File indexing completed on 2024-05-12 04:39:43
0001 /* 0002 SPDX-FileCopyrightText: 2013 Vlas Puhov <vlas.puhov@mail.ru> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "modelsmanager.h" 0008 0009 #include <QStandardItemModel> 0010 #include <QAbstractItemView> 0011 #include <QSharedPointer> 0012 0013 #include <KSharedConfig> 0014 0015 namespace KDevMI { 0016 0017 struct Model { 0018 Model(); 0019 Model(const QString& name, QSharedPointer<QStandardItemModel> model, QAbstractItemView* view); 0020 bool operator==(const Model& m) const; 0021 0022 QString name; 0023 QSharedPointer<QStandardItemModel> model; 0024 QAbstractItemView* view = nullptr; 0025 }; 0026 0027 class Models 0028 { 0029 public: 0030 QStandardItemModel* addModel(const Model& m); 0031 0032 void clear(); 0033 0034 bool contains(const QString& name) const; 0035 bool contains(QAbstractItemView* view) const; 0036 bool contains(QStandardItemModel* model) const; 0037 0038 QString nameForView(QAbstractItemView* view) const; 0039 0040 ///Returns registered model for @p name, 0 if not registered. 0041 QStandardItemModel* modelForName(const QString& name) const; 0042 ///Returns registered model for @p view, 0 if not registered. 0043 QStandardItemModel* modelForView(QAbstractItemView* view) const; 0044 0045 private: 0046 ///All models 0047 QVector<Model> m_models; 0048 }; 0049 0050 } // end of namespace KDevMI 0051 0052 Q_DECLARE_TYPEINFO(KDevMI::Model, Q_MOVABLE_TYPE); 0053 0054 using namespace KDevMI; 0055 0056 ModelsManager::ModelsManager(QObject* parent) 0057 : QObject(parent) 0058 , m_models(new Models) 0059 , m_config(KSharedConfig::openConfig()->group("Register models")) 0060 {} 0061 0062 ModelsManager::~ModelsManager() {} 0063 0064 QString ModelsManager::addView(QAbstractItemView* view) 0065 { 0066 if (m_models->contains(view)) { 0067 return m_models->nameForView(view); 0068 } 0069 0070 Q_ASSERT(m_controller); 0071 0072 QString name; 0073 const auto namesOfRegisterGroups = m_controller->namesOfRegisterGroups(); 0074 for (const GroupsName& group : namesOfRegisterGroups) { 0075 if (!m_models->contains(group.name())) { 0076 QStandardItemModel* m = m_models->addModel(Model(group.name(), QSharedPointer<QStandardItemModel>(new QStandardItemModel()), view)); 0077 view->setModel(m); 0078 0079 if (group.type() == flag) { 0080 connect(view, &QAbstractItemView::doubleClicked, this, &ModelsManager::flagChanged, Qt::UniqueConnection); 0081 } 0082 0083 name = group.name(); 0084 load(group); 0085 break; 0086 } 0087 } 0088 0089 return name; 0090 } 0091 0092 void ModelsManager::updateModelForGroup(const RegistersGroup& group) 0093 { 0094 QStandardItemModel* model = m_models->modelForName(group.groupName.name()); 0095 0096 if (!model) { 0097 return; 0098 } 0099 0100 disconnect(model, &QStandardItemModel::itemChanged, this, &ModelsManager::itemChanged); 0101 0102 model->setRowCount(group.registers.count()); 0103 model->setColumnCount(group.registers.first().value.split(QLatin1Char(' ')).size() + 1); 0104 0105 //set names and values separately as names don't change so often. 0106 if (!model->item(0, 0)) { 0107 for (int row = 0; row < group.registers.count(); row++) { 0108 const Register& r = group.registers[row]; 0109 auto* n = new QStandardItem(r.name); 0110 n->setFlags(Qt::ItemIsEnabled); 0111 model->setItem(row, 0, n); 0112 } 0113 } 0114 0115 for (int row = 0; row < group.registers.count(); row++) { 0116 const Register& r = group.registers[row]; 0117 0118 const QStringList& values = r.value.split(QLatin1Char(' ')); 0119 0120 //binary format workaround. 0121 Format currentFormat = formats(group.groupName.name()).first(); 0122 Mode currentMode = modes(group.groupName.name()).first(); 0123 QString prefix; 0124 if (currentFormat == Binary && ((currentMode < v4_float || currentMode > v2_double) && 0125 (currentMode < f32 || currentMode > f64) && group.groupName.type() != floatPoint)) { 0126 prefix = QStringLiteral("0b"); 0127 } 0128 0129 for (int column = 0; column < values.count(); column ++) { 0130 auto* v = new QStandardItem(prefix + values[column]); 0131 if (group.groupName.type() == flag) { 0132 v->setFlags(Qt::ItemIsEnabled); 0133 } 0134 model->setItem(row, column + 1, v); 0135 } 0136 } 0137 0138 connect(model, &QStandardItemModel::itemChanged, this, &ModelsManager::itemChanged); 0139 } 0140 0141 void ModelsManager::flagChanged(const QModelIndex& idx) 0142 { 0143 auto* view = static_cast<QAbstractItemView*>(sender()); 0144 int row = idx.row(); 0145 0146 QStandardItemModel* model = m_models->modelForView(view); 0147 0148 QStandardItem* item = model->item(row, 0); 0149 0150 Register r; 0151 r.name = item->text(); 0152 r.value = model->data(idx).toString(); 0153 emit registerChanged(r); 0154 } 0155 0156 QStandardItemModel* Models::addModel(const Model& m) 0157 { 0158 if (!contains(m.name) && !contains(m.view) && !contains(m.model.data())) { 0159 m_models.append(m); 0160 return m.model.data(); 0161 } 0162 return nullptr; 0163 } 0164 0165 bool Models::contains(const QString& name) const 0166 { 0167 for (const Model &m : m_models) { 0168 if (m.name == name) { 0169 return true; 0170 } 0171 } 0172 return false; 0173 } 0174 0175 bool Models::contains(QAbstractItemView* view) const 0176 { 0177 for (const Model& m : m_models) { 0178 if (m.view == view) { 0179 return true; 0180 } 0181 } 0182 return false; 0183 } 0184 0185 bool Models::contains(QStandardItemModel* model) const 0186 { 0187 for (const Model& m : m_models) { 0188 if (m.model.data() == model) { 0189 return true; 0190 } 0191 } 0192 return false; 0193 } 0194 0195 QStandardItemModel* Models::modelForName(const QString& name) const 0196 { 0197 for (const Model& m : m_models) { 0198 if (m.name == name) { 0199 return m.model.data(); 0200 } 0201 } 0202 return nullptr; 0203 } 0204 0205 QStandardItemModel* Models::modelForView(QAbstractItemView* view) const 0206 { 0207 for (const Model& m : m_models) { 0208 if (m.view == view) { 0209 return m.model.data(); 0210 } 0211 } 0212 return nullptr; 0213 } 0214 0215 void ModelsManager::itemChanged(QStandardItem* i) 0216 { 0217 auto* model = static_cast<QStandardItemModel*>(sender()); 0218 0219 int row = i->row(); 0220 0221 Register r; 0222 r.name = model->item(row, 0)->text(); 0223 for (int i = 1; i < model->columnCount(); i++) { 0224 r.value += model->item(row, i)->text() + QLatin1Char(' '); 0225 } 0226 r.value = r.value.trimmed(); 0227 emit registerChanged(r); 0228 } 0229 0230 QString Models::nameForView(QAbstractItemView* view) const 0231 { 0232 for (const Model& m : m_models) { 0233 if (m.view == view) { 0234 return m.name; 0235 } 0236 } 0237 return QString(); 0238 } 0239 0240 void ModelsManager::setController(IRegisterController* rc) 0241 { 0242 m_controller = rc; 0243 if (!m_controller) { 0244 m_models->clear(); 0245 } else { 0246 connect(this, &ModelsManager::registerChanged, m_controller, &IRegisterController::setRegisterValue); 0247 0248 connect(m_controller, &IRegisterController::registersChanged, this, &ModelsManager::updateModelForGroup); 0249 } 0250 } 0251 0252 Model::Model() {} 0253 0254 Model::Model(const QString& name, QSharedPointer<QStandardItemModel> model, QAbstractItemView* view) 0255 : name(name), model(model), view(view) {} 0256 0257 bool Model::operator==(const Model& m) const 0258 { 0259 return m.model == model && m.view == view && m.name == name; 0260 } 0261 0262 void ModelsManager::updateRegisters(const QString& group) 0263 { 0264 Q_ASSERT(m_controller); 0265 if (group.isEmpty()) { 0266 m_controller->updateRegisters(GroupsName()); 0267 } else { 0268 const auto namesOfRegisterGroups = m_controller->namesOfRegisterGroups(); 0269 for (const GroupsName& g : namesOfRegisterGroups) { 0270 if (g.name() == group) { 0271 m_controller->updateRegisters(g); 0272 break; 0273 } 0274 } 0275 } 0276 } 0277 0278 void Models::clear() 0279 { 0280 m_models.clear(); 0281 } 0282 0283 void ModelsManager::setFormat(const QString& group, Format format) 0284 { 0285 const auto namesOfRegisterGroups = m_controller->namesOfRegisterGroups(); 0286 for (const GroupsName& g : namesOfRegisterGroups) { 0287 if (g.name() == group) { 0288 m_controller->setFormat(format, g); 0289 save(g); 0290 break; 0291 } 0292 } 0293 } 0294 0295 QVector<Format> ModelsManager::formats(const QString& group) const 0296 { 0297 QVector<Format> formats; formats << Raw; 0298 0299 const auto namesOfRegisterGroups = m_controller->namesOfRegisterGroups(); 0300 for (const GroupsName& g : namesOfRegisterGroups) { 0301 if (g.name() == group) { 0302 formats = m_controller->formats(g); 0303 break; 0304 } 0305 } 0306 0307 return formats; 0308 } 0309 0310 void ModelsManager::save(const GroupsName& g) 0311 { 0312 KConfigGroup group = m_config.group(g.name()); 0313 group.writeEntry("format", static_cast<int>(m_controller->formats(g).first())); 0314 group.writeEntry("mode", static_cast<int>(m_controller->modes(g).first())); 0315 } 0316 0317 void ModelsManager::load(const GroupsName& g) 0318 { 0319 KConfigGroup group = m_config.group(g.name()); 0320 0321 Format format = static_cast<Format>(group.readEntry("format", static_cast<int>(m_controller->formats(g).first()))); 0322 setFormat(g.name(), format); 0323 0324 Mode mode = static_cast<Mode>(group.readEntry("mode", static_cast<int>(m_controller->modes(g).first()))); 0325 setMode(g.name(), mode); 0326 } 0327 0328 QVector< Mode > ModelsManager::modes(const QString& group) const 0329 { 0330 QVector<Mode> modes; 0331 0332 const auto namesOfRegisterGroups = m_controller->namesOfRegisterGroups(); 0333 for (const GroupsName& g : namesOfRegisterGroups) { 0334 if (g.name() == group) { 0335 modes = m_controller->modes(g); 0336 break; 0337 } 0338 } 0339 0340 return modes; 0341 } 0342 0343 void ModelsManager::setMode(const QString& group, Mode mode) 0344 { 0345 const auto namesOfRegisterGroups = m_controller->namesOfRegisterGroups(); 0346 for (const GroupsName& g : namesOfRegisterGroups) { 0347 if (g.name() == group) { 0348 m_controller->setMode(mode, g); 0349 save(g); 0350 break; 0351 } 0352 } 0353 } 0354 0355 #include "moc_modelsmanager.cpp"