File indexing completed on 2024-05-12 04:37:48

0001 /*
0002     SPDX-FileCopyrightText: 2017 Friedrich W. H. Kossebau <kossebau@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "templatepreviewicon.h"
0008 
0009 #include <debug.h>
0010 
0011 #include <KTar>
0012 #include <KZip>
0013 
0014 #include <QSharedData>
0015 #include <QIcon>
0016 #include <QPixmap>
0017 #include <QFileInfo>
0018 #include <QStandardPaths>
0019 
0020 using namespace KDevelop;
0021 
0022 class KDevelop::TemplatePreviewIconData
0023     : public QSharedData
0024 {
0025 public:
0026     QString iconName;
0027     QString archivePath;
0028     QString dataDir;
0029 };
0030 
0031 TemplatePreviewIcon::TemplatePreviewIcon(const QString& iconName, const QString& archivePath, const QString& dataDir)
0032     : d(new TemplatePreviewIconData)
0033 {
0034     d->iconName = iconName;
0035     d->archivePath = archivePath;
0036     d->dataDir = dataDir;
0037 }
0038 
0039 TemplatePreviewIcon::TemplatePreviewIcon()
0040     : d(new TemplatePreviewIconData)
0041 {
0042 }
0043 
0044 TemplatePreviewIcon::TemplatePreviewIcon(const TemplatePreviewIcon& other)
0045     : d(other.d)
0046 {
0047 }
0048 
0049 TemplatePreviewIcon::~TemplatePreviewIcon() = default;
0050 
0051 TemplatePreviewIcon& TemplatePreviewIcon::operator=(const TemplatePreviewIcon& other)
0052 {
0053     if (this != &other) {
0054         d = other.d;
0055     }
0056 
0057     return *this;
0058 }
0059 
0060 QPixmap TemplatePreviewIcon::pixmap() const
0061 {
0062     if (!d->iconName.isEmpty()) {
0063         // read icon from archive
0064         QScopedPointer<KArchive> templateArchive;
0065         if (QFileInfo(d->archivePath).completeSuffix() == QLatin1String("zip")) {
0066             templateArchive.reset(new KZip(d->archivePath));
0067         } else {
0068             templateArchive.reset(new KTar(d->archivePath));
0069         }
0070 
0071         if (templateArchive->open(QIODevice::ReadOnly)) {
0072             const KArchiveFile* iconFile = templateArchive->directory()->file(d->iconName);
0073             if (iconFile) {
0074                 QPixmap pixmap;
0075                 const bool loadSuccess = pixmap.loadFromData(iconFile->data());
0076                 if (loadSuccess) {
0077                     return pixmap;
0078                 }
0079                 qCWarning(LANGUAGE) << "Could not load preview icon" << d->iconName << "from" << d->archivePath;
0080             }
0081         }
0082 
0083         // support legacy templates with image files installed separately in the filesystem
0084         const QString iconFilePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
0085                                                             d->dataDir + d->iconName);
0086         if (!iconFilePath.isEmpty()) {
0087             QPixmap pixmap(iconFilePath);
0088             if (!pixmap.isNull()) {
0089                 return pixmap;
0090             }
0091             qCWarning(LANGUAGE) << "Could not load preview icon" << iconFilePath << "as wanted for" << d->archivePath;
0092         }
0093     }
0094 
0095     // try theme icon or default to a kdevelop icon
0096     // QIcon::hasThemeIcon for empty string can yield true with some engines, not wanted here
0097     const bool isThemeIcon = (!d->iconName.isEmpty() && QIcon::hasThemeIcon(d->iconName));
0098     const QString iconName = isThemeIcon ? d->iconName : QStringLiteral("kdevelop");
0099 
0100     const QIcon icon = QIcon::fromTheme(iconName);
0101     return icon.pixmap(128, 128);
0102 }