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) 2008, 2009 Matthew Woehlke <mw_triad@users.sourceforge.net> | ||||
3 | Copyright (C) 2007 Mirko Stocker <me@misto.ch> | ||||
4 | Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org> | ||||
5 | Copyright (C) 2001 Anders Lund <anders@alweb.dk> | ||||
6 | Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org> | ||||
7 | Copyright (C) 2011 Svyatoslav Kuzmich <svatoslav1@gmail.com> | ||||
8 | Copyright (C) 2012 Kåre Särs <kare.sars@iki.fi> (Minimap) | ||||
9 | Copyright (C) 2017 Friedrich W. H. Kossebau <kossebau@kde.org> | ||||
10 | | ||||
11 | This library is free software; you can redistribute it and/or | ||||
12 | modify it under the terms of the GNU Library General Public | ||||
13 | License version 2 as published by the Free Software Foundation. | ||||
14 | | ||||
15 | This library is distributed in the hope that it will be useful, | ||||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
18 | Library General Public License for more details. | ||||
19 | | ||||
20 | You should have received a copy of the GNU Library General Public License | ||||
21 | along with this library; see the file COPYING.LIB. If not, write to | ||||
22 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||
23 | Boston, MA 02110-1301, USA. | ||||
24 | */ | ||||
25 | | ||||
26 | #include "kateannotationitemdelegate.h" | ||||
27 | | ||||
28 | #include "kateviewinternal.h" | ||||
29 | | ||||
30 | #include <KLocalizedString> | ||||
31 | | ||||
32 | #include <QPainter> | ||||
33 | #include <QAction> | ||||
34 | #include <QMenu> | ||||
35 | #include <QToolTip> | ||||
36 | #include <QFontMetricsF> | ||||
37 | | ||||
38 | #include <math.h> | ||||
39 | | ||||
40 | | ||||
41 | KateAnnotationItemDelegate::KateAnnotationItemDelegate(KateViewInternal *internalView, QObject *parent) | ||||
42 | : KTextEditor::AbstractAnnotationItemDelegate(parent) | ||||
43 | , m_internalView(internalView) | ||||
44 | , m_view(internalView->m_view) | ||||
45 | { | ||||
46 | } | ||||
47 | | ||||
48 | KateAnnotationItemDelegate::~KateAnnotationItemDelegate() | ||||
49 | { | ||||
50 | } | ||||
51 | | ||||
52 | void KateAnnotationItemDelegate::paint(QPainter *painter, const KTextEditor::StyleOptionAnnotationItem &option, | ||||
53 | KTextEditor::AnnotationModel *model, int line) const | ||||
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 | Q_ASSERT(painter); | ||||
56 | Q_ASSERT(model); | ||||
57 | if (!painter || !model) { | ||||
58 | return; | ||||
dhaumann: validness --> validity :-) | |||||
59 | } | ||||
60 | // TODO: also test line for sake of completeness | ||||
61 | | ||||
62 | painter->save(); | ||||
63 | | ||||
64 | const int margin = 3; | ||||
65 | | ||||
66 | const QVariant background = model->data(line, Qt::BackgroundRole); | ||||
67 | // Fill the background | ||||
68 | if (background.isValid()) { | ||||
69 | painter->fillRect(option.rect, background.value<QBrush>()); | ||||
70 | } | ||||
71 | | ||||
72 | const QVariant foreground = model->data(line, Qt::ForegroundRole); | ||||
73 | // Set the pen for drawing the foreground | ||||
74 | if (foreground.isValid() && foreground.canConvert<QPen>()) { | ||||
75 | painter->setPen(foreground.value<QPen>()); | ||||
76 | } | ||||
77 | | ||||
78 | // Draw a border around all adjacent entries that have the same text as the currently hovered one | ||||
79 | if ((option.state & QStyle::State_MouseOver) && | ||||
80 | (option.annotationItemGroupingPosition & KTextEditor::StyleOptionAnnotationItem::InGroup)) { | ||||
81 | // draw left and right highlight borders | ||||
82 | painter->drawLine(option.rect.topLeft(), option.rect.bottomLeft()); | ||||
83 | painter->drawLine(option.rect.topRight(), option.rect.bottomRight()); | ||||
84 | | ||||
85 | if ((option.annotationItemGroupingPosition & KTextEditor::StyleOptionAnnotationItem::GroupBegin) && | ||||
86 | (option.wrappedLine == 0)) { | ||||
87 | painter->drawLine(option.rect.topLeft(), option.rect.topRight()); | ||||
88 | } | ||||
89 | | ||||
90 | if ((option.annotationItemGroupingPosition & KTextEditor::StyleOptionAnnotationItem::GroupEnd) && | ||||
91 | (option.wrappedLine == (option.wrappedLineCount-1))) { | ||||
92 | painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight()); | ||||
93 | } | ||||
94 | } | ||||
95 | // reset pen | ||||
96 | if (foreground.isValid()) { | ||||
97 | QPen pen = painter->pen(); | ||||
98 | pen.setWidth(1); | ||||
99 | painter->setPen(pen); | ||||
100 | } | ||||
101 | | ||||
102 | // Now draw the normal text | ||||
103 | const QVariant text = model->data(line, Qt::DisplayRole); | ||||
104 | if ((option.wrappedLine == 0) && text.isValid() && text.canConvert<QString>()) { | ||||
105 | painter->drawText(option.rect.x() + margin, option.rect.y(), | ||||
106 | option.rect.width() - 2*margin, option.rect.height(), | ||||
107 | Qt::AlignLeft | Qt::AlignVCenter, text.toString()); | ||||
108 | } | ||||
109 | | ||||
110 | painter->restore(); | ||||
111 | } | ||||
112 | | ||||
113 | bool KateAnnotationItemDelegate::helpEvent(QHelpEvent *event, KTextEditor::View *view, | ||||
114 | const KTextEditor::StyleOptionAnnotationItem &option, | ||||
115 | KTextEditor::AnnotationModel *model, int line) | ||||
116 | { | ||||
117 | Q_UNUSED(option); | ||||
118 | | ||||
119 | if (!model || event->type() != QEvent::ToolTip) { | ||||
120 | return false; | ||||
121 | } | ||||
122 | | ||||
123 | const QVariant data = model->data(line, Qt::ToolTipRole); | ||||
124 | if (!data.isValid()) { | ||||
125 | return false; | ||||
126 | } | ||||
127 | | ||||
128 | const QString toolTipText = data.toString(); | ||||
129 | if (toolTipText.isEmpty()) { | ||||
130 | return false; | ||||
131 | } | ||||
132 | | ||||
133 | QToolTip::showText(event->globalPos(), toolTipText, view); | ||||
134 | return true; | ||||
135 | } | ||||
136 | | ||||
137 | void KateAnnotationItemDelegate::hideTooltip(KTextEditor::View *view) | ||||
138 | { | ||||
139 | Q_UNUSED(view); | ||||
140 | QToolTip::hideText(); | ||||
141 | } | ||||
142 | | ||||
143 | void KateAnnotationItemDelegate::contextMenuRequested(KTextEditor::View *view, const QPoint &pos, | ||||
144 | const KTextEditor::StyleOptionAnnotationItem &option, | ||||
145 | KTextEditor::AnnotationModel *model, int line) | ||||
146 | { | ||||
147 | Q_UNUSED(model); | ||||
148 | Q_UNUSED(option); | ||||
149 | | ||||
150 | QMenu menu; | ||||
151 | QAction a(i18n("Disable Annotation Bar"), &menu); | ||||
152 | a.setIcon(QIcon::fromTheme(QStringLiteral("dialog-close"))); | ||||
153 | menu.addAction(&a); | ||||
154 | emit m_view->annotationContextMenuAboutToShow(m_view, &menu, line); | ||||
155 | if (menu.exec(view->mapToGlobal(pos)) == &a) { | ||||
156 | m_view->setAnnotationBorderVisible(false); | ||||
157 | } | ||||
158 | } | ||||
159 | | ||||
160 | QSize KateAnnotationItemDelegate::sizeHint(const KTextEditor::StyleOptionAnnotationItem &option, | ||||
161 | KTextEditor::AnnotationModel *model, int line) const | ||||
162 | { | ||||
163 | Q_ASSERT(model); | ||||
164 | if (!model) { | ||||
165 | return QSize(0, 0); | ||||
166 | } | ||||
167 | | ||||
168 | // TODO: cache maxCharWidth for given font | ||||
169 | qreal maxCharWidth = 0.0; | ||||
170 | // TODO: why only decimal digits? | ||||
171 | // Loop to determine the widest numeric character in the current font. | ||||
172 | // 48 is ascii '0' | ||||
173 | for (int i = 48; i < 58; ++i) { | ||||
174 | const qreal charWidth = ceil(option.contentFontMetrics.width(QChar(i))); | ||||
175 | maxCharWidth = qMax(maxCharWidth, charWidth); | ||||
176 | } | ||||
177 | QVariant data = model->data(line, Qt::DisplayRole); | ||||
178 | return QSize(data.toString().length() * maxCharWidth + 8, option.fontMetrics.height()); | ||||
179 | } |
Given you check for a valid pointers here, would it also be an option to pass references? Or would that violate Qt style API?