2006-06-17 [colin] 2.3.0cvs20
[claws.git] / src / mh.c
index 92e97b191138f570392432605f83edfecd6e9805..76a603c159dc68556fd3be11785fdccfb385af57 100644 (file)
--- a/src/mh.c
+++ b/src/mh.c
@@ -43,6 +43,8 @@
 #include "procheader.h"
 #include "utils.h"
 #include "codeconv.h"
+#include "statusbar.h"
+#include "gtkutils.h"
 
 /* Define possible missing constants for Windows. */
 #ifdef G_OS_WIN32
@@ -88,6 +90,10 @@ static gint  mh_copy_msgs            (Folder         *folder,
 static gint     mh_remove_msg          (Folder         *folder,
                                         FolderItem     *item,
                                         gint            num);
+static gint    mh_remove_msgs          (Folder         *folder, 
+                                        FolderItem     *item, 
+                                        MsgInfoList    *msglist, 
+                                        GRelation      *relation);
 static gint     mh_remove_all_msg      (Folder         *folder,
                                         FolderItem     *item);
 static gboolean mh_is_msg_changed      (Folder         *folder,
@@ -128,9 +134,11 @@ static gboolean mh_scan_required   (Folder         *folder,
                                         FolderItem     *item);
 static int mh_item_close               (Folder         *folder,
                                         FolderItem     *item);
+#if 0
 static gint mh_get_flags               (Folder *folder, FolderItem *item,
                                         MsgInfoList *msginfo_list, GRelation *msgflags);
-static void mh_write_sequences         (FolderItem     *item);
+#endif
+static void mh_write_sequences         (FolderItem     *item, gboolean remove_unseen);
 
 static FolderClass mh_class;
 
@@ -157,7 +165,7 @@ FolderClass *mh_get_class(void)
                mh_class.get_num_list = mh_get_num_list;
                mh_class.scan_required = mh_scan_required;
                mh_class.close = mh_item_close;
-               mh_class.get_flags = mh_get_flags;
+               mh_class.get_flags = NULL; /*mh_get_flags */;
 
                /* Message functions */
                mh_class.get_msginfo = mh_get_msginfo;
@@ -167,6 +175,7 @@ FolderClass *mh_get_class(void)
                mh_class.copy_msg = mh_copy_msg;
                mh_class.copy_msgs = mh_copy_msgs;
                mh_class.remove_msg = mh_remove_msg;
+               mh_class.remove_msgs = mh_remove_msgs;
                mh_class.remove_all_msg = mh_remove_all_msg;
                mh_class.is_msg_changed = mh_is_msg_changed;
        }
@@ -331,7 +340,8 @@ static MsgInfo *mh_get_msginfo(Folder *folder, FolderItem *item, gint num)
        gchar *file;
 
        g_return_val_if_fail(item != NULL, NULL);
-       g_return_val_if_fail(num > 0, NULL);
+       if (num <= 0)
+               return NULL;
 
        file = mh_fetch_msg(folder, item, num);
        if (!file) return NULL;
@@ -428,7 +438,7 @@ static gint mh_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
                g_free(destfile);
                dest->last_num++;
        }
-       mh_write_sequences(dest);
+       mh_write_sequences(dest, TRUE);
        return dest->last_num;
 }
 
