mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Added validator for locales based on all strings in the source code.
It checks: - whether all keys used by the program are in the locale - whether the right number of %s are used - if there are no extra keys in the locale that shouldn't be there This will become very useful when translations need to be updated for new MSE versions. There is a perl script for generating the 'expected_locale_keys' resource file. This file contains a list of all the locale keys used. This is a resource and not a data file because it is automatically generated from the code, the user has no business modifying it. I also fixed all the locale errors I found in the process. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@613 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -207,7 +207,7 @@ help:
|
|||||||
overlap: Place this shape, and its border above shapes below it
|
overlap: Place this shape, and its border above shapes below it
|
||||||
border: Draws this shape as a border
|
border: Draws this shape as a border
|
||||||
|
|
||||||
drag to shear: Drag to shear selected shape
|
drag to shear: Drag to shear selected %s
|
||||||
drag to rotate: Drag to rotate selected %s, Ctrl constrains angle to multiples of 15 degrees
|
drag to rotate: Drag to rotate selected %s, Ctrl constrains angle to multiples of 15 degrees
|
||||||
drag to resize: Drag to resize selected %s, Ctrl constrains size
|
drag to resize: Drag to resize selected %s, Ctrl constrains size
|
||||||
click to select shape: Click to select shape, drag to move shape, double click to edit shape
|
click to select shape: Click to select shape, drag to move shape, double click to edit shape
|
||||||
@@ -421,7 +421,7 @@ label:
|
|||||||
|
|
||||||
# apprentice export
|
# apprentice export
|
||||||
set code: Set &Code:
|
set code: Set &Code:
|
||||||
apprentice export cancled: Export to Apprentice is cancled
|
apprentice export cancelled: Export to Apprentice is cancelled
|
||||||
|
|
||||||
# Html export
|
# Html export
|
||||||
html template: Template:
|
html template: Template:
|
||||||
@@ -516,7 +516,7 @@ title:
|
|||||||
print preview: Print Preview
|
print preview: Print Preview
|
||||||
# export
|
# export
|
||||||
export images: Export Images
|
export images: Export Images
|
||||||
export cancled: Export Cancled
|
export cancelled: Export Cancelled
|
||||||
export html: Export to HTML
|
export html: Export to HTML
|
||||||
save html: Export to HTML
|
save html: Export to HTML
|
||||||
|
|
||||||
@@ -530,8 +530,13 @@ title:
|
|||||||
action:
|
action:
|
||||||
# Text editor
|
# Text editor
|
||||||
typing: Typing
|
typing: Typing
|
||||||
|
enter: Enter
|
||||||
|
soft line break: Soft line break
|
||||||
|
insert symbol: Insert symbol
|
||||||
backspace: Backspace
|
backspace: Backspace
|
||||||
delete: Delete
|
delete: Delete
|
||||||
|
cut: Cut
|
||||||
|
paste: Paste
|
||||||
# Choice/color editors
|
# Choice/color editors
|
||||||
change: Change %s
|
change: Change %s
|
||||||
|
|
||||||
@@ -561,7 +566,7 @@ action:
|
|||||||
|
|
||||||
# Symmetry
|
# Symmetry
|
||||||
add symmetry: Add symmetry
|
add symmetry: Add symmetry
|
||||||
remove symmetry: Remove symmetry
|
#remove symmetry: Remove symmetry
|
||||||
move symmetry center: Move symmetry center
|
move symmetry center: Move symmetry center
|
||||||
move symmetry handle: Change symmetry orientation
|
move symmetry handle: Change symmetry orientation
|
||||||
change symmetry type: Change symmetry type
|
change symmetry type: Change symmetry type
|
||||||
@@ -597,7 +602,6 @@ error:
|
|||||||
has no member value: String "%s" has no member '%s'
|
has no member value: String "%s" has no member '%s'
|
||||||
can't convert value: Can't convert "%s" from %s to %s
|
can't convert value: Can't convert "%s" from %s to %s
|
||||||
unsupported format: Invalid string format: '%s'
|
unsupported format: Invalid string format: '%s'
|
||||||
can not sort: I don't know how to sort a %s
|
|
||||||
|
|
||||||
# Image stuff
|
# Image stuff
|
||||||
coordinates for blending overlap: Coordinates for blending overlap
|
coordinates for blending overlap: Coordinates for blending overlap
|
||||||
@@ -638,7 +642,7 @@ type:
|
|||||||
collection: collection
|
collection: collection
|
||||||
collection of: collection of %ss
|
collection of: collection of %ss
|
||||||
object: object
|
object: object
|
||||||
real: real number
|
double: real number
|
||||||
integer: integer number
|
integer: integer number
|
||||||
string: string
|
string: string
|
||||||
boolean: boolean
|
boolean: boolean
|
||||||
@@ -675,7 +679,6 @@ type:
|
|||||||
|
|
||||||
point: point
|
point: point
|
||||||
points: points
|
points: points
|
||||||
handle: handle
|
|
||||||
|
|
||||||
# Package manager
|
# Package manager
|
||||||
installed: installed
|
installed: installed
|
||||||
|
|||||||
+1
-1
@@ -82,7 +82,7 @@ intrusive_ptr<Field> read_new<Field>(Reader& reader) {
|
|||||||
reader.warning(_ERROR_1_("expected key", _("type")));
|
reader.warning(_ERROR_1_("expected key", _("type")));
|
||||||
throw ParseError(_ERROR_("aborting parsing"));
|
throw ParseError(_ERROR_("aborting parsing"));
|
||||||
} else {
|
} else {
|
||||||
reader.warning(_ERROR_1_("Unsupported field type", type));
|
reader.warning(_ERROR_1_("unsupported field type", type));
|
||||||
throw ParseError(_ERROR_("aborting parsing"));
|
throw ParseError(_ERROR_("aborting parsing"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -697,7 +697,7 @@ void ApprenticeExportWindow::onOk(wxCommandEvent& ev) {
|
|||||||
}
|
}
|
||||||
} catch (const AbortException&) {
|
} catch (const AbortException&) {
|
||||||
// aborted, cleanup is already handled by dtors
|
// aborted, cleanup is already handled by dtors
|
||||||
wxMessageBox(_LABEL_("apprentice export cancled"), _TITLE_("export canceled"), wxOK | wxICON_INFORMATION);
|
wxMessageBox(_LABEL_("apprentice export cancelled"), _TITLE_("export cancelled"), wxOK | wxICON_INFORMATION);
|
||||||
}
|
}
|
||||||
// Done, close progress window
|
// Done, close progress window
|
||||||
progress_target->Hide();
|
progress_target->Hide();
|
||||||
|
|||||||
@@ -13,6 +13,11 @@
|
|||||||
#include <util/io/package_manager.hpp>
|
#include <util/io/package_manager.hpp>
|
||||||
#include <script/to_value.hpp>
|
#include <script/to_value.hpp>
|
||||||
|
|
||||||
|
#include <wx/stdpaths.h>
|
||||||
|
#if defined(__WXMSW__)
|
||||||
|
#include <wx/mstream.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Locale class
|
// ----------------------------------------------------------------------------- : Locale class
|
||||||
|
|
||||||
LocaleP the_locale;
|
LocaleP the_locale;
|
||||||
@@ -109,3 +114,148 @@ String tr(const SymbolFont& f, const String& key, const String& def) {
|
|||||||
if (!loc) return def; // no information on this symbol font
|
if (!loc) return def; // no information on this symbol font
|
||||||
return loc->tr(key, def);
|
return loc->tr(key, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Validation
|
||||||
|
|
||||||
|
DECLARE_POINTER_TYPE(SubLocaleValidator);
|
||||||
|
|
||||||
|
class KeyValidator {
|
||||||
|
public:
|
||||||
|
int args;
|
||||||
|
bool optional;
|
||||||
|
DECLARE_REFLECTION();
|
||||||
|
};
|
||||||
|
|
||||||
|
class SubLocaleValidator : public IntrusivePtrBase<SubLocaleValidator> {
|
||||||
|
public:
|
||||||
|
map<String,KeyValidator> keys; ///< Arg count for each key
|
||||||
|
DECLARE_REFLECTION();
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Validation information for locales
|
||||||
|
class LocaleValidator {
|
||||||
|
public:
|
||||||
|
map<String, SubLocaleValidatorP> sublocales;
|
||||||
|
DECLARE_REFLECTION();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> void Reader::handle(KeyValidator& k) {
|
||||||
|
String v = getValue();
|
||||||
|
if (starts_with(v, _("optional, "))) {
|
||||||
|
k.optional = true;
|
||||||
|
v = v.substr(10);
|
||||||
|
} else {
|
||||||
|
k.optional = false;
|
||||||
|
}
|
||||||
|
long l = 0;
|
||||||
|
v.ToLong(&l);
|
||||||
|
k.args = l;
|
||||||
|
}
|
||||||
|
template <> void Writer::handle(const KeyValidator& v) {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
IMPLEMENT_REFLECTION_NO_SCRIPT(SubLocaleValidator) {
|
||||||
|
REFLECT_NAMELESS(keys);
|
||||||
|
}
|
||||||
|
IMPLEMENT_REFLECTION_NO_SCRIPT(LocaleValidator) {
|
||||||
|
REFLECT_NAMELESS(sublocales);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Count "%s" in str
|
||||||
|
int string_format_args(const String& str) {
|
||||||
|
int count = 0;
|
||||||
|
bool in_percent = false;
|
||||||
|
FOR_EACH_CONST(c, str) {
|
||||||
|
if (in_percent) {
|
||||||
|
if (c == _('s')) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
in_percent = false;
|
||||||
|
} else if (c == _('%')) {
|
||||||
|
in_percent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a text file from a resource
|
||||||
|
/** TODO: Move me
|
||||||
|
*/
|
||||||
|
InputStreamP load_resource_text(const String& name);
|
||||||
|
InputStreamP load_resource_text(const String& name) {
|
||||||
|
#if defined(__WXMSW__)
|
||||||
|
HRSRC hResource = ::FindResource(wxGetInstance(), name, _("TEXT"));
|
||||||
|
if ( hResource == 0 ) throw InternalError(String::Format(_("Resource not found: %s"), name));
|
||||||
|
HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
|
||||||
|
if ( hData == 0 ) throw InternalError(String::Format(_("Resource not text: %s"), name));
|
||||||
|
char* data = (char *)::LockResource(hData);
|
||||||
|
if ( !data ) throw InternalError(String::Format(_("Resource cannot be locked: %s"), name));
|
||||||
|
int len = ::SizeofResource(wxGetInstance(), hResource);
|
||||||
|
return new_shared2<wxMemoryInputStream>(data, len);
|
||||||
|
#else
|
||||||
|
static String path = wxStandardPaths::Get().GetDataDir() + _("/resource/") + name;
|
||||||
|
return new_shared1<wxFileInputStream>(path);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DECLARE_TYPEOF(map<String COMMA String>);
|
||||||
|
DECLARE_TYPEOF(map<String COMMA KeyValidator>);
|
||||||
|
|
||||||
|
void Locale::validate(Version ver) {
|
||||||
|
// load locale validator
|
||||||
|
LocaleValidator v;
|
||||||
|
Reader r(load_resource_text(_("expected_locale_keys")), _("expected_locale_keys"));
|
||||||
|
r.handle_greedy(v);
|
||||||
|
// validate
|
||||||
|
String errors;
|
||||||
|
errors += translations[LOCALE_CAT_MENU ].validate(_("menu"), *v.sublocales[_("menu") ]);
|
||||||
|
errors += translations[LOCALE_CAT_HELP ].validate(_("help"), *v.sublocales[_("help") ]);
|
||||||
|
errors += translations[LOCALE_CAT_TOOL ].validate(_("tool"), *v.sublocales[_("tool") ]);
|
||||||
|
errors += translations[LOCALE_CAT_TOOLTIP].validate(_("tooltip"), *v.sublocales[_("tooltip")]);
|
||||||
|
errors += translations[LOCALE_CAT_LABEL ].validate(_("label"), *v.sublocales[_("label") ]);
|
||||||
|
errors += translations[LOCALE_CAT_BUTTON ].validate(_("button"), *v.sublocales[_("button") ]);
|
||||||
|
errors += translations[LOCALE_CAT_TITLE ].validate(_("title"), *v.sublocales[_("title") ]);
|
||||||
|
errors += translations[LOCALE_CAT_ACTION ].validate(_("action"), *v.sublocales[_("action") ]);
|
||||||
|
errors += translations[LOCALE_CAT_ERROR ].validate(_("error"), *v.sublocales[_("error") ]);
|
||||||
|
errors += translations[LOCALE_CAT_TYPE ].validate(_("type"), *v.sublocales[_("type") ]);
|
||||||
|
// errors?
|
||||||
|
if (!errors.empty()) {
|
||||||
|
if (ver != app_version) {
|
||||||
|
errors = _("Errors in locale file ") + short_name + _(":") + errors;
|
||||||
|
} else {
|
||||||
|
errors = _("Errors in locale file ") + short_name +
|
||||||
|
_("\nThis is probably because the locale was made for a different version of MSE.") + errors;
|
||||||
|
}
|
||||||
|
handle_warning(errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String SubLocale::validate(const String& name, const SubLocaleValidator& v) const {
|
||||||
|
String errors;
|
||||||
|
// 1. keys in v but not in this, check arg count
|
||||||
|
FOR_EACH_CONST(kc, v.keys) {
|
||||||
|
map<String,String>::const_iterator it = translations.find(kc.first);
|
||||||
|
if (it == translations.end()) {
|
||||||
|
if (!kc.second.optional) {
|
||||||
|
errors += _("\n Missing key:\t\t\t") + name + _(": ") + kc.first;
|
||||||
|
}
|
||||||
|
} else if (string_format_args(it->second) != kc.second.args) {
|
||||||
|
errors += _("\n Incorrect number of arguments for:\t") + name + _(": ") + kc.first
|
||||||
|
+ String::Format(_("\t expected: %d, found %d"), kc.second.args, string_format_args(it->second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 2. keys in this but not in v
|
||||||
|
FOR_EACH_CONST(kv, translations) {
|
||||||
|
map<String,KeyValidator>::const_iterator it = v.keys.find(kv.first);
|
||||||
|
if (it == v.keys.end() && !kv.second.empty()) {
|
||||||
|
// allow extra keys with empty values as a kind of documentation
|
||||||
|
// for example in the help stirngs:
|
||||||
|
// help:
|
||||||
|
// file:
|
||||||
|
// new set: blah blah
|
||||||
|
errors += _("\n Unexpected key:\t\t\t") + name + _(": ") + kv.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
DECLARE_POINTER_TYPE(Locale);
|
DECLARE_POINTER_TYPE(Locale);
|
||||||
DECLARE_POINTER_TYPE(SubLocale);
|
DECLARE_POINTER_TYPE(SubLocale);
|
||||||
|
class SubLocaleValidator;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Locale class
|
// ----------------------------------------------------------------------------- : Locale class
|
||||||
|
|
||||||
@@ -29,6 +30,9 @@ class SubLocale : public IntrusivePtrBase<SubLocale> {
|
|||||||
/// Translate a key with a default value
|
/// Translate a key with a default value
|
||||||
String tr(const String& key, const String& def);
|
String tr(const String& key, const String& def);
|
||||||
|
|
||||||
|
/// Is this a valid sublocale? Returns errors
|
||||||
|
String validate(const String& name, const SubLocaleValidator&) const;
|
||||||
|
|
||||||
DECLARE_REFLECTION();
|
DECLARE_REFLECTION();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,6 +51,9 @@ class Locale : public Packaged {
|
|||||||
/// Open a locale with the given name
|
/// Open a locale with the given name
|
||||||
static LocaleP byName(const String& name);
|
static LocaleP byName(const String& name);
|
||||||
|
|
||||||
|
/// Validate that the locale is valid for this MSE version
|
||||||
|
virtual void validate(Version = app_version);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
String typeName() const;
|
String typeName() const;
|
||||||
DECLARE_REFLECTION();
|
DECLARE_REFLECTION();
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ class KeywordList : public ItemList, public SetView {
|
|||||||
|
|
||||||
/// Send an 'item selected' event for the currently selected item (selected_item)
|
/// Send an 'item selected' event for the currently selected item (selected_item)
|
||||||
virtual void sendEvent();
|
virtual void sendEvent();
|
||||||
/// Compare cards
|
/// Compare keywords
|
||||||
virtual bool compareItems(void* a, void* b) const;
|
virtual bool compareItems(void* a, void* b) const;
|
||||||
|
|
||||||
/// Get the text of an item in a specific column
|
/// Get the text of an item in a specific column
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ SetWindow::SetWindow(Window* parent, const SetP& set)
|
|||||||
addPanel(menuWindow, tabBar, new StylePanel (this, wxID_ANY), 2, _("window_style"), _("style tab"));
|
addPanel(menuWindow, tabBar, new StylePanel (this, wxID_ANY), 2, _("window_style"), _("style tab"));
|
||||||
addPanel(menuWindow, tabBar, new KeywordsPanel(this, wxID_ANY), 3, _("window_keywords"), _("keywords tab"));
|
addPanel(menuWindow, tabBar, new KeywordsPanel(this, wxID_ANY), 3, _("window_keywords"), _("keywords tab"));
|
||||||
addPanel(menuWindow, tabBar, new StatsPanel (this, wxID_ANY), 4, _("window_statistics"), _("stats tab"));
|
addPanel(menuWindow, tabBar, new StatsPanel (this, wxID_ANY), 4, _("window_statistics"), _("stats tab"));
|
||||||
// addPanel(*s, *menuWindow, *tabBar, new DraftPanel (&this, wxID_ANY), 5, _("F10"))
|
// addPanel(menuWindow, tabBar, new DraftPanel (this, wxID_ANY), 5, _("window_draft"), _("draft tab"))
|
||||||
selectPanel(ID_WINDOW_CARDS); // select cards panel
|
selectPanel(ID_WINDOW_CARDS); // select cards panel
|
||||||
|
|
||||||
// loose ends
|
// loose ends
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ bool TextValueEditor::onChar(wxKeyEvent& ev) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
replaceSelection(wxEmptyString, _("Backspace"));
|
replaceSelection(wxEmptyString, _ACTION_("backspace"));
|
||||||
break;
|
break;
|
||||||
case WXK_DELETE:
|
case WXK_DELETE:
|
||||||
if (selection_start == selection_end) {
|
if (selection_start == selection_end) {
|
||||||
@@ -188,15 +188,15 @@ bool TextValueEditor::onChar(wxKeyEvent& ev) {
|
|||||||
moveSelection(TYPE_CURSOR, nextCharBoundry(selection_end), true, MOVE_RIGHT);
|
moveSelection(TYPE_CURSOR, nextCharBoundry(selection_end), true, MOVE_RIGHT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
replaceSelection(wxEmptyString, _("Delete"));
|
replaceSelection(wxEmptyString, _ACTION_("delete"));
|
||||||
break;
|
break;
|
||||||
case WXK_RETURN:
|
case WXK_RETURN:
|
||||||
if (field().multi_line) {
|
if (field().multi_line) {
|
||||||
if (ev.ShiftDown()) {
|
if (ev.ShiftDown()) {
|
||||||
// soft line break
|
// soft line break
|
||||||
replaceSelection(_("<soft-line>\n</soft-line>"), _("Soft line break"));
|
replaceSelection(_("<soft-line>\n</soft-line>"), _ACTION_("soft line break"));
|
||||||
} else {
|
} else {
|
||||||
replaceSelection(_("\n"), _("Enter"));
|
replaceSelection(_("\n"), _ACTION_("enter"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -212,9 +212,9 @@ bool TextValueEditor::onChar(wxKeyEvent& ev) {
|
|||||||
// this might not work for internationalized input.
|
// this might not work for internationalized input.
|
||||||
// It might also not be portable!
|
// It might also not be portable!
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
replaceSelection(escape(String(ev.GetUnicodeKey(), 1)), _("Typing"));
|
replaceSelection(escape(String(ev.GetUnicodeKey(), 1)), _ACTION_("typing"));
|
||||||
#else
|
#else
|
||||||
replaceSelection(escape(String((Char)ev.GetKeyCode(), 1)), _("Typing"));
|
replaceSelection(escape(String((Char)ev.GetKeyCode(), 1)), _ACTION_("typing"));
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -256,7 +256,7 @@ bool TextValueEditor::onCommand(int id) {
|
|||||||
if (!style().always_symbol) {
|
if (!style().always_symbol) {
|
||||||
code = _("<sym>") + code + _("</sym>");
|
code = _("<sym>") + code + _("</sym>");
|
||||||
}
|
}
|
||||||
replaceSelection(code, _("Insert Symbol"));
|
replaceSelection(code, _ACTION_("insert symbol"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -350,7 +350,7 @@ bool TextValueEditor::doPaste() {
|
|||||||
wxTheClipboard->Close();
|
wxTheClipboard->Close();
|
||||||
if (!ok) return false;
|
if (!ok) return false;
|
||||||
// paste
|
// paste
|
||||||
replaceSelection(escape(data.GetText()), _("Paste"));
|
replaceSelection(escape(data.GetText()), _ACTION_("paste"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,7 +370,7 @@ bool TextValueEditor::doCopy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TextValueEditor::doDelete() {
|
bool TextValueEditor::doDelete() {
|
||||||
replaceSelection(wxEmptyString, _("Cut"));
|
replaceSelection(wxEmptyString, _ACTION_("cut"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,495 @@
|
|||||||
|
# This file contains the keys expected to be in MSE locales
|
||||||
|
# It was automatically generated by tools/locale/locale.pl
|
||||||
|
# Generated on Fri Aug 17 22:58:51 2007
|
||||||
|
|
||||||
|
action:
|
||||||
|
add control point: 0
|
||||||
|
add part: 1
|
||||||
|
add symmetry: 0
|
||||||
|
backspace: 0
|
||||||
|
change: 1
|
||||||
|
change combine mode: 0
|
||||||
|
change shape name: 0
|
||||||
|
change symmetry copies: 0
|
||||||
|
change symmetry type: 0
|
||||||
|
convert to curve: 0
|
||||||
|
convert to line: 0
|
||||||
|
cut: 0
|
||||||
|
delete: 0
|
||||||
|
delete point: 0
|
||||||
|
delete points: 0
|
||||||
|
duplicate: 1
|
||||||
|
enter: 0
|
||||||
|
group parts: 0
|
||||||
|
insert symbol: 0
|
||||||
|
lock point: 0
|
||||||
|
move: 1
|
||||||
|
move curve: 0
|
||||||
|
move handle: 0
|
||||||
|
move symmetry center: 0
|
||||||
|
move symmetry handle: 0
|
||||||
|
paste: 0
|
||||||
|
remove parts: 1
|
||||||
|
reorder parts: 0
|
||||||
|
rotate: 1
|
||||||
|
scale: 1
|
||||||
|
shear: 1
|
||||||
|
soft line break: 0
|
||||||
|
typing: 0
|
||||||
|
ungroup parts: 0
|
||||||
|
button:
|
||||||
|
always: 0
|
||||||
|
browse: 0
|
||||||
|
check now: 0
|
||||||
|
close: 0
|
||||||
|
edit symbol: 0
|
||||||
|
hide: 0
|
||||||
|
high quality: 0
|
||||||
|
if internet connection exists: 0
|
||||||
|
insert parameter: 0
|
||||||
|
keep old: 0
|
||||||
|
last opened set: 0
|
||||||
|
move down: 0
|
||||||
|
move up: 0
|
||||||
|
never: 0
|
||||||
|
new set: 0
|
||||||
|
number: 0
|
||||||
|
number overwrite: 0
|
||||||
|
open set: 0
|
||||||
|
overwrite: 0
|
||||||
|
refer parameter: 0
|
||||||
|
select: optional, 0
|
||||||
|
select all: 0
|
||||||
|
select none: 0
|
||||||
|
show: 0
|
||||||
|
show lines: 0
|
||||||
|
symbol gallery: optional, 0
|
||||||
|
use custom styling options: 0
|
||||||
|
use for all cards: 0
|
||||||
|
zoom export: 0
|
||||||
|
error:
|
||||||
|
aborting parsing: 0
|
||||||
|
can't convert: 2
|
||||||
|
can't convert value: 3
|
||||||
|
checking updates: 0
|
||||||
|
checking updates failed: 0
|
||||||
|
coordinates for blending overlap: 0
|
||||||
|
dimension not found: 1
|
||||||
|
expected key: 1
|
||||||
|
file not found: 2
|
||||||
|
file parse error: 2
|
||||||
|
has no member: 2
|
||||||
|
has no member value: 2
|
||||||
|
images used for blending must have the same size: 0
|
||||||
|
internal error: 1
|
||||||
|
newer version: 2
|
||||||
|
no game specified for the set: 0
|
||||||
|
no packages: 0
|
||||||
|
no stylesheet specified for the set: 0
|
||||||
|
no updates: 0
|
||||||
|
package not found: 1
|
||||||
|
package out of date: 3
|
||||||
|
stylesheet and set refer to different game: 0
|
||||||
|
unable to open output file: 0
|
||||||
|
unable to store file: 0
|
||||||
|
unrecognized value: 1
|
||||||
|
unsupported field type: 1
|
||||||
|
unsupported fill type: 1
|
||||||
|
unsupported format: 1
|
||||||
|
help:
|
||||||
|
about: 0
|
||||||
|
add card: 0
|
||||||
|
add cards: 0
|
||||||
|
add keyword: 0
|
||||||
|
add symmetry: 0
|
||||||
|
app language: 0
|
||||||
|
basic shapes: 0
|
||||||
|
bold: 0
|
||||||
|
border: 0
|
||||||
|
card list columns: 0
|
||||||
|
cards tab: 0
|
||||||
|
check updates: 0
|
||||||
|
click to select shape: 0
|
||||||
|
close symbol editor: 0
|
||||||
|
copies: 0
|
||||||
|
copy: 0
|
||||||
|
copy card: 0
|
||||||
|
copy keyword: 0
|
||||||
|
curve segment: 0
|
||||||
|
cut: 0
|
||||||
|
cut card: 0
|
||||||
|
cut keyword: 0
|
||||||
|
difference: 0
|
||||||
|
draft tab: optional, 0
|
||||||
|
drag to draw shape: 0
|
||||||
|
drag to move curve: 0
|
||||||
|
drag to move line: 0
|
||||||
|
drag to move point: 0
|
||||||
|
drag to resize: 1
|
||||||
|
drag to rotate: 1
|
||||||
|
drag to shear: 1
|
||||||
|
draw ellipse: 0
|
||||||
|
draw polygon: 0
|
||||||
|
draw rectangle: 0
|
||||||
|
draw star: 0
|
||||||
|
duplicate: 0
|
||||||
|
ellipse: 0
|
||||||
|
exit: 0
|
||||||
|
export: 0
|
||||||
|
export apprentice: 0
|
||||||
|
export html: 0
|
||||||
|
export image: 0
|
||||||
|
export images: 0
|
||||||
|
export mws: 0
|
||||||
|
filename format: 0
|
||||||
|
free point: 0
|
||||||
|
grid: 0
|
||||||
|
group: 0
|
||||||
|
index: 0
|
||||||
|
intersect: 0
|
||||||
|
italic: 0
|
||||||
|
keywords tab: 0
|
||||||
|
last opened set: 1
|
||||||
|
line segment: 0
|
||||||
|
merge: 0
|
||||||
|
new set: 0
|
||||||
|
new symbol: 0
|
||||||
|
new window: 0
|
||||||
|
next card: 0
|
||||||
|
next keyword: 0
|
||||||
|
open set: 0
|
||||||
|
open symbol: 0
|
||||||
|
orientation: 0
|
||||||
|
overlap: 0
|
||||||
|
paint: 0
|
||||||
|
paste: 0
|
||||||
|
paste card: 0
|
||||||
|
paste keyword: 0
|
||||||
|
points: 0
|
||||||
|
polygon: 0
|
||||||
|
preferences: 0
|
||||||
|
previous card: 0
|
||||||
|
previous keyword: 0
|
||||||
|
print: 0
|
||||||
|
print preview: 0
|
||||||
|
rectangle: 0
|
||||||
|
redo: 0
|
||||||
|
reflection: 0
|
||||||
|
reload data: 0
|
||||||
|
reminder text: 0
|
||||||
|
remove card: 0
|
||||||
|
remove keyword: 0
|
||||||
|
remove symmetry: 0
|
||||||
|
rotate: 0
|
||||||
|
rotate 0: 0
|
||||||
|
rotate 180: 0
|
||||||
|
rotate 270: 0
|
||||||
|
rotate 90: 0
|
||||||
|
rotate card: 0
|
||||||
|
rotation: 0
|
||||||
|
save set: 0
|
||||||
|
save set as: 0
|
||||||
|
save symbol: 0
|
||||||
|
save symbol as: 0
|
||||||
|
select: 0
|
||||||
|
set code: 0
|
||||||
|
set info tab: 0
|
||||||
|
sides: 0
|
||||||
|
smooth point: 0
|
||||||
|
snap: 0
|
||||||
|
star: 0
|
||||||
|
stats tab: 0
|
||||||
|
store symbol: 0
|
||||||
|
style tab: 0
|
||||||
|
subtract: 0
|
||||||
|
symbols: 0
|
||||||
|
symmetric point: 0
|
||||||
|
symmetry: 0
|
||||||
|
undo: 0
|
||||||
|
ungroup: 0
|
||||||
|
website: 0
|
||||||
|
welcome: 0
|
||||||
|
zoom export: 0
|
||||||
|
label:
|
||||||
|
app language: 0
|
||||||
|
apprentice: 0
|
||||||
|
apprentice exe: 0
|
||||||
|
apprentice export cancelled: 0
|
||||||
|
card display: 0
|
||||||
|
card notes: 0
|
||||||
|
cards to export: 0
|
||||||
|
check at startup: 0
|
||||||
|
checking requires internet: 0
|
||||||
|
columns: 0
|
||||||
|
export filenames: 0
|
||||||
|
external programs: 0
|
||||||
|
filename conflicts: 0
|
||||||
|
filename format: 0
|
||||||
|
filename is ignored: 0
|
||||||
|
filter: 0
|
||||||
|
game type: 0
|
||||||
|
html export options: 0
|
||||||
|
html template: 0
|
||||||
|
keyword: 0
|
||||||
|
language: 0
|
||||||
|
match: 0
|
||||||
|
mode: 0
|
||||||
|
original: 0
|
||||||
|
percent of normal: 0
|
||||||
|
reminder: 0
|
||||||
|
result: 0
|
||||||
|
save changes: 1
|
||||||
|
select cards print: 0
|
||||||
|
select columns: 0
|
||||||
|
selection: 0
|
||||||
|
set code: 0
|
||||||
|
sides: optional, 0
|
||||||
|
size: 0
|
||||||
|
standard keyword: 1
|
||||||
|
style type: 0
|
||||||
|
styling options: 0
|
||||||
|
uses: 0
|
||||||
|
zoom: 0
|
||||||
|
menu:
|
||||||
|
about: 0
|
||||||
|
add card: 0
|
||||||
|
add cards: 0
|
||||||
|
add keyword: 0
|
||||||
|
basic shapes: 0
|
||||||
|
bold: 0
|
||||||
|
card list columns: 0
|
||||||
|
cards: 0
|
||||||
|
cards tab: 0
|
||||||
|
check updates: 0
|
||||||
|
close symbol editor: 0
|
||||||
|
copy: 0
|
||||||
|
cut: 0
|
||||||
|
draft tab: optional, 0
|
||||||
|
duplicate: 0
|
||||||
|
edit: 0
|
||||||
|
exit: 0
|
||||||
|
export: 0
|
||||||
|
export apprentice: 0
|
||||||
|
export html: 0
|
||||||
|
export image: 0
|
||||||
|
export images: 0
|
||||||
|
export mws: 0
|
||||||
|
file: 0
|
||||||
|
find: 0
|
||||||
|
find next: 0
|
||||||
|
format: 0
|
||||||
|
group: 0
|
||||||
|
help: 0
|
||||||
|
index: 0
|
||||||
|
insert symbol: 0
|
||||||
|
italic: 0
|
||||||
|
keywords: 0
|
||||||
|
keywords tab: 0
|
||||||
|
new set: 0
|
||||||
|
new symbol: 0
|
||||||
|
new window: 0
|
||||||
|
next card: 0
|
||||||
|
next keyword: 0
|
||||||
|
open set: 0
|
||||||
|
open symbol: 0
|
||||||
|
orientation: 0
|
||||||
|
paint: 0
|
||||||
|
paste: 0
|
||||||
|
points: 0
|
||||||
|
preferences: 0
|
||||||
|
previous card: 0
|
||||||
|
previous keyword: 0
|
||||||
|
print: 0
|
||||||
|
print preview: 0
|
||||||
|
redo: 1
|
||||||
|
reload data: 0
|
||||||
|
reminder text: 0
|
||||||
|
remove card: 0
|
||||||
|
remove keyword: 0
|
||||||
|
replace: 0
|
||||||
|
rotate: 0
|
||||||
|
rotate 0: 0
|
||||||
|
rotate 180: 0
|
||||||
|
rotate 270: 0
|
||||||
|
rotate 90: 0
|
||||||
|
save set: 0
|
||||||
|
save set as: 0
|
||||||
|
save symbol: 0
|
||||||
|
save symbol as: 0
|
||||||
|
select: 0
|
||||||
|
set info tab: 0
|
||||||
|
stats tab: 0
|
||||||
|
store symbol: 0
|
||||||
|
style tab: 0
|
||||||
|
symbols: 0
|
||||||
|
symmetry: 0
|
||||||
|
tool: 0
|
||||||
|
undo: 1
|
||||||
|
ungroup: 0
|
||||||
|
website: 0
|
||||||
|
window: 0
|
||||||
|
title:
|
||||||
|
%s - magic set editor: 1
|
||||||
|
about: 0
|
||||||
|
directories: 0
|
||||||
|
display: 0
|
||||||
|
export cancelled: 0
|
||||||
|
export html: 0
|
||||||
|
export images: 0
|
||||||
|
global: 0
|
||||||
|
locate apprentice: 0
|
||||||
|
magic set editor: 0
|
||||||
|
new status: 0
|
||||||
|
open set: 0
|
||||||
|
package list: 0
|
||||||
|
package name: 0
|
||||||
|
package status: 0
|
||||||
|
preferences: 0
|
||||||
|
print preview: 0
|
||||||
|
save changes: 0
|
||||||
|
save html: 0
|
||||||
|
save image: 0
|
||||||
|
save set: 0
|
||||||
|
select cards: 0
|
||||||
|
select cards export: 0
|
||||||
|
select columns: 0
|
||||||
|
slice image: 0
|
||||||
|
symbol editor: 0
|
||||||
|
untitled: 0
|
||||||
|
update check: 0
|
||||||
|
updates: 0
|
||||||
|
updates availible: 0
|
||||||
|
tool:
|
||||||
|
add symmetry: 0
|
||||||
|
basic shapes: 0
|
||||||
|
border: 0
|
||||||
|
cards tab: 0
|
||||||
|
curve segment: 0
|
||||||
|
difference: 0
|
||||||
|
draft tab: optional, 0
|
||||||
|
ellipse: 0
|
||||||
|
free point: 0
|
||||||
|
grid: 0
|
||||||
|
intersect: 0
|
||||||
|
keywords tab: 0
|
||||||
|
line segment: 0
|
||||||
|
merge: 0
|
||||||
|
overlap: 0
|
||||||
|
paint: optional, 0
|
||||||
|
points: 0
|
||||||
|
polygon: 0
|
||||||
|
rectangle: 0
|
||||||
|
redo: 0
|
||||||
|
reflection: 0
|
||||||
|
remove symmetry: 0
|
||||||
|
rotate: 0
|
||||||
|
rotation: 0
|
||||||
|
select: 0
|
||||||
|
set info tab: 0
|
||||||
|
smooth point: 0
|
||||||
|
snap: 0
|
||||||
|
star: 0
|
||||||
|
stats tab: 0
|
||||||
|
store symbol: 0
|
||||||
|
style tab: 0
|
||||||
|
subtract: 0
|
||||||
|
symmetric point: 0
|
||||||
|
symmetry: 0
|
||||||
|
undo: 0
|
||||||
|
tooltip:
|
||||||
|
add card: 0
|
||||||
|
add keyword: 0
|
||||||
|
add symmetry: 0
|
||||||
|
basic shapes: 0
|
||||||
|
bold: 0
|
||||||
|
border: 0
|
||||||
|
cards tab: 0
|
||||||
|
copy: 0
|
||||||
|
curve segment: 0
|
||||||
|
cut: 0
|
||||||
|
difference: 0
|
||||||
|
draft tab: optional, 0
|
||||||
|
ellipse: 0
|
||||||
|
export: 0
|
||||||
|
free point: 0
|
||||||
|
grid: 0
|
||||||
|
intersect: 0
|
||||||
|
italic: 0
|
||||||
|
keywords tab: 0
|
||||||
|
line segment: 0
|
||||||
|
merge: 0
|
||||||
|
new set: 0
|
||||||
|
open set: 0
|
||||||
|
overlap: 0
|
||||||
|
paint: optional, 0
|
||||||
|
paste: 0
|
||||||
|
points: 0
|
||||||
|
polygon: 0
|
||||||
|
rectangle: 0
|
||||||
|
redo: 1
|
||||||
|
reflection: 0
|
||||||
|
reminder text: 0
|
||||||
|
remove card: 0
|
||||||
|
remove keyword: 0
|
||||||
|
remove symmetry: 0
|
||||||
|
rotate: 0
|
||||||
|
rotate card: 0
|
||||||
|
rotation: 0
|
||||||
|
save set: 0
|
||||||
|
select: 0
|
||||||
|
set info tab: 0
|
||||||
|
smooth point: 0
|
||||||
|
snap: 0
|
||||||
|
star: 0
|
||||||
|
stats tab: 0
|
||||||
|
store symbol: 0
|
||||||
|
style tab: 0
|
||||||
|
subtract: 0
|
||||||
|
symbols: 0
|
||||||
|
symmetric point: 0
|
||||||
|
symmetry: 0
|
||||||
|
undo: 1
|
||||||
|
type:
|
||||||
|
boolean: 0
|
||||||
|
card: 0
|
||||||
|
circle: 0
|
||||||
|
collection: 0
|
||||||
|
collection of: 1
|
||||||
|
color: 0
|
||||||
|
do nothing: 0
|
||||||
|
double: 0
|
||||||
|
ellipse: 0
|
||||||
|
field: 0
|
||||||
|
function: 0
|
||||||
|
game: 0
|
||||||
|
group: 0
|
||||||
|
hexagon: 0
|
||||||
|
image: 0
|
||||||
|
install: 0
|
||||||
|
installed: 0
|
||||||
|
integer: 0
|
||||||
|
new mse: 0
|
||||||
|
nil: 0
|
||||||
|
object: 0
|
||||||
|
pentagon: 0
|
||||||
|
point: 0
|
||||||
|
points: 0
|
||||||
|
polygon: 0
|
||||||
|
rectangle: 0
|
||||||
|
reflection: 0
|
||||||
|
rhombus: 0
|
||||||
|
rotation: 0
|
||||||
|
set: 0
|
||||||
|
shape: 0
|
||||||
|
shapes: 0
|
||||||
|
square: 0
|
||||||
|
star: 0
|
||||||
|
string: 0
|
||||||
|
style: 0
|
||||||
|
stylesheet: 0
|
||||||
|
triangle: 0
|
||||||
|
uninstall: 0
|
||||||
|
uninstalled: 0
|
||||||
|
upgrade: 0
|
||||||
|
upgradeable: 0
|
||||||
|
value: 0
|
||||||
@@ -173,6 +173,10 @@ edit_symbol IMAGE "../common/edit_symbol.png"
|
|||||||
wxBITMAP_STD_COLOURS BITMAP "wx/msw/colours.bmp"
|
wxBITMAP_STD_COLOURS BITMAP "wx/msw/colours.bmp"
|
||||||
WXCURSOR_HAND CURSOR DISCARDABLE "wx/msw/hand.cur"
|
WXCURSOR_HAND CURSOR DISCARDABLE "wx/msw/hand.cur"
|
||||||
|
|
||||||
|
// -------------------------------------------------------- : Other
|
||||||
|
|
||||||
|
expected_locale_keys TEXT "../common/expected_locale_keys"
|
||||||
|
|
||||||
// -------------------------------------------------------- : Version info
|
// -------------------------------------------------------- : Version info
|
||||||
|
|
||||||
1 VERSIONINFO
|
1 VERSIONINFO
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ class ScriptCollection : public ScriptValue {
|
|||||||
public:
|
public:
|
||||||
inline ScriptCollection(const Collection* v) : value(v) {}
|
inline ScriptCollection(const Collection* v) : value(v) {}
|
||||||
virtual ScriptType type() const { return SCRIPT_COLLECTION; }
|
virtual ScriptType type() const { return SCRIPT_COLLECTION; }
|
||||||
virtual String typeName() const { return format_string(_TYPE_("collection"), type_name(*value->begin())); }
|
virtual String typeName() const { return format_string(_TYPE_("collection of"), type_name(*value->begin())); }
|
||||||
virtual ScriptValueP getMember(const String& name) const {
|
virtual ScriptValueP getMember(const String& name) const {
|
||||||
long index;
|
long index;
|
||||||
if (name.ToLong(&index) && index >= 0 && (size_t)index < value->size()) {
|
if (name.ToLong(&index) && index >= 0 && (size_t)index < value->size()) {
|
||||||
@@ -160,7 +160,7 @@ class ScriptMap : public ScriptValue {
|
|||||||
public:
|
public:
|
||||||
inline ScriptMap(const Collection* v) : value(v) {}
|
inline ScriptMap(const Collection* v) : value(v) {}
|
||||||
virtual ScriptType type() const { return SCRIPT_COLLECTION; }
|
virtual ScriptType type() const { return SCRIPT_COLLECTION; }
|
||||||
virtual String typeName() const { return format_string(_TYPE_("collection"), type_name(value->begin())); }
|
virtual String typeName() const { return format_string(_TYPE_("collection of"), type_name(value->begin())); }
|
||||||
virtual ScriptValueP getMember(const String& name) const {
|
virtual ScriptValueP getMember(const String& name) const {
|
||||||
return get_member(*value, name);
|
return get_member(*value, name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
ScriptValue::operator String() const { return _("[[") + typeName() + _("]]"); }
|
ScriptValue::operator String() const { return _("[[") + typeName() + _("]]"); }
|
||||||
ScriptValue::operator int() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("integer" ))); }
|
ScriptValue::operator int() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("integer" ))); }
|
||||||
ScriptValue::operator double() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("real" ))); }
|
ScriptValue::operator double() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("double" ))); }
|
||||||
ScriptValue::operator Color() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("color" ))); }
|
ScriptValue::operator Color() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("color" ))); }
|
||||||
ScriptValueP ScriptValue::eval(Context&) const { return delayError(_ERROR_2_("can't convert", typeName(), _TYPE_("function"))); }
|
ScriptValueP ScriptValue::eval(Context&) const { return delayError(_ERROR_2_("can't convert", typeName(), _TYPE_("function"))); }
|
||||||
ScriptValueP ScriptValue::getMember(const String& name) const { return delayError(_ERROR_2_("has no member", typeName(), name)); }
|
ScriptValueP ScriptValue::getMember(const String& name) const { return delayError(_ERROR_2_("has no member", typeName(), name)); }
|
||||||
@@ -149,7 +149,7 @@ class ScriptDouble : public ScriptValue {
|
|||||||
public:
|
public:
|
||||||
ScriptDouble(double v) : value(v) {}
|
ScriptDouble(double v) : value(v) {}
|
||||||
virtual ScriptType type() const { return SCRIPT_DOUBLE; }
|
virtual ScriptType type() const { return SCRIPT_DOUBLE; }
|
||||||
virtual String typeName() const { return _TYPE_("real"); }
|
virtual String typeName() const { return _TYPE_("double"); }
|
||||||
virtual operator String() const { return String() << value; }
|
virtual operator String() const { return String() << value; }
|
||||||
virtual operator double() const { return value; }
|
virtual operator double() const { return value; }
|
||||||
virtual operator int() const { return (int)value; }
|
virtual operator int() const { return (int)value; }
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ struct Version {
|
|||||||
Version() : version(0) {}
|
Version() : version(0) {}
|
||||||
Version(UInt version) : version(version) {}
|
Version(UInt version) : version(version) {}
|
||||||
|
|
||||||
|
inline bool operator == (Version v) const { return version == v.version; }
|
||||||
|
inline bool operator != (Version v) const { return version != v.version; }
|
||||||
inline bool operator < (Version v) const { return version < v.version; }
|
inline bool operator < (Version v) const { return version < v.version; }
|
||||||
inline bool operator <= (Version v) const { return version <= v.version; }
|
inline bool operator <= (Version v) const { return version <= v.version; }
|
||||||
inline bool operator > (Version v) const { return version > v.version; }
|
inline bool operator > (Version v) const { return version > v.version; }
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
#! /usr/bin/perl
|
||||||
|
|
||||||
|
# Determine the keys that should be in the locale file,
|
||||||
|
# and the number of arguments the keys should have
|
||||||
|
|
||||||
|
our %found;
|
||||||
|
|
||||||
|
use File::Find;
|
||||||
|
find(\&doit, '../../src');
|
||||||
|
|
||||||
|
sub arg_count {
|
||||||
|
return scalar split(/,/,$_[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub make_comment {
|
||||||
|
my $input = $_[0];
|
||||||
|
$input =~ s/(_[A-Z])/_COMMENT$1/g;
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
|
||||||
|
# for each .cpp/.hpp file, collect locale calls
|
||||||
|
sub doit {
|
||||||
|
my $file = $File::Find::name;
|
||||||
|
if (!($file =~ /\..pp$/)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# relative filename
|
||||||
|
#print "$file\n";
|
||||||
|
$file =~ s@.*/@@;
|
||||||
|
|
||||||
|
# Read file
|
||||||
|
open F, "< $file";
|
||||||
|
my $body = join('',<F>);
|
||||||
|
close F;
|
||||||
|
|
||||||
|
# Custom argument expansion
|
||||||
|
$inparen = qr/[^()]|\((??{$inparen})*\)/; # recursive paren matching
|
||||||
|
$body =~ s/format_string\((_[A-Z]+)(_\([^)]+\)),($inparen+)/
|
||||||
|
$1 . "_" . arg_count($3) . $2
|
||||||
|
/ge;
|
||||||
|
$body =~ s/action_name_for[(][^,]*,\s*(_[A-Z]+)(_\([^)]+\))/$1_1$2/g;
|
||||||
|
|
||||||
|
# Drop comments, mark found items as 'optional'
|
||||||
|
$body =~ s@//[^\n]*@ find_locale_calls($&, 1)@ge;
|
||||||
|
$body =~ s@/\*.*?\*/@find_locale_calls($&, 1)@ge;
|
||||||
|
|
||||||
|
find_locale_calls($body, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub find_locale_calls {
|
||||||
|
my $body = $_[0];
|
||||||
|
my $in_comment = $_[1];
|
||||||
|
|
||||||
|
# Find calls to locale functions
|
||||||
|
while ($body =~ /_(COMMENT_)?(MENU|HELP|TOOL|TOOLTIP|LABEL|BUTTON|TITLE|TYPE|ACTION|ERROR)_(?:([1-9])_)?\(\s*\"([^\"]+)\"/g) {
|
||||||
|
$argc = $3 ? $3 : 0;
|
||||||
|
if (defined($found{$2}{$4}{'argc'}) && $found{$2}{$4}{'argc'} != $argc) {
|
||||||
|
print "ERROR: key _$2_($4) used with different arities";
|
||||||
|
}
|
||||||
|
$found{$2}{$4}{'opt'} = defined($found{$2}{$4}{'opt'}) ? ($found{$2}{$4}{'opt'} && $in_comment) : $in_comment;
|
||||||
|
$found{$2}{$4}{'argc'} = $argc;
|
||||||
|
}
|
||||||
|
# Also translated:
|
||||||
|
while ($body =~ m@
|
||||||
|
( addPanel \((?:[^,]+,){6} # gui/set/window.cpp
|
||||||
|
)
|
||||||
|
\s* _ \(\" ([^\"]+) \"\)
|
||||||
|
@xg
|
||||||
|
) {
|
||||||
|
($key = $2) =~ s/_/ /g;
|
||||||
|
foreach $type ("MENU","HELP","TOOL","TOOLTIP") {
|
||||||
|
$found{$type}{$key}{'opt'} = $in_comment;
|
||||||
|
$found{$type}{$key}{'argc'} = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now process the items we found, print out a list in MSE reader format
|
||||||
|
|
||||||
|
my $result;
|
||||||
|
my $now = localtime;
|
||||||
|
$result .= "# This file contains the keys expected to be in MSE locales\n";
|
||||||
|
$result .= "# It was automatically generated by tools/locale/locale.pl\n";
|
||||||
|
$result .= "# Generated on " . $now . "\n\n";
|
||||||
|
|
||||||
|
my @types = sort keys %found;
|
||||||
|
foreach $type (@types) {
|
||||||
|
$result .= lc($type) . ":\n";
|
||||||
|
my @keys = sort keys %{$found{$type}};
|
||||||
|
foreach $key (@keys) {
|
||||||
|
$argc = $found{$type}{$key}{'argc'};
|
||||||
|
$opt = $found{$type}{$key}{'opt'} ? 'optional, ' : '';
|
||||||
|
$result .= "\t$key:\t$opt$argc\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Write to file
|
||||||
|
open F, "> ../../src/resource/common/expected_locale_keys";
|
||||||
|
print F $result;
|
||||||
|
close F;
|
||||||
|
|
||||||
|
# and to stdout
|
||||||
|
#print $result;
|
||||||
Reference in New Issue
Block a user