[evolution-data-server/evolution-data-server-3-12] Bug 732717 - Refreshing an IMAP account does not refresh folder list
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/evolution-data-server-3-12] Bug 732717 - Refreshing an IMAP account does not refresh folder list
- Date: Thu, 20 Nov 2014 16:15:39 +0000 (UTC)
commit 8770acdaa65a9c2cc3d73c3fa1e67cd07811eb15
Author: Milan Crha <mcrha redhat com>
Date: Thu Nov 20 17:15:23 2014 +0100
Bug 732717 - Refreshing an IMAP account does not refresh folder list
camel/providers/imapx/camel-imapx-mailbox.c | 44 +++++++++++++
camel/providers/imapx/camel-imapx-mailbox.h | 13 ++++
camel/providers/imapx/camel-imapx-store.c | 88 ++++++++++++++++++++++++++-
3 files changed, 143 insertions(+), 2 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-mailbox.c b/camel/providers/imapx/camel-imapx-mailbox.c
index fbdad1e..f5744e1 100644
--- a/camel/providers/imapx/camel-imapx-mailbox.c
+++ b/camel/providers/imapx/camel-imapx-mailbox.c
@@ -48,6 +48,8 @@ struct _CamelIMAPXMailboxPrivate {
guint64 highestmodseq;
guint32 permanentflags;
+ CamelIMAPXMailboxState state;
+
GMutex property_lock;
GRecMutex update_lock;
@@ -126,6 +128,7 @@ camel_imapx_mailbox_init (CamelIMAPXMailbox *mailbox)
g_rec_mutex_init (&mailbox->priv->update_lock);
mailbox->priv->message_map = g_sequence_new (NULL);
mailbox->priv->permanentflags = ~0;
+ mailbox->priv->state = CAMEL_IMAPX_MAILBOX_STATE_CREATED;
}
/**
@@ -217,6 +220,7 @@ camel_imapx_mailbox_clone (CamelIMAPXMailbox *mailbox,
clone->priv->uidnext = mailbox->priv->uidnext;
clone->priv->uidvalidity = mailbox->priv->uidvalidity;
clone->priv->highestmodseq = mailbox->priv->highestmodseq;
+ clone->priv->state = mailbox->priv->state;
clone->priv->quota_roots = g_strdupv (mailbox->priv->quota_roots);
@@ -238,6 +242,46 @@ camel_imapx_mailbox_clone (CamelIMAPXMailbox *mailbox,
}
/**
+ * camel_imapx_mailbox_get_state:
+ * @mailbox: a #CamelIMAPXMailbox
+ *
+ * Returns current state of the mailbox. This is used for folder
+ * structure updates, to identify newly created, updated, renamed
+ * or removed mailboxes.
+ *
+ * Returns: Current (update) state of the mailbox.
+ *
+ * Since: 3.12.9
+ **/
+CamelIMAPXMailboxState
+camel_imapx_mailbox_get_state (CamelIMAPXMailbox *mailbox)
+{
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), CAMEL_IMAPX_MAILBOX_STATE_UNKNOWN);
+
+ return mailbox->priv->state;
+}
+
+/**
+ * camel_imapx_mailbox_set_state:
+ * @mailbox: a #CamelIMAPXMailbox
+ * @state: a new #CamelIMAPXMailboxState to set
+ *
+ * Sets current (update) state of the mailbox. This is used for folder
+ * structure updates, to identify newly created, updated, renamed
+ * or removed mailboxes.
+ *
+ * Since: 3.12.9
+ **/
+void
+camel_imapx_mailbox_set_state (CamelIMAPXMailbox *mailbox,
+ CamelIMAPXMailboxState state)
+{
+ g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
+
+ mailbox->priv->state = state;
+}
+
+/**
* camel_imapx_mailbox_exists:
* @mailbox: a #CamelIMAPXMailbox
*
diff --git a/camel/providers/imapx/camel-imapx-mailbox.h b/camel/providers/imapx/camel-imapx-mailbox.h
index e89010c..5b9ef52 100644
--- a/camel/providers/imapx/camel-imapx-mailbox.h
+++ b/camel/providers/imapx/camel-imapx-mailbox.h
@@ -47,6 +47,13 @@ typedef struct _CamelIMAPXMailbox CamelIMAPXMailbox;
typedef struct _CamelIMAPXMailboxClass CamelIMAPXMailboxClass;
typedef struct _CamelIMAPXMailboxPrivate CamelIMAPXMailboxPrivate;
+typedef enum {
+ CAMEL_IMAPX_MAILBOX_STATE_UNKNOWN,
+ CAMEL_IMAPX_MAILBOX_STATE_CREATED,
+ CAMEL_IMAPX_MAILBOX_STATE_UPDATED,
+ CAMEL_IMAPX_MAILBOX_STATE_RENAMED
+} CamelIMAPXMailboxState;
+
/**
* CamelIMAPXMailbox:
*
@@ -73,6 +80,12 @@ CamelIMAPXMailbox *
camel_imapx_mailbox_clone
(CamelIMAPXMailbox *mailbox,
const gchar *new_mailbox_name);
+CamelIMAPXMailboxState
+ camel_imapx_mailbox_get_state
+ (CamelIMAPXMailbox *mailbox);
+void camel_imapx_mailbox_set_state
+ (CamelIMAPXMailbox *mailbox,
+ CamelIMAPXMailboxState state);
gboolean camel_imapx_mailbox_exists
(CamelIMAPXMailbox *mailbox);
gint camel_imapx_mailbox_compare
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index 302e68f..d8b5162 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -993,6 +993,7 @@ event:
camel_store_summary_save (imapx_store->summary);
fi = imapx_store_build_folder_info (imapx_store, folder_path, 0);
+ camel_subscribable_folder_unsubscribed (CAMEL_SUBSCRIBABLE (imapx_store), fi);
camel_store_folder_deleted (CAMEL_STORE (imapx_store), fi);
camel_folder_info_free (fi);
}
@@ -1352,10 +1353,73 @@ exit:
return success;
}
+static void
+imapx_store_mark_mailbox_unknown_cb (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ CamelIMAPXMailbox *mailbox = value;
+
+ g_return_if_fail (mailbox != NULL);
+
+ camel_imapx_mailbox_set_state (mailbox, CAMEL_IMAPX_MAILBOX_STATE_UNKNOWN);
+}
+
+static gboolean
+imapx_store_remove_unknown_mailboxes_cb (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ CamelIMAPXMailbox *mailbox = value;
+ CamelIMAPXStore *imapx_store = user_data;
+ CamelStoreInfo *si;
+
+ g_return_val_if_fail (mailbox != NULL, FALSE);
+ g_return_val_if_fail (CAMEL_IS_IMAPX_STORE (imapx_store), FALSE);
+
+ if (camel_imapx_mailbox_get_state (mailbox) == CAMEL_IMAPX_MAILBOX_STATE_CREATED) {
+ CamelFolderInfo *fi;
+ gchar *folder_path;
+
+ folder_path = camel_imapx_mailbox_dup_folder_path (mailbox);
+ fi = imapx_store_build_folder_info (imapx_store, folder_path,
+ imapx_store_mailbox_attributes_to_flags (mailbox));
+ camel_store_folder_created (CAMEL_STORE (imapx_store), fi);
+ camel_subscribable_folder_subscribed (CAMEL_SUBSCRIBABLE (imapx_store), fi);
+ camel_folder_info_free (fi);
+ g_free (folder_path);
+ }
+
+ if (camel_imapx_mailbox_get_state (mailbox) != CAMEL_IMAPX_MAILBOX_STATE_UNKNOWN) {
+ return FALSE;
+ }
+
+ si = (CamelStoreInfo *) camel_imapx_store_summary_mailbox (imapx_store->summary,
camel_imapx_mailbox_get_name (mailbox));
+ if (si) {
+ const gchar *si_path;
+ gchar *dup_folder_path;
+
+ si_path = camel_store_info_path (imapx_store->summary, si);
+ dup_folder_path = g_strdup (si_path);
+
+ if (dup_folder_path != NULL) {
+ imapx_delete_folder_from_cache (imapx_store, dup_folder_path);
+ g_free (dup_folder_path);
+ } else {
+ camel_store_summary_remove (imapx_store->summary, si);
+ }
+
+ camel_store_summary_info_unref (imapx_store->summary, si);
+ }
+
+ return TRUE;
+}
+
static gboolean
sync_folders (CamelIMAPXStore *imapx_store,
const gchar *root_folder_path,
CamelStoreGetFolderInfoFlags flags,
+ gboolean initial_setup,
GCancellable *cancellable,
GError **error)
{
@@ -1380,6 +1444,12 @@ sync_folders (CamelIMAPXStore *imapx_store,
* in imapx_store_process_mailbox_attributes(). */
g_atomic_int_inc (&imapx_store->priv->syncing_folders);
+ if (!initial_setup && (!root_folder_path || !*root_folder_path)) {
+ g_mutex_lock (&imapx_store->priv->mailboxes_lock);
+ g_hash_table_foreach (imapx_store->priv->mailboxes, imapx_store_mark_mailbox_unknown_cb,
imapx_store);
+ g_mutex_unlock (&imapx_store->priv->mailboxes_lock);
+ }
+
if (root_folder_path != NULL && *root_folder_path != '\0') {
success = fetch_folder_info_from_folder_path (
imapx_store, server, root_folder_path, flags,
@@ -1410,6 +1480,12 @@ sync_folders (CamelIMAPXStore *imapx_store,
if (!success)
goto exit;
+ if (!initial_setup && (!root_folder_path || !*root_folder_path)) {
+ g_mutex_lock (&imapx_store->priv->mailboxes_lock);
+ g_hash_table_foreach_remove (imapx_store->priv->mailboxes,
imapx_store_remove_unknown_mailboxes_cb, imapx_store);
+ g_mutex_unlock (&imapx_store->priv->mailboxes_lock);
+ }
+
array = camel_store_summary_array (imapx_store->summary);
for (ii = 0; ii < array->len; ii++) {
@@ -1483,7 +1559,7 @@ imapx_refresh_finfo (CamelSession *session,
CAMEL_SERVICE (store), cancellable, error))
goto exit;
- sync_folders (store, NULL, 0, cancellable, error);
+ sync_folders (store, NULL, 0, FALSE, cancellable, error);
camel_store_summary_save (store->summary);
@@ -1724,7 +1800,7 @@ imapx_store_get_folder_info_sync (CamelStore *store,
goto exit;
}
- if (!sync_folders (imapx_store, top, flags, cancellable, error))
+ if (!sync_folders (imapx_store, top, flags, initial_setup, cancellable, error))
goto exit;
camel_store_summary_save (imapx_store->summary);
@@ -3188,14 +3264,20 @@ camel_imapx_store_handle_list_response (CamelIMAPXStore *imapx_store,
mailbox = imapx_store_rename_mailbox_unlocked (
imapx_store, old_mailbox_name, mailbox_name);
emit_mailbox_renamed = (mailbox != NULL);
+ if (mailbox && camel_imapx_mailbox_get_state (mailbox) == CAMEL_IMAPX_MAILBOX_STATE_UNKNOWN)
+ camel_imapx_mailbox_set_state (mailbox, CAMEL_IMAPX_MAILBOX_STATE_RENAMED);
}
if (mailbox == NULL) {
mailbox = imapx_store_ref_mailbox_unlocked (imapx_store, mailbox_name);
emit_mailbox_updated = (mailbox != NULL);
+ if (mailbox && camel_imapx_mailbox_get_state (mailbox) == CAMEL_IMAPX_MAILBOX_STATE_UNKNOWN)
+ camel_imapx_mailbox_set_state (mailbox, CAMEL_IMAPX_MAILBOX_STATE_UPDATED);
}
if (mailbox == NULL) {
mailbox = imapx_store_create_mailbox_unlocked (imapx_store, response);
emit_mailbox_created = (mailbox != NULL);
+ if (mailbox)
+ camel_imapx_mailbox_set_state (mailbox, CAMEL_IMAPX_MAILBOX_STATE_CREATED);
} else {
camel_imapx_mailbox_handle_list_response (mailbox, response);
}
@@ -3250,6 +3332,8 @@ camel_imapx_store_handle_lsub_response (CamelIMAPXStore *imapx_store,
mailbox = imapx_store_ref_mailbox_unlocked (imapx_store, mailbox_name);
if (mailbox != NULL) {
camel_imapx_mailbox_handle_lsub_response (mailbox, response);
+ if (camel_imapx_mailbox_get_state (mailbox) == CAMEL_IMAPX_MAILBOX_STATE_UNKNOWN)
+ camel_imapx_mailbox_set_state (mailbox, CAMEL_IMAPX_MAILBOX_STATE_UPDATED);
emit_mailbox_updated = TRUE;
}
g_mutex_unlock (&imapx_store->priv->mailboxes_lock);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]