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