Commit 207270a5 authored by Don Gagne's avatar Don Gagne

Merge pull request #1455 from DonLakeFlyer/ViewWidgets

Qml based dock widget support
parents 3df5bb48 23aab118
...@@ -147,7 +147,6 @@ INCLUDEPATH += \ ...@@ -147,7 +147,6 @@ INCLUDEPATH += \
src/input \ src/input \
src/lib/qmapcontrol \ src/lib/qmapcontrol \
src/ui/mavlink \ src/ui/mavlink \
src/ui/param \
src/ui/map3D \ src/ui/map3D \
src/ui/mission \ src/ui/mission \
src/ui/designer \ src/ui/designer \
...@@ -159,7 +158,8 @@ INCLUDEPATH += \ ...@@ -159,7 +158,8 @@ INCLUDEPATH += \
src/ui/mapdisplay \ src/ui/mapdisplay \
src/VehicleSetup \ src/VehicleSetup \
src/AutoPilotPlugins \ src/AutoPilotPlugins \
src/QmlControls src/QmlControls \
src/ViewWidgets
FORMS += \ FORMS += \
src/ui/MainWindow.ui \ src/ui/MainWindow.ui \
...@@ -169,13 +169,11 @@ FORMS += \ ...@@ -169,13 +169,11 @@ FORMS += \
src/ui/UASInfo.ui \ src/ui/UASInfo.ui \
src/ui/Linechart.ui \ src/ui/Linechart.ui \
src/ui/UASView.ui \ src/ui/UASView.ui \
src/ui/ParameterInterface.ui \
src/ui/WaypointList.ui \ src/ui/WaypointList.ui \
src/ui/JoystickWidget.ui \ src/ui/JoystickWidget.ui \
src/ui/DebugConsole.ui \ src/ui/DebugConsole.ui \
src/ui/HDDisplay.ui \ src/ui/HDDisplay.ui \
src/ui/MAVLinkSettingsWidget.ui \ src/ui/MAVLinkSettingsWidget.ui \
src/ui/QGCSensorSettingsWidget.ui \
src/ui/QGCDataPlot2D.ui \ src/ui/QGCDataPlot2D.ui \
src/ui/QMap3D.ui \ src/ui/QMap3D.ui \
src/ui/uas/QGCUnconnectedInfoWidget.ui \ src/ui/uas/QGCUnconnectedInfoWidget.ui \
...@@ -263,7 +261,7 @@ HEADERS += \ ...@@ -263,7 +261,7 @@ HEADERS += \
src/comm/MAVLinkSimulationLink.h \ src/comm/MAVLinkSimulationLink.h \
src/comm/UDPLink.h \ src/comm/UDPLink.h \
src/comm/TCPLink.h \ src/comm/TCPLink.h \
src/ui/ParameterInterface.h \ src/ViewWidgets/ParameterEditorWidget.h \
src/ui/WaypointList.h \ src/ui/WaypointList.h \
src/Waypoint.h \ src/Waypoint.h \
src/input/JoystickInput.h \ src/input/JoystickInput.h \
...@@ -273,8 +271,6 @@ HEADERS += \ ...@@ -273,8 +271,6 @@ HEADERS += \
src/ui/MAVLinkSettingsWidget.h \ src/ui/MAVLinkSettingsWidget.h \
src/GAudioOutput.h \ src/GAudioOutput.h \
src/LogCompressor.h \ src/LogCompressor.h \
src/ui/QGCParamWidget.h \
src/ui/QGCSensorSettingsWidget.h \
src/ui/linechart/Linecharts.h \ src/ui/linechart/Linecharts.h \
src/uas/UASWaypointManager.h \ src/uas/UASWaypointManager.h \
src/ui/HSIDisplay.h \ src/ui/HSIDisplay.h \
...@@ -352,8 +348,6 @@ HEADERS += \ ...@@ -352,8 +348,6 @@ HEADERS += \
src/ui/configuration/ApmHighlighter.h \ src/ui/configuration/ApmHighlighter.h \
src/uas/UASParameterDataModel.h \ src/uas/UASParameterDataModel.h \
src/uas/UASParameterCommsMgr.h \ src/uas/UASParameterCommsMgr.h \
src/ui/QGCPendingParamWidget.h \
src/ui/QGCBaseParamWidget.h \
src/ui/px4_configuration/PX4RCCalibration.h \ src/ui/px4_configuration/PX4RCCalibration.h \
src/ui/px4_configuration/RCValueWidget.h \ src/ui/px4_configuration/RCValueWidget.h \
src/uas/UASManagerInterface.h \ src/uas/UASManagerInterface.h \
...@@ -369,7 +363,6 @@ HEADERS += \ ...@@ -369,7 +363,6 @@ HEADERS += \
src/QGCQuickWidget.h \ src/QGCQuickWidget.h \
src/QGCPalette.h \ src/QGCPalette.h \
src/QGCQmlWidgetHolder.h \ src/QGCQmlWidgetHolder.h \
src/ui/QGCParamTreeWidget.h \
src/ui/QGCMapRCToParamDialog.h \ src/ui/QGCMapRCToParamDialog.h \
src/QGCDockWidget.h \ src/QGCDockWidget.h \
src/ui/QGCLinkConfiguration.h \ src/ui/QGCLinkConfiguration.h \
...@@ -379,9 +372,11 @@ HEADERS += \ ...@@ -379,9 +372,11 @@ HEADERS += \
src/uas/UASMessageHandler.h \ src/uas/UASMessageHandler.h \
src/ui/toolbar/MainToolBar.h \ src/ui/toolbar/MainToolBar.h \
src/QmlControls/ScreenTools.h \ src/QmlControls/ScreenTools.h \
src/QmlControls/ParameterEditorController.h \
src/QGCLoggingCategory.h \ src/QGCLoggingCategory.h \
src/ui/flightdisplay/QGCFlightDisplay.h \ src/ui/flightdisplay/QGCFlightDisplay.h \
src/ui/mapdisplay/QGCMapDisplay.h src/ui/mapdisplay/QGCMapDisplay.h \
src/ViewWidgets/ViewWidgetController.h \
SOURCES += \ SOURCES += \
src/main.cc \ src/main.cc \
...@@ -410,7 +405,7 @@ SOURCES += \ ...@@ -410,7 +405,7 @@ SOURCES += \
src/comm/MAVLinkSimulationLink.cc \ src/comm/MAVLinkSimulationLink.cc \
src/comm/UDPLink.cc \ src/comm/UDPLink.cc \
src/comm/TCPLink.cc \ src/comm/TCPLink.cc \
src/ui/ParameterInterface.cc \ src/ViewWidgets/ParameterEditorWidget.cc \
src/ui/WaypointList.cc \ src/ui/WaypointList.cc \
src/Waypoint.cc \ src/Waypoint.cc \
src/input/JoystickInput.cc \ src/input/JoystickInput.cc \
...@@ -420,8 +415,6 @@ SOURCES += \ ...@@ -420,8 +415,6 @@ SOURCES += \
src/ui/MAVLinkSettingsWidget.cc \ src/ui/MAVLinkSettingsWidget.cc \
src/GAudioOutput.cc \ src/GAudioOutput.cc \
src/LogCompressor.cc \ src/LogCompressor.cc \
src/ui/QGCParamWidget.cc \
src/ui/QGCSensorSettingsWidget.cc \
src/ui/linechart/Linecharts.cc \ src/ui/linechart/Linecharts.cc \
src/uas/UASWaypointManager.cc \ src/uas/UASWaypointManager.cc \
src/ui/HSIDisplay.cc \ src/ui/HSIDisplay.cc \
...@@ -496,8 +489,6 @@ SOURCES += \ ...@@ -496,8 +489,6 @@ SOURCES += \
src/ui/configuration/ApmHighlighter.cc \ src/ui/configuration/ApmHighlighter.cc \
src/uas/UASParameterDataModel.cc \ src/uas/UASParameterDataModel.cc \
src/uas/UASParameterCommsMgr.cc \ src/uas/UASParameterCommsMgr.cc \
src/ui/QGCPendingParamWidget.cc \
src/ui/QGCBaseParamWidget.cc \
src/ui/px4_configuration/PX4RCCalibration.cc \ src/ui/px4_configuration/PX4RCCalibration.cc \
src/ui/px4_configuration/RCValueWidget.cc \ src/ui/px4_configuration/RCValueWidget.cc \
src/uas/QGCUASFileManager.cc \ src/uas/QGCUASFileManager.cc \
...@@ -510,7 +501,6 @@ SOURCES += \ ...@@ -510,7 +501,6 @@ SOURCES += \
src/QGCQuickWidget.cc \ src/QGCQuickWidget.cc \
src/QGCPalette.cc \ src/QGCPalette.cc \
src/QGCQmlWidgetHolder.cpp \ src/QGCQmlWidgetHolder.cpp \
src/ui/QGCParamTreeWidget.cpp \
src/ui/QGCMapRCToParamDialog.cpp \ src/ui/QGCMapRCToParamDialog.cpp \
src/QGCDockWidget.cc \ src/QGCDockWidget.cc \
src/ui/QGCLinkConfiguration.cc \ src/ui/QGCLinkConfiguration.cc \
...@@ -520,9 +510,11 @@ SOURCES += \ ...@@ -520,9 +510,11 @@ SOURCES += \
src/uas/UASMessageHandler.cc \ src/uas/UASMessageHandler.cc \
src/ui/toolbar/MainToolBar.cc \ src/ui/toolbar/MainToolBar.cc \
src/QmlControls/ScreenTools.cc \ src/QmlControls/ScreenTools.cc \
src/QmlControls/ParameterEditorController.cc \
src/QGCLoggingCategory.cc \ src/QGCLoggingCategory.cc \
src/ui/flightdisplay/QGCFlightDisplay.cc \ src/ui/flightdisplay/QGCFlightDisplay.cc \
src/ui/mapdisplay/QGCMapDisplay.cc src/ui/mapdisplay/QGCMapDisplay.cc \
src/ViewWidgets/ViewWidgetController.cc \
# #
# Unit Test specific configuration goes here # Unit Test specific configuration goes here
...@@ -605,7 +597,6 @@ HEADERS+= \ ...@@ -605,7 +597,6 @@ HEADERS+= \
src/VehicleSetup/SetupView.h \ src/VehicleSetup/SetupView.h \
src/VehicleSetup/VehicleComponent.h \ src/VehicleSetup/VehicleComponent.h \
src/VehicleSetup/FirmwareUpgradeController.h \ src/VehicleSetup/FirmwareUpgradeController.h \
src/VehicleSetup/ParameterEditorController.h \
src/VehicleSetup/PX4Bootloader.h \ src/VehicleSetup/PX4Bootloader.h \
src/VehicleSetup/PX4FirmwareUpgradeThread.h \ src/VehicleSetup/PX4FirmwareUpgradeThread.h \
src/AutoPilotPlugins/AutoPilotPluginManager.h \ src/AutoPilotPlugins/AutoPilotPluginManager.h \
...@@ -630,7 +621,6 @@ SOURCES += \ ...@@ -630,7 +621,6 @@ SOURCES += \
src/VehicleSetup/SetupView.cc \ src/VehicleSetup/SetupView.cc \
src/VehicleSetup/VehicleComponent.cc \ src/VehicleSetup/VehicleComponent.cc \
src/VehicleSetup/FirmwareUpgradeController.cc \ src/VehicleSetup/FirmwareUpgradeController.cc \
src/VehicleSetup/ParameterEditorController.cc \
src/VehicleSetup/PX4Bootloader.cc \ src/VehicleSetup/PX4Bootloader.cc \
src/VehicleSetup/PX4FirmwareUpgradeThread.cc \ src/VehicleSetup/PX4FirmwareUpgradeThread.cc \
src/AutoPilotPlugins/AutoPilotPluginManager.cc \ src/AutoPilotPlugins/AutoPilotPluginManager.cc \
......
...@@ -29,13 +29,17 @@ ...@@ -29,13 +29,17 @@
<file alias="QGroundControl/Controls/VehicleRotationCal.qml">src/QmlControls/VehicleRotationCal.qml</file> <file alias="QGroundControl/Controls/VehicleRotationCal.qml">src/QmlControls/VehicleRotationCal.qml</file>
<file alias="QGroundControl/Controls/VehicleSummaryRow.qml">src/QmlControls/VehicleSummaryRow.qml</file> <file alias="QGroundControl/Controls/VehicleSummaryRow.qml">src/QmlControls/VehicleSummaryRow.qml</file>
<file alias="QGroundControl/Controls/arrow-down.png">src/QmlControls/arrow-down.png</file> <file alias="QGroundControl/Controls/arrow-down.png">src/QmlControls/arrow-down.png</file>
<file alias="QGroundControl/Controls/ViewWidget.qml">src/ViewWidgets/ViewWidget.qml</file>
<file alias="QGroundControl/Controls/ParameterEditor.qml">src/QmlControls/ParameterEditor.qml</file>
<file alias="ParameterEditorWidget.qml">src/ViewWidgets/ParameterEditorWidget.qml</file>
<file alias="SetupViewButtonsConnected.qml">src/VehicleSetup/SetupViewButtonsConnected.qml</file> <file alias="SetupViewButtonsConnected.qml">src/VehicleSetup/SetupViewButtonsConnected.qml</file>
<file alias="SetupViewButtonsDisconnected.qml">src/VehicleSetup/SetupViewButtonsDisconnected.qml</file> <file alias="SetupViewButtonsDisconnected.qml">src/VehicleSetup/SetupViewButtonsDisconnected.qml</file>
<file alias="VehicleSummary.qml">src/VehicleSetup/VehicleSummary.qml</file> <file alias="VehicleSummary.qml">src/VehicleSetup/VehicleSummary.qml</file>
<file alias="FirmwareUpgrade.qml">src/VehicleSetup/FirmwareUpgrade.qml</file> <file alias="FirmwareUpgrade.qml">src/VehicleSetup/FirmwareUpgrade.qml</file>
<file alias="ParameterEditor.qml">src/VehicleSetup/ParameterEditor.qml</file> <file alias="SetupParameterEditor.qml">src/VehicleSetup/SetupParameterEditor.qml</file>
<file alias="SafetyComponent.qml">src/AutoPilotPlugins/PX4/SafetyComponent.qml</file> <file alias="SafetyComponent.qml">src/AutoPilotPlugins/PX4/SafetyComponent.qml</file>
<file alias="PowerComponent.qml">src/AutoPilotPlugins/PX4/PowerComponent.qml</file> <file alias="PowerComponent.qml">src/AutoPilotPlugins/PX4/PowerComponent.qml</file>
<file alias="SensorsComponent.qml">src/AutoPilotPlugins/PX4/SensorsComponent.qml</file> <file alias="SensorsComponent.qml">src/AutoPilotPlugins/PX4/SensorsComponent.qml</file>
......
...@@ -33,6 +33,14 @@ AutoPilotPlugin::AutoPilotPlugin(UASInterface* uas, QObject* parent) : ...@@ -33,6 +33,14 @@ AutoPilotPlugin::AutoPilotPlugin(UASInterface* uas, QObject* parent) :
_pluginReady(false) _pluginReady(false)
{ {
Q_ASSERT(_uas); Q_ASSERT(_uas);
connect(_uas, &UASInterface::disconnected, this, &AutoPilotPlugin::_uasDisconnected);
}
void AutoPilotPlugin::_uasDisconnected(void)
{
_pluginReady = false;
emit pluginReadyChanged(_pluginReady);
} }
void AutoPilotPlugin::refreshAllParameters(void) void AutoPilotPlugin::refreshAllParameters(void)
......
...@@ -51,8 +51,9 @@ class AutoPilotPlugin : public QObject ...@@ -51,8 +51,9 @@ class AutoPilotPlugin : public QObject
public: public:
AutoPilotPlugin(UASInterface* uas, QObject* parent); AutoPilotPlugin(UASInterface* uas, QObject* parent);
Q_PROPERTY(bool pluginReady READ pluginReady NOTIFY pluginReadyChanged) /// true: plugin is ready for use, plugin should no longer be used
Q_PROPERTY(bool pluginReady READ pluginReady NOTIFY pluginReadyChanged)
/// List of VehicleComponent objects /// List of VehicleComponent objects
Q_PROPERTY(QVariantList vehicleComponents READ vehicleComponents CONSTANT) Q_PROPERTY(QVariantList vehicleComponents READ vehicleComponents CONSTANT)
...@@ -100,17 +101,15 @@ public: ...@@ -100,17 +101,15 @@ public:
// Must be implemented by derived class // Must be implemented by derived class
virtual const QVariantList& vehicleComponents(void) = 0; virtual const QVariantList& vehicleComponents(void) = 0;
/// FIXME: Kind of hacky
static void clearStaticData(void); static void clearStaticData(void);
bool pluginReady(void) { return _pluginReady; }
UASInterface* uas(void) { return _uas; } UASInterface* uas(void) { return _uas; }
bool pluginReady(void) { return _pluginReady; }
signals: signals:
/// Signalled when plugin is ready for use /// Signalled when plugin is ready for use
void pluginReadyChanged(bool pluginReady); void pluginReadyChanged(bool pluginReady);
protected: protected:
/// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin /// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin
AutoPilotPlugin(QObject* parent = NULL) : QObject(parent) { } AutoPilotPlugin(QObject* parent = NULL) : QObject(parent) { }
...@@ -120,6 +119,9 @@ protected: ...@@ -120,6 +119,9 @@ protected:
UASInterface* _uas; UASInterface* _uas;
bool _pluginReady; bool _pluginReady;
private slots:
void _uasDisconnected(void);
}; };
#endif #endif
...@@ -61,6 +61,8 @@ ...@@ -61,6 +61,8 @@
#include "QGCPalette.h" #include "QGCPalette.h"
#include "ScreenTools.h" #include "ScreenTools.h"
#include "QGCLoggingCategory.h" #include "QGCLoggingCategory.h"
#include "ViewWidgetController.h"
#include "ParameterEditorController.h"
#ifdef QGC_RTLAB_ENABLED #ifdef QGC_RTLAB_ENABLED
#include "OpalLink.h" #include "OpalLink.h"
...@@ -262,6 +264,8 @@ void QGCApplication::_initCommon(void) ...@@ -262,6 +264,8 @@ void QGCApplication::_initCommon(void)
// Register our Qml objects // Register our Qml objects
qmlRegisterType<QGCPalette>("QGroundControl.Palette", 1, 0, "QGCPalette"); qmlRegisterType<QGCPalette>("QGroundControl.Palette", 1, 0, "QGCPalette");
qmlRegisterType<ScreenTools>("QGroundControl.ScreenTools", 1, 0, "ScreenTools"); qmlRegisterType<ScreenTools>("QGroundControl.ScreenTools", 1, 0, "ScreenTools");
qmlRegisterType<ViewWidgetController>("QGroundControl.Controllers", 1, 0, "ViewWidgetController");
qmlRegisterType<ParameterEditorController>("QGroundControl.Controllers", 1, 0, "ParameterEditorController");
} }
bool QGCApplication::_initForNormalAppBoot(void) bool QGCApplication::_initForNormalAppBoot(void)
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
// If you need to make an incompatible changes to stored settings, bump this version number // If you need to make an incompatible changes to stored settings, bump this version number
// up by 1. This will caused store settings to be cleared on next boot. // up by 1. This will caused store settings to be cleared on next boot.
#define QGC_SETTINGS_VERSION 4 #define QGC_SETTINGS_VERSION 5
#define QGC_APPLICATION_NAME "QGroundControl" #define QGC_APPLICATION_NAME "QGroundControl"
#define QGC_ORG_NAME "QGroundControl.org" #define QGC_ORG_NAME "QGroundControl.org"
......
...@@ -25,15 +25,23 @@ ...@@ -25,15 +25,23 @@
#include <QCloseEvent> #include <QCloseEvent>
QGCDockWidget::QGCDockWidget(const QString& title, QWidget *parent, Qt::WindowFlags flags) : QGCDockWidget::QGCDockWidget(const QString& title, QAction* action, QWidget *parent, Qt::WindowFlags flags) :
QDockWidget(title, parent, flags) QDockWidget(title, parent, flags),
_action(action)
{ {
QDockWidget::DockWidgetFeatures features = QDockWidget::DockWidgetMovable;
if (action) {
features |= QDockWidget::DockWidgetClosable;
}
setFeatures(features);
} }
// Instead of destroying the widget just hide it // Instead of destroying the widget just hide it
void QGCDockWidget::closeEvent(QCloseEvent* event) void QGCDockWidget::closeEvent(QCloseEvent* event)
{ {
Q_ASSERT(_action);
event->ignore(); event->ignore();
setVisible(false); _action->trigger();
} }
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define QGCDockWidget_h #define QGCDockWidget_h
#include <QDockWidget> #include <QDockWidget>
#include <QAction>
/// @file /// @file
/// @brief Subclass of QDockWidget so we can intercept the closeEvent. /// @brief Subclass of QDockWidget so we can intercept the closeEvent.
...@@ -35,9 +36,12 @@ class QGCDockWidget : public QDockWidget { ...@@ -35,9 +36,12 @@ class QGCDockWidget : public QDockWidget {
Q_OBJECT Q_OBJECT
public: public:
QGCDockWidget(const QString& title, QWidget *parent = 0, Qt::WindowFlags flags = 0); QGCDockWidget(const QString& title, QAction* action, QWidget *parent = 0, Qt::WindowFlags flags = 0);
void closeEvent(QCloseEvent* event); void closeEvent(QCloseEvent* event);
private:
QAction* _action;
}; };
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
======================================================================*/ ======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
import QtQuick 2.3 import QtQuick 2.3
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2 import QtQuick.Controls.Styles 1.2
...@@ -33,61 +36,51 @@ import QGroundControl.FactSystem 1.0 ...@@ -33,61 +36,51 @@ import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0 import QGroundControl.FactControls 1.0
Rectangle { Rectangle {
QGCPalette { id: qgcPal; colorGroupEnabled: true } /// true: show full information, false: for use in smaller widgets
ScreenTools { id: screenTools } property bool fullMode: true
ParameterEditorController { id: controller }
QGCLabel { id: charWidth; text: "X"; visible: false } QGCPalette { id: __qgcPal; colorGroupEnabled: true }
ScreenTools { id: __screenTools }
ParameterEditorController { id: __controller }
QGCLabel { id: __charWidth; text: "X"; visible: false }
readonly property real leftMargin: 10 readonly property real __leftMargin: 10
readonly property real rightMargin: 20 readonly property real __rightMargin: 20
readonly property int maxParamChars: 16 readonly property int __maxParamChars: 16
color: qgcPal.window color: __qgcPal.window
// We use an ExclusiveGroup to maintain the visibility of a single editing control at a time // We use an ExclusiveGroup to maintain the visibility of a single editing control at a time
ExclusiveGroup { ExclusiveGroup {
id: exclusiveEditorGroup id: __exclusiveEditorGroup
} }
Column { Column {
anchors.fill:parent anchors.fill:parent
QGCLabel {
text: "PARAMETER EDITOR"
font.pointSize: screenTools.dpiAdjustedPointSize(20)
}
Item {
height: 20
width: 5
}
Row { Row {
spacing: 10 spacing: 10
layoutDirection: Qt.RightToLeft layoutDirection: Qt.RightToLeft
width: parent.width width: parent.width
QGCButton { QGCButton {
text: "Clear RC to Param" text: "Clear RC to Param"
onClicked: controller.clearRCToParam() onClicked: __controller.clearRCToParam()
} }
QGCButton { QGCButton {
text: "Save to file" text: "Save to file"
onClicked: controller.saveToFile() visible: fullMode
onClicked: __controller.saveToFile()
} }
QGCButton { QGCButton {
text: "Load from file" text: "Load from file"
onClicked: controller.loadFromFile() visible: fullMode
onClicked: __controller.loadFromFile()
} }
QGCButton { QGCButton {
id: firstButton id: firstButton
text: "Refresh" text: "Refresh"
onClicked: controller.refresh() onClicked: __controller.refresh()
}
QGCLabel {
width: firstButton.x - parent.spacing
wrapMode: Text.WordWrap
text: "Click a parameter value to modify. Right-click to set an RC to Param mapping. Use caution when modifying parameters here since the values are not checked for validity."
} }
} }
...@@ -104,7 +97,7 @@ Rectangle { ...@@ -104,7 +97,7 @@ Rectangle {
Column { Column {
Repeater { Repeater {
model: controller.componentIds model: __controller.componentIds
Column { Column {
id: componentColumn id: componentColumn
...@@ -113,7 +106,7 @@ Rectangle { ...@@ -113,7 +106,7 @@ Rectangle {
QGCLabel { QGCLabel {
text: "Component #: " + componentId.toString() text: "Component #: " + componentId.toString()
font.pointSize: screenTools.dpiAdjustedPointSize(qgcPal.defaultFontPointSize + 4); font.pointSize: __screenTools.dpiAdjustedPointSize(__qgcPal.defaultFontPointSize + 4);
} }
Item { Item {
...@@ -122,51 +115,51 @@ Rectangle { ...@@ -122,51 +115,51 @@ Rectangle {
} }
Repeater { Repeater {
model: controller.getGroupsForComponent(componentColumn.componentId) model: __controller.getGroupsForComponent(componentColumn.componentId)
Column { Column {
Rectangle { Rectangle {
id: groupRect id: groupRect
color: qgcPal.windowShade color: __qgcPal.windowShade
height: groupBlock.height height: groupBlock.height
width: scrollView.viewport.width - rightMargin width: scrollView.viewport.width - __rightMargin
Column { Column {
id: groupBlock id: groupBlock
Rectangle { Rectangle {
color: qgcPal.windowShadeDark color: __qgcPal.windowShadeDark
height: groupLabel.height height: groupLabel.height
width: groupRect.width width: groupRect.width
QGCLabel { QGCLabel {
id: groupLabel id: groupLabel
height: contentHeight + 5 height: contentHeight + 5
x: leftMargin x: __leftMargin
text: modelData text: modelData
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
font.pointSize: screenTools.dpiAdjustedPointSize(qgcPal.defaultFontPointSize + 2); font.pointSize: __screenTools.dpiAdjustedPointSize(__qgcPal.defaultFontPointSize + 2);
} }
} }
Repeater { Repeater {
model: controller.getFactsForGroup(componentColumn.componentId, modelData) model: __controller.getFactsForGroup(componentColumn.componentId, modelData)
Row { Row {
spacing: 10 spacing: 10
x: leftMargin x: __leftMargin
Fact { id: modelFact; name: modelData + ":" + componentColumn.componentId } Fact { id: modelFact; name: modelData + ":" + componentColumn.componentId }
QGCLabel { QGCLabel {
text: modelFact.name text: modelFact.name
width: charWidth.contentWidth * (maxParamChars + 2) width: __charWidth.contentWidth * (__maxParamChars + 2)
} }
QGCLabel { QGCLabel {
text: modelFact.valueString + " " + modelFact.units text: modelFact.valueString + " " + modelFact.units
width: charWidth.contentWidth * 20 width: __charWidth.contentWidth * 20
height: contentHeight height: contentHeight
MouseArea { MouseArea {
...@@ -178,7 +171,7 @@ Rectangle { ...@@ -178,7 +171,7 @@ Rectangle {
editor.checked = true editor.checked = true
editor.focus = true editor.focus = true
} else if (mouse.button == Qt.RightButton) { } else if (mouse.button == Qt.RightButton) {
controller.setRCToParam(modelData) __controller.setRCToParam(modelData)
} }
} }
} }
...@@ -195,7 +188,7 @@ Rectangle { ...@@ -195,7 +188,7 @@ Rectangle {
// We use an ExclusiveGroup to manage visibility // We use an ExclusiveGroup to manage visibility
property bool checked: false property bool checked: false
property ExclusiveGroup exclusiveGroup: exclusiveEditorGroup property ExclusiveGroup exclusiveGroup: __exclusiveEditorGroup
onExclusiveGroupChanged: { onExclusiveGroupChanged: {
if (exclusiveGroup) if (exclusiveGroup)
exclusiveGroup.bindCheckable(editor) exclusiveGroup.bindCheckable(editor)
...@@ -205,6 +198,7 @@ Rectangle { ...@@ -205,6 +198,7 @@ Rectangle {
QGCLabel { QGCLabel {
text: modelFact.shortDescription text: modelFact.shortDescription
visible: fullMode
} }
} // Row - Fact value } // Row - Fact value
} // Repeater - Facts } // Repeater - Facts
......
...@@ -13,4 +13,6 @@ SubMenuButton 1.0 SubMenuButton.qml ...@@ -13,4 +13,6 @@ SubMenuButton 1.0 SubMenuButton.qml
IndicatorButton 1.0 IndicatorButton.qml IndicatorButton 1.0 IndicatorButton.qml
VehicleRotationCal 1.0 VehicleRotationCal.qml VehicleRotationCal 1.0 VehicleRotationCal.qml
VehicleSummaryRow 1.0 VehicleSummaryRow.qml VehicleSummaryRow 1.0 VehicleSummaryRow.qml
ParameterEditor 1.0 ParameterEditor.qml
ViewWidget 1.0 ViewWidget.qml
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
import QtQuick 2.3
import QtQuick.Controls 1.2
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
Rectangle {
QGCPalette { id: qgcPal; colorGroupEnabled: true }
ScreenTools { id: screenTools }
color: qgcPal.window
// We use an ExclusiveGroup to maintain the visibility of a single editing control at a time
ExclusiveGroup {
id: exclusiveEditorGroup
}
Column {
anchors.fill:parent
QGCLabel {
text: "PARAMETER EDITOR"
font.pointSize: screenTools.dpiAdjustedPointSize(20)
}
Item {
height: 20
width: 5
}
QGCLabel {
id: infoLabel
width: parent.width
wrapMode: Text.WordWrap
text: "Click a parameter value to modify. Right-click to set an RC to Param mapping. Use caution when modifying parameters here since the values are not checked for validity."
}
ParameterEditor {
width: parent.width
height: parent.height - (infoLabel.y + infoLabel.height)
}
}
}
...@@ -55,7 +55,6 @@ SetupView::SetupView(QWidget* parent) : ...@@ -55,7 +55,6 @@ SetupView::SetupView(QWidget* parent) :
Q_ASSERT(fSucceeded); Q_ASSERT(fSucceeded);
qmlRegisterType<FirmwareUpgradeController>("QGroundControl.Controllers", 1, 0, "FirmwareUpgradeController"); qmlRegisterType<FirmwareUpgradeController>("QGroundControl.Controllers", 1, 0, "FirmwareUpgradeController");
qmlRegisterType<ParameterEditorController>("QGroundControl.Controllers", 1, 0, "ParameterEditorController");
_ui->buttonHolder->rootContext()->setContextProperty("controller", this); _ui->buttonHolder->rootContext()->setContextProperty("controller", this);
_ui->buttonHolder->setAutoPilot(NULL); _ui->buttonHolder->setAutoPilot(NULL);
...@@ -137,7 +136,7 @@ void SetupView::parametersButtonClicked(void) ...@@ -137,7 +136,7 @@ void SetupView::parametersButtonClicked(void)
Q_ASSERT(_autoPilotPlugin); Q_ASSERT(_autoPilotPlugin);
setup->setAutoPilot(_autoPilotPlugin); setup->setAutoPilot(_autoPilotPlugin);
setup->setSource(QUrl::fromUserInput("qrc:/qml/ParameterEditor.qml")); setup->setSource(QUrl::fromUserInput("qrc:/qml/SetupParameterEditor.qml"));
_changeSetupWidget(setup); _changeSetupWidget(setup);
} }
......
...@@ -23,49 +23,15 @@ This file is part of the QGROUNDCONTROL project ...@@ -23,49 +23,15 @@ This file is part of the QGROUNDCONTROL project
/** /**
* @file * @file
* @brief Definition of class ParameterInterface * @brief Definition of class ParameterEditorWidget
*
* @author Lorenz Meier <mavteam@student.ethz.ch> * @author Lorenz Meier <mavteam@student.ethz.ch>
* *
*/ */
#ifndef PARAMETERINTERFACE_H #include "ParameterEditorWidget.h"
#define PARAMETERINTERFACE_H
#include <QWidget>
#include "ui_ParameterInterface.h"
#include "UASInterface.h"
#include "QGCParamWidget.h"
namespace Ui ParameterEditorWidget::ParameterEditorWidget(QWidget *parent) :
QGCQmlWidgetHolder(parent)
{ {
class ParameterInterface; setSource(QUrl::fromUserInput("qrc:/qml/ParameterEditorWidget.qml"));
} }
/**
* @brief Container class for onboard parameter widgets
*
* @see QGCParamWidget
*/
class ParameterInterface : public QWidget
{
Q_OBJECT
public:
explicit ParameterInterface(QWidget *parent = 0);
virtual ~ParameterInterface();
public slots:
void addUAS(UASInterface* uas);
void selectUAS(int index);
protected:
virtual void changeEvent(QEvent *e);
QMap<int, QGCParamWidget*>* paramWidgets;
int curr;
private:
Ui::parameterWidget *m_ui;
};
#endif // PARAMETERINTERFACE_H
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
QGroundControl Open Source Ground Control Station QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> (c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project This file is part of the QGROUNDCONTROL project
...@@ -21,65 +21,20 @@ This file is part of the QGROUNDCONTROL project ...@@ -21,65 +21,20 @@ This file is part of the QGROUNDCONTROL project
======================================================================*/ ======================================================================*/
/** /// @file
* @file /// @author Don Gagne <don@thegagnes.com>
* @brief Declaration of class QGCSensorSettingsWidget
* @author Lorenz Meier <mail@qgroundcontrol.org>
*/
#ifndef QGCSENSORSETTINGSWIDGET_H #ifndef PARAMETEREDITORWIDGET_H
#define QGCSENSORSETTINGSWIDGET_H #define PARAMETEREDITORWIDGET_H
#include <QWidget> #include "QGCQmlWidgetHolder.h"
#include "UASInterface.h" class ParameterEditorWidget : public QGCQmlWidgetHolder
namespace Ui
{
class QGCSensorSettingsWidget;
}
class QGCSensorSettingsWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
QGCSensorSettingsWidget(UASInterface* uas, QWidget *parent = 0); ParameterEditorWidget(QWidget *parent = 0);
~QGCSensorSettingsWidget();
public slots:
void delayedSendRawSensor(int rate);
void delayedSendController(int rate);
void delayedSendExtended(int rate);
void delayedSendRC(int rate);
void delayedSendPosition(int rate);
void delayedSendExtra1(int rate);
void delayedSendExtra2(int rate);
void delayedSendExtra3(int rate);
protected:
UASInterface* mav;
QTimer delayedSendRawSensorTimer;
QTimer delayedSendControllerTimer;
QTimer delayedSendExtendedTimer;
QTimer delayedSendRCTimer;
QTimer delayedSendPositionTimer;
QTimer delayedSendExtra1Timer;
QTimer delayedSendExtra2Timer;
QTimer delayedSendExtra3Timer;
void changeEvent(QEvent *e);
protected slots:
void sendRawSensor();
void sendController();
void sendExtended();
void sendRC();
void sendPosition();
void sendExtra1();
void sendExtra2();
void sendExtra3();
private:
Ui::QGCSensorSettingsWidget *ui;
}; };
#endif // QGCSENSORSETTINGSWIDGET_H #endif
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
import QtQuick 2.2
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
ViewWidget {
connectedComponent: editorComponent
Component {
id: editorComponent
ParameterEditor {
fullMode: false
}
}
}
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QGroundControl.Palette 1.0
import QGroundControl.Controllers 1.0
Rectangle {
property Component connectedComponent: __componentConnected
property Component disconnectedComponent: __componentDisconnected
QGCPalette { id: __qgcPal; colorGroupEnabled: enabled }
ViewWidgetController { id: __controller }
color: __qgcPal.window
Component.onCompleted: __controller.checkForVehicle()
Connections {
target: __controller
onPluginConnected: {
pageLoader.autopilot = autopilot
pageLoader.sourceComponent = connectedComponent
}
onPluginDisconnected: {
pageLoader.sourceComponent = disconnectedComponent
pageLoader.autopilot = {}
}
}
Loader {
id: pageLoader
anchors.fill: parent
property var autopilot
sourceComponent: __componentDisconnected
}
Component {
id: __componentConnected
Rectangle {
QGCPalette { id: __qgcPal; colorGroupEnabled: enabled }
anchors.fill: parent
color: __qgcPal.window
QGCLabel {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: "missing connected implementation"
}
}
}
Component {
id: __componentDisconnected
Rectangle {
QGCPalette { id: __qgcPal; colorGroupEnabled: enabled }
anchors.fill: parent
color: __qgcPal.window
QGCLabel {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: "no vehicle connected"
}
}
}
}
/*===================================================================== /*=====================================================================
QGroundControl Open Source Ground Control Station QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful, QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>. along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/ ======================================================================*/
/// @file #include "ViewWidgetController.h"
/// @author Thomas Gubler <thomasgubler@gmail.com> #include "UASManager.h"
#include "AutoPilotPluginManager.h"
#include "QGCParamTreeWidget.h" ViewWidgetController::ViewWidgetController(void) :
#include <QMenu> _autopilot(NULL),
#include <QTreeWidgetItem> _uas(NULL)
#include <QDebug>
QGCParamTreeWidget::QGCParamTreeWidget(QWidget *parent) :
QTreeWidget(parent)
{ {
setContextMenuPolicy(Qt::CustomContextMenu); _uasManager = UASManager::instance();
Q_ASSERT(_uasManager);
QObject::connect(this, &QGCParamTreeWidget::customContextMenuRequested,
this, &QGCParamTreeWidget::showContextMenu); connect(_uasManager, &UASManagerInterface::activeUASSet, this, &ViewWidgetController::_activeUasChanged);
qDebug() << "create QGCParamTreeWidget";
} }
QGCParamTreeWidget::~QGCParamTreeWidget() void ViewWidgetController::_activeUasChanged(UASInterface* currentUas)
{ {
if (currentUas != _uas) {
if (_uas) {
disconnect(_autopilot, &AutoPilotPlugin::pluginReadyChanged, this, &ViewWidgetController::_pluginReadyChanged);
_uas = NULL;
_autopilot = NULL;
emit pluginDisconnected();
}
if (currentUas) {
_uas = currentUas;
_autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(currentUas);
Q_ASSERT(_autopilot);
connect(_autopilot, &AutoPilotPlugin::pluginReadyChanged, this, &ViewWidgetController::_pluginReadyChanged);
if (_autopilot->pluginReady()) {
_pluginReadyChanged(true);
}
}
}
} }
void QGCParamTreeWidget::showContextMenu(const QPoint &pos) void ViewWidgetController::_pluginReadyChanged(bool pluginReady)
{ {
QMenu menu; Q_ASSERT(_autopilot);
QTreeWidgetItem* item = itemAt(pos);
if (pluginReady) {
// Only show context menu for parameter items and not for group items emit pluginConnected(QVariant::fromValue(_autopilot));
// (show for TEST_P but not for TEST) } else {
// If a context menu is needed later for the groups then move this 'if' _activeUasChanged(NULL);
// to below where the actions are created and filter out certain actions }
// for the outer nodes
if (indexOfTopLevelItem(item) > -1 ||
indexOfTopLevelItem(item->parent()) > -1) {
return;
}
QString param_id = item->data(0, Qt::DisplayRole).toString();
// Refresh single parameter
QAction* act = new QAction(tr("Refresh this param"), this);
act->setProperty("action", "refresh");
act->setProperty("param_id", param_id);
connect(act, &QAction::triggered, this,
&QGCParamTreeWidget::contextMenuAction);
menu.addAction(act);
// RC to parameter mapping
act = new QAction(tr("Map Parameter to RC"), this);
act->setProperty("action", "maprc");
act->setProperty("param_id", param_id);
connect(act, &QAction::triggered, this,
&QGCParamTreeWidget::contextMenuAction);
menu.addAction(act);
menu.exec(mapToGlobal(pos));
} }
void QGCParamTreeWidget::contextMenuAction() { Q_INVOKABLE void ViewWidgetController::checkForVehicle(void)
QString action = qobject_cast<QAction*>( {
sender())->property("action").toString(); _activeUasChanged(_uasManager->getActiveUAS());
QString param_id = qobject_cast<QAction*>(
sender())->property("param_id").toString();
if (action == "refresh") {
emit refreshParamRequest(param_id);
} else if (action == "maprc") {
emit mapRCToParamRequest(param_id);
} else {
qDebug() << "Undefined context menu action";
}
} }
/*===================================================================== /*=====================================================================
QGroundControl Open Source Ground Control Station QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful, QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>. along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/ ======================================================================*/
/// @file #ifndef VIEWWIDGETCONTROLLER_H
/// @brief A treeview with context menus for parameters #define VIEWWIDGETCONTROLLER_H
/// @author Thomas Gubler <thomasgubler@gmail.com>
#ifndef QGCPARAMTREEWIDGET_H #include <QObject>
#define QGCPARAMTREEWIDGET_H
#include <QTreeWidget> #include "UASInterface.h"
#include "AutoPilotPlugin.h"
#include "UASManagerInterface.h"
/// Implements individual context menus for the QTreeWidgetItems class ViewWidgetController : public QObject
class QGCParamTreeWidget : public QTreeWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
QGCParamTreeWidget(QWidget *parent = 0); ViewWidgetController(void);
~QGCParamTreeWidget();
Q_INVOKABLE void checkForVehicle(void);
signals: signals:
void mapRCToParamRequest(QString param_id); void pluginConnected(QVariant autopilot);
void refreshParamRequest(QString param_id); void pluginDisconnected(void);
public slots: private slots:
void showContextMenu(const QPoint &pos); void _activeUasChanged(UASInterface* UAS);
void contextMenuAction(); void _pluginReadyChanged(bool pluginReady);
private:
AutoPilotPlugin* _autopilot;
UASManagerInterface* _uasManager;
UASInterface* _uas;
}; };
#endif // QGCPARAMTREEWIDGET_H #endif
\ No newline at end of file
...@@ -338,12 +338,7 @@ void MainWindow::resizeEvent(QResizeEvent * event) ...@@ -338,12 +338,7 @@ void MainWindow::resizeEvent(QResizeEvent * event)
QString MainWindow::_getWindowStateKey() QString MainWindow::_getWindowStateKey()
{ {
if (UASManager::instance()->getActiveUAS()) return QString::number(_currentView)+"_windowstate_";
{
return QString::number(_currentView)+"_windowstate_" + UASManager::instance()->getActiveUAS()->getAutopilotTypeName();
}
else
return QString::number(_currentView)+"_windowstate_";
} }
QString MainWindow::_getWindowGeometryKey() QString MainWindow::_getWindowGeometryKey()
...@@ -372,22 +367,26 @@ void MainWindow::_buildCustomWidgets(void) ...@@ -372,22 +367,26 @@ void MainWindow::_buildCustomWidgets(void)
void MainWindow::_createDockWidget(const QString& title, const QString& name, Qt::DockWidgetArea area, QWidget* innerWidget) void MainWindow::_createDockWidget(const QString& title, const QString& name, Qt::DockWidgetArea area, QWidget* innerWidget)
{ {
Q_ASSERT(!_mapName2DockWidget.contains(name)); Q_ASSERT(!_mapName2DockWidget.contains(name));
QGCDockWidget* dockWidget = new QGCDockWidget(title, this);
Q_CHECK_PTR(dockWidget);
dockWidget->setObjectName(name);
dockWidget->setVisible (false);
if (innerWidget) {
// Put inner widget inside QDockWidget
innerWidget->setParent(dockWidget);
dockWidget->setWidget(innerWidget);
innerWidget->setVisible(true);
}
// Add to menu // Add to menu
QAction* action = new QAction(title, NULL); QAction* action = new QAction(title, NULL);
action->setCheckable(true); action->setCheckable(true);
action->setData(name); action->setData(name);
connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction); connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction);
_ui.menuTools->addAction(action); _ui.menuTools->addAction(action);
// Create widget
QGCDockWidget* dockWidget = new QGCDockWidget(title, action, this);
Q_CHECK_PTR(dockWidget);
dockWidget->setObjectName(name);
dockWidget->setVisible (false);
if (innerWidget) {
// Put inner widget inside QDockWidget
innerWidget->setParent(dockWidget);
dockWidget->setWidget(innerWidget);
innerWidget->setVisible(true);
}
_mapName2DockWidget[name] = dockWidget; _mapName2DockWidget[name] = dockWidget;
_mapDockWidget2Action[dockWidget] = action; _mapDockWidget2Action[dockWidget] = action;
addDockWidget(area, dockWidget); addDockWidget(area, dockWidget);
...@@ -421,7 +420,7 @@ void MainWindow::_buildCommonWidgets(void) ...@@ -421,7 +420,7 @@ void MainWindow::_buildCommonWidgets(void)
{ _uasListDockWidgetName, "Unmanned Systems", Qt::RightDockWidgetArea }, { _uasListDockWidgetName, "Unmanned Systems", Qt::RightDockWidgetArea },
{ _waypointsDockWidgetName, "Mission Plan", Qt::BottomDockWidgetArea }, { _waypointsDockWidgetName, "Mission Plan", Qt::BottomDockWidgetArea },
{ _mavlinkDockWidgetName, "MAVLink Inspector", Qt::RightDockWidgetArea }, { _mavlinkDockWidgetName, "MAVLink Inspector", Qt::RightDockWidgetArea },
{ _parametersDockWidgetName, "Onboard Parameters", Qt::RightDockWidgetArea }, { _parametersDockWidgetName, "Parameter Editor", Qt::RightDockWidgetArea },
{ _filesDockWidgetName, "Onboard Files", Qt::RightDockWidgetArea }, { _filesDockWidgetName, "Onboard Files", Qt::RightDockWidgetArea },
{ _uasStatusDetailsDockWidgetName, "Status Details", Qt::RightDockWidgetArea }, { _uasStatusDetailsDockWidgetName, "Status Details", Qt::RightDockWidgetArea },
{ _mapViewDockWidgetName, "Map view", Qt::RightDockWidgetArea }, { _mapViewDockWidgetName, "Map view", Qt::RightDockWidgetArea },
...@@ -431,7 +430,7 @@ void MainWindow::_buildCommonWidgets(void) ...@@ -431,7 +430,7 @@ void MainWindow::_buildCommonWidgets(void)
{ _pfdDockWidgetName, "Primary Flight Display", Qt::RightDockWidgetArea }, { _pfdDockWidgetName, "Primary Flight Display", Qt::RightDockWidgetArea },
{ _hudDockWidgetName, "Video Downlink", Qt::RightDockWidgetArea }, { _hudDockWidgetName, "Video Downlink", Qt::RightDockWidgetArea },
{ _uasInfoViewDockWidgetName, "Info View", Qt::LeftDockWidgetArea }, { _uasInfoViewDockWidgetName, "Info View", Qt::LeftDockWidgetArea },
{ _debugConsoleDockWidgetName, "Communications Console", Qt::LeftDockWidgetArea } { _debugConsoleDockWidgetName, "Communications Console", Qt::LeftDockWidgetArea },
}; };
static const size_t cDockWidgetInfo = sizeof(rgDockWidgetInfo) / sizeof(rgDockWidgetInfo[0]); static const size_t cDockWidgetInfo = sizeof(rgDockWidgetInfo) / sizeof(rgDockWidgetInfo[0]);
...@@ -550,7 +549,7 @@ void MainWindow::_createInnerDockWidget(const QString& widgetName) ...@@ -550,7 +549,7 @@ void MainWindow::_createInnerDockWidget(const QString& widgetName)
} else if (widgetName == _mavlinkDockWidgetName) { } else if (widgetName == _mavlinkDockWidgetName) {
widget = new QGCMAVLinkInspector(MAVLinkProtocol::instance(),this); widget = new QGCMAVLinkInspector(MAVLinkProtocol::instance(),this);
} else if (widgetName == _parametersDockWidgetName) { } else if (widgetName == _parametersDockWidgetName) {
widget = new ParameterInterface(this); widget = new ParameterEditorWidget(this);
} else if (widgetName == _filesDockWidgetName) { } else if (widgetName == _filesDockWidgetName) {
widget = new QGCUASFileViewMulti(this); widget = new QGCUASFileViewMulti(this);
} else if (widgetName == _uasStatusDetailsDockWidgetName) { } else if (widgetName == _uasStatusDetailsDockWidgetName) {
...@@ -614,7 +613,7 @@ void MainWindow::_showHILConfigurationWidgets(void) ...@@ -614,7 +613,7 @@ void MainWindow::_showHILConfigurationWidgets(void)
if (!_mapUasId2HilDockWidget.contains(uasId)) { if (!_mapUasId2HilDockWidget.contains(uasId)) {
// Create QDockWidget // Create QDockWidget
QGCDockWidget* dockWidget = new QGCDockWidget(tr("HIL Config %1").arg(uasId), this); QGCDockWidget* dockWidget = new QGCDockWidget(tr("HIL Config %1").arg(uasId), NULL, this);
Q_CHECK_PTR(dockWidget); Q_CHECK_PTR(dockWidget);
dockWidget->setObjectName(tr("HIL_CONFIG_%1").arg(uasId)); dockWidget->setObjectName(tr("HIL_CONFIG_%1").arg(uasId));
dockWidget->setVisible (false); dockWidget->setVisible (false);
...@@ -765,12 +764,11 @@ void MainWindow::storeSettings() ...@@ -765,12 +764,11 @@ void MainWindow::storeSettings()
settings.setValue("SHOW_STATUSBAR", _showStatusBar); settings.setValue("SHOW_STATUSBAR", _showStatusBar);
settings.endGroup(); settings.endGroup();
settings.setValue(_getWindowGeometryKey(), saveGeometry()); settings.setValue(_getWindowGeometryKey(), saveGeometry());
// Save the last current view in any case // Save the last current view in any case
settings.setValue("CURRENT_VIEW", _currentView); settings.setValue("CURRENT_VIEW", _currentView);
// Save the current window state, but only if a system is connected (else no real number of widgets would be present)) settings.setValue(_getWindowStateKey(), saveState());
if (UASManager::instance()->getUASList().length() > 0) settings.setValue(_getWindowStateKey(), saveState());
// Save the current UAS view if a UAS is connected
if (UASManager::instance()->getUASList().length() > 0) settings.setValue("CURRENT_VIEW_WITH_UAS_CONNECTED", _currentView);
// And save any custom weidgets // And save any custom weidgets
QGCToolWidget::storeWidgetsToSettings(settings); QGCToolWidget::storeWidgetsToSettings(settings);
} }
...@@ -877,7 +875,6 @@ void MainWindow::connectCommonActions() ...@@ -877,7 +875,6 @@ void MainWindow::connectCommonActions()
// Connect internal actions // Connect internal actions
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(UASCreated(UASInterface*))); connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(UASCreated(UASInterface*)));
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
// Unmanned System controls // Unmanned System controls
connect(_ui.actionLiftoff, SIGNAL(triggered()), UASManager::instance(), SLOT(launchActiveUAS())); connect(_ui.actionLiftoff, SIGNAL(triggered()), UASManager::instance(), SLOT(launchActiveUAS()));
...@@ -978,21 +975,6 @@ void MainWindow::commsWidgetDestroyed(QObject *obj) ...@@ -978,21 +975,6 @@ void MainWindow::commsWidgetDestroyed(QObject *obj)
} }
} }
void MainWindow::setActiveUAS(UASInterface* uas)
{
Q_UNUSED(uas);
if (settings.contains(_getWindowStateKey()))
{
restoreState(settings.value(_getWindowStateKey()).toByteArray());
}
}
void MainWindow::UASSpecsChanged(int uas)
{
Q_UNUSED(uas);
// TODO: Update UAS properties if its specs change
}
void MainWindow::UASCreated(UASInterface* uas) void MainWindow::UASCreated(UASInterface* uas)
{ {
// The UAS actions are not enabled without connection to system // The UAS actions are not enabled without connection to system
...@@ -1002,7 +984,6 @@ void MainWindow::UASCreated(UASInterface* uas) ...@@ -1002,7 +984,6 @@ void MainWindow::UASCreated(UASInterface* uas)
_ui.actionEmergency_Land->setEnabled(true); _ui.actionEmergency_Land->setEnabled(true);
_ui.actionShutdownMAV->setEnabled(true); _ui.actionShutdownMAV->setEnabled(true);
connect(uas, SIGNAL(systemSpecsChanged(int)), this, SLOT(UASSpecsChanged(int)));
connect(uas, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), this, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64))); connect(uas, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), this, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)));
connect(uas, SIGNAL(misconfigurationDetected(UASInterface*)), this, SLOT(handleMisconfiguration(UASInterface*))); connect(uas, SIGNAL(misconfigurationDetected(UASInterface*)), this, SLOT(handleMisconfiguration(UASInterface*)));
...@@ -1020,15 +1001,6 @@ void MainWindow::UASCreated(UASInterface* uas) ...@@ -1020,15 +1001,6 @@ void MainWindow::UASCreated(UASInterface* uas)
{ {
_analyzeView = linechartWidget; _analyzeView = linechartWidget;
} }
// Reload view state in case new widgets were added
_loadCurrentViewState();
}
void MainWindow::UASDeleted(UASInterface* uas)
{
Q_UNUSED(uas);
// TODO: Update the UI when a UAS is deleted
} }
/// Stores the state of the toolbar, status bar and widgets associated with the current view /// Stores the state of the toolbar, status bar and widgets associated with the current view
......
...@@ -53,7 +53,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -53,7 +53,7 @@ This file is part of the QGROUNDCONTROL project
#include "Mouse6dofInput.h" #include "Mouse6dofInput.h"
#endif // QGC_MOUSE_ENABLED_WIN #endif // QGC_MOUSE_ENABLED_WIN
#include "DebugConsole.h" #include "DebugConsole.h"
#include "ParameterInterface.h" #include "ParameterEditorWidget.h"
#include "HDDisplay.h" #include "HDDisplay.h"
#include "HSIDisplay.h" #include "HSIDisplay.h"
#include "opmapcontrol.h" #include "opmapcontrol.h"
...@@ -132,15 +132,9 @@ public slots: ...@@ -132,15 +132,9 @@ public slots:
void showSettings(); void showSettings();
/** @brief Simulate a link */ /** @brief Simulate a link */
void simulateLink(bool simulate); void simulateLink(bool simulate);
/** @brief Set the currently controlled UAS */
void setActiveUAS(UASInterface* uas);
/** @brief Add a new UAS */ /** @brief Add a new UAS */
void UASCreated(UASInterface* uas); void UASCreated(UASInterface* uas);
/** Delete an UAS */
void UASDeleted(UASInterface* uas);
/** @brief Update system specs of a UAS */
void UASSpecsChanged(int uas);
void handleMisconfiguration(UASInterface* uas); void handleMisconfiguration(UASInterface* uas);
/** @brief Load configuration views */ /** @brief Load configuration views */
......
#ifndef __OGREWIDGET_H__
#define __OGREWIDGET_H__
#include <OGRE/Ogre.h>
#include <QGLWidget>
#include <QX11Info>
class OgreWidget : public QGLWidget
{
//Q_OBJECT;
public:
OgreWidget( QWidget *parent=0 ):
QGLWidget( parent ),
mOgreWindow(NULL) {
init( "../bin/plugins.cfg", "../bin/ogre.cfg", "../bin/ogre.log" );
}
virtual ~OgreWidget() {
mOgreRoot->shutdown();
delete mOgreRoot;
destroy();
}
protected:
virtual void initializeGL();
virtual void resizeGL( int, int );
virtual void paintGL();
void init( std::string, std::string, std::string );
virtual Ogre::RenderSystem* chooseRenderer( Ogre::RenderSystemList* );
Ogre::Root *mOgreRoot;
Ogre::RenderWindow *mOgreWindow;
Ogre::Camera *mCamera;
Ogre::Viewport *mViewport;
Ogre::SceneManager *mSceneMgr;
};
#endif
#include "ogrewidget.h"
#define THIS OgreWidget
/**
* @brief init the object
* @author kito berg-taylor
*/
void THIS::init( std::string plugins_file,
std::string ogre_cfg_file,
std::string ogre_log )
{
// create the main ogre object
mOgreRoot = new Ogre::Root( plugins_file, ogre_cfg_file, ogre_log );
// setup a renderer
Ogre::RenderSystemList *renderers = mOgreRoot->getAvailableRenderers();
assert( !renderers->empty() ); // we need at least one renderer to do anything useful
Ogre::RenderSystem *renderSystem;
renderSystem = chooseRenderer( renderers );
assert( renderSystem ); // user might pass back a null renderer, which would be bad!
mOgreRoot->setRenderSystem( renderSystem );
QString dimensions = QString( "%1x%2" )
.arg(this->width())
.arg(this->height());
renderSystem->setConfigOption( "Video Mode", dimensions.toStdString() );
// initialize without creating window
mOgreRoot->getRenderSystem()->setConfigOption( "Full Screen", "No" );
mOgreRoot->saveConfig();
mOgreRoot->initialise(false); // don't create a window
}
/**
* @brief setup the rendering context
* @author Kito Berg-Taylor
*/
void THIS::initializeGL()
{
//== Creating and Acquiring Ogre Window ==//
// Get the parameters of the window QT created
QX11Info info = x11Info();
Ogre::String winHandle;
winHandle = Ogre::StringConverter::toString((unsigned long)(info.display()));
winHandle += ":";
winHandle += Ogre::StringConverter::toString((unsigned int)(info.screen()));
winHandle += ":";
winHandle += Ogre::StringConverter::toString((unsigned long)(this->parentWidget()->winId()));
Ogre::NameValuePairList params;
params["parentWindowHandle"] = winHandle;
mOgreWindow = mOgreRoot->createRenderWindow( "QOgreWidget_RenderWindow",
this->width(),
this->height(),
false,
&params );
mOgreWindow->setActive(true);
WId ogreWinId = 0x0;
mOgreWindow->getCustomAttribute( "WINDOW", &ogreWinId );
assert( ogreWinId );
this->create( ogreWinId );
setAttribute( Qt::WA_PaintOnScreen, true );
setAttribute( Qt::WA_NoBackground );
//== Ogre Initialization ==//
Ogre::SceneType scene_manager_type = Ogre::ST_EXTERIOR_CLOSE;
mSceneMgr = mOgreRoot->createSceneManager( scene_manager_type );
mSceneMgr->setAmbientLight( Ogre::ColourValue(1,1,1) );
mCamera = mSceneMgr->createCamera( "QOgreWidget_Cam" );
mCamera->setPosition( Ogre::Vector3(0,1,0) );
mCamera->lookAt( Ogre::Vector3(0,0,0) );
mCamera->setNearClipDistance( 1.0 );
Ogre::Viewport *mViewport = mOgreWindow->addViewport( mCamera );
mViewport->setBackgroundColour( Ogre::ColourValue( 0.8,0.8,1 ) );
}
/**
* @brief render a frame
* @author Kito Berg-Taylor
*/
void THIS::paintGL()
{
assert( mOgreWindow );
mOgreRoot->renderOneFrame();
}
/**
* @brief resize the GL window
* @author Kito Berg-Taylor
*/
void THIS::resizeGL( int width, int height )
{
assert( mOgreWindow );
mOgreWindow->windowMovedOrResized();
}
/**
* @brief choose the right renderer
* @author Kito Berg-Taylor
*/
Ogre::RenderSystem* THIS::chooseRenderer( Ogre::RenderSystemList *renderers )
{
// It would probably be wise to do something more friendly
// that just use the first available renderer
return *renderers->begin();
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Definition of class ParameterInterface
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#include <QTreeWidget>
#include "ParameterInterface.h"
#include "UASManager.h"
#include "ui_ParameterInterface.h"
#include "QGCSensorSettingsWidget.h"
#include <QDebug>
#include <QSettings>
ParameterInterface::ParameterInterface(QWidget *parent) :
QWidget(parent),
paramWidgets(new QMap<int, QGCParamWidget*>()),
curr(-1),
m_ui(new Ui::parameterWidget)
{
m_ui->setupUi(this);
QSettings settings;
// Get current MAV list
QList<UASInterface*> systems = UASManager::instance()->getUASList();
// Add each of them
foreach (UASInterface* sys, systems) {
addUAS(sys);
}
// Setup MAV connections
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(addUAS(UASInterface*)));
connect(UASManager::instance(), SIGNAL(activeUASSetListIndex(int)), this, SLOT(selectUAS(int)));
this->setVisible(false);
}
ParameterInterface::~ParameterInterface()
{
delete paramWidgets;
delete m_ui;
}
void ParameterInterface::selectUAS(int index)
{
m_ui->stackedWidget->setCurrentIndex(index);
m_ui->sensorSettings->setCurrentIndex(index);
curr = index;
}
/**
*
* @param uas System to add to list
*/
void ParameterInterface::addUAS(UASInterface* uas)
{
int uasId = uas->getUASID();
qDebug() << "ParameterInterface::addUAS : " << uasId ;
if (paramWidgets->contains(uasId) ) {
return;
}
QGCParamWidget* paramWidget = new QGCParamWidget(this);
paramWidget = (QGCParamWidget*)paramWidget->initWithUAS(uas);
QString ptrStr;
ptrStr.sprintf("QGCParamWidget %8p (parent %8p)", paramWidget,this);
qDebug() << "Created " << ptrStr << " for UAS id: " << uasId << " count: " << paramWidgets->count();
paramWidgets->insert(uasId, paramWidget);
m_ui->stackedWidget->addWidget(paramWidget);
QGCSensorSettingsWidget* sensor = NULL;
sensor = new QGCSensorSettingsWidget(uas, this);
m_ui->sensorSettings->addWidget(sensor);
// Set widgets as default
if (curr == -1) {
// Clear
if (m_ui->sensorSettings && sensor)
m_ui->sensorSettings->setCurrentWidget(sensor);
m_ui->stackedWidget->setCurrentWidget(paramWidget);
curr = 0;
}
}
void ParameterInterface::changeEvent(QEvent *e)
{
switch (e->type()) {
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
default:
break;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>parameterWidget</class>
<widget class="QWidget" name="parameterWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>707</width>
<height>572</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="100,1">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
<item>
<widget class="QStackedWidget" name="sensorSettings">
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UASView</class>
<widget class="QWidget" name="UASView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>428</width>
<height>419</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>100</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string>QWidget#colorIcon {}
QWidget {
background-color: #252528;
color: #DDDDDF;
border-color: #EEEEEE;
background-clip: margin;
}
QGroupBox {
border: 1px solid #EEEEEE;
border-radius: 5px;
padding: 0px 0px 0px 0px;
margin: 0px;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top center; /* position at the top center */
margin: 0 3px 0px 3px;
padding: 0 3px 0px 0px;
font: bold 8px;
}
QGroupBox#heartbeatIcon {
background-color: red;
}
QPushButton {
font-weight: bold;
font-size: 12px;
border: 1px solid #999999;
border-radius: 10px;
max-width: 40px;
padding: 2px;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #777777, stop: 1 #555555);
}
QPushButton:pressed {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #444444, stop: 1 #555555);
}
QPushButton#landButton {
color: #000000;
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #ffee01, stop:1 #ae8f00) url(&quot;ICONDIR/control/emergency-button.png&quot;);
}
QPushButton:pressed#landButton {
color: #000000;
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #bbaa00, stop:1 #a05b00) url(&quot;ICONDIR/control/emergency-button.png&quot;);
}
QPushButton#killButton {
color: #000000;
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #ffb917, stop:1 #b37300) url(&quot;ICONDIR/control/emergency-button.png&quot;);
}
QPushButton:pressed#killButton {
color: #000000;
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #bb8500, stop:1 #903000) url(&quot;ICONDIR/control/emergency-button.png&quot;);
}
QProgressBar {
border: 1px solid white;
border-radius: 4px;
text-align: center;
padding: 2px;
color: white;
background-color: #111111;
}
QProgressBar:horizontal {
height: 12px;
}
QProgressBar QLabel {
font-size: 8px;
}
QProgressBar:vertical {
width: 12px;
}
QProgressBar::chunk {
background-color: #656565;
}
QProgressBar::chunk#batteryBar {
background-color: green;
}
QProgressBar::chunk#speedBar {
background-color: yellow;
}
QProgressBar::chunk#thrustBar {
background-color: orange;
}</string>
</property>
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,10" columnstretch="0,10">
<property name="margin">
<number>0</number>
</property>
<item row="1" column="0" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>391</width>
<height>3</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0,0,0">
<property name="horizontalSpacing">
<number>5</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="margin">
<number>5</number>
</property>
<item row="0" column="0" rowspan="2" colspan="3">
<widget class="QLabel" name="nameLabel">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>UAS001</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="positionLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>12</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>12</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>00.0 00.0 00.0 m</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="gpsLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>12</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>12</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>00 00 00 N 00 00 00 E</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="timeRemainingLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>00:00:00</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="timeElapsedLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>00:00:00</string>
</property>
</widget>
</item>
<item row="2" column="3" rowspan="3">
<widget class="QProgressBar" name="speedBar">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="value">
<number>24</number>
</property>
</widget>
</item>
<item row="2" column="4" rowspan="3">
<widget class="QProgressBar" name="thrustBar">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="value">
<number>24</number>
</property>
</widget>
</item>
<item row="10" column="2" rowspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="11" column="3" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>10</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QPushButton" name="liftoffButton">
<property name="minimumSize">
<size>
<width>35</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="holdButton">
<property name="minimumSize">
<size>
<width>35</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="skipButton">
<property name="minimumSize">
<size>
<width>35</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="returnButton">
<property name="minimumSize">
<size>
<width>35</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="landButton">
<property name="minimumSize">
<size>
<width>35</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="killButton">
<property name="minimumSize">
<size>
<width>35</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="11" column="5">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>2</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="9" column="2">
<widget class="QLabel" name="stateLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>UNINIT</string>
</property>
</widget>
</item>
<item row="7" column="3" rowspan="4">
<widget class="QLabel" name="statusTextLabel">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>12</height>
</size>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Unknown status</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="groundDistanceLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>00.00 m</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="altitudeLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>00.00 m</string>
</property>
</widget>
</item>
<item row="8" column="1" rowspan="4">
<widget class="QProgressBar" name="batteryBar">
<property name="maximumSize">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
<property name="font">
<font>
<pointsize>6</pointsize>
</font>
</property>
<property name="value">
<number>24</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="8" column="0" rowspan="4">
<widget class="QGroupBox" name="heartbeatIcon">
<property name="maximumSize">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
<property name="title">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>74</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
<zorder>groupBox</zorder>
<zorder>horizontalSpacer_3</zorder>
</widget>
<resources/>
<connections/>
</ui>
#include "QGCBaseParamWidget.h"
#include <QFile>
#include <QVariant>
#include <QTextStream>
#include "QGCUASParamManagerInterface.h"
#include "UASInterface.h"
#include "QGCApplication.h"
#include "QGCFileDialog.h"
QGCBaseParamWidget::QGCBaseParamWidget(QWidget *parent) :
QWidget(parent),
paramMgr(NULL),
mav(NULL),
updatingParamNameLock("")
{
}
QGCBaseParamWidget* QGCBaseParamWidget::initWithUAS(UASInterface *uas)
{
setUAS(uas);
return this;
}
void QGCBaseParamWidget::setUAS(UASInterface* uas)
{
if (uas != mav) {
if (mav) {
//TODO disconnect any connections as needed
disconnectViewSignalsAndSlots();
disconnectFromParamManager();
clearOnboardParamDisplay();
clearPendingParamDisplay();
}
mav = uas;
if (mav) {
connectToParamManager();
connectViewSignalsAndSlots();
layoutWidget();
}
}
}
void QGCBaseParamWidget::connectToParamManager()
{
paramMgr = mav->getParamManager();
//TODO route via paramManager instead?
// Listen to updated param signals from the data model
connect(paramMgr, SIGNAL(parameterUpdated(int, QString , QVariant )),
this, SLOT(handleOnboardParamUpdate(int,QString,QVariant)));
connect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )),
this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool )));
// Listen for param list reload finished
connect(paramMgr, SIGNAL(parameterListUpToDate()),
this, SLOT(handleOnboardParameterListUpToDate()));
if (paramMgr->parametersReady()) {
handleOnboardParameterListUpToDate();
}
// Listen to communications status messages so we can display them
connect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)),
this, SLOT(handleParamStatusMsgUpdate(QString , int )));
}
void QGCBaseParamWidget::disconnectFromParamManager()
{
disconnect(paramMgr, SIGNAL(parameterUpdated(int, QString , QVariant )),
this, SLOT(handleOnboardParamUpdate(int,QString,QVariant)));
disconnect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )),
this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool )));
disconnect(paramMgr, SIGNAL(parameterListUpToDate()),
this, SLOT(handleOnboardParameterListUpToDate()));
// Listen to communications status messages so we can display them
disconnect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)),
this, SLOT(handleParamStatusMsgUpdate(QString , int )));
paramMgr = NULL;
}
void QGCBaseParamWidget::requestOnboardParamsUpdate()
{
paramMgr->requestParameterList();
}
void QGCBaseParamWidget::requestOnboardParamUpdate(QString parameterName)
{
paramMgr->requestParameterUpdate(paramMgr->getDefaultComponentId(), parameterName);
}
void QGCBaseParamWidget::saveParametersToFile()
{
if (!mav)
return;
QString fileName = QGCFileDialog::getSaveFileName(
this, tr("Save Parameters"), qgcApp()->savedParameterFilesLocation(), tr("Parameter Files (*.params)"), "params", true);
if (!fileName.isEmpty()) {
QFile file(fileName);
// TODO Display error message to the user if the file can't be created
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
return;
}
QTextStream outstream(&file);
paramMgr->writeOnboardParamsToStream(outstream,mav->getUASName());
file.close();
}
}
void QGCBaseParamWidget::loadParametersFromFile()
{
if (!mav)
return;
QString fileName = QGCFileDialog::getOpenFileName(
this, tr("Load Parameters"), qgcApp()->savedParameterFilesLocation(),
tr("Parameter Files (*.params);;All Files (*)"));
QFile file(fileName);
// TODO Display error message to the user if the file can't be opened
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return;
}
QTextStream in(&file);
paramMgr->readPendingParamsFromStream(in);
file.close();
}
#ifndef QGCBASEPARAMWIDGET_H
#define QGCBASEPARAMWIDGET_H
#include <QVariant>
#include <QWidget>
//forward declarations
class QGCUASParamManagerInterface;
class UASInterface;
class QGCBaseParamWidget : public QWidget
{
Q_OBJECT
public:
explicit QGCBaseParamWidget(QWidget *parent = 0);
virtual QGCBaseParamWidget* initWithUAS(UASInterface* uas);///< Two-stage construction: initialize this object
virtual void setUAS(UASInterface* uas);///< Allows swapping the underlying UAS
protected:
virtual void setParameterStatusMsg(const QString& msg) = 0;
virtual void layoutWidget() = 0;///< Layout the appearance of this widget
virtual void connectViewSignalsAndSlots() = 0;///< Connect view signals/slots as needed
virtual void disconnectViewSignalsAndSlots() = 0;///< Disconnect view signals/slots as needed
virtual void connectToParamManager(); ///>Connect to any required param manager signals
virtual void disconnectFromParamManager(); ///< Disconnect from any connected param manager signals
signals:
public slots:
virtual void handleOnboardParamUpdate(int component,const QString& parameterName, QVariant value) = 0;
virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) = 0;
virtual void handleOnboardParameterListUpToDate() = 0;
virtual void handleParamStatusMsgUpdate(QString msg, int level) = 0;
/** @brief Clear the rendering of onboard parameters */
virtual void clearOnboardParamDisplay() = 0;
/** @brief Clear the rendering of pending parameters */
virtual void clearPendingParamDisplay() = 0;
/** @brief Request list of parameters from MAV */
virtual void requestOnboardParamsUpdate();
/** @brief Request single parameter from MAV */
virtual void requestOnboardParamUpdate(QString parameterName);
/** @brief Store parameters to a file */
virtual void saveParametersToFile();
/** @brief Load parameters from a file */
virtual void loadParametersFromFile();
protected:
QGCUASParamManagerInterface* paramMgr;
UASInterface* mav;
QString updatingParamNameLock; ///< Name of param currently being updated-- used for reducing echo on param change
};
#endif // QGCBASEPARAMWIDGET_H
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Implementation of class QGCParamWidget
* @author Lorenz Meier <mail@qgroundcontrol.org>
*/
#include <cmath>
#include <float.h>
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QGridLayout>
#include <QList>
#include <QPushButton>
#include <QSettings>
#include <QTime>
#include <QTimer>
#include <QEventLoop>
#include "MainWindow.h"
#include "QGC.h"
#include "QGCParamWidget.h"
#include "UASInterface.h"
#include "UASParameterCommsMgr.h"
#include "QGCMapRCToParamDialog.h"
/**
* @param uas MAV to set the parameters on
* @param parent Parent widget
*/
QGCParamWidget::QGCParamWidget(QWidget *parent) :
QGCBaseParamWidget(parent),
componentItems(new QMap<int, QTreeWidgetItem*>()),
statusLabel(new QLabel(this)),
tree(new QGCParamTreeWidget(this)),
_fullParamListLoaded(false)
{
}
void QGCParamWidget::disconnectViewSignalsAndSlots()
{
disconnect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
this, SLOT(parameterItemChanged(QTreeWidgetItem*,int)));
disconnect(tree, &QGCParamTreeWidget::mapRCToParamRequest, this,
&QGCParamWidget::configureRCToParam);
}
void QGCParamWidget::connectViewSignalsAndSlots()
{
// Listen for edits to the tree UI
connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
this, SLOT(parameterItemChanged(QTreeWidgetItem*,int)));
connect(tree, &QGCParamTreeWidget::mapRCToParamRequest, this,
&QGCParamWidget::configureRCToParam);
connect(tree, &QGCParamTreeWidget::refreshParamRequest, this,
&QGCParamWidget::requestOnboardParamUpdate);
}
void QGCParamWidget::addActionButtonsToLayout(QGridLayout* layout)
{
QPushButton* refreshButton = new QPushButton(tr("Get"));
refreshButton->setToolTip(tr("Fetch parameters currently in volatile memory of aircraft."));
refreshButton->setWhatsThis(tr("Fetch parameters currently in volatile memory of aircraft."));
connect(refreshButton, SIGNAL(clicked()),
this, SLOT(requestOnboardParamsUpdate()));
layout->addWidget(refreshButton, 2, 0);
QPushButton* setButton = new QPushButton(tr("Set"));
setButton->setToolTip(tr("Send pending parameters to volatile onboard memory"));
setButton->setWhatsThis(tr("Send pending parameters to volatile onboard memory"));
connect(setButton, SIGNAL(clicked()),
paramMgr, SLOT(sendPendingParameters()));
layout->addWidget(setButton, 2, 1);
QPushButton* writeButton = new QPushButton(tr("Write (ROM)"));
writeButton->setToolTip(tr("Copy parameters in volatile memory of the aircraft to persistent memory. Transmit your parameters first to write these."));
writeButton->setWhatsThis(tr("Copy parameters in volatile memory of the aircraft to persistent memory. Transmit your parameters first to write these."));
connect(writeButton, SIGNAL(clicked()),
paramMgr, SLOT(copyVolatileParamsToPersistent()));
layout->addWidget(writeButton, 2, 2);
QPushButton* loadFileButton = new QPushButton(tr("Load File"));
loadFileButton->setToolTip(tr("Load parameters from a file into qgroundcontrol. To write these to the aircraft, use transmit after loading them."));
loadFileButton->setWhatsThis(tr("Load parameters from a file into qgroundcontrol. To write these to the aircraft, use transmit after loading them."));
connect(loadFileButton, SIGNAL(clicked()),
this, SLOT(loadParametersFromFile()));
layout->addWidget(loadFileButton, 3, 0);
QPushButton* saveFileButton = new QPushButton(tr("Save File"));
saveFileButton->setToolTip(tr("Save parameters in this view to a file on this computer."));
saveFileButton->setWhatsThis(tr("Save parameters in this view to a file on this computer."));
connect(saveFileButton, SIGNAL(clicked()),
this, SLOT(saveParametersToFile()));
layout->addWidget(saveFileButton, 3, 1);
QPushButton* readButton = new QPushButton(tr("Read (ROM)"));
readButton->setToolTip(tr("Copy parameters from persistent onboard memory to volatile onboard memory of aircraft. DOES NOT update the parameters in this view: click refresh after copying them to get them."));
readButton->setWhatsThis(tr("Copy parameters from persistent onboard memory to volatile onboard memory of aircraft. DOES NOT update the parameters in this view: click refresh after copying them to get them."));
connect(readButton, SIGNAL(clicked()),
paramMgr, SLOT(copyPersistentParamsToVolatile()));
layout->addWidget(readButton, 3, 2);
QPushButton* unsetRCToParamMapButton = new QPushButton(tr("Clear Rc to Param"));
unsetRCToParamMapButton->setToolTip(tr("Remove any bindings between RC channels and parameters."));
unsetRCToParamMapButton->setWhatsThis(tr("Remove any bindings between RC channels and parameters."));
connect(unsetRCToParamMapButton, &QPushButton::clicked,
mav, &UASInterface::unsetRCToParameterMap);
layout->addWidget(unsetRCToParamMapButton, 4, 1);
}
void QGCParamWidget::layoutWidget()
{
statusLabel->setAutoFillBackground(true);
QGridLayout* layout = new QGridLayout(this);
layout->setHorizontalSpacing(6);
layout->setVerticalSpacing(6);
layout->setMargin(0);
layout->setSizeConstraint(QLayout::SetMinimumSize);
// Parameter tree
layout->addWidget(tree, 0, 0, 1, 3);
// Status line
statusLabel->setText(tr("Click refresh to download parameters"));
layout->addWidget(statusLabel, 1, 0, 1, 3);
// BUTTONS
addActionButtonsToLayout(layout);
// Set correct vertical scaling
layout->setRowStretch(0, 100);
layout->setRowStretch(1, 10);
layout->setRowStretch(2, 10);
layout->setRowStretch(3, 10);
// Set layout
this->setLayout(layout);
// Set header
QStringList headerItems;
headerItems.append("Parameter");
headerItems.append("Value");
tree->setHeaderLabels(headerItems);
tree->setColumnCount(2);
tree->setColumnWidth(0,200);
tree->setColumnWidth(1,120);
tree->setExpandsOnDoubleClick(true);
tree->setVisible(true);
}
void QGCParamWidget::addComponentItem(int compId, QString compName)
{
QString compLine = QString("%1 (#%2)").arg(compName).arg(compId);
//QString ptrStr = QString().sprintf("%8p", this);
//qDebug() << "QGCParamWidget" << ptrStr << "addComponentItem:" << compLine;
if (componentItems->contains(compId)) {
// Update existing component item
componentItems->value(compId)->setData(0, Qt::DisplayRole, compLine);
//components->value(component)->setData(1, Qt::DisplayRole, QString::number(component));
componentItems->value(compId)->setFirstColumnSpanned(true);
} else {
// Add new component item
QStringList list(compLine);
QTreeWidgetItem* compItem = new QTreeWidgetItem(list);
compItem->setFirstColumnSpanned(true);
componentItems->insert(compId, compItem);
// Create parameter grouping for this component and update maps
paramGroups.insert(compId, new QMap<QString, QTreeWidgetItem*>());
tree->addTopLevelItem(compItem);
tree->update();
}
}
void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending)
{
//qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock;
if (updatingParamNameLock == paramName) {
//qDebug() << "ignoring bounce from " << paramName;
return;
}
else {
updatingParamNameLock = paramName;
}
QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value);
if (paramItem) {
if (isPending) {
paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange)));
paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange)));
//ensure that the adjusted item is visible
tree->expandItem(paramItem->parent());
}
else {
paramItem->setBackground(0, Qt::NoBrush);
paramItem->setBackground(1, Qt::NoBrush);
}
}
updatingParamNameLock.clear();
}
void QGCParamWidget::handleOnboardParamUpdate(int compId, const QString& paramName, QVariant value)
{
//qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock;
if (paramName == updatingParamNameLock) {
//qDebug() << "handlePendingParamUpdate ignoring bounce from " << paramName;
return;
}
updatingParamNameLock = paramName;
updateParameterDisplay(compId, paramName, value);
updatingParamNameLock.clear();
}
void QGCParamWidget::handleOnboardParameterListUpToDate()
{
// Don't load full param list more than once
if (_fullParamListLoaded) {
return;
}
_fullParamListLoaded = true;
//turn off updates while we refresh the entire list
tree->setUpdatesEnabled(false);
//rewrite the component item tree after receiving the full list
QMap<int, QMap<QString, QVariant>*>::iterator i;
QMap<int, QMap<QString, QVariant>*>* onboardParams = paramMgr->dataModel()->getAllOnboardParams();
for (i = onboardParams->begin(); i != onboardParams->end(); ++i) {
int compId = i.key();
QMap<QString, QVariant>* paramPairs = onboardParams->value(compId);
QMap<QString, QVariant>::iterator j;
for (j = paramPairs->begin(); j != paramPairs->end(); j++) {
updatingParamNameLock = j.key();
updateParameterDisplay(compId, j.key(),j.value());
updatingParamNameLock.clear();
}
}
// Expand visual tree
tree->expandItem(tree->topLevelItem(0));
tree->setUpdatesEnabled(true);
tree->update();
}
QTreeWidgetItem* QGCParamWidget::findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName)
{
QTreeWidgetItem* childItem = NULL;
for (int i = 0; i < parentItem->childCount(); i++) {
QTreeWidgetItem* child = parentItem->child(i);
QString key = child->data(0, Qt::DisplayRole).toString();
if (key == paramName) {
childItem = child;
break;
}
}
return childItem;
}
QTreeWidgetItem* QGCParamWidget::getParentWidgetItemForParam(int compId, const QString& paramName)
{
QTreeWidgetItem* parentItem = componentItems->value(compId);
QString splitToken = "_";
// Check if auto-grouping can work
if (paramName.contains(splitToken)) {
QString parentStr = paramName.section(splitToken, 0, 0, QString::SectionSkipEmpty);
QMap<QString, QTreeWidgetItem*>* compParamGroups = paramGroups.value(compId);
if (!compParamGroups->contains(parentStr)) {
// Insert group item
QStringList glist;
glist.append(parentStr);
QTreeWidgetItem* groupItem = new QTreeWidgetItem(glist);
compParamGroups->insert(parentStr, groupItem);
// insert new group alphabetized
QList<QString> groupKeys = compParamGroups->uniqueKeys();
int insertIdx = groupKeys.indexOf(parentStr);
componentItems->value(compId)->insertChild(insertIdx,groupItem);
}
//parent item for this parameter item will be a group widget item
parentItem = compParamGroups->value(parentStr);
}
else {
//parent item for this parameter will be the top level (component) widget item
parentItem = componentItems->value(compId);
}
return parentItem;
}
void QGCParamWidget::insertParamAlphabetical(int indexLowerBound, int indexUpperBound, QTreeWidgetItem* parentItem, QTreeWidgetItem* paramItem)
{
if (indexLowerBound >= indexUpperBound)
{
if (paramItem->text(0).compare(parentItem->child(indexLowerBound)->text(0)) < 0) {
parentItem->insertChild(indexLowerBound, paramItem);
}
else
{
if (indexLowerBound < parentItem->childCount() - 1) {
parentItem->insertChild(indexLowerBound + 1, paramItem);
}
else
{
parentItem->addChild(paramItem);
}
}
}
else
{
int midpoint = indexLowerBound + ((indexUpperBound - indexLowerBound) / 2);
if (paramItem->text(0).compare(parentItem->child(midpoint)->text(0)) < 0)
{
insertParamAlphabetical(indexLowerBound, midpoint - 1, parentItem, paramItem);
} else
{
insertParamAlphabetical(midpoint + 1, indexUpperBound, parentItem, paramItem);
}
}
}
QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, QVariant value)
{
//qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName;
// Filter the parameters according to the filter list
if (_filterList.count() != 0) {
bool filterFound = false;
foreach(QString paramFilter, _filterList) {
if (paramFilter.endsWith("*") && parameterName.startsWith(paramFilter.left(paramFilter.size() - 1))) {
filterFound = true;
break;
}
if (paramFilter == parameterName) {
filterFound = true;
break;
}
}
if (!filterFound) {
return NULL;
}
}
// Reference to item in tree
QTreeWidgetItem* paramItem = NULL;
// Add component item if necessary
if (!componentItems->contains(compId)) {
QString componentName = tr("Component #%1").arg(compId);
addComponentItem(compId, componentName);
}
//default parent item for this parameter widget item will be the top level component item
QTreeWidgetItem* parentItem = getParentWidgetItemForParam(compId,parameterName);
if (parentItem) {
paramItem = findChildWidgetItemForParam(parentItem,parameterName);
if (!paramItem) {
// Insert parameter into map
QStringList plist;
plist.append(parameterName);
// CREATE PARAMETER ITEM
paramItem = new QTreeWidgetItem(plist);
// CONFIGURE PARAMETER ITEM
if (value.type() == QVariant::Char) {
paramItem->setData(1, Qt::DisplayRole, value.toUInt());
}
else {
paramItem->setData(1, Qt::DisplayRole, value);
}
paramItem->setFlags(paramItem->flags() | Qt::ItemIsEditable);
//Insert alphabetically
if (parentItem->childCount() > 0) {
insertParamAlphabetical(0, parentItem->childCount() - 1, parentItem, paramItem);
} else
{
parentItem->addChild(paramItem);
}
//only add the tooltip when the parameter item is first added
QString paramDesc = paramMgr->dataModel()->getParamDescription(parameterName);
if (!paramDesc.isEmpty()) {
QString tooltipFormat;
if (paramMgr->dataModel()->isParamDefaultKnown(parameterName)) {
tooltipFormat = tr("Default: %1, %2");
double paramDefValue = paramMgr->dataModel()->getParamDefault(parameterName);
tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc);
}
else {
tooltipFormat = paramDesc;
}
paramItem->setToolTip(0, tooltipFormat);
paramItem->setToolTip(1, tooltipFormat);
}
}
//update the parameterItem's data
if (value.type() == QVariant::Char) {
paramItem->setData(1, Qt::DisplayRole, value.toUInt());
}
else {
paramItem->setData(1, Qt::DisplayRole, value);
}
}
if (paramItem) {
// Reset background color
paramItem->setBackground(0, Qt::NoBrush);
paramItem->setBackground(1, Qt::NoBrush);
paramItem->setTextColor(0, QGC::colorDarkWhite);
paramItem->setTextColor(1, QGC::colorDarkWhite);
if (paramItem == tree->currentItem()) {
//need to unset current item to clear highlighting (green by default)
tree->setCurrentItem(NULL); //clear the selected line
}
}
return paramItem;
}
void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column)
{
if (paramItem && column > 0) {
QString key = paramItem->data(0, Qt::DisplayRole).toString();
//qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock;
if (key == updatingParamNameLock) {
//qDebug() << "parameterItemChanged ignoring bounce from " << key;
return;
}
else {
updatingParamNameLock = key;
}
QTreeWidgetItem* parent = paramItem->parent();
while (parent->parent() != NULL) {
parent = parent->parent();
}
// Parent is now top-level component
int componentId = componentItems->key(parent);
QVariant value = paramItem->data(1, Qt::DisplayRole);
bool pending = paramMgr->dataModel()->updatePendingParamWithValue(componentId,key,value);
// If the value will result in an update
if (pending) {
// Set parameter on changed list to be transmitted to MAV
statusLabel->setText(tr("Pending: %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' ')));
paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange)));
paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange)));
}
else {
QMap<QString , QVariant>* pendingParams = paramMgr->dataModel()->getPendingParamsForComponent(componentId);
int pendingCount = pendingParams->count();
statusLabel->setText(tr("Pending items: %1").arg(pendingCount));
paramItem->setBackground(0, Qt::NoBrush);
paramItem->setBackground(1, Qt::NoBrush);
}
if (paramItem == tree->currentItem()) {
//need to unset current item to clear highlighting (green by default)
tree->setCurrentItem(NULL); //clear the selected line
}
updatingParamNameLock.clear();
}
}
void QGCParamWidget::setParameterStatusMsg(const QString& msg)
{
statusLabel->setText(msg);
}
void QGCParamWidget::clearOnboardParamDisplay()
{
tree->clear();
componentItems->clear();
}
void QGCParamWidget::clearPendingParamDisplay()
{
tree->clear();
componentItems->clear();
}
void QGCParamWidget::handleParamStatusMsgUpdate(QString msg, int level)
{
QColor bgColor = QGC::colorGreen;
if ((int)UASParameterCommsMgr::ParamCommsStatusLevel_Warning == level) {
bgColor = QGC::colorOrange;
}
else if ((int)UASParameterCommsMgr::ParamCommsStatusLevel_Error == level) {
bgColor = QGC::colorRed;
}
QPalette pal = statusLabel->palette();
pal.setColor(backgroundRole(), bgColor);
statusLabel->setPalette(pal);
statusLabel->setText(msg);
}
void QGCParamWidget::configureRCToParam(QString param_id) {
QGCMapRCToParamDialog * d = new QGCMapRCToParamDialog(param_id,
mav, this);
d->exec();
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Declaration of class QGCParamWidget
* @author Lorenz Meier <mail@qgroundcontrol.org>
*/
#ifndef QGCPARAMWIDGET_H
#define QGCPARAMWIDGET_H
#include <QWidget>
#include <QTreeWidget>
#include <QMap>
#include <QLabel>
#include <QTimer>
#include "QGCParamTreeWidget.h"
#include "QGCBaseParamWidget.h"
//forward declarations
class QGridLayout;
class UASInterface;
/**
* @brief Widget to read/set onboard parameters
*/
class QGCParamWidget : public QGCBaseParamWidget
{
Q_OBJECT
public:
QGCParamWidget(QWidget *parent = 0);
/// @brief Sets the list of parameters which should be shown by this editor. Parameter names can be
/// wildcarded at the end such as this: "RC*". Which will filter to all parameters which begin
/// with "RC". The wildcard (*) can only be at the end of the string.
void setFilterList(const QStringList& filterList) { _filterList = filterList; }
protected:
virtual void setParameterStatusMsg(const QString& msg);
virtual void layoutWidget();///< Layout the appearance of this widget
virtual void connectViewSignalsAndSlots();///< Connect view signals/slots as needed
virtual void disconnectViewSignalsAndSlots();///< Connect view signals/slots as needed
virtual QTreeWidgetItem* getParentWidgetItemForParam(int compId, const QString& paramName);
virtual QTreeWidgetItem* findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName);
/** @brief Add a component item as a child of this widget
* @param compId Component id of the component
* @param compName Human friendly name of the component
*/
void addComponentItem(int compId, QString compName);
virtual void addActionButtonsToLayout(QGridLayout* layout);
public slots:
virtual void handleOnboardParamUpdate(int component,const QString& parameterName, QVariant value);
virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending);
virtual void handleOnboardParameterListUpToDate();
virtual void handleParamStatusMsgUpdate(QString msg, int level);
virtual void clearOnboardParamDisplay();
virtual void clearPendingParamDisplay();
/** @brief Adds parameter at the correct location by a alphapetical comparison of the parameter names */
void insertParamAlphabetical(int indexLowerBound, int indexUpperBound, QTreeWidgetItem* parentItem, QTreeWidgetItem* paramItem);
/** @brief Ensure that view of parameter matches data in the model */
QTreeWidgetItem* updateParameterDisplay(int component, QString parameterName, QVariant value);
/** @brief Update when user changes parameters */
void parameterItemChanged(QTreeWidgetItem* prev, int column);
/** Promt configuration for param map config from user */
void configureRCToParam(QString param_id);
protected:
QMap<int, QTreeWidgetItem*>* componentItems; ///< The tree of component items, stored by component ID
QMap<int, QMap<QString, QTreeWidgetItem*>* > paramGroups; ///< Parameter groups to organize component items
QLabel* statusLabel; ///< User-facing parameter status label
QGCParamTreeWidget* tree; ///< The parameter tree
QStringList _filterList;
private:
bool _fullParamListLoaded;
};
#endif // QGCPARAMWIDGET_H
#include "QGCPendingParamWidget.h"
#include <QGridLayout>
#include <QPushButton>
#include "UASManager.h"
#include "UASParameterCommsMgr.h"
QGCPendingParamWidget::QGCPendingParamWidget(QObject *parent) :
QGCParamWidget((QWidget*)parent)
{
//this subclass doesn't display status updates
statusLabel->hide();
}
void QGCPendingParamWidget::connectToParamManager()
{
paramMgr = mav->getParamManager();
// Listen to updated param signals from the data model
connect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )),
this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool )));
}
void QGCPendingParamWidget::disconnectFromParamManager()
{
// Listen to updated param signals from the data model
disconnect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )),
this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool )));
paramMgr = NULL;
}
void QGCPendingParamWidget::disconnectViewSignalsAndSlots()
{
//we ignore edits from the tree view
}
void QGCPendingParamWidget::connectViewSignalsAndSlots()
{
//we ignore edits from the tree view
}
void QGCPendingParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending)
{
// qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock;
if (updatingParamNameLock == paramName) {
//qDebug() << "ignoring bounce from " << paramName;
return;
}
else {
updatingParamNameLock = paramName;
}
QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value);
if (isPending) {
QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value);
paramItem->setFlags(paramItem->flags() & ~Qt::ItemIsEditable); //disallow editing
paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange)));
paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange)));
tree->expandAll();
}
else {
//we don't display non-pending items
QTreeWidgetItem* groupItem = paramItem->parent();
if (NULL != groupItem) {
tree->setUpdatesEnabled(false);
QTreeWidgetItem* componentItem = NULL;
if (1 == groupItem->childCount()) {
componentItem = groupItem->parent();
}
//always remove the actual paramItem from its parent
groupItem->removeChild(paramItem);
//now we may need to remove the groupItem if it has no more children
if (NULL != componentItem) {
//remove the group from our internal data structures
QMap<QString, QTreeWidgetItem*>* compParamGroups = paramGroups.value(compId);
QString groupStr = paramName.section("_", 0, 0, QString::SectionSkipEmpty);
compParamGroups->remove(groupStr);
//remove the group item from componentItems
componentItems->value(compId)->removeChild(groupItem);
// remove the group item from the tree widget itself
componentItem->removeChild(groupItem);
if (0 == componentItem->childCount()) {
//the component itself no longer has any pending changes: remove it
paramGroups.remove(compId);
componentItems->remove(compId);
QTreeWidgetItem* compTop = tree->takeTopLevelItem(tree->indexOfTopLevelItem(componentItem));
delete compTop; //we own it after take
}
}
tree->setUpdatesEnabled(true);
tree->update();
}
}
updatingParamNameLock.clear();
}
void QGCPendingParamWidget::addActionButtonsToLayout(QGridLayout* layout)
{
QPushButton* setButton = new QPushButton(tr("Set"));
setButton->setToolTip(tr("Send pending parameters to volatile onboard memory"));
setButton->setWhatsThis(tr("Send pending parameters to volatile onboard memory"));
connect(setButton, SIGNAL(clicked()),
paramMgr, SLOT(sendPendingParameters()));
layout->addWidget(setButton, 2, 0);
QPushButton* clearButton = new QPushButton(tr("Clear"));
clearButton->setToolTip(tr("Clear pending parameters without sending"));
clearButton->setWhatsThis(tr("Clear pending parameters without sending"));
connect(clearButton, SIGNAL(clicked()),
paramMgr, SLOT(clearAllPendingParams()));
layout->addWidget(clearButton, 2, 1);
}
#ifndef QGCPENDINGPARAMWIDGET_H
#define QGCPENDINGPARAMWIDGET_H
#include "QGCParamWidget.h"
class QGridLayout;
class QGCPendingParamWidget : public QGCParamWidget
{
Q_OBJECT
public:
explicit QGCPendingParamWidget(QObject* parent);
protected:
virtual void connectToParamManager();
virtual void disconnectFromParamManager();
virtual void connectViewSignalsAndSlots();
virtual void disconnectViewSignalsAndSlots();
virtual void addActionButtonsToLayout(QGridLayout* layout);
signals:
public slots:
virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending);
};
#endif // QGCPENDINGPARAMWIDGET_H
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Implementation of QGCSensorSettingsWidget
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#include "QGCSensorSettingsWidget.h"
#include "ui_QGCSensorSettingsWidget.h"
QGCSensorSettingsWidget::QGCSensorSettingsWidget(UASInterface* uas, QWidget *parent) :
QWidget(parent),
mav(uas),
ui(new Ui::QGCSensorSettingsWidget)
{
ui->setupUi(this);
// Set up delay timers
delayedSendRawSensorTimer.setInterval(800);
delayedSendControllerTimer.setInterval(800);
delayedSendExtendedTimer.setInterval(800);
delayedSendRCTimer.setInterval(800);
delayedSendPositionTimer.setInterval(800);
delayedSendExtra1Timer.setInterval(800);
delayedSendExtra2Timer.setInterval(800);
delayedSendExtra3Timer.setInterval(800);
connect(&delayedSendRawSensorTimer, SIGNAL(timeout()), this, SLOT(sendRawSensor()));
connect(&delayedSendControllerTimer, SIGNAL(timeout()), this, SLOT(sendController()));
connect(&delayedSendExtendedTimer, SIGNAL(timeout()), this, SLOT(sendExtended()));
connect(&delayedSendRCTimer, SIGNAL(timeout()), this, SLOT(sendRC()));
connect(&delayedSendPositionTimer, SIGNAL(timeout()), this, SLOT(sendPosition()));
connect(&delayedSendExtra1Timer, SIGNAL(timeout()), this, SLOT(sendExtra1()));
connect(&delayedSendExtra2Timer, SIGNAL(timeout()), this, SLOT(sendExtra2()));
connect(&delayedSendExtra3Timer, SIGNAL(timeout()), this, SLOT(sendExtra3()));
// Connect UI
connect(ui->spinBox_rawSensor, SIGNAL(valueChanged(int)), this, SLOT(delayedSendRawSensor(int)));//mav, SLOT(enableRawSensorDataTransmission(int)));
connect(ui->spinBox_controller, SIGNAL(valueChanged(int)), this, SLOT(delayedSendController(int)));
connect(ui->spinBox_extended, SIGNAL(valueChanged(int)), this, SLOT(delayedSendExtended(int)));
connect(ui->spinBox_rc, SIGNAL(valueChanged(int)), this, SLOT(delayedSendRC(int)));
connect(ui->spinBox_position, SIGNAL(valueChanged(int)), this, SLOT(delayedSendPosition(int)));
connect(ui->spinBox_extra1, SIGNAL(valueChanged(int)), this, SLOT(delayedSendExtra1(int)));
connect(ui->spinBox_extra2, SIGNAL(valueChanged(int)), this, SLOT(delayedSendExtra2(int)));
connect(ui->spinBox_extra3, SIGNAL(valueChanged(int)), this, SLOT(delayedSendExtra3(int)));
// Calibration
connect(ui->rcCalButton, SIGNAL(clicked()), mav, SLOT(startRadioControlCalibration()));
connect(ui->magCalButton, SIGNAL(clicked()), mav, SLOT(startMagnetometerCalibration()));
connect(ui->pressureCalButton, SIGNAL(clicked()), mav, SLOT(startPressureCalibration()));
connect(ui->gyroCalButton, SIGNAL(clicked()), mav, SLOT(startGyroscopeCalibration()));
// Hide the calibration stuff - done in custom widgets anyway
ui->groupBox_3->hide();
}
void QGCSensorSettingsWidget::delayedSendRawSensor(int rate)
{
Q_UNUSED(rate);
delayedSendRawSensorTimer.start();
}
void QGCSensorSettingsWidget::delayedSendController(int rate)
{
Q_UNUSED(rate);
delayedSendControllerTimer.start();
}
void QGCSensorSettingsWidget::delayedSendExtended(int rate)
{
Q_UNUSED(rate);
delayedSendExtendedTimer.start();
}
void QGCSensorSettingsWidget::delayedSendRC(int rate)
{
Q_UNUSED(rate);
delayedSendRCTimer.start();
}
void QGCSensorSettingsWidget::delayedSendPosition(int rate)
{
Q_UNUSED(rate);
delayedSendPositionTimer.start();
}
void QGCSensorSettingsWidget::delayedSendExtra1(int rate)
{
Q_UNUSED(rate);
delayedSendExtra1Timer.start();
}
void QGCSensorSettingsWidget::delayedSendExtra2(int rate)
{
Q_UNUSED(rate);
delayedSendExtra2Timer.start();
}
void QGCSensorSettingsWidget::delayedSendExtra3(int rate)
{
Q_UNUSED(rate);
delayedSendExtra3Timer.start();
}
void QGCSensorSettingsWidget::sendRawSensor()
{
delayedSendRawSensorTimer.stop();
mav->enableRawSensorDataTransmission(ui->spinBox_rawSensor->value());
}
void QGCSensorSettingsWidget::sendController()
{
delayedSendControllerTimer.stop();
mav->enableRawControllerDataTransmission(ui->spinBox_controller->value());
}
void QGCSensorSettingsWidget::sendExtended()
{
delayedSendExtendedTimer.stop();
mav->enableExtendedSystemStatusTransmission(ui->spinBox_extended->value());
}
void QGCSensorSettingsWidget::sendRC()
{
delayedSendRCTimer.stop();
mav->enableRCChannelDataTransmission(ui->spinBox_rc->value());
}
void QGCSensorSettingsWidget::sendPosition()
{
delayedSendPositionTimer.stop();
mav->enablePositionTransmission(ui->spinBox_position->value());
}
void QGCSensorSettingsWidget::sendExtra1()
{
delayedSendExtra1Timer.stop();
mav->enableExtra1Transmission(ui->spinBox_extra1->value());
}
void QGCSensorSettingsWidget::sendExtra2()
{
delayedSendExtra2Timer.stop();
mav->enableExtra2Transmission(ui->spinBox_extra2->value());
}
void QGCSensorSettingsWidget::sendExtra3()
{
delayedSendExtra3Timer.stop();
mav->enableExtra3Transmission(ui->spinBox_extra3->value());
}
QGCSensorSettingsWidget::~QGCSensorSettingsWidget()
{
delete ui;
}
void QGCSensorSettingsWidget::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QGCSensorSettingsWidget</class>
<widget class="QWidget" name="QGCSensorSettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>307</width>
<height>221</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_4" rowstretch="10,0">
<property name="margin">
<number>0</number>
</property>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Calibration Wizards</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="100,100">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<property name="horizontalSpacing">
<number>12</number>
</property>
<property name="verticalSpacing">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QPushButton" name="rcCalButton">
<property name="text">
<string>RC Cal.</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="magCalButton">
<property name="text">
<string>Mag. Cal.</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="gyroCalButton">
<property name="text">
<string>Gyro Cal.</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pressureCalButton">
<property name="text">
<string>Pressure Cal.</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Data Stream Rates (Hz)</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<property name="horizontalSpacing">
<number>5</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QSpinBox" name="spinBox_rawSensor">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>Raw Sensor</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QSpinBox" name="spinBox_extended">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QSpinBox" name="spinBox_position">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QSpinBox" name="spinBox_controller">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Ext. Status</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Position</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Raw Contr.</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="spinBox_rc">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="spinBox_extra1">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QSpinBox" name="spinBox_extra2">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QSpinBox" name="spinBox_extra3">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_5">
<property name="text">
<string>RC Chan.</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Extra 1</string>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Extra 2</string>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Extra 3</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment