2006-02-16 [wwp] 2.0.0cvs58
[claws.git] / src / prefs_spelling.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2002-2006 Hiroyuki Yamamoto & the Sylpheed-Claws team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 /*
21  * General functions for accessing address book files.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
28 #if USE_ASPELL
29
30 #include "defs.h"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34
35 #include <glib.h>
36 #include <glib/gi18n.h>
37 #include <gtk/gtk.h>
38
39 #include "utils.h"
40 #include "prefs_common.h"
41 #include "prefs_gtk.h"
42
43 #include "gtk/gtkutils.h"
44 #include "gtk/prefswindow.h"
45 #include "gtk/filesel.h"
46 #include "gtk/colorsel.h"
47
48 typedef struct _SpellingPage
49 {
50         PrefsPage page;
51
52         GtkWidget *window;              /* do not modify */
53
54         GtkWidget *checkbtn_enable_aspell;
55         GtkWidget *entry_aspell_path;
56         GtkWidget *btn_aspell_path;
57         GtkWidget *optmenu_dictionary;
58         GtkWidget *optmenu_sugmode;
59         GtkWidget *misspelled_btn;
60         GtkWidget *checkbtn_use_alternate;
61         GtkWidget *checkbtn_check_while_typing;
62         GtkWidget *checkbtn_recheck_when_changing_dict;
63
64         gint       misspell_col;
65 } SpellingPage;
66
67 static void prefs_spelling_enable(SpellingPage *spelling, gboolean enable)
68 {
69         gtk_widget_set_sensitive(spelling->entry_aspell_path,           enable);
70         gtk_widget_set_sensitive(spelling->optmenu_dictionary,          enable);
71         gtk_widget_set_sensitive(spelling->optmenu_sugmode,             enable);
72         gtk_widget_set_sensitive(spelling->btn_aspell_path,             enable);
73         gtk_widget_set_sensitive(spelling->misspelled_btn,              enable);
74         gtk_widget_set_sensitive(spelling->checkbtn_use_alternate,      enable);
75         gtk_widget_set_sensitive(spelling->checkbtn_check_while_typing, enable);
76         gtk_widget_set_sensitive(spelling->checkbtn_recheck_when_changing_dict, enable);
77 }
78
79 static void prefs_spelling_checkbtn_enable_aspell_toggle_cb
80         (GtkWidget *widget,
81          gpointer data)
82 {
83         SpellingPage *spelling = (SpellingPage *) data;
84         gboolean toggled;
85
86         toggled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
87         prefs_spelling_enable(spelling, toggled);
88 }
89
90 static void prefs_spelling_btn_aspell_path_clicked_cb(GtkWidget *widget,
91                                                      gpointer data)
92 {
93         SpellingPage *spelling = (SpellingPage *) data;
94         gchar *file_path;
95         GtkWidget *new_menu;
96
97         file_path = filesel_select_file_open(_("Select dictionaries location"),
98                                         prefs_common.aspell_path);
99         if (file_path != NULL) {
100                 gchar *tmp_path, *tmp;
101
102                 tmp_path = g_path_get_dirname(file_path);
103                 tmp = g_strdup_printf("%s%s", tmp_path, G_DIR_SEPARATOR_S);
104                 g_free(tmp_path);
105
106                 new_menu = gtkaspell_dictionary_option_menu_new(tmp);
107                 gtk_option_menu_set_menu(GTK_OPTION_MENU(spelling->optmenu_dictionary),
108                                          new_menu);
109
110                 gtk_entry_set_text(GTK_ENTRY(spelling->entry_aspell_path), tmp);
111                 /* select first one */
112                 gtk_option_menu_set_history(GTK_OPTION_MENU(
113                                         spelling->optmenu_dictionary), 0);
114         
115                 g_free(tmp);
116
117         }
118 }
119
120 static void prefs_spelling_colorsel(GtkWidget *widget,
121                                     gpointer data)
122 {
123         SpellingPage *spelling = (SpellingPage *) data;
124         gint rgbcolor;
125
126         rgbcolor = colorsel_select_color_rgb(_("Pick color for misspelled word"), 
127                                              spelling->misspell_col);
128         gtkut_set_widget_bgcolor_rgb(spelling->misspelled_btn, rgbcolor);
129         spelling->misspell_col = rgbcolor;
130 }
131
132 #define SAFE_STRING(str) \
133         (str) ? (str) : ""
134
135 void prefs_spelling_create_widget(PrefsPage *_page, GtkWindow *window, gpointer data)
136 {
137         SpellingPage *prefs_spelling = (SpellingPage *) _page;
138
139         GtkWidget *table;
140         GtkWidget *checkbtn_enable_aspell;
141         GtkWidget *checkbtn_check_while_typing;
142         GtkWidget *checkbtn_recheck_when_changing_dict;
143         GtkWidget *checkbtn_use_alternate;
144         GtkWidget *label2;
145         GtkWidget *entry_aspell_path;
146         GtkWidget *label3;
147         GtkWidget *optmenu_dictionary;
148         GtkWidget *optmenu_dictionary_menu;
149         GtkWidget *label4;
150         GtkWidget *optmenu_sugmode;
151         GtkWidget *optmenu_sugmode_menu;
152         GtkWidget *label5;
153         GtkWidget *btn_aspell_path;
154         GtkWidget *hbox1;
155         GtkWidget *misspelled_btn;
156         GtkTooltips *tooltips;
157
158         tooltips = gtk_tooltips_new ();
159
160         table = gtk_table_new(9, 3, FALSE);
161         gtk_widget_show(table);
162         gtk_container_set_border_width(GTK_CONTAINER(table), VBOX_BORDER);
163         gtk_table_set_row_spacings(GTK_TABLE(table), 4);
164         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
165
166         checkbtn_enable_aspell =
167             gtk_check_button_new_with_label(_("Enable spell checker"));
168         gtk_widget_show(checkbtn_enable_aspell);
169         gtk_table_attach(GTK_TABLE(table), checkbtn_enable_aspell, 0, 3, 0,
170                          1, (GtkAttachOptions) (GTK_FILL),
171                          (GtkAttachOptions) (0), 0, 0);
172
173         checkbtn_check_while_typing =
174             gtk_check_button_new_with_label(_("Check while typing"));
175         gtk_widget_show(checkbtn_check_while_typing);
176         gtk_table_attach(GTK_TABLE(table), checkbtn_check_while_typing, 0,
177                          3, 1, 2, (GtkAttachOptions) (GTK_FILL),
178                          (GtkAttachOptions) (0), 0, 0);
179
180         checkbtn_recheck_when_changing_dict = gtk_check_button_new_with_label(
181                         _("Re-check message when changing dictionary"));
182         gtk_widget_show(checkbtn_recheck_when_changing_dict);
183         gtk_table_attach(GTK_TABLE(table), checkbtn_recheck_when_changing_dict, 0,
184                          3, 2, 3, (GtkAttachOptions) (GTK_FILL),
185                          (GtkAttachOptions) (0), 0, 0);
186
187         checkbtn_use_alternate =
188             gtk_check_button_new_with_label(_
189                                             ("Enable alternate dictionary"));
190         gtk_widget_show(checkbtn_use_alternate);
191         gtk_table_attach(GTK_TABLE(table), checkbtn_use_alternate, 0, 3, 3,
192                          4, (GtkAttachOptions) (GTK_FILL),
193                          (GtkAttachOptions) (0), 0, 0);
194         gtk_tooltips_set_tip (tooltips, checkbtn_use_alternate, 
195                         _("Faster switching with last used dictionary"), NULL);
196
197         label2 = gtk_label_new(_("Dictionaries path:"));
198         gtk_widget_show(label2);
199         gtk_table_attach(GTK_TABLE(table), label2, 0, 1, 5, 6,
200                          (GtkAttachOptions) (GTK_FILL),
201                          (GtkAttachOptions) (0), 0, 0);
202         gtk_label_set_justify(GTK_LABEL(label2), GTK_JUSTIFY_RIGHT);
203         gtk_misc_set_alignment(GTK_MISC(label2), 1, 0.5);
204
205         entry_aspell_path = gtk_entry_new();
206         gtk_widget_show(entry_aspell_path);
207         gtk_table_attach(GTK_TABLE(table), entry_aspell_path, 1, 2, 5, 6,
208                          (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
209                          (GtkAttachOptions) (0), 0, 0);
210
211         btn_aspell_path = gtkut_get_browse_directory_btn(_("_Browse"));
212         gtk_widget_show(btn_aspell_path);
213         gtk_table_attach(GTK_TABLE(table), btn_aspell_path, 2, 3, 5, 6,
214                          (GtkAttachOptions) (GTK_FILL),
215                          (GtkAttachOptions) (0), 0, 0);
216
217         label3 = gtk_label_new(_("Default dictionary:"));
218         gtk_widget_show(label3);
219         gtk_table_attach(GTK_TABLE(table), label3, 0, 1, 6, 7,
220                          (GtkAttachOptions) (GTK_FILL),
221                          (GtkAttachOptions) (0), 0, 0);
222         gtk_label_set_justify(GTK_LABEL(label3), GTK_JUSTIFY_RIGHT);
223         gtk_misc_set_alignment(GTK_MISC(label3), 1, 0.5);
224
225         optmenu_dictionary = gtk_option_menu_new();
226         gtk_widget_show(optmenu_dictionary);
227         gtk_table_attach(GTK_TABLE(table), optmenu_dictionary, 1, 3, 6, 7,
228                          (GtkAttachOptions) (GTK_FILL),
229                          (GtkAttachOptions) (0), 0, 0);
230         optmenu_dictionary_menu = gtk_menu_new();
231         gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu_dictionary),
232                                  optmenu_dictionary_menu);
233
234         label4 = gtk_label_new(_("Default suggestion mode:"));
235         gtk_widget_show(label4);
236         gtk_table_attach(GTK_TABLE(table), label4, 0, 1, 7, 8,
237                          (GtkAttachOptions) (GTK_FILL),
238                          (GtkAttachOptions) (0), 0, 0);
239         gtk_label_set_justify(GTK_LABEL(label4), GTK_JUSTIFY_RIGHT);
240         gtk_misc_set_alignment(GTK_MISC(label4), 1, 0.5);
241
242         optmenu_sugmode = gtk_option_menu_new();
243         gtk_widget_show(optmenu_sugmode);
244         gtk_table_attach(GTK_TABLE(table), optmenu_sugmode, 1, 3, 7, 8,
245                          (GtkAttachOptions) (GTK_FILL),
246                          (GtkAttachOptions) (0), 0, 0);
247         optmenu_sugmode_menu = gtk_menu_new();
248         gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu_sugmode),
249                                  optmenu_sugmode_menu);
250
251         label5 = gtk_label_new(_("Misspelled word color:"));
252         gtk_widget_show(label5);
253         gtk_table_attach(GTK_TABLE(table), label5, 0, 1, 8, 9,
254                          (GtkAttachOptions) (GTK_FILL),
255                          (GtkAttachOptions) (0), 0, 0);
256         gtk_label_set_justify(GTK_LABEL(label5), GTK_JUSTIFY_RIGHT);
257         gtk_misc_set_alignment(GTK_MISC(label5), 1, 0.5);
258
259         hbox1 = gtk_hbox_new(FALSE, 0);
260         gtk_widget_show(hbox1);
261         gtk_table_attach(GTK_TABLE(table), hbox1, 1, 2, 8, 9,
262                          (GtkAttachOptions) (GTK_FILL),
263                          (GtkAttachOptions) (GTK_FILL), 0, 0);
264
265         misspelled_btn = gtk_button_new_with_label("");
266         gtk_widget_show(misspelled_btn);
267         gtk_box_pack_start(GTK_BOX(hbox1), misspelled_btn, FALSE, FALSE, 0);
268         gtk_widget_set_size_request(misspelled_btn, 30, 20);
269         label5 = gtk_label_new(_("Use black to underline"));
270         gtkut_widget_set_small_font_size (label5);
271         gtk_widget_show(label5);
272         gtk_box_pack_start(GTK_BOX(hbox1), label5, FALSE, FALSE, 4);
273
274         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_enable_aspell),
275                                      prefs_common.enable_aspell);
276         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_check_while_typing),
277                                      prefs_common.check_while_typing);
278         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_recheck_when_changing_dict),
279                                      prefs_common.recheck_when_changing_dict);
280         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_use_alternate),
281                                      prefs_common.use_alternate);
282         gtk_entry_set_text(GTK_ENTRY(entry_aspell_path), 
283                            SAFE_STRING(prefs_common.aspell_path));
284
285         g_signal_connect(G_OBJECT(checkbtn_enable_aspell), "toggled",
286                          G_CALLBACK(prefs_spelling_checkbtn_enable_aspell_toggle_cb),
287                          prefs_spelling);
288         g_signal_connect(G_OBJECT(btn_aspell_path), "clicked", 
289                          G_CALLBACK(prefs_spelling_btn_aspell_path_clicked_cb),
290                          prefs_spelling);
291         g_signal_connect(G_OBJECT(misspelled_btn), "clicked",
292                          G_CALLBACK(prefs_spelling_colorsel), prefs_spelling);
293
294         gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu_dictionary),
295                                  gtkaspell_dictionary_option_menu_new(prefs_common.aspell_path));
296         gtkaspell_set_dictionary_menu_active_item(optmenu_dictionary, prefs_common.dictionary);
297
298         gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu_sugmode),
299                                  gtkaspell_sugmode_option_menu_new(prefs_common.aspell_sugmode));
300         gtkaspell_sugmode_option_menu_set(GTK_OPTION_MENU(optmenu_sugmode),
301                                           prefs_common.aspell_sugmode);
302
303         prefs_spelling->misspell_col = prefs_common.misspelled_col;
304         gtkut_set_widget_bgcolor_rgb(misspelled_btn, prefs_spelling->misspell_col);
305
306         prefs_spelling->window
307                 = GTK_WIDGET(window);
308         prefs_spelling->checkbtn_enable_aspell 
309                 = checkbtn_enable_aspell;
310         prefs_spelling->entry_aspell_path
311                 = entry_aspell_path;
312         prefs_spelling->btn_aspell_path
313                 = btn_aspell_path;
314         prefs_spelling->optmenu_dictionary
315                 = optmenu_dictionary;
316         prefs_spelling->optmenu_sugmode
317                 = optmenu_sugmode;
318         prefs_spelling->checkbtn_use_alternate
319                 = checkbtn_use_alternate;
320         prefs_spelling->checkbtn_check_while_typing
321                 = checkbtn_check_while_typing;
322         prefs_spelling->checkbtn_recheck_when_changing_dict
323                 = checkbtn_recheck_when_changing_dict;
324         prefs_spelling->misspelled_btn
325                 = misspelled_btn;
326
327         prefs_spelling->page.widget = table;
328
329         prefs_spelling_enable(prefs_spelling, prefs_common.enable_aspell);
330 }
331
332 void prefs_spelling_save(PrefsPage *_page)
333 {
334         SpellingPage *spelling = (SpellingPage *) _page;
335
336         prefs_common.enable_aspell =
337                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(spelling->checkbtn_enable_aspell));
338         prefs_common.check_while_typing =
339                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(spelling->checkbtn_check_while_typing));
340         prefs_common.recheck_when_changing_dict =
341                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(spelling->checkbtn_recheck_when_changing_dict));
342         prefs_common.use_alternate =
343                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(spelling->checkbtn_use_alternate));
344
345         if (prefs_common.aspell_path)
346                 g_free(prefs_common.aspell_path);
347         prefs_common.aspell_path =
348                 gtk_editable_get_chars(GTK_EDITABLE(spelling->entry_aspell_path), 0, -1);
349
350         if (prefs_common.dictionary != NULL)
351                 g_free(prefs_common.dictionary);
352         prefs_common.dictionary = 
353                 gtkaspell_get_dictionary_menu_active_item(
354                         gtk_option_menu_get_menu(
355                                 GTK_OPTION_MENU(
356                                         spelling->optmenu_dictionary)));
357
358         prefs_common.aspell_sugmode =
359                 gtkaspell_get_sugmode_from_option_menu(
360                         GTK_OPTION_MENU(spelling->optmenu_sugmode));
361
362         prefs_common.misspelled_col = spelling->misspell_col;
363 }
364
365 static void prefs_spelling_destroy_widget(PrefsPage *_page)
366 {
367         /* SpellingPage *spelling = (SpellingPage *) _page; */
368
369 }
370
371 SpellingPage *prefs_spelling;
372
373 void prefs_spelling_init(void)
374 {
375         SpellingPage *page;
376         static gchar *path[3];
377         const gchar* language = NULL;
378         
379         path[0] = _("Compose");
380         path[1] = _("Spell Checking");
381         path[2] = NULL;
382
383         page = g_new0(SpellingPage, 1);
384         page->page.path = path;
385         page->page.create_widget = prefs_spelling_create_widget;
386         page->page.destroy_widget = prefs_spelling_destroy_widget;
387         page->page.save_page = prefs_spelling_save;
388         page->page.weight = 180.0;
389
390         prefs_gtk_register_page((PrefsPage *) page);
391         prefs_spelling = page;
392         
393         language = g_getenv("LANG");
394         if (language == NULL)
395                 language = "en";
396         else if (!strcmp(language, "POSIX") || !strcmp(language, "C"))
397                 language = "en";
398         
399         if (!prefs_common.dictionary)
400                 prefs_common.dictionary = g_strdup_printf("%s%s",
401                                                 prefs_common.aspell_path,
402                                                 language);
403         if (!strlen(prefs_common.dictionary)
404         ||  !strcmp(prefs_common.dictionary,"(None"))
405                 prefs_common.dictionary = g_strdup_printf("%s%s",
406                                                 prefs_common.aspell_path,
407                                                 language);
408         if (strcasestr(prefs_common.dictionary,".utf"))
409                 *(strcasestr(prefs_common.dictionary,".utf")) = '\0';
410         if (strstr(prefs_common.dictionary,"@"))
411                 *(strstr(prefs_common.dictionary,"@")) = '\0';
412 }
413
414 void prefs_spelling_done(void)
415 {
416         prefs_gtk_unregister_page((PrefsPage *) prefs_spelling);
417         g_free(prefs_spelling);
418 }
419
420 #endif /* USE_ASPELL */