QGCToolBar.cc 28.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*=====================================================================

QGroundControl Open Source Ground Control Station

(c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

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/>.

======================================================================*/

#include <QToolButton>
#include <QLabel>
26
#include <QSpacerItem>
27
#include "SerialLink.h"
28
29
#include "QGCToolBar.h"
#include "UASManager.h"
lm's avatar
lm committed
30
#include "MainWindow.h"
31
32
33

QGCToolBar::QGCToolBar(QWidget *parent) :
    QToolBar(parent),
pixhawk's avatar
pixhawk committed
34
    mav(NULL),
Lorenz Meier's avatar
Lorenz Meier committed
35
    userBaudChoice(false),
Lorenz Meier's avatar
Lorenz Meier committed
36
    userPortChoice(false),
lm's avatar
lm committed
37
38
39
40
    changed(true),
    batteryPercent(0),
    batteryVoltage(0),
    wpId(0),
41
    wpDistance(0),
42
43
    altitudeMSL(0),
    altitudeRel(0),
44
    systemArmed(false),
45
    currentLink(NULL),
46
    firstAction(NULL)
47
{
48
    setObjectName("QGCToolBar");
49
    setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
lm's avatar
lm committed
50

51
52
    // Do not load UI, wait for actions
}
lm's avatar
lm committed
53

54
55
56
57
58
59
60
61
62
63
void QGCToolBar::globalPositionChanged(UASInterface* uas, double lat, double lon, double alt, quint64 usec)
{
    Q_UNUSED(uas);
    Q_UNUSED(lat);
    Q_UNUSED(lon);
    Q_UNUSED(usec);
    altitudeMSL = alt;
    changed = true;
}

64
65
66
67
68
69
70
71
void QGCToolBar::heartbeatTimeout(bool timeout, unsigned int ms)
{
    // set timeout label visible
    if (timeout)
    {
        // Alternate colors to increase visibility
        if ((ms / 1000) % 2 == 0)
        {
72
            toolBarTimeoutLabel->setStyleSheet(QString("QLabel {color: #000; background-color: #FF0037;}"));
73
74
75
        }
        else
        {
76
            toolBarTimeoutLabel->setStyleSheet(QString("QLabel {color: #FFF; background-color: #6B0017;}"));
77
78
        }
        toolBarTimeoutLabel->setText(tr("CONNECTION LOST: %1 s").arg((ms / 1000.0f), 2, 'f', 1, ' '));
79
        toolBarTimeoutAction->setVisible(true);
80
        toolBarMessageAction->setVisible(false);
Lorenz Meier's avatar
Lorenz Meier committed
81
        toolBarBatteryBarAction->setVisible(false);
82
83
84
85
    }
    else
    {
        // Check if loss text is present, reset once
86
        if (toolBarTimeoutAction->isVisible())
87
        {
88
            toolBarTimeoutAction->setVisible(false);
89
            toolBarMessageAction->setVisible(true);
Lorenz Meier's avatar
Lorenz Meier committed
90
            toolBarBatteryBarAction->setVisible(true);
91
92
93
        }
    }
}
lm's avatar
lm committed
94

95
96
void QGCToolBar::createUI()
{
97
98
99
100
101
102
    // CREATE TOOLBAR ITEMS
    // Add internal actions
    // Add MAV widget
    symbolLabel = new QLabel(this);
    addWidget(symbolLabel);

103
    toolBarNameLabel = new QLabel(this);
104
105
    toolBarNameLabel->setToolTip(tr("Currently controlled vehicle"));
    toolBarNameLabel->setAlignment(Qt::AlignCenter);
106
    toolBarNameLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
107
108
    addWidget(toolBarNameLabel);

109
    toolBarTimeoutLabel = new QLabel(this);
110
111
    toolBarTimeoutLabel->setToolTip(tr("System timed out, interval since last message"));
    toolBarTimeoutLabel->setAlignment(Qt::AlignCenter);
112
    toolBarTimeoutLabel->setObjectName("toolBarTimeoutLabel");
113
114
    toolBarTimeoutLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    toolBarTimeoutAction = addWidget(toolBarTimeoutLabel);
115

116
    toolBarSafetyLabel = new QLabel(this);
117
118
119
120
    toolBarSafetyLabel->setToolTip(tr("Vehicle safety state"));
    toolBarSafetyLabel->setAlignment(Qt::AlignCenter);
    addWidget(toolBarSafetyLabel);

121
    toolBarModeLabel = new QLabel(this);
122
    toolBarModeLabel->setToolTip(tr("Vehicle mode"));
123
    toolBarModeLabel->setObjectName("toolBarModeLabel");
124
125
126
    toolBarModeLabel->setAlignment(Qt::AlignCenter);
    addWidget(toolBarModeLabel);

127
128
129
130
131
//    toolBarStateLabel = new QLabel(this);
//    toolBarStateLabel->setToolTip(tr("Vehicle state"));
//    toolBarStateLabel->setObjectName("toolBarStateLabel");
//    toolBarStateLabel->setAlignment(Qt::AlignCenter);
//    addWidget(toolBarStateLabel);
132
133
134
135
136
137
138
139

    toolBarBatteryBar = new QProgressBar(this);
    toolBarBatteryBar->setMinimum(0);
    toolBarBatteryBar->setMaximum(100);
    toolBarBatteryBar->setMinimumWidth(20);
    toolBarBatteryBar->setMaximumWidth(100);
    toolBarBatteryBar->setToolTip(tr("Battery charge level"));
    toolBarBatteryBar->setObjectName("toolBarBatteryBar");
140
    toolBarBatteryBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);
Lorenz Meier's avatar
Lorenz Meier committed
141
    toolBarBatteryBarAction = addWidget(toolBarBatteryBar);
142

143
    toolBarBatteryVoltageLabel = new QLabel(this);
144
    toolBarBatteryVoltageLabel->setToolTip(tr("Battery voltage"));
145
    toolBarBatteryVoltageLabel->setObjectName("toolBarBatteryVoltageLabel");
146
    toolBarBatteryVoltageLabel->setAlignment(Qt::AlignCenter);
Lorenz Meier's avatar
Lorenz Meier committed
147
    toolBarBatteryVoltageAction = addWidget(toolBarBatteryVoltageLabel);
148

149
    toolBarWpLabel = new QLabel(this);
150
    toolBarWpLabel->setToolTip(tr("Current waypoint"));
151
    toolBarWpLabel->setObjectName("toolBarWpLabel");
152
    toolBarWpLabel->setAlignment(Qt::AlignCenter);
153
    toolBarWpAction = addWidget(toolBarWpLabel);
154

155
    toolBarMessageLabel = new QLabel(this);
156
    toolBarMessageLabel->setToolTip(tr("Most recent system message"));
157
    toolBarMessageLabel->setObjectName("toolBarMessageLabel");
158
    toolBarMessageAction = addWidget(toolBarMessageLabel);
159
160
161
162
163

    QWidget* spacer = new QWidget();
    spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    addWidget(spacer);

164
165
166
    portComboBox = new QComboBox(this);
    portComboBox->setToolTip(tr("Choose the COM port to use"));
    portComboBox->setEnabled(true);
167
    portComboBox->setMinimumWidth(100);
168
    toolBarPortAction = addWidget(portComboBox);
169
170
171
172

    baudcomboBox = new QComboBox(this);
    baudcomboBox->setToolTip(tr("Choose what baud rate to use"));
    baudcomboBox->setEnabled(true);
173
174
175
176
177
178
179
180
181
182
183
    baudcomboBox->setMinimumWidth(40);
    baudcomboBox->addItem("9600", 9600);
    baudcomboBox->addItem("14400", 14400);
    baudcomboBox->addItem("19200", 19200);
    baudcomboBox->addItem("38400", 38400);
    baudcomboBox->addItem("57600", 57600);
    baudcomboBox->addItem("115200", 115200);
    baudcomboBox->addItem("230400", 230400);
    baudcomboBox->addItem("460800", 460800);
    baudcomboBox->addItem("921600", 921600);
    baudcomboBox->setCurrentIndex(baudcomboBox->findData(57600));
184
    toolBarBaudAction = addWidget(baudcomboBox);
Lorenz Meier's avatar
Lorenz Meier committed
185
186
    connect(baudcomboBox, SIGNAL(activated(int)), this, SLOT(baudSelected(int)));
    connect(portComboBox, SIGNAL(activated(int)), this, SLOT(portSelected(int)));
187

188
    connectButton = new QPushButton(tr("Connect"), this);
189
    connectButton->setObjectName("connectButton");
190
191
192
    connectButton->setToolTip(tr("Connect wireless link to MAV"));
    connectButton->setCheckable(true);
    addWidget(connectButton);
193
194
    connect(connectButton, SIGNAL(clicked(bool)), this, SLOT(connectLink(bool)));

195
196
    resetToolbarUI();

lm's avatar
lm committed
197
198
    // DONE INITIALIZING BUTTONS

199
200
201
    // Set the toolbar to be updated every 2s
    connect(&updateViewTimer, SIGNAL(timeout()), this, SLOT(updateView()));

202
    // Configure the toolbar for the current default UAS
203
204
    setActiveUAS(UASManager::instance()->getActiveUAS());
    connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
205
206
207
208
    qDebug() << "LINK COUNT" << LinkManager::instance()->getLinks().count();
    // Update label if required
    if (LinkManager::instance()->getSerialLinks().count() < 1) {
        connectButton->setText(tr("New Serial Link"));
209
210
        toolBarPortAction->setVisible(false);
        toolBarBaudAction->setVisible(false);
211
    } else {
lm's avatar
lm committed
212

213
        QList<SerialLink*> links = LinkManager::instance()->getSerialLinks();
214

215
216
217
218
        foreach(SerialLink* slink, links)
        {
            addLink(slink);
        }
219
220
    }

221
222
223
    connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*)));
    connect(LinkManager::instance(), SIGNAL(linkRemoved(LinkInterface*)), this, SLOT(removeLink(LinkInterface*)));

