]> git.lyx.org Git - lyx.git/blobdiff - src/spellchecker.C
remove more forms.h cruft
[lyx.git] / src / spellchecker.C
index b381cda727acf06b2f361c5619ac40c9183cc91c..34759911e9d3989df02401385a97f0c97463fd37 100644 (file)
@@ -19,7 +19,6 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <cstdlib>
-#include <cstring>
 #include <csignal>
 #include <sys/wait.h>
 #include <sys/types.h>
 #ifdef HAVE_SYS_SELECT_H
 # ifdef HAVE_STRINGS_H
    // <strings.h> is needed at least on AIX because FD_ZERO uses bzero().
-# include <strings.h> 
+   // 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 "buffer.h"
 #include "lyxrc.h"
 #include "BufferView.h"
+#include "LyXView.h" 
+#include "frontends/Dialogs.h" 
 #include "gettext.h"
 #include "lyx_gui_misc.h"
 #include "debug.h"
 #include "support/lstrings.h"
+#include "language.h"
 #include "encoding.h"
-
-//#define USE_PSPELL 1
+#include "support/lstrings.h"
 
 #ifdef USE_PSPELL
-
-#include <pspell/pspell.h>
-
+#define USE_ORIGINAL_MANAGER_FUNCS 1
+# include <pspell/pspell.h>
 #endif
 
 using std::reverse;
 using std::endl;
 
+namespace {
+
 // Spellchecker status
 enum {
        ISP_OK = 1,
@@ -81,19 +86,20 @@ enum {
        ISP_IGNORE
 };
 
-static bool RunSpellChecker(BufferView * bv);
+bool RunSpellChecker(BufferView * bv);
 
 #ifndef USE_PSPELL
 
-static FILE * in, * out;  /* streams to communicate with ispell */
+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;
 
-static int isp_fd;
+int isp_fd;
 
 #else
 
@@ -101,13 +107,14 @@ PspellManager * sc;
 
 #endif
 
-static FD_form_spell_options *fd_form_spell_options = 0;
+} // namespace anon
+
+
+// Non-static so that it can be redrawn if the xforms colors are re-mapped
 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
@@ -158,135 +165,16 @@ const char * isp_result::next_miss()
 
 #endif
 
+namespace {
 const char * spell_error;
 
-
-/***** Spellchecker options *****/
-
-// Rewritten to use ordinary LyX xforms loop and OK, Apply and Cancel set,
-// now also string. Amazing, eh? (Asger)
-
-// Set (sane) values in form to current spellchecker options
-void SpellOptionsUpdate() 
-{
-       // Alternate language
-       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());
-       }
-       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 {
-               fl_set_button(fd_form_spell_options->buflang, 1);
-               fl_set_button(fd_form_spell_options->altlang, 0);
-       }  
-
-       // Personal dictionary
-       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());
-       }
-       fl_set_button(fd_form_spell_options->perdict,
-                     lyxrc.isp_use_pers_dict ? 1:0);
-
-       // Escape chars
-       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());
-       }
-       fl_set_button(fd_form_spell_options->esc_chars,
-                     lyxrc.isp_use_esc_chars ? 1:0);
-
-       // Options
-       fl_set_button(fd_form_spell_options->compounds,
-                     lyxrc.isp_accept_compound ? 1 : 0);
-       fl_set_button(fd_form_spell_options->inpenc,
-                     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 = 
-               fl_get_button(fd_form_spell_options->altlang);
-       lyxrc.isp_use_pers_dict = 
-               fl_get_button(fd_form_spell_options->perdict);
-       lyxrc.isp_accept_compound = 
-               fl_get_button(fd_form_spell_options->compounds);
-       lyxrc.isp_use_esc_chars = 
-               fl_get_button(fd_form_spell_options->esc_chars);
-       lyxrc.isp_use_input_encoding = 
-               fl_get_button(fd_form_spell_options->inpenc);
-
-       // Update strings with data from input fields
-       lyxrc.isp_alt_lang = 
-               fl_get_input(fd_form_spell_options->altlang_input);
-       lyxrc.isp_pers_dict = 
-               fl_get_input(fd_form_spell_options->perdict_input);
-       lyxrc.isp_esc_chars = 
-               fl_get_input(fd_form_spell_options->esc_chars_input);
-
-       // Update form
-       SpellOptionsUpdate();
-}
-
-
-void SpellOptionsCancelCB(FL_OBJECT *, long)
-{
-       fl_hide_form(fd_form_spell_options->form_spell_options);
-}
-
-
-void SpellOptionsOKCB(FL_OBJECT * ob, long data)
-{
-       SpellOptionsApplyCB(ob, data);
-       SpellOptionsCancelCB(ob, data);
-}
-
-
-// Show spellchecker options form
-void SpellCheckerOptions()
-{
-       // Create form if nescessary
-       if (fd_form_spell_options ==  0) {
-               fd_form_spell_options = create_form_form_spell_options();
-               // Make sure pressing the close box does not kill LyX. (RvdK)
-               fl_set_form_atclose(fd_form_spell_options->form_spell_options, 
-                                   CancelCloseBoxCB, 0);
-       }
-
-       // Update form to current options
-       SpellOptionsUpdate();
-
-       // Focus in alternate language field
-       fl_set_focus_object(fd_form_spell_options->form_spell_options,
-                           fd_form_spell_options->altlang_input);
-
-       // Show form
-       if (fd_form_spell_options->form_spell_options->visible) {
-               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,
-                            _("Spellchecker Options"));
-       }
-}
-
 #ifndef USE_PSPELL
 
 /***** Spellchecker *****/
 
 // Could also use a clean up. (Asger Alstrup)
 
-static
 void init_spell_checker(BufferParams const & params, string const & lang)
 {
        static char o_buf[BUFSIZ];  // jc: it could be smaller
@@ -296,7 +184,7 @@ void init_spell_checker(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;
                goto END;
        }
@@ -319,13 +207,13 @@ void init_spell_checker(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;
                goto END;
        }
        
-       if(isp_pid == 0) {        
+       if (isp_pid == 0) {        
                /* child process */
                dup2(pipein[0], STDIN_FILENO);
                dup2(pipeout[1], STDOUT_FILENO);
@@ -390,7 +278,7 @@ void init_spell_checker(BufferParams const & params, string const & lang)
                if (lyxrc.isp_use_input_encoding &&
                    params.inputenc != "default") {
                        string enc = (params.inputenc == "auto")
-                               ? params.language_info->encoding()->LatexName()
+                               ? params.language->encoding()->LatexName()
                                : params.inputenc;
                        string::size_type n = enc.length();
                        tmp = new char[3];
@@ -472,34 +360,34 @@ void init_spell_checker(BufferParams const & params, string const & lang)
                        "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.";
+                       "dictionary in the spellchecker preferences.";
        } else {
                spell_error = 0;
        }
 }
 
-static
+
 bool sc_still_alive() {
        return isp_pid != -1;
 }
 
-static
+
 void sc_clean_up_after_error() 
 {
-       fclose(out);
+       ::fclose(out);
 }
 
+
 // Send word to ispell and get reply
-static
 isp_result * sc_check_word(string const & word)
 {
        //Please rewrite to use string.
 
-       fputs(word.c_str(), out);
-       fputc('\n', out);
+       ::fputs(word.c_str(), out);
+       ::fputc('\n', out);
   
        char buf[1024];
-       fgets(buf, 1024, in); 
+       ::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 */
@@ -545,7 +433,7 @@ isp_result * sc_check_word(string const & word)
 }
 
 
-static inline 
+inline 
 void close_spell_checker()
 {
         // Note: If you decide to optimize this out when it is not 
@@ -560,31 +448,32 @@ void close_spell_checker()
 }
 
 
-static inline 
+inline 
 void sc_insert_word(string const & word)
 {
-       fputc('*', out); // Insert word in personal dictionary
-       fputs(word.c_str(), out);
-       fputc('\n', out);
+       ::fputc('*', out); // Insert word in personal dictionary
+       ::fputs(word.c_str(), out);
+       ::fputc('\n', out);
 }
 
 
-static inline 
+inline 
 void sc_accept_word(string const & word) 
 {
-       fputc('@', out); // Accept in this session
-       fputs(word.c_str(), out);
-       fputc('\n', out);
+       ::fputc('@', out); // Accept in this session
+       ::fputs(word.c_str(), out);
+       ::fputc('\n', out);
 }
 
-static inline
+
+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);
+        if (actual_spell_checker == ASC_ASPELL) {
+                ::fputs("$$ra ", out);
+                ::fputs(mis.c_str(), out);
+                ::fputc(',', out);
+                ::fputs(cor.c_str(), out);
+                ::fputc('\n', out);
         }
 }
 
