Fact.cc 18.2 KB
Newer Older
1 2 3 4 5 6 7 8 9
/****************************************************************************
 *
 *   (c) 2009-2016 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.
 *
 ****************************************************************************/

Don Gagne's avatar
Don Gagne committed
10
#include "Fact.h"
11
#include "FactValueSliderListModel.h"
Don Gagne's avatar
Don Gagne committed
12
#include "QGCMAVLink.h"
13 14
#include "QGCApplication.h"
#include "QGCCorePlugin.h"
Don Gagne's avatar
Don Gagne committed
15 16

#include <QtQml>
17
#include <QQmlEngine>
Don Gagne's avatar
Don Gagne committed
18

19 20
static const char* kMissingMetadata = "Meta data pointer missing";

Don Gagne's avatar
Don Gagne committed
21
Fact::Fact(QObject* parent)
22 23 24 25
    : QObject                   (parent)
    , _componentId              (-1)
    , _rawValue                 (0)
    , _type                     (FactMetaData::valueTypeInt32)
Gus Grubba's avatar
Gus Grubba committed
26
    , _metaData                 (nullptr)
27
    , _sendValueChangedSignals  (true)
Don Gagne's avatar
Don Gagne committed
28
    , _deferredValueChangeSignal(false)
Gus Grubba's avatar
Gus Grubba committed
29
    , _valueSliderModel         (nullptr)
Don Gagne's avatar
Don Gagne committed
30 31 32
{    
    FactMetaData* metaData = new FactMetaData(_type, this);
    setMetaData(metaData);
33

34
    _init();
Don Gagne's avatar
Don Gagne committed
35 36
}

Don Gagne's avatar
Don Gagne committed
37
Fact::Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObject* parent)
38 39 40 41 42
    : QObject                   (parent)
    , _name                     (name)
    , _componentId              (componentId)
    , _rawValue                 (0)
    , _type                     (type)
Gus Grubba's avatar
Gus Grubba committed
43
    , _metaData                 (nullptr)
44
    , _sendValueChangedSignals  (true)
Don Gagne's avatar
Don Gagne committed
45
    , _deferredValueChangeSignal(false)
Gus Grubba's avatar
Gus Grubba committed
46
    , _valueSliderModel         (nullptr)
Don Gagne's avatar
Don Gagne committed
47
{
Don Gagne's avatar
Don Gagne committed
48 49
    FactMetaData* metaData = new FactMetaData(_type, this);
    setMetaData(metaData);
50 51

    _init();
Don Gagne's avatar
Don Gagne committed
52
}
Don Gagne's avatar
Don Gagne committed
53

54
Fact::Fact(const QString& settingsGroup, FactMetaData* metaData, QObject* parent)
55 56 57 58 59
    : QObject(parent)
    , _name                     (metaData->name())
    , _componentId              (0)
    , _rawValue                 (0)
    , _type                     (metaData->type())
Gus Grubba's avatar
Gus Grubba committed
60
    , _metaData                 (nullptr)
61 62
    , _sendValueChangedSignals  (true)
    , _deferredValueChangeSignal(false)
Gus Grubba's avatar
Gus Grubba committed
63
    , _valueSliderModel         (nullptr)
64
{
65
    qgcApp()->toolbox()->corePlugin()->adjustSettingMetaData(settingsGroup, *metaData);
66
    setMetaData(metaData, true /* setDefaultFromMetaData */);
67 68

    _init();
69 70
}

Don Gagne's avatar
Don Gagne committed
71 72 73 74
Fact::Fact(const Fact& other, QObject* parent)
    : QObject(parent)
{
    *this = other;
75 76 77 78 79 80

    _init();
}

void Fact::_init(void)
{
81
    QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
82
    connect(this, &Fact::_containerRawValueChanged, this, &Fact::_checkForRebootMessaging);
Don Gagne's avatar
Don Gagne committed
83 84 85 86
}

const Fact& Fact::operator=(const Fact& other)
{
Don Gagne's avatar
Don Gagne committed
87 88 89 90 91 92
    _name                       = other._name;
    _componentId                = other._componentId;
    _rawValue                   = other._rawValue;
    _type                       = other._type;
    _sendValueChangedSignals    = other._sendValueChangedSignals;
    _deferredValueChangeSignal  = other._deferredValueChangeSignal;
Gus Grubba's avatar
Gus Grubba committed
93
    _valueSliderModel       = nullptr;
Don Gagne's avatar
Don Gagne committed
94 95 96
    if (_metaData && other._metaData) {
        *_metaData = *other._metaData;
    } else {
Gus Grubba's avatar
Gus Grubba committed
97
        _metaData = nullptr;
Don Gagne's avatar
Don Gagne committed
98 99 100
    }
    
    return *this;
Don Gagne's avatar
Don Gagne committed
101 102
}

