File indexing completed on 2024-05-19 04:24:17

0001 /*
0002  * SPDX-FileCopyrightText: 2018 Boudewijn Rempt <boud@valdyas.org>
0003  * SPDX-FileCopyrightText: 2019 Agata Cacko <cacko.azh@gmail.com>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "KisAbrStorage.h"
0009 #include "KisResourceStorage.h"
0010 
0011 #include <QFileInfo>
0012 #include <KisStaticInitializer.h>
0013 
0014 KIS_DECLARE_STATIC_INITIALIZER {
0015     KisStoragePluginRegistry::instance()->addStoragePluginFactory(KisResourceStorage::StorageType::AdobeBrushLibrary, new KisStoragePluginFactory<KisAbrStorage>());
0016 }
0017 
0018 class AbrTagIterator : public KisResourceStorage::TagIterator
0019 {
0020 public:
0021     AbrTagIterator(KisAbrBrushCollectionSP brushCollection, const QString &location, const QString &resourceType)
0022         : m_brushCollection(brushCollection)
0023         , m_location(location)
0024         , m_resourceType(resourceType)
0025     {}
0026 
0027     bool hasNext() const override {
0028         if (m_resourceType != ResourceType::Brushes) return false;
0029         return !m_taggingDone;
0030     }
0031 
0032     void next() override { m_taggingDone = true; }
0033 
0034     KisTagSP tag() const override
0035     {
0036         KisTagSP abrTag(new KisTag());
0037         abrTag->setUrl(QFileInfo(m_location).fileName());
0038         abrTag->setName(QFileInfo(m_location).fileName());
0039         abrTag->setComment(QFileInfo(m_location).fileName());
0040         abrTag->setFilename(QFileInfo(m_location).fileName());
0041         abrTag->setResourceType(m_resourceType);
0042         abrTag->setValid(true);
0043         QStringList brushes;
0044         Q_FOREACH(const KisAbrBrushSP brush, m_brushCollection->brushes()) {
0045             brushes << brush->filename();
0046         }
0047         abrTag->setDefaultResources(brushes);
0048 
0049         return abrTag;
0050     }
0051 
0052 private:
0053 
0054     bool m_taggingDone {false};
0055     KisAbrBrushCollectionSP m_brushCollection;
0056     QString m_location;
0057     QString m_resourceType;
0058 };
0059 
0060 class AbrIterator : public KisResourceStorage::ResourceIterator
0061 {
0062 public:
0063     KisAbrBrushCollectionSP m_brushCollection;
0064     QSharedPointer<QMap<QString, KisAbrBrushSP>> m_brushesMap;
0065     QMap<QString, KisAbrBrushSP>::const_iterator m_brushCollectionIterator;
0066     KisAbrBrushSP m_currentResource;
0067     bool isLoaded;
0068     QString m_currentUrl;
0069     QString m_resourceType;
0070 
0071 
0072     AbrIterator(KisAbrBrushCollectionSP brushCollection, const QString& resourceType)
0073         : m_brushCollection(brushCollection)
0074         , isLoaded(false)
0075         , m_resourceType(resourceType)
0076     {
0077     }
0078 
0079     bool hasNext() const override
0080     {
0081         if (m_resourceType != ResourceType::Brushes) {
0082             return false;
0083         }
0084 
0085         if (!isLoaded) {
0086             bool success = m_brushCollection->load();
0087             Q_UNUSED(success); // brush collection will be empty
0088             const_cast<AbrIterator*>(this)->m_brushesMap = m_brushCollection->brushesMap();
0089             const_cast<AbrIterator*>(this)->m_brushCollectionIterator = m_brushesMap->constBegin();
0090             const_cast<AbrIterator*>(this)->isLoaded = true;
0091         }
0092 
0093         if (m_brushCollectionIterator == m_brushesMap->constEnd()) {
0094             return false;
0095         }
0096 
0097         bool hasNext = (m_brushCollectionIterator != m_brushesMap->constEnd());
0098         return hasNext;
0099     }
0100 
0101     void next() override
0102     {
0103         if (m_resourceType != ResourceType::Brushes) {
0104             return;
0105         }
0106         KIS_SAFE_ASSERT_RECOVER_RETURN(m_brushCollectionIterator != m_brushesMap->constEnd());
0107         m_currentResource = m_brushCollectionIterator.value();
0108         m_currentUrl = m_brushCollectionIterator.key();
0109         m_brushCollectionIterator++;
0110     }
0111 
0112     QString url() const override { return m_currentUrl; }
0113     QString type() const override { return ResourceType::Brushes; }
0114     QDateTime lastModified() const override { return m_brushCollection->lastModified(); }
0115 
0116     KoResourceSP resourceImpl() const override
0117     {
0118         return m_currentResource;
0119     }
0120 };
0121 
0122 KisAbrStorage::KisAbrStorage(const QString &location)
0123     : KisStoragePlugin(location)
0124     , m_brushCollection(new KisAbrBrushCollection(location))
0125 {
0126 }
0127 
0128 KisAbrStorage::~KisAbrStorage()
0129 {
0130 
0131 }
0132 
0133 KisResourceStorage::ResourceItem KisAbrStorage::resourceItem(const QString &url)
0134 {
0135     KisResourceStorage::ResourceItem item;
0136     item.url = url;
0137     // last "_" with index is the suffix added by abr_collection
0138     int indexOfUnderscore = url.lastIndexOf("_");
0139     QString filenameUrl = url;
0140     // filenameUrl contains the name of the collection (filename without .abr, brush name without index)
0141     filenameUrl.remove(indexOfUnderscore, url.length() - indexOfUnderscore);
0142     item.folder = filenameUrl;
0143     item.resourceType = ResourceType::Brushes;
0144     item.lastModified = QFileInfo(m_brushCollection->filename()).lastModified();
0145     return item;
0146 }
0147 
0148 
0149 KoResourceSP KisAbrStorage::resource(const QString &url)
0150 {
0151     if (!m_brushCollection->isLoaded()) {
0152         m_brushCollection->load();
0153     }
0154     return m_brushCollection->brushByName(QFileInfo(url).fileName());
0155 }
0156 
0157 bool KisAbrStorage::loadVersionedResource(KoResourceSP /*resource*/)
0158 {
0159     return false;
0160 }
0161 
0162 bool KisAbrStorage::supportsVersioning() const
0163 {
0164     return false;
0165 }
0166 
0167 QSharedPointer<KisResourceStorage::ResourceIterator> KisAbrStorage::resources(const QString &resourceType)
0168 {
0169     return QSharedPointer<KisResourceStorage::ResourceIterator>(new AbrIterator(m_brushCollection, resourceType));
0170 }
0171 
0172 QSharedPointer<KisResourceStorage::TagIterator> KisAbrStorage::tags(const QString &resourceType)
0173 {
0174     return QSharedPointer<KisResourceStorage::TagIterator>(new AbrTagIterator(m_brushCollection, location(), resourceType));
0175 }
0176 
0177 QImage KisAbrStorage::thumbnail() const
0178 {
0179     return m_brushCollection->image();
0180 }