224
    loadSettings();
Lorenz Meier's avatar
Lorenz Meier committed
225

226
227
228
    connect(&portBoxTimer, SIGNAL(timeout()), this, SLOT(updateComboBox()));
    portBoxTimer.start(500);

229
230
231
    toolBarMessageAction->setVisible(false);
    toolBarBatteryBarAction->setVisible(false);

Lorenz Meier's avatar
Lorenz Meier committed
232
    changed = false;
233
234
}

235
236
237
238
239
240
241
242
243
/**
 * Reset all the labels and stuff for the toolbar to a pristine state. Done at startup after
 * all UI has been created and also when the last UAS has been deleted.
 **/
void QGCToolBar::resetToolbarUI()
{
    toolBarNameLabel->setText("------");
    toolBarNameLabel->setStyleSheet("");
    toolBarTimeoutLabel->setText(tr("UNCONNECTED"));
244
    //toolBarTimeoutLabel->show();
245
246
    toolBarSafetyLabel->setText("----");
    toolBarModeLabel->setText("------");
247
//    toolBarStateLabel->setText("------");
248
249
250
251
252
    toolBarBatteryBar->setValue(0);
    toolBarBatteryBar->setDisabled(true);
    toolBarBatteryVoltageLabel->setText("xx.x V");
    toolBarWpLabel->setText("WP--");
    toolBarMessageLabel->clear();
253
254
    lastSystemMessage = "";
    lastSystemMessageTimeMs = 0;
255
256
    symbolLabel->setStyleSheet("");
    symbolLabel->clear();
257
258
    toolBarMessageAction->setVisible(false);
    toolBarBatteryBarAction->setVisible(false);
259
260
}

