2007-08-27 [colin] 2.10.0cvs179
[claws.git] / src / quote_fmt.c
blobf5fa9ed31e9d2f2657c46df725a0b41ef28ceebb
1 /*
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/>.
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
24 #include <glib.h>
25 #include <glib/gi18n.h>
26 #include <gtk/gtk.h>
27 #include <gdk/gdkkeysyms.h>
29 #include "manage_window.h"
30 #include "description_window.h"
31 #include "gtkutils.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"),
83 "\\t", N_("tab"),
84 "\\n", N_("new line"),
85 "", NULL,
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 "", NULL,
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"),
97 NULL,NULL
100 static DescriptionWindow quote_desc_win = {
101 NULL,
102 NULL,
104 N_("Description of symbols"),
105 N_("The following symbols and commands can be used:"),
106 quote_desc_strings
110 void quote_fmt_quote_description(GtkWidget *widget, GtkWidget *pref_window)
112 quote_desc_win.parent = pref_window;
113 description_window_create(&quote_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;
133 if (add_info_button)
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 vbox_format = gtkut_get_options_frame(parent_box, &frame_format, checkbtn_compose_text);
149 if (checkbtn_compose_with_format)
150 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, frame_format);
152 hbox_format = gtk_hbox_new (FALSE, 8);
153 gtk_widget_show (hbox_format);
154 gtk_box_pack_start (GTK_BOX (vbox_format), hbox_format, FALSE, FALSE, 0);
156 label_subject = gtk_label_new (_("Subject"));
157 gtk_widget_show (label_subject);
158 gtk_box_pack_start (GTK_BOX (hbox_format), label_subject, FALSE, FALSE, 0);
160 entry_subject = gtk_entry_new ();
161 gtk_widget_show (entry_subject);
162 gtk_box_pack_start (GTK_BOX (hbox_format), entry_subject, TRUE, TRUE, 0);
163 gtk_widget_set_size_request (entry_subject, 100, -1);
165 scrolledwin_format = gtk_scrolled_window_new (NULL, NULL);
166 gtk_widget_show (scrolledwin_format);
167 gtk_box_pack_start (GTK_BOX (vbox_format), scrolledwin_format,
168 TRUE, TRUE, 0);
169 gtk_scrolled_window_set_policy
170 (GTK_SCROLLED_WINDOW (scrolledwin_format),
171 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
172 gtk_scrolled_window_set_shadow_type
173 (GTK_SCROLLED_WINDOW (scrolledwin_format), GTK_SHADOW_IN);
175 text_format = gtk_text_view_new ();
176 if (prefs_common.textfont) {
177 PangoFontDescription *font_desc;
179 font_desc = pango_font_description_from_string
180 (prefs_common.textfont);
181 if (font_desc) {
182 gtk_widget_modify_font(text_format, font_desc);
183 pango_font_description_free(font_desc);
186 gtk_widget_show(text_format);
187 gtk_container_add(GTK_CONTAINER(scrolledwin_format), text_format);
188 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_format), TRUE);
189 gtk_widget_set_size_request(text_format, -1, 100);
191 if (add_info_button)
192 quotefmt_add_info_button(parent_window, vbox_format);
194 if (checkbtn_compose_with_format)
195 *checkbtn_compose_with_format = checkbtn_use_format;
196 *edit_subject_format = entry_subject;
197 *edit_body_format = text_format;
200 void quotefmt_create_reply_fmt_widgets(GtkWindow *parent_window,
201 GtkWidget *parent_box,
202 GtkWidget **checkbtn_reply_with_format,
203 gchar *checkbtn_reply_text,
204 GtkWidget **edit_reply_quotemark,
205 GtkWidget **edit_reply_format,
206 gboolean add_info_button)
208 GtkWidget *checkbtn_use_format = NULL;
209 GtkWidget *frame_quote;
210 GtkWidget *vbox_quote;
211 GtkWidget *hbox1;
212 GtkWidget *hbox2;
213 GtkWidget *label_quotemark;
214 GtkWidget *entry_quotemark;
215 GtkWidget *scrolledwin_quotefmt;
216 GtkWidget *text_quotefmt;
218 if (add_info_button)
219 g_return_if_fail(parent_window != NULL);
220 g_return_if_fail(parent_box != NULL);
221 if (checkbtn_reply_with_format) {
222 g_return_if_fail(checkbtn_reply_with_format != NULL);
223 g_return_if_fail(checkbtn_reply_text != 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, checkbtn_reply_text);
231 PACK_FRAME (parent_box, frame_quote, _("Reply format"));
233 if (checkbtn_reply_with_format)
234 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, frame_quote);
236 vbox_quote = gtk_vbox_new (FALSE, VSPACING_NARROW);
237 gtk_widget_show (vbox_quote);
238 gtk_container_add (GTK_CONTAINER (frame_quote), vbox_quote);
239 gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
241 hbox1 = gtk_hbox_new (FALSE, 32);
242 gtk_widget_show (hbox1);
243 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
245 hbox2 = gtk_hbox_new (FALSE, 8);
246 gtk_widget_show (hbox2);
247 gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
249 label_quotemark = gtk_label_new (_("Quotation mark"));
250 gtk_widget_show (label_quotemark);
251 gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
253 entry_quotemark = gtk_entry_new ();
254 gtk_widget_show (entry_quotemark);
255 gtk_box_pack_start (GTK_BOX (hbox2), entry_quotemark, FALSE, FALSE, 0);
256 gtk_widget_set_size_request (entry_quotemark, 64, -1);
258 scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
259 gtk_widget_show (scrolledwin_quotefmt);
260 gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
261 TRUE, TRUE, 0);
262 gtk_scrolled_window_set_policy
263 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
264 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
265 gtk_scrolled_window_set_shadow_type
266 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
268 text_quotefmt = gtk_text_view_new ();
269 if (prefs_common.textfont) {
270 PangoFontDescription *font_desc;
272 font_desc = pango_font_description_from_string
273 (prefs_common.textfont);
274 if (font_desc) {
275 gtk_widget_modify_font(text_quotefmt, font_desc);
276 pango_font_description_free(font_desc);
279 gtk_widget_show(text_quotefmt);
280 gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt), text_quotefmt);
281 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_quotefmt), TRUE);
282 gtk_widget_set_size_request(text_quotefmt, -1, 100);
284 if (add_info_button)
285 quotefmt_add_info_button(parent_window, vbox_quote);
287 if (checkbtn_reply_with_format)
288 *checkbtn_reply_with_format = checkbtn_use_format;
289 *edit_reply_quotemark = entry_quotemark;
290 *edit_reply_format = text_quotefmt;
293 void quotefmt_create_forward_fmt_widgets(GtkWindow *parent_window,
294 GtkWidget *parent_box,
295 GtkWidget **checkbtn_forward_with_format,
296 gchar *checkbtn_forward_text,
297 GtkWidget **edit_fw_quotemark,
298 GtkWidget **edit_fw_format,
299 gboolean add_info_button)
301 GtkWidget *checkbtn_use_format = NULL;
302 GtkWidget *frame_quote;
303 GtkWidget *vbox_quote;
304 GtkWidget *hbox1;
305 GtkWidget *hbox2;
306 GtkWidget *label_quotemark;
307 GtkWidget *entry_fw_quotemark;
308 GtkWidget *scrolledwin_quotefmt;
309 GtkWidget *text_fw_quotefmt;
311 if (add_info_button)
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);
316 g_return_if_fail(checkbtn_forward_text != 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, checkbtn_forward_text);
324 PACK_FRAME (parent_box, frame_quote, _("Forward format"));
326 if (checkbtn_forward_with_format)
327 SET_TOGGLE_SENSITIVITY(checkbtn_use_format, frame_quote);
329 vbox_quote = gtk_vbox_new (FALSE, VSPACING_NARROW);
330 gtk_widget_show (vbox_quote);
331 gtk_container_add (GTK_CONTAINER (frame_quote), vbox_quote);
332 gtk_container_set_border_width (GTK_CONTAINER (vbox_quote), 8);
334 hbox1 = gtk_hbox_new (FALSE, 32);
335 gtk_widget_show (hbox1);
336 gtk_box_pack_start (GTK_BOX (vbox_quote), hbox1, FALSE, FALSE, 0);
338 hbox2 = gtk_hbox_new (FALSE, 8);
339 gtk_widget_show (hbox2);
340 gtk_box_pack_start (GTK_BOX (hbox1), hbox2, FALSE, FALSE, 0);
342 label_quotemark = gtk_label_new (_("Quotation mark"));
343 gtk_widget_show (label_quotemark);
344 gtk_box_pack_start (GTK_BOX (hbox2), label_quotemark, FALSE, FALSE, 0);
346 entry_fw_quotemark = gtk_entry_new ();
347 gtk_widget_show (entry_fw_quotemark);
348 gtk_box_pack_start (GTK_BOX (hbox2), entry_fw_quotemark,
349 FALSE, FALSE, 0);
350 gtk_widget_set_size_request (entry_fw_quotemark, 64, -1);
352 scrolledwin_quotefmt = gtk_scrolled_window_new (NULL, NULL);
353 gtk_widget_show (scrolledwin_quotefmt);
354 gtk_box_pack_start (GTK_BOX (vbox_quote), scrolledwin_quotefmt,
355 TRUE, TRUE, 0);
356 gtk_scrolled_window_set_policy
357 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt),
358 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
359 gtk_scrolled_window_set_shadow_type
360 (GTK_SCROLLED_WINDOW (scrolledwin_quotefmt), GTK_SHADOW_IN);
362 text_fw_quotefmt = gtk_text_view_new ();
363 if (prefs_common.textfont) {
364 PangoFontDescription *font_desc;
366 font_desc = pango_font_description_from_string
367 (prefs_common.textfont);
368 if (font_desc) {
369 gtk_widget_modify_font(text_fw_quotefmt, font_desc);
370 pango_font_description_free(font_desc);
373 gtk_widget_show(text_fw_quotefmt);
374 gtk_container_add(GTK_CONTAINER(scrolledwin_quotefmt),
375 text_fw_quotefmt);
376 gtk_text_view_set_editable (GTK_TEXT_VIEW (text_fw_quotefmt), TRUE);
377 gtk_widget_set_size_request (text_fw_quotefmt, -1, 100);
379 if (add_info_button)
380 quotefmt_add_info_button(parent_window, vbox_quote);
382 if (checkbtn_forward_with_format)
383 *checkbtn_forward_with_format = checkbtn_use_format;
384 *edit_fw_quotemark = entry_fw_quotemark;
385 *edit_fw_format = text_fw_quotefmt;
388 void quotefmt_add_info_button(GtkWindow *parent_window, GtkWidget *parent_box)
390 GtkWidget *hbox_formatdesc;
391 GtkWidget *btn_formatdesc;
393 hbox_formatdesc = gtk_hbox_new (FALSE, 32);
394 gtk_widget_show (hbox_formatdesc);
395 gtk_box_pack_start (GTK_BOX (parent_box), hbox_formatdesc, FALSE, FALSE, 0);
397 #if GTK_CHECK_VERSION(2, 8, 0)
398 btn_formatdesc = gtk_button_new_from_stock(GTK_STOCK_INFO);
399 #else
400 btn_formatdesc =
401 gtk_button_new_with_label (_("Description of symbols..."));
402 #endif
403 gtk_widget_show (btn_formatdesc);
404 gtk_box_pack_start (GTK_BOX (hbox_formatdesc), btn_formatdesc, FALSE, FALSE, 0);
405 g_signal_connect(G_OBJECT(btn_formatdesc), "clicked",
406 G_CALLBACK(quote_fmt_quote_description), GTK_WIDGET(parent_window));
410 void quotefmt_check_new_msg_formats(gboolean use_format,
411 gchar *subject_fmt,
412 gchar *body_fmt)
414 if (use_format) {
415 gint line;
417 if (!prefs_template_string_is_valid(subject_fmt, NULL))
418 alertpanel_error(_("New message subject format error."));
420 if (!prefs_template_string_is_valid(body_fmt, &line)) {
421 gchar *msg = g_strdup_printf(_("New message body format error at line %d."), line);
422 alertpanel_error(msg);
423 g_free(msg);
428 void quotefmt_check_reply_formats(gboolean use_format,
429 gchar *quotation_mark,
430 gchar *body_fmt)
432 if (use_format) {
433 gint line;
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 gchar *msg = g_strdup_printf(_("Message reply format error at line %d."), line);
440 alertpanel_error(msg);
441 g_free(msg);
446 void quotefmt_check_forward_formats(gboolean use_format,
447 gchar *quotation_mark,
448 gchar *body_fmt)
450 if (use_format) {
451 gint line;
453 if (!prefs_template_string_is_valid(quotation_mark, NULL))
454 alertpanel_error(_("Message forward quotation mark format error."));
456 if (!prefs_template_string_is_valid(body_fmt, &line)) {
457 gchar *msg = g_strdup_printf(_("Message forward format error at line %d."), line);
458 alertpanel_error(msg);
459 g_free(msg);