File indexing completed on 2024-04-28 15:32:16

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 #if KWIDGETSADDONS_BUILD_DEPRECATED_SINCE(5, 65)
0104         Q_EMIT leftClickedUrl(d->url);
0105 #endif
0106         break;
0107 
0108     case Qt::MiddleButton:
0109         Q_EMIT middleClickedUrl();
0110 #if KWIDGETSADDONS_BUILD_DEPRECATED_SINCE(5, 65)
0111         Q_EMIT middleClickedUrl(d->url);
0112 #endif
0113         break;
0114 
0115     case Qt::RightButton:
0116         Q_EMIT rightClickedUrl();
0117 #if KWIDGETSADDONS_BUILD_DEPRECATED_SINCE(5, 65)
0118         Q_EMIT rightClickedUrl(d->url);
0119 #endif
0120         break;
0121 
0122     default:
0123         break;
0124     }
0125 }
0126 
0127 void KUrlLabel::setFont(const QFont &font)
0128 {
0129     QFont newFont = font;
0130     newFont.setUnderline(d->textUnderlined);
0131 
0132     QLabel::setFont(newFont);
0133 }
0134 
0135 void KUrlLabel::setUnderline(bool on)
0136 {
0137     d->textUnderlined = on;
0138 
0139     setFont(font());
0140 }
0141 
0142 void KUrlLabel::setUrl(const QString &url)
0143 {
0144     if (d->tipText == d->url) { // update the tip as well
0145         d->tipText = url;
0146         setUseTips(d->useTips);
0147     }
0148 
0149     d->url = url;
0150 }
0151 
0152 QString KUrlLabel::url() const
0153 {
0154     return d->url;
0155 }
0156 
0157 void KUrlLabel::setUseCursor(bool on, QCursor *cursor)
0158 {
0159     d->useCursor = on;
0160     d->cursor = cursor;
0161 
0162     if (on) {
0163         if (cursor) {
0164             setCursor(*cursor);
0165         } else {
0166             setCursor(QCursor(Qt::PointingHandCursor));
0167         }
0168     } else {
0169         unsetCursor();
0170     }
0171 }
0172 
0173 bool KUrlLabel::useCursor() const
0174 {
0175     return d->useCursor;
0176 }
0177 
0178 void KUrlLabel::setUseTips(bool on)
0179 {
0180     d->useTips = on;
0181 
0182     if (on) {
0183         setToolTip(d->tipText);
0184     } else {
0185         setToolTip(QString());
0186     }
0187 }
0188 
0189 void KUrlLabel::setTipText(const QString &tipText)
0190 {
0191     d->tipText = tipText;
0192 
0193     setUseTips(d->useTips);
0194 }
0195 
0196 bool KUrlLabel::useTips() const
0197 {
0198     return d->useTips;
0199 }
0200 
0201 QString KUrlLabel::tipText() const
0202 {
0203     return d->tipText;
0204 }
0205 
0206 void KUrlLabel::setHighlightedColor(const QColor &color)
0207 {
0208     d->linkColor = color;
0209 
0210     if (!d->timer->isActive()) {
0211         d->setLinkColor(color);
0212     }
0213 }
0214 
0215 void KUrlLabel::setHighlightedColor(const QString &color)
0216 {
0217     setHighlightedColor(QColor(color));
0218 }
0219 
0220 void KUrlLabel::setSelectedColor(const QColor &color)
0221 {
0222     d->highlightedLinkColor = color;
0223 
0224     if (d->timer->isActive()) {
0225         d->setLinkColor(color);
0226     }
0227 }
0228 
0229 void KUrlLabel::setSelectedColor(const QString &color)
0230 {
0231     setSelectedColor(QColor(color));
0232 }
0233 
0234 void KUrlLabel::setGlowEnabled(bool glowEnabled)
0235 {
0236     d->glowEnabled = glowEnabled;
0237 }
0238 
0239 void KUrlLabel::setFloatEnabled(bool floatEnabled)
0240 {
0241     d->floatEnabled = floatEnabled;
0242 }
0243 
0244 bool KUrlLabel::isGlowEnabled() const
0245 {
0246     return d->glowEnabled;
0247 }
0248 
0249 bool KUrlLabel::isFloatEnabled() const
0250 {
0251     return d->floatEnabled;
0252 }
0253 
0254 void KUrlLabel::setAlternatePixmap(const QPixmap &pixmap)
0255 {
0256     d->alternatePixmap = pixmap;
0257 }
0258 
0259 const QPixmap *KUrlLabel::alternatePixmap() const
0260 {
0261     return &d->alternatePixmap;
0262 }
0263 
0264 void KUrlLabel::enterEvent(QEvent *event)
0265 {
0266     QLabel::enterEvent(event);
0267 
0268     if (!d->alternatePixmap.isNull()) {
0269         const auto currentPixmap = pixmap(Qt::ReturnByValue);
0270         if (!currentPixmap.isNull()) {
0271             d->realPixmap = currentPixmap;
0272             setPixmap(d->alternatePixmap);
0273         }
0274     }
0275 
0276     if (d->glowEnabled || d->floatEnabled) {
0277         d->timer->stop();
0278 
0279         d->setLinkColor(d->highlightedLinkColor);
0280 
0281         d->realUnderlined = d->textUnderlined;
0282 
0283         if (d->floatEnabled) {
0284             setUnderline(true);
0285         }
0286     }
0287     Q_EMIT enteredUrl();
0288 #if KWIDGETSADDONS_BUILD_DEPRECATED_SINCE(5, 65)
0289     Q_EMIT enteredUrl(d->url);
0290 #endif
0291 }
0292 
0293 void KUrlLabel::leaveEvent(QEvent *event)
0294 {
0295     QLabel::leaveEvent(event);
0296 
0297     if (!d->alternatePixmap.isNull() && !pixmap(Qt::ReturnByValue).isNull()) {
0298         setPixmap(d->realPixmap);
0299     }
0300 
0301     if ((d->glowEnabled || d->floatEnabled) && !d->timer->isActive()) {
0302         d->setLinkColor(d->linkColor);
0303     }
0304 
0305     setUnderline(d->realUnderlined);
0306     Q_EMIT leftUrl();
0307 #if KWIDGETSADDONS_BUILD_DEPRECATED_SINCE(5, 65)
0308     Q_EMIT leftUrl(d->url);
0309 #endif
0310 }
0311 
0312 bool KUrlLabel::event(QEvent *event)
0313 {
0314     if (event->type() == QEvent::PaletteChange) {
0315         // Use parentWidget() unless you are a toplevel widget, then try qAapp
0316         QPalette palette = parentWidget() ? parentWidget()->palette() : qApp->palette();
0317 
0318         palette.setBrush(QPalette::Base, palette.brush(QPalette::Normal, QPalette::Window));
0319         palette.setColor(QPalette::WindowText, this->palette().color(QPalette::Active, QPalette::WindowText));
0320         setPalette(palette);
0321 
0322         d->linkColor = palette.color(QPalette::Active, QPalette::Link);
0323         d->updateColor();
0324 
0325         return true;
0326     } else {
0327         return QLabel::event(event);
0328     }
0329 }
0330 
0331 #include "moc_kurllabel.cpp"