Fact.cc 15.8 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"
Don Gagne's avatar
Don Gagne committed
11
#include "QGCMAVLink.h"
12 13
#include "QGCApplication.h"
#include "QGCCorePlugin.h"
Don Gagne's avatar
Don Gagne committed
14 15

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

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

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

32
    // Better safe than sorry on object ownership
33
    QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
Don Gagne's avatar
Don Gagne committed
34 35
}

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

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
Fact::Fact(FactMetaData* metaData, QObject* parent)
    : QObject(parent)
    , _name                     (metaData->name())
    , _componentId              (0)
    , _rawValue                 (0)
    , _type                     (metaData->type())
    , _metaData                 (NULL)
    , _sendValueChangedSignals  (true)
    , _deferredValueChangeSignal(false)
{
    // Allow core plugin a chance to override the default value
    qgcApp()->toolbox()->corePlugin()->adjustSettingMetaData(*metaData);
    setMetaData(metaData, true /* setDefaultFromMetaData */);
}

Don Gagne's avatar
Don Gagne committed
66 67 68 69
Fact::Fact(const Fact& other, QObject* parent)
    : QObject(parent)
{
    *this = other;
70
    QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
Don Gagne's avatar
Don Gagne committed
71 72 73 74
}

const Fact& Fact::operator=(const Fact& other)
{
Don Gagne's avatar
Don Gagne committed
75 76 77 78 79 80 81
    _name                       = other._name;
    _componentId                = other._componentId;
    _rawValue                   = other._rawValue;
    _type                       = other._type;
    _sendValueChangedSignals    = other._sendValueChangedSignals;
    _deferredValueChangeSignal  = other._deferredValueChangeSignal;

Don Gagne's avatar
Don Gagne committed
82 83 84 85 86 87 88
    if (_metaData && other._metaData) {
        *_metaData = *other._metaData;
    } else {
        _metaData = NULL;
    }
    
    return *this;
Don Gagne's avatar
Don Gagne committed
89 90
}

Don Gagne's avatar
Don Gagne committed
91
void Fact::forceSetRawValue(const QVariant& value)
92 93 94 95 96
{
    if (_metaData) {
        QVariant    typedValue;
        QString     errorString;
        
97
        if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) {
Don Gagne's avatar
Don Gagne committed
98
            _rawValue.setValue(typedValue);
Don Gagne's avatar
Don Gagne committed
99
            _sendValueChangedSignal(cookedValue());
100 101
            //-- Must be in this order
            emit _containerRawValueChanged(rawValue());
102
            emit rawValueChanged(_rawValue);
103 104
        }
    } else {
105
        qWarning() << kMissingMetadata << name();
106 107 108
    }
}

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

Don Gagne's avatar
Don Gagne committed
129
void Fact::setCookedValue(const QVariant& value)
130 131 132 133
{
    if (_metaData) {
        setRawValue(_metaData->cookedTranslator()(value));
    } else {
134
        qWarning() << kMissingMetadata << name();
135 136 137 138 139 140 141 142
    }
}

void Fact::setEnumStringValue(const QString& value)
{
    if (_metaData) {
        int index = _metaData->enumStrings().indexOf(value);
        if (index != -1) {
Don Gagne's avatar
Don Gagne committed
143
            setCookedValue(_metaData->enumValues()[index]);
144 145
        }
    } else {
146
        qWarning() << kMissingMetadata << name();
147 148 149 150 151 152
    }
}

void Fact::setEnumIndex(int index)
{
    if (_metaData) {
Don Gagne's avatar
Don Gagne committed
153
        setCookedValue(_metaData->enumValues()[index]);
154
    } else {
155
        qWarning() << kMissingMetadata << name();
156 157 158
    }
}

