Simplify Buffer::spellCheck() by using Paragraph::spellCheck().

Paragrah::isMisspelled() is split in two.



git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@30222 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Abdelrazak Younes 2009-06-22 16:38:11 +00:00
parent 23b70a8fdd
commit 694399b16c
6 changed files with 73 additions and 109 deletions

View File

@ -3371,77 +3371,29 @@ void Buffer::updateLabels(ParIterator & parit) const
}
bool Buffer::nextWord(DocIterator & from, DocIterator & to,
docstring & word) const
{
bool inword = false;
bool ignoreword = false;
string lang_code;
// Go backward a bit if needed in order to return the word currently
// pointed by 'from'.
while (from && from.pos() && !isLetter(from))
from.backwardPos();
// OK, we start from here.
to = from;
while (to.depth()) {
if (isLetter(to)) {
if (!inword) {
inword = true;
ignoreword = false;
from = to;
word.clear();
lang_code = to.paragraph().getFontSettings(params(),
to.pos()).language()->code();
}
// Insets like optional hyphens and ligature
// break are part of a word.
if (!to.paragraph().isInset(to.pos())) {
char_type const c = to.paragraph().getChar(to.pos());
word += c;
if (isDigit(c))
ignoreword = true;
}
} else { // !isLetter(cur)
if (inword && !word.empty() && !ignoreword)
return true;
inword = false;
}
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();
WordLangTuple wl;
suggestions.clear();
docstring word;
while (nextWord(from, to, word)) {
// We are only interested in text so remove the math CursorSlice.
while (from.inMathed())
from.pop_back();
// OK, we start from here.
to = from;
while (!from.paragraph().spellCheck(from.pos(), to.pos(), wl, suggestions)) {
++progress;
string const lang_code = lyxrc.spellchecker_alt_lang.empty()
? from.paragraph().getFontSettings(params(), from.pos()).language()->code()
: lyxrc.spellchecker_alt_lang;
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;
if (from == to) {
// end of file reached.
word_lang = WordLangTuple();
suggestions.clear();
return progress;
}
from = to;
from.forwardPos();
}
while (!(word = speller->nextMiss()).empty())
suggestions.push_back(word);
return progress;
}

View File

@ -515,15 +515,12 @@ public:
///
void updateLabels(ParIterator & parit) const;
/// Find next word starting from \p from.
/// \p from initial position to search, will then points to the next
/// Spellcheck starting from \p from.
/// \p from initial position, will then points to the next misspelled
/// word.
/// \p to will points to the end of the next word.
/// \p word will contain the found word if any.
/// \return true if a new word was found.
bool nextWord(DocIterator & from, DocIterator & to,
docstring & word) const;
/// \p to will points to the end of the next misspelled word.
/// \p word_lang will contain the found misspelled word.
/// \return progress if a new word was found.
int spellCheck(DocIterator & from, DocIterator & to,
WordLangTuple & word_lang, docstring_list & suggestions) const;

View File

@ -610,9 +610,4 @@ bool operator==(StableDocIterator const & dit1, StableDocIterator const & dit2)
}
bool isLetter(DocIterator const & dit)
{
return dit.inTexted() && !dit.paragraph().isWordSeparator(dit.pos());
}
} // namespace lyx

View File

@ -355,10 +355,6 @@ private:
std::vector<CursorSlice> data_;
};
/// Indicate if the character pointed by dit is a letter.
/// This function takes care of spellchecker escape chars.
bool isLetter(DocIterator const & dit);
} // namespace lyx
#endif // DOCITERATOR_H

View File

