File indexing completed on 2024-06-23 05:06:41

0001 /*
0002     SPDX-FileCopyrightText: 2007 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "agentfilterproxymodel.h"
0008 
0009 #include "agentinstancemodel.h"
0010 #include "agenttypemodel.h"
0011 
0012 #include <QMimeDatabase>
0013 #include <QMimeType>
0014 #include <QStringList>
0015 
0016 using namespace Akonadi;
0017 
0018 // ensure the role numbers are equivalent for both source models
0019 static_assert(static_cast<int>(AgentTypeModel::CapabilitiesRole) == static_cast<int>(AgentInstanceModel::CapabilitiesRole),
0020               "AgentTypeModel::CapabilitiesRole does not match AgentInstanceModel::CapabilitiesRole");
0021 static_assert(static_cast<int>(AgentTypeModel::MimeTypesRole) == static_cast<int>(AgentInstanceModel::MimeTypesRole),
0022               "AgentTypeModel::MimeTypesRole does not match AgentInstanceModel::MimeTypesRole");
0023 
0024 /**
0025  * @internal
0026  */
0027 class Akonadi::AgentFilterProxyModelPrivate
0028 {
0029 public:
0030     QStringList mimeTypes;
0031     QStringList capabilities;
0032     QStringList excludeCapabilities;
0033     bool filterAcceptRegExp(const QModelIndex &index, const QRegularExpression &filterRegExpStr);
0034 };
0035 
0036 AgentFilterProxyModel::AgentFilterProxyModel(QObject *parent)
0037     : QSortFilterProxyModel(parent)
0038     , d(new AgentFilterProxyModelPrivate)
0039 {
0040     setDynamicSortFilter(true);
0041 }
0042 
0043 AgentFilterProxyModel::~AgentFilterProxyModel() = default;
0044 
0045 void AgentFilterProxyModel::addMimeTypeFilter(const QString &mimeType)
0046 {
0047     d->mimeTypes << mimeType;
0048     invalidateFilter();
0049 }
0050 
0051 void AgentFilterProxyModel::addCapabilityFilter(const QString &capability)
0052 {
0053     d->capabilities << capability;
0054     invalidateFilter();
0055 }
0056 
0057 void AgentFilterProxyModel::excludeCapabilities(const QString &capability)
0058 {
0059     d->excludeCapabilities << capability;
0060     invalidateFilter();
0061 }
0062 
0063 void AgentFilterProxyModel::clearFilters()
0064 {
0065     d->capabilities.clear();
0066     d->mimeTypes.clear();
0067     d->excludeCapabilities.clear();
0068     invalidateFilter();
0069 }
0070 
0071 bool AgentFilterProxyModelPrivate::filterAcceptRegExp(const QModelIndex &index, const QRegularExpression &filterRegExpStr)
0072 {
0073     // First see if the name matches a set regexp filter.
0074     if (!filterRegExpStr.pattern().isEmpty()) {
0075         return index.data(AgentTypeModel::IdentifierRole).toString().contains(filterRegExpStr) || index.data().toString().contains(filterRegExpStr);
0076     }
0077     return true;
0078 }
0079 
0080 bool AgentFilterProxyModel::filterAcceptsRow(int row, const QModelIndex & /*source_parent*/) const
0081 {
0082     const QModelIndex index = sourceModel()->index(row, 0);
0083 
0084     if (!d->mimeTypes.isEmpty()) {
0085         QMimeDatabase mimeDb;
0086         bool found = false;
0087         const QStringList lst = index.data(AgentTypeModel::MimeTypesRole).toStringList();
0088         for (const QString &mimeType : lst) {
0089             if (d->mimeTypes.contains(mimeType)) {
0090                 found = true;
0091             } else {
0092                 const QMimeType mt = mimeDb.mimeTypeForName(mimeType);
0093                 if (mt.isValid()) {
0094                     for (const QString &type : std::as_const(d->mimeTypes)) {
0095                         if (mt.inherits(type)) {
0096                             found = true;
0097                             break;
0098                         }
0099                     }
0100                 }
0101             }
0102 
0103             if (found) {
0104                 break;
0105             }
0106         }
0107 
0108         if (!found) {
0109             return false;
0110         }
0111     }
0112 
0113     if (!d->capabilities.isEmpty()) {
0114         bool found = false;
0115         const QStringList lst = index.data(AgentTypeModel::CapabilitiesRole).toStringList();
0116         for (const QString &capability : lst) {
0117             if (d->capabilities.contains(capability)) {
0118                 found = true;
0119                 break;
0120             }
0121         }
0122 
0123         if (!found) {
0124             return false;
0125         }
0126 
0127         if (!d->excludeCapabilities.isEmpty()) {
0128             const QStringList lstCapabilities = index.data(AgentTypeModel::CapabilitiesRole).toStringList();
0129             for (const QString &capability : lstCapabilities) {
0130                 if (d->excludeCapabilities.contains(capability)) {
0131                     found = false;
0132                     break;
0133                 }
0134             }
0135 
0136             if (!found) {
0137                 return false;
0138             }
0139         }
0140     }
0141 
0142     return d->filterAcceptRegExp(index, filterRegularExpression());
0143 }
0144 
0145 #include "moc_agentfilterproxymodel.cpp"