sync with 0.9.4cvs8
authorPaul Mangan <paul@claws-mail.org>
Mon, 25 Aug 2003 14:14:47 +0000 (14:14 +0000)
committerPaul Mangan <paul@claws-mail.org>
Mon, 25 Aug 2003 14:14:47 +0000 (14:14 +0000)
ChangeLog
ChangeLog.claws
ChangeLog.jp
configure.ac
src/folder.c
src/folder.h
src/folderview.c
src/imap.c
src/mh.c

index 0183455..1e6706d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2003-08-25
+
+       * src/folder.[ch]: added a reference to its own GNode in FolderItem.
+         folder_item_remove(): free all FolderItem's.
+         folder_tree_destroy(): use folder_item_remove().
+       * src/folderview.c: folderview_sort_folders(): keep the order even
+         if special folders' parents are different.
+       * src/imap.c: imap_scan_tree_recursive(): fixed a memory leak.
+       * src/mh.c: mh_scan_tree(): preserve the previous FolderItem's.
+         mh_remove_missing_folder_items(): scan the directories and remove
+         missing folders.
+         mh_scan_tree_recursive(): reuse the previous FolderItem objects.
+
 2003-08-20
 
        * src/mainwindow.c: always reflect window size changes.
index 51ce1e5..d7dd23a 100644 (file)
@@ -1,3 +1,8 @@
+2003-08-25 [paul]      0.9.4claws37
+
+       * sync with 0.9.4cvs8
+               see ChangeLog 2003-08-25
+
 2003-08-24 [christoph] 0.9.4claws36
 
        * src/prefs_filtering.c
index 7e0a3eb..905371f 100644 (file)
@@ -1,3 +1,16 @@
+2003-08-25
+
+       * src/folder.[ch]: FolderItem ¤Ë¼«Ê¬¼«¿È¤Î GNode ¤Ø¤Î»²¾È¤òÄɲá£
+         folder_item_remove(): Á´¤Æ¤Î FolderItem ¤ò³«Êü¡£
+         folder_tree_destroy(): folder_item_remove() ¤ò»ÈÍÑ¡£
+       * src/folderview.c: folderview_sort_folders(): ÆÃÊÌ¥Õ¥©¥ë¥À¤Î¿Æ¤¬
+         °Û¤Ê¤Ã¤Æ¤â½ç½ø¤òÊݤĤ褦¤Ë¤·¤¿¡£
+       * src/imap.c: imap_scan_tree_recursive(): ¥á¥â¥ê¥ê¡¼¥¯¤ò½¤Àµ¡£
+       * src/mh.c: mh_scan_tree(): °ÊÁ°¤Î FolderItem ¤òÊÝ»ý¡£
+         mh_remove_missing_folder_items(): ¥Ç¥£¥ì¥¯¥È¥ê¤ò¥¹¥­¥ã¥ó¤·¡¢
+         ¸«¤Ä¤«¤é¤Ê¤¤¥Õ¥©¥ë¥À¤òºï½ü¡£
+         mh_scan_tree_recursive(): °ÊÁ°¤Î FolderItem ¥ª¥Ö¥¸¥§¥¯¥È¤òºÆÍøÍÑ¡£
+
 2003-08-20
 
        * src/mainwindow.c: ¥¦¥£¥ó¥É¥¦¥µ¥¤¥º¤ÎÊѹ¹¤ò¾ï¤ËÈ¿±Ç¡£
index 8171894..5f824b6 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=9
 MICRO_VERSION=4
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=36
+EXTRA_VERSION=37
 if test $EXTRA_VERSION -eq 0; then
     VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}claws
 else
index 5284d29..5bc8eee 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2003 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -108,7 +108,7 @@ Folder *folder_new(FolderClass *klass, const gchar *name, const gchar *path)
        /* Create root folder item */
        item = folder_item_new(folder, name, NULL);
        item->folder = folder;
-       folder->node = g_node_new(item);
+       folder->node = item->node = g_node_new(item);
        folder->data = NULL;
 
        return folder;
