8import QGroundControl.Controls
9import QGroundControl.FactControls
11/// Mission item edit control
14 height: _currentItem ? (editorLoader.y + editorLoader.height + _innerMargin) : (topRowLayout.y + topRowLayout.height + _margin)
15 color: _currentItem ? qgcPal.buttonHighlight : qgcPal.windowShade
17 opacity: _currentItem ? 1.0 : 0.7
18 border.width: _readyForSave ? 0 : 2
19 border.color: qgcPal.warningText
21 property var map ///< Map control
22 property var masterController
23 property var missionItem ///< MissionItem associated with this editor
24 property bool readOnly ///< true: read only view, false: full editing view
28 signal selectNextNotReadyItem
30 property var _masterController: masterController
31 property var _missionController: _masterController.missionController
32 property bool _currentItem: missionItem.isCurrentItem
33 property color _outerTextColor: _currentItem ? qgcPal.buttonHighlightText : qgcPal.text
34 property bool _noMissionItemsAdded: _missionController.visualItems ? _missionController.visualItems.count <= 1 : true
35 property real _sectionSpacer: ScreenTools.defaultFontPixelWidth / 2 // spacing between section headings
36 property bool _singleComplexItem: _missionController.complexMissionItemNames.length === 1
37 property bool _readyForSave: missionItem.readyForSaveState === VisualMissionItem.ReadyForSave
39 readonly property real _editFieldWidth: Math.min(width - _innerMargin * 2, ScreenTools.defaultFontPixelWidth * 12)
40 readonly property real _margin: ScreenTools.defaultFontPixelWidth / 2
41 readonly property real _innerMargin: 2
42 readonly property real _radius: ScreenTools.defaultFontPixelWidth / 2
43 readonly property real _hamburgerSize: commandPicker.height * 0.75
44 readonly property real _trashSize: commandPicker.height * 0.75
45 readonly property bool _waypointsOnlyMode: QGroundControl.corePlugin.options.missionWaypointsOnly
49 colorGroupEnabled: enabled
59 if (mainWindow.allowViewSwitch()) {
60 currentItemScope.focus = true
67 QGCPopupDialogFactory {
68 id: editPositionDialogFactory
70 dialogComponent: editPositionDialog
74 id: editPositionDialog
77 coordinate: missionItem.isSurveyItem ? missionItem.centerCoordinate : missionItem.coordinate
78 onCoordinateChanged: missionItem.isSurveyItem ? missionItem.centerCoordinate = coordinate : missionItem.coordinate = coordinate
84 anchors.margins: _margin
85 anchors.left: parent.left
86 anchors.top: parent.top
90 id: notReadyForSaveIndicator
91 anchors.verticalCenter: parent.verticalCenter
95 border.color: qgcPal.warningText
98 visible: !_readyForSave
101 id: readyForSaveLabel
102 anchors.centerIn: parent
103 //: Indicator in Plan view to show mission item is not ready for save/send
105 color: qgcPal.warningText
106 font.pointSize: ScreenTools.smallFontPointSize
112 anchors.verticalCenter: parent.verticalCenter
113 height: _hamburgerSize
115 sourceSize.height: height
116 fillMode: Image.PreserveAspectFit
119 color: qgcPal.buttonHighlightText
120 visible: _currentItem && missionItem.sequenceNumber !== 0
121 source: "/res/TrashDelete.svg"
131 anchors.verticalCenter: parent.verticalCenter
132 height: ScreenTools.implicitComboBoxHeight
133 width: innerLayout.width
134 visible: !commandLabel.visible
138 anchors.verticalCenter: parent.verticalCenter
141 property real _padding: ScreenTools.comboBoxPadding
143 QGCLabel { text: missionItem.commandName }
146 height: ScreenTools.defaultFontPixelWidth
148 fillMode: Image.PreserveAspectFit
152 source: "/qmlimages/arrow-down.png"
158 onClicked: commandDialogFactory.open()
161 QGCPopupDialogFactory {
162 id: commandDialogFactory
164 dialogComponent: commandDialog
170 MissionCommandDialog {
171 vehicle: masterController.controllerVehicle
172 missionItem: _root.missionItem
174 // FIXME: Disabling fly through commands doesn't work since you may need to change from an RTL to something else
175 flyThroughCommandsAllowed: true //_missionController.flyThroughCommandsAllowed
182 anchors.verticalCenter: parent.verticalCenter
183 width: commandPicker.width
184 height: commandPicker.height
185 visible: !missionItem.isCurrentItem || !missionItem.isSimpleItem || _waypointsOnlyMode || missionItem.isTakeoffItem
186 verticalAlignment: Text.AlignVCenter
187 text: missionItem.commandName
188 color: _outerTextColor
193 id: hamburgerMenuDropPanelComponent
196 id: hamburgerMenuDropPanel
199 sourceComponent: Component {
201 spacing: ScreenTools.defaultFontPixelHeight / 2
204 Layout.fillWidth: true
205 text: qsTr("Move to vehicle position")
206 enabled: _activeVehicle && missionItem.specifiesCoordinate
209 missionItem.coordinate = _activeVehicle.coordinate
210 hamburgerMenuDropPanel.close()
213 property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
217 Layout.fillWidth: true
218 text: qsTr("Move to previous item position")
219 enabled: _missionController.previousCoordinate.isValid
221 missionItem.coordinate = _missionController.previousCoordinate
222 hamburgerMenuDropPanel.close()
227 Layout.fillWidth: true
228 text: qsTr("Edit position...")
229 enabled: missionItem.specifiesCoordinate
231 editPositionDialogFactory.open()
232 hamburgerMenuDropPanel.close()
237 Layout.fillWidth: true
238 Layout.preferredHeight: 1
239 color: qgcPal.groupBorder
243 Layout.fillWidth: true
244 text: qsTr("Show all values")
245 visible: QGroundControl.corePlugin.showAdvancedUI
246 checked: missionItem.isSimpleItem ? missionItem.rawEdit : false
247 enabled: missionItem.isSimpleItem && !_waypointsOnlyMode
250 missionItem.rawEdit = checked
251 if (missionItem.rawEdit && !missionItem.friendlyEditAllowed) {
252 missionItem.rawEdit = false
254 QGroundControl.showMessageDialog(_root, qsTr("Mission Edit"), qsTr("You have made changes to the mission item which cannot be shown in Simple Mode"))
256 hamburgerMenuDropPanel.close()
261 Layout.fillWidth: true
262 Layout.preferredHeight: 1
263 color: qgcPal.groupBorder
267 text: qsTr("Item #%1").arg(missionItem.sequenceNumber)
276 id: missionStartHamburgerMenuDropPanelComponent
279 id: missionStartHamburgerMenuDropPanel
282 sourceComponent: Component {
284 spacing: ScreenTools.defaultFontPixelHeight / 2
287 Layout.fillWidth: true
288 text: qsTr("Offset mission...")
289 enabled: _missionController.plannedHomePosition.isValid
291 offsetMissionDialogComponent.createObject(mainWindow).open()
292 missionStartHamburgerMenuDropPanel.close()
297 Layout.fillWidth: true
298 text: qsTr("Rotate mission...")
299 enabled: _missionController.plannedHomePosition.isValid
301 rotateMissionDialogComponent.createObject(mainWindow).open()
302 missionStartHamburgerMenuDropPanel.close()
307 Layout.fillWidth: true
308 text: qsTr("Edit mission position...")
309 enabled: _missionController.plannedHomePosition.isValid
311 editMissionPositionDialogComponent.createObject(mainWindow).open()
312 missionStartHamburgerMenuDropPanel.close()
321 id: offsetMissionDialogComponent
325 title: qsTr("Offset Mission")
326 buttons: Dialog.Cancel | Dialog.Ok
329 property real _margin: ScreenTools.defaultFontPixelWidth / 2
330 property real _textFieldWidth: ScreenTools.defaultFontPixelWidth * 20
331 property real _labelWidth: ScreenTools.defaultFontPixelWidth * 14
338 Layout.fillWidth: true
341 text: qsTr("East (m)")
342 Layout.preferredWidth: _labelWidth
343 Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
349 Layout.preferredWidth: _textFieldWidth
350 Layout.fillWidth: true
351 inputMethodHints: Qt.ImhPreferNumbers
352 validator: DoubleValidator {
353 notation: DoubleValidator.StandardNotation
361 Layout.fillWidth: true
364 text: qsTr("North (m)")
365 Layout.preferredWidth: _labelWidth
366 Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
372 Layout.preferredWidth: _textFieldWidth
373 Layout.fillWidth: true
374 inputMethodHints: Qt.ImhPreferNumbers
375 validator: DoubleValidator {
376 notation: DoubleValidator.StandardNotation
384 Layout.fillWidth: true
388 Layout.preferredWidth: _labelWidth
389 Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
395 Layout.preferredWidth: _textFieldWidth
396 Layout.fillWidth: true
397 inputMethodHints: Qt.ImhPreferNumbers
398 validator: DoubleValidator {
399 notation: DoubleValidator.StandardNotation
406 Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
409 id: offsetTakeoffCheck
410 text: qsTr("Also move takeoff items")
411 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
415 id: offsetLandingCheck
416 text: qsTr("Also move landing items")
417 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
422 Layout.fillWidth: true
423 Layout.maximumWidth: _labelWidth + _textFieldWidth
425 wrapMode: Text.WordWrap
426 font.pointSize: ScreenTools.smallFontPointSize
428 text: qsTr("Note: Home altitude is not modified.")
433 var east = Number.fromLocaleString(Qt.locale(), eastField.text)
434 var north = Number.fromLocaleString(Qt.locale(), northField.text)
435 var up = Number.fromLocaleString(Qt.locale(), upField.text)
437 if (isNaN(east)) east = 0
438 if (isNaN(north)) north = 0
439 if (isNaN(up)) up = 0
441 _missionController.offsetMission(
445 offsetTakeoffCheck.checked,
446 offsetLandingCheck.checked
453 id: rotateMissionDialogComponent
457 title: qsTr("Rotate Mission")
458 buttons: Dialog.Cancel | Dialog.Ok
461 property real _margin: ScreenTools.defaultFontPixelWidth / 2
462 property real _textFieldWidth: ScreenTools.defaultFontPixelWidth * 20
463 property real _labelWidth: ScreenTools.defaultFontPixelWidth * 14
470 Layout.fillWidth: true
473 text: qsTr("Clockwise (°)")
474 Layout.preferredWidth: _labelWidth
475 Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
481 Layout.preferredWidth: _textFieldWidth
482 Layout.fillWidth: true
483 inputMethodHints: Qt.ImhPreferNumbers
484 validator: DoubleValidator {
485 notation: DoubleValidator.StandardNotation
492 Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
495 id: rotateTakeoffCheck
496 text: qsTr("Also move takeoff items")
497 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
501 id: rotateLandingCheck
502 text: qsTr("Also move landing items")
503 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
508 Layout.fillWidth: true
509 Layout.maximumWidth: _labelWidth + _textFieldWidth
511 wrapMode: Text.WordWrap
512 font.pointSize: ScreenTools.smallFontPointSize
514 text: qsTr("Note: Complex items are rotated by moving their reference coordinate: their geometry and orientation are not changed.")
519 var degreesCW = Number.fromLocaleString(Qt.locale(), degreesCWField.text)
521 if (isNaN(degreesCW)) degreesCW = 0
523 _missionController.rotateMission(
525 rotateTakeoffCheck.checked,
526 rotateLandingCheck.checked
533 id: editMissionPositionDialogComponent
536 id: missionEditPositionDialog
538 coordinate: _missionController.plannedHomePosition
539 onCoordinateChanged: _missionController.repositionMission(coordinate)
546 anchors.margins: _margin
547 anchors.right: parent.right
548 anchors.verticalCenter: topRowLayout.verticalCenter
549 width: _hamburgerSize
550 height: _hamburgerSize
551 sourceSize.height: _hamburgerSize
552 source: "qrc:/qmlimages/Hamburger.svg"
553 visible: missionItem.isCurrentItem
554 color: qgcPal.buttonHighlightText
558 onClicked: (position) => {
559 currentItemScope.focus = true
560 position = Qt.point(position.x, position.y)
561 // For some strange reason using mainWindow in mapToItem doesn't work, so we use globals.parent instead which also gets us mainWindow
562 position = mapToItem(globals.parent, position)
564 var panelComponent = (missionItem.sequenceNumber === 0)
565 ? missionStartHamburgerMenuDropPanelComponent
566 : hamburgerMenuDropPanelComponent
567 var dropPanel = panelComponent.createObject(mainWindow, { clickRect: Qt.rect(position.x, position.y, 0, 0) })
575 id: notReadyForSaveLabel
576 anchors.margins: _margin
577 anchors.left: notReadyForSaveIndicator.right
578 anchors.right: parent.right
579 anchors.top: commandPicker.bottom
580 visible: _currentItem && !_readyForSave
581 text: missionItem.readyForSaveState === VisualMissionItem.NotReadyForSaveTerrain ?
582 qsTr("Incomplete: Waiting on terrain data.") :
583 qsTr("Incomplete: Item not fully specified.")
584 wrapMode: Text.WordWrap
585 horizontalAlignment: Text.AlignHCenter
586 color: qgcPal.warningText
593 anchors.margins: _innerMargin
594 anchors.left: parent.left
595 anchors.top: topRowLayout.bottom
596 source: _currentItem ? missionItem.editorQml : ""
599 property var masterController: _masterController
600 property real availableWidth: _root.width - (anchors.margins * 2) ///< How wide the editor should be
601 property var editorRoot: _root