I'm still testing this, but it works for old pspell at least a little.

This fixes a number of problems and cleans up some stuff.

o we start spell automatically on opening the dialog
o remove all the weirdo xforms stop/start stuff - it never worked
o save the word lists under all circumstances
o non-braindead check for ispell-process existence

I'd like people to look closely at this and, most importantly, TEST IT !

Since this fixes a couple of bugs, I'd like to backport to 1.3, but
*only* if it gets significant attention from testers. This means you
Moritz :)

Still on the cards is propogating ispell errors back up properly, needs
testing/investigation.

john


Index: SpellBase.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/SpellBase.h,v
retrieving revision 1.4
diff -u -r1.4 SpellBase.h
--- SpellBase.h 1 Dec 2002 22:59:17 -0000       1.4
+++ SpellBase.h 16 Feb 2003 02:44:19 -0000
@@ -36,14 +36,8 @@
        /// return true if the spellchecker instance still exists
        virtual bool alive() = 0;
 
-       /// clean up on messy exit
-       virtual void cleanUp() = 0;
-
        /// check the given word of the given lang code and return the result
        virtual enum Result check(WordLangTuple const &) = 0;
-
-       /// finish this spellchecker instance
-       virtual void close() = 0;
 
        /// insert the given word into the personal dictionary
        virtual void insert(WordLangTuple const &) = 0;
Index: ispell.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ispell.C,v
retrieving revision 1.6
diff -u -r1.6 ispell.C
--- ispell.C    13 Feb 2003 16:52:28 -0000      1.6
+++ ispell.C    16 Feb 2003 02:44:19 -0000
@@ -45,6 +45,7 @@
 #include "encoding.h"
 #include "ispell.h"
 #include "WordLangTuple.h"
+#include "gettext.h"
 
 #include "support/forkedcall.h"
 #include "support/lstrings.h"
@@ -60,9 +61,6 @@
 
 namespace {
 
-/// pid for the `ispell' process.
-pid_t isp_pid = -1;
-
 class LaunchIspell : public ForkedProcess {
 public:
        ///
@@ -96,7 +94,7 @@
 
 int LaunchIspell::generateChild()
 {
-       isp_pid = fork();
+       pid_t isp_pid = fork();
 
        if (isp_pid != 0) {
                // failed (-1) or parent process (>0)
@@ -206,25 +204,18 @@
        int pipein[2];
        int pipeout[2];
 
-       isp_pid = -1;
-
        if (pipe(pipein) == -1 || pipe(pipeout) == -1) {
-               lyxerr << "LyX: Can't create pipe for spellchecker!" << endl;
-               setError();
+               error_ = _("Can't create pipe for spellchecker.");
                return;
        }
 
        if ((out = fdopen(pipein[1], "w")) == 0) {
-               lyxerr << "LyX: Can't create stream for pipe for spellchecker!"
-                      << endl;
-               setError();
+               error_ = _("Can't create stream for pipe for spellchecker.");
                return;
        }
 
        if ((in = fdopen(pipeout[0], "r")) == 0) {
-               lyxerr <<"LyX: Can't create stream for pipe for spellchecker!"
-                      << endl;
-               setError();
+               error_ = _("Can't create stream for pipe for spellchecker.");
                return;
        }
 
@@ -232,16 +223,15 @@
 
        isp_fd = pipeout[0];
 
-       LaunchIspell childprocess(params, lang, pipein, pipeout);
-       isp_pid = childprocess.start();
-       if (isp_pid == -1) {
-               lyxerr << "LyX: Can't create child process for spellchecker!"
-                      << endl;
-               setError();
+       LaunchIspell * li = new LaunchIspell(params, lang, pipein, pipeout);
+       child_.reset(li);
+       if (li->start() == -1) {
+               error_ = _("Could not create an ispell process. You may not have "
+                       " the right languages installed.");     
+               child_.reset(0);
                return;
        }
 
-       setError();
        /* Parent process: Read ispells identification message */
        // Hmm...what are we using this id msg for? Nothing? (Lgb)
        // Actually I used it to tell if it's truly Ispell or if it's
@@ -255,8 +245,7 @@
        int retval = 0;
        FD_ZERO(&infds);
        FD_SET(pipeout[0], &infds);
-       tv.tv_sec = 15; // fifteen second timeout. Probably too much,
-       // but it can't really hurt.
+       tv.tv_sec = 3;
        tv.tv_usec = 0;
 
        // Configure provides us with macros which are supposed to do
@@ -276,46 +265,35 @@
 
        } else if (retval == 0) {
                // timeout. Give nice message to user.
-               lyxerr << "Ispell read timed out, what now?" << endl;
-               // This probably works but could need some thought
-               isp_pid = -1;
+               error_ = _("Ispell read timed out.");
                ::close(pipeout[0]);
                ::close(pipeout[1]);
                ::close(pipein[0]);
                ::close(pipein[1]);
-               isp_fd = -1;
+               child_.reset(0);
        } else {
                // Select returned error
-               lyxerr << "Select on ispell returned error, what now?" << endl;
+               error_ = _("Select on ispell returned error.");
+               child_.reset(0);
        }
 }
 
 
 ISpell::~ISpell()
 {
-       delete[] str;
-}
+       fputs("#\n", out); // Save personal dictionary
 
+       fflush(out);
+       fclose(out);
 
-void ISpell::setError()
-{
-       if (isp_pid == -1) {
-               error_ =
-                       "\n\n"
-                       "The spellcheck-process has died for some reason.\n"
-                       "*One* possible reason could be that you do not have\n"
-                       "a dictionary file for the language of this document\n"
-                       "installed.\n"
-                       "Check your spellchecker or set another dictionary\n"
-                       "in the Spellchecker Options menu.\n\n";
-       } else {
-               error_ = 0;
-       }
+       delete [] str;
 }
 
 
 string const ISpell::nextMiss()
 {
+       // Well, somebody is a sick fuck.
+
        if (str == 0 || *(e+1) == '\0')
                return "";
        char * b = e + 2;
@@ -329,13 +307,7 @@
 
 bool ISpell::alive()
 {
-       return isp_pid != -1;
-}
-
-
-void ISpell::cleanUp()
-{
-       ::fclose(out);
+       return child_.get() && child_->running();
 }
 
 
@@ -393,20 +365,6 @@
                        fgets(buf, 255, in);
        }
        return res;
-}
-
-
-void ISpell::close()
-{
-       // Note: If you decide to optimize this out when it is not
-       // needed please note that when Aspell is used this command
-       // is also needed to save the replacement dictionary.
-       // -- Kevin Atkinson ([EMAIL PROTECTED])
-
-       fputs("#\n", out); // Save personal dictionary
-
-       fflush(out);
-       fclose(out);
 }
 
 
Index: ispell.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ispell.h,v
retrieving revision 1.5
diff -u -r1.5 ispell.h
--- ispell.h    1 Dec 2002 22:59:17 -0000       1.5
+++ ispell.h    16 Feb 2003 02:44:19 -0000
@@ -13,8 +13,10 @@
 #include <cstdio>
 
 #include "SpellBase.h"
+#include <boost/scoped_ptr.hpp>
 
 class BufferParams;
+class ForkedProcess;
 
 /// i/a spell process-based spellchecker
 class ISpell : public SpellBase {
@@ -26,15 +28,9 @@
        /// return true if the spellchecker instance still exists
        virtual bool alive();
 
-       /// clean up on messy exit
-       virtual void cleanUp();
-
        /// check the given word and return the result
        virtual enum Result check(WordLangTuple const & word);
 
-       /// finish this spellchecker instance
-       virtual void close();
-
        /// insert the given word into the personal dictionary
        virtual void insert(WordLangTuple const & word);
 
@@ -48,9 +44,6 @@
        virtual string const error();
 
 private:
-       ///
-       void setError();
-
        /// instream to communicate with ispell
        FILE * in;
        /// outstream to communicate with ispell
@@ -59,6 +52,8 @@
        char const * error_;
        /// the fd of the outgoing pipe
        int isp_fd;
+
+       boost::scoped_ptr<ForkedProcess> child_;
 
        // vileness below ... please FIXME
        /// str ???
diff -u -r1.8 pspell.C
--- pspell.C    13 Feb 2003 16:52:40 -0000      1.8
+++ pspell.C    16 Feb 2003 02:44:20 -0000
@@ -12,6 +12,7 @@
 #ifdef USE_PSPELL
 
 #include "support/LAssert.h"
+#include "debug.h"
 
 #define USE_ORIGINAL_MANAGER_FUNCS 1
 // new aspell pspell missing extern "C"
@@ -22,38 +23,39 @@
 #include "pspell.h"
 #include "WordLangTuple.h"
 
+using std::endl;
+
 PSpell::PSpell(BufferParams const &, string const & lang)
        : els(0), spell_error_object(0)
 {
        addManager(lang);
+       lyxerr[Debug::GUI] << "created pspell" << endl;
 }
 
 
 PSpell::~PSpell()
 {
-       cleanUp();
-       close();
+       lyxerr[Debug::GUI] << "killed pspell" << endl;
+
+       if (spell_error_object) {
+               delete_pspell_can_have_error(spell_error_object);
+               spell_error_object = 0;
+       }
+
        if (els)
                delete_pspell_string_emulation(els);
+
        Managers::iterator it = managers_.begin();
        Managers::iterator end = managers_.end();
 
        for (; it != end; ++it) {
+               pspell_manager_save_all_word_lists(it->second.manager);
                delete_pspell_manager(it->second.manager);
                delete_pspell_config(it->second.config);
        }
 }
 
 
-void PSpell::cleanUp()
-{
-       if (spell_error_object) {
-               delete_pspell_can_have_error(spell_error_object);
-               spell_error_object = 0;
-       }
-}
-
-
 void PSpell::addManager(string const & lang)
 {
        PspellConfig * config = new_pspell_config();
@@ -105,17 +107,6 @@
                        res = MISSED;
        }
        return res;
-}
-
-
-void PSpell::close()
-{
-       Managers::iterator it = managers_.begin();
-       Managers::iterator end = managers_.end();
-
-       for (; it != end; ++it) {
-               pspell_manager_save_all_word_lists(it->second.manager);
-       }
 }
 
 
Index: pspell.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/pspell.h,v
retrieving revision 1.3
diff -u -r1.3 pspell.h
--- pspell.h    1 Dec 2002 22:59:17 -0000       1.3
+++ pspell.h    16 Feb 2003 02:44:20 -0000
@@ -37,14 +37,8 @@
         */
        virtual bool alive() { return true; }
 
-       /// clean up on messy exit
-       virtual void cleanUp();
-
        /// check the given word and return the result
        virtual enum Result check(WordLangTuple const &);
-
-       /// finish this spellchecker instance
-       virtual void close();
 
        /// insert the given word into the personal dictionary
        virtual void insert(WordLangTuple const &);
Index: frontends/controllers/ControlSpellchecker.C
===================================================================
RCS file: 
/usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ControlSpellchecker.C,v
retrieving revision 1.37
diff -u -r1.37 ControlSpellchecker.C
--- frontends/controllers/ControlSpellchecker.C 13 Feb 2003 16:52:49 -0000      1.37
+++ frontends/controllers/ControlSpellchecker.C 16 Feb 2003 02:44:28 -0000
@@ -19,6 +19,7 @@
 #include "language.h"
 #include "lyxrc.h"
 #include "lyxtext.h"
+#include "debug.h"
 
 #include "ispell.h"
 #ifdef USE_PSPELL
@@ -29,17 +30,41 @@
 
 #include "BoostFormat.h"
 
+using std::endl;
+
 ControlSpellchecker::ControlSpellchecker(LyXView & lv, Dialogs & d)
        : ControlDialogBD(lv, d),
-         newval_(0.0), oldval_(0), newvalue_(0), count_(0),
-         stop_(false), speller_(0)
+         newval_(0.0), oldval_(0), newvalue_(0), count_(0)
+{}
+
+
+ControlSpellchecker::~ControlSpellchecker()
 {}
 
 
 void ControlSpellchecker::setParams()
 {
-       if (speller_)
+       lyxerr[Debug::GUI] << "spell setParams" << endl;
+       startSession();
+}
+
+
+void ControlSpellchecker::clearParams()
+{
+       lyxerr[Debug::GUI] << "spell clearParams" << endl;
+       endSession();
+}
+
+       
+void ControlSpellchecker::startSession()
+{
+       lyxerr[Debug::GUI] << "spell startSession" << endl;
+
+       if (speller_.get()) {
+               lyxerr[Debug::GUI] << "startSession: speller exists" << endl;
+               speller_.reset(0);
                return;
+       }
 
        // create spell object
        string tmp;
@@ -48,70 +73,149 @@
                tmp = (lyxrc.isp_use_alt_lang) ?
                        lyxrc.isp_alt_lang : buffer()->params.language->code();
 
-               speller_ = new PSpell(buffer()->params, tmp);
+               speller_.reset(new PSpell(buffer()->params, tmp));
        } else {
 #endif
                tmp = (lyxrc.isp_use_alt_lang) ?
                        lyxrc.isp_alt_lang : buffer()->params.language->lang();
 
-               speller_ = new ISpell(buffer()->params, tmp);
+               speller_.reset(new ISpell(buffer()->params, tmp));
 #ifdef USE_PSPELL
        }
 #endif
 
-       if (!speller_->error().empty()) {
-               emergency_exit_ = true;
-               Alert::alert("The spellchecker has failed", speller_->error());
-               clearParams();
+       // reset values to initial
+       newval_ = 0.0;
+       oldval_ = 0;
+       newvalue_ = 0;
+       count_ = 0;
+
+       if (speller_->error().empty())
+               return;
+
+       emergency_exit_ = true;
+       string message = speller_->error();
+       if (message.empty())
+               message = _("The spell checker has died for some reason.\n"
+                        "Maybe it has been killed.");
+
+       Alert::alert("The spellchecker has failed", message);
+       speller_.reset(0);
+}
+
+
+void ControlSpellchecker::endSession()
+{
+       lyxerr[Debug::GUI] << "spell endSession" << endl;
+
+       bufferview()->endOfSpellCheck();
+
+       if (!speller_.get()) {
+               lyxerr[Debug::GUI] << "endSession with no speller" << endl;
                return;
        }
+
+       speller_.reset(0);
 }
 
 
 void ControlSpellchecker::check()
 {
+       lyxerr[Debug::GUI] << "spell check a word" << endl;
+
        SpellBase::Result res = SpellBase::OK;
-       stop_ = false;
 
        // clear any old selection
        LyXText * text = bufferview()->getLyXText();
        bufferview()->toggleSelection(true);
        bufferview()->update(text, BufferView::SELECT);
 
-       while ((res == SpellBase::OK || res == SpellBase::IGNORE) && !stop_) {
+       while ((res == SpellBase::OK || res == SpellBase::IGNORE)) {
                word_ = bufferview()->nextWord(newval_);
 
-               if (word_.word().empty()) {
-                       clearParams();
+               // end of document
+               if (word_.word().empty())
                        break;
-               }
 
                ++count_;
 
                // Update slider if and only if value has changed
                newvalue_ = int(100.0 * newval_);
                if (newvalue_!= oldval_) {
+                       lyxerr[Debug::GUI] << "Updating spell progress." << endl;
                        oldval_ = newvalue_;
                        // set progress bar
-                       view().partialUpdate(0);
+                       view().partialUpdate(SPELL_PROGRESSED);
                }
 
-               if (!speller_ || !speller_->alive()) {
-                       clearParams();
-                       stop();
+               if (!checkAlive())
                        return;
-               }
 
                res = speller_->check(word_);
        }
 
-       if (!stop_ && !word_.word().empty())
+       if (!word_.word().empty()) {
                bufferview()->selectLastWord();
+       } else {
+               showSummary();
+               endSession();
+               return;
+       }
 
        // set suggestions
        if (res != SpellBase::OK && res != SpellBase::IGNORE) {
-               view().partialUpdate(1);
+               lyxerr[Debug::GUI] << "Found a word needing checking." << endl;
+               view().partialUpdate(SPELL_FOUND_WORD);
+       }
+}
+
+
+bool ControlSpellchecker::checkAlive()
+{
+       if (speller_->alive())
+               return true;
+
+       string message = speller_->error();
+       if (message.empty())
+               message = _("The spell checker has died for some reason.\n"
+                        "Maybe it has been killed.");
+
+       Alert::alert("The spellchecker has failed", message);
+       return false;
+}
+
+
+void ControlSpellchecker::showSummary()
+{
+       if (!checkAlive())
+               return;
+
+       if (count_ == 0)
+               return;
+
+       string message;
+
+#if USE_BOOST_FORMAT
+       if (count_ != 1) {
+               boost::format fmter("%1$d words checked.");
+               fmter % count_;
+               message += fmter.str();
+       } else {
+               message += _("One word checked.");
+       }
+#else
+       if (count_ != 1) {
+               message += tostr(count_) + " words checked";
+       } else {
+               message = _("One word checked.");
        }
+#endif
+
+       Alert::alert("Spellchecking is complete", message);
+
+       // the session might have completed with out any errors at all
+       emergency_exit_ = true;
+       view().hide();
 }
 
 
@@ -157,64 +261,3 @@
 }
 
 
-void ControlSpellchecker::stop()
-{
-       stop_ = true;
-       bufferview()->endOfSpellCheck();
-}
-
-
-void ControlSpellchecker::clearParams()
-{
-       if (!speller_)
-               return;
-
-       if (speller_->alive()) {
-               speller_->close();
-
-               message_ = string(_("Spellchecking completed!")) + '\n';
-
-#if USE_BOOST_FORMAT
-               if (count_ != 1) {
-               boost::format fmter("%1$d words checked.");
-               fmter % count_;
-               message_ += fmter.str();
-               } else {
-                       message_ += _("One word checked.");
-               }
-#else
-               if (count_ != 1) {
-                       message_ += tostr(count_) + " words checked";
-               } else {
-                       message_ = _("One word checked.");
-               }
-#endif
-       } else {
-               message_ = speller_->error();
-               speller_->cleanUp();
-               if (message_.empty())
-                   message_ = _("The spell checker has died for some reason.\n"
-                                "Maybe it has been killed.");
-
-               // make sure that the dialog is not launched
-               emergency_exit_ = true;
-               Alert::alert("The spellchecker has failed", message_);
-       }
-
-       delete speller_;
-
-       bufferview()->endOfSpellCheck();
-
-       // show closing message if any words were checked.
-       if (count_ > 0)
-               view().partialUpdate(2);
-
-       // reset values to initial
-       newval_ = 0.0;
-       oldval_ = 0;
-       newvalue_ = 0;
-       count_ = 0;
-       message_.erase();
-       stop_ = false;
-       speller_ = 0;
-}
Index: frontends/controllers/ControlSpellchecker.h
===================================================================
RCS file: 
/usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ControlSpellchecker.h,v
retrieving revision 1.15
diff -u -r1.15 ControlSpellchecker.h
--- frontends/controllers/ControlSpellchecker.h 13 Feb 2003 16:52:49 -0000      1.15
+++ frontends/controllers/ControlSpellchecker.h 16 Feb 2003 02:44:28 -0000
@@ -12,6 +12,7 @@
 #ifndef CONTROLSPELLCHECKER_H
 #define CONTROLSPELLCHECKER_H
 
+#include <boost/scoped_ptr.hpp>
 
 #include "ControlDialog_impl.h"
 #include "LString.h"
@@ -23,9 +24,15 @@
  */
 class ControlSpellchecker : public ControlDialogBD {
 public:
-       ///
+       enum State {
+               SPELL_PROGRESSED, //< update progress bar
+               SPELL_FOUND_WORD //< found a bad word
+       };
+
        ControlSpellchecker(LyXView &, Dialogs &);
 
+       ~ControlSpellchecker();
+
        /// replace word with replacement
        void replace(string const &);
 
@@ -53,13 +60,22 @@
        /// returns progress value
        int getProgress() const { return oldval_; }
 
-       /// returns exit message
-       string const getMessage()  const { return message_; }
-
        /// returns word count
        int getCount()  const { return count_; }
 
 private:
+       /// give error message is spellchecker dies
+       bool checkAlive();
+
+       /// start a spell-checking session
+       void startSession();
+
+       /// end a spell-checking session
+       void endSession();
+
+       /// show count of checked words at normal exit
+       void showSummary();
+
        /// set the params before show or update
        void setParams();
        /// clean-up on hide.
@@ -79,14 +95,8 @@
        /// word count
        int count_;
 
-       /// exit message
-       string message_;
-
-       /// set to true to stop checking
-       bool stop_;
-
        /// The actual spellchecker object
-       SpellBase * speller_;
+       boost::scoped_ptr<SpellBase> speller_;
 };
 
 #endif // CONTROLSPELLCHECKER_H
Index: frontends/xforms/FormSpellchecker.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/FormSpellchecker.C,v
retrieving revision 1.31
diff -u -r1.31 FormSpellchecker.C
--- frontends/xforms/FormSpellchecker.C 13 Feb 2003 16:52:58 -0000      1.31
+++ frontends/xforms/FormSpellchecker.C 16 Feb 2003 02:44:30 -0000
@@ -12,7 +12,6 @@
 
 
 #include "xformsBC.h"
-#include "ControlSpellchecker.h"
 #include "FormSpellchecker.h"
 #include "forms/form_spellchecker.h"
 
@@ -23,11 +22,12 @@
 
 #include FORMS_H_LOCATION
 
-typedef FormCB<ControlSpellchecker, FormDB<FD_spellchecker> > base_class;
+using std::endl;
 
+typedef FormCB<ControlSpellchecker, FormDB<FD_spellchecker> > base_class;
 
 FormSpellchecker::FormSpellchecker()
-       : base_class(_("Spellchecker")), state_(STOPPED)
+       : base_class(_("Spellchecker"))
 {}
 
 
@@ -61,8 +61,6 @@
        tooltips().init(dialog_->browser_suggestions, str);
        // Work-around xforms' bug; enable tooltips for browser widgets.
        setPrehandler(dialog_->browser_suggestions);
-       str = _("Start the spellingchecker.");
-       tooltips().init(dialog_->button_start, str);
        str = _("Replace unknown word.");
        tooltips().init(dialog_->button_replace, str);
        str = _("Ignore unknown word.");
@@ -76,16 +74,14 @@
 }
 
 
-void FormSpellchecker::updateState(State state)
+void FormSpellchecker::partialUpdate(int s)
 {
+       ControlSpellchecker::State const state =
+               static_cast<ControlSpellchecker::State>(s);
+
        switch (state) {
-       case READY_TO_START:
-               fl_set_slider_value(dialog_->slider_progress, 0.0);
-               fl_set_object_label(dialog_->slider_progress, "0 %");
-               break;
 
-       case CHECKING:
-       {
+       case ControlSpellchecker::SPELL_FOUND_WORD: {
                // Set suggestions.
                string w = controller().getWord();
                fl_set_input(dialog_->input_replacement, w.c_str());
@@ -98,8 +94,7 @@
                // Fall through...
        }
 
-       case STARTED:
-       {
+       case ControlSpellchecker::SPELL_PROGRESSED: {
                int const progress = controller().getProgress();
                if (progress == 0)
                        break;
@@ -111,68 +106,33 @@
                fl_set_slider_bounds(dialog_->slider_progress, 0.0, total);
                fl_set_slider_value(dialog_->slider_progress, wordcount);
                fl_set_object_label(dialog_->slider_progress, label.c_str());
+               fl_redraw_object(dialog_->slider_progress);
                break;
        }
 
-       case STOPPED:
-       {
-               controller().stop();
-
-               double const wordcount = controller().getCount();
-
-               fl_set_slider_bounds(dialog_->slider_progress, 0.0, wordcount);
-               fl_set_slider_value(dialog_->slider_progress, wordcount);
-               fl_set_object_label(dialog_->slider_progress, "100 %");
-               break;
-       }
        }
-
-       bool const state_change = state_ != state;
-       state_ = state;
-
-       if (!state_change)
-               return;
-
-       bool const running = (state == STARTED || state == CHECKING);
-       string const label = running ? _("Stop|#S") : _("Start|#S");
-
-       fl_set_object_label(dialog_->button_start, idex(label).c_str());
-       fl_set_button_shortcut(dialog_->button_start, scex(label).c_str(), 1);
-       fl_redraw_object(dialog_->button_start);
-
-       string const tip = running ?
-               _("Stop the spellingchecker.") :
-               _("Start the spellingchecker.");
-       tooltips().init(dialog_->button_start, tip);
-
-       setEnabled(dialog_->button_replace,      running);
-       setEnabled(dialog_->button_ignore,       running);
-       setEnabled(dialog_->button_accept,       running);
-       setEnabled(dialog_->button_add,          running);
-       setEnabled(dialog_->browser_suggestions, running);
-       setEnabled(dialog_->input_replacement,   running);
 }
 
 
 void FormSpellchecker::update()
 {
+       lyxerr[Debug::GUI] << "Spell update() " << endl;
+
        // clear input fields
        fl_set_input(dialog_->input_replacement, "");
        fl_set_object_label(dialog_->text_unknown, "");
        fl_clear_browser(dialog_->browser_suggestions);
+       fl_set_slider_value(dialog_->slider_progress, 0.0);
+       fl_set_object_label(dialog_->slider_progress, "0 %");
 
-       // reset dialog and buttons into start condition
-       updateState(READY_TO_START);
+       // FIXME: can we do this in the controller ?
+       controller().check();
 }
 
 
 ButtonPolicy::SMInput FormSpellchecker::input(FL_OBJECT * ob, long ob_value)
 {
-       if (ob == dialog_->button_start) {
-               updateState(STARTED);
-               controller().check();
-
-       } else if (ob == dialog_->button_replace) {
+       if (ob == dialog_->button_replace) {
                string const tmp = getString(dialog_->input_replacement);
                controller().replace(tmp);
 
@@ -205,19 +165,4 @@
        }
 
        return ButtonPolicy::SMI_VALID;
-}
-
-
-void FormSpellchecker::partialUpdate(int id)
-{
-       switch (id) {
-       case 1:
-               // Set suggestions.
-               updateState(CHECKING);
-               break;
-       case 2:
-               // End of spell checking.
-               updateState(STOPPED);
-               break;
-       }
 }
Index: frontends/xforms/FormSpellchecker.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/FormSpellchecker.h,v
retrieving revision 1.16
diff -u -r1.16 FormSpellchecker.h
--- frontends/xforms/FormSpellchecker.h 13 Feb 2003 16:52:58 -0000      1.16
+++ frontends/xforms/FormSpellchecker.h 16 Feb 2003 02:44:30 -0000
@@ -14,8 +14,8 @@
 
 
 #include "FormBase.h"
+#include "ControlSpellchecker.h"
 
-class ControlSpellchecker;
 struct FD_spellchecker;
 
 /** This class provides an XForms implementation of the FormSpellchecker Dialog.
@@ -38,18 +38,6 @@
 
        /// Filter the inputs
        virtual ButtonPolicy::SMInput input(FL_OBJECT *, long);
-
-       ///
-       enum State {
-               READY_TO_START,
-               STARTED,
-               CHECKING,
-               STOPPED
-       };
-       ///
-       void updateState(State state);
-       ///
-       State state_;
 };
 
 #endif // FORMSPELLCHECKER_H
Index: frontends/xforms/forms/form_spellchecker.fd
===================================================================
RCS file: 
/usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/forms/form_spellchecker.fd,v
retrieving revision 1.10
diff -u -r1.10 form_spellchecker.fd
--- frontends/xforms/forms/form_spellchecker.fd 26 Jan 2003 16:58:37 -0000      1.10
+++ frontends/xforms/forms/form_spellchecker.fd 16 Feb 2003 02:44:31 -0000
@@ -11,7 +11,7 @@
 Name: form_spellchecker
 Width: 385
 Height: 375
-Number of Objects: 13
+Number of Objects: 12
 
 --------------------
 class: FL_BOX
@@ -118,24 +118,6 @@
 resize: FL_RESIZE_ALL
 gravity: FL_NorthWest FL_SouthEast
 name: browser_suggestions
-callback: C_FormBaseInputCB
-argument: 0
-
---------------------
-class: FL_BUTTON
-type: NORMAL_BUTTON
-box: 280 25 100 25
-boxtype: FL_UP_BOX
-colors: FL_COL1 FL_COL1
-alignment: FL_ALIGN_CENTER
-style: FL_NORMAL_STYLE
-size: FL_NORMAL_SIZE
-lcol: FL_BLACK
-label: Start|#S
-shortcut: 
-resize: FL_RESIZE_NONE
-gravity: FL_NorthEast FL_NorthEast
-name: button_start
 callback: C_FormBaseInputCB
 argument: 0
 
Index: support/forkedcall.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/support/forkedcall.C,v
retrieving revision 1.12
diff -u -r1.12 forkedcall.C
--- support/forkedcall.C        13 Feb 2003 16:53:14 -0000      1.12
+++ support/forkedcall.C        16 Feb 2003 02:44:33 -0000
@@ -143,6 +143,19 @@
        return retval_;
 }
 
+
+bool ForkedProcess::running() const
+{
+       if (!pid())
+               return false;
+
+       // Racy of course, but it will do.
+       if (::kill(pid(), 0) && errno == ESRCH)
+               return false;
+       return true;
+}
+
+
 void ForkedProcess::kill(int tol)
 {
        lyxerr << "ForkedProcess::kill(" << tol << ')' << endl;
Index: support/forkedcall.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/support/forkedcall.h,v
retrieving revision 1.8
diff -u -r1.8 forkedcall.h
--- support/forkedcall.h        13 Feb 2003 16:53:14 -0000      1.8
+++ support/forkedcall.h        16 Feb 2003 02:44:33 -0000
@@ -94,6 +94,9 @@
        /// Returns the identifying command (for display in the GUI perhaps).
        string const & command() const { return command_; }
 
+       /// is the process running ?
+       bool running() const;
+
        /** Kill child prematurely.
         *  First, a SIGHUP is sent to the child.
         *  If that does not end the child process within "tolerance"

Reply via email to