Krita Source Code Documentation
Loading...
Searching...
No Matches
KisFolderStorage.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2018 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7#include "KisFolderStorage.h"
8
9#include <QDirIterator>
10#include <KisMimeDatabase.h>
11#include <kis_debug.h>
12#include <KisTag.h>
15#include <kis_pointer_utils.h>
16#include <KoMD5Generator.h>
17
18
20{
21public:
22
23 FolderTagIterator(const QString &location, const QString &resourceType)
24 : m_location(location)
25 , m_resourceType(resourceType)
26 {
27 m_dirIterator.reset(new QDirIterator(location + '/' + resourceType,
28 QStringList() << "*.tag",
29 QDir::Files | QDir::Readable,
30 QDirIterator::Subdirectories));
31 }
32
33 bool hasNext() const override
34 {
35 return m_dirIterator->hasNext();
36 }
37
38 void next() override
39 {
40 m_dirIterator->next();
41 const_cast<FolderTagIterator*>(this)->m_tag.reset(new KisTag);
42 if (!load(m_tag)) {
43 qWarning() << "Could not load tag" << m_dirIterator->filePath();
44 }
45 }
46
47 KisTagSP tag() const override
48 {
49 return m_tag;
50 }
51
52private:
53
54 bool load(KisTagSP tag) const
55 {
56 QFile f(m_dirIterator->filePath());
57 tag->setFilename(m_dirIterator->fileName());
58 if (f.open(QFile::ReadOnly)) {
59 if (!tag->load(f)) {
60 qWarning() << m_dirIterator->filePath() << "is not a valid tag desktop file";
61 return false;
62 }
63
64 }
65 return true;
66 }
67
68 QScopedPointer<QDirIterator> m_dirIterator;
69 QString m_location;
72};
73
74
76{
77public:
78 ~FolderItem() override {}
79};
80
81
82KisFolderStorage::KisFolderStorage(const QString &location)
83 : KisStoragePlugin(location)
84{
85}
86
90
91bool KisFolderStorage::saveAsNewVersion(const QString &resourceType, KoResourceSP _resource)
92{
93 return KisStorageVersioningHelper::addVersionedResource(location() + "/" + resourceType, _resource, 0);
94}
95
97{
98 QFileInfo fi(url);
99 FolderItem item;
100 item.url = url;
101 item.folder = fi.path().split("/").last();
102 item.lastModified = fi.lastModified();
103 return item;
104}
105
107{
108 QFileInfo fi(location() + '/' + resource->resourceType().first + '/' + resource->filename());
109
110 QFile f(fi.absoluteFilePath());
111 if (!f.open(QFile::ReadOnly)) {
112 qWarning() << "Could not open" << fi.absoluteFilePath() << "for reading";
113 return false;
114 }
115
116 bool r = resource->loadFromDevice(&f, KisGlobalResourcesInterface::instance());
117
118 // Check for the thumbnail
119 if (r) {
121
122 if ((resource->image().isNull() || resource->thumbnail().isNull()) && !resource->thumbnailPath().isNull()) {
123 QImage img(location() + '/' + resource->resourceType().first + '/' + resource->thumbnailPath());
124 resource->setImage(img);
125 resource->updateThumbnail();
126 }
127 }
128
129 return r;
130}
131
132QString KisFolderStorage::resourceMd5(const QString &url)
133{
134 QString result;
135
136 QFile file(location() + "/" + url);
137 if (file.exists() && file.open(QIODevice::ReadOnly)) {
138 result = KoMD5Generator::generateHash(file.readAll());
139 }
140
141 return result;
142}
143
144QString KisFolderStorage::resourceFilePath(const QString &url)
145{
146 QFileInfo file(location() + "/" + url);
147 return file.exists() ? file.absoluteFilePath() : QString();
148}
149
151{
153
154 const QString resourcesSaveLocation = location() + "/" + resourceType;
155
156 QDirIterator it(resourcesSaveLocation,
157 KisResourceLoaderRegistry::instance()->filters(resourceType),
158 QDir::Files | QDir::Readable,
159 QDirIterator::Subdirectories);;
160
161 while (it.hasNext()) {
162 it.next();
163 QFileInfo info(it.fileInfo());
164
166 entry.filename = it.filePath().mid(resourcesSaveLocation.size() + 1);
167
168 // Don't load 4.x backup resources
169 if (entry.filename.contains("backup")) {
170 continue;
171 }
172
173 entry.lastModified = info.lastModified();
174 entry.tagList = {}; // TODO
175 entry.resourceType = resourceType;
176 entries.append(entry);
177 }
178
180
181 return toQShared(new KisVersionedStorageIterator(entries, this));
182}
183
188
189bool KisFolderStorage::importResource(const QString &url, QIODevice *device)
190{
191 bool result = false;
192
193 const QString resourcesLocation = location() + "/" + url;
194
195 QFile f(resourcesLocation);
196
197 if (f.exists()) return result;
198
199 if (f.open(QFile::WriteOnly)) {
200 qint64 writtenBytes = f.write(device->readAll());
201 f.close();
202 result = (writtenBytes == device->size());
203 } else {
204 qWarning() << "Cannot open" << resourcesLocation << "for writing";
205 }
206
207 KoResourceSP resourceAfterLoading = resource(url);
208
209 if (resourceAfterLoading.isNull()) {
210 f.remove();
211 return false;
212 }
213
214 return result;
215}
216
217bool KisFolderStorage::exportResource(const QString &url, QIODevice *device)
218{
219 bool result = false;
220
221 const QString resourcesLocation = location() + "/" + url;
222
223 QFile f(resourcesLocation);
224
225 if (!f.exists()) return result;
226
227 if (f.open(QFile::ReadOnly)) {
228 device->write(f.readAll());
229 f.close();
230 result = true;
231 } else {
232 qWarning() << "Cannot open" << resourcesLocation << "for reading";
233 }
234
235 return result;
236}
237
238bool KisFolderStorage::addResource(const QString &resourceType, KoResourceSP resource)
239{
240 if (!resource || !resource->valid()) return false;
241
242 const QString resourcesSaveLocation = location() + "/" + resourceType;
243
244 QFileInfo fi(resourcesSaveLocation + "/" + resource->filename());
245 if (fi.exists()) {
246 qWarning() << "Resource" << resourceType << resource->filename() << "already exists in" << resourcesSaveLocation;
247 return false;
248 }
249
250 QFile resourceFile(fi.absoluteFilePath());
251 if (!resourceFile.open(QFile::WriteOnly)) {
252 qWarning() << "Could not open" << fi.absoluteFilePath() << "for writing.";
253 return false;
254 }
255
256 if (!resource->saveToDevice(&resourceFile)) {
257 qWarning() << "Could not save resource to" << fi.absoluteFilePath();
258 resourceFile.close();
259 return false;
260 }
261 resourceFile.close();
262
263
264
265
266 return true;
267}
268
273
274QVariant KisFolderStorage::metaData(const QString &key) const
275{
277 return i18n("Local Resources");
278 }
279 return QVariant();
280
281}
QList< QString > QStringList
~FolderItem() override
bool hasNext() const override
KisTagSP tag() const override
A tag object on which we can set properties and which we can save.
void next() override
The iterator is only valid if next() has been called at least once.
bool load(KisTagSP tag) const
QScopedPointer< QDirIterator > m_dirIterator
FolderTagIterator(const QString &location, const QString &resourceType)
KisFolderStorage(const QString &location)
bool loadVersionedResource(KoResourceSP resource) override
QString resourceMd5(const QString &url) override
QVariant metaData(const QString &key) const override
bool addResource(const QString &resourceType, KoResourceSP resource) override
QStringList metaDataKeys() const override
QString resourceFilePath(const QString &url) override
KisResourceStorage::ResourceItem resourceItem(const QString &url) override
bool importResource(const QString &url, QIODevice *device) override
bool exportResource(const QString &url, QIODevice *device) override
QSharedPointer< KisResourceStorage::ResourceIterator > resources(const QString &resourceType) override
bool saveAsNewVersion(const QString &resourceType, KoResourceSP resource) override
Adds or updates this resource to the storage.
QSharedPointer< KisResourceStorage::TagIterator > tags(const QString &resourceType) override
static KisResourcesInterfaceSP instance()
static KisResourceLoaderRegistry * instance()
static const QString s_meta_name
QString location() const
virtual KoResourceSP resource(const QString &url)
void sanitizeResourceFileNameCase(KoResourceSP resource, const QDir &parentDir)
static void detectFileVersions(QVector< VersionedResourceEntry > &allFiles)
static bool addVersionedResource(const QString &saveLocation, KoResourceSP resource, int minVersion)
The KisTag loads a tag from a .tag file. A .tag file is a .desktop file. The following fields are imp...
Definition KisTag.h:34
static QString generateHash(const QString &filename)
generateHash reads the given file and generates a hex-encoded md5sum for the file.
QSharedPointer< T > toQShared(T *ptr)
A resource item is simply an entry in the storage,.