2 * \file EnchantChecker.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Caolán McNamara
7 * \author Jürgen Spitzmüller
9 * Full author contact details are available in file CREDITS.
14 #include <enchant++.h>
16 #include "EnchantChecker.h"
18 #include "WordLangTuple.h"
20 #include "support/lassert.h"
21 #include "support/debug.h"
22 #include "support/docstring_list.h"
34 enchant::Dict * speller;
37 typedef map<string, Speller> Spellers;
41 struct EnchantChecker::Private
48 /// add a speller of the given language
49 enchant::Dict * addSpeller(string const & lang);
52 enchant::Dict * speller(string const & lang);
59 EnchantChecker::Private::~Private()
61 Spellers::iterator it = spellers_.begin();
62 Spellers::iterator end = spellers_.end();
64 for (; it != end; ++it)
65 delete it->second.speller;
69 enchant::Dict * EnchantChecker::Private::addSpeller(string const & lang)
71 enchant::Broker * instance = enchant::Broker::instance();
75 LYXERR(Debug::FILES, "request enchant speller for language " << lang);
76 m.speller = instance->request_dict(lang);
78 catch (const enchant::Exception & e) {
79 // FIXME error handling?
80 // unfortunately the message of enchant::Exception is unreachable
81 LYXERR(Debug::FILES, "cannot add enchant speller, unspecified enchant exception in request_dict().");
89 enchant::Dict * EnchantChecker::Private::speller(string const & lang)
91 Spellers::iterator it = spellers_.find(lang);
92 if (it != spellers_.end())
93 return it->second.speller;
95 return addSpeller(lang);
99 EnchantChecker::EnchantChecker()
104 EnchantChecker::~EnchantChecker()
110 SpellChecker::Result EnchantChecker::check(WordLangTuple const & word)
112 enchant::Dict * m = d->speller(word.lang()->code());
115 return NO_DICTIONARY;
117 if (word.word().empty())
120 string utf8word = to_utf8(word.word());
122 if (m->check(utf8word))
129 void EnchantChecker::advanceChangeNumber()
135 void EnchantChecker::insert(WordLangTuple const & word)
137 enchant::Dict * m = d->speller(word.lang()->code());
139 m->add(to_utf8(word.word()));
140 advanceChangeNumber();
145 void EnchantChecker::remove(WordLangTuple const & word)
147 enchant::Dict * m = d->speller(word.lang()->code());
149 m->remove(to_utf8(word.word()));
150 advanceChangeNumber();
155 void EnchantChecker::accept(WordLangTuple const & word)
157 enchant::Dict * m = d->speller(word.lang()->code());
159 m->add_to_session(to_utf8(word.word()));
160 advanceChangeNumber();
165 void EnchantChecker::suggest(WordLangTuple const & wl,
166 docstring_list & suggestions)
169 enchant::Dict * m = d->speller(wl.lang()->code());
174 string utf8word = to_utf8(wl.word());
176 vector<string> suggs = m->suggest(utf8word);
177 vector<string>::const_iterator it = suggs.begin();
179 for (; it != suggs.end(); ++it)
180 suggestions.push_back(from_utf8(*it));
184 bool EnchantChecker::hasDictionary(Language const * lang) const
188 enchant::Broker * instance = enchant::Broker::instance();
189 return (instance->dict_exists(lang->code()));
193 int EnchantChecker::numDictionaries() const
195 return d->spellers_.size();
199 docstring const EnchantChecker::error()