0.8.8claws63
[claws.git] / src / folder.c
index c45394b844cdc55073cf19ed862e1a368e2ac1f3..bfac64ba4f6c1969168a1ad7d280aa5710865d30 100644 (file)
 #include "utils.h"
 #include "xml.h"
 #include "codeconv.h"
-#include "prefs.h"
+#include "prefs_gtk.h"
 #include "account.h"
 #include "filtering.h"
 #include "scoring.h"
 #include "prefs_folder_item.h"
 #include "procheader.h"
-#include "statusbar.h"
 #include "hooks.h"
+#include "log.h"
 
 /* Dependecies to be removed ?! */
 #include "prefs_common.h"
@@ -417,7 +417,7 @@ void folder_write_list(void)
 
        fputs("</folderlist>\n", pfile->fp);
 
-       if (prefs_write_close(pfile) < 0)
+       if (prefs_file_close(pfile) < 0)
                g_warning("failed to write folder list.\n");
 }
 
@@ -989,8 +989,7 @@ void folder_item_close(FolderItem *item)
 
        folder_item_write_cache(item);
        
-       folder_update_item(item, FALSE);
-
+       folder_item_update(item, F_ITEM_UPDATE_MSGCNT);
 }
 
 gint folder_item_scan(FolderItem *item)
@@ -999,7 +998,7 @@ gint folder_item_scan(FolderItem *item)
        GSList *folder_list = NULL, *cache_list = NULL, *folder_list_cur, *cache_list_cur, *new_list = NULL;
        guint newcnt = 0, unreadcnt = 0, totalcnt = 0, unreadmarkedcnt = 0;
        guint cache_max_num, folder_max_num, cache_cur_num, folder_cur_num;
-       gboolean contentchange = FALSE;
+       gboolean update_flags = 0;
     
        g_return_val_if_fail(item != NULL, -1);
        if (item->path == NULL) return -1;
@@ -1099,8 +1098,6 @@ gint folder_item_scan(FolderItem *item)
                        else
                                folder_cur_num = G_MAXINT;
 
-                       contentchange = TRUE;
-
                        continue;
                }
 
@@ -1120,7 +1117,7 @@ gint folder_item_scan(FolderItem *item)
                        else
                                cache_cur_num = G_MAXINT;
 
-                       contentchange = TRUE;
+                       update_flags |= F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT;
 
                        continue;
                }
@@ -1146,6 +1143,8 @@ gint folder_item_scan(FolderItem *item)
                                                unreadcnt++;
                                        if (MSG_IS_UNREAD(newmsginfo->flags) && procmsg_msg_has_marked_parent(newmsginfo))
                                                unreadmarkedcnt++;
+                                       if (procmsg_msg_has_flagged_parent(newmsginfo, MSG_IGNORE_THREAD))
+                                               procmsg_msginfo_set_flags(newmsginfo, MSG_IGNORE_THREAD, 0);
                                        procmsg_msginfo_free(newmsginfo);
                                }                                       
 
@@ -1157,6 +1156,8 @@ gint folder_item_scan(FolderItem *item)
                                        unreadcnt++;
                                if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
                                        unreadmarkedcnt++;
+                               if (!MSG_IS_IGNORE_THREAD(msginfo->flags) && procmsg_msg_has_flagged_parent(msginfo, MSG_IGNORE_THREAD))
+                                       procmsg_msginfo_set_flags(msginfo, MSG_IGNORE_THREAD, 0);
                        }
                        totalcnt++;
                        procmsg_msginfo_free(msginfo);
@@ -1175,7 +1176,7 @@ gint folder_item_scan(FolderItem *item)
                        else
                                folder_cur_num = G_MAXINT;
 
-                       contentchange = TRUE;
+                       update_flags |= F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT;
 
                        continue;
                }
@@ -1204,8 +1205,12 @@ gint folder_item_scan(FolderItem *item)
                                        unreadcnt++;
                                if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
                                        unreadmarkedcnt++;
