sync with sylpheed 0.6.5cvs14
[claws.git] / src / compose.c
index 8c745c374795fc23f8021fe1b5467ef6d102f8f2..94ff07815f8f89170b2492e23db505d434c70464 100644 (file)
@@ -123,6 +123,10 @@ static GdkColor quote_color = {0, 0, 0, 0xbfff};
 
 static GList *compose_list = NULL;
 
+Compose *compose_generic_new                   (PrefsAccount   *account,
+                                                const gchar    *to,
+                                                FolderItem     *item);
+
 static Compose *compose_create                 (PrefsAccount   *account,
                                                 ComposeMode     mode);
 static void compose_toolbar_create             (Compose        *compose,
@@ -130,8 +134,12 @@ static void compose_toolbar_create         (Compose        *compose,
 static GtkWidget *compose_account_option_menu_create
                                                (Compose        *compose);
 static void compose_set_template_menu          (Compose        *compose);
+static void compose_template_apply             (Compose        *compose,
+                                                Template       *tmpl);
 static void compose_destroy                    (Compose        *compose);
 
+static void compose_entries_set                        (Compose        *compose,
+                                                const gchar    *mailto);
 static gint compose_parse_header               (Compose        *compose,
                                                 MsgInfo        *msginfo);
 static gchar *compose_parse_references         (const gchar    *ref,
@@ -250,8 +258,9 @@ static void toolbar_linewrap_cb             (GtkWidget      *widget,
 static void toolbar_address_cb         (GtkWidget      *widget,
                                         gpointer        data);
 
+static void select_account             (Compose        *compose,
+                                        PrefsAccount   *ac);
 
-static void select_account(Compose * compose, PrefsAccount * ac);
 static void account_activated          (GtkMenuItem    *menuitem,
                                         gpointer        data);
 
@@ -324,6 +333,7 @@ static void compose_key_press_cb    (GtkWidget      *widget,
                                         Compose        *compose);
 #endif
 
+#if 0
 static void compose_toggle_to_cb       (gpointer        data,
                                         guint           action,
                                         GtkWidget      *widget);
@@ -342,6 +352,7 @@ static void compose_toggle_followupto_cb(gpointer    data,
 static void compose_toggle_attach_cb   (gpointer        data,
                                         guint           action,
                                         GtkWidget      *widget);
+#endif
 static void compose_toggle_ruler_cb    (gpointer        data,
                                         guint           action,
                                         GtkWidget      *widget);
@@ -373,6 +384,7 @@ static void compose_insert_drag_received_cb (GtkWidget              *widget,
                                             guint               time,
                                             gpointer            user_data);
 
+#if 0
 static void to_activated               (GtkWidget      *widget,
                                         Compose        *compose);
 static void newsgroups_activated       (GtkWidget      *widget,
@@ -387,23 +399,21 @@ static void replyto_activated             (GtkWidget      *widget,
                                         Compose        *compose);
 static void followupto_activated       (GtkWidget      *widget,
                                         Compose        *compose);
-static void compose_attach_parts(Compose * compose,
-                                MsgInfo * msginfo);
+#endif
+
+static void compose_attach_parts       (Compose        *compose,
+                                        MsgInfo        *msginfo);
 
 static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
                                  gboolean to_all,
                                  gboolean ignore_replyto,
                                  gboolean followup_and_reply_to);
 
-void compose_headerentry_changed_cb    (GtkWidget *entry,
-                                        compose_headerentry *headerentry);
-void compose_headerentry_key_press_event_cb    (GtkWidget *entry,
-                                                GdkEventKey *event,
-                                                compose_headerentry *headerentry);
-
-Compose * compose_generic_new (PrefsAccount    *account,
-                              const gchar      *to,
-                              FolderItem       *item);
+void compose_headerentry_changed_cb       (GtkWidget          *entry,
+                                           ComposeHeaderEntry *headerentry);
+void compose_headerentry_key_press_event_cb(GtkWidget         *entry,
+                                           GdkEventKey        *event,
+                                           ComposeHeaderEntry *headerentry);
 
 static GtkItemFactoryEntry compose_popup_entries[] =
 {
@@ -475,15 +485,15 @@ static GtkTargetEntry compose_mime_types[] =
        {"text/uri-list", 0, 0}
 };
 
-Compose * compose_new(PrefsAccount *account)
+Compose *compose_new(PrefsAccount *account)
 {
        return compose_generic_new(account, NULL, NULL);
 }
 
-Compose * compose_bounce(PrefsAccount *account, MsgInfo *msginfo)
+Compose *compose_bounce(PrefsAccount *account, MsgInfo *msginfo)
 {
-       Compose * c;
-       gchar * filename;
+       Compose *c;
+       gchar *filename;
        GtkItemFactory *ifactory;
        
        c = compose_generic_new(account, NULL, NULL);
@@ -532,97 +542,17 @@ Compose * compose_bounce(PrefsAccount *account, MsgInfo *msginfo)
        return c;
 }
 
-Compose * compose_new_with_recipient(PrefsAccount *account, const gchar *to)
+Compose *compose_new_with_recipient(PrefsAccount *account, const gchar *mailto)
 {
-       return compose_generic_new(account, to, NULL);
+       return compose_generic_new(account, mailto, NULL);
 }
 
-Compose * compose_new_with_folderitem(PrefsAccount *account, FolderItem *item)
+Compose *compose_new_with_folderitem(PrefsAccount *account, FolderItem *item)
 {
        return compose_generic_new(account, NULL, item);
 }
 
-static void set_compose_entries(Compose * compose, const gchar * mailto)
-{
-       gchar * subject = NULL;
-       gchar * to = NULL;
-       gchar * cc = NULL;
-       gchar * bcc = NULL;
-       gchar * body = NULL;
-       gchar * p;
-       gchar * tmp_mailto;
-       gchar * cur;
-       
-       Xstrdup_a(tmp_mailto, mailto, return);
-
-       cur = tmp_mailto;
-
-       p = strchr(cur, '?');
-       if (p != NULL) {
-               * p = 0;
-               cur = p + 1;
-       }
-       to = tmp_mailto;
-
-       while (p) {
-               char *field, *value;
-               
-               field = cur;
-
-               p = strchr(cur, '=');
-               if (p == NULL)
-                       break;
-               * p = 0;
-               cur = p + 1;
-
-               value = cur;
-
-               p = strchr(cur, '&');
-               if (p != NULL) {
-                       * p = 0;
-                       cur = p + 1;
-               }
-
-               if (value) {
-                       if (g_strcasecmp(field, "subject")==0) {
-                               Xstrdup_a(subject, value, );
-                               if (subject != NULL)
-                                       decode_uri(subject, value);
-                       }
-                       else if (g_strcasecmp(field, "cc")==0)
-                               cc = value;
-                       else if (g_strcasecmp(field, "bcc")==0)
-                               bcc = value;
-                       else if (g_strcasecmp(field, "body")==0) {
-                               Xstrdup_a(body, value, );
-                               if (body != NULL)
-                                       decode_uri(body, value);
-                       }
-               }
-       }                       
-
-       if (to) {
-               compose_entry_append(compose, to, COMPOSE_TO);
-               /*
-               gtk_widget_grab_focus(compose->text);
-               */
-       }
-
-       if (subject)
-               gtk_entry_set_text(GTK_ENTRY(compose->subject_entry), subject);
-       if (cc)
-               compose_entry_append(compose, cc, COMPOSE_CC);
-       if (bcc)
-               compose_entry_append(compose, bcc, COMPOSE_BCC);
-       if (body) {
-               gtk_stext_insert(GTK_STEXT(compose->text),
-                                NULL, NULL, NULL, body, -1);
-               gtk_stext_insert(GTK_STEXT(compose->text),
-                                NULL, NULL, NULL, "\n", 1);
-       }
-}      
-
-Compose * compose_generic_new(PrefsAccount *account, const gchar *to, FolderItem *item)
+Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderItem *item)
 {
        Compose *compose;
 
@@ -641,8 +571,8 @@ Compose * compose_generic_new(PrefsAccount *account, const gchar *to, FolderItem
        gtk_stext_set_point(GTK_STEXT(compose->text), 0);
 
        if (account->protocol != A_NNTP) {
-               if (to) {
-                       set_compose_entries(compose, to);
+               if (mailto) {
+                       compose_entries_set(compose, mailto);
 
                } else if(item && item->prefs->enable_default_to) {
                        compose_entry_append(compose, item->prefs->default_to, COMPOSE_TO);
@@ -654,8 +584,8 @@ Compose * compose_generic_new(PrefsAccount *account, const gchar *to, FolderItem
                        menu_set_toggle(ifactory, "/Message/Request Return Receipt", TRUE);
                }
        } else {
-               if (to) {
-                       compose_entry_append(compose, to, COMPOSE_NEWSGROUPS);
+               if (mailto) {
+                       compose_entry_append(compose, mailto, COMPOSE_NEWSGROUPS);
                }
        }
        gtk_widget_grab_focus(compose->subject_entry);
@@ -675,7 +605,7 @@ msginfo->folder->folder->change_flags(msginfo->folder->folder, \
 }
 
 /*
-Compose * compose_new_followup_and_replyto(PrefsAccount *account,
+Compose *compose_new_followup_and_replyto(PrefsAccount *account,
                                           const gchar *followupto, gchar * to)
 {
        Compose *compose;
@@ -815,9 +745,8 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
        gtk_editable_set_position(GTK_EDITABLE(text), 0);
        gtk_stext_set_point(text, 0);
 
-       if (quote && prefs_common.linewrap_quote) {
+       if (quote && prefs_common.linewrap_quote)
                compose_wrap_line_all(compose);
-       }
 
        gtk_stext_thaw(text);
        gtk_widget_grab_focus(compose->text);
@@ -838,20 +767,20 @@ static gchar *procmime_get_file_name(MimeInfo *mimeinfo)
                : mimeinfo->name ? mimeinfo->name : NULL;
 
        if (MIME_TEXT_HTML == mimeinfo->mime_type && base == NULL){
-               filename = g_strdup_printf("%s%smimetmp%i.html",
+               filename = g_strdup_printf("%s%smimetmp.%08x.html",
                                           get_mime_tmp_dir(),
                                           G_DIR_SEPARATOR_S,
-                                          mimeinfo);
+                                          (gint)mimeinfo);
                return filename;
        }
        else {
                base = base ? base : "";
                base = g_basename(base);
                if (*base == '\0') {
-                       filename = g_strdup_printf("%s%smimetmp%i",
+                       filename = g_strdup_printf("%s%smimetmp.%08x",
                                                   get_mime_tmp_dir(),
                                                   G_DIR_SEPARATOR_S,
-                                                  mimeinfo);
+                                                  (gint)mimeinfo);
                        return filename;
                }
        }
@@ -862,11 +791,11 @@ static gchar *procmime_get_file_name(MimeInfo *mimeinfo)
        return filename;
 }
 
-static gchar * mime_extract_file(gchar * source, MimeInfo *partinfo)
+static gchar *mime_extract_file(gchar *source, MimeInfo *partinfo)
 {
        gchar *filename;
 
-       if (!partinfo) return;
+       if (!partinfo) return NULL;
 
        filename = procmime_get_file_name(partinfo);
 
@@ -877,10 +806,8 @@ static gchar * mime_extract_file(gchar * source, MimeInfo *partinfo)
        return filename;
 }
 
-static void compose_attach_parts(Compose * compose,
-                                MsgInfo * msginfo)
+static void compose_attach_parts(Compose *compose, MsgInfo *msginfo)
 {
-
        FILE *fp;
        gchar *file;
        MimeInfo *mimeinfo;
@@ -891,8 +818,8 @@ static void compose_attach_parts(Compose * compose,
        gchar buf[BUFFSIZE];
        glong fpos, prev_fpos;
        gint npart;
-       gchar * source;
-       gchar * filename;
+       gchar *source;
+       gchar *filename;
 
        g_return_if_fail(msginfo != NULL);
        
@@ -1049,7 +976,7 @@ if (msginfo->var && *msginfo->var) { \
        gtk_stext_insert(text, NULL, NULL, NULL, "\n", 1); \
 }
 
-Compose *compose_forward(PrefsAccount * account, MsgInfo *msginfo,
+Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
                         gboolean as_attach)
 {
        Compose *compose;
@@ -1062,7 +989,7 @@ Compose *compose_forward(PrefsAccount * account, MsgInfo *msginfo,
        account = msginfo->folder->folder->account;
         if (!account && msginfo->to && prefs_common.forward_account_autosel) {
                gchar *to;
-               Xstrdup_a(to, msginfo->to, return);
+               Xstrdup_a(to, msginfo->to, return NULL);
                extract_address(to);
                account = account_find_from_address(to);
        }
@@ -1146,8 +1073,7 @@ Compose *compose_forward(PrefsAccount * account, MsgInfo *msginfo,
 
 #undef INSERT_FW_HEADER
 
-Compose * compose_forward_multiple(PrefsAccount * account, 
-                         GSList *msginfo_list) 
+Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_list)
 {
        Compose *compose;
        GtkSText *text;
@@ -1318,6 +1244,75 @@ void compose_entry_append(Compose *compose, const gchar *address,
        compose_add_header_entry(compose, header, (gchar *)address);
 }
 
+static void compose_entries_set(Compose *compose, const gchar *mailto)
+{
+       gchar *subject = NULL;
+       gchar *to = NULL;
+       gchar *cc = NULL;
+       gchar *bcc = NULL;
+       gchar *body = NULL;
+       gchar *p;
+       gchar *tmp_mailto;
+
+       Xstrdup_a(tmp_mailto, mailto, return);
+
+       to = tmp_mailto;
+
+       p = strchr(tmp_mailto, '?');
+       if (p) {
+               *p = '\0';
+               p++;
+       }
+
+       while (p) {
+               gchar *field, *value;
+
+               field = p;
+
+               p = strchr(p, '=');
+               if (!p) break;
+               *p = '\0';
+               p++;
+
+               value = p;
+
+               p = strchr(p, '&');
+               if (p) {
+                       *p = '\0';
+                       p++;
+               }
+
+               if (*value == '\0') continue;
+
+               if (!g_strcasecmp(field, "subject")) {
+                       Xalloca(subject, strlen(value) + 1, return);
+                       decode_uri(subject, value);
+               } else if (!g_strcasecmp(field, "cc")) {
+                       cc = value;
+               } else if (!g_strcasecmp(field, "bcc")) {
+                       bcc = value;
+               } else if (!g_strcasecmp(field, "body")) {
+                       Xalloca(body, strlen(value) + 1, return);
+                       decode_uri(body, value);
+               }
+       }
+
+       if (to)
+               compose_entry_append(compose, to, COMPOSE_TO);
+       if (subject)
+               gtk_entry_set_text(GTK_ENTRY(compose->subject_entry), subject);
+       if (cc)
+               compose_entry_append(compose, cc, COMPOSE_CC);
+       if (bcc)
+               compose_entry_append(compose, bcc, COMPOSE_BCC);
+       if (body) {
+               gtk_stext_insert(GTK_STEXT(compose->text),
+                               NULL, NULL, NULL, body, -1);
+               gtk_stext_insert(GTK_STEXT(compose->text),
+                               NULL, NULL, NULL, "\n", 1);
+       }
+}
+
 static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
 {
        static HeaderEntry hentry[] = {{"Reply-To:",       NULL, TRUE},
@@ -1362,7 +1357,7 @@ static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
        }
        if (hentry[H_X_MAILING_LIST].body != NULL) {
                /* this is good enough to parse debian-devel */
-               char * buf = g_malloc(strlen(hentry[H_X_MAILING_LIST].body) + 1);
+               gchar *buf = g_malloc(strlen(hentry[H_X_MAILING_LIST].body) + 1);
                g_return_val_if_fail(buf != NULL, -1 );
                if (1 == sscanf(hentry[H_X_MAILING_LIST].body, "<%[^>]>", buf))
                        compose->mailinglist = g_strdup(buf);
@@ -1372,7 +1367,7 @@ static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
        }
        if (hentry[H_X_BEENTHERE].body != NULL) {
                /* this is good enough to parse the sylpheed-claws lists */
-               char * buf = g_malloc(strlen(hentry[H_X_BEENTHERE].body) + 1);
+               gchar *buf = g_malloc(strlen(hentry[H_X_BEENTHERE].body) + 1);
                g_return_val_if_fail(buf != NULL, -1 );
                if (1 == sscanf(hentry[H_X_BEENTHERE].body, "%[^>]", buf))
                        compose->mailinglist = g_strdup(buf);
@@ -1550,24 +1545,19 @@ static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
                                     ? compose->replyto
                                     : msginfo->from ? msginfo->from : ""),
                                     COMPOSE_TO);
-       if (compose->account->protocol == A_NNTP)
+       if (compose->account->protocol == A_NNTP) {
                if (ignore_replyto)
-                       compose_entry_append(compose,
-                                            msginfo->from ? msginfo->from : "",
-                                            COMPOSE_TO);
+                       compose_entry_append
+                               (compose, msginfo->from ? msginfo->from : "",
+                                COMPOSE_TO);
                else
-                       compose_entry_append(compose,
-                                            compose->followup_to ? compose->followup_to
-                                            : compose->newsgroups ? compose->newsgroups
-                                            : "",
-                                            COMPOSE_NEWSGROUPS);
-       /*
-               compose_entry_append(compose,
-                                    compose->followup_to ? compose->followup_to
-                                    : compose->newsgroups ? compose->newsgroups
-                                    : "",
-                                    COMPOSE_NEWSGROUPS);
-       */
+                       compose_entry_append
+                               (compose,
+                                compose->followup_to ? compose->followup_to
+                                : compose->newsgroups ? compose->newsgroups
+                                : "",
+                                COMPOSE_NEWSGROUPS);
+       }
 
        if (msginfo->subject && *msginfo->subject) {
                gchar *buf, *buf2, *p;
@@ -2076,11 +2066,11 @@ compose_end:
 }
 
 /* return indent length */
-static guint get_indent_length(GtkSText *text, guint start_pos,
-                              guint text_len) {
+static guint get_indent_length(GtkSText *text, guint start_pos, guint text_len)
+{
        gint indent_len = 0;
        gint i, ch_len;
-       gchar cbuf[MB_CUR_MAX];
+       gchar cbuf[MB_LEN_MAX];
 
        for (i = start_pos; i < text_len; i++) {
                if (text->use_wchar)
@@ -2102,11 +2092,11 @@ static guint get_indent_length(GtkSText *text, guint start_pos,
        return indent_len;
 }
 
-/* insert quotation string when line was wrapped, we know these
-   are single byte characters */
+/* insert quotation string when line was wrapped */
 static guint ins_quote(GtkSText *text, guint quote_len, guint indent_len,
                       guint prev_line_pos, guint text_len,
-                      gchar *quote_fmt) {
+                      gchar *quote_fmt)
+{
        guint i, ins_len;
        gchar ch;
 
@@ -2130,18 +2120,17 @@ static guint ins_quote(GtkSText *text, guint quote_len, guint indent_len,
 /* Darko: used when I debug wrapping */
 void dump_text(GtkSText *text, int pos, int tlen, int breakoncr)
 {
-    int i;
-    char ch;
+       int i;
+       char ch;
 
-    printf("%d [", pos);
-    for (i = pos; i < tlen; i++)
-    {
-        ch = GTK_STEXT_INDEX(text, i);
-        if (breakoncr && ch == '\n')
-            break;
-        printf("%c", ch);
-    }
-    printf("]\n");
+       printf("%d [", pos);
+       for (i = pos; i < tlen; i++) {
+               ch = GTK_STEXT_INDEX(text, i);
+               if (breakoncr && ch == '\n')
+                       break;
+               printf("%c", ch);
+       }
+       printf("]\n");
 }
 #endif
 
@@ -2162,18 +2151,18 @@ static void compose_wrap_line_all(Compose *compose)
        gtk_stext_freeze(text);
 
        /* make text buffer contiguous */
-       gtk_stext_compact_buffer(text);
+       /* gtk_stext_compact_buffer(text); */
 
        tlen = gtk_stext_get_length(text);
 
        for (; cur_pos < tlen; cur_pos++) {
                /* mark position of new line - needed for quotation wrap */
                if (linewrap_quote && is_new_line) {
-                       qlen = gtkstext_str_strcmp(text, cur_pos, tlen, qfmt);
+                       qlen = gtkut_text_str_compare
+                               (text, cur_pos, tlen, qfmt);
                        is_new_line = 0;
-                       if (qlen) {
+                       if (qlen)
                                i_len = get_indent_length(text, cur_pos, tlen);
-                       }
                        else
                                i_len = 0;
                        p_pos = cur_pos;
@@ -2222,8 +2211,8 @@ static void compose_wrap_line_all(Compose *compose)
                        /* if it's just quotation + newline skip it */
                        if (i_len && (cur_pos + 1 < tlen)) {
                                /* check if text at new line matches indent */
-                               ilen =  gtkstext_strncmp(text, cur_pos + 1,
-                                                        p_pos, i_len, tlen);
+                               ilen =  gtkut_text_str_compare_n
+                                       (text, cur_pos + 1, p_pos, i_len, tlen);
                                if (cur_pos + ilen < tlen) {
                                        if (text->use_wchar)
                                                clen = wctomb(cb, (wchar_t)GTK_STEXT_INDEX(text, cur_pos + ilen + 1));
@@ -2252,20 +2241,19 @@ static void compose_wrap_line_all(Compose *compose)
                                /* if text starts with quote fmt or with
                                   indent string, delete them */
                                if (i_len) {
-                                       ilen =  gtkstext_strncmp(text, cur_pos,
-                                                                p_pos, i_len,
-                                                                tlen);
+                                       ilen =  gtkut_text_str_compare_n
+                                               (text, cur_pos, p_pos, i_len,
+                                                tlen);
                                        if (ilen) {
                                                gtk_stext_forward_delete(text,
                                                                         ilen);
                                                tlen -= ilen;
                                        }
-                               }
-                               else if (qlen) {
-                                       if (gtkstext_str_strcmp(text, cur_pos,
-                                                               tlen, qfmt)) {
-                                               gtk_stext_forward_delete(text,
-                                                                qlen);
+                               } else if (qlen) {
+                                       if (gtkut_text_str_compare
+                                           (text, cur_pos, tlen, qfmt)) {
+                                               gtk_stext_forward_delete
+                                                       (text, qlen);
                                                tlen -= qlen;
                                        }
                                }
@@ -2282,8 +2270,8 @@ static void compose_wrap_line_all(Compose *compose)
                                if ((cur_pos != line_pos) &&
                                    ((clen > 1) || isalnum(cb[0]))) {
                                        gtk_stext_insert(text, NULL, NULL,
-                                                        NULL, " ", 1);
-                                       gtk_stext_compact_buffer(text);
+                                                       NULL, " ", 1);
+                                       /* gtk_text_compact_buffer(text); */
                                        tlen++;
                                }
 
@@ -2332,7 +2320,8 @@ static void compose_wrap_line_all(Compose *compose)
 #endif
                        /* force wrapping if it is one long word but not URL */
                        if (p_pos + i_len == line_pos)
-                               if (!is_url_string(text, line_pos, tlen))
+                               if (!gtkut_text_is_uri_string
+                                   (text, line_pos, tlen))
                                        line_pos = cur_pos - 1;
 #ifdef WRAP_DEBUG
                        printf("new line_pos=%d\n", line_pos);
@@ -2347,7 +2336,8 @@ static void compose_wrap_line_all(Compose *compose)
                        }
                         if (clen == 1 && isspace(*cbuf)) {
                                if (p_pos + i_len != line_pos ||
-                                   !is_url_string(text, line_pos, tlen)) {
+                                   !gtkut_text_is_uri_string
+                                       (text, line_pos, tlen)) {
                                        gtk_stext_set_point(text, line_pos);
                                        gtk_stext_backward_delete(text, 1);
                                        tlen--;
@@ -2360,7 +2350,7 @@ static void compose_wrap_line_all(Compose *compose)
 
                        /* if it is URL at beginning of line don't wrap */
                        if (p_pos + i_len == line_pos &&
-                            is_url_string(text, line_pos, tlen)) {
+                           gtkut_text_is_uri_string(text, line_pos, tlen)) {
 #ifdef WRAP_DEBUG
                                printf("found URL at ");
                                dump_text(text, line_pos, tlen, 1);
@@ -2371,7 +2361,7 @@ static void compose_wrap_line_all(Compose *compose)
                        /* insert CR */
                        gtk_stext_set_point(text, line_pos);
                        gtk_stext_insert(text, NULL, NULL, NULL, "\n", 1);
-                       gtk_stext_compact_buffer(text);
+                       /* gtk_stext_compact_buffer(text); */
                        tlen++;
                        cur_pos++;
                        line_pos++;
@@ -2385,19 +2375,16 @@ static void compose_wrap_line_all(Compose *compose)
                        /* should we insert quotation ? */
                        if (linewrap_quote && qlen) {
                                /* only if line is not already quoted  */
-                               if (!gtkstext_str_strcmp(text, line_pos,
-                                                        tlen, qfmt)) {
+                               if (!gtkut_text_str_compare
+                                       (text, line_pos, tlen, qfmt)) {
                                        guint ins_len;
 
                                        if (line_pos - p_pos > i_len) {
-                                               ins_len = ins_quote(text,
-                                                                   qlen,
-                                                                   i_len,
-                                                                   p_pos,
-                                                                   tlen,
-                                                                   qfmt);
-
-                                               gtk_stext_compact_buffer(text);
+                                               ins_len = ins_quote
+                                                       (text, qlen, i_len,
+                                                        p_pos, tlen, qfmt);
+
+                                               /* gtk_stext_compact_buffer(text); */
                                                tlen += ins_len;
                                        }
 
@@ -2428,6 +2415,86 @@ static void compose_wrap_line_all(Compose *compose)
        gtk_stext_thaw(text);
 }
 
+#if 0
+static void compose_wrap_line_all(Compose *compose)
+{
+       GtkText *text = GTK_STEXT(compose->text);
+       guint text_len;
+       guint line_pos = 0, cur_pos = 0;
+       gint line_len = 0, cur_len = 0;
+       gint ch_len;
+       gchar cbuf[MB_LEN_MAX];
+
+       gtk_stext_freeze(text);
+
+       text_len = gtk_stext_get_length(text);
+
+       for (; cur_pos < text_len; cur_pos++) {
+               if (text->use_wchar)
+                       ch_len = wctomb
+                               (cbuf, (wchar_t)GTK_STEXT_INDEX(text, cur_pos));
+               else {
+                       cbuf[0] = GTK_STEXT_INDEX(text, cur_pos);
+                       ch_len = 1;
+               }
+
+               if (ch_len == 1 && *cbuf == '\n') {
+                       line_pos = cur_pos + 1;
+                       line_len = cur_len = 0;
+                       continue;
+               }
+
+               if (ch_len < 0) {
+                       cbuf[0] = '\0';
+                       ch_len = 1;
+               }
+
+               if (ch_len == 1 && isspace(*cbuf)) {
+                       line_pos = cur_pos + 1;
+                       line_len = cur_len + ch_len;
+               }
+
+               if (cur_len + ch_len > prefs_common.linewrap_len &&
+                   line_len > 0) {
+                       gint tlen;
+
+                       if (text->use_wchar)
+                               tlen = wctomb(cbuf, (wchar_t)GTK_STEXT_INDEX(text, line_pos - 1));
+                       else {
+                               cbuf[0] = GTK_STEXT_INDEX(text, line_pos - 1);
+                               tlen = 1;
+                       }
+                       if (tlen == 1 && isspace(*cbuf)) {
+                               gtk_stext_set_point(text, line_pos);
+                               gtk_stext_backward_delete(text, 1);
+                               text_len--;
+                               cur_pos--;
+                               line_pos--;
+                               cur_len--;
+                               line_len--;
+                       }
+
+                       gtk_stext_set_point(text, line_pos);
+                       gtk_stext_insert(text, NULL, NULL, NULL, "\n", 1);
+                       text_len++;
+                       cur_pos++;
+                       line_pos++;
+                       cur_len = cur_len - line_len + ch_len;
+                       line_len = 0;
+                       continue;
+               }
+
+               if (ch_len > 1) {
+                       line_pos = cur_pos + 1;
+                       line_len = cur_len + ch_len;
+               }
+               cur_len += ch_len;
+       }
+
+       gtk_stext_thaw(text);
+}
+#endif
+
 static void compose_set_title(Compose *compose)
 {
        gchar *str;
@@ -2490,8 +2557,8 @@ gboolean compose_check_for_valid_recipient(Compose *compose) {
        for(list = compose->header_list; list; list = list->next) {
                gchar *header;
                gchar *entry;
-               header = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(((compose_headerentry *)list->data)->combo)->entry));
-               entry = gtk_editable_get_chars(GTK_EDITABLE(((compose_headerentry *)list->data)->entry), 0, -1);
+               header = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(((ComposeHeaderEntry *)list->data)->combo)->entry));
+               entry = gtk_editable_get_chars(GTK_EDITABLE(((ComposeHeaderEntry *)list->data)->entry), 0, -1);
                g_strstrip(entry);
                if(entry[0] != '\0') {
                        for(strptr = recipient_headers_mail; *strptr != NULL; strptr++) {
@@ -2521,7 +2588,7 @@ gint compose_send(Compose *compose)
        val = compose_queue(compose, &msgnum, &folder);
        if (val) {
                alertpanel_error(_("Could not queue message for sending"));
-               return;
+               return -1;
        }
        
        val = procmsg_send_message_queue(folder_item_fetch_msg(folder, msgnum));
@@ -2658,10 +2725,6 @@ static gboolean compose_use_attach(Compose *compose) {
     return(gtk_clist_get_row_data(GTK_CLIST(compose->attach_clist), 0) != NULL);
 }
 
-
-
-
-
 static gint compose_bounce_write_headers_from_headerlist(Compose *compose, 
                                                         FILE *fp)
 {
@@ -2669,11 +2732,11 @@ static gint compose_bounce_write_headers_from_headerlist(Compose *compose,
        gchar *str;
        gboolean first_address;
        GSList *list;
-       compose_headerentry *headerentry;
-       gchar * headerentryname;
-       gchar * header_w_colon;
-       gchar * cc_hdr;
-       gchar * to_hdr;
+       ComposeHeaderEntry *headerentry;
+       gchar *headerentryname;
+       gchar *header_w_colon;
+       gchar *cc_hdr;
+       gchar *to_hdr;
 
        debug_print(_("Writing bounce header\n"));
 
@@ -2684,7 +2747,7 @@ static gint compose_bounce_write_headers_from_headerlist(Compose *compose,
        
        first_address = TRUE;
        for(list = compose->header_list; list; list = list->next) {
-               headerentry = ((compose_headerentry *)list->data);
+               headerentry = ((ComposeHeaderEntry *)list->data);
                headerentryname = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(headerentry->combo)->entry));
 
                if(g_strcasecmp(headerentryname, cc_hdr) == 0 
@@ -2706,14 +2769,13 @@ static gint compose_bounce_write_headers_from_headerlist(Compose *compose,
                        }
                }
        }
-       //      if(!first_address) {
+       /* if(!first_address) { */
        fprintf(fp, "\n");
-               //      }
+       /* } */
 
        return(0);
 }
 
-
 static gint compose_bounce_write_headers(Compose *compose, FILE *fp)
 {
        gchar buf[BUFFSIZE];
@@ -2772,6 +2834,12 @@ static gint compose_bounce_write_to_file(Compose *compose, const gchar *file)
        }
 
        while (procheader_get_unfolded_line(buf, sizeof(buf), fp)) {
+               /* should filter returnpath, delivered-to */
+               if ((g_strncasecmp(buf, "Return-Path:",
+                                  strlen("Return-Path:")) == 0)
+                   || (g_strncasecmp(buf, "Delivered-To:",
+                                     strlen("Delivered-To:")) == 0))
+                       continue;
                if (fputs(buf, fdest) == -1)
                        goto error;
                if (fputs("\n", fdest) == -1)
@@ -3052,7 +3120,6 @@ static gint compose_queue(Compose *compose, gint *msgnum, FolderItem **item)
                                                                        
        if (!compose->to_list && !compose->newsgroup_list) {
                g_warning(_("can't get recipient list."));
-               unlink(tmpfilename);
                lock = FALSE;
                 return -1;
         }
@@ -3062,7 +3129,7 @@ static gint compose_queue(Compose *compose, gint *msgnum, FolderItem **item)
                        
        /* write to temporary file */
        tmpfilename = g_strdup_printf("%s%cqueue.%d", g_get_tmp_dir(),
-                             G_DIR_SEPARATOR, (gint)compose);
+                                     G_DIR_SEPARATOR, (gint)compose);
        if ((fp = fopen(tmpfilename, "w")) == NULL) {
                FILE_OP_ERROR(tmpfilename, "fopen");
                g_free(tmpfilename);
@@ -3288,7 +3355,7 @@ static gint compose_write_headers_from_headerlist(Compose *compose,
        gchar *str, *header_w_colon, *trans_hdr;
        gboolean first_address;
        GSList *list;
-       compose_headerentry *headerentry;
+       ComposeHeaderEntry *headerentry;
        gchar * headerentryname;
 
        if (IS_IN_CUSTOM_HEADER(header)) {
@@ -3302,7 +3369,7 @@ static gint compose_write_headers_from_headerlist(Compose *compose,
 
        first_address = TRUE;
        for(list = compose->header_list; list; list = list->next) {
-               headerentry = ((compose_headerentry *)list->data);
+               headerentry = ((ComposeHeaderEntry *)list->data);
                headerentryname = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(headerentry->combo)->entry));
 
                if(!g_strcasecmp(trans_hdr, headerentryname)) {
@@ -3539,21 +3606,23 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
                     cur = cur->next) {
                        CustomHeader *chdr = (CustomHeader *)cur->data;
 
-                       if (strcasecmp(chdr->name, "Date")                      != 0 &&
-                           strcasecmp(chdr->name, "From")                      != 0 &&
-                           strcasecmp(chdr->name, "To")                        != 0 &&
-                           strcasecmp(chdr->name, "Sender")                    != 0 &&
-                           strcasecmp(chdr->name, "Message-Id")                != 0 &&
-                           strcasecmp(chdr->name, "In-Reply-To")               != 0 &&
-                           strcasecmp(chdr->name, "References")                != 0 &&
-                           strcasecmp(chdr->name, "Mime-Version")              != 0 &&
-                           strcasecmp(chdr->name, "Content-Type")              != 0 &&
-                           strcasecmp(chdr->name, "Content-Transfer-Encoding") != 0)
+                       if (strcasecmp(chdr->name, "Date")         != 0 &&
+                           strcasecmp(chdr->name, "From")         != 0 &&
+                           strcasecmp(chdr->name, "To")           != 0 &&
+                        /* strcasecmp(chdr->name, "Sender")       != 0 && */
+                           strcasecmp(chdr->name, "Message-Id")   != 0 &&
+                           strcasecmp(chdr->name, "In-Reply-To")  != 0 &&
+                           strcasecmp(chdr->name, "References")   != 0 &&
+                           strcasecmp(chdr->name, "Mime-Version") != 0 &&
+                           strcasecmp(chdr->name, "Content-Type") != 0 &&
+                           strcasecmp(chdr->name, "Content-Transfer-Encoding")
+                           != 0) {
                                compose_convert_header
                                        (buf, sizeof(buf),
                                         chdr->value ? chdr->value : "",
                                         strlen(chdr->name) + 2);
-                       fprintf(fp, "%s: %s\n", chdr->name, buf);
+                               fprintf(fp, "%s: %s\n", chdr->name, buf);
+                       }
                }
        }
 
@@ -3681,7 +3750,9 @@ static void compose_create_header_entry(Compose *compose) {
        GtkWidget *entry;
        GList *combo_list = NULL;
        gchar **string, *header;
-       compose_headerentry *headerentry = g_new0(compose_headerentry, 1);
+       ComposeHeaderEntry *headerentry;
+
+       headerentry = g_new0(ComposeHeaderEntry, 1);
 
        /* Combo box */
        combo = gtk_combo_new();
@@ -3729,7 +3800,7 @@ static void compose_create_header_entry(Compose *compose) {
 }
 
 static void compose_add_header_entry(Compose *compose, gchar *header, gchar *text) {
-       compose_headerentry *last_header;
+       ComposeHeaderEntry *last_header;
        
        last_header = compose->header_last;
        
@@ -4169,8 +4240,9 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        compose->vbox2         = vbox2;
 
        compose->table_vbox       = table_vbox;
-       compose->table            = table;
+       compose->table            = NULL;
 #if 0 /* NEW COMPOSE GUI */
+       compose->table            = table;
        compose->to_hbox          = to_hbox;
        compose->to_entry         = to_entry;
        compose->newsgroups_hbox  = newsgroups_hbox;
@@ -4565,29 +4637,33 @@ void compose_reflect_prefs_all(void)
        }
 }
 
-static void compose_template_apply(Compose *compose, const gchar *tmpl_str)
+static void compose_template_apply(Compose *compose, Template *tmpl)
 {
        gchar *qmark;
        gchar *parsed_str;
 
-       if (!tmpl_str) return;
+       if (!tmpl || !tmpl->value) return;
 
        gtk_stext_freeze(GTK_STEXT(compose->text));
+        
+       if (tmpl->subject)
+               gtk_entry_set_text(GTK_ENTRY(compose->subject_entry),
+                                  tmpl->subject);
 
        if (compose->replyinfo == NULL) {
                MsgInfo dummyinfo;
 
                memset(&dummyinfo, 0, sizeof(MsgInfo));
-               parsed_str = compose_quote_fmt(compose, &dummyinfo, tmpl_str,
-                                              NULL);
+               parsed_str = compose_quote_fmt(compose, &dummyinfo,
+                                              tmpl->value, NULL);
        } else {
                if (prefs_common.quotemark && *prefs_common.quotemark)
                        qmark = prefs_common.quotemark;
                else
                        qmark = "> ";
 
-               parsed_str = compose_quote_fmt(compose, compose->replyinfo, tmpl_str,
-                                              qmark);
+               parsed_str = compose_quote_fmt(compose, compose->replyinfo,
+                                              tmpl->value, qmark);
        }
 
        if (parsed_str && prefs_common.auto_sig)
@@ -5574,7 +5650,7 @@ static void compose_template_activate_cb(GtkWidget *widget, gpointer data)
        tmpl = gtk_object_get_data(GTK_OBJECT(widget), "template");
        g_return_if_fail(tmpl != NULL);
 
-       compose_template_apply(compose, tmpl->value);
+       compose_template_apply(compose, tmpl);
 }
 
 static void compose_ext_editor_cb(gpointer data, guint action,
@@ -5947,23 +6023,39 @@ static void compose_toggle_return_receipt_cb(gpointer data, guint action,
                compose->return_receipt = FALSE;
 }
 
-void compose_headerentry_key_press_event_cb(GtkWidget *entry, GdkEventKey *event, compose_headerentry *headerentry) {
-       if((g_slist_length(headerentry->compose->header_list) > 0) &&
+void compose_headerentry_key_press_event_cb(GtkWidget *entry,
+                                           GdkEventKey *event,
+                                           ComposeHeaderEntry *headerentry)
+{
+       if ((g_slist_length(headerentry->compose->header_list) > 0) &&
            ((headerentry->headernum + 1) != headerentry->compose->header_nextrow) &&
            !(event->state & GDK_MODIFIER_MASK) &&
            (event->keyval == GDK_BackSpace) &&
            (strlen(gtk_entry_get_text(GTK_ENTRY(entry))) == 0)) {
-               gtk_container_remove(GTK_CONTAINER(headerentry->compose->header_table), headerentry->combo);
-               gtk_container_remove(GTK_CONTAINER(headerentry->compose->header_table), headerentry->entry);
-               headerentry->compose->header_list = g_slist_remove(headerentry->compose->header_list, headerentry);
+               gtk_container_remove
+                       (GTK_CONTAINER(headerentry->compose->header_table),
+                        headerentry->combo);
+               gtk_container_remove
+                       (GTK_CONTAINER(headerentry->compose->header_table),
+                        headerentry->entry);
+               headerentry->compose->header_list =
+                       g_slist_remove(headerentry->compose->header_list,
+                                      headerentry);
                g_free(headerentry);
        }
 }
 
-void compose_headerentry_changed_cb(GtkWidget *entry, compose_headerentry *headerentry) {
-       if(strlen(gtk_entry_get_text(GTK_ENTRY(entry))) != 0) {
-               headerentry->compose->header_list = g_slist_append(headerentry->compose->header_list, headerentry);
+void compose_headerentry_changed_cb(GtkWidget *entry,
+                                   ComposeHeaderEntry *headerentry)
+{
+       if (strlen(gtk_entry_get_text(GTK_ENTRY(entry))) != 0) {
+               headerentry->compose->header_list =
+                       g_slist_append(headerentry->compose->header_list,
+                                      headerentry);
                compose_create_header_entry(headerentry->compose);
-               gtk_signal_disconnect_by_func(GTK_OBJECT(entry), GTK_SIGNAL_FUNC(compose_headerentry_changed_cb), headerentry);
+               gtk_signal_disconnect_by_func
+                       (GTK_OBJECT(entry),
+                        GTK_SIGNAL_FUNC(compose_headerentry_changed_cb),
+                        headerentry);
        }
 }