Don Gagne's avatar
Don Gagne committed
103
void Fact::forceSetRawValue(const QVariant& value)
104 105 106 107 108
{
    if (_metaData) {
        QVariant    typedValue;
        QString     errorString;
        
109
        if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) {
Don Gagne's avatar
Don Gagne committed
110
            _rawValue.setValue(typedValue);
Don Gagne's avatar
Don Gagne committed
111
            _sendValueChangedSignal(cookedValue());
112 113
            //-- Must be in this order
            emit _containerRawValueChanged(rawValue());
114
            emit rawValueChanged(_rawValue);
115 116
        }
    } else {
117
        qWarning() << kMissingMetadata << name();
118 119 120
    }
}

Gus Grubba's avatar
Gus Grubba committed
121
void Fact::setRawValue(const QVariant& value)
Don Gagne's avatar
Don Gagne committed
122
{
Don Gagne's avatar
Don Gagne committed
123 124 125 126
    if (_metaData) {
        QVariant    typedValue;
        QString     errorString;
        
127
        if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) {
128 129
            if (typedValue != _rawValue) {
                _rawValue.setValue(typedValue);
Don Gagne's avatar
Don Gagne committed
130
                _sendValueChangedSignal(cookedValue());
131 132
                //-- Must be in this order
                emit _containerRawValueChanged(rawValue());
133
                emit rawValueChanged(_rawValue);
Don Gagne's avatar
Don Gagne committed
134 135 136
            }
        }
    } else {
137
        qWarning() << kMissingMetadata << name();
138
    }
Don Gagne's avatar
Don Gagne committed
139 140
}

Don Gagne's avatar
Don Gagne committed
141
void Fact::setCookedValue(const QVariant& value)
142 143 144 145
{
    if (_metaData) {
        setRawValue(_metaData->cookedTranslator()(value));
    } else {
146
        qWarning() << kMissingMetadata << name();
147 148 149
    }
}

Gus Grubba's avatar
Gus Grubba committed
150
int Fact::valueIndex(const QString& value)
151 152
{
    if (_metaData) {
Gus Grubba's avatar
Gus Grubba committed
153 154 155 156 157 158 159 160 161 162 163
        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]);
164 165 166 167 168 169
    }
}

void Fact::setEnumIndex(int index)
{
    if (_metaData) {
Don Gagne's avatar
Don Gagne committed
170
        setCookedValue(_metaData->enumValues()[index]);
171
    } else {
172
        qWarning() << kMissingMetadata << name();
173 174 175
    }
}

Don Gagne's avatar
Don Gagne committed
176
void Fact::_containerSetRawValue(const QVariant& value)
Don Gagne's avatar
Don Gagne committed
177
{
178 179 180 181 182
    if(_rawValue != value) {
        _rawValue = value;
        _sendValueChangedSignal(cookedValue());
        emit rawValueChanged(_rawValue);
    }
183 184 185

    // This always need to be signalled in order to support forceSetRawValue usage and waiting for vehicleUpdated signal
    emit vehicleUpdated(_rawValue);
Don Gagne's avatar
Don Gagne committed
186
}
187 188 189 190 191 192

QString Fact::name(void) const
{
    return _name;
}

193 194 195 196 197
int Fact::componentId(void) const
{
    return _componentId;
}

Don Gagne's avatar
Don Gagne committed
198
QVariant Fact::cookedValue(void) const
199
{
200 201 202
    if (_metaData) {
        return _metaData->rawTranslator()(_rawValue);
    } else {
203
        qWarning() << kMissingMetadata << name();
204 205 206 207
        return _rawValue;
    }
}

208
QString Fact::enumStringValue(void)
209 210 211
{
    if (_metaData) {
        int enumIndex = this->enumIndex();
Don Gagne's avatar
Don Gagne committed
212
        if (enumIndex >= 0 && enumIndex < _metaData->enumStrings().count()) {
213 214 215
            return _metaData->enumStrings()[enumIndex];
        }
    } else {
216
        qWarning() << kMissingMetadata << name();
217 218 219 220 221
    }

    return QString();
}

