From 35bc7bd9f2ec7124ed3678b520ba51e81da5750a Mon Sep 17 00:00:00 2001 From: Colin Leroy Date: Wed, 11 Feb 2009 19:06:15 +0000 Subject: [PATCH] 2009-02-11 [colin] 3.7.0cvs58 * src/compose.c * src/gtk/Makefile.am * src/gtk/gtkaspell.c * src/gtk/gtkaspell.h Add spellcheck to subject. Patch by Pawel. --- ChangeLog | 9 ++ PATCHSETS | 1 + configure.ac | 2 +- src/compose.c | 56 +++++++-- src/gtk/Makefile.am | 2 + src/gtk/gtkaspell.c | 269 +++++++++++++++++++++++--------------------- src/gtk/gtkaspell.h | 82 +++++++++++++- 7 files changed, 278 insertions(+), 143 deletions(-) diff --git a/ChangeLog b/ChangeLog index e6bd62a38..e79069148 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-02-11 [colin] 3.7.0cvs58 + + * src/compose.c + * src/gtk/Makefile.am + * src/gtk/gtkaspell.c + * src/gtk/gtkaspell.h + Add spellcheck to subject. Patch by + Pawel. + 2009-02-10 [holger] 3.7.0cvs57 * src/printing.c diff --git a/PATCHSETS b/PATCHSETS index c912fc69c..792fda286 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -3719,3 +3719,4 @@ ( cvs diff -u -r 1.204.2.185 -r 1.204.2.186 src/prefs_common.c; cvs diff -u -r 1.103.2.121 -r 1.103.2.122 src/prefs_common.h; cvs diff -u -r 1.1.2.19 -r 1.1.2.20 src/printing.c; ) > 3.7.0cvs55.patchset ( cvs diff -u -r 1.39.2.16 -r 1.39.2.17 src/matcher.h; ) > 3.7.0cvs56.patchset ( cvs diff -u -r 1.1.2.20 -r 1.1.2.21 src/printing.c; cvs diff -u -r 1.9.2.48 -r 1.9.2.49 src/common/defs.h; ) > 3.7.0cvs57.patchset +( cvs diff -u -r 1.382.2.498 -r 1.382.2.499 src/compose.c; cvs diff -u -r 1.20.2.21 -r 1.20.2.22 src/gtk/Makefile.am; cvs diff -u -r 1.9.2.64 -r 1.9.2.65 src/gtk/gtkaspell.c; cvs diff -u -r 1.5.2.16 -r 1.5.2.17 src/gtk/gtkaspell.h; ) > 3.7.0cvs58.patchset diff --git a/configure.ac b/configure.ac index c3bcca8e7..91c518f02 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=7 MICRO_VERSION=0 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=57 +EXTRA_VERSION=58 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/compose.c b/src/compose.c index 2ba2c2ae0..34b4f07be 100644 --- a/src/compose.c +++ b/src/compose.c @@ -100,6 +100,7 @@ #include "privacy.h" #include "timing.h" #include "autofaces.h" +#include "spell_entry.h" enum { @@ -333,6 +334,7 @@ static void compose_remove_header_entries(Compose *compose); static void compose_update_priority_menu_item(Compose * compose); #if USE_ENCHANT static void compose_spell_menu_changed (void *data); +static void compose_dict_changed (void *data); #endif static void compose_add_field_list ( Compose *compose, GList *listAddress ); @@ -6687,7 +6689,18 @@ static void compose_spell_menu_changed(void *data) g_slist_free(spell_menu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent_item), GTK_WIDGET(menu)); - + gtk_widget_show(parent_item); +} + +static void compose_dict_changed(void *data) +{ + Compose *compose = (Compose *) data; + + if(compose->gtkaspell->recheck_when_changing_dict == FALSE) + return; + + gtkaspell_highlight_all(compose->gtkaspell); + claws_spell_entry_recheck_all(CLAWS_SPELL_ENTRY(compose->subject_entry)); } #endif @@ -7073,7 +7086,11 @@ static Compose *compose_create(PrefsAccount *account, gtk_box_pack_start(GTK_BOX(subject), label, FALSE, FALSE, 0); gtk_widget_show(label); +#ifdef USE_ENCHANT + subject_entry = claws_spell_entry_new(); +#else subject_entry = gtk_entry_new(); +#endif gtk_box_pack_start(GTK_BOX(subject), subject_entry, TRUE, TRUE, 0); g_signal_connect_after(G_OBJECT(subject_entry), "grab_focus", G_CALLBACK(compose_grab_focus_cb), compose); @@ -7276,6 +7293,7 @@ static Compose *compose_create(PrefsAccount *account, prefs_common.use_both_dicts, GTK_TEXT_VIEW(text), GTK_WINDOW(compose->window), + compose_dict_changed, compose_spell_menu_changed, compose); if (!gtkaspell) { @@ -7290,6 +7308,7 @@ static Compose *compose_create(PrefsAccount *account, } compose->gtkaspell = gtkaspell; compose_spell_menu_changed(compose); + claws_spell_entry_set_gtkaspell(CLAWS_SPELL_ENTRY(subject_entry), gtkaspell); #endif compose_select_account(compose, account, TRUE); @@ -10484,35 +10503,54 @@ static gint compose_defer_auto_save_draft(Compose *compose) static void compose_check_all(GtkAction *action, gpointer data) { Compose *compose = (Compose *)data; - if (compose->gtkaspell) + if (!compose->gtkaspell) + return; + + if (GTK_WIDGET_HAS_FOCUS(compose->subject_entry)) + claws_spell_entry_check_all( + CLAWS_SPELL_ENTRY(compose->subject_entry)); + else gtkaspell_check_all(compose->gtkaspell); } static void compose_highlight_all(GtkAction *action, gpointer data) { Compose *compose = (Compose *)data; - if (compose->gtkaspell) + if (compose->gtkaspell) { + claws_spell_entry_recheck_all( + CLAWS_SPELL_ENTRY(compose->subject_entry)); gtkaspell_highlight_all(compose->gtkaspell); + } } static void compose_check_backwards(GtkAction *action, gpointer data) { Compose *compose = (Compose *)data; - if (compose->gtkaspell) - gtkaspell_check_backwards(compose->gtkaspell); - else { + if (!compose->gtkaspell) { cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Spelling", FALSE); + return; } + + if (GTK_WIDGET_HAS_FOCUS(compose->subject_entry)) + claws_spell_entry_check_backwards( + CLAWS_SPELL_ENTRY(compose->subject_entry)); + else + gtkaspell_check_backwards(compose->gtkaspell); } static void compose_check_forwards_go(GtkAction *action, gpointer data) { Compose *compose = (Compose *)data; - if (compose->gtkaspell) - gtkaspell_check_forwards_go(compose->gtkaspell); - else { + if (!compose->gtkaspell) { cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Spelling", FALSE); + return; } + + if (GTK_WIDGET_HAS_FOCUS(compose->subject_entry)) + claws_spell_entry_check_forwards_go( + CLAWS_SPELL_ENTRY(compose->subject_entry)); + else + gtkaspell_check_forwards_go(compose->gtkaspell); } #endif diff --git a/src/gtk/Makefile.am b/src/gtk/Makefile.am index 6db802fb7..4f904001f 100644 --- a/src/gtk/Makefile.am +++ b/src/gtk/Makefile.am @@ -32,6 +32,7 @@ libclawsgtk_la_SOURCES = \ prefswindow.c \ progressdialog.c \ quicksearch.c \ + spell_entry.c \ sslcertwindow.c \ claws-marshal.c @@ -65,6 +66,7 @@ clawsgtkinclude_HEADERS = \ gtkvscrollbutton.h \ progressdialog.h \ quicksearch.h \ + spell_entry.h \ sslcertwindow.h \ claws-marshal.h diff --git a/src/gtk/gtkaspell.c b/src/gtk/gtkaspell.c index 2c716e117..b2a952c86 100644 --- a/src/gtk/gtkaspell.c +++ b/src/gtk/gtkaspell.c @@ -50,8 +50,6 @@ #include #include -#include - #include "utils.h" #include "alertpanel.h" #include "gtkaspell.h" @@ -62,8 +60,6 @@ #define ASPELL_NORMALMODE 2 #define ASPELL_BADSPELLERMODE 3 -#define GTKASPELLWORDSIZE 1024 - /* size of the text buffer used in various word-processing routines. */ #define BUFSIZE 1024 @@ -82,49 +78,6 @@ typedef struct _GtkAspellCheckers { gchar *error_message; } GtkAspellCheckers; -typedef struct _Dictionary { - gchar *fullname; - gchar *dictname; -} Dictionary; - -typedef struct _GtkAspeller { - Dictionary *dictionary; - EnchantBroker *broker; - EnchantDict *speller; -} GtkAspeller; - -typedef void (*ContCheckFunc) (gpointer *gtkaspell); - -struct _GtkAspell -{ - GtkAspeller *gtkaspeller; - GtkAspeller *alternate_speller; - gchar theword[GTKASPELLWORDSIZE]; - gint start_pos; - gint end_pos; - gint orig_pos; - gint end_check_pos; - gboolean misspelled; - gboolean check_while_typing; - gboolean recheck_when_changing_dict; - gboolean use_alternate; - gboolean use_both_dicts; - - ContCheckFunc continue_check; - - GtkWidget *replace_entry; - GtkWidget *parent_window; - - gint max_sug; - GList *suggestions_list; - - GtkTextView *gtktext; - GdkColor highlight; - GtkAccelGroup *accel_group; - void (*menu_changed_cb)(void *data); - void *menu_changed_data; -}; - /******************************************************************************/ static GtkAspellCheckers *gtkaspellcheckers; @@ -164,10 +117,11 @@ static void set_use_both_cb (GtkMenuItem *w, /* Checker actions */ static gboolean check_at (GtkAspell *gtkaspell, int from_pos); -static gboolean check_next_prev (GtkAspell *gtkaspell, - gboolean forward); +static gboolean check_at_cb (gpointer data); static GList* misspelled_suggest (GtkAspell *gtkaspell, gchar *word); +static gboolean find_misspelled_cb (gpointer data, + gboolean forward); static void add_word_to_session_cb (GtkWidget *w, gpointer data); static void add_word_to_personal_cb (GtkWidget *w, @@ -180,9 +134,10 @@ static void replace_word_cb (GtkWidget *w, gpointer data); static void replace_real_word (GtkAspell *gtkaspell, const gchar *newword); +static void replace_real_word_cb (gpointer data, + const gchar *newword); static void check_with_alternate_cb (GtkWidget *w, gpointer data); -static void use_alternate_dict (GtkAspell *gtkaspell); static void toggle_check_while_typing_cb (GtkWidget *w, gpointer data); @@ -227,7 +182,6 @@ static gint compare_dict (Dictionary *a, Dictionary *b); static void dictionary_delete (Dictionary *dict); static Dictionary * dictionary_dup (const Dictionary *dict); -static void free_suggestions_list (GtkAspell *gtkaspell); static void reset_theword_data (GtkAspell *gtkaspell); static void free_checkers (gpointer elt, gpointer data); @@ -367,6 +321,7 @@ GtkAspell *gtkaspell_new(const gchar *dictionary, gboolean use_both_dicts, GtkTextView *gtktext, GtkWindow *parent_win, + void (dict_changed_cb)(void *data), void (*spell_menu_cb)(void *data), void *data) { @@ -457,6 +412,7 @@ GtkAspell *gtkaspell_new(const gchar *dictionary, gtkaspell->use_alternate = use_alternate; gtkaspell->use_both_dicts = use_both_dicts; gtkaspell->parent_window = GTK_WIDGET(parent_win); + gtkaspell->dict_changed_cb = dict_changed_cb; gtkaspell->menu_changed_cb = spell_menu_cb; gtkaspell->menu_changed_data = data; @@ -499,7 +455,7 @@ void gtkaspell_delete(GtkAspell *gtkaspell) gtkaspeller_delete(gtkaspell->alternate_speller); if (gtkaspell->suggestions_list) - free_suggestions_list(gtkaspell); + gtkaspell_free_suggestions_list(gtkaspell); debug_print("Aspell: deleting gtkaspell %p\n", gtkaspell); @@ -508,6 +464,15 @@ void gtkaspell_delete(GtkAspell *gtkaspell) gtkaspell = NULL; } +void gtkaspell_dict_changed(GtkAspell *gtkaspell) +{ + if(!gtkaspell || !gtkaspell->dict_changed_cb || + !gtkaspell->menu_changed_data) + return; + + gtkaspell->dict_changed_cb(gtkaspell->menu_changed_data); +} + static void entry_insert_cb(GtkTextBuffer *textbuf, GtkTextIter *iter, gchar *newtext, @@ -570,32 +535,25 @@ static void entry_delete_cb(GtkTextBuffer *textbuf, /* gtk_editable_select_region(GTK_EDITABLE(gtktext), origpos, origpos); */ } -static void button_press_intercept_cb(GtkTextView *gtktext, - GtkMenu *menu, GtkAspell *gtkaspell) +void gtkaspell_make_context_menu(GtkMenu *menu, GtkAspell *gtkaspell) { GtkMenuItem *menuitem; GSList *spell_menu = NULL; GSList *items; gboolean suggest = FALSE; - menuitem = GTK_MENU_ITEM(gtk_separator_menu_item_new()); - gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), GTK_WIDGET(menuitem)); - gtk_widget_show(GTK_WIDGET(menuitem)); - - gtktext = gtkaspell->gtktext; - - gtkaspell->orig_pos = get_textview_buffer_offset(gtktext); - - if (check_at(gtkaspell, gtkaspell->orig_pos)) { - - if (misspelled_suggest(gtkaspell, gtkaspell->theword)) { - spell_menu = make_sug_menu(gtkaspell); - suggest = TRUE; - } + if (gtkaspell->misspelled && + misspelled_suggest(gtkaspell, gtkaspell->theword)) { + spell_menu = make_sug_menu(gtkaspell); + suggest = TRUE; } if (!spell_menu) spell_menu = gtkaspell_make_config_menu(gtkaspell); + menuitem = GTK_MENU_ITEM(gtk_separator_menu_item_new()); + gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), GTK_WIDGET(menuitem)); + gtk_widget_show(GTK_WIDGET(menuitem)); + spell_menu = g_slist_reverse(spell_menu); for (items = spell_menu; items; items = items->next) { @@ -606,14 +564,40 @@ static void button_press_intercept_cb(GtkTextView *gtktext, g_slist_free(spell_menu); g_signal_connect(G_OBJECT(menu), "deactivate", - G_CALLBACK(destroy_menu), + G_CALLBACK(destroy_menu), gtkaspell); if (suggest) g_signal_connect(G_OBJECT(menu), "key_press_event", - G_CALLBACK(aspell_key_pressed), gtkaspell); + G_CALLBACK(aspell_key_pressed), + gtkaspell); +} + +static void set_position_cb(gpointer data, gint pos) +{ + GtkAspell *gtkaspell = (GtkAspell *) data; + set_textview_buffer_offset(gtkaspell->gtktext, pos); +} +void gtkaspell_context_set(GtkAspell *gtkaspell) +{ + gtkaspell->ctx.set_position = set_position_cb; + gtkaspell->ctx.set_menu_pos = set_menu_pos; + gtkaspell->ctx.find_misspelled = find_misspelled_cb; + gtkaspell->ctx.check_word = check_at_cb; + gtkaspell->ctx.replace_word = replace_real_word_cb; + gtkaspell->ctx.data = (gpointer) gtkaspell; +} +static void button_press_intercept_cb(GtkTextView *gtktext, + GtkMenu *menu, GtkAspell *gtkaspell) +{ + gtktext = gtkaspell->gtktext; + gtkaspell->orig_pos = get_textview_buffer_offset(gtktext); + gtkaspell->misspelled = check_at(gtkaspell, gtkaspell->orig_pos); + + gtkaspell_context_set(gtkaspell); + gtkaspell_make_context_menu(menu, gtkaspell); } /* Checker creation */ static GtkAspeller *gtkaspeller_new(Dictionary *dictionary) @@ -746,10 +730,7 @@ static EnchantDict *set_dictionary(EnchantBroker *broker, Dictionary *dict) static void set_use_both_cb(GtkMenuItem *w, GtkAspell *gtkaspell) { gtkaspell->use_both_dicts = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)); - - if (gtkaspell->recheck_when_changing_dict) { - gtkaspell_highlight_all(gtkaspell); - } + gtkaspell_dict_changed(gtkaspell); if (gtkaspell->menu_changed_cb) gtkaspell->menu_changed_cb(gtkaspell->menu_changed_data); @@ -766,7 +747,7 @@ static GList *misspelled_suggest(GtkAspell *gtkaspell, gchar *word) if (*word == 0) return NULL; - free_suggestions_list(gtkaspell); + gtkaspell_free_suggestions_list(gtkaspell); suggestions = enchant_dict_suggest(gtkaspell->gtkaspeller->speller, word, strlen(word), &num_sug); if (suggestions == NULL || num_sug == 0) { @@ -785,7 +766,7 @@ static GList *misspelled_suggest(GtkAspell *gtkaspell, gchar *word) } /* misspelled_test() - Just test if word is correctly spelled */ -static int misspelled_test(GtkAspell *gtkaspell, char *word) +int gtkaspell_misspelled_test(GtkAspell *gtkaspell, char *word) { gint result = 0; g_return_val_if_fail(word, 0); @@ -796,11 +777,12 @@ static int misspelled_test(GtkAspell *gtkaspell, char *word) result = enchant_dict_check(gtkaspell->gtkaspeller->speller, word, strlen(word)); if (result && gtkaspell->use_both_dicts && gtkaspell->alternate_speller) { - use_alternate_dict(gtkaspell); + gtkaspell_use_alternate_dict(gtkaspell); result = enchant_dict_check(gtkaspell->gtkaspeller->speller, word, strlen(word)); - use_alternate_dict(gtkaspell); + gtkaspell_use_alternate_dict(gtkaspell); } - return result; + return (result && strcasecmp(word, "sylpheed") && + strcasecmp(word, "claws-mail")); } @@ -939,13 +921,12 @@ static gboolean check_at(GtkAspell *gtkaspell, gint from_pos) &start, &end)) return FALSE; - if (misspelled_test(gtkaspell, buf) - && strcasecmp(buf, "sylpheed") && strcasecmp(buf, "claws-mail")) { + if (gtkaspell_misspelled_test(gtkaspell, buf)) { strncpy(gtkaspell->theword, (gchar *)buf, GTKASPELLWORDSIZE - 1); gtkaspell->theword[GTKASPELLWORDSIZE - 1] = 0; gtkaspell->start_pos = start; gtkaspell->end_pos = end; - free_suggestions_list(gtkaspell); + gtkaspell_free_suggestions_list(gtkaspell); change_color(gtkaspell, start, end, (gchar *)buf, &(gtkaspell->highlight)); return TRUE; @@ -955,13 +936,20 @@ static gboolean check_at(GtkAspell *gtkaspell, gint from_pos) } } -static gboolean check_next_prev(GtkAspell *gtkaspell, gboolean forward) +static gboolean check_at_cb(gpointer data) { + GtkAspell *gtkaspell = (GtkAspell *)data; + return check_at(gtkaspell, gtkaspell->start_pos); +} + +static gboolean find_misspelled_cb(gpointer data, gboolean forward) +{ + GtkAspell *gtkaspell = (GtkAspell *)data; + gboolean misspelled; gint pos; gint minpos; gint maxpos; gint direc = -1; - gboolean misspelled; minpos = 0; maxpos = gtkaspell->end_check_pos; @@ -988,6 +976,14 @@ static gboolean check_next_prev(GtkAspell *gtkaspell, gboolean forward) pos > minpos && pos <= maxpos) pos += direc; } + + return misspelled; +} + +gboolean gtkaspell_check_next_prev(GtkAspell *gtkaspell, gboolean forward) +{ + gboolean misspelled = gtkaspell->ctx.find_misspelled(gtkaspell->ctx.data, + forward); if (misspelled) { GSList *list, *cur; GtkWidget *menu; @@ -996,16 +992,19 @@ static gboolean check_next_prev(GtkAspell *gtkaspell, gboolean forward) if (forward) gtkaspell->orig_pos = gtkaspell->end_pos; - set_textview_buffer_offset(gtkaspell->gtktext, - gtkaspell->end_pos); - /* scroll line to window center */ - gtk_text_view_scroll_to_mark(gtkaspell->gtktext, - gtk_text_buffer_get_insert( - gtk_text_view_get_buffer(gtkaspell->gtktext)), - 0.0, TRUE, 0.0, 0.5); - /* let textview recalculate coordinates (set_menu_pos) */ - while (gtk_events_pending ()) - gtk_main_iteration (); + gtkaspell->ctx.set_position(gtkaspell->ctx.data, gtkaspell->end_pos); + + /* only execute when in textview context */ + if (gtkaspell == (GtkAspell *)gtkaspell->ctx.data) { + /* scroll line to window center */ + gtk_text_view_scroll_to_mark(gtkaspell->gtktext, + gtk_text_buffer_get_insert( + gtk_text_view_get_buffer(gtkaspell->gtktext)), + 0.0, TRUE, 0.0, 0.5); + /* let textview recalculate coordinates (set_menu_pos) */ + while (gtk_events_pending ()) + gtk_main_iteration (); + } list = make_sug_menu(gtkaspell); menu = gtk_menu_new(); @@ -1013,21 +1012,24 @@ static gboolean check_next_prev(GtkAspell *gtkaspell, gboolean forward) gtk_menu_shell_append(GTK_MENU_SHELL(menu), GTK_WIDGET(cur->data)); g_slist_free(list); gtk_menu_popup(GTK_MENU(menu), NULL, NULL, - set_menu_pos, gtkaspell, 0, GDK_CURRENT_TIME); + gtkaspell->ctx.set_menu_pos, + gtkaspell->ctx.data, + 0, GDK_CURRENT_TIME); g_signal_connect(G_OBJECT(menu), "deactivate", - G_CALLBACK(destroy_menu), + G_CALLBACK(destroy_menu), gtkaspell); g_signal_connect(G_OBJECT(menu), "key_press_event", - G_CALLBACK(aspell_key_pressed), gtkaspell); + G_CALLBACK(aspell_key_pressed), + gtkaspell); } else { reset_theword_data(gtkaspell); alertpanel_notice(_("No misspelled word found.")); - set_textview_buffer_offset(gtkaspell->gtktext, - gtkaspell->orig_pos); + gtkaspell->ctx.set_position(gtkaspell->ctx.data, + gtkaspell->orig_pos); } return misspelled; @@ -1038,7 +1040,8 @@ void gtkaspell_check_backwards(GtkAspell *gtkaspell) gtkaspell->continue_check = NULL; gtkaspell->end_check_pos = get_textview_buffer_charcount(gtkaspell->gtktext); - check_next_prev(gtkaspell, FALSE); + gtkaspell_context_set(gtkaspell); + gtkaspell_check_next_prev(gtkaspell, FALSE); } void gtkaspell_check_forwards_go(GtkAspell *gtkaspell) @@ -1047,7 +1050,8 @@ void gtkaspell_check_forwards_go(GtkAspell *gtkaspell) gtkaspell->continue_check = NULL; gtkaspell->end_check_pos = get_textview_buffer_charcount(gtkaspell->gtktext); - check_next_prev(gtkaspell, TRUE); + gtkaspell_context_set(gtkaspell); + gtkaspell_check_next_prev(gtkaspell, TRUE); } void gtkaspell_check_all(GtkAspell *gtkaspell) @@ -1082,7 +1086,8 @@ void gtkaspell_check_all(GtkAspell *gtkaspell) gtkaspell->continue_check = continue_check; gtkaspell->end_check_pos = end; - gtkaspell->misspelled = check_next_prev(gtkaspell, TRUE); + gtkaspell_context_set(gtkaspell); + gtkaspell->misspelled = gtkaspell_check_next_prev(gtkaspell, TRUE); } static void continue_check(gpointer *data) @@ -1090,7 +1095,7 @@ static void continue_check(gpointer *data) GtkAspell *gtkaspell = (GtkAspell *) data; gint pos = get_textview_buffer_offset(gtkaspell->gtktext); if (pos < gtkaspell->end_check_pos && gtkaspell->misspelled) - gtkaspell->misspelled = check_next_prev(gtkaspell, TRUE); + gtkaspell->misspelled = gtkaspell_check_next_prev(gtkaspell, TRUE); else gtkaspell->continue_check = NULL; } @@ -1132,7 +1137,7 @@ static void replace_with_supplied_word_cb(GtkWidget *w, GtkAspell *gtkaspell) 0, -1); if (strcmp(newword, gtkaspell->theword)) { - replace_real_word(gtkaspell, newword); + gtkaspell->ctx.replace_word(gtkaspell->ctx.data, newword); if ((e->type == GDK_KEY_PRESS && ((GdkEventKey *) e)->state & GDK_CONTROL_MASK)) { @@ -1161,7 +1166,7 @@ static void replace_word_cb(GtkWidget *w, gpointer data) newword = gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN((w))))); - replace_real_word(gtkaspell, newword); + gtkaspell->ctx.replace_word(gtkaspell->ctx.data, newword); if ((e->type == GDK_KEY_PRESS && ((GdkEventKey *) e)->state & GDK_CONTROL_MASK) || @@ -1251,19 +1256,23 @@ static void replace_real_word(GtkAspell *gtkaspell, const gchar *newword) set_textview_buffer_offset(gtktext, gtkaspell->orig_pos); } +static void replace_real_word_cb(gpointer data, const gchar *newword) +{ + replace_real_word((GtkAspell *)data, newword); +} + /* Accept this word for this session */ static void add_word_to_session_cb(GtkWidget *w, gpointer data) { - guint pos; GtkTextView *gtktext; GtkAspell *gtkaspell = (GtkAspell *) data; gtktext = gtkaspell->gtktext; - pos = get_textview_buffer_offset(gtktext); enchant_dict_add_to_session(gtkaspell->gtkaspeller->speller, gtkaspell->theword, strlen(gtkaspell->theword)); - check_at(gtkaspell, gtkaspell->start_pos); + gtkaspell->ctx.check_word(gtkaspell->ctx.data); + gtkaspell_dict_changed(gtkaspell); gtk_menu_shell_deactivate(GTK_MENU_SHELL(GTK_WIDGET(w)->parent)); @@ -1277,21 +1286,22 @@ static void add_word_to_personal_cb(GtkWidget *w, gpointer data) enchant_dict_add_to_pwl(gtkaspell->gtkaspeller->speller, gtkaspell->theword, strlen(gtkaspell->theword)); - check_at(gtkaspell, gtkaspell->start_pos); - + gtkaspell->ctx.check_word(gtkaspell->ctx.data); + gtkaspell_dict_changed(gtkaspell); + gtk_menu_shell_deactivate(GTK_MENU_SHELL(GTK_WIDGET(w)->parent)); set_point_continue(gtkaspell); } static void check_with_alternate_cb(GtkWidget *w, gpointer data) { - GtkAspell *gtkaspell = (GtkAspell *) data; + GtkAspell *gtkaspell = (GtkAspell *)data; gint misspelled; gtk_menu_shell_deactivate(GTK_MENU_SHELL(GTK_WIDGET(w)->parent)); - use_alternate_dict(gtkaspell); - misspelled = check_at(gtkaspell, gtkaspell->start_pos); + gtkaspell_use_alternate_dict(gtkaspell); + misspelled = gtkaspell->ctx.check_word(gtkaspell->ctx.data); if (!gtkaspell->continue_check) { @@ -1302,7 +1312,7 @@ static void check_with_alternate_cb(GtkWidget *w, gpointer data) GSList *list, *cur; misspelled_suggest(gtkaspell, gtkaspell->theword); - set_textview_buffer_offset(gtkaspell->gtktext, + gtkaspell->ctx.set_position(gtkaspell->ctx.data, gtkaspell->end_pos); list = make_sug_menu(gtkaspell); @@ -1311,14 +1321,16 @@ static void check_with_alternate_cb(GtkWidget *w, gpointer data) gtk_menu_shell_append(GTK_MENU_SHELL(menu), GTK_WIDGET(cur->data)); g_slist_free(list); gtk_menu_popup(GTK_MENU(menu), NULL, NULL, - set_menu_pos, gtkaspell, 0, + gtkaspell->ctx.set_menu_pos, + gtkaspell->ctx.data, 0, GDK_CURRENT_TIME); g_signal_connect(G_OBJECT(menu), "deactivate", - G_CALLBACK(destroy_menu), + G_CALLBACK(destroy_menu), gtkaspell); g_signal_connect(G_OBJECT(menu), "key_press_event", - G_CALLBACK(aspell_key_pressed), gtkaspell); + G_CALLBACK(aspell_key_pressed), + gtkaspell); return; } } else @@ -1678,7 +1690,7 @@ gint gtkaspell_set_dictionary_menu_active_item(GtkComboBox *combo, return 0; } -static void use_alternate_dict(GtkAspell *gtkaspell) +void gtkaspell_use_alternate_dict(GtkAspell *gtkaspell) { GtkAspeller *tmp; @@ -1689,7 +1701,6 @@ static void use_alternate_dict(GtkAspell *gtkaspell) static void destroy_menu(GtkWidget *widget, gpointer user_data) { - GtkAspell *gtkaspell = (GtkAspell *)user_data; if (gtkaspell->accel_group) { @@ -2157,9 +2168,8 @@ static void change_dict_cb(GtkWidget *w, GtkAspell *gtkaspell) return; gtkaspell_change_dict(gtkaspell, fullname, TRUE); - if (gtkaspell->recheck_when_changing_dict) { - gtkaspell_highlight_all(gtkaspell); - } + gtkaspell_dict_changed(gtkaspell); + if (gtkaspell->menu_changed_cb) gtkaspell->menu_changed_cb(gtkaspell->menu_changed_data); } @@ -2168,10 +2178,9 @@ static void switch_to_alternate_cb(GtkWidget *w, gpointer data) { GtkAspell *gtkaspell = (GtkAspell *) data; - use_alternate_dict(gtkaspell); - if (gtkaspell->recheck_when_changing_dict) { - gtkaspell_highlight_all(gtkaspell); - } + gtkaspell_use_alternate_dict(gtkaspell); + gtkaspell_dict_changed(gtkaspell); + if (gtkaspell->menu_changed_cb) gtkaspell->menu_changed_cb(gtkaspell->menu_changed_data); } @@ -2184,10 +2193,10 @@ static void set_point_continue(GtkAspell *gtkaspell) gtktext = gtkaspell->gtktext; - set_textview_buffer_offset(gtktext, gtkaspell->orig_pos); + gtkaspell->ctx.set_position(gtkaspell->ctx.data, gtkaspell->orig_pos); if (gtkaspell->continue_check) - gtkaspell->continue_check((gpointer *) gtkaspell); + gtkaspell->continue_check((gpointer *) gtkaspell->ctx.data); } static void allocate_color(GtkAspell *gtkaspell, gint rgbvalue) @@ -2283,7 +2292,7 @@ static Dictionary *dictionary_dup(const Dictionary *dict) return dict2; } -static void free_suggestions_list(GtkAspell *gtkaspell) +void gtkaspell_free_suggestions_list(GtkAspell *gtkaspell) { GList *list; @@ -2304,7 +2313,7 @@ static void reset_theword_data(GtkAspell *gtkaspell) gtkaspell->theword[0] = 0; gtkaspell->max_sug = -1; - free_suggestions_list(gtkaspell); + gtkaspell_free_suggestions_list(gtkaspell); } static void free_checkers(gpointer elt, gpointer data) diff --git a/src/gtk/gtkaspell.h b/src/gtk/gtkaspell.h index 419e48812..e4b5c87a0 100644 --- a/src/gtk/gtkaspell.h +++ b/src/gtk/gtkaspell.h @@ -38,8 +38,71 @@ #ifdef USE_ENCHANT #include +#include + +#define GTKASPELLWORDSIZE 1024 + +typedef struct _Dictionary { + gchar *fullname; + gchar *dictname; +} Dictionary; + +typedef struct _GtkAspeller { + Dictionary *dictionary; + EnchantBroker *broker; + EnchantDict *speller; +} GtkAspeller; + +typedef void (*ContCheckFunc) (gpointer *gtkaspell); + +struct _WidgetContext +{ + void (*set_position)(gpointer data, gint pos); + void (*set_menu_pos)(GtkMenu *menu, gint *x, gint *y, + gboolean *push_in, gpointer user_data); + gboolean (*find_misspelled)(gpointer data, gboolean forward); + gboolean (*check_word)(gpointer data); + void (*replace_word)(gpointer data, const gchar *newword); + gpointer *data; +}; + +typedef struct _WidgetContext WidgetContext; + +struct _GtkAspell +{ + GtkAspeller *gtkaspeller; + GtkAspeller *alternate_speller; + gchar theword[GTKASPELLWORDSIZE]; + gint start_pos; + gint end_pos; + gint orig_pos; + gint end_check_pos; + gboolean misspelled; + gboolean check_while_typing; + gboolean recheck_when_changing_dict; + gboolean use_alternate; + gboolean use_both_dicts; + + ContCheckFunc continue_check; + + GtkWidget *replace_entry; + GtkWidget *parent_window; + + gint max_sug; + GList *suggestions_list; + + GtkTextView *gtktext; + GdkColor highlight; + GtkAccelGroup *accel_group; + void (*dict_changed_cb)(void *data); + void (*menu_changed_cb)(void *data); + void *menu_changed_data; + + WidgetContext ctx; +}; + +typedef struct _GtkAspell GtkAspell; -typedef struct _GtkAspell GtkAspell; /* Defined in gtkaspell.c */ void gtkaspell_checkers_init (void); @@ -59,6 +122,7 @@ GtkAspell* gtkaspell_new (const gchar *dictionary, gboolean use_both_dicts, GtkTextView *gtktext, GtkWindow *parent_win, + void (*dict_changed_cd)(void *data), void (*spell_menu_cb)(void *data), void *data); @@ -71,8 +135,10 @@ gboolean gtkaspell_change_dict (GtkAspell *gtkaspell, gboolean gtkaspell_change_alt_dict (GtkAspell *gtkaspell, const gchar* alt_dictionary); +void gtkaspell_use_alternate_dict (GtkAspell *gtkaspell); - +gboolean gtkaspell_check_next_prev (GtkAspell *gtkaspell, + gboolean forward); void gtkaspell_check_forwards_go (GtkAspell *gtkaspell); void gtkaspell_check_backwards (GtkAspell *gtkaspell); @@ -93,7 +159,17 @@ gint gtkaspell_set_dictionary_menu_active_item GSList* gtkaspell_make_config_menu (GtkAspell *gtkaspell); -gchar *gtkaspell_get_default_dictionary(GtkAspell *gtkaspell); +gchar* gtkaspell_get_default_dictionary (GtkAspell *gtkaspell); + +void gtkaspell_make_context_menu (GtkMenu *menu, + GtkAspell *gtkaspell); + +int gtkaspell_misspelled_test (GtkAspell *gtkaspell, + char *word); +void gtkaspell_dict_changed (GtkAspell *gtkaspell); +void gtkaspell_context_set (GtkAspell *gtkaspell); +void gtkaspell_free_suggestions_list (GtkAspell *gtkaspell); + #endif /* USE_ENCHANT */ #endif /* __GTKENCHANT_H__ */ -- 2.25.1