MainWindow.cc 45.2 KB
Newer Older
1
/*===================================================================
pixhawk's avatar
pixhawk committed
2 3 4 5
======================================================================*/

/**
 * @file
6
 *   @brief Implementation of class MainWindow
7
 *   @author Lorenz Meier <mail@qgroundcontrol.org>
pixhawk's avatar
pixhawk committed
8 9 10 11 12 13 14 15 16 17 18
 */

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

#include "MG.h"
19
#include "QGC.h"
pixhawk's avatar
pixhawk committed
20 21 22 23 24 25 26 27
#include "MAVLinkSimulationLink.h"
#include "SerialLink.h"
#include "UDPLink.h"
#include "MAVLinkProtocol.h"
#include "CommConfigurationWindow.h"
#include "WaypointList.h"
#include "MainWindow.h"
#include "JoystickWidget.h"
pixhawk's avatar
pixhawk committed
28
#include "GAudioOutput.h"
29
#include "QGCToolWidget.h"
30

31
#ifdef QGC_OSG_ENABLED
32
#include "Q3DWidgetFactory.h"
33
#endif
pixhawk's avatar
pixhawk committed
34

lm's avatar
lm committed
35 36 37 38
// FIXME Move
#include "PxQuadMAV.h"
#include "SlugsMAV.h"

pixhawk's avatar
pixhawk committed
39 40 41

#include "LogCompressor.h"

42 43
MainWindow* MainWindow::instance()
{
44 45 46 47
    static MainWindow* _instance = 0;
    if(_instance == 0)
    {
        _instance = new MainWindow();
48

49
        /* Set the application as parent to ensure that this object
50
                 * will be destroyed when the main application exits */
51 52 53
        //_instance->setParent(qApp);
    }
    return _instance;
54 55
}

pixhawk's avatar
pixhawk committed
56 57 58 59 60 61 62
/**
* 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()
**/
63
MainWindow::MainWindow(QWidget *parent):
pixhawk's avatar
pixhawk committed
64
        QMainWindow(parent),
65
        toolsMenuActions(),
66 67
        currentView(VIEW_OPERATOR),
        aboutToCloseFlag(false),
pixhawk's avatar
pixhawk committed
68
        settings()
pixhawk's avatar
pixhawk committed
69
{
70 71
    // Get current settings
    settings.sync();
72

73 74 75 76 77
    // Check if the settings exist, instantiate defaults if necessary
    QString centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_MAP, currentView);
    if (!settings.contains(centralKey))
    {
        settings.setValue(centralKey,true);
78 79 80 81 82
    }

    QString listKey = buildMenuKey(SUB_SECTION_CHECKED, MENU_UAS_LIST, currentView);
    if (!settings.contains(listKey))
    {
83 84
        settings.setValue(listKey, true);
    }
85

86 87
    settings.sync();

pixhawk's avatar
pixhawk committed
88 89 90
    // Setup user interface
    ui.setupUi(this);

91
    buildCommonWidgets();
92

93
    connectCommonWidgets();
94

95
    arrangeCommonCenterStack();
96 97

    configureWindowName();
pixhawk's avatar
pixhawk committed
98 99

    // Add status bar
100
    //setStatusBar(createStatusBar());
pixhawk's avatar
pixhawk committed
101 102 103 104

    // Set the application style (not the same as a style sheet)
    // Set the style to Plastique
    qApp->setStyle("plastique");
105

pixhawk's avatar
pixhawk committed
106 107 108
    // Set style sheet as last step
    reloadStylesheet();

109
    // Create actions
110
    connectCommonActions();
111 112
    // Add option for custom widgets
    connect(ui.actionNewCustomWidget, SIGNAL(triggered()), this, SLOT(createCustomWidget()));
113 114 115
    // Allow to mute audio
    ui.actionMuteAudioOutput->setChecked(GAudioOutput::instance()->isMuted());
    connect(ui.actionMuteAudioOutput, SIGNAL(triggered(bool)), GAudioOutput::instance(), SLOT(mute(bool)));
116

117 118 119
    // Set dock options
    setDockOptions(AnimatedDocks | AllowTabbedDocks | AllowNestedDocks);

120
    // Load mavlink view as default widget set
121
    //loadMAVLinkView();
122

lm's avatar
lm committed
123 124
    statusBar()->setSizeGripEnabled(true);

125 126 127 128 129 130 131 132 133 134
    if (settings.contains("geometry"))
    {
        // Restore the window geometry
        restoreGeometry(settings.value("geometry").toByteArray());
    }
    else
    {
        // Adjust the size
        adjustSize();
    }
pixhawk's avatar
pixhawk committed
135

136 137 138 139 140 141
    // Populate link menu
    QList<LinkInterface*> links = LinkManager::instance()->getLinks();
    foreach(LinkInterface* link, links)
    {
        this->addLink(link);
    }
142

lm's avatar
lm committed
143 144
    // Enable and update view
    presentView();
pixhawk's avatar
pixhawk committed
145 146
}

pixhawk's avatar
pixhawk committed
147
MainWindow::~MainWindow()
pixhawk's avatar
pixhawk committed
148
{
lm's avatar
lm committed
149

pixhawk's avatar
pixhawk committed
150 151
}

