Fact.cc 17.1 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 26 27
    : QObject                   (parent)
    , _componentId              (-1)
    , _rawValue                 (0)
    , _type                     (FactMetaData::valueTypeInt32)
    , _metaData                 (NULL)
    , _sendValueChangedSignals  (true)
Don Gagne's avatar
Don Gagne committed
28
    , _deferredValueChangeSignal(false)
29
    , _valueSliderModel         (NULL)
Don Gagne's avatar
Don Gagne committed
30 31 32
{    
    FactMetaData* metaData = new FactMetaData(_type, this);
    setMetaData(metaData);
33

34
    // Better safe than sorry on object ownership
35
    QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
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 44 45
    : QObject                   (parent)
    , _name                     (name)
    , _componentId              (componentId)
    , _rawValue                 (0)
    , _type                     (type)
    , _metaData                 (NULL)
    , _sendValueChangedSignals  (true)
Don Gagne's avatar
Don Gagne committed
46
    , _deferredValueChangeSignal(false)
47
    , _valueSliderModel         (NULL)
Don Gagne's avatar
Don Gagne committed
48
{
Don Gagne's avatar
Don Gagne committed
49 50
    FactMetaData* metaData = new FactMetaData(_type, this);
    setMetaData(metaData);
51
    QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
Don Gagne's avatar
Don Gagne committed
52
}
Don Gagne's avatar
Don Gagne committed
53

54 55 56 57 58 59 60 61 62
Fact::Fact(FactMetaData* metaData, QObject* parent)
    : QObject(parent)
    , _name                     (metaData->name())
    , _componentId              (0)
    , _rawValue                 (0)
    , _type                     (metaData->type())
    , _metaData                 (NULL)
    , _sendValueChangedSignals  (true)
    , _deferredValueChangeSignal(false)
63
    , _valueSliderModel         (NULL)
64 65 66 67
{
    setMetaData(metaData, true /* setDefaultFromMetaData */);
}

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

const Fact& Fact::operator=(const Fact& other)
{
Don Gagne's avatar
Don Gagne committed
77 78 79 80 81 82
    _name                       = other._name;
    _componentId                = other._componentId;
    _rawValue                   = other._rawValue;
    _type                       = other._type;
    _sendValueChangedSignals    = other._sendValueChangedSignals;
    _deferredValueChangeSignal  = other._deferredValueChangeSignal;
83
    _valueSliderModel       = NULL;
Don Gagne's avatar
Don Gagne committed
84 85 86 87 88 89 90
    if (_metaData && other._metaData) {
        *_metaData = *other._metaData;
    } else {
        _metaData = NULL;
    }
    
    return *this;
Don Gagne's avatar
Don Gagne committed
91 92
}

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

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

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

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

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

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

    // 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
171
}
172 173 174 175 176 177

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

178 179 180 181 182
int Fact::componentId(void) const
{
    return _componentId;
}

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

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

    return QString();
}

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

QStringList Fact::enumStrings(void) const
{
    if (_metaData) {
        return _metaData->enumStrings();
    } else {
243
        qWarning() << kMissingMetadata << name();
244 245 246 247 248 249 250 251 252
        return QStringList();
    }
}

QVariantList Fact::enumValues(void) const
{
    if (_metaData) {
        return _metaData->enumValues();
    } else {
253
        qWarning() << kMissingMetadata << name();
254 255
        return QVariantList();
    }
256 257
}

258 259 260
void Fact::setEnumInfo(const QStringList& strings, const QVariantList& values)
{
    if (_metaData) {
261
        _metaData->setEnumInfo(strings, values);
262
    } else {
263
        qWarning() << kMissingMetadata << name();
264 265 266
    }
}

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

QVariantList Fact::bitmaskValues(void) const
{
    if (_metaData) {
        return _metaData->bitmaskValues();
    } else {
282
        qWarning() << kMissingMetadata << name();
283 284 285 286
        return QVariantList();
    }
}

287
QString Fact::_variantToString(const QVariant& variant, int decimalPlaces) const
288
{
289 290 291
    QString valueString;

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

    return valueString;
330 331
}

332 333 334 335 336 337
QString Fact::rawValueStringFullPrecision(void) const
{
    return _variantToString(rawValue(), 18);
}


338 339
QString Fact::rawValueString(void) const
{
340
    return _variantToString(rawValue(), decimalPlaces());
341 342 343
}

QString Fact::cookedValueString(void) const
344
{
345
    return _variantToString(cookedValue(), decimalPlaces());
346 347
}

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

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

374
QString Fact::cookedDefaultValueString(void) const
375
{
376
    return _variantToString(cookedDefaultValue(), decimalPlaces());
377 378
}

379
FactMetaData::ValueType_t Fact::type(void) const
380
{
381
    return _type;
382 383
}

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

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

404 405 406 407 408
QString Fact::rawUnits(void) const
{
    if (_metaData) {
        return _metaData->rawUnits();
    } else {
409
        qWarning() << kMissingMetadata << name();
410 411 412 413 414
        return QString();
    }
}

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

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

