blob: d549e8cab54eb16c34dbff995d9513a9b287d3e4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#include "cachingimagemanager.hpp"
#include <qobject.h>
#include <QtQuick/QQuickItem>
#include <QtQuick/QQuickWindow>
#include <QCryptographicHash>
#include <QThreadPool>
#include <QFile>
qreal CachingImageManager::effectiveScale() const {
if (m_item->window() && m_item->window()->screen()) {
return m_item->window()->screen()->devicePixelRatio();
}
return 1.0;
}
int CachingImageManager::effectiveWidth() const {
int width = std::ceil(m_item->width() * effectiveScale());
m_item->setProperty("sourceWidth", width);
return width;
}
int CachingImageManager::effectiveHeight() const {
int height = std::ceil(m_item->height() * effectiveScale());
m_item->setProperty("sourceHeight", height);
return height;
}
QQuickItem* CachingImageManager::item() const {
return m_item;
}
void CachingImageManager::setItem(QQuickItem* item) {
if (m_item == item) {
return;
}
m_item = item;
emit itemChanged();
}
QUrl CachingImageManager::cacheDir() const {
return m_cacheDir;
}
void CachingImageManager::setCacheDir(const QUrl& cacheDir) {
if (m_cacheDir == cacheDir) {
return;
}
m_cacheDir = cacheDir;
if (!m_cacheDir.path().endsWith("/")) {
m_cacheDir.setPath(m_cacheDir.path() + "/");
}
emit cacheDirChanged();
}
QString CachingImageManager::path() const {
return m_path;
}
void CachingImageManager::setPath(const QString& path) {
if (m_path == path) {
return;
}
m_path = path;
emit pathChanged();
if (!path.isEmpty()) {
QThreadPool::globalInstance()->start([path, this] {
const QString filename = QString("%1@%2x%3.png")
.arg(sha256sum(path))
.arg(effectiveWidth())
.arg(effectiveHeight());
m_cachePath = m_cacheDir.resolved(QUrl(filename));
emit cachePathChanged();
if (!m_cachePath.isLocalFile()) {
qWarning() << "CachingImageManager::setPath: cachePath" << m_cachePath << "is not a local file";
return;
}
if (QFile::exists(m_cachePath.toLocalFile())) {
QMetaObject::invokeMethod(m_item, [this]() {
m_item->setProperty("source", m_cachePath);
}, Qt::QueuedConnection);
m_usingCache = true;
emit usingCacheChanged();
} else {
QMetaObject::invokeMethod(m_item, [path, this]() {
m_item->setProperty("source", QUrl::fromLocalFile(path));
}, Qt::QueuedConnection);
m_usingCache = false;
emit usingCacheChanged();
}
});
}
}
QUrl CachingImageManager::cachePath() const {
return m_cachePath;
}
bool CachingImageManager::usingCache() const {
return m_usingCache;
}
QString CachingImageManager::sha256sum(const QString& path) const {
QFile file(path);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "CachingImageManager::sha256sum: failed to open" << path;
return "";
}
QCryptographicHash hash(QCryptographicHash::Sha256);
hash.addData(&file);
file.close();
return hash.result().toHex();
}
|