Changeset View
Changeset View
Standalone View
Standalone View
src/view/kateannotationitemdelegate.cpp
- This file was added.
1 | /* This file is part of the KDE libraries | ||||
---|---|---|---|---|---|
2 | Copyright (C) 2017-18 Friedrich W. H. Kossebau <kossebau@kde.org> | ||||
3 | | ||||
4 | This library is free software; you can redistribute it and/or | ||||
5 | modify it under the terms of the GNU Library General Public | ||||
6 | License as published by the Free Software Foundation; either | ||||
7 | version 2 of the License, or (at your option) any later version. | ||||
8 | | ||||
9 | This library is distributed in the hope that it will be useful, | ||||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
12 | Library General Public License for more details. | ||||
13 | | ||||
14 | You should have received a copy of the GNU Library General Public License | ||||
15 | along with this library; see the file COPYING.LIB. If not, write to | ||||
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||
17 | Boston, MA 02110-1301, USA. | ||||
18 | */ | ||||
19 | | ||||
20 | #include "kateannotationitemdelegate.h" | ||||
21 | | ||||
22 | #include "kateviewinternal.h" | ||||
23 | | ||||
24 | #include <KLocalizedString> | ||||
25 | | ||||
26 | #include <QPainter> | ||||
27 | #include <QToolTip> | ||||
28 | #include <QFontMetricsF> | ||||
29 | | ||||
30 | #include <math.h> | ||||
31 | | ||||
32 | | ||||
33 | KateAnnotationItemDelegate::KateAnnotationItemDelegate(KateViewInternal *internalView, QObject *parent) | ||||
34 | : KTextEditor::AbstractAnnotationItemDelegate(parent) | ||||
35 | , m_internalView(internalView) | ||||
36 | , m_view(internalView->m_view) | ||||
37 | , m_cachedDataContentFontMetrics(QFont()) | ||||
38 | { | ||||
39 | } | ||||
40 | | ||||
41 | KateAnnotationItemDelegate::~KateAnnotationItemDelegate() = default; | ||||
42 | | ||||
43 | void KateAnnotationItemDelegate::paint(QPainter *painter, const KTextEditor::StyleOptionAnnotationItem &option, | ||||
44 | KTextEditor::AnnotationModel *model, int line) const | ||||
45 | { | ||||
46 | Q_ASSERT(painter); | ||||
47 | Q_ASSERT(model); | ||||
48 | if (!painter || !model) { | ||||
49 | return; | ||||
50 | } | ||||
51 | // TODO: also test line for validity for sake of completeness? | ||||
52 | | ||||
53 | painter->save(); | ||||
54 | | ||||
dhaumann: Given you check for a valid pointers here, would it also be an option to pass references? Or… | |||||
It is following QAbstractItemDelegate ::paint(...) signature here. So I would lean to stay with the current code. But as you prefer. kossebau: It is following [[ http://doc.qt.io/qt-5/qabstractitemdelegate.html#paint |… | |||||
55 | const int margin = 3; | ||||
56 | | ||||
57 | const QVariant background = model->data(line, Qt::BackgroundRole); | ||||
58 | // Fill the background | ||||
dhaumann: validness --> validity :-) | |||||
59 | if (background.isValid()) { | ||||
60 | painter->fillRect(option.rect, background.value<QBrush>()); | ||||
61 | } | ||||
62 | | ||||
63 | const QVariant foreground = model->data(line, Qt::ForegroundRole); | ||||
64 | // Set the pen for drawing the foreground | ||||
65 | if (foreground.isValid() && foreground.canConvert<QPen>()) { | ||||
66 | painter->setPen(foreground.value<QPen>()); | ||||
67 | } | ||||
68 | | ||||
69 | // Draw a border around all adjacent entries that have the same text as the currently hovered one | ||||
70 | if ((option.state & QStyle::State_MouseOver) && | ||||
71 | (option.annotationItemGroupingPosition & KTextEditor::StyleOptionAnnotationItem::InGroup)) { | ||||
72 | // Use floating point coordinates to support scaled rendering | ||||
73 | QRectF rect(option.rect); | ||||
74 | rect.adjust(0.5, 0.5, -0.5, -0.5); | ||||
75 | | ||||
76 | // draw left and right highlight borders | ||||
77 | painter->drawLine(rect.topLeft(), rect.bottomLeft()); | ||||
78 | painter->drawLine(rect.topRight(), rect.bottomRight()); | ||||
79 | | ||||
80 | if ((option.annotationItemGroupingPosition & KTextEditor::StyleOptionAnnotationItem::GroupBegin) && | ||||
81 | (option.wrappedLine == 0)) { | ||||
82 | painter->drawLine(rect.topLeft(), rect.topRight()); | ||||
83 | } | ||||
84 | | ||||
85 | if ((option.annotationItemGroupingPosition & KTextEditor::StyleOptionAnnotationItem::GroupEnd) && | ||||
86 | (option.wrappedLine == (option.wrappedLineCount-1))) { | ||||
87 | painter->drawLine(rect.bottomLeft(), rect.bottomRight()); | ||||
88 | } | ||||
89 | } | ||||
90 | // reset pen | ||||
91 | if (foreground.isValid()) { | ||||
92 | QPen pen = painter->pen(); | ||||
93 | pen.setWidth(1); | ||||
94 | painter->setPen(pen); | ||||
95 | } | ||||
96 | | ||||
97 | // Now draw the normal text | ||||
98 | const QVariant text = model->data(line, Qt::DisplayRole); | ||||
99 | if ((option.wrappedLine == 0) && text.isValid() && text.canConvert<QString>()) { | ||||
100 | painter->drawText(option.rect.x() + margin, option.rect.y(), | ||||
101 | option.rect.width() - 2*margin, option.rect.height(), | ||||
102 | Qt::AlignLeft | Qt::AlignVCenter, text.toString()); | ||||
103 | } | ||||
104 | | ||||
105 | painter->restore(); | ||||
106 | } | ||||
107 | | ||||
108 | bool KateAnnotationItemDelegate::helpEvent(QHelpEvent *event, KTextEditor::View *view, | ||||
109 | const KTextEditor::StyleOptionAnnotationItem &option, | ||||
110 | KTextEditor::AnnotationModel *model, int line) | ||||
111 | { | ||||
112 | Q_UNUSED(option); | ||||
113 | | ||||
114 | if (!model || event->type() != QEvent::ToolTip) { | ||||
115 | return false; | ||||
116 | } | ||||
117 | | ||||
118 | const QVariant data = model->data(line, Qt::ToolTipRole); | ||||
119 | if (!data.isValid()) { | ||||
120 | return false; | ||||
121 | } | ||||
122 | | ||||
123 | const QString toolTipText = data.toString(); | ||||
124 | if (toolTipText.isEmpty()) { | ||||
125 | return false; | ||||
126 | } | ||||
127 | | ||||
128 | QToolTip::showText(event->globalPos(), toolTipText, view, option.rect); | ||||
129 | | ||||
130 | return true; | ||||
131 | } | ||||
132 | | ||||
133 | void KateAnnotationItemDelegate::hideTooltip(KTextEditor::View *view) | ||||
134 | { | ||||
135 | Q_UNUSED(view); | ||||
136 | QToolTip::hideText(); | ||||
137 | } | ||||
138 | | ||||
139 | QSize KateAnnotationItemDelegate::sizeHint(const KTextEditor::StyleOptionAnnotationItem &option, | ||||
140 | KTextEditor::AnnotationModel *model, int line) const | ||||
141 | { | ||||
142 | Q_ASSERT(model); | ||||
143 | if (!model) { | ||||
144 | return QSize(0, 0); | ||||
145 | } | ||||
146 | | ||||
147 | // recalculate m_maxCharWidth if needed | ||||
148 | if (m_maxCharWidth == 0.0 || (option.contentFontMetrics != m_cachedDataContentFontMetrics)) { | ||||
149 | m_maxCharWidth = 0.0; | ||||
150 | // based on old code written when just a hash was shown, could see an update | ||||
151 | // Loop to determine the widest numeric character in the current font. | ||||
152 | for (char c = '0'; c <= '9'; ++c) { | ||||
153 | const qreal charWidth = ceil(option.contentFontMetrics.width(QLatin1Char(c))); | ||||
154 | m_maxCharWidth = qMax(m_maxCharWidth, charWidth); | ||||
155 | } | ||||
156 | | ||||
157 | m_cachedDataContentFontMetrics = option.contentFontMetrics; | ||||
158 | } | ||||
159 | | ||||
160 | const QString annotationText = model->data(line, Qt::DisplayRole).toString(); | ||||
161 | return QSize(annotationText.length() * m_maxCharWidth + 8, option.contentFontMetrics.height()); | ||||
162 | } |
Given you check for a valid pointers here, would it also be an option to pass references? Or would that violate Qt style API?