QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgslayertreegroup.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayertreegroup.cpp
3 --------------------------------------
4 Date : May 2014
5 Copyright : (C) 2014 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgslayertreegroup.h"
17
18#include "qgsgrouplayer.h"
19#include "qgslayertree.h"
20#include "qgslayertreeutils.h"
21#include "qgsmaplayer.h"
22
23#include <QDomElement>
24#include <QString>
25#include <QStringList>
26
27#include "moc_qgslayertreegroup.cpp"
28
29using namespace Qt::StringLiterals;
30
31QgsLayerTreeGroup::QgsLayerTreeGroup( const QString &name, bool checked )
32 : QgsLayerTreeNode( NodeGroup, checked )
33 , mName( name )
34 , mServerProperties( std::make_unique<QgsMapLayerServerProperties>() )
35{
36 init();
37}
38
40 : QgsLayerTreeNode( other )
41 , mName( other.mName )
46 , mGroupLayer( other.mGroupLayer )
47 , mServerProperties( std::make_unique<QgsMapLayerServerProperties>() )
48{
49 other.serverProperties()->copyTo( mServerProperties.get() );
50
51 init();
52}
53
54void QgsLayerTreeGroup::init()
55{
57 connect( this, &QgsLayerTreeNode::addedChildren, this, &QgsLayerTreeGroup::updateGroupLayers );
58 connect( this, &QgsLayerTreeNode::removedChildren, this, &QgsLayerTreeGroup::updateGroupLayers );
59 connect( this, &QgsLayerTreeNode::visibilityChanged, this, &QgsLayerTreeGroup::updateGroupLayers );
60}
61
63{
64 return mName;
65}
66
67void QgsLayerTreeGroup::setName( const QString &n )
68{
69 if ( mName == n )
70 return;
71
72 mName = n;
73 emit nameChanged( this, n );
74}
75
76
78{
80 insertChildNode( index, grp );
81 return grp;
82}
83
85{
87 addChildNode( grp );
88 return grp;
89}
90
92{
93 if ( !layer )
94 return nullptr;
95
96 QgsLayerTreeLayer *ll = new QgsLayerTreeLayer( layer );
97 insertChildNode( index, ll );
98
99 updateGroupLayers();
100 return ll;
101}
102
104{
105 if ( !layer )
106 return nullptr;
107
108 QgsLayerTreeLayer *ll = new QgsLayerTreeLayer( layer );
109 addChildNode( ll );
110
111 updateGroupLayers();
112 return ll;
113}
114
115QgsLayerTreeCustomNode *QgsLayerTreeGroup::insertCustomNode( int index, const QString &id, const QString &name )
116{
117 if ( id.trimmed().isEmpty() )
118 return nullptr;
119
120 // Avoid registering two custom nodes with the same id
121 const QStringList customNodeIds = findCustomNodeIds();
122 if ( customNodeIds.contains( id ) )
123 return nullptr;
124
125 QgsLayerTreeCustomNode *customNode = new QgsLayerTreeCustomNode( id, name );
126 insertChildNode( index, customNode );
127 return customNode;
128}
129
131{
132 if ( node->nodeId().trimmed().isEmpty() )
133 return nullptr;
134
135 // Avoid registering two custom nodes with the same id
136 const QStringList customNodeIds = findCustomNodeIds();
137 if ( customNodeIds.contains( node->nodeId() ) )
138 return nullptr;
139
140 insertChildNode( index, node );
141 return node;
142}
143
145{
146 if ( id.trimmed().isEmpty() )
147 return nullptr;
148
149 // Avoid registering two custom nodes with the same id
150 const QStringList customNodeIds = findCustomNodeIds();
151 if ( customNodeIds.contains( id ) )
152 return nullptr;
153
154 QgsLayerTreeCustomNode *customNode = new QgsLayerTreeCustomNode( id, name );
155 addChildNode( customNode );
156 return customNode;
157}
158
160{
161 QList<QgsLayerTreeNode *> nodes;
162 nodes << node;
163 insertChildNodes( index, nodes );
164}
165
166void QgsLayerTreeGroup::insertChildNodes( int index, const QList<QgsLayerTreeNode *> &nodes )
167{
168 QgsLayerTreeNode *meChild = nullptr;
171
172 // low-level insert
173 insertChildrenPrivate( index, nodes );
174
175 if ( mMutuallyExclusive )
176 {
177 if ( meChild )
178 {
179 // the child could have change its index - or the new children may have been also set as visible
180 mMutuallyExclusiveChildIndex = mChildren.indexOf( meChild );
181 }
182 else if ( mChecked )
183 {
184 // we have not picked a child index yet, but we should pick one now
185 // ... so pick the first one from the newly added
186 if ( index == -1 )
187 index = mChildren.count() - nodes.count(); // get real insertion index
189 }
191 }
192
193 updateGroupLayers();
194}
195
197{
198 insertChildNode( -1, node );
199
200 updateGroupLayers();
201}
202
204{
205 int i = mChildren.indexOf( node );
206 if ( i >= 0 )
207 removeChildren( i, 1 );
208
209 updateGroupLayers();
210}
211
213{
214 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
215 {
216 if ( QgsLayerTree::isLayer( child ) )
217 {
218 QgsLayerTreeLayer *childLayer = QgsLayerTree::toLayer( child );
219 if ( childLayer->layer() == layer )
220 {
221 removeChildren( mChildren.indexOf( child ), 1 );
222 break;
223 }
224 }
225 }
226
227 updateGroupLayers();
228}
229
230void QgsLayerTreeGroup::removeCustomNode( const QString &id )
231{
233 if ( node )
234 {
235 removeChildNode( node );
236 }
237}
238
239void QgsLayerTreeGroup::removeChildren( int from, int count )
240{
241 QgsLayerTreeNode *meChild = nullptr;
244
245 removeChildrenPrivate( from, count );
246
247 if ( meChild )
248 {
249 // the child could have change its index - or may have been removed completely
250 mMutuallyExclusiveChildIndex = mChildren.indexOf( meChild );
251 // we need to uncheck this group
252 //if ( mMutuallyExclusiveChildIndex == -1 )
253 // setItemVisibilityChecked( false );
254 }
255
256 updateGroupLayers();
257}
258
260{
261 // clean the layer tree by removing empty group
262 const auto childNodes = children();
263 for ( QgsLayerTreeNode *treeNode : childNodes )
264 {
265 if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup )
266 {
267 QgsLayerTreeGroup *treeGroup = qobject_cast<QgsLayerTreeGroup *>( treeNode );
268 if ( treeGroup->findLayerIds().isEmpty() )
269 removeChildNode( treeNode );
270 else
272 }
273 }
274
275 updateGroupLayers();
276}
277
282
284{
285 if ( !layer )
286 return nullptr;
287
288 return findLayer( layer->id() );
289}
290
291QgsLayerTreeLayer *QgsLayerTreeGroup::findLayer( const QString &layerId ) const
292{
293 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
294 {
295 if ( QgsLayerTree::isLayer( child ) )
296 {
297 QgsLayerTreeLayer *childLayer = QgsLayerTree::toLayer( child );
298 if ( childLayer->layerId() == layerId )
299 return childLayer;
300 }
301 else if ( QgsLayerTree::isGroup( child ) )
302 {
303 QgsLayerTreeLayer *res = QgsLayerTree::toGroup( child )->findLayer( layerId );
304 if ( res )
305 return res;
306 }
307 }
308 return nullptr;
309}
310
311QList<QgsLayerTreeLayer *> QgsLayerTreeGroup::findLayers() const
312{
313 QList<QgsLayerTreeLayer *> list;
314 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
315 {
316 if ( QgsLayerTree::isLayer( child ) )
317 list << QgsLayerTree::toLayer( child );
318 else if ( QgsLayerTree::isGroup( child ) )
319 list << QgsLayerTree::toGroup( child )->findLayers();
320 }
321 return list;
322}
323
325{
326 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
327 {
328 if ( QgsLayerTree::isCustomNode( child ) )
329 {
331 if ( childCustom->nodeId() == id )
332 return childCustom;
333 }
334 else if ( QgsLayerTree::isGroup( child ) )
335 {
337 if ( res )
338 return res;
339 }
340 }
341 return nullptr;
342}
343
344QList<QgsLayerTreeNode *> QgsLayerTreeGroup::findLayersAndCustomNodes() const
345{
346 QList<QgsLayerTreeNode *> list;
347 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
348 {
349 if ( QgsLayerTree::isLayer( child ) || QgsLayerTree::isCustomNode( child ) )
350 list << child;
351 else if ( QgsLayerTree::isGroup( child ) )
353 }
354 return list;
355}
356
357void QgsLayerTreeGroup::reorderGroupLayers( const QList<QgsMapLayer *> &order )
358{
359 const QList< QgsLayerTreeLayer * > childLayers = findLayers();
360 int targetIndex = 0;
361 for ( QgsMapLayer *targetLayer : order )
362 {
363 for ( QgsLayerTreeLayer *layerNode : childLayers )
364 {
365 if ( layerNode->layer() == targetLayer )
366 {
367 QgsLayerTreeLayer *cloned = layerNode->clone();
368 insertChildNode( targetIndex, cloned );
369 removeChildNode( layerNode );
370 targetIndex++;
371 break;
372 }
373 }
374 }
375}
376
377void QgsLayerTreeGroup::reorderGroupLayersAndCustomNodes( const QList<QgsLayerTreeNode *> &order )
378{
379 const QList< QgsLayerTreeNode * > childNodes = findLayersAndCustomNodes();
380 int targetIndex = 0;
381 for ( QgsLayerTreeNode *targetNode : order )
382 {
383 for ( QgsLayerTreeNode *childNode : childNodes )
384 {
385 if ( childNode == targetNode )
386 {
387 QgsLayerTreeNode *cloned = childNode->clone();
388 insertChildNode( targetIndex, cloned );
389 removeChildNode( childNode );
390 targetIndex++;
391 break;
392 }
393 }
394 }
395}
396
398{
399 QList<QgsMapLayer *> list;
400 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
401 {
402 if ( QgsLayerTree::isLayer( child ) )
403 {
404 QgsMapLayer *layer = QgsLayerTree::toLayer( child )->layer();
405 if ( !layer || !layer->isSpatial() )
406 continue;
407 list << layer;
408 }
409 else if ( QgsLayerTree::isGroup( child ) )
410 {
412 if ( group->groupLayer() )
413 {
414 list << group->groupLayer();
415 }
416 else
417 {
418 list << group->layerOrderRespectingGroupLayers();
419 }
420 }
421 }
422 return list;
423}
424
426{
427 QList<QgsLayerTreeNode *> list;
428 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
429 {
430 if ( QgsLayerTree::isLayer( child ) )
431 {
432 QgsMapLayer *layer = QgsLayerTree::toLayer( child )->layer();
433 if ( !layer || !layer->isSpatial() )
434 continue;
435 list << child;
436 }
437 else if ( QgsLayerTree::isCustomNode( child ) )
438 {
439 list << child;
440 }
441 else if ( QgsLayerTree::isGroup( child ) )
442 {
444 if ( group->groupLayer() )
445 {
446 list << group;
447 }
448 else
449 {
451 }
452 }
453 }
454 return list;
455}
456
458{
459 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
460 {
461 if ( QgsLayerTree::isGroup( child ) )
462 {
463 QgsLayerTreeGroup *childGroup = QgsLayerTree::toGroup( child );
464 if ( childGroup->name() == name )
465 return childGroup;
466 else
467 {
468 QgsLayerTreeGroup *grp = childGroup->findGroup( name );
469 if ( grp )
470 return grp;
471 }
472 }
473 }
474 return nullptr;
475}
476
477QList<QgsLayerTreeGroup *> QgsLayerTreeGroup::findGroups( bool recursive ) const
478{
479 QList<QgsLayerTreeGroup *> list;
480
481 for ( QgsLayerTreeNode *child : mChildren )
482 {
483 if ( QgsLayerTree::isGroup( child ) )
484 {
485 QgsLayerTreeGroup *childGroup = QgsLayerTree::toGroup( child );
486 list << childGroup;
487 if ( recursive )
488 list << childGroup->findGroups( recursive );
489 }
490 }
491 return list;
492}
493
494QgsLayerTreeGroup *QgsLayerTreeGroup::readXml( const QDomElement &element, const QgsReadWriteContext &context ) // cppcheck-suppress duplInheritedMember
495{
496 if ( element.tagName() != "layer-tree-group"_L1 )
497 return nullptr;
498
499 QString name = context.projectTranslator()->translate( u"project:layergroups"_s, element.attribute( u"name"_s ) );
500 bool isExpanded = ( element.attribute( u"expanded"_s, u"1"_s ) == "1"_L1 );
501 bool checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( u"checked"_s ) ) != Qt::Unchecked;
502 bool isMutuallyExclusive = element.attribute( u"mutually-exclusive"_s, u"0"_s ) == "1"_L1;
503 int mutuallyExclusiveChildIndex = element.attribute( u"mutually-exclusive-child"_s, u"-1"_s ).toInt();
504
505 QgsLayerTreeGroup *groupNode = new QgsLayerTreeGroup( name, checked );
506 groupNode->setExpanded( isExpanded );
507
508 groupNode->readCommonXml( element );
509
510 groupNode->readChildrenFromXml( element, context );
511
512 groupNode->setIsMutuallyExclusive( isMutuallyExclusive, mutuallyExclusiveChildIndex );
513
514 groupNode->mWmsHasTimeDimension = element.attribute( u"wms-has-time-dimension"_s, u"0"_s ) == "1"_L1;
515
516 groupNode->mGroupLayer = QgsMapLayerRef( element.attribute( u"groupLayer"_s ) );
517
518 readLegacyServerProperties( groupNode );
519
520 groupNode->serverProperties()->readXml( element );
521
522 return groupNode;
523}
524
525void QgsLayerTreeGroup::readLegacyServerProperties( QgsLayerTreeGroup *groupNode )
526{
527 const QVariant wmsShortName = groupNode->customProperty( u"wmsShortName"_s );
528 if ( wmsShortName.isValid() )
529 {
530 groupNode->serverProperties()->setShortName( wmsShortName.toString() );
531 groupNode->removeCustomProperty( u"wmsShortName"_s );
532 }
533
534 const QVariant wmsTitle = groupNode->customProperty( u"wmsTitle"_s );
535 if ( wmsTitle.isValid() )
536 {
537 groupNode->serverProperties()->setTitle( wmsTitle.toString() );
538 groupNode->removeCustomProperty( u"wmsTitle"_s );
539 }
540
541 const QVariant wmsAbstract = groupNode->customProperty( u"wmsAbstract"_s );
542 if ( wmsAbstract.isValid() )
543 {
544 groupNode->serverProperties()->setAbstract( wmsAbstract.toString() );
545 groupNode->removeCustomProperty( u"wmsAbstract"_s );
546 }
547}
548
549QgsLayerTreeGroup *QgsLayerTreeGroup::readXml( const QDomElement &element, const QgsProject *project, const QgsReadWriteContext &context )
550{
551 QgsLayerTreeGroup *node = readXml( element, context );
552 if ( !node )
553 return nullptr;
554
555 node->resolveReferences( project );
556
557 return node;
558}
559
560void QgsLayerTreeGroup::writeXml( QDomElement &parentElement, const QgsReadWriteContext &context )
561{
562 QDomDocument doc = parentElement.ownerDocument();
563 QDomElement elem = doc.createElement( u"layer-tree-group"_s );
564 elem.setAttribute( u"name"_s, mName );
565 elem.setAttribute( u"expanded"_s, mExpanded ? u"1"_s : u"0"_s );
566 elem.setAttribute( u"checked"_s, mChecked ? u"Qt::Checked"_s : u"Qt::Unchecked"_s );
567 if ( mMutuallyExclusive )
568 {
569 elem.setAttribute( u"mutually-exclusive"_s, u"1"_s );
570 elem.setAttribute( u"mutually-exclusive-child"_s, mMutuallyExclusiveChildIndex );
571 }
572
574 {
575 elem.setAttribute( u"wms-has-time-dimension"_s, u"1"_s );
576 }
577
578 elem.setAttribute( u"groupLayer"_s, mGroupLayer.layerId );
579
580 writeCommonXml( elem );
581
582 serverProperties()->writeXml( elem, doc );
583
584 for ( QgsLayerTreeNode *node : std::as_const( mChildren ) )
585 node->writeXml( elem, context );
586
587 parentElement.appendChild( elem );
588}
589
590void QgsLayerTreeGroup::readChildrenFromXml( const QDomElement &element, const QgsReadWriteContext &context )
591{
592 QList<QgsLayerTreeNode *> nodes;
593 QDomElement childElem = element.firstChildElement();
594 while ( !childElem.isNull() )
595 {
596 QgsLayerTreeNode *newNode = QgsLayerTreeNode::readXml( childElem, context );
597 if ( newNode )
598 nodes << newNode;
599
600 childElem = childElem.nextSiblingElement();
601 }
602
603 insertChildNodes( -1, nodes );
604}
605
607{
608 QString header = u"GROUP: %1 checked=%2 expanded=%3\n"_s.arg( name() ).arg( mChecked ).arg( mExpanded );
609 QStringList childrenDump;
610 for ( QgsLayerTreeNode *node : std::as_const( mChildren ) )
611 childrenDump << node->dump().split( '\n' );
612 for ( int i = 0; i < childrenDump.count(); ++i )
613 childrenDump[i].prepend( " " );
614 return header + childrenDump.join( QLatin1Char( '\n' ) );
615}
616
618{
619 return new QgsLayerTreeGroup( *this );
620}
621
622void QgsLayerTreeGroup::resolveReferences( const QgsProject *project, bool looseMatching )
623{
624 for ( QgsLayerTreeNode *node : std::as_const( mChildren ) )
625 node->resolveReferences( project, looseMatching );
626
627 mGroupLayer.resolve( project );
628}
629
630static bool _nodeIsChecked( QgsLayerTreeNode *node )
631{
632 return node->itemVisibilityChecked();
633}
634
635
640
641void QgsLayerTreeGroup::setIsMutuallyExclusive( bool enabled, int initialChildIndex )
642{
643 mMutuallyExclusive = enabled;
644 mMutuallyExclusiveChildIndex = initialChildIndex;
645
646 if ( !enabled )
647 {
648 return;
649 }
650
652 {
653 // try to use first checked index
654 int index = 0;
655 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
656 {
657 if ( _nodeIsChecked( child ) )
658 {
660 break;
661 }
662 index++;
663 }
664 }
665
667}
668
670{
671 return qobject_cast< QgsGroupLayer * >( mGroupLayer.layer );
672}
673
675{
676 if ( QgsGroupLayer *groupLayer = qobject_cast< QgsGroupLayer * >( mGroupLayer.get() ) )
677 {
678 if ( !layer )
679 {
680 groupLayer->prepareLayersForRemovalFromGroup();
681 }
682 }
683 mGroupLayer.setLayer( layer );
684 refreshParentGroupLayerMembers();
685}
686
688{
689 if ( !mGroupLayer.layerId.isEmpty() )
690 return nullptr;
691
692 auto res = std::make_unique< QgsGroupLayer >( name(), options );
693
694 mGroupLayer.setLayer( res.get() );
695 updateGroupLayers();
696
697 return res.release();
698}
699
700void QgsLayerTreeGroup::refreshParentGroupLayerMembers()
701{
702 QgsLayerTreeGroup *parentGroup = qobject_cast< QgsLayerTreeGroup * >( parent() );
703 while ( parentGroup )
704 {
705 if ( QgsLayerTree *layerTree = qobject_cast< QgsLayerTree * >( parentGroup ) )
706 layerTree->emit layerOrderChanged();
707
708 parentGroup->updateGroupLayers();
709 parentGroup = qobject_cast< QgsLayerTreeGroup * >( parentGroup->parent() );
710 }
711}
712
714{
715 QStringList lst;
716 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
717 {
718 if ( QgsLayerTree::isGroup( child ) )
719 lst << QgsLayerTree::toGroup( child )->findLayerIds();
720 else if ( QgsLayerTree::isLayer( child ) )
721 lst << QgsLayerTree::toLayer( child )->layerId();
722 }
723 return lst;
724}
725
727{
728 QStringList lst;
729 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
730 {
731 if ( QgsLayerTree::isGroup( child ) )
732 lst << QgsLayerTree::toGroup( child )->findCustomNodeIds();
733 else if ( QgsLayerTree::isCustomNode( child ) )
734 lst << QgsLayerTree::toCustomNode( child )->nodeId();
735 }
736 return lst;
737}
738
740{
741 int childIndex = mChildren.indexOf( node );
742 if ( childIndex == -1 )
743 {
744 updateGroupLayers();
745 return; // not a direct child - ignore
746 }
747
748 if ( mMutuallyExclusive )
749 {
750 if ( _nodeIsChecked( node ) )
751 mMutuallyExclusiveChildIndex = childIndex;
752 else if ( mMutuallyExclusiveChildIndex == childIndex )
754
755 // we need to make sure there is only one child node checked
757 }
758
759 updateGroupLayers();
760}
761
763{
764 if ( mChildren.isEmpty() )
765 return;
766
767 mChangingChildVisibility = true; // guard against running again setVisible() triggered from children
768
769 int index = 0;
770 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
771 {
772 child->setItemVisibilityChecked( index == mMutuallyExclusiveChildIndex );
773 ++index;
774 }
775
777
778 updateGroupLayers();
779}
780
782{
784 // Reconnect internal signals
786}
787
788void QgsLayerTreeGroup::updateGroupLayers()
789{
790 QgsGroupLayer *groupLayer = qobject_cast< QgsGroupLayer * >( mGroupLayer.get() );
791 if ( !groupLayer )
792 return;
793
794 QList< QgsMapLayer * > layers;
795
796 std::function< void( QgsLayerTreeGroup * ) > findGroupLayerChildren;
797 findGroupLayerChildren = [&layers, &findGroupLayerChildren]( QgsLayerTreeGroup * group )
798 {
799 for ( auto it = group->mChildren.crbegin(); it != group->mChildren.crend(); ++it )
800 {
801 if ( QgsLayerTreeLayer *layerTreeLayer = qobject_cast< QgsLayerTreeLayer * >( *it ) )
802 {
803 if ( layerTreeLayer->layer() && layerTreeLayer->isVisible() )
804 layers << layerTreeLayer->layer();
805 }
806 else if ( QgsLayerTreeGroup *childGroup = qobject_cast< QgsLayerTreeGroup * >( *it ) )
807 {
808 if ( childGroup->isVisible() )
809 {
810 if ( QgsGroupLayer *groupLayer = childGroup->groupLayer() )
811 layers << groupLayer;
812 else
813 findGroupLayerChildren( childGroup );
814 }
815 }
816 }
817 };
818 findGroupLayerChildren( this );
819
820 groupLayer->setChildLayers( layers );
821 refreshParentGroupLayerMembers();
822}
823
825{
827
828 mChangingChildVisibility = true; // guard against running again setVisible() triggered from children
829
830 int index = 0;
831 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
832 {
833 child->setItemVisibilityCheckedRecursive( checked && ( mMutuallyExclusiveChildIndex < 0 || index == mMutuallyExclusiveChildIndex ) );
834 ++index;
835 }
836
838
839 updateGroupLayers();
840}
841
843{
844 return mServerProperties.get();
845}
846
848{
849 return mServerProperties.get();
850}
851
856
A map layer which consists of a set of child layers, where all component layers are rendered as a sin...
Layer tree custom node serves as a node for objects that are not layers nor groups.
QString nodeId() const
Returns the node's unique identifier.
Layer tree group node serves as a container for layers and further groups.
QStringList findCustomNodeIds() const
Find custom node IDs.
void insertChildNode(int index, QgsLayerTreeNode *node)
Insert existing node at specified position.
QgsLayerTreeCustomNode * insertCustomNode(int index, const QString &id, const QString &name=QString())
Insert a new custom node with the given id and name at specified index.
QgsLayerTreeCustomNode * findCustomNode(const QString &id) const
Find custom node representing an object specified by its ID.
void setName(const QString &n) override
Sets the group's name.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Calls resolveReferences() on child tree nodes.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name.
QgsGroupLayer * convertToGroupLayer(const QgsGroupLayer::LayerOptions &options)
Converts the group to a QgsGroupLayer.
void setHasWmsTimeDimension(const bool hasWmsTimeDimension)
Sets whether the WMS time dimension should be computed for this group or not.
QgsLayerTreeGroup * insertGroup(int index, const QString &name)
Insert a new group node with given name at specified position.
void readChildrenFromXml(const QDomElement &element, const QgsReadWriteContext &context)
Read children from XML and append them to the group.
void removeChildNode(QgsLayerTreeNode *node)
Remove a child node from this group.
QList< QgsLayerTreeNode * > findLayersAndCustomNodes() const
Find all layer and custom nodes.
QList< QgsLayerTreeGroup * > findGroups(bool recursive=false) const
Find group layer nodes.
void writeXml(QDomElement &parentElement, const QgsReadWriteContext &context) override
Write group (tree) as XML element <layer-tree-group> and add it to the given parent element.
QString name() const override
Returns the group's name.
QgsLayerTreeGroup(const QString &name=QString(), bool checked=true)
Constructor.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
QList< QgsMapLayer * > layerOrderRespectingGroupLayers() const
Returns an ordered list of map layers in the group, ignoring any layers which are child layers of Qgs...
void removeCustomNode(const QString &id)
Remove a custom node from this group.
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the layer tree group.
void addChildNode(QgsLayerTreeNode *node)
Append an existing node.
QList< QgsLayerTreeNode * > layerAndCustomNodeOrderRespectingGroupLayers() const
Returns an ordered list of map layers and custom nodes in the group, ignoring any layers which are ch...
void insertChildNodes(int index, const QList< QgsLayerTreeNode * > &nodes)
Insert existing nodes at specified position.
void removeAllChildren()
Remove all child nodes.
bool mMutuallyExclusive
Whether the group is mutually exclusive (i.e. only one child can be checked at a time).
void setIsMutuallyExclusive(bool enabled, int initialChildIndex=-1)
Set whether the group is mutually exclusive (only one child can be checked at a time).
void setItemVisibilityCheckedRecursive(bool checked) override
Check or uncheck a node and all its children (taking into account exclusion rules).
QgsLayerTreeGroup * clone() const override
Returns a clone of the group.
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
bool isMutuallyExclusive() const
Returns whether the group is mutually exclusive (only one child can be checked at a time).
QgsLayerTreeCustomNode * addCustomNode(const QString &id, const QString &name=QString())
Append a new custom node with the given id and name.
void updateChildVisibilityMutuallyExclusive()
Set check state of children - if mutually exclusive.
bool hasWmsTimeDimension() const
Returns whether the WMS time dimension should be computed for this group or not.
static QgsLayerTreeGroup * readXml(const QDomElement &element, const QgsReadWriteContext &context)
Read group (tree) from XML element <layer-tree-group> and return the newly created group (or nullptr ...
void setGroupLayer(QgsGroupLayer *layer)
Sets the associated group layer, if the layer tree group will be treated as group layer during map re...
QgsLayerTreeGroup * addGroup(const QString &name)
Append a new group node with given name.
void removeChildren(int from, int count)
Remove child nodes from index "from".
void removeChildrenGroupWithoutLayers()
Remove all child group nodes without layers.
QgsLayerTreeLayer * addLayer(QgsMapLayer *layer)
Append a new layer node for given map layer.
void makeOrphan() override
Sets parent to nullptr and disconnects all external and forwarded signals.
void removeLayer(QgsMapLayer *layer)
Remove map layer's node from this group.
QgsLayerTreeLayer * insertLayer(int index, QgsMapLayer *layer)
Insert a new layer node for given map layer at specified position.
QString dump() const override
Returns text representation of the tree.
void nodeVisibilityChanged(QgsLayerTreeNode *node)
void reorderGroupLayers(const QList< QgsMapLayer * > &order)
Reorders layers in the group to match the order specified by order.
int mMutuallyExclusiveChildIndex
Keeps track which child has been most recently selected (so if the whole group is unchecked and check...
void reorderGroupLayersAndCustomNodes(const QList< QgsLayerTreeNode * > &order)
Reorders layers and custom nodes in the group to match the order specified by order.
QgsGroupLayer * groupLayer()
Returns a reference to the associated group layer, if the layer tree group will be treated as group l...
Layer tree node points to a map layer.
QString layerId() const
Returns the ID for the map layer associated with this node.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
QgsLayerTreeLayer * clone() const override
Create a copy of the node. Returns new instance.
Base class for nodes in a layer tree.
virtual void makeOrphan()
Sets parent to nullptr and disconnects all external and forwarded signals.
@ NodeGroup
Container of other groups and layers.
void removedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes has been removed from a node within the tree.
void nameChanged(QgsLayerTreeNode *node, QString name)
Emitted when the name of the node is changed.
static QgsLayerTreeNode * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read layer tree from XML.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
QgsLayerTreeNode(NodeType t, bool checked=true)
Constructor.
void writeCommonXml(QDomElement &element)
Write common XML elements.
void insertChildrenPrivate(int index, const QList< QgsLayerTreeNode * > &nodes)
Low-level insertion of children to the node. The children must not have any parent yet!
void addedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes have been added to a node within the tree.
void visibilityChanged(QgsLayerTreeNode *node)
Emitted when check state of a node within the tree has been changed.
QList< QgsLayerTreeNode * > mChildren
list of children - node is responsible for their deletion
bool mExpanded
whether the node should be shown in GUI as expanded
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children).
void readCommonXml(const QDomElement &element)
Read common XML elements.
bool itemVisibilityChecked() const
Returns whether a node is checked (independently of its ancestors or children).
void removeChildrenPrivate(int from, int count, bool destroy=true)
Low-level removal of children from the node.
static Qt::CheckState checkStateFromXml(const QString &txt)
Convert QString to Qt::CheckState.
Namespace with helper functions for layer tree operations.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
static bool isCustomNode(const QgsLayerTreeNode *node)
Check whether the node is a valid custom node.
static QgsLayerTreeCustomNode * toCustomNode(QgsLayerTreeNode *node)
Cast node to a custom node.
Manages QGIS Server properties for a map layer.
void readXml(const QDomNode &layer_node)
Reads server properties from project file.
void setAbstract(const QString &abstract)
Sets the abstract of the layer used by QGIS Server in GetCapabilities request.
void setShortName(const QString &name)
Sets the short name of the layer used by QGIS Server to identify the layer.
void writeXml(QDomNode &layer_node, QDomDocument &document) const
Saves server properties to xml under the layer node.
void setTitle(const QString &title)
Sets the title of the layer used by QGIS Server in GetCapabilities request.
Base class for all map layer types.
Definition qgsmaplayer.h:83
virtual bool isSpatial() const
Returns true if the layer is considered a spatial layer, ie it has some form of geometry associated w...
QString id
Definition qgsmaplayer.h:86
virtual QString translate(const QString &context, const QString &sourceText, const char *disambiguation=nullptr, int n=-1) const =0
Translates a string using the Qt QTranslator mechanism.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:112
A container for the context for various read/write operations on objects.
const QgsProjectTranslator * projectTranslator() const
Returns the project translator.
#define SIP_TRANSFER
Definition qgis_sip.h:36
_LayerRef< QgsMapLayer > QgsMapLayerRef
Setting options for loading group layers.
TYPE * get() const
Returns a pointer to the layer, or nullptr if the reference has not yet been matched to a layer.