MainWindow.cc 68.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*=====================================================================

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

pixhawk's avatar
pixhawk committed
22 23 24 25
======================================================================*/

/**
 * @file
26
 *   @brief Implementation of class MainWindow
27
 *   @author Lorenz Meier <mail@qgroundcontrol.org>
pixhawk's avatar
pixhawk committed
28 29 30 31 32 33 34 35 36 37
 */

#include <QSettings>
#include <QDockWidget>
#include <QNetworkInterface>
#include <QMessageBox>
#include <QDebug>
#include <QTimer>
#include <QHostInfo>

38
#include "QGC.h"
pixhawk's avatar
pixhawk committed
39 40 41 42 43
#include "MAVLinkSimulationLink.h"
#include "SerialLink.h"
#include "UDPLink.h"
#include "MAVLinkProtocol.h"
#include "CommConfigurationWindow.h"
44
#include "QGCWaypointListMulti.h"
pixhawk's avatar
pixhawk committed
45 46
#include "MainWindow.h"
#include "JoystickWidget.h"
pixhawk's avatar
pixhawk committed
47
#include "GAudioOutput.h"
48
#include "QGCToolWidget.h"
49
#include "QGCMAVLinkLogPlayer.h"
50
#include "QGCSettingsWidget.h"
51
#include "QGCMapTool.h"
52

53
#ifdef QGC_OSG_ENABLED
54
#include "Q3DWidgetFactory.h"
55
#endif
pixhawk's avatar
pixhawk committed
56

lm's avatar
lm committed
57 58 59 60
// FIXME Move
#include "PxQuadMAV.h"
#include "SlugsMAV.h"

pixhawk's avatar
pixhawk committed
61

62
#include "LogCompressor.h"
pixhawk's avatar
pixhawk committed
63

64 65
MainWindow* MainWindow::instance()
{
66
    static MainWindow* _instance = 0;
67
    if(_instance == 0) {
68
        _instance = new MainWindow();
69

70
        /* Set the application as parent to ensure that this object
71
                 * will be destroyed when the main application exits */
72 73 74
        //_instance->setParent(qApp);
    }
    return _instance;
75 76
}

pixhawk's avatar
pixhawk committed
77 78 79 80 81 82 83
/**
* Create new mainwindow. The constructor instantiates all parts of the user
* interface. It does NOT show the mainwindow. To display it, call the show()
* method.
*
* @see QMainWindow::show()
**/
84
MainWindow::MainWindow(QWidget *parent):
85 86 87 88 89 90 91
    QMainWindow(parent),
    toolsMenuActions(),
    currentView(VIEW_UNCONNECTED),
    aboutToCloseFlag(false),
    changingViewsFlag(false),
    styleFileName(QCoreApplication::applicationDirPath() + "/style-indoor.css"),
    autoReconnect(false),
92 93
    currentStyle(QGC_MAINWINDOW_STYLE_INDOOR),
    lowPowerMode(false)
pixhawk's avatar
pixhawk committed
94
{
95
    loadSettings();
96
    if (!settings.contains("CURRENT_VIEW")) {
97 98
        // Set this view as default view
        settings.setValue("CURRENT_VIEW", currentView);
99
    } else {
100 101 102
        // LOAD THE LAST VIEW
        VIEW_SECTIONS currentViewCandidate = (VIEW_SECTIONS) settings.value("CURRENT_VIEW", currentView).toInt();
        if (currentViewCandidate != VIEW_ENGINEER &&
103 104
                currentViewCandidate != VIEW_OPERATOR &&
                currentViewCandidate != VIEW_PILOT) {
105
            currentView = currentViewCandidate;
106
        }
107 108
    }

109
    setDefaultSettingsForAp();
110

111 112
    settings.sync();

pixhawk's avatar
pixhawk committed
113 114 115
    // Setup user interface
    ui.setupUi(this);

116 117
    setVisible(false);

118
    buildCommonWidgets();
119

120
    connectCommonWidgets();
121

122
    arrangeCommonCenterStack();
123 124

    configureWindowName();
pixhawk's avatar
pixhawk committed
125

126
    loadStyle(currentStyle);
127

128
    // Create actions
129
    connectCommonActions();
130

131 132 133
    // Set dock options
    setDockOptions(AnimatedDocks | AllowTabbedDocks | AllowNestedDocks);

lm's avatar
lm committed
134 135
    statusBar()->setSizeGripEnabled(true);

136
    // Restore the window position and size
137
    if (settings.contains(getWindowGeometryKey())) {
138
        // Restore the window geometry
139
        restoreGeometry(settings.value(getWindowGeometryKey()).toByteArray());
140
    } else {
141 142 143
        // Adjust the size
        adjustSize();
    }
pixhawk's avatar
pixhawk committed
144

145 146
    // Populate link menu
    QList<LinkInterface*> links = LinkManager::instance()->getLinks();
147
    foreach(LinkInterface* link, links) {
148 149
        this->addLink(link);
    }
150

151 152
    connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*)));

lm's avatar
lm committed
153 154 155
    // Add generic MAVLink decoder
    mavlinkDecoder = new MAVLinkDecoder(mavlink, this);

156
    // Connect user interface devices
157 158
    joystickWidget = 0;
    joystick = new JoystickInput();
159

160 161 162 163 164 165 166 167
    // Load Toolbar
    toolBar = new QGCToolBar(this);
    this->addToolBar(toolBar);
    // Add actions
    toolBar->addPerspectiveChangeAction(ui.actionOperatorsView);
    toolBar->addPerspectiveChangeAction(ui.actionEngineersView);
    toolBar->addPerspectiveChangeAction(ui.actionPilotsView);

lm's avatar
lm committed
168 169
    // Enable and update view
    presentView();
170 171

    // Connect link
172
    if (autoReconnect) {
173 174 175 176 177 178
        SerialLink* link = new SerialLink();
        // Add to registry
        LinkManager::instance()->add(link);
        LinkManager::instance()->addProtocol(link, mavlink);
        link->connect();
    }
