Added new create_folder_async API to folder store



Hi,

I'm attaching a patch that adds asynchronous creating of folders to the folder store API. Although the operation is not a heavy one, network delays can make it appear slow (for example with GMail IMAP).

Br
Index: libtinymail/tny-shared.h
===================================================================
--- libtinymail/tny-shared.h	(revision 3096)
+++ libtinymail/tny-shared.h	(working copy)
@@ -98,6 +98,7 @@
 typedef gchar* (*TnyGetPassFunc) (TnyAccount *self, const gchar *prompt, gboolean *cancel);
 typedef void (*TnyForgetPassFunc) (TnyAccount *self);
 typedef void (*TnyFolderCallback) (TnyFolder *self, gboolean canceled, GError *err, gpointer user_data);
+typedef void (*TnyCreateFolderCallback) (TnyFolderStore *self, gboolean canceled, TnyFolder *new_folder, GError *err, gpointer user_data);
 typedef void (*TnyMimePartCallback) (TnyMimePart *self, TnyStream *stream, gboolean canceled, GError *err, gpointer user_data);
 typedef void (*TnyGetHeadersCallback) (TnyFolder *self, gboolean canceled, TnyList *headers, GError *err, gpointer user_data);
 typedef void (*TnyGetMsgCallback) (TnyFolder *folder, gboolean canceled, TnyMsg *msg, GError *err, gpointer user_data);
Index: libtinymail/tny-folder-store.c
===================================================================
--- libtinymail/tny-folder-store.c	(revision 3096)
+++ libtinymail/tny-folder-store.c	(working copy)
@@ -191,6 +191,25 @@
 	return retval;
 }
 
