diff --git a/src/FactSystem/SettingsFact.cc b/src/FactSystem/SettingsFact.cc index 1d8f4f58f7db4a1fcb44dd8e025d44b6acecfa23..e6f79fffd66d3b2dd54ec8e2628c88b5af0dce2b 100644 --- a/src/FactSystem/SettingsFact.cc +++ b/src/FactSystem/SettingsFact.cc @@ -35,16 +35,18 @@ SettingsFact::SettingsFact(QString settingsGroup, FactMetaData* metaData, QObjec _visible = qgcApp()->toolbox()->corePlugin()->adjustSettingMetaData(settingsGroup, *metaData); setMetaData(metaData); - QVariant rawDefaultValue = metaData->rawDefaultValue(); - if (_visible) { - QVariant typedValue; - QString errorString; - metaData->convertAndValidateRaw(settings.value(_name, rawDefaultValue), true /* conertOnly */, typedValue, errorString); - _rawValue = typedValue; - } else { - // Setting is not visible, force to default value always - settings.setValue(_name, rawDefaultValue); - _rawValue = rawDefaultValue; + if (metaData->defaultValueAvailable()) { + QVariant rawDefaultValue = metaData->rawDefaultValue(); + if (_visible) { + QVariant typedValue; + QString errorString; + metaData->convertAndValidateRaw(settings.value(_name, rawDefaultValue), true /* conertOnly */, typedValue, errorString); + _rawValue = typedValue; + } else { + // Setting is not visible, force to default value always + settings.setValue(_name, rawDefaultValue); + _rawValue = rawDefaultValue; + } } connect(this, &Fact::rawValueChanged, this, &SettingsFact::_rawValueChanged); diff --git a/src/MissionManager/MissionController.cc b/src/MissionManager/MissionController.cc index 01b9a62263990266e497c7cdc622b570aa2b112d..2b96a09c85778dde83bc3da75a7b74c32a8708b1 100644 --- a/src/MissionManager/MissionController.cc +++ b/src/MissionManager/MissionController.cc @@ -1004,16 +1004,16 @@ bool MissionController::loadTextFile(QFile& file, QString& errorString) return true; } -bool MissionController::readyForSaveSend(void) const +int MissionController::readyForSaveState(void) const { for (int i=0; i<_visualItems->count(); i++) { VisualMissionItem* visualItem = qobject_cast(_visualItems->get(i)); if (visualItem->readyForSaveState() != VisualMissionItem::ReadyForSave) { - return false; + return visualItem->readyForSaveState(); } } - return true; + return VisualMissionItem::ReadyForSave; } void MissionController::save(QJsonObject& json) diff --git a/src/MissionManager/MissionController.h b/src/MissionManager/MissionController.h index 9a092c9c9cf77a131df2992e084daf6f805dd048..39eb1f50e50ec2b46a58139abcccb3a0728778f2 100644 --- a/src/MissionManager/MissionController.h +++ b/src/MissionManager/MissionController.h @@ -145,9 +145,10 @@ public: /// Returns the index of this item in the visual item list Q_INVOKABLE int visualItemIndexFromSequenceNumber(int sequenceNumber) const; - /// Determines if the mission has all data needed to be saved or sent to the vehicle. Currently the only case where this - /// would return false is when it is still waiting on terrain data to determine correct altitudes. - bool readyForSaveSend(void) const; + /// Determines if the mission has all data needed to be saved or sent to the vehicle. + /// IMPORTANT NOTE: The return value is a VisualMissionItem::ReadForSaveState value. It is an int here to work around + /// a nightmare of circular header dependency problems. + int readyForSaveState(void) const; /// Sends the mission items to the specified vehicle static void sendItemsToVehicle(Vehicle* vehicle, QmlObjectListModel* visualMissionItems); diff --git a/src/MissionManager/PlanMasterController.h b/src/MissionManager/PlanMasterController.h index 95ab6013b0a2da7367f149fd467ee3fb992f2aba..8f7e3211cf1d61bdbd9c4210ab57c2751e9b933e 100644 --- a/src/MissionManager/PlanMasterController.h +++ b/src/MissionManager/PlanMasterController.h @@ -29,7 +29,7 @@ class PlanMasterController : public QObject public: PlanMasterController(QObject* parent = nullptr); ~PlanMasterController(); - + Q_PROPERTY(MissionController* missionController READ missionController CONSTANT) Q_PROPERTY(GeoFenceController* geoFenceController READ geoFenceController CONSTANT) Q_PROPERTY(RallyPointController* rallyPointController READ rallyPointController CONSTANT) @@ -52,9 +52,10 @@ public: /// @param deleteWhenSendCmplete The PlanMasterController object should be deleted after the first send is completed. Q_INVOKABLE void startStaticActiveVehicle(Vehicle* vehicle, bool deleteWhenSendCompleted = false); - /// Determines if the plan has all data needed to be saved or sent to the vehicle. Currently the only case where this - /// would return false is when it is still waiting on terrain data to determine correct altitudes. - Q_INVOKABLE bool readyForSaveSend(void) const { return _missionController.readyForSaveSend(); } + /// Determines if the plan has all information needed to be saved or sent to the vehicle. + /// IMPORTANT NOTE: The return value is a VisualMissionItem::ReadForSaveState value. It is an int here to work around + /// a nightmare of circular header dependency problems. + Q_INVOKABLE int readyForSaveState(void) const { return _missionController.readyForSaveState(); } /// Sends a plan to the specified file /// @param[in] vehicle Vehicle we are sending a plan to diff --git a/src/PlanView/PlanView.qml b/src/PlanView/PlanView.qml index 42aeb4234179b9a7e78b0343b4ec7d40379a0103..19acdbfecd834680de6512a5dd10fcc9519e851c 100644 --- a/src/PlanView/PlanView.qml +++ b/src/PlanView/PlanView.qml @@ -181,13 +181,29 @@ Item { mainWindow.planMasterControllerPlan = _planMasterController } - function waitingOnDataMessage() { - mainWindow.showMessageDialog(qsTr("Unable to Save/Upload"), qsTr("Plan is waiting on terrain data from server for correct altitude values.")) + function waitingOnIncompleteDataMessage(save) { + var saveOrUpload = save ? qsTr("Save") : qsTr("Upload") + mainWindow.showMessageDialog(qsTr("Unable to %1").arg(saveOrUpload), qsTr("Plan has incomplete items. Complete all items and %1 again.").arg(saveOrUpload)) + } + + function waitingOnTerrainDataMessage(save) { + var saveOrUpload = save ? qsTr("Save") : qsTr("Upload") + mainWindow.showMessageDialog(qsTr("Unable to %1").arg(saveOrUpload), qsTr("Plan is waiting on terrain data from server for correct altitude values.")) + } + + function checkReadyForSaveUpload(save) { + if (readyForSaveState() == VisualMissionItem.NotReadyForSaveData) { + waitingOnIncompleteDataMessage(save) + return false + } else if (readyForSaveState() == VisualMissionItem.NotReadyForSaveTerrain) { + waitingOnTerrainDataMessage(save) + return false + } + return true } function upload() { - if (!readyForSaveSend()) { - waitingOnDataMessage() + if (!checkReadyForSaveUpload(false /* save */)) { return } if (activeVehicle && activeVehicle.armed && activeVehicle.flightMode === activeVehicle.missionFlightMode) { @@ -208,8 +224,7 @@ Item { } function saveToSelectedFile() { - if (!readyForSaveSend()) { - waitingOnDataMessage() + if (!checkReadyForSaveUpload(true /* save */)) { return } fileDialog.title = qsTr("Save Plan") @@ -236,8 +251,7 @@ Item { } function saveKmlToSelectedFile() { - if (!readyForSaveSend()) { - waitingOnDataMessage() + if (!checkReadyForSaveUpload(true /* save */)) { return } fileDialog.title = qsTr("Save KML") @@ -1040,10 +1054,13 @@ Item { QGCButton { text: qsTr("New...") Layout.fillWidth: true - enabled: _planMasterController.containsItems onClicked: { dropPanel.hide() - mainWindow.showComponentDialog(removeAllPromptDialog, qsTr("New Plan"), mainWindow.showDialogDefaultWidth, StandardButton.Yes | StandardButton.No) + if (_planMasterController.containsItems) { + mainWindow.showComponentDialog(removeAllPromptDialog, qsTr("New Plan"), mainWindow.showDialogDefaultWidth, StandardButton.Yes | StandardButton.No) + } else { + startOverlay.visible = true + } } }