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
This commit is contained in:
@ -22,6 +22,31 @@
|
||||
|
||||
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.
|
||||
|
||||
* component-factory.c (owner_unset_cb): Use a timeout not an idle
|
||||
handler.
|
||||
|
||||
|
@ -322,6 +322,8 @@ xfer_folder (EvolutionShellComponent *shell_component,
|
||||
CamelException ex;
|
||||
GPtrArray *uids;
|
||||
CamelURL *url;
|
||||
|
||||
printf("Renaming folder '%s' to dest '%s' type '%s'\n", source_physical_uri, destination_physical_uri, type);
|
||||
|
||||
url = camel_url_new (destination_physical_uri, NULL);
|
||||
noselect = url ? camel_url_get_param (url, "noselect") : NULL;
|
||||
@ -1091,6 +1093,43 @@ storage_remove_folder (EvolutionStorage *storage,
|
||||
notify_listener (listener, GNOME_Evolution_Storage_INVALID_URI);
|
||||
}
|
||||
|
||||
static void
|
||||
storage_xfer_folder (EvolutionStorage *storage,
|
||||
const Bonobo_Listener listener,
|
||||
const char *source_path,
|
||||
const char *destination_path,
|
||||
gboolean remove_source,
|
||||
CamelStore *store)
|
||||
{
|
||||
CamelException ex;
|
||||
|
||||
printf("Transfer folder on store source = '%s' dest = '%s'\n", source_path, destination_path);
|
||||
|
||||
/* FIXME: Need to remap path to real name */
|
||||
|
||||
if (source_path[0] == '/')
|
||||
source_path++;
|
||||
if (destination_path[0] == '/')
|
||||
destination_path++;
|
||||
|
||||
camel_exception_init (&ex);
|
||||
if (remove_source) {
|
||||
printf("trying to rename\n");
|
||||
camel_store_rename_folder(store, source_path, destination_path, &ex);
|
||||
} else {
|
||||
printf("No remove, can't rename\n");
|
||||
camel_exception_setv(&ex, 1, "Can copy folders");
|
||||
}
|
||||
|
||||
if (camel_exception_is_set(&ex)) {
|
||||
notify_listener (listener, GNOME_Evolution_Storage_INVALID_URI);
|
||||
} else {
|
||||
notify_listener (listener, GNOME_Evolution_Storage_OK);
|
||||
}
|
||||
|
||||
camel_exception_clear (&ex);
|
||||
}
|
||||
|
||||
static void
|
||||
add_storage (const char *name, const char *uri, CamelService *store,
|
||||
GNOME_Evolution_Shell corba_shell, CamelException *ex)
|
||||
@ -1099,12 +1138,9 @@ add_storage (const char *name, const char *uri, CamelService *store,
|
||||
EvolutionStorageResult res;
|
||||
|
||||
storage = evolution_storage_new (name, uri, "mailstorage");
|
||||
gtk_signal_connect (GTK_OBJECT (storage), "create_folder",
|
||||
GTK_SIGNAL_FUNC (storage_create_folder),
|
||||
store);
|
||||
gtk_signal_connect (GTK_OBJECT (storage), "remove_folder",
|
||||
GTK_SIGNAL_FUNC (storage_remove_folder),
|
||||
store);
|
||||
gtk_signal_connect (GTK_OBJECT (storage), "create_folder", storage_create_folder, store);
|
||||
gtk_signal_connect (GTK_OBJECT (storage), "remove_folder", storage_remove_folder, store);
|
||||
gtk_signal_connect ((GtkObject *)storage, "xfer_folder", storage_xfer_folder, store);
|
||||
|
||||
res = evolution_storage_register_on_shell (storage, corba_shell);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -221,6 +221,8 @@ save_metainfo(struct _local_meta *meta)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static CamelFolderClass *mlf_parent_class = NULL;
|
||||
|
||||
/* forward a bunch of functions to the real folder. This pretty
|
||||
* much sucks but I haven't found a better way of doing it.
|
||||
*/
|
||||
@ -401,6 +403,27 @@ mlf_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name,
|
||||
camel_object_unref((CamelObject *)f);
|
||||
}
|
||||
|
||||
/* Internal store-rename call, update our strings */
|
||||
static void
|
||||
mlf_rename(CamelFolder *folder, const char *new)
|
||||
{
|
||||
MailLocalFolder *mlf = (MailLocalFolder *)folder;
|
||||
|
||||
/* first, proxy it down */
|
||||
if (mlf->real_folder)
|
||||
camel_folder_rename(mlf->real_folder, new);
|
||||
|
||||
/* Then do our stuff */
|
||||
g_free(mlf->real_path);
|
||||
mlf->real_path = g_strdup(new);
|
||||
|
||||
g_free(mlf->meta->path);
|
||||
mlf->meta->path = g_strdup_printf("%s/%s/local-metadata.xml", ((CamelService *)folder->parent_store)->url->path, new);
|
||||
|
||||
/* Then pass it up */
|
||||
((CamelFolderClass *)mlf_parent_class)->rename(folder, new);
|
||||
}
|
||||
|
||||
/* and, conversely, forward the real folder's signals. */
|
||||
|
||||
static void
|
||||
@ -446,11 +469,13 @@ static gboolean
|
||||
mlf_set_folder(MailLocalFolder *mlf, guint32 flags, CamelException *ex)
|
||||
{
|
||||
CamelFolder *folder = (CamelFolder *)mlf;
|
||||
char *uri;
|
||||
char *uri, *mbox;
|
||||
|
||||
g_assert(mlf->real_folder == NULL);
|
||||
|
||||
uri = g_strdup_printf("%s:%s%s", mlf->meta->format, ((CamelService *)folder->parent_store)->url->path, mlf->real_path);
|
||||
/*uri = g_strdup_printf("%s:%s%s", mlf->meta->format, ((CamelService *)folder->parent_store)->url->path, mlf->real_path);*/
|
||||
uri = g_strdup_printf("%s:%s", mlf->meta->format, ((CamelService *)folder->parent_store)->url->path);
|
||||
|
||||
d(printf("opening real store: %s\n", uri));
|
||||
mlf->real_store = camel_session_get_store(session, uri, ex);
|
||||
g_free(uri);
|
||||
@ -460,7 +485,11 @@ mlf_set_folder(MailLocalFolder *mlf, guint32 flags, CamelException *ex)
|
||||
if (mlf->meta->indexed)
|
||||
flags |= CAMEL_STORE_FOLDER_BODY_INDEX;
|
||||
|
||||
mlf->real_folder = camel_store_get_folder(mlf->real_store, mlf->meta->name, flags, ex);
|
||||
/* mlf->real_folder = camel_store_get_folder(mlf->real_store, mlf->meta->name, flags, ex); */
|
||||
mbox = g_strdup_printf("%s/%s", mlf->real_path, mlf->meta->name);
|
||||
printf("Opening mbox on real path: %s\n", mbox);
|
||||
mlf->real_folder = camel_store_get_folder(mlf->real_store, mbox, flags, ex);
|
||||
g_free(mbox);
|
||||
if (mlf->real_folder == NULL)
|
||||
return FALSE;
|
||||
|
||||
@ -497,6 +526,8 @@ mlf_class_init (CamelObjectClass *camel_object_class)
|
||||
camel_folder_class->set_message_flags = mlf_set_message_flags;
|
||||
camel_folder_class->set_message_user_flag = mlf_set_message_user_flag;
|
||||
camel_folder_class->set_message_user_tag = mlf_set_message_user_tag;
|
||||
|
||||
camel_folder_class->rename = mlf_rename;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -538,6 +569,7 @@ mail_local_folder_get_type (void)
|
||||
NULL,
|
||||
mlf_init,
|
||||
mlf_finalize);
|
||||
mlf_parent_class = (CamelFolderClass *)camel_type_get_global_classfuncs (CAMEL_FOLDER_TYPE);
|
||||
}
|
||||
|
||||
return mail_local_folder_type;
|
||||
@ -772,6 +804,51 @@ mls_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex
|
||||
g_free(metapath);
|
||||
}
|
||||
|
||||
static void
|
||||
mls_rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex)
|
||||
{
|
||||
char *oldname, *newname;
|
||||
|
||||
/* folder:rename() updates all our in-memory data to match */
|
||||
|
||||
/* FIXME: Need to lock the subfolder that matches this if its open
|
||||
Then rename it and unlock it when done */
|
||||
|
||||
printf("Renaming folder from '%s' to '%s'\n", old_name, new_name);
|
||||
|
||||
oldname = g_strdup_printf("%s%s", ((CamelService *)store)->url->path, old_name);
|
||||
newname = g_strdup_printf("%s%s", ((CamelService *)store)->url->path, new_name);
|
||||
|
||||
if (rename(oldname, newname) == -1) {
|
||||
printf("Rename failed!\n");
|
||||
camel_exception_setv(ex, 1, "Rename failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
g_free(oldname);
|
||||
g_free(newname);
|
||||
#if 0
|
||||
/* find the real store for this folder, and proxy the call */
|
||||
metapath = g_strdup_printf("%s%s/local-metadata.xml", ((CamelService *)store)->url->path, old_name);
|
||||
meta = load_metainfo(metapath);
|
||||
uri = g_strdup_printf("%s:%s%s", meta->format, ((CamelService *)store)->url->path);
|
||||
real_store = (CamelStore *)camel_session_get_service(session, uri, CAMEL_PROVIDER_STORE, ex);
|
||||
g_free(uri);
|
||||
if (real_store == NULL) {
|
||||
g_free(metapath);
|
||||
free_metainfo(meta);
|
||||
return;
|
||||
}
|
||||
oldname = g_strdup_printf("%s/%s", old_name, mlf->meta->name);
|
||||
newname = g_strdup_printf("%s/%s", new_name, mlf->meta->name);
|
||||
|
||||
camel_store_rename_folder(real_store, old_name, new_name, &local_ex);
|
||||
|
||||
|
||||
|
||||
camel_exception_setv(ex, 1, "Not supported");
|
||||
#endif
|
||||
}
|
||||
|
||||
static char *
|
||||
mls_get_name (CamelService *service, gboolean brief)
|
||||
{
|
||||
@ -814,6 +891,7 @@ mls_class_init (CamelObjectClass *camel_object_class)
|
||||
camel_service_class->get_name = mls_get_name;
|
||||
camel_store_class->get_folder = mls_get_folder;
|
||||
camel_store_class->delete_folder = mls_delete_folder;
|
||||
camel_store_class->rename_folder = mls_rename_folder;
|
||||
|
||||
local_store_parent_class = camel_type_get_global_classfuncs (CAMEL_STORE_TYPE);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@
|
||||
|
||||
#include "e-util/e-unicode-i18n.h"
|
||||
|
||||
#define d(x)
|
||||
#define d(x) x
|
||||
|
||||
static VfolderContext *context; /* context remains open all time */
|
||||
static CamelStore *vfolder_store; /* the 1 static vfolder store */
|
||||
@ -458,16 +458,30 @@ rule_changed(FilterRule *rule, CamelFolder *folder)
|
||||
char *path, *key;
|
||||
CamelFolder *old;
|
||||
|
||||
LOCK();
|
||||
if (g_hash_table_lookup_extended(vfolder_hash, folder->full_name, (void **)&key, (void **)&old)) {
|
||||
g_hash_table_remove(vfolder_hash, key);
|
||||
g_free(key);
|
||||
g_hash_table_insert(vfolder_hash, g_strdup(rule->name), folder);
|
||||
UNLOCK();
|
||||
} else {
|
||||
UNLOCK();
|
||||
g_warning("couldn't find a vfolder rule in our table? %s", folder->full_name);
|
||||
}
|
||||
|
||||
camel_store_rename_folder(vfolder_store, folder->full_name, rule->name, NULL);
|
||||
|
||||
#if 0
|
||||
path = g_strdup_printf("/%s", folder->full_name);
|
||||
evolution_storage_removed_folder(mail_lookup_storage(vfolder_store), path);
|
||||
g_free(path);
|
||||
|
||||
gtk_signal_disconnect_by_func((GtkObject *)rule, rule_changed, folder);
|
||||
|
||||
context_rule_added((RuleContext *)context, rule);
|
||||
|
||||
/* TODO: remove folder from folder info cache? */
|
||||
|
||||
path = g_strdup_printf("/%s", folder->full_name);
|
||||
evolution_storage_removed_folder(mail_lookup_storage(vfolder_store), path);
|
||||
g_free(path);
|
||||
|
||||
LOCK();
|
||||
if (g_hash_table_lookup_extended(vfolder_hash, folder->full_name, (void **)&key, (void **)&old)) {
|
||||
g_hash_table_remove(vfolder_hash, key);
|
||||
@ -480,6 +494,7 @@ rule_changed(FilterRule *rule, CamelFolder *folder)
|
||||
}
|
||||
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
d(printf("Filter rule changed? for folder '%s'!!\n", folder->name));
|
||||
@ -595,8 +610,12 @@ store_folder_deleted(CamelObject *o, void *event_data, void *data)
|
||||
d(printf("Folder deleted: %s\n", info->name));
|
||||
store = store;
|
||||
|
||||
/* WARNING: Not thread safe, joy! */
|
||||
|
||||
LOCK();
|
||||
|
||||
/* delete it from our list */
|
||||
rule = rule_context_find_rule((RuleContext *)context, info->name, NULL);
|
||||
rule = rule_context_find_rule((RuleContext *)context, info->full_name, NULL);
|
||||
if (rule) {
|
||||
/* We need to stop listening to removed events, otherwise we'll try and remove it again */
|
||||
gtk_signal_disconnect_by_func((GtkObject *)context, context_rule_removed, context);
|
||||
@ -610,6 +629,34 @@ store_folder_deleted(CamelObject *o, void *event_data, void *data)
|
||||
} else {
|
||||
g_warning("Cannot find rule for deleted vfolder '%s'", info->name);
|
||||
}
|
||||
|
||||
UNLOCK();
|
||||
}
|
||||
|
||||
static void
|
||||
store_folder_renamed(CamelObject *o, void *event_data, void *data)
|
||||
{
|
||||
CamelStore *store = (CamelStore *)o;
|
||||
CamelRenameInfo *info = event_data;
|
||||
FilterRule *rule;
|
||||
char *user;
|
||||
|
||||
/* TODO: Scan all sub-folders? */
|
||||
|
||||
printf("Folder renamed to '%s' from '%s'\n", info->new->full_name, info->old_base);
|
||||
|
||||
rule = rule_context_find_rule((RuleContext *)context, info->old_base, NULL);
|
||||
if (rule) {
|
||||
/* TODO: We need to stop listening to removed events, otherwise we'll try and rename it again? */
|
||||
|
||||
filter_rule_set_name(rule, info->new->name);
|
||||
|
||||
user = g_strdup_printf("%s/vfolders.xml", evolution_dir);
|
||||
rule_context_save((RuleContext *)context, user);
|
||||
g_free(user);
|
||||
} else {
|
||||
/* We just got it inside renaming it ourself, ignore */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -632,6 +679,8 @@ vfolder_load_storage(GNOME_Evolution_Shell shell)
|
||||
(CamelObjectEventHookFunc)store_folder_created, NULL);
|
||||
camel_object_hook_event((CamelObject *)vfolder_store, "folder_deleted",
|
||||
(CamelObjectEventHookFunc)store_folder_deleted, NULL);
|
||||
camel_object_hook_event((CamelObject *)vfolder_store, "folder_renamed",
|
||||
(CamelObjectEventHookFunc)store_folder_renamed, NULL);
|
||||
|
||||
d(printf("got store '%s' = %p\n", storeuri, vfolder_store));
|
||||
mail_load_storage_by_uri(shell, storeuri, U_("VFolders"));
|
||||
|
Reference in New Issue
Block a user