Fact.cc 17.3 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
Fact::Fact(const QString& settingsGroup, FactMetaData* metaData, QObject* parent)
55 56 57 58 59 60 61 62
    : QObject(parent)
    , _name                     (metaData->name())
    , _componentId              (0)
    , _rawValue                 (0)
    , _type                     (metaData->type())
    , _metaData                 (NULL)
    , _sendValueChangedSignals  (true)
    , _deferredValueChangeSignal(false)
63
    , _valueSliderModel         (NULL)
64
{
65
    qgcApp()->toolbox()->corePlugin()->adjustSettingMetaData(settingsGroup, *metaData);
66 67 68
    setMetaData(metaData, true /* setDefaultFromMetaData */);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

    return QString();
}

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

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

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

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

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

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

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

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

    return valueString;
331 332
}

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

589 590 591 592 593
bool Fact::rebootRequired(void) const
{
    if (_metaData) {
        return _metaData->rebootRequired();
    } else {
594
        qWarning() << kMissingMetadata << name();
595 596 597
        return false;
    }
}
Don Gagne's avatar
Don Gagne committed
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 623

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

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

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

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

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

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

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

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

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