Lorenz Meier's avatar
Lorenz Meier committed
261
262
void QGCToolBar::baudSelected(int index)
{
Lorenz Meier's avatar
Lorenz Meier committed
263
    Q_UNUSED(index);
Lorenz Meier's avatar
Lorenz Meier committed
264
265
266
    userBaudChoice = true;
}

Lorenz Meier's avatar
Lorenz Meier committed
267
268
269
270
271
272
void QGCToolBar::portSelected(int index)
{
    Q_UNUSED(index);
    userPortChoice = true;
}

Lorenz Meier's avatar
Lorenz Meier committed
273
void QGCToolBar::setPerspectiveChangeActions(const QList<QAction*> &actions)
274
{
Lorenz Meier's avatar
Lorenz Meier committed
275
276
    if (actions.count() > 1)
    {
277
        group = new QButtonGroup(this);
Lorenz Meier's avatar
Lorenz Meier committed
278
279
        group->setExclusive(true);

280
        // Add the first button.
Lorenz Meier's avatar
Lorenz Meier committed
281
282
283
284
285
286
        QToolButton *first = new QToolButton(this);
        first->setIcon(actions.first()->icon());
        first->setText(actions.first()->text());
        first->setToolTip(actions.first()->toolTip());
        first->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
        first->setCheckable(true);
287

Lorenz Meier's avatar
Lorenz Meier committed
288
        connect(first, SIGNAL(clicked(bool)), actions.first(), SIGNAL(triggered(bool)));
289
        connect(actions.first(),SIGNAL(triggered(bool)),first,SLOT(setChecked(bool)));
290

291
        first->setObjectName("firstAction");
292
293

        //first->setStyleSheet("QToolButton { min-height: 24px; max-height: 24px; min-width: 60px; color: #222222; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #A2A3A4, stop: 1 #B6B7B8); margin-left: 8px; margin-right: 0px; padding-left: 4px; padding-right: 8px; border-radius: 0px; border : 0px solid blue; border-bottom-left-radius: 6px; border-top-left-radius: 6px; border-left: 1px solid #484848; border-top: 1px solid #484848; border-bottom: 1px solid #484848; } QToolButton:checked { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #555555, stop: 1 #787878); color: #DDDDDD; }");
Lorenz Meier's avatar
Lorenz Meier committed
294
295
296
        addWidget(first);
        group->addButton(first);

297
        // Add all the middle buttons.
298
        for (int i = 1; i < actions.count(); i++)
Lorenz Meier's avatar
Lorenz Meier committed
299
300
301
302
303
304
305
306
        {
            QToolButton *btn = new QToolButton(this);
            btn->setIcon(actions.at(i)->icon());
            btn->setText(actions.at(i)->text());
            btn->setToolTip(actions.at(i)->toolTip());
            btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
            btn->setCheckable(true);
            connect(btn, SIGNAL(clicked(bool)), actions.at(i), SIGNAL(triggered(bool)));
307
            connect(actions.at(i),SIGNAL(triggered(bool)),btn,SLOT(setChecked(bool)));
Lorenz Meier's avatar
Lorenz Meier committed
308
309
310
311
312
            addWidget(btn);
            group->addButton(btn);
        }

        // Add last button
313
        advancedButton = new QToolButton(this);
314
315
316
317
        advancedButton->setIcon(QIcon(":/files/images/apps/utilities-system-monitor.svg"));
        advancedButton->setText(tr("Pro"));
        advancedButton->setToolTip(tr("Options for advanced users"));
        advancedButton->setCheckable(true);
318
        advancedButton->setObjectName("advancedButton");
319
        advancedButton->setPopupMode(QToolButton::InstantPopup);
320
        advancedButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
321
322
        addWidget(advancedButton);
        group->addButton(advancedButton);
323
    } else {
Lorenz Meier's avatar
Lorenz Meier committed
324
        qDebug() << __FILE__ << __LINE__ << "Not enough perspective change actions provided";
325
    }
Lorenz Meier's avatar
Lorenz Meier committed
326

327
    // Add the "rest"
Lorenz Meier's avatar
Lorenz Meier committed
328
    createUI();
329
330
}

