]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/controllers/ControlSpellchecker.C
fix crash due to invalidated iterator
[lyx.git] / src / frontends / controllers / ControlSpellchecker.C
index 7e8c7b60f3026c95219b719db411f73c7c2c9a69..7e0c88d281d247a926c71ca8c48e638e65ac2387 100644 (file)
 #include "lyxrc.h"
 #include "paragraph.h"
 
-#include "ispell.h"
-#ifdef USE_PSPELL
-# include "pspell.h"
-#else
-#ifdef USE_ASPELL
+#if defined(USE_ASPELL)
 # include "aspell_local.h"
+#elif defined(USE_PSPELL)
+# include "pspell.h"
 #endif
+
+#if defined(USE_ISPELL)
+# include "ispell.h"
+#else
+# include "SpellBase.h"
 #endif
 
 #include "support/textutils.h"
@@ -51,7 +54,7 @@ namespace frontend {
 
 
 ControlSpellchecker::ControlSpellchecker(Dialog & parent)
-       : Dialog::Controller(parent),
+       : Dialog::Controller(parent), exitEarly_(false),
          oldval_(0), newvalue_(0), count_(0)
 {}
 
@@ -68,19 +71,22 @@ SpellBase * getSpeller(BufferParams const & bp)
                      ? lyxrc.isp_alt_lang
                      : bp.language->code();
 
-#ifdef USE_ASPELL
+#if defined(USE_ASPELL)
        if (lyxrc.use_spell_lib)
                return new ASpell(bp, lang);
-#endif
-#ifdef USE_PSPELL
+#elif defined(USE_PSPELL)
        if (lyxrc.use_spell_lib)
                return new PSpell(bp, lang);
 #endif
 
+#if defined(USE_ISPELL)
        lang = (lyxrc.isp_use_alt_lang) ?
                lyxrc.isp_alt_lang : bp.language->lang();
 
        return new ISpell(bp, lang);
+#else
+       return new SpellBase;
+#endif
 }
 
 } // namespace anon
@@ -91,6 +97,8 @@ bool ControlSpellchecker::initialiseParams(std::string const &)
        lyxerr[Debug::GUI] << "Spellchecker::initialiseParams" << endl;
 
        speller_.reset(getSpeller(kernel().buffer().params()));
+       if (!speller_.get())
+               return false;
 
        // reset values to initial
        oldval_ = 0;
@@ -100,8 +108,9 @@ bool ControlSpellchecker::initialiseParams(std::string const &)
        bool const success = speller_->error().empty();
 
        if (!success) {
-               Alert::error(_("The spell-checker could not be started"),
-                            speller_->error());
+               Alert::error(_("Spellchecker error"),
+                            _("The spellchecker could not be started\n")
+                            + speller_->error());
                speller_.reset(0);
        }
 
@@ -157,7 +166,7 @@ WordLangTuple nextWord(DocIterator & cur, ptrdiff_t & progress,
                        }
                } else { // !isLetter(cur)
                        if (inword)
-                               if (!ignoreword)
+                               if (!word.empty() && !ignoreword)
                                        return WordLangTuple(word, lang_code);
                                else
                                        inword = false;
@@ -176,11 +185,14 @@ WordLangTuple nextWord(DocIterator & cur, ptrdiff_t & progress,
 
 void ControlSpellchecker::check()
 {
-       lyxerr[Debug::GUI] << "spell check a word" << endl;
+       lyxerr[Debug::GUI] << "Check the spelling of a word" << endl;
 
        SpellBase::Result res = SpellBase::OK;
 
        DocIterator cur = kernel().bufferview()->cursor();
+       while (cur && cur.pos() && isLetter(cur)) {
+               cur.backwardPos();
+       }
 
        ptrdiff_t start = 0, total = 0;
        DocIterator it = DocIterator(kernel().buffer().inset());
@@ -190,10 +202,8 @@ void ControlSpellchecker::check()
        for (total = start; it; it.forwardPos())
                ++total;
 
-       for (; cur && isLetter(cur); cur.forwardPos())
-               ++start;
-
        BufferParams & bufferparams = kernel().buffer().params();
+       exitEarly_ = false;
 
        while (res == SpellBase::OK || res == SpellBase::IGNORED_WORD) {
                word_ = nextWord(cur, start, bufferparams);
@@ -201,6 +211,7 @@ void ControlSpellchecker::check()
                // end of document
                if (getWord().empty()) {
                        showSummary();
+                       exitEarly_ = true;
                        return;
                }
 
@@ -249,14 +260,17 @@ bool ControlSpellchecker::checkAlive()
        if (speller_->alive() && speller_->error().empty())
                return true;
 
-       string message = speller_->error();
-       if (message.empty())
-               message = _("The spell-checker has died for some reason.\n"
-                        "Maybe it has been killed.");
+       string message;
+       if (speller_->error().empty())
+               message = _("The spellchecker has died for some reason.\n"
+                           "Maybe it has been killed.");
+       else
+               message = _("The spellchecker has failed.\n") 
+                       + speller_->error();
 
        dialog().CancelButton();
 
-       Alert::error(_("The spell-checker has failed"), message);
+       Alert::error(_("The spellchecker has failed"), message);
        return false;
 }
 
@@ -275,7 +289,7 @@ void ControlSpellchecker::showSummary()
                message = _("One word checked.");
 
        dialog().CancelButton();
-       Alert::information(_("Spell-checking is complete"), message);
+       Alert::information(_("Spelling check completed"), message);
 }