From 7526fa169f9166e60073943ee46bfcf51fbb5cdc Mon Sep 17 00:00:00 2001 From: Jean Felder Date: Tue, 4 Feb 2025 15:49:28 +0100 Subject: [PATCH] postprocessing: Use QgsLayerTreeRegistryBridge to add layers When a profile tool is already opened, the output of a procssing is not added to its layer tree. This is because it relies on a `QgsLayerTreeRegistryBridge`. Indeed, `QgsLayerTreeRegistryBridge` listens to the `QgsProject::legendLayersAdded()` signal in order to update the elevation profile tree view. However this signal is not triggered by the current logic in `Postprocessing.py`because `QgsProject::addMaplayer` is called with `addToLegend` set to False. Then, the layer is added to the tree by calling `QgsLayerTreeGroup::insertChildNode`. This issue is fixed by creating a `QgsLayerTreeRegistryBridge::InsertionPoint` to set the insertion point and then calling `QgsProject::addMaplayer` with `addToLegend` set to True. --- .../plugins/processing/gui/Postprocessing.py | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/python/plugins/processing/gui/Postprocessing.py b/python/plugins/processing/gui/Postprocessing.py index d36ce1f34b53..f495c2af0091 100644 --- a/python/plugins/processing/gui/Postprocessing.py +++ b/python/plugins/processing/gui/Postprocessing.py @@ -35,6 +35,7 @@ QgsLayerTreeLayer, QgsLayerTreeGroup, QgsLayerTreeNode, + QgsLayerTreeRegistryBridge, ) from qgis.utils import iface @@ -237,8 +238,6 @@ def handleAlgorithmResults( # output layer already exists in the destination project owned_map_layer = context.temporaryLayerStore().takeMapLayer(layer) if owned_map_layer: - details.project.addMapLayer(owned_map_layer, False) - # we don't add the layer to the tree yet -- that's done # later, after we've sorted all added layers layer_tree_layer = create_layer_tree_layer(owned_map_layer, details) @@ -277,10 +276,15 @@ def handleAlgorithmResults( current_selected_node = iface.layerTreeView().currentNode() iface.layerTreeView().setUpdatesEnabled(False) + # store the current intersection point to restore it later + previous_insertion_point = ( + details.project.layerTreeRegistryBridge().layerInsertionPoint() + ) for group, layer_node in sorted_layer_tree_layers: layer_node.removeCustomProperty(SORT_ORDER_CUSTOM_PROPERTY) + insertion_point: Optional[QgsLayerTreeRegistryBridge.InsertionPoint] = None if group is not None: - group.insertChildNode(0, layer_node) + insertion_point = QgsLayerTreeRegistryBridge.InsertionPoint(group, 0) else: # no destination group for this layer, so should be placed # above the current layer @@ -289,16 +293,32 @@ def handleAlgorithmResults( current_node_index = current_node_group.children().index( current_selected_node ) - current_node_group.insertChildNode(current_node_index, layer_node) + insertion_point = QgsLayerTreeRegistryBridge.InsertionPoint( + current_node_group, current_node_index + ) elif isinstance(current_selected_node, QgsLayerTreeGroup): - current_selected_node.insertChildNode(0, layer_node) + insertion_point = QgsLayerTreeRegistryBridge.InsertionPoint( + current_selected_node, 0 + ) elif context.project(): - context.project().layerTreeRoot().insertChildNode(0, layer_node) + insertion_point = QgsLayerTreeRegistryBridge.InsertionPoint() + + if insertion_point: + details.project.layerTreeRegistryBridge().setLayerInsertionPoint( + insertion_point + ) + + details.project.addMapLayer(layer_node.layer()) if not have_set_active_layer and iface is not None: iface.setActiveLayer(layer_node.layer()) have_set_active_layer = True + # reset to the previous insertion point + details.project.layerTreeRegistryBridge().setLayerInsertionPoint( + previous_insertion_point + ) + # all layers have been added to the layer tree, so safe to call # postProcessors now for layer, details in layers_to_post_process: