diff options
Diffstat (limited to 'camel/camel-vee-store.c')
-rw-r--r-- | camel/camel-vee-store.c | 154 |
1 files changed, 63 insertions, 91 deletions
diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c index 4834ade7e1..9531d49fc0 100644 --- a/camel/camel-vee-store.c +++ b/camel/camel-vee-store.c @@ -74,7 +74,7 @@ camel_vee_store_class_init (CamelVeeStoreClass *klass) { CamelStoreClass *store_class = (CamelStoreClass *) klass; - camel_vee_store_parent = CAMEL_STORE_CLASS(camel_type_get_global_classfuncs (camel_store_get_type ())); + camel_vee_store_parent = (CamelStoreClass *)camel_store_get_type(); /* virtual method overload */ store_class->get_folder = vee_get_folder; @@ -146,7 +146,7 @@ change_folder(CamelStore *store, const char *name, guint32 flags, int count) fi->url = g_strdup_printf("vfolder:%s%s#%s", ((CamelService *)store)->url->path, (flags&CHANGE_NOSELECT)?";noselect=yes":"", name); fi->unread_message_count = count; camel_folder_info_build_path(fi, '/'); - camel_object_trigger_event(CAMEL_OBJECT(store), (flags&CHANGE_DELETE)?"folder_deleted":"folder_created", fi); + camel_object_trigger_event(store, (flags&CHANGE_DELETE)?"folder_deleted":"folder_created", fi); camel_folder_info_free(fi); } @@ -154,6 +154,7 @@ static CamelFolder * vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { CamelVeeFolder *vf; + CamelFolder *folder; char *name, *p; int add; @@ -166,12 +167,11 @@ vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Camel while ( (p = strchr(p, '/'))) { *p = 0; - CAMEL_STORE_LOCK(store, cache_lock); - add = g_hash_table_lookup (store->folders, name) == NULL; - CAMEL_STORE_UNLOCK(store, cache_lock); - - if (add) + folder = camel_object_bag_get(store->folders, name); + if (folder == NULL) change_folder(store, name, CHANGE_ADD|CHANGE_NOSELECT, -1); + else + camel_object_unref(folder); *p++='/'; } @@ -194,78 +194,55 @@ vee_get_trash (CamelStore *store, CamelException *ex) return NULL; } -struct _build_info { - const char *top; - guint32 flags; - GPtrArray *infos; - GPtrArray *folders; -}; - -static void -build_info(char *name, CamelVeeFolder *folder, struct _build_info *data) -{ - CamelFolderInfo *info; - - /* check we have to include this one */ - if (data->top) { - if (data->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) { - int namelen = strlen(name); - int toplen = strlen(data->top); - - if (!((namelen == toplen && - strcmp(name, data->top) == 0) - || ((namelen > toplen) - && strncmp(name, data->top, toplen) == 0 - && name[toplen] == '/'))) - return; - } else { - if (strcmp(name, data->top)) - return; - } - } else { - if ((data->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) == 0) { - if (strchr(name, '/')) - return; - } - } - - info = g_malloc0(sizeof(*info)); - info->url = g_strdup_printf("vfolder:%s#%s", ((CamelService *)((CamelFolder *)folder)->parent_store)->url->path, - ((CamelFolder *)folder)->full_name); - info->full_name = g_strdup(((CamelFolder *)folder)->full_name); - info->name = g_strdup(((CamelFolder *)folder)->name); - info->unread_message_count = -1; - g_ptr_array_add(data->infos, info); - camel_object_ref((CamelObject *)folder); - g_ptr_array_add(data->folders, folder); -} - static CamelFolderInfo * vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex) { - struct _build_info data; CamelFolderInfo *info; + GPtrArray *folders, *infos; int i; - /* first, build the info list */ - data.top = top; - data.flags = flags; - data.infos = g_ptr_array_new(); - data.folders = g_ptr_array_new(); - CAMEL_STORE_LOCK(store, cache_lock); - g_hash_table_foreach(store->folders, (GHFunc)build_info, &data); - CAMEL_STORE_UNLOCK(store, cache_lock); - - /* then make sure the unread counts are accurate */ - for (i=0;i<data.infos->len;i++) { - CamelFolderInfo *info = data.infos->pdata[i]; - CamelFolder *folder = data.folders->pdata[i]; - - camel_folder_refresh_info(folder, NULL); - info->unread_message_count = camel_folder_get_unread_message_count(folder); - camel_object_unref((CamelObject *)folder); + infos = g_ptr_array_new(); + folders = camel_object_bag_list(store->folders); + for (i=0;i<folders->len;i++) { + CamelVeeFolder *folder = folders->pdata[i]; + int add = FALSE; + char *name = ((CamelFolder *)folder)->full_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; + } + } else { + if ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) == 0) + add = strchr(name, '/') == NULL; + } + + if (add) { + /* ensures unread is correct */ + if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) + camel_folder_refresh_info((CamelFolder *)folder, NULL); + + info = g_malloc0(sizeof(*info)); + info->url = g_strdup_printf("vfolder:%s#%s", ((CamelService *)((CamelFolder *)folder)->parent_store)->url->path, + ((CamelFolder *)folder)->full_name); + 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); + } + camel_object_unref(folder); } - g_ptr_array_free(data.folders, TRUE); + g_ptr_array_free(folders, TRUE); /* 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) { @@ -275,12 +252,12 @@ vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelExce info->name = g_strdup(CAMEL_UNMATCHED_NAME); info->unread_message_count = -1; camel_folder_info_build_path(info, '/'); - g_ptr_array_add(data.infos, info); + g_ptr_array_add(infos, info); } /* convert it into a tree */ - info = camel_folder_info_build(data.infos, (top&&top[0])?top:"", '/', TRUE); - g_ptr_array_free(data.infos, TRUE); + info = camel_folder_info_build(infos, (top&&top[0])?top:"", '/', TRUE); + g_ptr_array_free(infos, TRUE); return info; } @@ -289,7 +266,6 @@ static void vee_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex) { CamelFolder *folder; - char *key; if (strcmp(folder_name, CAMEL_UNMATCHED_NAME) == 0) { camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, @@ -297,24 +273,20 @@ vee_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex return; } - CAMEL_STORE_LOCK(store, cache_lock); - if (g_hash_table_lookup_extended(store->folders, folder_name, (void **)&key, (void **)&folder)) { - int update; + folder = camel_object_bag_get(store->folders, folder_name); + if (folder) { + camel_object_bag_remove(store->folders, folder); - update = (((CamelVeeFolder *)folder)->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0; - g_hash_table_remove(store->folders, key); - CAMEL_STORE_UNLOCK(store, cache_lock); if (store->vtrash) camel_vee_folder_remove_folder((CamelVeeFolder *)store->vtrash, folder); - if (update) { + if ((((CamelVeeFolder *)folder)->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) { /* what about now-empty parents? ignore? */ - change_folder(store, key, CHANGE_DELETE, -1); + change_folder(store, folder_name, CHANGE_DELETE, -1); } - g_free(key); - } else { - CAMEL_STORE_UNLOCK(store, cache_lock); + camel_object_unref(folder); + } else { camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, _("Cannot delete folder: %s: No such folder"), folder_name); } @@ -334,11 +306,11 @@ vee_rename_folder(CamelStore *store, const char *old, const char *new, CamelExce } /* See if it exists, for vfolders, all folders are in the folders hash */ - CAMEL_STORE_LOCK(store, cache_lock); - if ((folder = g_hash_table_lookup(store->folders, old)) == NULL) { + folder = camel_object_bag_get(store->folders, old); + if (folder == NULL) { camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, _("Cannot rename folder: %s: No such folder"), old); + } else { + camel_object_unref(folder); } - - CAMEL_STORE_UNLOCK(store, cache_lock); } |