Patch: delayed refresh mode in folder list store



	Hi,

	This patch adds a new mode to tinymail TnyGtkFolderListStore called
"delayed refresh". This is for acting as an offline account to show fast
cached folders, but then do a refresh to act as offline (this improves a
lot the user experience, faster feedback). This patch also allows to
detect better new remote folders.

Changelog entry:
	* libtinymail-camel/tny-camel-store-account.c. New method
	_tny_camel_store_account_refresh_children. This is used for
	checking to recurse folders for knowing if there are new
	folders available.

	* libtinymailui-gtk/tny-gtk-folder-list-store.[ch]: implemented new
	"delayed refresh" flag. This is for telling store to act as
	offline in first seconds, but then do an online refresh. With this
	we get immediate view of cached folders, but after a while we get
	a network access so we see new folders.

-- 
José Dapena Paz <jdapena igalia com>
Igalia
diff --git a/ChangeLog b/ChangeLog
index 52aa31e..0df8e24 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2009-06-12  Jose Dapena Paz  <jdapena igalia com>
+
+	* libtinymail-camel/tny-camel-store-account.c. New method
+	_tny_camel_store_account_refresh_children. This is used for
+	checking to recurse folders for knowing if there are new
+	folders available.
+
+	* libtinymailui-gtk/tny-gtk-folder-list-store.[ch]: implemented new
+	"delayed refresh" flag. This is for telling store to act as
+	offline in first seconds, but then do an online refresh. With this
+	we get immediate view of cached folders, but after a while we get
+	a network access so we see new folders.
+
 2009-06-11  Sergio Villar Senin  <svillar igalia com>
 
 	* libtinymail-maemo/tny-maemo-conic-device.c (handle_connect)
diff --git a/libtinymail-camel/tny-camel-store-account.c b/libtinymail-camel/tny-camel-store-account.c
index eadba64..c69f3f0 100644
--- a/libtinymail-camel/tny-camel-store-account.c
+++ b/libtinymail-camel/tny-camel-store-account.c
@@ -1385,6 +1385,49 @@ tny_camel_store_account_factor_folder_default (TnyCamelStoreAccount *self, const
 	return (TnyFolder *) folder;
 }
 
