File indexing completed on 2024-11-10 05:02:45
0001 /* 0002 SPDX-FileCopyrightText: 2022 Fushan Wen <qydwhotmail@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "packageimageprovider.h" 0008 0009 #include <QImageReader> 0010 #include <QPalette> 0011 #include <QUrlQuery> 0012 0013 #include <KPackage/PackageLoader> 0014 0015 #include <KSvg/Svg> 0016 0017 #include "finder/packagefinder.h" 0018 0019 class AsyncPackageImageResponseRunnable : public QObject, public QRunnable 0020 { 0021 Q_OBJECT 0022 0023 public: 0024 explicit AsyncPackageImageResponseRunnable(const QString &path, const QSize &requestedSize); 0025 0026 /** 0027 * Read the image and resize it if the requested size is valid. 0028 */ 0029 void run() override; 0030 0031 Q_SIGNALS: 0032 void done(const QImage &image); 0033 0034 private: 0035 QString m_path; 0036 QSize m_requestedSize; 0037 }; 0038 0039 class AsyncPackageImageResponse : public QQuickImageResponse 0040 { 0041 Q_OBJECT 0042 0043 public: 0044 explicit AsyncPackageImageResponse(const QString &path, const QSize &requestedSize, QThreadPool *pool); 0045 0046 QQuickTextureFactory *textureFactory() const override; 0047 0048 protected Q_SLOTS: 0049 void slotHandleDone(const QImage &image); 0050 0051 protected: 0052 QImage m_image; 0053 }; 0054 0055 AsyncPackageImageResponseRunnable::AsyncPackageImageResponseRunnable(const QString &path, const QSize &requestedSize) 0056 : m_path(path) 0057 , m_requestedSize(requestedSize) 0058 { 0059 } 0060 0061 void AsyncPackageImageResponseRunnable::run() 0062 { 0063 const QUrlQuery urlQuery(QUrl(QStringLiteral("image://package/%1").arg(m_path))); 0064 const QString dir = urlQuery.queryItemValue(QStringLiteral("dir")); 0065 0066 if (dir.isEmpty()) { 0067 Q_EMIT done(QImage()); 0068 return; 0069 } 0070 0071 KPackage::Package package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Wallpaper/Images")); 0072 package.setPath(dir); 0073 0074 if (!package.isValid()) { 0075 Q_EMIT done(QImage()); 0076 return; 0077 } 0078 0079 PackageFinder::findPreferredImageInPackage(package, m_requestedSize); 0080 0081 QString path = package.filePath("preferred"); 0082 // 192 is from kcm_colors 0083 if (urlQuery.queryItemValue(QStringLiteral("darkMode")).toInt() == 1) { 0084 QString darkPath = package.filePath("preferredDark"); 0085 0086 if (!darkPath.isEmpty()) { 0087 path = darkPath; 0088 } 0089 } 0090 0091 QImageReader imageReader(path); 0092 QImage image; 0093 if (imageReader.format() == "svg" || imageReader.format() == "svgz") { 0094 KSvg::Svg svgRender; 0095 svgRender.setImagePath(path); 0096 image = svgRender.image(m_requestedSize.isValid() ? svgRender.size().toSize().scaled(m_requestedSize, Qt::KeepAspectRatioByExpanding) 0097 : svgRender.size().toSize()); 0098 } else if (imageReader.read(&image)) { 0099 if (m_requestedSize.isValid()) { 0100 image = image.scaled(m_requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); 0101 } 0102 } 0103 0104 Q_EMIT done(image); 0105 } 0106 0107 AsyncPackageImageResponse::AsyncPackageImageResponse(const QString &path, const QSize &requestedSize, QThreadPool *pool) 0108 { 0109 auto runnable = new AsyncPackageImageResponseRunnable(path, requestedSize); 0110 connect(runnable, &AsyncPackageImageResponseRunnable::done, this, &AsyncPackageImageResponse::slotHandleDone); 0111 pool->start(runnable); 0112 } 0113 0114 void AsyncPackageImageResponse::slotHandleDone(const QImage &image) 0115 { 0116 m_image = image; 0117 Q_EMIT finished(); 0118 } 0119 0120 QQuickTextureFactory *AsyncPackageImageResponse::textureFactory() const 0121 { 0122 return QQuickTextureFactory::textureFactoryForImage(m_image); 0123 } 0124 0125 PackageImageProvider::PackageImageProvider() 0126 { 0127 } 0128 0129 QQuickImageResponse *PackageImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize) 0130 { 0131 AsyncPackageImageResponse *response = new AsyncPackageImageResponse(id, requestedSize, &m_pool); 0132 0133 return response; 0134 } 0135 0136 #include "packageimageprovider.moc"