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