QGCParamWidget.cc 19.9 KB
Newer Older
1 2 3 4
/*=====================================================================

QGroundControl Open Source Ground Control Station

pixhawk's avatar
pixhawk committed
5
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

======================================================================*/
/**
 * @file
 *   @brief Implementation of class QGCParamWidget
 *   @author Lorenz Meier <mail@qgroundcontrol.org>
 */
Lorenz Meier's avatar
Lorenz Meier committed
28 29
#include <cmath>
#include <float.h>
tstellanova's avatar
tstellanova committed
30 31
#include <QApplication>
#include <QDebug>
32
#include <QFile>
tstellanova's avatar
tstellanova committed
33 34
#include <QGridLayout>

35
#include <QList>
tstellanova's avatar
tstellanova committed
36 37 38
#include <QPushButton>
#include <QSettings>
#include <QTime>
39 40
#include <QTimer>
#include <QEventLoop>
pixhawk's avatar
pixhawk committed
41

Lorenz Meier's avatar
Lorenz Meier committed
42
#include "MainWindow.h"
43
#include "QGC.h"
tstellanova's avatar
tstellanova committed
44 45 46
#include "QGCParamWidget.h"
#include "UASInterface.h"
#include "UASParameterCommsMgr.h"
47
#include "QGCMapRCToParamDialog.h"
pixhawk's avatar
pixhawk committed
48

49 50 51 52
/**
 * @param uas MAV to set the parameters on
 * @param parent Parent widget
 */
53 54
QGCParamWidget::QGCParamWidget(QWidget *parent) :
    QGCBaseParamWidget(parent),
55 56
    componentItems(new QMap<int, QTreeWidgetItem*>()),
    statusLabel(new QLabel(this)),
57
    tree(new QGCParamTreeWidget(this)),
58
    _fullParamListLoaded(false)
pixhawk's avatar
pixhawk committed
59
{
lm's avatar
lm committed
60

61

62 63 64
}


65

66 67 68 69
void QGCParamWidget::disconnectViewSignalsAndSlots()
{
    disconnect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
            this, SLOT(parameterItemChanged(QTreeWidgetItem*,int)));
70 71
    disconnect(tree, &QGCParamTreeWidget::mapRCToParamRequest, this,
            &QGCParamWidget::configureRCToParam);
72
}
73 74


75 76
void QGCParamWidget::connectViewSignalsAndSlots()
{
77 78 79
    // Listen for edits to the tree UI
    connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
            this, SLOT(parameterItemChanged(QTreeWidgetItem*,int)));
80 81
    connect(tree, &QGCParamTreeWidget::mapRCToParamRequest, this,
            &QGCParamWidget::configureRCToParam);
82 83
    connect(tree, &QGCParamTreeWidget::refreshParamRequest, this,
            &QGCParamWidget::requestOnboardParamUpdate);
84 85
}

86

