File indexing completed on 2023-09-24 04:08:35
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2022 Nicolas Fella <nicolas.fella@gmx.de> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "kfilefilter.h" 0009 0010 #include <QDebug> 0011 #include <QMetaType> 0012 #include <QMimeDatabase> 0013 #include <algorithm> 0014 #include <qchar.h> 0015 0016 #include "kiocoredebug.h" 0017 0018 class KFileFilterPrivate : public QSharedData 0019 { 0020 public: 0021 KFileFilterPrivate() 0022 { 0023 } 0024 0025 KFileFilterPrivate(const KFileFilterPrivate &other) 0026 : QSharedData(other) 0027 , m_label(other.m_label) 0028 , m_filePatterns(other.m_filePatterns) 0029 , m_mimePatterns(other.m_mimePatterns) 0030 { 0031 } 0032 0033 QString m_label; 0034 QStringList m_filePatterns; 0035 QStringList m_mimePatterns; 0036 }; 0037 0038 QVector<KFileFilter> KFileFilter::fromFilterString(const QString &filterString) 0039 { 0040 int pos = filterString.indexOf(QLatin1Char('/')); 0041 0042 // Check for an un-escaped '/', if found 0043 // interpret as a MIME filter. 0044 0045 if (pos > 0 && filterString[pos - 1] != QLatin1Char('\\')) { 0046 const QStringList filters = filterString.split(QLatin1Char(' '), Qt::SkipEmptyParts); 0047 0048 QVector<KFileFilter> result; 0049 result.reserve(filters.size()); 0050 0051 std::transform(filters.begin(), filters.end(), std::back_inserter(result), [](const QString &mimeType) { 0052 return KFileFilter::fromMimeType(mimeType); 0053 }); 0054 0055 return result; 0056 } 0057 0058 // Strip the escape characters from 0059 // escaped '/' characters. 0060 0061 QString escapeRemoved(filterString); 0062 for (pos = 0; (pos = escapeRemoved.indexOf(QLatin1String("\\/"), pos)) != -1; ++pos) { 0063 escapeRemoved.remove(pos, 1); 0064 } 0065 0066 const QStringList filters = escapeRemoved.split(QLatin1Char('\n'), Qt::SkipEmptyParts); 0067 0068 QVector<KFileFilter> result; 0069 0070 for (const QString &filter : filters) { 0071 int separatorPos = filter.indexOf(QLatin1Char('|')); 0072 0073 QString label; 0074 QStringList patterns; 0075 0076 if (separatorPos != -1) { 0077 label = filter.mid(separatorPos + 1); 0078 patterns = filter.left(separatorPos).split(QLatin1Char(' ')); 0079 } else { 0080 patterns = filter.split(QLatin1Char(' ')); 0081 label = patterns.join(QLatin1Char(' ')); 0082 } 0083 0084 result << KFileFilter(label, patterns, {}); 0085 } 0086 0087 return result; 0088 } 0089 0090 KFileFilter::KFileFilter() 0091 : d(new KFileFilterPrivate) 0092 { 0093 } 0094 0095 KFileFilter::KFileFilter(const QString &label, const QStringList &filePatterns, const QStringList &mimePatterns) 0096 : d(new KFileFilterPrivate) 0097 { 0098 d->m_filePatterns = filePatterns; 0099 d->m_mimePatterns = mimePatterns; 0100 d->m_label = label; 0101 } 0102 0103 KFileFilter::~KFileFilter() = default; 0104 0105 KFileFilter::KFileFilter(const KFileFilter &other) 0106 : d(other.d) 0107 { 0108 } 0109 0110 KFileFilter &KFileFilter::operator=(const KFileFilter &other) 0111 { 0112 if (this != &other) { 0113 d = other.d; 0114 } 0115 0116 return *this; 0117 } 0118 0119 QString KFileFilter::label() const 0120 { 0121 return d->m_label; 0122 } 0123 0124 QStringList KFileFilter::filePatterns() const 0125 { 0126 return d->m_filePatterns; 0127 } 0128 0129 QStringList KFileFilter::mimePatterns() const 0130 { 0131 return d->m_mimePatterns; 0132 } 0133 0134 bool KFileFilter::operator==(const KFileFilter &other) const 0135 { 0136 return d->m_label == other.d->m_label && d->m_filePatterns == other.d->m_filePatterns && d->m_mimePatterns == other.d->m_mimePatterns; 0137 } 0138 0139 bool KFileFilter::isEmpty() const 0140 { 0141 return d->m_filePatterns.isEmpty() && d->m_mimePatterns.isEmpty(); 0142 } 0143 0144 QString KFileFilter::toFilterString() const 0145 { 0146 if (!d->m_filePatterns.isEmpty() && !d->m_mimePatterns.isEmpty()) { 0147 qCWarning(KIO_CORE) << "KFileFilters with both mime and file patterns cannot be converted to filter strings"; 0148 return QString(); 0149 } 0150 0151 if (!d->m_mimePatterns.isEmpty()) { 0152 return d->m_mimePatterns.join(QLatin1Char(' ')); 0153 } 0154 0155 if (!d->m_label.isEmpty()) { 0156 const QString patterns = d->m_filePatterns.join(QLatin1Char(' ')); 0157 const QString escapedLabel = QString(d->m_label).replace(QLatin1String("/"), QLatin1String("\\/")); 0158 0159 if (patterns != d->m_label) { 0160 return patterns + QLatin1Char('|') + escapedLabel; 0161 } else { 0162 return patterns; 0163 } 0164 } else { 0165 return d->m_filePatterns.join(QLatin1Char(' ')); 0166 } 0167 } 0168 0169 KFileFilter KFileFilter::fromMimeType(const QString &mimeType) 0170 { 0171 if (mimeType.isEmpty()) { 0172 return KFileFilter(); 0173 } 0174 0175 static QMimeDatabase db; 0176 const QMimeType type = db.mimeTypeForName(mimeType); 0177 0178 KFileFilter filter(type.comment(), {}, {mimeType}); 0179 return filter; 0180 } 0181 0182 Q_DECLARE_METATYPE(KFileFilter);