diff --git a/src/data/filter.hpp b/src/data/filter.hpp new file mode 100644 index 00000000..63889f83 --- /dev/null +++ b/src/data/filter.hpp @@ -0,0 +1,88 @@ +//+----------------------------------------------------------------------------+ +//| Description: Magic Set Editor - Program to make Magic (tm) cards | +//| Copyright: (C) 2001 - 2010 Twan van Laarhoven and Sean Hunt | +//| License: GNU General Public License 2 or later (see file COPYING) | +//+----------------------------------------------------------------------------+ + +#ifndef HEADER_DATA_FILTER +#define HEADER_DATA_FILTER + +// ----------------------------------------------------------------------------- : Includes + +#include + +// ----------------------------------------------------------------------------- : Filters + +/// A filter function to determine which items are shown in a list +template +class Filter : public IntrusivePtrVirtualBase { + public: + typedef intrusive_ptr TP; + + virtual ~Filter() {} + /// Should an object be shown in the list? + virtual bool keep(T const& x) const { + return false; + } + /// Select objects from a list + virtual void getItems(vector const& in, vector& out) const { + for (vector::const_iterator it = in.begin() ; it != in.end() ; ++it) { + if (keep(**it)) { + out.push_back(*it); + } + } + } +}; + +// ----------------------------------------------------------------------------- : Quick search + +/// Does the given object match the quick search query? +template +bool match_quicksearch_query(String const& query, T const& object) { + bool need_match = true; + // iterate over the components of the query + for (size_t i = 0 ; i < query.size() ; ) { + if (query.GetChar(i) == _(' ')) { + // skip spaces + i++; + } else if (query.GetChar(i) == _('-')) { + // negate the next query, i.e. match only if it is not on the card + need_match = !need_match; + i++; + } else { + size_t end, next; + if (query.GetChar(i) == _('"')) { + // quoted string, match exactly + i++; + end =query.find_first_of(_('"'),i); + next = min(end,query.size()) + 1; + } else { + // single word + next = end = query.find_first_of(_(' '),i); + } + bool match = object.contains(query.substr(i,end-i)); + if (match != need_match) { + return false; + } + need_match = true; // next word is no longer negated + i = next; + } + } + return true; +} + +/// A filter function that searches for objects containing a string +template +class QuickFilter : public Filter { + public: + using typename Filter::TP; + QuickFilter(String const& query) : query(query) {} + virtual bool keep(T const& x) const { + return match_quicksearch_query(query, x); + } + private: + String query; +}; + +// ----------------------------------------------------------------------------- : EOF +#endif