MainWindow.cc 61.1 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
#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 42

#include "LogCompressor.h"

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 78 79 80 81 82 83 84
    if (!settings.contains("CURRENT_VIEW"))
    {
        // Set this view as default view
        settings.setValue("CURRENT_VIEW", currentView);

        // Enable default tools

        // ENABLE UAS LIST
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_UAS_LIST,currentView), true);
        // ENABLE COMMUNICATION CONSOLE
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_DEBUG_CONSOLE,currentView), true);
    }
    else
    {
85 86 87 88 89
        // 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)
90
        {
91
            currentView = currentViewCandidate;
92
        }
93 94
    }

95
    setDefaultSettingsForAp();
96

97 98
    settings.sync();

pixhawk's avatar
pixhawk committed
99 100
    // Setup user interface
    ui.setupUi(this);
lm's avatar
lm committed
101
    ui.actionNewCustomWidget->setEnabled(false);
pixhawk's avatar
pixhawk committed
102

103 104
    setVisible(false);

105 106 107 108 109 110
    // 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);
111
    perspectives->addAction(ui.actionUnconnectedView);
112 113 114 115 116 117 118
    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);
119
    if (currentView == VIEW_UNCONNECTED) ui.actionUnconnectedView->setChecked(true);
120

121 122
    // The pilot, engineer and operator view are not available on startup
    // since they only make sense with a system connected.
123
    ui.actionPilotsView->setEnabled(false);
124 125
    ui.actionOperatorsView->setEnabled(false);
    ui.actionEngineersView->setEnabled(false);
126

127
    buildCommonWidgets();
128

129
    connectCommonWidgets();
130

131
    arrangeCommonCenterStack();
132 133

    configureWindowName();
pixhawk's avatar
pixhawk committed
134 135 136 137

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

pixhawk's avatar
pixhawk committed
139
    // Set style sheet as last step
140 141 142 143 144 145 146
    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
147

148
    // Create actions
149
    connectCommonActions();
150

151 152 153
    // Set dock options
    setDockOptions(AnimatedDocks | AllowTabbedDocks | AllowNestedDocks);

154
    // Load mavlink view as default widget set
155
    //loadMAVLinkView();
156

lm's avatar
lm committed
157 158
    statusBar()->setSizeGripEnabled(true);

159 160
    // Restore the window position and size
    if (settings.contains(getWindowGeometryKey()))
161 162
    {
        // Restore the window geometry
163
        restoreGeometry(settings.value(getWindowGeometryKey()).toByteArray());
164 165 166 167 168 169
    }
    else
    {
        // Adjust the size
        adjustSize();
    }
pixhawk's avatar
pixhawk committed
170

171 172 173 174 175 176
    // Populate link menu
    QList<LinkInterface*> links = LinkManager::instance()->getLinks();
    foreach(LinkInterface* link, links)
    {
        this->addLink(link);
    }
177

178 179
    connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*)));

180 181 182 183 184 185
    // Connect user interface devices
    if (!joystick)
    {
        joystick = new JoystickInput();
    }

lm's avatar
lm committed
186 187
    // Enable and update view
    presentView();
pixhawk's avatar
pixhawk committed
188 189
}

pixhawk's avatar
pixhawk committed
190
MainWindow::~MainWindow()
pixhawk's avatar
pixhawk committed
191
{
lm's avatar
lm committed
192

pixhawk's avatar
pixhawk committed
193 194
}

195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
/**
 * 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);
    }

    // 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);
217 218
        // ENABLE HUD TOOL WIDGET
        settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_HUD,VIEW_OPERATOR), true);
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
    }

    // ENGINEER VIEW DEFAULT
    centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_LINECHART, VIEW_ENGINEER);
    if (!settings.contains(centralKey))
    {
        settings.setValue(centralKey,true);
    }

    // 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);
    }
}

lm's avatar
lm committed
243 244 245 246 247 248 249 250 251 252 253 254 255
void MainWindow::resizeEvent(QResizeEvent * event)
{
    Q_UNUSED(event);
    if (height() < 800)
    {
        ui.statusBar->setVisible(false);
    }
    else
    {
        ui.statusBar->setVisible(true);
    }
}

256 257 258 259 260 261 262 263 264 265
QString MainWindow::getWindowStateKey()
{
    return QString::number(currentView)+"/windowstate";
}

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

lm's avatar
lm committed
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
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);
            }
        }
    }
}

303 304 305 306
void MainWindow::buildCommonWidgets()
{
    //TODO:  move protocol outside UI
    mavlink     = new MAVLinkProtocol();
307
    connect(mavlink, SIGNAL(protocolStatusMessage(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection);
308 309

    // Dock widgets
310 311 312
    if (!controlDockWidget)
    {
        controlDockWidget = new QDockWidget(tr("Control"), this);
313
        controlDockWidget->setObjectName("UNMANNED_SYSTEM_CONTROL_DOCKWIDGET");
314
        controlDockWidget->setWidget( new UASControlWidget(this) );
315
        addToToolsMenu (controlDockWidget, tr("Control"), SLOT(showToolWidget(bool)), MENU_UAS_CONTROL, Qt::LeftDockWidgetArea);
316
    }
317

318 319 320 321
    if (!listDockWidget)
    {
        listDockWidget = new QDockWidget(tr("Unmanned Systems"), this);
        listDockWidget->setWidget( new UASListWidget(this) );
322
        listDockWidget->setObjectName("UNMANNED_SYSTEMS_LIST_DOCKWIDGET");
323
        addToToolsMenu (listDockWidget, tr("Unmanned Systems"), SLOT(showToolWidget(bool)), MENU_UAS_LIST, Qt::RightDockWidgetArea);
324
    }
325

326 327 328 329
    if (!waypointsDockWidget)
    {
        waypointsDockWidget = new QDockWidget(tr("Waypoint List"), this);
        waypointsDockWidget->setWidget( new WaypointList(this, NULL) );
330
        waypointsDockWidget->setObjectName("WAYPOINT_LIST_DOCKWIDGET");
331
        addToToolsMenu (waypointsDockWidget, tr("Waypoints List"), SLOT(showToolWidget(bool)), MENU_WAYPOINTS, Qt::BottomDockWidgetArea);
332
    }
333

334 335 336 337
    if (!infoDockWidget)
    {
        infoDockWidget = new QDockWidget(tr("Status Details"), this);
        infoDockWidget->setWidget( new UASInfoWidget(this) );
pixhawk's avatar
pixhawk committed
338
        infoDockWidget->setObjectName("UAS_STATUS_DETAILS_DOCKWIDGET");
339
        addToToolsMenu (infoDockWidget, tr("Status Details"), SLOT(showToolWidget(bool)), MENU_STATUS, Qt::RightDockWidgetArea);
340
    }
341

342 343 344 345
    if (!debugConsoleDockWidget)
    {
        debugConsoleDockWidget = new QDockWidget(tr("Communication Console"), this);
        debugConsoleDockWidget->setWidget( new DebugConsole(this) );
346
        debugConsoleDockWidget->setObjectName("COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET");
347
        addToToolsMenu (debugConsoleDockWidget, tr("Communication Console"), SLOT(showToolWidget(bool)), MENU_DEBUG_CONSOLE, Qt::BottomDockWidgetArea);
348
    }
349

350 351 352 353 354
    if (!logPlayerDockWidget)
    {
        logPlayerDockWidget = new QDockWidget(tr("MAVLink Log Player"), this);
        logPlayerDockWidget->setWidget( new QGCMAVLinkLogPlayer(mavlink, this) );
        logPlayerDockWidget->setObjectName("MAVLINK_LOG_PLAYER_DOCKWIDGET");
355
        addToToolsMenu(logPlayerDockWidget, tr("MAVLink Log Replay"), SLOT(showToolWidget(bool)), MENU_MAVLINK_LOG_PLAYER, Qt::RightDockWidgetArea);
356 357
    }

358
    // Center widgets
359 360
    if (!mapWidget)
    {
361
        mapWidget = new MapWidget(this);
362 363
        addToCentralWidgetsMenu (mapWidget, "Maps", SLOT(showCentralWidget()),CENTRAL_MAP);
    }
364

365 366 367 368 369
    if (!protocolWidget)
    {
        protocolWidget    = new XMLCommProtocolWidget(this);
        addToCentralWidgetsMenu (protocolWidget, "Mavlink Generator", SLOT(showCentralWidget()),CENTRAL_PROTOCOL);
    }
lm's avatar
lm committed
370

Alejandro's avatar
Alejandro committed
371 372 373 374 375
    //TODO temporaly debug
    if (!slugsHilSimWidget)
    {
        slugsHilSimWidget = new QDockWidget(tr("Slugs Hil Sim"), this);
        slugsHilSimWidget->setWidget( new SlugsHilSim(this));
376
        addToToolsMenu (slugsHilSimWidget, tr("HIL Sim Configuration"), SLOT(showToolWidget(bool)), MENU_SLUGS_HIL, Qt::LeftDockWidgetArea);
Alejandro's avatar
Alejandro committed
377 378 379 380 381 382 383
    }

    //TODO temporaly debug
    if (!slugsCamControlWidget)
    {
        slugsCamControlWidget = new QDockWidget(tr("Slugs Video Camera Control"), this);
        slugsCamControlWidget->setWidget(new SlugsVideoCamControl(this));
384
        addToToolsMenu (slugsCamControlWidget, tr("Camera Control"), SLOT(showToolWidget(bool)), MENU_SLUGS_CAMERA, Qt::BottomDockWidgetArea);
Alejandro's avatar
Alejandro committed
385
    }
lm's avatar
lm committed
386 387 388 389 390
    if (!dataplotWidget)
    {
        dataplotWidget    = new QGCDataPlot2D(this);
        addToCentralWidgetsMenu (dataplotWidget, "Data Plot", SLOT(showCentralWidget()),CENTRAL_DATA_PLOT);
    }
391
}
392

393
void MainWindow::buildPxWidgets()
394
{
pixhawk's avatar
pixhawk committed
395 396
    //FIXME: memory of acceptList will never be freed again
    QStringList* acceptList = new QStringList();
lm's avatar
lm committed
397 398 399
    acceptList->append("-105,roll,deg,+105,s");
    acceptList->append("-105,pitch,deg,+105,s");
    acceptList->append("-105,yaw,deg,+105,s");
400

lm's avatar
lm committed
401 402 403
    acceptList->append("-260,rollspeed,deg/s,+260,s");
    acceptList->append("-260,pitchspeed,deg/s,+260,s");
    acceptList->append("-260,yawspeed,deg/s,+260,s");
404

pixhawk's avatar
pixhawk committed
405 406
    //FIXME: memory of acceptList2 will never be freed again
    QStringList* acceptList2 = new QStringList();
lm's avatar
lm committed
407
    acceptList2->append("0,abs pressure,hPa,65500");
408 409
    acceptList2->append("-999,accel. X,raw,999,s");
    acceptList2->append("-999,accel. Y,raw,999,s");
410

411 412 413 414 415 416
    if (!linechartWidget)
    {
        // Center widgets
        linechartWidget   = new Linecharts(this);
        addToCentralWidgetsMenu(linechartWidget, "Line Plots", SLOT(showCentralWidget()), CENTRAL_LINECHART);
    }
417 418


419 420 421 422 423
    if (!hudWidget)
    {
        hudWidget         = new HUD(320, 240, this);
        addToCentralWidgetsMenu(hudWidget, "HUD", SLOT(showCentralWidget()), CENTRAL_HUD);
    }
424

425 426 427 428 429
    if (!dataplotWidget)
    {
        dataplotWidget    = new QGCDataPlot2D(this);
        addToCentralWidgetsMenu(dataplotWidget, "Data Plots", SLOT(showCentralWidget()), CENTRAL_DATA_PLOT);
    }
430

431
#ifdef QGC_OSG_ENABLED
432 433
    if (!_3DWidget)
    {
434 435
        _3DWidget         = Q3DWidgetFactory::get("PIXHAWK");
        addToCentralWidgetsMenu(_3DWidget, "Local 3D", SLOT(showCentralWidget()), CENTRAL_3D_LOCAL);
436
    }
437
#endif
438

439
#ifdef QGC_OSGEARTH_ENABLED
440 441 442 443 444
    if (!_3DMapWidget)
    {
        _3DMapWidget = Q3DWidgetFactory::get("MAP3D");
        addToCentralWidgetsMenu(_3DMapWidget, "OSG Earth 3D", SLOT(showCentralWidget()), CENTRAL_OSGEARTH);
    }
445
#endif
lm's avatar
lm committed
446

447
#if (defined _MSC_VER) | (defined Q_OS_MAC)
448 449 450 451 452
    if (!gEarthWidget)
    {
        gEarthWidget = new QGCGoogleEarthView(this);
        addToCentralWidgetsMenu(gEarthWidget, "Google Earth", SLOT(showCentralWidget()), CENTRAL_GOOGLE_EARTH);
    }
453

454
#endif
455

pixhawk's avatar
pixhawk committed
456
    // Dock widgets
457

458 459 460 461
    if (!detectionDockWidget)
    {
        detectionDockWidget = new QDockWidget(tr("Object Recognition"), this);
        detectionDockWidget->setWidget( new ObjectDetectionView("images/patterns", this) );
pixhawk's avatar
pixhawk committed
462
        detectionDockWidget->setObjectName("OBJECT_DETECTION_DOCK_WIDGET");
463
        addToToolsMenu (detectionDockWidget, tr("Object Recognition"), SLOT(showToolWidget(bool)), MENU_DETECTION, Qt::RightDockWidgetArea);
464
    }
465

466 467
    if (!parametersDockWidget)
    {
468
        parametersDockWidget = new QDockWidget(tr("Calibration and Onboard Parameters"), this);
469
        parametersDockWidget->setWidget( new ParameterInterface(this) );
pixhawk's avatar
pixhawk committed
470
        parametersDockWidget->setObjectName("PARAMETER_INTERFACE_DOCKWIDGET");
471
        addToToolsMenu (parametersDockWidget, tr("Calibration and Parameters"), SLOT(showToolWidget(bool)), MENU_PARAMETERS, Qt::RightDockWidgetArea);
472
    }
473

474 475 476 477
    if (!watchdogControlDockWidget)
    {
        watchdogControlDockWidget = new QDockWidget(tr("Process Control"), this);
        watchdogControlDockWidget->setWidget( new WatchdogControl(this) );
pixhawk's avatar
pixhawk committed
478
        watchdogControlDockWidget->setObjectName("WATCHDOG_CONTROL_DOCKWIDGET");
479
        addToToolsMenu (watchdogControlDockWidget, tr("Process Control"), SLOT(showToolWidget(bool)), MENU_WATCHDOG, Qt::BottomDockWidgetArea);
480
    }
481

482 483 484 485
    if (!hsiDockWidget)
    {
        hsiDockWidget = new QDockWidget(tr("Horizontal Situation Indicator"), this);
        hsiDockWidget->setWidget( new HSIDisplay(this) );
486
        hsiDockWidget->setObjectName("HORIZONTAL_SITUATION_INDICATOR_DOCK_WIDGET");
487
        addToToolsMenu (hsiDockWidget, tr("HSI"), SLOT(showToolWidget(bool)), MENU_HSI, Qt::BottomDockWidgetArea);
488
    }
489

490 491
    if (!headDown1DockWidget)
    {
492 493
        headDown1DockWidget = new QDockWidget(tr("Flight Display"), this);
        headDown1DockWidget->setWidget( new HDDisplay(acceptList, "Flight Display", this) );
494
        headDown1DockWidget->setObjectName("HEAD_DOWN_DISPLAY_1_DOCK_WIDGET");
495
        addToToolsMenu (headDown1DockWidget, tr("Flight Display"), SLOT(showToolWidget(bool)), MENU_HDD_1, Qt::RightDockWidgetArea);
496
    }
497

498 499 500
    if (!headDown2DockWidget)
    {
        headDown2DockWidget = new QDockWidget(tr("Payload Status"), this);
501
        headDown2DockWidget->setWidget( new HDDisplay(acceptList2, "Payload Status", this) );
502
        headDown2DockWidget->setObjectName("HEAD_DOWN_DISPLAY_2_DOCK_WIDGET");
503
        addToToolsMenu (headDown2DockWidget, tr("Payload Status"), SLOT(showToolWidget(bool)), MENU_HDD_2, Qt::RightDockWidgetArea);
504
    }
505

506 507 508 509
    if (!rcViewDockWidget)
    {
        rcViewDockWidget = new QDockWidget(tr("Radio Control"), this);
        rcViewDockWidget->setWidget( new QGCRemoteControlView(this) );
510
        rcViewDockWidget->setObjectName("RADIO_CONTROL_CHANNELS_DOCK_WIDGET");
511
        addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget(bool)), MENU_RC_VIEW, Qt::BottomDockWidgetArea);
512
    }
513

514 515 516 517
    if (!headUpDockWidget)
    {
        headUpDockWidget = new QDockWidget(tr("HUD"), this);
        headUpDockWidget->setWidget( new HUD(320, 240, this));
518
        headUpDockWidget->setObjectName("HEAD_UP_DISPLAY_DOCK_WIDGET");
519
        addToToolsMenu (headUpDockWidget, tr("Head Up Display"), SLOT(showToolWidget(bool)), MENU_HUD, Qt::RightDockWidgetArea);
520
    }
521

pixhawk's avatar
pixhawk committed
522 523 524 525 526 527 528 529 530
    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");
531
        addToToolsMenu (video1DockWidget, tr("Video Stream 1"), SLOT(showToolWidget(bool)), MENU_VIDEO_STREAM_1, Qt::LeftDockWidgetArea);
pixhawk's avatar
pixhawk committed
532 533 534 535 536 537 538 539 540 541 542
    }

    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");
543
        addToToolsMenu (video2DockWidget, tr("Video Stream 2"), SLOT(showToolWidget(bool)), MENU_VIDEO_STREAM_2, Qt::LeftDockWidgetArea);
pixhawk's avatar
pixhawk committed
544 545
    }

pixhawk's avatar
pixhawk committed
546 547
    // Dialogue widgets
    //FIXME: free memory in destructor
548 549 550 551
}

void MainWindow::buildSlugsWidgets()
{
552 553 554 555 556
    if (!linechartWidget)
    {
        // Center widgets
        linechartWidget   = new Linecharts(this);
    }
557

558 559 560 561 562
    if (!headUpDockWidget)
    {
        // Dock widgets
        headUpDockWidget = new QDockWidget(tr("Control Indicator"), this);
        headUpDockWidget->setWidget( new HUD(320, 240, this));
pixhawk's avatar
pixhawk committed
563
        headUpDockWidget->setObjectName("HEAD_UP_DISPLAY_DOCK_WIDGET");
564
        addToToolsMenu (headUpDockWidget, tr("HUD"), SLOT(showToolWidget(bool)), MENU_HUD, Qt::LeftDockWidgetArea);
565
    }
566

567 568 569 570
    if (!rcViewDockWidget)
    {
        rcViewDockWidget = new QDockWidget(tr("Radio Control"), this);
        rcViewDockWidget->setWidget( new QGCRemoteControlView(this) );
pixhawk's avatar
pixhawk committed
571
        rcViewDockWidget->setObjectName("RADIO_CONTROL_CHANNELS_DOCK_WIDGET");
572
        addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget(bool)), MENU_RC_VIEW, Qt::BottomDockWidgetArea);
573
    }
574

575 576 577 578 579
    if (!slugsDataWidget)
    {
        // Dialog widgets
        slugsDataWidget = new QDockWidget(tr("Slugs Data"), this);
        slugsDataWidget->setWidget( new SlugsDataSensorView(this));
pixhawk's avatar
pixhawk committed
580
        slugsDataWidget->setObjectName("SLUGS_DATA_DOCK_WIDGET");
581
        addToToolsMenu (slugsDataWidget, tr("Telemetry Data"), SLOT(showToolWidget(bool)), MENU_SLUGS_DATA, Qt::RightDockWidgetArea);
582
    }
583

584 585 586 587
    if (!slugsPIDControlWidget)
    {
        slugsPIDControlWidget = new QDockWidget(tr("Slugs PID Control"), this);
        slugsPIDControlWidget->setWidget(new SlugsPIDControl(this));
pixhawk's avatar
pixhawk committed
588
        slugsPIDControlWidget->setObjectName("SLUGS_PID_CONTROL_DOCK_WIDGET");
589
        addToToolsMenu (slugsPIDControlWidget, tr("PID Configuration"), SLOT(showToolWidget(bool)), MENU_SLUGS_PID, Qt::LeftDockWidgetArea);
590
    }
591

592 593 594 595
    if (!slugsHilSimWidget)
    {
        slugsHilSimWidget = new QDockWidget(tr("Slugs Hil Sim"), this);
        slugsHilSimWidget->setWidget( new SlugsHilSim(this));
pixhawk's avatar
pixhawk committed
596
        slugsHilSimWidget->setObjectName("SLUGS_HIL_SIM_DOCK_WIDGET");
597
        addToToolsMenu (slugsHilSimWidget, tr("HIL Sim Configuration"), SLOT(showToolWidget(bool)), MENU_SLUGS_HIL, Qt::LeftDockWidgetArea);
598
    }
599

600 601 602 603
    if (!slugsCamControlWidget)
    {
        slugsCamControlWidget = new QDockWidget(tr("Slugs Video Camera Control"), this);
        slugsCamControlWidget->setWidget(new SlugsVideoCamControl(this));
pixhawk's avatar
pixhawk committed
604
        slugsCamControlWidget->setObjectName("SLUGS_CAM_CONTROL_DOCK_WIDGET");
605
        addToToolsMenu (slugsCamControlWidget, tr("Camera Control"), SLOT(showToolWidget(bool)), MENU_SLUGS_CAMERA, Qt::BottomDockWidgetArea);
606
    }
607
}
608 609 610 611 612


void MainWindow::addToCentralWidgetsMenu ( QWidget* widget,
                                           const QString title,
                                           const char * slotName,
613 614
                                           TOOLS_WIDGET_NAMES centralWidget)
{
615
    QAction* tempAction;
616

617

618
// Not needed any more - separate menu now available
619

620 621 622 623 624 625 626 627 628
//    // 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);
//    }

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

630 631
    tempAction->setCheckable(true);
    tempAction->setData(centralWidget);
632

633 634 635
    // populate the Hashes
    toolsMenuActions[centralWidget] = tempAction;
    dockWidgets[centralWidget] = widget;
636

637
    QString chKey = buildMenuKey(SUB_SECTION_CHECKED, centralWidget, currentView);
638

639 640
    if (!settings.contains(chKey))
    {
641 642 643
        settings.setValue(chKey,false);
        tempAction->setChecked(false);
    }
644 645 646 647
    else
    {
        tempAction->setChecked(settings.value(chKey).toBool());
    }
648

649
    // connect the action
650
    connect(tempAction,SIGNAL(triggered(bool)),this, slotName);
651 652 653
}


lm's avatar
lm committed
654 655
void MainWindow::showCentralWidget()
{
656
    QAction* senderAction = qobject_cast<QAction *>(sender());
657 658 659 660

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

661 662
    int tool = senderAction->data().toInt();
    QString chKey;
663

664
    // check the current action
665

666 667 668 669
    if (senderAction && dockWidgets[tool])
    {
        // uncheck all central widget actions
        QHashIterator<int, QAction*> i(toolsMenuActions);
670 671
        while (i.hasNext())
        {
672
            i.next();
673 674 675
            //qDebug() << "shCW" << i.key() << "read";
            if (i.value() && i.value()->data().toInt() > 255)
            {
676 677 678
                // Block signals and uncheck action
                // firing would be unneccesary
                i.value()->blockSignals(true);
679
                i.value()->setChecked(false);
680
                i.value()->blockSignals(false);
681 682 683 684 685 686

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

688
        // check the current action
689
        //qDebug() << senderAction->text();
690
        senderAction->setChecked(true);
691

692 693
        // update the central widget
        centerStack->setCurrentWidget(dockWidgets[tool]);
694

695 696 697
        // store the selected central widget
        chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(tool), currentView);
        settings.setValue(chKey,true);
698

699 700 701
        // Unblock sender action
        senderAction->blockSignals(false);

702 703
        presentView();
    }
704
}
705

lm's avatar
lm committed
706 707 708 709
/**
 * Adds a widget to the tools menu and sets it visible if it was
 * enabled last time.
 */
