]> git.lyx.org Git - lyx.git/blob - src/frontends/controllers/ControlSpellchecker.C
Dispatch->dispatch, some trans work
[lyx.git] / src / frontends / controllers / ControlSpellchecker.C
1 /* This file is part of
2  * ====================================================== 
3  *
4  *           LyX, The Document Processor
5  *
6  *           Copyright 2001 The LyX Team.
7  *
8  * ======================================================
9  *
10  * \file ControlSpellchecker.C
11  * \author Edwin Leuven <leuven@fee.uva.nl>
12  */
13
14 #include <config.h>
15
16 #ifdef __GNUG__
17 #pragma implementation
18 #endif
19
20 #include FORMS_H_LOCATION
21
22 #ifdef HAVE_SYS_SELECT_H
23 # ifdef HAVE_STRINGS_H
24    // <strings.h> is needed at least on AIX because FD_ZERO uses bzero().
25    // BUT we cannot include both string.h and strings.h on Irix 6.5 :(
26 #  ifdef _AIX
27 #   include <strings.h>
28 #  endif
29 # endif
30 #include <sys/select.h>
31 #endif
32
33 #include "buffer.h"
34 #include "lyxrc.h"
35 #include "BufferView.h"
36 #include "LyXView.h" 
37 #include "gettext.h"
38 #include "support/lstrings.h"
39 #include "language.h"
40
41 #include "ViewBase.h"
42 #include "ButtonControllerBase.h"
43 #include "ControlSpellchecker.h"
44 #include "Dialogs.h"
45 #include "Liason.h"
46
47 # include "sp_ispell.h"
48 #ifdef USE_PSPELL
49 # include "sp_pspell.h"
50 #endif
51
52 #include "debug.h"
53
54 using SigC::slot;
55
56 ControlSpellchecker::ControlSpellchecker(LyXView & lv, Dialogs & d)
57         : ControlDialog<ControlConnectBD>(lv, d)
58 {
59         d_.showSpellchecker.connect(SigC::slot(this, &ControlSpellchecker::show));
60
61         rtl_ = false;
62         word_ = "";
63         newval_ = 0.0;
64         oldval_ = 0;
65         newvalue_ = 0;
66         count_ = 0;
67         message_ = "";
68         stop_ = false;
69         result_ = SpellBase::ISP_UNKNOWN;
70         speller_ = 0;
71         
72 }
73
74
75 ControlSpellchecker::~ControlSpellchecker()
76 {
77 }
78
79
80 void ControlSpellchecker::show()
81 {
82         if (isBufferDependent() && !lv_.view()->available())
83                 return;
84
85         if (!speller_) {
86                 // create spell object
87                 string tmp;
88 #ifdef USE_PSPELL
89                 if (lyxrc.use_pspell) {
90                         tmp = (lyxrc.isp_use_alt_lang) ?
91                                 lyxrc.isp_alt_lang : lv_.buffer()->params.language->code();
92                         
93                         speller_ = new PSpell(lv_.view()->buffer()->params, tmp);
94                 } else {
95 #endif
96                         tmp = (lyxrc.isp_use_alt_lang) ?
97                                 lyxrc.isp_alt_lang : lv_.buffer()->params.language->lang();
98                         
99                         speller_ = new ISpell(lv_.view()->buffer()->params, tmp);
100 #ifdef USE_PSPELL
101                 }
102 #endif
103         
104                 if (lyxrc.isp_use_alt_lang) {
105                         Language const * lang = languages.getLanguage(tmp);
106                         if (lang)
107                                 rtl_ = lang->RightToLeft();
108                 } else {
109                         rtl_ = lv_.buffer()->params.language->RightToLeft();
110                 }
111                 
112                 if (speller_->error() != 0) {
113                         message_ = speller_->error();
114                         view().partialUpdate(2);
115                         hide();
116                         return;
117                 }
118         }
119
120         bc().readOnly(isReadonly());
121         view().show();
122 }
123
124
125 void ControlSpellchecker::hide()
126 {
127         delete speller_;
128         speller_ = 0;
129
130         disconnect();
131         view().hide();
132 }
133
134
135 void ControlSpellchecker::check()
136 {
137         result_ = SpellBase::ISP_UNKNOWN;
138         stop_ = false;
139         
140         while (result_!=SpellBase::ISP_MISSED && !stop_) {
141                 word_ = lv_.view()->nextWord(newval_);
142                 if (word_.empty()) {
143                         quit();
144                         break;
145                 }
146                 
147                 ++count_;
148                 
149                 // Update slider if and only if value has changed
150                 newvalue_ = int(100.0*newval_);
151                 if (newvalue_!= oldval_) {
152                         oldval_ = newvalue_;
153                         // set progress bar
154                         view().partialUpdate(0);
155                 }
156                 
157                 if (!speller_->alive()) quit();
158                 
159                 result_ = speller_->check(word_);
160         }
161         
162         if (!stop_ && !word_.empty())
163                 lv_.view()->selectLastWord();
164
165         // set suggestions
166         if (result_==SpellBase::ISP_MISSED) {
167                 view().partialUpdate(1);
168         }
169 }
170
171
172 void ControlSpellchecker::replace(string const & replacement)
173 {
174         lv_.view()->replaceWord(replacement);
175         check();
176 }
177
178
179 void ControlSpellchecker::replaceAll(string const & replacement)
180 {
181         // TODO: add to list
182         replace(replacement);
183 }
184
185
186 void ControlSpellchecker::insert()
187 {
188         speller_->insert(word_);
189 }
190
191
192 string ControlSpellchecker::getSuggestion()
193 {
194         // this is needed because string tmp = nextmiss()
195         // segfaults when nextMiss is 0
196         string tmp;
197         char const * w = speller_->nextMiss();
198         
199         if (w!=0) {
200                 tmp = w;
201                 if (rtl_) std::reverse(tmp.begin(), tmp.end());
202         }
203         
204         return tmp;
205 }
206
207
208 string ControlSpellchecker::getWord()
209 {
210         string tmp = word_;
211         if (rtl_) std::reverse(tmp.begin(), tmp.end());
212         return tmp;
213 }
214
215
216 void ControlSpellchecker::ignoreAll()
217 {
218         speller_->accept(word_);
219         check();
220 }
221
222
223 void ControlSpellchecker::stop()
224 {
225         stop_ = true;
226 }
227
228
229 void ControlSpellchecker::quit()
230 {
231         if (speller_->alive()) {
232                 speller_->close();
233                 message_ = tostr(count_);
234                 if (count_ != 1) {
235                         message_ += _(" words checked.");
236                 } else {
237                         message_ += _(" word checked.");
238                 }
239                 message_ = "\n" + message_;
240                 message_ = _("Spellchecking completed! ") + message_;
241         } else {
242                 speller_->cleanUp();
243                 message_ = _("The spell checker has died for some reason.\n"
244                                   "Maybe it has been killed.");
245         }
246
247         lv_.view()->endOfSpellCheck();
248
249         // hide dialog, disconnect and delete speller
250         hide();
251         
252         // show closing message
253         view().partialUpdate(2);
254
255         // reset values to initial
256         rtl_ = false;
257         word_ = "";
258         newval_ = 0.0;
259         oldval_ = 0;
260         newvalue_ = 0;
261         count_ = 0;
262         message_ = "";
263         stop_ = false;
264         result_ = SpellBase::ISP_UNKNOWN;
265 }
266
267
268 void ControlSpellchecker::options()
269 {
270         lv_.getDialogs()->showSpellcheckerPreferences();
271 }
272
273