sync with HEAD
[claws.git] / src / folder.c
index 94f0d1fa3daf2414ebf41b18e1a36c29d5fde3ae..0b363f0027eddacdeeaa7c0d0ea051b74d6485bc 100644 (file)
@@ -48,6 +48,7 @@
 #include "log.h"
 #include "folder_item_prefs.h"
 #include "remotefolder.h"
+#include "partial_download.h"
 
 /* Dependecies to be removed ?! */
 #include "prefs_common.h"
@@ -235,18 +236,18 @@ XMLTag *folder_get_xml(Folder *folder)
 {
        XMLTag *tag;
 
-       tag = xml_new_tag("folder");
+       tag = xml_tag_new("folder");
 
        if (folder->name)
-               xml_tag_add_attr(tag, "name", g_strdup(folder->name));
+               xml_tag_add_attr(tag, xml_attr_new("name", folder->name));
        if (folder->account)
-               xml_tag_add_attr(tag, "account_id", g_strdup_printf("%d", folder->account->account_id));
+               xml_tag_add_attr(tag, xml_attr_new_int("account_id", folder->account->account_id));
        if (folder->node && folder->node->data) {
                FolderItem *rootitem = (FolderItem *) folder->node->data;
 
-               xml_tag_add_attr(tag, "collapsed", g_strdup(rootitem->collapsed ? "1" : "0"));
+               xml_tag_add_attr(tag, xml_attr_new("collapsed", rootitem->collapsed ? "1" : "0"));
        }
-       xml_tag_add_attr(tag, "sort", g_strdup_printf("%d", folder->sort));
+       xml_tag_add_attr(tag, xml_attr_new_int("sort", folder->sort));
 
        return tag;
 }
@@ -510,40 +511,43 @@ XMLTag *folder_item_get_xml(Folder *folder, FolderItem *item)
                                        "mark", "unread", "mime", "to", 
                                        "locked"};
        XMLTag *tag;
+       gchar *value;
 
-       tag = xml_new_tag("folderitem");
+       tag = xml_tag_new("folderitem");
 
-       xml_tag_add_attr(tag, "type", g_strdup(folder_item_stype_str[item->stype]));
+       xml_tag_add_attr(tag, xml_attr_new("type", folder_item_stype_str[item->stype]));
        if (item->name)
-               xml_tag_add_attr(tag, "name", g_strdup(item->name));
+               xml_tag_add_attr(tag, xml_attr_new("name", item->name));
        if (item->path)
-               xml_tag_add_attr(tag, "path", g_strdup(item->path));
+               xml_tag_add_attr(tag, xml_attr_new("path", item->path));
        if (item->no_sub)
-               xml_tag_add_attr(tag, "no_sub", g_strdup("1"));
+               xml_tag_add_attr(tag, xml_attr_new("no_sub", "1"));
        if (item->no_select)
-               xml_tag_add_attr(tag, "no_select", g_strdup("1"));
-       xml_tag_add_attr(tag, "collapsed", g_strdup(item->collapsed && item->node->children ? "1" : "0"));
-       xml_tag_add_attr(tag, "thread_collapsed", g_strdup(item->thread_collapsed ? "1" : "0"));
-       xml_tag_add_attr(tag, "threaded", g_strdup(item->threaded ? "1" : "0"));
-       xml_tag_add_attr(tag, "hidereadmsgs", g_strdup(item->hide_read_msgs ? "1" : "0"));
+               xml_tag_add_attr(tag, xml_attr_new("no_select", "1"));
+       xml_tag_add_attr(tag, xml_attr_new("collapsed", item->collapsed && item->node->children ? "1" : "0"));
+       xml_tag_add_attr(tag, xml_attr_new("thread_collapsed", item->thread_collapsed ? "1" : "0"));
+       xml_tag_add_attr(tag, xml_attr_new("threaded", item->threaded ? "1" : "0"));
+       xml_tag_add_attr(tag, xml_attr_new("hidereadmsgs", item->hide_read_msgs ? "1" : "0"));
        if (item->ret_rcpt)