710
void MainWindow::addToToolsMenu ( QWidget* widget,
711 712 713 714
                                  const QString title,
                                  const char * slotName,
                                  TOOLS_WIDGET_NAMES tool,
                                  Qt::DockWidgetArea location)
lm's avatar
lm committed
715
{
716 717
    QAction* tempAction;
    QString posKey, chKey;
718

719

720 721
    if (toolsMenuActions[CENTRAL_SEPARATOR])
    {
722 723 724
        tempAction = new QAction(title, this);
        ui.menuTools->insertAction(toolsMenuActions[CENTRAL_SEPARATOR],
                                   tempAction);
725 726 727
    }
    else
    {
728 729
        tempAction = ui.menuTools->addAction(title);
    }
730

731 732
    tempAction->setCheckable(true);
    tempAction->setData(tool);
733

734 735 736
    // populate the Hashes
    toolsMenuActions[tool] = tempAction;
    dockWidgets[tool] = widget;
737
    //qDebug() << widget;
738

739
    posKey = buildMenuKey (SUB_SECTION_LOCATION,tool, currentView);
740

741 742
    if (!settings.contains(posKey))
    {
743 744
        settings.setValue(posKey,location);
        dockWidgetLocations[tool] = location;
745 746 747 748
    }
    else
    {
        dockWidgetLocations[tool] = static_cast <Qt::DockWidgetArea> (settings.value(posKey, Qt::RightDockWidgetArea).toInt());
749
    }
750

751
    chKey = buildMenuKey(SUB_SECTION_CHECKED,tool, currentView);
752

753 754 755 756
    if (!settings.contains(chKey))
    {
        settings.setValue(chKey,false);
        tempAction->setChecked(false);
757
        widget->setVisible(false);
758 759 760
    }
    else
    {
761
        tempAction->setChecked(settings.value(chKey, false).toBool());
762
        widget->setVisible(settings.value(chKey, false).toBool());
763
    }
764

765
    // connect the action
766 767 768
    connect(tempAction,SIGNAL(toggled(bool)),this, slotName);

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

771 772
    //  connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
    //          SIGNAL(visibilityChanged(bool)), this, SLOT(updateVisibilitySettings(bool)));
773

774 775
    connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
            SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(updateLocationSettings(Qt::DockWidgetArea)));
