MainWindow.cc 62 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
#include "MAVLinkSimulationLink.h"
#include "SerialLink.h"
#include "UDPLink.h"
#include "MAVLinkProtocol.h"
#include "CommConfigurationWindow.h"
25
#include "QGCWaypointListMulti.h"
pixhawk's avatar
pixhawk committed
26 27
#include "MainWindow.h"
#include "JoystickWidget.h"
pixhawk's avatar
pixhawk committed
28
#include "GAudioOutput.h"
29
#include "QGCToolWidget.h"
30
#include "QGCMAVLinkLogPlayer.h"
31

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

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

pixhawk's avatar
pixhawk committed
40

41
#include "LogCompressor.h"
pixhawk's avatar
pixhawk committed
42

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

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

pixhawk's avatar
pixhawk committed
57 58 59 60 61 62 63
/**
* 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()
**/
64
MainWindow::MainWindow(QWidget *parent):
pixhawk's avatar
pixhawk committed
65
        QMainWindow(parent),
66
        toolsMenuActions(),
67
        currentView(VIEW_UNCONNECTED),
68
        aboutToCloseFlag(false),
69
        changingViewsFlag(false)
pixhawk's avatar
pixhawk committed
70
{
71 72 73 74 75 76 77
    if (!settings.contains("CURRENT_VIEW"))
    {
        // Set this view as default view
        settings.setValue("CURRENT_VIEW", currentView);
    }
    else
    {
78 79 80 81 82
        // LOAD THE LAST VIEW
        VIEW_SECTIONS currentViewCandidate = (VIEW_SECTIONS) settings.value("CURRENT_VIEW", currentView).toInt();
        if (currentViewCandidate != VIEW_ENGINEER &&
            currentViewCandidate != VIEW_OPERATOR &&
            currentViewCandidate != VIEW_PILOT)
83
        {
84
            currentView = currentViewCandidate;
85
        }
86 87
    }

88
    setDefaultSettingsForAp();
89

90 91
    settings.sync();

pixhawk's avatar
pixhawk committed
92 93 94
    // Setup user interface
    ui.setupUi(this);

95 96
    setVisible(false);

97
    buildCommonWidgets();
98

99
    connectCommonWidgets();
100

101
    arrangeCommonCenterStack();
102 103

    configureWindowName();
pixhawk's avatar
pixhawk committed
104 105 106 107

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

pixhawk's avatar
pixhawk committed
109
    // Set style sheet as last step
110 111 112 113 114 115 116
    QFile* styleSheet = new QFile(":/images/style-mission.css");
    if (styleSheet->open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QString style = QString(styleSheet->readAll());
        style.replace("ICONDIR", QCoreApplication::applicationDirPath()+ "/images/");
        qApp->setStyleSheet(style);
    }
pixhawk's avatar
pixhawk committed
117

118
    // Create actions
119
    connectCommonActions();
120

121 122 123
    // Set dock options
    setDockOptions(AnimatedDocks | AllowTabbedDocks | AllowNestedDocks);

124
    // Load mavlink view as default widget set
125
    //loadMAVLinkView();
126

lm's avatar
lm committed
127 128
    statusBar()->setSizeGripEnabled(true);

129 130
    // Restore the window position and size
    if (settings.contains(getWindowGeometryKey()))
131 132
    {
        // Restore the window geometry
133
        restoreGeometry(settings.value(getWindowGeometryKey()).toByteArray());
134 135 136 137 138 139
    }
    else
    {
        // Adjust the size
        adjustSize();
    }
pixhawk's avatar
pixhawk committed
140

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

148 149
    connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*)));

150 151 152 153 154 155
    // Connect user interface devices
    if (!joystick)
    {
        joystick = new JoystickInput();
    }

lm's avatar
lm committed
156 157
    // Enable and update view
    presentView();
pixhawk's avatar
pixhawk committed
158 159
}

pixhawk's avatar
pixhawk committed
160
MainWindow::~MainWindow()
pixhawk's avatar
pixhawk committed
161
{
lm's avatar
lm committed
162

pixhawk's avatar
pixhawk committed
163 164
}

