From 28fc38f60684a39c55740394b8afac347b9a4be1 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Tue, 13 Oct 2015 12:18:12 -0700 Subject: [PATCH] Dock Widgets only support floating This is in preparation for full Qml main window --- QGCApplication.pro | 4 +- src/FlightDisplay/FlightDisplayView.cc | 2 +- src/FlightDisplay/FlightDisplayWidget.cc | 6 +- src/FlightDisplay/FlightDisplayWidget.h | 2 +- src/MissionEditor/MissionEditor.cc | 2 +- src/QGCDockWidget.cc | 53 ++++-- src/QGCDockWidget.h | 19 +- src/QGCQmlWidgetHolder.cpp | 8 +- src/QGCQmlWidgetHolder.h | 12 +- src/QmlControls/QmlTestWidget.cc | 1 + src/QmlControls/ScreenToolsController.cc | 2 +- src/VehicleSetup/SetupView.cc | 2 +- src/ViewWidgets/CustomCommandWidget.cc | 8 +- src/ViewWidgets/CustomCommandWidget.h | 2 +- src/qgcunittest/PX4RCCalibrationTest.cc | 2 +- src/ui/HILDockWidget.cc | 6 +- src/ui/HILDockWidget.h | 2 +- src/ui/MainWindow.cc | 215 ++++++++++------------- src/ui/MainWindow.h | 22 ++- src/ui/MultiVehicleDockWidget.cc | 6 +- src/ui/MultiVehicleDockWidget.h | 6 +- src/ui/QGCHilConfiguration.ui | 2 +- src/ui/QGCMAVLinkInspector.cc | 6 +- src/ui/QGCMAVLinkInspector.h | 6 +- src/ui/QGCMAVLinkInspector.ui | 2 +- src/ui/QGCTabbedInfoView.cpp | 5 +- src/ui/QGCTabbedInfoView.h | 10 +- src/ui/QGCTabbedInfoView.ui | 2 +- src/ui/QGCUASFileViewMulti.cc | 6 +- src/ui/QGCUASFileViewMulti.h | 6 +- src/ui/QGCUASFileViewMulti.ui | 2 +- src/ui/UASInfo.ui | 2 +- src/ui/toolbar/MainToolBar.cc | 2 +- src/ui/uas/UASInfoWidget.cc | 5 +- src/ui/uas/UASInfoWidget.h | 6 +- 35 files changed, 240 insertions(+), 204 deletions(-) diff --git a/QGCApplication.pro b/QGCApplication.pro index 08f0eeedd..2ceff3dc7 100644 --- a/QGCApplication.pro +++ b/QGCApplication.pro @@ -230,6 +230,7 @@ HEADERS += \ src/QGCApplication.h \ src/QGCComboBox.h \ src/QGCConfig.h \ + src/QGCDockWidget.h \ src/QGCFileDialog.h \ src/QGCGeo.h \ src/QGCLoggingCategory.h \ @@ -289,7 +290,6 @@ HEADERS += \ src/comm/QGCHilLink.h \ src/comm/QGCJSBSimLink.h \ src/comm/QGCXPlaneLink.h \ - src/QGCDockWidget.h \ src/ui/CameraView.h \ src/ui/HILDockWidget.h \ src/ui/MultiVehicleDockWidget.h \ @@ -340,6 +340,7 @@ SOURCES += \ src/QGC.cc \ src/QGCApplication.cc \ src/QGCComboBox.cc \ + src/QGCDockWidget.cc \ src/QGCFileDialog.cc \ src/QGCLoggingCategory.cc \ src/QGCPalette.cc \ @@ -393,7 +394,6 @@ SOURCES += \ src/comm/QGCFlightGearLink.cc \ src/comm/QGCJSBSimLink.cc \ src/comm/QGCXPlaneLink.cc \ - src/QGCDockWidget.cc \ src/ui/CameraView.cc \ src/ui/HILDockWidget.cc \ src/ui/MultiVehicleDockWidget.cc \ diff --git a/src/FlightDisplay/FlightDisplayView.cc b/src/FlightDisplay/FlightDisplayView.cc index 8b19e357e..2d4d4cec8 100644 --- a/src/FlightDisplay/FlightDisplayView.cc +++ b/src/FlightDisplay/FlightDisplayView.cc @@ -35,7 +35,7 @@ This file is part of the QGROUNDCONTROL project const char* kMainFlightDisplayViewGroup = "FlightDisplayView"; FlightDisplayView::FlightDisplayView(QWidget *parent) - : QGCQmlWidgetHolder(parent) + : QGCQmlWidgetHolder(QString(), NULL, parent) { setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setObjectName("FlightDisplayView"); diff --git a/src/FlightDisplay/FlightDisplayWidget.cc b/src/FlightDisplay/FlightDisplayWidget.cc index 3b0b6e1c4..530f863c0 100644 --- a/src/FlightDisplay/FlightDisplayWidget.cc +++ b/src/FlightDisplay/FlightDisplayWidget.cc @@ -34,8 +34,8 @@ This file is part of the QGROUNDCONTROL project const char* kMainFlightDisplayWidgetGroup = "FlightDisplayWidget"; -FlightDisplayWidget::FlightDisplayWidget(QWidget *parent) - : QGCQmlWidgetHolder(parent) +FlightDisplayWidget::FlightDisplayWidget(const QString& title, QAction* action, QWidget *parent) + : QGCQmlWidgetHolder(title, action, parent) { setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setObjectName("FlightDisplayWidget"); @@ -86,6 +86,8 @@ FlightDisplayWidget::FlightDisplayWidget(QWidget *parent) setSource(QUrl::fromUserInput("qrc:/qml/FlightDisplayWidget.qml")); setVisible(true); + + loadSettings(); } FlightDisplayWidget::~FlightDisplayWidget() diff --git a/src/FlightDisplay/FlightDisplayWidget.h b/src/FlightDisplay/FlightDisplayWidget.h index bccb4dfdb..ccecbc449 100644 --- a/src/FlightDisplay/FlightDisplayWidget.h +++ b/src/FlightDisplay/FlightDisplayWidget.h @@ -30,7 +30,7 @@ class FlightDisplayWidget : public QGCQmlWidgetHolder { Q_OBJECT public: - FlightDisplayWidget(QWidget* parent = NULL); + FlightDisplayWidget(const QString& title, QAction* action, QWidget* parent = NULL); ~FlightDisplayWidget(); /// @brief Invokes the Flight Display Options menu diff --git a/src/MissionEditor/MissionEditor.cc b/src/MissionEditor/MissionEditor.cc index 44087a528..0ac950c5f 100644 --- a/src/MissionEditor/MissionEditor.cc +++ b/src/MissionEditor/MissionEditor.cc @@ -35,7 +35,7 @@ This file is part of the QGROUNDCONTROL project const char* MissionEditor::_settingsGroup = "MissionEditor"; MissionEditor::MissionEditor(QWidget *parent) - : QGCQmlWidgetHolder(parent) + : QGCQmlWidgetHolder(QString(), NULL, parent) , _missionItems(NULL) , _canEdit(true) { diff --git a/src/QGCDockWidget.cc b/src/QGCDockWidget.cc index 7fce8d785..b17cbc943 100644 --- a/src/QGCDockWidget.cc +++ b/src/QGCDockWidget.cc @@ -24,24 +24,51 @@ #include "QGCDockWidget.h" #include +#include -QGCDockWidget::QGCDockWidget(const QString& title, QAction* action, QWidget *parent, Qt::WindowFlags flags) : - QDockWidget(title, parent, flags), - _action(action) +const char* QGCDockWidget::_settingsGroup = "DockWidgets"; + +QGCDockWidget::QGCDockWidget(const QString& title, QAction* action, QWidget* parent) + : QWidget(parent) + , _title(title) + , _action(action) { - QDockWidget::DockWidgetFeatures features = QDockWidget::DockWidgetMovable; - - if (action) { - features |= QDockWidget::DockWidgetClosable; - } - setFeatures(features); + if (action) { + setWindowTitle(title); + setWindowFlags(Qt::Tool); + + loadSettings(); + } } // Instead of destroying the widget just hide it void QGCDockWidget::closeEvent(QCloseEvent* event) { - Q_ASSERT(_action); - - event->ignore(); - _action->trigger(); + if (_action) { + saveSettings(); + event->ignore(); + _action->trigger(); + } +} + +void QGCDockWidget::loadSettings(void) +{ + if (_action) { + QSettings settings; + + settings.beginGroup(_settingsGroup); + if (settings.contains(_title)) { + restoreGeometry(settings.value(_title).toByteArray()); + } + } +} + +void QGCDockWidget::saveSettings(void) +{ + if (_action) { + QSettings settings; + + settings.beginGroup(_settingsGroup); + settings.setValue(_title, saveGeometry()); + } } diff --git a/src/QGCDockWidget.h b/src/QGCDockWidget.h index 24f6e6a77..5452d1997 100644 --- a/src/QGCDockWidget.h +++ b/src/QGCDockWidget.h @@ -27,21 +27,22 @@ #include #include -/// @file -/// @brief Subclass of QDockWidget so we can intercept the closeEvent. -/// -/// @author Don Gagne - -class QGCDockWidget : public QDockWidget { +class QGCDockWidget : public QWidget { Q_OBJECT public: - QGCDockWidget(const QString& title, QAction* action, QWidget *parent = 0, Qt::WindowFlags flags = 0); + /// Pass in title = QString() and action = NULL when just using as a regular widget + QGCDockWidget(const QString& title, QAction* action, QWidget *parent = 0); + + void loadSettings(void); + void saveSettings(void); void closeEvent(QCloseEvent* event); -private: - QAction* _action; +protected: + QString _title; + QAction* _action; + static const char* _settingsGroup; }; diff --git a/src/QGCQmlWidgetHolder.cpp b/src/QGCQmlWidgetHolder.cpp index a769ea39e..ca44aea1a 100644 --- a/src/QGCQmlWidgetHolder.cpp +++ b/src/QGCQmlWidgetHolder.cpp @@ -26,10 +26,14 @@ #include "QGCQmlWidgetHolder.h" -QGCQmlWidgetHolder::QGCQmlWidgetHolder(QWidget *parent) : - QWidget(parent) +QGCQmlWidgetHolder::QGCQmlWidgetHolder(const QString& title, QAction* action, QWidget *parent) : + QGCDockWidget(title, action, parent) { _ui.setupUi(this); + + if (action) { + setWindowTitle(title); + } setResizeMode(QQuickWidget::SizeRootObjectToView); } diff --git a/src/QGCQmlWidgetHolder.h b/src/QGCQmlWidgetHolder.h index ae9907028..fa9749082 100644 --- a/src/QGCQmlWidgetHolder.h +++ b/src/QGCQmlWidgetHolder.h @@ -27,10 +27,10 @@ /// @file /// @author Don Gagne -#include +#include "QGCDockWidget.h" +#include "AutoPilotPlugin.h" #include "ui_QGCQmlWidgetHolder.h" -#include "AutoPilotPlugin.h" namespace Ui { class QGCQmlWidgetHolder; @@ -38,12 +38,16 @@ class QGCQmlWidgetHolder; /// This is used to create widgets which are implemented in QML. -class QGCQmlWidgetHolder : public QWidget +class QGCQmlWidgetHolder : public QGCDockWidget { Q_OBJECT public: - explicit QGCQmlWidgetHolder(QWidget *parent = 0); + // This has a title and action since the base class is QGCDockWidget. In order to use this + // control as a normal QWidget, not a doc widget just pass in: + // title = QString() + // action = NULL + explicit QGCQmlWidgetHolder(const QString& title, QAction* action, QWidget *parent = 0); ~QGCQmlWidgetHolder(); /// Sets the UAS into the widget which in turn will load facts into the context diff --git a/src/QmlControls/QmlTestWidget.cc b/src/QmlControls/QmlTestWidget.cc index 6afc244f6..03987b93d 100644 --- a/src/QmlControls/QmlTestWidget.cc +++ b/src/QmlControls/QmlTestWidget.cc @@ -27,6 +27,7 @@ #include "QmlTestWidget.h" QmlTestWidget::QmlTestWidget(void) + : QGCQmlWidgetHolder(QString(), NULL, NULL) { setAttribute(Qt::WA_DeleteOnClose); resize(900, 500); diff --git a/src/QmlControls/ScreenToolsController.cc b/src/QmlControls/ScreenToolsController.cc index 3e5244cbc..0b2ddf041 100644 --- a/src/QmlControls/ScreenToolsController.cc +++ b/src/QmlControls/ScreenToolsController.cc @@ -55,7 +55,7 @@ void ScreenToolsController::_updateCanvas() double ScreenToolsController::getQmlDefaultFontPixelSize(void) { if (_qmlDefaultFontPixelSize == -1) { - QGCQmlWidgetHolder qmlWidgetHolder; + QGCQmlWidgetHolder qmlWidgetHolder(QString(), NULL); qmlWidgetHolder.setSource(QUrl::fromUserInput("qrc:/qml/ScreenToolsFontQuery.qml")); } diff --git a/src/VehicleSetup/SetupView.cc b/src/VehicleSetup/SetupView.cc index 2bb35a817..90e63b161 100644 --- a/src/VehicleSetup/SetupView.cc +++ b/src/VehicleSetup/SetupView.cc @@ -41,7 +41,7 @@ #include SetupView::SetupView(QWidget* parent) : - QGCQmlWidgetHolder(parent) + QGCQmlWidgetHolder(QString(), NULL, parent) { setSource(QUrl::fromUserInput("qrc:/qml/SetupView.qml")); } diff --git a/src/ViewWidgets/CustomCommandWidget.cc b/src/ViewWidgets/CustomCommandWidget.cc index c7e5ece82..69a6c4134 100644 --- a/src/ViewWidgets/CustomCommandWidget.cc +++ b/src/ViewWidgets/CustomCommandWidget.cc @@ -23,8 +23,12 @@ This file is part of the QGROUNDCONTROL project #include "CustomCommandWidget.h" -CustomCommandWidget::CustomCommandWidget(QWidget *parent) : - QGCQmlWidgetHolder(parent) +CustomCommandWidget::CustomCommandWidget(const QString& title, QAction* action, QWidget *parent) : + QGCQmlWidgetHolder(title, action, parent) { + Q_UNUSED(title); + Q_UNUSED(action); setSource(QUrl::fromUserInput("qrc:/qml/CustomCommandWidget.qml")); + + loadSettings(); } diff --git a/src/ViewWidgets/CustomCommandWidget.h b/src/ViewWidgets/CustomCommandWidget.h index 5471d38d0..9c7197ea9 100644 --- a/src/ViewWidgets/CustomCommandWidget.h +++ b/src/ViewWidgets/CustomCommandWidget.h @@ -34,7 +34,7 @@ class CustomCommandWidget : public QGCQmlWidgetHolder Q_OBJECT public: - CustomCommandWidget(QWidget *parent = 0); + CustomCommandWidget(const QString& title, QAction* action, QWidget *parent = 0); }; #endif diff --git a/src/qgcunittest/PX4RCCalibrationTest.cc b/src/qgcunittest/PX4RCCalibrationTest.cc index e5f516029..d6c13a255 100644 --- a/src/qgcunittest/PX4RCCalibrationTest.cc +++ b/src/qgcunittest/PX4RCCalibrationTest.cc @@ -164,7 +164,7 @@ void RadioConfigTest::init(void) Q_ASSERT(_autopilot); // This will instatiate the widget with an active uas with ready parameters - _calWidget = new QGCQmlWidgetHolder(); + _calWidget = new QGCQmlWidgetHolder(QString(), NULL); _calWidget->resize(600, 600); Q_CHECK_PTR(_calWidget); _calWidget->setAutoPilot(_autopilot); diff --git a/src/ui/HILDockWidget.cc b/src/ui/HILDockWidget.cc index e10ee208e..31c609c99 100644 --- a/src/ui/HILDockWidget.cc +++ b/src/ui/HILDockWidget.cc @@ -24,10 +24,12 @@ #include "HILDockWidget.h" #include "QGCHilConfiguration.h" -HILDockWidget::HILDockWidget(QWidget *parent) - : MultiVehicleDockWidget(parent) +HILDockWidget::HILDockWidget(const QString& title, QAction* action, QWidget *parent) + : MultiVehicleDockWidget(title, action, parent) { init(); + + loadSettings(); } HILDockWidget::~HILDockWidget() diff --git a/src/ui/HILDockWidget.h b/src/ui/HILDockWidget.h index d8e8073ac..8194882c5 100644 --- a/src/ui/HILDockWidget.h +++ b/src/ui/HILDockWidget.h @@ -31,7 +31,7 @@ class HILDockWidget : public MultiVehicleDockWidget Q_OBJECT public: - explicit HILDockWidget(QWidget *parent = 0); + explicit HILDockWidget(const QString& title, QAction* action, QWidget *parent = 0); ~HILDockWidget(); protected: diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 18c414c4c..0a7fd1ad7 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -88,14 +88,15 @@ This file is part of the QGROUNDCONTROL project const char* MAIN_SETTINGS_GROUP = "QGC_MAINWINDOW"; #ifndef __mobile__ -const char* MainWindow::_mavlinkDockWidgetName = "MAVLINK_INSPECTOR_DOCKWIDGET"; -const char* MainWindow::_customCommandWidgetName = "CUSTOM_COMMAND_DOCKWIDGET"; -const char* MainWindow::_filesDockWidgetName = "FILE_VIEW_DOCKWIDGET"; -const char* MainWindow::_uasStatusDetailsDockWidgetName = "UAS_STATUS_DETAILS_DOCKWIDGET"; -const char* MainWindow::_mapViewDockWidgetName = "MAP_VIEW_DOCKWIDGET"; -const char* MainWindow::_pfdDockWidgetName = "PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET"; -const char* MainWindow::_uasInfoViewDockWidgetName = "UAS_INFO_INFOVIEW_DOCKWIDGET"; -const char* MainWindow::_hilDockWidgetName = "HIL_DOCKWIDGET"; +const char* MainWindow::_mavlinkDockWidgetName = "MAVLink Inspector"; +const char* MainWindow::_customCommandWidgetName = "Custom Command"; +const char* MainWindow::_filesDockWidgetName = "Onboard Files"; +const char* MainWindow::_uasStatusDetailsDockWidgetName = "Status Details"; +const char* MainWindow::_pfdDockWidgetName = "Primary Flight Display"; +const char* MainWindow::_uasInfoViewDockWidgetName = "Info View"; +const char* MainWindow::_hilDockWidgetName = "HIL Config"; + +const char* MainWindow::_visibleWidgetsKey = "VisibleWidgets"; #endif static MainWindow* _instance = NULL; ///< @brief MainWindow singleton @@ -313,6 +314,10 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) qd.close(); #endif } + +#ifndef __mobile__ + _loadVisibleWidgetsSettings(); +#endif } MainWindow::~MainWindow() @@ -341,34 +346,6 @@ QString MainWindow::_getWindowGeometryKey() } #ifndef __mobile__ -void MainWindow::_createDockWidget(const QString& title, const QString& name, Qt::DockWidgetArea area, QWidget* innerWidget) -{ - Q_ASSERT(!_mapName2DockWidget.contains(name)); - - // Add to menu - QAction* action = new QAction(title, NULL); - action->setCheckable(true); - action->setData(name); - connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction); - _ui.menuWidgets->addAction(action); - - // Create widget - QGCDockWidget* dockWidget = new QGCDockWidget(title, action, this); - Q_CHECK_PTR(dockWidget); - dockWidget->setObjectName(name); - dockWidget->setVisible (false); - if (innerWidget) { - // Put inner widget inside QDockWidget - innerWidget->setParent(dockWidget); - dockWidget->setWidget(innerWidget); - innerWidget->setVisible(true); - } - - _mapName2DockWidget[name] = dockWidget; - _mapDockWidget2Action[dockWidget] = action; - addDockWidget(area, dockWidget); -} - void MainWindow::_buildCommonWidgets(void) { // Add generic MAVLink decoder @@ -382,99 +359,80 @@ void MainWindow::_buildCommonWidgets(void) logPlayer = new QGCMAVLinkLogPlayer(statusBar()); statusBar()->addPermanentWidget(logPlayer); - // In order for Qt to save and restore state of widgets all widgets must be created ahead of time. We only create the QDockWidget - // holders. We do not create the actual inner widget until it is needed. This saves memory and cpu from running widgets that are - // never shown. - - struct DockWidgetInfo { - const char* name; - const char* title; - Qt::DockWidgetArea area; - }; - - static const struct DockWidgetInfo rgDockWidgetInfo[] = { - { _mavlinkDockWidgetName, "MAVLink Inspector", Qt::RightDockWidgetArea }, - { _customCommandWidgetName, "Custom Command", Qt::RightDockWidgetArea }, - { _filesDockWidgetName, "Onboard Files", Qt::RightDockWidgetArea }, - { _uasStatusDetailsDockWidgetName, "Status Details", Qt::RightDockWidgetArea }, - { _mapViewDockWidgetName, "Map view", Qt::RightDockWidgetArea }, - { _pfdDockWidgetName, "Primary Flight Display", Qt::RightDockWidgetArea }, - { _uasInfoViewDockWidgetName, "Info View", Qt::LeftDockWidgetArea }, - { _hilDockWidgetName, "HIL Config", Qt::LeftDockWidgetArea }, + static const char* rgDockWidgetNames[] = { + _mavlinkDockWidgetName, + _customCommandWidgetName, + _filesDockWidgetName, + _uasStatusDetailsDockWidgetName, + _pfdDockWidgetName, + _uasInfoViewDockWidgetName, + _hilDockWidgetName, }; - static const size_t cDockWidgetInfo = sizeof(rgDockWidgetInfo) / sizeof(rgDockWidgetInfo[0]); + static const size_t cDockWidgetNames = sizeof(rgDockWidgetNames) / sizeof(rgDockWidgetNames[0]); - for (size_t i=0; ititle, pDockInfo->name, pDockInfo->area, NULL /* no inner widget yet */); + for (size_t i=0; isetCheckable(true); + action->setData(pDockWidgetName); + connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction); + _ui.menuWidgets->addAction(action); + + _mapName2Action[pDockWidgetName] = action; } } /// Shows or hides the specified dock widget, creating if necessary void MainWindow::_showDockWidget(const QString& name, bool show) { - if (!_mapName2DockWidget.contains(name)) { - // Don't show any sort of warning here. Dock Widgets which have been remove could still be in settings. - // Which would cause us to end up here. - return; - } - // Create the inner widget if we need to - if (!_mapName2DockWidget[name]->widget()) { + if (!_mapName2DockWidget.contains(name)) { _createInnerDockWidget(name); } Q_ASSERT(_mapName2DockWidget.contains(name)); - QDockWidget* dockWidget = _mapName2DockWidget[name]; + QGCDockWidget* dockWidget = _mapName2DockWidget[name]; Q_ASSERT(dockWidget); dockWidget->setVisible(show); - Q_ASSERT(_mapDockWidget2Action.contains(dockWidget)); - _mapDockWidget2Action[dockWidget]->setChecked(show); + Q_ASSERT(_mapName2Action.contains(name)); + _mapName2Action[name]->setChecked(show); } /// Creates the specified inner dock widget and adds to the QDockWidget void MainWindow::_createInnerDockWidget(const QString& widgetName) { - Q_ASSERT(_mapName2DockWidget.contains(widgetName)); // QDockWidget should already exist - Q_ASSERT(!_mapName2DockWidget[widgetName]->widget()); // Inner widget should not - - QWidget* widget = NULL; + QGCDockWidget* widget = NULL; if (widgetName == _mavlinkDockWidgetName) { - widget = new QGCMAVLinkInspector(MAVLinkProtocol::instance(),this); + widget = new QGCMAVLinkInspector(widgetName, _mapName2Action[widgetName], MAVLinkProtocol::instance(),this); } else if (widgetName == _customCommandWidgetName) { - widget = new CustomCommandWidget(this); + widget = new CustomCommandWidget(widgetName, _mapName2Action[widgetName], this); } else if (widgetName == _filesDockWidgetName) { - widget = new QGCUASFileViewMulti(this); + widget = new QGCUASFileViewMulti(widgetName, _mapName2Action[widgetName], this); } else if (widgetName == _uasStatusDetailsDockWidgetName) { - widget = new UASInfoWidget(this); + widget = new UASInfoWidget(widgetName, _mapName2Action[widgetName], this); } else if (widgetName == _pfdDockWidgetName) { - widget = new FlightDisplayWidget(this); -#ifndef __mobile__ + widget = new FlightDisplayWidget(widgetName, _mapName2Action[widgetName], this); } else if (widgetName == _hilDockWidgetName) { - widget = new HILDockWidget(this); -#endif + widget = new HILDockWidget(widgetName, _mapName2Action[widgetName], this); } else if (widgetName == _uasInfoViewDockWidgetName) { - QGCTabbedInfoView* pInfoView = new QGCTabbedInfoView(this); + QGCTabbedInfoView* pInfoView = new QGCTabbedInfoView(widgetName, _mapName2Action[widgetName], this); pInfoView->addSource(mavlinkDecoder); widget = pInfoView; } else { qWarning() << "Attempt to create unknown Inner Dock Widget" << widgetName; } - if (widget) { - QDockWidget* dockWidget = _mapName2DockWidget[widgetName]; - Q_CHECK_PTR(dockWidget); - widget->setParent(dockWidget); - dockWidget->setWidget(widget); - } + _mapName2DockWidget[widgetName] = widget; } void MainWindow::_hideAllDockWidgets(void) { - foreach(QDockWidget* dockWidget, _mapName2DockWidget) { + foreach(QGCDockWidget* dockWidget, _mapName2DockWidget) { dockWidget->setVisible(false); } } @@ -483,7 +441,7 @@ void MainWindow::_showDockWidgetAction(bool show) { QAction* action = dynamic_cast(QObject::sender()); Q_ASSERT(action); - _showDockWidget(action->data().toString(), show); + _showDockWidget(action->text(), show); } #endif @@ -592,6 +550,10 @@ void MainWindow::storeSettings() // Save the last current view in any case settings.setValue("CURRENT_VIEW", _currentView); settings.setValue(_getWindowStateKey(), saveState()); + +#ifndef __mobile__ + _storeVisibleWidgetsSettings(); +#endif } void MainWindow::configureWindowName() @@ -751,20 +713,11 @@ void MainWindow::_vehicleAdded(Vehicle* vehicle) void MainWindow::_storeCurrentViewState(void) { #ifndef __mobile__ - // Save list of visible widgets - bool firstWidget = true; - QString widgetNames = ""; - foreach(QDockWidget* dockWidget, _mapName2DockWidget) { - if (dockWidget->isVisible()) { - if (!firstWidget) { - widgetNames += ","; - } - widgetNames += dockWidget->objectName(); - firstWidget = false; - } + foreach(QGCDockWidget* dockWidget, _mapName2DockWidget) { + dockWidget->saveSettings(); } - settings.setValue(_getWindowStateKey() + "WIDGETS", widgetNames); #endif + settings.setValue(_getWindowStateKey(), saveState()); settings.setValue(_getWindowGeometryKey(), saveGeometry()); } @@ -773,7 +726,6 @@ void MainWindow::_storeCurrentViewState(void) void MainWindow::_loadCurrentViewState(void) { QWidget* centerView = NULL; - QString defaultWidgets; switch (_currentView) { case VIEW_SETUP: @@ -784,13 +736,11 @@ void MainWindow::_loadCurrentViewState(void) case VIEW_ANALYZE: _buildAnalyzeView(); centerView = _analyzeView; - defaultWidgets = "PARAMETER_INTERFACE_DOCKWIDGET,FILE_VIEW_DOCKWIDGET"; break; case VIEW_FLIGHT: _buildFlightView(); centerView = _flightView; - defaultWidgets = "COMMUNICATION_CONSOLE_DOCKWIDGET,UAS_INFO_INFOVIEW_DOCKWIDGET"; break; case VIEW_MISSIONEDITOR: @@ -820,22 +770,6 @@ void MainWindow::_loadCurrentViewState(void) _centralLayout->setContentsMargins(0, 0, 0, 0); _currentViewWidget->setVisible(true); -#ifndef __mobile__ - // Hide all widgets from previous view - _hideAllDockWidgets(); - - // Restore the widgets for the new view - QString widgetNames = settings.value(_getWindowStateKey() + "WIDGETS", defaultWidgets).toString(); - qDebug() << widgetNames; - if (!widgetNames.isEmpty()) { - QStringList split = widgetNames.split(","); - foreach (QString widgetName, split) { - Q_ASSERT(!widgetName.isEmpty()); - _showDockWidget(widgetName, true); - } - } -#endif - if (settings.contains(_getWindowStateKey())) { restoreState(settings.value(_getWindowStateKey()).toByteArray()); } @@ -949,3 +883,42 @@ void MainWindow::_showQmlTestWidget(void) new QmlTestWidget(); } #endif + +#ifndef __mobile__ +void MainWindow::_loadVisibleWidgetsSettings(void) +{ + QSettings settings; + + QString widgets = settings.value(_visibleWidgetsKey).toString(); + + if (!widgets.isEmpty()) { + QStringList nameList = widgets.split(","); + + foreach (QString name, nameList) { + _showDockWidget(name, true); + } + } +} + +void MainWindow::_storeVisibleWidgetsSettings(void) +{ + QString widgetNames; + bool firstWidget = true; + + foreach (QString name, _mapName2DockWidget.keys()) { + if (_mapName2DockWidget[name]->isVisible()) { + if (!firstWidget) { + widgetNames += ","; + } else { + firstWidget = false; + } + + widgetNames += name; + } + } + + QSettings settings; + + settings.setValue(_visibleWidgetsKey, widgetNames); +} +#endif diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index da1e2de63..0261b56b1 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -35,24 +35,26 @@ This file is part of the QGROUNDCONTROL project #include #include #include -#include +#include #include "ui_MainWindow.h" #include "LinkManager.h" #include "LinkInterface.h" #include "UASInterface.h" #include "CameraView.h" -#if (defined QGC_MOUSE_ENABLED_WIN) | (defined QGC_MOUSE_ENABLED_LINUX) -#include "Mouse6dofInput.h" -#endif // QGC_MOUSE_ENABLED_WIN #include "MainToolBar.h" #include "LogCompressor.h" - #include "FlightDisplayView.h" #include "QGCMAVLinkInspector.h" #include "QGCMAVLinkLogPlayer.h" #include "MAVLinkDecoder.h" #include "Vehicle.h" +#include "QGCDockWidget.h" + +#if (defined QGC_MOUSE_ENABLED_WIN) | (defined QGC_MOUSE_ENABLED_LINUX) + #include "Mouse6dofInput.h" +#endif // QGC_MOUSE_ENABLED_WIN + class QGCFirmwareUpdate; class QSplashScreen; @@ -270,13 +272,12 @@ private: static const char* _customCommandWidgetName; static const char* _filesDockWidgetName; static const char* _uasStatusDetailsDockWidgetName; - static const char* _mapViewDockWidgetName; static const char* _pfdDockWidgetName; static const char* _uasInfoViewDockWidgetName; static const char* _hilDockWidgetName; - QMap _mapName2DockWidget; - QMap _mapDockWidget2Action; + QMap _mapName2DockWidget; + QMap _mapName2Action; #endif void _buildPlanView(void); @@ -290,11 +291,14 @@ private: void _loadCurrentViewState(void); #ifndef __mobile__ - void _createDockWidget(const QString& title, const QString& name, Qt::DockWidgetArea area, QWidget* innerWidget); void _createInnerDockWidget(const QString& widgetName); void _buildCommonWidgets(void); void _hideAllDockWidgets(void); void _showDockWidget(const QString &name, bool show); + void _loadVisibleWidgetsSettings(void); + void _storeVisibleWidgetsSettings(void); + + static const char* _visibleWidgetsKey; #endif bool _autoReconnect; diff --git a/src/ui/MultiVehicleDockWidget.cc b/src/ui/MultiVehicleDockWidget.cc index 6d788e44c..3f5e82fbc 100644 --- a/src/ui/MultiVehicleDockWidget.cc +++ b/src/ui/MultiVehicleDockWidget.cc @@ -25,12 +25,14 @@ #include "ui_MultiVehicleDockWidget.h" #include "MultiVehicleManager.h" -MultiVehicleDockWidget::MultiVehicleDockWidget(QWidget *parent) - : QWidget(parent) +MultiVehicleDockWidget::MultiVehicleDockWidget(const QString& title, QAction* action, QWidget *parent) + : QGCDockWidget(title, action, parent) , _ui(new Ui::MultiVehicleDockWidget) { _ui->setupUi(this); + setWindowTitle(title); + connect(MultiVehicleManager::instance(), &MultiVehicleManager::activeVehicleChanged, this, &MultiVehicleDockWidget::_activeVehicleChanged); connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleAdded, this, &MultiVehicleDockWidget::_vehicleAdded); connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleRemoved, this, &MultiVehicleDockWidget::_vehicleRemoved); diff --git a/src/ui/MultiVehicleDockWidget.h b/src/ui/MultiVehicleDockWidget.h index a78be28a6..49f73dda7 100644 --- a/src/ui/MultiVehicleDockWidget.h +++ b/src/ui/MultiVehicleDockWidget.h @@ -24,9 +24,9 @@ #ifndef MultiVehicleDockWidget_H #define MultiVehicleDockWidget_H -#include #include +#include "QGCDockWidget.h" #include "Vehicle.h" namespace Ui @@ -37,12 +37,12 @@ namespace Ui /// Provides a base class for a dock widget which automatically handles /// Vehicles coming and going. It does this by using a stacked widget which /// holds individual Vehicle specific widgets. -class MultiVehicleDockWidget : public QWidget +class MultiVehicleDockWidget : public QGCDockWidget { Q_OBJECT public: - explicit MultiVehicleDockWidget(QWidget *parent = 0); + explicit MultiVehicleDockWidget(const QString& title, QAction* action, QWidget *parent = 0); ~MultiVehicleDockWidget(); /// Must be called in the derived class contructor to initialize the base class diff --git a/src/ui/QGCHilConfiguration.ui b/src/ui/QGCHilConfiguration.ui index 8da9ad667..f80a307e3 100644 --- a/src/ui/QGCHilConfiguration.ui +++ b/src/ui/QGCHilConfiguration.ui @@ -17,7 +17,7 @@ - Form + HIL Config diff --git a/src/ui/QGCMAVLinkInspector.cc b/src/ui/QGCMAVLinkInspector.cc index fd5c01f65..2f1616301 100644 --- a/src/ui/QGCMAVLinkInspector.cc +++ b/src/ui/QGCMAVLinkInspector.cc @@ -12,8 +12,8 @@ const float QGCMAVLinkInspector::updateHzLowpass = 0.2f; const unsigned int QGCMAVLinkInspector::updateInterval = 1000U; -QGCMAVLinkInspector::QGCMAVLinkInspector(MAVLinkProtocol* protocol, QWidget *parent) : - QWidget(parent), +QGCMAVLinkInspector::QGCMAVLinkInspector(const QString& title, QAction* action, MAVLinkProtocol* protocol, QWidget *parent) : + QGCDockWidget(title, action, parent), _protocol(protocol), selectedSystemID(0), selectedComponentID(0), @@ -58,6 +58,8 @@ QGCMAVLinkInspector::QGCMAVLinkInspector(MAVLinkProtocol* protocol, QWidget *par // Attach the UI's refresh rate to a timer. connect(&updateTimer, SIGNAL(timeout()), this, SLOT(refreshView())); updateTimer.start(updateInterval); + + loadSettings(); } void QGCMAVLinkInspector::_vehicleAdded(Vehicle* vehicle) diff --git a/src/ui/QGCMAVLinkInspector.h b/src/ui/QGCMAVLinkInspector.h index 3c5a154b1..c1be7c4b8 100644 --- a/src/ui/QGCMAVLinkInspector.h +++ b/src/ui/QGCMAVLinkInspector.h @@ -1,10 +1,10 @@ #ifndef QGCMAVLINKINSPECTOR_H #define QGCMAVLINKINSPECTOR_H -#include #include #include +#include "QGCDockWidget.h" #include "MAVLinkProtocol.h" #include "Vehicle.h" @@ -15,12 +15,12 @@ namespace Ui { class QTreeWidgetItem; class UASInterface; -class QGCMAVLinkInspector : public QWidget +class QGCMAVLinkInspector : public QGCDockWidget { Q_OBJECT public: - explicit QGCMAVLinkInspector(MAVLinkProtocol* protocol, QWidget *parent = 0); + explicit QGCMAVLinkInspector(const QString& title, QAction* action, MAVLinkProtocol* protocol, QWidget *parent = 0); ~QGCMAVLinkInspector(); public slots: diff --git a/src/ui/QGCMAVLinkInspector.ui b/src/ui/QGCMAVLinkInspector.ui index acff603ea..ab42ff309 100644 --- a/src/ui/QGCMAVLinkInspector.ui +++ b/src/ui/QGCMAVLinkInspector.ui @@ -11,7 +11,7 @@ - Form + MAVLink Inspector diff --git a/src/ui/QGCTabbedInfoView.cpp b/src/ui/QGCTabbedInfoView.cpp index 6940111ee..0b06f4a07 100644 --- a/src/ui/QGCTabbedInfoView.cpp +++ b/src/ui/QGCTabbedInfoView.cpp @@ -1,6 +1,7 @@ #include "QGCTabbedInfoView.h" -QGCTabbedInfoView::QGCTabbedInfoView(QWidget *parent) : QWidget(parent) +QGCTabbedInfoView::QGCTabbedInfoView(const QString& title, QAction* action, QWidget *parent) + : QGCDockWidget(title, action, parent) { ui.setupUi(this); messageView = new UASMessageViewWidget(this); @@ -11,6 +12,8 @@ QGCTabbedInfoView::QGCTabbedInfoView(QWidget *parent) : QWidget(parent) //ui.tabWidget->addTab(actionsWidget,"Actions"); //ui.tabWidget->addTab(rawView,"Status"); ui.tabWidget->addTab(messageView,"Messages"); + + loadSettings(); } void QGCTabbedInfoView::addSource(MAVLinkDecoder *decoder) { diff --git a/src/ui/QGCTabbedInfoView.h b/src/ui/QGCTabbedInfoView.h index 57ea549f2..f14c5ed5f 100644 --- a/src/ui/QGCTabbedInfoView.h +++ b/src/ui/QGCTabbedInfoView.h @@ -1,18 +1,20 @@ #ifndef QGCTABBEDINFOVIEW_H #define QGCTABBEDINFOVIEW_H -#include -#include "ui_QGCTabbedInfoView.h" +#include "QGCDockWidget.h" #include "MAVLinkDecoder.h" #include "UASMessageView.h" #include "UASQuickView.h" #include "UASRawStatusView.h" -class QGCTabbedInfoView : public QWidget + +#include "ui_QGCTabbedInfoView.h" + +class QGCTabbedInfoView : public QGCDockWidget { Q_OBJECT public: - explicit QGCTabbedInfoView(QWidget *parent = 0); + explicit QGCTabbedInfoView(const QString& title, QAction* action, QWidget *parent = 0); ~QGCTabbedInfoView(); void addSource(MAVLinkDecoder *decoder); private: diff --git a/src/ui/QGCTabbedInfoView.ui b/src/ui/QGCTabbedInfoView.ui index fbc8809ba..ad8ae5ca9 100644 --- a/src/ui/QGCTabbedInfoView.ui +++ b/src/ui/QGCTabbedInfoView.ui @@ -11,7 +11,7 @@ - Form + Info View diff --git a/src/ui/QGCUASFileViewMulti.cc b/src/ui/QGCUASFileViewMulti.cc index a8b715e62..3455d3e60 100644 --- a/src/ui/QGCUASFileViewMulti.cc +++ b/src/ui/QGCUASFileViewMulti.cc @@ -4,8 +4,8 @@ #include "MultiVehicleManager.h" #include "QGCUASFileView.h" -QGCUASFileViewMulti::QGCUASFileViewMulti(QWidget *parent) : - QWidget(parent), +QGCUASFileViewMulti::QGCUASFileViewMulti(const QString& title, QAction* action, QWidget *parent) : + QGCDockWidget(title, action, parent), ui(new Ui::QGCUASFileViewMulti) { ui->setupUi(this); @@ -18,6 +18,8 @@ QGCUASFileViewMulti::QGCUASFileViewMulti(QWidget *parent) : _vehicleAdded(MultiVehicleManager::instance()->activeVehicle()); _activeVehicleChanged(MultiVehicleManager::instance()->activeVehicle()); } + + loadSettings(); } void QGCUASFileViewMulti::_vehicleRemoved(Vehicle* vehicle) diff --git a/src/ui/QGCUASFileViewMulti.h b/src/ui/QGCUASFileViewMulti.h index 5cb89da83..eedc93695 100644 --- a/src/ui/QGCUASFileViewMulti.h +++ b/src/ui/QGCUASFileViewMulti.h @@ -1,9 +1,9 @@ #ifndef QGCUASFILEVIEWMULTI_H #define QGCUASFILEVIEWMULTI_H -#include #include +#include "QGCDockWidget.h" #include "QGCUASFileView.h" #include "UAS.h" @@ -12,12 +12,12 @@ namespace Ui class QGCUASFileViewMulti; } -class QGCUASFileViewMulti : public QWidget +class QGCUASFileViewMulti : public QGCDockWidget { Q_OBJECT public: - explicit QGCUASFileViewMulti(QWidget *parent = 0); + explicit QGCUASFileViewMulti(const QString& title, QAction* action, QWidget *parent = 0); ~QGCUASFileViewMulti(); protected: diff --git a/src/ui/QGCUASFileViewMulti.ui b/src/ui/QGCUASFileViewMulti.ui index 547cfd4db..3b42db2c8 100644 --- a/src/ui/QGCUASFileViewMulti.ui +++ b/src/ui/QGCUASFileViewMulti.ui @@ -11,7 +11,7 @@ - Form + Onboard Files diff --git a/src/ui/UASInfo.ui b/src/ui/UASInfo.ui index 0912c7fa4..7f9503f9b 100644 --- a/src/ui/UASInfo.ui +++ b/src/ui/UASInfo.ui @@ -11,7 +11,7 @@ - Form + Status Details diff --git a/src/ui/toolbar/MainToolBar.cc b/src/ui/toolbar/MainToolBar.cc index f837b64c3..b997d1ad7 100644 --- a/src/ui/toolbar/MainToolBar.cc +++ b/src/ui/toolbar/MainToolBar.cc @@ -41,7 +41,7 @@ This file is part of the QGROUNDCONTROL project #include "UAS.h" MainToolBar::MainToolBar(QWidget* parent) - : QGCQmlWidgetHolder(parent) + : QGCQmlWidgetHolder(QString(), NULL, parent) , _vehicle(NULL) , _mav(NULL) , _toolBar(NULL) diff --git a/src/ui/uas/UASInfoWidget.cc b/src/ui/uas/UASInfoWidget.cc index 18e954c5a..c9f06d6af 100644 --- a/src/ui/uas/UASInfoWidget.cc +++ b/src/ui/uas/UASInfoWidget.cc @@ -43,7 +43,8 @@ This file is part of the PIXHAWK project #include "QGC.h" #include "UAS.h" -UASInfoWidget::UASInfoWidget(QWidget *parent, QString name) : QWidget(parent) +UASInfoWidget::UASInfoWidget(const QString& title, QAction* action, QWidget *parent, QString name) + : QGCDockWidget(title, action, parent) { ui.setupUi(this); this->name = name; @@ -72,6 +73,8 @@ UASInfoWidget::UASInfoWidget(QWidget *parent, QString name) : QWidget(parent) updateTimer->start(updateInterval); this->setVisible(false); + + loadSettings(); } UASInfoWidget::~UASInfoWidget() diff --git a/src/ui/uas/UASInfoWidget.h b/src/ui/uas/UASInfoWidget.h index 95ac958af..a7bd66616 100644 --- a/src/ui/uas/UASInfoWidget.h +++ b/src/ui/uas/UASInfoWidget.h @@ -32,10 +32,10 @@ This file is part of the QGROUNDCONTROL project #ifndef _UASINFOWIDGET_H_ #define _UASINFOWIDGET_H_ -#include #include #include +#include "QGCDockWidget.h" #include "UASInterface.h" #include "ui_UASInfo.h" #include "Vehicle.h" @@ -44,11 +44,11 @@ This file is part of the QGROUNDCONTROL project * @brief Info indicator for the currently active UAS * **/ -class UASInfoWidget : public QWidget +class UASInfoWidget : public QGCDockWidget { Q_OBJECT public: - UASInfoWidget(QWidget *parent = 0, QString name = ""); + UASInfoWidget(const QString& title, QAction* action, QWidget *parent = 0, QString name = ""); ~UASInfoWidget(); public slots: -- 2.22.0