179

180 181 182
    // Set low power mode
    enableLowPowerMode(lowPowerMode);

183 184
    // Initialize window state
    windowStateVal = windowState();
pixhawk's avatar
pixhawk committed
185 186
}

pixhawk's avatar
pixhawk committed
187
MainWindow::~MainWindow()
pixhawk's avatar
pixhawk committed
188
{
189 190 191
    // Store settings
    storeSettings();

192
    delete mavlink;
193
    delete joystick;
lm's avatar
lm committed
194

195 196 197 198 199 200
    // Get and delete all dockwidgets and contained
    // widgets
    QObjectList childList( this->children() );

    QObjectList::iterator i;
    QDockWidget* dockWidget;
201
    for (i = childList.begin(); i != childList.end(); ++i) {
202
        dockWidget = dynamic_cast<QDockWidget*>(*i);
203
        if (dockWidget) {
204 205 206 207 208 209
            // Remove dock widget from main window
            removeDockWidget(dockWidget);
            delete dockWidget->widget();
            delete dockWidget;
        }
    }
pixhawk's avatar
pixhawk committed
210 211
}

212 213 214 215 216 217 218 219 220
/**
 * Set default settings for this AP type.
 */
void MainWindow::setDefaultSettingsForAp()
{
    // Check if the settings exist, instantiate defaults if necessary

    // UNCONNECTED VIEW DEFAULT
    QString centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_MAP, VIEW_UNCONNECTED);
221
    if (!settings.contains(centralKey)) {
222
        settings.setValue(centralKey,true);
223 224 225 226 227

        // ENABLE UAS LIST
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_UAS_LIST, VIEW_UNCONNECTED), true);
        // ENABLE COMMUNICATION CONSOLE
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_DEBUG_CONSOLE, VIEW_UNCONNECTED), true);
228 229 230 231
    }

    // OPERATOR VIEW DEFAULT
    centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_MAP, VIEW_OPERATOR);
232
    if (!settings.contains(centralKey)) {
233 234 235 236
        settings.setValue(centralKey,true);

        // ENABLE UAS LIST
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_UAS_LIST,VIEW_OPERATOR), true);
237 238
        // ENABLE HUD TOOL WIDGET
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_HUD,VIEW_OPERATOR), true);
239 240
        // ENABLE WAYPOINTS
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_WAYPOINTS,VIEW_OPERATOR), true);
241 242 243 244
    }

    // ENGINEER VIEW DEFAULT
    centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_LINECHART, VIEW_ENGINEER);
245
    if (!settings.contains(centralKey)) {
246
        settings.setValue(centralKey,true);
247 248
        // Enable Parameter widget
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_PARAMETERS,VIEW_ENGINEER), true);
249 250 251 252
    }

    // MAVLINK VIEW DEFAULT
    centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_PROTOCOL, VIEW_MAVLINK);
253
    if (!settings.contains(centralKey)) {
254 255 256 257 258
        settings.setValue(centralKey,true);
    }

    // PILOT VIEW DEFAULT
    centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_HUD, VIEW_PILOT);
259
    if (!settings.contains(centralKey)) {
260
        settings.setValue(centralKey,true);
261 262
        // Enable Flight display
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_HDD_1,VIEW_PILOT), true);
263 264 265
    }
}

lm's avatar
lm committed
266 267 268
void MainWindow::resizeEvent(QResizeEvent * event)
{
    Q_UNUSED(event);
269
    if (height() < 800) {
lm's avatar
lm committed
270
        ui.statusBar->setVisible(false);
271
    } else {
lm's avatar
lm committed
272
        ui.statusBar->setVisible(true);
273
        ui.statusBar->setSizeGripEnabled(true);
lm's avatar
lm committed
274 275 276
    }
}

277 278
QString MainWindow::getWindowStateKey()
{
279
    return QString::number(currentView)+"_windowstate";
280 281 282 283
}

QString MainWindow::getWindowGeometryKey()
{
284 285
    //return QString::number(currentView)+"_geometry";
    return "_geometry";
286 287
}

lm's avatar
lm committed
288 289 290
void MainWindow::buildCustomWidget()
{
    // Show custom widgets only if UAS is connected
291
    if (UASManager::instance()->getActiveUAS() != NULL) {
lm's avatar
lm committed
292 293 294 295 296 297
        // Enable custom widgets
        ui.actionNewCustomWidget->setEnabled(true);

        // Create custom widgets
        QList<QGCToolWidget*> widgets = QGCToolWidget::createWidgetsFromSettings(this);

298
        if (widgets.size() > 0) {
lm's avatar
lm committed
299 300 301
            ui.menuTools->addSeparator();
        }

302
        for(int i = 0; i < widgets.size(); ++i) {
lm's avatar
lm committed
303
            // Check if this widget already has a parent, do not create it in this case
304 305
            QGCToolWidget* tool = widgets.at(i);
            QDockWidget* dock = dynamic_cast<QDockWidget*>(tool->parentWidget());
306
            if (!dock) {
307 308 309 310
                QDockWidget* dock = new QDockWidget(tool->windowTitle(), this);
                dock->setObjectName(tool->objectName()+"_DOCK");
                dock->setWidget(tool);
                connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater()));
lm's avatar
lm committed
311
                QAction* showAction = new QAction(widgets.at(i)->windowTitle(), this);
312
                showAction->setCheckable(true);
lm's avatar
lm committed
313 314 315 316
                connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool)));
                connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool)));
                widgets.at(i)->setMainMenuAction(showAction);
                ui.menuTools->addAction(showAction);
317 318

                // Load visibility for view (default is off)
lm's avatar
lm committed
319
                //dock->setVisible(tool->isVisible(currentView));
320 321 322 323 324

                // Load dock widget location (default is bottom)
                Qt::DockWidgetArea location = static_cast <Qt::DockWidgetArea>(tool->getDockWidgetArea(currentView));

                addDockWidget(location, dock);