776 777
}

778
void MainWindow::showToolWidget(bool visible)
779
{
780
    if (!aboutToCloseFlag && !changingViewsFlag)
781
    {
782 783
        QAction* action = qobject_cast<QAction *>(sender());

784 785
        // Prevent this to fire if undocked
        if (action)
786
        {
787
            int tool = action->data().toInt();
788

789
            QDockWidget* dockWidget = qobject_cast<QDockWidget *> (dockWidgets[tool]);
790

791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
            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();
                }
806 807 808 809 810 811 812 813 814 815 816 817 818

                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;
                    }
                }
819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
            }
        }

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

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

        if (dockWidget)
        {
            // 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;
                }
            }
850
        }
851 852 853 854
    }
}


855 856 857 858 859
void MainWindow::showTheWidget (TOOLS_WIDGET_NAMES widget, VIEW_SECTIONS view)
{
    bool tempVisible;
    Qt::DockWidgetArea tempLocation;
    QDockWidget* tempWidget = static_cast <QDockWidget *>(dockWidgets[widget]);
860

861
    tempVisible =  settings.value(buildMenuKey(SUB_SECTION_CHECKED,widget,view), false).toBool();
862

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

865 866 867 868
    if (tempWidget)
    {
        toolsMenuActions[widget]->setChecked(tempVisible);
    }
869 870


871
    //qDebug() <<  buildMenuKey (SUB_SECTION_CHECKED,widget,view) << tempVisible;
872

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

875 876 877 878 879 880 881
    //    if (widget == MainWindow::MENU_UAS_LIST)
    //    {
    //        if (!settings.contains(buildMenuKey (SUB_SECTION_LOCATION,widget, view)))
    //        {
    //            tempLocation = Qt::RightDockWidgetArea;
    //        }
    //    }
882

883
    if (tempWidget != NULL)
884
    {
885 886 887 888 889
        if (tempVisible)
        {
            addDockWidget(tempLocation, tempWidget);
            tempWidget->show();
        }
890 891
    }
}
892

