[graphics/drawy] src/gui: Load/save custom elements

Laurent Montel <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit e450cfb98b710ec907b2755d8db8a0104c985ab7 by Laurent Montel.
Committed on 17/07/2026 at 06:27.
Pushed by mlaurent into branch 'master'.

Load/save custom elements

M  +2    -0    src/gui/CMakeLists.txt
M  +2    -0    src/gui/autotests/CMakeLists.txt
A  +22   -0    src/gui/autotests/customelementsutilstest.cpp     [License: GPL(v3.0+)]
A  +19   -0    src/gui/autotests/customelementsutilstest.hpp     [License: GPL(v3.0+)]
A  +23   -0    src/gui/autotests/customelementtest.cpp     [License: GPL(v3.0+)]
A  +20   -0    src/gui/autotests/customelementtest.hpp     [License: GPL(v3.0+)]
M  +41   -3    src/gui/customelements/customelement.cpp
M  +21   -4    src/gui/customelements/customelement.hpp
M  +61   -1    src/gui/customelements/customelementsmanager.cpp
M  +5    -0    src/gui/customelements/customelementsmanager.hpp
A  +15   -0    src/gui/customelements/customelementsutils.cpp     [License: GPL(v3.0+)]
A  +13   -0    src/gui/customelements/customelementsutils.hpp     [License: GPL(v3.0+)]

https://invent.kde.org/graphics/drawy/-/commit/e450cfb98b710ec907b2755d8db8a0104c985ab7

diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 472b0837..57cbfd82 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -144,6 +144,8 @@ target_sources(
         customelements/customelementsmanager.cpp
         customelements/customelement.hpp
         customelements/customelement.cpp
+        customelements/customelementsutils.hpp
+        customelements/customelementsutils.cpp
 )
 
 ecm_qt_declare_logging_category(libdrawygui HEADER drawy_gui_debug.h IDENTIFIER DRAWY_GUI_LOG
diff --git a/src/gui/autotests/CMakeLists.txt b/src/gui/autotests/CMakeLists.txt
index d9cdde11..bbdfc10c 100644
--- a/src/gui/autotests/CMakeLists.txt
+++ b/src/gui/autotests/CMakeLists.txt
@@ -61,3 +61,5 @@ add_drawy_gui_unittest(diamonditemtest.cpp)
 add_drawy_gui_unittest(pluginformutilstest.cpp)
 add_drawy_gui_unittest(imageitemtest.cpp)
 add_drawy_gui_unittest(customelementsmanagertest.cpp)
+add_drawy_gui_unittest(customelementsutilstest.cpp)
+add_drawy_gui_unittest(customelementtest.cpp)
diff --git a/src/gui/autotests/customelementsutilstest.cpp b/src/gui/autotests/customelementsutilstest.cpp
new file mode 100644
index 00000000..cdc75ab0
--- /dev/null
+++ b/src/gui/autotests/customelementsutilstest.cpp
@@ -0,0 +1,22 @@
+/*
+ * SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+#include "customelementsutilstest.hpp"
+#include "customelements/customelementsutils.hpp"
+#include <QStandardPaths>
+#include <QTest>
+QTEST_GUILESS_MAIN(CustomElementsUtilsTest)
+using namespace Qt::Literals::StringLiterals;
+CustomElementsUtilsTest::CustomElementsUtilsTest(QObject *parent)
+    : QObject{parent}
+{
+}
+
+void CustomElementsUtilsTest::shouldHaveDefaultValues()
+{
+    QCOMPARE(CustomElementsUtils::customElementsFilePath(), QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + u"/custom-elements/"_s);
+}
+
+#include "moc_customelementsutilstest.cpp"
diff --git a/src/gui/autotests/customelementsutilstest.hpp b/src/gui/autotests/customelementsutilstest.hpp
new file mode 100644
index 00000000..f8c06159
--- /dev/null
+++ b/src/gui/autotests/customelementsutilstest.hpp
@@ -0,0 +1,19 @@
+/*
+ * SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+#pragma once
+
+#include <QObject>
+
+class CustomElementsUtilsTest : public QObject
+{
+    Q_OBJECT
+public:
+    explicit CustomElementsUtilsTest(QObject *parent = nullptr);
+    ~CustomElementsUtilsTest() override = default;
+
+private Q_SLOTS:
+    void shouldHaveDefaultValues();
+};
diff --git a/src/gui/autotests/customelementtest.cpp b/src/gui/autotests/customelementtest.cpp
new file mode 100644
index 00000000..f74d9365
--- /dev/null
+++ b/src/gui/autotests/customelementtest.cpp
@@ -0,0 +1,23 @@
+/*
+ * SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "customelementtest.hpp"
+#include "customelements/customelement.hpp"
+#include <QTest>
+QTEST_GUILESS_MAIN(CustomElementTest)
+
+CustomElementTest::CustomElementTest(QObject *parent)
+    : QObject{parent}
+{
+}
+
+void CustomElementTest::shouldHaveDefaultValues()
+{
+    const CustomElement w;
+    QVERIFY(!w.isValid());
+    QVERIFY(!w.item());
+}
+#include "moc_customelementtest.cpp"
diff --git a/src/gui/autotests/customelementtest.hpp b/src/gui/autotests/customelementtest.hpp
new file mode 100644
index 00000000..ce1b2cf1
--- /dev/null
+++ b/src/gui/autotests/customelementtest.hpp
@@ -0,0 +1,20 @@
+/*
+ * SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <QObject>
+
+class CustomElementTest : public QObject
+{
+    Q_OBJECT
+public:
+    explicit CustomElementTest(QObject *parent = nullptr);
+    ~CustomElementTest() override = default;
+
+private Q_SLOTS:
+    void shouldHaveDefaultValues();
+};
diff --git a/src/gui/customelements/customelement.cpp b/src/gui/customelements/customelement.cpp
index 2b5ed19f..b44b34e9 100644
--- a/src/gui/customelements/customelement.cpp
+++ b/src/gui/customelements/customelement.cpp
@@ -4,16 +4,54 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 #include "customelement.hpp"
+#include "serializer/deserializeutils.hpp"
+#include <QDateTime>
 #include <QJsonObject>
 
 using namespace Qt::Literals::StringLiterals;
-CustomElement::CustomElement() = default;
+CustomElement::CustomElement()
+    : mTimeStamp(QDateTime::currentSecsSinceEpoch())
+{
+}
+
 CustomElement::~CustomElement() = default;
 
-void CustomElement::load()
+bool CustomElement::isValid() const
+{
+    return mItem && mTimeStamp != -1;
+}
+
+void CustomElement::load(const QJsonObject &obj)
+{
+    mTimeStamp = obj["timestamp"_L1].toInteger(-1);
+    mItem = DeserializeUtils::deserializeItem(obj);
+}
+
+QJsonObject CustomElement::save() const
+{
+    QJsonObject obj = mItem->serialize(-1);
+    obj["timestamp"_L1] = mTimeStamp;
+    return obj;
+}
+
+qint64 CustomElement::timeStamp() const
+{
+    return mTimeStamp;
+}
+
+std::shared_ptr<Item> CustomElement::item() const
+{
+    return mItem;
+}
+
+void CustomElement::setItem(const std::shared_ptr<Item> &newItem)
 {
+    mItem = newItem;
 }
 
-void CustomElement::save()
+QDebug operator<<(QDebug d, const CustomElement &t)
 {
+    d.space() << "timestamp:" << t.timeStamp();
+    d.space() << "item:" << *t.item();
+    return d;
 }
diff --git a/src/gui/customelements/customelement.hpp b/src/gui/customelements/customelement.hpp
index 70ff95a6..1286c4d5 100644
--- a/src/gui/customelements/customelement.hpp
+++ b/src/gui/customelements/customelement.hpp
@@ -4,13 +4,30 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 #pragma once
-
-class CustomElement
+#include "item/item.hpp"
+#include "libdrawygui_export.h"
+#include <QString>
+#include <memory>
+class QDebug;
+class QJsonObject;
+class LIBDRAWYGUI_EXPORT CustomElement
 {
 public:
     CustomElement();
     ~CustomElement();
 
-    void load();
-    void save();
+    void load(const QJsonObject &obj);
+    [[nodiscard]] QJsonObject save() const;
+
+    [[nodiscard]] qint64 timeStamp() const;
+
+    [[nodiscard]] std::shared_ptr<Item> item() const;
+    void setItem(const std::shared_ptr<Item> &newItem);
+
+    [[nodiscard]] bool isValid() const;
+
+private:
+    qint64 mTimeStamp = -1;
+    std::shared_ptr<Item> mItem;
 };
+LIBDRAWYGUI_EXPORT QDebug operator<<(QDebug d, const CustomElement &t);
diff --git a/src/gui/customelements/customelementsmanager.cpp b/src/gui/customelements/customelementsmanager.cpp
index 96d5afbb..5ac3497f 100644
--- a/src/gui/customelements/customelementsmanager.cpp
+++ b/src/gui/customelements/customelementsmanager.cpp
@@ -5,6 +5,12 @@
  */
 
 #include "customelementsmanager.hpp"
+#include "customelements/customelementsutils.hpp"
+#include "drawy_gui_debug.h"
+#include "item/item.hpp"
+#include <QFile>
+#include <QJsonArray>
+#include <QJsonDocument>
 #include <QJsonObject>
 using namespace Qt::Literals::StringLiterals;
 CustomElementsManager::CustomElementsManager(QObject *parent)
@@ -22,14 +28,68 @@ CustomElementsManager *CustomElementsManager::self()
 
 void CustomElementsManager::loadCustomElements()
 {
-    // TODO
+    const auto path = CustomElementsUtils::customElementsFilePath();
+    if (QFile::exists(path)) {
+        QFile file(path);
+        if (!file.open(QFile::ReadOnly)) {
+            qCWarning(DRAWY_GUI_LOG) << "Impossible to open file: " << file.errorString();
+            return;
+        }
+        const QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
+        const QJsonObject obj = doc.object();
+        const int version = obj["version"_L1].toInt();
+        if (version != 1) {
+            qCWarning(DRAWY_GUI_LOG) << "Invalid version" << version;
+            return;
+        }
+        mCustomElements.clear();
+        const QJsonArray array = obj["librairies"_L1].toArray();
+        for (const auto &r : array) {
+            CustomElement e;
+            e.load(r.toObject());
+            if (e.isValid()) {
+                mCustomElements.append(e);
+            }
+        }
+    }
 }
 
 void CustomElementsManager::saveCustomElements()
 {
+    QJsonObject obj;
+    obj["version"_L1] = QString::number(1);
+    QJsonArray elementsObj;
+    for (const auto &element : std::as_const(mCustomElements)) {
+        elementsObj.append(element.save());
+    }
+    obj["librairies"_L1] = elementsObj;
+    const auto path = CustomElementsUtils::customElementsFilePath();
+    QFile file(path);
+    if (!file.open(QFile::WriteOnly)) {
+        qCWarning(DRAWY_GUI_LOG) << "Impossible to open file: " << file.errorString();
+        return;
+    }
+    const QJsonDocument doc{obj};
+    const auto data{doc.toJson(QJsonDocument::Compact)};
+
+    file.write(data);
+    file.close();
+}
+
+void CustomElementsManager::exportToFile(const QString &fileName)
+{
+    Q_UNUSED(fileName);
     // TODO
 }
 
+void CustomElementsManager::addItem(const std::shared_ptr<Item> &item)
+{
+    CustomElement element;
+    element.setItem(item);
+    mCustomElements.append(element);
+    saveCustomElements();
+}
+
 bool CustomElementsManager::isEmpty() const
 {
     return mCustomElements.isEmpty();
diff --git a/src/gui/customelements/customelementsmanager.hpp b/src/gui/customelements/customelementsmanager.hpp
index 59596e9c..4c28fad4 100644
--- a/src/gui/customelements/customelementsmanager.hpp
+++ b/src/gui/customelements/customelementsmanager.hpp
@@ -9,7 +9,9 @@
 #include "libdrawygui_export.h"
 #include <QList>
 #include <QObject>
+#include <memory>
 
+class Item;
 class LIBDRAWYGUI_EXPORT CustomElementsManager : public QObject
 {
     Q_OBJECT
@@ -22,6 +24,9 @@ public:
 
     [[nodiscard]] bool isEmpty() const;
 
+    void exportToFile(const QString &fileName);
+    void addItem(const std::shared_ptr<Item> &item);
+
 private:
     explicit CustomElementsManager(QObject *parent = nullptr);
     QList<CustomElement> mCustomElements;
diff --git a/src/gui/customelements/customelementsutils.cpp b/src/gui/customelements/customelementsutils.cpp
new file mode 100644
index 00000000..f6588463
--- /dev/null
+++ b/src/gui/customelements/customelementsutils.cpp
@@ -0,0 +1,15 @@
+/*
+ * SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+#include "customelementsutils.hpp"
+#include <QDir>
+#include <QStandardPaths>
+using namespace Qt::Literals::StringLiterals;
+QString CustomElementsUtils::customElementsFilePath()
+{
+    const QString customElementsPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + u"/custom-elements/"_s;
+    QDir().mkpath(customElementsPath);
+    return customElementsPath;
+}
diff --git a/src/gui/customelements/customelementsutils.hpp b/src/gui/customelements/customelementsutils.hpp
new file mode 100644
index 00000000..38e190ce
--- /dev/null
+++ b/src/gui/customelements/customelementsutils.hpp
@@ -0,0 +1,13 @@
+/*
+ * SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+#pragma once
+#include "libdrawygui_export.h"
+#include <QString>
+
+namespace CustomElementsUtils
+{
+[[nodiscard]] LIBDRAWYGUI_EXPORT QString customElementsFilePath();
+};
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.