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"
33 enchant::Broker & broker()
36 static enchant::Broker thebroker;
39 return *enchant::Broker::instance();
45 enchant::Dict * speller;
48 typedef map<string, Speller> Spellers;
52 struct EnchantChecker::Private
59 /// add a speller of the given language
60 enchant::Dict * addSpeller(string const & lang);
63 enchant::Dict * speller(string const & lang);
70 EnchantChecker::Private::~Private()
72 Spellers::iterator it = spellers_.begin();
73 Spellers::iterator end = spellers_.end();
75 for (; it != end; ++it)
76 delete it->second.speller;
80 enchant::Dict * EnchantChecker::Private::addSpeller(string const & lang)
85 LYXERR(Debug::FILES, "request enchant speller for language " << lang);
86 m.speller = broker().request_dict(lang);
88 catch (enchant::Exception & e) {
89 // FIXME error handling?
90 const char * what = e.what();
91 LYXERR(Debug::FILES, "cannot add enchant speller: " <<
92 ((what && *what) ? what : "unspecified enchant exception in request_dict()"));
100 enchant::Dict * EnchantChecker::Private::speller(string const & lang)
102 Spellers::iterator it = spellers_.find(lang);
103 if (it != spellers_.end())
104 return it->second.speller;
106 return addSpeller(lang);
110 EnchantChecker::EnchantChecker()
115 EnchantChecker::~EnchantChecker()
121 SpellChecker::Result EnchantChecker::check(WordLangTuple const & word,
122 std::vector<WordLangTuple> const & docdict)
124 enchant::Dict * m = d->speller(word.lang()->code());
127 return NO_DICTIONARY;
129 if (word.word().empty())
132 string utf8word = to_utf8(word.word());
134 if (m->check(utf8word))
137 vector<WordLangTuple>::const_iterator it = docdict.begin();
138 for (; it != docdict.end(); ++it) {
139 if (it->lang()->code() != word.lang()->code())
141 if (it->word() == word.word())
142 return DOCUMENT_LEARNED_WORD;
149 void EnchantChecker::advanceChangeNumber()
155 void EnchantChecker::insert(WordLangTuple const & word)
157 enchant::Dict * m = d->speller(word.lang()->code());
159 m->add(to_utf8(word.word()));
160 advanceChangeNumber();
165 void EnchantChecker::remove(WordLangTuple const & word)
167 enchant::Dict * m = d->speller(word.lang()->code());
169 m->remove(to_utf8(word.word()));
170 advanceChangeNumber();
175 void EnchantChecker::accept(WordLangTuple const & word)
177 enchant::Dict * m = d->speller(word.lang()->code());
179 m->add_to_session(to_utf8(word.word()));
180 advanceChangeNumber();
185 void EnchantChecker::suggest(WordLangTuple const & wl,
186 docstring_list & suggestions)
189 enchant::Dict * m = d->speller(wl.lang()->code());
194 string utf8word = to_utf8(wl.word());
196 vector<string> suggs = m->suggest(utf8word);
197 vector<string>::const_iterator it = suggs.begin();
199 for (; it != suggs.end(); ++it)
200 suggestions.push_back(from_utf8(*it));
204 bool EnchantChecker::hasDictionary(Language const * lang) const
208 return broker().dict_exists(lang->code());
212 int EnchantChecker::numDictionaries() const
214 return d->spellers_.size();
218 docstring const EnchantChecker::error()