87
void QGCParamWidget::addActionButtonsToLayout(QGridLayout* layout)
88
{
Jessica's avatar
Jessica committed
89
    QPushButton* refreshButton = new QPushButton(tr("Get"));
90 91
    refreshButton->setToolTip(tr("Fetch parameters currently in volatile memory of aircraft."));
    refreshButton->setWhatsThis(tr("Fetch parameters currently in volatile memory of aircraft."));
92 93
    connect(refreshButton, SIGNAL(clicked()),
            this, SLOT(requestOnboardParamsUpdate()));
94
    layout->addWidget(refreshButton, 2, 0);
95

Jessica's avatar
Jessica committed
96
    QPushButton* setButton = new QPushButton(tr("Set"));
97 98
    setButton->setToolTip(tr("Send pending parameters to volatile onboard memory"));
    setButton->setWhatsThis(tr("Send pending parameters to volatile onboard memory"));
tstellanova's avatar
tstellanova committed
99
    connect(setButton, SIGNAL(clicked()),
100
            paramMgr, SLOT(sendPendingParameters()));
101
    layout->addWidget(setButton, 2, 1);
102

103
    QPushButton* writeButton = new QPushButton(tr("Write (ROM)"));
104 105
    writeButton->setToolTip(tr("Copy parameters in volatile memory of the aircraft to persistent memory. Transmit your parameters first to write these."));
    writeButton->setWhatsThis(tr("Copy parameters in volatile memory of the aircraft to persistent memory. Transmit your parameters first to write these."));
106 107
    connect(writeButton, SIGNAL(clicked()),
            paramMgr, SLOT(copyVolatileParamsToPersistent()));
108
    layout->addWidget(writeButton, 2, 2);
109

110
    QPushButton* loadFileButton = new QPushButton(tr("Load File"));
111 112
    loadFileButton->setToolTip(tr("Load parameters from a file into qgroundcontrol. To write these to the aircraft, use transmit after loading them."));
    loadFileButton->setWhatsThis(tr("Load parameters from a file into qgroundcontrol. To write these to the aircraft, use transmit after loading them."));
113 114
    connect(loadFileButton, SIGNAL(clicked()),
            this, SLOT(loadParametersFromFile()));
115
    layout->addWidget(loadFileButton, 3, 0);
116 117

    QPushButton* saveFileButton = new QPushButton(tr("Save File"));
118 119
    saveFileButton->setToolTip(tr("Save parameters in this view to a file on this computer."));
    saveFileButton->setWhatsThis(tr("Save parameters in this view to a file on this computer."));
120 121
    connect(saveFileButton, SIGNAL(clicked()),
            this, SLOT(saveParametersToFile()));
122
    layout->addWidget(saveFileButton, 3, 1);
lm's avatar
lm committed
123 124

    QPushButton* readButton = new QPushButton(tr("Read (ROM)"));
125 126
    readButton->setToolTip(tr("Copy parameters from persistent onboard memory to volatile onboard memory of aircraft. DOES NOT update the parameters in this view: click refresh after copying them to get them."));
    readButton->setWhatsThis(tr("Copy parameters from persistent onboard memory to volatile onboard memory of aircraft. DOES NOT update the parameters in this view: click refresh after copying them to get them."));
127 128
    connect(readButton, SIGNAL(clicked()),
            paramMgr, SLOT(copyPersistentParamsToVolatile()));
129 130
    layout->addWidget(readButton, 3, 2);

131 132 133 134 135 136 137
    QPushButton* unsetRCToParamMapButton = new QPushButton(tr("Clear Rc to Param"));
    unsetRCToParamMapButton->setToolTip(tr("Remove any bindings between RC channels and parameters."));
    unsetRCToParamMapButton->setWhatsThis(tr("Remove any bindings between RC channels and parameters."));
    connect(unsetRCToParamMapButton, &QPushButton::clicked,
            mav, &UASInterface::unsetRCToParameterMap);
    layout->addWidget(unsetRCToParamMapButton, 4, 1);

138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
}

void QGCParamWidget::layoutWidget()
{

    statusLabel->setAutoFillBackground(true);

    QGridLayout* layout = new QGridLayout(this);
    layout->setHorizontalSpacing(6);
    layout->setVerticalSpacing(6);
    layout->setMargin(0);
    layout->setSizeConstraint(QLayout::SetMinimumSize);

    // Parameter tree
    layout->addWidget(tree, 0, 0, 1, 3);

    // Status line
    statusLabel->setText(tr("Click refresh to download parameters"));
    layout->addWidget(statusLabel, 1, 0, 1, 3);

    // BUTTONS
    addActionButtonsToLayout(layout);
160

161
    // Set correct vertical scaling
162 163 164 165
    layout->setRowStretch(0, 100);
    layout->setRowStretch(1, 10);
    layout->setRowStretch(2, 10);
    layout->setRowStretch(3, 10);
166

167
    // Set layout
168
    this->setLayout(layout);
pixhawk's avatar
pixhawk committed
169 170 171 172 173 174 175

    // Set header
    QStringList headerItems;
    headerItems.append("Parameter");
    headerItems.append("Value");
    tree->setHeaderLabels(headerItems);
    tree->setColumnCount(2);
tstellanova's avatar
tstellanova committed
176
    tree->setColumnWidth(0,200);
177
    tree->setColumnWidth(1,120);
178
    tree->setExpandsOnDoubleClick(true);
179

180
    tree->setVisible(true);
pixhawk's avatar
pixhawk committed
181 182
}