@@ -453,8 +463,11 @@ static gint mh_copy_msgs(Folder *folder, FolderItem *dest, MsgInfoList *msglist,
        gint filemode = 0;
        FolderItemPrefs *prefs;
        MsgInfo *msginfo = NULL;
-       gboolean remove_special_headers = FALSE;
        MsgInfoList *cur = NULL;
+       gint curnum = 0, total = 0;
+       gchar *srcpath = NULL;
+       gboolean full_fetch = FALSE;
+
        g_return_val_if_fail(dest != NULL, -1);
        g_return_val_if_fail(msglist != NULL, -1);
        
@@ -467,35 +480,51 @@ static gint mh_copy_msgs(Folder *folder, FolderItem *dest, MsgInfoList *msglist,
                return -1;
        }
 
+       if (msginfo->folder->folder != dest->folder)
+               full_fetch = TRUE;
+
        if (dest->last_num < 0) {
                mh_get_last_num(folder, dest);
                if (dest->last_num < 0) return -1;
        }
 
-       if ((MSG_IS_QUEUED(msginfo->flags) || MSG_IS_DRAFT(msginfo->flags))
-       && !folder_has_parent_of_type(dest, F_QUEUE)
-       && !folder_has_parent_of_type(dest, F_DRAFT)) {
-               /* as every msginfo comes from the same folder, it is supposed they
-                * will either match the preceding condition either all or none.
-                */
-               remove_special_headers = TRUE;
-       } else if (!(MSG_IS_QUEUED(msginfo->flags) || MSG_IS_DRAFT(msginfo->flags))
-       && (folder_has_parent_of_type(dest, F_QUEUE)
-        || folder_has_parent_of_type(dest, F_DRAFT))) {
-               return -1;
-       } 
-
        prefs = dest->prefs;
 
+       srcpath = folder_item_get_path(msginfo->folder);
+
+       total = g_slist_length(msglist);
+       if (total > 100) {
+               if (MSG_IS_MOVE(msginfo->flags))
+                       statusbar_print_all(_("Moving messages..."));
+               else
+                       statusbar_print_all(_("Copying messages..."));
+       }
        for (cur = msglist; cur; cur = cur->next) {
                msginfo = (MsgInfo *)cur->data;
-               if (!msginfo)
-                       continue;
-               srcfile = procmsg_get_message_file(msginfo);
+               if (!msginfo) {
+                       goto err_reset_status;
+               }
+               if (!full_fetch) {
+                       srcfile = g_strconcat(srcpath, 
+                               G_DIR_SEPARATOR_S, 
+                               itos(msginfo->msgnum), NULL);
+               } else {
+                       srcfile = procmsg_get_message_file(msginfo);
+               }
+               if (!srcfile) {
+                       goto err_reset_status;
+               }
                destfile = mh_get_new_msg_filename(dest);
                if (!destfile) {
                        g_free(srcfile);
-                       continue;
+                       goto err_reset_status;
+               }
+
+               if (total > 100) {
+                       statusbar_progress_all(curnum, total, 100);
+                       if (curnum % 100 == 0)
+                               GTK_EVENTS_FLUSH();
+                       curnum++;
                }
 
                debug_print("Copying message %s%c%d to %s ...\n",
@@ -503,18 +532,22 @@ static gint mh_copy_msgs(Folder *folder, FolderItem *dest, MsgInfoList *msglist,
                            msginfo->msgnum, dest->path);
 
 
-               if (remove_special_headers) {
-                       if (procmsg_remove_special_headers(srcfile, destfile) !=0) {
-                               g_free(srcfile);
-                               g_free(destfile);
-                               continue;
+               if (MSG_IS_MOVE(msginfo->flags)) {
+                       if (move_file(srcfile, destfile, TRUE) < 0) {
+                               FILE_OP_ERROR(srcfile, "move");
+                               if (copy_file(srcfile, destfile, TRUE) < 0) {
+                                       FILE_OP_ERROR(srcfile, "copy");
+                                       g_free(srcfile);
+                                       g_free(destfile);
+                                       goto err_reset_status;
+                               }
                        }
                } else if (copy_file(srcfile, destfile, TRUE) < 0) {
                        FILE_OP_ERROR(srcfile, "copy");
                        g_free(srcfile);
                        g_free(destfile);
-                       continue;
-               }
+                       goto err_reset_status;
+               } 
                if (prefs && prefs->enable_folder_chmod && prefs->folder_chmod) {
                        if (chmod(destfile, prefs->folder_chmod) < 0)
                                FILE_OP_ERROR(destfile, "chmod");
@@ -531,13 +564,27 @@ static gint mh_copy_msgs(Folder *folder, FolderItem *dest, MsgInfoList *msglist,
                dest->last_num++;
        }
 
+       g_free(srcpath);
+       mh_write_sequences(dest, TRUE);
+
        dest_need_scan = mh_scan_required(dest->folder, dest);
        if (!dest_need_scan)
                dest->mtime = time(NULL);
-       else
-               mh_write_sequences(dest);
-
+       
+       if (total > 100) {
+               statusbar_progress_all(0,0,0);
+               statusbar_pop_all();
+       }
        return dest->last_num;
+err_reset_status:
+       g_free(srcpath);
+       mh_write_sequences(dest, TRUE);
+       if (total > 100) {
+               statusbar_progress_all(0,0,0);
+               statusbar_pop_all();
+       }
+       return -1;
+
 }
 
 static gint mh_remove_msg(Folder *folder, FolderItem *item, gint num)
@@ -565,6 +612,42 @@ static gint mh_remove_msg(Folder *folder, FolderItem *item, gint num)
        return 0;
 }
 
+static gint mh_remove_msgs(Folder *folder, FolderItem *item, 
+                   MsgInfoList *msglist, GRelation *relation)
+{
+       gboolean need_scan = FALSE;
+       gchar *path, *file;
+       MsgInfoList *cur;
+
+       g_return_val_if_fail(item != NULL, -1);
+
+       path = folder_item_get_path(item);
+       
+       for (cur = msglist; cur; cur = cur->next) {
+               MsgInfo *msginfo = (MsgInfo *)cur->data;
+               if (msginfo == NULL)
+                       continue;
+               file = g_strconcat(path, G_DIR_SEPARATOR_S, itos(msginfo->msgnum), NULL);
+               if (file == NULL)
+                       continue;
+               
+               if (g_unlink(file) < 0) {
+                       g_free(file);
+                       continue;
+               }
+               
+               g_free(file);
+       }
+
+       need_scan = mh_scan_required(folder, item);
+
+       if (!need_scan)
+               item->mtime = time(NULL);
+
+       g_free(path);
+       return 0;
+}
+
 static gint mh_remove_all_msg(Folder *folder, FolderItem *item)
 {
        gchar *path;
@@ -577,7 +660,7 @@ static gint mh_remove_all_msg(Folder *folder, FolderItem *item)
        val = remove_all_numbered_files(path);
        g_free(path);
 
-       mh_write_sequences(item);
+       mh_write_sequences(item, TRUE);
 
        return val;
 }
@@ -1077,7 +1160,7 @@ static gchar *get_unseen_seq_name(void)
                gchar buf[BUFFSIZE];
                gchar *tmp;
                gchar *profile_path = g_strconcat(
-                       g_get_home_dir(), G_DIR_SEPARATOR_S,
+                       get_home_dir(), G_DIR_SEPARATOR_S,
                        ".mh_profile", NULL);
                FILE *fp = g_fopen(profile_path, "r");
                if (fp) {
@@ -1102,6 +1185,7 @@ static gchar *get_unseen_seq_name(void)
        return seq_name;        
 }
 
+#if 0
 static gint mh_get_flags(Folder *folder, FolderItem *item,
                            MsgInfoList *msginfo_list, GRelation *msgflags)
 {
@@ -1117,6 +1201,12 @@ static gint mh_get_flags(Folder *folder, FolderItem *item,
 */
        if (!item)
                return 0;
+
+       /* don't update from .mh_sequences if the item's opened: mails may have
+        * been marked read/unread and it's not yet written in the file. */     
+       if (item->opened)
+               return 0;
+
        path = folder_item_get_path(item);
 
        mh_sequences_filename = g_strconcat(path, G_DIR_SEPARATOR_S,
@@ -1131,6 +1221,9 @@ static gint mh_get_flags(Folder *folder, FolderItem *item,
                }
                fclose(mh_sequences_file);
        }
+       
+       g_free(mh_sequences_filename);
+       
        if (unseen_list) {
                gchar *cur = NULL;
                gchar *token = NULL, *next = NULL, *boundary = NULL;
@@ -1188,8 +1281,9 @@ next_token:
 */
        return 0;
 }
+#endif
 
-static void mh_write_sequences(FolderItem *item)
+static void mh_write_sequences(FolderItem *item, gboolean remove_unseen)
 {
        gchar *mh_sequences_old, *mh_sequences_new;
        FILE *mh_sequences_old_fp, *mh_sequences_new_fp;
@@ -1217,8 +1311,8 @@ static void mh_write_sequences(FolderItem *item)
                msglist = g_slist_sort(msglist, sort_cache_list_by_msgnum);
                cur = msglist;
                
-               /* write the unseen sequence */
-               do {
+               /* write the unseen sequence if we don't have to scrap it */
+               if (!remove_unseen) do {
                        info = (MsgInfo *)(cur ? cur->data:NULL);
                        if (info && (MSG_IS_UNREAD(info->flags) || MSG_IS_NEW(info->flags))) {
                                if (start < 0)
@@ -1270,6 +1364,6 @@ static void mh_write_sequences(FolderItem *item)
 
 static int mh_item_close(Folder *folder, FolderItem *item)
 {
-       mh_write_sequences(item);
+       mh_write_sequences(item, FALSE);
        return 0;
 }