QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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 <QStringList>
25
26#include "moc_qgslayertreegroup.cpp"
27
28QgsLayerTreeGroup::QgsLayerTreeGroup( const QString &name, bool checked )
29 : QgsLayerTreeNode( NodeGroup, checked )
30 , mName( name )
31 , mServerProperties( std::make_unique<QgsMapLayerServerProperties>() )
32{
33 init();
34}
35
37 : QgsLayerTreeNode( other )
38 , mName( other.mName )
43 , mGroupLayer( other.mGroupLayer )
44 , mServerProperties( std::make_unique<QgsMapLayerServerProperties>() )
45{
46 other.serverProperties()->copyTo( mServerProperties.get() );
47
48 init();
49}
50
51void QgsLayerTreeGroup::init()
52{
54 connect( this, &QgsLayerTreeNode::addedChildren, this, &QgsLayerTreeGroup::updateGroupLayers );
55 connect( this, &QgsLayerTreeNode::removedChildren, this, &QgsLayerTreeGroup::updateGroupLayers );
56 connect( this, &QgsLayerTreeNode::visibilityChanged, this, &QgsLayerTreeGroup::updateGroupLayers );
57}
58
60{
61 return mName;
62}
63
64void QgsLayerTreeGroup::setName( const QString &n )
65{
66 if ( mName == n )
67 return;
68
69 mName = n;
70 emit nameChanged( this, n );
71}
72
73
75{
77 insertChildNode( index, grp );
78 return grp;
79}
80
82{
84 addChildNode( grp );
85 return grp;
86}
87
89{
90 if ( !layer )
91 return nullptr;
92
93 QgsLayerTreeLayer *ll = new QgsLayerTreeLayer( layer );
94 insertChildNode( index, ll );
95
96 updateGroupLayers();
97 return ll;
98}
99
101{
102 if ( !layer )
103 return nullptr;
104
105 QgsLayerTreeLayer *ll = new QgsLayerTreeLayer( layer );
106 addChildNode( ll );
107
108 updateGroupLayers();
109 return ll;
110}
111
112QgsLayerTreeCustomNode *QgsLayerTreeGroup::insertCustomNode( int index, const QString &id, const QString &name )
113{
114 if ( id.trimmed().isEmpty() )
115 return nullptr;
116
117 // Avoid registering two custom nodes with the same id
118 const QStringList customNodeIds = findCustomNodeIds();
119 if ( customNodeIds.contains( id ) )
120 return nullptr;
121
122 QgsLayerTreeCustomNode *customNode = new QgsLayerTreeCustomNode( id, name );
123 insertChildNode( index, customNode );
124 return customNode;
125}
126
128{
129 if ( node->nodeId().trimmed().isEmpty() )
130 return nullptr;
131
132 // Avoid registering two custom nodes with the same id
133 const QStringList customNodeIds = findCustomNodeIds();
134 if ( customNodeIds.contains( node->nodeId() ) )
135 return nullptr;
136
137 insertChildNode( index, node );
138 return node;
139}
140
142{
143 if ( id.trimmed().isEmpty() )
144 return nullptr;
145
146 // Avoid registering two custom nodes with the same id
147 const QStringList customNodeIds = findCustomNodeIds();
148 if ( customNodeIds.contains( id ) )
149 return nullptr;
150
151 QgsLayerTreeCustomNode *customNode = new QgsLayerTreeCustomNode( id, name );
152 addChildNode( customNode );
153 return customNode;
154}
155
157{
158 QList<QgsLayerTreeNode *> nodes;
159 nodes << node;
160 insertChildNodes( index, nodes );
161}
162
163void QgsLayerTreeGroup::insertChildNodes( int index, const QList<QgsLayerTreeNode *> &nodes )
164{
165 QgsLayerTreeNode *meChild = nullptr;
168
169 // low-level insert
170 insertChildrenPrivate( index, nodes );
171
172 if ( mMutuallyExclusive )
173 {
174 if ( meChild )
175 {
176 // the child could have change its index - or the new children may have been also set as visible
177 mMutuallyExclusiveChildIndex = mChildren.indexOf( meChild );
178 }
179 else if ( mChecked )
180 {
181 // we have not picked a child index yet, but we should pick one now
182 // ... so pick the first one from the newly added
183 if ( index == -1 )
184 index = mChildren.count() - nodes.count(); // get real insertion index
186 }
188 }
189
190 updateGroupLayers();
191}
192
194{
195 insertChildNode( -1, node );
196
197 updateGroupLayers();
198}
199
201{
202 int i = mChildren.indexOf( node );
203 if ( i >= 0 )
204 removeChildren( i, 1 );
205
206 updateGroupLayers();
207}
208
210{
211 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
212 {
213 if ( QgsLayerTree::isLayer( child ) )
214 {
215 QgsLayerTreeLayer *childLayer = QgsLayerTree::toLayer( child );
216 if ( childLayer->layer() == layer )
217 {
218 removeChildren( mChildren.indexOf( child ), 1 );
219 break;
220 }
221 }
222 }
223
224 updateGroupLayers();
225}
226
227void QgsLayerTreeGroup::removeCustomNode( const QString &id )
228{
230 if ( node )
231 {
232 removeChildNode( node );
233 }
234}
235
236void QgsLayerTreeGroup::removeChildren( int from, int count )
237{
238 QgsLayerTreeNode *meChild = nullptr;
241
242 removeChildrenPrivate( from, count );
243
244 if ( meChild )
245 {
246 // the child could have change its index - or may have been removed completely
247 mMutuallyExclusiveChildIndex = mChildren.indexOf( meChild );
248 // we need to uncheck this group
249 //if ( mMutuallyExclusiveChildIndex == -1 )
250 // setItemVisibilityChecked( false );
251 }
252
253 updateGroupLayers();
254}
255
257{
258 // clean the layer tree by removing empty group
259 const auto childNodes = children();
260 for ( QgsLayerTreeNode *treeNode : childNodes )
261 {
262 if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup )
263 {
264 QgsLayerTreeGroup *treeGroup = qobject_cast<QgsLayerTreeGroup *>( treeNode );
265 if ( treeGroup->findLayerIds().isEmpty() )
266 removeChildNode( treeNode );
267 else
269 }
270 }
271
272 updateGroupLayers();
273}
274
279
281{
282 if ( !layer )
283 return nullptr;
284
285 return findLayer( layer->id() );
286}
287
288QgsLayerTreeLayer *QgsLayerTreeGroup::findLayer( const QString &layerId ) const
289{
290 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
291 {
292 if ( QgsLayerTree::isLayer( child ) )
293 {
294 QgsLayerTreeLayer *childLayer = QgsLayerTree::toLayer( child );
295 if ( childLayer->layerId() == layerId )
296 return childLayer;
297 }
298 else if ( QgsLayerTree::isGroup( child ) )
299 {
300 QgsLayerTreeLayer *res = QgsLayerTree::toGroup( child )->findLayer( layerId );
301 if ( res )
302 return res;
303 }
304 }
305 return nullptr;
306}
307
308QList<QgsLayerTreeLayer *> QgsLayerTreeGroup::findLayers() const
309{
310 QList<QgsLayerTreeLayer *> list;
311 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
312 {
313 if ( QgsLayerTree::isLayer( child ) )
314 list << QgsLayerTree::toLayer( child );
315 else if ( QgsLayerTree::isGroup( child ) )
316 list << QgsLayerTree::toGroup( child )->findLayers();
317 }
318 return list;
319}
320
322{
323 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
324 {
325 if ( QgsLayerTree::isCustomNode( child ) )
326 {
328 if ( childCustom->nodeId() == id )
329 return childCustom;
330 }
331 else if ( QgsLayerTree::isGroup( child ) )
332 {
334 if ( res )
335 return res;
336 }
337 }
338 return nullptr;
339}
340
341QList<QgsLayerTreeNode *> QgsLayerTreeGroup::findLayersAndCustomNodes() const
342{
343 QList<QgsLayerTreeNode *> list;
344 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
345 {
346 if ( QgsLayerTree::isLayer( child ) || QgsLayerTree::isCustomNode( child ) )
347 list << child;
348 else if ( QgsLayerTree::isGroup( child ) )
350 }
351 return list;
352}
353
354void QgsLayerTreeGroup::reorderGroupLayers( const QList<QgsMapLayer *> &order )
355{
356 const QList< QgsLayerTreeLayer * > childLayers = findLayers();
357 int targetIndex = 0;
358 for ( QgsMapLayer *targetLayer : order )
359 {
360 for ( QgsLayerTreeLayer *layerNode : childLayers )
361 {
362 if ( layerNode->layer() == targetLayer )
363 {
364 QgsLayerTreeLayer *cloned = layerNode->clone();
365 insertChildNode( targetIndex, cloned );
366 removeChildNode( layerNode );
367 targetIndex++;
368 break;
369 }
370 }
371 }
372}
373
374void QgsLayerTreeGroup::reorderGroupLayersAndCustomNodes( const QList<QgsLayerTreeNode *> &order )
375{
376 const QList< QgsLayerTreeNode * > childNodes = findLayersAndCustomNodes();
377 int targetIndex = 0;
378 for ( QgsLayerTreeNode *targetNode : order )
379 {
380 for ( QgsLayerTreeNode *childNode : childNodes )
381 {
382 if ( childNode == targetNode )
383 {
384 QgsLayerTreeNode *cloned = childNode->clone();
385 insertChildNode( targetIndex, cloned );
386 removeChildNode( childNode );
387 targetIndex++;
388 break;
389 }
390 }
391 }
392}
393
395{
396 QList<QgsMapLayer *> list;
397 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
398 {
399 if ( QgsLayerTree::isLayer( child ) )
400 {
401 QgsMapLayer *layer = QgsLayerTree::toLayer( child )->layer();
402 if ( !layer || !layer->isSpatial() )
403 continue;
404 list << layer;
405 }
406 else if ( QgsLayerTree::isGroup( child ) )
407 {
409 if ( group->groupLayer() )
410 {
411 list << group->groupLayer();
412 }
413 else
414 {
415 list << group->layerOrderRespectingGroupLayers();
416 }
417 }
418 }
419 return list;
420}
421
423{
424 QList<QgsLayerTreeNode *> list;
425 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
426 {
427 if ( QgsLayerTree::isLayer( child ) )
428 {
429 QgsMapLayer *layer = QgsLayerTree::toLayer( child )->layer();
430 if ( !layer || !layer->isSpatial() )
431 continue;
432 list << child;
433 }
434 else if ( QgsLayerTree::isCustomNode( child ) )
435 {
436 list << child;
437 }
438 else if ( QgsLayerTree::isGroup( child ) )
439 {
441 if ( group->groupLayer() )
442 {
443 list << group;
444 }
445 else
446 {
448 }
449 }
450 }
451 return list;
452}
453
455{
456 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
457 {
458 if ( QgsLayerTree::isGroup( child ) )
459 {
460 QgsLayerTreeGroup *childGroup = QgsLayerTree::toGroup( child );
461 if ( childGroup->name() == name )
462 return childGroup;
463 else
464 {
465 QgsLayerTreeGroup *grp = childGroup->findGroup( name );
466 if ( grp )
467 return grp;
468 }
469 }
470 }
471 return nullptr;
472}
473
474QList<QgsLayerTreeGroup *> QgsLayerTreeGroup::findGroups( bool recursive ) const
475{
476 QList<QgsLayerTreeGroup *> list;
477
478 for ( QgsLayerTreeNode *child : mChildren )
479 {
480 if ( QgsLayerTree::isGroup( child ) )
481 {
482 QgsLayerTreeGroup *childGroup = QgsLayerTree::toGroup( child );
483 list << childGroup;
484 if ( recursive )
485 list << childGroup->findGroups( recursive );
486 }
487 }
488 return list;
489}
490
491QgsLayerTreeGroup *QgsLayerTreeGroup::readXml( const QDomElement &element, const QgsReadWriteContext &context ) // cppcheck-suppress duplInheritedMember
492{
493 if ( element.tagName() != QLatin1String( "layer-tree-group" ) )
494 return nullptr;
495
496 QString name = context.projectTranslator()->translate( QStringLiteral( "project:layergroups" ), element.attribute( QStringLiteral( "name" ) ) );
497 bool isExpanded = ( element.attribute( QStringLiteral( "expanded" ), QStringLiteral( "1" ) ) == QLatin1String( "1" ) );
498 bool checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( QStringLiteral( "checked" ) ) ) != Qt::Unchecked;
499 bool isMutuallyExclusive = element.attribute( QStringLiteral( "mutually-exclusive" ), QStringLiteral( "0" ) ) == QLatin1String( "1" );
500 int mutuallyExclusiveChildIndex = element.attribute( QStringLiteral( "mutually-exclusive-child" ), QStringLiteral( "-1" ) ).toInt();
501
502 QgsLayerTreeGroup *groupNode = new QgsLayerTreeGroup( name, checked );
503 groupNode->setExpanded( isExpanded );
504
505 groupNode->readCommonXml( element );
506
507 groupNode->readChildrenFromXml( element, context );
508
509 groupNode->setIsMutuallyExclusive( isMutuallyExclusive, mutuallyExclusiveChildIndex );
510
511 groupNode->mWmsHasTimeDimension = element.attribute( QStringLiteral( "wms-has-time-dimension" ), QStringLiteral( "0" ) ) == QLatin1String( "1" );
512
513 groupNode->mGroupLayer = QgsMapLayerRef( element.attribute( QStringLiteral( "groupLayer" ) ) );
514
515 readLegacyServerProperties( groupNode );
516
517 groupNode->serverProperties()->readXml( element );
518
519 return groupNode;
520}
521
522void QgsLayerTreeGroup::readLegacyServerProperties( QgsLayerTreeGroup *groupNode )
523{
524 const QVariant wmsShortName = groupNode->customProperty( QStringLiteral( "wmsShortName" ) );
525 if ( wmsShortName.isValid() )
526 {
527 groupNode->serverProperties()->setShortName( wmsShortName.toString() );
528 groupNode->removeCustomProperty( QStringLiteral( "wmsShortName" ) );
529 }
530
531 const QVariant wmsTitle = groupNode->customProperty( QStringLiteral( "wmsTitle" ) );
532 if ( wmsTitle.isValid() )
533 {
534 groupNode->serverProperties()->setTitle( wmsTitle.toString() );
535 groupNode->removeCustomProperty( QStringLiteral( "wmsTitle" ) );
536 }
537
538 const QVariant wmsAbstract = groupNode->customProperty( QStringLiteral( "wmsAbstract" ) );
539 if ( wmsAbstract.isValid() )
540 {
541 groupNode->serverProperties()->setAbstract( wmsAbstract.toString() );
542 groupNode->removeCustomProperty( QStringLiteral( "wmsAbstract" ) );
543 }
544}
545
546QgsLayerTreeGroup *QgsLayerTreeGroup::readXml( const QDomElement &element, const QgsProject *project, const QgsReadWriteContext &context )
547{
548 QgsLayerTreeGroup *node = readXml( element, context );
549 if ( !node )
550 return nullptr;
551
552 node->resolveReferences( project );
553
554 return node;
555}
556
557void QgsLayerTreeGroup::writeXml( QDomElement &parentElement, const QgsReadWriteContext &context )
558{
559 QDomDocument doc = parentElement.ownerDocument();
560 QDomElement elem = doc.createElement( QStringLiteral( "layer-tree-group" ) );
561 elem.setAttribute( QStringLiteral( "name" ), mName );
562 elem.setAttribute( QStringLiteral( "expanded" ), mExpanded ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
563 elem.setAttribute( QStringLiteral( "checked" ), mChecked ? QStringLiteral( "Qt::Checked" ) : QStringLiteral( "Qt::Unchecked" ) );
564 if ( mMutuallyExclusive )
565 {
566 elem.setAttribute( QStringLiteral( "mutually-exclusive" ), QStringLiteral( "1" ) );
567 elem.setAttribute( QStringLiteral( "mutually-exclusive-child" ), mMutuallyExclusiveChildIndex );
568 }
569
571 {
572 elem.setAttribute( QStringLiteral( "wms-has-time-dimension" ), QStringLiteral( "1" ) );
573 }
574
575 elem.setAttribute( QStringLiteral( "groupLayer" ), mGroupLayer.layerId );
576
577 writeCommonXml( elem );
578
579 serverProperties()->writeXml( elem, doc );
580
581 for ( QgsLayerTreeNode *node : std::as_const( mChildren ) )
582 node->writeXml( elem, context );
583
584 parentElement.appendChild( elem );
585}
586
587void QgsLayerTreeGroup::readChildrenFromXml( const QDomElement &element, const QgsReadWriteContext &context )
588{
589 QList<QgsLayerTreeNode *> nodes;
590 QDomElement childElem = element.firstChildElement();
591 while ( !childElem.isNull() )
592 {
593 QgsLayerTreeNode *newNode = QgsLayerTreeNode::readXml( childElem, context );
594 if ( newNode )
595 nodes << newNode;
596
597 childElem = childElem.nextSiblingElement();
598 }
599
600 insertChildNodes( -1, nodes );
601}
602
604{
605 QString header = QStringLiteral( "GROUP: %1 checked=%2 expanded=%3\n" ).arg( name() ).arg( mChecked ).arg( mExpanded );
606 QStringList childrenDump;
607 for ( QgsLayerTreeNode *node : std::as_const( mChildren ) )
608 childrenDump << node->dump().split( '\n' );
609 for ( int i = 0; i < childrenDump.count(); ++i )
610 childrenDump[i].prepend( " " );
611 return header + childrenDump.join( QLatin1Char( '\n' ) );
612}
613
615{
616 return new QgsLayerTreeGroup( *this );
617}
618
619void QgsLayerTreeGroup::resolveReferences( const QgsProject *project, bool looseMatching )
620{
621 for ( QgsLayerTreeNode *node : std::as_const( mChildren ) )
622 node->resolveReferences( project, looseMatching );
623
624 mGroupLayer.resolve( project );
625}
626
627static bool _nodeIsChecked( QgsLayerTreeNode *node )
628{
629 return node->itemVisibilityChecked();
630}
631
632
637
638void QgsLayerTreeGroup::setIsMutuallyExclusive( bool enabled, int initialChildIndex )
639{
640 mMutuallyExclusive = enabled;
641 mMutuallyExclusiveChildIndex = initialChildIndex;
642
643 if ( !enabled )
644 {
645 return;
646 }
647
649 {
650 // try to use first checked index
651 int index = 0;
652 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
653 {
654 if ( _nodeIsChecked( child ) )
655 {
657 break;
658 }
659 index++;
660 }
661 }
662
664}
665
667{
668 return qobject_cast< QgsGroupLayer * >( mGroupLayer.layer );
669}
670
672{
673 if ( QgsGroupLayer *groupLayer = qobject_cast< QgsGroupLayer * >( mGroupLayer.get() ) )
674 {
675 if ( !layer )
676 {
677 groupLayer->prepareLayersForRemovalFromGroup();
678 }
679 }
680 mGroupLayer.setLayer( layer );
681 refreshParentGroupLayerMembers();
682}
683
685{
686 if ( !mGroupLayer.layerId.isEmpty() )
687 return nullptr;
688
689 auto res = std::make_unique< QgsGroupLayer >( name(), options );
690
691 mGroupLayer.setLayer( res.get() );
692 updateGroupLayers();
693
694 return res.release();
695}
696
697void QgsLayerTreeGroup::refreshParentGroupLayerMembers()
698{
699 QgsLayerTreeGroup *parentGroup = qobject_cast< QgsLayerTreeGroup * >( parent() );
700 while ( parentGroup )
701 {
702 if ( QgsLayerTree *layerTree = qobject_cast< QgsLayerTree * >( parentGroup ) )
703 layerTree->emit layerOrderChanged();
704
705 parentGroup->updateGroupLayers();
706 parentGroup = qobject_cast< QgsLayerTreeGroup * >( parentGroup->parent() );
707 }
708}
709
711{
712 QStringList lst;
713 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
714 {
715 if ( QgsLayerTree::isGroup( child ) )
716 lst << QgsLayerTree::toGroup( child )->findLayerIds();
717 else if ( QgsLayerTree::isLayer( child ) )
718 lst << QgsLayerTree::toLayer( child )->layerId();
719 }
720 return lst;
721}
722
724{
725 QStringList lst;
726 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
727 {
728 if ( QgsLayerTree::isGroup( child ) )
729 lst << QgsLayerTree::toGroup( child )->findCustomNodeIds();
730 else if ( QgsLayerTree::isCustomNode( child ) )
731 lst << QgsLayerTree::toCustomNode( child )->nodeId();
732 }
733 return lst;
734}
735
737{
738 int childIndex = mChildren.indexOf( node );
739 if ( childIndex == -1 )
740 {
741 updateGroupLayers();
742 return; // not a direct child - ignore
743 }
744
745 if ( mMutuallyExclusive )
746 {
747 if ( _nodeIsChecked( node ) )
748 mMutuallyExclusiveChildIndex = childIndex;
749 else if ( mMutuallyExclusiveChildIndex == childIndex )
751
752 // we need to make sure there is only one child node checked
754 }
755
756 updateGroupLayers();
757}
758
760{
761 if ( mChildren.isEmpty() )
762 return;
763
764 mChangingChildVisibility = true; // guard against running again setVisible() triggered from children
765
766 int index = 0;
767 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
768 {
769 child->setItemVisibilityChecked( index == mMutuallyExclusiveChildIndex );
770 ++index;
771 }
772
774
775 updateGroupLayers();
776}
777
779{
781 // Reconnect internal signals
783}
784
785void QgsLayerTreeGroup::updateGroupLayers()
786{
787 QgsGroupLayer *groupLayer = qobject_cast< QgsGroupLayer * >( mGroupLayer.get() );
788 if ( !groupLayer )
789 return;
790
791 QList< QgsMapLayer * > layers;
792
793 std::function< void( QgsLayerTreeGroup * ) > findGroupLayerChildren;
794 findGroupLayerChildren = [&layers, &findGroupLayerChildren]( QgsLayerTreeGroup * group )
795 {
796 for ( auto it = group->mChildren.crbegin(); it != group->mChildren.crend(); ++it )
797 {
798 if ( QgsLayerTreeLayer *layerTreeLayer = qobject_cast< QgsLayerTreeLayer * >( *it ) )
799 {
800 if ( layerTreeLayer->layer() && layerTreeLayer->isVisible() )
801 layers << layerTreeLayer->layer();
802 }
803 else if ( QgsLayerTreeGroup *childGroup = qobject_cast< QgsLayerTreeGroup * >( *it ) )
804 {
805 if ( childGroup->isVisible() )
806 {
807 if ( QgsGroupLayer *groupLayer = childGroup->groupLayer() )
808 layers << groupLayer;
809 else
810 findGroupLayerChildren( childGroup );
811 }
812 }
813 }
814 };
815 findGroupLayerChildren( this );
816
817 groupLayer->setChildLayers( layers );
818 refreshParentGroupLayerMembers();
819}
820
822{
824
825 mChangingChildVisibility = true; // guard against running again setVisible() triggered from children
826
827 int index = 0;
828 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
829 {
830 child->setItemVisibilityCheckedRecursive( checked && ( mMutuallyExclusiveChildIndex < 0 || index == mMutuallyExclusiveChildIndex ) );
831 ++index;
832 }
833
835
836 updateGroupLayers();
837}
838
840{
841 return mServerProperties.get();
842}
843
845{
846 return mServerProperties.get();
847}
848
853
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:80
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:83
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:109
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.