QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
Loading...
Searching...
No Matches
qgsattributesformtreeviewitemdelegate.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsattributesformtreeviewitemdelegate.cpp
3 ---------------------
4 begin : June 2025
5 copyright : (C) 2025 by Germán Carrillo
6 email : german at opengis dot ch
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
20
21#include <QHelpEvent>
22#include <QToolTip>
23
24#include "moc_qgsattributesformtreeviewitemdelegate.cpp"
25
27
28QgsAttributesFormTreeViewProxyStyle::QgsAttributesFormTreeViewProxyStyle( QgsAttributesFormBaseView *treeView )
29 : QgsProxyStyle( treeView )
30 , mAttributesFormTreeView( treeView )
31{}
32
33QRect QgsAttributesFormTreeViewProxyStyle::subElementRect( QStyle::SubElement element, const QStyleOption *option, const QWidget *widget ) const
34{
35 if ( element == SE_AttributesFormTreeItemIndicator )
36 {
37 if ( const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>( option ) )
38 {
39 if ( vopt->index.isValid() )
40 {
41 const int count = mAttributesFormTreeView->indicators( vopt->index ).count();
42 if ( count )
43 {
44 const QRect vpr = mAttributesFormTreeView->viewport()->rect();
45 const QRect r = QProxyStyle::subElementRect( SE_ItemViewItemText, option, widget );
46 const int indiWidth = r.height() * count;
47 const int spacing = r.height() / 10;
48 const int vpIndiWidth = vpr.width() - indiWidth - spacing;
49 return QRect( vpIndiWidth, r.top(), indiWidth, r.height() );
50 }
51 }
52 }
53 }
54 return QProxyStyle::subElementRect( element, option, widget );
55}
56
57
58QgsAttributesFormTreeViewItemDelegate::QgsAttributesFormTreeViewItemDelegate( QgsAttributesFormBaseView *parent )
59 : QStyledItemDelegate( parent )
60 , mAttributesFormTreeView( parent )
61{}
62
63void QgsAttributesFormTreeViewItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
64{
65 QStyledItemDelegate::paint( painter, option, index );
66
67 if ( !index.isValid() )
68 return;
69
70 QStyleOptionViewItem opt = option;
71 initStyleOption( &opt, index );
72
73 const QColor baseColor = opt.palette.base().color();
74 const QList<QgsAttributesFormTreeViewIndicator *> indicators = mAttributesFormTreeView->indicators( index );
75 if ( indicators.isEmpty() )
76 return;
77
78 const QRect indRect
79 = mAttributesFormTreeView->style()->subElementRect( static_cast<QStyle::SubElement>( QgsAttributesFormTreeViewProxyStyle::SE_AttributesFormTreeItemIndicator ), &opt, mAttributesFormTreeView );
80 const int spacing = indRect.height() / 10;
81 const int h = indRect.height();
82 int x = indRect.left();
83
84 for ( QgsAttributesFormTreeViewIndicator *indicator : indicators )
85 {
86 const QRect rect( x + spacing, indRect.top() + spacing, h - spacing * 2, h - spacing * 2 );
87 // Add a little more padding so the icon does not look misaligned to background
88 const QRect iconRect( x + spacing * 2, indRect.top() + spacing * 2, h - spacing * 4, h - spacing * 4 );
89 x += h;
90
91 QIcon::Mode mode = QIcon::Normal;
92 if ( !( opt.state & QStyle::State_Enabled ) )
93 mode = QIcon::Disabled;
94 else if ( opt.state & QStyle::State_Selected )
95 mode = QIcon::Selected;
96
97 // Draw indicator background, for when floating over text content
98 const qreal bradius = spacing;
99 const QBrush pb = painter->brush();
100 const QPen pp = painter->pen();
101 QBrush b = QBrush( opt.palette.midlight() );
102 QColor bc = b.color();
103 bc.setRed( static_cast<int>( bc.red() * 0.3 + baseColor.red() * 0.7 ) );
104 bc.setGreen( static_cast<int>( bc.green() * 0.3 + baseColor.green() * 0.7 ) );
105 bc.setBlue( static_cast<int>( bc.blue() * 0.3 + baseColor.blue() * 0.7 ) );
106 b.setColor( bc );
107 painter->setBrush( b );
108 painter->setPen( QPen( QBrush( opt.palette.mid() ), 0.25 ) );
109 painter->drawRoundedRect( rect, bradius, bradius );
110 painter->setBrush( pb );
111 painter->setPen( pp );
112
113 indicator->icon().paint( painter, iconRect, Qt::AlignCenter, mode );
114 }
115}
116
117bool QgsAttributesFormTreeViewItemDelegate::helpEvent( QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index )
118{
119 if ( event && event->type() == QEvent::ToolTip )
120 {
121 if ( index.isValid() )
122 {
123 const QList<QgsAttributesFormTreeViewIndicator *> indicators = mAttributesFormTreeView->indicators( index );
124 if ( !indicators.isEmpty() )
125 {
126 QStyleOptionViewItem opt = option;
127 initStyleOption( &opt, index );
128 opt.showDecorationSelected = true; // See https://github.com/qgis/QGIS/pull/7853 for the rationale of this fix
129
130 const QRect indRect
131 = mAttributesFormTreeView->style()->subElementRect( static_cast<QStyle::SubElement>( QgsAttributesFormTreeViewProxyStyle::SE_AttributesFormTreeItemIndicator ), &opt, mAttributesFormTreeView );
132
133 if ( indRect.contains( event->pos() ) )
134 {
135 const int indicatorIndex = ( event->pos().x() - indRect.left() ) / indRect.height();
136 if ( indicatorIndex >= 0 && indicatorIndex < indicators.count() )
137 {
138 const QString tooltip = indicators[indicatorIndex]->toolTip();
139 if ( !tooltip.isEmpty() )
140 {
141 QToolTip::showText( event->globalPos(), tooltip, view );
142 return true;
143 }
144 }
145 }
146 }
147 }
148 }
149 return QStyledItemDelegate::helpEvent( event, view, option, index );
150}
151
Graphical representation for the attribute drag and drop editor.
Indicator that can be used in an Attributes Form tree view to display icons next to field items.
A QProxyStyle subclass which correctly sets the base style to match the QGIS application style,...