QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgslayertreemodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayertreemodel.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 <QMimeData>
17 #include <QTextStream>
18 
19 #include "qgslayertreemodel.h"
20 
21 #include "qgsapplication.h"
22 #include "qgslayertree.h"
23 #include "qgslayertreeutils.h"
25 #include "qgsproject.h"
26 #include "qgsmaphittest.h"
27 #include "qgsmaplayer.h"
28 #include "qgsmaplayerlegend.h"
30 #include "qgsmeshlayer.h"
31 #include "qgspluginlayer.h"
32 #include "qgsrasterlayer.h"
33 #include "qgsrenderer.h"
34 #include "qgssymbollayerutils.h"
35 #include "qgsvectorlayer.h"
36 #include "qgslayerdefinition.h"
37 #include "qgsiconutils.h"
38 #include "qgsmimedatautils.h"
40 
41 #include <QPalette>
42 
44  : QAbstractItemModel( parent )
45  , mRootNode( rootNode )
46  , mFlags( ShowLegend | AllowLegendChangeState | DeferredLegendInvalidation )
47  , mAutoCollapseLegendNodesCount( -1 )
48  , mLegendFilterByScale( 0 )
49  , mLegendFilterUsesExtent( false )
50  , mLegendMapViewMupp( 0 )
51  , mLegendMapViewDpi( 0 )
52  , mLegendMapViewScale( 0 )
53 {
55 
56  mFontLayer.setBold( true );
57 
59  mDeferLegendInvalidationTimer.setSingleShot( true );
60 }
61 
63 {
64  legendCleanup();
65 }
66 
67 QgsLayerTreeNode *QgsLayerTreeModel::index2node( const QModelIndex &index ) const
68 {
69  if ( !index.isValid() )
70  return mRootNode;
71 
72  QObject *obj = reinterpret_cast<QObject *>( index.internalPointer() );
73  return qobject_cast<QgsLayerTreeNode *>( obj );
74 }
75 
76 
77 int QgsLayerTreeModel::rowCount( const QModelIndex &parent ) const
78 {
80  return legendNodeRowCount( nodeLegend );
81 
83  if ( !n )
84  return 0;
85 
86  if ( QgsLayerTree::isLayer( n ) )
87  {
88  if ( !testFlag( ShowLegend ) )
89  return 0;
90 
92  }
93 
94  return n->children().count();
95 }
96 
97 int QgsLayerTreeModel::columnCount( const QModelIndex &parent ) const
98 {
99  Q_UNUSED( parent )
100  return 1;
101 }
102 
103 QModelIndex QgsLayerTreeModel::index( int row, int column, const QModelIndex &parent ) const
104 {
105  if ( column < 0 || column >= columnCount( parent ) ||
106  row < 0 || row >= rowCount( parent ) )
107  return QModelIndex();
108 
109  if ( QgsLayerTreeModelLegendNode *nodeLegend = index2legendNode( parent ) )
110  return legendNodeIndex( row, column, nodeLegend );
111 
113  if ( !n )
114  return QModelIndex(); // have no children
115 
116  if ( testFlag( ShowLegend ) && QgsLayerTree::isLayer( n ) )
117  {
118  return legendRootIndex( row, column, QgsLayerTree::toLayer( n ) );
119  }
120 
121  return createIndex( row, column, static_cast<QObject *>( n->children().at( row ) ) );
122 }
123 
124 
125 QModelIndex QgsLayerTreeModel::parent( const QModelIndex &child ) const
126 {
127  if ( !child.isValid() )
128  return QModelIndex();
129 
130  if ( QgsLayerTreeNode *n = index2node( child ) )
131  {
132  return indexOfParentLayerTreeNode( n->parent() ); // must not be null
133  }
135  {
136  return legendParent( legendNode );
137  }
138  else
139  {
140  Q_ASSERT( false ); // no other node types!
141  return QModelIndex();
142  }
143 
144 }
145 
146 
148 {
149  Q_ASSERT( parentNode );
150 
151  QgsLayerTreeNode *grandParentNode = parentNode->parent();
152  if ( !grandParentNode )
153  return QModelIndex(); // root node -> invalid index
154 
155  int row = grandParentNode->children().indexOf( parentNode );
156  Q_ASSERT( row >= 0 );
157 
158  return createIndex( row, 0, static_cast<QObject *>( parentNode ) );
159 }
160 
161 
162 QVariant QgsLayerTreeModel::data( const QModelIndex &index, int role ) const
163 {
164  if ( !index.isValid() || index.column() > 1 )
165  return QVariant();
166 
168  return legendNodeData( sym, role );
169 
170  QgsLayerTreeNode *node = index2node( index );
171  if ( role == Qt::DisplayRole || role == Qt::EditRole )
172  {
173  if ( QgsLayerTree::isGroup( node ) )
174  return QgsLayerTree::toGroup( node )->name();
175 
176  if ( QgsLayerTree::isLayer( node ) )
177  {
178  QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
179  QString name = nodeLayer->name();
180  if ( nodeLayer->customProperty( QStringLiteral( "showFeatureCount" ), 0 ).toInt() && role == Qt::DisplayRole )
181  {
182  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( nodeLayer->layer() );
183  if ( vlayer && vlayer->featureCount() >= 0 )
184  name += QStringLiteral( " [%1]" ).arg( vlayer->featureCount() );
185  }
186  return name;
187  }
188  }
189  else if ( role == Qt::DecorationRole && index.column() == 0 )
190  {
191  if ( QgsLayerTree::isGroup( node ) )
192  return iconGroup();
193 
194  if ( QgsLayerTree::isLayer( node ) )
195  {
196  QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
197 
198  QgsMapLayer *layer = nodeLayer->layer();
199  if ( !layer )
200  return QVariant();
201 
202  // icons possibly overriding default icon
203  QIcon icon = QgsIconUtils::iconForLayer( layer );
204 
205  // if there's just on legend entry that should be embedded in layer - do that!
206  if ( testFlag( ShowLegend ) && legendEmbeddedInParent( nodeLayer ) )
207  {
208  icon = legendIconEmbeddedInParent( nodeLayer );
209  }
210 
211  if ( !icon.isNull() && layer->isEditable() && !( layer->properties() & Qgis::MapLayerProperty::UsersCannotToggleEditing ) && testFlag( UseTextFormatting ) )
212  {
213  const int iconSize = scaleIconSize( 16 );
214  QPixmap pixmap( icon.pixmap( iconSize, iconSize ) );
215 
216  QPainter painter( &pixmap );
217  painter.drawPixmap( 0, 0, iconSize, iconSize, QgsApplication::getThemePixmap( layer->isModified() ? QStringLiteral( "/mIconEditableEdits.svg" ) : QStringLiteral( "/mActionToggleEditing.svg" ) ) );
218  painter.end();
219 
220  icon = QIcon( pixmap );
221  }
222 
223  return icon;
224  }
225  }
226  else if ( role == Qt::CheckStateRole )
227  {
229  return QVariant();
230 
231  if ( QgsLayerTree::isLayer( node ) )
232  {
233  QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
234 
235  if ( nodeLayer->layer() && !nodeLayer->layer()->isSpatial() )
236  return QVariant(); // do not show checkbox for non-spatial tables
237 
238  return nodeLayer->itemVisibilityChecked() ? Qt::Checked : Qt::Unchecked;
239  }
240  else if ( QgsLayerTree::isGroup( node ) )
241  {
242  QgsLayerTreeGroup *nodeGroup = QgsLayerTree::toGroup( node );
243  return nodeGroup->itemVisibilityChecked() ? Qt::Checked : Qt::Unchecked;
244  }
245  }
246  else if ( role == Qt::FontRole && testFlag( UseTextFormatting ) )
247  {
248  QFont f( QgsLayerTree::isLayer( node ) ? mFontLayer : ( QgsLayerTree::isGroup( node ) ? mFontGroup : QFont() ) );
249  if ( index == mCurrentIndex )
250  f.setUnderline( true );
251  if ( QgsLayerTree::isLayer( node ) )
252  {
253  const QgsMapLayer *layer = QgsLayerTree::toLayer( node )->layer();
254  if ( ( !node->isVisible() && ( !layer || layer->isSpatial() ) ) || ( layer && !layer->isInScaleRange( mLegendMapViewScale ) ) )
255  {
256  f.setItalic( !f.italic() );
257  }
258  }
259  return f;
260  }
261  else if ( role == Qt::ForegroundRole && testFlag( UseTextFormatting ) )
262  {
263  QBrush brush( qApp->palette().color( QPalette::Text ), Qt::SolidPattern );
264  if ( QgsLayerTree::isLayer( node ) )
265  {
266  const QgsMapLayer *layer = QgsLayerTree::toLayer( node )->layer();
267  if ( ( !node->isVisible() && ( !layer || layer->isSpatial() ) ) || ( layer && !layer->isInScaleRange( mLegendMapViewScale ) ) )
268  {
269  QColor fadedTextColor = brush.color();
270  fadedTextColor.setAlpha( 128 );
271  brush.setColor( fadedTextColor );
272  }
273  }
274  return brush;
275  }
276  else if ( role == Qt::ToolTipRole )
277  {
278  if ( QgsLayerTree::isLayer( node ) )
279  {
280  if ( QgsMapLayer *layer = QgsLayerTree::toLayer( node )->layer() )
281  {
282  QString title =
283  !layer->title().isEmpty() ? layer->title() :
284  !layer->shortName().isEmpty() ? layer->shortName() :
285  layer->name();
286 
287  title = "<b>" + title.toHtmlEscaped() + "</b>";
288 
289  if ( layer->isSpatial() && layer->crs().isValid() )
290  {
291  if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ) )
292  title += tr( " (%1 - %2)" ).arg( QgsWkbTypes::displayString( vl->wkbType() ), layer->crs().authid() ).toHtmlEscaped();
293  else
294  title += tr( " (%1)" ).arg( layer->crs().authid() ).toHtmlEscaped();
295  }
296 
297  QStringList parts;
298  parts << title;
299 
300  if ( !layer->abstract().isEmpty() )
301  {
302  parts << QString();
303  const QStringList abstractLines = layer->abstract().split( '\n' );
304  for ( const auto &l : abstractLines )
305  {
306  parts << l.toHtmlEscaped();
307  }
308  parts << QString();
309  }
310 
311  QString source( layer->publicSource() );
312  if ( source.size() > 1024 )
313  {
314  source = source.left( 1023 ) + QString( QChar( 0x2026 ) );
315  }
316 
317  parts << "<i>" + source.toHtmlEscaped() + "</i>";
318 
319  return parts.join( QLatin1String( "<br/>" ) );
320  }
321  }
322  }
323 
324  return QVariant();
325 }
326 
327 
328 Qt::ItemFlags QgsLayerTreeModel::flags( const QModelIndex &index ) const
329 {
330  if ( !index.isValid() )
331  {
332  Qt::ItemFlags rootFlags = Qt::ItemFlags();
333  if ( testFlag( AllowNodeReorder ) )
334  rootFlags |= Qt::ItemIsDropEnabled;
335  return rootFlags;
336  }
337 
339  return legendNodeFlags( symn );
340 
341  Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
342 
343  if ( testFlag( AllowNodeRename ) )
344  f |= Qt::ItemIsEditable;
345 
346  QgsLayerTreeNode *node = index2node( index );
347  bool isEmbedded = node->customProperty( QStringLiteral( "embedded" ) ).toInt();
348 
349  if ( testFlag( AllowNodeReorder ) )
350  {
351  // only root embedded nodes can be reordered
352  if ( !isEmbedded || ( isEmbedded && node->parent() && !node->parent()->customProperty( QStringLiteral( "embedded" ) ).toInt() ) )
353  f |= Qt::ItemIsDragEnabled;
354  }
355 
357  f |= Qt::ItemIsUserCheckable;
358 
359  if ( testFlag( AllowNodeReorder ) && QgsLayerTree::isGroup( node ) && !isEmbedded )
360  f |= Qt::ItemIsDropEnabled;
361 
362  return f;
363 }
364 
365 bool QgsLayerTreeModel::setData( const QModelIndex &index, const QVariant &value, int role )
366 {
368  if ( sym )
369  {
370  if ( role == Qt::CheckStateRole && !testFlag( AllowLegendChangeState ) )
371  return false;
372  bool res = sym->setData( value, role );
373  if ( res )
374  emit dataChanged( index, index );
375  return res;
376  }
377 
378  QgsLayerTreeNode *node = index2node( index );
379  if ( !node )
380  return QAbstractItemModel::setData( index, value, role );
381 
382  if ( role == Qt::CheckStateRole )
383  {
385  return false;
386 
387  bool checked = static_cast< Qt::CheckState >( value.toInt() ) == Qt::Checked;
388  if ( checked && node->children().isEmpty() )
389  {
391  }
392  else if ( testFlag( ActionHierarchical ) )
393  {
394  if ( node->children().isEmpty() )
396  else
397  node->setItemVisibilityCheckedRecursive( checked );
398  }
399  else
400  {
401  node->setItemVisibilityChecked( checked );
402  }
403 
405 
406  return true;
407  }
408  else if ( role == Qt::EditRole )
409  {
410  if ( !testFlag( AllowNodeRename ) )
411  return false;
412 
413  if ( QgsLayerTree::isLayer( node ) )
414  {
415  QgsLayerTreeLayer *layer = QgsLayerTree::toLayer( node );
416  layer->setName( value.toString() );
417  emit dataChanged( index, index );
418  }
419  else if ( QgsLayerTree::isGroup( node ) )
420  {
421  QgsLayerTree::toGroup( node )->setName( value.toString() );
422  emit dataChanged( index, index );
423  }
424  }
425 
426  return QAbstractItemModel::setData( index, value, role );
427 }
428 
430 {
431  if ( !node || !node->parent() )
432  return QModelIndex(); // this is the only root item -> invalid index
433 
434  QModelIndex parentIndex = node2index( node->parent() );
435 
436  int row = node->parent()->children().indexOf( node );
437  Q_ASSERT( row >= 0 );
438  return index( row, 0, parentIndex );
439 }
440 
441 
442 static bool _isChildOfNode( QgsLayerTreeNode *child, QgsLayerTreeNode *node )
443 {
444  if ( !child->parent() )
445  return false;
446 
447  if ( child->parent() == node )
448  return true;
449 
450  return _isChildOfNode( child->parent(), node );
451 }
452 
453 static bool _isChildOfNodes( QgsLayerTreeNode *child, const QList<QgsLayerTreeNode *> &nodes )
454 {
455  for ( QgsLayerTreeNode *n : nodes )
456  {
457  if ( _isChildOfNode( child, n ) )
458  return true;
459  }
460 
461  return false;
462 }
463 
464 
465 QList<QgsLayerTreeNode *> QgsLayerTreeModel::indexes2nodes( const QModelIndexList &list, bool skipInternal ) const
466 {
467  QList<QgsLayerTreeNode *> nodes;
468  const auto constList = list;
469  for ( const QModelIndex &index : constList )
470  {
471  QgsLayerTreeNode *node = index2node( index );
472  if ( !node )
473  continue;
474 
475  nodes << node;
476  }
477 
478  if ( !skipInternal )
479  return nodes;
480 
481  // remove any children of nodes if both parent node and children are selected
482  QList<QgsLayerTreeNode *> nodesFinal;
483  for ( QgsLayerTreeNode *node : std::as_const( nodes ) )
484  {
485  if ( !_isChildOfNodes( node, nodes ) )
486  nodesFinal << node;
487  }
488 
489  return nodesFinal;
490 }
491 
493 {
494  return mRootNode;
495 }
496 
498 {
499  beginResetModel();
500 
502 
503  Q_ASSERT( mLegend.isEmpty() );
504 
505  mRootNode = newRootGroup;
506 
507  endResetModel();
508 
510 }
511 
513 {
514  // update title
515  QModelIndex idx = node2index( nodeLayer );
516  emit dataChanged( idx, idx );
517 
518  // update children
519  int oldNodeCount = rowCount( idx );
520  if ( oldNodeCount > 0 )
521  {
522  beginRemoveRows( idx, 0, oldNodeCount - 1 );
523  removeLegendFromLayer( nodeLayer );
524  endRemoveRows();
525  }
526 
527  addLegendToLayer( nodeLayer );
528  int newNodeCount = rowCount( idx );
529 
530  // automatic collapse of legend nodes - useful if a layer has many legend nodes
531  if ( mAutoCollapseLegendNodesCount != -1 && oldNodeCount != newNodeCount && newNodeCount >= mAutoCollapseLegendNodesCount )
532  nodeLayer->setExpanded( false );
533 }
534 
536 {
537  return mCurrentIndex;
538 }
539 
540 void QgsLayerTreeModel::setCurrentIndex( const QModelIndex &currentIndex )
541 {
543 }
544 
545 
546 void QgsLayerTreeModel::setLayerTreeNodeFont( int nodeType, const QFont &font )
547 {
548  if ( nodeType == QgsLayerTreeNode::NodeGroup )
549  {
550  if ( mFontGroup != font )
551  {
552  mFontGroup = font;
554  }
555  }
556  else if ( nodeType == QgsLayerTreeNode::NodeLayer )
557  {
558  if ( mFontLayer != font )
559  {
560  mFontLayer = font;
562  }
563  }
564  else
565  {
566  QgsDebugMsgLevel( QStringLiteral( "invalid node type" ), 4 );
567  }
568 }
569 
570 
571 QFont QgsLayerTreeModel::layerTreeNodeFont( int nodeType ) const
572 {
573  if ( nodeType == QgsLayerTreeNode::NodeGroup )
574  return mFontGroup;
575  else if ( nodeType == QgsLayerTreeNode::NodeLayer )
576  return mFontLayer;
577  else
578  {
579  QgsDebugMsgLevel( QStringLiteral( "invalid node type" ), 4 );
580  return QFont();
581  }
582 }
583 
585 {
586  mLegendFilterByScale = scale;
587 
588  // this could be later done in more efficient way
589  // by just updating active legend nodes, without refreshing original legend nodes
590  const auto layers = mRootNode->findLayers();
591  for ( QgsLayerTreeLayer *nodeLayer : layers )
592  refreshLayerLegend( nodeLayer );
593 }
594 
596 {
597  setLegendFilter( settings, /* useExtent = */ true );
598 }
599 
600 void QgsLayerTreeModel::setLegendFilter( const QgsMapSettings *settings, bool useExtent, const QgsGeometry &polygon, bool useExpressions )
601 {
602  if ( settings && settings->hasValidSettings() )
603  {
604  mLegendFilterMapSettings.reset( new QgsMapSettings( *settings ) );
605  mLegendFilterMapSettings->setLayerStyleOverrides( mLayerStyleOverrides );
607  mLegendFilterUsesExtent = useExtent;
608  // collect expression filters
609  if ( useExpressions )
610  {
611  const auto layers = mRootNode->findLayers();
612  for ( QgsLayerTreeLayer *nodeLayer : layers )
613  {
614  bool enabled;
615  QString expr = QgsLayerTreeUtils::legendFilterByExpression( *nodeLayer, &enabled );
616  if ( enabled && !expr.isEmpty() )
617  {
618  exprs[ nodeLayer->layerId()] = expr;
619  }
620  }
621  }
622  bool polygonValid = !polygon.isNull() && polygon.type() == QgsWkbTypes::PolygonGeometry;
623  if ( useExpressions && !useExtent && !polygonValid ) // only expressions
624  {
626  }
627  else
628  {
629  mLegendFilterHitTest.reset( new QgsMapHitTest( *mLegendFilterMapSettings, polygon, exprs ) );
630  }
631  mLegendFilterHitTest->run();
632  }
633  else
634  {
636  return; // no change
637 
638  mLegendFilterMapSettings.reset();
639  mLegendFilterHitTest.reset();
640  }
641 
642  // temporarily disable autocollapse so that legend nodes stay visible
643  int bkAutoCollapse = autoCollapseLegendNodes();
645 
646  // this could be later done in more efficient way
647  // by just updating active legend nodes, without refreshing original legend nodes
648  const auto layers = mRootNode->findLayers();
649  for ( QgsLayerTreeLayer *nodeLayer : layers )
650  refreshLayerLegend( nodeLayer );
651 
652  setAutoCollapseLegendNodes( bkAutoCollapse );
653 }
654 
655 void QgsLayerTreeModel::setLegendMapViewData( double mapUnitsPerPixel, int dpi, double scale )
656 {
657  if ( mLegendMapViewDpi == dpi && qgsDoubleNear( mLegendMapViewMupp, mapUnitsPerPixel ) && qgsDoubleNear( mLegendMapViewScale, scale ) )
658  return;
659 
660  double previousScale = mLegendMapViewScale;
661  mLegendMapViewScale = scale;
662  mLegendMapViewMupp = mapUnitsPerPixel;
663  mLegendMapViewDpi = dpi;
664 
665  // now invalidate legend nodes!
667 
668  if ( scale != previousScale )
669  refreshScaleBasedLayers( QModelIndex(), previousScale );
670 }
671 
672 void QgsLayerTreeModel::legendMapViewData( double *mapUnitsPerPixel, int *dpi, double *scale ) const
673 {
674  if ( mapUnitsPerPixel ) *mapUnitsPerPixel = mLegendMapViewMupp;
675  if ( dpi ) *dpi = mLegendMapViewDpi;
676  if ( scale ) *scale = mLegendMapViewScale;
677 }
678 
679 QMap<QString, QString> QgsLayerTreeModel::layerStyleOverrides() const
680 {
681  return mLayerStyleOverrides;
682 }
683 
684 void QgsLayerTreeModel::setLayerStyleOverrides( const QMap<QString, QString> &overrides )
685 {
686  mLayerStyleOverrides = overrides;
687 }
688 
689 int QgsLayerTreeModel::scaleIconSize( int standardSize )
690 {
691  return QgsApplication::scaleIconSize( standardSize, true );
692 }
693 
694 void QgsLayerTreeModel::nodeWillAddChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo )
695 {
696  beginInsertRows( node2index( node ), indexFrom, indexTo );
697 }
698 
699 static QList<QgsLayerTreeLayer *> _layerNodesInSubtree( QgsLayerTreeNode *node, int indexFrom, int indexTo )
700 {
701  QList<QgsLayerTreeNode *> children = node->children();
702  QList<QgsLayerTreeLayer *> newLayerNodes;
703  for ( int i = indexFrom; i <= indexTo; ++i )
704  {
705  QgsLayerTreeNode *child = children.at( i );
706  if ( QgsLayerTree::isLayer( child ) )
707  newLayerNodes << QgsLayerTree::toLayer( child );
708  else if ( QgsLayerTree::isGroup( child ) )
709  newLayerNodes << QgsLayerTree::toGroup( child )->findLayers();
710  }
711  return newLayerNodes;
712 }
713 
714 void QgsLayerTreeModel::nodeAddedChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo )
715 {
716  Q_ASSERT( node );
717 
718  endInsertRows();
719 
720  const auto subNodes = _layerNodesInSubtree( node, indexFrom, indexTo );
721  for ( QgsLayerTreeLayer *newLayerNode : subNodes )
722  connectToLayer( newLayerNode );
723 }
724 
725 void QgsLayerTreeModel::nodeWillRemoveChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo )
726 {
727  Q_ASSERT( node );
728 
729  beginRemoveRows( node2index( node ), indexFrom, indexTo );
730 
731  // disconnect from layers and remove their legend
732  const auto subNodes = _layerNodesInSubtree( node, indexFrom, indexTo );
733  for ( QgsLayerTreeLayer *nodeLayer : subNodes )
734  disconnectFromLayer( nodeLayer );
735 }
736 
738 {
739  endRemoveRows();
740 }
741 
743 {
744  Q_ASSERT( node );
745 
746  const QModelIndex index = node2index( node );
747  emit dataChanged( index, index );
748 }
749 
750 void QgsLayerTreeModel::nodeNameChanged( QgsLayerTreeNode *node, const QString &name )
751 {
752  Q_UNUSED( name )
753  Q_ASSERT( node );
754 
755  const QModelIndex index = node2index( node );
756  emit dataChanged( index, index );
757 }
758 
759 
761 {
762  if ( QgsLayerTree::isLayer( node ) && key == QLatin1String( "showFeatureCount" ) )
764 }
765 
766 
768 {
769  QgsLayerTreeLayer *nodeLayer = qobject_cast<QgsLayerTreeLayer *>( sender() );
770  if ( !nodeLayer )
771  return;
772 
773  // deferred connection to the layer
774  connectToLayer( nodeLayer );
775 }
776 
778 {
779  QgsLayerTreeLayer *nodeLayer = qobject_cast<QgsLayerTreeLayer *>( sender() );
780  if ( !nodeLayer )
781  return;
782 
783  disconnectFromLayer( nodeLayer );
784 
785  // wait for the layer to appear again
787 }
788 
790 {
791  if ( !mRootNode )
792  return;
793 
794  if ( !testFlag( ShowLegend ) )
795  return;
796 
797  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
798  if ( !layer )
799  return;
800 
801  QgsLayerTreeLayer *nodeLayer = mRootNode->findLayer( layer->id() );
802  if ( !nodeLayer )
803  return;
804 
805  refreshLayerLegend( nodeLayer );
806 }
807 
809 {
810  if ( !mRootNode )
811  return;
812 
813  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
814  if ( !layer )
815  return;
816 
817  QgsLayerTreeLayer *nodeLayer = mRootNode->findLayer( layer->id() );
818  if ( !nodeLayer )
819  return;
820 
821  const QModelIndex index = node2index( nodeLayer );
822  emit dataChanged( index, index );
823 }
824 
826 {
827  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
828  if ( !layer )
829  return;
830 
831  QgsLayerTreeLayer *nodeLayer = mRootNode->findLayer( layer->id() );
832  if ( !nodeLayer )
833  return;
834 
835  QModelIndex index = node2index( nodeLayer );
836  emit dataChanged( index, index );
837 
838  if ( nodeLayer->customProperty( QStringLiteral( "showFeatureCount" ) ).toInt() )
839  refreshLayerLegend( nodeLayer );
840 }
841 
842 
844 {
845  QgsLayerTreeModelLegendNode *legendNode = qobject_cast<QgsLayerTreeModelLegendNode *>( sender() );
846  if ( !legendNode )
847  return;
848 
849  QModelIndex index = legendNode2index( legendNode );
850  if ( index.isValid() )
851  emit dataChanged( index, index );
852 }
853 
854 void QgsLayerTreeModel::legendNodeSizeChanged()
855 {
856  QgsLayerTreeModelLegendNode *legendNode = qobject_cast<QgsLayerTreeModelLegendNode *>( sender() );
857  if ( !legendNode )
858  return;
859 
860  QModelIndex index = legendNode2index( legendNode );
861  if ( index.isValid() )
862  emit dataChanged( index, index, QVector<int> { Qt::SizeHintRole } );
863 }
864 
865 
867 {
868  if ( !nodeLayer->layer() )
869  {
870  // in order to connect to layer, we need to have it loaded.
871  // keep an eye on the layer ID: once loaded, we will use it
872  connect( nodeLayer, &QgsLayerTreeLayer::layerLoaded, this, &QgsLayerTreeModel::nodeLayerLoaded, Qt::UniqueConnection );
873  return;
874  }
875 
876  // watch if the layer is getting removed
877  connect( nodeLayer, &QgsLayerTreeLayer::layerWillBeUnloaded, this, &QgsLayerTreeModel::nodeLayerWillBeUnloaded, Qt::UniqueConnection );
878 
879  if ( testFlag( ShowLegend ) )
880  {
881  addLegendToLayer( nodeLayer );
882 
883  // if we aren't loading a layer from a project, setup some nice default settings
884  if ( !mRootNode->customProperty( QStringLiteral( "loading" ) ).toBool() )
885  {
886  // automatic collapse of legend nodes - useful if a layer has many legend nodes
888  nodeLayer->setExpanded( false );
889 
891  {
892  nodeLayer->setCustomProperty( QStringLiteral( "showFeatureCount" ), true );
893  }
894  }
895  }
896 
897  QgsMapLayer *layer = nodeLayer->layer();
898  connect( layer, &QgsMapLayer::legendChanged, this, &QgsLayerTreeModel::layerLegendChanged, Qt::UniqueConnection );
899  connect( layer, &QgsMapLayer::flagsChanged, this, &QgsLayerTreeModel::layerFlagsChanged, Qt::UniqueConnection );
900 
901  // using unique connection because there may be temporarily more nodes for a layer than just one
902  // which would create multiple connections, however disconnect() would disconnect all multiple connections
903  // even if we wanted to disconnect just one connection in each call.
904  connect( layer, &QgsMapLayer::editingStarted, this, &QgsLayerTreeModel::layerNeedsUpdate, Qt::UniqueConnection );
905  connect( layer, &QgsMapLayer::editingStopped, this, &QgsLayerTreeModel::layerNeedsUpdate, Qt::UniqueConnection );
906  connect( layer, &QgsMapLayer::layerModified, this, &QgsLayerTreeModel::layerNeedsUpdate, Qt::UniqueConnection );
907 
908  emit dataChanged( node2index( nodeLayer ), node2index( nodeLayer ) );
909 }
910 
911 // try to find out if the layer ID is present in the tree multiple times
912 static int _numLayerCount( QgsLayerTreeGroup *group, const QString &layerId )
913 {
914  int count = 0;
915  const auto constChildren = group->children();
916  for ( QgsLayerTreeNode *child : constChildren )
917  {
918  if ( QgsLayerTree::isLayer( child ) )
919  {
920  if ( QgsLayerTree::toLayer( child )->layerId() == layerId )
921  count++;
922  }
923  else if ( QgsLayerTree::isGroup( child ) )
924  {
925  count += _numLayerCount( QgsLayerTree::toGroup( child ), layerId );
926  }
927  }
928  return count;
929 }
930 
932 {
933  disconnect( nodeLayer, nullptr, this, nullptr ); // disconnect from delayed load of layer
934 
935  if ( !nodeLayer->layer() )
936  return; // we were never connected
937 
938  if ( testFlag( ShowLegend ) )
939  {
940  removeLegendFromLayer( nodeLayer );
941  }
942 
943  if ( _numLayerCount( mRootNode, nodeLayer->layerId() ) == 1 )
944  {
945  // last instance of the layer in the tree: disconnect from all signals from layer!
946  disconnect( nodeLayer->layer(), nullptr, this, nullptr );
947  }
948 }
949 
951 {
952  const auto constChildren = parentGroup->children();
953  for ( QgsLayerTreeNode *node : constChildren )
954  {
955  if ( QgsLayerTree::isGroup( node ) )
957  else if ( QgsLayerTree::isLayer( node ) )
959  }
960 }
961 
963 {
964  const auto constChildren = parentGroup->children();
965  for ( QgsLayerTreeNode *node : constChildren )
966  {
967  if ( QgsLayerTree::isGroup( node ) )
969  else if ( QgsLayerTree::isLayer( node ) )
971  }
972 }
973 
975 {
976  Q_ASSERT( mRootNode );
977 
978  connect( mRootNode, &QgsLayerTreeNode::willAddChildren, this, &QgsLayerTreeModel::nodeWillAddChildren, Qt::ConnectionType::UniqueConnection );
979  connect( mRootNode, &QgsLayerTreeNode::addedChildren, this, &QgsLayerTreeModel::nodeAddedChildren, Qt::ConnectionType::UniqueConnection );
980  connect( mRootNode, &QgsLayerTreeNode::willRemoveChildren, this, &QgsLayerTreeModel::nodeWillRemoveChildren, Qt::ConnectionType::UniqueConnection );
981  connect( mRootNode, &QgsLayerTreeNode::removedChildren, this, &QgsLayerTreeModel::nodeRemovedChildren, Qt::ConnectionType::UniqueConnection );
982  connect( mRootNode, &QgsLayerTreeNode::visibilityChanged, this, &QgsLayerTreeModel::nodeVisibilityChanged, Qt::ConnectionType::UniqueConnection );
983  connect( mRootNode, &QgsLayerTreeNode::nameChanged, this, &QgsLayerTreeModel::nodeNameChanged, Qt::ConnectionType::UniqueConnection );
984  connect( mRootNode, &QgsLayerTreeNode::customPropertyChanged, this, &QgsLayerTreeModel::nodeCustomPropertyChanged, Qt::ConnectionType::UniqueConnection );
985 
987 }
988 
990 {
991  disconnect( mRootNode, nullptr, this, nullptr );
992 
994 }
995 
996 void QgsLayerTreeModel::recursivelyEmitDataChanged( const QModelIndex &idx )
997 {
998  QgsLayerTreeNode *node = index2node( idx );
999  if ( !node )
1000  return;
1001 
1002  int count = node->children().count();
1003  if ( count == 0 )
1004  return;
1005  emit dataChanged( index( 0, 0, idx ), index( count - 1, 0, idx ) );
1006  for ( int i = 0; i < count; ++i )
1007  recursivelyEmitDataChanged( index( i, 0, idx ) );
1008 }
1009 
1010 void QgsLayerTreeModel::refreshScaleBasedLayers( const QModelIndex &idx, double previousScale )
1011 {
1012  QgsLayerTreeNode *node = index2node( idx );
1013  if ( !node )
1014  return;
1015 
1016  if ( node->nodeType() == QgsLayerTreeNode::NodeLayer )
1017  {
1018  const QgsMapLayer *layer = QgsLayerTree::toLayer( node )->layer();
1019  if ( layer && layer->hasScaleBasedVisibility() )
1020  {
1021  if ( layer->isInScaleRange( mLegendMapViewScale ) != layer->isInScaleRange( previousScale ) )
1022  emit dataChanged( idx, idx, QVector<int>() << Qt::FontRole << Qt::ForegroundRole );
1023  }
1024  }
1025  int count = node->children().count();
1026  for ( int i = 0; i < count; ++i )
1027  refreshScaleBasedLayers( index( i, 0, idx ), previousScale );
1028 }
1029 
1031 {
1032  return Qt::CopyAction | Qt::MoveAction;
1033 }
1034 
1035 QStringList QgsLayerTreeModel::mimeTypes() const
1036 {
1037  QStringList types;
1038  types << QStringLiteral( "application/qgis.layertreemodeldata" );
1039  return types;
1040 }
1041 
1042 
1043 QMimeData *QgsLayerTreeModel::mimeData( const QModelIndexList &indexes ) const
1044 {
1045  // Sort the indexes. Depending on how the user selected the items, the indexes may be unsorted.
1046  QModelIndexList sortedIndexes = indexes;
1047  std::sort( sortedIndexes.begin(), sortedIndexes.end(), std::less<QModelIndex>() );
1048 
1049  QList<QgsLayerTreeNode *> nodesFinal = indexes2nodes( sortedIndexes, true );
1050 
1051  if ( nodesFinal.isEmpty() )
1052  return nullptr;
1053 
1054  QMimeData *mimeData = new QMimeData();
1055 
1056  QDomDocument layerTreeDoc;
1057  QDomElement rootLayerTreeElem = layerTreeDoc.createElement( QStringLiteral( "layer_tree_model_data" ) );
1058 
1059  for ( QgsLayerTreeNode *node : std::as_const( nodesFinal ) )
1060  {
1061  node->writeXml( rootLayerTreeElem, QgsReadWriteContext() );
1062  }
1063  layerTreeDoc.appendChild( rootLayerTreeElem );
1064 
1065  QString errorMessage;
1066  QgsReadWriteContext readWriteContext;
1067  QDomDocument layerDefinitionsDoc( QStringLiteral( "qgis-layer-definition" ) );
1068  QgsLayerDefinition::exportLayerDefinition( layerDefinitionsDoc, nodesFinal, errorMessage, QgsReadWriteContext() );
1069 
1070  QString txt = layerDefinitionsDoc.toString();
1071 
1072  mimeData->setData( QStringLiteral( "application/qgis.layertreemodeldata" ), layerTreeDoc.toString().toUtf8() );
1073  mimeData->setData( QStringLiteral( "application/qgis.application.pid" ), QString::number( QCoreApplication::applicationPid() ).toUtf8() );
1074  mimeData->setData( QStringLiteral( "application/qgis.layertree.source" ), QStringLiteral( ":0x%1" ).arg( reinterpret_cast<quintptr>( this ), 2 * QT_POINTER_SIZE, 16, QLatin1Char( '0' ) ).toUtf8() );
1075  mimeData->setData( QStringLiteral( "application/qgis.layertree.layerdefinitions" ), txt.toUtf8() );
1076  mimeData->setData( QStringLiteral( "application/x-vnd.qgis.qgis.uri" ), QgsMimeDataUtils::layerTreeNodesToUriList( nodesFinal ) );
1077 
1078  return mimeData;
1079 }
1080 
1081 bool QgsLayerTreeModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
1082 {
1083  if ( action == Qt::IgnoreAction )
1084  return true;
1085 
1086  if ( !data->hasFormat( QStringLiteral( "application/qgis.layertreemodeldata" ) ) )
1087  return false;
1088 
1089  if ( column >= columnCount( parent ) )
1090  return false;
1091 
1092  // don't accept drops from some layer tree subclasses to non-matching subclasses
1093  const QString restrictTypes( data->data( QStringLiteral( "application/qgis.restrictlayertreemodelsubclass" ) ) );
1094  if ( !restrictTypes.isEmpty() && restrictTypes != QString( metaObject()->className() ) )
1095  return false;
1096 
1097  QgsLayerTreeNode *nodeParent = index2node( parent );
1098  if ( !QgsLayerTree::isGroup( nodeParent ) )
1099  return false;
1100 
1101  if ( parent.isValid() && row == -1 )
1102  row = 0; // if dropped directly onto group item, insert at first position
1103 
1104  // if we are coming from another QGIS instance, we need to add the layers too
1105  bool ok = false;
1106  // the application pid is only provided from QGIS 3.14, so do not check to OK before defaulting to moving in the legend
1107  qint64 qgisPid = data->data( QStringLiteral( "application/qgis.application.pid" ) ).toInt( &ok );
1108 
1109  if ( ok && qgisPid != QCoreApplication::applicationPid() )
1110  {
1111  QByteArray encodedLayerDefinitionData = data->data( QStringLiteral( "application/qgis.layertree.layerdefinitions" ) );
1112  QDomDocument layerDefinitionDoc;
1113  if ( !layerDefinitionDoc.setContent( QString::fromUtf8( encodedLayerDefinitionData ) ) )
1114  return false;
1115  QgsReadWriteContext context;
1116  QString errorMessage;
1117  QgsLayerDefinition::loadLayerDefinition( layerDefinitionDoc, QgsProject::instance(), QgsLayerTree::toGroup( nodeParent ), errorMessage, context );
1118  emit messageEmitted( tr( "New layers added from another QGIS instance" ) );
1119  }
1120  else
1121  {
1122  QByteArray encodedLayerTreeData = data->data( QStringLiteral( "application/qgis.layertreemodeldata" ) );
1123 
1124  QDomDocument layerTreeDoc;
1125  if ( !layerTreeDoc.setContent( QString::fromUtf8( encodedLayerTreeData ) ) )
1126  return false;
1127 
1128  QDomElement rootLayerTreeElem = layerTreeDoc.documentElement();
1129  if ( rootLayerTreeElem.tagName() != QLatin1String( "layer_tree_model_data" ) )
1130  return false;
1131 
1132  QList<QgsLayerTreeNode *> nodes;
1133 
1134  QDomElement elem = rootLayerTreeElem.firstChildElement();
1135  while ( !elem.isNull() )
1136  {
1138  if ( node )
1139  nodes << node;
1140 
1141  elem = elem.nextSiblingElement();
1142  }
1143 
1144  if ( nodes.isEmpty() )
1145  return false;
1146 
1147  QgsLayerTree::toGroup( nodeParent )->insertChildNodes( row, nodes );
1148  }
1149  return true;
1150 }
1151 
1152 bool QgsLayerTreeModel::removeRows( int row, int count, const QModelIndex &parent )
1153 {
1154  QgsLayerTreeNode *parentNode = index2node( parent );
1155  if ( QgsLayerTree::isGroup( parentNode ) )
1156  {
1157  QgsLayerTree::toGroup( parentNode )->removeChildren( row, count );
1158  return true;
1159  }
1160  return false;
1161 }
1162 
1163 void QgsLayerTreeModel::setFlags( QgsLayerTreeModel::Flags f )
1164 {
1165  mFlags = f;
1166 }
1167 
1169 {
1170  if ( on )
1171  mFlags |= f;
1172  else
1173  mFlags &= ~f;
1174 }
1175 
1176 QgsLayerTreeModel::Flags QgsLayerTreeModel::flags() const
1177 {
1178  return mFlags;
1179 }
1180 
1182 {
1183  return mFlags.testFlag( f );
1184 }
1185 
1187 {
1188  return QgsApplication::getThemeIcon( QStringLiteral( "/mActionFolder.svg" ) );
1189 }
1190 
1191 QList<QgsLayerTreeModelLegendNode *> QgsLayerTreeModel::filterLegendNodes( const QList<QgsLayerTreeModelLegendNode *> &nodes )
1192 {
1193  QList<QgsLayerTreeModelLegendNode *> filtered;
1194 
1195  if ( mLegendFilterByScale > 0 )
1196  {
1197  for ( QgsLayerTreeModelLegendNode *node : std::as_const( nodes ) )
1198  {
1199  if ( node->isScaleOK( mLegendFilterByScale ) )
1200  filtered << node;
1201  }
1202  }
1203  else if ( mLegendFilterMapSettings )
1204  {
1205  if ( !nodes.isEmpty() && mLegendFilterMapSettings->layers().contains( nodes.at( 0 )->layerNode()->layer() ) )
1206  {
1207  for ( QgsLayerTreeModelLegendNode *node : std::as_const( nodes ) )
1208  {
1210  {
1212  filtered << node;
1213  break;
1214 
1222  {
1223  const QString ruleKey = node->data( QgsSymbolLegendNode::RuleKeyRole ).toString();
1224  bool checked = mLegendFilterUsesExtent || node->data( Qt::CheckStateRole ).toInt() == Qt::Checked;
1225  if ( checked )
1226  {
1227  if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( node->layerNode()->layer() ) )
1228  {
1229  if ( mLegendFilterHitTest->legendKeyVisible( ruleKey, vl ) )
1230  filtered << node;
1231  }
1232  else
1233  {
1234  filtered << node;
1235  }
1236  }
1237  else // unknown node type or unchecked
1238  filtered << node;
1239  break;
1240  }
1241  }
1242  }
1243  }
1244  }
1245  else
1246  {
1247  return nodes;
1248  }
1249 
1250  return filtered;
1251 }
1252 
1253 
1254 
1256 // Legend nodes routines - start
1257 
1259 {
1260  const auto constMLegend = mLegend;
1261  for ( const LayerLegendData &data : constMLegend )
1262  {
1263  qDeleteAll( data.originalNodes );
1264  delete data.tree;
1265  }
1266  mLegend.clear();
1267 }
1268 
1269 
1271 {
1272  if ( mLegend.contains( nodeLayer ) )
1273  {
1274  qDeleteAll( mLegend[nodeLayer].originalNodes );
1275  delete mLegend[nodeLayer].tree;
1276  mLegend.remove( nodeLayer );
1277  }
1278 }
1279 
1280 
1282 {
1283  if ( !nodeL || !nodeL->layer() )
1284  return;
1285 
1286  QgsMapLayer *ml = nodeL->layer();
1287 
1288  QgsMapLayerStyleOverride styleOverride( ml );
1289  if ( mLayerStyleOverrides.contains( ml->id() ) )
1290  styleOverride.setOverrideStyle( mLayerStyleOverrides.value( ml->id() ) );
1291 
1292  QgsMapLayerLegend *layerLegend = ml->legend();
1293  if ( !layerLegend )
1294  return;
1295  QList<QgsLayerTreeModelLegendNode *> lstNew = layerLegend->createLayerTreeModelLegendNodes( nodeL );
1296 
1297  // apply filtering defined in layer node's custom properties (reordering, filtering, custom labels)
1299 
1300  if ( testFlag( UseEmbeddedWidgets ) )
1301  {
1302  // generate placeholder legend nodes that will be replaced by widgets in QgsLayerTreeView
1303  int widgetsCount = ml->customProperty( QStringLiteral( "embeddedWidgets/count" ), 0 ).toInt();
1304  while ( widgetsCount > 0 )
1305  {
1306  lstNew.insert( 0, new EmbeddedWidgetLegendNode( nodeL ) );
1307  --widgetsCount;
1308  }
1309  }
1310 
1311  QList<QgsLayerTreeModelLegendNode *> filteredLstNew = filterLegendNodes( lstNew );
1312 
1313  const auto constLstNew = lstNew;
1314  for ( QgsLayerTreeModelLegendNode *n : constLstNew )
1315  {
1316  n->setParent( this );
1318  connect( n, &QgsLayerTreeModelLegendNode::sizeChanged, this, &QgsLayerTreeModel::legendNodeSizeChanged );
1319  }
1320 
1321  // See if we have an embedded node - if we do, we will not use it among active nodes.
1322  // Legend node embedded in parent does not have to be the first one,
1323  // there can be also nodes generated for embedded widgets
1324  QgsLayerTreeModelLegendNode *embeddedNode = nullptr;
1325  const auto constFilteredLstNew = filteredLstNew;
1326  for ( QgsLayerTreeModelLegendNode *legendNode : constFilteredLstNew )
1327  {
1328  if ( legendNode->isEmbeddedInParent() )
1329  {
1330  embeddedNode = legendNode;
1331  filteredLstNew.removeOne( legendNode );
1332  break;
1333  }
1334  }
1335 
1336  LayerLegendTree *legendTree = nullptr;
1337 
1338  // maybe the legend nodes form a tree - try to create a tree structure from the list
1339  if ( testFlag( ShowLegendAsTree ) )
1340  legendTree = tryBuildLegendTree( filteredLstNew );
1341 
1342  int count = legendTree ? legendTree->children[nullptr].count() : filteredLstNew.count();
1343 
1344  if ( !filteredLstNew.isEmpty() )
1345  {
1346  // Make sure it's clear
1347  const QModelIndex nodeIndex { node2index( nodeL ) };
1348  if ( rowCount( nodeIndex ) > 0 )
1349  {
1350  beginRemoveRows( node2index( nodeL ), 0, rowCount( nodeIndex ) - 1 );
1351  mLegend[nodeL] = LayerLegendData();
1352  endRemoveRows();
1353  }
1354  beginInsertRows( node2index( nodeL ), 0, count - 1 );
1355  }
1356 
1358  data.originalNodes = lstNew;
1359  data.activeNodes = filteredLstNew;
1360  data.embeddedNodeInParent = embeddedNode;
1361  data.tree = legendTree;
1362 
1363  mLegend[nodeL] = data;
1364 
1365  if ( !filteredLstNew.isEmpty() )
1366  {
1367  endInsertRows();
1368  }
1369 
1370  // invalidate map based data even if the data is not map-based to make sure
1371  // the symbol sizes are computed at least once
1372  mInvalidatedNodes.insert( nodeL );
1374 }
1375 
1376 
1377 QgsLayerTreeModel::LayerLegendTree *QgsLayerTreeModel::tryBuildLegendTree( const QList<QgsLayerTreeModelLegendNode *> &nodes )
1378 {
1379  // first check whether there are any legend nodes that are not top-level
1380  bool hasParentKeys = false;
1381  for ( QgsLayerTreeModelLegendNode *n : nodes )
1382  {
1383  if ( !n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString().isEmpty() )
1384  {
1385  hasParentKeys = true;
1386  break;
1387  }
1388  }
1389  if ( !hasParentKeys )
1390  return nullptr; // all legend nodes are top-level => stick with list representation
1391 
1392  // make mapping from rules to nodes and do some sanity checks
1393  QHash<QString, QgsLayerTreeModelLegendNode *> rule2node;
1394  rule2node[QString()] = nullptr;
1395  for ( QgsLayerTreeModelLegendNode *n : nodes )
1396  {
1397  QString ruleKey = n->data( QgsLayerTreeModelLegendNode::RuleKeyRole ).toString();
1398  if ( ruleKey.isEmpty() ) // in tree all nodes must have key
1399  return nullptr;
1400  if ( rule2node.contains( ruleKey ) ) // and they must be unique
1401  return nullptr;
1402  rule2node[ruleKey] = n;
1403  }
1404 
1405  // create the tree structure
1406  LayerLegendTree *tree = new LayerLegendTree;
1407  for ( QgsLayerTreeModelLegendNode *n : nodes )
1408  {
1409  QString parentRuleKey = n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString();
1410  QgsLayerTreeModelLegendNode *parent = rule2node.value( parentRuleKey, nullptr );
1411  tree->parents[n] = parent;
1412  tree->children[parent] << n;
1413  }
1414  return tree;
1415 }
1416 
1418 {
1419  double scale = 0.0;
1420  double mupp = 0.0;
1421  int dpi = 0;
1422  legendMapViewData( &mupp, &dpi, &scale );
1423  bool validData = !qgsDoubleNear( mupp, 0.0 ) && dpi != 0 && !qgsDoubleNear( scale, 0.0 );
1424 
1425  // setup temporary render context
1426  std::unique_ptr<QgsRenderContext> context( new QgsRenderContext );
1427  context->setScaleFactor( dpi / 25.4 );
1428  context->setRendererScale( scale );
1429  context->setMapToPixel( QgsMapToPixel( mupp ) );
1431  return validData ? context.release() : nullptr;
1432 }
1433 
1434 
1436 {
1437  return qobject_cast<QgsLayerTreeModelLegendNode *>( reinterpret_cast<QObject *>( index.internalPointer() ) );
1438 }
1439 
1440 
1442 {
1444  if ( data.tree )
1445  {
1446  if ( QgsLayerTreeModelLegendNode *parentLegendNode = data.tree->parents[legendNode] )
1447  {
1448  QModelIndex parentIndex = legendNode2index( parentLegendNode );
1449  int row = data.tree->children[parentLegendNode].indexOf( legendNode );
1450  return index( row, 0, parentIndex );
1451  }
1452  else
1453  {
1454  QModelIndex parentIndex = node2index( legendNode->layerNode() );
1455  int row = data.tree->children[nullptr].indexOf( legendNode );
1456  return index( row, 0, parentIndex );
1457  }
1458  }
1459 
1460  QModelIndex parentIndex = node2index( legendNode->layerNode() );
1461  Q_ASSERT( parentIndex.isValid() );
1462  int row = data.activeNodes.indexOf( legendNode );
1463  if ( row < 0 ) // legend node may be filtered (exists within the list of original nodes, but not in active nodes)
1464  return QModelIndex();
1465 
1466  return index( row, 0, parentIndex );
1467 }
1468 
1469 
1471 {
1472  const LayerLegendData &data = mLegend[node->layerNode()];
1473  if ( data.tree )
1474  return data.tree->children[node].count();
1475 
1476  return 0; // they are leaves
1477 }
1478 
1479 
1481 {
1482  if ( !mLegend.contains( nL ) )
1483  return 0;
1484 
1485  const LayerLegendData &data = mLegend[nL];
1486  if ( data.tree )
1487  return data.tree->children[nullptr].count();
1488 
1489  int count = data.activeNodes.count();
1490  return count;
1491 }
1492 
1493 
1494 QModelIndex QgsLayerTreeModel::legendRootIndex( int row, int column, QgsLayerTreeLayer *nL ) const
1495 {
1496  Q_ASSERT( mLegend.contains( nL ) );
1497  const LayerLegendData &data = mLegend[nL];
1498  if ( data.tree )
1499  return createIndex( row, column, static_cast<QObject *>( data.tree->children[nullptr].at( row ) ) );
1500 
1501  return createIndex( row, column, static_cast<QObject *>( data.activeNodes.at( row ) ) );
1502 }
1503 
1504 
1505 QModelIndex QgsLayerTreeModel::legendNodeIndex( int row, int column, QgsLayerTreeModelLegendNode *node ) const
1506 {
1507  const LayerLegendData &data = mLegend[node->layerNode()];
1508  if ( data.tree )
1509  return createIndex( row, column, static_cast<QObject *>( data.tree->children[node].at( row ) ) );
1510 
1511  return QModelIndex(); // have no children
1512 }
1513 
1514 
1516 {
1517  QgsLayerTreeLayer *layerNode = legendNode->layerNode();
1518  const LayerLegendData &data = mLegend[layerNode];
1519  if ( data.tree )
1520  {
1521  if ( QgsLayerTreeModelLegendNode *parentNode = data.tree->parents[legendNode] )
1522  {
1523  QgsLayerTreeModelLegendNode *grandParentNode = data.tree->parents[parentNode]; // may be null (not a problem)
1524  int row = data.tree->children[grandParentNode].indexOf( parentNode );
1525  return createIndex( row, 0, static_cast<QObject *>( parentNode ) );
1526  }
1527  else
1528  return indexOfParentLayerTreeNode( layerNode );
1529  }
1530 
1531  return indexOfParentLayerTreeNode( layerNode );
1532 }
1533 
1534 
1536 {
1537  if ( role == Qt::CheckStateRole && !testFlag( AllowLegendChangeState ) )
1538  return QVariant();
1539  return node->data( role );
1540 }
1541 
1542 
1544 {
1545  Qt::ItemFlags f = node->flags();
1546  if ( !testFlag( AllowLegendChangeState ) )
1547  f &= ~Qt::ItemIsUserCheckable;
1548  return f;
1549 }
1550 
1551 
1553 {
1554  return static_cast< bool >( mLegend[nodeLayer].embeddedNodeInParent );
1555 }
1556 
1558 {
1559  return mLegend[nodeLayer].embeddedNodeInParent;
1560 }
1561 
1562 
1564 {
1565  QgsLayerTreeModelLegendNode *legendNode = mLegend[nodeLayer].embeddedNodeInParent;
1566  if ( !legendNode )
1567  return QIcon();
1568  return QIcon( qvariant_cast<QPixmap>( legendNode->data( Qt::DecorationRole ) ) );
1569 }
1570 
1571 
1572 QList<QgsLayerTreeModelLegendNode *> QgsLayerTreeModel::layerLegendNodes( QgsLayerTreeLayer *nodeLayer, bool skipNodeEmbeddedInParent )
1573 {
1574  if ( !mLegend.contains( nodeLayer ) )
1575  return QList<QgsLayerTreeModelLegendNode *>();
1576 
1577  const LayerLegendData &data = mLegend[nodeLayer];
1578  QList<QgsLayerTreeModelLegendNode *> lst( data.activeNodes );
1579  if ( !skipNodeEmbeddedInParent && data.embeddedNodeInParent )
1580  lst.prepend( data.embeddedNodeInParent );
1581  return lst;
1582 }
1583 
1584 QList<QgsLayerTreeModelLegendNode *> QgsLayerTreeModel::layerOriginalLegendNodes( QgsLayerTreeLayer *nodeLayer )
1585 {
1586  return mLegend.value( nodeLayer ).originalNodes;
1587 }
1588 
1589 QgsLayerTreeModelLegendNode *QgsLayerTreeModel::findLegendNode( const QString &layerId, const QString &ruleKey ) const
1590 {
1591  for ( auto it = mLegend.constBegin(); it != mLegend.constEnd(); ++it )
1592  {
1593  QgsLayerTreeLayer *layer = it.key();
1594  if ( layer->layerId() == layerId )
1595  {
1596  const auto activeNodes = mLegend.value( layer ).activeNodes;
1597  for ( QgsLayerTreeModelLegendNode *legendNode : activeNodes )
1598  {
1599  if ( legendNode->data( QgsLayerTreeModelLegendNode::RuleKeyRole ).toString() == ruleKey )
1600  {
1601  //found it!
1602  return legendNode;
1603  }
1604  }
1605  }
1606  }
1607 
1608  return nullptr;
1609 }
1610 
1612 {
1615  else
1616  mDeferLegendInvalidationTimer.start( 10 );
1617 }
1618 
1620 {
1621  // we have varying icon sizes, and we want icon to be centered and
1622  // text to be left aligned, so we have to compute the max width of icons
1623  //
1624  // we do that for nodes which share a common parent
1625  //
1626  // we do that here because for symbols with size defined in map units
1627  // the symbol sizes changes depends on the zoom level
1628 
1629  std::unique_ptr<QgsRenderContext> context( createTemporaryRenderContext() );
1630 
1631  for ( QgsLayerTreeLayer *layerNode : std::as_const( mInvalidatedNodes ) )
1632  {
1633  const LayerLegendData &data = mLegend.value( layerNode );
1634 
1635  QList<QgsSymbolLegendNode *> symbolNodes;
1636  QMap<QString, int> widthMax;
1637  for ( QgsLayerTreeModelLegendNode *legendNode : std::as_const( data.originalNodes ) )
1638  {
1639  QgsSymbolLegendNode *n = qobject_cast<QgsSymbolLegendNode *>( legendNode );
1640  if ( n )
1641  {
1642  const QSize sz( n->minimumIconSize( context.get() ) );
1643  const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
1644  widthMax[parentKey] = std::max( sz.width(), widthMax.contains( parentKey ) ? widthMax[parentKey] : 0 );
1645  n->setIconSize( sz );
1646  symbolNodes.append( n );
1647  }
1648  }
1649  for ( QgsSymbolLegendNode *n : std::as_const( symbolNodes ) )
1650  {
1651  const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
1652  Q_ASSERT( widthMax[parentKey] > 0 );
1653  const int twiceMarginWidth = 2; // a one pixel margin avoids hugly rendering of icon
1654  n->setIconSize( QSize( widthMax[parentKey] + twiceMarginWidth, n->iconSize().rheight() + twiceMarginWidth ) );
1655  }
1656  for ( QgsLayerTreeModelLegendNode *legendNode : std::as_const( data.originalNodes ) )
1658  }
1659 
1660  mInvalidatedNodes.clear();
1661 }
1662 
1663 // Legend nodes routines - end
QgsLayerTreeNode::NodeGroup
@ NodeGroup
Container of other groups and layers.
Definition: qgslayertreenode.h:102
QgsLayerTreeModel::setLayerStyleOverrides
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets map of map layer style overrides (key: layer ID, value: style name) where a different style shou...
Definition: qgslayertreemodel.cpp:684
QgsMapLayer::flagsChanged
void flagsChanged()
Emitted when layer's flags have been modified.
QgsLayerTreeModel::columnCount
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Definition: qgslayertreemodel.cpp:97
QgsLayerTreeModel::mFontGroup
QFont mFontGroup
Definition: qgslayertreemodel.h:461
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
qgssettingsregistrycore.h
QgsLayerTreeModel::nodeLayerLoaded
void nodeLayerLoaded()
Definition: qgslayertreemodel.cpp:767
QgsLayerTreeModel::nodeWillRemoveChildren
void nodeWillRemoveChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Definition: qgslayertreemodel.cpp:725
QgsMapLayerLegendUtils::applyLayerNodeProperties
static void applyLayerNodeProperties(QgsLayerTreeLayer *nodeLayer, QList< QgsLayerTreeModelLegendNode * > &nodes)
update according to layer node's custom properties (order of items, user labels for items)
Definition: qgsmaplayerlegend.cpp:278
Qgis::RenderContextFlag::RenderSymbolPreview
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
QgsLayerTreeModel::mRootNode
QgsLayerTree * mRootNode
Pointer to the root node of the layer tree. Not owned by the model.
Definition: qgslayertreemodel.h:382
QgsLayerTreeModel::disconnectFromRootNode
void disconnectFromRootNode()
Definition: qgslayertreemodel.cpp:989
QgsLayerTreeNode
This class is a base class for nodes in a layer tree.
Definition: qgslayertreenode.h:75
QgsLayerTreeModel::currentIndex
QModelIndex currentIndex() const
Gets index of the item marked as current. Item marked as current is underlined.
Definition: qgslayertreemodel.cpp:535
qgsmaplayerstylemanager.h
QgsLayerTreeModelLegendNode::isEmbeddedInParent
virtual bool isEmbeddedInParent() const
Definition: qgslayertreemodellegendnode.h:116
qgsrasterlayer.h
QgsLayerTreeModel::legendNodeFlags
Qt::ItemFlags legendNodeFlags(QgsLayerTreeModelLegendNode *node) const
Definition: qgslayertreemodel.cpp:1543
QgsWkbTypes::displayString
static QString displayString(Type type) SIP_HOLDGIL
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
Definition: qgswkbtypes.cpp:145
QgsLayerTreeModel::nodeLayerWillBeUnloaded
void nodeLayerWillBeUnloaded()
Definition: qgslayertreemodel.cpp:777
QgsLayerTreeModel::addLegendToLayer
void addLegendToLayer(QgsLayerTreeLayer *nodeL)
Definition: qgslayertreemodel.cpp:1281
QgsLayerTreeModel::tryBuildLegendTree
LayerLegendTree * tryBuildLegendTree(const QList< QgsLayerTreeModelLegendNode * > &nodes)
Definition: qgslayertreemodel.cpp:1377
QgsLayerTreeModel::indexOfParentLayerTreeNode
QModelIndex indexOfParentLayerTreeNode(QgsLayerTreeNode *parentNode) const
Definition: qgslayertreemodel.cpp:147
QgsMapLayer::editingStopped
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
qgslayertreemodellegendnode.h
QgsLayerTreeGroup::removeChildren
void removeChildren(int from, int count)
Remove child nodes from index "from".
Definition: qgslayertreegroup.cpp:177
QgsLayerTreeModel::LayerLegendTree::children
QMap< QgsLayerTreeModelLegendNode *, QList< QgsLayerTreeModelLegendNode * > > children
List of children for each active node. Top-level nodes are under nullptr key. Pointers are not owned.
Definition: qgslayertreemodel.h:406
QgsLayerTreeModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: qgslayertreemodel.cpp:103
QgsLayerTreeNode::setItemVisibilityChecked
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
Definition: qgslayertreenode.cpp:95
QgsLayerTreeNode::removedChildren
void removedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes has been removed from a node within the tree.
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsLayerTreeModelLegendNode::invalidateMapBasedData
virtual void invalidateMapBasedData()
Notification from model that information from associated map view has changed.
Definition: qgslayertreemodellegendnode.h:166
QgsLayerTreeModelLegendNode::data
virtual QVariant data(int role) const =0
Returns data associated with the item. Must be implemented in derived class.
QgsMapLayerType::VectorLayer
@ VectorLayer
Vector layer.
QgsLayerTreeModel::filterLegendNodes
QList< QgsLayerTreeModelLegendNode * > filterLegendNodes(const QList< QgsLayerTreeModelLegendNode * > &nodes)
Filter nodes from QgsMapLayerLegend according to the current filtering rules.
Definition: qgslayertreemodel.cpp:1191
QgsLayerTreeLayer::layerLoaded
void layerLoaded()
Emitted when a previously unavailable layer got loaded.
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsLayerTreeModel::findLegendNode
QgsLayerTreeModelLegendNode * findLegendNode(const QString &layerId, const QString &ruleKey) const
Searches through the layer tree to find a legend node with a matching layer ID and rule key.
Definition: qgslayertreemodel.cpp:1589
QgsLayerTreeLayer::layerId
QString layerId() const
Returns the ID for the map layer associated with this node.
Definition: qgslayertreelayer.h:71
QgsLayerTreeModel::recursivelyEmitDataChanged
void recursivelyEmitDataChanged(const QModelIndex &index=QModelIndex())
emit dataChanged() for layer tree node items
Definition: qgslayertreemodel.cpp:996
QgsLayerTreeModel::mLegendMapViewMupp
double mLegendMapViewMupp
Definition: qgslayertreemodel.h:472
QgsMimeDataUtils::layerTreeNodesToUriList
static QByteArray layerTreeNodesToUriList(const QList< QgsLayerTreeNode * > &nodes)
Returns encoded URI list from a list of layer tree nodes.
Definition: qgsmimedatautils.cpp:267
QgsLayerTreeNode::NodeLayer
@ NodeLayer
Leaf node pointing to a layer.
Definition: qgslayertreenode.h:103
QgsVectorLayer::featureCount
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
Definition: qgsvectorlayer.cpp:812
QgsIconUtils::iconForLayer
static QIcon iconForLayer(const QgsMapLayer *layer)
Returns the icon corresponding to a specified map layer.
Definition: qgsiconutils.cpp:94
QgsMapLayer::properties
virtual Qgis::MapLayerProperties properties() const
Returns the map layer properties of this layer.
Definition: qgsmaplayer.cpp:164
QgsLayerTreeModel::layerTreeNodeFont
QFont layerTreeNodeFont(int nodeType) const
Gets font for a particular type of layer tree node. nodeType should come from QgsLayerTreeNode::NodeT...
Definition: qgslayertreemodel.cpp:571
QgsLayerTreeModel::AllowLegendChangeState
@ AllowLegendChangeState
Allow check boxes for legend nodes (if supported by layer's legend)
Definition: qgslayertreemodel.h:108
QgsLayerTreeModel::mLegend
QHash< QgsLayerTreeLayer *, LayerLegendData > mLegend
Per layer data about layer's legend nodes.
Definition: qgslayertreemodel.h:452
QgsLayerTreeModel::mimeData
QMimeData * mimeData(const QModelIndexList &indexes) const override
Definition: qgslayertreemodel.cpp:1043
QgsLayerTreeModel::legendEmbeddedInParent
bool legendEmbeddedInParent(QgsLayerTreeLayer *nodeLayer) const
Definition: qgslayertreemodel.cpp:1552
qgssymbollayerutils.h
QgsLayerTreeModel::parent
QModelIndex parent(const QModelIndex &child) const override
Definition: qgslayertreemodel.cpp:125
QgsMapSettings::hasValidSettings
bool hasValidSettings() const
Check whether the map settings are valid and can be used for rendering.
Definition: qgsmapsettings.cpp:406
QgsLayerTreeModel::nodeWillAddChildren
void nodeWillAddChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Definition: qgslayertreemodel.cpp:694
QgsMapLayerLegend
The QgsMapLayerLegend class is abstract interface for implementations of legends for one map layer.
Definition: qgsmaplayerlegend.h:47
QgsLayerTreeModelLegendNode::SimpleLegend
@ SimpleLegend
Simple label with icon legend node type.
Definition: qgslayertreemodellegendnode.h:91
QgsLayerTreeModel::mFlags
Flags mFlags
Sets of flags for the model.
Definition: qgslayertreemodel.h:384
QgsLayerTreeModel::mLegendFilterHitTest
std::unique_ptr< QgsMapHitTest > mLegendFilterHitTest
Definition: qgslayertreemodel.h:467
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsMapHitTest::LayerFilterExpression
QMap< QString, QString > LayerFilterExpression
Maps an expression string to a layer id.
Definition: qgsmaphittest.h:41
QgsLayerTreeModel::removeLegendFromLayer
void removeLegendFromLayer(QgsLayerTreeLayer *nodeLayer)
Definition: qgslayertreemodel.cpp:1270
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
QgsLayerTreeModel::setFlags
void setFlags(QgsLayerTreeModel::Flags f)
Sets OR-ed combination of model flags.
Definition: qgslayertreemodel.cpp:1163
QgsLayerTreeModel::testFlag
bool testFlag(Flag f) const
Check whether a flag is enabled.
Definition: qgslayertreemodel.cpp:1181
QgsLayerTreeModel::mLegendFilterMapSettings
std::unique_ptr< QgsMapSettings > mLegendFilterMapSettings
Definition: qgslayertreemodel.h:466
QgsLayerTreeModel::mFontLayer
QFont mFontLayer
Definition: qgslayertreemodel.h:460
QgsLayerTreeModel::mLegendFilterUsesExtent
bool mLegendFilterUsesExtent
whether to use map filtering
Definition: qgslayertreemodel.h:470
QgsLayerTreeNode::customPropertyChanged
void customPropertyChanged(QgsLayerTreeNode *node, const QString &key)
Emitted when a custom property of a node within the tree has been changed or removed.
QgsMapLayerLegend::createLayerTreeModelLegendNodes
virtual QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer)=0
Returns list of legend nodes to be used for a particular layer tree layer node.
QgsLayerTree::toLayer
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Definition: qgslayertree.h:88
QgsLayerTreeNode::nameChanged
void nameChanged(QgsLayerTreeNode *node, QString name)
Emitted when the name of the node is changed.
qgsmimedatautils.h
QgsLayerTreeLayer::name
QString name() const override
Returns the layer's name.
Definition: qgslayertreelayer.cpp:81
QgsLayerTreeModel::messageEmitted
void messageEmitted(const QString &message, Qgis::MessageLevel level=Qgis::MessageLevel::Info, int duration=5)
Emits a message than can be displayed to the user in a GUI class.
QgsLayerTreeModel::legendNodeEmbeddedInParent
QgsLayerTreeModelLegendNode * legendNodeEmbeddedInParent(QgsLayerTreeLayer *nodeLayer) const
Returns legend node that may be embedded in parent (i.e.
Definition: qgslayertreemodel.cpp:1557
QgsMapLayer::editingStarted
void editingStarted()
Emitted when editing on this layer has started.
QgsLayerTreeModel::nodeCustomPropertyChanged
void nodeCustomPropertyChanged(QgsLayerTreeNode *node, const QString &key)
Definition: qgslayertreemodel.cpp:760
QgsLayerTreeModel::ShowLegendAsTree
@ ShowLegendAsTree
For legends that support it, will show them in a tree instead of a list (needs also ShowLegend)....
Definition: qgslayertreemodel.h:99
QgsLayerTreeModel::legendNodeData
QVariant legendNodeData(QgsLayerTreeModelLegendNode *node, int role) const
Definition: qgslayertreemodel.cpp:1535
QgsMapLayer::legend
QgsMapLayerLegend * legend() const
Can be nullptr.
Definition: qgsmaplayer.cpp:2087
QgsLayerTreeModel::layerLegendChanged
void layerLegendChanged()
Definition: qgslayertreemodel.cpp:789
QgsLayerTreeModel::disconnectFromLayer
void disconnectFromLayer(QgsLayerTreeLayer *nodeLayer)
Definition: qgslayertreemodel.cpp:931
QgsMapLayerStyleOverride
Restore overridden layer style on destruction.
Definition: qgsmaplayerstyle.h:81
QgsLayerTreeNode::setItemVisibilityCheckedParentRecursive
void setItemVisibilityCheckedParentRecursive(bool checked)
Check or uncheck a node and all its parents.
Definition: qgslayertreenode.cpp:108
QgsLayerTreeModel::ActionHierarchical
@ ActionHierarchical
Check/uncheck action has consequences on children (or parents for leaf node)
Definition: qgslayertreemodel.h:109
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsLayerTree::toGroup
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
Definition: qgslayertree.h:77
QgsLayerTreeModel::AllowNodeRename
@ AllowNodeRename
Allow renaming of groups and layers.
Definition: qgslayertreemodel.h:106
QgsLayerTreeModel::disconnectFromLayers
void disconnectFromLayers(QgsLayerTreeGroup *parentGroup)
Definition: qgslayertreemodel.cpp:962
QgsGuiUtils::iconSize
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
Definition: qgsguiutils.cpp:264
QgsApplication::getThemePixmap
static QPixmap getThemePixmap(const QString &name, const QColor &foreColor=QColor(), const QColor &backColor=QColor(), int size=16)
Helper to get a theme icon as a pixmap.
Definition: qgsapplication.cpp:827
QgsLayerTreeNode::nodeType
NodeType nodeType() const
Find out about type of the node. It is usually shorter to use convenience functions from QgsLayerTree...
Definition: qgslayertreenode.h:117
QgsLayerTreeModelLegendNode::sizeChanged
void sizeChanged()
Emitted when the size of this node changes.
qgsapplication.h
QgsLayerTreeModelLegendNode::flags
virtual Qt::ItemFlags flags() const
Returns item flags associated with the item. Default implementation returns Qt::ItemIsEnabled.
Definition: qgslayertreemodellegendnode.cpp:57
QgsLayerTreeModel::scaleIconSize
static int scaleIconSize(int standardSize)
Scales an layer tree model icon size to compensate for display pixel density, making the icon size hi...
Definition: qgslayertreemodel.cpp:689
QgsLayerTreeModel::legendNodeDataChanged
void legendNodeDataChanged()
Definition: qgslayertreemodel.cpp:843
QgsLayerTreeModel::dropMimeData
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
Definition: qgslayertreemodel.cpp:1081
QgsLayerTreeModel::layerNeedsUpdate
void layerNeedsUpdate()
Definition: qgslayertreemodel.cpp:825
QgsLayerTreeModel::removeRows
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Definition: qgslayertreemodel.cpp:1152
QgsLayerTreeModel::createTemporaryRenderContext
QgsRenderContext * createTemporaryRenderContext() const
Returns a temporary render context.
Definition: qgslayertreemodel.cpp:1417
QgsMapHitTest
Class that runs a hit test with given map settings. Based on the hit test it returns which symbols wi...
Definition: qgsmaphittest.h:37
QgsLayerTreeModel::legendNode2index
QModelIndex legendNode2index(QgsLayerTreeModelLegendNode *legendNode)
Returns index for a given legend node.
Definition: qgslayertreemodel.cpp:1441
QgsLayerTreeModel::node2index
QModelIndex node2index(QgsLayerTreeNode *node) const
Returns index for a given node. If the node does not belong to the layer tree, the result is undefine...
Definition: qgslayertreemodel.cpp:429
QgsSettingsRegistryCore::settingsLayerTreeShowFeatureCountForNewLayers
static const QgsSettingsEntryBool settingsLayerTreeShowFeatureCountForNewLayers
Settings entry show feature counts for newly added layers by default.
Definition: qgssettingsregistrycore.h:175
QgsMapLayer::isInScaleRange
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
Definition: qgsmaplayer.cpp:832
QgsLayerTreeModel::index2legendNode
static QgsLayerTreeModelLegendNode * index2legendNode(const QModelIndex &index)
Returns legend node for given index.
Definition: qgslayertreemodel.cpp:1435
QgsMapLayer::isModified
virtual bool isModified() const
Returns true if the layer has been modified since last commit/save.
Definition: qgsmaplayer.cpp:2026
QgsLayerTreeModelLegendNode::EmbeddedWidget
@ EmbeddedWidget
Embedded widget placeholder node type.
Definition: qgslayertreemodellegendnode.h:97
QgsLayerTree
Namespace with helper functions for layer tree operations.
Definition: qgslayertree.h:32
QgsLayerTreeModel::~QgsLayerTreeModel
~QgsLayerTreeModel() override
Definition: qgslayertreemodel.cpp:62
QgsLayerTreeModel::setLayerTreeNodeFont
void setLayerTreeNodeFont(int nodeType, const QFont &font)
Sets font for a particular type of layer tree node. nodeType should come from QgsLayerTreeNode::NodeT...
Definition: qgslayertreemodel.cpp:546
QgsLayerTreeModel::nodeAddedChildren
void nodeAddedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Definition: qgslayertreemodel.cpp:714
QgsLayerTreeModel::layerStyleOverrides
QMap< QString, QString > layerStyleOverrides() const
Gets map of map layer style overrides (key: layer ID, value: style name) where a different style shou...
Definition: qgslayertreemodel.cpp:679
QgsLayerTreeModelLegendNode::NodeTypeRole
@ NodeTypeRole
Type of node. Added in 3.16.
Definition: qgslayertreemodellegendnode.h:85
QgsLayerTreeModel::Flag
Flag
Definition: qgslayertreemodel.h:95
QgsLayerTreeModel::mCurrentIndex
QPersistentModelIndex mCurrentIndex
Current index - will be underlined.
Definition: qgslayertreemodel.h:386
QgsLayerTreeModel::connectToLayers
void connectToLayers(QgsLayerTreeGroup *parentGroup)
Definition: qgslayertreemodel.cpp:950
QgsLayerTreeModel::legendParent
QModelIndex legendParent(QgsLayerTreeModelLegendNode *legendNode) const
Definition: qgslayertreemodel.cpp:1515
QgsLayerTreeModelLegendNode::ImageLegend
@ ImageLegend
Raster image legend node type.
Definition: qgslayertreemodellegendnode.h:94
QgsLayerTreeLayer::setName
void setName(const QString &n) override
Sets the layer's name.
Definition: qgslayertreelayer.cpp:86
QgsLayerTreeModel::DeferredLegendInvalidation
@ DeferredLegendInvalidation
Defer legend model invalidation.
Definition: qgslayertreemodel.h:100
QgsLayerTreeModel::setLegendFilterByScale
void setLegendFilterByScale(double scale)
Force only display of legend nodes which are valid for a given scale.
Definition: qgslayertreemodel.cpp:584
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2265
QgsLayerTreeModel::mDeferLegendInvalidationTimer
QTimer mDeferLegendInvalidationTimer
Definition: qgslayertreemodel.h:475
QgsLayerTreeModel::refreshLayerLegend
void refreshLayerLegend(QgsLayerTreeLayer *nodeLayer)
Force a refresh of legend nodes of a layer node.
Definition: qgslayertreemodel.cpp:512
QgsLayerTreeModelLegendNode::DataDefinedSizeLegend
@ DataDefinedSizeLegend
Marker symbol legend node type.
Definition: qgslayertreemodellegendnode.h:96
QgsLayerTreeModelLegendNode::ColorRampLegend
@ ColorRampLegend
Color ramp legend (since QGIS 3.18)
Definition: qgslayertreemodellegendnode.h:98
QgsLayerTreeModel::legendNodeIndex
QModelIndex legendNodeIndex(int row, int column, QgsLayerTreeModelLegendNode *node) const
Definition: qgslayertreemodel.cpp:1505
QgsLayerTreeLayer
Layer tree node points to a map layer.
Definition: qgslayertreelayer.h:43
qgsmaplayer.h
QgsLayerTreeModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: qgslayertreemodel.cpp:77
QgsLayerTreeNode::writeXml
virtual void writeXml(QDomElement &parentElement, const QgsReadWriteContext &context)=0
Write layer tree to XML.
QgsSymbolLegendNode::setIconSize
void setIconSize(QSize sz)
Set the icon size.
Definition: qgslayertreemodellegendnode.h:395
QgsLayerTreeModel::LayerLegendData
Structure that stores all data associated with one map layer.
Definition: qgslayertreemodel.h:415
QgsLayerTreeModel::mLegendFilterByScale
double mLegendFilterByScale
scale denominator for filtering of legend nodes (<= 0 means no filtering)
Definition: qgslayertreemodel.h:464
QgsLayerTreeGroup
Layer tree group node serves as a container for layers and further groups.
Definition: qgslayertreegroup.h:40
QgsLayerTreeModel::setLegendFilterByMap
void setLegendFilterByMap(const QgsMapSettings *settings)
Force only display of legend nodes which are valid for given map settings.
Definition: qgslayertreemodel.cpp:595
QgsLayerTreeModel::LayerLegendTree
Structure that stores tree representation of map layer's legend.
Definition: qgslayertreemodel.h:401
QgsLayerTreeGroup::setName
void setName(const QString &n) override
Sets the group's name.
Definition: qgslayertreegroup.cpp:58
QgsLayerTreeGroup::insertChildNodes
void insertChildNodes(int index, const QList< QgsLayerTreeNode * > &nodes)
Insert existing nodes at specified position.
Definition: qgslayertreegroup.cpp:113
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
QgsMapLayer::title
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:310
QgsLayerTreeModel::setAutoCollapseLegendNodes
void setAutoCollapseLegendNodes(int nodeCount)
Sets at what number of legend nodes the layer node should be collapsed. Setting -1 disables the auto-...
Definition: qgslayertreemodel.h:208
QgsLayerTreeModel::LayerLegendTree::parents
QMap< QgsLayerTreeModelLegendNode *, QgsLayerTreeModelLegendNode * > parents
Pointer to parent for each active node. Top-level nodes have nullptr parent. Pointers are not owned.
Definition: qgslayertreemodel.h:404
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:127
QgsLayerTreeModelLegendNode::NodeTypes
NodeTypes
Types of legend nodes.
Definition: qgslayertreemodellegendnode.h:89
QgsLayerTreeModelLegendNode::ParentRuleKeyRole
@ ParentRuleKeyRole
Rule key of the parent legend node - for legends with tree hierarchy (QString). Added in 2....
Definition: qgslayertreemodellegendnode.h:84
QgsLayerTreeModel::refreshScaleBasedLayers
void refreshScaleBasedLayers(const QModelIndex &index=QModelIndex(), double previousScale=0.0)
Updates layer data for scale dependent layers, should be called when map scale changes.
Definition: qgslayertreemodel.cpp:1010
QgsMapLayer::layerModified
void layerModified()
Emitted when modifications has been done on layer.
QgsMapLayer::hasScaleBasedVisibility
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
Definition: qgsmaplayer.cpp:839
qgsrenderer.h
QgsLayerTreeLayer::layer
QgsMapLayer * layer() const
Returns the map layer associated with this node.
Definition: qgslayertreelayer.h:82
qgslayertree.h
QgsLayerTreeModel::supportedDropActions
Qt::DropActions supportedDropActions() const override
Definition: qgslayertreemodel.cpp:1030
QgsLayerTreeModel::setRootGroup
void setRootGroup(QgsLayerTree *newRootGroup)
Reset the model and use a new root group node.
Definition: qgslayertreemodel.cpp:497
QgsLayerTreeModel::legendIconEmbeddedInParent
QIcon legendIconEmbeddedInParent(QgsLayerTreeLayer *nodeLayer) const
Definition: qgslayertreemodel.cpp:1563
QgsLayerTreeModelLegendNode::RasterSymbolLegend
@ RasterSymbolLegend
Raster symbol legend node type.
Definition: qgslayertreemodellegendnode.h:93
QgsLayerTreeNode::readXml
static QgsLayerTreeNode * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read layer tree from XML.
Definition: qgslayertreenode.cpp:68
QgsLayerTreeModel::autoCollapseLegendNodes
int autoCollapseLegendNodes() const
Returns at what number of legend nodes the layer node should be collapsed. -1 means no auto-collapse ...
Definition: qgslayertreemodel.h:210
QgsLayerTreeModel::rootGroup
QgsLayerTree * rootGroup() const
Returns pointer to the root node of the layer tree. Always a non nullptr value.
Definition: qgslayertreemodel.cpp:492
QgsWms::legendNode
QgsLayerTreeModelLegendNode * legendNode(const QString &rule, QgsLayerTreeModel &model)
Definition: qgswmsgetlegendgraphics.cpp:363
QgsMapLayer::legendChanged
void legendChanged()
Signal emitted when legend of the layer has changed.
qgsmeshlayer.h
qgsvectorlayer.h
QgsLayerTreeLayer::layerWillBeUnloaded
void layerWillBeUnloaded()
Emitted when a previously available layer got unloaded (from layer registry).
qgslayerdefinition.h
QgsLayerTreeModel::index2node
QgsLayerTreeNode * index2node(const QModelIndex &index) const
Returns layer tree node for given index.
Definition: qgslayertreemodel.cpp:67
QgsLayerTreeModel::legendMapViewData
void legendMapViewData(double *mapUnitsPerPixel, int *dpi, double *scale) const
Gets hints about map view - to be used in legend nodes.
Definition: qgslayertreemodel.cpp:672
QgsLayerTreeNode::willAddChildren
void willAddChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes will be added to a node within the tree.
QgsLayerTreeNode::setItemVisibilityCheckedRecursive
virtual void setItemVisibilityCheckedRecursive(bool checked)
Check or uncheck a node and all its children (taking into account exclusion rules)
Definition: qgslayertreenode.cpp:103
QgsLayerTreeModelLegendNode::setData
virtual bool setData(const QVariant &value, int role)
Sets some data associated with the item. Default implementation does nothing and returns false.
Definition: qgslayertreemodellegendnode.cpp:62
QgsLayerDefinition::loadLayerDefinition
static bool loadLayerDefinition(const QString &path, QgsProject *project, QgsLayerTreeGroup *rootGroup, QString &errorMessage)
Loads the QLR at path into QGIS. New layers are added to given project into layer tree specified by r...
Definition: qgslayerdefinition.cpp:40
QgsLayerTreeModel::legendNodeRowCount
int legendNodeRowCount(QgsLayerTreeModelLegendNode *node) const
Definition: qgslayertreemodel.cpp:1470
QgsLayerTree::isLayer
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
Definition: qgslayertree.h:66
QgsLayerTreeModelLegendNode::layerNode
QgsLayerTreeLayer * layerNode() const
Returns pointer to the parent layer node.
Definition: qgslayertreemodellegendnode.h:102
QgsMapLayer::customProperty
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
Definition: qgsmaplayer.cpp:1999
QgsLayerTreeModel::mimeTypes
QStringList mimeTypes() const override
Definition: qgslayertreemodel.cpp:1035
QgsLayerTreeModel::mLegendMapViewScale
double mLegendMapViewScale
Definition: qgslayertreemodel.h:474
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsLayerTreeModel::setFlag
void setFlag(Flag f, bool on=true)
Enable or disable a model flag.
Definition: qgslayertreemodel.cpp:1168
QgsMapToPixel
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:38
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
QgsLayerTreeModel::layerFlagsChanged
void layerFlagsChanged()
Emitted when layer flags have changed.
Definition: qgslayertreemodel.cpp:808
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsLayerTreeModel::legendRootIndex
QModelIndex legendRootIndex(int row, int column, QgsLayerTreeLayer *nL) const
Definition: qgslayertreemodel.cpp:1494
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
QgsLayerTreeModel::flags
Flags flags() const
Returns OR-ed combination of model flags.
Definition: qgslayertreemodel.cpp:1176
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsLayerDefinition::exportLayerDefinition
static bool exportLayerDefinition(const QString &path, const QList< QgsLayerTreeNode * > &selectedTreeNodes, QString &errorMessage)
Exports the selected layer tree nodes to a QLR file.
Definition: qgslayerdefinition.cpp:202
QgsApplication::scaleIconSize
static int scaleIconSize(int standardSize, bool applyDevicePixelRatio=false)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
Definition: qgsapplication.cpp:1980
QgsLayerTreeModel::mLegendMapViewDpi
int mLegendMapViewDpi
Definition: qgslayertreemodel.h:473
QgsLayerTreeModel::mLayerStyleOverrides
QMap< QString, QString > mLayerStyleOverrides
Overrides of map layers' styles: key = layer ID, value = style XML.
Definition: qgslayertreemodel.h:449
QgsLayerTreeModel::UseTextFormatting
@ UseTextFormatting
Layer nodes will alter text appearance based on layer properties, such as scale based visibility.
Definition: qgslayertreemodel.h:102
QgsLayerTreeModel::legendCleanup
void legendCleanup()
Definition: qgslayertreemodel.cpp:1258
QgsLayerTreeNode::children
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
Definition: qgslayertreenode.h:121
QgsLayerTreeModel::setLegendFilter
void setLegendFilter(const QgsMapSettings *settings, bool useExtent=true, const QgsGeometry &polygon=QgsGeometry(), bool useExpressions=true)
Filter display of legend nodes for given map settings.
Definition: qgslayertreemodel.cpp:600
QgsSymbolLegendNode::data
QVariant data(int role) const override
Returns data associated with the item. Must be implemented in derived class.
Definition: qgslayertreemodellegendnode.cpp:502
QgsLayerTreeModel::setLegendMapViewData
void setLegendMapViewData(double mapUnitsPerPixel, int dpi, double scale)
Give the layer tree model hints about the currently associated map view so that legend nodes that use...
Definition: qgslayertreemodel.cpp:655
qgsmaplayerlegend.h
qgsiconutils.h
qgspluginlayer.h
QgsLayerTreeGroup::name
QString name() const override
Returns the group's name.
Definition: qgslayertreegroup.cpp:53
qgslayertreeutils.h
QgsLayerTreeNode::addedChildren
void addedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes have been added to a node within the tree.
QgsLayerTreeModel::mAutoCollapseLegendNodesCount
int mAutoCollapseLegendNodesCount
Minimal number of nodes when legend should be automatically collapsed. -1 = disabled.
Definition: qgslayertreemodel.h:388
QgsMapLayerStyleOverride::setOverrideStyle
void setOverrideStyle(const QString &style)
Temporarily apply a different style to the layer.
Definition: qgsmaplayerstyle.cpp:110
QgsLayerTreeModel::iconGroup
static QIcon iconGroup()
Definition: qgslayertreemodel.cpp:1186
qgslayertreemodel.h
QgsLayerTreeModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Definition: qgslayertreemodel.cpp:365
QgsLayerTreeNode::parent
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
Definition: qgslayertreenode.h:119
QgsLayerTreeModel::AllowNodeChangeVisibility
@ AllowNodeChangeVisibility
Allow user to set node visibility with a checkbox.
Definition: qgslayertreemodel.h:107
QgsLayerTreeModel::nodeRemovedChildren
void nodeRemovedChildren()
Definition: qgslayertreemodel.cpp:737
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Definition: qgsapplication.cpp:693
QgsLayerTreeModel::invalidateLegendMapBasedData
void invalidateLegendMapBasedData()
Definition: qgslayertreemodel.cpp:1619
QgsLayerTreeNode::willRemoveChildren
void willRemoveChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes will be removed from a node within the tree.
QgsLayerTreeModel::AllowNodeReorder
@ AllowNodeReorder
Allow reordering with drag'n'drop.
Definition: qgslayertreemodel.h:105
Qgis::MapLayerProperty::UsersCannotToggleEditing
@ UsersCannotToggleEditing
Indicates that users are not allowed to toggle editing for this layer. Note that this does not imply ...
QgsSymbolLegendNode::minimumIconSize
QSize minimumIconSize() const
Calculates the minimum icon size to prevent cropping.
Definition: qgslayertreemodellegendnode.cpp:335
QgsLayerTreeModel::connectToRootNode
void connectToRootNode()
Definition: qgslayertreemodel.cpp:974
QgsMapLayer::isSpatial
virtual bool isSpatial() const
Returns true if the layer is considered a spatial layer, ie it has some form of geometry associated w...
Definition: qgsmaplayer.cpp:2031
QgsLayerTreeModel::nodeVisibilityChanged
void nodeVisibilityChanged(QgsLayerTreeNode *node)
Definition: qgslayertreemodel.cpp:742
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
QgsLayerTreeModel::layerLegendNodes
QList< QgsLayerTreeModelLegendNode * > layerLegendNodes(QgsLayerTreeLayer *nodeLayer, bool skipNodeEmbeddedInParent=false)
Returns filtered list of active legend nodes attached to a particular layer node (by default it retur...
Definition: qgslayertreemodel.cpp:1572
QgsLayerTreeModel::data
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Definition: qgslayertreemodel.cpp:162
QgsLayerTreeModel::ShowLegend
@ ShowLegend
Add legend nodes for layer nodes.
Definition: qgslayertreemodel.h:98
QgsMapSettings
The QgsMapSettings class contains configuration for rendering of the map. The rendering itself is don...
Definition: qgsmapsettings.h:88
QgsLayerTreeModel::nodeNameChanged
void nodeNameChanged(QgsLayerTreeNode *node, const QString &name)
Updates model when node's name has changed.
Definition: qgslayertreemodel.cpp:750
QgsLayerTreeUtils::legendFilterByExpression
static QString legendFilterByExpression(const QgsLayerTreeLayer &layer, bool *enabled=nullptr)
Returns the expression filter of a legend layer.
Definition: qgslayertreeutils.cpp:433
qgsmaphittest.h
QgsSymbolLegendNode
Implementation of legend node interface for displaying preview of vector symbols and their labels and...
Definition: qgslayertreemodellegendnode.h:358
QgsLayerTreeModel::QgsLayerTreeModel
QgsLayerTreeModel(QgsLayerTree *rootNode, QObject *parent=nullptr)
Construct a new tree model with given layer tree (root node must not be nullptr).
Definition: qgslayertreemodel.cpp:43
QgsLayerTreeModelLegendNode::RuleKeyRole
@ RuleKeyRole
Rule key of the node (QString)
Definition: qgslayertreemodellegendnode.h:83
QgsLayerTreeNode::setExpanded
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
Definition: qgslayertreenode.cpp:198
QgsLayerTreeModel::legendRootRowCount
int legendRootRowCount(QgsLayerTreeLayer *nL) const
Definition: qgslayertreemodel.cpp:1480
QgsGeometry::type
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:128
QgsLayerTree::isGroup
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
Definition: qgslayertree.h:56
QgsLayerTreeModel::legendInvalidateMapBasedData
void legendInvalidateMapBasedData()
Definition: qgslayertreemodel.cpp:1611
QgsLayerTreeModel::connectToLayer
void connectToLayer(QgsLayerTreeLayer *nodeLayer)
Definition: qgslayertreemodel.cpp:866
QgsLayerTreeModelLegendNode::dataChanged
void dataChanged()
Emitted on internal data change so the layer tree model can forward the signal to views.
QgsLayerTreeModel::UseEmbeddedWidgets
@ UseEmbeddedWidgets
Layer nodes may optionally include extra embedded widgets (if used in QgsLayerTreeView)....
Definition: qgslayertreemodel.h:101
QgsLayerTreeModel::mInvalidatedNodes
QSet< QgsLayerTreeLayer * > mInvalidatedNodes
Keep track of layer nodes for which the legend size needs to be recalculated.
Definition: qgslayertreemodel.h:458
QgsLayerTreeModel::setCurrentIndex
void setCurrentIndex(const QModelIndex &currentIndex)
Sets index of the current item. May be used by view. Item marked as current is underlined.
Definition: qgslayertreemodel.cpp:540
qgsproject.h
QgsLayerTreeModelLegendNode::SymbolLegend
@ SymbolLegend
Vector symbol legend node type.
Definition: qgslayertreemodellegendnode.h:92
QgsLayerTreeModel::indexes2nodes
QList< QgsLayerTreeNode * > indexes2nodes(const QModelIndexList &list, bool skipInternal=false) const
Convert a list of indexes to a list of layer tree nodes.
Definition: qgslayertreemodel.cpp:465
QgsSettingsEntryByValue::value
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
Definition: qgssettingsentry.h:520
QgsLayerTreeNode::visibilityChanged
void visibilityChanged(QgsLayerTreeNode *node)
Emitted when check state of a node within the tree has been changed.
QgsLayerTreeModelLegendNode::WmsLegend
@ WmsLegend
WMS legend node type.
Definition: qgslayertreemodellegendnode.h:95
QgsLayerTreeModel::layerOriginalLegendNodes
QList< QgsLayerTreeModelLegendNode * > layerOriginalLegendNodes(QgsLayerTreeLayer *nodeLayer)
Returns original (unfiltered) list of legend nodes attached to a particular layer node.
Definition: qgslayertreemodel.cpp:1584
QgsMapLayer::type
QgsMapLayerType type
Definition: qgsmaplayer.h:80
QgsLayerTreeModelLegendNode
The QgsLegendRendererItem class is abstract interface for legend items returned from QgsMapLayerLegen...
Definition: qgslayertreemodellegendnode.h:49