From 7505181efb7012336b9522d9521b005432dd80ec Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Mon, 3 Oct 2016 19:16:02 -0700 Subject: [PATCH] GeoTag framework --- qgcresources.qrc | 2 + qgroundcontrol.pro | 5 +- qgroundcontrol.qrc | 3 + src/AnalyzeView/AnalyzePage.qml | 70 +++++++++ src/AnalyzeView/AnalyzeView.qml | 126 +++++++++++++++ src/AnalyzeView/GeoTagController.cc | 87 +++++++++++ src/AnalyzeView/GeoTagController.h | 97 ++++++++++++ src/AnalyzeView/GeoTagIcon.png | Bin 0 -> 502 bytes src/AnalyzeView/GeoTagPage.qml | 103 +++++++++++++ src/QGCApplication.cc | 35 +---- src/QGCApplication.h | 7 - .../QGroundControl.Controls.qmldir | 1 + src/VehicleSetup/SetupViewTest.cc | 52 ------- src/VehicleSetup/SetupViewTest.h | 29 ---- src/qgcunittest/UnitTestList.cc | 4 - src/ui/MainWindowHybrid.qml | 26 ---- src/ui/MainWindowInner.qml | 144 +++++++++--------- src/ui/MainWindowNative.qml | 26 ---- src/ui/toolbar/Images/Analyze.svg | 34 +++++ src/ui/toolbar/MainToolBar.qml | 28 +++- 20 files changed, 625 insertions(+), 254 deletions(-) create mode 100644 src/AnalyzeView/AnalyzePage.qml create mode 100644 src/AnalyzeView/AnalyzeView.qml create mode 100644 src/AnalyzeView/GeoTagController.cc create mode 100644 src/AnalyzeView/GeoTagController.h create mode 100644 src/AnalyzeView/GeoTagIcon.png create mode 100644 src/AnalyzeView/GeoTagPage.qml delete mode 100644 src/VehicleSetup/SetupViewTest.cc delete mode 100644 src/VehicleSetup/SetupViewTest.h create mode 100644 src/ui/toolbar/Images/Analyze.svg diff --git a/qgcresources.qrc b/qgcresources.qrc index 973da9ffa..418f773e9 100644 --- a/qgcresources.qrc +++ b/qgcresources.qrc @@ -54,6 +54,7 @@ src/AutoPilotPlugins/PX4/Images/DatalinkLossLight.svg src/AutoPilotPlugins/PX4/Images/GeoFence.svg src/AutoPilotPlugins/PX4/Images/GeoFenceLight.svg + src/AnalyzeView/GeoTagIcon.png src/AutoPilotPlugins/PX4/Images/LandMode.svg src/AutoPilotPlugins/PX4/Images/LandModeCopter.svg src/AutoPilotPlugins/PX4/Images/LowBattery.svg @@ -128,6 +129,7 @@ src/ui/toolbar/Images/Disarmed.svg src/ui/toolbar/Images/Disconnect.svg src/ui/toolbar/Images/Gears.svg + src/ui/toolbar/Images/Analyze.svg src/ui/toolbar/Images/Gps.svg src/ui/toolbar/Images/Hamburger.svg src/ui/toolbar/Images/Megaphone.svg diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index a4963410f..1b93afc20 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -212,6 +212,7 @@ INCLUDEPATH += . INCLUDEPATH += \ include/ui \ src \ + src/AnalyzeView \ src/audio \ src/AutoPilotPlugins \ src/comm \ @@ -371,6 +372,7 @@ HEADERS += \ !MobileBuild { HEADERS += \ + src/AnalyzeView/GeoTagController.h \ src/comm/LogReplayLink.h \ src/comm/QGCFlightGearLink.h \ src/comm/QGCHilLink.h \ @@ -525,6 +527,7 @@ contains(DEFINES, QGC_ENABLE_BLUETOOTH) { !MobileBuild { SOURCES += \ + src/AnalyzeView/GeoTagController.cc \ src/ui/uas/UASMessageView.cc \ src/uas/FileManager.cc \ src/ui/uas/QGCUnconnectedInfoWidget.cc \ @@ -613,7 +616,6 @@ HEADERS += \ src/qgcunittest/TCPLoopBackServer.h \ src/qgcunittest/UnitTest.h \ src/ViewWidgets/LogDownloadTest.h \ - src/VehicleSetup/SetupViewTest.h \ SOURCES += \ src/FactSystem/FactSystemTestBase.cc \ @@ -642,7 +644,6 @@ SOURCES += \ src/qgcunittest/UnitTest.cc \ src/qgcunittest/UnitTestList.cc \ src/ViewWidgets/LogDownloadTest.cc \ - src/VehicleSetup/SetupViewTest.cc \ } # !MobileBuild } # DebugBuild diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index ebf701b98..cf6bec343 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -47,6 +47,7 @@ src/AutoPilotPlugins/PX4/PowerComponentSummary.qml src/VehicleSetup/PX4FlowSensor.qml src/QmlControls/QGroundControl.Controls.qmldir + src/AnalyzeView/AnalyzePage.qml src/QmlControls/ClickableColor.qml src/QmlControls/DropButton.qml src/QmlControls/ExclusiveGroupItem.qml @@ -168,6 +169,8 @@ src/VehicleSetup/VehicleSummary.qml src/QmlControls/OfflineMapButton.qml src/AutoPilotPlugins/PX4/PX4TuningComponentVTOL.qml + src/AnalyzeView/GeoTagPage.qml + src/AnalyzeView/AnalyzeView.qml src/MissionManager/MavCmdInfoCommon.json diff --git a/src/AnalyzeView/AnalyzePage.qml b/src/AnalyzeView/AnalyzePage.qml new file mode 100644 index 000000000..36fc36048 --- /dev/null +++ b/src/AnalyzeView/AnalyzePage.qml @@ -0,0 +1,70 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.5 +import QtQuick.Controls 1.2 + +import QGroundControl 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 + +/// Base view control for all Analyze pages +QGCView { + id: analyePage + viewPanel: analyzePanel + + property alias pageComponent: pageLoader.sourceComponent + property alias pageName: pageNameLabel.text + property alias pageDescription: pageDescriptionLabel.text + property real availableWidth: width - pageLoader.x + property real availableHeight: height - pageLoader.y + + property real _margins: ScreenTools.defaultFontPixelHeight / 2 + + QGCPalette { id: qgcPal; colorGroupEnabled: analyzePanel.enabled } + + QGCViewPanel { + id: analyzePanel + anchors.fill: parent + + QGCFlickable { + anchors.fill: parent + contentWidth: pageLoader.x + pageLoader.item.width + contentHeight: pageLoader.y + pageLoader.item.height + clip: true + + Column { + id: headingColumn + width: analyzePanel.width + spacing: _margins + + QGCLabel { + id: pageNameLabel + font.pointSize: ScreenTools.largeFontPointSize + visible: !ScreenTools.isShortScreen + } + + QGCLabel { + id: pageDescriptionLabel + anchors.left: parent.left + anchors.right: parent.right + wrapMode: Text.WordWrap + visible: !ScreenTools.isShortScreen + } + } + + Loader { + id: pageLoader + anchors.topMargin: _margins + anchors.top: headingColumn.bottom + } + } + } +} diff --git a/src/AnalyzeView/AnalyzeView.qml b/src/AnalyzeView/AnalyzeView.qml new file mode 100644 index 000000000..103c41d86 --- /dev/null +++ b/src/AnalyzeView/AnalyzeView.qml @@ -0,0 +1,126 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + + +/// @file +/// @brief Setup View +/// @author Don Gagne + +import QtQuick 2.3 +import QtQuick.Controls 1.2 + +import QGroundControl 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 + +Rectangle { + id: setupView + color: qgcPal.window + z: QGroundControl.zOrderTopMost + + QGCPalette { id: qgcPal; colorGroupEnabled: true } + + ExclusiveGroup { id: setupButtonGroup } + + readonly property real _defaultTextHeight: ScreenTools.defaultFontPixelHeight + readonly property real _defaultTextWidth: ScreenTools.defaultFontPixelWidth + readonly property real _horizontalMargin: _defaultTextWidth / 2 + readonly property real _verticalMargin: _defaultTextHeight / 2 + readonly property real _buttonWidth: _defaultTextWidth * 18 + + function showGeoTagPanel() { + panelLoader.source = "GeoTagPage.qml" + } + + Component.onCompleted: showGeoTagPanel() + + QGCFlickable { + id: buttonScroll + width: buttonColumn.width + anchors.topMargin: _defaultTextHeight / 2 + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.leftMargin: _horizontalMargin + anchors.left: parent.left + contentHeight: buttonColumn.height + flickableDirection: Flickable.VerticalFlick + clip: true + + Column { + id: buttonColumn + width: _maxButtonWidth + spacing: _defaultTextHeight / 2 + + property real _maxButtonWidth: 0 + + Component.onCompleted: reflowWidths() + + // I don't know why this does not work + Connections { + target: QGroundControl + onBaseFontPointSizeChanged: buttonColumn.reflowWidths() + } + + function reflowWidths() { + buttonColumn._maxButtonWidth = 0 + for (var i = 0; i < children.length; i++) { + buttonColumn._maxButtonWidth = Math.max(buttonColumn._maxButtonWidth, children[i].width) + } + for (var j = 0; j < children.length; j++) { + children[j].width = buttonColumn._maxButtonWidth + } + } + + QGCLabel { + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Analyze") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + visible: !ScreenTools.isShortScreen + } + + SubMenuButton { + id: summaryButton + imageResource: "/qmlimages/GeoTagIcon.png" + setupIndicator: false + checked: true + exclusiveGroup: setupButtonGroup + text: "GeoTag Images" + + onClicked: showGeoTagPanel() + } + } + } + + Rectangle { + id: divider + anchors.topMargin: _verticalMargin + anchors.bottomMargin: _verticalMargin + anchors.leftMargin: _horizontalMargin + anchors.left: buttonScroll.right + anchors.top: parent.top + anchors.bottom: parent.bottom + width: 1 + color: qgcPal.windowShade + } + + Loader { + id: panelLoader + anchors.topMargin: _verticalMargin + anchors.bottomMargin: _verticalMargin + anchors.leftMargin: _horizontalMargin + anchors.rightMargin: _horizontalMargin + anchors.left: divider.right + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + } +} diff --git a/src/AnalyzeView/GeoTagController.cc b/src/AnalyzeView/GeoTagController.cc new file mode 100644 index 000000000..f9314c31e --- /dev/null +++ b/src/AnalyzeView/GeoTagController.cc @@ -0,0 +1,87 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#include "GeoTagController.h" +#include "QGCFileDialog.h" + +GeoTagController::GeoTagController(void) + : _progress(0) + , _inProgress(false) +{ + connect(&_worker, &GeoTagWorker::progressChanged, this, &GeoTagController::_workerProgressChanged); + connect(&_worker, &GeoTagWorker::error, this, &GeoTagController::_workerError); + connect(&_worker, &GeoTagWorker::started, this, &GeoTagController::inProgressChanged); + connect(&_worker, &GeoTagWorker::finished, this, &GeoTagController::inProgressChanged); +} + +GeoTagController::~GeoTagController() +{ + +} + +void GeoTagController::pickLogFile(void) +{ + QString filename = QGCFileDialog::getOpenFileName(NULL, "Select log file load", QString(), "PX4 log file (*.px4log);;All Files (*.*)"); + if (!filename.isEmpty()) { + _worker.setLogFile(filename); + emit logFileChanged(filename); + } +} + +void GeoTagController::pickImageDirectory(void) +{ + QString dir = QGCFileDialog::getExistingDirectory(NULL, "Select image directory"); + if (!dir.isEmpty()) { + _worker.setImageDirectory(dir); + emit imageDirectoryChanged(dir); + } +} + +void GeoTagController::startTagging(void) +{ + _errorMessage.clear(); + emit errorMessageChanged(_errorMessage); + _worker.start(); +} + +void GeoTagController::_workerProgressChanged(double progress) +{ + _progress = progress; + emit progressChanged(progress); +} + +void GeoTagController::_workerError(QString errorMessage) +{ + _errorMessage = errorMessage; + emit errorMessageChanged(errorMessage); +} + +GeoTagWorker::GeoTagWorker(void) + : _cancel(false) +{ + +} + +void GeoTagWorker::run(void) +{ + _cancel = false; + emit progressChanged(0); + + for (int i=0; i<10;i++) { + if (_cancel) { + emit error(tr("Tagging cancelled")); + return; + } + emit progressChanged(i*10); + sleep(1); + } + + emit progressChanged(100); + emit taggingComplete(); +} diff --git a/src/AnalyzeView/GeoTagController.h b/src/AnalyzeView/GeoTagController.h new file mode 100644 index 000000000..a2820fa35 --- /dev/null +++ b/src/AnalyzeView/GeoTagController.h @@ -0,0 +1,97 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#ifndef GeoTagController_H +#define GeoTagController_H + +#include +#include +#include + +class GeoTagWorker : public QThread +{ + Q_OBJECT + +public: + GeoTagWorker(void); + + QString logFile(void) const { return _logFile; } + QString imageDirectory(void) const { return _imageDirectory; } + + void setLogFile(const QString& logFile) { _logFile = logFile; } + void setImageDirectory(const QString& imageDirectory) { _imageDirectory = imageDirectory; } + + void cancellTagging(void) { _cancel = true; } + +protected: + void run(void) final; + +signals: + void error(QString errorMsg); + void taggingComplete(void); + void progressChanged(double progress); + +private: + bool _cancel; + QString _logFile; + QString _imageDirectory; +}; + +/// Controller for GeoTagPage.qml. Supports geotagging images based on logfile camera tags. +class GeoTagController : public QObject +{ + Q_OBJECT + +public: + GeoTagController(void); + ~GeoTagController(); + + Q_PROPERTY(QString logFile READ logFile NOTIFY logFileChanged) + Q_PROPERTY(QString imageDirectory READ imageDirectory NOTIFY imageDirectoryChanged) + + /// Set to an error message is geotagging fails + Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) + + /// Progress indicator: 0-100 + Q_PROPERTY(double progress READ progress NOTIFY progressChanged) + + /// true: Currently in the process of tagging + Q_PROPERTY(bool inProgress READ inProgress NOTIFY inProgressChanged) + + Q_INVOKABLE void pickLogFile(void); + Q_INVOKABLE void pickImageDirectory(void); + Q_INVOKABLE void startTagging(void); + Q_INVOKABLE void cancelTagging(void) { _worker.cancellTagging(); } + + QString logFile (void) const { return _worker.logFile(); } + QString imageDirectory (void) const { return _worker.imageDirectory(); } + double progress (void) const { return _progress; } + bool inProgress (void) const { return _worker.isRunning(); } + QString errorMessage (void) const { return _errorMessage; } + +signals: + void logFileChanged(QString logFile); + void imageDirectoryChanged(QString imageDirectory); + void progressChanged(double progress); + void inProgressChanged(void); + void errorMessageChanged(QString errorMessage); + +private slots: + void _workerProgressChanged(double progress); + void _workerError(QString errorMsg); + +private: + QString _errorMessage; + double _progress; + bool _inProgress; + + GeoTagWorker _worker; +}; + +#endif diff --git a/src/AnalyzeView/GeoTagIcon.png b/src/AnalyzeView/GeoTagIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..6aa8343a341df18048e0c9feeeb9491e2c63aaa8 GIT binary patch literal 502 zcmV4hVSb4Mz~&Q&|7Z z&UwJ@ya9HBqBx1P)|D|~jGYBW85^yg3FfMA>TTaE1&sNT#y*VM?;of8n{sAmb;d5v ze@+Qw)dJLAlrS2yOnPkt6^w0b0LoXJ8)gQo!9o%_VWy?AMG=6O#<5&5Q|*DVRb=cn z7tECMj?WMocgX=`r5xXWWvs-)FsLb8VIDTEUyBx0V_-Us)96-ZnAugOg1M)>6Gv?H z>r=qYDPK9UIKo#Q4Wr>eb%AQ+{%b-|9Wuzjl=m_e8>@;fUxNgc0iXf9?3gmJ1}FkP z{oa{=7H|yJlpT9g9C6;UK%3f;B*8n=0H~ZdoiCme>fy2mfXo|L`!|i0kA&D6$0H?1Qb3707*qoM6N<$f(`)6&Hw-a literal 0 HcmV?d00001 diff --git a/src/AnalyzeView/GeoTagPage.qml b/src/AnalyzeView/GeoTagPage.qml new file mode 100644 index 000000000..a7d840710 --- /dev/null +++ b/src/AnalyzeView/GeoTagPage.qml @@ -0,0 +1,103 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 + +import QGroundControl.Palette 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Controllers 1.0 + +AnalyzePage { + id: geoTagPage + pageComponent: pageComponent + pageName: qsTr("GeoTag Images (WIP)") + pageDescription: qsTr("GetTag Images is used to tag a set of images from a survey mission with gps coordinates. You must provide the binary log from the flight as well as the directory which contains the images to tag.") + + property real _margin: ScreenTools.defaultFontPixelWidth + + GeoTagController { + id: controller + } + + Component { + id: pageComponent + + Column { + id: mainColumn + width: availableWidth + spacing: _margin + + Row { + spacing: _margin + + QGCLabel { + text: "Log file:" + } + + QGCLabel { + text: controller.logFile + } + + QGCButton { + text: qsTr("Select log file") + onClicked: controller.pickLogFile() + } + } + + Row { + spacing: _margin + + QGCLabel { + text: "Image directory:" + } + + QGCLabel { + text: controller.imageDirectory + } + + QGCButton { + text: qsTr("Select image directory") + onClicked: controller.pickImageDirectory() + } + } + + QGCLabel { text: "NYI - Simulated only" } + + QGCButton { + text: controller.inProgress ? qsTr("Cancel Tagging") : qsTr("Start Tagging") + + onClicked: { + if (controller.inProgress) { + controller.cancelTagging() + } else { + if (controller.logFile == "" || controller.imageDirectory == "") { + geoTagPage.showMessage(qsTr("Error"), qsTr("You must select a log file and image directory before you can start tagging."), StandardButton.Ok) + return + } + controller.startTagging() + } + } + } + + QGCLabel { + text: controller.errorMessage + } + + ProgressBar { + anchors.left: parent.left + anchors.right: parent.right + maximumValue: 100 + value: controller.progress + } + } // Column + } // Component +} // AnalyzePage diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index e5e5582d5..cfa4dd755 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -107,6 +107,7 @@ #include "QGCMessageBox.h" #include "FirmwareUpgradeController.h" #include "MainWindow.h" + #include "GeoTagController.h" #endif #ifdef QGC_RTLAB_ENABLED @@ -413,6 +414,7 @@ void QGCApplication::_initCommon(void) qmlRegisterType ("QGroundControl.Controllers", 1, 0, "CustomCommandWidgetController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "FirmwareUpgradeController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "LogDownloadController"); + qmlRegisterType ("QGroundControl.Controllers", 1, 0, "GeoTagController"); #endif // Register Qml Singletons @@ -688,16 +690,6 @@ void QGCApplication::showMessage(const QString& message) } } -void QGCApplication::showFlyView(void) -{ - QMetaObject::invokeMethod(_rootQmlObject(), "showFlyView"); -} - -void QGCApplication::showPlanView(void) -{ - QMetaObject::invokeMethod(_rootQmlObject(), "showPlanView"); -} - void QGCApplication::showSetupView(void) { QMetaObject::invokeMethod(_rootQmlObject(), "showSetupView"); @@ -709,29 +701,6 @@ void QGCApplication::qmlAttemptWindowClose(void) } -void QGCApplication::_showSetupFirmware(void) -{ - QMetaObject::invokeMethod(_rootQmlObject(), "showSetupFirmware"); -} - -void QGCApplication::_showSetupParameters(void) -{ - QMetaObject::invokeMethod(_rootQmlObject(), "showSetupParameters"); -} - -void QGCApplication::_showSetupSummary(void) -{ - QMetaObject::invokeMethod(_rootQmlObject(), "showSetupSummary"); -} - -void QGCApplication::_showSetupVehicleComponent(VehicleComponent* vehicleComponent) -{ - QVariant varReturn; - QVariant varComponent = QVariant::fromValue(vehicleComponent); - - QMetaObject::invokeMethod(_rootQmlObject(), "showSetupVehicleComponent", Q_RETURN_ARG(QVariant, varReturn), Q_ARG(QVariant, varComponent)); -} - void QGCApplication::setLastKnownHomePosition(QGeoCoordinate& lastKnownHomePosition) { QSettings settings; diff --git a/src/QGCApplication.h b/src/QGCApplication.h index f6805a7e6..a5c9e7643 100644 --- a/src/QGCApplication.h +++ b/src/QGCApplication.h @@ -128,8 +128,6 @@ public slots: /// You can connect to this slot to show a critical message box from a different thread. void criticalMessageBoxOnMainThread(const QString& title, const QString& msg); - void showFlyView(void); - void showPlanView(void); void showSetupView(void); void qmlAttemptWindowClose(void); @@ -163,11 +161,6 @@ public: /// unit tests. Although public should only be called by main. bool _initForUnitTests(void); - void _showSetupFirmware(void); - void _showSetupParameters(void); - void _showSetupSummary(void); - void _showSetupVehicleComponent(VehicleComponent* vehicleComponent); - static QGCApplication* _app; ///< Our own singleton. Should be reference directly by qgcApp private slots: diff --git a/src/QmlControls/QGroundControl.Controls.qmldir b/src/QmlControls/QGroundControl.Controls.qmldir index e1ce19072..a04b37ba7 100644 --- a/src/QmlControls/QGroundControl.Controls.qmldir +++ b/src/QmlControls/QGroundControl.Controls.qmldir @@ -1,5 +1,6 @@ Module QGroundControl.Controls +AnalyzePage 1.0 AnalyzePage.qml AppMessages 1.0 AppMessages.qml ClickableColor 1.0 ClickableColor.qml DropButton 1.0 DropButton.qml diff --git a/src/VehicleSetup/SetupViewTest.cc b/src/VehicleSetup/SetupViewTest.cc deleted file mode 100644 index d81f55e85..000000000 --- a/src/VehicleSetup/SetupViewTest.cc +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2016 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - - -/// @file -/// @author Don Gagne - -#include "SetupViewTest.h" -#include "MockLink.h" -#include "MultiVehicleManager.h" -#include "QGCApplication.h" - -void SetupViewTest::_clickThrough_test(void) -{ - _createMainWindow(); - _connectMockLink(); - - AutoPilotPlugin* autopilot = qgcApp()->toolbox()->multiVehicleManager()->activeVehicle()->autopilotPlugin(); - Q_ASSERT(autopilot); - - // Switch to the Setup view - qgcApp()->showSetupView(); - QTest::qWait(1000); - - // Click through fixed buttons - qDebug() << "Showing firmware"; - qgcApp()->_showSetupFirmware(); - QTest::qWait(1000); - qDebug() << "Showing parameters"; - qgcApp()->_showSetupParameters(); - QTest::qWait(1000); - qDebug() << "Showing summary"; - qgcApp()->_showSetupSummary(); - QTest::qWait(1000); - - const QVariantList& components = autopilot->vehicleComponents(); - foreach(QVariant varComponent, components) { - VehicleComponent* component = qobject_cast(qvariant_cast(varComponent)); - qDebug() << "Showing" << component->name(); - qgcApp()->_showSetupVehicleComponent(component); - QTest::qWait(1000); - } - - _disconnectMockLink(); - _closeMainWindow(); -} diff --git a/src/VehicleSetup/SetupViewTest.h b/src/VehicleSetup/SetupViewTest.h deleted file mode 100644 index be3a9f970..000000000 --- a/src/VehicleSetup/SetupViewTest.h +++ /dev/null @@ -1,29 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2016 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - - -/// @file -/// @author Don Gagne - -#ifndef SetupViewTest_H -#define SetupViewTest_H - -#include "UnitTest.h" -#include "MainWindow.h" - -/// Click through test for Setup View buttons -class SetupViewTest : public UnitTest -{ - Q_OBJECT - -private slots: - void _clickThrough_test(void); -}; - -#endif diff --git a/src/qgcunittest/UnitTestList.cc b/src/qgcunittest/UnitTestList.cc index 4520a1cdc..23b28f6ab 100644 --- a/src/qgcunittest/UnitTestList.cc +++ b/src/qgcunittest/UnitTestList.cc @@ -24,7 +24,6 @@ #include "MissionControllerTest.h" #include "MissionManagerTest.h" #include "RadioConfigTest.h" -#include "SetupViewTest.h" #include "MavlinkLogTest.h" #include "MainWindowTest.h" #include "FileManagerTest.h" @@ -56,9 +55,6 @@ UT_REGISTER_TEST(LogDownloadTest) // List of unit test which are currently disabled. // If disabling a new test, include reason in comment. -// works, but causes other tests to fail -//UT_REGISTER_TEST(SetupViewTest) - // FIXME: Temporarily disabled until this can be stabilized //UT_REGISTER_TEST(MainWindowTest) diff --git a/src/ui/MainWindowHybrid.qml b/src/ui/MainWindowHybrid.qml index 93826db9c..1c27d9690 100644 --- a/src/ui/MainWindowHybrid.qml +++ b/src/ui/MainWindowHybrid.qml @@ -17,14 +17,6 @@ import QGroundControl.Controls 1.0 /// Native QML top level window Item { - function showFlyView() { - mainWindowInner.item.showFlyView() - } - - function showPlanView() { - mainWindowInner.item.showPlanView() - } - function showSetupView() { mainWindowInner.item.showSetupView() } @@ -33,24 +25,6 @@ Item { mainWindowInner.item.attemptWindowClose() } - // The following are use for unit testing only - - function showSetupFirmware() { - mainWindowInner.item.showSetupFirmware() - } - - function showSetupParameters() { - mainWindowInner.item.showSetupParameters() - } - - function showSetupSummary() { - mainWindowInner.item.showSetupSummary() - } - - function showSetupVehicleComponent(vehicleComponent) { - mainWindowInner.item.showSetupVehicleComponent(vehicleComponent) - } - function showMessage(message) { mainWindowInner.item.showMessage(message) } diff --git a/src/ui/MainWindowInner.qml b/src/ui/MainWindowInner.qml index cfedeaaab..1943f30e9 100644 --- a/src/ui/MainWindowInner.qml +++ b/src/ui/MainWindowInner.qml @@ -27,10 +27,6 @@ Item { signal reallyClose - readonly property string _planViewSource: "MissionEditor.qml" - readonly property string _setupViewSource: "SetupView.qml" - readonly property string _settingsViewSource: "AppSettings.qml" - QGCPalette { id: qgcPal; colorGroupEnabled: true } property real tbHeight: ScreenTools.isMobile ? (ScreenTools.isTinyScreen ? (mainWindow.width * 0.0666) : (mainWindow.width * 0.05)) : ScreenTools.defaultFontPixelHeight * 3 @@ -44,6 +40,13 @@ Item { property var activeVehicle: QGroundControl.multiVehicleManager.activeVehicle property string formatedMessage: activeVehicle ? activeVehicle.formatedMessage : "" + property var _viewList: [ settingsViewLoader, setupViewLoader, planViewLoader, flightView, analyzeViewLoader ] + + readonly property string _settingsViewSource: "AppSettings.qml" + readonly property string _setupViewSource: "SetupView.qml" + readonly property string _planViewSource: "MissionEditor.qml" + readonly property string _analyzeViewSource: "AnalyzeView.qml" + onHeightChanged: { //-- We only deal with the available height if within the Fly or Plan view if(!setupViewLoader.visible) { @@ -51,31 +54,24 @@ Item { } } - function showFlyView() { - if(currentPopUp) { - currentPopUp.close() + function hideAllViews() { + for (var i=0; i<_viewList.length; i++) { + _viewList[i].visible = false } - ScreenTools.availableHeight = parent.height - toolBar.height - settingsViewLoader.visible = false - flightView.visible = true - setupViewLoader.visible = false - planViewLoader.visible = false - toolBar.checkFlyButton() } - function showPlanView() { + function showSettingsView() { if(currentPopUp) { currentPopUp.close() } - if (planViewLoader.source != _planViewSource) { - planViewLoader.source = _planViewSource + //-- In settings view, the full height is available. Set to 0 so it is ignored. + ScreenTools.availableHeight = 0 + if (settingsViewLoader.source != _settingsViewSource) { + settingsViewLoader.source = _settingsViewSource } - ScreenTools.availableHeight = parent.height - toolBar.height - settingsViewLoader.visible = false - flightView.visible = false - setupViewLoader.visible = false - planViewLoader.visible = true - toolBar.checkPlanButton() + hideAllViews() + settingsViewLoader.visible = true + toolBar.checkSettingsButton() } function showSetupView() { @@ -87,45 +83,45 @@ Item { if (setupViewLoader.source != _setupViewSource) { setupViewLoader.source = _setupViewSource } - settingsViewLoader.visible = false - flightView.visible = false - setupViewLoader.visible = true - planViewLoader.visible = false + hideAllViews() + setupViewLoader.visible = true toolBar.checkSetupButton() } - function showSettingsView() { + function showPlanView() { if(currentPopUp) { currentPopUp.close() } - //-- In preferences view, the full height is available. Set to 0 so it is ignored. - ScreenTools.availableHeight = 0 - if (settingsViewLoader.source != _settingsViewSource) { - settingsViewLoader.source = _settingsViewSource + if (planViewLoader.source != _planViewSource) { + planViewLoader.source = _planViewSource } - flightView.visible = false - setupViewLoader.visible = false - planViewLoader.visible = false - settingsViewLoader.visible = true - toolBar.checkSettingsButton() - } - - // The following are use for unit testing only - - function showSetupFirmware() { - setupViewLoader.item.showFirmwarePanel() - } - - function showSetupParameters() { - setupViewLoader.item.showParametersPanel() + ScreenTools.availableHeight = parent.height - toolBar.height + hideAllViews() + planViewLoader.visible = true + toolBar.checkPlanButton() } - function showSetupSummary() { - setupViewLoader.item.showSummaryPanel() + function showFlyView() { + if(currentPopUp) { + currentPopUp.close() + } + ScreenTools.availableHeight = parent.height - toolBar.height + hideAllViews() + flightView.visible = true + toolBar.checkFlyButton() } - function showSetupVehicleComponent(vehicleComponent) { - setupViewLoader.item.showVehicleComponentPanel(vehicleComponent) + function showAnalyzeView() { + if(currentPopUp) { + currentPopUp.close() + } + ScreenTools.availableHeight = 0 + if (analyzeViewLoader.source != _analyzeViewSource) { + analyzeViewLoader.source = _analyzeViewSource + } + hideAllViews() + analyzeViewLoader.visible = true + toolBar.checkAnalyzeButton() } /// Start the process of closing QGroundControl. Prompts the user are needed. @@ -253,7 +249,7 @@ Item { function showPopUp(dropItem, centerX) { if(currentPopUp) { currentPopUp.close() - } + } indicatorDropdown.centerX = centerX indicatorDropdown.sourceComponent = dropItem indicatorDropdown.visible = true @@ -271,25 +267,30 @@ Item { mainWindow: mainWindow isBackgroundDark: flightView.isBackgroundDark z: QGroundControl.zOrderTopMost + onShowSettingsView: mainWindow.showSettingsView() onShowSetupView: mainWindow.showSetupView() onShowPlanView: mainWindow.showPlanView() onShowFlyView: mainWindow.showFlyView() - onShowSettingsView: mainWindow.showSettingsView() + onShowAnalyzeView: mainWindow.showAnalyzeView() Component.onCompleted: { ScreenTools.availableHeight = parent.height - toolBar.height } } - FlightDisplayView { - id: flightView - anchors.fill: parent - visible: true - } - Loader { - id: planViewLoader - anchors.fill: parent + id: settingsViewLoader + anchors.left: parent.left + anchors.right: parent.right + anchors.top: toolBar.bottom + anchors.bottom: parent.bottom visible: false + + onVisibleChanged: { + if (!visible) { + // Free up the memory for this when not shown. No need to persist. + source = "" + } + } } Loader { @@ -302,20 +303,25 @@ Item { } Loader { - id: settingsViewLoader + id: planViewLoader + anchors.fill: parent + visible: false + } + + FlightDisplayView { + id: flightView + anchors.fill: parent + visible: true + } + + Loader { + id: analyzeViewLoader anchors.left: parent.left anchors.right: parent.right anchors.top: toolBar.bottom anchors.bottom: parent.bottom visible: false - - onVisibleChanged: { - if (!visible) { - // Free up the memory for this when not shown. No need to persist. - source = "" - } - } - } + } //------------------------------------------------------------------------- //-- Dismiss Pop Up Messages diff --git a/src/ui/MainWindowNative.qml b/src/ui/MainWindowNative.qml index 208f5886e..a4c8a5603 100644 --- a/src/ui/MainWindowNative.qml +++ b/src/ui/MainWindowNative.qml @@ -28,36 +28,10 @@ Window { } } - function showFlyView() { - mainWindowInner.item.showFlyView() - } - - function showPlanView() { - mainWindowInner.item.showPlanView() - } - function showSetupView() { mainWindowInner.item.showSetupView() } - // The following are use for unit testing only - - function showSetupFirmware() { - mainWindowInner.item.showSetupFirmware() - } - - function showSetupParameters() { - mainWindowInner.item.showSetupParameters() - } - - function showSetupSummary() { - mainWindowInner.item.showSetupSummary() - } - - function showSetupVehicleComponent(vehicleComponent) { - mainWindowInner.showSetupVehicleComponent(vehicleComponent) - } - function showMessage(message) { mainWindowInner.item.showMessage(message) } diff --git a/src/ui/toolbar/Images/Analyze.svg b/src/ui/toolbar/Images/Analyze.svg new file mode 100644 index 000000000..308898715 --- /dev/null +++ b/src/ui/toolbar/Images/Analyze.svg @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/src/ui/toolbar/MainToolBar.qml b/src/ui/toolbar/MainToolBar.qml index 902b83e12..ad45e36ab 100644 --- a/src/ui/toolbar/MainToolBar.qml +++ b/src/ui/toolbar/MainToolBar.qml @@ -45,15 +45,16 @@ Rectangle { readonly property var colorBlue: "#636efe" readonly property var colorWhite: "#ffffff" - signal showSettingsView() - signal showSetupView() - signal showPlanView() - signal showFlyView() + signal showSettingsView + signal showSetupView + signal showPlanView + signal showFlyView + signal showAnalyzeView MainToolBarController { id: _controller } function checkSettingsButton() { - preferencesButton.checked = true + settingsButton.checked = true } function checkSetupButton() { @@ -68,6 +69,10 @@ Rectangle { flyButton.checked = true } + function checkAnalyzeButton() { + analyzeButton.checked = true + } + function getBatteryColor() { if(activeVehicle) { if(activeVehicle.battery.percentRemaining.value > 75) { @@ -325,7 +330,7 @@ Rectangle { ExclusiveGroup { id: mainActionGroup } QGCToolBarButton { - id: preferencesButton + id: settingsButton width: mainWindow.tbButtonWidth anchors.top: parent.top anchors.bottom: parent.bottom @@ -364,6 +369,17 @@ Rectangle { source: "/qmlimages/PaperPlane.svg" onClicked: toolBar.showFlyView() } + + QGCToolBarButton { + id: analyzeButton + width: mainWindow.tbButtonWidth + anchors.top: parent.top + anchors.bottom: parent.bottom + exclusiveGroup: mainActionGroup + source: "/qmlimages/Analyze.svg" + visible: !ScreenTools.isMobile + onClicked: toolBar.showAnalyzeView() + } } Item { -- 2.22.0