diff --git a/src/FactSystem/FactControls/FactTextField.qml b/src/FactSystem/FactControls/FactTextField.qml index 494a73f401b76a757e33b166fb4f7caeb2e246bb..dc6206170b00ac95cf975f83e582d09cd2e20ff4 100644 --- a/src/FactSystem/FactControls/FactTextField.qml +++ b/src/FactSystem/FactControls/FactTextField.qml @@ -16,12 +16,14 @@ QGCTextField { showUnits: true showHelp: true - property Fact fact: null + property Fact fact: null + property string _validateString + property bool _factIsString: fact ? fact.type === FactMetaData.valueTypeString : false // At this point all Facts are numeric - inputMethodHints: ScreenTools.isiOS ? - Qt.ImhNone : // iOS numeric keyboard has not done button, we can't use it + inputMethodHints: (_factIsString || ScreenTools.isiOS) ? + Qt.ImhNone : // iOS numeric keyboard has no done button, we can't use it Qt.ImhFormattedNumbersOnly // Forces use of virtual numeric keyboard onEditingFinished: { diff --git a/src/FactSystem/FactMetaData.cc b/src/FactSystem/FactMetaData.cc index 6d9f47f58b066e2a4c18819b6e60564873d7b98c..ade759c9a87ecc90b0c9a4704dac9b698a62c091 100644 --- a/src/FactSystem/FactMetaData.cc +++ b/src/FactSystem/FactMetaData.cc @@ -7,12 +7,6 @@ * ****************************************************************************/ - -/// @file -/// @brief Object which exposes a FactMetaData -/// -/// @author Don Gagne - #include "FactMetaData.h" #include "SettingsManager.h" #include "JsonHelper.h" @@ -157,7 +151,7 @@ QVariant FactMetaData::rawDefaultValue(void) const void FactMetaData::setRawDefaultValue(const QVariant& rawDefaultValue) { - if (_rawMin <= rawDefaultValue && rawDefaultValue <= _rawMax) { + if (_type == valueTypeString || (_rawMin <= rawDefaultValue && rawDefaultValue <= _rawMax)) { _rawDefaultValue = rawDefaultValue; _defaultValueAvailable = true; } else { @@ -208,6 +202,8 @@ QVariant FactMetaData::_minForType(void) const return QVariant(-std::numeric_limits::max()); case valueTypeDouble: return QVariant(-std::numeric_limits::max()); + case valueTypeString: + return QVariant(); } // Make windows compiler happy, even switch is full cased @@ -233,6 +229,8 @@ QVariant FactMetaData::_maxForType(void) const return QVariant(std::numeric_limits::max()); case valueTypeDouble: return QVariant(std::numeric_limits::max()); + case valueTypeString: + return QVariant(); } // Make windows compiler happy, even switch is full cased @@ -285,6 +283,10 @@ bool FactMetaData::convertAndValidateRaw(const QVariant& rawValue, bool convertO } } break; + case FactMetaData::valueTypeString: + convertOk = true; + typedValue = QVariant(rawValue.toString()); + break; } if (!convertOk) { @@ -340,6 +342,10 @@ bool FactMetaData::convertAndValidateCooked(const QVariant& cookedValue, bool co } } break; + case FactMetaData::valueTypeString: + convertOk = true; + typedValue = QVariant(cookedValue.toString()); + break; } if (!convertOk) { @@ -556,7 +562,8 @@ FactMetaData::ValueType_t FactMetaData::stringToType(const QString& typeString, << QStringLiteral("Uint32") << QStringLiteral("Int32") << QStringLiteral("Float") - << QStringLiteral("Double"); + << QStringLiteral("Double") + << QStringLiteral("String"); knownTypes << valueTypeUint8 << valueTypeInt8 @@ -565,7 +572,8 @@ FactMetaData::ValueType_t FactMetaData::stringToType(const QString& typeString, << valueTypeUint32 << valueTypeInt32 << valueTypeFloat - << valueTypeDouble; + << valueTypeDouble + << valueTypeString; for (int i=0; i types; - keys << _nameJsonKey << _decimalPlacesJsonKey << _typeJsonKey << _shortDescriptionJsonKey << _longDescriptionJsonKey << _unitsJsonKey << _defaultValueJsonKey << _minJsonKey << _maxJsonKey; - types << QJsonValue::String << QJsonValue::Double << QJsonValue::String << QJsonValue::String << QJsonValue::String << QJsonValue::String << QJsonValue::Double << QJsonValue::Double << QJsonValue::Double; + keys << _nameJsonKey << _decimalPlacesJsonKey << _typeJsonKey << _shortDescriptionJsonKey << _longDescriptionJsonKey << _unitsJsonKey << _minJsonKey << _maxJsonKey; + types << QJsonValue::String << QJsonValue::Double << QJsonValue::String << QJsonValue::String << QJsonValue::String << QJsonValue::String << QJsonValue::Double << QJsonValue::Double; if (!JsonHelper::validateKeyTypes(json, keys, types, errorString)) { qWarning() << errorString; return new FactMetaData(valueTypeUint32, metaDataParent); @@ -811,7 +819,7 @@ FactMetaData* FactMetaData::createFromJsonObject(const QJsonObject& json, QObjec metaData->setRawUnits(json[_unitsJsonKey].toString()); } if (json.contains(_defaultValueJsonKey)) { - metaData->setRawDefaultValue(json[_defaultValueJsonKey].toDouble()); + metaData->setRawDefaultValue(json[_defaultValueJsonKey]); } if (json.contains(_minJsonKey)) { metaData->setRawMin(json[_minJsonKey].toDouble()); diff --git a/src/FactSystem/FactMetaData.h b/src/FactSystem/FactMetaData.h index 07d4b4d23897d50dab53e4a51d8dd2987b1ffb90..abe3b7a12a996ad79ff8f048959e0f49b5c25a04 100644 --- a/src/FactSystem/FactMetaData.h +++ b/src/FactSystem/FactMetaData.h @@ -37,9 +37,12 @@ public: valueTypeUint32, valueTypeInt32, valueTypeFloat, - valueTypeDouble + valueTypeDouble, + valueTypeString } ValueType_t; + Q_ENUM(ValueType_t) + typedef QVariant (*Translator)(const QVariant& from); FactMetaData(QObject* parent = NULL); diff --git a/src/FactSystem/FactSystem.cc b/src/FactSystem/FactSystem.cc index e88b8ce552f5b85486222e9835c3458a826d8fe0..0b9cb3de3b8668536cbce719282f41bc09f23684 100644 --- a/src/FactSystem/FactSystem.cc +++ b/src/FactSystem/FactSystem.cc @@ -30,6 +30,7 @@ void FactSystem::setToolbox(QGCToolbox *toolbox) QGCTool::setToolbox(toolbox); qmlRegisterType (_factSystemQmlUri, 1, 0, "Fact"); + qmlRegisterType (_factSystemQmlUri, 1, 0, "FactMetaData"); qmlRegisterType(_factSystemQmlUri, 1, 0, "FactPanelController"); qmlRegisterUncreatableType(_factSystemQmlUri, 1, 0, "FactGroup", "ReferenceOnly"); diff --git a/src/FirmwarePlugin/APM/APMParameterMetaData.cc b/src/FirmwarePlugin/APM/APMParameterMetaData.cc index 929fe9e5e3608049417b0f8619e1609eabefb3eb..fa05f49b9c81114017c98430fcdebe0df6f2ed35 100644 --- a/src/FirmwarePlugin/APM/APMParameterMetaData.cc +++ b/src/FirmwarePlugin/APM/APMParameterMetaData.cc @@ -39,22 +39,26 @@ QVariant APMParameterMetaData::_stringToTypedVariant(const QString& string, int convertTo = QVariant::Int; // keep compiler warning happy switch (type) { - case FactMetaData::valueTypeUint8: - case FactMetaData::valueTypeUint16: - case FactMetaData::valueTypeUint32: - convertTo = QVariant::UInt; - break; - case FactMetaData::valueTypeInt8: - case FactMetaData::valueTypeInt16: - case FactMetaData::valueTypeInt32: - convertTo = QVariant::Int; - break; - case FactMetaData::valueTypeFloat: - convertTo = QMetaType::Float; - break; - case FactMetaData::valueTypeDouble: - convertTo = QVariant::Double; - break; + case FactMetaData::valueTypeUint8: + case FactMetaData::valueTypeUint16: + case FactMetaData::valueTypeUint32: + convertTo = QVariant::UInt; + break; + case FactMetaData::valueTypeInt8: + case FactMetaData::valueTypeInt16: + case FactMetaData::valueTypeInt32: + convertTo = QVariant::Int; + break; + case FactMetaData::valueTypeFloat: + convertTo = QMetaType::Float; + break; + case FactMetaData::valueTypeDouble: + convertTo = QVariant::Double; + break; + case FactMetaData::valueTypeString: + qWarning() << "Internal Error: No support for string parameters"; + convertTo = QVariant::String; + break; } *convertOk = var.convert(convertTo); diff --git a/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc b/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc index 7fcfaeb7b2fb150c9a2d7f550b27941d372a0df6..3adbce57e003bf33b73a7faf0685fdde67ef2994 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc +++ b/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc @@ -39,22 +39,26 @@ QVariant PX4ParameterMetaData::_stringToTypedVariant(const QString& string, Fact int convertTo = QVariant::Int; // keep compiler warning happy switch (type) { - case FactMetaData::valueTypeUint8: - case FactMetaData::valueTypeUint16: - case FactMetaData::valueTypeUint32: - convertTo = QVariant::UInt; - break; - case FactMetaData::valueTypeInt8: - case FactMetaData::valueTypeInt16: - case FactMetaData::valueTypeInt32: - convertTo = QVariant::Int; - break; - case FactMetaData::valueTypeFloat: - convertTo = QMetaType::Float; - break; - case FactMetaData::valueTypeDouble: - convertTo = QVariant::Double; - break; + case FactMetaData::valueTypeUint8: + case FactMetaData::valueTypeUint16: + case FactMetaData::valueTypeUint32: + convertTo = QVariant::UInt; + break; + case FactMetaData::valueTypeInt8: + case FactMetaData::valueTypeInt16: + case FactMetaData::valueTypeInt32: + convertTo = QVariant::Int; + break; + case FactMetaData::valueTypeFloat: + convertTo = QMetaType::Float; + break; + case FactMetaData::valueTypeDouble: + convertTo = QVariant::Double; + break; + case FactMetaData::valueTypeString: + qWarning() << "Internal Error: No support for string parameters"; + convertTo = QVariant::String; + break; } *convertOk = var.convert(convertTo); diff --git a/src/QmlControls/QGroundControlQmlGlobal.cc b/src/QmlControls/QGroundControlQmlGlobal.cc index df23461f73424279d6053e3decef11493da78a88..c43db9012bc72850cad952ec9d23d06d67cc1845 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.cc +++ b/src/QmlControls/QGroundControlQmlGlobal.cc @@ -21,7 +21,6 @@ static const char* kQmlGlobalKeyName = "QGCQml"; const char* QGroundControlQmlGlobal::_virtualTabletJoystickKey = "VirtualTabletJoystick"; const char* QGroundControlQmlGlobal::_baseFontPointSizeKey = "BaseDeviceFontPointSize"; -const char* QGroundControlQmlGlobal::_missionAutoLoadDirKey = "MissionAutoLoadDir"; QGroundControlQmlGlobal::QGroundControlQmlGlobal(QGCApplication* app) : QGCTool(app) @@ -227,15 +226,3 @@ bool QGroundControlQmlGlobal::linesIntersect(QPointF line1A, QPointF line1B, QPo return QLineF(line1A, line1B).intersect(QLineF(line2A, line2B), &intersectPoint) == QLineF::BoundedIntersection && intersectPoint != line1A && intersectPoint != line1B; } - -QString QGroundControlQmlGlobal::missionAutoLoadDir(void) -{ - QSettings settings; - return settings.value(_missionAutoLoadDirKey).toString(); -} - -void QGroundControlQmlGlobal::setMissionAutoLoadDir(const QString& missionAutoLoadDir) -{ - QSettings settings; - settings.setValue(_missionAutoLoadDirKey, missionAutoLoadDir); -} diff --git a/src/QmlControls/QGroundControlQmlGlobal.h b/src/QmlControls/QGroundControlQmlGlobal.h index bbd04899774f070935d57b9a45f731e4b42c5673..7eaa1c5eb3fce6cc31e606ba70942ee5ab17594c 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.h +++ b/src/QmlControls/QGroundControlQmlGlobal.h @@ -61,7 +61,6 @@ public: Q_PROPERTY(bool isSaveLogPromptNotArmed READ isSaveLogPromptNotArmed WRITE setIsSaveLogPromptNotArmed NOTIFY isSaveLogPromptNotArmedChanged) Q_PROPERTY(bool virtualTabletJoystick READ virtualTabletJoystick WRITE setVirtualTabletJoystick NOTIFY virtualTabletJoystickChanged) Q_PROPERTY(qreal baseFontPointSize READ baseFontPointSize WRITE setBaseFontPointSize NOTIFY baseFontPointSizeChanged) - Q_PROPERTY(QString missionAutoLoadDir READ missionAutoLoadDir WRITE setMissionAutoLoadDir NOTIFY missionAutoLoadDirChanged STORED false) //------------------------------------------------------------------------- // MavLink Protocol @@ -127,6 +126,8 @@ public: Q_INVOKABLE bool linesIntersect(QPointF xLine1, QPointF yLine1, QPointF xLine2, QPointF yLine2); + Q_INVOKABLE QString urlToLocalFile(QUrl url) { return url.toLocalFile(); } + // Property accesors FlightMapSettings* flightMapSettings () { return _flightMapSettings; } @@ -174,9 +175,6 @@ public: QString qgcVersion(void) const { return qgcApp()->applicationVersion(); } - static QString missionAutoLoadDir(void); - static void setMissionAutoLoadDir(const QString& missionAutoLoadDir); - // Overrides from QGCTool virtual void setToolbox(QGCToolbox* toolbox); @@ -192,7 +190,6 @@ signals: void mavlinkSystemIDChanged (int id); void flightMapPositionChanged (QGeoCoordinate flightMapPosition); void flightMapZoomChanged (double flightMapZoom); - void missionAutoLoadDirChanged (QString missionAutoLoadDir); private: FlightMapSettings* _flightMapSettings; @@ -214,7 +211,6 @@ private: static const char* _virtualTabletJoystickKey; static const char* _baseFontPointSizeKey; - static const char* _missionAutoLoadDirKey; }; #endif diff --git a/src/SettingsManager.cc b/src/SettingsManager.cc index 0408440f950f2774e1572ad1e2cfe51dfeee9071..42b8422538b46944dfb8958cb612de437d5d60a3 100644 --- a/src/SettingsManager.cc +++ b/src/SettingsManager.cc @@ -21,6 +21,7 @@ const char* SettingsManager::areaUnitsSettingsName = "Are const char* SettingsManager::speedUnitsSettingsName = "SpeedUnits"; const char* SettingsManager::batteryPercentRemainingAnnounceSettingsName = "batteryPercentRemainingAnnounce"; const char* SettingsManager::defaultMissionItemAltitudeSettingsName = "DefaultMissionItemAltitude"; +const char* SettingsManager::missionAutoLoadDirSettingsName = "MissionAutoLoadDir"; SettingsManager::SettingsManager(QGCApplication* app) : QGCTool(app) @@ -33,6 +34,7 @@ SettingsManager::SettingsManager(QGCApplication* app) , _speedUnitsFact(NULL) , _batteryPercentRemainingAnnounceFact(NULL) , _defaultMissionItemAltitudeFact(NULL) + , _missionAutoLoadDirFact(NULL) { } @@ -103,6 +105,15 @@ Fact* SettingsManager::defaultMissionItemAltitude(void) return _defaultMissionItemAltitudeFact; } +Fact* SettingsManager::missionAutoLoadDir(void) +{ + if (!_missionAutoLoadDirFact) { + _missionAutoLoadDirFact = _createSettingsFact(missionAutoLoadDirSettingsName); + } + + return _missionAutoLoadDirFact; +} + Fact* SettingsManager::distanceUnits(void) { if (!_distanceUnitsFact) { diff --git a/src/SettingsManager.h b/src/SettingsManager.h index bae2fd3b9183a9960986540f66342681adc6423f..14c6c4ec519fe2cceca41487c929571aeb945886 100644 --- a/src/SettingsManager.h +++ b/src/SettingsManager.h @@ -54,25 +54,27 @@ public: Q_ENUMS(AreaUnits) Q_ENUMS(SpeedUnits) - Q_PROPERTY(Fact* offlineEditingFirmwareType READ offlineEditingFirmwareType CONSTANT) - Q_PROPERTY(Fact* offlineEditingVehicleType READ offlineEditingVehicleType CONSTANT) - Q_PROPERTY(Fact* offlineEditingCruiseSpeed READ offlineEditingCruiseSpeed CONSTANT) - Q_PROPERTY(Fact* offlineEditingHoverSpeed READ offlineEditingHoverSpeed CONSTANT) - Q_PROPERTY(Fact* distanceUnits READ distanceUnits CONSTANT) - Q_PROPERTY(Fact* areaUnits READ areaUnits CONSTANT) - Q_PROPERTY(Fact* speedUnits READ speedUnits CONSTANT) - Q_PROPERTY(Fact* batteryPercentRemainingAnnounce READ batteryPercentRemainingAnnounce CONSTANT) - Q_PROPERTY(Fact* defaultMissionItemAltitude READ defaultMissionItemAltitude CONSTANT) - - Fact* offlineEditingFirmwareType (void); - Fact* offlineEditingVehicleType (void); - Fact* offlineEditingCruiseSpeed (void); - Fact* offlineEditingHoverSpeed (void); - Fact* distanceUnits (void); - Fact* areaUnits (void); - Fact* speedUnits (void); - Fact* batteryPercentRemainingAnnounce(void); - Fact* defaultMissionItemAltitude (void); + Q_PROPERTY(Fact* offlineEditingFirmwareType READ offlineEditingFirmwareType CONSTANT) + Q_PROPERTY(Fact* offlineEditingVehicleType READ offlineEditingVehicleType CONSTANT) + Q_PROPERTY(Fact* offlineEditingCruiseSpeed READ offlineEditingCruiseSpeed CONSTANT) + Q_PROPERTY(Fact* offlineEditingHoverSpeed READ offlineEditingHoverSpeed CONSTANT) + Q_PROPERTY(Fact* distanceUnits READ distanceUnits CONSTANT) + Q_PROPERTY(Fact* areaUnits READ areaUnits CONSTANT) + Q_PROPERTY(Fact* speedUnits READ speedUnits CONSTANT) + Q_PROPERTY(Fact* batteryPercentRemainingAnnounce READ batteryPercentRemainingAnnounce CONSTANT) + Q_PROPERTY(Fact* defaultMissionItemAltitude READ defaultMissionItemAltitude CONSTANT) + Q_PROPERTY(Fact* missionAutoLoadDir READ missionAutoLoadDir CONSTANT) + + Fact* offlineEditingFirmwareType (void); + Fact* offlineEditingVehicleType (void); + Fact* offlineEditingCruiseSpeed (void); + Fact* offlineEditingHoverSpeed (void); + Fact* distanceUnits (void); + Fact* areaUnits (void); + Fact* speedUnits (void); + Fact* batteryPercentRemainingAnnounce (void); + Fact* defaultMissionItemAltitude (void); + Fact* missionAutoLoadDir (void); // Override from QGCTool virtual void setToolbox(QGCToolbox *toolbox); @@ -86,13 +88,8 @@ public: static const char* speedUnitsSettingsName; static const char* batteryPercentRemainingAnnounceSettingsName; static const char* defaultMissionItemAltitudeSettingsName; + static const char* missionAutoLoadDirSettingsName; -public slots: - -signals: - -private slots: - private: SettingsFact* _createSettingsFact(const QString& name); @@ -107,6 +104,7 @@ private: SettingsFact* _speedUnitsFact; SettingsFact* _batteryPercentRemainingAnnounceFact; SettingsFact* _defaultMissionItemAltitudeFact; + SettingsFact* _missionAutoLoadDirFact; }; #endif diff --git a/src/SettingsManager.json b/src/SettingsManager.json index e58a6e2a6ab158e81cc631f0d180f0c98b7d634d..aca30132df7dae3b725db6a3705f750c1fbf2fc8 100644 --- a/src/SettingsManager.json +++ b/src/SettingsManager.json @@ -54,5 +54,12 @@ "min": 0.0, "units": "meters", "decimalPlaces": 2 +}, +{ + "name": "MissionAutoLoadDir", + "shortDescription": "Mission auto load directory", + "longDescription": "The directory from which missions will be automaticallu loaded onto a vehicle when it connects.", + "type": "string", + "defaultValue": "" } ] diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 24671d2534b53d6736cf2fb3a6a29c7f0f6500de..a98e094a520978a78e455401f62e79b12223389d 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -1579,7 +1579,7 @@ void Vehicle::_parametersReady(bool parametersReady) { if (parametersReady && !_missionManagerInitialRequestSent) { _missionManagerInitialRequestSent = true; - QString missionAutoLoadDirPath = QGroundControlQmlGlobal::missionAutoLoadDir(); + QString missionAutoLoadDirPath = _settingsManager->missionAutoLoadDir()->rawValue().toString(); if (missionAutoLoadDirPath.isEmpty()) { _missionManager->requestMissionItems(); } else { diff --git a/src/ui/preferences/GeneralSettings.qml b/src/ui/preferences/GeneralSettings.qml index f0f231b2422ff6b6ae60c2f9390e6aaa2dca3896..3783b1ba052332204dcc596d6e2e5408fbe612ad 100644 --- a/src/ui/preferences/GeneralSettings.qml +++ b/src/ui/preferences/GeneralSettings.qml @@ -33,6 +33,7 @@ QGCView { anchors.margins: ScreenTools.defaultFontPixelWidth property Fact _percentRemainingAnnounce: QGroundControl.settingsManager.batteryPercentRemainingAnnounce + property Fact _autoLoadDir: QGroundControl.settingsManager.missionAutoLoadDir property real _labelWidth: ScreenTools.defaultFontPixelWidth * 15 property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30 @@ -331,30 +332,41 @@ QGCView { } } //----------------------------------------------------------------- - //-- AutoLoad + //-- Mission AutoLoad Row { spacing: ScreenTools.defaultFontPixelWidth QGCCheckBox { id: autoLoadCheckbox anchors.verticalCenter: parent.verticalCenter text: qsTr("AutoLoad mission directory:") - checked: QGroundControl.missionAutoLoadDir != "" + checked: _autoLoadDir.valueString onClicked: { - autoLoadDir.enabled = checked - if (!checked) { - QGroundControl.missionAutoLoadDir = "" - autoLoadDir.text = "" + if (checked) { + _autoLoadDir.rawValue = QGroundControl.urlToLocalFile(autoloadDirPicker.shortcuts.home) + } else { + _autoLoadDir.rawValue = "" } } } - QGCTextField { - id: autoLoadDir + FactTextField { + id: autoLoadDirField width: _editFieldWidth enabled: autoLoadCheckbox.checked anchors.verticalCenter: parent.verticalCenter - text: QGroundControl.missionAutoLoadDir - onEditingFinished: QGroundControl.missionAutoLoadDir = text + fact: _autoLoadDir + } + QGCButton { + text: qsTr("Browse") + onClicked: autoloadDirPicker.visible = true + + FileDialog { + id: autoloadDirPicker + title: qsTr("Choose the location of mission file.") + folder: shortcuts.home + selectFolder: true + onAccepted: _autoLoadDir.rawValue = QGroundControl.urlToLocalFile(autoloadDirPicker.fileUrl) + } } } //----------------------------------------------------------------- @@ -561,7 +573,7 @@ QGCView { readOnly: true text: QGroundControl.videoManager.videoSavePath } - Button { + QGCButton { text: "Browse" onClicked: fileDialog.visible = true }