QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgslayertreenode.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayertreenode.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 "qgslayertreenode.h"
17 
18 #include "qgslayertree.h"
19 #include "qgslayertreeutils.h"
20 
21 #include <QDomElement>
22 #include <QStringList>
23 
24 
26  : mNodeType( t )
27  , mChecked( checked )
28  , mExpanded( true )
29 {
30 }
31 
33  : QObject( nullptr )
34  , mNodeType( other.mNodeType )
35  , mChecked( other.mChecked )
36  , mExpanded( other.mExpanded )
37  , mProperties( other.mProperties )
38 {
39  QList<QgsLayerTreeNode *> clonedChildren;
40 
41  for ( QgsLayerTreeNode *child : std::as_const( other.mChildren ) )
42  clonedChildren << child->clone();
43  insertChildrenPrivate( -1, clonedChildren );
44 }
45 
47 {
48  qDeleteAll( mChildren );
49 }
50 
51 QList<QgsLayerTreeNode *> QgsLayerTreeNode::abandonChildren()
52 {
53  const QList<QgsLayerTreeNode *> orphans { mChildren };
54  mChildren.clear();
55  for ( auto orphan : std::as_const( orphans ) )
56  {
57  orphan->makeOrphan( );
58  }
59  return orphans;
60 }
61 
63 {
64  disconnect();
65  mParent = nullptr;
66 }
67 
68 QgsLayerTreeNode *QgsLayerTreeNode::readXml( QDomElement &element, const QgsReadWriteContext &context )
69 {
70  QgsLayerTreeNode *node = nullptr;
71  if ( element.tagName() == QLatin1String( "layer-tree-group" ) )
72  node = QgsLayerTreeGroup::readXml( element, context );
73  else if ( element.tagName() == QLatin1String( "layer-tree-layer" ) )
74  node = QgsLayerTreeLayer::readXml( element, context );
75 
76  return node;
77 }
78 
79 QgsLayerTreeNode *QgsLayerTreeNode::readXml( QDomElement &element, const QgsProject *project )
80 {
81  QgsReadWriteContext context;
82  QgsPathResolver resolver;
83  if ( project )
84  resolver = project->pathResolver();
85  context.setPathResolver( resolver );
86  context.setProjectTranslator( const_cast<QgsProject *>( project ) );
87 
88  QgsLayerTreeNode *node = readXml( element, context );
89  if ( node )
90  node->resolveReferences( project );
91  return node;
92 }
93 
94 
96 {
97  if ( mChecked == checked )
98  return;
99  mChecked = checked;
100  emit visibilityChanged( this );
101 }
102 
104 {
105  setItemVisibilityChecked( checked );
106 }
107 
109 {
110  setItemVisibilityChecked( checked );
111  if ( mParent )
113 }
114 
116 {
117  return mChecked && ( !mParent || mParent->isVisible() );
118 }
119 
120 
122 {
123  return mExpanded;
124 }
125 
127 {
128  if ( !mChecked )
129  return false;
130  const auto constMChildren = mChildren;
131  for ( QgsLayerTreeNode *child : constMChildren )
132  {
133  if ( !child->isItemVisibilityCheckedRecursive() )
134  return false;
135  }
136 
137  return true;
138 }
139 
141 {
142  if ( mChecked )
143  return false;
144  const auto constMChildren = mChildren;
145  for ( QgsLayerTreeNode *child : constMChildren )
146  {
147  if ( !child->isItemVisibilityUncheckedRecursive() )
148  return false;
149  }
150 
151  return true;
152 }
153 
154 void fetchCheckedLayers( const QgsLayerTreeNode *node, QList<QgsMapLayer *> &layers )
155 {
156  if ( QgsLayerTree::isLayer( node ) )
157  {
158  const QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
159  if ( nodeLayer->isVisible() )
160  layers << nodeLayer->layer();
161  }
162 
163  const auto constChildren = node->children();
164  for ( QgsLayerTreeNode *child : constChildren )
165  {
166  if ( QgsLayerTreeGroup *group = qobject_cast< QgsLayerTreeGroup * >( child ) )
167  {
168  if ( QgsGroupLayer *groupLayer = group->groupLayer() )
169  {
170  layers << groupLayer;
171  continue;
172  }
173  }
174 
175  fetchCheckedLayers( child, layers );
176  }
177 }
178 
179 QList<QgsMapLayer *> QgsLayerTreeNode::checkedLayers() const
180 {
181  QList<QgsMapLayer *> layers;
182  fetchCheckedLayers( this, layers );
183  return layers;
184 }
185 
187 {
188  int depth = 0;
189  QgsLayerTreeNode *node = mParent;
190  while ( node )
191  {
192  node = node->parent();
193  ++depth;
194  }
195  return depth;
196 }
197 
198 void QgsLayerTreeNode::setExpanded( bool expanded )
199 {
200  if ( mExpanded == expanded )
201  return;
202 
203  mExpanded = expanded;
204  emit expandedChanged( this, expanded );
205 }
206 
207 
208 void QgsLayerTreeNode::setCustomProperty( const QString &key, const QVariant &value )
209 {
210  if ( !mProperties.contains( key ) || mProperties.value( key ) != value )
211  {
212  mProperties.setValue( key, value );
213  emit customPropertyChanged( this, key );
214  }
215 }
216 
217 QVariant QgsLayerTreeNode::customProperty( const QString &key, const QVariant &defaultValue ) const
218 {
219  return mProperties.value( key, defaultValue );
220 }
221 
222 void QgsLayerTreeNode::removeCustomProperty( const QString &key )
223 {
224  if ( mProperties.contains( key ) )
225  {
226  mProperties.remove( key );
227  emit customPropertyChanged( this, key );
228  }
229 }
230 
232 {
233  return mProperties.keys();
234 }
235 
236 void QgsLayerTreeNode::readCommonXml( QDomElement &element )
237 {
238  mProperties.readXml( element );
239 }
240 
241 void QgsLayerTreeNode::writeCommonXml( QDomElement &element )
242 {
243  QDomDocument doc( element.ownerDocument() );
244  mProperties.writeXml( element, doc );
245 }
246 
247 void QgsLayerTreeNode::insertChildrenPrivate( int index, const QList<QgsLayerTreeNode *> &nodes )
248 {
249  if ( nodes.isEmpty() )
250  return;
251 
252  for ( QgsLayerTreeNode *node : nodes )
253  {
254  Q_ASSERT( !node->mParent );
255  node->mParent = this;
256  }
257 
258  if ( index < 0 || index >= mChildren.count() )
259  index = mChildren.count();
260 
261  for ( int i = 0; i < nodes.count(); ++i )
262  {
263  QgsLayerTreeNode *node = nodes.at( i );
264 
265  const QList<QgsLayerTreeNode *> orphans { node->abandonChildren() };
266 
267  emit willAddChildren( this, index + i, index + i );
268  mChildren.insert( index + i, node );
269  emit addedChildren( this, index + i, index + i );
270 
271  // forward the signal towards the root
280 
281  // Now add children
282  if ( ! orphans.isEmpty() )
283  {
284  node->insertChildrenPrivate( -1, orphans );
285  }
286 
287  }
288 }
289 
290 void QgsLayerTreeNode::removeChildrenPrivate( int from, int count, bool destroy )
291 {
292  if ( from < 0 || count <= 0 )
293  return;
294 
295  const int to = from + count - 1;
296  if ( to >= mChildren.count() )
297  return;
298 
299  // Remove in reverse order
300  while ( --count >= 0 )
301  {
302  const int last { from + count };
303  Q_ASSERT( last >= 0 && last < mChildren.count( ) );
304  QgsLayerTreeNode *node = mChildren.at( last );
305 
306  // Remove children first
307  if ( ! node->children().isEmpty() )
308  {
309  node->removeChildrenPrivate( 0, node->children().count( ), destroy );
310  }
311 
312  emit willRemoveChildren( this, last, last );
313  node = mChildren.takeAt( last );
314  if ( destroy )
315  {
316  delete node;
317  }
318  else
319  {
320  node->makeOrphan();
321  }
322  emit removedChildren( this, last, last );
323  }
324 }
325 
327 {
328  int index = mChildren.indexOf( node );
329  if ( index < 0 )
330  return false;
331 
332  int n = mChildren.size();
333 
334  removeChildrenPrivate( index, 1, false );
335 
336  return mChildren.size() < n;
337 }
QgsReadWriteContext::setPathResolver
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
Definition: qgsreadwritecontext.cpp:52
QgsLayerTreeNode
This class is a base class for nodes in a layer tree.
Definition: qgslayertreenode.h:75
QgsLayerTreeNode::setItemVisibilityChecked
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
Definition: qgslayertreenode.cpp:95
QgsLayerTreeNode::removedChildren
void removedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes has been removed from a node within the tree.
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsLayerTreeNode::writeCommonXml
void writeCommonXml(QDomElement &element)
Write common XML elements.
Definition: qgslayertreenode.cpp:241
QgsLayerTreeNode::mChecked
bool mChecked
Definition: qgslayertreenode.h:295
QgsLayerTreeNode::resolveReferences
virtual void resolveReferences(const QgsProject *project, bool looseMatching=false)=0
Turn textual references to layers into map layer object from project.
QgsLayerTreeNode::QgsLayerTreeNode
QgsLayerTreeNode(NodeType t, bool checked=true)
Constructor.
Definition: qgslayertreenode.cpp:25
QgsLayerTreeNode::expandedChanged
void expandedChanged(QgsLayerTreeNode *node, bool expanded)
Emitted when the collapsed/expanded state of a node within the tree has been changed.
QgsProject::pathResolver
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
Definition: qgsproject.cpp:3094
QgsLayerTreeNode::~QgsLayerTreeNode
~QgsLayerTreeNode() override
Definition: qgslayertreenode.cpp:46
QgsGroupLayer
A map layer which consists of a set of child layers, where all component layers are rendered as a sin...
Definition: qgsgrouplayer.h:41
QgsLayerTreeNode::mChildren
QList< QgsLayerTreeNode * > mChildren
list of children - node is responsible for their deletion
Definition: qgslayertreenode.h:299
QgsLayerTreeNode::mParent
QgsLayerTreeNode * mParent
pointer to the parent node - nullptr in case of root node
Definition: qgslayertreenode.h:297
QgsObjectCustomProperties::readXml
void readXml(const QDomNode &parentNode, const QString &keyStartsWith=QString())
Read store contents from an XML node.
Definition: qgsobjectcustomproperties.cpp:51
QgsLayerTreeNode::customPropertyChanged
void customPropertyChanged(QgsLayerTreeNode *node, const QString &key)
Emitted when a custom property of a node within the tree has been changed or removed.
fetchCheckedLayers
void fetchCheckedLayers(const QgsLayerTreeNode *node, QList< QgsMapLayer * > &layers)
Definition: qgslayertreenode.cpp:154
QgsLayerTree::toLayer
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Definition: qgslayertree.h:88
QgsLayerTreeNode::nameChanged
void nameChanged(QgsLayerTreeNode *node, QString name)
Emitted when the name of the node is changed.
QgsLayerTreeNode::abandonChildren
QList< QgsLayerTreeNode * > abandonChildren()
Removes the childrens, disconnect all the forwarded and external signals and sets their parent to nul...
Definition: qgslayertreenode.cpp:51
QgsReadWriteContext::setProjectTranslator
void setProjectTranslator(QgsProjectTranslator *projectTranslator)
Sets the project translator.
Definition: qgsreadwritecontext.cpp:87
QgsLayerTreeNode::setItemVisibilityCheckedParentRecursive
void setItemVisibilityCheckedParentRecursive(bool checked)
Check or uncheck a node and all its parents.
Definition: qgslayertreenode.cpp:108
QgsLayerTreeNode::isItemVisibilityCheckedRecursive
bool isItemVisibilityCheckedRecursive() const
Returns whether this node is checked and all its children.
Definition: qgslayertreenode.cpp:126
QgsProject
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:103
QgsLayerTreeNode::insertChildrenPrivate
void insertChildrenPrivate(int index, const QList< QgsLayerTreeNode * > &nodes)
Low-level insertion of children to the node. The children must not have any parent yet!
Definition: qgslayertreenode.cpp:247
QgsLayerTreeNode::isItemVisibilityUncheckedRecursive
bool isItemVisibilityUncheckedRecursive() const
Returns whether this node is unchecked and all its children.
Definition: qgslayertreenode.cpp:140
QgsLayerTreeLayer
Layer tree node points to a map layer.
Definition: qgslayertreelayer.h:43
QgsObjectCustomProperties::setValue
void setValue(const QString &key, const QVariant &value)
Add an entry to the store with the specified key.
Definition: qgsobjectcustomproperties.cpp:31
QgsLayerTreeGroup
Layer tree group node serves as a container for layers and further groups.
Definition: qgslayertreegroup.h:40
QgsLayerTreeNode::depth
int depth() const
Returns the depth of this node, i.e.
Definition: qgslayertreenode.cpp:186
QgsLayerTreeLayer::layer
QgsMapLayer * layer() const
Returns the map layer associated with this node.
Definition: qgslayertreelayer.h:82
qgslayertree.h
QgsLayerTreeNode::isExpanded
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
Definition: qgslayertreenode.cpp:121
QgsLayerTreeNode::readXml
static QgsLayerTreeNode * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read layer tree from XML.
Definition: qgslayertreenode.cpp:68
QgsObjectCustomProperties::remove
void remove(const QString &key)
Removes a key (entry) from the store.
Definition: qgsobjectcustomproperties.cpp:41
QgsLayerTreeNode::mProperties
QgsObjectCustomProperties mProperties
custom properties attached to the node
Definition: qgslayertreenode.h:303
QgsLayerTreeNode::NodeType
NodeType
Enumeration of possible tree node types.
Definition: qgslayertreenode.h:100
QgsLayerTreeNode::customProperties
QStringList customProperties() const
Returns list of keys stored in custom properties.
Definition: qgslayertreenode.cpp:231
QgsLayerTreeNode::willAddChildren
void willAddChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes will be added to a node within the tree.
QgsLayerTreeNode::setItemVisibilityCheckedRecursive
virtual void setItemVisibilityCheckedRecursive(bool checked)
Check or uncheck a node and all its children (taking into account exclusion rules)
Definition: qgslayertreenode.cpp:103
QgsLayerTreeGroup::readXml
static QgsLayerTreeGroup * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read group (tree) from XML element <layer-tree-group> and return the newly created group (or nullptr ...
Definition: qgslayertreegroup.cpp:327
QgsLayerTree::isLayer
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
Definition: qgslayertree.h:66
QgsObjectCustomProperties::contains
bool contains(const QString &key) const
Returns true if the properties contains a key with the specified name.
Definition: qgsobjectcustomproperties.cpp:46
QgsLayerTreeNode::setCustomProperty
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
Definition: qgslayertreenode.cpp:208
QgsLayerTreeNode::customProperty
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.
Definition: qgslayertreenode.cpp:217
QgsObjectCustomProperties::keys
QStringList keys() const
Returns a list of all stored keys.
Definition: qgsobjectcustomproperties.cpp:26
QgsObjectCustomProperties::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Returns the value for the given key.
Definition: qgsobjectcustomproperties.cpp:36
QgsLayerTreeNode::makeOrphan
virtual void makeOrphan()
Sets parent to nullptr and disconnects all external and forwarded signals.
Definition: qgslayertreenode.cpp:62
QgsLayerTreeNode::children
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
Definition: qgslayertreenode.h:121
qgslayertreenode.h
QgsLayerTreeNode::takeChild
bool takeChild(QgsLayerTreeNode *node)
Remove a child from a node.
Definition: qgslayertreenode.cpp:326
QgsLayerTreeNode::mExpanded
bool mExpanded
whether the node should be shown in GUI as expanded
Definition: qgslayertreenode.h:301
qgslayertreeutils.h
QgsLayerTreeNode::addedChildren
void addedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes have been added to a node within the tree.
QgsLayerTreeNode::parent
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
Definition: qgslayertreenode.h:119
QgsLayerTreeNode::willRemoveChildren
void willRemoveChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes will be removed from a node within the tree.
QgsLayerTreeNode::isVisible
bool isVisible() const
Returns whether a node is really visible (ie checked and all its ancestors checked as well)
Definition: qgslayertreenode.cpp:115
QgsLayerTreeNode::setExpanded
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
Definition: qgslayertreenode.cpp:198
QgsLayerTreeNode::removeCustomProperty
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file.
Definition: qgslayertreenode.cpp:222
QgsLayerTreeNode::removeChildrenPrivate
void removeChildrenPrivate(int from, int count, bool destroy=true)
Low-level removal of children from the node.
Definition: qgslayertreenode.cpp:290
QgsPathResolver
Resolves relative paths into absolute paths and vice versa. Used for writing.
Definition: qgspathresolver.h:31
QgsLayerTreeLayer::readXml
static QgsLayerTreeLayer * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read layer node from XML.
Definition: qgslayertreelayer.cpp:104
QgsLayerTreeNode::checkedLayers
QList< QgsMapLayer * > checkedLayers() const
Returns a list of any checked layers which belong to this node or its children.
Definition: qgslayertreenode.cpp:179
QgsObjectCustomProperties::writeXml
void writeXml(QDomNode &parentNode, QDomDocument &doc) const
Writes the store contents to an XML node.
Definition: qgsobjectcustomproperties.cpp:130
QgsLayerTreeNode::visibilityChanged
void visibilityChanged(QgsLayerTreeNode *node)
Emitted when check state of a node within the tree has been changed.
QgsLayerTreeNode::readCommonXml
void readCommonXml(QDomElement &element)
Read common XML elements.
Definition: qgslayertreenode.cpp:236