]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiSpellchecker.cpp
Transfer some more dialog related code from core to frontend:
[lyx.git] / src / frontends / qt4 / GuiSpellchecker.cpp
index 4b0448c66347f59fa9df3f83ea4713e95e17acc1..daff427e85e51096ba85cf9daba6416dbf7f40e0 100644 (file)
@@ -27,8 +27,8 @@
 #include "Paragraph.h"
 
 #include "support/textutils.h"
-#include "support/convert.h"
 #include "support/docstring.h"
+#include "support/lstrings.h"
 
 #include <QProgressBar>
 #include <QLineEdit>
 #endif
 
 #include "frontends/alert.h"
-// FIXME: those two headers are needed because of the
-// WorkArea::redraw() call below.
-#include "frontends/LyXView.h"
-#include "frontends/WorkArea.h"
 
 using std::advance;
 using std::distance;
@@ -70,7 +66,7 @@ namespace frontend {
 using support::bformat;
 using support::contains;
 
-GuiSpellchecker::GuiSpellchecker(LyXView & lv)
+GuiSpellchecker::GuiSpellchecker(GuiView & lv)
        : GuiDialog(lv, "spellchecker"), exitEarly_(false),
          oldval_(0), newvalue_(0), count_(0), speller_(0)
 {
@@ -78,15 +74,15 @@ GuiSpellchecker::GuiSpellchecker(LyXView & lv)
        setViewTitle(_("Spellchecker"));
 
        connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
-       connect(replacePB, SIGNAL(clicked()), this, SLOT(replaceClicked()));
-       connect(ignorePB, SIGNAL(clicked()), this, SLOT(ignoreClicked()));
-       connect(replacePB_3, SIGNAL(clicked()), this, SLOT(acceptClicked()));
-       connect(addPB, SIGNAL(clicked()), this, SLOT(addClicked()));
+       connect(replacePB, SIGNAL(clicked()), this, SLOT(replace()));
+       connect(ignorePB, SIGNAL(clicked()), this, SLOT(ignore()));
+       connect(replacePB_3, SIGNAL(clicked()), this, SLOT(accept()));
+       connect(addPB, SIGNAL(clicked()), this, SLOT(add()));
 
        connect(replaceCO, SIGNAL(highlighted(QString)),
                this, SLOT(replaceChanged(QString)));
        connect(suggestionsLW, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
-               this, SLOT(replaceClicked()));
+               this, SLOT(replace()));
        connect(suggestionsLW, SIGNAL(itemClicked(QListWidgetItem*)),
                this, SLOT(suggestionChanged(QListWidgetItem*)));
 
@@ -144,8 +140,31 @@ void GuiSpellchecker::reject()
 
 void GuiSpellchecker::updateContents()
 {
-       if (isVisibleView() || exitEarly())
+       // The clauses below are needed because the spellchecker
+       // has many flaws (see bugs 1950, 2218).
+       // Basically, we have to distinguish the case where a
+       // spellcheck has already been performed for the whole
+       // document (exitEarly() == true, isVisible() == false) 
+       // from the rest (exitEarly() == false, isVisible() == true).
+       // FIXME: rewrite the whole beast!
+       static bool check_after_early_exit;
+       if (exitEarly()) {
+               // a spellcheck has already been performed,
                check();
+               check_after_early_exit = true;
+       }
+       else if (isVisible()) {
+               // the above check triggers a second update,
+               // and isVisible() is true then. Prevent a
+               // second check that skips the first word
+               if (check_after_early_exit)
+                       // don't check, but reset the bool.
+                       // business as usual after this.
+                       check_after_early_exit = false;
+               else
+                       // perform spellcheck (default case)
+                       check();
+       }
 }
 
 
@@ -227,7 +246,7 @@ static SpellBase * getSpeller(BufferParams const & bp)
 
 bool GuiSpellchecker::initialiseParams(std::string const &)
 {
-       LYXERR(Debug::GUI) << "Spellchecker::initialiseParams" << endl;
+       LYXERR(Debug::GUI, "Spellchecker::initialiseParams");
 
        speller_ = getSpeller(buffer().params());
        if (!speller_)
@@ -254,7 +273,7 @@ bool GuiSpellchecker::initialiseParams(std::string const &)
 
 void GuiSpellchecker::clearParams()
 {
-       LYXERR(Debug::GUI) << "Spellchecker::clearParams" << endl;
+       LYXERR(Debug::GUI, "Spellchecker::clearParams");
        delete speller_;
        speller_ = 0;
 }
@@ -294,8 +313,7 @@ static WordLangTuple nextWord(Cursor & cur, ptrdiff_t & progress)
                        // Insets like optional hyphens and ligature
                        // break are part of a word.
                        if (!cur.paragraph().isInset(cur.pos())) {
-                               Paragraph::value_type const c =
-                                       cur.paragraph().getChar(cur.pos());
+                               char_type const c = cur.paragraph().getChar(cur.pos());
                                word += c;
                                if (isDigit(c))
                                        ignoreword = true;
@@ -319,7 +337,7 @@ static WordLangTuple nextWord(Cursor & cur, ptrdiff_t & progress)
 
 void GuiSpellchecker::check()
 {
-       LYXERR(Debug::GUI) << "Check the spelling of a word" << endl;
+       LYXERR(Debug::GUI, "Check the spelling of a word");
 
        SpellBase::Result res = SpellBase::OK;
 
@@ -354,10 +372,10 @@ void GuiSpellchecker::check()
                float progress = total ? float(start)/total : 1;
                newvalue_ = int(100.0 * progress);
                if (newvalue_!= oldval_) {
-                       LYXERR(Debug::GUI) << "Updating spell progress." << endl;
+                       LYXERR(Debug::GUI, "Updating spell progress.");
                        oldval_ = newvalue_;
                        // set progress bar
-                       dialog().partialUpdateView(SPELL_PROGRESSED);
+                       partialUpdate(SPELL_PROGRESSED);
                }
 
                // speller might be dead ...
@@ -371,21 +389,20 @@ void GuiSpellchecker::check()
                        return;
        }
 
-       LYXERR(Debug::GUI) << "Found word \"" << to_utf8(getWord()) << "\"" << endl;
+       LYXERR(Debug::GUI, "Found word \"" << to_utf8(getWord()) << "\"");
 
        int const size = cur.selEnd().pos() - cur.selBegin().pos();
        cur.pos() -= size;
        bufferview()->putSelectionAt(cur, size, false);
        // FIXME: if we used a lfun like in find/replace, dispatch would do
        // that for us
-       bufferview()->update();
        // FIXME: this Controller is very badly designed...
-       lyxview().currentWorkArea()->redraw();
+       bufferview()->processUpdateFlags(Update::Force | Update::FitCursor);
 
        // set suggestions
        if (res != SpellBase::OK && res != SpellBase::IGNORED_WORD) {
-               LYXERR(Debug::GUI) << "Found a word needing checking." << endl;
-               dialog().partialUpdateView(SPELL_FOUND_WORD);
+               LYXERR(Debug::GUI, "Found a word needing checking.");
+               partialUpdate(SPELL_FOUND_WORD);
        }
 }
 
@@ -402,7 +419,7 @@ bool GuiSpellchecker::checkAlive()
        else
                message = _("The spellchecker has failed.\n") + speller_->error();
 
-       dialog().slotClose();
+       slotClose();
 
        Alert::error(_("The spellchecker has failed"), message);
        return false;
@@ -412,7 +429,7 @@ bool GuiSpellchecker::checkAlive()
 void GuiSpellchecker::showSummary()
 {
        if (!checkAlive() || count_ == 0) {
-               dialog().slotClose();
+               slotClose();
                return;
        }
 
@@ -422,19 +439,19 @@ void GuiSpellchecker::showSummary()
        else
                message = _("One word checked.");
 
-       dialog().slotClose();
+       slotClose();
        Alert::information(_("Spelling check completed"), message);
 }
 
 
 void GuiSpellchecker::replace(docstring const & replacement)
 {
-       LYXERR(Debug::GUI) << "GuiSpellchecker::replace("
-                          << to_utf8(replacement) << ")" << std::endl;
+       LYXERR(Debug::GUI, "GuiSpellchecker::replace("
+                          << to_utf8(replacement) << ")");
        cap::replaceSelectionWithString(bufferview()->cursor(), replacement, true);
        buffer().markDirty();
        // If we used an LFUN, we would not need that
-       bufferview()->update();
+       bufferview()->processUpdateFlags(Update::Force | Update::FitCursor);
        // fix up the count
        --count_;
        check();
@@ -474,7 +491,7 @@ void GuiSpellchecker::ignoreAll()
 }
 
 
-Dialog * createGuiSpellchecker(LyXView & lv) { return new GuiSpellchecker(lv); }
+Dialog * createGuiSpellchecker(GuiView & lv) { return new GuiSpellchecker(lv); }
 
 } // namespace frontend
 } // namespace lyx