tstellanova's avatar
tstellanova committed
183

tstellanova's avatar
tstellanova committed
184
void QGCParamWidget::addComponentItem(int compId, QString compName)
pixhawk's avatar
pixhawk committed
185
{
tstellanova's avatar
tstellanova committed
186

187 188
    QString compLine = QString("%1 (#%2)").arg(compName).arg(compId);

189 190
    //QString ptrStr = QString().sprintf("%8p", this);
    //qDebug() <<  "QGCParamWidget" << ptrStr << "addComponentItem:" << compLine;
191

tstellanova's avatar
tstellanova committed
192
    if (componentItems->contains(compId)) {
193 194
        // Update existing component item
        componentItems->value(compId)->setData(0, Qt::DisplayRole, compLine);
195
        //components->value(component)->setData(1, Qt::DisplayRole, QString::number(component));
tstellanova's avatar
tstellanova committed
196
        componentItems->value(compId)->setFirstColumnSpanned(true);
197
    } else {
198 199 200 201 202 203
        // Add new component item
        QStringList list(compLine);
        QTreeWidgetItem* compItem = new QTreeWidgetItem(list);
        compItem->setFirstColumnSpanned(true);
        componentItems->insert(compId, compItem);
        // Create parameter grouping for this component and update maps
tstellanova's avatar
tstellanova committed
204
        paramGroups.insert(compId, new QMap<QString, QTreeWidgetItem*>());
205
        tree->addTopLevelItem(compItem);
pixhawk's avatar
pixhawk committed
206 207
        tree->update();
    }
208

pixhawk's avatar
pixhawk committed
209 210
}

211 212
void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending)
{
213
    //qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock;
214

215
    if (updatingParamNameLock == paramName) {
216
        //qDebug() << "ignoring bounce from " << paramName;
217 218 219 220
        return;
    }
    else {
        updatingParamNameLock = paramName;
221 222
    }

223
    QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value);
Don Gagne's avatar
Don Gagne committed
224 225 226 227 228 229 230 231 232 233 234
    if (paramItem) {
        if (isPending) {
            paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange)));
            paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange)));
            //ensure that the adjusted item is visible
            tree->expandItem(paramItem->parent());
        }
        else {
            paramItem->setBackground(0, Qt::NoBrush);
            paramItem->setBackground(1, Qt::NoBrush);
        }
235 236
    }

237 238
    updatingParamNameLock.clear();

239
}
tstellanova's avatar
tstellanova committed
240

241
void QGCParamWidget::handleOnboardParamUpdate(int compId, const QString& paramName, QVariant value)
lm's avatar
lm committed
242
{
243
    //qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock;
244
    if (paramName == updatingParamNameLock) {
245
        //qDebug() << "handlePendingParamUpdate ignoring bounce from " << paramName;
246 247
        return;
    }
248
    updatingParamNameLock = paramName;
249
    updateParameterDisplay(compId, paramName, value);
250
    updatingParamNameLock.clear();
tstellanova's avatar
tstellanova committed
251
}
252

253

