Archiver plugin update and review:
[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         "|attach_output{<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 a command-line to get\nthe filename from"), /* attach file whose name's got from program output */
97         "",                                     NULL,
98         N_("<span weight=\"bold\">definition of terms:</span>"),        NULL,
99         "<span style=\"oblique\">expr</span>\n",                        N_("text that can contain any of the symbols or\ncommands above"),
100         "<span style=\"oblique\">sub_expr</span>\n",            N_("text that can contain any of the symbols (no\ncommands) above"),
101         "<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"),
102         NULL,NULL
103 };
104
105 static DescriptionWindow quote_desc_win = { 
106         NULL,
107         NULL,
108         TRUE,
109         2,
110         N_("Description of symbols"),
111         N_("The following symbols and commands can be used:"),
112         quote_desc_strings
113 };
114
115
116 void quote_fmt_quote_description(GtkWidget *widget, GtkWidget *pref_window)
117 {
118         quote_desc_win.parent = pref_window;
119         description_window_create(&quote_desc_win);
120 }
121
122 static void quote_fmt_add_buttons(GtkWindow* parent_window, GtkWidget *parent_box,
123                         gboolean add_info_button, void(*set_defaults_func)(void)) {
124         GtkWidget *hbox_btns;
125         
126         if (!add_info_button && !set_defaults_func)
127                 return;
128         
129         hbox_btns = gtk_hbox_new(FALSE, 0);
130         gtk_box_pack_end (GTK_BOX(parent_box), hbox_btns, FALSE, TRUE, 0);      
131
132         if (add_info_button)
133                 quotefmt_add_info_button(parent_window, hbox_btns);
134         if (set_defaults_func)
135                 quotefmt_add_defaults_button(parent_window, hbox_btns, set_defaults_func);
136
137         gtk_widget_show(GTK_WIDGET(hbox_btns));
138 }
139
140 void quotefmt_create_new_msg_fmt_widgets(GtkWindow *parent_window,
141                                                 GtkWidget *parent_box,
142                                                 GtkWidget **checkbtn_compose_with_format,
143                                                 GtkWidget **override_from_format,
144                                                 GtkWidget **edit_subject_format,
145                                                 GtkWidget **edit_body_format,
146                                                 gboolean add_info_button,
147                                                 void(*set_defaults_func)(void))
148 {
149         GtkWidget *checkbtn_use_format = NULL;
150         GtkWidget *vbox_format;
151         GtkWidget *hbox_format;
152         GtkWidget *hbox2_format;
153         GtkWidget *label_from = NULL;
154         GtkWidget *entry_from = NULL;
155         GtkWidget *label_subject;
156         GtkWidget *entry_subject;
157         GtkWidget *scrolledwin_format;
158         GtkWidget *text_format;
159         GtkSizeGroup *size_group;
160
161         if (add_info_button)
162                 cm_return_if_fail(parent_window != NULL);
163         cm_return_if_fail(parent_box != NULL);
164         if (checkbtn_compose_with_format)
165                 cm_return_if_fail(checkbtn_compose_with_format != NULL);
166
167         cm_return_if_fail(edit_subject_format != NULL);
168         cm_return_if_fail(edit_body_format != NULL);
169
170         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
171
172         if (checkbtn_compose_with_format)
173                 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format, 
174                                    _("Use template when composing new messages"));
175
176         vbox_format = gtk_vbox_new (FALSE, 4);
177         gtk_widget_show(vbox_format);
178         gtk_container_add(GTK_CONTAINER (parent_box), vbox_format);
179         gtk_container_set_border_width (GTK_CONTAINER (vbox_format), 8);
180
181         if (override_from_format) {
182                 hbox2_format = gtk_hbox_new (FALSE, 8);
183                 gtk_widget_show (hbox2_format);
184                 gtk_box_pack_start (GTK_BOX (vbox_format), hbox2_format, FALSE, FALSE, 0);
185
186                 label_from = gtk_label_new (prefs_common_translated_header_name("From"));
187                 gtk_misc_set_alignment(GTK_MISC(label_from), 1, 0.5);
188                 gtk_widget_show (label_from);
189                 gtk_box_pack_start (GTK_BOX (hbox2_format), label_from, FALSE, FALSE, 0);
190                 gtk_size_group_add_widget(size_group, label_from);
191
192                 entry_from = gtk_entry_new ();
193                 gtk_widget_show (entry_from);
194                 gtk_box_pack_start (GTK_BOX (hbox2_format), entry_from, TRUE, TRUE, 0);
195                 gtk_widget_set_size_request (entry_from, 100, -1);
196
197                 CLAWS_SET_TIP(entry_from,
198                                 _("Override From header. This doesn't change the account used to compose the new message."));
199         }
200
201         hbox_format = gtk_hbox_new (FALSE, 8);
202         gtk_widget_show (hbox_format);
203         gtk_box_pack_start (GTK_BOX (vbox_format), hbox_format, FALSE, FALSE, 0);
204
205         label_subject = gtk_label_new (prefs_common_translated_header_name("Subject"));
206         gtk_misc_set_alignment(GTK_MISC(label_subject), 1, 0.5);
207         gtk_widget_show (label_subject);
208         gtk_box_pack_start (GTK_BOX (hbox_format), label_subject, FALSE, FALSE, 0);
209         gtk_size_group_add_widget(size_group, label_subject);
210
211         entry_subject = gtk_entry_new ();
212         gtk_widget_show (entry_subject);
213         gtk_box_pack_start (GTK_BOX (hbox_format), entry_subject, TRUE, TRUE, 0);
214         gtk_widget_set_size_request (entry_subject, 100, -1);
215
216         scrolledwin_format = gtk_scrolled_window_new (NULL, NULL);
217         gtk_widget_show (scrolledwin_format);
218         gtk_box_pack_start (GTK_BOX (vbox_format), scrolledwin_format,
219                             TRUE, TRUE, 0);
220         gtk_scrolled_window_set_policy
221                 (GTK_SCROLLED_WINDOW (scrolledwin_format),
222                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
223         gtk_scrolled_window_set_shadow_type
224                 (GTK_SCROLLED_WINDOW (scrolledwin_format), GTK_SHADOW_IN);
225
226         text_format = gtk_text_view_new ();
227         if (prefs_common.textfont) {
228                 PangoFontDescription *font_desc;
229
230                 font_desc = pango_font_description_from_string
231                                                 (prefs_common.textfont);
232                 if (font_desc) {
233                         gtk_widget_modify_font(text_format, font_desc);
234                         pango_font_description_free(font_desc);
235                 }
236         }
237         gtk_widget_show(text_format);
238         gtk_container_add(GTK_CONTAINER(scrolledwin_format), text_format);
239         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_format), TRUE);
240         gtk_widget_set_size_request(text_format, -1, 100);
241
242         if (checkbtn_compose_with_format) {
243                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_subject);
244                 if (override_from_format) {
245                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_from);
246                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_from);
247                 }
248                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_subject);
249                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_format);
250         }
251
252         quote_fmt_add_buttons(parent_window, vbox_format,
253                                 add_info_button, set_defaults_func);
254
255         if (checkbtn_compose_with_format)
256                 *checkbtn_compose_with_format = checkbtn_use_format;
257         if (override_from_format)
258                 *override_from_format = entry_from;
259         *edit_subject_format = entry_subject;
260         *edit_body_format = text_format;
261
262         g_object_unref(G_OBJECT(size_group));
263 }
264
265 void quotefmt_create_reply_fmt_widgets(GtkWindow *parent_window,
266                                                 GtkWidget *parent_box,
267                                                 GtkWidget **checkbtn_reply_with_format,
268                                                 GtkWidget **override_from_format,
269                                                 GtkWidget **edit_reply_quotemark,
270                                                 GtkWidget **edit_reply_format,
271                                                 gboolean add_info_button,
272                                                 void(*set_defaults_func)(void))
273 {
274         GtkWidget *checkbtn_use_format = NULL;
275         GtkWidget *vbox_quote;
276         GtkWidget *hbox1;
277         GtkWidget *hbox2;
278         GtkWidget *hbox3;
279         GtkWidget *label_quotemark;
280         GtkWidget *entry_quotemark;
281         GtkWidget *label_from = NULL;
282         GtkWidget *entry_from = NULL;
283         GtkWidget *scrolledwin_quotefmt;
284         GtkWidget *text_quotefmt;
285         GtkSizeGroup *size_group;
286
287         if (add_info_button)
288                 cm_return_if_fail(parent_window != NULL);
289         cm_return_if_fail(parent_box != NULL);
290         if (checkbtn_reply_with_format)
291                 cm_return_if_fail(checkbtn_reply_with_format != NULL);
292
293         cm_return_if_fail(edit_reply_quotemark != NULL);
294         cm_return_if_fail(edit_reply_format != NULL);
295
296         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
297
298         if (checkbtn_reply_with_format)
299                 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
300                                    _("Use template when replying to messages"));
301
302         vbox_quote = gtk_vbox_new (FALSE, 4);
303         gtk_widget_show(vbox_quote);
304         gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
305         gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
306
307         if (override_from_format) {
308                 hbox3 = gtk_hbox_new (FALSE, 8);
309                 gtk_widget_show (hbox3);
310                 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox3, FALSE, FALSE, 0);
311
312                 label_from = gtk_label_new (prefs_common_translated_header_name("From:"));
313                 gtk_misc_set_alignment(GTK_MISC(label_from), 1, 0.5);
314                 gtk_widget_show (label_from);
315                 gtk_box_pack_start (GTK_BOX (hbox3), label_from, FALSE, FALSE, 0);
316                 gtk_size_group_add_widget(size_group, label_from);
317
318                 entry_from = gtk_entry_new ();
319                 gtk_widget_show (entry_from);
320                 gtk_box_pack_start (GTK_BOX (hbox3), entry_from, TRUE, TRUE, 0);
321                 gtk_widget_set_size_request (entry_from, 100, -1);
322
323                 CLAWS_SET_TIP(entry_from,
324                                 _("Override From header. This doesn't change the account used to reply."));
325         }
326
327         hbox1 = gtk_hbox_new (FALSE, 32);
328         gtk_widget_show (hbox1);
329         gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
330
331         hbox2 = gtk_hbox_new (FALSE, 8);
332         gtk_widget_show (hbox2);
333         gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
334
335         label_quotemark = gtk_label_new (_("Quotation mark"));
336         gtk_misc_set_alignment(GTK_MISC(label_quotemark), 1, 0.5);
337         gtk_widget_show (label_quotemark);
338         gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
339         gtk_size_group_add_widget(size_group, label_quotemark);
340
341         entry_quotemark = gtk_entry_new ();
342         gtk_widget_show (entry_quotemark);
343         gtk_box_pack_start (GTK_BOX (hbox2), entry_quotemark, FALSE, FALSE, 0);
344         gtk_widget_set_size_request (entry_quotemark, 64, -1);
345
346         scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
347         gtk_widget_show (scrolledwin_quotefmt);
348         gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
349                             TRUE, TRUE, 0);
350         gtk_scrolled_window_set_policy
351                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
352                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
353         gtk_scrolled_window_set_shadow_type
354                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
355
356         text_quotefmt = gtk_text_view_new ();
357         if (prefs_common.textfont) {
358                 PangoFontDescription *font_desc;
359
360                 font_desc = pango_font_description_from_string
361                                                 (prefs_common.textfont);
362                 if (font_desc) {
363                         gtk_widget_modify_font(text_quotefmt, font_desc);
364                         pango_font_description_free(font_desc);
365                 }
366         }
367         gtk_widget_show(text_quotefmt);
368         gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt), text_quotefmt);
369         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_quotefmt), TRUE);
370         gtk_widget_set_size_request(text_quotefmt, -1, 100);
371
372         if (checkbtn_reply_with_format) {
373                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
374                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_quotemark);
375                 if (override_from_format) {
376                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_from);
377                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_from);
378                 }
379                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_quotefmt);
380         }
381
382         quote_fmt_add_buttons(parent_window, vbox_quote,
383                                 add_info_button, set_defaults_func);
384
385         if (checkbtn_reply_with_format)
386                 *checkbtn_reply_with_format = checkbtn_use_format;
387         *edit_reply_quotemark = entry_quotemark;
388         if (override_from_format)
389                 *override_from_format = entry_from;
390         *edit_reply_format = text_quotefmt;
391
392         g_object_unref(G_OBJECT(size_group));
393 }
394
395 void quotefmt_create_forward_fmt_widgets(GtkWindow *parent_window,
396                                                 GtkWidget *parent_box,
397                                                 GtkWidget **checkbtn_forward_with_format,
398                                                 GtkWidget **override_from_format,
399                                                 GtkWidget **edit_fw_quotemark,
400                                                 GtkWidget **edit_fw_format,
401                                                 gboolean add_info_button,
402                                                 void(*set_defaults_func)(void))
403 {
404         GtkWidget *checkbtn_use_format = NULL;
405         GtkWidget *vbox_quote;
406         GtkWidget *hbox1;
407         GtkWidget *hbox2;
408         GtkWidget *hbox3;
409         GtkWidget *label_quotemark;
410         GtkWidget *entry_fw_quotemark;
411         GtkWidget *label_from = NULL;
412         GtkWidget *entry_from = NULL;
413         GtkWidget *scrolledwin_quotefmt;
414         GtkWidget *text_fw_quotefmt;
415         GtkSizeGroup *size_group;
416
417         if (add_info_button)
418                 cm_return_if_fail(parent_window != NULL);
419         cm_return_if_fail(parent_box != NULL);
420         if (checkbtn_forward_with_format) {
421                 cm_return_if_fail(checkbtn_forward_with_format != NULL);
422         }
423         cm_return_if_fail(edit_fw_quotemark != NULL);
424         cm_return_if_fail(edit_fw_format != NULL);
425
426         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
427
428         if (checkbtn_forward_with_format)
429                 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
430                                    _("Use template when forwarding messages"));
431
432         vbox_quote = gtk_vbox_new (FALSE, 4);
433         gtk_widget_show(vbox_quote);
434         gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
435         gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
436
437         if (override_from_format) {
438                 hbox3 = gtk_hbox_new (FALSE, 8);
439                 gtk_widget_show (hbox3);
440                 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox3, FALSE, FALSE, 0);
441
442                 label_from = gtk_label_new (prefs_common_translated_header_name("From:"));
443                 gtk_misc_set_alignment(GTK_MISC(label_from), 1, 0.5);
444                 gtk_widget_show (label_from);
445                 gtk_box_pack_start (GTK_BOX (hbox3), label_from, FALSE, FALSE, 0);
446                 gtk_size_group_add_widget(size_group, label_from);
447
448                 entry_from = gtk_entry_new ();
449                 gtk_widget_show (entry_from);
450                 gtk_box_pack_start (GTK_BOX (hbox3), entry_from, TRUE, TRUE, 0);
451                 gtk_widget_set_size_request (entry_from, 100, -1);
452
453                 CLAWS_SET_TIP(entry_from,
454                                 _("Override From header. This doesn't change the account used to forward."));
455         }
456
457         hbox1 = gtk_hbox_new (FALSE, 32);
458         gtk_widget_show (hbox1);
459         gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
460
461         hbox2 = gtk_hbox_new (FALSE, 8);
462         gtk_widget_show (hbox2);
463         gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
464
465         label_quotemark = gtk_label_new (_("Quotation mark"));
466         gtk_misc_set_alignment(GTK_MISC(label_quotemark), 1, 0.5);
467         gtk_widget_show (label_quotemark);
468         gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
469         gtk_size_group_add_widget(size_group, label_quotemark);
470
471         entry_fw_quotemark = gtk_entry_new ();
472         gtk_widget_show (entry_fw_quotemark);
473         gtk_box_pack_start (GTK_BOX (hbox2), entry_fw_quotemark,
474                             FALSE, FALSE, 0);
475         gtk_widget_set_size_request (entry_fw_quotemark, 64, -1);
476
477         scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
478         gtk_widget_show (scrolledwin_quotefmt);
479         gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
480                             TRUE, TRUE, 0);
481         gtk_scrolled_window_set_policy
482                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
483                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
484         gtk_scrolled_window_set_shadow_type
485                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
486
487         text_fw_quotefmt = gtk_text_view_new ();
488         if (prefs_common.textfont) {
489                 PangoFontDescription *font_desc;
490
491                 font_desc = pango_font_description_from_string
492                                                 (prefs_common.textfont);
493                 if (font_desc) {
494                         gtk_widget_modify_font(text_fw_quotefmt, font_desc);
495                         pango_font_description_free(font_desc);
496                 }
497         }
498         gtk_widget_show(text_fw_quotefmt);
499         gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt),
500                           text_fw_quotefmt);
501         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_fw_quotefmt), TRUE);
502         gtk_widget_set_size_request (text_fw_quotefmt, -1, 100);
503
504         if (checkbtn_forward_with_format) {
505                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
506                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_fw_quotemark);
507                 if (override_from_format) {
508                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_from);
509                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_from);
510                 }
511                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_fw_quotefmt);
512         }
513
514         quote_fmt_add_buttons(parent_window, vbox_quote,
515                                 add_info_button, set_defaults_func);
516
517         if (checkbtn_forward_with_format)
518                 *checkbtn_forward_with_format = checkbtn_use_format;
519         *edit_fw_quotemark = entry_fw_quotemark;
520         if (override_from_format)
521                 *override_from_format = entry_from;
522         *edit_fw_format = text_fw_quotefmt;
523         
524         g_object_unref(G_OBJECT(size_group));
525 }
526
527 void quotefmt_add_info_button(GtkWindow *parent_window, GtkWidget *parent_box)
528 {
529         GtkWidget *btn_formatdesc;
530
531         btn_formatdesc = gtk_button_new_from_stock(GTK_STOCK_INFO);
532         gtk_widget_show (btn_formatdesc);
533         gtk_box_pack_start (GTK_BOX (parent_box), btn_formatdesc, FALSE, FALSE, 0);
534         g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
535                          G_CALLBACK(quote_fmt_quote_description), GTK_WIDGET(parent_window));
536 }
537
538 void quotefmt_add_defaults_button(GtkWindow *parent_window,
539                                                                   GtkWidget *parent_box,
540                                                                   void(*set_defaults_func)(void))
541 {
542         GtkWidget *btn_formatdesc;
543
544         cm_return_if_fail(set_defaults_func != NULL);
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_end (GTK_BOX (parent_box), 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(_("The \"From\" field of the \"New message\" template contains an invalid email address."));
565
566                 if (!prefs_template_string_is_valid(subject_fmt, NULL, TRUE, FALSE))
567                         alertpanel_error(_("The \"Subject\" field of the \"New message\" template is invalid."));
568
569                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
570                         alertpanel_error(_("The body of the \"New message\" template has an 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(_("The \"Quotation mark\" field of the \"Reply\" template is invalid."));
585
586                 if (override_from_fmt && !prefs_template_string_is_valid(override_from_fmt, NULL, TRUE, TRUE))
587                         alertpanel_error(_("The \"From\" field of the \"Reply\" template contains an invalid email address."));
588
589                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
590                         alertpanel_error(_("The body of the \"Reply\" template has an 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(_("The \"Quotation mark\" field of the \"Forward\" template is invalid."));
605
606                 if (override_from_fmt && !prefs_template_string_is_valid(override_from_fmt, NULL, TRUE, TRUE))
607                         alertpanel_error(_("The \"From\" field of the \"Forward\" template contains an invalid email address."));
608
609                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
610                         alertpanel_error(_("The body of the \"Forward\" template has an error at line %d."), line);
611                 }
612         }
613 }