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 2 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, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
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 "%dict (%T)", N_("current dictionary"), /* current dictionary */
66 "%cursor (%X)", N_("cursor position"), /* X marks the cursor spot */
67 "%account_fullname (%af)", N_("account property: your name"), /* full name in compose account */
68 "%account_email (%ae)", N_("account property: your email address"), /* mail address in compose account */
69 "%account_name (%an)", N_("account property: account name"), /* compose account name itself */
70 "%account_org (%ao)", N_("account property: organization"), /* organization in compose account */
71 "%account_dict (%aT)", N_("account property: default dictionary"), /* main dict (if enabled) in account */
72 "%addrbook_cc (%ABc)", N_("address book <span style=\"oblique\">completion</span>: Cc"), /* completion of 'Cc' from address book */
73 "%addrbook_from (%ABf)", N_("address book <span style=\"oblique\">completion</span>: From"), /* completion of 'From' from address book */
74 "%addrbook_to (%ABt)", N_("address book <span style=\"oblique\">completion</span>: To"), /* completion of 'To' from address book */
75 "\\%", N_("literal %"),
76 "\\\\", N_("literal backslash"),
77 "\\?", N_("literal question mark"),
78 "\\!", N_("literal exclamation mark"),
79 "\\|", N_("literal pipe"),
80 "\\{", N_("literal opening curly brace"),
81 "\\}", N_("literal closing curly brace"),
83 "\\n", N_("new line"),
85 N_("<span weight=\"bold\">commands:</span>"), NULL,
86 "?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)"),
87 "!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)"),
88 "|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 */
89 "|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 */
90 "|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 N_("<span weight=\"bold\">definition of terms:</span>"), NULL,
93 "<span style=\"oblique\">expr</span>\n", N_("text that can contain any of the symbols or\ncommands above"),
94 "<span style=\"oblique\">sub_expr</span>\n", N_("text that can contain any of the symbols (no\ncommands) above"),
95 "<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"),
99 static DescriptionWindow quote_desc_win = {
103 N_("Description of symbols"),
104 N_("The following symbols and commands can be used:"),
109 void quote_fmt_quote_description(GtkWidget *widget, GtkWidget *pref_window)
111 quote_desc_win.parent = pref_window;
112 description_window_create("e_desc_win);
115 void quotefmt_create_new_msg_fmt_widgets(GtkWindow *parent_window,
116 GtkWidget *parent_box,
117 GtkWidget **checkbtn_compose_with_format,
118 gchar *checkbtn_compose_text,
119 GtkWidget **edit_subject_format,
120 GtkWidget **edit_body_format,
121 gboolean add_info_button)
123 GtkWidget *checkbtn_use_format = NULL;
124 GtkWidget *frame_format;
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);
137 g_return_if_fail(checkbtn_compose_text != NULL);
139 g_return_if_fail(edit_subject_format != NULL);
140 g_return_if_fail(edit_body_format != NULL);
142 if (checkbtn_compose_with_format)
143 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
144 _("Use format when composing new messages"));
146 vbox_format = gtkut_get_options_frame(parent_box, &frame_format, checkbtn_compose_text);
148 if (checkbtn_compose_with_format)
149 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, frame_format);
151 hbox_format = gtk_hbox_new (FALSE, 8);
152 gtk_widget_show (hbox_format);
153 gtk_box_pack_start (GTK_BOX (vbox_format), hbox_format, FALSE, FALSE, 0);
155 label_subject = gtk_label_new (_("Subject"));
156 gtk_widget_show (label_subject);
157 gtk_box_pack_start (GTK_BOX (hbox_format), label_subject, FALSE, FALSE, 0);
159 entry_subject = gtk_entry_new ();
160 gtk_widget_show (entry_subject);
161 gtk_box_pack_start (GTK_BOX (hbox_format), entry_subject, TRUE, TRUE, 0);
162 gtk_widget_set_size_request (entry_subject, 100, -1);
164 scrolledwin_format = gtk_scrolled_window_new (NULL, NULL);
165 gtk_widget_show (scrolledwin_format);
166 gtk_box_pack_start (GTK_BOX (vbox_format), scrolledwin_format,
168 gtk_scrolled_window_set_policy
169 (GTK_SCROLLED_WINDOW (scrolledwin_format),
170 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
171 gtk_scrolled_window_set_shadow_type
172 (GTK_SCROLLED_WINDOW (scrolledwin_format), GTK_SHADOW_IN);
174 text_format = gtk_text_view_new ();
175 if (prefs_common.textfont) {
176 PangoFontDescription *font_desc;
178 font_desc = pango_font_description_from_string
179 (prefs_common.textfont);
181 gtk_widget_modify_font(text_format, font_desc);
182 pango_font_description_free(font_desc);
185 gtk_widget_show(text_format);
186 gtk_container_add(GTK_CONTAINER(scrolledwin_format), text_format);
187 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_format), TRUE);
188 gtk_widget_set_size_request(text_format, -1, 100);
191 quotefmt_add_info_button(parent_window, vbox_format);
193 if (checkbtn_compose_with_format)
194 *checkbtn_compose_with_format = checkbtn_use_format;
195 *edit_subject_format = entry_subject;
196 *edit_body_format = text_format;
199 void quotefmt_create_reply_fmt_widgets(GtkWindow *parent_window,
200 GtkWidget *parent_box,
201 GtkWidget **checkbtn_reply_with_format,
202 gchar *checkbtn_reply_text,
203 GtkWidget **edit_reply_quotemark,
204 GtkWidget **edit_reply_format,
205 gboolean add_info_button)
207 GtkWidget *checkbtn_use_format = NULL;
208 GtkWidget *frame_quote;
209 GtkWidget *vbox_quote;
212 GtkWidget *label_quotemark;
213 GtkWidget *entry_quotemark;
214 GtkWidget *scrolledwin_quotefmt;
215 GtkWidget *text_quotefmt;
218 g_return_if_fail(parent_window != NULL);
219 g_return_if_fail(parent_box != NULL);
220 if (checkbtn_reply_with_format) {
221 g_return_if_fail(checkbtn_reply_with_format != NULL);
222 g_return_if_fail(checkbtn_reply_text != NULL);
224 g_return_if_fail(edit_reply_quotemark != NULL);
225 g_return_if_fail(edit_reply_format != NULL);
227 if (checkbtn_reply_with_format)
228 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format, checkbtn_reply_text);
230 PACK_FRAME (parent_box, frame_quote, _("Reply format"));
232 if (checkbtn_reply_with_format)
233 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, frame_quote);
235 vbox_quote = gtk_vbox_new (FALSE, VSPACING_NARROW);
236 gtk_widget_show (vbox_quote);
237 gtk_container_add (GTK_CONTAINER (frame_quote), vbox_quote);
238 gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
240 hbox1 = gtk_hbox_new (FALSE, 32);
241 gtk_widget_show (hbox1);
242 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
244 hbox2 = gtk_hbox_new (FALSE, 8);
245 gtk_widget_show (hbox2);
246 gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
248 label_quotemark = gtk_label_new (_("Quotation mark"));
249 gtk_widget_show (label_quotemark);
250 gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
252 entry_quotemark = gtk_entry_new ();
253 gtk_widget_show (entry_quotemark);
254 gtk_box_pack_start (GTK_BOX (hbox2), entry_quotemark, FALSE, FALSE, 0);
255 gtk_widget_set_size_request (entry_quotemark, 64, -1);
257 scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
258 gtk_widget_show (scrolledwin_quotefmt);
259 gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
261 gtk_scrolled_window_set_policy
262 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
263 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
264 gtk_scrolled_window_set_shadow_type
265 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
267 text_quotefmt = gtk_text_view_new ();
268 if (prefs_common.textfont) {
269 PangoFontDescription *font_desc;
271 font_desc = pango_font_description_from_string
272 (prefs_common.textfont);
274 gtk_widget_modify_font(text_quotefmt, font_desc);
275 pango_font_description_free(font_desc);
278 gtk_widget_show(text_quotefmt);
279 gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt), text_quotefmt);
280 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_quotefmt), TRUE);
281 gtk_widget_set_size_request(text_quotefmt, -1, 100);
284 quotefmt_add_info_button(parent_window, vbox_quote);
286 if (checkbtn_reply_with_format)
287 *checkbtn_reply_with_format = checkbtn_use_format;
288 *edit_reply_quotemark = entry_quotemark;
289 *edit_reply_format = text_quotefmt;
292 void quotefmt_create_forward_fmt_widgets(GtkWindow *parent_window,
293 GtkWidget *parent_box,
294 GtkWidget **checkbtn_forward_with_format,
295 gchar *checkbtn_forward_text,
296 GtkWidget **edit_fw_quotemark,
297 GtkWidget **edit_fw_format,
298 gboolean add_info_button)
300 GtkWidget *checkbtn_use_format = NULL;
301 GtkWidget *frame_quote;
302 GtkWidget *vbox_quote;
305 GtkWidget *label_quotemark;
306 GtkWidget *entry_fw_quotemark;
307 GtkWidget *scrolledwin_quotefmt;
308 GtkWidget *text_fw_quotefmt;
311 g_return_if_fail(parent_window != NULL);
312 g_return_if_fail(parent_box != NULL);
313 if (checkbtn_forward_with_format) {
314 g_return_if_fail(checkbtn_forward_with_format != NULL);
315 g_return_if_fail(checkbtn_forward_text != NULL);
317 g_return_if_fail(edit_fw_quotemark != NULL);
318 g_return_if_fail(edit_fw_format != NULL);
320 if (checkbtn_forward_with_format)
321 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format, checkbtn_forward_text);
323 PACK_FRAME (parent_box, frame_quote, _("Forward format"));
325 if (checkbtn_forward_with_format)
326 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, frame_quote);
328 vbox_quote = gtk_vbox_new (FALSE, VSPACING_NARROW);
329 gtk_widget_show (vbox_quote);
330 gtk_container_add (GTK_CONTAINER (frame_quote), vbox_quote);
331 gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
333 hbox1 = gtk_hbox_new (FALSE, 32);
334 gtk_widget_show (hbox1);
335 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
337 hbox2 = gtk_hbox_new (FALSE, 8);
338 gtk_widget_show (hbox2);
339 gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
341 label_quotemark = gtk_label_new (_("Quotation mark"));
342 gtk_widget_show (label_quotemark);
343 gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
345 entry_fw_quotemark = gtk_entry_new ();
346 gtk_widget_show (entry_fw_quotemark);
347 gtk_box_pack_start (GTK_BOX (hbox2), entry_fw_quotemark,
349 gtk_widget_set_size_request (entry_fw_quotemark, 64, -1);
351 scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
352 gtk_widget_show (scrolledwin_quotefmt);
353 gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
355 gtk_scrolled_window_set_policy
356 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
357 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
358 gtk_scrolled_window_set_shadow_type
359 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
361 text_fw_quotefmt = gtk_text_view_new ();
362 if (prefs_common.textfont) {
363 PangoFontDescription *font_desc;
365 font_desc = pango_font_description_from_string
366 (prefs_common.textfont);
368 gtk_widget_modify_font(text_fw_quotefmt, font_desc);
369 pango_font_description_free(font_desc);
372 gtk_widget_show(text_fw_quotefmt);
373 gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt),
375 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_fw_quotefmt), TRUE);
376 gtk_widget_set_size_request (text_fw_quotefmt, -1, 100);
379 quotefmt_add_info_button(parent_window, vbox_quote);
381 if (checkbtn_forward_with_format)
382 *checkbtn_forward_with_format = checkbtn_use_format;
383 *edit_fw_quotemark = entry_fw_quotemark;
384 *edit_fw_format = text_fw_quotefmt;
387 void quotefmt_add_info_button(GtkWindow *parent_window, GtkWidget *parent_box)
389 GtkWidget *hbox_formatdesc;
390 GtkWidget *btn_formatdesc;
392 hbox_formatdesc = gtk_hbox_new (FALSE, 32);
393 gtk_widget_show (hbox_formatdesc);
394 gtk_box_pack_start (GTK_BOX (parent_box), hbox_formatdesc, FALSE, FALSE, 0);
396 #if GTK_CHECK_VERSION(2, 8, 0)
397 btn_formatdesc = gtk_button_new_from_stock(GTK_STOCK_INFO);
400 gtk_button_new_with_label (_("Description of symbols..."));
402 gtk_widget_show (btn_formatdesc);
403 gtk_box_pack_start (GTK_BOX (hbox_formatdesc), btn_formatdesc, FALSE, FALSE, 0);
404 g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
405 G_CALLBACK(quote_fmt_quote_description), GTK_WIDGET(parent_window));
409 void quotefmt_check_new_msg_formats(gboolean use_format,
416 !prefs_template_string_is_valid(subject_fmt, NULL))
417 alertpanel_error(_("New message subject format error."));
419 !prefs_template_string_is_valid(body_fmt, &line)) {
420 gchar *msg = g_strdup_printf(_("New message body format error at line %d."), line);
421 alertpanel_error(msg);
426 void quotefmt_check_reply_formats(gboolean use_format,
432 !prefs_template_string_is_valid(body_fmt, &line)) {
433 gchar *msg = g_strdup_printf(_("Message reply format error at line %d."), line);
434 alertpanel_error(msg);
439 void quotefmt_check_forward_formats(gboolean use_format,
445 !prefs_template_string_is_valid(body_fmt, &line)) {
446 gchar *msg = g_strdup_printf(_("Message forward format error at line %d."), line);
447 alertpanel_error(msg);