File indexing completed on 2025-01-05 05:23:47

0001 /*
0002     This file is part of the Okteta Kasten Framework, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2022 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "structuresselectionmodel.hpp"
0010 
0011 // tool
0012 #include "../structuredefinitionfile.hpp"
0013 // KF
0014 #include <KCategorizedSortFilterProxyModel>
0015 #include <KLocalizedString>
0016 // Qt
0017 #include <QRegularExpression>
0018 #include <QHash>
0019 // Std
0020 #include <algorithm>
0021 
0022 StructuresSelectionModel::StructuresSelectionModel(QObject* parent)
0023     : QAbstractListModel(parent)
0024 {
0025 }
0026 
0027 StructuresSelectionModel::~StructuresSelectionModel() = default;
0028 
0029 void StructuresSelectionModel::setStructures(const QMap<QString, Kasten::StructureDefinitionFile*>& structureDefs)
0030 {
0031     // KCategorizedView at least with KF 5.95 fails to handle replacement in one go
0032     // so split up
0033     beginResetModel();
0034     m_metaDataList.clear();
0035     endResetModel();
0036 
0037     const int firstRowInserted = 0;
0038     const int lastRowInserted = structureDefs.size() - 1;
0039     beginInsertRows(QModelIndex(), firstRowInserted, lastRowInserted);
0040 
0041     QHash<QString, QStringList> ids;
0042     ids.reserve(structureDefs.size());
0043     m_metaDataList.reserve(structureDefs.size());
0044     // consider storing structureDefs directly in the model, but needs rework to not use raw pointers
0045     for (const Kasten::StructureDefinitionFile* def : structureDefs) {
0046         const StructureMetaData metaData = def->metaData();
0047         m_metaDataList.append(metaData);
0048         ids.insert(metaData.id(), def->structureNames());
0049     }
0050 
0051     // drop no longer existing ids from the enabled list
0052     m_enabledList.removeStructures(ids);
0053 
0054     endInsertRows();
0055 }
0056 
0057 QStringList StructuresSelectionModel::enabledStructures() const
0058 {
0059     return m_enabledList.toQStringList();
0060 }
0061 
0062 const StructureEnabledList& StructuresSelectionModel::enabledList() const
0063 {
0064     return m_enabledList;
0065 }
0066 
0067 void StructuresSelectionModel::setEnabledStructures(const QStringList& enabledStructures)
0068 {
0069     m_enabledList.setEnabledStructures(enabledStructures);
0070 
0071     // do a simple mass update for now
0072     const int lastRow = m_metaDataList.size()-1;
0073     if (lastRow >= 0) {
0074         const QModelIndex firstIndex = index(0, 0);
0075         const QModelIndex leastIndex = index(lastRow, 0);
0076         Q_EMIT dataChanged(firstIndex, leastIndex, {Qt::CheckStateRole});
0077         Q_EMIT enabledStructuresChanged();
0078     }
0079 }
0080 
0081 QVariant StructuresSelectionModel::data(const QModelIndex &index, int role) const
0082 {
0083     if (!index.isValid()) {
0084         return QVariant();
0085     }
0086 
0087     const int row = index.row();
0088     if (row >= m_metaDataList.size()) {
0089         return QVariant();
0090     }
0091 
0092     const StructureMetaData& metaData = m_metaDataList[row];
0093 
0094     switch (role) {
0095         case Qt::DisplayRole:
0096             return metaData.name();
0097         case CommentRole:
0098             return metaData.comment();
0099         case Qt::DecorationRole:
0100             return metaData.iconName();
0101         case Qt::CheckStateRole:
0102             return m_enabledList.isEnabled(metaData.id());
0103         case MetaDataRole:
0104             return QVariant::fromValue(metaData);
0105         case KCategorizedSortFilterProxyModel::CategoryDisplayRole:
0106             if (metaData.categoryId() == QLatin1String("structure/js")) {
0107                 return i18n("Dynamic Structure Definitions");
0108             }
0109             return i18n("Structure Definitions");
0110         case KCategorizedSortFilterProxyModel::CategorySortRole:
0111             return metaData.categoryId();
0112         default:
0113             return QVariant();
0114     }
0115 }
0116 
0117 bool StructuresSelectionModel::setData(const QModelIndex& index, const QVariant& value, int role)
0118 {
0119     if (!index.isValid()) {
0120         return false;
0121     }
0122 
0123     const int row = index.row();
0124     if (row >= m_metaDataList.size()) {
0125         return false;
0126     }
0127 
0128     if (role == Qt::CheckStateRole) {
0129         const StructureMetaData& metaData = m_metaDataList[row];
0130         const QString id = metaData.id();
0131         const bool isEnabled = value.toBool();
0132         m_enabledList.setEnabled(id, isEnabled);
0133         Q_EMIT dataChanged(index, index, {Qt::CheckStateRole});
0134         Q_EMIT enabledStructuresChanged();
0135         return true;
0136     }
0137 
0138     return false;
0139 }
0140 
0141 int StructuresSelectionModel::rowCount(const QModelIndex& parent) const
0142 {
0143     if (!parent.isValid()) {
0144         return m_metaDataList.size();
0145     }
0146 
0147     return 0;
0148 }
0149 
0150 #include "moc_structuresselectionmodel.cpp"