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 
quote_fmt_quote_description(GtkWidget * widget,GtkWidget * pref_window)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 
quote_fmt_add_buttons(GtkWindow * parent_window,GtkWidget * parent_box,gboolean add_info_button,void (* set_defaults_func)(void))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 
quotefmt_create_new_msg_fmt_widgets(GtkWindow * parent_window,GtkWidget * parent_box,GtkWidget ** checkbtn_compose_with_format,GtkWidget ** override_from_format,GtkWidget ** edit_subject_format,GtkWidget ** edit_body_format,gboolean add_info_button,void (* set_defaults_func)(void))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 
quotefmt_create_reply_fmt_widgets(GtkWindow * parent_window,GtkWidget * parent_box,GtkWidget ** checkbtn_reply_with_format,GtkWidget ** override_from_format,GtkWidget ** edit_reply_quotemark,GtkWidget ** edit_reply_format,gboolean add_info_button,void (* set_defaults_func)(void))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 
quotefmt_create_forward_fmt_widgets(GtkWindow * parent_window,GtkWidget * parent_box,GtkWidget ** checkbtn_forward_with_format,GtkWidget ** override_from_format,GtkWidget ** edit_fw_quotemark,GtkWidget ** edit_fw_format,gboolean add_info_button,void (* set_defaults_func)(void))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 
quotefmt_add_info_button(GtkWindow * parent_window,GtkWidget * parent_box)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 
quotefmt_add_defaults_button(GtkWindow * parent_window,GtkWidget * parent_box,void (* set_defaults_func)(void))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 
quotefmt_check_new_msg_formats(gboolean use_format,gchar * override_from_fmt,gchar * subject_fmt,gchar * body_fmt)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 
quotefmt_check_reply_formats(gboolean use_format,gchar * override_from_fmt,gchar * quotation_mark,gchar * body_fmt)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 
quotefmt_check_forward_formats(gboolean use_format,gchar * override_from_fmt,gchar * quotation_mark,gchar * body_fmt)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 }
607