diff --git a/src/comm/MAVLinkSimulationLink.cc b/src/comm/MAVLinkSimulationLink.cc index 4d89666210576182e1e3aa951c65a795d22c17e3..d5647da23539cfac3324d8f1d2567f81110cd544 100644 --- a/src/comm/MAVLinkSimulationLink.cc +++ b/src/comm/MAVLinkSimulationLink.cc @@ -659,7 +659,7 @@ qint64 MAVLinkSimulationLink::bytesAvailable() void MAVLinkSimulationLink::writeBytes(const char* data, qint64 size) { - qDebug() << "Simulation received " << size << " bytes from groundstation: "; + //qDebug() << "Simulation received " << size << " bytes from groundstation: "; // Increase write counter //bitsSentTotal += size * 8; diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 2b138dc5015dd818cd9a84dbf7ea0af20368dba3..5e6239535c13a1ef14f0cd41bbf88f3d3029c854 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -46,6 +46,7 @@ **/ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), + toolsMenuActions(), settings() { this->hide(); @@ -89,33 +90,39 @@ MainWindow::~MainWindow() } + void MainWindow::buildCommonWidgets() { //TODO: move protocol outside UI mavlink = new MAVLinkProtocol(); - // Center widgets - mapWidget = new MapWidget(this); - protocolWidget = new XMLCommProtocolWidget(this); - // Dock widgets controlDockWidget = new QDockWidget(tr("Control"), this); controlDockWidget->setWidget( new UASControlWidget(this) ); + addToToolsMenu (controlDockWidget, tr("UAS Control"), SLOT(showToolWidget()), MENU_UAS_CONTROL, Qt::LeftDockWidgetArea); listDockWidget = new QDockWidget(tr("Unmanned Systems"), this); listDockWidget->setWidget( new UASListWidget(this) ); + addToToolsMenu (listDockWidget, tr("UAS List"), SLOT(showToolWidget()), MENU_UAS_LIST, Qt::RightDockWidgetArea); waypointsDockWidget = new QDockWidget(tr("Waypoint List"), this); waypointsDockWidget->setWidget( new WaypointList(this, NULL) ); + addToToolsMenu (waypointsDockWidget, tr("Waypoints List"), SLOT(showToolWidget()), MENU_WAYPOINTS, Qt::BottomDockWidgetArea); infoDockWidget = new QDockWidget(tr("Status Details"), this); infoDockWidget->setWidget( new UASInfoWidget(this) ); + addToToolsMenu (infoDockWidget, tr("Status Details"), SLOT(showToolWidget()), MENU_STATUS, Qt::RightDockWidgetArea); + debugConsoleDockWidget = new QDockWidget(tr("Communication Console"), this); debugConsoleDockWidget->setWidget( new DebugConsole(this) ); + addToToolsMenu (debugConsoleDockWidget, tr("Communication Console"), SLOT(showToolWidget()), MENU_DEBUG_CONSOLE, Qt::BottomDockWidgetArea); -} + // Center widgets + mapWidget = new MapWidget(this); + protocolWidget = new XMLCommProtocolWidget(this); +} void MainWindow::buildPxWidgets() { //FIXME: memory of acceptList will never be freed again @@ -151,27 +158,37 @@ void MainWindow::buildPxWidgets() // Dock widgets detectionDockWidget = new QDockWidget(tr("Object Recognition"), this); detectionDockWidget->setWidget( new ObjectDetectionView("images/patterns", this) ); + addToToolsMenu (detectionDockWidget, tr("Object Recognition"), SLOT(showToolWidget()), MENU_DETECTION, Qt::RightDockWidgetArea); + parametersDockWidget = new QDockWidget(tr("Onboard Parameters"), this); parametersDockWidget->setWidget( new ParameterInterface(this) ); + addToToolsMenu (parametersDockWidget, tr("Onboard Parameters"), SLOT(showToolWidget()), MENU_PARAMETERS, Qt::RightDockWidgetArea); watchdogControlDockWidget = new QDockWidget(tr("Process Control"), this); watchdogControlDockWidget->setWidget( new WatchdogControl(this) ); + addToToolsMenu (watchdogControlDockWidget, tr("Process Control"), SLOT(showToolWidget()), MENU_WATCHDOG, Qt::BottomDockWidgetArea); + hsiDockWidget = new QDockWidget(tr("Horizontal Situation Indicator"), this); hsiDockWidget->setWidget( new HSIDisplay(this) ); + addToToolsMenu (hsiDockWidget, tr("HSI"), SLOT(showToolWidget()), MENU_HSI, Qt::BottomDockWidgetArea); headDown1DockWidget = new QDockWidget(tr("Primary Flight Display"), this); headDown1DockWidget->setWidget( new HDDisplay(acceptList, this) ); + addToToolsMenu (headDown1DockWidget, tr("Flight Display"), SLOT(showToolWidget()), MENU_HDD_1, Qt::RightDockWidgetArea); headDown2DockWidget = new QDockWidget(tr("Payload Status"), this); headDown2DockWidget->setWidget( new HDDisplay(acceptList2, this) ); + addToToolsMenu (headDown2DockWidget, tr("Payload Status"), SLOT(showToolWidget()), MENU_HDD_2, Qt::RightDockWidgetArea); rcViewDockWidget = new QDockWidget(tr("Radio Control"), this); rcViewDockWidget->setWidget( new QGCRemoteControlView(this) ); + addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget()), MENU_RC_VIEW, Qt::BottomDockWidgetArea); - headUpDockWidget = new QDockWidget(tr("Control Indicator"), this); + headUpDockWidget = new QDockWidget(tr("HUD"), this); headUpDockWidget->setWidget( new HUD(320, 240, this)); + addToToolsMenu (headUpDockWidget, tr("Control Indicator"), SLOT(showToolWidget()), MENU_HUD, Qt::LeftDockWidgetArea); // Dialogue widgets //FIXME: free memory in destructor @@ -183,32 +200,154 @@ void MainWindow::buildSlugsWidgets() { // Center widgets linechartWidget = new Linecharts(this); - hudWidget = new HUD(320, 240, this); // Dock widgets + headUpDockWidget = new QDockWidget(tr("Control Indicator"), this); + headUpDockWidget->setWidget( new HUD(320, 240, this)); + addToToolsMenu (headUpDockWidget, tr("HUD"), SLOT(showToolWidget()), MENU_HUD, Qt::LeftDockWidgetArea); + + rcViewDockWidget = new QDockWidget(tr("Radio Control"), this); rcViewDockWidget->setWidget( new QGCRemoteControlView(this) ); + addToToolsMenu (rcViewDockWidget, tr("Radio Control"), SLOT(showToolWidget()), MENU_RC_VIEW, Qt::BottomDockWidgetArea); - headUpDockWidget = new QDockWidget(tr("Control Indicator"), this); - headUpDockWidget->setWidget( new HUD(320, 240, this)); // Dialog widgets slugsDataWidget = new QDockWidget(tr("Slugs Data"), this); slugsDataWidget->setWidget( new SlugsDataSensorView(this)); + addToToolsMenu (slugsDataWidget, tr("Telemetry Data"), SLOT(showToolWidget()), MENU_SLUGS_DATA, Qt::RightDockWidgetArea); + slugsPIDControlWidget = new QDockWidget(tr("PID Control"), this); slugsPIDControlWidget->setWidget(new SlugsPIDControl(this)); + addToToolsMenu (slugsPIDControlWidget, tr("PID Configuration"), SLOT(showToolWidget()), MENU_SLUGS_PID, Qt::LeftDockWidgetArea); slugsHilSimWidget = new QDockWidget(tr("Slugs Hil Sim"), this); slugsHilSimWidget->setWidget( new SlugsHilSim(this)); + addToToolsMenu (slugsHilSimWidget, tr("HIL Sim Configuration"), SLOT(showToolWidget()), MENU_SLUGS_HIL, Qt::LeftDockWidgetArea); slugsCamControlWidget = new QDockWidget(tr("Video Camera Control"), this); slugsCamControlWidget->setWidget(new SlugsVideoCamControl(this)); + addToToolsMenu (slugsCamControlWidget, tr("Camera Control"), SLOT(showToolWidget()), MENU_SLUGS_CAMERA, Qt::BottomDockWidgetArea); } /** * Connect the signals and slots of the common window widgets */ + +void MainWindow::addToToolsMenu ( QWidget* widget, + const QString title, + const char * slotName, + TOOLS_WIDGET_NAMES tool, + Qt::DockWidgetArea location){ + QAction* tempAction; + QString posKey, chKey; + tempAction = ui.menuTools->addAction(title); + tempAction->setCheckable(true); + tempAction->setData(tool); + + // populate the Hashes + toolsMenuActions[tool] = tempAction; + dockWidgets[tool] = widget; + + // Based on Settings check/uncheck + // Postion key = menu/widget/position/pos_value + posKey = buildMenuKey (SUB_SECTION_LOCATION,tool); + + if (!settings.contains(posKey)){ + settings.setValue(posKey,location); + dockWidgetLocations[tool] = location; + } else { + dockWidgetLocations[tool] = static_cast (settings.value(posKey).toInt()); + } + + // Checked key = menu/widget/checked/pos_value + chKey = buildMenuKey(SUB_SECTION_CHECKED,tool); + + if (!settings.contains(chKey)){ + settings.setValue(chKey,false); + tempAction->setChecked(false); + } else { + tempAction->setChecked(settings.value(chKey).toBool()); + } + + // connect the action + connect(tempAction,SIGNAL(triggered()),this, slotName); + + connect(static_cast (dockWidgets[tool]), + SIGNAL(visibilityChanged(bool)), this, SLOT(updateVisibilitySettings(bool))); + + connect(static_cast (dockWidgets[tool]), + SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(updateLocationSettings(Qt::DockWidgetArea))); + +} + +QString MainWindow::buildMenuKey(SETTINGS_SECTIONS section, TOOLS_WIDGET_NAMES tool){ + return (QString::number(SECTION_MENU) + "/" + + QString::number(tool) + "/" + + QString::number(section) + "/" ); +} + + +void MainWindow::showToolWidget(){ + QAction* temp = qobject_cast(sender()); + int tool = temp->data().toInt(); + + if (temp && dockWidgets[tool]){ + if (temp->isChecked()){ + addDockWidget(dockWidgetLocations[tool], static_cast (dockWidgets[tool])); + static_cast (dockWidgets[tool])->show(); + } else { + removeDockWidget(static_cast (dockWidgets[tool])); + } + QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast(tool)); + settings.setValue(chKey,temp->isChecked()); + } +} + + +void MainWindow::updateVisibilitySettings (bool vis){ + Q_UNUSED(vis); + + // This is commented since when the application closes + // sets the visibility to false. + + // TODO: A workaround is needed. The QApplication::aboutToQuit + // did not work + + /* + QDockWidget* temp = qobject_cast(sender()); + + QHashIterator i(dockWidgets); + while (i.hasNext()) { + i.next(); + if ((static_cast (dockWidgets[i.key()])) == temp){ + QString chKey = buildMenuKey (SUB_SECTION_CHECKED,static_cast(i.key())); + qDebug() << "Key in visibility changed" << chKey; + settings.setValue(chKey,vis); + toolsMenuActions[i.key()]->setChecked(vis); + break; + } + } +*/ +} + +void MainWindow::updateLocationSettings (Qt::DockWidgetArea location){ + QDockWidget* temp = qobject_cast(sender()); + + QHashIterator i(dockWidgets); + while (i.hasNext()) { + i.next(); + if ((static_cast (dockWidgets[i.key()])) == temp){ + QString posKey = buildMenuKey (SUB_SECTION_LOCATION,static_cast(i.key())); + settings.setValue(posKey,location); + break; + } + } +} + + + void MainWindow::connectCommonWidgets() { if (infoDockWidget && infoDockWidget->widget()) @@ -278,8 +417,8 @@ void MainWindow::connectSlugsWidgets() void MainWindow::arrangeCommonCenterStack() { - centerStack = new QStackedWidget(this); + if (!centerStack) return; if (mapWidget) centerStack->addWidget(mapWidget); @@ -444,62 +583,9 @@ void MainWindow::showStatusMessage(const QString& status) * **/ -void MainWindow::buildHelpMenu (){ - QIcon icon; - - icon = QIcon(":/images/apps/utilities-system-monitor.svg"); - actionOnline_documentation = new QAction(icon,tr("Online Documentation"), this); - - icon = QIcon(":/images/status/software-update-available.svg"); - actionProject_Roadmap = new QAction(icon,tr("Project Roadmap"), this); - - icon = QIcon(":/images/categories/preferences-system.svg"); - actionCredits_Developers = new QAction(icon,tr("Developer Credits"), this); - - helpMenu = ui.menuBar->addMenu(tr("Help")); - - helpMenu->addAction(actionOnline_documentation); - helpMenu->addAction(actionProject_Roadmap); - helpMenu->addAction(actionCredits_Developers); - - -} - - -void MainWindow::buildViewsMenu (){ - QIcon icon; - - icon = QIcon(":/images/status/weather-overcast.svg"); - actionFlightView = new QAction(icon,"Flight View", this); - - icon = QIcon(":/images/apps/utilities-system-monitor.svg"); - actionEngineerView = new QAction(icon,"Engineer View", this); - - icon = QIcon(":/images/status/network-wireless-encrypted.svg"); - actionCalibrationView = new QAction(icon,"Calibration View", this); - - icon = QIcon(":/images/devices/network-wired.svg"); - actionMavlinkView = new QAction(icon,"Mavlink View", this); - - icon = QIcon(":/images/categories/applications-internet.svg"); - actionReloadStyle = new QAction(icon,"Reload Style", this); - - viewsMenu = ui.menuBar->addMenu("Views"); - - viewsMenu->addAction(actionFlightView); - viewsMenu->addAction(actionEngineerView); - viewsMenu->addAction(actionCalibrationView); - viewsMenu->addSeparator(); - viewsMenu->addAction(actionMavlinkView); - viewsMenu->addAction(actionReloadStyle); - -} - void MainWindow::connectCommonActions() { - buildViewsMenu(); - buildHelpMenu(); // Connect actions from ui connect(ui.actionAdd_Link, SIGNAL(triggered()), this, SLOT(addLink())); @@ -516,18 +602,17 @@ void MainWindow::connectCommonActions() connect(ui.actionConfiguration, SIGNAL(triggered()), UASManager::instance(), SLOT(configureActiveUAS())); // Views actions - connect(actionFlightView, SIGNAL(triggered()), this, SLOT(loadPilotView())); - connect(actionEngineerView, SIGNAL(triggered()), this, SLOT(loadEngineerView())); - connect(actionCalibrationView, SIGNAL(triggered()), this, SLOT(loadOperatorView())); + connect(ui.actionFlightView, SIGNAL(triggered()), this, SLOT(loadPilotView())); + connect(ui.actionEngineersView, SIGNAL(triggered()), this, SLOT(loadEngineerView())); + connect(ui.actionCalibrationView, SIGNAL(triggered()), this, SLOT(loadOperatorView())); - connect(actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView())); - connect(actionReloadStyle, SIGNAL(triggered()), this, SLOT(reloadStylesheet())); + connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView())); + connect(ui.actionReloadStyle, SIGNAL(triggered()), this, SLOT(reloadStylesheet())); // Help Actions - connect(actionOnline_documentation, SIGNAL(triggered()), this, SLOT(showHelp())); - connect(actionCredits_Developers, SIGNAL(triggered()), this, SLOT(showCredits())); - connect(actionProject_Roadmap, SIGNAL(triggered()), this, SLOT(showRoadMap())); - + connect(ui.actionOnline_documentation, SIGNAL(triggered()), this, SLOT(showHelp())); + connect(ui.actionDeveloper_Credits, SIGNAL(triggered()), this, SLOT(showCredits())); + connect(ui.actionProject_Roadmap, SIGNAL(triggered()), this, SLOT(showRoadMap())); } @@ -877,13 +962,16 @@ void MainWindow::loadPixhawkEngineerView() // 3D map if (_3DWidget) { - QStackedWidget *centerStack = dynamic_cast(centralWidget()); if (centerStack) { //map3DWidget->setActive(true); centerStack->setCurrentWidget(_3DWidget); } } +#else + if (centerStack && linechartWidget){ + centerStack->addWidget(linechartWidget); + } #endif // UAS CONTROL @@ -1290,9 +1378,13 @@ void MainWindow::load3DView() void MainWindow::loadEngineerView() { clearView(); - // Engineer view, used in EMAV2009 + // If there is no mav dont siwtch view + int selector = (UASManager::instance()->getActiveUAS())? + UASManager::instance()->getActiveUAS()->getAutopilotType() : + 255; + + switch (selector){ - switch (UASManager::instance()->getActiveUAS()->getAutopilotType()){ case (MAV_AUTOPILOT_GENERIC): case (MAV_AUTOPILOT_ARDUPILOTMEGA): case (MAV_AUTOPILOT_PIXHAWK): @@ -1320,9 +1412,35 @@ void MainWindow::loadMAVLinkView() } } + // TODO: Refactor this code to single function calls + + showTheWidget(MENU_UAS_CONTROL); + + showTheWidget(MENU_UAS_LIST); + + showTheWidget(MENU_WAYPOINTS); + + showTheWidget(MENU_STATUS); + + showTheWidget(MENU_DEBUG_CONSOLE); + this->show(); } +void MainWindow::showTheWidget (TOOLS_WIDGET_NAMES widget){ + bool tempVisible; + Qt::DockWidgetArea tempLocation; + QDockWidget* tempWidget = static_cast (dockWidgets[widget]); + + tempVisible = settings.value(buildMenuKey (SUB_SECTION_CHECKED,widget)).toBool(); + tempLocation = static_cast (settings.value(buildMenuKey (SUB_SECTION_LOCATION,widget)).toInt()); + + if (tempWidget && tempVisible){ + addDockWidget(tempLocation, tempWidget); + tempWidget->show(); + } +} + void MainWindow::loadAllView() { clearView(); @@ -1415,7 +1533,7 @@ void MainWindow::loadAllView() void MainWindow::loadWidgets() { //loadOperatorView(); - loadEngineerView(); + loadMAVLinkView(); //loadPilotView(); } diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 231c979d411c043532b7318bdbb504f7fe7904d0..ee1ed25ef2c3901e17af90bfc05260bebdd16399 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -148,7 +148,70 @@ public slots: /** @brief Reload the CSS style sheet */ void reloadStylesheet(); + + + void showToolWidget(); + void updateVisibilitySettings (bool vis); + void updateLocationSettings (Qt::DockWidgetArea location); protected: + + // These defines are used to save the settings when selecting with + // which widgets populate the views + // FIXME: DO NOT PUT CUSTOM VALUES IN THIS ENUM since it is iterated over + // this will be fixed in a future release. + typedef enum _TOOLS_WIDGET_NAMES { + MENU_UAS_CONTROL, + MENU_UAS_INFO, + MENU_CAMERA, + MENU_UAS_LIST, + MENU_WAYPOINTS, + MENU_STATUS, + MENU_DETECTION, + MENU_DEBUG_CONSOLE, + MENU_PARAMETERS, + MENU_HDD_1, + MENU_HDD_2, + MENU_WATCHDOG, + MENU_HUD, + MENU_HSI, + MENU_RC_VIEW, + MENU_SLUGS_DATA, + MENU_SLUGS_PID, + MENU_SLUGS_HIL, + MENU_SLUGS_CAMERA, + CENTRAL_LINECHART = 255, // Separation from dockwidgets and central widgets + CENTRAL_PROTOCOL, + CENTRAL_MAP, + CENTRAL_3D_LOCAL, + CENTRAL_3D_MAP, + CENTRAL_GOOGLE_EARTH, + CENTRAL_HUD, + CENTRAL_DATA_PLOT, + }TOOLS_WIDGET_NAMES; + + typedef enum _SETTINGS_SECTIONS { + SECTION_MENU, + VIEW_ENGINEER, + VIEW_OPERATOR, + VIEW_CALIBRATION, + VIEW_MAVLINK, + SUB_SECTION_CHECKED, + SUB_SECTION_LOCATION, + } SETTINGS_SECTIONS; + + + QHash toolsMenuActions; // Holds ptr to the Menu Actions + QHash dockWidgets; // Holds ptr to the Actual Dock widget + QHash dockWidgetLocations; // Holds the location + + + void addToToolsMenu (QWidget* widget, const QString title, const char * slotName, TOOLS_WIDGET_NAMES tool, Qt::DockWidgetArea location); + void showTheWidget (TOOLS_WIDGET_NAMES widget); + + int currentView; + int aboutToQuit; + //QHash settingsSections; + QStatusBar* statusBar; QStatusBar* createStatusBar(); void loadWidgets(); @@ -174,8 +237,6 @@ protected: void configureWindowName(); - void buildHelpMenu (); - void buildViewsMenu (); // TODO Should be moved elsewhere, as the protocol does not belong to the UI MAVLinkProtocol* mavlink; @@ -234,17 +295,7 @@ protected: QAction* stopUASAct; QAction* killUASAct; QAction* simulateUASAct; - QAction* actionOnline_documentation; - QAction* actionProject_Roadmap; - QAction* actionCredits_Developers; - QAction* actionCalibrationView; - QAction* actionEngineerView; - QAction* actionFlightView; - QAction* actionMavlinkView; - QAction* actionReloadStyle; - - QMenu* helpMenu; - QMenu* viewsMenu; + LogCompressor* comp; QString screenFileName; @@ -253,6 +304,8 @@ protected: private: Ui::MainWindow ui; + QString buildMenuKey (SETTINGS_SECTIONS section , TOOLS_WIDGET_NAMES tool); + }; #endif /* _MAINWINDOW_H_ */ diff --git a/src/ui/MainWindow.ui b/src/ui/MainWindow.ui index f6d151348b94d31a057ecfef61a172a35ab93237..a60e53c4e525d0178c01fde45827a5de82a16462 100644 --- a/src/ui/MainWindow.ui +++ b/src/ui/MainWindow.ui @@ -80,12 +80,34 @@ Tools + + + + + Help + + + + + + + + Perspectives + + + + + + + + + @@ -344,6 +366,78 @@ false + + + + :/images/apps/utilities-system-monitor.svg:/images/apps/utilities-system-monitor.svg + + + Online Documentation + + + + + + :/images/status/software-update-available.svg:/images/status/software-update-available.svg + + + Project Roadmap + + + + + + :/images/categories/preferences-system.svg:/images/categories/preferences-system.svg + + + Developer Credits + + + + + + :/images/status/weather-overcast.svg:/images/status/weather-overcast.svg + + + Flight + + + + + + :/images/apps/utilities-system-monitor.svg:/images/apps/utilities-system-monitor.svg + + + Engineer + + + + + + :/images/devices/network-wired.svg:/images/devices/network-wired.svg + + + Mavlink + + + + + + :/images/categories/applications-internet.svg:/images/categories/applications-internet.svg + + + Reload Style + + + + + + :/images/status/network-wireless-encrypted.svg:/images/status/network-wireless-encrypted.svg + + + Calibration + +