aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
author8 <NotZed@Ximian.com>2001-09-29 07:54:30 +0800
committerMichael Zucci <zucchi@src.gnome.org>2001-09-29 07:54:30 +0800
commit4b14db5520cf99cb30d39e14c2bb38071d4cad2d (patch)
tree54fa8819aa23d242cccd69a3ed365e69a690bee6 /mail
parentf1eb4aa8cf71a6e690eb76e00a3d5111035931b6 (diff)
downloadgsoc2013-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
Diffstat (limited to 'mail')
-rw-r--r--mail/ChangeLog45
-rw-r--r--mail/component-factory.c6
-rw-r--r--mail/mail-folder-cache.c75
-rw-r--r--mail/mail-folder-cache.h4
-rw-r--r--mail/mail-local.c10
-rw-r--r--mail/mail-tools.c4
-rw-r--r--mail/mail-vfolder.c399
-rw-r--r--mail/mail-vfolder.h8
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);