├── ConnectPage.qml
├── CustomPushButton.qml
├── CustomTextEdit.qml
├── HistoryPage.qml
├── MainForm.ui.qml
├── ScrollBarVertical.qml
├── SettingsPage.qml
├── TerminalPage.qml
├── android
├── AndroidManifest.xml
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── libs
│ ├── android-support-v4.jar
│ └── d2xx.jar
├── res
│ ├── drawable-hdpi
│ │ └── icon.png
│ ├── drawable-ldpi
│ │ └── icon.png
│ ├── drawable-mdpi
│ │ └── icon.png
│ ├── values
│ │ └── libs.xml
│ └── xml
│ │ └── device_filter.xml
└── src
│ ├── QtFtDev.java
│ └── TestClass.java
├── customproxy4qmlmodel.cpp
├── customproxy4qmlmodel.h
├── deployment.pri
├── ftdimanager.cpp
├── ftdimanager.h
├── katynko
├── .directory
├── android_ft232.png
├── clear_left.png
├── dashed_elmnt.png
├── dashed_elmnt_red.png
├── fontsizedefault_koffice.png
├── fontsizedown_koffice.png
├── fontsizeup_koffice.png
├── history.png
├── key_enter.png
└── settings.png
├── main.cpp
├── main.qml
├── qml.qrc
├── qmlitemmodel.cpp
├── qmlitemmodel.h
├── res.qrc
├── screenshot
├── .directory
├── Screenshot_2016-02-29-17-12-55.png
├── Screenshot_2016-02-29-17-13-02.png
├── Screenshot_2016-02-29-17-15-32.png
├── Screenshot_2016-02-29-17-33-36.png
├── android settings1.png
└── qt settings.png
├── untitled.pro
└── untitled.pro.user
/ConnectPage.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.4
2 | import QtQuick.Controls 1.3
3 | import QtQuick.Controls.Styles 1.2
4 | Item {
5 | id: root
6 | signal connectPageSettt(int dataIndx, int stopIndx, int parityIndx, int flowIndx, int baudIndx);
7 | signal setCurrntPortIndx(int portIndx);
8 |
9 | onConnectPageSettt: {
10 | cmbxDataBits.currentIndex = dataIndx
11 | cmbxStopBits.currentIndex = stopIndx
12 | cmbxParity.currentIndex = parityIndx
13 | cmbxFlow.currentIndex = flowIndx
14 | cmbxBaud.currentIndex = baudIndx
15 | }
16 |
17 | onSetCurrntPortIndx: {
18 | cmbxCurrentDevice.currentIndex = portIndx
19 | }
20 |
21 | property int defHeightPushButtonL: (root.height / 10) > defHeightPushButton ? defHeightPushButton : (root.height / 10)
22 |
23 | Column{
24 | anchors.fill: parent
25 | anchors.margins: defMargins
26 | spacing: defMargins
27 |
28 | Item {
29 | height: defHeightPushButtonL
30 |
31 | }
32 |
33 | ComboBox{
34 | id: cmbxDataBits
35 | height: defHeightPushButtonL
36 | width: parent.width - 2 * defMargins
37 | currentIndex: 0
38 | activeFocusOnPress: true
39 | style: comboboxStyle
40 | model: ListModel{
41 | ListElement{ value: qsTrId("Data 8")}
42 | ListElement{ value: qsTrId("Data 7")}
43 | }
44 | }
45 |
46 | ComboBox{
47 | id: cmbxStopBits
48 | height: defHeightPushButtonL
49 | width: cmbxDataBits.width
50 | currentIndex: 0
51 | activeFocusOnPress: true
52 | style: comboboxStyle
53 | model: ListModel{
54 | ListElement{ value: qsTrId("Stop 1")}
55 | ListElement{ value: qsTrId("Stop 2")}
56 | }
57 | }
58 |
59 | ComboBox{
60 | id: cmbxParity
61 | height: defHeightPushButtonL
62 | currentIndex: 0
63 | width: cmbxDataBits.width
64 | activeFocusOnPress: true
65 | style: comboboxStyle
66 | model: ListModel{
67 | ListElement{ value: qsTrId("Parity None")}
68 | ListElement{ value: qsTrId("Parity Odd")}
69 | ListElement{ value: qsTrId("Parity Even")}
70 | ListElement{ value: qsTrId("Parity Mark")}
71 | ListElement{ value: qsTrId("Parity Space")}
72 |
73 | }
74 | }
75 |
76 | ComboBox{
77 | id: cmbxFlow
78 | height: defHeightPushButtonL
79 | currentIndex: 0
80 | width: cmbxDataBits.width
81 | activeFocusOnPress: true
82 | style: comboboxStyle
83 | model: ListModel{
84 | ListElement{ value: qsTrId("None")}
85 | ListElement{ value: qsTrId("CTS/RTS")}
86 | ListElement{ value: qsTrId("DTR/DSR")}
87 | ListElement{ value: qsTrId("XOFF/XON")}
88 |
89 | }
90 | }
91 |
92 | ComboBox{
93 | id: cmbxBaud
94 | height: defHeightPushButtonL
95 | currentIndex: 3
96 | width: cmbxDataBits.width
97 | activeFocusOnPress: true
98 | style: comboboxStyle
99 | model: ListModel{
100 | ListElement{ value: qsTrId("1200")}
101 | ListElement{ value: qsTrId("2400")}
102 | ListElement{ value: qsTrId("4800")}
103 | ListElement{ value: qsTrId("9600")}
104 | ListElement{ value: qsTrId("19200")}
105 | ListElement{ value: qsTrId("38400")}
106 | ListElement{ value: qsTrId("57600")}
107 | ListElement{ value: qsTrId("115200")}
108 |
109 | }
110 | }
111 |
112 | ComboBox{
113 | id: cmbxCurrentDevice
114 | height: defHeightPushButtonL
115 | currentIndex: 0
116 | width: cmbxDataBits.width
117 | activeFocusOnPress: true
118 | style: comboboxStyle
119 | model: deviceModel
120 | }
121 |
122 | CustomPushButton{
123 | id: cpbConnect
124 | text: ftdiIsConnected ? qsTr("Disconnect") : qsTr("Connect")
125 | fillColor: defColorButtonFill;
126 | color: defColorBackground
127 | radius: defRadiusButton
128 | textSize: defHeightFontPixel
129 | width: cmbxDataBits.width
130 | height: defHeightPushButtonL * 2
131 |
132 | enabled: (cmbxCurrentDevice.currentIndex >= 0 && cmbxCurrentDevice.currentText.length)
133 |
134 | onAnimationDone: {
135 | if(ftdiIsConnected)
136 | ftdiManager.disconnectFromPort();
137 | else
138 | ftdiManager.connectToOnePort(cmbxCurrentDevice.currentIndex,
139 | cmbxBaud.currentIndex,
140 | cmbxDataBits.currentIndex,
141 | cmbxStopBits.currentIndex,
142 | cmbxParity.currentIndex,
143 | cmbxFlow.currentIndex);
144 | }
145 |
146 | }
147 |
148 | CustomPushButton{
149 | id: cpbUpdate
150 | text: qsTr("Update List")
151 | fillColor: defColorButtonFill;
152 | color: defColorBackground
153 | radius: defRadiusButton
154 | textSize: defHeightFontPixel
155 | width: cmbxDataBits.width
156 | height: defHeightPushButtonL
157 |
158 | onAnimationDone: {
159 | ftdiManager.createDeviceInfoList(true)
160 | }
161 |
162 | }
163 |
164 |
165 |
166 | }
167 | Component{
168 | id: comboboxStyle
169 | ComboBoxStyle {
170 | id: comboBox
171 | textColor: defColorText
172 | // selectedTextColor:
173 | // selectionColor:
174 |
175 | background: Rectangle {
176 | id: rectCategory
177 | radius: defRadiusButton
178 | color: defColorButtonFill
179 |
180 | // Image {
181 | // source: "qrc:/mainform/katynko/ComboImg.png"
182 | // anchors.verticalCenter: parent.verticalCenter
183 | // // anchors.bottom: parent.bottom
184 | // anchors.right: parent.right
185 | // // anchors.bottomMargin: 5
186 | // anchors.rightMargin: mainLeftMargin
187 | // height: parent.height * 0.8
188 | // width: height
189 | // fillMode: Image.Stretch
190 | // }
191 | }
192 | label: Text {
193 | verticalAlignment: Text.AlignVCenter
194 | horizontalAlignment: Text.AlignHCenter
195 | font.pixelSize: defHeightFontPixel
196 |
197 | color: defColorBackground
198 | text: control.currentText
199 | }
200 | }
201 | }
202 |
203 | }
204 |
205 |
--------------------------------------------------------------------------------
/CustomPushButton.qml:
--------------------------------------------------------------------------------
1 | //import QtQuick 2.0
2 |
3 | import QtQuick 2.4
4 | import QtQuick.Controls 1.3
5 | import QtQuick.Layouts 1.1
6 |
7 |
8 | FocusScope {
9 | id: container
10 | signal clicked
11 | signal iAmReleased
12 | signal animationDone
13 | signal iAmPressAndHold
14 | property string imgSource: ""
15 | property string text: ""
16 | property string color: "#ffffff"
17 | property string fillColor: "#00000000"
18 | property int textSize: height * 0.6
19 | property string borderColor: "#00000000"
20 | property int borderWidth: 0
21 | property int radius: 6
22 | property int marginss: 0
23 | // property bool checable: false
24 | width: 40
25 | height: 20
26 |
27 | onEnabledChanged: enabled ? opacity = 1 : opacity = 0.4
28 |
29 | Rectangle {
30 | id: buttonRectangle
31 | anchors.fill: parent
32 | color: fillColor
33 | radius: container.radius
34 | border.width: container.borderWidth
35 | border.color: container.borderColor
36 |
37 | Image {
38 | id: image
39 | smooth: true
40 |
41 | // fillMode: Image.PreserveAspectFit
42 | anchors.right: parent.right
43 | anchors.verticalCenter: parent.verticalCenter
44 | height: parent.height * 0.8
45 | width: (imgSource.length > 0) ? height : 0
46 | anchors.margins: container.marginss
47 |
48 | anchors.rightMargin: (container.text.length < 1) ? (parent.height - height) / 2 : container.marginss
49 |
50 | source: imgSource
51 |
52 | }
53 |
54 | Item {
55 | anchors.left: parent.left
56 | anchors.right: image.left
57 | anchors.top: parent.top
58 | anchors.bottom: parent.bottom
59 | anchors.leftMargin: container.marginss * 2
60 |
61 | Text {
62 | color: container.color
63 | anchors.centerIn: parent
64 | font.pixelSize: container.textSize
65 | text: container.text
66 | font.bold: true
67 | }
68 | }
69 |
70 | MouseArea {
71 | id: mouseArea;
72 | anchors.fill: parent
73 |
74 | onPressed:{
75 | buttonRectangle.state = "pressed"
76 | container.clicked()
77 | }
78 |
79 | onClicked: {
80 | buttonRectangle.state = "pressed"
81 |
82 | clkTmr.start()
83 | // container.clicked()
84 | }
85 | onReleased: {
86 | stateTimer.start()
87 | container.iAmReleased()
88 | }
89 |
90 | onPressAndHold: {
91 | buttonRectangle.state = "pressed"
92 | container.iAmPressAndHold()
93 | stateTimer.start()
94 |
95 | }
96 | }
97 |
98 | states: State {
99 | name: "pressed"
100 | PropertyChanges { target: /*image*/buttonRectangle; scale: 0.85 }
101 | }
102 |
103 | Timer{
104 | id: clkTmr
105 | interval: stateTimer.interval
106 | repeat: false
107 | onTriggered: container.animationDone()
108 | }
109 |
110 | Timer {
111 | id: stateTimer
112 | interval: 150;
113 | repeat: false
114 | onTriggered:{ buttonRectangle.state = 'State0';
115 |
116 | }
117 | }
118 |
119 | transitions: Transition {
120 | NumberAnimation { properties: "scale"; duration: 100; easing.type: Easing.InOutQuad /*InCubic*/} //.InOutQuad }
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/CustomTextEdit.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.4
2 | import QtQuick.Controls 1.3
3 | import QtQuick.Controls.Styles 1.1
4 |
5 | Rectangle{
6 | id: root
7 | property bool firstValBool: false
8 | signal customTextChanged
9 | signal cteEnter()
10 | signal cteEsc()
11 | property bool _readOnly: false
12 |
13 | property string placeholderText: qsTr("Type Here")
14 | property string imgSource: "qrc:/img/katynko/dashed_elmnt.png"
15 | property string imgSourceTextNotValid: "qrc:/img/katynko/dashed_elmnt_red.png"
16 |
17 | property string text: textField1.text
18 | property int cursorPosition: 0
19 | property int length: textField1.length
20 | property bool isValid: true
21 | property real scaleCoef: 1
22 |
23 |
24 |
25 | onEnabledChanged: enabled ? opacity = 1 : opacity = 0.4
26 |
27 |
28 | function setTextIsValid(_isValid){
29 | isValid = _isValid
30 | }
31 |
32 | function setText(txt){
33 | textField1.text = txt
34 | if(textField1.text.length)
35 | pbClearTextField1.state = "State0"
36 | else
37 | pbClearTextField1.state = "clear"
38 | }
39 |
40 | function setFocus(isTrue){
41 | textField1.focus = isTrue
42 | }
43 |
44 | color: defColorBackground
45 |
46 |
47 | height: 22
48 | width: 50
49 | x: 5
50 | y: 5
51 |
52 | TextField {
53 | id: textField1
54 | anchors.left: parent.left
55 | anchors.top: parent.top
56 | height: parent.height * 0.9
57 | width: _readOnly ? parent.width : parent.width - height
58 |
59 | placeholderText: root.placeholderText
60 | text: root.text
61 | readOnly: _readOnly
62 | cursorPosition: root.cursorPosition
63 |
64 | onTextChanged: {
65 | root.text = text
66 | if(textField1.text.length > 0 && !_readOnly){
67 | if(!pbClearTextField1.visible){
68 | firstValBool = true
69 | pbClearTextField1.state = "State0"
70 | }
71 | }else{
72 | if(pbClearTextField1.visible)
73 | pbClearTextField1.state = "clear"
74 | }
75 | if(!_readOnly)
76 | root.customTextChanged()
77 | }
78 |
79 | Keys.onEscapePressed: cteEsc()
80 |
81 | Keys.onReturnPressed: cteEnter()
82 |
83 | style: customTextEditStyle
84 |
85 | }
86 |
87 | Rectangle{
88 | id: pbClearTextField1
89 | anchors.top: parent.top
90 | anchors.right: parent.right
91 | anchors.bottom: parent.bottom
92 | anchors.bottomMargin: parent.height - textField1.height
93 |
94 | width: (!firstValBool) ? 0 : parent.height
95 | visible: firstValBool
96 | color: defColorBackground//"transparent"
97 |
98 | MouseArea{
99 | id: maPbClearTextField1
100 | anchors.fill: parent
101 |
102 | Image{
103 | id: image111
104 | anchors.fill: parent
105 | source: "qrc:/img/katynko/clear_left.png";
106 | }
107 |
108 | onClicked: {
109 | Qt.inputMethod.hide()
110 |
111 | textField1.text = "";
112 | textField1.cursorPosition = 0
113 | textField1.focus = true
114 |
115 | }
116 | }
117 | states: State {
118 | name: "clear"
119 | PropertyChanges { target: pbClearTextField1; visible: false; width: 0 }
120 | }
121 |
122 | transitions: Transition {
123 | NumberAnimation { properties: "width"; duration: 150; easing.type: Easing.Linear }
124 |
125 | }
126 |
127 | }
128 |
129 | Rectangle{
130 | anchors.left: parent.left
131 | anchors.right: parent.right
132 | anchors.bottom: parent.bottom
133 | anchors.rightMargin: pbClearTextField1.width
134 | color: "transparent"
135 | height: parent.height - textField1.height
136 |
137 | Image{id: imgValid; source: (isValid) ? imgSource : imgSourceTextNotValid; fillMode: Image.Tile; anchors.fill: parent; scale: scaleCoef }
138 |
139 | }
140 |
141 | Component{
142 | id: customTextEditStyle
143 | TextFieldStyle{
144 | textColor: defColorText
145 | // selectedTextColor: mainSelectedTextColor
146 | // selectionColor: mainSelectionColor
147 | // font.pixelSize: mainDefaultFontPixelSize
148 | background: Rectangle{
149 | color: defColorBackground
150 | }
151 | }
152 | }
153 | }
154 |
155 |
156 |
--------------------------------------------------------------------------------
/HistoryPage.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.4
2 | import QtQuick.Controls 1.3
3 | import QtQuick.Controls.Styles 1.2
4 | import QtQuick.Dialogs 1.2
5 |
6 |
7 | Item {
8 |
9 | property int lastDeleteIndx: -1;
10 | Item {
11 | id: itmTop
12 | anchors.left: parent.left
13 | anchors.right: parent.right
14 | anchors.top: parent.top
15 | height: defHeightPushButton * 1.3
16 |
17 |
18 | CustomPushButton{
19 | id: cpbHistory
20 | anchors.top: parent.top
21 | anchors.left: parent.left
22 | anchors.bottom: parent.bottom
23 | anchors.margins: defMargins
24 | width: defHeightFontPixel * text.length * 0.7
25 | imgSource: "";
26 |
27 | text: qsTrId("Back")
28 | radius: defRadiusButton;
29 | color: defColorButtonText
30 | fillColor: defColorButtonFill
31 |
32 | onAnimationDone: {
33 | changeStackViewPage(1);
34 | }
35 |
36 | }
37 |
38 | CustomTextEdit{
39 | id: cteFilter
40 | anchors.left: cpbHistory.right
41 | anchors.top: parent.top
42 | anchors.right: parent.right
43 | anchors.bottom: parent.bottom
44 | anchors.margins: defMargins
45 | placeholderText: qsTr("Enter command")
46 |
47 | onCteEnter: {
48 | Qt.inputMethod.hide()
49 |
50 | }
51 |
52 | onCteEsc: {
53 | Qt.inputMethod.hide()
54 | }
55 |
56 | onTextChanged: {
57 | ftdiManager.setThisHistoryFilter(cteFilter.text)
58 | }
59 |
60 |
61 | }
62 |
63 | }
64 |
65 | ListView{
66 | id: lvHistory
67 | anchors.left: parent.left
68 | anchors.top: itmTop.bottom
69 | anchors.right: parent.right
70 | anchors.bottom: parent.bottom
71 | clip: true
72 |
73 | delegate: Item{
74 |
75 | signal onPress();
76 | id: emnt1
77 | anchors.left: parent.left
78 | anchors.right: parent.right
79 | anchors.margins: defMargins
80 | height: defHeightPushButton
81 |
82 | Text{
83 | id: txtElmnt
84 | anchors.verticalCenter: parent.verticalCenter
85 | anchors.bottomMargin: defHeightLine
86 | anchors.leftMargin: defMargins
87 | anchors.left: parent.left
88 | color: defColorText //defColorBackground
89 | text: value
90 | elide: Text.ElideMiddle
91 | }
92 |
93 | Rectangle{
94 | anchors.left: parent.left
95 | anchors.right: parent.right
96 | anchors.bottom: parent.bottom
97 | anchors.leftMargin: defMargins
98 | anchors.rightMargin: defMargins
99 | height: defHeightLine
100 | color: defColorLine
101 | }
102 |
103 | MouseArea{
104 | anchors.fill: parent
105 |
106 | onClicked: {
107 | changeStackViewPage(1);
108 | tpPage.setThisCommandLine(txtElmnt.text)
109 |
110 | }
111 |
112 |
113 | onPressAndHold: {
114 | lastDeleteIndx = index;
115 | messageDialog.show(qsTr("Delete: ") + txtElmnt.text + "?");
116 | }
117 | }
118 |
119 |
120 | }
121 | model: historyModel
122 |
123 | Behavior on height {
124 |
125 | NumberAnimation {
126 | id: animateHeight
127 | property: "height"
128 | from: 0.9
129 | to: 1.0
130 | loops: Animation.Infinite
131 | duration: 200
132 | easing {type: Easing.OutInQuart }
133 | }
134 | }
135 |
136 | states: State {
137 | name: "ShowBars"
138 | when: lstUsrView.movingVertically
139 | PropertyChanges { target: verticalScrollBar; opacity: 1 }
140 | }
141 |
142 | transitions: Transition {
143 | NumberAnimation { properties: "opacity"; duration: 400 }
144 | }
145 | }
146 |
147 |
148 | ScrollBarVertical {
149 | target: lvHistory
150 | }
151 | MessageDialog {
152 | id: messageDialog
153 | title: qsTr("Delete")
154 |
155 | function show(caption) {
156 |
157 | messageDialog.text = caption;
158 | messageDialog.open();
159 |
160 | }
161 |
162 | standardButtons: StandardButton.Yes |
163 | StandardButton.No
164 |
165 | onYes: {
166 | ftdiManager.delThisHistoryIndx(lastDeleteIndx);
167 | lastDeleteIndx = -1;
168 | }
169 |
170 | onNo: {
171 | lastDeleteIndx = -1;
172 | }
173 | }
174 |
175 | }
176 |
177 |
--------------------------------------------------------------------------------
/MainForm.ui.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.4
2 | import QtQuick.Controls 1.3
3 | import QtQuick.Layouts 1.1
4 |
5 | Item {
6 | width: 640
7 | height: 480
8 |
9 | property alias button3: button3
10 | property alias button2: button2
11 | property alias button1: button1
12 |
13 | RowLayout {
14 | anchors.centerIn: parent
15 |
16 | Button {
17 | id: button1
18 | text: qsTr("Press Me 1")
19 | }
20 |
21 | Button {
22 | id: button2
23 | text: qsTr("Press Me 2")
24 | }
25 |
26 | Button {
27 | id: button3
28 | text: qsTr("Press Me 3")
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/ScrollBarVertical.qml:
--------------------------------------------------------------------------------
1 |
2 | import QtQuick 2.4
3 | import QtQuick.Controls 1.3
4 | import QtQuick.Layouts 1.1
5 |
6 |
7 | Rectangle {
8 | id: scrollBar
9 | property variant target
10 |
11 | clip: true
12 | width: defHeightFontPixel * 0.5
13 | radius: defRadiusButton
14 | smooth: true
15 |
16 | anchors.top: target.top
17 | anchors.bottom: target.bottom
18 | anchors.right: target.right
19 | anchors.rightMargin: 0
20 |
21 | states: [
22 | State { name: "nothing"; },
23 | State { name: "disabled"; when: (track.height == slider.height || target.width <= slider.width || target.contentHeight <= track.height) }
24 | ]
25 | transitions: [
26 | Transition { to: "disabled";
27 | ParallelAnimation {
28 | NumberAnimation { target: scrollBar; property: "opacity"; to: 0; duration: 500; }
29 | PropertyAction { target: scrollBar; property: "visible"; value: false; }
30 | }
31 | },
32 | Transition { to: "*";
33 | PropertyAction { target: scrollBar; property: "visible"; value: true; }
34 | NumberAnimation { target: scrollBar; property: "opacity"; to: 0.6; duration: 500; }
35 | }
36 | ]
37 |
38 | Timer {
39 | property int scrollAmount
40 |
41 | id: timer
42 | repeat: true
43 | interval: 20
44 | onTriggered: {
45 | target.contentY = Math.max(0, Math.min(target.contentY + scrollAmount,
46 | target.contentHeight - target.height));
47 | }
48 | }
49 |
50 | Item {
51 | id: track
52 | anchors.top: parent.top
53 | anchors.bottom: parent.bottom;
54 | width: parent.width
55 |
56 | MouseArea {
57 | anchors.fill: parent
58 | onPressed: {
59 | timer.scrollAmount = target.height * (mouseY < slider.y ? -1 : 1) // scroll by a page
60 | timer.running = true;
61 | }
62 | onReleased: {
63 | timer.running = false;
64 | }
65 | }
66 |
67 | Rectangle {
68 | id:slider
69 | color: defColorButtonFill
70 | smooth: true
71 | width: parent.width
72 | radius: 6
73 |
74 | anchors.bottom: (target.visibleArea.yPosition > 1)? parent.bottom: undefined
75 | height: {
76 | if(visible && target.contentHeight > 0 && target.height > 0 && target.visibleArea.yPosition > 0){
77 | if (target.visibleArea.yPosition < 0){ // Oberer Rand
78 | Math.max(30, Math.min(target.height / target.contentHeight * track.height, track.height-y) +target.height * target.visibleArea.yPosition)
79 |
80 | }else { // Mittelbereich
81 | Math.min(target.height / target.contentHeight * track.height, track.height-y)
82 |
83 | }
84 | }
85 | }
86 |
87 | y: Math.max(0,Math.min(track.height-30, target.visibleArea.yPosition * track.height));
88 |
89 |
90 | MouseArea {
91 | anchors.fill: parent
92 | drag.target: parent
93 | drag.axis: Drag.YAxis
94 | drag.minimumY: 0
95 | drag.maximumY: track.height - height
96 | hoverEnabled: true
97 | onPositionChanged: {
98 | if (pressedButtons == Qt.LeftButton) {
99 | target.contentY = slider.y * target.contentHeight / track.height
100 | }
101 | }
102 | onPressed: {
103 | scrollBar.opacity = 1
104 | }
105 |
106 | onEntered: {
107 | scrollBar.opacity = 1
108 | }
109 |
110 | onReleased: {
111 | scrollBar.opacity = 0.6
112 | }
113 |
114 | onExited: {
115 | if(pressedButtons == Qt.LeftButton)
116 | scrollBar.opacity = 1
117 | else
118 | scrollBar.opacity = 0.6
119 | }
120 | onWheel: {
121 | if(slider.y + slider.height +20 >= track.height){
122 | // flickTextLog.ensureVisible(textLog.cursorRectangle)
123 | console.log("down1")
124 | }
125 | }
126 | }
127 | }
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/SettingsPage.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.4
2 | import QtQuick.Window 2.2
3 |
4 | Item {
5 | Column{
6 | anchors.fill: parent
7 | anchors.margins: defMargins
8 |
9 | spacing: defMargins
10 |
11 | Row{
12 | height: defHeightPushButton
13 | spacing: defMargins
14 | Text{ text: qsTrId("Scale"); color: defColorText; font.pixelSize: defHeightFontPixel; height: defHeightPushButton }
15 |
16 | CustomPushButton{
17 | height: defHeightPushButton
18 | width: height;
19 | imgSource: "qrc:/img/katynko/fontsizedown_koffice.png";
20 |
21 | text: "";
22 | fillColor: defColorButtonFill;
23 | color: defColorText
24 | radius: defRadiusButton
25 | textSize: defHeightFontPixel
26 | enabled: (defHeightFontPixel > Screen.logicalPixelDensity)
27 | onAnimationDone: {
28 | defHeightFontPixel = defHeightFontPixel * 0.95
29 | console.log("minus = " + defHeightFontPixel)
30 | ftdiManager.saveQmlSettRealVal(defHeightFontPixel,0)
31 | }
32 | }
33 |
34 | CustomPushButton{
35 | height: defHeightPushButton
36 | width: height;
37 | imgSource: "qrc:/img/katynko/fontsizeup_koffice.png";
38 |
39 | text: "";
40 | fillColor: defColorButtonFill;
41 | color: defColorText
42 | radius: defRadiusButton
43 | textSize: defHeightFontPixel
44 |
45 | enabled: Screen.width < Screen.height ?
46 | width < (Screen.width * 0.25) :
47 | height < (Screen.height * 0.25)
48 | onAnimationDone: {
49 | defHeightFontPixel = defHeightFontPixel * 1.05
50 | console.log("plus = " + defHeightFontPixel)
51 | ftdiManager.saveQmlSettRealVal(defHeightFontPixel,0)
52 |
53 |
54 | }
55 | }
56 |
57 | CustomPushButton{
58 | height: defHeightPushButton
59 | width: height;
60 | imgSource: "qrc:/img/katynko/fontsizedefault_koffice.png";
61 |
62 | text: "";
63 | fillColor: defColorButtonFill;
64 | color: defColorText
65 | radius: defRadiusButton
66 | textSize: defHeightFontPixel
67 |
68 | onAnimationDone: {
69 | defHeightFontPixel = Screen.pixelDensity * 3.8;
70 | ftdiManager.saveQmlSettRealVal(defHeightFontPixel,0)
71 |
72 | }
73 | }
74 | }
75 |
76 |
77 | }
78 | }
79 |
80 |
--------------------------------------------------------------------------------
/TerminalPage.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.4
2 | import QtQuick.Controls 1.3
3 | import QtQuick.Controls.Styles 1.2
4 | import QtQuick.Window 2.2
5 |
6 | Item {
7 |
8 |
9 | signal appendPlainText(string plainTxt);
10 | signal terminalPageSettt(int endLineIndx, bool _hexOut);
11 | signal setThisCommandLine(string line)
12 | signal sendLineHexIsValid(bool isValid);
13 |
14 | property bool hexOut: false
15 |
16 |
17 |
18 | onAppendPlainText: {
19 | textArea1.append(plainTxt /*+ "\r\n"*/);
20 | }
21 |
22 | onTerminalPageSettt: {
23 | cmbxEndSymb.currentIndex = endLineIndx
24 | hexOut = _hexOut
25 | if(hexOut)
26 | ftdiManager.sendLineHexValidator(cteSend.text)
27 | }
28 |
29 | onSetThisCommandLine: {
30 | cteSend.setText(line)
31 | }
32 |
33 | onSendLineHexIsValid: {
34 | if(hexOut){
35 | cteSend.setTextIsValid(isValid)
36 | }
37 | }
38 |
39 | function sendLineNow(){
40 | if(hexOut && !cteSend.isValid)
41 | return;
42 |
43 | ftdiManager.sendDataToPort(cteSend.text , hexOut, cmbxEndSymb.currentIndex);
44 | cteSend.setText("");
45 |
46 | }
47 |
48 | Row{
49 | id: rwTop
50 | anchors.left: parent.left
51 | anchors.top: parent.top
52 | anchors.right: parent.right
53 | spacing: defMargins
54 |
55 | height: defHeightPushButtonSmll
56 |
57 | ComboBox{
58 | id: cmbxEndSymb
59 | width: parent.width * 0.27
60 | height: defHeightPushButtonSmll
61 | currentIndex: 0
62 | activeFocusOnPress: true
63 | style: comboboxStyle
64 | model: lstModelDN
65 |
66 | ListModel{
67 | id: lstModelDN
68 | ListElement{ value: qsTrId("CR+LF")}
69 | ListElement{ value: qsTrId("CR")}
70 | ListElement{ value: qsTrId("LF")}
71 | ListElement{ value: qsTrId("None")}
72 |
73 | }
74 |
75 | onCurrentIndexChanged: {
76 | ftdiManager.saveQmlSett(currentIndex, 0)
77 | }
78 | }
79 |
80 | CustomPushButton{
81 | id: cpbHex
82 | width: parent.width * 0.25
83 | height: defHeightPushButtonSmll
84 | radius: defRadiusButton
85 | color: defColorButtonText
86 | fillColor: defColorButtonFill
87 | textSize: defHeightFontPixel
88 | text: hexOut ? "Hex" : "String"
89 | onAnimationDone: {
90 | if(hexOut)
91 | cteSend.setTextIsValid(true)
92 | hexOut = !hexOut
93 | ftdiManager.saveQmlSett(hexOut,0);
94 |
95 | if(hexOut)
96 | ftdiManager.sendLineHexValidator(cteSend.text)
97 | }
98 | }
99 |
100 | CustomPushButton{
101 | id: cpbConnectPage
102 | height: defHeightPushButtonSmll
103 |
104 | width: text.length * defHeightFontPixel * 0.7
105 | text: qsTr("Clear")
106 |
107 | radius: defRadiusButton
108 | color: defColorButtonText
109 | fillColor: defColorButtonFill
110 | textSize: defHeightFontPixel
111 | onAnimationDone: {
112 | textArea1.text = "";
113 | }
114 | enabled: true
115 | }
116 | }
117 |
118 |
119 |
120 | TextArea {
121 | id: textArea1
122 | text: ""
123 | readOnly: true
124 | textColor: defColorText
125 | frameVisible: true
126 | font.pixelSize: defHeightFontPixelLog
127 | anchors.bottom: itmBottom.top
128 | anchors.right: parent.right
129 | anchors.left: parent.left
130 | anchors.top: rwTop.bottom
131 | anchors.margins: defMargins
132 |
133 | }
134 |
135 | Item {
136 | id: itmBottom
137 | anchors.left: parent.left
138 | anchors.right: parent.right
139 | anchors.bottom: parent.bottom
140 | height: defHeightPushButton * 1.3
141 | CustomPushButton{
142 | id: cpbSend
143 | anchors.top: parent.top
144 | anchors.right: parent.right
145 | anchors.bottom: parent.bottom
146 | anchors.margins: defMargins
147 | width: height
148 | imgSource: "qrc:/img/katynko/key_enter.png";
149 |
150 | text: ""
151 | radius: defRadiusButton;
152 |
153 | enabled: (ftdiIsConnected && !sendTmr.running && cteSend.isValid)
154 |
155 | color: defColorButtonText
156 | fillColor: defColorButtonFill
157 |
158 | onAnimationDone: {
159 | Qt.inputMethod.hide()
160 | sendTmr.start();
161 | }
162 |
163 | }
164 |
165 | CustomPushButton{
166 | id: cpbHistory
167 | anchors.top: parent.top
168 | anchors.left: parent.left
169 | anchors.bottom: parent.bottom
170 | anchors.margins: defMargins
171 | width: height
172 | imgSource: "qrc:/img/katynko/history.png";
173 |
174 | text: ""
175 | radius: defRadiusButton;
176 | color: defColorButtonText
177 | fillColor: defColorButtonFill
178 |
179 | onAnimationDone: {
180 | changeStackViewPage(3);
181 | }
182 |
183 | }
184 |
185 | CustomTextEdit{
186 | id: cteSend
187 | anchors.left: cpbHistory.right
188 | anchors.top: parent.top
189 | anchors.right: cpbSend.left
190 | anchors.bottom: parent.bottom
191 | anchors.margins: defMargins
192 | enabled: ftdiIsConnected
193 |
194 | text: "+++"
195 | placeholderText: qsTr("Enter command")
196 |
197 | // scaleCoef: defHeightFontPixel / (Screen.pixelDensity )
198 |
199 | onCteEnter: {
200 | Qt.inputMethod.hide()
201 | sendTmr.restart();
202 | // sendLineNow();
203 | }
204 |
205 | onCteEsc: {
206 | Qt.inputMethod.hide()
207 | }
208 |
209 | onTextChanged: {
210 | if(hexOut)
211 | ftdiManager.sendLineHexValidator(cteSend.text)
212 |
213 | }
214 |
215 |
216 | }
217 |
218 |
219 | Timer{
220 | id: sendTmr
221 | repeat: false
222 | interval: 50
223 | onTriggered: {
224 | sendLineNow();
225 |
226 | }
227 | }
228 | }
229 |
230 | Component{
231 | id: comboboxStyle
232 | ComboBoxStyle {
233 | id: comboBox
234 | textColor: defColorText
235 | // selectedTextColor:
236 | // selectionColor:
237 |
238 | background: Rectangle {
239 | id: rectCategory
240 | radius: defRadiusButton
241 | color: defColorButtonFill
242 |
243 | // Image {
244 | // source: "qrc:/mainform/katynko/ComboImg.png"
245 | // anchors.verticalCenter: parent.verticalCenter
246 | // // anchors.bottom: parent.bottom
247 | // anchors.right: parent.right
248 | // // anchors.bottomMargin: 5
249 | // anchors.rightMargin: mainLeftMargin
250 | // height: parent.height * 0.8
251 | // width: height
252 | // fillMode: Image.Stretch
253 | // }
254 | }
255 | label: Text {
256 | verticalAlignment: Text.AlignVCenter
257 | horizontalAlignment: Text.AlignHCenter
258 | font.pixelSize: defHeightFontPixel
259 |
260 | color: defColorBackground
261 | text: control.currentText
262 | }
263 | }
264 | }
265 | }
266 |
267 |
--------------------------------------------------------------------------------
/android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
41 |
42 |
43 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
62 |
63 |
64 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | jcenter()
4 | }
5 |
6 | dependencies {
7 | classpath 'com.android.tools.build:gradle:1.1.0'
8 | }
9 | }
10 |
11 | allprojects {
12 | repositories {
13 | jcenter()
14 | }
15 | }
16 |
17 | apply plugin: 'com.android.application'
18 |
19 | dependencies {
20 | compile fileTree(dir: 'libs', include: ['*.jar'])
21 | }
22 |
23 | android {
24 | /*******************************************************
25 | * The following variables:
26 | * - androidBuildToolsVersion,
27 | * - androidCompileSdkVersion
28 | * - qt5AndroidDir - holds the path to qt android files
29 | * needed to build any Qt application
30 | * on Android.
31 | *
32 | * are defined in gradle.properties file. This file is
33 | * updated by QtCreator and androiddeployqt tools.
34 | * Changing them manually might break the compilation!
35 | *******************************************************/
36 |
37 | compileSdkVersion androidCompileSdkVersion.toInteger()
38 |
39 | buildToolsVersion androidBuildToolsVersion
40 |
41 | sourceSets {
42 | main {
43 | manifest.srcFile 'AndroidManifest.xml'
44 | java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
45 | aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
46 | res.srcDirs = [qt5AndroidDir + '/res', 'res']
47 | resources.srcDirs = ['src']
48 | renderscript.srcDirs = ['src']
49 | assets.srcDirs = ['assets']
50 | jniLibs.srcDirs = ['libs']
51 | }
52 | }
53 |
54 | lintOptions {
55 | abortOnError false
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 10 15:27:10 PDT 2013
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
7 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/android/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/android/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/android/libs/d2xx.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/android/libs/d2xx.jar
--------------------------------------------------------------------------------
/android/res/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/android/res/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/android/res/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/android/res/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/android/res/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/android/res/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/android/res/values/libs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - https://download.qt-project.org/ministro/android/qt5/qt-5.4
5 |
6 |
7 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/android/res/xml/device_filter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/android/src/QtFtDev.java:
--------------------------------------------------------------------------------
1 | // Java class
2 | package org.qtproject.qt5;
3 |
4 | //import android.app.Activity;
5 | import com.ftdi.j2xx.D2xxManager;
6 | import com.ftdi.j2xx.FT_Device;
7 |
8 | import android.content.Context;
9 |
10 | //import android.os.Handler;
11 |
12 |
13 |
14 | import java.io.IOException;
15 |
16 |
17 | public class QtFtDev //extends org.qtproject.qt5.android.bindings.QtActivity//extends Activity
18 | {
19 | // j2xx
20 | public static D2xxManager ftD2xx = null;
21 | public Context global_context;
22 |
23 | FT_Device ftDev;
24 | int DevCount = -1;
25 | int currentPortIndex = -1;
26 | int portIndex = -1;
27 |
28 | enum DeviceStatus{
29 | DEV_NOT_CONNECT,
30 | DEV_NOT_CONFIG,
31 | DEV_CONFIG
32 | }
33 | boolean uart_configured = false;
34 |
35 | int lastReadLen;
36 |
37 | int baudRate; /* baud rate */
38 | byte stopBit; /* 1:1stop bits, 2:2 stop bits */
39 | byte dataBit; /* 8:8bit, 7: 7bit */
40 | byte parity; /* 0: none, 1: odd, 2: even, 3: mark, 4: space */
41 | byte flowControl; /* 0:none, 1: CTS/RTS, 2:DTR/DSR, 3:XOFF/XON */
42 |
43 | final byte XON = 0x11; /* Resume transmission */
44 | final byte XOFF = 0x13; /* Pause transmission */
45 | // ReadThread readThread; // read data from USB
46 |
47 | final int MAX_NUM_BYTES = 65536;
48 | final int USB_DATA_BUFFER = 8192;
49 |
50 | byte[] writeBuffer;
51 |
52 |
53 |
54 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
55 | static int fromNumber(int x, int y) {
56 | return x + y;
57 | }
58 |
59 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
60 |
61 | static String fromNumberOne(int x) {
62 | return "Hello Qt from Java " + x;
63 | }
64 |
65 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
66 |
67 | String fromNumberTwo(int x){
68 | return "from number two " + x;
69 | }
70 |
71 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
72 |
73 | //init lib
74 | int getInstance(Context parentContext)
75 | {
76 | int retVal = 1;
77 | writeBuffer = new byte[512];
78 | global_context = parentContext;
79 |
80 | try{
81 | ftD2xx = D2xxManager.getInstance(parentContext);
82 | retVal = 2;
83 | }
84 | catch (D2xxManager.D2xxException e) {
85 | retVal = 3;
86 | }
87 | return retVal;
88 | }
89 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
90 |
91 | //ftdev list
92 | int createDeviceList()
93 | {
94 | int tempDevCount = ftD2xx.createDeviceInfoList(global_context);
95 | if (tempDevCount > 0) {
96 | if( DevCount != tempDevCount )
97 | DevCount = tempDevCount;
98 | }else
99 | DevCount = -1;
100 |
101 | return DevCount;
102 |
103 | }
104 |
105 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
106 |
107 | int checkDeviceStatus()
108 | {
109 |
110 | int retVal = 0;
111 |
112 | switch(checkDevice()){
113 | case DEV_NOT_CONNECT: retVal = 0;
114 | case DEV_NOT_CONFIG: retVal = 1;
115 | case DEV_CONFIG: retVal = 2;
116 | }
117 | return retVal;
118 | }
119 |
120 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
121 |
122 | DeviceStatus checkDevice()
123 | {
124 | if(ftDev == null || false == ftDev.isOpen()) {
125 | //"Need to connect to cable"
126 | return DeviceStatus.DEV_NOT_CONNECT;
127 | }else{
128 | if(false == uart_configured){
129 | //midToast("CHECK: uart_configured == false", Toast.LENGTH_SHORT);
130 | //"Need to configure UART.
131 | return DeviceStatus.DEV_NOT_CONFIG;
132 | }
133 | }
134 | return DeviceStatus.DEV_CONFIG;
135 | }
136 |
137 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
138 |
139 | int connToOneDevice(int connIndx, int baudR, int dataB, int stopB, int partt, int flowCtrl)
140 | {
141 | lastReadLen = 0;
142 | portIndex = connIndx;
143 | int connF = 10;
144 | createDeviceList();
145 | if(DevCount > 0)
146 | connF = connectFunction();
147 |
148 | if(DeviceStatus.DEV_NOT_CONNECT == checkDevice())
149 | return connF; //dev not connect
150 |
151 | baudRate = baudR;
152 | stopBit = (byte)stopB ; /* 0:1stop bits, 1:2 stop bits */
153 | dataBit = (byte)dataB; /* 8:8bit, 7: 7bit */
154 | parity = (byte)partt; /* 0: none, 1: odd, 2: even, 3: mark, 4: space */
155 | flowControl = (byte)flowCtrl; /* 0:none, 1: CTS/RTS, 2:DTR/DSR, 3:XOFF/XON */
156 |
157 |
158 | setConfig(baudRate, dataBit, stopBit, parity, flowControl);
159 |
160 | uart_configured = true;
161 |
162 | if(true == ftDev.isOpen())
163 | return 0;
164 | else
165 | return 11;
166 | }
167 |
168 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
169 |
170 | void setConfig(int baud, byte dataBits, byte stopBits, byte parity, byte flowControl)
171 | {
172 | // configure port
173 | // reset to UART mode for 232 devices
174 | ftDev.setBitMode((byte) 0, D2xxManager.FT_BITMODE_RESET);
175 |
176 | ftDev.setBaudRate(baud);
177 |
178 | switch (dataBits){
179 | case 7: dataBits = D2xxManager.FT_DATA_BITS_7; break;
180 | case 8: dataBits = D2xxManager.FT_DATA_BITS_8; break;
181 | default: dataBits = D2xxManager.FT_DATA_BITS_8; break;
182 | }
183 |
184 | switch (stopBits){
185 | case 0: stopBits = D2xxManager.FT_STOP_BITS_1; break;
186 | case 1: stopBits = D2xxManager.FT_STOP_BITS_2; break;
187 | default: stopBits = D2xxManager.FT_STOP_BITS_1; break;
188 | }
189 |
190 | switch (parity){
191 | case 0: parity = D2xxManager.FT_PARITY_NONE; break;
192 | case 1: parity = D2xxManager.FT_PARITY_ODD; break;
193 | case 2: parity = D2xxManager.FT_PARITY_EVEN; break;
194 | case 3: parity = D2xxManager.FT_PARITY_MARK; break;
195 | case 4: parity = D2xxManager.FT_PARITY_SPACE; break;
196 | default: parity = D2xxManager.FT_PARITY_NONE; break;
197 | }
198 |
199 | ftDev.setDataCharacteristics(dataBits, stopBits, parity);
200 |
201 | short flowCtrlSetting;
202 | switch (flowControl){
203 | case 0: flowCtrlSetting = D2xxManager.FT_FLOW_NONE; break;
204 | case 1: flowCtrlSetting = D2xxManager.FT_FLOW_RTS_CTS; break;
205 | case 2: flowCtrlSetting = D2xxManager.FT_FLOW_DTR_DSR; break;
206 | case 3: flowCtrlSetting = D2xxManager.FT_FLOW_XON_XOFF; break;
207 | default: flowCtrlSetting = D2xxManager.FT_FLOW_NONE; break;
208 | }
209 |
210 | ftDev.setFlowControl(flowCtrlSetting, XON, XOFF);
211 | uart_configured = true;
212 | }
213 |
214 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
215 |
216 | int connectFunction()
217 | {
218 |
219 | if( portIndex + 1 > DevCount)
220 | portIndex = 0;
221 |
222 |
223 | if( currentPortIndex == portIndex && ftDev != null && true == ftDev.isOpen() )
224 | return 1;
225 |
226 |
227 | if(null == ftDev)
228 | ftDev = ftD2xx.openByIndex(global_context, portIndex);
229 | else
230 | ftDev = ftD2xx.openByIndex(global_context, portIndex);
231 |
232 | uart_configured = false;
233 |
234 | if(ftDev == null)
235 | return 2;
236 |
237 | if (true == ftDev.isOpen()){
238 | currentPortIndex = portIndex;
239 | return 0;
240 | }else
241 | return 3;
242 |
243 | }
244 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
245 |
246 | int sendData(String writeHex/*, byte[] buffer*/)
247 | {
248 | int numBytes = -1;
249 | try {
250 | String atemp = hexToAscii(writeHex);
251 | numBytes = atemp.length();
252 | for (int i = 0; i < numBytes; i++){
253 | writeBuffer[i] = (byte) atemp.charAt(i);
254 | }
255 | }catch(IllegalArgumentException e){
256 | return -2;
257 | }
258 |
259 | if (ftDev.isOpen() == false)
260 | return -3;
261 |
262 | if (numBytes > 0)
263 | return ftDev.write(writeBuffer, numBytes);
264 | return 0;
265 |
266 | }
267 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
268 | int readDataArrLen()
269 | {
270 | return USB_DATA_BUFFER;
271 | }
272 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
273 | int readDataLastReadLen()
274 | {
275 | return lastReadLen;
276 | }
277 |
278 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
279 | int bytesAvailable()
280 | {
281 | if (ftDev.isOpen() == false){
282 | lastReadLen = -1;
283 | return lastReadLen;
284 | }else{
285 | return ftDev.getQueueStatus();
286 | }
287 |
288 | }
289 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
290 | String readData()
291 | {
292 | byte[] usbdata = new byte[USB_DATA_BUFFER];
293 |
294 | if (ftDev.isOpen() == false){
295 | lastReadLen = -1;
296 | return new StringBuilder(0).toString();
297 | }
298 | int readcount = ftDev.getQueueStatus();
299 |
300 | if (readcount > 0){
301 | if(readcount > USB_DATA_BUFFER){
302 | readcount = USB_DATA_BUFFER;
303 | }
304 | ftDev.read(usbdata, readcount);
305 | }
306 | lastReadLen = readcount;
307 |
308 | return byteArrayToHex(usbdata);
309 | }
310 |
311 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
312 |
313 | int disconnectFunction()
314 | {
315 | DevCount = -1;
316 | currentPortIndex = -1;
317 |
318 | if(ftDev != null){
319 | if( true == ftDev.isOpen()) {
320 | ftDev.close();
321 | }
322 | }
323 | return 0;
324 | }
325 |
326 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
327 |
328 | String hexToAscii(String s) throws IllegalArgumentException
329 | {
330 | int n = s.length();
331 | StringBuilder sb = new StringBuilder(n / 2);
332 | for (int i = 0; i < n; i += 2)
333 | {
334 | char a = s.charAt(i);
335 | char b = s.charAt(i + 1);
336 | sb.append((char) ((hexToInt(a) << 4) | hexToInt(b)));
337 | }
338 | return sb.toString();
339 | }
340 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
341 | int hexToInt(char ch)
342 | {
343 | if ('a' <= ch && ch <= 'f') { return ch - 'a' + 10; }
344 | if ('A' <= ch && ch <= 'F') { return ch - 'A' + 10; }
345 | if ('0' <= ch && ch <= '9') { return ch - '0'; }
346 | throw new IllegalArgumentException(String.valueOf(ch));
347 | }
348 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
349 |
350 | String byteArrayToHex(byte[] a) {
351 | StringBuilder sb = new StringBuilder(a.length * 2);
352 | for(byte b: a)
353 | sb.append(String.format("%02x", b & 0xff));
354 | return sb.toString();
355 | }
356 |
357 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
358 | }
359 |
360 |
--------------------------------------------------------------------------------
/android/src/TestClass.java:
--------------------------------------------------------------------------------
1 | // Java class
2 | package org.qtproject.qt5;
3 | class TestClass
4 | {
5 | static int fromNumber(int x) {
6 | return x + 2;
7 | }
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/customproxy4qmlmodel.cpp:
--------------------------------------------------------------------------------
1 | #include "customproxy4qmlmodel.h"
2 | //========================================================================================
3 | CustomProxy4QmlModel::CustomProxy4QmlModel(const QList &sortCols, QObject *parent) :
4 | QSortFilterProxyModel(parent), sortCols(sortCols)
5 | {
6 |
7 | }
8 |
9 | //========================================================================================
10 | bool CustomProxy4QmlModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
11 | {
12 |
13 | QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
14 |
15 | bool retVal = false;
16 | if(sortCols.isEmpty()){
17 | retVal = true;
18 | }else{
19 | for( int i = 0, iMax = sortCols.size(); i < iMax && !retVal; i++)
20 | retVal = index.data(sortCols.at(i)).toString().contains(filterRegExp());
21 |
22 | }
23 |
24 | return retVal;
25 | }
26 | //========================================================================================
27 | void CustomProxy4QmlModel::setNewFileterStr(QString str)
28 | {
29 | if(str.contains("'")){
30 | str.replace("'", " ");
31 | }
32 |
33 | QRegExp regExp(str, Qt::CaseInsensitive, QRegExp::RegExp);
34 | this->setFilterRegExp(regExp);
35 | }
36 | //========================================================================================
37 |
--------------------------------------------------------------------------------
/customproxy4qmlmodel.h:
--------------------------------------------------------------------------------
1 | #ifndef CUSTOMPROXY4QMLMODEL_H
2 | #define CUSTOMPROXY4QMLMODEL_H
3 |
4 | #include
5 | #include
6 | #include "qmlitemmodel.h"
7 |
8 | class CustomProxy4QmlModel : public QSortFilterProxyModel
9 | {
10 | Q_OBJECT
11 | public:
12 | explicit CustomProxy4QmlModel(const QList &sortCols, QObject *parent = 0);
13 |
14 | signals:
15 |
16 | protected:
17 | bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
18 |
19 | public slots:
20 | void setNewFileterStr(QString str);
21 |
22 | private:
23 | QList sortCols;
24 |
25 | };
26 |
27 | #endif // CUSTOMPROXY4QMLMODEL_H
28 |
--------------------------------------------------------------------------------
/deployment.pri:
--------------------------------------------------------------------------------
1 | android-no-sdk {
2 | target.path = /data/user/qt
3 | export(target.path)
4 | INSTALLS += target
5 | } else:android {
6 | x86 {
7 | target.path = /libs/x86
8 | } else: armeabi-v7a {
9 | target.path = /libs/armeabi-v7a
10 | } else {
11 | target.path = /libs/armeabi
12 | }
13 | export(target.path)
14 | INSTALLS += target
15 | } else:unix {
16 | isEmpty(target.path) {
17 | qnx {
18 | target.path = /tmp/$${TARGET}/bin
19 | } else {
20 | target.path = /opt/$${TARGET}/bin
21 | }
22 | export(target.path)
23 | }
24 | INSTALLS += target
25 | }
26 |
27 | export(INSTALLS)
28 |
--------------------------------------------------------------------------------
/ftdimanager.cpp:
--------------------------------------------------------------------------------
1 | #include "ftdimanager.h"
2 | #include
3 | #include
4 |
5 | //=============================================================================================================================
6 | FtdiManager::FtdiManager(QObject *parent) : QObject(parent)
7 | {
8 | QTimer *readTmr = new QTimer;
9 | readTmr->setInterval(150);
10 | readTmr->setSingleShot(true);
11 |
12 | connect(this, SIGNAL(startReadTmr()), readTmr, SLOT(start()) );
13 | connect(this, SIGNAL(stopReadTmr()), readTmr, SLOT(stop()) );
14 | connect(readTmr, SIGNAL(timeout()), this, SLOT(onReadTmr()) );
15 |
16 | deviceModel = new QmlItemModel(QString("value").split(",") );
17 | historyModel = new QmlItemModel(QString("value").split(",") );
18 |
19 | QList listInt;
20 | listInt.append(Qt::UserRole + 1);
21 | proxy_historyModel = new CustomProxy4QmlModel(listInt);
22 | proxy_historyModel->setDynamicSortFilter(true);
23 | proxy_historyModel->setSourceModel(historyModel);
24 |
25 | this->adnrActivity = QtAndroid::androidActivity();
26 |
27 | }
28 | //=============================================================================================================================
29 | void FtdiManager::startJar()
30 | {
31 | qtFtDev2xxManager = QAndroidJniObject(QByteArray("org/qtproject/qt5/QtFtDev").constData());
32 |
33 | // qDebug() << "context is valid = " <ExceptionCheck()) {
37 | // Handle exception here.
38 | qDebug() << "1 env =================================================== ";
39 | env->ExceptionClear();
40 | }
41 | qDebug() << "getInstance = " << qtFtDev2xxManager.callMethod(QByteArray("getInstance").constData(), QByteArray("(Landroid/content/Context;)I").constData(), adnrActivity.object());
42 | // QByteArray("(I)Ljava/lang/Object;").constData(), adnrActivity.object());
43 |
44 | if (env->ExceptionCheck()) {
45 | // Handle exception here.
46 | qDebug() << "2 env =================================================== ";
47 | env->ExceptionClear();
48 | }
49 |
50 | QTimer::singleShot(200, this, SLOT(createDeviceInfoList()));
51 | loadSettings(0);
52 |
53 | historyModel->clearAllData();
54 | for(int i = 0, iMax = listHistoryCommand.size(); i < iMax; i++)
55 | historyModel->addCustomDevice(QList() << listHistoryCommand.at(i));
56 |
57 | }
58 | //=============================================================================================================================
59 | void FtdiManager::onBtnPrssd()
60 | {
61 | QAndroidJniObject strhello = QAndroidJniObject::callStaticObjectMethod(QByteArray("org/qtproject/qt5/QtFtDev").constData(),
62 | QByteArray("fromNumberOne").constData(),
63 | QByteArray("(I)Ljava/lang/String;").constData(),
64 | QTime::currentTime().second());
65 | QAndroidJniEnvironment env;
66 | if (env->ExceptionCheck()) {
67 | // Handle exception here.
68 | qDebug() << "4env =================================================== ";
69 | env->ExceptionClear();
70 | }
71 |
72 | // jstring strJ = strhello.object();
73 |
74 | qDebug() << "stringNumber=" << strhello.toString(); // <clearAllData();
82 |
83 | jint devCount = qtFtDev2xxManager.callMethod(QByteArray("createDeviceList").constData());
84 |
85 | QAndroidJniEnvironment env;
86 | if (env->ExceptionCheck()) {
87 | // Handle exception here.
88 | qDebug() << "11 env =================================================== ";
89 | env->ExceptionClear();
90 | }
91 |
92 | for(int i = 0; i < devCount; i++)
93 | deviceModel->addCustomDevice(QList() << QString("ttyUSB%1").arg(i));
94 |
95 | if(devCount > 0){
96 | emit setCurrntPortIndx(devCount - 1);
97 | }else
98 | emit setCurrntPortIndx(-1);
99 | if(devCount > 0 && !onlyUpdate)
100 | connectToOnePort();
101 | }
102 | //=============================================================================================================================
103 | void FtdiManager::deviceStatus()
104 | {
105 | jint devCount = qtFtDev2xxManager.callMethod(QByteArray("checkDeviceStatus").constData());
106 |
107 | QString devStts("");
108 | switch(devCount){
109 | case 0: devStts = "DEV_NOT_CONNECT"; break;
110 | case 1: devStts = "DEV_NOT_CONFIG"; break;
111 | case 2: devStts = "DEV_CONFIG"; break;
112 | default: devStts = "unknown"; break;
113 | }
114 |
115 | QAndroidJniEnvironment env;
116 | if (env->ExceptionCheck()) {
117 | // Handle exception here.
118 | qDebug() << "11 env =================================================== ";
119 | env->ExceptionClear();
120 | }
121 | emit addLineToLog("devStts= " + devStts + " retVal=" + QString::number(devCount));
122 | }
123 | //=============================================================================================================================
124 | void FtdiManager::connectToOnePort()
125 | {
126 | QList list = loadSettings(1);
127 | while(list.size() < 4)
128 | list.append(0);
129 |
130 | if(list.size() < 5)
131 | list.append(3);
132 |
133 | connectToOnePort(0, list.at(4).toInt(), list.at(0).toInt(), list.at(1).toInt(), list.at(2).toInt(), list.at(3).toInt());
134 | }
135 | //=============================================================================================================================
136 | void FtdiManager::connectToOnePort(int indx, int baudIndx, int dataIndx, int stopIndx, int parityIndx, int flowIndx)
137 | {
138 |
139 | QList listVar;
140 | listVar.append(dataIndx);
141 | listVar.append(stopIndx);
142 | listVar.append(parityIndx);
143 | listVar.append(flowIndx);
144 | listVar.append(baudIndx);
145 | saveSettings(listVar, 1);
146 |
147 | jint baudRate ;
148 |
149 | switch (baudIndx) {
150 | case 0: baudRate = 1200; break;
151 | case 1: baudRate = 2400; break;
152 | case 2: baudRate = 4800; break;
153 | case 3: baudRate = 9600; break;
154 | case 4: baudRate = 19200; break;
155 | case 5: baudRate = 38400; break;
156 | case 6: baudRate = 57600; break;
157 | case 7: baudRate = 115200; break;
158 |
159 | default: baudRate = 9600; break;
160 | }
161 |
162 | jint devIndx = indx;
163 | jint devDataIndx = dataIndx;
164 | jint devStopIndx = stopIndx ;
165 | jint devParityIndx = parityIndx;
166 | jint devFlowIndx = flowIndx;
167 |
168 | jint retVal = qtFtDev2xxManager.callMethod(QByteArray("connToOneDevice").constData(),
169 | QByteArray("(IIIIII)I").constData(), devIndx,
170 | baudRate,
171 | devDataIndx,
172 | devStopIndx,
173 | devParityIndx,
174 | devFlowIndx );
175 |
176 | QAndroidJniEnvironment env;
177 | if (env->ExceptionCheck()) {
178 | // Handle exception here.
179 | qDebug() << "11 env =================================================== ";
180 | env->ExceptionClear();
181 | }
182 |
183 | QString openStts("");
184 | switch (retVal) {
185 | case 0: openStts = tr("Opened ttyUSB%1!").arg(indx) ; emit onFtdiStateChanged(true); emit startReadTmr(); break;
186 | case 1: openStts = tr("Already opened ttyUSB%1!").arg(indx); emit onFtdiStateChanged(true); emit startReadTmr(); break;
187 | case 2: openStts = tr("Device not valid ttyUSB%1!").arg(indx); break;
188 | case 3: openStts = tr("Can't open ttyUSB%1!").arg(indx); break;
189 |
190 | default: openStts = "unkonown error"; break;
191 | }
192 |
193 | emit addLineToLog(openStts );
194 | }
195 | //=============================================================================================================================
196 | void FtdiManager::disconnectFromPort()
197 | {
198 | emit stopReadTmr();
199 | emit onFtdiStateChanged(false);
200 | emit addLineToLog("Device disconected");
201 | qtFtDev2xxManager.callMethod(QByteArray("disconnectFunction").constData());
202 |
203 | createDeviceInfoList(true);
204 | }
205 | //=============================================================================================================================
206 | void FtdiManager::sendDataToPort(QString line, bool hexOut, int endLineIndx)
207 | {
208 | QString tmpStr(line);
209 | emit startReadTmr();
210 |
211 | if(hexOut){
212 | switch(endLineIndx){
213 | case 0: line.append("0D0A"); break;
214 | case 1: line.append("0D"); break;
215 | case 2: line.append("0A"); break;
216 | default: break;
217 | }
218 | }else{
219 |
220 | switch(endLineIndx){
221 | case 0: line.append("\r\n"); break;
222 | case 1: line.append("\r"); break;
223 | case 2: line.append("\n"); break;
224 | default: break;
225 | }
226 | }
227 |
228 |
229 | QAndroidJniEnvironment env;
230 | if(!hexOut)
231 | line = line.toLocal8Bit().toHex();
232 |
233 | if((line.size() % 2))
234 | line.prepend("0");
235 |
236 | QAndroidJniObject string2 = QAndroidJniObject::fromString(line);
237 |
238 | jint retVal = qtFtDev2xxManager.callMethod(QByteArray("sendData").constData(),
239 | QByteArray("(Ljava/lang/String;)I").constData(),
240 | string2.object()/*, arr*/);
241 | if (env->ExceptionCheck()) {
242 | // Handle exception here.
243 | emit addLineToLog("write exeption");
244 | qDebug() << "11 env =================================================== ";
245 | env->ExceptionClear();
246 | }
247 |
248 | if(!listHistoryCommand.contains(tmpStr.simplified().trimmed(), Qt::CaseInsensitive)){
249 | listHistoryCommand.prepend(tmpStr.simplified().trimmed());
250 | historyModel->prependCustomDevice(QList() << listHistoryCommand.first());
251 | saveSettings(QList(), 4); //save list last command
252 | }
253 |
254 | if(retVal >= 0){
255 | emit addLineToLog(tmpStr);
256 | }else{
257 | emit addLineToLog("line error write\r\n" + QString::number(retVal));
258 | disconnectFromPort();
259 | }
260 | }
261 | //=============================================================================================================================
262 | void FtdiManager::setThisHistoryFilter(const QString &str)
263 | {
264 | proxy_historyModel->setNewFileterStr(str);
265 | }
266 | //=============================================================================================================================
267 | void FtdiManager::delThisHistoryIndx(const int &indx)
268 | {
269 | int row = proxy_historyModel->mapToSource(proxy_historyModel->index(indx,0)).row();
270 | if(row < 0 || row > listHistoryCommand.size())
271 | return;
272 | historyModel->removeThisRow(row);
273 | listHistoryCommand.removeAt(row);
274 | saveSettings(QList(), 4);
275 | }
276 | //=============================================================================================================================
277 | void FtdiManager::saveQmlSett(const int &intVal, const int &key)
278 | {
279 | QSettings settings("Hello_ZB", "QtAndroidFtdiTerminal");
280 |
281 | switch(key){
282 | case 0: { settings.beginGroup("terminal"); settings.setValue("endSymb", intVal); break;}
283 | }
284 | settings.endGroup();
285 | }
286 | //=============================================================================================================================
287 | void FtdiManager::saveQmlSett(const bool &boolVal, const int &key)
288 | {
289 | QSettings settings("Hello_ZB", "QtAndroidFtdiTerminal");
290 |
291 | switch(key){
292 | case 0: { settings.beginGroup("terminal"); settings.setValue("hexOut", boolVal); break;}
293 |
294 | }
295 | settings.endGroup();
296 |
297 | }
298 | //=============================================================================================================================
299 | void FtdiManager::saveQmlSettRealVal(const qreal &realVal, const int &key)
300 | {
301 | QSettings settings("Hello_ZB", "QtAndroidFtdiTerminal");
302 |
303 | switch(key){
304 | case 0: { settings.beginGroup("sett"); settings.setValue("fontSize", realVal); break;}
305 |
306 | }
307 | settings.endGroup();
308 |
309 | }
310 | //=============================================================================================================================
311 | void FtdiManager::sendLineHexValidator( QString line)
312 | {
313 | line = line.simplified().trimmed().remove(" ");
314 | bool isValid = false;
315 | if(line.isEmpty()){
316 | isValid = true;
317 | }else{
318 | if(line.size()%2){
319 | isValid = false;
320 | }else{
321 |
322 | QString tmpStr = QByteArray::fromHex(line.toLocal8Bit()).toHex();
323 | isValid = (tmpStr.length() == line.length());
324 | }
325 | }
326 |
327 | emit sendLineHexIsValid(isValid);
328 | }
329 | //=============================================================================================================================
330 | void FtdiManager::onReadTmr()
331 | {
332 | if(readData())
333 | emit startReadTmr();
334 | else{
335 | disconnectFromPort();
336 |
337 | }
338 | }
339 | //=============================================================================================================================
340 | bool FtdiManager::readData()
341 | {
342 | jint bytesAvailable = qtFtDev2xxManager.callMethod(QByteArray("bytesAvailable").constData());
343 | QAndroidJniEnvironment env;
344 | if (env->ExceptionCheck()) {
345 | // Handle exception here.
346 | qDebug() << "11 env =================================================== ";
347 | emit addLineToLog("read errror");
348 |
349 | env->ExceptionClear();
350 | return false;
351 | }
352 |
353 | if(bytesAvailable < 0){
354 | return false;
355 | }
356 |
357 | if(bytesAvailable < 1)
358 | return true;
359 |
360 | QAndroidJniObject stringArray = qtFtDev2xxManager.callObjectMethod(QByteArray("readData").constData());
361 | if (env->ExceptionCheck()) {
362 | // Handle exception here.
363 | qDebug() << "11 env =================================================== ";
364 | emit addLineToLog("read errror");
365 |
366 | env->ExceptionClear();
367 | disconnectFromPort();
368 | return false;
369 | }
370 | QString readStr = stringArray.toString();
371 | if(readStr.isEmpty())
372 | return true;
373 |
374 | if((readStr.length()%2))
375 | readStr.prepend("0");
376 |
377 | readStr = QByteArray::fromHex(readStr.toLocal8Bit());
378 |
379 | if(!readStr.isEmpty())
380 | emit addLineToLog(readStr);
381 |
382 | return true;
383 | }
384 | //=============================================================================================================================
385 | QList FtdiManager::loadSettings(int key)
386 | {
387 | QSettings settings("Hello_ZB", "QtAndroidFtdiTerminal");
388 | QList list;
389 | switch(key){
390 | case 0: { //load all settings
391 | settings.beginGroup("uart");
392 | emit onConnectPageSettt(settings.value("dataBits", 0).toInt(),
393 | settings.value("stopBits", 0).toInt(),
394 | settings.value("parity", 0).toInt(),
395 | settings.value("flowCtrl", 0).toInt(),
396 | settings.value("baudRate", 3).toInt() );
397 |
398 | settings.endGroup();
399 |
400 | settings.beginGroup("terminal");
401 | emit onTerminalPageSettt(settings.value("endSymb", 0).toInt(), settings.value("hexOut", false).toBool());
402 | settings.endGroup();
403 |
404 | settings.beginGroup("sett");
405 | emit onSettPage(settings.value("fontSize", 0).toReal());
406 | settings.endGroup();
407 |
408 | settings.beginGroup("app");
409 | listHistoryCommand = settings.value("listHistoryCommand").toStringList();
410 | if(listHistoryCommand.isEmpty())
411 | listHistoryCommand = QString("+++ ATAD ATBD ATCH ATID ATNI ATSL ATSH ATVR ATHV ATAP ATSM ATND ATBD").split(' ');
412 | settings.endGroup();
413 |
414 | return list; }
415 |
416 | case 1:{
417 | settings.beginGroup("uart");
418 | list.append(settings.value("dataBits", 0));
419 | list.append(settings.value("stopBits", 0));
420 | list.append(settings.value("parity", 0));
421 | list.append(settings.value("flowCtrl", 0));
422 | list.append(settings.value("baudRate", 3));
423 |
424 | settings.endGroup();
425 | return list;}
426 | }
427 | return list;
428 | }
429 | //=============================================================================================================================
430 | void FtdiManager::saveSettings(QList list, int key)
431 | {
432 | QSettings settings("Hello_ZB", "QtAndroidFtdiTerminal");
433 | switch(key){
434 | case 0: { //save all settings
435 | settings.beginGroup("uart");
436 | if(list.size() != 8)
437 | return;
438 | settings.setValue("dataBits", list.at(0));
439 | settings.setValue("stopBits", list.at(1));
440 | settings.setValue("parity", list.at(2));
441 | settings.setValue("flowCtrl", list.at(3));
442 | settings.setValue("baudRate", list.at(4));
443 | settings.endGroup();
444 |
445 | settings.beginGroup("terminal");
446 | settings.setValue("endSymb", list.at(5));
447 | settings.setValue("hexOut", list.at(6));
448 | settings.endGroup();
449 |
450 | settings.beginGroup("sett");
451 | settings.setValue("fontSize", list.at(7));
452 | settings.endGroup();
453 |
454 | while(listHistoryCommand.size() > 1000)
455 | listHistoryCommand.removeLast();
456 |
457 | settings.beginGroup("app");
458 | settings.setValue("listHistoryCommand",listHistoryCommand);
459 | settings.endGroup();
460 |
461 | return ; }
462 |
463 | case 1:{
464 | settings.beginGroup("uart");
465 | if(list.size() != 5)
466 | return;
467 | settings.setValue("dataBits", list.at(0));
468 | settings.setValue("stopBits", list.at(1));
469 | settings.setValue("parity", list.at(2));
470 | settings.setValue("flowCtrl", list.at(3));
471 | settings.setValue("baudRate", list.at(4));
472 |
473 | settings.endGroup();
474 | return ;}
475 |
476 | case 2:{
477 | if(list.size() != 2)
478 | return;
479 | settings.beginGroup("terminal");
480 | settings.setValue("endSymb", list.at(0));
481 | settings.setValue("hexOut", list.at(1));
482 | settings.endGroup();
483 | return; }
484 |
485 | case 3:{
486 | if(list.size() != 1)
487 | return;
488 | settings.beginGroup("sett");
489 | settings.setValue("fontSize", list.at(0));
490 | settings.endGroup();
491 | return; }
492 |
493 | case 4:{
494 | while(listHistoryCommand.size() > 1000)
495 | listHistoryCommand.removeLast();
496 |
497 | settings.beginGroup("app");
498 | settings.setValue("listHistoryCommand",listHistoryCommand);
499 | settings.endGroup();
500 | return;}
501 | }
502 | }
503 | //=============================================================================================================================
504 |
--------------------------------------------------------------------------------
/ftdimanager.h:
--------------------------------------------------------------------------------
1 | #ifndef FTDIMANAGER_H
2 | #define FTDIMANAGER_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include "qmlitemmodel.h"
11 | #include "customproxy4qmlmodel.h"
12 |
13 | class FtdiManager : public QObject
14 | {
15 | Q_OBJECT
16 | public:
17 | explicit FtdiManager(QObject *parent = 0);
18 | QmlItemModel *deviceModel;
19 | QmlItemModel *historyModel;
20 |
21 | CustomProxy4QmlModel *proxy_historyModel;
22 |
23 |
24 | signals:
25 | void addLineToLog(QString);
26 |
27 | void startReadTmr();
28 |
29 | void stopReadTmr();
30 |
31 | void onFtdiStateChanged(bool);
32 |
33 | void onConnectPageSettt(int, int,int ,int,int);
34 |
35 | void onTerminalPageSettt(int,bool);
36 |
37 | void onSettPage(qreal);
38 |
39 | void setCurrntPortIndx(int);
40 |
41 | void sendLineHexIsValid(bool);
42 |
43 | public slots:
44 | void startJar();
45 |
46 |
47 | void onBtnPrssd();
48 |
49 | void createDeviceInfoList(bool onlyUpdate = false);
50 |
51 | void deviceStatus();
52 |
53 | void connectToOnePort();
54 |
55 | void connectToOnePort(int indx , int baudIndx, int dataIndx, int stopIndx, int parityIndx, int flowIndx);
56 |
57 | void disconnectFromPort();
58 |
59 | void sendDataToPort(QString line, bool hexOut, int endLineIndx);
60 |
61 | void setThisHistoryFilter(const QString &str);
62 |
63 | void delThisHistoryIndx(const int &indx);
64 |
65 | void saveQmlSett(const int &intVal, const int &key);
66 |
67 | void saveQmlSett(const bool &boolVal, const int &key);
68 |
69 |
70 | void saveQmlSettRealVal(const qreal &realVal, const int &key);
71 |
72 | void sendLineHexValidator(QString line);
73 |
74 | private slots:
75 | void onReadTmr();
76 |
77 | private:
78 | bool readData();
79 |
80 | QList loadSettings(int key);
81 | void saveSettings(QList list, int key);
82 |
83 |
84 |
85 | int bufLen;
86 |
87 | QAndroidJniObject qtFtDev2xxManager;
88 | QAndroidJniObject adnrActivity;
89 |
90 | QAndroidJniObject ftD2xx;
91 |
92 | QStringList listHistoryCommand;
93 |
94 | };
95 |
96 | #endif // FTDIMANAGER_H
97 |
--------------------------------------------------------------------------------
/katynko/.directory:
--------------------------------------------------------------------------------
1 | [Dolphin]
2 | PreviewsShown=true
3 | Timestamp=2015,9,3,16,23,56
4 | Version=3
5 | ViewMode=1
6 |
--------------------------------------------------------------------------------
/katynko/android_ft232.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/katynko/android_ft232.png
--------------------------------------------------------------------------------
/katynko/clear_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/katynko/clear_left.png
--------------------------------------------------------------------------------
/katynko/dashed_elmnt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/katynko/dashed_elmnt.png
--------------------------------------------------------------------------------
/katynko/dashed_elmnt_red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/katynko/dashed_elmnt_red.png
--------------------------------------------------------------------------------
/katynko/fontsizedefault_koffice.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/katynko/fontsizedefault_koffice.png
--------------------------------------------------------------------------------
/katynko/fontsizedown_koffice.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/katynko/fontsizedown_koffice.png
--------------------------------------------------------------------------------
/katynko/fontsizeup_koffice.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/katynko/fontsizeup_koffice.png
--------------------------------------------------------------------------------
/katynko/history.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/katynko/history.png
--------------------------------------------------------------------------------
/katynko/key_enter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/katynko/key_enter.png
--------------------------------------------------------------------------------
/katynko/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/katynko/settings.png
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include "ftdimanager.h"
7 |
8 | int main(int argc, char *argv[])
9 | {
10 | QApplication app(argc, argv);
11 |
12 | FtdiManager ftdiManager;
13 |
14 | QQmlApplicationEngine engine;
15 |
16 | engine.rootContext()->setContextProperty("ftdiManager", &ftdiManager);
17 | engine.rootContext()->setContextProperty("deviceModel", ftdiManager.deviceModel);
18 | engine.rootContext()->setContextProperty("historyModel", ftdiManager.proxy_historyModel);
19 |
20 | //QtAndroid::androidActivity().callMethod()
21 | engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
22 |
23 | if(!engine.rootObjects().isEmpty()){
24 |
25 | qDebug() << "one line";
26 | QObject *item = engine.rootObjects().first();
27 |
28 | if(item)
29 | qDebug() << "item done";
30 | else
31 | return 100;
32 |
33 | QObject::connect(&ftdiManager, SIGNAL(addLineToLog(QString)), item, SIGNAL(addToLog(QString)));
34 | QObject::connect(&ftdiManager, SIGNAL(onFtdiStateChanged(bool)), item, SIGNAL(connStateChanged(bool)));
35 | QObject::connect(&ftdiManager, SIGNAL(onConnectPageSettt(int,int, int,int ,int)), item, SIGNAL(connectPageSettt(int, int,int ,int, int)));
36 | QObject::connect(&ftdiManager, SIGNAL(onTerminalPageSettt(int,bool)), item, SIGNAL(terminalPageSettt(int,bool)));
37 | QObject::connect(&ftdiManager, SIGNAL(onSettPage(qreal)), item, SIGNAL(settPage(qreal)));
38 | QObject::connect(&ftdiManager, SIGNAL(setCurrntPortIndx(int)), item, SIGNAL(setCurrntPortIndx(int)));
39 | QObject::connect(&ftdiManager, SIGNAL(sendLineHexIsValid(bool)), item, SIGNAL( sendLineHexIsValid(bool)));
40 |
41 | ftdiManager.startJar();
42 | return app.exec();
43 | }else{
44 | QMessageBox::critical(0,"AndroidFtdi", "Can't load qml content. Check your installation dir.");
45 | return 3;
46 | }
47 |
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/main.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.4
2 | import QtQuick.Controls 1.3
3 | import QtQuick.Window 2.2
4 | import QtQuick.Dialogs 1.2
5 |
6 | ApplicationWindow {
7 | title: qsTr("QtAndroidFTDI Terminal")
8 | width: 640
9 | height: 480
10 | visible: true
11 | property bool ftdiIsConnected: false
12 |
13 | signal addToLog(string mess)
14 | signal connStateChanged(bool isConnected)
15 |
16 | signal connectPageSettt(int dataIndx, int stopIndx, int parityIndx, int flowIndx, int baudIndx);
17 |
18 | signal terminalPageSettt(int endLineIndx, bool hexOut);
19 |
20 | signal settPage(real defH);
21 |
22 | signal setCurrntPortIndx(int portIndx);
23 |
24 | signal sendLineHexIsValid(bool isValid);
25 |
26 |
27 | onSetCurrntPortIndx: {
28 | cpPage.setCurrntPortIndx(portIndx);
29 | }
30 |
31 |
32 | onConnectPageSettt: {
33 | cpPage.connectPageSettt(dataIndx, stopIndx, parityIndx, flowIndx, baudIndx);
34 | }
35 |
36 | onTerminalPageSettt: {
37 | tpPage.terminalPageSettt(endLineIndx, hexOut);
38 | }
39 |
40 | onSettPage: {
41 | if(defH > Screen.logicalPixelDensity && (Screen.width < Screen.height ?
42 | width < (Screen.width * 0.25) :
43 | height < (Screen.height * 0.25)))
44 | defHeightFontPixel = defH
45 | }
46 |
47 | onSendLineHexIsValid: {
48 | tpPage.sendLineHexIsValid(isValid);
49 | }
50 |
51 | property real defHeightFontPixel: Screen.pixelDensity * 3.8;
52 | property real defHeightPushButton: defHeightFontPixel * 1.6
53 | property real defHeightPushButtonSmll: defHeightFontPixel * 1.4
54 | property real defHeightFontPixelLog: defHeightFontPixel * 0.6;
55 | property real defHeightLine: defHeightFontPixel * 0.1
56 |
57 |
58 | property string defColorBackground: "#efefef"
59 | property string defColorTop: "#aaaaaa"
60 | property string defColorText: "black"
61 | property string defColorButtonFill: "#0d670d"
62 | property string defColorButtonText: defColorBackground
63 | property string defColorLine: "#gray"
64 |
65 | property int defRadiusButton: 4;
66 |
67 | property real defMargins: defHeightFontPixel * 0.2
68 |
69 |
70 | onConnStateChanged: {
71 | ftdiIsConnected = isConnected
72 | if(isConnected){
73 | changeStackViewPage(1)
74 | }
75 | }
76 |
77 | onAddToLog: {
78 | tpPage.appendPlainText(mess)
79 | }
80 |
81 |
82 | function changeStackViewPage(indx){
83 | switch(indx){
84 | case 0: stackView.push({item: cpPage, visible: true}); break;
85 | case 1: stackView.push({item: tpPage, visible: true}); break;
86 | case 2: stackView.push({item: spPage, visible: true});break;
87 | case 3: stackView.push({item: hpPage, visible: true});break;
88 |
89 | default: break;
90 | }
91 | }
92 |
93 | Rectangle {
94 | id: root
95 | anchors.fill: parent
96 | color: defColorBackground
97 |
98 |
99 | Row{
100 | id: rtTop
101 |
102 | anchors.left: parent.left
103 | anchors.top: parent.top
104 | anchors.right: parent.right
105 | height: defHeightPushButton
106 |
107 | anchors.margins: defMargins
108 |
109 | spacing: defMargins
110 |
111 | CustomPushButton{
112 | id: cpbConnectPage
113 | height: parent.height
114 | text: qsTr("Device")
115 |
116 | width: (parent.width / 3 ) - parent.spacing
117 |
118 | radius: defRadiusButton
119 | color: defColorButtonText
120 | fillColor: defColorButtonFill
121 | textSize: defHeightFontPixel
122 | onAnimationDone: {
123 | changeStackViewPage(0);
124 | }
125 | enabled: false
126 | }
127 |
128 | CustomPushButton{
129 | id: cpbTerminalPage
130 | height: parent.height
131 | text: qsTr("Terminal")
132 | width: cpbConnectPage.width
133 | radius: defRadiusButton
134 | color: defColorButtonText
135 | fillColor: defColorButtonFill
136 | textSize: defHeightFontPixel
137 | onAnimationDone: {
138 | changeStackViewPage(1)
139 | }
140 | enabled: true
141 | }
142 |
143 | Item{
144 | height: parent.height
145 | width: parent.width - cpbConnectPage.width * 2 - cpbSettingsPage.width - 3 * parent.spacing - 2 * defMargins
146 | }
147 |
148 | CustomPushButton{
149 | id: cpbSettingsPage
150 | height: parent.height
151 | text: ""
152 | imgSource: "qrc:/img/katynko/settings.png"
153 | radius: defRadiusButton
154 | color: defColorButtonText
155 | fillColor: defColorButtonFill
156 | textSize: defHeightFontPixel
157 | width: height//cpbConnectPage.width
158 | // onIAmReleased: videoS.refreshDevList();
159 | onAnimationDone: {
160 | changeStackViewPage(2)
161 | }
162 | enabled: true
163 | }
164 |
165 | }
166 |
167 |
168 | StackView{
169 | id: stackView
170 | anchors.left: parent.left
171 | anchors.top: rtTop.bottom
172 | anchors.right: parent.right
173 | anchors.bottom: parent.bottom
174 | visible: true
175 | anchors.margins: defMargins
176 | initialItem: cpPage;
177 |
178 | focus: true
179 | Keys.onReleased: if (event.key === Qt.Key_Back && stackView.depth > 1) {
180 | stackView.pop();
181 | event.accepted = true;
182 | }
183 |
184 | onCurrentItemChanged: {
185 | cpbSettingsPage.enabled = !(currentItem === spPage);
186 | cpbTerminalPage.enabled = !((currentItem === tpPage) || (currentItem === hpPage));
187 | cpbConnectPage.enabled = !(currentItem === cpPage);
188 |
189 |
190 | }
191 |
192 | }
193 |
194 | ConnectPage{
195 | id: cpPage
196 | visible: true
197 | }
198 |
199 | TerminalPage{
200 | id: tpPage
201 | visible: false
202 | }
203 |
204 | SettingsPage{
205 | id: spPage
206 | visible: false
207 | }
208 |
209 | HistoryPage{
210 | id: hpPage
211 | visible: false
212 | }
213 |
214 | }
215 | }
216 |
--------------------------------------------------------------------------------
/qml.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | main.qml
4 | CustomTextEdit.qml
5 | ConnectPage.qml
6 | TerminalPage.qml
7 | SettingsPage.qml
8 | CustomPushButton.qml
9 | HistoryPage.qml
10 | ScrollBarVertical.qml
11 |
12 |
13 |
--------------------------------------------------------------------------------
/qmlitemmodel.cpp:
--------------------------------------------------------------------------------
1 | #include "qmlitemmodel.h"
2 |
3 | //=============================================================================
4 | CustomDevice::CustomDevice(const int &firstRole, const int &maxCount, const QList &list)
5 | {
6 | this->firtsRole = firstRole;
7 | for(int i = firstRole, j = 0, jMax = list.size(); i < 0xffff && j < maxCount && j < jMax; i++, j++){
8 | hashIntVar.insert(i,list.at(j));
9 | }
10 | }
11 |
12 | //=============================================================================
13 | QVariant CustomDevice::roleData(int role) const
14 | {
15 | if(role < firtsRole)
16 | return QVariant();
17 | return hashIntVar.value(role, QVariant());
18 | }
19 | //=============================================================================
20 | QHash CustomDevice::rolesData() const
21 | {
22 | return hashIntVar;
23 | }
24 | //=============================================================================
25 |
26 | QmlItemModel::QmlItemModel(QStringList listRoleName, int firstRole, QObject *parent) :
27 | QAbstractListModel(parent), firstRole(firstRole)
28 | {
29 |
30 | maxCount = listRoleName.size();
31 | for(int j = firstRole, i = 0; i < maxCount; i++ )
32 | m_roleNames.insert(j++,listRoleName.at(i).toLocal8Bit());
33 | }
34 | //=============================================================================
35 | void QmlItemModel::addCustomDevice(const QList &list)
36 | {
37 | beginInsertRows(QModelIndex(), rowCount(), rowCount());
38 | m_device.append(CustomDevice(firstRole,maxCount, list));
39 | endInsertRows();
40 | }
41 | //=============================================================================
42 | void QmlItemModel::prependCustomDevice(const QList &list)
43 | {
44 | beginInsertRows(QModelIndex(), 0, 0);
45 | m_device.prepend(CustomDevice(firstRole,maxCount, list));
46 | endInsertRows();
47 | }
48 | //=============================================================================
49 | int QmlItemModel::rowCount(const QModelIndex &parent) const
50 | {
51 | Q_UNUSED(parent);
52 | return m_device.count();
53 | }
54 | //=============================================================================
55 | QVariant QmlItemModel::data(const QModelIndex &index, int role) const
56 | {
57 | if(index.row() < 0 || index.row() >= m_device.count())
58 | return QVariant();
59 |
60 | const CustomDevice dev = m_device.at(index.row());
61 | return dev.roleData(role);
62 | }
63 | //=============================================================================
64 | QVariant QmlItemModel::dataRow(const int &row, int role) const
65 | {
66 | if(row < 0 || row >= m_device.count())
67 | return QVariant();
68 |
69 | const CustomDevice dev = m_device.at(row);
70 | return dev.roleData(role);
71 |
72 | // const VideoDevice &videoDev = m_device.at(row);
73 |
74 | // switch(role){
75 | // case IpRole: return videoDev.ipStr();
76 | // case TcpPortRole: return videoDev.tcpPort();
77 | // case UsrNameRole: return videoDev.usrName();
78 | // case PasswdRole: return videoDev.passwd();
79 | // case DeviceFirmwareRole: return videoDev.deviceFirmware();
80 | // }
81 | // return QVariant();
82 |
83 | }
84 | //=============================================================================
85 | void QmlItemModel::removeThisRow(const int &row)
86 | {
87 | if(row < 0 || row >= m_device.count())
88 | return;
89 | beginRemoveRows(QModelIndex(),row,row);
90 | m_device.removeAt(row);
91 | endRemoveRows();
92 | }
93 | //=============================================================================
94 | void QmlItemModel::clearAllData()
95 | {
96 | // qDebug() << "m_device size = " << m_device.size();
97 | beginRemoveRows(QModelIndex(), 0, rowCount());
98 | m_device.clear();
99 | endRemoveRows();
100 | }
101 | //=============================================================================
102 | void QmlItemModel::replaceData(const int &row, const int &role, const QVariant &dataVar)
103 | {
104 | if(row < 0 || row >= m_device.count())
105 | return;
106 |
107 | beginRemoveRows(QModelIndex(),row,row);
108 | CustomDevice dev = m_device.takeAt(row);
109 | endRemoveRows();
110 |
111 | QHash devHash = dev.rolesData();
112 |
113 | if(devHash.contains(role))
114 | devHash.insert(role,dataVar);
115 |
116 | QList listKeys = devHash.keys();
117 | qSort(listKeys);
118 |
119 | QList listVar;
120 |
121 | while(!listKeys.isEmpty())
122 | listVar.append(devHash.value(listKeys.takeFirst()));
123 |
124 | beginInsertRows(QModelIndex(), row,row);
125 | m_device.insert(row, CustomDevice(firstRole,maxCount, listVar));
126 | endInsertRows();
127 |
128 | }
129 | //=============================================================================
130 | QList QmlItemModel::dataRowInList(const int &row)
131 | {
132 | QList retList;
133 | if(row < 0 || row >= m_device.count())
134 | return retList;
135 |
136 | for(int role = firstRole, i = 0; i < maxCount ; i++, role++){
137 | const CustomDevice dev = m_device.at(row);
138 | retList.append(dev.roleData(role));
139 | }
140 |
141 | return retList;
142 | }
143 | //=============================================================================
144 | QHash QmlItemModel::roleNames() const
145 | {
146 | // QHash roles;
147 | // roles[IpRole] = "deviceIp";
148 | // roles[TcpPortRole] = "devPort";
149 | // roles[UsrNameRole] = "usrName";
150 | // roles[PasswdRole] = "psswrd";
151 | // roles[DeviceFirmwareRole] = "deviceFirmware";
152 | // return roles;
153 | return m_roleNames;
154 | }
155 | //=============================================================================
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
--------------------------------------------------------------------------------
/qmlitemmodel.h:
--------------------------------------------------------------------------------
1 | #ifndef QMLITEMMODEL_H
2 | #define QMLITEMMODEL_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | class CustomDevice
9 | {
10 | public:
11 | CustomDevice(const int &firstRole, const int &maxCount, const QList &list);
12 |
13 | QVariant roleData(int role) const;
14 |
15 | QHash rolesData() const;
16 |
17 | private:
18 | QHash hashIntVar;
19 | int firtsRole;
20 | };
21 |
22 | class QmlItemModel : public QAbstractListModel
23 | {
24 | Q_OBJECT
25 | public:
26 |
27 |
28 | QmlItemModel(QStringList listRoleName, int firstRole = Qt::UserRole + 1, QObject *parent = 0);
29 |
30 | void addCustomDevice(const QList &list);
31 |
32 | void prependCustomDevice(const QList &list);
33 |
34 |
35 | int rowCount(const QModelIndex &parent = QModelIndex()) const;
36 |
37 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
38 |
39 | QVariant dataRow(const int &row, int role = Qt::DisplayRole) const;
40 |
41 | void removeThisRow(const int &row);
42 |
43 | void clearAllData();
44 |
45 | void replaceData(const int &row, const int &role , const QVariant &dataVar);
46 |
47 | QList dataRowInList(const int &row);
48 |
49 |
50 | protected:
51 | QHash roleNames() const;
52 |
53 | private:
54 | QList m_device;
55 | QHash m_roleNames;
56 | int firstRole;
57 | int maxCount;
58 |
59 | };
60 |
61 | #endif // QMLITEMMODEL_H
62 |
--------------------------------------------------------------------------------
/res.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | katynko/clear_left.png
4 | katynko/dashed_elmnt_red.png
5 | katynko/dashed_elmnt.png
6 | katynko/settings.png
7 | katynko/key_enter.png
8 | katynko/fontsizedefault_koffice.png
9 | katynko/fontsizedown_koffice.png
10 | katynko/fontsizeup_koffice.png
11 | katynko/history.png
12 |
13 |
14 |
--------------------------------------------------------------------------------
/screenshot/.directory:
--------------------------------------------------------------------------------
1 | [Dolphin]
2 | PreviewsShown=true
3 | Timestamp=2016,2,29,17,38,5
4 | Version=3
5 | ViewMode=1
6 |
--------------------------------------------------------------------------------
/screenshot/Screenshot_2016-02-29-17-12-55.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/screenshot/Screenshot_2016-02-29-17-12-55.png
--------------------------------------------------------------------------------
/screenshot/Screenshot_2016-02-29-17-13-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/screenshot/Screenshot_2016-02-29-17-13-02.png
--------------------------------------------------------------------------------
/screenshot/Screenshot_2016-02-29-17-15-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/screenshot/Screenshot_2016-02-29-17-15-32.png
--------------------------------------------------------------------------------
/screenshot/Screenshot_2016-02-29-17-33-36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/screenshot/Screenshot_2016-02-29-17-33-36.png
--------------------------------------------------------------------------------
/screenshot/android settings1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/screenshot/android settings1.png
--------------------------------------------------------------------------------
/screenshot/qt settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HelloZB/QtAndroidFTDI/d3ee9c7e51aafa4962a5bb6f3148faa352b4aa5b/screenshot/qt settings.png
--------------------------------------------------------------------------------
/untitled.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = app
2 |
3 | QT += qml quick widgets androidextras
4 |
5 | TARGET = Terminalko
6 |
7 | SOURCES += main.cpp \
8 | ftdimanager.cpp \
9 | qmlitemmodel.cpp \
10 | customproxy4qmlmodel.cpp
11 |
12 | RESOURCES += qml.qrc \
13 | res.qrc
14 |
15 | # Additional import path used to resolve QML modules in Qt Creator's code model
16 | QML_IMPORT_PATH =
17 |
18 | # Default rules for deployment.
19 | include(deployment.pri)
20 |
21 |
22 | HEADERS += \
23 | ftdimanager.h \
24 | qmlitemmodel.h \
25 | customproxy4qmlmodel.h
26 |
27 | DISTFILES += \
28 | android/AndroidManifest.xml \
29 | android/gradle/wrapper/gradle-wrapper.jar \
30 | android/gradlew \
31 | android/res/values/libs.xml \
32 | android/build.gradle \
33 | android/gradle/wrapper/gradle-wrapper.properties \
34 | android/gradlew.bat\
35 | android/src/*
36 |
37 | ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
38 |
--------------------------------------------------------------------------------
/untitled.pro.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | EnvironmentId
7 | {2cc0458a-0814-4662-a33c-093d765b2485}
8 |
9 |
10 | ProjectExplorer.Project.ActiveTarget
11 | 0
12 |
13 |
14 | ProjectExplorer.Project.EditorSettings
15 |
16 | true
17 | false
18 | true
19 |
20 | Cpp
21 |
22 | CppGlobal
23 |
24 |
25 |
26 | QmlJS
27 |
28 | QmlJSGlobal
29 |
30 |
31 | 2
32 | UTF-8
33 | false
34 | 4
35 | false
36 | 80
37 | true
38 | true
39 | 1
40 | true
41 | false
42 | 0
43 | true
44 | 0
45 | 8
46 | true
47 | 1
48 | true
49 | true
50 | true
51 | false
52 |
53 |
54 |
55 | ProjectExplorer.Project.PluginSettings
56 |
57 |
58 |
59 | ProjectExplorer.Project.Target.0
60 |
61 | Android for armeabi-v7a (GCC 4.9, Qt 5.5.0)
62 | Android for armeabi-v7a (GCC 4.9, Qt 5.5.0)
63 | {a5e2cca9-5124-4751-b990-0a15b1378ec7}
64 | 1
65 | 0
66 | 0
67 |
68 | /home/hello_zb/My_Prog/Qt5_progs/TESTS/SerialPort/AndroidFTDI/build-untitled-Android_for_armeabi_v7a_GCC_4_9_Qt_5_5_0-Debug
69 |
70 |
71 | true
72 | qmake
73 |
74 | QtProjectManager.QMakeBuildStep
75 | true
76 |
77 | false
78 | false
79 | false
80 |
81 |
82 | true
83 | Make
84 |
85 | Qt4ProjectManager.MakeStep
86 |
87 | -w
88 | -r
89 |
90 | false
91 |
92 |
93 |
94 |
95 | true
96 | Copy application data
97 |
98 | Qt4ProjectManager.AndroidPackageInstallationStep
99 |
100 |
101 | android-22
102 |
103 | true
104 | Build Android APK
105 |
106 | QmakeProjectManager.AndroidBuildApkStep
107 | 2
108 | false
109 | false
110 |
111 | 4
112 | Build
113 |
114 | ProjectExplorer.BuildSteps.Build
115 |
116 |
117 |
118 | true
119 | Make
120 |
121 | Qt4ProjectManager.MakeStep
122 |
123 | -w
124 | -r
125 |
126 | true
127 | clean
128 |
129 |
130 | 1
131 | Clean
132 |
133 | ProjectExplorer.BuildSteps.Clean
134 |
135 | 2
136 | false
137 |
138 | Debug
139 |
140 | Qt4ProjectManager.Qt4BuildConfiguration
141 | 2
142 | true
143 |
144 |
145 | /home/hello_zb/My_Prog/Qt5_progs/TESTS/SerialPort/AndroidFTDI/build-untitled-Android_for_armeabi_v7a_GCC_4_9_Qt_5_5_0-Release
146 |
147 |
148 | true
149 | qmake
150 |
151 | QtProjectManager.QMakeBuildStep
152 | false
153 |
154 | false
155 | false
156 | false
157 |
158 |
159 | true
160 | Make
161 |
162 | Qt4ProjectManager.MakeStep
163 |
164 | -w
165 | -r
166 |
167 | false
168 |
169 |
170 |
171 |
172 | true
173 | Copy application data
174 |
175 | Qt4ProjectManager.AndroidPackageInstallationStep
176 |
177 |
178 | android-22
179 | /home/hello_zb/Dropbox/AndroidIntekKlu4yk.keystore
180 | true
181 | Build Android APK
182 |
183 | QmakeProjectManager.AndroidBuildApkStep
184 | 2
185 | false
186 | false
187 |
188 | 4
189 | Build
190 |
191 | ProjectExplorer.BuildSteps.Build
192 |
193 |
194 |
195 | true
196 | Make
197 |
198 | Qt4ProjectManager.MakeStep
199 |
200 | -w
201 | -r
202 |
203 | true
204 | clean
205 |
206 |
207 | 1
208 | Clean
209 |
210 | ProjectExplorer.BuildSteps.Clean
211 |
212 | 2
213 | false
214 |
215 | Release
216 |
217 | Qt4ProjectManager.Qt4BuildConfiguration
218 | 0
219 | true
220 |
221 | 2
222 |
223 |
224 |
225 | true
226 | Deploy to Android device
227 |
228 | Qt4ProjectManager.AndroidDeployQtStep
229 | false
230 |
231 | 1
232 | Deploy
233 |
234 | ProjectExplorer.BuildSteps.Deploy
235 |
236 | 1
237 | Deploy to Android device
238 | Deploy to Android device
239 | Qt4ProjectManager.AndroidDeployConfiguration2
240 |
241 | 1
242 |
243 | ZX1D322LVT
244 |
245 |
246 | false
247 | 1000
248 |
249 | true
250 |
251 | false
252 | false
253 | false
254 | false
255 | true
256 | 0.01
257 | 10
258 | true
259 | 1
260 | 25
261 |
262 | 1
263 | true
264 | false
265 | true
266 | valgrind
267 |
268 | 0
269 | 1
270 | 2
271 | 3
272 | 4
273 | 5
274 | 6
275 | 7
276 | 8
277 | 9
278 | 10
279 | 11
280 | 12
281 | 13
282 | 14
283 |
284 | untitled
285 |
286 | Qt4ProjectManager.AndroidRunConfiguration:/home/hello_zb/My_Prog/Qt5_progs/TESTS/SerialPort/AndroidFTDI/untitled/untitled.pro
287 | untitled.pro
288 | 3768
289 | false
290 | true
291 | false
292 | false
293 | true
294 |
295 | 1
296 |
297 |
298 |
299 | ProjectExplorer.Project.TargetCount
300 | 1
301 |
302 |
303 | ProjectExplorer.Project.Updater.FileVersion
304 | 18
305 |
306 |
307 | Version
308 | 18
309 |
310 |
311 |
--------------------------------------------------------------------------------