-               xml_tag_add_attr(tag, "reqretrcpt", g_strdup("1"));
+               xml_tag_add_attr(tag, xml_attr_new("reqretrcpt", "1"));
 
        if (item->sort_key != SORT_BY_NONE) {
-               xml_tag_add_attr(tag, "sort_key", g_strdup(sort_key_str[item->sort_key]));
-               xml_tag_add_attr(tag, "sort_type", g_strdup(item->sort_type == SORT_ASCENDING ? "ascending" : "descending"));
+               xml_tag_add_attr(tag, xml_attr_new("sort_key", sort_key_str[item->sort_key]));
+               xml_tag_add_attr(tag, xml_attr_new("sort_type", item->sort_type == SORT_ASCENDING ? "ascending" : "descending"));
        }
 
-       xml_tag_add_attr(tag, "mtime", g_strdup_printf("%ld", (unsigned long int) item->mtime));
-       xml_tag_add_attr(tag, "new", g_strdup_printf("%d", item->new_msgs));
-       xml_tag_add_attr(tag, "unread", g_strdup_printf("%d", item->unread_msgs));
-       xml_tag_add_attr(tag, "unreadmarked", g_strdup_printf("%d", item->unreadmarked_msgs));
-       xml_tag_add_attr(tag, "total", g_strdup_printf("%d", item->total_msgs));
+       value = g_strdup_printf("%ld", (unsigned long int) item->mtime);
+       xml_tag_add_attr(tag, xml_attr_new("mtime", value));
+       g_free(value);
+       xml_tag_add_attr(tag, xml_attr_new_int("new", item->new_msgs));
+       xml_tag_add_attr(tag, xml_attr_new_int("unread", item->unread_msgs));
+       xml_tag_add_attr(tag, xml_attr_new_int("unreadmarked", item->unreadmarked_msgs));
+       xml_tag_add_attr(tag, xml_attr_new_int("total", item->total_msgs));
 
        if (item->account)
-               xml_tag_add_attr(tag, "account_id", g_strdup_printf("%d", item->account->account_id));
+               xml_tag_add_attr(tag, xml_attr_new_int("account_id", item->account->account_id));
        if (item->apply_sub)
-               xml_tag_add_attr(tag, "apply_sub", g_strdup("1"));
+               xml_tag_add_attr(tag, xml_attr_new("apply_sub", "1"));
 
        return tag;
 }
@@ -700,13 +704,10 @@ void folder_write_list(void)
        path = folder_get_list_path();
        if ((pfile = prefs_write_open(path)) == NULL) return;
 
-       fprintf(pfile->fp, "<?xml version=\"1.0\" encoding=\"%s\"?>\n",
-               conv_get_current_charset_str());
-       tag = xml_new_tag("folderlist");
+       xml_file_put_xml_decl(pfile->fp);
+       tag = xml_tag_new("folderlist");
 
-       xmlnode = g_new0(XMLNode, 1);
-       xmlnode->tag = tag;
-       xmlnode->element = NULL;
+       xmlnode = xml_node_new(tag, NULL);
 
        rootnode = g_node_new(xmlnode);
 
