Commit 3b5740bc authored by Pritam Ghanghas's avatar Pritam Ghanghas

Merge branch 'master' of https://github.com/mavlink/qgroundcontrol into apm_mode_support

parents 3a3a8afc 3ba9c2f8
...@@ -21,23 +21,25 @@ test_script: ...@@ -21,23 +21,25 @@ test_script:
- if "%CONFIG%" EQU "debug" ( debug\qgroundcontrol --unittest ) - if "%CONFIG%" EQU "debug" ( debug\qgroundcontrol --unittest )
after_build: after_build:
- if "%CONFIG%" EQU "installer" ( appveyor PushArtifact C:\projects\qgroundcontrol\release\qgroundcontrol-installer-win32.exe ) - if "%CONFIG%" EQU "installer" ( appveyor PushArtifact C:\projects\qgroundcontrol\release\qgroundcontrol.exe )
deploy: deploy:
- provider: S3 - provider: S3
name: qgroundcontrol-s3 name: qgroundcontrol-s3
access_key_id: AKIAIVORNALE7NHD3T6Q access_key_id:
secure: IGAojLMqokL+76DbdulmWDA3MTsxEBBi3ReVVSqTy9c=
secret_access_key: secret_access_key:
secure: RiYqaR+3T2PMNz2j5ur8LCA6H/Zfd4jTX33CZE5iBxm+zaz4QLs25p0B7prpaoNN secure: RiYqaR+3T2PMNz2j5ur8LCA6H/Zfd4jTX33CZE5iBxm+zaz4QLs25p0B7prpaoNN
bucket: qgrondcontrol bucket: qgroundcontrol
set_public: true set_public: true
folder: "%APPVEYOR_REPO_BRANCH%" folder: $(APPVEYOR_REPO_BRANCH)
artifact: C:\projects\qgroundcontrol\release\qgroundcontrol-installer-win32.exe artifcat: 'release\qgroundcontrol.exe'
on:
CONFIG: installer
- provider: GitHub - provider: GitHub
artifact: C:\projects\qgroundcontrol\release\qgroundcontrol-installer-win32.exe artifact: 'release\qgroundcontrol.exe'
draft: false draft: false
prerelease: false prerelease: false
on: on:
CONFIG: installer
appveyor_repo_tag: true appveyor_repo_tag: true
\ No newline at end of file
...@@ -162,12 +162,10 @@ INCLUDEPATH += \ ...@@ -162,12 +162,10 @@ INCLUDEPATH += \
FORMS += \ FORMS += \
src/QGCQmlWidgetHolder.ui \ src/QGCQmlWidgetHolder.ui \
src/ui/Linechart.ui \
src/ui/LogReplayLinkConfigurationWidget.ui \ src/ui/LogReplayLinkConfigurationWidget.ui \
src/ui/MainWindow.ui \ src/ui/MainWindow.ui \
src/ui/MAVLinkSettingsWidget.ui \ src/ui/MAVLinkSettingsWidget.ui \
src/ui/QGCCommConfiguration.ui \ src/ui/QGCCommConfiguration.ui \
src/ui/QGCDataPlot2D.ui \
src/ui/QGCLinkConfiguration.ui \ src/ui/QGCLinkConfiguration.ui \
src/ui/QGCMapRCToParamDialog.ui \ src/ui/QGCMapRCToParamDialog.ui \
src/ui/QGCMAVLinkLogPlayer.ui \ src/ui/QGCMAVLinkLogPlayer.ui \
...@@ -185,7 +183,9 @@ FORMS += \ ...@@ -185,7 +183,9 @@ FORMS += \
!MobileBuild { !MobileBuild {
FORMS += \ FORMS += \
src/ui/Linechart.ui \
src/ui/MultiVehicleDockWidget.ui \ src/ui/MultiVehicleDockWidget.ui \
src/ui/QGCDataPlot2D.ui \
src/ui/QGCHilConfiguration.ui \ src/ui/QGCHilConfiguration.ui \
src/ui/QGCHilFlightGearConfiguration.ui \ src/ui/QGCHilFlightGearConfiguration.ui \
src/ui/QGCHilJSBSimConfiguration.ui \ src/ui/QGCHilJSBSimConfiguration.ui \
...@@ -230,6 +230,7 @@ HEADERS += \ ...@@ -230,6 +230,7 @@ HEADERS += \
src/QGCApplication.h \ src/QGCApplication.h \
src/QGCComboBox.h \ src/QGCComboBox.h \
src/QGCConfig.h \ src/QGCConfig.h \
src/QGCDockWidget.h \
src/QGCFileDialog.h \ src/QGCFileDialog.h \
src/QGCGeo.h \ src/QGCGeo.h \
src/QGCLoggingCategory.h \ src/QGCLoggingCategory.h \
...@@ -251,19 +252,11 @@ HEADERS += \ ...@@ -251,19 +252,11 @@ HEADERS += \
src/uas/UAS.h \ src/uas/UAS.h \
src/uas/UASInterface.h \ src/uas/UASInterface.h \
src/uas/UASMessageHandler.h \ src/uas/UASMessageHandler.h \
src/ui/linechart/ChartPlot.h \
src/ui/linechart/IncrementalPlot.h \
src/ui/linechart/LinechartPlot.h \
src/ui/linechart/Linecharts.h \
src/ui/linechart/LinechartWidget.h \
src/ui/linechart/Scrollbar.h \
src/ui/linechart/ScrollZoomer.h \
src/ui/LogReplayLinkConfigurationWidget.h \ src/ui/LogReplayLinkConfigurationWidget.h \
src/ui/MainWindow.h \ src/ui/MainWindow.h \
src/ui/MAVLinkDecoder.h \ src/ui/MAVLinkDecoder.h \
src/ui/MAVLinkSettingsWidget.h \ src/ui/MAVLinkSettingsWidget.h \
src/ui/QGCCommConfiguration.h \ src/ui/QGCCommConfiguration.h \
src/ui/QGCDataPlot2D.h \
src/ui/QGCLinkConfiguration.h \ src/ui/QGCLinkConfiguration.h \
src/ui/QGCMapRCToParamDialog.h \ src/ui/QGCMapRCToParamDialog.h \
src/ui/QGCMAVLinkLogPlayer.h \ src/ui/QGCMAVLinkLogPlayer.h \
...@@ -289,10 +282,17 @@ HEADERS += \ ...@@ -289,10 +282,17 @@ HEADERS += \
src/comm/QGCHilLink.h \ src/comm/QGCHilLink.h \
src/comm/QGCJSBSimLink.h \ src/comm/QGCJSBSimLink.h \
src/comm/QGCXPlaneLink.h \ src/comm/QGCXPlaneLink.h \
src/QGCDockWidget.h \
src/ui/CameraView.h \ src/ui/CameraView.h \
src/ui/HILDockWidget.h \ src/ui/HILDockWidget.h \
src/ui/linechart/ChartPlot.h \
src/ui/linechart/IncrementalPlot.h \
src/ui/linechart/LinechartPlot.h \
src/ui/linechart/Linecharts.h \
src/ui/linechart/LinechartWidget.h \
src/ui/linechart/Scrollbar.h \
src/ui/linechart/ScrollZoomer.h \
src/ui/MultiVehicleDockWidget.h \ src/ui/MultiVehicleDockWidget.h \
src/ui/QGCDataPlot2D.h \
src/ui/QGCHilConfiguration.h \ src/ui/QGCHilConfiguration.h \
src/ui/QGCHilFlightGearConfiguration.h \ src/ui/QGCHilFlightGearConfiguration.h \
src/ui/QGCHilJSBSimConfiguration.h \ src/ui/QGCHilJSBSimConfiguration.h \
...@@ -340,6 +340,7 @@ SOURCES += \ ...@@ -340,6 +340,7 @@ SOURCES += \
src/QGC.cc \ src/QGC.cc \
src/QGCApplication.cc \ src/QGCApplication.cc \
src/QGCComboBox.cc \ src/QGCComboBox.cc \
src/QGCDockWidget.cc \
src/QGCFileDialog.cc \ src/QGCFileDialog.cc \
src/QGCLoggingCategory.cc \ src/QGCLoggingCategory.cc \
src/QGCPalette.cc \ src/QGCPalette.cc \
...@@ -356,19 +357,11 @@ SOURCES += \ ...@@ -356,19 +357,11 @@ SOURCES += \
src/uas/FileManager.cc \ src/uas/FileManager.cc \
src/uas/UAS.cc \ src/uas/UAS.cc \
src/uas/UASMessageHandler.cc \ src/uas/UASMessageHandler.cc \
src/ui/linechart/ChartPlot.cc \
src/ui/linechart/IncrementalPlot.cc \
src/ui/linechart/LinechartPlot.cc \
src/ui/linechart/Linecharts.cc \
src/ui/linechart/LinechartWidget.cc \
src/ui/linechart/Scrollbar.cc \
src/ui/linechart/ScrollZoomer.cc \
src/ui/LogReplayLinkConfigurationWidget.cc \ src/ui/LogReplayLinkConfigurationWidget.cc \
src/ui/MainWindow.cc \ src/ui/MainWindow.cc \
src/ui/MAVLinkDecoder.cc \ src/ui/MAVLinkDecoder.cc \
src/ui/MAVLinkSettingsWidget.cc \ src/ui/MAVLinkSettingsWidget.cc \
src/ui/QGCCommConfiguration.cc \ src/ui/QGCCommConfiguration.cc \
src/ui/QGCDataPlot2D.cc \
src/ui/QGCLinkConfiguration.cc \ src/ui/QGCLinkConfiguration.cc \
src/ui/QGCMapRCToParamDialog.cpp \ src/ui/QGCMapRCToParamDialog.cpp \
src/ui/QGCMAVLinkLogPlayer.cc \ src/ui/QGCMAVLinkLogPlayer.cc \
...@@ -393,10 +386,17 @@ SOURCES += \ ...@@ -393,10 +386,17 @@ SOURCES += \
src/comm/QGCFlightGearLink.cc \ src/comm/QGCFlightGearLink.cc \
src/comm/QGCJSBSimLink.cc \ src/comm/QGCJSBSimLink.cc \
src/comm/QGCXPlaneLink.cc \ src/comm/QGCXPlaneLink.cc \
src/QGCDockWidget.cc \
src/ui/CameraView.cc \ src/ui/CameraView.cc \
src/ui/HILDockWidget.cc \ src/ui/HILDockWidget.cc \
src/ui/linechart/ChartPlot.cc \
src/ui/linechart/IncrementalPlot.cc \
src/ui/linechart/LinechartPlot.cc \
src/ui/linechart/Linecharts.cc \
src/ui/linechart/LinechartWidget.cc \
src/ui/linechart/Scrollbar.cc \
src/ui/linechart/ScrollZoomer.cc \
src/ui/MultiVehicleDockWidget.cc \ src/ui/MultiVehicleDockWidget.cc \
src/ui/QGCDataPlot2D.cc \
src/ui/QGCHilConfiguration.cc \ src/ui/QGCHilConfiguration.cc \
src/ui/QGCHilFlightGearConfiguration.cc \ src/ui/QGCHilFlightGearConfiguration.cc \
src/ui/QGCHilJSBSimConfiguration.cc \ src/ui/QGCHilJSBSimConfiguration.cc \
......
...@@ -46,7 +46,7 @@ installer { ...@@ -46,7 +46,7 @@ installer {
# easier to debug user crashes. # easier to debug user crashes.
#QMAKE_POST_LINK += $$escape_expand(\\n) $$QMAKE_COPY $${DESTDIR_WIN}\\qgroundcontrol.pdb #QMAKE_POST_LINK += $$escape_expand(\\n) $$QMAKE_COPY $${DESTDIR_WIN}\\qgroundcontrol.pdb
#QMAKE_POST_LINK += $$escape_expand(\\n) del $${DESTDIR_WIN}\\qgroundcontrol.pdb #QMAKE_POST_LINK += $$escape_expand(\\n) del $${DESTDIR_WIN}\\qgroundcontrol.pdb
QMAKE_POST_LINK += $$escape_expand(\\n) $$quote("\"C:\\Program Files \(x86\)\\NSIS\\makensis.exe\"" /NOCD "\"/XOutFile $${DESTDIR_WIN}\\qgroundcontrol-installer-win32.exe\"" "$$BASEDIR_WIN\\deploy\\qgroundcontrol_installer.nsi") QMAKE_POST_LINK += $$escape_expand(\\n) $$quote("\"C:\\Program Files \(x86\)\\NSIS\\makensis.exe\"" /NOCD "\"/XOutFile $${DESTDIR_WIN}\\qgroundcontrol.exe\"" "$$BASEDIR_WIN\\deploy\\qgroundcontrol_installer.nsi")
#QMAKE_POST_LINK += $$escape_expand(\\n) $$QMAKE_COPY qgroundcontrol.pdb $${DESTDIR_WIN} #QMAKE_POST_LINK += $$escape_expand(\\n) $$QMAKE_COPY qgroundcontrol.pdb $${DESTDIR_WIN}
#QMAKE_POST_LINK += $$escape_expand(\\n) del qgroundcontrol.pdb #QMAKE_POST_LINK += $$escape_expand(\\n) del qgroundcontrol.pdb
OTHER_FILES += deploy/qgroundcontrol_installer.nsi OTHER_FILES += deploy/qgroundcontrol_installer.nsi
......
...@@ -63,7 +63,7 @@ Supported builds are 64 bit, built using the clang compiler. ...@@ -63,7 +63,7 @@ Supported builds are 64 bit, built using the clang compiler.
Supported builds for Linux are 32 or 64-bit, built using gcc. Supported builds for Linux are 32 or 64-bit, built using gcc.
#### Install Qt5.4 and SDL1.2 prerequistites #### Install Qt5.4 and SDL1.2 prerequistites
* For Fedora: `sudo yum install qt-creator qt5-qtbase-devel qt5-qtdeclarative-devel qt5-qtserialport-devel qt5-qtsvg-devel qt5-qtwebkit-devel SDL-devel SDL-static systemd-devel qt5-qtgraphicaleffects qt5-qtquickcontrols` * For Fedora: `sudo yum install qt-creator qt5-qtbase-devel qt5-qtdeclarative-devel qt5-qtserialport-devel qt5-qtsvg-devel qt5-qtwebkit-devel SDL-devel SDL-static systemd-devel qt5-qtgraphicaleffects qt5-qtquickcontrols qt5-qtlocation-devel`
* For Arch Linux: `pacman -Sy qtcreator qt5-base qt5-declarative qt5-serialport qt5-svg qt5-webkit` * For Arch Linux: `pacman -Sy qtcreator qt5-base qt5-declarative qt5-serialport qt5-svg qt5-webkit`
* For Ubuntu: Please be aware that the time of writing, Qt5.4 is unavailable in the official repositories Ubuntu 14.04/Mint 17 * For Ubuntu: Please be aware that the time of writing, Qt5.4 is unavailable in the official repositories Ubuntu 14.04/Mint 17
* Add this PPA for Qt5.4: `sudo add-apt-repository ppa:beineri/opt-qt541-trusty` * Add this PPA for Qt5.4: `sudo add-apt-repository ppa:beineri/opt-qt541-trusty`
......
[Desktop Entry]
Type=Application
Name=qgroundcontrol
GenericName=Ground Control Station
Comment=UAS ground control station
Icon=qgroundcontrol
Exec=qgroundcontrol
Terminal=false
Categories=Utility;
Keywords=computer;
...@@ -117,6 +117,7 @@ ...@@ -117,6 +117,7 @@
<file alias="QGroundControl/Controls/DropButton.qml">src/QmlControls/DropButton.qml</file> <file alias="QGroundControl/Controls/DropButton.qml">src/QmlControls/DropButton.qml</file>
<file alias="QGroundControl/Controls/RoundButton.qml">src/QmlControls/RoundButton.qml</file> <file alias="QGroundControl/Controls/RoundButton.qml">src/QmlControls/RoundButton.qml</file>
<file alias="QGroundControl/Controls/QGCCanvas.qml">src/QmlControls/QGCCanvas.qml</file> <file alias="QGroundControl/Controls/QGCCanvas.qml">src/QmlControls/QGCCanvas.qml</file>
<file alias="QGroundControl/Controls/ExclusiveGroupItem.qml">src/QmlControls/ExclusiveGroupItem.qml</file>
<!-- Vehicle Setup --> <!-- Vehicle Setup -->
<file alias="SetupView.qml">src/VehicleSetup/SetupView.qml</file> <file alias="SetupView.qml">src/VehicleSetup/SetupView.qml</file>
......
...@@ -35,7 +35,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -35,7 +35,7 @@ This file is part of the QGROUNDCONTROL project
const char* kMainFlightDisplayViewGroup = "FlightDisplayView"; const char* kMainFlightDisplayViewGroup = "FlightDisplayView";
FlightDisplayView::FlightDisplayView(QWidget *parent) FlightDisplayView::FlightDisplayView(QWidget *parent)
: QGCQmlWidgetHolder(parent) : QGCQmlWidgetHolder(QString(), NULL, parent)
{ {
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setObjectName("FlightDisplayView"); setObjectName("FlightDisplayView");
......
...@@ -34,8 +34,8 @@ This file is part of the QGROUNDCONTROL project ...@@ -34,8 +34,8 @@ This file is part of the QGROUNDCONTROL project
const char* kMainFlightDisplayWidgetGroup = "FlightDisplayWidget"; const char* kMainFlightDisplayWidgetGroup = "FlightDisplayWidget";
FlightDisplayWidget::FlightDisplayWidget(QWidget *parent) FlightDisplayWidget::FlightDisplayWidget(const QString& title, QAction* action, QWidget *parent)
: QGCQmlWidgetHolder(parent) : QGCQmlWidgetHolder(title, action, parent)
{ {
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setObjectName("FlightDisplayWidget"); setObjectName("FlightDisplayWidget");
...@@ -86,6 +86,8 @@ FlightDisplayWidget::FlightDisplayWidget(QWidget *parent) ...@@ -86,6 +86,8 @@ FlightDisplayWidget::FlightDisplayWidget(QWidget *parent)
setSource(QUrl::fromUserInput("qrc:/qml/FlightDisplayWidget.qml")); setSource(QUrl::fromUserInput("qrc:/qml/FlightDisplayWidget.qml"));
setVisible(true); setVisible(true);
loadSettings();
} }
FlightDisplayWidget::~FlightDisplayWidget() FlightDisplayWidget::~FlightDisplayWidget()
......
...@@ -30,7 +30,7 @@ class FlightDisplayWidget : public QGCQmlWidgetHolder ...@@ -30,7 +30,7 @@ class FlightDisplayWidget : public QGCQmlWidgetHolder
{ {
Q_OBJECT Q_OBJECT
public: public:
FlightDisplayWidget(QWidget* parent = NULL); FlightDisplayWidget(const QString& title, QAction* action, QWidget* parent = NULL);
~FlightDisplayWidget(); ~FlightDisplayWidget();
/// @brief Invokes the Flight Display Options menu /// @brief Invokes the Flight Display Options menu
......
...@@ -50,7 +50,7 @@ Map { ...@@ -50,7 +50,7 @@ Map {
property string mapName: 'defaultMap' property string mapName: 'defaultMap'
property string mapType: QGroundControl.flightMapSettings.mapTypeForMapName(mapName) property string mapType: QGroundControl.flightMapSettings.mapTypeForMapName(mapName)
property alias mapWidgets: controlWidgets property alias mapWidgets: controlWidgets
property bool isSatelliteMap: false property bool isSatelliteMap: mapType == "Satellite Map" || mapType == "Hybrid Map"
property real lon: (longitude >= -180 && longitude <= 180) ? longitude : 0 property real lon: (longitude >= -180 && longitude <= 180) ? longitude : 0
property real lat: (latitude >= -90 && latitude <= 90) ? latitude : 0 property real lat: (latitude >= -90 && latitude <= 90) ? latitude : 0
...@@ -289,4 +289,11 @@ Map { ...@@ -289,4 +289,11 @@ Map {
} }
} }
*/ */
MouseArea {
//-- TODO: Check if this is still needed when we switch to 5.5.1
//-- Workaround for QTBUG-46388 (Pinch zoom doesn't work without it on mobile)
anchors.fill: parent
}
} // Map } // Map
...@@ -35,9 +35,11 @@ This file is part of the QGROUNDCONTROL project ...@@ -35,9 +35,11 @@ This file is part of the QGROUNDCONTROL project
const char* MissionEditor::_settingsGroup = "MissionEditor"; const char* MissionEditor::_settingsGroup = "MissionEditor";
MissionEditor::MissionEditor(QWidget *parent) MissionEditor::MissionEditor(QWidget *parent)
: QGCQmlWidgetHolder(parent) : QGCQmlWidgetHolder(QString(), NULL, parent)
, _missionItems(NULL) , _missionItems(NULL)
, _canEdit(true) , _canEdit(true)
, _activeVehicle(NULL)
, _liveHomePositionAvailable(false)
{ {
// Get rid of layout default margins // Get rid of layout default margins
QLayout* pl = layout(); QLayout* pl = layout();
...@@ -45,11 +47,16 @@ MissionEditor::MissionEditor(QWidget *parent) ...@@ -45,11 +47,16 @@ MissionEditor::MissionEditor(QWidget *parent)
pl->setContentsMargins(0,0,0,0); pl->setContentsMargins(0,0,0,0);
} }
Vehicle* activeVehicle = MultiVehicleManager::instance()->activeVehicle(); MultiVehicleManager* multiVehicleMgr = MultiVehicleManager::instance();
connect(multiVehicleMgr, &MultiVehicleManager::activeVehicleChanged, this, &MissionEditor::_activeVehicleChanged);
Vehicle* activeVehicle = multiVehicleMgr->activeVehicle();
if (activeVehicle) { if (activeVehicle) {
MissionManager* missionManager = activeVehicle->missionManager(); MissionManager* missionManager = activeVehicle->missionManager();
connect(missionManager, &MissionManager::newMissionItemsAvailable, this, &MissionEditor::_newMissionItemsAvailable); connect(missionManager, &MissionManager::newMissionItemsAvailable, this, &MissionEditor::_newMissionItemsAvailable);
_newMissionItemsAvailable(); _newMissionItemsAvailable();
_activeVehicleChanged(activeVehicle);
} else { } else {
_missionItems = new QmlObjectListModel(this); _missionItems = new QmlObjectListModel(this);
_initAllMissionItems(); _initAllMissionItems();
...@@ -135,52 +142,6 @@ void MissionEditor::removeMissionItem(int index) ...@@ -135,52 +142,6 @@ void MissionEditor::removeMissionItem(int index)
_recalcAll(); _recalcAll();
} }
void MissionEditor::moveUp(int index)
{
if (!_canEdit) {
qWarning() << "addMissionItem called with _canEdit == false";
return;
}
if (_missionItems->count() < 2 || index <= 0 || index >= _missionItems->count()) {
return;
}
MissionItem item1 = *qobject_cast<MissionItem*>(_missionItems->get(index - 1));
MissionItem item2 = *qobject_cast<MissionItem*>(_missionItems->get(index));
_missionItems->removeAt(index - 1);
_missionItems->removeAt(index - 1);
_missionItems->insert(index - 1, new MissionItem(item2, _missionItems));
_missionItems->insert(index, new MissionItem(item1, _missionItems));
_recalcAll();
}
void MissionEditor::moveDown(int index)
{
if (!_canEdit) {
qWarning() << "addMissionItem called with _canEdit == false";
return;
}
if (_missionItems->count() < 2 || index >= _missionItems->count() - 1) {
return;
}
MissionItem item1 = *qobject_cast<MissionItem*>(_missionItems->get(index));
MissionItem item2 = *qobject_cast<MissionItem*>(_missionItems->get(index + 1));
_missionItems->removeAt(index);
_missionItems->removeAt(index);
_missionItems->insert(index, new MissionItem(item2, _missionItems));
_missionItems->insert(index + 1, new MissionItem(item1, _missionItems));
_recalcAll();
}
void MissionEditor::loadMissionFromFile(void) void MissionEditor::loadMissionFromFile(void)
{ {
QString errorString; QString errorString;
...@@ -389,3 +350,34 @@ void MissionEditor::_itemCommandChanged(MavlinkQmlSingleton::Qml_MAV_CMD command ...@@ -389,3 +350,34 @@ void MissionEditor::_itemCommandChanged(MavlinkQmlSingleton::Qml_MAV_CMD command
_recalcChildItems(); _recalcChildItems();
_recalcWaypointLines(); _recalcWaypointLines();
} }
void MissionEditor::_activeVehicleChanged(Vehicle* activeVehicle)
{
if (_activeVehicle) {
disconnect(_activeVehicle, &Vehicle::homePositionAvailableChanged, this, &MissionEditor::_activeVehicleHomePositionAvailableChanged);
disconnect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionEditor::_activeVehicleHomePositionChanged);
_activeVehicle = NULL;
_activeVehicleHomePositionAvailableChanged(false);
}
_activeVehicle = activeVehicle;
if (_activeVehicle) {
connect(_activeVehicle, &Vehicle::homePositionAvailableChanged, this, &MissionEditor::_activeVehicleHomePositionAvailableChanged);
connect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionEditor::_activeVehicleHomePositionChanged);
_activeVehicleHomePositionChanged(_activeVehicle->homePosition());
_activeVehicleHomePositionAvailableChanged(_activeVehicle->homePositionAvailable());
}
}
void MissionEditor::_activeVehicleHomePositionAvailableChanged(bool homePositionAvailable)
{
_liveHomePositionAvailable = homePositionAvailable;
emit liveHomePositionAvailableChanged(_liveHomePositionAvailable);
}
void MissionEditor::_activeVehicleHomePositionChanged(const QGeoCoordinate& homePosition)
{
_liveHomePosition = homePosition;
emit liveHomePositionChanged(_liveHomePosition);
}
...@@ -26,6 +26,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -26,6 +26,7 @@ This file is part of the QGROUNDCONTROL project
#include "QGCQmlWidgetHolder.h" #include "QGCQmlWidgetHolder.h"
#include "QmlObjectListModel.h" #include "QmlObjectListModel.h"
#include "Vehicle.h"
class MissionEditor : public QGCQmlWidgetHolder class MissionEditor : public QGCQmlWidgetHolder
{ {
...@@ -38,6 +39,8 @@ public: ...@@ -38,6 +39,8 @@ public:
Q_PROPERTY(QmlObjectListModel* missionItems READ missionItems NOTIFY missionItemsChanged) Q_PROPERTY(QmlObjectListModel* missionItems READ missionItems NOTIFY missionItemsChanged)
Q_PROPERTY(QmlObjectListModel* waypointLines READ waypointLines NOTIFY waypointLinesChanged) Q_PROPERTY(QmlObjectListModel* waypointLines READ waypointLines NOTIFY waypointLinesChanged)
Q_PROPERTY(bool canEdit READ canEdit NOTIFY canEditChanged) Q_PROPERTY(bool canEdit READ canEdit NOTIFY canEditChanged)
Q_PROPERTY(bool liveHomePositionAvailable READ liveHomePositionAvailable NOTIFY liveHomePositionAvailableChanged)
Q_PROPERTY(QGeoCoordinate liveHomePosition READ liveHomePosition NOTIFY liveHomePositionChanged)
Q_INVOKABLE int addMissionItem(QGeoCoordinate coordinate); Q_INVOKABLE int addMissionItem(QGeoCoordinate coordinate);
Q_INVOKABLE void getMissionItems(void); Q_INVOKABLE void getMissionItems(void);
...@@ -45,24 +48,29 @@ public: ...@@ -45,24 +48,29 @@ public:
Q_INVOKABLE void loadMissionFromFile(void); Q_INVOKABLE void loadMissionFromFile(void);
Q_INVOKABLE void saveMissionToFile(void); Q_INVOKABLE void saveMissionToFile(void);
Q_INVOKABLE void removeMissionItem(int index); Q_INVOKABLE void removeMissionItem(int index);
Q_INVOKABLE void moveUp(int index);
Q_INVOKABLE void moveDown(int index);
// Property accessors // Property accessors
QmlObjectListModel* missionItems(void) { return _missionItems; } QmlObjectListModel* missionItems(void) { return _missionItems; }
QmlObjectListModel* waypointLines(void) { return &_waypointLines; } QmlObjectListModel* waypointLines(void) { return &_waypointLines; }
bool canEdit(void) { return _canEdit; } bool canEdit(void) { return _canEdit; }
bool liveHomePositionAvailable(void) { return _liveHomePositionAvailable; }
QGeoCoordinate liveHomePosition(void) { return _liveHomePosition; }
signals: signals:
void missionItemsChanged(void); void missionItemsChanged(void);
void canEditChanged(bool canEdit); void canEditChanged(bool canEdit);
void waypointLinesChanged(void); void waypointLinesChanged(void);
void liveHomePositionAvailableChanged(bool homePositionAvailable);
void liveHomePositionChanged(const QGeoCoordinate& homePosition);
private slots: private slots:
void _newMissionItemsAvailable(); void _newMissionItemsAvailable();
void _itemCoordinateChanged(const QGeoCoordinate& coordinate); void _itemCoordinateChanged(const QGeoCoordinate& coordinate);
void _itemCommandChanged(MavlinkQmlSingleton::Qml_MAV_CMD command); void _itemCommandChanged(MavlinkQmlSingleton::Qml_MAV_CMD command);
void _activeVehicleChanged(Vehicle* activeVehicle);
void _activeVehicleHomePositionAvailableChanged(bool homePositionAvailable);
void _activeVehicleHomePositionChanged(const QGeoCoordinate& homePosition);
private: private:
void _recalcSequence(void); void _recalcSequence(void);
...@@ -78,6 +86,9 @@ private: ...@@ -78,6 +86,9 @@ private:
QmlObjectListModel* _missionItems; QmlObjectListModel* _missionItems;
QmlObjectListModel _waypointLines; QmlObjectListModel _waypointLines;
bool _canEdit; ///< true: UI can edit these items, false: can't edit, can only send to vehicle or save bool _canEdit; ///< true: UI can edit these items, false: can't edit, can only send to vehicle or save
Vehicle* _activeVehicle;
bool _liveHomePositionAvailable;
QGeoCoordinate _liveHomePosition;
static const char* _settingsGroup; static const char* _settingsGroup;
}; };
......
...@@ -46,13 +46,14 @@ QGCView { ...@@ -46,13 +46,14 @@ QGCView {
readonly property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 16 readonly property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 16
property var _missionItems: controller.missionItems property var _missionItems: controller.missionItems
property bool _showHomePositionManager: false
property bool _addMissionItems: false
property bool _showHelpPanel: true
property var _homePositionManager: QGroundControl.homePositionManager property var _homePositionManager: QGroundControl.homePositionManager
property string _homePositionName: _homePositionManager.homePositions.get(0).name property string _homePositionName: _homePositionManager.homePositions.get(0).name
property var homePositionCoordinate: _homePositionManager.homePositions.get(0).coordinate
property var offlineHomePosition: _homePositionManager.homePositions.get(0).coordinate
property var liveHomePosition: controller.liveHomePosition
property var liveHomePositionAvailable: controller.liveHomePositionAvailable
property var homePosition: offlineHomePosition // live or offline depending on state
QGCPalette { id: _qgcPal; colorGroupEnabled: enabled } QGCPalette { id: _qgcPal; colorGroupEnabled: enabled }
...@@ -62,12 +63,7 @@ QGCView { ...@@ -62,12 +63,7 @@ QGCView {
ExclusiveGroup { ExclusiveGroup {
id: _dropButtonsExclusiveGroup id: _dropButtonsExclusiveGroup
} onCurrentChanged: console.log("Current button", current)
function disableToggles() {
_showHomePositionManager = false
_addMissionItems = false
_showHelpPanel = false
} }
function setCurrentItem(index) { function setCurrentItem(index) {
...@@ -76,20 +72,24 @@ QGCView { ...@@ -76,20 +72,24 @@ QGCView {
} }
} }
// Home position is mission item 0, so keep them in sync function updateHomePosition() {
onHomePositionCoordinateChanged: { homePosition = liveHomePositionAvailable ? liveHomePosition : offlineHomePosition
// Changing the coordinate will set the dirty bit, so we save and reset it // Changing the coordinate will set the dirty bit, so we save and reset it
var dirtyBit = _missionItems.dirty var dirtyBit = _missionItems.dirty
_missionItems.get(0).coordinate = homePositionCoordinate _missionItems.get(0).coordinate = homePosition
_missionItems.dirty = dirtyBit _missionItems.dirty = dirtyBit
} }
Component.onCompleted: onHomePositionCoordinateChanged Component.onCompleted: updateHomePosition()
onOfflineHomePositionChanged: updateHomePosition()
onLiveHomePositionAvailableChanged: updateHomePosition()
onLiveHomePositionChanged: updateHomePosition()
Connections { Connections {
target: controller target: controller
onMissionItemsChanged: _missionItems.get(0).coordinate = homePositionCoordinate // When the mission items change _missionsItems[0] changes as well so we need to reset it to home
onMissionItemsChanged: updateHomePosition
} }
QGCViewPanel { QGCViewPanel {
...@@ -108,8 +108,8 @@ QGCView { ...@@ -108,8 +108,8 @@ QGCView {
mapName: "MissionEditor" mapName: "MissionEditor"
Component.onCompleted: { Component.onCompleted: {
latitude = homePositionCoordinate.latitude latitude = homePosition.latitude
longitude = homePositionCoordinate.longitude longitude = homePosition.longitude
} }
MouseArea { MouseArea {
...@@ -120,9 +120,9 @@ QGCView { ...@@ -120,9 +120,9 @@ QGCView {
coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces) coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces)
coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces) coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces)
coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces) coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces)
if (_showHomePositionManager) { if (homePositionManagerButton.checked) {
homePositionCoordinate = coordinate offlineHomePosition = coordinate
} else if (_addMissionItems) { } else if (addMissionItemsButton.checked) {
var index = controller.addMissionItem(coordinate) var index = controller.addMissionItem(coordinate)
setCurrentItem(index) setCurrentItem(index)
} }
...@@ -164,20 +164,12 @@ QGCView { ...@@ -164,20 +164,12 @@ QGCView {
id: addMissionItemsButton id: addMissionItemsButton
buttonImage: "/qmlimages/MapAddMission.svg" buttonImage: "/qmlimages/MapAddMission.svg"
exclusiveGroup: _dropButtonsExclusiveGroup exclusiveGroup: _dropButtonsExclusiveGroup
onClicked: {
disableToggles()
_addMissionItems = addMissionItemsButton.checked
}
} }
RoundButton { RoundButton {
id: homePositionManagerButton id: homePositionManagerButton
buttonImage: "/qmlimages/MapHome.svg" buttonImage: "/qmlimages/MapHome.svg"
exclusiveGroup: _dropButtonsExclusiveGroup exclusiveGroup: _dropButtonsExclusiveGroup
onClicked: {
disableToggles()
_showHomePositionManager = homePositionManagerButton.checked
}
} }
DropButton { DropButton {
...@@ -187,10 +179,6 @@ QGCView { ...@@ -187,10 +179,6 @@ QGCView {
viewportMargins: ScreenTools.defaultFontPixelWidth / 2 viewportMargins: ScreenTools.defaultFontPixelWidth / 2
exclusiveGroup: _dropButtonsExclusiveGroup exclusiveGroup: _dropButtonsExclusiveGroup
onClicked: {
disableToggles()
}
dropDownComponent: Component { dropDownComponent: Component {
Row { Row {
spacing: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelWidth
...@@ -200,8 +188,7 @@ QGCView { ...@@ -200,8 +188,7 @@ QGCView {
onClicked: { onClicked: {
centerMapButton.hideDropDown() centerMapButton.hideDropDown()
editorMap.center = QtPositioning.coordinate(homePositionCoordinate.latitude, homePositionCoordinate.longitude) editorMap.center = QtPositioning.coordinate(homePosition.latitude, homePosition.longitude)
_showHomePositionManager = true
} }
} }
...@@ -229,8 +216,8 @@ QGCView { ...@@ -229,8 +216,8 @@ QGCView {
centerMapButton.hideDropDown() centerMapButton.hideDropDown()
// Begin with only the home position in the region // Begin with only the home position in the region
var region = QtPositioning.rectangle(QtPositioning.coordinate(homePositionCoordinate.latitude, _homePositionCoordinate.longitude), var region = QtPositioning.rectangle(QtPositioning.coordinate(homePosition.latitude, homePosition.longitude),
QtPositioning.coordinate(homePositionCoordinate.latitude, _homePositionCoordinate.longitude)) QtPositioning.coordinate(homePosition.latitude, homePosition.longitude))
// Now expand the region to include all mission items // Now expand the region to include all mission items
for (var i=0; i<_missionItems.count; i++) { for (var i=0; i<_missionItems.count; i++) {
...@@ -264,10 +251,6 @@ QGCView { ...@@ -264,10 +251,6 @@ QGCView {
viewportMargins: ScreenTools.defaultFontPixelWidth / 2 viewportMargins: ScreenTools.defaultFontPixelWidth / 2
exclusiveGroup: _dropButtonsExclusiveGroup exclusiveGroup: _dropButtonsExclusiveGroup
onClicked: {
disableToggles()
}
dropDownComponent: Component { dropDownComponent: Component {
Row { Row {
spacing: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelWidth
...@@ -320,10 +303,6 @@ QGCView { ...@@ -320,10 +303,6 @@ QGCView {
viewportMargins: ScreenTools.defaultFontPixelWidth / 2 viewportMargins: ScreenTools.defaultFontPixelWidth / 2
exclusiveGroup: _dropButtonsExclusiveGroup exclusiveGroup: _dropButtonsExclusiveGroup
onClicked: {
disableToggles()
}
dropDownComponent: Component { dropDownComponent: Component {
Row { Row {
spacing: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelWidth
...@@ -349,14 +328,9 @@ QGCView { ...@@ -349,14 +328,9 @@ QGCView {
} }
RoundButton { RoundButton {
id: showHelpButton id: helpButton
buttonImage: "/qmlimages/Help.svg" buttonImage: "/qmlimages/Help.svg"
exclusiveGroup: _dropButtonsExclusiveGroup exclusiveGroup: _dropButtonsExclusiveGroup
checked: true
onClicked: {
disableToggles()
_showHelpPanel = showHelpButton.checked
}
} }
} }
...@@ -368,27 +342,15 @@ QGCView { ...@@ -368,27 +342,15 @@ QGCView {
delegate: delegate:
MissionItemIndicator { MissionItemIndicator {
id: itemIndicator id: itemIndicator
label: object.sequenceNumber == 0 ? "H" : object.sequenceNumber label: object.sequenceNumber == 0 ? (liveHomePositionAvailable ? "H" : "F") : object.sequenceNumber
isCurrentItem: !_showHomePositionManager && object.isCurrentItem isCurrentItem: !homePositionManagerButton.checked && object.isCurrentItem
coordinate: object.coordinate coordinate: object.coordinate
z: 2 z: 2
visible: object.specifiesCoordinate visible: object.specifiesCoordinate
onClicked: { onClicked: {
disableToggles()
if (_dropButtonsExclusiveGroup.current) {
_dropButtonsExclusiveGroup.current.checked = false
}
//-- Home?
if (object.sequenceNumber === 0) {
homePositionManagerButton.checked = true
_showHomePositionManager = true
//-- Otherwise it's a mission item
} else {
addMissionItemsButton.checked = true
_addMissionItems = true
}
setCurrentItem(object.sequenceNumber) setCurrentItem(object.sequenceNumber)
missionItemEditorButton.checked
} }
Row { Row {
...@@ -401,12 +363,12 @@ QGCView { ...@@ -401,12 +363,12 @@ QGCView {
delegate: delegate:
MissionItemIndexLabel { MissionItemIndexLabel {
label: object.sequenceNumber label: object.sequenceNumber
isCurrentItem: !_showHomePositionManager && object.isCurrentItem isCurrentItem: !homePositionManagerButton.checked && object.isCurrentItem
z: 2 z: 2
onClicked: { onClicked: {
_showHomePositionManager = false
setCurrentItem(object.sequenceNumber) setCurrentItem(object.sequenceNumber)
missionItemEditorButton.checked
} }
} }
...@@ -461,8 +423,9 @@ QGCView { ...@@ -461,8 +423,9 @@ QGCView {
// Mission Item Editor // Mission Item Editor
Item { Item {
id: missionItemEditor
anchors.fill: parent anchors.fill: parent
visible: !_showHomePositionManager && controller.missionItems.count != 1 && ! _showHelpPanel visible: !helpButton.checked && !homePositionManagerButton.checked && _missionItems.count > 1
ListView { ListView {
id: missionItemSummaryList id: missionItemSummaryList
...@@ -477,6 +440,7 @@ QGCView { ...@@ -477,6 +440,7 @@ QGCView {
MissionItemEditor { MissionItemEditor {
missionItem: object missionItem: object
width: parent.width width: parent.width
readOnly: object.sequenceNumber == 0 && liveHomePositionAvailable
onClicked: setCurrentItem(object.sequenceNumber) onClicked: setCurrentItem(object.sequenceNumber)
...@@ -488,9 +452,6 @@ QGCView { ...@@ -488,9 +452,6 @@ QGCView {
setCurrentItem(newCurrentItem) setCurrentItem(newCurrentItem)
} }
} }
onMoveUp: controller.moveUp(object.sequenceNumber)
onMoveDown: controller.moveDown(object.sequenceNumber)
} }
} // ListView } // ListView
...@@ -505,15 +466,28 @@ QGCView { ...@@ -505,15 +466,28 @@ QGCView {
// Home Position Manager // Home Position Manager
Item { Item {
id: homePositionManager
anchors.fill: parent anchors.fill: parent
visible: _showHomePositionManager && !_showHelpPanel visible: homePositionManagerButton.checked
Column { Column {
anchors.fill: parent anchors.fill: parent
visible: !liveHomePositionAvailable
QGCLabel { QGCLabel {
font.pixelSize: ScreenTools.mediumFontPixelSize font.pixelSize: ScreenTools.mediumFontPixelSize
text: "Home Position Manager" text: "Flying Field Manager"
}
Item {
width: 10
height: ScreenTools.defaultFontPixelHeight
}
QGCLabel {
width: parent.width
wrapMode: Text.WordWrap
text: "This is used to save locations associated with your flying field for use while creating missions with no vehicle connection."
} }
Item { Item {
...@@ -522,7 +496,7 @@ QGCView { ...@@ -522,7 +496,7 @@ QGCView {
} }
QGCLabel { QGCLabel {
text: "Select home position to use:" text: "Select field to use:"
} }
QGCComboBox { QGCComboBox {
...@@ -535,9 +509,9 @@ QGCView { ...@@ -535,9 +509,9 @@ QGCView {
if (currentIndex != -1) { if (currentIndex != -1) {
var homePos = _homePositionManager.homePositions.get(currentIndex) var homePos = _homePositionManager.homePositions.get(currentIndex)
_homePositionName = homePos.name _homePositionName = homePos.name
homePositionCoordinate = homePos.coordinate offlineHomePosition = homePos.coordinate
editorMap.latitude = homePositionCoordinate.latitude editorMap.latitude = offlineHomePosition.latitude
editorMap.longitude = homePositionCoordinate.longitude editorMap.longitude = offlineHomePosition.longitude
} }
} }
} }
...@@ -550,9 +524,9 @@ QGCView { ...@@ -550,9 +524,9 @@ QGCView {
QGCLabel { QGCLabel {
width: parent.width width: parent.width
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: "To add a new home position, click on the Map to set the position. " + text: "To add a new flying field, click on the Map to set the position. " +
"Then give it a new name and click Add/Update. " + "Then give it a new name and click Add/Update. " +
"To change the current home position, click on the Map to set the new position. " + "To change the current field position, click on the Map to set the new position. " +
"Then click Add/Update without changing the name." "Then click Add/Update without changing the name."
} }
...@@ -585,18 +559,18 @@ QGCView { ...@@ -585,18 +559,18 @@ QGCView {
Item { Item {
width: parent.width width: parent.width
height: latitudeField.height height: offlineLatitudeField.height
QGCLabel { QGCLabel {
anchors.baseline: latitudeField.baseline anchors.baseline: offlineLatitudeField.baseline
text: "Lat:" text: "Lat:"
} }
QGCTextField { QGCTextField {
id: latitudeField id: offlineLatitudeField
anchors.right: parent.right anchors.right: parent.right
width: _editFieldWidth width: _editFieldWidth
text: homePositionCoordinate.latitude text: offlineHomePosition.latitude
} }
} }
...@@ -607,18 +581,18 @@ QGCView { ...@@ -607,18 +581,18 @@ QGCView {
Item { Item {
width: parent.width width: parent.width
height: longitudeField.height height: offlineLongitudeField.height
QGCLabel { QGCLabel {
anchors.baseline: longitudeField.baseline anchors.baseline: offlineLongitudeField.baseline
text: "Lon:" text: "Lon:"
} }
QGCTextField { QGCTextField {
id: longitudeField id: offlineLongitudeField
anchors.right: parent.right anchors.right: parent.right
width: _editFieldWidth width: _editFieldWidth
text: homePositionCoordinate.longitude text: offlineHomePosition.longitude
} }
} }
...@@ -629,18 +603,18 @@ QGCView { ...@@ -629,18 +603,18 @@ QGCView {
Item { Item {
width: parent.width width: parent.width
height: altitudeField.height height: offlineAltitudeField.height
QGCLabel { QGCLabel {
anchors.baseline: altitudeField.baseline anchors.baseline: offlineAltitudeField.baseline
text: "Alt:" text: "Alt:"
} }
QGCTextField { QGCTextField {
id: altitudeField id: offlineAltitudeField
anchors.right: parent.right anchors.right: parent.right
width: _editFieldWidth width: _editFieldWidth
text: homePositionCoordinate.altitude text: offlineHomePosition.altitude
} }
} }
...@@ -656,8 +630,8 @@ QGCView { ...@@ -656,8 +630,8 @@ QGCView {
text: "Add/Update" text: "Add/Update"
onClicked: { onClicked: {
homePositionCoordinate = QtPositioning.coordinate(latitudeField.text, longitudeField.text, altitudeField.text) offlineHomePosition = QtPositioning.coordinate(latitudeField.text, longitudeField.text, altitudeField.text)
_homePositionManager.updateHomePosition(nameField.text, homePositionCoordinate) _homePositionManager.updateHomePosition(nameField.text, offlineHomePosition)
homePosCombo.currentIndex = homePosCombo.find(nameField.text) homePosCombo.currentIndex = homePosCombo.find(nameField.text)
} }
} }
...@@ -671,17 +645,95 @@ QGCView { ...@@ -671,17 +645,95 @@ QGCView {
homePosCombo.currentIndex = 0 homePosCombo.currentIndex = 0
var homePos = _homePositionManager.homePositions.get(0) var homePos = _homePositionManager.homePositions.get(0)
_homePositionName = homePos.name _homePositionName = homePos.name
homePositionCoordinate = homePos.coordinate offlineHomePosition = homePos.coordinate
}
}
}
} // Column - Offline view
Column {
anchors.fill: parent
visible: liveHomePositionAvailable
QGCLabel {
font.pixelSize: ScreenTools.mediumFontPixelSize
text: "Vehicle Home Position"
}
Item {
width: 10
height: ScreenTools.defaultFontPixelHeight
}
Item {
width: parent.width
height: liveLatitudeField.height
QGCLabel {
anchors.baseline: liveLatitudeField.baseline
text: "Lat:"
}
QGCLabel {
id: liveLatitudeField
anchors.right: parent.right
width: _editFieldWidth
text: liveHomePosition.latitude
}
}
Item {
width: 10
height: ScreenTools.defaultFontPixelHeight / 3
}
Item {
width: parent.width
height: liveLongitudeField.height
QGCLabel {
anchors.baseline: liveLongitudeField.baseline
text: "Lon:"
}
QGCLabel {
id: liveLongitudeField
anchors.right: parent.right
width: _editFieldWidth
text: liveHomePosition.longitude
} }
} }
Item {
width: 10
height: ScreenTools.defaultFontPixelHeight / 3
} }
} // Column
Item {
width: parent.width
height: liveAltitudeField.height
QGCLabel {
anchors.baseline: liveAltitudeField.baseline
text: "Alt:"
}
QGCLabel {
id: liveAltitudeField
anchors.right: parent.right
width: _editFieldWidth
text: liveHomePosition.altitude
}
}
} // Column - Online view
} // Item - Home Position Manager } // Item - Home Position Manager
// Help Panel // Help Panel
Item { Item {
id: helpPanel
anchors.fill: parent anchors.fill: parent
visible: !_showHomePositionManager && (controller.missionItems.count == 1 || _showHelpPanel) visible: !homePositionManagerButton.checked && (_missionItems.count == 1 || helpButton.checked)
QGCLabel { QGCLabel {
id: helpTitle id: helpTitle
...@@ -738,9 +790,9 @@ QGCView { ...@@ -738,9 +790,9 @@ QGCView {
anchors.right: parent.right anchors.right: parent.right
anchors.top: homePositionManagerHelpIcon.top anchors.top: homePositionManagerHelpIcon.top
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: "<b>Home Position Manager</b><br>" + text: "<b>Flying Field Manager</b><br>" +
"When enabled, allows you to select/add/update home positions. " + "When enabled, allows you to select/add/update flying field locations. " +
"You can save multiple home position to represent multiple flying areas." "You can save multiple flying field locations for use while creating missions while you are not connected to your vehicle."
} }
Image { Image {
......
...@@ -450,9 +450,11 @@ bool QGCApplication::_initForNormalAppBoot(void) ...@@ -450,9 +450,11 @@ bool QGCApplication::_initForNormalAppBoot(void)
splashScreen->finish(mainWindow); splashScreen->finish(mainWindow);
mainWindow->splashScreenFinished(); mainWindow->splashScreenFinished();
#ifndef __mobile__
// Now that main window is up check for lost log files // Now that main window is up check for lost log files
connect(this, &QGCApplication::checkForLostLogFiles, MAVLinkProtocol::instance(), &MAVLinkProtocol::checkForLostLogFiles); connect(this, &QGCApplication::checkForLostLogFiles, MAVLinkProtocol::instance(), &MAVLinkProtocol::checkForLostLogFiles);
emit checkForLostLogFiles(); emit checkForLostLogFiles();
#endif
// Load known link configurations // Load known link configurations
LinkManager::instance()->loadLinkConfigurationList(); LinkManager::instance()->loadLinkConfigurationList();
......
...@@ -24,24 +24,51 @@ ...@@ -24,24 +24,51 @@
#include "QGCDockWidget.h" #include "QGCDockWidget.h"
#include <QCloseEvent> #include <QCloseEvent>
#include <QSettings>
QGCDockWidget::QGCDockWidget(const QString& title, QAction* action, QWidget *parent, Qt::WindowFlags flags) : const char* QGCDockWidget::_settingsGroup = "DockWidgets";
QDockWidget(title, parent, flags),
_action(action)
{
QDockWidget::DockWidgetFeatures features = QDockWidget::DockWidgetMovable;
QGCDockWidget::QGCDockWidget(const QString& title, QAction* action, QWidget* parent)
: QWidget(parent)
, _title(title)
, _action(action)
{
if (action) { if (action) {
features |= QDockWidget::DockWidgetClosable; setWindowTitle(title);
setWindowFlags(Qt::Tool);
loadSettings();
} }
setFeatures(features);
} }
// Instead of destroying the widget just hide it // Instead of destroying the widget just hide it
void QGCDockWidget::closeEvent(QCloseEvent* event) void QGCDockWidget::closeEvent(QCloseEvent* event)
{ {
Q_ASSERT(_action); if (_action) {
saveSettings();
event->ignore(); event->ignore();
_action->trigger(); _action->trigger();
}
}
void QGCDockWidget::loadSettings(void)
{
if (_action) {
QSettings settings;
settings.beginGroup(_settingsGroup);
if (settings.contains(_title)) {
restoreGeometry(settings.value(_title).toByteArray());
}
}
}
void QGCDockWidget::saveSettings(void)
{
if (_action) {
QSettings settings;
settings.beginGroup(_settingsGroup);
settings.setValue(_title, saveGeometry());
}
} }
...@@ -27,21 +27,22 @@ ...@@ -27,21 +27,22 @@
#include <QDockWidget> #include <QDockWidget>
#include <QAction> #include <QAction>
/// @file class QGCDockWidget : public QWidget {
/// @brief Subclass of QDockWidget so we can intercept the closeEvent.
///
/// @author Don Gagne <don@thegagnes.com>
class QGCDockWidget : public QDockWidget {
Q_OBJECT Q_OBJECT
public: public:
QGCDockWidget(const QString& title, QAction* action, QWidget *parent = 0, Qt::WindowFlags flags = 0); /// Pass in title = QString() and action = NULL when just using as a regular widget
QGCDockWidget(const QString& title, QAction* action, QWidget *parent = 0);
void loadSettings(void);
void saveSettings(void);
void closeEvent(QCloseEvent* event); void closeEvent(QCloseEvent* event);
private: protected:
QString _title;
QAction* _action; QAction* _action;
static const char* _settingsGroup;
}; };
......
...@@ -26,10 +26,14 @@ ...@@ -26,10 +26,14 @@
#include "QGCQmlWidgetHolder.h" #include "QGCQmlWidgetHolder.h"
QGCQmlWidgetHolder::QGCQmlWidgetHolder(QWidget *parent) : QGCQmlWidgetHolder::QGCQmlWidgetHolder(const QString& title, QAction* action, QWidget *parent) :
QWidget(parent) QGCDockWidget(title, action, parent)
{ {
_ui.setupUi(this); _ui.setupUi(this);
if (action) {
setWindowTitle(title);
}
setResizeMode(QQuickWidget::SizeRootObjectToView); setResizeMode(QQuickWidget::SizeRootObjectToView);
} }
......
...@@ -27,10 +27,10 @@ ...@@ -27,10 +27,10 @@
/// @file /// @file
/// @author Don Gagne <don@thegagnes.com> /// @author Don Gagne <don@thegagnes.com>
#include <QWidget> #include "QGCDockWidget.h"
#include "AutoPilotPlugin.h"
#include "ui_QGCQmlWidgetHolder.h" #include "ui_QGCQmlWidgetHolder.h"
#include "AutoPilotPlugin.h"
namespace Ui { namespace Ui {
class QGCQmlWidgetHolder; class QGCQmlWidgetHolder;
...@@ -38,12 +38,16 @@ class QGCQmlWidgetHolder; ...@@ -38,12 +38,16 @@ class QGCQmlWidgetHolder;
/// This is used to create widgets which are implemented in QML. /// This is used to create widgets which are implemented in QML.
class QGCQmlWidgetHolder : public QWidget class QGCQmlWidgetHolder : public QGCDockWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit QGCQmlWidgetHolder(QWidget *parent = 0); // This has a title and action since the base class is QGCDockWidget. In order to use this
// control as a normal QWidget, not a doc widget just pass in:
// title = QString()
// action = NULL
explicit QGCQmlWidgetHolder(const QString& title, QAction* action, QWidget *parent = 0);
~QGCQmlWidgetHolder(); ~QGCQmlWidgetHolder();
/// Sets the UAS into the widget which in turn will load facts into the context /// Sets the UAS into the widget which in turn will load facts into the context
......
import QtQuick 2.4
import QtQuick.Controls 1.2
/// The ExclusiveGroupItem control can be used as a base class for a control which
/// needs support for ExclusiveGroup
Item {
id: _root
property bool checked: false
property ExclusiveGroup exclusiveGroup: null
onExclusiveGroupChanged: {
if (exclusiveGroup) {
exclusiveGroup.bindCheckable(_root)
}
}
}
...@@ -13,17 +13,16 @@ import QGroundControl.Palette 1.0 ...@@ -13,17 +13,16 @@ import QGroundControl.Palette 1.0
Rectangle { Rectangle {
id: _root id: _root
property var missionItem property var missionItem ///< MissionItem associated with this editor
property bool readOnly ///< true: read only view, false: full editing view
signal clicked signal clicked
signal remove signal remove
signal moveUp
signal moveDown
height: missionItem.isCurrentItem ? height: missionItem.isCurrentItem ?
(missionItem.textFieldFacts.count * (measureTextField.height + _margin)) + (missionItem.textFieldFacts.count * (measureTextField.height + _margin)) +
(missionItem.checkboxFacts.count * (measureCheckbox.height + _margin)) + (missionItem.checkboxFacts.count * (measureCheckbox.height + _margin)) +
commandPicker.height + deleteButton.height + (_margin * 9) : commandPicker.height + (deleteButton.visible ? deleteButton.height : 0) + (_margin * 9) :
commandPicker.height + (_margin * 2) commandPicker.height + (_margin * 2)
color: missionItem.isCurrentItem ? qgcPal.buttonHighlight : qgcPal.windowShade color: missionItem.isCurrentItem ? qgcPal.buttonHighlight : qgcPal.windowShade
...@@ -63,7 +62,6 @@ Rectangle { ...@@ -63,7 +62,6 @@ Rectangle {
onClicked: _root.clicked() onClicked: _root.clicked()
} }
QGCComboBox { QGCComboBox {
id: commandPicker id: commandPicker
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 10 anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 10
...@@ -71,7 +69,7 @@ Rectangle { ...@@ -71,7 +69,7 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
currentIndex: missionItem.commandByIndex currentIndex: missionItem.commandByIndex
model: missionItem.commandNames model: missionItem.commandNames
visible: missionItem.sequenceNumber != 0 visible: missionItem.sequenceNumber != 0 // Item 0 is home position, can't change item type
onActivated: missionItem.commandByIndex = index onActivated: missionItem.commandByIndex = index
} }
...@@ -79,7 +77,7 @@ Rectangle { ...@@ -79,7 +77,7 @@ Rectangle {
Rectangle { Rectangle {
anchors.fill: commandPicker anchors.fill: commandPicker
color: qgcPal.button color: qgcPal.button
visible: missionItem.sequenceNumber == 0 visible: missionItem.sequenceNumber == 0 // Item 0 is home position, can't change item type
QGCLabel { QGCLabel {
id: homeLabel id: homeLabel
...@@ -119,6 +117,7 @@ Rectangle { ...@@ -119,6 +117,7 @@ Rectangle {
height: textField.height height: textField.height
QGCLabel { QGCLabel {
id: textFieldLabel
anchors.baseline: textField.baseline anchors.baseline: textField.baseline
text: object.name text: object.name
} }
...@@ -129,6 +128,14 @@ Rectangle { ...@@ -129,6 +128,14 @@ Rectangle {
width: _editFieldWidth width: _editFieldWidth
showUnits: true showUnits: true
fact: object fact: object
visible: !_root.readOnly
}
FactLabel {
anchors.baseline: textFieldLabel.baseline
anchors.right: parent.right
fact: object
visible: _root.readOnly
} }
} }
} }
...@@ -163,23 +170,10 @@ Rectangle { ...@@ -163,23 +170,10 @@ Rectangle {
id: deleteButton id: deleteButton
width: parent.buttonWidth width: parent.buttonWidth
text: "Delete" text: "Delete"
visible: !readOnly
onClicked: _root.remove() onClicked: _root.remove()
} }
QGCButton {
width: parent.buttonWidth
text: "Up"
onClicked: _root.moveUp()
}
QGCButton {
width: parent.buttonWidth
text: "Down"
onClicked: _root.moveDown()
}
} }
} // Column } // Column
......
...@@ -18,6 +18,7 @@ RoundButton 1.0 RoundButton.qml ...@@ -18,6 +18,7 @@ RoundButton 1.0 RoundButton.qml
VehicleRotationCal 1.0 VehicleRotationCal.qml VehicleRotationCal 1.0 VehicleRotationCal.qml
VehicleSummaryRow 1.0 VehicleSummaryRow.qml VehicleSummaryRow 1.0 VehicleSummaryRow.qml
ViewWidget 1.0 ViewWidget.qml ViewWidget 1.0 ViewWidget.qml
ExclusiveGroupItem 1.0 ExclusiveGroupItem.qml
ParameterEditor 1.0 ParameterEditor.qml ParameterEditor 1.0 ParameterEditor.qml
ParameterEditorDialog 1.0 ParameterEditorDialog.qml ParameterEditorDialog 1.0 ParameterEditorDialog.qml
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "QmlTestWidget.h" #include "QmlTestWidget.h"
QmlTestWidget::QmlTestWidget(void) QmlTestWidget::QmlTestWidget(void)
: QGCQmlWidgetHolder(QString(), NULL, NULL)
{ {
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
resize(900, 500); resize(900, 500);
......
...@@ -55,7 +55,7 @@ void ScreenToolsController::_updateCanvas() ...@@ -55,7 +55,7 @@ void ScreenToolsController::_updateCanvas()
double ScreenToolsController::getQmlDefaultFontPixelSize(void) double ScreenToolsController::getQmlDefaultFontPixelSize(void)
{ {
if (_qmlDefaultFontPixelSize == -1) { if (_qmlDefaultFontPixelSize == -1) {
QGCQmlWidgetHolder qmlWidgetHolder; QGCQmlWidgetHolder qmlWidgetHolder(QString(), NULL);
qmlWidgetHolder.setSource(QUrl::fromUserInput("qrc:/qml/ScreenToolsFontQuery.qml")); qmlWidgetHolder.setSource(QUrl::fromUserInput("qrc:/qml/ScreenToolsFontQuery.qml"));
} }
......
...@@ -227,8 +227,8 @@ void Vehicle::_handleHomePosition(mavlink_message_t& message) ...@@ -227,8 +227,8 @@ void Vehicle::_handleHomePosition(mavlink_message_t& message)
_homePosition.setAltitude(homePos.altitude / 1000.0); _homePosition.setAltitude(homePos.altitude / 1000.0);
_homePositionAvailable = true; _homePositionAvailable = true;
emit homePositionAvailableChanged(true);
emit homePositionChanged(_homePosition); emit homePositionChanged(_homePosition);
emit homePositionAvailableChanged(true);
} }
void Vehicle::_handleHeartbeat(mavlink_message_t& message) void Vehicle::_handleHeartbeat(mavlink_message_t& message)
...@@ -963,10 +963,6 @@ bool Vehicle::homePositionAvailable(void) ...@@ -963,10 +963,6 @@ bool Vehicle::homePositionAvailable(void)
QGeoCoordinate Vehicle::homePosition(void) QGeoCoordinate Vehicle::homePosition(void)
{ {
if (!_homePositionAvailable) {
qWarning() << "Call to homePosition while _homePositionAvailable == false";
}
return _homePosition; return _homePosition;
} }
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
#include <QDebug> #include <QDebug>
SetupView::SetupView(QWidget* parent) : SetupView::SetupView(QWidget* parent) :
QGCQmlWidgetHolder(parent) QGCQmlWidgetHolder(QString(), NULL, parent)
{ {
setSource(QUrl::fromUserInput("qrc:/qml/SetupView.qml")); setSource(QUrl::fromUserInput("qrc:/qml/SetupView.qml"));
} }
......
...@@ -23,8 +23,12 @@ This file is part of the QGROUNDCONTROL project ...@@ -23,8 +23,12 @@ This file is part of the QGROUNDCONTROL project
#include "CustomCommandWidget.h" #include "CustomCommandWidget.h"
CustomCommandWidget::CustomCommandWidget(QWidget *parent) : CustomCommandWidget::CustomCommandWidget(const QString& title, QAction* action, QWidget *parent) :
QGCQmlWidgetHolder(parent) QGCQmlWidgetHolder(title, action, parent)
{ {
Q_UNUSED(title);
Q_UNUSED(action);
setSource(QUrl::fromUserInput("qrc:/qml/CustomCommandWidget.qml")); setSource(QUrl::fromUserInput("qrc:/qml/CustomCommandWidget.qml"));
loadSettings();
} }
...@@ -34,7 +34,7 @@ class CustomCommandWidget : public QGCQmlWidgetHolder ...@@ -34,7 +34,7 @@ class CustomCommandWidget : public QGCQmlWidgetHolder
Q_OBJECT Q_OBJECT
public: public:
CustomCommandWidget(QWidget *parent = 0); CustomCommandWidget(const QString& title, QAction* action, QWidget *parent = 0);
}; };
#endif #endif
...@@ -367,7 +367,9 @@ void LogReplayLink::_play(void) ...@@ -367,7 +367,9 @@ void LogReplayLink::_play(void)
{ {
// FIXME: With move to link I don't think this is needed any more? Except for the replay widget handling multi-uas? // FIXME: With move to link I don't think this is needed any more? Except for the replay widget handling multi-uas?
LinkManager::instance()->setConnectionsSuspended(tr("Connect not allowed during Flight Data replay.")); LinkManager::instance()->setConnectionsSuspended(tr("Connect not allowed during Flight Data replay."));
#ifndef __mobile__
MAVLinkProtocol::instance()->suspendLogForReplay(true); MAVLinkProtocol::instance()->suspendLogForReplay(true);
#endif
// Make sure we aren't at the end of the file, if we are, reset to the beginning and play from there. // Make sure we aren't at the end of the file, if we are, reset to the beginning and play from there.
if (_logFile.atEnd()) { if (_logFile.atEnd()) {
...@@ -397,7 +399,9 @@ void LogReplayLink::_play(void) ...@@ -397,7 +399,9 @@ void LogReplayLink::_play(void)
void LogReplayLink::_pause(void) void LogReplayLink::_pause(void)
{ {
LinkManager::instance()->setConnectionsAllowed(); LinkManager::instance()->setConnectionsAllowed();
#ifndef __mobile__
MAVLinkProtocol::instance()->suspendLogForReplay(false); MAVLinkProtocol::instance()->suspendLogForReplay(false);
#endif
_readTickTimer.stop(); _readTickTimer.stop();
......
...@@ -33,8 +33,10 @@ Q_DECLARE_METATYPE(mavlink_message_t) ...@@ -33,8 +33,10 @@ Q_DECLARE_METATYPE(mavlink_message_t)
IMPLEMENT_QGC_SINGLETON(MAVLinkProtocol, MAVLinkProtocol) IMPLEMENT_QGC_SINGLETON(MAVLinkProtocol, MAVLinkProtocol)
QGC_LOGGING_CATEGORY(MAVLinkProtocolLog, "MAVLinkProtocolLog") QGC_LOGGING_CATEGORY(MAVLinkProtocolLog, "MAVLinkProtocolLog")
#ifndef __mobile__
const char* MAVLinkProtocol::_tempLogFileTemplate = "FlightDataXXXXXX"; ///< Template for temporary log file const char* MAVLinkProtocol::_tempLogFileTemplate = "FlightDataXXXXXX"; ///< Template for temporary log file
const char* MAVLinkProtocol::_logFileExtension = "mavlink"; ///< Extension for log files const char* MAVLinkProtocol::_logFileExtension = "mavlink"; ///< Extension for log files
#endif
/** /**
* The default constructor will create a new MAVLink object sending heartbeats at * The default constructor will create a new MAVLink object sending heartbeats at
...@@ -52,10 +54,12 @@ MAVLinkProtocol::MAVLinkProtocol(QObject* parent) : ...@@ -52,10 +54,12 @@ MAVLinkProtocol::MAVLinkProtocol(QObject* parent) :
m_actionRetransmissionTimeout(100), m_actionRetransmissionTimeout(100),
versionMismatchIgnore(false), versionMismatchIgnore(false),
systemId(QGC::defaultSystemId), systemId(QGC::defaultSystemId),
#ifndef __mobile__
_logSuspendError(false), _logSuspendError(false),
_logSuspendReplay(false), _logSuspendReplay(false),
_logWasArmed(false), _logWasArmed(false),
_tempLogFile(QString("%2.%3").arg(_tempLogFileTemplate).arg(_logFileExtension)), _tempLogFile(QString("%2.%3").arg(_tempLogFileTemplate).arg(_logFileExtension)),
#endif
_linkMgr(LinkManager::instance()), _linkMgr(LinkManager::instance()),
_heartbeatRate(MAVLINK_HEARTBEAT_DEFAULT_RATE), _heartbeatRate(MAVLINK_HEARTBEAT_DEFAULT_RATE),
_heartbeatsEnabled(true) _heartbeatsEnabled(true)
...@@ -91,7 +95,9 @@ MAVLinkProtocol::~MAVLinkProtocol() ...@@ -91,7 +95,9 @@ MAVLinkProtocol::~MAVLinkProtocol()
{ {
storeSettings(); storeSettings();
#ifndef __mobile__
_closeLogFile(); _closeLogFile();
#endif
} }
void MAVLinkProtocol::loadSettings() void MAVLinkProtocol::loadSettings()
...@@ -181,10 +187,12 @@ void MAVLinkProtocol::_linkStatusChanged(LinkInterface* link, bool connected) ...@@ -181,10 +187,12 @@ void MAVLinkProtocol::_linkStatusChanged(LinkInterface* link, bool connected)
// Use the same shared pointer as LinkManager // Use the same shared pointer as LinkManager
_connectedLinks.append(LinkManager::instance()->sharedPointerForLink(link)); _connectedLinks.append(LinkManager::instance()->sharedPointerForLink(link));
#ifndef __mobile__
if (_connectedLinks.count() == 1) { if (_connectedLinks.count() == 1) {
// This is the first link, we need to start logging // This is the first link, we need to start logging
_startLogging(); _startLogging();
} }
#endif
// Send command to start MAVLink // Send command to start MAVLink
// XXX hacky but safe // XXX hacky but safe
...@@ -206,10 +214,12 @@ void MAVLinkProtocol::_linkStatusChanged(LinkInterface* link, bool connected) ...@@ -206,10 +214,12 @@ void MAVLinkProtocol::_linkStatusChanged(LinkInterface* link, bool connected)
Q_UNUSED(found); Q_UNUSED(found);
Q_ASSERT(found); Q_ASSERT(found);
#ifndef __mobile__
if (_connectedLinks.count() == 0) { if (_connectedLinks.count() == 0) {
// Last link is gone, close out logging // Last link is gone, close out logging
_stopLogging(); _stopLogging();
} }
#endif
} }
} }
...@@ -303,6 +313,7 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) ...@@ -303,6 +313,7 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
rstatus.txbuf, rstatus.noise, rstatus.remnoise); rstatus.txbuf, rstatus.noise, rstatus.remnoise);
} }
#ifndef __mobile__
// Log data // Log data
if (!_logSuspendError && !_logSuspendReplay && _tempLogFile.isOpen()) { if (!_logSuspendError && !_logSuspendReplay && _tempLogFile.isOpen()) {
...@@ -339,6 +350,7 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) ...@@ -339,6 +350,7 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
} }
} }
} }
#endif
if (message.msgid == MAVLINK_MSG_ID_HEARTBEAT) { if (message.msgid == MAVLINK_MSG_ID_HEARTBEAT) {
// Notify the vehicle manager of the heartbeat. This will create/update vehicles as needed. // Notify the vehicle manager of the heartbeat. This will create/update vehicles as needed.
...@@ -613,6 +625,7 @@ int MAVLinkProtocol::getHeartbeatRate() ...@@ -613,6 +625,7 @@ int MAVLinkProtocol::getHeartbeatRate()
return _heartbeatRate; return _heartbeatRate;
} }
#ifndef __mobile__
/// @brief Closes the log file if it is open /// @brief Closes the log file if it is open
bool MAVLinkProtocol::_closeLogFile(void) bool MAVLinkProtocol::_closeLogFile(void)
{ {
...@@ -707,3 +720,4 @@ void MAVLinkProtocol::deleteTempLogFiles(void) ...@@ -707,3 +720,4 @@ void MAVLinkProtocol::deleteTempLogFiles(void)
QFile::remove(fileInfo.filePath()); QFile::remove(fileInfo.filePath());
} }
} }
#endif
...@@ -203,11 +203,13 @@ public slots: ...@@ -203,11 +203,13 @@ public slots:
/** @brief Store protocol settings */ /** @brief Store protocol settings */
void storeSettings(); void storeSettings();
#ifndef __mobile__
/// @brief Deletes any log files which are in the temp directory /// @brief Deletes any log files which are in the temp directory
static void deleteTempLogFiles(void); static void deleteTempLogFiles(void);
/// Checks for lost log files /// Checks for lost log files
void checkForLostLogFiles(void); void checkForLostLogFiles(void);
#endif
protected: protected:
bool m_multiplexingEnabled; ///< Enable/disable packet multiplexing bool m_multiplexingEnabled; ///< Enable/disable packet multiplexing
...@@ -281,15 +283,12 @@ private: ...@@ -281,15 +283,12 @@ private:
~MAVLinkProtocol(); ~MAVLinkProtocol();
void _linkStatusChanged(LinkInterface* link, bool connected); void _linkStatusChanged(LinkInterface* link, bool connected);
#ifndef __mobile__
bool _closeLogFile(void); bool _closeLogFile(void);
void _startLogging(void); void _startLogging(void);
void _stopLogging(void); void _stopLogging(void);
/// List of all links connected to protocol. We keep SharedLinkInterface objects
/// which are QSharedPointer's in order to maintain reference counts across threads.
/// This way Link deletion works correctly.
QList<SharedLinkInterface> _connectedLinks;
bool _logSuspendError; ///< true: Logging suspended due to error bool _logSuspendError; ///< true: Logging suspended due to error
bool _logSuspendReplay; ///< true: Logging suspended due to replay bool _logSuspendReplay; ///< true: Logging suspended due to replay
bool _logWasArmed; ///< true: vehicle was armed during logging bool _logWasArmed; ///< true: vehicle was armed during logging
...@@ -297,6 +296,12 @@ private: ...@@ -297,6 +296,12 @@ private:
QGCTemporaryFile _tempLogFile; ///< File to log to QGCTemporaryFile _tempLogFile; ///< File to log to
static const char* _tempLogFileTemplate; ///< Template for temporary log file static const char* _tempLogFileTemplate; ///< Template for temporary log file
static const char* _logFileExtension; ///< Extension for log files static const char* _logFileExtension; ///< Extension for log files
#endif
/// List of all links connected to protocol. We keep SharedLinkInterface objects
/// which are QSharedPointer's in order to maintain reference counts across threads.
/// This way Link deletion works correctly.
QList<SharedLinkInterface> _connectedLinks;
LinkManager* _linkMgr; LinkManager* _linkMgr;
......
...@@ -157,6 +157,7 @@ void MockLink::_run1HzTasks(void) ...@@ -157,6 +157,7 @@ void MockLink::_run1HzTasks(void)
{ {
if (_mavlinkStarted && _connected) { if (_mavlinkStarted && _connected) {
_sendHeartBeat(); _sendHeartBeat();
_sendHomePosition();
} }
} }
...@@ -692,3 +693,25 @@ void MockLink::setMissionItemFailureMode(MockLinkMissionItemHandler::FailureMode ...@@ -692,3 +693,25 @@ void MockLink::setMissionItemFailureMode(MockLinkMissionItemHandler::FailureMode
{ {
_missionItemHandler.setMissionItemFailureMode(failureMode, firstTimeOnly); _missionItemHandler.setMissionItemFailureMode(failureMode, firstTimeOnly);
} }
void MockLink::_sendHomePosition(void)
{
mavlink_message_t msg;
float bogus[4];
bogus[0] = 0.0f;
bogus[1] = 0.0f;
bogus[2] = 0.0f;
bogus[3] = 0.0f;
mavlink_msg_home_position_pack(_vehicleSystemId,
_vehicleComponentId,
&msg,
(int32_t)(47.633033f * 1E7),
(int32_t)(-122.08794f * 1E7),
(int32_t)(2.0f * 1000),
0.0f, 0.0f, 0.0f,
&bogus[0],
0.0f, 0.0f, 0.0f);
respondWithMavlinkMessage(msg);
}
...@@ -143,6 +143,7 @@ private: ...@@ -143,6 +143,7 @@ private:
void _handleCommandLong(const mavlink_message_t& msg); void _handleCommandLong(const mavlink_message_t& msg);
float _floatUnionForParam(int componentId, const QString& paramName); float _floatUnionForParam(int componentId, const QString& paramName);
void _setParamFloatUnionIntoMap(int componentId, const QString& paramName, float paramFloat); void _setParamFloatUnionIntoMap(int componentId, const QString& paramName, float paramFloat);
void _sendHomePosition(void);
MockLinkMissionItemHandler _missionItemHandler; MockLinkMissionItemHandler _missionItemHandler;
......
...@@ -84,8 +84,6 @@ void MainWindowTest::_connectWindowClose_test(MAV_AUTOPILOT autopilot) ...@@ -84,8 +84,6 @@ void MainWindowTest::_connectWindowClose_test(MAV_AUTOPILOT autopilot)
QTest::qWait(200); QTest::qWait(200);
_mainToolBar->onFlyView(); _mainToolBar->onFlyView();
QTest::qWait(200); QTest::qWait(200);
_mainToolBar->onAnalyzeView();
QTest::qWait(200);
// On MainWindow close we should get a message box telling the user to disconnect first. Cancel should do nothing. // On MainWindow close we should get a message box telling the user to disconnect first. Cancel should do nothing.
setExpectedMessageBox(QGCMessageBox::Cancel); setExpectedMessageBox(QGCMessageBox::Cancel);
......
...@@ -164,7 +164,7 @@ void RadioConfigTest::init(void) ...@@ -164,7 +164,7 @@ void RadioConfigTest::init(void)
Q_ASSERT(_autopilot); Q_ASSERT(_autopilot);
// This will instatiate the widget with an active uas with ready parameters // This will instatiate the widget with an active uas with ready parameters
_calWidget = new QGCQmlWidgetHolder(); _calWidget = new QGCQmlWidgetHolder(QString(), NULL);
_calWidget->resize(600, 600); _calWidget->resize(600, 600);
Q_CHECK_PTR(_calWidget); Q_CHECK_PTR(_calWidget);
_calWidget->setAutoPilot(_autopilot); _calWidget->setAutoPilot(_autopilot);
......
...@@ -206,6 +206,7 @@ UAS::~UAS() ...@@ -206,6 +206,7 @@ UAS::~UAS()
if (simulation) { if (simulation) {
// wait for the simulator to exit // wait for the simulator to exit
simulation->wait(); simulation->wait();
simulation->disconnectSimulation();
simulation->deleteLater(); simulation->deleteLater();
} }
#endif #endif
...@@ -1950,7 +1951,7 @@ void UAS::enableHilFlightGear(bool enable, QString options, bool sensorHil, QObj ...@@ -1950,7 +1951,7 @@ void UAS::enableHilFlightGear(bool enable, QString options, bool sensorHil, QObj
Q_UNUSED(configuration); Q_UNUSED(configuration);
QGCFlightGearLink* link = dynamic_cast<QGCFlightGearLink*>(simulation); QGCFlightGearLink* link = dynamic_cast<QGCFlightGearLink*>(simulation);
if (!link || !simulation) { if (!link) {
// Delete wrong sim // Delete wrong sim
if (simulation) { if (simulation) {
stopHil(); stopHil();
...@@ -1959,18 +1960,18 @@ void UAS::enableHilFlightGear(bool enable, QString options, bool sensorHil, QObj ...@@ -1959,18 +1960,18 @@ void UAS::enableHilFlightGear(bool enable, QString options, bool sensorHil, QObj
simulation = new QGCFlightGearLink(this, options); simulation = new QGCFlightGearLink(this, options);
} }
float noise_scaler = 0.05f; float noise_scaler = 0.002f;
xacc_var = noise_scaler * 0.2914f; xacc_var = noise_scaler * 0.2914f;
yacc_var = noise_scaler * 0.2914f; yacc_var = noise_scaler * 0.2914f;
zacc_var = noise_scaler * 0.9577f; zacc_var = noise_scaler * 0.9577f;
rollspeed_var = noise_scaler * 0.1f * 0.8126f; rollspeed_var = noise_scaler * 0.8126f;
pitchspeed_var = noise_scaler * 0.1f * 0.6145f; pitchspeed_var = noise_scaler * 0.6145f;
yawspeed_var = noise_scaler * 0.1f * 0.5852f; yawspeed_var = noise_scaler * 0.5852f;
xmag_var = noise_scaler * 0.0786f; xmag_var = noise_scaler * 0.0786f;
ymag_var = noise_scaler * 0.0566f; ymag_var = noise_scaler * 0.0566f;
zmag_var = noise_scaler * 0.0333f; zmag_var = noise_scaler * 0.0333f;
abs_pressure_var = noise_scaler * 1.1604f; abs_pressure_var = noise_scaler * 1.1604f;
diff_pressure_var = noise_scaler * 0.6604f; diff_pressure_var = noise_scaler * 0.3604f;
pressure_alt_var = noise_scaler * 1.1604f; pressure_alt_var = noise_scaler * 1.1604f;
temperature_var = noise_scaler * 2.4290f; temperature_var = noise_scaler * 2.4290f;
...@@ -1998,7 +1999,7 @@ void UAS::enableHilFlightGear(bool enable, QString options, bool sensorHil, QObj ...@@ -1998,7 +1999,7 @@ void UAS::enableHilFlightGear(bool enable, QString options, bool sensorHil, QObj
void UAS::enableHilJSBSim(bool enable, QString options) void UAS::enableHilJSBSim(bool enable, QString options)
{ {
QGCJSBSimLink* link = dynamic_cast<QGCJSBSimLink*>(simulation); QGCJSBSimLink* link = dynamic_cast<QGCJSBSimLink*>(simulation);
if (!link || !simulation) { if (!link) {
// Delete wrong sim // Delete wrong sim
if (simulation) { if (simulation) {
stopHil(); stopHil();
...@@ -2027,25 +2028,25 @@ void UAS::enableHilJSBSim(bool enable, QString options) ...@@ -2027,25 +2028,25 @@ void UAS::enableHilJSBSim(bool enable, QString options)
void UAS::enableHilXPlane(bool enable) void UAS::enableHilXPlane(bool enable)
{ {
QGCXPlaneLink* link = dynamic_cast<QGCXPlaneLink*>(simulation); QGCXPlaneLink* link = dynamic_cast<QGCXPlaneLink*>(simulation);
if (!link || !simulation) { if (!link) {
if (simulation) { if (simulation) {
stopHil(); stopHil();
delete simulation; delete simulation;
} }
simulation = new QGCXPlaneLink(this); simulation = new QGCXPlaneLink(this);
float noise_scaler = 0.02f; float noise_scaler = 0.0002f;
xacc_var = noise_scaler * 0.2914f; xacc_var = noise_scaler * 0.2914f;
yacc_var = noise_scaler * 0.2914f; yacc_var = noise_scaler * 0.2914f;
zacc_var = noise_scaler * 0.9577f; zacc_var = noise_scaler * 0.9577f;
rollspeed_var = noise_scaler * 0.15f * 0.8126f; rollspeed_var = noise_scaler * 0.8126f;
pitchspeed_var = noise_scaler * 0.15f * 0.6145f; pitchspeed_var = noise_scaler * 0.6145f;
yawspeed_var = noise_scaler * 0.15f * 0.5852f; yawspeed_var = noise_scaler * 0.5852f;
xmag_var = noise_scaler * 0.0786f; xmag_var = noise_scaler * 0.0786f;
ymag_var = noise_scaler * 0.0566f; ymag_var = noise_scaler * 0.0566f;
zmag_var = noise_scaler * 0.0333f; zmag_var = noise_scaler * 0.0333f;
abs_pressure_var = noise_scaler * 1.1604f; abs_pressure_var = noise_scaler * 1.1604f;
diff_pressure_var = noise_scaler * 0.6604f; diff_pressure_var = noise_scaler * 0.3604f;
pressure_alt_var = noise_scaler * 1.1604f; pressure_alt_var = noise_scaler * 1.1604f;
temperature_var = noise_scaler * 2.4290f; temperature_var = noise_scaler * 2.4290f;
} }
...@@ -2348,7 +2349,7 @@ void UAS::startHil() ...@@ -2348,7 +2349,7 @@ void UAS::startHil()
void UAS::stopHil() void UAS::stopHil()
{ {
if (simulation && simulation->isConnected()) { if (simulation && simulation->isConnected()) {
simulation->disconnectSim(); simulation->disconnectSimulation();
_vehicle->setHilMode(false); _vehicle->setHilMode(false);
qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to disable."; qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to disable.";
} }
......
...@@ -31,6 +31,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -31,6 +31,7 @@ This file is part of the QGROUNDCONTROL project
#include "CameraView.h" #include "CameraView.h"
#include <QDebug> #include <QDebug>
#include <QtOpenGL> #include <QtOpenGL>
#include <QOpenGLFunctions_2_0>
CameraView::CameraView(int width, int height, int depth, int channels, QWidget* parent) : QGLWidget(parent) CameraView::CameraView(int width, int height, int depth, int channels, QWidget* parent) : QGLWidget(parent)
{ {
...@@ -237,14 +238,26 @@ void CameraView::setPixels(int imgid, const unsigned char* imageData, int length ...@@ -237,14 +238,26 @@ void CameraView::setPixels(int imgid, const unsigned char* imageData, int length
void CameraView::paintGL() void CameraView::paintGL()
{ {
glDrawPixels(glImage.width(), glImage.height(), GL_RGBA, GL_UNSIGNED_BYTE, glImage.bits()); Q_ASSERT(QOpenGLContext::currentContext());
QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_2_0>();
if (!funcs) {
qWarning() << "OpenGL 2.0 not available on this platform. CameraView will not function";
return;
}
funcs->glDrawPixels(glImage.width(), glImage.height(), GL_RGBA, GL_UNSIGNED_BYTE, glImage.bits());
} }
void CameraView::resizeGL(int w, int h) void CameraView::resizeGL(int w, int h)
{ {
glViewport(0, 0, w, h); Q_ASSERT(QOpenGLContext::currentContext());
glMatrixMode(GL_PROJECTION); QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_2_0>();
glLoadIdentity(); if (!funcs) {
glOrtho(0, w, 0, h, -1, 1); // paintGL warning should suffice
glMatrixMode(GL_MODELVIEW); return;
}
funcs->glViewport(0, 0, w, h);
funcs->glMatrixMode(GL_PROJECTION);
funcs->glLoadIdentity();
funcs->glOrtho(0, w, 0, h, -1, 1);
funcs->glMatrixMode(GL_MODELVIEW);
} }
...@@ -24,10 +24,12 @@ ...@@ -24,10 +24,12 @@
#include "HILDockWidget.h" #include "HILDockWidget.h"
#include "QGCHilConfiguration.h" #include "QGCHilConfiguration.h"
HILDockWidget::HILDockWidget(QWidget *parent) HILDockWidget::HILDockWidget(const QString& title, QAction* action, QWidget *parent)
: MultiVehicleDockWidget(parent) : MultiVehicleDockWidget(title, action, parent)
{ {
init(); init();
loadSettings();
} }
HILDockWidget::~HILDockWidget() HILDockWidget::~HILDockWidget()
......
...@@ -31,7 +31,7 @@ class HILDockWidget : public MultiVehicleDockWidget ...@@ -31,7 +31,7 @@ class HILDockWidget : public MultiVehicleDockWidget
Q_OBJECT Q_OBJECT
public: public:
explicit HILDockWidget(QWidget *parent = 0); explicit HILDockWidget(const QString& title, QAction* action, QWidget *parent = 0);
~HILDockWidget(); ~HILDockWidget();
protected: protected:
......
...@@ -46,8 +46,6 @@ This file is part of the QGROUNDCONTROL project ...@@ -46,8 +46,6 @@ This file is part of the QGROUNDCONTROL project
#include "QGCMAVLinkLogPlayer.h" #include "QGCMAVLinkLogPlayer.h"
#include "SettingsDialog.h" #include "SettingsDialog.h"
#include "MAVLinkDecoder.h" #include "MAVLinkDecoder.h"
#include "QGCDataPlot2D.h"
#include "Linecharts.h"
#include "FlightDisplayView.h" #include "FlightDisplayView.h"
#include "SetupView.h" #include "SetupView.h"
#include "QGCApplication.h" #include "QGCApplication.h"
...@@ -60,6 +58,8 @@ This file is part of the QGROUNDCONTROL project ...@@ -60,6 +58,8 @@ This file is part of the QGROUNDCONTROL project
#include "UAS.h" #include "UAS.h"
#ifndef __mobile__ #ifndef __mobile__
#include "QGCDataPlot2D.h"
#include "Linecharts.h"
#include "QGCUASFileViewMulti.h" #include "QGCUASFileViewMulti.h"
#include "UASQuickView.h" #include "UASQuickView.h"
#include "QGCTabbedInfoView.h" #include "QGCTabbedInfoView.h"
...@@ -88,14 +88,16 @@ This file is part of the QGROUNDCONTROL project ...@@ -88,14 +88,16 @@ This file is part of the QGROUNDCONTROL project
const char* MAIN_SETTINGS_GROUP = "QGC_MAINWINDOW"; const char* MAIN_SETTINGS_GROUP = "QGC_MAINWINDOW";
#ifndef __mobile__ #ifndef __mobile__
const char* MainWindow::_mavlinkDockWidgetName = "MAVLINK_INSPECTOR_DOCKWIDGET"; const char* MainWindow::_mavlinkDockWidgetName = "MAVLink Inspector";
const char* MainWindow::_customCommandWidgetName = "CUSTOM_COMMAND_DOCKWIDGET"; const char* MainWindow::_customCommandWidgetName = "Custom Command";
const char* MainWindow::_filesDockWidgetName = "FILE_VIEW_DOCKWIDGET"; const char* MainWindow::_filesDockWidgetName = "Onboard Files";
const char* MainWindow::_uasStatusDetailsDockWidgetName = "UAS_STATUS_DETAILS_DOCKWIDGET"; const char* MainWindow::_uasStatusDetailsDockWidgetName = "Status Details";
const char* MainWindow::_mapViewDockWidgetName = "MAP_VIEW_DOCKWIDGET"; const char* MainWindow::_pfdDockWidgetName = "Primary Flight Display";
const char* MainWindow::_pfdDockWidgetName = "PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET"; const char* MainWindow::_uasInfoViewDockWidgetName = "Info View";
const char* MainWindow::_uasInfoViewDockWidgetName = "UAS_INFO_INFOVIEW_DOCKWIDGET"; const char* MainWindow::_hilDockWidgetName = "HIL Config";
const char* MainWindow::_hilDockWidgetName = "HIL_DOCKWIDGET"; const char* MainWindow::_analyzeDockWidgetName = "Analyze";
const char* MainWindow::_visibleWidgetsKey = "VisibleWidgets";
#endif #endif
static MainWindow* _instance = NULL; ///< @brief MainWindow singleton static MainWindow* _instance = NULL; ///< @brief MainWindow singleton
...@@ -276,13 +278,11 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) ...@@ -276,13 +278,11 @@ MainWindow::MainWindow(QSplashScreen* splashScreen)
_ui.actionSetup->setShortcut(QApplication::translate("MainWindow", "Meta+1", 0)); _ui.actionSetup->setShortcut(QApplication::translate("MainWindow", "Meta+1", 0));
_ui.actionPlan->setShortcut(QApplication::translate("MainWindow", "Meta+2", 0)); _ui.actionPlan->setShortcut(QApplication::translate("MainWindow", "Meta+2", 0));
_ui.actionFlight->setShortcut(QApplication::translate("MainWindow", "Meta+3", 0)); _ui.actionFlight->setShortcut(QApplication::translate("MainWindow", "Meta+3", 0));
_ui.actionAnalyze->setShortcut(QApplication::translate("MainWindow", "Meta+4", 0));
_ui.actionFullscreen->setShortcut(QApplication::translate("MainWindow", "Meta+Return", 0)); _ui.actionFullscreen->setShortcut(QApplication::translate("MainWindow", "Meta+Return", 0));
#else #else
_ui.actionSetup->setShortcut(QApplication::translate("MainWindow", "Ctrl+1", 0)); _ui.actionSetup->setShortcut(QApplication::translate("MainWindow", "Ctrl+1", 0));
_ui.actionPlan->setShortcut(QApplication::translate("MainWindow", "Ctrl+2", 0)); _ui.actionPlan->setShortcut(QApplication::translate("MainWindow", "Ctrl+2", 0));
_ui.actionFlight->setShortcut(QApplication::translate("MainWindow", "Ctrl+3", 0)); _ui.actionFlight->setShortcut(QApplication::translate("MainWindow", "Ctrl+3", 0));
_ui.actionAnalyze->setShortcut(QApplication::translate("MainWindow", "Ctrl+4", 0));
_ui.actionFullscreen->setShortcut(QApplication::translate("MainWindow", "Ctrl+Return", 0)); _ui.actionFullscreen->setShortcut(QApplication::translate("MainWindow", "Ctrl+Return", 0));
#endif #endif
...@@ -313,6 +313,10 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) ...@@ -313,6 +313,10 @@ MainWindow::MainWindow(QSplashScreen* splashScreen)
qd.close(); qd.close();
#endif #endif
} }
#ifndef __mobile__
_loadVisibleWidgetsSettings();
#endif
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
...@@ -341,34 +345,6 @@ QString MainWindow::_getWindowGeometryKey() ...@@ -341,34 +345,6 @@ QString MainWindow::_getWindowGeometryKey()
} }
#ifndef __mobile__ #ifndef __mobile__
void MainWindow::_createDockWidget(const QString& title, const QString& name, Qt::DockWidgetArea area, QWidget* innerWidget)
{
Q_ASSERT(!_mapName2DockWidget.contains(name));
// Add to menu
QAction* action = new QAction(title, NULL);
action->setCheckable(true);
action->setData(name);
connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction);
_ui.menuWidgets->addAction(action);
// Create widget
QGCDockWidget* dockWidget = new QGCDockWidget(title, action, this);
Q_CHECK_PTR(dockWidget);
dockWidget->setObjectName(name);
dockWidget->setVisible (false);
if (innerWidget) {
// Put inner widget inside QDockWidget
innerWidget->setParent(dockWidget);
dockWidget->setWidget(innerWidget);
innerWidget->setVisible(true);
}
_mapName2DockWidget[name] = dockWidget;
_mapDockWidget2Action[dockWidget] = action;
addDockWidget(area, dockWidget);
}
void MainWindow::_buildCommonWidgets(void) void MainWindow::_buildCommonWidgets(void)
{ {
// Add generic MAVLink decoder // Add generic MAVLink decoder
...@@ -382,99 +358,83 @@ void MainWindow::_buildCommonWidgets(void) ...@@ -382,99 +358,83 @@ void MainWindow::_buildCommonWidgets(void)
logPlayer = new QGCMAVLinkLogPlayer(statusBar()); logPlayer = new QGCMAVLinkLogPlayer(statusBar());
statusBar()->addPermanentWidget(logPlayer); statusBar()->addPermanentWidget(logPlayer);
// In order for Qt to save and restore state of widgets all widgets must be created ahead of time. We only create the QDockWidget static const char* rgDockWidgetNames[] = {
// holders. We do not create the actual inner widget until it is needed. This saves memory and cpu from running widgets that are _mavlinkDockWidgetName,
// never shown. _customCommandWidgetName,
_filesDockWidgetName,
struct DockWidgetInfo { _uasStatusDetailsDockWidgetName,
const char* name; _pfdDockWidgetName,
const char* title; _uasInfoViewDockWidgetName,
Qt::DockWidgetArea area; _hilDockWidgetName,
_analyzeDockWidgetName,
}; };
static const size_t cDockWidgetNames = sizeof(rgDockWidgetNames) / sizeof(rgDockWidgetNames[0]);
static const struct DockWidgetInfo rgDockWidgetInfo[] = { for (size_t i=0; i<cDockWidgetNames; i++) {
{ _mavlinkDockWidgetName, "MAVLink Inspector", Qt::RightDockWidgetArea }, const char* pDockWidgetName = rgDockWidgetNames[i];
{ _customCommandWidgetName, "Custom Command", Qt::RightDockWidgetArea },
{ _filesDockWidgetName, "Onboard Files", Qt::RightDockWidgetArea }, // Add to menu
{ _uasStatusDetailsDockWidgetName, "Status Details", Qt::RightDockWidgetArea }, QAction* action = new QAction(pDockWidgetName, NULL);
{ _mapViewDockWidgetName, "Map view", Qt::RightDockWidgetArea }, action->setCheckable(true);
{ _pfdDockWidgetName, "Primary Flight Display", Qt::RightDockWidgetArea }, action->setData(pDockWidgetName);
{ _uasInfoViewDockWidgetName, "Info View", Qt::LeftDockWidgetArea }, connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction);
{ _hilDockWidgetName, "HIL Config", Qt::LeftDockWidgetArea }, _ui.menuWidgets->addAction(action);
};
static const size_t cDockWidgetInfo = sizeof(rgDockWidgetInfo) / sizeof(rgDockWidgetInfo[0]);
for (size_t i=0; i<cDockWidgetInfo; i++) { _mapName2Action[pDockWidgetName] = action;
const struct DockWidgetInfo* pDockInfo = &rgDockWidgetInfo[i];
_createDockWidget(pDockInfo->title, pDockInfo->name, pDockInfo->area, NULL /* no inner widget yet */);
} }
} }
/// Shows or hides the specified dock widget, creating if necessary /// Shows or hides the specified dock widget, creating if necessary
void MainWindow::_showDockWidget(const QString& name, bool show) void MainWindow::_showDockWidget(const QString& name, bool show)
{ {
if (!_mapName2DockWidget.contains(name)) {
// Don't show any sort of warning here. Dock Widgets which have been remove could still be in settings.
// Which would cause us to end up here.
return;
}
// Create the inner widget if we need to // Create the inner widget if we need to
if (!_mapName2DockWidget[name]->widget()) { if (!_mapName2DockWidget.contains(name)) {
_createInnerDockWidget(name); _createInnerDockWidget(name);
} }
Q_ASSERT(_mapName2DockWidget.contains(name)); Q_ASSERT(_mapName2DockWidget.contains(name));
QDockWidget* dockWidget = _mapName2DockWidget[name]; QGCDockWidget* dockWidget = _mapName2DockWidget[name];
Q_ASSERT(dockWidget); Q_ASSERT(dockWidget);
dockWidget->setVisible(show); dockWidget->setVisible(show);
Q_ASSERT(_mapDockWidget2Action.contains(dockWidget)); Q_ASSERT(_mapName2Action.contains(name));
_mapDockWidget2Action[dockWidget]->setChecked(show); _mapName2Action[name]->setChecked(show);
} }
/// Creates the specified inner dock widget and adds to the QDockWidget /// Creates the specified inner dock widget and adds to the QDockWidget
void MainWindow::_createInnerDockWidget(const QString& widgetName) void MainWindow::_createInnerDockWidget(const QString& widgetName)
{ {
Q_ASSERT(_mapName2DockWidget.contains(widgetName)); // QDockWidget should already exist QGCDockWidget* widget = NULL;
Q_ASSERT(!_mapName2DockWidget[widgetName]->widget()); // Inner widget should not
QWidget* widget = NULL;
if (widgetName == _mavlinkDockWidgetName) { if (widgetName == _mavlinkDockWidgetName) {
widget = new QGCMAVLinkInspector(MAVLinkProtocol::instance(),this); widget = new QGCMAVLinkInspector(widgetName, _mapName2Action[widgetName], MAVLinkProtocol::instance(),this);
} else if (widgetName == _customCommandWidgetName) { } else if (widgetName == _customCommandWidgetName) {
widget = new CustomCommandWidget(this); widget = new CustomCommandWidget(widgetName, _mapName2Action[widgetName], this);
} else if (widgetName == _filesDockWidgetName) { } else if (widgetName == _filesDockWidgetName) {
widget = new QGCUASFileViewMulti(this); widget = new QGCUASFileViewMulti(widgetName, _mapName2Action[widgetName], this);
} else if (widgetName == _uasStatusDetailsDockWidgetName) { } else if (widgetName == _uasStatusDetailsDockWidgetName) {
widget = new UASInfoWidget(this); widget = new UASInfoWidget(widgetName, _mapName2Action[widgetName], this);
} else if (widgetName == _pfdDockWidgetName) { } else if (widgetName == _pfdDockWidgetName) {
widget = new FlightDisplayWidget(this); widget = new FlightDisplayWidget(widgetName, _mapName2Action[widgetName], this);
#ifndef __mobile__
} else if (widgetName == _hilDockWidgetName) { } else if (widgetName == _hilDockWidgetName) {
widget = new HILDockWidget(this); widget = new HILDockWidget(widgetName, _mapName2Action[widgetName], this);
#endif } else if (widgetName == _analyzeDockWidgetName) {
widget = new Linecharts(widgetName, _mapName2Action[widgetName], mavlinkDecoder, this);
} else if (widgetName == _uasInfoViewDockWidgetName) { } else if (widgetName == _uasInfoViewDockWidgetName) {
QGCTabbedInfoView* pInfoView = new QGCTabbedInfoView(this); QGCTabbedInfoView* pInfoView = new QGCTabbedInfoView(widgetName, _mapName2Action[widgetName], this);
pInfoView->addSource(mavlinkDecoder); pInfoView->addSource(mavlinkDecoder);
widget = pInfoView; widget = pInfoView;
} else { } else {
qWarning() << "Attempt to create unknown Inner Dock Widget" << widgetName; qWarning() << "Attempt to create unknown Inner Dock Widget" << widgetName;
} }
if (widget) { _mapName2DockWidget[widgetName] = widget;
QDockWidget* dockWidget = _mapName2DockWidget[widgetName];
Q_CHECK_PTR(dockWidget);
widget->setParent(dockWidget);
dockWidget->setWidget(widget);
}
} }
void MainWindow::_hideAllDockWidgets(void) void MainWindow::_hideAllDockWidgets(void)
{ {
foreach(QDockWidget* dockWidget, _mapName2DockWidget) { foreach(QGCDockWidget* dockWidget, _mapName2DockWidget) {
dockWidget->setVisible(false); dockWidget->setVisible(false);
} }
} }
...@@ -483,7 +443,7 @@ void MainWindow::_showDockWidgetAction(bool show) ...@@ -483,7 +443,7 @@ void MainWindow::_showDockWidgetAction(bool show)
{ {
QAction* action = dynamic_cast<QAction*>(QObject::sender()); QAction* action = dynamic_cast<QAction*>(QObject::sender());
Q_ASSERT(action); Q_ASSERT(action);
_showDockWidget(action->data().toString(), show); _showDockWidget(action->text(), show);
} }
#endif #endif
...@@ -511,14 +471,6 @@ void MainWindow::_buildSetupView(void) ...@@ -511,14 +471,6 @@ void MainWindow::_buildSetupView(void)
} }
} }
void MainWindow::_buildAnalyzeView(void)
{
if (!_analyzeView) {
_analyzeView = new QGCDataPlot2D(this);
_analyzeView->setVisible(false);
}
}
void MainWindow::fullScreenActionItemCallback(bool) void MainWindow::fullScreenActionItemCallback(bool)
{ {
_ui.actionNormal->setChecked(false); _ui.actionNormal->setChecked(false);
...@@ -592,6 +544,10 @@ void MainWindow::storeSettings() ...@@ -592,6 +544,10 @@ void MainWindow::storeSettings()
// Save the last current view in any case // Save the last current view in any case
settings.setValue("CURRENT_VIEW", _currentView); settings.setValue("CURRENT_VIEW", _currentView);
settings.setValue(_getWindowStateKey(), saveState()); settings.setValue(_getWindowStateKey(), saveState());
#ifndef __mobile__
_storeVisibleWidgetsSettings();
#endif
} }
void MainWindow::configureWindowName() void MainWindow::configureWindowName()
...@@ -627,18 +583,10 @@ void MainWindow::connectCommonActions() ...@@ -627,18 +583,10 @@ void MainWindow::connectCommonActions()
{ {
// Bind together the perspective actions // Bind together the perspective actions
QActionGroup* perspectives = new QActionGroup(_ui.menuPerspectives); QActionGroup* perspectives = new QActionGroup(_ui.menuPerspectives);
perspectives->addAction(_ui.actionAnalyze);
perspectives->addAction(_ui.actionFlight);
perspectives->addAction(_ui.actionPlan); perspectives->addAction(_ui.actionPlan);
perspectives->addAction(_ui.actionSetup); perspectives->addAction(_ui.actionSetup);
perspectives->setExclusive(true); perspectives->setExclusive(true);
// Mark the right one as selected
if (_currentView == VIEW_ANALYZE)
{
_ui.actionAnalyze->setChecked(true);
_ui.actionAnalyze->activate(QAction::Trigger);
}
if (_currentView == VIEW_FLIGHT) if (_currentView == VIEW_FLIGHT)
{ {
_ui.actionFlight->setChecked(true); _ui.actionFlight->setChecked(true);
...@@ -663,7 +611,6 @@ void MainWindow::connectCommonActions() ...@@ -663,7 +611,6 @@ void MainWindow::connectCommonActions()
// Views actions // Views actions
connect(_ui.actionFlight, SIGNAL(triggered()), this, SLOT(loadFlightView())); connect(_ui.actionFlight, SIGNAL(triggered()), this, SLOT(loadFlightView()));
connect(_ui.actionAnalyze, SIGNAL(triggered()), this, SLOT(loadAnalyzeView()));
connect(_ui.actionPlan, SIGNAL(triggered()), this, SLOT(loadPlanView())); connect(_ui.actionPlan, SIGNAL(triggered()), this, SLOT(loadPlanView()));
// Help Actions // Help Actions
...@@ -733,38 +680,17 @@ void MainWindow::commsWidgetDestroyed(QObject *obj) ...@@ -733,38 +680,17 @@ void MainWindow::commsWidgetDestroyed(QObject *obj)
void MainWindow::_vehicleAdded(Vehicle* vehicle) void MainWindow::_vehicleAdded(Vehicle* vehicle)
{ {
connect(vehicle->uas(), SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), this, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64))); connect(vehicle->uas(), SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), this, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)));
if (!linechartWidget)
{
linechartWidget = new Linecharts(this);
linechartWidget->setVisible(false);
}
linechartWidget->addSource(mavlinkDecoder);
if (_analyzeView != linechartWidget)
{
_analyzeView = linechartWidget;
}
} }
/// Stores the state of the toolbar, status bar and widgets associated with the current view /// Stores the state of the toolbar, status bar and widgets associated with the current view
void MainWindow::_storeCurrentViewState(void) void MainWindow::_storeCurrentViewState(void)
{ {
#ifndef __mobile__ #ifndef __mobile__
// Save list of visible widgets foreach(QGCDockWidget* dockWidget, _mapName2DockWidget) {
bool firstWidget = true; dockWidget->saveSettings();
QString widgetNames = "";
foreach(QDockWidget* dockWidget, _mapName2DockWidget) {
if (dockWidget->isVisible()) {
if (!firstWidget) {
widgetNames += ",";
} }
widgetNames += dockWidget->objectName();
firstWidget = false;
}
}
settings.setValue(_getWindowStateKey() + "WIDGETS", widgetNames);
#endif #endif
settings.setValue(_getWindowStateKey(), saveState()); settings.setValue(_getWindowStateKey(), saveState());
settings.setValue(_getWindowGeometryKey(), saveGeometry()); settings.setValue(_getWindowGeometryKey(), saveGeometry());
} }
...@@ -773,7 +699,6 @@ void MainWindow::_storeCurrentViewState(void) ...@@ -773,7 +699,6 @@ void MainWindow::_storeCurrentViewState(void)
void MainWindow::_loadCurrentViewState(void) void MainWindow::_loadCurrentViewState(void)
{ {
QWidget* centerView = NULL; QWidget* centerView = NULL;
QString defaultWidgets;
switch (_currentView) { switch (_currentView) {
case VIEW_SETUP: case VIEW_SETUP:
...@@ -781,16 +706,9 @@ void MainWindow::_loadCurrentViewState(void) ...@@ -781,16 +706,9 @@ void MainWindow::_loadCurrentViewState(void)
centerView = _setupView; centerView = _setupView;
break; break;
case VIEW_ANALYZE:
_buildAnalyzeView();
centerView = _analyzeView;
defaultWidgets = "PARAMETER_INTERFACE_DOCKWIDGET,FILE_VIEW_DOCKWIDGET";
break;
case VIEW_FLIGHT: case VIEW_FLIGHT:
_buildFlightView(); _buildFlightView();
centerView = _flightView; centerView = _flightView;
defaultWidgets = "COMMUNICATION_CONSOLE_DOCKWIDGET,UAS_INFO_INFOVIEW_DOCKWIDGET";
break; break;
case VIEW_MISSIONEDITOR: case VIEW_MISSIONEDITOR:
...@@ -820,22 +738,6 @@ void MainWindow::_loadCurrentViewState(void) ...@@ -820,22 +738,6 @@ void MainWindow::_loadCurrentViewState(void)
_centralLayout->setContentsMargins(0, 0, 0, 0); _centralLayout->setContentsMargins(0, 0, 0, 0);
_currentViewWidget->setVisible(true); _currentViewWidget->setVisible(true);
#ifndef __mobile__
// Hide all widgets from previous view
_hideAllDockWidgets();
// Restore the widgets for the new view
QString widgetNames = settings.value(_getWindowStateKey() + "WIDGETS", defaultWidgets).toString();
qDebug() << widgetNames;
if (!widgetNames.isEmpty()) {
QStringList split = widgetNames.split(",");
foreach (QString widgetName, split) {
Q_ASSERT(!widgetName.isEmpty());
_showDockWidget(widgetName, true);
}
}
#endif
if (settings.contains(_getWindowStateKey())) { if (settings.contains(_getWindowStateKey())) {
restoreState(settings.value(_getWindowStateKey()).toByteArray()); restoreState(settings.value(_getWindowStateKey()).toByteArray());
} }
...@@ -845,17 +747,6 @@ void MainWindow::_loadCurrentViewState(void) ...@@ -845,17 +747,6 @@ void MainWindow::_loadCurrentViewState(void)
emit repaintCanvas(); emit repaintCanvas();
} }
void MainWindow::loadAnalyzeView()
{
if (_currentView != VIEW_ANALYZE)
{
_storeCurrentViewState();
_currentView = VIEW_ANALYZE;
_ui.actionAnalyze->setChecked(true);
_loadCurrentViewState();
}
}
void MainWindow::loadPlanView() void MainWindow::loadPlanView()
{ {
if (_currentView != VIEW_MISSIONEDITOR) if (_currentView != VIEW_MISSIONEDITOR)
...@@ -949,3 +840,42 @@ void MainWindow::_showQmlTestWidget(void) ...@@ -949,3 +840,42 @@ void MainWindow::_showQmlTestWidget(void)
new QmlTestWidget(); new QmlTestWidget();
} }
#endif #endif
#ifndef __mobile__
void MainWindow::_loadVisibleWidgetsSettings(void)
{
QSettings settings;
QString widgets = settings.value(_visibleWidgetsKey).toString();
if (!widgets.isEmpty()) {
QStringList nameList = widgets.split(",");
foreach (QString name, nameList) {
_showDockWidget(name, true);
}
}
}
void MainWindow::_storeVisibleWidgetsSettings(void)
{
QString widgetNames;
bool firstWidget = true;
foreach (QString name, _mapName2DockWidget.keys()) {
if (_mapName2DockWidget[name]->isVisible()) {
if (!firstWidget) {
widgetNames += ",";
} else {
firstWidget = false;
}
widgetNames += name;
}
}
QSettings settings;
settings.setValue(_visibleWidgetsKey, widgetNames);
}
#endif
...@@ -35,26 +35,27 @@ This file is part of the QGROUNDCONTROL project ...@@ -35,26 +35,27 @@ This file is part of the QGROUNDCONTROL project
#include <QStatusBar> #include <QStatusBar>
#include <QStackedWidget> #include <QStackedWidget>
#include <QSettings> #include <QSettings>
#include <qlist.h> #include <QList>
#include "ui_MainWindow.h" #include "ui_MainWindow.h"
#include "LinkManager.h" #include "LinkManager.h"
#include "LinkInterface.h" #include "LinkInterface.h"
#include "UASInterface.h" #include "UASInterface.h"
#include "CameraView.h" #include "CameraView.h"
#if (defined QGC_MOUSE_ENABLED_WIN) | (defined QGC_MOUSE_ENABLED_LINUX)
#include "Mouse6dofInput.h"
#endif // QGC_MOUSE_ENABLED_WIN
#include "MainToolBar.h" #include "MainToolBar.h"
#include "LogCompressor.h" #include "LogCompressor.h"
#include "FlightDisplayView.h" #include "FlightDisplayView.h"
#include "QGCMAVLinkInspector.h" #include "QGCMAVLinkInspector.h"
#include "QGCMAVLinkLogPlayer.h" #include "QGCMAVLinkLogPlayer.h"
#include "MAVLinkDecoder.h" #include "MAVLinkDecoder.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "QGCDockWidget.h"
#if (defined QGC_MOUSE_ENABLED_WIN) | (defined QGC_MOUSE_ENABLED_LINUX)
#include "Mouse6dofInput.h"
#endif // QGC_MOUSE_ENABLED_WIN
class QGCFirmwareUpdate;
class QSplashScreen; class QSplashScreen;
class QGCStatusBar; class QGCStatusBar;
class Linecharts; class Linecharts;
...@@ -120,7 +121,6 @@ public slots: ...@@ -120,7 +121,6 @@ public slots:
void loadSetupView(); void loadSetupView();
void loadFlightView(); void loadFlightView();
void loadAnalyzeView();
void loadPlanView(); void loadPlanView();
void manageLinks(); void manageLinks();
...@@ -185,7 +185,7 @@ protected: ...@@ -185,7 +185,7 @@ protected:
typedef enum _VIEW_SECTIONS typedef enum _VIEW_SECTIONS
{ {
VIEW_ANALYZE, // Engineering/Analyze view mode. Used for analyzing data and modifying onboard parameters VIEW_UNUSED5, // Unused (don't remove, or it will screw up saved settigns indices)
VIEW_UNUSED3, // Unused (don't remove, or it will screw up saved settigns indices) VIEW_UNUSED3, // Unused (don't remove, or it will screw up saved settigns indices)
VIEW_FLIGHT, // Flight/Fly/Operate view mode. Used for 1st-person observation of the vehicle. VIEW_FLIGHT, // Flight/Fly/Operate view mode. Used for 1st-person observation of the vehicle.
VIEW_UNUSED4, // Unused (don't remove, or it will screw up saved settigns indices) VIEW_UNUSED4, // Unused (don't remove, or it will screw up saved settigns indices)
...@@ -203,7 +203,6 @@ protected: ...@@ -203,7 +203,6 @@ protected:
void loadSettings(); void loadSettings();
void storeSettings(); void storeSettings();
QSettings settings; QSettings settings;
// Center widgets // Center widgets
...@@ -261,7 +260,6 @@ private: ...@@ -261,7 +260,6 @@ private:
QPointer<QWidget> _planView; QPointer<QWidget> _planView;
QPointer<QWidget> _flightView; QPointer<QWidget> _flightView;
QPointer<QWidget> _setupView; QPointer<QWidget> _setupView;
QPointer<QWidget> _analyzeView;
QPointer<QWidget> _missionEditorView; QPointer<QWidget> _missionEditorView;
#ifndef __mobile__ #ifndef __mobile__
...@@ -270,19 +268,18 @@ private: ...@@ -270,19 +268,18 @@ private:
static const char* _customCommandWidgetName; static const char* _customCommandWidgetName;
static const char* _filesDockWidgetName; static const char* _filesDockWidgetName;
static const char* _uasStatusDetailsDockWidgetName; static const char* _uasStatusDetailsDockWidgetName;
static const char* _mapViewDockWidgetName;
static const char* _pfdDockWidgetName; static const char* _pfdDockWidgetName;
static const char* _uasInfoViewDockWidgetName; static const char* _uasInfoViewDockWidgetName;
static const char* _hilDockWidgetName; static const char* _hilDockWidgetName;
static const char* _analyzeDockWidgetName;
QMap<QString, QDockWidget*> _mapName2DockWidget; QMap<QString, QGCDockWidget*> _mapName2DockWidget;
QMap<QDockWidget*, QAction*> _mapDockWidget2Action; QMap<QString, QAction*> _mapName2Action;
#endif #endif
void _buildPlanView(void); void _buildPlanView(void);
void _buildFlightView(void); void _buildFlightView(void);
void _buildSetupView(void); void _buildSetupView(void);
void _buildAnalyzeView(void);
void _buildTerminalView(void); void _buildTerminalView(void);
void _buildMissionEditorView(void); void _buildMissionEditorView(void);
...@@ -290,11 +287,14 @@ private: ...@@ -290,11 +287,14 @@ private:
void _loadCurrentViewState(void); void _loadCurrentViewState(void);
#ifndef __mobile__ #ifndef __mobile__
void _createDockWidget(const QString& title, const QString& name, Qt::DockWidgetArea area, QWidget* innerWidget);
void _createInnerDockWidget(const QString& widgetName); void _createInnerDockWidget(const QString& widgetName);
void _buildCommonWidgets(void); void _buildCommonWidgets(void);
void _hideAllDockWidgets(void); void _hideAllDockWidgets(void);
void _showDockWidget(const QString &name, bool show); void _showDockWidget(const QString &name, bool show);
void _loadVisibleWidgetsSettings(void);
void _storeVisibleWidgetsSettings(void);
static const char* _visibleWidgetsKey;
#endif #endif
bool _autoReconnect; bool _autoReconnect;
......
...@@ -80,7 +80,6 @@ ...@@ -80,7 +80,6 @@
<addaction name="actionSetup"/> <addaction name="actionSetup"/>
<addaction name="actionPlan"/> <addaction name="actionPlan"/>
<addaction name="actionFlight"/> <addaction name="actionFlight"/>
<addaction name="actionAnalyze"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFullscreen"/> <addaction name="actionFullscreen"/>
<addaction name="actionNormal"/> <addaction name="actionNormal"/>
...@@ -134,14 +133,6 @@ ...@@ -134,14 +133,6 @@
<string>Plan</string> <string>Plan</string>
</property> </property>
</action> </action>
<action name="actionAnalyze">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Analyze</string>
</property>
</action>
<action name="actionFlight"> <action name="actionFlight">
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
...@@ -237,9 +228,7 @@ ...@@ -237,9 +228,7 @@
</action> </action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources> <resources/>
<include location="../../qgroundcontrol.qrc"/>
</resources>
<connections> <connections>
<connection> <connection>
<sender>actionExit</sender> <sender>actionExit</sender>
......
...@@ -25,12 +25,14 @@ ...@@ -25,12 +25,14 @@
#include "ui_MultiVehicleDockWidget.h" #include "ui_MultiVehicleDockWidget.h"
#include "MultiVehicleManager.h" #include "MultiVehicleManager.h"
MultiVehicleDockWidget::MultiVehicleDockWidget(QWidget *parent) MultiVehicleDockWidget::MultiVehicleDockWidget(const QString& title, QAction* action, QWidget *parent)
: QWidget(parent) : QGCDockWidget(title, action, parent)
, _ui(new Ui::MultiVehicleDockWidget) , _ui(new Ui::MultiVehicleDockWidget)
{ {
_ui->setupUi(this); _ui->setupUi(this);
setWindowTitle(title);
connect(MultiVehicleManager::instance(), &MultiVehicleManager::activeVehicleChanged, this, &MultiVehicleDockWidget::_activeVehicleChanged); connect(MultiVehicleManager::instance(), &MultiVehicleManager::activeVehicleChanged, this, &MultiVehicleDockWidget::_activeVehicleChanged);
connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleAdded, this, &MultiVehicleDockWidget::_vehicleAdded); connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleAdded, this, &MultiVehicleDockWidget::_vehicleAdded);
connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleRemoved, this, &MultiVehicleDockWidget::_vehicleRemoved); connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleRemoved, this, &MultiVehicleDockWidget::_vehicleRemoved);
...@@ -38,8 +40,11 @@ MultiVehicleDockWidget::MultiVehicleDockWidget(QWidget *parent) ...@@ -38,8 +40,11 @@ MultiVehicleDockWidget::MultiVehicleDockWidget(QWidget *parent)
void MultiVehicleDockWidget::init(void) void MultiVehicleDockWidget::init(void)
{ {
foreach (Vehicle* vehicle, MultiVehicleManager::instance()->vehicles()) {
_vehicleAdded(vehicle);
}
if (MultiVehicleManager::instance()->activeVehicle()) { if (MultiVehicleManager::instance()->activeVehicle()) {
_vehicleAdded(MultiVehicleManager::instance()->activeVehicle());
_activeVehicleChanged(MultiVehicleManager::instance()->activeVehicle()); _activeVehicleChanged(MultiVehicleManager::instance()->activeVehicle());
} }
} }
......
...@@ -24,9 +24,9 @@ ...@@ -24,9 +24,9 @@
#ifndef MultiVehicleDockWidget_H #ifndef MultiVehicleDockWidget_H
#define MultiVehicleDockWidget_H #define MultiVehicleDockWidget_H
#include <QWidget>
#include <QMap> #include <QMap>
#include "QGCDockWidget.h"
#include "Vehicle.h" #include "Vehicle.h"
namespace Ui namespace Ui
...@@ -37,12 +37,12 @@ namespace Ui ...@@ -37,12 +37,12 @@ namespace Ui
/// Provides a base class for a dock widget which automatically handles /// Provides a base class for a dock widget which automatically handles
/// Vehicles coming and going. It does this by using a stacked widget which /// Vehicles coming and going. It does this by using a stacked widget which
/// holds individual Vehicle specific widgets. /// holds individual Vehicle specific widgets.
class MultiVehicleDockWidget : public QWidget class MultiVehicleDockWidget : public QGCDockWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit MultiVehicleDockWidget(QWidget *parent = 0); explicit MultiVehicleDockWidget(const QString& title, QAction* action, QWidget *parent = 0);
~MultiVehicleDockWidget(); ~MultiVehicleDockWidget();
/// Must be called in the derived class contructor to initialize the base class /// Must be called in the derived class contructor to initialize the base class
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>HIL Config</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout" rowstretch="1,100,1" columnstretch="40,0"> <layout class="QGridLayout" name="gridLayout" rowstretch="1,100,1" columnstretch="40,0">
<item row="0" column="0"> <item row="0" column="0">
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
const float QGCMAVLinkInspector::updateHzLowpass = 0.2f; const float QGCMAVLinkInspector::updateHzLowpass = 0.2f;
const unsigned int QGCMAVLinkInspector::updateInterval = 1000U; const unsigned int QGCMAVLinkInspector::updateInterval = 1000U;
QGCMAVLinkInspector::QGCMAVLinkInspector(MAVLinkProtocol* protocol, QWidget *parent) : QGCMAVLinkInspector::QGCMAVLinkInspector(const QString& title, QAction* action, MAVLinkProtocol* protocol, QWidget *parent) :
QWidget(parent), QGCDockWidget(title, action, parent),
_protocol(protocol), _protocol(protocol),
selectedSystemID(0), selectedSystemID(0),
selectedComponentID(0), selectedComponentID(0),
...@@ -58,6 +58,8 @@ QGCMAVLinkInspector::QGCMAVLinkInspector(MAVLinkProtocol* protocol, QWidget *par ...@@ -58,6 +58,8 @@ QGCMAVLinkInspector::QGCMAVLinkInspector(MAVLinkProtocol* protocol, QWidget *par
// Attach the UI's refresh rate to a timer. // Attach the UI's refresh rate to a timer.
connect(&updateTimer, SIGNAL(timeout()), this, SLOT(refreshView())); connect(&updateTimer, SIGNAL(timeout()), this, SLOT(refreshView()));
updateTimer.start(updateInterval); updateTimer.start(updateInterval);
loadSettings();
} }
void QGCMAVLinkInspector::_vehicleAdded(Vehicle* vehicle) void QGCMAVLinkInspector::_vehicleAdded(Vehicle* vehicle)
......
#ifndef QGCMAVLINKINSPECTOR_H #ifndef QGCMAVLINKINSPECTOR_H
#define QGCMAVLINKINSPECTOR_H #define QGCMAVLINKINSPECTOR_H
#include <QWidget>
#include <QMap> #include <QMap>
#include <QTimer> #include <QTimer>
#include "QGCDockWidget.h"
#include "MAVLinkProtocol.h" #include "MAVLinkProtocol.h"
#include "Vehicle.h" #include "Vehicle.h"
...@@ -15,12 +15,12 @@ namespace Ui { ...@@ -15,12 +15,12 @@ namespace Ui {
class QTreeWidgetItem; class QTreeWidgetItem;
class UASInterface; class UASInterface;
class QGCMAVLinkInspector : public QWidget class QGCMAVLinkInspector : public QGCDockWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit QGCMAVLinkInspector(MAVLinkProtocol* protocol, QWidget *parent = 0); explicit QGCMAVLinkInspector(const QString& title, QAction* action, MAVLinkProtocol* protocol, QWidget *parent = 0);
~QGCMAVLinkInspector(); ~QGCMAVLinkInspector();
public slots: public slots:
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>MAVLink Inspector</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout" columnstretch="2,8,2,8,3"> <layout class="QGridLayout" name="gridLayout" columnstretch="2,8,2,8,3">
<property name="leftMargin"> <property name="leftMargin">
......
#include "QGCTabbedInfoView.h" #include "QGCTabbedInfoView.h"
QGCTabbedInfoView::QGCTabbedInfoView(QWidget *parent) : QWidget(parent) QGCTabbedInfoView::QGCTabbedInfoView(const QString& title, QAction* action, QWidget *parent)
: QGCDockWidget(title, action, parent)
{ {
ui.setupUi(this); ui.setupUi(this);
messageView = new UASMessageViewWidget(this); messageView = new UASMessageViewWidget(this);
...@@ -11,6 +12,8 @@ QGCTabbedInfoView::QGCTabbedInfoView(QWidget *parent) : QWidget(parent) ...@@ -11,6 +12,8 @@ QGCTabbedInfoView::QGCTabbedInfoView(QWidget *parent) : QWidget(parent)
//ui.tabWidget->addTab(actionsWidget,"Actions"); //ui.tabWidget->addTab(actionsWidget,"Actions");
//ui.tabWidget->addTab(rawView,"Status"); //ui.tabWidget->addTab(rawView,"Status");
ui.tabWidget->addTab(messageView,"Messages"); ui.tabWidget->addTab(messageView,"Messages");
loadSettings();
} }
void QGCTabbedInfoView::addSource(MAVLinkDecoder *decoder) void QGCTabbedInfoView::addSource(MAVLinkDecoder *decoder)
{ {
......
#ifndef QGCTABBEDINFOVIEW_H #ifndef QGCTABBEDINFOVIEW_H
#define QGCTABBEDINFOVIEW_H #define QGCTABBEDINFOVIEW_H
#include <QWidget> #include "QGCDockWidget.h"
#include "ui_QGCTabbedInfoView.h"
#include "MAVLinkDecoder.h" #include "MAVLinkDecoder.h"
#include "UASMessageView.h" #include "UASMessageView.h"
#include "UASQuickView.h" #include "UASQuickView.h"
#include "UASRawStatusView.h" #include "UASRawStatusView.h"
class QGCTabbedInfoView : public QWidget
#include "ui_QGCTabbedInfoView.h"
class QGCTabbedInfoView : public QGCDockWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit QGCTabbedInfoView(QWidget *parent = 0); explicit QGCTabbedInfoView(const QString& title, QAction* action, QWidget *parent = 0);
~QGCTabbedInfoView(); ~QGCTabbedInfoView();
void addSource(MAVLinkDecoder *decoder); void addSource(MAVLinkDecoder *decoder);
private: private:
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Info View</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
#include "MultiVehicleManager.h" #include "MultiVehicleManager.h"
#include "QGCUASFileView.h" #include "QGCUASFileView.h"
QGCUASFileViewMulti::QGCUASFileViewMulti(QWidget *parent) : QGCUASFileViewMulti::QGCUASFileViewMulti(const QString& title, QAction* action, QWidget *parent) :
QWidget(parent), QGCDockWidget(title, action, parent),
ui(new Ui::QGCUASFileViewMulti) ui(new Ui::QGCUASFileViewMulti)
{ {
ui->setupUi(this); ui->setupUi(this);
...@@ -18,6 +18,8 @@ QGCUASFileViewMulti::QGCUASFileViewMulti(QWidget *parent) : ...@@ -18,6 +18,8 @@ QGCUASFileViewMulti::QGCUASFileViewMulti(QWidget *parent) :
_vehicleAdded(MultiVehicleManager::instance()->activeVehicle()); _vehicleAdded(MultiVehicleManager::instance()->activeVehicle());
_activeVehicleChanged(MultiVehicleManager::instance()->activeVehicle()); _activeVehicleChanged(MultiVehicleManager::instance()->activeVehicle());
} }
loadSettings();
} }
void QGCUASFileViewMulti::_vehicleRemoved(Vehicle* vehicle) void QGCUASFileViewMulti::_vehicleRemoved(Vehicle* vehicle)
......
#ifndef QGCUASFILEVIEWMULTI_H #ifndef QGCUASFILEVIEWMULTI_H
#define QGCUASFILEVIEWMULTI_H #define QGCUASFILEVIEWMULTI_H
#include <QWidget>
#include <QMap> #include <QMap>
#include "QGCDockWidget.h"
#include "QGCUASFileView.h" #include "QGCUASFileView.h"
#include "UAS.h" #include "UAS.h"
...@@ -12,12 +12,12 @@ namespace Ui ...@@ -12,12 +12,12 @@ namespace Ui
class QGCUASFileViewMulti; class QGCUASFileViewMulti;
} }
class QGCUASFileViewMulti : public QWidget class QGCUASFileViewMulti : public QGCDockWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit QGCUASFileViewMulti(QWidget *parent = 0); explicit QGCUASFileViewMulti(const QString& title, QAction* action, QWidget *parent = 0);
~QGCUASFileViewMulti(); ~QGCUASFileViewMulti();
protected: protected:
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Onboard Files</string>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<property name="margin"> <property name="margin">
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Status Details</string>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true"/> <string notr="true"/>
......
...@@ -5,99 +5,27 @@ ...@@ -5,99 +5,27 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "UAS.h" #include "UAS.h"
Linecharts::Linecharts(QWidget *parent) : Linecharts::Linecharts(const QString& title, QAction* action, MAVLinkDecoder* decoder, QWidget *parent)
QStackedWidget(parent), : MultiVehicleDockWidget(title, action, parent)
plots(), , _mavlinkDecoder(decoder)
active(true)
{ {
this->setVisible(false); init();
// Add each MAV
foreach (Vehicle* vehicle, MultiVehicleManager::instance()->vehicles()) {
addVehicle(vehicle);
}
connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleAdded, this, &Linecharts::addVehicle);
}
void Linecharts::showEvent(QShowEvent* event) this->setVisible(false);
{
// React only to internal (pre-display)
// events
Q_UNUSED(event)
QWidget* prevWidget = currentWidget();
if (prevWidget)
{
LinechartWidget* chart = dynamic_cast<LinechartWidget*>(prevWidget);
if (chart) {
this->active = true;
chart->setActive(true);
}
}
QWidget::showEvent(event);
emit visibilityChanged(true);
}
void Linecharts::hideEvent(QHideEvent* event)
{
// React only to internal (pre-display)
// events
Q_UNUSED(event)
QWidget* prevWidget = currentWidget();
if (prevWidget) {
LinechartWidget* chart = dynamic_cast<LinechartWidget*>(prevWidget);
if (chart) {
this->active = false;
chart->setActive(false);
}
}
QWidget::hideEvent(event);
emit visibilityChanged(false);
} }
void Linecharts::addVehicle(Vehicle* vehicle) QWidget* Linecharts::_newVehicleWidget(Vehicle* vehicle, QWidget* parent)
{ {
UAS* uas = vehicle->uas(); LinechartWidget* widget = new LinechartWidget(vehicle->id(), parent);
// FIXME Add removeSystem() call
// Compatibility hack
int uasid = 0; /*uas->getUASID()*/
if (!plots.contains(uasid))
{
LinechartWidget* widget = new LinechartWidget(uasid, this);
addWidget(widget);
plots.insert(uasid, widget);
// Connect valueChanged signals // Connect valueChanged signals
connect(uas, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), widget, SLOT(appendData(int,QString,QString,QVariant,quint64))); connect(vehicle->uas(), &UAS::valueChanged, widget, &LinechartWidget::appendData);
// Connect decoder
connect(_mavlinkDecoder, &MAVLinkDecoder::valueChanged, widget, &LinechartWidget::appendData);
connect(widget, SIGNAL(logfileWritten(QString)), this, SIGNAL(logfileWritten(QString)));
// Set system active if this is the only system
// if (active)
// {
// if (plots.size() == 1)
// {
// FIXME XXX HACK
// Connect generic sources
for (int i = 0; i < genericSources.count(); ++i)
{
connect(genericSources[i], SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,QVariant,quint64)));
}
// Select system // Select system
widget->setActive(true); widget->setActive(true);
//widget->selectActiveSystem(0);
}
// }
// }
}
void Linecharts::addSource(QObject* obj) return widget;
{
genericSources.append(obj);
// FIXME XXX HACK
if (plots.size() > 0)
{
// Connect generic source
connect(obj, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,QVariant,quint64)));
}
} }
...@@ -7,34 +7,26 @@ ...@@ -7,34 +7,26 @@
#include "LinechartWidget.h" #include "LinechartWidget.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "MultiVehicleDockWidget.h"
#include "MAVLinkDecoder.h"
class Linecharts : public QStackedWidget class Linecharts : public MultiVehicleDockWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit Linecharts(QWidget *parent = 0); explicit Linecharts(const QString& title, QAction* action, MAVLinkDecoder* decoder, QWidget *parent = 0);
signals: signals:
/** @brief This signal is emitted once a logfile has been finished writing */ /** @brief This signal is emitted once a logfile has been finished writing */
void logfileWritten(QString fileName); void logfileWritten(QString fileName);
void visibilityChanged(bool visible); void visibilityChanged(bool visible);
public slots:
/** @brief Add a new system to the list of plots */
void addVehicle(Vehicle* vehicle);
/** @brief Add a new generic message source (not a system) */
void addSource(QObject* obj);
protected: protected:
// Override from MultiVehicleDockWidget
virtual QWidget* _newVehicleWidget(Vehicle* vehicle, QWidget* parent);
QMap<int, LinechartWidget*> plots; private:
QVector<QObject*> genericSources; MAVLinkDecoder* _mavlinkDecoder;
bool active;
/** @brief Start updating widget */
void showEvent(QShowEvent* event);
/** @brief Stop updating widget */
void hideEvent(QHideEvent* event);
}; };
#endif // LINECHARTS_H #endif // LINECHARTS_H
...@@ -41,7 +41,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -41,7 +41,7 @@ This file is part of the QGROUNDCONTROL project
#include "UAS.h" #include "UAS.h"
MainToolBar::MainToolBar(QWidget* parent) MainToolBar::MainToolBar(QWidget* parent)
: QGCQmlWidgetHolder(parent) : QGCQmlWidgetHolder(QString(), NULL, parent)
, _vehicle(NULL) , _vehicle(NULL)
, _mav(NULL) , _mav(NULL)
, _toolBar(NULL) , _toolBar(NULL)
...@@ -161,12 +161,6 @@ void MainToolBar::onFlyViewMenu() ...@@ -161,12 +161,6 @@ void MainToolBar::onFlyViewMenu()
} }
} }
void MainToolBar::onAnalyzeView()
{
setCurrentView(MainWindow::VIEW_ANALYZE);
MainWindow::instance()->loadAnalyzeView();
}
void MainToolBar::onDisconnect(QString conf) void MainToolBar::onDisconnect(QString conf)
{ {
if(conf.isEmpty()) { if(conf.isEmpty()) {
...@@ -248,9 +242,6 @@ void MainToolBar::setCurrentView(int currentView) ...@@ -248,9 +242,6 @@ void MainToolBar::setCurrentView(int currentView)
{ {
ViewType_t view = ViewNone; ViewType_t view = ViewNone;
switch((MainWindow::VIEW_SECTIONS)currentView) { switch((MainWindow::VIEW_SECTIONS)currentView) {
case MainWindow::VIEW_ANALYZE:
view = ViewAnalyze;
break;
case MainWindow::VIEW_MISSIONEDITOR: case MainWindow::VIEW_MISSIONEDITOR:
view = ViewPlan; view = ViewPlan;
break; break;
......
...@@ -64,7 +64,6 @@ public: ...@@ -64,7 +64,6 @@ public:
Q_INVOKABLE void onPlanView(); Q_INVOKABLE void onPlanView();
Q_INVOKABLE void onFlyView(); Q_INVOKABLE void onFlyView();
Q_INVOKABLE void onFlyViewMenu(); Q_INVOKABLE void onFlyViewMenu();
Q_INVOKABLE void onAnalyzeView();
Q_INVOKABLE void onConnect(QString conf); Q_INVOKABLE void onConnect(QString conf);
Q_INVOKABLE void onDisconnect(QString conf); Q_INVOKABLE void onDisconnect(QString conf);
Q_INVOKABLE void onEnterMessageArea(int x, int y); Q_INVOKABLE void onEnterMessageArea(int x, int y);
......
...@@ -626,7 +626,6 @@ Rectangle { ...@@ -626,7 +626,6 @@ Rectangle {
setupButton.repaintChevron = true; setupButton.repaintChevron = true;
planButton.repaintChevron = true; planButton.repaintChevron = true;
flyButton.repaintChevron = true; flyButton.repaintChevron = true;
analyzeButton.repaintChevron = true;
} }
} }
...@@ -670,19 +669,6 @@ Rectangle { ...@@ -670,19 +669,6 @@ Rectangle {
} }
z: 800 z: 800
} }
QGCToolBarButton {
id: analyzeButton
width: getProportionalDimmension(90)
height: cellHeight
exclusiveGroup: mainActionGroup
text: qsTr("Analyze")
checked: (mainToolBar.currentView === MainToolBar.ViewAnalyze)
onClicked: {
mainToolBar.onAnalyzeView();
}
z: 700
}
} // Row } // Row
//--------------------------------------------------------------------- //---------------------------------------------------------------------
......
...@@ -43,7 +43,8 @@ This file is part of the PIXHAWK project ...@@ -43,7 +43,8 @@ This file is part of the PIXHAWK project
#include "QGC.h" #include "QGC.h"
#include "UAS.h" #include "UAS.h"
UASInfoWidget::UASInfoWidget(QWidget *parent, QString name) : QWidget(parent) UASInfoWidget::UASInfoWidget(const QString& title, QAction* action, QWidget *parent, QString name)
: QGCDockWidget(title, action, parent)
{ {
ui.setupUi(this); ui.setupUi(this);
this->name = name; this->name = name;
...@@ -72,6 +73,8 @@ UASInfoWidget::UASInfoWidget(QWidget *parent, QString name) : QWidget(parent) ...@@ -72,6 +73,8 @@ UASInfoWidget::UASInfoWidget(QWidget *parent, QString name) : QWidget(parent)
updateTimer->start(updateInterval); updateTimer->start(updateInterval);
this->setVisible(false); this->setVisible(false);
loadSettings();
} }
UASInfoWidget::~UASInfoWidget() UASInfoWidget::~UASInfoWidget()
......
...@@ -32,10 +32,10 @@ This file is part of the QGROUNDCONTROL project ...@@ -32,10 +32,10 @@ This file is part of the QGROUNDCONTROL project
#ifndef _UASINFOWIDGET_H_ #ifndef _UASINFOWIDGET_H_
#define _UASINFOWIDGET_H_ #define _UASINFOWIDGET_H_
#include <QWidget>
#include <QTimer> #include <QTimer>
#include <QMap> #include <QMap>
#include "QGCDockWidget.h"
#include "UASInterface.h" #include "UASInterface.h"
#include "ui_UASInfo.h" #include "ui_UASInfo.h"
#include "Vehicle.h" #include "Vehicle.h"
...@@ -44,11 +44,11 @@ This file is part of the QGROUNDCONTROL project ...@@ -44,11 +44,11 @@ This file is part of the QGROUNDCONTROL project
* @brief Info indicator for the currently active UAS * @brief Info indicator for the currently active UAS
* *
**/ **/
class UASInfoWidget : public QWidget class UASInfoWidget : public QGCDockWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
UASInfoWidget(QWidget *parent = 0, QString name = ""); UASInfoWidget(const QString& title, QAction* action, QWidget *parent = 0, QString name = "");
~UASInfoWidget(); ~UASInfoWidget();
public slots: public slots:
......
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