File indexing completed on 2024-05-05 17:33:22

0001 /*
0002  *   SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #include "SourcesModel.h"
0008 #include "libdiscover_debug.h"
0009 #include "resources/AbstractResourcesBackend.h"
0010 #include "resources/AbstractSourcesBackend.h"
0011 #include <QtGlobal>
0012 #include <utils.h>
0013 
0014 Q_GLOBAL_STATIC(SourcesModel, s_sources)
0015 
0016 const auto DisplayName = "DisplayName";
0017 const auto SourcesBackendId = "SourcesBackend";
0018 
0019 SourcesModel::SourcesModel(QObject *parent)
0020     : QConcatenateTablesProxyModel(parent)
0021 {
0022 }
0023 
0024 SourcesModel::~SourcesModel() = default;
0025 
0026 SourcesModel *SourcesModel::global()
0027 {
0028     return s_sources;
0029 }
0030 
0031 QHash<int, QByteArray> SourcesModel::roleNames() const
0032 {
0033     QHash<int, QByteArray> roles = QConcatenateTablesProxyModel::roleNames();
0034     roles.insert(AbstractSourcesBackend::IdRole, "sourceId");
0035     roles.insert(Qt::DisplayRole, "display");
0036     roles.insert(Qt::ToolTipRole, "toolTip");
0037     roles.insert(Qt::CheckStateRole, "checkState");
0038     roles.insert(SourceNameRole, "sourceName");
0039     roles.insert(SourcesBackend, "sourcesBackend");
0040     roles.insert(ResourcesBackend, "resourcesBackend");
0041     roles.insert(EnabledRole, "enabled");
0042     return roles;
0043 }
0044 
0045 void SourcesModel::addSourcesBackend(AbstractSourcesBackend *sources)
0046 {
0047     auto backend = qobject_cast<AbstractResourcesBackend *>(sources->parent());
0048 
0049     auto m = sources->sources();
0050     m->setProperty(DisplayName, backend->displayName());
0051     m->setProperty(SourcesBackendId, QVariant::fromValue<QObject *>(sources));
0052 
0053     // QConcatenateTablesProxyModel will consider empty models as column==0. Empty models
0054     // will have 0 columns so it ends up showing nothing
0055     if (m->rowCount() == 0) {
0056         qWarning() << "adding empty sources model" << m;
0057         auto action = new OneTimeAction(
0058             [this, m] {
0059                 addSourceModel(m);
0060                 Q_EMIT sourcesChanged();
0061             },
0062             this);
0063         connect(m, &QAbstractItemModel::rowsInserted, action, &OneTimeAction::trigger);
0064     } else {
0065         addSourceModel(m);
0066         Q_EMIT sourcesChanged();
0067     }
0068 }
0069 
0070 const QAbstractItemModel *SourcesModel::modelAt(const QModelIndex &index) const
0071 {
0072     return mapToSource(index).model();
0073 }
0074 
0075 QVariant SourcesModel::data(const QModelIndex &index, int role) const
0076 {
0077     if (!index.isValid())
0078         return {};
0079     switch (role) {
0080     case SourceNameRole:
0081         return modelAt(index)->property(DisplayName);
0082     case SourcesBackend:
0083         return modelAt(index)->property(SourcesBackendId);
0084     case EnabledRole:
0085         return QVariant(flags(index) & Qt::ItemIsEnabled);
0086     default:
0087         return QConcatenateTablesProxyModel::data(index, role);
0088     }
0089 }
0090 
0091 AbstractSourcesBackend *SourcesModel::sourcesBackendByName(const QString &id) const
0092 {
0093     for (int i = 0, c = rowCount(); i < c; ++i) {
0094         const auto idx = index(i, 0);
0095         if (idx.data(SourceNameRole) == id) {
0096             return qobject_cast<AbstractSourcesBackend *>(idx.data(SourcesBackend).value<QObject *>());
0097         }
0098     }
0099     return nullptr;
0100 }
0101 
0102 QVector<AbstractSourcesBackend *> SourcesModel::sources() const
0103 {
0104     QVector<AbstractSourcesBackend *> sources;
0105     for (int i = 0, c = rowCount(); i < c; ++i) {
0106         const auto idx = index(i, 0);
0107         auto source = qobject_cast<AbstractSourcesBackend *>(modelAt(idx)->property(SourcesBackendId).value<QObject *>());
0108         if (!sources.contains(source)) {
0109             sources += source;
0110         }
0111     }
0112     return sources;
0113 }