165 166 167 168 169 170 171 172 173 174 175 176
/**
 * 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);
    if (!settings.contains(centralKey))
    {
        settings.setValue(centralKey,true);
177 178 179 180 181

        // 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);
182 183 184 185 186 187 188 189 190 191
    }

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

        // ENABLE UAS LIST
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_UAS_LIST,VIEW_OPERATOR), true);
192 193
        // ENABLE HUD TOOL WIDGET
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_HUD,VIEW_OPERATOR), true);
194 195 196 197 198 199 200
    }

    // ENGINEER VIEW DEFAULT
    centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_LINECHART, VIEW_ENGINEER);
    if (!settings.contains(centralKey))
    {
        settings.setValue(centralKey,true);
201 202
        // Enable Parameter widget
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_PARAMETERS,VIEW_ENGINEER), true);
203 204 205 206 207 208 209 210 211 212 213 214 215 216
    }

    // MAVLINK VIEW DEFAULT
    centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_PROTOCOL, VIEW_MAVLINK);
    if (!settings.contains(centralKey))
    {
        settings.setValue(centralKey,true);
    }

    // PILOT VIEW DEFAULT
    centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_HUD, VIEW_PILOT);
    if (!settings.contains(centralKey))
    {
        settings.setValue(centralKey,true);
217 218
        // Enable Flight display
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_HDD_1,VIEW_PILOT), true);
219 220 221
    }
}

lm's avatar
lm committed
222 223 224 225 226 227 228 229 230 231 232 233 234
void MainWindow::resizeEvent(QResizeEvent * event)
{
    Q_UNUSED(event);
    if (height() < 800)
    {
        ui.statusBar->setVisible(false);
    }
    else
    {
        ui.statusBar->setVisible(true);
    }
}

235 236 237 238 239 240 241 242 243 244
QString MainWindow::getWindowStateKey()
{
    return QString::number(currentView)+"/windowstate";
}

QString MainWindow::getWindowGeometryKey()
{
    return QString::number(currentView)+"/geometry";
}

lm's avatar
lm committed
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
void MainWindow::buildCustomWidget()
{
    // Show custom widgets only if UAS is connected
    if (UASManager::instance()->getActiveUAS() != NULL)
    {
        // Enable custom widgets
        ui.actionNewCustomWidget->setEnabled(true);

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

        if (widgets.size() > 0)
        {
            ui.menuTools->addSeparator();
        }

        for(int i = 0; i < widgets.size(); ++i)
        {
            qDebug() << "ADDING WIDGET #" << i << widgets.at(i);
            // Check if this widget already has a parent, do not create it in this case
            QDockWidget* dock = dynamic_cast<QDockWidget*>(widgets.at(i)->parentWidget());
            if (!dock)
            {
                QDockWidget* dock = new QDockWidget(widgets.at(i)->windowTitle(), this);
                dock->setWidget(widgets.at(i));
                connect(widgets.at(i), SIGNAL(destroyed()), dock, SLOT(deleteLater()));
                QAction* showAction = new QAction(widgets.at(i)->windowTitle(), this);
                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);
                addDockWidget(Qt::BottomDockWidgetArea, dock);
            }
        }
    }
}

282 283 284 285
void MainWindow::buildCommonWidgets()
{
    //TODO:  move protocol outside UI
    mavlink     = new MAVLinkProtocol();
286
    connect(mavlink, SIGNAL(protocolStatusMessage(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection);
287 288

    // Dock widgets
289 290 291
    if (!controlDockWidget)
    {
        controlDockWidget = new QDockWidget(tr("Control"), this);
292
        controlDockWidget->setObjectName("UNMANNED_SYSTEM_CONTROL_DOCKWIDGET");
293
        controlDockWidget->setWidget( new UASControlWidget(this) );
294
        addToToolsMenu (controlDockWidget, tr("Control"), SLOT(showToolWidget(bool)), MENU_UAS_CONTROL, Qt::LeftDockWidgetArea);
295
    }
296

297 298 299 300
    if (!listDockWidget)
    {
        listDockWidget = new QDockWidget(tr("Unmanned Systems"), this);
        listDockWidget->setWidget( new UASListWidget(this) );
301
        listDockWidget->setObjectName("UNMANNED_SYSTEMS_LIST_DOCKWIDGET");
302
        addToToolsMenu (listDockWidget, tr("Unmanned Systems"), SLOT(showToolWidget(bool)), MENU_UAS_LIST, Qt::RightDockWidgetArea);
303
    }
304

305 306 307
    if (!waypointsDockWidget)
    {
        waypointsDockWidget = new QDockWidget(tr("Waypoint List"), this);
308
        waypointsDockWidget->setWidget( new QGCWaypointListMulti(this) );
309
        waypointsDockWidget->setObjectName("WAYPOINT_LIST_DOCKWIDGET");
310
        addToToolsMenu (waypointsDockWidget, tr("Waypoints List"), SLOT(showToolWidget(bool)), MENU_WAYPOINTS, Qt::BottomDockWidgetArea);
311
    }
312

313 314 315 316
    if (!infoDockWidget)
    {
        infoDockWidget = new QDockWidget(tr("Status Details"), this);
        infoDockWidget->setWidget( new UASInfoWidget(this) );
pixhawk's avatar
pixhawk committed
317
        infoDockWidget->setObjectName("UAS_STATUS_DETAILS_DOCKWIDGET");
318
        addToToolsMenu (infoDockWidget, tr("Status Details"), SLOT(showToolWidget(bool)), MENU_STATUS, Qt::RightDockWidgetArea);
319
    }
320

321 322 323 324
    if (!debugConsoleDockWidget)
    {
        debugConsoleDockWidget = new QDockWidget(tr("Communication Console"), this);
        debugConsoleDockWidget->setWidget( new DebugConsole(this) );
325
        debugConsoleDockWidget->setObjectName("COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET");
326
        addToToolsMenu (debugConsoleDockWidget, tr("Communication Console"), SLOT(showToolWidget(bool)), MENU_DEBUG_CONSOLE, Qt::BottomDockWidgetArea);
327
    }
328

329 330 331 332 333
    if (!logPlayerDockWidget)
    {
        logPlayerDockWidget = new QDockWidget(tr("MAVLink Log Player"), this);
        logPlayerDockWidget->setWidget( new QGCMAVLinkLogPlayer(mavlink, this) );
        logPlayerDockWidget->setObjectName("MAVLINK_LOG_PLAYER_DOCKWIDGET");
334
        addToToolsMenu(logPlayerDockWidget, tr("MAVLink Log Replay"), SLOT(showToolWidget(bool)), MENU_MAVLINK_LOG_PLAYER, Qt::RightDockWidgetArea);
335 336
    }

337
    // Center widgets
338 339
    if (!mapWidget)
    {
340
        mapWidget = new MapWidget(this);
341 342
        addToCentralWidgetsMenu (mapWidget, "Maps", SLOT(showCentralWidget()),CENTRAL_MAP);
    }
343

344 345 346 347 348
    if (!protocolWidget)
    {
        protocolWidget    = new XMLCommProtocolWidget(this);
        addToCentralWidgetsMenu (protocolWidget, "Mavlink Generator", SLOT(showCentralWidget()),CENTRAL_PROTOCOL);
    }
lm's avatar
lm committed
349 350 351 352 353 354

    if (!dataplotWidget)
    {
        dataplotWidget    = new QGCDataPlot2D(this);
        addToCentralWidgetsMenu (dataplotWidget, "Data Plot", SLOT(showCentralWidget()),CENTRAL_DATA_PLOT);
    }
355
}
356

357

358
void MainWindow::buildPxWidgets()
359
{
pixhawk's avatar
pixhawk committed
360 361
    //FIXME: memory of acceptList will never be freed again
    QStringList* acceptList = new QStringList();
lm's avatar
lm committed
362 363 364
    acceptList->append("-105,roll,deg,+105,s");
    acceptList->append("-105,pitch,deg,+105,s");
    acceptList->append("-105,yaw,deg,+105,s");
365

lm's avatar
lm committed
366 367 368
    acceptList->append("-260,rollspeed,deg/s,+260,s");
    acceptList->append("-260,pitchspeed,deg/s,+260,s");
    acceptList->append("-260,yawspeed,deg/s,+260,s");
369

pixhawk's avatar
pixhawk committed
370 371
    //FIXME: memory of acceptList2 will never be freed again
    QStringList* acceptList2 = new QStringList();
lm's avatar
lm committed
372
    acceptList2->append("0,abs pressure,hPa,65500");
373 374
    acceptList2->append("-999,accel. X,raw,999,s");
    acceptList2->append("-999,accel. Y,raw,999,s");
375

376 377 378 379 380 381
    if (!linechartWidget)
    {
        // Center widgets
        linechartWidget   = new Linecharts(this);
        addToCentralWidgetsMenu(linechartWidget, "Line Plots", SLOT(showCentralWidget()), CENTRAL_LINECHART);
    }
382 383


384 385 386 387 388
    if (!hudWidget)
    {
        hudWidget         = new HUD(320, 240, this);
        addToCentralWidgetsMenu(hudWidget, "HUD", SLOT(showCentralWidget()), CENTRAL_HUD);
    }
389

390 391 392 393 394
    if (!dataplotWidget)
    {
        dataplotWidget    = new QGCDataPlot2D(this);
        addToCentralWidgetsMenu(dataplotWidget, "Data Plots", SLOT(showCentralWidget()), CENTRAL_DATA_PLOT);
    }
395

396
#ifdef QGC_OSG_ENABLED
397 398
    if (!_3DWidget)
    {
399 400
        _3DWidget         = Q3DWidgetFactory::get("PIXHAWK");
        addToCentralWidgetsMenu(_3DWidget, "Local 3D", SLOT(showCentralWidget()), CENTRAL_3D_LOCAL);
401
    }
402
#endif
403

404
#ifdef QGC_OSGEARTH_ENABLED
405 406 407 408 409
    if (!_3DMapWidget)
    {
        _3DMapWidget = Q3DWidgetFactory::get("MAP3D");
        addToCentralWidgetsMenu(_3DMapWidget, "OSG Earth 3D", SLOT(showCentralWidget()), CENTRAL_OSGEARTH);
    }
410
#endif
lm's avatar
lm committed
411

412
#if (defined _MSC_VER) | (defined Q_OS_MAC)
413 414 415 416 417
    if (!gEarthWidget)
    {
        gEarthWidget = new QGCGoogleEarthView(this);
        addToCentralWidgetsMenu(gEarthWidget, "Google Earth", SLOT(showCentralWidget()), CENTRAL_GOOGLE_EARTH);
    }
418

419
#endif
420

pixhawk's avatar
pixhawk committed
421
    // Dock widgets
422

423 424 425 426
    if (!detectionDockWidget)
    {
        detectionDockWidget = new QDockWidget(tr("Object Recognition"), this);
        detectionDockWidget->setWidget( new ObjectDetectionView("images/patterns", this) );
pixhawk's avatar
pixhawk committed
427
        detectionDockWidget->setObjectName("OBJECT_DETECTION_DOCK_WIDGET");
428
        addToToolsMenu (detectionDockWidget, tr("Object Recognition"), SLOT(showToolWidget(bool)), MENU_DETECTION, Qt::RightDockWidgetArea);
429
    }
430

431 432
    if (!parametersDockWidget)
    {
433
        parametersDockWidget = new QDockWidget(tr("Calibration and Onboard Parameters"), this);
434
        parametersDockWidget->setWidget( new ParameterInterface(this) );
pixhawk's avatar
pixhawk committed
435
        parametersDockWidget->setObjectName("PARAMETER_INTERFACE_DOCKWIDGET");
436
        addToToolsMenu (parametersDockWidget, tr("Calibration and Parameters"), SLOT(showToolWidget(bool)), MENU_PARAMETERS, Qt::RightDockWidgetArea);
437
    }
438

439 440 441 442
    if (!watchdogControlDockWidget)
    {
        watchdogControlDockWidget = new QDockWidget(tr("Process Control"), this);
        watchdogControlDockWidget->setWidget( new WatchdogControl(this) );
pixhawk's avatar
pixhawk committed
443
        watchdogControlDockWidget->setObjectName("WATCHDOG_CONTROL_DOCKWIDGET");
444
        addToToolsMenu (watchdogControlDockWidget, tr("Process Control"), SLOT(showToolWidget(bool)), MENU_WATCHDOG, Qt::BottomDockWidgetArea);
445
    }
446

447 448 449 450
    if (!hsiDockWidget)
    {
        hsiDockWidget = new QDockWidget(tr("Horizontal Situation Indicator"), this);
        hsiDockWidget->setWidget( new HSIDisplay(this) );
451
        hsiDockWidget->setObjectName("HORIZONTAL_SITUATION_INDICATOR_DOCK_WIDGET");
452
        addToToolsMenu (hsiDockWidget, tr("HSI"), SLOT(showToolWidget(bool)), MENU_HSI, Qt::BottomDockWidgetArea);
453
    }
454

455 456
    if (!headDown1DockWidget)
    {
457 458
        headDown1DockWidget = new QDockWidget(tr("Flight Display"), this);
        headDown1DockWidget->setWidget( new HDDisplay(acceptList, "Flight Display", this) );
459
        headDown1DockWidget->setObjectName("HEAD_DOWN_DISPLAY_1_DOCK_WIDGET");
460
        addToToolsMenu (headDown1DockWidget, tr("Flight Display"), SLOT(showToolWidget(bool)), MENU_HDD_1, Qt::RightDockWidgetArea);
461
    }
462

463 464 465
    if (!headDown2DockWidget)
    {
        headDown2DockWidget = new QDockWidget(tr("Payload Status"), this);
466
        headDown2DockWidget->setWidget( new HDDisplay(acceptList2, "Payload Status", this) );
467
        headDown2DockWidget->setObjectName("HEAD_DOWN_DISPLAY_2_DOCK_WIDGET");
468
        addToToolsMenu (headDown2DockWidget, tr("Payload Status"), SLOT(showToolWidget(bool)), MENU_HDD_2, Qt::RightDockWidgetArea);
469
    }
470

471 472 473 474
    if (!rcViewDockWidget)
    {
        rcViewDockWidget = new QDockWidget(tr("Radio Control"), this);
        rcViewDockWidget->setWidget( new QGCRemoteControlView(this) );
475
        rcViewDockWidget->setObjectName("RADIO_CONTROL_CHANNELS_DOCK_WIDGET");
476
        addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget(bool)), MENU_RC_VIEW, Qt::BottomDockWidgetArea);
477
    }
478

479 480 481 482
    if (!headUpDockWidget)
    {
        headUpDockWidget = new QDockWidget(tr("HUD"), this);
        headUpDockWidget->setWidget( new HUD(320, 240, this));
483
        headUpDockWidget->setObjectName("HEAD_UP_DISPLAY_DOCK_WIDGET");
484
        addToToolsMenu (headUpDockWidget, tr("Head Up Display"), SLOT(showToolWidget(bool)), MENU_HUD, Qt::RightDockWidgetArea);
485
    }
486

pixhawk's avatar
pixhawk committed
487 488 489 490 491 492 493 494 495
    if (!video1DockWidget)
    {
        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");
496
        addToToolsMenu (video1DockWidget, tr("Video Stream 1"), SLOT(showToolWidget(bool)), MENU_VIDEO_STREAM_1, Qt::LeftDockWidgetArea);
pixhawk's avatar
pixhawk committed
497 498 499 500 501 502 503 504 505 506 507
    }

    if (!video2DockWidget)
    {
        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");
508
        addToToolsMenu (video2DockWidget, tr("Video Stream 2"), SLOT(showToolWidget(bool)), MENU_VIDEO_STREAM_2, Qt::LeftDockWidgetArea);
509
    }
510

pixhawk's avatar
pixhawk committed
511 512
    // Dialogue widgets
    //FIXME: free memory in destructor
513 514 515 516
}

void MainWindow::buildSlugsWidgets()
{
517 518 519 520 521
    if (!linechartWidget)
    {
        // Center widgets
        linechartWidget   = new Linecharts(this);
    }
522

523 524 525 526 527
    if (!headUpDockWidget)
    {
        // Dock widgets
        headUpDockWidget = new QDockWidget(tr("Control Indicator"), this);
        headUpDockWidget->setWidget( new HUD(320, 240, this));
pixhawk's avatar
pixhawk committed
528
        headUpDockWidget->setObjectName("HEAD_UP_DISPLAY_DOCK_WIDGET");
529
        addToToolsMenu (headUpDockWidget, tr("HUD"), SLOT(showToolWidget(bool)), MENU_HUD, Qt::LeftDockWidgetArea);
530
    }
531

532 533 534 535
    if (!rcViewDockWidget)
    {
        rcViewDockWidget = new QDockWidget(tr("Radio Control"), this);
        rcViewDockWidget->setWidget( new QGCRemoteControlView(this) );
pixhawk's avatar
pixhawk committed
536
        rcViewDockWidget->setObjectName("RADIO_CONTROL_CHANNELS_DOCK_WIDGET");
537
        addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget(bool)), MENU_RC_VIEW, Qt::BottomDockWidgetArea);
538
    }
539

540 541 542 543 544 545 546 547
//    if (!slugsDataWidget)
//    {
//        // 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()), MENU_SLUGS_DATA, Qt::RightDockWidgetArea);
//    }
548

549 550 551 552 553 554 555
//    if (!slugsPIDControlWidget)
//    {
//        slugsPIDControlWidget = new QDockWidget(tr("Slugs PID Control"), this);
//        slugsPIDControlWidget->setWidget(new SlugsPIDControl(this));
//        slugsPIDControlWidget->setObjectName("SLUGS_PID_CONTROL_DOCK_WIDGET");
//        addToToolsMenu (slugsPIDControlWidget, tr("PID Configuration"), SLOT(showToolWidget()), MENU_SLUGS_PID, Qt::LeftDockWidgetArea);
//    }
556

557 558 559 560 561 562 563
//    if (!slugsHilSimWidget)
//    {
//        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()), MENU_SLUGS_HIL, Qt::LeftDockWidgetArea);
//    }
564

565 566 567 568 569 570 571
//    if (!slugsCamControlWidget)
//    {
//        slugsCamControlWidget = new QDockWidget(tr("Slugs Video Camera Control"), this);
//        slugsCamControlWidget->setWidget(new SlugsVideoCamControl(this));
//        slugsCamControlWidget->setObjectName("SLUGS_CAM_CONTROL_DOCK_WIDGET");
//        addToToolsMenu (slugsCamControlWidget, tr("Camera Control"), SLOT(showToolWidget()), MENU_SLUGS_CAMERA, Qt::BottomDockWidgetArea);
//    }
572
}
573 574 575 576 577


void MainWindow::addToCentralWidgetsMenu ( QWidget* widget,
                                           const QString title,
                                           const char * slotName,
578 579
                                           TOOLS_WIDGET_NAMES centralWidget)
{
580
    QAction* tempAction;
581

582

583
// Not needed any more - separate menu now available
584

585 586 587 588 589 590 591
//    // Add the separator that will separate tools from central Widgets
//    if (!toolsMenuActions[CENTRAL_SEPARATOR])
//    {
//        tempAction = ui.menuTools->addSeparator();
//        toolsMenuActions[CENTRAL_SEPARATOR] = tempAction;
//        tempAction->setData(CENTRAL_SEPARATOR);
//    }
592

593
    tempAction = ui.menuMain->addAction(title);
594

595 596
    tempAction->setCheckable(true);
    tempAction->setData(centralWidget);
597

598 599 600
    // populate the Hashes
    toolsMenuActions[centralWidget] = tempAction;
    dockWidgets[centralWidget] = widget;
601

602
    QString chKey = buildMenuKey(SUB_SECTION_CHECKED, centralWidget, currentView);
603

604 605
    if (!settings.contains(chKey))
    {
606 607 608
        settings.setValue(chKey,false);
        tempAction->setChecked(false);
    }
609 610 611 612
    else
    {
        tempAction->setChecked(settings.value(chKey).toBool());
    }
613

614
    // connect the action
615
    connect(tempAction,SIGNAL(triggered(bool)),this, slotName);
616 617 618
}


lm's avatar
lm committed
619 620
void MainWindow::showCentralWidget()
{
621
    QAction* senderAction = qobject_cast<QAction *>(sender());
622 623 624 625

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

626 627
    int tool = senderAction->data().toInt();
    QString chKey;
628

629
    // check the current action
630

631 632 633 634
    if (senderAction && dockWidgets[tool])
    {
        // uncheck all central widget actions
        QHashIterator<int, QAction*> i(toolsMenuActions);
635 636
        while (i.hasNext())
        {
637
            i.next();
638 639 640
            //qDebug() << "shCW" << i.key() << "read";
            if (i.value() && i.value()->data().toInt() > 255)
            {
641 642 643
                // Block signals and uncheck action
                // firing would be unneccesary
                i.value()->blockSignals(true);
644
                i.value()->setChecked(false);
645
                i.value()->blockSignals(false);
646 647 648 649 650 651

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

653
        // check the current action
654
        //qDebug() << senderAction->text();
655
        senderAction->setChecked(true);
656

657 658
        // update the central widget
        centerStack->setCurrentWidget(dockWidgets[tool]);
659

660 661 662
        // store the selected central widget
        chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(tool), currentView);
        settings.setValue(chKey,true);
663

664 665 666
        // Unblock sender action
        senderAction->blockSignals(false);

667 668
        presentView();
    }
669
}
670

lm's avatar
lm committed
671 672 673 674
/**
 * Adds a widget to the tools menu and sets it visible if it was
 * enabled last time.
 */
