File indexing completed on 2024-12-29 05:20:08

0001 /*
0002  * Copyright 2019 Patrick José Pereira <patrickjp@kde.org>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Lesser General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2.1 of the License, or (at your option) version 3, or any
0008  * later version accepted by the membership of KDE e.V. (or its
0009  * successor approved by the membership of KDE e.V.), which shall
0010  * act as a proxy defined in Section 6 of version 3 of the license.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Lesser General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Lesser General Public
0018  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0019  */
0020 
0021 #include "parametermodel.h"
0022 
0023 #include <QDebug>
0024 #include <QMetaEnum>
0025 
0026 ParameterModel::ParameterModel(QObject *parent)
0027     : QAbstractListModel(parent)
0028 {
0029     initializeRoleNames();
0030 
0031     // Initialize vector.
0032     for (const auto &key : m_roleNames.keys()) {
0033         m_vectors.insert(key, {});
0034     }
0035 
0036     // Allow the usage of this class in different threads.
0037     connect(this, &ParameterModel::update, this, &ParameterModel::doUpdate);
0038 }
0039 
0040 void ParameterModel::initializeRoleNames()
0041 {
0042     Q_ASSERT(m_roleNames.empty());
0043 
0044     auto desCapitalize = [](const char *input) -> QByteArray {
0045         QByteArray array(input);
0046         return array.left(1).toLower() + array.mid(1);
0047     };
0048 
0049     QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("Roles"));
0050     for (int i{0}; i < e.keyCount(); i++) {
0051         m_roleNames.insert(e.value(i), desCapitalize(e.key(i)));
0052     }
0053 }
0054 
0055 void ParameterModel::loadDescriptionFile(const QString &path)
0056 {
0057     Q_UNUSED(path)
0058     // TODO: Deal with description files.
0059 }
0060 
0061 void ParameterModel::doUpdate(const QMap<ParameterModel::Roles, QVariant> &parameter)
0062 {
0063     // Check if parameter argument contains name.
0064     if (!parameter.contains(ParameterModel::Roles::Name)) {
0065         qDebug() << "No name identification in parameter";
0066         return;
0067     };
0068 
0069     // If name already exists in the model, get the index and update the other keys.
0070     int nameIndex = -1;
0071     if (m_vectors[ParameterModel::Roles::Name].contains(parameter[ParameterModel::Roles::Name])) {
0072         nameIndex = m_vectors[ParameterModel::Roles::Name].indexOf(parameter[ParameterModel::Roles::Name]);
0073     }
0074 
0075     const int line = rowCount();
0076 
0077     beginInsertRows(QModelIndex(), line, line);
0078     // Run over all keys in the parameter argument and update the model.
0079     QMapIterator<ParameterModel::Roles, QVariant> parameterIterator{parameter};
0080     while (parameterIterator.hasNext()) {
0081         parameterIterator.next();
0082         // Ignore name if already exist in the model.
0083         if (nameIndex >= 0 && parameterIterator.key() == ParameterModel::Roles::Name) {
0084             continue;
0085         }
0086 
0087         // Update the key if name already exist otherwise append it in the model.
0088         if (nameIndex >= 0) {
0089             m_vectors[parameterIterator.key()][nameIndex] = parameterIterator.value();
0090         } else {
0091             m_vectors[parameterIterator.key()].append(parameterIterator.value());
0092         }
0093     }
0094     const auto &indexRow = index(line);
0095     endInsertRows();
0096 
0097     emit dataChanged(indexRow, indexRow, QVector<int>::fromList(m_vectors.keys()));
0098     emit countChanged();
0099 }
0100 
0101 QVariant ParameterModel::data(const QModelIndex &index, int role) const
0102 {
0103     if (!m_roleNames.contains(role)) {
0104         return {"No valid data"};
0105     }
0106 
0107     return m_vectors[role][index.row()];
0108 }
0109 
0110 QHash<int, QByteArray> ParameterModel::roleNames() const
0111 {
0112     return m_roleNames;
0113 }