On Sun, Feb 16, 2003 at 02:46:35AM +0000, John Levon wrote: > I'm still testing this, but it works for old pspell at least a little.
Here's another version with a couple of more fixes and improvements. That stupid 15 second timeout died, so now when the user has mis-configured their aspell, they'll see a message within 2 seconds, which is a lot more reasonable. There's still the bug I mentioned wrt completely-error-free document. I'll post the Qt side of things soon too john diff -u -r1.4 SpellBase.h --- SpellBase.h 1 Dec 2002 22:59:17 -0000 1.4 +++ SpellBase.h 16 Feb 2003 03:34:42 -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 03:34:43 -0000 @@ -9,35 +9,6 @@ #include <config.h> -#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" @@ -45,10 +16,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; @@ -60,9 +34,6 @@ namespace { -/// pid for the `ispell' process. -pid_t isp_pid = -1; - class LaunchIspell : public ForkedProcess { public: /// @@ -96,7 +67,7 @@ int LaunchIspell::generateChild() { - isp_pid = fork(); + pid_t isp_pid = fork(); if (isp_pid != 0) { // failed (-1) or parent process (>0) @@ -202,29 +173,24 @@ ISpell::ISpell(BufferParams const & params, string const & lang) : str(0) { + lyxerr[Debug::GUI] << "Created ispell" << endl; + static char o_buf[BUFSIZ]; // jc: it could be smaller 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 +198,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 +220,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 = 2; tv.tv_usec = 0; // Configure provides us with macros which are supposed to do @@ -272,50 +236,45 @@ // there is only one fd in infds. fgets(buf, 2048, in); - fputs("!\n", out); // Set terse mode (silently accept correct words) + // Set terse mode (silently accept correct words) + fputs("!\n", out); } 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_ = _("The spell process returned an error. Perhaps " + "it has been configured wrongly ?"); ::close(pipeout[0]); ::close(pipeout[1]); ::close(pipein[0]); ::close(pipein[1]); - isp_fd = -1; + child_->kill(); + child_.reset(0); } else { - // Select returned error - lyxerr << "Select on ispell returned error, what now?" << endl; + // select returned error + error_ = _("The spell process returned an error. Perhaps " + "it has been configured wrongly ?"); + child_->kill(); + child_.reset(0); } } ISpell::~ISpell() { - delete[] str; -} + lyxerr[Debug::GUI] << "Killing ispell" << endl; + 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 +288,7 @@ bool ISpell::alive() { - return isp_pid != -1; -} - - -void ISpell::cleanUp() -{ - ::fclose(out); + return child_.get() && child_->running(); } @@ -396,20 +349,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 @@ -428,7 +367,5 @@ string const ISpell::error() { - if (error_) - return error_; - return ""; + return error_; } 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 03:34:43 -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,16 @@ virtual string const error(); private: - /// - void setError(); - /// instream to communicate with ispell FILE * in; /// outstream to communicate with ispell FILE * out; /// spell error - char const * error_; + string 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 03:34:43 -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 03:34:44 -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 03:34:48 -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 could not be started.\n" + "Maybe it is mis-configured."); + + 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 03:34:49 -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 03:34:50 -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 03:34:50 -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 03:34:50 -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 03:34:51 -0000 @@ -143,6 +143,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: 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 03:34:51 -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"