diff --git a/data/en.mse-locale/locale b/data/en.mse-locale/locale index c94f68a8..be22ea6c 100644 --- a/data/en.mse-locale/locale +++ b/data/en.mse-locale/locale @@ -60,6 +60,8 @@ menu: symbols: &Symbols Ctrl+M reminder text: &Reminder Text Ctrl+R insert symbol: I&nsert Symbol + # spelling + no spelling suggestions: (no suggestions) graph: &Graph pie: &Pie 1 @@ -168,6 +170,8 @@ help: italic: Makes the selected text italic symbols: Draws the selected text with symbols reminder text: Show reminder text for the selected keyword + # spelling + no spelling suggestions: There are no suggestions for correcting this error graph: pie: A pie graph, the size of the slice indicates the number of cards @@ -669,6 +673,7 @@ action: cut: Cut paste: Paste auto replace: Auto Replace + correct: Spelling Correction # Choice/color editors change: Change %s @@ -704,17 +709,6 @@ action: ############################################################## Error messages error: - # General - internal error: - An internal error occured: - - %s - - Please save your work (use 'save as' to so you don't overwrite things) - and restart Magic Set Editor. - - You should leave a bug report on http://magicseteditor.sourceforge.net/ - # File related file not found: File not found: '%s' in package '%s' file not found package like: diff --git a/src/gui/icon_menu.cpp b/src/gui/icon_menu.cpp index d3950943..c2e942c4 100644 --- a/src/gui/icon_menu.cpp +++ b/src/gui/icon_menu.cpp @@ -91,6 +91,14 @@ void IconMenu::Append(wxMenuItem* item) { wxMenu::Append(item); } +void IconMenu::Insert(size_t pos, int id, const String& resource, const String& text, const String& help, int style, wxMenu* submenu) { + // create menu, load icon + wxMenuItem* item = new wxMenuItem(this, id, text, help, style, submenu); + set_menu_item_image(item, resource); + // add to menu + wxMenu::Insert(pos,item); +} + void IconMenu::Insert(size_t pos, int id, const String& text, const String& help) { wxMenuItem* item = new wxMenuItem (this, id, text, help); item->SetBitmap(wxNullBitmap); diff --git a/src/gui/icon_menu.hpp b/src/gui/icon_menu.hpp index 2609c465..76d440ae 100644 --- a/src/gui/icon_menu.hpp +++ b/src/gui/icon_menu.hpp @@ -29,6 +29,8 @@ class IconMenu : public wxMenu { void Append(int id, const String& text, const String& help, wxMenu* submenu); /// Append a menu item, without an image void Append(wxMenuItem* item); + /// Insert a menu item, with an image (loaded from a resource) + void Insert(size_t pos, int id, const String& resource, const String& text, const String& help, int style = wxITEM_NORMAL, wxMenu* submenu = nullptr); /// Insert a menu item, without an image void Insert(size_t pos, int id, const String& text, const String& help); }; diff --git a/src/gui/value/text.cpp b/src/gui/value/text.cpp index 9f320a72..bf0094b1 100644 --- a/src/gui/value/text.cpp +++ b/src/gui/value/text.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -508,6 +509,43 @@ bool TextValueEditor::onChar(wxKeyEvent& ev) { return true; } +// ----------------------------------------------------------------------------- : Spellchecking + +String spellcheck_word_at(const String& str, size_t start, String& before, String& after) { + size_t end = min(match_close_tag(str,start), str.size()); + String word = untag(str.substr(start,end-start)); + size_t start_u = 0, end_u = String::npos; + trim_punctuation(word, start_u, end_u); + before = word.substr(0,start_u); + after = word.substr(end_u,String::npos); + word.erase(end_u,String::npos); + word.erase(0,start_u); + return word; +} + +void spellcheck_language_at(const String& str, size_t error_pos, SpellChecker** out) { + String tag = tag_at(str,error_pos); + size_t pos = min(tag.find_first_of(_(':')), tag.size()-1); + size_t pos2 = min(tag.find_first_of(_(':'),pos+1), tag.size()-1); + String language = tag.substr(pos+1,pos2-pos-1); + if (language.empty()) return; + out[0] = &SpellChecker::get(language); + String extra = tag.substr(pos2+1); + if (extra.empty()) return; + out[1] = &SpellChecker::get(extra,language); +} + +void get_spelling_suggestions(const String& str, size_t error_pos, vector& suggestions_out, String& before, String& after) { + String word = spellcheck_word_at(str, error_pos, before, after); + // find dictionaries + SpellChecker* checkers[3] = {nullptr}; + spellcheck_language_at(str, error_pos, checkers); + // suggestions + for (size_t i = 0 ; checkers[i] ; ++i) { + checkers[i]->suggest(word, suggestions_out); + } +} + // ----------------------------------------------------------------------------- : Other events void TextValueEditor::onFocus() { @@ -527,12 +565,35 @@ bool TextValueEditor::onContextMenu(IconMenu& m, wxContextMenuEvent& ev) { // in a keword? => "reminder text" option size_t kwpos = in_tag(value().value(), _(" show suggestions and "add to dictionary" + size_t error_pos = in_tag(value().value(), _(" suggestions; + get_spelling_suggestions(value().value(), error_pos, suggestions,before,after); + // add suggestions to menu + m.InsertSeparator(0); + if (suggestions.empty()) { + m.Insert(0,ID_SPELLING_NO_SUGGEST, _MENU_("no spelling suggestions"), _HELP_("no spelling suggestions")); + } else { + int i = 0; + FOR_EACH(s,suggestions) { + m.Insert(i, ID_SPELLING_SUGGEST + i, before+s+after, wxEmptyString); + i++; + } + } } // always show the menu return true; } + bool TextValueEditor::onCommand(int id) { if (id >= ID_INSERT_SYMBOL_MENU_MIN && id <= ID_INSERT_SYMBOL_MENU_MAX) { // Insert a symbol @@ -544,9 +605,23 @@ bool TextValueEditor::onCommand(int id) { replaceSelection(code, _ACTION_("insert symbol")); return true; } + } else if (id == ID_SPELLING_ADD_TO_DICT) { + // TODO + } else if (id >= ID_SPELLING_SUGGEST && id <= ID_SPELLING_SUGGEST_MAX) { + size_t error_pos = in_tag(value().value(), _(" suggestions; + get_spelling_suggestions(value().value(), error_pos, suggestions,before,after); + selection_start_i = error_pos; + selection_end_i = match_close_tag(value().value(), error_pos); + fixSelection(TYPE_INDEX); + replaceSelection(before + suggestions.at(id - ID_SPELLING_SUGGEST) + after, _ACTION_("correct")); + return true; } return false; } + wxMenu* TextValueEditor::getMenu(int type) const { if (type == ID_INSERT_SYMBOL && (style().always_symbol || style().allow_formating) && style().symbol_font.valid()) { diff --git a/src/resource/common/expected_locale_keys b/src/resource/common/expected_locale_keys index 8189b2bd..5726feb1 100644 --- a/src/resource/common/expected_locale_keys +++ b/src/resource/common/expected_locale_keys @@ -1,606 +1,611 @@ -# This file contains the keys expected to be in MSE locales -# It was automatically generated by tools/locale/locale.pl -# Generated on Sun Aug 31 20:53:39 2008 - -action: - add control point: 0 - add item: 1 - add symmetry: 0 - auto replace: 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 item: 1 - reorder parts: 0 - rotate: 1 - scale: 1 - shear: 1 - soft line break: 0 - typing: 0 - ungroup parts: 0 -button: - add item: 0 - always: 0 - browse: 0 - check now: 0 - check updates: 0 - close: 0 - defaults: 0 - don't install package: 0 - edit symbol: 0 - enabled: 0 - export custom cards selection: 0 - export entire set: 0 - export generated packs: 0 - fixed seed: 0 - generate pack: 0 - hide: 0 - high quality: 0 - if internet connection exists: 0 - insert parameter: 0 - install group: optional, 0 - install package: 0 - keep old: 0 - keep package: 0 - last opened set: 0 - move down: 0 - move up: 0 - never: 0 - new set: 0 - number: 0 - number overwrite: 0 - open set: 0 - open sets in new window: 0 - overwrite: 0 - random seed: 0 - refer parameter: 0 - reinstall package: 0 - remove group: optional, 0 - remove item: 0 - remove package: 0 - select: optional, 0 - select all: 0 - select cards: 0 - select none: 0 - show: 0 - show editing hints: 0 - show lines: 0 - symbol gallery: optional, 0 - upgrade group: optional, 0 - upgrade package: 0 - use auto replace: 0 - use custom styling options: 0 - use for all cards: 0 - whole word: 0 - zoom export: 0 -error: - aborting parsing: 0 - can't convert: 2 - can't convert value: 3 - can't download installer: 2 - cannot create file: 1 - change packages successful: 1 - checking updates failed: 0 - coordinates for blending overlap: 0 - dependency not given: 4 - dimension not found: 1 - downloading updates: 0 - expected key: 1 - file not found: 2 - file not found package like: 2 - file parse error: 2 - has no member: 2 - has no member value: 2 - images used for blending must have the same size: 0 - in function: 2 - in keyword reminder: 2 - in parameter: 2 - install packages successful: 1 - installing updates: 0 - internal error: 1 - newer version: 2 - no game specified: 1 - no stylesheet specified for the set: 0 - no updates: 0 - pack item not found: 1 - package not found: 1 - package out of date: 3 - package too new: 4 - remove packages: 1 - remove packages modified: 2 - remove packages successful: 1 - stylesheet and set refer to different game: 0 - successful install: optional, 2 - 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 - word list type not found: 1 -help: - about: 0 - add card: 0 - add cards: 0 - add keyword: 0 - add symmetry: 0 - app language: 0 - auto replace: 0 - bar: 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 - collapse notes: 0 - copies: 0 - copy: 0 - copy card: 0 - copy keyword: 0 - curve segment: 0 - cut: 0 - cut card: 0 - cut keyword: 0 - difference: 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 - expand notes: 0 - export: 0 - export apprentice: 0 - export html: 0 - export image: 0 - export images: 0 - export mws: 0 - filename format: 0 - find: 0 - find next: 0 - fixed seed: 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 - pie: 0 - points: 0 - polygon: 0 - preferences: 0 - previous card: 0 - previous keyword: 0 - print: 0 - print preview: 0 - random pack tab: 0 - random seed: 0 - rectangle: 0 - redo: 0 - reflection: 0 - reload data: 0 - reminder text: 0 - remove card: 0 - remove keyword: 0 - remove symmetry: 0 - replace: 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 - scatter: 0 - scatter pie: 0 - seed: 0 - select: 0 - set code: 0 - set info tab: 0 - sides: 0 - smooth point: 0 - snap: 0 - stack: 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 - auto match: 0 - auto replace: 0 - card display: 0 - card notes: 0 - check at startup: 0 - checking requires internet: 0 - columns: 0 - custom size: 0 - export filenames: 0 - external programs: 0 - filename conflicts: 0 - filename format: 0 - filename is ignored: 0 - filter: 0 - fix aspect ratio: 0 - force to fit: 0 - game type: 0 - html export options: 0 - html template: 0 - install package: 0 - installable version: 0 - installed version: 0 - installer size: optional, 0 - installer status: optional, 0 - keyword: 0 - language: 0 - magic set editor package: optional, 0 - match: 0 - mode: 0 - no version: 0 - original: 0 - original size: 0 - pack selection: 0 - pack totals: 0 - package action: 0 - package conflicts: 0 - package installable: 0 - package installed: 0 - package modified: 0 - package name: 0 - package status: 0 - package updates: 0 - percent of normal: 0 - reinstall package: 0 - reminder: 0 - remove package: 0 - result: 0 - rules: 0 - save changes: 1 - seed: 0 - select cards: 0 - select cards print: optional, 0 - select columns: 0 - selected card count: 1 - selection: 0 - selection height: 0 - selection left: 0 - selection top: 0 - selection width: 0 - set code: 0 - sharpen filter: 0 - sides: optional, 0 - size: 0 - size to fit: 0 - standard keyword: 1 - style type: 0 - stylesheet not found: 1 - styling options: 0 - total cards: 0 - upgrade package: 0 - uses: 0 - windows: 0 - zoom: 0 - zoom %: 0 - zoom amount: 0 - zoom amount x: 0 - zoom amount y: 0 -menu: - about: 0 - add card: 0 - add cards: 0 - add keyword: 0 - auto replace: 0 - bar: 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 - 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 - graph: 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 - pie: 0 - points: 0 - preferences: 0 - previous card: 0 - previous keyword: 0 - print: 0 - print preview: 0 - random pack tab: 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 - scatter: 0 - scatter pie: 0 - select: 0 - set info tab: 0 - stack: 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 - auto replaces: 0 - cannot create file: 0 - directories: 0 - display: 0 - export cancelled: 0 - export html: 0 - export images: 0 - global: 0 - installing updates: 0 - locate apprentice: 0 - magic set editor: 0 - new set: 0 - open set: 0 - packages window: 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 - select stylesheet: 0 - slice image: 0 - symbol editor: 0 - untitled: 0 - update check: 0 - updates: 0 - updates available: 0 -tool: - add symmetry: 0 - basic shapes: 0 - border: 0 - cards tab: 0 - curve segment: 0 - difference: 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 - random pack tab: 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 - bar: 0 - basic shapes: 0 - bold: 0 - border: 0 - cards tab: 0 - copy: 0 - curve segment: 0 - cut: 0 - difference: 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 - pie: 0 - points: 0 - polygon: 0 - random pack tab: 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 - scatter: 0 - scatter pie: 0 - select: 0 - set info tab: 0 - smooth point: 0 - snap: 0 - stack: 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 - cards: 0 - circle: 0 - collection: 0 - collection of: 1 - color: 0 - double: 0 - ellipse: 0 - export template: 0 - field: 0 - function: 0 - game: 0 - group: 0 - hexagon: 0 - image: 0 - integer: 0 - keyword: 0 - keywords: 0 - locale: optional, 0 - nil: 0 - object: 0 - package: optional, 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 - symbol: 0 - triangle: 0 - value: 0 +# This file contains the keys expected to be in MSE locales +# It was automatically generated by tools/locale/locale.pl +# Generated on Tue Dec 30 20:45:27 2008 + +action: + add control point: 0 + add item: 1 + add symmetry: 0 + auto replace: 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 + correct: 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 item: 1 + reorder parts: 0 + rotate: 1 + scale: 1 + shear: 1 + soft line break: 0 + typing: 0 + ungroup parts: 0 +button: + add item: 0 + always: 0 + browse: 0 + check now: 0 + check updates: 0 + close: 0 + defaults: 0 + don't install package: 0 + edit symbol: 0 + enabled: 0 + export custom cards selection: 0 + export entire set: 0 + export generated packs: 0 + fixed seed: 0 + generate pack: 0 + hide: 0 + high quality: 0 + if internet connection exists: 0 + insert parameter: 0 + install group: optional, 0 + install package: 0 + keep old: 0 + keep package: 0 + last opened set: 0 + move down: 0 + move up: 0 + never: 0 + new set: 0 + number: 0 + number overwrite: 0 + open set: 0 + open sets in new window: 0 + overwrite: 0 + random seed: 0 + refer parameter: 0 + reinstall package: 0 + remove group: optional, 0 + remove item: 0 + remove package: 0 + select: optional, 0 + select all: 0 + select cards: 0 + select none: 0 + show: 0 + show editing hints: 0 + show lines: 0 + symbol gallery: optional, 0 + upgrade group: optional, 0 + upgrade package: 0 + use auto replace: 0 + use custom styling options: 0 + use for all cards: 0 + whole word: 0 + zoom export: 0 +error: + aborting parsing: 0 + can't convert: 2 + can't convert value: 3 + can't download installer: 2 + cannot create file: 1 + change packages successful: 1 + checking updates failed: 0 + coordinates for blending overlap: 0 + dependency not given: 4 + dimension not found: 1 + downloading updates: 0 + expected key: 1 + file not found: 2 + file not found package like: 2 + file parse error: 2 + has no member: 2 + has no member value: 2 + images used for blending must have the same size: 0 + in function: 2 + in keyword reminder: 2 + in parameter: 2 + install packages successful: 1 + installing updates: 0 + newer version: 2 + no game specified: 1 + no stylesheet specified for the set: 0 + no updates: 0 + pack item not found: 1 + pack type not found: 1 + package not found: 1 + package out of date: 3 + package too new: 4 + remove packages: 1 + remove packages modified: 2 + remove packages successful: 1 + stylesheet and set refer to different game: 0 + successful install: optional, 2 + 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 + word list type not found: 1 +help: + about: 0 + add card: 0 + add cards: 0 + add keyword: 0 + add symmetry: 0 + add to dictionary: optional, 0 + app language: 0 + auto replace: 0 + bar: 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 + collapse notes: 0 + copies: 0 + copy: 0 + copy card: 0 + copy keyword: 0 + curve segment: 0 + cut: 0 + cut card: 0 + cut keyword: 0 + difference: 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 + expand notes: 0 + export: 0 + export apprentice: 0 + export html: 0 + export image: 0 + export images: 0 + export mws: 0 + filename format: 0 + find: 0 + find next: 0 + fixed seed: 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 + no spelling suggestions: 0 + open set: 0 + open symbol: 0 + orientation: 0 + overlap: 0 + paint: 0 + paste: 0 + paste card: 0 + paste keyword: 0 + pie: 0 + points: 0 + polygon: 0 + preferences: 0 + previous card: 0 + previous keyword: 0 + print: 0 + print preview: 0 + random pack tab: 0 + random seed: 0 + rectangle: 0 + redo: 0 + reflection: 0 + reload data: 0 + reminder text: 0 + remove card: 0 + remove keyword: 0 + remove symmetry: 0 + replace: 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 + scatter: 0 + scatter pie: 0 + seed: 0 + select: 0 + set code: 0 + set info tab: 0 + sides: 0 + smooth point: 0 + snap: 0 + stack: 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 + auto match: 0 + auto replace: 0 + card display: 0 + card notes: 0 + check at startup: 0 + checking requires internet: 0 + columns: 0 + custom size: 0 + export filenames: 0 + external programs: 0 + filename conflicts: 0 + filename format: 0 + filename is ignored: 0 + filter: 0 + fix aspect ratio: 0 + force to fit: 0 + game type: 0 + html export options: 0 + html template: 0 + install package: 0 + installable version: 0 + installed version: 0 + installer size: optional, 0 + installer status: optional, 0 + keyword: 0 + language: 0 + magic set editor package: optional, 0 + match: 0 + mode: 0 + no version: 0 + original: 0 + original size: 0 + pack selection: 0 + pack totals: 0 + package action: 0 + package conflicts: 0 + package installable: 0 + package installed: 0 + package modified: 0 + package name: 0 + package status: 0 + package updates: 0 + percent of normal: 0 + reinstall package: 0 + reminder: 0 + remove package: 0 + result: 0 + rules: 0 + save changes: 1 + seed: 0 + select cards: 0 + select cards print: optional, 0 + select columns: 0 + selected card count: 1 + selection: 0 + selection height: 0 + selection left: 0 + selection top: 0 + selection width: 0 + set code: 0 + sharpen filter: 0 + sides: optional, 0 + size: 0 + size to fit: 0 + standard keyword: 1 + style type: 0 + stylesheet not found: 1 + styling options: 0 + total cards: 0 + upgrade package: 0 + uses: 0 + windows: 0 + zoom: 0 + zoom %: 0 + zoom amount: 0 + zoom amount x: 0 + zoom amount y: 0 +menu: + about: 0 + add card: 0 + add cards: 0 + add keyword: 0 + add to dictionary: optional, 0 + auto replace: 0 + bar: 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 + 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 + graph: 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 + no spelling suggestions: 0 + open set: 0 + open symbol: 0 + orientation: 0 + paint: 0 + paste: 0 + pie: 0 + points: 0 + preferences: 0 + previous card: 0 + previous keyword: 0 + print: 0 + print preview: 0 + random pack tab: 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 + scatter: 0 + scatter pie: 0 + select: 0 + set info tab: 0 + stack: 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 + auto replaces: 0 + cannot create file: 0 + directories: 0 + display: 0 + export cancelled: 0 + export html: 0 + export images: 0 + global: 0 + installing updates: 0 + locate apprentice: 0 + magic set editor: 0 + new set: 0 + open set: 0 + packages window: 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 + select stylesheet: 0 + slice image: 0 + symbol editor: 0 + untitled: 0 + update check: 0 + updates: 0 + updates available: 0 +tool: + add symmetry: 0 + basic shapes: 0 + border: 0 + cards tab: 0 + curve segment: 0 + difference: 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 + random pack tab: 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 + bar: 0 + basic shapes: 0 + bold: 0 + border: 0 + cards tab: 0 + copy: 0 + curve segment: 0 + cut: 0 + difference: 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 + pie: 0 + points: 0 + polygon: 0 + random pack tab: 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 + scatter: 0 + scatter pie: 0 + select: 0 + set info tab: 0 + smooth point: 0 + snap: 0 + stack: 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 + cards: 0 + circle: 0 + collection: 0 + collection of: 1 + color: 0 + double: 0 + ellipse: 0 + export template: 0 + field: 0 + function: 0 + game: 0 + group: 0 + hexagon: 0 + image: 0 + integer: 0 + keyword: 0 + keywords: 0 + locale: optional, 0 + nil: 0 + object: 0 + package: optional, 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 + symbol: 0 + triangle: 0 + value: 0 diff --git a/src/script/functions/spelling.cpp b/src/script/functions/spelling.cpp index e57515f9..141f5f9b 100644 --- a/src/script/functions/spelling.cpp +++ b/src/script/functions/spelling.cpp @@ -15,7 +15,7 @@ // ----------------------------------------------------------------------------- : Functions -inline bool spelled_correctly(const String& input, size_t start, size_t end, SpellChecker** checkers, const ScriptValueP& extra_test, Context& ctx) { +inline size_t spelled_correctly(const String& input, size_t start, size_t end, SpellChecker** checkers, const ScriptValueP& extra_test, Context& ctx) { // untag String word = untag(input.substr(start,end-start)); if (word.empty()) return true; @@ -36,8 +36,8 @@ inline bool spelled_correctly(const String& input, size_t start, size_t end, Spe // run through spellchecker(s) word.erase(end_u,String::npos); word.erase(0,start_u); - for (SpellChecker** c = checkers ; *c ; ++c) { - if ((*c)->spell(word)) { + for (size_t i = 0 ; checkers[i] ; ++i) { + if (checkers[i]->spell(word)) { return true; } } @@ -51,12 +51,12 @@ inline bool spelled_correctly(const String& input, size_t start, size_t end, Spe return false; } -void check_word(const String& input, String& out, size_t start, size_t end, SpellChecker** checkers, const ScriptValueP& extra_test, Context& ctx) { +void check_word(const String& tag, const String& input, String& out, size_t start, size_t end, SpellChecker** checkers, const ScriptValueP& extra_test, Context& ctx) { if (start >= end) return; bool good = spelled_correctly(input, start, end, checkers, extra_test, ctx); - if (!good) out += _(""); + if (!good) out += _("<") + tag; out.append(input, start, end-start); - if (!good) out += _(""); + if (!good) out += _(""); // now walk over the words in the input, and mark misspellings String result; size_t word_start = 0, word_end = 0, pos = 0; @@ -91,7 +98,7 @@ SCRIPT_FUNCTION(check_spelling) { } } else if (isSpace(c) || c == EM_DASH || c == EN_DASH) { // word boundary -> check word - check_word(input, result, word_start, word_end, checkers, extra_match, ctx); + check_word(tag, input, result, word_start, word_end, checkers, extra_match, ctx); // non-word characters result.append(input, word_end, pos - word_end + 1); // next @@ -101,7 +108,7 @@ SCRIPT_FUNCTION(check_spelling) { } } // last word - check_word(input, result, word_start, word_end, checkers, extra_match, ctx); + check_word(tag, input, result, word_start, word_end, checkers, extra_match, ctx); result.append(input, word_end, String::npos); // done SCRIPT_RETURN(result); diff --git a/src/util/spell_checker.cpp b/src/util/spell_checker.cpp index 6b8c8e9c..0291184c 100644 --- a/src/util/spell_checker.cpp +++ b/src/util/spell_checker.cpp @@ -71,8 +71,7 @@ void SpellChecker::destroyAll() { // ----------------------------------------------------------------------------- : Spell checker : use -bool SpellChecker::spell(const String& word) { - if (word.empty()) return true; // empty word is okay +bool SpellChecker::convert_encoding(const String& word, CharBuffer& out) { // fix curly quotes, especially apstrophes String fixed; FOR_EACH_CONST(c,word) { @@ -96,16 +95,20 @@ bool SpellChecker::spell(const String& word) { } } // convert encoding - #ifdef UNICODE - wxCharBuffer str = fixed.mb_str(encoding); - #else - wxCharBuffer str = fixed.mb_str(encoding); - #endif - if (*str == '\0') { + out = fixed.mb_str(encoding); + if (*out == '\0') { // If encoding fails we get an empty string, since the word was not empty this can never happen // words that can't be encoded are not in the dictionary, so they are wrong. return false; + } else { + return true; } +} + +bool SpellChecker::spell(const String& word) { + if (word.empty()) return true; // empty word is okay + CharBuffer str; + if (!convert_encoding(word,str)) return false; return Hunspell::spell(str); } @@ -115,3 +118,16 @@ bool SpellChecker::spell_with_punctuation(const String& word) { if (start >= end) return true; // just punctuation is wrong return spell(word.substr(start,end-start)); } + +void SpellChecker::suggest(const String& word, vector& suggestions_out) { + CharBuffer str; + if (!convert_encoding(word,str)) return; + // call Hunspell + char** suggestions; + int num_suggestions = Hunspell::suggest(&suggestions, str); + // copy sugestions + for (int i = 0 ; i < num_suggestions ; ++i) { + suggestions_out.push_back(String(suggestions[i],encoding)); + } + free(suggestions); +} diff --git a/src/util/spell_checker.hpp b/src/util/spell_checker.hpp index 52ffae0b..88afa128 100644 --- a/src/util/spell_checker.hpp +++ b/src/util/spell_checker.hpp @@ -14,6 +14,12 @@ DECLARE_POINTER_TYPE(SpellChecker); +#ifdef UNICODE + typedef wxCharBuffer CharBuffer; +#else + typedef char* CharBuffer; +#endif + // ----------------------------------------------------------------------------- : Spell checker /// A spelling checker for a particular language @@ -33,9 +39,13 @@ class SpellChecker : public Hunspell, public IntrusivePtrBase { /// Check the spelling of a single word, ignore punctuation bool spell_with_punctuation(const String& word); + /// Give spelling suggestions + void suggest(const String& word, vector& suggestions_out); + private: /// Convert between String and dictionary encoding wxCSConv encoding; + bool convert_encoding(const String& word, CharBuffer& out); SpellChecker(const char* aff_path, const char* dic_path); static map spellers; //< Cached checkers for each language diff --git a/src/util/window_id.hpp b/src/util/window_id.hpp index b740b51c..65595c06 100644 --- a/src/util/window_id.hpp +++ b/src/util/window_id.hpp @@ -120,8 +120,14 @@ enum ChildMenuID { , ID_FORMAT_REMINDER , ID_INSERT_SYMBOL + // Spelling errors +, ID_SPELLING_ADD_TO_DICT = 6301 +, ID_SPELLING_NO_SUGGEST +, ID_SPELLING_SUGGEST +, ID_SPELLING_SUGGEST_MAX = 6399 + // Graph menu -, ID_GRAPH_PIE = 6301 // corresponds to GraphType +, ID_GRAPH_PIE = 6401 // corresponds to GraphType , ID_GRAPH_BAR , ID_GRAPH_STACK , ID_GRAPH_SCATTER