diff --git a/QGCApplication.pro b/QGCApplication.pro index 08f0eeedd77d57bad01e6a1f90571ca39a678e11..2ceff3dc7153e11220da2a5351115477c9c34903 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 8b19e357ec4a743635991f74e44426d28db4cf2c..2d4d4cec87cddbb9a30d2cd652dcb3e36ae7bae8 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 3b0b6e1c44071602e0ec2ed18f983550d232c2cb..530f863c02be1d6e49a67331ac810242c7485f79 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 bccb4dfdbaa5e4b795278ebae5be3ed2f4b52c2d..ccecbc449a523a7b18d49123fccaefd13b4b87ef 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 44087a5289aec6c5e5630978dc3768dc50caa07b..0ac950c5fafa5bcab408b26ca7e872884b743fdd 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 7fce8d78564fcb092879e10f12a7bd5c2ae5f9da..b17cbc943399f010de9d401cf5ce8dea7d5468df 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 24f6e6a771a46010745f7306191ee12e9ca2caf9..5452d19973bcba2ac67c0147469a21fd819a20f1 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 a769ea39e69d8ea1f566df4306cded44f69d99d1..ca44aea1a464b4b9ff58e7b3c54ca06e10f87f99 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 ae99070283fafdd6ca5e37902342f32fa69a1e92..fa974908281b69b307bfdbf4ff44321eb5eda140 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 6afc244f66f971409a6527aa5ef0060e62106324..03987b93d32303b8b6a724eb7e0a0ce281ac8928 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 3e5244cbcc9d759798d86891ff3d307588436f15..0b2ddf041b7aa916ed08ff65d4a6bb903a01cab2 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 2bb35a81791de8d8fe269d88e441e495ee439276..90e63b1619e280847e657bfde0ad534a360964a4 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 c7e5ece821d2022c9888f7030772f5fbebd6a0a5..69a6c4134918564d1457d93bc570c8878cd26e65 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 5471d38d069dc8cb74a1bed68076d7db8f5f724f..9c7197ea96e8587514ef718a039ca5f9b92ebb14 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 e5f5160297d31ddff6051084e3affab6cf55a274..d6c13a2555a7ed508f5073954035bcb82807e159 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 e10ee208e1326a579424897a86237470de04942b..31c609c99481f405614fbf49a7d085ecf6573c5a 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 d8e8073acf9898d13855aa0afed3a81608fcf1c1..8194882c5efac10c4d28d20d282f2e8e8d5ced9e 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 18c414c4cf85dcac3f596e5a45924ab33fb7dddb..0a7fd1ad73d4d6ccfd85bdc33282476a64d9ea04 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 da1e2de63712aabb89433f0bf4646e7858e35bc2..0261b56b13a8611e8e28d65b9cf05a61119af136 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 6d788e44c82490658baa07e65b15812d37a6f5f6..3f5e82fbcc07454cd3f5dde3d29e69714f693a5b 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 a78be28a6e99a1f824489e58c9e7e9e77c48c7e6..49f73dda7273a4c42efc0866bed2cd35a6aa2587 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 8da9ad667bf99458144e621b9eba2f211b95db14..f80a307e3bae1cab6d28f8a7c93eb9b0998e7b9f 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 fd5c01f65b2dffd558cc038e2bb043d87d60e23d..2f1616301a1e5c946353573b0d77d059b7d40101 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 3c5a154b1785470d5b690c5891dff905aa0809bb..c1be7c4b88659cde723ed080169188841b766f54 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 acff603eaa3d89c05d5252fe6f133807ff879eab..ab42ff309a3048d37a4356968641fd0e200d6988 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 6940111eea57c39a3e479a05e062576c0fd95f36..0b06f4a07b643a55c7823a765a1c34b8e2af7f20 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 57ea549f2700a2d3dfbe3e169ce7e29679c53d05..f14c5ed5fa7c52e96337ab3838d5cdcf4c914761 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 fbc8809bafaf7602d8ef985f2ddc3bb386fa599c..ad8ae5ca9e34ae06cf11f832a751f884f496c60b 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 a8b715e625152ee12d4595f7051e5f54bd368b77..3455d3e60eb4cbfd7bfaa361c098ed34687669ad 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 5cb89da833412c4926bba4f9a3c1422e257bf3cc..eedc93695cc389a34b4b3d5d68168196f07eb765 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 547cfd4dbfc7bcd2804f80084d9ad76823175837..3b42db2c8d22c2fc5bcaa45d17443d8ed3ca3ed4 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 0912c7fa41bdda4f89eb55dd189777512cf01f2d..7f9503f9b29804cbf5a552bb51baf466f8115a23 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 f837b64c351b5c5b0466e59d4578cef552a50aed..b997d1ad7e222875e5f9e1cecc6ef64709b42a6d 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 18e954c5a668ba2567d9f9ef255f974dc3d4ff11..c9f06d6af5a78237b1c039f86e108b8f70b4faf1 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 95ac958af3ce2c4e1552ba795681c71a4188ed38..a7bd66616fa2dd18bf40cb3c8a0ac6c2f54b89f2 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: