#include "main.h" #define GSE_BTN_REPLACE 1 #define GSE_BTN_IGNORE 2 #define GSE_BTN_IGNORE_ALL 3 #define GSE_BTN_ADD 4 #define GSE_BTN_ADD_CASE 5 #define ISP_BUF_LEN 1024 #define BUF_LEN 255 GtkWidget *clist_results, *entry_line, *entry_word, *entry_custom; gint ispell_fd_in, ispell_fd_out; FILE *ispell_input, *ispell_output; spell_word *glob_word = NULL; /* Creates pipes to stdin/out and exectutes the spell command with arguments */ int gse_spell_init_aspell (gchar *lang) { int stdin_pipe[2], stdout_pipe[2], i = 0; gchar *arg, **argv; static gchar o_buf[ISP_BUF_LEN]; /* Create the two pipes to use as stdin and stdout */ if ((pipe (stdin_pipe) == -1) || (pipe (stdout_pipe) == -1)) { perror ("pipe"); return 1; } ispell_fd_out = stdout_pipe[0]; ispell_fd_in = stdin_pipe[1]; if ((ispell_input = fdopen(ispell_fd_in, "w")) == NULL) { g_warning ("Unable to open ispell stream for writing (fd: %d)\n", ispell_fd_in); return -1; } if ((ispell_output = fdopen(ispell_fd_out, "r")) == NULL) { g_warning ("Unable to open ispell stream for reading (fd: %d)\n", ispell_fd_out); return -1; } /* Set ispell input to be line-buffered! */ setvbuf(ispell_input, o_buf, _IOLBF, ISP_BUF_LEN); if (fork () == 0) { /* Child process */ dup2 (stdin_pipe[0], 0); close (stdin_pipe[0]); close (stdin_pipe[1]); dup2 (stdout_pipe[1], 1); close (stdout_pipe[0]); close (stdout_pipe[1]); arg = g_strdup_printf ("%s -a --language-tag=%s %s", cfg.isp_cmd, (*lang != '\0') ? lang : "en_US", cfg.isp_opt); argv = g_strsplit (arg, " ", 0); if (execvp (cfg.isp_cmd, argv) == -1) { perror ("execlp"); return 1; } /* This will never happen.. */ return 0; } /* Have to close these.. */ close (stdout_pipe[1]); close (stdin_pipe[0]); return 0; } /* Returns TRUE if 'c' is a character that marks the end of a word */ gboolean gse_spell_end_char (gchar c) { if (isdigit (c)) return TRUE; switch (c) { case ' ': case '\0': case '.': case ',': case ':': case ';': case '*': case '+': case '=': case '\t': case '(': case ')': case '!': case '|': case '?': case '-': case '"': return TRUE; default: return FALSE; } return FALSE; } spell_word *gse_spell_get_next_word (spell_word *prev_word) { gchar *text, *tmp; gint start, row, end; gfloat progress = 0; if (!prev_word) /* First time run.. */ { prev_word = (spell_word *) g_malloc (sizeof (spell_word)); prev_word->start = 0; prev_word->end = 0; prev_word->row = 0; prev_word->word = NULL; prev_word->line = NULL; } row = prev_word->row; gtk_clist_get_text (GTK_CLIST (mwin_clist), row, 3, &text); if (!prev_word->line) prev_word->line = g_strdup (text); text += prev_word->end; start = prev_word->end; /* Remove starting illegal chars */ while (!isalpha (*text) && *text) { text++; start++; } /* If end of string - get the next in the clist*/ if (!*text) { row++; progress = (gfloat) row / GTK_CLIST (mwin_clist)->rows; gnome_appbar_set_progress (GNOME_APPBAR (mwin_statusbar), progress); if (gtk_clist_get_text (GTK_CLIST (mwin_clist), row, 3, &text) == 0) return NULL; /* End of clist or major error */ start = 0; g_free (prev_word->line); prev_word->line = g_strdup (text); } g_free (prev_word->word); tmp = text; end = start; /* Step to the next wordseparator */ while (!gse_spell_end_char (*tmp)) { tmp++; end++; } prev_word->word = g_strndup (text, end - start); prev_word->start = start; prev_word->end = end; prev_word->row = row; return prev_word; } void gse_spell_exit_spellchecker () { /* Save personal dictionary and write EOT to ispell to make it exit */ fputs ("#\n", ispell_input); fputc ('\004', ispell_input); fclose (ispell_input); fclose (ispell_output); gnome_appbar_set_progress (GNOME_APPBAR (mwin_statusbar), 0.0); gnome_appbar_pop (GNOME_APPBAR (mwin_statusbar)); close (ispell_fd_in); close (ispell_fd_out); } gint gse_spell_dialog_delete (GtkWidget *wgt, gpointer data) { gse_spell_exit_spellchecker (); return TRUE; } void gse_spell_dialog_close (GtkWidget *wgt, gpointer data) { gse_spell_exit_spellchecker (); gtk_widget_destroy (wgt); } void gse_spell_add_suggestions (gpointer string, gpointer user_data) { gtk_clist_append (GTK_CLIST (clist_results), (gchar **) &string); } void gse_spell_enter_check_loop (GtkWidget *btn_start, gpointer data) { GList *suggestions = NULL; if (btn_start) gtk_widget_set_sensitive (btn_start, FALSE); while ((glob_word = gse_spell_get_next_word (glob_word))) { suggestions = gse_spell_check_word (glob_word->word); if (suggestions) { g_list_foreach (suggestions, gse_spell_add_suggestions, NULL); gtk_entry_set_text (GTK_ENTRY (entry_line), glob_word->line); gtk_entry_set_text (GTK_ENTRY (entry_word), glob_word->word); /* Select the line in the main clist */ gtk_clist_moveto (GTK_CLIST (mwin_clist), glob_word->row, 0, 0.2, 0); gtk_clist_select_row (GTK_CLIST (mwin_clist), glob_word->row, 0); GTK_CLIST (mwin_clist)->focus_row = GPOINTER_TO_INT (GTK_CLIST (mwin_clist)->selection->data); g_list_free (suggestions); suggestions = NULL; return; } } } GList *gse_spell_check_word (gchar *word) { GList *results = NULL; gchar buf[ISP_BUF_LEN], **result_v, *words; gint i; gboolean more_isp_output = TRUE; g_strchomp (word); if (*word == '\0') return NULL; fputs (word, ispell_input); fputc ('\n', ispell_input); fgets (buf, ISP_BUF_LEN, ispell_output); switch (*buf) { case '*': /* Word ok, return NULL */ results = NULL; break; case '&': /* Word misspelled, matches found! */ words = strchr (buf, ':') + 2; g_strchomp (words); result_v = g_strsplit (words, ", ", 0); for (i = 0; result_v[i] != NULL; i++) results = g_list_append (results, g_strdup (result_v[i])); g_strfreev (result_v); break; case '#': /* Word misspelled, no matches found */ results = g_list_append (results, g_strdup (_("(no suggestions)"))); break; case '\n': /* Word ok (Tierse mode or numeric word) */ more_isp_output = FALSE; break; } *buf = '\0'; if (more_isp_output) { while (*buf!='\n') fgets(buf, 255, ispell_output); } return results; } spell_word *gse_spell_replace_word (spell_word *word, gchar *new_word) { GString *new_line; gchar *tmp; /* Some sanitychecks first */ if (!word || !new_word) return NULL; new_line = g_string_new (word->line); new_line = g_string_truncate (new_line, word->start); new_line = g_string_append (new_line, new_word); new_line = g_string_append (new_line, (gchar *) &(word->line [word->end])); g_free (word->line); word->line = new_line->str; /* We'll have to update the end position since the new word can be longer/shorter that the original one */ tmp = &(word->line[word->start]); word->end = word->start; while (!gse_spell_end_char (*tmp)) { tmp++; word->end++; } g_string_free (new_line, FALSE); cur_open_file.changed = TRUE; gse_set_title_changed (TRUE); return word; } void gse_spell_insert_word (gchar *word, gboolean lowercase) { gchar buf[BUF_LEN]; g_snprintf (buf, BUF_LEN, "%s%s", lowercase ? "&" : "*", word); /* write (ispell_input, buf, strlen (buf)); write (ispell_input, "\n", 1);*/ fputs (buf, ispell_input); fputc ('\n', ispell_input); } void gse_spell_ignore_word (gchar *word) { gchar buf[BUF_LEN]; g_snprintf (buf, BUF_LEN, "@%s", word); /* write (ispell_input, buf, strlen (buf)); write (ispell_input, "\n", 1);*/ fputs (buf, ispell_input); fputc ('\n', ispell_input); } gchar *gse_spell_get_lang_from_user (void) { gchar *lang = NULL, *txt; GtkWidget *dlg, *lbl, *entry, *vbox, *chk_ask, *chk_def; gint ret; lbl = gtk_label_new (_("Enter the language code for this document\nExample: en_US for english")); entry = gtk_entry_new (); vbox = gtk_vbox_new (FALSE, 5); gtk_box_pack_start (GTK_BOX (vbox), lbl, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0); txt = g_strdup_printf (_("Use language from the mainwindow (Currently \"%s\")"), cur_open_file.lang); chk_def = gtk_check_button_new_with_label (txt); g_free (txt); if (!cur_open_file.lang) gtk_widget_set_sensitive (chk_def, FALSE); gtk_box_pack_start (GTK_BOX (vbox), chk_def, FALSE, FALSE, 5); chk_ask = gtk_check_button_new_with_label (_("Don't ask me again")); gtk_box_pack_start (GTK_BOX (vbox), chk_ask, FALSE, FALSE, 5); gtk_widget_show_all (vbox); dlg = gnome_dialog_new (_("Enter language code"), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL); gnome_dialog_set_parent (GNOME_DIALOG (dlg), GTK_WINDOW (main_window)); gnome_dialog_set_default (GNOME_DIALOG (dlg), 0); gnome_dialog_editable_enters (GNOME_DIALOG (dlg), GTK_EDITABLE (entry)); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dlg)->vbox), vbox, TRUE, TRUE, 0); gtk_widget_grab_focus (entry); ret = gnome_dialog_run (GNOME_DIALOG (dlg)); if (ret == 0) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chk_def))) lang = g_strdup (cur_open_file.lang); else lang = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); cfg.isp_ask = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chk_ask)); } gnome_dialog_close (GNOME_DIALOG (dlg)); return lang; } void gse_spell_show_dialog (GtkWidget *wgt, gpointer data) { GtkWidget *dialog; gchar buf[BUF_LEN], *lang = NULL; if (cfg.isp_ask || cur_open_file.lang == NULL) lang = gse_spell_get_lang_from_user (); else lang = g_strdup (cur_open_file.lang); if (lang == NULL) return; if (gse_spell_init_aspell (lang) == -1) { g_warning ("GSubEdit: Error initializing ispell pipes, aborting\n"); return; } g_free (lang); glob_word = NULL; dialog = gse_spell_create_dialog (); gtk_widget_show (dialog); gnome_appbar_push (GNOME_APPBAR (mwin_statusbar), _("Spellchecking document")); /* First read the starting Ispell output */ fgets (buf, BUF_LEN, ispell_output); } void on_clist_results_select_row (GtkWidget *wgt, gpointer data) { gchar *txt = ""; gtk_clist_get_text (GTK_CLIST (clist_results), (gint) GTK_CLIST (clist_results)->selection->data, 0, &txt); gtk_entry_set_text (GTK_ENTRY (entry_custom), txt); } void gse_spell_btn_clicked (GtkWidget *btn, gpointer data) { gchar *new_word; switch (GPOINTER_TO_INT (data)) { case GSE_BTN_REPLACE: if ((new_word = gtk_editable_get_chars (GTK_EDITABLE (entry_custom), 0, -1)) == NULL) { g_warning ("No word selected!\n"); return; } glob_word = gse_spell_replace_word (glob_word, new_word); gtk_clist_set_text (GTK_CLIST (mwin_clist), glob_word->row, 3, glob_word->line); g_free (new_word); break; case GSE_BTN_IGNORE: break; case GSE_BTN_IGNORE_ALL: gse_spell_ignore_word (glob_word->word); break; case GSE_BTN_ADD: gse_spell_insert_word (glob_word->word, TRUE); break; case GSE_BTN_ADD_CASE: gse_spell_insert_word (glob_word->word, FALSE); break; } gtk_clist_clear (GTK_CLIST (clist_results)); gtk_entry_set_text (GTK_ENTRY (entry_custom), ""); gse_spell_enter_check_loop (NULL, NULL); } void gse_spell_cb_entry_kpevent (GtkWidget *w, GdkEventKey *event, gpointer data) { switch (event->keyval) { case GDK_Return: case GDK_KP_Enter: gse_spell_btn_clicked (NULL, GINT_TO_POINTER (GSE_BTN_REPLACE)); break; } } GtkWidget *gse_spell_create_dialog (void) { GtkWidget *spell_dialog; GtkWidget *dialog_vbox2; GtkWidget *hbox3; GtkWidget *label3; GtkWidget *hseparator1; GtkWidget *hbox2; GtkWidget *vbox5; GtkWidget *hbox4; GtkWidget *label4; GtkWidget *scrolledwindow2; GtkWidget *label2; GtkWidget *hbox5; GtkWidget *label5; GtkWidget *vbox4; GtkWidget *btn_replace; GtkWidget *btn_ignore; GtkWidget *btn_ignore_all; GtkWidget *btn_add; GtkWidget *btn_add_case; GtkWidget *dialog_action_area2; GtkWidget *btn_start; GtkWidget *btn_close; GtkAccelGroup *accel_group; GtkTooltips *tooltips; tooltips = gtk_tooltips_new (); accel_group = gtk_accel_group_new (); spell_dialog = gnome_dialog_new (_("Spell Checking"), NULL); gtk_object_set_data (GTK_OBJECT (spell_dialog), "spell_dialog", spell_dialog); GTK_WINDOW (spell_dialog)->type = GTK_WINDOW_DIALOG; gtk_window_set_policy (GTK_WINDOW (spell_dialog), TRUE, TRUE, TRUE); gtk_signal_connect (GTK_OBJECT (spell_dialog), "close", GTK_SIGNAL_FUNC (gse_spell_dialog_close), NULL); dialog_vbox2 = GNOME_DIALOG (spell_dialog)->vbox; gtk_object_set_data (GTK_OBJECT (spell_dialog), "dialog_vbox2", dialog_vbox2); gtk_widget_show (dialog_vbox2); hbox3 = gtk_hbox_new (FALSE, 5); gtk_widget_ref (hbox3); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "hbox3", hbox3, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (hbox3); gtk_box_pack_start (GTK_BOX (dialog_vbox2), hbox3, FALSE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (hbox3), 2); gtk_widget_set_sensitive (hbox3, FALSE); label3 = gtk_label_new (_("Line")); gtk_widget_ref (label3); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "label3", label3, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (label3); gtk_box_pack_start (GTK_BOX (hbox3), label3, FALSE, FALSE, 0); entry_line = gtk_entry_new (); gtk_widget_ref (entry_line); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "entry_line", entry_line, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (entry_line); gtk_box_pack_start (GTK_BOX (hbox3), entry_line, TRUE, TRUE, 0); gtk_entry_set_editable (GTK_ENTRY (entry_line), FALSE); hseparator1 = gtk_hseparator_new (); gtk_widget_ref (hseparator1); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "hseparator1", hseparator1, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (hseparator1); gtk_box_pack_start (GTK_BOX (dialog_vbox2), hseparator1, FALSE, TRUE, 0); hbox2 = gtk_hbox_new (FALSE, 0); gtk_widget_ref (hbox2); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "hbox2", hbox2, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (hbox2); gtk_box_pack_start (GTK_BOX (dialog_vbox2), hbox2, TRUE, TRUE, 0); vbox5 = gtk_vbox_new (FALSE, 5); gtk_widget_ref (vbox5); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "vbox5", vbox5, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (vbox5); gtk_box_pack_start (GTK_BOX (hbox2), vbox5, TRUE, TRUE, 0); hbox4 = gtk_hbox_new (FALSE, 6); gtk_widget_ref (hbox4); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "hbox4", hbox4, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (hbox4); gtk_box_pack_start (GTK_BOX (vbox5), hbox4, FALSE, TRUE, 3); label4 = gtk_label_new (_("Mispelled word:")); gtk_widget_ref (label4); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "label4", label4, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (label4); gtk_box_pack_start (GTK_BOX (hbox4), label4, FALSE, FALSE, 0); entry_word = gtk_entry_new (); gtk_widget_ref (entry_word); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "entry_word", entry_word, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (entry_word); gtk_box_pack_end (GTK_BOX (hbox4), entry_word, FALSE, FALSE, 0); scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_ref (scrolledwindow2); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "scrolledwindow2", scrolledwindow2, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (scrolledwindow2); gtk_box_pack_start (GTK_BOX (vbox5), scrolledwindow2, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); clist_results = gtk_clist_new (1); gtk_widget_ref (clist_results); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "clist_results", clist_results, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (clist_results); gtk_container_add (GTK_CONTAINER (scrolledwindow2), clist_results); gtk_clist_set_column_width (GTK_CLIST (clist_results), 0, 80); gtk_clist_set_selection_mode (GTK_CLIST (clist_results), GTK_SELECTION_BROWSE); gtk_clist_column_titles_show (GTK_CLIST (clist_results)); label2 = gtk_label_new (_("Suggestions")); gtk_widget_ref (label2); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "label2", label2, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (label2); gtk_clist_set_column_widget (GTK_CLIST (clist_results), 0, label2); gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT); hbox5 = gtk_hbox_new (FALSE, 5); gtk_widget_ref (hbox5); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "hbox5", hbox5, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (hbox5); gtk_box_pack_start (GTK_BOX (vbox5), hbox5, FALSE, TRUE, 0); label5 = gtk_label_new (_("Replace with:")); gtk_widget_ref (label5); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "label5", label5, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (label5); gtk_box_pack_start (GTK_BOX (hbox5), label5, FALSE, FALSE, 0); entry_custom = gtk_entry_new (); gtk_widget_ref (entry_custom); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "entry_custom", entry_custom, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (entry_custom); gtk_box_pack_end (GTK_BOX (hbox5), entry_custom, FALSE, FALSE, 0); vbox4 = gtk_vbox_new (FALSE, 9); gtk_widget_ref (vbox4); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "vbox4", vbox4, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (vbox4); gtk_box_pack_start (GTK_BOX (hbox2), vbox4, TRUE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox4), 8); btn_replace = gtk_button_new_with_label (_("Replace")); gtk_widget_ref (btn_replace); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "btn_replace", btn_replace, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (btn_replace); gtk_box_pack_start (GTK_BOX (vbox4), btn_replace, FALSE, FALSE, 0); gtk_tooltips_set_tip (tooltips, btn_replace, _("Replaces the misspelled word with the one selected in the list"), NULL); gtk_widget_add_accelerator (btn_replace, "clicked", accel_group, GDK_r, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE); btn_ignore = gtk_button_new_with_label (_("Ignore")); gtk_widget_ref (btn_ignore); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "btn_ignore", btn_ignore, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (btn_ignore); gtk_box_pack_start (GTK_BOX (vbox4), btn_ignore, FALSE, FALSE, 0); gtk_tooltips_set_tip (tooltips, btn_ignore, _("Ignores this occurance of the word"), NULL); gtk_widget_add_accelerator (btn_ignore, "clicked", accel_group, GDK_i, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE); btn_ignore_all = gtk_button_new_with_label (_("Ignore All")); gtk_widget_ref (btn_ignore_all); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "btn_ignore_all", btn_ignore_all, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (btn_ignore_all); gtk_box_pack_start (GTK_BOX (vbox4), btn_ignore_all, FALSE, FALSE, 0); gtk_tooltips_set_tip (tooltips, btn_ignore_all, _("Ignores all occurances of the word"), NULL); gtk_widget_add_accelerator (btn_ignore_all, "clicked", accel_group, GDK_A, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE); btn_add = gtk_button_new_with_label (_("Add word")); gtk_widget_ref (btn_add); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "btn_add", btn_add, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (btn_add); gtk_box_pack_start (GTK_BOX (vbox4), btn_add, FALSE, FALSE, 0); gtk_tooltips_set_tip (tooltips, btn_add, _("Adds the word lowercased to the personal dictionary"), NULL); gtk_widget_add_accelerator (btn_add, "clicked", accel_group, GDK_A, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE); btn_add_case = gtk_button_new_with_label (_("Add with case")); gtk_widget_ref (btn_add_case); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "btn_add_case", btn_add_case, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (btn_add_case); gtk_box_pack_start (GTK_BOX (vbox4), btn_add_case, FALSE, FALSE, 0); gtk_tooltips_set_tip (tooltips, btn_add_case, _("Adds the word, with current case, to the personal dictionary"), NULL); gtk_widget_add_accelerator (btn_add_case, "clicked", accel_group, GDK_A, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE); dialog_action_area2 = GNOME_DIALOG (spell_dialog)->action_area; gtk_object_set_data (GTK_OBJECT (spell_dialog), "dialog_action_area2", dialog_action_area2); gtk_widget_show (dialog_action_area2); gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area2), GTK_BUTTONBOX_END); gtk_button_box_set_spacing (GTK_BUTTON_BOX (dialog_action_area2), 7); gtk_button_box_set_child_size (GTK_BUTTON_BOX (dialog_action_area2), 84, 25); gtk_button_box_set_child_ipadding (GTK_BUTTON_BOX (dialog_action_area2), 8, 0); gnome_dialog_append_button_with_pixmap (GNOME_DIALOG (spell_dialog), _("Start"), GNOME_STOCK_PIXMAP_SPELLCHECK); btn_start = GTK_WIDGET (g_list_last (GNOME_DIALOG (spell_dialog)->buttons)->data); gtk_widget_ref (btn_start); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "btn_start", btn_start, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (btn_start); GTK_WIDGET_SET_FLAGS (btn_start, GTK_CAN_DEFAULT); gtk_tooltips_set_tip (tooltips, btn_start, _("Start spellchecker"), NULL); gnome_dialog_append_button_with_pixmap (GNOME_DIALOG (spell_dialog), _("Close"), GNOME_STOCK_PIXMAP_CLOSE); btn_close = GTK_WIDGET (g_list_last (GNOME_DIALOG (spell_dialog)->buttons)->data); gtk_widget_ref (btn_close); gtk_object_set_data_full (GTK_OBJECT (spell_dialog), "btn_close", btn_close, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (btn_close); GTK_WIDGET_SET_FLAGS (btn_close, GTK_CAN_DEFAULT); gtk_tooltips_set_tip (tooltips, btn_close, _("Close spellchecker"), NULL); gtk_signal_connect_object (GTK_OBJECT (clist_results), "select_row", GTK_SIGNAL_FUNC (on_clist_results_select_row), GTK_OBJECT (entry_custom)); gtk_signal_connect (GTK_OBJECT (btn_replace), "clicked", GTK_SIGNAL_FUNC (gse_spell_btn_clicked), GINT_TO_POINTER (GSE_BTN_REPLACE)); gtk_signal_connect (GTK_OBJECT (btn_ignore), "clicked", GTK_SIGNAL_FUNC (gse_spell_btn_clicked), GINT_TO_POINTER (GSE_BTN_IGNORE)); gtk_signal_connect (GTK_OBJECT (btn_ignore_all), "clicked", GTK_SIGNAL_FUNC (gse_spell_btn_clicked), GINT_TO_POINTER (GSE_BTN_IGNORE_ALL)); gtk_signal_connect (GTK_OBJECT (btn_add), "clicked", GTK_SIGNAL_FUNC (gse_spell_btn_clicked), GINT_TO_POINTER (GSE_BTN_ADD)); gtk_signal_connect (GTK_OBJECT (btn_add_case), "clicked", GTK_SIGNAL_FUNC (gse_spell_btn_clicked), GINT_TO_POINTER (GSE_BTN_ADD_CASE)); gtk_signal_connect (GTK_OBJECT (btn_start), "clicked", GTK_SIGNAL_FUNC (gse_spell_enter_check_loop), NULL); gtk_signal_connect (GTK_OBJECT (entry_custom), "key-press-event", GTK_SIGNAL_FUNC (gse_spell_cb_entry_kpevent), NULL); gtk_signal_connect_object (GTK_OBJECT (btn_close), "clicked", GTK_SIGNAL_FUNC (gnome_dialog_close), GTK_OBJECT (spell_dialog)); gtk_object_set_data (GTK_OBJECT (spell_dialog), "tooltips", tooltips); gtk_window_add_accel_group (GTK_WINDOW (spell_dialog), accel_group); return spell_dialog; }