You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.2 KiB
128 lines
3.2 KiB
/* |
|
SPDX-FileCopyrightText: 2022 Fushan Wen <qydwhotmail@gmail.com> |
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later |
|
*/ |
|
|
|
#include "packageimageprovider.h" |
|
|
|
#include <QGuiApplication> |
|
#include <QImageReader> |
|
#include <QPalette> |
|
#include <QUrlQuery> |
|
|
|
#include <KPackage/PackageLoader> |
|
|
|
#include "finder/packagefinder.h" |
|
|
|
class AsyncPackageImageResponseRunnable : public QObject, public QRunnable |
|
{ |
|
Q_OBJECT |
|
|
|
public: |
|
explicit AsyncPackageImageResponseRunnable(const QString &path, const QSize &requestedSize); |
|
|
|
/** |
|
* Read the image and resize it if the requested size is valid. |
|
*/ |
|
void run() override; |
|
|
|
Q_SIGNALS: |
|
void done(const QImage &image); |
|
|
|
private: |
|
QString m_path; |
|
QSize m_requestedSize; |
|
}; |
|
|
|
class AsyncPackageImageResponse : public QQuickImageResponse |
|
{ |
|
Q_OBJECT |
|
|
|
public: |
|
explicit AsyncPackageImageResponse(const QString &path, const QSize &requestedSize, QThreadPool *pool); |
|
|
|
QQuickTextureFactory *textureFactory() const override; |
|
|
|
protected Q_SLOTS: |
|
void slotHandleDone(const QImage &image); |
|
|
|
protected: |
|
QImage m_image; |
|
}; |
|
|
|
AsyncPackageImageResponseRunnable::AsyncPackageImageResponseRunnable(const QString &path, const QSize &requestedSize) |
|
: m_path(path) |
|
, m_requestedSize(requestedSize) |
|
{ |
|
} |
|
|
|
void AsyncPackageImageResponseRunnable::run() |
|
{ |
|
const QUrlQuery urlQuery(QUrl(QStringLiteral("image://package/%1").arg(m_path))); |
|
const QString dir = urlQuery.queryItemValue(QStringLiteral("dir")); |
|
|
|
if (dir.isEmpty()) { |
|
Q_EMIT done(QImage()); |
|
return; |
|
} |
|
|
|
KPackage::Package package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Wallpaper/Images")); |
|
package.setPath(dir); |
|
|
|
if (!package.isValid()) { |
|
Q_EMIT done(QImage()); |
|
return; |
|
} |
|
|
|
PackageFinder::findPreferredImageInPackage(package, m_requestedSize); |
|
|
|
QString path = package.filePath("preferred"); |
|
// 192 is from kcm_colors |
|
if (qGray(qGuiApp->palette().window().color().rgb()) < 192) { |
|
QString darkPath = package.filePath("preferredDark"); |
|
|
|
if (!darkPath.isEmpty()) { |
|
path = darkPath; |
|
} |
|
} |
|
|
|
QImage image(path); |
|
|
|
if (!image.isNull() && m_requestedSize.isValid()) { |
|
image = image.scaled(m_requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); |
|
} |
|
|
|
Q_EMIT done(image); |
|
} |
|
|
|
AsyncPackageImageResponse::AsyncPackageImageResponse(const QString &path, const QSize &requestedSize, QThreadPool *pool) |
|
{ |
|
auto runnable = new AsyncPackageImageResponseRunnable(path, requestedSize); |
|
connect(runnable, &AsyncPackageImageResponseRunnable::done, this, &AsyncPackageImageResponse::slotHandleDone); |
|
pool->start(runnable); |
|
} |
|
|
|
void AsyncPackageImageResponse::slotHandleDone(const QImage &image) |
|
{ |
|
m_image = image; |
|
Q_EMIT finished(); |
|
} |
|
|
|
QQuickTextureFactory *AsyncPackageImageResponse::textureFactory() const |
|
{ |
|
return QQuickTextureFactory::textureFactoryForImage(m_image); |
|
} |
|
|
|
PackageImageProvider::PackageImageProvider() |
|
{ |
|
} |
|
|
|
QQuickImageResponse *PackageImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize) |
|
{ |
|
AsyncPackageImageResponse *response = new AsyncPackageImageResponse(id, requestedSize, &m_pool); |
|
|
|
return response; |
|
} |
|
|
|
#include "packageimageprovider.moc"
|
|
|