Skip to content
Snippets Groups Projects
MainWindow.cc 65.4 KiB
Newer Older
  • Learn to ignore specific revisions
  •     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;
            }
        }
    
        windowname.append(")");
    
        setWindowTitle(windowname);
    }
    
    void MainWindow::startVideoCapture()
    {
        QString format = "bmp";
        QString initialPath = QDir::currentPath() + tr("/untitled.") + format;
    
    
        QString screenFileName = QGCFileDialog::getSaveFileName(this, tr("Save As"),
    
                                                              initialPath,
                                                              tr("%1 Files (*.%2);;All Files (*)")
                                                              .arg(format.toUpper())
                                                              .arg(format));
        delete videoTimer;
        videoTimer = new QTimer(this);
    }
    
    void MainWindow::stopVideoCapture()
    {
        videoTimer->stop();
    
        // TODO Convert raw images to PNG
    }
    
    void MainWindow::saveScreen()
    {
        QPixmap window = QPixmap::grabWindow(this->winId());
        QString format = "bmp";
    
        if (!screenFileName.isEmpty())
        {
    
            window.save(screenFileName, format.toLatin1());
    
    void MainWindow::enableDockWidgetTitleBars(bool enabled)
    {
    
        menuActionHelper->setDockWidgetTitleBarsEnabled(enabled);
    
        QSettings settings;
        settings.beginGroup("QGC_MAINWINDOW");
    
        settings.setValue("DOCK_WIDGET_TITLEBARS",enabled);
    
    
    void MainWindow::enableAutoReconnect(bool enabled)
    {
        autoReconnect = enabled;
    }
    
    
    bool MainWindow::loadStyle(QGC_MAINWINDOW_STYLE style)
    
        qDebug() << "LOAD STYLE" << style;
    
        bool success = true;
        QString styles;
        
        // Signal to the user that the app will pause to apply a new stylesheet
        qApp->setOverrideCursor(Qt::WaitCursor);
        
    
        // Store the new style classification.
        currentStyle = style;
    
        
        // The dark style sheet is the master. Any other selected style sheet just overrides
        // the colors of the master sheet.
    
        QFile masterStyleSheet(defaultDarkStyle);
    
        if (masterStyleSheet.open(QIODevice::ReadOnly | QIODevice::Text)) {
            styles = masterStyleSheet.readAll();
        } else {
    
            qDebug() << "Unable to load master dark style sheet";
    
            success = false;
        }
    
        if (success && style == QGC_MAINWINDOW_STYLE_LIGHT) {
            qDebug() << "LOADING LIGHT";
            // Load the slave light stylesheet.
            QFile styleSheet(defaultLightStyle);
            if (styleSheet.open(QIODevice::ReadOnly | QIODevice::Text)) {
    
                styles += styleSheet.readAll();
            } else {
    
                qDebug() << "Unable to load slave light sheet:";
    
                success = false;
    
        if (!styles.isEmpty()) {
            qApp->setStyleSheet(styles);
            emit styleChanged(style);
        }
        
    
        // Finally restore the cursor before returning.
        qApp->restoreOverrideCursor();
        
        return success;
    
    }
    
    /**
     * 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
     */
    void MainWindow::showStatusMessage(const QString& status, int timeout)
    {
        statusBar()->showMessage(status, timeout);
    }
    
    /**
     * 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
     */
    void MainWindow::showStatusMessage(const QString& status)
    {
        statusBar()->showMessage(status, 20000);
    }
    
    void MainWindow::showCriticalMessage(const QString& title, const QString& message)
    {
    
    Don Gagne's avatar
    Don Gagne committed
        _hideSplashScreen();
        qDebug() << "Critical" << title << message;
    
    Don Gagne's avatar
    Don Gagne committed
        QGCMessageBox::critical(title, message);
    
    }
    
    void MainWindow::showInfoMessage(const QString& title, const QString& message)
    {
    
    Don Gagne's avatar
    Don Gagne committed
        _hideSplashScreen();
        qDebug() << "Information" << title << message;
    
    Don Gagne's avatar
    Don Gagne committed
        QGCMessageBox::information(title, message);
    
    }
    
    /**
    * @brief Create all actions associated to the main window
    *
    **/
    void MainWindow::connectCommonActions()
    {
        // Bind together the perspective actions
        QActionGroup* perspectives = new QActionGroup(ui.menuPerspectives);
        perspectives->addAction(ui.actionEngineersView);
    
        perspectives->addAction(ui.actionFlightView);
    
        perspectives->addAction(ui.actionSimulationView);
    
        perspectives->addAction(ui.actionMissionView);
    
        perspectives->addAction(ui.actionSetup);
    
        perspectives->addAction(ui.actionTerminalView);
    
    Lorenz Meier's avatar
    Lorenz Meier committed
        perspectives->addAction(ui.actionGoogleEarthView);
        perspectives->addAction(ui.actionLocal3DView);
    
        perspectives->setExclusive(true);
    
    
        /* Hide the actions that are not relevant */
    
    #ifndef QGC_GOOGLE_EARTH_ENABLED
        ui.actionGoogleEarthView->setVisible(false);
    #endif
    #ifndef QGC_OSG_ENABLED
        ui.actionLocal3DView->setVisible(false);
    #endif
    
    
        // Mark the right one as selected
    
        if (currentView == VIEW_ENGINEER)
        {
            ui.actionEngineersView->setChecked(true);
            ui.actionEngineersView->activate(QAction::Trigger);
        }
        if (currentView == VIEW_FLIGHT)
        {
            ui.actionFlightView->setChecked(true);
            ui.actionFlightView->activate(QAction::Trigger);
        }
        if (currentView == VIEW_SIMULATION)
        {
    
            ui.actionSimulationView->setChecked(true);
            ui.actionSimulationView->activate(QAction::Trigger);
    
        }
        if (currentView == VIEW_MISSION)
        {
            ui.actionMissionView->setChecked(true);
            ui.actionMissionView->activate(QAction::Trigger);
        }
    
        if (currentView == VIEW_SETUP)
    
            ui.actionSetup->setChecked(true);
            ui.actionSetup->activate(QAction::Trigger);
    
            ui.actionSoftwareConfig->setChecked(true);
            ui.actionSoftwareConfig->activate(QAction::Trigger);
    
        if (currentView == VIEW_TERMINAL)
        {
            ui.actionTerminalView->setChecked(true);
            ui.actionTerminalView->activate(QAction::Trigger);
        }
    
        if (currentView == VIEW_GOOGLEEARTH)
        {
            ui.actionGoogleEarthView->setChecked(true);
            ui.actionGoogleEarthView->activate(QAction::Trigger);
        }
        if (currentView == VIEW_LOCAL3D)
        {
            ui.actionLocal3DView->setChecked(true);
            ui.actionLocal3DView->activate(QAction::Trigger);
        }
    
    
        // 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);
    
        // Connect actions from ui
        connect(ui.actionAdd_Link, SIGNAL(triggered()), this, SLOT(addLink()));
    
        ui.actionAdvanced_Mode->setChecked(menuActionHelper->isAdvancedMode());
        connect(ui.actionAdvanced_Mode,SIGNAL(toggled(bool)),this,SLOT(setAdvancedMode(bool)));
    
    
        // Connect internal actions
        connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(UASCreated(UASInterface*)));
        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
    
        // Unmanned System controls
        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.actionShutdownMAV, SIGNAL(triggered()), UASManager::instance(), SLOT(shutdownActiveUAS()));
    
        // Views actions
    
        connect(ui.actionFlightView, SIGNAL(triggered()), this, SLOT(loadPilotView()));
    
        connect(ui.actionSimulationView, SIGNAL(triggered()), this, SLOT(loadSimulationView()));
    
        connect(ui.actionEngineersView, SIGNAL(triggered()), this, SLOT(loadEngineerView()));
    
        connect(ui.actionMissionView, SIGNAL(triggered()), this, SLOT(loadOperatorView()));
    
        connect(ui.actionSetup,SIGNAL(triggered()),this,SLOT(loadSetupView()));
    
        connect(ui.actionGoogleEarthView, SIGNAL(triggered()), this, SLOT(loadGoogleEarthView()));
        connect(ui.actionLocal3DView, SIGNAL(triggered()), this, SLOT(loadLocal3DView()));
    
        connect(ui.actionSoftwareConfig,SIGNAL(triggered()),this,SLOT(loadSoftwareConfigView()));
        connect(ui.actionTerminalView,SIGNAL(triggered()),this,SLOT(loadTerminalView()));
    
    
        // Help Actions
        connect(ui.actionOnline_Documentation, SIGNAL(triggered()), this, SLOT(showHelp()));
        connect(ui.actionDeveloper_Credits, SIGNAL(triggered()), this, SLOT(showCredits()));
        connect(ui.actionProject_Roadmap_2, SIGNAL(triggered()), this, SLOT(showRoadMap()));
    
        // Custom widget actions
        connect(ui.actionNewCustomWidget, SIGNAL(triggered()), this, SLOT(createCustomWidget()));
        connect(ui.actionLoadCustomWidgetFile, SIGNAL(triggered()), this, SLOT(loadCustomWidget()));
    
        // Audio output
        ui.actionMuteAudioOutput->setChecked(GAudioOutput::instance()->isMuted());
        connect(GAudioOutput::instance(), SIGNAL(mutedChanged(bool)), ui.actionMuteAudioOutput, SLOT(setChecked(bool)));
        connect(ui.actionMuteAudioOutput, SIGNAL(triggered(bool)), GAudioOutput::instance(), SLOT(mute(bool)));
    
        // 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);
    
        // Application Settings
        connect(ui.actionSettings, SIGNAL(triggered()), this, SLOT(showSettings()));
    
    
        connect(ui.actionSimulate, SIGNAL(triggered(bool)), this, SLOT(simulateLink(bool)));
    
    Don Gagne's avatar
    Don Gagne committed
    void MainWindow::_openUrl(const QString& url, const QString& errorMessage)
    
    Don Gagne's avatar
    Don Gagne committed
        if(!QDesktopServices::openUrl(QUrl(url))) {
            QMessageBox::critical(this,
                                  tr("Could not open information in browser"),
                                  errorMessage);
    
    Don Gagne's avatar
    Don Gagne committed
    void MainWindow::showHelp()
    {
        _openUrl("http://qgroundcontrol.org/users/start",
                 tr("To get to the online help, please open http://qgroundcontrol.org/user_guide in a browser."));
    }
    
    
    void MainWindow::showCredits()
    {
    
    Don Gagne's avatar
    Don Gagne committed
        _openUrl("http://qgroundcontrol.org/credits",
                 tr("To get to the credits, please open http://qgroundcontrol.org/credits in a browser."));
    
    Don Gagne's avatar
    Don Gagne committed
        _openUrl("http://qgroundcontrol.org/dev/roadmap",
                 tr("To get to the online help, please open http://qgroundcontrol.org/roadmap in a browser."));
    
    Don Gagne's avatar
    Don Gagne committed
        SettingsDialog settings(joystick, this);
        settings.exec();
    
    LinkInterface* MainWindow::addLink()
    
    {
        SerialLink* link = new SerialLink();
        // TODO This should be only done in the dialog itself
    
        LinkManager::instance()->add(link);
        LinkManager::instance()->addProtocol(link, mavlink);
    
        // Go fishing for this link's configuration window
        QList<QAction*> actions = ui.menuNetwork->actions();
    
    
        const int32_t& linkIndex(LinkManager::instance()->getLinks().indexOf(link));
        const int32_t& linkID(LinkManager::instance()->getLinks()[linkIndex]->getId());
    
    
        foreach (QAction* act, actions)
        {
            if (act->data().toInt() == linkID)
    
    
    bool MainWindow::configLink(LinkInterface *link)
    {
        // Go searching for this link's configuration window
        QList<QAction*> actions = ui.menuNetwork->actions();
    
        bool found(false);
    
        const int32_t& linkIndex(LinkManager::instance()->getLinks().indexOf(link));
        const int32_t& linkID(LinkManager::instance()->getLinks()[linkIndex]->getId());
    
        foreach (QAction* action, actions)
        {
            if (action->data().toInt() == linkID)
    
                found = true;
                action->trigger(); // Show the Link Config Dialog
            }
        }
    
        return found;
    }
    
    
    void MainWindow::addLink(LinkInterface *link)
    {
        // IMPORTANT! KEEP THESE TWO LINES
        // THEY MAKE SURE THE LINK IS PROPERLY REGISTERED
        // BEFORE LINKING THE UI AGAINST IT
        // Register (does nothing if already registered)
        LinkManager::instance()->add(link);
        LinkManager::instance()->addProtocol(link, mavlink);
    
        // Go fishing for this link's configuration window
        QList<QAction*> actions = ui.menuNetwork->actions();
    
        bool found(false);
    
    
        const int32_t& linkIndex(LinkManager::instance()->getLinks().indexOf(link));
        const int32_t& linkID(LinkManager::instance()->getLinks()[linkIndex]->getId());
    
    
        foreach (QAction* act, actions)
        {
            if (act->data().toInt() == linkID)
    
            CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, this);
    
            commsWidgetList.append(commWidget);
            connect(commWidget,SIGNAL(destroyed(QObject*)),this,SLOT(commsWidgetDestroyed(QObject*)));
    
            QAction* action = commWidget->getAction();
            ui.menuNetwork->addAction(action);
    
            // Error handling
            connect(link, SIGNAL(communicationError(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection);
        }
    }
    
    void MainWindow::simulateLink(bool simulate) {
    
    Don Gagne's avatar
    Don Gagne committed
        if (simulate) {
            if (!simulationLink) {
                simulationLink = new MAVLinkSimulationLink(":/demo-log.txt");
                Q_CHECK_PTR(simulationLink);
            }
            LinkManager::instance()->connectLink(simulationLink);
        } else {
            Q_ASSERT(simulationLink);
            LinkManager::instance()->disconnectLink(simulationLink);
        }
    
    void MainWindow::commsWidgetDestroyed(QObject *obj)
    {
    
        // Do not dynamic cast or de-reference QObject, since object is either in destructor or may have already
        // been destroyed.
    
    
        if (commsWidgetList.contains(obj))
        {
            commsWidgetList.removeOne(obj);
        }
    }
    
    
    void MainWindow::setActiveUAS(UASInterface* uas)
    {
    
        Q_UNUSED(uas);
    
        if (settings.contains(getWindowStateKey()))
        {
            SubMainWindow *win = qobject_cast<SubMainWindow*>(centerStack->currentWidget());
    
            win->restoreState(settings.value(getWindowStateKey()).toByteArray());
    
    }
    
    void MainWindow::UASSpecsChanged(int uas)
    {
    
        Q_UNUSED(uas);
        // TODO: Update UAS properties if its specs change
    
    }
    
    void MainWindow::UASCreated(UASInterface* uas)
    {
    
        // The pilot, operator and engineer views were not available on startup, enable them now
        ui.actionFlightView->setEnabled(true);
        ui.actionMissionView->setEnabled(true);
        ui.actionEngineersView->setEnabled(true);
        // 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);
    
        QIcon icon;
        // Set matching icon
        switch (uas->getSystemType())
        {
        case MAV_TYPE_GENERIC:
            icon = QIcon(":files/images/mavs/generic.svg");
            break;
        case MAV_TYPE_FIXED_WING:
            icon = QIcon(":files/images/mavs/fixed-wing.svg");
            break;
        case MAV_TYPE_QUADROTOR:
            icon = QIcon(":files/images/mavs/quadrotor.svg");
            break;
        case MAV_TYPE_COAXIAL:
            icon = QIcon(":files/images/mavs/coaxial.svg");
            break;
        case MAV_TYPE_HELICOPTER:
            icon = QIcon(":files/images/mavs/helicopter.svg");
            break;
        case MAV_TYPE_ANTENNA_TRACKER:
            icon = QIcon(":files/images/mavs/antenna-tracker.svg");
            break;
        case MAV_TYPE_GCS:
            icon = QIcon(":files/images/mavs/groundstation.svg");
            break;
        case MAV_TYPE_AIRSHIP:
            icon = QIcon(":files/images/mavs/airship.svg");
            break;
        case MAV_TYPE_FREE_BALLOON:
            icon = QIcon(":files/images/mavs/free-balloon.svg");
            break;
        case MAV_TYPE_ROCKET:
            icon = QIcon(":files/images/mavs/rocket.svg");
            break;
        case MAV_TYPE_GROUND_ROVER:
            icon = QIcon(":files/images/mavs/ground-rover.svg");
            break;
        case MAV_TYPE_SURFACE_BOAT:
            icon = QIcon(":files/images/mavs/surface-boat.svg");
            break;
        case MAV_TYPE_SUBMARINE:
            icon = QIcon(":files/images/mavs/submarine.svg");
            break;
        case MAV_TYPE_HEXAROTOR:
            icon = QIcon(":files/images/mavs/hexarotor.svg");
            break;
        case MAV_TYPE_OCTOROTOR:
            icon = QIcon(":files/images/mavs/octorotor.svg");
            break;
        case MAV_TYPE_TRICOPTER:
            icon = QIcon(":files/images/mavs/tricopter.svg");
            break;
        case MAV_TYPE_FLAPPING_WING:
            icon = QIcon(":files/images/mavs/flapping-wing.svg");
            break;
        case MAV_TYPE_KITE:
            icon = QIcon(":files/images/mavs/kite.svg");
            break;
        default:
            icon = QIcon(":files/images/mavs/unknown.svg");
            break;
        }
    
        connect(uas, SIGNAL(systemSpecsChanged(int)), this, SLOT(UASSpecsChanged(int)));
    
    John Tapsell's avatar
    John Tapsell committed
        connect(uas, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), this, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)));
    
        connect(uas, SIGNAL(misconfigurationDetected(UASInterface*)), this, SLOT(handleMisconfiguration(UASInterface*)));
    
        if (!linechartWidget)
        {
            linechartWidget = new Linecharts(this);
        }
    
        linechartWidget->addSource(mavlinkDecoder);
        if (engineeringView->centralWidget() != linechartWidget)
        {
            engineeringView->setCentralWidget(linechartWidget);
            linechartWidget->show();
        }
    
        // Load default custom widgets for this autopilot type
        loadCustomWidgetsFromDefaults(uas->getSystemTypeName(), uas->getAutopilotTypeName());
    
    
        // Reload view state in case new widgets were added
        loadViewState();
    }
    
    void MainWindow::UASDeleted(UASInterface* uas)
    {
    
        Q_UNUSED(uas);
    
        // TODO: Update the UI when a UAS is deleted
    
    }
    
    /**
     * Stores the current view state
     */
    void MainWindow::storeViewState()
    {
        if (!aboutToCloseFlag)
        {
            // Save current state
    
            SubMainWindow *win = qobject_cast<SubMainWindow*>(centerStack->currentWidget());
            QList<QDockWidget*> widgets = win->findChildren<QDockWidget*>();
            QString widgetnames = "";
            for (int i=0;i<widgets.size();i++)
            {
                widgetnames += widgets[i]->objectName() + ",";
            }
            widgetnames = widgetnames.mid(0,widgetnames.length()-1);
    
            settings.setValue(getWindowStateKey() + "WIDGETS",widgetnames);
    
            settings.setValue(getWindowStateKey(), win->saveState());
    
            settings.setValue(getWindowStateKey()+"CENTER_WIDGET", centerStack->currentIndex());
            // Although we want save the state of the window, we do not want to change the top-leve state (minimized, maximized, etc)
            // therefore this state is stored here and restored after applying the rest of the settings in the new
            // perspective.
            windowStateVal = this->windowState();
            settings.setValue(getWindowGeometryKey(), saveGeometry());
        }
    }
    
    void MainWindow::loadViewState()
    {
        // Restore center stack state
        int index = settings.value(getWindowStateKey()+"CENTER_WIDGET", -1).toInt();
    
        if (index != -1)
        {
            centerStack->setCurrentIndex(index);
        }
        else
        {
            // Hide custom widgets
            if (detectionDockWidget) detectionDockWidget->hide();
            if (watchdogControlDockWidget) watchdogControlDockWidget->hide();
    
            // Load defaults
            switch (currentView)
            {
    
            case VIEW_SETUP:
                centerStack->setCurrentWidget(setupView);
    
                if (softwareConfigView)
                    centerStack->setCurrentWidget(softwareConfigView);
    
                centerStack->setCurrentWidget(engineeringView);
    
                centerStack->setCurrentWidget(pilotView);
    
                centerStack->setCurrentWidget(plannerView);
    
                centerStack->setCurrentWidget(simView);
    
            case VIEW_TERMINAL:
                centerStack->setCurrentWidget(terminalView);
                break;
    
            case VIEW_GOOGLEEARTH:
                centerStack->setCurrentWidget(googleEarthView);
                break;
            case VIEW_LOCAL3D:
                centerStack->setCurrentWidget(local3DView);
                break;
    
            case VIEW_DEFAULT:
    
                if (controlDockWidget)
                {
                    controlDockWidget->hide();
                }
                if (listDockWidget)
                {
                    listDockWidget->show();
                }
    
                break;
            }
        }
    
        // Restore the widget positions and size
    
        if (settings.contains(getWindowStateKey() + "WIDGETS"))
        {
            QString widgetstr = settings.value(getWindowStateKey() + "WIDGETS").toString();
            QStringList split = widgetstr.split(",");
            foreach (QString widgetname,split)
            {
                if (widgetname != "")
                {
    
        if (settings.contains(getWindowStateKey()))
        {
    
            SubMainWindow *win = qobject_cast<SubMainWindow*>(centerStack->currentWidget());
    
            win->restoreState(settings.value(getWindowStateKey()).toByteArray());
    
    void MainWindow::setAdvancedMode(bool isAdvancedMode)
    
        menuActionHelper->setAdvancedMode(isAdvancedMode);
    
        ui.actionAdvanced_Mode->setChecked(isAdvancedMode);
        settings.setValue("ADVANCED_MODE",isAdvancedMode);
    
    void MainWindow::handleMisconfiguration(UASInterface* uas)
    {
        static QTime lastTime;
        
        // We have to debounce this signal
        if (!lastTime.isValid()) {
            lastTime.start();
        } else {
            if (lastTime.elapsed() < 10000) {
                lastTime.start();
                return;
            }
        }
    
    Don Gagne's avatar
    Don Gagne committed
        
        _hideSplashScreen();
        
    
        // Ask user if he wants to handle this now
    
    Don Gagne's avatar
    Don Gagne committed
        QMessageBox::StandardButton button = QGCMessageBox::question(tr("Missing or Invalid Onboard Configuration"),
                                                                        tr("The onboard system configuration is missing or incomplete. Do you want to resolve this now?"),
                                                                        QMessageBox::Ok | QMessageBox::Cancel,
                                                                        QMessageBox::Ok);
        if (button == QMessageBox::Ok) {
    
            // He wants to handle it, make sure this system is selected
            UASManager::instance()->setActiveUAS(uas);
    
            // Flick to config view
    
    void MainWindow::loadEngineerView()
    {
        if (currentView != VIEW_ENGINEER)
        {
            storeViewState();
            currentView = VIEW_ENGINEER;
            ui.actionEngineersView->setChecked(true);
            loadViewState();
        }
    }
    
    void MainWindow::loadOperatorView()
    {
    
            currentView = VIEW_MISSION;
            ui.actionMissionView->setChecked(true);
    
    void MainWindow::loadSetupView()
    
        if (currentView != VIEW_SETUP)
    
            currentView = VIEW_SETUP;
            ui.actionSetup->setChecked(true);
    
            loadViewState();
        }
    }
    
    void MainWindow::loadSoftwareConfigView()
    
            currentView = VIEW_SOFTWARE_CONFIG;
            ui.actionSoftwareConfig->setChecked(true);
    
    void MainWindow::loadTerminalView()
    {
        if (currentView != VIEW_TERMINAL)
        {
            storeViewState();
            currentView = VIEW_TERMINAL;
            ui.actionTerminalView->setChecked(true);
            loadViewState();
        }
    }
    
    
    void MainWindow::loadGoogleEarthView()
    {
        if (currentView != VIEW_GOOGLEEARTH)
        {
            storeViewState();
            currentView = VIEW_GOOGLEEARTH;
            ui.actionGoogleEarthView->setChecked(true);
            loadViewState();
        }
    }
    
    void MainWindow::loadLocal3DView()
    {
        if (currentView != VIEW_LOCAL3D)
        {
            storeViewState();
            currentView = VIEW_LOCAL3D;
            ui.actionLocal3DView->setChecked(true);
            loadViewState();
        }
    }
    
    void MainWindow::loadPilotView()
    {
    
            currentView = VIEW_FLIGHT;
            ui.actionFlightView->setChecked(true);
    
    void MainWindow::loadSimulationView()
    {
        if (currentView != VIEW_SIMULATION)
        {
            storeViewState();
            currentView = VIEW_SIMULATION;
    
            ui.actionSimulationView->setChecked(true);
    
    QList<QAction*> MainWindow::listLinkMenuActions()
    
    {
        return ui.menuNetwork->actions();
    }
    
    bool MainWindow::dockWidgetTitleBarsEnabled() const
    {
        return menuActionHelper->dockWidgetTitleBarsEnabled();
    }
    
    
    Don Gagne's avatar
    Don Gagne committed
    void MainWindow::_saveTempFlightDataLog(QString tempLogfile)
    {
        if (qgcApp()->promptFlightDataSave()) {
            _hideSplashScreen();
    
            QString saveFilename = QGCFileDialog::getSaveFileName(this,
    
    Don Gagne's avatar
    Don Gagne committed
                                                                tr("Select file to save Flight Data Log"),
                                                                qgcApp()->mavlinkLogFilesLocation(),
                                                                tr("Flight Data Log (*.mavlink)"));
            if (!saveFilename.isEmpty()) {
                QFile::copy(tempLogfile, saveFilename);
            }
        }
        QFile::remove(tempLogfile);
    }
    
    /// @brief Hides the spash screen if it is currently being shown
    void MainWindow::_hideSplashScreen(void)
    {
        if (_splashScreen) {
            _splashScreen->hide();
            _splashScreen = NULL;
        }
    }
    
    
    
    #ifdef QGC_MOUSE_ENABLED_LINUX
    
    bool MainWindow::x11Event(XEvent *event)
    {
        emit x11EventOccured(event);
    
    #endif // QGC_MOUSE_ENABLED_LINUX