893 894 895 896 897 898 899 900 901
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;

902 903 904 905 906
    return (QString::number(apType) + "_" +
            QString::number(SECTION_MENU) + "_" +
            QString::number(view) + "_" +
            QString::number(tool) + "_" +
            QString::number(section) + "_" );
907 908
}

909 910
void MainWindow::closeEvent(QCloseEvent *event)
{
911
    settings.setValue(getWindowGeometryKey(), saveGeometry());
912 913
    //settings.setValue("windowState", saveState());
    aboutToCloseFlag = true;
914 915 916 917 918 919
    // 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);
920 921 922
    settings.sync();
    QMainWindow::closeEvent(event);
}
923

924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946
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;
                }
            }
        }
    }
}
947

948 949
void MainWindow::updateVisibilitySettings (bool vis)
{
950
    if (!aboutToCloseFlag && !changingViewsFlag)
951 952 953 954 955 956
    {
        QDockWidget* temp = qobject_cast<QDockWidget *>(sender());

        if (temp)
        {
            QHashIterator<int, QWidget*> i(dockWidgets);
957 958
            while (i.hasNext())
            {
959
                i.next();
960 961
                if ((static_cast <QDockWidget *>(dockWidgets[i.key()])) == temp)
                {
962 963
                    QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.key()), currentView);
                    settings.setValue(chKey,vis);
964 965 966 967 968 969
                    toolsMenuActions[i.key()]->setChecked(vis);
                    break;
                }
            }
        }
    }
970 971
}

972 973 974
void MainWindow::updateLocationSettings (Qt::DockWidgetArea location)
{
    QDockWidget* temp = qobject_cast<QDockWidget *>(sender());
975

976 977 978 979 980 981 982 983 984 985 986
    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;
        }
    }
987 988
}

989 990 991
/**
 * Connect the signals and slots of the common window widgets
 */
992
void MainWindow::connectCommonWidgets()
993
{
pixhawk's avatar
pixhawk committed
994 995 996 997 998
    if (infoDockWidget && infoDockWidget->widget())
    {
        connect(mavlink, SIGNAL(receiveLossChanged(int, float)),
                infoDockWidget->widget(), SLOT(updateSendLoss(int, float)));
    }
999

pixhawk's avatar
pixhawk committed
1000 1001
    if (mapWidget && waypointsDockWidget->widget())
    {
1002

1003
    }
Alejandro's avatar
Alejandro committed
1004 1005 1006 1007 1008 1009

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

1012 1013
void MainWindow::createCustomWidget()
{
1014
    //qDebug() << "ADDING CUSTOM WIDGET";
lm's avatar
lm committed
1015 1016 1017 1018 1019 1020 1021 1022
    QGCToolWidget* tool = new QGCToolWidget("Unnamed Tool", this);

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

1023
    QDockWidget* dock = new QDockWidget("Unnamed Tool", this);
lm's avatar
lm committed
1024
    connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater()));
1025
    dock->setWidget(tool);
lm's avatar
lm committed
1026 1027 1028 1029 1030 1031
    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);
1032
    dock->setVisible(true);
1033 1034 1035 1036
}

void MainWindow::connectPxWidgets()
{
1037
    // No special connections necessary at this point
1038 1039 1040 1041
}

void MainWindow::connectSlugsWidgets()
{
1042
    if (slugsHilSimWidget && slugsHilSimWidget->widget()){
1043 1044
        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                slugsHilSimWidget->widget(), SLOT(activeUasSet(UASInterface*)));
1045 1046 1047
    }

    if (slugsDataWidget && slugsDataWidget->widget()){
1048 1049
        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                slugsDataWidget->widget(), SLOT(setActiveUAS(UASInterface*)));
1050 1051
    }

1052

1053 1054
}

