summaryrefslogtreecommitdiff
path: root/gui/qjsonmodel.cpp
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2020-06-04 11:39:41 +0200
committerkali kaneko (leap communications) <kali@leap.se>2020-06-12 20:02:45 +0200
commit9b88f3ce47d090df167263ce2b4b6b430694da72 (patch)
tree3435b273857cc6bd26009767fa701673358d57cb /gui/qjsonmodel.cpp
parent719413cad922e1d34f2ea495bae0165cae53b22f (diff)
[feat] add qt gui
Signed-off-by: kali kaneko (leap communications) <kali@leap.se>
Diffstat (limited to 'gui/qjsonmodel.cpp')
-rw-r--r--gui/qjsonmodel.cpp419
1 files changed, 419 insertions, 0 deletions
diff --git a/gui/qjsonmodel.cpp b/gui/qjsonmodel.cpp
new file mode 100644
index 0000000..4e36eb8
--- /dev/null
+++ b/gui/qjsonmodel.cpp
@@ -0,0 +1,419 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2011 SCHUTZ Sacha
+ * Copyright (c) 2020 Kali Kaneko
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <QFile>
+#include <QDebug>
+#include <QFont>
+
+#include "qjsonmodel.h"
+
+
+QJsonTreeItem::QJsonTreeItem(QJsonTreeItem *parent)
+{
+ mParent = parent;
+}
+
+QJsonTreeItem::~QJsonTreeItem()
+{
+ qDeleteAll(mChilds);
+}
+
+void QJsonTreeItem::appendChild(QJsonTreeItem *item)
+{
+ mChilds.append(item);
+}
+
+QJsonTreeItem *QJsonTreeItem::child(int row)
+{
+ return mChilds.value(row);
+}
+
+QJsonTreeItem *QJsonTreeItem::parent()
+{
+ return mParent;
+}
+
+int QJsonTreeItem::childCount() const
+{
+ return mChilds.count();
+}
+
+int QJsonTreeItem::row() const
+{
+ if (mParent)
+ return mParent->mChilds.indexOf(const_cast<QJsonTreeItem*>(this));
+
+ return 0;
+}
+
+void QJsonTreeItem::setKey(const QString &key)
+{
+ mKey = key;
+}
+
+void QJsonTreeItem::setValue(const QString &value)
+{
+ mValue = value;
+}
+
+void QJsonTreeItem::setType(const QJsonValue::Type &type)
+{
+ mType = type;
+}
+
+QString QJsonTreeItem::key() const
+{
+ return mKey;
+}
+
+QString QJsonTreeItem::value() const
+{
+ return mValue;
+}
+
+QJsonValue::Type QJsonTreeItem::type() const
+{
+ return mType;
+}
+
+QJsonTreeItem* QJsonTreeItem::load(const QJsonValue& value, QJsonTreeItem* parent)
+{
+ QJsonTreeItem * rootItem = new QJsonTreeItem(parent);
+ rootItem->setKey("root");
+
+ if ( value.isObject())
+ {
+
+ //Get all QJsonValue childs
+ for (QString key : value.toObject().keys()){
+ QJsonValue v = value.toObject().value(key);
+ QJsonTreeItem * child = load(v,rootItem);
+ child->setKey(key);
+ child->setType(v.type());
+ rootItem->appendChild(child);
+
+ }
+
+ }
+
+ else if ( value.isArray())
+ {
+ //Get all QJsonValue childs
+ int index = 0;
+ for (QJsonValue v : value.toArray()){
+
+ QJsonTreeItem * child = load(v,rootItem);
+ child->setKey(QString::number(index));
+ child->setType(v.type());
+ rootItem->appendChild(child);
+ ++index;
+ }
+ }
+ else
+ {
+ rootItem->setValue(value.toVariant().toString());
+ rootItem->setType(value.type());
+ }
+
+ return rootItem;
+}
+
+//=========================================================================
+
+QJsonModel::QJsonModel(QObject *parent)
+ : QAbstractItemModel(parent)
+ , mRootItem{new QJsonTreeItem}
+{
+ mHeaders.append("key");
+ mHeaders.append("value");
+}
+
+QJsonModel::QJsonModel(const QString& fileName, QObject *parent)
+ : QAbstractItemModel(parent)
+ , mRootItem{new QJsonTreeItem}
+{
+ mHeaders.append("key");
+ mHeaders.append("value");
+ load(fileName);
+}
+
+QJsonModel::QJsonModel(QIODevice * device, QObject *parent)
+ : QAbstractItemModel(parent)
+ , mRootItem{new QJsonTreeItem}
+{
+ mHeaders.append("key");
+ mHeaders.append("value");
+ load(device);
+}
+
+QJsonModel::QJsonModel(const QByteArray& json, QObject *parent)
+ : QAbstractItemModel(parent)
+ , mRootItem{new QJsonTreeItem}
+{
+ mHeaders.append("key");
+ mHeaders.append("value");
+ loadJson(json);
+}
+
+QJsonModel::~QJsonModel()
+{
+ delete mRootItem;
+}
+
+bool QJsonModel::load(const QString &fileName)
+{
+ QFile file(fileName);
+ bool success = false;
+ if (file.open(QIODevice::ReadOnly)) {
+ success = load(&file);
+ file.close();
+ }
+ else success = false;
+
+ return success;
+}
+
+bool QJsonModel::load(QIODevice *device)
+{
+ return loadJson(device->readAll());
+}
+
+bool QJsonModel::loadJson(const QByteArray &json)
+{
+ auto const& jdoc = QJsonDocument::fromJson(json);
+
+ if (!jdoc.isNull())
+ {
+ beginResetModel();
+
+ delete mRootItem;
+
+ if (jdoc.isArray()) {
+ mRootItem = QJsonTreeItem::load(QJsonValue(jdoc.array()));
+ mRootItem->setType(QJsonValue::Array);
+ } else {
+ mRootItem = QJsonTreeItem::load(QJsonValue(jdoc.object()));
+ mRootItem->setType(QJsonValue::Object);
+ }
+ endResetModel();
+
+ // ???
+ emit dataChanged(QModelIndex(), QModelIndex(), {});
+ return true;
+ }
+
+ qDebug()<<Q_FUNC_INFO<<"cannot load json";
+ return false;
+}
+
+
+QVariant QJsonModel::data(const QModelIndex &index, int role) const
+{
+
+ if (!index.isValid())
+ return QVariant();
+
+
+ QJsonTreeItem *item = static_cast<QJsonTreeItem*>(index.internalPointer());
+
+
+ switch (role) {
+ case Roles::KeyRole:
+ return item->key();
+ case Roles::ValueRole:
+ return item->value();
+ case Qt::DisplayRole:
+ {
+ if (index.column() == 0)
+ return QString("%1").arg(item->key());
+ else if (index.column() == 1)
+ return QString("%1").arg(item->value());
+ else
+ return QString("");
+
+ }
+ case Qt::EditRole:
+ {
+ if (index.column() == 1)
+ return QString("%1").arg(item->value());
+ else
+ return QString("");
+ }
+ default:
+ return QVariant();
+ }
+ return QVariant();
+
+}
+
+bool QJsonModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ int col = index.column();
+ if (Qt::EditRole == role) {
+ if (col == 1) {
+ QJsonTreeItem *item = static_cast<QJsonTreeItem*>(index.internalPointer());
+ item->setValue(value.toString());
+ emit dataChanged(index, index, {Qt::EditRole});
+ return true;
+ }
+ }
+
+ return false;
+}
+
+QVariant QJsonModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ if (orientation == Qt::Horizontal) {
+
+ return mHeaders.value(section);
+ }
+ else
+ return QVariant();
+}
+
+QModelIndex QJsonModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if (!hasIndex(row, column, parent))
+ return QModelIndex();
+
+ QJsonTreeItem *parentItem;
+
+ if (!parent.isValid())
+ parentItem = mRootItem;
+ else
+ parentItem = static_cast<QJsonTreeItem*>(parent.internalPointer());
+
+ QJsonTreeItem *childItem = parentItem->child(row);
+ if (childItem)
+ return createIndex(row, column, childItem);
+ else
+ return QModelIndex();
+}
+
+QModelIndex QJsonModel::parent(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return QModelIndex();
+
+ QJsonTreeItem *childItem = static_cast<QJsonTreeItem*>(index.internalPointer());
+ QJsonTreeItem *parentItem = childItem->parent();
+
+ if (parentItem == mRootItem)
+ return QModelIndex();
+
+ return createIndex(parentItem->row(), 0, parentItem);
+}
+
+int QJsonModel::rowCount(const QModelIndex &parent) const
+{
+ QJsonTreeItem *parentItem;
+ if (parent.column() > 0)
+ return 0;
+
+ if (!parent.isValid())
+ parentItem = mRootItem;
+ else
+ parentItem = static_cast<QJsonTreeItem*>(parent.internalPointer());
+
+ return parentItem->childCount();
+}
+
+int QJsonModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent)
+ return 2;
+}
+
+Qt::ItemFlags QJsonModel::flags(const QModelIndex &index) const
+{
+ int col = index.column();
+ auto item = static_cast<QJsonTreeItem*>(index.internalPointer());
+
+ auto isArray = QJsonValue::Array == item->type();
+ auto isObject = QJsonValue::Object == item->type();
+
+ if ((col == 1) && !(isArray || isObject)) {
+ return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
+ } else {
+ return QAbstractItemModel::flags(index);
+ }
+}
+
+QJsonDocument QJsonModel::json() const
+{
+
+ auto v = genJson(mRootItem);
+ QJsonDocument doc;
+
+ if (v.isObject()) {
+ doc = QJsonDocument(v.toObject());
+ } else {
+ doc = QJsonDocument(v.toArray());
+ }
+
+ return doc;
+}
+
+QJsonValue QJsonModel::genJson(QJsonTreeItem * item) const
+{
+ auto type = item->type();
+ int nchild = item->childCount();
+
+ if (QJsonValue::Object == type) {
+ QJsonObject jo;
+ for (int i = 0; i < nchild; ++i) {
+ auto ch = item->child(i);
+ auto key = ch->key();
+ jo.insert(key, genJson(ch));
+ }
+ return jo;
+ } else if (QJsonValue::Array == type) {
+ QJsonArray arr;
+ for (int i = 0; i < nchild; ++i) {
+ auto ch = item->child(i);
+ arr.append(genJson(ch));
+ }
+ return arr;
+ } else {
+ QJsonValue va(item->value());
+ return va;
+ }
+}
+
+QHash<int, QByteArray> QJsonModel::roleNames() const
+{
+ QHash<int, QByteArray> roles;
+ roles[Roles::KeyRole] = "key";
+ roles[Roles::ValueRole] = "value";
+ return roles;
+}
+
+QByteArray QJsonModel::getJson()
+{
+ return ((QJsonDocument)(this->json())).toJson();
+}