Commit c39e9c7f authored by Don Gagne's avatar Don Gagne

Initial GeoFence implementation

parent 32cfa15c
......@@ -273,12 +273,16 @@ HEADERS += \
src/LogCompressor.h \
src/MG.h \
src/MissionManager/ComplexMissionItem.h \
src/MissionManager/GeoFenceController.h \
src/MissionManager/GeoFenceManager.h \
src/MissionManager/QGCMapPolygon.h \
src/MissionManager/MissionCommandList.h \
src/MissionManager/MissionCommandTree.h \
src/MissionManager/MissionCommandUIInfo.h \
src/MissionManager/MissionController.h \
src/MissionManager/MissionItem.h \
src/MissionManager/MissionManager.h \
src/MissionManager/PlanElementController.h \
src/MissionManager/SimpleMissionItem.h \
src/MissionManager/SurveyMissionItem.h \
src/MissionManager/VisualMissionItem.h \
......@@ -434,12 +438,16 @@ SOURCES += \
src/LogCompressor.cc \
src/main.cc \
src/MissionManager/ComplexMissionItem.cc \
src/MissionManager/GeoFenceController.cc \
src/MissionManager/GeoFenceManager.cc \
src/MissionManager/QGCMapPolygon.cc \
src/MissionManager/MissionCommandList.cc \
src/MissionManager/MissionCommandTree.cc \
src/MissionManager/MissionCommandUIInfo.cc \
src/MissionManager/MissionController.cc \
src/MissionManager/MissionItem.cc \
src/MissionManager/MissionManager.cc \
src/MissionManager/PlanElementController.cc \
src/MissionManager/SimpleMissionItem.cc \
src/MissionManager/SurveyMissionItem.cc \
src/MissionManager/VisualMissionItem.cc \
......
......@@ -92,6 +92,7 @@
<file alias="QGroundControl/Controls/ViewWidget.qml">src/ViewWidgets/ViewWidget.qml</file>
<file alias="SimpleItemEditor.qml">src/MissionEditor/SimpleItemEditor.qml</file>
<file alias="SurveyItemEditor.qml">src/MissionEditor/SurveyItemEditor.qml</file>
<file alias="GeoFenceEditor.qml">src/MissionEditor/GeoFenceEditor.qml</file>
<file alias="QGroundControl/FactControls/FactBitmask.qml">src/FactSystem/FactControls/FactBitmask.qml</file>
<file alias="QGroundControl/FactControls/FactCheckBox.qml">src/FactSystem/FactControls/FactCheckBox.qml</file>
<file alias="QGroundControl/FactControls/FactComboBox.qml">src/FactSystem/FactControls/FactComboBox.qml</file>
......@@ -107,6 +108,7 @@
<file alias="VirtualJoystick.qml">src/FlightDisplay/VirtualJoystick.qml</file>
<file alias="QGroundControl/FlightMap/qmldir">src/FlightMap/qmldir</file>
<file alias="QGroundControl/FlightMap/FlightMap.qml">src/FlightMap/FlightMap.qml</file>
<file alias="QGroundControl/FlightMap/QGCMapPolygonControls.qml">src/MissionEditor/QGCMapPolygonControls.qml</file>
<file alias="QGroundControl/FlightMap/MapScale.qml">src/FlightMap/MapScale.qml</file>
<file alias="QGroundControl/FlightMap/MissionItemIndicator.qml">src/FlightMap/MapItems/MissionItemIndicator.qml</file>
<file alias="QGroundControl/FlightMap/MissionItemView.qml">src/FlightMap/MapItems/MissionItemView.qml</file>
......
......@@ -58,6 +58,11 @@ FlightMap {
Component.onCompleted: start(false /* editMode */)
}
GeoFenceController {
id: _geoFenceController
Component.onCompleted: start(false /* editMode */)
}
// Add trajectory points to the map
MapItemView {
model: _mainIsMap ? _activeVehicle ? _activeVehicle.trajectoryPoints : 0 : 0
......@@ -96,6 +101,20 @@ FlightMap {
model: _mainIsMap ? _missionController.waypointLines : 0
}
// GeoFence polygon
MapPolygon {
border.color: "#80FF0000"
border.width: 3
path: _geoFenceController.polygon.path
}
// GeoFence breach return point
MapQuickItem {
anchorPoint: Qt.point(sourceItem.width / 2, sourceItem.height / 2)
coordinate: _geoFenceController.breachReturnPoint
sourceItem: MissionItemIndexLabel { label: "F" }
}
// GoTo here waypoint
MapQuickItem {
coordinate: _gotoHereCoordinate
......
......@@ -198,30 +198,17 @@ Map {
property bool adjustingPolygon: false
property bool polygonReady: polygonDrawerPolygon.path.length > 3 ///< true: enough points have been captured to create a closed polygon
/// New polygon capture has started
signal polygonCaptureStarted
/// Polygon capture is complete
/// @param coordinates Map coordinates for the polygon points
signal polygonCaptureFinished(var coordinates)
/// Polygon adjustment has begun
signal polygonAdjustStarted
/// Polygon Vertex coordinate has been adjusted
signal polygonAdjustVertex(int vertexIndex, var vertexCoordinate)
/// Polygon adjustment finished
signal polygonAdjustFinished
property var _callbackObject
property var _vertexDragList: []
/// Begin capturing a new polygon
/// polygonCaptureStarted will be signalled
function startCapturePolygon() {
function startCapturePolygon(callback) {
polygonDrawer._callbackObject = callback
polygonDrawer.drawingPolygon = true
polygonDrawer._clearPolygon()
polygonDrawer.polygonCaptureStarted()
polygonDrawer._callbackObject.polygonCaptureStarted()
}
/// Finish capturing the polygon
......@@ -236,11 +223,12 @@ Map {
polygonPath.pop() // get rid of drag coordinate
polygonDrawer._clearPolygon()
polygonDrawer.drawingPolygon = false
polygonDrawer.polygonCaptureFinished(polygonPath)
polygonDrawer._callbackObject.polygonCaptureFinished(polygonPath)
return true
}
function startAdjustPolygon(vertexCoordinates) {
function startAdjustPolygon(callback, vertexCoordinates) {
polygonDraw._callbackObject = callback
polygonDrawer.adjustingPolygon = true
for (var i=0; i<vertexCoordinates.length; i++) {
var mapItem = Qt.createQmlObject(
......@@ -268,7 +256,7 @@ Map {
"" +
" function updateCoordinate() { " +
" vertexDrag.coordinate = _map.toCoordinate(Qt.point(vertexDrag.x + _halfSideLength, vertexDrag.y + _halfSideLength), false); " +
" polygonDrawer.polygonAdjustVertex(vertexDrag.index, vertexDrag.coordinate); " +
" polygonDrawer._callbackObject.polygonAdjustVertex(vertexDrag.index, vertexDrag.coordinate); " +
" } " +
"" +
" function updatePosition() { " +
......@@ -299,7 +287,7 @@ Map {
mapItem.index = i
mapItem.updatePosition()
polygonDrawer._vertexDragList.push(mapItem)
polygonDrawer.polygonAdjustStarted()
polygonDrawer._callbackObject.polygonAdjustStarted()
}
}
......@@ -309,7 +297,7 @@ Map {
polygonDrawer._vertexDragList[i].destroy()
}
polygonDrawer._vertexDragList = []
polygonDrawer.polygonAdjustFinished()
polygonDrawer._callbackObject.polygonAdjustFinished()
}
function _clearPolygon() {
......
......@@ -23,3 +23,6 @@ MissionItemIndicator 1.0 MissionItemIndicator.qml
MissionItemView 1.0 MissionItemView.qml
MissionLineView 1.0 MissionLineView.qml
VehicleMapItem 1.0 VehicleMapItem.qml
# Editor controls
QGCMapPolygonControls 1.0 QGCMapPolygonControls.qml
import QtQuick 2.2
import QtQuick.Controls 1.2
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.FlightMap 1.0
QGCFlickable {
id: root
width: availableWidth
height: Math.min(availableHeight, geoFenceEditorRect.height)
contentHeight: geoFenceEditorRect.height
clip: true
readonly property real _editFieldWidth: Math.min(width - _margin * 2, ScreenTools.defaultFontPixelWidth * 12)
readonly property real _margin: ScreenTools.defaultFontPixelWidth / 2
readonly property real _radius: ScreenTools.defaultFontPixelWidth / 2
property var polygon: geoFenceController.polygon
Connections {
target: geoFenceController.polygon
onPathChanged: {
if (geoFenceController.polygon.path.length > 2) {
geoFenceController.breachReturnPoint = geoFenceController.polygon.center()
}
}
}
Rectangle {
id: geoFenceEditorRect
width: parent.width
height: geoFenceItems.y + geoFenceItems.height + (_margin * 2)
radius: _radius
color: qgcPal.buttonHighlight
QGCLabel {
id: geoFenceLabel
anchors.margins: _margin
anchors.left: parent.left
anchors.top: parent.top
text: qsTr("Geo-Fence (WIP careful!)")
color: "black"
}
Rectangle {
id: geoFenceItems
anchors.margins: _margin
anchors.left: parent.left
anchors.right: parent.right
anchors.top: geoFenceLabel.bottom
height: editorColumn.height + (_margin * 2)
color: qgcPal.windowShadeDark
radius: _radius
Column {
id: editorColumn
anchors.margins: _margin
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: qsTr("Click in map to set breach return point.")
}
QGCLabel { text: qsTr("Fence Settings:") }
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: 1
color: qgcPal.text
}
QGCLabel {
text: qsTr("Must be connected to Vehicle to change fence settings.")
visible: !QGroundControl.multiVehicleManager.activeVehicle
}
Repeater {
model: geoFenceController.params
Item {
width: editorColumn.width
height: textField.height
QGCLabel {
id: textFieldLabel
anchors.baseline: textField.baseline
text: modelData.name
}
FactTextField {
id: textField
anchors.right: parent.right
width: _editFieldWidth
showUnits: true
fact: modelData
}
}
}
QGCMapPolygonControls {
anchors.left: parent.left
anchors.right: parent.right
flightMap: editorMap
polygon: root.polygon
sectionLabel: qsTr("Fence Polygon:")
}
}
}
}
}
......@@ -40,20 +40,23 @@ QGCView {
readonly property real _rightPanelWidth: Math.min(parent.width / 3, ScreenTools.defaultFontPixelWidth * 30)
readonly property real _rightPanelOpacity: 0.8
readonly property int _toolButtonCount: 6
readonly property string _autoSyncKey: "AutoSync"
readonly property real _toolButtonTopMargin: parent.height - ScreenTools.availableHeight + (ScreenTools.defaultFontPixelHeight / 2)
readonly property int _addMissionItemsButtonAutoOffTimeout: 10000
readonly property var _defaultVehicleCoordinate: QtPositioning.coordinate(37.803784, -122.462276)
property bool _syncNeeded: controller.visualItems.dirty // Unsaved changes, visible to parent container
property var _visualItems: controller.visualItems
property var _visualItems: missionController.visualItems
property var _currentMissionItem
property int _currentMissionIndex: 0
property bool _firstVehiclePosition: true
property var activeVehiclePosition: _activeVehicle ? _activeVehicle.coordinate : QtPositioning.coordinate()
property bool _lightWidgetBorders: editorMap.isSatelliteMap
/// The controller which should be called for load/save, send to/from vehicle calls
property var _syncDropDownController: missionController
readonly property int _layerMission: 1
readonly property int _layerGeoFence: 2
property int _editingLayer: _layerMission
onActiveVehiclePositionChanged: updateMapToVehiclePosition()
Connections {
......@@ -73,28 +76,6 @@ QGCView {
}
}
function loadFromVehicle() {
controller.getMissionItems()
}
function loadFromFile() {
if (ScreenTools.isMobile) {
_root.showDialog(mobileFilePicker, qsTr("Select Mission File"), _root.showDialogDefaultWidth, StandardButton.Yes | StandardButton.Cancel)
} else {
controller.loadMissionFromFilePicker()
fitViewportToMissionItems()
_currentMissionItem = _visualItems.get(0)
}
}
function saveToFile() {
if (ScreenTools.isMobile) {
_root.showDialog(mobileFileSaver, qsTr("Save Mission File"), _root.showDialogDefaultWidth, StandardButton.Save | StandardButton.Cancel)
} else {
controller.saveMissionToFilePicker()
}
}
function normalizeLat(lat) {
// Normalize latitude to range: 0 to 180, S to N
return lat + 90.0
......@@ -134,23 +115,45 @@ QGCView {
}
MissionController {
id: controller
id: missionController
Component.onCompleted: {
start(true /* editMode */)
setCurrentItem(0)
}
/*
FIXME: autoSync is temporarily disconnected since it's still buggy
function loadFromSelectedFile() {
if (ScreenTools.isMobile) {
_root.showDialog(mobileFilePicker, qsTr("Select Mission File"), _root.showDialogDefaultWidth, StandardButton.Yes | StandardButton.Cancel)
} else {
missionController.loadFromFilePicker()
fitViewportToMissionItems()
_currentMissionItem = _visualItems.get(0)
}
}
function saveToSelectedFile() {
if (ScreenTools.isMobile) {
_root.showDialog(mobileFileSaver, qsTr("Save Mission File"), _root.showDialogDefaultWidth, StandardButton.Save | StandardButton.Cancel)
} else {
missionController.saveToFilePicker()
}
}
onVisualItemsChanged: {
itemDragger.clearItem()
}
autoSync: QGroundControl.flightMapSettings.loadMapSetting(editorMap.mapName, _autoSyncKey, true)
onNewItemsFromVehicle: {
fitViewportToMissionItems()
_currentMissionItem = _visualItems.get(0)
}
}
onAutoSyncChanged: QGroundControl.flightMapSettings.saveMapSetting(editorMap.mapName, _autoSyncKey, autoSync)
*/
GeoFenceController {
id: geoFenceController
onVisualItemsChanged: itemDragger.clearItem()
onNewItemsFromVehicle: fitViewportToMissionItems()
Component.onCompleted: start(true /* editMode */)
}
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
......@@ -183,14 +186,9 @@ QGCView {
id: mobileFilePicker
QGCMobileFileDialog {
openDialog: true
fileExtension: QGroundControl.missionFileExtension
onFilenameReturned: {
controller.loadMissionFromFile(filename)
fitViewportToMissionItems()
_currentMissionItem = _visualItems.get(0)
}
openDialog: true
fileExtension: QGroundControl.missionFileExtension
onFilenameReturned: _syncDropDownController.loadFromfile(filename)
}
}
......@@ -198,12 +196,9 @@ QGCView {
id: mobileFileSaver
QGCMobileFileDialog {
openDialog: false
fileExtension: QGroundControl.missionFileExtension
onFilenameReturned: {
controller.saveMissionToFile(filename)
}
openDialog: false
fileExtension: QGroundControl.missionFileExtension
onFilenameReturned: _syncDropDownController.saveToFile()
}
}
......@@ -217,7 +212,7 @@ QGCView {
if (toIndex == 0) {
toIndex = 1
}
controller.moveMissionItem(_moveDialogMissionItemIndex, toIndex)
missionController.moveMissionItem(_moveDialogMissionItemIndex, toIndex)
hideDialog()
}
......@@ -260,8 +255,6 @@ QGCView {
anchors.right: parent.right
mapName: "MissionEditor"
signal mapClicked(var coordinate)
readonly property real animationDuration: 500
// Initial map position duplicates Fly view position
......@@ -283,17 +276,25 @@ QGCView {
onClicked: {
//-- Don't pay attention to items beneath the toolbar.
var topLimit = parent.height - ScreenTools.availableHeight
if(mouse.y >= topLimit) {
var coordinate = editorMap.toCoordinate(Qt.point(mouse.x, mouse.y))
coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces)
coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces)
coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces)
if(mouse.y < topLimit) {
return
}
var coordinate = editorMap.toCoordinate(Qt.point(mouse.x, mouse.y))
coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces)
coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces)
coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces)
switch (_editingLayer) {
case _layerMission:
if (addMissionItemsButton.checked) {
var sequenceNumber = controller.insertSimpleMissionItem(coordinate, controller.visualItems.count)
var sequenceNumber = missionController.insertSimpleMissionItem(coordinate, missionController.visualItems.count)
setCurrentItem(sequenceNumber)
} else {
editorMap.mapClicked(coordinate)
}
break
case _layerGeoFence:
geoFenceController.breachReturnPoint = coordinate
break
}
}
}
......@@ -350,7 +351,8 @@ QGCView {
// Add the complex mission item polygon to the map
MapItemView {
model: controller.complexVisualItems
model: _editingLayer == _layerMission ? missionController.complexVisualItems : undefined
delegate: MapPolygon {
color: 'green'
path: object.polygonPath
......@@ -360,7 +362,7 @@ QGCView {
// Add the complex mission item grid to the map
MapItemView {
model: controller.complexVisualItems
model: _editingLayer == _layerMission ? missionController.complexVisualItems : undefined
delegate: MapPolyline {
line.color: "white"
......@@ -371,7 +373,7 @@ QGCView {
// Add the complex mission item exit coordinates
MapItemView {
model: controller.complexVisualItems
model: _editingLayer == _layerMission ? missionController.complexVisualItems : undefined
delegate: exitCoordinateComponent
}
......@@ -389,7 +391,7 @@ QGCView {
// Add the simple mission items to the map
MapItemView {
model: controller.visualItems
model: _editingLayer == _layerMission ? missionController.visualItems : undefined
delegate: missionItemComponent
}
......@@ -447,7 +449,7 @@ QGCView {
// Add lines between waypoints
MissionLineView {
model: controller.waypointLines
model: _editingLayer == _layerMission ? missionController.waypointLines : undefined
}
// Add the vehicles to the map
......@@ -472,6 +474,7 @@ QGCView {
width: _rightPanelWidth
opacity: _rightPanelOpacity
z: QGroundControl.zOrderTopMost
visible: _editingLayer == _layerMission
MouseArea {
// This MouseArea prevents the Map below it from getting Mouse events. Without this
......@@ -488,7 +491,7 @@ QGCView {
height: parent.height
spacing: _margin / 2
orientation: ListView.Vertical
model: controller.visualItems
model: missionController.visualItems
cacheBuffer: height * 2
clip: true
currentIndex: _currentMissionIndex
......@@ -504,19 +507,48 @@ QGCView {
onRemove: {
itemDragger.clearItem()
controller.removeMissionItem(index)
missionController.removeMissionItem(index)
}
onInsert: {
var sequenceNumber = controller.insertSimpleMissionItem(editorMap.center, insertAfterIndex)
var sequenceNumber = missionController.insertSimpleMissionItem(editorMap.center, insertAfterIndex)
setCurrentItem(sequenceNumber)
}
onMoveHomeToMapCenter: controller.visualItems.get(0).coordinate = editorMap.center
onMoveHomeToMapCenter: missionController.visualItems.get(0).coordinate = editorMap.center
}
} // ListView
} // Item - Mission Item editor
// GeoFence Editor
Loader {
anchors.topMargin: parent.height - ScreenTools.availableHeight
anchors.top: parent.top
anchors.right: parent.right
opacity: _rightPanelOpacity
z: QGroundControl.zOrderTopMost
source: _editingLayer == _layerGeoFence ? "qrc:/qml/GeoFenceEditor.qml" : ""
property real availableWidth: _rightPanelWidth
property real availableHeight: ScreenTools.availableHeight
}
// GeoFence polygon
MapPolygon {
border.color: "#80FF0000"
border.width: 3
path: geoFenceController.polygon.path
}
// GeoFence breach return point
MapQuickItem {
anchorPoint: Qt.point(sourceItem.width / 2, sourceItem.height / 2)
coordinate: geoFenceController.breachReturnPoint
sourceItem: MissionItemIndexLabel {
label: "F"
}
}
//-- Dismiss Drop Down (if any)
MouseArea {
anchors.fill: parent
......@@ -548,23 +580,66 @@ QGCView {
spacing: ScreenTools.defaultFontPixelHeight
z: QGroundControl.zOrderWidgets
DropButton {
id: layerButton
dropDirection: dropRight
//buttonImage: "/qmlimages/MapCenter.svg"
viewportMargins: ScreenTools.defaultFontPixelWidth / 2
exclusiveGroup: _dropButtonsExclusiveGroup
lightBorders: _lightWidgetBorders
dropDownComponent: Component {
Column {
spacing: ScreenTools.defaultFontPixelWidth * 0.5
QGCLabel { text: qsTr("Editing Layer:") }
Row {
spacing: ScreenTools.defaultFontPixelWidth
QGCButton {
text: qsTr("Mission")
onClicked: {
layerButton.hideDropDown()
_editingLayer = _layerMission
_syncDropDownController = missionController
}
}
QGCButton {
text: qsTr("GeoFence")
onClicked: {
layerButton.hideDropDown()
_editingLayer = _layerGeoFence
_syncDropDownController = geoFenceController
}
}
}
}
}
}
RoundButton {
id: addMissionItemsButton
buttonImage: "/qmlimages/MapAddMission.svg"
lightBorders: _lightWidgetBorders
visible: _editingLayer == _layerMission
}
RoundButton {
id: addShapeButton
buttonImage: "/qmlimages/MapDrawShape.svg"
lightBorders: _lightWidgetBorders
visible: _editingLayer == _layerMission
onClicked: {
var coordinate = editorMap.center
coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces)
coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces)
coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces)
var sequenceNumber = controller.insertComplexMissionItem(coordinate, controller.visualItems.count)
var sequenceNumber = missionController.insertComplexMissionItem(coordinate, missionController.visualItems.count)
setCurrentItem(sequenceNumber)
checked = false
addMissionItemsButton.checked = false
......@@ -574,12 +649,12 @@ QGCView {
DropButton {
id: syncButton
dropDirection: dropRight
buttonImage: _syncNeeded ? "/qmlimages/MapSyncChanged.svg" : "/qmlimages/MapSync.svg"
buttonImage: _syncDropDownController.dirty ? "/qmlimages/MapSyncChanged.svg" : "/qmlimages/MapSync.svg"
viewportMargins: ScreenTools.defaultFontPixelWidth / 2
exclusiveGroup: _dropButtonsExclusiveGroup
dropDownComponent: syncDropDownComponent
enabled: !controller.syncInProgress
rotateImage: controller.syncInProgress
enabled: !_syncDropDownController.syncInProgress
rotateImage: _syncDropDownController.syncInProgress
lightBorders: _lightWidgetBorders
}
......@@ -602,7 +677,7 @@ QGCView {
width: ScreenTools.defaultFontPixelWidth * 10
onClicked: {
centerMapButton.hideDropDown()
editorMap.center = controller.visualItems.get(0).coordinate
editorMap.center = missionController.visualItems.get(0).coordinate
}
}
QGCButton {
......@@ -706,13 +781,13 @@ QGCView {
anchors.bottom: parent.bottom
z: QGroundControl.zOrderTopMost
currentMissionItem: _currentMissionItem
missionItems: controller.visualItems
missionItems: missionController.visualItems
expandedWidth: missionItemEditor.x - (ScreenTools.defaultFontPixelWidth * 2)
missionDistance: controller.missionDistance
missionMaxTelemetry: controller.missionMaxTelemetry
cruiseDistance: controller.cruiseDistance
hoverDistance: controller.hoverDistance
visible: !ScreenTools.isShortScreen
missionDistance: missionController.missionDistance
missionMaxTelemetry: missionController.missionMaxTelemetry
cruiseDistance: missionController.cruiseDistance
hoverDistance: missionController.hoverDistance
visible: _editingLayer == _layerMission && !ScreenTools.isShortScreen
}
} // FlightMap
} // Item - split view container
......@@ -748,7 +823,7 @@ QGCView {
message: qsTr("Are you sure you want to delete all mission items?")
function accept() {
itemDragger.clearItem()
controller.removeAllMissionItems()
missionController.removeAll()
hideDialog()
}
}
......@@ -756,96 +831,84 @@ QGCView {
Component {
id: syncDropDownComponent
Column {
id: columnHolder