aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-vee-store.c
diff options
context:
space:
mode:
author4 <NotZed@Ximian.com>2001-09-15 16:12:58 +0800
committerMichael Zucci <zucchi@src.gnome.org>2001-09-15 16:12:58 +0800
commit466e05c024510d8019989f8bf8f04541c3ca792d (patch)
treea744a404a3861eb09836240628b5f8480ced01c2 /camel/camel-vee-store.c
parent576a04e67d0f059992afbb1afdca67fb668288f4 (diff)
downloadgsoc2013-evolution-466e05c024510d8019989f8bf8f04541c3ca792d.tar.gz
gsoc2013-evolution-466e05c024510d8019989f8bf8f04541c3ca792d.tar.zst
gsoc2013-evolution-466e05c024510d8019989f8bf8f04541c3ca792d.zip
New function, set the complete list of folders on a vfolder, all at once.
2001-09-14 <NotZed@Ximian.com> * camel-vee-folder.c (camel_vee_folder_set_folders): New function, set the complete list of folders on a vfolder, all at once. (camel_vee_folder_set_expression): If we set the query to be the same thing, dont do anything. * camel-vee-store.c (camel_vee_store_init): Turn off vtrash for this store. * camel-store.c (camel_store_init): Enable vtrash by default via flags. (camel_store_get_trash): REturn NULL if the store doesn't support vtrash. (init_trash): Dont init if store doesn't support vtrash. * camel-store.h: Add a new flags CAMEL_STORE_VTRASH -> store supports vtrash. 2001-09-13 <NotZed@Ximian.com> * camel-vee-store.c (vee_get_folder_info): Implement. (build_info): Used to build a folder record from the folders hashtable. (vee_delete_folder): Implemented, remove folder from hashtable. (vee_rename_folder): Implemented, remove old folder from hashtable, add new one and rename its guts too. * camel-store.c (camel_store_rename_folder): Do nothing if we're not asked to actually change names. Also dont do the renamed cache check till after we've called the subclass. (camel_store_delete_folder): Call the subclass delete firs,t then make sure the cache is right. * camel-vee-folder.c (vee_folder_construct): Remove support for name?query syntax to setup vfolder. Abort if such syntax is used. (camel_vee_folder_new): Removed code that handles ? syntax, etc. (vee_folder_build_folder): Handle unset expression, treat it as an empty search. (camel_vee_folder_set_expression): Oops, actually set the expression. * camel-vtrash-folder.c (camel_vtrash_folder_new): Dont use name?query syntax to setup vfolder, but set the expression directly. Also fixes a small memleak. 2001-09-12 <NotZed@Ximian.com> * camel-store.c (camel_store_delete_folder): Fixed warnings with a cast. (camel_store_rename_folder): " svn path=/trunk/; revision=12854
Diffstat (limited to 'camel/camel-vee-store.c')
-rw-r--r--camel/camel-vee-store.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c
index 2d44b456d5..f5de80fd56 100644
--- a/camel/camel-vee-store.c
+++ b/camel/camel-vee-store.c
@@ -19,15 +19,22 @@
* USA
*/
+#include "camel-exception.h"
#include "camel-vee-store.h"
#include "camel-vee-folder.h"
+#include "camel-private.h"
+
#include <string.h>
static CamelFolder *vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex);
+static void vee_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex);
+static void vee_rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex);
static void vee_init_trash (CamelStore *store);
static CamelFolder *vee_get_trash (CamelStore *store, CamelException *ex);
+static CamelFolderInfo *vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex);
+
struct _CamelVeeStorePrivate {
CamelFolderInfo *folder_info;
};
@@ -67,6 +74,11 @@ camel_vee_store_class_init (CamelVeeStoreClass *klass)
/* virtual method overload */
store_class->get_folder = vee_get_folder;
+ store_class->rename_folder = vee_rename_folder;
+ store_class->delete_folder = vee_delete_folder;
+ store_class->get_folder_info = vee_get_folder_info;
+ store_class->free_folder_info = camel_store_free_folder_info_full;
+
store_class->init_trash = vee_init_trash;
store_class->get_trash = vee_get_trash;
}
@@ -75,6 +87,10 @@ static void
camel_vee_store_init (CamelVeeStore *obj)
{
struct _CamelVeeStorePrivate *p;
+ CamelStore *store = (CamelStore *)obj;
+
+ /* we dont want a vtrash on this one */
+ store->flags &= ~(CAMEL_STORE_VTRASH);
p = _PRIVATE(obj) = g_malloc0(sizeof(*p));
}
@@ -138,3 +154,158 @@ vee_get_trash (CamelStore *store, CamelException *ex)
{
return NULL;
}
+
+struct _build_info {
+ const char *top;
+ guint32 flags;
+ GPtrArray *infos;
+};
+
+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) {
+ if (strncmp(name, data->top, strlen(data->top) != 0))
+ 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 = camel_folder_get_unread_message_count((CamelFolder *)folder);
+ g_ptr_array_add(data->infos, info);
+}
+
+static CamelFolderInfo *
+vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex)
+{
+ struct _build_info data;
+ CamelFolderInfo *info;
+
+ /* first, build the info list */
+ data.top = top;
+ data.flags = flags;
+ data.infos = 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);
+
+ /* and always add UNMATCHED, if scanning from top/etc */
+ if (top == NULL || top[0] == 0 || strncmp(top, "UNMATCHED", strlen("UNMATCHED")) == 0) {
+ info = g_malloc0(sizeof(*info));
+ info->url = g_strdup_printf("vfolder:%s#UNMATCHED", ((CamelService *)store)->url->path);
+ info->full_name = g_strdup("UNMATCHED");
+ info->name = g_strdup("UNMATCHED");
+ info->unread_message_count = -1;
+ g_ptr_array_add(data.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);
+
+ return info;
+}
+
+static void
+vee_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex)
+{
+ CamelFolder *folder;
+ char *key;
+
+ if (strcmp(folder_name, "UNMATCHED") == 0) {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
+ _("Cannot delete folder: %s: Invalid operation"), folder_name);
+ return;
+ }
+
+ CAMEL_STORE_LOCK(store, cache_lock);
+ if (g_hash_table_lookup_extended(store->folders, folder_name, (void **)&key, (void **)&folder)) {
+ int update;
+
+ 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);
+
+ /* FIXME: deleted event shoudl just pass out the folder name, not all this shit?? */
+ if (update) {
+ CamelFolderInfo *fi = g_malloc0(sizeof(*fi));
+
+ fi->full_name = g_strdup(key);
+ fi->name = strrchr(key, '/');
+ if (fi->name == NULL)
+ fi->name = g_strdup(key);
+ else
+ fi->name = g_strdup(fi->name);
+ fi->url = g_strdup_printf("vfolder:%s#%s", ((CamelService *)store)->url->path, key);
+ fi->unread_message_count = -1;
+
+ camel_object_trigger_event(CAMEL_OBJECT(store), "folder_deleted", fi);
+ camel_folder_info_free(fi);
+ }
+ g_free(key);
+ } else {
+ CAMEL_STORE_UNLOCK(store, cache_lock);
+
+ camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
+ _("Cannot delete folder: %s: No such folder"), folder_name);
+ }
+}
+
+static void
+vee_rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex)
+{
+ CamelFolder *folder;
+ char *key, *oldname, *full_oldname;
+
+ if (strcmp(old, "UNMATCHED") == 0) {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
+ _("Cannot rename folder: %s: Invalid operation"), old);
+ return;
+ }
+
+ CAMEL_STORE_LOCK(store, cache_lock);
+ if (g_hash_table_lookup_extended(store->folders, old, (void **)&key, (void **)&folder)) {
+ g_hash_table_remove(store->folders, key);
+ g_free(key);
+
+ /* this should really be atomic */
+ oldname = folder->name;
+ full_oldname = folder->full_name;
+ key = folder->name;
+ folder->full_name = g_strdup(new);
+ key = strrchr(new, '/');
+ key = key?key+1:(char *)new;
+ folder->name = g_strdup(key);
+ g_hash_table_insert(store->folders, g_strdup(new), folder);
+
+ g_free(oldname);
+ g_free(full_oldname);
+ CAMEL_STORE_UNLOCK(store, cache_lock);
+
+
+ } else {
+ CAMEL_STORE_UNLOCK(store, cache_lock);
+
+ camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
+ _("Cannot rename folder: %s: No such folder"), new);
+ }
+}
+