File indexing completed on 2024-12-15 03:45:01

0001 /*
0002     SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: MIT
0005 */
0006 
0007 #include "schemamodel.h"
0008 
0009 #include <core/schemaentryelement.h>
0010 #include <core/util.h>
0011 
0012 #include <limits>
0013 
0014 using namespace KUserFeedback::Console;
0015 
0016 static const auto TOPLEVEL = std::numeric_limits<quintptr>::max();
0017 
0018 SchemaModel::SchemaModel(QObject *parent) :
0019     QAbstractItemModel(parent)
0020 {
0021 }
0022 
0023 SchemaModel::~SchemaModel() = default;
0024 
0025 Product SchemaModel::product() const
0026 {
0027     return m_product;
0028 }
0029 
0030 void SchemaModel::setProduct(const Product &product)
0031 {
0032     beginResetModel();
0033     m_product = product;
0034     endResetModel();
0035 }
0036 
0037 void SchemaModel::addEntry(const QString &name)
0038 {
0039     SchemaEntry entry;
0040     entry.setName(name);
0041     addEntry(entry);
0042 }
0043 
0044 void SchemaModel::addEntry(const SchemaEntry &entry)
0045 {
0046     auto schema = m_product.schema();
0047     beginInsertRows(QModelIndex(), schema.size(), schema.size());
0048     schema.push_back(entry);
0049     m_product.setSchema(schema);
0050     endInsertRows();
0051 }
0052 
0053 void SchemaModel::addElement(const QModelIndex& parent, const QString& name)
0054 {
0055     Q_ASSERT(parent.isValid());
0056     auto schema = m_product.schema();
0057     auto &entry = schema[parent.row()];
0058     auto elements = entry.elements();
0059     SchemaEntryElement e;
0060     e.setName(name);
0061     beginInsertRows(parent, elements.size(), elements.size());
0062     elements.push_back(e);
0063     entry.setElements(elements);
0064     m_product.setSchema(schema);
0065     endInsertRows();
0066 }
0067 
0068 void SchemaModel::deleteRow(const QModelIndex &idx)
0069 {
0070     if (!idx.isValid())
0071         return;
0072 
0073     auto schema = m_product.schema();
0074     beginRemoveRows(idx.parent(), idx.row(), idx.row());
0075     if (idx.internalId() == TOPLEVEL) {
0076         schema.removeAt(idx.row());
0077     } else {
0078         auto &entry = schema[idx.internalId()];
0079         auto elements = entry.elements();
0080         elements.removeAt(idx.row());
0081         entry.setElements(elements);
0082     }
0083     m_product.setSchema(schema);
0084     endRemoveRows();
0085 }
0086 
0087 int SchemaModel::columnCount(const QModelIndex &parent) const
0088 {
0089     Q_UNUSED(parent);
0090     return 2;
0091 }
0092 
0093 int SchemaModel::rowCount(const QModelIndex& parent) const
0094 {
0095     if (!parent.isValid())
0096         return m_product.schema().size();
0097     if (parent.internalId() == TOPLEVEL && parent.column() == 0)
0098         return m_product.schema().at(parent.row()).elements().size();
0099     return 0;
0100 }
0101 
0102 QVariant SchemaModel::data(const QModelIndex& index, int role) const
0103 {
0104     if (!index.isValid())
0105         return {};
0106 
0107     if (index.internalId() == TOPLEVEL) {
0108         const auto entry = m_product.schema().at(index.row());
0109         switch (index.column()) {
0110             case 0:
0111                 if (role == Qt::DisplayRole || role == Qt::EditRole)
0112                     return entry.name();
0113                 break;
0114             case 1:
0115                 if (role == Qt::DisplayRole)
0116                     return Util::enumToString(entry.dataType());
0117                 else if (role == Qt::EditRole)
0118                     return QVariant::fromValue(entry.dataType());
0119                 break;
0120         }
0121     } else {
0122         const auto entry = m_product.schema().at(index.internalId());
0123         const auto elem = entry.elements().at(index.row());
0124         switch (index.column()) {
0125             case 0:
0126                 if (role == Qt::DisplayRole || role == Qt::EditRole)
0127                     return elem.name();
0128                 break;
0129             case 1:
0130                 if (role == Qt::DisplayRole)
0131                     return Util::enumToString(elem.type());
0132                 else if (role == Qt::EditRole)
0133                     return QVariant::fromValue(elem.type());
0134                 break;
0135         }
0136     }
0137 
0138     return {};
0139 }
0140 
0141 QVariant SchemaModel::headerData(int section, Qt::Orientation orientation, int role) const
0142 {
0143     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
0144         switch (section) {
0145             case 0: return tr("Name");
0146             case 1: return tr("Type");
0147         }
0148     }
0149     return QAbstractItemModel::headerData(section, orientation, role);
0150 }
0151 
0152 Qt::ItemFlags SchemaModel::flags(const QModelIndex &index) const
0153 {
0154     const auto baseFlags = QAbstractItemModel::flags(index);
0155     if (!index.isValid())
0156         return baseFlags;
0157     return baseFlags | Qt::ItemIsEditable;
0158 }
0159 
0160 bool SchemaModel::setData(const QModelIndex &index, const QVariant &value, int role)
0161 {
0162     if (role != Qt::EditRole)
0163         return false;
0164 
0165     auto schema = m_product.schema();
0166 
0167     if (index.internalId() == TOPLEVEL) {
0168         auto &entry = schema[index.row()];
0169         switch (index.column()) {
0170             case 0:
0171                 entry.setName(value.toString());
0172                 break;
0173             case 1:
0174                 entry.setDataType(value.value<SchemaEntry::DataType>());
0175                 break;
0176         }
0177     } else {
0178         auto &entry = schema[index.internalId()];
0179         auto elems = entry.elements();
0180         auto &elem = elems[index.row()];
0181         switch (index.column()) {
0182             case 0:
0183                 elem.setName(value.toString());
0184                 break;
0185             case 1:
0186                 elem.setType(value.value<SchemaEntryElement::Type>());
0187                 break;
0188         }
0189         entry.setElements(elems);
0190     }
0191 
0192     m_product.setSchema(schema);
0193 
0194     Q_EMIT dataChanged(index, index);
0195     return false;
0196 }
0197 
0198 QModelIndex SchemaModel::index(int row, int column, const QModelIndex &parent) const
0199 {
0200     if (!hasIndex(row, column, parent))
0201         return {};
0202     if (!parent.isValid())
0203         return createIndex(row, column, TOPLEVEL);
0204     if (parent.internalId() == TOPLEVEL)
0205         return createIndex(row, column, parent.row());
0206     return {};
0207 }
0208 
0209 QModelIndex SchemaModel::parent(const QModelIndex &index) const
0210 {
0211     if (!index.isValid() || index.internalId() == TOPLEVEL)
0212         return {};
0213     return createIndex(index.internalId(), 0, TOPLEVEL);
0214 }
0215 
0216 #include "moc_schemamodel.cpp"