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