5import QGroundControl.Controls
9 spacing: ScreenTools.defaultFontPixelWidth
11 property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
12 property var _guidedController: globals.guidedControllerFlyView
13 property bool _armed: _activeVehicle ? _activeVehicle.armed : false
14 property real _margins: ScreenTools.defaultFontPixelWidth
15 property real _spacing: ScreenTools.defaultFontPixelWidth / 2
16 property bool _healthAndArmingChecksSupported: _activeVehicle ? _activeVehicle.healthAndArmingCheckReport.supported : false
17 property var _vehicleInAir: _activeVehicle ? _activeVehicle.airborne || _activeVehicle.landing : false
18 property bool _vtolInFWDFlight: _activeVehicle ? _activeVehicle.vtolInFwdFlight : false
19 property bool _rebootRequired: _activeVehicle ? _activeVehicle.rebootRequired : false
21 function dropMainStatusIndicator() {
22 let overallStatusComponent = _activeVehicle ? overallStatusIndicatorPage : overallStatusOfflineIndicatorPage
23 mainWindow.showIndicatorDrawer(overallStatusComponent, control)
26 QGCPalette { id: qgcPal }
30 Layout.fillHeight: true
31 Layout.preferredWidth: Math.max(contentWidth,
32 criticalMessageBadge.width + rebootRequiredIcon.width +
33 firmwareUpdateBadge.width + ScreenTools.defaultFontPixelWidth * 0.5)
34 verticalAlignment: Text.AlignVCenter
35 text: mainStatusText()
37 font.pointSize: ScreenTools.largeFontPointSize
39 property string _commLostText: qsTr("Comms Lost")
40 property string _readyToFlyText: qsTr("Ready")
41 property string _notReadyToFlyText: qsTr("Not Ready")
42 property string _disconnectedText: qsTr("Disconnected - Click to manually connect")
43 property string _armedText: qsTr("Armed")
44 property string _flyingText: qsTr("Flying")
45 property string _landingText: qsTr("Landing")
47 function mainStatusText() {
50 if (_communicationLost) {
51 _mainStatusBGColor = "red"
52 return mainStatusLabel._commLostText
54 if (_activeVehicle.armed) {
55 _mainStatusBGColor = "green"
57 if (_healthAndArmingChecksSupported) {
58 if (_activeVehicle.healthAndArmingCheckReport.canArm) {
59 if (_activeVehicle.healthAndArmingCheckReport.hasWarningsOrErrors) {
60 _mainStatusBGColor = "yellow"
63 _mainStatusBGColor = "red"
67 if (_activeVehicle.underway) {
68 return mainStatusLabel._flyingText
69 } else if (_activeVehicle.landing) {
70 return mainStatusLabel._landingText
72 return mainStatusLabel._armedText
75 if (_healthAndArmingChecksSupported) {
76 if (_activeVehicle.healthAndArmingCheckReport.canArm) {
77 if (_activeVehicle.healthAndArmingCheckReport.hasWarningsOrErrors) {
78 _mainStatusBGColor = "yellow"
80 _mainStatusBGColor = "green"
82 return mainStatusLabel._readyToFlyText
84 _mainStatusBGColor = "red"
85 return mainStatusLabel._notReadyToFlyText
87 } else if (_activeVehicle.readyToFlyAvailable) {
88 if (_activeVehicle.readyToFly) {
89 _mainStatusBGColor = "green"
90 return mainStatusLabel._readyToFlyText
92 _mainStatusBGColor = "yellow"
93 return mainStatusLabel._notReadyToFlyText
96 // Best we can do is determine readiness based on AutoPilot component setup and health indicators from SYS_STATUS
97 if (_activeVehicle.allSensorsHealthy && _activeVehicle.autopilotPlugin.setupComplete) {
98 _mainStatusBGColor = "green"
99 return mainStatusLabel._readyToFlyText
101 _mainStatusBGColor = "yellow"
102 return mainStatusLabel._notReadyToFlyText
107 _mainStatusBGColor = qgcPal.brandPrimary
108 return mainStatusLabel._disconnectedText
113 id: criticalMessageBadge
114 anchors.top: parent.top
115 anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.25
116 anchors.right: parent.right
117 width: ScreenTools.defaultFontPixelHeight
120 color: qgcPal.colorRed
121 visible: _criticalMessageCount > 0
123 property int _criticalMessageCount: _activeVehicle ? _activeVehicle.criticalMessageCount : 0
126 anchors.centerIn: parent
127 text: criticalMessageBadge._criticalMessageCount > 9 ? "!" : criticalMessageBadge._criticalMessageCount.toString()
128 color: qgcPal.buttonHighlightText
129 font.pointSize: ScreenTools.smallFontPointSize
135 id: rebootRequiredIcon
136 objectName: "mainStatusRebootRequiredIcon"
137 anchors.verticalCenter: criticalMessageBadge.verticalCenter
138 anchors.right: criticalMessageBadge.visible ? criticalMessageBadge.left : parent.right
139 anchors.rightMargin: criticalMessageBadge.visible ? ScreenTools.defaultFontPixelWidth * 0.25 : 0
140 width: criticalMessageBadge.width * 0.9
142 source: "/res/PowerButton.svg"
143 color: qgcPal.colorOrange
144 visible: _rebootRequired
148 id: firmwareUpdateBadge
149 objectName: "mainStatusFirmwareUpdateBadge"
150 anchors.verticalCenter: criticalMessageBadge.verticalCenter
151 anchors.right: rebootRequiredIcon.visible ? rebootRequiredIcon.left : (criticalMessageBadge.visible ? criticalMessageBadge.left : parent.right)
152 anchors.rightMargin: (rebootRequiredIcon.visible || criticalMessageBadge.visible) ? ScreenTools.defaultFontPixelWidth * 0.25 : 0
153 width: criticalMessageBadge.width
156 color: Qt.rgba(1, 1, 1, 0.75)
157 visible: _activeVehicle ? _activeVehicle.newStableFirmwareVersion !== "" && !_activeVehicle.newStableFirmwareVersionAcknowledged : false
161 source: "/res/UpdateAvailable.svg"
162 color: qgcPal.colorBlue
168 onClicked: dropMainStatusIndicator()
174 Layout.fillHeight: true
175 verticalAlignment: Text.AlignVCenter
176 text: _vtolInFWDFlight ? qsTr("FW(vtol)") : qsTr("MR(vtol)")
178 font.pointSize: _vehicleInAir ? ScreenTools.largeFontPointSize : ScreenTools.defaultFontPointSize
179 visible: _activeVehicle && _activeVehicle.vtol
185 mainWindow.showIndicatorDrawer(vtolTransitionIndicatorPage)
192 id: overallStatusOfflineIndicatorPage
194 MainStatusIndicatorOfflinePage {
195 Component.onCompleted: mainWindow.suppressCriticalVehicleMessages = true
196 Component.onDestruction: mainWindow.suppressCriticalVehicleMessages = false
201 id: overallStatusIndicatorPage
204 waitForParameters: false
206 contentComponent: mainStatusContentComponent
208 Component.onCompleted: mainWindow.suppressCriticalVehicleMessages = true
209 Component.onDestruction: mainWindow.suppressCriticalVehicleMessages = false
214 id: mainStatusContentComponent
220 property bool parametersReady: QGroundControl.multiVehicleManager.parameterReadyVehicleAvailable
223 Layout.fillWidth: true
224 spacing: ScreenTools.defaultFontPixelWidth
225 // Stop controls must stay reachable without parameters
226 visible: parametersReady || _guidedController.showEmergencyStop || _guidedController.showDisarm || _rebootRequired
229 objectName: "mainStatusArmButton"
230 enabled: _armed || _guidedController.showArm
231 text: _armed ? qsTr("Disarm") : qsTr("Arm")
232 visible: _armed ? _guidedController.showDisarm : parametersReady
235 _activeVehicle.armed = !_armed
236 mainWindow.closeIndicatorDrawer()
241 objectName: "mainStatusEmergencyStopButton"
242 text: qsTr("Emergency Stop")
243 backgroundColor: qgcPal.colorRed
244 textColor: qgcPal.buttonHighlightText
245 fontWeight: Font.Bold
246 visible: _guidedController.showEmergencyStop
249 _guidedController.confirmAction(_guidedController.actionEmergencyStop)
250 mainWindow.closeIndicatorDrawer()
255 text: qsTr("Force Arm")
256 visible: parametersReady && _guidedController.showForceArm
259 _activeVehicle.forceArm()
260 mainWindow.closeIndicatorDrawer()
266 Layout.alignment: Qt.AlignTop
267 label: qsTr("Primary Link")
268 alternateText: _primaryLinkName
269 visible: parametersReady && _activeVehicle && _activeVehicle.vehicleLinkManager.linkNames.length > 1
271 property var _rgLinkNames: _activeVehicle ? _activeVehicle.vehicleLinkManager.linkNames : [ ]
272 property var _rgLinkStatus: _activeVehicle ? _activeVehicle.vehicleLinkManager.linkStatuses : [ ]
273 property string _primaryLinkName: _activeVehicle ? _activeVehicle.vehicleLinkManager.primaryLinkName : ""
275 function updateComboModel() {
277 for (let i = 0; i < _rgLinkNames.length; i++) {
278 let linkStatus = _rgLinkStatus[i]
279 linkModel.push(_rgLinkNames[i] + (linkStatus === "" ? "" : " " + _rgLinkStatus[i]))
281 primaryLinkCombo.model = linkModel
282 primaryLinkCombo.currentIndex = -1
285 Component.onCompleted: updateComboModel()
286 on_RgLinkNamesChanged: updateComboModel()
287 on_RgLinkStatusChanged: updateComboModel()
289 onActivated: (index) => {
290 _activeVehicle.vehicleLinkManager.primaryLinkName = _rgLinkNames[index]; currentIndex = -1
291 mainWindow.closeIndicatorDrawer()
295 Item { Layout.fillWidth: true }
298 Layout.maximumWidth: ScreenTools.defaultFontPixelWidth * 16
299 Layout.maximumHeight: rebootButton.height
300 text: qsTr("Reboot required for changes to take effect")
301 font.pointSize: ScreenTools.smallFontPointSize
302 wrapMode: Text.WordWrap
303 elide: Text.ElideRight
304 horizontalAlignment: Text.AlignRight
305 visible: _rebootRequired && !_armed
309 objectName: "mainStatusRebootDisarmLabel"
310 Layout.maximumWidth: ScreenTools.defaultFontPixelWidth * 16
311 Layout.maximumHeight: rebootButton.height
312 text: qsTr("Reboot required. Disarm vehicle first.")
313 font.pointSize: ScreenTools.smallFontPointSize
314 wrapMode: Text.WordWrap
315 elide: Text.ElideRight
316 horizontalAlignment: Text.AlignRight
317 visible: _rebootRequired && _armed
322 objectName: "mainStatusRebootButton"
323 text: qsTr("Reboot Vehicle")
324 visible: _rebootRequired && !_armed
327 _activeVehicle.rebootVehicle()
328 mainWindow.closeIndicatorDrawer()
334 Layout.fillWidth: true
335 spacing: ScreenTools.defaultFontPixelWidth
336 visible: _activeVehicle && _activeVehicle.newStableFirmwareVersion !== ""
339 objectName: "mainStatusFirmwareUpdateLabel"
340 text: _activeVehicle ? qsTr("Firmware update available: %1.%2.%3 → %4")
341 .arg(_activeVehicle.firmwareMajorVersion)
342 .arg(_activeVehicle.firmwareMinorVersion)
343 .arg(_activeVehicle.firmwarePatchVersion)
344 .arg(_activeVehicle.newStableFirmwareVersion) : ""
348 objectName: "mainStatusFirmwareUpdateAckButton"
349 implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding
351 leftPadding: ScreenTools.defaultFontPixelWidth
352 rightPadding: leftPadding
353 text: qsTr("Acknowledge and Hide")
354 pointSize: ScreenTools.smallFontPointSize
355 visible: _activeVehicle && !_activeVehicle.newStableFirmwareVersionAcknowledged
356 onClicked: _activeVehicle.acknowledgeNewStableFirmwareVersion()
360 SettingsGroupLayout {
361 Layout.fillWidth: true
362 heading: qsTr("Vehicle Messages")
365 id: vehicleMessageList
366 Layout.fillWidth: true
371 text: qsTr("No new vehicle messages")
372 visible: vehicleMessageList.noMessages
376 SettingsGroupLayout {
377 Layout.fillWidth: true
378 heading: qsTr("Sensor Status")
379 visible: parametersReady && !_healthAndArmingChecksSupported
383 columnSpacing: _spacing
384 rows: _activeVehicle.sysStatusSensorInfo.sensorNames.length
385 flow: GridLayout.TopToBottom
388 model: _activeVehicle.sysStatusSensorInfo.sensorNames
389 QGCLabel { text: modelData }
393 model: _activeVehicle.sysStatusSensorInfo.sensorStatus
394 QGCLabel { text: modelData }
399 SettingsGroupLayout {
400 Layout.fillWidth: true
401 heading: qsTr("Overall Status")
402 visible: parametersReady && _healthAndArmingChecksSupported && _activeVehicle.healthAndArmingCheckReport.problemsForCurrentMode.count > 0
404 // List health and arming checks
406 model: _activeVehicle ? _activeVehicle.healthAndArmingCheckReport.problemsForCurrentMode : null
407 delegate: listdelegate
415 Layout.fillWidth: true
419 Layout.fillWidth: true
420 spacing: ScreenTools.defaultFontPixelHeight
424 Layout.fillWidth: true
425 // Rounded up: the layout's whole-pixel width would otherwise wrap a short message
426 Layout.maximumWidth: Math.ceil(implicitWidth)
428 textFormat: TextEdit.RichText
429 wrapMode: Text.WordWrap
430 color: object.severity == 'error' ? qgcPal.colorRed : object.severity == 'warning' ? qgcPal.colorOrange : qgcPal.text
434 if (object.description != "")
435 object.expanded = !object.expanded
441 id: arrowDownIndicator
442 Layout.alignment: Qt.AlignVCenter
443 Layout.preferredHeight: 1.5 * ScreenTools.defaultFontPixelWidth
444 Layout.preferredWidth: Layout.preferredHeight
445 source: "/qmlimages/arrow-down.png"
447 visible: object.description != ""
450 onClicked: object.expanded = !object.expanded
457 Layout.fillWidth: true
458 text: object.description
459 textFormat: TextEdit.RichText
460 wrapMode: Text.WordWrap
462 visible: object.expanded
464 property var fact: null
466 onLinkActivated: (link) => {
467 if (link.startsWith('param://')) {
468 var paramName = link.substr(8);
469 fact = controller.getParameterFact(-1, paramName, true)
471 paramEditorDialogFactory.open()
474 Qt.openUrlExternally(link);
478 FactPanelController {
482 QGCPopupDialogFactory {
483 id: paramEditorDialogFactory
485 dialogComponent: paramEditorDialogComponent
489 id: paramEditorDialogComponent
491 ParameterEditorDialog {
492 title: qsTr("Edit Parameter")
493 fact: description.fact