From 84ec518f60ce61ba4ea2b5b6d2ac241233983e9c Mon Sep 17 00:00:00 2001 From: Tristan Chabredier Date: Thu, 9 Nov 2006 15:15:17 +0000 Subject: [PATCH] 2006-11-09 [wwp] 2.6.0cvs21 * src/compose.c * src/prefs_common.c * src/prefs_common.h * src/prefs_compose_writing.c add a compose new message format (in prefs/compose/writing), it's a simple subject+body template to use when opening a new composition window. It's similar to the existent reply and forward formats. enhanced the template/format % symbols substitution mechanism to use current composition window information when % are used in the compose new message format or in templates applied to new messages (there were useless in that situations before). When applied to new messages, %d corresponds to the system time/date. --- ChangeLog | 16 +++ PATCHSETS | 1 + configure.ac | 2 +- src/compose.c | 248 ++++++++++++++++++++++++++++++------ src/prefs_common.c | 122 ++++++++++++++---- src/prefs_common.h | 6 + src/prefs_compose_writing.c | 92 +++++++++++++ 7 files changed, 422 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index 31bbc7550..9791c7784 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2006-11-09 [wwp] 2.6.0cvs21 + + * src/compose.c + * src/prefs_common.c + * src/prefs_common.h + * src/prefs_compose_writing.c + add a compose new message format (in prefs/compose/writing), it's a + simple subject+body template to use when opening a new composition + window. It's similar to the existent reply and forward formats. + + enhanced the template/format % symbols substitution mechanism to + use current composition window information when % are used in + the compose new message format or in templates applied to new + messages (there were useless in that situations before). When + applied to new messages, %d corresponds to the system time/date. + 2006-11-09 [paul] 2.6.0cvs20 * src/gtk/authors.h diff --git a/PATCHSETS b/PATCHSETS index 6b2af3ee1..9019c0a91 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -2045,3 +2045,4 @@ ( cvs diff -u -r 1.1.4.56 -r 1.1.4.57 src/etpan/imap-thread.c; ) > 2.6.0cvs18.patchset ( cvs diff -u -r 1.1.2.27 -r 1.1.2.28 src/gtk/authors.h; ) > 2.6.0cvs19.patchset ( cvs diff -u -r 1.1.2.28 -r 1.1.2.29 src/gtk/authors.h; ) > 2.6.0cvs20.patchset +( cvs diff -u -r 1.382.2.324 -r 1.382.2.325 src/compose.c; cvs diff -u -r 1.204.2.108 -r 1.204.2.109 src/prefs_common.c; cvs diff -u -r 1.103.2.66 -r 1.103.2.67 src/prefs_common.h; cvs diff -u -r 1.1.2.11 -r 1.1.2.12 src/prefs_compose_writing.c; ) > 2.6.0cvs21.patchset diff --git a/configure.ac b/configure.ac index e709be67e..6bd4aab64 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=6 MICRO_VERSION=0 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=20 +EXTRA_VERSION=21 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/compose.c b/src/compose.c index 5639fc952..a0f14802a 100644 --- a/src/compose.c +++ b/src/compose.c @@ -221,7 +221,8 @@ static gchar *compose_quote_fmt (Compose *compose, const gchar *fmt, const gchar *qmark, const gchar *body, - gboolean rewrap); + gboolean rewrap, + const gchar *err_msg); static void compose_reply_set_entry (Compose *compose, MsgInfo *msginfo, @@ -512,6 +513,8 @@ static void compose_check_forwards_go (Compose *compose); static gint compose_defer_auto_save_draft (Compose *compose); static PrefsAccount *compose_guess_forward_account_from_msginfo (MsgInfo *msginfo); +static MsgInfo *compose_msginfo_new_from_compose(Compose *compose); + static GtkItemFactoryEntry compose_popup_entries[] = { {N_("/_Add..."), NULL, compose_attach_cb, 0, NULL}, @@ -1004,6 +1007,67 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI } compose_add_field_list( compose, listAddress ); + if (prefs_common.compose_with_format) { + MsgInfo* dummyinfo = NULL; + + if ( prefs_common.compose_subject_format + && *prefs_common.compose_subject_format != '\0' ) + { + gchar *subject = NULL; + gchar *tmp = NULL; + gchar *buf = NULL; + + dummyinfo = compose_msginfo_new_from_compose(compose); + + /* decode \-escape sequences in the internal representation of the quote format */ + tmp = malloc(strlen(prefs_common.compose_subject_format)+1); + pref_get_unescaped_pref(tmp, prefs_common.compose_subject_format); + + subject = gtk_editable_get_chars(GTK_EDITABLE(compose->subject_entry), 0, -1); + quote_fmt_init(dummyinfo, NULL, subject, FALSE, compose->account); + quote_fmt_scan_string(tmp); + quote_fmt_parse(); + + buf = quote_fmt_get_buffer(); + if (buf == NULL) + alertpanel_error(_("New message subject format error.")); + else + gtk_entry_set_text(GTK_ENTRY(compose->subject_entry), buf); + quote_fmt_reset_vartable(); + + g_free(subject); + g_free(tmp); + } + + if ( prefs_common.compose_body_format + && *prefs_common.compose_body_format != '\0' ) + { + GtkTextView *text; + GtkTextBuffer *buffer; + GtkTextIter start, end; + gchar *tmp = NULL; + + if ( dummyinfo == NULL ) + dummyinfo = compose_msginfo_new_from_compose(compose); + + text = GTK_TEXT_VIEW(compose->text); + buffer = gtk_text_view_get_buffer(text); + gtk_text_buffer_get_start_iter(buffer, &start); + gtk_text_buffer_get_iter_at_offset(buffer, &end, -1); + tmp = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); + + compose_quote_fmt(compose, dummyinfo, + prefs_common.compose_body_format, + NULL, tmp, FALSE, + _("New message body format error.")); + quote_fmt_reset_vartable(); + + g_free(tmp); + } + + procmsg_msginfo_free( dummyinfo ); + } + if (attach_files) { gint i; gchar *file; @@ -1359,7 +1423,8 @@ static Compose *compose_generic_reply(MsgInfo *msginfo, gboolean quote, compose_quote_fmt(compose, compose->replyinfo, prefs_common.quotefmt, - qmark, body, FALSE); + qmark, body, FALSE, + _("Message reply format error.")); quote_fmt_reset_vartable(); } if (procmime_msginfo_is_encrypted(compose->replyinfo)) { @@ -1475,7 +1540,8 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo, compose_quote_fmt(compose, full_msginfo, prefs_common.fw_quotefmt, - qmark, body, FALSE); + qmark, body, FALSE, + _("Message forward format error.")); quote_fmt_reset_vartable(); compose_attach_parts(compose, msginfo); @@ -1949,7 +2015,8 @@ Compose *compose_redirect(PrefsAccount *account, MsgInfo *msginfo, msginfo->subject); gtk_editable_set_editable(GTK_EDITABLE(compose->subject_entry), FALSE); - compose_quote_fmt(compose, msginfo, "%M", NULL, NULL, FALSE); + compose_quote_fmt(compose, msginfo, "%M", NULL, NULL, FALSE, + _("Message redirect format error.")); quote_fmt_reset_vartable(); gtk_text_view_set_editable(GTK_TEXT_VIEW(compose->text), FALSE); @@ -2408,9 +2475,10 @@ static gchar *compose_parse_references(const gchar *ref, const gchar *msgid) static gchar *compose_quote_fmt(Compose *compose, MsgInfo *msginfo, const gchar *fmt, const gchar *qmark, - const gchar *body, gboolean rewrap) + const gchar *body, gboolean rewrap, + const gchar *err_msg) { - static MsgInfo dummyinfo; + MsgInfo* dummyinfo = NULL; gchar *quote_str = NULL; gchar *buf; gboolean prev_autowrap; @@ -2424,8 +2492,10 @@ static gchar *compose_quote_fmt(Compose *compose, MsgInfo *msginfo, SIGNAL_BLOCK(buffer); - if (!msginfo) - msginfo = &dummyinfo; + if (!msginfo) { + dummyinfo = compose_msginfo_new_from_compose(compose); + msginfo = dummyinfo; + } if (qmark != NULL) { quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account); @@ -2457,7 +2527,7 @@ static gchar *compose_quote_fmt(Compose *compose, MsgInfo *msginfo, buf = quote_fmt_get_buffer(); if (buf == NULL) { - alertpanel_error(_("Message reply/forward format error.")); + alertpanel_error(err_msg); goto error; } } else @@ -2504,6 +2574,7 @@ error: ok: SIGNAL_UNBLOCK(buffer); + procmsg_msginfo_free( dummyinfo ); return buf; } @@ -6729,6 +6800,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl, gchar *qmark; gchar *parsed_str = NULL; gint cursor_pos = 0; + const gchar *err_msg = _("Template body format error."); if (!tmpl) return; /* process the body */ @@ -6736,32 +6808,59 @@ static void compose_template_apply(Compose *compose, Template *tmpl, text = GTK_TEXT_VIEW(compose->text); buffer = gtk_text_view_get_buffer(text); - if (replace) - gtk_text_buffer_set_text(buffer, "", -1); + if (tmpl->value) { + if (prefs_common.quotemark && *prefs_common.quotemark) + qmark = prefs_common.quotemark; + else + qmark = "> "; - mark = gtk_text_buffer_get_insert(buffer); - gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); + if (compose->replyinfo != NULL) { + + if (replace) + gtk_text_buffer_set_text(buffer, "", -1); + mark = gtk_text_buffer_get_insert(buffer); + gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); + + parsed_str = compose_quote_fmt(compose, compose->replyinfo, + tmpl->value, qmark, NULL, FALSE, err_msg); + + } else if (compose->fwdinfo != NULL) { + + if (replace) + gtk_text_buffer_set_text(buffer, "", -1); + mark = gtk_text_buffer_get_insert(buffer); + gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); + + parsed_str = compose_quote_fmt(compose, compose->fwdinfo, + tmpl->value, qmark, NULL, FALSE, err_msg); - if (tmpl->value) { - if ((compose->replyinfo == NULL) && (compose->fwdinfo == NULL)) { - parsed_str = compose_quote_fmt(compose, NULL, tmpl->value, - NULL, NULL, FALSE); } else { - if (prefs_common.quotemark && *prefs_common.quotemark) - qmark = prefs_common.quotemark; - else - qmark = "> "; - - if (compose->replyinfo != NULL) - parsed_str = compose_quote_fmt(compose, compose->replyinfo, - tmpl->value, qmark, NULL, FALSE); - else if (compose->fwdinfo != NULL) - parsed_str = compose_quote_fmt(compose, compose->fwdinfo, - tmpl->value, qmark, NULL, FALSE); - else - parsed_str = NULL; - } - } + MsgInfo* dummyinfo = compose_msginfo_new_from_compose(compose); + + GtkTextIter start, end; + gchar *tmp = NULL; + + gtk_text_buffer_get_start_iter(buffer, &start); + gtk_text_buffer_get_iter_at_offset(buffer, &end, -1); + tmp = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); + + /* clear the buffer now */ + if (replace) + gtk_text_buffer_set_text(buffer, "", -1); + + parsed_str = compose_quote_fmt(compose, dummyinfo, + tmpl->value, qmark, tmp, FALSE, err_msg); + procmsg_msginfo_free( dummyinfo ); + + g_free( tmp ); + } + } else { + if (replace) + gtk_text_buffer_set_text(buffer, "", -1); + mark = gtk_text_buffer_get_insert(buffer); + gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); + } + if (replace && parsed_str && compose->account->auto_sig) compose_insert_sig(compose, FALSE); @@ -6781,6 +6880,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl, } /* process the other fields */ + compose_template_apply_fields(compose, tmpl); quote_fmt_reset_vartable(); compose_changed_cb(NULL, compose); @@ -6788,7 +6888,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl, void compose_template_apply_fields(Compose *compose, Template *tmpl) { - static MsgInfo dummyinfo; + MsgInfo* dummyinfo = NULL; MsgInfo *msginfo = NULL; gchar *buf = NULL; @@ -6796,8 +6896,10 @@ void compose_template_apply_fields(Compose *compose, Template *tmpl) msginfo = compose->replyinfo; else if (compose->fwdinfo != NULL) msginfo = compose->fwdinfo; - else - msginfo = &dummyinfo; + else { + dummyinfo = compose_msginfo_new_from_compose(compose); + msginfo = dummyinfo; + } if (tmpl->to && *tmpl->to != '\0') { quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account); @@ -6851,6 +6953,8 @@ void compose_template_apply_fields(Compose *compose, Template *tmpl) gtk_entry_set_text(GTK_ENTRY(compose->subject_entry), buf); } } + + procmsg_msginfo_free( dummyinfo ); } static void compose_destroy(Compose *compose) @@ -8980,7 +9084,8 @@ static void text_inserted(GtkTextBuffer *buffer, GtkTextIter *iter, mark = gtk_text_buffer_create_mark(buffer, NULL, iter, FALSE); gtk_text_buffer_place_cursor(buffer, iter); - compose_quote_fmt(compose, NULL, "%Q", qmark, new_text, TRUE); + compose_quote_fmt(compose, NULL, "%Q", qmark, new_text, TRUE, + _("Quote format error.")); quote_fmt_reset_vartable(); g_free(new_text); g_object_set_data(G_OBJECT(compose->text), "paste_as_quotation", @@ -9240,6 +9345,77 @@ gboolean compose_search_string_backward(Compose *compose, return gtkut_text_view_search_string_backward(text, str, case_sens); } +/* allocate a msginfo structure and populate its data from a compose data structure */ +static MsgInfo *compose_msginfo_new_from_compose(Compose *compose) +{ + MsgInfo *newmsginfo; + GSList *list; + gchar buf[BUFFSIZE]; + + g_return_val_if_fail( compose != NULL, NULL ); + + newmsginfo = procmsg_msginfo_new(); + + /* date is now */ + get_rfc822_date(buf, sizeof(buf)); + newmsginfo->date = g_strdup(buf); + + /* from */ + if (compose->from_name) { + newmsginfo->from = gtk_editable_get_chars(GTK_EDITABLE(compose->from_name), 0, -1); + newmsginfo->fromname = procheader_get_fromname(newmsginfo->from); + } + + /* subject */ + if (compose->subject_entry) + newmsginfo->subject = gtk_editable_get_chars(GTK_EDITABLE(compose->subject_entry), 0, -1); + + /* to, cc, reply-to, newsgroups */ + for (list = compose->header_list; list; list = list->next) { + gchar *header = gtk_editable_get_chars( + GTK_EDITABLE( + GTK_COMBO(((ComposeHeaderEntry *)list->data)->combo)->entry), 0, -1); + gchar *entry = gtk_editable_get_chars( + GTK_EDITABLE(((ComposeHeaderEntry *)list->data)->entry), 0, -1); + + if ( strcasecmp(header, (prefs_common.trans_hdr ? gettext("To:") : "To:")) == 0 ) { + if ( newmsginfo->to == NULL ) { + newmsginfo->to = g_strdup(entry); + } else { + gchar *tmp = g_strconcat(newmsginfo->to, ", ", entry, NULL); + g_free(newmsginfo->to); + newmsginfo->to = tmp; + } + } else + if ( strcasecmp(header, (prefs_common.trans_hdr ? gettext("Cc:") : "Cc:")) == 0 ) { + if ( newmsginfo->cc == NULL ) { + newmsginfo->cc = g_strdup(entry); + } else { + gchar *tmp = g_strconcat(newmsginfo->cc, ", ", entry, NULL); + g_free(newmsginfo->cc); + newmsginfo->cc = tmp; + } + } else + if ( strcasecmp(header, + (prefs_common.trans_hdr ? gettext("Newsgroups:") : "Newsgroups:")) == 0 ) { + if ( newmsginfo->newsgroups == NULL ) { + newmsginfo->newsgroups = g_strdup(entry); + } else { + gchar *tmp = g_strconcat(newmsginfo->newsgroups, ", ", entry, NULL); + g_free(newmsginfo->newsgroups); + newmsginfo->newsgroups = tmp; + } + } + + g_free(header); + g_free(entry); + } + + /* other data is unset */ + + return newmsginfo; +} + /* * End of Source. */ diff --git a/src/prefs_common.c b/src/prefs_common.c index ab897ca70..c304b5a4b 100644 --- a/src/prefs_common.c +++ b/src/prefs_common.c @@ -203,6 +203,12 @@ static PrefParam param[] = { NULL, NULL, NULL}, {"undo_level", "50", &prefs_common.undolevels, P_INT, NULL, NULL, NULL}, + {"compose_with_format", "FALSE", &prefs_common.compose_with_format, P_BOOL, + NULL, NULL, NULL}, + {"compose_subject_format", "", + &prefs_common.compose_subject_format, P_STRING, NULL, NULL, NULL}, + {"compose_body_format", N_("Hello,\\n"), + &prefs_common.compose_body_format, P_STRING, NULL, NULL, NULL}, {"linewrap_length", "72", &prefs_common.linewrap_len, P_INT, NULL, NULL, NULL}, @@ -926,10 +932,14 @@ void prefs_common_write_config(void) /* make a copy of string 'in' into buffer 'out'. un-escape \ sequences. both 'in' and 'out' must be non-NULL. 'out' must be a pointer to a buffer whose size is at least equal - to strlen(txt)+1, this buffer will get cleared. */ + to strlen(txt)+1, this buffer will get cleared. out's contents + will always get set to a valid string, even if it's "".*/ void pref_get_unescaped_pref(gchar *out, const gchar *in) { - gchar *o, *i; + const gchar *i; + gchar *o; + + *out = '\0'; g_return_if_fail( in != NULL ); g_return_if_fail( out != NULL ); @@ -955,56 +965,112 @@ void pref_get_unescaped_pref(gchar *out, const gchar *in) *o='\0'; } +/* make a copy of string 'in' into buffer 'out'. escape \ sequences. + both 'in' and 'out' must be non-NULL. + 'out' must be a pointer to a buffer whose size is at least equal + to 2*strlen(txt)+1. out's contents will always get set to a valid + string, even if it's "". */ +void pref_get_escaped_pref(gchar *out, const gchar *in) +{ + const gchar *i; + gchar *o; + + *out = '\0'; + + g_return_if_fail( in != NULL ); + g_return_if_fail( out != NULL ); + + i = in; + o = out; + while (*i != '\0') { + if (*i == '\n') { + *o++ = '\\'; + *o++ = 'n'; + } else if (*i == '\t') { + *o++ = '\\'; + *o++ = 't'; + } else if (*i == '\\') { + *o++ = '\\'; + *o++ = '\\'; + } else { + *o++ = *i; + } + i++; + } + *o = '\0'; +} + /* set the contents of a textview widget from the internal \-escaped - representation of a pref string */ + representation of a pref string. both txt and textview must be non-NULL. */ void pref_set_textview_from_pref(GtkTextView *textview, const gchar *txt) { - GtkTextBuffer *out_buffer; + GtkTextBuffer *buffer; + gchar *out = NULL; + + g_return_if_fail( txt != NULL ); + g_return_if_fail( textview != NULL ); + + buffer = gtk_text_view_get_buffer(textview); + out = malloc(strlen(txt)+1); + + pref_get_unescaped_pref(out, txt); + + gtk_text_buffer_set_text(buffer, out?out:"", -1); + g_free(out); +} + +/* set the contents of a gtkentry widget from the internal \-escaped + representation of a pref string. both txt and entry must be non-NULL. */ +void pref_set_entry_from_pref(GtkEntry *entry, const gchar *txt) +{ gchar *out = NULL; g_return_if_fail( txt != NULL ); + g_return_if_fail( entry != NULL ); - out_buffer = gtk_text_view_get_buffer(textview); - out = malloc(txt?(strlen(txt)+1):1); + out = malloc(strlen(txt)+1); pref_get_unescaped_pref(out, txt); - gtk_text_buffer_set_text(out_buffer, out?out:"", -1); + gtk_entry_set_text(entry, out?out:""); g_free(out); } /* get the \-escaped internal representation of a pref from the contents of - a textview widget */ + a textview widget. textview must be non-NULL. */ gchar *pref_get_pref_from_textview(GtkTextView *textview) { GtkTextBuffer *buffer; GtkTextIter start, end; - gchar *o_out, *out, *tmp, *t; + gchar *out, *tmp; + g_return_val_if_fail( textview != NULL, "" ); + buffer = gtk_text_view_get_buffer(textview); gtk_text_buffer_get_start_iter(buffer, &start); gtk_text_buffer_get_iter_at_offset(buffer, &end, -1); tmp = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); - t = tmp; - o_out = out = malloc(2*strlen(tmp)+1); + out = malloc(2*strlen(tmp)+1); - while (*t != '\0') { - if (*t == '\n') { - *out++ = '\\'; - *out++ = 'n'; - } else if (*t == '\t') { - *out++ = '\\'; - *out++ = 't'; - } else if (*t == '\\') { - *out++ = '\\'; - *out++ = '\\'; - } else { - *out++ = *t; - } - t++; - } - *out = '\0'; + pref_get_escaped_pref(out, tmp); + g_free(tmp); + + return out?out:""; +} + +/* get the \-escaped internal representation of a pref from the contents of + a gtkentry widget. entry must be non-NULL. */ +gchar *pref_get_pref_from_entry(GtkEntry *entry) +{ + gchar *out, *tmp; + + g_return_val_if_fail( entry != NULL, "" ); + + tmp = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); + out = malloc(2*strlen(tmp)+1); + + pref_get_escaped_pref(out, tmp); g_free(tmp); - return o_out; + return out?out:""; } diff --git a/src/prefs_common.h b/src/prefs_common.h index 506679808..de2396963 100644 --- a/src/prefs_common.h +++ b/src/prefs_common.h @@ -126,6 +126,9 @@ struct _PrefsCommon gint autosave_length; gboolean compose_no_markup; ComposeDndInsertOrAttach compose_dnd_mode; + gboolean compose_with_format; + gchar *compose_subject_format; + gchar *compose_body_format; /* Quote */ gboolean reply_with_quote; @@ -407,7 +410,10 @@ void prefs_common_write_config (void); void prefs_common_open (void); PrefsCommon *prefs_common_get (void); void pref_get_unescaped_pref(gchar *out, const gchar *in); +void pref_get_escaped_pref(gchar *out, const gchar *in); void pref_set_textview_from_pref(GtkTextView *textview, const gchar *txt); +void pref_set_entry_from_pref(GtkEntry *entry, const gchar *txt); gchar *pref_get_pref_from_textview(GtkTextView *textview); +gchar *pref_get_pref_from_entry(GtkEntry *entry); #endif /* __PREFS_COMMON_H__ */ diff --git a/src/prefs_compose_writing.c b/src/prefs_compose_writing.c index c6e36a70e..9aadf1618 100644 --- a/src/prefs_compose_writing.c +++ b/src/prefs_compose_writing.c @@ -40,6 +40,10 @@ #include "manage_window.h" +#include "quote_fmt.h" +#include "prefs_template.h" +#include "alertpanel.h" + typedef struct _WritingPage { PrefsPage page; @@ -58,6 +62,9 @@ typedef struct _WritingPage GtkWidget *checkbtn_autosave; GtkWidget *spinbtn_autosave_length; GtkWidget *optmenu_dnd_insert_or_attach; + GtkWidget *checkbtn_compose_with_format; + GtkWidget *entry_subject; + GtkWidget *text_format; } WritingPage; void prefs_compose_writing_create_widget(PrefsPage *_page, GtkWindow *window, @@ -98,6 +105,17 @@ void prefs_compose_writing_create_widget(PrefsPage *_page, GtkWindow *window, GtkWidget *menu; GtkWidget *menuitem; + GtkWidget *frame_format; + GtkWidget *checkbtn_compose_with_format; + GtkWidget *vbox_format; + GtkWidget *hbox_format; + GtkWidget *label_subject; + GtkWidget *entry_subject; + GtkWidget *scrolledwin_format; + GtkWidget *text_format; + GtkWidget *hbox_formatdesc; + GtkWidget *btn_formatdesc; + vbox1 = gtk_vbox_new (FALSE, VSPACING); gtk_widget_show (vbox1); gtk_container_set_border_width (GTK_CONTAINER (vbox1), VBOX_BORDER); @@ -204,6 +222,59 @@ void prefs_compose_writing_create_widget(PrefsPage *_page, GtkWindow *window, SET_TOGGLE_SENSITIVITY (checkbtn_autosave, spinbtn_autosave_length); SET_TOGGLE_SENSITIVITY (checkbtn_autosave, label_autosave_length); + PACK_CHECK_BUTTON (vbox1, checkbtn_compose_with_format, _("Use format when composing new messages")); + + PACK_FRAME (vbox1, frame_format, _("New message format")); + + vbox_format = gtk_vbox_new (FALSE, VSPACING_NARROW); + gtk_widget_show (vbox_format); + gtk_container_add (GTK_CONTAINER (frame_format), vbox_format); + gtk_container_set_border_width (GTK_CONTAINER (vbox_format), 8); + + hbox_format = gtk_hbox_new (FALSE, 8); + gtk_widget_show (hbox_format); + gtk_box_pack_start (GTK_BOX (vbox_format), hbox_format, FALSE, FALSE, 0); + + label_subject = gtk_label_new (_("Subject")); + gtk_widget_show (label_subject); + gtk_box_pack_start (GTK_BOX (hbox_format), label_subject, FALSE, FALSE, 0); + + entry_subject = gtk_entry_new (); + gtk_widget_show (entry_subject); + gtk_box_pack_start (GTK_BOX (hbox_format), entry_subject, TRUE, TRUE, 0); + gtk_widget_set_size_request (entry_subject, 100, -1); + + scrolledwin_format = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwin_format); + gtk_box_pack_start (GTK_BOX (vbox_format), scrolledwin_format, + TRUE, TRUE, 0); + gtk_scrolled_window_set_policy + (GTK_SCROLLED_WINDOW (scrolledwin_format), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type + (GTK_SCROLLED_WINDOW (scrolledwin_format), GTK_SHADOW_IN); + + text_format = gtk_text_view_new (); + gtk_widget_show (text_format); + gtk_container_add(GTK_CONTAINER(scrolledwin_format), text_format); + gtk_text_view_set_editable (GTK_TEXT_VIEW (text_format), TRUE); + gtk_widget_set_size_request(text_format, -1, 100); + + hbox_formatdesc = gtk_hbox_new (FALSE, 32); + gtk_widget_show (hbox_formatdesc); + gtk_box_pack_start (GTK_BOX (vbox_format), hbox_formatdesc, FALSE, FALSE, 0); + +#if GTK_CHECK_VERSION(2, 8, 0) + btn_formatdesc = gtk_button_new_from_stock(GTK_STOCK_INFO); +#else + btn_formatdesc = + gtk_button_new_with_label (_(" Description of symbols... ")); +#endif + gtk_widget_show (btn_formatdesc); + gtk_box_pack_start (GTK_BOX (hbox_formatdesc), btn_formatdesc, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(btn_formatdesc), "clicked", + G_CALLBACK(quote_fmt_quote_description), GTK_WIDGET(window)); + prefs_writing->checkbtn_autoextedit = checkbtn_autoextedit; prefs_writing->checkbtn_reply_account_autosel = checkbtn_reply_account_autosel; @@ -223,6 +294,11 @@ void prefs_compose_writing_create_widget(PrefsPage *_page, GtkWindow *window, prefs_writing->optmenu_dnd_insert_or_attach = optmenu_dnd_insert_or_attach; + prefs_writing->checkbtn_compose_with_format + = checkbtn_compose_with_format; + prefs_writing->entry_subject = entry_subject; + prefs_writing->text_format = text_format; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_writing->checkbtn_autoextedit), prefs_common.auto_exteditor); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_writing->checkbtn_forward_as_attachment), @@ -246,6 +322,11 @@ void prefs_compose_writing_create_widget(PrefsPage *_page, GtkWindow *window, gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu_dnd_insert_or_attach), prefs_common.compose_dnd_mode); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_writing->checkbtn_compose_with_format), + prefs_common.compose_with_format); + pref_set_entry_from_pref(GTK_ENTRY(prefs_writing->entry_subject), prefs_common.compose_subject_format); + pref_set_textview_from_pref(GTK_TEXT_VIEW(prefs_writing->text_format), prefs_common.compose_body_format); + prefs_writing->page.widget = vbox1; } @@ -281,6 +362,17 @@ void prefs_compose_writing_save(PrefsPage *_page) menuitem = gtk_menu_get_active(GTK_MENU(menu)); prefs_common.compose_dnd_mode = GPOINTER_TO_INT (g_object_get_data(G_OBJECT(menuitem), MENU_VAL_ID)); + + prefs_common.compose_with_format = + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_compose_with_format)); + prefs_common.compose_subject_format = pref_get_pref_from_entry( + GTK_ENTRY(page->entry_subject)); + if (!prefs_template_string_is_valid(prefs_common.compose_subject_format)) + alertpanel_error(_("New message subject format error.")); + prefs_common.compose_body_format = pref_get_pref_from_textview( + GTK_TEXT_VIEW(page->text_format)); + if (!prefs_template_string_is_valid(prefs_common.compose_body_format)) + alertpanel_error(_("New message body format error.")); } static void prefs_compose_writing_destroy_widget(PrefsPage *_page) -- 2.25.1