+                               if (procmsg_msg_has_flagged_parent(msginfo, MSG_IGNORE_THREAD))
+                                       procmsg_msginfo_set_flags(msginfo, MSG_IGNORE_THREAD, 0);
                                totalcnt++;
                                procmsg_msginfo_free(msginfo);
+
+                               update_flags |= F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT;
                        }
                        g_slist_free(newmsg_list);
                }
@@ -1226,10 +1231,14 @@ gint folder_item_scan(FolderItem *item)
                                    unreadcnt++;
                                if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
                                        unreadmarkedcnt++;
+                               if (procmsg_msg_has_flagged_parent(msginfo, MSG_IGNORE_THREAD))
+                                       procmsg_msginfo_set_flags(msginfo, MSG_IGNORE_THREAD, 0);
                                totalcnt++;
                                procmsg_msginfo_free(msginfo);
                                debug_print("Added newly found message %d to cache.\n", num);
                        }
+
+                       update_flags |= F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT;
                }
        }
 
@@ -1239,7 +1248,7 @@ gint folder_item_scan(FolderItem *item)
        item->unreadmarked = unreadmarkedcnt;
        g_slist_free(new_list);
 
-       folder_update_item(item, contentchange);
+       folder_item_update(item, update_flags);
 
        return 0;
 }
@@ -1478,8 +1487,10 @@ gint folder_item_add_msg(FolderItem *dest, const gchar *file,
                                dest->unread++;
                        if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
                                dest->unreadmarked++;
+                       if (procmsg_msg_has_flagged_parent(msginfo, MSG_IGNORE_THREAD))
+                               procmsg_msginfo_set_flags(msginfo, MSG_IGNORE_THREAD, 0);
                        dest->total++;
-                       dest->need_update = TRUE;
+                       folder_item_update(dest, F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT);
 
                        msgcache_add_msg(dest->cache, msginfo);
 
@@ -1539,7 +1550,7 @@ FolderItem *folder_item_move_recursive (FolderItem *src, FolderItem *dest)
                MsgInfo * msginfo;
                cnt++;
                if (cnt%500)
-                       statusbar_print_all(_("Moving %s to %s (%d%%)..."), src->name, 
+                       log_message(_("Moving %s to %s (%d%%)...\n"), src->name, 
                                        new_item->path,
                                        100*cnt/g_slist_length(mlist));
                msginfo = (MsgInfo *) cur->data;
@@ -1690,8 +1701,10 @@ gint folder_item_move_msg(FolderItem *dest, MsgInfo *msginfo)
                                dest->unread++;
                        if (MSG_IS_UNREAD(newmsginfo->flags) && procmsg_msg_has_marked_parent(newmsginfo))
                                dest->unreadmarked++;
+                       if (procmsg_msg_has_flagged_parent(newmsginfo, MSG_IGNORE_THREAD))
+                               procmsg_msginfo_set_flags(newmsginfo, MSG_IGNORE_THREAD, 0);
                        dest->total++;
-                       dest->need_update = TRUE;
+                       folder_item_update(dest, F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT);
 
                        procmsg_msginfo_free(newmsginfo);
                }
@@ -1709,7 +1722,7 @@ gint folder_item_move_msg(FolderItem *dest, MsgInfo *msginfo)
                        if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
                                msginfo->folder->unreadmarked--;
                        msginfo->folder->total--;
-                       msginfo->folder->need_update = TRUE;
+                       folder_item_update(dest, F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT);
                }
        }
        
@@ -1803,8 +1816,10 @@ gint folder_item_move_msgs_with_dest(FolderItem *dest, GSList *msglist)
                                        dest->unread++;
                                if (MSG_IS_UNREAD(newmsginfo->flags) && procmsg_msg_has_marked_parent(newmsginfo))
                                        dest->unreadmarked++;
+                               if (procmsg_msg_has_flagged_parent(newmsginfo, MSG_IGNORE_THREAD))
+                                       procmsg_msginfo_set_flags(newmsginfo, MSG_IGNORE_THREAD, 0);
                                dest->total++;
-                               dest->need_update = TRUE;
+                               folder_item_update(dest, F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT);
 
                                procmsg_msginfo_free(newmsginfo);
                        }