331
332
333
334
335
336
337
338
339
340
341
342
343
void QGCToolBar::setPerspectiveChangeAdvancedActions(const QList<QAction*> &actions)
{
    if (actions.count() > 1)
    {
        QMenu *menu = new QMenu(advancedButton);

        for (int i = 0; i < actions.count(); i++)
        {

            menu->addAction(actions.at(i));
        }

        advancedButton->setMenu(menu);
344
        connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(advancedActivityTriggered(QAction*)));
345
346
347
348
349
350

    } else {
        qDebug() << __FILE__ << __LINE__ << "Not enough perspective change actions provided";
    }
}

351
352
353
354
355
356
void QGCToolBar::advancedActivityTriggered(QAction* action)
{
    if (action->isChecked())
        advancedButton->setChecked(true);
}

357
358
void QGCToolBar::setActiveUAS(UASInterface* active)
{
359
    // Do nothing if system is the same
360
361
    if (mav == active || active == NULL)
        return;
362

363
    // If switching UASes, disconnect the only one.
364
365
366
367
368
369
    if (mav)
    {
        disconnect(mav, SIGNAL(statusChanged(UASInterface*,QString,QString)), this, SLOT(updateState(UASInterface*,QString,QString)));
        disconnect(mav, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int,QString,QString)));
        disconnect(mav, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString)));
        disconnect(mav, SIGNAL(systemTypeSet(UASInterface*,uint)), this, SLOT(setSystemType(UASInterface*,uint)));
LM's avatar
LM committed
370
        disconnect(mav, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(receiveTextMessage(int,int,int,QString)));
dongfang's avatar
dongfang committed
371
        disconnect(mav, SIGNAL(batteryChanged(UASInterface*, double, double, double,int)), this, SLOT(updateBatteryRemaining(UASInterface*, double, double, double, int)));
372
        disconnect(mav, SIGNAL(armingChanged(bool)), this, SLOT(updateArmingState(bool)));
373
        disconnect(mav, SIGNAL(heartbeatTimeout(bool, unsigned int)), this, SLOT(heartbeatTimeout(bool,unsigned int)));
374
        disconnect(active, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(globalPositionChanged(UASInterface*,double,double,double,quint64)));
