File indexing completed on 2024-05-12 05:47:29

0001 /*
0002  * SPDX-FileCopyrightText: 2011 Janardhan Reddy <annapareddyjanardhanreddy@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kfileitemmodelfilter.h"
0008 
0009 #include <QRegularExpression>
0010 
0011 #include <algorithm>
0012 
0013 #include <KFileItem>
0014 
0015 KFileItemModelFilter::KFileItemModelFilter()
0016     : m_useRegExp(false)
0017     , m_regExp(nullptr)
0018     , m_lowerCasePattern()
0019     , m_pattern()
0020 {
0021 }
0022 
0023 KFileItemModelFilter::~KFileItemModelFilter()
0024 {
0025     delete m_regExp;
0026     m_regExp = nullptr;
0027 }
0028 
0029 void KFileItemModelFilter::setPattern(const QString &filter)
0030 {
0031     m_pattern = filter;
0032     m_lowerCasePattern = filter.toLower();
0033 
0034     if (filter.contains(QLatin1Char('*')) || filter.contains(QLatin1Char('?')) || filter.contains(QLatin1Char('['))) {
0035         if (!m_regExp) {
0036             m_regExp = new QRegularExpression();
0037             m_regExp->setPatternOptions(QRegularExpression::CaseInsensitiveOption);
0038         }
0039         m_regExp->setPattern(QRegularExpression::wildcardToRegularExpression(filter));
0040         m_useRegExp = m_regExp->isValid();
0041     } else {
0042         m_useRegExp = false;
0043     }
0044 }
0045 
0046 QString KFileItemModelFilter::pattern() const
0047 {
0048     return m_pattern;
0049 }
0050 
0051 void KFileItemModelFilter::setMimeTypes(const QStringList &types)
0052 {
0053     m_mimeTypes = types;
0054 }
0055 
0056 QStringList KFileItemModelFilter::mimeTypes() const
0057 {
0058     return m_mimeTypes;
0059 }
0060 
0061 void KFileItemModelFilter::setExcludeMimeTypes(const QStringList &types)
0062 {
0063     m_excludeMimeTypes = types;
0064 }
0065 
0066 QStringList KFileItemModelFilter::excludeMimeTypes() const
0067 {
0068     return m_excludeMimeTypes;
0069 }
0070 
0071 bool KFileItemModelFilter::hasSetFilters() const
0072 {
0073     return (!m_pattern.isEmpty() || !m_mimeTypes.isEmpty() || !m_excludeMimeTypes.isEmpty());
0074 }
0075 
0076 bool KFileItemModelFilter::matches(const KFileItem &item) const
0077 {
0078     const bool hasPatternFilter = !m_pattern.isEmpty();
0079     const bool hasMimeTypesFilter = !m_mimeTypes.isEmpty() || !m_excludeMimeTypes.isEmpty();
0080 
0081     // If no filter is set, return true.
0082     if (!hasPatternFilter && !hasMimeTypesFilter) {
0083         return true;
0084     }
0085 
0086     // If both filters are set, return true when both filters are matched
0087     if (hasPatternFilter && hasMimeTypesFilter) {
0088         return (matchesPattern(item) && matchesType(item));
0089     }
0090 
0091     // If only one filter is set, return true when that filter is matched
0092     if (hasPatternFilter) {
0093         return matchesPattern(item);
0094     }
0095 
0096     return matchesType(item);
0097 }
0098 
0099 bool KFileItemModelFilter::matchesPattern(const KFileItem &item) const
0100 {
0101     if (m_useRegExp) {
0102         return m_regExp->match(item.text()).hasMatch();
0103     } else {
0104         return item.text().toLower().contains(m_lowerCasePattern);
0105     }
0106 }
0107 
0108 bool KFileItemModelFilter::matchesType(const KFileItem &item) const
0109 {
0110     bool excluded = std::any_of(m_excludeMimeTypes.constBegin(), m_excludeMimeTypes.constEnd(), [item](const QString &excludeMimetype) {
0111         return item.mimetype() == excludeMimetype;
0112     });
0113     if (excluded) {
0114         return false;
0115     }
0116 
0117     bool included = std::any_of(m_mimeTypes.constBegin(), m_mimeTypes.constEnd(), [item](const QString &mimeType) {
0118         return item.mimetype() == mimeType;
0119     });
0120     if (included) {
0121         return true;
0122     }
0123 
0124     return m_mimeTypes.isEmpty();
0125 }