152 153 154 155
void MainWindow::buildCommonWidgets()
{
    //TODO:  move protocol outside UI
    mavlink     = new MAVLinkProtocol();
156
    connect(mavlink, SIGNAL(protocolStatusMessage(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection);
157 158

    // Dock widgets
159 160 161 162 163 164
    if (!controlDockWidget)
    {
        controlDockWidget = new QDockWidget(tr("Control"), this);
        controlDockWidget->setWidget( new UASControlWidget(this) );
        addToToolsMenu (controlDockWidget, tr("Control"), SLOT(showToolWidget()), MENU_UAS_CONTROL, Qt::LeftDockWidgetArea);
    }
165

166 167 168 169 170 171
    if (!listDockWidget)
    {
        listDockWidget = new QDockWidget(tr("Unmanned Systems"), this);
        listDockWidget->setWidget( new UASListWidget(this) );
        addToToolsMenu (listDockWidget, tr("Unmanned Systems"), SLOT(showToolWidget()), MENU_UAS_LIST, Qt::RightDockWidgetArea);
    }
172

173 174 175 176 177 178
    if (!waypointsDockWidget)
    {
        waypointsDockWidget = new QDockWidget(tr("Waypoint List"), this);
        waypointsDockWidget->setWidget( new WaypointList(this, NULL) );
        addToToolsMenu (waypointsDockWidget, tr("Waypoints List"), SLOT(showToolWidget()), MENU_WAYPOINTS, Qt::BottomDockWidgetArea);
    }
179

180 181 182 183 184 185
    if (!infoDockWidget)
    {
        infoDockWidget = new QDockWidget(tr("Status Details"), this);
        infoDockWidget->setWidget( new UASInfoWidget(this) );
        addToToolsMenu (infoDockWidget, tr("Status Details"), SLOT(showToolWidget()), MENU_STATUS, Qt::RightDockWidgetArea);
    }
186

187 188 189 190 191 192
    if (!debugConsoleDockWidget)
    {
        debugConsoleDockWidget = new QDockWidget(tr("Communication Console"), this);
        debugConsoleDockWidget->setWidget( new DebugConsole(this) );
        addToToolsMenu (debugConsoleDockWidget, tr("Communication Console"), SLOT(showToolWidget()), MENU_DEBUG_CONSOLE, Qt::BottomDockWidgetArea);
    }
193

194
    // Center widgets
195 196 197 198 199
    if (!mapWidget)
    {
        mapWidget         = new MapWidget(this);
        addToCentralWidgetsMenu (mapWidget, "Maps", SLOT(showCentralWidget()),CENTRAL_MAP);
    }
200

201 202 203 204 205
    if (!protocolWidget)
    {
        protocolWidget    = new XMLCommProtocolWidget(this);
        addToCentralWidgetsMenu (protocolWidget, "Mavlink Generator", SLOT(showCentralWidget()),CENTRAL_PROTOCOL);
    }
206
}
207

208
void MainWindow::buildPxWidgets()
209
{
pixhawk's avatar
pixhawk committed
210 211
    //FIXME: memory of acceptList will never be freed again
    QStringList* acceptList = new QStringList();
212 213 214 215 216 217 218
    acceptList->append("-180,roll (deg),+180");
    acceptList->append("-180,pitch (deg),+180");
    acceptList->append("-180,yaw (deg),+180");

    acceptList->append("-500,roll V (deg/s),+500");
    acceptList->append("-500,pitch V (deg/s),+500");
    acceptList->append("-500,yaw V (deg/s),+500");
219

pixhawk's avatar
pixhawk committed
220 221
    //FIXME: memory of acceptList2 will never be freed again
    QStringList* acceptList2 = new QStringList();
222 223 224
    acceptList2->append("0,Abs pressure,65500");
    acceptList2->append("-2000,Accel. X, 2000");
    acceptList2->append("-2000,Accel. Y, 2000");
225

226 227 228 229 230 231
    if (!linechartWidget)
    {
        // Center widgets
        linechartWidget   = new Linecharts(this);
        addToCentralWidgetsMenu(linechartWidget, "Line Plots", SLOT(showCentralWidget()), CENTRAL_LINECHART);
    }
232 233


234 235 236 237 238
    if (!hudWidget)
    {
        hudWidget         = new HUD(320, 240, this);
        addToCentralWidgetsMenu(hudWidget, "HUD", SLOT(showCentralWidget()), CENTRAL_HUD);
    }
239

240 241 242 243 244
    if (!dataplotWidget)
    {
        dataplotWidget    = new QGCDataPlot2D(this);
        addToCentralWidgetsMenu(dataplotWidget, "Data Plots", SLOT(showCentralWidget()), CENTRAL_DATA_PLOT);
    }
245

246
#ifdef QGC_OSG_ENABLED
247 248 249 250 251
    if (!_3DWidget)
    {
        _3DWidget         = Q3DWidgetFactory::get("PIXHAWK");
        addToCentralWidgetsMenu(_3DWidget, "Local 3D", SLOT(showCentralWidget()), CENTRAL_3D_LOCAL);
    }
252
#endif
253

254
#ifdef QGC_OSGEARTH_ENABLED
255 256 257 258 259
    if (!_3DMapWidget)
    {
        _3DMapWidget = Q3DWidgetFactory::get("MAP3D");
        addToCentralWidgetsMenu(_3DMapWidget, "OSG Earth 3D", SLOT(showCentralWidget()), CENTRAL_OSGEARTH);
    }
260
#endif
lm's avatar
lm committed
261

262
#if (defined _MSC_VER) | (defined Q_OS_MAC)
263 264 265 266 267
    if (!gEarthWidget)
    {
        gEarthWidget = new QGCGoogleEarthView(this);
        addToCentralWidgetsMenu(gEarthWidget, "Google Earth", SLOT(showCentralWidget()), CENTRAL_GOOGLE_EARTH);
    }
268

269
#endif
270

pixhawk's avatar
pixhawk committed
271
    // Dock widgets
272

273 274 275 276 277 278
    if (!detectionDockWidget)
    {
        detectionDockWidget = new QDockWidget(tr("Object Recognition"), this);
        detectionDockWidget->setWidget( new ObjectDetectionView("images/patterns", this) );
        addToToolsMenu (detectionDockWidget, tr("Object Recognition"), SLOT(showToolWidget()), MENU_DETECTION, Qt::RightDockWidgetArea);
    }
279

280 281 282 283 284 285
    if (!parametersDockWidget)
    {
        parametersDockWidget = new QDockWidget(tr("Onboard Parameters"), this);
        parametersDockWidget->setWidget( new ParameterInterface(this) );
        addToToolsMenu (parametersDockWidget, tr("Onboard Parameters"), SLOT(showToolWidget()), MENU_PARAMETERS, Qt::RightDockWidgetArea);
    }
286

287 288 289 290 291 292
    if (!watchdogControlDockWidget)
    {
        watchdogControlDockWidget = new QDockWidget(tr("Process Control"), this);
        watchdogControlDockWidget->setWidget( new WatchdogControl(this) );
        addToToolsMenu (watchdogControlDockWidget, tr("Process Control"), SLOT(showToolWidget()), MENU_WATCHDOG, Qt::BottomDockWidgetArea);
    }
293

294 295 296 297 298 299
    if (!hsiDockWidget)
    {
        hsiDockWidget = new QDockWidget(tr("Horizontal Situation Indicator"), this);
        hsiDockWidget->setWidget( new HSIDisplay(this) );
        addToToolsMenu (hsiDockWidget, tr("HSI"), SLOT(showToolWidget()), MENU_HSI, Qt::BottomDockWidgetArea);
    }
300

301 302
    if (!headDown1DockWidget)
    {
303 304
        headDown1DockWidget = new QDockWidget(tr("Flight Display"), this);
        headDown1DockWidget->setWidget( new HDDisplay(acceptList, "Flight Display", this) );
305 306
        addToToolsMenu (headDown1DockWidget, tr("Flight Display"), SLOT(showToolWidget()), MENU_HDD_1, Qt::RightDockWidgetArea);
    }
307

308 309 310
    if (!headDown2DockWidget)
    {
        headDown2DockWidget = new QDockWidget(tr("Payload Status"), this);
311
        headDown2DockWidget->setWidget( new HDDisplay(acceptList2, "Payload Status", this) );
312 313
        addToToolsMenu (headDown2DockWidget, tr("Payload Status"), SLOT(showToolWidget()), MENU_HDD_2, Qt::RightDockWidgetArea);
    }
314

315 316 317 318 319 320
    if (!rcViewDockWidget)
    {
        rcViewDockWidget = new QDockWidget(tr("Radio Control"), this);
        rcViewDockWidget->setWidget( new QGCRemoteControlView(this) );
        addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget()), MENU_RC_VIEW, Qt::BottomDockWidgetArea);
    }
321

322 323 324 325 326 327
    if (!headUpDockWidget)
    {
        headUpDockWidget = new QDockWidget(tr("HUD"), this);
        headUpDockWidget->setWidget( new HUD(320, 240, this));
        addToToolsMenu (headUpDockWidget, tr("Control Indicator"), SLOT(showToolWidget()), MENU_HUD, Qt::LeftDockWidgetArea);
    }
328

pixhawk's avatar
pixhawk committed
329 330
    // Dialogue widgets
    //FIXME: free memory in destructor
331 332 333 334
    if (!joystick)
    {
        joystick    = new JoystickInput();
    }
335

336 337 338 339
}

