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"