Don Gagne's avatar
Don Gagne committed
159
void Fact::_containerSetRawValue(const QVariant& value)
Don Gagne's avatar
Don Gagne committed
160
{
161 162 163 164 165 166
    if(_rawValue != value) {
        _rawValue = value;
        _sendValueChangedSignal(cookedValue());
        emit vehicleUpdated(_rawValue);
        emit rawValueChanged(_rawValue);
    }
Don Gagne's avatar
Don Gagne committed
167
}
168 169 170 171 172 173

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

174 175 176 177 178
int Fact::componentId(void) const
{
    return _componentId;
}

Don Gagne's avatar
Don Gagne committed
179
QVariant Fact::cookedValue(void) const
180
{
181 182 183
    if (_metaData) {
        return _metaData->rawTranslator()(_rawValue);
    } else {
184
        qWarning() << kMissingMetadata << name();
185 186 187 188
        return _rawValue;
    }
}

189
QString Fact::enumStringValue(void)
190 191 192
{
    if (_metaData) {
        int enumIndex = this->enumIndex();
Don Gagne's avatar
Don Gagne committed
193
        if (enumIndex >= 0 && enumIndex < _metaData->enumStrings().count()) {
194 195 196
            return _metaData->enumStrings()[enumIndex];
        }
    } else {
197
        qWarning() << kMissingMetadata << name();
198 199 200 201 202
    }

    return QString();
}

203
int Fact::enumIndex(void)
204
{
205
    static const double accuracy = 1.0 / 1000000.0;
206
    if (_metaData) {
207 208 209 210 211
        //-- Only enums have an index
        if(_metaData->enumValues().count()) {
            int index = 0;
            foreach (QVariant enumValue, _metaData->enumValues()) {
                if (enumValue == rawValue()) {
212 213
                    return index;
                }
214 215 216 217 218 219 220 221
                //-- 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 ++;
222
            }
223
            // Current value is not in list, add it manually
224
            _metaData->addEnumInfo(tr("Unknown: %1").arg(rawValue().toString()), rawValue());
225 226
            emit enumsChanged();
            return index;
227 228
        }
    } else {
229
        qWarning() << kMissingMetadata << name();
230 231 232 233 234 235 236 237 238
    }
    return -1;
}

QStringList Fact::enumStrings(void) const
{
    if (_metaData) {
        return _metaData->enumStrings();
    } else {
239
        qWarning() << kMissingMetadata << name();
240 241 242 243 244 245 246 247 248
        return QStringList();
    }
}

QVariantList Fact::enumValues(void) const
{
    if (_metaData) {
        return _metaData->enumValues();
    } else {
249
        qWarning() << kMissingMetadata << name();
250 251
        return QVariantList();
    }
252 253
}

254 255 256
void Fact::setEnumInfo(const QStringList& strings, const QVariantList& values)
{
    if (_metaData) {
257
        _metaData->setEnumInfo(strings, values);
258
    } else {
259
        qWarning() << kMissingMetadata << name();
260 261 262
    }
}

263 264 265 266 267
QStringList Fact::bitmaskStrings(void) const
{
    if (_metaData) {
        return _metaData->bitmaskStrings();
    } else {
268
        qWarning() << kMissingMetadata << name();
269 270 271 272 273 274 275 276 277
        return QStringList();
    }
}

QVariantList Fact::bitmaskValues(void) const
{
    if (_metaData) {
        return _metaData->bitmaskValues();
    } else {
278
        qWarning() << kMissingMetadata << name();
279 280 281 282
        return QVariantList();
    }
}

