Fact.cc 16.5 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
    if(_rawValue != value) {
        _rawValue = value;
        _sendValueChangedSignal(cookedValue());
        emit rawValueChanged(_rawValue);
    }
166 167 168

    // 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
169
}
170 171 172 173 174 175

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

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

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

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

    return QString();
}

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

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

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

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

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

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

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

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

    return valueString;
328 329
}

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

bool Fact::hasControl(void) const
{
    if (_metaData) {
        return _metaData->hasControl();
    } else {
651
        qWarning() << kMissingMetadata << name();
652 653 654
        return false;
    }
}
655 656 657 658 659 660

bool Fact::readOnly(void) const
{
    if (_metaData) {
        return _metaData->readOnly();
    } else {
661
        qWarning() << kMissingMetadata << name();
662 663 664
        return false;
    }
}
665

666 667 668 669 670 671 672 673 674 675
bool Fact::writeOnly(void) const
{
    if (_metaData) {
        return _metaData->writeOnly();
    } else {
        qWarning() << kMissingMetadata << name();
        return false;
    }
}

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