QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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  Q_FOREACH ( QgsLayerTreeNode *child, other.mChildren )
41  clonedChildren << child->clone();
42  insertChildrenPrivate( -1, clonedChildren );
43 }
44 
46 {
47  qDeleteAll( mChildren );
48 }
49 
50 QgsLayerTreeNode *QgsLayerTreeNode::readXml( QDomElement &element, const QgsReadWriteContext &context )
51 {
52  QgsLayerTreeNode *node = nullptr;
53  if ( element.tagName() == QLatin1String( "layer-tree-group" ) )
54  node = QgsLayerTreeGroup::readXml( element, context );
55  else if ( element.tagName() == QLatin1String( "layer-tree-layer" ) )
56  node = QgsLayerTreeLayer::readXml( element, context );
57 
58  return node;
59 }
60 
61 QgsLayerTreeNode *QgsLayerTreeNode::readXml( QDomElement &element, const QgsProject *project )
62 {
63  QgsReadWriteContext context;
64  QgsPathResolver resolver;
65  if ( project )
66  resolver = project->pathResolver();
67  context.setPathResolver( resolver );
68  context.setProjectTranslator( const_cast<QgsProject *>( project ) );
69 
70  QgsLayerTreeNode *node = readXml( element, context );
71  if ( node )
72  node->resolveReferences( project );
73  return node;
74 }
75 
76 
78 {
79  if ( mChecked == checked )
80  return;
81  mChecked = checked;
82  emit visibilityChanged( this );
83 }
84 
86 {
87  setItemVisibilityChecked( checked );
88 }
89 
91 {
92  setItemVisibilityChecked( checked );
93  if ( mParent )
95 }
96 
98 {
99  return mChecked && ( !mParent || mParent->isVisible() );
100 }
101 
102 
104 {
105  return mExpanded;
106 }
107 
109 {
110  if ( !mChecked )
111  return false;
112  Q_FOREACH ( QgsLayerTreeNode *child, mChildren )
113  {
114  if ( !child->isItemVisibilityCheckedRecursive() )
115  return false;
116  }
117 
118  return true;
119 }
120 
122 {
123  if ( mChecked )
124  return false;
125  Q_FOREACH ( QgsLayerTreeNode *child, mChildren )
126  {
127  if ( !child->isItemVisibilityUncheckedRecursive() )
128  return false;
129  }
130 
131  return true;
132 }
133 
134 void fetchCheckedLayers( const QgsLayerTreeNode *node, QList<QgsMapLayer *> &layers )
135 {
136  if ( QgsLayerTree::isLayer( node ) )
137  {
138  const QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
139  if ( nodeLayer->isVisible() )
140  layers << nodeLayer->layer();
141  }
142 
143  Q_FOREACH ( QgsLayerTreeNode *child, node->children() )
144  fetchCheckedLayers( child, layers );
145 }
146 
147 QList<QgsMapLayer *> QgsLayerTreeNode::checkedLayers() const
148 {
149  QList<QgsMapLayer *> layers;
150  fetchCheckedLayers( this, layers );
151  return layers;
152 }
153 
154 void QgsLayerTreeNode::setExpanded( bool expanded )
155 {
156  if ( mExpanded == expanded )
157  return;
158 
159  mExpanded = expanded;
160  emit expandedChanged( this, expanded );
161 }
162 
163 
164 void QgsLayerTreeNode::setCustomProperty( const QString &key, const QVariant &value )
165 {
166  mProperties.setValue( key, value );
167  emit customPropertyChanged( this, key );
168 }
169 
170 QVariant QgsLayerTreeNode::customProperty( const QString &key, const QVariant &defaultValue ) const
171 {
172  return mProperties.value( key, defaultValue );
173 }
174 
175 void QgsLayerTreeNode::removeCustomProperty( const QString &key )
176 {
177  mProperties.remove( key );
178  emit customPropertyChanged( this, key );
179 }
180 
182 {
183  return mProperties.keys();
184 }
185 
186 void QgsLayerTreeNode::readCommonXml( QDomElement &element )
187 {
188  mProperties.readXml( element );
189 }
190 
191 void QgsLayerTreeNode::writeCommonXml( QDomElement &element )
192 {
193  QDomDocument doc( element.ownerDocument() );
194  mProperties.writeXml( element, doc );
195 }
196 
197 void QgsLayerTreeNode::insertChildrenPrivate( int index, QList<QgsLayerTreeNode *> nodes )
198 {
199  if ( nodes.isEmpty() )
200  return;
201 
202  Q_FOREACH ( QgsLayerTreeNode *node, nodes )
203  {
204  Q_ASSERT( !node->mParent );
205  node->mParent = this;
206  }
207 
208  if ( index < 0 || index >= mChildren.count() )
209  index = mChildren.count();
210 
211  int indexTo = index + nodes.count() - 1;
212  emit willAddChildren( this, index, indexTo );
213  for ( int i = 0; i < nodes.count(); ++i )
214  {
215  QgsLayerTreeNode *node = nodes.at( i );
216  mChildren.insert( index + i, node );
217 
218  // forward the signal towards the root
227  }
228  emit addedChildren( this, index, indexTo );
229 }
230 
231 void QgsLayerTreeNode::removeChildrenPrivate( int from, int count, bool destroy )
232 {
233  if ( from < 0 || count <= 0 )
234  return;
235 
236  int to = from + count - 1;
237  if ( to >= mChildren.count() )
238  return;
239  emit willRemoveChildren( this, from, to );
240  while ( --count >= 0 )
241  {
242  QgsLayerTreeNode *node = mChildren.takeAt( from );
243  node->mParent = nullptr;
244  if ( destroy )
245  delete node;
246  }
247  emit removedChildren( this, from, to );
248 }
249 
251 {
252  int index = mChildren.indexOf( node );
253  if ( index < 0 )
254  return false;
255 
256  int n = mChildren.size();
257 
258  removeChildrenPrivate( index, 1, false );
259 
260  return mChildren.size() < n;
261 }
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.
void readXml(const QDomNode &parentNode, const QString &keyStartsWith=QString())
Read store contents from XML.
void setProjectTranslator(QgsProjectTranslator *projectTranslator)
Sets the project translator.
bool takeChild(QgsLayerTreeNode *node)
Remove a child from a node.
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...
QgsMapLayer * layer() const
Returns the map layer associated with this node.
virtual QgsLayerTreeNode * clone() const =0
Create a copy of the node. Returns new instance.
bool mExpanded
whether the node should be shown in GUI as expanded
QStringList customProperties() const
Returns list of keys stored in custom properties.
void willRemoveChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes will be removed from a node within the tree.
QList< QgsMapLayer * > checkedLayers() const
Returns a list of any checked layers which belong to this node or its children.
bool isItemVisibilityCheckedRecursive() const
Returns whether this node is checked and all its children.
static QgsLayerTreeNode * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read layer tree from XML.
NodeType
Enumeration of possible tree node types.
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.
void removedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes has been 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.
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 fetchCheckedLayers(const QgsLayerTreeNode *node, QList< QgsMapLayer * > &layers)
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 insertChildrenPrivate(int index, 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.
QStringList keys() const
Returns list of stored keys.
void writeCommonXml(QDomElement &element)
Write common XML elements.
QgsLayerTreeNode * mParent
pointer to the parent node - null 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 null on ...
Reads and writes project states.
Definition: qgsproject.h:89
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file...
~QgsLayerTreeNode() override
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.
void writeXml(QDomNode &parentNode, QDomDocument &doc) const
Write store contents to XML.
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)
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
bool isItemVisibilityUncheckedRecursive() const
Returns whether this node is unchecked and all its children.