From 0e63bc3105b180d041328fc25dde86fa514e869f Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Wed, 29 Apr 2015 12:25:04 -0700 Subject: [PATCH] New Custom Command Widget --- QGCApplication.pro | 4 + qgroundcontrol.qrc | 1 + src/QGCApplication.cc | 4 +- src/ViewWidgets/CustomCommandWidget.cc | 30 +++++ src/ViewWidgets/CustomCommandWidget.h | 40 +++++++ src/ViewWidgets/CustomCommandWidget.qml | 106 ++++++++++++++++++ .../CustomCommandWidgetController.cc | 80 +++++++++++++ .../CustomCommandWidgetController.h | 55 +++++++++ src/ui/MainWindow.cc | 5 + src/ui/MainWindow.h | 1 + 10 files changed, 325 insertions(+), 1 deletion(-) create mode 100644 src/ViewWidgets/CustomCommandWidget.cc create mode 100644 src/ViewWidgets/CustomCommandWidget.h create mode 100644 src/ViewWidgets/CustomCommandWidget.qml create mode 100644 src/ViewWidgets/CustomCommandWidgetController.cc create mode 100644 src/ViewWidgets/CustomCommandWidgetController.h diff --git a/QGCApplication.pro b/QGCApplication.pro index acc9756e1..61a7500d4 100644 --- a/QGCApplication.pro +++ b/QGCApplication.pro @@ -354,6 +354,8 @@ HEADERS += \ src/ui/WaypointList.h \ src/ui/WaypointViewOnlyView.h \ src/ViewWidgets/ParameterEditorWidget.h \ + src/ViewWidgets/CustomCommandWidget.h \ + src/ViewWidgets/CustomCommandWidgetController.h \ src/ViewWidgets/ViewWidgetController.h \ src/Waypoint.h \ @@ -489,6 +491,8 @@ SOURCES += \ src/ui/WaypointList.cc \ src/ui/WaypointViewOnlyView.cc \ src/ViewWidgets/ParameterEditorWidget.cc \ + src/ViewWidgets/CustomCommandWidget.cc \ + src/ViewWidgets/CustomCommandWidgetController.cc \ src/ViewWidgets/ViewWidgetController.cc \ src/Waypoint.cc \ diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index c3b264b8a..3d7bab682 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -34,6 +34,7 @@ src/QmlControls/ParameterEditor.qml src/ViewWidgets/ParameterEditorWidget.qml + src/ViewWidgets/CustomCommandWidget.qml src/VehicleSetup/SetupViewButtonsConnected.qml src/VehicleSetup/SetupViewButtonsDisconnected.qml diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index b9db5f144..8377abc7f 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -63,6 +63,7 @@ #include "QGCLoggingCategory.h" #include "ViewWidgetController.h" #include "ParameterEditorController.h" +#include "CustomCommandWidgetController.h" #ifdef QGC_RTLAB_ENABLED #include "OpalLink.h" @@ -286,9 +287,10 @@ void QGCApplication::_initCommon(void) qmlRegisterType("QGroundControl.Palette", 1, 0, "QGCPalette"); qmlRegisterType("QGroundControl.Controllers", 1, 0, "ViewWidgetController"); qmlRegisterType("QGroundControl.Controllers", 1, 0, "ParameterEditorController"); + qmlRegisterType("QGroundControl.Controllers", 1, 0, "CustomCommandWidgetController"); + //-- Create QML Singleton Interfaces qmlRegisterSingletonType("QGroundControl.ScreenTools", 1, 0, "ScreenTools", screenToolsSingletonFactory); - } bool QGCApplication::_initForNormalAppBoot(void) diff --git a/src/ViewWidgets/CustomCommandWidget.cc b/src/ViewWidgets/CustomCommandWidget.cc new file mode 100644 index 000000000..c7e5ece82 --- /dev/null +++ b/src/ViewWidgets/CustomCommandWidget.cc @@ -0,0 +1,30 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009, 2010 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 . + +======================================================================*/ + +#include "CustomCommandWidget.h" + +CustomCommandWidget::CustomCommandWidget(QWidget *parent) : + QGCQmlWidgetHolder(parent) +{ + setSource(QUrl::fromUserInput("qrc:/qml/CustomCommandWidget.qml")); +} diff --git a/src/ViewWidgets/CustomCommandWidget.h b/src/ViewWidgets/CustomCommandWidget.h new file mode 100644 index 000000000..5471d38d0 --- /dev/null +++ b/src/ViewWidgets/CustomCommandWidget.h @@ -0,0 +1,40 @@ +/*===================================================================== + +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 +/// @author Don Gagne + +#ifndef CustomCommandWidget_H +#define CustomCommandWidget_H + +#include "QGCQmlWidgetHolder.h" + +class CustomCommandWidget : public QGCQmlWidgetHolder +{ + Q_OBJECT + +public: + CustomCommandWidget(QWidget *parent = 0); +}; + +#endif diff --git a/src/ViewWidgets/CustomCommandWidget.qml b/src/ViewWidgets/CustomCommandWidget.qml new file mode 100644 index 000000000..3b93c33bf --- /dev/null +++ b/src/ViewWidgets/CustomCommandWidget.qml @@ -0,0 +1,106 @@ +/*===================================================================== + +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 +/// @author Don Gagne + +import QtQuick 2.2 + +import QGroundControl.Palette 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.Controllers 1.0 + +ViewWidget { + connectedComponent: commandComponenet + + Component { + id: commandComponenet + + Item { + + CustomCommandWidgetController { id: controller } + + Item { + anchors.top: parent.top + anchors.bottom: buttonRow.top + width: parent.width + + QGCLabel { + id: errorOutput + anchors.fill: parent + wrapMode: Text.WordWrap + visible: false + } + + QGCLabel { + id: warning + anchors.fill: parent + wrapMode: Text.WordWrap + visible: !controller.customQmlFile + text: "You can create your own commands and parameter editing user interface in this widget. " + + "You do this by providing your own Qml file. " + + "This support is a work in progress and the details may change somewhat in the future. " + + "By using this feature you are connecting directly to the internals of QGroundControl. " + + "Doing so incorrectly may cause instability both in QGroundControl and/or your vehicle. " + + "So make sure to test your changes thoroughly before using them in flight.\n\n" + + "Click 'Select Qml file' to provide your custom qml file.\n" + + "Click 'Clear Qml file' to reset to none.\n" + + "Example usage: http://www.qgroundcontrol.org/custom_command_qml_widgets" + } + + Loader { + id: loader + anchors.fill: parent + source: controller.customQmlFile + visible: controller.customQmlFile + + onStatusChanged: { + if (loader.status == Loader.Error) { + if (sourceComponent.status == Component.Error) { + errorOutput.text = sourceComponent.errorString() + errorOutput.visible = true + loader.visible = false + } + } + } + } + } + + Row { + id: buttonRow + spacing: 10 + anchors.bottom: parent.bottom + + QGCButton { + text: "Select Qml file..." + onClicked: controller.selectQmlFile() + } + + QGCButton { + text: "Clear Qml file" + onClicked: controller.clearQmlFile() + } + } + } + } +} diff --git a/src/ViewWidgets/CustomCommandWidgetController.cc b/src/ViewWidgets/CustomCommandWidgetController.cc new file mode 100644 index 000000000..e5ca99583 --- /dev/null +++ b/src/ViewWidgets/CustomCommandWidgetController.cc @@ -0,0 +1,80 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 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 . + + ======================================================================*/ + +#include "CustomCommandWidgetController.h" +#include "UASManager.h" +#include "QGCMAVLink.h" +#include "QGCFileDialog.h" + +#include + +const char* CustomCommandWidgetController::_settingsKey = "CustomCommand.QmlFile"; + +CustomCommandWidgetController::CustomCommandWidgetController(void) : + _uas(NULL) +{ + _uas = UASManager::instance()->getActiveUAS(); + Q_ASSERT(_uas); + + QSettings settings; + _customQmlFile = settings.value(_settingsKey).toString(); +} + +void CustomCommandWidgetController::sendCommand(int commandId, QVariant componentId, QVariant confirm, QVariant param1, QVariant param2, QVariant param3, QVariant param4, QVariant param5, QVariant param6, QVariant param7) +{ + Q_UNUSED(commandId); + Q_UNUSED(componentId); + Q_UNUSED(confirm); + Q_UNUSED(param1); + Q_UNUSED(param2); + Q_UNUSED(param3); + Q_UNUSED(param4); + Q_UNUSED(param5); + Q_UNUSED(param6); + Q_UNUSED(param7); + _uas->executeCommand((MAV_CMD)commandId, confirm.toInt(), param1.toFloat(), param2.toFloat(), param3.toFloat(), param4.toFloat(), param5.toFloat(), param6.toFloat(), param7.toFloat(), componentId.toInt()); +} + +void CustomCommandWidgetController::selectQmlFile(void) +{ + QSettings settings; + + QString qmlFile = QGCFileDialog::getOpenFileName(NULL, "Select custom Qml file", QString(), "Qml files (*.qml)"); + if (qmlFile.isEmpty()) { + _customQmlFile.clear(); + settings.remove(_settingsKey); + } else { + _customQmlFile = QString("file:%1").arg(qmlFile); + settings.setValue(_settingsKey, _customQmlFile); + } + + emit customQmlFileChanged(_customQmlFile); +} + +void CustomCommandWidgetController::clearQmlFile(void) +{ + _customQmlFile.clear(); + QSettings settings; + settings.remove(_settingsKey); + emit customQmlFileChanged(_customQmlFile); +} diff --git a/src/ViewWidgets/CustomCommandWidgetController.h b/src/ViewWidgets/CustomCommandWidgetController.h new file mode 100644 index 000000000..be9dcdc91 --- /dev/null +++ b/src/ViewWidgets/CustomCommandWidgetController.h @@ -0,0 +1,55 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 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 . + + ======================================================================*/ + +#ifndef CustomCommandWidgetController_H +#define CustomCommandWidgetController_H + +#include + +#include "UASInterface.h" +#include "AutoPilotPlugin.h" +#include "UASManagerInterface.h" + +class CustomCommandWidgetController : public QObject +{ + Q_OBJECT + +public: + CustomCommandWidgetController(void); + + Q_PROPERTY(QString customQmlFile MEMBER _customQmlFile NOTIFY customQmlFileChanged) + + Q_INVOKABLE void sendCommand(int commandId, QVariant componentId, QVariant confirm, QVariant param1, QVariant param2, QVariant param3, QVariant param4, QVariant param5, QVariant param6, QVariant param7); + Q_INVOKABLE void selectQmlFile(void); + Q_INVOKABLE void clearQmlFile(void); + +signals: + void customQmlFileChanged(const QString& customQmlFile); + +private: + UASInterface* _uas; + QString _customQmlFile; + static const char* _settingsKey; +}; + +#endif \ No newline at end of file diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index eefc27135..d32b1428f 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -70,6 +70,7 @@ This file is part of the QGROUNDCONTROL project #include "QGCFileDialog.h" #include "QGCMessageBox.h" #include "QGCDockWidget.h" +#include "CustomCommandWidget.h" #ifdef UNITTEST_BUILD #include "QmlControls/QmlTestWidget.h" @@ -109,6 +110,7 @@ const char* MainWindow::_uasListDockWidgetName = "UNMANNED_SYSTEM_LIST_DOCKWIDGE const char* MainWindow::_waypointsDockWidgetName = "WAYPOINT_LIST_DOCKWIDGET"; const char* MainWindow::_mavlinkDockWidgetName = "MAVLINK_INSPECTOR_DOCKWIDGET"; const char* MainWindow::_parametersDockWidgetName = "PARAMETER_INTERFACE_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"; @@ -440,6 +442,7 @@ void MainWindow::_buildCommonWidgets(void) { _waypointsDockWidgetName, "Mission Plan", Qt::BottomDockWidgetArea }, { _mavlinkDockWidgetName, "MAVLink Inspector", Qt::RightDockWidgetArea }, { _parametersDockWidgetName, "Parameter Editor", Qt::RightDockWidgetArea }, + { _customCommandWidgetName, "Custom Command", Qt::RightDockWidgetArea }, { _filesDockWidgetName, "Onboard Files", Qt::RightDockWidgetArea }, { _uasStatusDetailsDockWidgetName, "Status Details", Qt::RightDockWidgetArea }, { _mapViewDockWidgetName, "Map view", Qt::RightDockWidgetArea }, @@ -556,6 +559,8 @@ void MainWindow::_createInnerDockWidget(const QString& widgetName) widget = new QGCMAVLinkInspector(MAVLinkProtocol::instance(),this); } else if (widgetName == _parametersDockWidgetName) { widget = new ParameterEditorWidget(this); + } else if (widgetName == _customCommandWidgetName) { + widget = new CustomCommandWidget(this); } else if (widgetName == _filesDockWidgetName) { widget = new QGCUASFileViewMulti(this); } else if (widgetName == _uasStatusDetailsDockWidgetName) { diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index f4f993152..6b771964e 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -328,6 +328,7 @@ private: static const char* _waypointsDockWidgetName; static const char* _mavlinkDockWidgetName; static const char* _parametersDockWidgetName; + static const char* _customCommandWidgetName; static const char* _filesDockWidgetName; static const char* _uasStatusDetailsDockWidgetName; static const char* _mapViewDockWidgetName; -- 2.22.0