254
void QGCParamWidget::handleOnboardParameterListUpToDate()
tstellanova's avatar
tstellanova committed
255
{
256 257 258 259
    // Don't load full param list more than once
    if (_fullParamListLoaded) {
        return;
    }
260

261
    _fullParamListLoaded = true;
262

263 264
    //turn off updates while we refresh the entire list
    tree->setUpdatesEnabled(false);
265 266 267

    //rewrite the component item tree after receiving the full list
    QMap<int, QMap<QString, QVariant>*>::iterator i;
268
    QMap<int, QMap<QString, QVariant>*>* onboardParams = paramMgr->dataModel()->getAllOnboardParams();
269 270 271 272 273 274

    for (i = onboardParams->begin(); i != onboardParams->end(); ++i) {
        int compId = i.key();
        QMap<QString, QVariant>* paramPairs = onboardParams->value(compId);
        QMap<QString, QVariant>::iterator j;
        for (j = paramPairs->begin(); j != paramPairs->end(); j++) {
275
            updatingParamNameLock = j.key();
276
            updateParameterDisplay(compId, j.key(),j.value());
277
            updatingParamNameLock.clear();
278 279 280
        }
    }

tstellanova's avatar
tstellanova committed
281 282
    // Expand visual tree
    tree->expandItem(tree->topLevelItem(0));
283 284 285
    tree->setUpdatesEnabled(true);
    tree->update();

lm's avatar
lm committed
286 287
}

288
QTreeWidgetItem* QGCParamWidget::findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName)
tstellanova's avatar
tstellanova committed
289
{
290 291 292 293 294 295 296 297 298
    QTreeWidgetItem* childItem = NULL;

    for (int i = 0; i < parentItem->childCount(); i++) {
        QTreeWidgetItem* child = parentItem->child(i);
        QString key = child->data(0, Qt::DisplayRole).toString();
        if (key == paramName)  {
            childItem = child;
            break;
        }
pixhawk's avatar
pixhawk committed
299
    }
300

301 302 303 304 305
    return childItem;
}

QTreeWidgetItem* QGCParamWidget::getParentWidgetItemForParam(int compId, const QString& paramName)
{
306 307
    QTreeWidgetItem* parentItem = componentItems->value(compId);

pixhawk's avatar
pixhawk committed
308 309
    QString splitToken = "_";
    // Check if auto-grouping can work
310 311
    if (paramName.contains(splitToken)) {
        QString parentStr = paramName.section(splitToken, 0, 0, QString::SectionSkipEmpty);
tstellanova's avatar
tstellanova committed
312 313
        QMap<QString, QTreeWidgetItem*>* compParamGroups = paramGroups.value(compId);
        if (!compParamGroups->contains(parentStr)) {
pixhawk's avatar
pixhawk committed
314 315
            // Insert group item
            QStringList glist;
tstellanova's avatar
tstellanova committed
316
            glist.append(parentStr);
317
            QTreeWidgetItem* groupItem = new QTreeWidgetItem(glist);
tstellanova's avatar
tstellanova committed
318 319 320 321 322 323 324

            compParamGroups->insert(parentStr, groupItem);

            // insert new group alphabetized
            QList<QString> groupKeys = compParamGroups->uniqueKeys();
            int insertIdx = groupKeys.indexOf(parentStr);
            componentItems->value(compId)->insertChild(insertIdx,groupItem);
325
        }
326

327
        //parent item for this parameter item will be a group widget item
328 329 330
        parentItem = compParamGroups->value(parentStr);
    }
    else  {
331
        //parent item for this parameter will be the top level (component) widget item
332 333 334
        parentItem = componentItems->value(compId);
    }

335 336
    return parentItem;
}
337

338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
void QGCParamWidget::insertParamAlphabetical(int indexLowerBound, int indexUpperBound, QTreeWidgetItem* parentItem, QTreeWidgetItem* paramItem)
{
    if (indexLowerBound >= indexUpperBound)
    {
        if (paramItem->text(0).compare(parentItem->child(indexLowerBound)->text(0)) < 0) {
            parentItem->insertChild(indexLowerBound, paramItem);
        }
        else
        {
            if (indexLowerBound < parentItem->childCount() - 1) {
                parentItem->insertChild(indexLowerBound + 1, paramItem);
            }
            else
            {
                parentItem->addChild(paramItem);
            }
        }
    }
    else
    {
Don Gagne's avatar
Don Gagne committed
358
        int midpoint = indexLowerBound + ((indexUpperBound - indexLowerBound) / 2);
359 360 361 362 363 364 365 366 367 368 369 370

        if (paramItem->text(0).compare(parentItem->child(midpoint)->text(0)) < 0)
        {
            insertParamAlphabetical(indexLowerBound, midpoint - 1, parentItem, paramItem);
        } else
        {
            insertParamAlphabetical(midpoint + 1, indexUpperBound, parentItem, paramItem);
        }

    }
}