+void 
+tny_folder_store_create_folder_async (TnyFolderStore *self, const gchar *name, TnyCreateFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+{
+#ifdef DBC /* require */
+	g_assert (TNY_IS_FOLDER_STORE (self));
+	g_assert (name);
+	g_assert (strlen (name) > 0);
+	g_assert (TNY_FOLDER_STORE_GET_IFACE (self)->create_folder_async_func != NULL);
+#endif
+
+	TNY_FOLDER_STORE_GET_IFACE (self)->create_folder_async_func (self, name, callback, status_callback, user_data);
+
+#ifdef DBC /* ensure */
+#endif
+
+	return;
+}
+
+
 /**
  * tny_folder_store_get_folders:
  * @self: a #TnyFolderStore object
Index: libtinymail/tny-folder-store.h
===================================================================
--- libtinymail/tny-folder-store.h	(revision 3096)
+++ libtinymail/tny-folder-store.h	(working copy)
@@ -47,6 +47,7 @@
 
    void (*remove_folder_func) (TnyFolderStore *self, TnyFolder *folder, GError **err);
    TnyFolder* (*create_folder_func) (TnyFolderStore *self, const gchar *name, GError **err);
+  void (*create_folder_async_func) (TnyFolderStore *self, const gchar *name, TnyCreateFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data);
    void (*get_folders_func) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err);
 	void (*get_folders_async_func) (TnyFolderStore *self, TnyList *list, TnyGetFoldersCallback callback, TnyFolderStoreQuery *query, TnyStatusCallback status_callback, gpointer user_data);
    void (*add_observer_func) (TnyFolderStore *self, TnyFolderStoreObserver *observer);
@@ -58,6 +59,7 @@
 
 void tny_folder_store_remove_folder (TnyFolderStore *self, TnyFolder *folder, GError **err);
 TnyFolder *tny_folder_store_create_folder (TnyFolderStore *self, const gchar *name, 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 (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err);
 void tny_folder_store_get_folders_async (TnyFolderStore *self, TnyList *list, TnyGetFoldersCallback callback, TnyFolderStoreQuery *query, TnyStatusCallback status_callback, gpointer user_data);
 void tny_folder_store_add_observer (TnyFolderStore *self, TnyFolderStoreObserver *observer);
Index: libtinymail-camel/tny-camel-folder.c
===================================================================
--- libtinymail-camel/tny-camel-folder.c	(revision 3096)
+++ libtinymail-camel/tny-camel-folder.c	(working copy)
@@ -4483,6 +4484,121 @@
 	return folder;
 }
 
+typedef struct 
+{
+	TnyCamelQueueable parent;
+
+	GError *err;
+	TnyFolderStore *self;
+	gchar *name;
+	TnyFolder *new_folder;
+	TnyCreateFolderCallback callback;
+	gpointer user_data;
+	TnySessionCamel *session;
+	gboolean cancelled;
+
+} CreateFolderInfo;
+
+static gpointer 
+tny_camel_folder_create_folder_async_thread (gpointer thr_user_data)
+{
+	CreateFolderInfo *info = (CreateFolderInfo*) thr_user_data;
+
+	info->new_folder = tny_camel_folder_create_folder (TNY_FOLDER_STORE (info->self), 
+							   (const gchar *) info->name, 
+							   &info->err);
+
+	info->cancelled = FALSE;
+	if (info->err != NULL) {
+		if (camel_strstrcase (info->err->message, "cancel") != NULL)
+			info->cancelled = TRUE;
+	}
+
+	return NULL;
+}
+
+static gboolean
+tny_camel_folder_create_folder_async_callback (gpointer thr_user_data)
+{
+	CreateFolderInfo *info = thr_user_data;
+	if (info->callback) {
+		tny_lockable_lock (info->session->priv->ui_lock);
+		info->callback (info->self, info->cancelled, info->new_folder, info->err, info->user_data);
+		tny_lockable_unlock (info->session->priv->ui_lock);
+	}
+	return FALSE;
+}
+
+static gboolean
+tny_camel_folder_create_folder_async_cancelled_callback (gpointer thr_user_data)
+{
+	CreateFolderInfo *info = thr_user_data;
+	if (info->callback) {
+		tny_lockable_lock (info->session->priv->ui_lock);
+		info->callback (info->self, TRUE, info->new_folder, info->err, info->user_data);
+		tny_lockable_unlock (info->session->priv->ui_lock);
+	}
+	return FALSE;
+}
+
+static void
+tny_camel_folder_create_folder_async_destroyer (gpointer thr_user_data)
+{
+	CreateFolderInfo *info = (CreateFolderInfo *) thr_user_data;
+	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self);
+
+	/* thread reference */
+	_tny_camel_folder_unreason (priv);
+	g_object_unref (info->self);
+	g_free (info->name);
+
+	if (info->err)
+		g_error_free (info->err);
+
+	_tny_session_stop_operation (info->session);
+
+	return;
+}
+
+static void
+tny_camel_folder_create_folder_async (TnyFolderStore *self, const gchar *name, TnyCreateFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+{
+	return TNY_CAMEL_FOLDER_GET_CLASS (self)->create_folder_async_func (self, name, callback, status_callback, user_data);
+}
+
+static void
+tny_camel_folder_create_folder_async_default (TnyFolderStore *self, const gchar *name, TnyCreateFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+{
+	CreateFolderInfo *info;
+	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
+
+	/* Idle info for the callbacks */
+	info = g_slice_new (CreateFolderInfo);
+	info->session = TNY_FOLDER_PRIV_GET_SESSION (priv);
+	info->self = self;
+	info->name = g_strdup (name);
+	info->callback = callback;
+	info->user_data = user_data;
+	info->new_folder = NULL;
+	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_create_folder_async_thread, 
+		tny_camel_folder_create_folder_async_callback,
+		tny_camel_folder_create_folder_async_destroyer, 
+		tny_camel_folder_create_folder_async_cancelled_callback,
+		tny_camel_folder_create_folder_async_destroyer, 
+		&info->cancelled, 
+		info, sizeof (CreateFolderInfo),
+		__FUNCTION__);
+
+	return;
+}
+
 /* Sets a TnyFolderStore as the parent of a TnyCamelFolder. Note that
  * this code could cause a cross-reference situation, if the parent
  * was used to create the child. */
@@ -5382,6 +5498,7 @@
 
 	klass->remove_folder_func = tny_camel_folder_remove_folder;
 	klass->create_folder_func = tny_camel_folder_create_folder;
+	klass->create_folder_async_func = tny_camel_folder_create_folder_async;
 	klass->get_folders_func = tny_camel_folder_get_folders;
 	klass->get_folders_async_func = tny_camel_folder_get_folders_async;
 	klass->add_observer_func = tny_camel_folder_store_add_observer;
@@ -5439,6 +5556,7 @@
 	class->get_folders_async_func = tny_camel_folder_get_folders_async_default;
 	class->get_folders_func = tny_camel_folder_get_folders_default;
 	class->create_folder_func = tny_camel_folder_create_folder_default;
+	class->create_folder_async_func = tny_camel_folder_create_folder_async_default;
 	class->remove_folder_func = tny_camel_folder_remove_folder_default;
 	class->add_store_observer_func = tny_camel_folder_store_add_observer_default;
 	class->remove_store_observer_func = tny_camel_folder_store_remove_observer_default;
Index: libtinymail-camel/tny-camel-folder.h
===================================================================
--- libtinymail-camel/tny-camel-folder.h	(revision 3096)
+++ libtinymail-camel/tny-camel-folder.h	(working copy)
@@ -94,6 +94,7 @@
 	void (*get_folders_func) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err);
 	void (*remove_folder_func) (TnyFolderStore *self, TnyFolder *folder, GError **err);
 	TnyFolder* (*create_folder_func) (TnyFolderStore *self, const gchar *name, GError **err);
+	void (*create_folder_async_func) (TnyFolderStore *self, const gchar *name, TnyCreateFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data);
 	TnyFolderStore* (*get_folder_store_func) (TnyFolder *self);
 	void (*add_store_observer_func) (TnyFolderStore *self, TnyFolderStoreObserver *observer);
 	void (*remove_store_observer_func) (TnyFolderStore *self, TnyFolderStoreObserver *observer);


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