From fc90eecd813165ded314ae06408387d2e0efe029 Mon Sep 17 00:00:00 2001 From: LM Date: Thu, 8 Sep 2011 10:26:42 +0200 Subject: [PATCH] Fixed window state initialization --- src/QGCCore.cc | 2 +- .../mavlinkgen/ui/XMLCommProtocolWidget.h | 16 +++ src/uas/UASInterface.h | 56 ++++++++- src/ui/HUD.cc | 4 +- src/ui/HUD.h | 3 + src/ui/MainWindow.cc | 110 ++++++++++++------ src/ui/MainWindow.h | 24 ++-- src/ui/QGCDataPlot2D.h | 15 +++ src/ui/designer/QGCToolWidget.cc | 7 +- src/ui/designer/QGCToolWidget.h | 2 +- src/ui/linechart/Linecharts.cc | 35 +++--- src/ui/linechart/Linecharts.h | 2 + src/ui/map/QGCMapTool.h | 16 +++ src/ui/map3D/QGCGoogleEarthView.cc | 13 ++- src/ui/map3D/QGCGoogleEarthView.h | 3 + 15 files changed, 230 insertions(+), 78 deletions(-) diff --git a/src/QGCCore.cc b/src/QGCCore.cc index ca6bf0c9af..f0ab2fba01 100644 --- a/src/QGCCore.cc +++ b/src/QGCCore.cc @@ -204,7 +204,7 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv) QGCCore::~QGCCore() { //mainWindow->storeSettings(); - mainWindow->hide(); + mainWindow->close(); mainWindow->deleteLater(); // Delete singletons delete LinkManager::instance(); diff --git a/src/apps/mavlinkgen/ui/XMLCommProtocolWidget.h b/src/apps/mavlinkgen/ui/XMLCommProtocolWidget.h index 5faecda723..0ad3fcc93a 100644 --- a/src/apps/mavlinkgen/ui/XMLCommProtocolWidget.h +++ b/src/apps/mavlinkgen/ui/XMLCommProtocolWidget.h @@ -66,6 +66,22 @@ protected: DomModel* model; void changeEvent(QEvent *e); +signals: + void visibilityChanged(bool visible); + +protected: + void showEvent(QShowEvent* event) + { + QWidget::showEvent(event); + emit visibilityChanged(true); + } + + void hideEvent(QHideEvent* event) + { + QWidget::hideEvent(event); + emit visibilityChanged(false); + } + private: Ui::XMLCommProtocolWidget *m_ui; }; diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index 0789d7c1f6..18a2d02915 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -176,14 +176,64 @@ public: /** @brief Get the type of the system (airplane, quadrotor, helicopter,..)*/ virtual int getSystemType() = 0; + /** @brief Get the type of the autopilot (PIXHAWK, APM, UDB, PPZ,..) */ + virtual int getAutopilotType() = 0; + virtual void setAutopilotType(int apType)= 0; + + QString getSystemTypeString(int type) + { + switch (type) + { + default: + case 0: + return "MAV_TYPE_GENERIC"; + case 1: + return "MAV_TYPE_FIXED_WING"; + case 2: + return "MAV_TYPE_QUADROTOR"; + case 3: + return "MAV_TYPE_COAXIAL"; + case 4: + return "MAV_TYPE_HELICOPTER"; + case 5: + return "MAV_TYPE_GROUND"; + case 6: + return "MAV_TYPE_GCS"; + case 7: + return "MAV_TYPE_AIRSHIP"; + case 8: + return "MAV_TYPE_FREE_BALLOON"; + case 9: + return "MAV_TYPE_ROCKET"; + case 10: + return "MAV_TYPE_UGV_GROUND_ROVER"; + case 11: + return "MAV_TYPE_UGV_SURFACE_SHIP"; + } + } + + QString getAutopilotTypeString(int type) + { + switch (type) + { + default: + case 0: + return "MAV_AUTOPILOT_GENERIC"; + case 1: + return "MAV_AUTOPILOT_PIXHAWK"; + case 2: + return "MAV_AUTOPILOT_SLUGS"; + case 3: + return "MAV_AUTOPILOT_ARDUPILOTMEGA"; + case 4: + return "MAV_AUTOPILOT_OPENPILOT"; + } + } QColor getColor() { return color; } - virtual int getAutopilotType() = 0; - virtual void setAutopilotType(int apType)= 0; - public slots: /** @brief Set a new name for the system */ diff --git a/src/ui/HUD.cc b/src/ui/HUD.cc index d5bf4bf0a8..780795b7e1 100644 --- a/src/ui/HUD.cc +++ b/src/ui/HUD.cc @@ -200,14 +200,16 @@ void HUD::showEvent(QShowEvent* event) // events QGLWidget::showEvent(event); refreshTimer->start(updateInterval); + emit visibilityChanged(true); } void HUD::hideEvent(QHideEvent* event) { // React only to internal (pre-display) // events - QGLWidget::hideEvent(event); refreshTimer->stop(); + QGLWidget::hideEvent(event); + emit visibilityChanged(false); } void HUD::contextMenuEvent (QContextMenuEvent* event) diff --git a/src/ui/HUD.h b/src/ui/HUD.h index 884a6db768..a6412ba7db 100644 --- a/src/ui/HUD.h +++ b/src/ui/HUD.h @@ -113,6 +113,9 @@ protected slots: void drawPolygon(QPolygonF refPolygon, QPainter* painter); +signals: + void visibilityChanged(bool visible); + protected: void commitRawDataToGL(); /** @brief Convert reference coordinates to screen coordinates */ diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 14a777b957..7db7f17805 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -128,11 +128,8 @@ MainWindow::MainWindow(QWidget *parent): setCentralWidget(centerStack); buildCommonWidgets(); - connectCommonWidgets(); - arrangeCommonCenterStack(); - configureWindowName(); loadStyle(currentStyle); @@ -235,7 +232,13 @@ MainWindow::~MainWindow() delete dockWidget->widget(); delete dockWidget; } + else + { + delete dynamic_cast(*i); + } } + + // Delete all UAS objects } /** @@ -243,11 +246,9 @@ MainWindow::~MainWindow() */ void MainWindow::setDefaultSettingsForAp() { + // Check if the settings exist, instantiate defaults if necessary - -// // Check if the settings exist, instantiate defaults if necessary - // // UNCONNECTED VIEW DEFAULT //// QString centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_MAP, VIEW_UNCONNECTED); // if (!settings.contains(centralKey)) { @@ -574,6 +575,9 @@ void MainWindow::buildCommonWidgets() addTool(video2DockWidget, tr("Video Stream 2"), Qt::LeftDockWidgetArea); } + // Custom widgets, added last to all menus and layouts + buildCustomWidget(); + // Dialogue widgets //FIXME: free memory in destructor @@ -588,6 +592,8 @@ void MainWindow::addTool(QDockWidget* widget, const QString& title, Qt::DockWidg var.setValue((QWidget*)widget); tempAction->setData(var); connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); + connect(widget, SIGNAL(visibilityChanged(bool)), tempAction, SLOT(setChecked(bool))); + tempAction->setChecked(widget->isVisible()); addDockWidget(area, widget); } @@ -614,6 +620,8 @@ void MainWindow::addCentralWidget(QWidget* widget, const QString& title) tempAction->setData(var); centerStackActionGroup.addAction(tempAction); connect(tempAction,SIGNAL(triggered()),this, SLOT(showCentralWidget())); + connect(widget, SIGNAL(visibilityChanged(bool)), tempAction, SLOT(setChecked(bool))); + tempAction->setChecked(widget->isVisible()); } } @@ -677,34 +685,58 @@ void MainWindow::loadCustomWidget() { QString widgetFileExtension(".qgw"); QString fileName = QFileDialog::getOpenFileName(this, tr("Specify Widget File Name"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("QGroundControl Widget (*%1);;").arg(widgetFileExtension)); - QGCToolWidget* tool = new QGCToolWidget("", this); - tool->loadSettings(fileName); + loadCustomWidget(fileName); +} - if (QGCToolWidget::instances()->size() < 2) +void MainWindow::loadCustomWidget(const QString& fileName, bool singleinstance) +{ + QGCToolWidget* tool = new QGCToolWidget("", this); + if (tool->loadSettings(fileName, true) || !singleinstance) { - // This is the first widget - ui.menuTools->addSeparator(); + // Add widget to UI + QDockWidget* dock = new QDockWidget(tool->getTitle(), this); + connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater())); + dock->setWidget(tool); + tool->setParent(dock); + + QAction* showAction = new QAction("Show Unnamed Tool", this); + showAction->setCheckable(true); + connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool))); + connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool))); + tool->setMainMenuAction(showAction); + ui.menuTools->addAction(showAction); + this->addDockWidget(Qt::BottomDockWidgetArea, dock); + dock->setVisible(true); + } + else + { + return; } - - // Add widget to UI - QDockWidget* dock = new QDockWidget(tool->getTitle(), this); - connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater())); - dock->setWidget(tool); - tool->setParent(dock); - - QAction* showAction = new QAction("Show Unnamed Tool", this); - showAction->setCheckable(true); - connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool))); - connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool))); - tool->setMainMenuAction(showAction); - ui.menuTools->addAction(showAction); - this->addDockWidget(Qt::BottomDockWidgetArea, dock); - dock->setVisible(true); } -void MainWindow::arrangeCommonCenterStack() +void MainWindow::loadCustomWidgetsFromDefaults(const QString& systemType, const QString& autopilotType) { + QString defaultsDir = qApp->applicationDirPath() + "/files/" + systemType.toLower() + "/" + autopilotType.toLower() + "/widgets/"; + QDir widgets(defaultsDir); + QStringList files = widgets.entryList(); + if (files.count() == 0) + { + qDebug() << "No default custom widgets for system " << systemType << "autopilot" << autopilotType << " found"; + qDebug() << "Tried with path: " << defaultsDir; + } + + // Load all custom widgets found in the AP folder + for(int i = 0; i < files.count(); ++i) + { + QString file = files[i]; + if (file.endsWith(".qgw")) + { + // Will only be loaded if not already a custom widget with + // the same name is present + loadCustomWidget(file, true); + } + } } void MainWindow::loadSettings() @@ -1155,10 +1187,8 @@ void MainWindow::UASCreated(UASInterface* uas) // Connect the UAS to the full user interface - if (uas != NULL) { - // Set default settings - setDefaultSettingsForAp(); - + if (uas != NULL) + { // The pilot, operator and engineer views were not available on startup, enable them now ui.actionPilotsView->setEnabled(true); ui.actionOperatorsView->setEnabled(true); @@ -1236,6 +1266,11 @@ void MainWindow::UASCreated(UASInterface* uas) addCentralWidget(linechartWidget, tr("Realtime Plot")); } + // Load default custom widgets for this autopilot type + loadCustomWidgetsFromDefaults(uas->getSystemTypeString(uas->getSystemType()), uas->getAutopilotTypeString(uas->getAutopilotType())); + + + // Change the view only if this is the first UAS // If this is the first connected UAS, it is both created as well as @@ -1275,10 +1310,9 @@ void MainWindow::UASCreated(UASInterface* uas) if (!ui.menuConnected_Systems->isEnabled()) ui.menuConnected_Systems->setEnabled(true); - // Custom widgets, added last to all menus and layouts - buildCustomWidget(); // Restore the mainwindow size - if (settings.contains(getWindowGeometryKey())) { + if (settings.contains(getWindowGeometryKey())) + { restoreGeometry(settings.value(getWindowGeometryKey()).toByteArray()); } } @@ -1302,7 +1336,13 @@ void MainWindow::loadViewState() { // Restore center stack state int index = settings.value(getWindowStateKey()+"CENTER_WIDGET", centerStack->currentIndex()).toInt(); - centerStack->setCurrentIndex(index); + // The offline plot view is usually the consequence of a logging run, always show the realtime view first + if (centerStack->indexOf(dataplotWidget) == index) + { + // Rewrite to realtime plot + index = centerStack->indexOf(linechartWidget); + } + if (index != -1) centerStack->setCurrentIndex(index); // Restore the widget positions and size if (settings.contains(getWindowStateKey())) diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 6096973d9a..4795a25a99 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -178,9 +178,15 @@ public slots: /** @brief Add a custom tool widget */ void createCustomWidget(); - /** @brief Load a custom tool widget from a file */ + /** @brief Load a custom tool widget from a file chosen by user (QFileDialog) */ void loadCustomWidget(); + /** @brief Load a custom tool widget from a file */ + void loadCustomWidget(const QString& fileName, bool singleinstance=false); + + /** @brief Load custom widgets from default file */ + void loadCustomWidgetsFromDefaults(const QString& systemType, const QString& autopilotType); + void closeEvent(QCloseEvent* event); /** @brief Load data view, allowing to plot flight data */ @@ -275,21 +281,8 @@ protected: void buildCustomWidget(); void buildCommonWidgets(); -// void buildPxWidgets(); -// void buildSlugsWidgets(); - void connectCommonWidgets(); -// void connectPxWidgets(); -// void connectSlugsWidgets(); - - void arrangeCommonCenterStack(); -// void arrangePxCenterStack(); -// void arrangeSlugsCenterStack(); - void connectCommonActions(); -// void connectPxActions(); -// void connectSlugsActions(); - void configureWindowName(); void loadSettings(); @@ -307,9 +300,7 @@ protected: // Center widgets QPointer linechartWidget; - QPointer hudWidget; - QPointer mapWidget; QPointer protocolWidget; QPointer dataplotWidget; @@ -322,6 +313,7 @@ protected: #if (defined _MSC_VER) || (defined Q_OS_MAC) QPointer gEarthWidget; #endif + // Dock widgets QPointer controlDockWidget; QPointer controlParameterWidget; diff --git a/src/ui/QGCDataPlot2D.h b/src/ui/QGCDataPlot2D.h index edfd248f4e..f87498bbaa 100644 --- a/src/ui/QGCDataPlot2D.h +++ b/src/ui/QGCDataPlot2D.h @@ -46,7 +46,22 @@ public slots: /** @brief Calculate and display regression function*/ bool calculateRegression(); +signals: + void visibilityChanged(bool visible); + protected: + void showEvent(QShowEvent* event) + { + QWidget::showEvent(event); + emit visibilityChanged(true); + } + + void hideEvent(QHideEvent* event) + { + QWidget::hideEvent(event); + emit visibilityChanged(false); + } + void changeEvent(QEvent *e); IncrementalPlot* plot; LogCompressor* compressor; diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index 9e2ac55792..ea43748855 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -109,14 +109,19 @@ QList QGCToolWidget::createWidgetsFromSettings(QWidget* parent, return instances()->values(); } -void QGCToolWidget::loadSettings(const QString& settings) +/** + * @param singleinstance If this is set to true, the widget settings will only be loaded if not another widget with the same title exists + */ +bool QGCToolWidget::loadSettings(const QString& settings, bool singleinstance) { QSettings set(settings, QSettings::IniFormat); QStringList groups = set.childGroups(); QString widgetName = groups.first(); + if (singleinstance && QGCToolWidget::instances()->keys().contains(widgetName)) return false; setTitle(widgetName); qDebug() << "WIDGET TITLE LOADED: " << widgetName; loadSettings(set); + return true; } void QGCToolWidget::loadSettings(QSettings& settings) diff --git a/src/ui/designer/QGCToolWidget.h b/src/ui/designer/QGCToolWidget.h index 7d8b74dadc..7246b3da84 100644 --- a/src/ui/designer/QGCToolWidget.h +++ b/src/ui/designer/QGCToolWidget.h @@ -47,7 +47,7 @@ public slots: /** @brief Load this widget from a QSettings object */ void loadSettings(QSettings& settings); /** @brief Load this widget from a settings file */ - void loadSettings(const QString& settings); + bool loadSettings(const QString& settings, bool singleinstance=false); /** @brief Store this widget to a QSettings object */ void storeSettings(QSettings& settings); /** @brief Store this widget to a settings file */ diff --git a/src/ui/linechart/Linecharts.cc b/src/ui/linechart/Linecharts.cc index af1fded4f8..c45f139818 100644 --- a/src/ui/linechart/Linecharts.cc +++ b/src/ui/linechart/Linecharts.cc @@ -30,32 +30,35 @@ void Linecharts::showEvent(QShowEvent* event) { // React only to internal (pre-display) // events - Q_UNUSED(event) { - QWidget* prevWidget = currentWidget(); - if (prevWidget) { - LinechartWidget* chart = dynamic_cast(prevWidget); - if (chart) { - this->active = true; - chart->setActive(true); - } + Q_UNUSED(event) + QWidget* prevWidget = currentWidget(); + if (prevWidget) + { + LinechartWidget* chart = dynamic_cast(prevWidget); + if (chart) { + this->active = true; + chart->setActive(true); } } + QWidget::showEvent(event); + emit visibilityChanged(true); } void Linecharts::hideEvent(QHideEvent* event) { // React only to internal (pre-display) // events - Q_UNUSED(event) { - QWidget* prevWidget = currentWidget(); - if (prevWidget) { - LinechartWidget* chart = dynamic_cast(prevWidget); - if (chart) { - this->active = false; - chart->setActive(false); - } + Q_UNUSED(event) + QWidget* prevWidget = currentWidget(); + if (prevWidget) { + LinechartWidget* chart = dynamic_cast(prevWidget); + if (chart) { + this->active = false; + chart->setActive(false); } } + QWidget::hideEvent(event); + emit visibilityChanged(false); } void Linecharts::selectSystem(int systemid) diff --git a/src/ui/linechart/Linecharts.h b/src/ui/linechart/Linecharts.h index 4b6ad5cce0..1c854ff9de 100644 --- a/src/ui/linechart/Linecharts.h +++ b/src/ui/linechart/Linecharts.h @@ -16,6 +16,7 @@ public: signals: /** @brief This signal is emitted once a logfile has been finished writing */ void logfileWritten(QString fileName); + void visibilityChanged(bool visible); public slots: /** @brief Select plot for one system */ @@ -24,6 +25,7 @@ public slots: void addSystem(UASInterface* uas); protected: + QMap plots; bool active; /** @brief Start updating widget */ diff --git a/src/ui/map/QGCMapTool.h b/src/ui/map/QGCMapTool.h index 784bf78625..ca0e33ad91 100644 --- a/src/ui/map/QGCMapTool.h +++ b/src/ui/map/QGCMapTool.h @@ -20,6 +20,22 @@ public slots: /** @brief Update slider zoom from map change */ void setZoom(int zoom); +signals: + void visibilityChanged(bool visible); + +protected: + void showEvent(QShowEvent* event) + { + QWidget::showEvent(event); + emit visibilityChanged(true); + } + + void hideEvent(QHideEvent* event) + { + QWidget::hideEvent(event); + emit visibilityChanged(false); + } + private: Ui::QGCMapTool *ui; }; diff --git a/src/ui/map3D/QGCGoogleEarthView.cc b/src/ui/map3D/QGCGoogleEarthView.cc index fe0d9928d4..a132252617 100644 --- a/src/ui/map3D/QGCGoogleEarthView.cc +++ b/src/ui/map3D/QGCGoogleEarthView.cc @@ -376,18 +376,20 @@ void QGCGoogleEarthView::moveToPosition() void QGCGoogleEarthView::hideEvent(QHideEvent* event) { - Q_UNUSED(event); updateTimer->stop(); + QWidget::hideEvent(event); + emit visibilityChanged(false); } void QGCGoogleEarthView::showEvent(QShowEvent* event) { // React only to internal (pre-display) // events - Q_UNUSED(event) + QWidget::showEvent(event); // Enable widget, initialize on first run - if (!webViewInitialized) { + if (!webViewInitialized) + { #if (defined Q_OS_MAC) webViewMac->setPage(new QGCWebPage(webViewMac)); webViewMac->settings()->setAttribute(QWebSettings::PluginsEnabled, true); @@ -404,9 +406,12 @@ void QGCGoogleEarthView::showEvent(QShowEvent* event) gEarthInitialized = false; QTimer::singleShot(3000, this, SLOT(initializeGoogleEarth())); - } else { + } + else + { updateTimer->start(refreshRateMs); } + emit visibilityChanged(true); } void QGCGoogleEarthView::printWinException(int no, QString str1, QString str2, QString str3) diff --git a/src/ui/map3D/QGCGoogleEarthView.h b/src/ui/map3D/QGCGoogleEarthView.h index b572678bce..117239aa4f 100644 --- a/src/ui/map3D/QGCGoogleEarthView.h +++ b/src/ui/map3D/QGCGoogleEarthView.h @@ -137,6 +137,9 @@ public: /** @brief Get a document element */ QVariant documentElement(QString name); +signals: + void visibilityChanged(bool visible); + protected: void changeEvent(QEvent *e); QTimer* updateTimer; -- GitLab