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