From fe630e052bcb28a66fd5a2cb92aa925fea584890 Mon Sep 17 00:00:00 2001 From: Stjepan Henc Date: Tue, 18 Dec 2012 17:54:53 +0100 Subject: [PATCH] Add Remove Word button to the spellchecker dialog. Updates #1184. --- .../include/libaegisub/spellchecker.h | 4 ++ aegisub/src/dialog_spellchecker.cpp | 10 +++ aegisub/src/dialog_spellchecker.h | 2 + aegisub/src/spellchecker_hunspell.cpp | 66 ++++++++++++++----- aegisub/src/spellchecker_hunspell.h | 6 ++ 5 files changed, 72 insertions(+), 16 deletions(-) diff --git a/aegisub/libaegisub/include/libaegisub/spellchecker.h b/aegisub/libaegisub/include/libaegisub/spellchecker.h index 4dbb41955..dd4500503 100644 --- a/aegisub/libaegisub/include/libaegisub/spellchecker.h +++ b/aegisub/libaegisub/include/libaegisub/spellchecker.h @@ -28,6 +28,10 @@ public: /// @param word Word to add virtual void AddWord(std::string const& word)=0; + /// Remove word from the dictionary + /// @param word Word to remove + virtual void RemoveWord(std::string const& word)=0; + /// Can the word be added to the current dictionary? /// @param word Word to check /// @return Whether or not word can be added diff --git a/aegisub/src/dialog_spellchecker.cpp b/aegisub/src/dialog_spellchecker.cpp index 5e142594c..224cacedf 100644 --- a/aegisub/src/dialog_spellchecker.cpp +++ b/aegisub/src/dialog_spellchecker.cpp @@ -143,6 +143,9 @@ DialogSpellChecker::DialogSpellChecker(agi::Context *context) actions_sizer->Add(add_button = new wxButton(this, -1, _("Add to &dictionary")), button_flags); add_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogSpellChecker::OnAdd, this); + actions_sizer->Add(remove_button = new wxButton(this, -1, _("Remove fro&m dictionary")), button_flags); + remove_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogSpellChecker::OnRemove, this); + actions_sizer->Add(new HelpButton(this, "Spell Checker"), button_flags); actions_sizer->Add(new wxButton(this, wxID_CANCEL), button_flags.Border(0)); @@ -180,6 +183,13 @@ void DialogSpellChecker::OnAdd(wxCommandEvent&) { FindNext(); } +void DialogSpellChecker::OnRemove(wxCommandEvent&) { + // TODO pop-up dialog + + spellchecker->RemoveWord(from_wx(replace_word->GetValue())); + FindNext(); +} + void DialogSpellChecker::OnChangeLanguage(wxCommandEvent&) { wxString code = dictionary_lang_codes[language->GetSelection()]; OPT_SET("Tool/Spell Checker/Language")->SetString(STD_STR(code)); diff --git a/aegisub/src/dialog_spellchecker.h b/aegisub/src/dialog_spellchecker.h index a5b6131d1..d8e89459f 100644 --- a/aegisub/src/dialog_spellchecker.h +++ b/aegisub/src/dialog_spellchecker.h @@ -58,6 +58,7 @@ class DialogSpellChecker : public wxDialog { wxComboBox *language; ///< The list of available languages wxButton *add_button; ///< Add word to currently active dictionary + wxButton *remove_button; ///< Remove word from currently active dictionary wxCheckBox *skip_comments; ///< Skip over commented lines AssDialogue *start_line; ///< The first line checked @@ -87,6 +88,7 @@ class DialogSpellChecker : public wxDialog { void OnReplaceAll(wxCommandEvent&); void OnIgnoreAll(wxCommandEvent&); void OnAdd(wxCommandEvent&); + void OnRemove(wxCommandEvent&); public: DialogSpellChecker(agi::Context *context); diff --git a/aegisub/src/spellchecker_hunspell.cpp b/aegisub/src/spellchecker_hunspell.cpp index 8e2642028..92111a711 100644 --- a/aegisub/src/spellchecker_hunspell.cpp +++ b/aegisub/src/spellchecker_hunspell.cpp @@ -71,6 +71,45 @@ void HunspellSpellChecker::AddWord(std::string const& word) { std::set words; + try { + ReadUserDictionary(words); + } + catch (agi::FileNotFoundError&) { + LOG_I("dictionary/hunspell/add") << "User dictionary not found; creating it"; + } + + // Add the word + words.insert(word); + + WriteUserDictionary(words); +} + +void HunspellSpellChecker::RemoveWord(std::string const& word) { + if (!hunspell) return; + + // Remove it from the in-memory dictionary + hunspell->remove(conv->Convert(word).c_str()); + + std::set words; + + try { + ReadUserDictionary(words); + } + catch (agi::FileNotFoundError&) { + LOG_I("dictionary/hunspell/remove") << "User dictionary not found; nothing to remove"; + return; + } + + auto word_iter = words.find(word); + if (word_iter != words.end()) { + words.erase(word_iter); + + WriteUserDictionary(words); + } +} + +void HunspellSpellChecker::ReadUserDictionary(std::set &words) +{ // Ensure that the path exists wxFileName fn(userDicPath); if (!fn.DirExists()) { @@ -78,22 +117,17 @@ void HunspellSpellChecker::AddWord(std::string const& word) { } // Read the old contents of the user's dictionary else { - try { - agi::scoped_ptr stream(agi::io::Open(STD_STR(userDicPath))); - remove_copy_if( - ++agi::line_iterator(*stream), - agi::line_iterator(), - inserter(words, words.end()), - [](std::string const& str) { return str.empty(); }); - } - catch (agi::FileNotFoundError&) { - LOG_I("dictionary/hunspell/add") << "User dictionary not found; creating it"; - } + agi::scoped_ptr stream(agi::io::Open(STD_STR(userDicPath))); + remove_copy_if( + ++agi::line_iterator(*stream), + agi::line_iterator(), + inserter(words, words.end()), + [](std::string const& str) { return str.empty(); }); } +} - // Add the word - words.insert(word); - +void HunspellSpellChecker::WriteUserDictionary(std::set const& words) +{ // Write the new dictionary { agi::io::Save writer(STD_STR(userDicPath)); @@ -101,8 +135,8 @@ void HunspellSpellChecker::AddWord(std::string const& word) { copy(words.begin(), words.end(), std::ostream_iterator(writer.Get(), "\n")); } - // Announce a language change so that any other spellcheckers pick up the - // new word + // Announce a language change so that any other spellcheckers reload the + // current dictionary to get the addition/removal lang_listener.Block(); OPT_SET("Tool/Spell Checker/Language")->SetString(OPT_GET("Tool/Spell Checker/Language")->GetString()); lang_listener.Unblock(); diff --git a/aegisub/src/spellchecker_hunspell.h b/aegisub/src/spellchecker_hunspell.h index 97be2f02b..eb31aa73a 100644 --- a/aegisub/src/spellchecker_hunspell.h +++ b/aegisub/src/spellchecker_hunspell.h @@ -56,11 +56,17 @@ class HunspellSpellChecker : public agi::SpellChecker { /// Dictionary path change handler void OnPathChanged(); + /// Load words from custom dictionary + void ReadUserDictionary(std::set &words); + /// Save words to custom dictionary + void WriteUserDictionary(std::set const& words); + public: HunspellSpellChecker(); ~HunspellSpellChecker(); void AddWord(std::string const& word); + void RemoveWord(std::string const& word); bool CanAddWord(std::string const& word); bool CheckWord(std::string const& word); std::vector GetSuggestions(std::string const& word);