From 343c43a010ffaf02a36102b80dd18b375e44e637 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 21 Jun 2009 11:31:03 -0400 Subject: [PATCH] Enhancement - filter on annotation - Description filters now automatically apply to annotations. --- src/Att.cpp | 14 ++++++------- src/Context.cpp | 5 +++++ src/Filter.cpp | 53 +++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/src/Att.cpp b/src/Att.cpp index d34002567..3208c7a2d 100644 --- a/src/Att.cpp +++ b/src/Att.cpp @@ -478,6 +478,13 @@ bool Att::match (const Att& other) const return false; } + // has = contains as a substring. + else if (mMod == "has" || mMod == "contains") // TODO i18n + { + if (other.mValue.find (mValue) == std::string::npos) + return false; + } + // is = equal. Nop. else if (mMod == "is" || mMod == "equals") // TODO i18n { @@ -528,13 +535,6 @@ bool Att::match (const Att& other) const return false; } - // has = contains as a substring. - else if (mMod == "has" || mMod == "contains") // TODO i18n - { - if (other.mValue.find (mValue) == std::string::npos) - return false; - } - // hasnt = does not contain as a substring. else if (mMod == "hasnt") // TODO i18n { diff --git a/src/Context.cpp b/src/Context.cpp index 0fd1a9908..cc9abda8d 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -573,6 +573,11 @@ void Context::autoFilter (Task& t, Filter& f) { f.push_back (Att ("description", "has", *word)); debug ("auto filter: " + att->first + ".has:" + *word); + +/* + f.push_back (Att ("annotation_*", "has", *word)); + debug ("auto filter: annotation_*.has:" + *word); +*/ } } diff --git a/src/Filter.cpp b/src/Filter.cpp index 98a098d44..052b043f3 100644 --- a/src/Filter.cpp +++ b/src/Filter.cpp @@ -38,19 +38,56 @@ bool Filter::pass (const Record& record) const { Record::const_iterator r; - // If record doesn't have the attribute, fail. If it does have the attribute - // but it doesn't match, fail. + // First do description/annotation matches. foreach (att, (*this)) { - // If the record doesn't have the attribute, match against a default one. - // This is because "att" may contain a modifier like "name.not:X". - if ((r = record.find (att->name ())) == record.end ()) + // Descriptions have special handling. + if (att->name () == "description") { - if (! att->match (Att ())) + if ((r = record.find (att->name ())) != record.end ()) + { + // A description match failure can be salvaged by an annotation match. + if (! att->match (r->second)) + { + bool annoMatch = false; + foreach (ra, record) + { + if (ra->first.length () > 11 && + ra->first.substr (0, 11) == "annotation_") + { + if (att->match (ra->second)) + { + annoMatch = true; + break; + } + } + } + + if (!annoMatch) + return false; + } + } + else if (! att->match (Att ())) + return false; + } + + // Annotations are skipped. + else if (att->name ().length () > 11 && + att->name ().substr (0, 11) == "annotation_") + { + } + + else + { + // An individual attribute match failure is enough to fail the filter. + if ((r = record.find (att->name ())) != record.end ()) + { + if (! att->match (r->second)) + return false; + } + else if (! att->match (Att ())) return false; } - else if (! att->match (r->second)) - return false; } return true;