File indexing completed on 2024-05-19 04:27:44

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 1999 Carsten Pfeiffer (pfeiffer@kde.org)
0003  * SPDX-FileCopyrightText: 2002 Igor Jansen (rm@kde.org)
0004  * SPDX-FileCopyrightText: 2018 Boudewijn Rempt <boud@valdyas.org>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "KisIconToolTip.h"
0010 
0011 #include <QTextDocument>
0012 #include <QUrl>
0013 #include <QModelIndex>
0014 #include <QPainter>
0015 
0016 #include <KisResourceModel.h>
0017 #include <KisResourceThumbnailCache.h>
0018 #include <klocalizedstring.h>
0019 
0020 #include "KoCheckerBoardPainter.h"
0021 #include "kis_assert.h"
0022 
0023 KisIconToolTip::KisIconToolTip()
0024 {
0025 }
0026 
0027 KisIconToolTip::~KisIconToolTip()
0028 {
0029 }
0030 
0031 void KisIconToolTip::setFixedToolTipThumbnailSize(const QSize &size)
0032 {
0033     m_fixedToolTipThumbnailSize = size;
0034 }
0035 
0036 void KisIconToolTip::setToolTipShouldRenderCheckers(bool value)
0037 {
0038     if (value) {
0039         m_checkersPainter.reset(new KoCheckerBoardPainter(4));
0040     } else {
0041         m_checkersPainter.reset();
0042     }
0043 }
0044 
0045 QTextDocument *KisIconToolTip::createDocument(const QModelIndex &index)
0046 {
0047     QTextDocument *doc = new QTextDocument(this);
0048 
0049     QImage thumb = index.data(Qt::DecorationRole).value<QImage>();
0050     if (thumb.isNull()) {
0051         thumb = index.data(Qt::UserRole + KisAbstractResourceModel::Thumbnail).value<QImage>();
0052     }
0053 
0054     if (!m_fixedToolTipThumbnailSize.isEmpty() && !thumb.isNull()) {
0055         int pixelSize = 48; //  // let's say, 48x48?
0056         if (!thumb.isNull()) {
0057             if (thumb.size().width() < pixelSize || thumb.size().height() < pixelSize) {
0058                 // this allows the pixel patterns to be displayed correctly,
0059                 // while the presets (which have 200x200 thumbnails) will still be pretty
0060                 // Fast Transformation == Nearest Neighbour
0061                 thumb = KisResourceThumbnailCache::instance()->getImage(index,
0062                                                                         m_fixedToolTipThumbnailSize
0063                                                                             * devicePixelRatioF(),
0064                                                                         Qt::IgnoreAspectRatio,
0065                                                                         Qt::FastTransformation);
0066             } else {
0067                 thumb = KisResourceThumbnailCache::instance()->getImage(index,
0068                                                                         m_fixedToolTipThumbnailSize
0069                                                                             * devicePixelRatioF(),
0070                                                                         Qt::IgnoreAspectRatio,
0071                                                                         Qt::SmoothTransformation);
0072             }
0073         }
0074     }
0075 
0076     if (m_checkersPainter) {
0077         QImage image(thumb.size(), QImage::Format_ARGB32);
0078 
0079         {
0080             QPainter gc(&image);
0081             m_checkersPainter->paint(gc, thumb.rect());
0082             gc.drawImage(QPoint(), thumb);
0083         }
0084 
0085         thumb = image;
0086     }
0087 
0088     thumb.setDevicePixelRatio(devicePixelRatioF());
0089     doc->addResource(QTextDocument::ImageResource, QUrl("data:thumbnail"), thumb);
0090 
0091     QString name = index.data(Qt::DisplayRole).toString();
0092     QString presetDisplayName = index.data(Qt::UserRole + KisAbstractResourceModel::Name).toString().replace("_", " ");
0093     //This is to ensure that the other uses of this class don't get an empty string, while resource management should get a nice string.
0094     if (!presetDisplayName.isEmpty()) {
0095         name = presetDisplayName;
0096     }
0097 
0098     QString translatedName = index.data(Qt::UserRole + KisAbstractResourceModel::Tooltip).toString().replace("_", " ");
0099 
0100     QString tagsRow;
0101     QString tagsData = index.data(Qt::UserRole + KisAbstractResourceModel::Tags).toStringList().join(", ");
0102     if (!tagsData.isEmpty()) {
0103         const QString list = QString("<ul style=\"list-style-type: none; margin: 0px;\">%1</ul> ").arg(tagsData);
0104         tagsRow = QString("<tr><td>%1:</td><td style=\"text-align: right;\">%2</td></tr>").arg(i18n("Tags"), list);
0105     }
0106 
0107     QString location = index.data(Qt::UserRole + KisAbstractResourceModel::Location).toString();
0108 
0109     if (location.isEmpty()) {
0110         location = i18nc("a placeholder name for the default storage of resources", "resource folder");
0111     }
0112 
0113     const QString locationRow = QString("<tr><td>%1:</td><td style=\"text-align: right;\">%2</td></tr>").arg(i18n("Location"), location);
0114 
0115     const QString footerTable = QString("<p><table>%1%2</table></p>").arg(tagsRow).arg(locationRow);
0116 
0117     const QString image = QString("<center><img src=\"data:thumbnail\"></center>");
0118     QString body = QString("<h3 align=\"center\">%1</h3>%2%3").arg(name, image, footerTable);
0119     if (translatedName != name) {
0120         body = QString("<h3 align=\"center\">%1</h3><h4 align=\"center\">%2</h4>%3%4").arg(name, translatedName, image, footerTable);
0121     }
0122     const QString html = QString("<html><body>%1</body></html>").arg(body);
0123 
0124     doc->setHtml(html);
0125 
0126     const int margin = 16;
0127     doc->setTextWidth(qMin(doc->size().width() + 2 * margin, qreal(500.0)));
0128     doc->setDocumentMargin(margin);
0129     doc->setUseDesignMetrics(true);
0130 
0131     return doc;
0132 }