371 372
QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, QVariant value)
{
373
    //qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName;
374

Don Gagne's avatar
Don Gagne committed
375 376 377 378 379 380 381 382 383 384
    // Filter the parameters according to the filter list
    if (_filterList.count() != 0) {
        bool filterFound = false;
        foreach(QString paramFilter, _filterList) {
            if (paramFilter.endsWith("*") && parameterName.startsWith(paramFilter.left(paramFilter.size() - 1))) {
                filterFound = true;
                break;
            }
            if (paramFilter == parameterName) {
                filterFound = true;
385
                break;
Don Gagne's avatar
Don Gagne committed
386 387 388 389 390 391
            }
        }
        if (!filterFound) {
            return NULL;
        }
    }
392 393

    // Reference to item in tree
394
    QTreeWidgetItem* paramItem = NULL;
395 396 397 398 399 400 401 402 403 404

    // Add component item if necessary
    if (!componentItems->contains(compId)) {
        QString componentName = tr("Component #%1").arg(compId);
        addComponentItem(compId, componentName);
    }

    //default parent item for this parameter widget item will be the top level component item
    QTreeWidgetItem* parentItem = getParentWidgetItemForParam(compId,parameterName);
    if (parentItem) {
405 406
        paramItem = findChildWidgetItemForParam(parentItem,parameterName);
        if (!paramItem) {
407 408 409
            // Insert parameter into map
            QStringList plist;
            plist.append(parameterName);
410
            // CREATE PARAMETER ITEM
411
            paramItem = new QTreeWidgetItem(plist);
412
            // CONFIGURE PARAMETER ITEM
tstellanova's avatar
tstellanova committed
413
            if (value.type() == QVariant::Char) {
414
                paramItem->setData(1, Qt::DisplayRole, value.toUInt());
415
            }
tstellanova's avatar
tstellanova committed
416
            else {
417
                paramItem->setData(1, Qt::DisplayRole, value);
418
            }
419
            paramItem->setFlags(paramItem->flags() | Qt::ItemIsEditable);
420

421
            //Insert alphabetically
422 423 424
            if (parentItem->childCount() > 0) {
                insertParamAlphabetical(0, parentItem->childCount() - 1, parentItem, paramItem);
            } else
425 426 427
            {
                parentItem->addChild(paramItem);
            }
428 429

            //only add the tooltip when the parameter item is first added
430
            QString paramDesc = paramMgr->dataModel()->getParamDescription(parameterName);
431 432
            if (!paramDesc.isEmpty()) {
                QString tooltipFormat;
433
                if (paramMgr->dataModel()->isParamDefaultKnown(parameterName)) {
434
                    tooltipFormat = tr("Default: %1, %2");
435
                    double paramDefValue = paramMgr->dataModel()->getParamDefault(parameterName);
436 437 438 439 440
                    tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc);
                }
                else {
                    tooltipFormat = paramDesc;
                }
441 442
                paramItem->setToolTip(0, tooltipFormat);
                paramItem->setToolTip(1, tooltipFormat);
443 444 445
            }
        }

446
        //update the parameterItem's data
447
        if (value.type() == QVariant::Char) {
448
            paramItem->setData(1, Qt::DisplayRole, value.toUInt());
449 450
        }
        else {
451
            paramItem->setData(1, Qt::DisplayRole, value);
pixhawk's avatar
pixhawk committed
452
        }
453

454
    }
455

