]> git.lyx.org Git - lyx.git/blob - src/frontends/controllers/ControlSpellchecker.C
Fix a bunch of doxygen warnings.
[lyx.git] / src / frontends / controllers / ControlSpellchecker.C
1 /**
2  * \file ControlSpellchecker.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "ControlSpellchecker.h"
14 #include "ViewBase.h"
15
16 #include "buffer.h"
17 #include "bufferparams.h"
18 #include "BufferView.h"
19 #include "debug.h"
20 #include "gettext.h"
21 #include "language.h"
22 #include "lyxrc.h"
23
24 #include "ispell.h"
25 #ifdef USE_PSPELL
26 # include "pspell.h"
27 #else
28 #ifdef USE_ASPELL
29 # include "aspell_local.h"
30 #endif
31 #endif
32
33 #include "support/tostr.h"
34
35 #include "frontends/Alert.h"
36
37
38 using lyx::support::bformat;
39
40 using std::endl;
41 using std::string;
42
43
44 ControlSpellchecker::ControlSpellchecker(LyXView & lv, Dialogs & d)
45         : ControlDialogBD(lv, d),
46           newval_(0.0), oldval_(0), newvalue_(0), count_(0)
47 {}
48
49
50 ControlSpellchecker::~ControlSpellchecker()
51 {}
52
53
54 void ControlSpellchecker::setParams()
55 {
56         lyxerr[Debug::GUI] << "spell setParams" << endl;
57         startSession();
58 }
59
60
61 void ControlSpellchecker::clearParams()
62 {
63         lyxerr[Debug::GUI] << "spell clearParams" << endl;
64         endSession();
65 }
66
67
68 namespace {
69
70 SpellBase * getSpeller(BufferParams const & bp)
71 {
72         string lang = (lyxrc.isp_use_alt_lang)
73                       ? lyxrc.isp_alt_lang
74                       : bp.language->code();
75
76 #ifdef USE_ASPELL
77         if (lyxrc.use_spell_lib)
78                 return new ASpell(bp, lang);
79 #endif
80 #ifdef USE_PSPELL
81         if (lyxrc.use_spell_lib)
82                 return new PSpell(bp, lang);
83 #endif
84
85         lang = (lyxrc.isp_use_alt_lang) ?
86                 lyxrc.isp_alt_lang : bp.language->lang();
87
88         return new ISpell(bp, lang);
89 }
90
91 }
92
93
94 void ControlSpellchecker::startSession()
95 {
96         lyxerr[Debug::GUI] << "spell startSession" << endl;
97
98         if (speller_.get()) {
99                 lyxerr[Debug::GUI] << "startSession: speller exists" << endl;
100                 speller_.reset(0);
101                 return;
102         }
103
104         speller_.reset(getSpeller(buffer()->params()));
105
106         // reset values to initial
107         newval_ = 0.0;
108         oldval_ = 0;
109         newvalue_ = 0;
110         count_ = 0;
111         emergency_exit_ = false;
112
113         // start off the check
114         if (speller_->error().empty()) {
115                 check();
116                 return;
117         }
118
119         emergency_exit_ = true;
120         string message = speller_->error();
121         if (message.empty())
122                 message = _("The spell-checker could not be started.\n"
123                          "Maybe it is mis-configured.");
124
125         Alert::error(_("The spell-checker has failed"), message);
126         speller_.reset(0);
127 }
128
129
130 void ControlSpellchecker::endSession()
131 {
132         lyxerr[Debug::GUI] << "spell endSession" << endl;
133
134         bufferview()->endOfSpellCheck();
135
136         emergency_exit_ = true;
137
138         if (!speller_.get()) {
139                 lyxerr[Debug::GUI] << "endSession with no speller" << endl;
140                 return;
141         }
142
143         speller_.reset(0);
144 }
145
146
147 void ControlSpellchecker::check()
148 {
149         lyxerr[Debug::GUI] << "spell check a word" << endl;
150
151         SpellBase::Result res = SpellBase::OK;
152
153         // clear any old selection
154         bufferview()->update();
155
156         while (res == SpellBase::OK || res == SpellBase::IGNORE) {
157                 word_ = bufferview()->nextWord(newval_);
158
159                 // end of document
160                 if (word_.word().empty())
161                         break;
162
163                 ++count_;
164
165                 // Update slider if and only if value has changed
166                 newvalue_ = int(100.0 * newval_);
167                 if (newvalue_!= oldval_) {
168                         lyxerr[Debug::GUI] << "Updating spell progress." << endl;
169                         oldval_ = newvalue_;
170                         // set progress bar
171                         view().partialUpdate(SPELL_PROGRESSED);
172                 }
173
174                 // speller might be dead ...
175                 if (!checkAlive())
176                         return;
177
178                 res = speller_->check(word_);
179
180                 // ... or it might just be reporting an error
181                 if (!checkAlive())
182                         return;
183         }
184
185         lyxerr[Debug::GUI] << "Found word \"" << word_.word() << "\"" << endl;
186         lyxerr << "Found word \"" << word_.word() << "\"" << endl;
187
188         if (!word_.word().empty()) {
189                 bufferview()->selectLastWord();
190                 bufferview()->fitCursor();
191         } else {
192                 showSummary();
193                 endSession();
194                 return;
195         }
196
197         // set suggestions
198         if (res != SpellBase::OK && res != SpellBase::IGNORE) {
199                 lyxerr[Debug::GUI] << "Found a word needing checking." << endl;
200                 view().partialUpdate(SPELL_FOUND_WORD);
201         }
202 }
203
204
205 bool ControlSpellchecker::checkAlive()
206 {
207         if (speller_->alive() && speller_->error().empty())
208                 return true;
209
210         string message = speller_->error();
211         if (message.empty())
212                 message = _("The spell-checker has died for some reason.\n"
213                          "Maybe it has been killed.");
214
215         view().hide();
216         speller_.reset(0);
217
218         Alert::error(_("The spell-checker has failed"), message);
219         return false;
220 }
221
222
223 void ControlSpellchecker::showSummary()
224 {
225         if (!checkAlive() || count_ == 0) {
226                 view().hide();
227                 return;
228         }
229
230         string message;
231         if (count_ != 1)
232                 message = bformat(_("%1$s words checked."), tostr(count_));
233         else
234                 message = _("One word checked.");
235
236         view().hide();
237         Alert::information(_("Spell-checking is complete"), message);
238 }
239
240
241 void ControlSpellchecker::replace(string const & replacement)
242 {
243         bufferview()->replaceWord(replacement);
244         // fix up the count
245         --count_;
246         check();
247 }
248
249
250 void ControlSpellchecker::replaceAll(string const & replacement)
251 {
252         // TODO: add to list
253         replace(replacement);
254 }
255
256
257 void ControlSpellchecker::insert()
258 {
259         speller_->insert(word_);
260         check();
261 }
262
263
264 string const ControlSpellchecker::getSuggestion() const
265 {
266         return speller_->nextMiss();
267 }
268
269
270 string const ControlSpellchecker::getWord() const
271 {
272         return word_.word();
273 }
274
275
276 void ControlSpellchecker::ignoreAll()
277 {
278         speller_->accept(word_);
279         check();
280 }