Fact.cc 18.5 KB
Newer Older
1
2
/****************************************************************************
 *
Gus Grubba's avatar
Gus Grubba committed
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4
5
6
7
8
9
 *
 * 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

Gus Grubba's avatar
Gus Grubba committed
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)
DonLakeFlyer's avatar
   
DonLakeFlyer committed
30
    , _ignoreQGCRebootRequired  (false)
Don Gagne's avatar
Don Gagne committed
31
32
33
{    
    FactMetaData* metaData = new FactMetaData(_type, this);
    setMetaData(metaData);
34

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

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

    _init();
Don Gagne's avatar
Don Gagne committed
54
}
Don Gagne's avatar
Don Gagne committed
55

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

    _init();
72
73
}

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

    _init();
}

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

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

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

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

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

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

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

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

    // 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
190
}
Don Gagne's avatar
Don Gagne committed
191
192
193
194
195
196

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

197
198
199
200
201
int Fact::componentId(void) const
{
    return _componentId;
}

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

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

    return QString();
}

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

QStringList Fact::enumStrings(void) const
{
    if (_metaData) {
        return _metaData->enumStrings();
    } else {
262
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
263
264
265
266
267
268
269
270
271
        return QStringList();
    }
}

QVariantList Fact::enumValues(void) const
{
    if (_metaData) {
        return _metaData->enumValues();
    } else {
272
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
273
274
        return QVariantList();
    }
Don Gagne's avatar
Don Gagne committed
275
276
}

Gus Grubba's avatar
Gus Grubba committed
277
278
279
void Fact::setEnumInfo(const QStringList& strings, const QVariantList& values)
{
    if (_metaData) {
280
        _metaData->setEnumInfo(strings, values);
Gus Grubba's avatar
Gus Grubba committed
281
    } else {
282
        qWarning() << kMissingMetadata << name();
Gus Grubba's avatar
Gus Grubba committed
283
284
285
    }
}

Don Gagne's avatar
Don Gagne committed
286
287
288
289
290
QStringList Fact::bitmaskStrings(void) const
{
    if (_metaData) {
        return _metaData->bitmaskStrings();
    } else {
291
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
292
293
294
295
296
297
298
299
300
        return QStringList();
    }
}

QVariantList Fact::bitmaskValues(void) const
{
    if (_metaData) {
        return _metaData->bitmaskValues();
    } else {
301
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
302
303
304
305
        return QVariantList();
    }
}

306
QString Fact::_variantToString(const QVariant& variant, int decimalPlaces) const
Don Gagne's avatar
Don Gagne committed
307
{
308
309
310
    QString valueString;

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

    return valueString;
Don Gagne's avatar
Don Gagne committed
352
353
}

354
355
356
357
358
359
QString Fact::rawValueStringFullPrecision(void) const
{
    return _variantToString(rawValue(), 18);
}


360
361
QString Fact::rawValueString(void) const
{
362
    return _variantToString(rawValue(), decimalPlaces());
363
364
365
}

QString Fact::cookedValueString(void) const
366
{
367
    return _variantToString(cookedValue(), decimalPlaces());
368
369
}

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

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

396
QString Fact::cookedDefaultValueString(void) const
397
{
398
    return _variantToString(cookedDefaultValue(), decimalPlaces());
399
400
}

401
FactMetaData::ValueType_t Fact::type(void) const
Don Gagne's avatar
Don Gagne committed
402
{
403
    return _type;
Don Gagne's avatar
Don Gagne committed
404
405
}

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

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

426
427
428
429
430
QString Fact::rawUnits(void) const
{
    if (_metaData) {
        return _metaData->rawUnits();
    } else {
431
        qWarning() << kMissingMetadata << name();
432
433
434
435
436
        return QString();
    }
}

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

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

456
QVariant Fact::cookedMin(void) const
457
{
458
459
460
    if (_metaData) {
        return _metaData->cookedMin();
    } else {
461
        qWarning() << kMissingMetadata << name();
462
463
        return QVariant(0);
    }
464
465
}

466
467
QString Fact::cookedMinString(void) const
{
468
    return _variantToString(cookedMin(), decimalPlaces());
469
470
471
}

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

481
QVariant Fact::cookedMax(void) const
482
{
483
484
485
    if (_metaData) {
        return _metaData->cookedMax();
    } else {
486
        qWarning() << kMissingMetadata << name();
487
488
489
490
491
492
        return QVariant(0);
    }
}

QString Fact::cookedMaxString(void) const
{
493
    return _variantToString(cookedMax(), decimalPlaces());
494
495
}

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

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

516
517
518
519
520
int Fact::decimalPlaces(void) const
{
    if (_metaData) {
        return _metaData->decimalPlaces();
    } else {
521
        qWarning() << kMissingMetadata << name();
DonLakeFlyer's avatar
   
DonLakeFlyer committed
522
        return FactMetaData::kDefaultDecimalPlaces;
523
524
525
    }
}

526
527
528
529
530
531
532
533
534
535
QString Fact::category(void) const
{
    if (_metaData) {
        return _metaData->category();
    } else {
        qWarning() << kMissingMetadata << name();
        return QString();
    }
}

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

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

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

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

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

594
595
596
597
598
599
600
601
602
603
604
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 {
605
        qWarning() << kMissingMetadata << name();
606
607
608
609
    }
    return QVariant();
}

Don Gagne's avatar
   
Don Gagne committed
610
bool Fact::vehicleRebootRequired(void) const
Don Gagne's avatar
Don Gagne committed
611
612
{
    if (_metaData) {
Don Gagne's avatar
   
Don Gagne committed
613
614
615
616
617
618
619
620
621
        return _metaData->vehicleRebootRequired();
    } else {
        qWarning() << kMissingMetadata << name();
        return false;
    }
}

bool Fact::qgcRebootRequired(void) const
{
DonLakeFlyer's avatar
   
DonLakeFlyer committed
622
623
624
    if (_ignoreQGCRebootRequired) {
        return false;
    } else if (_metaData) {
Don Gagne's avatar
   
Don Gagne committed
625
        return _metaData->qgcRebootRequired();
Don Gagne's avatar
Don Gagne committed
626
    } else {
627
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
628
629
630
        return false;
    }
}
Don Gagne's avatar
Don Gagne committed
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());
    }
}
657
658
659
660
661
662
663
664
665
666

QString Fact::enumOrValueString(void)
{
    if (_metaData) {
        if (_metaData->enumStrings().count()) {
            return enumStringValue();
        } else {
            return cookedValueString();
        }
    } else {
667
        qWarning() << kMissingMetadata << name();
668
669
670
    }
    return QString();
}
Don Gagne's avatar
Don Gagne committed
671

672
double Fact::rawIncrement(void) const
Don Gagne's avatar
Don Gagne committed
673
674
{
    if (_metaData) {
675
        return _metaData->rawIncrement();
Don Gagne's avatar
Don Gagne committed
676
    } else {
677
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
678
679
680
    }
    return std::numeric_limits<double>::quiet_NaN();
}
Gus Grubba's avatar
Gus Grubba committed
681

DonLakeFlyer's avatar
DonLakeFlyer committed
682
683
684
685
686
687
688
689
690
691
double Fact::cookedIncrement(void) const
{
    if (_metaData) {
        return _metaData->cookedIncrement();
    } else {
        qWarning() << kMissingMetadata << name();
    }
    return std::numeric_limits<double>::quiet_NaN();
}

Gus Grubba's avatar
Gus Grubba committed
692
693
694
695
696
bool Fact::hasControl(void) const
{
    if (_metaData) {
        return _metaData->hasControl();
    } else {
697
        qWarning() << kMissingMetadata << name();
Gus Grubba's avatar
Gus Grubba committed
698
699
700
        return false;
    }
}
701
702
703
704
705
706

bool Fact::readOnly(void) const
{
    if (_metaData) {
        return _metaData->readOnly();
    } else {
707
        qWarning() << kMissingMetadata << name();
708
709
710
        return false;
    }
}
711

712
713
714
715
716
717
718
719
720
721
bool Fact::writeOnly(void) const
{
    if (_metaData) {
        return _metaData->writeOnly();
    } else {
        qWarning() << kMissingMetadata << name();
        return false;
    }
}

722
723
724
725
726
727
728
729
730
bool Fact::volatileValue(void) const
{
    if (_metaData) {
        return _metaData->volatileValue();
    } else {
        qWarning() << kMissingMetadata << name();
        return false;
    }
}
731
732
733
734
735
736
737
738

FactValueSliderListModel* Fact::valueSliderModel(void)
{
    if (!_valueSliderModel) {
        _valueSliderModel = new FactValueSliderListModel(*this);
    }
    return _valueSliderModel;
}
Don Gagne's avatar
   
Don Gagne committed
739
740
741

void Fact::_checkForRebootMessaging(void)
{
742
743
744
    if(qgcApp()) {
        if (!qgcApp()->runningUnitTests()) {
            if (vehicleRebootRequired()) {
DoinLakeFlyer's avatar
   
DoinLakeFlyer committed
745
                qgcApp()->showAppMessage(tr("Change of parameter %1 requires a Vehicle reboot to take effect.").arg(name()));
746
            } else if (qgcRebootRequired()) {
DoinLakeFlyer's avatar
   
DoinLakeFlyer committed
747
                qgcApp()->showAppMessage(tr("Change of '%1' value requires restart of %2 to take effect.").arg(shortDescription()).arg(qgcApp()->applicationName()));
748
            }
Don Gagne's avatar
   
Don Gagne committed
749
750
751
        }
    }
}
DonLakeFlyer's avatar
   
DonLakeFlyer committed
752
753
754
755
756

void Fact::_setIgnoreQGCRebootRequired(bool ignore)
{
    _ignoreQGCRebootRequired = ignore;
}