X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fspellchecker.C;h=609aa93502e7406cf83ca63ca8df60e15f60a9ec;hb=c90c5e6386ce69c34c99b3594d6fa452e6a13161;hp=be3479aab617e52d52a58fb2f7b17c74c0c4c861;hpb=c52895023e231587208b5c9257ae7825dc493ef0;p=lyx.git diff --git a/src/spellchecker.C b/src/spellchecker.C index be3479aab6..609aa93502 100644 --- a/src/spellchecker.C +++ b/src/spellchecker.C @@ -12,6 +12,10 @@ #include +#ifdef __GNUG__ +#pragma implementation +#endif + #include #include #include @@ -34,9 +38,18 @@ #endif #ifdef HAVE_SYS_SELECT_H +# ifdef HAVE_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 +# endif +# endif #include #endif +#include + #include "LString.h" #include "sp_form.h" #include "spellchecker.h" @@ -48,8 +61,18 @@ #include "lyx_gui_misc.h" #include "debug.h" #include "support/lstrings.h" +#include "language.h" +#include "encoding.h" +#include "support/lstrings.h" + +#ifdef USE_PSPELL +# include +#endif + +using std::reverse; +using std::endl; -extern LyXRC * lyxrc; +namespace { // Spellchecker status enum { @@ -61,42 +84,88 @@ enum { ISP_IGNORE }; -static bool RunSpellChecker(BufferView * bv); +bool RunSpellChecker(BufferView * bv); -static FILE *in, *out; /* streams to communicate with ispell */ +#ifndef USE_PSPELL + +FILE * in; +FILE * out; /* streams to communicate with ispell */ pid_t isp_pid = -1; // pid for the `ispell' process. Also used (RO) in // lyx_cb.C // the true spell checker program being used enum ActualSpellChecker {ASC_ISPELL, ASC_ASPELL}; -static ActualSpellChecker actual_spell_checker; +ActualSpellChecker actual_spell_checker; + +int isp_fd; + +#else + +PspellManager * sc; + +#endif + +} // namespace anon -static int isp_fd; -static FD_form_spell_options *fd_form_spell_options = 0; +// Non-static so that it can be redrawn if the xforms colors are re-mapped +FD_form_spell_options *fd_form_spell_options = 0; FD_form_spell_check *fd_form_spell_check = 0; -//void sigchldhandler(int sig); void sigchldhandler(pid_t pid, int *status); -//extern void sigchldchecker(int sig); extern void sigchldchecker(pid_t pid, int *status); +#ifndef USE_PSPELL + +struct isp_result { + int flag; + char * str; + char * b; + char * e; + const char * next_miss(); + isp_result() { + flag = ISP_UNKNOWN; + str = 0; + } + ~isp_result() { + delete[] str; + } +}; + +const char * isp_result::next_miss() { + if (str == 0 || *(e+1) == '\0') return 0; + b = e + 2; + e = strpbrk(b, ",\n"); + *e = '\0'; + return b; +} + +#else + struct isp_result { int flag; - int count; - string str; - char ** misses; + PspellStringEmulation * els; + + const char * next_miss(); isp_result() { flag = ISP_UNKNOWN; - count = 0; - misses = static_cast(0); + els = 0; } ~isp_result() { - delete[] misses; + delete_pspell_string_emulation(els); } }; +const char * isp_result::next_miss() +{ + return pspell_string_emulation_next(els); +} + +#endif + +const char * spell_error; + /***** Spellchecker options *****/ @@ -107,13 +176,13 @@ struct isp_result { void SpellOptionsUpdate() { // Alternate language - if (lyxrc->isp_alt_lang.empty()) { - lyxrc->isp_use_alt_lang = false; + if (lyxrc.isp_alt_lang.empty()) { + lyxrc.isp_use_alt_lang = false; } else { fl_set_input(fd_form_spell_options->altlang_input, - lyxrc->isp_alt_lang.c_str()); + lyxrc.isp_alt_lang.c_str()); } - if (lyxrc->isp_use_alt_lang) { + if (lyxrc.isp_use_alt_lang) { fl_set_button(fd_form_spell_options->buflang, 0); fl_set_button(fd_form_spell_options->altlang, 1); } else { @@ -122,53 +191,53 @@ void SpellOptionsUpdate() } // Personal dictionary - if (lyxrc->isp_pers_dict.empty()) { - lyxrc->isp_use_pers_dict = false; + if (lyxrc.isp_pers_dict.empty()) { + lyxrc.isp_use_pers_dict = false; } else { fl_set_input(fd_form_spell_options->perdict_input, - lyxrc->isp_pers_dict.c_str()); + lyxrc.isp_pers_dict.c_str()); } fl_set_button(fd_form_spell_options->perdict, - lyxrc->isp_use_pers_dict ? 1:0); + lyxrc.isp_use_pers_dict ? 1:0); // Escape chars - if (lyxrc->isp_esc_chars.empty()) { - lyxrc->isp_use_esc_chars = false; + if (lyxrc.isp_esc_chars.empty()) { + lyxrc.isp_use_esc_chars = false; } else { fl_set_input(fd_form_spell_options->esc_chars_input, - lyxrc->isp_esc_chars.c_str()); + lyxrc.isp_esc_chars.c_str()); } fl_set_button(fd_form_spell_options->esc_chars, - lyxrc->isp_use_esc_chars ? 1:0); + lyxrc.isp_use_esc_chars ? 1:0); // Options fl_set_button(fd_form_spell_options->compounds, - lyxrc->isp_accept_compound ? 1 : 0); + lyxrc.isp_accept_compound ? 1 : 0); fl_set_button(fd_form_spell_options->inpenc, - lyxrc->isp_use_input_encoding ? 1 : 0); + lyxrc.isp_use_input_encoding ? 1 : 0); } // Update spellchecker options void SpellOptionsApplyCB(FL_OBJECT *, long) { // Build new status from form data - lyxrc->isp_use_alt_lang = + lyxrc.isp_use_alt_lang = fl_get_button(fd_form_spell_options->altlang); - lyxrc->isp_use_pers_dict = + lyxrc.isp_use_pers_dict = fl_get_button(fd_form_spell_options->perdict); - lyxrc->isp_accept_compound = + lyxrc.isp_accept_compound = fl_get_button(fd_form_spell_options->compounds); - lyxrc->isp_use_esc_chars = + lyxrc.isp_use_esc_chars = fl_get_button(fd_form_spell_options->esc_chars); - lyxrc->isp_use_input_encoding = + lyxrc.isp_use_input_encoding = fl_get_button(fd_form_spell_options->inpenc); // Update strings with data from input fields - lyxrc->isp_alt_lang = + lyxrc.isp_alt_lang = fl_get_input(fd_form_spell_options->altlang_input); - lyxrc->isp_pers_dict = + lyxrc.isp_pers_dict = fl_get_input(fd_form_spell_options->perdict_input); - lyxrc->isp_esc_chars = + lyxrc.isp_esc_chars = fl_get_input(fd_form_spell_options->esc_chars_input); // Update form @@ -212,18 +281,20 @@ void SpellCheckerOptions() fl_raise_form(fd_form_spell_options->form_spell_options); } else { fl_show_form(fd_form_spell_options->form_spell_options, - FL_PLACE_MOUSE, FL_FULLBORDER, + FL_PLACE_MOUSE | FL_FREE_SIZE, FL_TRANSIENT, _("Spellchecker Options")); } } +namespace { + +#ifndef USE_PSPELL /***** Spellchecker *****/ // Could also use a clean up. (Asger Alstrup) -static -void create_ispell_pipe(BufferParams const & params, string const & lang) +void init_spell_checker(BufferParams const & params, string const & lang) { static char o_buf[BUFSIZ]; // jc: it could be smaller int pipein[2], pipeout[2]; @@ -232,21 +303,21 @@ void create_ispell_pipe(BufferParams const & params, string const & lang) isp_pid = -1; - if(pipe(pipein) == -1 || pipe(pipeout) == -1) { + if (pipe(pipein) == -1 || pipe(pipeout) == -1) { lyxerr << "LyX: Can't create pipe for spellchecker!" << endl; - return; + goto END; } if ((out = fdopen(pipein[1], "w")) == 0) { lyxerr << "LyX: Can't create stream for pipe for spellchecker!" << endl; - return; + goto END; } if ((in = fdopen(pipeout[0], "r")) == 0) { lyxerr <<"LyX: Can't create stream for pipe for spellchecker!" << endl; - return; + goto END; } setvbuf(out, o_buf, _IOLBF, BUFSIZ); @@ -255,13 +326,13 @@ void create_ispell_pipe(BufferParams const & params, string const & lang) isp_pid = fork(); - if(isp_pid == -1) { + if (isp_pid == -1) { lyxerr << "LyX: Can't create child process for spellchecker!" << endl; - return; + goto END; } - - if(isp_pid == 0) { + + if (isp_pid == 0) { /* child process */ dup2(pipein[0], STDIN_FILENO); dup2(pipeout[1], STDOUT_FILENO); @@ -271,9 +342,9 @@ void create_ispell_pipe(BufferParams const & params, string const & lang) close(pipeout[1]); argc = 0; - char * tmp = new char[lyxrc->isp_command.length() + 1]; - lyxrc->isp_command.copy(tmp, lyxrc->isp_command.length()); - tmp[lyxrc->isp_command.length()] = '\0'; + char * tmp = new char[lyxrc.isp_command.length() + 1]; + lyxrc.isp_command.copy(tmp, lyxrc.isp_command.length()); + tmp[lyxrc.isp_command.length()] = '\0'; argv[argc++] = tmp; tmp = new char[3]; string("-a").copy(tmp, 2); tmp[2] = '\0'; // pipe mode @@ -288,7 +359,7 @@ void create_ispell_pipe(BufferParams const & params, string const & lang) argv[argc++] = tmp; } - if (lyxrc->isp_accept_compound) { + if (lyxrc.isp_accept_compound) { // Consider run-together words as legal compounds tmp = new char[3]; string("-C").copy(tmp, 2); tmp[2] = '\0'; @@ -300,43 +371,47 @@ void create_ispell_pipe(BufferParams const & params, string const & lang) string("-B").copy(tmp, 2); tmp[2] = '\0'; argv[argc++] = tmp; } - if (lyxrc->isp_use_esc_chars) { + if (lyxrc.isp_use_esc_chars) { // Specify additional characters that // can be part of a word tmp = new char[3]; string("-w").copy(tmp, 2); tmp[2] = '\0'; argv[argc++] = tmp; // Put the escape chars in ""s - string tms = "\"" + lyxrc->isp_esc_chars + "\""; + string tms = "\"" + lyxrc.isp_esc_chars + "\""; tmp = new char[tms.length() + 1]; tms.copy(tmp, tms.length()); tmp[tms.length()] = '\0'; argv[argc++] = tmp; } - if (lyxrc->isp_use_pers_dict) { + if (lyxrc.isp_use_pers_dict) { // Specify an alternate personal dictionary tmp = new char[3]; string("-p").copy(tmp, 2); tmp[2]= '\0'; argv[argc++] = tmp; - tmp = new char[lyxrc->isp_pers_dict.length() + 1]; - lyxrc->isp_pers_dict.copy(tmp, lyxrc->isp_pers_dict.length()); - tmp[lyxrc->isp_pers_dict.length()] = '\0'; + tmp = new char[lyxrc.isp_pers_dict.length() + 1]; + lyxrc.isp_pers_dict.copy(tmp, lyxrc.isp_pers_dict.length()); + tmp[lyxrc.isp_pers_dict.length()] = '\0'; argv[argc++] = tmp; } - if (lyxrc->isp_use_input_encoding && - params.inputenc != "default") { + if (lyxrc.isp_use_input_encoding && + params.inputenc != "default") { + string enc = (params.inputenc == "auto") + ? params.language->encoding()->LatexName() + : params.inputenc; + string::size_type n = enc.length(); tmp = new char[3]; string("-T").copy(tmp, 2); tmp[2] = '\0'; argv[argc++] = tmp; // Input encoding - tmp = new char[params.inputenc.length() + 1]; - params.inputenc.copy(tmp, params.inputenc.length()); - tmp[params.inputenc.length()] = '\0'; + tmp = new char[n + 1]; + enc.copy(tmp, n); + tmp[n] = '\0'; argv[argc++] = tmp; } argv[argc++] = 0; - execvp("ispell", const_cast(argv)); + execvp(argv[0], const_cast(argv)); // free the memory used by string::copy in the // setup of argv @@ -346,7 +421,7 @@ void create_ispell_pipe(BufferParams const & params, string const & lang) lyxerr << "LyX: Failed to start ispell!" << endl; _exit(0); } - + { /* 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 @@ -379,6 +454,9 @@ void create_ispell_pipe(BufferParams const & params, string const & lang) actual_spell_checker = ASC_ASPELL; else actual_spell_checker = ASC_ISPELL; + + fputs("!\n", out); // Set terse mode (silently accept correct words) + } else if (retval == 0) { // timeout. Give nice message to user. @@ -392,28 +470,49 @@ void create_ispell_pipe(BufferParams const & params, string const & lang) // Select returned error lyxerr << "Select on ispell returned error, what now?" << endl; } + } + END: + if (isp_pid == -1) { + spell_error = + "\n\n" + "The ispell-process has died for some reason. *One* possible reason\n" + "could be that you do not have a dictionary file\n" + "for the language of this document installed.\n" + "Check /usr/lib/ispell or set another\n" + "dictionary in the Spellchecker Options menu."; + } else { + spell_error = 0; + } +} + + +bool sc_still_alive() { + return isp_pid != -1; +} + + +void sc_clean_up_after_error() +{ + ::fclose(out); } // Send word to ispell and get reply -static -isp_result *ispell_check_word(char *word) +isp_result * sc_check_word(string const & word) { //Please rewrite to use string. - isp_result *result; - char buf[1024], *p; - int count, i; - fputs(word, out); - fputc('\n', out); + ::fputs(word.c_str(), out); + ::fputc('\n', out); - fgets(buf, 1024, in); + char buf[1024]; + ::fgets(buf, 1024, in); /* I think we have to check if ispell is still alive here because the signal-handler could have disabled blocking on the fd */ - if (isp_pid == -1) return 0; + if (!sc_still_alive()) return 0; - result = new isp_result; + isp_result * result = new isp_result; switch (*buf) { case '*': // Word found @@ -435,25 +534,10 @@ isp_result *ispell_check_word(char *word) case '&': // Not found, but we have near misses { result->flag = ISP_MISSED; - result->str = buf; - // nb is leaked! where should it be freed? I have to - // admit I do not understand the intent of the code :( - // (JMarc) - char * nb = new char[result->str.length() + 1]; - result->str.copy(nb, result->str.length()); - nb[result->str.length()]= '\0'; - p = strpbrk(nb+2, " "); - sscanf(p, "%d", &count); // Get near misses count - result->count = count; - if (count) result->misses = new char*[count]; - p = strpbrk(nb, ":"); - p += 2; - for (i = 0; i < count; ++i) { - result->misses[i] = p; - p = strpbrk(p, ",\n"); - *p = 0; - p += 2; - } + char * p = strpbrk(buf, ":"); + result->str = new char[strlen(p) + 1]; + result->e = result->str; + strcpy(result->str, p); break; } default: // This shouldn't happend, but you know Murphy @@ -468,8 +552,8 @@ isp_result *ispell_check_word(char *word) } -static -inline void ispell_terminate() +inline +void close_spell_checker() { // Note: If you decide to optimize this out when it is not // needed please note that when Aspell is used this command @@ -483,42 +567,124 @@ inline void ispell_terminate() } -static -inline void ispell_terse_mode() +inline +void sc_insert_word(string const & word) +{ + ::fputc('*', out); // Insert word in personal dictionary + ::fputs(word.c_str(), out); + ::fputc('\n', out); +} + + +inline +void sc_accept_word(string const & word) { - fputs("!\n", out); // Set terse mode (silently accept correct words) + ::fputc('@', out); // Accept in this session + ::fputs(word.c_str(), out); + ::fputc('\n', out); } -static -inline void ispell_insert_word(char const *word) +inline +void sc_store_replacement(string const & mis, string const & cor) { + if (actual_spell_checker == ASC_ASPELL) { + ::fputs("$$ra ", out); + ::fputs(mis.c_str(), out); + ::fputc(',', out); + ::fputs(cor.c_str(), out); + ::fputc('\n', out); + } +} + +#else + +PspellCanHaveError * spell_error_object; + +void init_spell_checker(BufferParams const &, string const & lang) { - fputc('*', out); // Insert word in personal dictionary - fputs(word, out); - fputc('\n', out); + PspellConfig * config = new_pspell_config(); + string code; + split(lang, code, '_'); + config->replace("language-tag", code.c_str()); + spell_error_object = new_pspell_manager(config); + if (pspell_error_number(spell_error_object) != 0) { + spell_error = pspell_error_message(spell_error_object); + } else { + spell_error = 0; + sc = to_pspell_manager(spell_error_object); + spell_error_object = 0; + } } -static -inline void ispell_accept_word(char const *word) +bool sc_still_alive() { + return true; +} + + +void sc_clean_up_after_error() { - fputc('@', out); // Accept in this session - fputs(word, out); - fputc('\n', out); + delete_pspell_can_have_error(spell_error_object); } -static -inline void ispell_store_replacement(char const *mis, string const & cor) { - if(actual_spell_checker == ASC_ASPELL) { - fputs("$$ra ", out); - fputs(mis, out); - fputc(',', out); - fputs(cor.c_str(), out); - fputc('\n', out); - } + + +// Send word to pspell and get reply +isp_result * sc_check_word(string const & word) +{ + isp_result * result = new isp_result; +#warning Why isnt word_ok a bool? (Lgb) + int word_ok = pspell_manager_check(sc, word.c_str()); + Assert(word_ok != -1); + + if (word_ok) { + result->flag = ISP_OK; + } else { + PspellWordList const * sugs = + pspell_manager_suggest(sc, word.c_str()); + Assert(sugs != 0); + result->els = pspell_word_list_elements(sugs); + if (pspell_word_list_empty(sugs)) + result->flag = ISP_UNKNOWN; + else + result->flag = ISP_MISSED; + } + return result; +} + + +inline +void close_spell_checker() +{ + pspell_manager_save_all_word_lists(sc); +} + + +inline +void sc_insert_word(string const & word) +{ + pspell_manager_add_to_personal(sc, word.c_str()); +} + + +inline +void sc_accept_word(string const & word) +{ + pspell_manager_add_to_session(sc, word.c_str()); } +inline +void sc_store_replacement(string const & mis, string const & cor) +{ + pspell_manager_store_replacement(sc, mis.c_str(), cor.c_str()); +} + +#endif + +} // namespace anon + + void ShowSpellChecker(BufferView * bv) { FL_OBJECT * obj; @@ -531,7 +697,8 @@ void ShowSpellChecker(BufferView * bv) if (fd_form_spell_check == 0) { fd_form_spell_check = create_form_form_spell_check(); // Make sure pressing the close box does not kill LyX. (RvdK) - fl_set_form_atclose(fd_form_spell_check->form_spell_check, IgnoreCloseBoxCB, 0); + fl_set_form_atclose(fd_form_spell_check->form_spell_check, + CancelCloseBoxCB, 0); } // Clear form @@ -546,7 +713,7 @@ void ShowSpellChecker(BufferView * bv) fl_raise_form(fd_form_spell_check->form_spell_check); } else { fl_show_form(fd_form_spell_check->form_spell_check, - FL_PLACE_MOUSE, FL_FULLBORDER, + FL_PLACE_MOUSE | FL_FREE_SIZE, FL_TRANSIENT, _("Spellchecker")); } fl_deactivate_object(fd_form_spell_check->slider); @@ -567,12 +734,12 @@ void ShowSpellChecker(BufferView * bv) fl_set_object_lcol(fd_form_spell_check->input, FL_INACTIVE); fl_set_object_lcol(fd_form_spell_check->browser, FL_INACTIVE); - while (true){ + while (true) { obj = fl_do_forms(); - if (obj == fd_form_spell_check->options){ + if (obj == fd_form_spell_check->options) { SpellCheckerOptions(); } - if (obj == fd_form_spell_check->start){ + if (obj == fd_form_spell_check->start) { // activate insert, accept, and stop fl_activate_object(fd_form_spell_check->insert); fl_activate_object(fd_form_spell_check->accept); @@ -633,91 +800,112 @@ void ShowSpellChecker(BufferView * bv) } -// Perform an ispell session -static +// Perform a spell session +namespace { + bool RunSpellChecker(BufferView * bv) { isp_result * result; - int i, newvalue; + int newvalue; FL_OBJECT * obj; - string tmp = (lyxrc->isp_use_alt_lang) ? lyxrc->isp_alt_lang : bv->buffer()->GetLanguage(); +#ifndef NEW_INSETS + // Open all floats + bv->allFloats(1, 0); + bv->allFloats(1, 1); +#endif + +#ifdef USE_PSPELL + string tmp = (lyxrc.isp_use_alt_lang) ? + lyxrc.isp_alt_lang : bv->buffer()->params.language->code(); +#else + string tmp = (lyxrc.isp_use_alt_lang) ? + lyxrc.isp_alt_lang : bv->buffer()->params.language->lang(); +#endif + bool rtl = false; + if (lyxrc.isp_use_alt_lang) { + Language const * lang = languages.getLanguage(tmp); + if (lang) + rtl = lang->RightToLeft(); + } else + rtl = bv->buffer()->params.language->RightToLeft(); int oldval = 0; /* used for updating slider only when needed */ float newval = 0.0; /* create ispell process */ - create_ispell_pipe(bv->buffer()->params, tmp); + init_spell_checker(bv->buffer()->params, tmp); - if (isp_pid == -1) { - fl_show_message( - _("\n\n" - "The ispell-process has died for some reason. *One* possible reason\n" - "could be that you do not have a dictionary file\n" - "for the language of this document installed.\n" - "Check /usr/lib/ispell or set another\n" - "dictionary in the Spellchecker Options menu."), "", ""); - fclose(out); - return true; + if (spell_error != 0) { + fl_show_message(_(spell_error), "", ""); + sc_clean_up_after_error(); + return false; } - // Put ispell in terse mode to improve speed - ispell_terse_mode(); - unsigned int word_count = 0; + while (true) { - char * word = bv->nextWord(newval); - if (word == 0) break; + string const word = bv->nextWord(newval); + if (word.empty()) break; ++word_count; // Update slider if and only if value has changed newvalue = int(100.0*newval); - if(newvalue!= oldval) { + if (newvalue!= oldval) { oldval = newvalue; fl_set_slider_value(fd_form_spell_check->slider, oldval); } - result = ispell_check_word(word); - if (isp_pid == -1) { - delete[] word; - break; + if (word_count%1000 == 0) { + obj = fl_check_forms(); + if (obj == fd_form_spell_check->stop) { + close_spell_checker(); + return true; + } + if (obj == fd_form_spell_check->done) { + close_spell_checker(); + return false; + } } - obj = fl_check_forms(); - if (obj == fd_form_spell_check->stop) { - delete result; - delete[] word; - ispell_terminate(); - return true; - } - if (obj == fd_form_spell_check->done) { + result = sc_check_word(word); + if (!sc_still_alive()) { delete result; - delete[] word; - ispell_terminate(); - return false; + break; } - + switch (result->flag) { case ISP_UNKNOWN: case ISP_MISSED: { bv->selectLastWord(); - fl_set_object_label(fd_form_spell_check->text, word); - fl_set_input(fd_form_spell_check->input, word); + if (rtl) { + string tmp = word; + reverse(tmp.begin(),tmp.end()); + fl_set_object_label(fd_form_spell_check->text, tmp.c_str()); + } else + fl_set_object_label(fd_form_spell_check->text, word.c_str()); + fl_set_input(fd_form_spell_check->input, word.c_str()); fl_clear_browser(fd_form_spell_check->browser); - for (i = 0; i < result->count; ++i) { - fl_add_browser_line(fd_form_spell_check->browser, result->misses[i]); + const char * w; + while ((w = result->next_miss()) != 0) { + if (rtl) { + string tmp = w; + reverse(tmp.begin(),tmp.end()); + fl_add_browser_line(fd_form_spell_check->browser, tmp.c_str()); + } else + fl_add_browser_line(fd_form_spell_check->browser, w); } int clickline = -1; while (true) { obj = fl_do_forms(); if (obj == fd_form_spell_check->insert) { - ispell_insert_word(word); + sc_insert_word(word); break; } if (obj == fd_form_spell_check->accept) { - ispell_accept_word(word); + sc_accept_word(word); break; } if (obj == fd_form_spell_check->ignore) { @@ -725,7 +913,7 @@ bool RunSpellChecker(BufferView * bv) } if (obj == fd_form_spell_check->replace || obj == fd_form_spell_check->input) { - ispell_store_replacement(word, fl_get_input(fd_form_spell_check->input)); + sc_store_replacement(word, fl_get_input(fd_form_spell_check->input)); bv->replaceWord(fl_get_input(fd_form_spell_check->input)); break; } @@ -734,41 +922,44 @@ bool RunSpellChecker(BufferView * bv) // sent to lyx@via by Mark Burton if (clickline == fl_get_browser(fd_form_spell_check->browser)) { - ispell_store_replacement(word, fl_get_input(fd_form_spell_check->input)); + sc_store_replacement(word, fl_get_input(fd_form_spell_check->input)); bv->replaceWord(fl_get_input(fd_form_spell_check->input)); break; } clickline = fl_get_browser(fd_form_spell_check->browser); - fl_set_input(fd_form_spell_check->input, - fl_get_browser_line(fd_form_spell_check->browser, - fl_get_browser(fd_form_spell_check->browser))); - + /// Why not use + /// fl_set_input(fd_form_spell_check->input, result->misses[clickline-1]); ? + if (rtl) { + string tmp = fl_get_browser_line(fd_form_spell_check->browser, + clickline); + reverse(tmp.begin(),tmp.end()); + fl_set_input(fd_form_spell_check->input, tmp.c_str()); + } else + fl_set_input(fd_form_spell_check->input, + fl_get_browser_line(fd_form_spell_check->browser, + clickline)); } if (obj == fd_form_spell_check->stop) { delete result; - delete[] word; - ispell_terminate(); + close_spell_checker(); return true; } if (obj == fd_form_spell_check->done) { delete result; - delete[] word; - ispell_terminate(); + close_spell_checker(); return false; } } } default: delete result; - delete[] word; } } - if(isp_pid!= -1) { - ispell_terminate(); - string word_msg; - word_msg += tostr(word_count); + if (sc_still_alive()) { + close_spell_checker(); + string word_msg(tostr(word_count)); if (word_count != 1) { word_msg += _(" words checked."); } else { @@ -778,16 +969,21 @@ bool RunSpellChecker(BufferView * bv) word_msg.c_str()); return false; } else { - fl_show_message(_("The ispell-process has died for some reason.\n" + fl_show_message(_("The spell checker has died for some reason.\n" "Maybe it has been killed."), "", ""); - fclose(out); + sc_clean_up_after_error(); return true; } } +} // namespace anon +#ifdef WITH_WARNINGS +#warning should go somewhere more sensible +#endif void sigchldhandler(pid_t pid, int * status) -{ +{ +#ifndef USE_PSPELL if (isp_pid > 0) if (pid == isp_pid) { isp_pid= -1; @@ -795,5 +991,8 @@ void sigchldhandler(pid_t pid, int * status) to nonblocking so we can continue */ } +#endif sigchldchecker(pid, status); } + +