mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-11 13:17:00 -04:00
Support for 2d bar graphs;
separator_after for keywords; Slightly more advanced english_plural/singular; Windows uninstaller will remove app data git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@348 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
+62
-27
@@ -38,6 +38,7 @@ IMPLEMENT_REFLECTION(KeywordParam) {
|
||||
REFLECT(optional);
|
||||
REFLECT(match);
|
||||
REFLECT(separator_before_is);
|
||||
REFLECT(separator_after_is);
|
||||
REFLECT(eat_separator);
|
||||
REFLECT(script);
|
||||
REFLECT(reminder_script);
|
||||
@@ -119,12 +120,20 @@ String KeywordParam::make_separator_before() const {
|
||||
return ret;
|
||||
}*/
|
||||
void KeywordParam::compile() {
|
||||
// compile separator_before
|
||||
if (!separator_before_is.empty() && !separator_before_re.IsValid()) {
|
||||
separator_before_re.Compile(_("^") + separator_before_is, wxRE_ADVANCED);
|
||||
if (eat_separator) {
|
||||
separator_before_eat.Compile(separator_before_is + _("$"), wxRE_ADVANCED);
|
||||
}
|
||||
}
|
||||
// compile separator_after
|
||||
if (!separator_after_is.empty() && !separator_after_re.IsValid()) {
|
||||
separator_after_re.Compile(separator_after_is + _("$"), wxRE_ADVANCED);
|
||||
if (eat_separator) {
|
||||
separator_after_eat.Compile(_("^") + separator_after_is, wxRE_ADVANCED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t Keyword::findMode(const vector<KeywordModeP>& modes) const {
|
||||
@@ -239,6 +248,12 @@ void Keyword::prepare(const vector<KeywordParamP>& param_types, bool force) {
|
||||
// modify regex : match parameter
|
||||
regex += _("(") + make_non_capturing(p->match) + (p->optional ? _(")?") : _(")"));
|
||||
i = skip_tag(match, end);
|
||||
// eat separator_after?
|
||||
if (p->separator_after_eat.IsValid() && p->separator_after_eat.Matches(match.substr(i))) {
|
||||
size_t start, len;
|
||||
p->separator_before_eat.GetMatch(&start, &len);
|
||||
i += start + len;
|
||||
}
|
||||
} else {
|
||||
text += c;
|
||||
i++;
|
||||
@@ -347,22 +362,28 @@ void KeywordDatabase::add(const Keyword& kw) {
|
||||
for (size_t i = 0 ; i < kw.match.size() ;) {
|
||||
Char c = kw.match.GetChar(i);
|
||||
if (is_substr(kw.match, i, _("<atom-param"))) {
|
||||
i = match_close_tag_end(kw.match, i);
|
||||
// parameter, is there a separator we should eat?
|
||||
if (param < kw.parameters.size()) {
|
||||
wxRegEx& sep = kw.parameters[param]->separator_before_eat;
|
||||
if (sep.IsValid() && sep.Matches(text)) {
|
||||
wxRegEx& sep_before = kw.parameters[param]->separator_before_eat;
|
||||
wxRegEx& sep_after = kw.parameters[param]->separator_after_eat;
|
||||
if (sep_before.IsValid() && sep_before.Matches(text)) {
|
||||
// remove the separator from the text to prevent duplicates
|
||||
size_t start, len;
|
||||
sep.GetMatch(&start, &len);
|
||||
sep_before.GetMatch(&start, &len);
|
||||
text = text.substr(0, start);
|
||||
}
|
||||
if (sep_after.IsValid() && sep_after.Matches(kw.match.substr(i))) {
|
||||
size_t start, len;
|
||||
sep_after.GetMatch(&start, &len);
|
||||
i += start + len;
|
||||
}
|
||||
}
|
||||
++param;
|
||||
// match anything
|
||||
cur = cur->insert(text);
|
||||
text.clear();
|
||||
cur = cur->insertAnyStar();
|
||||
i = match_close_tag_end(kw.match, i);
|
||||
} else {
|
||||
text += c;
|
||||
i++;
|
||||
@@ -501,27 +522,40 @@ String KeywordDatabase::expand(const String& text,
|
||||
// parameter
|
||||
KeywordParam& kwp = *kw->parameters[j/2-1];
|
||||
String param = untagged.substr(start_u, len_u); // untagged version
|
||||
// strip separator
|
||||
String separator;
|
||||
if (kwp.separator_before_re.IsValid()) {
|
||||
if (kwp.separator_before_re.Matches(param)) {
|
||||
size_t s_start, s_len; // start should be 0
|
||||
kwp.separator_before_re.GetMatch(&s_start, &s_len);
|
||||
separator = param.substr(0, s_start + s_len);
|
||||
param = param.substr(s_start + s_len);
|
||||
// strip from tagged version
|
||||
size_t end_t = untagged_to_index(part, s_start + s_len, false);
|
||||
part = get_tags(part, 0, end_t, true, true) + part.substr(end_t);
|
||||
// transform?
|
||||
if (kwp.separator_script) {
|
||||
ctx.setVariable(_("input"), to_script(separator));
|
||||
separator = kwp.separator_script.invoke(ctx)->toString();
|
||||
}
|
||||
// strip separator_before
|
||||
String separator_before, separator_after;
|
||||
if (kwp.separator_before_re.IsValid() && kwp.separator_before_re.Matches(param)) {
|
||||
size_t s_start, s_len; // start should be 0
|
||||
kwp.separator_before_re.GetMatch(&s_start, &s_len);
|
||||
separator_before = param.substr(0, s_start + s_len);
|
||||
param = param.substr(s_start + s_len);
|
||||
// strip from tagged version
|
||||
size_t end_t = untagged_to_index(part, s_start + s_len, false);
|
||||
part = get_tags(part, 0, end_t, true, true) + part.substr(end_t);
|
||||
// transform?
|
||||
if (kwp.separator_script) {
|
||||
ctx.setVariable(_("input"), to_script(separator_before));
|
||||
separator_before = kwp.separator_script.invoke(ctx)->toString();
|
||||
}
|
||||
}
|
||||
// strip separator_after
|
||||
if (kwp.separator_after_re.IsValid() && kwp.separator_after_re.Matches(param)) {
|
||||
size_t s_start, s_len; // start + len should be param.size()
|
||||
kwp.separator_after_re.GetMatch(&s_start, &s_len);
|
||||
separator_after = param.substr(s_start);
|
||||
param = param.substr(0, s_start);
|
||||
// strip from tagged version
|
||||
size_t start_t = untagged_to_index(part, s_start, false);
|
||||
part = part.substr(0, start_t) + get_tags(part, start_t, part.size(), true, true);
|
||||
// transform?
|
||||
if (kwp.separator_script) {
|
||||
ctx.setVariable(_("input"), to_script(separator_after));
|
||||
separator_after = kwp.separator_script.invoke(ctx)->toString();
|
||||
}
|
||||
}
|
||||
// to script
|
||||
KeywordParamValueP script_param(new KeywordParamValue(kwp.name, separator, param));
|
||||
KeywordParamValueP script_part (new KeywordParamValue(kwp.name, separator, part));
|
||||
KeywordParamValueP script_param(new KeywordParamValue(kwp.name, separator_before, separator_after, param));
|
||||
KeywordParamValueP script_part (new KeywordParamValue(kwp.name, separator_before, separator_after, part));
|
||||
// process param
|
||||
if (param.empty()) {
|
||||
// placeholder
|
||||
@@ -538,7 +572,7 @@ String KeywordDatabase::expand(const String& text,
|
||||
script_param->value = kwp.reminder_script.invoke(ctx)->toString();
|
||||
}
|
||||
}
|
||||
part = separator + script_part->toString();
|
||||
part = separator_before + script_part->toString() + separator_after;
|
||||
ctx.setVariable(String(_("param")) << (int)(j/2), script_param);
|
||||
}
|
||||
total += part;
|
||||
@@ -601,9 +635,10 @@ KeywordParamValue::operator String() const {
|
||||
return _("<param-") + safe_type + _(">") + value + _("</param-") + safe_type + _(">");
|
||||
}
|
||||
ScriptValueP KeywordParamValue::getMember(const String& name) const {
|
||||
if (name == _("type")) return to_script(type_name);
|
||||
if (name == _("separator")) return to_script(separator);
|
||||
if (name == _("value")) return to_script(value);
|
||||
if (name == _("param")) return to_script(value);
|
||||
if (name == _("type")) return to_script(type_name);
|
||||
if (name == _("separator before")) return to_script(separator_before);
|
||||
if (name == _("separator after")) return to_script(separator_after);
|
||||
if (name == _("value")) return to_script(value);
|
||||
if (name == _("param")) return to_script(value);
|
||||
return ScriptValue::getMember(name);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ class KeywordParam : public IntrusivePtrBase<KeywordParam> {
|
||||
String separator_before_is; ///< Regular expression of separator before the param
|
||||
wxRegEx separator_before_re; ///< Regular expression of separator before the param, compiled
|
||||
wxRegEx separator_before_eat;///< Regular expression of separator before the param, if eat_separator
|
||||
String separator_after_is; ///< Regular expression of separator after the param
|
||||
wxRegEx separator_after_re; ///< Regular expression of separator after the param, compiled
|
||||
wxRegEx separator_after_eat; ///< Regular expression of separator after the param, if eat_separator
|
||||
bool eat_separator; ///< Remove the separator from the match string if it also appears there (prevent duplicates)
|
||||
OptionalScript script; ///< Transformation of the value for showing as the parameter
|
||||
OptionalScript reminder_script; ///< Transformation of the value for showing in the reminder text
|
||||
@@ -53,7 +56,7 @@ class KeywordParam : public IntrusivePtrBase<KeywordParam> {
|
||||
//% /** This tries to decode the separator_before_is regex */
|
||||
//% String make_separator_before() const;
|
||||
|
||||
/// Compile regexes
|
||||
/// Compile regexes for separators
|
||||
void compile();
|
||||
|
||||
DECLARE_REFLECTION();
|
||||
@@ -150,11 +153,11 @@ class KeywordDatabase {
|
||||
/// A script value containing the value of a keyword parameter
|
||||
class KeywordParamValue : public ScriptValue {
|
||||
public:
|
||||
KeywordParamValue(const String& type, const String& separator, const String& value)
|
||||
: type_name(type), separator(separator), value(value)
|
||||
KeywordParamValue(const String& type, const String& separator_before, const String& separator_after, const String& value)
|
||||
: type_name(type), separator_before(separator_before), separator_after(separator_after), value(value)
|
||||
{}
|
||||
String type_name;
|
||||
String separator;
|
||||
String separator_before, separator_after;
|
||||
String value;
|
||||
|
||||
virtual ScriptType type() const;
|
||||
|
||||
+23
-1
@@ -10,6 +10,9 @@
|
||||
#include <data/field.hpp>
|
||||
#include <data/field/choice.hpp>
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(String);
|
||||
DECLARE_TYPEOF_COLLECTION(StatsDimensionP);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Statistics dimension
|
||||
|
||||
StatsDimension::StatsDimension()
|
||||
@@ -68,6 +71,7 @@ StatsCategory::StatsCategory(const StatsDimensionP& dim)
|
||||
|
||||
IMPLEMENT_REFLECTION_ENUM(GraphType) {
|
||||
VALUE_N("bar", GRAPH_TYPE_BAR);
|
||||
VALUE_N("stack", GRAPH_TYPE_STACK);
|
||||
VALUE_N("pie", GRAPH_TYPE_PIE);
|
||||
VALUE_N("scatter", GRAPH_TYPE_SCATTER);
|
||||
}
|
||||
@@ -78,6 +82,24 @@ IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsCategory) {
|
||||
REFLECT(description);
|
||||
REFLECT_N("icon", icon_filename);
|
||||
REFLECT(type);
|
||||
REFLECT(dimensions);
|
||||
REFLECT_N("dimensions", dimension_names);
|
||||
}
|
||||
}
|
||||
|
||||
void StatsCategory::find_dimensions(const vector<StatsDimensionP>& available) {
|
||||
if (!dimensions.empty()) return;
|
||||
FOR_EACH_CONST(n, dimension_names) {
|
||||
StatsDimensionP dim;
|
||||
FOR_EACH_CONST(d, available) {
|
||||
if (d->name == n) {
|
||||
dim = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!dim) {
|
||||
handle_error(_ERROR_1_("dimension not found",dim),false);
|
||||
} else {
|
||||
dimensions.push_back(dim);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ class StatsDimension : public IntrusivePtrBase<StatsDimension> {
|
||||
/// Types of graphs
|
||||
enum GraphType
|
||||
{ GRAPH_TYPE_BAR
|
||||
, GRAPH_TYPE_STACK
|
||||
, GRAPH_TYPE_PIE
|
||||
, GRAPH_TYPE_SCATTER
|
||||
};
|
||||
@@ -59,9 +60,13 @@ class StatsCategory : public IntrusivePtrBase<StatsCategory> {
|
||||
String description; ///< Description, used in status bar
|
||||
String icon_filename; ///< Icon for lists
|
||||
Bitmap icon; ///< The loaded icon (optional of course)
|
||||
vector<StatsDimensionP> dimensions; ///< The dimensions to use, higher dimensions may be null
|
||||
vector<String> dimension_names;///< Names of the dimensions to use
|
||||
vector<StatsDimensionP> dimensions; ///< Actual dimensions
|
||||
GraphType type; ///< Type of graph to use
|
||||
|
||||
/// Initialize dimensions from dimension_names
|
||||
void find_dimensions(const vector<StatsDimensionP>& available);
|
||||
|
||||
DECLARE_REFLECTION();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user