lm's avatar
lm committed
325 326 327 328 329
            }
        }
    }
}

330 331 332 333
void MainWindow::buildCommonWidgets()
{
    //TODO:  move protocol outside UI
    mavlink     = new MAVLinkProtocol();
334
    connect(mavlink, SIGNAL(protocolStatusMessage(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection);
335 336

    // Dock widgets
337
    if (!controlDockWidget) {
338
        controlDockWidget = new QDockWidget(tr("Control"), this);
339
        controlDockWidget->setObjectName("UNMANNED_SYSTEM_CONTROL_DOCKWIDGET");
340
        controlDockWidget->setWidget( new UASControlWidget(this) );
341
        addToToolsMenu (controlDockWidget, tr("Control"), SLOT(showToolWidget(bool)), MENU_UAS_CONTROL, Qt::LeftDockWidgetArea);
342
    }
343

344
    if (!listDockWidget) {
345 346
        listDockWidget = new QDockWidget(tr("Unmanned Systems"), this);
        listDockWidget->setWidget( new UASListWidget(this) );
347
        listDockWidget->setObjectName("UNMANNED_SYSTEMS_LIST_DOCKWIDGET");
348
        addToToolsMenu (listDockWidget, tr("Unmanned Systems"), SLOT(showToolWidget(bool)), MENU_UAS_LIST, Qt::RightDockWidgetArea);
349
    }
350

351
    if (!waypointsDockWidget) {
352
        waypointsDockWidget = new QDockWidget(tr("Mission Plan"), this);
353
        waypointsDockWidget->setWidget( new QGCWaypointListMulti(this) );
354
        waypointsDockWidget->setObjectName("WAYPOINT_LIST_DOCKWIDGET");
355
        addToToolsMenu (waypointsDockWidget, tr("Mission Plan"), SLOT(showToolWidget(bool)), MENU_WAYPOINTS, Qt::BottomDockWidgetArea);
356
    }
357

358
    if (!infoDockWidget) {
359 360
        infoDockWidget = new QDockWidget(tr("Status Details"), this);
        infoDockWidget->setWidget( new UASInfoWidget(this) );
pixhawk's avatar
pixhawk committed
361
        infoDockWidget->setObjectName("UAS_STATUS_DETAILS_DOCKWIDGET");
362
        addToToolsMenu (infoDockWidget, tr("Status Details"), SLOT(showToolWidget(bool)), MENU_STATUS, Qt::RightDockWidgetArea);
363
    }
364

365
    if (!debugConsoleDockWidget) {
366 367
        debugConsoleDockWidget = new QDockWidget(tr("Communication Console"), this);
        debugConsoleDockWidget->setWidget( new DebugConsole(this) );
368
        debugConsoleDockWidget->setObjectName("COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET");
369
        addToToolsMenu (debugConsoleDockWidget, tr("Communication Console"), SLOT(showToolWidget(bool)), MENU_DEBUG_CONSOLE, Qt::BottomDockWidgetArea);
370
    }
371

372
    if (!logPlayerDockWidget) {
373 374 375
        logPlayerDockWidget = new QDockWidget(tr("MAVLink Log Player"), this);
        logPlayerDockWidget->setWidget( new QGCMAVLinkLogPlayer(mavlink, this) );
        logPlayerDockWidget->setObjectName("MAVLINK_LOG_PLAYER_DOCKWIDGET");
376
        addToToolsMenu(logPlayerDockWidget, tr("MAVLink Log Replay"), SLOT(showToolWidget(bool)), MENU_MAVLINK_LOG_PLAYER, Qt::RightDockWidgetArea);
377 378
    }

lm's avatar
lm committed
379 380 381 382 383 384 385 386
    if (!mavlinkInspectorWidget)
    {
        mavlinkInspectorWidget = new QDockWidget(tr("MAVLink Message Inspector"), this);
        mavlinkInspectorWidget->setWidget( new QGCMAVLinkInspector(mavlink, this) );
        mavlinkInspectorWidget->setObjectName("MAVLINK_INSPECTOR_DOCKWIDGET");
        addToToolsMenu(mavlinkInspectorWidget, tr("MAVLink Inspector"), SLOT(showToolWidget(bool)), MENU_MAVLINK_INSPECTOR, Qt::RightDockWidgetArea);
    }

387
    // Center widgets
388 389
    if (!mapWidget)
    {
390
        mapWidget = new QGCMapTool(this);
391 392
        addToCentralWidgetsMenu (mapWidget, "Maps", SLOT(showCentralWidget()),CENTRAL_MAP);
    }
393

394
    if (!protocolWidget) {
395 396 397
        protocolWidget    = new XMLCommProtocolWidget(this);
        addToCentralWidgetsMenu (protocolWidget, "Mavlink Generator", SLOT(showCentralWidget()),CENTRAL_PROTOCOL);
    }
lm's avatar
lm committed
398

399
    if (!dataplotWidget) {
lm's avatar
lm committed
400
        dataplotWidget    = new QGCDataPlot2D(this);
401
        addToCentralWidgetsMenu (dataplotWidget, "Logfile Plot", SLOT(showCentralWidget()),CENTRAL_DATA_PLOT);
lm's avatar
lm committed
402
    }
403

lm's avatar
lm committed
404 405 406 407 408 409 410 411 412 413 414
    if (!hudWidget) {
        hudWidget         = new HUD(320, 240, this);
        addToCentralWidgetsMenu(hudWidget, tr("Head Up Display"), SLOT(showCentralWidget()), CENTRAL_HUD);
    }

    if (!hsiDockWidget) {
        hsiDockWidget = new QDockWidget(tr("Horizontal Situation Indicator"), this);
        hsiDockWidget->setWidget( new HSIDisplay(this) );
        hsiDockWidget->setObjectName("HORIZONTAL_SITUATION_INDICATOR_DOCK_WIDGET");
        addToToolsMenu (hsiDockWidget, tr("Horizontal Situation"), SLOT(showToolWidget(bool)), MENU_HSI, Qt::BottomDockWidgetArea);
    }
415

pixhawk's avatar
pixhawk committed
416 417
    //FIXME: memory of acceptList will never be freed again
    QStringList* acceptList = new QStringList();
pixhawk's avatar
pixhawk committed
418 419 420
    acceptList->append("-105,roll deg,deg,+105,s");
    acceptList->append("-105,pitch deg,deg,+105,s");
    acceptList->append("-105,heading deg,deg,+105,s");
421

pixhawk's avatar
pixhawk committed
422 423 424
    acceptList->append("-60,rollspeed d/s,deg/s,+60,s");
    acceptList->append("-60,pitchspeed d/s,deg/s,+60,s");
    acceptList->append("-60,yawspeed d/s,deg/s,+60,s");
425
    acceptList->append("0,airspeed,m/s,30");
426 427
    acceptList->append("0,groundspeed,m/s,30");
    acceptList->append("0,climbrate,m/s,30");
428
    acceptList->append("0,throttle,%,100");
429

pixhawk's avatar
pixhawk committed
430 431
    //FIXME: memory of acceptList2 will never be freed again
    QStringList* acceptList2 = new QStringList();
432 433 434
    acceptList2->append("900,servo #6,us,2100,s");
    acceptList2->append("900,servo #7,us,2100,s");
    acceptList2->append("900,servo #8,us,2100,s");
lm's avatar
lm committed
435
    acceptList2->append("0,abs pressure,hPa,65500");
436

lm's avatar
lm committed
437 438 439 440 441
    if (!headDown1DockWidget) {
        headDown1DockWidget = new QDockWidget(tr("Flight Instruments"), this);
        headDown1DockWidget->setWidget( new HDDisplay(acceptList, "Flight Display", this) );
        headDown1DockWidget->setObjectName("HEAD_DOWN_DISPLAY_1_DOCK_WIDGET");
        addToToolsMenu (headDown1DockWidget, tr("Flight Display"), SLOT(showToolWidget(bool)), MENU_HDD_1, Qt::RightDockWidgetArea);
442
    }
443

lm's avatar
lm committed
444 445 446 447 448 449
    if (!headDown2DockWidget) {
        headDown2DockWidget = new QDockWidget(tr("Payload Instruments"), this);
        headDown2DockWidget->setWidget( new HDDisplay(acceptList2, "Actuator Status", this) );
        headDown2DockWidget->setObjectName("HEAD_DOWN_DISPLAY_2_DOCK_WIDGET");
        addToToolsMenu (headDown2DockWidget, tr("Actuator Status"), SLOT(showToolWidget(bool)), MENU_HDD_2, Qt::RightDockWidgetArea);
    }
450

lm's avatar
lm committed
451 452 453 454 455
    if (!rcViewDockWidget) {
        rcViewDockWidget = new QDockWidget(tr("Radio Control"), this);
        rcViewDockWidget->setWidget( new QGCRemoteControlView(this) );
        rcViewDockWidget->setObjectName("RADIO_CONTROL_CHANNELS_DOCK_WIDGET");
        addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget(bool)), MENU_RC_VIEW, Qt::BottomDockWidgetArea);
456
    }
457

lm's avatar
lm committed
458 459 460 461 462 463 464 465 466 467 468 469
    if (!headUpDockWidget) {
        headUpDockWidget = new QDockWidget(tr("HUD"), this);
        headUpDockWidget->setWidget( new HUD(320, 240, this));
        headUpDockWidget->setObjectName("HEAD_UP_DISPLAY_DOCK_WIDGET");
        addToToolsMenu (headUpDockWidget, tr("Head Up Display"), SLOT(showToolWidget(bool)), MENU_HUD, Qt::RightDockWidgetArea);
    }

    if (!parametersDockWidget) {
        parametersDockWidget = new QDockWidget(tr("Onboard Parameters"), this);
        parametersDockWidget->setWidget( new ParameterInterface(this) );
        parametersDockWidget->setObjectName("PARAMETER_INTERFACE_DOCKWIDGET");
        addToToolsMenu (parametersDockWidget, tr("Calibration and Parameters"), SLOT(showToolWidget(bool)), MENU_PARAMETERS, Qt::RightDockWidgetArea);
470
    }
471

472
#ifdef QGC_OSG_ENABLED
473
    if (!_3DWidget) {
474
        _3DWidget         = Q3DWidgetFactory::get("PIXHAWK");
475
        addToCentralWidgetsMenu(_3DWidget, tr("Local 3D"), SLOT(showCentralWidget()), CENTRAL_3D_LOCAL);
476
    }
477
#endif
478

479
#if (defined _MSC_VER) | (defined Q_OS_MAC)
480
    if (!gEarthWidget) {
481
        gEarthWidget = new QGCGoogleEarthView(this);
482
        addToCentralWidgetsMenu(gEarthWidget, tr("Google Earth"), SLOT(showCentralWidget()), CENTRAL_GOOGLE_EARTH);
483
    }
484
#endif
lm's avatar
lm committed
485
}
486 487


