aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-12-08 12:47:40 +0800
committerMatthew Barnes <mbarnes@redhat.com>2011-12-08 13:32:22 +0800
commite3b8f3fbb3f1cbd981e8a6382365cd699a95c149 (patch)
tree801149129483001b9c322e264919a16466e9471b
parent60978976388e00a611f2aeb87c9b27e67a2b0f05 (diff)
downloadgsoc2013-evolution-e3b8f3fbb3f1cbd981e8a6382365cd699a95c149.tar.gz
gsoc2013-evolution-e3b8f3fbb3f1cbd981e8a6382365cd699a95c149.tar.zst
gsoc2013-evolution-e3b8f3fbb3f1cbd981e8a6382365cd699a95c149.zip
Move folder URI caching to MailFolderCache.
-rw-r--r--mail/mail-folder-cache.c222
-rw-r--r--mail/mail-folder-cache.h7
-rw-r--r--mail/mail-vfolder.c112
-rw-r--r--mail/mail-vfolder.h3
-rw-r--r--modules/mail/e-mail-shell-view.c28
5 files changed, 270 insertions, 102 deletions
diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c
index 0baaa0eb72..cab15c5e93 100644
--- a/mail/mail-folder-cache.c
+++ b/mail/mail-folder-cache.c
@@ -76,6 +76,9 @@ struct _MailFolderCachePrivate {
/* hack for people who LIKE to have unsent count */
gint count_sent;
gint count_trash;
+
+ GQueue local_folder_uris;
+ GQueue remote_folder_uris;
};
enum {
@@ -887,6 +890,22 @@ store_go_online_cb (CamelStore *store,
g_mutex_unlock (ud->cache->priv->stores_mutex);
}
+static GList *
+find_folder_uri (GQueue *queue,
+ CamelSession *session,
+ const gchar *folder_uri)
+{
+ GList *head, *link;
+
+ head = g_queue_peek_head_link (queue);
+
+ for (link = head; link != NULL; link = g_list_next (link))
+ if (e_mail_folder_uri_equal (session, link->data, folder_uri))
+ break;
+
+ return link;
+}
+
struct _find_info {
const gchar *folder_uri;
struct _folder_info *fi;
@@ -931,11 +950,167 @@ mail_folder_cache_finalize (GObject *object)
cache->priv->update_id = 0;
}
+ while (!g_queue_is_empty (&cache->priv->local_folder_uris))
+ g_free (g_queue_pop_head (&cache->priv->local_folder_uris));
+
+ while (!g_queue_is_empty (&cache->priv->remote_folder_uris))
+ g_free (g_queue_pop_head (&cache->priv->remote_folder_uris));
+
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (mail_folder_cache_parent_class)->finalize (object);
}
static void
+mail_folder_cache_folder_available (MailFolderCache *cache,
+ CamelStore *store,
+ const gchar *folder_name)
+{
+ CamelService *service;
+ CamelSession *session;
+ CamelProvider *provider;
+ GQueue *queue;
+ gchar *folder_uri;
+
+ /* Disregard virtual stores. */
+ if (CAMEL_IS_VEE_STORE (store))
+ return;
+
+ /* Disregard virtual Junk folders. */
+ if (store->flags & CAMEL_STORE_VJUNK)
+ if (g_strcmp0 (folder_name, CAMEL_VJUNK_NAME) == 0)
+ return;
+
+ /* Disregard virtual Trash folders. */
+ if (store->flags & CAMEL_STORE_VTRASH)
+ if (g_strcmp0 (folder_name, CAMEL_VTRASH_NAME) == 0)
+ return;
+
+ service = CAMEL_SERVICE (store);
+ session = camel_service_get_session (service);
+ provider = camel_service_get_provider (service);
+
+ /* Reuse the stores mutex just because it's handy. */
+ g_mutex_lock (cache->priv->stores_mutex);
+
+ folder_uri = e_mail_folder_uri_build (store, folder_name);
+
+ if (provider->flags & CAMEL_PROVIDER_IS_REMOTE)
+ queue = &cache->priv->remote_folder_uris;
+ else
+ queue = &cache->priv->local_folder_uris;
+
+ if (find_folder_uri (queue, session, folder_uri) == NULL)
+ g_queue_push_tail (queue, folder_uri);
+ else
+ g_free (folder_uri);
+
+ g_mutex_unlock (cache->priv->stores_mutex);
+}
+
+static void
+mail_folder_cache_folder_unavailable (MailFolderCache *cache,
+ CamelStore *store,
+ const gchar *folder_name)
+{
+ CamelService *service;
+ CamelSession *session;
+ CamelProvider *provider;
+ GQueue *queue;
+ GList *link;
+ gchar *folder_uri;
+
+ /* Disregard virtual stores. */
+ if (CAMEL_IS_VEE_STORE (store))
+ return;
+
+ /* Disregard virtual Junk folders. */
+ if (store->flags & CAMEL_STORE_VJUNK)
+ if (g_strcmp0 (folder_name, CAMEL_VJUNK_NAME) == 0)
+ return;
+
+ /* Disregard virtual Trash folders. */
+ if (store->flags & CAMEL_STORE_VTRASH)
+ if (g_strcmp0 (folder_name, CAMEL_VTRASH_NAME) == 0)
+ return;
+
+ service = CAMEL_SERVICE (store);
+ session = camel_service_get_session (service);
+ provider = camel_service_get_provider (service);
+
+ /* Reuse the stores mutex just because it's handy. */
+ g_mutex_lock (cache->priv->stores_mutex);
+
+ folder_uri = e_mail_folder_uri_build (store, folder_name);
+
+ if (provider->flags & CAMEL_PROVIDER_IS_REMOTE)
+ queue = &cache->priv->remote_folder_uris;
+ else
+ queue = &cache->priv->local_folder_uris;
+
+ link = find_folder_uri (queue, session, folder_uri);
+ if (link != NULL) {
+ g_free (link->data);
+ g_queue_delete_link (queue, link);
+ }
+
+ g_free (folder_uri);
+
+ g_mutex_unlock (cache->priv->stores_mutex);
+}
+
+static void
+mail_folder_cache_folder_deleted (MailFolderCache *cache,
+ CamelStore *store,
+ const gchar *folder_name)
+{
+ CamelService *service;
+ CamelSession *session;
+ GQueue *queue;
+ GList *link;
+ gchar *folder_uri;
+
+ /* Disregard virtual stores. */
+ if (CAMEL_IS_VEE_STORE (store))
+ return;
+
+ /* Disregard virtual Junk folders. */
+ if (store->flags & CAMEL_STORE_VJUNK)
+ if (g_strcmp0 (folder_name, CAMEL_VJUNK_NAME) == 0)
+ return;
+
+ /* Disregard virtual Trash folders. */
+ if (store->flags & CAMEL_STORE_VTRASH)
+ if (g_strcmp0 (folder_name, CAMEL_VTRASH_NAME) == 0)
+ return;
+
+ service = CAMEL_SERVICE (store);
+ session = camel_service_get_session (service);
+
+ /* Reuse the stores mutex just because it's handy. */
+ g_mutex_lock (cache->priv->stores_mutex);
+
+ folder_uri = e_mail_folder_uri_build (store, folder_name);
+
+ queue = &cache->priv->local_folder_uris;
+ link = find_folder_uri (queue, session, folder_uri);
+ if (link != NULL) {
+ g_free (link->data);
+ g_queue_delete_link (queue, link);
+ }
+
+ queue = &cache->priv->remote_folder_uris;
+ link = find_folder_uri (queue, session, folder_uri);
+ if (link != NULL) {
+ g_free (link->data);
+ g_queue_delete_link (queue, link);
+ }
+
+ g_free (folder_uri);
+
+ g_mutex_unlock (cache->priv->stores_mutex);
+}
+
+static void
mail_folder_cache_class_init (MailFolderCacheClass *class)
{
GObjectClass *object_class;
@@ -945,6 +1120,10 @@ mail_folder_cache_class_init (MailFolderCacheClass *class)
object_class = G_OBJECT_CLASS (class);
object_class->finalize = mail_folder_cache_finalize;
+ class->folder_available = mail_folder_cache_folder_available;
+ class->folder_unavailable = mail_folder_cache_folder_unavailable;
+ class->folder_deleted = mail_folder_cache_folder_deleted;
+
/**
* MailFolderCache::folder-available
* @store: the #CamelStore containing the folder
@@ -1089,6 +1268,9 @@ mail_folder_cache_init (MailFolderCache *cache)
timeout = buf ? strtoul (buf, NULL, 10) : 600;
cache->priv->ping_id = g_timeout_add_seconds (
timeout, (GSourceFunc) ping_cb, cache);
+
+ g_queue_init (&cache->priv->local_folder_uris);
+ g_queue_init (&cache->priv->remote_folder_uris);
}
MailFolderCache *
@@ -1397,3 +1579,43 @@ mail_folder_cache_get_folder_has_children (MailFolderCache *cache,
return fi.fi != NULL && fi.fi->has_children;
}
+
+void
+mail_folder_cache_get_local_folder_uris (MailFolderCache *self,
+ GQueue *out_queue)
+{
+ GList *head, *link;
+
+ g_return_if_fail (MAIL_IS_FOLDER_CACHE (self));
+ g_return_if_fail (out_queue != NULL);
+
+ /* Reuse the stores mutex just because it's handy. */
+ g_mutex_lock (self->priv->stores_mutex);
+
+ head = g_queue_peek_head_link (&self->priv->local_folder_uris);
+
+ for (link = head; link != NULL; link = g_list_next (link))
+ g_queue_push_tail (out_queue, g_strdup (link->data));
+
+ g_mutex_unlock (self->priv->stores_mutex);
+}
+
+void
+mail_folder_cache_get_remote_folder_uris (MailFolderCache *self,
+ GQueue *out_queue)
+{
+ GList *head, *link;
+
+ g_return_if_fail (MAIL_IS_FOLDER_CACHE (self));
+ g_return_if_fail (out_queue != NULL);
+
+ /* Reuse the stores mutex just because it's handy. */
+ g_mutex_lock (self->priv->stores_mutex);
+
+ head = g_queue_peek_head_link (&self->priv->remote_folder_uris);
+
+ for (link = head; link != NULL; link = g_list_next (link))
+ g_queue_push_tail (out_queue, g_strdup (link->data));
+
+ g_mutex_unlock (self->priv->stores_mutex);
+}
diff --git a/mail/mail-folder-cache.h b/mail/mail-folder-cache.h
index 8253461c6b..146ead5012 100644
--- a/mail/mail-folder-cache.h
+++ b/mail/mail-folder-cache.h
@@ -126,11 +126,16 @@ gboolean mail_folder_cache_get_folder_info_flags
(MailFolderCache *self,
CamelFolder *folder,
CamelFolderInfoFlags *flags);
-
gboolean mail_folder_cache_get_folder_has_children
(MailFolderCache *self,
CamelFolder *folder,
gboolean *found);
+void mail_folder_cache_get_local_folder_uris
+ (MailFolderCache *self,
+ GQueue *out_queue);
+void mail_folder_cache_get_remote_folder_uris
+ (MailFolderCache *self,
+ GQueue *out_queue);
G_END_DECLS
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index b93122ac00..b37d042077 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -61,12 +61,6 @@ static EMVFolderContext *context; /* context remains open all time */
/* lock for accessing shared resources (below) */
G_LOCK_DEFINE_STATIC (vfolder);
-/* list of source folder uri's - remote ones */
-static GQueue source_folders_remote = G_QUEUE_INIT;
-
-/* list of source folder uri's - local ones */
-static GQueue source_folders_local = G_QUEUE_INIT;
-
static GHashTable *vfolder_hash;
/* This is a slightly hacky solution to shutting down, we poll this variable in various
* loops, and just quit processing if it is set. */
@@ -329,24 +323,6 @@ vfolder_adduri (EMailBackend *backend,
/* ********************************************************************** */
-static GList *
-mv_find_folder (GQueue *queue,
- EMailSession *session,
- const gchar *uri)
-{
- CamelSession *camel_session = CAMEL_SESSION (session);
- GList *head, *link;
-
- head = g_queue_peek_head_link (queue);
-
- for (link = head; link != NULL; link = g_list_next (link)) {
- if (e_mail_folder_uri_equal (camel_session, link->data, uri))
- break;
- }
-
- return link;
-}
-
/* so special we never use it */
static gint
folder_is_spethal (CamelStore *store,
@@ -395,17 +371,14 @@ mail_vfolder_add_folder (EMailBackend *backend,
const gchar *source;
CamelVeeFolder *vf;
CamelProvider *provider;
- GList *folders = NULL, *link;
- GQueue *queue;
+ GList *folders = NULL;
gint remote;
- gint is_ignore = FALSE;
gchar *uri;
session = e_mail_backend_get_session (backend);
provider = camel_service_get_provider (CAMEL_SERVICE (store));
remote = (provider->flags & CAMEL_PROVIDER_IS_REMOTE) != 0;
- queue = remote ? &source_folders_remote : &source_folders_local;
if (folder_is_spethal (store, folder_name))
return;
@@ -416,21 +389,6 @@ mail_vfolder_add_folder (EMailBackend *backend,
G_LOCK (vfolder);
- /* maintain the source folders lists for changed rules later on */
- if (CAMEL_IS_VEE_STORE (store)) {
- is_ignore = TRUE;
- } else if (remove) {
- link = mv_find_folder (queue, session, uri);
- if (link != NULL) {
- g_free (link->data);
- g_queue_delete_link (queue, link);
- }
- } else if (!is_ignore) {
- /* we ignore drafts/sent/outbox here */
- if (mv_find_folder (queue, session, uri) == NULL)
- g_queue_push_tail (queue, g_strdup (uri));
- }
-
if (context == NULL)
goto done;
@@ -445,7 +403,7 @@ mail_vfolder_add_folder (EMailBackend *backend,
/* Don't auto-add any sent/drafts folders etc,
* they must be explictly listed as a source. */
if (rule->source
- && !is_ignore
+ && !CAMEL_IS_VEE_STORE (store)
&& ((((EMVFolderRule *) rule)->with ==
EM_VFOLDER_RULE_WITH_LOCAL && !remote)
|| (((EMVFolderRule *) rule)->with ==
@@ -510,10 +468,8 @@ mail_vfolder_delete_folder (EMailBackend *backend,
const gchar *source;
CamelVeeFolder *vf;
GString *changed;
- GQueue *queue;
guint changed_count;
gchar *uri;
- GList *link;
g_return_if_fail (E_IS_MAIL_BACKEND (backend));
g_return_if_fail (CAMEL_IS_STORE (store));
@@ -590,20 +546,6 @@ mail_vfolder_delete_folder (EMailBackend *backend,
}
done:
- queue = &source_folders_remote;
- link = mv_find_folder (queue, session, uri);
- if (link != NULL) {
- g_free (link->data);
- g_queue_delete_link (queue, link);
- }
-
- queue = &source_folders_local;
- link = mv_find_folder (queue, session, uri);
- if (link != NULL) {
- g_free (link->data);
- g_queue_delete_link (queue, link);
- }
-
G_UNLOCK (vfolder);
if (changed_count > 0) {
@@ -724,18 +666,6 @@ mail_vfolder_rename_folder (CamelStore *store,
g_free (new_uri);
}
-GList *
-mail_vfolder_get_sources_local (void)
-{
- return g_queue_peek_head_link (&source_folders_local);
-}
-
-GList *
-mail_vfolder_get_sources_remote (void)
-{
- return g_queue_peek_head_link (&source_folders_remote);
-}
-
/* ********************************************************************** */
static void context_rule_added (ERuleContext *ctx, EFilterRule *rule);
@@ -780,7 +710,8 @@ rule_changed (EFilterRule *rule,
EMailBackend *backend;
EMailSession *session;
CamelService *service;
- GList *sources_uri = NULL, *sources_folder = NULL;
+ GList *sources_uri = NULL;
+ GList *sources_folder = NULL;
GString *query;
const gchar *full_name;
@@ -827,20 +758,43 @@ rule_changed (EFilterRule *rule,
&sources_folder, &sources_uri);
G_LOCK (vfolder);
+
if (((EMVFolderRule *) rule)->with ==
EM_VFOLDER_RULE_WITH_LOCAL ||
((EMVFolderRule *) rule)->with ==
- EM_VFOLDER_RULE_WITH_LOCAL_REMOTE_ACTIVE)
+ EM_VFOLDER_RULE_WITH_LOCAL_REMOTE_ACTIVE) {
+
+ MailFolderCache *cache;
+ GQueue queue = G_QUEUE_INIT;
+
+ cache = e_mail_session_get_folder_cache (session);
+ mail_folder_cache_get_local_folder_uris (cache, &queue);
+
rule_add_sources (
- session, &source_folders_local,
- &sources_folder, &sources_uri);
+ session, &queue, &sources_folder, &sources_uri);
+
+ while (!g_queue_is_empty (&queue))
+ g_free (g_queue_pop_head (&queue));
+ }
+
if (((EMVFolderRule *) rule)->with ==
EM_VFOLDER_RULE_WITH_REMOTE_ACTIVE ||
((EMVFolderRule *) rule)->with ==
- EM_VFOLDER_RULE_WITH_LOCAL_REMOTE_ACTIVE)
+ EM_VFOLDER_RULE_WITH_LOCAL_REMOTE_ACTIVE) {
+
+ MailFolderCache *cache;
+ GQueue queue = G_QUEUE_INIT;
+
+ cache = e_mail_session_get_folder_cache (session);
+ mail_folder_cache_get_remote_folder_uris (cache, &queue);
+
rule_add_sources (
- session, &source_folders_remote,
- &sources_folder, &sources_uri);
+ session, &queue, &sources_folder, &sources_uri);
+
+ while (!g_queue_is_empty (&queue))
+ g_free (g_queue_pop_head (&queue));
+ }
+
G_UNLOCK (vfolder);
query = g_string_new("");
diff --git a/mail/mail-vfolder.h b/mail/mail-vfolder.h
index 7ef5956758..c180106562 100644
--- a/mail/mail-vfolder.h
+++ b/mail/mail-vfolder.h
@@ -46,9 +46,6 @@ void vfolder_gui_add_from_address (EMailSession *session,
gint flags,
CamelFolder *folder);
-GList * mail_vfolder_get_sources_local (void);
-GList * mail_vfolder_get_sources_remote (void);
-
/* close up, clean up */
void mail_vfolder_shutdown (void);
diff --git a/modules/mail/e-mail-shell-view.c b/modules/mail/e-mail-shell-view.c
index 74a69a9127..02a31c20de 100644
--- a/modules/mail/e-mail-shell-view.c
+++ b/modules/mail/e-mail-shell-view.c
@@ -224,6 +224,7 @@ mail_shell_view_execute_search (EShellView *shell_view)
EActionComboBox *combo_box;
EMailBackend *backend;
EMailSession *session;
+ MailFolderCache *cache;
EMFolderTree *folder_tree;
GtkWidget *message_list;
EFilterRule *rule;
@@ -240,6 +241,7 @@ mail_shell_view_execute_search (EShellView *shell_view)
GString *string;
GList *list, *iter;
GSList *search_strings = NULL;
+ GQueue queue = G_QUEUE_INIT;
const gchar *text;
gboolean valid;
gchar *query;
@@ -564,26 +566,14 @@ all_accounts:
CAMEL_STORE_VEE_FOLDER_AUTO);
priv->search_account_all = search_folder;
- /* Add local folders. */
- iter = mail_vfolder_get_sources_local ();
- while (iter != NULL) {
- const gchar *folder_uri = iter->data;
- /* FIXME Not passing a GCancellable or GError here. */
- folder = e_mail_session_uri_to_folder_sync (
- E_MAIL_SESSION (session), folder_uri, 0, NULL, NULL);
+ cache = e_mail_session_get_folder_cache (session);
+ mail_folder_cache_get_local_folder_uris (cache, &queue);
+ mail_folder_cache_get_remote_folder_uris (cache, &queue);
- if (folder != NULL)
- list = g_list_append (list, folder);
- else
- g_warning ("Could not open vfolder source: %s", folder_uri);
-
- iter = g_list_next (iter);
- }
+ /* Add all available local and remote folders. */
+ while (!g_queue_is_empty (&queue)) {
+ gchar *folder_uri = g_queue_pop_head (&queue);
- /* Add remote folders. */
- iter = mail_vfolder_get_sources_remote ();
- while (iter != NULL) {
- const gchar *folder_uri = iter->data;
/* FIXME Not passing a GCancellable or GError here. */
folder = e_mail_session_uri_to_folder_sync (
E_MAIL_SESSION (session), folder_uri, 0, NULL, NULL);
@@ -593,7 +583,7 @@ all_accounts:
else
g_warning ("Could not open vfolder source: %s", folder_uri);
- iter = g_list_next (iter);
+ g_free (folder_uri);
}
camel_vee_folder_set_expression (search_folder, query);