Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/PlanView/MissionItemEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,14 @@ Rectangle {
readonly property real _trashSize: commandPicker.height * 0.75
readonly property bool _waypointsOnlyMode: QGroundControl.corePlugin.options.missionWaypointsOnly

// setSource() injects missionItem before internal bindings activate
function _loadEditor() {
// setSource() injects missionItem before internal bindings activate.
// Called on completion and by PlanTreeView when the current item changes.
// Intentionally NOT driven by a Connections to missionItem: missionItem
// outlives this delegate, and a released-but-not-yet-deleted delegate
// receiving isCurrentItemChanged would call setSource() on a Loader whose
// QML context is already invalidated ("Cannot create a component in an
// invalid context"). PlanTreeView only reaches live delegates.
function reloadEditor() {
if (missionItem.isCurrentItem) {
editorLoader.setSource(missionItem.editorQml, {
missionItem: _root.missionItem,
Expand All @@ -55,11 +61,6 @@ Rectangle {
}
}

Connections {
target: missionItem
function onIsCurrentItemChanged() { _root._loadEditor() }
}

QGCPalette {
id: qgcPal
colorGroupEnabled: enabled
Expand Down Expand Up @@ -351,7 +352,7 @@ Rectangle {
anchors.top: topRowLayout.bottom
asynchronous: true

Component.onCompleted: _root._loadEditor()
Component.onCompleted: _root.reloadEditor()
}

onHeightChanged: {
Expand Down
28 changes: 27 additions & 1 deletion src/PlanView/PlanTreeView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ TreeView {
QGCFlickableScrollIndicator { parent: root; orientation: QGCFlickableScrollIndicator.Vertical }

property int _lastMissionItemCount: 0
property int _lastPlanViewSeqNum: -1

Connections {
target: root._missionController.visualItems
Expand Down Expand Up @@ -94,7 +95,29 @@ TreeView {
root.editingLayerChangeRequested(PlanEditLayers.layerMission)
}
function onPlanViewStateChanged() {
// Current item changed — bring it on-screen if completely off-screen.
// planViewStateChanged is also emitted for forced recalcs (home position
// set, settings changes) where the current item is unchanged. Skip the
// editor reload in that case to avoid tearing down the current editor
// (and losing focus/UI state) for no reason.
if (_missionController.currentPlanViewSeqNum === root._lastPlanViewSeqNum) {
return
}
root._lastPlanViewSeqNum = _missionController.currentPlanViewSeqNum

// Current item changed — reload the inline editors of the loaded
// mission item delegates. Driven from here rather than from a
// Connections inside MissionItemEditor because a released-but-not-
// yet-deleted delegate would still receive isCurrentItemChanged and
// trigger a Loader load in an invalidated QML context. Iterating
// the table only ever reaches live delegates.
for (let row = Math.max(root.topRow, 0); row <= root.bottomRow; row++) {
let delegateItem = root.itemAtCell(Qt.point(0, row))
if (delegateItem && delegateItem.nodeType === "missionItem" && delegateItem.editorItem) {
delegateItem.editorItem.reloadEditor()
}
Comment on lines +113 to +117
}

// Bring the new current item on-screen if completely off-screen.
// Fine-tuned scroll happens later via editorExpandedAndLoaded.
var item = _missionController.currentPlanViewItem
if (item) {
Expand Down Expand Up @@ -218,6 +241,9 @@ TreeView {
readonly property string nodeType: model.nodeType
readonly property bool separator: model.separator ?? false

// Loaded editor item, reached by PlanTreeView's onPlanViewStateChanged
readonly property Item editorItem: loader.item

// In create-new-plan mode, only the Plan Info and Defaults groups and their children are enabled
readonly property bool _enabledInCreateMode: nodeType === "planFileGroup" || nodeType === "planFileInfo"
|| nodeType === "defaultsGroup" || nodeType === "defaultsInfo"
Expand Down
Loading