revert because it crashes on Reply and Compose
[claws.git] / src / compose.c
index 97618a2ac81a04a00c676527bc0a1c48d004a55d..3333d5c3aa0fb68e7201f3e78ade465a696dbb75 100644 (file)
@@ -188,11 +188,10 @@ static void compose_insert_file                   (Compose        *compose,
                                                 const gchar    *file);
 static void compose_attach_append              (Compose        *compose,
                                                 const gchar    *file,
-                                                ContentType     cnttype);
-static void compose_attach_append_with_type(Compose *compose,
-                                           const gchar *file,
-                                           const gchar *type,
-                                           ContentType cnttype);
+                                                const gchar    *type,
+                                                const gchar    *content_type);
+static void compose_attach_parts               (Compose        *compose,
+                                                MsgInfo        *msginfo);
 static void compose_wrap_line                  (Compose        *compose);
 static void compose_wrap_line_all              (Compose        *compose);
 static void compose_set_title                  (Compose        *compose);
@@ -436,9 +435,6 @@ static void followupto_activated    (GtkWidget      *widget,
                                         Compose        *compose);
 #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,
@@ -944,6 +940,7 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
                compose_exec_ext_editor(compose);
 }
 
+static void set_toolbar_style(Compose *compose);
 
 static gchar *procmime_get_file_name(MimeInfo *mimeinfo)
 {
@@ -995,167 +992,6 @@ static gchar *mime_extract_file(gchar *source, MimeInfo *partinfo)
        return filename;
 }
 
