QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
Fact.cc
Go to the documentation of this file.
1#include <cmath>
2#include <cstdio>
3#include <cstdlib>
4#include <cstring>
5#include <limits>
6
7#include "Fact.h"
9#include "AppMessages.h"
10#include "QGCApplication.h"
11#include "QGCCorePlugin.h"
12#include "QGCLoggingCategory.h"
13#include "SettingsManager.h"
14
15QGC_LOGGING_CATEGORY(FactLog, "FactSystem.Fact")
16
17Fact::Fact(QObject *parent)
18 : QObject(parent)
19{
20 // qCDebug(FactLog) << Q_FUNC_INFO << this;
21
22 FactMetaData *const metaData = new FactMetaData(_type, this);
23 setMetaData(metaData);
24
25 _init();
26}
27
28Fact::Fact(int componentId, const QString &name, FactMetaData::ValueType_t type, QObject *parent)
29 : QObject(parent)
30 , _name(name)
31 , _componentId(componentId)
32 , _type(type)
33{
34 // qCDebug(FactLog) << Q_FUNC_INFO << this;
35
36 FactMetaData *const metaData = new FactMetaData(_type, this);
38
39 _init();
40}
41
42Fact::Fact(const QString& settingsGroup, FactMetaData *metaData, QObject *parent)
43 : QObject(parent)
44 , _name(metaData->name())
45 , _componentId(0)
46 , _type(metaData->type())
47{
48 // qCDebug(FactLog) << Q_FUNC_INFO << this;
49
50 bool visible = true;
51 SettingsManager::adjustSettingMetaData(settingsGroup, *metaData, visible);
52 setMetaData(metaData, true /* setDefaultFromMetaData */);
53
54 if (!QGC::runningUnitTests()) {
55 if (metaData->defaultValueAvailable() && !visible) {
56 // If setting is not visible, we force to default value
57 const QVariant defaultValue = metaData->rawDefaultValue();
58 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
59 _rawValue = defaultValue;
60 }
61 }
62
63 _init();
64}
65
66Fact::Fact(const Fact &other, QObject *parent)
67 : QObject(parent)
68{
69 // qCDebug(FactLog) << Q_FUNC_INFO << this;
70
71 *this = other;
72
73 _init();
74}
75
77{
78 // qCDebug(FactLog) << Q_FUNC_INFO << this;
79}
80
81void Fact::_init()
82{
83 (void) connect(this, &Fact::containerRawValueChanged, this, &Fact::_checkForRebootMessaging);
84}
85
86const Fact &Fact::operator=(const Fact& other)
87{
88 if (this == &other) {
89 return *this;
90 }
91
92 QMutexLocker<QRecursiveMutex> otherLocker(&other._rawValueMutex);
93 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
94
95 _name = other._name;
97 _rawValue = other._rawValue;
98 _type = other._type;
101 _valueSliderModel = nullptr;
102 if (_metaData && other._metaData) {
103 *_metaData = *other._metaData;
104 } else {
105 _metaData = nullptr;
106 }
107
108 return *this;
109}
110
111void Fact::forceSetRawValue(const QVariant &value)
112{
113 if (_metaData) {
114 QVariant typedValue;
115 QString errorString;
116
117 if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) {
118 {
119 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
120 _rawValue = typedValue;
121 }
122
123 const QVariant cooked = _metaData->rawTranslator()(typedValue);
125 //-- Must be in this order
126 emit containerRawValueChanged(typedValue);
127 emit rawValueChanged(typedValue);
128 }
129 } else {
130 qCWarning(FactLog) << kMissingMetadata << name();
131 }
132}
133
134void Fact::setRawValue(const QVariant &value)
135{
136 if (_metaData) {
137 QVariant typedValue;
138 QString errorString;
139
140 if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) {
141 bool changed = false;
142 {
143 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
144 if (typedValue != _rawValue) {
145 _rawValue = typedValue;
146 changed = true;
147 }
148 }
149
150 if (changed) {
151 const QVariant cooked = _metaData->rawTranslator()(typedValue);
153 //-- Must be in this order
154 emit containerRawValueChanged(typedValue);
155 emit rawValueChanged(typedValue);
156 }
157 }
158 } else {
159 qCWarning(FactLog) << kMissingMetadata << name();
160 }
161}
162
163void Fact::setCookedValue(const QVariant& value)
164{
165 if (_metaData) {
167 } else {
168 qCWarning(FactLog) << kMissingMetadata << name();
169 }
170}
171
172int Fact::valueIndex(const QString &value) const
173{
174 if (_metaData) {
175 return _metaData->enumStrings().indexOf(value);
176 }
177 qCWarning(FactLog) << kMissingMetadata << name();
178 return -1;
179}
180
181void Fact::setEnumStringValue(const QString &value)
182{
183 const int index = valueIndex(value);
184 if (index != -1) {
186 }
187}
188
189void Fact::setEnumIndex(int index)
190{
191 if (_metaData) {
193 } else {
194 qCWarning(FactLog) << kMissingMetadata << name();
195 }
196}
197
198void Fact::containerSetRawValue(const QVariant &value)
199{
200 QVariant cooked;
201 QVariant currentRaw = value;
202 bool changed = false;
203 {
204 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
205 if (_rawValue != value) {
206 _rawValue = value;
207 changed = true;
208 }
209 currentRaw = _rawValue;
210 if (_metaData) {
211 cooked = _metaData->rawTranslator()(_rawValue);
212 } else {
213 cooked = _rawValue;
214 }
215 }
216
217 if (changed) {
219 emit rawValueChanged(currentRaw);
220 }
221
222 // This always need to be signalled in order to support forceSetRawValue usage and waiting for vehicleUpdated signal
223 emit vehicleUpdated(currentRaw);
224}
225
226QVariant Fact::cookedValue() const
227{
228 QMutexLocker<QRecursiveMutex> locker(&_rawValueMutex);
229 if (_metaData) {
231 }
232
233 qCWarning(FactLog) << kMissingMetadata << name();
234 return _rawValue;
235}
236
237QVariant Fact::rawToCooked(const QVariant &rawValue) const
238{
239 if (_metaData) {
241 }
242
243 qCWarning(FactLog) << kMissingMetadata << name();
244 return rawValue;
245}
246
248{
249 if (_metaData) {
250 const int enumIndex = this->enumIndex();
251 if ((enumIndex >= 0) && (enumIndex < _metaData->enumStrings().count())) {
253 }
254 } else {
255 qCWarning(FactLog) << kMissingMetadata << name();
256 }
257
258 return QString();
259}
260
262{
263 if (_metaData) {
264 //-- Only enums have an index
265 if (!_metaData->enumValues().isEmpty()) {
266 int index = 0;
267 for (const QVariant &enumValue: _metaData->enumValues()) {
268 if (enumValue == rawValue()) {
269 return index;
270 }
271 //-- Float comparisons don't always work
273 const double diff = fabs(enumValue.toDouble() - rawValue().toDouble());
274 static constexpr double accuracy = 1.0 / 1000000.0;
275 if (diff < accuracy) {
276 return index;
277 }
278 }
279 index++;
280 }
281 // Current value is not in list, add it manually. Defer the signal since this can
282 // be called from within a QML binding read and a synchronous emit causes binding loops.
283 _metaData->addEnumInfo(tr("Unknown: %1").arg(rawValue().toString()), rawValue());
284 QMetaObject::invokeMethod(this, &Fact::enumsChanged, Qt::QueuedConnection);
285 return index;
286 }
287 } else {
288 qCWarning(FactLog) << kMissingMetadata << name();
289 }
290 return -1;
291}
292
293QStringList Fact::enumStrings() const
294{
295 if (_metaData) {
296 return _metaData->enumStrings();
297 } else {
298 qCWarning(FactLog) << kMissingMetadata << name();
299 return QStringList();
300 }
301}
302
303QVariantList Fact::enumValues() const
304{
305 if (_metaData) {
306 return _metaData->enumValues();
307 } else {
308 qCWarning(FactLog) << kMissingMetadata << name();
309 return QVariantList();
310 }
311}
312
313void Fact::setEnumInfo(const QStringList &strings, const QVariantList &values)
314{
315 if (_metaData) {
316 _metaData->setEnumInfo(strings, values);
317 emit enumsChanged();
318 } else {
319 qCWarning(FactLog) << kMissingMetadata << name();
320 }
321}
322
323QStringList Fact::bitmaskStrings() const
324{
325 if (_metaData) {
326 return _metaData->bitmaskStrings();
327 } else {
328 qCWarning(FactLog) << kMissingMetadata << name();
329 return QStringList();
330 }
331}
332
333QVariantList Fact::bitmaskValues() const
334{
335 if (_metaData) {
336 return _metaData->bitmaskValues();
337 } else {
338 qCWarning(FactLog) << kMissingMetadata << name();
339 return QVariantList();
340 }
341}
342
344{
345 if (_metaData) {
346 const auto values = _metaData->bitmaskValues();
347 const auto strings = _metaData->bitmaskStrings();
348 if (values.size() != strings.size()) {
349 qCWarning(FactLog) << "Size of bitmask value and string is different." << name();
350 return {};
351 }
352
353 QStringList selected;
354 for (qsizetype i = 0; i < values.size(); i++) {
355 if (rawValue().toInt() & values[i].toInt()) {
356 selected += strings[i];
357 }
358 }
359
360 if (selected.isEmpty()) {
361 selected += "Not value selected";
362 }
363
364 return selected;
365 } else {
366 qCWarning(FactLog) << kMissingMetadata << name();
367 return {};
368 }
369}
370
371QString Fact::_variantToString(const QVariant &variant, int decimalPlaces) const
372{
373 QString valueString;
374
375 const auto stripNegativeZero = [](QString &candidate) {
376 static const QRegularExpression reNegativeZero(QStringLiteral("^-0\\.0+$"));
377 const auto match = reNegativeZero.match(candidate);
378 if (match.hasMatch() || candidate == QStringLiteral("-0")) {
379 candidate = candidate.mid(1);
380 }
381 };
382
383 switch (type()) {
385 {
386 const float fValue = variant.toFloat();
387 if (qIsNaN(fValue)) {
388 valueString = invalidValueString(decimalPlaces);
389 } else {
390 valueString = QStringLiteral("%1").arg(fValue, 0, 'f', decimalPlaces);
391 stripNegativeZero(valueString);
392 }
393 }
394 break;
396 {
397 const double dValue = variant.toDouble();
398 if (qIsNaN(dValue)) {
399 valueString = invalidValueString(decimalPlaces);
400 } else {
401 valueString = QStringLiteral("%1").arg(dValue, 0, 'f', decimalPlaces);
402 stripNegativeZero(valueString);
403 }
404 break;
405 }
407 valueString = variant.toBool() ? tr("true") : tr("false");
408 break;
410 {
411 const double dValue = variant.toDouble();
412 if (qIsNaN(dValue)) {
413 valueString = invalidValueString(decimalPlaces);
414 } else {
415 QTime time(0, 0, 0, 0);
416 time = time.addSecs(dValue);
417 valueString = time.toString(QStringLiteral("hh:mm:ss"));
418 }
419 break;
420 }
421 default:
422 valueString = variant.toString();
423 break;
424 }
425
426 return valueString;
427}
428
429QString Fact::invalidValueString(int decimalPlaces) const {
430 switch (type()) {
433 if (decimalPlaces <= 0) {
434 return QStringLiteral("–");
435 }
436 return QStringLiteral("–.") +
437 QString(decimalPlaces, QChar(u'–'));
439 return QStringLiteral("––:––:––");
440 default:
441 return QStringLiteral("–");
442 }
443}
444
446{
448 const float fValue = rawValue().toFloat();
449 if (std::isnan(fValue)) {
450 return invalidValueString(0);
451 }
452 // Find the shortest decimal string that round-trips back to the same float bits.
453 // snprintf with "%.*g" formats to p significant digits; strtof checks the round-trip.
454 // TODO: replace with std::to_chars once macOS min target >= 13.3
455 char buf[32];
456 for (int p = 1; p <= std::numeric_limits<float>::max_digits10; ++p) {
457 std::snprintf(buf, sizeof(buf), "%.*g", p, static_cast<double>(fValue));
458 if (std::strtof(buf, nullptr) == fValue) {
459 break;
460 }
461 }
462 if (std::strcmp(buf, "-0") == 0) {
463 buf[0] = '0';
464 buf[1] = '\0';
465 }
466 return QString::fromLatin1(buf);
467 } else if (type() == FactMetaData::valueTypeDouble) {
468 const double dValue = rawValue().toDouble();
469 if (std::isnan(dValue)) {
470 return invalidValueString(0);
471 }
472 // TODO: replace with std::to_chars once macOS min target >= 13.3
473 QString result = QString::number(dValue, 'g', QLocale::FloatingPointShortest);
474 if (result == QStringLiteral("-0")) {
475 result = QStringLiteral("0");
476 }
477 return result;
478 } else {
479 return _variantToString(rawValue(), 0);
480 }
481}
482
483QString Fact::rawValueString() const
484{
486}
487
489{
491}
492
493QVariant Fact::rawDefaultValue() const
494{
495 if (_metaData) {
497 qCDebug(FactLog) << "Access to unavailable default value";
498 }
499 return _metaData->rawDefaultValue();
500 } else {
501 qCWarning(FactLog) << kMissingMetadata << name();
502 return QVariant(0);
503 }
504}
505
507{
508 if (_metaData) {
510 qCDebug(FactLog) << "Access to unavailable default value";
511 }
513 } else {
514 qCWarning(FactLog) << kMissingMetadata << name();
515 return QVariant(0);
516 }
517}
518
523
525{
526 if (_metaData) {
527 return _metaData->shortDescription();
528 } else {
529 qCWarning(FactLog) << kMissingMetadata << name();
530 return QString();
531 }
532}
533
534QString Fact::label() const
535{
536 if (_metaData) {
537 // Fall back for older metadata which is missing a label
538 if (!_metaData->label().isEmpty()) {
539 return _metaData->label();
540 }
541 if (!_metaData->shortDescription().isEmpty()) {
542 return _metaData->shortDescription();
543 }
544 return name();
545 } else {
546 qCWarning(FactLog) << kMissingMetadata << name();
547 return QString();
548 }
549}
550
552{
553 if (_metaData) {
554 return _metaData->longDescription();
555 } else {
556 qCWarning(FactLog) << kMissingMetadata << name();
557 return QString();
558 }
559}
560
561QString Fact::rawUnits() const
562{
563 if (_metaData) {
564 return _metaData->rawUnits();
565 } else {
566 qCWarning(FactLog) << kMissingMetadata << name();
567 return QString();
568 }
569}
570
571QString Fact::cookedUnits() const
572{
573 if (_metaData) {
574 return _metaData->cookedUnits();
575 } else {
576 qCWarning(FactLog) << kMissingMetadata << name();
577 return QString();
578 }
579}
580
581QVariant Fact::rawMin() const
582{
583 if (_metaData) {
584 return _metaData->rawMin();
585 } else {
586 qCWarning(FactLog) << kMissingMetadata << name();
587 return QVariant(0);
588 }
589}
590
591QVariant Fact::cookedMin() const
592{
593 if (_metaData) {
594 return _metaData->cookedMin();
595 } else {
596 qCWarning(FactLog) << kMissingMetadata << name();
597 return QVariant(0);
598 }
599}
600
601QVariant Fact::rawUserMin() const
602{
603 if (_metaData) {
604 return _metaData->rawUserMin();
605 }
606
607 qCWarning(FactLog) << kMissingMetadata << name();
608 return QVariant(0);
609}
610
611QVariant Fact::cookedUserMin() const
612{
613 if (_metaData) {
614 return _metaData->cookedUserMin();
615 }
616
617 qCWarning(FactLog) << kMissingMetadata << name();
618 return QVariant(0);
619}
620
622{
624}
625
627{
629}
630
631QVariant Fact::rawMax() const
632{
633 if (_metaData) {
634 return _metaData->rawMax();
635 } else {
636 qCWarning(FactLog) << kMissingMetadata << name();
637 return QVariant(0);
638 }
639}
640
641QVariant Fact::cookedMax() const
642{
643 if (_metaData) {
644 return _metaData->cookedMax();
645 } else {
646 qCWarning(FactLog) << kMissingMetadata << name();
647 return QVariant(0);
648 }
649}
650
651QVariant Fact::rawUserMax() const
652{
653 if (_metaData) {
654 return _metaData->rawUserMax();
655 }
656
657 qCWarning(FactLog) << kMissingMetadata << name();
658 return QVariant(0);
659}
660
661QVariant Fact::cookedUserMax() const
662{
663 if (_metaData) {
664 return _metaData->cookedUserMax();
665 }
666
667 qCWarning(FactLog) << kMissingMetadata << name();
668 return QVariant(0);
669}
670
672{
674}
675
677{
679}
680
682{
683 if (_metaData) {
685 } else {
686 qCWarning(FactLog) << kMissingMetadata << name();
687 return false;
688 }
689}
690
692{
693 if (_metaData) {
695 } else {
696 qCWarning(FactLog) << kMissingMetadata << name();
697 return false;
698 }
699}
700
702{
703 if (_metaData) {
704 return _metaData->decimalPlaces();
705 } else {
706 qCWarning(FactLog) << kMissingMetadata << name();
708 }
709}
710
712{
713 if (_metaData) {
714 return _metaData->maxStringLength();
715 } else {
716 qCWarning(FactLog) << kMissingMetadata << name();
717 return 0;
718 }
719}
720
721QString Fact::category() const
722{
723 if (_metaData) {
724 return _metaData->category();
725 } else {
726 qCWarning(FactLog) << kMissingMetadata << name();
727 return QString();
728 }
729}
730
731QString Fact::group() const
732{
733 if (_metaData) {
734 return _metaData->group();
735 } else {
736 qCWarning(FactLog) << kMissingMetadata << name();
737 return QString();
738 }
739}
740
741void Fact::setMetaData(FactMetaData *metaData, bool setDefaultFromMetaData)
742{
744 if (setDefaultFromMetaData && metaData->defaultValueAvailable()) {
746 }
748}
749
751{
752 if (_metaData) {
754 return _metaData->rawDefaultValue() == rawValue();
755 } else {
756 return false;
757 }
758 } else {
759 qCWarning(FactLog) << kMissingMetadata << name();
760 return false;
761 }
762}
763
765{
766 if (_metaData) {
768 } else {
769 qCWarning(FactLog) << kMissingMetadata << name();
770 return false;
771 }
772}
773
774QString Fact::validate(const QString &cookedValue, bool convertOnly)
775{
776 if (_metaData) {
777 QVariant typedValue;
778 QString errorString;
779
780 _metaData->convertAndValidateCooked(cookedValue, convertOnly, typedValue, errorString);
781
782 return errorString;
783 } else {
784 qCWarning(FactLog) << kMissingMetadata << name();
785 return QStringLiteral("Internal error: Meta data pointer missing");
786 }
787}
788
789QVariant Fact::clamp(const QString &cookedValue)
790{
791 if (_metaData) {
792 QVariant typedValue;
793 if (_metaData->clampValue(cookedValue, typedValue)) {
794 return typedValue;
795 } else {
796 //-- If conversion failed, return current value
797 return rawValue();
798 }
799 } else {
800 qCWarning(FactLog) << kMissingMetadata << name();
801 }
802 return QVariant();
803}
804
806{
807 if (_metaData) {
809 } else {
810 qCWarning(FactLog) << kMissingMetadata << name();
811 return false;
812 }
813}
814
816{
817 if (_metaData) {
819 } else {
820 qCWarning(FactLog) << kMissingMetadata << name();
821 return false;
822 }
823}
824
832
833void Fact::_sendValueChangedSignal(const QVariant &value)
834{
836 emit valueChanged(value);
838 } else {
840 }
841}
842
850
852{
853 if (_metaData) {
854 if (_metaData->enumStrings().count()) {
855 return enumStringValue();
856 } else {
857 return cookedValueString();
858 }
859 } else {
860 qCWarning(FactLog) << kMissingMetadata << name();
861 }
862 return QString();
863}
864
865double Fact::rawIncrement() const
866{
867 if (_metaData) {
868 return _metaData->rawIncrement();
869 } else {
870 qCWarning(FactLog) << kMissingMetadata << name();
871 }
872 return std::numeric_limits<double>::quiet_NaN();
873}
874
876{
877 if (_metaData) {
878 return _metaData->cookedIncrement();
879 } else {
880 qCWarning(FactLog) << kMissingMetadata << name();
881 }
882 return std::numeric_limits<double>::quiet_NaN();
883}
884
886{
887 if (_metaData) {
888 return _metaData->hasControl();
889 } else {
890 qCWarning(FactLog) << kMissingMetadata << name();
891 return false;
892 }
893}
894
895bool Fact::readOnly() const
896{
897 if (_metaData) {
898 return _metaData->readOnly();
899 } else {
900 qCWarning(FactLog) << kMissingMetadata << name();
901 return false;
902 }
903}
904
905bool Fact::writeOnly() const
906{
907 if (_metaData) {
908 return _metaData->writeOnly();
909 } else {
910 qCWarning(FactLog) << kMissingMetadata << name();
911 return false;
912 }
913}
914
916{
917 if (_metaData) {
918 return _metaData->volatileValue();
919 } else {
920 qCWarning(FactLog) << kMissingMetadata << name();
921 return false;
922 }
923}
924
933
934void Fact::_checkForRebootMessaging()
935{
936 if (qgcApp()) {
937 // showAppMessage() logs during unit tests (and additionally shows the real
938 // dialog in UI test mode), so tests assert this messaging via expectAppMessage()
939 if (vehicleRebootRequired()) {
940 QGC::showRebootVehicleMessage(tr("Reboot vehicle for changes to take effect."));
941 } else if (qgcRebootRequired()) {
942 QGC::showRebootAppMessage(tr("Restart application for changes to take effect."));
943 }
944 }
945}
#define qgcApp()
QString errorString
#define QGC_LOGGING_CATEGORY(name, categoryStr)
Holds the meta data associated with a Fact.
QString label() const
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
int maxStringLength() const
Maximum string length for valueTypeString facts. 0 means no limit.
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:17
bool _sendValueChangedSignals
Definition Fact.h:214
QString _name
Definition Fact.h:208
QStringList bitmaskStrings() const
Definition Fact.cc:323
bool writeOnly() const
Definition Fact.cc:905
int valueIndex(const QString &value) const
Definition Fact.cc:172
Q_INVOKABLE FactValueSliderListModel * valueSliderModel()
Definition Fact.cc:925
int enumIndex()
Definition Fact.cc:261
QString enumOrValueString()
Definition Fact.cc:851
void setMetaData(FactMetaData *metaData, bool setDefaultFromMetaData=false)
Definition Fact.cc:741
QStringList selectedBitmaskStrings() const
Provide a list of selected strings based on the fact value with the bitmaskString/bitmaskValues map.
Definition Fact.cc:343
QString cookedUnits() const
Definition Fact.cc:571
bool qgcRebootRequired() const
Definition Fact.cc:815
QString longDescription() const
Definition Fact.cc:551
Fact(QObject *parent=nullptr)
Definition Fact.cc:17
virtual ~Fact()
Definition Fact.cc:76
bool _deferredValueChangeSignal
Definition Fact.h:215
Q_INVOKABLE QVariant rawToCooked(const QVariant &rawValue) const
Definition Fact.cc:237
QVariant cookedValue() const
Definition Fact.cc:226
void sendValueChangedSignalsChanged(bool sendValueChangedSignals)
QString shortDescription() const
Definition Fact.cc:524
void containerSetRawValue(const QVariant &value)
Value coming from Vehicle. This does NOT send a _containerRawValueChanged signal.
Definition Fact.cc:198
FactMetaData * _metaData
Definition Fact.h:213
QVariantList enumValues() const
Definition Fact.cc:303
QString cookedMaxString() const
Definition Fact.cc:671
FactMetaData * metaData()
Definition Fact.h:177
QVariant rawDefaultValue() const
Definition Fact.cc:493
bool valueEqualsDefault() const
Definition Fact.cc:750
FactMetaData::ValueType_t _type
Definition Fact.h:212
double rawIncrement() const
Definition Fact.cc:865
bool maxIsDefaultForType() const
Definition Fact.cc:691
bool readOnly() const
Definition Fact.cc:895
QString cookedMinString() const
Definition Fact.cc:621
QString cookedUserMinString() const
Definition Fact.cc:626
void setEnumInfo(const QStringList &strings, const QVariantList &values)
Generally this is done during parsing. But if you know what you are doing, you can.
Definition Fact.cc:313
void sendDeferredValueChangedSignal()
Definition Fact.cc:843
QVariant cookedUserMax() const
Definition Fact.cc:661
QString invalidValueString() const
Definition Fact.h:134
void rawValueChanged(const QVariant &value)
QRecursiveMutex _rawValueMutex
Definition Fact.h:211
QString cookedUserMaxString() const
Definition Fact.cc:676
static constexpr const char * kMissingMetadata
Definition Fact.h:218
QString group() const
Definition Fact.cc:731
FactMetaData::ValueType_t type() const
Definition Fact.h:130
void setSendValueChangedSignals(bool sendValueChangedSignals)
Definition Fact.cc:825
QVariant cookedUserMin() const
Definition Fact.cc:611
QString cookedDefaultValueString() const
Definition Fact.cc:519
const Fact & operator=(const Fact &other)
Definition Fact.cc:86
QVariant cookedMin() const
Definition Fact.cc:591
double cookedIncrement() const
Definition Fact.cc:875
void setRawValue(const QVariant &value)
Definition Fact.cc:134
QString rawValueString() const
Definition Fact.cc:483
void setEnumIndex(int index)
Definition Fact.cc:189
bool sendValueChangedSignals() const
Definition Fact.h:164
bool defaultValueAvailable() const
Definition Fact.cc:764
QVariant rawUserMax() const
Definition Fact.cc:651
bool volatileValue() const
Definition Fact.cc:915
QVariant rawMax() const
Definition Fact.cc:631
void forceSetRawValue(const QVariant &value)
Sets and sends new value to vehicle even if value is the same.
Definition Fact.cc:111
int decimalPlaces() const
Definition Fact.cc:701
QStringList enumStrings() const
Definition Fact.cc:293
QString cookedValueString() const
Definition Fact.cc:488
QString name() const
Definition Fact.h:127
void containerRawValueChanged(const QVariant &value)
This signal is meant for use by Fact container implementations. Used to send changed values to vehicl...
QString rawValueStringFullPrecision() const
Returns the values as a string with full 18 digit precision if float/double.
Definition Fact.cc:445
QVariantList bitmaskValues() const
Definition Fact.cc:333
QVariant cookedMax() const
Definition Fact.cc:641
QVariant rawMin() const
Definition Fact.cc:581
Q_INVOKABLE QString validate(const QString &cookedValue, bool convertOnly)
Definition Fact.cc:774
void setEnumStringValue(const QString &value)
Definition Fact.cc:181
int _componentId
Definition Fact.h:209
QString rawUnits() const
Definition Fact.cc:561
Q_INVOKABLE QVariant clamp(const QString &cookedValue)
Convert and clamp value.
Definition Fact.cc:789
QString _variantToString(const QVariant &variant, int decimalPlaces) const
Definition Fact.cc:371
FactValueSliderListModel * _valueSliderModel
Definition Fact.h:216
QVariant cookedDefaultValue() const
Definition Fact.cc:506
QString category() const
Definition Fact.cc:721
bool minIsDefaultForType() const
Definition Fact.cc:681
QVariant _rawValue
Definition Fact.h:210
void _sendValueChangedSignal(const QVariant &value)
Definition Fact.cc:833
int maxStringLength() const
Definition Fact.cc:711
void setCookedValue(const QVariant &value)
Definition Fact.cc:163
QVariant rawUserMin() const
Definition Fact.cc:601
void enumsChanged()
QString enumStringValue()
Definition Fact.cc:247
QString label() const
Definition Fact.cc:534
void vehicleUpdated(const QVariant &value)
Signalled when the param write ack comes back from the vehicle.
bool hasControl() const
Definition Fact.cc:885
bool vehicleRebootRequired() const
Definition Fact.cc:805
QVariant rawValue() const
Definition Fact.h:90
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 ...
static void adjustSettingMetaData(const QString &settingsGroup, FactMetaData &metaData, bool &userVisible)
bool runningUnitTests()
void showRebootVehicleMessage(const QString &message, const QString &title)
Modal vehicle-reboot-required message with a reboot button. Debounced within 2 minutes.
void showRebootAppMessage(const QString &message, const QString &title)
Modal reboot-required message. Debounced within 2 minutes.