void MainWindow::buildSlugsWidgets()
{
340 341 342 343 344
    if (!linechartWidget)
    {
        // Center widgets
        linechartWidget   = new Linecharts(this);
    }
345

346 347 348 349 350 351 352
    if (!headUpDockWidget)
    {
        // Dock widgets
        headUpDockWidget = new QDockWidget(tr("Control Indicator"), this);
        headUpDockWidget->setWidget( new HUD(320, 240, this));
        addToToolsMenu (headUpDockWidget, tr("HUD"), SLOT(showToolWidget()), MENU_HUD, Qt::LeftDockWidgetArea);
    }
353

354 355 356 357 358 359
    if (!rcViewDockWidget)
    {
        rcViewDockWidget = new QDockWidget(tr("Radio Control"), this);
        rcViewDockWidget->setWidget( new QGCRemoteControlView(this) );
        addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget()), MENU_RC_VIEW, Qt::BottomDockWidgetArea);
    }
360

361 362 363 364 365 366 367
    if (!slugsDataWidget)
    {
        // Dialog widgets
        slugsDataWidget = new QDockWidget(tr("Slugs Data"), this);
        slugsDataWidget->setWidget( new SlugsDataSensorView(this));
        addToToolsMenu (slugsDataWidget, tr("Telemetry Data"), SLOT(showToolWidget()), MENU_SLUGS_DATA, Qt::RightDockWidgetArea);
    }
368

369 370 371 372 373 374
    if (!slugsPIDControlWidget)
    {
        slugsPIDControlWidget = new QDockWidget(tr("Slugs PID Control"), this);
        slugsPIDControlWidget->setWidget(new SlugsPIDControl(this));
        addToToolsMenu (slugsPIDControlWidget, tr("PID Configuration"), SLOT(showToolWidget()), MENU_SLUGS_PID, Qt::LeftDockWidgetArea);
    }
375

376 377 378 379 380 381
    if (!slugsHilSimWidget)
    {
        slugsHilSimWidget = new QDockWidget(tr("Slugs Hil Sim"), this);
        slugsHilSimWidget->setWidget( new SlugsHilSim(this));
        addToToolsMenu (slugsHilSimWidget, tr("HIL Sim Configuration"), SLOT(showToolWidget()), MENU_SLUGS_HIL, Qt::LeftDockWidgetArea);
    }
382

383 384 385 386 387 388
    if (!slugsCamControlWidget)
    {
        slugsCamControlWidget = new QDockWidget(tr("Slugs Video Camera Control"), this);
        slugsCamControlWidget->setWidget(new SlugsVideoCamControl(this));
        addToToolsMenu (slugsCamControlWidget, tr("Camera Control"), SLOT(showToolWidget()), MENU_SLUGS_CAMERA, Qt::BottomDockWidgetArea);
    }
389
}
390 391 392 393 394


void MainWindow::addToCentralWidgetsMenu ( QWidget* widget,
                                           const QString title,
                                           const char * slotName,
395 396
                                           TOOLS_WIDGET_NAMES centralWidget)
{
397
    QAction* tempAction;
398

399

400
    // Add the separator that will separate tools from central Widgets
401 402
    if (!toolsMenuActions[CENTRAL_SEPARATOR])
    {
403 404 405 406
        tempAction = ui.menuTools->addSeparator();
        toolsMenuActions[CENTRAL_SEPARATOR] = tempAction;
        tempAction->setData(CENTRAL_SEPARATOR);
    }
407

408
    tempAction = ui.menuTools->addAction(title);
409

410 411
    tempAction->setCheckable(true);
    tempAction->setData(centralWidget);
412

413 414 415
    // populate the Hashes
    toolsMenuActions[centralWidget] = tempAction;
    dockWidgets[centralWidget] = widget;
416

417
    QString chKey = buildMenuKey(SUB_SECTION_CHECKED, centralWidget, currentView);
418

419 420
    if (!settings.contains(chKey))
    {
421 422 423
        settings.setValue(chKey,false);
        tempAction->setChecked(false);
    }
424 425 426 427
    else
    {
        tempAction->setChecked(settings.value(chKey).toBool());
    }
428

429 430
    // connect the action
    connect(tempAction,SIGNAL(triggered()),this, slotName);
431 432 433
}


lm's avatar
lm committed
434 435
void MainWindow::showCentralWidget()
{
436 437 438
    QAction* senderAction = qobject_cast<QAction *>(sender());
    int tool = senderAction->data().toInt();
    QString chKey;
439

440
    // check the current action
441

442 443
    if (senderAction && dockWidgets[tool])
    {
444

445 446 447 448 449 450 451 452 453 454 455 456 457
        // uncheck all central widget actions
        QHashIterator<int, QAction*> i(toolsMenuActions);
        while (i.hasNext()) {
            i.next();
            qDebug() << "shCW" << i.key() << "read";
            if (i.value() && i.value()->data().toInt() > 255){
                i.value()->setChecked(false);

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

459 460 461
        // check the current action
        qDebug() << senderAction->text();
        senderAction->setChecked(true);
462

463 464
        // update the central widget
        centerStack->setCurrentWidget(dockWidgets[tool]);
465

466 467 468 469
        // store the selected central widget
        chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(tool), currentView);
        settings.setValue(chKey,true);
        settings.sync();
470

471 472
        presentView();
    }
473
}
474

lm's avatar
lm committed
475 476 477 478
/**
 * Adds a widget to the tools menu and sets it visible if it was
 * enabled last time.
 */
479
void MainWindow::addToToolsMenu ( QWidget* widget,
480 481 482 483
                                  const QString title,
                                  const char * slotName,
                                  TOOLS_WIDGET_NAMES tool,
                                  Qt::DockWidgetArea location)
lm's avatar
lm committed
484
{
485 486
    QAction* tempAction;
    QString posKey, chKey;
487

488

489 490
    if (toolsMenuActions[CENTRAL_SEPARATOR])
    {
491 492 493
        tempAction = new QAction(title, this);
        ui.menuTools->insertAction(toolsMenuActions[CENTRAL_SEPARATOR],
                                   tempAction);
494 495 496
    }
    else
    {
497 498
        tempAction = ui.menuTools->addAction(title);
    }
499

500 501
    tempAction->setCheckable(true);
    tempAction->setData(tool);
502

503 504 505 506
    // populate the Hashes
    toolsMenuActions[tool] = tempAction;
    dockWidgets[tool] = widget;
    qDebug() << widget;
507

508
    posKey = buildMenuKey (SUB_SECTION_LOCATION,tool, currentView);
509

510 511
    if (!settings.contains(posKey))
    {
512 513
        settings.setValue(posKey,location);
        dockWidgetLocations[tool] = location;
514 515 516 517
    }
    else
    {
        dockWidgetLocations[tool] = static_cast <Qt::DockWidgetArea> (settings.value(posKey, Qt::RightDockWidgetArea).toInt());
518
    }
519

520
    chKey = buildMenuKey(SUB_SECTION_CHECKED,tool, currentView);
521

522 523 524 525
    if (!settings.contains(chKey))
    {
        settings.setValue(chKey,false);
        tempAction->setChecked(false);
526
        widget->setVisible(false);
527 528 529 530
    }
    else
    {
        tempAction->setChecked(settings.value(chKey).toBool());
531
        widget->setVisible(settings.value(chKey, false).toBool());
532
    }
533

534 535
    // connect the action
    connect(tempAction,SIGNAL(triggered()),this, slotName);
536

537 538
    connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
            SIGNAL(visibilityChanged(bool)), this, SLOT(updateVisibilitySettings(bool)));
539

540 541
    connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
            SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(updateLocationSettings(Qt::DockWidgetArea)));
