File indexing completed on 2024-05-19 05:38:36

0001 /*
0002     SPDX-FileCopyrightText: 2023 Fushan Wen <qydwhotmail@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-or-later
0005 */
0006 
0007 #include "mpris2filterproxymodel.h"
0008 
0009 #include "mpris2sourcemodel.h"
0010 
0011 std::shared_ptr<Mpris2FilterProxyModel> Mpris2FilterProxyModel::self()
0012 {
0013     static std::weak_ptr<Mpris2FilterProxyModel> s_model;
0014     if (s_model.expired()) {
0015         std::shared_ptr<Mpris2FilterProxyModel> ptr{new Mpris2FilterProxyModel};
0016         s_model = ptr;
0017         return ptr;
0018     }
0019 
0020     return s_model.lock();
0021 }
0022 
0023 Mpris2FilterProxyModel::Mpris2FilterProxyModel(QObject *parent)
0024     : QSortFilterProxyModel(parent)
0025     , m_sourceModel(Mpris2SourceModel::self())
0026 {
0027     // Must update m_proxyPidList before QSortFilterProxyModel receives updates from the source model,
0028     // so when filterAcceptsRow is called, m_proxyPidList is the latest
0029     connect(m_sourceModel.get(), &QAbstractListModel::rowsInserted, this, &Mpris2FilterProxyModel::onRowsInserted);
0030     connect(m_sourceModel.get(), &QAbstractListModel::rowsAboutToBeRemoved, this, &Mpris2FilterProxyModel::onRowsAboutToBeRemoved);
0031     connect(m_sourceModel.get(), &QAbstractListModel::dataChanged, this, &Mpris2FilterProxyModel::onDataChanged);
0032     setSourceModel(m_sourceModel.get());
0033     connect(m_sourceModel.get(), &QAbstractListModel::rowsInserted, this, &Mpris2FilterProxyModel::invalidateRowsFilter);
0034     connect(m_sourceModel.get(), &QAbstractListModel::rowsRemoved, this, &Mpris2FilterProxyModel::invalidateRowsFilter);
0035     connect(m_sourceModel.get(), &QAbstractListModel::dataChanged, this, &Mpris2FilterProxyModel::invalidateRowsFilter);
0036 }
0037 
0038 Mpris2FilterProxyModel::~Mpris2FilterProxyModel()
0039 {
0040 }
0041 
0042 bool Mpris2FilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &) const
0043 {
0044     if (m_proxyPidList.empty()) {
0045         return true;
0046     }
0047 
0048     const unsigned instancePid = m_sourceModel->index(sourceRow).data(Mpris2SourceModel::InstancePidRole).toUInt();
0049     return !m_proxyPidList.contains(instancePid);
0050 }
0051 
0052 void Mpris2FilterProxyModel::onRowsInserted(const QModelIndex &, int first, int)
0053 {
0054     if (const unsigned proxyPid = m_sourceModel->index(first).data(Mpris2SourceModel::KDEPidRole).toUInt(); proxyPid > 0) {
0055         m_proxyPidList.emplace(proxyPid);
0056     }
0057 }
0058 
0059 void Mpris2FilterProxyModel::onRowsAboutToBeRemoved(const QModelIndex &, int first, int)
0060 {
0061     if (const unsigned proxyPid = m_sourceModel->index(first).data(Mpris2SourceModel::KDEPidRole).toUInt(); proxyPid > 0) {
0062         m_proxyPidList.erase(proxyPid);
0063         // invalidateRowsFilter is called after rowsRemoved
0064     }
0065 }
0066 
0067 void Mpris2FilterProxyModel::onDataChanged(const QModelIndex &topLeft, const QModelIndex &, const QList<int> &roles)
0068 {
0069     if (!roles.contains(Mpris2SourceModel::KDEPidRole)) {
0070         return;
0071     }
0072 
0073     if (const unsigned proxyPid = topLeft.data(Mpris2SourceModel::KDEPidRole).toUInt(); proxyPid > 0) {
0074         m_proxyPidList.emplace(proxyPid);
0075     }
0076 }
0077 
0078 #include "moc_mpris2filterproxymodel.cpp"