675
void MainWindow::addToToolsMenu ( QWidget* widget,
676 677 678 679
                                  const QString title,
                                  const char * slotName,
                                  TOOLS_WIDGET_NAMES tool,
                                  Qt::DockWidgetArea location)
lm's avatar
lm committed
680
{
681 682
    QAction* tempAction;
    QString posKey, chKey;
683

684

685 686
    if (toolsMenuActions[CENTRAL_SEPARATOR])
    {
687 688 689
        tempAction = new QAction(title, this);
        ui.menuTools->insertAction(toolsMenuActions[CENTRAL_SEPARATOR],
                                   tempAction);
690 691 692
    }
    else
    {
693 694
        tempAction = ui.menuTools->addAction(title);
    }
695

696 697
    tempAction->setCheckable(true);
    tempAction->setData(tool);
698

699 700 701
    // populate the Hashes
    toolsMenuActions[tool] = tempAction;
    dockWidgets[tool] = widget;
702
    //qDebug() << widget;
703

704
    posKey = buildMenuKey (SUB_SECTION_LOCATION,tool, currentView);
705

706 707
    if (!settings.contains(posKey))
    {
708 709
        settings.setValue(posKey,location);
        dockWidgetLocations[tool] = location;
710 711 712 713
    }
    else
    {
        dockWidgetLocations[tool] = static_cast <Qt::DockWidgetArea> (settings.value(posKey, Qt::RightDockWidgetArea).toInt());
714
    }
715

716
    chKey = buildMenuKey(SUB_SECTION_CHECKED,tool, currentView);
717

718 719 720 721
    if (!settings.contains(chKey))
    {
        settings.setValue(chKey,false);
        tempAction->setChecked(false);
722
        widget->setVisible(false);
723 724 725
    }
    else
    {
726
        tempAction->setChecked(settings.value(chKey, false).toBool());
727
        widget->setVisible(settings.value(chKey, false).toBool());
728
    }
729

730
    // connect the action
731 732 733
    connect(tempAction,SIGNAL(toggled(bool)),this, slotName);

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

736 737
    //  connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
    //          SIGNAL(visibilityChanged(bool)), this, SLOT(updateVisibilitySettings(bool)));
738

739 740
    connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
            SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(updateLocationSettings(Qt::DockWidgetArea)));
