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

Halla Rempt null at kde.org
Fri Oct 8 12:40:19 BST 2021


Git commit 43186c29b617c95192eb2ccfbe683a3cb0ca9628 by Halla Rempt, on behalf of Dmitry Kazakov.
Committed on 08/10/2021 at 11:39.
Pushed by rempt into branch 'master'.

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/43186c29b617c95192eb2ccfbe683a3cb0ca9628

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 5bbd2fa53b..d5cacd2c96 100644
--- a/libs/resources/KoResource.cpp
+++ b/libs/resources/KoResource.cpp
@@ -124,6 +124,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