222
int Fact::enumIndex(void)
223
{
224
    static const double accuracy = 1.0 / 1000000.0;
225
    if (_metaData) {
226 227 228
        //-- Only enums have an index
        if(_metaData->enumValues().count()) {
            int index = 0;
229
            for (QVariant enumValue: _metaData->enumValues()) {
230
                if (enumValue == rawValue()) {
231 232
                    return index;
                }
233 234 235 236 237 238 239 240
                //-- 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 ++;
241
            }
242
            // Current value is not in list, add it manually
243
            _metaData->addEnumInfo(tr("Unknown: %1").arg(rawValue().toString()), rawValue());
244 245
            emit enumsChanged();
            return index;
246 247
        }
    } else {
248
        qWarning() << kMissingMetadata << name();
249 250 251 252 253 254 255 256 257
    }
    return -1;
}

QStringList Fact::enumStrings(void) const
{
    if (_metaData) {
        return _metaData->enumStrings();
    } else {
258
        qWarning() << kMissingMetadata << name();
259 260 261 262 263 264 265 266 267
        return QStringList();
    }
}

QVariantList Fact::enumValues(void) const
{
    if (_metaData) {
        return _metaData->enumValues();
    } else {
268
        qWarning() << kMissingMetadata << name();
269 270
        return QVariantList();
    }
271 272
}

273 274 275
void Fact::setEnumInfo(const QStringList& strings, const QVariantList& values)
{
    if (_metaData) {
276
        _metaData->setEnumInfo(strings, values);
277
    } else {
278
        qWarning() << kMissingMetadata << name();
279 280 281
    }
}

282 283 284 285 286
QStringList Fact::bitmaskStrings(void) const
{
    if (_metaData) {
        return _metaData->bitmaskStrings();
    } else {
287
        qWarning() << kMissingMetadata << name();
288 289 290 291 292 293 294 295 296
        return QStringList();
    }
}

QVariantList Fact::bitmaskValues(void) const
{
    if (_metaData) {
        return _metaData->bitmaskValues();
    } else {
297
        qWarning() << kMissingMetadata << name();
298 299 300 301
        return QVariantList();
    }
}

302
QString Fact::_variantToString(const QVariant& variant, int decimalPlaces) const
303
{
304 305 306
    QString valueString;

    switch (type()) {
Don Gagne's avatar
Don Gagne committed
307 308 309 310 311 312
    case FactMetaData::valueTypeFloat:
    {
        float fValue = variant.toFloat();
        if (qIsNaN(fValue)) {
            valueString = QStringLiteral("--.--");
        } else {
313
            valueString = QString("%1").arg(fValue, 0, 'f', decimalPlaces);
Don Gagne's avatar
Don Gagne committed
314 315 316 317 318 319 320 321 322
        }
    }
        break;
    case FactMetaData::valueTypeDouble:
    {
        double dValue = variant.toDouble();
        if (qIsNaN(dValue)) {
            valueString = QStringLiteral("--.--");
        } else {
323
            valueString = QString("%1").arg(dValue, 0, 'f', decimalPlaces);
Don Gagne's avatar
Don Gagne committed
324 325 326
        }
    }
        break;
Don Gagne's avatar
Don Gagne committed
327 328 329
    case FactMetaData::valueTypeBool:
        valueString = variant.toBool() ? tr("true") : tr("false");
        break;
330 331 332 333 334 335 336 337 338 339 340 341
    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;
Don Gagne's avatar
Don Gagne committed
342 343 344
    default:
        valueString = variant.toString();
        break;
345 346 347
    }

    return valueString;
348 349
}

350 351 352 353 354 355
QString Fact::rawValueStringFullPrecision(void) const
{
    return _variantToString(rawValue(), 18);
}


356 357
QString Fact::rawValueString(void) const
{
358
    return _variantToString(rawValue(), decimalPlaces());
359 360 361
}

QString Fact::cookedValueString(void) const
362
{
363
    return _variantToString(cookedValue(), decimalPlaces());
364 365
}

366 367 368 369 370 371 372 373
QVariant Fact::rawDefaultValue(void) const
{
    if (_metaData) {
        if (!_metaData->defaultValueAvailable()) {
            qDebug() << "Access to unavailable default value";
        }
        return _metaData->rawDefaultValue();
    } else {
374
        qWarning() << kMissingMetadata << name();
375 376 377 378 379
        return QVariant(0);
    }
}

QVariant Fact::cookedDefaultValue(void) const
380
{
Don Gagne's avatar
Don Gagne committed
381 382 383 384
    if (_metaData) {
        if (!_metaData->defaultValueAvailable()) {
            qDebug() << "Access to unavailable default value";
        }
385
        return _metaData->cookedDefaultValue();
Don Gagne's avatar
Don Gagne committed
386
    } else {
387
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
388
        return QVariant(0);
389
    }
390 391
}

392
QString Fact::cookedDefaultValueString(void) const
393
{
394
    return _variantToString(cookedDefaultValue(), decimalPlaces());
395 396
}

