QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
ParameterEditorController.cc
Go to the documentation of this file.
3#include "AppMessages.h"
4#include "ParameterManager.h"
5#include "AppSettings.h"
6#include "SettingsManager.h"
7#include "Vehicle.h"
9
10QGC_LOGGING_CATEGORY(ParameterEditorControllerLog, "QMLControls.ParameterEditorController")
11
13 : QAbstractTableModel(parent)
14{
15
16}
17
22
23int ParameterTableModel::rowCount(const QModelIndex& /*parent*/) const
24{
25 return _tableData.count();
26}
27
28int ParameterTableModel::columnCount(const QModelIndex & /*parent*/) const
29{
30 return _tableViewColCount;
31}
32
33QVariant ParameterTableModel::data(const QModelIndex &index, int role) const
34{
35 if (!index.isValid()) {
36 return QVariant();
37 }
38
39 if (index.row() < 0 || index.row() >= _tableData.count()) {
40 return QVariant();
41 }
42 if (index.column() < 0 || index.column() >= _tableViewColCount) {
43 return QVariant();
44 }
45
46 switch (role) {
47 case Qt::DisplayRole:
48 return QVariant::fromValue(_tableData[index.row()][index.column()]);
49 case FactRole:
50 return QVariant::fromValue(_tableData[index.row()][ValueColumn]);
51 default:
52 return QVariant();
53 }
54}
55
56QVariant ParameterTableModel::headerData(int section, Qt::Orientation orientation, int role) const
57{
58 if (orientation != Qt::Horizontal || role != Qt::DisplayRole) {
59 return QVariant();
60 }
61
62 switch (section) {
63 case FavColumn: return tr("Fav");
64 case NameColumn: return tr("Name");
65 case ValueColumn: return tr("Value");
66 case DescriptionColumn: return tr("Description");
67 default: return QVariant();
68 }
69}
70
71QHash<int, QByteArray> ParameterTableModel::roleNames() const
72{
73 return {
74 {Qt::DisplayRole, "display"},
75 {FactRole, "fact"}
76 };
77}
78
80{
81 beginReset();
82 _tableData.clear();
83 endReset();
84}
85
87{
88 insert(rowCount(), fact);
89}
90
92{
93 if (row < 0 || row > rowCount()) {
94 qWarning() << "Invalid row row:rowCount" << row << rowCount() << Q_FUNC_INFO;
95 row = qMax(qMin(row, rowCount()), 0);
96 }
97
98 ColumnData colData(_tableViewColCount, QString());
99 colData[FavColumn] = QString();
100 colData[NameColumn] = fact->name();
101 colData[ValueColumn] = QVariant::fromValue(fact);
102 colData[DescriptionColumn] = fact->shortDescription();
103
104 if (!_isResetting()) {
105 beginInsertRows(QModelIndex(), row, row);
106 }
107 _tableData.insert(row, colData);
108 if (!_isResetting()) {
109 endInsertRows();
111 }
112}
113
115{
116 _resetNestingCount++;
117
118 if (_resetNestingCount == 1) {
119 beginResetModel();
120 }
121}
122
124{
125 if (_resetNestingCount == 0) {
126 qWarning() << "ParameterTableModel::endReset called without prior beginReset";
127 return;
128 }
129 _resetNestingCount--;
130 if (_resetNestingCount == 0) {
131 endResetModel();
133 }
134}
135
137{
138 if (row < 0 || row >= _tableData.count()) {
139 qWarning() << "Invalid row row:rowCount" << row << _tableData.count() << Q_FUNC_INFO;
140 return nullptr;
141 }
142
143 return _tableData[row][ValueColumn].value<Fact*>();
144}
145
146
148 : QObject(parent)
149{
150
151}
152
154 : FactPanelController(parent)
155 , _parameterMgr(_vehicle->parameterManager())
156{
157 // qCDebug(ParameterEditorControllerLog) << Q_FUNC_INFO << this;
158
159 _buildLists();
160
161 _searchTimer.setSingleShot(true);
162 _searchTimer.setInterval(300);
163
164 connect(this, &ParameterEditorController::currentCategoryChanged, this, &ParameterEditorController::_currentCategoryChanged);
165 connect(this, &ParameterEditorController::currentGroupChanged, this, &ParameterEditorController::_currentGroupChanged);
166 connect(this, &ParameterEditorController::searchTextChanged, this, &ParameterEditorController::_searchTextChanged);
167 connect(this, &ParameterEditorController::showModifiedOnlyChanged, this, &ParameterEditorController::_searchTextChanged);
168 connect(this, &ParameterEditorController::showFavoritesOnlyChanged, this, &ParameterEditorController::_searchTextChanged);
169 connect(this, &ParameterEditorController::hideReadOnlyChanged, this, &ParameterEditorController::_hideReadOnlyChanged);
170 connect(&_searchTimer, &QTimer::timeout, this, &ParameterEditorController::_performSearch);
171 connect(_parameterMgr, &ParameterManager::factAdded, this, &ParameterEditorController::_factAdded);
172
173 _loadFavorites();
174
175 ParameterEditorCategory* category = _categories.count() ? _categories.value<ParameterEditorCategory*>(0) : nullptr;
176 setCurrentCategory(category);
177}
178
180{
181 // qCDebug(ParameterEditorControllerLog) << Q_FUNC_INFO << this;
182}
183
184void ParameterEditorController::_buildListsForComponent(int compId)
185{
186 for (const QString& factName: _parameterMgr->parameterNames(compId)) {
187 Fact* fact = _parameterMgr->getParameter(compId, factName);
188
189 if (_hideReadOnly && fact->readOnly()) {
190 continue;
191 }
192
193 ParameterEditorCategory* category = nullptr;
194 if (_mapCategoryName2Category.contains(fact->category())) {
195 category = _mapCategoryName2Category[fact->category()];
196 } else {
197 category = new ParameterEditorCategory(this);
198 category->name = fact->category();
199 _mapCategoryName2Category[fact->category()] = category;
200 _categories.append(category);
201 }
202
203 ParameterEditorGroup* group = nullptr;
204 if (category->mapGroupName2Group.contains(fact->group())) {
205 group = category->mapGroupName2Group[fact->group()];
206 } else {
207 group = new ParameterEditorGroup(this);
208 group->componentId = compId;
209 group->name = fact->group();
210 category->mapGroupName2Group[fact->group()] = group;
211 category->groups.append(group);
212 }
213
214 group->facts.append(fact);
215 }
216}
217
218void ParameterEditorController::_buildLists(void)
219{
220 _currentCategory = nullptr;
221 _currentGroup = nullptr;
222 _parameters = nullptr;
223 _mapCategoryName2Category.clear();
224 _categories.clearAndDeleteContents();
225 emit parametersChanged();
226
227 // Autopilot component should always be first list
228 _buildListsForComponent(MAV_COMP_ID_AUTOPILOT1);
229
230 // "Standard" category should always be first
231 for (int i=0; i<_categories.count(); i++) {
232 ParameterEditorCategory* category = _categories.value<ParameterEditorCategory*>(i);
233 if (category->name == "Standard" && i != 0) {
234 _categories.removeAt(i);
235 _categories.insert(0, category);
236 break;
237 }
238 }
239
240 // Default category should always be last
241 for (int i=0; i<_categories.count(); i++) {
242 ParameterEditorCategory* category = _categories.value<ParameterEditorCategory*>(i);
243 if (category->name == FactMetaData::kDefaultCategory) {
244 if (i != _categories.count() - 1) {
245 _categories.removeAt(i);
246 _categories.append(category);
247 }
248 break;
249 }
250 }
251
252 // Now add other random components
253 for (int compId: _parameterMgr->componentIds()) {
254 if (compId != MAV_COMP_ID_AUTOPILOT1) {
255 _buildListsForComponent(compId);
256 }
257 }
258
259 // Default group should always be last
260 for (int i=0; i<_categories.count(); i++) {
261 ParameterEditorCategory* category = _categories.value<ParameterEditorCategory*>(i);
262 for (int j=0; j<category->groups.count(); j++) {
264 if (group->name == FactMetaData::kDefaultGroup) {
265 if (j != _categories.count() - 1) {
266 category->groups.removeAt(j);
267 category->groups.append(group);
268 }
269 break;
270 }
271 }
272 }
273}
274
275void ParameterEditorController::_factAdded(int compId, Fact* fact)
276{
277 if (_hideReadOnly && fact->readOnly()) {
278 return;
279 }
280
281 bool inserted = false;
282 ParameterEditorCategory* category = nullptr;
283
284 if (_mapCategoryName2Category.contains(fact->category())) {
285 category = _mapCategoryName2Category[fact->category()];
286 } else {
287 category = new ParameterEditorCategory(this);
288 category->name = fact->category();
289 _mapCategoryName2Category[fact->category()] = category;
290
291 // Insert in sorted order
292 inserted = false;
293 for (int i=0; i<_categories.count(); i++) {
294 if (_categories.value<ParameterEditorCategory*>(i)->name > category->name) {
295 _categories.insert(i, category);
296 inserted = true;
297 break;
298 }
299 }
300 if (!inserted) {
301 _categories.append(category);
302 }
303 }
304
305 ParameterEditorGroup* group = nullptr;
306 if (category->mapGroupName2Group.contains(fact->group())) {
307 group = category->mapGroupName2Group[fact->group()];
308 } else {
309 group = new ParameterEditorGroup(this);
310 group->componentId = compId;
311 group->name = fact->group();
312 category->mapGroupName2Group[fact->group()] = group;
313
314 // Insert in sorted order
315 QmlObjectListModel& groups = category->groups;
316 inserted = false;
317 for (int i=0; i<groups.count(); i++) {
318 if (groups.value<ParameterEditorGroup*>(i)->name > group->name) {
319 groups.insert(i, group);
320 inserted = true;
321 break;
322 }
323 }
324 if (!inserted) {
325 groups.append(group);
326 }
327 }
328
329 // Insert in sorted order
330 auto& facts = group->facts;
331 for (int i=0; i<facts.rowCount(); i++) {
332 if (facts.factAt(i)->name() > fact->name()) {
333 facts.insert(i, fact);
334 return;
335 }
336 }
337 facts.append(fact);
338}
339
340void ParameterEditorController::saveToFile(const QString& filename)
341{
342 if (!filename.isEmpty()) {
343 QString parameterFilename = filename;
344 if (!QFileInfo(filename).fileName().contains(".")) {
345 parameterFilename += QString(".%1").arg(AppSettings::parameterFileExtension);
346 }
347
348 QFile file(parameterFilename);
349
350 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
351 QGC::showAppMessage(tr("Unable to create file: %1").arg(parameterFilename));
352 return;
353 }
354
355 QTextStream stream(&file);
356 _parameterMgr->writeParametersToStream(stream);
357 file.close();
358 }
359}
360
362{
363 _diffList.clearAndDeleteContents();
364 _diffOtherVehicle = false;
365 _diffMultipleComponents = false;
366 _diffMissingParams.clear();
367
368 emit diffOtherVehicleChanged(_diffOtherVehicle);
369 emit diffMultipleComponentsChanged(_diffMultipleComponents);
370}
371
373{
374 for (int i=0; i<_diffList.count(); i++) {
375 ParameterEditorDiff* paramDiff = _diffList.value<ParameterEditorDiff*>(i);
376
377 if (paramDiff->load) {
378 if (paramDiff->noVehicleValue) {
379 _parameterMgr->_mavlinkParamSet(paramDiff->componentId, paramDiff->name, paramDiff->valueType, paramDiff->fileValueVar);
380 } else {
381 Fact* fact = _parameterMgr->getParameter(paramDiff->componentId, paramDiff->name);
382 fact->setRawValue(paramDiff->fileValueVar);
383 }
384 }
385 }
386}
387
389{
390 QFile file(filename);
391
392 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
393 QGC::showAppMessage(tr("Unable to open file: %1").arg(filename));
394 return false;
395 }
396
397 clearDiff();
398
399 QTextStream stream(&file);
400
401 int parsedLineCount = 0;
402 int firstComponentId = -1;
403 while (!stream.atEnd()) {
404 QString line = stream.readLine();
405 if (!line.startsWith("#") && !line.trimmed().isEmpty()) {
406 QStringList wpParams = line.trimmed().split(QRegularExpression("[\\t ,]+"));
407
408 int componentId = -1;
409 QString paramName;
410 QString fileValueStr;
411 int mavParamType = -1;
412 bool isMPFormat = false;
413
414 if (wpParams.size() == 5) {
415 // QGC tab-delimited: VehicleId ComponentId Name Value Type
416 int vehicleId = wpParams.at(0).toInt();
417 componentId = wpParams.at(1).toInt();
418 paramName = wpParams.at(2);
419 fileValueStr = wpParams.at(3);
420 mavParamType = wpParams.at(4).toInt();
421
422 if (_vehicle->id() != vehicleId) {
423 _diffOtherVehicle = true;
424 }
425 if (firstComponentId == -1) {
426 firstComponentId = componentId;
427 } else if (firstComponentId != componentId) {
428 _diffMultipleComponents = true;
429 }
430 } else if (wpParams.size() == 2) {
431 // Mission Planner 2-column: Name Value
432 paramName = wpParams.at(0);
433 fileValueStr = wpParams.at(1);
435 isMPFormat = true;
436 } else {
437 continue;
438 }
439
440 parsedLineCount++;
441
442 QString vehicleValueStr;
443 QString units;
444 QVariant fileValueVar = fileValueStr;
445 bool noVehicleValue = false;
446 bool readOnly = false;
447
448 if (_parameterMgr->parameterExists(componentId, paramName)) {
449 Fact* vehicleFact = _parameterMgr->getParameter(componentId, paramName);
450 FactMetaData* vehicleFactMetaData = vehicleFact->metaData();
451 Fact* fileFact = new Fact(vehicleFact->componentId(), vehicleFact->name(), vehicleFact->type(), this);
452
453 if (mavParamType == -1) {
454 mavParamType = ParameterManager::factTypeToMavType(vehicleFact->type());
455 }
456
457 // Turn off reboot messaging before setting value in fileFact
458 bool vehicleRebootRequired = vehicleFactMetaData->vehicleRebootRequired();
459 vehicleFactMetaData->setVehicleRebootRequired(false);
460 fileFact->setMetaData(vehicleFact->metaData());
461 fileFact->setRawValue(fileValueStr);
462 vehicleFactMetaData->setVehicleRebootRequired(vehicleRebootRequired);
463 readOnly = vehicleFact->readOnly();
464
465 if (vehicleFact->rawValue() == fileFact->rawValue()) {
466 continue;
467 }
468 fileValueStr = fileFact->enumOrValueString();
469 fileValueVar = fileFact->rawValue();
470 vehicleValueStr = vehicleFact->enumOrValueString();
471 units = vehicleFact->cookedUnits();
472 } else if (isMPFormat) {
473 // MP format: skip params not on vehicle and report them
474 _diffMissingParams.append(paramName);
475 continue;
476 } else {
477 noVehicleValue = true;
478 }
479
480 if (!readOnly) {
481 ParameterEditorDiff* paramDiff = new ParameterEditorDiff(this);
482
483 paramDiff->componentId = componentId;
484 paramDiff->name = paramName;
485 paramDiff->valueType = ParameterManager::mavTypeToFactType(static_cast<MAV_PARAM_TYPE>(mavParamType));
486 paramDiff->fileValue = fileValueStr;
487 paramDiff->fileValueVar = fileValueVar;
488 paramDiff->vehicleValue = vehicleValueStr;
489 paramDiff->noVehicleValue = noVehicleValue;
490 paramDiff->units = units;
491
492 _diffList.append(paramDiff);
493 }
494 }
495 }
496
497 file.close();
498
499 if (parsedLineCount == 0) {
500 QGC::showAppMessage(tr("No valid parameters found in file. Check that the file is in QGC or Mission Planner format."));
501 return false;
502 }
503
504 emit diffOtherVehicleChanged(_diffOtherVehicle);
505 emit diffMultipleComponentsChanged(_diffMultipleComponents);
506 if (!_diffMissingParams.isEmpty()) {
507 emit missingParamsFromFile(_diffMissingParams);
508 }
509
510 return true;
511}
512
514{
515 _parameterMgr->refreshAllParameters();
516}
517
523
529
530bool ParameterEditorController::_shouldShow(Fact* fact) const
531{
532 if (_hideReadOnly && fact->readOnly()) {
533 return false;
534 }
535 if (_showModifiedOnly) {
536 if (!fact->defaultValueAvailable() || fact->valueEqualsDefault()) {
537 return false;
538 }
539 }
540 if (_showFavoritesOnly) {
541 if (!_favoriteNames.contains(fact->name())) {
542 return false;
543 }
544 }
545 return true;
546}
547
548void ParameterEditorController::_searchTextChanged(void)
549{
550 _searchTimer.start();
551}
552
553void ParameterEditorController::_hideReadOnlyChanged(void)
554{
555 _buildLists();
556
557 ParameterEditorCategory* category = _categories.count() ? _categories.value<ParameterEditorCategory*>(0) : nullptr;
558 setCurrentCategory(category);
559
560 // Re-trigger search if active
561 if (!_searchText.isEmpty() || _showModifiedOnly) {
562 _performSearch();
563 }
564}
565
566void ParameterEditorController::_performSearch(void)
567{
568 QObjectList newParameterList;
569
570 QStringList rgSearchStrings = _searchText.split(' ', Qt::SkipEmptyParts);
571
572 if (rgSearchStrings.isEmpty() && !_showModifiedOnly && !_showFavoritesOnly) {
573 ParameterEditorCategory* category = _categories.count() ? _categories.value<ParameterEditorCategory*>(0) : nullptr;
574 setCurrentCategory(category);
575 _searchParameters.clear();
576 } else {
577 QVector<QRegularExpression> regexList;
578 regexList.reserve(rgSearchStrings.size());
579 for (const QString &searchItem : rgSearchStrings) {
580 QRegularExpression re(searchItem, QRegularExpression::CaseInsensitiveOption);
581 regexList.append(re.isValid() ? re : QRegularExpression());
582 }
583
584 _searchParameters.beginReset();
585 _searchParameters.clear();
586
587 for (int compId : _parameterMgr->componentIds()) {
588 for (const QString &paraName: _parameterMgr->parameterNames(compId)) {
589 Fact* fact = _parameterMgr->getParameter(compId, paraName);
590 bool matched = _shouldShow(fact);
591 // All of the search items must match in order for the parameter to be added to the list
592 if (matched) {
593 for (int i = 0; i < rgSearchStrings.size(); ++i) {
594 const QRegularExpression &re = regexList.at(i);
595 if (re.isValid()) {
596 if (!fact->name().contains(re) &&
597 !fact->shortDescription().contains(re) &&
598 !fact->longDescription().contains(re)) {
599 matched = false;
600 }
601 } else {
602 const QString &searchItem = rgSearchStrings.at(i);
603 if (!fact->name().contains(searchItem, Qt::CaseInsensitive) &&
604 !fact->shortDescription().contains(searchItem, Qt::CaseInsensitive) &&
605 !fact->longDescription().contains(searchItem, Qt::CaseInsensitive)) {
606 matched = false;
607 }
608 }
609 }
610 }
611 if (matched) {
612 _searchParameters.append(fact);
613 }
614 }
615 }
616
617 _searchParameters.endReset();
618
619 if (_parameters != &_searchParameters) {
620 _parameters = &_searchParameters;
621 emit parametersChanged();
622
623 _currentCategory = nullptr;
624 _currentGroup = nullptr;
625 }
626 }
627}
628
629void ParameterEditorController::_currentCategoryChanged(void)
630{
631 ParameterEditorGroup* group = nullptr;
632 if (_currentCategory) {
633 // Select first group when category changes
634 group = _currentCategory->groups.value<ParameterEditorGroup*>(0);
635 } else {
636 group = nullptr;
637 }
638 setCurrentGroup(group);
639}
640
641void ParameterEditorController::_currentGroupChanged(void)
642{
643 _parameters = _currentGroup ? &_currentGroup->facts : nullptr;
644 emit parametersChanged();
645}
646
648{
649 ParameterEditorCategory* category = qobject_cast<ParameterEditorCategory*>(currentCategory);
650 if (category != _currentCategory) {
651 _currentCategory = category;
653 }
654}
655
657{
658 ParameterEditorGroup* group = qobject_cast<ParameterEditorGroup*>(currentGroup);
659 if (group != _currentGroup) {
660 _currentGroup = group;
661 emit currentGroupChanged();
662 }
663}
664
666{
667 QStringList list(_favoriteNames.begin(), _favoriteNames.end());
668 list.sort();
669 return list;
670}
671
672void ParameterEditorController::toggleFavorite(const QString& paramName)
673{
674 if (_favoriteNames.contains(paramName)) {
675 _favoriteNames.remove(paramName);
676 } else {
677 _favoriteNames.insert(paramName);
678 }
679 _saveFavorites();
680 emit favoritesChanged();
681
682 if (_showFavoritesOnly) {
683 _performSearch();
684 }
685}
686
687bool ParameterEditorController::isFavorite(const QString& paramName) const
688{
689 return _favoriteNames.contains(paramName);
690}
691
693{
694 _favoriteNames.clear();
695 _saveFavorites();
696 emit favoritesChanged();
697
698 if (_showFavoritesOnly) {
699 _performSearch();
700 }
701}
702
703void ParameterEditorController::_loadFavorites()
704{
705 Fact* fact = SettingsManager::instance()->appSettings()->favoriteParameters();
706 const QStringList list = fact->rawValue().toString().split(",", Qt::SkipEmptyParts);
707 _favoriteNames = QSet<QString>(list.begin(), list.end());
708}
709
710void ParameterEditorController::_saveFavorites()
711{
712 QStringList list(_favoriteNames.begin(), _favoriteNames.end());
713 list.sort();
714 Fact* fact = SettingsManager::instance()->appSettings()->favoriteParameters();
715 fact->setRawValue(list.join(","));
716}
#define QGC_LOGGING_CATEGORY(name, categoryStr)
static constexpr const char * parameterFileExtension
Definition AppSettings.h:99
Holds the meta data associated with a Fact.
static constexpr const char * kDefaultGroup
static constexpr const char * kDefaultCategory
void setVehicleRebootRequired(bool rebootRequired)
bool vehicleRebootRequired() const
Used for handling missing Facts from C++ code.
A Fact is used to hold a single value within the system.
Definition Fact.h:17
QString enumOrValueString()
Definition Fact.cc:823
void setMetaData(FactMetaData *metaData, bool setDefaultFromMetaData=false)
Definition Fact.cc:713
QString cookedUnits() const
Definition Fact.cc:553
QString longDescription() const
Definition Fact.cc:533
QString shortDescription() const
Definition Fact.cc:513
FactMetaData * metaData()
Definition Fact.h:171
bool valueEqualsDefault() const
Definition Fact.cc:722
bool readOnly() const
Definition Fact.cc:867
int componentId() const
Definition Fact.h:90
QString group() const
Definition Fact.cc:703
FactMetaData::ValueType_t type() const
Definition Fact.h:124
void setRawValue(const QVariant &value)
Definition Fact.cc:134
bool defaultValueAvailable() const
Definition Fact.cc:736
QString name() const
Definition Fact.h:121
QString category() const
Definition Fact.cc:693
QVariant rawValue() const
Value after translation.
Definition Fact.h:85
QMap< QString, ParameterEditorGroup * > mapGroupName2Group
Q_INVOKABLE void resetAllToVehicleConfiguration(void)
void showFavoritesOnlyChanged(void)
Q_INVOKABLE bool buildDiffFromFile(const QString &filename)
void diffMultipleComponentsChanged(bool diffMultipleComponents)
Q_INVOKABLE void toggleFavorite(const QString &paramName)
Q_INVOKABLE void clearAllFavorites(void)
QStringList favoriteParameterNames(void) const
void setCurrentGroup(QObject *currentGroup)
Q_INVOKABLE void saveToFile(const QString &filename)
ParameterEditorController(QObject *parent=nullptr)
void searchTextChanged(QString searchText)
void currentCategoryChanged(void)
void diffOtherVehicleChanged(bool diffOtherVehicle)
void setCurrentCategory(QObject *currentCategory)
Q_INVOKABLE bool isFavorite(const QString &paramName) const
void showModifiedOnlyChanged(void)
void missingParamsFromFile(const QStringList &missingParams)
Q_INVOKABLE void resetAllToDefaults(void)
FactMetaData::ValueType_t valueType
bool parameterExists(int componentId, const QString &paramName) const
Fact * getParameter(int componentId, const QString &paramName)
void factAdded(int componentId, Fact *fact)
static FactMetaData::ValueType_t mavTypeToFactType(MAV_PARAM_TYPE mavType)
static constexpr int defaultComponentId
void refreshAllParameters(uint8_t componentID)
Re-request the full set of parameters from the autopilot.
static MAV_PARAM_TYPE factTypeToMavType(FactMetaData::ValueType_t factType)
void resetAllToVehicleConfiguration()
void writeParametersToStream(QTextStream &stream) const
QVector< QVariant > ColumnData
void insert(int row, Fact *fact)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QHash< int, QByteArray > roleNames(void) const override
void rowCountChanged(int count)
void endReset()
Supports nesting - only outermost call has effect.
void beginReset()
Supports nesting - only outermost call has effect.
void append(QObject *object)
Caller maintains responsibility for object ownership and deletion.
T value(int index) const
QObject * removeAt(int index)
int count() const override final
void clearAndDeleteContents() override final
Clears the list and calls deleteLater on each entry.
void insert(int index, QObject *object)
static SettingsManager * instance()
AppSettings * appSettings() const
int id() const
Definition Vehicle.h:429
void showAppMessage(const QString &message, const QString &title)
Modal application message. Queued if the UI isn't ready yet.
Definition AppMessages.cc:9