Skip to content
Snippets Groups Projects
PlanView.qml 41.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • /****************************************************************************
     *
     *   (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.
     *
     ****************************************************************************/
    
    Don Gagne's avatar
    Don Gagne committed
    
    
    
    import QtQuick          2.3
    import QtQuick.Controls 1.2
    
    Don Gagne's avatar
    Don Gagne committed
    import QtQuick.Dialogs  1.2
    
    import QtLocation       5.3
    import QtPositioning    5.3
    import QtQuick.Layouts  1.2
    
    import QtQuick.Window   2.2
    
    Don Gagne's avatar
    Don Gagne committed
    
    
    import QGroundControl               1.0
    
    Don Gagne's avatar
    Don Gagne committed
    import QGroundControl.FlightMap     1.0
    import QGroundControl.ScreenTools   1.0
    import QGroundControl.Controls      1.0
    
    import QGroundControl.FactSystem    1.0
    
    import QGroundControl.FactControls  1.0
    
    Don Gagne's avatar
    Don Gagne committed
    import QGroundControl.Palette       1.0
    
    Don Gagne's avatar
    Don Gagne committed
    import QGroundControl.Mavlink       1.0
    
    import QGroundControl.Controllers   1.0
    
    Gus Grubba's avatar
    Gus Grubba committed
    import QGroundControl.Airmap        1.0
    
    Don Gagne's avatar
    Don Gagne committed
    
    /// Mission Editor
    
    Don Gagne's avatar
    Don Gagne committed
    QGCView {
    
        z:          QGroundControl.zOrderTopMost
    
    Gus Grubba's avatar
    Gus Grubba committed
        property bool planControlColapsed: false
    
    
        readonly property int   _decimalPlaces:             8
    
    Gus Grubba's avatar
    Gus Grubba committed
        readonly property real  _horizontalMargin:          ScreenTools.defaultFontPixelWidth  * 0.5
    
        readonly property real  _margin:                    ScreenTools.defaultFontPixelHeight * 0.5
    
    Gus Grubba's avatar
    Gus Grubba committed
        readonly property real  _radius:                    ScreenTools.defaultFontPixelWidth  * 0.5
    
        readonly property var   _activeVehicle:             QGroundControl.multiVehicleManager.activeVehicle
        readonly property real  _rightPanelWidth:           Math.min(parent.width / 3, ScreenTools.defaultFontPixelWidth * 30)
        readonly property real  _toolButtonTopMargin:       parent.height - ScreenTools.availableHeight + (ScreenTools.defaultFontPixelHeight / 2)
        readonly property var   _defaultVehicleCoordinate:  QtPositioning.coordinate(37.803784, -122.462276)
        readonly property bool  _waypointsOnlyMode:         QGroundControl.corePlugin.options.missionWaypointsOnly
    
    Gus Grubba's avatar
    Gus Grubba committed
        property bool   _enableAirMap:                      QGroundControl.airmapSupported ? QGroundControl.settingsManager.airMapSettings.enableAirMap.rawValue : false
    
    Gus Grubba's avatar
    Gus Grubba committed
        property var    _planMasterController:              masterController
        property var    _missionController:                 _planMasterController.missionController
        property var    _geoFenceController:                _planMasterController.geoFenceController
        property var    _rallyPointController:              _planMasterController.rallyPointController
        property var    _visualItems:                       _missionController.visualItems
        property bool   _lightWidgetBorders:                editorMap.isSatelliteMap
        property bool   _addWaypointOnClick:                false
        property bool   _addROIOnClick:                     false
        property bool   _singleComplexItem:                 _missionController.complexMissionItemNames.length === 1
        property real   _toolbarHeight:                     _qgcView.height - ScreenTools.availableHeight
        property int    _editingLayer:                      _layerMission
        property int    _toolStripBottom:                   toolStrip.height + toolStrip.y
    
        readonly property int       _layerMission:              1
        readonly property int       _layerGeoFence:             2
        readonly property int       _layerRallyPoints:          3
        readonly property string    _armedVehicleUploadPrompt:  qsTr("Vehicle is currently armed. Do you want to upload the mission to the vehicle?")
    
        Component.onCompleted: {
    
            toolbar.planMasterController =  Qt.binding(function () { return _planMasterController })
    
            toolbar.currentMissionItem =    Qt.binding(function () { return _missionController.currentPlanViewItem })
    
        function addComplexItem(complexItemName) {
            var coordinate = editorMap.center
            coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces)
            coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces)
            coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces)
    
            insertComplexMissionItem(complexItemName, coordinate, _missionController.visualItems.count)
    
        }
    
        function insertComplexMissionItem(complexItemName, coordinate, index) {
    
            var sequenceNumber = _missionController.insertComplexMissionItem(complexItemName, coordinate, index)
    
            _missionController.setCurrentPlanViewIndex(sequenceNumber, true)
    
        property bool _firstMissionLoadComplete:    false
        property bool _firstFenceLoadComplete:      false
        property bool _firstRallyLoadComplete:      false
        property bool _firstLoadComplete:           false
    
    
        MapFitFunctions {
            id:                         mapFitFunctions
            map:                        editorMap
            usePlannedHomePosition:     true
    
            planMasterController:       _planMasterController
    
    Gus Grubba's avatar
    Gus Grubba committed
        on_EnableAirMapChanged: {
    
            if(QGroundControl.airmapSupported) {
    
                if(!_activeVehicle) {
                    planControlColapsed = false
                } else if(_enableAirMap) {
                    planControlColapsed = _activeVehicle.airspaceController.airspaceVisible
    
                } else {
                    planControlColapsed = false
                }
    
    Gus Grubba's avatar
    Gus Grubba committed
                planControlColapsed = false
            }
        }
    
    
    DonLakeFlyer's avatar
    DonLakeFlyer committed
        Connections {
            target: QGroundControl.settingsManager.appSettings.defaultMissionItemAltitude
    
            onRawValueChanged: {
                if (_visualItems.count > 1) {
                    _qgcView.showDialog(applyNewAltitude, qsTr("Apply new alititude"), showDialogDefaultWidth, StandardButton.Yes | StandardButton.No)
                }
            }
        }
    
        Component {
            id: applyNewAltitude
    
            QGCViewMessage {
                message:    qsTr("You have changed the default altitude for mission items. Would you like to apply that altitude to all the items in the current mission?")
    
                function accept() {
                    hideDialog()
    
                    _missionController.applyDefaultMissionAltitude()
    
        Component {
            id: activeMissionUploadDialogComponent
    
            QGCViewDialog {
    
                Column {
                    anchors.fill:   parent
                    spacing:        ScreenTools.defaultFontPixelHeight
    
                    QGCLabel {
                        width:      parent.width
                        wrapMode:   Text.WordWrap
                        text:       qsTr("Your vehicle is currently flying a mission. In order to upload a new or modified mission the current mission will be paused.")
                    }
    
                    QGCLabel {
                        width:      parent.width
                        wrapMode:   Text.WordWrap
                        text:       qsTr("After the mission is uploaded you can adjust the current waypoint and start the mission.")
                    }
    
                    QGCButton {
                        text:       qsTr("Pause and Upload")
                        onClicked: {
                            _activeVehicle.flightMode = _activeVehicle.pauseFlightMode
    
                            _planMasterController.sendToVehicle()
    
    Gus Grubba's avatar
    Gus Grubba committed
        Connections {
    
            target:         _activeVehicle ? _activeVehicle.airspaceController : null
            onAirspaceVisibleChanged: {
    
    Gus Grubba's avatar
    Gus Grubba committed
                planControlColapsed = _activeVehicle.airspaceController.airspaceVisible
            }
        }
    
    
        Component {
            id: noItemForKML
            QGCViewMessage {
                message:    qsTr("You need at least one item to create a KML.")
            }
        }
    
    
        PlanMasterController {
    
            id: masterController
    
            Component.onCompleted: {
                start(true /* editMode */)
    
                _missionController.setCurrentPlanViewIndex(0, true)
    
            function upload() {
    
                if (_activeVehicle && _activeVehicle.armed && _activeVehicle.flightMode === _activeVehicle.missionFlightMode) {
    
                    _qgcView.showDialog(activeMissionUploadDialogComponent, qsTr("Plan Upload"), _qgcView.showDialogDefaultWidth, StandardButton.Cancel)
    
                } else {
    
            function loadFromSelectedFile() {
    
                fileDialog.title =          qsTr("Select Plan File")
    
                fileDialog.selectExisting = true
    
                fileDialog.nameFilters =    masterController.loadNameFilters
    
            }
    
            function saveToSelectedFile() {
    
                fileDialog.title =          qsTr("Save Plan")
    
                fileDialog.plan =           true
    
                fileDialog.selectExisting = false
    
                fileDialog.nameFilters =    masterController.saveNameFilters
    
            function fitViewportToItems() {
    
                mapFitFunctions.fitMapViewportToMissionItems()
    
    
            function saveKmlToSelectedFile() {
                fileDialog.title =          qsTr("Save KML")
                fileDialog.plan =           false
                fileDialog.selectExisting = false
                fileDialog.nameFilters =    masterController.saveKmlFilters
                fileDialog.openForSave()
            }
    
        Connections {
            target: _missionController
    
            onNewItemsFromVehicle: {
    
                if (_visualItems && _visualItems.count != 1) {
                    mapFitFunctions.fitMapViewportToMissionItems()
                }
    
                _missionController.setCurrentPlanViewIndex(0, true)
    
        QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
    
    Don Gagne's avatar
    Don Gagne committed
    
    
        ExclusiveGroup {
            id: _mapTypeButtonsExclusiveGroup
        }
    
    
        /// Inserts a new simple mission item
        ///     @param coordinate Location to insert item
        ///     @param index Insert item at this index
        function insertSimpleMissionItem(coordinate, index) {
    
            var sequenceNumber = _missionController.insertSimpleMissionItem(coordinate, index)
    
            _missionController.setCurrentPlanViewIndex(sequenceNumber, true)
    
        /// Inserts a new ROI mission item
        ///     @param coordinate Location to insert item
        ///     @param index Insert item at this index
        function insertROIMissionItem(coordinate, index) {
            var sequenceNumber = _missionController.insertROIMissionItem(coordinate, index)
            _missionController.setCurrentPlanViewIndex(sequenceNumber, true)
            _addROIOnClick = false
            toolStrip.uncheckAll()
        }
    
    
        property int _moveDialogMissionItemIndex
    
    
        QGCFileDialog {
            id:             fileDialog
            qgcView:        _qgcView
    
            property var plan:           true
    
            folder:         QGroundControl.settingsManager.appSettings.missionSavePath
    
            fileExtension:  QGroundControl.settingsManager.appSettings.planFileExtension
            fileExtension2: QGroundControl.settingsManager.appSettings.missionFileExtension
    
                plan ? masterController.saveToFile(file) : masterController.saveToKml(file)
    
                masterController.loadFromFile(file)
                masterController.fitViewportToItems()
    
                _missionController.setCurrentPlanViewIndex(0, true)
    
        Component {
            id: moveDialog
    
            QGCViewDialog {
                function accept() {
                    var toIndex = toCombo.currentIndex
    
    
    Gus Grubba's avatar
    Gus Grubba committed
                    if (toIndex === 0) {
    
                    _missionController.moveMissionItem(_moveDialogMissionItemIndex, toIndex)
    
                    hideDialog()
                }
    
                Column {
                    anchors.left:   parent.left
                    anchors.right:  parent.right
                    spacing:        ScreenTools.defaultFontPixelHeight
    
                    QGCLabel {
                        anchors.left:   parent.left
                        anchors.right:  parent.right
                        wrapMode:       Text.WordWrap
    
                        text:           qsTr("Move the selected mission item to the be after following mission item:")
    
                        model:          _visualItems.count
    
                        currentIndex:   _moveDialogMissionItemIndex
                    }
                }
            }
        }
    
    
    Don Gagne's avatar
    Don Gagne committed
        QGCViewPanel {
            id:             panel
    
            anchors.fill:   parent
    
    Don Gagne's avatar
    Don Gagne committed
    
    
            FlightMap {
    
                id:                         editorMap
                anchors.fill:               parent
                mapName:                    "MissionEditor"
                allowGCSLocationCenter:     true
                allowVehicleLocationCenter: true
    
    Don Gagne's avatar
    Don Gagne committed
    
    
                // This is the center rectangle of the map which is not obscured by tools
    
    Gus Grubba's avatar
    Gus Grubba committed
                property rect centerViewport:   Qt.rect(_leftToolWidth, _toolbarHeight, editorMap.width - _leftToolWidth - _rightPanelWidth, editorMap.height - _statusHeight - _toolbarHeight)
    
                property real _leftToolWidth:   toolStrip.x + toolStrip.width
                property real _statusHeight:    waypointValuesDisplay.visible ? editorMap.height - waypointValuesDisplay.y : 0
    
                readonly property real animationDuration: 500
    
                // Initial map position duplicates Fly view position
                Component.onCompleted: editorMap.center = QGroundControl.flightMapPosition
    
                Behavior on zoomLevel {
                    NumberAnimation {
                        duration:       editorMap.animationDuration
                        easing.type:    Easing.InOutQuad
                    }
                }
    
                QGCMapPalette { id: mapPal; lightColors: editorMap.isSatelliteMap }
    
                MouseArea {
                    //-- It's a whole lot faster to just fill parent and deal with top offset below
                    //   than computing the coordinate offset.
                    anchors.fill: parent
                    onClicked: {
                        //-- Don't pay attention to items beneath the toolbar.
                        var topLimit = parent.height - ScreenTools.availableHeight
                        if(mouse.y < topLimit) {
                            return
    
                        var coordinate = editorMap.toCoordinate(Qt.point(mouse.x, mouse.y), false /* clipToViewPort */)
                        coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces)
                        coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces)
                        coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces)
    
                        switch (_editingLayer) {
                        case _layerMission:
                            if (_addWaypointOnClick) {
    
                                insertSimpleMissionItem(coordinate, _missionController.visualItems.count)
    
                            } else if (_addROIOnClick) {
                                _addROIOnClick = false
                                insertROIMissionItem(coordinate, _missionController.visualItems.count)
    
                            break
                        case _layerRallyPoints:
    
                            if (_rallyPointController.supported) {
    
                                _rallyPointController.addPoint(coordinate)
    
    Don Gagne's avatar
    Don Gagne committed
                        }
    
                // Add the mission item visuals to the map
                Repeater {
    
                    model: _editingLayer == _layerMission ? _missionController.visualItems : undefined
    
                    delegate: MissionItemMapVisual {
                        map:        editorMap
    
    DonLakeFlyer's avatar
    DonLakeFlyer committed
                        qgcView:    _qgcView
    
                        onClicked:  _missionController.setCurrentPlanViewIndex(sequenceNumber, false)
    
                        visible:    _editingLayer == _layerMission
    
                // Add lines between waypoints
                MissionLineView {
    
                    model: _editingLayer == _layerMission ? _missionController.waypointLines : undefined
    
                // Add the vehicles to the map
                MapItemView {
                    model: QGroundControl.multiVehicleManager.vehicles
                    delegate:
                        VehicleMapItem {
                        vehicle:        object
                        coordinate:     object.coordinate
    
                        map:            editorMap
    
                        size:           ScreenTools.defaultFontPixelHeight * 3
                        z:              QGroundControl.zOrderMapItems - 1
    
                GeoFenceMapVisuals {
                    map:                    editorMap
    
                    myGeoFenceController:   _geoFenceController
    
                    interactive:            _editingLayer == _layerGeoFence
    
                    homePosition:           _missionController.plannedHomePosition
    
                    planView:               true
                }
    
                RallyPointMapVisuals {
                    map:                    editorMap
    
                    myRallyPointController: _rallyPointController
    
                    interactive:            _editingLayer == _layerRallyPoints
                    planView:               true
    
                ToolStrip {
                    id:                 toolStrip
                    anchors.leftMargin: ScreenTools.defaultFontPixelWidth
                    anchors.left:       parent.left
                    anchors.topMargin:  _toolButtonTopMargin
                    anchors.top:        parent.top
                    color:              qgcPal.window
                    title:              qsTr("Plan")
                    z:                  QGroundControl.zOrderWidgets
    
                    showAlternateIcon:  [ false, false, false, masterController.dirty, false, false, false ]
                    rotateImage:        [ false, false, false, masterController.syncInProgress, false, false, false ]
                    animateImage:       [ false, false, false, masterController.dirty, false, false, false ]
                    buttonEnabled:      [ true, true, true, !masterController.syncInProgress, true, true, true ]
                    buttonVisible:      [ true, _waypointsOnlyMode, true, true, true, _showZoom, _showZoom ]
    
                    maxHeight:          mapScale.y - toolStrip.y
    
                    property bool _showZoom: !ScreenTools.isMobile
    
                    model: [
                        {
                            name:       "Waypoint",
                            iconSource: "/qmlimages/MapAddMission.svg",
                            toggle:     true
                        },
    
                        {
                            name:       "ROI",
                            iconSource: "/qmlimages/MapAddMission.svg",
                            toggle:     true
                        },
    
                            name:               _singleComplexItem ? _missionController.complexMissionItemNames[0] : "Pattern",
    
                            iconSource:         "/qmlimages/MapDrawShape.svg",
                            dropPanelComponent: _singleComplexItem ? undefined : patternDropPanel
                        },
    
                        {
                            name:                   "Sync",
                            iconSource:             "/qmlimages/MapSync.svg",
                            alternateIconSource:    "/qmlimages/MapSyncChanged.svg",
                            dropPanelComponent:     syncDropPanel
                        },
    
                        {
                            name:               "Center",
                            iconSource:         "/qmlimages/MapCenter.svg",
                            dropPanelComponent: centerMapDropPanel
                        },
                        {
                            name:               "In",
                            iconSource:         "/qmlimages/ZoomPlus.svg"
                        },
                        {
                            name:               "Out",
                            iconSource:         "/qmlimages/ZoomMinus.svg"
                        }
                    ]
    
                    onClicked: {
                        switch (index) {
                        case 0:
                            _addWaypointOnClick = checked
    
                            _addROIOnClick = false
    
                            break
                        case 1:
    
                            _addROIOnClick = checked
                            _addWaypointOnClick = false
                            break
                        case 2:
    
                            if (_singleComplexItem) {
    
                                addComplexItem(_missionController.complexMissionItemNames[0])
    
                            editorMap.zoomLevel += 0.5
                            break
    
                            editorMap.zoomLevel -= 0.5
                            break
                        }
                    }
                }
    
    Gus Grubba's avatar
    Gus Grubba committed
            }
            //-----------------------------------------------------------
    
            // Right pane for mission editing controls
            Rectangle {
                id:                 rightPanel
    
                height:             ScreenTools.availableHeight
    
                width:              _rightPanelWidth
                color:              qgcPal.window
    
    Gus Grubba's avatar
    Gus Grubba committed
                anchors.bottom:     parent.bottom
                anchors.right:      parent.right
                anchors.rightMargin: ScreenTools.defaultFontPixelWidth
    
    Gus Grubba's avatar
    Gus Grubba committed
            //-------------------------------------------------------
            // Right Panel Controls
    
    Gus Grubba's avatar
    Gus Grubba committed
                anchors.fill:           rightPanel
                Column {
                    id:                 rightControls
    
    Gus Grubba's avatar
    Gus Grubba committed
                    spacing:            ScreenTools.defaultFontPixelHeight * 0.5
    
                    anchors.left:       parent.left
                    anchors.right:      parent.right
    
    Gus Grubba's avatar
    Gus Grubba committed
                    anchors.top:        parent.top
                    anchors.topMargin:  ScreenTools.defaultFontPixelHeight * 0.25
                    //-------------------------------------------------------
                    // Airmap Airspace Control
                    AirspaceControl {
    
    Gus Grubba's avatar
    Gus Grubba committed
                        id:             airspaceControl
                        width:          parent.width
    
    Gus Grubba's avatar
    Gus Grubba committed
                        visible:        _enableAirMap
    
    Gus Grubba's avatar
    Gus Grubba committed
                    //-------------------------------------------------------
                    // Mission Controls (Colapsed)
                    Rectangle {
                        width:      parent.width
    
    Gus Grubba's avatar
    Gus Grubba committed
                        height:     planControlColapsed ? colapsedRow.height + ScreenTools.defaultFontPixelHeight : 0
    
    Gus Grubba's avatar
    Gus Grubba committed
                        color:      qgcPal.missionItemEditor
                        radius:     _radius
    
    Gus Grubba's avatar
    Gus Grubba committed
                        visible:    planControlColapsed && _enableAirMap
    
    Gus Grubba's avatar
    Gus Grubba committed
                        Row {
                            id:                     colapsedRow
                            spacing:                ScreenTools.defaultFontPixelWidth
                            anchors.left:           parent.left
                            anchors.leftMargin:     ScreenTools.defaultFontPixelWidth
                            anchors.verticalCenter: parent.verticalCenter
                            QGCColoredImage {
    
                                width:              height
                                height:             ScreenTools.defaultFontPixelWidth * 2.5
                                sourceSize.height:  height
                                source:             "qrc:/res/waypoint.svg"
                                color:              qgcPal.text
    
    Gus Grubba's avatar
    Gus Grubba committed
                                anchors.verticalCenter: parent.verticalCenter
                            }
                            QGCLabel {
    
                                text:               qsTr("Plan")
                                color:              qgcPal.text
    
    Gus Grubba's avatar
    Gus Grubba committed
                                anchors.verticalCenter: parent.verticalCenter
    
    Gus Grubba's avatar
    Gus Grubba committed
                        QGCColoredImage {
                            width:                  height
                            height:                 ScreenTools.defaultFontPixelWidth * 2.5
                            sourceSize.height:      height
    
                            source:                 QGroundControl.airmapSupported ? "qrc:/airmap/expand.svg" : ""
    
                            color:                  "white"
    
                            visible:                QGroundControl.airmapSupported
    
    Gus Grubba's avatar
    Gus Grubba committed
                            anchors.right:          parent.right
                            anchors.rightMargin:    ScreenTools.defaultFontPixelWidth
                            anchors.verticalCenter: parent.verticalCenter
                        }
                        MouseArea {
                            anchors.fill:   parent
    
                            enabled:        QGroundControl.airmapSupported
    
    Gus Grubba's avatar
    Gus Grubba committed
                            onClicked: {
    
                                if(_activeVehicle) {
                                    _activeVehicle.airspaceController.airspaceVisible = false
                                }
    
    Gus Grubba's avatar
    Gus Grubba committed
                    }
    
    Gus Grubba's avatar
    Gus Grubba committed
                    //-------------------------------------------------------
                    // Mission Controls (Expanded)
                    Rectangle {
                        id:         planExpanded
                        width:      parent.width
    
                        height:     (!planControlColapsed || !_enableAirMap) ? expandedCol.height + ScreenTools.defaultFontPixelHeight : 0
    
    Gus Grubba's avatar
    Gus Grubba committed
                        color:      qgcPal.missionItemEditor
                        radius:     _radius
    
    Gus Grubba's avatar
    Gus Grubba committed
                        visible:    !planControlColapsed || !_enableAirMap
    
    Gus Grubba's avatar
    Gus Grubba committed
                        Item {
                            height:             expandedCol.height
                            anchors.left:       parent.left
                            anchors.right:      parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            Column {
                                id:                     expandedCol
                                spacing:                ScreenTools.defaultFontPixelHeight * 0.5
                                anchors.left:           parent.left
                                anchors.right:          parent.right
                                //-- Header
                                Row {
                                    id:                     expandedRow
                                    spacing:                ScreenTools.defaultFontPixelWidth
                                    anchors.left:           parent.left
                                    anchors.leftMargin:     ScreenTools.defaultFontPixelWidth
                                    readonly property real _buttonRadius: ScreenTools.defaultFontPixelHeight * 0.75
                                    QGCColoredImage {
                                        width:                  height
                                        height:                 ScreenTools.defaultFontPixelWidth * 2.5
                                        sourceSize.height:      height
                                        source:                 "qrc:/res/waypoint.svg"
                                        color:                  qgcPal.text
                                        anchors.verticalCenter: parent.verticalCenter
                                    }
                                    QGCLabel {
                                        text:           qsTr("Plan")
                                        color:          qgcPal.text
                                        visible:        !QGroundControl.corePlugin.options.enablePlanViewSelector
                                        anchors.verticalCenter: parent.verticalCenter
                                    }
                                    ExclusiveGroup {
                                        id: planElementSelectorGroup
                                        onCurrentChanged: {
                                            switch (current) {
                                            case planElementMission:
                                                _editingLayer = _layerMission
                                                break
                                            case planElementGeoFence:
                                                _editingLayer = _layerGeoFence
                                                break
                                            case planElementRallyPoints:
                                                _editingLayer = _layerRallyPoints
                                                break
                                            }
                                        }
                                    }
                                    QGCRadioButton {
                                        id:             planElementMission
                                        exclusiveGroup: planElementSelectorGroup
                                        text:           qsTr("Mission")
                                        checked:        true
                                        visible:        QGroundControl.corePlugin.options.enablePlanViewSelector
                                        anchors.verticalCenter: parent.verticalCenter
                                    }
                                    QGCRadioButton {
                                        id:             planElementGeoFence
                                        exclusiveGroup: planElementSelectorGroup
                                        text:           qsTr("Fence")
                                        visible:        QGroundControl.corePlugin.options.enablePlanViewSelector
                                        anchors.verticalCenter: parent.verticalCenter
                                    }
                                    QGCRadioButton {
                                        id:             planElementRallyPoints
                                        exclusiveGroup: planElementSelectorGroup
                                        text:           qsTr("Rally")
                                        visible:        QGroundControl.corePlugin.options.enablePlanViewSelector
                                        anchors.verticalCenter: parent.verticalCenter
                                    }
                                }
                            }
                        }
                    }
                }
                //-------------------------------------------------------
                // Mission Item Editor
                Item {
                    id:                     missionItemEditor
                    anchors.left:           parent.left
                    anchors.right:          parent.right
                    anchors.top:            rightControls.bottom
                    anchors.topMargin:      ScreenTools.defaultFontPixelHeight * 0.5
                    anchors.bottom:         parent.bottom
                    anchors.bottomMargin:   ScreenTools.defaultFontPixelHeight * 0.25
                    visible:                _editingLayer == _layerMission && !planControlColapsed
                    QGCListView {
                        id:             missionItemEditorListView
                        anchors.fill:   parent
                        spacing:        ScreenTools.defaultFontPixelHeight * 0.5
                        orientation:    ListView.Vertical
                        model:          _missionController.visualItems
                        cacheBuffer:    Math.max(height * 2, 0)
                        clip:           true
                        currentIndex:   _missionController.currentPlanViewIndex
                        highlightMoveDuration: 250
                        visible:        _editingLayer == _layerMission && !planControlColapsed
                        //-- List Elements
                        delegate: MissionItemEditor {
                            map:                editorMap
                            masterController:  _planMasterController
                            missionItem:        object
                            width:              parent.width
                            readOnly:           false
                            rootQgcView:        _qgcView
                            onClicked:  _missionController.setCurrentPlanViewIndex(object.sequenceNumber, false)
                            onRemove: {
                                var removeIndex = index
                                _missionController.removeMissionItem(removeIndex)
                                if (removeIndex >= _missionController.visualItems.count) {
                                    removeIndex--
                                }
                                _missionController.setCurrentPlanViewIndex(removeIndex, true)
                            }
                            onInsertWaypoint:       insertSimpleMissionItem(editorMap.center, index)
                            onInsertComplexItem:    insertComplexMissionItem(complexItemName, editorMap.center, index)
                        }
                    }
                }
                // GeoFence Editor
                GeoFenceEditor {
                    anchors.top:            rightControls.bottom
                    anchors.topMargin:      ScreenTools.defaultFontPixelHeight * 0.5
                    anchors.left:           parent.left
                    anchors.right:          parent.right
                    availableHeight:        ScreenTools.availableHeight
                    myGeoFenceController:   _geoFenceController
                    flightMap:              editorMap
                    visible:                _editingLayer == _layerGeoFence
                }
                // Rally Point Editor
                RallyPointEditorHeader {
                    id:                     rallyPointHeader
                    anchors.top:            rightControls.bottom
                    anchors.topMargin:      ScreenTools.defaultFontPixelHeight * 0.5
                    anchors.left:           parent.left
                    anchors.right:          parent.right
                    visible:                _editingLayer == _layerRallyPoints
                    controller:             _rallyPointController
                }
                RallyPointItemEditor {
                    id:                     rallyPointEditor
                    anchors.top:            rallyPointHeader.bottom
                    anchors.topMargin:      ScreenTools.defaultFontPixelHeight * 0.5
                    anchors.left:           parent.left
                    anchors.right:          parent.right
                    visible:                _editingLayer == _layerRallyPoints && _rallyPointController.points.count
                    rallyPoint:             _rallyPointController.currentRallyPoint
                    controller:             _rallyPointController
    
    Gus Grubba's avatar
    Gus Grubba committed
            }
    
    
            MapScale {
                id:                 mapScale
                anchors.margins:    ScreenTools.defaultFontPixelHeight * (0.66)
                anchors.bottom:     waypointValuesDisplay.visible ? waypointValuesDisplay.top : parent.bottom
                anchors.left:       parent.left
                mapControl:         editorMap
    
                visible:            _toolStripBottom < y
    
            }
    
            MissionItemStatus {
                id:                 waypointValuesDisplay
                anchors.margins:    ScreenTools.defaultFontPixelWidth
                anchors.left:       parent.left
    
                height:             ScreenTools.defaultFontPixelHeight * 7
    
                maxWidth:           parent.width - rightPanel.width - x
    
                anchors.bottom:     parent.bottom
    
                missionItems:       _missionController.visualItems
    
                visible:            _editingLayer === _layerMission && (_toolStripBottom + mapScale.height) < y && QGroundControl.corePlugin.options.showMissionStatus
    
        Component {
            id: syncLoadFromVehicleOverwrite
            QGCViewMessage {
                id:         syncLoadFromVehicleCheck
    
    Don Gagne's avatar
    Don Gagne committed
                message:   qsTr("You have unsaved/unsent changes. Loading from the Vehicle will lose these changes. Are you sure you want to load from the Vehicle?")
    
                function accept() {
                    hideDialog()
    
                    masterController.loadFromVehicle()
    
                }
            }
        }
    
        Component {
            id: syncLoadFromFileOverwrite
            QGCViewMessage {
                id:         syncLoadFromVehicleCheck
    
    DonLakeFlyer's avatar
    DonLakeFlyer committed
                message:   qsTr("You have unsaved/unsent changes. Loading from a file will lose these changes. Are you sure you want to load from a file?")
    
                function accept() {
                    hideDialog()
    
                    masterController.loadFromSelectedFile()
    
        Component {
            id: removeAllPromptDialog
            QGCViewMessage {
    
                message: qsTr("Are you sure you want to remove all items? ") +
                         (_planMasterController.offline ? "" : qsTr("This will also remove all items from the vehicle."))
    
                function accept() {
    
                    if (_planMasterController.offline) {
                        masterController.removeAll()
                    } else {
                        masterController.removeAllFromVehicle()
                    }
    
        //- ToolStrip DropPanel Components
    
        Component {
            id: centerMapDropPanel
    
            CenterMapDropPanel {
                map:            editorMap
                fitFunctions:   mapFitFunctions
            }
        }
    
    
        Component {
            id: patternDropPanel
    
            ColumnLayout {
                spacing:    ScreenTools.defaultFontPixelWidth * 0.5
    
                QGCLabel { text: qsTr("Create complex pattern:") }
    
                Repeater {
    
                    model: _missionController.complexMissionItemNames
    
    
                    QGCButton {
                        text:               modelData
                        Layout.fillWidth:   true
    
                        onClicked: {
    
                            addComplexItem(modelData)
    
                            dropPanel.hide()
                        }
                    }
                }
            } // Column
        }
    
            id: syncDropPanel
    
            Column {
                id:         columnHolder
                spacing:    _margin
    
                property string _overwriteText: (_editingLayer == _layerMission) ? qsTr("Mission overwrite") : ((_editingLayer == _layerGeoFence) ? qsTr("GeoFence overwrite") : qsTr("Rally Points overwrite"))
    
                QGCLabel {
                    width:      sendSaveGrid.width
                    wrapMode:   Text.WordWrap
    
                    text:       masterController.dirty ?
    
                                    qsTr("You have unsaved changes. You should upload to your vehicle, or save to a file:") :
                                    qsTr("Sync:")
    
                GridLayout {
                    id:                 sendSaveGrid
                    columns:            2
                    anchors.margins:    _margin
                    rowSpacing:         _margin
                    columnSpacing:      ScreenTools.defaultFontPixelWidth
    
                    QGCButton {
                        text:               qsTr("Upload")
                        Layout.fillWidth:   true
    
                        enabled:            !masterController.offline && !masterController.syncInProgress
    
                        onClicked: {
                            dropPanel.hide()
    
                            masterController.upload()
    
                    QGCButton {
                        text:               qsTr("Download")
                        Layout.fillWidth:   true
    
                        enabled:            !masterController.offline && !masterController.syncInProgress
    
                        onClicked: {
                            dropPanel.hide()
    
                            if (masterController.dirty) {
    
                                _qgcView.showDialog(syncLoadFromVehicleOverwrite, columnHolder._overwriteText, _qgcView.showDialogDefaultWidth, StandardButton.Yes | StandardButton.Cancel)
                            } else {
    
                                masterController.loadFromVehicle()
    
                    QGCButton {
                        text:               qsTr("Save To File...")
                        Layout.fillWidth:   true
    
                        enabled:            !masterController.syncInProgress
    
                        onClicked: {
                            dropPanel.hide()
    
                            masterController.saveToSelectedFile()
    
                        }
                    }
    
                    QGCButton {
                        text:               qsTr("Load From File...")
                        Layout.fillWidth:   true
    
                        enabled:            !masterController.syncInProgress
    
                        onClicked: {
                            dropPanel.hide()
    
                            if (masterController.dirty) {
    
                                _qgcView.showDialog(syncLoadFromFileOverwrite, columnHolder._overwriteText, _qgcView.showDialogDefaultWidth, StandardButton.Yes | StandardButton.Cancel)
                            } else {
    
                                masterController.loadFromSelectedFile()
    
                            }
                        }
                    }
    
                    QGCButton {
                        text:               qsTr("Remove All")
                        Layout.fillWidth:   true
                        onClicked:  {
                            dropPanel.hide()
                            _qgcView.showDialog(removeAllPromptDialog, qsTr("Remove all"), _qgcView.showDialogDefaultWidth, StandardButton.Yes | StandardButton.No)
                        }
                    }
    
    
                    QGCButton {
                        text:               qsTr("Save KML...")
                        Layout.fillWidth:   true
                        enabled:            !masterController.syncInProgress
                        onClicked: {
    
                            // First point do not count
                            if (_visualItems.count < 2) {
                                _qgcView.showDialog(noItemForKML, qsTr("KML"), _qgcView.showDialogDefaultWidth, StandardButton.Cancel)
                                return
                            }
    
                            dropPanel.hide()
                            masterController.saveKmlToSelectedFile()
                        }
                    }
    
    Don Gagne's avatar
    Don Gagne committed
    } // QGCVIew