diff --git a/model/foldermodel.cpp b/model/foldermodel.cpp index 6230bec..d133b8d 100644 --- a/model/foldermodel.cpp +++ b/model/foldermodel.cpp @@ -73,6 +73,8 @@ FolderModel::FolderModel(QObject *parent) , m_sortMode(0) , m_sortDesc(false) , m_sortDirsFirst(true) + , m_filterMode(NoFilter) + , m_filterPatternMatchAll(true) , m_complete(false) , m_isDesktop(false) , m_actionCollection(this) @@ -341,6 +343,70 @@ void FolderModel::setSortDirsFirst(bool enable) } } +int FolderModel::filterMode() const +{ + return m_filterMode; +} + +void FolderModel::setFilterMode(int filterMode) +{ + if (m_filterMode != (FilterMode)filterMode) { + m_filterMode = (FilterMode)filterMode; + + invalidateFilterIfComplete(); + + emit filterModeChanged(); + } +} + +QStringList FolderModel::filterMimeTypes() const +{ + return m_mimeSet.values(); +} + +void FolderModel::setFilterMimeTypes(const QStringList &mimeList) +{ + const QSet set(mimeList.constBegin(), mimeList.constEnd()); + + if (m_mimeSet != set) { + m_mimeSet = set; + + invalidateFilterIfComplete(); + + emit filterMimeTypesChanged(); + } +} + +QString FolderModel::filterPattern() const +{ + return m_filterPattern; +} + +void FolderModel::setFilterPattern(const QString &pattern) +{ + if (m_filterPattern == pattern) { + return; + } + + m_filterPattern = pattern; + m_filterPatternMatchAll = (pattern == QLatin1String("*")); + + const QStringList patterns = pattern.split(QLatin1Char(' ')); + m_regExps.clear(); + m_regExps.reserve(patterns.count()); + + foreach (const QString &pattern, patterns) { + QRegExp rx(pattern); + rx.setPatternSyntax(QRegExp::Wildcard); + rx.setCaseSensitivity(Qt::CaseInsensitive); + m_regExps.append(rx); + } + + invalidateFilterIfComplete(); + + emit filterPatternChanged(); +} + QObject *FolderModel::viewAdapter() const { return m_viewAdapter; @@ -1088,6 +1154,53 @@ bool FolderModel::isSupportThumbnails(const QString &mimeType) const return false; } +bool FolderModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + const KDirModel *dirModel = static_cast(sourceModel()); + const KFileItem item = dirModel->itemForIndex(dirModel->index(sourceRow, KDirModel::Name, sourceParent)); + + if (m_filterMode == NoFilter) { + return true; + } + + if (m_filterMode == FilterShowMatches) { + return (matchPattern(item) && matchMimeType(item)); + } else { + return !(matchPattern(item) && matchMimeType(item)); + } +} + +bool FolderModel::matchMimeType(const KFileItem &item) const +{ + if (m_mimeSet.isEmpty()) { + return false; + } + + if (m_mimeSet.contains(QLatin1String("all/all")) || m_mimeSet.contains(QLatin1String("all/allfiles"))) { + return true; + } + + const QString mimeType = item.determineMimeType().name(); + return m_mimeSet.contains(mimeType); +} + +bool FolderModel::matchPattern(const KFileItem &item) const +{ + if (m_filterPatternMatchAll) { + return true; + } + + const QString name = item.name(); + QListIterator i(m_regExps); + while (i.hasNext()) { + if (i.next().exactMatch(name)) { + return true; + } + } + + return false; +} + bool FolderModel::isDesktop() const { return m_isDesktop; diff --git a/model/foldermodel.h b/model/foldermodel.h index 3e81eb9..3b211de 100644 --- a/model/foldermodel.h +++ b/model/foldermodel.h @@ -53,7 +53,10 @@ class FolderModel : public QSortFilterProxyModel, public QQmlParserStatus Q_PROPERTY(QObject *viewAdapter READ viewAdapter WRITE setViewAdapter NOTIFY viewAdapterChanged) Q_PROPERTY(bool isDesktop READ isDesktop WRITE setIsDesktop NOTIFY isDesktopChanged) Q_PROPERTY(int selectionCount READ selectionCount NOTIFY selectionCountChanged) + Q_PROPERTY(int filterMode READ filterMode WRITE setFilterMode NOTIFY filterModeChanged) + Q_PROPERTY(QString filterPattern READ filterPattern WRITE setFilterPattern NOTIFY filterPatternChanged) Q_PROPERTY(int count READ count NOTIFY countChanged) + Q_PROPERTY(QStringList filterMimeTypes READ filterMimeTypes WRITE setFilterMimeTypes NOTIFY filterMimeTypesChanged) public: enum DataRole { @@ -121,6 +124,15 @@ public: bool sortDirsFirst() const; void setSortDirsFirst(bool enable); + int filterMode() const; + void setFilterMode(int filterMode); + + QStringList filterMimeTypes() const; + void setFilterMimeTypes(const QStringList &mimeList); + + QString filterPattern() const; + void setFilterPattern(const QString &pattern); + QObject *viewAdapter() const; void setViewAdapter(QObject *adapter); @@ -195,12 +207,15 @@ signals: void sortModeChanged(); void sortDescChanged(); void sortDirsFirstChanged(); + void filterModeChanged(); void requestRename(); void draggingChanged(); void viewAdapterChanged(); void isDesktopChanged(); void selectionCountChanged(); void countChanged(); + void filterPatternChanged(); + void filterMimeTypesChanged(); private slots: void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); @@ -215,6 +230,11 @@ private: bool isSupportThumbnails(const QString &mimeType) const; +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; + bool matchMimeType(const KFileItem &item) const; + bool matchPattern(const KFileItem &item) const; + private: KDirModel *m_dirModel; KDirWatch *m_dirWatch; @@ -228,6 +248,12 @@ private: bool m_sortDesc; bool m_sortDirsFirst; + FilterMode m_filterMode; + QString m_filterPattern; + bool m_filterPatternMatchAll; + QSet m_mimeSet; + QList m_regExps; + bool m_complete; bool m_isDesktop; bool m_suffixVisible;