mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Allow "field:query" in the quick filter bar
This commit is contained in:
+3
-3
@@ -52,11 +52,11 @@ String Card::identification() const {
|
||||
}
|
||||
}
|
||||
|
||||
bool Card::contains(String const& query) const {
|
||||
bool Card::contains(QuickFilterPart const& query) const {
|
||||
FOR_EACH_CONST(v, data) {
|
||||
if (find_i(v->toString(),query) != String::npos) return true;
|
||||
if (query.match(v->fieldP->name, v->toString())) return true;
|
||||
}
|
||||
if (find_i(notes,query) != String::npos) return true;
|
||||
if (query.match(_("notes"), notes)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -11,6 +11,7 @@
|
||||
#include <util/prec.hpp>
|
||||
#include <util/reflect.hpp>
|
||||
#include <util/error.hpp>
|
||||
#include <data/filter.hpp>
|
||||
#include <data/field.hpp> // for Card::value
|
||||
|
||||
class Game;
|
||||
@@ -61,9 +62,7 @@ class Card : public IntrusivePtrVirtualBase {
|
||||
/** May return "" */
|
||||
String identification() const;
|
||||
/// Does any field contains the given query string?
|
||||
bool contains(String const& query) const;
|
||||
/// Does this card contain each of the words in the query string?
|
||||
bool contains_words(String const& query) const;
|
||||
bool contains(QuickFilterPart const& query) const;
|
||||
|
||||
/// Find a value in the data by name and type
|
||||
template <typename T> T& value(const String& name) {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
//+----------------------------------------------------------------------------+
|
||||
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
|
||||
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||
//+----------------------------------------------------------------------------+
|
||||
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <data/filter.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : Quick filter
|
||||
|
||||
vector<QuickFilterPart> parse_quicksearch_query(String const& query) {
|
||||
// iterate over the components of the query
|
||||
vector<QuickFilterPart> parts;
|
||||
QuickFilterPart part;
|
||||
bool quoted = false;
|
||||
for (wxUniChar c : query) {
|
||||
if (isSpace(c) && !quoted) {
|
||||
if (!part.query.empty()) {
|
||||
parts.push_back(part);
|
||||
part = {};
|
||||
}
|
||||
} else if (c == _('"')) {
|
||||
// begin/end quoted string, match exactly
|
||||
quoted = !quoted;
|
||||
} else if (c == _(':') && part.type.empty()) {
|
||||
part.type = part.query;
|
||||
part.query.clear();
|
||||
} else if (c == _('!') && part.query.empty() && part.type.empty()) {
|
||||
// negate
|
||||
part.need_match = false;
|
||||
} else {
|
||||
part.query += c;
|
||||
}
|
||||
}
|
||||
if (!part.query.empty()) {
|
||||
parts.push_back(part);
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
+22
-34
@@ -35,37 +35,26 @@ class Filter : public IntrusivePtrVirtualBase {
|
||||
|
||||
// ----------------------------------------------------------------------------- : Quick search
|
||||
|
||||
struct QuickFilterQuery {
|
||||
String type;
|
||||
String query;
|
||||
bool match(String const& key, String const& x) const {
|
||||
return (type.empty() || find_i(key,type) != String::npos) && find_i(x,query) != String::npos;
|
||||
}
|
||||
};
|
||||
|
||||
struct QuickFilterPart : QuickFilterQuery {
|
||||
bool need_match = true;
|
||||
};
|
||||
|
||||
/// Parse a quick filter string
|
||||
vector<QuickFilterPart> parse_quicksearch_query(String const& query);
|
||||
|
||||
/// Does the given object match the quick search query?
|
||||
template <typename T>
|
||||
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;
|
||||
}
|
||||
bool match_quicksearch_query(vector<QuickFilterPart> const& query, T const& object) {
|
||||
for (auto const& part : query) {
|
||||
if (object.contains(part) != part.need_match) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -73,13 +62,12 @@ bool match_quicksearch_query(String const& query, T const& object) {
|
||||
/// A filter function that searches for objects containing a string
|
||||
template <typename T>
|
||||
class QuickFilter : public Filter<T> {
|
||||
public:
|
||||
using typename Filter<T>::TP;
|
||||
QuickFilter(String const& query) : query(query) {}
|
||||
public:
|
||||
QuickFilter(String const& query) : query(parse_quicksearch_query(query)) {}
|
||||
virtual bool keep(T const& x) const {
|
||||
return match_quicksearch_query(query, x);
|
||||
}
|
||||
private:
|
||||
String query;
|
||||
private:
|
||||
vector<QuickFilterPart> query;
|
||||
};
|
||||
|
||||
|
||||
@@ -73,11 +73,11 @@ void read_compat(Reader& handler, Keyword* k) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Keyword::contains(String const& query) const {
|
||||
if (find_i(keyword,query) != String::npos) return true;
|
||||
if (find_i(rules,query) != String::npos) return true;
|
||||
if (find_i(match,query) != String::npos) return true;
|
||||
if (find_i(reminder.get(),query) != String::npos) return true;
|
||||
bool Keyword::contains(QuickFilterPart const& query) const {
|
||||
if (query.match(_("keyword"), keyword)) return true;
|
||||
if (query.match(_("rules"), rules)) return true;
|
||||
if (query.match(_("match"), match)) return true;
|
||||
if (query.match(_("reminder"), reminder.get())) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <script/scriptable.hpp>
|
||||
#include <util/dynamic_arg.hpp>
|
||||
#include <util/regex.hpp>
|
||||
#include <data/filter.hpp>
|
||||
|
||||
DECLARE_POINTER_TYPE(KeywordParam);
|
||||
DECLARE_POINTER_TYPE(KeywordMode);
|
||||
@@ -116,7 +117,7 @@ class Keyword : public IntrusivePtrVirtualBase {
|
||||
void prepare(const vector<KeywordParamP>& param_types, bool force = false);
|
||||
|
||||
/// Does the keyword contain the given query word?
|
||||
bool contains(String const& word) const;
|
||||
bool contains(QuickFilterPart const& query) const;
|
||||
|
||||
DECLARE_REFLECTION();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user