Commit 72b8d9f9 authored by Don Gagne's avatar Don Gagne

Merge pull request #1915 from DonLakeFlyer/TBButtons

New toolbar dropdowns
parents 69d14982 2b206c00
......@@ -201,11 +201,8 @@ FORMS += \
src/ui/uas/UASMessageView.ui \
src/ui/uas/UASQuickView.ui \
src/ui/uas/UASQuickViewItemSelect.ui \
src/ui/UASControl.ui \
src/ui/UASInfo.ui \
src/ui/UASList.ui \
src/ui/UASRawStatusView.ui \
src/ui/UASView.ui \
src/ui/WaypointEditableView.ui \
src/ui/WaypointList.ui \
src/ui/WaypointViewOnlyView.ui \
......@@ -322,16 +319,13 @@ HEADERS += \
src/ui/SettingsDialog.h \
src/ui/toolbar/MainToolBar.h \
src/ui/uas/QGCUnconnectedInfoWidget.h \
src/ui/uas/UASControlWidget.h \
src/ui/uas/UASInfoWidget.h \
src/ui/uas/UASListWidget.h \
src/ui/uas/UASMessageView.h \
src/ui/uas/UASQuickView.h \
src/ui/uas/UASQuickViewGaugeItem.h \
src/ui/uas/UASQuickViewItem.h \
src/ui/uas/UASQuickViewItemSelect.h \
src/ui/uas/UASQuickViewTextItem.h \
src/ui/uas/UASView.h \
src/ui/UASRawStatusView.h \
src/ui/WaypointEditableView.h \
src/ui/WaypointList.h \
......@@ -452,16 +446,13 @@ SOURCES += \
src/ui/SettingsDialog.cc \
src/ui/toolbar/MainToolBar.cc \
src/ui/uas/QGCUnconnectedInfoWidget.cc \
src/ui/uas/UASControlWidget.cc \
src/ui/uas/UASInfoWidget.cc \
src/ui/uas/UASListWidget.cc \
src/ui/uas/UASMessageView.cc \
src/ui/uas/UASQuickView.cc \
src/ui/uas/UASQuickViewGaugeItem.cc \
src/ui/uas/UASQuickViewItem.cc \
src/ui/uas/UASQuickViewItemSelect.cc \
src/ui/uas/UASQuickViewTextItem.cc \
src/ui/uas/UASView.cc \
src/ui/UASRawStatusView.cpp \
src/ui/WaypointEditableView.cc \
src/ui/WaypointList.cc \
......
......@@ -39,7 +39,6 @@ AutoPilotPlugin::AutoPilotPlugin(Vehicle* vehicle, QObject* parent) :
Q_ASSERT(vehicle);
connect(_vehicle->uas(), &UASInterface::disconnected, this, &AutoPilotPlugin::_uasDisconnected);
connect(_vehicle->uas(), &UASInterface::armingChanged, this, &AutoPilotPlugin::armedChanged);
connect(this, &AutoPilotPlugin::pluginReadyChanged, this, &AutoPilotPlugin::_pluginReadyChanged);
}
......@@ -176,8 +175,3 @@ QString AutoPilotPlugin::readParametersFromStream(QTextStream &stream)
{
return _getParameterLoader()->readParametersFromStream(stream);
}
bool AutoPilotPlugin::armed(void)
{
return _vehicle->uas()->isArmed();
}
......@@ -63,8 +63,6 @@ public:
/// false: One or more vehicle components require setup
Q_PROPERTY(bool setupComplete READ setupComplete NOTIFY setupCompleteChanged)
Q_PROPERTY(bool armed READ armed NOTIFY armedChanged)
/// Reset all parameters to their default values
Q_INVOKABLE void resetAllParametersToDefaults(void);
......@@ -117,7 +115,6 @@ public:
// Property accessors
bool pluginReady(void) { return _pluginReady; }
bool setupComplete(void);
bool armed(void);
Vehicle* vehicle(void) { return _vehicle; }
......@@ -125,7 +122,6 @@ signals:
void pluginReadyChanged(bool pluginReady);
void setupCompleteChanged(bool setupComplete);
void parameterListProgress(float value);
void armedChanged(bool armed);
protected:
/// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin
......
......@@ -115,7 +115,6 @@ QUrl SensorsComponent::summaryQmlSource(void) const
{
QString summaryQml;
qDebug() << _uas->getSystemType();
if (_uas->getSystemType() == MAV_TYPE_FIXED_WING ||
_uas->getSystemType() == MAV_TYPE_VTOL_DUOROTOR ||
_uas->getSystemType() == MAV_TYPE_VTOL_QUADROTOR ||
......
......@@ -191,5 +191,5 @@ void PX4FirmwarePlugin::adjustMavlinkMessage(mavlink_message_t* message)
bool PX4FirmwarePlugin::isCapable(FirmwareCapabilities capabilities)
{
return capabilities == MavCmdPreflightStorageCapability;
return capabilities && (MavCmdPreflightStorageCapability | SetFlightModeCapability);
}
......@@ -42,7 +42,7 @@ QGC_LOGGING_CATEGORY(JoystickValuesLog, "JoystickValuesLog")
const char* Joystick::_settingsGroup = "Joysticks";
const char* Joystick::_calibratedSettingsKey = "Calibrated";
const char* Joystick::_buttonActionSettingsKey = "ButtonAction%1";
const char* Joystick::_buttonActionSettingsKey = "ButtonActionName%1";
const char* Joystick::_throttleModeSettingsKey = "ThrottleMode";
const char* Joystick::_rgFunctionSettingsKey[Joystick::maxFunction] = {
......@@ -144,10 +144,8 @@ void Joystick::_loadSettings(void)
}
for (int button=0; button<_cButtons; button++) {
_rgButtonActions[button] = settings.value(QString(_buttonActionSettingsKey).arg(button), -1).toInt(&convertOk);
badSettings |= !convertOk;
qCDebug(JoystickLog) << "_loadSettings button:action:badsettings" << button << _rgButtonActions[button] << badSettings;
_rgButtonActions[button] = settings.value(QString(_buttonActionSettingsKey).arg(button), QString()).toString();
qCDebug(JoystickLog) << "_loadSettings button:action" << button << _rgButtonActions[button];
}
if (badSettings) {
......@@ -322,10 +320,9 @@ void Joystick::run(void)
if (buttonIndex >= reservedButtonCount) {
// Button is above firmware reserved set
int buttonAction =_rgButtonActions[buttonIndex];
if (buttonAction != -1) {
qCDebug(JoystickLog) << "buttonActionTriggered" << buttonAction;
emit buttonActionTriggered(buttonAction);
QString buttonAction =_rgButtonActions[buttonIndex];
if (!buttonAction.isEmpty()) {
_buttonAction(buttonAction);
}
}
}
......@@ -369,7 +366,8 @@ void Joystick::startPolling(Vehicle* vehicle)
UAS* uas = _activeVehicle->uas();
connect(this, &Joystick::manualControl, uas, &UAS::setExternalControlSetpoint);
connect(this, &Joystick::buttonActionTriggered, uas, &UAS::triggerAction);
// FIXME: ****
//connect(this, &Joystick::buttonActionTriggered, uas, &UAS::triggerAction);
_exitThread = false;
start();
......@@ -382,7 +380,8 @@ void Joystick::stopPolling(void)
UAS* uas = _activeVehicle->uas();
disconnect(this, &Joystick::manualControl, uas, &UAS::setExternalControlSetpoint);
disconnect(this, &Joystick::buttonActionTriggered, uas, &UAS::triggerAction);
// FIXME: ****
//disconnect(this, &Joystick::buttonActionTriggered, uas, &UAS::triggerAction);
_exitThread = true;
}
......@@ -435,27 +434,27 @@ int Joystick::getFunctionAxis(AxisFunction_t function)
QStringList Joystick::actions(void)
{
QStringList list;
foreach(QAction* action, MultiVehicleManager::instance()->activeVehicle()->uas()->getActions()) {
list += action->text();
}
list << "Arm" << "Disarm";
return list;
}
void Joystick::setButtonAction(int button, int action)
void Joystick::setButtonAction(int button, const QString& action)
{
if (button < 0 || button > _cButtons) {
qCWarning(JoystickLog) << "Invalid button index" << button;
return;
}
qDebug() << "setButtonAction" << action;
_rgButtonActions[button] = action;
_saveSettings();
emit buttonActionsChanged(buttonActions());
}
int Joystick::getButtonAction(int button)
QString Joystick::getButtonAction(int button)
{
if (button < 0 || button > _cButtons) {
qCWarning(JoystickLog) << "Invalid button index" << button;
......@@ -512,9 +511,6 @@ void Joystick::stopCalibrationMode(CalibrationMode_t mode)
if (mode == CalibrationModeOff) {
qWarning() << "Incorrect mode: CalibrationModeOff";
return;
} else if (mode != _calibrationMode) {
qWarning() << "Incorrect mode sequence request:active" << mode << _calibrationMode;
return;
}
if (mode == CalibrationModeCalibrating) {
......@@ -527,4 +523,15 @@ void Joystick::stopCalibrationMode(CalibrationMode_t mode)
}
}
void Joystick::_buttonAction(const QString& action)
{
if (action == "Arm") {
_activeVehicle->setArmed(true);
} else if (action == "Disarm") {
_activeVehicle->setArmed(false);
} else {
qCDebug(JoystickLog) << "_buttonAction unknown action:" << action;
}
}
#endif // __mobile__
......@@ -73,8 +73,8 @@ public:
Q_PROPERTY(QStringList actions READ actions CONSTANT)
Q_PROPERTY(QVariantList buttonActions READ buttonActions NOTIFY buttonActionsChanged)
Q_INVOKABLE void setButtonAction(int button, int action);
Q_INVOKABLE int getButtonAction(int button);
Q_INVOKABLE void setButtonAction(int button, const QString& action);
Q_INVOKABLE QString getButtonAction(int button);
Q_PROPERTY(int throttleMode READ throttleMode WRITE setThrottleMode NOTIFY throttleModeChanged)
......@@ -135,6 +135,7 @@ private:
void _saveSettings(void);
void _loadSettings(void);
float _adjustRange(int value, Calibration_t calibration);
void _buttonAction(const QString& action);
// Override from QThread
virtual void run(void);
......@@ -158,7 +159,7 @@ private:
static const int _cButtons = 12;
bool _rgButtonValues[_cButtons];
int _rgButtonActions[_cButtons];
QString _rgButtonActions[_cButtons];
quint16 _lastButtonBits;
ThrottleMode_t _throttleMode;
......
......@@ -27,6 +27,7 @@
#include "QmlObjectListModel.h"
#include <QDebug>
#include <QQmlEngine>
const int QmlObjectListModel::ObjectRole = Qt::UserRole;
const int QmlObjectListModel::TextRole = Qt::UserRole + 1;
......@@ -156,6 +157,8 @@ void QmlObjectListModel::insert(int i, QObject* object)
qWarning() << "Invalid index index:count" << i << _objectList.count();
}
QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
_objectList.insert(i, object);
insertRows(i, 1);
}
......
......@@ -58,7 +58,7 @@ public:
/// @return true: continue further processing of this message, false: disregard this message
bool notifyHeartbeatInfo(LinkInterface* link, int vehicleId, mavlink_heartbeat_t& heartbeat);
Vehicle* getVehicleById(int vehicleId);
Q_INVOKABLE Vehicle* getVehicleById(int vehicleId);
void setHomePositionForAllVehicles(double lat, double lon, double alt);
......
This diff is collapsed.
......@@ -35,6 +35,7 @@
#include "QGCMAVLink.h"
#include "MissionItem.h"
#include "QmlObjectListModel.h"
#include "MAVLinkProtocol.h"
class UAS;
class UASInterface;
......@@ -62,6 +63,14 @@ public:
Q_PROPERTY(bool homePositionAvailable READ homePositionAvailable NOTIFY homePositionAvailableChanged)
Q_PROPERTY(QGeoCoordinate homePosition READ homePosition NOTIFY homePositionChanged)
Q_PROPERTY(bool armed READ armed WRITE setArmed NOTIFY armedChanged)
Q_PROPERTY(bool flightModeSetAvailable READ flightModeSetAvailable CONSTANT)
Q_PROPERTY(QStringList flightModes READ flightModes CONSTANT)
Q_PROPERTY(QString flightMode READ flightMode WRITE setFlightMode NOTIFY flightModeChanged)
Q_PROPERTY(bool hilMode READ hilMode WRITE setHilMode NOTIFY hilModeChanged)
Q_INVOKABLE QString getMavIconColor();
//-- System Messages
......@@ -87,8 +96,6 @@ public:
Q_PROPERTY(double batteryVoltage READ batteryVoltage NOTIFY batteryVoltageChanged)
Q_PROPERTY(double batteryPercent READ batteryPercent NOTIFY batteryPercentChanged)
Q_PROPERTY(double batteryConsumed READ batteryConsumed NOTIFY batteryConsumedChanged)
Q_PROPERTY(bool systemArmed READ systemArmed NOTIFY systemArmedChanged)
Q_PROPERTY(QString currentMode READ currentMode NOTIFY currentModeChanged)
Q_PROPERTY(QString systemPixmap READ systemPixmap NOTIFY systemPixmapChanged)
Q_PROPERTY(int satelliteCount READ satelliteCount NOTIFY satelliteCountChanged)
Q_PROPERTY(QString currentState READ currentState NOTIFY currentStateChanged)
......@@ -160,6 +167,17 @@ public:
bool homePositionAvailable(void);
QGeoCoordinate homePosition(void);
bool armed(void) { return _armed; }
void setArmed(bool armed);
bool flightModeSetAvailable(void);
QStringList flightModes(void);
QString flightMode(void);
void setFlightMode(const QString& flightMode);
bool hilMode(void);
void setHilMode(bool hilMode);
typedef enum {
MessageNone,
MessageNormal,
......@@ -206,8 +224,6 @@ public:
double batteryVoltage () { return _batteryVoltage; }
double batteryPercent () { return _batteryPercent; }
double batteryConsumed () { return _batteryConsumed; }
bool systemArmed () { return _systemArmed; }
QString currentMode () { return _currentMode; }
QString systemPixmap () { return _systemPixmap; }
QString currentState () { return _currentState; }
QString systemName () { return _systemName; }
......@@ -229,6 +245,9 @@ signals:
void mavlinkMessageReceived(const mavlink_message_t& message);
void homePositionAvailableChanged(bool homePositionAvailable);
void homePositionChanged(const QGeoCoordinate& homePosition);
void armedChanged(bool armed);
void flightModeChanged(const QString& flightMode);
void hilModeChanged(bool hilMode);
/// Used internally to move sendMessage call to main thread
void _sendMessageOnThread(mavlink_message_t message);
......@@ -251,9 +270,7 @@ signals:
void batteryVoltageChanged ();
void batteryPercentChanged ();
void batteryConsumedChanged ();
void systemArmedChanged ();
void heartbeatTimeoutChanged();
void currentModeChanged ();
void currentConfigChanged ();
void systemPixmapChanged ();
void satelliteCountChanged ();
......@@ -282,9 +299,7 @@ private slots:
void _checkUpdate ();
void _updateBatteryRemaining (UASInterface*, double voltage, double, double percent, int);
void _updateBatteryConsumedChanged (UASInterface*, double current_consumed);
void _updateArmingState (bool armed);
void _updateState (UASInterface* system, QString name, QString description);
void _updateMode (int system, QString name, QString description);
void _updateName (const QString& name);
void _setSystemType (UASInterface* uas, unsigned int systemType);
void _heartbeatTimeout (bool timeout, unsigned int ms);
......@@ -301,7 +316,9 @@ private:
void _loadSettings(void);
void _saveSettings(void);
void _startJoystick(bool start);
void _handleHomePosition(mavlink_message_t& message);
void _handleHeartbeat(mavlink_message_t& message);
bool _isAirplane ();
void _addChange (int id);
float _oneDecimal (float value);
......@@ -313,6 +330,7 @@ private:
MAV_AUTOPILOT _firmwareType;
FirmwarePlugin* _firmwarePlugin;
AutoPilotPlugin* _autopilotPlugin;
MAVLinkProtocol* _mavlink;
/// List of all links associated with this vehicle. We keep SharedLinkInterface objects
/// which are QSharedPointer's in order to maintain reference counts across threads.
......@@ -357,9 +375,7 @@ private:
double _batteryVoltage;
double _batteryPercent;
double _batteryConsumed;
bool _systemArmed;
QString _currentState;
QString _currentMode;
QString _systemName;
QString _systemPixmap;
unsigned int _currentHeartbeatTimeout;
......@@ -373,6 +389,10 @@ private:
MissionManager* _missionManager;
QmlObjectListModel _missionItems;
bool _armed; ///< true: vehicle is armed
uint8_t _base_mode; ///< base_mode from HEARTBEAT
uint32_t _custom_mode; ///< custom_mode from HEARTBEAT
static const char* _settingsGroup;
static const char* _joystickModeSettingsKey;
static const char* _joystickEnabledSettingsKey;
......
......@@ -482,9 +482,9 @@ QGCView {
QGCCheckBox {
anchors.verticalCenter: parent.verticalCenter
checked: _activeJoystick.buttonActions[modelData] != -1
checked: _activeJoystick.buttonActions[modelData] != ""
onClicked: _activeJoystick.setButtonAction(modelData, checked ? buttonActionCombo.currentIndex : -1)
onClicked: _activeJoystick.setButtonAction(modelData, checked ? buttonActionCombo.textAt(buttonActionCombo.currentIndex) : "")
}
Rectangle {
......@@ -509,9 +509,9 @@ QGCView {
id: buttonActionCombo
width: ScreenTools.defaultFontPixelWidth * 20
model: _activeJoystick.actions
currentIndex: _activeJoystick.buttonActions[modelData]
onActivated: _activeJoystick.setButtonAction(modelData, index)
onActivated: _activeJoystick.setButtonAction(modelData, textAt(index))
Component.onCompleted: currentIndex = find(_activeJoystick.buttonActions[modelData])
}
}
} // Repeater
......
......@@ -63,7 +63,7 @@ Rectangle {
function showFirmwarePanel()
{
if (!ScreenTools.isMobile) {
if (multiVehicleManager.activeVehicleAvailable && multiVehicleManager.activeVehicle.autopilot.armed) {
if (multiVehicleManager.activeVehicleAvailable && multiVehicleManager.activeVehicle.armed) {
messagePanelText = armedVehicleText
panelLoader.sourceComponent = messagePanelComponent
} else {
......@@ -74,7 +74,7 @@ Rectangle {
function showJoystickPanel()
{
if (multiVehicleManager.activeVehicleAvailable && multiVehicleManager.activeVehicle.autopilot.armed) {
if (multiVehicleManager.activeVehicleAvailable && multiVehicleManager.activeVehicle.armed) {
messagePanelText = armedVehicleText
panelLoader.sourceComponent = messagePanelComponent
} else {
......@@ -89,7 +89,7 @@ Rectangle {
function showVehicleComponentPanel(vehicleComponent)
{
if (multiVehicleManager.activeVehicle.autopilot.armed) {
if (multiVehicleManager.activeVehicle.armed) {
messagePanelText = armedVehicleText
panelLoader.sourceComponent = messagePanelComponent
} else {
......
......@@ -338,7 +338,6 @@ void MockLink::_handleIncomingMavlinkBytes(const uint8_t* bytes, int cBytes)
break;
default:
qDebug() << "MockLink: Unhandled mavlink message, id:" << msg.msgid;
break;
}
}
......
......@@ -150,13 +150,10 @@ void MavlinkLogTest::_connectLogWorker(bool arm)
QSignalSpy spyVehicle(MultiVehicleManager::instance(), SIGNAL(activeVehicleChanged(Vehicle*)));
QCOMPARE(spyVehicle.wait(5000), true);
UAS* uas = MultiVehicleManager::instance()->activeUas();
QVERIFY(uas);
QDir logSaveDir;
if (arm) {
uas->armSystem();
MultiVehicleManager::instance()->activeVehicle()->setArmed(true);
QTest::qWait(1500); // Wait long enough for heartbeat to come through
// On Disconnect: We should get a getSaveFileName dialog.
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -86,8 +86,6 @@ This file is part of the QGROUNDCONTROL project
/// The key under which the Main Window settings are saved
const char* MAIN_SETTINGS_GROUP = "QGC_MAINWINDOW";
const char* MainWindow::_uasControlDockWidgetName = "UNMANNED_SYSTEM_CONTROL_DOCKWIDGET";
const char* MainWindow::_uasListDockWidgetName = "UNMANNED_SYSTEM_LIST_DOCKWIDGET";
const char* MainWindow::_waypointsDockWidgetName = "WAYPOINT_LIST_DOCKWIDGET";
const char* MainWindow::_mavlinkDockWidgetName = "MAVLINK_INSPECTOR_DOCKWIDGET";
const char* MainWindow::_customCommandWidgetName = "CUSTOM_COMMAND_DOCKWIDGET";
......@@ -388,8 +386,6 @@ void MainWindow::_buildCommonWidgets(void)
};
static const struct DockWidgetInfo rgDockWidgetInfo[] = {
{ _uasControlDockWidgetName, "Control", Qt::LeftDockWidgetArea },
{ _uasListDockWidgetName, "Unmanned Systems", Qt::RightDockWidgetArea },
{ _waypointsDockWidgetName, "Mission Plan", Qt::BottomDockWidgetArea },
{ _mavlinkDockWidgetName, "MAVLink Inspector", Qt::RightDockWidgetArea },
{ _customCommandWidgetName, "Custom Command", Qt::RightDockWidgetArea },
......@@ -487,11 +483,7 @@ void MainWindow::_createInnerDockWidget(const QString& widgetName)
QWidget* widget = NULL;
if (widgetName == _uasControlDockWidgetName) {
widget = new UASControlWidget(this);
} else if (widgetName == _uasListDockWidgetName) {
widget = new UASListWidget(this);
} else if (widgetName == _waypointsDockWidgetName) {
if (widgetName == _waypointsDockWidgetName) {
widget = new QGCWaypointListMulti(this);
} else if (widgetName == _mavlinkDockWidgetName) {
widget = new QGCMAVLinkInspector(MAVLinkProtocol::instance(),this);
......@@ -880,7 +872,7 @@ void MainWindow::_loadCurrentViewState(void)
case VIEW_SIMULATION:
_buildSimView();
centerView = _simView;
defaultWidgets = "UNMANNED_SYSTEM_CONTROL_DOCKWIDGET,WAYPOINT_LIST_DOCKWIDGET,PARAMETER_INTERFACE_DOCKWIDGET,PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET";
defaultWidgets = "WAYPOINT_LIST_DOCKWIDGET,PARAMETER_INTERFACE_DOCKWIDGET,PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET";
break;
default:
......
......@@ -41,11 +41,9 @@ This file is part of the QGROUNDCONTROL project
#include "LinkManager.h"
#include "LinkInterface.h"
#include "UASInterface.h"
#include "UASControlWidget.h"
#include "UASInfoWidget.h"
#include "WaypointList.h"
#include "CameraView.h"
#include "UASListWidget.h"
#if (defined QGC_MOUSE_ENABLED_WIN) | (defined QGC_MOUSE_ENABLED_LINUX)
#include "Mouse6dofInput.h"
#endif // QGC_MOUSE_ENABLED_WIN
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>uasControl</class>
<widget class="QWidget" name="uasControl">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>200</width>
<height>228</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>150</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>267</width>
<height>16777215</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="toolTip">
<string>Control widget to send basic control actions to the micro air vehicle</string>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="5,1,40,1,40,40,40,1000" columnstretch="5,20,20,25,5">
<property name="margin">
<number>4</number>
</property>
<item row="0" column="0" rowspan="7">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>31</width>
<height>159</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1" rowspan="2" colspan="3">
<widget class="QLabel" name="controlStatusLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="toolTip">
<string>Currently controlled system</string>
</property>
<property name="statusTip">
<string>Currently controlled system</string>
</property>
<property name="text">
<string>UNCONNECTED</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="margin">
<number>0</number>
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>216</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="liftoffButton">
<property name="minimumSize">
<size>
<width>25</width>
<height>16</height>
</size>
</property>
<property name="toolTip">
<string>Liftoff / Launch</string>
</property>
<property name="statusTip">
<string>Liftoff / Launch</string>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="landButton">
<property name="minimumSize">
<size>
<width>25</width>
<height>16</height>
</size>
</property>
<property name="toolTip">
<string>Fly straight to landing spot</string>
</property>
<property name="statusTip">
<string>Fly straight to landing spot</string>
</property>
<property name="text">
<string>Land</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="shutdownButton">
<property name="minimumSize">
<size>
<width>25</width>
<height>16</height>
</size>
</property>
<property name="toolTip">
<string>Only active on the ground: Poweroff system</string>
</property>
<property name="statusTip">
<string>Only active on the ground: Poweroff system</string>
</property>
<property name="text">
<string>Halt</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="1" colspan="2">
<widget class="QComboBox" name="modeComboBox">
<property name="minimumSize">
<size>
<width>25</width>
<height>16</height>
</size>
</property>
<property name="toolTip">
<string>Select MAV operation mode</string>
</property>
<property name="statusTip">
<string>Select MAV operation mode</string>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QPushButton" name="setModeButton">
<property name="minimumSize">
<size>
<width>25</width>
<height>16</height>
</size>
</property>
<property name="toolTip">
<string>Transmit and enable mode on MAV</string>
</property>
<property name="statusTip">
<string>Transmit and enable mode on MAV</string>
</property>
<property name="text">
<string>Set</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="3">
<widget class="QLabel" name="lastActionLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="toolTip">
<string>Status label</string>
</property>
<property name="statusTip">
<string>Status label</string>
</property>
<property name="text">
<string>No actions executed so far</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="4" rowspan="6">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>159</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1" colspan="3">
<widget class="QPushButton" name="controlButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>Main control button</string>
</property>
<property name="statusTip">
<string>Main control button</string>
</property>
<property name="text">
<string>Activate Engine</string>
</property>
</widget>
</item>
<item row="7" column="1" colspan="3">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UASList</class>
<widget class="QWidget" name="UASList">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>300</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>3</number>
</property>
</layout>
</widget>
<resources/>
<connections/>
</ui>
This diff is collapsed.
......@@ -13,6 +13,7 @@
#include <QDoubleSpinBox>
#include <QDebug>
#include <QGroupBox>
#include <cmath>
#include <qmath.h>
......
......@@ -279,24 +279,59 @@ Rectangle {
}
Rectangle {
id: mavIcon
width: cellHeight
height: cellHeight
visible: mainToolBar.showMav
QGCButton {
width: ScreenTools.defaultFontPixelWidth * 12
height: cellHeight
visible: mainToolBar.showMav
anchors.verticalCenter: parent.verticalCenter
color: colorBlue
border.color: "#00000000"
border.width: 0
Image {
source: activeVehicle.systemPixmap
height: cellHeight * 0.75
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
text: "Vehicle " + activeVehicle.id
menu: vehicleMenu
Menu {
id: vehicleMenu
}
Component {
id: vehicleMenuItemComponent
MenuItem {
checkable: true
checked: vehicle.active
onTriggered: multiVehicleManager.activeVehicle = vehicle
property int vehicleId: Number(text.split(" ")[1])
property var vehicle: multiVehicleManager.getVehicleById(vehicleId)
}
}
property var vehicleMenuItems: []
function updateVehicleMenu() {
// Remove old menu items
for (var i=0; i<vehicleMenuItems.length; i++) {
vehicleMenu.removeItem(vehicleMenuItems[i])
}
vehicleMenuItems.length = 0
// Add new items
for (var i=0; i<multiVehicleManager.vehicles.count; i++) {
var vehicle = multiVehicleManager.vehicles.get(i)
var menuItem = vehicleMenuItemComponent.createObject(null, { "text": "Vehicle " + vehicle.id })
vehicleMenuItems.push(menuItem)
vehicleMenu.insertItem(i, menuItem)
}
}
Component.onCompleted: updateVehicleMenu()
Connections {
target: multiVehicleManager.vehicles
onCountChanged: parent.updateVehicleMenu
}
}
Rectangle {
id: satelitte
width: getProportionalDimmension(55)
......@@ -478,69 +513,92 @@ Rectangle {
}
}
Column {
height: cellHeight * 0.85
width: getProportionalDimmension(80)
QGCButton {
width: ScreenTools.defaultFontPixelWidth * 11
height: cellHeight
anchors.verticalCenter: parent.verticalCenter
text: activeVehicle.armed ? "Armed" : "Disarmed"
Rectangle {
id: armedStatus
width: parent.width
height: parent.height / 2
anchors.horizontalCenter: parent.horizontalCenter
color: "#00000000"
border.color: "#00000000"
border.width: 0
menu: Menu {
MenuItem {
enabled: !activeVehicle.armed
text: "Arm"
QGCLabel {
id: armedStatusText
text: (activeVehicle.systemArmed) ? qsTr("ARMED") : qsTr("DISARMED")
font.pixelSize: ScreenTools.smallFontPixelSize
font.weight: Font.DemiBold
anchors.centerIn: parent
color: (activeVehicle.systemArmed) ? colorOrangeText : colorGreenText
onTriggered: activeVehicle.armed = true
}
MenuItem {
enabled: activeVehicle.armed
text: "Disarm"
onTriggered: activeVehicle.armed = false
}
}
}
Rectangle {
id: stateStatus
width: parent.width
height: parent.height / 2
anchors.horizontalCenter: parent.horizontalCenter
color: "#00000000"
border.color: "#00000000"
border.width: 0
QGCButton {
width: ScreenTools.defaultFontPixelWidth * 15
height: cellHeight
anchors.verticalCenter: parent.verticalCenter
text: activeVehicle.flightMode
QGCLabel {
id: stateStatusText
text: activeVehicle.currentState
font.pixelSize: ScreenTools.smallFontPixelSize
font.weight: Font.DemiBold
anchors.centerIn: parent
color: (activeVehicle.currentState === "STANDBY") ? colorGreenText : colorRedText
menu: flightModesMenu
Menu {
id: flightModesMenu
}
Component {
id: flightModeMenuItemComponent
MenuItem {
checkable: true
checked: activeVehicle.flightMode == text
onTriggered: activeVehicle.flightMode = text
}
}
property var flightModesMenuItems: []
function updateFlightModesMenu() {
// Remove old menu items
for (var i=0; i<flightModesMenuItems.length; i++) {
flightModesMenu.removeItem(flightModesMenuItems[i])
}
flightModesMenuItems.length = 0
// Add new items
for (var i=0; i<activeVehicle.flightModes.length; i++) {
var menuItem = flightModeMenuItemComponent.createObject(null, { "text": activeVehicle.flightModes[i] })
flightModesMenuItems.push(menuItem)
flightModesMenu.insertItem(i, menuItem)
}
}
Component.onCompleted: updateFlightModesMenu()
Connections {
target: multiVehicleManager
onActiveVehicleChanged: parent.updateFlightModesMenu
}
}
Rectangle {
id: modeStatus
width: getProportionalDimmension(90)
height: cellHeight
color: "#00000000"
border.color: "#00000000"
border.width: 0
width: ScreenTools.defaultFontPixelWidth * 4
height: cellHeight
anchors.verticalCenter: parent.verticalCenter
color: colorBlue
border.width: 0
visible: activeVehicle.hilMode
QGCLabel {
id: modeStatusText
text: activeVehicle.currentMode
font.pixelSize: ScreenTools.smallFontPixelSize
font.weight: Font.DemiBold
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: colorWhiteText
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: "HIL"
}
}
} // Row
} // Component - activeVehicleComponent
......
/*=====================================================================
PIXHAWK Micro Air Vehicle Flying Robotics Toolkit
(c) 2009, 2010 PIXHAWK PROJECT <http://pixhawk.ethz.ch>
This file is part of the PIXHAWK project
PIXHAWK 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.
PIXHAWK 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 PIXHAWK. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Definition of widget controlling one MAV
*
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#include <QString>
#include <QTimer>
#include <QLabel>
#include <QProcess>
#include <QPalette>
#include "UASControlWidget.h"
#include "MultiVehicleManager.h"
#include "UAS.h"
#include "QGC.h"
#include "AutoPilotPluginManager.h"
#include "FirmwarePluginManager.h"
UASControlWidget::UASControlWidget(QWidget *parent) : QWidget(parent),
_uas(NULL),
armed(false)
{
ui.setupUi(this);
_activeVehicleChanged(MultiVehicleManager::instance()->activeVehicle());
connect(MultiVehicleManager::instance(), &MultiVehicleManager::activeVehicleChanged, this, &UASControlWidget::_activeVehicleChanged);
connect(ui.setModeButton, SIGNAL(clicked()), this, SLOT(transmitMode()));
ui.liftoffButton->hide();
ui.landButton->hide();
ui.shutdownButton->hide();
ui.gridLayout->setAlignment(Qt::AlignTop);
}
void UASControlWidget::updateModesList()
{
if (!_uas) {
return;
}
_modeList = FirmwarePluginManager::instance()->firmwarePluginForAutopilot((MAV_AUTOPILOT)_uas->getAutopilotType())->flightModes();
// Set combobox items
ui.modeComboBox->clear();
foreach (QString flightMode, _modeList) {
ui.modeComboBox->addItem(flightMode);
}
// Select first mode in list
ui.modeComboBox->setCurrentIndex(0);
ui.modeComboBox->update();
}
void UASControlWidget::_activeVehicleChanged(Vehicle* vehicle)
{
if (_uas) {
disconnect(ui.controlButton, SIGNAL(clicked()), _uas, SLOT(armSystem()));
disconnect(ui.liftoffButton, SIGNAL(clicked()), _uas, SLOT(launch()));
disconnect(ui.landButton, SIGNAL(clicked()), _uas, SLOT(home()));
disconnect(ui.shutdownButton, SIGNAL(clicked()), _uas, SLOT(shutdown()));
disconnect(_uas, SIGNAL(statusChanged(int)), this, SLOT(updateState(int)));
_uas = NULL;
}
// Connect user interface controls
if (vehicle) {
_uas = vehicle->uas();
connect(ui.controlButton, SIGNAL(clicked()), this, SLOT(cycleContextButton()));
connect(ui.liftoffButton, SIGNAL(clicked()), _uas, SLOT(launch()));
connect(ui.landButton, SIGNAL(clicked()), _uas, SLOT(home()));
connect(ui.shutdownButton, SIGNAL(clicked()), _uas, SLOT(shutdown()));
connect(_uas, SIGNAL(statusChanged(int)), this, SLOT(updateState(int)));
ui.controlStatusLabel->setText(tr("Connected to ") + _uas->getUASName());
setBackgroundColor(_uas->getColor());
this->updateModesList();
this->updateArmText();
}
}
UASControlWidget::~UASControlWidget()
{
}
void UASControlWidget::updateArmText()
{
if (armed) {
ui.controlButton->setText(tr("DISARM SYSTEM"));
} else {
ui.controlButton->setText(tr("ARM SYSTEM"));
}
}
/**
* Set the background color based on the MAV color. If the MAV is selected as the
* currently actively controlled system, the frame color is highlighted
*/
void UASControlWidget::setBackgroundColor(QColor color)
{
// UAS color
QColor uasColor = color;
QString colorstyle;
QString borderColor = "#4A4A4F";
borderColor = "#FA4A4F";
uasColor = uasColor.darker(400);
colorstyle = colorstyle.sprintf("QLabel { border-radius: 3px; padding: 0px; margin: 0px; background-color: #%02X%02X%02X; border: 0px solid %s; }",
uasColor.red(), uasColor.green(), uasColor.blue(), borderColor.toStdString().c_str());
setStyleSheet(colorstyle);
QPalette palette = this->palette();
palette.setBrush(QPalette::Window, QBrush(uasColor));
setPalette(palette);
setAutoFillBackground(true);
}
void UASControlWidget::updateState(int state)
{
switch (state) {
case (int)MAV_STATE_ACTIVE:
armed = true;
break;
case (int)MAV_STATE_STANDBY:
armed = false;
break;
}
this->updateArmText();
}
void UASControlWidget::transmitMode()
{
if (_uas) {
uint8_t base_mode;
uint32_t custom_mode;
QString flightMode = ui.modeComboBox->itemText(ui.modeComboBox->currentIndex());
if (FirmwarePluginManager::instance()->firmwarePluginForAutopilot((MAV_AUTOPILOT)_uas->getAutopilotType())->setFlightMode(flightMode, &base_mode, &custom_mode)) {
if (armed) {
base_mode |= MAV_MODE_FLAG_SAFETY_ARMED;
}
if (_uas->isHilEnabled() || _uas->isHilActive()) {
base_mode |= MAV_MODE_FLAG_HIL_ENABLED;
}
_uas->setMode(base_mode, custom_mode);
QString modeText = ui.modeComboBox->currentText();
ui.lastActionLabel->setText(QString("Sent new mode %1 to %2").arg(flightMode).arg(_uas->getUASName()));
}
}
}
void UASControlWidget::cycleContextButton()
{
if (_uas) {
if (!armed) {
_uas->armSystem();
ui.lastActionLabel->setText(QString("Arm %1").arg(_uas->getUASName()));
} else {
_uas->disarmSystem();
ui.lastActionLabel->setText(QString("Disarm %1").arg(_uas->getUASName()));
}
}
}
/*=====================================================================
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 UASControlWidget
*
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#ifndef _UASCONTROLWIDGET_H_
#define _UASCONTROLWIDGET_H_
#include <QWidget>
#include <QLineEdit>
#include <QString>
#include <QPushButton>
#include "ui_UASControl.h"
#include "UASInterface.h"
#include "Vehicle.h"
/**
* @brief Widget controlling one MAV
*/
class UASControlWidget : public QWidget
{
Q_OBJECT
public:
UASControlWidget(QWidget *parent = 0);
~UASControlWidget();
public slots:
/** @brief Update modes list for selected system */
void updateModesList();
/** @brief Trigger next context action */
void cycleContextButton();
/** @brief Transmit the operation mode */
void transmitMode();
/** @brief Update state */
void updateState(int state);
/** @brief Update internal state machine */
void updateArmText();
protected slots:
/** @brief Set the background color for the widget */
void setBackgroundColor(QColor color);
protected:
UAS* _uas;
QStringList _modeList; ///< Mode list for the current UAS
bool armed; ///< Engine state
private slots:
void _activeVehicleChanged(Vehicle* vehicle);
private:
Ui::uasControl ui;
};
#endif // _UASCONTROLWIDGET_H_
......@@ -74,10 +74,7 @@ public slots:
void setVoltage(UASInterface* uas, double voltage);
void setChargeLevel(UASInterface* uas, double chargeLevel);
void setTimeRemaining(UASInterface* uas, double seconds);
// void setBattery(int uasid, BatteryType type, int cells);
// void valueChanged(int uasid, QString key, double value,quint64 time);
// void actuatorChanged(UASInterface* uas, int actId, double value);
void refresh();
protected:
......
/*=====================================================================
PIXHAWK Micro Air Vehicle Flying Robotics Toolkit
(c) 2009, 2010 PIXHAWK PROJECT <http://pixhawk.ethz.ch>
This file is part of the PIXHAWK project
PIXHAWK 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.
PIXHAWK 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 PIXHAWK. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief List of unmanned vehicles
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#include <QString>
#include <QTimer>
#include <QLabel>
#include <QDebug>
#include <QApplication>
#include "MG.h"
#include "UASListWidget.h"
#include "MultiVehicleManager.h"
#include "UAS.h"
#include "UASView.h"
#include "QGCUnconnectedInfoWidget.h"
#include "MainWindow.h"
#include "LinkManager.h"
UASListWidget::UASListWidget(QWidget *parent) : QWidget(parent),
uWidget(NULL),
m_ui(new Ui::UASList)
{
// Use a timer to update the link health display.
updateTimer = new QTimer(this);
connect(updateTimer,SIGNAL(timeout()),this,SLOT(updateStatus()));
m_ui->setupUi(this);
m_ui->verticalLayout->setAlignment(Qt::AlignTop);
this->setMinimumWidth(262);
linkToBoxMapping = QMap<LinkInterface*, QGroupBox*>();
uasToBoxMapping = QMap<UASInterface*, QGroupBox*>();
uasViews = QMap<UASInterface*, UASView*>();
this->setVisible(false);
connect(LinkManager::instance(), SIGNAL(linkDeleted(LinkInterface*)), this, SLOT(removeLink(LinkInterface*)));
connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleAdded, this, &UASListWidget::_vehicleAdded);
connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleRemoved, this, &UASListWidget::_vehicleRemoved);
// Get a list of all existing UAS
foreach (Vehicle* vehicle, MultiVehicleManager::instance()->vehicles())
{
_vehicleAdded(vehicle);
}
}
UASListWidget::~UASListWidget()
{
delete m_ui;
}
void UASListWidget::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
switch (e->type())
{
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
default:
break;
}
}
// XXX This is just to prevent
// upfront crashes, will probably need further inspection
void UASListWidget::removeLink(LinkInterface* link)
{
QGroupBox* box = linkToBoxMapping.value(link, NULL);
if (box) {
// Just stop updating the status for now - we should
// remove the UAS probably
linkToBoxMapping.remove(link);
}
}
void UASListWidget::updateStatus()
{
QMapIterator<LinkInterface*, QGroupBox*> i(linkToBoxMapping);
while (i.hasNext()) {
i.next();
LinkInterface* link = i.key();
// Paranoid sanity check
if (!LinkManager::instance()->containsLink(link))
continue;
if (!link)
continue;
MAVLinkProtocol* mavlink = MAVLinkProtocol::instance();
// Build the tooltip out of the protocol parsing data: received, dropped, and parsing errors.
QString displayString("");
int c;
if ((c = mavlink->getReceivedPacketCount(link)) != -1)
{
displayString += QString(tr("<br/>Received: %2")).arg(QString::number(c));
}
if ((c = mavlink->getDroppedPacketCount(link)) != -1)
{
displayString += QString(tr("<br/>Dropped: %2")).arg(QString::number(c));
}
if ((c = mavlink->getParsingErrorCount(link)) != -1)
{
displayString += QString(tr("<br/>Errors: %2")).arg(QString::number(c));
}
if (!displayString.isEmpty())
{
displayString = QString("<b>%1</b>").arg(i.key()->getName()) + displayString;
}
// qDebug() << p << ": " + displayString;
i.value()->setToolTip(displayString);
}
}
void UASListWidget::_vehicleAdded(Vehicle* vehicle)
{
UAS* uas = vehicle->uas();
// If the list was empty, remove the unconnected widget and start the update timer.
if (uasViews.isEmpty())
{
updateTimer->start(5000);
if (uWidget)
{
m_ui->verticalLayout->removeWidget(uWidget);
delete uWidget;
uWidget = NULL;
}
}
if (!uasViews.contains(uas))
{
// Only display the UAS in a single link.
QList<LinkInterface*> x = vehicle->links();
if (x.size())
{
LinkInterface* li = x.first();
// Find an existing QGroupBox for this LinkInterface or create a
// new one.
QGroupBox* newBox;
if (linkToBoxMapping.contains(li))
{
newBox = linkToBoxMapping[li];
}
else
{
newBox = new QGroupBox(li->getName(), this);
QVBoxLayout* boxLayout = new QVBoxLayout(newBox);
newBox->setLayout(boxLayout);
m_ui->verticalLayout->addWidget(newBox);
linkToBoxMapping[li] = newBox;
updateStatus(); // Update the link status for this GroupBox.
}
// And add the new UAS to the UASList
UASView* newView = new UASView(vehicle, newBox);
uasViews.insert(uas, newView);
uasToBoxMapping[uas] = newBox;
newBox->layout()->addWidget(newView);
}
}
UASView* view = uasViews.value(uas, NULL);
if (view) {
view->setUASasActive(true);
}
}
/**
* If the UAS was removed, check to see if it was the last one in the QGroupBox and delete
* the QGroupBox if so.
*/
void UASListWidget::_vehicleRemoved(Vehicle* vehicle)
{
UAS* uas = vehicle->uas();
// Remove the UASView and check if its parent GroupBox has any other children,
// delete it if it doesn't.
QGroupBox* box = uasToBoxMapping[uas];
uasToBoxMapping.remove(uas);
uasViews.remove(uas);
int otherViews = 0;
foreach (UASView* view, box->findChildren<UASView*>())
{
if (view->uas == uas)
{
view->deleteLater();
}
else
{
++otherViews;
}
}
if (otherViews == 0)
{
// Delete the groupbox.
QMap<LinkInterface*, QGroupBox*>::const_iterator i = linkToBoxMapping.constBegin();
while (i != linkToBoxMapping.constEnd()) {
if (i.value() == box)
{
linkToBoxMapping.remove(i.key());
break;
}
++i;
}
box->deleteLater();
// And if no other QGroupBoxes are left, put the initial widget back.
// We also stop the update timer as there's nothing to update at this point.
int otherBoxes = 0;
foreach (const QGroupBox* otherBox, findChildren<QGroupBox*>())
{
if (otherBox != box)
{
++otherBoxes;
}
}
if (otherBoxes == 0)
{
uWidget = new QGCUnconnectedInfoWidget(this);
m_ui->verticalLayout->addWidget(uWidget);
updateTimer->stop();
}
}
}
/*=====================================================================
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 List of unmanned vehicles
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#ifndef _UASLISTWIDGET_H_
#define _UASLISTWIDGET_H_
#include <QWidget>
#include <QMap>
#include <QList>
#include <QVBoxLayout>
#include <QGroupBox>
#include "UASInterface.h"
#include "UASView.h"
#include "QGCUnconnectedInfoWidget.h"
#include "ui_UASList.h"
#include "Vehicle.h"
class UASListWidget : public QWidget
{
Q_OBJECT
public:
UASListWidget(QWidget *parent = 0);
~UASListWidget();
public slots:
void removeLink(LinkInterface* link);
protected:
// Keep a mapping from UASes to their GroupBox. Useful for determining when groupboxes are empty.
QMap<UASInterface*, QGroupBox*> uasToBoxMapping;
// Keep a mapping from Links to GroupBoxes for adding new links.
QMap<LinkInterface*, QGroupBox*> linkToBoxMapping;
// Tie each view to their UAS object so they can be removed easily.
QMap<UASInterface*, UASView*> uasViews;
QGCUnconnectedInfoWidget* uWidget;
QTimer* updateTimer;
void changeEvent(QEvent *e);
private slots:
void _vehicleAdded(Vehicle* vehicle);
void _vehicleRemoved(Vehicle* vehicle);
private:
Ui::UASList* m_ui;
private slots:
void updateStatus();
};
#endif // _UASLISTWIDGET_H_
This diff is collapsed.
This diff is collapsed.
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