sync with 0.7.4cvs21
[claws.git] / src / compose.c
index dcb199c2e9901001a5324716128fa3414bfe45be..7d29e8df5f8e19731660d84912f2b2345478a8c6 100644 (file)
@@ -198,13 +198,14 @@ static void compose_set_title                     (Compose        *compose);
 
 static PrefsAccount *compose_current_mail_account(void);
 /* static gint compose_send                    (Compose        *compose); */
+static gboolean compose_check_for_valid_recipient
+                                               (Compose        *compose);
+static gboolean compose_check_entries          (Compose        *compose);
 static gint compose_write_to_file              (Compose        *compose,
                                                 const gchar    *file,
                                                 gboolean        is_draft);
 static gint compose_write_body_to_file         (Compose        *compose,
                                                 const gchar    *file);
-static gint compose_save_to_outbox             (Compose        *compose,
-                                                const gchar    *file);
 static gint compose_remove_reedit_target       (Compose        *compose);
 static gint compose_queue                      (Compose        *compose,
                                                 gint           *msgnum,
@@ -568,8 +569,6 @@ static GtkItemFactoryEntry compose_entries[] =
                                        "<control><alt>L", compose_wrap_line_all, 0, NULL},
        {N_("/_Edit/Edit with e_xternal editor"),
                                        "<shift><control>X", compose_ext_editor_cb, 0, NULL},
-       {N_("/_Edit/---"),              NULL, NULL, 0, "<Separator>"},
-       {N_("/_Edit/Actio_ns"),         NULL, NULL, 0, "<Branch>"},
 #if USE_PSPELL
        {N_("/_Spelling"),              NULL, NULL, 0, "<Branch>"},
        {N_("/_Spelling/_Check all or check selection"),
@@ -625,10 +624,11 @@ static GtkItemFactoryEntry compose_entries[] =
 #endif /* USE_GPGME */
        {N_("/_Message/---"),           NULL,           NULL,   0, "<Separator>"},
        {N_("/_Message/_Request Return Receipt"),       NULL, compose_toggle_return_receipt_cb, 0, "<ToggleItem>"},
-       {N_("/_Tool"),                  NULL, NULL, 0, "<Branch>"},
-       {N_("/_Tool/Show _ruler"),      NULL, compose_toggle_ruler_cb, 0, "<ToggleItem>"},
-       {N_("/_Tool/_Address book"),    "<shift><control>A", compose_address_cb , 0, NULL},
-       {N_("/_Tool/_Template"),        NULL, NULL, 0, "<Branch>"},
+       {N_("/_Tools"),                 NULL, NULL, 0, "<Branch>"},
+       {N_("/_Tools/Show _ruler"),     NULL, compose_toggle_ruler_cb, 0, "<ToggleItem>"},
+       {N_("/_Tools/_Address book"),   "<shift><control>A", compose_address_cb , 0, NULL},
+       {N_("/_Tools/_Template"),       NULL, NULL, 0, "<Branch>"},
+       {N_("/_Tools/Actio_ns"),        NULL, NULL, 0, "<Branch>"},
        {N_("/_Help"),                  NULL, NULL, 0, "<Branch>"},
        {N_("/_Help/_About"),           NULL, about_show, 0, NULL}
 };
@@ -684,7 +684,7 @@ Compose *compose_bounce(PrefsAccount *account, MsgInfo *msginfo)
        menu_set_sensitive(ifactory, "/Message/Encrypt", FALSE);
 #endif
        menu_set_sensitive(ifactory, "/Message/Request Return Receipt", FALSE);
-       menu_set_sensitive(ifactory, "/Tool/Template", FALSE);
+       menu_set_sensitive(ifactory, "/Tools/Template", FALSE);
        
        gtk_widget_set_sensitive(c->insert_btn, FALSE);
        gtk_widget_set_sensitive(c->attach_btn, FALSE);
@@ -1835,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;
        }
@@ -1881,7 +1881,7 @@ static void compose_attach_append(Compose *compose, const gchar *file,
                alertpanel_notice(_("File %s is empty."), file);
                return;
        }
-       if ((fp = fopen(file, "r")) == NULL) {
+       if ((fp = fopen(file, "rb")) == NULL) {
                alertpanel_error(_("Can't read %s."), file);
                return;
        }
@@ -2037,7 +2037,7 @@ static void compose_wrap_line(Compose *compose)
                        }
                        line_end = 1;
                } else {
-                       if (ch_len == 1 && strchr(">:#", *cbuf))
+                       if (ch_len == 1 && strchr(">|:#", *cbuf))
                                quoted = 1;
                        else if (ch_len != 1 || !isspace(*cbuf))
                                quoted = 0;
@@ -2059,7 +2059,7 @@ static void compose_wrap_line(Compose *compose)
                        }
                        line_end = 1;
                } else {
-                       if (line_end && ch_len == 1 && strchr(">:#", *cbuf))
+                       if (line_end && ch_len == 1 && strchr(">|:#", *cbuf))
                                goto compose_end; /* quoted part */
 
                        line_end = 0;
@@ -2167,9 +2167,8 @@ static guint get_indent_length(GtkSText *text, guint start_pos, guint text_len)
                GET_CHAR(i, cbuf, ch_len);
                if (ch_len > 1)
                        break;
-               /* allow space, tab, > or | */
-               if (cbuf[0] != ' ' && cbuf[0] != '\t' &&
-                   cbuf[0] != '>' && cbuf[0] != '|')
+               /* allow space, tab, >, |, : or # */
+               if (!strchr(" \t>|:#", *cbuf))
                        break;
                indent_len++;
        }
@@ -2574,6 +2573,29 @@ gboolean compose_check_for_valid_recipient(Compose *compose) {
        return recipient_found;
 }
 
+static gboolean compose_check_entries(Compose *compose)
+{
+       gchar *str;
+
+       if (compose_check_for_valid_recipient(compose) == FALSE) {
+               alertpanel_error(_("Recipient is not specified."));
+               return FALSE;
+       }
+
+       str = gtk_entry_get_text(GTK_ENTRY(compose->subject_entry));
+       if (*str == '\0') {
+               AlertValue aval;
+
+               aval = alertpanel(_("Send"),
+                                 _("Subject is empty. Send it anyway?"),
+                                 _("Yes"), _("No"), NULL);
+               if (aval != G_ALERTDEFAULT)
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
 gint compose_send(Compose *compose)
 {
        gint msgnum;
@@ -2608,8 +2630,7 @@ gint compose_send(Compose *compose)
 
        lock = TRUE;
 
-       if(!compose_check_for_valid_recipient(compose)) {
-               alertpanel_error(_("Recipient is not specified."));
+       if (compose_check_entries(compose) == FALSE) {
                lock = FALSE;
                return 1;
        }
@@ -2700,13 +2721,17 @@ gint compose_send(Compose *compose)
                                folderview_update_item
                                        (compose->targetinfo->folder, TRUE);
                }
-       }
-
-       /* save message to outbox */
-       if (ok == 0 && prefs_common.savemsg) {
-               if (compose_save_to_outbox(compose, tmp) < 0)
-                       alertpanel_error
-                               (_("Can't save the message to outbox."));
+               /* save message to outbox */
+               if (prefs_common.savemsg) {
+                       Folder *folder = FOLDER(compose->account->folder);
+                       FolderItem *outbox = NULL;
+
+                       if (folder)
+                               outbox = folder->outbox;
+                       if (procmsg_save_to_outbox(outbox, tmp, FALSE) < 0)
+                               alertpanel_error
+                                       (_("Can't save the message to outbox."));
+               }
        }
 
        unlink(tmp);
@@ -2810,12 +2835,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;
@@ -2838,20 +2863,24 @@ static gint compose_bounce_write_to_file(Compose *compose, const gchar *file)
                if (fputs(buf, fdest) == -1)
                        goto error;
 
-               if (g_strncasecmp(buf, "From:", strlen("From:")) == 0) {
-                       fputs(" (by way of ", fdest);
-                       if (compose->account->name
-                           && *compose->account->name) {
-                               compose_convert_header
-                                       (buf, sizeof(buf),
-                                        compose->account->name,
-                                        strlen("From: "));
-                               fprintf(fdest, "%s <%s>",
-                                       buf, compose->account->address);
-                       } else
-                               fprintf(fdest, "%s",
-                                       compose->account->address);
-                       fputs(")", fdest);
+               if (!prefs_common.bounce_keep_from) {
+                       if (g_strncasecmp(buf, "From:",
+                                         strlen("From:")) == 0) {
+                               fputs(" (by way of ", fdest);
+                               if (compose->account->name
+                                   && *compose->account->name) {
+                                       compose_convert_header
+                                               (buf, sizeof(buf),
+                                                compose->account->name,
+                                                strlen("From: "));
+                                       fprintf(fdest, "%s <%s>",
+                                               buf,
+                                               compose->account->address);
+                               } else
+                                       fprintf(fdest, "%s",
+                                               compose->account->address);
+                               fputs(")", fdest);
+                       }
                }
 
                if (fputs("\n", fdest) == -1)
@@ -2926,7 +2955,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;
        }
@@ -3066,7 +3095,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;
        }
@@ -3099,43 +3128,6 @@ static gint compose_write_body_to_file(Compose *compose, const gchar *file)
        return 0;
 }
 
-static gint compose_save_to_outbox(Compose *compose, const gchar *file)
-{
-       FolderItem *outbox;
-       gchar *path;
-       gint num;
-       FILE *fp;
-
-       debug_print(_("saving sent message...\n"));
-
-       outbox = folder_get_default_outbox();
-       path = folder_item_get_path(outbox);
-       if (!is_dir_exist(path))
-               make_dir_hier(path);
-
-       folder_item_scan(outbox);
-       if ((num = folder_item_add_msg(outbox, file, FALSE)) < 0) {
-               g_free(path);
-               g_warning(_("can't save message\n"));
-               return -1;
-       }
-
-       if ((fp = procmsg_open_mark_file(path, TRUE)) == NULL)
-               g_warning(_("can't open mark file\n"));
-       else {
-               MsgInfo newmsginfo;
-
-               newmsginfo.msgnum = num;
-               newmsginfo.flags.perm_flags = 0;
-               newmsginfo.flags.tmp_flags = 0;
-               procmsg_write_flags(&newmsginfo, fp);
-               fclose(fp);
-       }
-       g_free(path);
-
-       return 0;
-}
-
 static gint compose_remove_reedit_target(Compose *compose)
 {
        FolderItem *item;
@@ -3177,12 +3169,17 @@ static gint compose_queue(Compose *compose, gint *msgnum, FolderItem **item)
 
         lock = TRUE;
        
-        if(!compose_check_for_valid_recipient(compose)) {
+/*        if(!compose_check_for_valid_recipient(compose)) {
                 alertpanel_error(_("Recipient is not specified."));
                 lock = FALSE;
                 return -1;
-        }
+        } */
                                                                        
+       if (compose_check_entries(compose) == FALSE) {
+                lock = FALSE;
+                return -1;
+       }
+
        if (!compose->to_list && !compose->newsgroup_list) {
                g_warning(_("can't get recipient list."));
                lock = FALSE;
@@ -3237,13 +3234,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);
@@ -3335,9 +3332,12 @@ static gint compose_queue(Compose *compose, gint *msgnum, FolderItem **item)
                g_free(tmp2);
                return -1;
        }
-                                               
-       /* queue message */
-       queue = folder_get_default_queue();
+
+       if (compose->account->folder &&
+           FOLDER(compose->account->folder)->queue)
+               queue = FOLDER(compose->account->folder)->queue;
+       else
+               queue = folder_get_default_queue();
 
        folder_item_scan(queue);
        queue_path = folder_item_get_path(queue);
@@ -3398,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;
                }
@@ -3421,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))
@@ -3443,6 +3450,7 @@ static void compose_write_attach(Compose *compose, FILE *fp)
                                fputs(outbuf, fp);
                                fputc('\n', fp);
                        }
+                       break;
                }
 
                fclose(attach_fp);
@@ -4436,7 +4444,7 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        menu_set_sensitive(ifactory, "/Edit/Undo", FALSE);
        menu_set_sensitive(ifactory, "/Edit/Redo", FALSE);
 
-       tmpl_menu = gtk_item_factory_get_item(ifactory, "/Tool/Template");
+       tmpl_menu = gtk_item_factory_get_item(ifactory, "/Tools/Template");
 #if 0 /* NEW COMPOSE GUI */
        gtk_widget_hide(bcc_hbox);
        gtk_widget_hide(bcc_entry);
@@ -4464,7 +4472,7 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        }
 #endif
 
-       update_compose_actions_menu(ifactory, "/Edit/Actions", compose);
+       update_compose_actions_menu(ifactory, "/Tools/Actions", compose);
 
 
        undostruct = undo_init(text);
@@ -5214,13 +5222,19 @@ static void compose_attach_property_create(gboolean *cancelled)
                         GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
 
        optmenu = gtk_option_menu_new();
-       gtk_box_pack_start(GTK_BOX(hbox), optmenu, FALSE, FALSE, 0);
+       gtk_box_pack_start(GTK_BOX(hbox), optmenu, TRUE, TRUE, 0);
 
        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);
@@ -5681,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);
 
@@ -5755,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)
@@ -5848,7 +5890,11 @@ static void compose_draft_cb(gpointer data, guint action, GtkWidget *widget)
 
        if (lock) return;
 
-       draft = folder_get_default_draft();
+       if (compose->account && compose->account->folder &&
+           FOLDER(compose->account->folder)->draft)
+               draft = FOLDER(compose->account->folder)->draft;
+       else
+               draft = folder_get_default_draft();
        g_return_if_fail(draft != NULL);
 
        lock = TRUE;
@@ -5863,7 +5909,7 @@ static void compose_draft_cb(gpointer data, guint action, GtkWidget *widget)
        }
 
        folder_item_scan(draft);
-       if ((msgnum = folder_item_add_msg(draft, tmp, TRUE)) <= 0) {
+       if ((msgnum = folder_item_add_msg(draft, tmp, TRUE)) < 0) {
                unlink(tmp);
                g_free(tmp);
                lock = FALSE;