QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 : qgis::as_const( other.mChildren ) )
42  clonedChildren << child->clone();
43  insertChildrenPrivate( -1, clonedChildren );
44 }
45 
47 {
48  qDeleteAll( mChildren );
49 }
50 
51 QgsLayerTreeNode *QgsLayerTreeNode::readXml( QDomElement &element, const QgsReadWriteContext &context )
52 {
53  QgsLayerTreeNode *node = nullptr;
54  if ( element.tagName() == QLatin1String( "layer-tree-group" ) )
55  node = QgsLayerTreeGroup::readXml( element, context );
56  else if ( element.tagName() == QLatin1String( "layer-tree-layer" ) )
57  node = QgsLayerTreeLayer::readXml( element, context );
58 
59  return node;
60 }
61 
62 QgsLayerTreeNode *QgsLayerTreeNode::readXml( QDomElement &element, const QgsProject *project )
63 {
64  QgsReadWriteContext context;
65  QgsPathResolver resolver;
66  if ( project )
67  resolver = project->pathResolver();
68  context.setPathResolver( resolver );
69  context.setProjectTranslator( const_cast<QgsProject *>( project ) );
70 
71  QgsLayerTreeNode *node = readXml( element, context );
72  if ( node )
73  node->resolveReferences( project );
74  return node;
75 }
76 
77 
79 {
80  if ( mChecked == checked )
81  return;
82  mChecked = checked;
83  emit visibilityChanged( this );
84 }
85 
87 {
88  setItemVisibilityChecked( checked );
89 }
90 
92 {
93  setItemVisibilityChecked( checked );
94  if ( mParent )
96 }
97 
99 {
100  return mChecked && ( !mParent || mParent->isVisible() );
101 }
102 
103 
105 {
106  return mExpanded;
107 }
108 
110 {
111  if ( !mChecked )
112  return false;
113  const auto constMChildren = mChildren;
114  for ( QgsLayerTreeNode *child : constMChildren )
115  {
116  if ( !child->isItemVisibilityCheckedRecursive() )
117  return false;
118  }
119 
120  return true;
121 }
122 
124 {
125  if ( mChecked )
126  return false;
127  const auto constMChildren = mChildren;
128  for ( QgsLayerTreeNode *child : constMChildren )
129  {
130  if ( !child->isItemVisibilityUncheckedRecursive() )
131  return false;
132  }
133 
134  return true;
135 }
136 
137 void fetchCheckedLayers( const QgsLayerTreeNode *node, QList<QgsMapLayer *> &layers )
138 {
139  if ( QgsLayerTree::isLayer( node ) )
140  {
141  const QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
142  if ( nodeLayer->isVisible() )
143  layers << nodeLayer->layer();
144  }
145 
146  const auto constChildren = node->children();
147  for ( QgsLayerTreeNode *child : constChildren )
148  fetchCheckedLayers( child, layers );
149 }
150 
151 QList<QgsMapLayer *> QgsLayerTreeNode::checkedLayers() const
152 {
153  QList<QgsMapLayer *> layers;
154  fetchCheckedLayers( this, layers );
155  return layers;
156 }
157 
159 {
160  int depth = 0;
161  QgsLayerTreeNode *node = mParent;
162  while ( node )
163  {
164  node = node->parent();
165  ++depth;
166  }
167  return depth;
168 }
169 
170 void QgsLayerTreeNode::setExpanded( bool expanded )
171 {
172  if ( mExpanded == expanded )
173  return;
174 
175  mExpanded = expanded;
176  emit expandedChanged( this, expanded );
177 }
178 
179 
180 void QgsLayerTreeNode::setCustomProperty( const QString &key, const QVariant &value )
181 {
182  if ( !mProperties.contains( key ) || mProperties.value( key ) != value )
183  {
184  mProperties.setValue( key, value );
185  emit customPropertyChanged( this, key );
186  }
187 }
188 
189 QVariant QgsLayerTreeNode::customProperty( const QString &key, const QVariant &defaultValue ) const
190 {
191  return mProperties.value( key, defaultValue );
192 }
193 
194 void QgsLayerTreeNode::removeCustomProperty( const QString &key )
195 {
196  if ( mProperties.contains( key ) )
197  {
198  mProperties.remove( key );
199  emit customPropertyChanged( this, key );
200  }
201 }
202 
204 {
205  return mProperties.keys();
206 }
207 
208 void QgsLayerTreeNode::readCommonXml( QDomElement &element )
209 {
210  mProperties.readXml( element );
211 }
212 
213 void QgsLayerTreeNode::writeCommonXml( QDomElement &element )
214 {
215  QDomDocument doc( element.ownerDocument() );
216  mProperties.writeXml( element, doc );
217 }
218 
219 void QgsLayerTreeNode::insertChildrenPrivate( int index, QList<QgsLayerTreeNode *> nodes )
220 {
221  if ( nodes.isEmpty() )
222  return;
223 
224  const auto constNodes = nodes;
225  for ( QgsLayerTreeNode *node : constNodes )
226  {
227  Q_ASSERT( !node->mParent );
228  node->mParent = this;
229  }
230 
231  if ( index < 0 || index >= mChildren.count() )
232  index = mChildren.count();
233 
234  int indexTo = index + nodes.count() - 1;
235  emit willAddChildren( this, index, indexTo );
236  for ( int i = 0; i < nodes.count(); ++i )
237  {
238  QgsLayerTreeNode *node = nodes.at( i );
239  mChildren.insert( index + i, node );
240 
241  // forward the signal towards the root
250  }
251  emit addedChildren( this, index, indexTo );
252 }
253 
254 void QgsLayerTreeNode::removeChildrenPrivate( int from, int count, bool destroy )
255 {
256  if ( from < 0 || count <= 0 )
257  return;
258 
259  int to = from + count - 1;
260  if ( to >= mChildren.count() )
261  return;
262  emit willRemoveChildren( this, from, to );
263  while ( --count >= 0 )
264  {
265  QgsLayerTreeNode *node = mChildren.takeAt( from );
266  node->mParent = nullptr;
267  if ( destroy )
268  delete node;
269  }
270  emit removedChildren( this, from, to );
271 }
272 
274 {
275  int index = mChildren.indexOf( node );
276  if ( index < 0 )
277  return false;
278 
279  int n = mChildren.size();
280 
281  removeChildrenPrivate( index, 1, false );
282 
283  return mChildren.size() < n;
284 }
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:78
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:35
QgsLayerTreeNode::writeCommonXml
void writeCommonXml(QDomElement &element)
Write common XML elements.
Definition: qgslayertreenode.cpp:213
QgsLayerTreeNode::mChecked
bool mChecked
Definition: qgslayertreenode.h:279
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:2674
QgsLayerTreeNode::insertChildrenPrivate
void insertChildrenPrivate(int index, QList< QgsLayerTreeNode * > nodes)
Low-level insertion of children to the node. The children must not have any parent yet!
Definition: qgslayertreenode.cpp:219
QgsLayerTreeNode::~QgsLayerTreeNode
~QgsLayerTreeNode() override
Definition: qgslayertreenode.cpp:46
QgsLayerTreeNode::mChildren
QList< QgsLayerTreeNode * > mChildren
list of children - node is responsible for their deletion
Definition: qgslayertreenode.h:283
QgsLayerTreeNode::mParent
QgsLayerTreeNode * mParent
pointer to the parent node - nullptr in case of root node
Definition: qgslayertreenode.h:281
QgsObjectCustomProperties::readXml
void readXml(const QDomNode &parentNode, const QString &keyStartsWith=QString())
Read store contents from an XML node.
Definition: qgsobjectcustomproperties.cpp:50
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:137
QgsLayerTree::toLayer
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Definition: qgslayertree.h:75
QgsLayerTreeNode::nameChanged
void nameChanged(QgsLayerTreeNode *node, QString name)
Emitted when the name of the node is changed.
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:91
QgsLayerTreeNode::isItemVisibilityCheckedRecursive
bool isItemVisibilityCheckedRecursive() const
Returns whether this node is checked and all its children.
Definition: qgslayertreenode.cpp:109
QgsProject
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:95
QgsLayerTreeNode::isItemVisibilityUncheckedRecursive
bool isItemVisibilityUncheckedRecursive() const
Returns whether this node is unchecked and all its children.
Definition: qgslayertreenode.cpp:123
QgsLayerTreeLayer
Layer tree node points to a map layer.
Definition: qgslayertreelayer.h:44
QgsObjectCustomProperties::setValue
void setValue(const QString &key, const QVariant &value)
Add an entry to the store with the specified key.
Definition: qgsobjectcustomproperties.cpp:30
QgsLayerTreeNode::depth
int depth() const
Returns the depth of this node, i.e.
Definition: qgslayertreenode.cpp:158
QgsLayerTreeLayer::layer
QgsMapLayer * layer() const
Returns the map layer associated with this node.
Definition: qgslayertreelayer.h:74
qgslayertree.h
QgsLayerTreeNode::isExpanded
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
Definition: qgslayertreenode.cpp:104
QgsLayerTreeNode::readXml
static QgsLayerTreeNode * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read layer tree from XML.
Definition: qgslayertreenode.cpp:51
QgsObjectCustomProperties::remove
void remove(const QString &key)
Removes a key (entry) from the store.
Definition: qgsobjectcustomproperties.cpp:40
QgsLayerTreeNode::mProperties
QgsObjectCustomProperties mProperties
custom properties attached to the node
Definition: qgslayertreenode.h:287
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:203
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:86
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:268
QgsLayerTree::isLayer
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
Definition: qgslayertree.h:53
QgsObjectCustomProperties::contains
bool contains(const QString &key) const
Returns true if the properties contains a key with the specified name.
Definition: qgsobjectcustomproperties.cpp:45
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:180
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:189
QgsObjectCustomProperties::keys
QStringList keys() const
Returns a list of all stored keys.
Definition: qgsobjectcustomproperties.cpp:25
QgsObjectCustomProperties::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Returns the value for the given key.
Definition: qgsobjectcustomproperties.cpp:35
QgsLayerTreeNode::children
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
Definition: qgslayertreenode.h:112
qgslayertreenode.h
QgsLayerTreeNode::takeChild
bool takeChild(QgsLayerTreeNode *node)
Remove a child from a node.
Definition: qgslayertreenode.cpp:273
QgsLayerTreeNode::mExpanded
bool mExpanded
whether the node should be shown in GUI as expanded
Definition: qgslayertreenode.h:285
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:110
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:98
QgsLayerTreeNode::setExpanded
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
Definition: qgslayertreenode.cpp:170
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:194
QgsLayerTreeNode::removeChildrenPrivate
void removeChildrenPrivate(int from, int count, bool destroy=true)
Low-level removal of children from the node.
Definition: qgslayertreenode.cpp:254
QgsPathResolver
Resolves relative paths into absolute paths and vice versa.
Definition: qgspathresolver.h:32
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:151
QgsObjectCustomProperties::writeXml
void writeXml(QDomNode &parentNode, QDomDocument &doc) const
Writes the store contents to an XML node.
Definition: qgsobjectcustomproperties.cpp:115
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:208