From 6de30e71829d78382399873a444eb409c436ffbe Mon Sep 17 00:00:00 2001 From: Alfons Hoogervorst Date: Tue, 31 Jul 2001 17:33:35 +0000 Subject: [PATCH] add global setting stuff for spelling checker; 'nother 20% done --- ChangeLog.claws | 12 ++- acconfig.h | 3 + configure.in | 11 +++ src/Makefile.am | 3 +- src/gtkspell.c | 149 +++++++++++++++++++++++++++++++++++++ src/gtkspell.h | 16 +++- src/mainwindow.c | 1 + src/prefs_common.c | 180 +++++++++++++++++++++++++++++++++++++++++++++ src/prefs_common.h | 3 + 9 files changed, 374 insertions(+), 4 deletions(-) diff --git a/ChangeLog.claws b/ChangeLog.claws index 59ce12c1d..8ffedaa7e 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,13 @@ +2001-07-31 [alfons] + + * src/prefs_common.c, src/prefs_common.h, + src/gtkspell.c, src/gtkspell.h + add global spelling checker settings (compose tab) + + selection of dictionary + + * configure.in + guess valid ispell location + 2001-07-31 [paul] * po/POTFILES.in @@ -6,7 +16,6 @@ Updated de.po (submitted by Jens Oberender ) - 2001-07-31 [darko] * src/folder.[ch] @@ -40,6 +49,7 @@ updated (submitted by Fabio Junior Beneditto) +>>>>>>> 1.258 2001-07-28 [paul] * src/procmime.c diff --git a/acconfig.h b/acconfig.h index 6bd4cdf82..3194d263a 100644 --- a/acconfig.h +++ b/acconfig.h @@ -37,3 +37,6 @@ #undef VERSION #undef CLAWS + +/* Has ispell path */ +#undef ISPELL_PATH diff --git a/configure.in b/configure.in index 81b563b1c..576b101bc 100644 --- a/configure.in +++ b/configure.in @@ -186,6 +186,17 @@ else AC_MSG_RESULT(no) fi +dnl get ispell path +dnl +AC_PATH_PROG(ispell_path, ispell, x) +if test "$ispell_path" != x; then + AC_DEFINE_UNQUOTED(ISPELL_PATH, "$ispell_path") + AC_SUBST(ISPELL_PATH) +else + AC_DEFINE_UNQUOTED(ISPELL_PATH, "$ispell_path") + AC_SUBST(ISPELL_PATH) +fi + dnl Check for libjconv AC_ARG_ENABLE(jconv, [ --disable-jconv Do not use libjconv], diff --git a/src/Makefile.am b/src/Makefile.am index 1850ac5b0..28594526e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -99,7 +99,8 @@ sylpheed_SOURCES = \ editldap.c editldap.h \ editldap_basedn.c editldap_basedn.h \ labelcolors.c labelcolors.h \ - ssl.c ssl.h + ssl.c ssl.h \ + gtkspell.c gtkspell.h gtkxtext.h EXTRA_DIST = \ quote_fmt_parse.h \ diff --git a/src/gtkspell.c b/src/gtkspell.c index 7856fb68d..3b9517ebc 100644 --- a/src/gtkspell.c +++ b/src/gtkspell.c @@ -47,8 +47,16 @@ #include #include +#include + +#include +#include +#include + #include "gtkxtext.h" +#include "gtkspell.h" + /* size of the text buffer used in various word-processing routines. */ #define BUFSIZE 1024 @@ -658,3 +666,144 @@ static void set_up_signal() signal(SIGCHLD, sigchld); #endif } + +/*** Sylpheed (Claws) ***/ + +static GSList *create_empty_dictionary_list(void) +{ + GSList *list = NULL; + Dictionary *dict; + + dict = g_new0(Dictionary, 1); + dict->name = g_strdup(_("None")); + dict->path = NULL; + return g_slist_append(list, dict); +} + +/* gtkspell_get_dictionary_list() - returns list of dictionary names and the full + * path of file names. */ +GSList *gtkspell_get_dictionary_list(const gchar *ispell_path) +{ + GSList *list; + gchar *dict_path, *tmp, *prevdir; + GSList *walk; + Dictionary *dict; + DIR *dir; + struct dirent *ent; + + list = NULL; + + /* ASSUME: ispell_path is full path */ + dict_path = strstr(ispell_path + 1, G_DIR_SEPARATOR_S); + tmp = g_strndup(ispell_path, dict_path - ispell_path); + + /* ASSUME: ispell dictionaries in PREFIX/lib/ispell */ + dict_path = g_strconcat(tmp, G_DIR_SEPARATOR_S, "lib", G_DIR_SEPARATOR_S, "ispell", NULL); + g_free(tmp); + +#ifdef USE_THREADS +#warning TODO: no directory change +#endif + + prevdir = g_get_current_dir(); + if (chdir(dict_path) <0) { + FILE_OP_ERROR(dict_path, "chdir"); + g_free(prevdir); + g_free(dict_path); + return create_empty_dictionary_list(); + } + + debug_print(_("Checking for dictionaries in %s\n"), dict_path); + + if (NULL != (dir = opendir("."))) { + while (NULL != (ent = readdir(dir))) { + /* search for hash table */ + if (NULL != (tmp = strstr(ent->d_name, ".hash"))) { + dict = g_new0(Dictionary, 1); + dict->name = g_strndup(ent->d_name, tmp - ent->d_name); + dict->path = g_strconcat(dict_path, G_DIR_SEPARATOR_S, ent->d_name, NULL); + debug_print(_("Found dictionary %s\n"), dict->path); + list = g_slist_append(list, dict); + } + } + closedir(dir); + } + else { + FILE_OP_ERROR(dict_path, "opendir"); + debug_print(_("No dictionary found\n")); + list = create_empty_dictionary_list(); + } + chdir(prevdir); + g_free(dict_path); + g_free(prevdir); + return list; +} + +void gtkspell_free_dictionary_list(GSList *list) +{ + Dictionary *dict; + GSList *walk; + for (walk = list; walk != NULL; walk = g_slist_next(walk)) + if (walk->data) { + dict = (Dictionary *) walk->data; + if (dict->name) + g_free(dict->name); + if (dict->path) + g_free(dict->path); + g_free(dict); + } + g_slist_free(list); +} + +static void dictionary_option_menu_item_data_destroy(gpointer data) +{ + gchar *str = (gchar *) data; + + if (str) + g_free(str); +} + +GtkWidget *gtkspell_dictionary_option_menu_new(const gchar *ispell_path) +{ + GSList *dict_list, *tmp; + GtkWidget *item; + GtkWidget *menu; + Dictionary *dict; + + dict_list = gtkspell_get_dictionary_list(ispell_path); + g_return_val_if_fail(dict_list, NULL); + + menu = gtk_menu_new(); + + for (tmp = dict_list; tmp != NULL; tmp = g_slist_next(tmp)) { + dict = (Dictionary *) tmp->data; + item = gtk_menu_item_new_with_label(dict->name); + if (dict->path) + gtk_object_set_data_full(GTK_OBJECT(item), "full_path", + g_strdup(dict->path), + dictionary_option_menu_item_data_destroy); + gtk_menu_append(GTK_MENU(menu), item); + gtk_widget_show(item); + } + + gtk_widget_show(menu); + + gtkspell_free_dictionary_list(dict_list); + + return menu; +} + +gchar *gtkspell_get_dictionary_menu_active_item(GtkWidget *menu) +{ + GtkWidget *menuitem; + gchar *result; + + g_return_val_if_fail(GTK_IS_MENU(menu), NULL); + menuitem = gtk_menu_get_active(GTK_MENU(menu)); + + result = gtk_object_get_data(GTK_OBJECT(menuitem), "full_path"); + g_return_val_if_fail(result, NULL); + + return g_strdup(result); +} + diff --git a/src/gtkspell.h b/src/gtkspell.h index 5b3577966..03214187a 100644 --- a/src/gtkspell.h +++ b/src/gtkspell.h @@ -28,9 +28,14 @@ #include "gtkxtext.h" -extern void gtkspell_attach(GtkXText *text_ccc); +typedef struct _Dictionary { + gchar *name; + gchar *path; +} Dictionary; -int gtkspell_start(unsigned char *path, char * args[]); +int gtkspell_start(unsigned char *path, char * args[]); + +void gtkspell_attach(GtkXText *text_ccc); void gtkspell_detach(GtkXText *gtktext); @@ -38,4 +43,11 @@ void gtkspell_check_all(GtkXText *gtktext); void gtkspell_uncheck_all(GtkXText *gtktext); +GSList *gtkspell_get_dictionary_list(const char *ispell_path); + +void gtkspell_free_dictionary_list(GSList *list); + +GtkWidget *gtkspell_dictionary_option_menu_new(const gchar *ispell_path); +gchar *gtkspell_get_dictionary_menu_active_item(GtkWidget *menu); + #endif /* __gtkspell_h__ */ diff --git a/src/mainwindow.c b/src/mainwindow.c index 7ba88fb3d..8032f6b25 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -75,6 +75,7 @@ #include "about.h" #include "manual.h" + #define AC_LABEL_WIDTH 240 #define STATUSBAR_PUSH(mainwin, str) \ diff --git a/src/prefs_common.c b/src/prefs_common.c index 37555103a..a0f434a9f 100644 --- a/src/prefs_common.c +++ b/src/prefs_common.c @@ -49,6 +49,8 @@ #include "gtkutils.h" #include "alertpanel.h" #include "folder.h" +#include "gtkspell.h" +#include "filesel.h" #include "folderview.h" PrefsCommon prefs_common; @@ -106,6 +108,12 @@ static struct Compose { GtkWidget * checkbtn_forward_as_attachment; GtkWidget * checkbtn_smart_wrapping; + + /* spelling */ + GtkWidget *checkbtn_enable_ispell; + GtkWidget *entry_ispell_path; + GtkWidget *btn_ispell_path; + GtkWidget *optmenu_dictionary_path; } compose; static struct Display { @@ -200,6 +208,10 @@ static void prefs_common_default_signkey_set_optmenu (PrefParam *pparam); static void prefs_recvdialog_set_data_from_optmenu(PrefParam *pparam); static void prefs_recvdialog_set_optmenu(PrefParam *pparam); +static void prefs_dictionary_set_data_from_optmenu(PrefParam *param); +static void prefs_dictionary_set_optmenu(PrefParam *pparam); + + /* parameter name, default value, pointer to the prefs variable, data type, pointer to the widget pointer, @@ -303,6 +315,15 @@ static PrefParam param[] = { {"smart_wrapping", "TRUE", &prefs_common.smart_wrapping, P_BOOL, &compose.checkbtn_smart_wrapping, prefs_set_data_from_toggle, prefs_set_toggle}, + {"enable_ispell", "TRUE", &prefs_common.enable_ispell, + P_BOOL, &compose.checkbtn_enable_ispell, + prefs_set_data_from_toggle, prefs_set_toggle}, + {"ispell_path", ISPELL_PATH, &prefs_common.ispell_path, + P_STRING, &compose.entry_ispell_path, + prefs_set_data_from_entry, prefs_set_entry}, + {"dictionary_path", "", &prefs_common.dictionary_path, + P_STRING, &compose.optmenu_dictionary_path, + prefs_dictionary_set_data_from_optmenu, prefs_dictionary_set_optmenu }, {"show_ruler", "TRUE", &prefs_common.show_ruler, P_BOOL, NULL, NULL, NULL}, @@ -1060,6 +1081,96 @@ static void prefs_send_create(void) send.optmenu_charset = optmenu; } +static void prefs_dictionary_set_data_from_optmenu(PrefParam *param) +{ + gchar *str; + gchar *dict_path; + + g_return_if_fail(param); + g_return_if_fail(param->data); + g_return_if_fail(param->widget); + g_return_if_fail(*(param->widget)); + + dict_path = gtkspell_get_dictionary_menu_active_item + (gtk_option_menu_get_menu(GTK_OPTION_MENU(*(param->widget)))); + str = *((gchar **) param->data); + if (str) + g_free(str); + *((gchar **) param->data) = dict_path; +} + +static void prefs_dictionary_set_optmenu(PrefParam *pparam) +{ + GList *cur; + GtkOptionMenu *optmenu = GTK_OPTION_MENU(*pparam->widget); + GtkWidget *menu; + GtkWidget *menuitem; + gchar *dict_path; + gint n = 0; + + g_return_if_fail(optmenu != NULL); + g_return_if_fail(pparam->data != NULL); + + if (*(gchar **) pparam->data) { + menu = gtk_option_menu_get_menu(optmenu); + for (cur = GTK_MENU_SHELL(menu)->children; + cur != NULL; cur = cur->next) { + menuitem = GTK_WIDGET(cur->data); + dict_path = gtk_object_get_data(GTK_OBJECT(menuitem), "full_path"); + if (!strcmp(dict_path, *((gchar **)pparam->data))) { + gtk_option_menu_set_history(optmenu, n); + return; + } + n++; + } + } + + gtk_option_menu_set_history(optmenu, 0); + prefs_dictionary_set_data_from_optmenu(pparam); +} + +static void prefs_compose_checkbtn_enable_ispell_toggle_cb + (GtkWidget *widget, + gpointer data) +{ + gboolean toggled; + + toggled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + gtk_widget_set_sensitive(compose.entry_ispell_path, toggled); + gtk_widget_set_sensitive(compose.optmenu_dictionary_path, toggled); + gtk_widget_set_sensitive(compose.btn_ispell_path, toggled); +} + +static void prefs_compose_btn_ispell_path_clicked_cb(GtkWidget *widget, + gpointer data) +{ + gchar *file_path; + GtkWidget *new_menu; + + file_path = filesel_select_file(_("Select spelling checker location"), + prefs_common.ispell_path); + if (file_path == NULL) { + /* don't change */ + } + else { + if (prefs_common.ispell_path) + g_free(prefs_common.ispell_path); + prefs_common.ispell_path = file_path; + + new_menu = gtkspell_dictionary_option_menu_new(file_path); + gtk_option_menu_set_menu(GTK_OPTION_MENU(compose.optmenu_dictionary_path), + new_menu); + + gtk_entry_set_text(GTK_ENTRY(compose.entry_ispell_path), file_path); + /* select first one */ + gtk_option_menu_set_history(GTK_OPTION_MENU(compose.optmenu_dictionary_path), 0); + + prefs_common.dictionary_path = gtkspell_get_dictionary_menu_active_item( + gtk_option_menu_get_menu(GTK_OPTION_MENU(compose.optmenu_dictionary_path))); + } + +} + static void prefs_compose_create(void) { GtkWidget *vbox1; @@ -1101,6 +1212,18 @@ static void prefs_compose_create(void) GtkWidget *checkbtn_forward_as_attachment; GtkWidget *checkbtn_smart_wrapping; + GtkWidget *frame_spell; + GtkWidget *hbox_spell; + GtkWidget *vbox_spell; + GtkWidget *hbox_ispell_path; + GtkWidget *checkbtn_enable_ispell; + GtkWidget *label_ispell_path; + GtkWidget *entry_ispell_path; + GtkWidget *btn_ispell_path; + GtkWidget *hbox_dictionary_path; + GtkWidget *label_dictionary_path; + GtkWidget *optmenu_dictionary_path; + vbox1 = gtk_vbox_new (FALSE, VSPACING); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (dialog.notebook), vbox1); @@ -1234,6 +1357,58 @@ static void prefs_compose_create(void) PACK_CHECK_BUTTON (vbox1, checkbtn_smart_wrapping, _("Smart wrapping (EXPERIMENTAL)")); + /* spell checker defaults */ + PACK_FRAME(vbox1, frame_spell, _("Global spelling checker settings")); + vbox_spell = gtk_vbox_new(FALSE, VSPACING_NARROW); + gtk_widget_show (vbox_spell); + gtk_container_add(GTK_CONTAINER(frame_spell), vbox_spell); + gtk_container_set_border_width(GTK_CONTAINER(vbox_spell), 8); + + PACK_CHECK_BUTTON(vbox_spell, checkbtn_enable_ispell, + _("Enable spell checker")); + + gtk_signal_connect(GTK_OBJECT(checkbtn_enable_ispell), "toggled", + GTK_SIGNAL_FUNC(prefs_compose_checkbtn_enable_ispell_toggle_cb), + NULL); + + hbox_ispell_path = gtk_hbox_new (FALSE, 8); + gtk_widget_show(hbox_ispell_path); + gtk_box_pack_start(GTK_BOX(vbox_spell), hbox_ispell_path, TRUE, TRUE, 0); + + label_ispell_path = gtk_label_new (_("Ispelll path")); + gtk_widget_show(label_ispell_path); + gtk_box_pack_start(GTK_BOX(hbox_ispell_path), label_ispell_path, FALSE, FALSE, 0); + + entry_ispell_path = gtk_entry_new(); + gtk_widget_show(entry_ispell_path); + gtk_box_pack_start(GTK_BOX(hbox_ispell_path), entry_ispell_path, FALSE, FALSE, 0); + gtk_widget_set_usize(entry_ispell_path, 150, -1); + gtk_widget_set_sensitive(entry_ispell_path, prefs_common.enable_ispell); + + btn_ispell_path = gtk_button_new_with_label(_("...")); + gtk_widget_show(btn_ispell_path); + gtk_box_pack_start(GTK_BOX(hbox_ispell_path), btn_ispell_path, FALSE, FALSE, 0); + gtk_widget_set_sensitive(btn_ispell_path, prefs_common.enable_ispell); + + gtk_signal_connect(GTK_OBJECT(btn_ispell_path), "clicked", + GTK_SIGNAL_FUNC(prefs_compose_btn_ispell_path_clicked_cb), + NULL); + + hbox_dictionary_path = gtk_hbox_new(FALSE, 8); + gtk_widget_show(hbox_dictionary_path); + gtk_box_pack_start(GTK_BOX(vbox_spell), hbox_dictionary_path, TRUE, TRUE, 0); + + label_dictionary_path = gtk_label_new(_("Dictionaries")); + gtk_widget_show(label_dictionary_path); + gtk_box_pack_start(GTK_BOX(hbox_dictionary_path), label_dictionary_path, FALSE, FALSE, 0); + + optmenu_dictionary_path = gtk_option_menu_new(); + gtk_widget_show(optmenu_dictionary_path); + gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu_dictionary_path), + gtkspell_dictionary_option_menu_new(prefs_common.ispell_path)); + gtk_box_pack_start(GTK_BOX(hbox_dictionary_path), optmenu_dictionary_path, FALSE, FALSE, 0); + gtk_widget_set_sensitive(optmenu_dictionary_path, prefs_common.enable_ispell); + /* compose.checkbtn_quote = checkbtn_quote; compose.entry_quotemark = entry_quotemark; @@ -1253,6 +1428,11 @@ static void prefs_compose_create(void) checkbtn_forward_as_attachment; compose.checkbtn_smart_wrapping = checkbtn_smart_wrapping; + + compose.checkbtn_enable_ispell = checkbtn_enable_ispell; + compose.entry_ispell_path = entry_ispell_path; + compose.btn_ispell_path = btn_ispell_path; + compose.optmenu_dictionary_path = optmenu_dictionary_path; } static void prefs_display_create(void) diff --git a/src/prefs_common.h b/src/prefs_common.h index 8adbf2663..e89a90a12 100644 --- a/src/prefs_common.h +++ b/src/prefs_common.h @@ -75,6 +75,9 @@ struct _PrefsCommon gchar *fw_quotefmt; gboolean forward_as_attachment; gboolean smart_wrapping; + gboolean enable_ispell; + gchar *ispell_path; + gchar *dictionary_path; /* Display */ gchar *widgetfont; -- 2.25.1