@@ -1838,7 +1853,7 @@ gint folder_item_move_msgs_with_dest(FolderItem *dest, GSList *msglist)
                        if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
                                msginfo->folder->unreadmarked--;
                        msginfo->folder->total--;                       
-                       msginfo->folder->need_update = TRUE;
+                       folder_item_update(dest, F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT);
                }
 
                l2 = g_slist_next(l2);
@@ -1905,8 +1920,10 @@ gint folder_item_copy_msg(FolderItem *dest, MsgInfo *msginfo)
                                dest->unread++;
                        if (MSG_IS_UNREAD(newmsginfo->flags) && procmsg_msg_has_marked_parent(newmsginfo))
                                dest->unreadmarked++;
+                       if (procmsg_msg_has_flagged_parent(newmsginfo, MSG_IGNORE_THREAD))
+                               procmsg_msginfo_set_flags(newmsginfo, MSG_IGNORE_THREAD, 0);
                        dest->total++;
-                       dest->need_update = TRUE;
+                       folder_item_update(dest, F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT);
 
                        procmsg_msginfo_free(newmsginfo);
                }                       
@@ -1996,8 +2013,10 @@ gint folder_item_copy_msgs_with_dest(FolderItem *dest, GSList *msglist)
                                        dest->unread++;
                                if (MSG_IS_UNREAD(newmsginfo->flags) && procmsg_msg_has_marked_parent(newmsginfo))
                                        dest->unreadmarked++;
+                               if (procmsg_msg_has_flagged_parent(newmsginfo, MSG_IGNORE_THREAD))
+                                       procmsg_msginfo_set_flags(newmsginfo, MSG_IGNORE_THREAD, 0);
                                dest->total++;
-                               dest->need_update = TRUE;
+                               folder_item_update(dest, F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT);
 
                                procmsg_msginfo_free(newmsginfo);
                        }
@@ -2037,7 +2056,7 @@ gint folder_item_remove_msg(FolderItem *item, gint num)
                msgcache_remove_msg(item->cache, num);
        }
        item->total--;
-       item->need_update = TRUE;
+       folder_item_update(item, F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT);
 
        return ret;
 }
@@ -2096,7 +2115,7 @@ gint folder_item_remove_all_msg(FolderItem *item)
                item->unread = 0;
                item->unreadmarked = 0;
                item->total = 0;
-               item->need_update = TRUE;
+               folder_item_update(item, F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT);
        }
 
        return result;
@@ -2245,6 +2264,8 @@ static gboolean folder_build_tree(GNode *node, gpointer data)
                                sort_key = SORT_BY_UNREAD;
                        else if (!strcmp(attr->value, "mime"))
                                sort_key = SORT_BY_MIME;
+                       else if (!strcmp(attr->value, "to"))
+                               sort_key = SORT_BY_TO;
                        else if (!strcmp(attr->value, "locked"))
                                sort_key = SORT_BY_LOCKED;
                } else if (!strcmp(attr->name, "sort_type")) {
@@ -2400,7 +2421,8 @@ static void folder_write_list_recursive(GNode *node, gpointer data)
                                                 "draft", "queue", "trash"};
        static gchar *sort_key_str[] = {"none", "number", "size", "date",
                                        "from", "subject", "score", "label",
-                                       "mark", "unread", "mime", "locked" };
+                                       "mark", "unread", "mime", "to", 
+                                       "locked"};
        g_return_if_fail(node != NULL);
        g_return_if_fail(fp != NULL);
 
