@@ -37,6 +37,8 @@ QgsMapThemeCollection::MapThemeLayerRecord QgsMapThemeCollection::createThemeLay
37
37
MapThemeLayerRecord layerRec ( nodeLayer->layer () );
38
38
layerRec.usingCurrentStyle = true ;
39
39
layerRec.currentStyle = nodeLayer->layer ()->styleManager ()->currentStyle ();
40
+ layerRec.expandedLayerNode = nodeLayer->isExpanded ();
41
+ layerRec.expandedLegendItems = nodeLayer->customProperty ( QStringLiteral ( " expandedLegendNodes" ) ).toStringList ().toSet ();
40
42
41
43
// get checked legend items
42
44
bool hasCheckableItems = false ;
@@ -63,12 +65,27 @@ QgsMapThemeCollection::MapThemeLayerRecord QgsMapThemeCollection::createThemeLay
63
65
return layerRec;
64
66
}
65
67
68
+ static QString _groupId ( QgsLayerTreeNode *node )
69
+ {
70
+ QStringList lst;
71
+ while ( node->parent () )
72
+ {
73
+ lst.prepend ( node->name () );
74
+ node = node->parent ();
75
+ }
76
+ return lst.join ( ' /' );
77
+ }
78
+
66
79
void QgsMapThemeCollection::createThemeFromCurrentState ( QgsLayerTreeGroup *parent, QgsLayerTreeModel *model, QgsMapThemeCollection::MapThemeRecord &rec )
67
80
{
68
81
Q_FOREACH ( QgsLayerTreeNode *node, parent->children () )
69
82
{
70
83
if ( QgsLayerTree::isGroup ( node ) )
84
+ {
71
85
createThemeFromCurrentState ( QgsLayerTree::toGroup ( node ), model, rec );
86
+ if ( node->isExpanded () )
87
+ rec.mExpandedGroupNodes .insert ( _groupId ( node ) );
88
+ }
72
89
else if ( QgsLayerTree::isLayer ( node ) )
73
90
{
74
91
QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer ( node );
@@ -81,6 +98,7 @@ void QgsMapThemeCollection::createThemeFromCurrentState( QgsLayerTreeGroup *pare
81
98
QgsMapThemeCollection::MapThemeRecord QgsMapThemeCollection::createThemeFromCurrentState ( QgsLayerTreeGroup *root, QgsLayerTreeModel *model )
82
99
{
83
100
QgsMapThemeCollection::MapThemeRecord rec;
101
+ rec.setHasExpandedStateInfo ( true ); // all newly created theme records have expanded state info
84
102
createThemeFromCurrentState ( root, model, rec );
85
103
return rec;
86
104
}
@@ -140,6 +158,13 @@ void QgsMapThemeCollection::applyThemeToLayer( QgsLayerTreeLayer *nodeLayer, Qgs
140
158
legendNode->setData ( Qt::Checked, Qt::CheckStateRole );
141
159
}
142
160
}
161
+
162
+ // apply expanded/collapsed state to the layer and its legend nodes
163
+ if ( rec.hasExpandedStateInfo () )
164
+ {
165
+ nodeLayer->setExpanded ( layerRec.expandedLayerNode );
166
+ nodeLayer->setCustomProperty ( QStringLiteral ( " expandedLegendNodes" ), QStringList ( layerRec.expandedLegendItems .toList () ) );
167
+ }
143
168
}
144
169
145
170
@@ -148,7 +173,11 @@ void QgsMapThemeCollection::applyThemeToGroup( QgsLayerTreeGroup *parent, QgsLay
148
173
Q_FOREACH ( QgsLayerTreeNode *node, parent->children () )
149
174
{
150
175
if ( QgsLayerTree::isGroup ( node ) )
176
+ {
151
177
applyThemeToGroup ( QgsLayerTree::toGroup ( node ), model, rec );
178
+ if ( rec.hasExpandedStateInfo () )
179
+ node->setExpanded ( rec.expandedGroupNodes ().contains ( _groupId ( node ) ) );
180
+ }
152
181
else if ( QgsLayerTree::isLayer ( node ) )
153
182
applyThemeToLayer ( QgsLayerTree::toLayer ( node ), model, rec );
154
183
}
@@ -385,6 +414,10 @@ void QgsMapThemeCollection::readXml( const QDomDocument &doc )
385
414
{
386
415
QHash<QString, MapThemeLayerRecord> layerRecords; // key = layer ID
387
416
417
+ bool expandedStateInfo = false ;
418
+ if ( visPresetElem.hasAttribute ( QStringLiteral ( " has-expanded-info" ) ) )
419
+ expandedStateInfo = visPresetElem.attribute ( QStringLiteral ( " has-expanded-info" ) ).toInt ();
420
+
388
421
QString presetName = visPresetElem.attribute ( QStringLiteral ( " name" ) );
389
422
QDomElement visPresetLayerElem = visPresetElem.firstChildElement ( QStringLiteral ( " layer" ) );
390
423
while ( !visPresetLayerElem.isNull () )
@@ -399,6 +432,9 @@ void QgsMapThemeCollection::readXml( const QDomDocument &doc )
399
432
layerRecords[layerID].usingCurrentStyle = true ;
400
433
layerRecords[layerID].currentStyle = visPresetLayerElem.attribute ( QStringLiteral ( " style" ) );
401
434
}
435
+
436
+ if ( visPresetLayerElem.hasAttribute ( QStringLiteral ( " expanded" ) ) )
437
+ layerRecords[layerID].expandedLayerNode = visPresetLayerElem.attribute ( QStringLiteral ( " expanded" ) ).toInt ();
402
438
}
403
439
visPresetLayerElem = visPresetLayerElem.nextSiblingElement ( QStringLiteral ( " layer" ) );
404
440
}
@@ -424,8 +460,47 @@ void QgsMapThemeCollection::readXml( const QDomDocument &doc )
424
460
checkedLegendNodesElem = checkedLegendNodesElem.nextSiblingElement ( QStringLiteral ( " checked-legend-nodes" ) );
425
461
}
426
462
463
+ QSet<QString> expandedGroupNodes;
464
+ if ( expandedStateInfo )
465
+ {
466
+ // expanded state of legend nodes
467
+ QDomElement expandedLegendNodesElem = visPresetElem.firstChildElement ( QStringLiteral ( " expanded-legend-nodes" ) );
468
+ while ( !expandedLegendNodesElem.isNull () )
469
+ {
470
+ QSet<QString> expandedLegendNodes;
471
+
472
+ QDomElement expandedLegendNodeElem = expandedLegendNodesElem.firstChildElement ( QStringLiteral ( " expanded-legend-node" ) );
473
+ while ( !expandedLegendNodeElem.isNull () )
474
+ {
475
+ expandedLegendNodes << expandedLegendNodeElem.attribute ( QStringLiteral ( " id" ) );
476
+ expandedLegendNodeElem = expandedLegendNodeElem.nextSiblingElement ( QStringLiteral ( " expanded-legend-node" ) );
477
+ }
478
+
479
+ QString layerID = expandedLegendNodesElem.attribute ( QStringLiteral ( " id" ) );
480
+ if ( mProject ->mapLayer ( layerID ) ) // only use valid IDs
481
+ {
482
+ layerRecords[layerID].expandedLegendItems = expandedLegendNodes;
483
+ }
484
+ expandedLegendNodesElem = expandedLegendNodesElem.nextSiblingElement ( QStringLiteral ( " expanded-legend-nodes" ) );
485
+ }
486
+
487
+ // expanded state of group nodes
488
+ QDomElement expandedGroupNodesElem = visPresetElem.firstChildElement ( QStringLiteral ( " expanded-group-nodes" ) );
489
+ if ( !expandedGroupNodesElem.isNull () )
490
+ {
491
+ QDomElement expandedGroupNodeElem = expandedGroupNodesElem.firstChildElement ( QStringLiteral ( " expanded-group-node" ) );
492
+ while ( !expandedGroupNodeElem.isNull () )
493
+ {
494
+ expandedGroupNodes << expandedGroupNodeElem.attribute ( QStringLiteral ( " id" ) );
495
+ expandedGroupNodeElem = expandedGroupNodeElem.nextSiblingElement ( QStringLiteral ( " expanded-group-node" ) );
496
+ }
497
+ }
498
+ }
499
+
427
500
MapThemeRecord rec;
428
501
rec.setLayerRecords ( layerRecords.values () );
502
+ rec.setHasExpandedStateInfo ( expandedStateInfo );
503
+ rec.setExpandedGroupNodes ( expandedGroupNodes );
429
504
mMapThemes .insert ( presetName, rec );
430
505
emit mapThemeChanged ( presetName );
431
506
@@ -446,6 +521,8 @@ void QgsMapThemeCollection::writeXml( QDomDocument &doc )
446
521
const MapThemeRecord &rec = it.value ();
447
522
QDomElement visPresetElem = doc.createElement ( QStringLiteral ( " visibility-preset" ) );
448
523
visPresetElem.setAttribute ( QStringLiteral ( " name" ), grpName );
524
+ if ( rec.hasExpandedStateInfo () )
525
+ visPresetElem.setAttribute ( QStringLiteral ( " has-expanded-info" ), QStringLiteral ( " 1" ) );
449
526
Q_FOREACH ( const MapThemeLayerRecord &layerRec, rec.mLayerRecords )
450
527
{
451
528
if ( !layerRec.layer () )
@@ -469,6 +546,34 @@ void QgsMapThemeCollection::writeXml( QDomDocument &doc )
469
546
}
470
547
visPresetElem.appendChild ( checkedLegendNodesElem );
471
548
}
549
+
550
+ if ( rec.hasExpandedStateInfo () )
551
+ {
552
+ layerElem.setAttribute ( QStringLiteral ( " expanded" ), layerRec.expandedLayerNode ? QStringLiteral ( " 1" ) : QStringLiteral ( " 0" ) );
553
+
554
+ QDomElement expandedLegendNodesElem = doc.createElement ( QStringLiteral ( " expanded-legend-nodes" ) );
555
+ expandedLegendNodesElem.setAttribute ( QStringLiteral ( " id" ), layerID );
556
+ for ( const QString &expandedLegendNode : qgis::as_const ( layerRec.expandedLegendItems ) )
557
+ {
558
+ QDomElement expandedLegendNodeElem = doc.createElement ( QStringLiteral ( " expanded-legend-node" ) );
559
+ expandedLegendNodeElem.setAttribute ( QStringLiteral ( " id" ), expandedLegendNode );
560
+ expandedLegendNodesElem.appendChild ( expandedLegendNodeElem );
561
+ }
562
+ visPresetElem.appendChild ( expandedLegendNodesElem );
563
+ }
564
+ }
565
+
566
+ if ( rec.hasExpandedStateInfo () )
567
+ {
568
+ QDomElement expandedGroupElems = doc.createElement ( QStringLiteral ( " expanded-group-nodes" ) );
569
+ const QSet<QString> expandedGroupNodes = rec.expandedGroupNodes ();
570
+ for ( const QString &groupId : expandedGroupNodes )
571
+ {
572
+ QDomElement expandedGroupElem = doc.createElement ( QStringLiteral ( " expanded-group-node" ) );
573
+ expandedGroupElem.setAttribute ( QStringLiteral ( " id" ), groupId );
574
+ expandedGroupElems.appendChild ( expandedGroupElem );
575
+ }
576
+ visPresetElem.appendChild ( expandedGroupElems );
472
577
}
473
578
474
579
visPresetsElem.appendChild ( visPresetElem );
0 commit comments