Skip to content
Snippets Groups Projects
MainWindow.cc 67.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*===================================================================
    
    pixhawk's avatar
    pixhawk committed
    ======================================================================*/
    
    /**
     * @file
    
     *   @brief Implementation of class MainWindow
    
     *   @author Lorenz Meier <mail@qgroundcontrol.org>
    
    pixhawk's avatar
    pixhawk committed
     */
    
    #include <QSettings>
    #include <QDockWidget>
    #include <QNetworkInterface>
    #include <QMessageBox>
    #include <QDebug>
    #include <QTimer>
    #include <QHostInfo>
    
    #include "MG.h"
    
    #include "QGC.h"
    
    pixhawk's avatar
    pixhawk committed
    #include "MAVLinkSimulationLink.h"
    #include "SerialLink.h"
    #include "UDPLink.h"
    #include "MAVLinkProtocol.h"
    #include "CommConfigurationWindow.h"
    
    #include "QGCWaypointListMulti.h"
    
    pixhawk's avatar
    pixhawk committed
    #include "MainWindow.h"
    #include "JoystickWidget.h"
    
    pixhawk's avatar
    pixhawk committed
    #include "GAudioOutput.h"
    
    #include "QGCMapTool.h"
    
    #ifdef QGC_OSG_ENABLED
    
    #include "Q3DWidgetFactory.h"
    
    pixhawk's avatar
    pixhawk committed
    
    
    lm's avatar
    lm committed
    // FIXME Move
    #include "PxQuadMAV.h"
    #include "SlugsMAV.h"
    
    
    pixhawk's avatar
    pixhawk committed
    
    
    #include "LogCompressor.h"
    
    pixhawk's avatar
    pixhawk committed
    
    
    MainWindow* MainWindow::instance()
    {
    
        if(_instance == 0) {
    
            /* Set the application as parent to ensure that this object
    
                     * will be destroyed when the main application exits */
    
            //_instance->setParent(qApp);
        }
        return _instance;
    
    pixhawk's avatar
    pixhawk committed
    /**
    * 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()
    **/
    
        QMainWindow(parent),
        toolsMenuActions(),
        currentView(VIEW_UNCONNECTED),
        aboutToCloseFlag(false),
        changingViewsFlag(false),
        styleFileName(QCoreApplication::applicationDirPath() + "/style-indoor.css"),
        autoReconnect(false),
    
        currentStyle(QGC_MAINWINDOW_STYLE_INDOOR),
        lowPowerMode(false)
    
    pixhawk's avatar
    pixhawk committed
    {
    
        if (!settings.contains("CURRENT_VIEW")) {
    
            // Set this view as default view
            settings.setValue("CURRENT_VIEW", currentView);
    
            // 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) {
    
                currentView = currentViewCandidate;
    
        setDefaultSettingsForAp();
    
    pixhawk's avatar
    pixhawk committed
        // Setup user interface
        ui.setupUi(this);
    
    
    pixhawk's avatar
    pixhawk committed
    
    
        // Create actions
    
        // Set dock options
        setDockOptions(AnimatedDocks | AllowTabbedDocks | AllowNestedDocks);
    
    
        // Load mavlink view as default widget set
    
    lm's avatar
    lm committed
        statusBar()->setSizeGripEnabled(true);
    
    
        // Restore the window position and size
    
        if (settings.contains(getWindowGeometryKey())) {
    
            restoreGeometry(settings.value(getWindowGeometryKey()).toByteArray());
    
    pixhawk's avatar
    pixhawk committed
    
    
        // Populate link menu
        QList<LinkInterface*> links = LinkManager::instance()->getLinks();
    
        foreach(LinkInterface* link, links) {
    
        connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*)));
    
    
        // Connect user interface devices
    
        if (!joystick) {
    
            joystick = new JoystickInput();
        }
    
    
    lm's avatar
    lm committed
        // Enable and update view
        presentView();
    
        if (autoReconnect) {
    
            SerialLink* link = new SerialLink();
            // Add to registry
            LinkManager::instance()->add(link);
            LinkManager::instance()->addProtocol(link, mavlink);
            link->connect();
        }
    
        // Set low power mode
        enableLowPowerMode(lowPowerMode);
    
    
        // Initialize window state
        windowStateVal = windowState();
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    pixhawk's avatar
    pixhawk committed
    MainWindow::~MainWindow()
    
    pixhawk's avatar
    pixhawk committed
    {
    
        delete joystick;
    
        // Get and delete all dockwidgets and contained
        // widgets
        QObjectList childList( this->children() );
    
        QObjectList::iterator i;
        QDockWidget* dockWidget;
    
        for (i = childList.begin(); i != childList.end(); ++i) {
    
            dockWidget = dynamic_cast<QDockWidget*>(*i);
    
            if (dockWidget) {
    
                // Remove dock widget from main window
                removeDockWidget(dockWidget);
                delete dockWidget->widget();
                delete dockWidget;
            }
        }
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    /**
     * 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);
    
    
            // ENABLE UAS LIST
            settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_UAS_LIST, VIEW_UNCONNECTED), true);
            // ENABLE COMMUNICATION CONSOLE
            settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_DEBUG_CONSOLE, VIEW_UNCONNECTED), true);
    
        }
    
        // 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);
    
            // ENABLE HUD TOOL WIDGET
            settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_HUD,VIEW_OPERATOR), true);
    
            // ENABLE WAYPOINTS
            settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_WAYPOINTS,VIEW_OPERATOR), true);
    
        }
    
        // ENGINEER VIEW DEFAULT
        centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_LINECHART, VIEW_ENGINEER);
    
        if (!settings.contains(centralKey)) {
    
            settings.setValue(centralKey,true);
    
            // Enable Parameter widget
            settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_PARAMETERS,VIEW_ENGINEER), 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);
    
            // Enable Flight display
            settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_HDD_1,VIEW_PILOT), true);
    
    lm's avatar
    lm committed
    void MainWindow::resizeEvent(QResizeEvent * event)
    {
        Q_UNUSED(event);
    
        if (height() < 800) {
    
    lm's avatar
    lm committed
            ui.statusBar->setVisible(false);
    
    lm's avatar
    lm committed
            ui.statusBar->setVisible(true);
        }
    }
    
    
    QString MainWindow::getWindowStateKey()
    {
    
        return QString::number(currentView)+"_windowstate";
    
    }
    
    QString MainWindow::getWindowGeometryKey()
    {
    
        //return QString::number(currentView)+"_geometry";
        return "_geometry";
    
    lm's avatar
    lm committed
    void MainWindow::buildCustomWidget()
    {
        // Show custom widgets only if UAS is connected
    
        if (UASManager::instance()->getActiveUAS() != NULL) {
    
    lm's avatar
    lm committed
            // Enable custom widgets
            ui.actionNewCustomWidget->setEnabled(true);
    
            // Create custom widgets
            QList<QGCToolWidget*> widgets = QGCToolWidget::createWidgetsFromSettings(this);
    
    
            if (widgets.size() > 0) {
    
    lm's avatar
    lm committed
                ui.menuTools->addSeparator();
            }
    
    
            for(int i = 0; i < widgets.size(); ++i) {
    
    lm's avatar
    lm committed
                // Check if this widget already has a parent, do not create it in this case
    
                QGCToolWidget* tool = widgets.at(i);
                QDockWidget* dock = dynamic_cast<QDockWidget*>(tool->parentWidget());
    
                if (!dock) {
    
                    QDockWidget* dock = new QDockWidget(tool->windowTitle(), this);
                    dock->setObjectName(tool->objectName()+"_DOCK");
                    dock->setWidget(tool);
                    connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater()));
    
    lm's avatar
    lm committed
                    QAction* showAction = new QAction(widgets.at(i)->windowTitle(), this);
    
                    showAction->setCheckable(true);
    
    lm's avatar
    lm committed
                    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);
    
    
                    // Load visibility for view (default is off)
                    dock->setVisible(tool->isVisible(currentView));
    
                    // Load dock widget location (default is bottom)
                    Qt::DockWidgetArea location = static_cast <Qt::DockWidgetArea>(tool->getDockWidgetArea(currentView));
    
                    addDockWidget(location, dock);
    
    void MainWindow::buildCommonWidgets()
    {
        //TODO:  move protocol outside UI
        mavlink     = new MAVLinkProtocol();
    
        connect(mavlink, SIGNAL(protocolStatusMessage(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection);
    
        if (!controlDockWidget) {
    
            controlDockWidget = new QDockWidget(tr("Control"), this);
    
            controlDockWidget->setObjectName("UNMANNED_SYSTEM_CONTROL_DOCKWIDGET");
    
            controlDockWidget->setWidget( new UASControlWidget(this) );
    
            addToToolsMenu (controlDockWidget, tr("Control"), SLOT(showToolWidget(bool)), MENU_UAS_CONTROL, Qt::LeftDockWidgetArea);
    
        if (!listDockWidget) {
    
            listDockWidget = new QDockWidget(tr("Unmanned Systems"), this);
            listDockWidget->setWidget( new UASListWidget(this) );
    
            listDockWidget->setObjectName("UNMANNED_SYSTEMS_LIST_DOCKWIDGET");
    
            addToToolsMenu (listDockWidget, tr("Unmanned Systems"), SLOT(showToolWidget(bool)), MENU_UAS_LIST, Qt::RightDockWidgetArea);
    
        if (!waypointsDockWidget) {
    
            waypointsDockWidget = new QDockWidget(tr("Mission Plan"), this);
    
            waypointsDockWidget->setWidget( new QGCWaypointListMulti(this) );
    
            waypointsDockWidget->setObjectName("WAYPOINT_LIST_DOCKWIDGET");
    
            addToToolsMenu (waypointsDockWidget, tr("Mission Plan"), SLOT(showToolWidget(bool)), MENU_WAYPOINTS, Qt::BottomDockWidgetArea);
    
        if (!infoDockWidget) {
    
            infoDockWidget = new QDockWidget(tr("Status Details"), this);
            infoDockWidget->setWidget( new UASInfoWidget(this) );
    
    pixhawk's avatar
    pixhawk committed
            infoDockWidget->setObjectName("UAS_STATUS_DETAILS_DOCKWIDGET");
    
            addToToolsMenu (infoDockWidget, tr("Status Details"), SLOT(showToolWidget(bool)), MENU_STATUS, Qt::RightDockWidgetArea);
    
        if (!debugConsoleDockWidget) {
    
            debugConsoleDockWidget = new QDockWidget(tr("Communication Console"), this);
            debugConsoleDockWidget->setWidget( new DebugConsole(this) );
    
            debugConsoleDockWidget->setObjectName("COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET");
    
            addToToolsMenu (debugConsoleDockWidget, tr("Communication Console"), SLOT(showToolWidget(bool)), MENU_DEBUG_CONSOLE, Qt::BottomDockWidgetArea);
    
        if (!logPlayerDockWidget) {
    
            logPlayerDockWidget = new QDockWidget(tr("MAVLink Log Player"), this);
            logPlayerDockWidget->setWidget( new QGCMAVLinkLogPlayer(mavlink, this) );
            logPlayerDockWidget->setObjectName("MAVLINK_LOG_PLAYER_DOCKWIDGET");
    
            addToToolsMenu(logPlayerDockWidget, tr("MAVLink Log Replay"), SLOT(showToolWidget(bool)), MENU_MAVLINK_LOG_PLAYER, Qt::RightDockWidgetArea);
    
            mapWidget = new QGCMapTool(this);
    
            addToCentralWidgetsMenu (mapWidget, "Maps", SLOT(showCentralWidget()),CENTRAL_MAP);
        }
    
        if (!protocolWidget) {
    
            protocolWidget    = new XMLCommProtocolWidget(this);
            addToCentralWidgetsMenu (protocolWidget, "Mavlink Generator", SLOT(showCentralWidget()),CENTRAL_PROTOCOL);
        }
    
        if (!dataplotWidget) {
    
    lm's avatar
    lm committed
            dataplotWidget    = new QGCDataPlot2D(this);
    
            addToCentralWidgetsMenu (dataplotWidget, "Logfile Plot", SLOT(showCentralWidget()),CENTRAL_DATA_PLOT);
    
    pixhawk's avatar
    pixhawk committed
        //FIXME: memory of acceptList will never be freed again
        QStringList* acceptList = new QStringList();
    
    pixhawk's avatar
    pixhawk committed
        acceptList->append("-105,roll deg,deg,+105,s");
        acceptList->append("-105,pitch deg,deg,+105,s");
        acceptList->append("-105,heading deg,deg,+105,s");
    
    pixhawk's avatar
    pixhawk committed
        acceptList->append("-60,rollspeed d/s,deg/s,+60,s");
        acceptList->append("-60,pitchspeed d/s,deg/s,+60,s");
        acceptList->append("-60,yawspeed d/s,deg/s,+60,s");
    
        acceptList->append("0,airspeed,m/s,30");
    
        acceptList->append("0,groundspeed,m/s,30");
        acceptList->append("0,climbrate,m/s,30");
    
        acceptList->append("0,throttle,%,100");
    
    pixhawk's avatar
    pixhawk committed
        //FIXME: memory of acceptList2 will never be freed again
        QStringList* acceptList2 = new QStringList();
    
        acceptList2->append("900,servo #1,us,2100,s");
        acceptList2->append("900,servo #2,us,2100,s");
        acceptList2->append("900,servo #3,us,2100,s");
        acceptList2->append("900,servo #4,us,2100,s");
        acceptList2->append("900,servo #5,us,2100,s");
        acceptList2->append("900,servo #6,us,2100,s");
        acceptList2->append("900,servo #7,us,2100,s");
        acceptList2->append("900,servo #8,us,2100,s");
    
    lm's avatar
    lm committed
        acceptList2->append("0,abs pressure,hPa,65500");
    
        //acceptList2->append("-2048,accel. x,raw,2048,s");
        //acceptList2->append("-2048,accel. y,raw,2048,s");
        //acceptList2->append("-2048,accel. z,raw,2048,s");
    
        if (!linechartWidget) {
    
            // Center widgets
            linechartWidget   = new Linecharts(this);
    
            addToCentralWidgetsMenu(linechartWidget, tr("Realtime Plot"), SLOT(showCentralWidget()), CENTRAL_LINECHART);
    
        if (!hudWidget) {
    
            addToCentralWidgetsMenu(hudWidget, tr("Head Up Display"), SLOT(showCentralWidget()), CENTRAL_HUD);
    
        if (!dataplotWidget) {
    
            dataplotWidget    = new QGCDataPlot2D(this);
    
            addToCentralWidgetsMenu(dataplotWidget, "Logfile Plot", SLOT(showCentralWidget()), CENTRAL_DATA_PLOT);
    
        if (!_3DWidget) {
    
            _3DWidget         = Q3DWidgetFactory::get("PIXHAWK");
    
            addToCentralWidgetsMenu(_3DWidget, tr("Local 3D"), SLOT(showCentralWidget()), CENTRAL_3D_LOCAL);
    
    #ifdef QGC_OSGEARTH_ENABLED
    
        if (!_3DMapWidget) {
    
            _3DMapWidget = Q3DWidgetFactory::get("MAP3D");
    
            addToCentralWidgetsMenu(_3DMapWidget, tr("OSG Earth 3D"), SLOT(showCentralWidget()), CENTRAL_OSGEARTH);
    
    lm's avatar
    lm committed
    
    
    #if (defined _MSC_VER) | (defined Q_OS_MAC)
    
        if (!gEarthWidget) {
    
            gEarthWidget = new QGCGoogleEarthView(this);
    
            addToCentralWidgetsMenu(gEarthWidget, tr("Google Earth"), SLOT(showCentralWidget()), CENTRAL_GOOGLE_EARTH);
    
    pixhawk's avatar
    pixhawk committed
        // Dock widgets
    
        if (!detectionDockWidget) {
    
            detectionDockWidget = new QDockWidget(tr("Object Recognition"), this);
            detectionDockWidget->setWidget( new ObjectDetectionView("images/patterns", this) );
    
    pixhawk's avatar
    pixhawk committed
            detectionDockWidget->setObjectName("OBJECT_DETECTION_DOCK_WIDGET");
    
            addToToolsMenu (detectionDockWidget, tr("Object Recognition"), SLOT(showToolWidget(bool)), MENU_DETECTION, Qt::RightDockWidgetArea);
    
        if (!parametersDockWidget) {
    
            parametersDockWidget = new QDockWidget(tr("Calibration and Onboard Parameters"), this);
    
            parametersDockWidget->setWidget( new ParameterInterface(this) );
    
    pixhawk's avatar
    pixhawk committed
            parametersDockWidget->setObjectName("PARAMETER_INTERFACE_DOCKWIDGET");
    
            addToToolsMenu (parametersDockWidget, tr("Calibration and Parameters"), SLOT(showToolWidget(bool)), MENU_PARAMETERS, Qt::RightDockWidgetArea);
    
        if (!watchdogControlDockWidget) {
    
            watchdogControlDockWidget = new QDockWidget(tr("Process Control"), this);
            watchdogControlDockWidget->setWidget( new WatchdogControl(this) );
    
    pixhawk's avatar
    pixhawk committed
            watchdogControlDockWidget->setObjectName("WATCHDOG_CONTROL_DOCKWIDGET");
    
            addToToolsMenu (watchdogControlDockWidget, tr("Process Control"), SLOT(showToolWidget(bool)), MENU_WATCHDOG, Qt::BottomDockWidgetArea);
    
        if (!hsiDockWidget) {
    
            hsiDockWidget = new QDockWidget(tr("Horizontal Situation Indicator"), this);
            hsiDockWidget->setWidget( new HSIDisplay(this) );
    
            hsiDockWidget->setObjectName("HORIZONTAL_SITUATION_INDICATOR_DOCK_WIDGET");
    
            addToToolsMenu (hsiDockWidget, tr("Horizontal Situation"), SLOT(showToolWidget(bool)), MENU_HSI, Qt::BottomDockWidgetArea);
    
        if (!headDown1DockWidget) {
    
            headDown1DockWidget = new QDockWidget(tr("Flight Display"), this);
            headDown1DockWidget->setWidget( new HDDisplay(acceptList, "Flight Display", this) );
    
            headDown1DockWidget->setObjectName("HEAD_DOWN_DISPLAY_1_DOCK_WIDGET");
    
            addToToolsMenu (headDown1DockWidget, tr("Flight Display"), SLOT(showToolWidget(bool)), MENU_HDD_1, Qt::RightDockWidgetArea);
    
        if (!headDown2DockWidget) {
    
            headDown2DockWidget = new QDockWidget(tr("Actuator Status"), this);
            headDown2DockWidget->setWidget( new HDDisplay(acceptList2, "Actuator Status", this) );
    
            headDown2DockWidget->setObjectName("HEAD_DOWN_DISPLAY_2_DOCK_WIDGET");
    
            addToToolsMenu (headDown2DockWidget, tr("Actuator Status"), SLOT(showToolWidget(bool)), MENU_HDD_2, Qt::RightDockWidgetArea);
    
        if (!rcViewDockWidget) {
    
            rcViewDockWidget = new QDockWidget(tr("Radio Control"), this);
            rcViewDockWidget->setWidget( new QGCRemoteControlView(this) );
    
            rcViewDockWidget->setObjectName("RADIO_CONTROL_CHANNELS_DOCK_WIDGET");
    
            addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget(bool)), MENU_RC_VIEW, Qt::BottomDockWidgetArea);
    
        if (!headUpDockWidget) {
    
            headUpDockWidget = new QDockWidget(tr("HUD"), this);
            headUpDockWidget->setWidget( new HUD(320, 240, this));
    
            headUpDockWidget->setObjectName("HEAD_UP_DISPLAY_DOCK_WIDGET");
    
            addToToolsMenu (headUpDockWidget, tr("Head Up Display"), SLOT(showToolWidget(bool)), MENU_HUD, Qt::RightDockWidgetArea);
    
        if (!video1DockWidget) {
    
    pixhawk's avatar
    pixhawk committed
            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");
    
            addToToolsMenu (video1DockWidget, tr("Video Stream 1"), SLOT(showToolWidget(bool)), MENU_VIDEO_STREAM_1, Qt::LeftDockWidgetArea);
    
        if (!video2DockWidget) {
    
    pixhawk's avatar
    pixhawk committed
            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");
    
            addToToolsMenu (video2DockWidget, tr("Video Stream 2"), SLOT(showToolWidget(bool)), MENU_VIDEO_STREAM_2, Qt::LeftDockWidgetArea);
    
    pixhawk's avatar
    pixhawk committed
        // Dialogue widgets
        //FIXME: free memory in destructor
    
        if (!linechartWidget) {
    
            // Center widgets
            linechartWidget   = new Linecharts(this);
    
            addToCentralWidgetsMenu(linechartWidget, tr("Realtime Plot"), SLOT(showCentralWidget()), CENTRAL_LINECHART);
    
        if (!headUpDockWidget) {
    
            // Dock widgets
            headUpDockWidget = new QDockWidget(tr("Control Indicator"), this);
            headUpDockWidget->setWidget( new HUD(320, 240, this));
    
    pixhawk's avatar
    pixhawk committed
            headUpDockWidget->setObjectName("HEAD_UP_DISPLAY_DOCK_WIDGET");
    
            addToToolsMenu (headUpDockWidget, tr("Head Up Display"), SLOT(showToolWidget(bool)), MENU_HUD, Qt::LeftDockWidgetArea);
    
        if (!rcViewDockWidget) {
    
            rcViewDockWidget = new QDockWidget(tr("Radio Control"), this);
            rcViewDockWidget->setWidget( new QGCRemoteControlView(this) );
    
    pixhawk's avatar
    pixhawk committed
            rcViewDockWidget->setObjectName("RADIO_CONTROL_CHANNELS_DOCK_WIDGET");
    
            addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget(bool)), MENU_RC_VIEW, Qt::BottomDockWidgetArea);
    
        if (!gEarthWidget) {
    
            gEarthWidget = new QGCGoogleEarthView(this);
            addToCentralWidgetsMenu(gEarthWidget, tr("Google Earth"), SLOT(showCentralWidget()), CENTRAL_GOOGLE_EARTH);
        }
    
    #endif
    
    
        if (!slugsDataWidget) {
    
            // Dialog widgets
            slugsDataWidget = new QDockWidget(tr("Slugs Data"), this);
            slugsDataWidget->setWidget( new SlugsDataSensorView(this));
            slugsDataWidget->setObjectName("SLUGS_DATA_DOCK_WIDGET");
            addToToolsMenu (slugsDataWidget, tr("Telemetry Data"), SLOT(showToolWidget(bool)), MENU_SLUGS_DATA, Qt::RightDockWidgetArea);
        }
    
        if (!slugsHilSimWidget) {
    
            slugsHilSimWidget = new QDockWidget(tr("Slugs Hil Sim"), this);
            slugsHilSimWidget->setWidget( new SlugsHilSim(this));
            slugsHilSimWidget->setObjectName("SLUGS_HIL_SIM_DOCK_WIDGET");
            addToToolsMenu (slugsHilSimWidget, tr("HIL Sim Configuration"), SLOT(showToolWidget(bool)), MENU_SLUGS_HIL, Qt::LeftDockWidgetArea);
        }
    
        if (!controlParameterWidget) {
            controlParameterWidget = new QDockWidget(tr("Control Parameters"), this);
    
            controlParameterWidget->setObjectName("UNMANNED_SYSTEM_CONTROL_PARAMETERWIDGET");
            controlParameterWidget->setWidget( new UASControlParameters(this) );
            addToToolsMenu (controlParameterWidget, tr("Control Parameters"), SLOT(showToolWidget(bool)), MENU_UAS_CONTROL_PARAM, Qt::LeftDockWidgetArea);
    
        if (!parametersDockWidget) {
    
            parametersDockWidget = new QDockWidget(tr("Calibration and Onboard Parameters"), this);
            parametersDockWidget->setWidget( new ParameterInterface(this) );
            parametersDockWidget->setObjectName("PARAMETER_INTERFACE_DOCKWIDGET");
            addToToolsMenu (parametersDockWidget, tr("Calibration and Parameters"), SLOT(showToolWidget(bool)), MENU_PARAMETERS, Qt::RightDockWidgetArea);
        }
    
    
        if (!slugsCamControlWidget) {
    
            slugsCamControlWidget = new QDockWidget(tr("Camera Control"), this);
            slugsCamControlWidget->setWidget(new SlugsPadCameraControl(this));
            slugsCamControlWidget->setObjectName("SLUGS_CAM_CONTROL_DOCK_WIDGET");
            addToToolsMenu (slugsCamControlWidget, tr("Camera Control"), SLOT(showToolWidget(bool)), MENU_SLUGS_CAMERA, Qt::BottomDockWidgetArea);
        }
    
    
    
    void MainWindow::addToCentralWidgetsMenu ( QWidget* widget,
    
            const QString title,
            const char * slotName,
            TOOLS_WIDGET_NAMES centralWidget)
    
        QAction* tempAction;
    
    // Not needed any more - separate menu now available
    
    //    // 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);
    
        tempAction->setCheckable(true);
        tempAction->setData(centralWidget);
    
        // populate the Hashes
        toolsMenuActions[centralWidget] = tempAction;
        dockWidgets[centralWidget] = widget;
    
        QString chKey = buildMenuKey(SUB_SECTION_CHECKED, centralWidget, currentView);
    
        if (!settings.contains(chKey)) {
    
            settings.setValue(chKey,false);
            tempAction->setChecked(false);
    
            tempAction->setChecked(settings.value(chKey).toBool());
        }
    
        // connect the action
    
        connect(tempAction,SIGNAL(triggered(bool)),this, slotName);
    
    lm's avatar
    lm committed
    void MainWindow::showCentralWidget()
    {
    
        QAction* senderAction = qobject_cast<QAction *>(sender());
    
    
        // Block sender action while manipulating state
        senderAction->blockSignals(true);
    
    
        int tool = senderAction->data().toInt();
        QString chKey;
    
        // check the current action
    
        if (senderAction && dockWidgets[tool]) {
    
            // uncheck all central widget actions
            QHashIterator<int, QAction*> i(toolsMenuActions);
    
            while (i.hasNext()) {
    
                i.next();
    
                //qDebug() << "shCW" << i.key() << "read";
    
                if (i.value() && i.value()->data().toInt() > 255) {
    
                    // Block signals and uncheck action
                    // firing would be unneccesary
                    i.value()->blockSignals(true);
    
                    i.value()->setChecked(false);
    
                    i.value()->blockSignals(false);
    
    
                    // update the settings
                    chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(i.value()->data().toInt()), currentView);
                    settings.setValue(chKey,false);
                }
            }
    
            // check the current action
    
            senderAction->setChecked(true);
    
            // update the central widget
            centerStack->setCurrentWidget(dockWidgets[tool]);
    
            // store the selected central widget
            chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast<TOOLS_WIDGET_NAMES>(tool), currentView);
            settings.setValue(chKey,true);
    
            // Unblock sender action
            senderAction->blockSignals(false);
    
    
            presentView();
        }
    
    lm's avatar
    lm committed
    /**
     * Adds a widget to the tools menu and sets it visible if it was
     * enabled last time.
     */
    
    void MainWindow::addToToolsMenu ( QWidget* widget,
    
                                      const QString title,
                                      const char * slotName,
                                      TOOLS_WIDGET_NAMES tool,
                                      Qt::DockWidgetArea location)
    
    lm's avatar
    lm committed
    {
    
        QAction* tempAction;
        QString posKey, chKey;
    
        if (toolsMenuActions[CENTRAL_SEPARATOR]) {
    
            tempAction = new QAction(title, this);
            ui.menuTools->insertAction(toolsMenuActions[CENTRAL_SEPARATOR],
                                       tempAction);
    
            tempAction = ui.menuTools->addAction(title);
        }
    
        tempAction->setCheckable(true);
        tempAction->setData(tool);
    
        // populate the Hashes
        toolsMenuActions[tool] = tempAction;
        dockWidgets[tool] = widget;
    
        posKey = buildMenuKey (SUB_SECTION_LOCATION,tool, currentView);
    
        if (!settings.contains(posKey)) {
    
            settings.setValue(posKey,location);
            dockWidgetLocations[tool] = location;
    
            dockWidgetLocations[tool] = static_cast <Qt::DockWidgetArea> (settings.value(posKey, Qt::RightDockWidgetArea).toInt());
    
        chKey = buildMenuKey(SUB_SECTION_CHECKED,tool, currentView);
    
        if (!settings.contains(chKey)) {
    
            settings.setValue(chKey,false);
            tempAction->setChecked(false);
    
            tempAction->setChecked(settings.value(chKey, false).toBool());
    
            widget->setVisible(settings.value(chKey, false).toBool());
    
        // connect the action
    
        connect(tempAction,SIGNAL(toggled(bool)),this, slotName);
    
        connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
    
                SIGNAL(visibilityChanged(bool)), this, SLOT(showToolWidget(bool)));
    
        //  connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
        //          SIGNAL(visibilityChanged(bool)), this, SLOT(updateVisibilitySettings(bool)));
    
        connect(qobject_cast <QDockWidget *>(dockWidgets[tool]),
                SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(updateLocationSettings(Qt::DockWidgetArea)));
    
    void MainWindow::showToolWidget(bool visible)
    
        if (!aboutToCloseFlag && !changingViewsFlag) {
    
            QAction* action = qobject_cast<QAction *>(sender());
    
    
            // Prevent this to fire if undocked
    
            if (action) {
    
                int tool = action->data().toInt();
    
                QDockWidget* dockWidget = qobject_cast<QDockWidget *> (dockWidgets[tool]);
    
                if (dockWidget && dockWidget->isVisible() != visible) {
                    if (visible) {
    
                        addDockWidget(dockWidgetLocations[tool], dockWidget);
                        dockWidget->show();
    
                        removeDockWidget(dockWidget);
                    }
    
    
                    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;
    
    
            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()) {
    
                    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;
    
    void MainWindow::showTheWidget (TOOLS_WIDGET_NAMES widget, VIEW_SECTIONS view)
    {
        bool tempVisible;
        Qt::DockWidgetArea tempLocation;
        QDockWidget* tempWidget = static_cast <QDockWidget *>(dockWidgets[widget]);
    
        tempVisible =  settings.value(buildMenuKey(SUB_SECTION_CHECKED,widget,view), false).toBool();
    
        //qDebug() << "showTheWidget(): Set key" << buildMenuKey(SUB_SECTION_CHECKED,widget,view) << "to" << tempVisible;
    
        if (tempWidget) {
    
            toolsMenuActions[widget]->setChecked(tempVisible);
        }
    
        //qDebug() <<  buildMenuKey (SUB_SECTION_CHECKED,widget,view) << tempVisible;
    
        tempLocation = static_cast <Qt::DockWidgetArea>(settings.value(buildMenuKey (SUB_SECTION_LOCATION,widget, view), QVariant(Qt::RightDockWidgetArea)).toInt());
    
    
        if (tempWidget != NULL) {
            if (tempVisible) {
    
                addDockWidget(tempLocation, tempWidget);
                tempWidget->show();
            }
    
    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;
    
        apType = 1;
    
        return (QString::number(apType) + "_" +
                QString::number(SECTION_MENU) + "_" +
                QString::number(view) + "_" +
                QString::number(tool) + "_" +
                QString::number(section) + "_" );
    
    void MainWindow::closeEvent(QCloseEvent *event)
    {
    
        aboutToCloseFlag = true;
    
    lm's avatar
    lm committed
        UASManager::instance()->storeSettings();
    
        QMainWindow::closeEvent(event);
    }
    
    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;
                    }
                }
            }
        }
    }
    
    void MainWindow::updateVisibilitySettings (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;
                    }
                }
            }
        }
    
    void MainWindow::updateLocationSettings (Qt::DockWidgetArea location)
    {
        QDockWidget* temp = qobject_cast<QDockWidget *>(sender());
    
        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;
            }
        }
    
    /**
     * Connect the signals and slots of the common window widgets
     */
    
        if (infoDockWidget && infoDockWidget->widget()) {
    
    pixhawk's avatar
    pixhawk committed
            connect(mavlink, SIGNAL(receiveLossChanged(int, float)),
                    infoDockWidget->widget(), SLOT(updateSendLoss(int, float)));
        }
    
    lm's avatar
    lm committed
    //    //TODO temporaly debug
    //    if (slugsHilSimWidget && slugsHilSimWidget->widget()) {
    //        connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
    //                slugsHilSimWidget->widget(), SLOT(activeUasSet(UASInterface*)));
    //    }
    
    lm's avatar
    lm committed
        QGCToolWidget* tool = new QGCToolWidget("Unnamed Tool", this);
    
    
        if (QGCToolWidget::instances()->size() < 2) {
    
    lm's avatar
    lm committed
            // This is the first widget
            ui.menuTools->addSeparator();
        }
    
    
        QDockWidget* dock = new QDockWidget("Unnamed Tool", this);
    
    lm's avatar
    lm committed
        connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater()));
    
    lm's avatar
    lm committed
        QAction* showAction = new QAction("Show Unnamed Tool", this);
    
        showAction->setCheckable(true);
    
    lm's avatar
    lm committed
        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);
    
        // No special connections necessary at this point
    
        if (slugsHilSimWidget && slugsHilSimWidget->widget()) {
    
            connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                    slugsHilSimWidget->widget(), SLOT(activeUasSet(UASInterface*)));
    
        if (slugsDataWidget && slugsDataWidget->widget()) {
    
            connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                    slugsDataWidget->widget(), SLOT(setActiveUAS(UASInterface*)));
    
        if (controlParameterWidget && controlParameterWidget->widget()) {
    
            connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
                    controlParameterWidget->widget(), SLOT(activeUasSet(UASInterface*)));
        }
    
        if(controlDockWidget && controlParameterWidget) {
            connect(controlDockWidget->widget(), SIGNAL(changedMode(int)), controlParameterWidget->widget(), SLOT(changedMode(int)));
    
    void MainWindow::arrangeCommonCenterStack()
    
        centerStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    
    pixhawk's avatar
    pixhawk committed
        if (!centerStack) return;
    
        if (mapWidget && (centerStack->indexOf(mapWidget) == -1)) centerStack->addWidget(mapWidget);
    
    lm's avatar
    lm committed
        if (dataplotWidget && (centerStack->indexOf(dataplotWidget) == -1)) centerStack->addWidget(dataplotWidget);
    
        if (protocolWidget && (centerStack->indexOf(protocolWidget) == -1)) centerStack->addWidget(protocolWidget);