741 742
}

743
void MainWindow::showToolWidget(bool visible)
744
{
745
    if (!aboutToCloseFlag && !changingViewsFlag)
746
    {
747 748
        QAction* action = qobject_cast<QAction *>(sender());

749 750
        // Prevent this to fire if undocked
        if (action)
751
        {
752
            int tool = action->data().toInt();
753

754
            QDockWidget* dockWidget = qobject_cast<QDockWidget *> (dockWidgets[tool]);
755

756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
            qDebug() << "DATA:" << tool << "FLOATING" << dockWidget->isFloating() << "checked" << action->isChecked() << "visible" << dockWidget->isVisible() << "action vis:" << action->isVisible();
            if (dockWidget && dockWidget->isVisible() != visible)
            {
                if (visible)
                {
                    qDebug() << "DOCK WIDGET ADDED";
                    addDockWidget(dockWidgetLocations[tool], dockWidget);
                    dockWidget->show();
                }
                else
                {
                    qDebug() << "DOCK WIDGET REMOVED";
                    removeDockWidget(dockWidget);
                    //dockWidget->hide();
                }
771 772 773 774 775 776 777 778 779 780 781 782 783

                QHashIterator<int, QWidget*> i(dockWidgets);
                while (i.hasNext())
                {
                    i.next();
                    if ((static_cast <QDockWidget *>(dockWidgets[i.key()])) == dockWidget)
                    {
                        QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
                        settings.setValue(chKey,visible);
                        qDebug() << "showToolWidget(): Set key" << chKey << "to" << visible;
                        break;
                    }
                }
784
            }
785
        }
786 787 788 789 790 791

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

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

        if (dockWidget)
792
        {
793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
            // Get action
            int tool = dockWidgets.key(dockWidget);

            qDebug() << "Updating widget setting" << tool << "to" << visible;

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

            QHashIterator<int, QWidget*> i(dockWidgets);
            while (i.hasNext())
            {
                i.next();
                if ((static_cast <QDockWidget *>(dockWidgets[i.key()])) == dockWidget)
                {
                    QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
                    settings.setValue(chKey,visible);
                    qDebug() << "showToolWidget(): Set key" << chKey << "to" << visible;
                    break;
                }
            }
815
        }
816 817 818 819
    }
}


820 821 822 823 824
void MainWindow::showTheWidget (TOOLS_WIDGET_NAMES widget, VIEW_SECTIONS view)
{
    bool tempVisible;
    Qt::DockWidgetArea tempLocation;
    QDockWidget* tempWidget = static_cast <QDockWidget *>(dockWidgets[widget]);
825

826
    tempVisible =  settings.value(buildMenuKey(SUB_SECTION_CHECKED,widget,view), false).toBool();
827

828 829
     qDebug() << "showTheWidget(): Set key" << buildMenuKey(SUB_SECTION_CHECKED,widget,view) << "to" << tempVisible;

830 831 832 833
    if (tempWidget)
    {
        toolsMenuActions[widget]->setChecked(tempVisible);
    }
834 835


836
    //qDebug() <<  buildMenuKey (SUB_SECTION_CHECKED,widget,view) << tempVisible;
837

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

840 841 842 843 844 845 846
    //    if (widget == MainWindow::MENU_UAS_LIST)
    //    {
    //        if (!settings.contains(buildMenuKey (SUB_SECTION_LOCATION,widget, view)))
    //        {
    //            tempLocation = Qt::RightDockWidgetArea;
    //        }
    //    }
847

848
    if (tempWidget != NULL)
849
    {
850 851 852 853 854
        if (tempVisible)
        {
            addDockWidget(tempLocation, tempWidget);
            tempWidget->show();
        }
855 856
    }
}
857

858 859 860 861 862
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;

863 864 865 866 867
//    apType = (UASManager::instance() && UASManager::instance()->silentGetActiveUAS())?
//             UASManager::instance()->getActiveUAS()->getAutopilotType():
//             -1;

    apType = 1;
868

869 870 871 872 873
    return (QString::number(apType) + "_" +
            QString::number(SECTION_MENU) + "_" +
            QString::number(view) + "_" +
            QString::number(tool) + "_" +
            QString::number(section) + "_" );
874 875
}

876 877
void MainWindow::closeEvent(QCloseEvent *event)
{
878
    settings.setValue(getWindowGeometryKey(), saveGeometry());
879 880
    //settings.setValue("windowState", saveState());
    aboutToCloseFlag = true;
881 882 883 884 885 886
    // Save the last current view in any case
    settings.setValue("CURRENT_VIEW", currentView);
    // Save the current window state, but only if a system is connected (else no real number of widgets would be present)
    if (UASManager::instance()->getActiveUAS()) settings.setValue(getWindowStateKey(), saveState(QGC::applicationVersion()));
    // Save the current view only if a UAS is connected
    if (UASManager::instance()->getUASList().length() > 0) settings.setValue("CURRENT_VIEW_WITH_UAS_CONNECTED", currentView);
887 888 889
    settings.sync();
    QMainWindow::closeEvent(event);
}
890

891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913
void MainWindow::showDockWidget (bool vis)
{
    if (!aboutToCloseFlag && !changingViewsFlag)
    {
        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)
                {
                    QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
                    settings.setValue(chKey,vis);
                    toolsMenuActions[i.key()]->setChecked(vis);
                    break;
                }
            }
        }
    }
}
914

