]> git.lyx.org Git - lyx.git/blob - src/EnchantChecker.cpp
793bc16fb95da8499743b6c8bc4fc26645ff3ee7
[lyx.git] / src / EnchantChecker.cpp
1 /**
2  * \file EnchantChecker.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Caolán McNamara
7  * \author Jürgen Spitzmüller
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include <enchant++.h>
15
16 #include "EnchantChecker.h"
17 #include "LyXRC.h"
18 #include "WordLangTuple.h"
19
20 #include "support/lassert.h"
21 #include "support/debug.h"
22 #include "support/docstring_list.h"
23
24 #include <map>
25 #include <string>
26
27 using namespace std;
28
29 namespace lyx {
30
31 namespace {
32
33 struct Speller {
34         enchant::Dict * speller;
35 };
36
37 typedef map<string, Speller> Spellers;
38   
39 } // anon namespace
40
41 struct EnchantChecker::Private
42 {
43         Private() {}
44
45         ~Private();
46
47         /// add a speller of the given language
48         enchant::Dict * addSpeller(string const & lang);
49
50         ///
51         enchant::Dict * speller(string const & lang);
52
53         /// the spellers
54         Spellers spellers_;
55 };
56
57
58 EnchantChecker::Private::~Private()
59 {
60         Spellers::iterator it = spellers_.begin();
61         Spellers::iterator end = spellers_.end();
62
63         for (; it != end; ++it) {
64                 delete it->second.speller;
65         }
66 }
67
68
69 enchant::Dict * EnchantChecker::Private::addSpeller(string const & lang)
70 {
71         enchant::Broker * instance = enchant::Broker::instance();
72
73         if (!instance->dict_exists(lang))
74                 // FIXME error handling?
75                 return 0;
76
77         enchant::Dict * dict = instance->request_dict(lang);
78
79         if (dict) {
80                 Speller m;
81                 m.speller = dict;
82                 spellers_[lang] = m;
83                 return m.speller;
84         }
85         // FIXME error handling?
86         return 0;
87 }
88
89
90 enchant::Dict * EnchantChecker::Private::speller(string const & lang)
91 {
92         Spellers::iterator it = spellers_.find(lang);
93         if (it != spellers_.end())
94                 return it->second.speller;
95         
96         return addSpeller(lang);
97 }
98
99
100 EnchantChecker::EnchantChecker(): d(new Private)
101 {
102 }
103
104
105 EnchantChecker::~EnchantChecker()
106 {
107         delete d;
108 }
109
110
111 SpellChecker::Result EnchantChecker::check(WordLangTuple const & word)
112 {
113         enchant::Dict * m = d->speller(word.lang()->code());
114
115         if (!m)
116                 return WORD_OK;
117
118         string utf8word = to_utf8(word.word());
119
120         if (m->check(utf8word))
121                 return WORD_OK;
122
123         return UNKNOWN_WORD;
124 }
125
126
127 void EnchantChecker::insert(WordLangTuple const & word)
128 {
129         Spellers::iterator it = d->spellers_.find(word.lang()->code());
130         if (it != d->spellers_.end())
131                 it->second.speller->add(to_utf8(word.word()));
132 }
133
134
135 void EnchantChecker::accept(WordLangTuple const & word)
136 {
137         Spellers::iterator it = d->spellers_.find(word.lang()->code());
138         if (it != d->spellers_.end())
139                 it->second.speller->add_to_session(to_utf8(word.word()));
140 }
141
142
143 void EnchantChecker::suggest(WordLangTuple const & wl,
144         docstring_list & suggestions)
145 {
146         suggestions.clear();
147         enchant::Dict * m = d->speller(wl.lang()->code());
148
149         if (!m)
150                 return;
151
152         string utf8word = to_utf8(wl.word());
153
154         vector<string> suggs = m->suggest(utf8word);
155         vector<string>::const_iterator it = suggs.begin();
156         
157         for (; it != suggs.end(); ++it)
158                 suggestions.push_back(from_utf8(*it));
159 }
160
161
162 bool EnchantChecker::hasDictionary(Language const * lang) const
163 {
164         if (!lang)
165                 return false;
166         enchant::Broker * instance = enchant::Broker::instance();
167         return (instance->dict_exists(lang->code()));
168 }
169
170
171 docstring const EnchantChecker::error()
172 {
173         return docstring();
174 }
175
176
177 } // namespace lyx