mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-13 14:07:01 -04:00
Fixed undo issue for combined editor;
Added keyword usage statistics git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@516 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
class Game;
|
class Game;
|
||||||
class Dependency;
|
class Dependency;
|
||||||
|
class Keyword;
|
||||||
DECLARE_POINTER_TYPE(Card);
|
DECLARE_POINTER_TYPE(Card);
|
||||||
DECLARE_POINTER_TYPE(Field);
|
DECLARE_POINTER_TYPE(Field);
|
||||||
DECLARE_POINTER_TYPE(Value);
|
DECLARE_POINTER_TYPE(Value);
|
||||||
@@ -50,6 +51,9 @@ class Card : public IntrusivePtrVirtualBase {
|
|||||||
/// Styling information for a particular stylesheet
|
/// Styling information for a particular stylesheet
|
||||||
IndexMap<FieldP, ValueP>& extraDataFor(const StyleSheet& stylesheet) ;
|
IndexMap<FieldP, ValueP>& extraDataFor(const StyleSheet& stylesheet) ;
|
||||||
|
|
||||||
|
/// Keyword usage statistics
|
||||||
|
vector<pair<Value*,const Keyword*> > keyword_usage;
|
||||||
|
|
||||||
/// Get the identification of this card, an identification is something like a name, title, etc.
|
/// Get the identification of this card, an identification is something like a name, title, etc.
|
||||||
/** May return "" */
|
/** May return "" */
|
||||||
String identification() const;
|
String identification() const;
|
||||||
|
|||||||
@@ -199,6 +199,8 @@ StyleListener::~StyleListener() {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Value
|
// ----------------------------------------------------------------------------- : Value
|
||||||
|
|
||||||
|
IMPLEMENT_DYNAMIC_ARG(Value*, value_being_updated, nullptr);
|
||||||
|
|
||||||
Value::~Value() {}
|
Value::~Value() {}
|
||||||
|
|
||||||
IMPLEMENT_REFLECTION_NAMELESS(Value) {
|
IMPLEMENT_REFLECTION_NAMELESS(Value) {
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ class DataViewer; class DataEditor;
|
|||||||
DECLARE_POINTER_TYPE(ValueViewer);
|
DECLARE_POINTER_TYPE(ValueViewer);
|
||||||
DECLARE_POINTER_TYPE(ValueEditor);
|
DECLARE_POINTER_TYPE(ValueEditor);
|
||||||
|
|
||||||
|
// Value for which script updates are being run
|
||||||
|
DECLARE_DYNAMIC_ARG(Value*, value_being_updated);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Field
|
// ----------------------------------------------------------------------------- : Field
|
||||||
|
|
||||||
/// Information on how to store a value
|
/// Information on how to store a value
|
||||||
|
|||||||
@@ -119,7 +119,8 @@ String TextValue::toString() const {
|
|||||||
}
|
}
|
||||||
bool TextValue::update(Context& ctx) {
|
bool TextValue::update(Context& ctx) {
|
||||||
Value::update(ctx);
|
Value::update(ctx);
|
||||||
WITH_DYNAMIC_ARG(last_update_age, value.isDefault() ? 0 : last_update.get());
|
WITH_DYNAMIC_ARG(last_update_age, last_update.get());
|
||||||
|
WITH_DYNAMIC_ARG(value_being_updated, this);
|
||||||
bool change = field().default_script.invokeOnDefault(ctx, value)
|
bool change = field().default_script.invokeOnDefault(ctx, value)
|
||||||
| field(). script.invokeOn(ctx, value);
|
| field(). script.invokeOn(ctx, value);
|
||||||
if (change) last_update.update();
|
if (change) last_update.update();
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class TextStyle : public Style {
|
|||||||
/// The Value in a TextField
|
/// The Value in a TextField
|
||||||
class TextValue : public Value {
|
class TextValue : public Value {
|
||||||
public:
|
public:
|
||||||
inline TextValue(const TextFieldP& field) : Value(field) {}
|
inline TextValue(const TextFieldP& field) : Value(field), last_update(1) {}
|
||||||
DECLARE_HAS_FIELD(Text)
|
DECLARE_HAS_FIELD(Text)
|
||||||
|
|
||||||
typedef Defaultable<String> ValueType;
|
typedef Defaultable<String> ValueType;
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ DECLARE_TYPEOF_COLLECTION(KeywordModeP);
|
|||||||
DECLARE_TYPEOF_COLLECTION(KeywordParamP);
|
DECLARE_TYPEOF_COLLECTION(KeywordParamP);
|
||||||
DECLARE_TYPEOF_COLLECTION(const Keyword*);
|
DECLARE_TYPEOF_COLLECTION(const Keyword*);
|
||||||
DECLARE_POINTER_TYPE(KeywordParamValue);
|
DECLARE_POINTER_TYPE(KeywordParamValue);
|
||||||
|
class Value;
|
||||||
|
DECLARE_DYNAMIC_ARG(Value*, value_being_updated);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Reflection
|
// ----------------------------------------------------------------------------- : Reflection
|
||||||
|
|
||||||
@@ -329,6 +331,8 @@ KeywordTrie* KeywordTrie::insertAnyStar() {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : KeywordDatabase
|
// ----------------------------------------------------------------------------- : KeywordDatabase
|
||||||
|
|
||||||
|
IMPLEMENT_DYNAMIC_ARG(KeywordUsageStatistics*, keyword_usage_statistics, nullptr);
|
||||||
|
|
||||||
KeywordDatabase::KeywordDatabase()
|
KeywordDatabase::KeywordDatabase()
|
||||||
: root(nullptr)
|
: root(nullptr)
|
||||||
{}
|
{}
|
||||||
@@ -440,6 +444,17 @@ String KeywordDatabase::expand(const String& text,
|
|||||||
Context& ctx) const {
|
Context& ctx) const {
|
||||||
assert(combine_script);
|
assert(combine_script);
|
||||||
|
|
||||||
|
// Clean up usage statistics
|
||||||
|
KeywordUsageStatistics* stat = keyword_usage_statistics();
|
||||||
|
Value* stat_key = value_being_updated();
|
||||||
|
if (stat && stat_key) {
|
||||||
|
for (size_t i = stat->size() - 1 ; i + 1 > 0 ; --i) { // loop backwards
|
||||||
|
if ((*stat)[i].first == stat_key) {
|
||||||
|
stat->erase(stat->begin() + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove all old reminder texts
|
// Remove all old reminder texts
|
||||||
String s = remove_tag_contents(text, _("<atom-reminder"));
|
String s = remove_tag_contents(text, _("<atom-reminder"));
|
||||||
s = remove_tag_contents(s, _("<atom-keyword")); // OLD, TODO: REMOVEME
|
s = remove_tag_contents(s, _("<atom-keyword")); // OLD, TODO: REMOVEME
|
||||||
@@ -614,6 +629,11 @@ String KeywordDatabase::expand(const String& text,
|
|||||||
result += _("</kw-"); result += expand_type; result += _(">");
|
result += _("</kw-"); result += expand_type; result += _(">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add to usage statistics
|
||||||
|
if (stat && stat_key) {
|
||||||
|
stat->push_back(make_pair(stat_key, kw));
|
||||||
|
}
|
||||||
|
|
||||||
// After keyword
|
// After keyword
|
||||||
s = s.substr(end);
|
s = s.substr(end);
|
||||||
untagged = untagged.substr(start_u + len_u);
|
untagged = untagged.substr(start_u + len_u);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
#include <script/scriptable.hpp>
|
#include <script/scriptable.hpp>
|
||||||
|
#include <util/dynamic_arg.hpp>
|
||||||
#include <wx/regex.h>
|
#include <wx/regex.h>
|
||||||
|
|
||||||
DECLARE_POINTER_TYPE(KeywordParam);
|
DECLARE_POINTER_TYPE(KeywordParam);
|
||||||
@@ -18,6 +19,7 @@ DECLARE_POINTER_TYPE(KeywordMode);
|
|||||||
DECLARE_POINTER_TYPE(Keyword);
|
DECLARE_POINTER_TYPE(Keyword);
|
||||||
DECLARE_POINTER_TYPE(ParamReferenceType);
|
DECLARE_POINTER_TYPE(ParamReferenceType);
|
||||||
class KeywordTrie;
|
class KeywordTrie;
|
||||||
|
class Value;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Keyword parameters
|
// ----------------------------------------------------------------------------- : Keyword parameters
|
||||||
|
|
||||||
@@ -115,6 +117,10 @@ class Keyword : public IntrusivePtrVirtualBase {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Using keywords
|
// ----------------------------------------------------------------------------- : Using keywords
|
||||||
|
|
||||||
|
/// Store keyword usage statistics here, using value_being_updated as the key
|
||||||
|
typedef vector<pair<Value*, const Keyword*> > KeywordUsageStatistics;
|
||||||
|
DECLARE_DYNAMIC_ARG(KeywordUsageStatistics*, keyword_usage_statistics);
|
||||||
|
|
||||||
/// A database of keywords to allow for fast matching
|
/// A database of keywords to allow for fast matching
|
||||||
/** NOTE: keywords may not be altered after they are added to the database,
|
/** NOTE: keywords may not be altered after they are added to the database,
|
||||||
* The database should be rebuild.
|
* The database should be rebuild.
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <gui/icon_menu.hpp>
|
#include <gui/icon_menu.hpp>
|
||||||
#include <data/set.hpp>
|
#include <data/set.hpp>
|
||||||
#include <data/game.hpp>
|
#include <data/game.hpp>
|
||||||
|
#include <data/card.hpp>
|
||||||
#include <data/keyword.hpp>
|
#include <data/keyword.hpp>
|
||||||
#include <data/action/value.hpp>
|
#include <data/action/value.hpp>
|
||||||
#include <data/action/keyword.hpp>
|
#include <data/action/keyword.hpp>
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
#include <wx/clipbrd.h>
|
#include <wx/clipbrd.h>
|
||||||
|
|
||||||
DECLARE_TYPEOF_COLLECTION(KeywordP);
|
DECLARE_TYPEOF_COLLECTION(KeywordP);
|
||||||
|
DECLARE_TYPEOF_COLLECTION(CardP);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Events
|
// ----------------------------------------------------------------------------- : Events
|
||||||
|
|
||||||
@@ -49,6 +51,7 @@ void KeywordList::onBeforeChangeSet() {
|
|||||||
storeColumns();
|
storeColumns();
|
||||||
}
|
}
|
||||||
void KeywordList::onChangeSet() {
|
void KeywordList::onChangeSet() {
|
||||||
|
updateUsageStatistics();
|
||||||
refreshList();
|
refreshList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +86,15 @@ void KeywordList::onAction(const Action& action, bool undone) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KeywordList::updateUsageStatistics() {
|
||||||
|
usage_statistics.clear();
|
||||||
|
FOR_EACH_CONST(card, set->cards) {
|
||||||
|
for (KeywordUsageStatistics::const_iterator it = card->keyword_usage.begin() ; it != card->keyword_usage.end() ; ++it) {
|
||||||
|
usage_statistics[it->second]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Clipboard
|
// ----------------------------------------------------------------------------- : Clipboard
|
||||||
|
|
||||||
bool KeywordList::canCopy() const { return !!selected_item; }
|
bool KeywordList::canCopy() const { return !!selected_item; }
|
||||||
@@ -154,13 +166,19 @@ bool KeywordList::compareItems(void* a, void* b) const {
|
|||||||
case 0: return ka.keyword < kb.keyword;
|
case 0: return ka.keyword < kb.keyword;
|
||||||
case 1: return ka.match < kb.match;
|
case 1: return ka.match < kb.match;
|
||||||
case 2: return ka.mode < kb.mode;
|
case 2: return ka.mode < kb.mode;
|
||||||
//case 3:
|
case 3: return usage(ka) < usage(kb);
|
||||||
case 4: return ka.reminder.getUnparsed() < kb.reminder.getUnparsed();
|
case 4: return ka.reminder.getUnparsed() < kb.reminder.getUnparsed();
|
||||||
default: // TODO: 3
|
default: // TODO: 3
|
||||||
return ka.keyword < kb.keyword;
|
return ka.keyword < kb.keyword;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int KeywordList::usage(const Keyword& kw) const {
|
||||||
|
map<const Keyword*,int>::const_iterator it = usage_statistics.find(&kw);
|
||||||
|
if (it == usage_statistics.end()) return 0;
|
||||||
|
else return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : KeywordList : Item text
|
// ----------------------------------------------------------------------------- : KeywordList : Item text
|
||||||
|
|
||||||
String KeywordList::OnGetItemText (long pos, long col) const {
|
String KeywordList::OnGetItemText (long pos, long col) const {
|
||||||
@@ -169,7 +187,7 @@ String KeywordList::OnGetItemText (long pos, long col) const {
|
|||||||
case 0: return kw.keyword;
|
case 0: return kw.keyword;
|
||||||
case 1: return match_string(kw);
|
case 1: return match_string(kw);
|
||||||
case 2: return kw.mode;
|
case 2: return kw.mode;
|
||||||
case 3: return _("?");
|
case 3: return String::Format(_("%d"), usage(kw));
|
||||||
case 4: {
|
case 4: {
|
||||||
// convert all whitespace to ' '
|
// convert all whitespace to ' '
|
||||||
String formatted;
|
String formatted;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class KeywordList : public ItemList, public SetView {
|
|||||||
virtual void onBeforeChangeSet();
|
virtual void onBeforeChangeSet();
|
||||||
virtual void onChangeSet();
|
virtual void onChangeSet();
|
||||||
virtual void onAction(const Action&, bool);
|
virtual void onAction(const Action&, bool);
|
||||||
|
void updateUsageStatistics();
|
||||||
|
|
||||||
// --------------------------------------------------- : Selection
|
// --------------------------------------------------- : Selection
|
||||||
|
|
||||||
@@ -86,6 +87,10 @@ class KeywordList : public ItemList, public SetView {
|
|||||||
|
|
||||||
mutable wxListItemAttr item_attr; // for OnGetItemAttr
|
mutable wxListItemAttr item_attr; // for OnGetItemAttr
|
||||||
|
|
||||||
|
/// How often is a keyword used in the set?
|
||||||
|
int usage(const Keyword&) const;
|
||||||
|
map<const Keyword*,int> usage_statistics;
|
||||||
|
|
||||||
// --------------------------------------------------- : Window events
|
// --------------------------------------------------- : Window events
|
||||||
DECLARE_EVENT_TABLE();
|
DECLARE_EVENT_TABLE();
|
||||||
|
|
||||||
|
|||||||
@@ -285,6 +285,8 @@ SCRIPT_RULE_2_N_DEP(expand_keywords, ScriptValueP, _("default expand"), default_
|
|||||||
db.add(set->game->keywords);
|
db.add(set->game->keywords);
|
||||||
db.add(set->keywords);
|
db.add(set->keywords);
|
||||||
}
|
}
|
||||||
|
SCRIPT_OPTIONAL_PARAM_(CardP, card);
|
||||||
|
WITH_DYNAMIC_ARG(keyword_usage_statistics, card ? &card->keyword_usage : nullptr);
|
||||||
SCRIPT_RETURN(db.expand(input, default_expand, combine, ctx));
|
SCRIPT_RETURN(db.expand(input, default_expand, combine, ctx));
|
||||||
}
|
}
|
||||||
SCRIPT_RULE_2_DEPENDENCIES(expand_keywords) {
|
SCRIPT_RULE_2_DEPENDENCIES(expand_keywords) {
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@
|
|||||||
/** Age is counted using a global variable */
|
/** Age is counted using a global variable */
|
||||||
class Age {
|
class Age {
|
||||||
public:
|
public:
|
||||||
/// Construct a new age value,
|
/// Construct a new age value
|
||||||
Age() {
|
Age() {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user