Conflicts resolved. Haven't tested the Qt bits, if somebody wants to ...

Anyway, if you want to consider this JMarc, here's the patch.

regards
john


Index: status.13x
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/Attic/status.13x,v
retrieving revision 1.1.2.24
diff -u -r1.1.2.24 status.13x
--- status.13x  17 Feb 2003 18:39:06 -0000      1.1.2.24
+++ status.13x  17 Feb 2003 19:05:48 -0000
@@ -78,3 +78,15 @@
 - fix strerror() build problem with some gcc/glibc versions [bug #874]
 
 - revert is now disabled for an unchanged or unsaved document [bug #783]
+
+- The spell-checking system has been over-hauled, including the following
+  changes :
+
+  o start spell-checking immediately on pressing F7
+  o xform's broken start/stop button removed
+  o better spell progress feedback
+  o long hang on ispell error changed
+  o infinite hang on ispell error fixed
+  o reports ispell errors back to the user
+  o the personal dictionaries are always correctly written out
+  o "Accept" button became "Ignore All" for clarity
Index: src/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ChangeLog,v
retrieving revision 1.1021.2.4
diff -u -r1.1021.2.4 ChangeLog
--- src/ChangeLog       17 Feb 2003 18:39:06 -0000      1.1021.2.4
+++ src/ChangeLog       17 Feb 2003 19:06:00 -0000
@@ -1,5 +1,13 @@
 2003-02-17  John Levon  <[EMAIL PROTECTED]>
 
+       * SpellBase.h:
+       * ispell.h:
+       * ispell.C:
+       * pspell.h:
+       * pspell.C: reworking
+
+2003-02-17  John Levon  <[EMAIL PROTECTED]>
+
        * lyxfunc.C: fix bug 738 - revert behaves sensibly
 
 2003-02-14  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
Index: src/SpellBase.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/SpellBase.h,v
retrieving revision 1.4
diff -u -r1.4 SpellBase.h
--- src/SpellBase.h     1 Dec 2002 22:59:17 -0000       1.4
+++ src/SpellBase.h     17 Feb 2003 19:06:00 -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: src/ispell.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ispell.C,v
retrieving revision 1.5
diff -u -r1.5 ispell.C
--- src/ispell.C        27 Nov 2002 10:30:07 -0000      1.5
+++ src/ispell.C        17 Feb 2003 19:06:00 -0000
@@ -13,35 +13,6 @@
 #pragma implementation
 #endif
 
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <cstdio>
-
-// FIXME: do we need any of this horrible gook ?
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <ctime>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <ctime>
-# endif
-#endif
-
-#ifdef HAVE_SYS_SELECT_H
-# ifdef HAVE_STRINGS_H
-   // <strings.h> is needed at least on AIX because FD_ZERO uses bzero().
-   // BUT we cannot include both string.h and strings.h on Irix 6.5 :(
-#  ifdef _AIX
-#   include <strings.h>
-#  endif
-# endif
-#include <sys/select.h>
-#endif
-
 #include "LString.h"
 #include "lyxrc.h"
 #include "language.h"
@@ -49,10 +20,13 @@
 #include "encoding.h"
 #include "ispell.h"
 #include "WordLangTuple.h"
+#include "gettext.h"
 
 #include "support/forkedcall.h"
 #include "support/lstrings.h"
 
+#include <sys/select.h>
+
 #ifndef CXX_GLOBAL_CSTD
 using std::strcpy;
 using std::strlen;
@@ -61,18 +35,16 @@
 #endif
 
 using std::endl;
+using std::max;
 
 namespace {
 
-/// pid for the `ispell' process.
-pid_t isp_pid = -1;
-
 class LaunchIspell : public ForkedProcess {
 public:
        ///
        LaunchIspell(BufferParams const & p, string const & l,
-                    int * in, int * out)
-               : params(p), lang(l), pipein(in), pipeout(out) {}
+                    int * in, int * out, int * err)
+               : params(p), lang(l), pipein(in), pipeout(out), pipeerr(err) {}
        ///
        virtual ForkedProcess * clone() const {
                return new LaunchIspell(*this);
@@ -88,6 +60,7 @@
        string const & lang;
        int * const pipein;
        int * const pipeout;
+       int * const pipeerr;
 };
 
 
@@ -100,7 +73,7 @@
 
 int LaunchIspell::generateChild()
 {
-       isp_pid = fork();
+       pid_t isp_pid = fork();
 
        if (isp_pid != 0) {
                // failed (-1) or parent process (>0)
@@ -110,10 +83,13 @@
        // child process
        dup2(pipein[0], STDIN_FILENO);
        dup2(pipeout[1], STDOUT_FILENO);
-       ::close(pipein[0]);
-       ::close(pipein[1]);
-       ::close(pipeout[0]);
-       ::close(pipeout[1]);
+       dup2(pipeerr[1], STDERR_FILENO);
+       close(pipein[0]);
+       close(pipein[1]);
+       close(pipeout[0]);
+       close(pipeout[1]);
+       close(pipeerr[0]);
+       close(pipeerr[1]);
 
        char * argv[14];
        int argc = 0;
@@ -204,122 +180,161 @@
 
 
 ISpell::ISpell(BufferParams const & params, string const & lang)
-       : str(0)
+       : in(0), out(0), inerr(0), str(0)
 {
-       static char o_buf[BUFSIZ];  // jc: it could be smaller
-       int pipein[2];
-       int pipeout[2];
+       lyxerr[Debug::GUI] << "Created ispell" << endl;
+
+       // static due to the setvbuf. Ugly.
+       static char o_buf[BUFSIZ];
+       
+       // We need to throw an exception not do this
+       pipein[0] = pipein[1] = pipeout[0] = pipeout[1]
+               = pipeerr[0] = pipeerr[1] = -1;
 
-       isp_pid = -1;
+       // This is what happens when goto gets banned.
 
-       if (pipe(pipein) == -1 || pipe(pipeout) == -1) {
-               lyxerr << "LyX: Can't create pipe for spellchecker!" << endl;
-               setError();
+       if (pipe(pipein) == -1) {
+               error_ = _("Can't create pipe for spellchecker.");
+               return;
+       }
+
+       if (pipe(pipeout) == -1) {
+               close(pipein[0]);
+               close(pipein[1]);
+               error_ = _("Can't create pipe for spellchecker.");
+               return;
+       }
+
+       if (pipe(pipeerr) == -1) {
+               close(pipein[0]);
+               close(pipein[1]);
+               close(pipeout[0]);
+               close(pipeout[1]);
+               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 open 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 open pipe for spellchecker.");
                return;
        }
 
-       setvbuf(out, o_buf, _IOLBF, BUFSIZ);
+       if ((inerr = fdopen(pipeerr[0], "r")) == 0) {
+               error_ = _("Can't open pipe for spellchecker.");
+               return;
+       }
 
-       isp_fd = pipeout[0];
+       setvbuf(out, o_buf, _IOLBF, BUFSIZ);
 
-       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, pipeerr);
+       child_.reset(li);
+       if (li->start() == -1) {
+               error_ = _("Could not create an ispell process.\nYou 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
-       // aspell -- ([EMAIL PROTECTED])
-       // But no code actually used the results for anything useful
-       // so I removed it again. Perhaps we can remove this code too.
-       // - jbl
-       char buf[2048];
-       fd_set infds;
-       struct timeval tv;
-       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_usec = 0;
 
-       // Configure provides us with macros which are supposed to do
-       // the right typecast.
-       retval = select(SELECT_TYPE_ARG1 (pipeout[0]+1),
-                       SELECT_TYPE_ARG234 (&infds),
-                       0,
-                       0,
-                       SELECT_TYPE_ARG5 (&tv));
+       bool err_read;
+       bool error = select(err_read);
 
-       if (retval > 0) {
-               // Ok, do the reading. We don't have to FD_ISSET since
-               // there is only one fd in infds.
-               fgets(buf, 2048, in);
-
-               fputs("!\n", out); // Set terse mode (silently accept correct words)
-
-       } 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;
-               ::close(pipeout[0]);
-               ::close(pipeout[1]);
-               ::close(pipein[0]);
-               ::close(pipein[1]);
-               isp_fd = -1;
+       if (!error) {
+               if (!err_read) {
+                       // Set terse mode (silently accept correct words)
+                       fputs("!\n", out);
+                       return;
+               }
+
+               /* must have read something from stderr */
+               error_ = buf;
        } else {
-               // Select returned error
-               lyxerr << "Select on ispell returned error, what now?" << endl;
+               // select returned error
+               error_ = _("The spell process returned an error.\nPerhaps "
+                               "it has been configured wrongly ?");
        }
+
+       close(pipein[0]);
+       close(pipein[1]);
+       close(pipeout[0]);
+       close(pipeout[1]);
+       close(pipeerr[0]);
+       close(pipeerr[1]);
+       child_->kill();
+       child_.reset(0);
 }
 
 
 ISpell::~ISpell()
 {
-       delete[] str;
+       lyxerr[Debug::GUI] << "Killing ispell" << endl;
+
+       if (in)
+               fclose(in);
+
+       if (inerr)
+               fclose(inerr);
+
+       if (out) {
+               fputs("#\n", out); // Save personal dictionary
+
+               fflush(out);
+               fclose(out);
+       }
+
+       close(pipein[0]);
+       close(pipein[1]);
+       close(pipeout[0]);
+       close(pipeout[1]);
+       close(pipeerr[0]);
+       close(pipeerr[1]);
+       delete [] str;
 }
 
 
-void ISpell::setError()
+bool ISpell::select(bool & err_read)
 {
-       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;
+       fd_set infds;
+       struct timeval tv;
+       int retval = 0;
+       FD_ZERO(&infds);
+       FD_SET(pipeout[0], &infds);
+       FD_SET(pipeerr[0], &infds);
+       tv.tv_sec = 2;
+       tv.tv_usec = 0;
+
+       retval = ::select(SELECT_TYPE_ARG1 (max(pipeout[0], pipeerr[0]) + 1),
+                       SELECT_TYPE_ARG234 (&infds),
+                       0,
+                       0,
+                       SELECT_TYPE_ARG5 (&tv));
+
+       // error
+       if (retval <= 0)
+               return true;
+
+       if (FD_ISSET(pipeerr[0], &infds)) {
+               fgets(buf, BUFSIZ, inerr);
+               err_read = true;
+               return false;
        }
+
+       fgets(buf, BUFSIZ, in);
+       err_read = false;
+       return false;
 }
 
 
 string const ISpell::nextMiss()
 {
+       // Well, somebody is a sick fuck.
+
        if (str == 0 || *(e+1) == '\0')
                return "";
        char * b = e + 2;
@@ -333,13 +348,7 @@
 
 bool ISpell::alive()
 {
-       return isp_pid != -1;
-}
-
-
-void ISpell::cleanUp()
-{
-       ::fclose(out);
+       return child_.get() && child_->running();
 }
 
 
@@ -352,8 +361,18 @@
        ::fputs(word.word().c_str(), out);
        ::fputc('\n', out);
 
-       char buf[1024];
-       ::fgets(buf, 1024, in);
+       bool err_read;
+       bool error = select(err_read);
+
+       if (error) {
+               error_ = _("Could not communicate with the spell-checker program");
+               return UNKNOWN;
+       }
+
+       if (err_read) {
+               error_ = buf;
+               return UNKNOWN;
+       }
 
        // I think we have to check if ispell is still alive here because
        // the signal-handler could have disabled blocking on the fd
@@ -400,20 +419,6 @@
 }
 
 
-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);
-}
-
-
 void ISpell::insert(WordLangTuple const & word)
 {
        ::fputc('*', out); // Insert word in personal dictionary
@@ -432,7 +437,5 @@
 
 string const ISpell::error()
 {
-       if (error_)
-               return error_;
-       return "";
+       return error_;
 }
Index: src/ispell.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ispell.h,v
retrieving revision 1.5
diff -u -r1.5 ispell.h
--- src/ispell.h        1 Dec 2002 22:59:17 -0000       1.5
+++ src/ispell.h        17 Feb 2003 19:06:00 -0000
@@ -10,11 +10,14 @@
 #ifndef SP_ISPELL_H
 #define SP_ISPELL_H
 
-#include <cstdio>
-
 #include "SpellBase.h"
 
+#include <boost/scoped_ptr.hpp>
+
+#include <cstdio>
+
 class BufferParams;
+class ForkedProcess;
 
 /// i/a spell process-based spellchecker
 class ISpell : public SpellBase {
@@ -26,15 +29,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,17 +45,29 @@
        virtual string const error();
 
 private:
-       ///
-       void setError();
+       /// read some data. Returns true on an error. Sets err_read
+       /// to true if the data was from stderr.
+       bool select(bool & err_read);
 
        /// instream to communicate with ispell
        FILE * in;
        /// outstream to communicate with ispell
        FILE * out;
+       /// errstream for ispell
+       FILE * inerr;
+
+       /// pipe fds
+       int pipein[2];
+       int pipeout[2];
+       int pipeerr[2];
+
+       /// buffer for reading
+       char buf[BUFSIZ];
+
        /// spell error
-       char const * error_;
-       /// the fd of the outgoing pipe
-       int isp_fd;
+       string error_;
+
+       boost::scoped_ptr<ForkedProcess> child_;
 
        // vileness below ... please FIXME
        /// str ???
Index: src/pspell.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/pspell.C,v
retrieving revision 1.7
diff -u -r1.7 pspell.C
--- src/pspell.C        1 Dec 2002 22:59:17 -0000       1.7
+++ src/pspell.C        17 Feb 2003 19:06:00 -0000
@@ -16,6 +16,7 @@
 #ifdef USE_PSPELL
 
 #include "support/LAssert.h"
+#include "debug.h"
 
 #define USE_ORIGINAL_MANAGER_FUNCS 1
 // new aspell pspell missing extern "C"
@@ -26,38 +27,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();
@@ -109,17 +111,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: src/pspell.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/pspell.h,v
retrieving revision 1.3
diff -u -r1.3 pspell.h
--- src/pspell.h        1 Dec 2002 22:59:17 -0000       1.3
+++ src/pspell.h        17 Feb 2003 19:06:01 -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: src/frontends/controllers/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ChangeLog,v
retrieving revision 1.273
diff -u -r1.273 ChangeLog
--- src/frontends/controllers/ChangeLog 2 Feb 2003 00:48:38 -0000       1.273
+++ src/frontends/controllers/ChangeLog 17 Feb 2003 19:06:03 -0000
@@ -1,3 +1,10 @@
+2003-02-17  John Levon  <[EMAIL PROTECTED]>
+
+       * ControlDialog.tmpl: do build before  setParams for spellchecker's sake
+
+       * ControlSpellchecker.h:
+       * ControlSpellchecker.C: rework
+
 2003-01-31  Angus Leeming  <[EMAIL PROTECTED]>
 
        * ViewBase.h: add an isVisible() pure virtual method.
Index: src/frontends/controllers/ControlDialog.tmpl
===================================================================
RCS file: 
/usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ControlDialog.tmpl,v
retrieving revision 1.9
diff -u -r1.9 ControlDialog.tmpl
--- src/frontends/controllers/ControlDialog.tmpl        22 Oct 2002 12:39:05 -0000     
 1.9
+++ src/frontends/controllers/ControlDialog.tmpl        17 Feb 2003 19:06:03 -0000
@@ -32,15 +32,15 @@
 
        connect();
 
+       if (!dialog_built_) {
+               view().build();
+               dialog_built_ = true;
+       }
+
        setParams();
        if (emergency_exit_) {
                hide();
                return;
-       }
-
-       if (!dialog_built_) {
-               view().build();
-               dialog_built_ = true;
        }
 
        bc().readOnly(bufferIsReadonly());
Index: src/frontends/controllers/ControlSpellchecker.C
===================================================================
RCS file: 
/usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ControlSpellchecker.C,v
retrieving revision 1.36
diff -u -r1.36 ControlSpellchecker.C
--- src/frontends/controllers/ControlSpellchecker.C     15 Jan 2003 14:23:21 -0000     
 1.36
+++ src/frontends/controllers/ControlSpellchecker.C     17 Feb 2003 19:06:03 -0000
@@ -22,6 +22,7 @@
 #include "language.h"
 #include "lyxrc.h"
 #include "lyxtext.h"
+#include "debug.h"
 
 #include "ispell.h"
 #ifdef USE_PSPELL
@@ -32,17 +33,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;
@@ -51,70 +76,161 @@
                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;
+       emergency_exit_ = false;
+
+       // start off the check
+       if (speller_->error().empty()) {
+               check();
                return;
        }
+
+       emergency_exit_ = true;
+       string message = speller_->error();
+       if (message.empty())
+               message = _("The spell-checker could not be started.\n"
+                        "Maybe it is mis-configured.");
+
+       Alert::alert(_("The spell-checker has failed"), message);
+       speller_.reset(0);
+}
+
+
+void ControlSpellchecker::endSession()
+{
+       lyxerr[Debug::GUI] << "spell endSession" << endl;
+
+       bufferview()->endOfSpellCheck();
+
+       emergency_exit_ = true;
+
+       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();
+               // speller might be dead ...
+               if (!checkAlive())
                        return;
-               }
 
                res = speller_->check(word_);
+
+               // ... or it might just be reporting an error
+               if (!checkAlive())
+                       return;
        }
 
-       if (!stop_ && !word_.word().empty())
+       lyxerr[Debug::GUI] << "Found word \"" << word_.word() << "\"" << endl;
+
+       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() && 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.");
+
+       view().hide();
+       speller_.reset(0);
+
+       Alert::alert(_("The spell-checker has failed"), message);
+       return false;
+}
+
+
+void ControlSpellchecker::showSummary()
+{
+       if (!checkAlive() || count_ == 0) {
+               view().hide();
+               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
+
+       view().hide();
+       Alert::alert(_("Spell-checking is complete"), message);
 }
 
 
@@ -160,64 +276,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: src/frontends/controllers/ControlSpellchecker.h
===================================================================
RCS file: 
/usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ControlSpellchecker.h,v
retrieving revision 1.14
diff -u -r1.14 ControlSpellchecker.h
--- src/frontends/controllers/ControlSpellchecker.h     15 Jan 2003 14:23:21 -0000     
 1.14
+++ src/frontends/controllers/ControlSpellchecker.h     17 Feb 2003 19:06:03 -0000
@@ -20,15 +20,23 @@
 #include "LString.h"
 #include "WordLangTuple.h"
 
+#include <boost/scoped_ptr.hpp>
+
 class SpellBase;
 
 /** A controller for Spellchecker dialogs.
  */
 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 &);
 
@@ -41,10 +49,8 @@
        /// ignore all occurances of word
        void ignoreAll();
 
-       /// stop checking
-       void stop();
-
        /// check text until next misspelled/unknown word
+       /// returns true when finished
        void check();
 
        /// get suggestion
@@ -56,13 +62,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.
@@ -82,14 +97,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: src/frontends/qt2/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/ChangeLog,v
retrieving revision 1.389.2.10
diff -u -r1.389.2.10 ChangeLog
--- src/frontends/qt2/ChangeLog 17 Feb 2003 00:40:29 -0000      1.389.2.10
+++ src/frontends/qt2/ChangeLog 17 Feb 2003 19:06:06 -0000
@@ -1,5 +1,13 @@
 2003-02-17  John Levon  <[EMAIL PROTECTED]>
 
+       * ui/QSpellcheckerDialogBase.ui:
+       * QSpellchecker.h:
+       * QSpellchecker.C:
+       * QSpellcheckerDialog.h:
+       * QSpellcheckerDialog.C: reworking
+
+2003-02-17  John Levon  <[EMAIL PROTECTED]>
+
        * ui/QSpellcheckerModule.ui: capitalization fix
 
 2003-02-15  John Levon  <[EMAIL PROTECTED]>
Index: src/frontends/qt2/QSpellchecker.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/QSpellchecker.C,v
retrieving revision 1.16
diff -u -r1.16 QSpellchecker.C
--- src/frontends/qt2/QSpellchecker.C   13 Jan 2003 09:17:12 -0000      1.16
+++ src/frontends/qt2/QSpellchecker.C   17 Feb 2003 19:06:06 -0000
@@ -46,22 +46,6 @@
 }
 
 
-void QSpellchecker::update_contents()
-{
-       dialog_->wordED->setText("");
-       dialog_->replaceCO->clear();
-       dialog_->suggestionsLB->clear();
-       dialog_->spellcheckPR->setProgress(0);
-       dialog_->spellcheckPB->setEnabled(true);
-       dialog_->wordED->setEnabled(false);
-       dialog_->replaceCO->setEnabled(false);
-       dialog_->replacePB->setEnabled(false);
-       dialog_->ignorePB->setEnabled(false);
-       dialog_->replacePB_3->setEnabled(false);
-       dialog_->addPB->setEnabled(false);
-}
-
-
 void QSpellchecker::accept()
 {
        controller().ignoreAll();
@@ -86,35 +70,18 @@
 }
 
 
-void QSpellchecker::spellcheck()
-{
-       dialog_->spellcheckPB->setEnabled(false);
-       dialog_->wordED->setEnabled(true);
-       dialog_->replaceCO->setEnabled(true);
-       dialog_->replacePB->setEnabled(true);
-       dialog_->ignorePB->setEnabled(true);
-       dialog_->replacePB_3->setEnabled(true);
-       dialog_->addPB->setEnabled(true);
-       controller().check();
-}
-
-
-void QSpellchecker::stop()
+void QSpellchecker::partialUpdate(int s)
 {
-       controller().stop();
-       dialog_->spellcheckPB->setEnabled(true);
-       hide();
-}
+       ControlSpellchecker::State const state = 
+               static_cast<ControlSpellchecker::State>(s);
 
+       switch (state) {
 
-void QSpellchecker::partialUpdate(int id)
-{
-       switch (id) {
-       case 0:
+       case ControlSpellchecker::SPELL_PROGRESSED:
                dialog_->spellcheckPR->setProgress(controller().getProgress());
                break;
 
-       case 1: {
+       case ControlSpellchecker::SPELL_FOUND_WORD: {
                dialog_->wordED->setText(toqstr(controller().getWord()));
                dialog_->suggestionsLB->clear();
 
@@ -127,12 +94,5 @@
        }
                break;
 
-       case 2:
-               dialog_->spellcheckPB->setEnabled(true);
-               hide();
-               QMessageBox::information(0, qt_("Spellcheck complete"),
-                                        toqstr(controller().getMessage()),
-                                        qt_("OK"));
-               break;
        }
 }
Index: src/frontends/qt2/QSpellchecker.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/QSpellchecker.h,v
retrieving revision 1.7
diff -u -r1.7 QSpellchecker.h
--- src/frontends/qt2/QSpellchecker.h   20 Oct 2002 01:48:28 -0000      1.7
+++ src/frontends/qt2/QSpellchecker.h   17 Feb 2003 19:06:06 -0000
@@ -34,17 +34,15 @@
        /// update from controller
        void partialUpdate(int id);
 private:
-       void stop();
        void accept();
        void add();
        void ignore();
        void replace();
-       void spellcheck();
 
        /// Apply changes
        virtual void apply() {}
-       /// update
-       virtual void update_contents();
+       /// not needed
+       virtual void update_contents() {}
        /// build the dialog
        virtual void build_dialog();
 };
Index: src/frontends/qt2/QSpellcheckerDialog.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/QSpellcheckerDialog.C,v
retrieving revision 1.9
diff -u -r1.9 QSpellcheckerDialog.C
--- src/frontends/qt2/QSpellcheckerDialog.C     17 Dec 2002 20:37:10 -0000      1.9
+++ src/frontends/qt2/QSpellcheckerDialog.C     17 Feb 2003 19:06:06 -0000
@@ -29,13 +29,7 @@
        form_(form)
 {
        connect(closePB, SIGNAL(clicked()),
-               this, SLOT(stop()));
-}
-
-
-void QSpellcheckerDialog::stop()
-{
-       form_->stop();
+               form, SLOT(slotClose()));
 }
 
 
@@ -45,12 +39,6 @@
 }
 
 
-void QSpellcheckerDialog::spellcheckClicked()
-{
-       form_->spellcheck();
-}
-
-
 void QSpellcheckerDialog::addClicked()
 {
        form_->add();
@@ -98,7 +86,6 @@
 
 void QSpellcheckerDialog::closeEvent(QCloseEvent * e)
 {
-       form_->stop();
        form_->slotWMHide();
        e->accept();
 }
Index: src/frontends/qt2/QSpellcheckerDialog.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/QSpellcheckerDialog.h,v
retrieving revision 1.9
diff -u -r1.9 QSpellcheckerDialog.h
--- src/frontends/qt2/QSpellcheckerDialog.h     12 Dec 2002 21:07:20 -0000      1.9
+++ src/frontends/qt2/QSpellcheckerDialog.h     17 Feb 2003 19:06:06 -0000
@@ -28,9 +28,7 @@
        virtual void suggestionChanged(const QString &);
  
 protected slots:
-       virtual void stop();
        virtual void acceptClicked();
-       virtual void spellcheckClicked();
        virtual void addClicked();
        virtual void replaceClicked();
        virtual void ignoreClicked();
Index: src/frontends/qt2/ui/QSpellcheckerDialogBase.ui
===================================================================
RCS file: 
/usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/ui/QSpellcheckerDialogBase.ui,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 QSpellcheckerDialogBase.ui
--- src/frontends/qt2/ui/QSpellcheckerDialogBase.ui     13 Feb 2003 22:40:28 -0000     
 1.1.2.1
+++ src/frontends/qt2/ui/QSpellcheckerDialogBase.ui     17 Feb 2003 19:06:07 -0000
@@ -13,7 +13,7 @@
         <rect>
             <x>0</x>
             <y>0</y>
-            <width>309</width>
+            <width>305</width>
             <height>395</height>
         </rect>
     </property>
@@ -72,7 +72,7 @@
             </property>
             <property stdset="1">
                 <name>text</name>
-                <string>A&amp;dd</string>
+                <string>&amp;Add</string>
             </property>
             <property>
                 <name>toolTip</name>
@@ -102,7 +102,7 @@
             </property>
             <property stdset="1">
                 <name>text</name>
-                <string>&amp;Accept</string>
+                <string>I&amp;gnore All</string>
             </property>
             <property>
                 <name>toolTip</name>
@@ -218,7 +218,7 @@
             </property>
             <property stdset="1">
                 <name>text</name>
-                <string>Unknown:</string>
+                <string>Unknown word:</string>
             </property>
             <property>
                 <name>buddy</name>
@@ -263,21 +263,6 @@
                 <string>Replace with selected word</string>
             </property>
         </widget>
-        <widget row="1"  column="2" >
-            <class>QPushButton</class>
-            <property stdset="1">
-                <name>name</name>
-                <cstring>spellcheckPB</cstring>
-            </property>
-            <property stdset="1">
-                <name>text</name>
-                <string>&amp;Start...</string>
-            </property>
-            <property>
-                <name>toolTip</name>
-                <string>Start spellcheck</string>
-            </property>
-        </widget>
     </grid>
 </widget>
 <connections>
@@ -312,12 +297,6 @@
         <slot>addClicked()</slot>
     </connection>
     <connection>
-        <sender>spellcheckPB</sender>
-        <signal>clicked()</signal>
-        <receiver>QSpellcheckerDialogBase</receiver>
-        <slot>spellcheckClicked()</slot>
-    </connection>
-    <connection>
         <sender>suggestionsLB</sender>
         <signal>doubleClicked(QListBoxItem*)</signal>
         <receiver>QSpellcheckerDialogBase</receiver>
@@ -335,11 +314,9 @@
     <slot access="public">optionsClicked()</slot>
     <slot access="public">replaceChanged(const QString &amp;)</slot>
     <slot access="public">replaceClicked()</slot>
-    <slot access="public">spellcheckClicked()</slot>
     <slot access="public">suggestionChanged(const QString &amp;)</slot>
 </connections>
 <tabstops>
-    <tabstop>spellcheckPB</tabstop>
     <tabstop>wordED</tabstop>
     <tabstop>replaceCO</tabstop>
     <tabstop>suggestionsLB</tabstop>
Index: src/frontends/xforms/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/ChangeLog,v
retrieving revision 1.661.2.3
diff -u -r1.661.2.3 ChangeLog
--- src/frontends/xforms/ChangeLog      15 Feb 2003 19:09:04 -0000      1.661.2.3
+++ src/frontends/xforms/ChangeLog      17 Feb 2003 19:06:12 -0000
@@ -1,3 +1,9 @@
+2003-02-17  John Levon  <[EMAIL PROTECTED]>
+
+       * FormSpellchecker.h:
+       * FormSpellchecker.C:
+       * forms/form_spellchecker.fd: reworking
+
 2003-02-15  John Levon  <[EMAIL PROTECTED]>
 
        * forms/form_graphics.fd: fix duplicate 'a' shortcut
Index: src/frontends/xforms/FormSpellchecker.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/FormSpellchecker.C,v
retrieving revision 1.30
diff -u -r1.30 FormSpellchecker.C
--- src/frontends/xforms/FormSpellchecker.C     26 Dec 2002 14:14:29 -0000      1.30
+++ src/frontends/xforms/FormSpellchecker.C     17 Feb 2003 19:06:13 -0000
@@ -15,8 +15,8 @@
 #endif
 
 #include "xformsBC.h"
-#include "ControlSpellchecker.h"
 #include "FormSpellchecker.h"
+#include "ControlSpellchecker.h"
 #include "forms/form_spellchecker.h"
 
 #include "forms_gettext.h"
@@ -26,11 +26,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"))
 {}
 
 
@@ -64,8 +65,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.");
@@ -79,16 +78,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());
@@ -101,8 +98,7 @@
                // Fall through...
        }
 
-       case STARTED:
-       {
+       case ControlSpellchecker::SPELL_PROGRESSED: {
                int const progress = controller().getProgress();
                if (progress == 0)
                        break;
@@ -114,68 +110,17 @@
                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()
-{
-       // clear input fields
-       fl_set_input(dialog_->input_replacement, "");
-       fl_set_object_label(dialog_->text_unknown, "");
-       fl_clear_browser(dialog_->browser_suggestions);
-
-       // reset dialog and buttons into start condition
-       updateState(READY_TO_START);
 }
 
 
 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);
 
@@ -208,19 +153,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: src/frontends/xforms/FormSpellchecker.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/FormSpellchecker.h,v
retrieving revision 1.15
diff -u -r1.15 FormSpellchecker.h
--- src/frontends/xforms/FormSpellchecker.h     29 Nov 2002 12:47:33 -0000      1.15
+++ src/frontends/xforms/FormSpellchecker.h     17 Feb 2003 19:06:13 -0000
@@ -33,26 +33,14 @@
        virtual void apply() {}
        /// Build the dialog
        virtual void build();
-       ///
-       virtual void update();
+       /// not needed.
+       virtual void update() {}
 
        /// set suggestions and exit message
        virtual void partialUpdate(int);
 
        /// 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: src/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
--- src/frontends/xforms/forms/form_spellchecker.fd     26 Jan 2003 16:58:37 -0000     
 1.10
+++ src/frontends/xforms/forms/form_spellchecker.fd     17 Feb 2003 19:06:13 -0000
@@ -11,7 +11,7 @@
 Name: form_spellchecker
 Width: 385
 Height: 375
-Number of Objects: 13
+Number of Objects: 12
 
 --------------------
 class: FL_BOX
@@ -124,24 +124,6 @@
 --------------------
 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
-
---------------------
-class: FL_BUTTON
-type: NORMAL_BUTTON
 box: 280 195 100 25
 boxtype: FL_UP_BOX
 colors: FL_COL1 FL_COL1
@@ -185,7 +167,7 @@
 style: FL_NORMAL_STYLE
 size: FL_NORMAL_SIZE
 lcol: FL_BLACK
-label: Accept|#A
+label: Ignore All|#g
 shortcut: 
 resize: FL_RESIZE_X
 gravity: FL_NorthEast FL_NorthEast
Index: src/support/forkedcall.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/support/forkedcall.C,v
retrieving revision 1.11
diff -u -r1.11 forkedcall.C
--- src/support/forkedcall.C    27 Nov 2002 10:30:28 -0000      1.11
+++ src/support/forkedcall.C    17 Feb 2003 19:06:14 -0000
@@ -147,6 +147,24 @@
        return retval_;
 }
 
+
+bool ForkedProcess::running() const
+{
+       if (!pid())
+               return false;
+
+       // Un-UNIX like, but we don't have much use for
+       // knowing if a zombie exists, so just reap it first.
+       int waitstatus;
+       waitpid(pid(), &waitstatus, WNOHANG);
+
+       // 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: src/support/forkedcall.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/support/forkedcall.h,v
retrieving revision 1.7
diff -u -r1.7 forkedcall.h
--- src/support/forkedcall.h    31 Oct 2002 12:42:26 -0000      1.7
+++ src/support/forkedcall.h    17 Feb 2003 19:06:14 -0000
@@ -98,6 +98,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"
Index: src/support/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/support/ChangeLog,v
retrieving revision 1.149
diff -u -r1.149 ChangeLog
--- src/support/ChangeLog       4 Dec 2002 13:26:55 -0000       1.149
+++ src/support/ChangeLog       17 Feb 2003 19:08:40 -0000
@@ -1,3 +1,8 @@
+2003-02-17  John Levon  <[EMAIL PROTECTED]>
+
+       * forkedcall.h:
+       * forkedcall.C: add running()
+
 2002-12-04  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
 
        * filetools.C (getExtFromContents): remove detection of epsi

Reply via email to