29#include <QApplication> 
   31#include <QContextMenuEvent> 
   36#ifdef ENABLE_MODELTEST 
   46  , mBlockDoubleClickTimer( new QTimer( this ) )
 
   49  mBlockDoubleClickTimer->setSingleShot( 
true );
 
   50  mBlockDoubleClickTimer->setInterval( QApplication::doubleClickInterval() );
 
   51  setHeaderHidden( 
true );
 
   53  setDragEnabled( 
true );
 
   54  setAcceptDrops( 
true );
 
   55  setDropIndicatorShown( 
true );
 
   56  setEditTriggers( EditKeyPressed );
 
   57  setExpandsOnDoubleClick( 
false ); 
 
   60  header()->setStretchLastSection( 
false );
 
   61  header()->setSectionResizeMode( QHeaderView::ResizeToContents );
 
   64  setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
 
   66  setSelectionMode( ExtendedSelection );
 
   67  setDefaultDropAction( Qt::MoveAction );
 
   71  setStyle( 
new QgsLayerTreeViewProxyStyle( 
this ) );
 
   78  connect( horizontalScrollBar(), &QScrollBar::valueChanged, 
this, &QgsLayerTreeView::onHorizontalScroll );
 
 
   84  delete mBlockDoubleClickTimer;
 
 
  109#ifdef ENABLE_MODELTEST 
  110  new ModelTest( mProxyModel, 
this );
 
  115  QTreeView::setModel( mProxyModel );
 
  124  connect( treeModel, &QAbstractItemModel::dataChanged, 
this, &QgsLayerTreeView::onDataChanged );
 
 
  133  return mProxyModel ? qobject_cast<QgsLayerTreeModel *>( mProxyModel->sourceModel() ) : 
nullptr;
 
 
  158    setCurrentIndex( QModelIndex() );
 
 
  169    setCurrentIndex( QModelIndex() );
 
 
  195  const QModelIndex idx = indexAt( event->pos() );
 
  196  if ( !idx.isValid() )
 
  197    setCurrentIndex( QModelIndex() );
 
  204    if ( menu->actions().count() != 0 )
 
  205      menu->exec( mapToGlobal( event->pos() ) );
 
 
  223      const int widgetsCount = layer->customProperty( QStringLiteral( 
"embeddedWidgets/count" ), 0 ).toInt();
 
  225      for ( 
int i = 0; i < widgetsCount; ++i )
 
  227        const QString providerId = layer->customProperty( QStringLiteral( 
"embeddedWidgets/%1/id" ).arg( i ) ).toString();
 
  231          QWidget *wdgt = provider->createWidget( layer, i );
 
  248          setIndexWidget( index, wdgt );
 
  258    const QStringList expandedNodeKeys = parentNode->
customProperty( QStringLiteral( 
"expandedLegendNodes" ) ).toStringList();
 
  259    if ( expandedNodeKeys.isEmpty() )
 
  266      if ( expandedNodeKeys.contains( ruleKey ) )
 
  272  QList<QgsLayerTreeNode *> children = parentNode->
children();
 
  273  for ( 
int i = start; i <= end && i < children.count(); ++i )
 
 
  292    node->setExpanded( isExpanded( index ) );
 
  297    QStringList lst = node->layerNode()->customProperty( QStringLiteral( 
"expandedLegendNodes" ) ).toStringList();
 
  298    const bool expanded = isExpanded( index );
 
  299    const bool isInList = lst.contains( ruleKey );
 
  300    if ( expanded && !isInList )
 
  302      lst.append( ruleKey );
 
  303      node->layerNode()->setCustomProperty( QStringLiteral( 
"expandedLegendNodes" ), lst );
 
  305    else if ( !expanded && isInList )
 
  307      lst.removeAll( ruleKey );
 
  308      node->layerNode()->setCustomProperty( QStringLiteral( 
"expandedLegendNodes" ), lst );
 
 
  316  const QString layerCurrentID = layerCurrent ? layerCurrent->
id() : QString();
 
  321  QModelIndex proxyModelNodeLayerIndex;
 
  326      proxyModelNodeLayerIndex = 
node2index( nodeLayer );
 
  329  if ( ! proxyModelNodeLayerIndex.isValid() )
 
 
  348  if ( isExpanded( idx ) != expanded )
 
  349    setExpanded( idx, expanded );
 
 
  352void QgsLayerTreeView::onCustomPropertyChanged( 
QgsLayerTreeNode *node, 
const QString &key )
 
  357  const QSet<QString> expandedLegendNodes = qgis::listToSet( node->
customProperty( QStringLiteral( 
"expandedLegendNodes" ) ).toStringList() );
 
  363    if ( !key.isEmpty() )
 
  364      setExpanded( 
legendNode2index( legendNode ), expandedLegendNodes.contains( key ) );
 
  379  const auto constChildren = node->
children();
 
 
  408  return index2node( selectionModel()->currentIndex() );
 
 
  440  QModelIndexList mapped;
 
  441  const QModelIndexList selected = selectionModel()->selectedIndexes();
 
  442  mapped.reserve( selected.size() );
 
  443  for ( 
const QModelIndex &index : selected )
 
  444    mapped << mProxyModel->mapToSource( index );
 
 
  451  QList<QgsLayerTreeLayer *> layerNodes;
 
  452  const QList<QgsLayerTreeNode *> constSelectedNodes = 
selectedNodes();
 
  453  layerNodes.reserve( constSelectedNodes.size() );
 
 
  464  QList<QgsMapLayer *> list;
 
  466  list.reserve( constSelectedLayerNodes.size() );
 
  470      list << node->layer();
 
 
  477  QList<QgsLayerTreeModelLegendNode *> res;
 
  478  const QModelIndexList selected = selectionModel()->selectedIndexes();
 
  479  res.reserve( selected.size() );
 
  480  for ( 
const QModelIndex &index : selected )
 
  482    const QModelIndex &modelIndex = mProxyModel->mapToSource( index );
 
  485      res.push_back( node );
 
 
  494  QModelIndexList mapped;
 
  495  const QModelIndexList selected = selectionModel()->selectedIndexes();
 
  496  mapped.reserve( selected.size() );
 
  497  for ( 
const QModelIndex &index : selected )
 
  498    mapped << mProxyModel->mapToSource( index );
 
  502  return qgis::setToList( layersSet );
 
 
  513      viewport()->repaint();
 
  516    viewport()->repaint(); 
 
 
  532QStringList QgsLayerTreeView::viewOnlyCustomProperties()
 
  534  return QStringList() << QStringLiteral( 
"expandedLegendNodes" );
 
  553    const auto constLayerLegendNodes = model->
layerLegendNodes( nodeLayer, 
true );
 
  557      if ( !parentKey.isEmpty() && !lst.contains( parentKey ) )
 
  567  const auto constChildren = parent->
children();
 
  595  if ( mMessageBar == messageBar )
 
  598  mMessageBar = messageBar;
 
 
  612  mShowPrivateLayers = showPrivate;
 
 
  618  mHideValidLayers = hideValid;
 
 
  624  return mShowPrivateLayers;
 
 
  629  return mHideValidLayers;
 
 
  634  if ( mBlockDoubleClickTimer->isActive() )
 
  637    QTreeView::mouseDoubleClickEvent( event );
 
 
  647  if ( event->modifiers() & Qt::ControlModifier )
 
  651  QTreeView::mouseReleaseEvent( event );
 
 
  657  if ( event->key() == Qt::Key_Space )
 
  659    const QList<QgsLayerTreeNode *> constSelectedNodes = 
selectedNodes();
 
  661    if ( !constSelectedNodes.isEmpty() )
 
  663      const bool isFirstNodeChecked = constSelectedNodes[0]->itemVisibilityChecked();
 
  675  if ( event->modifiers() & Qt::ControlModifier )
 
  679  QTreeView::keyPressEvent( event );
 
 
  685  if ( event->mimeData()->hasUrls() || event->mimeData()->hasFormat( QStringLiteral( 
"application/x-vnd.qgis.qgis.uri" ) ) )
 
  688    if ( !event->mimeData()->hasFormat( QStringLiteral( 
"application/qgis.layertreemodeldata" ) ) )
 
  694  QTreeView::dragEnterEvent( event );
 
 
  699  if ( event->mimeData()->hasUrls() || event->mimeData()->hasFormat( QStringLiteral( 
"application/x-vnd.qgis.qgis.uri" ) ) )
 
  702    if ( !event->mimeData()->hasFormat( QStringLiteral( 
"application/qgis.layertreemodeldata" ) ) )
 
  708  QTreeView::dragMoveEvent( event );
 
 
  713  if ( event->mimeData()->hasUrls() || event->mimeData()->hasFormat( QStringLiteral( 
"application/x-vnd.qgis.qgis.uri" ) ) )
 
  716    if ( !event->mimeData()->hasFormat( QStringLiteral( 
"application/qgis.layertreemodeldata" ) ) )
 
  720      QModelIndex index = indexAt( event->pos() );
 
  721      if ( index.isValid() )
 
  723        setCurrentIndex( index );
 
  730  if ( event->keyboardModifiers() & Qt::AltModifier || event->keyboardModifiers() & Qt::ControlModifier )
 
  734  QTreeView::dropEvent( event );
 
 
  747  header()->setMinimumSectionSize( viewport()->width() );
 
  748  QTreeView::resizeEvent( event );
 
 
  751void QgsLayerTreeView::onHorizontalScroll( 
int value )
 
  754  viewport()->update();
 
  757void QgsLayerTreeView::onDataChanged( 
const QModelIndex &topLeft, 
const QModelIndex &bottomRight, 
const QVector<int> &roles )
 
  760  Q_UNUSED( bottomRight )
 
  766  if ( roles.contains( Qt::SizeHintRole ) )
 
  767    viewport()->update();
 
  769  mBlockDoubleClickTimer->start();
 
  775void QgsLayerTreeView::checkModel()
 
  781      qDebug() << 