1055
void MainWindow::arrangeCommonCenterStack()
1056
{
1057
    centerStack = new QStackedWidget(this);
1058
    centerStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1059

pixhawk's avatar
pixhawk committed
1060
    if (!centerStack) return;
1061

1062
    if (mapWidget && (centerStack->indexOf(mapWidget) == -1)) centerStack->addWidget(mapWidget);
lm's avatar
lm committed
1063
    if (dataplotWidget && (centerStack->indexOf(dataplotWidget) == -1)) centerStack->addWidget(dataplotWidget);
1064
    if (protocolWidget && (centerStack->indexOf(protocolWidget) == -1)) centerStack->addWidget(protocolWidget);
1065 1066 1067 1068 1069 1070 1071

    setCentralWidget(centerStack);
}

void MainWindow::arrangePxCenterStack()
{

1072 1073 1074 1075
    if (!centerStack) {
        qDebug() << "Center Stack not Created!";
        return;
    }
1076

1077 1078

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

1080
#ifdef QGC_OSG_ENABLED
1081
    if (_3DWidget && (centerStack->indexOf(_3DWidget) == -1)) centerStack->addWidget(_3DWidget);
1082
#endif
1083
#ifdef QGC_OSGEARTH_ENABLED
1084
    if (_3DMapWidget && (centerStack->indexOf(_3DMapWidget) == -1)) centerStack->addWidget(_3DMapWidget);
1085
#endif
1086
#if (defined _MSC_VER) | (defined Q_OS_MAC)
1087
    if (gEarthWidget && (centerStack->indexOf(gEarthWidget) == -1)) centerStack->addWidget(gEarthWidget);
1088
#endif
1089 1090
    if (hudWidget && (centerStack->indexOf(hudWidget) == -1)) centerStack->addWidget(hudWidget);
    if (dataplotWidget && (centerStack->indexOf(dataplotWidget) == -1)) centerStack->addWidget(dataplotWidget);
1091 1092 1093 1094 1095
}

void MainWindow::arrangeSlugsCenterStack()
{

1096 1097 1098 1099
    if (!centerStack) {
        qDebug() << "Center Stack not Created!";
        return;
    }
1100

1101 1102
    if (linechartWidget && (centerStack->indexOf(linechartWidget) == -1)) centerStack->addWidget(linechartWidget);
    if (hudWidget && (centerStack->indexOf(hudWidget) == -1)) centerStack->addWidget(hudWidget);
1103

1104 1105
}

1106 1107
void MainWindow::configureWindowName()
{
pixhawk's avatar
pixhawk committed
1108 1109 1110
    QList<QHostAddress> hostAddresses = QNetworkInterface::allAddresses();
    QString windowname = qApp->applicationName() + " " + qApp->applicationVersion();
    bool prevAddr = false;
1111

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

pixhawk's avatar
pixhawk committed
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
    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;
        }
    }
1124

pixhawk's avatar
pixhawk committed
1125
    windowname.append(")");
1126

pixhawk's avatar
pixhawk committed
1127
    setWindowTitle(windowname);
1128 1129

#ifndef Q_WS_MAC
pixhawk's avatar
pixhawk committed
1130
    //qApp->setWindowIcon(QIcon(":/core/images/qtcreator_logo_128.png"));
1131 1132 1133
#endif
}

pixhawk's avatar
pixhawk committed
1134
void MainWindow::startVideoCapture()
pixhawk's avatar
pixhawk committed
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145
{
    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);
1146 1147 1148
    //videoTimer->setInterval(40);
    //connect(videoTimer, SIGNAL(timeout()), this, SLOT(saveScreen()));
    //videoTimer->stop();
pixhawk's avatar
pixhawk committed
1149 1150
}

pixhawk's avatar
pixhawk committed
1151
void MainWindow::stopVideoCapture()
pixhawk's avatar
pixhawk committed
1152 1153 1154 1155 1156 1157
{
    videoTimer->stop();

    // TODO Convert raw images to PNG
}

pixhawk's avatar
pixhawk committed
1158
void MainWindow::saveScreen()
pixhawk's avatar
pixhawk committed
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168
{
    QPixmap window = QPixmap::grabWindow(this->winId());
    QString format = "bmp";

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

1169 1170 1171 1172 1173 1174
/**
 * 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
1175
void MainWindow::reloadStylesheet()
pixhawk's avatar
pixhawk committed
1176
{
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
    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
1194
    // Load style sheet
1195
    QFile* styleSheet = new QFile(fileName);
1196 1197 1198 1199
    if (!styleSheet->exists())
    {
        styleSheet = new QFile(":/images/style-mission.css");
    }
1200 1201
    if (styleSheet->open(QIODevice::ReadOnly | QIODevice::Text))
    {
1202 1203
        QString style = QString(styleSheet->readAll());
        style.replace("ICONDIR", QCoreApplication::applicationDirPath()+ "/images/");
pixhawk's avatar
pixhawk committed
1204
        qApp->setStyleSheet(style);
1205 1206 1207
    }
    else
    {
1208 1209 1210 1211 1212 1213 1214
        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
1215
    }
1216
    delete styleSheet;
pixhawk's avatar
pixhawk committed
1217 1218
}

1219 1220 1221 1222 1223 1224
/**
 * 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
1225
void MainWindow::showStatusMessage(const QString& status, int timeout)
pixhawk's avatar
pixhawk committed
1226
{
lm's avatar
lm committed
1227
    statusBar()->showMessage(status, timeout);
pixhawk's avatar
pixhawk committed
1228 1229
}

1230 1231 1232 1233 1234 1235
/**
 * 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
 */
1236
void MainWindow::showStatusMessage(const QString& status)
pixhawk's avatar
pixhawk committed
1237
{
lm's avatar
lm committed
1238
    statusBar()->showMessage(status, 20000);
1239 1240 1241 1242
}

void MainWindow::showCriticalMessage(const QString& title, const QString& message)
{
1243
    QMessageBox msgBox(this);
1244 1245 1246 1247 1248 1249
    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
1250 1251
}

lm's avatar
lm committed
1252 1253
void MainWindow::showInfoMessage(const QString& title, const QString& message)
{
1254
    QMessageBox msgBox(this);
lm's avatar
lm committed
1255 1256 1257 1258 1259 1260 1261 1262
    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
1263 1264 1265 1266
/**
* @brief Create all actions associated to the main window
*
**/
1267
void MainWindow::connectCommonActions()
pixhawk's avatar
pixhawk committed
1268 1269 1270 1271 1272 1273
{
    // 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*)));
1274
    connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
pixhawk's avatar
pixhawk committed
1275

1276
    // Unmanned System controls
pixhawk's avatar
pixhawk committed
1277 1278 1279 1280 1281 1282 1283
    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()));

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

1290 1291
    connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView()));
    connect(ui.actionReloadStyle, SIGNAL(triggered()), this, SLOT(reloadStylesheet()));
1292

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

    // Custom widget actions
    connect(ui.actionNewCustomWidget, SIGNAL(triggered()), this, SLOT(createCustomWidget()));
1300 1301 1302 1303

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

    // 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()));
1313 1314 1315 1316 1317 1318 1319 1320 1321 1322
}

void MainWindow::connectPxActions()
{


}

void MainWindow::connectSlugsActions()
{
1323

pixhawk's avatar
pixhawk committed
1324 1325
}

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

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

1386
    LinkManager::instance()->add(link);
pixhawk's avatar
pixhawk committed
1387 1388
    LinkManager::instance()->addProtocol(link, mavlink);

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

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

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

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

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);
}

pixhawk's avatar
pixhawk committed
1428
void MainWindow::UASCreated(UASInterface* uas)
pixhawk's avatar
pixhawk committed
1429
{
1430

pixhawk's avatar
pixhawk committed
1431 1432
    // Connect the UAS to the full user interface

1433 1434
    if (uas != NULL)
    {
1435 1436 1437 1438
        // Set default settings
        setDefaultSettingsForAp();

        // The pilot, operator and engineer views were not available on startup, enable them now
1439
        ui.actionPilotsView->setEnabled(true);
1440 1441
        ui.actionOperatorsView->setEnabled(true);
        ui.actionEngineersView->setEnabled(true);
1442

1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469
        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;
        }

1470 1471 1472 1473 1474
        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()));

        ui.menuConnected_Systems->addAction(uasAction);
1475 1476

        // FIXME Should be not inside the mainwindow
1477 1478
        if (debugConsoleDockWidget)
        {
pixhawk's avatar
pixhawk committed
1479 1480 1481 1482 1483 1484
            DebugConsole *debugConsole = dynamic_cast<DebugConsole*>(debugConsoleDockWidget->widget());
            if (debugConsole)
            {
                connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)),
                        debugConsole, SLOT(receiveTextMessage(int,int,int,QString)));
            }
1485
        }
1486 1487

        // Health / System status indicator
1488 1489
        if (infoDockWidget)
        {
pixhawk's avatar
pixhawk committed
1490 1491 1492 1493 1494
            UASInfoWidget *infoWidget = dynamic_cast<UASInfoWidget*>(infoDockWidget->widget());
            if (infoWidget)
            {
                infoWidget->addUAS(uas);
            }
1495
        }
1496 1497

        // UAS List
1498 1499
        if (listDockWidget)
        {
pixhawk's avatar
pixhawk committed
1500 1501 1502 1503 1504
            UASListWidget *listWidget = dynamic_cast<UASListWidget*>(listDockWidget->widget());
            if (listWidget)
            {
                listWidget->addUAS(uas);
            }
1505
        }
1506

1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534
        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();
                //                }
                //              }
                //            }
1535

1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561
            }
            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
1562
        if (UASManager::instance()->getUASList().size() == 1)
1563
        {
1564
            //qDebug() << "UPDATING THE VIEW SINCE THIS IS THE FIRST CONNECTED SYSTEM";
1565 1566

            // Load last view if setting is present
1567
            if (settings.contains("CURRENT_VIEW_WITH_UAS_CONNECTED"))
1568
            {
1569
                clearView();
1570
                int view = settings.value("CURRENT_VIEW_WITH_UAS_CONNECTED").toInt();
1571
                switch (view)
1572
                {
1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588
                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;
1589
                }
1590 1591 1592
            }
            else
            {
1593
                loadOperatorView();
1594
            }
1595
        }
1596

1597
    }
1598 1599

    if (!ui.menuConnected_Systems->isEnabled()) ui.menuConnected_Systems->setEnabled(true);
lm's avatar
lm committed
1600 1601 1602

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

1605 1606 1607
/**
 * Clears the current view completely
 */
pixhawk's avatar
pixhawk committed
1608
void MainWindow::clearView()
1609
{
1610
    // Save current state
1611
    if (UASManager::instance()->getUASList().count() > 0) settings.setValue(getWindowStateKey(), saveState(QGC::applicationVersion()));
1612
    settings.setValue(getWindowGeometryKey(), saveGeometry());
1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623

    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)
        {
1624
            qDebug() << "TOOL:" << chKey << "IS:" << temp->isChecked();
1625 1626 1627 1628
            settings.setValue(chKey,temp->isChecked());
        }
        else
        {
1629
            qDebug() << "TOOL:" << chKey << "IS DEFAULT AND UNCHECKED";
1630 1631 1632 1633
            settings.setValue(chKey,false);
        }
    }

1634
    changingViewsFlag = true;
1635 1636
    // Remove all dock widgets from main window
    QObjectList childList( this->children() );
pixhawk's avatar
pixhawk committed
1637

1638 1639 1640
    QObjectList::iterator i;
    QDockWidget* dockWidget;
    for (i = childList.begin(); i != childList.end(); ++i)
pixhawk's avatar
pixhawk committed
1641
    {
1642 1643
        dockWidget = dynamic_cast<QDockWidget*>(*i);
        if (dockWidget)
pixhawk's avatar
pixhawk committed
1644
        {
1645
            // Remove dock widget from main window
1646 1647
            removeDockWidget(dockWidget);
            //dockWidget->setVisible(false);
pixhawk's avatar
pixhawk committed
1648 1649
        }
    }
1650
    changingViewsFlag = false;
pixhawk's avatar
pixhawk committed
1651 1652
}

1653
void MainWindow::loadEngineerView()
lm's avatar
lm committed
1654
{
1655 1656
    if (currentView != VIEW_ENGINEER)
    {
1657 1658 1659 1660
        clearView();
        currentView = VIEW_ENGINEER;
        ui.actionEngineersView->setChecked(true);
        presentView();
1661
    }
lm's avatar
lm committed
1662 1663
}

1664
void MainWindow::loadOperatorView()
lm's avatar
lm committed
1665
{
1666 1667
    if (currentView != VIEW_OPERATOR)
    {
1668 1669 1670 1671 1672 1673
        clearView();
        currentView = VIEW_OPERATOR;
        ui.actionOperatorsView->setChecked(true);
        presentView();
    }
}
lm's avatar
lm committed
1674

1675 1676 1677 1678 1679 1680 1681 1682
void MainWindow::loadUnconnectedView()
{
    if (currentView != VIEW_UNCONNECTED)
    {
        clearView();
        currentView = VIEW_UNCONNECTED;
        ui.actionUnconnectedView->setChecked(true);
        presentView();
1683
    }
lm's avatar
lm committed
1684 1685
}

1686
void MainWindow::loadPilotView()
1687
{
1688 1689
    if (currentView != VIEW_PILOT)
    {
1690 1691 1692 1693
        clearView();
        currentView = VIEW_PILOT;
        ui.actionPilotsView->setChecked(true);
        presentView();
1694
    }
1695 1696
}

