QGIS API Documentation  3.2.0-Bonn (bc43194)
qgslayertreeviewitemdelegate.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayertreeviewitemdelegate.cpp
3  --------------------------------------
4  Date : January 2018
5  Copyright : (C) 2018 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 
17 
18 #include "qgslayertreemodel.h"
19 #include "qgslayertreeview.h"
21 
22 #include <QHelpEvent>
23 #include <QToolTip>
24 
26 
27 QgsLayerTreeViewProxyStyle::QgsLayerTreeViewProxyStyle( QgsLayerTreeView *treeView )
28  : QgsProxyStyle( treeView )
29  , mLayerTreeView( treeView )
30 {
31 }
32 
33 
34 QRect QgsLayerTreeViewProxyStyle::subElementRect( QStyle::SubElement element, const QStyleOption *option, const QWidget *widget ) const
35 {
36  if ( element == SE_ItemViewItemText || element == SE_LayerTreeItemIndicator )
37  {
38  if ( const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>( option ) )
39  {
40  if ( QgsLayerTreeNode *node = mLayerTreeView->layerTreeModel()->index2node( vopt->index ) )
41  {
42  int count = mLayerTreeView->indicators( node ).count();
43  if ( count )
44  {
45  QRect r = QProxyStyle::subElementRect( SE_ItemViewItemText, option, widget );
46  int indiWidth = r.height() * count;
47  int textWidth = r.width() - indiWidth;
48  if ( element == SE_LayerTreeItemIndicator )
49  {
50  return QRect( r.left() + textWidth, r.top(), indiWidth, r.height() );
51  }
52  else if ( element == SE_ItemViewItemText )
53  {
54  return QRect( r.left(), r.top(), textWidth, r.height() );
55  }
56  }
57  }
58  }
59  }
60  return QProxyStyle::subElementRect( element, option, widget );
61 }
62 
63 
64 // -----
65 
66 
67 QgsLayerTreeViewItemDelegate::QgsLayerTreeViewItemDelegate( QgsLayerTreeView *parent )
68  : QStyledItemDelegate( parent )
69  , mLayerTreeView( parent )
70 {
71  connect( mLayerTreeView, &QgsLayerTreeView::clicked, this, &QgsLayerTreeViewItemDelegate::onClicked );
72 }
73 
74 
75 void QgsLayerTreeViewItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
76 {
77  QStyledItemDelegate::paint( painter, option, index );
78 
79  QgsLayerTreeNode *node = mLayerTreeView->layerTreeModel()->index2node( index );
80  if ( !node )
81  return;
82 
83  const QList<QgsLayerTreeViewIndicator *> indicators = mLayerTreeView->indicators( node );
84  if ( indicators.isEmpty() )
85  return;
86 
87  QStyleOptionViewItem opt = option;
88  initStyleOption( &opt, index );
89 
90  QRect indRect = mLayerTreeView->style()->subElementRect( static_cast<QStyle::SubElement>( QgsLayerTreeViewProxyStyle::SE_LayerTreeItemIndicator ), &opt, mLayerTreeView );
91  int spacing = indRect.height() / 10;
92  int h = indRect.height();
93  int x = indRect.left();
94 
95  for ( QgsLayerTreeViewIndicator *indicator : indicators )
96  {
97  QRect rect( x + spacing, indRect.top() + spacing, h - spacing * 2, h - spacing * 2 );
98  x += h;
99 
100  QIcon::Mode mode = QIcon::Normal;
101  if ( !( opt.state & QStyle::State_Enabled ) )
102  mode = QIcon::Disabled;
103  else if ( opt.state & QStyle::State_Selected )
104  mode = QIcon::Selected;
105 
106  indicator->icon().paint( painter, rect, Qt::AlignCenter, mode );
107  }
108 }
109 
110 
111 bool QgsLayerTreeViewItemDelegate::helpEvent( QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index )
112 {
113  if ( event && event->type() == QEvent::ToolTip )
114  {
115  QHelpEvent *he = static_cast<QHelpEvent *>( event );
116 
117  QgsLayerTreeNode *node = mLayerTreeView->layerTreeModel()->index2node( index );
118  if ( node )
119  {
120  const QList<QgsLayerTreeViewIndicator *> indicators = mLayerTreeView->indicators( node );
121  if ( !indicators.isEmpty() )
122  {
123  QStyleOptionViewItem opt = option;
124  initStyleOption( &opt, index );
125  QRect indRect = mLayerTreeView->style()->subElementRect( static_cast<QStyle::SubElement>( QgsLayerTreeViewProxyStyle::SE_LayerTreeItemIndicator ), &opt, mLayerTreeView );
126 
127  if ( indRect.contains( he->pos() ) )
128  {
129  int indicatorIndex = ( he->pos().x() - indRect.left() ) / indRect.height();
130  if ( indicatorIndex >= 0 && indicatorIndex < indicators.count() )
131  {
132  const QString tooltip = indicators[indicatorIndex]->toolTip();
133  if ( !tooltip.isEmpty() )
134  {
135  QToolTip::showText( he->globalPos(), tooltip, view );
136  return true;
137  }
138  }
139  }
140  }
141  }
142  }
143  return QStyledItemDelegate::helpEvent( event, view, option, index );
144 }
145 
146 
147 void QgsLayerTreeViewItemDelegate::onClicked( const QModelIndex &index )
148 {
149  QgsLayerTreeNode *node = mLayerTreeView->layerTreeModel()->index2node( index );
150  if ( !node )
151  return;
152 
153  const QList<QgsLayerTreeViewIndicator *> indicators = mLayerTreeView->indicators( node );
154  if ( indicators.isEmpty() )
155  return;
156 
157  QStyleOptionViewItem opt( mLayerTreeView->viewOptions() );
158  opt.rect = mLayerTreeView->visualRect( index );
159  initStyleOption( &opt, index );
160  QRect indRect = mLayerTreeView->style()->subElementRect( static_cast<QStyle::SubElement>( QgsLayerTreeViewProxyStyle::SE_LayerTreeItemIndicator ), &opt, mLayerTreeView );
161 
162  QPoint pos = mLayerTreeView->mLastReleaseMousePos;
163  if ( indRect.contains( pos ) )
164  {
165  int indicatorIndex = ( pos.x() - indRect.left() ) / indRect.height();
166  if ( indicatorIndex >= 0 && indicatorIndex < indicators.count() )
167  emit indicators[indicatorIndex]->clicked( index );
168  }
169 }
170 
The QgsLayerTreeView class extends QTreeView and provides some additional functionality when working ...
A QProxyStyle subclass which correctly sets the base style to match the QGIS application style...
Definition: qgsproxystyle.h:30
This class is a base class for nodes in a layer tree.
void clicked(const QModelIndex &index)
Signal that is emitted when user clicks on the indicator.
Indicator that can be used in a layer tree view to display icons next to items of the layer tree...