diff --git a/custom-example/custom.qrc b/custom-example/custom.qrc index 08de536f4c3729b2b70885b89c3e3838650edc1f..1c8f6a95fc1ee24f5fc130ead469df7d36061f80 100644 --- a/custom-example/custom.qrc +++ b/custom-example/custom.qrc @@ -10,6 +10,7 @@ res/MainToolbar/CustomModeIndicator.qml res/MainToolbar/CustomMultiVehicleSelector.qml res/MainToolbar/CustomRCRSSIIndicator.qml + res/PairingIndicator.qml res/PreFlightCheckList.qml @@ -25,12 +26,16 @@ res/Images/compass_pointer.svg res/Images/distance.svg res/Images/gimbal_icon.svg - res/Images/gimbal_position.svg res/Images/gimbal_pitch_indoors.svg res/Images/gimbal_pitch_outdoors.svg + res/Images/gimbal_position.svg res/Images/horizontal_speed.svg res/Images/microSD.svg res/Images/odometer.svg + res/Images/PairingButton.svg + res/Images/PairingConnected.svg + res/Images/PairingError.svg + res/Images/PairingIcon.svg res/Images/thermal-brightness.svg res/Images/thermal-palette.svg res/Images/thermal-pip.svg diff --git a/custom-example/res/Images/PairingButton.svg b/custom-example/res/Images/PairingButton.svg new file mode 100644 index 0000000000000000000000000000000000000000..1166e2088531d3f02037d96689860f18e3ce50d9 --- /dev/null +++ b/custom-example/res/Images/PairingButton.svg @@ -0,0 +1,23 @@ + + + + + + + diff --git a/custom-example/res/Images/PairingConnected.svg b/custom-example/res/Images/PairingConnected.svg new file mode 100644 index 0000000000000000000000000000000000000000..02ac3be8013eb9ef2c442180c1884149119dc910 --- /dev/null +++ b/custom-example/res/Images/PairingConnected.svg @@ -0,0 +1,44 @@ + + + + + + + + + + diff --git a/custom-example/res/Images/PairingError.svg b/custom-example/res/Images/PairingError.svg new file mode 100644 index 0000000000000000000000000000000000000000..db184514218ec8b85ace94d8feb58ad60bbcdd14 --- /dev/null +++ b/custom-example/res/Images/PairingError.svg @@ -0,0 +1,11 @@ + + + + + + diff --git a/custom-example/res/Images/PairingIcon.svg b/custom-example/res/Images/PairingIcon.svg new file mode 100644 index 0000000000000000000000000000000000000000..aff3e41e0c410917695aabaa5bd7112bcdd3e70e --- /dev/null +++ b/custom-example/res/Images/PairingIcon.svg @@ -0,0 +1,31 @@ + + + + + + + diff --git a/src/PairingManager/Images/PairingIconLight.svg b/custom-example/res/Images/PairingIconLight.svg similarity index 100% rename from src/PairingManager/Images/PairingIconLight.svg rename to custom-example/res/Images/PairingIconLight.svg diff --git a/custom-example/res/MainToolbar/CustomMainToolBarIndicators.qml b/custom-example/res/MainToolbar/CustomMainToolBarIndicators.qml index c07ee69252e980dc10b9cca83ca43adf99b9db7a..a86c52d589dc05a8e7afd38476f8b0f02372eff3 100644 --- a/custom-example/res/MainToolbar/CustomMainToolBarIndicators.qml +++ b/custom-example/res/MainToolbar/CustomMainToolBarIndicators.qml @@ -23,6 +23,29 @@ import QGroundControl.Palette 1.0 Item { anchors.fill: parent readonly property real _indicatorMargins: ScreenTools.defaultFontPixelHeight * 0.75 + Component.onCompleted: { + if(QGroundControl.pairingManager) { + if(!activeVehicle) { + pairingTimer.start() + } + } + } + //------------------------------------------------------------------------- + //-- Launch pairing manager if nothing connected + Timer { + id: pairingTimer + interval: 5000 + running: false; + repeat: false; + onTriggered: { + if(!activeVehicle) { + if(QGroundControl.pairingManager.firstBoot && pairingLoader.item) { + QGroundControl.pairingManager.firstBoot = false + pairingLoader.item.runPairing() + } + } + } + } //------------------------------------------------------------------------- //-- Waiting for a vehicle Row { @@ -34,7 +57,6 @@ Item { anchors.left: parent.left QGCColoredImage { id: menuEdge - visible: !QGroundControl.supportsPairing || !QGroundControl.settingsManager.appSettings.usePairing.rawValue anchors.verticalCenter: parent.verticalCenter height: ScreenTools.defaultFontPixelHeight width: height @@ -44,18 +66,28 @@ Item { color: qgcPal.buttonText } QGCLabel { - visible: menuEdge.visible anchors.verticalCenter: parent.verticalCenter text: qsTr("Waiting for a vehicle") font.pointSize: ScreenTools.mediumFontPointSize font.family: ScreenTools.demiboldFontFamily } + } + //------------------------------------------------------------------------- + //-- Pairing Indicator (not connected) + Row { + id: pairingRow + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.rightMargin: ScreenTools.defaultFontPixelWidth * 2 + spacing: ScreenTools.defaultFontPixelWidth * 2 + visible: !indicatorRow.visible Loader { - visible: !menuEdge.visible + id: pairingLoader anchors.top: parent.top anchors.bottom: parent.bottom anchors.margins: _indicatorMargins - source: "/toolbar/PairingIndicator.qml" + source: "/custom/PairingIndicator.qml" } } //------------------------------------------------------------------------- diff --git a/src/ui/toolbar/PairingIndicator.qml b/custom-example/res/PairingIndicator.qml similarity index 54% rename from src/ui/toolbar/PairingIndicator.qml rename to custom-example/res/PairingIndicator.qml index 751a878edf33d3619b02245bd94a3ad37e39a402..e200148f8990dfada8be8c4dc294cf29c66d3422 100644 --- a/src/ui/toolbar/PairingIndicator.qml +++ b/custom-example/res/PairingIndicator.qml @@ -10,6 +10,7 @@ import QtQuick 2.11 import QtQuick.Controls 2.4 import QtQuick.Layouts 1.11 +import QtQuick.Dialogs 1.3 import QGroundControl 1.0 import QGroundControl.Controls 1.0 @@ -24,20 +25,48 @@ Item { width: pairingRow.width * 1.1 anchors.top: parent.top anchors.bottom: parent.bottom - property bool _light: qgcPal.globalTheme === QGCPalette.Light && !activeVehicle - property real _contentWidth: ScreenTools.defaultFontPixelWidth * 30 - property real _contentSpacing: ScreenTools.defaultFontPixelHeight * 0.5 + + property bool _light: qgcPal.globalTheme === QGCPalette.Light && !activeVehicle + property real _contentWidth: ScreenTools.defaultFontPixelWidth * 34 + property real _contentSpacing: ScreenTools.defaultFontPixelHeight * 0.5 + property real _rectWidth: _contentWidth + property real _rectHeight: _contentWidth * 0.75 + + property string kPairingManager: qsTr("Pairing Manager") + + function runPairing() { + QGroundControl.pairingManager.firstBoot = false + if(QGroundControl.pairingManager.pairedDeviceNameList.length > 0) { + connectionPopup.open() + } else { + mhPopup.open() + } + } + + Connections { + target: QGroundControl.pairingManager + //-- Connect automatically once paired + onPairingStatusChanged: { + if(QGroundControl.pairingManager.pairingStatus === PairingManager.PairingSuccess) { + if(QGroundControl.pairingManager.pairedVehicle !== "") { + QGroundControl.pairingManager.connectToPairedDevice(QGroundControl.pairingManager.pairedVehicle) + } + } + } + } + Row { id: pairingRow spacing: ScreenTools.defaultFontPixelWidth anchors.top: parent.top anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter - Image { + QGCColoredImage { id: pairingIcon height: parent.height width: height - source: _light ? "/qmlimages/PairingIconLight.svg" : "/qmlimages/PairingIcon.svg" + color: qgcPal.text + source: "/custom/img/PairingIcon.svg" sourceSize.width: width fillMode: Image.PreserveAspectFit smooth: true @@ -49,7 +78,6 @@ Item { text: qsTr("Pair Vehicle") width: !activeVehicle ? (ScreenTools.defaultFontPixelWidth * 12) : 0 visible: !activeVehicle - font.pointSize: ScreenTools.mediumFontPointSize font.family: ScreenTools.demiboldFontFamily anchors.verticalCenter: parent.verticalCenter } @@ -57,90 +85,7 @@ Item { MouseArea { anchors.fill: parent onClicked: { - if(QGroundControl.pairingManager.pairedDeviceNameList.length > 1) { - connectionPopup.open() - } else { - if(QGroundControl.pairingManager.pairingLinkTypeStrings.length > 1) - pairingPopup.open() - else { - mhPopup.open() - } - } - } - } - //------------------------------------------------------------------------- - //-- Pairing - Popup { - id: pairingPopup - width: pairingBody.width - height: pairingBody.height - modal: true - focus: true - parent: Overlay.overlay - x: Math.round((mainWindow.width - width) * 0.5) - y: Math.round((mainWindow.height - height) * 0.5) - closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside - background: Rectangle { - anchors.fill: parent - color: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75) - radius: ScreenTools.defaultFontPixelWidth * 0.25 - } - Item { - id: pairingBody - width: comboListCol.width + (ScreenTools.defaultFontPixelWidth * 8) - height: comboListCol.height + (ScreenTools.defaultFontPixelHeight * 2) - anchors.centerIn: parent - Column { - id: comboListCol - spacing: _contentSpacing - anchors.centerIn: parent - Item { width: 1; height: 1; } - QGCLabel { - text: qsTr("Pair New Vehicle") - font.pointSize: ScreenTools.mediumFontPointSize - font.family: ScreenTools.demiboldFontFamily - anchors.horizontalCenter: parent.horizontalCenter - } - Item { width: 1; height: 1; } - Rectangle { - width: ScreenTools.defaultFontPixelWidth * 40 - height: ScreenTools.defaultFontPixelHeight * 8 - color: Qt.rgba(0,0,0,0) - border.color: qgcPal.text - border.width: 1 - anchors.horizontalCenter: parent.horizontalCenter - QGCLabel { - text: "Graphic" - anchors.centerIn: parent - } - } - Item { width: 1; height: 1; } - QGCLabel { - text: qsTr("Please choose a pairing method in order to connect to a nearby device") - width: _contentWidth - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignHCenter - anchors.horizontalCenter: parent.horizontalCenter - } - Item { width: 1; height: 1; } - Repeater { - model: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairingLinkTypeStrings : [] - delegate: QGCButton { - text: modelData - width: _contentWidth - anchors.horizontalCenter: parent.horizontalCenter - onClicked: { - pairingPopup.close() - if (index === QGroundControl.pairingManager.nfcIndex) { - nfcPopup.open() - } else if (index === QGroundControl.pairingManager.microhardIndex) { - mhPopup.open() - } - } - } - } - Item { width: 1; height: 1; } - } + runPairing() } } //------------------------------------------------------------------------- @@ -171,40 +116,44 @@ Item { anchors.centerIn: parent Item { width: 1; height: 1; } QGCLabel { - text: qsTr("Pair New Vehicle") - font.pointSize: ScreenTools.mediumFontPointSize + text: kPairingManager font.family: ScreenTools.demiboldFontFamily + font.pointSize: ScreenTools.mediumFontPointSize anchors.horizontalCenter: parent.horizontalCenter } + Rectangle { + width: _contentWidth + height: 1 + color: qgcPal.globalTheme !== QGCPalette.Light ? Qt.rgba(1,1,1,0.25) : Qt.rgba(0,0,0,0.25) + } Item { width: 1; height: 1; } QGCLabel { - text: qsTr("To connect to your vehicle, please click 3 times on the button in order to put the vehicle in a discovery mode") + text: qsTr("To connect to your vehicle, please click on the pairing button in order to put the vehicle in discovery mode") width: _contentWidth wrapMode: Text.WordWrap horizontalAlignment: Text.AlignHCenter anchors.horizontalCenter: parent.horizontalCenter } - Item { width: 1; height: 1; } - Rectangle { - width: ScreenTools.defaultFontPixelWidth * 40 - height: ScreenTools.defaultFontPixelHeight * 8 - color: Qt.rgba(0,0,0,0) - border.color: qgcPal.text - border.width: 1 + Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 2; } + QGCColoredImage { + height: ScreenTools.defaultFontPixelHeight * 6 + width: height + source: "/custom/img/PairingButton.svg" + sourceSize.height: height + fillMode: Image.PreserveAspectFit + mipmap: true + smooth: true + color: qgcPal.text anchors.horizontalCenter: parent.horizontalCenter - QGCLabel { - text: "Graphic" - anchors.centerIn: parent - } } - Item { width: 1; height: 1; } + Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 2; } QGCButton { - text: qsTr("Pair Via Microhard") + text: qsTr("Pair a Vehicle") width: _contentWidth anchors.horizontalCenter: parent.horizontalCenter onClicked: { mhPopup.close() - connectionPopup.open() + progressPopup.open() QGroundControl.pairingManager.startMicrohardPairing(); } } @@ -240,21 +189,26 @@ Item { anchors.centerIn: parent Item { width: 1; height: 1; } QGCLabel { - text: qsTr("Pair New Vehicle") - font.pointSize: ScreenTools.mediumFontPointSize + text: kPairingManager font.family: ScreenTools.demiboldFontFamily + font.pointSize: ScreenTools.mediumFontPointSize anchors.horizontalCenter: parent.horizontalCenter } + Rectangle { + width: _contentWidth + height: 1 + color: qgcPal.globalTheme !== QGCPalette.Light ? Qt.rgba(1,1,1,0.25) : Qt.rgba(0,0,0,0.25) + } Item { width: 1; height: 1; } Rectangle { - width: ScreenTools.defaultFontPixelWidth * 40 - height: ScreenTools.defaultFontPixelHeight * 12 + width: _rectWidth + height: _rectHeight color: Qt.rgba(0,0,0,0) border.color: qgcPal.text border.width: 1 anchors.horizontalCenter: parent.horizontalCenter QGCLabel { - text: "Graphic" + text: "Vehicle and Tablet Graphic" anchors.centerIn: parent } } @@ -273,7 +227,7 @@ Item { anchors.horizontalCenter: parent.horizontalCenter onClicked: { nfcPopup.close() - connectionPopup.open() + progressPopup.open() QGroundControl.pairingManager.startNFCScan(); } } @@ -282,11 +236,11 @@ Item { } } //------------------------------------------------------------------------- - //-- Connection Manager + //-- Pairing/Connection Progress Popup { - id: connectionPopup - width: connectionBody.width - height: connectionBody.height + id: progressPopup + width: progressBody.width + height: progressBody.height modal: true focus: true parent: Overlay.overlay @@ -299,25 +253,37 @@ Item { radius: ScreenTools.defaultFontPixelWidth * 0.25 } Item { - id: connectionBody - width: connectionCol.width + (ScreenTools.defaultFontPixelWidth * 8) - height: connectionCol.height + (ScreenTools.defaultFontPixelHeight * 2) + id: progressBody + width: progressCol.width + (ScreenTools.defaultFontPixelWidth * 8) + height: progressCol.height + (ScreenTools.defaultFontPixelHeight * 2) anchors.centerIn: parent Column { - id: connectionCol - spacing: _contentSpacing * 2 - anchors.centerIn: parent + id: progressCol + spacing: _contentSpacing + anchors.centerIn: parent Item { width: 1; height: 1; } QGCLabel { - text: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairingStatusStr : "" - font.pointSize: ScreenTools.mediumFontPointSize - font.family: ScreenTools.demiboldFontFamily + text: kPairingManager + font.family: ScreenTools.demiboldFontFamily + font.pointSize: ScreenTools.mediumFontPointSize anchors.horizontalCenter: parent.horizontalCenter } + QGCLabel { + text: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairingStatusStr : "" + visible: !connectedIndicator.visible + anchors.horizontalCenter: parent.horizontalCenter + } + Rectangle { + width: _contentWidth + height: 1 + color: qgcPal.globalTheme !== QGCPalette.Light ? Qt.rgba(1,1,1,0.25) : Qt.rgba(0,0,0,0.25) + } Item { width: 1; height: 1; } + //-- Pairing/Connecting + Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 3; visible: busyIndicator.visible; } QGCColoredImage { id: busyIndicator - height: ScreenTools.defaultFontPixelHeight * 2 + height: ScreenTools.defaultFontPixelHeight * 4 width: height source: "/qmlimages/MapSync.svg" sourceSize.height: height @@ -325,7 +291,7 @@ Item { mipmap: true smooth: true color: qgcPal.text - visible: cancelButton.visible + visible: QGroundControl.pairingManager.pairingStatus === PairingManager.PairingActive || QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnecting anchors.horizontalCenter: parent.horizontalCenter RotationAnimation on rotation { loops: Animation.Infinite @@ -335,10 +301,135 @@ Item { running: busyIndicator.visible } } + Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 3; visible: busyIndicator.visible; } + //-- Error State + Image { + height: ScreenTools.defaultFontPixelHeight * 4 + width: height + source: "/custom/img/PairingError.svg" + sourceSize.height: height + fillMode: Image.PreserveAspectFit + mipmap: true + smooth: true + visible: QGroundControl.pairingManager.errorState + anchors.horizontalCenter: parent.horizontalCenter + } + //-- Connection Successful + Image { + id: connectedIndicator + height: width * 0.2 + width: _contentWidth + source: "/custom/img/PairingConnected.svg" + sourceSize.height: height + fillMode: Image.PreserveAspectFit + mipmap: true + smooth: true + visible: QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnected + anchors.horizontalCenter: parent.horizontalCenter + } + Item { width: 1; height: _contentSpacing; visible: connectedIndicator.visible; } + QGCLabel { + text: QGroundControl.pairingManager.pairedVehicle + visible: connectedIndicator.visible + anchors.horizontalCenter: parent.horizontalCenter + } + QGCLabel { + text: qsTr("Connection Successful") + visible: connectedIndicator.visible + anchors.horizontalCenter: parent.horizontalCenter + } + Item { width: 1; height: _contentSpacing; } + //-- Buttons + QGCButton { + width: _contentWidth + visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnected) : false + text: qsTr("Done") + anchors.horizontalCenter: parent.horizontalCenter + onClicked: { + progressPopup.close() + } + } + QGCButton { + text: qsTr("Pair Another") + width: _contentWidth + visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnected) : false + anchors.horizontalCenter: parent.horizontalCenter + onClicked: { + progressPopup.close() + mhPopup.open() + } + } + QGCButton { + text: qsTr("Try Again") + width: _contentWidth + visible: QGroundControl.pairingManager ? QGroundControl.pairingManager.errorState : false + anchors.horizontalCenter: parent.horizontalCenter + onClicked: { + progressPopup.close() + runPairing() + } + } + QGCButton { + id: cancelButton + width: _contentWidth + visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingActive || QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnecting || QGroundControl.pairingManager.errorState) : false + text: qsTr("Cancel") + anchors.horizontalCenter: parent.horizontalCenter + onClicked: { + if(QGroundControl.pairingManager.pairingStatus === PairingManager.PairingActive) + QGroundControl.pairingManager.stopPairing() + else { + //-- TODO: Cancel connection to paired device + } + progressPopup.close() + } + } + Item { width: 1; height: 1; } + } + } + } + //------------------------------------------------------------------------- + //-- Connection Manager + Popup { + id: connectionPopup + width: connectionBody.width + height: connectionBody.height + modal: true + focus: true + parent: Overlay.overlay + x: Math.round((mainWindow.width - width) * 0.5) + y: Math.round((mainWindow.height - height) * 0.5) + closePolicy: cancelButton.visible ? Popup.NoAutoClose : (Popup.CloseOnEscape | Popup.CloseOnPressOutside) + background: Rectangle { + anchors.fill: parent + color: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75) + radius: ScreenTools.defaultFontPixelWidth * 0.25 + } + Item { + id: connectionBody + width: connectionCol.width + (ScreenTools.defaultFontPixelWidth * 8) + height: connectionCol.height + (ScreenTools.defaultFontPixelHeight * 2) + anchors.centerIn: parent + Column { + id: connectionCol + spacing: _contentSpacing + anchors.centerIn: parent + Item { width: 1; height: 1; } + QGCLabel { + text: kPairingManager + font.family: ScreenTools.demiboldFontFamily + font.pointSize: ScreenTools.mediumFontPointSize + anchors.horizontalCenter: parent.horizontalCenter + } + Rectangle { + width: _contentWidth + height: 1 + color: qgcPal.globalTheme !== QGCPalette.Light ? Qt.rgba(1,1,1,0.25) : Qt.rgba(0,0,0,0.25) + } + Item { width: 1; height: 1; } QGCLabel { text: qsTr("List Of Available Devices") visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairedDeviceNameList.length > 0 && !cancelButton.visible) : false - font.pointSize: ScreenTools.mediumFontPointSize font.family: ScreenTools.demiboldFontFamily } Item { width: 1; height: 1; } @@ -348,10 +439,11 @@ Item { columnSpacing: ScreenTools.defaultFontPixelWidth rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25 anchors.horizontalCenter: parent.horizontalCenter + property var _pairModel: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairedDeviceNameList : [] Repeater { - model: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairedDeviceNameList : [] - QGCLabel { - text: modelData + model: parent._pairModel + delegate: QGCLabel { + text: modelData Layout.row: index Layout.column: 0 Layout.minimumWidth:ScreenTools.defaultFontPixelWidth * 14 @@ -359,85 +451,64 @@ Item { } } Repeater { - model: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairedDeviceNameList : [] - QGCButton { + model: parent._pairModel + delegate: QGCButton { text: qsTr("Connect") Layout.row: index Layout.column: 1 onClicked: { QGroundControl.pairingManager.connectToPairedDevice(modelData) + connectionPopup.close() + progressPopup.open() } } } Repeater { - model: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairedDeviceNameList : [] - QGCColoredImage { - height: ScreenTools.defaultFontPixelHeight * 1.5 - width: height - sourceSize.height: height - source: "/res/TrashDelete.svg" - color: qgcPal.colorRed - Layout.row: index - Layout.column: 2 + model: parent._pairModel + delegate: QGCColoredImage { + Layout.preferredWidth: ScreenTools.defaultFontPixelHeight * 1.5 + Layout.preferredHeight: ScreenTools.defaultFontPixelHeight * 1.5 + sourceSize.height: height + source: "/res/TrashDelete.svg" + color: qgcPal.colorRed + Layout.row: index + Layout.column: 2 MouseArea { - anchors.fill: parent + anchors.fill: parent onClicked: { - //-- TODO: + removePrompt.open() } } - } - } - } - Item { width: 1; height: 1; } - RowLayout { - id: connectedButtons - visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnected || QGroundControl.pairingManager.pairingStatus === PairingManager.PairingIdle) : false - spacing: ScreenTools.defaultFontPixelWidth * 4 - anchors.horizontalCenter: parent.horizontalCenter - QGCButton { - text: qsTr("Pair Another") - Layout.minimumWidth: _contentWidth * 0.333 - Layout.fillWidth: true - onClicked: { - connectionPopup.close() - if(QGroundControl.pairingManager.pairingLinkTypeStrings.length > 1) - pairingPopup.open() - else { - mhPopup.open() + MessageDialog { + id: removePrompt + title: qsTr("Remove Paired Vehicle") + text: qsTr("Confirm removing %1?").arg(modelData) + standardButtons: StandardButton.Yes | StandardButton.No + onNo: removePrompt.close() + onYes: { + QGroundControl.pairingManager.removePairedDevice(modelData) + removePrompt.close() + } } } } - QGCButton { - text: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnected ? qsTr("Go And Fly") : qsTr("Close")) : "" - Layout.minimumWidth: _contentWidth * 0.333 - Layout.fillWidth: true - onClicked: { - connectionPopup.close() - } - } } + Item { width: 1; height: _contentSpacing; } QGCButton { - id: cancelButton - visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingActive || QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnecting) : false - text: qsTr("Cancel") - width: _contentWidth - anchors.horizontalCenter: parent.horizontalCenter + width: _contentWidth + text: qsTr("Close") + anchors.horizontalCenter: parent.horizontalCenter onClicked: { - if(QGroundControl.pairingManager.pairingStatus === PairingManager.PairingActive) - QGroundControl.pairingManager.stopPairing() - else { - //-- TODO: Cancel connection to paired device - } connectionPopup.close() } } QGCButton { - visible: !cancelButton.visible && !connectedButtons.visible - text: qsTr("Close") - width: _contentWidth - anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Pair Another") + width: _contentWidth + anchors.horizontalCenter: parent.horizontalCenter onClicked: { connectionPopup.close() + mhPopup.open() } } Item { width: 1; height: 1; } diff --git a/custom-example/src/FirmwarePlugin/CustomFirmwarePlugin.cc b/custom-example/src/FirmwarePlugin/CustomFirmwarePlugin.cc index 420c72a5d1b32afc9a985534cf17ac416d84eef3..a460de252f4aacf49c5aeeeae212bc89de7d17a9 100644 --- a/custom-example/src/FirmwarePlugin/CustomFirmwarePlugin.cc +++ b/custom-example/src/FirmwarePlugin/CustomFirmwarePlugin.cc @@ -56,7 +56,7 @@ CustomFirmwarePlugin::toolBarIndicators(const Vehicle* vehicle) Q_UNUSED(vehicle); if(_toolBarIndicatorList.size() == 0) { #if defined(QGC_ENABLE_PAIRING) - _toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/PairingIndicator.qml"))); + _toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/custom/PairingIndicator.qml"))); #endif _toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/GPSIndicator.qml"))); _toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/TelemetryRSSIIndicator.qml"))); diff --git a/qgcimages.qrc b/qgcimages.qrc index 031ea95f2c56156268fb45afbf19d5ada73e5e5d..e025d9c09b730e59d24846e64480bce57053d876 100644 --- a/qgcimages.qrc +++ b/qgcimages.qrc @@ -66,11 +66,11 @@ src/AutoPilotPlugins/PX4/Images/CameraTrigger.svg resources/check.svg src/QmlControls/checkbox-check.svg + src/FlightMap/Images/cOGPointer.svg src/MissionManager/CogWheel.svg + src/FlightMap/Images/compassDottedLine.svg src/FlightMap/Images/compassInstrumentArrow.svg src/FlightMap/Images/compassInstrumentDial.svg - src/FlightMap/Images/compassDottedLine.svg - src/FlightMap/Images/cOGPointer.svg src/ui/toolbar/Images/Connect.svg src/FlightMap/Images/crossHair.svg src/AutoPilotPlugins/PX4/Images/DatalinkLoss.svg @@ -181,9 +181,5 @@ src/ui/toolbar/Images/Yield.svg src/FlightMap/Images/ZoomMinus.svg src/FlightMap/Images/ZoomPlus.svg - - src/PairingManager/Images/PairingIcon.svg - src/PairingManager/Images/PairingIconLight.svg - diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index b1bc3f5855dc8cb7a61cd35d948cbfd8561461bf..148e3fa81f0656f24069cc7b43b58aa672f4e2fa 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -14,7 +14,6 @@ src/ui/toolbar/MessageIndicator.qml src/ui/toolbar/ModeIndicator.qml src/ui/toolbar/MultiVehicleSelector.qml - src/ui/toolbar/PairingIndicator.qml src/ui/toolbar/RCRSSIIndicator.qml src/ui/toolbar/TelemetryRSSIIndicator.qml src/ui/toolbar/VTOLModeIndicator.qml diff --git a/src/PairingManager/Images/PairingIcon.svg b/src/PairingManager/Images/PairingIcon.svg deleted file mode 100644 index 23579e8cc8fc68f551c0da86eb59a8d368af9c05..0000000000000000000000000000000000000000 --- a/src/PairingManager/Images/PairingIcon.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - diff --git a/src/PairingManager/PairingManager.cc b/src/PairingManager/PairingManager.cc index 84f8208d8c77157f8fb480b14945de083b69cc7a..9df59ccaa4fed36b5350dcc1f91240a61e9fb800 100644 --- a/src/PairingManager/PairingManager.cc +++ b/src/PairingManager/PairingManager.cc @@ -62,6 +62,8 @@ void PairingManager::setToolbox(QGCToolbox *toolbox) { QGCTool::setToolbox(toolbox); + _updatePairedDeviceNameList(); + emit pairedListChanged(); } //----------------------------------------------------------------------------- @@ -70,18 +72,21 @@ PairingManager::_pairingCompleted(QString name) { _writeJson(_jsonDoc, _pairingCacheFile(name)); _remotePairingMap["NM"] = name; + _lastPaired = name; + _updatePairedDeviceNameList(); emit pairedListChanged(); - _app->informationMessageBoxOnMainThread("", tr("Paired with %1").arg(name)); + emit pairedVehicleChanged(); + //_app->informationMessageBoxOnMainThread("", tr("Paired with %1").arg(name)); setPairingStatus(PairingSuccess, tr("Pairing Successfull")); } //----------------------------------------------------------------------------- void -PairingManager::_connectionCompleted(QString name) +PairingManager::_connectionCompleted(QString /*name*/) { //QString pwd = _remotePairingMap["PWD"].toString(); //_toolbox->microhardManager()->switchToConnectionEncryptionKey(pwd); - _app->informationMessageBoxOnMainThread("", tr("Connected to %1").arg(name)); + //_app->informationMessageBoxOnMainThread("", tr("Connected to %1").arg(name)); setPairingStatus(PairingConnected, tr("Connection Successfull")); } @@ -126,7 +131,7 @@ PairingManager::_stopUpload() //----------------------------------------------------------------------------- void -PairingManager::_uploadFinished(void) +PairingManager::_uploadFinished() { QMutexLocker lock(&_uploadMutex); QNetworkReply* reply = qobject_cast(QObject::sender()); @@ -154,7 +159,7 @@ PairingManager::_uploadFinished(void) } else { if(++_pairRetryCount > 3) { qCDebug(PairingManagerLog) << "Giving up"; - setPairingStatus(PairingError, tr("Too Many Errors")); + setPairingStatus(PairingError, tr("No Response From Vehicle")); _uploadManager->deleteLater(); _uploadManager = nullptr; } else { @@ -191,18 +196,26 @@ PairingManager::connectToPairedDevice(QString name) } //----------------------------------------------------------------------------- -QStringList -PairingManager::pairedDeviceNameList(void) +void +PairingManager::removePairedDevice(QString name) { - QStringList list; + QFile file(_pairingCacheFile(name)); + file.remove(); + _updatePairedDeviceNameList(); + emit pairedListChanged(); +} + +//----------------------------------------------------------------------------- +void +PairingManager::_updatePairedDeviceNameList() +{ + _deviceList.clear(); QDirIterator it(_pairingCacheDir().absolutePath(), QDir::Files); while (it.hasNext()) { QFileInfo fileInfo(it.next()); - list.append(fileInfo.fileName()); + _deviceList.append(fileInfo.fileName()); qCDebug(PairingManagerLog) << "Listing: " << fileInfo.fileName(); } - - return list; } //----------------------------------------------------------------------------- @@ -215,9 +228,9 @@ PairingManager::_assumeMicrohardPairingJson() jsonObject.insert("LT", "MH"); jsonObject.insert("IP", "192.168.168.10"); jsonObject.insert("AIP", _toolbox->microhardManager()->remoteIPAddr()); - jsonObject.insert("CU", _toolbox->microhardManager()->configUserName()); - jsonObject.insert("CP", _toolbox->microhardManager()->configPassword()); - jsonObject.insert("EK", _toolbox->microhardManager()->encryptionKey()); + jsonObject.insert("CU", _toolbox->microhardManager()->configUserName()); + jsonObject.insert("CP", _toolbox->microhardManager()->configPassword()); + jsonObject.insert("EK", _toolbox->microhardManager()->encryptionKey()); json.setObject(jsonObject); return QString(json.toJson(QJsonDocument::Compact)); @@ -255,8 +268,8 @@ PairingManager::_parsePairingJson(QString jsonEnc) } _remotePairingMap = jsonObj.toVariantMap(); - QString linkType = _remotePairingMap["LT"].toString(); - QString pport = _remotePairingMap["PP"].toString(); + QString linkType = _remotePairingMap["LT"].toString(); + QString pport = _remotePairingMap["PP"].toString(); if (pport.length()==0) { pport = "29351"; } @@ -438,7 +451,7 @@ PairingManager::_createMicrohardConnectJson(QString cert2) //----------------------------------------------------------------------------- QStringList -PairingManager::pairingLinkTypeStrings(void) +PairingManager::pairingLinkTypeStrings() { //-- Must follow same order as enum LinkType in LinkConfiguration.h static QStringList list; @@ -467,7 +480,7 @@ PairingManager::_setPairingStatus(PairingStatus status, QString statusStr) //----------------------------------------------------------------------------- QString -PairingManager::pairingStatusStr(void) const +PairingManager::pairingStatusStr() const { return _statusString; } diff --git a/src/PairingManager/PairingManager.h b/src/PairingManager/PairingManager.h index 71c79ae1afc7c641bc323f459fcb58adc72c4ddf..44a123cc1fa9ee3ea95a81492cebc10ea4462f98 100644 --- a/src/PairingManager/PairingManager.h +++ b/src/PairingManager/PairingManager.h @@ -61,18 +61,23 @@ public: Q_ENUM(PairingStatus) - QStringList pairingLinkTypeStrings(void); - QString pairingStatusStr(void) const; - QStringList pairedDeviceNameList(void); - PairingStatus pairingStatus() { return _status; } - int nfcIndex(void) { return _nfcIndex; } - int microhardIndex(void) { return _microhardIndex; } - void setStatusMessage(PairingStatus status, QString statusStr) { emit setPairingStatus(status, statusStr); } - void jsonReceived(QString json) { emit parsePairingJson(json); } + QStringList pairingLinkTypeStrings (); + QString pairingStatusStr () const; + QStringList pairedDeviceNameList () { return _deviceList; } + PairingStatus pairingStatus () { return _status; } + QString pairedVehicle () { return _lastPaired; } + int nfcIndex () { return _nfcIndex; } + int microhardIndex () { return _microhardIndex; } + bool firstBoot () { return _firstBoot; } + bool errorState () { return _status == PairingRejected || _status == PairingConnectionRejected || _status == PairingError; } + void setStatusMessage (PairingStatus status, QString statusStr) { emit setPairingStatus(status, statusStr); } + void jsonReceived (QString json) { emit parsePairingJson(json); } + void setFirstBoot (bool set) { _firstBoot = set; emit firstBootChanged(); } #ifdef __android__ - static void setNativeMethods(void); + static void setNativeMethods (void); #endif - Q_INVOKABLE void connectToPairedDevice(QString name); + Q_INVOKABLE void connectToPairedDevice (QString name); + Q_INVOKABLE void removePairedDevice (QString name); #if defined QGC_ENABLE_NFC || defined QGC_ENABLE_QTNFC Q_INVOKABLE void startNFCScan(); @@ -86,29 +91,35 @@ public: Q_PROPERTY(PairingStatus pairingStatus READ pairingStatus NOTIFY pairingStatusChanged) Q_PROPERTY(QStringList pairedDeviceNameList READ pairedDeviceNameList NOTIFY pairedListChanged) Q_PROPERTY(QStringList pairingLinkTypeStrings READ pairingLinkTypeStrings CONSTANT) + Q_PROPERTY(QString pairedVehicle READ pairedVehicle NOTIFY pairedVehicleChanged) + Q_PROPERTY(bool errorState READ errorState NOTIFY pairingStatusChanged) Q_PROPERTY(int nfcIndex READ nfcIndex CONSTANT) Q_PROPERTY(int microhardIndex READ microhardIndex CONSTANT) + Q_PROPERTY(bool firstBoot READ firstBoot WRITE setFirstBoot NOTIFY firstBootChanged) signals: - void startUpload(QString pairURL, QJsonDocument); - void closeConnection(); - void pairingConfigurationsChanged(); - void nameListChanged(); - void pairingStatusChanged(); - void parsePairingJson(QString json); - void setPairingStatus(PairingStatus status, QString pairingStatus); - void pairedListChanged(); + void startUpload (QString pairURL, QJsonDocument); + void closeConnection (); + void pairingConfigurationsChanged (); + void nameListChanged (); + void pairingStatusChanged (); + void parsePairingJson (QString json); + void setPairingStatus (PairingStatus status, QString pairingStatus); + void pairedListChanged (); + void pairedVehicleChanged (); + void firstBootChanged (); private slots: - void _startUpload(QString pairURL, QJsonDocument); - void _stopUpload(); - void _startUploadRequest(); - void _parsePairingJson(QString jsonEnc); - void _setPairingStatus(PairingStatus status, QString pairingStatus); + void _startUpload (QString pairURL, QJsonDocument); + void _stopUpload (); + void _startUploadRequest (); + void _parsePairingJson (QString jsonEnc); + void _setPairingStatus (PairingStatus status, QString pairingStatus); private: QString _statusString; QString _jsonFileName; + QString _lastPaired; QVariantMap _remotePairingMap; int _nfcIndex = -1; int _microhardIndex = -1; @@ -120,23 +131,26 @@ private: QNetworkAccessManager* _uploadManager = nullptr; QString _uploadURL{}; QString _uploadData{}; - - void _parsePairingJsonFile(); - QJsonDocument _createZeroTierConnectJson(QString cert2); - QJsonDocument _createMicrohardConnectJson(QString cert2); - QJsonDocument _createZeroTierPairingJson(QString cert1); - QJsonDocument _createMicrohardPairingJson(QString pwd, QString cert1); - QString _assumeMicrohardPairingJson(); - void _writeJson(QJsonDocument &jsonDoc, QString fileName); - QString _getLocalIPInNetwork(QString remoteIP, int num); - void _uploadFinished(void); - void _uploadError(QNetworkReply::NetworkError code); - void _pairingCompleted(QString name); - void _connectionCompleted(QString name); - QDir _pairingCacheDir(); - QString _pairingCacheFile(QString uavName); + bool _firstBoot = true; + QStringList _deviceList; + + void _parsePairingJsonFile (); + QJsonDocument _createZeroTierConnectJson (QString cert2); + QJsonDocument _createMicrohardConnectJson (QString cert2); + QJsonDocument _createZeroTierPairingJson (QString cert1); + QJsonDocument _createMicrohardPairingJson (QString pwd, QString cert1); + QString _assumeMicrohardPairingJson (); + void _writeJson (QJsonDocument &jsonDoc, QString fileName); + QString _getLocalIPInNetwork (QString remoteIP, int num); + void _uploadFinished (); + void _uploadError (QNetworkReply::NetworkError code); + void _pairingCompleted (QString name); + void _connectionCompleted (QString name); + QDir _pairingCacheDir (); + QString _pairingCacheFile (QString uavName); + void _updatePairedDeviceNameList (); #if defined QGC_ENABLE_NFC || defined QGC_ENABLE_QTNFC - PairingNFC pairingNFC; + PairingNFC pairingNFC; #endif }; diff --git a/src/ui/preferences/GeneralSettings.qml b/src/ui/preferences/GeneralSettings.qml index d0dc21807577c9eb0b92130a6d1b28735be12ac9..2809c201da091f8410b677f5911b56423502ef05 100644 --- a/src/ui/preferences/GeneralSettings.qml +++ b/src/ui/preferences/GeneralSettings.qml @@ -484,14 +484,14 @@ Rectangle { } FactCheckBox { text: qsTr("Show additional heading indicators on Compass") - visible: _showAdditionalIndicatorsCompass.visible + visible: _showAdditionalIndicatorsCompass ? _showAdditionalIndicatorsCompass.visible : false fact: _showAdditionalIndicatorsCompass property Fact _showAdditionalIndicatorsCompass: QGroundControl.settingsManager.flyViewSettings.showAdditionalIndicatorsCompass } FactCheckBox { text: qsTr("Lock Compass Nose-Up") - visible: _lockNoseUpCompass.visible + visible: _lockNoseUpCompass ? _lockNoseUpCompass.visible : false fact: _lockNoseUpCompass property Fact _lockNoseUpCompass: QGroundControl.settingsManager.flyViewSettings.lockNoseUpCompass