cache icons based on pixel content instead of image string
This commit is contained in:
+5
-30
@@ -218,7 +218,7 @@ Singleton {
|
|||||||
function onImageChanged(): void {
|
function onImageChanged(): void {
|
||||||
notif.imageSource = notif.notification.image || "";
|
notif.imageSource = notif.notification.image || "";
|
||||||
notif.image = notif.imageSource;
|
notif.image = notif.imageSource;
|
||||||
notif.cacheImageIfNeeded();
|
notif.cacheImageIfNeeded(notif.imageSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onResidentChanged(): void {
|
function onResidentChanged(): void {
|
||||||
@@ -283,29 +283,18 @@ Singleton {
|
|||||||
}
|
}
|
||||||
property int urgency: NotificationUrgency.Normal
|
property int urgency: NotificationUrgency.Normal
|
||||||
|
|
||||||
function cacheImageIfNeeded(): void {
|
function cacheImageIfNeeded(source: string): void {
|
||||||
const source = imageSource;
|
|
||||||
|
|
||||||
if (!source || cachingImage)
|
if (!source || cachingImage)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cachedImageSource === source)
|
if (cachedImageSource === source)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (source.startsWith("file:")) {
|
|
||||||
cachedImageSource = source;
|
|
||||||
image = source;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const hash = hashForString(source);
|
|
||||||
const cache = `${Paths.notifimagecache}/${hash}.png`;
|
|
||||||
const cacheUrl = Qt.resolvedUrl(cache);
|
|
||||||
|
|
||||||
cachingImage = true;
|
cachingImage = true;
|
||||||
ZShellIo.saveImage(source, cacheUrl, () => {
|
|
||||||
|
ZShellIo.cacheImage(Qt.resolvedUrl(source), Paths.notifimagecache, (path, url) => {
|
||||||
cachedImageSource = source;
|
cachedImageSource = source;
|
||||||
image = cache;
|
image = path;
|
||||||
cachingImage = false;
|
cachingImage = false;
|
||||||
}, () => {
|
}, () => {
|
||||||
cachingImage = false;
|
cachingImage = false;
|
||||||
@@ -321,20 +310,6 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hashForString(s: string): string {
|
|
||||||
let h1 = 0xdeadbeef, h2 = 0x41c6ce57, ch;
|
|
||||||
for (let i = 0; i < s.length; i++) {
|
|
||||||
ch = s.charCodeAt(i);
|
|
||||||
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
||||||
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
||||||
}
|
|
||||||
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
|
|
||||||
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
|
|
||||||
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);
|
|
||||||
h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);
|
|
||||||
return (h2 >>> 0).toString(16).padStart(8, "0") + (h1 >>> 0).toString(16).padStart(8, "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
function lock(item: Item): void {
|
function lock(item: Item): void {
|
||||||
locks.add(item);
|
locks.add(item);
|
||||||
}
|
}
|
||||||
|
|||||||
+141
-155
@@ -1,17 +1,22 @@
|
|||||||
#include "writefile.hpp"
|
#include "writefile.hpp"
|
||||||
|
|
||||||
#include <QtConcurrent/qtconcurrentrun.h>
|
#include <QtConcurrent/qtconcurrentrun.h>
|
||||||
|
#include <QtCore/QCryptographicHash>
|
||||||
|
#include <QtCore/QSaveFile>
|
||||||
|
#include <QtGui/QImageReader>
|
||||||
#include <QtQuick/qquickimageprovider.h>
|
#include <QtQuick/qquickimageprovider.h>
|
||||||
#include <QtQuick/qquickitemgrabresult.h>
|
#include <QtQuick/qquickitemgrabresult.h>
|
||||||
#include <QtQuick/qquickwindow.h>
|
#include <QtQuick/qquickwindow.h>
|
||||||
|
|
||||||
#include <qdir.h>
|
#include <QDir>
|
||||||
#include <qfile.h>
|
#include <QFile>
|
||||||
#include <qfileinfo.h>
|
#include <QFileInfo>
|
||||||
#include <qfuturewatcher.h>
|
#include <QFutureWatcher>
|
||||||
#include <qimage.h>
|
#include <QImage>
|
||||||
#include <qjsengine.h>
|
#include <QJSValue>
|
||||||
#include <qqmlengine.h>
|
#include <QQmlEngine>
|
||||||
|
#include <QSize>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
namespace ZShell {
|
namespace ZShell {
|
||||||
|
|
||||||
@@ -84,54 +89,51 @@ void ZShellIo::saveItem(
|
|||||||
&QQuickItemGrabResult::ready,
|
&QQuickItemGrabResult::ready,
|
||||||
this,
|
this,
|
||||||
[grabResult, scaledRect, path, onSaved, onFailed, this]() {
|
[grabResult, scaledRect, path, onSaved, onFailed, this]() {
|
||||||
|
const auto future = QtConcurrent::run([grabResult, scaledRect, path]() {
|
||||||
|
QImage image = grabResult->image();
|
||||||
|
|
||||||
QImage image = grabResult->image();
|
if (scaledRect.isValid()) {
|
||||||
|
image = image.copy(scaledRect);
|
||||||
if (scaledRect.isValid()) {
|
}
|
||||||
image = image.copy(scaledRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto future = QtConcurrent::run([image, path]() {
|
|
||||||
|
|
||||||
const QString file = path.toLocalFile();
|
const QString file = path.toLocalFile();
|
||||||
const QString parent = QFileInfo(file).absolutePath();
|
const QString parent = QFileInfo(file).absolutePath();
|
||||||
|
|
||||||
return QDir().mkpath(parent) && image.save(file);
|
QDir().mkpath(parent);
|
||||||
|
|
||||||
|
QSaveFile out(file);
|
||||||
|
if (!out.open(QIODevice::WriteOnly)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!image.save(&out, "PNG")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.commit();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* watcher = new QFutureWatcher<bool>(this);
|
auto* watcher = new QFutureWatcher<bool>(this);
|
||||||
auto* engine = qmlEngine(this);
|
auto* engine = qmlEngine(this);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(watcher, &QFutureWatcher<bool>::finished, this, [=]() {
|
||||||
watcher,
|
|
||||||
&QFutureWatcher<bool>::finished,
|
|
||||||
this,
|
|
||||||
[=]() {
|
|
||||||
|
|
||||||
if (watcher->result()) {
|
if (watcher->result()) {
|
||||||
|
if (onSaved.isCallable() && engine) {
|
||||||
if (onSaved.isCallable()) {
|
|
||||||
onSaved.call({
|
onSaved.call({
|
||||||
QJSValue(path.toLocalFile()),
|
engine->toScriptValue(path.toLocalFile()),
|
||||||
engine->toScriptValue(QVariant::fromValue(path))
|
engine->toScriptValue(path)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
qWarning() << "ZShellIo::saveItem: failed to save" << path;
|
||||||
qWarning() << "ZShellIo::saveItem: failed to save"
|
if (onFailed.isCallable() && engine) {
|
||||||
<< path;
|
|
||||||
|
|
||||||
if (onFailed.isCallable()) {
|
|
||||||
onFailed.call({
|
onFailed.call({
|
||||||
engine->toScriptValue(QVariant::fromValue(path))
|
engine->toScriptValue(path)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watcher->deleteLater();
|
watcher->deleteLater();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
watcher->setFuture(future);
|
watcher->setFuture(future);
|
||||||
}
|
}
|
||||||
@@ -139,106 +141,130 @@ void ZShellIo::saveItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// saveImage
|
// cacheImage
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
void ZShellIo::saveImage(const QUrl& source, const QUrl& target) {
|
void ZShellIo::cacheImage(const QUrl& source, const QString& cacheDir) {
|
||||||
this->saveImage(source, target, QJSValue(), QJSValue());
|
this->cacheImage(source, cacheDir, QJSValue(), QJSValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZShellIo::saveImage(const QUrl& source, const QUrl& target, QJSValue onSaved) {
|
void ZShellIo::cacheImage(const QUrl& source, const QString& cacheDir, QJSValue onSaved) {
|
||||||
this->saveImage(source, target, onSaved, QJSValue());
|
this->cacheImage(source, cacheDir, onSaved, QJSValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZShellIo::saveImage(
|
void ZShellIo::cacheImage(
|
||||||
const QUrl& source,
|
const QUrl& source,
|
||||||
const QUrl& target,
|
const QString& cacheDir,
|
||||||
QJSValue onSaved,
|
QJSValue onSaved,
|
||||||
QJSValue onFailed
|
QJSValue onFailed
|
||||||
) {
|
) {
|
||||||
auto* engine = qmlEngine(this);
|
if (cacheDir.isEmpty()) {
|
||||||
|
qWarning() << "ZShellIo::cacheImage: cacheDir is empty";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto future = QtConcurrent::run([this, source, target]() {
|
QImage image;
|
||||||
return this->saveImageInternal(source, target);
|
if (!loadSourceImage(source, image)) {
|
||||||
|
qWarning() << "ZShellIo::cacheImage: failed to load source image" << source;
|
||||||
|
auto* engine = qmlEngine(this);
|
||||||
|
if (onFailed.isCallable() && engine) {
|
||||||
|
onFailed.call({
|
||||||
|
engine->toScriptValue(source),
|
||||||
|
engine->toScriptValue(cacheDir)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto future = QtConcurrent::run([image, cacheDir]() -> QString {
|
||||||
|
if (image.isNull()) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QImage normalized = image.convertToFormat(QImage::Format_RGBA8888);
|
||||||
|
|
||||||
|
const QByteArray bytes(
|
||||||
|
reinterpret_cast<const char*>(normalized.constBits()),
|
||||||
|
qsizetype(normalized.sizeInBytes())
|
||||||
|
);
|
||||||
|
|
||||||
|
const QByteArray digest =
|
||||||
|
QCryptographicHash::hash(bytes, QCryptographicHash::Sha256).toHex();
|
||||||
|
|
||||||
|
QDir dir(cacheDir);
|
||||||
|
if (!dir.exists() && !QDir().mkpath(cacheDir)) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString finalPath = dir.filePath(QString::fromLatin1(digest) + ".png");
|
||||||
|
|
||||||
|
if (QFile::exists(finalPath)) {
|
||||||
|
return finalPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSaveFile out(finalPath);
|
||||||
|
if (!out.open(QIODevice::WriteOnly)) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!normalized.save(&out, "PNG")) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!out.commit()) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalPath;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* watcher = new QFutureWatcher<bool>(this);
|
auto* watcher = new QFutureWatcher<QString>(this);
|
||||||
|
auto* engine = qmlEngine(this);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(watcher, &QFutureWatcher<QString>::finished, this, [=]() {
|
||||||
watcher,
|
const QString finalPath = watcher->result();
|
||||||
&QFutureWatcher<bool>::finished,
|
|
||||||
this,
|
|
||||||
[=]() {
|
|
||||||
|
|
||||||
if (watcher->result()) {
|
if (!finalPath.isEmpty()) {
|
||||||
|
if (onSaved.isCallable() && engine) {
|
||||||
if (onSaved.isCallable()) {
|
|
||||||
onSaved.call({
|
onSaved.call({
|
||||||
QJSValue(target.toLocalFile()),
|
engine->toScriptValue(finalPath),
|
||||||
engine->toScriptValue(QVariant::fromValue(target))
|
engine->toScriptValue(QUrl::fromLocalFile(finalPath))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
qWarning() << "ZShellIo::cacheImage: failed to cache" << source;
|
||||||
qWarning() << "ZShellIo::saveImage: failed to save"
|
if (onFailed.isCallable() && engine) {
|
||||||
<< source
|
|
||||||
<< "to"
|
|
||||||
<< target;
|
|
||||||
|
|
||||||
if (onFailed.isCallable()) {
|
|
||||||
onFailed.call({
|
onFailed.call({
|
||||||
engine->toScriptValue(QVariant::fromValue(target))
|
engine->toScriptValue(source),
|
||||||
|
engine->toScriptValue(cacheDir)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watcher->deleteLater();
|
watcher->deleteLater();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
watcher->setFuture(future);
|
watcher->setFuture(future);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZShellIo::saveImageInternal(const QUrl& source, const QUrl& target) const {
|
// ============================================================
|
||||||
|
// loadSourceImage
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
if (!target.isLocalFile()) {
|
bool ZShellIo::loadSourceImage(const QUrl& source, QImage& image) const {
|
||||||
qWarning() << "ZShellIo::saveImage: target"
|
image = QImage();
|
||||||
<< target
|
|
||||||
<< "is not a local file";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString targetFile = target.toLocalFile();
|
|
||||||
|
|
||||||
if (!QDir().mkpath(QFileInfo(targetFile).absolutePath())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========================================================
|
|
||||||
// Local file path
|
|
||||||
// ========================================================
|
|
||||||
|
|
||||||
if (source.isLocalFile()) {
|
if (source.isLocalFile()) {
|
||||||
|
QImageReader reader(source.toLocalFile());
|
||||||
QFile::remove(targetFile);
|
reader.setAutoTransform(true);
|
||||||
|
image = reader.read();
|
||||||
return QFile::copy(
|
return !image.isNull();
|
||||||
source.toLocalFile(),
|
|
||||||
targetFile
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========================================================
|
|
||||||
// image:// provider path
|
|
||||||
// ========================================================
|
|
||||||
|
|
||||||
if (source.scheme() == "image") {
|
if (source.scheme() == "image") {
|
||||||
|
|
||||||
auto* engine = qmlEngine(const_cast<ZShellIo*>(this));
|
auto* engine = qmlEngine(const_cast<ZShellIo*>(this));
|
||||||
|
|
||||||
if (!engine) {
|
if (!engine) {
|
||||||
qWarning() << "ZShellIo::saveImage: no QQmlEngine";
|
qWarning() << "ZShellIo::loadSourceImage: no QQmlEngine";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,70 +272,44 @@ bool ZShellIo::saveImageInternal(const QUrl& source, const QUrl& target) const {
|
|||||||
|
|
||||||
const QString imageId =
|
const QString imageId =
|
||||||
source.path().startsWith('/')
|
source.path().startsWith('/')
|
||||||
? source.path().mid(1)
|
? source.path().mid(1)
|
||||||
: source.path();
|
: source.path();
|
||||||
|
|
||||||
auto* providerBase =
|
|
||||||
engine->imageProvider(providerId);
|
|
||||||
|
|
||||||
|
auto* providerBase = engine->imageProvider(providerId);
|
||||||
if (!providerBase) {
|
if (!providerBase) {
|
||||||
qWarning() << "ZShellIo::saveImage: provider not found"
|
qWarning() << "ZShellIo::loadSourceImage: provider not found"
|
||||||
<< providerId;
|
<< providerId;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* provider =
|
auto* provider = dynamic_cast<QQuickImageProvider*>(providerBase);
|
||||||
dynamic_cast<QQuickImageProvider*>(providerBase);
|
|
||||||
|
|
||||||
if (!provider) {
|
if (!provider) {
|
||||||
qWarning() << "ZShellIo::saveImage: provider is not a QQuickImageProvider"
|
qWarning() << "ZShellIo::loadSourceImage: provider is not a QQuickImageProvider"
|
||||||
<< providerId;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!provider) {
|
|
||||||
qWarning() << "ZShellIo::saveImage: provider not found"
|
|
||||||
<< providerId;
|
<< providerId;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize size;
|
QSize size;
|
||||||
QImage image;
|
|
||||||
|
|
||||||
switch (provider->imageType()) {
|
switch (provider->imageType()) {
|
||||||
|
|
||||||
case QQuickImageProvider::Image:
|
case QQuickImageProvider::Image:
|
||||||
image = provider->requestImage(
|
image = provider->requestImage(imageId, &size, QSize());
|
||||||
imageId,
|
|
||||||
&size,
|
|
||||||
QSize()
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QQuickImageProvider::Pixmap:
|
case QQuickImageProvider::Pixmap:
|
||||||
image = provider->requestPixmap(
|
image = provider->requestPixmap(imageId, &size, QSize()).toImage();
|
||||||
imageId,
|
|
||||||
&size,
|
|
||||||
QSize()
|
|
||||||
).toImage();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
qWarning() << "ZShellIo::saveImage: unsupported provider type";
|
qWarning() << "ZShellIo::loadSourceImage: unsupported provider type"
|
||||||
|
<< providerId;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image.isNull()) {
|
return !image.isNull();
|
||||||
qWarning() << "ZShellIo::saveImage: provider returned null image";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return image.save(targetFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qWarning() << "ZShellIo::saveImage: unsupported source"
|
qWarning() << "ZShellIo::loadSourceImage: unsupported source" << source;
|
||||||
<< source;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,18 +318,12 @@ bool ZShellIo::saveImageInternal(const QUrl& source, const QUrl& target) const {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
bool ZShellIo::copyFile(const QUrl& source, const QUrl& target, bool overwrite) const {
|
bool ZShellIo::copyFile(const QUrl& source, const QUrl& target, bool overwrite) const {
|
||||||
|
|
||||||
if (!source.isLocalFile()) {
|
if (!source.isLocalFile()) {
|
||||||
qWarning() << "ZShellIo::copyFile: source"
|
qWarning() << "ZShellIo::copyFile: source" << source << "is not a local file";
|
||||||
<< source
|
|
||||||
<< "is not a local file";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target.isLocalFile()) {
|
if (!target.isLocalFile()) {
|
||||||
qWarning() << "ZShellIo::copyFile: target"
|
qWarning() << "ZShellIo::copyFile: target" << target << "is not a local file";
|
||||||
<< target
|
|
||||||
<< "is not a local file";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,18 +331,12 @@ bool ZShellIo::copyFile(const QUrl& source, const QUrl& target, bool overwrite)
|
|||||||
QFile::remove(target.toLocalFile());
|
QFile::remove(target.toLocalFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
return QFile::copy(
|
return QFile::copy(source.toLocalFile(), target.toLocalFile());
|
||||||
source.toLocalFile(),
|
|
||||||
target.toLocalFile()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZShellIo::deleteFile(const QUrl& path) const {
|
bool ZShellIo::deleteFile(const QUrl& path) const {
|
||||||
|
|
||||||
if (!path.isLocalFile()) {
|
if (!path.isLocalFile()) {
|
||||||
qWarning() << "ZShellIo::deleteFile: path"
|
qWarning() << "ZShellIo::deleteFile: path" << path << "is not a local file";
|
||||||
<< path
|
|
||||||
<< "is not a local file";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,10 +344,8 @@ bool ZShellIo::deleteFile(const QUrl& path) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString ZShellIo::toLocalFile(const QUrl& url) const {
|
QString ZShellIo::toLocalFile(const QUrl& url) const {
|
||||||
|
|
||||||
if (!url.isLocalFile()) {
|
if (!url.isLocalFile()) {
|
||||||
qWarning() << "ZShellIo::toLocalFile: given url is not a local file"
|
qWarning() << "ZShellIo::toLocalFile: given url is not a local file" << url;
|
||||||
<< url;
|
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QtQuick/qquickitem.h>
|
#include <QtQuick/qquickitem.h>
|
||||||
#include <qjsvalue.h>
|
#include <QImage>
|
||||||
#include <qobject.h>
|
#include <QJSValue>
|
||||||
|
#include <QObject>
|
||||||
#include <qqmlintegration.h>
|
#include <qqmlintegration.h>
|
||||||
#include <qurl.h>
|
#include <QUrl>
|
||||||
|
|
||||||
namespace ZShell {
|
namespace ZShell {
|
||||||
|
|
||||||
@@ -23,9 +24,9 @@ Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved
|
|||||||
Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved);
|
Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved);
|
||||||
Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved, QJSValue onFailed);
|
Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved, QJSValue onFailed);
|
||||||
|
|
||||||
Q_INVOKABLE void saveImage(const QUrl& source, const QUrl& target);
|
Q_INVOKABLE void cacheImage(const QUrl& source, const QString& cacheDir);
|
||||||
Q_INVOKABLE void saveImage(const QUrl& source, const QUrl& target, QJSValue onSaved);
|
Q_INVOKABLE void cacheImage(const QUrl& source, const QString& cacheDir, QJSValue onSaved);
|
||||||
Q_INVOKABLE void saveImage(const QUrl& source, const QUrl& target, QJSValue onSaved, QJSValue onFailed);
|
Q_INVOKABLE void cacheImage(const QUrl& source, const QString& cacheDir, QJSValue onSaved, QJSValue onFailed);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
Q_INVOKABLE bool copyFile(const QUrl& source, const QUrl& target, bool overwrite = true) const;
|
Q_INVOKABLE bool copyFile(const QUrl& source, const QUrl& target, bool overwrite = true) const;
|
||||||
@@ -33,7 +34,7 @@ Q_INVOKABLE bool deleteFile(const QUrl& path) const;
|
|||||||
Q_INVOKABLE QString toLocalFile(const QUrl& url) const;
|
Q_INVOKABLE QString toLocalFile(const QUrl& url) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool saveImageInternal(const QUrl& source, const QUrl& target) const;
|
bool loadSourceImage(const QUrl& source, QImage& image) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZShell
|
} // namespace ZShell
|
||||||
|
|||||||
Reference in New Issue
Block a user