1697
void MainWindow::loadMAVLinkView()
1698
{
1699 1700
    if (currentView != VIEW_MAVLINK)
    {
1701 1702 1703 1704
        clearView();
        currentView = VIEW_MAVLINK;
        ui.actionMavlinkView->setChecked(true);
        presentView();
1705
    }
1706 1707
}

lm's avatar
lm committed
1708 1709
void MainWindow::presentView()
{
1710
    // LINE CHART
1711
    showTheCentralWidget(CENTRAL_LINECHART, currentView);
1712

1713 1714
    // MAP
    showTheCentralWidget(CENTRAL_MAP, currentView);
pixhawk's avatar
pixhawk committed
1715

1716 1717
    // PROTOCOL
    showTheCentralWidget(CENTRAL_PROTOCOL, currentView);
pixhawk's avatar
pixhawk committed
1718

1719 1720
    // HEAD UP DISPLAY
    showTheCentralWidget(CENTRAL_HUD, currentView);
pixhawk's avatar
pixhawk committed
1721 1722 1723 1724 1725 1726 1727 1728 1729 1730

    // GOOGLE EARTH
    showTheCentralWidget(CENTRAL_GOOGLE_EARTH, currentView);

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

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

1731 1732 1733
    // DATA PLOT
    showTheCentralWidget(CENTRAL_DATA_PLOT, currentView);

pixhawk's avatar
pixhawk committed
1734

1735
    // Show docked widgets based on current view and autopilot type
1736

1737 1738
    // UAS CONTROL
    showTheWidget(MENU_UAS_CONTROL, currentView);
1739

1740 1741
    // UAS LIST
    showTheWidget(MENU_UAS_LIST, currentView);
1742

1743 1744
    // WAYPOINT LIST
    showTheWidget(MENU_WAYPOINTS, currentView);
pixhawk's avatar
pixhawk committed
1745

1746 1747
    // UAS STATUS
    showTheWidget(MENU_STATUS, currentView);
1748

1749 1750
    // DETECTION
    showTheWidget(MENU_DETECTION, currentView);
1751

1752 1753
    // DEBUG CONSOLE
    showTheWidget(MENU_DEBUG_CONSOLE, currentView);
1754

1755 1756
    // ONBOARD PARAMETERS
    showTheWidget(MENU_PARAMETERS, currentView);
1757

1758 1759
    // WATCHDOG
    showTheWidget(MENU_WATCHDOG, currentView);
1760

1761 1762 1763 1764 1765
    // HUD
    showTheWidget(MENU_HUD, currentView);
    if (headUpDockWidget)
    {
        HUD* tmpHud = dynamic_cast<HUD*>( headUpDockWidget->widget() );
1766 1767 1768 1769
        if (tmpHud)
        {
            if (settings.value(buildMenuKey (SUB_SECTION_CHECKED,MENU_HUD,currentView)).toBool())
            {
1770
                addDockWidget(static_cast <Qt::DockWidgetArea>(settings.value(buildMenuKey (SUB_SECTION_LOCATION,MENU_HUD, currentView)).toInt()),
1771
                        headUpDockWidget);
1772
                headUpDockWidget->show();
1773 1774 1775
            }
            else
            {
1776 1777
                headUpDockWidget->hide();
            }
1778
        }
1779
    }
1780

1781

1782 1783
    // RC View
    showTheWidget(MENU_RC_VIEW, currentView);
1784

1785 1786
    // SLUGS DATA
    showTheWidget(MENU_SLUGS_DATA, currentView);
1787

1788 1789
    // SLUGS PID
    showTheWidget(MENU_SLUGS_PID, currentView);
1790

1791 1792
    // SLUGS HIL
    showTheWidget(MENU_SLUGS_HIL, currentView);
1793

1794 1795
    // SLUGS CAMERA
    showTheWidget(MENU_SLUGS_CAMERA, currentView);
1796

1797 1798
    // HORIZONTAL SITUATION INDICATOR
    showTheWidget(MENU_HSI, currentView);
1799

1800 1801 1802 1803 1804
    // HEAD DOWN 1
    showTheWidget(MENU_HDD_1, currentView);

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

1806 1807 1808
    // MAVLINK LOG PLAYER
    showTheWidget(MENU_MAVLINK_LOG_PLAYER, currentView);

1809 1810 1811 1812 1813 1814
    // VIDEO 1
    showTheWidget(MENU_VIDEO_STREAM_1, currentView);

    // VIDEO 2
    showTheWidget(MENU_VIDEO_STREAM_2, currentView);

1815
    this->show();
1816

1817
    // Restore window state
1818 1819 1820
    if (UASManager::instance()->getUASList().count() > 0)
    {
        // Restore the mainwindow size
1821 1822 1823 1824
        if (settings.contains(getWindowGeometryKey()))
        {
            restoreGeometry(settings.value(getWindowGeometryKey()).toByteArray());
        }
1825 1826 1827 1828 1829 1830 1831

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

1834 1835 1836 1837
void MainWindow::showTheCentralWidget (TOOLS_WIDGET_NAMES centralWidget, VIEW_SECTIONS view)
{
    bool tempVisible;
    QWidget* tempWidget = dockWidgets[centralWidget];
1838

1839 1840
    tempVisible =  settings.value(buildMenuKey(SUB_SECTION_CHECKED,centralWidget,view), false).toBool();
    qDebug() << buildMenuKey (SUB_SECTION_CHECKED,centralWidget,view) << tempVisible;
1841
    if (toolsMenuActions[centralWidget])
1842
    {
1843
        qDebug() << "SETTING TO:" << tempVisible;
1844
        toolsMenuActions[centralWidget]->setChecked(tempVisible);
1845
    }
1846

1847
    if (centerStack && tempWidget && tempVisible)
1848
    {
1849
        qDebug() << "ACTIVATING MAIN WIDGET";
1850
        centerStack->setCurrentWidget(tempWidget);
1851
    }
1852 1853
}

1854 1855
void MainWindow::loadDataView(QString fileName)
{
1856
    clearView();
1857 1858 1859 1860 1861

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

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

1866
    presentView();
1867

1868 1869
    // Plot is now selected, now load data from file
    if (dataplotWidget)
1870
    {
1871
        dataplotWidget->loadFile(fileName);
1872
        }
1873 1874 1875 1876 1877 1878 1879
//        QStackedWidget *centerStack = dynamic_cast<QStackedWidget*>(centralWidget());
//        if (centerStack)
//        {
//            centerStack->setCurrentWidget(dataplotWidget);
//            dataplotWidget->loadFile(fileName);
//        }
//    }
1880 1881 1882
}