@@ -202,6 +202,7 @@ FolderItem *folder_item_new(Folder *folder, const gchar *name, const gchar *path
        item->threaded  = TRUE;
        item->ret_rcpt  = FALSE;
        item->opened    = FALSE;
+       item->node = NULL;
        item->parent = NULL;
        item->folder = NULL;
        item->account = NULL;
@@ -216,19 +217,22 @@ FolderItem *folder_item_new(Folder *folder, const gchar *name, const gchar *path
 
 void folder_item_append(FolderItem *parent, FolderItem *item)
 {
-       GNode *node;
-
        g_return_if_fail(parent != NULL);
        g_return_if_fail(parent->folder != NULL);
+       g_return_if_fail(parent->node != NULL);
        g_return_if_fail(item != NULL);
 
-       node = parent->folder->node;
-       node = g_node_find(node, G_PRE_ORDER, G_TRAVERSE_ALL, parent);
-       g_return_if_fail(node != NULL);
-
        item->parent = parent;
        item->folder = parent->folder;
-       g_node_append_data(node, item);
+       item->node = g_node_append_data(parent->node, item);
+}
+
+static gboolean folder_item_remove_func(GNode *node, gpointer data)
+{
+       FolderItem *item = FOLDER_ITEM(node->data);
+
+       folder_item_destroy(item);
+       return FALSE;
 }
 
 void folder_item_remove(FolderItem *item)
@@ -237,22 +241,37 @@ void folder_item_remove(FolderItem *item)
 
        g_return_if_fail(item != NULL);
        g_return_if_fail(item->folder != NULL);
+       g_return_if_fail(item->node != NULL);
 
-       node = item->folder->node;
-       node = g_node_find(node, G_PRE_ORDER, G_TRAVERSE_ALL, item);
-       g_return_if_fail(node != NULL);
+       node = item->node;
 
-       /* TODO: free all FolderItem's first */
        if (item->folder->node == node)
                item->folder->node = NULL;
+
+       g_node_traverse(node, G_POST_ORDER, G_TRAVERSE_ALL, -1,
+                       folder_item_remove_func, NULL);
        g_node_destroy(node);
 }
 
 void folder_item_destroy(FolderItem *item)
 {
+       Folder *folder;
+
        g_return_if_fail(item != NULL);
 
-       debug_print("Destroying folder item %s\n", item->path);
+       folder = item->folder;
+       if (folder) {
+               if (folder->inbox == item)
+                       folder->inbox = NULL;
+               else if (folder->outbox == item)
+                       folder->outbox = NULL;
+               else if (folder->draft == item)
+                       folder->draft = NULL;
+               else if (folder->queue == item)
+                       folder->queue = NULL;
+               else if (folder->trash == item)
+                       folder->trash = NULL;
+       }
 
        if (item->cache)
                folder_item_free_cache(item);
@@ -300,21 +319,12 @@ gboolean folder_tree_destroy_func(GNode *node, gpointer data) {
 void folder_tree_destroy(Folder *folder)
 {
        g_return_if_fail(folder != NULL);
-       g_return_if_fail(folder->node != NULL);
        
        prefs_scoring_clear_folder(folder);
        prefs_filtering_clear_folder(folder);
 
-       g_node_traverse(folder->node, G_POST_ORDER, G_TRAVERSE_ALL, -1, folder_tree_destroy_func, NULL);
        if (folder->node)
-               g_node_destroy(folder->node);
-
-       folder->inbox = NULL;
-       folder->outbox = NULL;
-       folder->draft = NULL;
-       folder->queue = NULL;
-       folder->trash = NULL;
-       folder->node = NULL;
+               folder_item_remove(FOLDER_ITEM(folder->node->data));
 }
 
 void folder_add(Folder *folder)
@@ -2473,6 +2483,7 @@ static gboolean folder_build_tree(GNode *node, gpointer data)
        item->ret_rcpt  = ret_rcpt;
        item->sort_key  = sort_key;
        item->sort_type = sort_type;
+       item->node = node;
        item->parent = FOLDER_ITEM(node->parent->data);
        item->folder = folder;
        switch (stype) {
@@ -2496,6 +2507,7 @@ static gboolean folder_build_tree(GNode *node, gpointer data)
 static gboolean folder_read_folder_func(GNode *node, gpointer data)
 {
        Folder *folder;
+       FolderItem *item;
        XMLNode *xmlnode;
        GList *list;
        FolderClass *class = NULL;
@@ -2546,16 +2558,18 @@ static gboolean folder_read_folder_func(GNode *node, gpointer data)
        folder->account = account;
        if (account != NULL)
                account->folder = REMOTE_FOLDER(folder);
-       node->data = folder->node->data;
+       item = FOLDER_ITEM(folder->node->data);
+       node->data = item;
+       item->node = node;
        g_node_destroy(folder->node);
        folder->node = node;
        folder_add(folder);
-       FOLDER_ITEM(node->data)->collapsed = collapsed;
-       FOLDER_ITEM(node->data)->thread_collapsed = thread_collapsed;
-       FOLDER_ITEM(node->data)->threaded  = threaded;
-       FOLDER_ITEM(node->data)->account   = account;
-       FOLDER_ITEM(node->data)->apply_sub = apply_sub;
-       FOLDER_ITEM(node->data)->ret_rcpt  = ret_rcpt;
+       item->collapsed = collapsed;
+       item->thread_collapsed = thread_collapsed;
+       item->threaded  = threaded;
+       item->account   = account;
+       item->apply_sub = apply_sub;
+       item->ret_rcpt  = ret_rcpt;
 
        g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
                        folder_build_tree, folder);
index 5479277..35abd7d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2003 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -301,6 +301,8 @@ struct _FolderItem
        FolderSortKey sort_key;
        FolderSortType sort_type;
 
+       GNode *node;
+
        FolderItem *parent;
 
        Folder *folder;
index 2bb1c38..625e58c 100644 (file)
@@ -1293,6 +1293,16 @@ static void folderview_expand_func(GtkCTree *ctree, GtkCTreeNode *node,
                                sibling = GTK_CTREE_ROW(prev)->sibling; \
                        else \
                                sibling = GTK_CTREE_ROW(parent)->children; \
+                       while (sibling) { \
+                               FolderItem *tmp; \
+ \
+                               tmp = gtk_ctree_node_get_row_data \
+                                       (ctree, sibling); \
+                               if (tmp->stype != F_NORMAL) \
+                                       sibling = GTK_CTREE_ROW(sibling)->sibling; \
+                               else \
+                                       break; \
+                       } \
                        if (node != sibling) \
                                gtk_ctree_move(ctree, node, parent, sibling); \
                } \
index 1077547..6f29266 100644 (file)
@@ -1173,7 +1173,7 @@ void imap_scan_tree(Folder *folder)
                        folder_tree_destroy(folder);
                        item = folder_item_new(folder, folder->name, NULL);
                        item->folder = folder;
-                       folder->node = g_node_new(item);
+                       folder->node = item->node = g_node_new(item);
                }
                return;
        }
@@ -1187,10 +1187,9 @@ void imap_scan_tree(Folder *folder)
        item = folder_item_new(folder, folder->name, root_folder);
        item->folder = folder;
        item->no_select = TRUE;
-       folder->node = g_node_new(item);
+       folder->node = item->node = g_node_new(item);
 
        imap_scan_tree_recursive(session, item);
-
        imap_create_missing_folders(folder);
 }
 
@@ -1209,13 +1208,13 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
        g_return_val_if_fail(item->folder != NULL, -1);
        g_return_val_if_fail(item->no_sub == FALSE, -1);
 
-       folder = FOLDER(item->folder);
+       folder = item->folder;
        imapfolder = IMAP_FOLDER(folder);
 
        separator = imap_get_path_separator(imapfolder, item->path);
 
-       if (item->folder->ui_func)
-               item->folder->ui_func(folder, item, folder->ui_func_data);
+       if (folder->ui_func)
+               folder->ui_func(folder, item, folder->ui_func_data);
 
        if (item->path) {
                wildcard[0] = separator;
@@ -1244,7 +1243,7 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
                if (!strcmp(new_item->path, "INBOX")) {
                        if (!folder->inbox) {
                                new_item->stype = F_INBOX;
-                               item->folder->inbox = new_item;
+                               folder->inbox = new_item;
                        } else {
                                folder_item_destroy(new_item);
                                continue;
@@ -1273,6 +1272,8 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
                        imap_scan_tree_recursive(session, new_item);
        }
 
+       g_slist_free(item_list);
+
        return IMAP_SUCCESS;
 }
 
@@ -1577,7 +1578,6 @@ gint imap_rename_folder(Folder *folder, FolderItem *item, const gchar *name)
        gchar *newpath;
        gchar *real_oldpath;
        gchar *real_newpath;
-       GNode *node;
        gchar *paths[2];
        gchar *old_cache_dir;
        gchar *new_cache_dir;
@@ -1632,11 +1632,9 @@ gint imap_rename_folder(Folder *folder, FolderItem *item, const gchar *name)
 
        old_cache_dir = folder_item_get_path(item);
 
-       node = g_node_find(item->folder->node, G_PRE_ORDER, G_TRAVERSE_ALL,
-                          item);
        paths[0] = g_strdup(item->path);
        paths[1] = newpath;
-       g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
+       g_node_traverse(item->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
                        imap_rename_folder_func, paths);
 
        if (is_dir_exist(old_cache_dir)) {
index 140d35d..e0bc447 100644 (file)
--- a/src/mh.c
+++ b/src/mh.c
@@ -79,6 +79,7 @@ static gint mh_remove_folder(Folder * folder, FolderItem * item);
 static gchar *mh_get_new_msg_filename(FolderItem * dest);
 
 static MsgInfo *mh_parse_msg(const gchar * file, FolderItem * item);
+static void    mh_remove_missing_folder_items  (Folder         *folder);
 static void mh_scan_tree_recursive(FolderItem * item);
 
 static gboolean mh_rename_folder_func(GNode * node, gpointer data);
@@ -472,9 +473,12 @@ void mh_scan_tree(Folder *folder)
 
        g_return_if_fail(folder != NULL);
 
-       item = folder_item_new(folder, folder->name, NULL);
-       item->folder = folder;
-       folder->node = g_node_new(item);
+       if (!folder->node) {
+               item = folder_item_new(folder, folder->name, NULL);
+               item->folder = folder;
+               folder->node = item->node = g_node_new(item);
+       } else
+               item = FOLDER_ITEM(folder->node->data);
 
        rootpath = folder_item_get_path(item);
        if (change_dir(rootpath) < 0) {
@@ -484,6 +488,7 @@ void mh_scan_tree(Folder *folder)
        g_free(rootpath);
 
        mh_create_tree(folder);
+       mh_remove_missing_folder_items(folder);
        mh_scan_tree_recursive(item);
 }
 
@@ -606,7 +611,6 @@ gint mh_rename_folder(Folder *folder, FolderItem *item, const gchar *name)
        gchar *oldpath;
        gchar *dirname;
        gchar *newpath;
-       GNode *node;
        gchar *paths[2];
 
        g_return_val_if_fail(folder != NULL, -1);
@@ -642,11 +646,9 @@ gint mh_rename_folder(Folder *folder, FolderItem *item, const gchar *name)
        g_free(item->name);
        item->name = g_strdup(name);
 
-       node = g_node_find(item->folder->node, G_PRE_ORDER, G_TRAVERSE_ALL,
-                          item);
        paths[0] = g_strdup(item->path);
        paths[1] = newpath;
-       g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
+       g_node_traverse(item->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
                        mh_rename_folder_func, paths);
 
        g_free(paths[0]);
@@ -736,8 +738,41 @@ static gboolean mh_is_maildir(const gchar *path)
 }
 #endif
 
+static gboolean mh_remove_missing_folder_items_func(GNode *node, gpointer data)
+{
+       FolderItem *item;
+       gchar *path;
+
+       g_return_val_if_fail(node->data != NULL, FALSE);
+
+       if (G_NODE_IS_ROOT(node))
+               return FALSE;
+
+       item = FOLDER_ITEM(node->data);
+
+       path = folder_item_get_path(item);
+       if (!is_dir_exist(path)) {
+               debug_print("folder '%s' not found. removing...\n", path);
+               folder_item_remove(item);
+       }
+       g_free(path);
+
+       return FALSE;
+}
+
+static void mh_remove_missing_folder_items(Folder *folder)
+{
+       g_return_if_fail(folder != NULL);
+
+       debug_print("searching missing folders...\n");
+
+       g_node_traverse(folder->node, G_POST_ORDER, G_TRAVERSE_ALL, -1,
+                       mh_remove_missing_folder_items_func, folder);
+}
+
 static void mh_scan_tree_recursive(FolderItem *item)
 {
+       Folder *folder;
        DIR *dp;
        struct dirent *d;
        struct stat s;
@@ -747,6 +782,8 @@ static void mh_scan_tree_recursive(FolderItem *item)
        g_return_if_fail(item != NULL);
        g_return_if_fail(item->folder != NULL);
 
+       folder = item->folder;
+
        dp = opendir(item->path ? item->path : ".");
        if (!dp) {
                FILE_OP_ERROR(item->path ? item->path : ".", "opendir");
@@ -756,9 +793,8 @@ static void mh_scan_tree_recursive(FolderItem *item)
        debug_print("scanning %s ...\n",
                    item->path ? item->path
                    : LOCAL_FOLDER(item->folder)->rootpath);
-       if (item->folder->ui_func)
-               item->folder->ui_func(item->folder, item,
-                                     item->folder->ui_func_data);
+       if (folder->ui_func)
+               folder->ui_func(folder, item, folder->ui_func_data);
 
        while ((d = readdir(dp)) != NULL) {
                if (d->d_name[0] == '.') continue;
@@ -776,7 +812,8 @@ static void mh_scan_tree_recursive(FolderItem *item)
                }
 
                if (S_ISDIR(s.st_mode)) {
-                       FolderItem *new_item;
+                       FolderItem *new_item = NULL;
+                       GNode *node;
 
 #if 0
                        if (mh_is_maildir(entry)) {
@@ -785,26 +822,44 @@ static void mh_scan_tree_recursive(FolderItem *item)
                        }
 #endif
 
-                       new_item = folder_item_new(item->folder, d->d_name, entry);
-                       folder_item_append(item, new_item);
+                       node = item->node;
+                       for (node = node->children; node != NULL; node = node->next) {
+                               FolderItem *cur_item = FOLDER_ITEM(node->data);
+                               if (!strcmp2(cur_item->path, entry)) {
+                                       new_item = cur_item;
+                                       break;
+                               }
+                       }
+                       if (!new_item) {
+                               debug_print("new folder '%s' found.\n", entry);
+                               new_item = folder_item_new(folder, d->d_name, entry);
+                               folder_item_append(item, new_item);
+                       }
+
                        if (!item->path) {
-                               if (!strcmp(d->d_name, INBOX_DIR)) {
+                               if (!folder->inbox &&
+                                   !strcmp(d->d_name, INBOX_DIR)) {
                                        new_item->stype = F_INBOX;
-                                       item->folder->inbox = new_item;
-                               } else if (!strcmp(d->d_name, OUTBOX_DIR)) {
+                                       folder->inbox = new_item;
+                               } else if (!folder->outbox &&
+                                          !strcmp(d->d_name, OUTBOX_DIR)) {
                                        new_item->stype = F_OUTBOX;
-                                       item->folder->outbox = new_item;
-                               } else if (!strcmp(d->d_name, DRAFT_DIR)) {
+                                       folder->outbox = new_item;
+                               } else if (!folder->draft &&
+                                          !strcmp(d->d_name, DRAFT_DIR)) {
                                        new_item->stype = F_DRAFT;
-                                       item->folder->draft = new_item;
-                               } else if (!strcmp(d->d_name, QUEUE_DIR)) {
+                                       folder->draft = new_item;
+                               } else if (!folder->queue &&
+                                          !strcmp(d->d_name, QUEUE_DIR)) {
                                        new_item->stype = F_QUEUE;
-                                       item->folder->queue = new_item;
-                               } else if (!strcmp(d->d_name, TRASH_DIR)) {
+                                       folder->queue = new_item;
+                               } else if (!folder->trash &&
+                                          !strcmp(d->d_name, TRASH_DIR)) {
                                        new_item->stype = F_TRASH;
-                                       item->folder->trash = new_item;
+                                       folder->trash = new_item;
                                }
                        }
+
                        mh_scan_tree_recursive(new_item);
                } else if (to_number(d->d_name) != -1) n_msg++;