1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 2001 The LyX Team.
8 * ======================================================
10 * \file ControlSpellchecker.C
11 * \author Edwin Leuven <leuven@fee.uva.nl>
17 #pragma implementation
20 #include <sys/types.h> // needed by <sys/select.h> at least on freebsd
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 :(
30 #include <sys/select.h>
35 #include "BufferView.h"
39 #include "support/lstrings.h"
43 #include "ButtonControllerBase.h"
44 #include "ControlSpellchecker.h"
48 # include "sp_ispell.h"
50 # include "sp_pspell.h"
57 ControlSpellchecker::ControlSpellchecker(LyXView & lv, Dialogs & d)
58 : ControlDialogBD(lv, d),
59 rtl_(false), newval_(0.0), oldval_(0), newvalue_(0), count_(0),
60 stop_(false), result_(SpellBase::ISP_OK), speller_(0)
62 d_.showSpellchecker.connect(SigC::slot(this, &ControlSpellchecker::show));
66 void ControlSpellchecker::setParams()
69 // create spell object
72 if (lyxrc.use_pspell) {
73 tmp = (lyxrc.isp_use_alt_lang) ?
74 lyxrc.isp_alt_lang : lv_.buffer()->params.language->code();
76 speller_ = new PSpell(lv_.view()->buffer()->params, tmp);
79 tmp = (lyxrc.isp_use_alt_lang) ?
80 lyxrc.isp_alt_lang : lv_.buffer()->params.language->lang();
82 speller_ = new ISpell(lv_.view()->buffer()->params, tmp);
87 if (lyxrc.isp_use_alt_lang) {
88 Language const * lang = languages.getLanguage(tmp);
90 rtl_ = lang->RightToLeft();
92 rtl_ = lv_.buffer()->params.language->RightToLeft();
95 if (speller_->error() != 0) {
97 message_ = speller_->error();
99 view().partialUpdate(2);
108 void ControlSpellchecker::check()
110 result_ = SpellBase::ISP_OK;
113 // clear any old selection
114 LyXText * text = lv_.view()->getLyXText();
115 lv_.view()->toggleSelection(true);
116 lv_.view()->update(text, BufferView::SELECT);
118 while ((result_==SpellBase::ISP_OK || result_==SpellBase::ISP_IGNORE) &&
120 word_ = lv_.view()->nextWord(newval_);
129 // Update slider if and only if value has changed
130 newvalue_ = int(100.0*newval_);
131 if (newvalue_!= oldval_) {
134 view().partialUpdate(0);
137 if (!speller_->alive()) clearParams();
139 result_ = speller_->check(word_);
142 if (!stop_ && !word_.empty())
143 lv_.view()->selectLastWord();
146 if (result_!=SpellBase::ISP_OK && result_!=SpellBase::ISP_IGNORE) {
147 view().partialUpdate(1);
152 void ControlSpellchecker::replace(string const & replacement)
154 lv_.view()->replaceWord(replacement);
159 void ControlSpellchecker::replaceAll(string const & replacement)
162 replace(replacement);
166 void ControlSpellchecker::insert()
168 speller_->insert(word_);
173 string ControlSpellchecker::getSuggestion()
175 // this is needed because string tmp = nextmiss()
176 // segfaults when nextMiss is 0
178 char const * w = speller_->nextMiss();
182 if (rtl_) std::reverse(tmp.begin(), tmp.end());
189 string ControlSpellchecker::getWord()
192 if (rtl_) std::reverse(tmp.begin(), tmp.end());
197 void ControlSpellchecker::ignoreAll()
199 speller_->accept(word_);
204 void ControlSpellchecker::stop()
207 lv_.view()->endOfSpellCheck();
211 void ControlSpellchecker::clearParams()
213 if (!speller_) return;
215 if (speller_->alive()) {
217 message_ = tostr(count_);
219 message_ += _(" words checked.");
222 message_ += _(" word checked.");
224 message_ = "\n" + message_;
225 message_ = _("Spellchecking completed! ") + message_;
228 message_ = speller_->error();
230 if (message_.empty())
231 message_ = _("The spell checker has died for some reason.\n"
232 "Maybe it has been killed.");
234 // make sure that the dialog is not launched
235 emergency_exit_ = true;
240 lv_.view()->endOfSpellCheck();
242 // show closing message if any words were checked.
244 view().partialUpdate(2);
246 // reset values to initial
255 result_ = SpellBase::ISP_OK;
260 void ControlSpellchecker::options()
262 lv_.getDialogs()->showSpellcheckerPreferences();