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"