From fb8a050bddd663ec1d5eec0126ca4b9235464898 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Fri, 29 May 2015 09:28:59 -0700 Subject: [PATCH] SetupView converted to Qml only --- QGCApplication.pro | 3 - qgroundcontrol.qrc | 1 + src/AutoPilotPlugins/AutoPilotPlugin.cc | 14 +- src/AutoPilotPlugins/AutoPilotPlugin.h | 4 + src/AutoPilotPlugins/PX4/AirframeComponent.cc | 11 +- src/AutoPilotPlugins/PX4/AirframeComponent.h | 2 +- .../PX4/FlightModesComponent.cc | 11 +- .../PX4/FlightModesComponent.h | 2 +- src/AutoPilotPlugins/PX4/PowerComponent.cc | 8 +- src/AutoPilotPlugins/PX4/PowerComponent.h | 2 +- src/AutoPilotPlugins/PX4/RadioComponent.cc | 8 +- src/AutoPilotPlugins/PX4/RadioComponent.h | 2 +- src/AutoPilotPlugins/PX4/SafetyComponent.cc | 11 +- src/AutoPilotPlugins/PX4/SafetyComponent.h | 2 +- src/AutoPilotPlugins/PX4/SensorsComponent.cc | 10 +- src/AutoPilotPlugins/PX4/SensorsComponent.h | 2 +- src/FactSystem/FactSystem.cc | 2 - src/QGCApplication.cc | 15 +- src/QGCQmlWidgetHolder.cpp | 7 +- src/QGCQmlWidgetHolder.h | 5 +- src/VehicleSetup/SetupView.cc | 146 +++++-------- src/VehicleSetup/SetupView.h | 38 ++-- src/VehicleSetup/SetupView.qml | 199 ++++++++++++++++++ src/VehicleSetup/SetupView.ui | 66 ------ src/VehicleSetup/SetupViewTest.cc | 13 +- src/VehicleSetup/VehicleComponent.h | 4 +- src/VehicleSetup/VehicleSummary.qml | 14 +- src/uas/UASInterface.h | 2 - 28 files changed, 347 insertions(+), 257 deletions(-) create mode 100644 src/VehicleSetup/SetupView.qml delete mode 100644 src/VehicleSetup/SetupView.ui diff --git a/QGCApplication.pro b/QGCApplication.pro index cb8e95428..c8575e3b0 100644 --- a/QGCApplication.pro +++ b/QGCApplication.pro @@ -546,9 +546,6 @@ INCLUDEPATH += \ src/VehicleSetup \ src/AutoPilotPlugins/PX4 \ -FORMS += \ - src/VehicleSetup/SetupView.ui \ - HEADERS+= \ src/AutoPilotPlugins/AutoPilotPlugin.h \ src/AutoPilotPlugins/AutoPilotPluginManager.h \ diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 02dee6604..575b191d2 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -43,6 +43,7 @@ src/ViewWidgets/ParameterEditorWidget.qml src/ViewWidgets/CustomCommandWidget.qml + src/VehicleSetup/SetupView.qml src/VehicleSetup/SetupViewButtonsConnected.qml src/VehicleSetup/SetupViewButtonsDisconnected.qml diff --git a/src/AutoPilotPlugins/AutoPilotPlugin.cc b/src/AutoPilotPlugins/AutoPilotPlugin.cc index 41765aeec..f2b09e692 100644 --- a/src/AutoPilotPlugins/AutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/AutoPilotPlugin.cc @@ -25,7 +25,6 @@ /// @author Don Gagne #include "AutoPilotPlugin.h" -#include "SetupView.h" #include "QGCApplication.h" #include "QGCMessageBox.h" #include "MainWindow.h" @@ -40,6 +39,8 @@ AutoPilotPlugin::AutoPilotPlugin(UASInterface* uas, QObject* parent) : Q_ASSERT(_uas); connect(_uas, &UASInterface::disconnected, this, &AutoPilotPlugin::_uasDisconnected); + connect(_uas, &UASInterface::armingChanged, this, &AutoPilotPlugin::armedChanged); + connect(this, &AutoPilotPlugin::pluginReadyChanged, this, &AutoPilotPlugin::_pluginReadyChanged); } @@ -66,12 +67,6 @@ void AutoPilotPlugin::_pluginReadyChanged(bool pluginReady) Q_ASSERT(mainWindow); mainWindow->getMainToolBar()->onSetupView(); qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents); - QWidget* setupViewWidget = mainWindow->getCurrentViewWidget(); - Q_ASSERT(setupViewWidget); - SetupView* setupView = qobject_cast(setupViewWidget); - Q_ASSERT(setupView); - setupView->summaryButtonClicked(); - qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents); } } } @@ -172,3 +167,8 @@ void AutoPilotPlugin::readParametersFromStream(QTextStream &stream) { _getParameterLoader()->readParametersFromStream(stream); } + +bool AutoPilotPlugin::armed(void) +{ + return _uas->isArmed(); +} diff --git a/src/AutoPilotPlugins/AutoPilotPlugin.h b/src/AutoPilotPlugins/AutoPilotPlugin.h index 4fbd9435f..f5367d6ca 100644 --- a/src/AutoPilotPlugins/AutoPilotPlugin.h +++ b/src/AutoPilotPlugins/AutoPilotPlugin.h @@ -61,6 +61,8 @@ public: /// false: One or more vehicle components require setup Q_PROPERTY(bool setupComplete READ setupComplete NOTIFY setupCompleteChanged) + + Q_PROPERTY(bool armed READ armed NOTIFY armedChanged) /// Re-request the full set of parameters from the autopilot Q_INVOKABLE void refreshAllParameters(void); @@ -111,6 +113,7 @@ public: // Property accessors bool pluginReady(void) { return _pluginReady; } bool setupComplete(void); + bool armed(void); UASInterface* uas(void) { return _uas; } @@ -118,6 +121,7 @@ signals: void pluginReadyChanged(bool pluginReady); void setupCompleteChanged(bool setupComplete); void parameterListProgress(float value); + void armedChanged(bool armed); protected: /// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin diff --git a/src/AutoPilotPlugins/PX4/AirframeComponent.cc b/src/AutoPilotPlugins/PX4/AirframeComponent.cc index f3c5fcd27..dbda69dbd 100644 --- a/src/AutoPilotPlugins/PX4/AirframeComponent.cc +++ b/src/AutoPilotPlugins/PX4/AirframeComponent.cc @@ -171,16 +171,9 @@ QStringList AirframeComponent::paramFilterList(void) const return list; } -QWidget* AirframeComponent::setupWidget(void) const +QUrl AirframeComponent::setupSource(void) const { - QGCQmlWidgetHolder* holder = new QGCQmlWidgetHolder(); - Q_CHECK_PTR(holder); - - holder->setAutoPilot(_autopilot); - - holder->setSource(QUrl::fromUserInput("qrc:/qml/AirframeComponent.qml")); - - return holder; + return QUrl::fromUserInput("qrc:/qml/AirframeComponent.qml"); } QUrl AirframeComponent::summaryQmlSource(void) const diff --git a/src/AutoPilotPlugins/PX4/AirframeComponent.h b/src/AutoPilotPlugins/PX4/AirframeComponent.h index 9a25d80ba..8c02eb4cb 100644 --- a/src/AutoPilotPlugins/PX4/AirframeComponent.h +++ b/src/AutoPilotPlugins/PX4/AirframeComponent.h @@ -47,7 +47,7 @@ public: virtual bool requiresSetup(void) const; virtual bool setupComplete(void) const; virtual QString setupStateDescription(void) const; - virtual QWidget* setupWidget(void) const; + virtual QUrl setupSource(void) const; virtual QStringList paramFilterList(void) const; virtual QUrl summaryQmlSource(void) const; virtual QString prerequisiteSetup(void) const; diff --git a/src/AutoPilotPlugins/PX4/FlightModesComponent.cc b/src/AutoPilotPlugins/PX4/FlightModesComponent.cc index f7f5e2266..02f6893cc 100644 --- a/src/AutoPilotPlugins/PX4/FlightModesComponent.cc +++ b/src/AutoPilotPlugins/PX4/FlightModesComponent.cc @@ -104,16 +104,9 @@ QStringList FlightModesComponent::paramFilterList(void) const return list; } -QWidget* FlightModesComponent::setupWidget(void) const +QUrl FlightModesComponent::setupSource(void) const { - QGCQmlWidgetHolder* holder = new QGCQmlWidgetHolder(); - Q_CHECK_PTR(holder); - - holder->setAutoPilot(_autopilot); - - holder->setSource(QUrl::fromUserInput("qrc:/qml/FlightModesComponent.qml")); - - return holder; + return QUrl::fromUserInput("qrc:/qml/FlightModesComponent.qml"); } QUrl FlightModesComponent::summaryQmlSource(void) const diff --git a/src/AutoPilotPlugins/PX4/FlightModesComponent.h b/src/AutoPilotPlugins/PX4/FlightModesComponent.h index 097bb1171..19e772f82 100644 --- a/src/AutoPilotPlugins/PX4/FlightModesComponent.h +++ b/src/AutoPilotPlugins/PX4/FlightModesComponent.h @@ -47,7 +47,7 @@ public: virtual bool requiresSetup(void) const; virtual bool setupComplete(void) const; virtual QString setupStateDescription(void) const; - virtual QWidget* setupWidget(void) const; + virtual QUrl setupSource(void) const; virtual QStringList paramFilterList(void) const; virtual QUrl summaryQmlSource(void) const; virtual QString prerequisiteSetup(void) const; diff --git a/src/AutoPilotPlugins/PX4/PowerComponent.cc b/src/AutoPilotPlugins/PX4/PowerComponent.cc index cb2f404b2..093e67c61 100644 --- a/src/AutoPilotPlugins/PX4/PowerComponent.cc +++ b/src/AutoPilotPlugins/PX4/PowerComponent.cc @@ -86,13 +86,9 @@ QStringList PowerComponent::paramFilterList(void) const return list; } -QWidget* PowerComponent::setupWidget(void) const +QUrl PowerComponent::setupSource(void) const { - QGCQmlWidgetHolder* holder = new QGCQmlWidgetHolder(); - Q_CHECK_PTR(holder); - holder->setAutoPilot(_autopilot); - holder->setSource(QUrl::fromUserInput("qrc:/qml/PowerComponent.qml")); - return holder; + return QUrl::fromUserInput("qrc:/qml/PowerComponent.qml"); } QUrl PowerComponent::summaryQmlSource(void) const diff --git a/src/AutoPilotPlugins/PX4/PowerComponent.h b/src/AutoPilotPlugins/PX4/PowerComponent.h index a89ef9a4a..ca0841c8d 100644 --- a/src/AutoPilotPlugins/PX4/PowerComponent.h +++ b/src/AutoPilotPlugins/PX4/PowerComponent.h @@ -47,7 +47,7 @@ public: virtual bool requiresSetup (void) const; virtual bool setupComplete (void) const; virtual QString setupStateDescription (void) const; - virtual QWidget* setupWidget (void) const; + virtual QUrl setupSource (void) const; virtual QStringList paramFilterList (void) const; virtual QUrl summaryQmlSource (void) const; virtual QString prerequisiteSetup (void) const; diff --git a/src/AutoPilotPlugins/PX4/RadioComponent.cc b/src/AutoPilotPlugins/PX4/RadioComponent.cc index 5040baf70..a45346b81 100644 --- a/src/AutoPilotPlugins/PX4/RadioComponent.cc +++ b/src/AutoPilotPlugins/PX4/RadioComponent.cc @@ -138,13 +138,9 @@ QStringList RadioComponent::paramFilterList(void) const return list; } -QWidget* RadioComponent::setupWidget(void) const +QUrl RadioComponent::setupSource(void) const { - QGCQmlWidgetHolder* holder = new QGCQmlWidgetHolder(); - Q_CHECK_PTR(holder); - holder->setAutoPilot(_autopilot); - holder->setSource(QUrl::fromUserInput("qrc:/qml/RadioComponent.qml")); - return holder; + return QUrl::fromUserInput("qrc:/qml/RadioComponent.qml"); } QUrl RadioComponent::summaryQmlSource(void) const diff --git a/src/AutoPilotPlugins/PX4/RadioComponent.h b/src/AutoPilotPlugins/PX4/RadioComponent.h index 9ed4ff1cd..7e4bf5776 100644 --- a/src/AutoPilotPlugins/PX4/RadioComponent.h +++ b/src/AutoPilotPlugins/PX4/RadioComponent.h @@ -48,7 +48,7 @@ public: virtual bool requiresSetup(void) const; virtual bool setupComplete(void) const; virtual QString setupStateDescription(void) const; - virtual QWidget* setupWidget(void) const; + virtual QUrl setupSource(void) const; virtual QStringList paramFilterList(void) const; virtual QUrl summaryQmlSource(void) const; virtual QString prerequisiteSetup(void) const; diff --git a/src/AutoPilotPlugins/PX4/SafetyComponent.cc b/src/AutoPilotPlugins/PX4/SafetyComponent.cc index 6e71a9941..d0e06df3c 100644 --- a/src/AutoPilotPlugins/PX4/SafetyComponent.cc +++ b/src/AutoPilotPlugins/PX4/SafetyComponent.cc @@ -84,16 +84,9 @@ QStringList SafetyComponent::paramFilterList(void) const return list; } -QWidget* SafetyComponent::setupWidget(void) const +QUrl SafetyComponent::setupSource(void) const { - QGCQmlWidgetHolder* holder = new QGCQmlWidgetHolder(); - Q_CHECK_PTR(holder); - - holder->setAutoPilot(_autopilot); - - holder->setSource(QUrl::fromUserInput("qrc:/qml/SafetyComponent.qml")); - - return holder; + return QUrl::fromUserInput("qrc:/qml/SafetyComponent.qml"); } QUrl SafetyComponent::summaryQmlSource(void) const diff --git a/src/AutoPilotPlugins/PX4/SafetyComponent.h b/src/AutoPilotPlugins/PX4/SafetyComponent.h index b915f02f7..cdcc68bfa 100644 --- a/src/AutoPilotPlugins/PX4/SafetyComponent.h +++ b/src/AutoPilotPlugins/PX4/SafetyComponent.h @@ -48,7 +48,7 @@ public: virtual bool requiresSetup(void) const; virtual bool setupComplete(void) const; virtual QString setupStateDescription(void) const; - virtual QWidget* setupWidget(void) const; + virtual QUrl setupSource(void) const; virtual QStringList paramFilterList(void) const; virtual QUrl summaryQmlSource(void) const; virtual QString prerequisiteSetup(void) const; diff --git a/src/AutoPilotPlugins/PX4/SensorsComponent.cc b/src/AutoPilotPlugins/PX4/SensorsComponent.cc index ac931624c..d7e4b7a83 100644 --- a/src/AutoPilotPlugins/PX4/SensorsComponent.cc +++ b/src/AutoPilotPlugins/PX4/SensorsComponent.cc @@ -105,15 +105,9 @@ QStringList SensorsComponent::paramFilterList(void) const return list; } -QWidget* SensorsComponent::setupWidget(void) const +QUrl SensorsComponent::setupSource(void) const { - QGCQmlWidgetHolder* holder = new QGCQmlWidgetHolder(); - Q_CHECK_PTR(holder); - - holder->setAutoPilot(_autopilot); - holder->setSource(QUrl::fromUserInput("qrc:/qml/SensorsComponent.qml")); - - return holder; + return QUrl::fromUserInput("qrc:/qml/SensorsComponent.qml"); } QUrl SensorsComponent::summaryQmlSource(void) const diff --git a/src/AutoPilotPlugins/PX4/SensorsComponent.h b/src/AutoPilotPlugins/PX4/SensorsComponent.h index 699822e15..5ce0e00fc 100644 --- a/src/AutoPilotPlugins/PX4/SensorsComponent.h +++ b/src/AutoPilotPlugins/PX4/SensorsComponent.h @@ -47,7 +47,7 @@ public: virtual bool requiresSetup(void) const; virtual bool setupComplete(void) const; virtual QString setupStateDescription(void) const; - virtual QWidget* setupWidget(void) const; + virtual QUrl setupSource(void) const; virtual QStringList paramFilterList(void) const; virtual QUrl summaryQmlSource(void) const; virtual QString prerequisiteSetup(void) const; diff --git a/src/FactSystem/FactSystem.cc b/src/FactSystem/FactSystem.cc index 05caa927a..32409fabf 100644 --- a/src/FactSystem/FactSystem.cc +++ b/src/FactSystem/FactSystem.cc @@ -27,7 +27,6 @@ #include "FactSystem.h" #include "UASManager.h" #include "QGCApplication.h" -#include "VehicleComponent.h" #include "FactPanelController.h" #include @@ -42,7 +41,6 @@ FactSystem::FactSystem(QObject* parent) : qmlRegisterType(_factSystemQmlUri, 1, 0, "Fact"); qmlRegisterType(_factSystemQmlUri, 1, 0, "FactPanelController"); - qmlRegisterUncreatableType(_factSystemQmlUri, 1, 0, "VehicleComponent", "Can only reference, cannot create"); } FactSystem::~FactSystem() diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index f66e7b9bb..3724033d5 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -67,6 +67,11 @@ #include "SensorsComponentController.h" #include "PowerComponentController.h" #include "RadioComponentController.h" +#ifndef __android__ +#include "FirmwareUpgradeController.h" +#endif +#include "AutoPilotPlugin.h" +#include "VehicleComponent.h" #include "ScreenTools.h" #include "MavManager.h" @@ -318,6 +323,9 @@ void QGCApplication::_initCommon(void) qmlRegisterType("QGroundControl.Palette", 1, 0, "QGCPalette"); + qmlRegisterUncreatableType("QGroundControl.AutoPilotPlugin", 1, 0, "AutoPilotPlugin", "Can only reference, cannot create"); + qmlRegisterUncreatableType("QGroundControl.AutoPilotPlugin", 1, 0, "VehicleComponent", "Can only reference, cannot create"); + qmlRegisterType("QGroundControl.Controllers", 1, 0, "ViewWidgetController"); qmlRegisterType("QGroundControl.Controllers", 1, 0, "ParameterEditorController"); qmlRegisterType("QGroundControl.Controllers", 1, 0, "CustomCommandWidgetController"); @@ -326,7 +334,10 @@ void QGCApplication::_initCommon(void) qmlRegisterType("QGroundControl.Controllers", 1, 0, "SensorsComponentController"); qmlRegisterType("QGroundControl.Controllers", 1, 0, "PowerComponentController"); qmlRegisterType("QGroundControl.Controllers", 1, 0, "RadioComponentController"); - +#ifndef __android__ + qmlRegisterType("QGroundControl.Controllers", 1, 0, "FirmwareUpgradeController"); +#endif + //-- Create QML Singleton Interfaces qmlRegisterSingletonType("QGroundControl.ScreenTools", 1, 0, "ScreenTools", screenToolsSingletonFactory); qmlRegisterSingletonType("QGroundControl.MavManager", 1, 0, "MavManager", mavManagerSingletonFactory); @@ -372,7 +383,7 @@ bool QGCApplication::_initForNormalAppBoot(void) splashScreen->finish(mainWindow); mainWindow->splashScreenFinished(); - // Now that main window is upcheck for lost log files + // Now that main window is up check for lost log files connect(this, &QGCApplication::checkForLostLogFiles, MAVLinkProtocol::instance(), &MAVLinkProtocol::checkForLostLogFiles); emit checkForLostLogFiles(); diff --git a/src/QGCQmlWidgetHolder.cpp b/src/QGCQmlWidgetHolder.cpp index d9e1d20b8..9651cf262 100644 --- a/src/QGCQmlWidgetHolder.cpp +++ b/src/QGCQmlWidgetHolder.cpp @@ -53,7 +53,12 @@ void QGCQmlWidgetHolder::setContextPropertyObject(const QString& name, QObject* _ui.qmlWidget->rootContext()->setContextProperty(name, object); } -QQmlContext* QGCQmlWidgetHolder::getRootContext() +QQmlContext* QGCQmlWidgetHolder::getRootContext(void) { return _ui.qmlWidget->rootContext(); } + +QQuickItem* QGCQmlWidgetHolder::getRootObject(void) +{ + return _ui.qmlWidget->rootObject(); +} diff --git a/src/QGCQmlWidgetHolder.h b/src/QGCQmlWidgetHolder.h index 9acbf16e2..0439d01b8 100644 --- a/src/QGCQmlWidgetHolder.h +++ b/src/QGCQmlWidgetHolder.h @@ -50,8 +50,11 @@ public: void setAutoPilot(AutoPilotPlugin* autoPilot); /// Get Root Context - QQmlContext* getRootContext(); + QQmlContext* getRootContext(void); + /// Get Root Object + QQuickItem* getRootObject(void); + /// Sets the QML into the control. Will display errors message box if error occurs loading source. /// @return true: source loaded, false: source not loaded, errors occured bool setSource(const QUrl& qmlUrl); diff --git a/src/VehicleSetup/SetupView.cc b/src/VehicleSetup/SetupView.cc index 3878600e0..fa8398811 100644 --- a/src/VehicleSetup/SetupView.cc +++ b/src/VehicleSetup/SetupView.cc @@ -43,26 +43,20 @@ #include SetupView::SetupView(QWidget* parent) : - QWidget(parent), + QGCQmlWidgetHolder(parent), _uasCurrent(NULL), - _initComplete(false), - _autoPilotPlugin(NULL), - _currentSetupWidget(NULL), - _ui(new Ui::SetupView) + _initComplete(false) { - _ui->setupUi(this); - - bool fSucceeded = connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(_setActiveUAS(UASInterface*))); - Q_UNUSED(fSucceeded); - Q_ASSERT(fSucceeded); - -#ifndef __android__ - qmlRegisterType("QGroundControl.Controllers", 1, 0, "FirmwareUpgradeController"); +#ifdef __android__ + _showFirmware = false; +#else + _showFirmware = true; #endif - - _ui->buttonHolder->rootContext()->setContextProperty("controller", this); - _ui->buttonHolder->setAutoPilot(NULL); - _ui->buttonHolder->setSource(QUrl::fromUserInput("qrc:/qml/SetupViewButtonsDisconnected.qml")); + + connect(UASManager::instance(), &UASManager::activeUASSet, this, &SetupView::_setActiveUAS); + + getRootContext()->setContextProperty("controller", this); + setSource(QUrl::fromUserInput("qrc:/qml/SetupView.qml")); _setActiveUAS(UASManager::instance()->getActiveUAS()); } @@ -75,8 +69,7 @@ SetupView::~SetupView() void SetupView::_setActiveUAS(UASInterface* uas) { if (_uasCurrent) { - Q_ASSERT(_autoPilotPlugin); - disconnect(_autoPilotPlugin, &AutoPilotPlugin::pluginReadyChanged, this, &SetupView::_pluginReadyChanged); + disconnect(_autopilot.data(), &AutoPilotPlugin::pluginReadyChanged, this, &SetupView::_pluginReadyChanged); } _pluginReadyChanged(false); @@ -84,98 +77,69 @@ void SetupView::_setActiveUAS(UASInterface* uas) _uasCurrent = uas; if (_uasCurrent) { - _autoPilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uasCurrent).data(); - _pluginReadyChanged(_autoPilotPlugin->pluginReady()); - connect(_autoPilotPlugin, &AutoPilotPlugin::pluginReadyChanged, this, &SetupView::_pluginReadyChanged); + _autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uasCurrent); + if (_autopilot.data()->pluginReady()) { + _pluginReadyChanged(_autopilot.data()->pluginReady()); + } + connect(_autopilot.data(), &AutoPilotPlugin::pluginReadyChanged, this, &SetupView::_pluginReadyChanged); } } void SetupView::_pluginReadyChanged(bool pluginReady) { if (pluginReady) { - _ui->buttonHolder->setAutoPilot(_autoPilotPlugin); - _ui->buttonHolder->setSource(QUrl::fromUserInput("qrc:/qml/SetupViewButtonsConnected.qml")); - summaryButtonClicked(); - QObject* button = _ui->buttonHolder->rootObject()->findChild("summaryButton"); - Q_ASSERT(button); - button->setProperty("checked", true); + _readyAutopilot = _autopilot.data(); + emit autopilotChanged(_readyAutopilot); } else { - _ui->buttonHolder->setSource(QUrl::fromUserInput("qrc:/qml/SetupViewButtonsDisconnected.qml")); - _ui->buttonHolder->setAutoPilot(NULL); - firmwareButtonClicked(); - QObject* button = _ui->buttonHolder->rootObject()->findChild("firmwareButton"); - Q_ASSERT(button); - button->setProperty("checked", true); + _readyAutopilot = NULL; + emit autopilotChanged(NULL); + _autopilot.clear(); } } -void SetupView::_changeSetupWidget(QWidget* newWidget) -{ - if (_currentSetupWidget) { - delete _currentSetupWidget; - } - _currentSetupWidget = newWidget; - _ui->horizontalLayout->addWidget(newWidget); -} - -void SetupView::firmwareButtonClicked(void) +#ifdef UNITTEST_BUILD +void SetupView::showFirmware(void) { #ifndef __android__ - //FIXME: Hack out for android for now - if (_uasCurrent && _uasCurrent->isArmed()) { - QGCMessageBox::warning("Setup", "Firmware Update cannot be performed while vehicle is armed."); - return; - } - - QGCQmlWidgetHolder* setup = new QGCQmlWidgetHolder; - Q_CHECK_PTR(setup); - - setup->setSource(QUrl::fromUserInput("qrc:/qml/FirmwareUpgrade.qml")); - - _changeSetupWidget(setup); + QVariant returnedValue; + bool success = QMetaObject::invokeMethod(getRootObject(), + "showFirmwarePanel", + Q_RETURN_ARG(QVariant, returnedValue)); + Q_ASSERT(success); #endif } -void SetupView::parametersButtonClicked(void) +void SetupView::showParameters(void) { - QGCQmlWidgetHolder* setup = new QGCQmlWidgetHolder; - Q_CHECK_PTR(setup); - - Q_ASSERT(_autoPilotPlugin); - setup->setAutoPilot(_autoPilotPlugin); - setup->setSource(QUrl::fromUserInput("qrc:/qml/SetupParameterEditor.qml")); - - _changeSetupWidget(setup); + QVariant returnedValue; + bool success = QMetaObject::invokeMethod(getRootObject(), + "showParametersPanel", + Q_RETURN_ARG(QVariant, returnedValue)); + Q_ASSERT(success); } -void SetupView::summaryButtonClicked(void) +void SetupView::showSummary(void) { - Q_ASSERT(_autoPilotPlugin); - - QGCQmlWidgetHolder* summary = new QGCQmlWidgetHolder; - Q_CHECK_PTR(summary); - - summary->setAutoPilot(_autoPilotPlugin); - summary->setSource(QUrl::fromUserInput("qrc:/qml/VehicleSummary.qml")); - - _changeSetupWidget(summary); + QVariant returnedValue; + bool success = QMetaObject::invokeMethod(getRootObject(), + "showSummaryPanel", + Q_RETURN_ARG(QVariant, returnedValue)); + Q_ASSERT(success); } -void SetupView::setupButtonClicked(const QVariant& component) +void SetupView::showVehicleComponentSetup(const QUrl& url) { - if (_uasCurrent->isArmed()) { - QGCMessageBox::warning("Setup", "Setup cannot be performed while vehicle is armed."); - return; - } - - VehicleComponent* vehicle = qobject_cast(component.value()); - Q_ASSERT(vehicle); - - QString setupPrereq = vehicle->prerequisiteSetup(); - if (!setupPrereq.isEmpty()) { - QGCMessageBox::warning("Setup", QString("%1 setup must be completed prior to %2 setup.").arg(setupPrereq).arg(vehicle->name())); - return; - } - - _changeSetupWidget(vehicle->setupWidget()); + QVariant returnedValue; + QVariant varSource = url; + bool success = QMetaObject::invokeMethod(getRootObject(), + "showVehicleComponentPanel", + Q_RETURN_ARG(QVariant, returnedValue), + Q_ARG(QVariant, varSource)); + Q_ASSERT(success); } +#endif + +AutoPilotPlugin* SetupView::autopilot(void) +{ + return _readyAutopilot; +} \ No newline at end of file diff --git a/src/VehicleSetup/SetupView.h b/src/VehicleSetup/SetupView.h index 0a931ca03..dcca47bed 100644 --- a/src/VehicleSetup/SetupView.h +++ b/src/VehicleSetup/SetupView.h @@ -27,6 +27,7 @@ #include "UASInterface.h" #include "VehicleComponent.h" #include "AutoPilotPlugin.h" +#include "QGCQmlWidgetHolder.h" #include @@ -34,11 +35,7 @@ /// @brief This class is used to display the UI for the VehicleComponent objects. /// @author Don Gagne -namespace Ui { - class SetupView; -} - -class SetupView : public QWidget +class SetupView : public QGCQmlWidgetHolder { Q_OBJECT @@ -46,24 +43,31 @@ public: explicit SetupView(QWidget* parent = 0); ~SetupView(); - Q_INVOKABLE void firmwareButtonClicked(void); - Q_INVOKABLE void parametersButtonClicked(void); - Q_INVOKABLE void summaryButtonClicked(void); - Q_INVOKABLE void setupButtonClicked(const QVariant& component); + Q_PROPERTY(AutoPilotPlugin* autopilot READ autopilot NOTIFY autopilotChanged) + Q_PROPERTY (bool showFirmware MEMBER _showFirmware CONSTANT) + +#ifdef UNITTEST_BUILD + void showFirmware(void); + void showParameters(void); + void showSummary(void); + void showVehicleComponentSetup(const QUrl& url); +#endif + + AutoPilotPlugin* autopilot(void); + +signals: + void autopilotChanged(AutoPilotPlugin* autopilot); private slots: void _setActiveUAS(UASInterface* uas); void _pluginReadyChanged(bool pluginReady); private: - void _changeSetupWidget(QWidget* newWidget); - - UASInterface* _uasCurrent; ///< Currently active UAS - bool _initComplete; ///< true: parameters are ready and ui has been setup - AutoPilotPlugin* _autoPilotPlugin; - QWidget* _currentSetupWidget; - - Ui::SetupView* _ui; + UASInterface* _uasCurrent; + bool _initComplete; ///< true: parameters are ready and ui has been setup + QSharedPointer _autopilot; // Shared pointer to prevent shutdown ordering problems + AutoPilotPlugin* _readyAutopilot; // NULL if autopilot is not yet read + bool _showFirmware; }; #endif diff --git a/src/VehicleSetup/SetupView.qml b/src/VehicleSetup/SetupView.qml new file mode 100644 index 000000000..3dd60eadb --- /dev/null +++ b/src/VehicleSetup/SetupView.qml @@ -0,0 +1,199 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009, 2015 QGROUNDCONTROL PROJECT + +This file is part of the QGROUNDCONTROL project + +QGROUNDCONTROL is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +QGROUNDCONTROL is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/// @file +/// @brief Setup View +/// @author Don Gagne + +import QtQuick 2.3 +import QtQuick.Controls 1.2 + +import QGroundControl.AutoPilotPlugin 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 + +Rectangle { + id: topLevel + color: palette.window + + QGCPalette { id: palette; colorGroupEnabled: true } + + ExclusiveGroup { id: setupButtonGroup } + + QGCLabel { id: _textMeasure; text: "X"; visible: false } + + readonly property real defaultTextHeight: _textMeasure.contentHeight + readonly property real defaultTextWidth: _textMeasure.contentWidth + readonly property real buttonWidth: defaultTextWidth * 15 + + property string messagePanelText: "missing message panel text" + readonly property string armedVehicleText: "This operation cannot be performed while vehicle is armed." + + function showSummaryPanel() + { + if (controller.autopilot) { + panelLoader.source = "VehicleSummary.qml"; + } else { + panelLoader.sourceComponent = disconnectedVehicleSummaryComponent + } + } + + function showFirmwarePanel() + { + if (controller.showFirmware) { + if (controller.autopilot && controller.autopilot.armed) { + messagePanelText = armedVehicleText + panelLoader.sourceComponent = messagePanelComponent + } else { + panelLoader.source = "FirmwareUpgrade.qml"; + } + } + } + + function showParametersPanel() + { + panelLoader.source = "SetupParameterEditor.qml"; + } + + function showVehicleComponentPanel(setupSource) + { + if (controller.autopilot.armed) { + messagePanelText = armedVehicleText + panelLoader.sourceComponent = messagePanelComponent + } else { + panelLoader.source = setupSource + } + } + + Connections { + target: controller + + onAutopilotChanged: { + summaryButton.checked = true + showSummaryPanel() + } + } + + Component.onCompleted: showSummaryPanel() + + Component { + id: disconnectedVehicleSummaryComponent + + Rectangle { + color: palette.windowShade + + QGCLabel { + anchors.margins: defaultTextWidth * 2 + anchors.fill: parent + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + font.pointSize: ScreenTools.mediumFontPointSize + text: "Welcome to QGroundControl. " + + "QGroundControl supports any mavlink enabled vehicle. " + + "If you are using the PX4 Flight Stack, you also get full support for setting up and calibrating your vehicle. "+ + "Otherwise you will only get support for flying a vehicle which has been setup and calibrated using other means. " + + "Use the Connect button above to connect to your vehicle." + + onLinkActivated: Qt.openUrlExternally(link) + } + } + } + + Component { + id: messagePanelComponent + + Item { + QGCLabel { + anchors.fill: parent + wrapMode: Text.WordWrap + text: messagePanelText + } + } + } + + Column { + id: buttonColumn + width: buttonWidth + + SubMenuButton { + id: summaryButton + width: buttonWidth + imageResource: "VehicleSummaryIcon.png" + setupIndicator: false + exclusiveGroup: setupButtonGroup + text: "SUMMARY" + + onClicked: showSummaryPanel() + } + + SubMenuButton { + id: firmwareButton + width: buttonWidth + imageResource: "FirmwareUpgradeIcon.png" + setupIndicator: false + exclusiveGroup: setupButtonGroup + visible: controller.showFirmware + text: "FIRMWARE" + + onClicked: showFirmwarePanel() + } + + Repeater { + model: controller.autopilot ? controller.autopilot.vehicleComponents : 0 + + SubMenuButton { + width: buttonWidth + imageResource: modelData.iconResource + setupComplete: modelData.setupComplete + exclusiveGroup: setupButtonGroup + text: modelData.name.toUpperCase() + + onClicked: showVehicleComponentPanel(modelData.setupSource) + } + } + + SubMenuButton { + width: buttonWidth + setupIndicator: false + exclusiveGroup: setupButtonGroup + visible: controller.autopilot + text: "PARAMETERS" + + onClicked: showParametersPanel() + } + } // Column + + Loader { + id: panelLoader + anchors.leftMargin: defaultTextWidth + anchors.rightMargin: defaultTextWidth + anchors.left: buttonColumn.right + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + + property var autopilot: controller.autopilot + } +} diff --git a/src/VehicleSetup/SetupView.ui b/src/VehicleSetup/SetupView.ui deleted file mode 100644 index 1c0358cd5..000000000 --- a/src/VehicleSetup/SetupView.ui +++ /dev/null @@ -1,66 +0,0 @@ - - - SetupView - - - - 0 - 0 - 946 - 821 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 125 - 0 - - - - - 125 - 16777215 - - - - QGCQuickWidget::SizeRootObjectToView - - - - - - - - QGCQuickWidget - QQuickWidget -
QGCQuickWidget.h
- 1 -
-
- - -
diff --git a/src/VehicleSetup/SetupViewTest.cc b/src/VehicleSetup/SetupViewTest.cc index 54a544f23..72449715e 100644 --- a/src/VehicleSetup/SetupViewTest.cc +++ b/src/VehicleSetup/SetupViewTest.cc @@ -92,16 +92,21 @@ void SetupViewTest::_clickThrough_test(void) Q_ASSERT(setupView); // Click through fixed buttons - setupView->firmwareButtonClicked(); + qDebug() << "Showing firmware"; + setupView->showFirmware(); QTest::qWait(1000); - setupView->parametersButtonClicked(); + qDebug() << "Showing parameters"; + setupView->showParameters(); QTest::qWait(1000); - setupView->summaryButtonClicked(); + qDebug() << "Showing summary"; + setupView->showSummary(); QTest::qWait(1000); const QVariantList& components = autopilot->vehicleComponents(); foreach(QVariant varComponent, components) { - setupView->setupButtonClicked(varComponent); + VehicleComponent* component = qobject_cast(qvariant_cast(varComponent)); + qDebug() << "Showing" << component->name(); + setupView->showVehicleComponentSetup(component->setupSource()); } // On MainWindow close we should get a message box telling the user to disconnect first. Disconnect will then pop diff --git a/src/VehicleSetup/VehicleComponent.h b/src/VehicleSetup/VehicleComponent.h index 5d928cfc4..3756a812a 100644 --- a/src/VehicleSetup/VehicleComponent.h +++ b/src/VehicleSetup/VehicleComponent.h @@ -48,7 +48,7 @@ class VehicleComponent : public QObject Q_PROPERTY(bool setupComplete READ setupComplete STORED false NOTIFY setupCompleteChanged) Q_PROPERTY(QString setupStateDescription READ setupStateDescription STORED false) Q_PROPERTY(QString iconResource READ iconResource CONSTANT) - Q_PROPERTY(QWidget* setupWidget READ setupWidget STORED false) + Q_PROPERTY(QUrl setupSource READ setupSource CONSTANT) Q_PROPERTY(QUrl summaryQmlSource READ summaryQmlSource CONSTANT); Q_PROPERTY(QString prerequisiteSetup READ prerequisiteSetup) @@ -62,7 +62,7 @@ public: virtual bool requiresSetup(void) const = 0; virtual bool setupComplete(void) const = 0; virtual QString setupStateDescription(void) const = 0; - virtual QWidget* setupWidget(void) const = 0; + virtual QUrl setupSource(void) const = 0; virtual QStringList paramFilterList(void) const = 0; virtual QUrl summaryQmlSource(void) const = 0; virtual QString prerequisiteSetup(void) const = 0; diff --git a/src/VehicleSetup/VehicleSummary.qml b/src/VehicleSetup/VehicleSummary.qml index 63331d0b9..21657f06d 100644 --- a/src/VehicleSetup/VehicleSummary.qml +++ b/src/VehicleSetup/VehicleSummary.qml @@ -58,11 +58,13 @@ Rectangle { QGCLabel { width: parent.width wrapMode: Text.WordWrap - color: autopilot.setupComplete ? qgcPal.text : "red" - font.pointSize: autopilot.setupComplete ? ScreenTools.defaultFontPointSize : ScreenTools.fontPointFactor * (20) - text: autopilot.setupComplete ? - "Below you will find a summary of the settings for your vehicle. To the left are the setup menus for each component." : - "WARNING: Your vehicle requires setup prior to flight. Please resolve the items marked in red using the menu on the left." + color: setupComplete ? qgcPal.text : "red" + font.pointSize: setupComplete ? ScreenTools.defaultFontPointSize : ScreenTools.fontPointFactor * (20) + text: setupComplete ? + "Below you will find a summary of the settings for your vehicle. To the left are the setup menus for each component." : + "WARNING: Your vehicle requires setup prior to flight. Please resolve the items marked in red using the menu on the left." + + property bool setupComplete: autopilot && autopilot.setupComplete } Item { @@ -76,7 +78,7 @@ Rectangle { spacing: 10 Repeater { - model: autopilot.vehicleComponents + model: autopilot ? autopilot.vehicleComponents : 0 // Outer summary item rectangle Rectangle { diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index c538a4ce4..ede2bebfc 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -444,8 +444,6 @@ signals: void dropRateChanged(int systemId, float receiveDrop); /** @brief Robot mode has changed */ void modeChanged(int sysId, QString status, QString description); - /** @brief Robot armed state has changed */ - void armingChanged(int sysId, QString armingState); /** @brief A command has been issued **/ void commandSent(int command); /** @brief The robot is connecting **/ -- 2.22.0