From 76adcad999e2477c74f476abd1eccba831601d43 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 30 Oct 2012 08:59:47 -0700 Subject: [PATCH] Move the spellchecker base class to libaegisub --- .../libaegisub_vs2008.vcproj | 4 + .../include/libaegisub/spellchecker.h | 52 ++++++++++++ aegisub/src/compat.cpp | 7 ++ aegisub/src/compat.h | 2 + aegisub/src/dialog_spellchecker.cpp | 11 +-- aegisub/src/dialog_spellchecker.h | 5 +- aegisub/src/include/aegisub/spellchecker.h | 83 ++++--------------- aegisub/src/spellchecker.cpp | 13 +-- aegisub/src/spellchecker_hunspell.cpp | 73 +++++++--------- aegisub/src/spellchecker_hunspell.h | 77 +++++------------ aegisub/src/subs_edit_ctrl.cpp | 47 ++++++----- aegisub/src/subs_edit_ctrl.h | 12 +-- aegisub/src/thesaurus.cpp | 45 ++++------ aegisub/src/thesaurus.h | 45 ++++------ 14 files changed, 205 insertions(+), 271 deletions(-) create mode 100644 aegisub/libaegisub/include/libaegisub/spellchecker.h diff --git a/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj b/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj index 3c33d931b..032c86d34 100644 --- a/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj +++ b/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj @@ -489,6 +489,10 @@ RelativePath="..\..\libaegisub\include\libaegisub\signal.h" > + + diff --git a/aegisub/libaegisub/include/libaegisub/spellchecker.h b/aegisub/libaegisub/include/libaegisub/spellchecker.h new file mode 100644 index 000000000..e3418ac29 --- /dev/null +++ b/aegisub/libaegisub/include/libaegisub/spellchecker.h @@ -0,0 +1,52 @@ +// Copyright (c) 2012, Thomas Goyne +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +// Aegisub Project http://www.aegisub.org/ + +#pragma once + +#ifndef LAGI_PRE +#include +#include +#endif + +namespace agi { +class SpellChecker { +public: + virtual ~SpellChecker() { } + + /// Add word to the dictionary + /// @param word Word to add + virtual void AddWord(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 + virtual bool CanAddWord(std::string const& word)=0; + + /// Check if the given word is spelled correctly + /// @param word Word to check + /// @return Whether or not the word is valid + virtual bool CheckWord(std::string const& word)=0; + + /// Get possible corrections for a misspelled word + /// @param word Word to get suggestions for + /// @return List of suggestions, if any + virtual std::vector GetSuggestions(std::string const& word)=0; + + /// Get a list of languages which dictionaries are present for + virtual std::vector GetLanguageList()=0; +}; + +} diff --git a/aegisub/src/compat.cpp b/aegisub/src/compat.cpp index ad579061f..06f1ac398 100644 --- a/aegisub/src/compat.cpp +++ b/aegisub/src/compat.cpp @@ -12,3 +12,10 @@ wxArrayString lagi_MRU_wxAS(const wxString &list) { transform(map->begin(), map->end(), std::back_inserter(work), lagi_wxString); return work; } + +wxArrayString to_wx(std::vector const& vec) { + wxArrayString ret; + ret.reserve(vec.size()); + transform(vec.begin(), vec.end(), std::back_inserter(ret), lagi_wxString); + return ret; +} diff --git a/aegisub/src/compat.h b/aegisub/src/compat.h index 3c2fa9495..a98b47fb8 100644 --- a/aegisub/src/compat.h +++ b/aegisub/src/compat.h @@ -1,5 +1,6 @@ #ifndef AGI_PRE #include +#include #include #include @@ -12,6 +13,7 @@ inline wxColour to_wx(agi::Color color) { return wxColour(color.r, color.g, color.b, 255 - color.a); } inline wxString to_wx(std::string const& str) { return wxString(str.c_str(), wxConvUTF8); } +wxArrayString to_wx(std::vector const& vec); inline agi::Color from_wx(wxColour color) { return agi::Color(color.Red(), color.Green(), color.Blue(), 255 - color.Alpha()); } inline std::string from_wx(wxString const& str) { return std::string(str.utf8_str()); } diff --git a/aegisub/src/dialog_spellchecker.cpp b/aegisub/src/dialog_spellchecker.cpp index b3d696e53..c6582202c 100644 --- a/aegisub/src/dialog_spellchecker.cpp +++ b/aegisub/src/dialog_spellchecker.cpp @@ -48,6 +48,7 @@ #include "utils.h" #include +#include static void save_skip_comments(wxCommandEvent &evt) { OPT_SET("Tool/Spell Checker/Skip Comments")->SetBool(!!evt.GetInt()); @@ -97,7 +98,7 @@ DialogSpellChecker::DialogSpellChecker(agi::Context *context) throw agi::UserCancelException("No spellchecker available"); } - dictionary_lang_codes = spellchecker->GetLanguageList(); + dictionary_lang_codes = to_wx(spellchecker->GetLanguageList()); if (dictionary_lang_codes.empty()) { wxMessageBox("No spellchecker dictionaries available.", "Error", wxOK | wxICON_ERROR | wxCENTER); throw agi::UserCancelException("No spellchecker dictionaries available"); @@ -183,7 +184,7 @@ void DialogSpellChecker::OnIgnoreAll(wxCommandEvent&) { } void DialogSpellChecker::OnAdd(wxCommandEvent&) { - spellchecker->AddWord(orig_word->GetValue()); + spellchecker->AddWord(from_wx(orig_word->GetValue())); FindNext(); } @@ -256,7 +257,7 @@ bool DialogSpellChecker::CheckLine(AssDialogue *active_line, int start_pos, int word_end = results[j].second + shift; wxString word = active_line->Text.Mid(word_start, word_end - word_start); - if (auto_ignore.count(word) || spellchecker->CheckWord(word)) continue; + if (auto_ignore.count(word) || spellchecker->CheckWord(from_wx(word))) continue; std::map::const_iterator auto_rep = auto_replace.find(word); if (auto_rep == auto_replace.end()) { @@ -294,7 +295,7 @@ void DialogSpellChecker::Replace() { void DialogSpellChecker::SetWord(wxString const& word) { orig_word->SetValue(word); - wxArrayString suggestions = spellchecker->GetSuggestions(word); + wxArrayString suggestions = to_wx(spellchecker->GetSuggestions(from_wx(word))); replace_word->SetValue(suggestions.size() ? suggestions[0] : word); suggest_list->Clear(); suggest_list->Append(suggestions); @@ -302,5 +303,5 @@ void DialogSpellChecker::SetWord(wxString const& word) { context->textSelectionController->SetSelection(word_start, word_end); context->textSelectionController->SetInsertionPoint(word_end); - add_button->Enable(spellchecker->CanAddWord(word)); + add_button->Enable(spellchecker->CanAddWord(from_wx(word))); } diff --git a/aegisub/src/dialog_spellchecker.h b/aegisub/src/dialog_spellchecker.h index a96bd3fbd..0fe012395 100644 --- a/aegisub/src/dialog_spellchecker.h +++ b/aegisub/src/dialog_spellchecker.h @@ -24,13 +24,14 @@ #include #include +#include #endif #include namespace agi { struct Context; } +namespace agi { class SpellChecker; } class AssDialogue; -class SpellChecker; class wxButton; class wxCheckBox; class wxComboBox; @@ -44,7 +45,7 @@ class wxTextCtrl; /// DOCME class DialogSpellChecker : public wxDialog { agi::Context *context; ///< The project context - agi::scoped_ptr spellchecker; ///< The spellchecking engine + agi::scoped_ptr spellchecker; ///< The spellchecking engine /// Words which the user has indicated should always be corrected std::map auto_replace; diff --git a/aegisub/src/include/aegisub/spellchecker.h b/aegisub/src/include/aegisub/spellchecker.h index d06d06c0d..de4052d67 100644 --- a/aegisub/src/include/aegisub/spellchecker.h +++ b/aegisub/src/include/aegisub/spellchecker.h @@ -1,81 +1,30 @@ -// Copyright (c) 2006, Rodrigo Braz Monteiro -// All rights reserved. +// Copyright (c) 2012, Thomas Goyne // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. // -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // // Aegisub Project http://www.aegisub.org/ /// @file spellchecker.h -/// @brief Declaration of base-class for spell checkers +/// @brief Declaration of factory for spell checkers /// @ingroup main_headers spelling /// -#pragma once - -#ifndef AGI_PRE -#include -#include -#endif - #include "factory_manager.h" -/// @class SpellChecker -/// @brief DOCME -/// -/// DOCME -class SpellChecker { +namespace agi { class SpellChecker; } + +class SpellCheckerFactory : public Factory0 { public: - /// @brief DOCME - /// - virtual ~SpellChecker() {} - - /// @brief DOCME - /// @param word - /// @return - /// - virtual void AddWord(wxString word) {} - - /// @brief DOCME - /// @param word - /// @return - /// - virtual bool CanAddWord(wxString word) { return false; } - - virtual bool CheckWord(wxString word)=0; - virtual wxArrayString GetSuggestions(wxString word)=0; - - virtual wxArrayString GetLanguageList()=0; -}; - -/// DOCME -/// @class SpellCheckerFactoryManager -/// @brief DOCME -/// -/// DOCME -class SpellCheckerFactory : public Factory0 { -public: - static SpellChecker *GetSpellChecker(); + static agi::SpellChecker *GetSpellChecker(); static void RegisterProviders(); }; diff --git a/aegisub/src/spellchecker.cpp b/aegisub/src/spellchecker.cpp index 453872018..77e3a91d1 100644 --- a/aegisub/src/spellchecker.cpp +++ b/aegisub/src/spellchecker.cpp @@ -42,11 +42,7 @@ #include "include/aegisub/spellchecker.h" #include "main.h" -/// @brief Get spell checker -/// @return -/// -SpellChecker *SpellCheckerFactory::GetSpellChecker() { - // List of providers +agi::SpellChecker *SpellCheckerFactory::GetSpellChecker() { std::vector list = GetClasses(OPT_GET("Tool/Spell Checker/Backend")->GetString()); if (list.empty()) return NULL; @@ -54,7 +50,7 @@ SpellChecker *SpellCheckerFactory::GetSpellChecker() { wxString error; for (unsigned int i=0;i("Hunspell"); #endif } -template<> SpellCheckerFactory::map *FactoryBase::classes = NULL; +template<> SpellCheckerFactory::map *FactoryBase::classes = NULL; diff --git a/aegisub/src/spellchecker_hunspell.cpp b/aegisub/src/spellchecker_hunspell.cpp index a8de07e25..fa8af2cb0 100644 --- a/aegisub/src/spellchecker_hunspell.cpp +++ b/aegisub/src/spellchecker_hunspell.cpp @@ -1,31 +1,17 @@ -// Copyright (c) 2010, Thomas Goyne -// All rights reserved. +// Copyright (c) 2012, Thomas Goyne // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. // -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Aegisub Project http://www.aegisub.org/ /// @file spellchecker_hunspell.cpp /// @brief Hunspell-based spell checker implementation @@ -68,10 +54,10 @@ HunspellSpellChecker::HunspellSpellChecker() HunspellSpellChecker::~HunspellSpellChecker() { } -bool HunspellSpellChecker::CanAddWord(wxString word) { +bool HunspellSpellChecker::CanAddWord(std::string const& word) { if (!hunspell) return false; try { - conv->Convert(STD_STR(word)); + conv->Convert(word); return true; } catch (agi::charset::ConvError const&) { @@ -79,13 +65,11 @@ bool HunspellSpellChecker::CanAddWord(wxString word) { } } -void HunspellSpellChecker::AddWord(wxString word) { +void HunspellSpellChecker::AddWord(std::string const& word) { if (!hunspell) return; - std::string sword = STD_STR(word); - // Add it to the in-memory dictionary - hunspell->add(conv->Convert(sword).c_str()); + hunspell->add(conv->Convert(word).c_str()); std::set words; @@ -110,7 +94,7 @@ void HunspellSpellChecker::AddWord(wxString word) { } // Add the word - words.insert(sword); + words.insert(word); // Write the new dictionary { @@ -126,29 +110,28 @@ void HunspellSpellChecker::AddWord(wxString word) { lang_listener.Unblock(); } -bool HunspellSpellChecker::CheckWord(wxString word) { +bool HunspellSpellChecker::CheckWord(std::string const& word) { if (!hunspell) return true; try { - return hunspell->spell(conv->Convert(STD_STR(word)).c_str()) == 1; + return hunspell->spell(conv->Convert(word).c_str()) == 1; } catch (agi::charset::ConvError const&) { return false; } } -wxArrayString HunspellSpellChecker::GetSuggestions(wxString word) { - wxArrayString suggestions; +std::vector HunspellSpellChecker::GetSuggestions(std::string const& word) { + std::vector suggestions; if (!hunspell) return suggestions; - // Grab raw from Hunspell char **results; - int n = hunspell->suggest(&results,conv->Convert(STD_STR(word)).c_str()); + int n = hunspell->suggest(&results, conv->Convert(word).c_str()); suggestions.reserve(n); - // Convert each + // Convert suggestions to UTF-8 for (int i = 0; i < n; ++i) { try { - suggestions.Add(lagi_wxString(rconv->Convert(results[i]))); + suggestions.push_back(rconv->Convert(results[i])); } catch (agi::charset::ConvError const&) { // Shouldn't ever actually happen... @@ -161,7 +144,7 @@ wxArrayString HunspellSpellChecker::GetSuggestions(wxString word) { return suggestions; } -wxArrayString HunspellSpellChecker::GetLanguageList() { +std::vector HunspellSpellChecker::GetLanguageList() { if (!languages.empty()) return languages; wxArrayString dic, aff; @@ -172,12 +155,12 @@ wxArrayString HunspellSpellChecker::GetLanguageList() { wxDir::GetAllFiles(path, &dic, "*.dic", wxDIR_FILES); wxDir::GetAllFiles(path, &aff, "*.aff", wxDIR_FILES); } - path = StandardPaths::DecodePath(lagi_wxString(OPT_GET("Path/Dictionary")->GetString()) + "/"); + path = StandardPaths::DecodePath(to_wx(OPT_GET("Path/Dictionary")->GetString()) + "/"); if (wxFileName::DirExists(path)) { wxDir::GetAllFiles(path, &dic, "*.dic", wxDIR_FILES); wxDir::GetAllFiles(path, &aff, "*.aff", wxDIR_FILES); } - if (aff.empty()) return wxArrayString(); + if (aff.empty()) return std::vector(); dic.Sort(); aff.Sort(); @@ -194,7 +177,7 @@ wxArrayString HunspellSpellChecker::GetLanguageList() { else { // Don't insert a language twice if it's in both the user dir and // the app's dir - wxString name = wxFileName(aff[j]).GetName(); + std::string name = from_wx(wxFileName(aff[j]).GetName()); if (languages.empty() || name != languages.back()) languages.push_back(name); ++i; @@ -210,7 +193,7 @@ void HunspellSpellChecker::OnLanguageChanged() { std::string language = OPT_GET("Tool/Spell Checker/Language")->GetString(); if (language.empty()) return; - wxString custDicRoot = StandardPaths::DecodePath(lagi_wxString(OPT_GET("Path/Dictionary")->GetString())); + wxString custDicRoot = StandardPaths::DecodePath(to_wx(OPT_GET("Path/Dictionary")->GetString())); wxString dataDicRoot = StandardPaths::DecodePath("?data/dictionaries"); // If the user has a dic/aff pair in their dictionary path for this language diff --git a/aegisub/src/spellchecker_hunspell.h b/aegisub/src/spellchecker_hunspell.h index 4d98968a4..841e2de8b 100644 --- a/aegisub/src/spellchecker_hunspell.h +++ b/aegisub/src/spellchecker_hunspell.h @@ -1,29 +1,16 @@ -// Copyright (c) 2008, Rodrigo Braz Monteiro -// All rights reserved. +// Copyright (c) 2012, Thomas Goyne // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. // -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // // Aegisub Project http://www.aegisub.org/ @@ -34,22 +21,16 @@ #ifdef WITH_HUNSPELL -#include "include/aegisub/spellchecker.h" +#include #include #include -namespace agi { - namespace charset { - class IconvWrapper; - } -} +namespace agi { namespace charset { class IconvWrapper; } } class Hunspell; -/// @class HunspellSpellChecker -/// @brief Hunspell spell checker -/// -class HunspellSpellChecker : public SpellChecker { +/// @brief Hunspell-based spell checker implementation +class HunspellSpellChecker : public agi::SpellChecker { /// Hunspell instance agi::scoped_ptr hunspell; @@ -58,7 +39,7 @@ class HunspellSpellChecker : public SpellChecker { agi::scoped_ptr rconv; /// Languages which we have dictionaries for - wxArrayString languages; + std::vector languages; /// Path to user-local dictionary. wxString userDicPath; @@ -77,27 +58,11 @@ public: HunspellSpellChecker(); ~HunspellSpellChecker(); - /// @brief Add word to dictionary - /// @param word Word to add. - void AddWord(wxString word); - - /// @brief Can add to dictionary? - /// @param word Word to check. - /// @return Whether word can be added or not. - bool CanAddWord(wxString word); - - /// @brief Check if the word is valid. - /// @param word Word to check - /// @return Whether word is valid or not. - bool CheckWord(wxString word); - - /// @brief Get suggestions for word. - /// @param word Word to get suggestions for - /// @return List of suggestions - wxArrayString GetSuggestions(wxString word); - - /// @brief Get a list of languages which dictionaries are present for - wxArrayString GetLanguageList(); + void AddWord(std::string const& word); + bool CanAddWord(std::string const& word); + bool CheckWord(std::string const& word); + std::vector GetSuggestions(std::string const& word); + std::vector GetLanguageList(); }; #endif diff --git a/aegisub/src/subs_edit_ctrl.cpp b/aegisub/src/subs_edit_ctrl.cpp index 345c11d92..db9027f4d 100644 --- a/aegisub/src/subs_edit_ctrl.cpp +++ b/aegisub/src/subs_edit_ctrl.cpp @@ -58,6 +58,8 @@ #include "thesaurus.h" #include "utils.h" +#include + /// Event ids enum { EDIT_MENU_SPLIT_PRESERVE = 1400, @@ -670,7 +672,7 @@ void SubsTextEditCtrl::StyleSpellCheck() { wxString curWord = text.Mid(s,e-s); // Check if it's valid - if (!spellchecker->CheckWord(curWord)) { + if (!spellchecker->CheckWord(from_wx(curWord))) { StartUnicodeStyling(s,32); SetUnicodeStyling(s,e-s,32); } @@ -730,7 +732,7 @@ void SubsTextEditCtrl::OnContextMenu(wxContextMenuEvent &event) { } currentWordPos = GetReverseUnicodePosition(activePos); - currentWord = GetWordAtPosition(currentWordPos); + currentWord = from_wx(GetWordAtPosition(currentWordPos)); wxMenu menu; if (!currentWord.empty()) { @@ -764,9 +766,9 @@ void SubsTextEditCtrl::AddSpellCheckerEntries(wxMenu &menu) { else { wxMenu *subMenu = new wxMenu; for (size_t i = 0; i < sugs.size(); ++i) - subMenu->Append(EDIT_MENU_SUGGESTIONS+i, sugs[i]); + subMenu->Append(EDIT_MENU_SUGGESTIONS+i, to_wx(sugs[i])); - menu.Append(-1, wxString::Format(_("Spell checker suggestions for \"%s\""),currentWord), subMenu); + menu.Append(-1, wxString::Format(_("Spell checker suggestions for \"%s\""), to_wx(currentWord)), subMenu); } } else { @@ -774,17 +776,17 @@ void SubsTextEditCtrl::AddSpellCheckerEntries(wxMenu &menu) { menu.Append(EDIT_MENU_SUGGESTION,_("No correction suggestions"))->Enable(false); for (size_t i = 0; i < sugs.size(); ++i) - menu.Append(EDIT_MENU_SUGGESTIONS+i, sugs[i]); + menu.Append(EDIT_MENU_SUGGESTIONS+i, to_wx(sugs[i])); // Append "add word" - menu.Append(EDIT_MENU_ADD_TO_DICT, wxString::Format(_("Add \"%s\" to dictionary"), currentWord))->Enable(spellchecker->CanAddWord(currentWord)); + menu.Append(EDIT_MENU_ADD_TO_DICT, wxString::Format(_("Add \"%s\" to dictionary"), to_wx(currentWord)))->Enable(spellchecker->CanAddWord(currentWord)); } // Append language list menu.Append(-1,_("Spell checker language"), GetLanguagesMenu( EDIT_MENU_DIC_LANGS, lagi_wxString(OPT_GET("Tool/Spell Checker/Language")->GetString()), - spellchecker->GetLanguageList())); + to_wx(spellchecker->GetLanguageList()))); menu.AppendSeparator(); } @@ -821,7 +823,7 @@ void SubsTextEditCtrl::AddThesaurusEntries(wxMenu &menu) { } } - menu.Append(-1, wxString::Format(_("Thesaurus suggestions for \"%s\""), currentWord), thesMenu); + menu.Append(-1, wxString::Format(_("Thesaurus suggestions for \"%s\""), to_wx(currentWord)), thesMenu); } else menu.Append(EDIT_MENU_THESAURUS,_("No thesaurus suggestions"))->Enable(false); @@ -830,7 +832,7 @@ void SubsTextEditCtrl::AddThesaurusEntries(wxMenu &menu) { menu.Append(-1,_("Thesaurus language"), GetLanguagesMenu( EDIT_MENU_THES_LANGS, lagi_wxString(OPT_GET("Tool/Thesaurus/Language")->GetString()), - thesaurus->GetLanguageList())); + to_wx(thesaurus->GetLanguageList()))); menu.AppendSeparator(); } @@ -874,7 +876,7 @@ void SubsTextEditCtrl::OnAddToDictionary(wxCommandEvent &) { } void SubsTextEditCtrl::OnUseSuggestion(wxCommandEvent &event) { - wxString suggestion; + std::string suggestion; int sugIdx = event.GetId() - EDIT_MENU_THESAURUS_SUGS; if (sugIdx >= 0) { suggestion = lagi_wxString(thesSugs[sugIdx]); @@ -883,33 +885,32 @@ void SubsTextEditCtrl::OnUseSuggestion(wxCommandEvent &event) { suggestion = sugs[event.GetId() - EDIT_MENU_SUGGESTIONS]; } - // Stripe suggestion of parenthesis - int pos = suggestion.Find("("); - if (pos != wxNOT_FOUND) { - suggestion = suggestion.Left(pos-1); - } + // Strip suggestion of parenthesis + size_t pos = suggestion.find("("); + if (pos != suggestion.npos) + suggestion.resize(pos - 1); // Get boundaries of text being replaced int start, end; GetBoundsOfWordAtPosition(currentWordPos, start, end); wxString text = GetText(); - SetText(text.Left(std::max(0, start)) + suggestion + text.Mid(end)); + SetText(text.Left(std::max(0, start)) + to_wx(suggestion) + text.Mid(end)); // Set selection - SetSelectionU(start,start+suggestion.Length()); + SetSelectionU(start, start+suggestion.size()); SetFocus(); } void SubsTextEditCtrl::OnSetDicLanguage(wxCommandEvent &event) { - wxArrayString langs = spellchecker->GetLanguageList(); + std::vector langs = spellchecker->GetLanguageList(); int index = event.GetId() - EDIT_MENU_DIC_LANGS - 1; - wxString lang; + std::string lang; if (index >= 0) lang = langs[index]; - OPT_SET("Tool/Spell Checker/Language")->SetString(STD_STR(lang)); + OPT_SET("Tool/Spell Checker/Language")->SetString(lang); UpdateStyle(); } @@ -917,12 +918,12 @@ void SubsTextEditCtrl::OnSetDicLanguage(wxCommandEvent &event) { void SubsTextEditCtrl::OnSetThesLanguage(wxCommandEvent &event) { if (!thesaurus) return; - wxArrayString langs = thesaurus->GetLanguageList(); + std::vector langs = thesaurus->GetLanguageList(); int index = event.GetId() - EDIT_MENU_THES_LANGS - 1; - wxString lang; + std::string lang; if (index >= 0) lang = langs[index]; - OPT_SET("Tool/Thesaurus/Language")->SetString(STD_STR(lang)); + OPT_SET("Tool/Thesaurus/Language")->SetString(lang); UpdateStyle(); } diff --git a/aegisub/src/subs_edit_ctrl.h b/aegisub/src/subs_edit_ctrl.h index dab6e4972..07c967c78 100644 --- a/aegisub/src/subs_edit_ctrl.h +++ b/aegisub/src/subs_edit_ctrl.h @@ -41,16 +41,18 @@ #include -class SpellChecker; class SubsEditBox; class Thesaurus; -namespace agi { struct Context; } +namespace agi { + class SpellChecker; + struct Context; +} /// @class SubsTextEditCtrl /// @brief A Scintilla control with spell checking and syntax highlighting class SubsTextEditCtrl : public ScintillaTextCtrl { /// Backend spellchecker to use - agi::scoped_ptr spellchecker; + agi::scoped_ptr spellchecker; /// Backend thesaurus to use agi::scoped_ptr thesaurus; @@ -59,13 +61,13 @@ class SubsTextEditCtrl : public ScintillaTextCtrl { agi::Context *context; /// The word right-clicked on, used for spellchecker replacing - wxString currentWord; + std::string currentWord; /// The beginning of the word right-clicked on, for spellchecker replacing int currentWordPos; /// Spellchecker suggestions for the last right-clicked word - wxArrayString sugs; + std::vector sugs; /// Thesaurus suggestions for the last right-clicked word std::vector thesSugs; diff --git a/aegisub/src/thesaurus.cpp b/aegisub/src/thesaurus.cpp index 00f8f6b27..78d30f4bb 100644 --- a/aegisub/src/thesaurus.cpp +++ b/aegisub/src/thesaurus.cpp @@ -1,29 +1,16 @@ -// Copyright (c) 2011, Thomas Goyne -// All rights reserved. +// Copyright (c) 2012, Thomas Goyne // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. // -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // // Aegisub Project http://www.aegisub.org/ @@ -43,6 +30,7 @@ #include #include +#include #include "compat.h" #include "main.h" @@ -59,12 +47,13 @@ Thesaurus::~Thesaurus() { // Explicit empty destructor needed for scoped_ptr with incomplete types } -void Thesaurus::Lookup(wxString const& word, std::vector *result) { +void Thesaurus::Lookup(std::string word, std::vector *result) { if (!impl.get()) return; - impl->Lookup(STD_STR(word.Lower()), result); + agi::util::str_lower(word); + impl->Lookup(word, result); } -wxArrayString Thesaurus::GetLanguageList() const { +std::vector Thesaurus::GetLanguageList() const { if (!languages.empty()) return languages; wxArrayString idx, dat; @@ -97,7 +86,7 @@ wxArrayString Thesaurus::GetLanguageList() const { else { // Don't insert a language twice if it's in both the user dir and // the app's dir - wxString name = wxFileName(dat[j]).GetName().Mid(3); + std::string name = from_wx(wxFileName(dat[j]).GetName().Mid(3)); if (languages.empty() || name != languages.back()) languages.push_back(name); ++i; diff --git a/aegisub/src/thesaurus.h b/aegisub/src/thesaurus.h index 8ef41380b..70b9f6494 100644 --- a/aegisub/src/thesaurus.h +++ b/aegisub/src/thesaurus.h @@ -1,29 +1,16 @@ -// Copyright (c) 2011, Thomas Goyne -// All rights reserved. +// Copyright (c) 2012, Thomas Goyne // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. // -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // // Aegisub Project http://www.aegisub.org/ @@ -33,10 +20,8 @@ /// #ifndef AGI_PRE +#include #include - -#include -#include #endif #include @@ -50,7 +35,7 @@ class Thesaurus { /// The actual thesarus implementation agi::scoped_ptr impl; /// A cached list of languages available - mutable wxArrayString languages; + mutable std::vector languages; /// Thesaurus language change slot agi::signal::Connection lang_listener; @@ -71,8 +56,8 @@ public: /// Get a list of synonyms for a word, grouped by possible meanings of the word /// @param word Word to get synonyms for /// @param[out] result Output list - void Lookup(wxString const& word, std::vector *result); + void Lookup(std::string word, std::vector *result); /// Get a list of language codes which thesauri are available for - wxArrayString GetLanguageList() const; + std::vector GetLanguageList() const; };