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