]> git.lyx.org Git - lyx.git/blob - src/frontends/controllers/ControlSpellchecker.C
_("blah") + 'f' is most definitely non-U. I suppose I'm the sucker who
[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 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "ControlSpellchecker.h"
18 #include "ViewBase.h"
19 #include "buffer.h"
20 #include "BufferView.h"
21 #include "gettext.h"
22 #include "language.h"
23 #include "lyxrc.h"
24 #include "lyxtext.h"
25
26 #include "ispell.h"
27 #ifdef USE_PSPELL
28 # include "pspell.h"
29 #endif
30
31 #include "frontends/Alert.h"
32
33 #include "support/lstrings.h"
34
35 #include "BoostFormat.h"
36
37 ControlSpellchecker::ControlSpellchecker(LyXView & lv, Dialogs & d)
38         : ControlDialogBD(lv, d),
39           rtl_(false), newval_(0.0), oldval_(0), newvalue_(0), count_(0),
40           stop_(false), speller_(0)
41 {}
42
43
44 void ControlSpellchecker::setParams()
45 {
46         if (speller_)
47                 return;
48
49         // create spell object
50         string tmp;
51 #ifdef USE_PSPELL
52         if (lyxrc.use_pspell) {
53                 tmp = (lyxrc.isp_use_alt_lang) ?
54                         lyxrc.isp_alt_lang : buffer()->params.language->code();
55
56                 speller_ = new PSpell(buffer()->params, tmp);
57         } else {
58 #endif
59                 tmp = (lyxrc.isp_use_alt_lang) ?
60                         lyxrc.isp_alt_lang : buffer()->params.language->lang();
61
62                 speller_ = new ISpell(buffer()->params, tmp);
63 #ifdef USE_PSPELL
64         }
65 #endif
66
67         if (lyxrc.isp_use_alt_lang) {
68                 Language const * lang = languages.getLanguage(tmp);
69                 if (lang)
70                         rtl_ = lang->RightToLeft();
71         } else {
72                 rtl_ = buffer()->params.language->RightToLeft();
73         }
74
75         if (!speller_->error().empty()) {
76                 emergency_exit_ = true;
77                 Alert::alert("The spellchecker has failed", speller_->error());
78                 clearParams();
79                 return;
80         }
81 }
82
83
84 void ControlSpellchecker::check()
85 {
86         SpellBase::Result res = SpellBase::OK;
87         stop_ = false;
88
89         // clear any old selection
90         LyXText * text = bufferview()->getLyXText();
91         bufferview()->toggleSelection(true);
92         bufferview()->update(text, BufferView::SELECT);
93
94         while ((res == SpellBase::OK || res == SpellBase::IGNORE) && !stop_) {
95                 word_ = bufferview()->nextWord(newval_);
96
97                 if (word_.word().empty()) {
98                         clearParams();
99                         break;
100                 }
101
102                 ++count_;
103
104                 // Update slider if and only if value has changed
105                 newvalue_ = int(100.0 * newval_);
106                 if (newvalue_!= oldval_) {
107                         oldval_ = newvalue_;
108                         // set progress bar
109                         view().partialUpdate(0);
110                 }
111
112                 if (!speller_ || !speller_->alive()) {
113                         clearParams();
114                         stop();
115                         return;
116                 }
117
118                 res = speller_->check(word_);
119         }
120
121         if (!stop_ && !word_.word().empty())
122                 bufferview()->selectLastWord();
123
124         // set suggestions
125         if (res != SpellBase::OK && res != SpellBase::IGNORE) {
126                 view().partialUpdate(1);
127         }
128 }
129
130
131 void ControlSpellchecker::replace(string const & replacement)
132 {
133         bufferview()->replaceWord(replacement);
134         // fix up the count
135         --count_;
136         check();
137 }
138
139
140 void ControlSpellchecker::replaceAll(string const & replacement)
141 {
142         // TODO: add to list
143         replace(replacement);
144 }
145
146
147 void ControlSpellchecker::insert()
148 {
149         speller_->insert(word_);
150         check();
151 }
152
153
154 string const ControlSpellchecker::getSuggestion() const
155 {
156         string miss(speller_->nextMiss());
157
158         if (rtl_)
159                 std::reverse(miss.begin(), miss.end());
160
161         return miss;
162 }
163
164
165 string const ControlSpellchecker::getWord() const
166 {
167         string tmp = word_.word();
168         if (rtl_)
169                 std::reverse(tmp.begin(), tmp.end());
170         return tmp;
171 }
172
173
174 void ControlSpellchecker::ignoreAll()
175 {
176         speller_->accept(word_);
177         check();
178 }
179
180
181 void ControlSpellchecker::stop()
182 {
183         stop_ = true;
184         bufferview()->endOfSpellCheck();
185 }
186
187
188 void ControlSpellchecker::clearParams()
189 {
190         if (!speller_)
191                 return;
192
193         if (speller_->alive()) {
194                 speller_->close();
195
196                 message_ = string(_("Spellchecking completed!")) + '\n';
197
198 #if USE_BOOST_FORMAT
199                 if (count_ != 1) {
200                 boost::format fmter("%1$d words checked.");
201                 fmter % count_;
202                 message_ += fmter.str();
203                 } else {
204                         message_ += _("One word checked.");
205                 }
206 #else
207                 if (count_ != 1) {
208                         message_ += tostr(count_) + " words checked";
209                 } else {
210                         message_ = _("One word checked.");
211                 }
212 #endif
213         } else {
214                 message_ = speller_->error();
215                 speller_->cleanUp();
216                 if (message_.empty())
217                     message_ = _("The spell checker has died for some reason.\n"
218                                  "Maybe it has been killed.");
219
220                 // make sure that the dialog is not launched
221                 emergency_exit_ = true;
222                 Alert::alert("The spellchecker has failed", message_);
223         }
224
225         delete speller_;
226
227         bufferview()->endOfSpellCheck();
228
229         // show closing message if any words were checked.
230         if (count_ > 0)
231                 view().partialUpdate(2);
232
233         // reset values to initial
234         rtl_ = false;
235         newval_ = 0.0;
236         oldval_ = 0;
237         newvalue_ = 0;
238         count_ = 0;
239         message_.erase();
240         stop_ = false;
241         speller_ = 0;
242 }