283
QString Fact::_variantToString(const QVariant& variant, int decimalPlaces) const
284
{
285 286 287
    QString valueString;

    switch (type()) {
Don Gagne's avatar
Don Gagne committed
288 289 290 291 292 293
    case FactMetaData::valueTypeFloat:
    {
        float fValue = variant.toFloat();
        if (qIsNaN(fValue)) {
            valueString = QStringLiteral("--.--");
        } else {
294
            valueString = QString("%1").arg(fValue, 0, 'f', decimalPlaces);
Don Gagne's avatar
Don Gagne committed
295 296 297 298 299 300 301 302 303
        }
    }
        break;
    case FactMetaData::valueTypeDouble:
    {
        double dValue = variant.toDouble();
        if (qIsNaN(dValue)) {
            valueString = QStringLiteral("--.--");
        } else {
304
            valueString = QString("%1").arg(dValue, 0, 'f', decimalPlaces);
Don Gagne's avatar
Don Gagne committed
305 306 307
        }
    }
        break;
308 309 310 311 312 313 314 315 316 317 318 319
    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
320 321 322
    default:
        valueString = variant.toString();
        break;
323 324 325
    }

    return valueString;
326 327
}

328 329 330 331 332 333
QString Fact::rawValueStringFullPrecision(void) const
{
    return _variantToString(rawValue(), 18);
}


334 335
QString Fact::rawValueString(void) const
{
336
    return _variantToString(rawValue(), decimalPlaces());
337 338 339
}

QString Fact::cookedValueString(void) const
340
{
341
    return _variantToString(cookedValue(), decimalPlaces());
342 343
}

344 345 346 347 348 349 350 351
QVariant Fact::rawDefaultValue(void) const
{
    if (_metaData) {
        if (!_metaData->defaultValueAvailable()) {
            qDebug() << "Access to unavailable default value";
        }
        return _metaData->rawDefaultValue();
    } else {
352
        qWarning() << kMissingMetadata << name();
353 354 355 356 357
        return QVariant(0);
    }
}

QVariant Fact::cookedDefaultValue(void) const
358
{
Don Gagne's avatar
Don Gagne committed
359 360 361 362
    if (_metaData) {
        if (!_metaData->defaultValueAvailable()) {
            qDebug() << "Access to unavailable default value";
        }
363
        return _metaData->cookedDefaultValue();
Don Gagne's avatar
Don Gagne committed
364
    } else {
365
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
366
        return QVariant(0);
367
    }
368 369
}

370
QString Fact::cookedDefaultValueString(void) const
371
{
372
    return _variantToString(cookedDefaultValue(), decimalPlaces());
373 374
}

375
FactMetaData::ValueType_t Fact::type(void) const
376
{
377
    return _type;
378 379
}

380
QString Fact::shortDescription(void) const
381
{
Don Gagne's avatar
Don Gagne committed
382 383 384
    if (_metaData) {
        return _metaData->shortDescription();
    } else {
385
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
386 387
        return QString();
    }
388 389
}

390
QString Fact::longDescription(void) const
391
{
Don Gagne's avatar
Don Gagne committed
392 393 394
    if (_metaData) {
        return _metaData->longDescription();
    } else {
395
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
396 397
        return QString();
    }
398 399
}

400 401 402 403 404
QString Fact::rawUnits(void) const
{
    if (_metaData) {
        return _metaData->rawUnits();
    } else {
405
        qWarning() << kMissingMetadata << name();
406 407 408 409 410
        return QString();
    }
}

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

420
QVariant Fact::rawMin(void) const
421
{
Don Gagne's avatar
Don Gagne committed
422
    if (_metaData) {
423
        return _metaData->rawMin();
Don Gagne's avatar
Don Gagne committed
424
    } else {
425
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
426 427
        return QVariant(0);
    }
428 429
}

430
QVariant Fact::cookedMin(void) const
431
{
432 433 434
    if (_metaData) {
        return _metaData->cookedMin();
    } else {
435
        qWarning() << kMissingMetadata << name();
436 437
        return QVariant(0);
    }
438 439
}

440 441
QString Fact::cookedMinString(void) const
{
442
    return _variantToString(cookedMin(), decimalPlaces());
443 444 445
}

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

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

QString Fact::cookedMaxString(void) const
{
467
    return _variantToString(cookedMax(), decimalPlaces());
468 469
}

