2011-07-05 [paul] 3.7.9cvs31
[claws.git] / src / compose.c
index 429e77c45086658b82cb160e985bd2a0983b3543..8f27aa95d99f3ffb9b74939f152d9c3c78dfef5b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2009 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2011 Hiroyuki Yamamoto and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -107,8 +107,9 @@ enum
        COL_MIMETYPE = 0,
        COL_SIZE     = 1,
        COL_NAME     = 2,
-       COL_DATA     = 3,
-       COL_AUTODATA = 4,
+       COL_CHARSET  = 3,
+       COL_DATA     = 4,
+       COL_AUTODATA = 5,
        N_COL_COLUMNS
 };
 
@@ -249,7 +250,8 @@ static ComposeInsertResult compose_insert_file      (Compose        *compose,
 static gboolean compose_attach_append          (Compose        *compose,
                                                 const gchar    *file,
                                                 const gchar    *type,
-                                                const gchar    *content_type);
+                                                const gchar    *content_type,
+                                                const gchar    *charset);
 static void compose_attach_parts               (Compose        *compose,
                                                 MsgInfo        *msginfo);
 
@@ -499,7 +501,7 @@ static Compose *compose_generic_reply(MsgInfo *msginfo,
                                  gboolean followup_and_reply_to,
                                  const gchar *body);
 
