aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author5 <NotZed@Ximian.com>2001-09-15 16:13:41 +0800
committerMichael Zucci <zucchi@src.gnome.org>2001-09-15 16:13:41 +0800
commitc2a0bf66ba4970b4a5afb29cfbadeaabbea88d4f (patch)
tree0ea489e0281c231fa922ffee00dca120b6f4a9af
parent07a40707a39c663f06893a5cba36d49ed63ba5b6 (diff)
downloadgsoc2013-evolution-c2a0bf66ba4970b4a5afb29cfbadeaabbea88d4f.tar.gz
gsoc2013-evolution-c2a0bf66ba4970b4a5afb29cfbadeaabbea88d4f.tar.zst
gsoc2013-evolution-c2a0bf66ba4970b4a5afb29cfbadeaabbea88d4f.zip
Major rewrite of most of the guts, handle changes based on signals and
2001-09-15 <NotZed@Ximian.com> * mail-vfolder.c: Major rewrite of most of the guts, handle changes based on signals and events, etc. Use the main storage handling code that imap uses, etc. * mail-tools.c (mail_tool_uri_to_folder): Dont special case vfolder: anymore. * component-factory.c (owner_set_cb): use vfolder_load_storage(), new function to setup vfolder storage, after interaction has been enabled only. This might need some tweaking ... (storage_remove_folder): Removed all the folder lookup stuff. Just delete the folder based on the path passed in. There should be no reason this wouldn't work, right? 2001-09-14 <NotZed@Ximian.com> * mail-ops.c (get_folderinfo_get): Only add vtrash folder info, if store supports vtrash. * component-factory.c (mail_load_storage_by_uri): Let 'vfolder' stores show up too. 2001-09-13 <NotZed@Ximian.com> * mail-vfolder.c (vfolder_uri_to_folder): Open a vfolder then set its expression, since name?query open method is removed. svn path=/trunk/; revision=12856
-rw-r--r--mail/ChangeLog31
-rw-r--r--mail/component-factory.c29
-rw-r--r--mail/mail-ops.c2
-rw-r--r--mail/mail-tools.c46
-rw-r--r--mail/mail-vfolder.c583
-rw-r--r--mail/mail-vfolder.h4
6 files changed, 371 insertions, 324 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index ddaa383a83..08b95312ad 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,32 @@
+2001-09-15 <NotZed@Ximian.com>
+
+ * mail-vfolder.c: Major rewrite of most of the guts, handle
+ changes based on signals and events, etc. Use the main storage
+ handling code that imap uses, etc.
+
+ * mail-tools.c (mail_tool_uri_to_folder): Dont special case
+ vfolder: anymore.
+
+ * component-factory.c (owner_set_cb): use vfolder_load_storage(),
+ new function to setup vfolder storage, after interaction has been
+ enabled only. This might need some tweaking ...
+ (storage_remove_folder): Removed all the folder lookup stuff.
+ Just delete the folder based on the path passed in. There should
+ be no reason this wouldn't work, right?
+
+2001-09-14 <NotZed@Ximian.com>
+
+ * mail-ops.c (get_folderinfo_get): Only add vtrash folder info, if
+ store supports vtrash.
+
+ * component-factory.c (mail_load_storage_by_uri): Let 'vfolder'
+ stores show up too.
+
+2001-09-13 <NotZed@Ximian.com>
+
+ * mail-vfolder.c (vfolder_uri_to_folder): Open a vfolder then set
+ its expression, since name?query open method is removed.
+
2001-09-14 Jeffrey Stedfast <fejj@ximian.com>
* subscribe-dialog.c (fe_root_value_at): Return the cached value
@@ -56,6 +85,8 @@
* mail-vfolder.c (vfolder_remove_cb): Fixed the remove callback
prototype, and return the result properly using the listener.
+ (vfolder_uri_to_folder): Always use the same store uri, so we dont
+ create a new store for each folder.
2001-09-12 Jeffrey Stedfast <fejj@ximian.com>
diff --git a/mail/component-factory.c b/mail/component-factory.c
index 32194cc177..6a238ea2aa 100644
--- a/mail/component-factory.c
+++ b/mail/component-factory.c
@@ -647,7 +647,7 @@ owner_set_cb (EvolutionShellComponent *shell_component,
storages_hash = g_hash_table_new (NULL, NULL);
- vfolder_create_storage (shell_component);
+ /*vfolder_create_storage (shell_component);*/
corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client));
@@ -668,6 +668,8 @@ owner_set_cb (EvolutionShellComponent *shell_component,
}
mail_session_enable_interaction (TRUE);
+
+ vfolder_load_storage(corba_shell);
mail_autoreceive_setup ();
}
@@ -900,9 +902,13 @@ storage_remove_folder (EvolutionStorage *storage,
gpointer user_data)
{
CamelStore *store = user_data;
+#if 0
CamelURL *url = NULL;
CamelFolderInfo *fi;
+#endif
CamelException ex;
+
+ /* FIXME: Jeff does this look right? */
g_warning ("storage_remove_folder: path=\"%s\"; uri=\"%s\"", path, physical_uri);
@@ -911,12 +917,14 @@ storage_remove_folder (EvolutionStorage *storage,
notify_listener (listener, GNOME_Evolution_Storage_INVALID_URI);
return;
}
-
+
+#if 0
url = camel_url_new (physical_uri, NULL);
if (!url) {
notify_listener (listener, GNOME_Evolution_Storage_INVALID_URI);
return;
}
+#endif
} else {
if (!*path) {
notify_listener (listener, GNOME_Evolution_Storage_INVALID_URI);
@@ -925,32 +933,37 @@ storage_remove_folder (EvolutionStorage *storage,
}
camel_exception_init (&ex);
+#if 0
fi = camel_store_get_folder_info (store, url ? url->path + 1 : path + 1,
CAMEL_STORE_FOLDER_INFO_FAST, &ex);
if (url)
camel_url_free (url);
if (camel_exception_is_set (&ex))
goto exception;
-
+
camel_store_delete_folder (store, fi->full_name, &ex);
+#endif
+ camel_store_delete_folder (store, path+1, &ex);
if (camel_exception_is_set (&ex))
goto exception;
if (camel_store_supports_subscriptions (store))
- camel_store_unsubscribe_folder (store, fi->full_name, NULL);
+ /*camel_store_unsubscribe_folder (store, fi->full_name, NULL);*/
+ camel_store_unsubscribe_folder (store, path+1, NULL);
evolution_storage_removed_folder (storage, path);
- camel_store_free_folder_info (store, fi);
+ /*camel_store_free_folder_info (store, fi);*/
notify_listener (listener, GNOME_Evolution_Storage_OK);
return;
exception:
/* FIXME: do better than this... */
-
+#if 0
if (fi)
camel_store_free_folder_info (store, fi);
+#endif
notify_listener (listener, GNOME_Evolution_Storage_INVALID_URI);
}
@@ -1016,11 +1029,13 @@ mail_load_storage_by_uri (GNOME_Evolution_Shell shell, const char *uri, const ch
* That issue can't be resolved on the provider level
* -- it's a per-URL problem.
* MPZ Added a hack to let spool protocol through temporarily ...
+ * And vfolder, and maildir ...
*/
if ((!(prov->flags & CAMEL_PROVIDER_IS_STORAGE) ||
!(prov->flags & CAMEL_PROVIDER_IS_REMOTE))
&& !((strcmp (prov->protocol, "spool") == 0)
- || strcmp (prov->protocol, "maildir") == 0))
+ || (strcmp (prov->protocol, "maildir") == 0)
+ || (strcmp (prov->protocol, "vfolder") == 0)))
return;
store = camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex);
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 15fe17c4e9..b8f8e29df4 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -1117,7 +1117,7 @@ get_folderinfo_get (struct _mail_msg *mm)
flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
m->info = camel_store_get_folder_info (m->store, NULL, flags, &mm->ex);
- if (m->info && m->info->url)
+ if (m->info && m->info->url && (m->store->flags & CAMEL_STORE_VTRASH))
add_vtrash_info (m->store, m->info);
}
diff --git a/mail/mail-tools.c b/mail/mail-tools.c
index 0848044b92..1cbf3163a2 100644
--- a/mail/mail-tools.c
+++ b/mail/mail-tools.c
@@ -333,32 +333,30 @@ mail_tool_uri_to_folder (const char *uri, CamelException *ex)
if (!url) {
return NULL;
}
-
- if (!strcmp (url->protocol, "vfolder")) {
- folder = vfolder_uri_to_folder (uri, ex);
- } else {
- store = camel_session_get_store (session, uri + offset, ex);
- if (store) {
- const char *name;
-
- /* if we have a fragment, then the path is actually used by the store,
- so the fragment is the path to the folder instead */
- if (url->fragment) {
- name = url->fragment;
- } else {
- if (url->path && *url->path)
- name = url->path + 1;
- else
- name = "";
- }
-
- if (offset)
- folder = camel_store_get_trash (store, ex);
+
+ store = camel_session_get_store (session, uri + offset, ex);
+ if (store) {
+ const char *name;
+
+ /* if we have a fragment, then the path is actually used by the store,
+ so the fragment is the path to the folder instead */
+ if (url->fragment) {
+ name = url->fragment;
+ } else {
+ if (url->path && *url->path)
+ name = url->path + 1;
else
- folder = camel_store_get_folder (store, name,
- CAMEL_STORE_FOLDER_CREATE, ex);
- camel_object_unref (CAMEL_OBJECT (store));
+ name = "";
}
+
+ printf("opening folder '%s' on store (%p) '%s'\n", name, store, uri);
+
+ if (offset)
+ folder = camel_store_get_trash (store, ex);
+ else
+ folder = camel_store_get_folder (store, name,
+ CAMEL_STORE_FOLDER_CREATE, ex);
+ camel_object_unref (CAMEL_OBJECT (store));
}
if (camel_exception_is_set (ex)) {
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index 84523a1b69..0f4c271255 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -24,6 +24,8 @@
#include "mail-autofilter.h"
#include "mail-folder-cache.h"
#include "mail.h"
+#include "mail-ops.h"
+#include "mail-mt.h"
#include "camel/camel.h"
#include "camel/camel-remote-store.h"
@@ -44,10 +46,12 @@ struct _vfolder_info {
};
/* list of vfolders available */
-static GList *available_vfolders = NULL;
static VfolderContext *context;
+static CamelStore *vfolder_store;
static GList *source_folders; /* list of source folders */
+static GHashTable *vfolder_hash;
+
/* Ditto below */
EvolutionStorage *vfolder_storage;
@@ -57,59 +61,46 @@ extern EvolutionShellClient *global_shell_client;
extern char *evolution_dir;
extern CamelSession *session;
-static struct _vfolder_info *
-vfolder_find (const char *name)
-{
- GList *l = available_vfolders;
- struct _vfolder_info *info;
-
- while (l) {
- info = l->data;
- if (!strcmp (info->name, name))
- return info;
- l = g_list_next (l);
- }
- return NULL;
-}
+/* ********************************************************************** */
-static void
-register_new_source (struct _vfolder_info *info, CamelFolder *folder)
+/* return true if this folder should be added to this rule */
+static int
+check_source(FilterRule *rule, CamelFolder *folder)
{
- FilterRule *rule = info->rule;
-
- if (rule && info->folder && rule->source) {
+ if (rule->source) {
int remote = (((CamelService *)folder->parent_store)->provider->flags & CAMEL_PROVIDER_IS_REMOTE) != 0;
if (!strcmp(rule->source, "local")) {
if (!remote) {
- printf("adding local folder to vfolder %s\n", rule->name);
- camel_vee_folder_add_folder(info->folder, folder);
+ return TRUE;
}
} else if (!strcmp(rule->source, "remote_active")) {
if (remote) {
- printf("adding remote folder to vfolder %s\n", rule->name);
- camel_vee_folder_add_folder(info->folder, folder);
+ return TRUE;
}
} else if (!strcmp(rule->source, "local_remote_active")) {
- printf("adding local or remote folder to vfolder %s\n", rule->name);
- camel_vee_folder_add_folder(info->folder, folder);
+ return TRUE;
}
}
+
+ return FALSE;
}
static void
-source_finalise (CamelFolder *sub, gpointer type, CamelFolder *vf)
+register_source(char *key, CamelVeeFolder *vfolder, CamelFolder *folder)
{
- GList *l = available_vfolders;
+ FilterRule *rule;
- while (l) {
- struct _vfolder_info *info = l->data;
-
- if (info->folder)
- camel_vee_folder_remove_folder(info->folder, sub);
-
- l = l->next;
- }
+ 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)
+{
+ source_folders = g_list_remove(source_folders, folder);
}
/* for registering potential vfolder sources */
@@ -124,309 +115,326 @@ vfolder_register_source (CamelFolder *folder)
if (g_list_find(source_folders, folder))
return;
- /* FIXME: Hook to destroy event */
+ /* 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);
- l = available_vfolders;
+ g_hash_table_foreach(vfolder_hash, (GHFunc)register_source, folder);
+}
+
+/* ********************************************************************** */
+
+struct _setup_msg {
+ struct _mail_msg msg;
+
+ CamelFolder *folder;
+ char *query;
+ GList *sources_uri;
+ GList *sources_folder;
+};
+
+static void
+vfolder_setup_do(struct _mail_msg *mm)
+{
+ struct _setup_msg *m = (struct _setup_msg *)mm;
+ GList *l, *list = NULL;
+ CamelFolder *folder;
+
+ camel_vee_folder_set_expression((CamelVeeFolder *)m->folder, m->query);
+
+ l = m->sources_uri;
+ while (l) {
+ folder = mail_tool_uri_to_folder(l->data, &mm->ex);
+ if (folder) {
+ list = g_list_append(list, folder);
+ } else {
+ g_warning("Could not open vfolder source: %s", (char *)l->data);
+ camel_exception_clear(&mm->ex);
+ }
+ l = l->next;
+ }
+
+ l = m->sources_folder;
while (l) {
- register_new_source(l->data, folder);
+ camel_object_ref((CamelObject *)l->data);
+ list = g_list_append(list, l->data);
l = l->next;
}
+
+ camel_vee_folder_set_folders((CamelVeeFolder *)m->folder, list);
+
+ l = list;
+ while (l) {
+ camel_object_unref((CamelObject *)l->data);
+ l = l->next;
+ }
+ g_list_free(list);
}
-/* go through the list of what we have, what we want, and make
- them match, deleting/reconfiguring as required */
static void
-vfolder_refresh (void)
+vfolder_setup_done(struct _mail_msg *mm)
{
+ struct _setup_msg *m = (struct _setup_msg *)mm;
+
+ m = m;
+}
+
+static void
+vfolder_setup_free (struct _mail_msg *mm)
+{
+ struct _setup_msg *m = (struct _setup_msg *)mm;
GList *l;
- GList *head = NULL; /* processed list */
- struct _vfolder_info *info;
- FilterRule *rule;
- GString *expr = g_string_new ("");
- char *uri, *path;
-
- rule = NULL;
- while ( (rule = rule_context_next_rule((RuleContext *)context, rule, NULL)) ) {
- info = vfolder_find(rule->name);
- g_string_truncate(expr, 0);
- filter_rule_build_code(rule, expr);
- if (info) {
- gtk_object_ref((GtkObject *)rule);
- if (info->rule)
- gtk_object_unref((GtkObject *)info->rule);
- info->rule = rule;
-
- available_vfolders = g_list_remove(available_vfolders, info);
-
- /* check if the rule has changed ... otherwise, leave it */
- if (strcmp(expr->str, info->query)) {
- d(printf("Must reconfigure vfolder with new rule?\n"));
- g_free(info->query);
- info->query = g_strdup(expr->str);
-
- uri = g_strdup_printf("vfolder:%s", info->name);
- path = g_strdup_printf("/%s", info->name);
- evolution_storage_removed_folder(vfolder_storage, path);
- evolution_storage_new_folder(vfolder_storage, path, g_basename(path),
- "mail", uri, info->name, 0);
- g_free(uri);
- g_free(path);
- }
- } else {
- info = g_malloc(sizeof(*info));
- info->name = g_strdup(rule->name);
- info->query = g_strdup(expr->str);
- gtk_object_ref((GtkObject *)rule);
- info->rule = rule;
- info->folder = NULL;
- d(printf("Adding new vfolder: %s %s\n", rule->name, expr->str));
-
- uri = g_strdup_printf("vfolder:%s", info->name);
- path = g_strdup_printf("/%s", info->name);
- evolution_storage_new_folder(vfolder_storage, path, g_basename(path),
- "mail", uri, info->name, 0);
- g_free(uri);
- g_free(path);
- }
- head = g_list_append(head, info);
+
+ camel_object_unref((CamelObject *)m->folder);
+ g_free(m->query);
+
+ l = m->sources_uri;
+ while (l) {
+ g_free(l->data);
+ l = l->next;
}
- /* everything in available_vfolders are to be removed ... */
- l = available_vfolders;
+ g_list_free(m->sources_uri);
+
+ l = m->sources_folder;
while (l) {
- info = l->data;
- d(printf("removing vfolders %s %s\n", info->name, info->query));
- path = g_strdup_printf("/%s", info->name);
- evolution_storage_removed_folder(vfolder_storage, path);
- g_free(path);
- g_free(info->name);
- g_free(info->query);
- gtk_object_unref((GtkObject *)info->rule);
- g_free(info);
- l = g_list_next(l);
+ camel_object_unref(l->data);
+ l = l->next;
}
+ g_list_free(m->sources_folder);
+}
+
+static struct _mail_msg_op vfolder_setup_op = {
+ NULL,
+ vfolder_setup_do,
+ vfolder_setup_done,
+ vfolder_setup_free,
+};
+
+static int
+vfolder_setup(CamelFolder *folder, const char *query, GList *sources_uri, GList *sources_folder)
+{
+ struct _setup_msg *m;
+ int id;
- /* setup the virtual unmatched folder */
- info = vfolder_find("UNMATCHED");
- if (info == NULL) {
- char *uri, *path;
-
- info = g_malloc(sizeof(*info));
- info->name = g_strdup("UNMATCHED");
- info->query = g_strdup("UNMATCHED");
- info->rule = NULL;
- info->folder = NULL;
- d(printf("Adding new vfolder: %s %s\n", info->name, info->query));
-
- uri = g_strdup_printf("vfolder:%s", info->name);
- path = g_strdup_printf("/%s", info->name);
- evolution_storage_new_folder(vfolder_storage, path, g_basename(path),
- "mail", uri, info->name, 0);
- g_free(uri);
- g_free(path);
- }
- head = g_list_append(head, info);
+ m = mail_msg_new(&vfolder_setup_op, NULL, sizeof (*m));
+ m->folder = folder;
+ camel_object_ref((CamelObject *)folder);
+ m->query = g_strdup(query);
+ m->sources_uri = sources_uri;
+ m->sources_folder = sources_folder;
- g_list_free(available_vfolders);
- available_vfolders = head;
- g_string_free(expr, TRUE);
+ id = m->msg.seq;
+ e_thread_put(mail_thread_queued, (EMsg *)m);
+
+ return id;
}
+/* ********************************************************************** */
+
+static void context_rule_added(RuleContext *ctx, FilterRule *rule);
+
static void
-unlist_vfolder (CamelObject *folder, gpointer event_data, gpointer user_data)
+rule_changed(FilterRule *rule, CamelFolder *folder)
{
+ const char *sourceuri;
GList *l;
+ GList *sources_uri = NULL, *sources_folder = NULL;
+ GString *query;
- l = available_vfolders;
- while (l) {
- struct _vfolder_info *info = l->data;
+ /* if the folder has changed name, then add it, then remove the old manually */
+ if (strcmp(folder->full_name, rule->name) != 0) {
+ char *uri, *path, *key;
+ CamelFolder *old;
+
+ gtk_signal_disconnect_by_func((GtkObject *)rule, rule_changed, folder);
- if ((CamelObject *)info->folder == folder) {
- info->folder = NULL;
- return;
+ context_rule_added((RuleContext *)context, rule);
+
+ uri = g_strdup_printf("vfolder:%s/vfolder#%s", evolution_dir, folder->full_name);
+ mail_folder_cache_remove_folder(uri);
+ g_free(uri);
+
+ path = g_strdup_printf("/%s", folder->full_name);
+ evolution_storage_removed_folder(mail_lookup_storage(vfolder_store), path);
+ g_free(path);
+
+ 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);
+ camel_object_unref((CamelObject *)folder);
+ } else {
+ g_warning("couldn't find a vfolder rule in our table? %s", folder->full_name);
}
+ return;
+ }
+
+ printf("Filter rule changed? for folder '%s'!!\n", folder->name);
+
+ /* work out the work to do, then do it in another thread */
+ sourceuri = NULL;
+ while ( (sourceuri = vfolder_rule_next_source((VfolderRule *)rule, sourceuri)) ) {
+ sources_uri = g_list_append(sources_uri, g_strdup(sourceuri));
+ }
+
+ 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);
+ }
l = l->next;
}
- g_message ("Whoa, unlisting vfolder %p but can't find it", folder);
+ query = g_string_new("");
+ filter_rule_build_code(rule, query);
+
+ vfolder_setup(folder, query->str, sources_uri, sources_folder);
+
+ g_string_free(query, TRUE);
}
-static void
-vfolder_remove_cb (EvolutionStorage *storage,
- const Bonobo_Listener listener,
- const char *path,
- const char *physical_uri,
- gpointer user_data)
+static void context_rule_added(RuleContext *ctx, FilterRule *rule)
{
- CORBA_any any;
- CORBA_Environment ev;
- GNOME_Evolution_Storage_Result corba_result = GNOME_Evolution_Storage_OK;
+ CamelFolder *folder;
+ char *uri, *path;
+
+ printf("rule added: %s\n", rule->name);
- if (strncmp(physical_uri, "vfolder:", 8) != 0)
- corba_result = GNOME_Evolution_Storage_UNSUPPORTED_TYPE;
- else if (vfolder_find(physical_uri + 8) == NULL)
- corba_result = GNOME_Evolution_Storage_INVALID_URI;
- else
- vfolder_remove (physical_uri);
+ /* this always runs quickly */
+ folder = camel_store_get_folder(vfolder_store, rule->name, 0, NULL);
+ if (folder) {
+ gtk_signal_connect((GtkObject *)rule, "changed", rule_changed, folder);
- CORBA_exception_init (&ev);
+ g_hash_table_insert(vfolder_hash, g_strdup(rule->name), folder);
- any._type = TC_GNOME_Evolution_Storage_Result;
- any._value = &corba_result;
+ /* Ok, so the mail_folder_cache api is a complete fuckup,
+ I think this mess probably does what it is supposed to do */
+ uri = g_strdup_printf("vfolder:%s/vfolder#%s", evolution_dir, rule->name);
+ printf("Noting folder '%s', storage = %p\n", uri, mail_lookup_storage(vfolder_store));
+ path = g_strdup_printf("/%s", rule->name);
+ evolution_storage_new_folder(mail_lookup_storage(vfolder_store),
+ path, rule->name,
+ "mail", uri,
+ rule->name,
+ FALSE);
- Bonobo_Listener_event (listener, "result", &any, &ev);
+ mail_folder_cache_note_folder(uri, folder);
+ mail_folder_cache_set_update_estorage(uri, mail_lookup_storage(vfolder_store));
+ g_free(uri);
+ g_free(path);
- CORBA_exception_free (&ev);
+ rule_changed(rule, folder);
+ }
}
-void
-vfolder_create_storage (EvolutionShellComponent *shell_component)
+static void context_rule_removed(RuleContext *ctx, FilterRule *rule)
{
- GNOME_Evolution_Shell corba_shell;
- EvolutionStorage *storage;
- char *user, *system;
-
- if (global_shell_client == NULL) {
- g_warning ("We have no shell!?");
- return;
- }
-
- corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (global_shell_client));
-
- storage = evolution_storage_new (U_("VFolders"), NULL, NULL);
- if (evolution_storage_register_on_shell (storage, corba_shell) != EVOLUTION_STORAGE_OK) {
- g_warning ("Cannot register storage");
- return;
- }
-
- vfolder_storage = storage;
- gtk_signal_connect (GTK_OBJECT (storage), "remove_folder",
- GTK_SIGNAL_FUNC (vfolder_remove_cb),
- NULL);
-
- user = g_strdup_printf ("%s/vfolders.xml", evolution_dir);
- system = EVOLUTION_DATADIR "/evolution/vfoldertypes.xml";
-
- context = vfolder_context_new ();
- printf("loading rules %s %s\n", system, user);
- if (rule_context_load ((RuleContext *)context, system, user) != 0) {
- g_warning("cannot load vfolders: %s\n", ((RuleContext *)context)->error);
+ char *uri, *key, *path;
+ CamelFolder *folder;
+
+ printf("rule removed; %s\n", rule->name);
+
+ /* have to remove this first before unrefing the folder, otherwise it gets itself lost */
+ uri = g_strdup_printf("vfolder:%s/vfolder#%s", evolution_dir, rule->name);
+ mail_folder_cache_remove_folder(uri);
+ g_free(uri);
+
+ path = g_strdup_printf("/%s", rule->name);
+ evolution_storage_removed_folder(mail_lookup_storage(vfolder_store), path);
+ g_free(path);
+
+ if (g_hash_table_lookup_extended(vfolder_hash, rule->name, (void **)&key, (void **)&folder)) {
+ g_hash_table_remove(vfolder_hash, key);
+ g_free(key);
+ camel_object_unref((CamelObject *)folder);
}
- g_free (user);
- vfolder_refresh ();
+
+ camel_store_delete_folder(vfolder_store, rule->name, NULL);
}
-void
-vfolder_remove (const char *uri)
+static void
+store_folder_created(CamelObject *o, void *event_data, void *data)
{
- struct _vfolder_info *info;
- VfolderRule *rule;
+ CamelStore *store = (CamelStore *)o;
+ CamelFolderInfo *info = event_data;
+
+ store = store;
+ info = info;
+}
+
+static void
+store_folder_deleted(CamelObject *o, void *event_data, void *data)
+{
+ CamelStore *store = (CamelStore *)o;
+ CamelFolderInfo *info = event_data;
+ FilterRule *rule;
char *user;
-
- g_warning ("vfolder_remove (\"%s\");", uri);
-
- if (strncmp (uri, "vfolder:", 8))
- return;
-
- info = vfolder_find (uri + 8);
- if (!info)
- return;
-
- user = g_strdup_printf ("%s/vfolders.xml", evolution_dir);
- rule = (VfolderRule *)rule_context_find_rule ((RuleContext *) context, info->name, NULL);
- rule_context_remove_rule ((RuleContext *) context, (FilterRule *) rule);
- rule_context_save ((RuleContext *) context, user);
- g_free (user);
- vfolder_refresh ();
+
+ printf("Folder deleted: %s\n", info->name);
+ store = store;
+
+ /* delete it from our list */
+ rule = rule_context_find_rule((RuleContext *)context, info->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);
+ rule_context_remove_rule((RuleContext *)context, rule);
+ gtk_object_unref((GtkObject *)rule);
+ gtk_signal_connect((GtkObject *)context, "rule_removed", context_rule_removed, context);
+
+ user = g_strdup_printf("%s/vfolders.xml", evolution_dir);
+ rule_context_save((RuleContext *)context, user);
+ g_free(rule);
+ } else {
+ g_warning("Cannot find rule for deleted vfolder '%s'", info->name);
+ }
}
-/* maps the shell's uri to the real vfolder uri and open the folder */
-CamelFolder *
-vfolder_uri_to_folder(const char *uri, CamelException *ex)
+void
+vfolder_load_storage(GNOME_Evolution_Shell shell)
{
- struct _vfolder_info *info;
- char *storeuri, *foldername;
- VfolderRule *rule;
- CamelFolder *folder = NULL, *sourcefolder;
- const char *sourceuri;
- int sources;
- GList *l;
-
- if (strncmp (uri, "vfolder:", 8))
- return NULL;
-
- info = vfolder_find(uri+8);
- if (info == NULL) {
- g_warning("Shell trying to open unknown vFolder: %s", uri);
- return NULL;
+ char *user, *storeuri;
+ FilterRule *rule;
+
+ vfolder_hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+ /* first, create the vfolder store, and set it up */
+ storeuri = g_strdup_printf("vfolder:%s/vfolder", evolution_dir);
+ vfolder_store = camel_session_get_store(session, storeuri, NULL);
+ if (vfolder_store == NULL) {
+ g_warning("Cannot open vfolder store - no vfolders available");
+ return;
}
-
- if (info->folder) {
- camel_object_ref((CamelObject *)info->folder);
- return (CamelFolder *)info->folder;
+
+ camel_object_hook_event((CamelObject *)vfolder_store, "folder_created",
+ (CamelObjectEventHookFunc)store_folder_created, NULL);
+ camel_object_hook_event((CamelObject *)vfolder_store, "folder_deleted",
+ (CamelObjectEventHookFunc)store_folder_deleted, NULL);
+
+ printf("got store '%s' = %p\n", storeuri, vfolder_store);
+ mail_load_storage_by_uri(shell, storeuri, U_("VFolders"));
+
+ /* load our rules */
+ user = g_strdup_printf ("%s/vfolders.xml", evolution_dir);
+ context = vfolder_context_new ();
+ if (rule_context_load ((RuleContext *)context, EVOLUTION_DATADIR "/evolution/vfoldertypes.xml", user) != 0) {
+ g_warning("cannot load vfolders: %s\n", ((RuleContext *)context)->error);
}
+ g_free (user);
- d(printf("Opening vfolder: %s\n", uri));
-
- rule = (VfolderRule *)rule_context_find_rule((RuleContext *)context, info->name, NULL);
-
- storeuri = g_strdup_printf("vfolder:%s/vfolder/%s", evolution_dir, info->name);
- foldername = g_strdup_printf("%s?%s", info->name, info->query);
-
- /* we dont have indexing on vfolders */
- folder = mail_tool_get_folder_from_urlname (storeuri, foldername, CAMEL_STORE_FOLDER_CREATE, ex);
- info->folder = (CamelVeeFolder *)folder;
- camel_object_hook_event ((CamelObject *) info->folder, "finalize", unlist_vfolder, NULL);
-
- mail_folder_cache_set_update_estorage (uri, vfolder_storage);
- mail_folder_cache_note_folder (uri, CAMEL_FOLDER (info->folder));
-
- bonobo_object_ref (BONOBO_OBJECT (vfolder_storage));
- mail_hash_storage ((CamelService *)folder->parent_store, vfolder_storage);
-
- if (strcmp (uri + 8, "UNMATCHED") != 0) {
- sourceuri = NULL;
- sources = 0;
- while ( (sourceuri = vfolder_rule_next_source(rule, sourceuri)) ) {
- d(printf("adding vfolder source: %s\n", sourceuri));
- sourcefolder = mail_tool_uri_to_folder (sourceuri, ex);
- printf("source folder = %p\n", sourcefolder);
- if (sourcefolder) {
- sources++;
- camel_vee_folder_add_folder((CamelVeeFolder *)folder, sourcefolder);
- } else {
- /* we'll just silently ignore now-missing sources */
- camel_exception_clear(ex);
- }
- }
+ gtk_signal_connect((GtkObject *)context, "rule_added", context_rule_added, context);
+ gtk_signal_connect((GtkObject *)context, "rule_removed", context_rule_removed, context);
- l = source_folders;
- while (l) {
- register_new_source(info, l->data);
- l = l->next;
- }
-#if 0
- /* if we didn't have any sources, just use Inbox as the default */
- if (sources == 0) {
- char *defaulturi;
-
- defaulturi = g_strdup_printf("file://%s/local/Inbox", evolution_dir);
- d(printf("No sources configured/found, using default: %s\n", defaulturi));
- sourcefolder = mail_tool_uri_to_folder (defaulturi, ex);
- g_free(defaulturi);
- if (sourcefolder) {
- camel_vee_folder_add_folder(folder, sourcefolder);
- }
- }
-#endif
+ /* and setup the rules we have */
+ rule = NULL;
+ while ( (rule = rule_context_next_rule((RuleContext *)context, rule, NULL)) ) {
+ context_rule_added((RuleContext *)context, rule);
}
- g_free(foldername);
g_free(storeuri);
-
- return folder;
}
static GtkWidget *vfolder_editor = NULL;
@@ -446,7 +454,6 @@ vfolder_editor_clicked (GtkWidget *dialog, int button, void *data)
user = g_strdup_printf ("%s/vfolders.xml", evolution_dir);
rule_context_save ((RuleContext *)context, user);
g_free (user);
- vfolder_refresh ();
}
if (button != -1) {
gnome_dialog_close (GNOME_DIALOG (dialog));
@@ -479,7 +486,6 @@ new_rule_clicked(GtkWidget *w, int button, void *data)
user = g_strdup_printf("%s/vfolders.xml", evolution_dir);
rule_context_save((RuleContext *)context, user);
g_free(user);
- vfolder_refresh();
}
if (button != -1) {
gnome_dialog_close((GnomeDialog *)w);
@@ -555,6 +561,5 @@ vfolder_gui_add_from_mlist(CamelMimeMessage *msg, const char *mlist, const char
EvolutionStorage *
mail_vfolder_get_vfolder_storage (void)
{
- bonobo_object_ref (BONOBO_OBJECT (vfolder_storage));
- return vfolder_storage;
+ return mail_lookup_storage(vfolder_store);
}
diff --git a/mail/mail-vfolder.h b/mail/mail-vfolder.h
index 052d2b976a..1245a4cd77 100644
--- a/mail/mail-vfolder.h
+++ b/mail/mail-vfolder.h
@@ -11,7 +11,7 @@
#include "filter/vfolder-rule.h"
#include "filter/filter-part.h"
-void vfolder_create_storage (EvolutionShellComponent *shell_component);
+void vfolder_load_storage(GNOME_Evolution_Shell shell);
CamelFolder *vfolder_uri_to_folder (const char *uri, CamelException *ex);
void vfolder_edit (void);
@@ -24,8 +24,6 @@ void vfolder_gui_add_from_mlist (CamelMimeMessage *msg, const char *mlist, const
/* for registering all open folders as potential vfolder sources */
void vfolder_register_source (CamelFolder *folder);
-void vfolder_remove (const char *uri);
-
EvolutionStorage *mail_vfolder_get_vfolder_storage (void);
#endif