/*===================================================================== QGroundControl Open Source Ground Control Station (c) 2009 - 2014 QGROUNDCONTROL PROJECT This file is part of the QGROUNDCONTROL project QGROUNDCONTROL is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QGROUNDCONTROL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QGROUNDCONTROL. If not, see . ======================================================================*/ /// @file /// @brief Object which exposes a FactMetaData /// /// @author Don Gagne #include "FactMetaData.h" #include #include FactMetaData::FactMetaData(QObject* parent) : QObject(parent) , _type(valueTypeInt32) , _decimalPlaces(defaultDecimalPlaces) , _defaultValue(0) , _defaultValueAvailable(false) , _group("*Default Group") , _max(_maxForType()) , _maxIsDefaultForType(true) , _min(_minForType()) , _minIsDefaultForType(true) , _rawTranslator(defaultTranslator) , _cookedTranslator(defaultTranslator) { } FactMetaData::FactMetaData(ValueType_t type, QObject* parent) : QObject(parent) , _type(type) , _decimalPlaces(defaultDecimalPlaces) , _defaultValue(0) , _defaultValueAvailable(false) , _group("*Default Group") , _max(_maxForType()) , _maxIsDefaultForType(true) , _min(_minForType()) , _minIsDefaultForType(true) , _rawTranslator(defaultTranslator) , _cookedTranslator(defaultTranslator) { } FactMetaData::FactMetaData(const FactMetaData& other, QObject* parent) : QObject(parent) { *this = other; } const FactMetaData& FactMetaData::operator=(const FactMetaData& other) { _decimalPlaces = other._decimalPlaces; _defaultValue = other._defaultValue; _defaultValueAvailable = other._defaultValueAvailable; _enumStrings = other._enumStrings; _enumValues = other._enumValues; _group = other._group; _longDescription = other._longDescription; _max = other._max; _maxIsDefaultForType = other._maxIsDefaultForType; _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; } QVariant FactMetaData::defaultValue(void) const { if (_defaultValueAvailable) { return _defaultValue; } else { qWarning() << "Attempt to access unavailable default value"; return QVariant(0); } } void FactMetaData::setDefaultValue(const QVariant& defaultValue) { if (_min <= defaultValue && defaultValue <= _max) { _defaultValue = defaultValue; _defaultValueAvailable = true; } else { qWarning() << "Attempt to set default value which is outside min/max range"; } } void FactMetaData::setMin(const QVariant& min) { if (min > _minForType()) { _min = min; _minIsDefaultForType = false; } else { qWarning() << "Attempt to set min below allowable value for fact: " << name() << ", value attempted: " << min << ", type: " << type() << ", min for type: " << _minForType(); _min = _minForType(); } } void FactMetaData::setMax(const QVariant& max) { if (max > _maxForType()) { qWarning() << "Attempt to set max above allowable value"; _max = _maxForType(); } else { _max = max; _maxIsDefaultForType = false; } } QVariant FactMetaData::_minForType(void) const { switch (_type) { case valueTypeUint8: return QVariant(std::numeric_limits::min()); case valueTypeInt8: return QVariant(std::numeric_limits::min()); case valueTypeUint16: return QVariant(std::numeric_limits::min()); case valueTypeInt16: return QVariant(std::numeric_limits::min()); case valueTypeUint32: return QVariant(std::numeric_limits::min()); case valueTypeInt32: return QVariant(std::numeric_limits::min()); case valueTypeFloat: return QVariant(-std::numeric_limits::max()); case valueTypeDouble: return QVariant(-std::numeric_limits::max()); } // Make windows compiler happy, even switch is full cased return QVariant(); } QVariant FactMetaData::_maxForType(void) const { switch (_type) { case valueTypeUint8: return QVariant(std::numeric_limits::max()); case valueTypeInt8: return QVariant(std::numeric_limits::max()); case valueTypeUint16: return QVariant(std::numeric_limits::max()); case valueTypeInt16: return QVariant(std::numeric_limits::max()); case valueTypeUint32: return QVariant(std::numeric_limits::max()); case valueTypeInt32: return QVariant(std::numeric_limits::max()); case valueTypeFloat: return QVariant(std::numeric_limits::max()); case valueTypeDouble: return QVariant(std::numeric_limits::max()); } // Make windows compiler happy, even switch is full cased return QVariant(); } bool FactMetaData::convertAndValidate(const QVariant& value, bool convertOnly, QVariant& typedValue, QString& errorString) { bool convertOk = false; errorString.clear(); switch (type()) { case FactMetaData::valueTypeInt8: case FactMetaData::valueTypeInt16: case FactMetaData::valueTypeInt32: typedValue = QVariant(value.toInt(&convertOk)); if (!convertOnly && convertOk) { if (min() > typedValue || typedValue > max()) { errorString = QString("Value must be within %1 and %2").arg(min().toInt()).arg(max().toInt()); } } break; case FactMetaData::valueTypeUint8: case FactMetaData::valueTypeUint16: case FactMetaData::valueTypeUint32: typedValue = QVariant(value.toUInt(&convertOk)); if (!convertOnly && convertOk) { if (min() > typedValue || typedValue > max()) { errorString = QString("Value must be within %1 and %2").arg(min().toUInt()).arg(max().toUInt()); } } break; case FactMetaData::valueTypeFloat: typedValue = QVariant(value.toFloat(&convertOk)); if (!convertOnly && convertOk) { if (min() > typedValue || typedValue > max()) { errorString = QString("Value must be within %1 and %2").arg(min().toFloat()).arg(max().toFloat()); } } break; case FactMetaData::valueTypeDouble: typedValue = QVariant(value.toDouble(&convertOk)); if (!convertOnly && convertOk) { if (min() > typedValue || typedValue > max()) { errorString = QString("Value must be within %1 and %2").arg(min().toDouble()).arg(max().toDouble()); } } break; } if (!convertOk) { errorString += "Invalid number"; } 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; } void FactMetaData::addEnumInfo(const QString& name, const QVariant& value) { _enumStrings << name; _enumValues << value; }