diff --git a/src/FactSystem/Fact.cc b/src/FactSystem/Fact.cc index 59c62ecec2765eb622168adc8047c4bcf7a2ecd5..81c92061693f3c4f83a879c090446111bd004246 100644 --- a/src/FactSystem/Fact.cc +++ b/src/FactSystem/Fact.cc @@ -31,7 +31,7 @@ Fact::Fact(QObject* parent) : QObject(parent) , _componentId(-1) - , _value(0) + , _rawValue(0) , _type(FactMetaData::valueTypeInt32) , _metaData(NULL) { @@ -43,7 +43,7 @@ Fact::Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObjec : QObject(parent) , _name(name) , _componentId(componentId) - , _value(0) + , _rawValue(0) , _type(type) , _metaData(NULL) { @@ -61,7 +61,7 @@ const Fact& Fact::operator=(const Fact& other) { _name = other._name; _componentId = other._componentId; - _value = other._value; + _rawValue = other._rawValue; _type = other._type; if (_metaData && other._metaData) { @@ -80,26 +80,26 @@ void Fact::forceSetValue(const QVariant& value) QString errorString; if (_metaData->convertAndValidate(value, true /* convertOnly */, typedValue, errorString)) { - _value.setValue(typedValue); - emit valueChanged(_value); - emit _containerValueChanged(_value); + _rawValue.setValue(_metaData->cookedTranslator()(typedValue)); + emit valueChanged(typedValue); + emit _containerValueChanged(typedValue); } } else { qWarning() << "Meta data pointer missing"; } } -void Fact::setValue(const QVariant& value) +void Fact::setRawValue(const QVariant& value) { if (_metaData) { QVariant typedValue; QString errorString; if (_metaData->convertAndValidate(value, true /* convertOnly */, typedValue, errorString)) { - if (typedValue != _value) { - _value.setValue(typedValue); - emit valueChanged(_value); - emit _containerValueChanged(_value); + if (typedValue != _rawValue) { + _rawValue.setValue(typedValue); + emit valueChanged(this->value()); + emit _containerValueChanged(this->value()); } } } else { @@ -107,11 +107,41 @@ void Fact::setValue(const QVariant& value) } } +void Fact::setValue(const QVariant& value) +{ + if (_metaData) { + setRawValue(_metaData->cookedTranslator()(value)); + } else { + qWarning() << "Meta data pointer missing"; + } +} + +void Fact::setEnumStringValue(const QString& value) +{ + if (_metaData) { + int index = _metaData->enumStrings().indexOf(value); + if (index != -1) { + setValue(_metaData->enumValues()[index]); + } + } else { + qWarning() << "Meta data pointer missing"; + } +} + +void Fact::setEnumIndex(int index) +{ + if (_metaData) { + setValue(_metaData->enumValues()[index]); + } else { + qWarning() << "Meta data pointer missing"; + } +} + void Fact::_containerSetValue(const QVariant& value) { - _value = value; - emit valueChanged(_value); - emit vehicleUpdated(_value); + _rawValue = value; + emit valueChanged(_rawValue); + emit vehicleUpdated(_rawValue); } QString Fact::name(void) const @@ -126,7 +156,63 @@ int Fact::componentId(void) const QVariant Fact::value(void) const { - return _value; + if (_metaData) { + return _metaData->rawTranslator()(_rawValue); + } else { + qWarning() << "Meta data pointer missing"; + return _rawValue; + } +} + +QString Fact::enumStringValue(void) const +{ + if (_metaData) { + int enumIndex = this->enumIndex(); + if (enumIndex > 0 && enumIndex < _metaData->enumStrings().count()) { + return _metaData->enumStrings()[enumIndex]; + } + } else { + qWarning() << "Meta data pointer missing"; + } + + return QString(); +} + +int Fact::enumIndex(void) const +{ + if (_metaData) { + int index = 0; + foreach (QVariant enumValue, _metaData->enumValues()) { + if (enumValue == value()) { + return index; + } + index ++; + } + } else { + qWarning() << "Meta data pointer missing"; + } + + return -1; +} + +QStringList Fact::enumStrings(void) const +{ + if (_metaData) { + return _metaData->enumStrings(); + } else { + qWarning() << "Meta data pointer missing"; + return QStringList(); + } +} + +QVariantList Fact::enumValues(void) const +{ + if (_metaData) { + return _metaData->enumValues(); + } else { + qWarning() << "Meta data pointer missing"; + return QVariantList(); + } } QString Fact::_variantToString(const QVariant& variant) const @@ -279,6 +365,7 @@ QString Fact::group(void) const void Fact::setMetaData(FactMetaData* metaData) { _metaData = metaData; + emit valueChanged(value()); } bool Fact::valueEqualsDefault(void) const diff --git a/src/FactSystem/Fact.h b/src/FactSystem/Fact.h index 92c38e92918354a511585eff942227166108d66f..a1f2b6c5ffc20f86581cd52c6b752c53ec78789c 100644 --- a/src/FactSystem/Fact.h +++ b/src/FactSystem/Fact.h @@ -46,56 +46,67 @@ public: const Fact& operator=(const Fact& other); - Q_PROPERTY(int componentId READ componentId CONSTANT) - Q_PROPERTY(QString group READ group CONSTANT) - Q_PROPERTY(QString name READ name CONSTANT) - Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true) - Q_PROPERTY(QVariant valueString READ valueString NOTIFY valueChanged) - Q_PROPERTY(QString units READ units CONSTANT) - Q_PROPERTY(QVariant defaultValue READ defaultValue CONSTANT) - Q_PROPERTY(QString defaultValueString READ defaultValueString CONSTANT) - Q_PROPERTY(bool defaultValueAvailable READ defaultValueAvailable CONSTANT) - Q_PROPERTY(bool valueEqualsDefault READ valueEqualsDefault NOTIFY valueChanged) - Q_PROPERTY(FactMetaData::ValueType_t type READ type CONSTANT) - Q_PROPERTY(QString shortDescription READ shortDescription CONSTANT) - Q_PROPERTY(QString longDescription READ longDescription CONSTANT) - Q_PROPERTY(QVariant min READ min CONSTANT) - Q_PROPERTY(QString minString READ minString CONSTANT) - Q_PROPERTY(bool minIsDefaultForType READ minIsDefaultForType CONSTANT) - Q_PROPERTY(QVariant max READ max CONSTANT) - Q_PROPERTY(QString maxString READ maxString CONSTANT) - Q_PROPERTY(bool maxIsDefaultForType READ maxIsDefaultForType CONSTANT) - Q_PROPERTY(int decimalPlaces READ decimalPlaces CONSTANT) - + Q_PROPERTY(int componentId READ componentId CONSTANT) + Q_PROPERTY(int decimalPlaces READ decimalPlaces CONSTANT) + Q_PROPERTY(QVariant defaultValue READ defaultValue CONSTANT) + Q_PROPERTY(QString defaultValueString READ defaultValueString CONSTANT) + Q_PROPERTY(bool defaultValueAvailable READ defaultValueAvailable CONSTANT) + Q_PROPERTY(int enumIndex READ enumIndex WRITE setEnumIndex NOTIFY valueChanged) + Q_PROPERTY(QStringList enumStrings READ enumStrings CONSTANT) + Q_PROPERTY(QString enumStringValue READ enumStringValue WRITE setEnumStringValue NOTIFY valueChanged) + Q_PROPERTY(QVariantList enumValues READ enumValues CONSTANT) + Q_PROPERTY(QString group READ group CONSTANT) + Q_PROPERTY(QString longDescription READ longDescription CONSTANT) + Q_PROPERTY(QVariant max READ max CONSTANT) + Q_PROPERTY(QString maxString READ maxString CONSTANT) + Q_PROPERTY(bool maxIsDefaultForType READ maxIsDefaultForType CONSTANT) + Q_PROPERTY(QVariant min READ min CONSTANT) + Q_PROPERTY(QString minString READ minString CONSTANT) + Q_PROPERTY(bool minIsDefaultForType READ minIsDefaultForType CONSTANT) + Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(QString shortDescription READ shortDescription CONSTANT) + Q_PROPERTY(FactMetaData::ValueType_t type READ type CONSTANT) + Q_PROPERTY(QString units READ units CONSTANT) + Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged) + Q_PROPERTY(bool valueEqualsDefault READ valueEqualsDefault NOTIFY valueChanged) + Q_PROPERTY(QVariant valueString READ valueString NOTIFY valueChanged) + /// Convert and validate value /// @param convertOnly true: validate type conversion only, false: validate against meta data as well Q_INVOKABLE QString validate(const QString& value, bool convertOnly); - // Property system methods - - QString name(void) const; - int componentId(void) const; - QVariant value(void) const; - QString valueString(void) const; - QVariant defaultValue(void) const; - QString defaultValueString(void) const; - bool defaultValueAvailable(void) const; - bool valueEqualsDefault(void) const; - QString shortDescription(void) const; - QString longDescription(void) const; - QString units(void) const; - QVariant min(void) const; - QString minString(void) const; - bool minIsDefaultForType(void) const; - QVariant max(void) const; - QString maxString(void) const; - bool maxIsDefaultForType(void) const; - QString group(void) const; - int decimalPlaces(void) const; + int componentId (void) const; + int decimalPlaces (void) const; + QVariant defaultValue (void) const; + bool defaultValueAvailable (void) const; + QString defaultValueString (void) const; + int enumIndex (void) const; + QStringList enumStrings (void) const; + QString enumStringValue (void) const; + QVariantList enumValues (void) const; + QString group (void) const; + QString longDescription (void) const; + QVariant max (void) const; + QString maxString (void) const; + bool maxIsDefaultForType (void) const; + QVariant min (void) const; + QString minString (void) const; + bool minIsDefaultForType (void) const; + QString name (void) const; + QVariant rawValue (void) const { return _rawValue; } /// value prior to translation, careful + QString shortDescription (void) const; + FactMetaData::ValueType_t type (void) const; + QString units (void) const; + QVariant value (void) const; + QString valueString (void) const; + bool valueEqualsDefault (void) const; - FactMetaData::ValueType_t type(void) const; + void setRawValue (const QVariant& value); + void setValue (const QVariant& value); + void setEnumIndex (int index); + void setEnumStringValue (const QString& value); - void setValue(const QVariant& value); + // C++ methods /// Sets and sends new value to vehicle even if value is the same void forceSetValue(const QVariant& value); @@ -127,7 +138,7 @@ private: QString _name; int _componentId; - QVariant _value; + QVariant _rawValue; FactMetaData::ValueType_t _type; FactMetaData* _metaData; }; diff --git a/src/FactSystem/FactControls/FactComboBox.qml b/src/FactSystem/FactControls/FactComboBox.qml index 14368d032c61cc2c61bbb212427495e091eeb78c..2a6f12e22cd6cb984766da2fbb9283e847241966 100644 --- a/src/FactSystem/FactControls/FactComboBox.qml +++ b/src/FactSystem/FactControls/FactComboBox.qml @@ -8,6 +8,18 @@ import QGroundControl.Controls 1.0 QGCComboBox { property Fact fact: Fact { } - currentIndex: fact.value - onActivated: fact.value = index + property bool indexModel: true ///< true: model must be specifed, selected index is fact value, false: use enum meta data + + model: fact.enumStrings + + currentIndex: indexModel ? fact.value : fact.enumIndex + + onActivated: { + if (indexModel) { + fact.value = index + } else { + console.log("setting enumIndex", index) + fact.enumIndex = index + } + } } diff --git a/src/FactSystem/FactMetaData.cc b/src/FactSystem/FactMetaData.cc index 942d4e35af262a976c8c94ff2d0f4d6557b80e18..08dba2d0280363accbef398343d2bb05dd30aa95 100644 --- a/src/FactSystem/FactMetaData.cc +++ b/src/FactSystem/FactMetaData.cc @@ -34,30 +34,34 @@ FactMetaData::FactMetaData(QObject* parent) : QObject(parent) - , _group("*Default Group") , _type(valueTypeInt32) + , _decimalPlaces(defaultDecimalPlaces) , _defaultValue(0) , _defaultValueAvailable(false) - , _min(_minForType()) + , _group("*Default Group") , _max(_maxForType()) - , _minIsDefaultForType(true) , _maxIsDefaultForType(true) - , _decimalPlaces(defaultDecimalPlaces) + , _min(_minForType()) + , _minIsDefaultForType(true) + , _rawTranslator(defaultTranslator) + , _cookedTranslator(defaultTranslator) { } FactMetaData::FactMetaData(ValueType_t type, QObject* parent) : QObject(parent) - , _group("*Default Group") , _type(type) + , _decimalPlaces(defaultDecimalPlaces) , _defaultValue(0) , _defaultValueAvailable(false) - , _min(_minForType()) + , _group("*Default Group") , _max(_maxForType()) - , _minIsDefaultForType(true) , _maxIsDefaultForType(true) - , _decimalPlaces(defaultDecimalPlaces) + , _min(_minForType()) + , _minIsDefaultForType(true) + , _rawTranslator(defaultTranslator) + , _cookedTranslator(defaultTranslator) { } @@ -70,16 +74,24 @@ FactMetaData::FactMetaData(const FactMetaData& other, QObject* parent) const FactMetaData& FactMetaData::operator=(const FactMetaData& other) { - _group = other._group; - _type = other._type; + _decimalPlaces = other._decimalPlaces; _defaultValue = other._defaultValue; _defaultValueAvailable = other._defaultValueAvailable; - _min = other._min; + _enumStrings = other._enumStrings; + _enumValues = other._enumValues; + _group = other._group; + _longDescription = other._longDescription; _max = other._max; - _minIsDefaultForType = other._minIsDefaultForType; _maxIsDefaultForType = other._maxIsDefaultForType; - _decimalPlaces = other._decimalPlaces; - + _min = other._min; + _minIsDefaultForType = other._minIsDefaultForType; + _name = other._name; + _shortDescription = other._shortDescription; + _type = other._type; + _units = other._units; + _rawTranslator = other._rawTranslator; + _cookedTranslator = other._cookedTranslator; + return *this; } @@ -229,3 +241,20 @@ bool FactMetaData::convertAndValidate(const QVariant& value, bool convertOnly, Q return convertOk && errorString.isEmpty(); } + +void FactMetaData::setEnumInfo(const QStringList& strings, const QVariantList& values) +{ + if (strings.count() != values.count()) { + qWarning() << "Count mismatch strings:values" << strings.count() << values.count(); + return; + } + + _enumStrings = strings; + _enumValues = values; +} + +void FactMetaData::setTranslators(Translator rawTranslator, Translator cookedTranslator) +{ + _rawTranslator = rawTranslator; + _cookedTranslator = cookedTranslator; +} diff --git a/src/FactSystem/FactMetaData.h b/src/FactSystem/FactMetaData.h index 03c78d2f87642f7a213de8d455e6bc61198d6d1e..b276455ec0ba8cd90af714c654c58c95f29e126b 100644 --- a/src/FactSystem/FactMetaData.h +++ b/src/FactSystem/FactMetaData.h @@ -51,6 +51,8 @@ public: valueTypeFloat, valueTypeDouble } ValueType_t; + + typedef QVariant (*Translator)(const QVariant& from); FactMetaData(QObject* parent = NULL); FactMetaData(ValueType_t type, QObject* parent = NULL); @@ -58,32 +60,39 @@ public: const FactMetaData& operator=(const FactMetaData& other); - // Property accessors - QString name(void) const { return _name; } - QString group(void) const { return _group; } - ValueType_t type(void) const { return _type; } - QVariant defaultValue(void) const; - bool defaultValueAvailable(void) const { return _defaultValueAvailable; } - QString shortDescription(void) const { return _shortDescription; } - QString longDescription(void) const { return _longDescription;} - QString units(void) const { return _units; } - QVariant min(void) const { return _min; } - QVariant max(void) const { return _max; } - bool minIsDefaultForType(void) const { return _minIsDefaultForType; } - bool maxIsDefaultForType(void) const { return _maxIsDefaultForType; } - int decimalPlaces(void) const { return _decimalPlaces; } + int decimalPlaces (void) const { return _decimalPlaces; } + QVariant defaultValue (void) const; + bool defaultValueAvailable (void) const { return _defaultValueAvailable; } + QStringList enumStrings (void) const { return _enumStrings; } + QVariantList enumValues (void) const { return _enumValues; } + QString group (void) const { return _group; } + QString longDescription (void) const { return _longDescription;} + QVariant max (void) const { return _max; } + bool maxIsDefaultForType (void) const { return _maxIsDefaultForType; } + QVariant min (void) const { return _min; } + bool minIsDefaultForType (void) const { return _minIsDefaultForType; } + QString name (void) const { return _name; } + QString shortDescription (void) const { return _shortDescription; } + ValueType_t type (void) const { return _type; } + QString units (void) const { return _units; } + + Translator rawTranslator (void) const { return _rawTranslator; } + Translator cookedTranslator (void) const { return _cookedTranslator; } - // Property setters - void setName(const QString& name) { _name = name; } - void setGroup(const QString& group) { _group = group; } - void setDefaultValue(const QVariant& defaultValue); + void setDecimalPlaces (int decimalPlaces) { _decimalPlaces = decimalPlaces; } + void setDefaultValue (const QVariant& defaultValue); + void setEnumInfo (const QStringList& strings, const QVariantList& values); + void setGroup (const QString& group) { _group = group; } + void setLongDescription (const QString& longDescription) { _longDescription = longDescription;} + void setMax (const QVariant& max); + void setMin (const QVariant& max); + void setName (const QString& name) { _name = name; } void setShortDescription(const QString& shortDescription) { _shortDescription = shortDescription; } - void setLongDescription(const QString& longDescription) { _longDescription = longDescription;} - void setUnits(const QString& units) { _units = units; } - void setMin(const QVariant& max); - void setMax(const QVariant& max); - void setDecimalPlaces(int decimalPlaces) { _decimalPlaces = decimalPlaces; } - + void setUnits (const QString& units) { _units = units; } + + void setTranslators(Translator rawTranslator, Translator cookedTranslator); + static QVariant defaultTranslator(const QVariant& from) { return from; } + /// Converts the specified value, validating against meta data /// @param value Value to convert, can be string /// @param convertOnly true: convert to correct type only, do not validate against meta data @@ -98,19 +107,23 @@ private: QVariant _minForType(void) const; QVariant _maxForType(void) const; - QString _name; - QString _group; - ValueType_t _type; - QVariant _defaultValue; - bool _defaultValueAvailable; - QString _shortDescription; - QString _longDescription; - QString _units; - QVariant _min; - QVariant _max; - bool _minIsDefaultForType; - bool _maxIsDefaultForType; - int _decimalPlaces; + ValueType_t _type; // must be first for correct constructor init + int _decimalPlaces; + QVariant _defaultValue; + bool _defaultValueAvailable; + QStringList _enumStrings; + QVariantList _enumValues; + QString _group; + QString _longDescription; + QVariant _max; + bool _maxIsDefaultForType; + QVariant _min; + bool _minIsDefaultForType; + QString _name; + QString _shortDescription; + QString _units; + Translator _rawTranslator; + Translator _cookedTranslator; }; #endif