QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
Fact.cc
Go to the documentation of this file.
1#include "Fact.h"
3#include "QGCApplication.h"
4#include "QGCCorePlugin.h"
6#include "SettingsManager.h"
7
8QGC_LOGGING_CATEGORY(FactLog, "FactSystem.Fact")
9
10Fact::Fact(QObject *parent)
11 : QObject(parent)
12{
13 // qCDebug(FactLog) << Q_FUNC_INFO << this;
14
15 FactMetaData *const metaData = new FactMetaData(_type, this);
16 setMetaData(metaData);
17
18 _init();
19}
20
21Fact::Fact(int componentId, const QString &name, FactMetaData::ValueType_t type, QObject *parent)
22 : QObject(parent)
23 , _name(name)
24 , _componentId(componentId)
25 , _type(type)
26{
27 // qCDebug(FactLog) << Q_FUNC_INFO << this;
28
29 FactMetaData *const metaData = new FactMetaData(_type, this);
30 setMetaData(metaData);
31
32 _init();
33}
34
35Fact::Fact(const QString& settingsGroup, FactMetaData *metaData, QObject *parent)
36 : QObject(parent)
37 , _name(metaData->name())
38 , _componentId(0)
39 , _type(metaData->type())
40{
41 // qCDebug(FactLog) << Q_FUNC_INFO << this;
42
43 bool visible = true;
44 SettingsManager::adjustSettingMetaData(settingsGroup, *metaData, visible);
45 setMetaData(metaData, true /* setDefaultFromMetaData */);
46
47 if (!qgcApp()->runningUnitTests()) {
48 if (metaData->defaultValueAvailable() && !visible) {
49 // If setting is not visible, we force to default value
50 const QVariant defaultValue = metaData->rawDefaultValue();
51 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
52 _rawValue = defaultValue;
53 }
54 }
55
56 _init();
57}
58
59Fact::Fact(const Fact &other, QObject *parent)
60 : QObject(parent)
61{
62 // qCDebug(FactLog) << Q_FUNC_INFO << this;
63
64 *this = other;
65
66 _init();
67}
68
69Fact::~Fact()
70{
71 // qCDebug(FactLog) << Q_FUNC_INFO << this;
72}
73
74void Fact::_init()
75{
76 (void) connect(this, &Fact::containerRawValueChanged, this, &Fact::_checkForRebootMessaging);
77}
78
79const Fact &Fact::operator=(const Fact& other)
80{
81 if (this == &other) {
82 return *this;
83 }
84
85 QMutexLocker<QRecursiveMutex> otherLocker(&other._rawValueMutex);
86 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
87
88 _name = other._name;
90 _rawValue = other._rawValue;
91 _type = other._type;
94 _valueSliderModel = nullptr;
95 if (_metaData && other._metaData) {
96 *_metaData = *other._metaData;
97 } else {
98 _metaData = nullptr;
99 }
100
101 return *this;
102}
103
104void Fact::forceSetRawValue(const QVariant &value)
105{
106 if (_metaData) {
107 QVariant typedValue;
108 QString errorString;
109
110 if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) {
111 {
112 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
113 _rawValue = typedValue;
114 }
115
116 const QVariant cooked = _metaData->rawTranslator()(typedValue);
118 //-- Must be in this order
119 emit containerRawValueChanged(typedValue);
120 emit rawValueChanged(typedValue);
121 }
122 } else {
123 qCWarning(FactLog) << kMissingMetadata << name();
124 }
125}
126
127void Fact::setRawValue(const QVariant &value)
128{
129 if (_metaData) {
130 QVariant typedValue;
131 QString errorString;
132
133 if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) {
134 bool changed = false;
135 {
136 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
137 if (typedValue != _rawValue) {
138 _rawValue = typedValue;
139 changed = true;
140 }
141 }
142
143 if (changed) {
144 const QVariant cooked = _metaData->rawTranslator()(typedValue);
146 //-- Must be in this order
147 emit containerRawValueChanged(typedValue);
148 emit rawValueChanged(typedValue);
149 }
150 }
151 } else {
152 qCWarning(FactLog) << kMissingMetadata << name();
153 }
154}
155
156void Fact::setCookedValue(const QVariant& value)
157{
158 if (_metaData) {
159 setRawValue(_metaData->cookedTranslator()(value));
160 } else {
161 qCWarning(FactLog) << kMissingMetadata << name();
162 }
163}
164
165int Fact::valueIndex(const QString &value) const
166{
167 if (_metaData) {
168 return _metaData->enumStrings().indexOf(value);
169 }
170 qCWarning(FactLog) << kMissingMetadata << name();
171 return -1;
172}
173
174void Fact::setEnumStringValue(const QString &value)
175{
176 const int index = valueIndex(value);
177 if (index != -1) {
178 setCookedValue(_metaData->enumValues()[index]);
179 }
180}
181
182void Fact::setEnumIndex(int index)
183{
184 if (_metaData) {
185 setCookedValue(_metaData->enumValues()[index]);
186 } else {
187 qCWarning(FactLog) << kMissingMetadata << name();
188 }
189}
190
191void Fact::containerSetRawValue(const QVariant &value)
192{
193 QVariant cooked;
194 QVariant currentRaw = value;
195 bool changed = false;
196 {
197 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
198 if (_rawValue != value) {
199 _rawValue = value;
200 changed = true;
201 }
202 currentRaw = _rawValue;
203 if (_metaData) {
204 cooked = _metaData->rawTranslator()(_rawValue);
205 } else {
206 cooked = _rawValue;
207 }
208 }
209
210 if (changed) {
212 emit rawValueChanged(currentRaw);
213 }
214
215 // This always need to be signalled in order to support forceSetRawValue usage and waiting for vehicleUpdated signal
216 emit vehicleUpdated(currentRaw);
217}
218
219QVariant Fact::cookedValue() const
220{
221 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
222 if (_metaData) {
224 }
225
226 qCWarning(FactLog) << kMissingMetadata << name();
227 return _rawValue;
228}
229
230QString Fact::enumStringValue()
231{
232 if (_metaData) {
233 const int enumIndex = this->enumIndex();
234 if ((enumIndex >= 0) && (enumIndex < _metaData->enumStrings().count())) {
235 return _metaData->enumStrings()[enumIndex];
236 }
237 } else {
238 qCWarning(FactLog) << kMissingMetadata << name();
239 }
240
241 return QString();
242}
243
244int Fact::enumIndex()
245{
246 if (_metaData) {
247 //-- Only enums have an index
248 if (!_metaData->enumValues().isEmpty()) {
249 int index = 0;
250 for (const QVariant &enumValue: _metaData->enumValues()) {
251 if (enumValue == rawValue()) {
252 return index;
253 }
254 //-- Float comparisons don't always work
255 if ((type() == FactMetaData::valueTypeFloat) || (type() == FactMetaData::valueTypeDouble)) {
256 const double diff = fabs(enumValue.toDouble() - rawValue().toDouble());
257 static constexpr double accuracy = 1.0 / 1000000.0;
258 if (diff < accuracy) {
259 return index;
260 }
261 }
262 index++;
263 }
264 // Current value is not in list, add it manually
265 _metaData->addEnumInfo(tr("Unknown: %1").arg(rawValue().toString()), rawValue());
266 emit enumsChanged();
267 return index;
268 }
269 } else {
270 qCWarning(FactLog) << kMissingMetadata << name();
271 }
272 return -1;
273}
274
275QStringList Fact::enumStrings() const
276{
277 if (_metaData) {
278 return _metaData->enumStrings();
279 } else {
280 qCWarning(FactLog) << kMissingMetadata << name();
281 return QStringList();
282 }
283}
284
285QVariantList Fact::enumValues() const
286{
287 if (_metaData) {
288 return _metaData->enumValues();
289 } else {
290 qCWarning(FactLog) << kMissingMetadata << name();
291 return QVariantList();
292 }
293}
294
295void Fact::setEnumInfo(const QStringList &strings, const QVariantList &values)
296{
297 if (_metaData) {
298 _metaData->setEnumInfo(strings, values);
299 emit enumsChanged();
300 } else {
301 qCWarning(FactLog) << kMissingMetadata << name();
302 }
303}
304
305QStringList Fact::bitmaskStrings() const
306{
307 if (_metaData) {
308 return _metaData->bitmaskStrings();
309 } else {
310 qCWarning(FactLog) << kMissingMetadata << name();
311 return QStringList();
312 }
313}
314
315QVariantList Fact::bitmaskValues() const
316{
317 if (_metaData) {
318 return _metaData->bitmaskValues();
319 } else {
320 qCWarning(FactLog) << kMissingMetadata << name();
321 return QVariantList();
322 }
323}
324
325QStringList Fact::selectedBitmaskStrings() const
326{
327 if (_metaData) {
328 const auto values = _metaData->bitmaskValues();
329 const auto strings = _metaData->bitmaskStrings();
330 if (values.size() != strings.size()) {
331 qCWarning(FactLog) << "Size of bitmask value and string is different." << name();
332 return {};
333 }
334
335 QStringList selected;
336 for (qsizetype i = 0; i < values.size(); i++) {
337 if (rawValue().toInt() & values[i].toInt()) {
338 selected += strings[i];
339 }
340 }
341
342 if (selected.isEmpty()) {
343 selected += "Not value selected";
344 }
345
346 return selected;
347 } else {
348 qCWarning(FactLog) << kMissingMetadata << name();
349 return {};
350 }
351}
352
353QString Fact::_variantToString(const QVariant &variant, int decimalPlaces) const
354{
355 QString valueString;
356
357 const auto stripNegativeZero = [](QString &candidate) {
358 static const QRegularExpression reNegativeZero(QStringLiteral("^-0\\.0+$"));
359 const auto match = reNegativeZero.match(candidate);
360 if (match.hasMatch() || candidate == QStringLiteral("-0")) {
361 candidate = candidate.mid(1);
362 }
363 };
364
365 switch (type()) {
367 {
368 const float fValue = variant.toFloat();
369 if (qIsNaN(fValue)) {
370 valueString = invalidValueString(decimalPlaces);
371 } else {
372 valueString = QStringLiteral("%1").arg(fValue, 0, 'f', decimalPlaces);
373 stripNegativeZero(valueString);
374 }
375 }
376 break;
378 {
379 const double dValue = variant.toDouble();
380 if (qIsNaN(dValue)) {
381 valueString = invalidValueString(decimalPlaces);
382 } else {
383 valueString = QStringLiteral("%1").arg(dValue, 0, 'f', decimalPlaces);
384 stripNegativeZero(valueString);
385 }
386 break;
387 }
389 valueString = variant.toBool() ? tr("true") : tr("false");
390 break;
392 {
393 const double dValue = variant.toDouble();
394 if (qIsNaN(dValue)) {
395 valueString = invalidValueString(decimalPlaces);
396 } else {
397 QTime time(0, 0, 0, 0);
398 time = time.addSecs(dValue);
399 valueString = time.toString(QStringLiteral("hh:mm:ss"));
400 }
401 break;
402 }
403 default:
404 valueString = variant.toString();
405 break;
406 }
407
408 return valueString;
409}
410
411QString Fact::invalidValueString(int decimalPlaces) const {
412 switch (type()) {
415 if (decimalPlaces <= 0) {
416 return QStringLiteral("–");
417 }
418 return QStringLiteral("–.") +
419 QString(decimalPlaces, QChar(u'–'));
421 return QStringLiteral("––:––:––");
422 default:
423 return QStringLiteral("–");
424 }
425}
426
427QString Fact::rawValueStringFullPrecision() const
428{
429 return _variantToString(rawValue(), 18);
430}
431
432QString Fact::rawValueString() const
433{
434 return _variantToString(rawValue(), decimalPlaces());
435}
436
437QString Fact::cookedValueString() const
438{
439 return _variantToString(cookedValue(), decimalPlaces());
440}
441
442QVariant Fact::rawDefaultValue() const
443{
444 if (_metaData) {
446 qCDebug(FactLog) << "Access to unavailable default value";
447 }
448 return _metaData->rawDefaultValue();
449 } else {
450 qCWarning(FactLog) << kMissingMetadata << name();
451 return QVariant(0);
452 }
453}
454
455QVariant Fact::cookedDefaultValue() const
456{
457 if (_metaData) {
459 qCDebug(FactLog) << "Access to unavailable default value";
460 }
462 } else {
463 qCWarning(FactLog) << kMissingMetadata << name();
464 return QVariant(0);
465 }
466}
467
468QString Fact::cookedDefaultValueString() const
469{
470 return _variantToString(cookedDefaultValue(), decimalPlaces());
471}
472
473QString Fact::shortDescription() const
474{
475 if (_metaData) {
476 return _metaData->shortDescription();
477 } else {
478 qCWarning(FactLog) << kMissingMetadata << name();
479 return QString();
480 }
481}
482
483QString Fact::longDescription() const
484{
485 if (_metaData) {
486 return _metaData->longDescription();
487 } else {
488 qCWarning(FactLog) << kMissingMetadata << name();
489 return QString();
490 }
491}
492
493QString Fact::rawUnits() const
494{
495 if (_metaData) {
496 return _metaData->rawUnits();
497 } else {
498 qCWarning(FactLog) << kMissingMetadata << name();
499 return QString();
500 }
501}
502
503QString Fact::cookedUnits() const
504{
505 if (_metaData) {
506 return _metaData->cookedUnits();
507 } else {
508 qCWarning(FactLog) << kMissingMetadata << name();
509 return QString();
510 }
511}
512
513QVariant Fact::rawMin() const
514{
515 if (_metaData) {
516 return _metaData->rawMin();
517 } else {
518 qCWarning(FactLog) << kMissingMetadata << name();
519 return QVariant(0);
520 }
521}
522
523QVariant Fact::cookedMin() const
524{
525 if (_metaData) {
526 return _metaData->cookedMin();
527 } else {
528 qCWarning(FactLog) << kMissingMetadata << name();
529 return QVariant(0);
530 }
531}
532
533QVariant Fact::rawUserMin() const
534{
535 if (_metaData) {
536 return _metaData->rawUserMin();
537 }
538
539 qCWarning(FactLog) << kMissingMetadata << name();
540 return QVariant(0);
541}
542
543QVariant Fact::cookedUserMin() const
544{
545 if (_metaData) {
546 return _metaData->cookedUserMin();
547 }
548
549 qCWarning(FactLog) << kMissingMetadata << name();
550 return QVariant(0);
551}
552
553QString Fact::cookedMinString() const
554{
555 return _variantToString(cookedMin(), decimalPlaces());
556}
557
558QString Fact::cookedUserMinString() const
559{
560 return _variantToString(cookedUserMin(), decimalPlaces());
561}
562
563QVariant Fact::rawMax() const
564{
565 if (_metaData) {
566 return _metaData->rawMax();
567 } else {
568 qCWarning(FactLog) << kMissingMetadata << name();
569 return QVariant(0);
570 }
571}
572
573QVariant Fact::cookedMax() const
574{
575 if (_metaData) {
576 return _metaData->cookedMax();
577 } else {
578 qCWarning(FactLog) << kMissingMetadata << name();
579 return QVariant(0);
580 }
581}
582
583QVariant Fact::rawUserMax() const
584{
585 if (_metaData) {
586 return _metaData->rawUserMax();
587 }
588
589 qCWarning(FactLog) << kMissingMetadata << name();
590 return QVariant(0);
591}
592
593QVariant Fact::cookedUserMax() const
594{
595 if (_metaData) {
596 return _metaData->cookedUserMax();
597 }
598
599 qCWarning(FactLog) << kMissingMetadata << name();
600 return QVariant(0);
601}
602
603QString Fact::cookedMaxString() const
604{
605 return _variantToString(cookedMax(), decimalPlaces());
606}
607
608QString Fact::cookedUserMaxString() const
609{
610 return _variantToString(cookedUserMax(), decimalPlaces());
611}
612
613bool Fact::minIsDefaultForType() const
614{
615 if (_metaData) {
617 } else {
618 qCWarning(FactLog) << kMissingMetadata << name();
619 return false;
620 }
621}
622
623bool Fact::maxIsDefaultForType() const
624{
625 if (_metaData) {
627 } else {
628 qCWarning(FactLog) << kMissingMetadata << name();
629 return false;
630 }
631}
632
633int Fact::decimalPlaces() const
634{
635 if (_metaData) {
636 return _metaData->decimalPlaces();
637 } else {
638 qCWarning(FactLog) << kMissingMetadata << name();
640 }
641}
642
643QString Fact::category() const
644{
645 if (_metaData) {
646 return _metaData->category();
647 } else {
648 qCWarning(FactLog) << kMissingMetadata << name();
649 return QString();
650 }
651}
652
653QString Fact::group() const
654{
655 if (_metaData) {
656 return _metaData->group();
657 } else {
658 qCWarning(FactLog) << kMissingMetadata << name();
659 return QString();
660 }
661}
662
663void Fact::setMetaData(FactMetaData *metaData, bool setDefaultFromMetaData)
664{
665 _metaData = metaData;
666 if (setDefaultFromMetaData && metaData->defaultValueAvailable()) {
667 setRawValue(rawDefaultValue());
668 }
669 emit valueChanged(cookedValue());
670}
671
672bool Fact::valueEqualsDefault() const
673{
674 if (_metaData) {
676 return _metaData->rawDefaultValue() == rawValue();
677 } else {
678 return false;
679 }
680 } else {
681 qCWarning(FactLog) << kMissingMetadata << name();
682 return false;
683 }
684}
685
686bool Fact::defaultValueAvailable() const
687{
688 if (_metaData) {
690 } else {
691 qCWarning(FactLog) << kMissingMetadata << name();
692 return false;
693 }
694}
695
696QString Fact::validate(const QString &cookedValue, bool convertOnly)
697{
698 if (_metaData) {
699 QVariant typedValue;
700 QString errorString;
701
702 _metaData->convertAndValidateCooked(cookedValue, convertOnly, typedValue, errorString);
703
704 return errorString;
705 } else {
706 qCWarning(FactLog) << kMissingMetadata << name();
707 return QStringLiteral("Internal error: Meta data pointer missing");
708 }
709}
710
711QVariant Fact::clamp(const QString &cookedValue)
712{
713 if (_metaData) {
714 QVariant typedValue;
715 if (_metaData->clampValue(cookedValue, typedValue)) {
716 return typedValue;
717 } else {
718 //-- If conversion failed, return current value
719 return rawValue();
720 }
721 } else {
722 qCWarning(FactLog) << kMissingMetadata << name();
723 }
724 return QVariant();
725}
726
727bool Fact::vehicleRebootRequired() const
728{
729 if (_metaData) {
731 } else {
732 qCWarning(FactLog) << kMissingMetadata << name();
733 return false;
734 }
735}
736
737bool Fact::qgcRebootRequired() const
738{
739 if (_metaData) {
741 } else {
742 qCWarning(FactLog) << kMissingMetadata << name();
743 return false;
744 }
745}
746
747void Fact::setSendValueChangedSignals(bool sendValueChangedSignals)
748{
749 if (sendValueChangedSignals != _sendValueChangedSignals) {
750 _sendValueChangedSignals = sendValueChangedSignals;
752 }
753}
754
755void Fact::_sendValueChangedSignal(const QVariant &value)
756{
758 emit valueChanged(value);
760 } else {
762 }
763}
764
765void Fact::sendDeferredValueChangedSignal()
766{
769 emit valueChanged(cookedValue());
770 }
771}
772
773QString Fact::enumOrValueString()
774{
775 if (_metaData) {
776 if (_metaData->enumStrings().count()) {
777 return enumStringValue();
778 } else {
779 return cookedValueString();
780 }
781 } else {
782 qCWarning(FactLog) << kMissingMetadata << name();
783 }
784 return QString();
785}
786
787double Fact::rawIncrement() const
788{
789 if (_metaData) {
790 return _metaData->rawIncrement();
791 } else {
792 qCWarning(FactLog) << kMissingMetadata << name();
793 }
794 return std::numeric_limits<double>::quiet_NaN();
795}
796
797double Fact::cookedIncrement() const
798{
799 if (_metaData) {
800 return _metaData->cookedIncrement();
801 } else {
802 qCWarning(FactLog) << kMissingMetadata << name();
803 }
804 return std::numeric_limits<double>::quiet_NaN();
805}
806
807bool Fact::hasControl() const
808{
809 if (_metaData) {
810 return _metaData->hasControl();
811 } else {
812 qCWarning(FactLog) << kMissingMetadata << name();
813 return false;
814 }
815}
816
817bool Fact::readOnly() const
818{
819 if (_metaData) {
820 return _metaData->readOnly();
821 } else {
822 qCWarning(FactLog) << kMissingMetadata << name();
823 return false;
824 }
825}
826
827bool Fact::writeOnly() const
828{
829 if (_metaData) {
830 return _metaData->writeOnly();
831 } else {
832 qCWarning(FactLog) << kMissingMetadata << name();
833 return false;
834 }
835}
836
837bool Fact::volatileValue() const
838{
839 if (_metaData) {
840 return _metaData->volatileValue();
841 } else {
842 qCWarning(FactLog) << kMissingMetadata << name();
843 return false;
844 }
845}
846
847FactValueSliderListModel *Fact::valueSliderModel()
848{
849 if (!_valueSliderModel) {
851 }
852
853 return _valueSliderModel;
854}
855
856void Fact::_checkForRebootMessaging()
857{
858 if (qgcApp()) {
859 if (!qgcApp()->runningUnitTests()) {
860 if (vehicleRebootRequired()) {
861 qgcApp()->showRebootAppMessage(tr("Reboot vehicle for changes to take effect."));
862 } else if (qgcRebootRequired()) {
863 qgcApp()->showRebootAppMessage(tr("Restart application for changes to take effect."));
864 }
865 }
866 }
867}
#define qgcApp()
QString errorString
#define QGC_LOGGING_CATEGORY(name, categoryStr)
QStringList enumStrings() const
QVariant cookedDefaultValue() const
bool hasControl() const
QVariant cookedMin() const
QStringList bitmaskStrings() const
bool clampValue(const QVariant &cookedValue, QVariant &typedValue) const
bool qgcRebootRequired() const
bool convertAndValidateCooked(const QVariant &cookedValue, bool convertOnly, QVariant &typedValue, QString &errorString) const
Same as convertAndValidateRaw except for cookedValue input.
QVariant cookedUserMax() const
Translator cookedTranslator() const
QVariant cookedMax() const
QString group() const
QVariant rawMin() const
@ valueTypeElapsedTimeInSeconds
QVariantList enumValues() const
QString cookedUnits() const
QString shortDescription() const
bool maxIsDefaultForType() const
int decimalPlaces() const
static constexpr int kDefaultDecimalPlaces
Default value for decimal places if not specified/known.
QVariant cookedUserMin() const
QVariant rawUserMin() const
bool convertAndValidateRaw(const QVariant &rawValue, bool convertOnly, QVariant &typedValue, QString &errorString) const
QString rawUnits() const
QVariant rawUserMax() const
double rawIncrement() const
void setEnumInfo(const QStringList &strings, const QVariantList &values)
bool readOnly() const
QString category() const
QString longDescription() const
bool minIsDefaultForType() const
bool writeOnly() const
void addEnumInfo(const QString &name, const QVariant &value)
Used to add new values to the enum lists after the meta data has been loaded.
QVariantList bitmaskValues() const
QVariant rawDefaultValue() const
bool vehicleRebootRequired() const
bool volatileValue() const
QVariant rawMax() const
bool defaultValueAvailable() const
double cookedIncrement() const
Translator rawTranslator() const
Provides a list model of values for incrementing/decrementing the value of a Fact.
A Fact is used to hold a single value within the system.
Definition Fact.h:19
bool _sendValueChangedSignals
Definition Fact.h:208
QString _name
Definition Fact.h:202
bool _deferredValueChangeSignal
Definition Fact.h:209
void sendValueChangedSignalsChanged(bool sendValueChangedSignals)
FactMetaData * _metaData
Definition Fact.h:207
FactMetaData::ValueType_t _type
Definition Fact.h:206
void rawValueChanged(const QVariant &value)
QRecursiveMutex _rawValueMutex
Definition Fact.h:205
static constexpr const char * kMissingMetadata
Definition Fact.h:212
void containerRawValueChanged(const QVariant &value)
This signal is meant for use by Fact container implementations. Used to send changed values to vehicl...
int _componentId
Definition Fact.h:203
QString _variantToString(const QVariant &variant, int decimalPlaces) const
Definition Fact.cc:353
FactValueSliderListModel * _valueSliderModel
Definition Fact.h:210
QVariant _rawValue
Definition Fact.h:204
void _sendValueChangedSignal(const QVariant &value)
Definition Fact.cc:755
void enumsChanged()
void vehicleUpdated(const QVariant &value)
Signalled when the param write ack comes back from the vehicle.
void valueChanged(const QVariant &value)
This signal is only meant for use by the QT property system. It should not be connected to by client ...