QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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  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  const QDomNodeList mlNodeList( doc->documentElement()
318  .firstChildElement( QStringLiteral( "projectlayers" ) )
319  .elementsByTagName( QStringLiteral( "maplayer" ) ) );
320 
321  std::function<void ( QgsLayerTreeNode * )> _store = [ & ]( QgsLayerTreeNode * node )
322  {
323  if ( QgsLayerTree::isLayer( node ) )
324  {
325  QgsMapLayer *l( QgsLayerTree::toLayer( node )->layer() );
326  if ( l )
327  {
328  for ( int i = 0; i < mlNodeList.count(); i++ )
329  {
330  QDomNode mlNode( mlNodeList.at( i ) );
331  QString id( mlNode.firstChildElement( QStringLiteral( "id" ) ).firstChild().nodeValue() );
332  if ( id == l->id() )
333  {
334  QDomImplementation DomImplementation;
335  QDomDocumentType documentType = DomImplementation.createDocumentType( QStringLiteral( "qgis" ), QStringLiteral( "http://mrcc.com/qgis.dtd" ), QStringLiteral( "SYSTEM" ) );
336  QDomDocument document( documentType );
337  QDomElement element = mlNode.toElement();
338  document.appendChild( element );
339  QString str;
340  QTextStream stream( &str );
341  document.save( stream, 4 /*indent*/ );
342  l->setOriginalXmlProperties( str );
343  }
344  }
345  }
346  }
347  else if ( QgsLayerTree::isGroup( node ) )
348  {
349  const QList<QgsLayerTreeNode *> constChildren( node->children( ) );
350  for ( const auto &childNode : constChildren )
351  {
352  _store( childNode );
353  }
354  }
355  };
356 
357  for ( QgsLayerTreeNode *node : group->children() )
358  {
359  _store( node );
360  }
361 }
362 
364 {
365  QStringList list;
366 
367  if ( QgsLayerTree::isGroup( node ) )
368  {
369  const auto constChildren = QgsLayerTree::toGroup( node )->children();
370  for ( QgsLayerTreeNode *child : constChildren )
371  {
372  if ( child->itemVisibilityChecked() == Qt::Unchecked )
373  {
374  list << invisibleLayerList( child );
375  }
376  }
377  }
378  else if ( QgsLayerTree::isLayer( node ) )
379  {
380  QgsLayerTreeLayer *layer = QgsLayerTree::toLayer( node );
381 
382  if ( !layer->isVisible() )
383  list << layer->layerId();
384  }
385 
386  return list;
387 }
388 
390 {
391  const auto constChildren = group->children();
392  for ( QgsLayerTreeNode *child : constChildren )
393  {
394  if ( QgsLayerTree::isGroup( child ) )
395  {
396  if ( child->customProperty( QStringLiteral( "embedded" ) ).toInt() )
397  {
398  child->setCustomProperty( QStringLiteral( "embedded-invisible-layers" ), invisibleLayerList( child ) );
400  }
401  else
402  {
404  }
405  }
406  }
407 }
408 
409 
411 {
412  const auto constChildren = group->children();
413  for ( QgsLayerTreeNode *node : constChildren )
414  {
415  if ( !node->customProperty( QStringLiteral( "embedded_project" ) ).toString().isEmpty() )
416  {
417  // may change from absolute path to relative path
418  QString newPath = project->writePath( node->customProperty( QStringLiteral( "embedded_project" ) ).toString() );
419  node->setCustomProperty( QStringLiteral( "embedded_project" ), newPath );
420  }
421 
422  if ( QgsLayerTree::isGroup( node ) )
423  {
425  }
426  }
427 }
428 
429 void QgsLayerTreeUtils::setLegendFilterByExpression( QgsLayerTreeLayer &layer, const QString &expr, bool enabled )
430 {
431  layer.setCustomProperty( QStringLiteral( "legend/expressionFilter" ), expr );
432  layer.setCustomProperty( QStringLiteral( "legend/expressionFilterEnabled" ), enabled && !expr.isEmpty() );
433 }
434 
436 {
437  const QString expression = layer.customProperty( QStringLiteral( "legend/expressionFilter" ), QString() ).toString();
438  if ( enabled )
439  *enabled = !expression.isEmpty() && layer.customProperty( QStringLiteral( "legend/expressionFilterEnabled" ), QString() ).toBool();
440  return expression;
441 }
442 
444 {
445  const auto constFindLayers = group.findLayers();
446  for ( QgsLayerTreeLayer *l : constFindLayers )
447  {
448  bool exprEnabled;
449  QString expr = legendFilterByExpression( *l, &exprEnabled );
450  if ( exprEnabled && !expr.isEmpty() )
451  {
452  return true;
453  }
454  }
455  return false;
456 }
457 
459 {
460  // get the index of the reflayer
461  QgsLayerTreeLayer *inTree = group->findLayer( refLayer->id() );
462  if ( !inTree )
463  return nullptr;
464 
465  int idx = 0;
466  const auto constChildren = inTree->parent()->children();
467  for ( QgsLayerTreeNode *vl : constChildren )
468  {
469  if ( vl->nodeType() == QgsLayerTreeNode::NodeLayer && static_cast<QgsLayerTreeLayer *>( vl )->layer() == refLayer )
470  {
471  break;
472  }
473  idx++;
474  }
475  // insert the new layer
476  QgsLayerTreeGroup *parent = static_cast<QgsLayerTreeGroup *>( inTree->parent() ) ? static_cast<QgsLayerTreeGroup *>( inTree->parent() ) : group;
477  return parent->insertLayer( idx, layerToInsert );
478 }
479 
480 static void _collectMapLayers( const QList<QgsLayerTreeNode *> &nodes, QSet<QgsMapLayer *> &layersSet )
481 {
482  for ( QgsLayerTreeNode *node : nodes )
483  {
484  if ( QgsLayerTree::isLayer( node ) )
485  {
486  QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
487  if ( nodeLayer->layer() )
488  layersSet << nodeLayer->layer();
489  }
490  else if ( QgsLayerTree::isGroup( node ) )
491  {
492  _collectMapLayers( QgsLayerTree::toGroup( node )->children(), layersSet );
493  }
494  }
495 }
496 
497 QSet<QgsMapLayer *> QgsLayerTreeUtils::collectMapLayersRecursive( const QList<QgsLayerTreeNode *> &nodes )
498 {
499  QSet<QgsMapLayer *> layersSet;
500  _collectMapLayers( nodes, layersSet );
501  return layersSet;
502 }
503 
505 {
506  if ( QgsLayerTree::isLayer( tree ) )
507  {
508  if ( QgsLayerTree::toLayer( tree )->layer() == layer )
509  return 1;
510  return 0;
511  }
512 
513  int cnt = 0;
514  const QList<QgsLayerTreeNode *> children = tree->children();
515  for ( QgsLayerTreeNode *child : children )
516  cnt += countMapLayerInTree( child, layer );
517  return cnt;
518 }
519 
521 {
522  // if the group is embedded go to the first non-embedded group, at worst the top level item
523  while ( group->customProperty( property ).toInt() )
524  {
525  if ( !group->parent() )
526  break;
527 
528  if ( QgsLayerTree::isGroup( group->parent() ) )
529  group = QgsLayerTree::toGroup( group->parent() );
530  else
531  Q_ASSERT( false );
532  }
533  return group;
534 }
QgsLayerTreeUtils::checkStateToXml
static QString checkStateToXml(Qt::CheckState state)
Convert Qt::CheckState to QString.
Definition: qgslayertreeutils.cpp:183
QgsLayerTreeGroup::findLayer
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
Definition: qgslayertreegroup.cpp:195
QgsLayerTreeGroup::findLayers
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
Definition: qgslayertreegroup.cpp:223
QgsLayerTreeUtils::readOldLegend
static bool readOldLegend(QgsLayerTreeGroup *root, const QDomElement &legendElem)
Try to load layer tree from.
Definition: qgslayertreeutils.cpp:28
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:172
QgsLayerTreeGroup::removeChildNode
void removeChildNode(QgsLayerTreeNode *node)
Remove a child node from this group.
Definition: qgslayertreegroup.cpp:132
QgsLayerTreeNode::setItemVisibilityChecked
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
Definition: qgslayertreenode.cpp:78
QgsLayerTreeGroup::removeAllChildren
void removeAllChildren()
Remove all child nodes.
Definition: qgslayertreegroup.cpp:190
QgsLayerTreeLayer::layerId
QString layerId() const
Returns the ID for the map layer associated with this node.
Definition: qgslayertreelayer.h:63
QgsLayerTreeNode::NodeLayer
@ NodeLayer
Leaf node pointing to a layer.
Definition: qgslayertreenode.h:102
QgsLayerTree::toLayer
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Definition: qgslayertree.h:75
QgsLayerTreeLayer::name
QString name() const override
Returns the layer's name.
Definition: qgslayertreelayer.cpp:81
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsVectorLayer::isEditable
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
Definition: qgsvectorlayer.cpp:3594
QgsLayerTree::toGroup
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
Definition: qgslayertree.h:64
QgsProject
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:95
QgsLayerTreeUtils::hasLegendFilterExpression
static bool hasLegendFilterExpression(const QgsLayerTreeGroup &group)
Test if one of the layers in a group has an expression filter.
Definition: qgslayertreeutils.cpp:443
QgsLayerTreeUtils::layersModified
static bool layersModified(const QList< QgsLayerTreeLayer * > &layerNodes)
Returns true if any of the layers is modified.
Definition: qgslayertreeutils.cpp:280
QgsMapLayer::setOriginalXmlProperties
void setOriginalXmlProperties(const QString &originalXmlProperties)
Sets the original XML properties for the layer to originalXmlProperties.
Definition: qgsmaplayer.cpp:1873
QgsLayerTreeLayer
Layer tree node points to a map layer.
Definition: qgslayertreelayer.h:44
QgsLayerTreeGroup
Layer tree group node serves as a container for layers and further groups.
Definition: qgslayertreegroup.h:35
QgsLayerTreeUtils::collectMapLayersRecursive
static QSet< QgsMapLayer * > collectMapLayersRecursive(const QList< QgsLayerTreeNode * > &nodes)
Returns map layers from the given list of layer tree nodes.
Definition: qgslayertreeutils.cpp:497
QgsLayerTreeUtils::insertLayerBelow
static QgsLayerTreeLayer * insertLayerBelow(QgsLayerTreeGroup *group, const QgsMapLayer *refLayer, QgsMapLayer *layerToInsert)
Insert a QgsMapLayer just below another one.
Definition: qgslayertreeutils.cpp:458
QgsLayerTreeUtils::layersEditable
static bool layersEditable(const QList< QgsLayerTreeLayer * > &layerNodes)
Returns true if any of the layers is editable.
Definition: qgslayertreeutils.cpp:265
QgsMapLayer::id
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Definition: qgsmaplayer.cpp:148
QgsLayerTreeUtils::checkStateFromXml
static Qt::CheckState checkStateFromXml(const QString &txt)
Convert QString to Qt::CheckState.
Definition: qgslayertreeutils.cpp:197
QgsLayerTreeLayer::layer
QgsMapLayer * layer() const
Returns the map layer associated with this node.
Definition: qgslayertreelayer.h:74
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:72
QgsLayerTreeNode::isExpanded
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
Definition: qgslayertreenode.cpp:104
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:389
QgsLayerTreeUtils::setLegendFilterByExpression
static void setLegendFilterByExpression(QgsLayerTreeLayer &layer, const QString &expr, bool enabled=true)
Sets the expression filter of a legend layer.
Definition: qgslayertreeutils.cpp:429
QgsLayerTree::isLayer
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
Definition: qgslayertree.h:53
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:520
QgsLayerTreeUtils::storeOriginalLayersProperties
static void storeOriginalLayersProperties(QgsLayerTreeGroup *group, const QDomDocument *doc)
Stores in a layer's originalXmlProperties the layer properties information.
Definition: qgslayertreeutils.cpp:315
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:180
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsProject::writePath
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
Definition: qgsproject.cpp:2700
QgsLayerTreeGroup::addChildNode
void addChildNode(QgsLayerTreeNode *node)
Append an existing node.
Definition: qgslayertreegroup.cpp:127
QgsLayerTreeNode::itemVisibilityChecked
bool itemVisibilityChecked() const
Returns whether a node is checked (independently of its ancestors or children)
Definition: qgslayertreenode.h:171
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:189
QgsMapLayer
Base class for all map layer types.
Definition: qgsmaplayer.h:83
QgsLayerTreeNode::children
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
Definition: qgslayertreenode.h:112
QgsLayerTreeGroup::name
QString name() const override
Returns the group's name.
Definition: qgslayertreegroup.cpp:43
qgslayertreeutils.h
QgsLayerTreeUtils::updateEmbeddedGroupsProjectPath
static void updateEmbeddedGroupsProjectPath(QgsLayerTreeGroup *group, const QgsProject *project)
Updates an embedded group from a project.
Definition: qgslayertreeutils.cpp:410
QgsVectorLayer::isModified
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
Definition: qgsvectorlayer.cpp:3621
QgsLayerTreeNode::parent
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
Definition: qgslayertreenode.h:110
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:504
QgsLayerTreeUtils::invisibleLayerList
static QStringList invisibleLayerList(QgsLayerTreeNode *node)
Gets invisible layers.
Definition: qgslayertreeutils.cpp:363
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:98
QgsLayerTreeUtils::legendFilterByExpression
static QString legendFilterByExpression(const QgsLayerTreeLayer &layer, bool *enabled=nullptr)
Returns the expression filter of a legend layer.
Definition: qgslayertreeutils.cpp:435
QgsLayerTreeNode::setExpanded
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
Definition: qgslayertreenode.cpp:170
QgsLayerTree::isGroup
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
Definition: qgslayertree.h:43
qgsproject.h
QgsLayerTreeUtils::readOldLegendLayerOrder
static bool readOldLegendLayerOrder(const QDomElement &legendElem, bool &hasCustomOrder, QStringList &order)
Try to load custom layer order from.
Definition: qgslayertreeutils.cpp:80
QgsLayerTreeUtils::removeInvalidLayers
static void removeInvalidLayers(QgsLayerTreeGroup *group)
Removes layer nodes that refer to invalid layers.
Definition: qgslayertreeutils.cpp:295