2010-01-22 15:26:38 +00:00
|
|
|
/**
|
|
|
|
* \file EnchantChecker.cpp
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
|
|
|
* \author Caolán McNamara
|
|
|
|
* \author Jürgen Spitzmüller
|
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <enchant++.h>
|
|
|
|
|
|
|
|
#include "EnchantChecker.h"
|
|
|
|
#include "LyXRC.h"
|
|
|
|
#include "WordLangTuple.h"
|
|
|
|
|
|
|
|
#include "support/lassert.h"
|
|
|
|
#include "support/debug.h"
|
|
|
|
#include "support/docstring_list.h"
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
namespace lyx {
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
struct Speller {
|
|
|
|
enchant::Dict * speller;
|
|
|
|
};
|
|
|
|
|
2010-07-02 12:38:39 +00:00
|
|
|
typedef map<string, Speller> Spellers;
|
2010-01-22 15:26:38 +00:00
|
|
|
|
|
|
|
} // anon namespace
|
|
|
|
|
|
|
|
struct EnchantChecker::Private
|
|
|
|
{
|
2012-10-27 13:45:27 +00:00
|
|
|
Private()
|
|
|
|
{}
|
2010-01-22 15:26:38 +00:00
|
|
|
|
|
|
|
~Private();
|
|
|
|
|
|
|
|
/// add a speller of the given language
|
|
|
|
enchant::Dict * addSpeller(string const & lang);
|
|
|
|
|
|
|
|
///
|
|
|
|
enchant::Dict * speller(string const & lang);
|
|
|
|
|
|
|
|
/// the spellers
|
|
|
|
Spellers spellers_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
EnchantChecker::Private::~Private()
|
|
|
|
{
|
|
|
|
Spellers::iterator it = spellers_.begin();
|
|
|
|
Spellers::iterator end = spellers_.end();
|
|
|
|
|
2012-10-27 13:45:27 +00:00
|
|
|
for (; it != end; ++it)
|
2010-01-22 15:26:38 +00:00
|
|
|
delete it->second.speller;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
enchant::Dict * EnchantChecker::Private::addSpeller(string const & lang)
|
|
|
|
{
|
|
|
|
enchant::Broker * instance = enchant::Broker::instance();
|
2014-05-18 08:43:32 +00:00
|
|
|
Speller m;
|
2010-02-09 14:14:38 +00:00
|
|
|
|
2014-05-18 08:43:32 +00:00
|
|
|
try {
|
2014-11-18 07:48:02 +00:00
|
|
|
LYXERR(Debug::FILES, "request enchant speller for language " << lang);
|
2014-05-18 08:43:32 +00:00
|
|
|
m.speller = instance->request_dict(lang);
|
|
|
|
}
|
|
|
|
catch (const enchant::Exception & e) {
|
2010-02-09 14:14:38 +00:00
|
|
|
// FIXME error handling?
|
2014-11-18 07:48:02 +00:00
|
|
|
// unfortunately the message of enchant::Exception is unreachable
|
|
|
|
LYXERR(Debug::FILES, "cannot add enchant speller, unspecified enchant exception in request_dict().");
|
2014-05-18 08:43:32 +00:00
|
|
|
m.speller = 0;
|
2010-01-22 15:26:38 +00:00
|
|
|
}
|
2014-05-18 08:43:32 +00:00
|
|
|
spellers_[lang] = m;
|
|
|
|
return m.speller;
|
2010-01-22 15:26:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
enchant::Dict * EnchantChecker::Private::speller(string const & lang)
|
|
|
|
{
|
|
|
|
Spellers::iterator it = spellers_.find(lang);
|
|
|
|
if (it != spellers_.end())
|
|
|
|
return it->second.speller;
|
|
|
|
|
|
|
|
return addSpeller(lang);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-10-27 13:45:27 +00:00
|
|
|
EnchantChecker::EnchantChecker()
|
|
|
|
: d(new Private)
|
|
|
|
{}
|
2010-01-22 15:26:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
EnchantChecker::~EnchantChecker()
|
|
|
|
{
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SpellChecker::Result EnchantChecker::check(WordLangTuple const & word)
|
|
|
|
{
|
2010-02-09 11:26:49 +00:00
|
|
|
enchant::Dict * m = d->speller(word.lang()->code());
|
2010-01-22 15:26:38 +00:00
|
|
|
|
2012-01-11 17:03:49 +00:00
|
|
|
if (!m)
|
|
|
|
return NO_DICTIONARY;
|
|
|
|
|
|
|
|
if (word.word().empty())
|
2010-08-05 20:10:40 +00:00
|
|
|
return WORD_OK;
|
2010-01-22 15:26:38 +00:00
|
|
|
|
2010-07-02 12:38:39 +00:00
|
|
|
string utf8word = to_utf8(word.word());
|
2010-01-22 15:26:38 +00:00
|
|
|
|
|
|
|
if (m->check(utf8word))
|
2010-08-05 20:10:40 +00:00
|
|
|
return WORD_OK;
|
2010-01-22 15:26:38 +00:00
|
|
|
|
|
|
|
return UNKNOWN_WORD;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-09-14 05:24:04 +00:00
|
|
|
void EnchantChecker::advanceChangeNumber()
|
|
|
|
{
|
|
|
|
nextChangeNumber();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-22 15:26:38 +00:00
|
|
|
void EnchantChecker::insert(WordLangTuple const & word)
|
|
|
|
{
|
2014-05-18 08:43:32 +00:00
|
|
|
enchant::Dict * m = d->speller(word.lang()->code());
|
|
|
|
if (m) {
|
|
|
|
m->add(to_utf8(word.word()));
|
2010-09-14 05:24:04 +00:00
|
|
|
advanceChangeNumber();
|
|
|
|
}
|
2010-01-22 15:26:38 +00:00
|
|
|
}
|
2011-04-13 10:55:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
void EnchantChecker::remove(WordLangTuple const & word)
|
|
|
|
{
|
2014-05-18 08:43:32 +00:00
|
|
|
enchant::Dict * m = d->speller(word.lang()->code());
|
|
|
|
if (m) {
|
|
|
|
m->remove(to_utf8(word.word()));
|
2011-04-13 10:55:51 +00:00
|
|
|
advanceChangeNumber();
|
|
|
|
}
|
|
|
|
}
|
2010-01-22 15:26:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
void EnchantChecker::accept(WordLangTuple const & word)
|
|
|
|
{
|
2014-05-18 08:43:32 +00:00
|
|
|
enchant::Dict * m = d->speller(word.lang()->code());
|
|
|
|
if (m) {
|
|
|
|
m->add_to_session(to_utf8(word.word()));
|
2010-09-14 05:24:04 +00:00
|
|
|
advanceChangeNumber();
|
|
|
|
}
|
2010-01-22 15:26:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void EnchantChecker::suggest(WordLangTuple const & wl,
|
|
|
|
docstring_list & suggestions)
|
|
|
|
{
|
|
|
|
suggestions.clear();
|
2010-02-09 11:26:49 +00:00
|
|
|
enchant::Dict * m = d->speller(wl.lang()->code());
|
2010-01-22 15:26:38 +00:00
|
|
|
|
|
|
|
if (!m)
|
|
|
|
return;
|
|
|
|
|
|
|
|
string utf8word = to_utf8(wl.word());
|
|
|
|
|
|
|
|
vector<string> suggs = m->suggest(utf8word);
|
|
|
|
vector<string>::const_iterator it = suggs.begin();
|
|
|
|
|
|
|
|
for (; it != suggs.end(); ++it)
|
|
|
|
suggestions.push_back(from_utf8(*it));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-10 08:10:31 +00:00
|
|
|
bool EnchantChecker::hasDictionary(Language const * lang) const
|
|
|
|
{
|
|
|
|
if (!lang)
|
|
|
|
return false;
|
|
|
|
enchant::Broker * instance = enchant::Broker::instance();
|
|
|
|
return (instance->dict_exists(lang->code()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-01-05 13:19:04 +00:00
|
|
|
int EnchantChecker::numDictionaries() const
|
|
|
|
{
|
|
|
|
return d->spellers_.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-22 15:26:38 +00:00
|
|
|
docstring const EnchantChecker::error()
|
|
|
|
{
|
|
|
|
return docstring();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace lyx
|