diff --git a/QGCApplication.pro b/QGCApplication.pro
index acc9756e1ed0f7f330248c2c82467b881089f252..d9be8e77697cc6a7081544e9832a59ac039a0224 100644
--- a/QGCApplication.pro
+++ b/QGCApplication.pro
@@ -635,7 +635,8 @@ SOURCES += \
# Fact System code
INCLUDEPATH += \
- src/FactSystem
+ src/FactSystem \
+ src/FactSystem/FactControls \
HEADERS += \
src/FactSystem/Fact.h \
@@ -644,6 +645,7 @@ HEADERS += \
src/FactSystem/FactSystem.h \
src/FactSystem/FactValidator.h \
src/FactSystem/ParameterLoader.h \
+ src/FactSystem/FactControls/FactPanelController.h \
SOURCES += \
src/FactSystem/Fact.cc \
@@ -652,6 +654,7 @@ SOURCES += \
src/FactSystem/FactSystem.cc \
src/FactSystem/FactValidator.cc \
src/FactSystem/ParameterLoader.cc \
+ src/FactSystem/FactControls/FactPanelController.cc \
# Android
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index c3b264b8a1866729cefe8cc7d5cbc1631d030235..b2fc060de43c52a7212ee9e71824676d621f34bb 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -9,6 +9,7 @@
src/QmlControls/QmlTest.qml
src/FactSystem/FactControls/qmldir
+ src/FactSystem/FactControls/FactPanel.qml
src/FactSystem/FactControls/FactLabel.qml
src/FactSystem/FactControls/FactTextField.qml
src/FactSystem/FactControls/FactCheckBox.qml
diff --git a/src/AutoPilotPlugins/PX4/AirframeComponent.qml b/src/AutoPilotPlugins/PX4/AirframeComponent.qml
index 96ea119466f74195ae5d092b7d9416558b562b0e..b7a483768cb5fddbde800432d810d2127cc4fdcc 100644
--- a/src/AutoPilotPlugins/PX4/AirframeComponent.qml
+++ b/src/AutoPilotPlugins/PX4/AirframeComponent.qml
@@ -31,125 +31,132 @@ import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Controllers 1.0
-Rectangle {
- AirframeComponentController { id: controller }
- QGCPalette { id: qgcPal; colorGroupEnabled: true }
+FactPanel {
+ id: panel
- color: qgcPal.window
+ AirframeComponentController { id: controller; factPanel: panel }
- Column {
+ Rectangle {
anchors.fill: parent
- QGCLabel {
- text: "AIRFRAME CONFIG"
- font.pointSize: 20
- }
+ QGCPalette { id: qgcPal; colorGroupEnabled: true }
- Item { height: 20; width: 10 } // spacer
+ color: qgcPal.window
- Row {
- width: parent.width
+ Column {
+ anchors.fill: parent
QGCLabel {
- width: parent.width - applyButton.width
- text: "Select you airframe type and specific vehicle bellow. Click 'Apply and Restart' when ready and your vehicle will be disconnected, rebooted to the new settings and re-connected."
- wrapMode: Text.WordWrap
+ text: "AIRFRAME CONFIG"
+ font.pointSize: 20
}
- QGCButton {
- id: applyButton
- text: "Apply and Restart"
- onClicked: { controller.changeAutostart() }
- }
- }
+ Item { height: 20; width: 10 } // spacer
- Item { height: 20; width: 10 } // spacer
+ Row {
+ width: parent.width
- Flow {
- width: parent.width
- spacing: 10
+ QGCLabel {
+ width: parent.width - applyButton.width
+ text: "Select you airframe type and specific vehicle bellow. Click 'Apply and Restart' when ready and your vehicle will be disconnected, rebooted to the new settings and re-connected."
+ wrapMode: Text.WordWrap
+ }
- ExclusiveGroup {
- id: airframeTypeExclusive
+ QGCButton {
+ id: applyButton
+ text: "Apply and Restart"
+ onClicked: { controller.changeAutostart() }
+ }
}
- Repeater {
- model: controller.airframeTypes
+ Item { height: 20; width: 10 } // spacer
- // Outer summary item rectangle
- Rectangle {
- readonly property real titleHeight: 30
- readonly property real innerMargin: 10
+ Flow {
+ width: parent.width
+ spacing: 10
- width: 250
- height: 200
- color: qgcPal.windowShade
+ ExclusiveGroup {
+ id: airframeTypeExclusive
+ }
+
+ Repeater {
+ model: controller.airframeTypes
+ // Outer summary item rectangle
Rectangle {
- id: title
- width: parent.width
- height: parent.titleHeight
- color: qgcPal.windowShadeDark
+ readonly property real titleHeight: 30
+ readonly property real innerMargin: 10
- Text {
- anchors.fill: parent
+ width: 250
+ height: 200
+ color: qgcPal.windowShade
- color: qgcPal.buttonText
- font.pixelSize: 12
- text: modelData.name
+ Rectangle {
+ id: title
+ width: parent.width
+ height: parent.titleHeight
+ color: qgcPal.windowShadeDark
- verticalAlignment: TextEdit.AlignVCenter
- horizontalAlignment: TextEdit.AlignHCenter
- }
- }
+ Text {
+ anchors.fill: parent
- Image {
- id: image
- x: innerMargin
- width: parent.width - (innerMargin * 2)
- height: parent.height - title.height - combo.height - (innerMargin * 3)
- anchors.topMargin: innerMargin
- anchors.top: title.bottom
+ color: qgcPal.buttonText
+ font.pixelSize: 12
+ text: modelData.name
- source: modelData.imageResource
- fillMode: Image.PreserveAspectFit
- smooth: true
+ verticalAlignment: TextEdit.AlignVCenter
+ horizontalAlignment: TextEdit.AlignHCenter
+ }
+ }
- }
+ Image {
+ id: image
+ x: innerMargin
+ width: parent.width - (innerMargin * 2)
+ height: parent.height - title.height - combo.height - (innerMargin * 3)
+ anchors.topMargin: innerMargin
+ anchors.top: title.bottom
+
+ source: modelData.imageResource
+ fillMode: Image.PreserveAspectFit
+ smooth: true
- QGCCheckBox {
- id: airframeCheckBox
- anchors.bottom: image.bottom
- anchors.right: image.right
- checked: modelData.name == controller.currentAirframeType
- exclusiveGroup: airframeTypeExclusive
+ }
- onCheckedChanged: {
- if (checked && combo.currentIndex != -1) {
- controller.autostartId = modelData.airframes[combo.currentIndex].autostartId
+ QGCCheckBox {
+ id: airframeCheckBox
+ anchors.bottom: image.bottom
+ anchors.right: image.right
+ checked: modelData.name == controller.currentAirframeType
+ exclusiveGroup: airframeTypeExclusive
+
+ onCheckedChanged: {
+ if (checked && combo.currentIndex != -1) {
+ controller.autostartId = modelData.airframes[combo.currentIndex].autostartId
+ }
}
}
- }
- QGCComboBox {
- id: combo
- objectName: modelData.airframeType + "ComboBox"
- x: innerMargin
- anchors.topMargin: innerMargin
- anchors.top: image.bottom
- width: parent.width - (innerMargin * 2)
- model: modelData.airframes
- currentIndex: (modelData.name == controller.currentAirframeType) ? controller.currentVehicleIndex : 0
-
- onCurrentIndexChanged: {
- if (airframeCheckBox.checked) {
- controller.autostartId = modelData.airframes[currentIndex].autostartId
+ QGCComboBox {
+ id: combo
+ objectName: modelData.airframeType + "ComboBox"
+ x: innerMargin
+ anchors.topMargin: innerMargin
+ anchors.top: image.bottom
+ width: parent.width - (innerMargin * 2)
+ model: modelData.airframes
+ currentIndex: (modelData.name == controller.currentAirframeType) ? controller.currentVehicleIndex : 0
+
+ onCurrentIndexChanged: {
+ if (airframeCheckBox.checked) {
+ controller.autostartId = modelData.airframes[currentIndex].autostartId
+ }
}
}
}
}
}
- }
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/AutoPilotPlugins/PX4/AirframeComponentController.cc b/src/AutoPilotPlugins/PX4/AirframeComponentController.cc
index 6e367f175a4c5ade2c3ee906876584c6c15e98a7..d0c9bf04ece1c34ab82147523d22b140fd623f1d 100644
--- a/src/AutoPilotPlugins/PX4/AirframeComponentController.cc
+++ b/src/AutoPilotPlugins/PX4/AirframeComponentController.cc
@@ -37,19 +37,13 @@
bool AirframeComponentController::_typesRegistered = false;
-AirframeComponentController::AirframeComponentController(QObject* parent) :
- QObject(parent),
+AirframeComponentController::AirframeComponentController(void) :
_uas(NULL),
- _autoPilotPlugin(NULL),
_currentVehicleIndex(0),
_autostartId(0)
{
_uas = UASManager::instance()->getActiveUAS();
Q_ASSERT(_uas);
-
- _autoPilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uas);
- Q_ASSERT(_autoPilotPlugin);
- Q_ASSERT(_autoPilotPlugin->pluginReady());
if (!_typesRegistered) {
_typesRegistered = true;
@@ -57,10 +51,16 @@ AirframeComponentController::AirframeComponentController(QObject* parent) :
qmlRegisterUncreatableType("QGroundControl.Controllers", 1, 0, "Aiframe", "Can only reference Airframe");
}
+ QStringList usedFacts;
+ usedFacts << "SYS_AUTOSTART" << "SYS_AUTOCONFIG";
+ if (!_allFactsExists(usedFacts)) {
+ return;
+ }
+
// Load up member variables
bool autostartFound = false;
- _autostartId = _autoPilotPlugin->getParameterFact("SYS_AUTOSTART")->value().toInt();
+ _autostartId = _autopilot->getParameterFact("SYS_AUTOSTART")->value().toInt();
for (const AirframeComponentAirframes::AirframeType_t* pType=&AirframeComponentAirframes::rgAirframeTypes[0]; pType->name != NULL; pType++) {
AirframeType* airframeType = new AirframeType(pType->name, pType->imageResource, this);
@@ -81,7 +81,7 @@ AirframeComponentController::AirframeComponentController(QObject* parent) :
_airframeTypes.append(QVariant::fromValue(airframeType));
}
-
+
if (_autostartId != 0) {
// FIXME: Should be a user error
Q_UNUSED(autostartFound);
@@ -101,8 +101,8 @@ void AirframeComponentController::changeAutostart(void)
return;
}
- _autoPilotPlugin->getParameterFact("SYS_AUTOSTART")->setValue(_autostartId);
- _autoPilotPlugin->getParameterFact("SYS_AUTOCONFIG")->setValue(1);
+ _autopilot->getParameterFact("SYS_AUTOSTART")->setValue(_autostartId);
+ _autopilot->getParameterFact("SYS_AUTOCONFIG")->setValue(1);
qgcApp()->setOverrideCursor(Qt::WaitCursor);
diff --git a/src/AutoPilotPlugins/PX4/AirframeComponentController.h b/src/AutoPilotPlugins/PX4/AirframeComponentController.h
index 25ac266a348e1100d4e1418583140a1c2ebe657b..0e8b5ced752de8125c2e5edb4e33985f9df32d9d 100644
--- a/src/AutoPilotPlugins/PX4/AirframeComponentController.h
+++ b/src/AutoPilotPlugins/PX4/AirframeComponentController.h
@@ -33,14 +33,15 @@
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
+#include "FactPanelController.h"
/// MVC Controller for AirframeComponent.qml.
-class AirframeComponentController : public QObject
+class AirframeComponentController : public FactPanelController
{
Q_OBJECT
public:
- AirframeComponentController(QObject* parent = NULL);
+ AirframeComponentController(void);
~AirframeComponentController();
Q_PROPERTY(QVariantList airframeTypes MEMBER _airframeTypes CONSTANT)
@@ -63,7 +64,6 @@ private:
static bool _typesRegistered;
UASInterface* _uas;
- AutoPilotPlugin* _autoPilotPlugin;
QVariantList _airframeTypes;
QString _currentAirframeType;
QString _currentVehicleName;
diff --git a/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml b/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml
index 7677cb66775490f6f1dd4059a447c14c560829c2..2d47877e61c468c3eeb05c5426680d99859e3112 100644
--- a/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml
+++ b/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml
@@ -1,35 +1,39 @@
import QtQuick 2.2
import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Controllers 1.0
-Column {
- Fact { id: sysIdFact; name: "MAV_SYS_ID" }
- Fact { id: sysAutoStartFact; name: "SYS_AUTOSTART" }
+FactPanel {
+ id: panel
+ anchors.fill: parent
- property bool autoStartSet: sysAutoStartFact.value != 0
+ AirframeComponentController { id: controller; factPanel: panel }
- anchors.fill: parent
- anchors.margins: 8
+ Fact { id: sysIdFact; name: "MAV_SYS_ID"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: sysAutoStartFact; name: "SYS_AUTOSTART"; onFactMissing: showMissingFactOverlay(name) }
- AirframeComponentController { id: controller }
+ property bool autoStartSet: sysAutoStartFact.value != 0
- VehicleSummaryRow {
- labelText: "System ID:"
- valueText: sysIdFact.valueString
- }
+ Column {
+ anchors.fill: parent
+ anchors.margins: 8
- VehicleSummaryRow {
- labelText: "Airframe type:"
- valueText: autoStartSet ? controller.currentAirframeType : "Setup required"
- }
+ VehicleSummaryRow {
+ labelText: "System ID:"
+ valueText: sysIdFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "Airframe type:"
+ valueText: autoStartSet ? controller.currentAirframeType : "Setup required"
+ }
- VehicleSummaryRow {
- labelText: "Vehicle:"
- valueText: autoStartSet ? controller.currentVehicleName : "Setup required"
+ VehicleSummaryRow {
+ labelText: "Vehicle:"
+ valueText: autoStartSet ? controller.currentVehicleName : "Setup required"
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/AutoPilotPlugins/PX4/FlightModesComponentSummary.qml b/src/AutoPilotPlugins/PX4/FlightModesComponentSummary.qml
index a61aa64575dddf9fd50821eb483ae18abfc1deff..451bf8aa32990595e0e7819f5657c5e8f6cb90ab 100644
--- a/src/AutoPilotPlugins/PX4/FlightModesComponentSummary.qml
+++ b/src/AutoPilotPlugins/PX4/FlightModesComponentSummary.qml
@@ -1,36 +1,40 @@
import QtQuick 2.2
import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
+import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
-Column {
- Fact { id: modeSwFact; name: "RC_MAP_MODE_SW" }
- Fact { id: posCtlSwFact; name: "RC_MAP_POSCTL_SW" }
- Fact { id: loiterSwFact; name: "RC_MAP_LOITER_SW" }
- Fact { id: returnSwFact; name: "RC_MAP_RETURN_SW" }
+FactPanel {
+ anchors.fill: parent
- anchors.fill: parent
- anchors.margins: 8
+ Fact { id: modeSwFact; name: "RC_MAP_MODE_SW"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: posCtlSwFact; name: "RC_MAP_POSCTL_SW"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: loiterSwFact; name: "RC_MAP_LOITER_SW"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: returnSwFact; name: "RC_MAP_RETURN_SW"; onFactMissing: showMissingFactOverlay(name) }
- VehicleSummaryRow {
- labelText: "Mode switch:"
- valueText: modeSwFact.value == 0 ? "Setup required" : modeSwFact.valueString
- }
+ Column {
+ anchors.fill: parent
+ anchors.margins: 8
- VehicleSummaryRow {
- labelText: "Position Ctl switch:"
- valueText: posCtlSwFact.value == 0 ? "Disabled" : posCtlSwFact.valueString
- }
+ VehicleSummaryRow {
+ labelText: "Mode switch:"
+ valueText: modeSwFact.value == 0 ? "Setup required" : modeSwFact.valueString
+ }
- VehicleSummaryRow {
- labelText: "Loiter switch:"
- valueText: loiterSwFact.value == 0 ? "Disabled" : loiterSwFact.valueString
- }
+ VehicleSummaryRow {
+ labelText: "Position Ctl switch:"
+ valueText: posCtlSwFact.value == 0 ? "Disabled" : posCtlSwFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "Loiter switch:"
+ valueText: loiterSwFact.value == 0 ? "Disabled" : loiterSwFact.valueString
+ }
- VehicleSummaryRow {
- labelText: "Return switch:"
- valueText: returnSwFact.value == 0 ? "Disabled" : returnSwFact.valueString
+ VehicleSummaryRow {
+ labelText: "Return switch:"
+ valueText: returnSwFact.value == 0 ? "Disabled" : returnSwFact.valueString
+ }
}
}
diff --git a/src/AutoPilotPlugins/PX4/PowerComponentSummary.qml b/src/AutoPilotPlugins/PX4/PowerComponentSummary.qml
index 6577fe9bcc435221d49770852ae2f83aedc19531..86c3800fa9f13030d02d559d0f402cde1d645e44 100644
--- a/src/AutoPilotPlugins/PX4/PowerComponentSummary.qml
+++ b/src/AutoPilotPlugins/PX4/PowerComponentSummary.qml
@@ -27,32 +27,35 @@
import QtQuick 2.2
import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
-Column {
- Fact { id: batVChargedFact; name: "BAT_V_CHARGED" }
- Fact { id: batVEmptyFact; name: "BAT_V_EMPTY" }
- Fact { id: batCellsFact; name: "BAT_N_CELLS" }
+FactPanel {
+ anchors.fill: parent
- anchors.fill: parent
- anchors.margins: 8
+ Fact { id: batVChargedFact; name: "BAT_V_CHARGED"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: batVEmptyFact; name: "BAT_V_EMPTY"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: batCellsFact; name: "BAT_N_CELLS"; onFactMissing: showMissingFactOverlay(name) }
- VehicleSummaryRow {
- labelText: "Battery Full:"
- valueText: batVChargedFact.valueString
- }
+ Column {
+ anchors.fill: parent
+ anchors.margins: 8
- VehicleSummaryRow {
- labelText: "Battery Empty:"
- valueText: batVEmptyFact.valueString
- }
+ VehicleSummaryRow {
+ labelText: "Battery Full:"
+ valueText: batVChargedFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "Battery Empty:"
+ valueText: batVEmptyFact.valueString
+ }
- VehicleSummaryRow {
- labelText: "Number of Cells:"
- valueText: batCellsFact.valueString
+ VehicleSummaryRow {
+ labelText: "Number of Cells:"
+ valueText: batCellsFact.valueString
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/AutoPilotPlugins/PX4/RadioComponentSummary.qml b/src/AutoPilotPlugins/PX4/RadioComponentSummary.qml
index 4038a6161b21980a18938dce14a704616652fe0e..d74e4552d1d250f80367367b9555a8ab3c7ae546 100644
--- a/src/AutoPilotPlugins/PX4/RadioComponentSummary.qml
+++ b/src/AutoPilotPlugins/PX4/RadioComponentSummary.qml
@@ -1,54 +1,58 @@
import QtQuick 2.2
import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
+import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
-Column {
- Fact { id: mapRollFact; name: "RC_MAP_ROLL" }
- Fact { id: mapPitchFact; name: "RC_MAP_PITCH" }
- Fact { id: mapYawFact; name: "RC_MAP_YAW" }
- Fact { id: mapThrottleFact; name: "RC_MAP_THROTTLE" }
- Fact { id: mapFlapsFact; name: "RC_MAP_FLAPS" }
- Fact { id: mapAux1Fact; name: "RC_MAP_AUX1" }
- Fact { id: mapAux2Fact; name: "RC_MAP_AUX2" }
-
- anchors.fill: parent
- anchors.margins: 8
-
- VehicleSummaryRow {
- labelText: "Roll:"
- valueText: mapRollFact.value == 0 ? "Setup required" : mapRollFact.valueString
- }
-
- VehicleSummaryRow {
- labelText: "Pitch:"
- valueText: mapPitchFact.value == 0 ? "Setup required" : mapPitchFact.valueString
- }
-
- VehicleSummaryRow {
- labelText: "Yaw:"
- valueText: mapYawFact.value == 0 ? "Setup required" : mapYawFact.valueString
- }
-
- VehicleSummaryRow {
- labelText: "Throttle:"
- valueText: mapThrottleFact.value == 0 ? "Setup required" : mapThrottleFact.valueString
- }
-
- VehicleSummaryRow {
- labelText: "Flaps:"
- valueText: mapFlapsFact.value == 0 ? "Disabled" : mapFlapsFact.valueString
- }
-
- VehicleSummaryRow {
- labelText: "Aux1:"
- valueText: mapAux1Fact.value == 0 ? "Disabled" : mapAux1Fact.valueString
- }
-
- VehicleSummaryRow {
- labelText: "Aux2:"
- valueText: mapAux2Fact.value == 0 ? "Disabled" : mapAux2Fact.valueString
+FactPanel {
+ anchors.fill: parent
+
+ Fact { id: mapRollFact; name: "RC_MAP_ROLL"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: mapPitchFact; name: "RC_MAP_PITCH"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: mapYawFact; name: "RC_MAP_YAW"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: mapThrottleFact; name: "RC_MAP_THROTTLE"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: mapFlapsFact; name: "RC_MAP_FLAPS"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: mapAux1Fact; name: "RC_MAP_AUX1"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: mapAux2Fact; name: "RC_MAP_AUX2"; onFactMissing: showMissingFactOverlay(name) }
+
+ Column {
+ anchors.fill: parent
+ anchors.margins: 8
+
+ VehicleSummaryRow {
+ labelText: "Roll:"
+ valueText: mapRollFact.value == 0 ? "Setup required" : mapRollFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "Pitch:"
+ valueText: mapPitchFact.value == 0 ? "Setup required" : mapPitchFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "Yaw:"
+ valueText: mapYawFact.value == 0 ? "Setup required" : mapYawFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "Throttle:"
+ valueText: mapThrottleFact.value == 0 ? "Setup required" : mapThrottleFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "Flaps:"
+ valueText: mapFlapsFact.value == 0 ? "Disabled" : mapFlapsFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "Aux1:"
+ valueText: mapAux1Fact.value == 0 ? "Disabled" : mapAux1Fact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "Aux2:"
+ valueText: mapAux2Fact.value == 0 ? "Disabled" : mapAux2Fact.valueString
+ }
}
}
diff --git a/src/AutoPilotPlugins/PX4/SafetyComponentSummary.qml b/src/AutoPilotPlugins/PX4/SafetyComponentSummary.qml
index f55be12b61ed816b7b5615245f2ed3945b7221df..f5acedbc0454facbfe37bd89ad4b45c35f31660f 100644
--- a/src/AutoPilotPlugins/PX4/SafetyComponentSummary.qml
+++ b/src/AutoPilotPlugins/PX4/SafetyComponentSummary.qml
@@ -1,43 +1,46 @@
import QtQuick 2.2
import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
-Column {
- Fact { id: returnAltFact; name: "RTL_RETURN_ALT" }
- Fact { id: descendAltFact; name: "RTL_DESCEND_ALT" }
- Fact { id: landDelayFact; name: "RTL_LAND_DELAY" }
- Fact { id: commDLLossFact; name: "COM_DL_LOSS_EN" }
- Fact { id: commRCLossFact; name: "COM_RC_LOSS_T" }
-
- anchors.fill: parent
- anchors.margins: 8
-
- VehicleSummaryRow {
- labelText: "RTL min alt:"
- valueText: returnAltFact.valueString
- }
-
- VehicleSummaryRow {
- labelText: "RTL home alt:"
- valueText: descendAltFact.valueString
- }
-
- VehicleSummaryRow {
- labelText: "RTL loiter delay:"
- valueText: landDelayFact.value < 0 ? "Disabled" : landDelayFact.valueString
- }
-
- VehicleSummaryRow {
- labelText: "Telemetry loss RTL:"
- valueText: commDLLossFact.value != -1 ? "Disabled" : commDLLossFact.valueString
- }
-
- VehicleSummaryRow {
- labelText: "RC loss RTL (seconds):"
- valueText: commRCLossFact.valueString
+FactPanel {
+ anchors.fill: parent
+
+ Fact { id: returnAltFact; name: "RTL_RETURN_ALT"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: descendAltFact; name: "RTL_DESCEND_ALT"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: landDelayFact; name: "RTL_LAND_DELAY"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: commDLLossFact; name: "COM_DL_LOSS_EN"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: commRCLossFact; name: "COM_RC_LOSS_T"; onFactMissing: showMissingFactOverlay(name) }
+
+ Column {
+ anchors.fill: parent
+ anchors.margins: 8
+
+ VehicleSummaryRow {
+ labelText: "RTL min alt:"
+ valueText: returnAltFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "RTL home alt:"
+ valueText: descendAltFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "RTL loiter delay:"
+ valueText: landDelayFact.value < 0 ? "Disabled" : landDelayFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "Telemetry loss RTL:"
+ valueText: commDLLossFact.value != -1 ? "Disabled" : commDLLossFact.valueString
+ }
+
+ VehicleSummaryRow {
+ labelText: "RC loss RTL (seconds):"
+ valueText: commRCLossFact.valueString
+ }
}
}
diff --git a/src/AutoPilotPlugins/PX4/SensorsComponentSummary.qml b/src/AutoPilotPlugins/PX4/SensorsComponentSummary.qml
index 3fabc547a18722c97237e55d7ca5e8b3f606580a..b79a2206f30b4a68864053ee49231404a6c0858f 100644
--- a/src/AutoPilotPlugins/PX4/SensorsComponentSummary.qml
+++ b/src/AutoPilotPlugins/PX4/SensorsComponentSummary.qml
@@ -3,32 +3,37 @@ import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
+import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
/*
IMPORTANT NOTE: Any changes made here must also be made to SensorsComponentSummary.qml
*/
-Column {
- Fact { id: mag0IdFact; name: "CAL_MAG0_ID" }
- Fact { id: gyro0IdFact; name: "CAL_GYRO0_ID" }
- Fact { id: accel0IdFact; name: "CAL_ACC0_ID" }
+FactPanel {
+ anchors.fill: parent
- anchors.fill: parent
- anchors.margins: 8
+ Fact { id: mag0IdFact; name: "CAL_MAG0_ID"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: gyro0IdFact; name: "CAL_GYRO0_ID"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: accel0IdFact; name: "CAL_ACC0_ID"; onFactMissing: showMissingFactOverlay(name) }
- VehicleSummaryRow {
- labelText: "Compass:"
- valueText: mag0IdFact.value == 0 ? "Setup required" : "Ready"
- }
+ Column {
+ anchors.fill: parent
+ anchors.margins: 8
- VehicleSummaryRow {
- labelText: "Gyro:"
- valueText: gyro0IdFact.value == 0 ? "Setup required" : "Ready"
- }
+ VehicleSummaryRow {
+ labelText: "Compass:"
+ valueText: mag0IdFact.value == 0 ? "Setup required" : "Ready"
+ }
+
+ VehicleSummaryRow {
+ labelText: "Gyro:"
+ valueText: gyro0IdFact.value == 0 ? "Setup required" : "Ready"
+ }
- VehicleSummaryRow {
- labelText: "Accelerometer:"
- valueText: accel0IdFact.value == 0 ? "Setup required" : "Ready"
+ VehicleSummaryRow {
+ labelText: "Accelerometer:"
+ valueText: accel0IdFact.value == 0 ? "Setup required" : "Ready"
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/AutoPilotPlugins/PX4/SensorsComponentSummaryFixedWing.qml b/src/AutoPilotPlugins/PX4/SensorsComponentSummaryFixedWing.qml
index 7705086747fff718f256f4369494166726c98713..23580cafa906502cd9a408dabb22b488dd0441de 100644
--- a/src/AutoPilotPlugins/PX4/SensorsComponentSummaryFixedWing.qml
+++ b/src/AutoPilotPlugins/PX4/SensorsComponentSummaryFixedWing.qml
@@ -1,40 +1,44 @@
import QtQuick 2.2
import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
+import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
/*
IMPORTANT NOTE: Any changes made here must also be made to SensorsComponentSummary.qml
*/
-Column {
- Fact { id: mag0IdFact; name: "CAL_MAG0_ID" }
- Fact { id: gyro0IdFact; name: "CAL_GYRO0_ID" }
- Fact { id: accel0IdFact; name: "CAL_ACC0_ID" }
- Fact { id: dPressOffFact; name: "SENS_DPRES_OFF" }
-
- anchors.fill: parent
- anchors.margins: 8
-
- VehicleSummaryRow {
- labelText: "Compass:"
- valueText: mag0IdFact.value == 0 ? "Setup required" : "Ready"
- }
-
- VehicleSummaryRow {
- labelText: "Gyro:"
- valueText: gyro0IdFact.value == 0 ? "Setup required" : "Ready"
- }
-
- VehicleSummaryRow {
- labelText: "Accelerometer:"
- valueText: accel0IdFact.value == 0 ? "Setup required" : "Ready"
- }
-
- VehicleSummaryRow {
- labelText: "Airspeed:"
- valueText: dPressOffFact.value == 0 ? "Setup required" : "Ready"
+FactPanel {
+ anchors.fill: parent
+
+ Fact { id: mag0IdFact; name: "CAL_MAG0_ID"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: gyro0IdFact; name: "CAL_GYRO0_ID"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: accel0IdFact; name: "CAL_ACC0_ID"; onFactMissing: showMissingFactOverlay(name) }
+ Fact { id: dPressOffFact; name: "SENS_DPRES_OFF"; onFactMissing: showMissingFactOverlay(name) }
+
+ Column {
+ anchors.fill: parent
+ anchors.margins: 8
+
+ VehicleSummaryRow {
+ labelText: "Compass:"
+ valueText: mag0IdFact.value == 0 ? "Setup required" : "Ready"
+ }
+
+ VehicleSummaryRow {
+ labelText: "Gyro:"
+ valueText: gyro0IdFact.value == 0 ? "Setup required" : "Ready"
+ }
+
+ VehicleSummaryRow {
+ labelText: "Accelerometer:"
+ valueText: accel0IdFact.value == 0 ? "Setup required" : "Ready"
+ }
+
+ VehicleSummaryRow {
+ labelText: "Airspeed:"
+ valueText: dPressOffFact.value == 0 ? "Setup required" : "Ready"
+ }
}
}
diff --git a/src/FactSystem/Fact.h b/src/FactSystem/Fact.h
index 5ba11139500c74d778851970dcff5143e7195d9e..5d0cb58cf95a01e5eff16582490ceb3e0de204db 100644
--- a/src/FactSystem/Fact.h
+++ b/src/FactSystem/Fact.h
@@ -35,16 +35,11 @@
#include
/// @brief A Fact is used to hold a single value within the system.
-///
-/// Along with the value property is a set of meta data which further describes the Fact. This information is
-/// exposed through QObject Properties such that you can bind to it from QML as well as use it within C++ code.
-/// Since the meta data is common to all instances of the same Fact, it is acually stored once in a seperate object.
class Fact : public QObject
{
Q_OBJECT
public:
- //Fact(int componentId, QString name = "", FactMetaData::ValueType_t type = FactMetaData::valueTypeInt32, QObject* parent = NULL);
Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObject* parent = NULL);
// Property system methods
diff --git a/src/FactSystem/FactBinder.cc b/src/FactSystem/FactBinder.cc
index d0979c390974ef87f6a266f792f75f006b8d6b2d..55c1965d06d06ba0cac7ca2201616caec3be64c9 100644
--- a/src/FactSystem/FactBinder.cc
+++ b/src/FactSystem/FactBinder.cc
@@ -34,7 +34,8 @@
FactBinder::FactBinder(void) :
_autopilotPlugin(NULL),
_fact(NULL),
- _componentId(FactSystem::defaultComponentId)
+ _componentId(FactSystem::defaultComponentId),
+ _factMissingSignalConnected(false)
{
UASInterface* uas = UASManager::instance()->getActiveUAS();
Q_ASSERT(uas);
@@ -85,8 +86,12 @@ void FactBinder::setName(const QString& name)
emit nameChanged();
emit metaDataChanged();
} else {
- QString panicMessage("Required parameter (component id: %1, name: %2), is missing from vehicle. QGroundControl cannot operate with this firmware revision. QGroundControl will now shut down.");
- qgcApp()->panicShutdown(panicMessage.arg(_componentId).arg(parsedName));
+ qgcApp()->reportMissingFact(name);
+ if (_factMissingSignalConnected) {
+ emit factMissing(name);
+ } else {
+ _missedFactMissingSignals << name;
+ }
}
}
}
@@ -208,3 +213,27 @@ bool FactBinder::valueEqualsDefault(void)
return false;
}
}
+
+void FactBinder::connectNotify(const QMetaMethod & signal)
+{
+ if (signal == QMetaMethod::fromSignal(&FactBinder::factMissing)) {
+ _factMissingSignalConnected = true;
+ if (_missedFactMissingSignals.count()) {
+ QTimer::singleShot(10, this, &FactBinder::_delayedFactMissing);
+ }
+ }
+}
+
+void FactBinder::disconnectNotify(const QMetaMethod & signal)
+{
+ if (signal == QMetaMethod::fromSignal(&FactBinder::factMissing)) {
+ _factMissingSignalConnected = false;
+ }
+}
+
+void FactBinder::_delayedFactMissing(void)
+{
+ foreach (QString name, _missedFactMissingSignals) {
+ emit factMissing(name);
+ }
+}
\ No newline at end of file
diff --git a/src/FactSystem/FactBinder.h b/src/FactSystem/FactBinder.h
index 8cac12080c063a35a41c0d771b1ca656363e9717..22bb9f0c458fa3a009678db15500f0e56a508166 100644
--- a/src/FactSystem/FactBinder.h
+++ b/src/FactSystem/FactBinder.h
@@ -78,14 +78,24 @@ public:
QString group(void);
signals:
+ void factMissing(const QString& name);
void nameChanged(void);
void valueChanged(void);
void metaDataChanged(void);
+private slots:
+ void _delayedFactMissing(void);
+
private:
+ // Overrides from QObject
+ void connectNotify(const QMetaMethod & signal);
+ void disconnectNotify(const QMetaMethod & signal);
+
AutoPilotPlugin* _autopilotPlugin;
Fact* _fact;
int _componentId;
+ bool _factMissingSignalConnected;
+ QStringList _missedFactMissingSignals;
};
#endif
\ No newline at end of file
diff --git a/src/FactSystem/FactControls/FactPanel.qml b/src/FactSystem/FactControls/FactPanel.qml
new file mode 100644
index 0000000000000000000000000000000000000000..dde0acf93689f3ca8602df554375f7468de2c49f
--- /dev/null
+++ b/src/FactSystem/FactControls/FactPanel.qml
@@ -0,0 +1,61 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2015 QGROUNDCONTROL PROJECT
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see .
+
+ ======================================================================*/
+
+/// @file
+/// @author Don Gagne
+
+import QtQuick 2.3
+import QtQuick.Controls 1.3
+
+import QGroundControl.FactSystem 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.Palette 1.0
+
+Item {
+ property string __missingFacts: ""
+
+ function showMissingFactOverlay(missingFactName) {
+ if (__missingFacts.length != 0) {
+ __missingFacts = __missingFacts.concat(", ")
+ }
+ __missingFacts = __missingFacts.concat(missingFactName)
+ __missingFactOverlay.visible = true
+ }
+
+ Rectangle {
+ QGCPalette { id: __qgcPal; colorGroupEnabled: true }
+
+ id: __missingFactOverlay
+ anchors.fill: parent
+ z: 9999
+ visible: false
+ color: __qgcPal.window
+ opacity: 0.85
+
+ QGCLabel {
+ anchors.fill: parent
+ wrapMode: Text.WordWrap
+ text: "Fact(s) missing: " + __missingFacts
+ }
+ }
+}
diff --git a/src/FactSystem/FactControls/FactPanelController.cc b/src/FactSystem/FactControls/FactPanelController.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ddebadd4a75125195e7f140c745d1461e557c8a9
--- /dev/null
+++ b/src/FactSystem/FactControls/FactPanelController.cc
@@ -0,0 +1,108 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2014 QGROUNDCONTROL PROJECT
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see .
+
+ ======================================================================*/
+
+#include "FactPanelController.h"
+#include "UASManager.h"
+#include "AutoPilotPluginManager.h"
+#include "QGCMessageBox.h"
+
+/// @file
+/// @author Don Gagne
+
+FactPanelController::FactPanelController(void) :
+ _autopilot(NULL),
+ _factPanel(NULL)
+{
+ UASInterface* uas = UASManager::instance()->getActiveUAS();
+ Q_ASSERT(uas);
+
+ _autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(uas);
+ Q_ASSERT(_autopilot);
+ Q_ASSERT(_autopilot->pluginReady());
+
+ // Do a delayed check for the _factPanel finally being set correctly from Qml
+ QTimer::singleShot(1000, this, &FactPanelController::_checkForMissingFactPanel);
+}
+
+QQuickItem* FactPanelController::factPanel(void)
+{
+ return _factPanel;
+}
+
+void FactPanelController::setFactPanel(QQuickItem* panel)
+{
+ // Once we finally have the _factPanel member set send any
+ // missing fact notices that were waiting to go out
+
+ _factPanel = panel;
+ foreach (QString missingFact, _delayedMissingFacts) {
+ _notifyPanelMissingFact(missingFact);
+ }
+ _delayedMissingFacts.clear();
+}
+
+void FactPanelController::_notifyPanelMissingFact(const QString& missingFact)
+{
+ QVariant returnedValue;
+
+ QMetaObject::invokeMethod(_factPanel,
+ "showMissingFactOverlay",
+ Q_RETURN_ARG(QVariant, returnedValue),
+ Q_ARG(QVariant, missingFact));
+}
+
+void FactPanelController::_reportMissingFact(const QString& missingFact)
+{
+ qgcApp()->reportMissingFact(missingFact);
+
+ // If missing facts a reported from the constructor of a derived class we
+ // will not have access to _factPanel yet. Just record list of missing facts
+ // in that case instead of notify. Once _factPanel is available they will be
+ // send out for real.
+ if (_factPanel) {
+ _notifyPanelMissingFact(missingFact);
+ } else {
+ _delayedMissingFacts += missingFact;
+ }
+}
+
+bool FactPanelController::_allFactsExists(QStringList factList)
+{
+ bool noMissingFacts = true;
+
+ foreach (QString fact, factList) {
+ if (!_autopilot->parameterExists(fact)) {
+ _reportMissingFact(fact);
+ noMissingFacts = false;
+ }
+ }
+
+ return noMissingFacts;
+}
+
+void FactPanelController::_checkForMissingFactPanel(void)
+{
+ if (!_factPanel) {
+ QGCMessageBox::critical("Incorrect FactPanel Qml implementation", "FactPanelController used without passing in factPanel. This could lead to non-functioning user interface being displayed.");
+ }
+}
\ No newline at end of file
diff --git a/src/FactSystem/FactControls/FactPanelController.h b/src/FactSystem/FactControls/FactPanelController.h
new file mode 100644
index 0000000000000000000000000000000000000000..09411432037d815bd87b470fb5febf9816d7a89e
--- /dev/null
+++ b/src/FactSystem/FactControls/FactPanelController.h
@@ -0,0 +1,71 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2014 QGROUNDCONTROL PROJECT
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see .
+
+ ======================================================================*/
+
+#ifndef FactPanelController_H
+#define FactPanelController_H
+
+/// @file
+/// @author Don Gagne
+
+#include
+#include
+
+#include "UASInterface.h"
+#include "AutoPilotPlugin.h"
+#include "UASManagerInterface.h"
+
+/// FactPanelController is used in combination with the FactPanel Qml control for handling
+/// missing Facts from C++ code.
+class FactPanelController : public QObject
+{
+ Q_OBJECT
+
+public:
+ FactPanelController(void);
+
+ Q_PROPERTY(QQuickItem* factPanel READ factPanel WRITE setFactPanel)
+
+ QQuickItem* factPanel(void);
+ void setFactPanel(QQuickItem* panel);
+
+protected:
+ /// Checks for existence of the specified facts
+ /// @return true: all facts exists, false: facts missing and reported
+ bool _allFactsExists(QStringList factList);
+
+ /// Report a missing fact to the FactPanel Qml element
+ void _reportMissingFact(const QString& missingFact);
+
+ AutoPilotPlugin* _autopilot;
+
+private slots:
+ void _checkForMissingFactPanel(void);
+
+private:
+ void _notifyPanelMissingFact(const QString& missingFact);
+
+ QQuickItem* _factPanel;
+ QStringList _delayedMissingFacts;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/FactSystem/FactControls/qmldir b/src/FactSystem/FactControls/qmldir
index 9a6de26b5864ea5843239ab83e9b11f3bb12adf6..b982d612fcdaf8b509097f80250dde4bf3004bb6 100644
--- a/src/FactSystem/FactControls/qmldir
+++ b/src/FactSystem/FactControls/qmldir
@@ -1,5 +1,6 @@
Module QGroundControl.FactControls
+FactPanel 1.0 FactPanel.qml
FactLabel 1.0 FactLabel.qml
FactTextField 1.0 FactTextField.qml
FactCheckBox 1.0 FactCheckBox.qml
diff --git a/src/FactSystem/FactSystem.cc b/src/FactSystem/FactSystem.cc
index 450b0b8e354e85a52fa35fd9f54c3c72f6b5257e..257193792f210e982dbdf84e47c6ad578f8c0118 100644
--- a/src/FactSystem/FactSystem.cc
+++ b/src/FactSystem/FactSystem.cc
@@ -29,6 +29,7 @@
#include "QGCApplication.h"
#include "VehicleComponent.h"
#include "FactBinder.h"
+#include "FactPanelController.h"
#include
@@ -40,6 +41,7 @@ FactSystem::FactSystem(QObject* parent) :
QGCSingleton(parent)
{
qmlRegisterType(_factSystemQmlUri, 1, 0, "Fact");
+ qmlRegisterType(_factSystemQmlUri, 1, 0, "FactPanelController");
qmlRegisterUncreatableType(_factSystemQmlUri, 1, 0, "VehicleComponent", "Can only reference, cannot create");
}
diff --git a/src/FactSystem/ParameterLoader.cc b/src/FactSystem/ParameterLoader.cc
index 27d235fe3de1dc799a411d276251ea7805aad234..94d635025a0f06423bdbd9cb654a1391a310ed34 100644
--- a/src/FactSystem/ParameterLoader.cc
+++ b/src/FactSystem/ParameterLoader.cc
@@ -386,8 +386,7 @@ Fact* ParameterLoader::getFact(int componentId, const QString& name)
componentId = _actualComponentId(componentId);
if (!_mapParameterName2Variant.contains(componentId) || !_mapParameterName2Variant[componentId].contains(name)) {
- QString panicMessage("Required parameter (component id: %1, name: %2), is missing from vehicle. QGroundControl cannot operate with this firmware revision. QGroundControl will now shut down.");
- qgcApp()->panicShutdown(panicMessage.arg(componentId).arg(name));
+ return NULL;
}
Fact* fact = _mapParameterName2Variant[componentId][name].value();
diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc
index b9db5f144986cbca3bc00bcd738f31077eee0cf7..6f685abcf77ada21fc506996c12d3c7cded05390 100644
--- a/src/QGCApplication.cc
+++ b/src/QGCApplication.cc
@@ -166,6 +166,10 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) :
#endif
#endif
+ // Set up timer for delayed missing fact display
+ _missingFactDelayedDisplayTimer.setSingleShot(true);
+ _missingFactDelayedDisplayTimer.setInterval(_missingFactDelayedDisplayTimerTimeout);
+ connect(&_missingFactDelayedDisplayTimer, &QTimer::timeout, this, &QGCApplication::_missingFactsDisplay);
// Set application information
if (_runningUnitTests) {
@@ -660,8 +664,28 @@ void QGCApplication::_reconnect(void)
_reconnectLinkConfig = NULL;
}
-void QGCApplication::panicShutdown(const QString& panicMessage)
+void QGCApplication::reportMissingFact(const QString& name)
{
- QGCMessageBox::critical("Panic Shutdown", panicMessage);
- ::exit(0);
+ _missingFacts += name;
+ _missingFactDelayedDisplayTimer.start();
}
+
+/// Called when the delay timer fires to show the missing facts warning
+void QGCApplication::_missingFactsDisplay(void)
+{
+ Q_ASSERT(_missingFacts.count());
+
+ QString facts;
+ foreach (QString fact, _missingFacts) {
+ if (facts.isEmpty()) {
+ facts += fact;
+ } else {
+ facts += QString(", %1").arg(fact);
+ }
+ }
+ _missingFacts.clear();
+
+ QGCMessageBox::critical("Missing Parameters",
+ QString("Parameters missing from firmware: %1.\n\n"
+ "You should quit QGroundControl immediately and update your firmware.").arg(facts));
+}
\ No newline at end of file
diff --git a/src/QGCApplication.h b/src/QGCApplication.h
index 695d3d7d404ed73797d96cb6bef4f486b0d1019a..481f88319ca9f96d126b945595333fee2fbb4d47 100644
--- a/src/QGCApplication.h
+++ b/src/QGCApplication.h
@@ -33,6 +33,7 @@
#define QGCAPPLICATION_H
#include
+#include
#include "LinkConfiguration.h"
@@ -98,9 +99,9 @@ public:
/// Disconnects the current link and waits for the specified number of seconds before reconnecting.
void reconnectAfterWait(int waitSeconds);
- /// Used to shutdown the app if a fatal condition occurs from which it cannot recover
- /// @param panicMessage Message to display to user
- void panicShutdown(const QString& panicMessage);
+ /// Used to report a missing Fact. Warning will be displayed to user. Method may be called
+ /// multiple times.
+ void reportMissingFact(const QString& name);
public slots:
/// You can connect to this slot to show an information message box from a different thread.
@@ -143,6 +144,7 @@ public:
private slots:
void _reconnect(void);
+ void _missingFactsDisplay(void);
private:
void _createSingletons(void);
@@ -165,7 +167,11 @@ private:
static const char* _lightStyleFile;
bool _styleIsDark; ///< true: dark style, false: light style
- LinkConfiguration* _reconnectLinkConfig; ///< Configuration to reconnect for reconnectAfterWai
+ LinkConfiguration* _reconnectLinkConfig; ///< Configuration to reconnect for reconnectAfterWait
+
+ static const int _missingFactDelayedDisplayTimerTimeout = 1000; ///< Timeout to wait for next missing fact to come in before display
+ QTimer _missingFactDelayedDisplayTimer; ///< Timer use to delay missing fact display
+ QStringList _missingFacts; ///< List of missing facts to be displayed
/// Unit Test have access to creating and destroying singletons
friend class UnitTest;