diff options
author | 8 <NotZed@Ximian.com> | 2001-09-29 07:54:30 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2001-09-29 07:54:30 +0800 |
commit | 4b14db5520cf99cb30d39e14c2bb38071d4cad2d (patch) | |
tree | 54fa8819aa23d242cccd69a3ed365e69a690bee6 | |
parent | f1eb4aa8cf71a6e690eb76e00a3d5111035931b6 (diff) | |
download | gsoc2013-evolution-4b14db5520cf99cb30d39e14c2bb38071d4cad2d.tar.gz gsoc2013-evolution-4b14db5520cf99cb30d39e14c2bb38071d4cad2d.tar.zst gsoc2013-evolution-4b14db5520cf99cb30d39e14c2bb38071d4cad2d.zip |
Emit folder_deleted event. (remove_find_path): Fix, compare against path,
2001-09-28 <NotZed@Ximian.com>
* mail-local.c (mail_local_store_remove_folder): Emit
folder_deleted event.
(remove_find_path): Fix, compare against path, not full_name.
* mail-tools.c (mail_tool_uri_to_folder): Dont
vfolder_register_source anymore.
* mail-vfolder.c (rule_changed): Changed to access
mail_fodler_cahce to find out if the folder exist yet before
trying to open them, also use the cache as a cache so we dont have
to open the folder if its already been opened.
(vfolder_register_source, register_source): Removed.
(source_finalise): Removed,
(check_source): Removed. All handled through diff mechanism.
(mail_vfolder_add_uri): New function, records uri's of available
folders, and adds them to any active vfolders if required.
(mail_vfolder_remove_uri): New function, removes a uri from
available folders, and checks any rules to see fi they need
updating.
(vfolder_adduri): New async function to add a uri to all vfolders
that need it.
(store_folder_deleted): oops! free user, not rule!!
* mail-folder-cache.c: Add uri->folderinfo hashtable, and the
store from which they come into the store info struct.
Add uri to the folder_info.
(setup_folder): Store the uri in the folderinfo.
(setup_folder): And the uri in the folder_uri hashtable.
(mail_note_store): Store the store in the storeinfo, and setup the
folders_uri hashtable via the store's hash functions.
(setup_folder): Call mail_vfolder_add_uri to note this newly setup
folder uri.
(store_folder_deleted): Proxy call to main thread.
(real_folder_deleted): And tell the vfolder to remove this uri
from its folder list.
(setup_folder): Dont call vfolder_add_uri if noselect is set on
the uri.
2001-09-27 <NotZed@Ximian.com>
* mail-vfolder.c: Removed vfolder_info struct, vfolder_storage.
Neither used anymore.
svn path=/trunk/; revision=13242
-rw-r--r-- | mail/ChangeLog | 45 | ||||
-rw-r--r-- | mail/component-factory.c | 6 | ||||
-rw-r--r-- | mail/mail-folder-cache.c | 75 | ||||
-rw-r--r-- | mail/mail-folder-cache.h | 4 | ||||
-rw-r--r-- | mail/mail-local.c | 10 | ||||
-rw-r--r-- | mail/mail-tools.c | 4 | ||||
-rw-r--r-- | mail/mail-vfolder.c | 399 | ||||
-rw-r--r-- | mail/mail-vfolder.h | 8 |
8 files changed, 437 insertions, 114 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index b297f0614e..dd3daf533c 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,48 @@ +2001-09-28 <NotZed@Ximian.com> + + * mail-local.c (mail_local_store_remove_folder): Emit + folder_deleted event. + (remove_find_path): Fix, compare against path, not full_name. + + * mail-tools.c (mail_tool_uri_to_folder): Dont + vfolder_register_source anymore. + + * mail-vfolder.c (rule_changed): Changed to access + mail_fodler_cahce to find out if the folder exist yet before + trying to open them, also use the cache as a cache so we dont have + to open the folder if its already been opened. + (vfolder_register_source, register_source): Removed. + (source_finalise): Removed, + (check_source): Removed. All handled through diff mechanism. + (mail_vfolder_add_uri): New function, records uri's of available + folders, and adds them to any active vfolders if required. + (mail_vfolder_remove_uri): New function, removes a uri from + available folders, and checks any rules to see fi they need + updating. + (vfolder_adduri): New async function to add a uri to all vfolders + that need it. + (store_folder_deleted): oops! free user, not rule!! + + * mail-folder-cache.c: Add uri->folderinfo hashtable, and the + store from which they come into the store info struct. + Add uri to the folder_info. + (setup_folder): Store the uri in the folderinfo. + (setup_folder): And the uri in the folder_uri hashtable. + (mail_note_store): Store the store in the storeinfo, and setup the + folders_uri hashtable via the store's hash functions. + (setup_folder): Call mail_vfolder_add_uri to note this newly setup + folder uri. + (store_folder_deleted): Proxy call to main thread. + (real_folder_deleted): And tell the vfolder to remove this uri + from its folder list. + (setup_folder): Dont call vfolder_add_uri if noselect is set on + the uri. + +2001-09-27 <NotZed@Ximian.com> + + * mail-vfolder.c: Removed vfolder_info struct, vfolder_storage. + Neither used anymore. + 2001-09-28 Jeffrey Stedfast <fejj@ximian.com> * mail-config.c (mail_config_get_account_by_transport_url): Use diff --git a/mail/component-factory.c b/mail/component-factory.c index 4696351613..6fb72410af 100644 --- a/mail/component-factory.c +++ b/mail/component-factory.c @@ -672,6 +672,8 @@ owner_set_cb (EvolutionShellComponent *shell_component, corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); + vfolder_load_storage(corba_shell); + accounts = mail_config_get_accounts (); mail_load_storages (corba_shell, accounts, TRUE); @@ -689,9 +691,7 @@ owner_set_cb (EvolutionShellComponent *shell_component, } mail_session_enable_interaction (TRUE); - - vfolder_load_storage(corba_shell); - + mail_autoreceive_setup (); if (mail_config_is_corrupt ()) { diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c index 9ccf138a75..5d5f81e2a9 100644 --- a/mail/mail-folder-cache.c +++ b/mail/mail-folder-cache.c @@ -40,6 +40,7 @@ #include "mail-mt.h" #include "mail-folder-cache.h" #include "mail-ops.h" +#include "mail-vfolder.h" #define d(x) @@ -56,11 +57,16 @@ struct _folder_info { char *path; /* shell path */ char *name; /* shell display name? */ char *full_name; /* full name of folder/folderinfo */ + char *uri; /* uri of folder */ + CamelFolder *folder; /* if known */ }; struct _store_info { GHashTable *folders; /* by full_name */ + GHashTable *folders_uri; /* by uri */ + + CamelStore *store; /* the store for these folders */ /* only 1 should be set */ EvolutionStorage *storage; @@ -136,6 +142,7 @@ setup_folder(CamelFolderInfo *fi, struct _store_info *si) { struct _folder_info *mfi; char *type; + CamelStore *store; LOCK(info_lock); mfi = g_hash_table_lookup(si->folders, fi->full_name); @@ -149,8 +156,12 @@ setup_folder(CamelFolderInfo *fi, struct _store_info *si) mfi->path = g_strdup(fi->path); mfi->name = g_strdup(fi->name); 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); + store = si->store; + camel_object_ref((CamelObject *)store); UNLOCK(info_lock); if (si->storage != NULL) { @@ -160,6 +171,11 @@ setup_folder(CamelFolderInfo *fi, struct _store_info *si) evolution_storage_new_folder(si->storage, mfi->path, mfi->name, type, fi->url, mfi->name, unread); } + + if (strstr(fi->url, ";noselect") == NULL) + mail_vfolder_add_uri(store, fi->url); + + camel_object_unref((CamelObject *)store); } } @@ -248,7 +264,7 @@ real_folder_created(CamelStore *store, void *event_data, CamelFolderInfo *fi) { struct _store_info *si; - d(printf("real_folder_created: %s (%s)\n", fi->full_name, fi->url)); + (printf("real_folder_created: %s (%s)\n", fi->full_name, fi->url)); LOCK(info_lock); si = g_hash_table_lookup(stores, store); @@ -274,6 +290,15 @@ store_folder_created(CamelObject *o, void *event_data, void *data) } static void +real_folder_deleted(CamelStore *store, void *event_data, CamelFolderInfo *fi) +{ + (printf("real_folder_deleted: %s (%s)\n", fi->full_name, fi->url)); + + if (strstr(fi->url, ";noselect") == NULL) + mail_vfolder_remove_uri(store, fi->url); +} + +static void store_folder_deleted(CamelObject *o, void *event_data, void *data) { CamelStore *store = (CamelStore *)o; @@ -284,6 +309,8 @@ store_folder_deleted(CamelObject *o, void *event_data, void *data) /* should really remove it? */ d(printf("folder deleted: %s\n", info->full_name)); + + mail_msg_wait(mail_proxy_event((CamelObjectEventHookFunc)real_folder_deleted, o, NULL, info)); } static void @@ -292,6 +319,7 @@ free_folder_info(char *path, struct _folder_info *info, void *data) g_free(info->path); g_free(info->name); g_free(info->full_name); + g_free(info->uri); } static void @@ -315,8 +343,10 @@ store_finalised(CamelObject *o, void *event_data, void *data) static void create_folders(CamelFolderInfo *fi, struct _store_info *si) { + printf("Setup new folder: %s\n", fi->url); + setup_folder(fi, si); - + if (fi->child) create_folders(fi->child, si); if (fi->sibling) @@ -365,12 +395,15 @@ mail_note_store(CamelStore *store, EvolutionStorage *storage, GNOME_Evolution_St d(printf("Noting a new store: %p: %s\n", store, camel_url_to_string(((CamelService *)store)->url, 0))); - /* FIXME: Need to ref the storages or something?? */ + /* FIXME: Need to ref the storages & store or something?? */ si = g_malloc0(sizeof(*si)); si->folders = g_hash_table_new(g_str_hash, g_str_equal); + si->folders_uri = g_hash_table_new(CAMEL_STORE_CLASS(CAMEL_OBJECT_GET_CLASS(store))->hash_folder_name, + CAMEL_STORE_CLASS(CAMEL_OBJECT_GET_CLASS(store))->compare_folder_name); si->storage = storage; si->corba_storage = corba_storage; + si->store = store; g_hash_table_insert(stores, store, si); camel_object_hook_event((CamelObject *)store, "folder_created", store_folder_created, NULL); @@ -387,3 +420,39 @@ mail_note_store(CamelStore *store, EvolutionStorage *storage, GNOME_Evolution_St mail_get_folderinfo(store, update_folders, ud); } + +struct _find_info { + const char *uri; + struct _folder_info *fi; +}; + +/* look up on each storeinfo using proper hash function for that stores uri's */ +static void storeinfo_find_folder_info(CamelStore *store, struct _store_info *si, struct _find_info *fi) +{ + if (fi->fi == NULL) + fi->fi = g_hash_table_lookup(si->folders_uri, fi->uri); +} + +/* returns TRUE if the uri is available, folderp is set to a + reffed folder if the folder has also already been opened */ +int mail_note_get_folder_from_uri(const char *uri, CamelFolder **folderp) +{ + struct _find_info fi = { uri, NULL }; + + if (stores == NULL) + return FALSE; + + LOCK(info_lock); + g_hash_table_foreach(stores, (GHFunc)storeinfo_find_folder_info, &fi); + if (folderp) { + if (fi.fi && fi.fi->folder) { + *folderp = fi.fi->folder; + camel_object_ref((CamelObject *)*folderp); + } else { + *folderp = NULL; + } + } + UNLOCK(info_lock); + + return fi.fi != NULL; +} diff --git a/mail/mail-folder-cache.h b/mail/mail-folder-cache.h index 34be34425b..92cbfa6739 100644 --- a/mail/mail-folder-cache.h +++ b/mail/mail-folder-cache.h @@ -41,4 +41,8 @@ mail_note_store(CamelStore *store, EvolutionStorage *storage, GNOME_Evolution_St */ void mail_note_folder(struct _CamelFolder *folder); +/* Returns true if a folder is available (yet), and also sets *folderp (if supplied) + to a (referenced) copy of the folder if it has already been opened */ +int mail_note_get_folder_from_uri(const char *uri, CamelFolder **folderp); + #endif diff --git a/mail/mail-local.c b/mail/mail-local.c index 6af58a87e2..5fbb457543 100644 --- a/mail/mail-local.c +++ b/mail/mail-local.c @@ -858,7 +858,7 @@ struct _search_info { static void remove_find_path(char *uri, CamelFolderInfo *info, struct _search_info *data) { - if (!strcmp(info->full_name, data->path)) + if (!strcmp(info->path, data->path)) data->info = info; } @@ -870,14 +870,18 @@ static void mail_local_store_remove_folder(MailLocalStore *mls, const char *path LOCAL_STORE_LOCK(mls); g_hash_table_foreach(mls->folder_infos, (GHFunc)remove_find_path, &data); - if (data.info) { + if (data.info) g_hash_table_remove(mls->folder_infos, data.info->url); + LOCAL_STORE_UNLOCK(mls); + + if (data.info) { + camel_object_trigger_event((CamelObject *)mls, "folder_deleted", data.info); + g_free(data.info->url); g_free(data.info->full_name); g_free(data.info->name); g_free(data.info); } - LOCAL_STORE_UNLOCK(mls); } /* ** Local Provider ************************************************************** */ diff --git a/mail/mail-tools.c b/mail/mail-tools.c index 16e37047d9..2844f74097 100644 --- a/mail/mail-tools.c +++ b/mail/mail-tools.c @@ -360,10 +360,8 @@ mail_tool_uri_to_folder (const char *uri, CamelException *ex) camel_object_unref (CAMEL_OBJECT (store)); } - if (folder) { - vfolder_register_source (folder); + if (folder) mail_note_folder (folder); - } camel_url_free (url); diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c index 48943eea26..185a2e92c2 100644 --- a/mail/mail-vfolder.c +++ b/mail/mail-vfolder.c @@ -12,6 +12,11 @@ #include <config.h> #endif +#include <glib.h> +#include <libgnome/gnome-defs.h> +#include <libgnome/gnome-i18n.h> +#include <libgnomeui/gnome-dialog.h> +#include <libgnomeui/gnome-dialog-util.h> #include <libgnomeui/gnome-stock.h> #include "Evolution.h" @@ -30,22 +35,14 @@ #include "camel/camel.h" #include "camel/camel-remote-store.h" #include "camel/camel-vee-folder.h" +#include "camel/camel-vee-store.h" #include "filter/vfolder-context.h" #include "filter/vfolder-editor.h" #include "e-util/e-unicode-i18n.h" -#define d(x) - -struct _vfolder_info { - char *name; - char *query; - FilterRule *rule; - CamelVeeFolder *folder; -}; - -/* list of vfolders available */ +#define d(x) x static VfolderContext *context; /* context remains open all time */ static CamelStore *vfolder_store; /* the 1 static vfolder store */ @@ -53,97 +50,23 @@ static CamelStore *vfolder_store; /* the 1 static vfolder store */ /* lock for accessing shared resources (below) */ static pthread_mutex_t vfolder_lock = PTHREAD_MUTEX_INITIALIZER; -static GList *source_folders; /* list of source folders */ +static GList *source_folders_remote; /* list of source folder uri's - remote ones */ +static GList *source_folders_local; /* list of source folder uri's - local ones */ static GHashTable *vfolder_hash; - -/* Ditto below */ -EvolutionStorage *vfolder_storage; - extern EvolutionShellClient *global_shell_client; /* more globals ... */ extern char *evolution_dir; extern CamelSession *session; +static void rule_changed(FilterRule *rule, CamelFolder *folder); + #define LOCK() pthread_mutex_lock(&vfolder_lock); #define UNLOCK() pthread_mutex_unlock(&vfolder_lock); /* ********************************************************************** */ -/* return true if this folder should be added to this rule */ -static int -check_source(FilterRule *rule, CamelFolder *folder) -{ - extern CamelFolder *drafts_folder, *outbox_folder, *sent_folder; - - if (folder == drafts_folder || folder == outbox_folder || folder == sent_folder) - return FALSE; - - if (rule->source) { - int remote = (((CamelService *)folder->parent_store)->provider->flags & CAMEL_PROVIDER_IS_REMOTE) != 0; - - if (!strcmp(rule->source, "local")) { - if (!remote) { - return TRUE; - } - } else if (!strcmp(rule->source, "remote_active")) { - if (remote) { - return TRUE; - } - } else if (!strcmp(rule->source, "local_remote_active")) { - return TRUE; - } - } - - return FALSE; -} - -static void -register_source(char *key, CamelVeeFolder *vfolder, CamelFolder *folder) -{ - FilterRule *rule; - - rule = rule_context_find_rule((RuleContext *)context, key, NULL); - if (rule && check_source(rule, folder)) - camel_vee_folder_add_folder(vfolder, folder); -} - -/* the source will never be finalised while a vfolder has it */ -static void -source_finalise(CamelFolder *folder, void *event_data, void *data) -{ - LOCK(); - source_folders = g_list_remove(source_folders, folder); - UNLOCK(); -} - -/* for registering potential vfolder sources */ -void -vfolder_register_source (CamelFolder *folder) -{ - if (CAMEL_IS_VEE_FOLDER(folder)) - return; - - LOCK(); - if (g_list_find(source_folders, folder)) { - UNLOCK(); - return; - } - - /* note that once we register a source, it will be ref'd - by our vfolder ... and wont go away with this, but we - do this so our source_folders list doesn't get stale */ - camel_object_hook_event((CamelObject *)folder, "finalize", (CamelObjectEventHookFunc)source_finalise, folder); - - source_folders = g_list_append(source_folders, folder); - if (vfolder_hash) - g_hash_table_foreach(vfolder_hash, (GHFunc)register_source, folder); - UNLOCK(); -} - -/* ********************************************************************** */ - struct _setup_msg { struct _mail_msg msg; @@ -174,6 +97,7 @@ vfolder_setup_do(struct _mail_msg *mm) l = m->sources_uri; while (l) { + (printf(" Adding uri: %s\n", (char *)l->data)); folder = mail_tool_uri_to_folder(l->data, &mm->ex); if (folder) { list = g_list_append(list, folder); @@ -186,6 +110,7 @@ vfolder_setup_do(struct _mail_msg *mm) l = m->sources_folder; while (l) { + d(printf(" Adding folder: %s\n", ((CamelFolder *)l->data)->full_name)); camel_object_ref((CamelObject *)l->data); list = g_list_append(list, l->data); l = l->next; @@ -261,6 +186,260 @@ vfolder_setup(CamelFolder *folder, const char *query, GList *sources_uri, GList /* ********************************************************************** */ +struct _adduri_msg { + struct _mail_msg msg; + + char *uri; + GList *folders; +}; + +static char * +vfolder_adduri_desc(struct _mail_msg *mm, int done) +{ + struct _adduri_msg *m = (struct _adduri_msg *)mm; + + return g_strdup_printf(_("Updating vfolders for uri: %s"), m->uri); +} + +static void +vfolder_adduri_do(struct _mail_msg *mm) +{ + struct _adduri_msg *m = (struct _adduri_msg *)mm; + GList *l; + CamelFolder *folder; + extern CamelFolder *drafts_folder, *outbox_folder, *sent_folder; + + d(printf("Adding uri to vfolder: %s\n", m->uri)); + + if (!mail_note_get_folder_from_uri(m->uri, &folder)) { + g_warning("Folder '%s' disappeared while I was adding it to my vfolder", m->uri); + return; + } + + if (folder == NULL) + folder = mail_tool_uri_to_folder(m->uri, &mm->ex); + + if (folder != NULL) { + if (folder != drafts_folder && folder != outbox_folder && folder != sent_folder) { + l = m->folders; + while (l) { + camel_vee_folder_add_folder((CamelVeeFolder *)l->data, folder); + l = l->next; + } + } + camel_object_unref((CamelObject *)folder); + } +} + +static void +vfolder_adduri_done(struct _mail_msg *mm) +{ + struct _adduri_msg *m = (struct _adduri_msg *)mm; + + m = m; +} + +static void +vfolder_adduri_free (struct _mail_msg *mm) +{ + struct _adduri_msg *m = (struct _adduri_msg *)mm; + + g_list_foreach(m->folders, (GFunc)camel_object_unref, NULL); + g_list_free(m->folders); + g_free(m->uri); +} + +static struct _mail_msg_op vfolder_adduri_op = { + vfolder_adduri_desc, + vfolder_adduri_do, + vfolder_adduri_done, + vfolder_adduri_free, +}; + +static int +vfolder_adduri(const char *uri, GList *folders) +{ + struct _adduri_msg *m; + int id; + + m = mail_msg_new(&vfolder_adduri_op, NULL, sizeof (*m)); + m->folders = folders; + m->uri = g_strdup(uri); + + id = m->msg.seq; + e_thread_put(mail_thread_queued_slow, (EMsg *)m); + + return id; +} + +/* ********************************************************************** */ + +/* So, uh, apparently g_list_find_custom expect the compare func to return 0 to mean true? */ +static GList * +my_list_find(GList *l, const char *uri, GCompareFunc cmp) +{ + while (l) { + if (cmp(l->data, uri)) + break; + l = l->next; + } + return l; +} + +/* called when a new uri becomes available */ +void +mail_vfolder_add_uri(CamelStore *store, const char *uri) +{ + FilterRule *rule; + const char *source; + CamelVeeFolder *vf; + GList *folders = NULL; + int remote = (((CamelService *)store)->provider->flags & CAMEL_PROVIDER_IS_REMOTE) != 0; + GCompareFunc uri_cmp = CAMEL_STORE_CLASS(CAMEL_OBJECT_GET_CLASS(store))->compare_folder_name; + + if (CAMEL_IS_VEE_STORE(store) || !strncmp(uri, "vtrash:", 7)) + return; + + LOCK(); + + printf("Adding uri to check: %s\n", uri); + + /* maintain the source folders lists for changed rules later on */ + if (remote) { + if (my_list_find(source_folders_remote, (void *)uri, uri_cmp) == NULL) + source_folders_remote = g_list_prepend(source_folders_remote, g_strdup(uri)); + } else { + if (my_list_find(source_folders_local, (void *)uri, uri_cmp) == NULL) + source_folders_local = g_list_prepend(source_folders_local, g_strdup(uri)); + } + + rule = NULL; + while ( (rule = rule_context_next_rule((RuleContext *)context, rule, NULL)) ) { + int found = FALSE; + + if (rule->source + && ((!strcmp(rule->source, "local") && !remote) + || (!strcmp(rule->source, "remote_active") && remote) + || (!strcmp(rule->source, "local_remote_active")))) + found = TRUE; + + /* we check using the store uri_cmp since its more accurate */ + source = NULL; + while ( !found && (source = vfolder_rule_next_source((VfolderRule *)rule, source)) ) + found = uri_cmp(uri, source); + + if (found) { + vf = g_hash_table_lookup(vfolder_hash, rule->name); + g_assert(vf); + camel_object_ref((CamelObject *)vf); + folders = g_list_prepend(folders, vf); + } + } + + UNLOCK(); + + if (folders != NULL) + vfolder_adduri(uri, folders); +} + +/* called when a uri is removed from a store */ +void +mail_vfolder_remove_uri(CamelStore *store, const char *uri) +{ + int remote = (((CamelService *)store)->provider->flags & CAMEL_PROVIDER_IS_REMOTE) != 0; + GCompareFunc uri_cmp = CAMEL_STORE_CLASS(CAMEL_OBJECT_GET_CLASS(store))->compare_folder_name; + GList *link; + FilterRule *rule; + const char *source; + CamelVeeFolder *vf; + GString *changed; + + if (CAMEL_IS_VEE_STORE(store) || !strncmp(uri, "vtrash:", 7)) + return; + + printf("Removing uri to check: %s\n", uri); + + g_assert(pthread_self() == mail_gui_thread); + + changed = g_string_new(""); + + LOCK(); + + /* maintain remote/local lists */ + if (remote) { + if ((link = my_list_find(source_folders_remote, (void *)uri, uri_cmp)) == NULL) { + g_free(link->data); + source_folders_remote = g_list_remove_link(source_folders_remote, link); + } + } else { + if ((link = my_list_find(source_folders_local, (void *)uri, uri_cmp)) == NULL) { + g_free(link->data); + source_folders_local = g_list_remove_link(source_folders_local, link); + } + } + + printf("vfolder remove uri: %s\n", uri); + + /* check to see if a rule needs updating, if it does, make out it changed which will re-build it */ + rule = NULL; + while ( (rule = rule_context_next_rule((RuleContext *)context, rule, NULL)) ) { + int found = FALSE; + + source = NULL; + while ( !found && (source = vfolder_rule_next_source((VfolderRule *)rule, source)) ) + found = uri_cmp(uri, source); + + if (found + || (rule->source + && ((!strcmp(rule->source, "local") && !remote) + || (!strcmp(rule->source, "remote_active") && remote) + || (!strcmp(rule->source, "local_remote_active"))))) { + + vf = g_hash_table_lookup(vfolder_hash, rule->name); + g_assert(vf); + if (source) { + vfolder_rule_remove_source((VfolderRule *)rule, source); + g_string_sprintfa(changed, " %s\n", rule->name); + } else + rule_changed(rule, (CamelFolder *)vf); + } + } + + UNLOCK(); + + if (changed->str[0]) { + GnomeDialog *gd; + char *text, *user; + + text = g_strdup_printf(_("The following vFolder(s):\n%s" + "Used the removed folder:\n '%s'\n" + "And have been updated."), + changed->str, uri); + + gd = (GnomeDialog *)gnome_warning_dialog(text); + g_free(text); + gnome_dialog_set_close(gd, TRUE); + gtk_widget_show((GtkWidget *)gd); + + user = g_strdup_printf("%s/vfolders.xml", evolution_dir); + rule_context_save((RuleContext *)context, user); + g_free(user); + } + + g_string_free(changed, TRUE); +} + +/* called when a uri is renamed in a store */ +#if 0 +void +mail_vfolder_rename_uri(CamelStore *store, const char *from, const char *to) +{ + printf("vfolder rename uri: %s to %s\n", from, to); +} +#endif + +/* ********************************************************************** */ + static void context_rule_added(RuleContext *ctx, FilterRule *rule); static void @@ -270,6 +449,8 @@ rule_changed(FilterRule *rule, CamelFolder *folder) GList *l; GList *sources_uri = NULL, *sources_folder = NULL; GString *query; + int i; + CamelFolder *newfolder; /* if the folder has changed name, then add it, then remove the old manually */ if (strcmp(folder->full_name, rule->name) != 0) { @@ -302,22 +483,42 @@ rule_changed(FilterRule *rule, CamelFolder *folder) d(printf("Filter rule changed? for folder '%s'!!\n", folder->name)); - /* work out the work to do, then do it in another thread */ + /* find any (currently available) folders, and add them to the ones to open */ sourceuri = NULL; while ( (sourceuri = vfolder_rule_next_source((VfolderRule *)rule, sourceuri)) ) { - sources_uri = g_list_append(sources_uri, g_strdup(sourceuri)); + if (mail_note_get_folder_from_uri(sourceuri, &newfolder)) { + if (newfolder) + sources_folder = g_list_append(sources_folder, newfolder); + else + sources_uri = g_list_append(sources_uri, g_strdup(sourceuri)); + } } - LOCK(); - l = source_folders; - while (l) { - if (check_source(rule, l->data)) { - camel_object_ref(l->data); - sources_folder = g_list_append(sources_folder, l->data); + /* check the remote/local uri lists for any other uri's that should be looked at */ + if (rule->source) { + LOCK(); + for (i=0;i<2;i++) { + if (i==0 && (!strcmp(rule->source, "local") || !strcmp(rule->source, "local_remote_active"))) + l = source_folders_local; + else if (i==1 && (!strcmp(rule->source, "remote_active") || !strcmp(rule->source, "local_remote_active"))) + l = source_folders_remote; + else + l = NULL; + + while (l) { + if (mail_note_get_folder_from_uri(l->data, &newfolder)) { + if (newfolder) + sources_folder = g_list_append(sources_folder, newfolder); + else + sources_uri = g_list_append(sources_uri, g_strdup(sourceuri)); + } else { + printf(" -> No such folder?\n"); + } + l = l->next; + } } - l = l->next; + UNLOCK(); } - UNLOCK(); query = g_string_new(""); filter_rule_build_code(rule, query); @@ -404,7 +605,7 @@ store_folder_deleted(CamelObject *o, void *event_data, void *data) user = g_strdup_printf("%s/vfolders.xml", evolution_dir); rule_context_save((RuleContext *)context, user); - g_free(rule); + g_free(user); } else { g_warning("Cannot find rule for deleted vfolder '%s'", info->name); } diff --git a/mail/mail-vfolder.h b/mail/mail-vfolder.h index 1245a4cd77..d27698bfdd 100644 --- a/mail/mail-vfolder.h +++ b/mail/mail-vfolder.h @@ -13,7 +13,6 @@ void vfolder_load_storage(GNOME_Evolution_Shell shell); -CamelFolder *vfolder_uri_to_folder (const char *uri, CamelException *ex); void vfolder_edit (void); FilterPart *vfolder_create_part (const char *name); FilterRule *vfolder_clone_rule (FilterRule *in); @@ -21,8 +20,11 @@ void vfolder_gui_add_rule (VfolderRule *rule); void vfolder_gui_add_from_message (CamelMimeMessage *msg, int flags, const char *source); void vfolder_gui_add_from_mlist (CamelMimeMessage *msg, const char *mlist, const char *source); -/* for registering all open folders as potential vfolder sources */ -void vfolder_register_source (CamelFolder *folder); +/* add a uri that is now available to vfolders */ +void mail_vfolder_add_uri(CamelStore *store, const char *uri); + +/* remove a uri that should be removed from vfolders */ +void mail_vfolder_remove_uri(CamelStore *store, const char *uri); EvolutionStorage *mail_vfolder_get_vfolder_storage (void); |