File indexing completed on 2024-05-12 15:59:56

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 
0015 #include <KisResourceModel.h>
0016 #include "KoCheckerBoardPainter.h"
0017 #include <QPainter>
0018 
0019 #include <klocalizedstring.h>
0020 #include "kis_assert.h"
0021 
0022 KisIconToolTip::KisIconToolTip()
0023 {
0024 }
0025 
0026 KisIconToolTip::~KisIconToolTip()
0027 {
0028 }
0029 
0030 void KisIconToolTip::setFixedToolTipThumbnailSize(const QSize &size)
0031 {
0032     m_fixedToolTipThumbnailSize = size;
0033 }
0034 
0035 void KisIconToolTip::setToolTipShouldRenderCheckers(bool value)
0036 {
0037     if (value) {
0038         m_checkersPainter.reset(new KoCheckerBoardPainter(4));
0039     } else {
0040         m_checkersPainter.reset();
0041     }
0042 }
0043 
0044 QTextDocument *KisIconToolTip::createDocument(const QModelIndex &index)
0045 {
0046     QTextDocument *doc = new QTextDocument(this);
0047 
0048     QImage thumb = index.data(Qt::DecorationRole).value<QImage>();
0049     if (thumb.isNull()) {
0050         thumb = index.data(Qt::UserRole + KisAbstractResourceModel::Thumbnail).value<QImage>();
0051     }
0052 
0053     if (!m_fixedToolTipThumbnailSize.isEmpty() && !thumb.isNull()) {
0054         int pixelSize = 48; //  // let's say, 48x48?
0055         if (!thumb.isNull()) {
0056             if (thumb.size().width() < pixelSize || thumb.size().height() < pixelSize) {
0057                 // this allows the pixel patterns to be displayed correctly,
0058                 // while the presets (which have 200x200 thumbnails) will still be pretty
0059                 // Fast Transformation == Nearest Neighbour
0060                 thumb = thumb.scaled(m_fixedToolTipThumbnailSize*devicePixelRatioF(), Qt::IgnoreAspectRatio, Qt::FastTransformation);
0061             } else {
0062                 thumb = thumb.scaled(m_fixedToolTipThumbnailSize*devicePixelRatioF(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
0063             }
0064         }
0065     }
0066 
0067     if (m_checkersPainter) {
0068         QImage image(thumb.size(), QImage::Format_ARGB32);
0069 
0070         {
0071             QPainter gc(&image);
0072             m_checkersPainter->paint(gc, thumb.rect());
0073             gc.drawImage(QPoint(), thumb);
0074         }
0075 
0076         thumb = image;
0077     }
0078 
0079     thumb.setDevicePixelRatio(devicePixelRatioF());
0080     doc->addResource(QTextDocument::ImageResource, QUrl("data:thumbnail"), thumb);
0081 
0082     QString name = index.data(Qt::DisplayRole).toString();
0083     QString presetDisplayName = index.data(Qt::UserRole + KisAbstractResourceModel::Name).toString().replace("_", " ");
0084     //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.
0085     if (!presetDisplayName.isEmpty()) {
0086         name = presetDisplayName;
0087     }
0088 
0089     QString translatedName = index.data(Qt::UserRole + KisAbstractResourceModel::Tooltip).toString().replace("_", " ");
0090 
0091     QString tagsRow;
0092     QString tagsData = index.data(Qt::UserRole + KisAbstractResourceModel::Tags).toStringList().join(", ");
0093     if (!tagsData.isEmpty()) {
0094         const QString list = QString("<ul style=\"list-style-type: none; margin: 0px;\">%1</ul> ").arg(tagsData);
0095         tagsRow = QString("<tr><td>%1:</td><td style=\"text-align: right;\">%2</td></tr>").arg(i18n("Tags"), list);
0096     }
0097 
0098     QString location = index.data(Qt::UserRole + KisAbstractResourceModel::Location).toString();
0099 
0100     if (location.isEmpty()) {
0101         location = i18nc("a placeholder name for the default storage of resources", "resource folder");
0102     }
0103 
0104     const QString locationRow = QString("<tr><td>%1:</td><td style=\"text-align: right;\">%2</td></tr>").arg(i18n("Location"), location);
0105 
0106     const QString footerTable = QString("<p><table>%1%2</table></p>").arg(tagsRow).arg(locationRow);
0107 
0108     const QString image = QString("<center><img src=\"data:thumbnail\"></center>");
0109     QString body = QString("<h3 align=\"center\">%1</h3>%2%3").arg(name, image, footerTable);
0110     if (translatedName != name) {
0111         body = QString("<h3 align=\"center\">%1</h3><h4 align=\"center\">%2</h4>%3%4").arg(name, translatedName, image, footerTable);
0112     }
0113     const QString html = QString("<html><body>%1</body></html>").arg(body);
0114 
0115     doc->setHtml(html);
0116 
0117     const int margin = 16;
0118     doc->setTextWidth(qMin(doc->size().width() + 2 * margin, qreal(500.0)));
0119     doc->setDocumentMargin(margin);
0120     doc->setUseDesignMetrics(true);
0121 
0122     return doc;
0123 }