diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2011-12-08 12:47:40 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2011-12-08 13:32:22 +0800 |
commit | e3b8f3fbb3f1cbd981e8a6382365cd699a95c149 (patch) | |
tree | 801149129483001b9c322e264919a16466e9471b | |
parent | 60978976388e00a611f2aeb87c9b27e67a2b0f05 (diff) | |
download | gsoc2013-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.c | 222 | ||||
-rw-r--r-- | mail/mail-folder-cache.h | 7 | ||||
-rw-r--r-- | mail/mail-vfolder.c | 112 | ||||
-rw-r--r-- | mail/mail-vfolder.h | 3 | ||||
-rw-r--r-- | modules/mail/e-mail-shell-view.c | 28 |
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); |