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 += \
src/input \
src/lib/qmapcontrol \
src/ui/mavlink \
src/ui/param \
src/ui/map3D \
src/ui/mission \
src/ui/designer \
......@@ -159,7 +158,8 @@ INCLUDEPATH += \
src/ui/mapdisplay \
src/VehicleSetup \
src/AutoPilotPlugins \
src/QmlControls
src/QmlControls \
src/ViewWidgets
FORMS += \
src/ui/MainWindow.ui \
......@@ -169,13 +169,11 @@ FORMS += \
src/ui/UASInfo.ui \
src/ui/Linechart.ui \
src/ui/UASView.ui \
src/ui/ParameterInterface.ui \
src/ui/WaypointList.ui \
src/ui/JoystickWidget.ui \
src/ui/DebugConsole.ui \
src/ui/HDDisplay.ui \
src/ui/MAVLinkSettingsWidget.ui \
src/ui/QGCSensorSettingsWidget.ui \
src/ui/QGCDataPlot2D.ui \
src/ui/QMap3D.ui \
src/ui/uas/QGCUnconnectedInfoWidget.ui \
......@@ -263,7 +261,7 @@ HEADERS += \
src/comm/MAVLinkSimulationLink.h \
src/comm/UDPLink.h \
src/comm/TCPLink.h \
src/ui/ParameterInterface.h \
src/ViewWidgets/ParameterEditorWidget.h \
src/ui/WaypointList.h \
src/Waypoint.h \
src/input/JoystickInput.h \
......@@ -273,8 +271,6 @@ HEADERS += \
src/ui/MAVLinkSettingsWidget.h \
src/GAudioOutput.h \
src/LogCompressor.h \
src/ui/QGCParamWidget.h \
src/ui/QGCSensorSettingsWidget.h \
src/ui/linechart/Linecharts.h \
src/uas/UASWaypointManager.h \
src/ui/HSIDisplay.h \
......@@ -352,8 +348,6 @@ HEADERS += \
src/ui/configuration/ApmHighlighter.h \
src/uas/UASParameterDataModel.h \
src/uas/UASParameterCommsMgr.h \
src/ui/QGCPendingParamWidget.h \
src/ui/QGCBaseParamWidget.h \
src/ui/px4_configuration/PX4RCCalibration.h \
src/ui/px4_configuration/RCValueWidget.h \
src/uas/UASManagerInterface.h \
......@@ -369,7 +363,6 @@ HEADERS += \
src/QGCQuickWidget.h \
src/QGCPalette.h \
src/QGCQmlWidgetHolder.h \
src/ui/QGCParamTreeWidget.h \
src/ui/QGCMapRCToParamDialog.h \
src/QGCDockWidget.h \
src/ui/QGCLinkConfiguration.h \
......@@ -379,9 +372,11 @@ HEADERS += \
src/uas/UASMessageHandler.h \
src/ui/toolbar/MainToolBar.h \
src/QmlControls/ScreenTools.h \
src/QmlControls/ParameterEditorController.h \
src/QGCLoggingCategory.h \
src/ui/flightdisplay/QGCFlightDisplay.h \
src/ui/mapdisplay/QGCMapDisplay.h
src/ui/mapdisplay/QGCMapDisplay.h \
src/ViewWidgets/ViewWidgetController.h \
SOURCES += \
src/main.cc \
......@@ -410,7 +405,7 @@ SOURCES += \
src/comm/MAVLinkSimulationLink.cc \
src/comm/UDPLink.cc \
src/comm/TCPLink.cc \
src/ui/ParameterInterface.cc \
src/ViewWidgets/ParameterEditorWidget.cc \
src/ui/WaypointList.cc \
src/Waypoint.cc \
src/input/JoystickInput.cc \
......@@ -420,8 +415,6 @@ SOURCES += \
src/ui/MAVLinkSettingsWidget.cc \
src/GAudioOutput.cc \
src/LogCompressor.cc \
src/ui/QGCParamWidget.cc \
src/ui/QGCSensorSettingsWidget.cc \
src/ui/linechart/Linecharts.cc \
src/uas/UASWaypointManager.cc \
src/ui/HSIDisplay.cc \
......@@ -496,8 +489,6 @@ SOURCES += \
src/ui/configuration/ApmHighlighter.cc \
src/uas/UASParameterDataModel.cc \
src/uas/UASParameterCommsMgr.cc \
src/ui/QGCPendingParamWidget.cc \
src/ui/QGCBaseParamWidget.cc \
src/ui/px4_configuration/PX4RCCalibration.cc \
src/ui/px4_configuration/RCValueWidget.cc \
src/uas/QGCUASFileManager.cc \
......@@ -510,7 +501,6 @@ SOURCES += \
src/QGCQuickWidget.cc \
src/QGCPalette.cc \
src/QGCQmlWidgetHolder.cpp \
src/ui/QGCParamTreeWidget.cpp \
src/ui/QGCMapRCToParamDialog.cpp \
src/QGCDockWidget.cc \
src/ui/QGCLinkConfiguration.cc \
......@@ -520,9 +510,11 @@ SOURCES += \
src/uas/UASMessageHandler.cc \
src/ui/toolbar/MainToolBar.cc \
src/QmlControls/ScreenTools.cc \
src/QmlControls/ParameterEditorController.cc \
src/QGCLoggingCategory.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
......@@ -605,7 +597,6 @@ HEADERS+= \
src/VehicleSetup/SetupView.h \
src/VehicleSetup/VehicleComponent.h \
src/VehicleSetup/FirmwareUpgradeController.h \
src/VehicleSetup/ParameterEditorController.h \
src/VehicleSetup/PX4Bootloader.h \
src/VehicleSetup/PX4FirmwareUpgradeThread.h \
src/AutoPilotPlugins/AutoPilotPluginManager.h \
......@@ -630,7 +621,6 @@ SOURCES += \
src/VehicleSetup/SetupView.cc \
src/VehicleSetup/VehicleComponent.cc \
src/VehicleSetup/FirmwareUpgradeController.cc \
src/VehicleSetup/ParameterEditorController.cc \
src/VehicleSetup/PX4Bootloader.cc \
src/VehicleSetup/PX4FirmwareUpgradeThread.cc \
src/AutoPilotPlugins/AutoPilotPluginManager.cc \
......
......@@ -29,13 +29,17 @@
<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/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="SetupViewButtonsDisconnected.qml">src/VehicleSetup/SetupViewButtonsDisconnected.qml</file>
<file alias="VehicleSummary.qml">src/VehicleSetup/VehicleSummary.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="PowerComponent.qml">src/AutoPilotPlugins/PX4/PowerComponent.qml</file>
<file alias="SensorsComponent.qml">src/AutoPilotPlugins/PX4/SensorsComponent.qml</file>
......
......@@ -33,6 +33,14 @@ AutoPilotPlugin::AutoPilotPlugin(UASInterface* uas, QObject* parent) :
_pluginReady(false)
{
Q_ASSERT(_uas);
connect(_uas, &UASInterface::disconnected, this, &AutoPilotPlugin::_uasDisconnected);
}
void AutoPilotPlugin::_uasDisconnected(void)
{
_pluginReady = false;
emit pluginReadyChanged(_pluginReady);
}
void AutoPilotPlugin::refreshAllParameters(void)
......
......@@ -51,6 +51,7 @@ class AutoPilotPlugin : public QObject
public:
AutoPilotPlugin(UASInterface* uas, QObject* parent);
/// true: plugin is ready for use, plugin should no longer be used
Q_PROPERTY(bool pluginReady READ pluginReady NOTIFY pluginReadyChanged)
/// List of VehicleComponent objects
......@@ -100,12 +101,10 @@ public:
// Must be implemented by derived class
virtual const QVariantList& vehicleComponents(void) = 0;
/// FIXME: Kind of hacky
static void clearStaticData(void);
UASInterface* uas(void) { return _uas; }
bool pluginReady(void) { return _pluginReady; }
UASInterface* uas(void) { return _uas; }
signals:
/// Signalled when plugin is ready for use
......@@ -120,6 +119,9 @@ protected:
UASInterface* _uas;
bool _pluginReady;
private slots:
void _uasDisconnected(void);
};
#endif
......@@ -61,6 +61,8 @@
#include "QGCPalette.h"
#include "ScreenTools.h"
#include "QGCLoggingCategory.h"
#include "ViewWidgetController.h"
#include "ParameterEditorController.h"
#ifdef QGC_RTLAB_ENABLED
#include "OpalLink.h"
......@@ -262,6 +264,8 @@ void QGCApplication::_initCommon(void)
// Register our Qml objects
qmlRegisterType<QGCPalette>("QGroundControl.Palette", 1, 0, "QGCPalette");
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)
......
......@@ -12,7 +12,7 @@
// 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.
#define QGC_SETTINGS_VERSION 4
#define QGC_SETTINGS_VERSION 5
#define QGC_APPLICATION_NAME "QGroundControl"
#define QGC_ORG_NAME "QGroundControl.org"
......
......@@ -25,15 +25,23 @@
#include <QCloseEvent>
QGCDockWidget::QGCDockWidget(const QString& title, QWidget *parent, Qt::WindowFlags flags) :
QDockWidget(title, parent, flags)
QGCDockWidget::QGCDockWidget(const QString& title, QAction* action, QWidget *parent, Qt::WindowFlags 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
void QGCDockWidget::closeEvent(QCloseEvent* event)
{
Q_ASSERT(_action);
event->ignore();
setVisible(false);
_action->trigger();
}
......@@ -25,6 +25,7 @@
#define QGCDockWidget_h
#include <QDockWidget>
#include <QAction>
/// @file
/// @brief Subclass of QDockWidget so we can intercept the closeEvent.
......@@ -35,9 +36,12 @@ class QGCDockWidget : public QDockWidget {
Q_OBJECT
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);
private:
QAction* _action;
};
......
......@@ -21,6 +21,9 @@
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
......@@ -33,35 +36,28 @@ import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
Rectangle {
QGCPalette { id: qgcPal; colorGroupEnabled: true }
ScreenTools { id: screenTools }
ParameterEditorController { id: controller }
QGCLabel { id: charWidth; text: "X"; visible: false }
/// true: show full information, false: for use in smaller widgets
property bool fullMode: true
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 rightMargin: 20
readonly property int maxParamChars: 16
readonly property real __leftMargin: 10
readonly property real __rightMargin: 20
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
ExclusiveGroup {
id: exclusiveEditorGroup
id: __exclusiveEditorGroup
}
Column {
anchors.fill:parent
QGCLabel {
text: "PARAMETER EDITOR"
font.pointSize: screenTools.dpiAdjustedPointSize(20)
}
Item {
height: 20
width: 5
}
Row {
spacing: 10
layoutDirection: Qt.RightToLeft
......@@ -69,25 +65,22 @@ Rectangle {
QGCButton {
text: "Clear RC to Param"
onClicked: controller.clearRCToParam()
onClicked: __controller.clearRCToParam()
}
QGCButton {
text: "Save to file"
onClicked: controller.saveToFile()
visible: fullMode
onClicked: __controller.saveToFile()
}
QGCButton {
text: "Load from file"
onClicked: controller.loadFromFile()
visible: fullMode
onClicked: __controller.loadFromFile()
}
QGCButton {
id: firstButton
text: "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."
onClicked: __controller.refresh()
}
}
......@@ -104,7 +97,7 @@ Rectangle {
Column {
Repeater {
model: controller.componentIds
model: __controller.componentIds
Column {
id: componentColumn
......@@ -113,7 +106,7 @@ Rectangle {
QGCLabel {
text: "Component #: " + componentId.toString()
font.pointSize: screenTools.dpiAdjustedPointSize(qgcPal.defaultFontPointSize + 4);
font.pointSize: __screenTools.dpiAdjustedPointSize(__qgcPal.defaultFontPointSize + 4);
}
Item {
......@@ -122,51 +115,51 @@ Rectangle {
}
Repeater {
model: controller.getGroupsForComponent(componentColumn.componentId)
model: __controller.getGroupsForComponent(componentColumn.componentId)
Column {
Rectangle {
id: groupRect
color: qgcPal.windowShade
color: __qgcPal.windowShade
height: groupBlock.height
width: scrollView.viewport.width - rightMargin
width: scrollView.viewport.width - __rightMargin
Column {
id: groupBlock
Rectangle {
color: qgcPal.windowShadeDark
color: __qgcPal.windowShadeDark
height: groupLabel.height
width: groupRect.width
QGCLabel {
id: groupLabel
height: contentHeight + 5
x: leftMargin
x: __leftMargin
text: modelData
verticalAlignment: Text.AlignVCenter
font.pointSize: screenTools.dpiAdjustedPointSize(qgcPal.defaultFontPointSize + 2);
font.pointSize: __screenTools.dpiAdjustedPointSize(__qgcPal.defaultFontPointSize + 2);
}
}
Repeater {
model: controller.getFactsForGroup(componentColumn.componentId, modelData)
model: __controller.getFactsForGroup(componentColumn.componentId, modelData)
Row {
spacing: 10
x: leftMargin
x: __leftMargin
Fact { id: modelFact; name: modelData + ":" + componentColumn.componentId }
QGCLabel {
text: modelFact.name
width: charWidth.contentWidth * (maxParamChars + 2)
width: __charWidth.contentWidth * (__maxParamChars + 2)
}
QGCLabel {
text: modelFact.valueString + " " + modelFact.units
width: charWidth.contentWidth * 20
width: __charWidth.contentWidth * 20
height: contentHeight
MouseArea {
......@@ -178,7 +171,7 @@ Rectangle {
editor.checked = true
editor.focus = true
} else if (mouse.button == Qt.RightButton) {
controller.setRCToParam(modelData)
__controller.setRCToParam(modelData)
}
}
}
......@@ -195,7 +188,7 @@ Rectangle {
// We use an ExclusiveGroup to manage visibility
property bool checked: false
property ExclusiveGroup exclusiveGroup: exclusiveEditorGroup
property ExclusiveGroup exclusiveGroup: __exclusiveEditorGroup
onExclusiveGroupChanged: {
if (exclusiveGroup)
exclusiveGroup.bindCheckable(editor)
......@@ -205,6 +198,7 @@ Rectangle {
QGCLabel {
text: modelFact.shortDescription
visible: fullMode
}
} // Row - Fact value
} // Repeater - Facts
......
......@@ -13,4 +13,6 @@ SubMenuButton 1.0 SubMenuButton.qml
IndicatorButton 1.0 IndicatorButton.qml
VehicleRotationCal 1.0 VehicleRotationCal.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) :
Q_ASSERT(fSucceeded);
qmlRegisterType<FirmwareUpgradeController>("QGroundControl.Controllers", 1, 0, "FirmwareUpgradeController");
qmlRegisterType<ParameterEditorController>("QGroundControl.Controllers", 1, 0, "ParameterEditorController");
_ui->buttonHolder->rootContext()->setContextProperty("controller", this);
_ui->buttonHolder->setAutoPilot(NULL);
......@@ -137,7 +136,7 @@ void SetupView::parametersButtonClicked(void)
Q_ASSERT(_autoPilotPlugin);
setup->setAutoPilot(_autoPilotPlugin);
setup->setSource(QUrl::fromUserInput("qrc:/qml/ParameterEditor.qml"));
setup->setSource(QUrl::fromUserInput("qrc:/qml/SetupParameterEditor.qml"));
_changeSetupWidget(setup);
}
......
......@@ -23,49 +23,15 @@ This file is part of the QGROUNDCONTROL project
/**
* @file
* @brief Definition of class ParameterInterface
*
* @brief Definition of class ParameterEditorWidget
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#ifndef PARAMETERINTERFACE_H
#define PARAMETERINTERFACE_H
#include <QWidget>
#include "ui_ParameterInterface.h"
#include "UASInterface.h"
#include "QGCParamWidget.h"
#include "ParameterEditorWidget.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 @@
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
......@@ -21,65 +21,20 @@ This file is part of the QGROUNDCONTROL project
======================================================================*/
/**
* @file
* @brief Declaration of class QGCSensorSettingsWidget
* @author Lorenz Meier <mail@qgroundcontrol.org>
*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef QGCSENSORSETTINGSWIDGET_H
#define QGCSENSORSETTINGSWIDGET_H
#ifndef PARAMETEREDITORWIDGET_H
#define PARAMETEREDITORWIDGET_H
#include <QWidget>
#include "QGCQmlWidgetHolder.h"
#include "UASInterface.h"
namespace Ui
{
class QGCSensorSettingsWidget;
}
class QGCSensorSettingsWidget : public QWidget
class ParameterEditorWidget : public QGCQmlWidgetHolder
{
Q_OBJECT
public:
QGCSensorSettingsWidget(UASInterface* uas, 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;
public:
ParameterEditorWidget(QWidget *parent = 0);
};
#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"
}
}
}
}
......@@ -21,76 +21,55 @@
======================================================================*/
/// @file
/// @author Thomas Gubler <thomasgubler@gmail.com>
#include "ViewWidgetController.h"
#include "UASManager.h"
#include "AutoPilotPluginManager.h"
#include "QGCParamTreeWidget.h"
#include <QMenu>
#include <QTreeWidgetItem>
#include <QDebug>
QGCParamTreeWidget::QGCParamTreeWidget(QWidget *parent) :
QTreeWidget(parent)
ViewWidgetController::ViewWidgetController(void) :
_autopilot(NULL),
_uas(NULL)
{
setContextMenuPolicy(Qt::CustomContextMenu);
QObject::connect(this, &QGCParamTreeWidget::customContextMenuRequested,
this, &QGCParamTreeWidget::showContextMenu);
qDebug() << "create QGCParamTreeWidget";
_uasManager = UASManager::instance();
Q_ASSERT(_uasManager);
connect(_uasManager, &UASManagerInterface::activeUASSet, this, &ViewWidgetController::_activeUasChanged);
}
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);
void QGCParamTreeWidget::showContextMenu(const QPoint &pos)
{
QMenu menu;
QTreeWidgetItem* item = itemAt(pos);
// Only show context menu for parameter items and not for group items
// (show for TEST_P but not for TEST)
// If a context menu is needed later for the groups then move this 'if'
// 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;
connect(_autopilot, &AutoPilotPlugin::pluginReadyChanged, this, &ViewWidgetController::_pluginReadyChanged);
if (_autopilot->pluginReady()) {
_pluginReadyChanged(true);
}
}
}
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() {
QString action = qobject_cast<QAction*>(
sender())->property("action").toString();
QString param_id = qobject_cast<QAction*>(
sender())->property("param_id").toString();
void ViewWidgetController::_pluginReadyChanged(bool pluginReady)
{
Q_ASSERT(_autopilot);
if (action == "refresh") {
emit refreshParamRequest(param_id);
} else if (action == "maprc") {
emit mapRCToParamRequest(param_id);
if (pluginReady) {
emit pluginConnected(QVariant::fromValue(_autopilot));
} else {
qDebug() << "Undefined context menu action";
_activeUasChanged(NULL);
}
}
Q_INVOKABLE void ViewWidgetController::checkForVehicle(void)
{
_activeUasChanged(_uasManager->getActiveUAS());
}
......@@ -21,31 +21,36 @@
======================================================================*/
/// @file
/// @brief A treeview with context menus for parameters
/// @author Thomas Gubler <thomasgubler@gmail.com>
#ifndef VIEWWIDGETCONTROLLER_H
#define VIEWWIDGETCONTROLLER_H
#ifndef QGCPARAMTREEWIDGET_H
#define QGCPARAMTREEWIDGET_H
#include <QObject>
#include <QTreeWidget>
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
#include "UASManagerInterface.h"
/// Implements individual context menus for the QTreeWidgetItems
class QGCParamTreeWidget : public QTreeWidget
class ViewWidgetController : public QObject
{
Q_OBJECT
public:
QGCParamTreeWidget(QWidget *parent = 0);
~QGCParamTreeWidget();
ViewWidgetController(void);
Q_INVOKABLE void checkForVehicle(void);
signals:
void mapRCToParamRequest(QString param_id);
void refreshParamRequest(QString param_id);
void pluginConnected(QVariant autopilot);
void pluginDisconnected(void);
public slots:
void showContextMenu(const QPoint &pos);
void contextMenuAction();
private slots:
void _activeUasChanged(UASInterface* UAS);
void _pluginReadyChanged(bool pluginReady);
private:
AutoPilotPlugin* _autopilot;
UASManagerInterface* _uasManager;
UASInterface* _uas;
};
#endif // QGCPARAMTREEWIDGET_H
#endif
\ No newline at end of file
......@@ -338,11 +338,6 @@ void MainWindow::resizeEvent(QResizeEvent * event)
QString MainWindow::_getWindowStateKey()
{
if (UASManager::instance()->getActiveUAS())
{
return QString::number(_currentView)+"_windowstate_" + UASManager::instance()->getActiveUAS()->getAutopilotTypeName();
}
else
return QString::number(_currentView)+"_windowstate_";
}
......@@ -372,7 +367,16 @@ void MainWindow::_buildCustomWidgets(void)
void MainWindow::_createDockWidget(const QString& title, const QString& name, Qt::DockWidgetArea area, QWidget* innerWidget)
{
Q_ASSERT(!_mapName2DockWidget.contains(name));
QGCDockWidget* dockWidget = new QGCDockWidget(title, this);
// Add to menu
QAction* action = new QAction(title, NULL);
action->setCheckable(true);
action->setData(name);
connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction);
_ui.menuTools->addAction(action);
// Create widget
QGCDockWidget* dockWidget = new QGCDockWidget(title, action, this);
Q_CHECK_PTR(dockWidget);
dockWidget->setObjectName(name);
dockWidget->setVisible (false);
......@@ -382,12 +386,7 @@ void MainWindow::_createDockWidget(const QString& title, const QString& name, Qt
dockWidget->setWidget(innerWidget);
innerWidget->setVisible(true);
}
// Add to menu
QAction* action = new QAction(title, NULL);
action->setCheckable(true);
action->setData(name);
connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction);
_ui.menuTools->addAction(action);
_mapName2DockWidget[name] = dockWidget;
_mapDockWidget2Action[dockWidget] = action;
addDockWidget(area, dockWidget);
......@@ -421,7 +420,7 @@ void MainWindow::_buildCommonWidgets(void)
{ _uasListDockWidgetName, "Unmanned Systems", Qt::RightDockWidgetArea },
{ _waypointsDockWidgetName, "Mission Plan", Qt::BottomDockWidgetArea },
{ _mavlinkDockWidgetName, "MAVLink Inspector", Qt::RightDockWidgetArea },
{ _parametersDockWidgetName, "Onboard Parameters", Qt::RightDockWidgetArea },
{ _parametersDockWidgetName, "Parameter Editor", Qt::RightDockWidgetArea },
{ _filesDockWidgetName, "Onboard Files", Qt::RightDockWidgetArea },
{ _uasStatusDetailsDockWidgetName, "Status Details", Qt::RightDockWidgetArea },
{ _mapViewDockWidgetName, "Map view", Qt::RightDockWidgetArea },
......@@ -431,7 +430,7 @@ void MainWindow::_buildCommonWidgets(void)
{ _pfdDockWidgetName, "Primary Flight Display", Qt::RightDockWidgetArea },
{ _hudDockWidgetName, "Video Downlink", Qt::RightDockWidgetArea },
{ _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]);
......@@ -550,7 +549,7 @@ void MainWindow::_createInnerDockWidget(const QString& widgetName)
} else if (widgetName == _mavlinkDockWidgetName) {
widget = new QGCMAVLinkInspector(MAVLinkProtocol::instance(),this);
} else if (widgetName == _parametersDockWidgetName) {
widget = new ParameterInterface(this);
widget = new ParameterEditorWidget(this);
} else if (widgetName == _filesDockWidgetName) {
widget = new QGCUASFileViewMulti(this);
} else if (widgetName == _uasStatusDetailsDockWidgetName) {
......@@ -614,7 +613,7 @@ void MainWindow::_showHILConfigurationWidgets(void)
if (!_mapUasId2HilDockWidget.contains(uasId)) {
// 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);
dockWidget->setObjectName(tr("HIL_CONFIG_%1").arg(uasId));
dockWidget->setVisible (false);
......@@ -765,12 +764,11 @@ void MainWindow::storeSettings()
settings.setValue("SHOW_STATUSBAR", _showStatusBar);
settings.endGroup();
settings.setValue(_getWindowGeometryKey(), saveGeometry());
// Save the last current view in any case
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))
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);
settings.setValue(_getWindowStateKey(), saveState());
// And save any custom weidgets
QGCToolWidget::storeWidgetsToSettings(settings);
}
......@@ -877,7 +875,6 @@ void MainWindow::connectCommonActions()
// Connect internal actions
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(UASCreated(UASInterface*)));
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
// Unmanned System controls
connect(_ui.actionLiftoff, SIGNAL(triggered()), UASManager::instance(), SLOT(launchActiveUAS()));
......@@ -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)
{
// The UAS actions are not enabled without connection to system
......@@ -1002,7 +984,6 @@ void MainWindow::UASCreated(UASInterface* uas)
_ui.actionEmergency_Land->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(misconfigurationDetected(UASInterface*)), this, SLOT(handleMisconfiguration(UASInterface*)));
......@@ -1020,15 +1001,6 @@ void MainWindow::UASCreated(UASInterface* uas)
{
_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
......
......@@ -53,7 +53,7 @@ This file is part of the QGROUNDCONTROL project
#include "Mouse6dofInput.h"
#endif // QGC_MOUSE_ENABLED_WIN
#include "DebugConsole.h"
#include "ParameterInterface.h"
#include "ParameterEditorWidget.h"
#include "HDDisplay.h"
#include "HSIDisplay.h"
#include "opmapcontrol.h"
......@@ -132,15 +132,9 @@ public slots:
void showSettings();
/** @brief Simulate a link */
void simulateLink(bool simulate);
/** @brief Set the currently controlled UAS */
void setActiveUAS(UASInterface* uas);
/** @brief Add a new 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);
/** @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