-static gboolean compose_headerentry_changed_cb    (GtkWidget          *entry,
+static void compose_headerentry_changed_cb        (GtkWidget          *entry,
                                            ComposeHeaderEntry *headerentry);
 static gboolean compose_headerentry_key_press_event_cb(GtkWidget              *entry,
                                            GdkEventKey        *event,
@@ -523,7 +525,6 @@ static void compose_check_backwards    (GtkAction *action, gpointer data);
 static void compose_check_forwards_go     (GtkAction *action, gpointer data);
 #endif
 
-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);
@@ -533,6 +534,8 @@ static void compose_set_dictionaries_from_folder_prefs(Compose *compose,
                                                FolderItem *folder_item);
 #endif
 static void compose_attach_update_label(Compose *compose);
+static void compose_set_folder_prefs(Compose *compose, FolderItem *folder,
+                                    gboolean respect_default_to);
 
 static GtkActionEntry compose_popup_entries[] =
 {
@@ -710,6 +713,7 @@ static GtkRadioActionEntry compose_radio_enc_entries[] =
        ENC_ACTION("Japanese/"CS_ISO_2022_JP_2, C_ISO_2022_JP_2, "ISO-2022-JP-_2"), /* RADIO compose_set_encoding_cb */
        ENC_ACTION("Japanese/"CS_EUC_JP, C_EUC_JP, "_EUC-JP"), /* RADIO compose_set_encoding_cb */
        ENC_ACTION("Japanese/"CS_SHIFT_JIS, C_SHIFT_JIS, "_Shift-JIS"), /* RADIO compose_set_encoding_cb */
+       ENC_ACTION("Chinese/"CS_GB18030, C_GB18030, "_GB18030"), /* RADIO compose_set_encoding_cb */
        ENC_ACTION("Chinese/"CS_GB2312, C_GB2312, "_GB2312"), /* RADIO compose_set_encoding_cb */
        ENC_ACTION("Chinese/"CS_GBK, C_GBK, "GB_K"), /* RADIO compose_set_encoding_cb */
        ENC_ACTION("Chinese/"CS_BIG5, C_BIG5, "_Big5-JP"), /* RADIO compose_set_encoding_cb */
@@ -943,13 +947,14 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
        gchar *mailto_from = NULL;
        PrefsAccount *mailto_account = NULL;
        MsgInfo* dummyinfo = NULL;
+       gint cursor_pos = -1;
        MailField mfield = NO_FIELD_PRESENT;
        gchar* buf;
        GtkTextMark *mark;
 
        /* check if mailto defines a from */
        if (mailto && *mailto != '\0') {
-               scan_mailto_url(mailto, &mailto_from, NULL, NULL, NULL, NULL, NULL, NULL);
+               scan_mailto_url(mailto, &mailto_from, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
                /* mailto defines a from, check if we can get account prefs from it,
                   if not, the account prefs will be guessed using other ways, but we'll keep
                   the from anyway */
@@ -986,7 +991,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                        dummyinfo = compose_msginfo_new_from_compose(compose);
 
                        /* decode \-escape sequences in the internal representation of the quote format */
-                       tmp = malloc(strlen(item->prefs->compose_override_from_format)+1);
+                       tmp = g_malloc(strlen(item->prefs->compose_override_from_format)+1);
                        pref_get_unescaped_pref(tmp, item->prefs->compose_override_from_format);
 
 #ifdef USE_ENCHANT
@@ -1029,24 +1034,8 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                if (mailto && *mailto != '\0') {
                        mfield = compose_entries_set(compose, mailto, COMPOSE_TO);
 
-               } else if (item && item->prefs) {
-                       if (item->prefs->enable_default_bcc) {
-                               compose_entry_append(compose, item->prefs->default_bcc,
-                                               COMPOSE_BCC, PREF_FOLDER);
-                       }
-                       if (item->prefs->enable_default_cc) {
-                               compose_entry_append(compose, item->prefs->default_cc,
-                                               COMPOSE_CC, PREF_FOLDER);
-                       }
-                       if (item->prefs->enable_default_replyto) {
-                               compose_entry_append(compose, item->prefs->default_replyto,
-                                               COMPOSE_REPLYTO, PREF_FOLDER);
-                       }
-                       if (item->prefs->enable_default_to) {
-                               compose_entry_append(compose, item->prefs->default_to,
-                                               COMPOSE_TO, PREF_FOLDER);
-                               compose_entry_mark_default_to(compose, item->prefs->default_to);
-                       }
+               } else {
+                       compose_set_folder_prefs(compose, item, TRUE);
                }
                if (item && item->ret_rcpt) {
                        cm_toggle_menu_set_active_full(compose->ui_manager, "Menu/Options/RequestRetRcpt", TRUE);
@@ -1093,7 +1082,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                                dummyinfo = compose_msginfo_new_from_compose(compose);
 
                        /* decode \-escape sequences in the internal representation of the quote format */
-                       tmp = malloc(strlen(subject_format)+1);
+                       tmp = g_malloc(strlen(subject_format)+1);
                        pref_get_unescaped_pref(tmp, subject_format);
 
                        subject = gtk_editable_get_chars(GTK_EDITABLE(compose->subject_entry), 0, -1);
@@ -1160,7 +1149,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
 
                for (i = 0; i < attach_files->len; i++) {
                        file = g_ptr_array_index(attach_files, i);
-                       compose_attach_append(compose, file, file, NULL);
+                       compose_attach_append(compose, file, file, NULL, NULL);
                }
        }
 
@@ -1209,7 +1198,11 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                     * is therefore created before placing the cursor
                     */
                case BODY_FIELD_PRESENT:
-                       gtk_widget_grab_focus(compose->text);
+                       cursor_pos = quote_fmt_get_cursor_pos();
+                       if (cursor_pos == -1)
+                               gtk_widget_grab_focus(compose->header_last->entry);
+                       else
+                               gtk_widget_grab_focus(compose->text);
                        break;
        }
 
@@ -1224,7 +1217,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
        compose->modified = FALSE;
        compose_set_title(compose);
 
-  hooks_invoke(COMPOSE_CREATED_HOOKLIST, compose);
+       hooks_invoke(COMPOSE_CREATED_HOOKLIST, compose);
 
         return compose;
 }
@@ -1310,6 +1303,7 @@ static Compose *compose_reply_mode(ComposeMode mode, GSList *msginfo_list, gchar
 
        switch (mode) {
        case COMPOSE_REPLY:
+       case COMPOSE_REPLY_TO_ADDRESS:
                compose = compose_reply(msginfo, COMPOSE_QUOTE_CHECK,
                              FALSE, prefs_common.default_reply_list, FALSE, body);
                break;
@@ -1421,6 +1415,9 @@ static Compose *compose_reply_mode(ComposeMode mode, GSList *msginfo_list, gchar
                debug_print("reply mode List\n");
                cm_toggle_menu_set_active_full(compose->ui_manager, "Menu/Options/ReplyMode/List", TRUE);
                break;
+       case COMPOSE_REPLY_TO_ADDRESS:
+               cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Options/ReplyMode", FALSE);
+               break;
        default:
                break;
        }
@@ -1432,7 +1429,7 @@ static Compose *compose_reply(MsgInfo *msginfo,
                                   gboolean to_all,
                                   gboolean to_ml,
                                   gboolean to_sender, 
-                  const gchar *body)
+                                  const gchar *body)
 {
        return compose_generic_reply(msginfo, quote_mode, to_all, to_ml, 
                              to_sender, FALSE, body);
@@ -1555,7 +1552,7 @@ static Compose *compose_generic_reply(MsgInfo *msginfo,
                gchar *buf = NULL;
 
                /* decode \-escape sequences in the internal representation of the quote format */
-               tmp = malloc(strlen(msginfo->folder->prefs->reply_override_from_format)+1);
+               tmp = g_malloc(strlen(msginfo->folder->prefs->reply_override_from_format)+1);
                pref_get_unescaped_pref(tmp, msginfo->folder->prefs->reply_override_from_format);
 
 #ifdef USE_ENCHANT
@@ -1683,6 +1680,7 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
        GtkTextView *textview;
        GtkTextBuffer *textbuf;
        GtkTextIter iter;
+       ComposeMode mode;
 
        cm_return_val_if_fail(msginfo != NULL, NULL);
        cm_return_val_if_fail(msginfo->folder != NULL, NULL);
@@ -1692,7 +1690,11 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
                                (msginfo)))
                account = cur_account;
 
-       compose = compose_create(account, msginfo->folder, COMPOSE_FORWARD, batch);
+       if (!prefs_common.forward_as_attachment)
+               mode = COMPOSE_FORWARD_INLINE;
+       else
+               mode = COMPOSE_FORWARD;
+       compose = compose_create(account, msginfo->folder, mode, batch);
 
        compose->updating = TRUE;
        compose->fwdinfo = procmsg_msginfo_get_full_info(msginfo);
@@ -1731,7 +1733,7 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
                        full_msginfo = procmsg_msginfo_copy(msginfo);
 
                /* decode \-escape sequences in the internal representation of the quote format */
-               tmp = malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
+               tmp = g_malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
                pref_get_unescaped_pref(tmp, msginfo->folder->prefs->forward_override_from_format);
 
 #ifdef USE_ENCHANT
@@ -1767,7 +1769,7 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
                        g_warning("%s: file not exist\n", msgfile);
                else
                        compose_attach_append(compose, msgfile, msgfile,
-                                             "message/rfc822");
+                                             "message/rfc822", NULL);
 
                g_free(msgfile);
        } else {
@@ -1926,7 +1928,7 @@ static Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_
                        gchar *buf = NULL;
 
                        /* decode \-escape sequences in the internal representation of the quote format */
-                       tmp = malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
+                       tmp = g_malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
                        pref_get_unescaped_pref(tmp, msginfo->folder->prefs->forward_override_from_format);
 
 #ifdef USE_ENCHANT
@@ -1961,7 +1963,7 @@ static Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_
                        g_warning("%s: file not exist\n", msgfile);
                else
                        compose_attach_append(compose, msgfile, msgfile,
-                               "message/rfc822");
+                               "message/rfc822", NULL);
                g_free(msgfile);
        }
        
@@ -2484,6 +2486,9 @@ void compose_entry_append(Compose *compose, const gchar *address,
        case COMPOSE_FOLLOWUPTO:
                header = N_( "Followup-To:");
                break;
+       case COMPOSE_INREPLYTO:
+               header = N_( "In-Reply-To:");
+               break;
        case COMPOSE_TO:
        default:
                header = N_("To:");
@@ -2616,10 +2621,11 @@ static MailField compose_entries_set(Compose *compose, const gchar *mailto, Comp
        gchar *temp = NULL;
        gsize  len = 0;
        gchar **attach = NULL;
+       gchar *inreplyto = NULL;
        MailField mfield = NO_FIELD_PRESENT;
 
        /* get mailto parts but skip from */
-       scan_mailto_url(mailto, NULL, &to, &cc, &bcc, &subject, &body, &attach);
+       scan_mailto_url(mailto, NULL, &to, &cc, &bcc, &subject, &body, &attach, &inreplyto);
 
        if (to) {
                compose_entry_append(compose, to, to_type, PREF_MAILTO);
@@ -2672,7 +2678,7 @@ static MailField compose_entries_set(Compose *compose, const gchar *mailto, Comp
                while (attach[i] != NULL) {
                        gchar *utf8_filename = conv_filename_to_utf8(attach[i]);
                        if (utf8_filename) {
-                               if (compose_attach_append(compose, attach[i], utf8_filename, NULL)) {
+                               if (compose_attach_append(compose, attach[i], utf8_filename, NULL, NULL)) {
                                        gchar *tmp = g_strdup_printf("%s%s\n",
                                                        warn_files?warn_files:"",
                                                        utf8_filename);
@@ -2693,12 +2699,16 @@ static MailField compose_entries_set(Compose *compose, const gchar *mailto, Comp
                        g_free(warn_files);
                }
        }
+       if (inreplyto)
+               compose_entry_append(compose, inreplyto, COMPOSE_INREPLYTO, PREF_MAILTO);
+
        g_free(to);
        g_free(cc);
        g_free(bcc);
        g_free(subject);
        g_free(body);
        g_strfreev(attach);
+       g_free(inreplyto);
        
        return mfield;
 }
@@ -2739,13 +2749,13 @@ static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
                if (hentry[H_REPLY_TO].body[0] != '\0') {
                        compose->replyto =
                                conv_unmime_header(hentry[H_REPLY_TO].body,
-                                                  NULL);
+                                                  NULL, TRUE);
                }
                g_free(hentry[H_REPLY_TO].body);
                hentry[H_REPLY_TO].body = NULL;
        }
        if (hentry[H_CC].body != NULL) {
-               compose->cc = conv_unmime_header(hentry[H_CC].body, NULL);
+               compose->cc = conv_unmime_header(hentry[H_CC].body, NULL, TRUE);
                g_free(hentry[H_CC].body);
                hentry[H_CC].body = NULL;
        }
@@ -2762,7 +2772,7 @@ static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
        if (hentry[H_BCC].body != NULL) {
                if (compose->mode == COMPOSE_REEDIT)
                        compose->bcc =
-                               conv_unmime_header(hentry[H_BCC].body, NULL);
+                               conv_unmime_header(hentry[H_BCC].body, NULL, TRUE);
                g_free(hentry[H_BCC].body);
                hentry[H_BCC].body = NULL;
        }
@@ -2774,7 +2784,7 @@ static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
                if (hentry[H_FOLLOWUP_TO].body[0] != '\0') {
                        compose->followup_to =
                                conv_unmime_header(hentry[H_FOLLOWUP_TO].body,
-                                                  NULL);
+                                                  NULL, TRUE);
                }
                g_free(hentry[H_FOLLOWUP_TO].body);
                hentry[H_FOLLOWUP_TO].body = NULL;
@@ -2787,7 +2797,7 @@ static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
                        start = strstr(hentry[H_LIST_POST].body, "mailto:");
                        
                        scan_mailto_url(start ? start : hentry[H_LIST_POST].body,
-                                       NULL, &to, NULL, NULL, NULL, NULL, NULL);
+                                       NULL, &to, NULL, NULL, NULL, NULL, NULL, NULL);
 
                        if (to) {
                                g_free(compose->ml_post);
@@ -2953,7 +2963,7 @@ static gchar *compose_quote_fmt(Compose *compose, MsgInfo *msginfo,
                        gchar *tmp = NULL;
 
                        /* decode \-escape sequences in the internal representation of the quote format */
-                       tmp = malloc(strlen(fmt)+1);
+                       tmp = g_malloc(strlen(fmt)+1);
                        pref_get_unescaped_pref(tmp, fmt);
                        quote_fmt_scan_string(tmp);
                        quote_fmt_parse();
@@ -3055,6 +3065,52 @@ static gboolean is_subscription(const gchar *ml_post, const gchar *from)
        return result;
 }
 
+static void compose_set_folder_prefs(Compose *compose, FolderItem *folder,
+                                    gboolean respect_default_to)
+{
+       if (!compose)
+               return;
+       if (!folder || !folder->prefs)
+               return;
+
+       if (respect_default_to && folder->prefs->enable_default_to) {
+               compose_entry_append(compose, folder->prefs->default_to,
+                                       COMPOSE_TO, PREF_FOLDER);
+               compose_entry_mark_default_to(compose, folder->prefs->default_to);
+       }
+       if (folder->prefs->enable_default_cc)
+               compose_entry_append(compose, folder->prefs->default_cc,
+                                       COMPOSE_CC, PREF_FOLDER);
+       if (folder->prefs->enable_default_bcc)
+               compose_entry_append(compose, folder->prefs->default_bcc,
+                                       COMPOSE_BCC, PREF_FOLDER);
+       if (folder->prefs->enable_default_replyto)
+               compose_entry_append(compose, folder->prefs->default_replyto,
+                                       COMPOSE_REPLYTO, PREF_FOLDER);
+}
+
+static void compose_reply_set_subject(Compose *compose, MsgInfo *msginfo)
+{
+       gchar *buf, *buf2;
+       gchar *p;
+       
+       if (!compose || !msginfo)
+               return;
+
+       if (msginfo->subject && *msginfo->subject) {
+               buf = p = g_strdup(msginfo->subject);
+               p += subject_get_prefix_length(p);
+               memmove(buf, p, strlen(p) + 1);
+
+               buf2 = g_strdup_printf("Re: %s", buf);
+               gtk_entry_set_text(GTK_ENTRY(compose->subject_entry), buf2);
+
+               g_free(buf2);
+               g_free(buf);
+       } else
+               gtk_entry_set_text(GTK_ENTRY(compose->subject_entry), "Re: ");
+}
+
 static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
                                    gboolean to_all, gboolean to_ml,
                                    gboolean to_sender,
@@ -3078,20 +3134,8 @@ static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
                msginfo->folder->prefs->enable_default_reply_to;
 
        if (compose->account->protocol != A_NNTP) {
-               if (msginfo && msginfo->folder && msginfo->folder->prefs) {
-                       if (msginfo->folder->prefs->enable_default_replyto) {
-                               compose_entry_append(compose, msginfo->folder->prefs->default_replyto,
-                                                       COMPOSE_REPLYTO, PREF_FOLDER);
-                       }
-                       if (msginfo->folder->prefs->enable_default_bcc) {
-                               compose_entry_append(compose, msginfo->folder->prefs->default_bcc,
-                                                       COMPOSE_BCC, PREF_FOLDER);
-                       }
-                       if (msginfo->folder->prefs->enable_default_cc) {
-                               compose_entry_append(compose, msginfo->folder->prefs->default_cc,
-                                                       COMPOSE_CC, PREF_FOLDER);
-                       }
-               }
+               compose_set_folder_prefs(compose, msginfo->folder, FALSE);
+
                if (reply_to_ml && !default_reply_to) {
                        
                        gboolean is_subscr = is_subscription(compose->ml_post,
@@ -3189,22 +3233,7 @@ static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
                                 compose->newsgroups ? compose->newsgroups : "",
                                 COMPOSE_NEWSGROUPS, PREF_NONE);
        }
-
-       if (msginfo->subject && *msginfo->subject) {
-               gchar *buf, *buf2;
-               gchar *p;
-
-               buf = p = g_strdup(msginfo->subject);
-               p += subject_get_prefix_length(p);
-               memmove(buf, p, strlen(p) + 1);
-
-               buf2 = g_strdup_printf("Re: %s", buf);
-               gtk_entry_set_text(GTK_ENTRY(compose->subject_entry), buf2);
-
-               g_free(buf2);
-               g_free(buf);
-       } else
-               gtk_entry_set_text(GTK_ENTRY(compose->subject_entry), "Re: ");
+       compose_reply_set_subject(compose, msginfo);
 
        if (to_ml && compose->ml_post) return;
        if (!to_all || compose->account->protocol == A_NNTP) return;
@@ -3494,7 +3523,8 @@ static ComposeInsertResult compose_insert_file(Compose *compose, const gchar *fi
 
 static gboolean compose_attach_append(Compose *compose, const gchar *file,
                                  const gchar *filename,
-                                 const gchar *content_type)
+                                 const gchar *content_type,
+                                 const gchar *charset)
 {
        AttachInfo *ainfo;
        GtkTreeIter iter;
@@ -3512,8 +3542,8 @@ static gboolean compose_attach_append(Compose *compose, const gchar *file,
                if (file_from_uri && is_file_exist(file_from_uri)) {
                        result = compose_attach_append(
                                                compose, file_from_uri,
-                                               filename,
-                                               content_type);
+                                               filename, content_type,
+                                               charset);
                }
                g_free(file_from_uri);
                if (result)
@@ -3561,10 +3591,12 @@ static gboolean compose_attach_append(Compose *compose, const gchar *file,
 
                        procmsg_msginfo_free(msginfo);
                } else {
-                       if (!g_ascii_strncasecmp(content_type, "text", 4))
+                       if (!g_ascii_strncasecmp(content_type, "text/", 5)) {
+                               ainfo->charset = g_strdup(charset);
                                ainfo->encoding = procmime_get_encoding_for_text_file(file, &has_binary);
-                       else
+                       } else {
                                ainfo->encoding = ENC_BASE64;
+                       }
                        name = g_path_get_basename(filename ? filename : file);
                        ainfo->name = g_strdup(name);
                }
@@ -3575,7 +3607,7 @@ static gboolean compose_attach_append(Compose *compose, const gchar *file,
                        ainfo->content_type =
                                g_strdup("application/octet-stream");
                        ainfo->encoding = ENC_BASE64;
-               } else if (!g_ascii_strncasecmp(ainfo->content_type, "text", 4))
+               } else if (!g_ascii_strncasecmp(ainfo->content_type, "text/", 5))
                        ainfo->encoding =
                                procmime_get_encoding_for_text_file(file, &has_binary);
                else
@@ -3594,6 +3626,8 @@ static gboolean compose_attach_append(Compose *compose, const gchar *file,
        if (!strcmp(ainfo->content_type, "unknown") || has_binary) {
                g_free(ainfo->content_type);
                ainfo->content_type = g_strdup("application/octet-stream");
+               g_free(ainfo->charset);
+               ainfo->charset = NULL;
        }
 
        ainfo->size = (goffset)size;
@@ -3607,6 +3641,7 @@ static gboolean compose_attach_append(Compose *compose, const gchar *file,
                           COL_MIMETYPE, ainfo->content_type,
                           COL_SIZE, size_text,
                           COL_NAME, ainfo->name,
+                          COL_CHARSET, ainfo->charset,
                           COL_DATA, ainfo,
                           COL_AUTODATA, auto_ainfo,
                           -1);
@@ -3710,7 +3745,8 @@ static void compose_attach_parts(Compose *compose, MsgInfo *msginfo)
                                if (partname == NULL)
                                        partname = "";
                                compose_attach_append(compose, outfile, 
-                                                     partname, content_type);
+                                                     partname, content_type,
+                                                     procmime_mimeinfo_get_parameter(child, "charset"));
                        } else {
                                compose_force_signing(compose, compose->account, NULL);
                        }
@@ -5943,24 +5979,40 @@ static int compose_add_attachments(Compose *compose, MimeInfo *parent)
                if (mimepart->type == MIMETYPE_MESSAGE && 
                    !g_ascii_strcasecmp(mimepart->subtype, "rfc822")) {
                        mimepart->disposition = DISPOSITIONTYPE_INLINE;
-               } else {
-                       if (ainfo->name) {
-                               if (mimepart->type == MIMETYPE_APPLICATION && 
-                                  !strcmp2(mimepart->subtype, "octet-stream"))
-                                       g_hash_table_insert(mimepart->typeparameters,
-                                                   g_strdup("name"), g_strdup(ainfo->name));
-                               g_hash_table_insert(mimepart->dispositionparameters,
-                                           g_strdup("filename"), g_strdup(ainfo->name));
+               } else if (mimepart->type == MIMETYPE_TEXT) {
+                       if (!ainfo->name && compose->mode == COMPOSE_FORWARD_INLINE) {
+                               /* Text parts with no name come from multipart/alternative
+                               * forwards. Make sure the recipient won't look at the 
+                               * original HTML part by mistake. */
                                mimepart->disposition = DISPOSITIONTYPE_ATTACHMENT;
+                               ainfo->name = g_strdup_printf(_("Original %s part"),
+                                                               mimepart->subtype);
                        }
-               }
-
-               if (compose->use_signing) {
+                       if (ainfo->charset)
+                               g_hash_table_insert(mimepart->typeparameters,
+                                                   g_strdup("charset"), g_strdup(ainfo->charset));
+               }
+               if (ainfo->name && mimepart->type != MIMETYPE_MESSAGE) {
+                       if (mimepart->type == MIMETYPE_APPLICATION && 
+                          !strcmp2(mimepart->subtype, "octet-stream"))
+                               g_hash_table_insert(mimepart->typeparameters,
+                                               g_strdup("name"), g_strdup(ainfo->name));
+                       g_hash_table_insert(mimepart->dispositionparameters,
+                                       g_strdup("filename"), g_strdup(ainfo->name));
+                       mimepart->disposition = DISPOSITIONTYPE_ATTACHMENT;
+               }
+
+               if (mimepart->type == MIMETYPE_MESSAGE
+                   || mimepart->type == MIMETYPE_MULTIPART)
+                       ainfo->encoding = ENC_BINARY;
+               else if (compose->use_signing) {
                        if (ainfo->encoding == ENC_7BIT)
                                ainfo->encoding = ENC_QUOTED_PRINTABLE;
                        else if (ainfo->encoding == ENC_8BIT)
                                ainfo->encoding = ENC_BASE64;
                }
+
+               
                
                procmime_encode_content(mimepart, ainfo->encoding);
 
@@ -6108,7 +6160,12 @@ static gchar *compose_get_header(Compose *compose)
        compose_add_headerfield_from_headerlist(compose, header, "Cc", ", ");
 
        /* Bcc */
-       compose_add_headerfield_from_headerlist(compose, header, "Bcc", ", ");
+       /* 
+        * If this account is a NNTP account remove Bcc header from 
+        * message body since it otherwise will be publicly shown
+        */
+       if (compose->account->protocol != A_NNTP)
+               compose_add_headerfield_from_headerlist(compose, header, "Bcc", ", ");
 
        /* Subject */
        str = gtk_editable_get_chars(GTK_EDITABLE(compose->subject_entry), 0, -1);
@@ -6486,13 +6543,9 @@ static void compose_create_header_entry(Compose *compose)
                         G_CALLBACK(compose_grab_focus_cb), compose);
 
        /* Entry field with cleanup button */
-#if GTK_CHECK_VERSION(2, 8, 0)
        button = gtk_button_new();
        gtk_button_set_image(GTK_BUTTON(button),
                         gtk_image_new_from_stock(GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU));
-#else
-       button = gtk_button_new_with_label(_("Clear"));
-#endif
        gtk_widget_show(button);
        CLAWS_SET_TIP(button,
                _("Delete entry contents"));
@@ -6557,8 +6610,15 @@ static void compose_add_header_entry(Compose *compose, const gchar *header,
 {
        ComposeHeaderEntry *last_header = compose->header_last;
        gchar *tmp = g_strdup(text), *email;
-       gboolean replyto_hdr = g_str_has_suffix(header, "-To:");
-       
+       gboolean replyto_hdr;
+       
+       replyto_hdr = (!strcasecmp(header,
+                               prefs_common_translated_header_name("Reply-To:")) ||
+                       !strcasecmp(header,
+                               prefs_common_translated_header_name("Followup-To:")) ||
+                       !strcasecmp(header,
+                               prefs_common_translated_header_name("In-Reply-To:")));
+               
        extract_address(tmp);
        email = g_utf8_strdown(tmp, -1);
        
@@ -6572,7 +6632,11 @@ static void compose_add_header_entry(Compose *compose, const gchar *header,
                return;
        }
        
-       combobox_select_by_text(GTK_COMBO_BOX(last_header->combo), header);
+       if (!strcasecmp(header, prefs_common_translated_header_name("In-Reply-To:")))
+               gtk_entry_set_text(GTK_ENTRY(
+                       gtk_bin_get_child(GTK_BIN(last_header->combo))), header);
+       else
+               combobox_select_by_text(GTK_COMBO_BOX(last_header->combo), header);
        gtk_entry_set_text(GTK_ENTRY(last_header->entry), text);
        last_header->type = pref_type;
 
@@ -6686,6 +6750,7 @@ static GtkWidget *compose_create_attach(Compose *compose)
                                   G_TYPE_STRING,
                                   G_TYPE_STRING,
                                   G_TYPE_STRING,
+                                  G_TYPE_STRING,
                                   G_TYPE_POINTER,
                                   G_TYPE_AUTO_POINTER,
                                   -1);
@@ -7019,6 +7084,7 @@ static Compose *compose_create(PrefsAccount *account,
        titles[COL_MIMETYPE] = _("MIME type");
        titles[COL_SIZE]     = _("Size");
        titles[COL_NAME]     = _("Name");
+       titles[COL_CHARSET]  = _("Charset");
 
        compose->batch = batch;
        compose->account = account;
@@ -7230,6 +7296,7 @@ static Compose *compose_create(PrefsAccount *account,
        MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding/Japanese", CS_SHIFT_JIS, "Options/Encoding/Japanese/"CS_SHIFT_JIS, GTK_UI_MANAGER_MENUITEM)
 
        MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding", "Chinese", "Options/Encoding/Chinese", GTK_UI_MANAGER_MENU)
+       MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding/Chinese", CS_GB18030, "Options/Encoding/Chinese/"CS_GB18030, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding/Chinese", CS_GB2312, "Options/Encoding/Chinese/"CS_GB2312, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding/Chinese", CS_GBK, "Options/Encoding/Chinese/"CS_GBK, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding/Chinese", CS_BIG5, "Options/Encoding/Chinese/"CS_BIG5, GTK_UI_MANAGER_MENUITEM)
@@ -7367,6 +7434,10 @@ static Compose *compose_create(PrefsAccount *account,
        gtk_widget_set_size_request(scrolledwin, prefs_common.compose_width, -1);
 
        text = gtk_text_view_new();
+       if (prefs_common.show_compose_margin) {
+               gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text), 6);
+               gtk_text_view_set_right_margin(GTK_TEXT_VIEW(text), 6);
+       }
        buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD_CHAR);
        gtk_text_view_set_editable(GTK_TEXT_VIEW(text), TRUE);
@@ -7554,7 +7625,7 @@ static Compose *compose_create(PrefsAccount *account,
                        }
                }
        }
-    compose->gtkaspell = gtkaspell;
+       compose->gtkaspell = gtkaspell;
        compose_spell_menu_changed(compose);
        claws_spell_entry_set_gtkaspell(CLAWS_SPELL_ENTRY(subject_entry), gtkaspell);
 #endif
@@ -7695,6 +7766,7 @@ static GtkWidget *compose_account_option_menu_create(Compose *compose)
        CLAWS_SET_TIP(from_name,
                _("Sender address to be used"));
 
+       compose->account_combo = optmenu;
        compose->from_name = from_name;
        
        return hbox;
@@ -7896,6 +7968,7 @@ static void compose_set_out_encoding(Compose *compose)
                case C_ISO_2022_JP_2: branch = "Menu/Options/Encoding/Japanese/" CS_ISO_2022_JP_2; break;
                case C_EUC_JP: branch = "Menu/Options/Encoding/Japanese/" CS_EUC_JP; break;
                case C_SHIFT_JIS: branch = "Menu/Options/Encoding/Japanese/" CS_SHIFT_JIS; break;
+               case C_GB18030: branch = "Menu/Options/Encoding/Chinese/" CS_GB18030; break;
                case C_GB2312: branch = "Menu/Options/Encoding/Chinese/" CS_GB2312; break;
                case C_GBK: branch = "Menu/Options/Encoding/Chinese/" CS_GBK; break;
                case C_BIG5: branch = "Menu/Options/Encoding/Chinese/" CS_BIG5; break;
@@ -8345,6 +8418,7 @@ static void compose_attach_info_free(AttachInfo *ainfo)
        g_free(ainfo->file);
        g_free(ainfo->content_type);
        g_free(ainfo->name);
+       g_free(ainfo->charset);
        g_free(ainfo);
 }
 
