Lines 14-50
Link Here
|
14 |
|
14 |
|
15 |
#define GTKSPELL_MISSPELLED_TAG "gtkspell-misspelled" |
15 |
#define GTKSPELL_MISSPELLED_TAG "gtkspell-misspelled" |
16 |
|
16 |
|
17 |
#ifdef HAVE_ASPELL_H |
17 |
#include <enchant.h> |
18 |
#define USING_ASPELL |
18 |
|
19 |
#include <aspell.h> |
19 |
/* prepare for gettext internationalization */ |
20 |
#elif defined HAVE_PSPELL_H |
20 |
#undef _ |
21 |
#define USING_PSPELL |
21 |
#define _(x) x |
22 |
#include <pspell/pspell.h> |
|
|
23 |
#define AspellSpeller PspellManager |
24 |
#define speller manager |
25 |
#define aspell_speller_check pspell_manager_check |
26 |
#define aspell_speller_add_to_session pspell_manager_add_to_session |
27 |
#define aspell_speller_add_to_personal pspell_manager_add_to_personal |
28 |
#define aspell_speller_save_all_word_lists pspell_manager_save_all_word_lists |
29 |
#define aspell_speller_store_replacement pspell_manager_store_replacement |
30 |
#define AspellWordList PspellWordList |
31 |
#define AspellStringEnumeration PspellStringEmulation |
32 |
#define aspell_speller_suggest pspell_manager_suggest |
33 |
#define aspell_word_list_elements pspell_word_list_elements |
34 |
#define aspell_string_enumeration_next pspell_string_emulation_next |
35 |
#define delete_aspell_string_enumeration delete_pspell_string_emulation |
36 |
#define AspellConfig PspellConfig |
37 |
#define AspellCanHaveError PspellCanHaveError |
38 |
#define new_aspell_config new_pspell_config |
39 |
#define aspell_config_replace pspell_config_replace |
40 |
#define new_aspell_speller new_pspell_manager |
41 |
#define delete_aspell_config delete_pspell_config |
42 |
#define aspell_error_message pspell_error_message |
43 |
#define delete_aspell_speller delete_pspell_manager |
44 |
#define to_aspell_speller to_pspell_manager |
45 |
#define aspell_error_number pspell_error_number |
46 |
#define aspell pspell |
47 |
#endif |
48 |
|
22 |
|
49 |
const int debug = 0; |
23 |
const int debug = 0; |
50 |
const int quiet = 0; |
24 |
const int quiet = 0; |
Lines 55-61
Link Here
|
55 |
GtkTextMark *mark_insert_start; |
29 |
GtkTextMark *mark_insert_start; |
56 |
GtkTextMark *mark_insert_end; |
30 |
GtkTextMark *mark_insert_end; |
57 |
gboolean deferred_check; |
31 |
gboolean deferred_check; |
58 |
AspellSpeller *speller; |
32 |
EnchantBroker *broker; |
|
|
33 |
EnchantDict *speller; |
59 |
GtkTextMark *mark_click; |
34 |
GtkTextMark *mark_click; |
60 |
}; |
35 |
}; |
61 |
|
36 |
|
Lines 126-135
Link Here
|
126 |
check_word(GtkSpell *spell, GtkTextBuffer *buffer, |
101 |
check_word(GtkSpell *spell, GtkTextBuffer *buffer, |
127 |
GtkTextIter *start, GtkTextIter *end) { |
102 |
GtkTextIter *start, GtkTextIter *end) { |
128 |
char *text; |
103 |
char *text; |
|
|
104 |
if (!spell->speller) |
105 |
return; |
129 |
text = gtk_text_buffer_get_text(buffer, start, end, FALSE); |
106 |
text = gtk_text_buffer_get_text(buffer, start, end, FALSE); |
130 |
if (debug) g_print("checking: %s\n", text); |
107 |
if (debug) g_print("checking: %s\n", text); |
131 |
if (g_unichar_isdigit(*text) == FALSE) /* don't check numbers */ |
108 |
if (g_unichar_isdigit(*text) == FALSE) /* don't check numbers */ |
132 |
if (aspell_speller_check(spell->speller, text, -1) == FALSE) |
109 |
if (enchant_dict_check(spell->speller, text, strlen(text)) != 0) |
133 |
gtk_text_buffer_apply_tag(buffer, spell->tag_highlight, start, end); |
110 |
gtk_text_buffer_apply_tag(buffer, spell->tag_highlight, start, end); |
134 |
g_free(text); |
111 |
g_free(text); |
135 |
} |
112 |
} |
Lines 304-311
Link Here
|
304 |
get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); |
281 |
get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); |
305 |
word = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); |
282 |
word = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); |
306 |
|
283 |
|
307 |
aspell_speller_add_to_personal(spell->speller, word, strlen(word)); |
284 |
enchant_dict_add_to_pwl( spell->speller, word, strlen(word)); |
308 |
aspell_speller_save_all_word_lists(spell->speller); |
|
|
309 |
|
285 |
|
310 |
gtkspell_recheck_all(spell); |
286 |
gtkspell_recheck_all(spell); |
311 |
|
287 |
|
Lines 323-329
Link Here
|
323 |
get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); |
299 |
get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); |
324 |
word = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); |
300 |
word = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); |
325 |
|
301 |
|
326 |
aspell_speller_add_to_session(spell->speller, word, strlen(word)); |
302 |
enchant_dict_add_to_session(spell->speller, word, strlen(word)); |
327 |
|
303 |
|
328 |
gtkspell_recheck_all(spell); |
304 |
gtkspell_recheck_all(spell); |
329 |
|
305 |
|
Lines 337-342
Link Here
|
337 |
GtkTextIter start, end; |
313 |
GtkTextIter start, end; |
338 |
GtkTextBuffer *buffer; |
314 |
GtkTextBuffer *buffer; |
339 |
|
315 |
|
|
|
316 |
if (!spell->speller) |
317 |
return; |
318 |
|
340 |
buffer = gtk_text_view_get_buffer(spell->view); |
319 |
buffer = gtk_text_view_get_buffer(spell->view); |
341 |
|
320 |
|
342 |
get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); |
321 |
get_word_extents_from_mark(buffer, &start, &end, spell->mark_click); |
Lines 352-384
Link Here
|
352 |
gtk_text_buffer_delete(buffer, &start, &end); |
331 |
gtk_text_buffer_delete(buffer, &start, &end); |
353 |
gtk_text_buffer_insert(buffer, &start, newword, -1); |
332 |
gtk_text_buffer_insert(buffer, &start, newword, -1); |
354 |
|
333 |
|
355 |
aspell_speller_store_replacement(spell->speller, |
334 |
enchant_dict_store_replacement(spell->speller, |
356 |
oldword, strlen(oldword), |
335 |
oldword, strlen(oldword), |
357 |
newword, strlen(newword)); |
336 |
newword, strlen(newword)); |
358 |
|
337 |
|
359 |
g_free(oldword); |
338 |
g_free(oldword); |
360 |
} |
339 |
} |
361 |
|
340 |
|
362 |
GtkWidget* |
341 |
static GtkWidget* |
363 |
build_suggestion_menu(GtkSpell *spell, GtkTextBuffer *buffer, |
342 |
build_suggestion_menu(GtkSpell *spell, GtkTextBuffer *buffer, |
364 |
const char *word) { |
343 |
const char *word) { |
365 |
const char *suggestion; |
344 |
const char *suggestion; |
366 |
GtkWidget *topmenu, *menu; |
345 |
GtkWidget *topmenu, *menu; |
367 |
GtkWidget *mi; |
346 |
GtkWidget *mi; |
368 |
GtkWidget *hbox; |
347 |
GtkWidget *hbox; |
369 |
int count = 0; |
|
|
370 |
void *spelldata; |
348 |
void *spelldata; |
371 |
const AspellWordList *suggestions; |
349 |
char **suggestions; |
372 |
AspellStringEnumeration *elements; |
350 |
size_t n_suggs, i; |
373 |
char *label; |
351 |
char *label; |
374 |
|
352 |
|
375 |
topmenu = menu = gtk_menu_new(); |
353 |
topmenu = menu = gtk_menu_new(); |
376 |
|
354 |
|
377 |
suggestions = aspell_speller_suggest(spell->speller, word, -1); |
355 |
if (!spell->speller) |
378 |
elements = aspell_word_list_elements(suggestions); |
356 |
return topmenu; |
379 |
|
357 |
|
380 |
suggestion = aspell_string_enumeration_next(elements); |
358 |
suggestions = enchant_dict_suggest(spell->speller, word, strlen(word), &n_suggs); |
381 |
if (suggestion == NULL) { |
359 |
|
|
|
360 |
if (suggestions == NULL || !n_suggs) { |
382 |
/* no suggestions. put something in the menu anyway... */ |
361 |
/* no suggestions. put something in the menu anyway... */ |
383 |
GtkWidget *label; |
362 |
GtkWidget *label; |
384 |
label = gtk_label_new(""); |
363 |
label = gtk_label_new(""); |
Lines 390-397
Link Here
|
390 |
gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), mi); |
369 |
gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), mi); |
391 |
} else { |
370 |
} else { |
392 |
/* build a set of menus with suggestions. */ |
371 |
/* build a set of menus with suggestions. */ |
393 |
while (suggestion != NULL) { |
372 |
for (i = 0; i < n_suggs; i++ ) { |
394 |
if (count == 10) { |
373 |
if (i % 10 == 0) { |
395 |
mi = gtk_menu_item_new(); |
374 |
mi = gtk_menu_item_new(); |
396 |
gtk_widget_show(mi); |
375 |
gtk_widget_show(mi); |
397 |
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); |
376 |
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); |
Lines 402-420
Link Here
|
402 |
|
381 |
|
403 |
menu = gtk_menu_new(); |
382 |
menu = gtk_menu_new(); |
404 |
gtk_menu_item_set_submenu(GTK_MENU_ITEM(mi), menu); |
383 |
gtk_menu_item_set_submenu(GTK_MENU_ITEM(mi), menu); |
405 |
count = 0; |
|
|
406 |
} |
384 |
} |
407 |
mi = gtk_menu_item_new_with_label(suggestion); |
385 |
mi = gtk_menu_item_new_with_label(suggestions[i]); |
408 |
g_signal_connect(G_OBJECT(mi), "activate", |
386 |
g_signal_connect(G_OBJECT(mi), "activate", |
409 |
G_CALLBACK(replace_word), spell); |
387 |
G_CALLBACK(replace_word), spell); |
410 |
gtk_widget_show(mi); |
388 |
gtk_widget_show(mi); |
411 |
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); |
389 |
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); |
412 |
count++; |
|
|
413 |
suggestion = aspell_string_enumeration_next(elements); |
414 |
} |
390 |
} |
415 |
} |
391 |
} |
416 |
|
392 |
|
417 |
delete_aspell_string_enumeration(elements); |
393 |
enchant_dict_free_suggestions(spell->speller, suggestions); |
418 |
|
394 |
|
419 |
/* Separator */ |
395 |
/* Separator */ |
420 |
mi = gtk_menu_item_new(); |
396 |
mi = gtk_menu_item_new(); |
Lines 519-527
Link Here
|
519 |
|
495 |
|
520 |
static gboolean |
496 |
static gboolean |
521 |
gtkspell_set_language_internal(GtkSpell *spell, const gchar *lang, GError **error) { |
497 |
gtkspell_set_language_internal(GtkSpell *spell, const gchar *lang, GError **error) { |
522 |
AspellConfig *config; |
|
|
523 |
AspellCanHaveError *err; |
524 |
AspellSpeller *speller; |
525 |
|
498 |
|
526 |
if (lang == NULL) { |
499 |
if (lang == NULL) { |
527 |
lang = g_getenv("LANG"); |
500 |
lang = g_getenv("LANG"); |
Lines 533-558
Link Here
|
533 |
} |
506 |
} |
534 |
} |
507 |
} |
535 |
|
508 |
|
536 |
config = new_aspell_config(); |
509 |
if (!spell->broker) |
537 |
if (lang) |
510 |
spell->broker = enchant_broker_init(); |
538 |
aspell_config_replace(config, "language-tag", lang); |
|
|
539 |
aspell_config_replace(config, "encoding", "utf-8"); |
540 |
err = new_aspell_speller(config); |
541 |
delete_aspell_config(config); |
542 |
|
511 |
|
543 |
if (aspell_error_number(err) != 0) { |
512 |
if (spell->speller) { |
544 |
#ifdef USING_ASPELL |
513 |
enchant_broker_free_dict(spell->broker, spell->speller); |
545 |
g_set_error(error, GTKSPELL_ERROR, GTKSPELL_ERROR_BACKEND, |
514 |
spell->speller = NULL; |
546 |
"aspell: %s", aspell_error_message(err)); |
515 |
} |
547 |
#elif defined USING_PSPELL |
516 |
|
|
|
517 |
if (!lang) { |
518 |
lang = "en"; |
519 |
} |
520 |
|
521 |
spell->speller = enchant_broker_request_dict(spell->broker, lang ); |
522 |
|
523 |
if (!spell->speller) { |
548 |
g_set_error(error, GTKSPELL_ERROR, GTKSPELL_ERROR_BACKEND, |
524 |
g_set_error(error, GTKSPELL_ERROR, GTKSPELL_ERROR_BACKEND, |
549 |
"pspell: %s", aspell_error_message(err)); |
525 |
_("enchant error for language: %s"),lang); |
550 |
#endif |
|
|
551 |
return FALSE; |
526 |
return FALSE; |
552 |
} |
527 |
} |
553 |
if (spell->speller) |
|
|
554 |
delete_aspell_speller(spell->speller); |
555 |
spell->speller = to_aspell_speller(err); |
556 |
|
528 |
|
557 |
return TRUE; |
529 |
return TRUE; |
558 |
} |
530 |
} |
Lines 715-722
Link Here
|
715 |
gtk_text_buffer_delete_mark(buffer, spell->mark_insert_end); |
687 |
gtk_text_buffer_delete_mark(buffer, spell->mark_insert_end); |
716 |
gtk_text_buffer_delete_mark(buffer, spell->mark_click); |
688 |
gtk_text_buffer_delete_mark(buffer, spell->mark_click); |
717 |
|
689 |
|
718 |
delete_aspell_speller(spell->speller); |
|
|
719 |
|
690 |
|
|
|
691 |
if (spell->broker) { |
692 |
if (spell->speller) { |
693 |
enchant_broker_free_dict(spell->broker, spell->speller); |
694 |
} |
695 |
enchant_broker_free(spell->broker); |
696 |
} |
720 |
g_signal_handlers_disconnect_matched(spell->view, |
697 |
g_signal_handlers_disconnect_matched(spell->view, |
721 |
G_SIGNAL_MATCH_DATA, |
698 |
G_SIGNAL_MATCH_DATA, |
722 |
0, 0, NULL, NULL, |
699 |
0, 0, NULL, NULL, |