"----------------------------------------------";
 
  788    for ( 
int i = 0; i < mProxyModel->rowCount( 
node2index( node ) ); i++ )
 
  792        debug( childNode, depth + 1 );
 
  794        qDebug() << 
"Warning no child node!";
 
  837  : QSortFilterProxyModel( parent )
 
  838  , mLayerTreeModel( treeModel )
 
  840  setSourceModel( treeModel );
 
 
  845  if ( filterText == mFilterText )
 
  848  mFilterText = filterText;
 
 
  855  return nodeShown( node );
 
 
  872    if ( !mFilterText.isEmpty() && !layer->
name().contains( mFilterText, Qt::CaseInsensitive ) )
 
  878    if ( mHideValidLayers && layer->
isValid() )
 
  887  return mShowPrivateLayers;
 
 
  892  if ( showPrivate == mShowPrivateLayers )
 
  895  mShowPrivateLayers = showPrivate;
 
 
  901  return mHideValidLayers;
 
 
  906  if ( hideValid == mHideValidLayers )
 
  909  mHideValidLayers = hideValid;
 
 
MessageLevel
Level for messages This will be used both for message log and message bar in application.
 
@ Info
Information message.
 
static const double UI_SCALE_FACTOR
UI scaling factor.
 
static QgsLayerTreeEmbeddedWidgetRegistry * layerTreeEmbeddedWidgetRegistry()
Returns the global layer tree embedded widget registry, used for registering widgets that may be embe...
 
Layer tree group node serves as a container for layers and further groups.
 
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
 
Layer tree node points to a map layer.
 
QgsMapLayer * layer() const
Returns the map layer associated with this node.
 
The QgsLegendRendererItem class is abstract interface for legend items returned from QgsMapLayerLegen...
 
virtual QVariant data(int role) const =0
Returns data associated with the item. Must be implemented in derived class.
 
@ ParentRuleKey
Rule key of the parent legend node - for legends with tree hierarchy (QString). Added in 2....
 
@ RuleKey
Rule key of the node (QString)
 
QgsLayerTreeLayer * layerNode() const
Returns pointer to the parent layer node.
 
The QgsLayerTreeModel class is model implementation for Qt item views framework.
 
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...
 
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...
 
QModelIndex legendNode2index(QgsLayerTreeModelLegendNode *legendNode)
Returns index for a given legend node.
 
Qt::ItemFlags flags(const QModelIndex &index) const override
 
void setCurrentIndex(const QModelIndex ¤tIndex)
Sets index of the current item. May be used by view. Item marked as current is underlined.
 
void setFlags(QgsLayerTreeModel::Flags f)
Sets OR-ed combination of model flags.
 
QgsLayerTree * rootGroup() const
Returns pointer to the root node of the layer tree. Always a non nullptr value.
 
QgsLayerTreeNode * index2node(const QModelIndex &index) const
Returns layer tree node for given index.
 
int rowCount(const QModelIndex &parent=QModelIndex()) const override
 
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.
 
QList< QgsLayerTreeNode * > indexes2nodes(const QModelIndexList &list, bool skipInternal=false) const
Convert a list of indexes to a list of layer tree nodes.
 
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
 
static QgsLayerTreeModelLegendNode * index2legendNode(const QModelIndex &index)
Returns legend node for given index.
 
void refreshLayerLegend(QgsLayerTreeLayer *nodeLayer)
Force a refresh of legend nodes of a layer node.
 
