QGIS API Documentation  3.6.0-Noosa (5873452)
qgslayertreeutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayertreeutils.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 "qgslayertreeutils.h"
17 #include "qgslayertree.h"
18 #include "qgsvectorlayer.h"
19 #include "qgsproject.h"
20 #include "qgslogger.h"
21 
22 #include <QDomElement>
23 
24 
25 static void _readOldLegendGroup( const QDomElement &groupElem, QgsLayerTreeGroup *parent );
26 static void _readOldLegendLayer( const QDomElement &layerElem, QgsLayerTreeGroup *parent );
27 
28 bool QgsLayerTreeUtils::readOldLegend( QgsLayerTreeGroup *root, const QDomElement &legendElem )
29 {
30  if ( legendElem.isNull() )
31  return false;
32 
33  QDomNodeList legendChildren = legendElem.childNodes();
34 
35  for ( int i = 0; i < legendChildren.size(); ++i )
36  {
37  QDomElement currentChildElem = legendChildren.at( i ).toElement();
38  if ( currentChildElem.tagName() == QLatin1String( "legendlayer" ) )
39  {
40  _readOldLegendLayer( currentChildElem, root );
41  }
42  else if ( currentChildElem.tagName() == QLatin1String( "legendgroup" ) )
43  {
44  _readOldLegendGroup( currentChildElem, root );
45  }
46  }
47 
48  return true;
49 }
50 
51 
52 
53 static bool _readOldLegendLayerOrderGroup( const QDomElement &groupElem, QMap<int, QString> &layerIndexes )
54 {
55  QDomNodeList legendChildren = groupElem.childNodes();
56 
57  for ( int i = 0; i < legendChildren.size(); ++i )
58  {
59  QDomElement currentChildElem = legendChildren.at( i ).toElement();
60  if ( currentChildElem.tagName() == QLatin1String( "legendlayer" ) )
61  {
62  QDomElement layerFileElem = currentChildElem.firstChildElement( QStringLiteral( "filegroup" ) ).firstChildElement( QStringLiteral( "legendlayerfile" ) );
63 
64  int layerIndex = currentChildElem.attribute( QStringLiteral( "drawingOrder" ) ).toInt();
65  if ( layerIndex == -1 )
66  return false; // order undefined
67  layerIndexes.insert( layerIndex, layerFileElem.attribute( QStringLiteral( "layerid" ) ) );
68  }
69  else if ( currentChildElem.tagName() == QLatin1String( "legendgroup" ) )
70  {
71  if ( !_readOldLegendLayerOrderGroup( currentChildElem, layerIndexes ) )
72  return false;
73  }
74  }
75 
76  return true;
77 }
78 
79 
80 bool QgsLayerTreeUtils::readOldLegendLayerOrder( const QDomElement &legendElem, bool &hasCustomOrder, QStringList &order )
81 {
82  if ( legendElem.isNull() )
83  return false;
84 
85  hasCustomOrder = legendElem.attribute( QStringLiteral( "updateDrawingOrder" ) ) == QLatin1String( "false" );
86  order.clear();
87 
88  QMap<int, QString> layerIndexes;
89 
90  // try to read the order. may be undefined (order = -1) for some or all items
91  bool res = _readOldLegendLayerOrderGroup( legendElem, layerIndexes );
92 
93  if ( !res && hasCustomOrder )
94  return false; // invalid state
95 
96  Q_FOREACH ( const QString &layerId, layerIndexes )
97  {
98  QgsDebugMsg( layerId );
99  order.append( layerId );
100  }
101 
102  return true;
103 }
104 
105 
106 static QDomElement _writeOldLegendLayer( QDomDocument &doc, QgsLayerTreeLayer *nodeLayer, bool hasCustomOrder, const QList<QgsMapLayer *> &order )
107 {
108  int drawingOrder = -1;
109  if ( hasCustomOrder )
110  drawingOrder = order.indexOf( nodeLayer->layer() );
111 
112  QDomElement layerElem = doc.createElement( QStringLiteral( "legendlayer" ) );
113  layerElem.setAttribute( QStringLiteral( "drawingOrder" ), drawingOrder );
114  layerElem.setAttribute( QStringLiteral( "open" ), nodeLayer->isExpanded() ? QStringLiteral( "true" ) : QStringLiteral( "false" ) );
115  layerElem.setAttribute( QStringLiteral( "checked" ), QgsLayerTreeUtils::checkStateToXml( nodeLayer->itemVisibilityChecked() ? Qt::Checked : Qt::Unchecked ) );
116  layerElem.setAttribute( QStringLiteral( "name" ), nodeLayer->name() );
117  layerElem.setAttribute( QStringLiteral( "showFeatureCount" ), nodeLayer->customProperty( QStringLiteral( "showFeatureCount" ) ).toInt() );
118 
119  QDomElement fileGroupElem = doc.createElement( QStringLiteral( "filegroup" ) );
120  fileGroupElem.setAttribute( QStringLiteral( "open" ), nodeLayer->isExpanded() ? "true" : "false" );
121  fileGroupElem.setAttribute( QStringLiteral( "hidden" ), QStringLiteral( "false" ) );
122 
123  QDomElement layerFileElem = doc.createElement( QStringLiteral( "legendlayerfile" ) );
124  layerFileElem.setAttribute( QStringLiteral( "isInOverview" ), nodeLayer->customProperty( QStringLiteral( "overview" ) ).toInt() );
125  layerFileElem.setAttribute( QStringLiteral( "layerid" ), nodeLayer->layerId() );
126  layerFileElem.setAttribute( QStringLiteral( "visible" ), nodeLayer->isVisible() ? 1 : 0 );
127 
128  layerElem.appendChild( fileGroupElem );
129  fileGroupElem.appendChild( layerFileElem );
130  return layerElem;
131 }
132 
133 // need forward declaration as write[..]Group and write[..]GroupChildren call each other
134 static void _writeOldLegendGroupChildren( QDomDocument &doc, QDomElement &groupElem, QgsLayerTreeGroup *nodeGroup, bool hasCustomOrder, const QList<QgsMapLayer *> &order );
135 
136 static QDomElement _writeOldLegendGroup( QDomDocument &doc, QgsLayerTreeGroup *nodeGroup, bool hasCustomOrder, const QList<QgsMapLayer *> &order )
137 {
138  QDomElement groupElem = doc.createElement( QStringLiteral( "legendgroup" ) );
139  groupElem.setAttribute( QStringLiteral( "open" ), nodeGroup->isExpanded() ? "true" : "false" );
140  groupElem.setAttribute( QStringLiteral( "name" ), nodeGroup->name() );
141  groupElem.setAttribute( QStringLiteral( "checked" ), QgsLayerTreeUtils::checkStateToXml( nodeGroup->itemVisibilityChecked() ? Qt::Checked : Qt::Unchecked ) );
142 
143  if ( nodeGroup->customProperty( QStringLiteral( "embedded" ) ).toInt() )
144  {
145  groupElem.setAttribute( QStringLiteral( "embedded" ), 1 );
146  groupElem.setAttribute( QStringLiteral( "project" ), nodeGroup->customProperty( QStringLiteral( "embedded_project" ) ).toString() );
147  }
148 
149  _writeOldLegendGroupChildren( doc, groupElem, nodeGroup, hasCustomOrder, order );
150  return groupElem;
151 }
152 
153 
154 static void _writeOldLegendGroupChildren( QDomDocument &doc, QDomElement &groupElem, QgsLayerTreeGroup *nodeGroup, bool hasCustomOrder, const QList<QgsMapLayer *> &order )
155 {
156  Q_FOREACH ( QgsLayerTreeNode *node, nodeGroup->children() )
157  {
158  if ( QgsLayerTree::isGroup( node ) )
159  {
160  groupElem.appendChild( _writeOldLegendGroup( doc, QgsLayerTree::toGroup( node ), hasCustomOrder, order ) );
161  }
162  else if ( QgsLayerTree::isLayer( node ) )
163  {
164  groupElem.appendChild( _writeOldLegendLayer( doc, QgsLayerTree::toLayer( node ), hasCustomOrder, order ) );
165  }
166  }
167 }
168 
169 
170 QDomElement QgsLayerTreeUtils::writeOldLegend( QDomDocument &doc, QgsLayerTreeGroup *root, bool hasCustomOrder, const QList<QgsMapLayer *> &order )
171 {
172  QDomElement legendElem = doc.createElement( QStringLiteral( "legend" ) );
173  legendElem.setAttribute( QStringLiteral( "updateDrawingOrder" ), hasCustomOrder ? QStringLiteral( "false" ) : QStringLiteral( "true" ) );
174 
175  _writeOldLegendGroupChildren( doc, legendElem, root, hasCustomOrder, order );
176 
177  return legendElem;
178 }
179 
180 
181 QString QgsLayerTreeUtils::checkStateToXml( Qt::CheckState state )
182 {
183  switch ( state )
184  {
185  case Qt::Unchecked:
186  return QStringLiteral( "Qt::Unchecked" );
187  case Qt::PartiallyChecked:
188  return QStringLiteral( "Qt::PartiallyChecked" );
189  case Qt::Checked:
190  default:
191  return QStringLiteral( "Qt::Checked" );
192  }
193 }
194 
195 Qt::CheckState QgsLayerTreeUtils::checkStateFromXml( const QString &txt )
196 {
197  if ( txt == QLatin1String( "Qt::Unchecked" ) )
198  return Qt::Unchecked;
199  else if ( txt == QLatin1String( "Qt::PartiallyChecked" ) )
200  return Qt::PartiallyChecked;
201  else // "Qt::Checked"
202  return Qt::Checked;
203 }
204 
205 
206 
207 static void _readOldLegendGroup( const QDomElement &groupElem, QgsLayerTreeGroup *parent )
208 {
209  QDomNodeList groupChildren = groupElem.childNodes();
210 
211  QgsLayerTreeGroup *groupNode = new QgsLayerTreeGroup( groupElem.attribute( QStringLiteral( "name" ) ) );
212 
213  groupNode->setItemVisibilityChecked( QgsLayerTreeUtils::checkStateFromXml( groupElem.attribute( QStringLiteral( "checked" ) ) ) != Qt::Unchecked );
214  groupNode->setExpanded( groupElem.attribute( QStringLiteral( "open" ) ) == QLatin1String( "true" ) );
215 
216  if ( groupElem.attribute( QStringLiteral( "embedded" ) ) == QLatin1String( "1" ) )
217  {
218  groupNode->setCustomProperty( QStringLiteral( "embedded" ), 1 );
219  groupNode->setCustomProperty( QStringLiteral( "embedded_project" ), groupElem.attribute( QStringLiteral( "project" ) ) );
220  }
221 
222  for ( int i = 0; i < groupChildren.size(); ++i )
223  {
224  QDomElement currentChildElem = groupChildren.at( i ).toElement();
225  if ( currentChildElem.tagName() == QLatin1String( "legendlayer" ) )
226  {
227  _readOldLegendLayer( currentChildElem, groupNode );
228  }
229  else if ( currentChildElem.tagName() == QLatin1String( "legendgroup" ) )
230  {
231  _readOldLegendGroup( currentChildElem, groupNode );
232  }
233  }
234 
235  parent->addChildNode( groupNode );
236 }
237 
238 static void _readOldLegendLayer( const QDomElement &layerElem, QgsLayerTreeGroup *parent )
239 {
240  QDomElement layerFileElem = layerElem.firstChildElement( QStringLiteral( "filegroup" ) ).firstChildElement( QStringLiteral( "legendlayerfile" ) );
241  QString layerId = layerFileElem.attribute( QStringLiteral( "layerid" ) );
242  QgsLayerTreeLayer *layerNode = new QgsLayerTreeLayer( layerId, layerElem.attribute( QStringLiteral( "name" ) ) );
243 
244  layerNode->setItemVisibilityChecked( QgsLayerTreeUtils::checkStateFromXml( layerElem.attribute( QStringLiteral( "checked" ) ) ) != Qt::Unchecked );
245  layerNode->setExpanded( layerElem.attribute( QStringLiteral( "open" ) ) == QLatin1String( "true" ) );
246 
247  if ( layerFileElem.attribute( QStringLiteral( "isInOverview" ) ) == QLatin1String( "1" ) )
248  layerNode->setCustomProperty( QStringLiteral( "overview" ), 1 );
249 
250  if ( layerElem.attribute( QStringLiteral( "embedded" ) ) == QLatin1String( "1" ) )
251  layerNode->setCustomProperty( QStringLiteral( "embedded" ), 1 );
252 
253  if ( layerElem.attribute( QStringLiteral( "showFeatureCount" ) ) == QLatin1String( "1" ) )
254  layerNode->setCustomProperty( QStringLiteral( "showFeatureCount" ), 1 );
255 
256  // drawing order is handled by readOldLegendLayerOrder()
257 
258  parent->addChildNode( layerNode );
259 }
260 
261 
262 
263 bool QgsLayerTreeUtils::layersEditable( const QList<QgsLayerTreeLayer *> &layerNodes )
264 {
265  Q_FOREACH ( QgsLayerTreeLayer *layerNode, layerNodes )
266  {
267  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerNode->layer() );
268  if ( !vl )
269  continue;
270 
271  if ( vl->isEditable() )
272  return true;
273  }
274  return false;
275 }
276 
277 bool QgsLayerTreeUtils::layersModified( const QList<QgsLayerTreeLayer *> &layerNodes )
278 {
279  Q_FOREACH ( QgsLayerTreeLayer *layerNode, layerNodes )
280  {
281  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerNode->layer() );
282  if ( !vl )
283  continue;
284 
285  if ( vl->isEditable() && vl->isModified() )
286  return true;
287  }
288  return false;
289 }
290 
292 {
293  QList<QgsLayerTreeNode *> nodesToRemove;
294  Q_FOREACH ( QgsLayerTreeNode *node, group->children() )
295  {
296  if ( QgsLayerTree::isGroup( node ) )
298  else if ( QgsLayerTree::isLayer( node ) )
299  {
300  if ( !QgsLayerTree::toLayer( node )->layer() )
301  nodesToRemove << node;
302  }
303  }
304 
305  Q_FOREACH ( QgsLayerTreeNode *node, nodesToRemove )
306  group->removeChildNode( node );
307 }
308 
310 {
311  const QDomNodeList mlNodeList( doc->documentElement()
312  .firstChildElement( QStringLiteral( "projectlayers" ) )
313  .elementsByTagName( QStringLiteral( "maplayer" ) ) );
314 
315  std::function<void ( QgsLayerTreeNode * )> _store = [ & ]( QgsLayerTreeNode * node )
316  {
317  if ( QgsLayerTree::isLayer( node ) )
318  {
319  QgsMapLayer *l( QgsLayerTree::toLayer( node )->layer() );
320  if ( l )
321  {
322  for ( int i = 0; i < mlNodeList.count(); i++ )
323  {
324  QDomNode mlNode( mlNodeList.at( i ) );
325  QString id( mlNode.firstChildElement( QStringLiteral( "id" ) ).firstChild().nodeValue() );
326  if ( id == l->id() )
327  {
328  QDomImplementation DomImplementation;
329  QDomDocumentType documentType = DomImplementation.createDocumentType( QStringLiteral( "qgis" ), QStringLiteral( "http://mrcc.com/qgis.dtd" ), QStringLiteral( "SYSTEM" ) );
330  QDomDocument document( documentType );
331  QDomElement element = mlNode.toElement();
332  document.appendChild( element );
333  QString str;
334  QTextStream stream( &str );
335  document.save( stream, 4 /*indent*/ );
336  l->setOriginalXmlProperties( str );
337  }
338  }
339  }
340  }
341  else if ( QgsLayerTree::isGroup( node ) )
342  {
343  const QList<QgsLayerTreeNode *> constChildren( node->children( ) );
344  for ( const auto &childNode : constChildren )
345  {
346  _store( childNode );
347  }
348  }
349  };
350 
351  for ( QgsLayerTreeNode *node : group->children() )
352  {
353  _store( node );
354  }
355 }
356 
358 {
359  QStringList list;
360 
361  if ( QgsLayerTree::isGroup( node ) )
362  {
363  Q_FOREACH ( QgsLayerTreeNode *child, QgsLayerTree::toGroup( node )->children() )
364  {
365  list << invisibleLayerList( child );
366  }
367  }
368  else if ( QgsLayerTree::isLayer( node ) )
369  {
370  QgsLayerTreeLayer *layer = QgsLayerTree::toLayer( node );
371 
372  if ( !layer->isVisible() )
373  list << layer->layerId();
374  }
375 
376  return list;
377 }
378 
380 {
381  Q_FOREACH ( QgsLayerTreeNode *child, group->children() )
382  {
383  if ( QgsLayerTree::isGroup( child ) )
384  {
385  if ( child->customProperty( QStringLiteral( "embedded" ) ).toInt() )
386  {
387  child->setCustomProperty( QStringLiteral( "embedded-invisible-layers" ), invisibleLayerList( child ) );
389  }
390  else
391  {
393  }
394  }
395  }
396 }
397 
398 
400 {
401  Q_FOREACH ( QgsLayerTreeNode *node, group->children() )
402  {
403  if ( !node->customProperty( QStringLiteral( "embedded_project" ) ).toString().isEmpty() )
404  {
405  // may change from absolute path to relative path
406  QString newPath = project->writePath( node->customProperty( QStringLiteral( "embedded_project" ) ).toString() );
407  node->setCustomProperty( QStringLiteral( "embedded_project" ), newPath );
408  }
409 
410  if ( QgsLayerTree::isGroup( node ) )
411  {
413  }
414  }
415 }
416 
417 void QgsLayerTreeUtils::setLegendFilterByExpression( QgsLayerTreeLayer &layer, const QString &expr, bool enabled )
418 {
419  layer.setCustomProperty( QStringLiteral( "legend/expressionFilter" ), expr );
420  layer.setCustomProperty( QStringLiteral( "legend/expressionFilterEnabled" ), enabled );
421 }
422 
424 {
425  if ( enabled )
426  *enabled = layer.customProperty( QStringLiteral( "legend/expressionFilterEnabled" ), "" ).toBool();
427  return layer.customProperty( QStringLiteral( "legend/expressionFilter" ), "" ).toString();
428 }
429 
431 {
432  Q_FOREACH ( QgsLayerTreeLayer *l, group.findLayers() )
433  {
434  bool exprEnabled;
435  QString expr = legendFilterByExpression( *l, &exprEnabled );
436  if ( exprEnabled && !expr.isEmpty() )
437  {
438  return true;
439  }
440  }
441  return false;
442 }
443 
445 {
446  // get the index of the reflayer
447  QgsLayerTreeLayer *inTree = group->findLayer( refLayer->id() );
448  if ( !inTree )
449  return nullptr;
450 
451  int idx = 0;
452  Q_FOREACH ( QgsLayerTreeNode *vl, inTree->parent()->children() )
453  {
454  if ( vl->nodeType() == QgsLayerTreeNode::NodeLayer && static_cast<QgsLayerTreeLayer *>( vl )->layer() == refLayer )
455  {
456  break;
457  }
458  idx++;
459  }
460  // insert the new layer
461  QgsLayerTreeGroup *parent = static_cast<QgsLayerTreeGroup *>( inTree->parent() ) ? static_cast<QgsLayerTreeGroup *>( inTree->parent() ) : group;
462  return parent->insertLayer( idx, layerToInsert );
463 }
464 
465 static void _collectMapLayers( const QList<QgsLayerTreeNode *> &nodes, QSet<QgsMapLayer *> &layersSet )
466 {
467  for ( QgsLayerTreeNode *node : nodes )
468  {
469  if ( QgsLayerTree::isLayer( node ) )
470  {
471  QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
472  if ( nodeLayer->layer() )
473  layersSet << nodeLayer->layer();
474  }
475  else if ( QgsLayerTree::isGroup( node ) )
476  {
477  _collectMapLayers( QgsLayerTree::toGroup( node )->children(), layersSet );
478  }
479  }
480 }
481 
482 QSet<QgsMapLayer *> QgsLayerTreeUtils::collectMapLayersRecursive( const QList<QgsLayerTreeNode *> &nodes )
483 {
484  QSet<QgsMapLayer *> layersSet;
485  _collectMapLayers( nodes, layersSet );
486  return layersSet;
487 }
488 
490 {
491  if ( QgsLayerTree::isLayer( tree ) )
492  {
493  if ( QgsLayerTree::toLayer( tree )->layer() == layer )
494  return 1;
495  return 0;
496  }
497 
498  int cnt = 0;
499  const QList<QgsLayerTreeNode *> children = tree->children();
500  for ( QgsLayerTreeNode *child : children )
501  cnt += countMapLayerInTree( child, layer );
502  return cnt;
503 }
static bool readOldLegendLayerOrder(const QDomElement &legendElem, bool &hasCustomOrder, QStringList &order)
Try to load custom layer order from.
static int countMapLayerInTree(QgsLayerTreeNode *tree, QgsMapLayer *layer)
Returns how many occurrences of a map layer are there in a layer tree.
Layer tree group node serves as a container for layers and further groups.
static bool layersEditable(const QList< QgsLayerTreeLayer *> &layerNodes)
Returns true if any of the layers is editable.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Definition: qgslayertree.h:75
Base class for all map layer types.
Definition: qgsmaplayer.h:64
static void removeInvalidLayers(QgsLayerTreeGroup *group)
Removes layer nodes that refer to invalid layers.
static QString checkStateToXml(Qt::CheckState state)
Convert Qt::CheckState to QString.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
Definition: qgslayertree.h:43
bool itemVisibilityChecked() const
Returns whether a node is checked (independently of its ancestors or children)
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
void removeAllChildren()
Remove all child nodes.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
Definition: qgslayertree.h:64
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
static bool readOldLegend(QgsLayerTreeGroup *root, const QDomElement &legendElem)
Try to load layer tree from.
static bool layersModified(const QList< QgsLayerTreeLayer *> &layerNodes)
Returns true if any of the layers is modified.
void removeChildNode(QgsLayerTreeNode *node)
Remove a child node from this group.
bool isVisible() const
Returns whether a node is really visible (ie checked and all its ancestors checked as well) ...
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
QString layerId() const
Returns the ID for the map layer associated with this node.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
QString name() const override
Returns the layer&#39;s name.
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsProject.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
void setOriginalXmlProperties(const QString &originalXmlProperties)
Sets the original XML properties for the layer to originalXmlProperties.
static QDomElement writeOldLegend(QDomDocument &doc, QgsLayerTreeGroup *root, bool hasCustomOrder, const QList< QgsMapLayer *> &order)
Returns.
QgsLayerTreeLayer * insertLayer(int index, QgsMapLayer *layer)
Insert a new layer node for given map layer at specified position.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is a null pointer, the node is a root 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...
static void replaceChildrenOfEmbeddedGroups(QgsLayerTreeGroup *group)
Remove subtree of embedded groups and replaces it with a custom property embedded-visible-layers.
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 Qt::CheckState checkStateFromXml(const QString &txt)
Convert QString to Qt::CheckState.
Reads and writes project states.
Definition: qgsproject.h:89
static bool hasLegendFilterExpression(const QgsLayerTreeGroup &group)
Test if one of the layers in a group has an expression filter.
NodeType nodeType() const
Find out about type of the node. It is usually shorter to use convenience functions from QgsLayerTree...
static QSet< QgsMapLayer * > collectMapLayersRecursive(const QList< QgsLayerTreeNode *> &nodes)
Returns map layers from the given list of layer tree nodes.
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
Leaf node pointing to a layer.
static QgsLayerTreeLayer * insertLayerBelow(QgsLayerTreeGroup *group, const QgsMapLayer *refLayer, QgsMapLayer *layerToInsert)
Insert a QgsMapLayer just below another one.
static void setLegendFilterByExpression(QgsLayerTreeLayer &layer, const QString &expr, bool enabled=true)
Sets the expression filter of a legend layer.
static void storeOriginalLayersProperties(QgsLayerTreeGroup *group, const QDomDocument *doc)
Stores in a layer&#39;s originalXmlProperties the layer properties information.
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
void addChildNode(QgsLayerTreeNode *node)
Append an existing node.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
QString name() const override
Returns the group&#39;s name.
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
Represents a vector layer which manages a vector based data sets.
static QStringList invisibleLayerList(QgsLayerTreeNode *node)
Gets invisible layers.
static QString legendFilterByExpression(const QgsLayerTreeLayer &layer, bool *enabled=nullptr)
Returns the expression filter of a legend layer.
static void updateEmbeddedGroupsProjectPath(QgsLayerTreeGroup *group, const QgsProject *project)
Updates an embedded group from a project.
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.