mirror of https://github.com/odrling/Aegisub
Move the spellchecker base class to libaegisub
This commit is contained in:
parent
47bafe4b9f
commit
76adcad999
|
@ -489,6 +489,10 @@
|
||||||
RelativePath="..\..\libaegisub\include\libaegisub\signal.h"
|
RelativePath="..\..\libaegisub\include\libaegisub\signal.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\libaegisub\include\libaegisub\spellchecker.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\libaegisub\include\libaegisub\thesaurus.h"
|
RelativePath="..\..\libaegisub\include\libaegisub\thesaurus.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
|
||||||
|
//
|
||||||
|
// 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 <string>
|
||||||
|
#include <vector>
|
||||||
|
#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<std::string> GetSuggestions(std::string const& word)=0;
|
||||||
|
|
||||||
|
/// Get a list of languages which dictionaries are present for
|
||||||
|
virtual std::vector<std::string> GetLanguageList()=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -12,3 +12,10 @@ wxArrayString lagi_MRU_wxAS(const wxString &list) {
|
||||||
transform(map->begin(), map->end(), std::back_inserter(work), lagi_wxString);
|
transform(map->begin(), map->end(), std::back_inserter(work), lagi_wxString);
|
||||||
return work;
|
return work;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxArrayString to_wx(std::vector<std::string> const& vec) {
|
||||||
|
wxArrayString ret;
|
||||||
|
ret.reserve(vec.size());
|
||||||
|
transform(vec.begin(), vec.end(), std::back_inserter(ret), lagi_wxString);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#ifndef AGI_PRE
|
#ifndef AGI_PRE
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
#include <wx/arrstr.h>
|
#include <wx/arrstr.h>
|
||||||
|
@ -12,6 +13,7 @@
|
||||||
|
|
||||||
inline wxColour to_wx(agi::Color color) { return wxColour(color.r, color.g, color.b, 255 - color.a); }
|
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); }
|
inline wxString to_wx(std::string const& str) { return wxString(str.c_str(), wxConvUTF8); }
|
||||||
|
wxArrayString to_wx(std::vector<std::string> const& vec);
|
||||||
|
|
||||||
inline agi::Color from_wx(wxColour color) { return agi::Color(color.Red(), color.Green(), color.Blue(), 255 - color.Alpha()); }
|
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()); }
|
inline std::string from_wx(wxString const& str) { return std::string(str.utf8_str()); }
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include <libaegisub/exception.h>
|
#include <libaegisub/exception.h>
|
||||||
|
#include <libaegisub/spellchecker.h>
|
||||||
|
|
||||||
static void save_skip_comments(wxCommandEvent &evt) {
|
static void save_skip_comments(wxCommandEvent &evt) {
|
||||||
OPT_SET("Tool/Spell Checker/Skip Comments")->SetBool(!!evt.GetInt());
|
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");
|
throw agi::UserCancelException("No spellchecker available");
|
||||||
}
|
}
|
||||||
|
|
||||||
dictionary_lang_codes = spellchecker->GetLanguageList();
|
dictionary_lang_codes = to_wx(spellchecker->GetLanguageList());
|
||||||
if (dictionary_lang_codes.empty()) {
|
if (dictionary_lang_codes.empty()) {
|
||||||
wxMessageBox("No spellchecker dictionaries available.", "Error", wxOK | wxICON_ERROR | wxCENTER);
|
wxMessageBox("No spellchecker dictionaries available.", "Error", wxOK | wxICON_ERROR | wxCENTER);
|
||||||
throw agi::UserCancelException("No spellchecker dictionaries available");
|
throw agi::UserCancelException("No spellchecker dictionaries available");
|
||||||
|
@ -183,7 +184,7 @@ void DialogSpellChecker::OnIgnoreAll(wxCommandEvent&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogSpellChecker::OnAdd(wxCommandEvent&) {
|
void DialogSpellChecker::OnAdd(wxCommandEvent&) {
|
||||||
spellchecker->AddWord(orig_word->GetValue());
|
spellchecker->AddWord(from_wx(orig_word->GetValue()));
|
||||||
FindNext();
|
FindNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +257,7 @@ bool DialogSpellChecker::CheckLine(AssDialogue *active_line, int start_pos, int
|
||||||
word_end = results[j].second + shift;
|
word_end = results[j].second + shift;
|
||||||
wxString word = active_line->Text.Mid(word_start, word_end - word_start);
|
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<wxString, wxString>::const_iterator auto_rep = auto_replace.find(word);
|
std::map<wxString, wxString>::const_iterator auto_rep = auto_replace.find(word);
|
||||||
if (auto_rep == auto_replace.end()) {
|
if (auto_rep == auto_replace.end()) {
|
||||||
|
@ -294,7 +295,7 @@ void DialogSpellChecker::Replace() {
|
||||||
void DialogSpellChecker::SetWord(wxString const& word) {
|
void DialogSpellChecker::SetWord(wxString const& word) {
|
||||||
orig_word->SetValue(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);
|
replace_word->SetValue(suggestions.size() ? suggestions[0] : word);
|
||||||
suggest_list->Clear();
|
suggest_list->Clear();
|
||||||
suggest_list->Append(suggestions);
|
suggest_list->Append(suggestions);
|
||||||
|
@ -302,5 +303,5 @@ void DialogSpellChecker::SetWord(wxString const& word) {
|
||||||
context->textSelectionController->SetSelection(word_start, word_end);
|
context->textSelectionController->SetSelection(word_start, word_end);
|
||||||
context->textSelectionController->SetInsertionPoint(word_end);
|
context->textSelectionController->SetInsertionPoint(word_end);
|
||||||
|
|
||||||
add_button->Enable(spellchecker->CanAddWord(word));
|
add_button->Enable(spellchecker->CanAddWord(from_wx(word)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,13 +24,14 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
|
#include <wx/arrstr.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <libaegisub/scoped_ptr.h>
|
#include <libaegisub/scoped_ptr.h>
|
||||||
|
|
||||||
namespace agi { struct Context; }
|
namespace agi { struct Context; }
|
||||||
|
namespace agi { class SpellChecker; }
|
||||||
class AssDialogue;
|
class AssDialogue;
|
||||||
class SpellChecker;
|
|
||||||
class wxButton;
|
class wxButton;
|
||||||
class wxCheckBox;
|
class wxCheckBox;
|
||||||
class wxComboBox;
|
class wxComboBox;
|
||||||
|
@ -44,7 +45,7 @@ class wxTextCtrl;
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class DialogSpellChecker : public wxDialog {
|
class DialogSpellChecker : public wxDialog {
|
||||||
agi::Context *context; ///< The project context
|
agi::Context *context; ///< The project context
|
||||||
agi::scoped_ptr<SpellChecker> spellchecker; ///< The spellchecking engine
|
agi::scoped_ptr<agi::SpellChecker> spellchecker; ///< The spellchecking engine
|
||||||
|
|
||||||
/// Words which the user has indicated should always be corrected
|
/// Words which the user has indicated should always be corrected
|
||||||
std::map<wxString,wxString> auto_replace;
|
std::map<wxString,wxString> auto_replace;
|
||||||
|
|
|
@ -1,81 +1,30 @@
|
||||||
// Copyright (c) 2006, Rodrigo Braz Monteiro
|
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
|
||||||
// All rights reserved.
|
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
// modification, are permitted provided that the following conditions are met:
|
// 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,
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
// this list of conditions and the following disclaimer.
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
// and/or other materials provided with the distribution.
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
// may be used to endorse or promote products derived from this software
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 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.
|
|
||||||
//
|
//
|
||||||
// Aegisub Project http://www.aegisub.org/
|
// Aegisub Project http://www.aegisub.org/
|
||||||
|
|
||||||
/// @file spellchecker.h
|
/// @file spellchecker.h
|
||||||
/// @brief Declaration of base-class for spell checkers
|
/// @brief Declaration of factory for spell checkers
|
||||||
/// @ingroup main_headers spelling
|
/// @ingroup main_headers spelling
|
||||||
///
|
///
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef AGI_PRE
|
|
||||||
#include <wx/arrstr.h>
|
|
||||||
#include <wx/string.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "factory_manager.h"
|
#include "factory_manager.h"
|
||||||
|
|
||||||
/// @class SpellChecker
|
namespace agi { class SpellChecker; }
|
||||||
/// @brief DOCME
|
|
||||||
///
|
class SpellCheckerFactory : public Factory0<agi::SpellChecker> {
|
||||||
/// DOCME
|
|
||||||
class SpellChecker {
|
|
||||||
public:
|
public:
|
||||||
/// @brief DOCME
|
static agi::SpellChecker *GetSpellChecker();
|
||||||
///
|
|
||||||
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<SpellChecker> {
|
|
||||||
public:
|
|
||||||
static SpellChecker *GetSpellChecker();
|
|
||||||
static void RegisterProviders();
|
static void RegisterProviders();
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,11 +42,7 @@
|
||||||
#include "include/aegisub/spellchecker.h"
|
#include "include/aegisub/spellchecker.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
/// @brief Get spell checker
|
agi::SpellChecker *SpellCheckerFactory::GetSpellChecker() {
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
SpellChecker *SpellCheckerFactory::GetSpellChecker() {
|
|
||||||
// List of providers
|
|
||||||
std::vector<std::string> list = GetClasses(OPT_GET("Tool/Spell Checker/Backend")->GetString());
|
std::vector<std::string> list = GetClasses(OPT_GET("Tool/Spell Checker/Backend")->GetString());
|
||||||
if (list.empty()) return NULL;
|
if (list.empty()) return NULL;
|
||||||
|
|
||||||
|
@ -54,7 +50,7 @@ SpellChecker *SpellCheckerFactory::GetSpellChecker() {
|
||||||
wxString error;
|
wxString error;
|
||||||
for (unsigned int i=0;i<list.size();i++) {
|
for (unsigned int i=0;i<list.size();i++) {
|
||||||
try {
|
try {
|
||||||
SpellChecker *checker = Create(list[i]);
|
agi::SpellChecker *checker = Create(list[i]);
|
||||||
if (checker) return checker;
|
if (checker) return checker;
|
||||||
}
|
}
|
||||||
catch (wxString const& err) { error += list[i] + " factory: " + err + "\n"; }
|
catch (wxString const& err) { error += list[i] + " factory: " + err + "\n"; }
|
||||||
|
@ -62,16 +58,13 @@ SpellChecker *SpellCheckerFactory::GetSpellChecker() {
|
||||||
catch (...) { error += list[i] + " factory: Unknown error\n"; }
|
catch (...) { error += list[i] + " factory: Unknown error\n"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Failed
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Register all providers
|
|
||||||
///
|
|
||||||
void SpellCheckerFactory::RegisterProviders() {
|
void SpellCheckerFactory::RegisterProviders() {
|
||||||
#ifdef WITH_HUNSPELL
|
#ifdef WITH_HUNSPELL
|
||||||
Register<HunspellSpellChecker>("Hunspell");
|
Register<HunspellSpellChecker>("Hunspell");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> SpellCheckerFactory::map *FactoryBase<SpellChecker *(*)()>::classes = NULL;
|
template<> SpellCheckerFactory::map *FactoryBase<agi::SpellChecker *(*)()>::classes = NULL;
|
||||||
|
|
|
@ -1,31 +1,17 @@
|
||||||
// Copyright (c) 2010, Thomas Goyne <plorkyeran@aegisub.org>
|
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
|
||||||
// All rights reserved.
|
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
// modification, are permitted provided that the following conditions are met:
|
// 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,
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
// this list of conditions and the following disclaimer.
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
// and/or other materials provided with the distribution.
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
// may be used to endorse or promote products derived from this software
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 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.
|
|
||||||
//
|
|
||||||
// Aegisub Project http://www.aegisub.org/
|
|
||||||
|
|
||||||
/// @file spellchecker_hunspell.cpp
|
/// @file spellchecker_hunspell.cpp
|
||||||
/// @brief Hunspell-based spell checker implementation
|
/// @brief Hunspell-based spell checker implementation
|
||||||
|
@ -68,10 +54,10 @@ HunspellSpellChecker::HunspellSpellChecker()
|
||||||
HunspellSpellChecker::~HunspellSpellChecker() {
|
HunspellSpellChecker::~HunspellSpellChecker() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HunspellSpellChecker::CanAddWord(wxString word) {
|
bool HunspellSpellChecker::CanAddWord(std::string const& word) {
|
||||||
if (!hunspell) return false;
|
if (!hunspell) return false;
|
||||||
try {
|
try {
|
||||||
conv->Convert(STD_STR(word));
|
conv->Convert(word);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (agi::charset::ConvError const&) {
|
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;
|
if (!hunspell) return;
|
||||||
|
|
||||||
std::string sword = STD_STR(word);
|
|
||||||
|
|
||||||
// Add it to the in-memory dictionary
|
// Add it to the in-memory dictionary
|
||||||
hunspell->add(conv->Convert(sword).c_str());
|
hunspell->add(conv->Convert(word).c_str());
|
||||||
|
|
||||||
std::set<std::string> words;
|
std::set<std::string> words;
|
||||||
|
|
||||||
|
@ -110,7 +94,7 @@ void HunspellSpellChecker::AddWord(wxString word) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the word
|
// Add the word
|
||||||
words.insert(sword);
|
words.insert(word);
|
||||||
|
|
||||||
// Write the new dictionary
|
// Write the new dictionary
|
||||||
{
|
{
|
||||||
|
@ -126,29 +110,28 @@ void HunspellSpellChecker::AddWord(wxString word) {
|
||||||
lang_listener.Unblock();
|
lang_listener.Unblock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HunspellSpellChecker::CheckWord(wxString word) {
|
bool HunspellSpellChecker::CheckWord(std::string const& word) {
|
||||||
if (!hunspell) return true;
|
if (!hunspell) return true;
|
||||||
try {
|
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&) {
|
catch (agi::charset::ConvError const&) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxArrayString HunspellSpellChecker::GetSuggestions(wxString word) {
|
std::vector<std::string> HunspellSpellChecker::GetSuggestions(std::string const& word) {
|
||||||
wxArrayString suggestions;
|
std::vector<std::string> suggestions;
|
||||||
if (!hunspell) return suggestions;
|
if (!hunspell) return suggestions;
|
||||||
|
|
||||||
// Grab raw from Hunspell
|
|
||||||
char **results;
|
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);
|
suggestions.reserve(n);
|
||||||
// Convert each
|
// Convert suggestions to UTF-8
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
try {
|
try {
|
||||||
suggestions.Add(lagi_wxString(rconv->Convert(results[i])));
|
suggestions.push_back(rconv->Convert(results[i]));
|
||||||
}
|
}
|
||||||
catch (agi::charset::ConvError const&) {
|
catch (agi::charset::ConvError const&) {
|
||||||
// Shouldn't ever actually happen...
|
// Shouldn't ever actually happen...
|
||||||
|
@ -161,7 +144,7 @@ wxArrayString HunspellSpellChecker::GetSuggestions(wxString word) {
|
||||||
return suggestions;
|
return suggestions;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxArrayString HunspellSpellChecker::GetLanguageList() {
|
std::vector<std::string> HunspellSpellChecker::GetLanguageList() {
|
||||||
if (!languages.empty()) return languages;
|
if (!languages.empty()) return languages;
|
||||||
|
|
||||||
wxArrayString dic, aff;
|
wxArrayString dic, aff;
|
||||||
|
@ -172,12 +155,12 @@ wxArrayString HunspellSpellChecker::GetLanguageList() {
|
||||||
wxDir::GetAllFiles(path, &dic, "*.dic", wxDIR_FILES);
|
wxDir::GetAllFiles(path, &dic, "*.dic", wxDIR_FILES);
|
||||||
wxDir::GetAllFiles(path, &aff, "*.aff", 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)) {
|
if (wxFileName::DirExists(path)) {
|
||||||
wxDir::GetAllFiles(path, &dic, "*.dic", wxDIR_FILES);
|
wxDir::GetAllFiles(path, &dic, "*.dic", wxDIR_FILES);
|
||||||
wxDir::GetAllFiles(path, &aff, "*.aff", wxDIR_FILES);
|
wxDir::GetAllFiles(path, &aff, "*.aff", wxDIR_FILES);
|
||||||
}
|
}
|
||||||
if (aff.empty()) return wxArrayString();
|
if (aff.empty()) return std::vector<std::string>();
|
||||||
|
|
||||||
dic.Sort();
|
dic.Sort();
|
||||||
aff.Sort();
|
aff.Sort();
|
||||||
|
@ -194,7 +177,7 @@ wxArrayString HunspellSpellChecker::GetLanguageList() {
|
||||||
else {
|
else {
|
||||||
// Don't insert a language twice if it's in both the user dir and
|
// Don't insert a language twice if it's in both the user dir and
|
||||||
// the app's dir
|
// 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())
|
if (languages.empty() || name != languages.back())
|
||||||
languages.push_back(name);
|
languages.push_back(name);
|
||||||
++i;
|
++i;
|
||||||
|
@ -210,7 +193,7 @@ void HunspellSpellChecker::OnLanguageChanged() {
|
||||||
std::string language = OPT_GET("Tool/Spell Checker/Language")->GetString();
|
std::string language = OPT_GET("Tool/Spell Checker/Language")->GetString();
|
||||||
if (language.empty()) return;
|
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");
|
wxString dataDicRoot = StandardPaths::DecodePath("?data/dictionaries");
|
||||||
|
|
||||||
// If the user has a dic/aff pair in their dictionary path for this language
|
// If the user has a dic/aff pair in their dictionary path for this language
|
||||||
|
|
|
@ -1,29 +1,16 @@
|
||||||
// Copyright (c) 2008, Rodrigo Braz Monteiro
|
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
|
||||||
// All rights reserved.
|
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
// modification, are permitted provided that the following conditions are met:
|
// 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,
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
// this list of conditions and the following disclaimer.
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
// and/or other materials provided with the distribution.
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
// may be used to endorse or promote products derived from this software
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 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.
|
|
||||||
//
|
//
|
||||||
// Aegisub Project http://www.aegisub.org/
|
// Aegisub Project http://www.aegisub.org/
|
||||||
|
|
||||||
|
@ -34,22 +21,16 @@
|
||||||
|
|
||||||
#ifdef WITH_HUNSPELL
|
#ifdef WITH_HUNSPELL
|
||||||
|
|
||||||
#include "include/aegisub/spellchecker.h"
|
#include <libaegisub/spellchecker.h>
|
||||||
|
|
||||||
#include <libaegisub/scoped_ptr.h>
|
#include <libaegisub/scoped_ptr.h>
|
||||||
#include <libaegisub/signal.h>
|
#include <libaegisub/signal.h>
|
||||||
|
|
||||||
namespace agi {
|
namespace agi { namespace charset { class IconvWrapper; } }
|
||||||
namespace charset {
|
|
||||||
class IconvWrapper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class Hunspell;
|
class Hunspell;
|
||||||
|
|
||||||
/// @class HunspellSpellChecker
|
/// @brief Hunspell-based spell checker implementation
|
||||||
/// @brief Hunspell spell checker
|
class HunspellSpellChecker : public agi::SpellChecker {
|
||||||
///
|
|
||||||
class HunspellSpellChecker : public SpellChecker {
|
|
||||||
/// Hunspell instance
|
/// Hunspell instance
|
||||||
agi::scoped_ptr<Hunspell> hunspell;
|
agi::scoped_ptr<Hunspell> hunspell;
|
||||||
|
|
||||||
|
@ -58,7 +39,7 @@ class HunspellSpellChecker : public SpellChecker {
|
||||||
agi::scoped_ptr<agi::charset::IconvWrapper> rconv;
|
agi::scoped_ptr<agi::charset::IconvWrapper> rconv;
|
||||||
|
|
||||||
/// Languages which we have dictionaries for
|
/// Languages which we have dictionaries for
|
||||||
wxArrayString languages;
|
std::vector<std::string> languages;
|
||||||
|
|
||||||
/// Path to user-local dictionary.
|
/// Path to user-local dictionary.
|
||||||
wxString userDicPath;
|
wxString userDicPath;
|
||||||
|
@ -77,27 +58,11 @@ public:
|
||||||
HunspellSpellChecker();
|
HunspellSpellChecker();
|
||||||
~HunspellSpellChecker();
|
~HunspellSpellChecker();
|
||||||
|
|
||||||
/// @brief Add word to dictionary
|
void AddWord(std::string const& word);
|
||||||
/// @param word Word to add.
|
bool CanAddWord(std::string const& word);
|
||||||
void AddWord(wxString word);
|
bool CheckWord(std::string const& word);
|
||||||
|
std::vector<std::string> GetSuggestions(std::string const& word);
|
||||||
/// @brief Can add to dictionary?
|
std::vector<std::string> GetLanguageList();
|
||||||
/// @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();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -58,6 +58,8 @@
|
||||||
#include "thesaurus.h"
|
#include "thesaurus.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <libaegisub/spellchecker.h>
|
||||||
|
|
||||||
/// Event ids
|
/// Event ids
|
||||||
enum {
|
enum {
|
||||||
EDIT_MENU_SPLIT_PRESERVE = 1400,
|
EDIT_MENU_SPLIT_PRESERVE = 1400,
|
||||||
|
@ -670,7 +672,7 @@ void SubsTextEditCtrl::StyleSpellCheck() {
|
||||||
wxString curWord = text.Mid(s,e-s);
|
wxString curWord = text.Mid(s,e-s);
|
||||||
|
|
||||||
// Check if it's valid
|
// Check if it's valid
|
||||||
if (!spellchecker->CheckWord(curWord)) {
|
if (!spellchecker->CheckWord(from_wx(curWord))) {
|
||||||
StartUnicodeStyling(s,32);
|
StartUnicodeStyling(s,32);
|
||||||
SetUnicodeStyling(s,e-s,32);
|
SetUnicodeStyling(s,e-s,32);
|
||||||
}
|
}
|
||||||
|
@ -730,7 +732,7 @@ void SubsTextEditCtrl::OnContextMenu(wxContextMenuEvent &event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
currentWordPos = GetReverseUnicodePosition(activePos);
|
currentWordPos = GetReverseUnicodePosition(activePos);
|
||||||
currentWord = GetWordAtPosition(currentWordPos);
|
currentWord = from_wx(GetWordAtPosition(currentWordPos));
|
||||||
|
|
||||||
wxMenu menu;
|
wxMenu menu;
|
||||||
if (!currentWord.empty()) {
|
if (!currentWord.empty()) {
|
||||||
|
@ -764,9 +766,9 @@ void SubsTextEditCtrl::AddSpellCheckerEntries(wxMenu &menu) {
|
||||||
else {
|
else {
|
||||||
wxMenu *subMenu = new wxMenu;
|
wxMenu *subMenu = new wxMenu;
|
||||||
for (size_t i = 0; i < sugs.size(); ++i)
|
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 {
|
else {
|
||||||
|
@ -774,17 +776,17 @@ void SubsTextEditCtrl::AddSpellCheckerEntries(wxMenu &menu) {
|
||||||
menu.Append(EDIT_MENU_SUGGESTION,_("No correction suggestions"))->Enable(false);
|
menu.Append(EDIT_MENU_SUGGESTION,_("No correction suggestions"))->Enable(false);
|
||||||
|
|
||||||
for (size_t i = 0; i < sugs.size(); ++i)
|
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"
|
// 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
|
// Append language list
|
||||||
menu.Append(-1,_("Spell checker language"), GetLanguagesMenu(
|
menu.Append(-1,_("Spell checker language"), GetLanguagesMenu(
|
||||||
EDIT_MENU_DIC_LANGS,
|
EDIT_MENU_DIC_LANGS,
|
||||||
lagi_wxString(OPT_GET("Tool/Spell Checker/Language")->GetString()),
|
lagi_wxString(OPT_GET("Tool/Spell Checker/Language")->GetString()),
|
||||||
spellchecker->GetLanguageList()));
|
to_wx(spellchecker->GetLanguageList())));
|
||||||
menu.AppendSeparator();
|
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
|
else
|
||||||
menu.Append(EDIT_MENU_THESAURUS,_("No thesaurus suggestions"))->Enable(false);
|
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(
|
menu.Append(-1,_("Thesaurus language"), GetLanguagesMenu(
|
||||||
EDIT_MENU_THES_LANGS,
|
EDIT_MENU_THES_LANGS,
|
||||||
lagi_wxString(OPT_GET("Tool/Thesaurus/Language")->GetString()),
|
lagi_wxString(OPT_GET("Tool/Thesaurus/Language")->GetString()),
|
||||||
thesaurus->GetLanguageList()));
|
to_wx(thesaurus->GetLanguageList())));
|
||||||
menu.AppendSeparator();
|
menu.AppendSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -874,7 +876,7 @@ void SubsTextEditCtrl::OnAddToDictionary(wxCommandEvent &) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubsTextEditCtrl::OnUseSuggestion(wxCommandEvent &event) {
|
void SubsTextEditCtrl::OnUseSuggestion(wxCommandEvent &event) {
|
||||||
wxString suggestion;
|
std::string suggestion;
|
||||||
int sugIdx = event.GetId() - EDIT_MENU_THESAURUS_SUGS;
|
int sugIdx = event.GetId() - EDIT_MENU_THESAURUS_SUGS;
|
||||||
if (sugIdx >= 0) {
|
if (sugIdx >= 0) {
|
||||||
suggestion = lagi_wxString(thesSugs[sugIdx]);
|
suggestion = lagi_wxString(thesSugs[sugIdx]);
|
||||||
|
@ -883,33 +885,32 @@ void SubsTextEditCtrl::OnUseSuggestion(wxCommandEvent &event) {
|
||||||
suggestion = sugs[event.GetId() - EDIT_MENU_SUGGESTIONS];
|
suggestion = sugs[event.GetId() - EDIT_MENU_SUGGESTIONS];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stripe suggestion of parenthesis
|
// Strip suggestion of parenthesis
|
||||||
int pos = suggestion.Find("(");
|
size_t pos = suggestion.find("(");
|
||||||
if (pos != wxNOT_FOUND) {
|
if (pos != suggestion.npos)
|
||||||
suggestion = suggestion.Left(pos-1);
|
suggestion.resize(pos - 1);
|
||||||
}
|
|
||||||
|
|
||||||
// Get boundaries of text being replaced
|
// Get boundaries of text being replaced
|
||||||
int start, end;
|
int start, end;
|
||||||
GetBoundsOfWordAtPosition(currentWordPos, start, end);
|
GetBoundsOfWordAtPosition(currentWordPos, start, end);
|
||||||
|
|
||||||
wxString text = GetText();
|
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
|
// Set selection
|
||||||
SetSelectionU(start,start+suggestion.Length());
|
SetSelectionU(start, start+suggestion.size());
|
||||||
SetFocus();
|
SetFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubsTextEditCtrl::OnSetDicLanguage(wxCommandEvent &event) {
|
void SubsTextEditCtrl::OnSetDicLanguage(wxCommandEvent &event) {
|
||||||
wxArrayString langs = spellchecker->GetLanguageList();
|
std::vector<std::string> langs = spellchecker->GetLanguageList();
|
||||||
|
|
||||||
int index = event.GetId() - EDIT_MENU_DIC_LANGS - 1;
|
int index = event.GetId() - EDIT_MENU_DIC_LANGS - 1;
|
||||||
wxString lang;
|
std::string lang;
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
lang = langs[index];
|
lang = langs[index];
|
||||||
|
|
||||||
OPT_SET("Tool/Spell Checker/Language")->SetString(STD_STR(lang));
|
OPT_SET("Tool/Spell Checker/Language")->SetString(lang);
|
||||||
|
|
||||||
UpdateStyle();
|
UpdateStyle();
|
||||||
}
|
}
|
||||||
|
@ -917,12 +918,12 @@ void SubsTextEditCtrl::OnSetDicLanguage(wxCommandEvent &event) {
|
||||||
void SubsTextEditCtrl::OnSetThesLanguage(wxCommandEvent &event) {
|
void SubsTextEditCtrl::OnSetThesLanguage(wxCommandEvent &event) {
|
||||||
if (!thesaurus) return;
|
if (!thesaurus) return;
|
||||||
|
|
||||||
wxArrayString langs = thesaurus->GetLanguageList();
|
std::vector<std::string> langs = thesaurus->GetLanguageList();
|
||||||
|
|
||||||
int index = event.GetId() - EDIT_MENU_THES_LANGS - 1;
|
int index = event.GetId() - EDIT_MENU_THES_LANGS - 1;
|
||||||
wxString lang;
|
std::string lang;
|
||||||
if (index >= 0) lang = langs[index];
|
if (index >= 0) lang = langs[index];
|
||||||
OPT_SET("Tool/Thesaurus/Language")->SetString(STD_STR(lang));
|
OPT_SET("Tool/Thesaurus/Language")->SetString(lang);
|
||||||
|
|
||||||
UpdateStyle();
|
UpdateStyle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,16 +41,18 @@
|
||||||
|
|
||||||
#include <libaegisub/scoped_ptr.h>
|
#include <libaegisub/scoped_ptr.h>
|
||||||
|
|
||||||
class SpellChecker;
|
|
||||||
class SubsEditBox;
|
class SubsEditBox;
|
||||||
class Thesaurus;
|
class Thesaurus;
|
||||||
namespace agi { struct Context; }
|
namespace agi {
|
||||||
|
class SpellChecker;
|
||||||
|
struct Context;
|
||||||
|
}
|
||||||
|
|
||||||
/// @class SubsTextEditCtrl
|
/// @class SubsTextEditCtrl
|
||||||
/// @brief A Scintilla control with spell checking and syntax highlighting
|
/// @brief A Scintilla control with spell checking and syntax highlighting
|
||||||
class SubsTextEditCtrl : public ScintillaTextCtrl {
|
class SubsTextEditCtrl : public ScintillaTextCtrl {
|
||||||
/// Backend spellchecker to use
|
/// Backend spellchecker to use
|
||||||
agi::scoped_ptr<SpellChecker> spellchecker;
|
agi::scoped_ptr<agi::SpellChecker> spellchecker;
|
||||||
|
|
||||||
/// Backend thesaurus to use
|
/// Backend thesaurus to use
|
||||||
agi::scoped_ptr<Thesaurus> thesaurus;
|
agi::scoped_ptr<Thesaurus> thesaurus;
|
||||||
|
@ -59,13 +61,13 @@ class SubsTextEditCtrl : public ScintillaTextCtrl {
|
||||||
agi::Context *context;
|
agi::Context *context;
|
||||||
|
|
||||||
/// The word right-clicked on, used for spellchecker replacing
|
/// 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
|
/// The beginning of the word right-clicked on, for spellchecker replacing
|
||||||
int currentWordPos;
|
int currentWordPos;
|
||||||
|
|
||||||
/// Spellchecker suggestions for the last right-clicked word
|
/// Spellchecker suggestions for the last right-clicked word
|
||||||
wxArrayString sugs;
|
std::vector<std::string> sugs;
|
||||||
|
|
||||||
/// Thesaurus suggestions for the last right-clicked word
|
/// Thesaurus suggestions for the last right-clicked word
|
||||||
std::vector<std::string> thesSugs;
|
std::vector<std::string> thesSugs;
|
||||||
|
|
|
@ -1,29 +1,16 @@
|
||||||
// Copyright (c) 2011, Thomas Goyne <plorkyeran@aegisub.org>
|
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
|
||||||
// All rights reserved.
|
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
// modification, are permitted provided that the following conditions are met:
|
// 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,
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
// this list of conditions and the following disclaimer.
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
// and/or other materials provided with the distribution.
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
// may be used to endorse or promote products derived from this software
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 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.
|
|
||||||
//
|
//
|
||||||
// Aegisub Project http://www.aegisub.org/
|
// Aegisub Project http://www.aegisub.org/
|
||||||
|
|
||||||
|
@ -43,6 +30,7 @@
|
||||||
|
|
||||||
#include <libaegisub/log.h>
|
#include <libaegisub/log.h>
|
||||||
#include <libaegisub/thesaurus.h>
|
#include <libaegisub/thesaurus.h>
|
||||||
|
#include <libaegisub/util.h>
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
@ -59,12 +47,13 @@ Thesaurus::~Thesaurus() {
|
||||||
// Explicit empty destructor needed for scoped_ptr with incomplete types
|
// Explicit empty destructor needed for scoped_ptr with incomplete types
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thesaurus::Lookup(wxString const& word, std::vector<Entry> *result) {
|
void Thesaurus::Lookup(std::string word, std::vector<Entry> *result) {
|
||||||
if (!impl.get()) return;
|
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<std::string> Thesaurus::GetLanguageList() const {
|
||||||
if (!languages.empty()) return languages;
|
if (!languages.empty()) return languages;
|
||||||
|
|
||||||
wxArrayString idx, dat;
|
wxArrayString idx, dat;
|
||||||
|
@ -97,7 +86,7 @@ wxArrayString Thesaurus::GetLanguageList() const {
|
||||||
else {
|
else {
|
||||||
// Don't insert a language twice if it's in both the user dir and
|
// Don't insert a language twice if it's in both the user dir and
|
||||||
// the app's dir
|
// 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())
|
if (languages.empty() || name != languages.back())
|
||||||
languages.push_back(name);
|
languages.push_back(name);
|
||||||
++i;
|
++i;
|
||||||
|
|
|
@ -1,29 +1,16 @@
|
||||||
// Copyright (c) 2011, Thomas Goyne <plorkyeran@aegisub.org>
|
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
|
||||||
// All rights reserved.
|
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
// modification, are permitted provided that the following conditions are met:
|
// 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,
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
// this list of conditions and the following disclaimer.
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
// and/or other materials provided with the distribution.
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
// may be used to endorse or promote products derived from this software
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 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.
|
|
||||||
//
|
//
|
||||||
// Aegisub Project http://www.aegisub.org/
|
// Aegisub Project http://www.aegisub.org/
|
||||||
|
|
||||||
|
@ -33,10 +20,8 @@
|
||||||
///
|
///
|
||||||
|
|
||||||
#ifndef AGI_PRE
|
#ifndef AGI_PRE
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <wx/arrstr.h>
|
|
||||||
#include <wx/string.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <libaegisub/scoped_ptr.h>
|
#include <libaegisub/scoped_ptr.h>
|
||||||
|
@ -50,7 +35,7 @@ class Thesaurus {
|
||||||
/// The actual thesarus implementation
|
/// The actual thesarus implementation
|
||||||
agi::scoped_ptr<agi::Thesaurus> impl;
|
agi::scoped_ptr<agi::Thesaurus> impl;
|
||||||
/// A cached list of languages available
|
/// A cached list of languages available
|
||||||
mutable wxArrayString languages;
|
mutable std::vector<std::string> languages;
|
||||||
|
|
||||||
/// Thesaurus language change slot
|
/// Thesaurus language change slot
|
||||||
agi::signal::Connection lang_listener;
|
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
|
/// Get a list of synonyms for a word, grouped by possible meanings of the word
|
||||||
/// @param word Word to get synonyms for
|
/// @param word Word to get synonyms for
|
||||||
/// @param[out] result Output list
|
/// @param[out] result Output list
|
||||||
void Lookup(wxString const& word, std::vector<Entry> *result);
|
void Lookup(std::string word, std::vector<Entry> *result);
|
||||||
|
|
||||||
/// Get a list of language codes which thesauri are available for
|
/// Get a list of language codes which thesauri are available for
|
||||||
wxArrayString GetLanguageList() const;
|
std::vector<std::string> GetLanguageList() const;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue