*** empty log message ***
[claws.git] / src / quote_fmt.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2009 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_sig (%as)",           N_("account property: signature"), /* signature set in account prefs */
73         "%account_sigpath (%asp)",      N_("account property: signature path"), /* signature path set in account prefs */
74         "%account_dict (%aT)",          N_("account property: default dictionary"), /* main dict (if enabled) in account */
75         "%addrbook_cc (%ABc)",          N_("address book <span style=\"oblique\">completion</span>: Cc"), /* completion of 'Cc' from address book */
76         "%addrbook_from (%ABf)",        N_("address book <span style=\"oblique\">completion</span>: From"), /* completion of 'From' from address book */
77         "%addrbook_to (%ABt)",          N_("address book <span style=\"oblique\">completion</span>: To"), /* completion of 'To' from address book */
78         "\\%",                          N_("literal %"),
79         "\\\\",                         N_("literal backslash"),
80         "\\?",                          N_("literal question mark"),
81         "\\!",                          N_("literal exclamation mark"),
82         "\\|",                          N_("literal pipe"),
83         "\\{",                          N_("literal opening curly brace"),
84         "\\}",                          N_("literal closing curly brace"),
85         "\\t",                          N_("tab"),
86         "\\n",                          N_("new line"),
87         "",                                     NULL,
88         N_("<span weight=\"bold\">commands:</span>"),           NULL,
89         "?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, as, asp, aT, ABc, ABf, ABt]\nsymbols (or their long equivalent)"),
90         "!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, as, asp, aT, ABc, ABf, ABt]\nsymbols (or their long equivalent)"),
91         "|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 */
92         "|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 */
93         "|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 */
94         "|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 */
95         "",                                     NULL,
96         N_("<span weight=\"bold\">definition of terms:</span>"),        NULL,
97         "<span style=\"oblique\">expr</span>\n",                        N_("text that can contain any of the symbols or\ncommands above"),
98         "<span style=\"oblique\">sub_expr</span>\n",            N_("text that can contain any of the symbols (no\ncommands) above"),
99         "<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"),
100         NULL,NULL
101 };
102
103 static DescriptionWindow quote_desc_win = { 
104         NULL,
105         NULL,
106         2,
107         N_("Description of symbols"),
108         N_("The following symbols and commands can be used:"),
109         quote_desc_strings
110 };
111
112
113 void quote_fmt_quote_description(GtkWidget *widget, GtkWidget *pref_window)
114 {
115         quote_desc_win.parent = pref_window;
116         description_window_create(&quote_desc_win);
117 }
118
119 void quotefmt_create_new_msg_fmt_widgets(GtkWindow *parent_window,
120                                                 GtkWidget *parent_box,
121                                                 GtkWidget **checkbtn_compose_with_format,
122                                                 GtkWidget **override_from_format,
123                                                 GtkWidget **edit_subject_format,
124                                                 GtkWidget **edit_body_format,
125                                                 gboolean add_info_button,
126                                                 void(*set_defaults_func)(void))
127 {
128         GtkWidget *checkbtn_use_format = NULL;
129         GtkWidget *vbox_format;
130         GtkWidget *hbox_format;
131         GtkWidget *hbox2_format;
132         GtkWidget *label_from = NULL;
133         GtkWidget *entry_from = NULL;
134         GtkWidget *label_subject;
135         GtkWidget *entry_subject;
136         GtkWidget *scrolledwin_format;
137         GtkWidget *text_format;
138         GtkSizeGroup *size_group;
139
140         if (add_info_button)
141                 cm_return_if_fail(parent_window != NULL);
142         cm_return_if_fail(parent_box != NULL);
143         if (checkbtn_compose_with_format)
144                 cm_return_if_fail(checkbtn_compose_with_format != NULL);
145
146         cm_return_if_fail(edit_subject_format != NULL);
147         cm_return_if_fail(edit_body_format != NULL);
148
149         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
150
151         if (checkbtn_compose_with_format)
152                 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format, 
153                                    _("Use template when composing new messages"));
154
155         vbox_format = gtk_vbox_new (FALSE, 4);
156         gtk_widget_show(vbox_format);
157         gtk_container_add(GTK_CONTAINER (parent_box), vbox_format);
158         gtk_container_set_border_width (GTK_CONTAINER (vbox_format), 8);
159
160         if (override_from_format) {
161                 CLAWS_TIP_DECL();
162
163                 hbox2_format = gtk_hbox_new (FALSE, 8);
164                 gtk_widget_show (hbox2_format);
165                 gtk_box_pack_start (GTK_BOX (vbox_format), hbox2_format, FALSE, FALSE, 0);
166
167                 label_from = gtk_label_new (_("From"));
168                 gtk_misc_set_alignment(GTK_MISC(label_from), 1, 0.5);
169                 gtk_widget_show (label_from);
170                 gtk_box_pack_start (GTK_BOX (hbox2_format), label_from, FALSE, FALSE, 0);
171                 gtk_size_group_add_widget(size_group, label_from);
172
173                 entry_from = gtk_entry_new ();
174                 gtk_widget_show (entry_from);
175                 gtk_box_pack_start (GTK_BOX (hbox2_format), entry_from, TRUE, TRUE, 0);
176                 gtk_widget_set_size_request (entry_from, 100, -1);
177
178                 CLAWS_SET_TIP(entry_from,
179                                 _("Override From header. This doesn't change the account used to compose the new message."));
180         }
181
182         hbox_format = gtk_hbox_new (FALSE, 8);
183         gtk_widget_show (hbox_format);
184         gtk_box_pack_start (GTK_BOX (vbox_format), hbox_format, FALSE, FALSE, 0);
185
186         label_subject = gtk_label_new (_("Subject"));
187         gtk_misc_set_alignment(GTK_MISC(label_subject), 1, 0.5);
188         gtk_widget_show (label_subject);
189         gtk_box_pack_start (GTK_BOX (hbox_format), label_subject, FALSE, FALSE, 0);
190         gtk_size_group_add_widget(size_group, label_subject);
191
192         entry_subject = gtk_entry_new ();
193         gtk_widget_show (entry_subject);
194         gtk_box_pack_start (GTK_BOX (hbox_format), entry_subject, TRUE, TRUE, 0);
195         gtk_widget_set_size_request (entry_subject, 100, -1);
196
197         scrolledwin_format = gtk_scrolled_window_new (NULL, NULL);
198         gtk_widget_show (scrolledwin_format);
199         gtk_box_pack_start (GTK_BOX (vbox_format), scrolledwin_format,
200                             TRUE, TRUE, 0);
201         gtk_scrolled_window_set_policy
202                 (GTK_SCROLLED_WINDOW (scrolledwin_format),
203                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
204         gtk_scrolled_window_set_shadow_type
205                 (GTK_SCROLLED_WINDOW (scrolledwin_format), GTK_SHADOW_IN);
206
207         text_format = gtk_text_view_new ();
208         if (prefs_common.textfont) {
209                 PangoFontDescription *font_desc;
210
211                 font_desc = pango_font_description_from_string
212                                                 (prefs_common.textfont);
213                 if (font_desc) {
214                         gtk_widget_modify_font(text_format, font_desc);
215                         pango_font_description_free(font_desc);
216                 }
217         }
218         gtk_widget_show(text_format);
219         gtk_container_add(GTK_CONTAINER(scrolledwin_format), text_format);
220         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_format), TRUE);
221         gtk_widget_set_size_request(text_format, -1, 100);
222
223         if (checkbtn_compose_with_format) {
224                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_subject);
225                 if (override_from_format) {
226                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_from);
227                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_from);
228                 }
229                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_subject);
230                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_format);
231         }
232
233         if (add_info_button)
234                 quotefmt_add_info_button(parent_window, vbox_format);
235         if (set_defaults_func)
236                 quotefmt_add_defaults_button(parent_window, vbox_format, set_defaults_func);
237
238         if (checkbtn_compose_with_format)
239                 *checkbtn_compose_with_format = checkbtn_use_format;
240         if (override_from_format)
241                 *override_from_format = entry_from;
242         *edit_subject_format = entry_subject;
243         *edit_body_format = text_format;
244 }
245
246 void quotefmt_create_reply_fmt_widgets(GtkWindow *parent_window,
247                                                 GtkWidget *parent_box,
248                                                 GtkWidget **checkbtn_reply_with_format,
249                                                 GtkWidget **override_from_format,
250                                                 GtkWidget **edit_reply_quotemark,
251                                                 GtkWidget **edit_reply_format,
252                                                 gboolean add_info_button,
253                                                 void(*set_defaults_func)(void))
254 {
255         GtkWidget *checkbtn_use_format = NULL;
256         GtkWidget *vbox_quote;
257         GtkWidget *hbox1;
258         GtkWidget *hbox2;
259         GtkWidget *hbox3;
260         GtkWidget *label_quotemark;
261         GtkWidget *entry_quotemark;
262         GtkWidget *label_from = NULL;
263         GtkWidget *entry_from = NULL;
264         GtkWidget *scrolledwin_quotefmt;
265         GtkWidget *text_quotefmt;
266         GtkSizeGroup *size_group;
267
268         if (add_info_button)
269                 cm_return_if_fail(parent_window != NULL);
270         cm_return_if_fail(parent_box != NULL);
271         if (checkbtn_reply_with_format)
272                 cm_return_if_fail(checkbtn_reply_with_format != NULL);
273
274         cm_return_if_fail(edit_reply_quotemark != NULL);
275         cm_return_if_fail(edit_reply_format != NULL);
276
277         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
278
279         if (checkbtn_reply_with_format)
280                 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
281                                    _("Use template when replying to messages"));
282
283         vbox_quote = gtk_vbox_new (FALSE, 4);
284         gtk_widget_show(vbox_quote);
285         gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
286         gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
287
288         if (override_from_format) {
289                 CLAWS_TIP_DECL();
290
291                 hbox3 = gtk_hbox_new (FALSE, 8);
292                 gtk_widget_show (hbox3);
293                 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox3, FALSE, FALSE, 0);
294
295                 label_from = gtk_label_new (_("From"));
296                 gtk_misc_set_alignment(GTK_MISC(label_from), 1, 0.5);
297                 gtk_widget_show (label_from);
298                 gtk_box_pack_start (GTK_BOX (hbox3), label_from, FALSE, FALSE, 0);
299                 gtk_size_group_add_widget(size_group, label_from);
300
301                 entry_from = gtk_entry_new ();
302                 gtk_widget_show (entry_from);
303                 gtk_box_pack_start (GTK_BOX (hbox3), entry_from, TRUE, TRUE, 0);
304                 gtk_widget_set_size_request (entry_from, 100, -1);
305
306                 CLAWS_SET_TIP(entry_from,
307                                 _("Override From header. This doesn't change the account used to reply."));
308         }
309
310         hbox1 = gtk_hbox_new (FALSE, 32);
311         gtk_widget_show (hbox1);
312         gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
313
314         hbox2 = gtk_hbox_new (FALSE, 8);
315         gtk_widget_show (hbox2);
316         gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
317
318         label_quotemark = gtk_label_new (_("Quotation mark"));
319         gtk_misc_set_alignment(GTK_MISC(label_quotemark), 1, 0.5);
320         gtk_widget_show (label_quotemark);
321         gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
322         gtk_size_group_add_widget(size_group, label_quotemark);
323
324         entry_quotemark = gtk_entry_new ();
325         gtk_widget_show (entry_quotemark);
326         gtk_box_pack_start (GTK_BOX (hbox2), entry_quotemark, FALSE, FALSE, 0);
327         gtk_widget_set_size_request (entry_quotemark, 64, -1);
328
329         scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
330         gtk_widget_show (scrolledwin_quotefmt);
331         gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
332                             TRUE, TRUE, 0);
333         gtk_scrolled_window_set_policy
334                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
335                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
336         gtk_scrolled_window_set_shadow_type
337                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
338
339         text_quotefmt = gtk_text_view_new ();
340         if (prefs_common.textfont) {
341                 PangoFontDescription *font_desc;
342
343                 font_desc = pango_font_description_from_string
344                                                 (prefs_common.textfont);
345                 if (font_desc) {
346                         gtk_widget_modify_font(text_quotefmt, font_desc);
347                         pango_font_description_free(font_desc);
348                 }
349         }
350         gtk_widget_show(text_quotefmt);
351         gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt), text_quotefmt);
352         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_quotefmt), TRUE);
353         gtk_widget_set_size_request(text_quotefmt, -1, 100);
354
355         if (checkbtn_reply_with_format) {
356                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
357                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_quotemark);
358                 if (override_from_format) {
359                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_from);
360                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_from);
361                 }
362                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_quotefmt);
363         }
364
365         if (add_info_button)
366                 quotefmt_add_info_button(parent_window, vbox_quote);
367         if (set_defaults_func)
368                 quotefmt_add_defaults_button(parent_window, vbox_quote, set_defaults_func);
369
370         if (checkbtn_reply_with_format)
371                 *checkbtn_reply_with_format = checkbtn_use_format;
372         *edit_reply_quotemark = entry_quotemark;
373         if (override_from_format)
374                 *override_from_format = entry_from;
375         *edit_reply_format = text_quotefmt;
376 }
377
378 void quotefmt_create_forward_fmt_widgets(GtkWindow *parent_window,
379                                                 GtkWidget *parent_box,
380                                                 GtkWidget **checkbtn_forward_with_format,
381                                                 GtkWidget **override_from_format,
382                                                 GtkWidget **edit_fw_quotemark,
383                                                 GtkWidget **edit_fw_format,
384                                                 gboolean add_info_button,
385                                                 void(*set_defaults_func)(void))
386 {
387         GtkWidget *checkbtn_use_format = NULL;
388         GtkWidget *vbox_quote;
389         GtkWidget *hbox1;
390         GtkWidget *hbox2;
391         GtkWidget *hbox3;
392         GtkWidget *label_quotemark;
393         GtkWidget *entry_fw_quotemark;
394         GtkWidget *label_from = NULL;
395         GtkWidget *entry_from = NULL;
396         GtkWidget *scrolledwin_quotefmt;
397         GtkWidget *text_fw_quotefmt;
398         GtkSizeGroup *size_group;
399
400         if (add_info_button)
401                 cm_return_if_fail(parent_window != NULL);
402         cm_return_if_fail(parent_box != NULL);
403         if (checkbtn_forward_with_format) {
404                 cm_return_if_fail(checkbtn_forward_with_format != NULL);
405         }
406         cm_return_if_fail(edit_fw_quotemark != NULL);
407         cm_return_if_fail(edit_fw_format != NULL);
408
409         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
410
411         if (checkbtn_forward_with_format)
412                 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
413                                    _("Use template when forwarding messages"));
414
415         vbox_quote = gtk_vbox_new (FALSE, 4);
416         gtk_widget_show(vbox_quote);
417         gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
418         gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
419
420         if (override_from_format) {
421                 CLAWS_TIP_DECL();
422
423                 hbox3 = gtk_hbox_new (FALSE, 8);
424                 gtk_widget_show (hbox3);
425                 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox3, FALSE, FALSE, 0);
426
427                 label_from = gtk_label_new (_("From"));
428                 gtk_misc_set_alignment(GTK_MISC(label_from), 1, 0.5);
429                 gtk_widget_show (label_from);
430                 gtk_box_pack_start (GTK_BOX (hbox3), label_from, FALSE, FALSE, 0);
431                 gtk_size_group_add_widget(size_group, label_from);
432
433                 entry_from = gtk_entry_new ();
434                 gtk_widget_show (entry_from);
435                 gtk_box_pack_start (GTK_BOX (hbox3), entry_from, TRUE, TRUE, 0);
436                 gtk_widget_set_size_request (entry_from, 100, -1);
437
438                 CLAWS_SET_TIP(entry_from,
439                                 _("Override From header. This doesn't change the account used to forward."));
440         }
441
442         hbox1 = gtk_hbox_new (FALSE, 32);
443         gtk_widget_show (hbox1);
444         gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
445
446         hbox2 = gtk_hbox_new (FALSE, 8);
447         gtk_widget_show (hbox2);
448         gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
449
450         label_quotemark = gtk_label_new (_("Quotation mark"));
451         gtk_misc_set_alignment(GTK_MISC(label_quotemark), 1, 0.5);
452         gtk_widget_show (label_quotemark);
453         gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
454         gtk_size_group_add_widget(size_group, label_quotemark);
455
456         entry_fw_quotemark = gtk_entry_new ();
457         gtk_widget_show (entry_fw_quotemark);
458         gtk_box_pack_start (GTK_BOX (hbox2), entry_fw_quotemark,
459                             FALSE, FALSE, 0);
460         gtk_widget_set_size_request (entry_fw_quotemark, 64, -1);
461
462         scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
463         gtk_widget_show (scrolledwin_quotefmt);
464         gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
465                             TRUE, TRUE, 0);
466         gtk_scrolled_window_set_policy
467                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
468                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
469         gtk_scrolled_window_set_shadow_type
470                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
471
472         text_fw_quotefmt = gtk_text_view_new ();
473         if (prefs_common.textfont) {
474                 PangoFontDescription *font_desc;
475
476                 font_desc = pango_font_description_from_string
477                                                 (prefs_common.textfont);
478                 if (font_desc) {
479                         gtk_widget_modify_font(text_fw_quotefmt, font_desc);
480                         pango_font_description_free(font_desc);
481                 }
482         }
483         gtk_widget_show(text_fw_quotefmt);
484         gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt),
485                           text_fw_quotefmt);
486         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_fw_quotefmt), TRUE);
487         gtk_widget_set_size_request (text_fw_quotefmt, -1, 100);
488
489         if (checkbtn_forward_with_format) {
490                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
491                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_fw_quotemark);
492                 if (override_from_format) {
493                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_from);
494                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_from);
495                 }
496                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_fw_quotefmt);
497         }
498
499         if (add_info_button)
500                 quotefmt_add_info_button(parent_window, vbox_quote);
501         if (set_defaults_func)
502                 quotefmt_add_defaults_button(parent_window, vbox_quote, set_defaults_func);
503
504         if (checkbtn_forward_with_format)
505                 *checkbtn_forward_with_format = checkbtn_use_format;
506         *edit_fw_quotemark = entry_fw_quotemark;
507         if (override_from_format)
508                 *override_from_format = entry_from;
509         *edit_fw_format = text_fw_quotefmt;
510 }
511
512 void quotefmt_add_info_button(GtkWindow *parent_window, GtkWidget *parent_box)
513 {
514         GtkWidget *hbox_formatdesc;
515         GtkWidget *btn_formatdesc;
516
517         hbox_formatdesc = gtk_hbox_new (FALSE, 32);
518         gtk_widget_show (hbox_formatdesc);
519         gtk_box_pack_start (GTK_BOX (parent_box), hbox_formatdesc, FALSE, FALSE,
520                                 VBOX_BORDER);
521
522 #if GTK_CHECK_VERSION(2, 8, 0)
523         btn_formatdesc = gtk_button_new_from_stock(GTK_STOCK_INFO);
524 #else
525         btn_formatdesc =
526                 gtk_button_new_with_label (_("Description of symbols..."));
527 #endif
528         gtk_widget_show (btn_formatdesc);
529         gtk_box_pack_start (GTK_BOX (hbox_formatdesc), btn_formatdesc, FALSE, FALSE, 0);
530         g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
531                          G_CALLBACK(quote_fmt_quote_description), GTK_WIDGET(parent_window));
532 }
533
534 void quotefmt_add_defaults_button(GtkWindow *parent_window,
535                                                                   GtkWidget *parent_box,
536                                                                   void(*set_defaults_func)(void))
537 {
538         GtkWidget *hbox_formatdesc;
539         GtkWidget *btn_formatdesc;
540
541         cm_return_if_fail(set_defaults_func != NULL);
542
543         hbox_formatdesc = gtk_hbox_new (FALSE, 32);
544         gtk_widget_show (hbox_formatdesc);
545         gtk_box_pack_start (GTK_BOX (parent_box), hbox_formatdesc, FALSE, FALSE,
546                                 VBOX_BORDER);
547
548         btn_formatdesc = gtk_button_new_with_mnemonic (_("Defaults"));
549         gtk_button_set_image (GTK_BUTTON(btn_formatdesc),
550                 gtk_image_new_from_stock(GTK_STOCK_UNDO, GTK_ICON_SIZE_BUTTON));
551         gtk_widget_show (btn_formatdesc);
552         gtk_box_pack_start (GTK_BOX (hbox_formatdesc), btn_formatdesc, FALSE, FALSE, 0);
553         g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
554                          G_CALLBACK(set_defaults_func), GTK_WIDGET(parent_window));
555 }
556
557 void quotefmt_check_new_msg_formats(gboolean use_format,
558                                     gchar *override_from_fmt,
559                                     gchar *subject_fmt,
560                                     gchar *body_fmt)
561 {
562         if (use_format) {
563                 gint line;
564
565                 if (override_from_fmt && !prefs_template_string_is_valid(override_from_fmt, NULL, TRUE, TRUE))
566                         alertpanel_error(_("The \"From\" field of the \"New message\" template contains an invalid email address."));
567
568                 if (!prefs_template_string_is_valid(subject_fmt, NULL, TRUE, FALSE))
569                         alertpanel_error(_("The \"Subject\" field of the \"New message\" template is invalid."));
570
571                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
572                         alertpanel_error(_("The body of the \"New message\" template has an error at line %d."), line);
573                 }
574         }
575 }
576
577 void quotefmt_check_reply_formats(gboolean use_format,
578                                   gchar *override_from_fmt,
579                                   gchar *quotation_mark,
580                                   gchar *body_fmt)
581 {
582         if (use_format) {
583                 gint line;
584
585                 if (!prefs_template_string_is_valid(quotation_mark, NULL, TRUE, FALSE))
586                         alertpanel_error(_("The \"Quotation mark\" field of the \"Reply\" template is invalid."));
587
588                 if (override_from_fmt && !prefs_template_string_is_valid(override_from_fmt, NULL, TRUE, TRUE))
589                         alertpanel_error(_("The \"From\" field of the \"Reply\" template contains an invalid email address."));
590
591                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
592                         alertpanel_error(_("The body of the \"Reply\" template has an error at line %d."), line);
593                 }
594         }
595 }
596
597 void quotefmt_check_forward_formats(gboolean use_format,
598                                     gchar *override_from_fmt,
599                                     gchar *quotation_mark,
600                                     gchar *body_fmt)
601 {
602         if (use_format) {
603                 gint line;
604
605                 if (!prefs_template_string_is_valid(quotation_mark, NULL, TRUE, FALSE))
606                         alertpanel_error(_("The \"Quotation mark\" field of the \"Forward\" template is invalid."));
607
608                 if (override_from_fmt && !prefs_template_string_is_valid(override_from_fmt, NULL, TRUE, TRUE))
609                         alertpanel_error(_("The \"From\" field of the \"Forward\" template contains an invalid email address."));
610
611                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
612                         alertpanel_error(_("The body of the \"Forward\" template has an error at line %d."), line);
613                 }
614         }
615 }