375
376
        if (mav->getWaypointManager())
        {
377
            disconnect(mav->getWaypointManager(), SIGNAL(currentWaypointChanged(quint16)), this, SLOT(updateCurrentWaypoint(quint16)));
378
379
            disconnect(mav->getWaypointManager(), SIGNAL(waypointDistanceChanged(double)), this, SLOT(updateWaypointDistance(double)));
        }
380
    }
381
382
383
384
385
    else
    {
        // Only update the UI once a UAS has been selected.
        updateViewTimer.start(2000);
    }
386
387
388

    // Connect new system
    mav = active;
389
    if (mav)
390
    {
391
392
393
394
395
        connect(mav, SIGNAL(statusChanged(UASInterface*,QString,QString)), this, SLOT(updateState(UASInterface*, QString,QString)));
        connect(mav, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int,QString,QString)));
        connect(mav, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString)));
        connect(mav, SIGNAL(systemTypeSet(UASInterface*,uint)), this, SLOT(setSystemType(UASInterface*,uint)));
        connect(mav, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(receiveTextMessage(int,int,int,QString)));
396
        connect(mav, SIGNAL(batteryChanged(UASInterface*,double,double,double,int)), this, SLOT(updateBatteryRemaining(UASInterface*,double,double,double,int)));
397
398
399
400
401
402
403
404
        connect(mav, SIGNAL(armingChanged(bool)), this, SLOT(updateArmingState(bool)));
        connect(mav, SIGNAL(heartbeatTimeout(bool, unsigned int)), this, SLOT(heartbeatTimeout(bool,unsigned int)));
        connect(mav, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(globalPositionChanged(UASInterface*,double,double,double,quint64)));
        if (mav->getWaypointManager())
        {
            connect(mav->getWaypointManager(), SIGNAL(currentWaypointChanged(quint16)), this, SLOT(updateCurrentWaypoint(quint16)));
            connect(mav->getWaypointManager(), SIGNAL(waypointDistanceChanged(double)), this, SLOT(updateWaypointDistance(double)));
        }
405

406
407
408
        // Update all values once
        systemName = mav->getUASName();
        systemArmed = mav->isArmed();
409
        toolBarNameLabel->setText(mav->getUASName().replace("MAV", ""));
410
411
        toolBarNameLabel->setStyleSheet(QString("QLabel {color: %1;}").arg(mav->getColor().name()));
        symbolLabel->setStyleSheet(QString("QWidget {background-color: %1;}").arg(mav->getColor().name()));
412
413
414
415
416
        QString shortMode = mav->getShortMode();
        shortMode = shortMode.replace("D|", "");
        shortMode = shortMode.replace("A|", "");
        toolBarModeLabel->setText(shortMode);
//        toolBarStateLabel->setText(mav->getShortState());
417
418
419
        toolBarTimeoutAction->setVisible(false);
        toolBarMessageLabel->clear();
        lastSystemMessageTimeMs = 0;
420
421
422
423
424
        toolBarBatteryBar->setEnabled(true);
        setSystemType(mav, mav->getSystemType());
    }
    else
    {
425
426
427
428
429
        updateViewTimer.stop();
        resetToolbarUI();
    }
}

430
431
432
433
void QGCToolBar::updateArmingState(bool armed)
{
    systemArmed = armed;
    changed = true;
Lorenz Meier's avatar
Lorenz Meier committed
434
435
    /* important, immediately update */
    updateView();
436
437
}