@@ -1095,8 +1096,8 @@ gchar *folder_get_identifier(Folder *folder)
 
 gchar *folder_item_get_identifier(FolderItem *item)
 {
-       gchar *id;
-       gchar *folder_id;
+       gchar *id = NULL;
+       gchar *folder_id = NULL;
 
        g_return_val_if_fail(item != NULL, NULL);
        g_return_val_if_fail(item->path != NULL, NULL);
@@ -1579,21 +1580,30 @@ gint folder_item_scan_full(FolderItem *item, gboolean filtering)
        guint newcnt = 0, unreadcnt = 0, totalcnt = 0, unreadmarkedcnt = 0;
        guint cache_max_num, folder_max_num, cache_cur_num, folder_cur_num;
        gboolean update_flags = 0, old_uids_valid = FALSE;
-    
-       g_return_val_if_fail(item != NULL, -1);
-       if (item->path == NULL) return -1;
+       gint err = -1;
+#ifdef USE_GPGME
+       gint old_auto_check = 0;
+       old_auto_check = prefs_common.auto_check_signatures;
+       prefs_common.auto_check_signatures = 0;
+#endif
+       if (item == NULL)
+               goto bail_scan;
+       if (item->path == NULL)
+               goto bail_scan;
 
        folder = item->folder;
 
-       g_return_val_if_fail(folder != NULL, -1);
-       g_return_val_if_fail(folder->klass->get_num_list != NULL, -1);
+       if (folder == NULL)
+               goto bail_scan;
+       if (folder->klass->get_num_list == NULL)
+               goto bail_scan;
 
        debug_print("Scanning folder %s for cache changes.\n", item->path);
 
        /* Get list of messages for folder and cache */
        if (folder->klass->get_num_list(item->folder, item, &folder_list, &old_uids_valid) < 0) {
                debug_print("Error fetching list of message numbers\n");
-               return(-1);
+               goto bail_scan;
        }
 
        if (old_uids_valid) {
@@ -1806,8 +1816,12 @@ gint folder_item_scan_full(FolderItem *item, gboolean filtering)
 
        folder_item_update(item, update_flags);
        folder_item_update_thaw();
-
-       return 0;
+       err = 0;
+bail_scan:
+#ifdef USE_GPGME
+       prefs_common.auto_check_signatures = old_auto_check;
+#endif
+       return err;
 }
 
 gint folder_item_syncronize_flags(FolderItem *item)
@@ -1984,10 +1998,33 @@ void folder_item_read_cache(FolderItem *item)
                mark_file = folder_item_get_mark_file(item);
                item->cache = msgcache_read_cache(item, cache_file);
                if (!item->cache) {
+                       MsgInfoList *list, *cur;
+                       guint newcnt = 0, unreadcnt = 0, unreadmarkedcnt = 0;
+                       MsgInfo *msginfo;
+
                        item->cache = msgcache_new();
                        folder_item_scan_full(item, TRUE);
-               }
-               msgcache_read_mark(item->cache, mark_file);
+
+                       msgcache_read_mark(item->cache, mark_file);
+
+                       list = msgcache_get_msg_list(item->cache);
+                       for (cur = list; cur != NULL; cur = g_slist_next(cur)) {
+                               msginfo = cur->data;
+
+                               if (MSG_IS_NEW(msginfo->flags))
+                                       newcnt++;
+                               if (MSG_IS_UNREAD(msginfo->flags))
+                                       unreadcnt++;
+                               if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
+                                       unreadmarkedcnt++;
+                       }
+                       item->new_msgs = newcnt;
+                       item->unread_msgs = unreadcnt;
+                       item->unreadmarked_msgs = unreadmarkedcnt;
+                       procmsg_msg_list_free(list);
+               } else
+                       msgcache_read_mark(item->cache, mark_file);
+
                g_free(cache_file);
                g_free(mark_file);
        } else {
@@ -2383,7 +2420,12 @@ FolderItem *folder_item_move_recursive(FolderItem *src, FolderItem *dest)
        FolderItem *next_item;
        GNode *srcnode;
        gchar *old_id, *new_id;
-
+       gint err = 1;
+#ifdef USE_GPGME
+       gint old_auto_check = 0;
+       old_auto_check = prefs_common.auto_check_signatures;
+       prefs_common.auto_check_signatures = 0;
+#endif
        mlist = folder_item_get_msg_list(src);
 
        /* move messages */
@@ -2391,7 +2433,7 @@ FolderItem *folder_item_move_recursive(FolderItem *src, FolderItem *dest)
        new_item = folder_create_folder(dest, src->name);
        if (new_item == NULL) {
                printf("Can't create folder\n");
-               return NULL;
+               goto bail_move;
        }
        
        if (new_item->folder == NULL)
@@ -2424,7 +2466,7 @@ FolderItem *folder_item_move_recursive(FolderItem *src, FolderItem *dest)
                        next_item = (FolderItem*) srcnode->data;
                        srcnode = srcnode->next;
                        if (folder_item_move_recursive(next_item, new_item) == NULL)
-                               return NULL;
+                               goto bail_move;
                }
        }
        old_id = folder_item_get_identifier(src);
@@ -2440,8 +2482,17 @@ FolderItem *folder_item_move_recursive(FolderItem *src, FolderItem *dest)
                prefs_filtering_rename_path(old_id, new_id);
        g_free(old_id);
        g_free(new_id);
