[graphics/krita/krita/5.0] libs: Fix consistency of 'dependent_resources_filenames' metadata

Dmitry Kazakov null at kde.org
Mon Oct 11 15:19:45 BST 2021


Git commit 45e5907b4776f13c643d21772e9bed163aaf16e4 by Dmitry Kazakov.
Committed on 11/10/2021 at 14:19.
Pushed by dkazakov into branch 'krita/5.0'.

Fix consistency of 'dependent_resources_filenames' metadata

Now the update of this metadata is requested by KisResourceLocator
every time a new version of the resource is added to the database.

As noted in the commets, this check works only for legacy presets,
which don't include all their dependent resources. For the modern
presets we don't check if the dependent resources has been loaded
successfully or not. We just hope that they have been embeded
correctly.

WARNING: the previous code sometimes generated incorrect
"dependent_resources_filenames" information. If your resources became
marked as "broken", just activate them to update the metadata.

CC:kimageshop at kde.org

M  +46   -20   libs/image/brushengine/kis_paintop_preset.cpp
M  +2    -0    libs/image/brushengine/kis_paintop_preset.h
M  +5    -0    libs/resources/KisResourceLocator.cpp
M  +4    -0    libs/resources/KoResource.cpp
M  +9    -0    libs/resources/KoResource.h

https://invent.kde.org/graphics/krita/commit/45e5907b4776f13c643d21772e9bed163aaf16e4

diff --git a/libs/image/brushengine/kis_paintop_preset.cpp b/libs/image/brushengine/kis_paintop_preset.cpp
index edcd36505a..4d848c4b8b 100644
--- a/libs/image/brushengine/kis_paintop_preset.cpp
+++ b/libs/image/brushengine/kis_paintop_preset.cpp
@@ -64,13 +64,15 @@ struct Q_DECL_HIDDEN KisPaintOpPreset::Private {
 
 public:
     Private(KisPaintOpPreset *q)
-        : settingsUpdateListener(new UpdateListener(q))
+        : settingsUpdateListener(new UpdateListener(q)),
+          version("5.0")
     {
     }
 
     KisPaintOpSettingsSP settings {0};
     QScopedPointer<KisPaintOpPresetUpdateProxy> updateProxy;
     KisPaintOpSettings::UpdateListenerSP settingsUpdateListener;
+    QString version;
 };
 
 
