Commit 5c9a40f9 authored by olliw42's avatar olliw42

Merge branch 'master' into pr-compid-2nd

parents 4d02fe4e d6c3a1eb
......@@ -127,7 +127,7 @@
<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/BlankPlanCreator.png">src/MissionManager/BlankPlanCreator.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>
......
......@@ -592,7 +592,7 @@ HEADERS += \
src/MissionManager/ComplexMissionItem.h \
src/MissionManager/CorridorScanComplexItem.h \
src/MissionManager/CorridorScanPlanCreator.h \
src/MissionManager/CustomPlanCreator.h \
src/MissionManager/BlankPlanCreator.h \
src/MissionManager/FixedWingLandingComplexItem.h \
src/MissionManager/GeoFenceController.h \
src/MissionManager/GeoFenceManager.h \
......@@ -823,7 +823,7 @@ SOURCES += \
src/MissionManager/ComplexMissionItem.cc \
src/MissionManager/CorridorScanComplexItem.cc \
src/MissionManager/CorridorScanPlanCreator.cc \
src/MissionManager/CustomPlanCreator.cc \
src/MissionManager/BlankPlanCreator.cc \
src/MissionManager/FixedWingLandingComplexItem.cc \
src/MissionManager/GeoFenceController.cc \
src/MissionManager/GeoFenceManager.cc \
......
......@@ -102,7 +102,6 @@
<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>
......
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-89 46 72 72" enable-background="new -89 46 72 72" xml:space="preserve">
<rect x="-78.911" y="46" fill="#FFFFFF" width="51.822" height="10.66"/>
<path fill="#FFFFFF" d="M-27.089,59.781h-51.822V118h51.822L-27.089,59.781L-27.089,59.781z M-33.927,110.332h-7.17V68.068h7.17
V110.332z M-49.416,110.332h-7.17V68.068h7.17V110.332z M-64.245,110.332h-7.17V68.068h7.17V110.332z"/>
</svg>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
viewBox="-89 46 72 72"
enable-background="new -89 46 72 72"
xml:space="preserve"
sodipodi:docname="TrashDelete.svg"
inkscape:version="0.92.4 (f8dce91, 2019-08-02)"><metadata
id="metadata3771"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs3769"><inkscape:path-effect
effect="bspline"
id="path-effect3883"
is_visible="true"
weight="50"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" /><inkscape:path-effect
effect="bspline"
id="path-effect3874"
is_visible="true"
weight="10"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" /><filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter3830"
x="-1.2740651"
width="3.5481301"
y="-1.1340731"
height="3.2681461"><feBlend
inkscape:collect="always"
mode="lighten"
in2="BackgroundImage"
id="feBlend3834" /></filter><inkscape:path-effect
effect="bspline"
id="path-effect3883-3"
is_visible="true"
weight="50"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1735"
inkscape:window-height="1038"
id="namedview3767"
showgrid="false"
inkscape:pagecheckerboard="true"
inkscape:zoom="2.9861111"
inkscape:cx="-39.595586"
inkscape:cy="61.570647"
inkscape:window-x="2103"
inkscape:window-y="20"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1" />
<path
style="fill:#ffffff;stroke-width:1.1104244"
d="m -81.92009,46.487004 c 0.487005,-0.487004 57.353171,-0.487004 57.840175,0 0.487005,0.487005 2.055265,2.055266 2.54227,2.54227 0.487005,0.487005 0.487005,4.114447 0,4.601451 -0.487004,0.487005 -2.055265,2.055266 -2.54227,2.54227 -0.487004,0.487005 -57.35317,0.487005 -57.840175,0 -0.487004,-0.487004 -2.055265,-2.055265 -2.54227,-2.54227 -0.487004,-0.487004 -0.487004,-4.114446 10e-7,-4.601451 0.487005,-0.487005 2.055265,-2.055265 2.542269,-2.54227 z"
id="rect3762"
inkscape:path-effect="#path-effect3883"
inkscape:original-d="m -81.433085,46 h 56.866166 c 1.948018,0 3.516279,1.56826 3.516279,3.516279 v 3.627442 c 0,1.948018 -1.568261,3.516279 -3.516279,3.516279 h -56.866166 c -1.948018,0 -3.516279,-1.568261 -3.516279,-3.516279 V 49.516279 C -84.949364,47.56826 -83.381103,46 -81.433085,46 Z"
inkscape:connector-curvature="0"
transform="matrix(0.83070712,0,0,0.82950228,-8.6376373,16.905515)" />
<g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="Layer 1"
style="display:inline" /><path
d="m -29.6796,62.69245 c -2.5906,-2.91145 -44.0482,-2.91145 -46.6398,0 -2.5916,2.91145 -2.5916,49.48665 0,52.3971 2.5916,2.91045 44.0492,2.91045 46.6398,0 2.5906,-2.91045 2.5906,-49.48565 0,-52.3971 z m -4.6054,45.52685 c -0.358,2.1127 -6.094,2.1127 -6.453,0 -0.359,-2.1127 -0.359,-35.9239 0,-38.0376 0.359,-2.1137 6.095,-2.1137 6.453,0 0.358,2.1137 0.358,35.9249 0,38.0376 z m -15.489,0 c -0.358,2.1127 -6.094,2.1127 -6.453,0 -0.359,-2.1127 -0.359,-35.9239 0,-38.0376 0.359,-2.1137 6.095,-2.1137 6.453,0 0.358,2.1137 0.358,35.9249 0,38.0376 z m -14.829,0 c -0.358,2.1127 -6.094,2.1127 -6.453,0 -0.359,-2.1127 -0.359,-35.9239 0,-38.0376 0.359,-2.1137 6.095,-2.1137 6.453,0 0.358,2.1137 0.358,35.9249 0,38.0376 z"
id="path3764"
inkscape:connector-curvature="0"
style="fill:#ffffff;filter:url(#filter3830)"
inkscape:path-effect="#path-effect3874"
inkscape:original-d="m -27.089,59.781 c -5.1812,10e-4 -46.6388,10e-4 -51.822,0 0.001,5.8229 0.001,52.3981 0,58.219 5.1832,0.001 46.6408,0.001 51.822,0 10e-4,-5.8209 10e-4,-52.3961 0,-58.219 z m -6.838,50.551 c -0.716,0.001 -6.452,0.001 -7.17,0 0.001,-4.2254 0.001,-38.0366 0,-42.264 0.718,0.001 6.454,0.001 7.17,0 10e-4,4.2274 10e-4,38.0386 0,42.264 z m -15.489,0 c -0.716,0.001 -6.452,0.001 -7.17,0 10e-4,-4.2254 10e-4,-38.0366 0,-42.264 0.718,0.001 6.454,0.001 7.17,0 10e-4,4.2274 10e-4,38.0386 0,42.264 z m -14.829,0 c -0.716,0.001 -6.452,0.001 -7.17,0 0.001,-4.2254 0.001,-38.0366 0,-42.264 0.718,0.001 6.454,0.001 7.17,0 0.001,4.2274 0.001,38.0386 0,42.264 z"
transform="matrix(1,0,0,0.76115058,0.66964846,21.432082)" /><g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="Layer 3" /><g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2" /><path
style="fill:#ffffff;stroke-width:1.1104244"
d="m -81.92009,46.487004 c 0.487005,-0.487004 57.353171,-0.487004 57.840175,0 0.487005,0.487005 2.055265,2.055266 2.54227,2.54227 0.487005,0.487005 0.487005,4.114447 0,4.601451 -0.487004,0.487005 -2.055265,2.055266 -2.54227,2.54227 -0.487004,0.487005 -57.35317,0.487005 -57.840175,0 -0.487004,-0.487004 -2.055265,-2.055265 -2.54227,-2.54227 -0.487004,-0.487004 -0.487004,-4.114446 10e-7,-4.601451 0.487005,-0.487005 2.055265,-2.055265 2.542269,-2.54227 z"
id="rect3762-6"
inkscape:path-effect="#path-effect3883-3"
inkscape:original-d="m -81.433085,46 h 56.866166 c 1.948018,0 3.516279,1.56826 3.516279,3.516279 v 3.627442 c 0,1.948018 -1.568261,3.516279 -3.516279,3.516279 h -56.866166 c -1.948018,0 -3.516279,-1.568261 -3.516279,-3.516279 V 49.516279 C -84.949364,47.56826 -83.381103,46 -81.433085,46 Z"
inkscape:connector-curvature="0"
transform="matrix(0.20525298,0,0,0.52828964,-41.786708,26.697818)" /></svg>
\ No newline at end of file
......@@ -22,11 +22,12 @@ Item {
anchors.fill: parent
anchors.margins: ScreenTools.defaultFontPixelWidth
property var curVehicle: controller ? controller.activeVehicle : null
property int curMessageIndex:0
property var curMessage: curVehicle && curVehicle.messages.count ? curVehicle.messages.get(curMessageIndex) : null
property int curCompID: 0
property bool selectionValid: false
property var curVehicle: controller ? controller.activeVehicle : null
property int curMessageIndex: 0
property var curMessage: curVehicle && curVehicle.messages.count ? curVehicle.messages.get(curMessageIndex) : null
property int curCompID: 0
property bool selectionValid: false
property real maxButtonWidth: 0
MAVLinkInspectorController {
id: controller
......@@ -76,11 +77,13 @@ Item {
anchors.topMargin: ScreenTools.defaultFontPixelHeight
anchors.bottom: parent.bottom
anchors.left: parent.left
width: buttonCol.width
contentWidth: buttonCol.width
width: maxButtonWidth
contentWidth: width
contentHeight: buttonCol.height
ColumnLayout {
id: buttonCol
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelHeight * 0.25
Repeater {
model: curVehicle ? curVehicle.messages : []
......@@ -94,7 +97,7 @@ Item {
selectionValid = true
curMessageIndex = index
}
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 40
Layout.fillWidth: true
}
}
}
......
......@@ -439,6 +439,11 @@
<output name="MAIN3">motor 3</output>
<output name="MAIN4">motor 4</output>
</airframe>
<airframe id="4500" maintainer="Oleg Kalachev &lt;okalachev@gmail.com&gt;" name="COEX Clover 4">
<class>Copter</class>
<maintainer>Oleg Kalachev &lt;okalachev@gmail.com&gt;</maintainer>
<type>Quadrotor x</type>
</airframe>
<airframe id="4900" maintainer="Dennis Shtatov &lt;densht@gmail.com&gt;" name="Crazyflie 2">
<class>Copter</class>
<maintainer>Dennis Shtatov &lt;densht@gmail.com&gt;</maintainer>
......
......@@ -131,6 +131,63 @@ ParameterManager::~ParameterManager()
delete _parameterMetaData;
}
void ParameterManager::_updateProgressBar(void)
{
int waitingReadParamIndexCount = 0;
int waitingReadParamNameCount = 0;
int waitingWriteParamCount = 0;
for (int compId: _waitingReadParamIndexMap.keys()) {
waitingReadParamIndexCount += _waitingReadParamIndexMap[compId].count();
}
for(int compId: _waitingReadParamNameMap.keys()) {
waitingReadParamNameCount += _waitingReadParamNameMap[compId].count();
}
for(int compId: _waitingWriteParamNameMap.keys()) {
waitingWriteParamCount += _waitingWriteParamNameMap[compId].count();
}
if (waitingReadParamIndexCount == 0) {
if (_readParamIndexProgressActive) {
_readParamIndexProgressActive = false;
_setLoadProgress(0.0);
return;
}
} else {
_readParamIndexProgressActive = true;
_setLoadProgress((double)(_totalParamCount - waitingReadParamIndexCount) / (double)_totalParamCount);
return;
}
if (waitingWriteParamCount == 0) {
if (_writeParamProgressActive) {
_writeParamProgressActive = false;
_waitingWriteParamBatchCount = 0;
_setLoadProgress(0.0);
emit pendingWritesChanged(false);
return;
}
} else {
_writeParamProgressActive = true;
_setLoadProgress((double)(qMax(_waitingWriteParamBatchCount - waitingWriteParamCount, 1)) / (double)(_waitingWriteParamBatchCount + 1));
emit pendingWritesChanged(true);
return;
}
if (waitingReadParamNameCount == 0) {
if (_readParamNameProgressActive) {
_readParamNameProgressActive = false;
_waitingReadParamNameBatchCount = 0;
_setLoadProgress(0.0);
return;
}
} else {
_readParamNameProgressActive = true;
_setLoadProgress((double)(qMax(_waitingReadParamNameBatchCount - waitingReadParamNameCount, 1)) / (double)(_waitingReadParamNameBatchCount + 1));
return;
}
}
/// Called whenever a parameter is updated or first seen.
void ParameterManager::_parameterUpdate(int vehicleId, int componentId, QString parameterName, int parameterCount, int parameterId, int mavType, QVariant value)
{
......@@ -299,17 +356,8 @@ void ParameterManager::_parameterUpdate(int vehicleId, int componentId, QString
qCDebug(ParameterManagerVerbose1Log) << _logVehiclePrefix(-1) << "Not restarting _waitingParamTimeoutTimer (all requests satisfied)";
}
}
// Update progress bar for waiting reads
if (readWaitingParamCount == 0) {
// We are no longer waiting for any reads to complete
if (_prevWaitingReadParamIndexCount + _prevWaitingReadParamNameCount != 0) {
// Set progress to 0 if not already there
_setLoadProgress(0.0);
}
} else {
_setLoadProgress((double)(_totalParamCount - readWaitingParamCount) / (double)_totalParamCount);
}
\
_updateProgressBar();
// Get parameter set version
if (!_versionParam.isEmpty() && _versionParam == parameterName) {
......@@ -425,8 +473,13 @@ void ParameterManager::_valueUpdated(const QVariant& value)
_dataMutex.lock();
if (_waitingWriteParamNameMap.contains(componentId)) {
_waitingWriteParamNameMap[componentId].remove(name); // Remove any old entry
_waitingWriteParamNameMap[componentId][name] = 0; // Add new entry and set retry count
if (_waitingWriteParamNameMap[componentId].contains(name)) {
_waitingWriteParamNameMap[componentId].remove(name);
} else {
_waitingWriteParamBatchCount++;
}
_waitingWriteParamNameMap[componentId][name] = 0; // Add new entry and set retry count
_updateProgressBar();
_waitingParamTimeoutTimer.start();
_saveRequired = true;
} else {
......@@ -502,8 +555,13 @@ void ParameterManager::refreshParameter(int componentId, const QString& paramNam
if (_waitingReadParamNameMap.contains(componentId)) {
QString mappedParamName = _remapParamNameToVersion(paramName);
_waitingReadParamNameMap[componentId].remove(mappedParamName); // Remove old wait entry if there
if (_waitingReadParamNameMap[componentId].contains(mappedParamName)) {
_waitingReadParamNameMap[componentId].remove(mappedParamName);
} else {
_waitingReadParamNameBatchCount++;
}
_waitingReadParamNameMap[componentId][mappedParamName] = 0; // Add new wait entry and update retry count
_updateProgressBar();
qCDebug(ParameterManagerLog) << _logVehiclePrefix(componentId) << "restarting _waitingParamTimeout";
_waitingParamTimeoutTimer.start();
} else {
......@@ -978,7 +1036,8 @@ void ParameterManager::_tryCacheHashLoad(int vehicleId, int componentId, QVarian
QString ParameterManager::readParametersFromStream(QTextStream& stream)
{
QString errors;
QString missingErrors;
QString typeErrors;
while (!stream.atEnd()) {
QString line = stream.readLine();
......@@ -997,18 +1056,18 @@ QString ParameterManager::readParametersFromStream(QTextStream& stream)
if (!parameterExists(componentId, paramName)) {
QString error;
error = QString("Skipped parameter %1:%2 - does not exist on this vehicle\n").arg(componentId).arg(paramName);
errors += error;
qCDebug(ParameterManagerLog) << error;
error += QStringLiteral("%1:%2 ").arg(componentId).arg(paramName);
missingErrors += error;
qCDebug(ParameterManagerLog) << QStringLiteral("Skipped due to missing: %1").arg(error);
continue;
}
Fact* fact = getParameter(componentId, paramName);
if (fact->type() != _mavTypeToFactType((MAV_PARAM_TYPE)mavType)) {
QString error;
error = QString("Skipped parameter %1:%2 - type mismatch %3:%4\n").arg(componentId).arg(paramName).arg(fact->type()).arg(_mavTypeToFactType((MAV_PARAM_TYPE)mavType));
errors += error;
qCDebug(ParameterManagerLog) << error;
error = QStringLiteral("%1:%2 ").arg(componentId).arg(paramName);
typeErrors += error;
qCDebug(ParameterManagerLog) << QStringLiteral("Skipped due to type mismatch: %1").arg(error);
continue;
}
......@@ -1018,6 +1077,16 @@ QString ParameterManager::readParametersFromStream(QTextStream& stream)
}
}
QString errors;
if (!missingErrors.isEmpty()) {
errors = tr("Parameters not loaded since they are not currently on the vehicle: %1\n").arg(missingErrors);
}
if (!typeErrors.isEmpty()) {
errors += tr("Parameters not loaded due to type mismatch: %1").arg(typeErrors);
}
return errors;
}
......@@ -1661,11 +1730,24 @@ QString ParameterManager::_logVehiclePrefix(int componentId)
void ParameterManager::_setLoadProgress(double loadProgress)
{
_loadProgress = loadProgress;
emit loadProgressChanged(static_cast<float>(loadProgress));
if (_loadProgress != loadProgress) {
_loadProgress = loadProgress;
emit loadProgressChanged(static_cast<float>(loadProgress));
}
}
QList<int> ParameterManager::componentIds(void)
{
return _paramCountMap.keys();
}
bool ParameterManager::pendingWrites(void)
{
for (int compId: _waitingWriteParamNameMap.keys()) {
if (_waitingWriteParamNameMap[compId].count()) {
return true;
}
}
return false;
}
......@@ -39,6 +39,7 @@ public:
Q_PROPERTY(bool parametersReady READ parametersReady NOTIFY parametersReadyChanged) ///< true: Parameters are ready for use
Q_PROPERTY(bool missingParameters READ missingParameters NOTIFY missingParametersChanged) ///< true: Parameters are missing from firmware response, false: all parameters received from firmware
Q_PROPERTY(double loadProgress READ loadProgress NOTIFY loadProgressChanged)
Q_PROPERTY(bool pendingWrites READ pendingWrites NOTIFY pendingWritesChanged) ///< true: There are still pending write updates against the vehicle
bool parametersReady (void) const { return _parametersReady; }
bool missingParameters (void) const { return _missingParameters; }
......@@ -113,12 +114,15 @@ public:
/// @return true: success, false: failure (errorString set)
bool loadFromJson(const QJsonObject& json, bool required, QString& errorString);
bool pendingWrites(void);
Vehicle* vehicle(void) { return _vehicle; }
signals:
void parametersReadyChanged(bool parametersReady);
void missingParametersChanged(bool missingParameters);
void loadProgressChanged(float value);
void parametersReadyChanged (bool parametersReady);
void missingParametersChanged (bool missingParameters);
void loadProgressChanged (float value);
void pendingWritesChanged (bool pendingWrites);
protected:
Vehicle* _vehicle;
......@@ -149,6 +153,7 @@ private:
QString _logVehiclePrefix(int componentId);
void _setLoadProgress(double loadProgress);
bool _fillIndexBatchQueue(bool waitingParamTimeout);
void _updateProgressBar(void);
MAV_PARAM_TYPE _factTypeToMavType(FactMetaData::ValueType_t factType);
FactMetaData::ValueType_t _mavTypeToFactType(MAV_PARAM_TYPE mavType);
......@@ -183,9 +188,13 @@ private:
QMap<int /* component id */, QMap<QString /* param name */, bool /* seen */>> _debugCacheParamSeen;
// Wait counts from previous parameter update cycle
int _prevWaitingReadParamIndexCount;
int _prevWaitingReadParamNameCount;
int _prevWaitingWriteParamNameCount;
int _prevWaitingReadParamIndexCount;
int _prevWaitingReadParamNameCount;
int _prevWaitingWriteParamNameCount;
bool _readParamIndexProgressActive = false;
bool _readParamNameProgressActive = false;
bool _writeParamProgressActive = false;
static const int _maxInitialRequestListRetry = 4; ///< Maximum retries for request list
int _initialRequestRetryCount; ///< Current retry count for request list
......@@ -202,7 +211,9 @@ private:
QMap<int, QMap<QString, int> > _waitingWriteParamNameMap; ///< Key: Component id, Value: Map { Key: parameter name still waiting for, Value: retry count }
QMap<int, QList<int> > _failedReadParamIndexMap; ///< Key: Component id, Value: failed parameter index
int _totalParamCount; ///< Number of parameters across all components
int _totalParamCount; ///< Number of parameters across all components
int _waitingWriteParamBatchCount = 0; ///< Number of parameters which are batched up waiting on write responses
int _waitingReadParamNameBatchCount = 0; ///< Number of parameters which are batched up waiting on read responses
QTimer _initialRequestTimeoutTimer;
QTimer _waitingParamTimeoutTimer;
......
/****************************************************************************
*
* (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 "BlankPlanCreator.h"
#include "PlanMasterController.h"
#include "MissionSettingsItem.h"
#include "FixedWingLandingComplexItem.h"
BlankPlanCreator::BlankPlanCreator(PlanMasterController* planMasterController, QObject* parent)
: PlanCreator(planMasterController, tr("Blank"), QStringLiteral("/qmlimages/PlanCreator/BlankPlanCreator.png"), parent)
{
}
void BlankPlanCreator::createPlan(const QGeoCoordinate& /*mapCenterCoord*/)
{
_planMasterController->removeAll();
}
......@@ -11,12 +11,12 @@
#include "PlanCreator.h"
class CustomPlanCreator : public PlanCreator
class BlankPlanCreator : public PlanCreator
{
Q_OBJECT
public:
CustomPlanCreator(PlanMasterController* planMasterController, QObject* parent = nullptr);
BlankPlanCreator(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"
#include "FixedWingLandingComplexItem.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();
VisualMissionItem* takeoffItem = _missionController->insertSimpleMissionItem(mapCenterCoord, -1);
takeoffItem->setWizardMode(true);
_missionController->insertSimpleMissionItem(mapCenterCoord.atDistanceAndAzimuth(50, 135), -1);
_missionController->insertSimpleMissionItem(mapCenterCoord.atDistanceAndAzimuth(50, -135),-1);
if (_planMasterController->managerVehicle()->fixedWing()) {
FixedWingLandingComplexItem* landingItem = qobject_cast<FixedWingLandingComplexItem*>(_missionController->insertComplexMissionItem(MissionController::patternFWLandingName, mapCenterCoord, -1));
landingItem->setWizardMode(true);
landingItem->setLoiterDragAngleOnly(true);
} else {
MissionSettingsItem* settingsItem = _missionController->visualItems()->value<MissionSettingsItem*>(0);
settingsItem->setMissionEndRTL(true);
}
_missionController->setCurrentPlanViewIndex(takeoffItem->sequenceNumber(), true);
}
......@@ -19,7 +19,7 @@
#include "SurveyPlanCreator.h"
#include "StructureScanPlanCreator.h"
#include "CorridorScanPlanCreator.h"
#include "CustomPlanCreator.h"
#include "BlankPlanCreator.h"
#if defined(QGC_AIRMAP_ENABLED)
#include "AirspaceFlightPlanProvider.h"
#endif
......@@ -601,19 +601,19 @@ void PlanMasterController::_updatePlanCreatorsList(void)
if (!_flyView) {
if (!_planCreators) {
_planCreators = new QmlObjectListModel(this);
_planCreators->append(new BlankPlanCreator(this, 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);
_planCreators->removeAt(_planCreators->count() - 1);
}
} else {
if (_planCreators->count() != 4) {
_planCreators->insert(_planCreators->count() - 1, new StructureScanPlanCreator(this, this));
_planCreators->append(new StructureScanPlanCreator(this, this));
}
}
}
......
......@@ -538,7 +538,7 @@ Item {
QGCButton {
_horizontalPadding: 0
text: _traceMode ? qsTr("Done Tracing") : qsTr("Trace Polygon")
text: _traceMode ? qsTr("Done Tracing") : qsTr("Trace")
onClicked: {
if (_traceMode) {
if (mapPolygon.count < 3) {
......
......@@ -38,7 +38,7 @@ Item {
property real _zorderSplitHandle: QGroundControl.zOrderMapItems + 2
property var _savedVertices: [ ]
readonly property string _corridorToolsText: qsTr("Corridor Tools")
readonly property string _corridorToolsText: qsTr("Polyline Tools")
readonly property string _traceText: qsTr("Click in the map to add vertices. Click 'Done Tracing' when finished.")
function _addCommonVisuals() {
......
......@@ -24,6 +24,8 @@ Column {
SectionHeader {
id: cameraSectionHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Camera")
checked: false
}
......
......@@ -65,7 +65,7 @@ Rectangle {
QGCLabel {
Layout.fillWidth: true
wrapMode: Text.WordWrap
text: qsTr("Use the Corridor Tools to create the polyline which defines the corridor.")
text: qsTr("Use the Polyline Tools to create the polyline which defines the corridor.")
}
QGCButton {
......@@ -124,8 +124,10 @@ Rectangle {
}
SectionHeader {
id: corridorHeader
text: qsTr("Corridor")
id: corridorHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Corridor")
}
GridLayout {
......@@ -182,9 +184,11 @@ Rectangle {
}
SectionHeader {
id: terrainHeader
text: qsTr("Terrain")
checked: missionItem.followTerrain
id: terrainHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Terrain")
checked: missionItem.followTerrain
}
ColumnLayout {
......@@ -228,8 +232,10 @@ Rectangle {
}
SectionHeader {
id: statsHeader
text: qsTr("Statistics")
id: statsHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Statistics")
}
TransectStyleComplexItemStats { }
......
......@@ -52,8 +52,10 @@ Rectangle {
visible: !editorColumnNeedLandingPoint.visible
SectionHeader {
id: loiterPointSection
text: qsTr("Loiter point")
id: loiterPointSection
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Loiter point")
}
Column {
......@@ -101,8 +103,10 @@ Rectangle {
}
SectionHeader {
id: landingPointSection
text: qsTr("Landing point")
id: landingPointSection
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Landing point")
}
Column {
......@@ -181,9 +185,11 @@ Rectangle {
}
SectionHeader {
id: cameraSection
text: qsTr("Camera")
visible: _showCameraSection
id: cameraSection
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Camera")
visible: _showCameraSection
}
Column {
......@@ -208,6 +214,16 @@ Rectangle {
property Fact _stopTakingVideo: missionItem.stopTakingVideo
}
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
color: qgcPal.warningText
font.pointSize: ScreenTools.smallFontPointSize
horizontalAlignment: Text.AlignHCenter
text: qsTr("* Glide slope altitudes are approximate. Actual flight path will vary due to environmental conditions and vehicle settings.")
}
}
Column {
......
......@@ -455,8 +455,8 @@ Item {
visible: _missionItem.isCurrentItem
sourceItem: HeightIndicator {
heightText: QGroundControl.metersToAppSettingsDistanceUnits(_transitionAltitudeMeters).toFixed(1) + " " +
QGroundControl.appSettingsDistanceUnitsString
heightText: Math.floor(QGroundControl.metersToAppSettingsDistanceUnits(_transitionAltitudeMeters)) +
QGroundControl.appSettingsDistanceUnitsString + "<sup>*</sup>"
}
function recalc() {
......@@ -486,8 +486,8 @@ Item {
visible: _missionItem.isCurrentItem
sourceItem: HeightIndicator {
heightText: QGroundControl.metersToAppSettingsDistanceUnits(_midSlopeAltitudeMeters).toFixed(1) + " " +
QGroundControl.appSettingsDistanceUnitsString
heightText: Math.floor(QGroundControl.metersToAppSettingsDistanceUnits(_midSlopeAltitudeMeters)) +
QGroundControl.appSettingsDistanceUnitsString + "<sup>*</sup>"
}
function recalc() {
......@@ -520,7 +520,7 @@ Item {
coordinate: _missionItem.loiterTangentCoordinate
sourceItem: HeightIndicator {
heightText: _missionItem.loiterAltitude.value.toFixed(1) + " " + QGroundControl.appSettingsDistanceUnitsString
heightText: _missionItem.loiterAltitude.value.toFixed(1) + QGroundControl.appSettingsDistanceUnitsString
}
}
}
......
......@@ -110,8 +110,10 @@ QGCFlickable {
}
SectionHeader {
id: insertSection
text: qsTr("Insert GeoFence")
id: insertSection
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Insert GeoFence")
}
QGCButton {
......@@ -139,8 +141,10 @@ QGCFlickable {
}
SectionHeader {
id: polygonSection
text: qsTr("Polygon Fences")
id: polygonSection
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Polygon Fences")
}
QGCLabel {
......@@ -212,8 +216,10 @@ QGCFlickable {
} // GridLayout
SectionHeader {
id: circleSection
text: qsTr("Circular Fences")
id: circleSection
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Circular Fences")
}
QGCLabel {
......@@ -302,8 +308,10 @@ QGCFlickable {
} // GridLayout
SectionHeader {
id: breachReturnSection
text: qsTr("Breach Return Point")
id: breachReturnSection
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Breach Return Point")
}
QGCButton {
......
......@@ -3,6 +3,7 @@ import QtQuick.Controls 2.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.2
import QtQml 2.2
import QtQuick.Layouts 1.11
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
......@@ -46,6 +47,7 @@ Rectangle {
readonly property real _margin: ScreenTools.defaultFontPixelWidth / 2
readonly property real _radius: ScreenTools.defaultFontPixelWidth / 2
readonly property real _hamburgerSize: commandPicker.height * 0.75
readonly property real _trashSize: commandPicker.height * 0.75
readonly property bool _waypointsOnlyMode: QGroundControl.corePlugin.options.missionWaypointsOnly
QGCPalette {
......@@ -137,46 +139,6 @@ Rectangle {
QGCMenu {
id: hamburgerMenu
QGCMenuItem {
text: qsTr("Insert waypoint")
onTriggered: insertWaypoint()
}
QGCMenu {
id: patternMenu
title: qsTr("Insert pattern")
visible: !_singleComplexItem
Instantiator {
model: _missionController.complexMissionItemNames
onObjectAdded: patternMenu.insertItem(index, object)
onObjectRemoved: patternMenu.removeItem(object)
QGCMenuItem {
text: modelData
onTriggered: insertComplexItem(modelData)
}
}
}
QGCMenuItem {
text: qsTr("Insert ") + _missionController.complexMissionItemNames[0]
visible: _singleComplexItem
onTriggered: insertComplexItem(_missionController.complexMissionItemNames[0])
}
QGCMenuItem {
text: qsTr("Delete")
onTriggered: remove()
}
QGCMenuItem {
text: qsTr("Change command...")
onTriggered: commandPicker.clicked()
visible: missionItem.isSimpleItem && !_waypointsOnlyMode
}
QGCMenuItem {
text: qsTr("Edit position...")
visible: missionItem.specifiesCoordinate
......@@ -214,15 +176,66 @@ Rectangle {
}
}
QGCButton {
id: commandPicker
anchors.topMargin: _margin
anchors.rightMargin: ScreenTools.defaultFontPixelWidth
anchors.leftMargin: _margin
QGCColoredImage {
id: deleteButton
anchors.margins: _margin
anchors.left: parent.left
anchors.top: parent.top
visible: !commandLabel.visible
text: missionItem.commandName
anchors.verticalCenter: commandPicker.verticalCenter
height: _hamburgerSize
width: height
sourceSize.height: height
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
color: qgcPal.text
visible: _currentItem && missionItem.sequenceNumber !== 0
source: "/res/TrashDelete.svg"
QGCMouseArea {
fillItem: parent
onClicked: remove()
}
}
Rectangle {
id: commandPicker
anchors.margins: _margin
anchors.left: deleteButton.right
anchors.top: parent.top
height: ScreenTools.implicitComboBoxHeight
width: innerLayout.x + innerLayout.width + ScreenTools.comboBoxPadding
visible: !commandLabel.visible
color: qgcPal.window
border.width: 1
border.color: qgcPal.text
RowLayout {
id: innerLayout
anchors.margins: _padding
anchors.left: parent.left
anchors.top: parent.top
spacing: _padding
property real _padding: ScreenTools.comboBoxPadding
QGCLabel { text: missionItem.commandName }
QGCColoredImage {
height: ScreenTools.implicitComboBoxHeight - (ScreenTools.comboBoxPadding * 2)
width: height
sourceSize.height: height
fillMode: Image.PreserveAspectFit
smooth: true
antialiasing: true
color: qgcPal.text
source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/images/double-arrow.png"
}
}
QGCMouseArea {
fillItem: parent
onClicked: mainWindow.showComponentDialog(commandDialog, qsTr("Select Mission Command"), mainWindow.showDialogDefaultWidth, StandardButton.Cancel)
}
Component {
id: commandDialog
......@@ -233,15 +246,14 @@ Rectangle {
}
}
onClicked: mainWindow.showComponentDialog(commandDialog, qsTr("Select Mission Command"), mainWindow.showDialogDefaultWidth, StandardButton.Cancel)
}
QGCLabel {
id: commandLabel
anchors.leftMargin: ScreenTools.comboBoxPadding
anchors.fill: commandPicker
visible: !missionItem.isCurrentItem || !missionItem.isSimpleItem || _waypointsOnlyMode
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: missionItem.commandName
color: _outerTextColor
}
......
......@@ -108,9 +108,11 @@ Rectangle {
}
SectionHeader {
id: missionEndHeader
text: qsTr("Mission End")
checked: true
id: missionEndHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Mission End")
checked: true
}
Column {
......@@ -128,10 +130,12 @@ Rectangle {
SectionHeader {
id: vehicleInfoSectionHeader
text: qsTr("Vehicle Info")
visible: _offlineEditing && !_waypointsOnlyMode
checked: false
id: vehicleInfoSectionHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Vehicle Info")
visible: _offlineEditing && !_waypointsOnlyMode
checked: false
}
GridLayout {
......@@ -192,10 +196,12 @@ Rectangle {
} // GridLayout
SectionHeader {
id: plannedHomePositionSection
text: qsTr("Planned Home Position")
visible: !_vehicleHasHomePosition
checked: false
id: plannedHomePositionSection
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Planned Home Position")
visible: !_vehicleHasHomePosition
checked: false
}
Column {
......
/****************************************************************************
*
* (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.
*
****************************************************************************/
import QtQuick 2.3
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.2
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
Item {
id: _root
property var planMasterController
property var mapControl
property real _radius: ScreenTools.defaultFontPixelWidth / 2
property real _margins: ScreenTools.defaultFontPixelWidth
function _mapCenter() {
var centerPoint = Qt.point(mapControl.centerViewport.left + (mapControl.centerViewport.width / 2), mapControl.centerViewport.top + (mapControl.centerViewport.height / 2))
return mapControl.toCoordinate(centerPoint, false /* clipToViewPort */)
}
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
Rectangle {
anchors.fill: parent
radius: _radius
color: "white"
opacity: 0.75
}
// Close Icon
QGCColoredImage {
anchors.margins: ScreenTools.defaultFontPixelWidth / 2
anchors.top: parent.top
anchors.right: parent.right
width: ScreenTools.defaultFontPixelHeight
height: width
sourceSize.height: width
source: "/res/XDelete.svg"
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
color: "black"
QGCMouseArea {
fillItem: parent
onClicked: _root.visible = false
}
}
QGCLabel {
id: title
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
text: qsTr("Create Plan")
color: "black"
}
QGCFlickable {
id: flickable
anchors.margins: _margins
anchors.top: title.bottom
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
contentHeight: creatorFlow.height
contentWidth: creatorFlow.width
Flow {
id: creatorFlow
width: flickable.width
spacing: _margins
Repeater {
model: _planMasterController.planCreators
Rectangle {
id: button
width: ScreenTools.defaultFontPixelHeight * 10
height: width
color: button.pressed || button.highlighted ? qgcPal.buttonHighlight : qgcPal.button
property bool highlighted: mouseArea.containsMouse
property bool pressed: mouseArea.pressed
Image {
anchors.margins: _margins
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
source: object.imageResource
fillMode: Image.PreserveAspectFit
mipmap: true
}
QGCLabel {
anchors.margins: _margins
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
text: object.name
color: button.pressed || button.highlighted ? qgcPal.buttonHighlightText : qgcPal.buttonText
}
QGCMouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
preventStealing: true
onClicked: { object.createPlan(_mapCenter()); _root.visible = false }
}
}
}
}
}
}
This diff is collapsed.
......@@ -130,8 +130,10 @@ Rectangle {
}
SectionHeader {
id: scanHeader
text: qsTr("Scan")
id: scanHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Scan")
}
Column {
......@@ -200,8 +202,10 @@ Rectangle {
} // Column - Scan
SectionHeader {
id: statsHeader
text: qsTr("Statistics")
id: statsHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Statistics")
}
Grid {
......
......@@ -124,8 +124,10 @@ Rectangle {
}
SectionHeader {
id: transectsHeader
text: qsTr("Transects")
id: transectsHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Transects")
}
GridLayout {
......@@ -233,9 +235,11 @@ Rectangle {
}
SectionHeader {
id: terrainHeader
text: qsTr("Terrain")
checked: missionItem.followTerrain
id: terrainHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Terrain")
checked: missionItem.followTerrain
}
ColumnLayout {
......@@ -280,8 +284,10 @@ Rectangle {
}
SectionHeader {
id: statsHeader
text: qsTr("Statistics")
id: statsHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Statistics")
}
TransectStyleComplexItemStats {
......@@ -357,8 +363,6 @@ Rectangle {
SectionHeader {
id: presectsTransectsHeader
anchors.left: undefined
anchors.right: undefined
Layout.fillWidth: true
text: qsTr("Transects")
}
......@@ -400,11 +404,9 @@ Rectangle {
}
SectionHeader {
id: presetsStatsHeader
anchors.left: undefined
anchors.right: undefined
id: presetsStatsHeader
Layout.fillWidth: true
text: qsTr("Statistics")
text: qsTr("Statistics")
}
TransectStyleComplexItemStats {
......
......@@ -158,12 +158,8 @@ static QObject* shapeFileHelperSingletonFactory(QQmlEngine*, QJSEngine*)
}
QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting)
#if defined(__mobile__)
: QGuiApplication (argc, argv)
#else
: QApplication (argc, argv)
#endif
, _runningUnitTests (unitTesting)
: QGuiApplication (argc, argv)
, _runningUnitTests (unitTesting)
{
_app = this;
_msecsElapsedTime.start();
......
......@@ -7,17 +7,7 @@
*
****************************************************************************/
/**
* @file
* @brief Definition of main class
*
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#ifndef QGCAPPLICATION_H
#define QGCAPPLICATION_H
#pragma once
#include <QApplication>
#include <QTimer>
......@@ -45,21 +35,7 @@ class QGCSingleton;
class QGCToolbox;
class QGCFileDownload;
/**
* @brief The main application and management class.
*
* This class is started by the main method and provides
* the central management unit of the groundstation application.
*
* Needs QApplication base to support QtCharts drawing module and
* avoid application crashing on 5.12. Enforce no widget on mobile
**/
class QGCApplication :
#if defined(__mobile__)
public QGuiApplication
#else
public QApplication
#endif
class QGCApplication : public QGuiApplication
{
Q_OBJECT
......@@ -214,5 +190,3 @@ private:
/// @brief Returns the QGCApplication object singleton.
QGCApplication* qgcApp(void);
#endif
......@@ -18,6 +18,12 @@ Button {
id: control
height: ScreenTools.defaultFontPixelHeight * 2
autoExclusive: true
leftPadding: ScreenTools.defaultFontPixelWidth
rightPadding: leftPadding
property real _compIDWidth: ScreenTools.defaultFontPixelWidth * 3
property real _hzWidth: ScreenTools.defaultFontPixelWidth * 7
property real _nameWidth: nameLabel.contentWidth
background: Rectangle {
anchors.fill: parent
......@@ -28,20 +34,27 @@ Button {
property int compID: 0
contentItem: RowLayout {
id: rowLayout
spacing: ScreenTools.defaultFontPixelWidth
QGCLabel {
text: control.compID
color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 3
text: control.compID
color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText
Layout.minimumWidth: _compIDWidth
}
QGCLabel {
text: control.text
color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 28
id: nameLabel
text: control.text
color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText
Layout.fillWidth: true
}
QGCLabel {
color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText
text: messageHz.toFixed(1) + 'Hz'
Layout.alignment: Qt.AlignRight
color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText
text: messageHz.toFixed(1) + 'Hz'
horizontalAlignment: Text.AlignRight
Layout.minimumWidth: _hzWidth
}
}
Component.onCompleted: maxButtonWidth = Math.max(maxButtonWidth, _compIDWidth + _hzWidth + _nameWidth + (rowLayout.spacing * 2) + (control.leftPadding * 2))
}
......@@ -29,14 +29,16 @@ Rectangle {
centeredLabel: true
font.pointSize: ScreenTools.smallFontPointSize
Image {
QGCColoredImage {
anchors.leftMargin: _margins
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
source: "/res/gear-black.svg"
mipmap: true
width: parent.height -(_margins * 2)
sourceSize.width: width
height: parent.height * 0.7
width: height
sourceSize.height: height
color: qgcPal.text
fillMode: Image.PreserveAspectFit
visible: pageWidgetLoader.item ? (pageWidgetLoader.item.showSettingsIcon ? pageWidgetLoader.item.showSettingsIcon : false) : false
......
......@@ -32,10 +32,8 @@ Item {
property var _appSettings: QGroundControl.settingsManager.appSettings
ParameterEditorController {
id: controller;
onShowErrorMessage: {
mainWindow.showMessageDialog(qsTr("Parameter Editor"), qsTr("Parameter Load Errors"))
}
id: controller
onShowErrorMessage: mainWindow.showMessageDialog(qsTr("Parameter Load Errors"), errorMsg)
}
ExclusiveGroup { id: sectionGroup }
......@@ -176,6 +174,8 @@ Item {
SectionHeader {
id: categoryHeader
anchors.left: parent.left
anchors.right: parent.right
text: category
checked: controller.currentCategory === text
exclusiveGroup: sectionGroup
......
......@@ -43,8 +43,10 @@ Column {
}
SectionHeader {
id: header
text: name + (passed ? qsTr(" (passed)") : "")
id: header
anchors.left: parent.left
anchors.right: parent.right
text: name + (passed ? qsTr(" (passed)") : "")
}
Column {
......
......@@ -40,7 +40,6 @@ ParameterEditor 1.0 ParameterEditor.qml
ParameterEditorDialog 1.0 ParameterEditorDialog.qml
PIDTuning 1.0 PIDTuning.qml
PlanEditToolbar 1.0 PlanEditToolbar.qml
PlanStartOverlay 1.0 PlanStartOverlay.qml
PreFlightCheckButton 1.0 PreFlightCheckButton.qml
PreFlightCheckGroup 1.0 PreFlightCheckGroup.qml
PreFlightCheckModel 1.0 PreFlightCheckModel.qml
......
......@@ -7,10 +7,8 @@ import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
FocusScope {
id: _root
anchors.left: parent.left
anchors.right: parent.right
height: column.height
id: _root
height: column.height
property alias text: label.text
property bool checked: true
......
......@@ -27,6 +27,11 @@ Rectangle {
property AbstractButton lastClickedButton: null
function simulateClick(buttonIndex) {
toolStripColumn.children[buttonIndex].checked = true
toolStripColumn.children[buttonIndex].clicked()
}
// Ensure we don't get narrower than content
property real _idealWidth: (ScreenTools.isMobile ? ScreenTools.minTouchPixels : ScreenTools.defaultFontPixelWidth * 8) + toolStripColumn.anchors.margins * 2
......@@ -73,7 +78,7 @@ Rectangle {
checked: modelData.checked !== undefined ? modelData.checked : checked
ButtonGroup.group: buttonGroup
// Only drop pannel and toggleable are checkable
// Only drop panel and toggleable are checkable
checkable: modelData.dropPanelComponent !== undefined || (modelData.toggle !== undefined && modelData.toggle)
onClicked: {
......
......@@ -19,22 +19,29 @@ TrajectoryPoints::TrajectoryPoints(Vehicle* vehicle, QObject* parent)
void TrajectoryPoints::_vehicleCoordinateChanged(QGeoCoordinate coordinate)
{
// The goal of this algorithm is to limit the number of trajectory points whic represent the vehicle path.
// Fewer points means higher performance of map display.
if (_lastPoint.isValid()) {
if (_lastPoint.distanceTo(coordinate) > _distanceTolerance) {
// Vehicle has moved far enough from previous point for an update
double newAzimuth = _lastPoint.azimuthTo(coordinate);
if (qIsNaN(_lastAzimuth) || qAbs(newAzimuth - _lastAzimuth) > _azimuthTolerance) {
// The new position IS NOT colinear with the last segment. Append the new position to the list.
_lastAzimuth = _lastPoint.azimuthTo(coordinate);
_lastPoint = coordinate;
_points.append(QVariant::fromValue(coordinate));
emit pointAdded(coordinate);
} else {
// The new position IS colinear with the last segment. Don't add a new point, just update
// the last point to be the new position.
_lastPoint = coordinate;
_points[_points.count() - 1] = QVariant::fromValue(coordinate);
emit updateLastPoint(coordinate);
}
}
} else {
_lastAzimuth = _lastPoint.azimuthTo(coordinate);
// Add the very first trajectory point to the list
_lastPoint = coordinate;
_points.append(QVariant::fromValue(coordinate));
emit pointAdded(coordinate);
......@@ -56,5 +63,7 @@ void TrajectoryPoints::stop(void)
void TrajectoryPoints::clear(void)
{
_points.clear();
_lastPoint = QGeoCoordinate();
_lastAzimuth = qQNaN();
emit pointsCleared();
}
......@@ -196,47 +196,66 @@ ApplicationWindow {
mainWindow.close()
}
// On attempting an application close we check for:
// Unsaved missions - then
// Pending parameter writes - then
// Active connections
onClosing: {
if (!_forceClose) {
unsavedMissionCloseDialog.check()
close.accepted = false
}
}
MessageDialog {
id: activeConnectionsCloseDialog
id: unsavedMissionCloseDialog
title: qsTr("%1 close").arg(QGroundControl.appName)
text: qsTr("There are still active connections to vehicles. Are you sure you want to exit?")
standardButtons: StandardButton.Yes | StandardButton.Cancel
text: qsTr("You have a mission edit in progress which has not been saved/sent. If you close you will lose changes. Are you sure you want to close?")
standardButtons: StandardButton.Yes | StandardButton.No
modality: Qt.ApplicationModal
visible: false
onYes: finishCloseProcess()
onYes: pendingParameterWritesCloseDialog.check()
function check() {
if (QGroundControl.multiVehicleManager.activeVehicle) {
activeConnectionsCloseDialog.open()
if (planMasterControllerPlan && planMasterControllerPlan.dirty) {
unsavedMissionCloseDialog.open()
} else {
finishCloseProcess()
pendingParameterWritesCloseDialog.check()
}
}
}
//-------------------------------------------------------------------------
//-- Check for unsaved missions
onClosing: {
// Check first for unsaved missions and active connections
if (!_forceClose) {
unsavedMissionCloseDialog.check()
close.accepted = false
MessageDialog {
id: pendingParameterWritesCloseDialog
title: qsTr("%1 close").arg(QGroundControl.appName)
text: qsTr("You have pending parameter updates to a vehicle. If you close you will lose changes. Are you sure you want to close?")
standardButtons: StandardButton.Yes | StandardButton.No
modality: Qt.ApplicationModal
visible: false
onYes: activeConnectionsCloseDialog.check()
function check() {
for (var index=0; index<QGroundControl.multiVehicleManager.vehicles.count; index++) {
if (QGroundControl.multiVehicleManager.vehicles.get(index).parameterManager.pendingWrites) {
pendingParameterWritesCloseDialog.open()
return
}
}
activeConnectionsCloseDialog.check()
}
}
MessageDialog {
id: unsavedMissionCloseDialog
id: activeConnectionsCloseDialog
title: qsTr("%1 close").arg(QGroundControl.appName)
text: qsTr("You have a mission edit in progress which has not been saved/sent. If you close you will lose changes. Are you sure you want to close?")
standardButtons: StandardButton.Yes | StandardButton.No
text: qsTr("There are still active connections to vehicles. Are you sure you want to exit?")
standardButtons: StandardButton.Yes | StandardButton.Cancel
modality: Qt.ApplicationModal
visible: false
onYes: activeConnectionsCloseDialog.check()
onYes: finishCloseProcess()
function check() {
if (planMasterControllerPlan && planMasterControllerPlan.dirty) {
unsavedMissionCloseDialog.open()
if (QGroundControl.multiVehicleManager.activeVehicle) {
activeConnectionsCloseDialog.open()
} else {
activeConnectionsCloseDialog.check()
finishCloseProcess()
}
}
}
......
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