- string hunspell_path = external_path(lyxrc.hunspelldir_path);
- LYXERR(Debug::FILES, "hunspell 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;
- }
-
- 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;
+ Hunspell * h = lookup(lang);
+ if (h) return h;
+
+ setUserPath(lyxrc.hunspelldir_path);
+ return addSpeller(lang);
+}
+
+
+Hunspell * HunspellChecker::Private::lookup(Language const * lang)
+{
+ Spellers::iterator it = spellers_.find(lang->lang());
+ return it != spellers_.end() ? it->second : nullptr;
+}
+
+
+Hunspell * HunspellChecker::Private::addSpeller(Language const * lang, string & path)
+{
+ if (!haveDictionary(lang, path)) {
+ spellers_[lang->lang()] = nullptr;
+ return nullptr;
+ }
+
+ FileName const affix(path + ".aff");
+ FileName const dict(path + ".dic");
+ Hunspell * h = new Hunspell(affix.absFileName().c_str(), dict.absFileName().c_str());
+ LYXERR(Debug::FILES, "Hunspell speller for langage " << lang << " at " << dict << " added.");
+ spellers_[lang->lang()] = h;
+ return h;
+}
+
+
+Hunspell * HunspellChecker::Private::addSpeller(Language const * lang)
+{
+ Hunspell * h = nullptr;
+ for (int p = 0; p < maxLookupSelector() && nullptr == h; ++p) {
+ string lpath = dictPath(p);
+ h = addSpeller(lang, lpath);
+ }
+ if (h) {
+ string const encoding = h->get_dic_encoding();
+ PersonalWordList * pd = new PersonalWordList(lang->lang());
+ pd->load();
+ personal_[lang->lang()] = pd;
+ docstring_list::const_iterator it = pd->begin();
+ docstring_list::const_iterator et = pd->end();
+ for (; it != et; ++it) {
+ string const word_to_add = to_iconv_encoding(*it, encoding);
+ h->add(word_to_add.c_str());