542 543 544

}

545 546 547 548
void MainWindow::showToolWidget()
{
    QAction* temp = qobject_cast<QAction *>(sender());
    int tool = temp->data().toInt();
549 550


551 552 553 554 555 556 557 558 559 560 561 562 563 564
    if (temp && dockWidgets[tool])
    {
        if (temp->isChecked())
        {
            addDockWidget(dockWidgetLocations[tool], qobject_cast<QDockWidget *> (dockWidgets[tool]));
            qobject_cast<QDockWidget *>(dockWidgets[tool])->show();
        }
        else
        {
            removeDockWidget(qobject_cast<QDockWidget *>(dockWidgets[tool]));
        }
        QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(tool), currentView);
        settings.setValue(chKey,temp->isChecked());
        settings.sync();
565 566 567 568
    }
}


569 570 571 572 573
void MainWindow::showTheWidget (TOOLS_WIDGET_NAMES widget, VIEW_SECTIONS view)
{
    bool tempVisible;
    Qt::DockWidgetArea tempLocation;
    QDockWidget* tempWidget = static_cast <QDockWidget *>(dockWidgets[widget]);
574

575 576 577 578 579 580 581 582 583 584
    tempVisible =  settings.value(buildMenuKey (SUB_SECTION_CHECKED,widget,view), false).toBool();

    // Some widgets are per default visible. Overwrite the settings value if not present.
    if (widget == MainWindow::MENU_UAS_LIST)
    {
        if (!settings.contains(buildMenuKey (SUB_SECTION_CHECKED,widget,view)))
        {
            tempVisible = true;
        }
    }
585 586 587 588 589

    if (tempWidget)
    {
        toolsMenuActions[widget]->setChecked(tempVisible);
    }
590 591


592
    //qDebug() <<  buildMenuKey (SUB_SECTION_CHECKED,widget,view) << tempVisible;
593

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

596 597 598 599 600 601 602
    //    if (widget == MainWindow::MENU_UAS_LIST)
    //    {
    //        if (!settings.contains(buildMenuKey (SUB_SECTION_LOCATION,widget, view)))
    //        {
    //            tempLocation = Qt::RightDockWidgetArea;
    //        }
    //    }
603

604
    if ((tempWidget != NULL) && tempVisible)
605 606 607 608
    {
        addDockWidget(tempLocation, tempWidget);
        tempWidget->show();
    }
609

610
}
611

612 613 614 615 616 617 618 619 620 621 622 623 624 625
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
    int apType;

    apType = (UASManager::instance() && UASManager::instance()->silentGetActiveUAS())?
             UASManager::instance()->getActiveUAS()->getAutopilotType():
             -1;

    return (QString::number(apType) + "/" +
            QString::number(SECTION_MENU) + "/" +
            QString::number(view) + "/" +
            QString::number(tool) + "/" +
            QString::number(section) + "/" );
626 627
}

628 629
void MainWindow::closeEvent(QCloseEvent *event)
{
630
    settings.setValue("geometry", saveGeometry());
631 632 633 634 635 636
    //settings.setValue("windowState", saveState());
    aboutToCloseFlag = true;
    settings.setValue("VIEW_ON_APPLICATION_CLOSE", currentView);
    settings.sync();
    QMainWindow::closeEvent(event);
}
637

638 639 640 641 642
/**
 * Stores the visibility setting of each widget. This method
 * will only change the settings if the application is not
 * about to close.
 */
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
void MainWindow::updateVisibilitySettings (bool vis)
{
    if (!aboutToCloseFlag)
    {

        QDockWidget* temp = qobject_cast<QDockWidget *>(sender());

        if (temp)
        {
            QHashIterator<int, QWidget*> i(dockWidgets);
            while (i.hasNext())
            {
                i.next();
                if ((static_cast <QDockWidget *>(dockWidgets[i.key()])) == temp)
                {
658 659 660
                    QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
                    settings.setValue(chKey,vis);
                    settings.sync();
661 662 663 664 665 666
                    toolsMenuActions[i.key()]->setChecked(vis);
                    break;
                }
            }
        }
    }
667 668
}

669 670 671
void MainWindow::updateLocationSettings (Qt::DockWidgetArea location)
{
    QDockWidget* temp = qobject_cast<QDockWidget *>(sender());
672

673 674 675 676 677 678 679 680 681 682 683
    QHashIterator<int, QWidget*> i(dockWidgets);
    while (i.hasNext())
    {
        i.next();
        if ((static_cast <QDockWidget *>(dockWidgets[i.key()])) == temp)
        {
            QString posKey = buildMenuKey (SUB_SECTION_LOCATION,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
            settings.setValue(posKey,location);
            break;
        }
    }
684 685
}

686 687 688
/**
 * Connect the signals and slots of the common window widgets
 */
689
void MainWindow::connectCommonWidgets()
690
{
pixhawk's avatar
pixhawk committed
691 692 693 694 695
    if (infoDockWidget && infoDockWidget->widget())
    {
        connect(mavlink, SIGNAL(receiveLossChanged(int, float)),
                infoDockWidget->widget(), SLOT(updateSendLoss(int, float)));
    }
696

pixhawk's avatar
pixhawk committed
697 698 699 700 701 702
    if (mapWidget && waypointsDockWidget->widget())
    {
        // clear path create on the map
        connect(waypointsDockWidget->widget(), SIGNAL(clearPathclicked()), mapWidget, SLOT(clearPath()));
        // add Waypoint widget in the WaypointList widget when mouse clicked
        connect(mapWidget, SIGNAL(captureMapCoordinateClick(QPointF)), waypointsDockWidget->widget(), SLOT(addWaypointMouse(QPointF)));
703 704 705

        // it notifies that a waypoint global goes to do create and a map graphic too
        connect(waypointsDockWidget->widget(), SIGNAL(createWaypointAtMap(QPointF)), mapWidget, SLOT(createWaypointGraphAtMap(QPointF)));
706
    }
707
}
708

709 710 711 712 713 714 715 716
void MainWindow::createCustomWidget()
{
    qDebug() << "ADDING CUSTOM WIDGET";
    QGCToolWidget* tool = new QGCToolWidget(this);
    QDockWidget* dock = new QDockWidget("Unnamed Tool", this);
    dock->setWidget(tool);
    this->addDockWidget(Qt::LeftDockWidgetArea, dock);
    dock->setVisible(true);
717 718 719 720
}

void MainWindow::connectPxWidgets()
{
721
    // No special connections necessary at this point
722 723 724 725
}

void MainWindow::connectSlugsWidgets()
{
726
    if (slugsHilSimWidget && slugsHilSimWidget->widget()){
727 728
        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                slugsHilSimWidget->widget(), SLOT(activeUasSet(UASInterface*)));
729 730 731
    }

    if (slugsDataWidget && slugsDataWidget->widget()){
732 733
        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                slugsDataWidget->widget(), SLOT(setActiveUAS(UASInterface*)));
734 735
    }

736

737 738
}

739
void MainWindow::arrangeCommonCenterStack()
740
{
741
    centerStack = new QStackedWidget(this);
742

pixhawk's avatar
pixhawk committed
743
    if (!centerStack) return;
744

745 746
    if (mapWidget && (centerStack->indexOf(mapWidget) == -1)) centerStack->addWidget(mapWidget);
    if (protocolWidget && (centerStack->indexOf(protocolWidget) == -1)) centerStack->addWidget(protocolWidget);
747 748 749 750 751 752 753

    setCentralWidget(centerStack);
}

void MainWindow::arrangePxCenterStack()
{

754 755 756 757
    if (!centerStack) {
        qDebug() << "Center Stack not Created!";
        return;
    }
758

759 760

    if (linechartWidget && (centerStack->indexOf(linechartWidget) == -1)) centerStack->addWidget(linechartWidget);
761

762
#ifdef QGC_OSG_ENABLED
763
    if (_3DWidget && (centerStack->indexOf(_3DWidget) == -1)) centerStack->addWidget(_3DWidget);
764
#endif
765
#ifdef QGC_OSGEARTH_ENABLED
766
    if (_3DMapWidget && (centerStack->indexOf(_3DMapWidget) == -1)) centerStack->addWidget(_3DMapWidget);
767
#endif
768
#if (defined _MSC_VER) | (defined Q_OS_MAC)
769
    if (gEarthWidget && (centerStack->indexOf(gEarthWidget) == -1)) centerStack->addWidget(gEarthWidget);
770
#endif
771 772
    if (hudWidget && (centerStack->indexOf(hudWidget) == -1)) centerStack->addWidget(hudWidget);
    if (dataplotWidget && (centerStack->indexOf(dataplotWidget) == -1)) centerStack->addWidget(dataplotWidget);
773 774 775 776 777
}

void MainWindow::arrangeSlugsCenterStack()
{

778 779 780 781
    if (!centerStack) {
        qDebug() << "Center Stack not Created!";
        return;
    }
782

783 784
    if (linechartWidget && (centerStack->indexOf(linechartWidget) == -1)) centerStack->addWidget(linechartWidget);
    if (hudWidget && (centerStack->indexOf(hudWidget) == -1)) centerStack->addWidget(hudWidget);
785

786 787
}

788 789
void MainWindow::configureWindowName()
{
pixhawk's avatar
pixhawk committed
790 791 792
    QList<QHostAddress> hostAddresses = QNetworkInterface::allAddresses();
    QString windowname = qApp->applicationName() + " " + qApp->applicationVersion();
    bool prevAddr = false;
793

pixhawk's avatar
pixhawk committed
794
    windowname.append(" (" + QHostInfo::localHostName() + ": ");
795

pixhawk's avatar
pixhawk committed
796 797 798 799 800 801 802 803 804 805
    for (int i = 0; i < hostAddresses.size(); i++)
    {
        // Exclude loopback IPv4 and all IPv6 addresses
        if (hostAddresses.at(i) != QHostAddress("127.0.0.1") && !hostAddresses.at(i).toString().contains(":"))
        {
            if(prevAddr) windowname.append("/");
            windowname.append(hostAddresses.at(i).toString());
            prevAddr = true;
        }
    }
806

pixhawk's avatar
pixhawk committed
807
    windowname.append(")");
808

pixhawk's avatar
pixhawk committed
809
    setWindowTitle(windowname);
810 811

#ifndef Q_WS_MAC
pixhawk's avatar
pixhawk committed
812
    //qApp->setWindowIcon(QIcon(":/core/images/qtcreator_logo_128.png"));
813 814 815
#endif
}

pixhawk's avatar
pixhawk committed
816
void MainWindow::startVideoCapture()
pixhawk's avatar
pixhawk committed
817 818 819 820 821 822 823 824 825 826 827
{
    QString format = "bmp";
    QString initialPath = QDir::currentPath() + tr("/untitled.") + format;

    QString screenFileName = QFileDialog::getSaveFileName(this, tr("Save As"),
                                                          initialPath,
                                                          tr("%1 Files (*.%2);;All Files (*)")
                                                          .arg(format.toUpper())
                                                          .arg(format));
    delete videoTimer;
    videoTimer = new QTimer(this);
828 829 830
    //videoTimer->setInterval(40);
    //connect(videoTimer, SIGNAL(timeout()), this, SLOT(saveScreen()));
    //videoTimer->stop();
pixhawk's avatar
pixhawk committed
831 832
}

pixhawk's avatar
pixhawk committed
833
void MainWindow::stopVideoCapture()
pixhawk's avatar
pixhawk committed
834 835 836 837 838 839
{
    videoTimer->stop();

    // TODO Convert raw images to PNG
}

pixhawk's avatar
pixhawk committed
840
void MainWindow::saveScreen()
pixhawk's avatar
pixhawk committed
841 842 843 844 845 846 847 848 849 850
{
    QPixmap window = QPixmap::grabWindow(this->winId());
    QString format = "bmp";

    if (!screenFileName.isEmpty())
    {
        window.save(screenFileName, format.toAscii());
    }
}

851 852 853 854 855 856
/**
 * Reload the style sheet from disk. The function tries to load "qgroundcontrol.css" from the application
 * directory (which by default does not exist). If it fails, it will load the bundled default CSS
 * from memory.
 * To customize the application, just create a qgroundcontrol.css file in the application directory
 */
pixhawk's avatar
pixhawk committed
857
void MainWindow::reloadStylesheet()
pixhawk's avatar
pixhawk committed
858 859
{
    // Load style sheet
860 861 862 863 864
    QFile* styleSheet = new QFile(QCoreApplication::applicationDirPath() + "/qgroundcontrol.css");
    if (!styleSheet->exists())
    {
        styleSheet = new QFile(":/images/style-mission.css");
    }
865 866
    if (styleSheet->open(QIODevice::ReadOnly | QIODevice::Text))
    {
867 868
        QString style = QString(styleSheet->readAll());
        style.replace("ICONDIR", QCoreApplication::applicationDirPath()+ "/images/");
pixhawk's avatar
pixhawk committed
869
        qApp->setStyleSheet(style);
870 871 872
    }
    else
    {
873
        qDebug() << "Style not set:" << styleSheet->fileName() << "opened: " << styleSheet->isOpen();
pixhawk's avatar
pixhawk committed
874
    }
875
    delete styleSheet;
pixhawk's avatar
pixhawk committed
876 877
}

878 879 880 881 882 883
/**
 * The status message will be overwritten if a new message is posted to this function
 *
 * @param status message text
 * @param timeout how long the status should be displayed
 */
pixhawk's avatar
pixhawk committed
884
void MainWindow::showStatusMessage(const QString& status, int timeout)
pixhawk's avatar
pixhawk committed
885
{
lm's avatar
lm committed
886
    statusBar()->showMessage(status, timeout);
pixhawk's avatar
pixhawk committed
887 888
}

889 890 891 892 893 894
/**
 * The status message will be overwritten if a new message is posted to this function.
 * it will be automatically hidden after 5 seconds.
 *
 * @param status message text
 */
895
void MainWindow::showStatusMessage(const QString& status)
pixhawk's avatar
pixhawk committed
896
{
lm's avatar
lm committed
897
    statusBar()->showMessage(status, 20000);
898 899 900 901 902 903 904 905 906 907 908
}

void MainWindow::showCriticalMessage(const QString& title, const QString& message)
{
    QMessageBox msgBox(MainWindow::instance());
    msgBox.setIcon(QMessageBox::Critical);
    msgBox.setText(title);
    msgBox.setInformativeText(message);
    msgBox.setStandardButtons(QMessageBox::Ok);
    msgBox.setDefaultButton(QMessageBox::Ok);
    msgBox.exec();
pixhawk's avatar
pixhawk committed
909 910
}

