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