[PATCH 03/18] New observer behaviour
- From: Rob Taylor <rob taylor codethink co uk>
- To: tinymail-devel-list <tinymail-devel-list gnome org>
- Subject: [PATCH 03/18] New observer behaviour
- Date: Fri, 29 Aug 2008 17:40:51 +0100
New observer behaviour. Observers will get folders_appeared events when
a tny_folder_store_refresh or tny_folder_store_get_folders occurs and
the cache is loaded for the first time. They get folders_created events
when a new folder appears that we didn't know about before. Observers
are notified about existing folders when they're attached.
---
ChangeLog | 18 ++
libtinymail-camel/tny-camel-folder-priv.h | 1 +
libtinymail-camel/tny-camel-folder.c | 166
+++++++++++++++++---
libtinymail-camel/tny-camel-store-account-priv.h | 1 +
libtinymail-camel/tny-camel-store-account.c | 182
+++++++++++++++------
libtinymail/tny-folder-store-change.c | 81 +++++++++-
libtinymail/tny-folder-store-change.h | 5 +-
7 files changed, 372 insertions(+), 82 deletions(-)
--
Rob Taylor, Codethink Ltd. - http://codethink.co.uk
diff --git a/ChangeLog b/ChangeLog
index d780dc9..958b547 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -236,6 +236,24 @@
Added stream cache implementation files.
2008-06-12 Rob Taylor <rob taylor codethink co uk>
+ * libtinymail-camel/tny-camel-folder.c:
+ * libtinymail-camel/tny-camel-store-account.c:
+ Notify observers about existing folders when they're attached.
+
+2008-06-12 Rob Taylor <rob taylor codethink co uk>
+
+ * libtinymail-camel/tny-camel-folder-priv.h:
+ * libtinymail-camel/tny-camel-folder.c:
+ * libtinymail-camel/tny-camel-store-account-priv.h:
+ * libtinymail-camel/tny-camel-store-account.c:
+ * libtinymail/tny-folder-store-change.c:
+ * libtinymail/tny-folder-store-change.h:
+ New observer behaviour. Observers will get folders_appeared events when a
+ tny_folder_store_refresh or tny_folder_store_get_folders occurs and the cache
+ is loaded for the first time. They get folders_created events when a new folder
+ appears that we didn't know about before.
+
+2008-06-12 Rob Taylor <rob taylor codethink co uk>
* libtinymail-camel/tny-camel-folder.c:
* libtinymail-camel/tny-camel-folder.h:
diff --git a/libtinymail-camel/tny-camel-folder-priv.h b/libtinymail-camel/tny-camel-folder-priv.h
index 48bc5eb..11bde07 100644
--- a/libtinymail-camel/tny-camel-folder-priv.h
+++ b/libtinymail-camel/tny-camel-folder-priv.h
@@ -54,6 +54,7 @@ struct _TnyCamelFolderPriv
CamelException load_ex;
GList *obs, *sobs;
gboolean cant_reuse_iter;
+ GHashTable *known_folders;
};
CamelFolder* _tny_camel_folder_get_camel_folder (TnyCamelFolder *self);
diff --git a/libtinymail-camel/tny-camel-folder.c b/libtinymail-camel/tny-camel-folder.c
index e03ad47..17257f7 100644
--- a/libtinymail-camel/tny-camel-folder.c
+++ b/libtinymail-camel/tny-camel-folder.c
@@ -1533,6 +1533,23 @@ notify_account_del (gpointer user_data, GObject *parent)
}
#endif
+static void
+known_folder_del (gpointer user_data, GObject *folder)
+{
+ TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (user_data);
+ g_hash_table_remove (priv->known_folders, folder);
+}
+
+
+static gboolean
+known_folder_remover (GObject *folder,
+ gpointer value,
+ TnyCamelFolder *self)
+{
+ g_object_weak_unref (folder, known_folder_del, self);
+ return TRUE;
+}
+
void
_tny_camel_folder_set_account (TnyCamelFolder *self, TnyAccount *account)
{
@@ -5028,7 +5045,6 @@ _tny_camel_folder_set_folder_info (TnyFolderStore *self, TnyCamelFolder *folder,
"in the software\n");
_tny_camel_folder_set_name (folder, info->name);
- _tny_camel_folder_set_iter (folder, info);
if (TNY_IS_CAMEL_FOLDER (self)) {
TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
@@ -5037,6 +5053,7 @@ _tny_camel_folder_set_folder_info (TnyFolderStore *self, TnyCamelFolder *folder,
_tny_camel_folder_set_account (folder, TNY_ACCOUNT (self));
}
+ _tny_camel_folder_set_iter (folder, info);
_tny_camel_folder_set_parent (folder, self);
}
@@ -5305,10 +5322,10 @@ _tny_camel_folder_set_folder_type (TnyCamelFolder *folder, CamelFolderInfo *fold
}
}
-void
-_tny_camel_folder_set_iter (TnyCamelFolder *folder, CamelFolderInfo *iter)
+void
+_tny_camel_folder_set_iter (TnyCamelFolder *self, CamelFolderInfo *iter)
{
- TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (folder);
+ TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
priv->cant_reuse_iter = FALSE;
priv->iter = iter;
@@ -5320,6 +5337,32 @@ _tny_camel_folder_set_iter (TnyCamelFolder *folder, CamelFolderInfo *iter)
priv->iter_parented = TRUE;
+ //fill up known-folders with the folders we know about from this 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 (priv->account),
+ iter->full_name, &was_new);
+
+ if (was_new)
+ _tny_camel_folder_set_folder_info (TNY_FOLDER_STORE(self), folder, iter);
+
+ if (folder && !g_hash_table_lookup_extended (priv->known_folders, folder, NULL, NULL)) {
+ g_hash_table_insert(priv->known_folders, folder, NULL);
+ g_object_weak_ref (G_OBJECT(folder), known_folder_del, self);
+ }
+ g_object_unref (folder);
+ }
+ iter = iter->next;
+ }
+ }
return;
}
@@ -5336,6 +5379,7 @@ tny_camel_folder_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFo
TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
CamelFolderInfo *iter;
TnyAccount *account = NULL;
+ gboolean first_time = FALSE;
if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv),
priv->account, err, TNY_ERROR_DOMAIN,
@@ -5362,11 +5406,15 @@ tny_camel_folder_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFo
g_return_if_fail (priv->folder_name != NULL);
if (!refresh && CAMEL_IS_DISCO_STORE(store)) {
- priv->iter = CAMEL_DISCO_STORE_CLASS(store)->get_folder_info_offline(store, priv->folder_name, 0, &ex);
+ iter = CAMEL_DISCO_STORE_CLASS(CAMEL_OBJECT_GET_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);
+ iter = camel_store_get_folder_info (store, priv->folder_name, 0, &ex);
}
+ if (iter && priv->iter == NULL) {
+ first_time = TRUE;
+ }
+ priv->iter = iter;
priv->cant_reuse_iter = FALSE;
if (camel_exception_is_set (&ex))
@@ -5384,25 +5432,52 @@ tny_camel_folder_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFo
iter = priv->iter;
- if (iter)
+ if (iter && priv->account)
{
+ TnyFolderStoreChange *change = NULL;
+
iter = iter->child;
while (iter)
{
/* Also take a look at camel-maildir-store.c:525 */
- if (!(iter->flags & CAMEL_FOLDER_VIRTUAL) && _tny_folder_store_query_passes (query, iter) && priv->account)
+ if (!(iter->flags & CAMEL_FOLDER_VIRTUAL))
{
gboolean was_new = FALSE;
TnyCamelFolder *folder = (TnyCamelFolder *) tny_camel_store_account_factor_folder (
- TNY_CAMEL_STORE_ACCOUNT (priv->account),
+ TNY_CAMEL_STORE_ACCOUNT (priv->account),
iter->full_name, &was_new);
+
if (was_new)
_tny_camel_folder_set_folder_info (self, folder, iter);
- tny_list_prepend (list, G_OBJECT (folder));
+
+ if (folder && !g_hash_table_lookup_extended (priv->known_folders, folder, NULL, NULL)) {
+ g_hash_table_insert(priv->known_folders, folder, NULL);
+ g_object_weak_ref (G_OBJECT(folder), known_folder_del, self);
+
+ if (!change)
+ change = tny_folder_store_change_new (TNY_FOLDER_STORE(self));
+
+
+ if (first_time) {
+ tny_folder_store_change_add_appeared_folder (change, TNY_FOLDER(folder));
+ } else {
+ tny_folder_store_change_add_created_folder (change, TNY_FOLDER(folder));
+ }
+
+ }
+
+ if (_tny_folder_store_query_passes (query, iter)) {
+ tny_list_prepend (list, G_OBJECT (folder));
+ }
g_object_unref (folder);
}
iter = iter->next;
}
+ if (change) {
+ notify_folder_store_observers_about_in_idle (self, change,
+ TNY_FOLDER_PRIV_GET_SESSION (priv));
+ g_object_unref(change);
+ }
}
#ifdef MERGEFOLDERTEST
@@ -5588,18 +5663,16 @@ tny_camel_folder_store_refresh (TnyFolderStore *self, GError **err)
TnyAccount *account = NULL;
CamelStore *store = priv->store;
CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+ gboolean first_time = FALSE;
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;
+ iter = camel_store_get_folder_info (store, priv->folder_name, 0, &ex);
if (camel_exception_is_set (&ex))
{
@@ -5611,36 +5684,59 @@ tny_camel_folder_store_refresh (TnyFolderStore *self, GError **err)
return;
}
+ priv->cant_reuse_iter = FALSE;
priv->iter_parented = FALSE;
- iter = priv->iter;
-
- if (iter)
+ if (iter && priv->iter == NULL) {
+ first_time = TRUE;
+ }
+
+ priv->iter = iter;
+
+ if (iter && priv->account)
{
+ TnyFolderStoreChange *change = NULL;
iter = iter->child;
while (iter)
{
/* Also take a look at camel-maildir-store.c:525 */
- if (!(iter->flags & CAMEL_FOLDER_VIRTUAL) && priv->account)
+ if (!(iter->flags & CAMEL_FOLDER_VIRTUAL))
{
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;
+ if (was_new)
+ _tny_camel_folder_set_folder_info (self, folder, iter);
+
+ if (was_new)
_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);
+
+ if (folder && !g_hash_table_lookup_extended (priv->known_folders, folder, NULL, NULL)) {
+ g_hash_table_insert(priv->known_folders, folder, NULL);
+ g_object_weak_ref (G_OBJECT(folder), known_folder_del, self);
+
+ if (!change)
+ change = tny_folder_store_change_new (TNY_FOLDER_STORE(self));
+
+
+ if (first_time) {
+ tny_folder_store_change_add_appeared_folder (change, TNY_FOLDER(folder));
+ } else {
+ tny_folder_store_change_add_created_folder (change, TNY_FOLDER(folder));
+ }
+
}
g_object_unref (folder);
}
iter = iter->next;
}
+ if (change) {
+ notify_folder_store_observers_about_in_idle (self, change,
+ TNY_FOLDER_PRIV_GET_SESSION (priv));
+ g_object_unref(change);
+ }
+
}
@@ -6086,10 +6182,20 @@ notify_store_observer_del (gpointer user_data, GObject *observer)
g_static_rec_mutex_unlock (priv->obs_lock);
}
+static void build_appeared_change (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ TnyFolder *folder = key;
+ TnyFolderStoreChange *change = user_data;
+ tny_folder_store_change_add_appeared_folder (change, folder);
+}
+
static void
tny_camel_folder_store_add_observer_default (TnyFolderStore *self, TnyFolderStoreObserver *observer)
{
TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
+ TnyFolderStoreChange *change = tny_folder_store_change_new (self);
g_assert (TNY_IS_FOLDER_STORE_OBSERVER (observer));
@@ -6100,6 +6206,10 @@ tny_camel_folder_store_add_observer_default (TnyFolderStore *self, TnyFolderStor
}
g_static_rec_mutex_unlock (priv->obs_lock);
+ g_hash_table_foreach (priv->known_folders, build_appeared_change, change);
+ notify_folder_store_observers_about_in_idle (self, change, TNY_FOLDER_PRIV_GET_SESSION (priv));
+ g_object_unref (change);
+
return;
}
@@ -6249,6 +6359,9 @@ tny_camel_folder_dispose (GObject *object)
TnyCamelFolder *self = (TnyCamelFolder*) object;
TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
+ g_hash_table_foreach_remove (priv->known_folders, (GHRFunc) known_folder_remover, self);
+ g_hash_table_unref(priv->known_folders);
+
if (priv->store)
camel_object_unref (priv->store);
@@ -6540,6 +6653,7 @@ tny_camel_folder_instance_init (GTypeInstance *instance, gpointer g_class)
priv->folder = NULL;
priv->cached_name = NULL;
priv->cached_folder_type = TNY_FOLDER_TYPE_UNKNOWN;
+ priv->known_folders = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
priv->remove_strat = tny_camel_msg_remove_strategy_new ();
priv->receive_strat = tny_camel_full_msg_receive_strategy_new ();
priv->reason_lock = g_new0 (GStaticRecMutex, 1);
diff --git a/libtinymail-camel/tny-camel-store-account-priv.h b/libtinymail-camel/tny-camel-store-account-priv.h
index ea37d0b..0e21081 100644
--- a/libtinymail-camel/tny-camel-store-account-priv.h
+++ b/libtinymail-camel/tny-camel-store-account-priv.h
@@ -37,6 +37,7 @@ struct _TnyCamelStoreAccountPriv
gboolean cant_reuse_iter;
GStaticRecMutex *factory_lock, *obs_lock;
TnyCamelQueue *queue, *msg_queue;
+ GHashTable *known_folders;
gboolean deleted;
};
diff --git a/libtinymail-camel/tny-camel-store-account.c b/libtinymail-camel/tny-camel-store-account.c
index e803879..76d59c9 100644
--- a/libtinymail-camel/tny-camel-store-account.c
+++ b/libtinymail-camel/tny-camel-store-account.c
@@ -767,6 +767,8 @@ tny_camel_store_account_instance_init (GTypeInstance *instance, gpointer g_class
priv->sobs = NULL;
priv->iter = NULL;
priv->cant_reuse_iter = TRUE;
+ priv->known_folders = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
+
priv->factory_lock = g_new0 (GStaticRecMutex, 1);
g_static_rec_mutex_init (priv->factory_lock);
priv->obs_lock = g_new0 (GStaticRecMutex, 1);
@@ -798,12 +800,18 @@ notify_store_observer_del (gpointer user_data, GObject *observer)
g_static_rec_mutex_unlock (priv->obs_lock);
}
+
+static gboolean known_folder_remover (GObject *folder, gpointer value, TnyCamelStoreAccount *self);
+
static void
tny_camel_store_account_dispose (GObject *object)
{
TnyCamelStoreAccount *self = (TnyCamelStoreAccount *)object;
TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
+ g_hash_table_foreach_remove (priv->known_folders, (GHRFunc) known_folder_remover, self);
+ g_hash_table_unref (priv->known_folders);
+
if (priv->sobs) {
GList *copy = priv->sobs;
while (copy) {
@@ -1313,6 +1321,22 @@ notify_factory_del (TnyCamelStoreAccount *self, GObject *folder)
}
+static void
+known_folder_del (gpointer user_data, GObject *folder)
+{
+ TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (user_data);
+ g_hash_table_remove (priv->known_folders, folder);
+}
+
+static gboolean
+known_folder_remover (GObject *folder,
+ gpointer value,
+ TnyCamelStoreAccount *self)
+{
+ g_object_weak_unref (folder, known_folder_del, self);
+ return TRUE;
+}
+
static TnyFolder *
tny_camel_store_account_factor_folder_default (TnyCamelStoreAccount *self, const gchar *full_name, gboolean *was_new)
{
@@ -1357,6 +1381,7 @@ tny_camel_store_account_get_folders_default (TnyFolderStore *self, TnyList *list
TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
CamelException ex = CAMEL_EXCEPTION_INITIALISER;
CamelFolderInfo *iter=NULL; guint32 flags; CamelStore *store;
+ gboolean first_time = FALSE;
g_assert (TNY_IS_LIST (list));
g_assert (CAMEL_IS_SESSION (apriv->session));
@@ -1403,9 +1428,9 @@ tny_camel_store_account_get_folders_default (TnyFolderStore *self, TnyList *list
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);
+ iter = CAMEL_DISCO_STORE_CLASS(CAMEL_OBJECT_GET_CLASS(store))->get_folder_info_offline(store, "", 0, &ex);
} else {
- priv->iter = camel_store_get_folder_info (store, "", 0, &ex);
+ iter = camel_store_get_folder_info (store, "", 0, &ex);
}
}
@@ -1424,6 +1449,11 @@ tny_camel_store_account_get_folders_default (TnyFolderStore *self, TnyList *list
return;
}
+ if (iter && priv->iter == NULL) {
+ first_time = TRUE;
+ }
+
+
priv->iter = iter;
priv->cant_reuse_iter = FALSE;
@@ -1434,33 +1464,53 @@ tny_camel_store_account_get_folders_default (TnyFolderStore *self, TnyList *list
camel_object_ref (CAMEL_OBJECT (store));
priv->iter_store = store;
- if (iter)
- {
- while (iter)
- {
- /* Also take a look at camel-maildir-store.c:525 */
- if (!(iter->flags & CAMEL_FOLDER_VIRTUAL) && _tny_folder_store_query_passes (query, iter))
- {
- gboolean was_new = FALSE;
- TnyCamelFolder *folder = (TnyCamelFolder *) tny_camel_store_account_factor_folder (
- TNY_CAMEL_STORE_ACCOUNT (self),
- iter->full_name, &was_new);
+ if (iter) {
+ TnyFolderStoreChange *change = NULL;
- if (was_new && folder != NULL)
- _tny_camel_folder_set_folder_info (self, folder, iter);
+ while (iter) {
+ /* Also take a look at camel-maildir-store.c:525 */
+ if (!(iter->flags & CAMEL_FOLDER_VIRTUAL)) {
+ gboolean was_new = FALSE;
- if (folder != NULL)
- {
- const gchar *name = tny_folder_get_name (TNY_FOLDER(folder));
- /* TNY TODO: Temporary fix for empty root folders */
- if (name && strlen(name) > 0)
- tny_list_prepend (list, G_OBJECT (folder));
+ TnyCamelFolder *folder = (TnyCamelFolder *) tny_camel_store_account_factor_folder (
+ TNY_CAMEL_STORE_ACCOUNT (self),
+ iter->full_name, &was_new);
+
+ if (folder != NULL && was_new)
+ _tny_camel_folder_set_folder_info (self, folder, iter);
+
+ if (folder && !g_hash_table_lookup_extended (priv->known_folders, folder, NULL, NULL)) {
+ g_hash_table_insert(priv->known_folders, folder, NULL);
+ g_object_weak_ref (G_OBJECT(folder), known_folder_del, self);
+
+ if (!change)
+ change = tny_folder_store_change_new (TNY_FOLDER_STORE(self));
+
+
+ if (first_time) {
+ tny_folder_store_change_add_appeared_folder (change, TNY_FOLDER(folder));
+ } else {
+ tny_folder_store_change_add_created_folder (change, TNY_FOLDER(folder));
+ }
+
+ }
+
+ if (folder != NULL && _tny_folder_store_query_passes (query, iter))
+ {
+ const gchar *name = tny_folder_get_name (TNY_FOLDER(folder));
+ /* TNY TODO: Temporary fix for empty root folders */
+ if (name && strlen(name) > 0)
+ tny_list_prepend (list, G_OBJECT (folder));
+ }
g_object_unref (G_OBJECT (folder));
}
+ iter = iter->next;
+ }
+ if (change) {
+ notify_folder_store_observers_about_in_idle (self, change);
+ g_object_unref(change);
}
- iter = iter->next;
- }
}
_tny_session_stop_operation (apriv->session);
@@ -1619,6 +1669,7 @@ tny_camel_store_account_store_refresh (TnyFolderStore *self, GError **err)
TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
CamelException ex = CAMEL_EXCEPTION_INITIALISER;
CamelFolderInfo *iter=NULL; guint32 flags; CamelStore *store;
+ gboolean first_time = FALSE;
g_assert (CAMEL_IS_SESSION (apriv->session));
@@ -1655,7 +1706,7 @@ tny_camel_store_account_store_refresh (TnyFolderStore *self, GError **err)
flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
- priv->iter = camel_store_get_folder_info (store, "", 0, &ex);
+ iter = camel_store_get_folder_info (store, "", 0, &ex);
if (camel_exception_is_set (&ex))
{
@@ -1667,41 +1718,55 @@ tny_camel_store_account_store_refresh (TnyFolderStore *self, GError **err)
return;
}
- priv->cant_reuse_iter = FALSE;
+ if (iter && priv->iter == NULL) {
+ first_time = TRUE;
+ }
+ priv->cant_reuse_iter = FALSE;
camel_object_ref (CAMEL_OBJECT (store));
priv->iter_store = store;
+ priv->iter = iter;
- iter = priv->iter;
+ if (iter) {
+ TnyFolderStoreChange *change = NULL;
- 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);
+ 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 (folder != NULL && was_new)
+ _tny_camel_folder_set_folder_info (self, folder, iter);
+
+ if (folder && !g_hash_table_lookup_extended (priv->known_folders, folder, NULL, NULL)) {
+ g_hash_table_insert(priv->known_folders, folder, NULL);
+ g_object_weak_ref (G_OBJECT(folder), known_folder_del, self);
+
+ if (!change)
+ change = tny_folder_store_change_new (TNY_FOLDER_STORE(self));
+
+
+ if (first_time) {
+ tny_folder_store_change_add_appeared_folder (change, TNY_FOLDER(folder));
+ } else {
+ tny_folder_store_change_add_created_folder (change, TNY_FOLDER(folder));
+ }
+ }
+
+ g_object_unref(folder);
}
- g_object_unref (folder);
+ iter = iter->next;
+ }
+ if (change) {
+ notify_folder_store_observers_about_in_idle (self, change);
+ g_object_unref(change);
}
- iter = iter->next;
- }
}
-
_tny_session_stop_operation (apriv->session);
return;
@@ -1833,10 +1898,21 @@ tny_camel_store_account_add_observer (TnyFolderStore *self, TnyFolderStoreObserv
TNY_CAMEL_STORE_ACCOUNT_GET_CLASS (self)->add_observer(self, observer);
}
+static void build_appeared_change (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ TnyFolder *folder = key;
+ TnyFolderStoreChange *change = user_data;
+ tny_folder_store_change_add_appeared_folder (change, folder);
+}
+
+
static void
tny_camel_store_account_add_observer_default (TnyFolderStore *self, TnyFolderStoreObserver *observer)
{
TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
+ TnyFolderStoreChange *change = tny_folder_store_change_new (self);
g_assert (TNY_IS_FOLDER_STORE_OBSERVER (observer));
@@ -1847,11 +1923,13 @@ tny_camel_store_account_add_observer_default (TnyFolderStore *self, TnyFolderSto
}
g_static_rec_mutex_unlock (priv->obs_lock);
+ g_hash_table_foreach (priv->known_folders, build_appeared_change, change);
+ notify_folder_store_observers_about_in_idle (self, change);
+ g_object_unref (change);
+
return;
}
-
-
static void
tny_camel_store_account_remove_observer (TnyFolderStore *self, TnyFolderStoreObserver *observer)
{
diff --git a/libtinymail/tny-folder-store-change.c b/libtinymail/tny-folder-store-change.c
index 3ac9bb1..118b715 100644
--- a/libtinymail/tny-folder-store-change.c
+++ b/libtinymail/tny-folder-store-change.c
@@ -36,7 +36,7 @@ typedef struct _TnyFolderStoreChangePriv TnyFolderStoreChangePriv;
struct _TnyFolderStoreChangePriv
{
- TnyList *created, *removed;
+ TnyList *created, *removed, *appeared;
GMutex *lock;
TnyFolderStore *folderstore;
TnyFolderStoreChangeChanged changed;
@@ -125,6 +125,35 @@ tny_folder_store_change_add_removed_folder (TnyFolderStoreChange *self, TnyFolde
}
/**
+ * tny_folder_store_change_add_appeared_folder:
+ * @self: a #TnyFolderStoreChange
+ * @folder: a #TnyFolder to add to the changeset
+ *
+ * Add @folder to the changeset of appeared folders. This is an internal
+ * function not intended for application developers to alter.
+ *
+ * since: 1.0
+ * audience: tinymail-developer
+ **/
+void
+tny_folder_store_change_add_appeared_folder (TnyFolderStoreChange *self, TnyFolder *folder)
+{
+ TnyFolderStoreChangePriv *priv = TNY_FOLDER_STORE_CHANGE_GET_PRIVATE (self);
+
+ g_mutex_lock (priv->lock);
+
+ if (!priv->appeared)
+ priv->appeared = tny_simple_list_new ();
+ tny_list_prepend (priv->appeared, G_OBJECT (folder));
+ priv->changed |= TNY_FOLDER_STORE_CHANGE_CHANGED_APPEARED_FOLDERS;
+
+ g_mutex_unlock (priv->lock);
+
+ return;
+}
+
+
+/**
* tny_folder_store_change_get_created_folders:
* @self: a #TnyFolderStoreChange
* @folders: a #TnyList where the created folders will be prepended to
@@ -168,8 +197,6 @@ tny_folder_store_change_get_created_folders (TnyFolderStoreChange *self, TnyList
}
-
-
/**
* tny_folder_store_change_get_removed_folders:
* @self: a #TnyFolderStoreChange
@@ -213,6 +240,51 @@ tny_folder_store_change_get_removed_folders (TnyFolderStoreChange *self, TnyList
return;
}
+
+
+/**
+ * tny_folder_store_change_get_appeared_folders:
+ * @self: a #TnyFolderStoreChange
+ * @folders: a #TnyList where the appeared folders will be prepended to
+ *
+ * Get the appeared folders in this changeset
+ *
+ * since: 1.0
+ * audience: application-developer
+ **/
+void
+tny_folder_store_change_get_appeared_folders (TnyFolderStoreChange *self, TnyList *folders)
+{
+ TnyFolderStoreChangePriv *priv = TNY_FOLDER_STORE_CHANGE_GET_PRIVATE (self);
+ TnyIterator *iter;
+
+ g_assert (TNY_IS_LIST (folders));
+
+ g_mutex_lock (priv->lock);
+
+ if (!priv->appeared)
+ {
+ g_mutex_unlock (priv->lock);
+ return;
+ }
+
+ iter = tny_list_create_iterator (priv->appeared);
+
+ while (!tny_iterator_is_done (iter))
+ {
+ GObject *folder = tny_iterator_get_current (iter);
+ tny_list_prepend (folders, folder);
+ g_object_unref (folder);
+ tny_iterator_next (iter);
+ }
+
+ g_object_unref (iter);
+
+ g_mutex_unlock (priv->lock);
+
+ return;
+}
+
/**
* tny_folder_store_change_reset:
* @self: a #TnyFolderStoreChange
@@ -321,8 +393,11 @@ tny_folder_store_change_finalize (GObject *object)
g_object_unref (G_OBJECT (priv->created));
if (priv->removed)
g_object_unref (G_OBJECT (priv->removed));
+ if (priv->appeared)
+ g_object_unref (G_OBJECT (priv->appeared));
priv->created = NULL;
priv->removed = NULL;
+ priv->appeared = NULL;
if (priv->folderstore)
g_object_unref (G_OBJECT (priv->folderstore));
diff --git a/libtinymail/tny-folder-store-change.h b/libtinymail/tny-folder-store-change.h
index c49e97a..7e8742f 100644
--- a/libtinymail/tny-folder-store-change.h
+++ b/libtinymail/tny-folder-store-change.h
@@ -45,7 +45,8 @@ typedef struct _TnyFolderStoreChangeClass TnyFolderStoreChangeClass;
enum _TnyFolderStoreChangeChanged
{
TNY_FOLDER_STORE_CHANGE_CHANGED_CREATED_FOLDERS = 1<<0,
- TNY_FOLDER_STORE_CHANGE_CHANGED_REMOVED_FOLDERS = 1<<1
+ TNY_FOLDER_STORE_CHANGE_CHANGED_REMOVED_FOLDERS = 1<<1,
+ TNY_FOLDER_STORE_CHANGE_CHANGED_APPEARED_FOLDERS = 1<<2
};
typedef enum _TnyFolderStoreChangeChanged TnyFolderStoreChangeChanged;
@@ -68,9 +69,11 @@ TnyFolderStoreChange* tny_folder_store_change_new (TnyFolderStore *folderstore);
void tny_folder_store_change_add_created_folder (TnyFolderStoreChange *self, TnyFolder *folder);
void tny_folder_store_change_add_removed_folder (TnyFolderStoreChange *self, TnyFolder *folder);
+void tny_folder_store_change_add_appeared_folder (TnyFolderStoreChange *self, TnyFolder *folder);
void tny_folder_store_change_get_created_folders (TnyFolderStoreChange *self, TnyList *folders);
void tny_folder_store_change_get_removed_folders (TnyFolderStoreChange *self, TnyList *folders);
+void tny_folder_store_change_get_appeared_folders (TnyFolderStoreChange *self, TnyList *folders);
void tny_folder_store_change_reset (TnyFolderStoreChange *self);
TnyFolderStore* tny_folder_store_change_get_folder_store (TnyFolderStoreChange *self);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]