2008-08-29 [paul] 3.5.0cvs82
[claws.git] / src / quote_fmt.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2007 Hiroyuki Yamamoto and the Claws Mail 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 3 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, see <http://www.gnu.org/licenses/>.
17  * 
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include <glib.h>
25 #include <glib/gi18n.h>
26 #include <gtk/gtk.h>
27 #include <gdk/gdkkeysyms.h>
28
29 #include "manage_window.h"
30 #include "description_window.h"
31 #include "gtkutils.h"
32
33 #include "prefs_gtk.h"
34 #include "prefs_common.h"
35 #include "quote_fmt.h"
36 #include "alertpanel.h"
37 #include "prefs_template.h"
38
39
40 /*
41  * Strings describing quote format strings
42  * 
43  * When adding new lines, remember to put 2 strings for each line
44  */
45 static gchar *quote_desc_strings[] = {
46         N_("<span weight=\"bold\">symbols:</span>"),                            NULL,
47         "%date_fmt{<span style=\"oblique\">fmt</span>} (%D{<span style=\"oblique\">fmt</span>})",       N_("customized date format (see 'man strftime')"), /* date expression */
48         "%date (%d)",                           N_("Date"), /* date */
49         "%from (%f)",                           N_("From"), /* from */
50         "%email (%A)",                          N_("email address of sender"), /* email address */
51         "%fullname (%N)",                       N_("full name of sender"), /* full name */
52         "%firstname (%F)",                      N_("first name of sender"), /* first name */
53         "%lastname (%L)",                       N_("last name of sender"), /* last name */
54         "%initials (%I)",                       N_("initials of sender"), /* initial of sender */
55         "%subject (%s)",                        N_("Subject"), /* subject */ 
56         "%to (%t)",                                     N_("To"), /* to */ 
57         "%cc (%c)",                                     N_("Cc"), /* cc */ 
58         "%newsgroups (%n)",                     N_("Newsgroups"), /* newsgroups */ 
59         "%references (%r)",                     N_("References"), /* references */ 
60         "%messageid (%i)",                      N_("Message-ID"), /* message-id */ 
61         "%msg (%M)",                            N_("message body"), /* message */
62         "%quoted_msg (%Q)",                     N_("quoted message body"), /* quoted message */
63         "%msg_no_sig (%m)",                     N_("message body without signature"), /* message with no signature */
64         "%quoted_msg_no_sig (%q)",      N_("quoted message body without signature"), /* quoted message with no signature */
65         "%tags",                                N_("message tags"), /* message tags */
66         "%dict (%T)",                           N_("current dictionary"), /* current dictionary */
67         "%cursor (%X)",                         N_("cursor position"), /* X marks the cursor spot */
68         "%account_fullname (%af)",      N_("account property: your name"), /* full name in compose account */
69         "%account_email (%am)",         N_("account property: your email address"), /* mail address in compose account */
70         "%account_name (%an)",          N_("account property: account name"), /* compose account name itself */
71         "%account_org (%ao)",           N_("account property: organization"), /* organization in compose account */
72         "%account_dict (%aT)",          N_("account property: default dictionary"), /* main dict (if enabled) in account */
73         "%addrbook_cc (%ABc)",          N_("address book <span style=\"oblique\">completion</span>: Cc"), /* completion of 'Cc' from address book */
74         "%addrbook_from (%ABf)",        N_("address book <span style=\"oblique\">completion</span>: From"), /* completion of 'From' from address book */
75         "%addrbook_to (%ABt)",          N_("address book <span style=\"oblique\">completion</span>: To"), /* completion of 'To' from address book */
76         "\\%",                          N_("literal %"),
77         "\\\\",                         N_("literal backslash"),
78         "\\?",                          N_("literal question mark"),
79         "\\!",                          N_("literal exclamation mark"),
80         "\\|",                          N_("literal pipe"),
81         "\\{",                          N_("literal opening curly brace"),
82         "\\}",                          N_("literal closing curly brace"),
83         "\\t",                          N_("tab"),
84         "\\n",                          N_("new line"),
85         "",                                     NULL,
86         N_("<span weight=\"bold\">commands:</span>"),           NULL,
87         "?x{<span style=\"oblique\">expr</span>}\n\n",          N_("insert <span style=\"oblique\">expr</span> if x is set, where x is one of\nthe [dfNFLIstcnriT, ad, af, ao, aT, ABc, ABf, ABt]\nsymbols (or their long equivalent)"),
88         "!x{<span style=\"oblique\">expr</span>}\n\n",          N_("insert <span style=\"oblique\">expr</span> if x is not set, where x is one of\nthe [dfNFLIstcnriT, ad, af, ao, aT, ABc, ABf, ABt]\nsymbols (or their long equivalent)"),
89         "|file{<span style=\"oblique\">sub_expr</span>}\n(|f{<span style=\"oblique\">sub_expr</span>})",                N_("insert file:\n<span style=\"oblique\">sub_expr</span> is evaluated as the path of the file to insert"), /* insert file */
90         "|program{<span style=\"oblique\">sub_expr</span>}\n(|p{<span style=\"oblique\">sub_expr</span>})\n",   N_("insert program output:\n<span style=\"oblique\">sub_expr</span> is evaluated as a command-line to get\nthe output from"), /* insert program output */
91         "|input{<span style=\"oblique\">sub_expr</span>}\n(|i{<span style=\"oblique\">sub_expr</span>})\n",             N_("insert user input:\n<span style=\"oblique\">sub_expr</span> is a variable to be replaced by\nuser-entered text"), /* insert user input */
92         "|attach{<span style=\"oblique\">sub_expr</span>}\n(|a{<span style=\"oblique\">sub_expr</span>})",              N_("attach file:\n<span style=\"oblique\">sub_expr</span> is evaluated as the path of the file to attach"), /* attach file */
93         "",                                     NULL,
94         N_("<span weight=\"bold\">definition of terms:</span>"),        NULL,
95         "<span style=\"oblique\">expr</span>\n",                        N_("text that can contain any of the symbols or\ncommands above"),
96         "<span style=\"oblique\">sub_expr</span>\n",            N_("text that can contain any of the symbols (no\ncommands) above"),
97         "<span style=\"oblique\">completion</span>\n\n\n",      N_("completion from address book only works with the first\naddress of the header, it outputs the full name\nof the contact if that address matches exactly\none contact in the address book"),
98         NULL,NULL
99 };
100
101 static DescriptionWindow quote_desc_win = { 
102         NULL,
103         NULL,
104         2,
105         N_("Description of symbols"),
106         N_("The following symbols and commands can be used:"),
107         quote_desc_strings
108 };
109
110
111 void quote_fmt_quote_description(GtkWidget *widget, GtkWidget *pref_window)
112 {
113         quote_desc_win.parent = pref_window;
114         description_window_create(&quote_desc_win);
115 }
116
117 void quotefmt_create_new_msg_fmt_widgets(GtkWindow *parent_window,
118                                                 GtkWidget *parent_box,
119                                                 GtkWidget **checkbtn_compose_with_format,
120                                                 GtkWidget **override_from_format,
121                                                 GtkWidget **edit_subject_format,
122                                                 GtkWidget **edit_body_format,
123                                                 gboolean add_info_button,
124                                                 void(*set_defaults_func)(void))
125 {
126         GtkWidget *checkbtn_use_format = NULL;
127         GtkWidget *vbox_format;
128         GtkWidget *hbox_format;
129         GtkWidget *hbox2_format;
130         GtkWidget *label_from = NULL;
131         GtkWidget *entry_from = NULL;
132         GtkWidget *label_subject;
133         GtkWidget *entry_subject;
134         GtkWidget *scrolledwin_format;
135         GtkWidget *text_format;
136         GtkSizeGroup *size_group;
137
138         if (add_info_button)
139                 g_return_if_fail(parent_window != NULL);
140         g_return_if_fail(parent_box != NULL);
141         if (checkbtn_compose_with_format)
142                 g_return_if_fail(checkbtn_compose_with_format != NULL);
143
144         g_return_if_fail(edit_subject_format != NULL);
145         g_return_if_fail(edit_body_format != NULL);
146
147         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
148
149         if (checkbtn_compose_with_format)
150                 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format, 
151                                    _("Use template when composing new messages"));
152
153         vbox_format = gtk_vbox_new (FALSE, 4);
154         gtk_widget_show(vbox_format);
155         gtk_container_add(GTK_CONTAINER (parent_box), vbox_format);
156         gtk_container_set_border_width (GTK_CONTAINER (vbox_format), 8);
157
158         if (override_from_format) {
159                 CLAWS_TIP_DECL();
160
161                 hbox2_format = gtk_hbox_new (FALSE, 8);
162                 gtk_widget_show (hbox2_format);
163                 gtk_box_pack_start (GTK_BOX (vbox_format), hbox2_format, FALSE, FALSE, 0);
164
165                 label_from = gtk_label_new (_("From"));
166                 gtk_misc_set_alignment(GTK_MISC(label_from), 1, 0.5);
167                 gtk_widget_show (label_from);
168                 gtk_box_pack_start (GTK_BOX (hbox2_format), label_from, FALSE, FALSE, 0);
169                 gtk_size_group_add_widget(size_group, label_from);
170
171                 entry_from = gtk_entry_new ();
172                 gtk_widget_show (entry_from);
173                 gtk_box_pack_start (GTK_BOX (hbox2_format), entry_from, TRUE, TRUE, 0);
174                 gtk_widget_set_size_request (entry_from, 100, -1);
175
176                 CLAWS_SET_TIP(entry_from,
177                                 _("Override From header. This doesn't change the account used to compose the new message."));
178         }
179
180         hbox_format = gtk_hbox_new (FALSE, 8);
181         gtk_widget_show (hbox_format);
182         gtk_box_pack_start (GTK_BOX (vbox_format), hbox_format, FALSE, FALSE, 0);
183
184         label_subject = gtk_label_new (_("Subject"));
185         gtk_misc_set_alignment(GTK_MISC(label_subject), 1, 0.5);
186         gtk_widget_show (label_subject);
187         gtk_box_pack_start (GTK_BOX (hbox_format), label_subject, FALSE, FALSE, 0);
188         gtk_size_group_add_widget(size_group, label_subject);
189
190         entry_subject = gtk_entry_new ();
191         gtk_widget_show (entry_subject);
192         gtk_box_pack_start (GTK_BOX (hbox_format), entry_subject, TRUE, TRUE, 0);
193         gtk_widget_set_size_request (entry_subject, 100, -1);
194
195         scrolledwin_format = gtk_scrolled_window_new (NULL, NULL);
196         gtk_widget_show (scrolledwin_format);
197         gtk_box_pack_start (GTK_BOX (vbox_format), scrolledwin_format,
198                             TRUE, TRUE, 0);
199         gtk_scrolled_window_set_policy
200                 (GTK_SCROLLED_WINDOW (scrolledwin_format),
201                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
202         gtk_scrolled_window_set_shadow_type
203                 (GTK_SCROLLED_WINDOW (scrolledwin_format), GTK_SHADOW_IN);
204
205         text_format = gtk_text_view_new ();
206         if (prefs_common.textfont) {
207                 PangoFontDescription *font_desc;
208
209                 font_desc = pango_font_description_from_string
210                                                 (prefs_common.textfont);
211                 if (font_desc) {
212                         gtk_widget_modify_font(text_format, font_desc);
213                         pango_font_description_free(font_desc);
214                 }
215         }
216         gtk_widget_show(text_format);
217         gtk_container_add(GTK_CONTAINER(scrolledwin_format), text_format);
218         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_format), TRUE);
219         gtk_widget_set_size_request(text_format, -1, 100);
220
221         if (checkbtn_compose_with_format) {
222                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_subject);
223                 if (override_from_format) {
224                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_from);
225                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_from);
226                 }
227                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_subject);
228                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_format);
229         }
230
231         if (add_info_button)
232                 quotefmt_add_info_button(parent_window, vbox_format);
233         if (set_defaults_func)
234                 quotefmt_add_defaults_button(parent_window, vbox_format, set_defaults_func);
235
236         if (checkbtn_compose_with_format)
237                 *checkbtn_compose_with_format = checkbtn_use_format;
238         if (override_from_format)
239                 *override_from_format = entry_from;
240         *edit_subject_format = entry_subject;
241         *edit_body_format = text_format;
242 }
243
244 void quotefmt_create_reply_fmt_widgets(GtkWindow *parent_window,
245                                                 GtkWidget *parent_box,
246                                                 GtkWidget **checkbtn_reply_with_format,
247                                                 GtkWidget **override_from_format,
248                                                 GtkWidget **edit_reply_quotemark,
249                                                 GtkWidget **edit_reply_format,
250                                                 gboolean add_info_button,
251                                                 void(*set_defaults_func)(void))
252 {
253         GtkWidget *checkbtn_use_format = NULL;
254         GtkWidget *vbox_quote;
255         GtkWidget *hbox1;
256         GtkWidget *hbox2;
257         GtkWidget *hbox3;
258         GtkWidget *label_quotemark;
259         GtkWidget *entry_quotemark;
260         GtkWidget *label_from = NULL;
261         GtkWidget *entry_from = NULL;
262         GtkWidget *scrolledwin_quotefmt;
263         GtkWidget *text_quotefmt;
264         GtkSizeGroup *size_group;
265
266         if (add_info_button)
267                 g_return_if_fail(parent_window != NULL);
268         g_return_if_fail(parent_box != NULL);
269         if (checkbtn_reply_with_format)
270                 g_return_if_fail(checkbtn_reply_with_format != NULL);
271
272         g_return_if_fail(edit_reply_quotemark != NULL);
273         g_return_if_fail(edit_reply_format != NULL);
274
275         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
276
277         if (checkbtn_reply_with_format)
278                 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
279                                    _("Use template when replying to messages"));
280
281         vbox_quote = gtk_vbox_new (FALSE, 4);
282         gtk_widget_show(vbox_quote);
283         gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
284         gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
285
286         if (override_from_format) {
287                 CLAWS_TIP_DECL();
288
289                 hbox3 = gtk_hbox_new (FALSE, 8);
290                 gtk_widget_show (hbox3);
291                 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox3, FALSE, FALSE, 0);
292
293                 label_from = gtk_label_new (_("From"));
294                 gtk_misc_set_alignment(GTK_MISC(label_from), 1, 0.5);
295                 gtk_widget_show (label_from);
296                 gtk_box_pack_start (GTK_BOX (hbox3), label_from, FALSE, FALSE, 0);
297                 gtk_size_group_add_widget(size_group, label_from);
298
299                 entry_from = gtk_entry_new ();
300                 gtk_widget_show (entry_from);
301                 gtk_box_pack_start (GTK_BOX (hbox3), entry_from, TRUE, TRUE, 0);
302                 gtk_widget_set_size_request (entry_from, 100, -1);
303
304                 CLAWS_SET_TIP(entry_from,
305                                 _("Override From header. This doesn't change the account used to reply."));
306         }
307
308         hbox1 = gtk_hbox_new (FALSE, 32);
309         gtk_widget_show (hbox1);
310         gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
311
312         hbox2 = gtk_hbox_new (FALSE, 8);
313         gtk_widget_show (hbox2);
314         gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
315
316         label_quotemark = gtk_label_new (_("Quotation mark"));
317         gtk_misc_set_alignment(GTK_MISC(label_quotemark), 1, 0.5);
318         gtk_widget_show (label_quotemark);
319         gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
320         gtk_size_group_add_widget(size_group, label_quotemark);
321
322         entry_quotemark = gtk_entry_new ();
323         gtk_widget_show (entry_quotemark);
324         gtk_box_pack_start (GTK_BOX (hbox2), entry_quotemark, FALSE, FALSE, 0);
325         gtk_widget_set_size_request (entry_quotemark, 64, -1);
326
327         scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
328         gtk_widget_show (scrolledwin_quotefmt);
329         gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
330                             TRUE, TRUE, 0);
331         gtk_scrolled_window_set_policy
332                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
333                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
334         gtk_scrolled_window_set_shadow_type
335                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
336
337         text_quotefmt = gtk_text_view_new ();
338         if (prefs_common.textfont) {
339                 PangoFontDescription *font_desc;
340
341                 font_desc = pango_font_description_from_string
342                                                 (prefs_common.textfont);
343                 if (font_desc) {
344                         gtk_widget_modify_font(text_quotefmt, font_desc);
345                         pango_font_description_free(font_desc);
346                 }
347         }
348         gtk_widget_show(text_quotefmt);
349         gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt), text_quotefmt);
350         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_quotefmt), TRUE);
351         gtk_widget_set_size_request(text_quotefmt, -1, 100);
352
353         if (checkbtn_reply_with_format) {
354                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
355                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_quotemark);
356                 if (override_from_format) {
357                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_from);
358                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_from);
359                 }
360                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_quotefmt);
361         }
362
363         if (add_info_button)
364                 quotefmt_add_info_button(parent_window, vbox_quote);
365         if (set_defaults_func)
366                 quotefmt_add_defaults_button(parent_window, vbox_quote, set_defaults_func);
367
368         if (checkbtn_reply_with_format)
369                 *checkbtn_reply_with_format = checkbtn_use_format;
370         *edit_reply_quotemark = entry_quotemark;
371         if (override_from_format)
372                 *override_from_format = entry_from;
373         *edit_reply_format = text_quotefmt;
374 }
375
376 void quotefmt_create_forward_fmt_widgets(GtkWindow *parent_window,
377                                                 GtkWidget *parent_box,
378                                                 GtkWidget **checkbtn_forward_with_format,
379                                                 GtkWidget **override_from_format,
380                                                 GtkWidget **edit_fw_quotemark,
381                                                 GtkWidget **edit_fw_format,
382                                                 gboolean add_info_button,
383                                                 void(*set_defaults_func)(void))
384 {
385         GtkWidget *checkbtn_use_format = NULL;
386         GtkWidget *vbox_quote;
387         GtkWidget *hbox1;
388         GtkWidget *hbox2;
389         GtkWidget *hbox3;
390         GtkWidget *label_quotemark;
391         GtkWidget *entry_fw_quotemark;
392         GtkWidget *label_from = NULL;
393         GtkWidget *entry_from = NULL;
394         GtkWidget *scrolledwin_quotefmt;
395         GtkWidget *text_fw_quotefmt;
396         GtkSizeGroup *size_group;
397
398         if (add_info_button)
399                 g_return_if_fail(parent_window != NULL);
400         g_return_if_fail(parent_box != NULL);
401         if (checkbtn_forward_with_format) {
402                 g_return_if_fail(checkbtn_forward_with_format != NULL);
403         }
404         g_return_if_fail(edit_fw_quotemark != NULL);
405         g_return_if_fail(edit_fw_format != NULL);
406
407         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
408
409         if (checkbtn_forward_with_format)
410                 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
411                                    _("Use template when forwarding messages"));
412
413         vbox_quote = gtk_vbox_new (FALSE, 4);
414         gtk_widget_show(vbox_quote);
415         gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
416         gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
417
418         if (override_from_format) {
419                 CLAWS_TIP_DECL();
420
421                 hbox3 = gtk_hbox_new (FALSE, 8);
422                 gtk_widget_show (hbox3);
423                 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox3, FALSE, FALSE, 0);
424
425                 label_from = gtk_label_new (_("From"));
426                 gtk_misc_set_alignment(GTK_MISC(label_from), 1, 0.5);
427                 gtk_widget_show (label_from);
428                 gtk_box_pack_start (GTK_BOX (hbox3), label_from, FALSE, FALSE, 0);
429                 gtk_size_group_add_widget(size_group, label_from);
430
431                 entry_from = gtk_entry_new ();
432                 gtk_widget_show (entry_from);
433                 gtk_box_pack_start (GTK_BOX (hbox3), entry_from, TRUE, TRUE, 0);
434                 gtk_widget_set_size_request (entry_from, 100, -1);
435
436                 CLAWS_SET_TIP(entry_from,
437                                 _("Override From header. This doesn't change the account used to forward."));
438         }
439
440         hbox1 = gtk_hbox_new (FALSE, 32);
441         gtk_widget_show (hbox1);
442         gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
443
444         hbox2 = gtk_hbox_new (FALSE, 8);
445         gtk_widget_show (hbox2);
446         gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
447
448         label_quotemark = gtk_label_new (_("Quotation mark"));
449         gtk_misc_set_alignment(GTK_MISC(label_quotemark), 1, 0.5);
450         gtk_widget_show (label_quotemark);
451         gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
452         gtk_size_group_add_widget(size_group, label_quotemark);
453
454         entry_fw_quotemark = gtk_entry_new ();
455         gtk_widget_show (entry_fw_quotemark);
456         gtk_box_pack_start (GTK_BOX (hbox2), entry_fw_quotemark,
457                             FALSE, FALSE, 0);
458         gtk_widget_set_size_request (entry_fw_quotemark, 64, -1);
459
460         scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
461         gtk_widget_show (scrolledwin_quotefmt);
462         gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
463                             TRUE, TRUE, 0);
464         gtk_scrolled_window_set_policy
465                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
466                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
467         gtk_scrolled_window_set_shadow_type
468                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
469
470         text_fw_quotefmt = gtk_text_view_new ();
471         if (prefs_common.textfont) {
472                 PangoFontDescription *font_desc;
473
474                 font_desc = pango_font_description_from_string
475                                                 (prefs_common.textfont);
476                 if (font_desc) {
477                         gtk_widget_modify_font(text_fw_quotefmt, font_desc);
478                         pango_font_description_free(font_desc);
479                 }
480         }
481         gtk_widget_show(text_fw_quotefmt);
482         gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt),
483                           text_fw_quotefmt);
484         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_fw_quotefmt), TRUE);
485         gtk_widget_set_size_request (text_fw_quotefmt, -1, 100);
486
487         if (checkbtn_forward_with_format) {
488                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
489                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_fw_quotemark);
490                 if (override_from_format) {
491                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_from);
492                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_from);
493                 }
494                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_fw_quotefmt);
495         }
496
497         if (add_info_button)
498                 quotefmt_add_info_button(parent_window, vbox_quote);
499         if (set_defaults_func)
500                 quotefmt_add_defaults_button(parent_window, vbox_quote, set_defaults_func);
501
502         if (checkbtn_forward_with_format)
503                 *checkbtn_forward_with_format = checkbtn_use_format;
504         *edit_fw_quotemark = entry_fw_quotemark;
505         if (override_from_format)
506                 *override_from_format = entry_from;
507         *edit_fw_format = text_fw_quotefmt;
508 }
509
510 void quotefmt_add_info_button(GtkWindow *parent_window, GtkWidget *parent_box)
511 {
512         GtkWidget *hbox_formatdesc;
513         GtkWidget *btn_formatdesc;
514
515         hbox_formatdesc = gtk_hbox_new (FALSE, 32);
516         gtk_widget_show (hbox_formatdesc);
517         gtk_box_pack_start (GTK_BOX (parent_box), hbox_formatdesc, FALSE, FALSE,
518                                 VBOX_BORDER);
519
520 #if GTK_CHECK_VERSION(2, 8, 0)
521         btn_formatdesc = gtk_button_new_from_stock(GTK_STOCK_INFO);
522 #else
523         btn_formatdesc =
524                 gtk_button_new_with_label (_("Description of symbols..."));
525 #endif
526         gtk_widget_show (btn_formatdesc);
527         gtk_box_pack_start (GTK_BOX (hbox_formatdesc), btn_formatdesc, FALSE, FALSE, 0);
528         g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
529                          G_CALLBACK(quote_fmt_quote_description), GTK_WIDGET(parent_window));
530 }
531
532 void quotefmt_add_defaults_button(GtkWindow *parent_window,
533                                                                   GtkWidget *parent_box,
534                                                                   void(*set_defaults_func)(void))
535 {
536         GtkWidget *hbox_formatdesc;
537         GtkWidget *btn_formatdesc;
538
539         g_return_if_fail(set_defaults_func != NULL);
540
541         hbox_formatdesc = gtk_hbox_new (FALSE, 32);
542         gtk_widget_show (hbox_formatdesc);
543         gtk_box_pack_start (GTK_BOX (parent_box), hbox_formatdesc, FALSE, FALSE,
544                                 VBOX_BORDER);
545
546         btn_formatdesc = gtk_button_new_with_mnemonic (_("Defaults"));
547         gtk_button_set_image (GTK_BUTTON(btn_formatdesc),
548                 gtk_image_new_from_stock(GTK_STOCK_UNDO, GTK_ICON_SIZE_BUTTON));
549         gtk_widget_show (btn_formatdesc);
550         gtk_box_pack_start (GTK_BOX (hbox_formatdesc), btn_formatdesc, FALSE, FALSE, 0);
551         g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
552                          G_CALLBACK(set_defaults_func), GTK_WIDGET(parent_window));
553 }
554
555 void quotefmt_check_new_msg_formats(gboolean use_format,
556                                     gchar *override_from_fmt,
557                                     gchar *subject_fmt,
558                                     gchar *body_fmt)
559 {
560         if (use_format) {
561                 gint line;
562
563                 if (override_from_fmt && !prefs_template_string_is_valid(override_from_fmt, NULL, TRUE, TRUE))
564                         alertpanel_error(_("New message From format error."));
565
566                 if (!prefs_template_string_is_valid(subject_fmt, NULL, TRUE, FALSE))
567                         alertpanel_error(_("New message subject format error."));
568
569                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
570                         alertpanel_error(_("New message body format error at line %d."), line);
571                 }
572         }
573 }
574
575 void quotefmt_check_reply_formats(gboolean use_format,
576                                   gchar *override_from_fmt,
577                                   gchar *quotation_mark,
578                                   gchar *body_fmt)
579 {
580         if (use_format) {
581                 gint line;
582
583                 if (!prefs_template_string_is_valid(quotation_mark, NULL, TRUE, FALSE))
584                         alertpanel_error(_("Message reply quotation mark format error."));
585
586                 if (override_from_fmt && !prefs_template_string_is_valid(override_from_fmt, NULL, TRUE, TRUE))
587                         alertpanel_error(_("Message reply From format error."));
588
589                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
590                         alertpanel_error(_("Message reply format error at line %d."), line);
591                 }
592         }
593 }
594
595 void quotefmt_check_forward_formats(gboolean use_format,
596                                     gchar *override_from_fmt,
597                                     gchar *quotation_mark,
598                                     gchar *body_fmt)
599 {
600         if (use_format) {
601                 gint line;
602
603                 if (!prefs_template_string_is_valid(quotation_mark, NULL, TRUE, FALSE))
604                         alertpanel_error(_("Message forward quotation mark format error."));
605
606                 if (override_from_fmt && !prefs_template_string_is_valid(override_from_fmt, NULL, TRUE, TRUE))
607                         alertpanel_error(_("Message forward From format error."));
608
609                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
610                         alertpanel_error(_("Message forward format error at line %d."), line);
611                 }
612         }
613 }