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