2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2007 Hiroyuki Yamamoto and the Claws Mail team
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.
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.
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/>.
25 #include <glib/gi18n.h>
27 #include <gdk/gdkkeysyms.h>
29 #include "manage_window.h"
30 #include "description_window.h"
33 #include "prefs_gtk.h"
34 #include "prefs_common.h"
35 #include "quote_fmt.h"
36 #include "alertpanel.h"
37 #include "prefs_template.h"
41 * Strings describing quote format strings
43 * When adding new lines, remember to put 2 strings for each line
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"),
84 "\\n", N_("new line"),
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 */
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"),
101 static DescriptionWindow quote_desc_win = {
105 N_("Description of symbols"),
106 N_("The following symbols and commands can be used:"),
111 void quote_fmt_quote_description(GtkWidget *widget, GtkWidget *pref_window)
113 quote_desc_win.parent = pref_window;
114 description_window_create("e_desc_win);
117 void quotefmt_create_new_msg_fmt_widgets(GtkWindow *parent_window,
118 GtkWidget *parent_box,
119 GtkWidget **checkbtn_compose_with_format,
120 GtkWidget **edit_subject_format,
121 GtkWidget **edit_body_format,
122 gboolean add_info_button)
124 GtkWidget *checkbtn_use_format = NULL;
125 GtkWidget *vbox_format;
126 GtkWidget *hbox_format;
127 GtkWidget *label_subject;
128 GtkWidget *entry_subject;
129 GtkWidget *scrolledwin_format;
130 GtkWidget *text_format;
133 g_return_if_fail(parent_window != NULL);
134 g_return_if_fail(parent_box != NULL);
135 if (checkbtn_compose_with_format)
136 g_return_if_fail(checkbtn_compose_with_format != NULL);
138 g_return_if_fail(edit_subject_format != NULL);
139 g_return_if_fail(edit_body_format != NULL);
141 if (checkbtn_compose_with_format)
142 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
143 _("Use template when composing new messages"));
145 vbox_format = gtk_vbox_new (FALSE, 4);
146 gtk_widget_show(vbox_format);
147 gtk_container_add(GTK_CONTAINER (parent_box), vbox_format);
148 gtk_container_set_border_width (GTK_CONTAINER (vbox_format), 8);
150 hbox_format = gtk_hbox_new (FALSE, 8);
151 gtk_widget_show (hbox_format);
152 gtk_box_pack_start (GTK_BOX (vbox_format), hbox_format, FALSE, FALSE, 0);
154 label_subject = gtk_label_new (_("Subject"));
155 gtk_widget_show (label_subject);
156 gtk_box_pack_start (GTK_BOX (hbox_format), label_subject, FALSE, FALSE, 0);
158 entry_subject = gtk_entry_new ();
159 gtk_widget_show (entry_subject);
160 gtk_box_pack_start (GTK_BOX (hbox_format), entry_subject, TRUE, TRUE, 0);
161 gtk_widget_set_size_request (entry_subject, 100, -1);
163 scrolledwin_format = gtk_scrolled_window_new (NULL, NULL);
164 gtk_widget_show (scrolledwin_format);
165 gtk_box_pack_start (GTK_BOX (vbox_format), scrolledwin_format,
167 gtk_scrolled_window_set_policy
168 (GTK_SCROLLED_WINDOW (scrolledwin_format),
169 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
170 gtk_scrolled_window_set_shadow_type
171 (GTK_SCROLLED_WINDOW (scrolledwin_format), GTK_SHADOW_IN);
173 text_format = gtk_text_view_new ();
174 if (prefs_common.textfont) {
175 PangoFontDescription *font_desc;
177 font_desc = pango_font_description_from_string
178 (prefs_common.textfont);
180 gtk_widget_modify_font(text_format, font_desc);
181 pango_font_description_free(font_desc);
184 gtk_widget_show(text_format);
185 gtk_container_add(GTK_CONTAINER(scrolledwin_format), text_format);
186 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_format), TRUE);
187 gtk_widget_set_size_request(text_format, -1, 100);
189 if (checkbtn_compose_with_format) {
190 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_subject);
191 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_subject);
192 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_format);
196 quotefmt_add_info_button(parent_window, vbox_format);
198 if (checkbtn_compose_with_format)
199 *checkbtn_compose_with_format = checkbtn_use_format;
200 *edit_subject_format = entry_subject;
201 *edit_body_format = text_format;
204 void quotefmt_create_reply_fmt_widgets(GtkWindow *parent_window,
205 GtkWidget *parent_box,
206 GtkWidget **checkbtn_reply_with_format,
207 GtkWidget **edit_reply_quotemark,
208 GtkWidget **edit_reply_format,
209 gboolean add_info_button)
211 GtkWidget *checkbtn_use_format = NULL;
212 GtkWidget *vbox_quote;
215 GtkWidget *label_quotemark;
216 GtkWidget *entry_quotemark;
217 GtkWidget *scrolledwin_quotefmt;
218 GtkWidget *text_quotefmt;
221 g_return_if_fail(parent_window != NULL);
222 g_return_if_fail(parent_box != NULL);
223 if (checkbtn_reply_with_format)
224 g_return_if_fail(checkbtn_reply_with_format != NULL);
226 g_return_if_fail(edit_reply_quotemark != NULL);
227 g_return_if_fail(edit_reply_format != NULL);
229 if (checkbtn_reply_with_format)
230 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
231 _("Use template when replying to messages"));
233 vbox_quote = gtk_vbox_new (FALSE, 4);
234 gtk_widget_show(vbox_quote);
235 gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
236 gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
238 hbox1 = gtk_hbox_new (FALSE, 32);
239 gtk_widget_show (hbox1);
240 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
242 hbox2 = gtk_hbox_new (FALSE, 8);
243 gtk_widget_show (hbox2);
244 gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
246 label_quotemark = gtk_label_new (_("Quotation mark"));
247 gtk_widget_show (label_quotemark);
248 gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
250 entry_quotemark = gtk_entry_new ();
251 gtk_widget_show (entry_quotemark);
252 gtk_box_pack_start (GTK_BOX (hbox2), entry_quotemark, FALSE, FALSE, 0);
253 gtk_widget_set_size_request (entry_quotemark, 64, -1);
255 scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
256 gtk_widget_show (scrolledwin_quotefmt);
257 gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
259 gtk_scrolled_window_set_policy
260 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
261 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
262 gtk_scrolled_window_set_shadow_type
263 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
265 text_quotefmt = gtk_text_view_new ();
266 if (prefs_common.textfont) {
267 PangoFontDescription *font_desc;
269 font_desc = pango_font_description_from_string
270 (prefs_common.textfont);
272 gtk_widget_modify_font(text_quotefmt, font_desc);
273 pango_font_description_free(font_desc);
276 gtk_widget_show(text_quotefmt);
277 gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt), text_quotefmt);
278 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_quotefmt), TRUE);
279 gtk_widget_set_size_request(text_quotefmt, -1, 100);
281 if (checkbtn_reply_with_format) {
282 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
283 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_quotemark);
284 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_quotefmt);
288 quotefmt_add_info_button(parent_window, vbox_quote);
290 if (checkbtn_reply_with_format)
291 *checkbtn_reply_with_format = checkbtn_use_format;
292 *edit_reply_quotemark = entry_quotemark;
293 *edit_reply_format = text_quotefmt;
296 void quotefmt_create_forward_fmt_widgets(GtkWindow *parent_window,
297 GtkWidget *parent_box,
298 GtkWidget **checkbtn_forward_with_format,
299 GtkWidget **edit_fw_quotemark,
300 GtkWidget **edit_fw_format,
301 gboolean add_info_button)
303 GtkWidget *checkbtn_use_format = NULL;
304 GtkWidget *vbox_quote;
307 GtkWidget *label_quotemark;
308 GtkWidget *entry_fw_quotemark;
309 GtkWidget *scrolledwin_quotefmt;
310 GtkWidget *text_fw_quotefmt;
313 g_return_if_fail(parent_window != NULL);
314 g_return_if_fail(parent_box != NULL);
315 if (checkbtn_forward_with_format) {
316 g_return_if_fail(checkbtn_forward_with_format != NULL);
318 g_return_if_fail(edit_fw_quotemark != NULL);
319 g_return_if_fail(edit_fw_format != NULL);
321 if (checkbtn_forward_with_format)
322 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
323 _("Use template when forwarding messages"));
325 vbox_quote = gtk_vbox_new (FALSE, 4);
326 gtk_widget_show(vbox_quote);
327 gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
328 gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
330 hbox1 = gtk_hbox_new (FALSE, 32);
331 gtk_widget_show (hbox1);
332 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
334 hbox2 = gtk_hbox_new (FALSE, 8);
335 gtk_widget_show (hbox2);
336 gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
338 label_quotemark = gtk_label_new (_("Quotation mark"));
339 gtk_widget_show (label_quotemark);
340 gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
342 entry_fw_quotemark = gtk_entry_new ();
343 gtk_widget_show (entry_fw_quotemark);
344 gtk_box_pack_start (GTK_BOX (hbox2), entry_fw_quotemark,
346 gtk_widget_set_size_request (entry_fw_quotemark, 64, -1);
348 scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
349 gtk_widget_show (scrolledwin_quotefmt);
350 gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
352 gtk_scrolled_window_set_policy
353 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
354 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
355 gtk_scrolled_window_set_shadow_type
356 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
358 text_fw_quotefmt = gtk_text_view_new ();
359 if (prefs_common.textfont) {
360 PangoFontDescription *font_desc;
362 font_desc = pango_font_description_from_string
363 (prefs_common.textfont);
365 gtk_widget_modify_font(text_fw_quotefmt, font_desc);
366 pango_font_description_free(font_desc);
369 gtk_widget_show(text_fw_quotefmt);
370 gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt),
372 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_fw_quotefmt), TRUE);
373 gtk_widget_set_size_request (text_fw_quotefmt, -1, 100);
375 if (checkbtn_forward_with_format) {
376 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
377 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_fw_quotemark);
378 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_fw_quotefmt);
382 quotefmt_add_info_button(parent_window, vbox_quote);
384 if (checkbtn_forward_with_format)
385 *checkbtn_forward_with_format = checkbtn_use_format;
386 *edit_fw_quotemark = entry_fw_quotemark;
387 *edit_fw_format = text_fw_quotefmt;
390 void quotefmt_add_info_button(GtkWindow *parent_window, GtkWidget *parent_box)
392 GtkWidget *hbox_formatdesc;
393 GtkWidget *btn_formatdesc;
395 hbox_formatdesc = gtk_hbox_new (FALSE, 32);
396 gtk_widget_show (hbox_formatdesc);
397 gtk_box_pack_start (GTK_BOX (parent_box), hbox_formatdesc, FALSE, FALSE,
400 #if GTK_CHECK_VERSION(2, 8, 0)
401 btn_formatdesc = gtk_button_new_from_stock(GTK_STOCK_INFO);
404 gtk_button_new_with_label (_("Description of symbols..."));
406 gtk_widget_show (btn_formatdesc);
407 gtk_box_pack_start (GTK_BOX (hbox_formatdesc), btn_formatdesc, FALSE, FALSE, 0);
408 g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
409 G_CALLBACK(quote_fmt_quote_description), GTK_WIDGET(parent_window));
413 void quotefmt_check_new_msg_formats(gboolean use_format,
420 if (!prefs_template_string_is_valid(subject_fmt, NULL))
421 alertpanel_error(_("New message subject format error."));
423 if (!prefs_template_string_is_valid(body_fmt, &line)) {
424 alertpanel_error(_("New message body format error at line %d."), line);
429 void quotefmt_check_reply_formats(gboolean use_format,
430 gchar *quotation_mark,
436 if (!prefs_template_string_is_valid(quotation_mark, NULL))
437 alertpanel_error(_("Message reply quotation mark format error."));
439 if (!prefs_template_string_is_valid(body_fmt, &line)) {
440 alertpanel_error(_("Message reply format error at line %d."), line);
445 void quotefmt_check_forward_formats(gboolean use_format,
446 gchar *quotation_mark,
452 if (!prefs_template_string_is_valid(quotation_mark, NULL))
453 alertpanel_error(_("Message forward quotation mark format error."));
455 if (!prefs_template_string_is_valid(body_fmt, &line)) {
456 alertpanel_error(_("Message forward format error at line %d."), line);