lm's avatar
lm committed
488 489 490 491 492
void MainWindow::buildPxWidgets()
{
    // Dock widgets
    if (!detectionDockWidget)
    {
493 494
        detectionDockWidget = new QDockWidget(tr("Object Recognition"), this);
        detectionDockWidget->setWidget( new ObjectDetectionView("images/patterns", this) );
pixhawk's avatar
pixhawk committed
495
        detectionDockWidget->setObjectName("OBJECT_DETECTION_DOCK_WIDGET");
496
        addToToolsMenu (detectionDockWidget, tr("Object Recognition"), SLOT(showToolWidget(bool)), MENU_DETECTION, Qt::RightDockWidgetArea);
497
    }
498

lm's avatar
lm committed
499 500
    if (!watchdogControlDockWidget)
    {
501 502
        watchdogControlDockWidget = new QDockWidget(tr("Process Control"), this);
        watchdogControlDockWidget->setWidget( new WatchdogControl(this) );
pixhawk's avatar
pixhawk committed
503
        watchdogControlDockWidget->setObjectName("WATCHDOG_CONTROL_DOCKWIDGET");
504
        addToToolsMenu (watchdogControlDockWidget, tr("Process Control"), SLOT(showToolWidget(bool)), MENU_WATCHDOG, Qt::BottomDockWidgetArea);
505
    }
506

lm's avatar
lm committed
507 508
    if (!video1DockWidget)
    {
pixhawk's avatar
pixhawk committed
509 510 511 512 513 514 515
        video1DockWidget = new QDockWidget(tr("Video Stream 1"), this);
        HUD* video1 =  new HUD(160, 120, this);
        video1->enableHUDInstruments(false);
        video1->enableVideo(true);
        // FIXME select video stream as well
        video1DockWidget->setWidget(video1);
        video1DockWidget->setObjectName("VIDEO_STREAM_1_DOCK_WIDGET");
516
        addToToolsMenu (video1DockWidget, tr("Video Stream 1"), SLOT(showToolWidget(bool)), MENU_VIDEO_STREAM_1, Qt::LeftDockWidgetArea);
pixhawk's avatar
pixhawk committed
517 518
    }

lm's avatar
lm committed
519 520
    if (!video2DockWidget)
    {
pixhawk's avatar
pixhawk committed
521 522 523 524 525 526 527
        video2DockWidget = new QDockWidget(tr("Video Stream 2"), this);
        HUD* video2 =  new HUD(160, 120, this);
        video2->enableHUDInstruments(false);
        video2->enableVideo(true);
        // FIXME select video stream as well
        video2DockWidget->setWidget(video2);
        video2DockWidget->setObjectName("VIDEO_STREAM_2_DOCK_WIDGET");
528
        addToToolsMenu (video2DockWidget, tr("Video Stream 2"), SLOT(showToolWidget(bool)), MENU_VIDEO_STREAM_2, Qt::LeftDockWidgetArea);
529
    }
530

pixhawk's avatar
pixhawk committed
531 532
    // Dialogue widgets
    //FIXME: free memory in destructor
533 534 535 536
}

