]> git.lyx.org Git - features.git/blobdiff - src/frontends/controllers/ControlSpellchecker.C
use std::advance and std::distance instead of home-grown versions
[features.git] / src / frontends / controllers / ControlSpellchecker.C
index e8802c35f6f001fc877b927345af088cd41d5fab..835aa4c1e9fa76230fa57e9cf7dda8cc9ac0beb8 100644 (file)
 
 #include "ControlSpellchecker.h"
 #include "ViewBase.h"
+
 #include "buffer.h"
+#include "bufferparams.h"
 #include "BufferView.h"
+#include "bufferview_funcs.h"
+#include "debug.h"
 #include "gettext.h"
 #include "language.h"
 #include "lyxrc.h"
-#include "lyxtext.h"
-#include "debug.h"
+
+#include "PosIterator.h"
+#include "paragraph.h"
 
 #include "ispell.h"
 #ifdef USE_PSPELL
 
 #include "frontends/Alert.h"
 
-using namespace lyx::support;
+
+using lyx::support::bformat;
 
 using std::endl;
+using std::string;
 
 
 ControlSpellchecker::ControlSpellchecker(LyXView & lv, Dialogs & d)
        : ControlDialogBD(lv, d),
-         newval_(0.0), oldval_(0), newvalue_(0), count_(0)
+         oldval_(0), newvalue_(0), count_(0)
 {}
 
 
@@ -64,6 +71,7 @@ void ControlSpellchecker::clearParams()
 
 namespace {
 
+
 SpellBase * getSpeller(BufferParams const & bp)
 {
        string lang = (lyxrc.isp_use_alt_lang)
@@ -98,10 +106,9 @@ void ControlSpellchecker::startSession()
                return;
        }
 
-       speller_.reset(getSpeller(buffer()->params));
+       speller_.reset(getSpeller(buffer()->params()));
 
        // reset values to initial
-       newval_ = 0.0;
        oldval_ = 0;
        newvalue_ = 0;
        count_ = 0;
@@ -128,8 +135,6 @@ void ControlSpellchecker::endSession()
 {
        lyxerr[Debug::GUI] << "spell endSession" << endl;
 
-       bufferview()->endOfSpellCheck();
-
        emergency_exit_ = true;
 
        if (!speller_.get()) {
@@ -141,18 +146,63 @@ void ControlSpellchecker::endSession()
 }
 
 
+namespace {
+
+
+bool isLetter(PosIterator & cur)
+{
+       return !cur.at_end()
+               && cur.pit()->isLetter(cur.pos())
+               && !isDeletedText(*cur.pit(), cur.pos())
+               && (!cur.inset() || cur.inset()->allowSpellCheck());
+}
+
+
+WordLangTuple nextWord(PosIterator & cur, PosIterator const & end,
+                      int & progress, BufferParams & bp)
+{
+       // skip until we have real text (will jump paragraphs)
+       for (; cur != end && !isLetter(cur); ++cur, ++progress);
+
+       if (cur == end)
+               return WordLangTuple(string(), string());
+
+       string lang_code = cur.pit()->getFontSettings(bp, cur.pos()).language()->code();
+       string str;
+       // and find the end of the word (insets like optional hyphens
+       // and ligature break are part of a word)
+       for (; cur != end && isLetter(cur); ++cur, ++progress) {
+               if (!cur.pit()->isInset(cur.pos()))
+                       str += cur.pit()->getChar(cur.pos());
+       }
+
+       return WordLangTuple(str, lang_code);
+}
+
+
+} //namespace anon
+
+
+
+
 void ControlSpellchecker::check()
 {
        lyxerr[Debug::GUI] << "spell check a word" << endl;
 
        SpellBase::Result res = SpellBase::OK;
 
-       // clear any old selection
-       LyXText * text = bufferview()->getLyXText();
-       bufferview()->update();
+       PosIterator cur(*bufferview());
+       PosIterator const beg = buffer()->pos_iterator_begin();
+       PosIterator const end = buffer()->pos_iterator_end();
+
+       int start = std::distance(beg, cur);
+       int const total = start + std::distance(cur, end);
+
+       if (cur != buffer()->pos_iterator_begin())
+               for (; cur != end && isLetter(cur); ++cur, ++start);
 
        while (res == SpellBase::OK || res == SpellBase::IGNORE) {
-               word_ = bufferview()->nextWord(newval_);
+               word_ = nextWord(cur, end, start, buffer()->params());
 
                // end of document
                if (word_.word().empty())
@@ -161,7 +211,8 @@ void ControlSpellchecker::check()
                ++count_;
 
                // Update slider if and only if value has changed
-               newvalue_ = int(100.0 * newval_);
+               float progress = total ? float(start)/total : 1;
+               newvalue_ = int(100.0 * progress);
                if (newvalue_!= oldval_) {
                        lyxerr[Debug::GUI] << "Updating spell progress." << endl;
                        oldval_ = newvalue_;
@@ -181,11 +232,12 @@ void ControlSpellchecker::check()
        }
 
        lyxerr[Debug::GUI] << "Found word \"" << word_.word() << "\"" << endl;
-       lyxerr << "Found word \"" << word_.word() << "\"" << endl;
 
        if (!word_.word().empty()) {
-               bufferview()->selectLastWord();
-               bufferview()->fitCursor();
+               int const size = word_.word().size();
+               std::advance(cur, -size);
+               bufferview()->putSelectionAt(cur, size, false);
+               std::advance(cur, size);
        } else {
                showSummary();
                endSession();