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 GtkWidget **edit_subject_format,
120 GtkWidget **edit_body_format,
121 gboolean add_info_button)
123 GtkWidget *checkbtn_use_format = NULL;
124 GtkWidget *vbox_format;
125 GtkWidget *hbox_format;
126 GtkWidget *label_subject;
127 GtkWidget *entry_subject;
128 GtkWidget *scrolledwin_format;
129 GtkWidget *text_format;
132 g_return_if_fail(parent_window != NULL);
133 g_return_if_fail(parent_box != NULL);
134 if (checkbtn_compose_with_format)
135 g_return_if_fail(checkbtn_compose_with_format != NULL);
137 g_return_if_fail(edit_subject_format != NULL);
138 g_return_if_fail(edit_body_format != NULL);
140 if (checkbtn_compose_with_format)
141 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
142 _("Use template when composing new messages"));
144 vbox_format = gtk_vbox_new (FALSE, 4);
145 gtk_widget_show(vbox_format);
146 gtk_container_add(GTK_CONTAINER (parent_box), vbox_format);
147 gtk_container_set_border_width (GTK_CONTAINER (vbox_format), 8);
149 hbox_format = gtk_hbox_new (FALSE, 8);
150 gtk_widget_show (hbox_format);
151 gtk_box_pack_start (GTK_BOX (vbox_format), hbox_format, FALSE, FALSE, 0);
153 label_subject = gtk_label_new (_("Subject"));
154 gtk_widget_show (label_subject);
155 gtk_box_pack_start (GTK_BOX (hbox_format), label_subject, FALSE, FALSE, 0);
157 entry_subject = gtk_entry_new ();
158 gtk_widget_show (entry_subject);
159 gtk_box_pack_start (GTK_BOX (hbox_format), entry_subject, TRUE, TRUE, 0);
160 gtk_widget_set_size_request (entry_subject, 100, -1);
162 scrolledwin_format = gtk_scrolled_window_new (NULL, NULL);
163 gtk_widget_show (scrolledwin_format);
164 gtk_box_pack_start (GTK_BOX (vbox_format), scrolledwin_format,
166 gtk_scrolled_window_set_policy
167 (GTK_SCROLLED_WINDOW (scrolledwin_format),
168 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
169 gtk_scrolled_window_set_shadow_type
170 (GTK_SCROLLED_WINDOW (scrolledwin_format), GTK_SHADOW_IN);
172 text_format = gtk_text_view_new ();
173 if (prefs_common.textfont) {
174 PangoFontDescription *font_desc;
176 font_desc = pango_font_description_from_string
177 (prefs_common.textfont);
179 gtk_widget_modify_font(text_format, font_desc);
180 pango_font_description_free(font_desc);
183 gtk_widget_show(text_format);
184 gtk_container_add(GTK_CONTAINER(scrolledwin_format), text_format);
185 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_format), TRUE);
186 gtk_widget_set_size_request(text_format, -1, 100);
188 if (checkbtn_compose_with_format) {
189 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_subject);
190 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_subject);
191 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_format);
195 quotefmt_add_info_button(parent_window, vbox_format);
197 if (checkbtn_compose_with_format)
198 *checkbtn_compose_with_format = checkbtn_use_format;
199 *edit_subject_format = entry_subject;
200 *edit_body_format = text_format;
203 void quotefmt_create_reply_fmt_widgets(GtkWindow *parent_window,
204 GtkWidget *parent_box,
205 GtkWidget **checkbtn_reply_with_format,
206 GtkWidget **edit_reply_quotemark,
207 GtkWidget **edit_reply_format,
208 gboolean add_info_button)
210 GtkWidget *checkbtn_use_format = NULL;
211 GtkWidget *vbox_quote;
214 GtkWidget *label_quotemark;
215 GtkWidget *entry_quotemark;
216 GtkWidget *scrolledwin_quotefmt;
217 GtkWidget *text_quotefmt;
220 g_return_if_fail(parent_window != NULL);
221 g_return_if_fail(parent_box != NULL);
222 if (checkbtn_reply_with_format)
223 g_return_if_fail(checkbtn_reply_with_format != NULL);
225 g_return_if_fail(edit_reply_quotemark != NULL);
226 g_return_if_fail(edit_reply_format != NULL);
228 if (checkbtn_reply_with_format)
229 PACK_CHECK_BUTTON (parent_box, checkbtn_use_format,
230 _("Use template when replying to messages"));
232 vbox_quote = gtk_vbox_new (FALSE, 4);
233 gtk_widget_show(vbox_quote);
234 gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
235 gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
237 hbox1 = gtk_hbox_new (FALSE, 32);
238 gtk_widget_show (hbox1);
239 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
241 hbox2 = gtk_hbox_new (FALSE, 8);
242 gtk_widget_show (hbox2);
243 gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
245 label_quotemark = gtk_label_new (_("Quotation mark"));
246 gtk_widget_show (label_quotemark);
247 gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
249 entry_quotemark = gtk_entry_new ();
250 gtk_widget_show (entry_quotemark);
251 gtk_box_pack_start (GTK_BOX (hbox2), entry_quotemark, FALSE, FALSE, 0);
252 gtk_widget_set_size_request (entry_quotemark, 64, -1);
254 scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
255 gtk_widget_show (scrolledwin_quotefmt);
256 gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
258 gtk_scrolled_window_set_policy
259 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
260 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
261 gtk_scrolled_window_set_shadow_type
262 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
264 text_quotefmt = gtk_text_view_new ();
265 if (prefs_common.textfont) {
266 PangoFontDescription *font_desc;
268 font_desc = pango_font_description_from_string
269 (prefs_common.textfont);
271 gtk_widget_modify_font(text_quotefmt, font_desc);
272 pango_font_description_free(font_desc);
275 gtk_widget_show(text_quotefmt);
276 gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt), text_quotefmt);
277 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_quotefmt), TRUE);
278 gtk_widget_set_size_request(text_quotefmt, -1, 100);
280 if (checkbtn_reply_with_format) {
281 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
282 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_quotemark);
283 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_quotefmt);
287 quotefmt_add_info_button(parent_window, vbox_quote);
289 if (checkbtn_reply_with_format)
290 *checkbtn_reply_with_format = checkbtn_use_format;
291 *edit_reply_quotemark = entry_quotemark;
292 *edit_reply_format = text_quotefmt;
295 void quotefmt_create_forward_fmt_widgets(GtkWindow *parent_window,
296 GtkWidget *parent_box,
297 GtkWidget **checkbtn_forward_with_format,
298 GtkWidget **edit_fw_quotemark,
299 GtkWidget **edit_fw_format,
300 gboolean add_info_button)
302 GtkWidget *checkbtn_use_format = NULL;
303 GtkWidget *vbox_quote;
306 GtkWidget *label_quotemark;
307 GtkWidget *entry_fw_quotemark;
308 GtkWidget *scrolledwin_quotefmt;
309 GtkWidget *text_fw_quotefmt;
312 g_return_if_fail(parent_window != NULL);
313 g_return_if_fail(parent_box != NULL);
314 if (checkbtn_forward_with_format) {
315 g_return_if_fail(checkbtn_forward_with_format != 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,
322 _("Use template when forwarding messages"));
324 vbox_quote = gtk_vbox_new (FALSE, 4);
325 gtk_widget_show(vbox_quote);
326 gtk_container_add(GTK_CONTAINER (parent_box), vbox_quote);
327 gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
329 hbox1 = gtk_hbox_new (FALSE, 32);
330 gtk_widget_show (hbox1);
331 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
333 hbox2 = gtk_hbox_new (FALSE, 8);
334 gtk_widget_show (hbox2);
335 gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
337 label_quotemark = gtk_label_new (_("Quotation mark"));
338 gtk_widget_show (label_quotemark);
339 gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
341 entry_fw_quotemark = gtk_entry_new ();
342 gtk_widget_show (entry_fw_quotemark);
343 gtk_box_pack_start (GTK_BOX (hbox2), entry_fw_quotemark,
345 gtk_widget_set_size_request (entry_fw_quotemark, 64, -1);
347 scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
348 gtk_widget_show (scrolledwin_quotefmt);
349 gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
351 gtk_scrolled_window_set_policy
352 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
353 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
354 gtk_scrolled_window_set_shadow_type
355 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
357 text_fw_quotefmt = gtk_text_view_new ();
358 if (prefs_common.textfont) {
359 PangoFontDescription *font_desc;
361 font_desc = pango_font_description_from_string
362 (prefs_common.textfont);
364 gtk_widget_modify_font(text_fw_quotefmt, font_desc);
365 pango_font_description_free(font_desc);
368 gtk_widget_show(text_fw_quotefmt);
369 gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt),
371 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_fw_quotefmt), TRUE);
372 gtk_widget_set_size_request (text_fw_quotefmt, -1, 100);
374 if (checkbtn_forward_with_format) {
375 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, label_quotemark);
376 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, entry_fw_quotemark);
377 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, text_fw_quotefmt);
381 quotefmt_add_info_button(parent_window, vbox_quote);
383 if (checkbtn_forward_with_format)
384 *checkbtn_forward_with_format = checkbtn_use_format;
385 *edit_fw_quotemark = entry_fw_quotemark;
386 *edit_fw_format = text_fw_quotefmt;
389 void quotefmt_add_info_button(GtkWindow *parent_window, GtkWidget *parent_box)
391 GtkWidget *hbox_formatdesc;
392 GtkWidget *btn_formatdesc;
394 hbox_formatdesc = gtk_hbox_new (FALSE, 32);
395 gtk_widget_show (hbox_formatdesc);
396 gtk_box_pack_start (GTK_BOX (parent_box), hbox_formatdesc, FALSE, FALSE,
399 #if GTK_CHECK_VERSION(2, 8, 0)
400 btn_formatdesc = gtk_button_new_from_stock(GTK_STOCK_INFO);
403 gtk_button_new_with_label (_("Description of symbols..."));
405 gtk_widget_show (btn_formatdesc);
406 gtk_box_pack_start (GTK_BOX (hbox_formatdesc), btn_formatdesc, FALSE, FALSE, 0);
407 g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
408 G_CALLBACK(quote_fmt_quote_description), GTK_WIDGET(parent_window));
412 void quotefmt_check_new_msg_formats(gboolean use_format,
419 if (!prefs_template_string_is_valid(subject_fmt, NULL))
420 alertpanel_error(_("New message subject format error."));
422 if (!prefs_template_string_is_valid(body_fmt, &line)) {
423 alertpanel_error(_("New message body format error at line %d."), line);
428 void quotefmt_check_reply_formats(gboolean use_format,
429 gchar *quotation_mark,
435 if (!prefs_template_string_is_valid(quotation_mark, NULL))
436 alertpanel_error(_("Message reply quotation mark format error."));
438 if (!prefs_template_string_is_valid(body_fmt, &line)) {
439 alertpanel_error(_("Message reply format error at line %d."), line);
444 void quotefmt_check_forward_formats(gboolean use_format,
445 gchar *quotation_mark,
451 if (!prefs_template_string_is_valid(quotation_mark, NULL))
452 alertpanel_error(_("Message forward quotation mark format error."));
454 if (!prefs_template_string_is_valid(body_fmt, &line)) {
455 alertpanel_error(_("Message forward format error at line %d."), line);