void MainWindow::buildSlugsWidgets()
{
537
    if (!linechartWidget) {
538 539
        // Center widgets
        linechartWidget   = new Linecharts(this);
540
        addToCentralWidgetsMenu(linechartWidget, tr("Realtime Plot"), SLOT(showCentralWidget()), CENTRAL_LINECHART);
541
    }
542

543
    if (!headUpDockWidget) {
544 545 546
        // Dock widgets
        headUpDockWidget = new QDockWidget(tr("Control Indicator"), this);
        headUpDockWidget->setWidget( new HUD(320, 240, this));
pixhawk's avatar
pixhawk committed
547
        headUpDockWidget->setObjectName("HEAD_UP_DISPLAY_DOCK_WIDGET");
548
        addToToolsMenu (headUpDockWidget, tr("Head Up Display"), SLOT(showToolWidget(bool)), MENU_HUD, Qt::LeftDockWidgetArea);
549
    }
550

551
    if (!rcViewDockWidget) {
552 553
        rcViewDockWidget = new QDockWidget(tr("Radio Control"), this);
        rcViewDockWidget->setWidget( new QGCRemoteControlView(this) );
pixhawk's avatar
pixhawk committed
554
        rcViewDockWidget->setObjectName("RADIO_CONTROL_CHANNELS_DOCK_WIDGET");
555
        addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget(bool)), MENU_RC_VIEW, Qt::BottomDockWidgetArea);
556
    }
557

558
#if (defined _MSC_VER) | (defined Q_OS_MAC)
559
    if (!gEarthWidget) {
560 561 562 563 564 565
        gEarthWidget = new QGCGoogleEarthView(this);
        addToCentralWidgetsMenu(gEarthWidget, tr("Google Earth"), SLOT(showCentralWidget()), CENTRAL_GOOGLE_EARTH);
    }

#endif

566
    if (!slugsDataWidget) {
567 568 569 570 571 572
        // Dialog widgets
        slugsDataWidget = new QDockWidget(tr("Slugs Data"), this);
        slugsDataWidget->setWidget( new SlugsDataSensorView(this));
        slugsDataWidget->setObjectName("SLUGS_DATA_DOCK_WIDGET");
        addToToolsMenu (slugsDataWidget, tr("Telemetry Data"), SLOT(showToolWidget(bool)), MENU_SLUGS_DATA, Qt::RightDockWidgetArea);
    }
573

574

575
    if (!slugsHilSimWidget) {
576 577 578 579 580
        slugsHilSimWidget = new QDockWidget(tr("Slugs Hil Sim"), this);
        slugsHilSimWidget->setWidget( new SlugsHilSim(this));
        slugsHilSimWidget->setObjectName("SLUGS_HIL_SIM_DOCK_WIDGET");
        addToToolsMenu (slugsHilSimWidget, tr("HIL Sim Configuration"), SLOT(showToolWidget(bool)), MENU_SLUGS_HIL, Qt::LeftDockWidgetArea);
    }
581

582 583
    if (!controlParameterWidget) {
        controlParameterWidget = new QDockWidget(tr("Control Parameters"), this);
584 585 586
        controlParameterWidget->setObjectName("UNMANNED_SYSTEM_CONTROL_PARAMETERWIDGET");
        controlParameterWidget->setWidget( new UASControlParameters(this) );
        addToToolsMenu (controlParameterWidget, tr("Control Parameters"), SLOT(showToolWidget(bool)), MENU_UAS_CONTROL_PARAM, Qt::LeftDockWidgetArea);
587
    }
588