@ -52,10 +52,11 @@
#include "insets/InsetBibitem.h"
#include "insets/InsetLabel.h"
#include "support/lassert.h"
#include "support/debug.h"
#include "support/docstring_list.h"
#include "support/ExceptionMessage.h"
#include "support/gettext.h"
#include "support/lassert.h"
#include "support/lstrings.h"
#include "support/Messages.h"
#include "support/textutils.h"
@ -2469,7 +2470,7 @@ bool Paragraph::isWordSeparator(pos_type pos) const
if (Inset const * inset = getInset(pos))
return !inset->isLetter();
char_type const c = d->text_[pos];
// We want to pass the ' and escape chars to the spellchecker
// We want to pass the ' and escape chars to the spellchecker
static docstring const quote = from_utf8(lyxrc.spellchecker_esc_chars + '\'');
return (!isLetterChar(c) && !isDigit(c) && !contains(quote, c))
|| pos == size();
@ -2888,28 +2889,27 @@ void Paragraph::changeCase(BufferParams const & bparams, pos_type pos,
capitalize = true;
}
if (oldChar != newChar)
if (oldChar != newChar) {
changes += newChar;
if (oldChar == newChar || pos == right - 1) {
if (oldChar != newChar) {
// step behind the changing area
pos++;
}
int erasePos = pos - changes.size();
for (size_t i = 0; i < changes.size(); i++) {
insertChar(pos, changes[i],
getFontSettings(bparams,
erasePos),
trackChanges);
if (!eraseChar(erasePos, trackChanges)) {
++erasePos;
++pos; // advance
++right; // expand selection
}
}
changes.clear();
if (pos != right - 1)
continue;
// step behind the changing area
pos++;
}
int erasePos = pos - changes.size();
for (size_t i = 0; i < changes.size(); i++) {
insertChar(pos, changes[i],
getFontSettings(bparams,
erasePos),
trackChanges);
if (!eraseChar(erasePos, trackChanges)) {
++erasePos;
++pos; // advance
++right; // expand selection
}
}
changes.clear();
}
}
@ -3081,31 +3081,47 @@ void Paragraph::updateWords()
}
bool Paragraph::isMisspelled(pos_type pos) const
bool Paragraph::spellCheck(pos_type & from, pos_type & to, WordLangTuple & wl,
docstring_list & suggestions) const
{
SpellChecker * speller = theSpellChecker();
pos_type from = pos;
pos_type to = pos;
locateWord(from, to, WHOLE_WORD);
docstring word = asString(from, to, false);
docstring word = asString(from, to, AS_STR_INSETS);
if (!speller)
return false;
string const lang_code = lyxrc.spellchecker_alt_lang.empty()
? getFontSettings(d->inset_owner_->buffer().params(), from).language()->code()
: lyxrc.spellchecker_alt_lang;
WordLangTuple wl(word, lang_code);
wl = WordLangTuple(word, lang_code);
SpellChecker::Result res = speller->check(wl);
// ... just ignore any error that the spellchecker reports.
// Just ignore any error that the spellchecker reports.
// FIXME: we should through out an exception and catch it in the GUI to
// display the error.
if (!speller->error().empty())
return false;
bool const misspelled = res != SpellChecker::OK
&& res != SpellChecker::IGNORED_WORD;
if (lyxrc.spellcheck_continuously)
d->fontlist_.setMisspelled(from, pos, misspelled);
d->fontlist_.setMisspelled(from, to, misspelled);
while (!(word = speller->nextMiss()).empty())
suggestions.push_back(word);
return misspelled;
}
bool Paragraph::isMisspelled(pos_type pos) const
{
pos_type from = pos;
pos_type to = pos;
WordLangTuple wl;
docstring_list suggestions;
return spellCheck(from, to, wl, suggestions);
}
} // namespace lyx

View File

@ -34,6 +34,7 @@ class Counters;
class Cursor;
class CursorSlice;
class DocIterator;
class docstring_list;
class DocumentClass;
class Inset;
class InsetBibitem;
@ -49,6 +50,7 @@ class PainterInfo;
class ParagraphParameters;
class TexRow;
class Toc;
class WordLangTuple;
class FontSpan {
public:
@ -417,6 +419,12 @@ public:
word_location const loc) const;
///
void updateWords();
/// Spellcheck word at position \p from and fill in found misspelled word.
/// \return true if pointed word is misspelled.
bool spellCheck(pos_type & from, pos_type & to, WordLangTuple & wl,
docstring_list & suggestions) const;
/// Spellcheck word at position \p pos.
/// \return true if pointed word is misspelled.
bool isMisspelled(pos_type pos) const;