diff --git a/QGCApplication.pro b/QGCApplication.pro
index f32186ca295398c22ae02db366304c2c95c6f3f1..06ecd51971046d7f4cb277f224bcb765d2282419 100644
--- a/QGCApplication.pro
+++ b/QGCApplication.pro
@@ -352,6 +352,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 \
@@ -479,6 +481,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 c3b264b8a1866729cefe8cc7d5cbc1631d030235..3d7bab682cbb7c65678411303839e77a18e31b7f 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 90c5e5a2ba39a38e05e4da4fc7e73c86cec770e7..7c6e65fd2d7d4cd09961fbde544e8a187bb1f2b3 100644
--- a/src/QGCApplication.cc
+++ b/src/QGCApplication.cc
@@ -62,6 +62,7 @@
#include "QGCLoggingCategory.h"
#include "ViewWidgetController.h"
#include "ParameterEditorController.h"
+#include "CustomCommandWidgetController.h"
#ifdef QGC_RTLAB_ENABLED
#include "OpalLink.h"
@@ -285,9 +286,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 0000000000000000000000000000000000000000..c7e5ece821d2022c9888f7030772f5fbebd6a0a5
--- /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 0000000000000000000000000000000000000000..5471d38d069dc8cb74a1bed68076d7db8f5f724f
--- /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 0000000000000000000000000000000000000000..5f353f065774bb76a8a0d0240836d39803a54002
--- /dev/null
+++ b/src/ViewWidgets/CustomCommandWidget.qml
@@ -0,0 +1,110 @@
+/*=====================================================================
+
+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: {
+ errorOutput.visible = false
+ controller.clearQmlFile()
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/ViewWidgets/CustomCommandWidgetController.cc b/src/ViewWidgets/CustomCommandWidgetController.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a4282a286dfb2e3593b1ec1135d08194b785794d
--- /dev/null
+++ b/src/ViewWidgets/CustomCommandWidgetController.cc
@@ -0,0 +1,82 @@
+/*=====================================================================
+
+ 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
+#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 {
+ QUrl url = QUrl::fromLocalFile(qmlFile);
+ _customQmlFile = url.toString();
+ 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 0000000000000000000000000000000000000000..be9dcdc91483caa621ca4199fb06e393c4361391
--- /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 d035870866635cf8d09b80793f5cefe14bd122b7..fde97c80208517ec189fae77cf154e31506e0ba0 100644
--- a/src/ui/MainWindow.cc
+++ b/src/ui/MainWindow.cc
@@ -69,6 +69,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"
@@ -108,6 +109,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";
@@ -433,6 +435,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 },
@@ -549,6 +552,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 54c7023f8f587f7c3d0cab8523e9b15c698396be..e3c0f86da460847fda68855d1284a18aa8db81e7 100644
--- a/src/ui/MainWindow.h
+++ b/src/ui/MainWindow.h
@@ -324,6 +324,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;