File indexing completed on 2024-04-28 03:59:17

0001 /*
0002     SPDX-FileCopyrightText: 2000 Peter Putzer <putzer@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-or-later
0005 */
0006 
0007 #include "kurllabel.h"
0008 
0009 #include <QApplication>
0010 #include <QMouseEvent>
0011 #include <QPalette>
0012 #include <QTimer>
0013 
0014 class KUrlLabelPrivate
0015 {
0016 public:
0017     KUrlLabelPrivate(const QString &_url, KUrlLabel *_parent)
0018         : parent(_parent)
0019         , url(_url)
0020         , tipText(url)
0021         , linkColor(_parent->palette().color(QPalette::Active, QPalette::Link))
0022         , highlightedLinkColor(_parent->palette().color(QPalette::Active, QPalette::BrightText))
0023         , cursor(nullptr)
0024         , textUnderlined(true)
0025         , realUnderlined(true)
0026         , useTips(false)
0027         , useCursor(false)
0028         , glowEnabled(true)
0029         , floatEnabled(false)
0030         , timer(new QTimer(parent))
0031     {
0032         QObject::connect(timer, &QTimer::timeout, parent, [this]() {
0033             updateColor();
0034         });
0035     }
0036 
0037     void updateColor()
0038     {
0039         timer->stop();
0040 
0041         if (!(glowEnabled || floatEnabled) || !parent->rect().contains(parent->mapFromGlobal(QCursor::pos()))) {
0042             setLinkColor(linkColor);
0043         }
0044     }
0045 
0046     void setLinkColor(const QColor &color)
0047     {
0048         QPalette palette = parent->palette();
0049         palette.setColor(QPalette::WindowText, color);
0050         parent->setPalette(palette);
0051 
0052         parent->update();
0053     }
0054 
0055     KUrlLabel *parent;
0056 
0057     QString url;
0058     QString tipText;
0059     QColor linkColor;
0060     QColor highlightedLinkColor;
0061     QCursor *cursor;
0062     bool textUnderlined : 1;
0063     bool realUnderlined : 1;
0064     bool useTips : 1;
0065     bool useCursor : 1;
0066     bool glowEnabled : 1;
0067     bool floatEnabled : 1;
0068     QPixmap alternatePixmap;
0069     QPixmap realPixmap;
0070     QTimer *timer;
0071 };
0072 
0073 KUrlLabel::KUrlLabel(const QString &url, const QString &text, QWidget *parent)
0074     : QLabel(!text.isNull() ? text : url, parent)
0075     , d(new KUrlLabelPrivate(url, this))
0076 {
0077     setFont(font());
0078     setCursor(QCursor(Qt::PointingHandCursor));
0079     d->setLinkColor(d->linkColor);
0080 }
0081 
0082 KUrlLabel::KUrlLabel(QWidget *parent)
0083     : QLabel(parent)
0084     , d(new KUrlLabelPrivate(QString(), this))
0085 {
0086     setFont(font());
0087     setCursor(QCursor(Qt::PointingHandCursor));
0088     d->setLinkColor(d->linkColor);
0089 }
0090 
0091 KUrlLabel::~KUrlLabel() = default;
0092 
0093 void KUrlLabel::mouseReleaseEvent(QMouseEvent *event)
0094 {
0095     QLabel::mouseReleaseEvent(event);
0096 
0097     d->setLinkColor(d->highlightedLinkColor);
0098     d->timer->start(300);
0099 
0100     switch (event->button()) {
0101     case Qt::LeftButton:
0102         Q_EMIT leftClickedUrl();
0103         break;
0104 
0105     case Qt::MiddleButton:
0106         Q_EMIT middleClickedUrl();
0107         break;
0108 
0109     case Qt::RightButton:
0110         Q_EMIT rightClickedUrl();
0111         break;
0112 
0113     default:
0114         break;
0115     }
0116 }
0117 
0118 void KUrlLabel::setFont(const QFont &font)
0119 {
0120     QFont newFont = font;
0121     newFont.setUnderline(d->textUnderlined);
0122 
0123     QLabel::setFont(newFont);
0124 }
0125 
0126 void KUrlLabel::setUnderline(bool on)
0127 {
0128     d->textUnderlined = on;
0129 
0130     setFont(font());
0131 }
0132 
0133 void KUrlLabel::setUrl(const QString &url)
0134 {
0135     if (d->tipText == d->url) { // update the tip as well
0136         d->tipText = url;
0137         setUseTips(d->useTips);
0138     }
0139 
0140     d->url = url;
0141 }
0142 
0143 QString KUrlLabel::url() const
0144 {
0145     return d->url;
0146 }
0147 
0148 void KUrlLabel::setUseCursor(bool on, QCursor *cursor)
0149 {
0150     d->useCursor = on;
0151     d->cursor = cursor;
0152 
0153     if (on) {
0154         if (cursor) {
0155             setCursor(*cursor);
0156         } else {
0157             setCursor(QCursor(Qt::PointingHandCursor));
0158         }
0159     } else {
0160         unsetCursor();
0161     }
0162 }
0163 
0164 bool KUrlLabel::useCursor() const
0165 {
0166     return d->useCursor;
0167 }
0168 
0169 void KUrlLabel::setUseTips(bool on)
0170 {
0171     d->useTips = on;
0172 
0173     if (on) {
0174         setToolTip(d->tipText);
0175     } else {
0176         setToolTip(QString());
0177     }
0178 }
0179 
0180 void KUrlLabel::setTipText(const QString &tipText)
0181 {
0182     d->tipText = tipText;
0183 
0184     setUseTips(d->useTips);
0185 }
0186 
0187 bool KUrlLabel::useTips() const
0188 {
0189     return d->useTips;
0190 }
0191 
0192 QString KUrlLabel::tipText() const
0193 {
0194     return d->tipText;
0195 }
0196 
0197 void KUrlLabel::setHighlightedColor(const QColor &color)
0198 {
0199     d->linkColor = color;
0200 
0201     if (!d->timer->isActive()) {
0202         d->setLinkColor(color);
0203     }
0204 }
0205 
0206 void KUrlLabel::setHighlightedColor(const QString &color)
0207 {
0208     setHighlightedColor(QColor(color));
0209 }
0210 
0211 void KUrlLabel::setSelectedColor(const QColor &color)
0212 {
0213     d->highlightedLinkColor = color;
0214 
0215     if (d->timer->isActive()) {
0216         d->setLinkColor(color);
0217     }
0218 }
0219 
0220 void KUrlLabel::setSelectedColor(const QString &color)
0221 {
0222     setSelectedColor(QColor(color));
0223 }
0224 
0225 void KUrlLabel::setGlowEnabled(bool glowEnabled)
0226 {
0227     d->glowEnabled = glowEnabled;
0228 }
0229 
0230 void KUrlLabel::setFloatEnabled(bool floatEnabled)
0231 {
0232     d->floatEnabled = floatEnabled;
0233 }
0234 
0235 bool KUrlLabel::isGlowEnabled() const
0236 {
0237     return d->glowEnabled;
0238 }
0239 
0240 bool KUrlLabel::isFloatEnabled() const
0241 {
0242     return d->floatEnabled;
0243 }
0244 
0245 void KUrlLabel::setAlternatePixmap(const QPixmap &pixmap)
0246 {
0247     d->alternatePixmap = pixmap;
0248 }
0249 
0250 const QPixmap *KUrlLabel::alternatePixmap() const
0251 {
0252     return &d->alternatePixmap;
0253 }
0254 
0255 void KUrlLabel::enterEvent(QEnterEvent *event)
0256 {
0257     QLabel::enterEvent(event);
0258 
0259     if (!d->alternatePixmap.isNull()) {
0260         const auto currentPixmap = pixmap(Qt::ReturnByValue);
0261         if (!currentPixmap.isNull()) {
0262             d->realPixmap = currentPixmap;
0263             setPixmap(d->alternatePixmap);
0264         }
0265     }
0266 
0267     if (d->glowEnabled || d->floatEnabled) {
0268         d->timer->stop();
0269 
0270         d->setLinkColor(d->highlightedLinkColor);
0271 
0272         d->realUnderlined = d->textUnderlined;
0273 
0274         if (d->floatEnabled) {
0275             setUnderline(true);
0276         }
0277     }
0278     Q_EMIT enteredUrl();
0279 }
0280 
0281 void KUrlLabel::leaveEvent(QEvent *event)
0282 {
0283     QLabel::leaveEvent(event);
0284 
0285     if (!d->alternatePixmap.isNull() && !pixmap(Qt::ReturnByValue).isNull()) {
0286         setPixmap(d->realPixmap);
0287     }
0288 
0289     if ((d->glowEnabled || d->floatEnabled) && !d->timer->isActive()) {
0290         d->setLinkColor(d->linkColor);
0291     }
0292 
0293     setUnderline(d->realUnderlined);
0294     Q_EMIT leftUrl();
0295 }
0296 
0297 bool KUrlLabel::event(QEvent *event)
0298 {
0299     if (event->type() == QEvent::PaletteChange) {
0300         // Use parentWidget() unless you are a toplevel widget, then try qAapp
0301         QPalette palette = parentWidget() ? parentWidget()->palette() : qApp->palette();
0302 
0303         palette.setBrush(QPalette::Base, palette.brush(QPalette::Normal, QPalette::Window));
0304         palette.setColor(QPalette::WindowText, this->palette().color(QPalette::Active, QPalette::WindowText));
0305         setPalette(palette);
0306 
0307         d->linkColor = palette.color(QPalette::Active, QPalette::Link);
0308         d->updateColor();
0309 
0310         return true;
0311     } else {
0312         return QLabel::event(event);
0313     }
0314 }
0315 
0316 #include "moc_kurllabel.cpp"