@ ActionHierarchical
Check/uncheck action has consequences on children (or parents for leaf node)
 
@ UseEmbeddedWidgets
Layer nodes may optionally include extra embedded widgets (if used in QgsLayerTreeView)....
 
void addTargetScreenProperties(const QgsScreenProperties &properties)
Adds additional target screen properties to use when generating icons for Qt::DecorationRole data.
 
This class is a base class for nodes in a layer tree.
 
@ NodeGroup
Container of other groups and layers.
 
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.
 
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
 
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
 
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
 
virtual QString name() const =0
Returns name of the node.
 
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
 
NodeType nodeType() const
Find out about type of the node. It is usually shorter to use convenience functions from QgsLayerTree...
 
void customPropertyChanged(QgsLayerTreeNode *node, const QString &key)
Emitted when a custom property of a node within the tree has been changed or removed.
 
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
 
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
 
void expandedChanged(QgsLayerTreeNode *node, bool expanded)
Emitted when the collapsed/expanded state of a node within the tree has been changed.
 
The QgsLayerTreeProxyModel class is a proxy model for QgsLayerTreeModel, supports private layers and ...
 
bool showPrivateLayers() const
Returns if private layers are shown.
 
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
 
void setFilterText(const QString &filterText=QString())
Sets filter to filterText.
 
