QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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
231{
232 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
233 {
234 if ( QgsLayerTree::isCustomNode( child ) )
235 {
237 if ( childCustom->nodeId() == customNode->nodeId() )
238 {
239 removeChildren( mChildren.indexOf( child ), 1 );
240 break;
241 }
242 }
243 }
244
245 updateGroupLayers();
246}
247
248void QgsLayerTreeGroup::removeChildren( int from, int count )
249{
250 QgsLayerTreeNode *meChild = nullptr;
253
254 removeChildrenPrivate( from, count );
255
256 if ( meChild )
257 {
258 // the child could have change its index - or may have been removed completely
259 mMutuallyExclusiveChildIndex = mChildren.indexOf( meChild );
260 // we need to uncheck this group
261 //if ( mMutuallyExclusiveChildIndex == -1 )
262 // setItemVisibilityChecked( false );
263 }
264
265 updateGroupLayers();
266}
267
269{
270 // clean the layer tree by removing empty group
271 const auto childNodes = children();
272 for ( QgsLayerTreeNode *treeNode : childNodes )
273 {
274 if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup )
275 {
276 QgsLayerTreeGroup *treeGroup = qobject_cast<QgsLayerTreeGroup *>( treeNode );
277 if ( treeGroup->findLayerIds().isEmpty() )
278 removeChildNode( treeNode );
279 else
281 }
282 }
283
284 updateGroupLayers();
285}
286
291
293{
294 if ( !layer )
295 return nullptr;
296
297 return findLayer( layer->id() );
298}
299
300QgsLayerTreeLayer *QgsLayerTreeGroup::findLayer( const QString &layerId ) const
301{
302 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
303 {
304 if ( QgsLayerTree::isLayer( child ) )
305 {
306 QgsLayerTreeLayer *childLayer = QgsLayerTree::toLayer( child );
307 if ( childLayer->layerId() == layerId )
308 return childLayer;
309 }
310 else if ( QgsLayerTree::isGroup( child ) )
311 {
312 QgsLayerTreeLayer *res = QgsLayerTree::toGroup( child )->findLayer( layerId );
313 if ( res )
314 return res;
315 }
316 }
317 return nullptr;
318}
319
320QList<QgsLayerTreeLayer *> QgsLayerTreeGroup::findLayers() const
321{
322 QList<QgsLayerTreeLayer *> list;
323 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
324 {
325 if ( QgsLayerTree::isLayer( child ) )
326 list << QgsLayerTree::toLayer( child );
327 else if ( QgsLayerTree::isGroup( child ) )
328 list << QgsLayerTree::toGroup( child )->findLayers();
329 }
330 return list;
331}
332
334{
335 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
336 {
337 if ( QgsLayerTree::isCustomNode( child ) )
338 {
340 if ( childCustom->nodeId() == id )
341 return childCustom;
342 }
343 else if ( QgsLayerTree::isGroup( child ) )
344 {
346 if ( res )
347 return res;
348 }
349 }
350 return nullptr;
351}
352
353QList<QgsLayerTreeNode *> QgsLayerTreeGroup::findLayersAndCustomNodes() const
354{
355 QList<QgsLayerTreeNode *> list;
356 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
357 {
358 if ( QgsLayerTree::isLayer( child ) || QgsLayerTree::isCustomNode( child ) )
359 list << child;
360 else if ( QgsLayerTree::isGroup( child ) )
362 }
363 return list;
364}
365
366void QgsLayerTreeGroup::reorderGroupLayers( const QList<QgsMapLayer *> &order )
367{
368 const QList< QgsLayerTreeLayer * > childLayers = findLayers();
369 int targetIndex = 0;
370 for ( QgsMapLayer *targetLayer : order )
371 {
372 for ( QgsLayerTreeLayer *layerNode : childLayers )
373 {
374 if ( layerNode->layer() == targetLayer )
375 {
376 QgsLayerTreeLayer *cloned = layerNode->clone();
377 insertChildNode( targetIndex, cloned );
378 removeChildNode( layerNode );
379 targetIndex++;
380 break;
381 }
382 }
383 }
384}
385
386void QgsLayerTreeGroup::reorderGroupLayersAndCustomNodes( const QList<QgsLayerTreeNode *> &order )
387{
388 const QList< QgsLayerTreeNode * > childNodes = findLayersAndCustomNodes();
389 int targetIndex = 0;
390 for ( QgsLayerTreeNode *targetNode : order )
391 {
392 for ( QgsLayerTreeNode *childNode : childNodes )
393 {
394 if ( childNode == targetNode )
395 {
396 QgsLayerTreeNode *cloned = childNode->clone();
397 insertChildNode( targetIndex, cloned );
398 removeChildNode( childNode );
399 targetIndex++;
400 break;
401 }
402 }
403 }
404}
405
407{
408 QList<QgsMapLayer *> list;
409 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
410 {
411 if ( QgsLayerTree::isLayer( child ) )
412 {
413 QgsMapLayer *layer = QgsLayerTree::toLayer( child )->layer();
414 if ( !layer || !layer->isSpatial() )
415 continue;
416 list << layer;
417 }
418 else if ( QgsLayerTree::isGroup( child ) )
419 {
421 if ( group->groupLayer() )
422 {
423 list << group->groupLayer();
424 }
425 else
426 {
427 list << group->layerOrderRespectingGroupLayers();
428 }
429 }
430 }
431 return list;
432}
433
435{
436 QList<QgsLayerTreeNode *> list;
437 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
438 {
439 if ( QgsLayerTree::isLayer( child ) )
440 {
441 QgsMapLayer *layer = QgsLayerTree::toLayer( child )->layer();
442 if ( !layer || !layer->isSpatial() )
443 continue;
444 list << child;
445 }
446 else if ( QgsLayerTree::isCustomNode( child ) )
447 {
448 list << child;
449 }
450 else if ( QgsLayerTree::isGroup( child ) )
451 {
453 if ( group->groupLayer() )
454 {
455 list << group;
456 }
457 else
458 {
460 }
461 }
462 }
463 return list;
464}
465
467{
468 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
469 {
470 if ( QgsLayerTree::isGroup( child ) )
471 {
472 QgsLayerTreeGroup *childGroup = QgsLayerTree::toGroup( child );
473 if ( childGroup->name() == name )
474 return childGroup;
475 else
476 {
477 QgsLayerTreeGroup *grp = childGroup->findGroup( name );
478 if ( grp )
479 return grp;
480 }
481 }
482 }
483 return nullptr;
484}
485
486QList<QgsLayerTreeGroup *> QgsLayerTreeGroup::findGroups( bool recursive ) const
487{
488 QList<QgsLayerTreeGroup *> list;
489
490 for ( QgsLayerTreeNode *child : mChildren )
491 {
492 if ( QgsLayerTree::isGroup( child ) )
493 {
494 QgsLayerTreeGroup *childGroup = QgsLayerTree::toGroup( child );
495 list << childGroup;
496 if ( recursive )
497 list << childGroup->findGroups( recursive );
498 }
499 }
500 return list;
501}
502
503QgsLayerTreeGroup *QgsLayerTreeGroup::readXml( const QDomElement &element, const QgsReadWriteContext &context ) // cppcheck-suppress duplInheritedMember
504{
505 if ( element.tagName() != "layer-tree-group"_L1 )
506 return nullptr;
507
508 QString name = context.projectTranslator()->translate( u"project:layergroups"_s, element.attribute( u"name"_s ) );
509 bool isExpanded = ( element.attribute( u"expanded"_s, u"1"_s ) == "1"_L1 );
510 bool checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( u"checked"_s ) ) != Qt::Unchecked;
511 bool isMutuallyExclusive = element.attribute( u"mutually-exclusive"_s, u"0"_s ) == "1"_L1;
512 int mutuallyExclusiveChildIndex = element.attribute( u"mutually-exclusive-child"_s, u"-1"_s ).toInt();
513
514 QgsLayerTreeGroup *groupNode = new QgsLayerTreeGroup( name, checked );
515 groupNode->setExpanded( isExpanded );
516
517 groupNode->readCommonXml( element );
518
519 groupNode->readChildrenFromXml( element, context );
520
521 groupNode->setIsMutuallyExclusive( isMutuallyExclusive, mutuallyExclusiveChildIndex );
522
523 groupNode->mWmsHasTimeDimension = element.attribute( u"wms-has-time-dimension"_s, u"0"_s ) == "1"_L1;
524
525 groupNode->mGroupLayer = QgsMapLayerRef( element.attribute( u"groupLayer"_s ) );
526
527 readLegacyServerProperties( groupNode );
528
529 groupNode->serverProperties()->readXml( element );
530
531 return groupNode;
532}
533
534void QgsLayerTreeGroup::readLegacyServerProperties( QgsLayerTreeGroup *groupNode )
535{
536 const QVariant wmsShortName = groupNode->customProperty( u"wmsShortName"_s );
537 if ( wmsShortName.isValid() )
538 {
539 groupNode->serverProperties()->setShortName( wmsShortName.toString() );
540 groupNode->removeCustomProperty( u"wmsShortName"_s );
541 }
542
543 const QVariant wmsTitle = groupNode->customProperty( u"wmsTitle"_s );
544 if ( wmsTitle.isValid() )
545 {
546 groupNode->serverProperties()->setTitle( wmsTitle.toString() );
547 groupNode->removeCustomProperty( u"wmsTitle"_s );
548 }
549
550 const QVariant wmsAbstract = groupNode->customProperty( u"wmsAbstract"_s );
551 if ( wmsAbstract.isValid() )
552 {
553 groupNode->serverProperties()->setAbstract( wmsAbstract.toString() );
554 groupNode->removeCustomProperty( u"wmsAbstract"_s );
555 }
556}
557
558QgsLayerTreeGroup *QgsLayerTreeGroup::readXml( const QDomElement &element, const QgsProject *project, const QgsReadWriteContext &context )
559{
560 QgsLayerTreeGroup *node = readXml( element, context );
561 if ( !node )
562 return nullptr;
563
564 node->resolveReferences( project );
565
566 return node;
567}
568
569void QgsLayerTreeGroup::writeXml( QDomElement &parentElement, const QgsReadWriteContext &context )
570{
571 QDomDocument doc = parentElement.ownerDocument();
572 QDomElement elem = doc.createElement( u"layer-tree-group"_s );
573 elem.setAttribute( u"name"_s, mName );
574 elem.setAttribute( u"expanded"_s, mExpanded ? u"1"_s : u"0"_s );
575 elem.setAttribute( u"checked"_s, mChecked ? u"Qt::Checked"_s : u"Qt::Unchecked"_s );
576 if ( mMutuallyExclusive )
577 {
578 elem.setAttribute( u"mutually-exclusive"_s, u"1"_s );
579 elem.setAttribute( u"mutually-exclusive-child"_s, mMutuallyExclusiveChildIndex );
580 }
581
583 {
584 elem.setAttribute( u"wms-has-time-dimension"_s, u"1"_s );
585 }
586
587 elem.setAttribute( u"groupLayer"_s, mGroupLayer.layerId );
588
589 writeCommonXml( elem );
590
591 serverProperties()->writeXml( elem, doc );
592
593 for ( QgsLayerTreeNode *node : std::as_const( mChildren ) )
594 node->writeXml( elem, context );
595
596 parentElement.appendChild( elem );
597}
598
599void QgsLayerTreeGroup::readChildrenFromXml( const QDomElement &element, const QgsReadWriteContext &context )
600{
601 QList<QgsLayerTreeNode *> nodes;
602 QDomElement childElem = element.firstChildElement();
603 while ( !childElem.isNull() )
604 {
605 QgsLayerTreeNode *newNode = QgsLayerTreeNode::readXml( childElem, context );
606 if ( newNode )
607 nodes << newNode;
608
609 childElem = childElem.nextSiblingElement();
610 }
611
612 insertChildNodes( -1, nodes );
613}
614
616{
617 QString header = u"GROUP: %1 checked=%2 expanded=%3\n"_s.arg( name() ).arg( mChecked ).arg( mExpanded );
618 QStringList childrenDump;
619 for ( QgsLayerTreeNode *node : std::as_const( mChildren ) )
620 childrenDump << node->dump().split( '\n' );
621 for ( int i = 0; i < childrenDump.count(); ++i )
622 childrenDump[i].prepend( " " );
623 return header + childrenDump.join( QLatin1Char( '\n' ) );
624}
625
627{
628 return new QgsLayerTreeGroup( *this );
629}
630
631void QgsLayerTreeGroup::resolveReferences( const QgsProject *project, bool looseMatching )
632{
633 for ( QgsLayerTreeNode *node : std::as_const( mChildren ) )
634 node->resolveReferences( project, looseMatching );
635
636 mGroupLayer.resolve( project );
637}
638
639static bool _nodeIsChecked( QgsLayerTreeNode *node )
640{
641 return node->itemVisibilityChecked();
642}
643
644
649
650void QgsLayerTreeGroup::setIsMutuallyExclusive( bool enabled, int initialChildIndex )
651{
652 mMutuallyExclusive = enabled;
653 mMutuallyExclusiveChildIndex = initialChildIndex;
654
655 if ( !enabled )
656 {
657 return;
658 }
659
661 {
662 // try to use first checked index
663 int index = 0;
664 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
665 {
666 if ( _nodeIsChecked( child ) )
667 {
669 break;
670 }
671 index++;
672 }
673 }
674
676}
677
679{
680 return qobject_cast< QgsGroupLayer * >( mGroupLayer.layer );
681}
682
684{
685 if ( QgsGroupLayer *groupLayer = qobject_cast< QgsGroupLayer * >( mGroupLayer.get() ) )
686 {
687 if ( !layer )
688 {
689 groupLayer->prepareLayersForRemovalFromGroup();
690 }
691 }
692 mGroupLayer.setLayer( layer );
693 refreshParentGroupLayerMembers();
694}
695
697{
698 if ( !mGroupLayer.layerId.isEmpty() )
699 return nullptr;
700
701 auto res = std::make_unique< QgsGroupLayer >( name(), options );
702
703 mGroupLayer.setLayer( res.get() );
704 updateGroupLayers();
705
706 return res.release();
707}
708
709void QgsLayerTreeGroup::refreshParentGroupLayerMembers()
710{
711 QgsLayerTreeGroup *parentGroup = qobject_cast< QgsLayerTreeGroup * >( parent() );
712 while ( parentGroup )
713 {
714 if ( QgsLayerTree *layerTree = qobject_cast< QgsLayerTree * >( parentGroup ) )
715 layerTree->emit layerOrderChanged();
716
717 parentGroup->updateGroupLayers();
718 parentGroup = qobject_cast< QgsLayerTreeGroup * >( parentGroup->parent() );
719 }
720}
721
723{
724 QStringList lst;
725 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
726 {
727 if ( QgsLayerTree::isGroup( child ) )
728 lst << QgsLayerTree::toGroup( child )->findLayerIds();
729 else if ( QgsLayerTree::isLayer( child ) )
730 lst << QgsLayerTree::toLayer( child )->layerId();
731 }
732 return lst;
733}
734
736{
737 QStringList lst;
738 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
739 {
740 if ( QgsLayerTree::isGroup( child ) )
741 lst << QgsLayerTree::toGroup( child )->findCustomNodeIds();
742 else if ( QgsLayerTree::isCustomNode( child ) )
743 lst << QgsLayerTree::toCustomNode( child )->nodeId();
744 }
745 return lst;
746}
747
749{
750 int childIndex = mChildren.indexOf( node );
751 if ( childIndex == -1 )
752 {
753 updateGroupLayers();
754 return; // not a direct child - ignore
755 }
756
757 if ( mMutuallyExclusive )
758 {
759 if ( _nodeIsChecked( node ) )
760 mMutuallyExclusiveChildIndex = childIndex;
761 else if ( mMutuallyExclusiveChildIndex == childIndex )
763
764 // we need to make sure there is only one child node checked
766 }
767
768 updateGroupLayers();
769}
770
772{
773 if ( mChildren.isEmpty() )
774 return;
775
776 mChangingChildVisibility = true; // guard against running again setVisible() triggered from children
777
778 int index = 0;
779 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
780 {
781 child->setItemVisibilityChecked( index == mMutuallyExclusiveChildIndex );
782 ++index;
783 }
784
786
787 updateGroupLayers();
788}
789
791{
793 // Reconnect internal signals
795}
796
797void QgsLayerTreeGroup::updateGroupLayers()
798{
799 QgsGroupLayer *groupLayer = qobject_cast< QgsGroupLayer * >( mGroupLayer.get() );
800 if ( !groupLayer )
801 return;
802
803 QList< QgsMapLayer * > layers;
804
805 std::function< void( QgsLayerTreeGroup * ) > findGroupLayerChildren;
806 findGroupLayerChildren = [&layers, &findGroupLayerChildren]( QgsLayerTreeGroup *group ) {
807 for ( auto it = group->mChildren.crbegin(); it != group->mChildren.crend(); ++it )
808 {
809 if ( QgsLayerTreeLayer *layerTreeLayer = qobject_cast< QgsLayerTreeLayer * >( *it ) )
810 {
811 if ( layerTreeLayer->layer() && layerTreeLayer->isVisible() )
812 layers << layerTreeLayer->layer();
813 }
814 else if ( QgsLayerTreeGroup *childGroup = qobject_cast< QgsLayerTreeGroup * >( *it ) )
815 {
816 if ( childGroup->isVisible() )
817 {
818 if ( QgsGroupLayer *groupLayer = childGroup->groupLayer() )
819 layers << groupLayer;
820 else
821 findGroupLayerChildren( childGroup );
822 }
823 }
824 }
825 };
826 findGroupLayerChildren( this );
827
828 groupLayer->setChildLayers( layers );
829 refreshParentGroupLayerMembers();
830}
831
833{
835
836 mChangingChildVisibility = true; // guard against running again setVisible() triggered from children
837
838 int index = 0;
839 for ( QgsLayerTreeNode *child : std::as_const( mChildren ) )
840 {
841 child->setItemVisibilityCheckedRecursive( checked && ( mMutuallyExclusiveChildIndex < 0 || index == mMutuallyExclusiveChildIndex ) );
842 ++index;
843 }
844
846
847 updateGroupLayers();
848}
849
851{
852 return mServerProperties.get();
853}
854
856{
857 return mServerProperties.get();
858}
859
864
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(QgsLayerTreeCustomNode *customNode)
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:113
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:35
_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.