@@ -165,11 +167,11 @@ bool KisPaintOpPreset::loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP re
 {
     QImageReader reader(dev, "PNG");
 
-    QString version = reader.text("version");
+    d->version = reader.text("version");
     QString preset = reader.text("preset");
     int resourceCount = reader.text("embedded_resources").toInt();
 
-    if (!(version == "2.2" || "5.0")) {
+    if (!(d->version == "2.2" || "5.0")) {
         return false;
     }
 
@@ -189,7 +191,7 @@ bool KisPaintOpPreset::loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP re
         return false;
     }
 
-    if (version == "5.0" && resourceCount > 0) {
+    if (d->version == "5.0" && resourceCount > 0) {
         // Load the embedded resources
         QDomNode n = doc.firstChild();
         while (!n.isNull()) {
@@ -245,21 +247,6 @@ bool KisPaintOpPreset::loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP re
 
     setValid(d->settings->isValid());
 
-    {
-        QList<KoResourceSP> dependentResources = this->requiredResources(resourcesInterface);
-        KritaUtils::makeContainerUnique(dependentResources);
-
-        QStringList resourceFileNames;
-
-        Q_FOREACH (KoResourceSP resource, dependentResources) {
-            resourceFileNames.append(resource->filename());
-        }
-
-        if (!resourceFileNames.isEmpty()) {
-            addMetaData("dependent_resources_filenames", resourceFileNames);
-        }
-    }
-
     setImage(img);
 
     return true;
@@ -370,7 +357,22 @@ bool KisPaintOpPreset::saveToDevice(QIODevice *dev) const
 
     doc.appendChild(root);
 
-    writer.setText("version", "5.0");
+    /**
+     * HACK ALERT: We update the version of the resource format on
+     * the first save operation, even though there is no guarantee
+     * that it was "save" operation, but not "export" operation.
+     *
+     * The only point it affects now is whether we need to check
+     * for the presence of the linkedResources() in
+     * updateLinkedResourcesMetaData(). The new version of the
+     * preset format ("5.0") has all the linked resources embedded
+     * outside KisPaintOpSettings, which are automatically
+     * loaded on the the resource activation. We we shouldn't
+     * add them into metaData()["dependent_resources_filenames"].
+     */
+    d->version = "5.0";
+
+    writer.setText("version", d->version);
     writer.setText("preset", doc.toString());
 
     QImage img;
@@ -385,6 +387,30 @@ bool KisPaintOpPreset::saveToDevice(QIODevice *dev) const
 
 }
 
+void KisPaintOpPreset::updateLinkedResourcesMetaData(KisResourcesInterfaceSP resourcesInterface)
+{
+    /**
+     * The new preset format embeds all the linked resources outside
+     * KisPaintOpSettings and loads them on activation, therefore we
+     * shouldn't add them into "dependent_resources_filenames".
+     */
+
+    if (d->version == "2.2") {
+        QList<KoResourceSP> dependentResources = this->linkedResources(resourcesInterface);
+        KritaUtils::makeContainerUnique(dependentResources);
+
+        QStringList resourceFileNames;
+
+        Q_FOREACH (KoResourceSP resource, dependentResources) {
+            resourceFileNames.append(resource->filename());
+        }
+
+        if (!resourceFileNames.isEmpty()) {
+            addMetaData("dependent_resources_filenames", resourceFileNames);
+        }
+    }
+}
+
 QPointer<KisPaintOpPresetUpdateProxy> KisPaintOpPreset::updateProxy() const
 {
     if (!d->updateProxy) {
diff --git a/libs/image/brushengine/kis_paintop_preset.h b/libs/image/brushengine/kis_paintop_preset.h
index 93c034422f..797efaf7a7 100644
--- a/libs/image/brushengine/kis_paintop_preset.h
+++ b/libs/image/brushengine/kis_paintop_preset.h
@@ -148,6 +148,8 @@ public:
         return QPair<QString, QString>(ResourceType::PaintOpPresets, "");
     }
 
+    void updateLinkedResourcesMetaData(KisResourcesInterfaceSP resourcesInterface) override;
+
     void toXML(QDomDocument& doc, QDomElement& elt) const;
 
     void fromXML(const QDomElement& elt, KisResourcesInterfaceSP resourcesInterface);
diff --git a/libs/resources/KisResourceLocator.cpp b/libs/resources/KisResourceLocator.cpp
index 0cad4fcdc0..7ce2dcd593 100644
--- a/libs/resources/KisResourceLocator.cpp
+++ b/libs/resources/KisResourceLocator.cpp
@@ -200,6 +200,7 @@ KoResourceSP KisResourceLocator::resource(QString storageLocation, const QString
             d->resourceCache[key] = resource;
             // load all the embedded resources into temporary "memory" storage
             loadRequiredResources(resource);
+            resource->updateLinkedResourcesMetaData(KisGlobalResourcesInterface::instance());
         }
     }
 
@@ -369,6 +370,7 @@ KoResourceSP KisResourceLocator::importResourceFromFile(const QString &resourceT
 
         Q_ASSERT(resource->md5Sum() == md5);
         resource->setVersion(0);
+        resource->updateLinkedResourcesMetaData(KisGlobalResourcesInterface::instance());
 
         // Insert into the database
         const bool result = KisResourceCacheDb::addResource(storage,
@@ -412,6 +414,7 @@ bool KisResourceLocator::addResource(const QString &resourceType, const KoResour
     resource->setStorageLocation(storageLocation);
     resource->setMD5Sum(storage->resourceMd5(resourceType + "/" + resource->filename()));
     resource->setDirty(false);
+    resource->updateLinkedResourcesMetaData(KisGlobalResourcesInterface::instance());
 
     d->resourceCache[QPair<QString, QString>(storageLocation, resourceType + "/" + resource->filename())] = resource;
 
@@ -451,6 +454,7 @@ bool KisResourceLocator::updateResource(const QString &resourceType, const KoRes
 
     resource->setMD5Sum(storage->resourceMd5(resourceType + "/" + resource->filename()));
     resource->setDirty(false);
+    resource->updateLinkedResourcesMetaData(KisGlobalResourcesInterface::instance());
 
     // The version needs already to have been incremented
     if (!KisResourceCacheDb::addResourceVersion(resource->resourceId(), QDateTime::currentDateTime(), storage, resource)) {
@@ -483,6 +487,7 @@ bool KisResourceLocator::reloadResource(const QString &resourceType, const KoRes
 
     resource->setMD5Sum(storage->resourceMd5(resourceType + "/" + resource->filename()));
     resource->setDirty(false);
+    resource->updateLinkedResourcesMetaData(KisGlobalResourcesInterface::instance());
 
     // We haven't changed the version of the resource, so the cache must be still valid
     QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType + "/" + resource->filename());
diff --git a/libs/resources/KoResource.cpp b/libs/resources/KoResource.cpp
index 6abfac224d..b9b83f8e73 100644
--- a/libs/resources/KoResource.cpp
+++ b/libs/resources/KoResource.cpp
@@ -119,6 +119,10 @@ void KoResource::updateThumbnail()
 {
 }
 
+void KoResource::updateLinkedResourcesMetaData(KisResourcesInterfaceSP resourcesInterface)
+{
+}
+
 QImage KoResource::thumbnail() const
 {
     return image();
diff --git a/libs/resources/KoResource.h b/libs/resources/KoResource.h
index 09e36da713..9547944b99 100644
--- a/libs/resources/KoResource.h
+++ b/libs/resources/KoResource.h
@@ -91,6 +91,15 @@ public:
      */
     virtual void updateThumbnail();
 
+    /**
+     * Requests the resource to update its linked-resources
+     * metadata stored in metaData()["dependent_resources_filenames"].
+     *
+     * This request comes from KisResourceLocator every time a
+     * new version of the resource is added to the database.
+     */
+    virtual void updateLinkedResourcesMetaData(KisResourcesInterfaceSP resourcesInterface);
+
     /**
      * @brief thumbnail the thumbnail image to use in resource selectors
      * @return a valid qimage. All thumbnails for a given resource have the



More information about the kimageshop mailing list