915 916
void MainWindow::updateVisibilitySettings (bool vis)
{
917
    if (!aboutToCloseFlag && !changingViewsFlag)
918 919 920 921 922 923
    {
        QDockWidget* temp = qobject_cast<QDockWidget *>(sender());

        if (temp)
        {
            QHashIterator<int, QWidget*> i(dockWidgets);
924 925
            while (i.hasNext())
            {
926
                i.next();
927 928
                if ((static_cast <QDockWidget *>(dockWidgets[i.key()])) == temp)
                {
929 930
                    QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
                    settings.setValue(chKey,vis);
931 932 933 934 935 936
                    toolsMenuActions[i.key()]->setChecked(vis);
                    break;
                }
            }
        }
    }
937 938
}

939 940 941
void MainWindow::updateLocationSettings (Qt::DockWidgetArea location)
{
    QDockWidget* temp = qobject_cast<QDockWidget *>(sender());
942

943 944 945 946 947 948 949 950 951 952 953
    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;
        }
    }
954 955
}

956 957 958
/**
 * Connect the signals and slots of the common window widgets
 */
959
void MainWindow::connectCommonWidgets()
960
{
pixhawk's avatar
pixhawk committed
961 962 963 964 965
    if (infoDockWidget && infoDockWidget->widget())
    {
        connect(mavlink, SIGNAL(receiveLossChanged(int, float)),
                infoDockWidget->widget(), SLOT(updateSendLoss(int, float)));
    }
966

pixhawk's avatar
pixhawk committed
967 968
    if (mapWidget && waypointsDockWidget->widget())
    {
969

970
    }
Alejandro's avatar
Alejandro committed
971 972 973 974 975 976

    //TODO temporaly debug
    if (slugsHilSimWidget && slugsHilSimWidget->widget()){
        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                slugsHilSimWidget->widget(), SLOT(activeUasSet(UASInterface*)));
    }
977
}
978

979 980
void MainWindow::createCustomWidget()
{
981
    //qDebug() << "ADDING CUSTOM WIDGET";
lm's avatar
lm committed
982 983 984 985 986 987 988 989
    QGCToolWidget* tool = new QGCToolWidget("Unnamed Tool", this);

    if (QGCToolWidget::instances()->size() < 2)
    {
        // This is the first widget
        ui.menuTools->addSeparator();
    }

990
    QDockWidget* dock = new QDockWidget("Unnamed Tool", this);
lm's avatar
lm committed
991
    connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater()));
992
    dock->setWidget(tool);
lm's avatar
lm committed
993 994 995 996 997 998
    QAction* showAction = new QAction("Show Unnamed Tool", this);
    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);
999
    dock->setVisible(true);
1000 1001 1002 1003
}

void MainWindow::connectPxWidgets()
{
1004
    // No special connections necessary at this point
1005 1006 1007 1008
}

void MainWindow::connectSlugsWidgets()
{
1009
    if (slugsHilSimWidget && slugsHilSimWidget->widget()){
1010 1011
        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                slugsHilSimWidget->widget(), SLOT(activeUasSet(UASInterface*)));
1012 1013 1014
    }

    if (slugsDataWidget && slugsDataWidget->widget()){
1015 1016
        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                slugsDataWidget->widget(), SLOT(setActiveUAS(UASInterface*)));
1017 1018
    }

1019

1020 1021
}

1022
void MainWindow::arrangeCommonCenterStack()
1023
{
1024
    centerStack = new QStackedWidget(this);
1025
    centerStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1026

pixhawk's avatar
pixhawk committed
1027
    if (!centerStack) return;
1028

1029
    if (mapWidget && (centerStack->indexOf(mapWidget) == -1)) centerStack->addWidget(mapWidget);
lm's avatar
lm committed
1030
    if (dataplotWidget && (centerStack->indexOf(dataplotWidget) == -1)) centerStack->addWidget(dataplotWidget);
1031
    if (protocolWidget && (centerStack->indexOf(protocolWidget) == -1)) centerStack->addWidget(protocolWidget);
1032 1033 1034 1035 1036 1037 1038

    setCentralWidget(centerStack);
}

void MainWindow::arrangePxCenterStack()
{

1039 1040 1041 1042
    if (!centerStack) {
        qDebug() << "Center Stack not Created!";
        return;
    }
1043

1044 1045

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

1047
#ifdef QGC_OSG_ENABLED
1048
    if (_3DWidget && (centerStack->indexOf(_3DWidget) == -1)) centerStack->addWidget(_3DWidget);
1049
#endif
1050
#ifdef QGC_OSGEARTH_ENABLED
1051
    if (_3DMapWidget && (centerStack->indexOf(_3DMapWidget) == -1)) centerStack->addWidget(_3DMapWidget);
1052
#endif
1053
#if (defined _MSC_VER) | (defined Q_OS_MAC)
1054
    if (gEarthWidget && (centerStack->indexOf(gEarthWidget) == -1)) centerStack->addWidget(gEarthWidget);
1055
#endif
1056 1057
    if (hudWidget && (centerStack->indexOf(hudWidget) == -1)) centerStack->addWidget(hudWidget);
    if (dataplotWidget && (centerStack->indexOf(dataplotWidget) == -1)) centerStack->addWidget(dataplotWidget);
1058 1059 1060 1061 1062
}

void MainWindow::arrangeSlugsCenterStack()
{

1063 1064 1065 1066
    if (!centerStack) {
        qDebug() << "Center Stack not Created!";
        return;
    }
1067

1068 1069
    if (linechartWidget && (centerStack->indexOf(linechartWidget) == -1)) centerStack->addWidget(linechartWidget);
    if (hudWidget && (centerStack->indexOf(hudWidget) == -1)) centerStack->addWidget(hudWidget);
1070

1071 1072
}

1073 1074
void MainWindow::configureWindowName()
{
pixhawk's avatar
pixhawk committed
1075 1076 1077
    QList<QHostAddress> hostAddresses = QNetworkInterface::allAddresses();
    QString windowname = qApp->applicationName() + " " + qApp->applicationVersion();
    bool prevAddr = false;
1078

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

pixhawk's avatar
pixhawk committed
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
    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;
        }
    }
1091

pixhawk's avatar
pixhawk committed
1092
    windowname.append(")");
1093

pixhawk's avatar
pixhawk committed
1094
    setWindowTitle(windowname);
1095 1096

#ifndef Q_WS_MAC
pixhawk's avatar
pixhawk committed
1097
    //qApp->setWindowIcon(QIcon(":/core/images/qtcreator_logo_128.png"));
1098 1099 1100
#endif
}

pixhawk's avatar
pixhawk committed
1101
void MainWindow::startVideoCapture()
pixhawk's avatar
pixhawk committed
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
{
    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);
1113 1114 1115
    //videoTimer->setInterval(40);
    //connect(videoTimer, SIGNAL(timeout()), this, SLOT(saveScreen()));
    //videoTimer->stop();
pixhawk's avatar
pixhawk committed
1116 1117
}

pixhawk's avatar
pixhawk committed
1118
void MainWindow::stopVideoCapture()
pixhawk's avatar
pixhawk committed
1119 1120 1121 1122 1123 1124
{
    videoTimer->stop();

    // TODO Convert raw images to PNG
}

