From a418d2a6f52bc2d68fcba7a5670c00a6c535b7df Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Mon, 30 Aug 2021 15:07:12 +0200
Subject: [PATCH] UI: Clean a bit the property model

---
 src/UI/PropertyModel.cc | 170 ++++++++++++++++------------------------
 src/UI/PropertyModel.hh |  21 +++--
 2 files changed, 78 insertions(+), 113 deletions(-)

diff --git a/src/UI/PropertyModel.cc b/src/UI/PropertyModel.cc
index fc4d3ea7..c0068cbd 100644
--- a/src/UI/PropertyModel.cc
+++ b/src/UI/PropertyModel.cc
@@ -33,10 +33,11 @@ PropertyModel::Item::getChildCount() const noexcept
     return childs.count();
 }
 
+// Can't be const because of indexOf...
 int
-PropertyModel::Item::getRow() const noexcept
+PropertyModel::Item::getRow() noexcept
 {
-    return parent ? parent->childs.indexOf(const_cast<Item *>(this)) : 0;
+    return parent ? parent->childs.indexOf(this) : 0;
 }
 
 void
@@ -81,6 +82,55 @@ PropertyModel::Item::getChilds() const noexcept
     return childs;
 }
 
+bool
+PropertyModel::Item::isOrderedJsonObject(const QJsonValue &value) noexcept
+{
+    if (value.isArray()) {
+        for (const QJsonValue v : value.toArray()) {
+            if (!v.isObject() || v.toObject().count() != 1)
+                return false;
+        }
+        return true;
+    }
+    return false;
+}
+
+PropertyModel::Item *
+PropertyModel::Item::createChild(Item *root, QJsonObject::ConstIterator const &it) noexcept
+{
+    const QString key  = it.key();
+    const QJsonValue v = it.value();
+    Item *child        = fromJson(v, root);
+    child->setKey(key);
+    child->setType(v.type());
+    return child;
+}
+
+PropertyModel::Item *
+PropertyModel::Item::createChild(Item *root, QJsonArray const &singleElemArray) noexcept
+{
+    Q_ASSERT(singleElemArray.count() == 1);
+
+    const QJsonValue v   = singleElemArray.at(0);
+    const QString key    = v.toObject().keys().at(0);
+    const QJsonValue val = v.toObject().value(key);
+
+    Item *child = fromJson(val, root);
+    child->setKey(key);
+    child->setType(val.type());
+
+    return child;
+}
+
+PropertyModel::Item *
+PropertyModel::Item::createChild(Item *root, int pos, QJsonValue const &val) noexcept
+{
+    Item *child = fromJson(val, root);
+    child->setKey(QString::number(pos));
+    child->setType(val.type());
+    return child;
+}
+
 PropertyModel::Item *
 PropertyModel::Item::fromJson(const QJsonValue &value, PropertyModel::Item *parent)
 {
@@ -88,45 +138,19 @@ PropertyModel::Item::fromJson(const QJsonValue &value, PropertyModel::Item *pare
     root->setKey("root");
 
     if (value.isObject()) {
-        for (const QString &key : value.toObject().keys()) {
-            QJsonValue v = value.toObject().value(key);
-            Item *child  = fromJson(v, root);
-            child->setKey(key);
-            child->setType(v.type());
-            root->appendChild(child);
-        }
-
+        const QJsonObject objValue = value.toObject();
+        const auto end             = objValue.constEnd();
+        for (auto it = objValue.constBegin(); it != end; ++it)
+            root->appendChild(createChild(root, it));
     }
 
-    else if (value.isArray()) {
-        // With arrays with one object per index, treat them as ordered QJsonObject
-        bool isOrderedQJsonObject = true;
-        for (const QJsonValue v : value.toArray()) {
-            if (!v.isObject() || v.toObject().count() != 1)
-                isOrderedQJsonObject = false;
-        }
-
-        if (isOrderedQJsonObject) {
-            for (const QJsonValue v : value.toArray()) {
-                // `count == 1` was already checked
-                const QString key    = v.toObject().keys().at(0);
-                const QJsonValue val = v.toObject().value(key);
-
-                Item *child = fromJson(val, root);
-                child->setKey(key);
-                child->setType(val.type());
-                root->appendChild(child);
-            }
-        }
+    else if (isOrderedJsonObject(value))
+        root->appendChild(createChild(root, value.toArray()));
 
-        else {
-            for (int index = 0; const QJsonValue v : value.toArray()) {
-                Item *child = fromJson(v, root);
-                child->setKey(QString::number(index));
-                child->setType(v.type());
-                root->appendChild(child);
-                ++index;
-            }
+    else if (value.isArray()) {
+        for (int index = 0; const QJsonValue v : value.toArray()) {
+            root->appendChild(createChild(root, index, v));
+            ++index;
         }
     }
 
@@ -141,18 +165,14 @@ PropertyModel::Item::fromJson(const QJsonValue &value, PropertyModel::Item *pare
 PropertyModel::PropertyModel(QObject *parent) noexcept
     : QAbstractItemModel(parent)
 {
-    headers.append("key");
-    headers.append("value");
+    headers.append(QStringLiteral("Key"));
+    headers.append(QStringLiteral("Value"));
 }
 
-PropertyModel::PropertyModel(const QJsonDocument &properties, QObject *parent) noexcept
+PropertyModel::PropertyModel(const QJsonDocument &properties, QObject *parent)
     : PropertyModel(parent)
 {
-    try {
-        loadJson(properties);
-    } catch (const std::runtime_error &e) {
-        qCritical() << "Failed to create the property model object:" << e.what();
-    }
+    loadJson(properties);
 }
 
 void
@@ -194,28 +214,12 @@ PropertyModel::data(const QModelIndex &index, int role) const noexcept
             return QString("%1").arg(item->getValue());
     }
 
-    else if (Qt::EditRole == role) {
-        if (index.column() == 1) {
-            return QString("%1").arg(item->getValue());
-        }
-    }
-
     return QVariant();
 }
 
 bool
-PropertyModel::setData(const QModelIndex &index, const QVariant &value, int role) noexcept
+PropertyModel::setData(const QModelIndex &, const QVariant &, int) noexcept
 {
-    const int col = index.column();
-    if (Qt::EditRole == role) {
-        if (col == 1) {
-            Item *item = static_cast<Item *>(index.internalPointer());
-            item->setValue(value.toString());
-            emit dataChanged(index, index, { Qt::EditRole });
-            return true;
-        }
-    }
-
     return false;
 }
 
@@ -271,7 +275,7 @@ PropertyModel::rowCount(const QModelIndex &parent) const noexcept
 }
 
 int
-PropertyModel::columnCount(const QModelIndex & /* parent */) const noexcept
+PropertyModel::columnCount(const QModelIndex &) const noexcept
 {
     return 2;
 }
@@ -281,41 +285,3 @@ PropertyModel::flags(const QModelIndex &index) const noexcept
 {
     return QAbstractItemModel::flags(index);
 }
-
-// Get the json stored inside the model
-QJsonDocument
-PropertyModel::getJson() const noexcept
-{
-    QJsonValue v = generateJson(root.get());
-    return v.isObject() ? QJsonDocument(v.toObject()) : QJsonDocument(v.toArray());
-}
-
-// Get the json stored inside the model by calculating it
-QJsonValue
-PropertyModel::generateJson(PropertyModel::Item *item) const noexcept
-{
-    if (QJsonValue::Type type = item->getType(); QJsonValue::Object == type) {
-        QJsonObject jo;
-        for (const auto &child : item->getChilds())
-            jo.insert(child->getKey(), generateJson(child));
-        return jo;
-    }
-
-    else if (QJsonValue::Array == type) {
-        QJsonArray arr;
-        for (const auto &child : item->getChilds())
-            arr.append(generateJson(child));
-        return arr;
-    }
-
-    else {
-        QJsonValue va(item->getValue());
-        return va;
-    }
-}
-
-QString
-PropertyModel::getName() const noexcept
-{
-    return root ? "Property for " + root->getKey() : "Property view";
-}
diff --git a/src/UI/PropertyModel.hh b/src/UI/PropertyModel.hh
index 3053d7de..2a4d1815 100644
--- a/src/UI/PropertyModel.hh
+++ b/src/UI/PropertyModel.hh
@@ -33,7 +33,7 @@ private:
         const QVector<Item *> getChilds() const noexcept;
         Item *getParent() const noexcept;
         int getChildCount() const noexcept;
-        int getRow() const noexcept;
+        int getRow() noexcept;
         void setKey(const QString &) noexcept;
         void setValue(const QString &) noexcept;
         void setType(const QJsonValue::Type &) noexcept;
@@ -43,8 +43,12 @@ private:
 
         static Item *fromJson(const QJsonValue &, Item *parent = nullptr);
 
-    protected:
     private:
+        static bool isOrderedJsonObject(QJsonValue const &) noexcept;
+        static Item *createChild(Item *root, QJsonObject::ConstIterator const &) noexcept;
+        static Item *createChild(Item *root, QJsonArray const &) noexcept;
+        static Item *createChild(Item *root, int pos, QJsonValue const &) noexcept;
+
         QString key{};
         QString value{};
         QJsonValue::Type type{ QJsonValue::Null };
@@ -54,9 +58,8 @@ private:
 
 public:
     explicit PropertyModel(QObject *parent = nullptr) noexcept;
-    explicit PropertyModel(const QJsonDocument &, QObject *parent = nullptr) noexcept;
-    explicit PropertyModel(const PropertyConstViewable auto &object,
-                           QObject *parent = nullptr) noexcept
+    explicit PropertyModel(const QJsonDocument &, QObject *parent = nullptr);
+    explicit PropertyModel(const PropertyConstViewable auto &object, QObject *parent = nullptr)
         : PropertyModel(object.getProperties(), parent)
     {
         // With concepts it seems that the function must be implemented where
@@ -64,8 +67,6 @@ public:
         root->setKey(object.getElementName());
     }
 
-    void loadJson(const QJsonDocument &json);
-
     QVariant data(const QModelIndex &, int role) const noexcept override;
     bool setData(const QModelIndex &, const QVariant &v, int r = Qt::EditRole) noexcept override;
 
@@ -78,12 +79,10 @@ public:
     int columnCount(const QModelIndex &parent = QModelIndex()) const noexcept override;
 
     Qt::ItemFlags flags(const QModelIndex &) const noexcept override;
-    QJsonDocument getJson() const noexcept;
-
-    QString getName() const noexcept;
 
 private:
-    QJsonValue generateJson(Item *) const noexcept;
+    void loadJson(const QJsonDocument &json);
+
     std::unique_ptr<Item> root{ nullptr };
     QStringList headers{};
 };
-- 
GitLab