@@ -8549,6 +8623,7 @@ static void compose_attach_property(GtkAction *action, gpointer data)
                                   COL_MIMETYPE, ainfo->content_type,
                                   COL_SIZE, text,
                                   COL_NAME, ainfo->name,
+                                  COL_CHARSET, ainfo->charset,
                                   -1);
                
                break;
@@ -8897,7 +8972,7 @@ static gboolean compose_input_cb(GIOChannel *source, GIOCondition condition,
        Compose *compose = (Compose *)data;
        gsize bytes_read;
 
-       debug_print(_("Compose: input from monitoring process\n"));
+       debug_print("Compose: input from monitoring process\n");
 
        g_io_channel_read_chars(source, buf, sizeof(buf), &bytes_read, NULL);
 
@@ -9055,7 +9130,7 @@ static gboolean compose_edit_size_alloc(GtkEditable *widget,
 }
 
 typedef struct {
-       ComposeEntryType        header;
+       gchar                   *header;
        gchar                   *entry;
        ComposePrefType         type;
        gboolean                entry_marked;
@@ -9096,8 +9171,8 @@ static void account_activated(GtkComboBox *optmenu, gpointer data)
                        }
                        
                        state = g_malloc0(sizeof(HeaderEntryState));
-                       state->header = combobox_get_active_data(
-                                       GTK_COMBO_BOX(hentry->combo));
+                       state->header = gtk_editable_get_chars(GTK_EDITABLE(
+                                       gtk_bin_get_child(GTK_BIN(hentry->combo))), 0, -1);
                        state->entry = gtk_editable_get_chars(
                                        GTK_EDITABLE(hentry->entry), 0, -1);
                        state->type = hentry->type;
@@ -9138,12 +9213,14 @@ static void account_activated(GtkComboBox *optmenu, gpointer data)
                for (list = saved_list; list; list = list->next) {
                        state = (HeaderEntryState *) list->data;
                        
-                       compose_entry_append(compose, state->entry,
-                                               state->header, state->type);
+                       compose_add_header_entry(compose, state->header,
+                                               state->entry, state->type);
                        if (state->entry_marked)
                                compose_entry_mark_default_to(compose, state->entry);
-                               
+                       
+                       g_free(state->header);  
                        g_free(state->entry);
+                       g_free(state);
                }
                g_slist_free(saved_list);
                
@@ -9238,7 +9315,7 @@ static void compose_allow_user_actions (Compose *compose, gboolean allow)
 static void compose_send_cb(GtkAction *action, gpointer data)
 {
        Compose *compose = (Compose *)data;
-       
+
        if (prefs_common.work_offline && 
            !inc_offline_should_override(TRUE,
                _("Claws Mail needs network access in order "
@@ -9576,7 +9653,7 @@ void compose_attach_from_list(Compose *compose, GList *file_list, gboolean free_
                for ( tmp = file_list; tmp; tmp = tmp->next) {
                        gchar *file = (gchar *) tmp->data;
                        gchar *utf8_filename = conv_filename_to_utf8(file);
-                       compose_attach_append(compose, file, utf8_filename, NULL);
+                       compose_attach_append(compose, file, utf8_filename, NULL, NULL);
                        compose_changed_cb(NULL, compose);
                        if (free_data) {
                        g_free(file);
@@ -9892,7 +9969,7 @@ static void compose_cut_cb(GtkAction *action, gpointer data)
        Compose *compose = (Compose *)data;
        if (compose->focused_editable 
 #ifndef GENERIC_UMPC
-           && GTK_WIDGET_HAS_FOCUS(compose->focused_editable)
+           && gtkut_widget_has_focus(compose->focused_editable)
 #endif
            )
                entry_cut_clipboard(compose->focused_editable);
@@ -9903,7 +9980,7 @@ static void compose_copy_cb(GtkAction *action, gpointer data)
        Compose *compose = (Compose *)data;
        if (compose->focused_editable 
 #ifndef GENERIC_UMPC
-           && GTK_WIDGET_HAS_FOCUS(compose->focused_editable)
+           && gtkut_widget_has_focus(compose->focused_editable)
 #endif
            )
                entry_copy_clipboard(compose->focused_editable);
@@ -9916,14 +9993,14 @@ static void compose_paste_cb(GtkAction *action, gpointer data)
        GtkTextBuffer *buffer;
        BLOCK_WRAP();
        if (compose->focused_editable &&
-           GTK_WIDGET_HAS_FOCUS(compose->focused_editable))
+           gtkut_widget_has_focus(compose->focused_editable))
                entry_paste_clipboard(compose, compose->focused_editable, 
                                prefs_common.linewrap_pastes,
                                GDK_SELECTION_CLIPBOARD, NULL);
        UNBLOCK_WRAP();
 
 #ifdef USE_ENCHANT
-       if (GTK_WIDGET_HAS_FOCUS(compose->text) &&
+       if (gtkut_widget_has_focus(compose->text) &&
            compose->gtkaspell && 
             compose->gtkaspell->check_while_typing)
                gtkaspell_highlight_all(compose->gtkaspell);
@@ -9936,7 +10013,7 @@ static void compose_paste_as_quote_cb(GtkAction *action, gpointer data)
        gint wrap_quote = prefs_common.linewrap_quote;
        if (compose->focused_editable 
 #ifndef GENERIC_UMPC
-           && GTK_WIDGET_HAS_FOCUS(compose->focused_editable)
+           && gtkut_widget_has_focus(compose->focused_editable)
 #endif
            ) {
                /* let text_insert() (called directly or at a later time
@@ -9965,7 +10042,7 @@ static void compose_paste_no_wrap_cb(GtkAction *action, gpointer data)
        BLOCK_WRAP();
        if (compose->focused_editable 
 #ifndef GENERIC_UMPC
-           && GTK_WIDGET_HAS_FOCUS(compose->focused_editable)
+           && gtkut_widget_has_focus(compose->focused_editable)
 #endif
            )
                entry_paste_clipboard(compose, compose->focused_editable, FALSE,
@@ -9973,7 +10050,7 @@ static void compose_paste_no_wrap_cb(GtkAction *action, gpointer data)
        UNBLOCK_WRAP();
 
 #ifdef USE_ENCHANT
-       if (GTK_WIDGET_HAS_FOCUS(compose->text) &&
+       if (gtkut_widget_has_focus(compose->text) &&
            compose->gtkaspell && 
             compose->gtkaspell->check_while_typing)
                gtkaspell_highlight_all(compose->gtkaspell);
@@ -9988,7 +10065,7 @@ static void compose_paste_wrap_cb(GtkAction *action, gpointer data)
        BLOCK_WRAP();
        if (compose->focused_editable 
 #ifndef GENERIC_UMPC
-           && GTK_WIDGET_HAS_FOCUS(compose->focused_editable)
+           && gtkut_widget_has_focus(compose->focused_editable)
 #endif
            )
                entry_paste_clipboard(compose, compose->focused_editable, TRUE,
@@ -9996,7 +10073,7 @@ static void compose_paste_wrap_cb(GtkAction *action, gpointer data)
        UNBLOCK_WRAP();
 
 #ifdef USE_ENCHANT
-       if (GTK_WIDGET_HAS_FOCUS(compose->text) &&
+       if (gtkut_widget_has_focus(compose->text) &&
            compose->gtkaspell &&
             compose->gtkaspell->check_while_typing)
                gtkaspell_highlight_all(compose->gtkaspell);
@@ -10008,7 +10085,7 @@ static void compose_allsel_cb(GtkAction *action, gpointer data)
        Compose *compose = (Compose *)data;
        if (compose->focused_editable 
 #ifndef GENERIC_UMPC
-           && GTK_WIDGET_HAS_FOCUS(compose->focused_editable)
+           && gtkut_widget_has_focus(compose->focused_editable)
 #endif
            )
                entry_allsel(compose->focused_editable);
@@ -10312,7 +10389,7 @@ static void compose_advanced_action_cb(GtkAction *gaction, gpointer data)
                {textview_delete_to_line_end}
        };
 
-       if (!GTK_WIDGET_HAS_FOCUS(text)) return;
+       if (!gtkut_widget_has_focus(GTK_WIDGET(text))) return;
 
        if (action >= COMPOSE_CALL_ADVANCED_ACTION_MOVE_BEGINNING_OF_LINE &&
            action <= COMPOSE_CALL_ADVANCED_ACTION_DELETE_TO_LINE_END) {
@@ -10502,7 +10579,7 @@ static void compose_attach_drag_received_cb (GtkWidget          *widget,
                        gchar *utf8_filename = conv_filename_to_utf8((const gchar *)tmp->data);
                        compose_attach_append
                                (compose, (const gchar *)tmp->data,
-                                utf8_filename, NULL);
+                                utf8_filename, NULL, NULL);
                        g_free(utf8_filename);
                }
                if (list) compose_changed_cb(NULL, compose);
@@ -10528,7 +10605,7 @@ static void compose_attach_drag_received_cb (GtkWidget          *widget,
                                        TRUE, TRUE);
                        if (file) {
                                compose_attach_append(compose, (const gchar *)file, 
-                                       (const gchar *)file, "message/rfc822");
+                                       (const gchar *)file, "message/rfc822", NULL);
                                g_free(file);
                        }
                }
@@ -10629,16 +10706,6 @@ static void compose_insert_drag_received_cb (GtkWidget         *widget,
                gtk_drag_finish(drag_context, TRUE, FALSE, time);
                return;
        } else {
-#if GTK_CHECK_VERSION(2, 8, 0)
-               /* do nothing, handled by GTK */
-#else
-               gchar *tmpfile = get_tmp_file();
-               str_write_to_file((const gchar *)data->data, tmpfile);
-               compose_insert_file(compose, tmpfile);
-               claws_unlink(tmpfile);
-               g_free(tmpfile);
-               gtk_drag_finish(drag_context, TRUE, FALSE, time);
-#endif
                return;
        }
        gtk_drag_finish(drag_context, TRUE, FALSE, time);
@@ -10733,7 +10800,18 @@ static gboolean compose_headerentry_key_press_event_cb(GtkWidget *entry,
        return FALSE;
 }
 
-static gboolean compose_headerentry_changed_cb(GtkWidget *entry,
+static gboolean scroll_postpone(gpointer data)
+{
+       Compose *compose = (Compose *)data;
+
+       cm_return_val_if_fail(!compose->batch, FALSE);
+
+       GTK_EVENTS_FLUSH();
+       compose_show_first_last_header(compose, FALSE);
+       return FALSE;
+}
+
+static void compose_headerentry_changed_cb(GtkWidget *entry,
                                    ComposeHeaderEntry *headerentry)
 {
        if (strlen(gtk_entry_get_text(GTK_ENTRY(entry))) != 0) {
@@ -10741,12 +10819,16 @@ static gboolean compose_headerentry_changed_cb(GtkWidget *entry,
                g_signal_handlers_disconnect_matched
                        (G_OBJECT(entry), G_SIGNAL_MATCH_DATA,
                         0, 0, NULL, NULL, headerentry);
-               
-               /* Automatically scroll down */
-               GTK_EVENTS_FLUSH();
-               compose_show_first_last_header(headerentry->compose, FALSE);
-               
+
+               if (!headerentry->compose->batch)
+                       g_timeout_add(0, scroll_postpone, headerentry->compose);
        }
+}
+
+static gboolean compose_defer_auto_save_draft(Compose *compose)
+{
+       compose->draft_timeout_tag = -1;
+       compose_draft((gpointer)compose, COMPOSE_AUTO_SAVE);
        return FALSE;
 }
 
@@ -10755,6 +10837,7 @@ static void compose_show_first_last_header(Compose *compose, gboolean show_first
        GtkAdjustment *vadj;
 
        cm_return_if_fail(compose);
+       cm_return_if_fail(!compose->batch);
        cm_return_if_fail(GTK_IS_WIDGET(compose->header_table));
        cm_return_if_fail(GTK_IS_VIEWPORT(compose->header_table->parent));
        vadj = gtk_viewport_get_vadjustment(GTK_VIEWPORT(compose->header_table->parent));
@@ -10863,13 +10946,7 @@ static void text_inserted(GtkTextBuffer *buffer, GtkTextIter *iter,
            gtk_text_buffer_get_char_count(buffer) % prefs_common.autosave_length == 0 &&
            compose->draft_timeout_tag != -2 /* disabled while loading */)
                compose->draft_timeout_tag = g_timeout_add
-                       (500, (GtkFunction) compose_defer_auto_save_draft, compose);
-}
-static gint compose_defer_auto_save_draft(Compose *compose)
-{
-       compose->draft_timeout_tag = -1;
-       compose_draft((gpointer)compose, COMPOSE_AUTO_SAVE);
-       return FALSE;
+                       (500, (GSourceFunc) compose_defer_auto_save_draft, compose);
 }
 
 #if USE_ENCHANT
@@ -10879,7 +10956,7 @@ static void compose_check_all(GtkAction *action, gpointer data)
        if (!compose->gtkaspell)
                return;
                
-       if (GTK_WIDGET_HAS_FOCUS(compose->subject_entry))
+       if (gtkut_widget_has_focus(compose->subject_entry))
                claws_spell_entry_check_all(
                        CLAWS_SPELL_ENTRY(compose->subject_entry));             
        else
@@ -10904,7 +10981,7 @@ static void compose_check_backwards(GtkAction *action, gpointer data)
                return;
        }
 
-       if (GTK_WIDGET_HAS_FOCUS(compose->subject_entry))
+       if (gtkut_widget_has_focus(compose->subject_entry))
                claws_spell_entry_check_backwards(
                        CLAWS_SPELL_ENTRY(compose->subject_entry));
        else
@@ -10919,7 +10996,7 @@ static void compose_check_forwards_go(GtkAction *action, gpointer data)
                return;
        }
 
-       if (GTK_WIDGET_HAS_FOCUS(compose->subject_entry))
+       if (gtkut_widget_has_focus(compose->subject_entry))
                claws_spell_entry_check_forwards_go(
                        CLAWS_SPELL_ENTRY(compose->subject_entry));
        else
@@ -11112,6 +11189,51 @@ void compose_reply_from_messageview(MessageView *msgview, GSList *msginfo_list,
        }
 }
 
+void compose_check_for_email_account(Compose *compose)
+{
+       PrefsAccount *ac = NULL, *curr = NULL;
+       GList *list;
+       
+       if (!compose)
+               return;
+
+       if (compose->account && compose->account->protocol == A_NNTP) {
+               ac = account_get_cur_account();
+               if (ac->protocol == A_NNTP) {
+                       list = account_get_list();
+                       
+                       for( ; list != NULL ; list = g_list_next(list)) {
+                               curr = (PrefsAccount *) list->data;
+                               if (curr->protocol != A_NNTP) {
+                                       ac = curr;
+                                       break;
+                               }
+                       }
+               }
+               combobox_select_by_data(GTK_COMBO_BOX(compose->account_combo),
+                                       ac->account_id); 
+       }
+}
+
+void compose_reply_to_address(MessageView *msgview, MsgInfo *msginfo, 
+                               const gchar *address)
+{
+       GSList *msginfo_list = NULL;
+       gchar *body =  messageview_get_selection(msgview);
+       Compose *compose;
+       
+       msginfo_list = g_slist_prepend(msginfo_list, msginfo);
+       
+       compose = compose_reply_mode(COMPOSE_REPLY_TO_ADDRESS, msginfo_list, body);
+       compose_check_for_email_account(compose);
+       compose_set_folder_prefs(compose, msginfo->folder, FALSE);
+       compose_entry_append(compose, address, COMPOSE_TO, PREF_NONE);
+       compose_reply_set_subject(compose, msginfo);
+
+       g_free(body);
+       hooks_invoke(COMPOSE_CREATED_HOOKLIST, compose);
+}
+
 void compose_set_position(Compose *compose, gint pos)
 {
        GtkTextView *text = GTK_TEXT_VIEW(compose->text);