lm's avatar
lm committed
438
439
440
void QGCToolBar::updateView()
{
    if (!changed) return;
441
    if (toolBarWpAction->isVisible())
442
443
        toolBarWpLabel->setText(tr("WP%1").arg(wpId));

444
    if (toolBarBatteryBarAction->isVisible()) {
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
        toolBarBatteryBar->setValue(batteryPercent);

        if (batteryPercent < 30 && toolBarBatteryBar->value() >= 30) {
            if (MainWindow::instance()->getStyle() == MainWindow::QGC_MAINWINDOW_STYLE_LIGHT)
            {
                toolBarBatteryBar->setStyleSheet("QProgressBar {color: #FFF} QProgressBar::chunk { background-color: #008000}");
            }
            else
            {
                toolBarBatteryBar->setStyleSheet("QProgressBar {color: #000} QProgressBar QProgressBar::chunk { background-color: #0F0}");
            }
        } else if (batteryPercent >= 30 && toolBarBatteryBar->value() < 30){
            if (MainWindow::instance()->getStyle() == MainWindow::QGC_MAINWINDOW_STYLE_LIGHT)
            {
                toolBarBatteryBar->setStyleSheet("QProgressBar {color: #FFF} QProgressBar::chunk { background-color: #808000}");
            }
            else
            {
                toolBarBatteryBar->setStyleSheet("QProgressBar {color: #000} QProgressBar QProgressBar::chunk { background-color: #FF0}");
            }
465
        }
466

467
468
469
    }
    if (toolBarBatteryVoltageLabel->isVisible()) {
	toolBarBatteryVoltageLabel->setText(tr("%1 V").arg(batteryVoltage, 4, 'f', 1, ' '));
Lorenz Meier's avatar
Lorenz Meier committed
470
471
    }

472
473

//    toolBarStateLabel->setText(QString("%1").arg(state));
474
    toolBarModeLabel->setText(QString("%1").arg(mode));
lm's avatar
lm committed
475
    toolBarNameLabel->setText(systemName);
476
    // expire after 15 seconds
477

478
    if (toolBarMessageAction->isVisible()) {
479
480
481
482
483
        if (QGC::groundTimeMilliseconds() - lastSystemMessageTimeMs < 15000) {
            toolBarMessageLabel->setText(QString("%1").arg(lastSystemMessage));
        } else {
            toolBarMessageLabel->clear();
        }
484
    }
485

486
    // Display the system armed state with a red-on-yellow background if armed or green text if safe.
487
488
    if (systemArmed)
    {
489
        toolBarSafetyLabel->setStyleSheet(QString("QLabel {color: %1; background-color: %2; font-size: 15pt;}").arg(QGC::colorRed.name()).arg(QGC::colorYellow.name()));
490
491
492
493
        toolBarSafetyLabel->setText(tr("ARMED"));
    }
    else
    {
494
495
        if (MainWindow::instance()->getStyle() == MainWindow::QGC_MAINWINDOW_STYLE_LIGHT)
        {
496
            toolBarSafetyLabel->setStyleSheet("QLabel {color: #0D820D; font-size: 15pt;}");
497
498
499
        }
        else
        {
500
            toolBarSafetyLabel->setStyleSheet("QLabel {color: #14C814; font-size: 15pt;}");
501
        }
Lorenz Meier's avatar
Lorenz Meier committed
502
        toolBarSafetyLabel->setText(tr("DISARMED"));
503
504
    }

lm's avatar
lm committed
505
    changed = false;
lm's avatar
lm committed
506
507
}

508
509
void QGCToolBar::updateWaypointDistance(double distance)
{
lm's avatar
lm committed
510
511
    if (wpDistance != distance) changed = true;
    wpDistance = distance;
512
513
514
515
}

void QGCToolBar::updateCurrentWaypoint(quint16 id)
{
lm's avatar
lm committed
516
    if (wpId != id) changed = true;
lm's avatar
lm committed
517
    wpId = id;
518
519
}

dongfang's avatar
dongfang committed
520
void QGCToolBar::updateBatteryRemaining(UASInterface* uas, double voltage, double current, double percent, int seconds)
LM's avatar
LM committed
521
{
522
523
    Q_UNUSED(uas);
    Q_UNUSED(seconds);
524
    Q_UNUSED(current);
525

lm's avatar
lm committed
526
    if (batteryPercent != percent || batteryVoltage != voltage) changed = true;
lm's avatar
lm committed
527
528
    batteryPercent = percent;
    batteryVoltage = voltage;
LM's avatar
LM committed
529
530
}

531
532
533
534
void QGCToolBar::updateState(UASInterface* system, QString name, QString description)
{
    Q_UNUSED(system);
    Q_UNUSED(description);
lm's avatar
lm committed
535
    if (state != name) changed = true;
lm's avatar
lm committed
536
    state = name;
Lorenz Meier's avatar
Lorenz Meier committed
537
538
    /* important, immediately update */
    updateView();
539
540
541
542
543
544
}

void QGCToolBar::updateMode(int system, QString name, QString description)
{
    Q_UNUSED(system);
    Q_UNUSED(description);
lm's avatar
lm committed
545
546
    if (mode != name) changed = true;
    mode = name;
Lorenz Meier's avatar
Lorenz Meier committed
547
548
    /* important, immediately update */
    updateView();
549
550
551
552
}

void QGCToolBar::updateName(const QString& name)
{
Lorenz Meier's avatar
Lorenz Meier committed
553
554
555
556
    if (systemName != name)
    {
        changed = true;
    }
lm's avatar
lm committed
557
    systemName = name;
558
559
560
561
562
563
564
565
566
567
568
569
}

/**
 * The current system type is represented through the system icon.
 *
 * @param uas Source system, has to be the same as this->uas
 * @param systemType type ID, following the MAVLink system type conventions
 * @see http://pixhawk.ethz.ch/software/mavlink
 */