589
    if (!parametersDockWidget) {
590 591 592 593 594 595
        parametersDockWidget = new QDockWidget(tr("Calibration and Onboard Parameters"), this);
        parametersDockWidget->setWidget( new ParameterInterface(this) );
        parametersDockWidget->setObjectName("PARAMETER_INTERFACE_DOCKWIDGET");
        addToToolsMenu (parametersDockWidget, tr("Calibration and Parameters"), SLOT(showToolWidget(bool)), MENU_PARAMETERS, Qt::RightDockWidgetArea);
    }

596
    if (!slugsCamControlWidget) {
597 598 599 600 601
        slugsCamControlWidget = new QDockWidget(tr("Camera Control"), this);
        slugsCamControlWidget->setWidget(new SlugsPadCameraControl(this));
        slugsCamControlWidget->setObjectName("SLUGS_CAM_CONTROL_DOCK_WIDGET");
        addToToolsMenu (slugsCamControlWidget, tr("Camera Control"), SLOT(showToolWidget(bool)), MENU_SLUGS_CAMERA, Qt::BottomDockWidgetArea);
    }
602

603
}
604 605 606


void MainWindow::addToCentralWidgetsMenu ( QWidget* widget,
607 608 609
        const QString title,
        const char * slotName,
        TOOLS_WIDGET_NAMES centralWidget)
610
{
611
    QAction* tempAction;
612

613
    tempAction = ui.menuMain->addAction(title);
614

615 616
    tempAction->setCheckable(true);
    tempAction->setData(centralWidget);
617

618 619 620
    // populate the Hashes
    toolsMenuActions[centralWidget] = tempAction;
    dockWidgets[centralWidget] = widget;
621

622
    QString chKey = buildMenuKey(SUB_SECTION_CHECKED, centralWidget, currentView);
623

lm's avatar
lm committed
624 625
    if (!settings.contains(chKey))
    {
626 627
        settings.setValue(chKey,false);
        tempAction->setChecked(false);
lm's avatar
lm committed
628 629 630
    }
    else
    {
631 632
        tempAction->setChecked(settings.value(chKey).toBool());
    }
633

634
    // connect the action
635
    connect(tempAction,SIGNAL(triggered(bool)),this, slotName);
636 637 638
}


lm's avatar
lm committed
639 640
void MainWindow::showCentralWidget()
{
641
    QAction* senderAction = qobject_cast<QAction *>(sender());
642 643 644 645

    // Block sender action while manipulating state
    senderAction->blockSignals(true);

646 647
    int tool = senderAction->data().toInt();
    QString chKey;
648

649
    // check the current action
650

lm's avatar
lm committed
651 652
    if (senderAction && dockWidgets[tool])
    {
653 654
        // uncheck all central widget actions
        QHashIterator<int, QAction*> i(toolsMenuActions);
655
        while (i.hasNext()) {
656
            i.next();
657
            //qDebug() << "shCW" << i.key() << "read";
lm's avatar
lm committed
658 659
            if (i.value() && i.value()->data().toInt() > 255)
            {
660 661 662
                // Block signals and uncheck action
                // firing would be unneccesary
                i.value()->blockSignals(true);
663
                i.value()->setChecked(false);
664
                i.value()->blockSignals(false);
665 666 667 668 669 670

                // update the settings
                chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.value()->data().toInt()), currentView);
                settings.setValue(chKey,false);
            }
        }
671

672
        // check the current action
673
        //qDebug() << senderAction->text();
674
        senderAction->setChecked(true);
675

676 677
        // update the central widget
        centerStack->setCurrentWidget(dockWidgets[tool]);
678

679 680 681
        // store the selected central widget
        chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(tool), currentView);
        settings.setValue(chKey,true);
682

683 684 685
        // Unblock sender action
        senderAction->blockSignals(false);

686 687
        presentView();
    }
688
}
689

lm's avatar
lm committed
690 691 692 693
/**
 * Adds a widget to the tools menu and sets it visible if it was
 * enabled last time.
 */
694
void MainWindow::addToToolsMenu ( QWidget* widget,
695 696 697 698
                                  const QString title,
                                  const char * slotName,
                                  TOOLS_WIDGET_NAMES tool,
                                  Qt::DockWidgetArea location)
lm's avatar
lm committed
699
{
700 701
    QAction* tempAction;
    QString posKey, chKey;
702

703

704
    if (toolsMenuActions[CENTRAL_SEPARATOR]) {
705 706 707
        tempAction = new QAction(title, this);
        ui.menuTools->insertAction(toolsMenuActions[CENTRAL_SEPARATOR],
                                   tempAction);
708
    } else {
709 710
        tempAction = ui.menuTools->addAction(title);
    }
711

712 713
    tempAction->setCheckable(true);
    tempAction->setData(tool);
714

715 716 717
    // populate the Hashes
    toolsMenuActions[tool] = tempAction;
    dockWidgets[tool] = widget;
718
    //qDebug() << widget;
719

720
    posKey = buildMenuKey (SUB_SECTION_LOCATION,tool, currentView);
721

722
    if (!settings.contains(posKey)) {
723 724
        settings.setValue(posKey,location);
        dockWidgetLocations[tool] = location;
725
    } else {
726
        dockWidgetLocations[tool] = static_cast <Qt::DockWidgetArea> (settings.value(posKey, Qt::RightDockWidgetArea).toInt());
727
    }
728

729
    chKey = buildMenuKey(SUB_SECTION_CHECKED,tool, currentView);
730

731
    if (!settings.contains(chKey)) {
732 733
        settings.setValue(chKey,false);
        tempAction->setChecked(false);
734
        widget->setVisible(false);
735
    } else {
736
        tempAction->setChecked(settings.value(chKey, false).toBool());
737
        widget->setVisible(settings.value(chKey, false).toBool());
738
    }
739

740
    // connect the action
741 742 743
    connect(tempAction,SIGNAL(toggled(bool)),this, slotName);

    connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
744
            SIGNAL(visibilityChanged(bool)), this, SLOT(showToolWidget(bool)));
