|
|
| |
#define GTKSPELL_MISSPELLED_TAG "gtkspell-misspelled" | #define GTKSPELL_MISSPELLED_TAG "gtkspell-misspelled" |
| |
#ifdef HAVE_ASPELL_H |
#include <enchant.h> |
#define USING_ASPELL |
|
#include <aspell.h> |
/* prepare for gettext internationalization */ |
#elif defined HAVE_PSPELL_H |
#undef _ |
#define USING_PSPELL |
#define _(x) x |
#include <pspell/pspell.h> |
|
#define AspellSpeller PspellManager |
|
#define speller manager |
|
#define aspell_speller_check pspell_manager_check |
|
#define aspell_speller_add_to_session pspell_manager_add_to_session |
|
#define aspell_speller_add_to_personal pspell_manager_add_to_personal |
|
#define aspell_speller_save_all_word_lists pspell_manager_save_all_word_lists |
|
#define aspell_speller_store_replacement pspell_manager_store_replacement |
|
#define AspellWordList PspellWordList |
|
#define AspellStringEnumeration PspellStringEmulation |
|
#define aspell_speller_suggest pspell_manager_suggest |
|
#define aspell_word_list_elements pspell_word_list_elements |
|
#define aspell_string_enumeration_next pspell_string_emulation_next |
|
#define delete_aspell_string_enumeration delete_pspell_string_emulation |
|
#define AspellConfig PspellConfig |
|
#define AspellCanHaveError PspellCanHaveError |
|
#define new_aspell_config new_pspell_config |
|
#define aspell_config_replace pspell_config_replace |
|
#define new_aspell_speller new_pspell_manager |
|
#define delete_aspell_config delete_pspell_config |
|
#define aspell_error_message pspell_error_message |
|
#define delete_aspell_speller delete_pspell_manager |
|
#define to_aspell_speller to_pspell_manager |
|
#define aspell_error_number pspell_error_number |
|
#define aspell pspell |
|
#endif |
|
| |
const int debug = 0; | const int debug = 0; |
const int quiet = 0; | const int quiet = 0; |
|
|
GtkTextMark *mark_insert_start; | GtkTextMark *mark_insert_start; |
GtkTextMark *mark_insert_end; | GtkTextMark *mark_insert_end; |
gboolean deferred_check; | gboolean deferred_check; |
AspellSpeller *speller; |
EnchantBroker *broker; |
|
EnchantDict *speller; |
GtkTextMark *mark_click; | GtkTextMark *mark_click; |
}; | }; |
| |
|
|
check_word(GtkSpell *spell, GtkTextBuffer *buffer, | check_word(GtkSpell *spell, GtkTextBuffer *buffer, |
GtkTextIter *start, GtkTextIter *end) { | GtkTextIter *start, GtkTextIter *end) { |
char *text; | char *text; |
|
if (!spell->speller) |
|
return; |
text = gtk_text_buffer_get_text(buffer, start, end, FALSE); | text = gtk_text_buffer_get_text(buffer, start, end, FALSE); |
if (debug) g_print("checking: %s\n", text); | if (debug) g_print("checking: %s\n", text); |
if (g_unichar_isdigit(*text) == FALSE) /* don't check numbers */ | if (g_unichar_isdigit(*text) == FALSE) /* don't check numbers */ |
if (aspell_speller_check(spell->speller, text, -1) == FALSE) |
if (enchant_dict_check(spell->speller, text, strlen(text)) != 0) |
gtk_text_buffer_apply_tag(buffer, spell->tag_highlight, start, end); | gtk_text_buffer_apply_tag(buffer, spell->tag_highlight, start, end); |
g_free(text); | g_free(text); |
} | } |
|
|
get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); | get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); |
word = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); | word = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); |
| |
aspell_speller_add_to_personal(spell->speller, word, strlen(word)); |
enchant_dict_add_to_personal( spell->speller, word, strlen(word)); |
aspell_speller_save_all_word_lists(spell->speller); |
|
| |
gtkspell_recheck_all(spell); | gtkspell_recheck_all(spell); |
| |
|
|
get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); | get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); |
word = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); | word = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); |
| |
aspell_speller_add_to_session(spell->speller, word, strlen(word)); |
enchant_dict_add_to_session(spell->speller, word, strlen(word)); |
| |
gtkspell_recheck_all(spell); | gtkspell_recheck_all(spell); |
| |
|
|
GtkTextIter start, end; | GtkTextIter start, end; |
GtkTextBuffer *buffer; | GtkTextBuffer *buffer; |
| |
|
if (!spell->speller) |
|
return; |
|
|
buffer = gtk_text_view_get_buffer(spell->view); | buffer = gtk_text_view_get_buffer(spell->view); |
| |
get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); | get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); |
|
|
gtk_text_buffer_delete(buffer, &start, &end); | gtk_text_buffer_delete(buffer, &start, &end); |
gtk_text_buffer_insert(buffer, &start, newword, -1); | gtk_text_buffer_insert(buffer, &start, newword, -1); |
| |
aspell_speller_store_replacement(spell->speller, |
enchant_dict_store_replacement(spell->speller, |
oldword, strlen(oldword), | oldword, strlen(oldword), |
newword, strlen(newword)); | newword, strlen(newword)); |
| |
g_free(oldword); | g_free(oldword); |
} | } |
| |
GtkWidget* |
static GtkWidget* |
build_suggestion_menu(GtkSpell *spell, GtkTextBuffer *buffer, | build_suggestion_menu(GtkSpell *spell, GtkTextBuffer *buffer, |
const char *word) { | const char *word) { |
const char *suggestion; | const char *suggestion; |
GtkWidget *topmenu, *menu; | GtkWidget *topmenu, *menu; |
GtkWidget *mi; | GtkWidget *mi; |
GtkWidget *hbox; | GtkWidget *hbox; |
int count = 0; |
|
void *spelldata; | void *spelldata; |
const AspellWordList *suggestions; |
char **suggestions; |
AspellStringEnumeration *elements; |
size_t n_suggs, i; |
char *label; | char *label; |
| |
topmenu = menu = gtk_menu_new(); | topmenu = menu = gtk_menu_new(); |
| |
suggestions = aspell_speller_suggest(spell->speller, word, -1); |
if (!spell->speller) |
elements = aspell_word_list_elements(suggestions); |
return topmenu; |
| |
suggestion = aspell_string_enumeration_next(elements); |
suggestions = enchant_dict_suggest(spell->speller, word, strlen(word), &n_suggs); |
if (suggestion == NULL) { |
|
|
if (suggestions == NULL || !n_suggs) { |
/* no suggestions. put something in the menu anyway... */ | /* no suggestions. put something in the menu anyway... */ |
GtkWidget *label; | GtkWidget *label; |
label = gtk_label_new(""); | label = gtk_label_new(""); |
|
|
gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), mi); | gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), mi); |
} else { | } else { |
/* build a set of menus with suggestions. */ | /* build a set of menus with suggestions. */ |
while (suggestion != NULL) { |
for (i = 0; i < n_suggs; i++ ) { |
if (count == 10) { |
if (i > 0 && i % 10 == 0) { |
mi = gtk_menu_item_new(); | mi = gtk_menu_item_new(); |
gtk_widget_show(mi); | gtk_widget_show(mi); |
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); | gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); |
|
|
| |
menu = gtk_menu_new(); | menu = gtk_menu_new(); |
gtk_menu_item_set_submenu(GTK_MENU_ITEM(mi), menu); | gtk_menu_item_set_submenu(GTK_MENU_ITEM(mi), menu); |
count = 0; |
|
} | } |
mi = gtk_menu_item_new_with_label(suggestion); |
mi = gtk_menu_item_new_with_label(suggestions[i]); |
g_signal_connect(G_OBJECT(mi), "activate", | g_signal_connect(G_OBJECT(mi), "activate", |
G_CALLBACK(replace_word), spell); | G_CALLBACK(replace_word), spell); |
gtk_widget_show(mi); | gtk_widget_show(mi); |
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); | gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); |
count++; |
|
suggestion = aspell_string_enumeration_next(elements); |
|
} | } |
} | } |
| |
delete_aspell_string_enumeration(elements); |
enchant_dict_free_suggestions(spell->speller, suggestions); |
| |
/* Separator */ | /* Separator */ |
mi = gtk_menu_item_new(); | mi = gtk_menu_item_new(); |
|
|
| |
static gboolean | static gboolean |
gtkspell_set_language_internal(GtkSpell *spell, const gchar *lang, GError **error) { | gtkspell_set_language_internal(GtkSpell *spell, const gchar *lang, GError **error) { |
AspellConfig *config; |
|
AspellCanHaveError *err; |
|
AspellSpeller *speller; |
|
| |
if (lang == NULL) { | if (lang == NULL) { |
lang = g_getenv("LANG"); | lang = g_getenv("LANG"); |
|
|
} | } |
} | } |
| |
config = new_aspell_config(); |
if (!spell->broker) |
if (lang) |
spell->broker = enchant_broker_init(); |
aspell_config_replace(config, "language-tag", lang); |
|
aspell_config_replace(config, "encoding", "utf-8"); |
|
err = new_aspell_speller(config); |
|
delete_aspell_config(config); |
|
| |
if (aspell_error_number(err) != 0) { |
if (spell->speller) { |
#ifdef USING_ASPELL |
enchant_broker_free_dict(spell->broker, spell->speller); |
g_set_error(error, GTKSPELL_ERROR, GTKSPELL_ERROR_BACKEND, |
spell->speller = NULL; |
"aspell: %s", aspell_error_message(err)); |
} |
#elif defined USING_PSPELL |
|
|
if (!lang) { |
|
lang = "en"; |
|
} |
|
|
|
spell->speller = enchant_broker_request_dict(spell->broker, lang ); |
|
|
|
if (!spell->speller) { |
g_set_error(error, GTKSPELL_ERROR, GTKSPELL_ERROR_BACKEND, | g_set_error(error, GTKSPELL_ERROR, GTKSPELL_ERROR_BACKEND, |
"pspell: %s", aspell_error_message(err)); |
_("enchant error for language: %s"),lang); |
#endif |
|
return FALSE; | return FALSE; |
} | } |
if (spell->speller) |
|
delete_aspell_speller(spell->speller); |
|
spell->speller = to_aspell_speller(err); |
|
| |
return TRUE; | return TRUE; |
} | } |
|
|
gtk_text_buffer_delete_mark(buffer, spell->mark_insert_end); | gtk_text_buffer_delete_mark(buffer, spell->mark_insert_end); |
gtk_text_buffer_delete_mark(buffer, spell->mark_click); | gtk_text_buffer_delete_mark(buffer, spell->mark_click); |
| |
delete_aspell_speller(spell->speller); |
|
| |
|
if (spell->broker) { |
|
if (spell->speller) { |
|
enchant_broker_free_dict(spell->broker, spell->speller); |
|
} |
|
enchant_broker_free(spell->broker); |
|
} |
g_signal_handlers_disconnect_matched(spell->view, | g_signal_handlers_disconnect_matched(spell->view, |
G_SIGNAL_MATCH_DATA, | G_SIGNAL_MATCH_DATA, |
0, 0, NULL, NULL, | 0, 0, NULL, NULL, |