void QGCToolBar::setSystemType(UASInterface* uas, unsigned int systemType)
{
    Q_UNUSED(uas);
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
    QPixmap newPixmap;
    switch (systemType) {
    case MAV_TYPE_GENERIC:
        newPixmap = QPixmap(":/files/images/mavs/generic.svg");
        break;
    case MAV_TYPE_FIXED_WING:
        newPixmap = QPixmap(":/files/images/mavs/fixed-wing.svg");
        break;
    case MAV_TYPE_QUADROTOR:
        newPixmap = QPixmap(":/files/images/mavs/quadrotor.svg");
        break;
    case MAV_TYPE_COAXIAL:
        newPixmap = QPixmap(":/files/images/mavs/coaxial.svg");
        break;
    case MAV_TYPE_HELICOPTER:
        newPixmap = QPixmap(":/files/images/mavs/helicopter.svg");
        break;
    case MAV_TYPE_ANTENNA_TRACKER:
        newPixmap = QPixmap(":/files/images/mavs/antenna-tracker.svg");
        break;
    case MAV_TYPE_GCS:
        newPixmap = QPixmap(":files/images/mavs/groundstation.svg");
        break;
    case MAV_TYPE_AIRSHIP:
        newPixmap = QPixmap(":files/images/mavs/airship.svg");
        break;
    case MAV_TYPE_FREE_BALLOON:
        newPixmap = QPixmap(":files/images/mavs/free-balloon.svg");
        break;
    case MAV_TYPE_ROCKET:
        newPixmap = QPixmap(":files/images/mavs/rocket.svg");
        break;
    case MAV_TYPE_GROUND_ROVER:
        newPixmap = QPixmap(":files/images/mavs/ground-rover.svg");
        break;
    case MAV_TYPE_SURFACE_BOAT:
        newPixmap = QPixmap(":files/images/mavs/surface-boat.svg");
        break;
    case MAV_TYPE_SUBMARINE:
        newPixmap = QPixmap(":files/images/mavs/submarine.svg");
        break;
    case MAV_TYPE_HEXAROTOR:
        newPixmap = QPixmap(":files/images/mavs/hexarotor.svg");
        break;
    case MAV_TYPE_OCTOROTOR:
        newPixmap = QPixmap(":files/images/mavs/octorotor.svg");
        break;
    case MAV_TYPE_TRICOPTER:
        newPixmap = QPixmap(":files/images/mavs/tricopter.svg");
        break;
    case MAV_TYPE_FLAPPING_WING:
        newPixmap = QPixmap(":files/images/mavs/flapping-wing.svg");
        break;
    case MAV_TYPE_KITE:
        newPixmap = QPixmap(":files/images/mavs/kite.svg");
        break;
    default:
        newPixmap = QPixmap(":/files/images/mavs/unknown.svg");
        break;
    }
    symbolLabel->setPixmap(newPixmap.scaledToHeight(24));
631
632
}

LM's avatar
LM committed
633
634
635
636
637
void QGCToolBar::receiveTextMessage(int uasid, int componentid, int severity, QString text)
{
    Q_UNUSED(uasid);
    Q_UNUSED(componentid);
    Q_UNUSED(severity);
lm's avatar
lm committed
638
    if (lastSystemMessage != text) changed = true;
lm's avatar
lm committed
639
    lastSystemMessage = text;
640
    lastSystemMessageTimeMs = QGC::groundTimeMilliseconds();
LM's avatar
LM committed
641
642
}

643
644
void QGCToolBar::addLink(LinkInterface* link)
{
645
646
647
648
649
    // Accept only serial links as current link
    SerialLink* serial = qobject_cast<SerialLink*>(link);

    if (serial && !currentLink)
    {
650
651
        toolBarPortAction->setVisible(true);
        toolBarBaudAction->setVisible(true);
652

653
654
655
        currentLink = link;
        connect(currentLink, SIGNAL(connected(bool)), this, SLOT(updateLinkState(bool)));
        updateLinkState(link->isConnected());
656
657
658
659

        qDebug() << "ADD LINK";

        updateComboBox();
660
661
662
663
664
665
666
    }
}