@@ -2500,7 +2522,7 @@ static void folder_update_op_count_rec(GNode *node)
        if (g_node_depth(node) > 0) {
                if (fitem->op_count > 0) {
                        fitem->op_count = 0;
-                       folder_update_item(fitem, FALSE);
+                       folder_item_update(fitem, F_ITEM_UPDATE_MSGCNT);
                }
                if (node->children) {
                        GNode *child;
@@ -2711,8 +2733,9 @@ void folder_item_apply_processing(FolderItem *item)
        if (processing_list == NULL)
                return;
 
+       folder_item_update_freeze();
+
        mlist = folder_item_get_msg_list(item);
-       
        for (cur = mlist ; cur != NULL ; cur = cur->next) {
                MsgInfo * msginfo;
 
@@ -2720,63 +2743,81 @@ void folder_item_apply_processing(FolderItem *item)
                filter_message_by_msginfo(processing_list, msginfo);
                procmsg_msginfo_free(msginfo);
        }
-       
-       folder_update_items_when_required(FALSE);
-
        g_slist_free(mlist);
+
+       folder_item_update_thaw();
 }
 
 /*
- *  Callback handling for FolderItem content changes
+ *  functions for handling FolderItem content changes
  */
-void folder_update_item(FolderItem *item, gboolean contentchange)
-{
-       FolderItemUpdateData source;
-       
-       source.item = item;
-       source.content_change = contentchange;
-       hooks_invoke(FOLDER_ITEM_UPDATE_HOOKLIST, &source);
-}
+static gint folder_item_update_freeze_cnt = 0;
 
-static void folder_update_item_func(FolderItem *item, gpointer contentchange)
+/**
+ * Notify the folder system about changes to a folder. If the
+ * update system is not frozen the FOLDER_ITEM_UPDATE_HOOKLIST will
+ * be invoked, otherwise the changes will be remebered until
+ * the folder system is thawed.
+ *
+ * \param item The FolderItem that was changed
+ * \param update_flags Type of changed that was made
+ */
+void folder_item_update(FolderItem *item, FolderItemUpdateFlags update_flags)
 {
-       FolderItemUpdateData source;
-
-       if (item->need_update) {
+       if (folder_item_update_freeze_cnt == 0) {
+               FolderItemUpdateData source;
+       
                source.item = item;
-               source.content_change = GPOINTER_TO_INT(contentchange);
-               hooks_invoke(FOLDER_ITEM_UPDATE_HOOKLIST, &source);
-
-               item->need_update = FALSE;
+               source.update_flags = update_flags;
+               hooks_invoke(FOLDER_ITEM_UPDATE_HOOKLIST, &source);
+       } else {
+               item->update_flags |= update_flags;
        }
 }
 
-void folder_update_items_when_required(gboolean contentchange)
-{
-       folder_func_to_all_folders(folder_update_item_func, GINT_TO_POINTER(contentchange));
-}
-
-void folder_update_item_recursive(FolderItem *item, gboolean update_summary)
+void folder_item_update_recursive(FolderItem *item, FolderItemUpdateFlags update_flags)
 {
        GNode *node = item->folder->node;       
-       FolderItemUpdateData source;
 
        node = g_node_find(node, G_PRE_ORDER, G_TRAVERSE_ALL, item);
        node = node->children;
 
-       source.item = item;
-       source.content_change = update_summary; 
-       hooks_invoke(FOLDER_ITEM_UPDATE_HOOKLIST, &source);
+       folder_item_update(item, update_flags);
        while (node != NULL) {
                if (node && node->data) {
                        FolderItem *next_item = (FolderItem*) node->data;
 
-                       source.item = next_item;
-                       source.content_change = update_summary; 
-                       hooks_invoke(FOLDER_ITEM_UPDATE_HOOKLIST, &source);
+                       folder_item_update(next_item, update_flags);
                }
                node = node->next;
        }
 }
 
+void folder_item_update_freeze()
+{
+       folder_item_update_freeze_cnt++;
+}
+
+static void folder_item_update_func(FolderItem *item, gpointer data)
+{
+       FolderItemUpdateData source;
+    
+       if (item->update_flags) {
+               source.item = item;
+               source.update_flags = item->update_flags;
+               hooks_invoke(FOLDER_ITEM_UPDATE_HOOKLIST, &source);                             
+               item->update_flags = 0;
+       }
+}
+
+void folder_item_update_thaw()
+{
+       if (folder_item_update_freeze_cnt > 0)
+               folder_item_update_freeze_cnt--;
+       if (folder_item_update_freeze_cnt == 0) {
+               /* Update all folders */
+               folder_func_to_all_folders(folder_item_update_func, NULL);
+       }
+}
+
 #undef PUT_ESCAPE_STR