bool hideValidLayers() const
Returns if valid layers should be hidden (i.e.
 
void setHideValidLayers(bool hideValid)
Sets whether valid layers should be hidden (i.e.
 
void setShowPrivateLayers(bool showPrivate)
Determines if private layers are shown.
 
QgsLayerTreeProxyModel(QgsLayerTreeModel *treeModel, QObject *parent)
Constructs QgsLayerTreeProxyModel with source model treeModel and a parent.
 
static QSet< QgsMapLayer * > collectMapLayersRecursive(const QList< QgsLayerTreeNode * > &nodes)
Returns map layers from the given list of layer tree nodes.
 
The QgsLayerTreeViewDefaultActions class serves as a factory of actions that can be used together wit...
 
Indicator that can be used in a layer tree view to display icons next to items of the layer tree.
 
void changed()
Emitted when the indicator changes state (e.g.
 
void expandAllNodes()
Enhancement of QTreeView::expandAll() that also records expanded state in layer tree nodes.
 
QList< QgsLayerTreeViewIndicator * > indicators(QgsLayerTreeNode *node) const
Returns list of indicators associated with a particular layer tree node.
 
void currentLayerChanged(QgsMapLayer *layer)
Emitted when a current layer is changed.
 
void contextMenuAboutToShow(QMenu *menu)
Emitted when the context menu is about to show.
 
void collapseAllNodes()
Enhancement of QTreeView::collapseAll() that also records expanded state in layer tree nodes.
 
QModelIndex legendNode2index(QgsLayerTreeModelLegendNode *legendNode)
Returns proxy model index for a given legend node.
 
QgsLayerTreeViewDefaultActions * defaultActions()
Gets access to the default actions that may be used with the tree view.
 
void setCurrentNode(QgsLayerTreeNode *node)
Sets the currently selected node.
 
QString mCurrentLayerID
Keeps track of current layer ID (to check when to emit signal about change of current layer)
 
void datasetsDropped(QDropEvent *event)
Emitted when datasets are dropped onto the layer tree view.
 
void setModel(QAbstractItemModel *model) override
Overridden setModel() from base class. Only QgsLayerTreeModel is an acceptable model.
 
QHash< QgsLayerTreeNode *, QList< QgsLayerTreeViewIndicator * > > mIndicators
Storage of indicators used with the tree view.
 
QList< QgsLayerTreeLayer * > selectedLayerNodes() const
Returns the list of selected nodes filtered to just layer nodes (QgsLayerTreeLayer).
 
void removeIndicator(QgsLayerTreeNode *node, QgsLayerTreeViewIndicator *indicator)
Removes a previously added indicator to a layer tree node.
 
void refreshLayerSymbology(const QString &layerId)
Force refresh of layer symbology. Normally not needed as the changes of layer's renderer are monitore...
 
void dropEvent(QDropEvent *event) override
 
QgsLayerTreeView(QWidget *parent=nullptr)
Constructor for QgsLayerTreeView.
 
QgsMapLayer * currentLayer() const
Returns the currently selected layer, or nullptr if no layers is selected.
 
QgsLayerTreeViewMenuProvider * menuProvider() const
Returns pointer to the context menu provider. May be nullptr.
 
void onExpandedChanged(QgsLayerTreeNode *node, bool expanded)
 
QgsLayerTreeNode * index2node(const QModelIndex &index) const
Returns layer tree node for given proxy model tree index.
 
void resizeEvent(QResizeEvent *event) override
 
QList< QgsMapLayer * > selectedLayersRecursive() const
Gets list of selected layers, including those that are not directly selected, but their ancestor grou...
 
void mouseReleaseEvent(QMouseEvent *event) override
 
bool hideValidLayers() const
Returns if valid layers should be hidden (i.e.
 
void updateExpandedStateFromNode(QgsLayerTreeNode *node)
 
QgsLayerTreeModelLegendNode * currentLegendNode() const
Gets current legend node.
 
QgsLayerTreeModel * layerTreeModel() const
Gets access to the model casted to QgsLayerTreeModel.
 
void setMenuProvider(QgsLayerTreeViewMenuProvider *menuProvider)
Sets provider for context menu. Takes ownership of the instance.
 
void setLayerVisible(QgsMapLayer *layer, bool visible)
Convenience methods which sets the visible state of the specified map layer.
 
QModelIndex node2sourceIndex(QgsLayerTreeNode *node) const
Returns source model index for a given node.
 
QgsMapLayer * layerForIndex(const QModelIndex &index) const
 
void dragMoveEvent(QDragMoveEvent *event) override
 
void mouseDoubleClickEvent(QMouseEvent *event) override
 
QPoint mLastReleaseMousePos
Used by the item delegate for identification of which indicator has been clicked.
 
friend class QgsLayerTreeViewItemDelegate
 
void updateExpandedStateToNode(const QModelIndex &index)
 
QgsLayerTreeProxyModel * proxyModel() const
Returns the proxy model used by the view.
 
QgsLayerTreeViewMenuProvider * mMenuProvider
Context menu provider. Owned by the view.
 
QList< QgsLayerTreeModelLegendNode * > selectedLegendNodes() const
Returns the list of selected legend nodes.
 
QgsLayerTreeModelLegendNode * index2legendNode(const QModelIndex &index) const
Returns legend node for given proxy model tree index.
 
void contextMenuEvent(QContextMenuEvent *event) override
 
void keyPressEvent(QKeyEvent *event) override
 
void setMessageBar(QgsMessageBar *messageBar)
Set the message bar to display messages from the layer tree.
 
void addIndicator(QgsLayerTreeNode *node, QgsLayerTreeViewIndicator *indicator)
Adds an indicator to the given layer tree node.
 
void setHideValidLayers(bool hideValid)
Sets whether valid layers should be hidden (i.e.
 
void modelRowsInserted(const QModelIndex &index, int start, int end)
 
QList< QgsLayerTreeNode * > selectedNodes(bool skipInternal=false) const
Returns the list of selected layer tree nodes.
 
void setLayerMarkWidth(int width)
Set width of contextual menu mark, at right of layer node items.
 
QModelIndex node2index(QgsLayerTreeNode *node) const
Returns proxy model index for a given node.
 
void setCurrentLayer(QgsMapLayer *layer)
Sets the currently selected layer.
 
void setShowPrivateLayers(bool showPrivate)
Set the show private layers to showPrivate.
 
QgsLayerTreeNode * currentNode() const
Gets current node. May be nullptr.
 
~QgsLayerTreeView() override
 
QgsLayerTreeGroup * currentGroupNode() const
Gets current group node. If a layer is current node, the function will return parent group....
 
void dragEnterEvent(QDragEnterEvent *event) override
 
QgsLayerTreeViewDefaultActions * mDefaultActions
helper class with default actions. Lazily initialized.
 
QList< QgsMapLayer * > selectedLayers() const
Returns the list of selected layers.
 
QModelIndex legendNode2sourceIndex(QgsLayerTreeModelLegendNode *legendNode)
Returns index for a given legend node.
 
bool showPrivateLayers() const
Returns the show private layers status.
 
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
 
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
 
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
 
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
 
Base class for all map layer types.
 
QgsMapLayer::LayerFlags flags() const
Returns the flags for this layer.
 
@ Private
Determines if the layer is meant to be exposed to the GUI, i.e. visible in the layer legend tree.
 
A bar for displaying non-blocking messages to the user.
 
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::MessageLevel::Info, int duration=-1)
A convenience method for pushing a message with the specified text to the bar.
 
Stores properties relating to a screen.