-static void compose_attach_parts(Compose *compose, MsgInfo *msginfo)
-{
-       FILE *fp;
-       gchar *file;
-       MimeInfo *mimeinfo;
-       MsgInfo *tmpmsginfo;
-       gchar *p;
-       gchar *boundary;
-       gint boundary_len = 0;
-       gchar buf[BUFFSIZE];
-       glong fpos, prev_fpos;
-       gint npart;
-       gchar *source;
-       gchar *filename;
-
-       g_return_if_fail(msginfo != NULL);
-       
-#if USE_GPGME
-       for (;;) {
-               if ((fp = procmsg_open_message(msginfo)) == NULL) return;
-               mimeinfo = procmime_scan_mime_header(fp, MIME_TEXT);
-               if (!mimeinfo) break;
-
-               if (!MSG_IS_ENCRYPTED(msginfo->flags) &&
-                   rfc2015_is_encrypted(mimeinfo)) {
-                       MSG_SET_TMP_FLAGS(msginfo->flags, MSG_ENCRYPTED);
-               }
-               if (MSG_IS_ENCRYPTED(msginfo->flags) &&
-                   !msginfo->plaintext_file  &&
-                   !msginfo->decryption_failed) {
-                       rfc2015_decrypt_message(msginfo, mimeinfo, fp);
-                       if (msginfo->plaintext_file &&
-                           !msginfo->decryption_failed) {
-                               fclose(fp);
-                               continue;
-                       }
-               }
-               
-               break;
-       }
-#else /* !USE_GPGME */
-       if ((fp = procmsg_open_message(msginfo)) == NULL) return;
-       mimeinfo = procmime_scan_mime_header(fp, MIME_TEXT);
-#endif /* USE_GPGME */
-
-       fclose(fp);
-       if (!mimeinfo) return;
-       if (mimeinfo->mime_type == MIME_TEXT)
-               return;
-
-       if ((fp = procmsg_open_message(msginfo)) == NULL) return;
-
-       g_return_if_fail(mimeinfo != NULL);
-       g_return_if_fail(mimeinfo->mime_type != MIME_TEXT);
-
-       if (mimeinfo->mime_type == MIME_MULTIPART) {
-               g_return_if_fail(mimeinfo->boundary != NULL);
-               g_return_if_fail(mimeinfo->sub == NULL);
-       }
-       g_return_if_fail(fp != NULL);
-
-       boundary = mimeinfo->boundary;
-
-       if (boundary) {
-               boundary_len = strlen(boundary);
-
-               /* look for first boundary */
-               while ((p = fgets(buf, sizeof(buf), fp)) != NULL)
-                       if (IS_BOUNDARY(buf, boundary, boundary_len)) break;
-               if (!p) {
-                       fclose(fp);
-                       return;
-               }
-       }
-
-       if ((fpos = ftell(fp)) < 0) {
-               perror("ftell");
-               fclose(fp);
-               return;
-       }
-
-       for (npart = 0;; npart++) {
-               MimeInfo *partinfo;
-               gboolean eom = FALSE;
-
-               prev_fpos = fpos;
-
-               partinfo = procmime_scan_mime_header(fp, MIME_TEXT);
-               if (!partinfo) break;
-
-               if (npart != 0)
-                       procmime_mimeinfo_insert(mimeinfo, partinfo);
-               else
-                       procmime_mimeinfo_free(partinfo);
-
-               /* look for next boundary */
-               buf[0] = '\0';
-               while ((p = fgets(buf, sizeof(buf), fp)) != NULL) {
-                       if (IS_BOUNDARY(buf, boundary, boundary_len)) {
-                               if (buf[2 + boundary_len]     == '-' &&
-                                   buf[2 + boundary_len + 1] == '-')
-                                       eom = TRUE;
-                               break;
-                       }
-               }
-               if (p == NULL)
-                       eom = TRUE;     /* broken MIME message */
-               fpos = ftell(fp);
-
-               partinfo->size = fpos - prev_fpos - strlen(buf);
-
-               if (eom) break;
-       }
-
-       source = procmsg_get_message_file_path(msginfo);
-
-       g_return_if_fail(mimeinfo != NULL);
-
-       if (!mimeinfo->main && mimeinfo->parent)
-               {
-                       filename = mime_extract_file(source, mimeinfo);
-
-                       compose_attach_append_with_type(compose, filename,
-                                                       mimeinfo->content_type,
-                                                       mimeinfo->mime_type);
-
-                       g_free(filename);
-               }
-
-       if (mimeinfo->sub && mimeinfo->sub->children)
-               {
-                       filename = mime_extract_file(source, mimeinfo->sub);
-
-                       compose_attach_append_with_type(compose, filename,
-                                                       mimeinfo->content_type,
-                                                       mimeinfo->sub->mime_type);
-
-                       g_free(filename);
-               }
-
-       if (mimeinfo->children) {
-               MimeInfo *child;
-
-               child = mimeinfo->children;
-               while (child) {
-                       filename = mime_extract_file(source, child);
-
-                       compose_attach_append_with_type(compose, filename,
-                                                       child->content_type,
-                                                       child->mime_type);
-
-                       g_free(filename);
-
-                       child = child->next;
-               }
-       }
-
-       fclose(fp);
-
-       procmime_mimeinfo_free_all(mimeinfo);
-}
 
 
 #define INSERT_FW_HEADER(var, hdr) \
@@ -1217,31 +1053,33 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
        text = GTK_STEXT(compose->text);
        gtk_stext_freeze(text);
 
-       if (as_attach) {
-               gchar *msgfile;
 
-               msgfile = procmsg_get_message_file_path(msginfo);
-               if (!is_file_exist(msgfile))
-                       g_warning(_("%s: file not exist\n"), msgfile);
-               else
-                       compose_attach_append(compose, msgfile,
-                                             MIME_MESSAGE_RFC822);
+               if (as_attach) {
+                       gchar *msgfile;
 
-               g_free(msgfile);
-       } else {
-               gchar *qmark;
-               gchar *quote_str;
+                       msgfile = procmsg_get_message_file_path(msginfo);
+                       if (!is_file_exist(msgfile))
+                               g_warning(_("%s: file not exist\n"), msgfile);
+                       else
+                               compose_attach_append(compose, msgfile, msgfile,
+                                                     "message/rfc822");
 
-               if (prefs_common.fw_quotemark && *prefs_common.fw_quotemark)
-                       qmark = prefs_common.fw_quotemark;
-               else
-                       qmark = "> ";
+                       g_free(msgfile);
+               } else {
+                       gchar *qmark;
+                       gchar *quote_str;
 
-               quote_str = compose_quote_fmt(compose, msginfo,
-                                             prefs_common.fw_quotefmt, qmark,
-                                             body);
-               compose_attach_parts(compose, msginfo);
-       }
+                       if (prefs_common.fw_quotemark &&
+                           *prefs_common.fw_quotemark)
+                               qmark = prefs_common.fw_quotemark;
+                       else
+                               qmark = "> ";
+
+                       quote_str = compose_quote_fmt(compose, msginfo,
+                                                     prefs_common.fw_quotefmt,
+                                                     qmark, body);
+                       compose_attach_parts(compose, msginfo);
+               }
 
        if (prefs_common.auto_sig)
                compose_insert_sig(compose);