+static void
+_tny_camel_store_account_refresh_children (TnyFolderStore *self, TnyFolder *folder, CamelFolderInfo *iter)
+{
+	TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
+	CamelFolderInfo *child;
+
+	child = iter->child;
+	for (child = iter->child; child != NULL; child = child->next) {
+		GList *managed_folders;
+		TnyFolder *found = NULL;
+
+		for (managed_folders = priv->managed_folders; 
+		     managed_folders != NULL; 
+		     managed_folders = g_list_next (managed_folders)) {
+
+			TnyFolder *fnd = (TnyFolder*) managed_folders->data;
+			const gchar *name = tny_folder_get_id (fnd);
+
+			if (name && child->full_name && !strcmp (name, child->full_name))
+			{
+				found = fnd;
+				break;
+			}
+		}
+
+		if (!found) {
+			TnyCamelFolderPriv *fpriv = TNY_CAMEL_FOLDER_GET_PRIVATE (folder);
+			if (fpriv->iter) {
+				CamelFolderInfo *copy;
+
+				copy = camel_folder_info_clone (child);
+				copy->next = fpriv->iter->child;
+				copy->parent = iter;
+				fpriv->iter->child = copy;
+			}
+		} else {
+			_tny_camel_store_account_refresh_children (self, found, child);
+		}
+
+	}
+}
+
+
 static void 
 tny_camel_store_account_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err)
 {
@@ -1477,11 +1520,13 @@ tny_camel_store_account_get_folders_default (TnyFolderStore *self, TnyList *list
 				TNY_CAMEL_STORE_ACCOUNT (self), 
 				iter->full_name, &was_new);
 
-			if (was_new && folder != NULL)
-				_tny_camel_folder_set_folder_info (self, folder, iter);
-
 			if (folder != NULL)
 			{
+				if (was_new)
+					_tny_camel_folder_set_folder_info (self, folder, iter);
+				else
+					_tny_camel_store_account_refresh_children (self, folder, iter);
+			
 				const gchar *name = tny_folder_get_name (TNY_FOLDER(folder));
 				/* TNY TODO: Temporary fix for empty root folders */
 				if (name && strlen(name) > 0)
diff --git a/libtinymailui-gtk/tny-gtk-folder-list-store.c b/libtinymailui-gtk/tny-gtk-folder-list-store.c
index 28b4096..e082913 100644
--- a/libtinymailui-gtk/tny-gtk-folder-list-store.c
+++ b/libtinymailui-gtk/tny-gtk-folder-list-store.c
@@ -81,6 +81,29 @@ guint tny_gtk_folder_list_store_signals [LAST_SIGNAL];
 
 typedef void (*listaddfunc) (GtkListStore *list_store, GtkTreeIter *iter);
 
+static void tny_gtk_folder_list_store_on_constatus_changed (TnyAccount *account, 
+							    TnyConnectionStatus status, 
+							    TnyGtkFolderListStore *self);
+
+
+static gboolean
+delayed_refresh_timeout_handler (TnyGtkFolderListStore *self)
+{
+	GList *node;
+	self->delayed_refresh_timeout_id = 0;
+
+	for (node = self->first; node != NULL; node = g_list_next (node)) {
+		if (TNY_IS_ACCOUNT (node->data)) {
+			tny_gtk_folder_list_store_on_constatus_changed (
+				TNY_ACCOUNT (node->data),
+				tny_account_get_connection_status (TNY_ACCOUNT (node->data)),
+				self);
+		}
+	}
+
+	return FALSE;
+}
+
 
 static void 
 add_folder_observer_weak (TnyGtkFolderListStore *self, TnyFolder *folder)
@@ -342,6 +365,18 @@ recurse_folders_async_cb (TnyFolderStore *store,
 			if (mark_for_removal) {
 				g_object_unref (mark_for_removal);
 				mark_for_removal = NULL;
+			} else if (folder_store) {
+				/* We still keep recursing already fetch folders, to know if there are new child
+				   folders */
+				TnyList *folders = tny_simple_list_new ();
+
+				self->progress_count++;
+				tny_folder_store_get_folders_async (folder_store,
+								    folders, NULL, 
+								    !(self->flags & TNY_GTK_FOLDER_LIST_STORE_FLAG_NO_REFRESH),
+								    recurse_folders_async_cb,
+								    NULL, g_object_ref (self));
+				g_object_unref (folders);
 			}
 		}
 
@@ -466,6 +501,12 @@ tny_gtk_folder_list_store_on_constatus_changed (TnyAccount *account, TnyConnecti
 	if (self->progress_count == 1) {
 		g_signal_emit (self, tny_gtk_folder_list_store_signals[ACTIVITY_CHANGED_SIGNAL], 0, TRUE);
 	}
+
+	if (self->flags & TNY_GTK_FOLDER_LIST_STORE_FLAG_DELAYED_REFRESH) {
+		self->flags &= (~TNY_GTK_FOLDER_LIST_STORE_FLAG_DELAYED_REFRESH);
+		self->flags &= (~TNY_GTK_FOLDER_LIST_STORE_FLAG_NO_REFRESH);
+	}
+
 	tny_folder_store_get_folders_async (TNY_FOLDER_STORE (account),
 					    list, self->query,
 					    !(self->flags & TNY_GTK_FOLDER_LIST_STORE_FLAG_NO_REFRESH),
@@ -651,6 +692,18 @@ tny_gtk_folder_list_store_add_i (TnyGtkFolderListStore *self, TnyFolderStore *fo
 	if (self->progress_count == 1) {
 		g_signal_emit (self, tny_gtk_folder_list_store_signals[ACTIVITY_CHANGED_SIGNAL], 0, TRUE);
 	}
+
+	if (self->flags & TNY_GTK_FOLDER_LIST_STORE_FLAG_DELAYED_REFRESH) {
+		if (self->delayed_refresh_timeout_id > 0) {
+			g_source_remove (self->delayed_refresh_timeout_id);
+		}
+		self->delayed_refresh_timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
+									       1,
+									       (GSourceFunc) delayed_refresh_timeout_handler,
+									       g_object_ref (self),
+									       g_object_unref);
+	}
+
 	tny_folder_store_get_folders_async (TNY_FOLDER_STORE (folder_store), 
 					    folders, self->query, 
 					    !(self->flags & TNY_GTK_FOLDER_LIST_STORE_FLAG_NO_REFRESH),  
@@ -703,6 +756,10 @@ tny_gtk_folder_list_store_new_with_flags (TnyFolderStoreQuery *query,
 	if (query) 
 		self->query = g_object_ref (query);
 
+	/* DELAYED_REFRESH implies NO_REFRESH */
+	if (flags & TNY_GTK_FOLDER_LIST_STORE_FLAG_DELAYED_REFRESH)
+		flags |= TNY_GTK_FOLDER_LIST_STORE_FLAG_NO_REFRESH;
+
 	self->flags = flags;
 
 	return GTK_TREE_MODEL (self);
@@ -716,6 +773,11 @@ tny_gtk_folder_list_store_finalize (GObject *object)
 	TnyGtkFolderListStore *me = (TnyGtkFolderListStore*) object;
 	int i = 0;
 
+	if (me->delayed_refresh_timeout_id > 0) {
+		g_source_remove (me->delayed_refresh_timeout_id);
+		me->delayed_refresh_timeout_id = 0;
+	}
+
 	for (i = 0; i < me->signals->len; i++) {
 		SignalSlot *slot = (SignalSlot *) me->signals->pdata [i];
 		if (slot->instance) {
@@ -796,6 +858,7 @@ tny_gtk_folder_list_store_instance_init (GTypeInstance *instance, gpointer g_cla
 	me->path_separator = g_strdup (DEFAULT_PATH_SEPARATOR);
 
 	me->progress_count = 0;
+	me->delayed_refresh_timeout_id = 0;
 
 	gtk_list_store_set_column_types (store, 
 		TNY_GTK_FOLDER_LIST_STORE_N_COLUMNS, types);
diff --git a/libtinymailui-gtk/tny-gtk-folder-list-store.h b/libtinymailui-gtk/tny-gtk-folder-list-store.h
index 28ecf9e..a8bac19 100644
--- a/libtinymailui-gtk/tny-gtk-folder-list-store.h
+++ b/libtinymailui-gtk/tny-gtk-folder-list-store.h
@@ -58,6 +58,7 @@ enum _TnyGtkFolderListStoreFlags
 {
 	TNY_GTK_FOLDER_LIST_STORE_FLAG_SHOW_PATH = 1<<0,
 	TNY_GTK_FOLDER_LIST_STORE_FLAG_NO_REFRESH = 1<<2,
+	TNY_GTK_FOLDER_LIST_STORE_FLAG_DELAYED_REFRESH = 1<<3,
 };
 
 typedef enum _TnyGtkFolderListStoreFlags TnyGtkFolderListStoreFlags;
@@ -74,6 +75,7 @@ struct _TnyGtkFolderListStore
 	TnyGtkFolderListStoreFlags flags;
 	gchar *path_separator;
 	gint progress_count;
+	guint delayed_refresh_timeout_id;
 };
 
 struct _TnyGtkFolderListStoreClass


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]