diff options
author | Not Zed <NotZed@Ximian.com> | 2004-01-15 14:18:56 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2004-01-15 14:18:56 +0800 |
commit | 1f36dc67c07a017659d0fb2b543d8706b5425e0b (patch) | |
tree | c6e8d1edec579e04f651d9cda2b10687fff55439 /camel/camel-vee-store.c | |
parent | bbdcea50101fdf73c85a422af5e06c91d4204334 (diff) | |
download | gsoc2013-evolution-1f36dc67c07a017659d0fb2b543d8706b5425e0b.tar.gz gsoc2013-evolution-1f36dc67c07a017659d0fb2b543d8706b5425e0b.tar.zst gsoc2013-evolution-1f36dc67c07a017659d0fb2b543d8706b5425e0b.zip |
** See bug #52881.
2004-01-15 Not Zed <NotZed@Ximian.com>
** See bug #52881.
* camel-object.c (camel_object_bag*): Support reserving different
keys from the same thread. Oh the pain.
* camel-vee-store.c (vee_get_folder_info): implement child flags
properly. Changed to build tree itself rather than calling
camel_folder_info_build.
(vee_get_folder): if we're adding a folder with dummy parents,
create and add the dummy parent folders too (as real folder
objects). We are the only owner of the ref, so this sort of leaks
the folder, but they're small.
svn path=/trunk/; revision=24233
Diffstat (limited to 'camel/camel-vee-store.c')
-rw-r--r-- | camel/camel-vee-store.c | 114 |
1 files changed, 88 insertions, 26 deletions
diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c index b13522b8de..2d15bac7c3 100644 --- a/camel/camel-vee-store.c +++ b/camel/camel-vee-store.c @@ -160,11 +160,16 @@ vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Camel while ( (p = strchr(p, '/'))) { *p = 0; - folder = camel_object_bag_get(store->folders, name); - if (folder == NULL) - change_folder(store, name, CHANGE_ADD|CHANGE_NOSELECT, -1); - else + folder = camel_object_bag_reserve(store->folders, name); + if (folder == NULL) { + /* create a dummy vFolder for this, makes get_folder_info simpler */ + folder = camel_vee_folder_new(store, name, flags); + camel_object_bag_add(store->folders, name, folder); + change_folder(store, name, CHANGE_ADD|CHANGE_NOSELECT, 0); + /* FIXME: this sort of leaks folder, nobody owns a ref to it but us */ + } else { camel_object_unref(folder); + } *p++='/'; } @@ -200,39 +205,52 @@ vee_get_junk (CamelStore *store, CamelException *ex) return NULL; } +static int +vee_folder_cmp(const void *ap, const void *bp) +{ + return strcmp(((CamelFolder **)ap)[0]->full_name, ((CamelFolder **)bp)[0]->full_name); +} + static CamelFolderInfo * vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex) { - CamelFolderInfo *info; + CamelFolderInfo *info, *res = NULL, *tail; GPtrArray *folders, *infos; + GHashTable *infos_hash; int i; - infos = g_ptr_array_new(); + printf("Get folder info '%s'\n", top?top:"<null>"); + + infos_hash = g_hash_table_new(g_str_hash, g_str_equal); folders = camel_object_bag_list(store->folders); + qsort(folders->pdata, folders->len, sizeof(folders->pdata[0]), vee_folder_cmp); for (i=0;i<folders->len;i++) { CamelVeeFolder *folder = folders->pdata[i]; int add = FALSE; - char *name = ((CamelFolder *)folder)->full_name; + char *name = ((CamelFolder *)folder)->full_name, *pname, *tmp; + CamelFolderInfo *pinfo; + + printf("folder '%s'\n", name); /* check we have to include this one */ if (top) { - if (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) { - int namelen = strlen(name); - int toplen = strlen(top); - - add = ((namelen == toplen && - strcmp(name, top) == 0) - || ((namelen > toplen) - && strncmp(name, top, toplen) == 0 - && name[toplen] == '/')); - } else { - add = strcmp(name, top) == 0; - } + int namelen = strlen(name); + int toplen = strlen(top); + + add = ((namelen == toplen + && strcmp(name, top) == 0) + || ((namelen > toplen) + && strncmp(name, top, toplen) == 0 + && name[toplen] == '/' + && ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) + || strchr(name+toplen+1, '/') == NULL))); } else { if ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) == 0) add = strchr(name, '/') == NULL; } + printf("%sadding '%s'\n", add?"":"not ", name); + if (add) { /* ensures unread is correct */ if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) @@ -244,11 +262,50 @@ vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelExce info->full_name = g_strdup(((CamelFolder *)folder)->full_name); info->name = g_strdup(((CamelFolder *)folder)->name); info->unread_message_count = camel_folder_get_unread_message_count((CamelFolder *)folder); - g_ptr_array_add(infos, info); + info->flags = CAMEL_FOLDER_NOCHILDREN; + camel_folder_info_build_path(info, '/'); + g_hash_table_insert(infos_hash, info->full_name, info); + + if (res == NULL) + res = info; + } else { + info = NULL; + } + + /* check for parent, if present, update flags and if adding, update parent linkage */ + pname = g_strdup(((CamelFolder *)folder)->full_name); + printf("looking up parent of '%s'\n", pname); + tmp = strrchr(pname, '/'); + if (tmp) { + *tmp = 0; + pinfo = g_hash_table_lookup(infos_hash, pname); + } else + pinfo = NULL; + + if (pinfo) { + pinfo->flags = (pinfo->flags & ~(CAMEL_FOLDER_CHILDREN|CAMEL_FOLDER_NOCHILDREN))|CAMEL_FOLDER_CHILDREN; + printf("updating parent flags for children '%s' %08x\n", pinfo->full_name, pinfo->flags); + tail = pinfo->child; + if (tail == NULL) + pinfo->child = info; + } else if (info != res) { + tail = res; + } else { + tail = NULL; } + + if (info && tail) { + while (tail->sibling) + tail = tail->sibling; + tail->sibling = info; + info->parent = pinfo; + } + + g_free(pname); camel_object_unref(folder); } g_ptr_array_free(folders, TRUE); + g_hash_table_destroy(infos_hash); /* and always add UNMATCHED, if scanning from top/etc */ if (top == NULL || top[0] == 0 || strncmp(top, CAMEL_UNMATCHED_NAME, strlen(CAMEL_UNMATCHED_NAME)) == 0) { @@ -257,15 +314,20 @@ vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelExce info->full_name = g_strdup(CAMEL_UNMATCHED_NAME); info->name = g_strdup(CAMEL_UNMATCHED_NAME); info->unread_message_count = -1; + info->flags = CAMEL_FOLDER_NOCHILDREN|CAMEL_FOLDER_NOINFERIORS; camel_folder_info_build_path(info, '/'); - g_ptr_array_add(infos, info); + + if (res == NULL) + res = info; + else { + tail = res; + while (tail->sibling) + tail = tail->sibling; + tail->sibling = info; + } } - - /* convert it into a tree */ - info = camel_folder_info_build(infos, (top&&top[0])?top:"", '/', TRUE); - g_ptr_array_free(infos, TRUE); - return info; + return res; } static void |