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