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