@@ -1308,8 +1146,8 @@ Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_list)
                if (!is_file_exist(msgfile))
                        g_warning(_("%s: file not exist\n"), msgfile);
                else
-                       compose_attach_append(compose, msgfile,
-                               MIME_MESSAGE_RFC822);
+                       compose_attach_append(compose, msgfile, msgfile,
+                               "message/rfc822");
                g_free(msgfile);
        }
 
@@ -1997,7 +1835,7 @@ static void compose_insert_file(Compose *compose, const gchar *file)
 
        g_return_if_fail(file != NULL);
 
-       if ((fp = fopen(file, "r")) == NULL) {
+       if ((fp = fopen(file, "rb")) == NULL) {
                FILE_OP_ERROR(file, "fopen");
                return;
        }
@@ -2021,30 +1859,15 @@ static void compose_insert_file(Compose *compose, const gchar *file)
        fclose(fp);
 }
 
-static void compose_attach_info(Compose * compose, AttachInfo * ainfo,
-                               ContentType cnttype)
-{
-       gchar *text[N_ATTACH_COLS];
-       gint row;
-
-       text[COL_MIMETYPE] = ainfo->content_type;
-       text[COL_SIZE] = to_human_readable(ainfo->size);
-       text[COL_NAME] = ainfo->name;
-
-       row = gtk_clist_append(GTK_CLIST(compose->attach_clist), text);
-       gtk_clist_set_row_data(GTK_CLIST(compose->attach_clist), row, ainfo);
-
-       if (cnttype != MIME_MESSAGE_RFC822)
-               compose_changed_cb(NULL, compose);
-}
-
-static void compose_attach_append_with_type(Compose *compose,
-                                           const gchar *file,
-                                           const gchar *type,
-                                           ContentType cnttype)
+static void compose_attach_append(Compose *compose, const gchar *file,
+                                 const gchar *filename,
+                                 const gchar *content_type)
 {
        AttachInfo *ainfo;
+       gchar *text[N_ATTACH_COLS];
+       FILE *fp;
        off_t size;
+       gint row;
 
        if (!is_file_exist(file)) {
                g_warning(_("File %s doesn't exist\n"), file);
@@ -2055,9 +1878,15 @@ static void compose_attach_append_with_type(Compose *compose,
                return;
        }
        if (size == 0) {
-               alertpanel_notice(_("File %s is empty\n"), file);
+               alertpanel_notice(_("File %s is empty."), file);
+               return;
+       }
+       if ((fp = fopen(file, "rb")) == NULL) {
+               alertpanel_error(_("Can't read %s."), file);
                return;
        }
+       fclose(fp);
+
 #if 0 /* NEW COMPOSE GUI */
        if (!compose->use_attach) {
                GtkItemFactory *ifactory;
@@ -2065,7 +1894,7 @@ static void compose_attach_append_with_type(Compose *compose,
 
                ifactory = gtk_item_factory_from_widget(compose->menubar);
                menuitem = gtk_item_factory_get_item(ifactory,
-                                                    "/Message/Attach");
+                                                    "/View/Attachment");
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
                                               TRUE);
        }
@@ -2073,74 +1902,91 @@ static void compose_attach_append_with_type(Compose *compose,
        ainfo = g_new0(AttachInfo, 1);
        ainfo->file = g_strdup(file);
 
-       if (cnttype == MIME_MESSAGE_RFC822) {
-               ainfo->encoding = ENC_7BIT;
-               ainfo->name = g_strdup_printf(_("Message: %s"),
-                                             g_basename(file));
+       if (content_type) {
+               ainfo->content_type = g_strdup(content_type);
+               if (!strcasecmp(content_type, "message/rfc822")) {
+                       ainfo->encoding = ENC_7BIT;
+                       ainfo->name = g_strdup_printf
+                               (_("Message: %s"),
+                                g_basename(filename ? filename : file));
+               } else {
+                       ainfo->encoding = ENC_BASE64;
+                       ainfo->name = g_strdup
+                               (g_basename(filename ? filename : file));
+               }
        } else {
+               ainfo->content_type = procmime_get_mime_type(file);
+               if (!ainfo->content_type)
+                       ainfo->content_type =
+                               g_strdup("application/octet-stream");
                ainfo->encoding = ENC_BASE64;
-               ainfo->name = g_strdup(g_basename(file));
+               ainfo->name = g_strdup(g_basename(filename ? filename : file)); 
        }
-
-       ainfo->content_type = g_strdup(type);
        ainfo->size = size;
 
-       compose_attach_info(compose, ainfo, cnttype);
+       text[COL_MIMETYPE] = ainfo->content_type;
+       text[COL_SIZE] = to_human_readable(size);
+       text[COL_NAME] = ainfo->name;
+
+       row = gtk_clist_append(GTK_CLIST(compose->attach_clist), text);
+       gtk_clist_set_row_data(GTK_CLIST(compose->attach_clist), row, ainfo);
 }
 
-static void compose_attach_append(Compose *compose, const gchar *file,
-                                 ContentType cnttype)
+#define IS_FIRST_PART_TEXT(info) \
+       ((info->mime_type == MIME_TEXT || info->mime_type == MIME_TEXT_HTML || \
+         info->mime_type == MIME_TEXT_ENRICHED) || \
+        (info->mime_type == MIME_MULTIPART && info->content_type && \
+         !strcasecmp(info->content_type, "multipart/alternative") && \
+         (info->children && \
+          (info->children->mime_type == MIME_TEXT || \
+           info->children->mime_type == MIME_TEXT_HTML || \
+           info->children->mime_type == MIME_TEXT_ENRICHED))))
+
+static void compose_attach_parts(Compose *compose, MsgInfo *msginfo)
 {
-       AttachInfo *ainfo;
-       gchar *text[N_ATTACH_COLS];
-       off_t size;
-       gint row;
+       MimeInfo *mimeinfo;
+       MimeInfo *child;
+       gchar *infile;
+       gchar *outfile;
 
-       if (!is_file_exist(file)) {
-               g_warning(_("File %s doesn't exist\n"), file);
-               return;
-       }
-       if ((size = get_file_size(file)) < 0) {
-               g_warning(_("Can't get file size of %s\n"), file);
-               return;
-       }
-       if (size == 0) {
-               alertpanel_notice(_("File %s is empty\n"), file);
+       mimeinfo = procmime_scan_message(msginfo);
+       if (!mimeinfo) return;
+
+       /* skip first text (presumably message body) */
+       child = mimeinfo->children;
+       if (!child || IS_FIRST_PART_TEXT(mimeinfo)) {
+               procmime_mimeinfo_free_all(mimeinfo);
                return;
        }
-#if 0 /* NEW COMPOSE GUI */
-       if (!compose->use_attach) {
-               GtkItemFactory *ifactory;
-               GtkWidget *menuitem;
+       if (IS_FIRST_PART_TEXT(child))
+               child = child->next;
 
-               ifactory = gtk_item_factory_from_widget(compose->menubar);
-               menuitem = gtk_item_factory_get_item(ifactory,
-                                                    "/View/Attachment");
-               gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
-                                              TRUE);
-       }
-#endif
-       ainfo = g_new0(AttachInfo, 1);
-       ainfo->file = g_strdup(file);
+       infile = procmsg_get_message_file_path(msginfo);
 
-       if (cnttype == MIME_MESSAGE_RFC822) {
-               ainfo->content_type = g_strdup("message/rfc822");
-               ainfo->encoding = ENC_7BIT;
-               ainfo->name = g_strdup_printf(_("Message: %s"),
-                                             g_basename(file));
-       } else {
-               ainfo->content_type = procmime_get_mime_type(file);
-               if (!ainfo->content_type)
-                       ainfo->content_type =
-                               g_strdup("application/octet-stream");
-               ainfo->encoding = ENC_BASE64;
-               ainfo->name = g_strdup(g_basename(file));
+       while (child != NULL) {
+               if (child->children || child->mime_type == MIME_MULTIPART) {
+                       child = procmime_mimeinfo_next(child);
+                       continue;
+               }
+
+               outfile = procmime_get_tmp_file_name(child);
+               if (procmime_get_part(outfile, infile, child) < 0)
+                       g_warning(_("Can't get the part of multipart message."));
+               else
+                       compose_attach_append
+                               (compose, outfile,
+                                child->filename ? child->filename : child->name,
+                                child->content_type);
+
+               child = child->next;
        }
-       ainfo->size = size;
 
-       compose_attach_info(compose, ainfo, cnttype);
+       g_free(infile);
+       procmime_mimeinfo_free_all(mimeinfo);
 }
 
+#undef IS_FIRST_PART_TEXT
+
 #define GET_CHAR(pos, buf, len)                                                     \
 {                                                                           \
        if (text->use_wchar)                                                 \
@@ -2741,10 +2587,9 @@ gint compose_send(Compose *compose)
        }
        
        val = procmsg_send_message_queue(folder_item_fetch_msg(folder, msgnum));
-       if(!val) {
-               folder_item_remove_msg(folder, msgnum);
-               folderview_update_item(folder, TRUE);
-       }
+
+       folder_item_remove_msg(folder, msgnum);
+       folderview_update_item(folder, TRUE);
 
        return val;
 }
@@ -2965,12 +2810,12 @@ static gint compose_bounce_write_to_file(Compose *compose, const gchar *file)
        size_t len;
        gchar buf[BUFFSIZE];
 
-       if ((fp = fopen(compose->bounce_filename, "r")) == NULL) {
+       if ((fp = fopen(compose->bounce_filename, "rb")) == NULL) {
                FILE_OP_ERROR(file, "fopen");
                return -1;
        }
 
-       if ((fdest = fopen(file, "w")) == NULL) {
+       if ((fdest = fopen(file, "wb")) == NULL) {
                FILE_OP_ERROR(file, "fopen");
                fclose(fp);
                return -1;
@@ -3081,7 +2926,7 @@ static gint compose_write_to_file(Compose *compose, const gchar *file,
        const gchar *out_codeset;
        EncodingType encoding;
 
-       if ((fp = fopen(file, "w")) == NULL) {
+       if ((fp = fopen(file, "wb")) == NULL) {
                FILE_OP_ERROR(file, "fopen");
                return -1;
        }
@@ -3118,11 +2963,20 @@ static gint compose_write_to_file(Compose *compose, const gchar *file,
 
                buf = conv_codeset_strdup(chars, src_codeset, out_codeset);
                if (!buf) {
-                       g_free(chars);
-                       fclose(fp);
-                       unlink(file);
-                       alertpanel_error(_("Can't convert the codeset of the message."));
-                       return -1;
+                       AlertValue aval;
+
+                       aval = alertpanel
+                               (_("Error"),
+                                _("Can't convert the character encoding of the message.\n"
+                                  "Send it anyway?"), _("Yes"), _("+No"), NULL);
+                       if (aval != G_ALERTDEFAULT) {
+                               g_free(chars);
+                               fclose(fp);
+                               unlink(file);
+                               return -1;
+                       } else {
+                               buf = g_strdup(chars);
+                       }
                }
        }
        g_free(chars);
@@ -3212,7 +3066,7 @@ static gint compose_write_body_to_file(Compose *compose, const gchar *file)
        size_t len;
        gchar *chars;
 
-       if ((fp = fopen(file, "w")) == NULL) {
+       if ((fp = fopen(file, "wb")) == NULL) {
                FILE_OP_ERROR(file, "fopen");
                return -1;
        }
@@ -3383,13 +3237,13 @@ static gint compose_queue(Compose *compose, gint *msgnum, FolderItem **item)
 
        /* add queue header */
        tmp = g_strdup_printf("%s%cqueue.%d", g_get_tmp_dir(),
-                                     G_DIR_SEPARATOR, (gint)compose);
-       if ((fp = fopen(tmp, "w")) == NULL) {
+                             G_DIR_SEPARATOR, (gint)compose);
+       if ((fp = fopen(tmp, "wb")) == NULL) {
                FILE_OP_ERROR(tmp, "fopen");
                g_free(tmp);
                return -1;
        }
-       if ((src_fp = fopen(tmp2, "r")) == NULL) {
+       if ((src_fp = fopen(tmp2, "rb")) == NULL) {
                FILE_OP_ERROR(tmp2, "fopen");
                fclose(fp);
                unlink(tmp);
@@ -3544,7 +3398,10 @@ static void compose_write_attach(Compose *compose, FILE *fp)
 
        for (row = 0; (ainfo = gtk_clist_get_row_data(clist, row)) != NULL;
             row++) {
-               if ((attach_fp = fopen(ainfo->file, "r")) == NULL) {
+               gchar buf[BUFFSIZE];
+               gchar inbuf[B64_LINE_SIZE], outbuf[B64_BUFFSIZE];
+
+               if ((attach_fp = fopen(ainfo->file, "rb")) == NULL) {
                        g_warning(_("Can't open file %s\n"), ainfo->file);
                        continue;
                }
@@ -3567,15 +3424,19 @@ static void compose_write_attach(Compose *compose, FILE *fp)
                fprintf(fp, "Content-Transfer-Encoding: %s\n\n",
                        procmime_get_encoding_str(ainfo->encoding));
 
-               if (ainfo->encoding == ENC_7BIT) {
-                       gchar buf[BUFFSIZE];
+               switch (ainfo->encoding) {
+
+               case ENC_7BIT:
+               case ENC_8BIT:
+                       /* if (ainfo->encoding == ENC_7BIT) { */
 
                        while (fgets(buf, sizeof(buf), attach_fp) != NULL) {
                                strcrchomp(buf);
                                fputs(buf, fp);
                        }
-               } else {
-                       gchar inbuf[B64_LINE_SIZE], outbuf[B64_BUFFSIZE];
+                       break;
+                       /* } else { */
+               case ENC_BASE64:
 
                        while ((len = fread(inbuf, sizeof(gchar),
                                            B64_LINE_SIZE, attach_fp))
@@ -3589,6 +3450,7 @@ static void compose_write_attach(Compose *compose, FILE *fp)
                                fputs(outbuf, fp);
                                fputc('\n', fp);
                        }
+                       break;
                }
 
                fclose(attach_fp);
@@ -4394,10 +4256,7 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
                           GTK_SIGNAL_FUNC(compose_delete_cb), compose);
        gtk_signal_connect(GTK_OBJECT(window), "destroy",
                           GTK_SIGNAL_FUNC(compose_destroy_cb), compose);
-       gtk_signal_connect(GTK_OBJECT(window), "focus_in_event",
-                          GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
-       gtk_signal_connect(GTK_OBJECT(window), "focus_out_event",
-                          GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
+       MANAGE_WINDOW_SIGNALS_CONNECT(window);
        gtk_widget_realize(window);
 
        gtkut_widget_set_composer_icon(window);
@@ -4615,23 +4474,6 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
 
        update_compose_actions_menu(ifactory, "/Edit/Actions", compose);
 
-       switch (prefs_common.toolbar_style) {
-       case TOOLBAR_NONE:
-               gtk_widget_hide(handlebox);
-               break;
-       case TOOLBAR_ICON:
-               gtk_toolbar_set_style(GTK_TOOLBAR(compose->toolbar),
-                                     GTK_TOOLBAR_ICONS);
-               break;
-       case TOOLBAR_TEXT:
-               gtk_toolbar_set_style(GTK_TOOLBAR(compose->toolbar),
-                                     GTK_TOOLBAR_TEXT);
-               break;
-       case TOOLBAR_BOTH:
-               gtk_toolbar_set_style(GTK_TOOLBAR(compose->toolbar),
-                                     GTK_TOOLBAR_BOTH);
-               break;
-       }
 
        undostruct = undo_init(text);
        undo_set_change_state_func(undostruct, &compose_undo_state_changed,
@@ -4838,6 +4680,7 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
                gtk_widget_hide(ruler_hbox);
 
        select_account(compose, account);
+       set_toolbar_style(compose);
 
        return compose;
 }
@@ -4889,7 +4732,7 @@ static void compose_toolbar_create(Compose *compose, GtkWidget *container)
 
        gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
 
-       icon_wid = stock_pixmap_widget(container, STOCK_PIXMAP_PASTE);
+       icon_wid = stock_pixmap_widget(container, STOCK_PIXMAP_INSERT_FILE);
        insert_btn = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
                                             _("Insert"),
                                             _("Insert file"),
@@ -4907,7 +4750,7 @@ static void compose_toolbar_create(Compose *compose, GtkWidget *container)
 
        gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
 
-       icon_wid = stock_pixmap_widget(container, STOCK_PIXMAP_MAIL);
+       icon_wid = stock_pixmap_widget(container, STOCK_PIXMAP_MAIL_SIGN);
        sig_btn = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
                                          _("Signature"),
                                          _("Insert signature"),
@@ -4916,7 +4759,7 @@ static void compose_toolbar_create(Compose *compose, GtkWidget *container)
 
        gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
 
-       icon_wid = stock_pixmap_widget(container, STOCK_PIXMAP_MAIL_COMPOSE);
+       icon_wid = stock_pixmap_widget(container, STOCK_PIXMAP_EDIT_EXTERN);
        exteditor_btn = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
                                                _("Editor"),
                                                _("Edit with external editor"),
@@ -5033,6 +4876,21 @@ void compose_reflect_prefs_all(void)
        }
 }
 
+void compose_reflect_prefs_pixmap_theme(void)
+{
+       GList *cur;
+       Compose *compose;
+
+       for (cur = compose_list; cur != NULL; cur = cur->next) {
+               compose = (Compose *)cur->data;
+               gtk_container_remove(GTK_CONTAINER(compose->handlebox), GTK_WIDGET(compose->toolbar));
+               compose->toolbar = NULL;
+               compose_toolbar_create(compose, compose->handlebox);
+               set_toolbar_style(compose);
+       }
+}
+
+
 static void compose_template_apply(Compose *compose, Template *tmpl)
 {
        gchar *qmark;
@@ -5368,9 +5226,15 @@ static void compose_attach_property_create(gboolean *cancelled)
 
        optmenu_menu = gtk_menu_new();
        MENUITEM_ADD(optmenu_menu, menuitem, "7bit", ENC_7BIT);
+       gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), optmenu_menu);
+#if 0
        gtk_widget_set_sensitive(menuitem, FALSE);
+#endif
        MENUITEM_ADD(optmenu_menu, menuitem, "8bit", ENC_8BIT);
+       gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), optmenu_menu);
+#if 0
        gtk_widget_set_sensitive(menuitem, FALSE);
+#endif
        MENUITEM_ADD(optmenu_menu, menuitem, "quoted-printable", ENC_QUOTED_PRINTABLE);
        gtk_widget_set_sensitive(menuitem, FALSE);
        MENUITEM_ADD(optmenu_menu, menuitem, "base64", ENC_BASE64);
@@ -5831,6 +5695,10 @@ static void toolbar_address_cb(GtkWidget *widget, gpointer data)
 
 static void select_account(Compose * compose, PrefsAccount * ac)
 {
+#if USE_GPGME
+       GtkItemFactory *ifactory;
+       GtkWidget *menuitem;
+#endif /* USE_GPGME */
        compose->account = ac;
        compose_set_title(compose);
 
@@ -5905,6 +5773,30 @@ static void select_account(Compose * compose, PrefsAccount * ac)
                }
                gtk_widget_queue_resize(compose->table_vbox);
 #endif
+#if USE_GPGME
+               ifactory = gtk_item_factory_from_widget(compose->menubar);
+                       menu_set_sensitive(ifactory,
+                                          "/Message/Sign", TRUE);
+                       menu_set_sensitive(ifactory,
+                                          "/Message/Encrypt", TRUE);
+
+                       menuitem = gtk_item_factory_get_item(ifactory, "/Message/Sign");
+               if (ac->default_sign)
+                       gtk_check_menu_item_set_active
+                               (GTK_CHECK_MENU_ITEM(menuitem), TRUE);
+               else
+                       gtk_check_menu_item_set_active
+                               (GTK_CHECK_MENU_ITEM(menuitem), FALSE);
+
+                       menuitem = gtk_item_factory_get_item(ifactory, "/Message/Encrypt");
+               if (ac->default_encrypt)
+                       gtk_check_menu_item_set_active
+                               (GTK_CHECK_MENU_ITEM(menuitem), TRUE);
+               else
+                       gtk_check_menu_item_set_active
+                               (GTK_CHECK_MENU_ITEM(menuitem), FALSE);
+#endif /* USE_GPGME */
+
 }
 
 static void account_activated(GtkMenuItem *menuitem, gpointer data)
@@ -6077,7 +5969,8 @@ static void compose_attach_cb(gpointer data, guint action, GtkWidget *widget)
 
                for ( tmp = file_list; tmp; tmp = tmp->next) {
                        gchar *file = (gchar *) tmp->data;
-                       compose_attach_append(compose, file, MIME_UNKNOWN);
+                       compose_attach_append(compose, file, file, NULL);
+                       compose_changed_cb(NULL, compose);
                        g_free(file);
                }
                g_list_free(file_list);
@@ -6500,8 +6393,10 @@ static void compose_attach_drag_received_cb (GtkWidget           *widget,
 
        list = uri_list_extract_filenames((const gchar *)data->data);
        for (tmp = list; tmp != NULL; tmp = tmp->next)
-               compose_attach_append(compose, (const gchar *)tmp->data,
-                                     MIME_UNKNOWN);
+               compose_attach_append
+                       (compose, (const gchar *)tmp->data,
+                        (const gchar *)tmp->data, NULL);
+       if (list) compose_changed_cb(NULL, compose);
        list_free_strings(list);
        g_list_free(list);
 }
@@ -6732,3 +6627,29 @@ static void compose_check_forwards_go(Compose *compose)
        }
 }
 #endif
+
+static void set_toolbar_style(Compose *compose)
+{
+       switch (prefs_common.toolbar_style) {
+       case TOOLBAR_NONE:
+               gtk_widget_hide(compose->handlebox);
+               break;
+       case TOOLBAR_ICON:
+               gtk_toolbar_set_style(GTK_TOOLBAR(compose->toolbar),
+                                     GTK_TOOLBAR_ICONS);
+               break;
+       case TOOLBAR_TEXT:
+               gtk_toolbar_set_style(GTK_TOOLBAR(compose->toolbar),
+                                     GTK_TOOLBAR_TEXT);
+               break;
+       case TOOLBAR_BOTH:
+               gtk_toolbar_set_style(GTK_TOOLBAR(compose->toolbar),
+                                     GTK_TOOLBAR_BOTH);
+               break;
+       }
+       
+       if (prefs_common.toolbar_style != TOOLBAR_NONE) {
+               gtk_widget_show(compose->handlebox);
+               gtk_widget_queue_resize(compose->handlebox);
+       }
+}