pixhawk's avatar
pixhawk committed
1125
void MainWindow::saveScreen()
pixhawk's avatar
pixhawk committed
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135
{
    QPixmap window = QPixmap::grabWindow(this->winId());
    QString format = "bmp";

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

1136 1137 1138 1139 1140 1141
/**
 * 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
1142
void MainWindow::reloadStylesheet()
pixhawk's avatar
pixhawk committed
1143
{
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160
    QString fileName = QCoreApplication::applicationDirPath() + "/style-indoor.css";

    // Let user select style sheet
    fileName = QFileDialog::getOpenFileName(this, tr("Specify stylesheet"), fileName, tr("CSS Stylesheet (*.css);;"));

    if (!fileName.endsWith(".css"))
    {
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Information);
        msgBox.setText(tr("QGroundControl did lot load a new style"));
        msgBox.setInformativeText(tr("No suitable .css file selected. Please select a valid .css file."));
        msgBox.setStandardButtons(QMessageBox::Ok);
        msgBox.setDefaultButton(QMessageBox::Ok);
        msgBox.exec();
        return;
    }

pixhawk's avatar
pixhawk committed
1161
    // Load style sheet
1162
    QFile* styleSheet = new QFile(fileName);
1163 1164 1165 1166
    if (!styleSheet->exists())
    {
        styleSheet = new QFile(":/images/style-mission.css");
    }
1167 1168
    if (styleSheet->open(QIODevice::ReadOnly | QIODevice::Text))
    {
1169 1170
        QString style = QString(styleSheet->readAll());
        style.replace("ICONDIR", QCoreApplication::applicationDirPath()+ "/images/");
pixhawk's avatar
pixhawk committed
1171
        qApp->setStyleSheet(style);
1172 1173 1174
    }
    else
    {
1175 1176 1177 1178 1179 1180 1181
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Information);
        msgBox.setText(tr("QGroundControl did lot load a new style"));
        msgBox.setInformativeText(tr("Stylesheet file %1 was not readable").arg(fileName));
        msgBox.setStandardButtons(QMessageBox::Ok);
        msgBox.setDefaultButton(QMessageBox::Ok);
        msgBox.exec();
pixhawk's avatar
pixhawk committed
1182
    }
1183
    delete styleSheet;
pixhawk's avatar
pixhawk committed
1184 1185
}

1186 1187 1188 1189 1190 1191
/**
 * 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
1192
void MainWindow::showStatusMessage(const QString& status, int timeout)
pixhawk's avatar
pixhawk committed
1193
{
lm's avatar
lm committed
1194
    statusBar()->showMessage(status, timeout);
pixhawk's avatar
pixhawk committed
1195 1196
}

1197 1198 1199 1200 1201 1202
/**
 * 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
 */
1203
void MainWindow::showStatusMessage(const QString& status)
pixhawk's avatar
pixhawk committed
1204
{
lm's avatar
lm committed
1205
    statusBar()->showMessage(status, 20000);
1206 1207 1208 1209
}

void MainWindow::showCriticalMessage(const QString& title, const QString& message)
{
1210
    QMessageBox msgBox(this);
1211 1212 1213 1214 1215 1216
    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
1217 1218
}

lm's avatar
lm committed
1219 1220
void MainWindow::showInfoMessage(const QString& title, const QString& message)
{
1221
    QMessageBox msgBox(this);
lm's avatar
lm committed
1222 1223 1224 1225 1226 1227 1228 1229
    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
1230 1231 1232 1233
/**
* @brief Create all actions associated to the main window
*
**/
1234
void MainWindow::connectCommonActions()
pixhawk's avatar
pixhawk committed
1235
{
1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
    ui.actionNewCustomWidget->setEnabled(false);

    // Bind together the perspective actions
    QActionGroup* perspectives = new QActionGroup(ui.menuPerspectives);
    perspectives->addAction(ui.actionEngineersView);
    perspectives->addAction(ui.actionMavlinkView);
    perspectives->addAction(ui.actionPilotsView);
    perspectives->addAction(ui.actionOperatorsView);
    perspectives->addAction(ui.actionUnconnectedView);
    perspectives->setExclusive(true);

    // Mark the right one as selected
    if (currentView == VIEW_ENGINEER) ui.actionEngineersView->setChecked(true);
    if (currentView == VIEW_MAVLINK) ui.actionMavlinkView->setChecked(true);
    if (currentView == VIEW_PILOT) ui.actionPilotsView->setChecked(true);
    if (currentView == VIEW_OPERATOR) ui.actionOperatorsView->setChecked(true);
    if (currentView == VIEW_UNCONNECTED) ui.actionUnconnectedView->setChecked(true);

    // The pilot, engineer and operator view are not available on startup
    // since they only make sense with a system connected.
    ui.actionPilotsView->setEnabled(false);
    ui.actionOperatorsView->setEnabled(false);
    ui.actionEngineersView->setEnabled(false);
    // The UAS actions are not enabled without connection to system
    ui.actionLiftoff->setEnabled(false);
    ui.actionLand->setEnabled(false);
    ui.actionEmergency_Kill->setEnabled(false);
    ui.actionEmergency_Land->setEnabled(false);
    ui.actionShutdownMAV->setEnabled(false);

pixhawk's avatar
pixhawk committed
1266 1267 1268 1269 1270
    // 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*)));
1271
    connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
pixhawk's avatar
pixhawk committed
1272

1273
    // Unmanned System controls
pixhawk's avatar
pixhawk committed
1274 1275 1276 1277
    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()));
1278
    connect(ui.actionShutdownMAV, SIGNAL(triggered()), UASManager::instance(), SLOT(shutdownActiveUAS()));
pixhawk's avatar
pixhawk committed
1279 1280
    connect(ui.actionConfiguration, SIGNAL(triggered()), UASManager::instance(), SLOT(configureActiveUAS()));

1281
    // Views actions
1282
    connect(ui.actionPilotsView, SIGNAL(triggered()), this, SLOT(loadPilotView()));
1283
    connect(ui.actionEngineersView, SIGNAL(triggered()), this, SLOT(loadEngineerView()));
1284
    connect(ui.actionOperatorsView, SIGNAL(triggered()), this, SLOT(loadOperatorView()));
1285
    connect(ui.actionUnconnectedView, SIGNAL(triggered()), this, SLOT(loadUnconnectedView()));
1286

1287 1288
    connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView()));
    connect(ui.actionReloadStyle, SIGNAL(triggered()), this, SLOT(reloadStylesheet()));
1289

1290
    // Help Actions
1291
    connect(ui.actionOnline_Documentation, SIGNAL(triggered()), this, SLOT(showHelp()));
1292
    connect(ui.actionDeveloper_Credits, SIGNAL(triggered()), this, SLOT(showCredits()));
1293
    connect(ui.actionProject_Roadmap_2, SIGNAL(triggered()), this, SLOT(showRoadMap()));
1294 1295 1296

    // Custom widget actions
    connect(ui.actionNewCustomWidget, SIGNAL(triggered()), this, SLOT(createCustomWidget()));
1297 1298 1299 1300

    // Audio output
    ui.actionMuteAudioOutput->setChecked(GAudioOutput::instance()->isMuted());
    connect(ui.actionMuteAudioOutput, SIGNAL(triggered(bool)), GAudioOutput::instance(), SLOT(mute(bool)));
1301 1302 1303 1304 1305 1306 1307 1308 1309

    // User interaction
    // NOTE: Joystick thread is not started and
    // configuration widget is not instantiated
    // unless it is actually used
    // so no ressources spend on this.
    ui.actionJoystickSettings->setVisible(true);
    // Joystick configuration
    connect(ui.actionJoystickSettings, SIGNAL(triggered()), this, SLOT(configure()));
1310 1311 1312 1313 1314 1315 1316 1317 1318 1319
}

void MainWindow::connectPxActions()
{


}

void MainWindow::connectSlugsActions()
{
1320

pixhawk's avatar
pixhawk committed
1321 1322
}

