X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FHunspellChecker.cpp;h=30d799a7f2243ad9d6a26b5cd01f358202d87d6d;hb=2098f1d8c20d51e63e670bcdc9da8996068975bf;hp=c51c0001a6b29d8dc967b3358d1e9bdee9fa2210;hpb=1f53de65928c5d09b343c2beed9f37060e82b611;p=lyx.git diff --git a/src/HunspellChecker.cpp b/src/HunspellChecker.cpp index c51c0001a6..30d799a7f2 100644 --- a/src/HunspellChecker.cpp +++ b/src/HunspellChecker.cpp @@ -15,20 +15,25 @@ #include "LyXRC.h" #include "WordLangTuple.h" -#include "support/lassert.h" +#include "frontends/alert.h" + #include "support/debug.h" #include "support/docstring_list.h" +#include "support/filetools.h" +#include "support/FileName.h" +#include "support/gettext.h" +#include "support/lassert.h" +#include "support/lstrings.h" +#include "support/os.h" #include #include #include -// FIXME (Abdel): I still got linking problems but if anybody wants -// to try, defines this to 1. -#define TRY_HUNSPELL 0 - using namespace std; +using namespace lyx::support; +using namespace lyx::support::os; namespace lyx { @@ -54,24 +59,71 @@ struct HunspellChecker::Private HunspellChecker::Private::~Private() { -#if TRY_HUNSPELL Spellers::iterator it = spellers_.begin(); Spellers::iterator end = spellers_.end(); for (; it != end; ++it) { delete it->second; } -#endif +} + + +namespace { +bool haveLanguageFiles(string const & hpath) +{ + FileName const affix(hpath + ".aff"); + FileName const dict(hpath + ".dic"); + if (!affix.isReadableFile()) { + // FIXME: We should indicate somehow that this language is not + // supported. + LYXERR(Debug::FILES, "Hunspell affix file " << affix << " does not exist"); + return false; + } + if (!dict.isReadableFile()) { + LYXERR(Debug::FILES, "Hunspell dictionary file " << dict << " does not exist"); + return false; + } + return true; +} } Hunspell * HunspellChecker::Private::addSpeller(string const & lang) { - // FIXME: not implemented! + string hunspell_path = lyxrc.hunspelldir_path; + LYXERR(Debug::FILES, "hunspell path: " << external_path(hunspell_path)); + if (hunspell_path.empty()) { + // FIXME We'd like to issue a better error message here, but there seems + // to be a problem about thread safety, or something of the sort. If + // we issue the message using frontend::Alert, then the code comes + // back through here while the box is waiting, and causes some kind + // of crash. + static bool warned = false; + if (!warned) { + warned = true; + LYXERR0("Hunspell path not set."); + //frontend::Alert::error(_("Hunspell Path Not Found"), + // _("You must set the Hunspell dictionary path in Tools>Preferences>Paths.")); + } + return 0; + } - // FIXME: We should we indicate somehow that this language is not - // supported. - return 0; + hunspell_path = external_path(addName(hunspell_path, lang)); + if (!haveLanguageFiles(hunspell_path)) { + // try with '_' replaced by '-' + hunspell_path = subst(hunspell_path, '_', '-'); + if (!haveLanguageFiles(hunspell_path)) { + // FIXME: We should indicate somehow that this language is not + // supported, probably by popping a warning. But we'll need to + // remember which warnings we've issued. + return 0; + } + } + FileName const affix(hunspell_path + ".aff"); + FileName const dict(hunspell_path + ".dic"); + Hunspell * h = new Hunspell(affix.absFilename().c_str(), dict.absFilename().c_str()); + spellers_[lang] = h; + return h; } @@ -99,35 +151,37 @@ HunspellChecker::~HunspellChecker() SpellChecker::Result HunspellChecker::check(WordLangTuple const & wl) { string const word_to_check = to_utf8(wl.word()); -#if TRY_HUNSPELL Hunspell * h = d->speller(wl.lang_code()); + if (!h) + return OK; int info; if (h->spell(word_to_check.c_str(), &info)) return OK; - // FIXME: What to do with that? - switch (info) { - case SPELL_COMPOUND: - case SPELL_FORBIDDEN: - default: - return UNKNOWN_WORD; + + if (info & SPELL_COMPOUND) { + // FIXME: What to do with that? + LYXERR(Debug::FILES, "Hunspell compound word found " << word_to_check); + } + if (info & SPELL_FORBIDDEN) { + // FIXME: What to do with that? + LYXERR(Debug::FILES, "Hunspell explicit forbidden word found " << word_to_check); } + return UNKNOWN_WORD; -#endif - return OK; } void HunspellChecker::insert(WordLangTuple const & wl) { string const word_to_check = to_utf8(wl.word()); -#if TRY_HUNSPELL Hunspell * h = d->speller(wl.lang_code()); + if (!h) + return; h->add(word_to_check.c_str()); -#endif } -void HunspellChecker::accept(WordLangTuple const & word) +void HunspellChecker::accept(WordLangTuple const &) { // FIXME: not implemented! } @@ -138,14 +192,16 @@ void HunspellChecker::suggest(WordLangTuple const & wl, { suggestions.clear(); string const word_to_check = to_utf8(wl.word()); -#if TRY_HUNSPELL Hunspell * h = d->speller(wl.lang_code()); - char *** suggestion_list = 0; - int const suggestion_number = h->suggest(suggestion_list, word_to_check.c_str()); - if (suggestion_number == 0) + if (!h) + return; + char ** suggestion_list; + int const suggestion_number = h->suggest(&suggestion_list, word_to_check.c_str()); + if (suggestion_number <= 0) return; - h->free_list(suggestion_list, suggestion_number); -#endif + for (int i = 0; i != suggestion_number; ++i) + suggestions.push_back(from_utf8(suggestion_list[i])); + h->free_list(&suggestion_list, suggestion_number); }