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