+       err = 0;
 
-       return new_item;
+bail_move:
+#ifdef USE_GPGME
+       prefs_common.auto_check_signatures = old_auto_check;
+#endif
+
+       if (err != 0)
+               return NULL;
+       else
+               return new_item;
 }
 
 gint folder_item_move_to(FolderItem *src, FolderItem *dest, FolderItem **new_item)
@@ -2523,6 +2574,17 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
        g_relation_index(relation, 0, g_direct_hash, g_direct_equal);
        g_relation_index(relation, 1, g_direct_hash, g_direct_equal);
 
+       for (l = msglist ; l != NULL ; l = g_slist_next(l)) {
+               MsgInfo * msginfo = (MsgInfo *) l->data;
+
+               if (msginfo->planned_download != 0) {
+                       int old_planned = msginfo->planned_download;
+                       partial_unmark(msginfo);
+                       /* little hack to reenable after */
+                       msginfo->planned_download = old_planned;
+               }
+       }
+
        /* 
         * Copy messages to destination folder and 
         * store new message numbers in newmsgnums
@@ -2570,17 +2632,26 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
                                        if (newmsginfo != NULL) {
                                                copy_msginfo_flags(msginfo, newmsginfo);
                                                num = newmsginfo->msgnum;
-                                               procmsg_msginfo_free(newmsginfo);
                                        }
                                }
                        } else {
                                newmsginfo = get_msginfo(dest, num);
                                if (newmsginfo != NULL) {
                                        add_msginfo_to_cache(dest, newmsginfo, msginfo);
-                                       procmsg_msginfo_free(newmsginfo);
                                }
                        }
 
+                       if (msginfo->planned_download 
+                           == POP3_PARTIAL_DLOAD_DELE) {
+                               partial_mark_for_delete(newmsginfo);
+                       }
+                       if (msginfo->planned_download 
+                           == POP3_PARTIAL_DLOAD_DLOAD) {
+                               partial_mark_for_download(newmsginfo);
+                       }
+                       procmsg_msginfo_free(newmsginfo);
+
+
                        if (num > lastnum)
                                lastnum = num;
                }
@@ -2927,7 +2998,6 @@ static gchar *folder_get_list_path(void)
 static gpointer folder_item_to_xml(gpointer nodedata, gpointer data)
 {
        FolderItem *item = (FolderItem *) nodedata;
-       XMLNode *xmlnode;
        XMLTag *tag;
 
        g_return_val_if_fail(item != NULL, NULL);
@@ -2937,11 +3007,7 @@ static gpointer folder_item_to_xml(gpointer nodedata, gpointer data)
        else
                tag = folder_item_get_xml(item->folder, item);
 
-       xmlnode = g_new0(XMLNode, 1);
-       xmlnode->tag = tag;
-       xmlnode->element = NULL;
-
-       return xmlnode;
+       return xml_node_new(tag, NULL);;
 }
 
 static GNode *folder_get_xml_node(Folder *folder)
@@ -2957,11 +3023,9 @@ static GNode *folder_get_xml_node(Folder *folder)
        else
                tag = folder_get_xml(folder);
 
-       xml_tag_add_attr(tag, "type", g_strdup(folder->klass->idstr));
+       xml_tag_add_attr(tag, xml_attr_new("type", folder->klass->idstr));
 
-       xmlnode = g_new0(XMLNode, 1);
-       xmlnode->tag = tag;
-       xmlnode->element = NULL;
+       xmlnode = xml_node_new(tag, NULL);
 
        node = g_node_new(xmlnode);
        if (folder->node->children) {
@@ -3241,7 +3305,7 @@ static gint folder_item_update_freeze_cnt = 0;
 
 static void folder_item_update_with_msg(FolderItem *item, FolderItemUpdateFlags update_flags, MsgInfo *msg)
 {
-       if (folder_item_update_freeze_cnt == 0 || (msg != NULL && item->opened)) {
+       if (folder_item_update_freeze_cnt == 0 /* || (msg != NULL && item->opened) */) {
                FolderItemUpdateData source;
        
                source.item = item;