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 */
93 N_("<span weight=\"bold\">definition of terms:</span>"), NULL,
94 "<span style=\"oblique\">expr</span>\n", N_("text that can contain any of the symbols or\ncommands above"),
95 "<span style=\"oblique\">sub_expr</span>\n", N_("text that can contain any of the symbols (no\ncommands) above"),
96 "<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"),
100 static DescriptionWindow quote_desc_win = {
104 N_("Description of symbols"),
105 N_("The following symbols and commands can be used:"),
110 void quote_fmt_quote_description(GtkWidget *widget, GtkWidget *pref_window)
112 quote_desc_win.parent = pref_window;
113 description_window_create("e_desc_win);
116 void quotefmt_create_new_msg_fmt_widgets(GtkWindow *parent_window,
117 GtkWidget *parent_box,
118 GtkWidget **checkbtn_compose_with_format,
119 gchar *checkbtn_compose_text,
120 GtkWidget **edit_subject_format,
121 GtkWidget **edit_body_format,
122 gboolean add_info_button)
124 GtkWidget *checkbtn_use_format = NULL;
125 GtkWidget *frame_format;
126 GtkWidget *vbox_format;
127 GtkWidget *hbox_format;
128 GtkWidget *label_subject;
129 GtkWidget *entry_subject;
130 GtkWidget *scrolledwin_format;
131 GtkWidget *text_format;
134 g_return_if_fail(parent_window != NULL);
135 g_return_if_fail(parent_box != NULL);
136 if (checkbtn_compose_with_format) {
137 g_return_if_fail(checkbtn_compose_with_format != NULL);
138 g_return_if_fail(checkbtn_compose_text != NULL);
140 g_return_if_fail(edit_subject_format != NULL);
141 g_return_if_fail(edit_body_format != NULL);
143 if (checkbtn_compose_with_format)
144 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
145 _("Use format when composing new messages"));
147 frame_format = gtk_frame_new(checkbtn_compose_text);
148 gtk_widget_show(frame_format);
149 gtk_box_pack_start(GTK_BOX(parent_box), frame_format, TRUE, TRUE, 0);
150 gtk_frame_set_label_align(GTK_FRAME(frame_format), 0.01, 0.5);
152 vbox_format = gtk_vbox_new (FALSE, 4);
153 gtk_widget_show(vbox_format);
154 gtk_container_add(GTK_CONTAINER (frame_format), vbox_format);
155 gtk_container_set_border_width (GTK_CONTAINER (vbox_format), 8);
157 if (checkbtn_compose_with_format)
158 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, frame_format);
160 hbox_format = gtk_hbox_new (FALSE, 8);
161 gtk_widget_show (hbox_format);
162 gtk_box_pack_start (GTK_BOX (vbox_format), hbox_format, FALSE, FALSE, 0);
164 label_subject = gtk_label_new (_("Subject"));
165 gtk_widget_show (label_subject);
166 gtk_box_pack_start (GTK_BOX (hbox_format), label_subject, FALSE, FALSE, 0);
168 entry_subject = gtk_entry_new ();
169 gtk_widget_show (entry_subject);
170 gtk_box_pack_start (GTK_BOX (hbox_format), entry_subject, TRUE, TRUE, 0);
171 gtk_widget_set_size_request (entry_subject, 100, -1);
173 scrolledwin_format = gtk_scrolled_window_new (NULL, NULL);
174 gtk_widget_show (scrolledwin_format);
175 gtk_box_pack_start (GTK_BOX (vbox_format), scrolledwin_format,
177 gtk_scrolled_window_set_policy
178 (GTK_SCROLLED_WINDOW (scrolledwin_format),
179 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
180 gtk_scrolled_window_set_shadow_type
181 (GTK_SCROLLED_WINDOW (scrolledwin_format), GTK_SHADOW_IN);
183 text_format = gtk_text_view_new ();
184 if (prefs_common.textfont) {
185 PangoFontDescription *font_desc;
187 font_desc = pango_font_description_from_string
188 (prefs_common.textfont);
190 gtk_widget_modify_font(text_format, font_desc);
191 pango_font_description_free(font_desc);
194 gtk_widget_show(text_format);
195 gtk_container_add(GTK_CONTAINER(scrolledwin_format), text_format);
196 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_format), TRUE);
197 gtk_widget_set_size_request(text_format, -1, 100);
200 quotefmt_add_info_button(parent_window, vbox_format);
202 if (checkbtn_compose_with_format)
203 *checkbtn_compose_with_format = checkbtn_use_format;
204 *edit_subject_format = entry_subject;
205 *edit_body_format = text_format;
208 void quotefmt_create_reply_fmt_widgets(GtkWindow *parent_window,
209 GtkWidget *parent_box,
210 GtkWidget **checkbtn_reply_with_format,
211 gchar *checkbtn_reply_text,
212 GtkWidget **edit_reply_quotemark,
213 GtkWidget **edit_reply_format,
214 gboolean add_info_button)
216 GtkWidget *checkbtn_use_format = NULL;
217 GtkWidget *frame_quote;
218 GtkWidget *vbox_quote;
221 GtkWidget *label_quotemark;
222 GtkWidget *entry_quotemark;
223 GtkWidget *scrolledwin_quotefmt;
224 GtkWidget *text_quotefmt;
227 g_return_if_fail(parent_window != NULL);
228 g_return_if_fail(parent_box != NULL);
229 if (checkbtn_reply_with_format) {
230 g_return_if_fail(checkbtn_reply_with_format != NULL);
231 g_return_if_fail(checkbtn_reply_text != NULL);
233 g_return_if_fail(edit_reply_quotemark != NULL);
234 g_return_if_fail(edit_reply_format != NULL);
236 if (checkbtn_reply_with_format)
237 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format, checkbtn_reply_text);
239 frame_quote = gtk_frame_new(checkbtn_reply_text);
240 gtk_widget_show(frame_quote);
241 gtk_box_pack_start(GTK_BOX(parent_box), frame_quote, TRUE, TRUE, 0);
242 gtk_frame_set_label_align(GTK_FRAME(frame_quote), 0.01, 0.5);
244 vbox_quote = gtk_vbox_new (FALSE, 4);
245 gtk_widget_show(vbox_quote);
246 gtk_container_add(GTK_CONTAINER (frame_quote), vbox_quote);
247 gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
249 if (checkbtn_reply_with_format)
250 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, frame_quote);
252 hbox1 = gtk_hbox_new (FALSE, 32);
253 gtk_widget_show (hbox1);
254 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
256 hbox2 = gtk_hbox_new (FALSE, 8);
257 gtk_widget_show (hbox2);
258 gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
260 label_quotemark = gtk_label_new (_("Quotation mark"));
261 gtk_widget_show (label_quotemark);
262 gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
264 entry_quotemark = gtk_entry_new ();
265 gtk_widget_show (entry_quotemark);
266 gtk_box_pack_start (GTK_BOX (hbox2), entry_quotemark, FALSE, FALSE, 0);
267 gtk_widget_set_size_request (entry_quotemark, 64, -1);
269 scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
270 gtk_widget_show (scrolledwin_quotefmt);
271 gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
273 gtk_scrolled_window_set_policy
274 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
275 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
276 gtk_scrolled_window_set_shadow_type
277 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
279 text_quotefmt = gtk_text_view_new ();
280 if (prefs_common.textfont) {
281 PangoFontDescription *font_desc;
283 font_desc = pango_font_description_from_string
284 (prefs_common.textfont);
286 gtk_widget_modify_font(text_quotefmt, font_desc);
287 pango_font_description_free(font_desc);
290 gtk_widget_show(text_quotefmt);
291 gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt), text_quotefmt);
292 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_quotefmt), TRUE);
293 gtk_widget_set_size_request(text_quotefmt, -1, 100);
296 quotefmt_add_info_button(parent_window, vbox_quote);
298 if (checkbtn_reply_with_format)
299 *checkbtn_reply_with_format = checkbtn_use_format;
300 *edit_reply_quotemark = entry_quotemark;
301 *edit_reply_format = text_quotefmt;
304 void quotefmt_create_forward_fmt_widgets(GtkWindow *parent_window,
305 GtkWidget *parent_box,
306 GtkWidget **checkbtn_forward_with_format,
307 gchar *checkbtn_forward_text,
308 GtkWidget **edit_fw_quotemark,
309 GtkWidget **edit_fw_format,
310 gboolean add_info_button)
312 GtkWidget *checkbtn_use_format = NULL;
313 GtkWidget *frame_quote;
314 GtkWidget *vbox_quote;
317 GtkWidget *label_quotemark;
318 GtkWidget *entry_fw_quotemark;
319 GtkWidget *scrolledwin_quotefmt;
320 GtkWidget *text_fw_quotefmt;
323 g_return_if_fail(parent_window != NULL);
324 g_return_if_fail(parent_box != NULL);
325 if (checkbtn_forward_with_format) {
326 g_return_if_fail(checkbtn_forward_with_format != NULL);
327 g_return_if_fail(checkbtn_forward_text != NULL);
329 g_return_if_fail(edit_fw_quotemark != NULL);
330 g_return_if_fail(edit_fw_format != NULL);
332 if (checkbtn_forward_with_format)
333 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format, checkbtn_forward_text);
335 frame_quote = gtk_frame_new(checkbtn_forward_text);
336 gtk_widget_show(frame_quote);
337 gtk_box_pack_start(GTK_BOX(parent_box), frame_quote, TRUE, TRUE, 0);
338 gtk_frame_set_label_align(GTK_FRAME(frame_quote), 0.01, 0.5);
340 vbox_quote = gtk_vbox_new (FALSE, 4);
341 gtk_widget_show(vbox_quote);
342 gtk_container_add(GTK_CONTAINER (frame_quote), vbox_quote);
343 gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
345 if (checkbtn_forward_with_format)
346 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, frame_quote);
348 hbox1 = gtk_hbox_new (FALSE, 32);
349 gtk_widget_show (hbox1);
350 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
352 hbox2 = gtk_hbox_new (FALSE, 8);
353 gtk_widget_show (hbox2);
354 gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
356 label_quotemark = gtk_label_new (_("Quotation mark"));
357 gtk_widget_show (label_quotemark);
358 gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
360 entry_fw_quotemark = gtk_entry_new ();
361 gtk_widget_show (entry_fw_quotemark);
362 gtk_box_pack_start (GTK_BOX (hbox2), entry_fw_quotemark,
364 gtk_widget_set_size_request (entry_fw_quotemark, 64, -1);
366 scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
367 gtk_widget_show (scrolledwin_quotefmt);
368 gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
370 gtk_scrolled_window_set_policy
371 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
372 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
373 gtk_scrolled_window_set_shadow_type
374 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
376 text_fw_quotefmt = gtk_text_view_new ();
377 if (prefs_common.textfont) {
378 PangoFontDescription *font_desc;
380 font_desc = pango_font_description_from_string
381 (prefs_common.textfont);
383 gtk_widget_modify_font(text_fw_quotefmt, font_desc);
384 pango_font_description_free(font_desc);
387 gtk_widget_show(text_fw_quotefmt);
388 gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt),
390 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_fw_quotefmt), TRUE);
391 gtk_widget_set_size_request (text_fw_quotefmt, -1, 100);
394 quotefmt_add_info_button(parent_window, vbox_quote);
396 if (checkbtn_forward_with_format)
397 *checkbtn_forward_with_format = checkbtn_use_format;
398 *edit_fw_quotemark = entry_fw_quotemark;
399 *edit_fw_format = text_fw_quotefmt;
402 void quotefmt_add_info_button(GtkWindow *parent_window, GtkWidget *parent_box)
404 GtkWidget *hbox_formatdesc;
405 GtkWidget *btn_formatdesc;
407 hbox_formatdesc = gtk_hbox_new (FALSE, 32);
408 gtk_widget_show (hbox_formatdesc);
409 gtk_box_pack_start (GTK_BOX (parent_box), hbox_formatdesc, FALSE, FALSE,
412 #if GTK_CHECK_VERSION(2, 8, 0)
413 btn_formatdesc = gtk_button_new_from_stock(GTK_STOCK_INFO);
416 gtk_button_new_with_label (_("Description of symbols..."));
418 gtk_widget_show (btn_formatdesc);
419 gtk_box_pack_start (GTK_BOX (hbox_formatdesc), btn_formatdesc, FALSE, FALSE, 0);
420 g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
421 G_CALLBACK(quote_fmt_quote_description), GTK_WIDGET(parent_window));
425 void quotefmt_check_new_msg_formats(gboolean use_format,
432 if (!prefs_template_string_is_valid(subject_fmt, NULL))
433 alertpanel_error(_("New message subject format error."));
435 if (!prefs_template_string_is_valid(body_fmt, &line)) {
436 alertpanel_error(_("New message body format error at line %d."), line);
441 void quotefmt_check_reply_formats(gboolean use_format,
442 gchar *quotation_mark,
448 if (!prefs_template_string_is_valid(quotation_mark, NULL))
449 alertpanel_error(_("Message reply quotation mark format error."));
451 if (!prefs_template_string_is_valid(body_fmt, &line)) {
452 alertpanel_error(_("Message reply format error at line %d."), line);
457 void quotefmt_check_forward_formats(gboolean use_format,
458 gchar *quotation_mark,
464 if (!prefs_template_string_is_valid(quotation_mark, NULL))
465 alertpanel_error(_("Message forward quotation mark format error."));
467 if (!prefs_template_string_is_valid(body_fmt, &line)) {
468 alertpanel_error(_("Message forward format error at line %d."), line);