434
QVariant Fact::cookedMin(void) const
435
{
436 437 438
    if (_metaData) {
        return _metaData->cookedMin();
    } else {
439
        qWarning() << kMissingMetadata << name();
440 441
        return QVariant(0);
    }
442 443
}

444 445
QString Fact::cookedMinString(void) const
{
446
    return _variantToString(cookedMin(), decimalPlaces());
447 448 449
}

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

459
QVariant Fact::cookedMax(void) const
460
{
461 462 463
    if (_metaData) {
        return _metaData->cookedMax();
    } else {
464
        qWarning() << kMissingMetadata << name();
465 466 467 468 469 470
        return QVariant(0);
    }
}

QString Fact::cookedMaxString(void) const
{
471
    return _variantToString(cookedMax(), decimalPlaces());
472 473
}

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

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

494 495 496 497 498
int Fact::decimalPlaces(void) const
{
    if (_metaData) {
        return _metaData->decimalPlaces();
    } else {
499
        qWarning() << kMissingMetadata << name();
500 501 502 503
        return FactMetaData::defaultDecimalPlaces;
    }
}

504 505 506 507 508 509 510 511 512 513
QString Fact::category(void) const
{
    if (_metaData) {
        return _metaData->category();
    } else {
        qWarning() << kMissingMetadata << name();
        return QString();
    }
}

514
QString Fact::group(void) const
515
{
Don Gagne's avatar
Don Gagne committed
516 517 518
    if (_metaData) {
        return _metaData->group();
    } else {
519
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
520 521
        return QString();
    }
522 523
}

524
void Fact::setMetaData(FactMetaData* metaData, bool setDefaultFromMetaData)
525 526
{
    _metaData = metaData;
527 528 529
    if (setDefaultFromMetaData) {
        setRawValue(rawDefaultValue());
    }
Don Gagne's avatar
Don Gagne committed
530
    emit valueChanged(cookedValue());
531
}
532

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

547
bool Fact::defaultValueAvailable(void) const
548
{
Don Gagne's avatar
Don Gagne committed
549 550 551
    if (_metaData) {
        return _metaData->defaultValueAvailable();
    } else {
552
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
553 554 555 556
        return false;
    }
}

557
QString Fact::validate(const QString& cookedValue, bool convertOnly)
Don Gagne's avatar
Don Gagne committed
558 559 560 561 562
{
    if (_metaData) {
        QVariant    typedValue;
        QString     errorString;
        
563
        _metaData->convertAndValidateCooked(cookedValue, convertOnly, typedValue, errorString);
Don Gagne's avatar
Don Gagne committed
564 565 566
        
        return errorString;
    } else {
567
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
568 569 570
        return QString("Internal error: Meta data pointer missing");
    }
}
571

572 573 574 575 576 577 578 579 580 581 582
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 {
583
        qWarning() << kMissingMetadata << name();
584 585 586 587
    }
    return QVariant();
}

588 589 590 591 592
bool Fact::rebootRequired(void) const
{
    if (_metaData) {
        return _metaData->rebootRequired();
    } else {
593
        qWarning() << kMissingMetadata << name();
594 595 596
        return false;
    }
}
Don Gagne's avatar
Don Gagne committed
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622

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());
    }
}
623 624 625 626 627 628 629 630 631 632

QString Fact::enumOrValueString(void)
{
    if (_metaData) {
        if (_metaData->enumStrings().count()) {
            return enumStringValue();
        } else {
            return cookedValueString();
        }
    } else {
633
        qWarning() << kMissingMetadata << name();
634 635 636
    }
    return QString();
}
Don Gagne's avatar
Don Gagne committed
637

638
double Fact::rawIncrement(void) const
Don Gagne's avatar
Don Gagne committed
639 640
{
    if (_metaData) {
641
        return _metaData->rawIncrement();
Don Gagne's avatar
Don Gagne committed
642
    } else {
643
        qWarning() << kMissingMetadata << name();
Don Gagne's avatar
Don Gagne committed
644 645 646
    }
    return std::numeric_limits<double>::quiet_NaN();
}
647

648 649 650 651 652 653 654 655 656 657
double Fact::cookedIncrement(void) const
{
    if (_metaData) {
        return _metaData->cookedIncrement();
    } else {
        qWarning() << kMissingMetadata << name();
    }
    return std::numeric_limits<double>::quiet_NaN();
}

658 659 660 661 662
bool Fact::hasControl(void) const
{
    if (_metaData) {
        return _metaData->hasControl();
    } else {
663
        qWarning() << kMissingMetadata << name();
664 665 666
        return false;
    }
}
667 668 669 670 671 672

bool Fact::readOnly(void) const
{
    if (_metaData) {
        return _metaData->readOnly();
    } else {
673
        qWarning() << kMissingMetadata << name();
674 675 676
        return false;
    }
}
677

678 679 680 681 682 683 684 685 686 687
bool Fact::writeOnly(void) const
{
    if (_metaData) {
        return _metaData->writeOnly();
    } else {
        qWarning() << kMissingMetadata << name();
        return false;
    }
}

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

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