|
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_personal( 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 > 0 && 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, |