diff --git a/src/FactSystem/FactMetaData.cc b/src/FactSystem/FactMetaData.cc index b4b8ce4de4272c4bfc1f66837dd99f085349a14a..7cccda13260f8ff42f4adf3800cbed2538f5bba3 100644 --- a/src/FactSystem/FactMetaData.cc +++ b/src/FactSystem/FactMetaData.cc @@ -32,6 +32,11 @@ const qreal FactMetaData::UnitConsts_s::milesToMeters = 1609.344; const qreal FactMetaData::UnitConsts_s::feetToMeters = 0.3048; const qreal FactMetaData::UnitConsts_s::inchesToCentimeters = 2.54; +//Weight +const qreal FactMetaData::UnitConsts_s::ouncesToGrams = 28.3495; +const qreal FactMetaData::UnitConsts_s::poundsToGrams = 453.592; + + static const char* kDefaultCategory = QT_TRANSLATE_NOOP("FactMetaData", "Other"); static const char* kDefaultGroup = QT_TRANSLATE_NOOP("FactMetaData", "Misc"); @@ -51,24 +56,31 @@ const FactMetaData::AppSettingsTranslation_s FactMetaData::_rgAppSettingsTransla { "m", "m", FactMetaData::UnitDistance, UnitsSettings::DistanceUnitsMeters, FactMetaData::_defaultTranslator, FactMetaData::_defaultTranslator }, { "meter", "meter", FactMetaData::UnitDistance, UnitsSettings::DistanceUnitsMeters, FactMetaData::_defaultTranslator, FactMetaData::_defaultTranslator }, { "meters", "meters", FactMetaData::UnitDistance, UnitsSettings::DistanceUnitsMeters, FactMetaData::_defaultTranslator, FactMetaData::_defaultTranslator }, + //NOTE: we've coined an artificial "raw unit" of "altitude metre" to separate it from the distance metre - a bit awkward but this is all the design permits + { "alt m", "m", FactMetaData::UnitAltitude, UnitsSettings::AltitudeUnitsMeters, FactMetaData::_defaultTranslator, FactMetaData::_defaultTranslator }, { "cm/px", "cm/px", FactMetaData::UnitDistance, UnitsSettings::DistanceUnitsMeters, FactMetaData::_defaultTranslator, FactMetaData::_defaultTranslator }, { "m/s", "m/s", FactMetaData::UnitSpeed, UnitsSettings::SpeedUnitsMetersPerSecond, FactMetaData::_defaultTranslator, FactMetaData::_defaultTranslator }, { "C", "C", FactMetaData::UnitTemperature, UnitsSettings::TemperatureUnitsCelsius, FactMetaData::_defaultTranslator, FactMetaData::_defaultTranslator }, - { "m^2", "m^2", FactMetaData::UnitArea, UnitsSettings::AreaUnitsSquareMeters, FactMetaData::_defaultTranslator, FactMetaData::_defaultTranslator }, + { "m^2", "m\u00B2", FactMetaData::UnitArea, UnitsSettings::AreaUnitsSquareMeters, FactMetaData::_defaultTranslator, FactMetaData::_defaultTranslator }, { "m", "ft", FactMetaData::UnitDistance, UnitsSettings::DistanceUnitsFeet, FactMetaData::_metersToFeet, FactMetaData::_feetToMeters }, { "meter", "ft", FactMetaData::UnitDistance, UnitsSettings::DistanceUnitsFeet, FactMetaData::_metersToFeet, FactMetaData::_feetToMeters }, { "meters", "ft", FactMetaData::UnitDistance, UnitsSettings::DistanceUnitsFeet, FactMetaData::_metersToFeet, FactMetaData::_feetToMeters }, + { "alt m", "ft", FactMetaData::UnitAltitude, UnitsSettings::AltitudeUnitsFeet, FactMetaData::_metersToFeet, FactMetaData::_feetToMeters }, { "cm/px", "in/px", FactMetaData::UnitDistance, UnitsSettings::DistanceUnitsFeet, FactMetaData::_centimetersToInches, FactMetaData::_inchesToCentimeters }, - { "m^2", "km^2", FactMetaData::UnitArea, UnitsSettings::AreaUnitsSquareKilometers, FactMetaData::_squareMetersToSquareKilometers, FactMetaData::_squareKilometersToSquareMeters }, + { "m^2", "km\u00B2", FactMetaData::UnitArea, UnitsSettings::AreaUnitsSquareKilometers, FactMetaData::_squareMetersToSquareKilometers, FactMetaData::_squareKilometersToSquareMeters }, { "m^2", "ha", FactMetaData::UnitArea, UnitsSettings::AreaUnitsHectares, FactMetaData::_squareMetersToHectares, FactMetaData::_hectaresToSquareMeters }, - { "m^2", "ft^2", FactMetaData::UnitArea, UnitsSettings::AreaUnitsSquareFeet, FactMetaData::_squareMetersToSquareFeet, FactMetaData::_squareFeetToSquareMeters }, + { "m^2", "ft\u00B2", FactMetaData::UnitArea, UnitsSettings::AreaUnitsSquareFeet, FactMetaData::_squareMetersToSquareFeet, FactMetaData::_squareFeetToSquareMeters }, { "m^2", "ac", FactMetaData::UnitArea, UnitsSettings::AreaUnitsAcres, FactMetaData::_squareMetersToAcres, FactMetaData::_acresToSquareMeters }, - { "m^2", "mi^2", FactMetaData::UnitArea, UnitsSettings::AreaUnitsSquareMiles, FactMetaData::_squareMetersToSquareMiles, FactMetaData::_squareMilesToSquareMeters }, + { "m^2", "mi\u00B2", FactMetaData::UnitArea, UnitsSettings::AreaUnitsSquareMiles, FactMetaData::_squareMetersToSquareMiles, FactMetaData::_squareMilesToSquareMeters }, { "m/s", "ft/s", FactMetaData::UnitSpeed, UnitsSettings::SpeedUnitsFeetPerSecond, FactMetaData::_metersToFeet, FactMetaData::_feetToMeters }, { "m/s", "mph", FactMetaData::UnitSpeed, UnitsSettings::SpeedUnitsMilesPerHour, FactMetaData::_metersPerSecondToMilesPerHour, FactMetaData::_milesPerHourToMetersPerSecond }, { "m/s", "km/h", FactMetaData::UnitSpeed, UnitsSettings::SpeedUnitsKilometersPerHour, FactMetaData::_metersPerSecondToKilometersPerHour, FactMetaData::_kilometersPerHourToMetersPerSecond }, { "m/s", "kn", FactMetaData::UnitSpeed, UnitsSettings::SpeedUnitsKnots, FactMetaData::_metersPerSecondToKnots, FactMetaData::_knotsToMetersPerSecond }, { "C", "F", FactMetaData::UnitTemperature, UnitsSettings::TemperatureUnitsFarenheit, FactMetaData::_celsiusToFarenheit, FactMetaData::_farenheitToCelsius }, + { "g", "g", FactMetaData::UnitWeight, UnitsSettings::WeightUnitsGrams, FactMetaData::_defaultTranslator, FactMetaData::_defaultTranslator }, + { "g", "kg", FactMetaData::UnitWeight, UnitsSettings::WeightUnitsKg, FactMetaData::_gramsToKilograms, FactMetaData::_kilogramsToGrams }, + { "g", "oz", FactMetaData::UnitWeight, UnitsSettings::WeightUnitsOz, FactMetaData::_gramsToOunces, FactMetaData::_ouncesToGrams }, + { "g", "lbs", FactMetaData::UnitWeight, UnitsSettings::WeightUnitsLbs, FactMetaData::_gramsToPunds, FactMetaData::_poundsToGrams }, }; const char* FactMetaData::_decimalPlacesJsonKey = "decimalPlaces"; @@ -790,6 +802,30 @@ QVariant FactMetaData::_farenheitToCelsius(const QVariant& farenheit) return QVariant((farenheit.toDouble() - 32) * (5.0 / 9.0)); } +QVariant FactMetaData::_kilogramsToGrams(const QVariant& kg) { + return QVariant(kg.toDouble() * 1000); +} + +QVariant FactMetaData::_ouncesToGrams(const QVariant& oz) { + return QVariant(oz.toDouble() * constants.ouncesToGrams); +} + +QVariant FactMetaData::_poundsToGrams(const QVariant& lbs) { + return QVariant(lbs.toDouble() * constants.poundsToGrams); +} + +QVariant FactMetaData::_gramsToKilograms(const QVariant& g) { + return QVariant(g.toDouble() / 1000); +} + +QVariant FactMetaData::_gramsToOunces(const QVariant& g) { + return QVariant(g.toDouble() / constants.ouncesToGrams); +} + +QVariant FactMetaData::_gramsToPunds(const QVariant& g) { + return QVariant(g.toDouble() / constants.poundsToGrams); +} + void FactMetaData::setRawUnits(const QString& rawUnits) { _rawUnits = rawUnits; @@ -895,6 +931,9 @@ void FactMetaData::_setAppSettingsTranslators(void) case UnitDistance: settingsUnits = settings->distanceUnits()->rawValue().toUInt(); break; + case UnitAltitude: + settingsUnits = settings->altitudeUnits()->rawValue().toUInt(); + break; case UnitSpeed: settingsUnits = settings->speedUnits()->rawValue().toUInt(); break; @@ -904,6 +943,9 @@ void FactMetaData::_setAppSettingsTranslators(void) case UnitTemperature: settingsUnits = settings->temperatureUnits()->rawValue().toUInt(); break; + case UnitWeight: + settingsUnits = settings->weightUnits()->rawValue().toUInt(); + break; default: break; } @@ -936,6 +978,44 @@ const FactMetaData::AppSettingsTranslation_s* FactMetaData::_findAppSettingsDist return nullptr; } +const FactMetaData::AppSettingsTranslation_s* FactMetaData::_findAppSettingsAltitudeUnitsTranslation(const QString& rawUnits) +{ + for (size_t i=0; irawUnits.toLower()) { + continue; + } + + uint settingsUnits = qgcApp()->toolbox()->settingsManager()->unitsSettings()->altitudeUnits()->rawValue().toUInt(); + + if (pAppSettingsTranslation->unitType == UnitAltitude + && pAppSettingsTranslation->unitOption == settingsUnits) { + return pAppSettingsTranslation; + } + } + return nullptr; +} + +const FactMetaData::AppSettingsTranslation_s* FactMetaData::_findAppSettingsWeightUnitsTranslation(const QString& rawUnits) +{ + for (size_t i=0; irawUnits.toLower()) { + continue; + } + + uint settingsUnits = qgcApp()->toolbox()->settingsManager()->unitsSettings()->weightUnits()->rawValue().toUInt(); + + if (pAppSettingsTranslation->unitType == UnitWeight + && pAppSettingsTranslation->unitOption == settingsUnits) { + return pAppSettingsTranslation; + } + } + return nullptr; +} + const FactMetaData::AppSettingsTranslation_s* FactMetaData::_findAppSettingsAreaUnitsTranslation(const QString& rawUnits) { for (size_t i=0; irawTranslator(meters); + } else { + return meters; + } +} + QVariant FactMetaData::appSettingsDistanceUnitsToMeters(const QVariant& distance) { const AppSettingsTranslation_s* pAppSettingsTranslation = _findAppSettingsDistanceUnitsTranslation("m"); @@ -976,6 +1066,16 @@ QVariant FactMetaData::appSettingsDistanceUnitsToMeters(const QVariant& distance } } +QVariant FactMetaData::appSettingsAltitudeUnitsToMeters(const QVariant& distance) +{ + const AppSettingsTranslation_s* pAppSettingsTranslation = _findAppSettingsAltitudeUnitsTranslation("alt m"); + if (pAppSettingsTranslation) { + return pAppSettingsTranslation->cookedTranslator(distance); + } else { + return distance; + } +} + QString FactMetaData::appSettingsDistanceUnitsString(void) { const AppSettingsTranslation_s* pAppSettingsTranslation = _findAppSettingsDistanceUnitsTranslation("m"); @@ -986,6 +1086,26 @@ QString FactMetaData::appSettingsDistanceUnitsString(void) } } +QString FactMetaData::appSettingsAltitudeUnitsString(void) +{ + const AppSettingsTranslation_s* pAppSettingsTranslation = _findAppSettingsAltitudeUnitsTranslation("alt m"); + if (pAppSettingsTranslation) { + return pAppSettingsTranslation->cookedUnits; + } else { + return QStringLiteral("m"); + } +} + +QString FactMetaData::appSettingsWeightUnitsString(void) +{ + const AppSettingsTranslation_s* pAppSettingsTranslation = _findAppSettingsWeightUnitsTranslation("g"); + if (pAppSettingsTranslation) { + return pAppSettingsTranslation->cookedUnits; + } else { + return QStringLiteral("g"); + } +} + QVariant FactMetaData::squareMetersToAppSettingsAreaUnits(const QVariant& squareMeters) { const AppSettingsTranslation_s* pAppSettingsTranslation = _findAppSettingsAreaUnitsTranslation("m^2"); @@ -1016,6 +1136,25 @@ QString FactMetaData::appSettingsAreaUnitsString(void) } } +QVariant FactMetaData::gramsToAppSettingsWeightUnits(const QVariant& grams) { + const AppSettingsTranslation_s* pAppSettingsTranslation = _findAppSettingsWeightUnitsTranslation("g"); + if (pAppSettingsTranslation) { + return pAppSettingsTranslation->rawTranslator(grams); + } else { + return grams; + } +} + +QVariant FactMetaData::appSettingsWeightUnitsToGrams(const QVariant& weight) { + const AppSettingsTranslation_s* pAppSettingsTranslation = _findAppSettingsWeightUnitsTranslation("g"); + if (pAppSettingsTranslation) { + return pAppSettingsTranslation->cookedTranslator(weight); + } else { + return weight; + } +} + + double FactMetaData::cookedIncrement(void) const { return _rawTranslator(this->rawIncrement()).toDouble(); diff --git a/src/FactSystem/FactMetaData.h b/src/FactSystem/FactMetaData.h index c6c1484c2a7af43e7e63495de0f61010595091d3..4842b06aa5b53df8c320f2f6580aea9e9d9ec1d9 100644 --- a/src/FactSystem/FactMetaData.h +++ b/src/FactSystem/FactMetaData.h @@ -69,6 +69,24 @@ public: /// Returns the string for distance units which has configued by user static QString appSettingsDistanceUnitsString(void); + /// Converts from meters to the user specified altitude unit + static QVariant metersToAppSettingsAltitudeUnits(const QVariant& meters); + + /// Converts from user specified altitude unit to meters + static QVariant appSettingsAltitudeUnitsToMeters(const QVariant& distance); + + /// Returns the string for altitude units which has configued by user + static QString appSettingsAltitudeUnitsString(void); + + /// Converts from grams to the user specified weight unit + static QVariant gramsToAppSettingsWeightUnits(const QVariant& meters); + + /// Converts from user specified weight unit to grams + static QVariant appSettingsWeightUnitsToGrams(const QVariant& distance); + + /// Returns the string for weight units which has configued by user + static QString appSettingsWeightUnitsString(void); + /// Converts from meters to the user specified distance unit static QVariant squareMetersToAppSettingsAreaUnits(const QVariant& squareMeters); @@ -209,12 +227,21 @@ private: static QVariant _inchesToCentimeters(const QVariant& inches); static QVariant _celsiusToFarenheit(const QVariant& celsius); static QVariant _farenheitToCelsius(const QVariant& farenheit); + static QVariant _kilogramsToGrams(const QVariant& kg); + static QVariant _ouncesToGrams(const QVariant& oz); + static QVariant _poundsToGrams(const QVariant& lbs); + static QVariant _gramsToKilograms(const QVariant& g); + static QVariant _gramsToOunces(const QVariant& g); + static QVariant _gramsToPunds(const QVariant& g); + enum UnitTypes { UnitDistance = 0, + UnitAltitude, UnitArea, UnitSpeed, - UnitTemperature + UnitTemperature, + UnitWeight }; struct AppSettingsTranslation_s { @@ -227,7 +254,9 @@ private: }; static const AppSettingsTranslation_s* _findAppSettingsDistanceUnitsTranslation(const QString& rawUnits); + static const AppSettingsTranslation_s* _findAppSettingsAltitudeUnitsTranslation(const QString& rawUnits); static const AppSettingsTranslation_s* _findAppSettingsAreaUnitsTranslation(const QString& rawUnits); + static const AppSettingsTranslation_s* _findAppSettingsWeightUnitsTranslation(const QString& rawUnits); static void _loadJsonDefines(const QJsonObject& jsonDefinesObject, QMap& defineMap); @@ -267,6 +296,8 @@ private: static const qreal milesToMeters; static const qreal feetToMeters; static const qreal inchesToCentimeters; + static const qreal ouncesToGrams; + static const qreal poundsToGrams; } constants; struct BuiltInTranslation_s { diff --git a/src/QmlControls/QGroundControlQmlGlobal.h b/src/QmlControls/QGroundControlQmlGlobal.h index a3ebcf4d6ffe8d4276e2008c1612dd0b957cf37e..6a8ab6668e98d6d3b73f84e5a20b8eeb11677ed7 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.h +++ b/src/QmlControls/QGroundControlQmlGlobal.h @@ -145,6 +145,22 @@ public: QString appSettingsDistanceUnitsString(void) const { return FactMetaData::appSettingsDistanceUnitsString(); } + /// Converts from meters to the user specified distance unit + Q_INVOKABLE QVariant metersToAppSettingsAltitudeUnits(const QVariant& meters) const { return FactMetaData::metersToAppSettingsAltitudeUnits(meters); } + + /// Converts from user specified distance unit to meters + Q_INVOKABLE QVariant appSettingsAltitudeUnitsToMeters(const QVariant& distance) const { return FactMetaData::appSettingsAltitudeUnitsToMeters(distance); } + + QString appSettingsAltitudeUnitsString(void) const { return FactMetaData::appSettingsAltitudeUnitsString(); } + + /// Converts from grams to the user specified weight unit + Q_INVOKABLE QVariant gramsToAppSettingsWeightUnits(const QVariant& meters) const { return FactMetaData::gramsToAppSettingsWeightUnits(meters); } + + /// Converts from user specified weight unit to grams + Q_INVOKABLE QVariant appSettingsWeightUnitsToGrams(const QVariant& distance) const { return FactMetaData::appSettingsWeightUnitsToGrams(distance); } + + QString appSettingsWeightUnitsString(void) const { return FactMetaData::appSettingsWeightUnitsString(); } + /// Converts from square meters to the user specified area unit Q_INVOKABLE QVariant squareMetersToAppSettingsAreaUnits(const QVariant& meters) const { return FactMetaData::squareMetersToAppSettingsAreaUnits(meters); } diff --git a/src/Settings/UnitsSettings.cc b/src/Settings/UnitsSettings.cc index 86ba175285a4aa602896e460d22db8567e88a533..a8963fef1cf0a6cb6dfd8a62a5c11a130c231753 100644 --- a/src/Settings/UnitsSettings.cc +++ b/src/Settings/UnitsSettings.cc @@ -47,6 +47,35 @@ DECLARE_SETTINGSFACT_NO_FUNC(UnitsSettings, distanceUnits) return _distanceUnitsFact; } +DECLARE_SETTINGSFACT_NO_FUNC(UnitsSettings, altitudeUnits) +{ + if (!_altitudeUnitsFact) { + // Distance/Area/Speed units settings can't be loaded from json since it creates an infinite loop of meta data loading. + QStringList enumStrings; + QVariantList enumValues; + enumStrings << "Feet" << "Meters"; + enumValues << QVariant::fromValue(static_cast(DistanceUnitsFeet)) << QVariant::fromValue(static_cast(DistanceUnitsMeters)); + FactMetaData* metaData = new FactMetaData(FactMetaData::valueTypeUint32, this); + metaData->setName(altitudeUnitsName); + metaData->setShortDescription("Altitude units"); + metaData->setEnumInfo(enumStrings, enumValues); + AltitudeUnits defaultAltitudeUnit = AltitudeUnitsMeters; + switch(QLocale::system().measurementSystem()) { + case QLocale::MetricSystem: { + defaultAltitudeUnit = AltitudeUnitsMeters; + } break; + case QLocale::ImperialUSSystem: + case QLocale::ImperialUKSystem: + defaultAltitudeUnit = AltitudeUnitsFeet; + break; + } + metaData->setRawDefaultValue(defaultAltitudeUnit); + metaData->setQGCRebootRequired(true); + _altitudeUnitsFact = new SettingsFact(_settingsGroup, metaData, this); + } + return _altitudeUnitsFact; +} + DECLARE_SETTINGSFACT_NO_FUNC(UnitsSettings, areaUnits) { if (!_areaUnitsFact) { @@ -147,3 +176,36 @@ DECLARE_SETTINGSFACT_NO_FUNC(UnitsSettings, temperatureUnits) } return _temperatureUnitsFact; } + +DECLARE_SETTINGSFACT_NO_FUNC(UnitsSettings, weightUnits) +{ + if (!_weightUnitsFact) { + // Units settings can't be loaded from json since it creates an infinite loop of meta data loading. + QStringList enumStrings; + QVariantList enumValues; + enumStrings << "Grams" << "Kilograms" << "Ounces" << "Pounds"; + enumValues + << QVariant::fromValue(static_cast(WeightUnitsGrams)) + << QVariant::fromValue(static_cast(WeightUnitsKg)) + << QVariant::fromValue(static_cast(WeightUnitsOz)) + << QVariant::fromValue(static_cast(WeightUnitsLbs)); + FactMetaData* metaData = new FactMetaData(FactMetaData::valueTypeUint32, this); + metaData->setName(weightUnitsName); + metaData->setShortDescription(tr("Weight units")); + metaData->setEnumInfo(enumStrings, enumValues); + WeightUnits defaultWeightUnit = WeightUnitsGrams; + switch(QLocale::system().measurementSystem()) { + case QLocale::MetricSystem: + case QLocale::ImperialUKSystem: { + defaultWeightUnit = WeightUnitsGrams; + } break; + case QLocale::ImperialUSSystem: + defaultWeightUnit = WeightUnitsOz; + break; + } + metaData->setRawDefaultValue(defaultWeightUnit); + metaData->setQGCRebootRequired(true); + _weightUnitsFact = new SettingsFact(_settingsGroup, metaData, this); + } + return _weightUnitsFact; +} diff --git a/src/Settings/UnitsSettings.h b/src/Settings/UnitsSettings.h index dab67a32ac010b7e84fcaf89d7fd34efb482ce3c..d9a9340b662d441e5edcf9cb7d08d90cbcd8194c 100644 --- a/src/Settings/UnitsSettings.h +++ b/src/Settings/UnitsSettings.h @@ -24,6 +24,11 @@ public: DistanceUnitsMeters }; + enum AltitudeUnits { + AltitudeUnitsFeet = 0, + AltitudeUnitsMeters + }; + enum AreaUnits { AreaUnitsSquareFeet = 0, AreaUnitsSquareMeters, @@ -46,17 +51,28 @@ public: TemperatureUnitsFarenheit, }; + enum WeightUnits { + WeightUnitsGrams = 0, + WeightUnitsKg, + WeightUnitsOz, + WeightUnitsLbs + }; + Q_ENUM(DistanceUnits) Q_ENUM(AreaUnits) + Q_ENUM(AltitudeUnits) Q_ENUM(SpeedUnits) Q_ENUM(TemperatureUnits) + Q_ENUM(WeightUnits) DEFINE_SETTING_NAME_GROUP() DEFINE_SETTINGFACT(distanceUnits) + DEFINE_SETTINGFACT(altitudeUnits) DEFINE_SETTINGFACT(areaUnits) DEFINE_SETTINGFACT(speedUnits) DEFINE_SETTINGFACT(temperatureUnits) + DEFINE_SETTINGFACT(weightUnits) }; #endif