File indexing completed on 2024-05-12 05:36:51
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "ProcessSortFilterModel.h" 0008 0009 #include <QDebug> 0010 0011 #include <processcore/process_data_model.h> 0012 0013 using namespace KSysGuard; 0014 0015 ProcessSortFilterModel::ProcessSortFilterModel(QObject *parent) 0016 : QSortFilterProxyModel(parent) 0017 { 0018 setSortRole(ProcessDataModel::Value); 0019 setSortCaseSensitivity(Qt::CaseInsensitive); 0020 setSortLocaleAware(true); 0021 0022 setFilterRole(ProcessDataModel::Value); 0023 setFilterCaseSensitivity(Qt::CaseInsensitive); 0024 setRecursiveFilteringEnabled(true); 0025 setAutoAcceptChildRows(true); 0026 } 0027 0028 void ProcessSortFilterModel::setSourceModel(QAbstractItemModel *newSourceModel) 0029 { 0030 auto oldSourceModel = sourceModel(); 0031 0032 if (newSourceModel == oldSourceModel) { 0033 return; 0034 } 0035 0036 if (oldSourceModel) { 0037 oldSourceModel->disconnect(this); 0038 } 0039 0040 QSortFilterProxyModel::setSourceModel(newSourceModel); 0041 if (newSourceModel) { 0042 connect(newSourceModel, &QAbstractItemModel::modelReset, this, &ProcessSortFilterModel::findColumns); 0043 connect(newSourceModel, &QAbstractItemModel::columnsInserted, this, &ProcessSortFilterModel::findColumns); 0044 connect(newSourceModel, &QAbstractItemModel::columnsRemoved, this, &ProcessSortFilterModel::findColumns); 0045 connect(newSourceModel, &QAbstractItemModel::columnsMoved, this, &ProcessSortFilterModel::findColumns); 0046 findColumns(); 0047 } 0048 } 0049 0050 bool ProcessSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const 0051 { 0052 // not handled a reset yet, we'll invalidate at the end of modelReset anyway 0053 if (m_uidColumn == -1 && m_pidColumn == -1 && filterKeyColumn() == -1) { 0054 return false; 0055 } 0056 0057 auto source = sourceModel(); 0058 0059 bool result = true; 0060 0061 if (m_viewMode != ViewAll && m_uidColumn != -1) { 0062 auto uid = source->data(source->index(sourceRow, m_uidColumn, sourceParent), ProcessDataModel::Value).toUInt(); 0063 0064 switch (m_viewMode) { 0065 case ViewOwn: 0066 result = m_currentUser.userId().nativeId() == uid; 0067 break; 0068 case ViewUser: 0069 result = uid >= 1000 && uid < 65534; 0070 break; 0071 case ViewSystem: 0072 result = uid < 1000 || uid >= 65534; 0073 break; 0074 default: 0075 break; 0076 } 0077 } 0078 0079 if (!m_filterPids.isEmpty()) { 0080 auto pid = source->data(source->index(sourceRow, m_pidColumn, sourceParent), ProcessDataModel::Value); 0081 result = m_filterPids.contains(pid); 0082 } 0083 0084 if (!result) { 0085 return false; 0086 } 0087 0088 if (filterString().isEmpty()) { 0089 return true; 0090 } 0091 0092 const QString name = source->data(source->index(sourceRow, 0, sourceParent), filterRole()).toString(); 0093 0094 const QString filter = filterString(); 0095 const QList<QStringView> splitFilterStrings = QStringView(filter).split(QLatin1Char(','), Qt::SkipEmptyParts); 0096 0097 for (const QStringView &string : splitFilterStrings) { 0098 if (name.contains(string.trimmed(), Qt::CaseInsensitive)) { 0099 return true; 0100 } 0101 } 0102 0103 return false; 0104 } 0105 0106 bool ProcessSortFilterModel::filterAcceptsColumn(int sourceColumn, const QModelIndex &sourceParent) const 0107 { 0108 Q_UNUSED(sourceParent) 0109 0110 auto attribute = sourceModel()->headerData(sourceColumn, Qt::Horizontal, ProcessDataModel::Attribute).toString(); 0111 if (m_hiddenAttributes.contains(attribute)) { 0112 return false; 0113 } 0114 0115 return true; 0116 } 0117 0118 QString ProcessSortFilterModel::filterString() const 0119 { 0120 return m_filterString; 0121 } 0122 0123 void ProcessSortFilterModel::setFilterString(const QString &newFilterString) 0124 { 0125 if (newFilterString == m_filterString) { 0126 return; 0127 } 0128 0129 m_filterString = newFilterString; 0130 setFilterWildcard(m_filterString); 0131 Q_EMIT filterStringChanged(); 0132 } 0133 0134 ProcessSortFilterModel::ViewMode ProcessSortFilterModel::viewMode() const 0135 { 0136 return m_viewMode; 0137 } 0138 0139 void ProcessSortFilterModel::setViewMode(ViewMode newViewMode) 0140 { 0141 if (newViewMode == m_viewMode) { 0142 return; 0143 } 0144 0145 m_viewMode = newViewMode; 0146 invalidateFilter(); 0147 Q_EMIT viewModeChanged(); 0148 } 0149 0150 QStringList ProcessSortFilterModel::hiddenAttributes() const 0151 { 0152 return m_hiddenAttributes; 0153 } 0154 0155 void ProcessSortFilterModel::setHiddenAttributes(const QStringList &newHiddenAttributes) 0156 { 0157 if (newHiddenAttributes == m_hiddenAttributes) { 0158 return; 0159 } 0160 0161 m_hiddenAttributes = newHiddenAttributes; 0162 invalidateFilter(); 0163 Q_EMIT hiddenAttributesChanged(); 0164 } 0165 0166 QVariantList ProcessSortFilterModel::filterPids() const 0167 { 0168 return m_filterPids; 0169 } 0170 0171 void ProcessSortFilterModel::setFilterPids(const QVariantList &newFilterPids) 0172 { 0173 if (newFilterPids == m_filterPids) { 0174 return; 0175 } 0176 0177 m_filterPids = newFilterPids; 0178 invalidateFilter(); 0179 Q_EMIT filterPidsChanged(); 0180 } 0181 0182 void ProcessSortFilterModel::sort(int column, Qt::SortOrder order) 0183 { 0184 QSortFilterProxyModel::sort(column, order); 0185 Q_EMIT sorted(); 0186 } 0187 0188 void ProcessSortFilterModel::findColumns() 0189 { 0190 m_uidColumn = -1; 0191 m_pidColumn = -1; 0192 int nameColumn = -1; 0193 0194 auto source = sourceModel(); 0195 0196 for (auto column = 0; column < source->columnCount(); ++column) { 0197 auto attribute = source->headerData(column, Qt::Horizontal, ProcessDataModel::Attribute).toString(); 0198 if (attribute == QStringLiteral("uid")) { 0199 m_uidColumn = column; 0200 } else if (attribute == QStringLiteral("pid")) { 0201 m_pidColumn = column; 0202 } else if (attribute == QStringLiteral("name")) { 0203 nameColumn = column; 0204 } 0205 } 0206 setFilterKeyColumn(nameColumn); 0207 } 0208 0209 #include "moc_ProcessSortFilterModel.cpp"