2006-11-09 [wwp] 2.6.0cvs21
authorTristan Chabredier <wwp@claws-mail.org>
Thu, 9 Nov 2006 15:15:17 +0000 (15:15 +0000)
committerTristan Chabredier <wwp@claws-mail.org>
Thu, 9 Nov 2006 15:15:17 +0000 (15:15 +0000)
* 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
PATCHSETS
configure.ac
src/compose.c
src/prefs_common.c
src/prefs_common.h
src/prefs_compose_writing.c

index 31bbc75503eb16c980018412e4cf8b28dfef52ef..9791c778474f9aed92d2fa6fefb19f7f4c204946 100644 (file)
--- 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
index 6b2af3ee13374309d42ecb07f0839155d3925a3a..9019c0a9120e7cc15b97cd2225a5b46532715404 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( 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
index e709be67eccbb6e35211d2e729e926c7e5624831..6bd4aab64bc60aadf4bb089df45c6d46725efddc 100644 (file)
@@ -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=
 
index 5639fc9527fa934c9101084fe5a223c76e530801..a0f14802a7a2a55a0d3643246032444172c84e03 100644 (file)
@@ -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.
  */
index ab897ca70a40e8d2e0f2513a037d6c9f7d77d660..c304b5a4b23879259b12c8017312281eb0642936 100644 (file)
@@ -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:"";
 }
index 506679808e512cb1d9990c214901a717db7ede79..de239696345ed7f15e1ae129225dd25cadd93501 100644 (file)
@@ -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__ */
index c6e36a70e465f44fa5afa413c057abb6befdbdcd..9aadf1618cfc33c45a9529a16517b89c145257cd 100644 (file)
 
 #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)