745

746 747
    //  connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
    //          SIGNAL(visibilityChanged(bool)), this, SLOT(updateVisibilitySettings(bool)));
748

749 750
    connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
            SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(updateLocationSettings(Qt::DockWidgetArea)));
751 752
}

753
void MainWindow::showToolWidget(bool visible)
754
{
755
    if (!aboutToCloseFlag && !changingViewsFlag) {
756 757
        QAction* action = qobject_cast<QAction *>(sender());

758
        // Prevent this to fire if undocked
759
        if (action) {
760
            int tool = action->data().toInt();
761

762
            QDockWidget* dockWidget = qobject_cast<QDockWidget *> (dockWidgets[tool]);
763

764 765
            if (dockWidget && dockWidget->isVisible() != visible) {
                if (visible) {
766 767
                    addDockWidget(dockWidgetLocations[tool], dockWidget);
                    dockWidget->show();
768
                } else {
769 770
                    removeDockWidget(dockWidget);
                }
771 772

                QHashIterator<int, QWidget*> i(dockWidgets);
773
                while (i.hasNext()) {
774
                    i.next();
775
                    if ((static_cast <QDockWidget *>(dockWidgets[i.key()])) == dockWidget) {
776 777
                        QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
                        settings.setValue(chKey,visible);
778
                        //qDebug() << "showToolWidget(): Set key" << chKey << "to" << visible;
779 780 781
                        break;
                    }
                }
782
            }
783
        }
784 785 786

        QDockWidget* dockWidget = qobject_cast<QDockWidget*>(QObject::sender());

787
        //qDebug() << "Trying to cast dockwidget" << dockWidget << "isvisible" << visible;
788

lm's avatar
lm committed
789 790
        if (dockWidget)
        {
791 792 793
            // Get action
            int tool = dockWidgets.key(dockWidget);

794
            //qDebug() << "Updating widget setting" << tool << "to" << visible;
795 796 797 798 799 800 801

            QAction* action = toolsMenuActions[tool];
            action->blockSignals(true);
            action->setChecked(visible);
            action->blockSignals(false);

            QHashIterator<int, QWidget*> i(dockWidgets);
802
            while (i.hasNext()) {
803
                i.next();
804
                if ((static_cast <QDockWidget *>(dockWidgets[i.key()])) == dockWidget) {
805 806
                    QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
                    settings.setValue(chKey,visible);
807
                    // qDebug() << "showToolWidget(): Set key" << chKey << "to" << visible;
808 809 810
                    break;
                }
            }
811
        }
812 813 814 815
    }
}


816 817 818 819 820
void MainWindow::showTheWidget (TOOLS_WIDGET_NAMES widget, VIEW_SECTIONS view)
{
    bool tempVisible;
    Qt::DockWidgetArea tempLocation;
    QDockWidget* tempWidget = static_cast <QDockWidget *>(dockWidgets[widget]);
821

822
    tempVisible =  settings.value(buildMenuKey(SUB_SECTION_CHECKED,widget,view), false).toBool();
823

824
    //qDebug() << "showTheWidget(): Set key" << buildMenuKey(SUB_SECTION_CHECKED,widget,view) << "to" << tempVisible;
825

826
    if (tempWidget) {
827 828
        toolsMenuActions[widget]->setChecked(tempVisible);
    }
829 830


831
    //qDebug() <<  buildMenuKey (SUB_SECTION_CHECKED,widget,view) << tempVisible;
832

833 834
    tempLocation = static_cast <Qt::DockWidgetArea>(settings.value(buildMenuKey (SUB_SECTION_LOCATION,widget, view), QVariant(Qt::RightDockWidgetArea)).toInt());

lm's avatar
lm committed
835 836 837 838
    if (tempWidget != NULL)
    {
        if (tempVisible)
        {
839 840 841
            addDockWidget(tempLocation, tempWidget);
            tempWidget->show();
        }
842 843
    }
}
844

845 846 847
QString MainWindow::buildMenuKey(SETTINGS_SECTIONS section, TOOLS_WIDGET_NAMES tool, VIEW_SECTIONS view)
{
    // Key is built as follows: autopilot_type/section_menu/view/tool/section
lm's avatar
lm committed
848
    int apType = 1;
849

850 851 852 853 854
    return (QString::number(apType) + "_" +
            QString::number(SECTION_MENU) + "_" +
            QString::number(view) + "_" +
            QString::number(tool) + "_" +
            QString::number(section) + "_" );
855 856
}

857 858
void MainWindow::closeEvent(QCloseEvent *event)
{
859
    storeSettings();
860
    aboutToCloseFlag = true;
861
    mavlink->storeSettings();
862
    UASManager::instance()->storeSettings();
863 864
    QMainWindow::closeEvent(event);
}
865

866 867
void MainWindow::showDockWidget (bool vis)
{
868
    if (!aboutToCloseFlag && !changingViewsFlag) {
869 870
        QDockWidget* temp = qobject_cast<QDockWidget *>(sender());

871
        if (temp) {
872
            QHashIterator<int, QWidget*> i(dockWidgets);
873
            while (i.hasNext()) {
874
                i.next();
875
                if ((static_cast <QDockWidget *>(dockWidgets[i.key()])) == temp) {
876 877 878 879 880 881 882 883 884
                    QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
                    settings.setValue(chKey,vis);
                    toolsMenuActions[i.key()]->setChecked(vis);
                    break;
                }
            }
        }
    }
}
885

886 887
void MainWindow::updateVisibilitySettings (bool vis)
{
888
    if (!aboutToCloseFlag && !changingViewsFlag) {
889 890
        QDockWidget* temp = qobject_cast<QDockWidget *>(sender());

891
        if (temp) {
892
            QHashIterator<int, QWidget*> i(dockWidgets);
893
            while (i.hasNext()) {
894
                i.next();
895
                if ((static_cast <QDockWidget *>(dockWidgets[i.key()])) == temp) {
896 897
                    QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
                    settings.setValue(chKey,vis);
898 899 900 901 902 903
                    toolsMenuActions[i.key()]->setChecked(vis);
                    break;
                }
            }
        }
    }
904 905
}