456
    if (paramItem) {
457
        // Reset background color
458 459
        paramItem->setBackground(0, Qt::NoBrush);
        paramItem->setBackground(1, Qt::NoBrush);
460

461 462 463 464 465 466 467
        paramItem->setTextColor(0, QGC::colorDarkWhite);
        paramItem->setTextColor(1, QGC::colorDarkWhite);

        if (paramItem == tree->currentItem()) {
            //need to unset current item to clear highlighting (green by default)
            tree->setCurrentItem(NULL); //clear the selected line
        }
468

469
    }
470

471
    return paramItem;
pixhawk's avatar
pixhawk committed
472 473
}

lm's avatar
lm committed
474

475

476
void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column)
lm's avatar
lm committed
477
{
478
    if (paramItem && column > 0) {
479

480
        QString key = paramItem->data(0, Qt::DisplayRole).toString();
481
        //qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock;
482 483

        if (key == updatingParamNameLock) {
484
            //qDebug() << "parameterItemChanged ignoring bounce from " << key;
485 486
            return;
        }
487 488 489
        else {
            updatingParamNameLock = key;
        }
490 491

        QTreeWidgetItem* parent = paramItem->parent();
492
        while (parent->parent() != NULL) {
493 494 495
            parent = parent->parent();
        }
        // Parent is now top-level component
496
        int componentId = componentItems->key(parent);
497
        QVariant value = paramItem->data(1, Qt::DisplayRole);
498

499

500
        bool pending = paramMgr->dataModel()->updatePendingParamWithValue(componentId,key,value);
501

502 503
        // If the value will result in an update
        if (pending) {
504
            // Set parameter on changed list to be transmitted to MAV
505
            statusLabel->setText(tr("Pending: %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' ')));
506

507 508
            paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange)));
            paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange)));
509
        }
510
        else {
511
            QMap<QString , QVariant>* pendingParams = paramMgr->dataModel()->getPendingParamsForComponent(componentId);
512 513
            int pendingCount = pendingParams->count();
            statusLabel->setText(tr("Pending items: %1").arg(pendingCount));
514 515
            paramItem->setBackground(0, Qt::NoBrush);
            paramItem->setBackground(1, Qt::NoBrush);
516
        }
517

518 519 520 521 522 523

        if (paramItem == tree->currentItem()) {
            //need to unset current item to clear highlighting (green by default)
            tree->setCurrentItem(NULL); //clear the selected line
        }

524
        updatingParamNameLock.clear();
525 526 527
    }
}

tstellanova's avatar
tstellanova committed
528
void QGCParamWidget::setParameterStatusMsg(const QString& msg)
529
{
tstellanova's avatar
tstellanova committed
530 531 532
    statusLabel->setText(msg);
}

533

534
void QGCParamWidget::clearOnboardParamDisplay()
535
{
536 537
    tree->clear();
    componentItems->clear();
538 539
}

540
void QGCParamWidget::clearPendingParamDisplay()
pixhawk's avatar
pixhawk committed
541 542
{
    tree->clear();
543
    componentItems->clear();
pixhawk's avatar
pixhawk committed
544
}
tstellanova's avatar
tstellanova committed
545

546

tstellanova's avatar
tstellanova committed
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
void QGCParamWidget::handleParamStatusMsgUpdate(QString msg, int level)
{
    QColor bgColor = QGC::colorGreen;
    if ((int)UASParameterCommsMgr::ParamCommsStatusLevel_Warning == level) {
        bgColor = QGC::colorOrange;
    }
    else if ((int)UASParameterCommsMgr::ParamCommsStatusLevel_Error == level) {
        bgColor =  QGC::colorRed;
    }

    QPalette pal = statusLabel->palette();
    pal.setColor(backgroundRole(), bgColor);
    statusLabel->setPalette(pal);
    statusLabel->setText(msg);
}
562 563 564 565 566 567

void QGCParamWidget::configureRCToParam(QString param_id) {
    QGCMapRCToParamDialog * d = new QGCMapRCToParamDialog(param_id,
            mav, this);
    d->exec();
}