CollectionFilter: Use recursive filtering

Fixes #1486
Fixes #1487
This commit is contained in:
Jonas Kvinge 2024-07-15 13:44:50 +02:00
parent f4ec3ab379
commit 3100b0c044
3 changed files with 16 additions and 25 deletions

View File

@ -43,7 +43,13 @@ const QStringList CollectionFilter::Operators = QStringList() << QStringLiteral(
<< QStringLiteral(">") << QStringLiteral(">")
<< QStringLiteral(">="); << QStringLiteral(">=");
CollectionFilter::CollectionFilter(QObject *parent) : QSortFilterProxyModel(parent) {} CollectionFilter::CollectionFilter(QObject *parent) : QSortFilterProxyModel(parent) {
setSortLocaleAware(true);
setDynamicSortFilter(true);
setRecursiveFilteringEnabled(true);
}
bool CollectionFilter::filterAcceptsRow(const int source_row, const QModelIndex &source_parent) const { bool CollectionFilter::filterAcceptsRow(const int source_row, const QModelIndex &source_parent) const {
@ -54,7 +60,9 @@ bool CollectionFilter::filterAcceptsRow(const int source_row, const QModelIndex
CollectionItem *item = model->IndexToItem(idx); CollectionItem *item = model->IndexToItem(idx);
if (!item) return false; if (!item) return false;
if (item->type == CollectionItem::Type::LoadingIndicator) return true; if (item->type != CollectionItem::Type::Song) {
return item->type == CollectionItem::Type::LoadingIndicator;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QString filter_text = filterRegularExpression().pattern().remove(QLatin1Char('\\')); QString filter_text = filterRegularExpression().pattern().remove(QLatin1Char('\\'));
@ -65,9 +73,11 @@ bool CollectionFilter::filterAcceptsRow(const int source_row, const QModelIndex
if (filter_text.isEmpty()) return true; if (filter_text.isEmpty()) return true;
for (const QString &foperator : Operators) { for (const QString &foperator : Operators) {
if (filter_text.contains(foperator)) { if (filter_text.contains(foperator + QLatin1Char(' '))) {
QRegularExpression regex(QStringLiteral("\\s*") + foperator + QStringLiteral("\\s*")); filter_text = filter_text.replace(foperator + QLatin1Char(' '), foperator);
filter_text = filter_text.replace(regex, foperator); }
if (filter_text.contains(QLatin1Char(' ') + foperator)) {
filter_text = filter_text.replace(QLatin1Char(' ') + foperator, foperator);
} }
} }
@ -156,23 +166,7 @@ bool CollectionFilter::filterAcceptsRow(const int source_row, const QModelIndex
if (filter_text.isEmpty() && filters.isEmpty()) return true; if (filter_text.isEmpty() && filters.isEmpty()) return true;
return ItemMatchesFilters(item, filters, filter_text); return item->metadata.is_valid() && ItemMetadataMatchesFilters(item->metadata, filters, filter_text);
}
bool CollectionFilter::ItemMatchesFilters(CollectionItem *item, const FilterList &filters, const QString &filter_text) {
if (item->type == CollectionItem::Type::Song &&
item->metadata.is_valid() &&
ItemMetadataMatchesFilters(item->metadata, filters, filter_text)) {
return true;
}
for (CollectionItem *child : std::as_const(item->children)) {
if (ItemMatchesFilters(child, filters, filter_text)) return true;
}
return false;
} }

View File

@ -52,7 +52,6 @@ class CollectionFilter : public QSortFilterProxyModel {
QString foperator; QString foperator;
}; };
using FilterList = QMap<QString, Filter>; using FilterList = QMap<QString, Filter>;
static bool ItemMatchesFilters(CollectionItem *item, const FilterList &filters, const QString &filter_text);
static bool ItemMetadataMatchesFilters(const Song &metadata, const FilterList &filters, const QString &filter_text); static bool ItemMetadataMatchesFilters(const Song &metadata, const FilterList &filters, const QString &filter_text);
static bool ItemMetadataMatchesFilterText(const Song &metadata, const QString &filter_text); static bool ItemMetadataMatchesFilterText(const Song &metadata, const QString &filter_text);
static QVariant DataFromField(const QString &field, const Song &metadata); static QVariant DataFromField(const QString &field, const Song &metadata);

View File

@ -100,8 +100,6 @@ CollectionModel::CollectionModel(SharedPtr<CollectionBackend> backend, Applicati
filter_->setSourceModel(this); filter_->setSourceModel(this);
filter_->setSortRole(Role_SortText); filter_->setSortRole(Role_SortText);
filter_->setDynamicSortFilter(true);
filter_->setSortLocaleAware(true);
filter_->sort(0); filter_->sort(0);
if (app_) { if (app_) {