lm's avatar
lm committed
911 912 913 914 915 916 917 918 919 920 921
void MainWindow::showInfoMessage(const QString& title, const QString& message)
{
    QMessageBox msgBox(MainWindow::instance());
    msgBox.setIcon(QMessageBox::Information);
    msgBox.setText(title);
    msgBox.setInformativeText(message);
    msgBox.setStandardButtons(QMessageBox::Ok);
    msgBox.setDefaultButton(QMessageBox::Ok);
    msgBox.exec();
}

pixhawk's avatar
pixhawk committed
922 923 924 925
/**
* @brief Create all actions associated to the main window
*
**/
926
void MainWindow::connectCommonActions()
pixhawk's avatar
pixhawk committed
927 928 929 930 931 932 933
{
    // Connect actions from ui
    connect(ui.actionAdd_Link, SIGNAL(triggered()), this, SLOT(addLink()));

    // Connect internal actions
    connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(UASCreated(UASInterface*)));

934
    // Unmanned System controls
pixhawk's avatar
pixhawk committed
935 936 937 938 939 940 941
    connect(ui.actionLiftoff, SIGNAL(triggered()), UASManager::instance(), SLOT(launchActiveUAS()));
    connect(ui.actionLand, SIGNAL(triggered()), UASManager::instance(), SLOT(returnActiveUAS()));
    connect(ui.actionEmergency_Land, SIGNAL(triggered()), UASManager::instance(), SLOT(stopActiveUAS()));
    connect(ui.actionEmergency_Kill, SIGNAL(triggered()), UASManager::instance(), SLOT(killActiveUAS()));

    connect(ui.actionConfiguration, SIGNAL(triggered()), UASManager::instance(), SLOT(configureActiveUAS()));

942
    // Views actions
943
    connect(ui.actionPilotsView, SIGNAL(triggered()), this, SLOT(loadPilotView()));
944
    connect(ui.actionEngineersView, SIGNAL(triggered()), this, SLOT(loadEngineerView()));
945
    connect(ui.actionOperatorsView, SIGNAL(triggered()), this, SLOT(loadOperatorView()));
946

947 948
    connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView()));
    connect(ui.actionReloadStyle, SIGNAL(triggered()), this, SLOT(reloadStylesheet()));
949

950
    // Help Actions
951 952 953
    connect(ui.actionOnline_documentation, SIGNAL(triggered()), this, SLOT(showHelp()));
    connect(ui.actionDeveloper_Credits, SIGNAL(triggered()), this, SLOT(showCredits()));
    connect(ui.actionProject_Roadmap, SIGNAL(triggered()), this, SLOT(showRoadMap()));
954 955 956 957
}

void MainWindow::connectPxActions()
{
958
    ui.actionJoystickSettings->setVisible(true);
959

960 961
    // Joystick configuration
    connect(ui.actionJoystickSettings, SIGNAL(triggered()), this, SLOT(configure()));
962 963 964 965 966

}

void MainWindow::connectSlugsActions()
{
967

pixhawk's avatar
pixhawk committed
968 969
}

970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011
void MainWindow::showHelp()
{
    if(!QDesktopServices::openUrl(QUrl("http://qgroundcontrol.org/user_guide")))
    {
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Critical);
        msgBox.setText("Could not open help in browser");
        msgBox.setInformativeText("To get to the online help, please open http://qgroundcontrol.org/user_guide in a browser.");
        msgBox.setStandardButtons(QMessageBox::Ok);
        msgBox.setDefaultButton(QMessageBox::Ok);
        msgBox.exec();
    }
}

void MainWindow::showCredits()
{
    if(!QDesktopServices::openUrl(QUrl("http://qgroundcontrol.org/credits")))
    {
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Critical);
        msgBox.setText("Could not open credits in browser");
        msgBox.setInformativeText("To get to the online help, please open http://qgroundcontrol.org/credits in a browser.");
        msgBox.setStandardButtons(QMessageBox::Ok);
        msgBox.setDefaultButton(QMessageBox::Ok);
        msgBox.exec();
    }
}

void MainWindow::showRoadMap()
{
    if(!QDesktopServices::openUrl(QUrl("http://qgroundcontrol.org/roadmap")))
    {
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Critical);
        msgBox.setText("Could not open roadmap in browser");
        msgBox.setInformativeText("To get to the online help, please open http://qgroundcontrol.org/roadmap in a browser.");
        msgBox.setStandardButtons(QMessageBox::Ok);
        msgBox.setDefaultButton(QMessageBox::Ok);
        msgBox.exec();
    }
}

pixhawk's avatar
pixhawk committed
1012
void MainWindow::configure()
pixhawk's avatar
pixhawk committed
1013 1014 1015 1016
{
    joystickWidget = new JoystickWidget(joystick, this);
}

pixhawk's avatar
pixhawk committed
1017
void MainWindow::addLink()
pixhawk's avatar
pixhawk committed
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030
{
    SerialLink* link = new SerialLink();
    // TODO This should be only done in the dialog itself

    LinkManager::instance()->addProtocol(link, mavlink);

    CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, this);

    ui.menuNetwork->addAction(commWidget->getAction());

    commWidget->show();
}

pixhawk's avatar
pixhawk committed
1031 1032
void MainWindow::addLink(LinkInterface *link)
{
1033
    LinkManager::instance()->addProtocol(link, mavlink);
pixhawk's avatar
pixhawk committed
1034 1035 1036 1037 1038 1039 1040
    CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, this);
    ui.menuNetwork->addAction(commWidget->getAction());

    // Special case for simulationlink
    MAVLinkSimulationLink* sim = dynamic_cast<MAVLinkSimulationLink*>(link);
    if (sim)
    {
1041
        //connect(sim, SIGNAL(valueChanged(int,QString,double,quint64)), linechart, SLOT(appendData(int,QString,double,quint64)));
pixhawk's avatar
pixhawk committed
1042 1043 1044 1045
        connect(ui.actionSimulate, SIGNAL(triggered(bool)), sim, SLOT(connectLink(bool)));
    }
}

pixhawk's avatar
pixhawk committed
1046
void MainWindow::UASCreated(UASInterface* uas)
pixhawk's avatar
pixhawk committed
1047 1048 1049
{
    // Connect the UAS to the full user interface

1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
    if (uas != NULL)
    {
        QIcon icon;
        // Set matching icon
        switch (uas->getSystemType())
        {
        case 0:
            icon = QIcon(":/images/mavs/generic.svg");
            break;
        case 1:
            icon = QIcon(":/images/mavs/fixed-wing.svg");
            break;
        case 2:
            icon = QIcon(":/images/mavs/quadrotor.svg");
            break;
        case 3:
            icon = QIcon(":/images/mavs/coaxial.svg");
            break;
        case 4:
            icon = QIcon(":/images/mavs/helicopter.svg");
            break;
        case 5:
            icon = QIcon(":/images/mavs/groundstation.svg");
            break;
        default:
            icon = QIcon(":/images/mavs/unknown.svg");
            break;
        }

        ui.menuConnected_Systems->addAction(icon, tr("Select %1 for control").arg(uas->getUASName()), uas, SLOT(setSelected()));

        // FIXME Should be not inside the mainwindow
1082 1083
        if (debugConsoleDockWidget)
        {
pixhawk's avatar
pixhawk committed
1084 1085 1086 1087 1088 1089
            DebugConsole *debugConsole = dynamic_cast<DebugConsole*>(debugConsoleDockWidget->widget());
            if (debugConsole)
            {
                connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)),
                        debugConsole, SLOT(receiveTextMessage(int,int,int,QString)));
            }