397
FactMetaData::ValueType_t Fact::type(void) const
398
{
399
    return _type;
400 401
}

402
QString Fact::shortDescription(void) const
403
{
Don Gagne's avatar
Don Gagne committed
404 405 406
    if (_metaData) {
        return _metaData->shortDescription();
    } else {
407
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
408 409
        return QString();
    }
410 411
}

412
QString Fact::longDescription(void) const
413
{
Don Gagne's avatar
Don Gagne committed
414 415 416
    if (_metaData) {
        return _metaData->longDescription();
    } else {
417
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
418 419
        return QString();
    }
420 421
}

422 423 424 425 426
QString Fact::rawUnits(void) const
{
    if (_metaData) {
        return _metaData->rawUnits();
    } else {
427
        qWarning() << kMissingMetadata << name();
428 429 430 431 432
        return QString();
    }
}

QString Fact::cookedUnits(void) const
433
{
Don Gagne's avatar
Don Gagne committed
434
    if (_metaData) {
435
        return _metaData->cookedUnits();
Don Gagne's avatar
Don Gagne committed
436
    } else {
437
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
438 439
        return QString();
    }
440 441
}

442
QVariant Fact::rawMin(void) const
443
{
Don Gagne's avatar
Don Gagne committed
444
    if (_metaData) {
445
        return _metaData->rawMin();
Don Gagne's avatar
Don Gagne committed
446
    } else {
447
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
448 449
        return QVariant(0);
    }
450 451
}

452
QVariant Fact::cookedMin(void) const
453
{
454 455 456
    if (_metaData) {
        return _metaData->cookedMin();
    } else {
457
        qWarning() << kMissingMetadata << name();
458 459
        return QVariant(0);
    }
460 461
}

462 463
QString Fact::cookedMinString(void) const
{
464
    return _variantToString(cookedMin(), decimalPlaces());
465 466 467
}

QVariant Fact::rawMax(void) const
468
{
Don Gagne's avatar
Don Gagne committed
469
    if (_metaData) {
470
        return _metaData->rawMax();
Don Gagne's avatar
Don Gagne committed
471
    } else {
472
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
473 474 475 476
        return QVariant(0);
    }
}

477
QVariant Fact::cookedMax(void) const
478
{
479 480 481
    if (_metaData) {
        return _metaData->cookedMax();
    } else {
482
        qWarning() << kMissingMetadata << name();
483 484 485 486 487 488
        return QVariant(0);
    }
}

QString Fact::cookedMaxString(void) const
{
489
    return _variantToString(cookedMax(), decimalPlaces());
490 491
}

492
bool Fact::minIsDefaultForType(void) const
Don Gagne's avatar
Don Gagne committed
493 494 495 496
{
    if (_metaData) {
        return _metaData->minIsDefaultForType();
    } else {
497
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
498 499 500 501
        return false;
    }
}

502
bool Fact::maxIsDefaultForType(void) const
Don Gagne's avatar
Don Gagne committed
503 504 505 506
{
    if (_metaData) {
        return _metaData->maxIsDefaultForType();
    } else {
507
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
508 509
        return false;
    }
510 511
}

512 513 514 515 516
int Fact::decimalPlaces(void) const
{
    if (_metaData) {
        return _metaData->decimalPlaces();
    } else {
517
        qWarning() << kMissingMetadata << name();
518 519 520 521
        return FactMetaData::defaultDecimalPlaces;
    }
}

522 523 524 525 526 527 528 529 530 531
QString Fact::category(void) const
{
    if (_metaData) {
        return _metaData->category();
    } else {
        qWarning() << kMissingMetadata << name();
        return QString();
    }
}

532
QString Fact::group(void) const
533
{
Don Gagne's avatar
Don Gagne committed
534 535 536
    if (_metaData) {
        return _metaData->group();
    } else {
537
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
538 539
        return QString();
    }
540 541
}

542
void Fact::setMetaData(FactMetaData* metaData, bool setDefaultFromMetaData)
543 544
{
    _metaData = metaData;
545 546 547
    if (setDefaultFromMetaData) {
        setRawValue(rawDefaultValue());
    }
Don Gagne's avatar
Don Gagne committed
548
    emit valueChanged(cookedValue());
549
}
550

551
bool Fact::valueEqualsDefault(void) const
552
{
Don Gagne's avatar
Don Gagne committed
553 554
    if (_metaData) {
        if (_metaData->defaultValueAvailable()) {
555
            return _metaData->rawDefaultValue() == rawValue();
Don Gagne's avatar
Don Gagne committed
556 557 558
        } else {
            return false;
        }
559
    } else {
560
        qWarning() << kMissingMetadata << name();
561 562 563 564
        return false;
    }
}

