More SpellChecker cleanups.

* Buffer::spellCheck() new method constructed from mutiple bits of GuiSpellchecker.cpp.

* GuiSpellchecker: lots of simplifications.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@29090 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Abdelrazak Younes 2009-04-04 16:40:47 +00:00
parent 1352592874
commit a4169da139
4 changed files with 107 additions and 152 deletions

View File

@ -50,6 +50,7 @@
#include "ParagraphParameters.h"
#include "ParIterator.h"
#include "PDFOptions.h"
#include "SpellChecker.h"
#include "sgml.h"
#include "TexRow.h"
#include "TexStream.h"
@ -59,6 +60,7 @@
#include "Undo.h"
#include "VCBackend.h"
#include "version.h"
#include "WordLangTuple.h"
#include "WordList.h"
#include "insets/InsetBibitem.h"
@ -79,6 +81,7 @@
#include "support/lassert.h"
#include "support/convert.h"
#include "support/debug.h"
#include "support/docstring_list.h"
#include "support/ExceptionMessage.h"
#include "support/FileName.h"
#include "support/FileNameList.h"
@ -3115,8 +3118,41 @@ bool Buffer::nextWord(DocIterator & from, DocIterator & to,
}
to.forwardPos();
}
from = to;
word.clear();
return false;
}
int Buffer::spellCheck(DocIterator & from, DocIterator & to,
WordLangTuple & word_lang, docstring_list & suggestions) const
{
int progress = 0;
SpellChecker::Result res = SpellChecker::OK;
SpellChecker * speller = theSpellChecker();
suggestions.clear();
docstring word;
while (nextWord(from, to, word)) {
++progress;
string lang_code = lyxrc.spellchecker_use_alt_lang
? lyxrc.spellchecker_alt_lang
: from.paragraph().getFontSettings(params(), from.pos()).language()->code();
WordLangTuple wl(word, lang_code);
res = speller->check(wl);
// ... just bail out if the spellchecker reports an error.
if (!speller->error().empty()) {
throw ExceptionMessage(WarningException,
_("The spellchecker has failed."), speller->error());
}
if (res != SpellChecker::OK && res != SpellChecker::IGNORED_WORD) {
word_lang = wl;
break;
}
from = to;
}
while (!(word = speller->nextMiss()).empty())
suggestions.push_back(word);
return progress;
}
} // namespace lyx

View File

@ -28,6 +28,7 @@ class BiblioInfo;
class BufferParams;
class BufferSet;
class DocIterator;
class docstring_list;
class ErrorItem;
class ErrorList;
class FuncRequest;
@ -54,6 +55,7 @@ class TeXErrors;
class TexRow;
class TocBackend;
class Undo;
class WordLangTuple;
namespace frontend {
class GuiBufferDelegate;
@ -500,6 +502,9 @@ public:
bool nextWord(DocIterator & from, DocIterator & to,
docstring & word) const;
int spellCheck(DocIterator & from, DocIterator & to,
WordLangTuple & word_lang, docstring_list & suggestions) const;
private:
/// search for macro in local (buffer) table or in children
MacroData const * getBufferMacro(docstring const & name,

View File

@ -18,6 +18,7 @@
#include "Buffer.h"
#include "BufferParams.h"
#include "BufferView.h"
#include "buffer_funcs.h"
#include "Cursor.h"
#include "CutAndPaste.h"
#include "Language.h"
@ -27,16 +28,14 @@
#include "support/debug.h"
#include "support/docstring.h"
#include "support/docstring_list.h"
#include "support/ExceptionMessage.h"
#include "support/gettext.h"
#include "support/lstrings.h"
#include "support/textutils.h"
#include <QListWidgetItem>
#if defined(USE_ASPELL)
# include "ASpell_local.h"
#endif
#include "SpellChecker.h"
#include "frontends/alert.h"
@ -50,7 +49,7 @@ namespace frontend {
GuiSpellchecker::GuiSpellchecker(GuiView & lv)
: GuiDialog(lv, "spellchecker", qt_("Spellchecker")), exitEarly_(false),
oldprogress_(0), newprogress_(0), count_(0), speller_(0)
progress_(0), count_(0)
{
setupUi(this);
@ -139,13 +138,15 @@ void GuiSpellchecker::updateContents()
void GuiSpellchecker::accept()
{
ignoreAll();
theSpellChecker()->accept(word_);
check();
}
void GuiSpellchecker::add()
{
insert();
theSpellChecker()->insert(word_);
check();
}
@ -161,30 +162,20 @@ void GuiSpellchecker::replace()
}
void GuiSpellchecker::partialUpdate(int state)
void GuiSpellchecker::updateSuggestions(docstring_list & words)
{
switch (state) {
case SPELL_PROGRESSED:
spellcheckPR->setValue(oldprogress_);
break;
wordED->setText(toqstr(word_.word()));
suggestionsLW->clear();
case SPELL_FOUND_WORD: {
wordED->setText(toqstr(word_.word()));
suggestionsLW->clear();
docstring w;
while (!(w = speller_->nextMiss()).empty())
suggestionsLW->addItem(toqstr(w));
if (suggestionsLW->count() == 0)
suggestionChanged(new QListWidgetItem(wordED->text()));
else
suggestionChanged(suggestionsLW->item(0));
suggestionsLW->setCurrentRow(0);
break;
}
if (words.empty() == 0) {
suggestionChanged(new QListWidgetItem(wordED->text()));
return;
}
for (size_t i = 0; i != words.size(); ++i)
suggestionsLW->addItem(toqstr(words[i]));
suggestionChanged(suggestionsLW->item(0));
suggestionsLW->setCurrentRow(0);
}
@ -192,54 +183,21 @@ bool GuiSpellchecker::initialiseParams(string const &)
{
LYXERR(Debug::GUI, "Spellchecker::initialiseParams");
speller_ = theSpellChecker();
if (!speller_)
if (!theSpellChecker())
return false;
// reset values to initial
oldprogress_ = 0;
newprogress_ = 0;
DocIterator const begin = doc_iterator_begin(&buffer());
Cursor const & cur = bufferview()->cursor();
progress_ = countWords(begin, cur);
total_ = progress_ + countWords(cur, doc_iterator_end(&buffer()));
count_ = 0;
bool const success = speller_->error().empty();
if (!success) {
Alert::error(_("Spellchecker error"),
_("The spellchecker could not be started\n")
+ speller_->error());
speller_ = 0;
}
return success;
return true;
}
void GuiSpellchecker::clearParams()
{
LYXERR(Debug::GUI, "Spellchecker::clearParams");
speller_ = 0;
}
static WordLangTuple nextWord(Cursor & cur, ptrdiff_t & progress)
{
Buffer const & buf = cur.bv().buffer();
cur.resetAnchor();
docstring word;
DocIterator from = cur;
DocIterator to;
if (!buf.nextWord(from, to, word))
return WordLangTuple(docstring(), string());
cur.setCursor(from);
cur.resetAnchor();
cur.setCursor(to);
cur.setSelection();
string lang_code = lyxrc.spellchecker_use_alt_lang
? lyxrc.spellchecker_alt_lang
: from.paragraph().getFontSettings(buf.params(), cur.pos()).language()->code();
++progress;
return WordLangTuple(word, lang_code);
}
@ -247,72 +205,50 @@ void GuiSpellchecker::check()
{
LYXERR(Debug::GUI, "Check the spelling of a word");
SpellChecker::Result res = SpellChecker::OK;
Cursor cur = bufferview()->cursor();
while (cur && cur.pos() && isLetter(cur))
cur.backwardPos();
ptrdiff_t start = 0;
ptrdiff_t total = 0;
DocIterator it = doc_iterator_begin(&buffer());
for (start = 1; it != cur; it.forwardPos())
++start;
for (total = start; it; it.forwardPos())
++total;
DocIterator from = bufferview()->cursor();
while (from && from.pos() && isLetter(from))
from.backwardPos();
DocIterator to;
exitEarly_ = false;
WordLangTuple word_lang;
docstring_list suggestions;
while (res == SpellChecker::OK || res == SpellChecker::IGNORED_WORD) {
word_ = nextWord(cur, start);
// end of document
if (word_.word().empty()) {
showSummary();
exitEarly_ = true;
return;
}
++count_;
// Update slider if and only if value has changed
float progress = total ? float(start)/total : 1;
newprogress_ = int(100.0 * progress);
if (newprogress_!= oldprogress_) {
LYXERR(Debug::GUI, "Updating spell progress.");
oldprogress_ = newprogress_;
// set progress bar
partialUpdate(SPELL_PROGRESSED);
}
res = speller_->check(word_);
// ... just bail out if the spellchecker reports an error.
if (!speller_->error().empty()) {
docstring const message =
_("The spellchecker has failed.\n") + speller_->error();
int progress;
try {
progress = buffer().spellCheck(from, to, word_lang, suggestions);
} catch (ExceptionMessage const & message) {
if (message.type_ == WarningException) {
Alert::warning(message.title_, message.details_);
slotClose();
return;
}
}
throw message;
}
LYXERR(Debug::GUI, "Found word \"" << word_lang.word() << "\"");
count_ += progress;
progress_ += progress;
LYXERR(Debug::GUI, "Found word \"" << to_utf8(word_.word()) << "\"");
// end of document
if (from == to) {
showSummary();
exitEarly_ = true;
return;
}
word_ = word_lang;
int const progress_bar = total_
? int(100.0 * float(progress_)/total_) : 100;
LYXERR(Debug::GUI, "Updating spell progress.");
// set progress bar
spellcheckPR->setValue(progress_bar);
// set suggestions
updateSuggestions(suggestions);
int const size = cur.selEnd().pos() - cur.selBegin().pos();
cur.pos() -= size;
BufferView * bv = const_cast<BufferView *>(bufferview());
bv->putSelectionAt(cur, size, false);
// FIXME: if we used a lfun like in find/replace, dispatch would do
// that for us
// FIXME: this Controller is very badly designed...
bv->processUpdateFlags(Update::Force | Update::FitCursor);
// set suggestions
if (res != SpellChecker::OK && res != SpellChecker::IGNORED_WORD) {
LYXERR(Debug::GUI, "Found a word needing checking.");
partialUpdate(SPELL_FOUND_WORD);
}
int const size = to.pos() - from.pos();
BufferView * bv = const_cast<BufferView *>(bufferview());
bv->putSelectionAt(from, size, false);
}
@ -356,20 +292,6 @@ void GuiSpellchecker::replaceAll(docstring const & replacement)
}
void GuiSpellchecker::insert()
{
speller_->insert(word_);
check();
}
void GuiSpellchecker::ignoreAll()
{
speller_->accept(word_);
check();
}
Dialog * createGuiSpellchecker(GuiView & lv) { return new GuiSpellchecker(lv); }
} // namespace frontend

View File

@ -23,6 +23,7 @@ class QListWidgetItem;
namespace lyx {
class docstring_list;
class SpellChecker;
namespace frontend {
@ -38,6 +39,7 @@ public Q_SLOTS:
void suggestionChanged(QListWidgetItem *);
private Q_SLOTS:
/// ignore all occurances of word
void accept();
void add();
void ignore();
@ -47,16 +49,10 @@ private Q_SLOTS:
private:
/// update from controller
void partialUpdate(int id);
void updateSuggestions(docstring_list & words);
///
void updateContents();
///
enum State {
SPELL_PROGRESSED, //< update progress bar
SPELL_FOUND_WORD //< found a bad word
};
///
bool initialiseParams(std::string const & data);
///
@ -75,8 +71,6 @@ private:
void replaceAll(docstring const &);
/// insert word in personal dictionary
void insert();
/// ignore all occurances of word
void ignoreAll();
/// check text until next misspelled/unknown word
/// returns true when finished
void check();
@ -88,12 +82,10 @@ private:
/// current word being checked and lang code
WordLangTuple word_;
/// values for progress
int oldprogress_;
int newprogress_;
int total_;
int progress_;
/// word count
int count_;
/// The actual spellchecker object
SpellChecker * speller_;
};
} // namespace frontend