static void add_word_to_session (GtkWidget *w, GtkPspell *d);
static void add_word_to_personal (GtkWidget *w, GtkPspell *d);
static void set_sug_mode (GtkWidget *w, GtkPspell *gtkpspell);
+static void set_learn_mode (GtkWidget *w, GtkPspell *gtkpspell);
static void check_all (GtkWidget *w, GtkPspell *gtkpspell);
static void menu_change_dict (GtkWidget *w, GtkPspell *gtkpspell);
static void entry_insert_cb (GtkXText *gtktext, gchar *newtext,
guint len, guint *ppos,
GtkPspell *gtkpspell);
+static gint compare_dict (Dictionary *a, Dictionary *b);
+
/* gtkspellconfig - only one config per session */
GtkPspellConfig * gtkpspellconfig;
gtkpspell->path = NULL;
gtkpspell->dict = NULL;
gtkpspell->mode = PSPELL_FASTMODE;
+ gtkpspell->learn = TRUE;
gtkpspell->gtktext = NULL;
return gtkpspell;
}
gtkpspell->config = pspell_config_clone(gtkpspellconfig);
gtkpspell->mode = PSPELL_FASTMODE;
+ gtkpspell->learn = TRUE;
if (!set_path_and_dict(gtkpspell, gtkpspell->config, path, dict)) {
debug_print(_("Pspell could not be configured."));
GtkPspell *gtkpspell_delete( GtkPspell *gtkpspell )
{
if ( gtkpspell->checker ) {
+ /* First save all word lists */
+ pspell_manager_save_all_word_lists(gtkpspell->checker);
delete_pspell_manager(gtkpspell->checker);
gtkpspell->checker = NULL;
gtkpspell->possible_err = NULL; /* checker is a cast from possible_err */
/* pspell dict name format : */
/* <lang>[[-<spelling>[-<jargon>]]-<module>.pwli */
/* Strip off path */
-
- if (!strrchr(dict, G_DIR_SEPARATOR)) { /* plain dict name */
- strncpy(buf, dict, BUFSIZE - 1);
+
+ if (!strrchr(dict,G_DIR_SEPARATOR)) {
+ /* plain dict name */
+ strncpy(buf,dict,BUFSIZE-1);
}
- else { /* strip path */
- strncpy(buf, strrchr(dict, G_DIR_SEPARATOR) + 1, BUFSIZE - 1);
+ else {
+ /* strip path */
+ strncpy(buf, strrchr(dict, G_DIR_SEPARATOR)+1, BUFSIZE-1);
}
+
g_free(gtkpspell->dict);
/* Ensure no buffers overflows if the dict is to long */
- buf[BUFSIZE - 1] = 0x00;
-
+ buf[BUFSIZE-1] = 0x00;
+
language = buf;
- if ((module = strrchr(buf,'-')) != NULL) {
+ if ((module = strrchr(buf, '-')) != NULL) {
module++;
- if ((end = strrchr(module,'.')) != NULL)
- *end = 0;
+ if ((end = strrchr(module, '.')) != NULL)
+ end[0] = 0x00;
}
/* In tempdict, we have only the dict name, without path nor
- * extension. Useful in the popup menus */
+ extension. Useful in the popup menus */
tempdict = g_strdup(buf);
/* Probably I am too paranoied... */
- if (!( language[0] != 0x00 && language[1] != 0x00))
+ if (!(language[0] != 0x00 && language[1] != 0x00))
language = NULL;
else {
- spelling = strchr(language,'-');
- if (spelling!=NULL) {
- *spelling = 0;
+ spelling = strchr(language, '-');
+ if (spelling != NULL) {
+ spelling[0] = 0x00;
spelling++;
}
if (spelling != module) {
- if ((end = strchr(spelling, '-' )) != NULL) {
- *end = 0;
+ if ((end = strchr(spelling, '-')) != NULL) {
+ end[0] = 0x00;
jargon = end + 1;
if (jargon != module)
if ((end = strchr(jargon, '-')) != NULL)
- *end = 0;
+ end[0] = 0x00;
else
jargon = NULL;
else
debug_print(_("Language : %s\nSpelling: %s\nJargon: %s\nModule: %s\n"),
language, spelling, jargon, module);
-
+
if (language)
pspell_config_replace(config, "language-tag", language);
if (spelling)
g_free(temppath);
g_free(tempdict);
- return -1;
+ return TRUE;
}
+
/* gtkpspell_set_path_and_dict() - Set path and dict. The session is
* resetted.
- * 0 on error, -1 on success */
+ * FALSE on error, TRUE on success */
int gtkpspell_set_path_and_dict(GtkPspell * gtkpspell, guchar * path,
guchar * dict)
{
config2 = pspell_config_clone(gtkpspell->config);
- if (gtkpspell->checker)
+ if (gtkpspell->checker) {
+ pspell_manager_save_all_word_lists(gtkpspell->checker);
delete_pspell_manager(gtkpspell->checker);
+ }
gtkpspell->checker = NULL;
gtkpspell->possible_err = NULL;
if (set_path_and_dict(gtkpspell,config2,path,dict) == 0) {
debug_print(_("Pspell set_path_and_dict error."));
- return 0;
+ return FALSE;
}
gtkpspell->possible_err = new_pspell_manager(config2);
pspell_error_message(gtkpspell->possible_err));
delete_pspell_can_have_error(gtkpspell->possible_err);
gtkpspell->possible_err = NULL;
- return 0;
+ return FALSE;
}
gtkpspell->checker=to_pspell_manager(gtkpspell->possible_err);
- return -1;
+ return TRUE;
}
/* gtkpspell_get_dict() - What dict are we using ? language-spelling-jargon-module format */
guchar *path;
guchar *dict;
+ pspell_manager_save_all_word_lists(gtkpspell->checker);
delete_pspell_manager(gtkpspell->checker);
+
gtkpspell->checker = NULL;
config2 = pspell_config_clone(gtkpspell->config);
if (!set_path_and_dict(gtkpspell, config2, gtkpspell->path, gtkpspell->dict)) {
debug_print(_("Pspell set_sug_mod could not reset path & dict\n"));
- return 0;
+ return FALSE;
}
pspell_config_replace(config2, "sug-mode", themode);
pspell_error_message(gtkpspell->possible_err));
delete_pspell_can_have_error(gtkpspell->possible_err);
gtkpspell->possible_err = NULL;
- return 0;
+ return FALSE;
}
gtkpspell->checker = to_pspell_manager(gtkpspell->possible_err);
- return -1;
+ return TRUE;
+}
+
+/* set_learn_mode() - menu callback to toggle learn mode */
+static void set_learn_mode (GtkWidget *w, GtkPspell *gtkpspell)
+{
+ gtkpspell->learn = gtkpspell->learn == FALSE ;
}
/* misspelled_suggest() - Create a suggestion list for word */
return a;
}
+/* get_word_from_pos () - return the word pointed to. */
+/* Handles correctly the quotes. */
static gboolean get_word_from_pos(GtkPspell *gtkpspell, int pos,
unsigned char* buf,
int *pstart, int *pend)
{
- gint start, end;
+
+ /* TODO : when correcting a word into quotes, change the color of */
+ /* the quotes too, as may be they were highlighted before. To do */
+ /* so, we can use two others pointers that points to the whole */
+ /* word including quotes. */
+
+ gint start,
+ end;
+ guchar c;
GtkXText *gtktext;
gtktext = gtkpspell->gtktext;
if (iswordsep(get_text_index_whar(gtkpspell, pos)))
return FALSE;
-
+
+ /* The apostrophe character is somtimes used for quotes
+ * So include it in the word only if it is not surrounded
+ * by other characters.
+ */
+
for (start = pos; start >= 0; --start) {
- if (iswordsep(get_text_index_whar(gtkpspell, start)))
- break;
+ c = get_text_index_whar(gtkpspell, start);
+ if (c == '\'') {
+ if (start > 0) {
+ if (!isalpha(get_text_index_whar(gtkpspell, start - 1))) {
+ /* start_quote = TRUE; */
+ break;
+ }
+ }
+ else {
+ /* start_quote = TRUE; */
+ break;
+ }
+ }
+ else
+ if (!isalpha(c))
+ break;
}
start++;
for (end = pos; end < gtk_xtext_get_length(gtktext); end++) {
- if (iswordsep(get_text_index_whar(gtkpspell, end)))
- break;
+ c = get_text_index_whar(gtkpspell, end);
+ if (c == '\'') {
+ if (end < gtk_xtext_get_length(gtktext)) {
+ if (!isalpha(get_text_index_whar(gtkpspell, end + 1))) {
+ /* end_quote = TRUE; */
+ break;
+ }
+ }
+ else {
+ /* end_quote = TRUE; */
+ break;
+ }
+ }
+ else
+ if(!isalpha(c))
+ break;
}
-
+
if (buf) {
for (pos = start; pos < end; pos++)
buf[pos - start] = get_text_index_whar(gtkpspell, pos);
g_return_val_if_fail(from_pos >= 0, FALSE);
gtktext = gtkpspell->gtktext;
+
if (!get_word_from_pos(gtkpspell, from_pos, buf, &start, &end))
return FALSE;
+
strncpy(gtkpspell->theword, buf, BUFSIZE - 1);
gtkpspell->theword[BUFSIZE - 1] = 0;
void gtkpspell_check_all(GtkPspell *gtkpspell)
{
- guint origpos;
- guint pos = 0;
- guint len;
- float adj_value;
+ guint origpos;
+ guint pos = 0;
+ guint len;
+ float adj_value;
GtkXText *gtktext;
guint len, guint *ppos,
GtkPspell * gtkpspell)
{
+ guint origpos;
if (!gtkpspell_running(gtkpspell))
return;
+ /* We must insert ourself the character to impose the */
+ /* color of the inserted character to be default */
+ /* Never mess with set_insertion when frozen */
+ gtk_xtext_freeze(gtktext);
+ gtk_xtext_backward_delete(GTK_XTEXT(gtktext), len);
+ gtk_xtext_insert(GTK_XTEXT(gtktext), NULL,
+ &(GTK_WIDGET(gtktext)->style->fg[0]), NULL, newtext, len);
+ *ppos = gtk_xtext_get_point(GTK_XTEXT(gtktext));
+
if (iswordsep(newtext[0])) {
/* did we just end a word? */
if (*ppos >= 2)
&& !iswordsep(get_text_index_whar(gtkpspell, *ppos)))
check_at(gtkpspell, *ppos - 1);
}
-
+ gtk_xtext_thaw(gtktext);
+ gtk_editable_set_position(GTK_EDITABLE(gtktext), *ppos);
}
static void entry_delete_cb(GtkXText *gtktext, gint start, gint end,
return;
origpos = gtk_editable_get_position(GTK_EDITABLE(gtktext));
- check_at(gtkpspell, start - 1);
+ if (start)
+ check_at(gtkpspell, start - 1);
gtk_editable_set_position(GTK_EDITABLE(gtktext), origpos);
gtk_editable_select_region(GTK_EDITABLE(gtktext), origpos, origpos);
/* this is to *UNDO* the selection, in case they were holding shift
gtk_xtext_backward_delete(GTK_XTEXT(gtktext), end - start);
gtk_xtext_insert(GTK_XTEXT(gtktext), NULL, NULL, NULL, newword, strlen(newword));
-#if 0
- if(end-start>0 /*&& gtkpspell->learn*/){
- buf[end-start]=0x00; /* Just be sure the buffer is correct... */
- /* Learn from common misspellings */
- pspell_manager_store_replacement(gtkpspell->checker,buf,end-start,
- newword,strlen(newword));
- }
-#endif
+ if (end-start > 0 && gtkpspell->learn) {
+ /* Just be sure the buffer ends somewhere... */
+ buf[end-start] = 0;
+ /* Learn from common misspellings */
+ pspell_manager_store_replacement(gtkpspell->checker, buf,
+ end-start, newword,
+ strlen(newword));
+ }
/* Put the point and the position where we clicked with the mouse */
/* It seems to be a hack, as I must thaw,freeze,thaw the widget */
gtk_xtext_thaw(GTK_XTEXT(gtkxtext));
}
-/* add_word_to_personal() - add word to personal dict. Save the list at every addition (may be
- * not efficient...) */
+/* add_word_to_personal() - add word to personal dict. */
static void add_word_to_personal(GtkWidget *w, GtkPspell *gtkpspell)
{
pos = gtk_editable_get_position(GTK_EDITABLE(gtkxtext));
pspell_manager_add_to_personal(gtkpspell->checker,gtkpspell->theword,strlen(gtkpspell->theword));
- pspell_manager_save_all_word_lists(gtkpspell->checker);
check_at(gtkpspell,gtk_editable_get_position(GTK_EDITABLE(gtkxtext)));
gtk_xtext_thaw(GTK_XTEXT(gtkxtext));
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),TRUE);
}
else
- gtk_signal_connect(GTK_OBJECT(item),"activate",
+ gtk_signal_connect(GTK_OBJECT(item), "activate",
GTK_SIGNAL_FUNC(set_sug_mode),
gtkpspell);
item = gtk_check_menu_item_new_with_label(_("Bad Spellers Mode"));
gtk_widget_show(item);
- gtk_menu_append(GTK_MENU(menu),item);
+ gtk_menu_append(GTK_MENU(menu), item);
if (gtkpspell->mode==PSPELL_BADSPELLERMODE) {
gtk_widget_set_sensitive(GTK_WIDGET(item), FALSE);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
}
else
- gtk_signal_connect(GTK_OBJECT(item),"activate",
+ gtk_signal_connect(GTK_OBJECT(item), "activate",
GTK_SIGNAL_FUNC(set_sug_mode),
gtkpspell);
+ item = gtk_menu_item_new();
+ gtk_widget_show(item);
+ gtk_menu_append(GTK_MENU(menu), item);
+ item = gtk_check_menu_item_new_with_label(_("Learn from mistakes"));
+ gtk_widget_show(item);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
+ gtkpspell->learn);
+ gtk_signal_connect(GTK_OBJECT(item), "activate",
+ GTK_SIGNAL_FUNC(set_learn_mode), gtkpspell);
+
+
return GTK_MENU(menu);
}
void gtkpspell_attach(GtkPspell *gtkpspell, GtkXText *gtktext)
{
gtkpspell->gtktext=gtktext;
-/* if (prefs_common.auto_makepspell) { */
- gtk_signal_connect(GTK_OBJECT(gtktext), "insert-text",
+ gtk_signal_connect_after(GTK_OBJECT(gtktext), "insert-text",
GTK_SIGNAL_FUNC(entry_insert_cb), gtkpspell);
gtk_signal_connect_after(GTK_OBJECT(gtktext), "delete-text",
GTK_SIGNAL_FUNC(entry_delete_cb), gtkpspell);
-/* }; */
gtk_signal_connect(GTK_OBJECT(gtktext), "button-press-event",
GTK_SIGNAL_FUNC(button_press_intercept_cb), gtkpspell);
dict = g_new0(Dictionary, 1);
dict->name = g_strndup(ent->d_name, tmp - ent->d_name);
debug_print(_("Found dictionary %s\n"), dict->name);
- list = g_slist_append(list, dict);
+ list = g_slist_insert_sorted(list, dict, (GCompareFunc) compare_dict);
}
}
closedir(dir);
return list;
}
+/* compare_dict () - compare 2 dict names */
+
+static gint compare_dict(Dictionary *a, Dictionary *b)
+{
+ guchar *alanguage, *blanguage,
+ *aspelling, *bspelling,
+ *ajargon , *bjargon ,
+ *amodule , *bmodule ;
+ guint aparts = 0, bparts = 0, i;
+
+ for (i=0; i < strlen(a->name) ; i++)
+ if (a->name[i]=='-')
+ aparts++;
+ for (i=0; i < strlen(b->name) ; i++)
+ if (b->name[i]=='-')
+ bparts++;
+
+ if (aparts != bparts)
+ return (aparts < bparts) ? -1 : +1 ;
+ else
+ return strcmp2(a->name, b->name);
+}
void gtkpspell_free_dictionary_list(GSList *list)
{
Dictionary *dict;