Libravatar: more compact prefs, add hint to entry
[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         g_object_unref(G_OBJECT(size_group));
262 }
263
264 void quotefmt_create_reply_fmt_widgets(GtkWindow *parent_window,
265                                                 GtkWidget *parent_box,
266                                                 GtkWidget **checkbtn_reply_with_format,
267                                                 GtkWidget **override_from_format,
268                                                 GtkWidget **edit_reply_quotemark,
269                                                 GtkWidget **edit_reply_format,
270                                                 gboolean add_info_button,
271                                                 void(*set_defaults_func)(void))
272 {
273         GtkWidget *checkbtn_use_format = NULL;
274         GtkWidget *vbox_quote;
275         GtkWidget *hbox1;
276         GtkWidget *hbox2;
277         GtkWidget *hbox3;
278         GtkWidget *label_quotemark;
279         GtkWidget *entry_quotemark;
280         GtkWidget *label_from = NULL;
281         GtkWidget *entry_from = NULL;
282         GtkWidget *scrolledwin_quotefmt;
283         GtkWidget *text_quotefmt;
284         GtkSizeGroup *size_group;
285
286         if (add_info_button)
287                 cm_return_if_fail(parent_window != NULL);
288         cm_return_if_fail(parent_box != NULL);
289         if (checkbtn_reply_with_format)
290                 cm_return_if_fail(checkbtn_reply_with_format != NULL);
291
292         cm_return_if_fail(edit_reply_quotemark != NULL);
293         cm_return_if_fail(edit_reply_format != NULL);
294
295         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
296
297         if (checkbtn_reply_with_format)
298                 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
299                                    _("Use template when replying to messages"));
300
301         vbox_quote = gtk_vbox_new (FALSE, 4);
302         gtk_widget_show(vbox_quote);
303         gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
304         gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
305
306         if (override_from_format) {
307                 hbox3 = gtk_hbox_new (FALSE, 8);
308                 gtk_widget_show (hbox3);
309                 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox3, FALSE, FALSE, 0);
310
311                 label_from = gtk_label_new (prefs_common_translated_header_name("From"));
312                 gtk_misc_set_alignment(GTK_MISC(label_from), 1, 0.5);
313                 gtk_widget_show (label_from);
314                 gtk_box_pack_start (GTK_BOX (hbox3), label_from, FALSE, FALSE, 0);
315                 gtk_size_group_add_widget(size_group, label_from);
316
317                 entry_from = gtk_entry_new ();
318                 gtk_widget_show (entry_from);
319                 gtk_box_pack_start (GTK_BOX (hbox3), entry_from, TRUE, TRUE, 0);
320                 gtk_widget_set_size_request (entry_from, 100, -1);
321
322                 CLAWS_SET_TIP(entry_from,
323                                 _("Override From header. This doesn't change the account used to reply."));
324         }
325
326         hbox1 = gtk_hbox_new (FALSE, 32);
327         gtk_widget_show (hbox1);
328         gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
329
330         hbox2 = gtk_hbox_new (FALSE, 8);
331         gtk_widget_show (hbox2);
332         gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
333
334         label_quotemark = gtk_label_new (_("Quotation mark"));
335         gtk_misc_set_alignment(GTK_MISC(label_quotemark), 1, 0.5);
336         gtk_widget_show (label_quotemark);
337         gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
338         gtk_size_group_add_widget(size_group, label_quotemark);
339
340         entry_quotemark = gtk_entry_new ();
341         gtk_widget_show (entry_quotemark);
342         gtk_box_pack_start (GTK_BOX (hbox2), entry_quotemark, FALSE, FALSE, 0);
343         gtk_widget_set_size_request (entry_quotemark, 64, -1);
344
345         scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
346         gtk_widget_show (scrolledwin_quotefmt);
347         gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
348                             TRUE, TRUE, 0);
349         gtk_scrolled_window_set_policy
350                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
351                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
352         gtk_scrolled_window_set_shadow_type
353                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
354
355         text_quotefmt = gtk_text_view_new ();
356         if (prefs_common.textfont) {
357                 PangoFontDescription *font_desc;
358
359                 font_desc = pango_font_description_from_string
360                                                 (prefs_common.textfont);
361                 if (font_desc) {
362                         gtk_widget_modify_font(text_quotefmt, font_desc);
363                         pango_font_description_free(font_desc);
364                 }
365         }
366         gtk_widget_show(text_quotefmt);
367         gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt), text_quotefmt);
368         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_quotefmt), TRUE);
369         gtk_widget_set_size_request(text_quotefmt, -1, 100);
370
371         if (checkbtn_reply_with_format) {
372                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
373                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_quotemark);
374                 if (override_from_format) {
375                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_from);
376                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_from);
377                 }
378                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_quotefmt);
379         }
380
381         quote_fmt_add_buttons(parent_window, vbox_quote,
382                                 add_info_button, set_defaults_func);
383
384         if (checkbtn_reply_with_format)
385                 *checkbtn_reply_with_format = checkbtn_use_format;
386         *edit_reply_quotemark = entry_quotemark;
387         if (override_from_format)
388                 *override_from_format = entry_from;
389         *edit_reply_format = text_quotefmt;
390
391         g_object_unref(G_OBJECT(size_group));
392 }
393
394 void quotefmt_create_forward_fmt_widgets(GtkWindow *parent_window,
395                                                 GtkWidget *parent_box,
396                                                 GtkWidget **checkbtn_forward_with_format,
397                                                 GtkWidget **override_from_format,
398                                                 GtkWidget **edit_fw_quotemark,
399                                                 GtkWidget **edit_fw_format,
400                                                 gboolean add_info_button,
401                                                 void(*set_defaults_func)(void))
402 {
403         GtkWidget *checkbtn_use_format = NULL;
404         GtkWidget *vbox_quote;
405         GtkWidget *hbox1;
406         GtkWidget *hbox2;
407         GtkWidget *hbox3;
408         GtkWidget *label_quotemark;
409         GtkWidget *entry_fw_quotemark;
410         GtkWidget *label_from = NULL;
411         GtkWidget *entry_from = NULL;
412         GtkWidget *scrolledwin_quotefmt;
413         GtkWidget *text_fw_quotefmt;
414         GtkSizeGroup *size_group;
415
416         if (add_info_button)
417                 cm_return_if_fail(parent_window != NULL);
418         cm_return_if_fail(parent_box != NULL);
419         if (checkbtn_forward_with_format) {
420                 cm_return_if_fail(checkbtn_forward_with_format != NULL);
421         }
422         cm_return_if_fail(edit_fw_quotemark != NULL);
423         cm_return_if_fail(edit_fw_format != NULL);
424
425         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
426
427         if (checkbtn_forward_with_format)
428                 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
429                                    _("Use template when forwarding messages"));
430
431         vbox_quote = gtk_vbox_new (FALSE, 4);
432         gtk_widget_show(vbox_quote);
433         gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
434         gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
435
436         if (override_from_format) {
437                 hbox3 = gtk_hbox_new (FALSE, 8);
438                 gtk_widget_show (hbox3);
439                 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox3, FALSE, FALSE, 0);
440
441                 label_from = gtk_label_new (prefs_common_translated_header_name("From"));
442                 gtk_misc_set_alignment(GTK_MISC(label_from), 1, 0.5);
443                 gtk_widget_show (label_from);
444                 gtk_box_pack_start (GTK_BOX (hbox3), label_from, FALSE, FALSE, 0);
445                 gtk_size_group_add_widget(size_group, label_from);
446
447                 entry_from = gtk_entry_new ();
448                 gtk_widget_show (entry_from);
449                 gtk_box_pack_start (GTK_BOX (hbox3), entry_from, TRUE, TRUE, 0);
450                 gtk_widget_set_size_request (entry_from, 100, -1);
451
452                 CLAWS_SET_TIP(entry_from,
453                                 _("Override From header. This doesn't change the account used to forward."));
454         }
455
456         hbox1 = gtk_hbox_new (FALSE, 32);
457         gtk_widget_show (hbox1);
458         gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
459
460         hbox2 = gtk_hbox_new (FALSE, 8);
461         gtk_widget_show (hbox2);
462         gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
463
464         label_quotemark = gtk_label_new (_("Quotation mark"));
465         gtk_misc_set_alignment(GTK_MISC(label_quotemark), 1, 0.5);
466         gtk_widget_show (label_quotemark);
467         gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
468         gtk_size_group_add_widget(size_group, label_quotemark);
469
470         entry_fw_quotemark = gtk_entry_new ();
471         gtk_widget_show (entry_fw_quotemark);
472         gtk_box_pack_start (GTK_BOX (hbox2), entry_fw_quotemark,
473                             FALSE, FALSE, 0);
474         gtk_widget_set_size_request (entry_fw_quotemark, 64, -1);
475
476         scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
477         gtk_widget_show (scrolledwin_quotefmt);
478         gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
479                             TRUE, TRUE, 0);
480         gtk_scrolled_window_set_policy
481                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
482                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
483         gtk_scrolled_window_set_shadow_type
484                 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
485
486         text_fw_quotefmt = gtk_text_view_new ();
487         if (prefs_common.textfont) {
488                 PangoFontDescription *font_desc;
489
490                 font_desc = pango_font_description_from_string
491                                                 (prefs_common.textfont);
492                 if (font_desc) {
493                         gtk_widget_modify_font(text_fw_quotefmt, font_desc);
494                         pango_font_description_free(font_desc);
495                 }
496         }
497         gtk_widget_show(text_fw_quotefmt);
498         gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt),
499                           text_fw_quotefmt);
500         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_fw_quotefmt), TRUE);
501         gtk_widget_set_size_request (text_fw_quotefmt, -1, 100);
502
503         if (checkbtn_forward_with_format) {
504                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
505                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_fw_quotemark);
506                 if (override_from_format) {
507                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_from);
508                         SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_from);
509                 }
510                 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_fw_quotefmt);
511         }
512
513         quote_fmt_add_buttons(parent_window, vbox_quote,
514                                 add_info_button, set_defaults_func);
515
516         if (checkbtn_forward_with_format)
517                 *checkbtn_forward_with_format = checkbtn_use_format;
518         *edit_fw_quotemark = entry_fw_quotemark;
519         if (override_from_format)
520                 *override_from_format = entry_from;
521         *edit_fw_format = text_fw_quotefmt;
522         
523         g_object_unref(G_OBJECT(size_group));
524 }
525
526 void quotefmt_add_info_button(GtkWindow *parent_window, GtkWidget *parent_box)
527 {
528         GtkWidget *btn_formatdesc;
529
530         btn_formatdesc = gtk_button_new_from_stock(GTK_STOCK_INFO);
531         gtk_widget_show (btn_formatdesc);
532         gtk_box_pack_start (GTK_BOX (parent_box), btn_formatdesc, FALSE, FALSE, 0);
533         g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
534                          G_CALLBACK(quote_fmt_quote_description), GTK_WIDGET(parent_window));
535 }
536
537 void quotefmt_add_defaults_button(GtkWindow *parent_window,
538                                                                   GtkWidget *parent_box,
539                                                                   void(*set_defaults_func)(void))
540 {
541         GtkWidget *btn_formatdesc;
542
543         cm_return_if_fail(set_defaults_func != NULL);
544
545         btn_formatdesc = gtk_button_new_with_mnemonic (_("Defaults"));
546         gtk_button_set_image (GTK_BUTTON(btn_formatdesc),
547                 gtk_image_new_from_stock(GTK_STOCK_UNDO, GTK_ICON_SIZE_BUTTON));
548         gtk_widget_show (btn_formatdesc);
549         gtk_box_pack_end (GTK_BOX (parent_box), btn_formatdesc, FALSE, FALSE, 0);
550         g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
551                          G_CALLBACK(set_defaults_func), GTK_WIDGET(parent_window));
552 }
553
554 void quotefmt_check_new_msg_formats(gboolean use_format,
555                                     gchar *override_from_fmt,
556                                     gchar *subject_fmt,
557                                     gchar *body_fmt)
558 {
559         if (use_format) {
560                 gint line;
561
562                 if (override_from_fmt && !prefs_template_string_is_valid(override_from_fmt, NULL, TRUE, TRUE))
563                         alertpanel_error(_("The \"From\" field of the \"New message\" template contains an invalid email address."));
564
565                 if (!prefs_template_string_is_valid(subject_fmt, NULL, TRUE, FALSE))
566                         alertpanel_error(_("The \"Subject\" field of the \"New message\" template is invalid."));
567
568                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
569                         alertpanel_error(_("The body of the \"New message\" template has an error at line %d."), line);
570                 }
571         }
572 }
573
574 void quotefmt_check_reply_formats(gboolean use_format,
575                                   gchar *override_from_fmt,
576                                   gchar *quotation_mark,
577                                   gchar *body_fmt)
578 {
579         if (use_format) {
580                 gint line;
581
582                 if (!prefs_template_string_is_valid(quotation_mark, NULL, TRUE, FALSE))
583                         alertpanel_error(_("The \"Quotation mark\" field of the \"Reply\" template is invalid."));
584
585                 if (override_from_fmt && !prefs_template_string_is_valid(override_from_fmt, NULL, TRUE, TRUE))
586                         alertpanel_error(_("The \"From\" field of the \"Reply\" template contains an invalid email address."));
587
588                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
589                         alertpanel_error(_("The body of the \"Reply\" template has an error at line %d."), line);
590                 }
591         }
592 }
593
594 void quotefmt_check_forward_formats(gboolean use_format,
595                                     gchar *override_from_fmt,
596                                     gchar *quotation_mark,
597                                     gchar *body_fmt)
598 {
599         if (use_format) {
600                 gint line;
601
602                 if (!prefs_template_string_is_valid(quotation_mark, NULL, TRUE, FALSE))
603                         alertpanel_error(_("The \"Quotation mark\" field of the \"Forward\" template is invalid."));
604
605                 if (override_from_fmt && !prefs_template_string_is_valid(override_from_fmt, NULL, TRUE, TRUE))
606                         alertpanel_error(_("The \"From\" field of the \"Forward\" template contains an invalid email address."));
607
608                 if (!prefs_template_string_is_valid(body_fmt, &line, TRUE, FALSE)) {
609                         alertpanel_error(_("The body of the \"Forward\" template has an error at line %d."), line);
610                 }
611         }
612 }