906 907 908
void MainWindow::updateLocationSettings (Qt::DockWidgetArea location)
{
    QDockWidget* temp = qobject_cast<QDockWidget *>(sender());
909

910
    QHashIterator<int, QWidget*> i(dockWidgets);
911
    while (i.hasNext()) {
912
        i.next();
913
        if ((static_cast <QDockWidget *>(dockWidgets[i.key()])) == temp) {
914 915 916 917 918
            QString posKey = buildMenuKey (SUB_SECTION_LOCATION,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
            settings.setValue(posKey,location);
            break;
        }
    }
919 920
}

921

922 923 924
/**
 * Connect the signals and slots of the common window widgets
 */
925
void MainWindow::connectCommonWidgets()
926
{
927
    if (infoDockWidget && infoDockWidget->widget()) {
pixhawk's avatar
pixhawk committed
928 929 930
        connect(mavlink, SIGNAL(receiveLossChanged(int, float)),
                infoDockWidget->widget(), SLOT(updateSendLoss(int, float)));
    }
931
}
932

933 934
void MainWindow::createCustomWidget()
{
935 936
    QDockWidget* dock = new QDockWidget("Unnamed Tool", this);
    QGCToolWidget* tool = new QGCToolWidget("Unnamed Tool", dock);
lm's avatar
lm committed
937

LM's avatar
LM committed
938 939
    if (QGCToolWidget::instances()->size() < 2)
    {
lm's avatar
lm committed
940 941 942 943 944
        // This is the first widget
        ui.menuTools->addSeparator();
    }

    connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater()));
945
    dock->setWidget(tool);
946

947 948 949 950 951 952 953 954 955 956 957 958 959 960 961
    QAction* showAction = new QAction(tool->getTitle(), this);
    showAction->setCheckable(true);
    connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool)));
    connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool)));
    tool->setMainMenuAction(showAction);
    ui.menuTools->addAction(showAction);
    this->addDockWidget(Qt::BottomDockWidgetArea, dock);
    dock->setVisible(true);
}

void MainWindow::loadCustomWidget()
{
    QString widgetFileExtension(".qgw");
    QString fileName = QFileDialog::getOpenFileName(this, tr("Specify Widget File Name"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("QGroundControl Widget (*%1);;").arg(widgetFileExtension));

LM's avatar
LM committed
962 963
    if (fileName.length() > 0)
    {
964

LM's avatar
LM committed
965 966
        QGCToolWidget* tool = new QGCToolWidget("", this);
        tool->loadSettings(fileName);
967

LM's avatar
LM committed
968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988
        if (QGCToolWidget::instances()->size() < 2)
        {
            // This is the first widget
            ui.menuTools->addSeparator();
        }

        // Add widget to UI
        QDockWidget* dock = new QDockWidget(tool->getTitle(), this);
        connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater()));
        dock->setWidget(tool);
        tool->setParent(dock);

        QAction* showAction = new QAction(tool->getTitle(), this);
        showAction->setCheckable(true);
        connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool)));
        connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool)));
        tool->setMainMenuAction(showAction);
        ui.menuTools->addAction(showAction);
        this->addDockWidget(Qt::BottomDockWidgetArea, dock);
        dock->setVisible(true);
    }
989 990 991 992
}

void MainWindow::connectPxWidgets()
{
993
    // No special connections necessary at this point
994 995 996 997
}

void MainWindow::connectSlugsWidgets()
{
998
    if (slugsHilSimWidget && slugsHilSimWidget->widget()) {
999 1000
        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                slugsHilSimWidget->widget(), SLOT(activeUasSet(UASInterface*)));
1001 1002
    }

1003
    if (slugsDataWidget && slugsDataWidget->widget()) {
1004 1005
        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                slugsDataWidget->widget(), SLOT(setActiveUAS(UASInterface*)));
1006 1007
    }

1008
    if (controlParameterWidget && controlParameterWidget->widget()) {
1009 1010 1011
        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                controlParameterWidget->widget(), SLOT(activeUasSet(UASInterface*)));
    }
1012

1013 1014
    if(controlDockWidget && controlParameterWidget) {
        connect(controlDockWidget->widget(), SIGNAL(changedMode(int)), controlParameterWidget->widget(), SLOT(changedMode(int)));
1015
    }
1016 1017
}

1018
void MainWindow::arrangeCommonCenterStack()
1019
{
1020
    centerStack = new QStackedWidget(this);
1021
    centerStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1022

pixhawk's avatar
pixhawk committed
1023
    if (!centerStack) return;
1024

1025
    if (mapWidget && (centerStack->indexOf(mapWidget) == -1)) centerStack->addWidget(mapWidget);
lm's avatar
lm committed
1026
    if (dataplotWidget && (centerStack->indexOf(dataplotWidget) == -1)) centerStack->addWidget(dataplotWidget);
1027 1028
    if (protocolWidget && (centerStack->indexOf(protocolWidget) == -1)) centerStack->addWidget(protocolWidget);
    if (linechartWidget && (centerStack->indexOf(linechartWidget) == -1)) centerStack->addWidget(linechartWidget);
1029

1030
#ifdef QGC_OSG_ENABLED
1031
    if (_3DWidget && (centerStack->indexOf(_3DWidget) == -1)) centerStack->addWidget(_3DWidget);
1032
#endif
1033
#if (defined _MSC_VER) | (defined Q_OS_MAC)
1034
    if (gEarthWidget && (centerStack->indexOf(gEarthWidget) == -1)) centerStack->addWidget(gEarthWidget);
1035
#endif
1036 1037
    if (hudWidget && (centerStack->indexOf(hudWidget) == -1)) centerStack->addWidget(hudWidget);