1323 1324
void MainWindow::showHelp()
{
1325
    if(!QDesktopServices::openUrl(QUrl("http://qgroundcontrol.org/users/")))
1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338
    {
        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()
{
1339
    if(!QDesktopServices::openUrl(QUrl("http://qgroundcontrol.org/credits/")))
1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
    {
        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()
{
1353
    if(!QDesktopServices::openUrl(QUrl("http://qgroundcontrol.org/roadmap/")))
1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364
    {
        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
1365
void MainWindow::configure()
pixhawk's avatar
pixhawk committed
1366
{
1367 1368 1369 1370 1371 1372 1373 1374 1375
    if (!joystickWidget)
    {
        if (!joystick->isRunning())
        {
            joystick->start();
        }
        joystickWidget = new JoystickWidget(joystick);
    }
    joystickWidget->show();
pixhawk's avatar
pixhawk committed
1376 1377
}

pixhawk's avatar
pixhawk committed
1378
void MainWindow::addLink()
pixhawk's avatar
pixhawk committed
1379 1380 1381 1382
{
    SerialLink* link = new SerialLink();
    // TODO This should be only done in the dialog itself

1383
    LinkManager::instance()->add(link);
pixhawk's avatar
pixhawk committed
1384 1385
    LinkManager::instance()->addProtocol(link, mavlink);

1386 1387
    // Go fishing for this link's configuration window
    QList<QAction*> actions = ui.menuNetwork->actions();
pixhawk's avatar
pixhawk committed
1388

1389 1390 1391 1392 1393 1394 1395 1396
    foreach (QAction* act, actions)
    {
        if (act->data().toInt() == LinkManager::instance()->getLinks().indexOf(link))
        {
            act->trigger();
            break;
        }
    }
pixhawk's avatar
pixhawk committed
1397 1398
}

pixhawk's avatar
pixhawk committed
1399 1400
void MainWindow::addLink(LinkInterface *link)
{
1401
    LinkManager::instance()->add(link);
1402
    LinkManager::instance()->addProtocol(link, mavlink);
1403

pixhawk's avatar
pixhawk committed
1404 1405 1406
    CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, this);
    ui.menuNetwork->addAction(commWidget->getAction());

1407 1408 1409
    // Error handling
    connect(link, SIGNAL(communicationError(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection);

1410 1411
    //qDebug() << "ADDING LINK:" << link->getName() << "ACTION IS: " << commWidget->getAction();

pixhawk's avatar
pixhawk committed
1412 1413 1414 1415
    // Special case for simulationlink
    MAVLinkSimulationLink* sim = dynamic_cast<MAVLinkSimulationLink*>(link);
    if (sim)
    {
1416
        //connect(sim, SIGNAL(valueChanged(int,QString,double,quint64)), linechart, SLOT(appendData(int,QString,double,quint64)));
pixhawk's avatar
pixhawk committed
1417 1418 1419 1420
        connect(ui.actionSimulate, SIGNAL(triggered(bool)), sim, SLOT(connectLink(bool)));
    }
}

1421 1422 1423 1424 1425 1426 1427
void MainWindow::setActiveUAS(UASInterface* uas)
{
    // Enable and rename menu
    ui.menuUnmanned_System->setTitle(uas->getUASName());
    if (!ui.menuUnmanned_System->isEnabled()) ui.menuUnmanned_System->setEnabled(true);
}

1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439
void MainWindow::UASSpecsChanged(int uas)
{
    UASInterface* activeUAS = UASManager::instance()->getActiveUAS();
    if (activeUAS)
    {
        if (activeUAS->getUASID() == uas)
        {
            ui.menuUnmanned_System->setTitle(activeUAS->getUASName());
        }
    }
}

pixhawk's avatar
pixhawk committed
1440
void MainWindow::UASCreated(UASInterface* uas)
pixhawk's avatar
pixhawk committed
1441
{
1442

pixhawk's avatar
pixhawk committed
1443 1444
    // Connect the UAS to the full user interface

1445 1446
    if (uas != NULL)
    {
1447 1448 1449 1450
        // Set default settings
        setDefaultSettingsForAp();

        // The pilot, operator and engineer views were not available on startup, enable them now
1451
        ui.actionPilotsView->setEnabled(true);
1452 1453
        ui.actionOperatorsView->setEnabled(true);
        ui.actionEngineersView->setEnabled(true);
1454 1455 1456 1457 1458 1459
        // The UAS actions are not enabled without connection to system
        ui.actionLiftoff->setEnabled(true);
        ui.actionLand->setEnabled(true);
        ui.actionEmergency_Kill->setEnabled(true);
        ui.actionEmergency_Land->setEnabled(true);
        ui.actionShutdownMAV->setEnabled(true);
1460

1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487
        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;
        }

1488 1489 1490
        QAction* uasAction = new QAction(icon, tr("Select %1 for control").arg(uas->getUASName()), ui.menuConnected_Systems);
        connect(uas, SIGNAL(systemRemoved()), uasAction, SLOT(deleteLater()));
        connect(uasAction, SIGNAL(triggered()), uas, SLOT(setSelected()));
1491
        connect(uas, SIGNAL(systemSpecsChanged(int)), this, SLOT(UASSpecsChanged(int)));
1492 1493

        ui.menuConnected_Systems->addAction(uasAction);
1494 1495

        // FIXME Should be not inside the mainwindow
1496 1497
        if (debugConsoleDockWidget)
        {
pixhawk's avatar
pixhawk committed
1498 1499 1500 1501 1502 1503
            DebugConsole *debugConsole = dynamic_cast<DebugConsole*>(debugConsoleDockWidget->widget());
            if (debugConsole)
            {
                connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)),
                        debugConsole, SLOT(receiveTextMessage(int,int,int,QString)));
            }
1504
        }
1505 1506

        // Health / System status indicator
1507 1508
        if (infoDockWidget)
        {
pixhawk's avatar
pixhawk committed
1509 1510 1511 1512 1513
            UASInfoWidget *infoWidget = dynamic_cast<UASInfoWidget*>(infoDockWidget->widget());
            if (infoWidget)
            {
                infoWidget->addUAS(uas);
            }
1514
        }
1515 1516

        // UAS List
1517 1518
        if (listDockWidget)
        {
pixhawk's avatar
pixhawk committed
1519 1520 1521 1522 1523
            UASListWidget *listWidget = dynamic_cast<UASListWidget*>(listDockWidget->widget());
            if (listWidget)
            {
                listWidget->addUAS(uas);
            }
1524
        }
1525

1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553
        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();
                //                }
                //              }
                //            }
1554

1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580
            }
            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
1581
        if (UASManager::instance()->getUASList().size() == 1)
1582
        {
1583
            //qDebug() << "UPDATING THE VIEW SINCE THIS IS THE FIRST CONNECTED SYSTEM";
1584 1585

            // Load last view if setting is present
1586
            if (settings.contains("CURRENT_VIEW_WITH_UAS_CONNECTED"))
1587
            {
1588
                clearView();
1589
                int view = settings.value("CURRENT_VIEW_WITH_UAS_CONNECTED").toInt();
1590
                switch (view)
1591
                {
1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607
                case VIEW_ENGINEER:
                    loadEngineerView();
                    break;
                case VIEW_MAVLINK:
                    loadMAVLinkView();
                    break;
                case VIEW_PILOT:
                    loadPilotView();
                    break;
                case VIEW_UNCONNECTED:
                    loadUnconnectedView();
                    break;
                case VIEW_OPERATOR:
                default:
                    loadOperatorView();
                    break;
1608
                }
1609 1610 1611
            }
            else
            {
1612
                loadOperatorView();
1613
            }
1614
        }
1615

1616
    }
1617 1618

    if (!ui.menuConnected_Systems->isEnabled()) ui.menuConnected_Systems->setEnabled(true);
lm's avatar
lm committed
1619 1620 1621

    // Custom widgets, added last to all menus and layouts
    buildCustomWidget();
pixhawk's avatar
pixhawk committed
1622 1623
}

1624 1625 1626
/**
 * Clears the current view completely
 */
pixhawk's avatar
pixhawk committed
1627
void MainWindow::clearView()
1628
{
1629
    // Save current state
1630
    if (UASManager::instance()->getUASList().count() > 0) settings.setValue(getWindowStateKey(), saveState(QGC::applicationVersion()));
1631
    settings.setValue(getWindowGeometryKey(), saveGeometry());
1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642

    QAction* temp;

    // Set tool widget visibility settings for this view
    foreach (int key, toolsMenuActions.keys())
    {
        temp = toolsMenuActions[key];
        QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(key), currentView);

        if (temp)
        {
1643
            qDebug() << "TOOL:" << chKey << "IS:" << temp->isChecked();
1644 1645 1646 1647
            settings.setValue(chKey,temp->isChecked());
        }
        else
        {
1648
            qDebug() << "TOOL:" << chKey << "IS DEFAULT AND UNCHECKED";
1649 1650 1651 1652
            settings.setValue(chKey,false);
        }
    }

1653
    changingViewsFlag = true;
1654 1655
    // Remove all dock widgets from main window
    QObjectList childList( this->children() );
pixhawk's avatar
pixhawk committed
1656

1657 1658 1659
    QObjectList::iterator i;
    QDockWidget* dockWidget;
    for (i = childList.begin(); i != childList.end(); ++i)
pixhawk's avatar
pixhawk committed
1660
    {
1661 1662
        dockWidget = dynamic_cast<QDockWidget*>(*i);
        if (dockWidget)
pixhawk's avatar
pixhawk committed
1663
        {
1664
            // Remove dock widget from main window
1665
            removeDockWidget(dockWidget);
1666
            dockWidget->hide();
1667
            //dockWidget->setVisible(false);
pixhawk's avatar
pixhawk committed
1668 1669
        }
    }
1670
    changingViewsFlag = false;
pixhawk's avatar
pixhawk committed
1671 1672
}

1673
void MainWindow::loadEngineerView()
lm's avatar
lm committed
1674
{
1675 1676
    if (currentView != VIEW_ENGINEER)
    {
1677 1678 1679 1680
        clearView();
        currentView = VIEW_ENGINEER;
        ui.actionEngineersView->setChecked(true);
        presentView();
1681
    }
lm's avatar
lm committed
1682 1683
}

1684
void MainWindow::loadOperatorView()
lm's avatar
lm committed
1685
{
1686 1687
    if (currentView != VIEW_OPERATOR)
    {
1688 1689 1690 1691 1692 1693
        clearView();
        currentView = VIEW_OPERATOR;
        ui.actionOperatorsView->setChecked(true);
        presentView();
    }
}
lm's avatar
lm committed
1694

1695 1696 1697 1698 1699 1700 1701 1702
void MainWindow::loadUnconnectedView()
{
    if (currentView != VIEW_UNCONNECTED)
    {
        clearView();
        currentView = VIEW_UNCONNECTED;
        ui.actionUnconnectedView->setChecked(true);
        presentView();
1703
    }
lm's avatar
lm committed
1704 1705
}

1706
void MainWindow::loadPilotView()
1707
{
1708 1709
    if (currentView != VIEW_PILOT)
    {
1710 1711 1712 1713
        clearView();
        currentView = VIEW_PILOT;
        ui.actionPilotsView->setChecked(true);
        presentView();
1714
    }
1715 1716
}

1717
void MainWindow::loadMAVLinkView()
1718
{
1719 1720
    if (currentView != VIEW_MAVLINK)
    {
1721 1722 1723 1724
        clearView();
        currentView = VIEW_MAVLINK;
        ui.actionMavlinkView->setChecked(true);
        presentView();
1725
    }
1726 1727
}

lm's avatar
lm committed
1728 1729
void MainWindow::presentView()
{
1730
    // LINE CHART
1731
    showTheCentralWidget(CENTRAL_LINECHART, currentView);
1732

1733 1734
    // MAP
    showTheCentralWidget(CENTRAL_MAP, currentView);
pixhawk's avatar
pixhawk committed
1735

1736 1737
    // PROTOCOL
    showTheCentralWidget(CENTRAL_PROTOCOL, currentView);
pixhawk's avatar
pixhawk committed
1738

1739 1740
    // HEAD UP DISPLAY
    showTheCentralWidget(CENTRAL_HUD, currentView);
pixhawk's avatar
pixhawk committed
1741 1742 1743 1744 1745 1746 1747 1748 1749 1750

    // GOOGLE EARTH
    showTheCentralWidget(CENTRAL_GOOGLE_EARTH, currentView);

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

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

1751 1752 1753
    // DATA PLOT
    showTheCentralWidget(CENTRAL_DATA_PLOT, currentView);

pixhawk's avatar
pixhawk committed
1754

1755
    // Show docked widgets based on current view and autopilot type
1756

1757 1758
    // UAS CONTROL
    showTheWidget(MENU_UAS_CONTROL, currentView);
1759

1760 1761
    // UAS LIST
    showTheWidget(MENU_UAS_LIST, currentView);
1762

1763 1764
    // WAYPOINT LIST
    showTheWidget(MENU_WAYPOINTS, currentView);
pixhawk's avatar
pixhawk committed
1765

1766 1767
    // UAS STATUS
    showTheWidget(MENU_STATUS, currentView);
1768

1769 1770
    // DETECTION
    showTheWidget(MENU_DETECTION, currentView);
1771

1772 1773
    // DEBUG CONSOLE
    showTheWidget(MENU_DEBUG_CONSOLE, currentView);
1774

1775 1776
    // ONBOARD PARAMETERS
    showTheWidget(MENU_PARAMETERS, currentView);
1777

1778 1779
    // WATCHDOG
    showTheWidget(MENU_WATCHDOG, currentView);
1780

1781 1782 1783 1784 1785
    // HUD
    showTheWidget(MENU_HUD, currentView);
    if (headUpDockWidget)
    {
        HUD* tmpHud = dynamic_cast<HUD*>( headUpDockWidget->widget() );
1786 1787 1788 1789
        if (tmpHud)
        {
            if (settings.value(buildMenuKey (SUB_SECTION_CHECKED,MENU_HUD,currentView)).toBool())
            {
1790
                addDockWidget(static_cast <Qt::DockWidgetArea>(settings.value(buildMenuKey (SUB_SECTION_LOCATION,MENU_HUD, currentView)).toInt()),
1791
                        headUpDockWidget);
1792
                headUpDockWidget->show();
1793 1794 1795
            }
            else
            {
1796 1797
                headUpDockWidget->hide();
            }
1798
        }
1799
    }
1800

1801

1802 1803
    // RC View
    showTheWidget(MENU_RC_VIEW, currentView);
1804

1805 1806
    // SLUGS DATA
    showTheWidget(MENU_SLUGS_DATA, currentView);
1807

1808 1809
    // SLUGS PID
    showTheWidget(MENU_SLUGS_PID, currentView);
1810

1811 1812
    // SLUGS HIL
    showTheWidget(MENU_SLUGS_HIL, currentView);
1813

1814 1815
    // SLUGS CAMERA
    showTheWidget(MENU_SLUGS_CAMERA, currentView);
1816

1817 1818
    // HORIZONTAL SITUATION INDICATOR
    showTheWidget(MENU_HSI, currentView);
1819

1820 1821 1822 1823 1824
    // HEAD DOWN 1
    showTheWidget(MENU_HDD_1, currentView);

    // HEAD DOWN 2
    showTheWidget(MENU_HDD_2, currentView);
1825

1826 1827 1828
    // MAVLINK LOG PLAYER
    showTheWidget(MENU_MAVLINK_LOG_PLAYER, currentView);

1829 1830 1831 1832 1833 1834
    // VIDEO 1
    showTheWidget(MENU_VIDEO_STREAM_1, currentView);

    // VIDEO 2
    showTheWidget(MENU_VIDEO_STREAM_2, currentView);

1835
    this->show();
1836

1837
    // Restore window state
1838 1839 1840
    if (UASManager::instance()->getUASList().count() > 0)
    {
        // Restore the mainwindow size
1841 1842 1843 1844
        if (settings.contains(getWindowGeometryKey()))
        {
            restoreGeometry(settings.value(getWindowGeometryKey()).toByteArray());
        }
1845 1846 1847 1848 1849 1850 1851

        // Restore the widget positions and size
        if (settings.contains(getWindowStateKey()))
        {
            restoreState(settings.value(getWindowStateKey()).toByteArray(), QGC::applicationVersion());
        }
    }
1852
}
1853

1854 1855 1856 1857
void MainWindow::showTheCentralWidget (TOOLS_WIDGET_NAMES centralWidget, VIEW_SECTIONS view)
{
    bool tempVisible;
    QWidget* tempWidget = dockWidgets[centralWidget];
1858

1859 1860
    tempVisible =  settings.value(buildMenuKey(SUB_SECTION_CHECKED,centralWidget,view), false).toBool();
    qDebug() << buildMenuKey (SUB_SECTION_CHECKED,centralWidget,view) << tempVisible;
1861
    if (toolsMenuActions[centralWidget])
1862
    {
1863
        qDebug() << "SETTING TO:" << tempVisible;
1864
        toolsMenuActions[centralWidget]->setChecked(tempVisible);
1865
    }
1866

1867
    if (centerStack && tempWidget && tempVisible)
1868
    {
1869
        qDebug() << "ACTIVATING MAIN WIDGET";
1870
        centerStack->setCurrentWidget(tempWidget);
1871
    }
1872 1873
}

1874 1875
void MainWindow::loadDataView(QString fileName)
{
1876
    clearView();
1877 1878 1879 1880 1881

    // Unload line chart
    QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(CENTRAL_LINECHART), currentView);
    settings.setValue(chKey,false);

1882
    // Set data plot in settings as current widget and then run usual update procedure
1883
    chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(CENTRAL_DATA_PLOT), currentView);
1884
    settings.setValue(chKey,true);
1885

1886
    presentView();
1887

1888 1889
    // Plot is now selected, now load data from file
    if (dataplotWidget)
1890
    {
1891
        dataplotWidget->loadFile(fileName);
1892
        }
1893 1894 1895 1896 1897 1898 1899
//        QStackedWidget *centerStack = dynamic_cast<QStackedWidget*>(centralWidget());
//        if (centerStack)
//        {
//            centerStack->setCurrentWidget(dataplotWidget);
//            dataplotWidget->loadFile(fileName);
//        }
//    }
1900 1901 1902
}