QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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 
158 void QgsLayerTreeNode::setExpanded( bool expanded )
159 {
160  if ( mExpanded == expanded )
161  return;
162 
163  mExpanded = expanded;
164  emit expandedChanged( this, expanded );
165 }
166 
167 
168 void QgsLayerTreeNode::setCustomProperty( const QString &key, const QVariant &value )
169 {
170  mProperties.setValue( key, value );
171  emit customPropertyChanged( this, key );
172 }
173 
174 QVariant QgsLayerTreeNode::customProperty( const QString &key, const QVariant &defaultValue ) const
175 {
176  return mProperties.value( key, defaultValue );
177 }
178 
179 void QgsLayerTreeNode::removeCustomProperty( const QString &key )
180 {
181  mProperties.remove( key );
182  emit customPropertyChanged( this, key );
183 }
184 
186 {
187  return mProperties.keys();
188 }
189 
190 void QgsLayerTreeNode::readCommonXml( QDomElement &element )
191 {
192  mProperties.readXml( element );
193 }
194 
195 void QgsLayerTreeNode::writeCommonXml( QDomElement &element )
196 {
197  QDomDocument doc( element.ownerDocument() );
198  mProperties.writeXml( element, doc );
199 }
200 
201 void QgsLayerTreeNode::insertChildrenPrivate( int index, QList<QgsLayerTreeNode *> nodes )
202 {
203  if ( nodes.isEmpty() )
204  return;
205 
206  const auto constNodes = nodes;
207  for ( QgsLayerTreeNode *node : constNodes )
208  {
209  Q_ASSERT( !node->mParent );
210  node->mParent = this;
211  }
212 
213  if ( index < 0 || index >= mChildren.count() )
214  index = mChildren.count();
215 
216  int indexTo = index + nodes.count() - 1;
217  emit willAddChildren( this, index, indexTo );
218  for ( int i = 0; i < nodes.count(); ++i )
219  {
220  QgsLayerTreeNode *node = nodes.at( i );
221  mChildren.insert( index + i, node );
222 
223  // forward the signal towards the root
232  }
233  emit addedChildren( this, index, indexTo );
234 }
235 
236 void QgsLayerTreeNode::removeChildrenPrivate( int from, int count, bool destroy )
237 {
238  if ( from < 0 || count <= 0 )
239  return;
240 
241  int to = from + count - 1;
242  if ( to >= mChildren.count() )
243  return;
244  emit willRemoveChildren( this, from, to );
245  while ( --count >= 0 )
246  {
247  QgsLayerTreeNode *node = mChildren.takeAt( from );
248  node->mParent = nullptr;
249  if ( destroy )
250  delete node;
251  }
252  emit removedChildren( this, from, to );
253 }
254 
256 {
257  int index = mChildren.indexOf( node );
258  if ( index < 0 )
259  return false;
260 
261  int n = mChildren.size();
262 
263  removeChildrenPrivate( index, 1, false );
264 
265  return mChildren.size() < n;
266 }
The class is used as a container of context for various read/write operations on other objects...
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Definition: qgslayertree.h:75
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
bool isItemVisibilityUncheckedRecursive() const
Returns whether this node is unchecked and all its children.
void readXml(const QDomNode &parentNode, const QString &keyStartsWith=QString())
Read store contents from XML.
void setProjectTranslator(QgsProjectTranslator *projectTranslator)
Sets the project translator.
void insertChildrenPrivate(int index, QList< QgsLayerTreeNode *> nodes)
Low-level insertion of children to the node. The children must not have any parent yet! ...
bool takeChild(QgsLayerTreeNode *node)
Remove a child from a node.
bool mExpanded
whether the node should be shown in GUI as expanded
void willRemoveChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes will be removed from a node within the tree.
bool isVisible() const
Returns whether a node is really visible (ie checked and all its ancestors checked as well) ...
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Returns value for the given key. If the key is not stored, default value will be used.
void writeXml(QDomNode &parentNode, QDomDocument &doc) const
Write store contents to XML.
static QgsLayerTreeNode * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read layer tree from XML.
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
NodeType
Enumeration of possible tree node types.
QStringList customProperties() const
Returns list of keys stored in custom properties.
void remove(const QString &key)
Remove a key (entry) from the store.
void willAddChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes will be added to a node within the tree.
QList< QgsMapLayer *> checkedLayers() const
Returns a list of any checked layers which belong to this node or its children.
void removedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes has been removed from a node within the tree.
NodeType mNodeType
type of the node - determines which subclass is used
virtual void setItemVisibilityCheckedRecursive(bool checked)
Check or uncheck a node and all its children (taking into account exclusion rules) ...
void setValue(const QString &key, const QVariant &value)
Add an entry to the store. If the entry with the keys exists already, it will be overwritten.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
void expandedChanged(QgsLayerTreeNode *node, bool expanded)
Emitted when the collapsed/expanded state of a node within the tree has been changed.
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
void addedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes have been added to a node within the tree.
void writeCommonXml(QDomElement &element)
Write common XML elements.
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...
QgsLayerTreeNode * mParent
pointer to the parent node - nullptr in case of root node
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
Definition: qgslayertree.h:53
This class is a base class for nodes in a layer tree.
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 ...
Reads and writes project states.
Definition: qgsproject.h:89
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file...
~QgsLayerTreeNode() override
QStringList keys() const
Returns list of stored keys.
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
void setItemVisibilityCheckedParentRecursive(bool checked)
Check or uncheck a node and all its parents.
void removeChildrenPrivate(int from, int count, bool destroy=true)
Low-level removal of children from the node.
bool isItemVisibilityCheckedRecursive() const
Returns whether this node is checked and all its children.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
void visibilityChanged(QgsLayerTreeNode *node)
Emitted when check state of a node within the tree has been changed.
void readCommonXml(QDomElement &element)
Read common XML elements.
virtual void resolveReferences(const QgsProject *project, bool looseMatching=false)=0
Turn textual references to layers into map layer object from project.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
void fetchCheckedLayers(const QgsLayerTreeNode *node, QList< QgsMapLayer *> &layers)
QList< QgsLayerTreeNode * > mChildren
list of children - node is responsible for their deletion
void customPropertyChanged(QgsLayerTreeNode *node, const QString &key)
Emitted when a custom property of a node within the tree has been changed or removed.
Resolves relative paths into absolute paths and vice versa.
void nameChanged(QgsLayerTreeNode *node, QString name)
Emitted when the name of the node is changed.
static QgsLayerTreeLayer * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read layer node from XML.
QgsLayerTreeNode(NodeType t, bool checked=true)
Constructor.
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...
Layer tree node points to a map layer.
QgsObjectCustomProperties mProperties
custom properties attached to the node