Krita Source Code Documentation
Loading...
Searching...
No Matches
KisAslStorage.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 "KisAslStorage.h"
10
11#include <QFileInfo>
14
15
18}
19
21{
22public:
23
24 AslTagIterator(const QString &location, const QString &resourceType)
25 : m_location(location)
26 , m_resourceType(resourceType)
27 {}
28
29 bool hasNext() const override {return false;}
30 void next() override {}
31
32 KisTagSP tag() const override { return nullptr; }
33
34private:
35
36 QString m_location;
38
39};
40
42{
43
44private:
45
46 QString m_filename;
49 QHash<QString, KoPatternSP> m_patterns;
51 QScopedPointer<QHashIterator<QString, KoPatternSP>> m_patternsIterator;
52 QScopedPointer<QVectorIterator<KisPSDLayerStyleSP>> m_stylesIterator;
57
58public:
59
60 AslIterator(QSharedPointer<KisAslLayerStyleSerializer> aslSerializer, const QString& filename, const QString& resourceType)
61 : m_filename(filename)
62 , m_aslSerializer(aslSerializer)
63 , m_isLoaded(false)
64 , m_resourceType(resourceType)
65 {
66 }
67
68 bool hasNext() const override
69 {
71 if (!m_aslSerializer->isInitialized()) {
72 m_aslSerializer->readFromFile(m_filename);
73 }
74
75 const_cast<AslIterator*>(this)->m_isLoaded = true;
76 const_cast<AslIterator*>(this)->m_patterns = m_aslSerializer->patterns();
77 const_cast<AslIterator*>(this)->m_styles = m_aslSerializer->styles();
78
79 const_cast<AslIterator*>(this)->m_patternsIterator.reset(new QHashIterator<QString, KoPatternSP>(m_patterns));
80 const_cast<AslIterator*>(this)->m_stylesIterator.reset(new QVectorIterator<KisPSDLayerStyleSP>(m_styles));
81 }
82 if (!m_aslSerializer->isValid()) {
83 return false;
84 }
85
89 return m_stylesIterator->hasNext();
90 }
91 return false;
92 }
93 void next() override
94 {
96 if (m_patternsIterator->hasNext()) {
98 m_patternsIterator->next();
99 KoPatternSP currentPattern = m_patternsIterator->value();
100 m_currentResource = currentPattern;
101 KIS_ASSERT(currentPattern);
102 m_currentUuid = currentPattern->filename();
103 }
105 if (m_stylesIterator->hasNext()) {
107 KisPSDLayerStyleSP currentLayerStyle = m_stylesIterator->next();
108 m_currentResource = currentLayerStyle;
109 KIS_ASSERT(currentLayerStyle);
110 m_currentUuid = currentLayerStyle->filename();
111 }
112 }
113 }
114
115 QString url() const override
116 {
117 if (m_currentResource.isNull()) {
118 return QString();
119 }
120 return m_currentUuid;
121 }
122
123 QString type() const override
124 {
125 return m_currentResource.isNull() ? QString() : m_currentType;
126 }
127
128 QDateTime lastModified() const override {
129 QFileInfo fi(m_filename);
130 return fi.lastModified();
131 }
132
133
135 KoResourceSP resourceImpl() const override
136 {
137 return m_currentResource;
138 }
139};
140
141KisAslStorage::KisAslStorage(const QString &location)
142 : KisStoragePlugin(location)
143 , m_aslSerializer(new KisAslLayerStyleSerializer())
144{
145}
146
151
153{
155 item.url = url;
156 item.folder = location();
157 item.resourceType = url.contains("pattern") ? ResourceType::Patterns : ResourceType::LayerStyles;
158 item.lastModified = QFileInfo(location()).lastModified();
159 return item;
160}
161
163{
164 if (!m_aslSerializer->isInitialized()) {
165 m_aslSerializer->readFromFile(location());
166 }
167 int indexOfUnderscore = url.lastIndexOf("_");
168 QString realUuid = url;
169 if (indexOfUnderscore >= 0) {
170 realUuid.remove(indexOfUnderscore, url.length() - indexOfUnderscore); // remove _pattern or _style added in iterator
171 }
172 // TODO: RESOURCES: Since we do get a resource type at the beginning of the path now
173 // maybe we could skip adding the _[resourcetype] at the end of the path as well?
174 realUuid = QFileInfo(realUuid).baseName(); // remove patterns/ at the beginning, if there are any
175
176 if (url.contains("pattern") || url.contains(".pat")) {
177 QHash<QString, KoPatternSP> patterns = m_aslSerializer->patterns();
178
179 if (patterns.contains(realUuid)) {
180 return patterns[realUuid];
181 }
182 }
183 else {
184 KisPSDLayerStyleSP resultingStyle;
185
186 QHash<QString, KisPSDLayerStyleSP> styles = m_aslSerializer->stylesHash();
187 if (styles.contains(realUuid)) {
188 resultingStyle = styles[realUuid];
189 } else {
190 // can be {realUuid} or {realUuid}
191 if (realUuid.startsWith("{")) {
192 realUuid = realUuid.right(realUuid.length() - 1);
193 }
194 if (realUuid.endsWith("}")) {
195 realUuid = realUuid.left(realUuid.length() - 1);
196 }
197
198 if (styles.contains(realUuid)) {
199 resultingStyle = styles[realUuid];
200 }
201 }
202
203 if (resultingStyle) {
204 KisPSDLayerStyleSP newStyle = resultingStyle->clone().dynamicCast<KisPSDLayerStyle>();
205
206 // newStyle->resourcesInterface() is guaranteed to point to a local copy of the resouces
207 // stored inside the serializer, so we need to side-load them and then reset the resources
208 // interface to the global one
209 KisAslLayerStyleSerializer::sideLoadLinkedResources(newStyle.data(), newStyle->resourcesInterface());
210 newStyle->setResourcesInterface(KisGlobalResourcesInterface::instance());
211
212 return newStyle;
213 }
214 }
215 return 0;
216}
217
219{
220 return false;
221}
222
224{
225 return false;
226}
227
232
237
238bool KisAslStorage::saveAsNewVersion(const QString &/*resourceType*/, KoResourceSP /*resource*/)
239{
240 // not implemented yet
241 warnKrita << "KisAslStorage::saveAsNewVersion is not implemented yet";
242 return false;
243}
244
245bool KisAslStorage::addResource(const QString &/*resourceType*/, KoResourceSP resource)
246{
247 if (!resource) {
248 warnKrita << "Trying to add a null resource to KisAslStorage";
249 return false;
250 }
251 KisPSDLayerStyleSP layerStyle = resource.dynamicCast<KisPSDLayerStyle>();
252 if (!layerStyle) {
253 warnKrita << "Trying to add a resource that is not a layer style to KisAslStorage";
254 return false;
255 }
256
258 styles << layerStyle;
259 m_aslSerializer->setStyles(styles);
260 return m_aslSerializer->saveToFile(location());
261}
262
264{
265 if (!m_aslSerializer->isInitialized()) {
266 m_aslSerializer->readFromFile(location());
267 }
268 return m_aslSerializer->isValid();
269}
KIS_DECLARE_STATIC_INITIALIZER
QVector< KisPSDLayerStyleSP > m_styles
QScopedPointer< QHashIterator< QString, KoPatternSP > > m_patternsIterator
QString m_currentType
QHash< QString, KoPatternSP > m_patterns
KoResourceSP resourceImpl() const override
This only loads the resource when called (but not in case of asl...)
QScopedPointer< QVectorIterator< KisPSDLayerStyleSP > > m_stylesIterator
QString type() const override
QString url() const override
AslIterator(QSharedPointer< KisAslLayerStyleSerializer > aslSerializer, const QString &filename, const QString &resourceType)
QSharedPointer< KisAslLayerStyleSerializer > m_aslSerializer
KoResourceSP m_currentResource
QString m_resourceType
QDateTime lastModified() const override
void next() override
The iterator is only valid if next() has been called at least once.
QString m_filename
QString m_currentUuid
bool hasNext() const override
void next() override
The iterator is only valid if next() has been called at least once.
AslTagIterator(const QString &location, const QString &resourceType)
bool hasNext() const override
KisTagSP tag() const override
A tag object on which we can set properties and which we can save.
static void sideLoadLinkedResources(KisPSDLayerStyle *style, KisResourcesInterfaceSP resourcesInterface)
QSharedPointer< KisResourceStorage::ResourceIterator > resources(const QString &resourceType) override
QSharedPointer< KisResourceStorage::TagIterator > tags(const QString &resourceType) override
virtual ~KisAslStorage()
bool addResource(const QString &resourceType, KoResourceSP resource) override
bool loadVersionedResource(KoResourceSP resource) override
KisResourceStorage::ResourceItem resourceItem(const QString &url) override
KisAslStorage(const QString &location)
bool saveAsNewVersion(const QString &resourceType, KoResourceSP resource) override
bool supportsVersioning() const override
QSharedPointer< KisAslLayerStyleSerializer > m_aslSerializer
KoResourceSP resource(const QString &url) override
bool isValid() const override
static KisResourcesInterfaceSP instance()
void addStoragePluginFactory(KisResourceStorage::StorageType storageType, KisStoragePluginFactoryBase *factory)
static KisStoragePluginRegistry * instance()
QString location() const
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
#define warnKrita
Definition kis_debug.h:87
const QString LayerStyles
const QString Patterns
The KisPSDLayerStyle class implements loading, saving and applying the PSD layer effects.
A resource item is simply an entry in the storage,.