QGIS API Documentation 3.99.0-Master (21b3aa880ba)
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}
33
34QRect QgsAttributesFormTreeViewProxyStyle::subElementRect( QStyle::SubElement element, const QStyleOption *option, const QWidget *widget ) const
35{
36 if ( element == SE_AttributesFormTreeItemIndicator )
37 {
38 if ( const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>( option ) )
39 {
40 if ( vopt->index.isValid() )
41 {
42 const int count = mAttributesFormTreeView->indicators( vopt->index ).count();
43 if ( count )
44 {
45 const QRect vpr = mAttributesFormTreeView->viewport()->rect();
46 const QRect r = QProxyStyle::subElementRect( SE_ItemViewItemText, option, widget );
47 const int indiWidth = r.height() * count;
48 const int spacing = r.height() / 10;
49 const int vpIndiWidth = vpr.width() - indiWidth - spacing;
50 return QRect( vpIndiWidth, r.top(), indiWidth, r.height() );
51 }
52 }
53 }
54 }
55 return QProxyStyle::subElementRect( element, option, widget );
56}
57
58
59QgsAttributesFormTreeViewItemDelegate::QgsAttributesFormTreeViewItemDelegate( QgsAttributesFormBaseView *parent )
60 : QStyledItemDelegate( parent )
61 , mAttributesFormTreeView( parent )
62{
63}
64
65void QgsAttributesFormTreeViewItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
66{
67 QStyledItemDelegate::paint( painter, option, index );
68
69 if ( !index.isValid() )
70 return;
71
72 QStyleOptionViewItem opt = option;
73 initStyleOption( &opt, index );
74
75 const QColor baseColor = opt.palette.base().color();
76 const QList<QgsAttributesFormTreeViewIndicator *> indicators = mAttributesFormTreeView->indicators( index );
77 if ( indicators.isEmpty() )
78 return;
79
80 const QRect indRect = mAttributesFormTreeView->style()->subElementRect( static_cast<QStyle::SubElement>( QgsAttributesFormTreeViewProxyStyle::SE_AttributesFormTreeItemIndicator ), &opt, mAttributesFormTreeView );
81 const int spacing = indRect.height() / 10;
82 const int h = indRect.height();
83 int x = indRect.left();
84
85 for ( QgsAttributesFormTreeViewIndicator *indicator : indicators )
86 {
87 const QRect rect( x + spacing, indRect.top() + spacing, h - spacing * 2, h - spacing * 2 );
88 // Add a little more padding so the icon does not look misaligned to background
89 const QRect iconRect( x + spacing * 2, indRect.top() + spacing * 2, h - spacing * 4, h - spacing * 4 );
90 x += h;
91
92 QIcon::Mode mode = QIcon::Normal;
93 if ( !( opt.state & QStyle::State_Enabled ) )
94 mode = QIcon::Disabled;
95 else if ( opt.state & QStyle::State_Selected )
96 mode = QIcon::Selected;
97
98 // Draw indicator background, for when floating over text content
99 const qreal bradius = spacing;
100 const QBrush pb = painter->brush();
101 const QPen pp = painter->pen();
102 QBrush b = QBrush( opt.palette.midlight() );
103 QColor bc = b.color();
104 bc.setRed( static_cast<int>( bc.red() * 0.3 + baseColor.red() * 0.7 ) );
105 bc.setGreen( static_cast<int>( bc.green() * 0.3 + baseColor.green() * 0.7 ) );
106 bc.setBlue( static_cast<int>( bc.blue() * 0.3 + baseColor.blue() * 0.7 ) );
107 b.setColor( bc );
108 painter->setBrush( b );
109 painter->setPen( QPen( QBrush( opt.palette.mid() ), 0.25 ) );
110 painter->drawRoundedRect( rect, bradius, bradius );
111 painter->setBrush( pb );
112 painter->setPen( pp );
113
114 indicator->icon().paint( painter, iconRect, Qt::AlignCenter, mode );
115 }
116}
117
118bool QgsAttributesFormTreeViewItemDelegate::helpEvent( QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index )
119{
120 if ( event && event->type() == QEvent::ToolTip )
121 {
122 if ( index.isValid() )
123 {
124 const QList<QgsAttributesFormTreeViewIndicator *> indicators = mAttributesFormTreeView->indicators( index );
125 if ( !indicators.isEmpty() )
126 {
127 QStyleOptionViewItem opt = option;
128 initStyleOption( &opt, index );
129 opt.showDecorationSelected = true; // See https://github.com/qgis/QGIS/pull/7853 for the rationale of this fix
130
131 const QRect indRect = 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,...