470
bool Fact::minIsDefaultForType(void) const
Don Gagne's avatar
Don Gagne committed
471 472 473 474
{
    if (_metaData) {
        return _metaData->minIsDefaultForType();
    } else {
475
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
476 477 478 479
        return false;
    }
}

480
bool Fact::maxIsDefaultForType(void) const
Don Gagne's avatar
Don Gagne committed
481 482 483 484
{
    if (_metaData) {
        return _metaData->maxIsDefaultForType();
    } else {
485
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
486 487
        return false;
    }
488 489
}

490 491 492 493 494
int Fact::decimalPlaces(void) const
{
    if (_metaData) {
        return _metaData->decimalPlaces();
    } else {
495
        qWarning() << kMissingMetadata << name();
496 497 498 499
        return FactMetaData::defaultDecimalPlaces;
    }
}

500
QString Fact::group(void) const
501
{
Don Gagne's avatar
Don Gagne committed
502 503 504
    if (_metaData) {
        return _metaData->group();
    } else {
505
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
506 507
        return QString();
    }
508 509
}

510
void Fact::setMetaData(FactMetaData* metaData, bool setDefaultFromMetaData)
511 512
{
    _metaData = metaData;
513 514 515
    if (setDefaultFromMetaData) {
        setRawValue(rawDefaultValue());
    }
Don Gagne's avatar
Don Gagne committed
516
    emit valueChanged(cookedValue());
517
}
518

519
bool Fact::valueEqualsDefault(void) const
520
{
Don Gagne's avatar
Don Gagne committed
521 522
    if (_metaData) {
        if (_metaData->defaultValueAvailable()) {
523
            return _metaData->rawDefaultValue() == rawValue();
Don Gagne's avatar
Don Gagne committed
524 525 526
        } else {
            return false;
        }
527
    } else {
528
        qWarning() << kMissingMetadata << name();
529 530 531 532
        return false;
    }
}

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

543
QString Fact::validate(const QString& cookedValue, bool convertOnly)
Don Gagne's avatar
Don Gagne committed
544 545 546 547 548
{
    if (_metaData) {
        QVariant    typedValue;
        QString     errorString;
        
549
        _metaData->convertAndValidateCooked(cookedValue, convertOnly, typedValue, errorString);
Don Gagne's avatar
Don Gagne committed
550 551 552
        
        return errorString;
    } else {
553
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
554 555 556
        return QString("Internal error: Meta data pointer missing");
    }
}
557

558 559 560 561 562 563 564 565 566 567 568
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 {
569
        qWarning() << kMissingMetadata << name();
570 571 572 573
    }
    return QVariant();
}

574 575 576 577 578
bool Fact::rebootRequired(void) const
{
    if (_metaData) {
        return _metaData->rebootRequired();
    } else {
579
        qWarning() << kMissingMetadata << name();
580 581 582
        return false;
    }
}
Don Gagne's avatar
Don Gagne committed
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608

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());
    }
}
609 610 611 612 613 614 615 616 617 618

QString Fact::enumOrValueString(void)
{
    if (_metaData) {
        if (_metaData->enumStrings().count()) {
            return enumStringValue();
        } else {
            return cookedValueString();
        }
    } else {
619
        qWarning() << kMissingMetadata << name();
620 621 622
    }
    return QString();
}
Don Gagne's avatar
Don Gagne committed
623 624 625 626 627 628

double Fact::increment(void) const
{
    if (_metaData) {
        return _metaData->increment();
    } else {
629
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
630 631 632
    }
    return std::numeric_limits<double>::quiet_NaN();
}
633 634 635 636 637 638

bool Fact::hasControl(void) const
{
    if (_metaData) {
        return _metaData->hasControl();
    } else {
639
        qWarning() << kMissingMetadata << name();
640 641 642
        return false;
    }
}
643 644 645 646 647 648

bool Fact::readOnly(void) const
{
    if (_metaData) {
        return _metaData->readOnly();
    } else {
649
        qWarning() << kMissingMetadata << name();
650 651 652
        return false;
    }
}