Fix duplicate layers in custom layer order panel

Fixes #21955
This commit is contained in:
Nyall Dawson 2019-04-30 12:24:23 +10:00
parent 9dcdbbcff4
commit 346cb388cf
2 changed files with 35 additions and 1 deletions

View File

@ -210,7 +210,18 @@ void QgsLayerTree::nodeRemovedChildren()
++layer;
}
// we need to ensure that the customLayerOrderChanged signal is ALWAYS raised
// here, since that order HAS changed due to removal of the child!
// setCustomLayerOrder will only emit this signal when the layers list
// at this stage is different to the stored customer layer order. If this
// isn't the case (i.e. the lists ARE the same) then manually emit the
// signal
const bool emitSignal = _qgis_listRawToQPointer( layers ) == mCustomLayerOrder;
setCustomLayerOrder( layers );
if ( emitSignal )
emit customLayerOrderChanged();
emit layerOrderChanged();
}

View File

@ -19,7 +19,8 @@ import os
from qgis.core import (
QgsLayerTree,
QgsProject,
QgsVectorLayer
QgsVectorLayer,
QgsLayerTreeLayer
)
from qgis.testing import start_app, unittest
from utilities import (unitTestDataPath)
@ -78,6 +79,28 @@ class TestQgsLayerTree(unittest.TestCase):
prj.clear()
self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [])
def testCustomLayerOrderChanged(self):
layer = QgsVectorLayer("Point?field=fldtxt:string",
"layer1", "memory")
layer2 = QgsVectorLayer("Point?field=fldtxt:string",
"layer2", "memory")
layer_tree = QgsLayerTree()
layer_order_changed_spy = QSignalSpy(layer_tree.customLayerOrderChanged)
layer1_node = QgsLayerTreeLayer(layer)
layer_tree.addChildNode(layer1_node)
self.assertEqual(len(layer_order_changed_spy), 1)
layer2_node = QgsLayerTreeLayer(layer2)
layer_tree.addChildNode(layer2_node)
self.assertEqual(len(layer_order_changed_spy), 2)
# simulate a layer move in the tree
layer3_node = QgsLayerTreeLayer(layer)
layer_tree.addChildNode(layer3_node)
self.assertEqual(len(layer_order_changed_spy), 3)
layer_tree.removeChildNode(layer1_node)
self.assertEqual(len(layer_order_changed_spy), 4)
if __name__ == '__main__':
unittest.main()