1090
        }
1091 1092

        // Health / System status indicator
1093 1094
        if (infoDockWidget)
        {
pixhawk's avatar
pixhawk committed
1095 1096 1097 1098 1099
            UASInfoWidget *infoWidget = dynamic_cast<UASInfoWidget*>(infoDockWidget->widget());
            if (infoWidget)
            {
                infoWidget->addUAS(uas);
            }
1100
        }
1101 1102

        // UAS List
1103 1104
        if (listDockWidget)
        {
pixhawk's avatar
pixhawk committed
1105 1106 1107 1108 1109
            UASListWidget *listWidget = dynamic_cast<UASListWidget*>(listDockWidget->widget());
            if (listWidget)
            {
                listWidget->addUAS(uas);
            }
1110
        }
1111 1112 1113 1114 1115 1116 1117 1118

        // Camera view
        //camera->addUAS(uas);

        // Revalidate UI
        // TODO Stylesheet reloading should in theory not be necessary
        reloadStylesheet();

1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189
        switch (uas->getAutopilotType())
        {
        case (MAV_AUTOPILOT_SLUGS):
            {
                // Build Slugs Widgets
                buildSlugsWidgets();

                // Connect Slugs Widgets
                connectSlugsWidgets();

                // Arrange Slugs Centerstack
                arrangeSlugsCenterStack();

                // Connect Slugs Actions
                connectSlugsActions();

                // FIXME: This type checking might be redundant
                //            if (slugsDataWidget) {
                //              SlugsDataSensorView* dataWidget = dynamic_cast<SlugsDataSensorView*>(slugsDataWidget->widget());
                //              if (dataWidget) {
                //                SlugsMAV* mav2 = dynamic_cast<SlugsMAV*>(uas);
                //                if (mav2) {
                (dynamic_cast<SlugsDataSensorView*>(slugsDataWidget->widget()))->addUAS(uas);
                //                  //loadSlugsView();
                //                  loadGlobalOperatorView();
                //                }
                //              }
                //            }
            }
            break;
        default:
        case (MAV_AUTOPILOT_GENERIC):
        case (MAV_AUTOPILOT_ARDUPILOTMEGA):
        case (MAV_AUTOPILOT_PIXHAWK):
            {
                // Build Pixhawk Widgets
                buildPxWidgets();

                // Connect Pixhawk Widgets
                connectPxWidgets();

                // Arrange Pixhawk Centerstack
                arrangePxCenterStack();

                // Connect Pixhawk Actions
                connectPxActions();

            }
            break;

        }

        // Change the view only if this is the first UAS

        // If this is the first connected UAS, it is both created as well as
        // the currently active UAS
        if (UASManager::instance()->getActiveUAS() == uas)
        {
            qDebug() << "UPDATING THE VIEW SINCE THIS IS THE FIRST CONNECTED SYSTEM";

            // Load last view if setting is present
            if (settings.contains("VIEW_ON_APPLICATION_CLOSE"))
            {
                int view = settings.value("VIEW_ON_APPLICATION_CLOSE").toInt();
                currentView = (VIEW_SECTIONS) view;
                presentView();
            }
            else
            {
                loadEngineerView();
            }
1190
        }
1191

1192
    }
pixhawk's avatar
pixhawk committed
1193 1194
}

1195 1196 1197
/**
 * Clears the current view completely
 */
pixhawk's avatar
pixhawk committed
1198
void MainWindow::clearView()
1199
{
1200 1201
    // Remove all dock widgets from main window
    QObjectList childList( this->children() );
pixhawk's avatar
pixhawk committed
1202

1203 1204 1205
    QObjectList::iterator i;
    QDockWidget* dockWidget;
    for (i = childList.begin(); i != childList.end(); ++i)
pixhawk's avatar
pixhawk committed
1206
    {
1207 1208
        dockWidget = dynamic_cast<QDockWidget*>(*i);
        if (dockWidget)
pixhawk's avatar
pixhawk committed
1209
        {
1210
            // Remove dock widget from main window
1211 1212
            //this->removeDockWidget(dockWidget);
            dockWidget->setVisible(false);
1213 1214 1215
            // Deletion of dockWidget would also delete all child
            // widgets of dockWidget
            // Is there a way to unset a widget from QDockWidget?
pixhawk's avatar
pixhawk committed
1216 1217 1218 1219
        }
    }
}

1220
void MainWindow::loadEngineerView()
lm's avatar
lm committed
1221
{
1222
    clearView();
lm's avatar
lm committed
1223

1224
    currentView = VIEW_ENGINEER;
lm's avatar
lm committed
1225

1226
    presentView();
lm's avatar
lm committed
1227 1228
}

1229
void MainWindow::loadOperatorView()
lm's avatar
lm committed
1230
{
1231 1232 1233
    clearView();

    currentView = VIEW_OPERATOR;
lm's avatar
lm committed
1234

1235
    presentView();
lm's avatar
lm committed
1236 1237
}

1238
void MainWindow::loadPilotView()
1239 1240
{
    clearView();
1241

1242 1243 1244
    currentView = VIEW_PILOT;

    presentView();
1245 1246
}

1247
void MainWindow::loadMAVLinkView()
1248 1249
{
    clearView();
pixhawk's avatar
pixhawk committed
1250

1251 1252 1253
    currentView = VIEW_MAVLINK;

    presentView();
1254 1255
}

lm's avatar
lm committed
1256 1257
void MainWindow::presentView()
{
1258 1259
    qDebug() << "LC";
    showTheCentralWidget(CENTRAL_LINECHART, currentView);
1260

1261 1262 1263
    // MAP
    qDebug() << "MAP";
    showTheCentralWidget(CENTRAL_MAP, currentView);
pixhawk's avatar
pixhawk committed
1264

1265 1266 1267
    // PROTOCOL
    qDebug() << "CP";
    showTheCentralWidget(CENTRAL_PROTOCOL, currentView);
pixhawk's avatar
pixhawk committed
1268

1269 1270
    // HEAD UP DISPLAY
    showTheCentralWidget(CENTRAL_HUD, currentView);
pixhawk's avatar
pixhawk committed
1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281

    // GOOGLE EARTH
    showTheCentralWidget(CENTRAL_GOOGLE_EARTH, currentView);

    // LOCAL 3D VIEW
    showTheCentralWidget(CENTRAL_3D_LOCAL, currentView);

    // GLOBAL 3D VIEW
    showTheCentralWidget(CENTRAL_3D_MAP, currentView);


pixhawk's avatar
pixhawk committed
1282

1283
    // Show docked widgets based on current view and autopilot type
1284

1285 1286
    // UAS CONTROL
    showTheWidget(MENU_UAS_CONTROL, currentView);
1287

1288 1289
    // UAS LIST
    showTheWidget(MENU_UAS_LIST, currentView);
1290

1291 1292
    // WAYPOINT LIST
    showTheWidget(MENU_WAYPOINTS, currentView);
pixhawk's avatar
pixhawk committed
1293

1294 1295
    // UAS STATUS
    showTheWidget(MENU_STATUS, currentView);
1296

1297 1298
    // DETECTION
    showTheWidget(MENU_DETECTION, currentView);
1299

1300 1301
    // DEBUG CONSOLE
    showTheWidget(MENU_DEBUG_CONSOLE, currentView);
1302

1303 1304
    // ONBOARD PARAMETERS
    showTheWidget(MENU_PARAMETERS, currentView);
1305

1306 1307
    // WATCHDOG
    showTheWidget(MENU_WATCHDOG, currentView);
1308

1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321
    // HUD
    showTheWidget(MENU_HUD, currentView);
    if (headUpDockWidget)
    {
        HUD* tmpHud = dynamic_cast<HUD*>( headUpDockWidget->widget() );
        if (tmpHud){
            if (settings.value(buildMenuKey (SUB_SECTION_CHECKED,MENU_HUD,currentView)).toBool()){
                addDockWidget(static_cast <Qt::DockWidgetArea>(settings.value(buildMenuKey (SUB_SECTION_LOCATION,MENU_HUD, currentView)).toInt()),
                              hsiDockWidget);
                headUpDockWidget->show();
            } else {
                headUpDockWidget->hide();
            }
1322
        }
1323
    }
1324

1325

1326 1327
    // RC View
    showTheWidget(MENU_RC_VIEW, currentView);
1328

1329 1330
    // SLUGS DATA
    showTheWidget(MENU_SLUGS_DATA, currentView);
1331

1332 1333
    // SLUGS PID
    showTheWidget(MENU_SLUGS_PID, currentView);
1334

1335 1336
    // SLUGS HIL
    showTheWidget(MENU_SLUGS_HIL, currentView);
1337

1338 1339
    // SLUGS CAMERA
    showTheWidget(MENU_SLUGS_CAMERA, currentView);
1340

1341 1342
    // HORIZONTAL SITUATION INDICATOR
    showTheWidget(MENU_HSI, currentView);
1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
    //    if (hsiDockWidget)
    //    {
    //        HSIDisplay* hsi = dynamic_cast<HSIDisplay*>( hsiDockWidget->widget() );
    //        if (hsi){
    //            if (settings.value(buildMenuKey (SUB_SECTION_CHECKED,MENU_HSI,currentView)).toBool()){
    //                addDockWidget(static_cast <Qt::DockWidgetArea>(settings.value(buildMenuKey (SUB_SECTION_LOCATION,MENU_HSI, currentView)).toInt()),
    //                              hsiDockWidget);
    //            }
    //        }
    //    }
1353

1354 1355
    // HEAD DOWN 1
    showTheWidget(MENU_HDD_1, currentView);
1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370
    //    if (headDown1DockWidget)
    //    {
    //        HDDisplay *hdd = dynamic_cast<HDDisplay*>(headDown1DockWidget->widget());
    //        if (hdd) {
    //            if (settings.value(buildMenuKey (SUB_SECTION_CHECKED,MENU_HDD_1,currentView)).toBool()) {
    //                addDockWidget(static_cast <Qt::DockWidgetArea>(settings.value(buildMenuKey (SUB_SECTION_LOCATION,MENU_HDD_1, currentView)).toInt()),
    //                              headDown1DockWidget);
    //                headDown1DockWidget->show();
    //                hdd->start();
    //            } else {
    //                headDown1DockWidget->hide();;
    //                hdd->stop();
    //            }
    //        }
    //    }
1371 1372 1373

    // HEAD DOWN 2
    showTheWidget(MENU_HDD_2, currentView);
1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388
    //    if (headDown2DockWidget)
    //    {
    //        HDDisplay *hdd = dynamic_cast<HDDisplay*>(headDown2DockWidget->widget());
    //        if (hdd){
    //            if (settings.value(buildMenuKey (SUB_SECTION_CHECKED,MENU_HDD_2,currentView)).toBool()){
    //                addDockWidget(static_cast <Qt::DockWidgetArea>(settings.value(buildMenuKey (SUB_SECTION_LOCATION,MENU_HDD_2, currentView)).toInt()),
    //                              headDown2DockWidget);
    //                headDown2DockWidget->show();
    //                hdd->start();
    //            } else {
    //                headDown2DockWidget->hide();
    //                hdd->stop();
    //            }
    //        }
    //    }
1389

1390
    this->show();
1391

1392
}
1393

1394 1395 1396 1397
void MainWindow::showTheCentralWidget (TOOLS_WIDGET_NAMES centralWidget, VIEW_SECTIONS view)
{
    bool tempVisible;
    QWidget* tempWidget = dockWidgets[centralWidget];
1398

1399 1400 1401
    tempVisible =  settings.value(buildMenuKey (SUB_SECTION_CHECKED,centralWidget,view)).toBool();
    qDebug() << buildMenuKey (SUB_SECTION_CHECKED,centralWidget,view) << tempVisible;
    if (toolsMenuActions[centralWidget])
1402
    {
1403
        toolsMenuActions[centralWidget]->setChecked(tempVisible);
1404
    }
1405

1406
    if (centerStack && tempWidget && tempVisible)
1407
    {
1408
        centerStack->setCurrentWidget(tempWidget);
1409
    }
1410 1411
}

pixhawk's avatar
pixhawk committed
1412
void MainWindow::loadWidgets()
pixhawk's avatar
pixhawk committed
1413
{
1414 1415
    loadOperatorView();
    //loadMAVLinkView();
pixhawk's avatar
pixhawk committed
1416 1417
    //loadPilotView();
}
1418

1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435
void MainWindow::loadDataView(QString fileName)
{
    // DATAPLOT
    if (dataplotWidget)
    {
        QStackedWidget *centerStack = dynamic_cast<QStackedWidget*>(centralWidget());
        if (centerStack)
        {
            centerStack->setCurrentWidget(dataplotWidget);
            dataplotWidget->loadFile(fileName);
        }
    }
}

void MainWindow::load3DMapView()
{
#ifdef QGC_OSGEARTH_ENABLED
1436
    clearView();
1437

1438 1439 1440 1441 1442 1443 1444 1445 1446 1447
    // 3D map
    if (_3DMapWidget)
    {
        QStackedWidget *centerStack = dynamic_cast<QStackedWidget*>(centralWidget());
        if (centerStack)
        {
            //map3DWidget->setActive(true);
            centerStack->setCurrentWidget(_3DMapWidget);
        }
    }
1448 1449 1450 1451 1452
#endif
}

void MainWindow::loadGoogleEarthView()
{
1453
#if (defined _MSC_VER) | (defined Q_OS_MAC)
1454
    clearView();
1455

1456 1457
    // 3D map
    if (gEarthWidget)
1458 1459 1460 1461
    {
        QStackedWidget *centerStack = dynamic_cast<QStackedWidget*>(centralWidget());
        if (centerStack)
        {
1462
            centerStack->setCurrentWidget(gEarthWidget);
1463 1464
        }
    }
1465
#endif
1466 1467 1468

}

1469
void MainWindow::load3DView()
1470 1471
{
#ifdef QGC_OSG_ENABLED
1472
    clearView();
1473

1474 1475
    // 3D map
    if (_3DWidget)
1476
    {
1477 1478 1479 1480 1481 1482
        QStackedWidget *centerStack = dynamic_cast<QStackedWidget*>(centralWidget());
        if (centerStack)
        {
            //map3DWidget->setActive(true);
            centerStack->setCurrentWidget(_3DWidget);
        }
1483
    }
1484 1485 1486
#endif
}