[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();
+};