Newer
Older
/****************************************************************************
*
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "FactValueSliderListModel.h"
#include "QGCApplication.h"
#include "QGCCorePlugin.h"
#include <QQmlEngine>
static const char* kMissingMetadata = "Meta data pointer missing";
: QObject (parent)
, _componentId (-1)
, _rawValue (0)
, _type (FactMetaData::valueTypeInt32)
, _sendValueChangedSignals (true)
{
FactMetaData* metaData = new FactMetaData(_type, this);
setMetaData(metaData);
Fact::Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObject* parent)
: QObject (parent)
, _name (name)
, _componentId (componentId)
, _rawValue (0)
, _type (type)
, _sendValueChangedSignals (true)
FactMetaData* metaData = new FactMetaData(_type, this);
setMetaData(metaData);
Fact::Fact(const QString& settingsGroup, FactMetaData* metaData, QObject* parent)
: QObject(parent)
, _name (metaData->name())
, _componentId (0)
, _rawValue (0)
, _type (metaData->type())
, _sendValueChangedSignals (true)
, _deferredValueChangeSignal(false)
qgcApp()->toolbox()->corePlugin()->adjustSettingMetaData(settingsGroup, *metaData);
setMetaData(metaData, true /* setDefaultFromMetaData */);
Fact::Fact(const Fact& other, QObject* parent)
: QObject(parent)
{
*this = other;
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
connect(this, &Fact::_containerRawValueChanged, this, &Fact::_checkForRebootMessaging);
}
const Fact& Fact::operator=(const Fact& other)
{
_name = other._name;
_componentId = other._componentId;
_rawValue = other._rawValue;
_type = other._type;
_sendValueChangedSignals = other._sendValueChangedSignals;
_deferredValueChangeSignal = other._deferredValueChangeSignal;
_valueSliderModel = nullptr;
_ignoreQGCRebootRequired = other._ignoreQGCRebootRequired;
if (_metaData && other._metaData) {
*_metaData = *other._metaData;
} else {
void Fact::forceSetRawValue(const QVariant& value)
{
if (_metaData) {
QVariant typedValue;
QString errorString;
if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) {
//-- Must be in this order
emit _containerRawValueChanged(rawValue());
emit rawValueChanged(_rawValue);
qWarning() << kMissingMetadata << name();
if (_metaData) {
QVariant typedValue;
QString errorString;
if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) {
if (typedValue != _rawValue) {
_rawValue.setValue(typedValue);
//-- Must be in this order
emit _containerRawValueChanged(rawValue());
emit rawValueChanged(_rawValue);
qWarning() << kMissingMetadata << name();
{
if (_metaData) {
setRawValue(_metaData->cookedTranslator()(value));
} else {
qWarning() << kMissingMetadata << name();
return _metaData->enumStrings().indexOf(value);
}
qWarning() << kMissingMetadata << name();
return -1;
}
void Fact::setEnumStringValue(const QString& value)
{
int index = valueIndex(value);
if (index != -1) {
setCookedValue(_metaData->enumValues()[index]);
}
}
void Fact::setEnumIndex(int index)
{
if (_metaData) {
qWarning() << kMissingMetadata << name();
void Fact::_containerSetRawValue(const QVariant& value)
if(_rawValue != value) {
_rawValue = value;
_sendValueChangedSignal(cookedValue());
emit rawValueChanged(_rawValue);
}
// This always need to be signalled in order to support forceSetRawValue usage and waiting for vehicleUpdated signal
emit vehicleUpdated(_rawValue);
QString Fact::name(void) const
{
return _name;
}
int Fact::componentId(void) const
{
return _componentId;
}
if (_metaData) {
return _metaData->rawTranslator()(_rawValue);
} else {
qWarning() << kMissingMetadata << name();
{
if (_metaData) {
int enumIndex = this->enumIndex();
if (enumIndex >= 0 && enumIndex < _metaData->enumStrings().count()) {
return _metaData->enumStrings()[enumIndex];
}
} else {
qWarning() << kMissingMetadata << name();
static const double accuracy = 1.0 / 1000000.0;
//-- Only enums have an index
if(_metaData->enumValues().count()) {
int index = 0;
for (QVariant enumValue: _metaData->enumValues()) {
if (enumValue == rawValue()) {
//-- Float comparissons don't always work
if(type() == FactMetaData::valueTypeFloat || type() == FactMetaData::valueTypeDouble) {
double diff = fabs(enumValue.toDouble() - rawValue().toDouble());
if(diff < accuracy) {
return index;
}
}
index ++;
// Current value is not in list, add it manually
_metaData->addEnumInfo(tr("Unknown: %1").arg(rawValue().toString()), rawValue());
emit enumsChanged();
return index;
qWarning() << kMissingMetadata << name();
}
return -1;
}
QStringList Fact::enumStrings(void) const
{
if (_metaData) {
return _metaData->enumStrings();
} else {
qWarning() << kMissingMetadata << name();
return QStringList();
}
}
QVariantList Fact::enumValues(void) const
{
if (_metaData) {
return _metaData->enumValues();
} else {
qWarning() << kMissingMetadata << name();
void Fact::setEnumInfo(const QStringList& strings, const QVariantList& values)
{
if (_metaData) {
_metaData->setEnumInfo(strings, values);
qWarning() << kMissingMetadata << name();
QStringList Fact::bitmaskStrings(void) const
{
if (_metaData) {
return _metaData->bitmaskStrings();
} else {
qWarning() << kMissingMetadata << name();
return QStringList();
}
}
QVariantList Fact::bitmaskValues(void) const
{
if (_metaData) {
return _metaData->bitmaskValues();
} else {
qWarning() << kMissingMetadata << name();
QString Fact::_variantToString(const QVariant& variant, int decimalPlaces) const
QString valueString;
switch (type()) {
case FactMetaData::valueTypeFloat:
{
float fValue = variant.toFloat();
if (qIsNaN(fValue)) {
valueString = QStringLiteral("--.--");
} else {
valueString = QString("%1").arg(fValue, 0, 'f', decimalPlaces);
}
}
break;
case FactMetaData::valueTypeDouble:
{
double dValue = variant.toDouble();
if (qIsNaN(dValue)) {
valueString = QStringLiteral("--.--");
} else {
valueString = QString("%1").arg(dValue, 0, 'f', decimalPlaces);
case FactMetaData::valueTypeBool:
valueString = variant.toBool() ? tr("true") : tr("false");
break;
case FactMetaData::valueTypeElapsedTimeInSeconds:
{
double dValue = variant.toDouble();
if (qIsNaN(dValue)) {
valueString = QStringLiteral("--:--:--");
} else {
QTime time(0, 0, 0, 0);
time = time.addSecs(dValue);
valueString = time.toString(QStringLiteral("hh:mm:ss"));
}
}
break;
default:
valueString = variant.toString();
break;
QString Fact::rawValueStringFullPrecision(void) const
{
return _variantToString(rawValue(), 18);
}
QString Fact::rawValueString(void) const
{
return _variantToString(rawValue(), decimalPlaces());
}
QString Fact::cookedValueString(void) const
return _variantToString(cookedValue(), decimalPlaces());
QVariant Fact::rawDefaultValue(void) const
{
if (_metaData) {
if (!_metaData->defaultValueAvailable()) {
qDebug() << "Access to unavailable default value";
}
return _metaData->rawDefaultValue();
} else {
qWarning() << kMissingMetadata << name();
return QVariant(0);
}
}
QVariant Fact::cookedDefaultValue(void) const
if (_metaData) {
if (!_metaData->defaultValueAvailable()) {
qDebug() << "Access to unavailable default value";
}
return _metaData->cookedDefaultValue();
qWarning() << kMissingMetadata << name();
QString Fact::cookedDefaultValueString(void) const
return _variantToString(cookedDefaultValue(), decimalPlaces());
FactMetaData::ValueType_t Fact::type(void) const
QString Fact::shortDescription(void) const
if (_metaData) {
return _metaData->shortDescription();
} else {
qWarning() << kMissingMetadata << name();
QString Fact::longDescription(void) const
if (_metaData) {
return _metaData->longDescription();
} else {
qWarning() << kMissingMetadata << name();
QString Fact::rawUnits(void) const
{
if (_metaData) {
return _metaData->rawUnits();
} else {
qWarning() << kMissingMetadata << name();
return QString();
}
}
QString Fact::cookedUnits(void) const
return _metaData->cookedUnits();
qWarning() << kMissingMetadata << name();
QVariant Fact::rawMin(void) const
return _metaData->rawMin();
qWarning() << kMissingMetadata << name();
QVariant Fact::cookedMin(void) const
if (_metaData) {
return _metaData->cookedMin();
} else {
qWarning() << kMissingMetadata << name();
QString Fact::cookedMinString(void) const
{
return _variantToString(cookedMin(), decimalPlaces());
}
QVariant Fact::rawMax(void) const
return _metaData->rawMax();
qWarning() << kMissingMetadata << name();
QVariant Fact::cookedMax(void) const
if (_metaData) {
return _metaData->cookedMax();
} else {
qWarning() << kMissingMetadata << name();
return QVariant(0);
}
}
QString Fact::cookedMaxString(void) const
{
return _variantToString(cookedMax(), decimalPlaces());
bool Fact::minIsDefaultForType(void) const
{
if (_metaData) {
return _metaData->minIsDefaultForType();
} else {
qWarning() << kMissingMetadata << name();
bool Fact::maxIsDefaultForType(void) const
{
if (_metaData) {
return _metaData->maxIsDefaultForType();
} else {
qWarning() << kMissingMetadata << name();
int Fact::decimalPlaces(void) const
{
if (_metaData) {
return _metaData->decimalPlaces();
} else {
qWarning() << kMissingMetadata << name();
QString Fact::category(void) const
{
if (_metaData) {
return _metaData->category();
} else {
qWarning() << kMissingMetadata << name();
return QString();
}
}
QString Fact::group(void) const
if (_metaData) {
return _metaData->group();
} else {
qWarning() << kMissingMetadata << name();
void Fact::setMetaData(FactMetaData* metaData, bool setDefaultFromMetaData)
if (setDefaultFromMetaData) {
setRawValue(rawDefaultValue());
}
bool Fact::valueEqualsDefault(void) const
if (_metaData) {
if (_metaData->defaultValueAvailable()) {
return _metaData->rawDefaultValue() == rawValue();
qWarning() << kMissingMetadata << name();
bool Fact::defaultValueAvailable(void) const
if (_metaData) {
return _metaData->defaultValueAvailable();
} else {
qWarning() << kMissingMetadata << name();
QString Fact::validate(const QString& cookedValue, bool convertOnly)
{
if (_metaData) {
QVariant typedValue;
QString errorString;
_metaData->convertAndValidateCooked(cookedValue, convertOnly, typedValue, errorString);
qWarning() << kMissingMetadata << name();
return QString("Internal error: Meta data pointer missing");
}
}
QVariant Fact::clamp(const QString& cookedValue)
{
if (_metaData) {
QVariant typedValue;
if(_metaData->clampValue(cookedValue, typedValue)) {
return typedValue;
} else {
//-- If conversion failed, return current value
return rawValue();
}
} else {
qWarning() << kMissingMetadata << name();
}
return QVariant();
}
return _metaData->vehicleRebootRequired();
} else {
qWarning() << kMissingMetadata << name();
return false;
}
}
bool Fact::qgcRebootRequired(void) const
{
if (_ignoreQGCRebootRequired) {
return false;
} else if (_metaData) {
qWarning() << kMissingMetadata << name();
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
void Fact::setSendValueChangedSignals (bool sendValueChangedSignals)
{
if (sendValueChangedSignals != _sendValueChangedSignals) {
_sendValueChangedSignals = sendValueChangedSignals;
emit sendValueChangedSignalsChanged(_sendValueChangedSignals);
}
}
void Fact::_sendValueChangedSignal(QVariant value)
{
if (_sendValueChangedSignals) {
emit valueChanged(value);
_deferredValueChangeSignal = false;
} else {
_deferredValueChangeSignal = true;
}
}
void Fact::sendDeferredValueChangedSignal(void)
{
if (_deferredValueChangeSignal) {
_deferredValueChangeSignal = false;
emit valueChanged(cookedValue());
}
}
QString Fact::enumOrValueString(void)
{
if (_metaData) {
if (_metaData->enumStrings().count()) {
return enumStringValue();
} else {
return cookedValueString();
}
} else {
qWarning() << kMissingMetadata << name();
double Fact::rawIncrement(void) const
return _metaData->rawIncrement();
qWarning() << kMissingMetadata << name();
}
return std::numeric_limits<double>::quiet_NaN();
}
double Fact::cookedIncrement(void) const
{
if (_metaData) {
return _metaData->cookedIncrement();
} else {
qWarning() << kMissingMetadata << name();
}
return std::numeric_limits<double>::quiet_NaN();
}
bool Fact::hasControl(void) const
{
if (_metaData) {
return _metaData->hasControl();
} else {
qWarning() << kMissingMetadata << name();
bool Fact::readOnly(void) const
{
if (_metaData) {
return _metaData->readOnly();
} else {
qWarning() << kMissingMetadata << name();
bool Fact::writeOnly(void) const
{
if (_metaData) {
return _metaData->writeOnly();
} else {
qWarning() << kMissingMetadata << name();
return false;
}
}
bool Fact::volatileValue(void) const
{
if (_metaData) {
return _metaData->volatileValue();
} else {
qWarning() << kMissingMetadata << name();
return false;
}
}
FactValueSliderListModel* Fact::valueSliderModel(void)
{
if (!_valueSliderModel) {
_valueSliderModel = new FactValueSliderListModel(*this);
}
return _valueSliderModel;
}
if(qgcApp()) {
if (!qgcApp()->runningUnitTests()) {
if (vehicleRebootRequired()) {
qgcApp()->showAppMessage(tr("Change of parameter %1 requires a Vehicle reboot to take effect.").arg(name()));
} else if (qgcRebootRequired()) {
qgcApp()->showAppMessage(tr("Change of '%1' value requires restart of %2 to take effect.").arg(shortDescription()).arg(qgcApp()->applicationName()));