565
bool Fact::defaultValueAvailable(void) const
566
{
Don Gagne's avatar
Don Gagne committed
567 568 569
    if (_metaData) {
        return _metaData->defaultValueAvailable();
    } else {
570
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
571 572 573 574
        return false;
    }
}

575
QString Fact::validate(const QString& cookedValue, bool convertOnly)
Don Gagne's avatar
Don Gagne committed
576 577 578 579 580
{
    if (_metaData) {
        QVariant    typedValue;
        QString     errorString;
        
581
        _metaData->convertAndValidateCooked(cookedValue, convertOnly, typedValue, errorString);
Don Gagne's avatar
Don Gagne committed
582 583 584
        
        return errorString;
    } else {
585
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
586 587 588
        return QString("Internal error: Meta data pointer missing");
    }
}
589

590 591 592 593 594 595 596 597 598 599 600
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 {
601
        qWarning() << kMissingMetadata << name();
602 603 604 605
    }
    return QVariant();
}

606
bool Fact::vehicleRebootRequired(void) const
607 608
{
    if (_metaData) {
609 610 611 612 613 614 615 616 617 618 619
        return _metaData->vehicleRebootRequired();
    } else {
        qWarning() << kMissingMetadata << name();
        return false;
    }
}

bool Fact::qgcRebootRequired(void) const
{
    if (_metaData) {
        return _metaData->qgcRebootRequired();
620
    } else {
621
        qWarning() << kMissingMetadata << name();
622 623 624
        return false;
    }
}
Don Gagne's avatar
Don Gagne committed
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650

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());
    }
}
651 652 653 654 655 656 657 658 659 660

QString Fact::enumOrValueString(void)
{
    if (_metaData) {
        if (_metaData->enumStrings().count()) {
            return enumStringValue();
        } else {
            return cookedValueString();
        }
    } else {
661
        qWarning() << kMissingMetadata << name();
662 663 664
    }
    return QString();
}
Don Gagne's avatar
Don Gagne committed
665

666
double Fact::rawIncrement(void) const
Don Gagne's avatar
Don Gagne committed
667 668
{
    if (_metaData) {
669
        return _metaData->rawIncrement();
Don Gagne's avatar
Don Gagne committed
670
    } else {
671
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
672 673 674
    }
    return std::numeric_limits<double>::quiet_NaN();
}
675

676 677 678 679 680 681 682 683 684 685
double Fact::cookedIncrement(void) const
{
    if (_metaData) {
        return _metaData->cookedIncrement();
    } else {
        qWarning() << kMissingMetadata << name();
    }
    return std::numeric_limits<double>::quiet_NaN();
}

686 687 688 689 690
bool Fact::hasControl(void) const
{
    if (_metaData) {
        return _metaData->hasControl();
    } else {
691
        qWarning() << kMissingMetadata << name();
692 693 694
        return false;
    }
}
695 696 697 698 699 700

bool Fact::readOnly(void) const
{
    if (_metaData) {
        return _metaData->readOnly();
    } else {
701
        qWarning() << kMissingMetadata << name();
702 703 704
        return false;
    }
}
705

706 707 708 709 710 711 712 713 714 715
bool Fact::writeOnly(void) const
{
    if (_metaData) {
        return _metaData->writeOnly();
    } else {
        qWarning() << kMissingMetadata << name();
        return false;
    }
}

716 717 718 719 720 721 722 723 724
bool Fact::volatileValue(void) const
{
    if (_metaData) {
        return _metaData->volatileValue();
    } else {
        qWarning() << kMissingMetadata << name();
        return false;
    }
}
725 726 727 728 729 730 731 732

FactValueSliderListModel* Fact::valueSliderModel(void)
{
    if (!_valueSliderModel) {
        _valueSliderModel = new FactValueSliderListModel(*this);
    }
    return _valueSliderModel;
}
733 734 735

void Fact::_checkForRebootMessaging(void)
{
736 737 738 739 740 741 742
    if(qgcApp()) {
        if (!qgcApp()->runningUnitTests()) {
            if (vehicleRebootRequired()) {
                qgcApp()->showMessage(tr("Change of parameter %1 requires a Vehicle reboot to take effect.").arg(name()));
            } else if (qgcRebootRequired()) {
                qgcApp()->showMessage(tr("Change of '%1' value requires restart of %2 to take effect.").arg(shortDescription()).arg(qgcApp()->applicationName()));
            }
743 744 745
        }
    }
}