1 /***************************************************************************
2 * Copyright (C) 2003 by Sébastien Laoût *
3 * slaout@linux62.org *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 #include "linklabel.h"
22
23 #include <QtCore/QEvent>
24 #include <QLabel>
25 #include <QLayout>
26 #include <QHBoxLayout>
27 #include <QVBoxLayout>
28 #include <QBoxLayout>
29 #include <QGridLayout>
30 #include <QPixmap>
31 #include <QFrame>
32 #include <QCursor>
33 #include <QCheckBox>
34 #include <QPainter>
35 #include <QStyle>
36 #include <QGroupBox>
37 #include <QApplication>
38 #include <QLocale>
39 #include <QUrl>
40
41 #include <KAboutData>
42 #include <KComboBox>
43 #include <KIconLoader>
44 #include <KCModule>
45 #include <KLocalizedString>
46
47 #include "variouswidgets.h"
48 #include "tools.h"
49 #include "global.h"
50 #include "kcolorcombo2.h"
51 #include "htmlexporter.h"
52
53 /** LinkLook */
54
55 LinkLook *LinkLook::soundLook = new LinkLook(/*useLinkColor=*/false, /*canPreview=*/false);
56 LinkLook *LinkLook::fileLook = new LinkLook(/*useLinkColor=*/false, /*canPreview=*/true);
57 LinkLook *LinkLook::localLinkLook = new LinkLook(/*useLinkColor=*/true, /*canPreview=*/true);
58 LinkLook *LinkLook::networkLinkLook = new LinkLook(/*useLinkColor=*/true, /*canPreview=*/false);
59 LinkLook *LinkLook::launcherLook = new LinkLook(/*useLinkColor=*/true, /*canPreview=*/false);
60 LinkLook *LinkLook::crossReferenceLook=new LinkLook(/*useLinkColor=*/true, /*canPreview=*/false);
61
LinkLook(bool useLinkColor,bool canPreview)62 LinkLook::LinkLook(bool useLinkColor, bool canPreview)
63 {
64 m_useLinkColor = useLinkColor;
65 m_canPreview = canPreview;
66 m_iconSize = 0;
67 }
68
LinkLook(const LinkLook & other)69 LinkLook::LinkLook(const LinkLook &other)
70 {
71 m_useLinkColor = other.useLinkColor();
72 m_canPreview = other.canPreview();
73 setLook(other.italic(), other.bold(), other.underlining(),
74 other.color(), other.hoverColor(),
75 other.iconSize(), other.preview());
76 }
77
setLook(bool italic,bool bold,int underlining,QColor color,QColor hoverColor,int iconSize,int preview)78 void LinkLook::setLook(bool italic, bool bold, int underlining,
79 QColor color, QColor hoverColor,
80 int iconSize, int preview)
81 {
82 m_italic = italic;
83 m_bold = bold;
84 m_underlining = underlining;
85 m_color = color;
86 m_hoverColor = hoverColor;
87 m_iconSize = iconSize;
88 m_preview = (canPreview() ? preview : None);
89 }
90
previewSize() const91 int LinkLook::previewSize() const
92 {
93 if (previewEnabled()) {
94 switch (preview()) {
95 default:
96 case None: return 0;
97 case IconSize: return iconSize();
98 case TwiceIconSize: return iconSize() * 2;
99 case ThreeIconSize: return iconSize() * 3;
100 }
101 } else
102 return 0;
103 }
104
effectiveColor() const105 QColor LinkLook::effectiveColor() const
106 {
107 if (m_color.isValid())
108 return m_color;
109 else
110 return defaultColor();
111 }
112
effectiveHoverColor() const113 QColor LinkLook::effectiveHoverColor() const
114 {
115 if (m_hoverColor.isValid())
116 return m_hoverColor;
117 else
118 return defaultHoverColor();
119 }
120
defaultColor() const121 QColor LinkLook::defaultColor() const
122 {
123 if (m_useLinkColor)
124 return qApp->palette().color(QPalette::Link);
125 else
126 return qApp->palette().color(QPalette::Text);
127 }
128
defaultHoverColor() const129 QColor LinkLook::defaultHoverColor() const
130 {
131 return Qt::red;
132 }
133
lookForURL(const QUrl & url)134 LinkLook* LinkLook::lookForURL(const QUrl &url)
135 {
136 return url.isLocalFile() ? localLinkLook : networkLinkLook;
137 }
138
toCSS(const QString & cssClass,const QColor & defaultTextColor) const139 QString LinkLook::toCSS(const QString &cssClass, const QColor &defaultTextColor) const
140 {
141 // Set the link class:
142 QString css = QString("{ display: block; width: 100%;");
143 if (underlineOutside())
144 css += " text-decoration: underline;";
145 else
146 css += " text-decoration: none;";
147 if (m_italic == true)
148 css += " font-style: italic;";
149 if (m_bold == true)
150 css += " font-weight: bold;";
151 QColor textColor = (color().isValid() || m_useLinkColor ? effectiveColor() : defaultTextColor);
152 css += QString(" color: %1; }\n").arg(textColor.name());
153
154 QString css2 = css;
155 css.prepend(QString(" .%1 a").arg(cssClass));
156 css2.prepend(QString(" a.%1").arg(cssClass));
157
158 // Set the hover state class:
159 QString hover;
160 if (m_underlining == OnMouseHover)
161 hover = "text-decoration: underline;";
162 else if (m_underlining == OnMouseOutside)
163 hover = "text-decoration: none;";
164 if (effectiveHoverColor() != effectiveColor()) {
165 if (!hover.isEmpty())
166 hover += " ";
167 hover += QString("color: %4;").arg(effectiveHoverColor().name());
168 }
169
170 // But include it only if it contain a different style than non-hover state:
171 if (!hover.isEmpty()) {
172 css += QString(" .%1 a:hover { %2 }\n").arg(cssClass, hover);
173 css2 += QString(" a:hover.%1 { %2 }\n").arg(cssClass, hover);
174 }
175 return css + css2;
176 }
177
178 /** LinkLabel */
179
LinkLabel(int hAlign,int vAlign,QWidget * parent,Qt::WindowFlags f)180 LinkLabel::LinkLabel(int hAlign, int vAlign, QWidget *parent, Qt::WindowFlags f)
181 : QFrame(parent, f), m_isSelected(false), m_isHovered(false), m_look(0)
182 {
183 initLabel(hAlign, vAlign);
184 }
185
LinkLabel(const QString & title,const QString & icon,LinkLook * look,int hAlign,int vAlign,QWidget * parent,Qt::WindowFlags f)186 LinkLabel::LinkLabel(const QString &title, const QString &icon, LinkLook *look, int hAlign, int vAlign,
187 QWidget *parent, Qt::WindowFlags f)
188 : QFrame(parent, f), m_isSelected(false), m_isHovered(false), m_look(0)
189 {
190 initLabel(hAlign, vAlign);
191 setLink(title, icon, look);
192 }
193
initLabel(int hAlign,int vAlign)194 void LinkLabel::initLabel(int hAlign, int vAlign)
195 {
196 m_layout = new QBoxLayout(QBoxLayout::LeftToRight, this);
197 m_icon = new QLabel(this);
198 m_title = new QLabel(this);
199 m_spacer1 = new QSpacerItem(0, 0, QSizePolicy::Preferred/*Expanding*/, QSizePolicy::Preferred/*Expanding*/);
200 m_spacer2 = new QSpacerItem(0, 0, QSizePolicy::Preferred/*Expanding*/, QSizePolicy::Preferred/*Expanding*/);
201
202 m_hAlign = hAlign;
203 m_vAlign = vAlign;
204
205 m_title->setTextFormat(Qt::PlainText);
206
207 // DEGUB:
208 //m_icon->setPaletteBackgroundColor("lightblue");
209 //m_title->setPaletteBackgroundColor("lightyellow");
210 }
211
~LinkLabel()212 LinkLabel::~LinkLabel()
213 {
214 }
215
setLink(const QString & title,const QString & icon,LinkLook * look)216 void LinkLabel::setLink(const QString &title, const QString &icon, LinkLook *look)
217 {
218 if (look)
219 m_look = look; // Needed for icon size
220
221 m_title->setText(title);
222 m_title->setVisible(! title.isEmpty());
223
224 if (icon.isEmpty())
225 m_icon->clear();
226 else {
227 QPixmap pixmap = DesktopIcon(icon, m_look->iconSize(), m_look->iconSize());
228 if (!pixmap.isNull())
229 m_icon->setPixmap(pixmap);
230 }
231 m_icon->setVisible(! icon.isEmpty());
232
233 if (look)
234 setLook(look);
235 }
236
setLook(LinkLook * look)237 void LinkLabel::setLook(LinkLook *look) // FIXME: called externaly (so, without setLink()) it's buggy (icon not
238 {
239 m_look = look;
240
241 QFont font;
242 font.setBold(look->bold());
243 font.setUnderline(look->underlineOutside());
244 font.setItalic(look->italic());
245 m_title->setFont(font);
246 QPalette palette;
247 if (m_isSelected)
248 palette.setColor(m_title->foregroundRole(), QApplication::palette().color(QPalette::Text));
249 else
250 palette.setColor(m_title->foregroundRole(), look->effectiveColor());
251
252 m_title->setPalette(palette);
253
254
255 m_icon->setVisible(m_icon->pixmap() && ! m_icon->pixmap()->isNull());
256
257 setAlign(m_hAlign, m_vAlign);
258 }
259
setAlign(int hAlign,int vAlign)260 void LinkLabel::setAlign(int hAlign, int vAlign)
261 {
262 m_hAlign = hAlign;
263 m_vAlign = vAlign;
264
265 if (!m_look)
266 return;
267
268 // Define alignment flags :
269 Qt::Alignment hFlag, vFlag;
270 switch (hAlign) {
271 default:
272 case 0: hFlag = Qt::AlignLeft; break;
273 case 1: hFlag = Qt::AlignHCenter; break;
274 case 2: hFlag = Qt::AlignRight; break;
275 }
276 switch (vAlign) {
277 case 0: vFlag = Qt::AlignTop; break;
278 default:
279 case 1: vFlag = Qt::AlignVCenter; break;
280 case 2: vFlag = Qt::AlignBottom; break;
281 }
282
283 // Clear the widget :
284 m_layout->removeItem(m_spacer1);
285 m_layout->removeWidget(m_icon);
286 m_layout->removeWidget(m_title);
287 m_layout->removeItem(m_spacer2);
288
289 // Otherwise, minimumSize will be incoherent (last size ? )
290 m_layout->setSizeConstraint(QLayout::SetMinimumSize);
291
292 // And re-populate the widget with the appropriates things and order
293 bool addSpacers = (hAlign == 1);
294 m_layout->setDirection(QBoxLayout::LeftToRight);
295 //m_title->setSizePolicy( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Maximum/*Expanding*/, 0, 0, false) );
296 m_icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
297 m_spacer1->changeSize(QSizePolicy::Expanding, QSizePolicy::Preferred);
298 m_spacer2->changeSize(QSizePolicy::Expanding, QSizePolicy::Preferred);
299
300 m_icon->setAlignment(hFlag | vFlag);
301 m_title->setAlignment(hFlag | vFlag);
302 if (hAlign)
303 m_title->setWordWrap(true);
304
305 if ((addSpacers && (vAlign != 0)) ||
306 (m_title->text().isEmpty() && hAlign == 2))
307 m_layout->addItem(m_spacer1);
308 if (hAlign == 2) { // If align at right, icon is at right
309 m_layout->addWidget(m_title);
310 m_layout->addWidget(m_icon);
311 } else {
312 m_layout->addWidget(m_icon);
313 m_layout->addWidget(m_title);
314 }
315 if ((addSpacers && (vAlign != 2)) ||
316 (m_title->text().isEmpty() && hAlign == 0))
317 m_layout->addItem(m_spacer2);
318 }
319
enterEvent(QEvent *)320 void LinkLabel::enterEvent(QEvent*)
321 {
322 m_isHovered = true;
323
324 if (!m_isSelected) {
325 QPalette palette;
326 palette.setColor(m_title->foregroundRole(), m_look->effectiveHoverColor());
327 m_title->setPalette(palette);
328 }
329
330 QFont font = m_title->font();
331 font.setUnderline(m_look->underlineInside());
332 m_title->setFont(font);
333 }
334
leaveEvent(QEvent *)335 void LinkLabel::leaveEvent(QEvent*)
336 {
337 m_isHovered = false;
338
339 if (!m_isSelected) {
340 QPalette palette;
341 palette.setColor(m_title->foregroundRole(), m_look->effectiveColor());
342 m_title->setPalette(palette);
343 }
344
345 QFont font = m_title->font();
346 font.setUnderline(m_look->underlineOutside());
347 m_title->setFont(font);
348 }
349
setSelected(bool selected)350 void LinkLabel::setSelected(bool selected)
351 {
352 m_isSelected = selected;
353 QPalette palette;
354
355 if (selected)
356 palette.setColor(m_title->foregroundRole(), QApplication::palette().color(QPalette::HighlightedText));
357 else if (m_isHovered)
358 palette.setColor(m_title->foregroundRole(), m_look->effectiveHoverColor());
359 else
360 palette.setColor(m_title->foregroundRole(), m_look->effectiveColor());
361
362 m_title->setPalette(palette);
363 }
364
setPaletteBackgroundColor(const QColor & color)365 void LinkLabel::setPaletteBackgroundColor(const QColor &color)
366 {
367 QPalette framePalette;
368 framePalette.setColor(QFrame::foregroundRole(), color);
369 QFrame::setPalette(framePalette);
370
371 QPalette titlePalette;
372 titlePalette.setColor(m_title->foregroundRole(), color);
373 m_title->setPalette(titlePalette);
374 }
375
heightForWidth(int w) const376 int LinkLabel::heightForWidth(int w) const
377 {
378 int iconS = (m_icon->isVisible()) ? m_look->iconSize() : 0; // Icon size
379 int iconW = iconS; // Icon width to remove to w
380 int titleH = (m_title->isVisible()) ? m_title->heightForWidth(w - iconW) : 0; // Title height
381
382 return (titleH >= iconS) ? titleH : iconS; // No margin for the moment !
383 }
384
385 /** class LinkDisplay
386 */
387
LinkDisplay()388 LinkDisplay::LinkDisplay()
389 : m_title(), m_icon(), m_preview(), m_look(0), m_font(), m_minWidth(0), m_width(0), m_height(0)
390 {
391 }
392
setLink(const QString & title,const QString & icon,LinkLook * look,const QFont & font)393 void LinkDisplay::setLink(const QString &title, const QString &icon, LinkLook *look, const QFont &font)
394 {
395 setLink(title, icon, m_preview, look, font);
396 }
397
setLink(const QString & title,const QString & icon,const QPixmap & preview,LinkLook * look,const QFont & font)398 void LinkDisplay::setLink(const QString &title, const QString &icon, const QPixmap &preview, LinkLook *look, const QFont &font)
399 {
400 m_title = title;
401 m_icon = icon;
402 m_preview = preview;
403 m_look = look;
404 m_font = font;
405
406 // "Constants":
407 int BUTTON_MARGIN = qApp->style()->pixelMetric(QStyle::PM_ButtonMargin);
408 int LINK_MARGIN = BUTTON_MARGIN + 2;
409
410 // Recompute m_minWidth:
411 QRect textRect = QFontMetrics(labelFont(font, false)).boundingRect(0, 0, /*width=*/1, 500000, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, m_title);
412 int iconPreviewWidth = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.width() : 0));
413 m_minWidth = BUTTON_MARGIN - 1 + iconPreviewWidth + LINK_MARGIN + textRect.width();
414 // Recompute m_maxWidth:
415 textRect = QFontMetrics(labelFont(font, false)).boundingRect(0, 0, /*width=*/50000000, 500000, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, m_title);
416 m_maxWidth = BUTTON_MARGIN - 1 + iconPreviewWidth + LINK_MARGIN + textRect.width();
417 // Adjust m_width:
418 if (m_width < m_minWidth)
419 setWidth(m_minWidth);
420 // Recompute m_height:
421 m_height = heightForWidth(m_width);
422 }
423
setWidth(qreal width)424 void LinkDisplay::setWidth(qreal width)
425 {
426 if (width < m_minWidth)
427 width = m_minWidth;
428
429 if (width != m_width) {
430 m_width = width;
431 m_height = heightForWidth(m_width);
432 }
433 }
434
435 /** Paint on @p painter
436 * in (@p x, @p y, @p width, @p height)
437 * using @p palette for the button drawing (if @p isHovered)
438 * and the LinkLook color() for the text,
439 * 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.
440 * It will draw the button if @p isIconButtonHovered.
441 */
paint(QPainter * painter,qreal x,qreal y,qreal width,qreal height,const QPalette & palette,bool isDefaultColor,bool isSelected,bool isHovered,bool isIconButtonHovered) const442 void LinkDisplay::paint(QPainter *painter, qreal x, qreal y, qreal width, qreal height, const QPalette &palette,
443 bool isDefaultColor, bool isSelected, bool isHovered, bool isIconButtonHovered) const
444 {
445 qreal BUTTON_MARGIN = qApp->style()->pixelMetric(QStyle::PM_ButtonMargin);
446 qreal LINK_MARGIN = BUTTON_MARGIN + 2;
447
448 QPixmap pixmap;
449 // Load the preview...:
450 if (!isHovered && m_look->previewEnabled() && !m_preview.isNull())
451 pixmap = m_preview;
452 // ... Or the icon (if no preview or if the "Open" icon should be shown):
453 else {
454 qreal iconSize = m_look->iconSize();
455 QString iconName = (isHovered ? Global::openNoteIcon() : m_icon);
456 KIconLoader::States iconState = (isIconButtonHovered ? KIconLoader::ActiveState : KIconLoader::DefaultState);
457 pixmap = KIconLoader::global()->loadIcon(
458 iconName, KIconLoader::Desktop, iconSize, iconState, QStringList(),
459 0L, /*canReturnNull=*/false
460 );
461 }
462 qreal iconPreviewWidth = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.width() : 0));
463 qreal pixmapX = (iconPreviewWidth - pixmap.width()) / 2;
464 qreal pixmapY = (height - pixmap.height()) / 2;
465 // Draw the button (if any) and the icon:
466 if (isHovered) {
467 QStyleOption opt;
468 opt.rect = QRect(-1, -1, iconPreviewWidth + 2 * BUTTON_MARGIN, height + 2);
469 opt.state = isIconButtonHovered ? (QStyle::State_MouseOver | QStyle::State_Enabled) : QStyle::State_Enabled;
470 qApp->style()->drawPrimitive(QStyle::PE_PanelButtonCommand, &opt, painter);
471 }
472 painter->drawPixmap(x + BUTTON_MARGIN - 1 + pixmapX, y + pixmapY, pixmap);
473
474 // Figure out the text color:
475 if (isSelected) {
476 painter->setPen(qApp->palette().color(QPalette::HighlightedText));
477 } else if (isIconButtonHovered)
478 painter->setPen(m_look->effectiveHoverColor());
479 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:
480 painter->setPen(palette.color(QPalette::Active, QPalette::WindowText));
481 else
482 painter->setPen(m_look->effectiveColor());
483 // Draw the text:
484 painter->setFont(labelFont(m_font, isIconButtonHovered));
485 painter->drawText(x + BUTTON_MARGIN - 1 + iconPreviewWidth + LINK_MARGIN, y, width - BUTTON_MARGIN + 1 - iconPreviewWidth - LINK_MARGIN, height,
486 Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, m_title);
487 }
488
feedbackPixmap(qreal width,qreal height,const QPalette & palette,bool isDefaultColor)489 QPixmap LinkDisplay::feedbackPixmap(qreal width, qreal height, const QPalette &palette, bool isDefaultColor)
490 {
491 qreal theWidth = qMin(width, maxWidth());
492 qreal theHeight = qMin(height, heightForWidth(theWidth));
493 QPixmap pixmap(theWidth, theHeight);
494 pixmap.fill(palette.color(QPalette::Active, QPalette::Background));
495 QPainter painter(&pixmap);
496 paint(&painter, 0, 0, theWidth, theHeight, palette, isDefaultColor,
497 /*isSelected=*/false, /*isHovered=*/false, /*isIconButtonHovered=*/false);
498 painter.end();
499 return pixmap;
500 }
501
iconButtonAt(const QPointF & pos) const502 bool LinkDisplay::iconButtonAt(const QPointF &pos) const
503 {
504 qreal BUTTON_MARGIN = qApp->style()->pixelMetric(QStyle::PM_ButtonMargin);
505 // int LINK_MARGIN = BUTTON_MARGIN + 2;
506 qreal iconPreviewWidth = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.width() : 0));
507
508 return pos.x() <= BUTTON_MARGIN - 1 + iconPreviewWidth + BUTTON_MARGIN;
509 }
510
iconButtonRect() const511 QRectF LinkDisplay::iconButtonRect() const
512 {
513 qreal BUTTON_MARGIN = qApp->style()->pixelMetric(QStyle::PM_ButtonMargin);
514 // int LINK_MARGIN = BUTTON_MARGIN + 2;
515 qreal iconPreviewWidth = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.width() : 0));
516
517 return QRectF(0, 0, BUTTON_MARGIN - 1 + iconPreviewWidth + BUTTON_MARGIN, m_height);
518 }
519
labelFont(QFont font,bool isIconButtonHovered) const520 QFont LinkDisplay::labelFont(QFont font, bool isIconButtonHovered) const
521 {
522 if (m_look->italic())
523 font.setItalic(true);
524 if (m_look->bold())
525 font.setBold(true);
526 if (isIconButtonHovered) {
527 if (m_look->underlineInside())
528 font.setUnderline(true);
529 } else {
530 if (m_look->underlineOutside())
531 font.setUnderline(true);
532 }
533 return font;
534 }
535
heightForWidth(qreal width) const536 qreal LinkDisplay::heightForWidth(qreal width) const
537 {
538 qreal BUTTON_MARGIN = qApp->style()->pixelMetric(QStyle::PM_ButtonMargin);
539 qreal LINK_MARGIN = BUTTON_MARGIN + 2;
540 qreal iconPreviewWidth = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.width() : 0));
541 qreal iconPreviewHeight = qMax(m_look->iconSize(), (m_look->previewEnabled() ? m_preview.height() : 0));
542
543 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);
544 return qMax(textRect.height(), iconPreviewHeight + 2*BUTTON_MARGIN - 2);
545 }
546
toHtml(const QString &) const547 QString LinkDisplay::toHtml(const QString &/*imageName*/) const
548 {
549 // TODO
550 return "";
551 }
552
toHtml(HTMLExporter * exporter,const QUrl & url,const QString & title)553 QString LinkDisplay::toHtml(HTMLExporter *exporter, const QUrl &url, const QString &title)
554 {
555 QString linkIcon;
556 if (m_look->previewEnabled() && !m_preview.isNull()) {
557 QString fileName = Tools::fileNameForNewFile("preview_" + url.fileName() + ".png", exporter->iconsFolderPath);
558 QString fullPath = exporter->iconsFolderPath + fileName;
559 m_preview.save(fullPath, "PNG");
560 linkIcon = QString("<img src=\"%1\" width=\"%2\" height=\"%3\" alt=\"\">")
561 .arg(exporter->iconsFolderName + fileName, QString::number(m_preview.width()), QString::number(m_preview.height()));
562 } else {
563 linkIcon = exporter->iconsFolderName + exporter->copyIcon(m_icon, m_look->iconSize());
564 linkIcon = QString("<img src=\"%1\" width=\"%2\" height=\"%3\" alt=\"\">")
565 .arg(linkIcon, QString::number(m_look->iconSize()), QString::number(m_look->iconSize()));
566 }
567
568 QString linkTitle = Tools::textToHTMLWithoutP(title.isEmpty() ? m_title : title);
569
570 return QString("<a href=\"%1\">%2 %3</a>").arg(url.toDisplayString(), linkIcon, linkTitle);
571 }
572
573 /** LinkLookEditWidget **/
574
LinkLookEditWidget(KCModule * module,const QString exTitle,const QString exIcon,QWidget * parent,Qt::WindowFlags fl)575 LinkLookEditWidget::LinkLookEditWidget(KCModule *module, const QString exTitle, const QString exIcon,
576 QWidget *parent, Qt::WindowFlags fl)
577 : QWidget(parent, fl)
578 {
579 QLabel *label;
580 QVBoxLayout *layout = new QVBoxLayout(this);
581
582 m_italic = new QCheckBox(i18n("I&talic"), this);
583 layout->addWidget(m_italic);
584
585 m_bold = new QCheckBox(i18n("&Bold"), this);
586 layout->addWidget(m_bold);
587
588 QGridLayout *gl = new QGridLayout;
589 layout->addLayout(gl);
590 gl->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding), 1, /*2*/3);
591
592 m_underlining = new KComboBox(this);
593 m_underlining->addItem(i18n("Always"));
594 m_underlining->addItem(i18n("Never"));
595 m_underlining->addItem(i18n("On mouse hovering"));
596 m_underlining->addItem(i18n("When mouse is outside"));
597 label = new QLabel(this);
598 label->setText(i18n("&Underline:"));
599 label->setBuddy(m_underlining);
600 gl->addWidget(label, 0, 0);
601 gl->addWidget(m_underlining, 0, 1);
602
603 m_color = new KColorCombo2(QRgb(), this);
604 label = new QLabel(this);
605 label->setText(i18n("Colo&r:"));
606 label->setBuddy(m_color);
607 gl->addWidget(label, 1, 0);
608 gl->addWidget(m_color, 1, 1);
609
610 m_hoverColor = new KColorCombo2(QRgb(), this);
611 label = new QLabel(this);
612 label->setText(i18n("&Mouse hover color:"));
613 label->setBuddy(m_hoverColor);
614 gl->addWidget(label, 2, 0);
615 gl->addWidget(m_hoverColor, 2, 1);
616
617 QHBoxLayout *icoLay = new QHBoxLayout(0);
618 m_iconSize = new IconSizeCombo(this);
619 icoLay->addWidget(m_iconSize);
620 label = new QLabel(this);
621 label->setText(i18n("&Icon size:"));
622 label->setBuddy(m_iconSize);
623 gl->addWidget(label, 3, 0);
624 gl->addItem(icoLay, 3, 1);
625
626 m_preview = new KComboBox(this);
627 m_preview->addItem(i18n("None"));
628 m_preview->addItem(i18n("Icon size"));
629 m_preview->addItem(i18n("Twice the icon size"));
630 m_preview->addItem(i18n("Three times the icon size"));
631 m_label = new QLabel(this);
632 m_label->setText(i18n("&Preview:"));
633 m_label->setBuddy(m_preview);
634 m_hLabel = new HelpLabel(
635 i18n("You disabled preview but still see images?"),
636 i18n("<p>This is normal because there are several type of notes.<br>"
637 "This setting only applies to file and local link notes.<br>"
638 "The images you see are image notes, not file notes.<br>"
639 "File notes are generic documents, whereas image notes are pictures you can draw in.</p>"
640 "<p>When dropping files to baskets, %1 detects their type and shows you the content of the files.<br>"
641 "For instance, when dropping image or text files, image and text notes are created for them.<br>"
642 "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>"
643 "<p>If you do not want the application to create notes depending on the content of the files you drop, "
644 "go to the \"General\" page and uncheck \"Image or animation\" in the \"View Content of Added Files for the Following Types\" group.</p>",
645 // TODO: Note: you can resize down maximum size of images...
646 QGuiApplication::applicationDisplayName(), QGuiApplication::applicationDisplayName()),
647 this);
648 gl->addWidget(m_label, 4, 0);
649 gl->addWidget(m_preview, 4, 1);
650 gl->addWidget(m_hLabel, 5, 1, 1, 2);
651
652 QGroupBox *gb = new QGroupBox(i18n("Example"), this);
653 QHBoxLayout* gbLayout = new QHBoxLayout;
654 gb->setLayout(gbLayout);
655
656 m_exLook = new LinkLook;
657 m_example = new LinkLabel(exTitle, exIcon, m_exLook, 1, 1);
658 gbLayout->addWidget(m_example);
659 m_example->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
660 m_example->setCursor(QCursor(Qt::PointingHandCursor));
661 layout->addWidget(gb);
662 m_exTitle = exTitle;
663 m_exIcon = exIcon;
664
665 connect(m_italic, SIGNAL(stateChanged(int)), this, SLOT(slotChangeLook()));
666 connect(m_bold, SIGNAL(stateChanged(int)), this, SLOT(slotChangeLook()));
667 connect(m_underlining, SIGNAL(activated(int)), this, SLOT(slotChangeLook()));
668 connect(m_color, SIGNAL(activated(int)), this, SLOT(slotChangeLook()));
669 connect(m_hoverColor, SIGNAL(activated(int)), this, SLOT(slotChangeLook()));
670 connect(m_iconSize, SIGNAL(activated(int)), this, SLOT(slotChangeLook()));
671 connect(m_preview, SIGNAL(activated(int)), this, SLOT(slotChangeLook()));
672
673 connect(m_italic, SIGNAL(stateChanged(int)), module, SLOT(changed()));
674 connect(m_bold, SIGNAL(stateChanged(int)), module, SLOT(changed()));
675 connect(m_underlining, SIGNAL(activated(int)), module, SLOT(changed()));
676 connect(m_color, SIGNAL(activated(int)), module, SLOT(changed()));
677 connect(m_hoverColor, SIGNAL(activated(int)), module, SLOT(changed()));
678 connect(m_iconSize, SIGNAL(activated(int)), module, SLOT(changed()));
679 connect(m_preview, SIGNAL(activated(int)), module, SLOT(changed()));
680 }
681
set(LinkLook * look)682 void LinkLookEditWidget::set(LinkLook *look)
683 {
684 m_look = look;
685
686 m_italic->setChecked(look->italic());
687 m_bold->setChecked(look->bold());
688 m_underlining->setCurrentIndex(look->underlining());
689 m_preview->setCurrentIndex(look->preview());
690 m_color->setDefaultColor(m_look->defaultColor());
691 m_color->setColor(m_look->color());
692 m_hoverColor->setDefaultColor(m_look->defaultHoverColor());
693 m_hoverColor->setColor(m_look->hoverColor());
694 m_iconSize->setSize(look->iconSize());
695 m_exLook = new LinkLook(*look);
696 m_example->setLook(m_exLook);
697
698 if (!look->canPreview()) {
699 m_label->setEnabled(false);
700 m_hLabel->setEnabled(false);
701 m_preview->setEnabled(false);
702 }
703 slotChangeLook();
704 }
705
slotChangeLook()706 void LinkLookEditWidget::slotChangeLook()
707 {
708 saveToLook(m_exLook);
709 m_example->setLink(m_exTitle, m_exIcon, m_exLook); // and can't reload it at another size
710 }
711
~LinkLookEditWidget()712 LinkLookEditWidget::~LinkLookEditWidget()
713 {
714 }
715
saveChanges()716 void LinkLookEditWidget::saveChanges()
717 {
718 saveToLook(m_look);
719 }
720
saveToLook(LinkLook * look)721 void LinkLookEditWidget::saveToLook(LinkLook *look)
722 {
723 look->setLook(m_italic->isChecked(), m_bold->isChecked(), m_underlining->currentIndex(),
724 m_color->color(), m_hoverColor->color(),
725 m_iconSize->iconSize(), (look->canPreview() ? m_preview->currentIndex() : LinkLook::None));
726 }
727
728