aboutsummaryrefslogtreecommitdiffstats
path: root/mail/mail-folder-cache.c
diff options
context:
space:
mode:
author6 <NotZed@Ximian.com>2001-10-27 14:02:04 +0800
committerMichael Zucci <zucchi@src.gnome.org>2001-10-27 14:02:04 +0800
commit8f8b24c737a907f91b88bf0b2b985d56b4051848 (patch)
tree8af1be6e77686cb935ae5a21ac17d7b14a9b0463 /mail/mail-folder-cache.c
parentc4d87ba45ad016d5a6607df96ed27ba02910e2e6 (diff)
downloadgsoc2013-evolution-8f8b24c737a907f91b88bf0b2b985d56b4051848.tar.gz
gsoc2013-evolution-8f8b24c737a907f91b88bf0b2b985d56b4051848.tar.zst
gsoc2013-evolution-8f8b24c737a907f91b88bf0b2b985d56b4051848.zip
Changed to open the source store from '/', so we can do renames across
2001-10-26 <NotZed@Ximian.com> * mail-local.c (mlf_set_folder): Changed to open the source store from '/', so we can do renames across directories. Of course, this doesn't quite work with different filesystems, but we'll assume this isn't a problem we're going to have. (mail_local_folder_get_type): Setup parent_class. (mlf_rename): Implement folder rename call, rename internal data. Is this a security issue? Well, not really, no more than anything else. * mail-folder-cache.c (mail_note_store): Listen to rename event. (store_folder_renamed): Function to handle it, empty. (mail_note_store_remove): Unhook from rename event. (mail_note_folder): Hook onto renamed event. (unset_folder_info): Unhook from renamed event. (folder_finalised): Lock around update. (folder_deleted): Lock around update. (real_flush_updates): If we have a path to remove remove it. (rename_folders): Scan folderinfo's, if we can find ones renamed, rename them, otherwise add them. * component-factory.c (owner_unset_cb): Use a timeout not an idle handler. (storage_xfer_folder): Implementation of xfer_folder signal handler, so we can rename imap/vfolders/etc. svn path=/trunk/; revision=14205
Diffstat (limited to 'mail/mail-folder-cache.c')
-rw-r--r--mail/mail-folder-cache.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c
index c08da26a5a..6ae250df0c 100644
--- a/mail/mail-folder-cache.c
+++ b/mail/mail-folder-cache.c
@@ -75,6 +75,8 @@ struct _folder_update {
char *path;
char *name;
char *uri;
+ char *oldpath;
+
int unread;
CamelStore *store;
};
@@ -95,6 +97,7 @@ struct _store_info {
static void folder_changed(CamelObject *o, gpointer event_data, gpointer user_data);
static void folder_deleted(CamelObject *o, gpointer event_data, gpointer user_data);
+static void folder_renamed(CamelObject *o, gpointer event_data, gpointer user_data);
static void folder_finalised(CamelObject *o, gpointer event_data, gpointer user_data);
/* Store to storeinfo table, active stores */
@@ -149,6 +152,12 @@ real_flush_updates(void *o, void *event_data, void *data)
else
mail_vfolder_add_uri(up->store, up->uri, TRUE);
} else {
+ if (up->oldpath) {
+ if (storage != NULL)
+ evolution_storage_removed_folder(storage, up->oldpath);
+ /* ELSE? Shell supposed to handle the local snot case */
+ }
+
if (up->name == NULL) {
if (storage != NULL) {
d(printf("Updating existing folder: %s (%d unread)\n", up->path, up->unread));
@@ -198,6 +207,7 @@ unset_folder_info(struct _folder_info *mfi, int delete)
camel_object_unhook_event((CamelObject *)folder, "folder_changed", folder_changed, mfi);
camel_object_unhook_event((CamelObject *)folder, "message_changed", folder_changed, mfi);
camel_object_unhook_event((CamelObject *)folder, "deleted", folder_deleted, mfi);
+ camel_object_unhook_event((CamelObject *)folder, "renamed", folder_renamed, mfi);
camel_object_unhook_event((CamelObject *)folder, "finalize", folder_finalised, mfi);
}
@@ -352,7 +362,9 @@ folder_finalised(CamelObject *o, gpointer event_data, gpointer user_data)
struct _folder_info *mfi = user_data;
d(printf("Folder finalised '%s'!\n", ((CamelFolder *)o)->full_name));
+ LOCK(info_lock);
mfi->folder = NULL;
+ UNLOCK(info_lock);
}
static void
@@ -361,7 +373,21 @@ folder_deleted(CamelObject *o, gpointer event_data, gpointer user_data)
struct _folder_info *mfi = user_data;
d(printf("Folder deleted '%s'!\n", ((CamelFolder *)o)->full_name));
+ LOCK(info_lock);
mfi->folder = NULL;
+ UNLOCK(info_lock);
+}
+
+static void
+folder_renamed(CamelObject *o, gpointer event_data, gpointer user_data)
+{
+ struct _folder_info *mfi = user_data;
+ CamelFolder *folder = (CamelFolder *)o;
+ char *old = event_data;
+
+ printf("Folder renamed from '%s' to '%s'\n", old, folder->full_name);
+ mfi = mfi;
+ /* Dont do anything, do it from the store rename event? */
}
void mail_note_folder(CamelFolder *folder)
@@ -401,6 +427,7 @@ void mail_note_folder(CamelFolder *folder)
camel_object_hook_event((CamelObject *)folder, "folder_changed", folder_changed, mfi);
camel_object_hook_event((CamelObject *)folder, "message_changed", folder_changed, mfi);
camel_object_hook_event((CamelObject *)folder, "deleted", folder_deleted, mfi);
+ camel_object_hook_event((CamelObject *)folder, "renamed", folder_renamed, mfi);
camel_object_hook_event((CamelObject *)folder, "finalize", folder_finalised, mfi);
update_1folder(mfi, NULL);
@@ -461,6 +488,116 @@ store_folder_deleted(CamelObject *o, void *event_data, void *data)
store_folder_unsubscribed(o, event_data, data);
}
+static void
+rename_folders(struct _store_info *si, const char *oldbase, const char *newbase, CamelFolderInfo *fi)
+{
+ char *old;
+ struct _folder_info *mfi;
+ struct _folder_update *up;
+
+ up = g_malloc0(sizeof(*up));
+
+ /* Form what was the old name, and try and look it up */
+ old = g_strdup_printf("%s%s", oldbase, fi->full_name + strlen(newbase));
+ mfi = g_hash_table_lookup(si->folders, old);
+ if (mfi) {
+ printf("Found old folder '%s' renaming to '%s'\n", mfi->full_name, fi->full_name);
+
+ up->oldpath = mfi->path;
+
+ /* Its a rename op */
+ g_hash_table_remove(si->folders, mfi->full_name);
+ g_hash_table_remove(si->folders, mfi->uri);
+ g_free(mfi->full_name);
+ g_free(mfi->uri);
+ mfi->path = g_strdup(fi->path);
+ mfi->full_name = g_strdup(fi->full_name);
+ mfi->uri = g_strdup(fi->url);
+ g_hash_table_insert(si->folders, mfi->full_name, mfi);
+ g_hash_table_insert(si->folders_uri, mfi->uri, mfi);
+ } else {
+ printf("Rename found a new folder? old '%s' new '%s'\n", old, fi->full_name);
+ /* Its a new op */
+ mfi = g_malloc0(sizeof(*mfi));
+ mfi->path = g_strdup(fi->path);
+ mfi->full_name = g_strdup(fi->full_name);
+ mfi->uri = g_strdup(fi->url);
+ mfi->store_info = si;
+ g_hash_table_insert(si->folders, mfi->full_name, mfi);
+ g_hash_table_insert(si->folders_uri, mfi->uri, mfi);
+ }
+
+ g_free(old);
+
+ up->path = g_strdup(mfi->path);
+ if (si->storage)
+ up->name = g_strdup(fi->name);
+ up->uri = g_strdup(mfi->uri);
+ up->unread = fi->unread_message_count==-1?0:fi->unread_message_count;
+ up->store = si->store;
+ camel_object_ref((CamelObject *)up->store);
+ if (strstr(fi->url, ";noselect") == NULL)
+ up->add = TRUE;
+
+ e_dlist_addtail(&updates, (EDListNode *)up);
+ flush_updates();
+
+ if (fi->sibling)
+ rename_folders(si, oldbase, newbase, fi->sibling);
+ if (fi->child)
+ rename_folders(si, oldbase, newbase, fi->child);
+}
+
+#if 0
+/* This is if we want to get the folders individually and sort them and change them on
+ the shell atomically (whcih of course, we can't) */
+static void
+get_folders(GPtrArray *folders, CamelFolderInfo *fi)
+{
+}
+
+static int
+folder_cmp(const void *ap, const void *bp)
+{
+ const struct _folder_update *a = ((struct _folder_update **)ap)[0];
+ const struct _folder_update *b = ((struct _folder_update **)bp)[0];
+
+ return strcmp(a->path, b->path);
+}
+#endif
+
+static void
+store_folder_renamed(CamelObject *o, void *event_data, void *data)
+{
+ CamelStore *store = (CamelStore *)o;
+ CamelRenameInfo *info = event_data;
+ struct _store_info *si;
+
+ d(printf("Folder renamed?\n"));
+
+ LOCK(info_lock);
+ si = g_hash_table_lookup(stores, store);
+ if (si) {
+ GPtrArray *folders = g_ptr_array_new();
+ struct _folder_update *up;
+
+#if 0
+ /* first, get an array of all folders */
+ get_folders(folders, info->new);
+#endif
+ rename_folders(si, info->old_base, info->new->full_name, info->new);
+#if 0
+ qsort(folders->pdata, folders->len, sizeof(folders->pdata[0]), folder_cmp);
+ up = g_malloc0(sizeof(*up));
+ up->renamed = folders;
+
+ e_dlist_addtail(&updates, (EDListNode *)up);
+ flush_updates();
+#endif
+ }
+ UNLOCK(info_lock);
+}
+
struct _update_data {
struct _update_data *next;
struct _update_data *prev;
@@ -502,6 +639,7 @@ mail_note_store_remove(CamelStore *store)
camel_object_unhook_event((CamelObject *)store, "folder_created", store_folder_created, NULL);
camel_object_unhook_event((CamelObject *)store, "folder_deleted", store_folder_deleted, NULL);
+ camel_object_unhook_event((CamelObject *)store, "folder_renamed", store_folder_renamed, NULL);
camel_object_unhook_event((CamelObject *)store, "folder_subscribed", store_folder_subscribed, NULL);
camel_object_unhook_event((CamelObject *)store, "folder_unsubscribed", store_folder_unsubscribed, NULL);
g_hash_table_foreach(si->folders, (GHFunc)unset_folder_info_hash, NULL);
@@ -593,6 +731,7 @@ mail_note_store(CamelStore *store, EvolutionStorage *storage, GNOME_Evolution_St
camel_object_hook_event((CamelObject *)store, "folder_created", store_folder_created, NULL);
camel_object_hook_event((CamelObject *)store, "folder_deleted", store_folder_deleted, NULL);
+ camel_object_hook_event((CamelObject *)store, "folder_renamed", store_folder_renamed, NULL);
camel_object_hook_event((CamelObject *)store, "folder_subscribed", store_folder_subscribed, NULL);
camel_object_hook_event((CamelObject *)store, "folder_unsubscribed", store_folder_unsubscribed, NULL);
}