From 8efab8bf129b6f9928f478a429e20cf018e5e373 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Fri, 31 May 2019 10:54:36 -0400 Subject: FilterWidget takes a predicate to match strings copied the logic from modlistsortproxy so the basic boolean syntax in filters works --- src/filterwidget.cpp | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'src/filterwidget.cpp') diff --git a/src/filterwidget.cpp b/src/filterwidget.cpp index 7c47980e..16a46b0e 100644 --- a/src/filterwidget.cpp +++ b/src/filterwidget.cpp @@ -30,9 +30,39 @@ void FilterWidget::clear() m_edit->clear(); } -bool FilterWidget::matches(const QString& s) const +bool FilterWidget::matches(std::function pred) const { - return s.contains(m_text); + const QStringList ORList = [&] { + QString filterCopy = QString(m_text); + filterCopy.replace("||", ";").replace("OR", ";").replace("|", ";"); + return filterCopy.split(";", QString::SkipEmptyParts); + }(); + + if (ORList.isEmpty() || !pred) { + return true; + } + + // split in ORSegments that internally use AND logic + for (auto& ORSegment : ORList) { + QStringList ANDKeywords = ORSegment.split(" ", QString::SkipEmptyParts); + bool segmentGood = true; + + // check each word in the segment for match, each word needs to be matched + // but it doesn't matter where. + for (auto& currentKeyword : ANDKeywords) { + if (!pred(currentKeyword)) { + segmentGood = false; + } + } + + if (segmentGood) { + // the last AND loop didn't break so the ORSegments is true so mod + // matches filter + return true; + } + } + + return false; } void FilterWidget::unhook() -- cgit v1.3.1