[PATCH] Give tny_folder_store_get_folders a refresh parameter, for optionally not refreshing from the server. Add tny_folder_store_refresh_async that will asynchronously refresh the store from the server, emitting TnyFolderStoreChanged events to observers. Implement it all for camel.
- From: Rob Taylor <rob taylor codethink co uk>
- Subject: [PATCH] Give tny_folder_store_get_folders a refresh parameter, for optionally not refreshing from the server. Add tny_folder_store_refresh_async that will asynchronously refresh the store from the server, emitting TnyFolderStoreChanged events to observers. Implement it all for camel.
- Date: Mon, 9 Jun 2008 20:03:33 +0100
---
ChangeLog | 14 ++
libtinymail-camel/tny-camel-folder.c | 226 +++++++++++++++++++++++--
libtinymail-camel/tny-camel-folder.h | 4 +-
libtinymail-camel/tny-camel-store-account.c | 243 +++++++++++++++++++++++++-
libtinymail-camel/tny-camel-store-account.h | 4 +-
libtinymail/tny-combined-account.c | 17 ++-
libtinymail/tny-folder-store.c | 34 +++-
libtinymail/tny-folder-store.h | 10 +-
libtinymail/tny-shared.h | 2 +
9 files changed, 512 insertions(+), 42 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 334f3bc..dba5a15 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,20 @@
2008-06-12 Rob Taylor <rob taylor codethink co uk>
* libtinymail-camel/tny-camel-folder.c:
+ * libtinymail-camel/tny-camel-folder.h:
+ * libtinymail-camel/tny-camel-store-account.c:
+ * libtinymail-camel/tny-camel-store-account.h:
+ * libtinymail/tny-combined-account.c:
+ * libtinymail/tny-folder-store.c: (tny_folder_store_get_folders),
+ * libtinymail/tny-folder-store.h:
+ * libtinymail/tny-shared.h:
+ Give tny_folder_store_get_folders a refresh parameter, for optionally not refreshing from the server.
+ Add tny_folder_store_refresh_async that will asynchronously refresh the store from the server, emitting TnyFolderStoreChanged events to observers.
+ Implement it all for camel.
+
+2008-06-12 Rob Taylor <rob taylor codethink co uk>
+
+ * libtinymail-camel/tny-camel-folder.c:
* libtinymail-camel/tny-camel-store-account.c:
do unrefs in dispose, not finalise for tny-camel-folder and tny-camel-store-account.
diff --git a/libtinymail-camel/tny-camel-folder.c b/libtinymail-camel/tny-camel-folder.c
index 26ec7fd..baec87e 100644
--- a/libtinymail-camel/tny-camel-folder.c
+++ b/libtinymail-camel/tny-camel-folder.c
@@ -3130,7 +3130,7 @@ recurse_copy (TnyFolder *folder, TnyFolderStore *into, const gchar *new_name, gb
TnyList *folders = tny_simple_list_new ();
TnyIterator *iter;
- tny_folder_store_get_folders (TNY_FOLDER_STORE (folder), folders, NULL, &nerr);
+ tny_folder_store_get_folders (TNY_FOLDER_STORE (folder), folders, NULL, TRUE, &nerr);
if (nerr != NULL)
{
@@ -3302,7 +3302,7 @@ recurse_evt (TnyFolder *folder, TnyFolderStore *into, GList *list, lstmodfunc fu
g_object_unref (acc);
list = func (list, cpy_event_new (TNY_FOLDER_STORE (into), folder));
- tny_folder_store_get_folders (TNY_FOLDER_STORE (folder), folders, NULL, NULL);
+ tny_folder_store_get_folders (TNY_FOLDER_STORE (folder), folders, NULL, TRUE, NULL);
iter = tny_list_create_iterator (folders);
while (!tny_iterator_is_done (iter))
{
@@ -4838,8 +4838,8 @@ recurse_remove (TnyFolderStore *from, TnyFolder *folder, GList *changes, GError
TnyList *folders = tny_simple_list_new ();
TnyIterator *iter;
- tny_folder_store_get_folders (TNY_FOLDER_STORE (folder),
- folders, NULL, &nerr);
+ tny_folder_store_get_folders (TNY_FOLDER_STORE (folder),
+ folders, NULL, TRUE, &nerr);
if (nerr != NULL)
{
@@ -5282,13 +5282,13 @@ _tny_camel_folder_set_iter (TnyCamelFolder *folder, CamelFolderInfo *iter)
}
static void
-tny_camel_folder_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err)
+tny_camel_folder_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err)
{
- TNY_CAMEL_FOLDER_GET_CLASS (self)->get_folders(self, list, query, err);
+ TNY_CAMEL_FOLDER_GET_CLASS (self)->get_folders(self, list, query, refresh, err);
}
static void
-tny_camel_folder_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err)
+tny_camel_folder_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err)
{
gboolean cant_reuse_iter = TRUE;
TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
@@ -5319,7 +5319,11 @@ tny_camel_folder_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFo
g_return_if_fail (priv->folder_name != NULL);
- priv->iter = camel_store_get_folder_info (store, priv->folder_name, 0, &ex);
+ if (!refresh && CAMEL_IS_DISCO_STORE(store)) {
+ priv->iter = CAMEL_DISCO_STORE_CLASS(store)->get_folder_info_offline(store, priv->folder_name, 0, &ex);
+ } else {
+ priv->iter = camel_store_get_folder_info (store, priv->folder_name, 0, &ex);
+ }
priv->cant_reuse_iter = FALSE;
@@ -5383,7 +5387,6 @@ tny_camel_folder_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFo
return;
}
-
typedef struct
{
TnyCamelQueueable parent;
@@ -5393,6 +5396,7 @@ typedef struct
TnyList *list;
TnyGetFoldersCallback callback;
TnyFolderStoreQuery *query;
+ gboolean refresh;
gpointer user_data;
TnySessionCamel *session;
gboolean cancelled;
@@ -5443,7 +5447,7 @@ tny_camel_folder_get_folders_async_thread (gpointer thr_user_data)
GetFoldersInfo *info = (GetFoldersInfo*) thr_user_data;
tny_folder_store_get_folders (TNY_FOLDER_STORE (info->self),
- info->list, info->query, &info->err);
+ info->list, info->query, info->refresh, &info->err);
info->cancelled = FALSE;
if (info->err != NULL) {
@@ -5490,14 +5494,14 @@ tny_camel_folder_get_folders_async_cancelled_callback (gpointer thr_user_data)
}
static void
-tny_camel_folder_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+tny_camel_folder_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
{
- TNY_CAMEL_FOLDER_GET_CLASS (self)->get_folders_async(self, list, query, callback, status_callback, user_data);
+ TNY_CAMEL_FOLDER_GET_CLASS (self)->get_folders_async(self, list, query, refresh, callback, status_callback, user_data);
}
static void
-tny_camel_folder_get_folders_async_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+tny_camel_folder_get_folders_async_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
{
GetFoldersInfo *info;
TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
@@ -5511,6 +5515,7 @@ tny_camel_folder_get_folders_async_default (TnyFolderStore *self, TnyList *list,
info->callback = callback;
info->user_data = user_data;
info->query = query;
+ info->refresh = refresh;
info->err = NULL;
/* thread reference */
@@ -5533,6 +5538,200 @@ tny_camel_folder_get_folders_async_default (TnyFolderStore *self, TnyList *list,
return;
}
+static void
+tny_camel_folder_store_refresh (TnyFolderStore *self, GError **err)
+{
+ TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
+ CamelFolderInfo *iter;
+ TnyAccount *account = NULL;
+ CamelStore *store = priv->store;
+ CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+
+ if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv),
+ priv->account, err, TNY_ERROR_DOMAIN,
+ TNY_SERVICE_ERROR_GET_FOLDERS))
+ return;
+
+ account = tny_folder_get_account (TNY_FOLDER (self));
+
+ g_return_if_fail (priv->folder_name != NULL);
+
+ priv->iter = camel_store_get_folder_info (store, priv->folder_name, 0, &ex);
+ priv->cant_reuse_iter = FALSE;
+
+ if (camel_exception_is_set (&ex))
+ {
+ _tny_camel_exception_to_tny_error (&ex, err);
+ camel_exception_clear (&ex);
+ _tny_session_stop_operation (TNY_FOLDER_PRIV_GET_SESSION (priv));
+
+ if (priv->iter == NULL)
+ return;
+ }
+
+ priv->iter_parented = FALSE;
+
+ iter = priv->iter;
+
+ if (iter)
+ {
+ iter = iter->child;
+ while (iter)
+ {
+ /* Also take a look at camel-maildir-store.c:525 */
+ if (!(iter->flags & CAMEL_FOLDER_VIRTUAL) && priv->account)
+ {
+ gboolean was_new = FALSE;
+ TnyCamelFolder *folder = (TnyCamelFolder *) tny_camel_store_account_factor_folder (
+ TNY_CAMEL_STORE_ACCOUNT (priv->account),
+ iter->full_name, &was_new);
+ if (was_new) {
+ TnyFolderStoreChange *change;
+ _tny_camel_folder_set_folder_info (self, folder, iter);
+ change = tny_folder_store_change_new (TNY_FOLDER_STORE(self));
+ tny_folder_store_change_add_created_folder (change, TNY_FOLDER(folder));
+ notify_folder_store_observers_about_in_idle (self,
+ change,
+ TNY_FOLDER_PRIV_GET_SESSION (priv));
+ g_object_unref(change);
+ }
+ g_object_unref (folder);
+ }
+ iter = iter->next;
+ }
+ }
+
+
+ _tny_session_stop_operation (TNY_FOLDER_PRIV_GET_SESSION (priv));
+
+ return;
+}
+
+typedef struct
+{
+ TnyCamelQueueable parent;
+
+ GError *err;
+ TnyFolderStore *self;
+ TnyFolderStoreCallback callback;
+ gpointer user_data;
+ TnySessionCamel *session;
+ gboolean cancelled;
+} StoreRefreshInfo;
+
+
+static void
+tny_camel_folder_store_refresh_async_destroyer (gpointer thr_user_data)
+{
+ StoreRefreshInfo *info = thr_user_data;
+ TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self);
+
+ /* thread reference */
+ _tny_camel_folder_unreason (priv);
+ g_object_unref (info->self);
+
+ if (info->err)
+ g_error_free (info->err);
+
+ _tny_session_stop_operation (info->session);
+
+ camel_object_unref (info->session);
+
+ return;
+}
+
+static gboolean
+tny_camel_folder_store_refresh_async_callback (gpointer thr_user_data)
+{
+ StoreRefreshInfo *info = thr_user_data;
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
+ info->callback (info->self, info->cancelled, info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
+ return FALSE;
+}
+
+
+static gpointer
+tny_camel_folder_store_refresh_async_thread (gpointer thr_user_data)
+{
+ StoreRefreshInfo *info = (StoreRefreshInfo*) thr_user_data;
+
+ tny_camel_folder_store_refresh (TNY_FOLDER_STORE (info->self), &info->err);
+
+ info->cancelled = FALSE;
+ if (info->err != NULL) {
+ if (camel_strstrcase (info->err->message, "cancel") != NULL)
+ info->cancelled = TRUE;
+ }
+
+ return NULL;
+}
+
+static void
+tny_camel_folder_store_refresh_async_cancelled_destroyer (gpointer thr_user_data)
+{
+ StoreRefreshInfo *info = thr_user_data;
+ TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self);
+
+ /* thread reference */
+ _tny_camel_folder_unreason (priv);
+ g_object_unref (info->self);
+
+ if (info->err)
+ g_error_free (info->err);
+
+ /**/
+
+ camel_object_unref (info->session);
+
+ return;
+}
+
+static gboolean
+tny_camel_folder_store_refresh_async_cancelled_callback (gpointer thr_user_data)
+{
+ StoreRefreshInfo *info = thr_user_data;
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
+ info->callback (info->self, TRUE, info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
+ return FALSE;
+}
+
+static void
+tny_camel_folder_store_refresh_async (TnyFolderStore *self, TnyFolderStoreCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+{
+ StoreRefreshInfo *info;
+ TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
+
+ /* Idle info for the callbacks */
+ info = g_slice_new (StoreRefreshInfo);
+ info->session = TNY_FOLDER_PRIV_GET_SESSION (priv);
+ camel_object_ref (info->session);
+ info->self = self;
+ info->callback = callback;
+ info->user_data = user_data;
+ info->err = NULL;
+
+ /* thread reference */
+ _tny_camel_folder_reason (priv);
+ g_object_ref (info->self);
+
+ _tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_QUEUE (priv),
+ tny_camel_folder_store_refresh_async_thread,
+ tny_camel_folder_store_refresh_async_callback,
+ tny_camel_folder_store_refresh_async_destroyer,
+ tny_camel_folder_store_refresh_async_cancelled_callback,
+ tny_camel_folder_store_refresh_async_cancelled_destroyer,
+ &info->cancelled,
+ info, sizeof (StoreRefreshInfo),
+ __FUNCTION__);
+
+ return;
+}
void
_tny_camel_folder_set_folder (TnyCamelFolder *self, CamelFolder *camel_folder)
@@ -6180,6 +6379,7 @@ tny_folder_store_init (gpointer g, gpointer iface_data)
klass->get_folders_async= tny_camel_folder_get_folders_async;
klass->add_observer= tny_camel_folder_store_add_observer;
klass->remove_observer= tny_camel_folder_store_remove_observer;
+ klass->refresh_async = tny_camel_folder_store_refresh_async;
return;
}
diff --git a/libtinymail-camel/tny-camel-folder.h b/libtinymail-camel/tny-camel-folder.h
index deffe45..522e8e1 100644
--- a/libtinymail-camel/tny-camel-folder.h
+++ b/libtinymail-camel/tny-camel-folder.h
@@ -92,8 +92,8 @@ struct _TnyCamelFolderClass
TnyFolderCaps (*get_caps) (TnyFolder *self);
void (*remove_msgs_async) (TnyFolder *self, TnyList *headers, TnyFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data);
- void (*get_folders_async) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data);
- void (*get_folders) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err);
+ void (*get_folders_async) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data);
+ void (*get_folders) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err);
void (*remove_folder) (TnyFolderStore *self, TnyFolder *folder, GError **err);
TnyFolder* (*create_folder) (TnyFolderStore *self, const gchar *name, GError **err);
void (*create_folder_async) (TnyFolderStore *self, const gchar *name, TnyCreateFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data);
diff --git a/libtinymail-camel/tny-camel-store-account.c b/libtinymail-camel/tny-camel-store-account.c
index f3dcbaa..b758b8c 100644
--- a/libtinymail-camel/tny-camel-store-account.c
+++ b/libtinymail-camel/tny-camel-store-account.c
@@ -952,7 +952,7 @@ recurse_remove (TnyFolderStore *from, TnyFolder *folder, GList *changes, GError
TnyIterator *iter;
tny_folder_store_get_folders (TNY_FOLDER_STORE (folder),
- folders, NULL, &nerr);
+ folders, NULL, TRUE, &nerr);
if (nerr != NULL)
{
@@ -1276,9 +1276,9 @@ tny_camel_store_account_create_folder_async_default (TnyFolderStore *self, const
static void
-tny_camel_store_account_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err)
+tny_camel_store_account_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err)
{
- TNY_CAMEL_STORE_ACCOUNT_GET_CLASS (self)->get_folders(self, list, query, err);
+ TNY_CAMEL_STORE_ACCOUNT_GET_CLASS (self)->get_folders(self, list, query, refresh, err);
}
/**
@@ -1351,7 +1351,7 @@ tny_camel_store_account_factor_folder_default (TnyCamelStoreAccount *self, const
}
static void
-tny_camel_store_account_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err)
+tny_camel_store_account_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err)
{
TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
@@ -1401,8 +1401,14 @@ tny_camel_store_account_get_folders_default (TnyFolderStore *self, TnyList *list
iter = priv->iter;
- if (!iter || priv->cant_reuse_iter)
- iter = camel_store_get_folder_info (store, "", flags, &ex);
+ if (!iter || priv->cant_reuse_iter) {
+ if (!refresh && CAMEL_IS_DISCO_STORE(store)) {
+ priv->iter = CAMEL_DISCO_STORE_CLASS(store)->get_folder_info_offline(store, "", 0, &ex);
+ } else {
+ priv->iter = camel_store_get_folder_info (store, "", 0, &ex);
+ }
+
+ }
/*else
iter = priv->iter;*/
@@ -1468,6 +1474,7 @@ typedef struct
TnyList *list;
TnyGetFoldersCallback callback;
TnyFolderStoreQuery *query;
+ gboolean refresh;
gpointer user_data;
TnySessionCamel *session;
gboolean cancelled;
@@ -1514,7 +1521,7 @@ tny_camel_store_account_get_folders_async_thread (gpointer thr_user_data)
GetFoldersInfo *info = (GetFoldersInfo*) thr_user_data;
tny_folder_store_get_folders (TNY_FOLDER_STORE (info->self),
- info->list, info->query, &info->err);
+ info->list, info->query, info->refresh, &info->err);
info->cancelled = FALSE;
if (info->err != NULL) {
@@ -1555,13 +1562,13 @@ tny_camel_store_account_get_folders_async_cancelled_callback (gpointer thr_user_
}
static void
-tny_camel_store_account_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+tny_camel_store_account_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
{
- TNY_CAMEL_STORE_ACCOUNT_GET_CLASS (self)->get_folders_async(self, list, query, callback, status_callback, user_data);
+ TNY_CAMEL_STORE_ACCOUNT_GET_CLASS (self)->get_folders_async(self, list, query, refresh, callback, status_callback, user_data);
}
static void
-tny_camel_store_account_get_folders_async_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+tny_camel_store_account_get_folders_async_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
{
GetFoldersInfo *info;
TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
@@ -1580,6 +1587,7 @@ tny_camel_store_account_get_folders_async_default (TnyFolderStore *self, TnyList
info->callback = callback;
info->user_data = user_data;
info->query = query;
+ info->refresh = refresh;
/* thread reference */
g_object_ref (info->self);
@@ -1600,6 +1608,220 @@ tny_camel_store_account_get_folders_async_default (TnyFolderStore *self, TnyList
return;
}
+static void
+tny_camel_store_account_store_refresh (TnyFolderStore *self, GError **err)
+{
+ TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
+ TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
+ CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+ CamelFolderInfo *iter=NULL; guint32 flags; CamelStore *store;
+
+ g_assert (CAMEL_IS_SESSION (apriv->session));
+
+ if (!_tny_session_check_operation (apriv->session, TNY_ACCOUNT (self), err,
+ TNY_ERROR_DOMAIN, TNY_SERVICE_ERROR_GET_FOLDERS))
+ return;
+
+ if (apriv->service == NULL || !CAMEL_IS_SERVICE (apriv->service))
+ {
+ g_set_error (err, TNY_ERROR_DOMAIN,
+ TNY_SERVICE_ERROR_GET_FOLDERS,
+ _("Account not ready for this operation. "
+ "This problem indicates a bug in the software."));
+ _tny_session_stop_operation (apriv->session);
+ return;
+ }
+
+ store = CAMEL_STORE (apriv->service);
+
+ if (camel_exception_is_set (&ex))
+ {
+ _tny_camel_exception_to_tny_error (&ex, err);
+ camel_exception_clear (&ex);
+ _tny_session_stop_operation (apriv->session);
+ return;
+ }
+
+ g_assert (CAMEL_IS_STORE (store));
+
+ flags = CAMEL_STORE_FOLDER_INFO_FAST | CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL |
+ CAMEL_STORE_FOLDER_INFO_RECURSIVE;
+
+ if (!camel_session_is_online ((CamelSession*) apriv->session))
+ flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
+
+
+ priv->iter = camel_store_get_folder_info (store, "", 0, &ex);
+
+ if (camel_exception_is_set (&ex))
+ {
+ _tny_camel_exception_to_tny_error (&ex, err);
+ camel_exception_clear (&ex);
+
+ _tny_session_stop_operation (apriv->session);
+
+ return;
+ }
+
+ priv->cant_reuse_iter = FALSE;
+
+ camel_object_ref (CAMEL_OBJECT (store));
+ priv->iter_store = store;
+
+ iter = priv->iter;
+
+ if (iter)
+ {
+ iter = iter->child;
+ while (iter)
+ {
+ /* Also take a look at camel-maildir-store.c:525 */
+ if (!(iter->flags & CAMEL_FOLDER_VIRTUAL))
+ {
+ gboolean was_new = FALSE;
+ TnyCamelFolder *folder = (TnyCamelFolder *) tny_camel_store_account_factor_folder (
+ TNY_CAMEL_STORE_ACCOUNT (self),
+ iter->full_name, &was_new);
+ if (was_new) {
+ TnyFolderStoreChange *change;
+ _tny_camel_folder_set_folder_info (self, folder, iter);
+ change = tny_folder_store_change_new (TNY_FOLDER_STORE(self));
+ tny_folder_store_change_add_created_folder (change, TNY_FOLDER(folder));
+ notify_folder_store_observers_about_in_idle (self,
+ change);
+ g_object_unref(change);
+ }
+ g_object_unref (folder);
+ }
+ iter = iter->next;
+ }
+ }
+
+
+ _tny_session_stop_operation (apriv->session);
+
+ return;
+}
+
+
+typedef struct
+{
+ TnyCamelQueueable parent;
+
+ GError *err;
+ TnyFolderStore *self;
+ TnyFolderStoreCallback callback;
+ gpointer user_data;
+ TnySessionCamel *session;
+ gboolean cancelled;
+
+} StoreRefreshInfo;
+
+
+static void
+tny_camel_store_account_store_refresh_async_destroyer (gpointer thr_user_data)
+{
+ StoreRefreshInfo *info = thr_user_data;
+
+ /* gidle reference */
+ g_object_unref (info->self);
+
+ if (info->err)
+ g_error_free (info->err);
+
+ camel_object_unref (info->session);
+
+ return;
+}
+
+static gboolean
+tny_camel_store_account_store_refresh_async_callback (gpointer thr_user_data)
+{
+ StoreRefreshInfo *info = thr_user_data;
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
+ info->callback (info->self, info->cancelled, info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
+ return FALSE;
+}
+
+
+static gpointer
+tny_camel_store_account_store_refresh_async_thread (gpointer thr_user_data)
+{
+ StoreRefreshInfo *info = (StoreRefreshInfo*) thr_user_data;
+
+ tny_camel_store_account_store_refresh (TNY_FOLDER_STORE (info->self), &info->err);
+
+ info->cancelled = FALSE;
+ if (info->err != NULL) {
+ if (camel_strstrcase (info->err->message, "cancel") != NULL)
+ info->cancelled = TRUE;
+ }
+
+ return NULL;
+}
+
+static void
+tny_camel_store_account_store_refresh_async_cancelled_destroyer (gpointer thr_user_data)
+{
+ StoreRefreshInfo *info = thr_user_data;
+ /* gidle references */
+ g_object_unref (info->self);
+ if (info->err)
+ g_error_free (info->err);
+
+ camel_object_unref (info->session);
+
+ return;
+}
+
+static gboolean
+tny_camel_store_account_store_refresh_async_cancelled_callback (gpointer thr_user_data)
+{
+ StoreRefreshInfo *info = thr_user_data;
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
+ info->callback (info->self, TRUE, info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
+ return FALSE;
+}
+
+static void
+tny_camel_store_account_store_refresh_async (TnyFolderStore *self, TnyFolderStoreCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+{
+ StoreRefreshInfo *info;
+ TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
+ TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
+
+ /* Idle info for the callbacks */
+ info = g_slice_new0 (StoreRefreshInfo);
+ info->session = apriv->session;
+ camel_object_ref (info->session);
+
+ info->err = NULL;
+ info->self = self;
+ info->callback = callback;
+ info->user_data = user_data;
+
+ /* thread reference */
+ g_object_ref (info->self);
+
+ _tny_camel_queue_launch_wflags (priv->queue,
+ tny_camel_store_account_store_refresh_async_thread,
+ tny_camel_store_account_store_refresh_async_callback,
+ tny_camel_store_account_store_refresh_async_destroyer,
+ tny_camel_store_account_store_refresh_async_cancelled_callback,
+ tny_camel_store_account_store_refresh_async_cancelled_destroyer,
+ &info->cancelled, info, sizeof (StoreRefreshInfo),
+ TNY_CAMEL_QUEUE_NORMAL_ITEM|TNY_CAMEL_QUEUE_PRIORITY_ITEM,
+ __FUNCTION__);
+
+ return;
+}
+
static void
tny_camel_store_account_add_observer (TnyFolderStore *self, TnyFolderStoreObserver *observer)
@@ -2068,6 +2290,7 @@ tny_folder_store_init (gpointer g, gpointer iface_data)
klass->get_folders_async= tny_camel_store_account_get_folders_async;
klass->add_observer= tny_camel_store_account_add_observer;
klass->remove_observer= tny_camel_store_account_remove_observer;
+ klass->refresh_async = tny_camel_store_account_store_refresh_async;
return;
}
diff --git a/libtinymail-camel/tny-camel-store-account.h b/libtinymail-camel/tny-camel-store-account.h
index e5299b7..a702eb1 100644
--- a/libtinymail-camel/tny-camel-store-account.h
+++ b/libtinymail-camel/tny-camel-store-account.h
@@ -49,8 +49,8 @@ struct _TnyCamelStoreAccountClass
TnyCamelAccountClass parent;
/* virtual methods */
- void (*get_folders_async) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data);
- void (*get_folders) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err);
+ void (*get_folders_async) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data);
+ void (*get_folders) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err);
void (*remove_folder) (TnyFolderStore *self, TnyFolder *folder, GError **err);
TnyFolder* (*create_folder) (TnyFolderStore *self, const gchar *name, GError **err);
void (*create_folder_async) (TnyFolderStore *self, const gchar *name, TnyCreateFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data);
diff --git a/libtinymail/tny-combined-account.c b/libtinymail/tny-combined-account.c
index 8ef3f4b..32f34a0 100644
--- a/libtinymail/tny-combined-account.c
+++ b/libtinymail/tny-combined-account.c
@@ -299,19 +299,27 @@ tny_combined_account_create_folder (TnyFolderStore *self, const gchar *name, GEr
}
static void
-tny_combined_account_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err)
+tny_combined_account_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err)
{
TnyCombinedAccountPriv *priv = TNY_COMBINED_ACCOUNT_GET_PRIVATE (self);
- tny_folder_store_get_folders (TNY_FOLDER_STORE (priv->store_account), list, query, err);
+ tny_folder_store_get_folders (TNY_FOLDER_STORE (priv->store_account), list, query, refresh, err);
}
static void
-tny_combined_account_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+tny_combined_account_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
{
TnyCombinedAccountPriv *priv = TNY_COMBINED_ACCOUNT_GET_PRIVATE (self);
- tny_folder_store_get_folders_async (TNY_FOLDER_STORE (priv->store_account), list, query, callback, status_callback, user_data);
+ tny_folder_store_get_folders_async (TNY_FOLDER_STORE (priv->store_account), list, query, refresh, callback, status_callback, user_data);
+}
+
+static void
+tny_combined_account_refresh_async (TnyFolderStore *self, TnyFolderStoreCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+{
+ TnyCombinedAccountPriv *priv = TNY_COMBINED_ACCOUNT_GET_PRIVATE (self);
+
+ tny_folder_store_refresh_async (TNY_FOLDER_STORE (priv->store_account), callback, status_callback, user_data);
}
static void
@@ -540,6 +548,7 @@ tny_folder_store_init (TnyFolderStoreIface *klass)
klass->get_folders_async= tny_combined_account_get_folders_async;
klass->add_observer= tny_combined_account_add_observer;
klass->remove_observer= tny_combined_account_remove_observer;
+ klass->refresh_async = tny_combined_account_refresh_async;
}
static void
diff --git a/libtinymail/tny-folder-store.c b/libtinymail/tny-folder-store.c
index 57caee7..62fe7c1 100644
--- a/libtinymail/tny-folder-store.c
+++ b/libtinymail/tny-folder-store.c
@@ -266,6 +266,7 @@ tny_folder_store_create_folder_async (TnyFolderStore *self, const gchar *name, T
* @self: a #TnyFolderStore
* @list: a #TnyList to to which the folders will be prepended
* @query: (null-ok): a #TnyFolderStoreQuery or NULL
+ * @refresh: synchronize with the service first
* @err: (null-ok): a #GError or NULL
*
* Get a list of child folders from @self. You can use @query to limit the list
@@ -277,7 +278,7 @@ tny_folder_store_create_folder_async (TnyFolderStore *self, const gchar *name, T
* TnyFolderStore *store = ...
* TnyIterator *iter; TnyFolderStoreQuery *query = ...
* TnyList *folders = tny_simple_list_new ();
- * tny_folder_store_get_folders (store, folders, query, NULL);
+ * tny_folder_store_get_folders (store, folders, query, TRUE, NULL);
* iter = tny_list_create_iterator (folders);
* while (!tny_iterator_is_done (iter))
* {
@@ -295,7 +296,7 @@ tny_folder_store_create_folder_async (TnyFolderStore *self, const gchar *name, T
* audience: application-developer
**/
void
-tny_folder_store_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err)
+tny_folder_store_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err)
{
#ifdef DBC /* require */
g_assert (TNY_IS_FOLDER_STORE (self));
@@ -306,7 +307,7 @@ tny_folder_store_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStor
g_assert (TNY_FOLDER_STORE_GET_IFACE (self)->get_folders!= NULL);
#endif
- TNY_FOLDER_STORE_GET_IFACE (self)->get_folders(self, list, query, err);
+ TNY_FOLDER_STORE_GET_IFACE (self)->get_folders(self, list, query, refresh, err);
#ifdef DBC /* ensure */
#endif
@@ -343,6 +344,7 @@ tny_folder_store_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStor
* @self: a #TnyFolderStore
* @list: a #TnyList to to which the folders will be prepended
* @query: (null-ok): A #TnyFolderStoreQuery object
+ * @refresh: synchronize with the service first
* @callback: (null-ok): a #TnyGetFoldersCallback or NULL
* @status_callback: (null-ok): a #TnyStatusCallback or NULL
* @user_data: (null-ok): user data that will be passed to the callbacks
@@ -363,7 +365,7 @@ tny_folder_store_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStor
* TnyList *folders = tny_simple_list_new ();
* g_print ("%s\n", tny_folder_get_name (TNY_FOLDER (folder)));
* tny_folder_store_get_folders_async (folder,
- * folders, NULL, callback, NULL, NULL);
+ * folders, NULL, true, callback, NULL, NULL);
* g_object_unref (folder);
* tny_iterator_next (iter);
* }
@@ -375,7 +377,7 @@ tny_folder_store_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStor
* TnyList *folders;
* folders = tny_simple_list_new ();
* tny_folder_store_get_folders_async (TNY_FOLDER_STORE (account),
- * folders, NULL, callback, NULL, NULL);
+ * folders, NULL, TRUE, callback, NULL, NULL);
* g_object_unref (folders);
* }
* </programlisting></informalexample>
@@ -388,7 +390,7 @@ tny_folder_store_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStor
* audience: application-developer
**/
void
-tny_folder_store_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+tny_folder_store_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data)
{
#ifdef DBC /* require */
g_assert (TNY_IS_FOLDER_STORE (self));
@@ -399,7 +401,7 @@ tny_folder_store_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFold
g_assert (TNY_FOLDER_STORE_GET_IFACE (self)->get_folders_async!= NULL);
#endif
- TNY_FOLDER_STORE_GET_IFACE (self)->get_folders_async(self, list, query, callback, status_callback, user_data);
+ TNY_FOLDER_STORE_GET_IFACE (self)->get_folders_async(self, list, query, refresh, callback, status_callback, user_data);
#ifdef DBC /* ensure */
#endif
@@ -408,6 +410,24 @@ tny_folder_store_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFold
}
+void tny_folder_store_refresh_async (TnyFolderStore *self, TnyFolderStoreCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+{
+#ifdef DBC /* require */
+ g_assert (TNY_IS_FOLDER_STORE (self));
+ g_assert (list);
+ g_assert (TNY_IS_LIST (list));
+ if (query)
+ g_assert (TNY_IS_FOLDER_STORE_QUERY (query));
+ g_assert (TNY_FOLDER_STORE_GET_IFACE (self)->get_folders_async!= NULL);
+#endif
+
+ TNY_FOLDER_STORE_GET_IFACE (self)->refresh_async(self, callback, status_callback, user_data);
+
+#ifdef DBC /* ensure */
+#endif
+
+ return;
+}
static void
tny_folder_store_base_init (gpointer g_class)
diff --git a/libtinymail/tny-folder-store.h b/libtinymail/tny-folder-store.h
index d3b13cc..ebd52ef 100644
--- a/libtinymail/tny-folder-store.h
+++ b/libtinymail/tny-folder-store.h
@@ -48,10 +48,11 @@ struct _TnyFolderStoreIface
void (*remove_folder) (TnyFolderStore *self, TnyFolder *folder, GError **err);
TnyFolder* (*create_folder) (TnyFolderStore *self, const gchar *name, GError **err);
void (*create_folder_async) (TnyFolderStore *self, const gchar *name, TnyCreateFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data);
- void (*get_folders) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err);
- void (*get_folders_async) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data);
+ void (*get_folders) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err);
+ void (*get_folders_async) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data);
void (*add_observer) (TnyFolderStore *self, TnyFolderStoreObserver *observer);
void (*remove_observer) (TnyFolderStore *self, TnyFolderStoreObserver *observer);
+ void (*refresh_async) (TnyFolderStore *self, TnyFolderStoreCallback callback, TnyStatusCallback status_callback, gpointer user_data);
};
@@ -59,12 +60,13 @@ GType tny_folder_store_get_type (void);
void tny_folder_store_remove_folder (TnyFolderStore *self, TnyFolder *folder, GError **err);
void tny_folder_store_create_folder_async (TnyFolderStore *self, const gchar *name, TnyCreateFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data);
-void tny_folder_store_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data);
+void tny_folder_store_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data);
void tny_folder_store_add_observer (TnyFolderStore *self, TnyFolderStoreObserver *observer);
void tny_folder_store_remove_observer (TnyFolderStore *self, TnyFolderStoreObserver *observer);
+void tny_folder_store_refresh_async (TnyFolderStore *self, TnyFolderStoreCallback callback, TnyStatusCallback status_callback, gpointer user_data);
#ifndef TNY_DISABLE_DEPRECATED
-void tny_folder_store_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err);
+void tny_folder_store_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err);
TnyFolder *tny_folder_store_create_folder (TnyFolderStore *self, const gchar *name, GError **err);
#endif
diff --git a/libtinymail/tny-shared.h b/libtinymail/tny-shared.h
index f74e169..71cd67f 100644
--- a/libtinymail/tny-shared.h
+++ b/libtinymail/tny-shared.h
@@ -127,6 +127,8 @@ typedef void (*TnyCreateFolderCallback) (TnyFolderStore *self, gboolean cancelle
typedef void (*TnyFolderCallback) (TnyFolder *self, gboolean cancelled, GError *err, gpointer user_data);
typedef void (*TnyGetHeadersCallback) (TnyFolder *self, gboolean cancelled, TnyList *headers, GError *err, gpointer user_data);
+typedef void (*TnyFolderStoreCallback) (TnyFolderStore *self, gboolean cancelled, GError *err, gpointer user_data);
+
/**
* TnyGetMsgCallback:
* @folder: a #TnyFolder that caused the callback
--
1.5.4.3
--------------040209010609030806090308
Content-Type: text/x-diff;
name="0003-New-observer-behaviour.-Observers-will-get-folders_a.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename*0="0003-New-observer-behaviour.-Observers-will-get-folders_a.pa";
filename*1="tch"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]