File indexing completed on 2024-04-14 05:41:12
0001 /** 0002 * SPDX-FileCopyrightText: (C) 2003 Sébastien Laoût <slaout@linux62.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "linklabel.h" 0008 0009 #include <QApplication> 0010 #include <QBoxLayout> 0011 #include <QCheckBox> 0012 #include <QCursor> 0013 #include <QFrame> 0014 #include <QGridLayout> 0015 #include <QGroupBox> 0016 #include <QHBoxLayout> 0017 #include <QLabel> 0018 #include <QLayout> 0019 #include <QLocale> 0020 #include <QPainter> 0021 #include <QPixmap> 0022 #include <QStyle> 0023 #include <QUrl> 0024 #include <QVBoxLayout> 0025 #include <QtCore/QEvent> 0026 0027 #include <KAboutData> 0028 #include <KCModule> 0029 #include <KComboBox> 0030 #include <KIconLoader> 0031 #include <KLocalizedString> 0032 0033 #include "global.h" 0034 #include "htmlexporter.h" 0035 #include "kcolorcombo2.h" 0036 #include "tools.h" 0037 #include "variouswidgets.h" 0038 0039 /** LinkLook */ 0040 0041 LinkLook *LinkLook::soundLook = new LinkLook(/*useLinkColor=*/false, /*canPreview=*/false); 0042 LinkLook *LinkLook::fileLook = new LinkLook(/*useLinkColor=*/false, /*canPreview=*/true); 0043 LinkLook *LinkLook::localLinkLook = new LinkLook(/*useLinkColor=*/true, /*canPreview=*/true); 0044 LinkLook *LinkLook::networkLinkLook = new LinkLook(/*useLinkColor=*/true, /*canPreview=*/false); 0045 LinkLook *LinkLook::launcherLook = new LinkLook(/*useLinkColor=*/true, /*canPreview=*/false); 0046 LinkLook *LinkLook::crossReferenceLook = new LinkLook(/*useLinkColor=*/true, /*canPreview=*/false); 0047 0048 LinkLook::LinkLook(bool useLinkColor, bool canPreview) 0049 { 0050 m_useLinkColor = useLinkColor; 0051 m_canPreview = canPreview; 0052 m_iconSize = 0; 0053 } 0054 0055 LinkLook::LinkLook(const LinkLook &other) 0056 { 0057 m_useLinkColor = other.useLinkColor(); 0058 m_canPreview = other.canPreview(); 0059 setLook(other.italic(), other.bold(), other.underlining(), other.color(), other.hoverColor(), other.iconSize(), other.preview()); 0060 } 0061 0062 void LinkLook::setLook(bool italic, bool bold, int underlining, QColor color, QColor hoverColor, int iconSize, int preview) 0063 { 0064 m_italic = italic; 0065 m_bold = bold; 0066 m_underlining = underlining; 0067 m_color = color; 0068 m_hoverColor = hoverColor; 0069 m_iconSize = iconSize; 0070 m_preview = (canPreview() ? preview : None); 0071 } 0072 0073 int LinkLook::previewSize() const 0074 { 0075 if (previewEnabled()) { 0076 switch (preview()) { 0077 default: 0078 case None: 0079 return 0; 0080 case IconSize: 0081 return iconSize(); 0082 case TwiceIconSize: 0083 return iconSize() * 2; 0084 case ThreeIconSize: 0085 return iconSize() * 3; 0086 } 0087 } else 0088 return 0; 0089 } 0090 0091 QColor LinkLook::effectiveColor() const 0092 { 0093 if (m_color.isValid()) 0094 return m_color; 0095 else 0096 return defaultColor(); 0097 } 0098 0099 QColor LinkLook::effectiveHoverColor() const 0100 { 0101 if (m_hoverColor.isValid()) 0102 return m_hoverColor; 0103 else 0104 return defaultHoverColor(); 0105 } 0106 0107 QColor LinkLook::defaultColor() const 0108 { 0109 if (m_useLinkColor) 0110 return qApp->palette().color(QPalette::Link); 0111 else 0112 return qApp->palette().color(QPalette::Text); 0113 } 0114 0115 QColor LinkLook::defaultHoverColor() const 0116 { 0117 return Qt::red; 0118 } 0119 0120 LinkLook *LinkLook::lookForURL(const QUrl &url) 0121 { 0122 return url.isLocalFile() ? localLinkLook : networkLinkLook; 0123 } 0124 0125 QString LinkLook::toCSS(const QString &cssClass, const QColor &defaultTextColor) const 0126 { 0127 // Set the link class: 0128 QString css = QString("{ display: block; width: 100%;"); 0129 if (underlineOutside()) 0130 css += " text-decoration: underline;"; 0131 else 0132 css += " text-decoration: none;"; 0133 if (m_italic == true) 0134 css += " font-style: italic;"; 0135 if (m_bold == true) 0136 css += " font-weight: bold;"; 0137 QColor textColor = (color().isValid() || m_useLinkColor ? effectiveColor() : defaultTextColor); 0138 css += QString(" color: %1; }\n").arg(textColor.name()); 0139 0140 QString css2 = css; 0141 css.prepend(QString(" .%1 a").arg(cssClass)); 0142 css2.prepend(QString(" a.%1").arg(cssClass)); 0143 0144 // Set the hover state class: 0145 QString hover; 0146 if (m_underlining == OnMouseHover) 0147 hover = "text-decoration: underline;"; 0148 else if (m_underlining == OnMouseOutside) 0149 hover = "text-decoration: none;"; 0150 if (effectiveHoverColor() != effectiveColor()) { 0151 if (!hover.isEmpty()) 0152 hover += ' '; 0153 hover += QString("color: %4;").arg(effectiveHoverColor().name()); 0154 } 0155 0156 // But include it only if it contain a different style than non-hover state: 0157 if (!hover.isEmpty()) { 0158 css += QString(" .%1 a:hover { %2 }\n").arg(cssClass, hover); 0159 css2 += QString(" a:hover.%1 { %2 }\n").arg(cssClass, hover); 0160 } 0161 return css + css2; 0162 } 0163 0164 /** LinkLabel */ 0165 0166 LinkLabel::LinkLabel(int hAlign, int vAlign, QWidget *parent, Qt::WindowFlags f) 0167 : QFrame(parent, f) 0168 , m_isSelected(false) 0169 , m_isHovered(false) 0170 , m_look(nullptr) 0171 { 0172 initLabel(hAlign, vAlign); 0173 } 0174 0175 LinkLabel::LinkLabel(const QString &title, const QString &icon, LinkLook *look, int hAlign, int vAlign, QWidget *parent, Qt::WindowFlags f) 0176 : QFrame(parent, f) 0177 , m_isSelected(false) 0178 , m_isHovered(false) 0179 , m_look(nullptr) 0180 { 0181 initLabel(hAlign, vAlign); 0182 setLink(title, icon, look); 0183 } 0184 0185 void LinkLabel::initLabel(int hAlign, int vAlign) 0186 { 0187 m_layout = new QBoxLayout(QBoxLayout::LeftToRight, this); 0188 m_icon = new QLabel(this); 0189 m_title = new QLabel(this); 0190 m_spacer1 = new QSpacerItem(0, 0, QSizePolicy::Preferred /*Expanding*/, QSizePolicy::Preferred /*Expanding*/); 0191 m_spacer2 = new QSpacerItem(0, 0, QSizePolicy::Preferred /*Expanding*/, QSizePolicy::Preferred /*Expanding*/); 0192 0193 m_hAlign = hAlign; 0194 m_vAlign = vAlign; 0195 0196 m_title->setTextFormat(Qt::PlainText); 0197 0198 // DEGUB: 0199 // m_icon->setPaletteBackgroundColor("lightblue"); 0200 // m_title->setPaletteBackgroundColor("lightyellow"); 0201 } 0202 0203 LinkLabel::~LinkLabel() 0204 { 0205 } 0206 0207 void LinkLabel::setLink(const QString &title, const QString &icon, LinkLook *look) 0208 { 0209 if (look) 0210 m_look = look; // Needed for icon size 0211 0212 m_title->setText(title); 0213 m_title->setVisible(!title.isEmpty()); 0214 0215 if (icon.isEmpty()) 0216 m_icon->clear(); 0217 else { 0218 QPixmap pixmap = QIcon::fromTheme(icon).pixmap(m_look->iconSize()); 0219 if (!pixmap.isNull()) 0220 m_icon->setPixmap(pixmap); 0221 } 0222 m_icon->setVisible(!icon.isEmpty()); 0223 0224 if (look) 0225 setLook(look); 0226 } 0227 0228 void LinkLabel::setLook(LinkLook *look) // FIXME: called externally (so, without setLink()) it's buggy (icon not 0229 { 0230 m_look = look; 0231 0232 QFont font; 0233 font.setBold(look->bold()); 0234 font.setUnderline(look->underlineOutside()); 0235 font.setItalic(look->italic()); 0236 m_title->setFont(font); 0237 QPalette palette; 0238 if (m_isSelected) 0239 palette.setColor(m_title->foregroundRole(), QApplication::palette().color(QPalette::Text)); 0240 else 0241 palette.setColor(m_title->foregroundRole(), look->effectiveColor()); 0242 0243 m_title->setPalette(palette); 0244 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) 0245 m_icon->setVisible(!m_icon->pixmap(Qt::ReturnByValueConstant::ReturnByValue).isNull()); 0246 #else 0247 m_icon->setVisible(m_icon->pixmap() && !m_icon->pixmap()->isNull()); 0248 #endif 0249 setAlign(m_hAlign, m_vAlign); 0250 } 0251 0252 void LinkLabel::setAlign(int hAlign, int vAlign) 0253 { 0254 m_hAlign = hAlign; 0255 m_vAlign = vAlign; 0256 0257 if (!m_look) 0258 return; 0259 0260 // Define alignment flags : 0261 Qt::Alignment hFlag, vFlag; 0262 switch (hAlign) { 0263 default: 0264 case 0: 0265 hFlag = Qt::AlignLeft; 0266 break; 0267 case 1: 0268 hFlag = Qt::AlignHCenter; 0269 break; 0270 case 2: 0271 hFlag = Qt::AlignRight; 0272 break; 0273 } 0274 switch (vAlign) { 0275 case 0: 0276 vFlag = Qt::AlignTop; 0277 break; 0278 default: 0279 case 1: 0280 vFlag = Qt::AlignVCenter; 0281 break; 0282 case 2: 0283 vFlag = Qt::AlignBottom; 0284 break; 0285 } 0286 0287 // Clear the widget : 0288 m_layout->removeItem(m_spacer1); 0289 m_layout->removeWidget(m_icon); 0290 m_layout->removeWidget(m_title); 0291 m_layout->removeItem(m_spacer2); 0292 0293 // Otherwise, minimumSize will be incoherent (last size ? ) 0294 m_layout->setSizeConstraint(QLayout::SetMinimumSize); 0295 0296 // And re-populate the widget with the appropriates things and order 0297 bool addSpacers = (hAlign == 1); 0298 m_layout->setDirection(QBoxLayout::LeftToRight); 0299 // m_title->setSizePolicy( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Maximum/*Expanding*/, 0, 0, false) ); 0300 m_icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); 0301 m_spacer1->changeSize(QSizePolicy::Expanding, QSizePolicy::Preferred); 0302 m_spacer2->changeSize(QSizePolicy::Expanding, QSizePolicy::Preferred); 0303 0304 m_icon->setAlignment(hFlag | vFlag); 0305 m_title->setAlignment(hFlag | vFlag); 0306 if (hAlign) 0307 m_title->setWordWrap(true); 0308 0309 if ((addSpacers && (vAlign != 0)) || (m_title->text().isEmpty() && hAlign == 2)) 0310 m_layout->addItem(m_spacer1); 0311 if (hAlign == 2) { // If align at right, icon is at right 0312 m_layout->addWidget(m_title); 0313 m_layout->addWidget(m_icon); 0314 } else { 0315 m_layout->addWidget(m_icon); 0316 m_layout->addWidget(m_title); 0317 } 0318 if ((addSpacers && (vAlign != 2)) || (m_title->text().isEmpty() && hAlign == 0)) 0319 m_layout->addItem(m_spacer2); 0320 } 0321 0322 void LinkLabel::enterEvent(QEvent *) 0323 { 0324 m_isHovered = true; 0325 0326 if (!m_isSelected) { 0327 QPalette palette; 0328 palette.setColor(m_title->foregroundRole(), m_look->effectiveHoverColor()); 0329 m_title->setPalette(palette); 0330 } 0331 0332 QFont font = m_title->font(); 0333 font.setUnderline(m_look->underlineInside()); 0334 m_title->setFont(font); 0335 } 0336 0337 void LinkLabel::leaveEvent(QEvent *) 0338 { 0339 m_isHovered = false; 0340 0341 if (!m_isSelected) { 0342 QPalette palette; 0343 palette.setColor(m_title->foregroundRole(), m_look->effectiveColor()); 0344 m_title->setPalette(palette); 0345 } 0346 0347 QFont font = m_title->font(); 0348 font.setUnderline(m_look->underlineOutside()); 0349 m_title->setFont(font); 0350 } 0351 0352 void LinkLabel::setSelected(bool selected) 0353 { 0354 m_isSelected = selected; 0355 QPalette palette; 0356 0357 if (selected) 0358 palette.setColor(m_title->foregroundRole(), QApplication::palette().color(QPalette::HighlightedText)); 0359 else if (m_isHovered) 0360 palette.setColor(m_title->foregroundRole(), m_look->effectiveHoverColor()); 0361 else 0362 palette.setColor(m_title->foregroundRole(), m_look->effectiveColor()); 0363 0364 m_title->setPalette(palette); 0365 } 0366 0367 void LinkLabel::setPaletteBackgroundColor(const QColor &color) 0368 { 0369 QPalette framePalette; 0370 framePalette.setColor(QFrame::foregroundRole(), color); 0371 QFrame::setPalette(framePalette); 0372 0373 QPalette titlePalette; 0374 titlePalette.setColor(m_title->foregroundRole(), color); 0375 m_title->setPalette(titlePalette); 0376 } 0377 0378 int LinkLabel::heightForWidth(int w) const 0379 { 0380 int iconS = (m_icon->isVisible()) ? m_look->iconSize() : 0; // Icon size 0381 int iconW = iconS; // Icon width to remove to w 0382 int titleH = (m_title->isVisible()) ? m_title->heightForWidth(w - iconW) : 0; // Title height 0383 0384 return (titleH >= iconS) ? titleH : iconS; // No margin for the moment ! 0385 } 0386 0387 /** class LinkDisplay 0388 */ 0389 0390 LinkDisplay::LinkDisplay() 0391 : m_title() 0392 , m_icon() 0393 , m_preview() 0394 , m_look(nullptr) 0395 , m_font() 0396 , m_minWidth(0) 0397 , m_width(0) 0398 , m_height(0) 0399 { 0400 } 0401 0402 void LinkDisplay::setLink(const QString &title, const QString &icon, LinkLook *look, const QFont &font) 0403 { 0404 setLink(title, icon, m_preview, look, font); 0405 } 0406 0407 void LinkDisplay::setLink(const QString &title, const QString &icon, const QPixmap &preview, LinkLook *look, const QFont &font) 0408 { 0409 m_title = title; 0410 m_icon = icon; 0411 m_preview = preview; 0412 m_look = look; 0413 m_font = font; 0414 0415 // "Constants": 0416 int BUTTON_MARGIN = qApp->style()->pixelMetric(QStyle::PM_ButtonMargin); 0417 int LINK_MARGIN = BUTTON_MARGIN + 2; 0418 0419 // Recompute m_minWidth: 0420 QRect textRect = QFontMetrics(labelFont(font, false)).boundingRect(0, 0, /*width=*/1, 500000, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, m_title); 0421 int iconPreviewWidth = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.width() : 0)); 0422 m_minWidth = BUTTON_MARGIN - 1 + iconPreviewWidth + LINK_MARGIN + textRect.width(); 0423 // Recompute m_maxWidth: 0424 textRect = QFontMetrics(labelFont(font, false)).boundingRect(0, 0, /*width=*/50000000, 500000, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, m_title); 0425 m_maxWidth = BUTTON_MARGIN - 1 + iconPreviewWidth + LINK_MARGIN + textRect.width(); 0426 // Adjust m_width: 0427 if (m_width < m_minWidth) 0428 setWidth(m_minWidth); 0429 // Recompute m_height: 0430 m_height = heightForWidth(m_width); 0431 } 0432 0433 void LinkDisplay::setWidth(qreal width) 0434 { 0435 if (width < m_minWidth) 0436 width = m_minWidth; 0437 0438 if (width != m_width) { 0439 m_width = width; 0440 m_height = heightForWidth(m_width); 0441 } 0442 } 0443 0444 /** Paint on @p painter 0445 * in (@p x, @p y, @p width, @p height) 0446 * using @p palette for the button drawing (if @p isHovered) 0447 * and the LinkLook color() for the text, 0448 * unless [the LinkLook !color.isValid() and it does not useLinkColor()] or [@p isDefaultColor is false]: in this case it will use @p palette's active text color. 0449 * It will draw the button if @p isIconButtonHovered. 0450 */ 0451 void LinkDisplay::paint(QPainter *painter, qreal x, qreal y, qreal width, qreal height, const QPalette &palette, bool isDefaultColor, bool isSelected, bool isHovered, bool isIconButtonHovered) const 0452 { 0453 qreal BUTTON_MARGIN = qApp->style()->pixelMetric(QStyle::PM_ButtonMargin); 0454 qreal LINK_MARGIN = BUTTON_MARGIN + 2; 0455 0456 QPixmap pixmap; 0457 // Load the preview...: 0458 if (!isHovered && m_look->previewEnabled() && !m_preview.isNull()) 0459 pixmap = m_preview; 0460 // ... Or the icon (if no preview or if the "Open" icon should be shown): 0461 else { 0462 qreal iconSize = m_look->iconSize(); 0463 QString iconName = (isHovered ? Global::openNoteIcon() : m_icon); 0464 KIconLoader::States iconState = (isIconButtonHovered ? KIconLoader::ActiveState : KIconLoader::DefaultState); 0465 pixmap = KIconLoader::global()->loadIcon(iconName, KIconLoader::Desktop, iconSize, iconState, QStringList(), nullptr, /*canReturnNull=*/false); 0466 } 0467 qreal iconPreviewWidth = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.width() : 0)); 0468 qreal pixmapX = (iconPreviewWidth - pixmap.width()) / 2; 0469 qreal pixmapY = (height - pixmap.height()) / 2; 0470 // Draw the button (if any) and the icon: 0471 if (isHovered) { 0472 QStyleOption opt; 0473 opt.rect = QRect(-1, -1, iconPreviewWidth + 2 * BUTTON_MARGIN, height + 2); 0474 opt.state = isIconButtonHovered ? (QStyle::State_MouseOver | QStyle::State_Enabled) : QStyle::State_Enabled; 0475 qApp->style()->drawPrimitive(QStyle::PE_PanelButtonCommand, &opt, painter); 0476 } 0477 painter->drawPixmap(x + BUTTON_MARGIN - 1 + pixmapX, y + pixmapY, pixmap); 0478 0479 // Figure out the text color: 0480 if (isSelected) { 0481 painter->setPen(qApp->palette().color(QPalette::HighlightedText)); 0482 } else if (isIconButtonHovered) 0483 painter->setPen(m_look->effectiveHoverColor()); 0484 else if (!isDefaultColor || (!m_look->color().isValid() && !m_look->useLinkColor())) // If the color is FORCED or if the link color default to the text color: 0485 painter->setPen(palette.color(QPalette::Active, QPalette::WindowText)); 0486 else 0487 painter->setPen(m_look->effectiveColor()); 0488 // Draw the text: 0489 painter->setFont(labelFont(m_font, isIconButtonHovered)); 0490 painter->drawText(x + BUTTON_MARGIN - 1 + iconPreviewWidth + LINK_MARGIN, y, width - BUTTON_MARGIN + 1 - iconPreviewWidth - LINK_MARGIN, height, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, m_title); 0491 } 0492 0493 QPixmap LinkDisplay::feedbackPixmap(qreal width, qreal height, const QPalette &palette, bool isDefaultColor) 0494 { 0495 qreal theWidth = qMin(width, maxWidth()); 0496 qreal theHeight = qMin(height, heightForWidth(theWidth)); 0497 QPixmap pixmap(theWidth, theHeight); 0498 pixmap.fill(palette.color(QPalette::Active, QPalette::Background)); 0499 QPainter painter(&pixmap); 0500 paint(&painter, 0501 0, 0502 0, 0503 theWidth, 0504 theHeight, 0505 palette, 0506 isDefaultColor, 0507 /*isSelected=*/false, 0508 /*isHovered=*/false, 0509 /*isIconButtonHovered=*/false); 0510 painter.end(); 0511 return pixmap; 0512 } 0513 0514 bool LinkDisplay::iconButtonAt(const QPointF &pos) const 0515 { 0516 qreal BUTTON_MARGIN = qApp->style()->pixelMetric(QStyle::PM_ButtonMargin); 0517 // int LINK_MARGIN = BUTTON_MARGIN + 2; 0518 qreal iconPreviewWidth = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.width() : 0)); 0519 0520 return pos.x() <= BUTTON_MARGIN - 1 + iconPreviewWidth + BUTTON_MARGIN; 0521 } 0522 0523 QRectF LinkDisplay::iconButtonRect() const 0524 { 0525 qreal BUTTON_MARGIN = qApp->style()->pixelMetric(QStyle::PM_ButtonMargin); 0526 // int LINK_MARGIN = BUTTON_MARGIN + 2; 0527 qreal iconPreviewWidth = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.width() : 0)); 0528 0529 return QRectF(0, 0, BUTTON_MARGIN - 1 + iconPreviewWidth + BUTTON_MARGIN, m_height); 0530 } 0531 0532 QFont LinkDisplay::labelFont(QFont font, bool isIconButtonHovered) const 0533 { 0534 if (m_look->italic()) 0535 font.setItalic(true); 0536 if (m_look->bold()) 0537 font.setBold(true); 0538 if (isIconButtonHovered) { 0539 if (m_look->underlineInside()) 0540 font.setUnderline(true); 0541 } else { 0542 if (m_look->underlineOutside()) 0543 font.setUnderline(true); 0544 } 0545 return font; 0546 } 0547 0548 qreal LinkDisplay::heightForWidth(qreal width) const 0549 { 0550 qreal BUTTON_MARGIN = qApp->style()->pixelMetric(QStyle::PM_ButtonMargin); 0551 qreal LINK_MARGIN = BUTTON_MARGIN + 2; 0552 qreal iconPreviewWidth = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.width() : 0)); 0553 qreal iconPreviewHeight = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.height() : 0)); 0554 0555 QRectF textRect = QFontMetrics(labelFont(m_font, false)).boundingRect(0, 0, width - BUTTON_MARGIN + 1 - iconPreviewWidth - LINK_MARGIN, 500000, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, m_title); 0556 return qMax(textRect.height(), iconPreviewHeight + 2 * BUTTON_MARGIN - 2); 0557 } 0558 0559 QString LinkDisplay::toHtml(const QString & /*imageName*/) const 0560 { 0561 // TODO 0562 return QString(); 0563 } 0564 0565 QString LinkDisplay::toHtml(HTMLExporter *exporter, const QUrl &url, const QString &title) 0566 { 0567 QString linkIcon; 0568 if (m_look->previewEnabled() && !m_preview.isNull()) { 0569 QString fileName = Tools::fileNameForNewFile("preview_" + url.fileName() + ".png", exporter->iconsFolderPath); 0570 QString fullPath = exporter->iconsFolderPath + fileName; 0571 m_preview.save(fullPath, "PNG"); 0572 linkIcon = QString("<img src=\"%1\" width=\"%2\" height=\"%3\" alt=\"\">").arg(exporter->iconsFolderName + fileName, QString::number(m_preview.width()), QString::number(m_preview.height())); 0573 } else { 0574 linkIcon = exporter->iconsFolderName + exporter->copyIcon(m_icon, m_look->iconSize()); 0575 linkIcon = QString("<img src=\"%1\" width=\"%2\" height=\"%3\" alt=\"\">").arg(linkIcon, QString::number(m_look->iconSize()), QString::number(m_look->iconSize())); 0576 } 0577 0578 QString linkTitle = Tools::textToHTMLWithoutP(title.isEmpty() ? m_title : title); 0579 0580 return QString("<a href=\"%1\">%2 %3</a>").arg(url.toDisplayString(), linkIcon, linkTitle); 0581 } 0582 0583 /** LinkLookEditWidget **/ 0584 0585 LinkLookEditWidget::LinkLookEditWidget(KCModule *module, const QString exTitle, const QString exIcon, QWidget *parent, Qt::WindowFlags fl) 0586 : QWidget(parent, fl) 0587 { 0588 QLabel *label; 0589 QVBoxLayout *layout = new QVBoxLayout(this); 0590 0591 m_italic = new QCheckBox(i18n("I&talic"), this); 0592 layout->addWidget(m_italic); 0593 0594 m_bold = new QCheckBox(i18n("&Bold"), this); 0595 layout->addWidget(m_bold); 0596 0597 QGridLayout *gl = new QGridLayout; 0598 layout->addLayout(gl); 0599 gl->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding), 1, /*2*/ 3); 0600 0601 m_underlining = new KComboBox(this); 0602 m_underlining->addItem(i18n("Always")); 0603 m_underlining->addItem(i18n("Never")); 0604 m_underlining->addItem(i18n("On mouse hovering")); 0605 m_underlining->addItem(i18n("When mouse is outside")); 0606 label = new QLabel(this); 0607 label->setText(i18n("&Underline:")); 0608 label->setBuddy(m_underlining); 0609 gl->addWidget(label, 0, 0); 0610 gl->addWidget(m_underlining, 0, 1); 0611 0612 m_color = new KColorCombo2(QRgb(), this); 0613 label = new QLabel(this); 0614 label->setText(i18n("Colo&r:")); 0615 label->setBuddy(m_color); 0616 gl->addWidget(label, 1, 0); 0617 gl->addWidget(m_color, 1, 1); 0618 0619 m_hoverColor = new KColorCombo2(QRgb(), this); 0620 label = new QLabel(this); 0621 label->setText(i18n("&Mouse hover color:")); 0622 label->setBuddy(m_hoverColor); 0623 gl->addWidget(label, 2, 0); 0624 gl->addWidget(m_hoverColor, 2, 1); 0625 0626 QHBoxLayout *icoLay = new QHBoxLayout(nullptr); 0627 m_iconSize = new IconSizeCombo(this); 0628 icoLay->addWidget(m_iconSize); 0629 label = new QLabel(this); 0630 label->setText(i18n("&Icon size:")); 0631 label->setBuddy(m_iconSize); 0632 gl->addWidget(label, 3, 0); 0633 gl->addItem(icoLay, 3, 1); 0634 0635 m_preview = new KComboBox(this); 0636 m_preview->addItem(i18n("None")); 0637 m_preview->addItem(i18n("Icon size")); 0638 m_preview->addItem(i18n("Twice the icon size")); 0639 m_preview->addItem(i18n("Three times the icon size")); 0640 m_label = new QLabel(this); 0641 m_label->setText(i18n("&Preview:")); 0642 m_label->setBuddy(m_preview); 0643 m_hLabel = new HelpLabel(i18n("You disabled preview but still see images?"), 0644 i18n("<p>This is normal because there are several type of notes.<br>" 0645 "This setting only applies to file and local link notes.<br>" 0646 "The images you see are image notes, not file notes.<br>" 0647 "File notes are generic documents, whereas image notes are pictures you can draw in.</p>" 0648 "<p>When dropping files to baskets, %1 detects their type and shows you the content of the files.<br>" 0649 "For instance, when dropping image or text files, image and text notes are created for them.<br>" 0650 "For type of files %2 does not understand, they are shown as generic file notes with just an icon or file preview and a filename.</p>" 0651 "<p>If you do not want the application to create notes depending on the content of the files you drop, " 0652 "go to the \"General\" page and uncheck \"Image or animation\" in the \"View Content of Added Files for the Following Types\" group.</p>", 0653 // TODO: Note: you can resize down maximum size of images... 0654 QGuiApplication::applicationDisplayName(), 0655 QGuiApplication::applicationDisplayName()), 0656 this); 0657 gl->addWidget(m_label, 4, 0); 0658 gl->addWidget(m_preview, 4, 1); 0659 gl->addWidget(m_hLabel, 5, 1, 1, 2); 0660 0661 QGroupBox *gb = new QGroupBox(i18n("Example"), this); 0662 QHBoxLayout *gbLayout = new QHBoxLayout; 0663 gb->setLayout(gbLayout); 0664 0665 m_exLook = new LinkLook; 0666 m_example = new LinkLabel(exTitle, exIcon, m_exLook, 1, 1); 0667 gbLayout->addWidget(m_example); 0668 m_example->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0669 m_example->setCursor(QCursor(Qt::PointingHandCursor)); 0670 layout->addWidget(gb); 0671 m_exTitle = exTitle; 0672 m_exIcon = exIcon; 0673 0674 connect(m_italic, &QCheckBox::stateChanged, this, &LinkLookEditWidget::slotChangeLook); 0675 connect(m_bold, &QCheckBox::stateChanged, this, &LinkLookEditWidget::slotChangeLook); 0676 connect(m_underlining, SIGNAL(activated(int)), this, SLOT(slotChangeLook())); 0677 connect(m_color, SIGNAL(activated(int)), this, SLOT(slotChangeLook())); 0678 connect(m_hoverColor, SIGNAL(activated(int)), this, SLOT(slotChangeLook())); 0679 connect(m_iconSize, SIGNAL(activated(int)), this, SLOT(slotChangeLook())); 0680 connect(m_preview, SIGNAL(activated(int)), this, SLOT(slotChangeLook())); 0681 0682 connect(m_italic, SIGNAL(stateChanged(int)), module, SLOT(changed())); 0683 connect(m_bold, SIGNAL(stateChanged(int)), module, SLOT(changed())); 0684 connect(m_underlining, SIGNAL(activated(int)), module, SLOT(changed())); 0685 connect(m_color, SIGNAL(activated(int)), module, SLOT(changed())); 0686 connect(m_hoverColor, SIGNAL(activated(int)), module, SLOT(changed())); 0687 connect(m_iconSize, SIGNAL(activated(int)), module, SLOT(changed())); 0688 connect(m_preview, SIGNAL(activated(int)), module, SLOT(changed())); 0689 } 0690 0691 void LinkLookEditWidget::set(LinkLook *look) 0692 { 0693 m_look = look; 0694 0695 m_italic->setChecked(look->italic()); 0696 m_bold->setChecked(look->bold()); 0697 m_underlining->setCurrentIndex(look->underlining()); 0698 m_preview->setCurrentIndex(look->preview()); 0699 m_color->setDefaultColor(m_look->defaultColor()); 0700 m_color->setColor(m_look->color()); 0701 m_hoverColor->setDefaultColor(m_look->defaultHoverColor()); 0702 m_hoverColor->setColor(m_look->hoverColor()); 0703 m_iconSize->setSize(look->iconSize()); 0704 m_exLook = new LinkLook(*look); 0705 m_example->setLook(m_exLook); 0706 0707 if (!look->canPreview()) { 0708 m_label->setEnabled(false); 0709 m_hLabel->setEnabled(false); 0710 m_preview->setEnabled(false); 0711 } 0712 slotChangeLook(); 0713 } 0714 0715 void LinkLookEditWidget::slotChangeLook() 0716 { 0717 saveToLook(m_exLook); 0718 m_example->setLink(m_exTitle, m_exIcon, m_exLook); // and can't reload it at another size 0719 } 0720 0721 LinkLookEditWidget::~LinkLookEditWidget() 0722 { 0723 } 0724 0725 void LinkLookEditWidget::saveChanges() 0726 { 0727 saveToLook(m_look); 0728 } 0729 0730 void LinkLookEditWidget::saveToLook(LinkLook *look) 0731 { 0732 look->setLook(m_italic->isChecked(), m_bold->isChecked(), m_underlining->currentIndex(), m_color->color(), m_hoverColor->color(), m_iconSize->iconSize(), (look->canPreview() ? m_preview->currentIndex() : LinkLook::None)); 0733 } 0734 0735 #include "moc_linklabel.cpp"