Commit cfedca5a authored by DonLakeFlyer's avatar DonLakeFlyer

parent 10fc35fb
......@@ -6,6 +6,7 @@ Note: This file only contains high level features or important fixes.
### 3.6.0 - Daily Build
* Plan View: New create plan UI for initial plan creation
* New Corridor editing tools ui. Includes ability to trace polyline by clicking.
* New Polygon editing tools ui. Includes ability to trace polygon by clicking.
* ArduCopter/Rover: Follow Me setup page
......
......@@ -127,6 +127,10 @@
<file alias="pipHide.svg">src/FlightMap/Images/pipHide.svg</file>
<file alias="pipResize.svg">src/FlightMap/Images/pipResize.svg</file>
<file alias="Plan.svg">src/ui/toolbar/Images/Plan.svg</file>
<file alias="PlanCreator/CustomPlanCreator.png">src/MissionManager/CustomPlanCreator.png</file>
<file alias="PlanCreator/CorridorScanPlanCreator.png">src/MissionManager/CorridorScanPlanCreator.png</file>
<file alias="PlanCreator/StructureScanPlanCreator.png">src/MissionManager/StructureScanPlanCreator.png</file>
<file alias="PlanCreator/SurveyPlanCreator.png">src/MissionManager/SurveyPlanCreator.png</file>
<file alias="PowerComponentBattery_01cell.svg">src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_01cell.svg</file>
<file alias="PowerComponentBattery_02cell.svg">src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_02cell.svg</file>
<file alias="PowerComponentBattery_03cell.svg">src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_03cell.svg</file>
......
......@@ -591,6 +591,8 @@ HEADERS += \
src/MissionManager/CameraSpec.h \
src/MissionManager/ComplexMissionItem.h \
src/MissionManager/CorridorScanComplexItem.h \
src/MissionManager/CorridorScanPlanCreator.h \
src/MissionManager/CustomPlanCreator.h \
src/MissionManager/FixedWingLandingComplexItem.h \
src/MissionManager/GeoFenceController.h \
src/MissionManager/GeoFenceManager.h \
......@@ -603,6 +605,7 @@ HEADERS += \
src/MissionManager/MissionManager.h \
src/MissionManager/MissionSettingsItem.h \
src/MissionManager/PlanElementController.h \
src/MissionManager/PlanCreator.h \
src/MissionManager/PlanManager.h \
src/MissionManager/PlanMasterController.h \
src/MissionManager/QGCFenceCircle.h \
......@@ -617,7 +620,9 @@ HEADERS += \
src/MissionManager/Section.h \
src/MissionManager/SpeedSection.h \
src/MissionManager/StructureScanComplexItem.h \
src/MissionManager/StructureScanPlanCreator.h \
src/MissionManager/SurveyComplexItem.h \
src/MissionManager/SurveyPlanCreator.h \
src/MissionManager/TransectStyleComplexItem.h \
src/MissionManager/VisualMissionItem.h \
src/PositionManager/PositionManager.h \
......@@ -817,6 +822,8 @@ SOURCES += \
src/MissionManager/CameraSpec.cc \
src/MissionManager/ComplexMissionItem.cc \
src/MissionManager/CorridorScanComplexItem.cc \
src/MissionManager/CorridorScanPlanCreator.cc \
src/MissionManager/CustomPlanCreator.cc \
src/MissionManager/FixedWingLandingComplexItem.cc \
src/MissionManager/GeoFenceController.cc \
src/MissionManager/GeoFenceManager.cc \
......@@ -829,6 +836,7 @@ SOURCES += \
src/MissionManager/MissionManager.cc \
src/MissionManager/MissionSettingsItem.cc \
src/MissionManager/PlanElementController.cc \
src/MissionManager/PlanCreator.cc \
src/MissionManager/PlanManager.cc \
src/MissionManager/PlanMasterController.cc \
src/MissionManager/QGCFenceCircle.cc \
......@@ -842,7 +850,9 @@ SOURCES += \
src/MissionManager/SimpleMissionItem.cc \
src/MissionManager/SpeedSection.cc \
src/MissionManager/StructureScanComplexItem.cc \
src/MissionManager/StructureScanPlanCreator.cc \
src/MissionManager/SurveyComplexItem.cc \
src/MissionManager/SurveyPlanCreator.cc \
src/MissionManager/TransectStyleComplexItem.cc \
src/MissionManager/VisualMissionItem.cc \
src/PositionManager/PositionManager.cpp \
......
......@@ -102,6 +102,7 @@
<file alias="QGroundControl/Controls/ParameterEditorDialog.qml">src/QmlControls/ParameterEditorDialog.qml</file>
<file alias="QGroundControl/Controls/PIDTuning.qml">src/QmlControls/PIDTuning.qml</file>
<file alias="QGroundControl/Controls/PlanEditToolbar.qml">src/PlanView/PlanEditToolbar.qml</file>
<file alias="QGroundControl/Controls/PlanStartOverlay.qml">src/PlanView/PlanStartOverlay.qml</file>
<file alias="QGroundControl/Controls/PreFlightCheckButton.qml">src/QmlControls/PreFlightCheckButton.qml</file>
<file alias="QGroundControl/Controls/PreFlightCheckGroup.qml">src/QmlControls/PreFlightCheckGroup.qml</file>
<file alias="QGroundControl/Controls/PreFlightCheckModel.qml">src/QmlControls/PreFlightCheckModel.qml</file>
......
......@@ -51,6 +51,8 @@ CorridorScanComplexItem::CorridorScanComplexItem(Vehicle* vehicle, bool flyView,
connect(&_corridorPolyline, &QGCMapPolyline::pathChanged, this, &CorridorScanComplexItem::_rebuildCorridorPolygon);
connect(&_corridorWidthFact, &Fact::valueChanged, this, &CorridorScanComplexItem::_rebuildCorridorPolygon);
connect(&_corridorPolyline, &QGCMapPolyline::isValidChanged,this, &CorridorScanComplexItem::readyForSaveStateChanged);
if (!kmlFile.isEmpty()) {
_corridorPolyline.loadKMLFile(kmlFile);
_corridorPolyline.setDirty(false);
......@@ -490,9 +492,9 @@ void CorridorScanComplexItem::_recalcCameraShots(void)
emit cameraShotsChanged();
}
bool CorridorScanComplexItem::readyForSave(void) const
CorridorScanComplexItem::ReadyForSaveState CorridorScanComplexItem::readyForSaveState(void) const
{
return TransectStyleComplexItem::readyForSave();
return TransectStyleComplexItem::readyForSaveState();
}
double CorridorScanComplexItem::timeBetweenShots(void)
......
......@@ -51,7 +51,7 @@ public:
QString commandDescription (void) const final { return tr("Corridor Scan"); }
QString commandName (void) const final { return tr("Corridor Scan"); }
QString abbreviation (void) const final { return tr("C"); }
bool readyForSave (void) const;
ReadyForSaveState readyForSaveState (void) const final;
double additionalTimeDelay (void) const final { return 0; }
static const char* jsonComplexItemTypeValue;
......
......@@ -139,7 +139,7 @@ void CorridorScanComplexItemTest::_waitForReadyForSave(void)
{
int loops = 0;
while (loops++ < 8) {
if (_corridorItem->readyForSave()) {
if (_corridorItem->readyForSaveState() == CorridorScanComplexItem::ReadyForSave) {
return;
}
QTest::qWait(500);
......
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "CorridorScanPlanCreator.h"
#include "PlanMasterController.h"
#include "MissionSettingsItem.h"
CorridorScanPlanCreator::CorridorScanPlanCreator(PlanMasterController* planMasterController, QObject* parent)
: PlanCreator(planMasterController, MissionController::patternCorridorScanName, QStringLiteral("/qmlimages/PlanCreator/CorridorScanPlanCreator.png"), parent)
{
}
void CorridorScanPlanCreator::createPlan(const QGeoCoordinate& mapCenterCoord)
{
_planMasterController->removeAll();
int seqNum = _missionController->insertComplexMissionItem(
MissionController::patternCorridorScanName,
mapCenterCoord,
_missionController->visualItems()->count());
if (_planMasterController->managerVehicle()->fixedWing()) {
_missionController->insertComplexMissionItem(
MissionController::patternFWLandingName,
mapCenterCoord,
_missionController->visualItems()->count());
} else {
MissionSettingsItem* settingsItem = _missionController->visualItems()->value<MissionSettingsItem*>(0);
settingsItem->setMissionEndRTL(true);
}
_missionController->setCurrentPlanViewIndex(seqNum, false);
}
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#pragma once
#include "PlanCreator.h"
class CorridorScanPlanCreator : public PlanCreator
{
Q_OBJECT
public:
CorridorScanPlanCreator(PlanMasterController* planMasterController, QObject* parent = nullptr);
Q_INVOKABLE void createPlan(const QGeoCoordinate& mapCenterCoord) final;
};
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "CustomPlanCreator.h"
#include "PlanMasterController.h"
#include "MissionSettingsItem.h"
CustomPlanCreator::CustomPlanCreator(PlanMasterController* planMasterController, QObject* parent)
: PlanCreator(planMasterController, tr("Custom"), QStringLiteral("/qmlimages/PlanCreator/CustomPlanCreator.png"), parent)
{
}
void CustomPlanCreator::createPlan(const QGeoCoordinate& mapCenterCoord)
{
_planMasterController->removeAll();
int seqNum = _missionController->insertSimpleMissionItem(mapCenterCoord, _missionController->visualItems()->count());
_missionController->insertSimpleMissionItem(mapCenterCoord.atDistanceAndAzimuth(50, 135), _missionController->visualItems()->count());
_missionController->insertSimpleMissionItem(mapCenterCoord.atDistanceAndAzimuth(50, -135), _missionController->visualItems()->count());
if (_planMasterController->managerVehicle()->fixedWing()) {
_missionController->insertComplexMissionItem(
MissionController::patternFWLandingName,
mapCenterCoord,
_missionController->visualItems()->count());
} else {
MissionSettingsItem* settingsItem = _missionController->visualItems()->value<MissionSettingsItem*>(0);
settingsItem->setMissionEndRTL(true);
}
_missionController->setCurrentPlanViewIndex(seqNum, false);
}
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#pragma once
#include "PlanCreator.h"
class CustomPlanCreator : public PlanCreator
{
Q_OBJECT
public:
CustomPlanCreator(PlanMasterController* planMasterController, QObject* parent = nullptr);
Q_INVOKABLE void createPlan(const QGeoCoordinate& mapCenterCoord) final;
};
......@@ -100,6 +100,7 @@ FixedWingLandingComplexItem::FixedWingLandingComplexItem(Vehicle* vehicle, bool
connect(this, &FixedWingLandingComplexItem::altitudesAreRelativeChanged, this, &FixedWingLandingComplexItem::coordinateHasRelativeAltitudeChanged);
connect(this, &FixedWingLandingComplexItem::altitudesAreRelativeChanged, this, &FixedWingLandingComplexItem::exitCoordinateHasRelativeAltitudeChanged);
connect(this, &FixedWingLandingComplexItem::landingCoordSetChanged, this, &FixedWingLandingComplexItem::readyForSaveStateChanged);
if (vehicle->apmFirmware()) {
// ArduPilot does not support camera commands
_stopTakingVideoFact.setRawValue(false);
......@@ -708,3 +709,8 @@ void FixedWingLandingComplexItem::_signalLastSequenceNumberChanged(void)
{
emit lastSequenceNumberChanged(lastSequenceNumber());
}
FixedWingLandingComplexItem::ReadyForSaveState FixedWingLandingComplexItem::readyForSaveState(void) const
{
return _landingCoordSet ? ReadyForSave : NotReadyForSaveData;
}
......@@ -74,7 +74,6 @@ public:
QString mapVisualQML (void) const final { return QStringLiteral("FWLandingPatternMapVisual.qml"); }
// Overrides from VisualMissionItem
bool dirty (void) const final { return _dirty; }
bool isSimpleItem (void) const final { return false; }
bool isStandaloneCoordinate (void) const final { return false; }
......@@ -92,6 +91,7 @@ public:
void appendMissionItems (QList<MissionItem*>& items, QObject* missionItemParent) final;
void applyNewAltitude (double newAltitude) final;
double additionalTimeDelay (void) const final { return 0; }
ReadyForSaveState readyForSaveState (void) const final;
bool coordinateHasRelativeAltitude (void) const final { return _altitudesAreRelative; }
bool exitCoordinateHasRelativeAltitude (void) const final { return _altitudesAreRelative; }
......
......@@ -51,6 +51,7 @@ const char* MissionController::_jsonMavAutopilotKey = "MAV_AUTOPILOT";
const int MissionController::_missionFileVersion = 2;
const QString MissionController::patternSurveyName (QT_TRANSLATE_NOOP("MissionController", "Survey"));
const QString MissionController::patternFWLandingName (QT_TRANSLATE_NOOP("MissionController", "Fixed Wing Landing"));
const QString MissionController::patternStructureScanName (QT_TRANSLATE_NOOP("MissionController", "Structure Scan"));
const QString MissionController::patternCorridorScanName (QT_TRANSLATE_NOOP("MissionController", "Corridor Scan"));
......@@ -64,7 +65,6 @@ MissionController::MissionController(PlanMasterController* masterController, QOb
, _firstItemsFromVehicle (false)
, _itemsRequested (false)
, _inRecalcSequence (false)
, _surveyMissionItemName (tr("Survey"))
, _appSettings (qgcApp()->toolbox()->settingsManager()->appSettings())
, _progressPct (0)
, _currentPlanViewIndex (-1)
......@@ -417,7 +417,7 @@ int MissionController::insertComplexMissionItem(QString itemName, QGeoCoordinate
}
int sequenceNumber = _nextSequenceNumber();
if (itemName == _surveyMissionItemName) {
if (itemName == patternSurveyName) {
newItem = new SurveyComplexItem(_controllerVehicle, _flyView, QString() /* kmlFile */, _visualItems /* parent */);
newItem->setCoordinate(mapCenterCoordinate);
} else if (itemName == patternFWLandingName) {
......@@ -438,7 +438,7 @@ int MissionController::insertComplexMissionItemFromKMLOrSHP(QString itemName, QS
{
ComplexMissionItem* newItem;
if (itemName == _surveyMissionItemName) {
if (itemName == patternSurveyName) {
newItem = new SurveyComplexItem(_controllerVehicle, _flyView, file, _visualItems);
} else if (itemName == patternStructureScanName) {
newItem = new StructureScanComplexItem(_controllerVehicle, _flyView, file, _visualItems);
......@@ -987,7 +987,7 @@ bool MissionController::readyForSaveSend(void) const
{
for (int i=0; i<_visualItems->count(); i++) {
VisualMissionItem* visualItem = qobject_cast<VisualMissionItem*>(_visualItems->get(i));
if (!visualItem->readyForSave()) {
if (visualItem->readyForSaveState() != VisualMissionItem::ReadyForSave) {
return false;
}
}
......@@ -2006,7 +2006,7 @@ QStringList MissionController::complexMissionItemNames(void) const
{
QStringList complexItems;
complexItems.append(_surveyMissionItemName);
complexItems.append(patternSurveyName);
complexItems.append(patternCorridorScanName);
if (_controllerVehicle->fixedWing()) {
complexItems.append(patternFWLandingName);
......@@ -2112,7 +2112,6 @@ VisualMissionItem* MissionController::currentPlanViewItem(void) const
void MissionController::setCurrentPlanViewIndex(int sequenceNumber, bool force)
{
qDebug() << "setCurrentPlanViewIndex" << sequenceNumber << force << _currentPlanViewIndex;
if(_visualItems && (force || sequenceNumber != _currentPlanViewIndex)) {
_splitSegment = nullptr;
_currentPlanViewItem = nullptr;
......
......@@ -180,7 +180,7 @@ public:
QGeoCoordinate plannedHomePosition (void) const;
VisualMissionItem* currentPlanViewItem (void) const;
double progressPct (void) const { return _progressPct; }
QString surveyComplexItemName (void) const { return _surveyMissionItemName; }
QString surveyComplexItemName (void) const { return patternSurveyName; }
QString corridorScanComplexItemName (void) const { return patternCorridorScanName; }
QString structureScanComplexItemName(void) const { return patternStructureScanName; }
......@@ -207,6 +207,7 @@ public:
static const QString patternFWLandingName;
static const QString patternStructureScanName;
static const QString patternCorridorScanName;
static const QString patternSurveyName;
signals:
void visualItemsChanged (void);
......@@ -299,7 +300,6 @@ private:
bool _itemsRequested;
bool _inRecalcSequence;
MissionFlightStatus_t _missionFlightStatus;
QString _surveyMissionItemName;
AppSettings* _appSettings;
double _progressPct;
int _currentPlanViewIndex;
......
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "PlanCreator.h"
#include "PlanMasterController.h"
PlanCreator::PlanCreator(PlanMasterController* planMasterController, QString name, QString imageResource, QObject* parent)
: QObject (parent)
, _planMasterController (planMasterController)
, _missionController (planMasterController->missionController())
, _name (name)
, _imageResource (imageResource)
{
}
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#pragma once
#include <QObject>
#include <QString>
#include "QGeoCoordinate"
class PlanMasterController;
class MissionController;
/// Base class for PlanCreator objects which are used to create a full plan in a single step.
class PlanCreator : public QObject
{
Q_OBJECT
public:
PlanCreator(PlanMasterController* planMasterController, QString name, QString imageResource, QObject* parent = nullptr);
Q_PROPERTY(QString name MEMBER _name CONSTANT)
Q_PROPERTY(QString imageResource MEMBER _imageResource CONSTANT)
Q_INVOKABLE virtual void createPlan(const QGeoCoordinate& mapCenterCoord) = 0;
protected:
PlanMasterController* _planMasterController;
MissionController* _missionController;
QString _name;
QString _imageResource;
};
......@@ -16,6 +16,10 @@
#include "JsonHelper.h"
#include "MissionManager.h"
#include "KML.h"
#include "SurveyPlanCreator.h"
#include "StructureScanPlanCreator.h"
#include "CorridorScanPlanCreator.h"
#include "CustomPlanCreator.h"
#if defined(QGC_AIRMAP_ENABLED)
#include "AirspaceFlightPlanProvider.h"
#endif
......@@ -50,6 +54,7 @@ PlanMasterController::PlanMasterController(QObject* parent)
, _sendGeoFence (false)
, _sendRallyPoints (false)
, _deleteWhenSendCompleted (false)
, _planCreators (nullptr)
{
connect(&_missionController, &MissionController::dirtyChanged, this, &PlanMasterController::dirtyChanged);
connect(&_geoFenceController, &GeoFenceController::dirtyChanged, this, &PlanMasterController::dirtyChanged);
......@@ -79,6 +84,8 @@ void PlanMasterController::start(bool flyView)
connect(_multiVehicleMgr, &MultiVehicleManager::activeVehicleChanged, this, &PlanMasterController::_activeVehicleChanged);
_activeVehicleChanged(_multiVehicleMgr->activeVehicle());
_updatePlanCreatorsList();
#if defined(QGC_AIRMAP_ENABLED)
//-- This assumes there is one single instance of PlanMasterController in edit mode.
if(!flyView) {
......@@ -115,12 +122,15 @@ void PlanMasterController::_activeVehicleChanged(Vehicle* activeVehicle)
disconnect(_managerVehicle->missionManager(), &MissionManager::sendComplete, this, &PlanMasterController::_sendMissionComplete);
disconnect(_managerVehicle->geoFenceManager(), &GeoFenceManager::sendComplete, this, &PlanMasterController::_sendGeoFenceComplete);
disconnect(_managerVehicle->rallyPointManager(), &RallyPointManager::sendComplete, this, &PlanMasterController::_sendRallyPointsComplete);
disconnect(_managerVehicle, &Vehicle::vehicleTypeChanged, this, &PlanMasterController::_updatePlanCreatorsList);
}
bool newOffline = false;
if (activeVehicle == nullptr) {
// Since there is no longer an active vehicle we use the offline controller vehicle as the manager vehicle
_managerVehicle = _controllerVehicle;
// The vehicle type can change on the offline vehicle. Keep the creators list in sync with that.
connect(_managerVehicle, &Vehicle::vehicleTypeChanged, this, &PlanMasterController::_updatePlanCreatorsList);
newOffline = true;
} else {
newOffline = false;
......@@ -172,6 +182,8 @@ void PlanMasterController::_activeVehicleChanged(Vehicle* activeVehicle)
_showPlanFromManagerVehicle();
}
}
_updatePlanCreatorsList();
}
void PlanMasterController::loadFromVehicle(void)
......@@ -583,3 +595,26 @@ bool PlanMasterController::isEmpty(void) const
_geoFenceController.isEmpty() &&
_rallyPointController.isEmpty();
}
void PlanMasterController::_updatePlanCreatorsList(void)
{
if (!_flyView) {
if (!_planCreators) {
_planCreators = new QmlObjectListModel(this);
_planCreators->append(new SurveyPlanCreator(this, this));
_planCreators->append(new CorridorScanPlanCreator(this, this));
_planCreators->append(new CustomPlanCreator(this, this));
emit planCreatorsChanged(_planCreators);
}
if (_managerVehicle->fixedWing()) {
if (_planCreators->count() == 4) {
_planCreators->removeAt(_planCreators->count() - 2);
}
} else {
if (_planCreators->count() != 4) {
_planCreators->insert(_planCreators->count() - 1, new StructureScanPlanCreator(this, this));
}
}
}
}
......@@ -17,6 +17,7 @@
#include "Vehicle.h"
#include "MultiVehicleManager.h"
#include "QGCLoggingCategory.h"
#include "QmlObjectListModel.h"
Q_DECLARE_LOGGING_CATEGORY(PlanMasterControllerLog)
......@@ -32,7 +33,6 @@ public:
Q_PROPERTY(MissionController* missionController READ missionController CONSTANT)
Q_PROPERTY(GeoFenceController* geoFenceController READ geoFenceController CONSTANT)
Q_PROPERTY(RallyPointController* rallyPointController READ rallyPointController CONSTANT)
Q_PROPERTY(Vehicle* controllerVehicle MEMBER _controllerVehicle CONSTANT)
Q_PROPERTY(bool offline READ offline NOTIFY offlineChanged) ///< true: controller is not connected to an active vehicle
Q_PROPERTY(bool containsItems READ containsItems NOTIFY containsItemsChanged) ///< true: Elemement is non-empty
......@@ -41,9 +41,9 @@ public:
Q_PROPERTY(QString fileExtension READ fileExtension CONSTANT) ///< File extension for missions
Q_PROPERTY(QString kmlFileExtension READ kmlFileExtension CONSTANT)
Q_PROPERTY(QString currentPlanFile READ currentPlanFile NOTIFY currentPlanFileChanged)
///< kml file extension for missions
Q_PROPERTY(QStringList loadNameFilters READ loadNameFilters CONSTANT) ///< File filter list loading plan files
Q_PROPERTY(QStringList saveNameFilters READ saveNameFilters CONSTANT) ///< File filter list saving plan files
Q_PROPERTY(QmlObjectListModel* planCreators MEMBER _planCreators NOTIFY planCreatorsChanged)
/// Should be called immediately upon Component.onCompleted.
Q_INVOKABLE void start(bool flyView);
......@@ -103,17 +103,19 @@ signals:
void dirtyChanged (bool dirty);
void offlineChanged (bool offlineEditing);
void currentPlanFileChanged ();
void planCreatorsChanged (QmlObjectListModel* planCreators);
private slots:
void _activeVehicleChanged(Vehicle* activeVehicle);
void _loadMissionComplete(void);
void _loadGeoFenceComplete(void);
void _loadRallyPointsComplete(void);
void _sendMissionComplete(void);
void _sendGeoFenceComplete(void);
void _sendRallyPointsComplete(void);
void _activeVehicleChanged (Vehicle* activeVehicle);
void _loadMissionComplete (void);
void _loadGeoFenceComplete (void);
void _loadRallyPointsComplete (void);
void _sendMissionComplete (void);
void _sendGeoFenceComplete (void);
void _sendRallyPointsComplete (void);
void _updatePlanCreatorsList (void);
#if defined(QGC_AIRMAP_ENABLED)
void _startFlightPlanning(void);
void _startFlightPlanning (void);
#endif
private:
......@@ -133,5 +135,6 @@ private:
bool _sendRallyPoints;
QString _currentPlanFile;
bool _deleteWhenSendCompleted;
QmlObjectListModel* _planCreators;
};
......@@ -51,7 +51,10 @@ void QGCMapPolygon::_init(void)
{
connect(&_polygonModel, &QmlObjectListModel::dirtyChanged, this, &QGCMapPolygon::_polygonModelDirtyChanged);
connect(&_polygonModel, &QmlObjectListModel::countChanged, this, &QGCMapPolygon::_polygonModelCountChanged);
connect(this, &QGCMapPolygon::pathChanged, this, &QGCMapPolygon::_updateCenter);
connect(this, &QGCMapPolygon::countChanged, this, &QGCMapPolygon::isValidChanged);
connect(this, &QGCMapPolygon::countChanged, this, &QGCMapPolygon::isEmptyChanged);
}
const QGCMapPolygon& QGCMapPolygon::operator=(const QGCMapPolygon& other)
......
......@@ -36,8 +36,8 @@ public:
Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged)
Q_PROPERTY(bool centerDrag READ centerDrag WRITE setCenterDrag NOTIFY centerDragChanged)
Q_PROPERTY(bool interactive READ interactive WRITE setInteractive NOTIFY interactiveChanged)
Q_PROPERTY(bool isValid READ isValid NOTIFY countChanged)
Q_PROPERTY(bool empty READ empty NOTIFY countChanged)
Q_PROPERTY(bool isValid READ isValid NOTIFY isValidChanged)
Q_PROPERTY(bool empty READ empty NOTIFY isEmptyChanged)
Q_INVOKABLE void clear(void);
Q_INVOKABLE void appendVertex(const QGeoCoordinate& coordinate);
......@@ -122,6 +122,8 @@ signals:
void centerChanged (QGeoCoordinate center);
void centerDragChanged (bool centerDrag);
void interactiveChanged (bool interactive);
bool isValidChanged (void);
bool isEmptyChanged (void);
private slots:
void _polygonModelCountChanged(int count);
......
......@@ -516,13 +516,11 @@ Item {
id: toolbarComponent
PlanEditToolbar {
x: mapControl.centerViewport.left + _margins
y: mapControl.centerViewport.top + _margins
width: mapControl.centerViewport.width - (_margins * 2)
x: mapControl.centerViewport.left
y: mapControl.centerViewport.top
width: mapControl.centerViewport.width
z: QGroundControl.zOrderMapItems + 2
property real _margins: ScreenTools.defaultFontPixelWidth
QGCButton {
_horizontalPadding: 0
text: qsTr("Basic")
......
......@@ -61,6 +61,9 @@ void QGCMapPolyline::_init(void)
{
connect(&_polylineModel, &QmlObjectListModel::dirtyChanged, this, &QGCMapPolyline::_polylineModelDirtyChanged);
connect(&_polylineModel, &QmlObjectListModel::countChanged, this, &QGCMapPolyline::_polylineModelCountChanged);
connect(this, &QGCMapPolyline::countChanged, this, &QGCMapPolyline::isValidChanged);
connect(this, &QGCMapPolyline::countChanged, this, &QGCMapPolyline::isEmptyChanged);
}
void QGCMapPolyline::clear(void)
......
......@@ -30,8 +30,8 @@ public:
Q_PROPERTY(QmlObjectListModel* pathModel READ qmlPathModel CONSTANT)
Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged)
Q_PROPERTY(bool interactive READ interactive WRITE setInteractive NOTIFY interactiveChanged)
Q_PROPERTY(bool isValid READ isValid NOTIFY countChanged)
Q_PROPERTY(bool empty READ empty NOTIFY countChanged)
Q_PROPERTY(bool isValid READ isValid NOTIFY isValidChanged)
Q_PROPERTY(bool empty READ empty NOTIFY isEmptyChanged)
Q_INVOKABLE void clear(void);
Q_INVOKABLE void appendVertex(const QGeoCoordinate& coordinate);
......@@ -104,6 +104,8 @@ signals:
void dirtyChanged (bool dirty);
void cleared (void);
void interactiveChanged (bool interactive);
void isValidChanged (void);
void isEmptyChanged (void);
private slots:
void _polylineModelCountChanged(int count);
......
......@@ -314,13 +314,11 @@ Item {
id: toolbarComponent
PlanEditToolbar {
x: mapControl.centerViewport.left + _margins
y: mapControl.centerViewport.top + _margins
width: mapControl.centerViewport.width - (_margins * 2)
x: mapControl.centerViewport.left
y: mapControl.centerViewport.top
width: mapControl.centerViewport.width
z: QGroundControl.zOrderMapItems + 2
property real _margins: ScreenTools.defaultFontPixelWidth
QGCButton {
_horizontalPadding: 0
text: qsTr("Basic")
......
......@@ -710,25 +710,24 @@ void SimpleMissionItem::_terrainAltChanged(void)
}
if (qIsNaN(terrainAltitude())) {
qDebug() << "1";
// Set NaNs to signal we are waiting on terrain data
_missionItem._param7Fact.setRawValue(qQNaN());
_amslAltAboveTerrainFact.setRawValue(qQNaN());
} else {
double newAboveTerrain = terrainAltitude() + _altitudeFact.rawValue().toDouble();
double oldAboveTerrain = _amslAltAboveTerrainFact.rawValue().toDouble();
qDebug() << "2" << newAboveTerrain << oldAboveTerrain;
if (qIsNaN(oldAboveTerrain) || !qFuzzyCompare(newAboveTerrain, oldAboveTerrain)) {
qDebug() << "3";
_missionItem._param7Fact.setRawValue(newAboveTerrain);
_amslAltAboveTerrainFact.setRawValue(newAboveTerrain);
}
}
emit readyForSaveStateChanged();
}
bool SimpleMissionItem::readyForSave(void) const
SimpleMissionItem::ReadyForSaveState SimpleMissionItem::readyForSaveState(void) const
{
return !specifiesAltitude() || !qIsNaN(_missionItem._param7Fact.rawValue().toDouble());
bool terrainReady = !specifiesAltitude() || !qIsNaN(_missionItem._param7Fact.rawValue().toDouble());
return terrainReady ? ReadyForSave : NotReadyForSaveTerrain;
}