@@ -592,10 +481,12 @@ void sc_store_replacement(string const & mis, string const & cor) {
 
 PspellCanHaveError * spell_error_object;
 
-static
-void init_spell_checker(BufferParams const &, string const & /* lang */)
+void init_spell_checker(BufferParams const &, string const & lang)
 {
        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);
@@ -606,12 +497,12 @@ void init_spell_checker(BufferParams const &, string const & /* lang */)
        }
 }
 
-static 
+
 bool sc_still_alive() {
        return true;
 }
 
-static
+
 void sc_clean_up_after_error() 
 {
        delete_pspell_can_have_error(spell_error_object);
@@ -619,20 +510,22 @@ void sc_clean_up_after_error()
 
 
 
-// Send word to ispell and get reply
-static
+// Send word to pspell and get reply
 isp_result * sc_check_word(string const & word)
 {
        isp_result * result = new isp_result;
+#ifdef WITH_WARNINGS
+#warning Why isnt word_ok a bool? (Lgb)
+#endif
        int word_ok = pspell_manager_check(sc, word.c_str());
-       Assert(word_ok != -1);
+       lyx::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);
+               lyx::Assert(sugs != 0);
                result->els = pspell_word_list_elements(sugs);
                if (pspell_word_list_empty(sugs)) 
                        result->flag = ISP_UNKNOWN;
@@ -643,28 +536,28 @@ isp_result * sc_check_word(string const & word)
 }
 
 
-static inline 
+inline 
 void close_spell_checker()
 {
        pspell_manager_save_all_word_lists(sc);
 }
 
 
-static inline 
+inline 
 void sc_insert_word(string const & word)
 {
        pspell_manager_add_to_personal(sc, word.c_str());
 }
 
 
-static inline 
+inline 
 void sc_accept_word(string const & word) 
 {
        pspell_manager_add_to_session(sc, word.c_str());
 }
 
 
-static inline 
+inline 
 void sc_store_replacement(string const & mis, string const & cor)
 {
        pspell_manager_store_replacement(sc, mis.c_str(), cor.c_str());
@@ -672,6 +565,9 @@ void sc_store_replacement(string const & mis, string const & cor)
 
 #endif
 
+} // namespace anon
+
+
 void ShowSpellChecker(BufferView * bv)
 {
        FL_OBJECT * obj;
@@ -700,7 +596,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); 
@@ -721,12 +617,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){
-                       SpellCheckerOptions();
+               if (obj == fd_form_spell_check->options) {
+                       bv->owner()->getDialogs()->showSpellcheckerPreferences();
                }
-               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);
@@ -787,16 +683,29 @@ void ShowSpellChecker(BufferView * bv)
 }
 
 
-// Perform an ispell session
-static
+// Perform a spell session
+namespace {
+
 bool RunSpellChecker(BufferView * bv)
 {
        isp_result * result;
        int newvalue;
        FL_OBJECT * obj;
 
-       string tmp = (lyxrc.isp_use_alt_lang) ? lyxrc.isp_alt_lang : bv->buffer()->GetLanguage();
-       bool rtl = tmp == "hebrew" || tmp == "arabic";
+#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;
@@ -819,7 +728,7 @@ bool RunSpellChecker(BufferView * bv)
                
                // 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);
                }
@@ -925,7 +834,7 @@ bool RunSpellChecker(BufferView * bv)
                }
        }
    
-       if(sc_still_alive()) {
+       if (sc_still_alive()) {
                close_spell_checker();
                string word_msg(tostr(word_count));
                if (word_count != 1) {
@@ -944,11 +853,14 @@ bool RunSpellChecker(BufferView * bv)
        }
 }
 
+} // namespace anon
 
-#ifndef USE_PSPELL
-
+#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;
@@ -956,14 +868,8 @@ void sigchldhandler(pid_t pid, int * status)
                                                               to nonblocking so we can 
                                                               continue */
                }
+#endif
        sigchldchecker(pid, status);
 }
 
-#else
-
-void sigchldhandler(pid_t, int *)
-{ 
-       // do nothing
-}
 
-#endif