File indexing completed on 2024-06-23 04:38:07

0001 // SPDX-FileCopyrightText: 2020 Henri Chain <henri.chain@enioka.com>
0002 // SPDX-FileCopyrightText: 2020 Kevin Ottens <kevin.ottens@enioka.com>
0003 //
0004 // SPDX-License-Identifier: LGPL-2.1-or-later
0005 
0006 #include "kapplicationscopelistmodel.h"
0007 #include "kapplicationscopelistmodel_p.h"
0008 #include "kcgroups_debug.h"
0009 #include <QDebug>
0010 #include <algorithm>
0011 
0012 KApplicationScopeListModel::KApplicationScopeListModel(QObject *parent)
0013     : KApplicationScopeListModel(nullptr, parent)
0014 {
0015 }
0016 
0017 KApplicationScopeListModel::KApplicationScopeListModel(KApplicationScopeLister *lister, QObject *parent)
0018     : QAbstractListModel(parent)
0019     , d_ptr(new KApplicationScopeListModelPrivate(lister, this))
0020 {
0021 }
0022 
0023 KApplicationScopeListModel::~KApplicationScopeListModel()
0024 {
0025     delete d_ptr;
0026 }
0027 
0028 QVariant KApplicationScopeListModel::data(const QModelIndex &index, int role) const
0029 {
0030     const auto row = index.row();
0031     if (row < d_ptr->m_apps.length()) {
0032         auto *app = d_ptr->m_apps[row];
0033         switch (role) {
0034         case Qt::DisplayRole:
0035             return !app->description().isEmpty() ? app->description() : !app->desktopName().isEmpty() ? app->desktopName() : app->id();
0036         case ObjectRole:
0037             return QVariant::fromValue(app);
0038         }
0039     }
0040     return QVariant();
0041 }
0042 
0043 int KApplicationScopeListModel::rowCount(const QModelIndex &parent) const
0044 {
0045     Q_UNUSED(parent);
0046     return d_ptr->m_apps.size();
0047 }
0048 
0049 QHash<int, QByteArray> KApplicationScopeListModel::roleNames() const
0050 {
0051     return {{Qt::DisplayRole, "display"}, {ObjectRole, "object"}};
0052 }
0053 
0054 KApplicationScopeListModelPrivate::KApplicationScopeListModelPrivate(KApplicationScopeLister *lister,
0055                                                                      KApplicationScopeListModel *parent)
0056     : m_apps({})
0057     , q_ptr(parent)
0058     , m_lister(lister == nullptr ? new KApplicationScopeLister(parent) : lister)
0059 {
0060     QObject::connect(m_lister,
0061                      &KApplicationScopeLister::pathAdded,
0062                      q_ptr,
0063                      [this](const QString &path, const QString &id) { handleNewApp(path, id); });
0064     QObject::connect(m_lister, &KApplicationScopeLister::pathRemoved, q_ptr, [this](const QString &path) {
0065         handleRemovedApp(path);
0066     });
0067 }
0068 
0069 void KApplicationScopeListModelPrivate::handleNewApp(const QString &path, const QString &id)
0070 {
0071     const auto row = m_apps.size();
0072     q_ptr->beginInsertRows(QModelIndex(), row, row);
0073     const auto app = new KApplicationScope(path, id, q_ptr);
0074     QObject::connect(app, &KApplicationScope::propertyChanged, q_ptr, [this, app]() {
0075         const auto row = m_apps.indexOf(app);
0076         if (row >= 0) {
0077             const auto idx = q_ptr->index(row, 0);
0078             emit q_ptr->dataChanged(idx, idx);
0079         }
0080     });
0081     m_apps.append(app);
0082     q_ptr->endInsertRows();
0083 }
0084 
0085 void KApplicationScopeListModelPrivate::handleRemovedApp(const QString &path)
0086 {
0087     const auto it = std::find_if(
0088         m_apps.begin(), m_apps.end(), [&path](const KApplicationScope *app) { return app->path() == path; });
0089     if (it != m_apps.end()) {
0090         const auto *app = *it;
0091         const auto row = static_cast<int>(std::distance(m_apps.begin(), it));
0092         q_ptr->beginRemoveRows(QModelIndex(), row, row);
0093         delete app;
0094         m_apps.removeAt(row);
0095         q_ptr->endRemoveRows();
0096     } else {
0097         qCDebug(KCGROUPS_LOG) << "app not found:" << path;
0098     }
0099 }