1 /*
2 SPDX-FileCopyrightText: 2000 Peter Putzer <putzer@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6
7 #include "kurllabel.h"
8
9 #include <QApplication>
10 #include <QMouseEvent>
11 #include <QPalette>
12 #include <QTimer>
13
14 class KUrlLabelPrivate
15 {
16 public:
KUrlLabelPrivate(const QString & _url,KUrlLabel * _parent)17 KUrlLabelPrivate(const QString &_url, KUrlLabel *_parent)
18 : parent(_parent)
19 , url(_url)
20 , tipText(url)
21 , linkColor(_parent->palette().color(QPalette::Active, QPalette::Link))
22 , highlightedLinkColor(_parent->palette().color(QPalette::Active, QPalette::BrightText))
23 , cursor(nullptr)
24 , textUnderlined(true)
25 , realUnderlined(true)
26 , useTips(false)
27 , useCursor(false)
28 , glowEnabled(true)
29 , floatEnabled(false)
30 , timer(new QTimer(parent))
31 {
32 QObject::connect(timer, &QTimer::timeout, parent, [this]() {
33 updateColor();
34 });
35 }
36
updateColor()37 void updateColor()
38 {
39 timer->stop();
40
41 if (!(glowEnabled || floatEnabled) || !parent->rect().contains(parent->mapFromGlobal(QCursor::pos()))) {
42 setLinkColor(linkColor);
43 }
44 }
45
setLinkColor(const QColor & color)46 void setLinkColor(const QColor &color)
47 {
48 QPalette palette = parent->palette();
49 palette.setColor(QPalette::WindowText, color);
50 parent->setPalette(palette);
51
52 parent->update();
53 }
54
55 KUrlLabel *parent;
56
57 QString url;
58 QString tipText;
59 QColor linkColor;
60 QColor highlightedLinkColor;
61 QCursor *cursor;
62 bool textUnderlined : 1;
63 bool realUnderlined : 1;
64 bool useTips : 1;
65 bool useCursor : 1;
66 bool glowEnabled : 1;
67 bool floatEnabled : 1;
68 QPixmap alternatePixmap;
69 QPixmap realPixmap;
70 QTimer *timer;
71 };
72
KUrlLabel(const QString & url,const QString & text,QWidget * parent)73 KUrlLabel::KUrlLabel(const QString &url, const QString &text, QWidget *parent)
74 : QLabel(!text.isNull() ? text : url, parent)
75 , d(new KUrlLabelPrivate(url, this))
76 {
77 setFont(font());
78 setCursor(QCursor(Qt::PointingHandCursor));
79 d->setLinkColor(d->linkColor);
80 }
81
KUrlLabel(QWidget * parent)82 KUrlLabel::KUrlLabel(QWidget *parent)
83 : QLabel(parent)
84 , d(new KUrlLabelPrivate(QString(), this))
85 {
86 setFont(font());
87 setCursor(QCursor(Qt::PointingHandCursor));
88 d->setLinkColor(d->linkColor);
89 }
90
91 KUrlLabel::~KUrlLabel() = default;
92
mouseReleaseEvent(QMouseEvent * event)93 void KUrlLabel::mouseReleaseEvent(QMouseEvent *event)
94 {
95 QLabel::mouseReleaseEvent(event);
96
97 d->setLinkColor(d->highlightedLinkColor);
98 d->timer->start(300);
99
100 switch (event->button()) {
101 case Qt::LeftButton:
102 Q_EMIT leftClickedUrl();
103 #if KWIDGETSADDONS_BUILD_DEPRECATED_SINCE(5, 65)
104 Q_EMIT leftClickedUrl(d->url);
105 #endif
106 break;
107
108 case Qt::MiddleButton:
109 Q_EMIT middleClickedUrl();
110 #if KWIDGETSADDONS_BUILD_DEPRECATED_SINCE(5, 65)
111 Q_EMIT middleClickedUrl(d->url);
112 #endif
113 break;
114
115 case Qt::RightButton:
116 Q_EMIT rightClickedUrl();
117 #if KWIDGETSADDONS_BUILD_DEPRECATED_SINCE(5, 65)
118 Q_EMIT rightClickedUrl(d->url);
119 #endif
120 break;
121
122 default:
123 break;
124 }
125 }
126
setFont(const QFont & font)127 void KUrlLabel::setFont(const QFont &font)
128 {
129 QFont newFont = font;
130 newFont.setUnderline(d->textUnderlined);
131
132 QLabel::setFont(newFont);
133 }
134
setUnderline(bool on)135 void KUrlLabel::setUnderline(bool on)
136 {
137 d->textUnderlined = on;
138
139 setFont(font());
140 }
141
setUrl(const QString & url)142 void KUrlLabel::setUrl(const QString &url)
143 {
144 if (d->tipText == d->url) { // update the tip as well
145 d->tipText = url;
146 setUseTips(d->useTips);
147 }
148
149 d->url = url;
150 }
151
url() const152 QString KUrlLabel::url() const
153 {
154 return d->url;
155 }
156
setUseCursor(bool on,QCursor * cursor)157 void KUrlLabel::setUseCursor(bool on, QCursor *cursor)
158 {
159 d->useCursor = on;
160 d->cursor = cursor;
161
162 if (on) {
163 if (cursor) {
164 setCursor(*cursor);
165 } else {
166 setCursor(QCursor(Qt::PointingHandCursor));
167 }
168 } else {
169 unsetCursor();
170 }
171 }
172
useCursor() const173 bool KUrlLabel::useCursor() const
174 {
175 return d->useCursor;
176 }
177
setUseTips(bool on)178 void KUrlLabel::setUseTips(bool on)
179 {
180 d->useTips = on;
181
182 if (on) {
183 setToolTip(d->tipText);
184 } else {
185 setToolTip(QString());
186 }
187 }
188
setTipText(const QString & tipText)189 void KUrlLabel::setTipText(const QString &tipText)
190 {
191 d->tipText = tipText;
192
193 setUseTips(d->useTips);
194 }
195
useTips() const196 bool KUrlLabel::useTips() const
197 {
198 return d->useTips;
199 }
200
tipText() const201 QString KUrlLabel::tipText() const
202 {
203 return d->tipText;
204 }
205
setHighlightedColor(const QColor & color)206 void KUrlLabel::setHighlightedColor(const QColor &color)
207 {
208 d->linkColor = color;
209
210 if (!d->timer->isActive()) {
211 d->setLinkColor(color);
212 }
213 }
214
setHighlightedColor(const QString & color)215 void KUrlLabel::setHighlightedColor(const QString &color)
216 {
217 setHighlightedColor(QColor(color));
218 }
219
setSelectedColor(const QColor & color)220 void KUrlLabel::setSelectedColor(const QColor &color)
221 {
222 d->highlightedLinkColor = color;
223
224 if (d->timer->isActive()) {
225 d->setLinkColor(color);
226 }
227 }
228
setSelectedColor(const QString & color)229 void KUrlLabel::setSelectedColor(const QString &color)
230 {
231 setSelectedColor(QColor(color));
232 }
233
setGlowEnabled(bool glowEnabled)234 void KUrlLabel::setGlowEnabled(bool glowEnabled)
235 {
236 d->glowEnabled = glowEnabled;
237 }
238
setFloatEnabled(bool floatEnabled)239 void KUrlLabel::setFloatEnabled(bool floatEnabled)
240 {
241 d->floatEnabled = floatEnabled;
242 }
243
isGlowEnabled() const244 bool KUrlLabel::isGlowEnabled() const
245 {
246 return d->glowEnabled;
247 }
248
isFloatEnabled() const249 bool KUrlLabel::isFloatEnabled() const
250 {
251 return d->floatEnabled;
252 }
253
setAlternatePixmap(const QPixmap & pixmap)254 void KUrlLabel::setAlternatePixmap(const QPixmap &pixmap)
255 {
256 d->alternatePixmap = pixmap;
257 }
258
alternatePixmap() const259 const QPixmap *KUrlLabel::alternatePixmap() const
260 {
261 return &d->alternatePixmap;
262 }
263
enterEvent(QEvent * event)264 void KUrlLabel::enterEvent(QEvent *event)
265 {
266 QLabel::enterEvent(event);
267
268 if (!d->alternatePixmap.isNull()) {
269 const auto currentPixmap = pixmap(Qt::ReturnByValue);
270 if (!currentPixmap.isNull()) {
271 d->realPixmap = currentPixmap;
272 setPixmap(d->alternatePixmap);
273 }
274 }
275
276 if (d->glowEnabled || d->floatEnabled) {
277 d->timer->stop();
278
279 d->setLinkColor(d->highlightedLinkColor);
280
281 d->realUnderlined = d->textUnderlined;
282
283 if (d->floatEnabled) {
284 setUnderline(true);
285 }
286 }
287 Q_EMIT enteredUrl();
288 #if KWIDGETSADDONS_BUILD_DEPRECATED_SINCE(5, 65)
289 Q_EMIT enteredUrl(d->url);
290 #endif
291 }
292
leaveEvent(QEvent * event)293 void KUrlLabel::leaveEvent(QEvent *event)
294 {
295 QLabel::leaveEvent(event);
296
297 if (!d->alternatePixmap.isNull() && !pixmap(Qt::ReturnByValue).isNull()) {
298 setPixmap(d->realPixmap);
299 }
300
301 if ((d->glowEnabled || d->floatEnabled) && !d->timer->isActive()) {
302 d->setLinkColor(d->linkColor);
303 }
304
305 setUnderline(d->realUnderlined);
306 Q_EMIT leftUrl();
307 #if KWIDGETSADDONS_BUILD_DEPRECATED_SINCE(5, 65)
308 Q_EMIT leftUrl(d->url);
309 #endif
310 }
311
event(QEvent * event)312 bool KUrlLabel::event(QEvent *event)
313 {
314 if (event->type() == QEvent::PaletteChange) {
315 // Use parentWidget() unless you are a toplevel widget, then try qAapp
316 QPalette palette = parentWidget() ? parentWidget()->palette() : qApp->palette();
317
318 palette.setBrush(QPalette::Base, palette.brush(QPalette::Normal, QPalette::Window));
319 palette.setColor(QPalette::WindowText, this->palette().color(QPalette::Active, QPalette::WindowText));
320 setPalette(palette);
321
322 d->linkColor = palette.color(QPalette::Active, QPalette::Link);
323 d->updateColor();
324
325 return true;
326 } else {
327 return QLabel::event(event);
328 }
329 }
330
331 #include "moc_kurllabel.cpp"
332