2001-07-13 11:50:39 +00:00
|
|
|
/* This file is part of
|
2002-03-21 21:21:28 +00:00
|
|
|
* ======================================================
|
2001-07-13 11:50:39 +00:00
|
|
|
*
|
|
|
|
* LyX, The Document Processor
|
|
|
|
*
|
|
|
|
* Copyright 2001 The LyX Team.
|
|
|
|
*
|
|
|
|
* ======================================================
|
|
|
|
*
|
|
|
|
* \file ControlSpellchecker.C
|
|
|
|
* \author Edwin Leuven <leuven@fee.uva.nl>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#ifdef __GNUG__
|
|
|
|
#pragma implementation
|
|
|
|
#endif
|
|
|
|
|
2001-10-23 16:32:16 +00:00
|
|
|
#include <sys/types.h> // needed by <sys/select.h> at least on freebsd
|
|
|
|
|
2001-10-09 16:28:02 +00:00
|
|
|
#ifdef HAVE_SYS_SELECT_H
|
|
|
|
# ifdef HAVE_STRINGS_H
|
|
|
|
// <strings.h> is needed at least on AIX because FD_ZERO uses bzero().
|
|
|
|
// BUT we cannot include both string.h and strings.h on Irix 6.5 :(
|
|
|
|
# ifdef _AIX
|
|
|
|
# include <strings.h>
|
|
|
|
# endif
|
|
|
|
# endif
|
|
|
|
#include <sys/select.h>
|
|
|
|
#endif
|
2001-07-13 11:50:39 +00:00
|
|
|
|
|
|
|
#include "buffer.h"
|
|
|
|
#include "lyxrc.h"
|
|
|
|
#include "BufferView.h"
|
2002-03-21 21:21:28 +00:00
|
|
|
#include "LyXView.h"
|
2002-02-04 11:30:25 +00:00
|
|
|
#include "lyxtext.h"
|
2001-07-13 11:50:39 +00:00
|
|
|
#include "gettext.h"
|
|
|
|
#include "support/lstrings.h"
|
|
|
|
#include "language.h"
|
|
|
|
|
|
|
|
#include "ViewBase.h"
|
|
|
|
#include "ButtonControllerBase.h"
|
|
|
|
#include "ControlSpellchecker.h"
|
|
|
|
#include "Dialogs.h"
|
|
|
|
#include "Liason.h"
|
|
|
|
|
2001-07-16 10:03:38 +00:00
|
|
|
# include "sp_ispell.h"
|
2001-07-13 11:50:39 +00:00
|
|
|
#ifdef USE_PSPELL
|
|
|
|
# include "sp_pspell.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
using SigC::slot;
|
|
|
|
|
|
|
|
ControlSpellchecker::ControlSpellchecker(LyXView & lv, Dialogs & d)
|
2002-01-16 14:47:58 +00:00
|
|
|
: ControlDialogBD(lv, d),
|
2001-07-17 09:00:17 +00:00
|
|
|
rtl_(false), newval_(0.0), oldval_(0), newvalue_(0), count_(0),
|
2001-10-01 14:00:46 +00:00
|
|
|
stop_(false), result_(SpellBase::ISP_OK), speller_(0)
|
2001-07-13 11:50:39 +00:00
|
|
|
{
|
|
|
|
d_.showSpellchecker.connect(SigC::slot(this, &ControlSpellchecker::show));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-17 09:00:17 +00:00
|
|
|
void ControlSpellchecker::setParams()
|
2001-07-13 11:50:39 +00:00
|
|
|
{
|
|
|
|
if (!speller_) {
|
|
|
|
// create spell object
|
2001-07-16 10:03:38 +00:00
|
|
|
string tmp;
|
2001-07-13 11:50:39 +00:00
|
|
|
#ifdef USE_PSPELL
|
2001-07-16 10:03:38 +00:00
|
|
|
if (lyxrc.use_pspell) {
|
|
|
|
tmp = (lyxrc.isp_use_alt_lang) ?
|
|
|
|
lyxrc.isp_alt_lang : lv_.buffer()->params.language->code();
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-16 10:03:38 +00:00
|
|
|
speller_ = new PSpell(lv_.view()->buffer()->params, tmp);
|
|
|
|
} else {
|
|
|
|
#endif
|
|
|
|
tmp = (lyxrc.isp_use_alt_lang) ?
|
|
|
|
lyxrc.isp_alt_lang : lv_.buffer()->params.language->lang();
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-16 10:03:38 +00:00
|
|
|
speller_ = new ISpell(lv_.view()->buffer()->params, tmp);
|
|
|
|
#ifdef USE_PSPELL
|
|
|
|
}
|
2001-07-13 11:50:39 +00:00
|
|
|
#endif
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
if (lyxrc.isp_use_alt_lang) {
|
|
|
|
Language const * lang = languages.getLanguage(tmp);
|
|
|
|
if (lang)
|
|
|
|
rtl_ = lang->RightToLeft();
|
|
|
|
} else {
|
|
|
|
rtl_ = lv_.buffer()->params.language->RightToLeft();
|
|
|
|
}
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
if (speller_->error() != 0) {
|
2001-10-22 21:17:06 +00:00
|
|
|
#if 0
|
2001-07-13 11:50:39 +00:00
|
|
|
message_ = speller_->error();
|
2001-07-17 09:00:17 +00:00
|
|
|
// show error message
|
2001-07-13 11:50:39 +00:00
|
|
|
view().partialUpdate(2);
|
2001-10-22 21:17:06 +00:00
|
|
|
#endif
|
2001-07-17 09:00:17 +00:00
|
|
|
clearParams();
|
2001-07-13 11:50:39 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ControlSpellchecker::check()
|
|
|
|
{
|
2001-10-01 14:00:46 +00:00
|
|
|
result_ = SpellBase::ISP_OK;
|
2001-07-13 11:50:39 +00:00
|
|
|
stop_ = false;
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2002-02-04 11:30:25 +00:00
|
|
|
// clear any old selection
|
|
|
|
LyXText * text = lv_.view()->getLyXText();
|
|
|
|
lv_.view()->toggleSelection(true);
|
|
|
|
lv_.view()->update(text, BufferView::SELECT);
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-10-01 14:00:46 +00:00
|
|
|
while ((result_==SpellBase::ISP_OK || result_==SpellBase::ISP_IGNORE) &&
|
|
|
|
!stop_) {
|
2001-07-13 11:50:39 +00:00
|
|
|
word_ = lv_.view()->nextWord(newval_);
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
if (word_.empty()) {
|
2001-07-17 09:00:17 +00:00
|
|
|
clearParams();
|
2001-07-13 11:50:39 +00:00
|
|
|
break;
|
|
|
|
}
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
++count_;
|
2001-07-17 09:00:17 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
// Update slider if and only if value has changed
|
|
|
|
newvalue_ = int(100.0*newval_);
|
|
|
|
if (newvalue_!= oldval_) {
|
|
|
|
oldval_ = newvalue_;
|
|
|
|
// set progress bar
|
|
|
|
view().partialUpdate(0);
|
|
|
|
}
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-17 09:00:17 +00:00
|
|
|
if (!speller_->alive()) clearParams();
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
result_ = speller_->check(word_);
|
|
|
|
}
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
if (!stop_ && !word_.empty())
|
|
|
|
lv_.view()->selectLastWord();
|
|
|
|
|
|
|
|
// set suggestions
|
2001-10-01 14:00:46 +00:00
|
|
|
if (result_!=SpellBase::ISP_OK && result_!=SpellBase::ISP_IGNORE) {
|
2001-07-13 11:50:39 +00:00
|
|
|
view().partialUpdate(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ControlSpellchecker::replace(string const & replacement)
|
|
|
|
{
|
|
|
|
lv_.view()->replaceWord(replacement);
|
|
|
|
check();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ControlSpellchecker::replaceAll(string const & replacement)
|
|
|
|
{
|
|
|
|
// TODO: add to list
|
|
|
|
replace(replacement);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ControlSpellchecker::insert()
|
|
|
|
{
|
|
|
|
speller_->insert(word_);
|
2001-08-07 15:07:36 +00:00
|
|
|
check();
|
2001-07-13 11:50:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string ControlSpellchecker::getSuggestion()
|
|
|
|
{
|
|
|
|
// this is needed because string tmp = nextmiss()
|
|
|
|
// segfaults when nextMiss is 0
|
|
|
|
string tmp;
|
|
|
|
char const * w = speller_->nextMiss();
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
if (w!=0) {
|
|
|
|
tmp = w;
|
2001-07-13 13:54:14 +00:00
|
|
|
if (rtl_) std::reverse(tmp.begin(), tmp.end());
|
2001-07-13 11:50:39 +00:00
|
|
|
}
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string ControlSpellchecker::getWord()
|
|
|
|
{
|
|
|
|
string tmp = word_;
|
2001-07-13 13:54:14 +00:00
|
|
|
if (rtl_) std::reverse(tmp.begin(), tmp.end());
|
2001-07-13 11:50:39 +00:00
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ControlSpellchecker::ignoreAll()
|
|
|
|
{
|
|
|
|
speller_->accept(word_);
|
|
|
|
check();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ControlSpellchecker::stop()
|
|
|
|
{
|
|
|
|
stop_ = true;
|
2001-07-17 09:00:17 +00:00
|
|
|
lv_.view()->endOfSpellCheck();
|
2001-07-13 11:50:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-17 09:00:17 +00:00
|
|
|
void ControlSpellchecker::clearParams()
|
2001-07-13 11:50:39 +00:00
|
|
|
{
|
2001-07-17 09:00:17 +00:00
|
|
|
if (!speller_) return;
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
if (speller_->alive()) {
|
|
|
|
speller_->close();
|
|
|
|
message_ = tostr(count_);
|
|
|
|
if (count_ != 1) {
|
|
|
|
message_ += _(" words checked.");
|
2001-07-17 09:00:17 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
} else {
|
|
|
|
message_ += _(" word checked.");
|
|
|
|
}
|
|
|
|
message_ = "\n" + message_;
|
|
|
|
message_ = _("Spellchecking completed! ") + message_;
|
2001-07-17 09:00:17 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
} else {
|
2001-10-22 21:17:06 +00:00
|
|
|
message_ = speller_->error();
|
2001-07-13 11:50:39 +00:00
|
|
|
speller_->cleanUp();
|
2001-10-22 21:17:06 +00:00
|
|
|
if (message_.empty())
|
|
|
|
message_ = _("The spell checker has died for some reason.\n"
|
|
|
|
"Maybe it has been killed.");
|
2001-09-27 13:10:28 +00:00
|
|
|
|
|
|
|
// make sure that the dialog is not launched
|
|
|
|
emergency_exit_ = true;
|
2001-07-13 11:50:39 +00:00
|
|
|
}
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-17 09:00:17 +00:00
|
|
|
delete speller_;
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-07-13 11:50:39 +00:00
|
|
|
lv_.view()->endOfSpellCheck();
|
|
|
|
|
2002-01-07 17:57:21 +00:00
|
|
|
// show closing message if any words were checked.
|
|
|
|
if (count_ > 0)
|
|
|
|
view().partialUpdate(2);
|
2001-07-13 11:50:39 +00:00
|
|
|
|
|
|
|
// reset values to initial
|
|
|
|
rtl_ = false;
|
2002-01-07 17:57:21 +00:00
|
|
|
word_.erase();
|
2001-07-13 11:50:39 +00:00
|
|
|
newval_ = 0.0;
|
|
|
|
oldval_ = 0;
|
|
|
|
newvalue_ = 0;
|
|
|
|
count_ = 0;
|
2002-01-07 17:57:21 +00:00
|
|
|
message_.erase();
|
2001-07-13 11:50:39 +00:00
|
|
|
stop_ = false;
|
2001-10-01 14:00:46 +00:00
|
|
|
result_ = SpellBase::ISP_OK;
|
2001-07-17 09:00:17 +00:00
|
|
|
speller_ = 0;
|
2001-07-13 11:50:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ControlSpellchecker::options()
|
|
|
|
{
|
|
|
|
lv_.getDialogs()->showSpellcheckerPreferences();
|
|
|
|
}
|