void QGCToolBar::removeLink(LinkInterface* link)
{
    if (link == currentLink) {
        currentLink = NULL;
667
668
669
670
671
672
673
674
675

        // Try to get a new serial link
        foreach (SerialLink* s, LinkManager::instance()->getSerialLinks())
        {
            addLink(s);
        }

        // Update GUI according to scan result
        if (currentLink) {
676
677
            updateLinkState(currentLink->isConnected());
        } else {
678
679
680
            connectButton->setText(tr("New Serial Link"));
            portComboBox->hide();
            baudcomboBox->hide();
681
682
        }
    }
683
684
685
686
    updateComboBox();
}
void QGCToolBar::updateComboBox()
{
687
    if (currentLink && !currentLink->isConnected())
688
    {
Lorenz Meier's avatar
Lorenz Meier committed
689
690
691
692
        // Do not update if not visible
        if (!portComboBox->isVisible())
            return;

693
694
        SerialLink *slink = qobject_cast<SerialLink*>(currentLink);
        QList<QString> portlist = slink->getCurrentPorts();
695
696
697
698
699
700
        foreach (QString port, portlist)
        {
            if (portComboBox->findText(port) == -1)
            {
                portComboBox->addItem(port, port);
            }
701
702
        }

Lorenz Meier's avatar
Lorenz Meier committed
703
704
        if (!userPortChoice) {
            if (slink->getPortName().trimmed().length() > 0)
705
            {
Lorenz Meier's avatar
Lorenz Meier committed
706
707
708
709
710
                int portIndex = portComboBox->findData(slink->getPortName());
                if (portIndex >= 0) {
                    portComboBox->setCurrentIndex(portIndex);
                    portComboBox->setEditText(slink->getPortName());
                }
711
712
713
            }
            else
            {
Lorenz Meier's avatar
Lorenz Meier committed
714
715
716
717
718
719
720
721
                if (portlist.length() > 0)
                {
                    portComboBox->setEditText(portlist.last());
                }
                else
                {
                    portComboBox->setEditText(tr("No serial port found"));
                }
722
            }
723
        }
Lorenz Meier's avatar
Lorenz Meier committed
724
725
726

        if (!userBaudChoice) {
            int index = baudcomboBox->findData(slink->getBaudRate());
Lorenz Meier's avatar
Lorenz Meier committed
727
            if (index >= 0)
Lorenz Meier's avatar
Lorenz Meier committed
728
729
                baudcomboBox->setCurrentIndex(index);
        }
730
    }
731
732
733
734
}

void QGCToolBar::updateLinkState(bool connected)
{
735
    Q_UNUSED(connected);
736
    if (currentLink && currentLink->isConnected() && portComboBox->isVisible())
737
738
739
740
741
    {
        connectButton->setText(tr("Disconnect"));
        connectButton->blockSignals(true);
        connectButton->setChecked(true);
        connectButton->blockSignals(false);
742
743
744
745
        toolBarPortAction->setVisible(false);
        toolBarBaudAction->setVisible(false);
        toolBarMessageAction->setVisible(true);
        toolBarWpAction->setVisible(true);
746
747
748
749
750
751
752
    }
    else
    {
        connectButton->setText(tr("Connect"));
        connectButton->blockSignals(true);
        connectButton->setChecked(false);
        connectButton->blockSignals(false);
753
754
755
756
        toolBarPortAction->setVisible(true);
        toolBarBaudAction->setVisible(true);
        toolBarMessageAction->setVisible(false);
        toolBarWpAction->setVisible(false);
757
758
759
    }
}

760
761
void QGCToolBar::connectLink(bool connect)
{
762
    // No serial port yet present
763
    if (connect && LinkManager::instance()->getSerialLinks().count() == 0)
764
765
    {
        MainWindow::instance()->addLink();
766
        currentLink = LinkManager::instance()->getLinks().last();
767
    } else if (connect) {
768
769
        SerialLink *link = qobject_cast<SerialLink*>(currentLink);
        if (link)
770
        {
771
            link->setPortName(portComboBox->itemData(portComboBox->currentIndex()).toString().trimmed());
772
773
            int baud = baudcomboBox->currentText().toInt();
            link->setBaudRate(baud);
774
775
            link->connect();
        }
776
777
778

    } else if (!connect && currentLink) {
        currentLink->disconnect();
779
780
781
    }
}

782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797

void QGCToolBar::loadSettings()
{
    QSettings settings;
    settings.beginGroup("QGC_TOOLBAR");
    settings.endGroup();
}

void QGCToolBar::storeSettings()
{
    QSettings settings;
    settings.beginGroup("QGC_TOOLBAR");
    settings.endGroup();
    settings.sync();
}

798
799
void QGCToolBar::clearStatusString()
{
Lorenz Meier's avatar
Lorenz Meier committed
800
801
802
803
804
    if (toolBarMessageLabel->text().length() > 0)
    {
        lastSystemMessage = "";
        changed = true;
    }
805
806
}

807
808
QGCToolBar::~QGCToolBar()
{
809
    storeSettings();
810
}