Skip to content
Permalink
Browse files
Ensure group logic works nicely with nested grouped layers
  • Loading branch information
nyalldawson committed Nov 25, 2021
1 parent 23c4ead commit bcde12d88f1b14c5c36e1565a6aeba4b20622ff4
Showing with 171 additions and 1 deletion.
  1. +24 −1 src/core/layertree/qgslayertreegroup.cpp
  2. +1 −0 src/core/layertree/qgslayertreegroup.h
  3. +146 −0 tests/src/python/test_qgslayertree.py
@@ -466,6 +466,7 @@ QgsGroupLayer *QgsLayerTreeGroup::groupLayer()
void QgsLayerTreeGroup::setGroupLayer( QgsGroupLayer *layer )
{
mGroupLayer.setLayer( layer );
refreshParentGroupLayerMembers();
}

QgsGroupLayer *QgsLayerTreeGroup::convertToGroupLayer( const QgsGroupLayer::LayerOptions &options )
@@ -481,6 +482,19 @@ QgsGroupLayer *QgsLayerTreeGroup::convertToGroupLayer( const QgsGroupLayer::Laye
return res.release();
}

void QgsLayerTreeGroup::refreshParentGroupLayerMembers()
{
QgsLayerTreeGroup *parentGroup = qobject_cast< QgsLayerTreeGroup * >( parent() );
while ( parentGroup )
{
if ( QgsLayerTree *layerTree = qobject_cast< QgsLayerTree * >( parentGroup ) )
layerTree->emit layerOrderChanged();

parentGroup->updateGroupLayers();
parentGroup = qobject_cast< QgsLayerTreeGroup * >( parentGroup->parent() );
}
}

QStringList QgsLayerTreeGroup::findLayerIds() const
{
QStringList lst;
@@ -498,7 +512,10 @@ void QgsLayerTreeGroup::nodeVisibilityChanged( QgsLayerTreeNode *node )
{
int childIndex = mChildren.indexOf( node );
if ( childIndex == -1 )
{
updateGroupLayers();
return; // not a direct child - ignore
}

if ( mMutuallyExclusive )
{
@@ -561,13 +578,19 @@ void QgsLayerTreeGroup::updateGroupLayers()
else if ( QgsLayerTreeGroup *childGroup = qobject_cast< QgsLayerTreeGroup * >( *it ) )
{
if ( childGroup->isVisible() )
findGroupLayerChildren( childGroup );
{
if ( QgsGroupLayer *groupLayer = childGroup->groupLayer() )
layers << groupLayer;
else
findGroupLayerChildren( childGroup );
}
}
}
};
findGroupLayerChildren( this );

groupLayer->setChildLayers( layers );
refreshParentGroupLayerMembers();
}

void QgsLayerTreeGroup::setItemVisibilityCheckedRecursive( bool checked )
@@ -309,6 +309,7 @@ class CORE_EXPORT QgsLayerTreeGroup : public QgsLayerTreeNode

void init();
void updateGroupLayers();
void refreshParentGroupLayerMembers();

QgsMapLayerRef mGroupLayer;
};
@@ -376,6 +376,152 @@ def test_layer_order_with_group_layer(self):
self.assertEqual(p.layerTreeRoot().layerOrder(), [layer, group_layer, layer4])
self.assertEqual(group_layer.childLayers(), [layer3, layer2])

def test_nested_groups(self):
"""
Test logic relating to nested groups with group layers
"""
p = QgsProject()
layer = QgsVectorLayer("Point?field=fldtxt:string",
"layer1", "memory")
p.addMapLayer(layer, False)
layer2 = QgsVectorLayer("Point?field=fldtxt:string",
"layer2", "memory")
p.addMapLayer(layer2, False)
layer3 = QgsVectorLayer("Point?field=fldtxt:string",
"layer3", "memory")
p.addMapLayer(layer3, False)
layer4 = QgsVectorLayer("Point?field=fldtxt:string",
"layer4", "memory")
p.addMapLayer(layer4, False)

group_node = p.layerTreeRoot().addGroup('my group')
group_node.addLayer(layer)
group_node.addLayer(layer2)

child_group = group_node.addGroup('child')
layer3_node = child_group.addLayer(layer3)

grandchild_group = child_group.addGroup('grandchild')
layer4_node = grandchild_group.addLayer(layer4)

self.assertEqual(p.layerTreeRoot().layerOrder(), [layer, layer2, layer3, layer4])

spy = QSignalSpy(p.layerTreeRoot().layerOrderChanged)

options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext())
group_layer = group_node.convertToGroupLayer(options)
p.addMapLayer(group_layer, False)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [layer4, layer3, layer2, layer])
spy_count = len(spy)
self.assertEqual(spy_count, 1)

grandchild_group_layer = grandchild_group.convertToGroupLayer(options)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer])
self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

layer4_node.setItemVisibilityChecked(False)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer])
self.assertEqual(grandchild_group_layer.childLayers(), [])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

layer4_node.setItemVisibilityChecked(True)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer])
self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

grandchild_group.setItemVisibilityChecked(False)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [layer3, layer2, layer])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

grandchild_group.setItemVisibilityChecked(True)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer])
self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

child_group_layer = child_group.convertToGroupLayer(options)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer])
self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3])
self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

layer4_node.setItemVisibilityChecked(False)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer])
self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3])
self.assertEqual(grandchild_group_layer.childLayers(), [])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

layer4_node.setItemVisibilityChecked(True)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer])
self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3])
self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

grandchild_group.setItemVisibilityChecked(False)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer])
self.assertEqual(child_group_layer.childLayers(), [layer3])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

grandchild_group.setItemVisibilityChecked(True)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer])
self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3])
self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

layer3_node.setItemVisibilityChecked(False)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer])
self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer])
self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

layer3_node.setItemVisibilityChecked(True)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer])
self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3])
self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

grandchild_group.setGroupLayer(None)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer])
self.assertEqual(child_group_layer.childLayers(), [layer4, layer3])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

child_group.setGroupLayer(None)
self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
self.assertEqual(group_layer.childLayers(), [layer4, layer3, layer2, layer])
self.assertGreater(len(spy), spy_count)
spy_count = len(spy)

group_node.setGroupLayer(None)
self.assertEqual(p.layerTreeRoot().layerOrder(), [layer, layer2, layer3, layer4])
self.assertGreater(len(spy), spy_count)


if __name__ == '__main__':
unittest.main()

0 comments on commit bcde12d

Please sign in to comment.