mirror of
https://github.com/Serial-Studio/Serial-Studio.git
synced 2025-01-31 17:42:55 +08:00
Add network controls
This commit is contained in:
parent
3a5d664ad1
commit
a9ad58b62e
@ -120,8 +120,12 @@ RESOURCES += \
|
||||
assets/assets.qrc
|
||||
|
||||
DISTFILES += \
|
||||
assets/qml/SetupPanes/Network.qml \
|
||||
assets/qml/SetupPanes/Serial.qml \
|
||||
assets/qml/SetupPanes/Settings.qml \
|
||||
assets/qml/Widgets/*.qml \
|
||||
assets/qml/Windows/*.qml \
|
||||
assets/qml/SetupPanes/*.qml \
|
||||
assets/qml/*.qml
|
||||
|
||||
TRANSLATIONS += \
|
||||
|
@ -85,5 +85,8 @@
|
||||
<file>icons/scroll-top.svg</file>
|
||||
<file>icons/scroll-up.svg</file>
|
||||
<file>qml/Widgets/SimpleDial.qml</file>
|
||||
<file>qml/SetupPanes/Network.qml</file>
|
||||
<file>qml/SetupPanes/Serial.qml</file>
|
||||
<file>qml/SetupPanes/Settings.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
127
assets/qml/SetupPanes/Network.qml
Normal file
127
assets/qml/SetupPanes/Network.qml
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Alex Spataru <https://github.com/alex-spataru>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
Control {
|
||||
id: root
|
||||
|
||||
//
|
||||
// Access to properties
|
||||
//
|
||||
property alias port: _portText.text
|
||||
property alias address: _ipText.text
|
||||
property alias socketType: _typeCombo.currentIndex
|
||||
|
||||
//
|
||||
// Layout
|
||||
//
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing / 2
|
||||
|
||||
GridLayout {
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// Socket type
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
text: qsTr("Socket type") + ":"
|
||||
} ComboBox {
|
||||
id: _typeCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Network.socketTypes
|
||||
currentIndex: Cpp_IO_Network.socketTypeIndex
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Network.socketTypeIndex)
|
||||
Cpp_IO_Network.socketTypeIndex = currentIndex
|
||||
}
|
||||
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
}
|
||||
|
||||
//
|
||||
// Address
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
text: qsTr("IP Address") + ":"
|
||||
} TextField {
|
||||
id: _ipText
|
||||
Layout.fillWidth: true
|
||||
placeholderText: Cpp_IO_Network.defaultHost
|
||||
text: Cpp_IO_Network.host
|
||||
onTextChanged: {
|
||||
if (Cpp_IO_Network.host !== text)
|
||||
Cpp_IO_Network.host = text
|
||||
}
|
||||
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
}
|
||||
|
||||
//
|
||||
// Port
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
text: qsTr("Port") + ":"
|
||||
} TextField {
|
||||
id: _portText
|
||||
Layout.fillWidth: true
|
||||
text: Cpp_IO_Network.port
|
||||
placeholderText: Cpp_IO_Network.defaultPort
|
||||
onTextChanged: {
|
||||
if (Cpp_IO_Network.port !== text)
|
||||
Cpp_IO_Network.port = text
|
||||
}
|
||||
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Vertical spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
210
assets/qml/SetupPanes/Serial.qml
Normal file
210
assets/qml/SetupPanes/Serial.qml
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Alex Spataru <https://github.com/alex-spataru>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
Control {
|
||||
id: root
|
||||
|
||||
//
|
||||
// Access to properties
|
||||
//
|
||||
property alias port: _portCombo.currentIndex
|
||||
property alias baudRate: _baudCombo.currentIndex
|
||||
property alias dataBits: _dataCombo.currentIndex
|
||||
property alias parity: _parityCombo.currentIndex
|
||||
property alias flowControl: _flowCombo.currentIndex
|
||||
property alias stopBits: _stopBitsCombo.currentIndex
|
||||
|
||||
//
|
||||
// Update listbox models when translation is changed
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Misc_Translator
|
||||
function onLanguageChanged() {
|
||||
var oldParityIndex = _parityCombo.currentIndex
|
||||
var oldFlowControlIndex = _flowCombo.currentIndex
|
||||
|
||||
_parityCombo.model = Cpp_IO_Serial.parityList
|
||||
_flowCombo.model = Cpp_IO_Serial.flowControlList
|
||||
|
||||
_parityCombo.currentIndex = oldParityIndex
|
||||
_flowCombo.currentIndex = oldFlowControlIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Control layout
|
||||
//
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing / 2
|
||||
|
||||
//
|
||||
// Controls
|
||||
//
|
||||
GridLayout {
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// COM port selector
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
text: qsTr("COM Port") + ":"
|
||||
} ComboBox {
|
||||
id: _portCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.portList
|
||||
currentIndex: Cpp_IO_Serial.portIndex
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Serial.portIndex)
|
||||
Cpp_IO_Serial.portIndex = currentIndex
|
||||
}
|
||||
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
}
|
||||
|
||||
//
|
||||
// Baud rate selector
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
text: qsTr("Baud Rate") + ":"
|
||||
} ComboBox {
|
||||
id: _baudCombo
|
||||
editable: true
|
||||
currentIndex: 4
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.baudRateList
|
||||
|
||||
validator: IntValidator {
|
||||
bottom: 1
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
if (find(editText) === -1)
|
||||
Cpp_IO_Serial.appendBaudRate(editText)
|
||||
}
|
||||
|
||||
onCurrentTextChanged: {
|
||||
var value = currentText
|
||||
Cpp_IO_Serial.baudRate = value
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.minimumHeight: app.spacing / 2
|
||||
Layout.maximumHeight: app.spacing / 2
|
||||
} Item {
|
||||
Layout.minimumHeight: app.spacing / 2
|
||||
Layout.maximumHeight: app.spacing / 2
|
||||
}
|
||||
|
||||
//
|
||||
// Data bits selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Data Bits") + ":"
|
||||
} ComboBox {
|
||||
id: _dataCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.dataBitsList
|
||||
currentIndex: Cpp_IO_Serial.dataBitsIndex
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.dataBitsIndex !== currentIndex)
|
||||
Cpp_IO_Serial.dataBitsIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Parity selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Parity") + ":"
|
||||
} ComboBox {
|
||||
id: _parityCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.parityList
|
||||
currentIndex: Cpp_IO_Serial.parityIndex
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.parityIndex !== currentIndex)
|
||||
Cpp_IO_Serial.parityIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Stop bits selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Stop Bits") + ":"
|
||||
} ComboBox {
|
||||
id: _stopBitsCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.stopBitsList
|
||||
currentIndex: Cpp_IO_Serial.stopBitsIndex
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.stopBitsIndex !== currentIndex)
|
||||
Cpp_IO_Serial.stopBitsIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Flow control selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Flow Control") + ":"
|
||||
} ComboBox {
|
||||
id: _flowCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.flowControlList
|
||||
currentIndex: Cpp_IO_Serial.flowControlIndex
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.flowControlIndex !== currentIndex)
|
||||
Cpp_IO_Serial.flowControlIndex = currentIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Vertical spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
105
assets/qml/SetupPanes/Settings.qml
Normal file
105
assets/qml/SetupPanes/Settings.qml
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Alex Spataru <https://github.com/alex-spataru>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
Control {
|
||||
id: root
|
||||
|
||||
//
|
||||
// Access to properties
|
||||
//
|
||||
property alias endSequence: _endSequence.text
|
||||
property alias language: _langCombo.currentIndex
|
||||
property alias startSequence: _startSequence.text
|
||||
|
||||
//
|
||||
// Layout
|
||||
//
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing / 2
|
||||
|
||||
//
|
||||
// Controls
|
||||
//
|
||||
GridLayout {
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// Language selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Language") + ":"
|
||||
} ComboBox {
|
||||
id: _langCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_Misc_Translator.availableLanguages
|
||||
onCurrentIndexChanged: Cpp_Misc_Translator.setLanguage(currentIndex)
|
||||
}
|
||||
|
||||
//
|
||||
// Start sequence
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Start sequence") + ": "
|
||||
} TextField {
|
||||
id: _startSequence
|
||||
Layout.fillWidth: true
|
||||
placeholderText: "/*"
|
||||
text: "/*"
|
||||
onTextChanged: {
|
||||
if (text !== Cpp_IO_Manager.startSequence)
|
||||
Cpp_IO_Manager.startSequence = text
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// End sequence
|
||||
//
|
||||
Label {
|
||||
text: qsTr("End sequence") + ": "
|
||||
} TextField {
|
||||
id: _endSequence
|
||||
Layout.fillWidth: true
|
||||
placeholderText: "*/"
|
||||
text: "*/"
|
||||
onTextChanged: {
|
||||
if (text !== Cpp_IO_Manager.finishSequence)
|
||||
Cpp_IO_Manager.finishSequence = text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Vertical spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
@ -48,7 +48,6 @@ Control {
|
||||
// Clears console output
|
||||
//
|
||||
function clearConsole() {
|
||||
console.log("clear console")
|
||||
Cpp_IO_Console.clear()
|
||||
textEdit.clear()
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import Qt.labs.settings 1.0
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import "../Widgets" as Widgets
|
||||
import "../SetupPanes" as SetupPanes
|
||||
|
||||
Control {
|
||||
id: root
|
||||
@ -39,35 +40,36 @@ Control {
|
||||
// Save settings
|
||||
//
|
||||
Settings {
|
||||
category: "Setup"
|
||||
property alias dmAuto: commAuto.checked
|
||||
property alias dmManual: commManual.checked
|
||||
property alias dmParity: parity.currentIndex
|
||||
property alias dmCsvExport: csvLogging.checked
|
||||
property alias dmStopBits: stopBits.currentIndex
|
||||
property alias dmDataBits: dataBits.currentIndex
|
||||
property alias dmBaudValue: baudRate.currentIndex
|
||||
property alias dmFlowControl: flowControl.currentIndex
|
||||
property alias dmStartSequence: startSeqText.text
|
||||
property alias dmEndSequence: endSeqText.text
|
||||
property alias appLanguage: languageCombo.currentIndex
|
||||
}
|
||||
//
|
||||
// Misc settings
|
||||
//
|
||||
property alias auto: commAuto.checked
|
||||
property alias manual: commManual.checked
|
||||
property alias csvExport: csvLogging.checked
|
||||
property alias tabIndex: tab.currentIndex
|
||||
|
||||
//
|
||||
// Update listbox models when translation is changed
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Misc_Translator
|
||||
function onLanguageChanged() {
|
||||
var oldParityIndex = parity.currentIndex
|
||||
var oldFlowControlIndex = flowControl.currentIndex
|
||||
//
|
||||
// Serial settings
|
||||
//
|
||||
property alias baudRate: serial.baudRate
|
||||
property alias stopBits: serial.stopBits
|
||||
property alias parity: serial.parity
|
||||
property alias flowControl: serial.flowControl
|
||||
property alias dataBits: serial.dataBits
|
||||
|
||||
parity.model = Cpp_IO_Serial.parityList
|
||||
flowControl.model = Cpp_IO_Serial.flowControlList
|
||||
//
|
||||
// Network settings
|
||||
//
|
||||
property alias address: network.address
|
||||
property alias port: network.port
|
||||
property alias socketType: network.socketType
|
||||
|
||||
parity.currentIndex = oldParityIndex
|
||||
flowControl.currentIndex = oldFlowControlIndex
|
||||
}
|
||||
//
|
||||
// App settings
|
||||
//
|
||||
property alias language: settings.language
|
||||
property alias endSequence: settings.endSequence
|
||||
property alias startSequence: settings.startSequence
|
||||
}
|
||||
|
||||
//
|
||||
@ -175,194 +177,55 @@ Control {
|
||||
}
|
||||
|
||||
//
|
||||
// A lot of comboboxes
|
||||
// Tab bar
|
||||
//
|
||||
GridLayout {
|
||||
columns: 2
|
||||
TabBar {
|
||||
height: 24
|
||||
id: tab
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// COM port selector
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
text: qsTr("COM Port") + ":"
|
||||
} ComboBox {
|
||||
id: portSelector
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.portList
|
||||
currentIndex: Cpp_IO_Serial.portIndex
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Serial.portIndex)
|
||||
Cpp_IO_Serial.portIndex = currentIndex
|
||||
}
|
||||
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex < 2)
|
||||
Cpp_IO_Manager.dataSource = currentIndex
|
||||
}
|
||||
|
||||
//
|
||||
// Baud rate selector
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
text: qsTr("Baud Rate") + ":"
|
||||
} ComboBox {
|
||||
id: baudRate
|
||||
editable: true
|
||||
currentIndex: 3
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.baudRateList
|
||||
|
||||
validator: IntValidator {
|
||||
bottom: 1
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
if (find(editText) === -1)
|
||||
Cpp_IO_Serial.appendBaudRate(editText)
|
||||
}
|
||||
|
||||
onCurrentTextChanged: {
|
||||
var value = currentText
|
||||
Cpp_IO_Serial.baudRate = value
|
||||
}
|
||||
TabButton {
|
||||
text: qsTr("Serial")
|
||||
height: tab.height + 3
|
||||
width: implicitWidth + 2 * app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.minimumHeight: app.spacing / 2
|
||||
Layout.maximumHeight: app.spacing / 2
|
||||
} Item {
|
||||
Layout.minimumHeight: app.spacing / 2
|
||||
Layout.maximumHeight: app.spacing / 2
|
||||
TabButton {
|
||||
text: qsTr("Network")
|
||||
height: tab.height + 3
|
||||
width: implicitWidth + 2 * app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// Data bits selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Data Bits") + ":"
|
||||
} ComboBox {
|
||||
id: dataBits
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.dataBitsList
|
||||
currentIndex: Cpp_IO_Serial.dataBitsIndex
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.dataBitsIndex !== currentIndex)
|
||||
Cpp_IO_Serial.dataBitsIndex = currentIndex
|
||||
}
|
||||
TabButton {
|
||||
text: qsTr("Settings")
|
||||
height: tab.height + 3
|
||||
width: implicitWidth + 2 * app.spacing
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Tab bar contents
|
||||
//
|
||||
StackLayout {
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
currentIndex: tab.currentIndex
|
||||
|
||||
SetupPanes.Serial {
|
||||
id: serial
|
||||
}
|
||||
|
||||
//
|
||||
// Parity selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Parity") + ":"
|
||||
} ComboBox {
|
||||
id: parity
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.parityList
|
||||
currentIndex: Cpp_IO_Serial.parityIndex
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.parityIndex !== currentIndex)
|
||||
Cpp_IO_Serial.parityIndex = currentIndex
|
||||
}
|
||||
SetupPanes.Network {
|
||||
id: network
|
||||
}
|
||||
|
||||
//
|
||||
// Stop bits selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Stop Bits") + ":"
|
||||
} ComboBox {
|
||||
id: stopBits
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.stopBitsList
|
||||
currentIndex: Cpp_IO_Serial.stopBitsIndex
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.stopBitsIndex !== currentIndex)
|
||||
Cpp_IO_Serial.stopBitsIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Flow control selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Flow Control") + ":"
|
||||
} ComboBox {
|
||||
id: flowControl
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.flowControlList
|
||||
currentIndex: Cpp_IO_Serial.flowControlIndex
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.flowControlIndex !== currentIndex)
|
||||
Cpp_IO_Serial.flowControlIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.minimumHeight: app.spacing / 2
|
||||
Layout.maximumHeight: app.spacing / 2
|
||||
} Item {
|
||||
Layout.minimumHeight: app.spacing / 2
|
||||
Layout.maximumHeight: app.spacing / 2
|
||||
}
|
||||
|
||||
//
|
||||
// Language selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Language") + ":"
|
||||
} ComboBox {
|
||||
id: languageCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_Misc_Translator.availableLanguages
|
||||
onCurrentIndexChanged: Cpp_Misc_Translator.setLanguage(currentIndex)
|
||||
}
|
||||
|
||||
//
|
||||
// Start sequence
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Start sequence") + ": "
|
||||
} TextField {
|
||||
id: startSeqText
|
||||
Layout.fillWidth: true
|
||||
placeholderText: "/*"
|
||||
text: "/*"
|
||||
onTextChanged: {
|
||||
if (text !== Cpp_IO_Manager.startSequence)
|
||||
Cpp_IO_Manager.startSequence = text
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// End sequence
|
||||
//
|
||||
Label {
|
||||
text: qsTr("End sequence") + ": "
|
||||
} TextField {
|
||||
id: endSeqText
|
||||
Layout.fillWidth: true
|
||||
placeholderText: "*/"
|
||||
text: "*/"
|
||||
onTextChanged: {
|
||||
if (text !== Cpp_IO_Manager.finishSequence)
|
||||
Cpp_IO_Manager.finishSequence = text
|
||||
}
|
||||
SetupPanes.Settings {
|
||||
id: settings
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,8 +233,8 @@ Control {
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumHeight: app.spacing * 2
|
||||
Layout.minimumHeight: app.spacing / 2
|
||||
Layout.maximumHeight: app.spacing / 2
|
||||
}
|
||||
|
||||
//
|
||||
@ -445,8 +308,7 @@ Control {
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumHeight: app.spacing * 2
|
||||
height: app.spacing * 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ ApplicationWindow {
|
||||
target: Cpp_JSON_Generator
|
||||
enabled: !app.firstValidPacket
|
||||
function onFrameChanged() {
|
||||
if (Cpp_IO_Manager.connected || Cpp_CSV_Player.isOpen) {
|
||||
if ((Cpp_IO_Manager.connected || Cpp_CSV_Player.isOpen) && Cpp_JSON_Generator.frameValid()) {
|
||||
app.firstValidPacket = true
|
||||
setup.hide()
|
||||
toolbar.dataClicked()
|
||||
|
@ -55,6 +55,7 @@ Console::Console()
|
||||
auto dm = Manager::getInstance();
|
||||
auto te = Misc::TimerEvents::getInstance();
|
||||
connect(te, SIGNAL(timeout42Hz()), this, SLOT(displayData()));
|
||||
connect(dm, &Manager::dataSent, this, &Console::onDataSent);
|
||||
connect(dm, &Manager::dataReceived, this, &Console::onDataReceived);
|
||||
|
||||
// Log something to look like a pro
|
||||
@ -321,27 +322,7 @@ void Console::send(const QString &data)
|
||||
}
|
||||
|
||||
// Write data to device
|
||||
auto bytes = Manager::getInstance()->writeData(bin);
|
||||
|
||||
// Write success, notify UI & log bytes written
|
||||
if (bytes > 0)
|
||||
{
|
||||
// Get sent byte array
|
||||
auto sent = bin;
|
||||
sent.chop(bin.length() - bytes);
|
||||
|
||||
// Display sent data on console (if allowed)
|
||||
if (echo())
|
||||
{
|
||||
m_isStartingLine = true;
|
||||
append(dataToString(bin), showTimestamp());
|
||||
m_isStartingLine = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Write error
|
||||
else
|
||||
LOG_WARNING() << Manager::getInstance()->device()->errorString();
|
||||
Manager::getInstance()->writeData(bin);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -484,6 +465,17 @@ void Console::displayData()
|
||||
m_dataBuffer.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the given @a data in the console. @c QByteArray to ~@c QString conversion is
|
||||
* done by the @c dataToString() function, which displays incoming data either in UTF-8
|
||||
* or in hexadecimal mode.
|
||||
*/
|
||||
void Console::onDataSent(const QByteArray &data)
|
||||
{
|
||||
if (echo())
|
||||
append(dataToString(data) + "\n", showTimestamp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given @a data to the incoming data buffer, which is read later by the UI
|
||||
* refresh functions (displayData())
|
||||
|
@ -133,6 +133,7 @@ public slots:
|
||||
|
||||
private slots:
|
||||
void displayData();
|
||||
void onDataSent(const QByteArray &data);
|
||||
void addToHistory(const QString &command);
|
||||
void onDataReceived(const QByteArray &data);
|
||||
|
||||
|
@ -21,25 +21,34 @@
|
||||
*/
|
||||
|
||||
#include "Network.h"
|
||||
#include <Misc/Utilities.h>
|
||||
|
||||
using namespace IO::DataSources;
|
||||
|
||||
static Network *INSTANCE = nullptr;
|
||||
|
||||
/**
|
||||
* Constructor function
|
||||
*/
|
||||
Network::Network()
|
||||
{
|
||||
setPort(0);
|
||||
setHost("");
|
||||
setPort(defaultPort());
|
||||
setSocketType(QAbstractSocket::TcpSocket);
|
||||
connect(&m_tcpSocket, &QTcpSocket::errorOccurred, this, &Network::onErrorOccurred);
|
||||
connect(&m_udpSocket, &QTcpSocket::errorOccurred, this, &Network::onErrorOccurred);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor function
|
||||
*/
|
||||
Network::~Network()
|
||||
{
|
||||
disconnectDevice();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the only instance of this class
|
||||
*/
|
||||
Network *Network::getInstance()
|
||||
{
|
||||
if (!INSTANCE)
|
||||
@ -48,26 +57,75 @@ Network *Network::getInstance()
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the host address
|
||||
*/
|
||||
QString Network::host() const
|
||||
{
|
||||
return m_host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the network port number
|
||||
*/
|
||||
quint16 Network::port() const
|
||||
{
|
||||
return m_port;
|
||||
}
|
||||
|
||||
bool Network::configurationOk() const
|
||||
/**
|
||||
* Returns the current socket type as an index of the list returned by the @c socketType
|
||||
* function.
|
||||
*/
|
||||
int Network::socketTypeIndex() const
|
||||
{
|
||||
return port() >= 0 && !QHostAddress(host()).isNull();
|
||||
switch (socketType())
|
||||
{
|
||||
case QAbstractSocket::TcpSocket:
|
||||
return 0;
|
||||
break;
|
||||
case QAbstractSocket::UdpSocket:
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns @c true if the port is greater than 0 and the host address is valid.
|
||||
*/
|
||||
bool Network::configurationOk() const
|
||||
{
|
||||
return true;
|
||||
// return port() > 0 && !QHostAddress(host()).isNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list with the available socket types
|
||||
*/
|
||||
QStringList Network::socketTypes() const
|
||||
{
|
||||
return QStringList { "TCP", "UDP" };
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the socket type. Valid return values are:
|
||||
*
|
||||
* @c QAbstractSocket::TcpSocket
|
||||
* @c QAbstractSocket::UdpSocket
|
||||
* @c QAbstractSocket::SctpSocket
|
||||
* @c QAbstractSocket::UnknownSocketType
|
||||
*/
|
||||
QAbstractSocket::SocketType Network::socketType() const
|
||||
{
|
||||
return m_socketType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to make a connection to the given host, port and TCP/UDP socket type.
|
||||
*/
|
||||
QIODevice *Network::openNetworkPort()
|
||||
{
|
||||
// Disconnect all sockets
|
||||
@ -76,59 +134,122 @@ QIODevice *Network::openNetworkPort()
|
||||
// Init socket pointer
|
||||
QAbstractSocket *socket = nullptr;
|
||||
|
||||
// Get host & port
|
||||
auto hostAddr = host();
|
||||
auto portAddr = port();
|
||||
if (hostAddr.isEmpty())
|
||||
hostAddr = defaultHost();
|
||||
if (portAddr <= 0)
|
||||
portAddr = defaultPort();
|
||||
|
||||
// TCP connection, assign socket pointer & connect to host
|
||||
if (socketType() == QAbstractSocket::TcpSocket)
|
||||
{
|
||||
socket = &m_tcpSocket;
|
||||
m_tcpSocket.connectToHost(host(), port());
|
||||
m_tcpSocket.connectToHost(hostAddr, portAddr);
|
||||
}
|
||||
|
||||
// UDP connection, assign socket pointer & connect to host
|
||||
else if (socketType() == QAbstractSocket::UdpSocket)
|
||||
{
|
||||
socket = &m_udpSocket;
|
||||
m_udpSocket.connectToHost(host(), port());
|
||||
m_udpSocket.connectToHost(hostAddr, portAddr);
|
||||
}
|
||||
|
||||
// Convert socket to IO device pointer
|
||||
return static_cast<QIODevice *>(socket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the module to communicate via a TCP socket.
|
||||
*/
|
||||
void Network::setTcpSocket()
|
||||
{
|
||||
setSocketType(QAbstractSocket::TcpSocket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the module to communicate via an UDP socket.
|
||||
*/
|
||||
void Network::setUdpSocket()
|
||||
{
|
||||
setSocketType(QAbstractSocket::UdpSocket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the TCP/UDP sockets from the host
|
||||
*/
|
||||
void Network::disconnectDevice()
|
||||
{
|
||||
m_tcpSocket.disconnectFromHost();
|
||||
m_udpSocket.disconnectFromHost();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the @c port number
|
||||
*/
|
||||
void Network::setPort(const quint16 port)
|
||||
{
|
||||
m_port = port;
|
||||
emit portChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the IPv4 or IPv6 address specified by the input string representation
|
||||
*/
|
||||
void Network::setHost(const QString &host)
|
||||
{
|
||||
m_host = host;
|
||||
emit hostChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the current socket type given an index of the list returned by the
|
||||
* @c socketType() function.
|
||||
*/
|
||||
void Network::setSocketTypeIndex(const int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
setTcpSocket();
|
||||
break;
|
||||
case 1:
|
||||
setUdpSocket();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the socket type. Valid input values are:
|
||||
*
|
||||
* @c QAbstractSocket::TcpSocket
|
||||
* @c QAbstractSocket::UdpSocket
|
||||
* @c QAbstractSocket::SctpSocket
|
||||
* @c QAbstractSocket::UnknownSocketType
|
||||
*/
|
||||
void Network::setSocketType(const QAbstractSocket::SocketType type)
|
||||
{
|
||||
m_socketType = type;
|
||||
emit socketTypeChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called whenever a socket error occurs, it disconnects the socket
|
||||
* from the host and displays the error in a message box.
|
||||
*/
|
||||
void Network::onErrorOccurred(const QAbstractSocket::SocketError socketError)
|
||||
{
|
||||
qDebug() << socketError;
|
||||
QString error;
|
||||
if (socketType() == QAbstractSocket::TcpSocket)
|
||||
error = m_tcpSocket.errorString();
|
||||
else if (socketType() == QAbstractSocket::UdpSocket)
|
||||
error = m_udpSocket.errorString();
|
||||
else
|
||||
error = QString::number(socketError);
|
||||
|
||||
Misc::Utilities::showMessageBox(tr("Socket error"), error);
|
||||
disconnectDevice();
|
||||
}
|
||||
|
@ -1,23 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Alex Spataru <https://github.com/alex-spataru>
|
||||
* Copyright (C) MATUSICA S.A. de C.V. - All Rights Reserved
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Proprietary and confidential.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
* Written by Alex Spataru <https://alex-spataru.com/>, February 2021
|
||||
*/
|
||||
|
||||
#ifndef IO_DATA_SOURCES_NETWORK_H
|
||||
@ -49,6 +36,19 @@ class Network : public QObject
|
||||
READ socketType
|
||||
WRITE setSocketType
|
||||
NOTIFY socketTypeChanged)
|
||||
Q_PROPERTY(int socketTypeIndex
|
||||
READ socketTypeIndex
|
||||
WRITE setSocketTypeIndex
|
||||
NOTIFY socketTypeChanged)
|
||||
Q_PROPERTY(QStringList socketTypes
|
||||
READ socketTypes
|
||||
CONSTANT)
|
||||
Q_PROPERTY(QString defaultHost
|
||||
READ defaultHost
|
||||
CONSTANT)
|
||||
Q_PROPERTY(quint16 defaultPort
|
||||
READ defaultPort
|
||||
CONSTANT)
|
||||
// clang-format on
|
||||
|
||||
signals:
|
||||
@ -61,9 +61,15 @@ public:
|
||||
|
||||
QString host() const;
|
||||
quint16 port() const;
|
||||
int socketTypeIndex() const;
|
||||
bool configurationOk() const;
|
||||
QStringList socketTypes() const;
|
||||
QAbstractSocket::SocketType socketType() const;
|
||||
|
||||
static QString defaultHost() { return "127.0.0.1"; }
|
||||
|
||||
static quint16 defaultPort() { return 23; }
|
||||
|
||||
QIODevice *openNetworkPort();
|
||||
|
||||
public slots:
|
||||
@ -72,6 +78,7 @@ public slots:
|
||||
void disconnectDevice();
|
||||
void setPort(const quint16 port);
|
||||
void setHost(const QString &host);
|
||||
void setSocketTypeIndex(const int index);
|
||||
void setSocketType(const QAbstractSocket::SocketType type);
|
||||
|
||||
private slots:
|
||||
|
@ -271,17 +271,23 @@ QStringList Manager::dataSourcesList() const
|
||||
*/
|
||||
qint64 Manager::writeData(const QByteArray &data)
|
||||
{
|
||||
// Write data to device
|
||||
qint64 bytes = 0;
|
||||
if (readWrite())
|
||||
bytes = device()->write(data);
|
||||
if (connected())
|
||||
{
|
||||
qint64 bytes = device()->write(data);
|
||||
|
||||
// Flash UI lights (if any)
|
||||
if (bytes > 0)
|
||||
emit tx();
|
||||
if (bytes > 0)
|
||||
{
|
||||
auto writtenData = data;
|
||||
writtenData.chop(data.length() - bytes);
|
||||
|
||||
// Return number of bytes written
|
||||
return bytes;
|
||||
emit tx();
|
||||
emit dataSent(writtenData);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -392,6 +398,9 @@ void Manager::setDataSource(const DataSource source)
|
||||
// Change data source
|
||||
m_dataSource = source;
|
||||
emit dataSourceChanged();
|
||||
|
||||
// Log changes
|
||||
LOG_INFO() << "Data source set to" << source;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,6 +80,7 @@ signals:
|
||||
void finishSequenceChanged();
|
||||
void watchdogIntervalChanged();
|
||||
void frameValidationRegexChanged();
|
||||
void dataSent(const QByteArray &data);
|
||||
void dataReceived(const QByteArray &data);
|
||||
void frameReceived(const QByteArray &frame);
|
||||
|
||||
|
@ -100,6 +100,14 @@ public:
|
||||
QString jsonMapFilepath() const;
|
||||
OperationMode operationMode() const;
|
||||
|
||||
Q_INVOKABLE bool frameValid()
|
||||
{
|
||||
if (frame())
|
||||
return frame()->groupCount() > 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void loadJsonMap();
|
||||
void setOperationMode(const OperationMode mode);
|
||||
|
Loading…
x
Reference in New Issue
Block a user