diff --git a/qgcimages.qrc b/qgcimages.qrc index ffb1b4cffdb0ea7a5bd91319823b67b6e423ee59..e0e6be14833fcebeb03ca4c7f8a2d0e5d12c004a 100644 --- a/qgcimages.qrc +++ b/qgcimages.qrc @@ -127,7 +127,7 @@ src/FlightMap/Images/pipHide.svg src/FlightMap/Images/pipResize.svg src/ui/toolbar/Images/Plan.svg - src/MissionManager/CustomPlanCreator.png + src/MissionManager/BlankPlanCreator.png src/MissionManager/CorridorScanPlanCreator.png src/MissionManager/StructureScanPlanCreator.png src/MissionManager/SurveyPlanCreator.png diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 536f6155be31199ef81d01b6efae9b574d77842c..74ff318dbdd9b4c5409b07bc5250c2c6e17557e1 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -592,7 +592,7 @@ HEADERS += \ src/MissionManager/ComplexMissionItem.h \ src/MissionManager/CorridorScanComplexItem.h \ src/MissionManager/CorridorScanPlanCreator.h \ - src/MissionManager/CustomPlanCreator.h \ + src/MissionManager/BlankPlanCreator.h \ src/MissionManager/FixedWingLandingComplexItem.h \ src/MissionManager/GeoFenceController.h \ src/MissionManager/GeoFenceManager.h \ @@ -823,7 +823,7 @@ SOURCES += \ src/MissionManager/ComplexMissionItem.cc \ src/MissionManager/CorridorScanComplexItem.cc \ src/MissionManager/CorridorScanPlanCreator.cc \ - src/MissionManager/CustomPlanCreator.cc \ + src/MissionManager/BlankPlanCreator.cc \ src/MissionManager/FixedWingLandingComplexItem.cc \ src/MissionManager/GeoFenceController.cc \ src/MissionManager/GeoFenceManager.cc \ diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 99908ea6b068c45618a3bcfc558df8129086c1ee..fb2a636586da75ea2b0e38636b630e257f343181 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -102,7 +102,6 @@ src/QmlControls/ParameterEditorDialog.qml src/QmlControls/PIDTuning.qml src/PlanView/PlanEditToolbar.qml - src/PlanView/PlanStartOverlay.qml src/QmlControls/PreFlightCheckButton.qml src/QmlControls/PreFlightCheckGroup.qml src/QmlControls/PreFlightCheckModel.qml diff --git a/resources/TrashDelete.svg b/resources/TrashDelete.svg index cb4c5a3d7a24e8b7eb722bdd3730bfa4a5d70704..8d8af7f4e4dbbfdc2b3bd7f1d537b066eff67836 100644 --- a/resources/TrashDelete.svg +++ b/resources/TrashDelete.svg @@ -1,8 +1,116 @@ - + - - - - + +image/svg+xml + + + \ No newline at end of file diff --git a/src/AnalyzeView/MAVLinkInspectorPage.qml b/src/AnalyzeView/MAVLinkInspectorPage.qml index c43dabafa39069e86eccc629f45c7afd2c94e595..e1c4b25bf2ad62319e55ee258a6535cb47e24de1 100644 --- a/src/AnalyzeView/MAVLinkInspectorPage.qml +++ b/src/AnalyzeView/MAVLinkInspectorPage.qml @@ -22,11 +22,12 @@ Item { anchors.fill: parent anchors.margins: ScreenTools.defaultFontPixelWidth - property var curVehicle: controller ? controller.activeVehicle : null - property int curMessageIndex:0 - property var curMessage: curVehicle && curVehicle.messages.count ? curVehicle.messages.get(curMessageIndex) : null - property int curCompID: 0 - property bool selectionValid: false + property var curVehicle: controller ? controller.activeVehicle : null + property int curMessageIndex: 0 + property var curMessage: curVehicle && curVehicle.messages.count ? curVehicle.messages.get(curMessageIndex) : null + property int curCompID: 0 + property bool selectionValid: false + property real maxButtonWidth: 0 MAVLinkInspectorController { id: controller @@ -76,11 +77,13 @@ Item { anchors.topMargin: ScreenTools.defaultFontPixelHeight anchors.bottom: parent.bottom anchors.left: parent.left - width: buttonCol.width - contentWidth: buttonCol.width + width: maxButtonWidth + contentWidth: width contentHeight: buttonCol.height ColumnLayout { id: buttonCol + anchors.left: parent.left + anchors.right: parent.right spacing: ScreenTools.defaultFontPixelHeight * 0.25 Repeater { model: curVehicle ? curVehicle.messages : [] @@ -94,7 +97,7 @@ Item { selectionValid = true curMessageIndex = index } - Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 40 + Layout.fillWidth: true } } } diff --git a/src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml b/src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml index 6a91e439475eaefb493ce80ad3aa53656f543242..1644ada8f269afaaa713e4a0c1ea9855e9d0ce9b 100644 --- a/src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml +++ b/src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml @@ -439,6 +439,11 @@ motor 3 motor 4 + + Copter + Oleg Kalachev <okalachev@gmail.com> + Quadrotor x + Copter Dennis Shtatov <densht@gmail.com> diff --git a/src/FactSystem/ParameterManager.cc b/src/FactSystem/ParameterManager.cc index f77bcf36dd36ffce6f6ed8001f3363995f938c83..4124c4b9b13b8935cded0f0719225c4e93aa6fc1 100644 --- a/src/FactSystem/ParameterManager.cc +++ b/src/FactSystem/ParameterManager.cc @@ -131,6 +131,63 @@ ParameterManager::~ParameterManager() delete _parameterMetaData; } +void ParameterManager::_updateProgressBar(void) +{ + int waitingReadParamIndexCount = 0; + int waitingReadParamNameCount = 0; + int waitingWriteParamCount = 0; + + for (int compId: _waitingReadParamIndexMap.keys()) { + waitingReadParamIndexCount += _waitingReadParamIndexMap[compId].count(); + } + for(int compId: _waitingReadParamNameMap.keys()) { + waitingReadParamNameCount += _waitingReadParamNameMap[compId].count(); + } + for(int compId: _waitingWriteParamNameMap.keys()) { + waitingWriteParamCount += _waitingWriteParamNameMap[compId].count(); + } + + if (waitingReadParamIndexCount == 0) { + if (_readParamIndexProgressActive) { + _readParamIndexProgressActive = false; + _setLoadProgress(0.0); + return; + } + } else { + _readParamIndexProgressActive = true; + _setLoadProgress((double)(_totalParamCount - waitingReadParamIndexCount) / (double)_totalParamCount); + return; + } + + if (waitingWriteParamCount == 0) { + if (_writeParamProgressActive) { + _writeParamProgressActive = false; + _waitingWriteParamBatchCount = 0; + _setLoadProgress(0.0); + emit pendingWritesChanged(false); + return; + } + } else { + _writeParamProgressActive = true; + _setLoadProgress((double)(qMax(_waitingWriteParamBatchCount - waitingWriteParamCount, 1)) / (double)(_waitingWriteParamBatchCount + 1)); + emit pendingWritesChanged(true); + return; + } + + if (waitingReadParamNameCount == 0) { + if (_readParamNameProgressActive) { + _readParamNameProgressActive = false; + _waitingReadParamNameBatchCount = 0; + _setLoadProgress(0.0); + return; + } + } else { + _readParamNameProgressActive = true; + _setLoadProgress((double)(qMax(_waitingReadParamNameBatchCount - waitingReadParamNameCount, 1)) / (double)(_waitingReadParamNameBatchCount + 1)); + return; + } +} + /// Called whenever a parameter is updated or first seen. void ParameterManager::_parameterUpdate(int vehicleId, int componentId, QString parameterName, int parameterCount, int parameterId, int mavType, QVariant value) { @@ -299,17 +356,8 @@ void ParameterManager::_parameterUpdate(int vehicleId, int componentId, QString qCDebug(ParameterManagerVerbose1Log) << _logVehiclePrefix(-1) << "Not restarting _waitingParamTimeoutTimer (all requests satisfied)"; } } - - // Update progress bar for waiting reads - if (readWaitingParamCount == 0) { - // We are no longer waiting for any reads to complete - if (_prevWaitingReadParamIndexCount + _prevWaitingReadParamNameCount != 0) { - // Set progress to 0 if not already there - _setLoadProgress(0.0); - } - } else { - _setLoadProgress((double)(_totalParamCount - readWaitingParamCount) / (double)_totalParamCount); - } +\ + _updateProgressBar(); // Get parameter set version if (!_versionParam.isEmpty() && _versionParam == parameterName) { @@ -425,8 +473,13 @@ void ParameterManager::_valueUpdated(const QVariant& value) _dataMutex.lock(); if (_waitingWriteParamNameMap.contains(componentId)) { - _waitingWriteParamNameMap[componentId].remove(name); // Remove any old entry - _waitingWriteParamNameMap[componentId][name] = 0; // Add new entry and set retry count + if (_waitingWriteParamNameMap[componentId].contains(name)) { + _waitingWriteParamNameMap[componentId].remove(name); + } else { + _waitingWriteParamBatchCount++; + } + _waitingWriteParamNameMap[componentId][name] = 0; // Add new entry and set retry count + _updateProgressBar(); _waitingParamTimeoutTimer.start(); _saveRequired = true; } else { @@ -502,8 +555,13 @@ void ParameterManager::refreshParameter(int componentId, const QString& paramNam if (_waitingReadParamNameMap.contains(componentId)) { QString mappedParamName = _remapParamNameToVersion(paramName); - _waitingReadParamNameMap[componentId].remove(mappedParamName); // Remove old wait entry if there + if (_waitingReadParamNameMap[componentId].contains(mappedParamName)) { + _waitingReadParamNameMap[componentId].remove(mappedParamName); + } else { + _waitingReadParamNameBatchCount++; + } _waitingReadParamNameMap[componentId][mappedParamName] = 0; // Add new wait entry and update retry count + _updateProgressBar(); qCDebug(ParameterManagerLog) << _logVehiclePrefix(componentId) << "restarting _waitingParamTimeout"; _waitingParamTimeoutTimer.start(); } else { @@ -978,7 +1036,8 @@ void ParameterManager::_tryCacheHashLoad(int vehicleId, int componentId, QVarian QString ParameterManager::readParametersFromStream(QTextStream& stream) { - QString errors; + QString missingErrors; + QString typeErrors; while (!stream.atEnd()) { QString line = stream.readLine(); @@ -997,18 +1056,18 @@ QString ParameterManager::readParametersFromStream(QTextStream& stream) if (!parameterExists(componentId, paramName)) { QString error; - error = QString("Skipped parameter %1:%2 - does not exist on this vehicle\n").arg(componentId).arg(paramName); - errors += error; - qCDebug(ParameterManagerLog) << error; + error += QStringLiteral("%1:%2 ").arg(componentId).arg(paramName); + missingErrors += error; + qCDebug(ParameterManagerLog) << QStringLiteral("Skipped due to missing: %1").arg(error); continue; } Fact* fact = getParameter(componentId, paramName); if (fact->type() != _mavTypeToFactType((MAV_PARAM_TYPE)mavType)) { QString error; - error = QString("Skipped parameter %1:%2 - type mismatch %3:%4\n").arg(componentId).arg(paramName).arg(fact->type()).arg(_mavTypeToFactType((MAV_PARAM_TYPE)mavType)); - errors += error; - qCDebug(ParameterManagerLog) << error; + error = QStringLiteral("%1:%2 ").arg(componentId).arg(paramName); + typeErrors += error; + qCDebug(ParameterManagerLog) << QStringLiteral("Skipped due to type mismatch: %1").arg(error); continue; } @@ -1018,6 +1077,16 @@ QString ParameterManager::readParametersFromStream(QTextStream& stream) } } + QString errors; + + if (!missingErrors.isEmpty()) { + errors = tr("Parameters not loaded since they are not currently on the vehicle: %1\n").arg(missingErrors); + } + + if (!typeErrors.isEmpty()) { + errors += tr("Parameters not loaded due to type mismatch: %1").arg(typeErrors); + } + return errors; } @@ -1661,11 +1730,24 @@ QString ParameterManager::_logVehiclePrefix(int componentId) void ParameterManager::_setLoadProgress(double loadProgress) { - _loadProgress = loadProgress; - emit loadProgressChanged(static_cast(loadProgress)); + if (_loadProgress != loadProgress) { + _loadProgress = loadProgress; + emit loadProgressChanged(static_cast(loadProgress)); + } } QList ParameterManager::componentIds(void) { return _paramCountMap.keys(); } + +bool ParameterManager::pendingWrites(void) +{ + for (int compId: _waitingWriteParamNameMap.keys()) { + if (_waitingWriteParamNameMap[compId].count()) { + return true; + } + } + + return false; +} diff --git a/src/FactSystem/ParameterManager.h b/src/FactSystem/ParameterManager.h index 2929913a95f4c277b21680f65b7da26961c3eab1..eed51b4e066e508a681892a90789cd73eba3a544 100644 --- a/src/FactSystem/ParameterManager.h +++ b/src/FactSystem/ParameterManager.h @@ -39,6 +39,7 @@ public: Q_PROPERTY(bool parametersReady READ parametersReady NOTIFY parametersReadyChanged) ///< true: Parameters are ready for use Q_PROPERTY(bool missingParameters READ missingParameters NOTIFY missingParametersChanged) ///< true: Parameters are missing from firmware response, false: all parameters received from firmware Q_PROPERTY(double loadProgress READ loadProgress NOTIFY loadProgressChanged) + Q_PROPERTY(bool pendingWrites READ pendingWrites NOTIFY pendingWritesChanged) ///< true: There are still pending write updates against the vehicle bool parametersReady (void) const { return _parametersReady; } bool missingParameters (void) const { return _missingParameters; } @@ -113,12 +114,15 @@ public: /// @return true: success, false: failure (errorString set) bool loadFromJson(const QJsonObject& json, bool required, QString& errorString); + bool pendingWrites(void); + Vehicle* vehicle(void) { return _vehicle; } signals: - void parametersReadyChanged(bool parametersReady); - void missingParametersChanged(bool missingParameters); - void loadProgressChanged(float value); + void parametersReadyChanged (bool parametersReady); + void missingParametersChanged (bool missingParameters); + void loadProgressChanged (float value); + void pendingWritesChanged (bool pendingWrites); protected: Vehicle* _vehicle; @@ -149,6 +153,7 @@ private: QString _logVehiclePrefix(int componentId); void _setLoadProgress(double loadProgress); bool _fillIndexBatchQueue(bool waitingParamTimeout); + void _updateProgressBar(void); MAV_PARAM_TYPE _factTypeToMavType(FactMetaData::ValueType_t factType); FactMetaData::ValueType_t _mavTypeToFactType(MAV_PARAM_TYPE mavType); @@ -183,9 +188,13 @@ private: QMap> _debugCacheParamSeen; // Wait counts from previous parameter update cycle - int _prevWaitingReadParamIndexCount; - int _prevWaitingReadParamNameCount; - int _prevWaitingWriteParamNameCount; + int _prevWaitingReadParamIndexCount; + int _prevWaitingReadParamNameCount; + int _prevWaitingWriteParamNameCount; + + bool _readParamIndexProgressActive = false; + bool _readParamNameProgressActive = false; + bool _writeParamProgressActive = false; static const int _maxInitialRequestListRetry = 4; ///< Maximum retries for request list int _initialRequestRetryCount; ///< Current retry count for request list @@ -202,7 +211,9 @@ private: QMap > _waitingWriteParamNameMap; ///< Key: Component id, Value: Map { Key: parameter name still waiting for, Value: retry count } QMap > _failedReadParamIndexMap; ///< Key: Component id, Value: failed parameter index - int _totalParamCount; ///< Number of parameters across all components + int _totalParamCount; ///< Number of parameters across all components + int _waitingWriteParamBatchCount = 0; ///< Number of parameters which are batched up waiting on write responses + int _waitingReadParamNameBatchCount = 0; ///< Number of parameters which are batched up waiting on read responses QTimer _initialRequestTimeoutTimer; QTimer _waitingParamTimeoutTimer; diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index 482a4d7632149b04f5d8a28f16da7388627f5bbe..3d444e1c9abf1d950ce029b559dc1087ab2a4e7c 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -9846,175 +9846,175 @@ is less than 50% of this value - + ID of Accelerometer that the calibration is for - + Accelerometer scale factor - X axis - + Accelerometer scale factor - Y axis - + Accelerometer scale factor - Z axis - + Accelerometer calibration maximum temperature - + Accelerometer calibration minimum temperature - + Accelerometer calibration reference temperature - + Accelerometer offset temperature ^0 polynomial coefficient - X axis - + Accelerometer offset temperature ^0 polynomial coefficient - Y axis - + Accelerometer offset temperature ^0 polynomial coefficient - Z axis - + Accelerometer offset temperature ^1 polynomial coefficient - X axis - + Accelerometer offset temperature ^1 polynomial coefficient - Y axis - + Accelerometer offset temperature ^1 polynomial coefficient - Z axis - + Accelerometer offset temperature ^2 polynomial coefficient - X axis - + Accelerometer offset temperature ^2 polynomial coefficient - Y axis - + Accelerometer offset temperature ^2 polynomial coefficient - Z axis - + Accelerometer offset temperature ^3 polynomial coefficient - X axis - + Accelerometer offset temperature ^3 polynomial coefficient - Y axis - + Accelerometer offset temperature ^3 polynomial coefficient - Z axis - + ID of Accelerometer that the calibration is for - + Accelerometer scale factor - X axis - + Accelerometer scale factor - Y axis - + Accelerometer scale factor - Z axis - + Accelerometer calibration maximum temperature - + Accelerometer calibration minimum temperature - + Accelerometer calibration reference temperature - + Accelerometer offset temperature ^0 polynomial coefficient - X axis - + Accelerometer offset temperature ^0 polynomial coefficient - Y axis - + Accelerometer offset temperature ^0 polynomial coefficient - Z axis - + Accelerometer offset temperature ^1 polynomial coefficient - X axis - + Accelerometer offset temperature ^1 polynomial coefficient - Y axis - + Accelerometer offset temperature ^1 polynomial coefficient - Z axis - + Accelerometer offset temperature ^2 polynomial coefficient - X axis - + Accelerometer offset temperature ^2 polynomial coefficient - Y axis - + Accelerometer offset temperature ^2 polynomial coefficient - Z axis - + Accelerometer offset temperature ^3 polynomial coefficient - X axis - + Accelerometer offset temperature ^3 polynomial coefficient - Y axis - + Accelerometer offset temperature ^3 polynomial coefficient - Z axis - + ID of Accelerometer that the calibration is for - + Accelerometer scale factor - X axis - + Accelerometer scale factor - Y axis - + Accelerometer scale factor - Z axis - + Accelerometer calibration maximum temperature - + Accelerometer calibration minimum temperature - + Accelerometer calibration reference temperature - + Accelerometer offset temperature ^0 polynomial coefficient - X axis - + Accelerometer offset temperature ^0 polynomial coefficient - Y axis - + Accelerometer offset temperature ^0 polynomial coefficient - Z axis - + Accelerometer offset temperature ^1 polynomial coefficient - X axis - + Accelerometer offset temperature ^1 polynomial coefficient - Y axis - + Accelerometer offset temperature ^1 polynomial coefficient - Z axis - + Accelerometer offset temperature ^2 polynomial coefficient - X axis - + Accelerometer offset temperature ^2 polynomial coefficient - Y axis - + Accelerometer offset temperature ^2 polynomial coefficient - Z axis - + Accelerometer offset temperature ^3 polynomial coefficient - X axis - + Accelerometer offset temperature ^3 polynomial coefficient - Y axis - + Accelerometer offset temperature ^3 polynomial coefficient - Z axis @@ -10022,103 +10022,103 @@ is less than 50% of this value 0 1 - + ID of Barometer that the calibration is for - + Barometer scale factor - X axis - + Barometer calibration maximum temperature - + Barometer calibration minimum temperature - + Barometer calibration reference temperature - + Barometer offset temperature ^0 polynomial coefficient - + Barometer offset temperature ^1 polynomial coefficients - + Barometer offset temperature ^2 polynomial coefficient - + Barometer offset temperature ^3 polynomial coefficient - + Barometer offset temperature ^4 polynomial coefficient - + Barometer offset temperature ^5 polynomial coefficient - + ID of Barometer that the calibration is for - + Barometer scale factor - X axis - + Barometer calibration maximum temperature - + Barometer calibration minimum temperature - + Barometer calibration reference temperature - + Barometer offset temperature ^0 polynomial coefficient - + Barometer offset temperature ^1 polynomial coefficients - + Barometer offset temperature ^2 polynomial coefficient - + Barometer offset temperature ^3 polynomial coefficient - + Barometer offset temperature ^4 polynomial coefficient - + Barometer offset temperature ^5 polynomial coefficient - + ID of Barometer that the calibration is for - + Barometer scale factor - X axis - + Barometer calibration maximum temperature - + Barometer calibration minimum temperature - + Barometer calibration reference temperature - + Barometer offset temperature ^0 polynomial coefficient - + Barometer offset temperature ^1 polynomial coefficients - + Barometer offset temperature ^2 polynomial coefficient - + Barometer offset temperature ^3 polynomial coefficient - + Barometer offset temperature ^4 polynomial coefficient - + Barometer offset temperature ^5 polynomial coefficient @@ -10126,175 +10126,175 @@ is less than 50% of this value 0 1 - + ID of Gyro that the calibration is for - + Gyro scale factor - X axis - + Gyro scale factor - Y axis - + Gyro scale factor - Z axis - + Gyro calibration maximum temperature - + Gyro calibration minimum temperature - + Gyro calibration reference temperature - + Gyro rate offset temperature ^0 polynomial coefficient - X axis - + Gyro rate offset temperature ^0 polynomial coefficient - Y axis - + Gyro rate offset temperature ^0 polynomial coefficient - Z axis - + Gyro rate offset temperature ^1 polynomial coefficient - X axis - + Gyro rate offset temperature ^1 polynomial coefficient - Y axis - + Gyro rate offset temperature ^1 polynomial coefficient - Z axis - + Gyro rate offset temperature ^2 polynomial coefficient - X axis - + Gyro rate offset temperature ^2 polynomial coefficient - Y axis - + Gyro rate offset temperature ^2 polynomial coefficient - Z axis - + Gyro rate offset temperature ^3 polynomial coefficient - X axis - + Gyro rate offset temperature ^3 polynomial coefficient - Y axis - + Gyro rate offset temperature ^3 polynomial coefficient - Z axis - + ID of Gyro that the calibration is for - + Gyro scale factor - X axis - + Gyro scale factor - Y axis - + Gyro scale factor - Z axis - + Gyro calibration maximum temperature - + Gyro calibration minimum temperature - + Gyro calibration reference temperature - + Gyro rate offset temperature ^0 polynomial coefficient - X axis - + Gyro rate offset temperature ^0 polynomial coefficient - Y axis - + Gyro rate offset temperature ^0 polynomial coefficient - Z axis - + Gyro rate offset temperature ^1 polynomial coefficient - X axis - + Gyro rate offset temperature ^1 polynomial coefficient - Y axis - + Gyro rate offset temperature ^1 polynomial coefficient - Z axis - + Gyro rate offset temperature ^2 polynomial coefficient - X axis - + Gyro rate offset temperature ^2 polynomial coefficient - Y axis - + Gyro rate offset temperature ^2 polynomial coefficient - Z axis - + Gyro rate offset temperature ^3 polynomial coefficient - X axis - + Gyro rate offset temperature ^3 polynomial coefficient - Y axis - + Gyro rate offset temperature ^3 polynomial coefficient - Z axis - + ID of Gyro that the calibration is for - + Gyro scale factor - X axis - + Gyro scale factor - Y axis - + Gyro scale factor - Z axis - + Gyro calibration maximum temperature - + Gyro calibration minimum temperature - + Gyro calibration reference temperature - + Gyro rate offset temperature ^0 polynomial coefficient - X axis - + Gyro rate offset temperature ^0 polynomial coefficient - Y axis - + Gyro rate offset temperature ^0 polynomial coefficient - Z axis - + Gyro rate offset temperature ^1 polynomial coefficient - X axis - + Gyro rate offset temperature ^1 polynomial coefficient - Y axis - + Gyro rate offset temperature ^1 polynomial coefficient - Z axis - + Gyro rate offset temperature ^2 polynomial coefficient - X axis - + Gyro rate offset temperature ^2 polynomial coefficient - Y axis - + Gyro rate offset temperature ^2 polynomial coefficient - Z axis - + Gyro rate offset temperature ^3 polynomial coefficient - X axis - + Gyro rate offset temperature ^3 polynomial coefficient - Y axis - + Gyro rate offset temperature ^3 polynomial coefficient - Z axis diff --git a/src/MissionManager/BlankPlanCreator.cc b/src/MissionManager/BlankPlanCreator.cc new file mode 100644 index 0000000000000000000000000000000000000000..abd4562f90926c3c387a09d4775ba2c708a76bff --- /dev/null +++ b/src/MissionManager/BlankPlanCreator.cc @@ -0,0 +1,24 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#include "BlankPlanCreator.h" +#include "PlanMasterController.h" +#include "MissionSettingsItem.h" +#include "FixedWingLandingComplexItem.h" + +BlankPlanCreator::BlankPlanCreator(PlanMasterController* planMasterController, QObject* parent) + : PlanCreator(planMasterController, tr("Blank"), QStringLiteral("/qmlimages/PlanCreator/BlankPlanCreator.png"), parent) +{ + +} + +void BlankPlanCreator::createPlan(const QGeoCoordinate& /*mapCenterCoord*/) +{ + _planMasterController->removeAll(); +} diff --git a/src/MissionManager/CustomPlanCreator.h b/src/MissionManager/BlankPlanCreator.h similarity index 78% rename from src/MissionManager/CustomPlanCreator.h rename to src/MissionManager/BlankPlanCreator.h index 56b0900686cb24b36263f19ec74fa76b637590ea..b11c7190c67464e1599feb7117344304b821f90c 100644 --- a/src/MissionManager/CustomPlanCreator.h +++ b/src/MissionManager/BlankPlanCreator.h @@ -11,12 +11,12 @@ #include "PlanCreator.h" -class CustomPlanCreator : public PlanCreator +class BlankPlanCreator : public PlanCreator { Q_OBJECT public: - CustomPlanCreator(PlanMasterController* planMasterController, QObject* parent = nullptr); + BlankPlanCreator(PlanMasterController* planMasterController, QObject* parent = nullptr); Q_INVOKABLE void createPlan(const QGeoCoordinate& mapCenterCoord) final; }; diff --git a/src/MissionManager/BlankPlanCreator.png b/src/MissionManager/BlankPlanCreator.png new file mode 100644 index 0000000000000000000000000000000000000000..7951383a98c6f7de98d1fb7812c4db69b6b748d1 Binary files /dev/null and b/src/MissionManager/BlankPlanCreator.png differ diff --git a/src/MissionManager/CorridorScanPlanCreator.png b/src/MissionManager/CorridorScanPlanCreator.png index d50b0a273749a2bde7b278f7662092cbd6e1125f..3889f6c89a2a1a043bf34dc03bc23d2fbb6f2b46 100644 Binary files a/src/MissionManager/CorridorScanPlanCreator.png and b/src/MissionManager/CorridorScanPlanCreator.png differ diff --git a/src/MissionManager/CustomPlanCreator.cc b/src/MissionManager/CustomPlanCreator.cc deleted file mode 100644 index 8900f86331d689530502bce4a7c78d9b11ea5dd0..0000000000000000000000000000000000000000 --- a/src/MissionManager/CustomPlanCreator.cc +++ /dev/null @@ -1,38 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2016 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - -#include "CustomPlanCreator.h" -#include "PlanMasterController.h" -#include "MissionSettingsItem.h" -#include "FixedWingLandingComplexItem.h" - -CustomPlanCreator::CustomPlanCreator(PlanMasterController* planMasterController, QObject* parent) - : PlanCreator(planMasterController, tr("Custom"), QStringLiteral("/qmlimages/PlanCreator/CustomPlanCreator.png"), parent) -{ - -} - -void CustomPlanCreator::createPlan(const QGeoCoordinate& mapCenterCoord) -{ - _planMasterController->removeAll(); - VisualMissionItem* takeoffItem = _missionController->insertSimpleMissionItem(mapCenterCoord, -1); - takeoffItem->setWizardMode(true); - _missionController->insertSimpleMissionItem(mapCenterCoord.atDistanceAndAzimuth(50, 135), -1); - _missionController->insertSimpleMissionItem(mapCenterCoord.atDistanceAndAzimuth(50, -135),-1); - if (_planMasterController->managerVehicle()->fixedWing()) { - FixedWingLandingComplexItem* landingItem = qobject_cast(_missionController->insertComplexMissionItem(MissionController::patternFWLandingName, mapCenterCoord, -1)); - landingItem->setWizardMode(true); - landingItem->setLoiterDragAngleOnly(true); - } else { - MissionSettingsItem* settingsItem = _missionController->visualItems()->value(0); - settingsItem->setMissionEndRTL(true); - } - _missionController->setCurrentPlanViewIndex(takeoffItem->sequenceNumber(), true); - -} diff --git a/src/MissionManager/CustomPlanCreator.png b/src/MissionManager/CustomPlanCreator.png deleted file mode 100644 index ca0eb9860c55af3bc53b93d04da0eff290598f88..0000000000000000000000000000000000000000 Binary files a/src/MissionManager/CustomPlanCreator.png and /dev/null differ diff --git a/src/MissionManager/PlanMasterController.cc b/src/MissionManager/PlanMasterController.cc index db2dd88f935592c6a8f27475a0ea27d789ae8ba9..de6d94f60cc830c2f4aee64d879821b315c7719e 100644 --- a/src/MissionManager/PlanMasterController.cc +++ b/src/MissionManager/PlanMasterController.cc @@ -19,7 +19,7 @@ #include "SurveyPlanCreator.h" #include "StructureScanPlanCreator.h" #include "CorridorScanPlanCreator.h" -#include "CustomPlanCreator.h" +#include "BlankPlanCreator.h" #if defined(QGC_AIRMAP_ENABLED) #include "AirspaceFlightPlanProvider.h" #endif @@ -601,19 +601,19 @@ void PlanMasterController::_updatePlanCreatorsList(void) if (!_flyView) { if (!_planCreators) { _planCreators = new QmlObjectListModel(this); + _planCreators->append(new BlankPlanCreator(this, this)); _planCreators->append(new SurveyPlanCreator(this, this)); _planCreators->append(new CorridorScanPlanCreator(this, this)); - _planCreators->append(new CustomPlanCreator(this, this)); emit planCreatorsChanged(_planCreators); } if (_managerVehicle->fixedWing()) { if (_planCreators->count() == 4) { - _planCreators->removeAt(_planCreators->count() - 2); + _planCreators->removeAt(_planCreators->count() - 1); } } else { if (_planCreators->count() != 4) { - _planCreators->insert(_planCreators->count() - 1, new StructureScanPlanCreator(this, this)); + _planCreators->append(new StructureScanPlanCreator(this, this)); } } } diff --git a/src/MissionManager/QGCMapPolygonVisuals.qml b/src/MissionManager/QGCMapPolygonVisuals.qml index c00fb1b95991c12da619b99d97a5a161e502f94e..2e9c6f65b3542b77473cd1aa840069411b65d838 100644 --- a/src/MissionManager/QGCMapPolygonVisuals.qml +++ b/src/MissionManager/QGCMapPolygonVisuals.qml @@ -538,7 +538,7 @@ Item { QGCButton { _horizontalPadding: 0 - text: _traceMode ? qsTr("Done Tracing") : qsTr("Trace Polygon") + text: _traceMode ? qsTr("Done Tracing") : qsTr("Trace") onClicked: { if (_traceMode) { if (mapPolygon.count < 3) { diff --git a/src/MissionManager/QGCMapPolylineVisuals.qml b/src/MissionManager/QGCMapPolylineVisuals.qml index ab88a61c9a24a8869348c95978fa9cc472ac556a..8294d6e3ce437d33891b0d3aca383b9b68dccdc4 100644 --- a/src/MissionManager/QGCMapPolylineVisuals.qml +++ b/src/MissionManager/QGCMapPolylineVisuals.qml @@ -38,7 +38,7 @@ Item { property real _zorderSplitHandle: QGroundControl.zOrderMapItems + 2 property var _savedVertices: [ ] - readonly property string _corridorToolsText: qsTr("Corridor Tools") + readonly property string _corridorToolsText: qsTr("Polyline Tools") readonly property string _traceText: qsTr("Click in the map to add vertices. Click 'Done Tracing' when finished.") function _addCommonVisuals() { diff --git a/src/MissionManager/StructureScanPlanCreator.png b/src/MissionManager/StructureScanPlanCreator.png index ac9f1bf5c26dd091a0f6112c1a69da6381bdb944..e43c41600cd3d312d946145cdd6ffd195fe70929 100644 Binary files a/src/MissionManager/StructureScanPlanCreator.png and b/src/MissionManager/StructureScanPlanCreator.png differ diff --git a/src/MissionManager/SurveyPlanCreator.png b/src/MissionManager/SurveyPlanCreator.png index 5ca4e15b193bd42d7f2e0dfafeb2cab80a3f2069..e2163ea43243f52cde4296d242874dddf3f676f2 100644 Binary files a/src/MissionManager/SurveyPlanCreator.png and b/src/MissionManager/SurveyPlanCreator.png differ diff --git a/src/PlanView/CameraSection.qml b/src/PlanView/CameraSection.qml index 0a01e62e09489081785e110d83f2f4ca54c582c2..fc588b18a0830297018c662ae854a12ef722ded0 100644 --- a/src/PlanView/CameraSection.qml +++ b/src/PlanView/CameraSection.qml @@ -24,6 +24,8 @@ Column { SectionHeader { id: cameraSectionHeader + anchors.left: parent.left + anchors.right: parent.right text: qsTr("Camera") checked: false } diff --git a/src/PlanView/CorridorScanEditor.qml b/src/PlanView/CorridorScanEditor.qml index 86058e936df4b4d78d7eee3403c6a6184598fba1..f47c521919ff67d2cf83194ad9aac84a6bac8f24 100644 --- a/src/PlanView/CorridorScanEditor.qml +++ b/src/PlanView/CorridorScanEditor.qml @@ -65,7 +65,7 @@ Rectangle { QGCLabel { Layout.fillWidth: true wrapMode: Text.WordWrap - text: qsTr("Use the Corridor Tools to create the polyline which defines the corridor.") + text: qsTr("Use the Polyline Tools to create the polyline which defines the corridor.") } QGCButton { @@ -124,8 +124,10 @@ Rectangle { } SectionHeader { - id: corridorHeader - text: qsTr("Corridor") + id: corridorHeader + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Corridor") } GridLayout { @@ -182,9 +184,11 @@ Rectangle { } SectionHeader { - id: terrainHeader - text: qsTr("Terrain") - checked: missionItem.followTerrain + id: terrainHeader + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Terrain") + checked: missionItem.followTerrain } ColumnLayout { @@ -228,8 +232,10 @@ Rectangle { } SectionHeader { - id: statsHeader - text: qsTr("Statistics") + id: statsHeader + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Statistics") } TransectStyleComplexItemStats { } diff --git a/src/PlanView/FWLandingPatternEditor.qml b/src/PlanView/FWLandingPatternEditor.qml index 44a1493d7a6d41fb9e40e6f1a358727cfa8c0dc4..c5434397fe52880ae222a4d1b35f4fbe1f97544c 100644 --- a/src/PlanView/FWLandingPatternEditor.qml +++ b/src/PlanView/FWLandingPatternEditor.qml @@ -52,8 +52,10 @@ Rectangle { visible: !editorColumnNeedLandingPoint.visible SectionHeader { - id: loiterPointSection - text: qsTr("Loiter point") + id: loiterPointSection + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Loiter point") } Column { @@ -101,8 +103,10 @@ Rectangle { } SectionHeader { - id: landingPointSection - text: qsTr("Landing point") + id: landingPointSection + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Landing point") } Column { @@ -181,9 +185,11 @@ Rectangle { } SectionHeader { - id: cameraSection - text: qsTr("Camera") - visible: _showCameraSection + id: cameraSection + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Camera") + visible: _showCameraSection } Column { @@ -208,6 +214,16 @@ Rectangle { property Fact _stopTakingVideo: missionItem.stopTakingVideo } } + + QGCLabel { + anchors.left: parent.left + anchors.right: parent.right + wrapMode: Text.WordWrap + color: qgcPal.warningText + font.pointSize: ScreenTools.smallFontPointSize + horizontalAlignment: Text.AlignHCenter + text: qsTr("* Glide slope altitudes are approximate. Actual flight path will vary due to environmental conditions and vehicle settings.") + } } Column { diff --git a/src/PlanView/FWLandingPatternMapVisual.qml b/src/PlanView/FWLandingPatternMapVisual.qml index d46634551973ce32f8c46b6016c08de8538df5f7..22d85921959a23280a0819886880f99db604dc1c 100644 --- a/src/PlanView/FWLandingPatternMapVisual.qml +++ b/src/PlanView/FWLandingPatternMapVisual.qml @@ -455,8 +455,8 @@ Item { visible: _missionItem.isCurrentItem sourceItem: HeightIndicator { - heightText: QGroundControl.metersToAppSettingsDistanceUnits(_transitionAltitudeMeters).toFixed(1) + " " + - QGroundControl.appSettingsDistanceUnitsString + heightText: Math.floor(QGroundControl.metersToAppSettingsDistanceUnits(_transitionAltitudeMeters)) + + QGroundControl.appSettingsDistanceUnitsString + "*" } function recalc() { @@ -486,8 +486,8 @@ Item { visible: _missionItem.isCurrentItem sourceItem: HeightIndicator { - heightText: QGroundControl.metersToAppSettingsDistanceUnits(_midSlopeAltitudeMeters).toFixed(1) + " " + - QGroundControl.appSettingsDistanceUnitsString + heightText: Math.floor(QGroundControl.metersToAppSettingsDistanceUnits(_midSlopeAltitudeMeters)) + + QGroundControl.appSettingsDistanceUnitsString + "*" } function recalc() { @@ -520,7 +520,7 @@ Item { coordinate: _missionItem.loiterTangentCoordinate sourceItem: HeightIndicator { - heightText: _missionItem.loiterAltitude.value.toFixed(1) + " " + QGroundControl.appSettingsDistanceUnitsString + heightText: _missionItem.loiterAltitude.value.toFixed(1) + QGroundControl.appSettingsDistanceUnitsString } } } diff --git a/src/PlanView/GeoFenceEditor.qml b/src/PlanView/GeoFenceEditor.qml index 40bfa0e62d1f1b0b9fa996e5ebcc6867579f47fe..667b6d37d84d99a21bdf9698550d9d96e7c8c751 100644 --- a/src/PlanView/GeoFenceEditor.qml +++ b/src/PlanView/GeoFenceEditor.qml @@ -110,8 +110,10 @@ QGCFlickable { } SectionHeader { - id: insertSection - text: qsTr("Insert GeoFence") + id: insertSection + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Insert GeoFence") } QGCButton { @@ -139,8 +141,10 @@ QGCFlickable { } SectionHeader { - id: polygonSection - text: qsTr("Polygon Fences") + id: polygonSection + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Polygon Fences") } QGCLabel { @@ -212,8 +216,10 @@ QGCFlickable { } // GridLayout SectionHeader { - id: circleSection - text: qsTr("Circular Fences") + id: circleSection + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Circular Fences") } QGCLabel { @@ -302,8 +308,10 @@ QGCFlickable { } // GridLayout SectionHeader { - id: breachReturnSection - text: qsTr("Breach Return Point") + id: breachReturnSection + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Breach Return Point") } QGCButton { diff --git a/src/PlanView/MissionItemEditor.qml b/src/PlanView/MissionItemEditor.qml index 5a1ec4936356561016360eaa788a985ee7cea7d8..a6119058eb20f1af427d6774aef4f641c5c94596 100644 --- a/src/PlanView/MissionItemEditor.qml +++ b/src/PlanView/MissionItemEditor.qml @@ -3,6 +3,7 @@ import QtQuick.Controls 2.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Dialogs 1.2 import QtQml 2.2 +import QtQuick.Layouts 1.11 import QGroundControl 1.0 import QGroundControl.ScreenTools 1.0 @@ -46,6 +47,7 @@ Rectangle { readonly property real _margin: ScreenTools.defaultFontPixelWidth / 2 readonly property real _radius: ScreenTools.defaultFontPixelWidth / 2 readonly property real _hamburgerSize: commandPicker.height * 0.75 + readonly property real _trashSize: commandPicker.height * 0.75 readonly property bool _waypointsOnlyMode: QGroundControl.corePlugin.options.missionWaypointsOnly QGCPalette { @@ -137,46 +139,6 @@ Rectangle { QGCMenu { id: hamburgerMenu - QGCMenuItem { - text: qsTr("Insert waypoint") - onTriggered: insertWaypoint() - } - - QGCMenu { - id: patternMenu - title: qsTr("Insert pattern") - visible: !_singleComplexItem - - Instantiator { - model: _missionController.complexMissionItemNames - - onObjectAdded: patternMenu.insertItem(index, object) - onObjectRemoved: patternMenu.removeItem(object) - - QGCMenuItem { - text: modelData - onTriggered: insertComplexItem(modelData) - } - } - } - - QGCMenuItem { - text: qsTr("Insert ") + _missionController.complexMissionItemNames[0] - visible: _singleComplexItem - onTriggered: insertComplexItem(_missionController.complexMissionItemNames[0]) - } - - QGCMenuItem { - text: qsTr("Delete") - onTriggered: remove() - } - - QGCMenuItem { - text: qsTr("Change command...") - onTriggered: commandPicker.clicked() - visible: missionItem.isSimpleItem && !_waypointsOnlyMode - } - QGCMenuItem { text: qsTr("Edit position...") visible: missionItem.specifiesCoordinate @@ -214,15 +176,66 @@ Rectangle { } } - QGCButton { - id: commandPicker - anchors.topMargin: _margin - anchors.rightMargin: ScreenTools.defaultFontPixelWidth - anchors.leftMargin: _margin + QGCColoredImage { + id: deleteButton + anchors.margins: _margin anchors.left: parent.left - anchors.top: parent.top - visible: !commandLabel.visible - text: missionItem.commandName + anchors.verticalCenter: commandPicker.verticalCenter + height: _hamburgerSize + width: height + sourceSize.height: height + fillMode: Image.PreserveAspectFit + mipmap: true + smooth: true + color: qgcPal.text + visible: _currentItem && missionItem.sequenceNumber !== 0 + source: "/res/TrashDelete.svg" + + QGCMouseArea { + fillItem: parent + onClicked: remove() + } + } + + Rectangle { + id: commandPicker + anchors.margins: _margin + anchors.left: deleteButton.right + anchors.top: parent.top + height: ScreenTools.implicitComboBoxHeight + width: innerLayout.x + innerLayout.width + ScreenTools.comboBoxPadding + visible: !commandLabel.visible + color: qgcPal.window + border.width: 1 + border.color: qgcPal.text + + RowLayout { + id: innerLayout + anchors.margins: _padding + anchors.left: parent.left + anchors.top: parent.top + spacing: _padding + + property real _padding: ScreenTools.comboBoxPadding + + QGCLabel { text: missionItem.commandName } + + QGCColoredImage { + height: ScreenTools.implicitComboBoxHeight - (ScreenTools.comboBoxPadding * 2) + width: height + sourceSize.height: height + fillMode: Image.PreserveAspectFit + smooth: true + antialiasing: true + color: qgcPal.text + source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/images/double-arrow.png" + } + } + + QGCMouseArea { + fillItem: parent + onClicked: mainWindow.showComponentDialog(commandDialog, qsTr("Select Mission Command"), mainWindow.showDialogDefaultWidth, StandardButton.Cancel) + } Component { id: commandDialog @@ -233,15 +246,14 @@ Rectangle { } } - onClicked: mainWindow.showComponentDialog(commandDialog, qsTr("Select Mission Command"), mainWindow.showDialogDefaultWidth, StandardButton.Cancel) } QGCLabel { id: commandLabel + anchors.leftMargin: ScreenTools.comboBoxPadding anchors.fill: commandPicker visible: !missionItem.isCurrentItem || !missionItem.isSimpleItem || _waypointsOnlyMode verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter text: missionItem.commandName color: _outerTextColor } diff --git a/src/PlanView/MissionSettingsEditor.qml b/src/PlanView/MissionSettingsEditor.qml index 3efe77fc971de78d972708421a9a15df36394812..4c6f5095aaa5299f69d65bc40b51fb666873a731 100644 --- a/src/PlanView/MissionSettingsEditor.qml +++ b/src/PlanView/MissionSettingsEditor.qml @@ -108,9 +108,11 @@ Rectangle { } SectionHeader { - id: missionEndHeader - text: qsTr("Mission End") - checked: true + id: missionEndHeader + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Mission End") + checked: true } Column { @@ -128,10 +130,12 @@ Rectangle { SectionHeader { - id: vehicleInfoSectionHeader - text: qsTr("Vehicle Info") - visible: _offlineEditing && !_waypointsOnlyMode - checked: false + id: vehicleInfoSectionHeader + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Vehicle Info") + visible: _offlineEditing && !_waypointsOnlyMode + checked: false } GridLayout { @@ -192,10 +196,12 @@ Rectangle { } // GridLayout SectionHeader { - id: plannedHomePositionSection - text: qsTr("Planned Home Position") - visible: !_vehicleHasHomePosition - checked: false + id: plannedHomePositionSection + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Planned Home Position") + visible: !_vehicleHasHomePosition + checked: false } Column { diff --git a/src/PlanView/PlanStartOverlay.qml b/src/PlanView/PlanStartOverlay.qml deleted file mode 100644 index 6475f5ad5370e87bf14021c159b1aedd8b22d898..0000000000000000000000000000000000000000 --- a/src/PlanView/PlanStartOverlay.qml +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2016 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - -import QtQuick 2.3 -import QtQuick.Controls 2.4 -import QtQuick.Layouts 1.2 - -import QGroundControl 1.0 -import QGroundControl.ScreenTools 1.0 -import QGroundControl.Controls 1.0 -import QGroundControl.Palette 1.0 - -Item { - id: _root - - property var planMasterController - property var mapControl - - property real _radius: ScreenTools.defaultFontPixelWidth / 2 - property real _margins: ScreenTools.defaultFontPixelWidth - - function _mapCenter() { - var centerPoint = Qt.point(mapControl.centerViewport.left + (mapControl.centerViewport.width / 2), mapControl.centerViewport.top + (mapControl.centerViewport.height / 2)) - return mapControl.toCoordinate(centerPoint, false /* clipToViewPort */) - } - - QGCPalette { id: qgcPal; colorGroupEnabled: enabled } - - Rectangle { - anchors.fill: parent - radius: _radius - color: "white" - opacity: 0.75 - } - - // Close Icon - QGCColoredImage { - anchors.margins: ScreenTools.defaultFontPixelWidth / 2 - anchors.top: parent.top - anchors.right: parent.right - width: ScreenTools.defaultFontPixelHeight - height: width - sourceSize.height: width - source: "/res/XDelete.svg" - fillMode: Image.PreserveAspectFit - mipmap: true - smooth: true - color: "black" - QGCMouseArea { - fillItem: parent - onClicked: _root.visible = false - } - } - - QGCLabel { - id: title - anchors.left: parent.left - anchors.right: parent.right - horizontalAlignment: Text.AlignHCenter - text: qsTr("Create Plan") - color: "black" - } - - QGCFlickable { - id: flickable - anchors.margins: _margins - anchors.top: title.bottom - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - contentHeight: creatorFlow.height - contentWidth: creatorFlow.width - - Flow { - id: creatorFlow - width: flickable.width - spacing: _margins - - Repeater { - model: _planMasterController.planCreators - - Rectangle { - id: button - width: ScreenTools.defaultFontPixelHeight * 10 - height: width - color: button.pressed || button.highlighted ? qgcPal.buttonHighlight : qgcPal.button - - property bool highlighted: mouseArea.containsMouse - property bool pressed: mouseArea.pressed - - Image { - anchors.margins: _margins - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - source: object.imageResource - fillMode: Image.PreserveAspectFit - mipmap: true - } - - QGCLabel { - anchors.margins: _margins - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - horizontalAlignment: Text.AlignHCenter - text: object.name - color: button.pressed || button.highlighted ? qgcPal.buttonHighlightText : qgcPal.buttonText - } - - QGCMouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - preventStealing: true - onClicked: { object.createPlan(_mapCenter()); _root.visible = false } - } - } - } - } - } -} diff --git a/src/PlanView/PlanView.qml b/src/PlanView/PlanView.qml index 19acdbfecd834680de6512a5dd10fcc9519e851c..21a6d3ce298d8571ff388ef53b183292786a7e92 100644 --- a/src/PlanView/PlanView.qml +++ b/src/PlanView/PlanView.qml @@ -28,6 +28,7 @@ import QGroundControl.Airspace 1.0 import QGroundControl.Airmap 1.0 Item { + id: _root property bool planControlColapsed: false @@ -64,7 +65,14 @@ Item { coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces) coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces) coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces) - insertComplexMissionItem(complexItemName, coordinate, _missionController.visualItems.count) + var next_index = _missionController.visualItemIndexFromSequenceNumber(_missionController.currentPlanViewIndex)+1 + if(next_index ==1 && _missionController.visualItems.count >1){ + console.log(next_index, _missionController.visualItems.count) + insertComplexMissionItem(complexItemName, coordinate, next_index+1) + } + else if(next_index <= _missionController.visualItems.count){ + insertComplexMissionItem(complexItemName, coordinate, next_index) + } } function insertComplexMissionItem(complexItemName, coordinate, index) { @@ -110,6 +118,12 @@ Item { } } + onVisibleChanged: { + if (visible && !_planMasterController.containsItems) { + toolStrip.simulateClick(toolStrip.fileButtonIndex) + } + } + Connections { target: _appSettings ? _appSettings.defaultMissionItemAltitude : null onRawValueChanged: { @@ -330,7 +344,7 @@ Item { if (retList[0] == ShapeFileHelper.Error) { mainWindow.showMessageDialog("Error", retList[1]) } else if (retList[0] == ShapeFileHelper.Polygon) { - var editVehicle = activeVehicle ? activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle + var editVehicle = activeVehicle ? activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle if (editVehicle.fixedWing) { insertComplexMissionItemFromKMLOrSHP(_missionController.surveyComplexItemName, file, -1) } else { @@ -461,7 +475,14 @@ Item { switch (_editingLayer) { case _layerMission: if (_addWaypointOnClick) { - insertSimpleMissionItem(coordinate, _missionController.visualItems.count) + var next_index = _missionController.visualItemIndexFromSequenceNumber(_missionController.currentPlanViewIndex)+1 + if(next_index ==1 && _missionController.visualItems.count >1){ + console.log(next_index, _missionController.visualItems.count) + insertSimpleMissionItem(coordinate, next_index+1) + } + else if(next_index <= _missionController.visualItems.count){ + insertSimpleMissionItem(coordinate, next_index) + } } else if (_addROIOnClick) { _addROIOnClick = false insertROIMissionItem(coordinate, _missionController.visualItems.count) @@ -476,18 +497,6 @@ Item { } } - PlanStartOverlay { - id: startOverlay - x: editorMap.centerViewport.left - y: editorMap.centerViewport.top - width: editorMap.centerViewport.width - height: editorMap.centerViewport.height - z: QGroundControl.zOrderMapItems + 2 - visible: !_planMasterController.containsItems - planMasterController: _planMasterController - mapControl: editorMap - } - // Add the mission item visuals to the map Repeater { model: _editingLayer == _layerMission ? _missionController.visualItems : undefined @@ -609,6 +618,8 @@ Item { z: QGroundControl.zOrderWidgets maxHeight: mapScale.y - toolStrip.y + property int fileButtonIndex: 1 + property bool _isRally: _editingLayer == _layerRallyPoints model: [ @@ -939,19 +950,14 @@ Item { } } + property var createPlanRemoveAllPromptDialogMapCenter + property var createPlanRemoveAllPromptDialogPlanCreator Component { - id: removeAllPromptDialog + id: createPlanRemoveAllPromptDialog QGCViewMessage { - message: qsTr("Are you sure you want to remove all items and create a new plan? ") + - (_planMasterController.offline ? "" : qsTr("This will also remove all items from the vehicle.")) + message: qsTr("Are you sure you want to remove current plan and create a new plan? ") function accept() { - if (_planMasterController.offline) { - _planMasterController.removeAll() - } else { - _planMasterController.removeAllFromVehicle() - } - _missionController.setCurrentPlanViewIndex(0, true) - startOverlay.visible = true + createPlanRemoveAllPromptDialogPlanCreator.createPlan(createPlanRemoveAllPromptDialogMapCenter) hideDialog() } } @@ -964,7 +970,6 @@ Item { function accept() { _planMasterController.removeAllFromVehicle() _missionController.setCurrentPlanViewIndex(0, true) - startOverlay.visible = true hideDialog() } } @@ -1027,42 +1032,115 @@ Item { Component { id: syncDropPanel - Column { + ColumnLayout { id: columnHolder spacing: _margin property string _overwriteText: (_editingLayer == _layerMission) ? qsTr("Mission overwrite") : ((_editingLayer == _layerGeoFence) ? qsTr("GeoFence overwrite") : qsTr("Rally Points overwrite")) QGCLabel { - width: sendSaveGrid.width - wrapMode: Text.WordWrap - text: _planMasterController.dirty ? - (activeVehicle ? - qsTr("You have unsaved changes. You should upload to your vehicle, or save to a file:") : - qsTr("You have unsaved changes.") - ) : - qsTr("Plan File:") + id: unsavedChangedLabel + Layout.fillWidth: true + wrapMode: Text.WordWrap + text: activeVehicle ? + qsTr("You have unsaved changes. You should upload to your vehicle, or save to a file.") : + qsTr("You have unsaved changes.") + visible: _planMasterController.dirty + } + + SectionHeader { + id: createSection + Layout.fillWidth: true + text: qsTr("Create Plan") + showSpacer: false } GridLayout { - id: sendSaveGrid columns: 2 - anchors.margins: _margin + columnSpacing: _margin + rowSpacing: _margin + Layout.fillWidth: true + visible: createSection.visible + + Repeater { + model: _planMasterController.planCreators + + Rectangle { + id: button + width: ScreenTools.defaultFontPixelHeight * 7 + height: planCreatorNameLabel.y + planCreatorNameLabel.height + color: button.pressed || button.highlighted ? qgcPal.buttonHighlight : qgcPal.button + + property bool highlighted: mouseArea.containsMouse + property bool pressed: mouseArea.pressed + + Image { + id: planCreatorImage + anchors.left: parent.left + anchors.right: parent.right + source: object.imageResource + sourceSize.width: width + fillMode: Image.PreserveAspectFit + mipmap: true + } + + QGCLabel { + id: planCreatorNameLabel + anchors.top: planCreatorImage.bottom + anchors.left: parent.left + anchors.right: parent.right + horizontalAlignment: Text.AlignHCenter + text: object.name + color: button.pressed || button.highlighted ? qgcPal.buttonHighlightText : qgcPal.buttonText + } + + QGCMouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + preventStealing: true + onClicked: { + if (_planMasterController.containsItems) { + createPlanRemoveAllPromptDialogMapCenter = _mapCenter() + createPlanRemoveAllPromptDialogPlanCreator = object + mainWindow.showComponentDialog(createPlanRemoveAllPromptDialog, qsTr("Create Plan"), mainWindow.showDialogDefaultWidth, StandardButton.Yes | StandardButton.No) + } else { + object.createPlan(_mapCenter()) + } + dropPanel.hide() + } + + function _mapCenter() { + var centerPoint = Qt.point(editorMap.centerViewport.left + (editorMap.centerViewport.width / 2), editorMap.centerViewport.top + (editorMap.centerViewport.height / 2)) + return editorMap.toCoordinate(centerPoint, false /* clipToViewPort */) + } + } + } + } + } + + SectionHeader { + id: storageSection + Layout.fillWidth: true + text: qsTr("Storage") + } + + GridLayout { + columns: 3 rowSpacing: _margin columnSpacing: ScreenTools.defaultFontPixelWidth + visible: storageSection.visible - QGCButton { + /*QGCButton { text: qsTr("New...") Layout.fillWidth: true onClicked: { dropPanel.hide() if (_planMasterController.containsItems) { mainWindow.showComponentDialog(removeAllPromptDialog, qsTr("New Plan"), mainWindow.showDialogDefaultWidth, StandardButton.Yes | StandardButton.No) - } else { - startOverlay.visible = true } } - } + }*/ QGCButton { text: qsTr("Open...") @@ -1103,8 +1181,9 @@ Item { } QGCButton { + Layout.columnSpan: 3 + Layout.fillWidth: true text: qsTr("Save Mission Waypoints As KML...") - Layout.columnSpan: 2 enabled: !_planMasterController.syncInProgress && _visualItems.count > 1 onClicked: { // First point does not count @@ -1116,16 +1195,18 @@ Item { _planMasterController.saveKmlToSelectedFile() } } + } - Rectangle { - width: parent.width * 0.8 - height: 1 - color: qgcPal.text - opacity: 0.5 - visible: !QGroundControl.corePlugin.options.disableVehicleConnection - Layout.fillWidth: true - Layout.columnSpan: 2 - } + SectionHeader { + id: vehicleSection + Layout.fillWidth: true + text: qsTr("Vehicle") + } + + RowLayout { + Layout.fillWidth: true + spacing: _margin + visible: vehicleSection.visible QGCButton { text: qsTr("Upload") @@ -1154,7 +1235,7 @@ Item { } QGCButton { - text: qsTr("Clear Vehicle Mission") + text: qsTr("Clear") Layout.fillWidth: true Layout.columnSpan: 2 enabled: !_planMasterController.offline && !_planMasterController.syncInProgress @@ -1164,8 +1245,9 @@ Item { mainWindow.showComponentDialog(clearVehicleMissionDialog, text, mainWindow.showDialogDefaultWidth, StandardButton.Yes | StandardButton.Cancel) } } - } + + } } } diff --git a/src/PlanView/StructureScanEditor.qml b/src/PlanView/StructureScanEditor.qml index 31e307ef69f47cae28e5518651a3445c97f75d6d..c8a8611477410cf7129e0ab4f8aea33bd9820599 100644 --- a/src/PlanView/StructureScanEditor.qml +++ b/src/PlanView/StructureScanEditor.qml @@ -130,8 +130,10 @@ Rectangle { } SectionHeader { - id: scanHeader - text: qsTr("Scan") + id: scanHeader + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Scan") } Column { @@ -200,8 +202,10 @@ Rectangle { } // Column - Scan SectionHeader { - id: statsHeader - text: qsTr("Statistics") + id: statsHeader + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Statistics") } Grid { diff --git a/src/PlanView/SurveyItemEditor.qml b/src/PlanView/SurveyItemEditor.qml index 291dd8680b1446a8cb8525da21f5a12bbe542e6f..c2fcf07e697ce1f7fbacfc7bc0dd62fe46397a32 100644 --- a/src/PlanView/SurveyItemEditor.qml +++ b/src/PlanView/SurveyItemEditor.qml @@ -124,8 +124,10 @@ Rectangle { } SectionHeader { - id: transectsHeader - text: qsTr("Transects") + id: transectsHeader + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Transects") } GridLayout { @@ -233,9 +235,11 @@ Rectangle { } SectionHeader { - id: terrainHeader - text: qsTr("Terrain") - checked: missionItem.followTerrain + id: terrainHeader + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Terrain") + checked: missionItem.followTerrain } ColumnLayout { @@ -280,8 +284,10 @@ Rectangle { } SectionHeader { - id: statsHeader - text: qsTr("Statistics") + id: statsHeader + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Statistics") } TransectStyleComplexItemStats { @@ -357,8 +363,6 @@ Rectangle { SectionHeader { id: presectsTransectsHeader - anchors.left: undefined - anchors.right: undefined Layout.fillWidth: true text: qsTr("Transects") } @@ -400,11 +404,9 @@ Rectangle { } SectionHeader { - id: presetsStatsHeader - anchors.left: undefined - anchors.right: undefined + id: presetsStatsHeader Layout.fillWidth: true - text: qsTr("Statistics") + text: qsTr("Statistics") } TransectStyleComplexItemStats { diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 40c3a62d9dadb43ea2f377048b0ea78eb913e59c..c2b744209e1121622c442896f9d6541bec7de1cf 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -158,12 +158,8 @@ static QObject* shapeFileHelperSingletonFactory(QQmlEngine*, QJSEngine*) } QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) - #if defined(__mobile__) - : QGuiApplication (argc, argv) - #else - : QApplication (argc, argv) - #endif - , _runningUnitTests (unitTesting) + : QGuiApplication (argc, argv) + , _runningUnitTests (unitTesting) { _app = this; _msecsElapsedTime.start(); diff --git a/src/QGCApplication.h b/src/QGCApplication.h index 19b293883e9d3ea0a28a9d4e961bf3068c55bef3..364da2d10866ba52ff126b0b678e7fae543af5cd 100644 --- a/src/QGCApplication.h +++ b/src/QGCApplication.h @@ -7,17 +7,7 @@ * ****************************************************************************/ - -/** - * @file - * @brief Definition of main class - * - * @author Lorenz Meier - * - */ - -#ifndef QGCAPPLICATION_H -#define QGCAPPLICATION_H +#pragma once #include #include @@ -45,21 +35,7 @@ class QGCSingleton; class QGCToolbox; class QGCFileDownload; -/** - * @brief The main application and management class. - * - * This class is started by the main method and provides - * the central management unit of the groundstation application. - * - * Needs QApplication base to support QtCharts drawing module and - * avoid application crashing on 5.12. Enforce no widget on mobile -**/ -class QGCApplication : - #if defined(__mobile__) - public QGuiApplication - #else - public QApplication - #endif +class QGCApplication : public QGuiApplication { Q_OBJECT @@ -214,5 +190,3 @@ private: /// @brief Returns the QGCApplication object singleton. QGCApplication* qgcApp(void); - -#endif diff --git a/src/QmlControls/MAVLinkMessageButton.qml b/src/QmlControls/MAVLinkMessageButton.qml index 9ae7d1eff10b501033cc4cf2bf09b98a005e56a2..8b9f543d626bd9e66e7626fd9f8f89eae98568fc 100644 --- a/src/QmlControls/MAVLinkMessageButton.qml +++ b/src/QmlControls/MAVLinkMessageButton.qml @@ -18,6 +18,12 @@ Button { id: control height: ScreenTools.defaultFontPixelHeight * 2 autoExclusive: true + leftPadding: ScreenTools.defaultFontPixelWidth + rightPadding: leftPadding + + property real _compIDWidth: ScreenTools.defaultFontPixelWidth * 3 + property real _hzWidth: ScreenTools.defaultFontPixelWidth * 7 + property real _nameWidth: nameLabel.contentWidth background: Rectangle { anchors.fill: parent @@ -28,20 +34,27 @@ Button { property int compID: 0 contentItem: RowLayout { + id: rowLayout + spacing: ScreenTools.defaultFontPixelWidth + QGCLabel { - text: control.compID - color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText - Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 3 + text: control.compID + color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText + Layout.minimumWidth: _compIDWidth } QGCLabel { - text: control.text - color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText - Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 28 + id: nameLabel + text: control.text + color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText + Layout.fillWidth: true } QGCLabel { - color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText - text: messageHz.toFixed(1) + 'Hz' - Layout.alignment: Qt.AlignRight + color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText + text: messageHz.toFixed(1) + 'Hz' + horizontalAlignment: Text.AlignRight + Layout.minimumWidth: _hzWidth } } + + Component.onCompleted: maxButtonWidth = Math.max(maxButtonWidth, _compIDWidth + _hzWidth + _nameWidth + (rowLayout.spacing * 2) + (control.leftPadding * 2)) } diff --git a/src/QmlControls/PageView.qml b/src/QmlControls/PageView.qml index 3be0cfd1c9e48198cd2fb0b35915399c6d4497bc..bece2868151ac77ca3b4606f37eabc88d08d77d9 100644 --- a/src/QmlControls/PageView.qml +++ b/src/QmlControls/PageView.qml @@ -29,14 +29,16 @@ Rectangle { centeredLabel: true font.pointSize: ScreenTools.smallFontPointSize - Image { + QGCColoredImage { anchors.leftMargin: _margins anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter source: "/res/gear-black.svg" mipmap: true - width: parent.height -(_margins * 2) - sourceSize.width: width + height: parent.height * 0.7 + width: height + sourceSize.height: height + color: qgcPal.text fillMode: Image.PreserveAspectFit visible: pageWidgetLoader.item ? (pageWidgetLoader.item.showSettingsIcon ? pageWidgetLoader.item.showSettingsIcon : false) : false diff --git a/src/QmlControls/ParameterEditor.qml b/src/QmlControls/ParameterEditor.qml index f7537f3fb5f6575ef1c5dc1cbba0a90d774c345d..4095eb1570b16ab7ddcdfb4b8c369518f1fc8920 100644 --- a/src/QmlControls/ParameterEditor.qml +++ b/src/QmlControls/ParameterEditor.qml @@ -32,10 +32,8 @@ Item { property var _appSettings: QGroundControl.settingsManager.appSettings ParameterEditorController { - id: controller; - onShowErrorMessage: { - mainWindow.showMessageDialog(qsTr("Parameter Editor"), qsTr("Parameter Load Errors")) - } + id: controller + onShowErrorMessage: mainWindow.showMessageDialog(qsTr("Parameter Load Errors"), errorMsg) } ExclusiveGroup { id: sectionGroup } @@ -176,6 +174,8 @@ Item { SectionHeader { id: categoryHeader + anchors.left: parent.left + anchors.right: parent.right text: category checked: controller.currentCategory === text exclusiveGroup: sectionGroup diff --git a/src/QmlControls/PreFlightCheckGroup.qml b/src/QmlControls/PreFlightCheckGroup.qml index f3d2b3feeffece0f96f44bbc397a0dfc13ee3a1f..19280ba8d26d38b7159a36e57ea82939d059b293 100644 --- a/src/QmlControls/PreFlightCheckGroup.qml +++ b/src/QmlControls/PreFlightCheckGroup.qml @@ -43,8 +43,10 @@ Column { } SectionHeader { - id: header - text: name + (passed ? qsTr(" (passed)") : "") + id: header + anchors.left: parent.left + anchors.right: parent.right + text: name + (passed ? qsTr(" (passed)") : "") } Column { diff --git a/src/QmlControls/QGroundControl/Controls/qmldir b/src/QmlControls/QGroundControl/Controls/qmldir index 8d3abf8b978a55fef6836b857c163d878045c1f2..fae59ca2d0aa2dbf6937ea1a1ba846b3c7feffae 100644 --- a/src/QmlControls/QGroundControl/Controls/qmldir +++ b/src/QmlControls/QGroundControl/Controls/qmldir @@ -40,7 +40,6 @@ ParameterEditor 1.0 ParameterEditor.qml ParameterEditorDialog 1.0 ParameterEditorDialog.qml PIDTuning 1.0 PIDTuning.qml PlanEditToolbar 1.0 PlanEditToolbar.qml -PlanStartOverlay 1.0 PlanStartOverlay.qml PreFlightCheckButton 1.0 PreFlightCheckButton.qml PreFlightCheckGroup 1.0 PreFlightCheckGroup.qml PreFlightCheckModel 1.0 PreFlightCheckModel.qml diff --git a/src/QmlControls/SectionHeader.qml b/src/QmlControls/SectionHeader.qml index 06c9a2ca533ccb57c9f5a810bd242c016ab98931..dc763f2e3da17c4fe55391980e5bd5fca492156e 100644 --- a/src/QmlControls/SectionHeader.qml +++ b/src/QmlControls/SectionHeader.qml @@ -7,10 +7,8 @@ import QGroundControl.ScreenTools 1.0 import QGroundControl.Palette 1.0 FocusScope { - id: _root - anchors.left: parent.left - anchors.right: parent.right - height: column.height + id: _root + height: column.height property alias text: label.text property bool checked: true diff --git a/src/QmlControls/ToolStrip.qml b/src/QmlControls/ToolStrip.qml index 5c09c525280de91a04b1b0f23af7389e324f42f5..be668af7f2288bda4e65edfb795c0be71938ecfa 100644 --- a/src/QmlControls/ToolStrip.qml +++ b/src/QmlControls/ToolStrip.qml @@ -27,6 +27,11 @@ Rectangle { property AbstractButton lastClickedButton: null + function simulateClick(buttonIndex) { + toolStripColumn.children[buttonIndex].checked = true + toolStripColumn.children[buttonIndex].clicked() + } + // Ensure we don't get narrower than content property real _idealWidth: (ScreenTools.isMobile ? ScreenTools.minTouchPixels : ScreenTools.defaultFontPixelWidth * 8) + toolStripColumn.anchors.margins * 2 @@ -73,7 +78,7 @@ Rectangle { checked: modelData.checked !== undefined ? modelData.checked : checked ButtonGroup.group: buttonGroup - // Only drop pannel and toggleable are checkable + // Only drop panel and toggleable are checkable checkable: modelData.dropPanelComponent !== undefined || (modelData.toggle !== undefined && modelData.toggle) onClicked: { diff --git a/src/Vehicle/TrajectoryPoints.cc b/src/Vehicle/TrajectoryPoints.cc index 49f6b1f5f4d63d9d7a285756897c06d58fad7b85..aa3e719c67941875e79a617dde5f3cdea588d126 100644 --- a/src/Vehicle/TrajectoryPoints.cc +++ b/src/Vehicle/TrajectoryPoints.cc @@ -19,22 +19,29 @@ TrajectoryPoints::TrajectoryPoints(Vehicle* vehicle, QObject* parent) void TrajectoryPoints::_vehicleCoordinateChanged(QGeoCoordinate coordinate) { + // The goal of this algorithm is to limit the number of trajectory points whic represent the vehicle path. + // Fewer points means higher performance of map display. + if (_lastPoint.isValid()) { if (_lastPoint.distanceTo(coordinate) > _distanceTolerance) { + // Vehicle has moved far enough from previous point for an update double newAzimuth = _lastPoint.azimuthTo(coordinate); if (qIsNaN(_lastAzimuth) || qAbs(newAzimuth - _lastAzimuth) > _azimuthTolerance) { + // The new position IS NOT colinear with the last segment. Append the new position to the list. _lastAzimuth = _lastPoint.azimuthTo(coordinate); _lastPoint = coordinate; _points.append(QVariant::fromValue(coordinate)); emit pointAdded(coordinate); } else { + // The new position IS colinear with the last segment. Don't add a new point, just update + // the last point to be the new position. _lastPoint = coordinate; _points[_points.count() - 1] = QVariant::fromValue(coordinate); emit updateLastPoint(coordinate); } } } else { - _lastAzimuth = _lastPoint.azimuthTo(coordinate); + // Add the very first trajectory point to the list _lastPoint = coordinate; _points.append(QVariant::fromValue(coordinate)); emit pointAdded(coordinate); @@ -56,5 +63,7 @@ void TrajectoryPoints::stop(void) void TrajectoryPoints::clear(void) { _points.clear(); + _lastPoint = QGeoCoordinate(); + _lastAzimuth = qQNaN(); emit pointsCleared(); } diff --git a/src/ui/MainRootWindow.qml b/src/ui/MainRootWindow.qml index 8111f221af6b367701ccc3bd1715ce5843bdfa69..0468d92cbfbad93c81d9b6e0d2ba6e55bb82508a 100644 --- a/src/ui/MainRootWindow.qml +++ b/src/ui/MainRootWindow.qml @@ -196,47 +196,66 @@ ApplicationWindow { mainWindow.close() } + // On attempting an application close we check for: + // Unsaved missions - then + // Pending parameter writes - then + // Active connections + onClosing: { + if (!_forceClose) { + unsavedMissionCloseDialog.check() + close.accepted = false + } + } + MessageDialog { - id: activeConnectionsCloseDialog + id: unsavedMissionCloseDialog title: qsTr("%1 close").arg(QGroundControl.appName) - text: qsTr("There are still active connections to vehicles. Are you sure you want to exit?") - standardButtons: StandardButton.Yes | StandardButton.Cancel + text: qsTr("You have a mission edit in progress which has not been saved/sent. If you close you will lose changes. Are you sure you want to close?") + standardButtons: StandardButton.Yes | StandardButton.No modality: Qt.ApplicationModal visible: false - onYes: finishCloseProcess() + onYes: pendingParameterWritesCloseDialog.check() function check() { - if (QGroundControl.multiVehicleManager.activeVehicle) { - activeConnectionsCloseDialog.open() + if (planMasterControllerPlan && planMasterControllerPlan.dirty) { + unsavedMissionCloseDialog.open() } else { - finishCloseProcess() + pendingParameterWritesCloseDialog.check() } } } - //------------------------------------------------------------------------- - //-- Check for unsaved missions - - onClosing: { - // Check first for unsaved missions and active connections - if (!_forceClose) { - unsavedMissionCloseDialog.check() - close.accepted = false + MessageDialog { + id: pendingParameterWritesCloseDialog + title: qsTr("%1 close").arg(QGroundControl.appName) + text: qsTr("You have pending parameter updates to a vehicle. If you close you will lose changes. Are you sure you want to close?") + standardButtons: StandardButton.Yes | StandardButton.No + modality: Qt.ApplicationModal + visible: false + onYes: activeConnectionsCloseDialog.check() + function check() { + for (var index=0; index