[nautilus-sendto] Make ->send_files asynchronous



commit 9a4f539d3d34a4789c479ff475dfbf52c09c79fd
Author: Bastien Nocera <hadess hadess net>
Date:   Mon Aug 23 16:38:21 2010 +0100

    Make ->send_files asynchronous
    
    So that the UI is not blocked, and progress reports can be made
    from within the plugin itself.

 src/nautilus-sendto-command.c                     |   29 ++++++++++--
 src/plugins/evolution/evolution.c                 |   20 +++++++-
 src/plugins/nautilus-sendto-plugin.c              |   51 +++++++++++++++++----
 src/plugins/nautilus-sendto-plugin.h              |   21 +++++---
 src/plugins/removable-devices/removable-devices.c |   26 +++++++++--
 5 files changed, 117 insertions(+), 30 deletions(-)
---
diff --git a/src/nautilus-sendto-command.c b/src/nautilus-sendto-command.c
index b59b4a3..adc44e0 100644
--- a/src/nautilus-sendto-command.c
+++ b/src/nautilus-sendto-command.c
@@ -97,6 +97,30 @@ make_sensitive_for_send (NS_ui *ui,
 }
 
 static void
+send_callback (GObject      *object,
+	       GAsyncResult *res,
+	       gpointer      user_data)
+{
+	NS_ui *ui = (NS_ui *) user_data;
+	NautilusSendtoSendStatus status;
+
+	status = nautilus_sendto_plugin_send_files_finish (NAUTILUS_SENDTO_PLUGIN (object),
+							   res, NULL);
+
+	g_message ("send_callback %d", status);
+
+	if (status == NST_SEND_STATUS_SUCCESS_DONE) {
+		destroy_dialog (NULL, NULL);
+	} else if (status == NST_SEND_STATUS_SUCCESS) {
+		//FIXME make the buttons into a single close button
+	} else if (status == NST_SEND_STATUS_FAILED) {
+		/* Do nothing, the plugin should report an error */
+	} else {
+		g_assert_not_reached ();
+	}
+}
+
+static void
 send_button_cb (GtkWidget *widget, NS_ui *ui)
 {
 	GtkTreeModel *model;
@@ -105,7 +129,6 @@ send_button_cb (GtkWidget *widget, NS_ui *ui)
 	char *id;
 	PeasPluginInfo *info;
 	PeasExtension *ext;
-	NautilusSendtoSendStatus status;
 
 	treeselection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ui->options_treeview));
 	if (gtk_tree_selection_get_selected (treeselection, &model, &iter) == FALSE)
@@ -124,8 +147,7 @@ send_button_cb (GtkWidget *widget, NS_ui *ui)
 	info = peas_engine_get_plugin_info (engine, id);
 	ext = peas_extension_set_get_extension (exten_set, info);
 
-	if (peas_extension_call (ext, "send_files", file_list, &status) == FALSE ||
-	    status != NST_SEND_STATUS_SUCCESS) {
+	if (peas_extension_call (ext, "send_files", file_list, send_callback, ui) == FALSE) {
 		/* FIXME report the error in the UI */
 		g_warning ("Failed to send files");
 		make_sensitive_for_send (ui, TRUE);
@@ -134,7 +156,6 @@ send_button_cb (GtkWidget *widget, NS_ui *ui)
 	}
 
 	g_free (id);
-	destroy_dialog (NULL,NULL);
 }
 
 static void
diff --git a/src/plugins/evolution/evolution.c b/src/plugins/evolution/evolution.c
index 83b74b6..0b30567 100644
--- a/src/plugins/evolution/evolution.c
+++ b/src/plugins/evolution/evolution.c
@@ -413,14 +413,17 @@ get_sylpheed_mailto (EvolutionPlugin *p,
 	}
 }
 
-static NautilusSendtoSendStatus
+static void
 evolution_plugin_send_files (NautilusSendtoPlugin *plugin,
-			     GList                *file_list)
+			     GList                *file_list,
+			     GAsyncReadyCallback   callback,
+			     gpointer              user_data)
 {
 	EvolutionPlugin *p;
 	gchar *cmd;
 	GString *mailto;
 	GList *packed;
+	GSimpleAsyncResult *simple;
 
 	p = EVOLUTION_PLUGIN (plugin);
 
@@ -428,10 +431,16 @@ evolution_plugin_send_files (NautilusSendtoPlugin *plugin,
 	if (nst_pack_widget_get_enabled (NST_PACK_WIDGET (p->packer))) {
 		char *filename;
 
+		/* FIXME: this should be async */
 		filename = nst_pack_widget_pack_files (NST_PACK_WIDGET (p->packer), file_list);
 		packed = g_list_append (packed, filename);
 	}
 
+	simple = g_simple_async_result_new (G_OBJECT (plugin),
+					    callback,
+					    user_data,
+					    nautilus_sendto_plugin_send_files);
+
 	mailto = g_string_new ("");
 	switch (p->type) {
 	case MAILER_BALSA:
@@ -459,10 +468,15 @@ evolution_plugin_send_files (NautilusSendtoPlugin *plugin,
 	g_message ("Mailer type: %d", p->type);
 	g_message ("Command: %s", cmd);
 
+	/* FIXME: collect errors from this call */
 	g_spawn_command_line_async (cmd, NULL);
 	g_free (cmd);
 
-	return NST_SEND_STATUS_SUCCESS;
+	g_simple_async_result_set_op_res_gpointer (simple,
+						   GINT_TO_POINTER (NST_SEND_STATUS_SUCCESS_DONE),
+						   NULL);
+	g_simple_async_result_complete_in_idle (simple);
+	g_object_unref (simple);
 }
 
 static void
diff --git a/src/plugins/nautilus-sendto-plugin.c b/src/plugins/nautilus-sendto-plugin.c
index a2b85b7..6fc41e8 100644
--- a/src/plugins/nautilus-sendto-plugin.c
+++ b/src/plugins/nautilus-sendto-plugin.c
@@ -89,25 +89,56 @@ nautilus_sendto_plugin_supports_mime_types (NautilusSendtoPlugin  *plugin,
  * nautilus_sendto_plugin_send_files:
  * @plugin: a #NautilusSendtoPlugin instance
  * @file_list: (element-type utf8): a #GList of strings representing the files to send
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
  *
- * Returns a #NautilusSendtoSendStatus representing failure or success
- *
- * Return value: %NST_SEND_STATUS_SUCCESS on success,
- * %NST_SEND_STATUS_IN_PROGRESS if the send will take a while,
- * %NST_SEND_STATUS_FAILED if it failed.
+ * Sends the list of files in @file_list, and calls the @callback
+ * when done. You should then call nautilus_sendto_plugin_send_files_finish().
  */
-NautilusSendtoSendStatus
+void
 nautilus_sendto_plugin_send_files (NautilusSendtoPlugin *plugin,
-				   GList                *file_list)
+				   GList                *file_list,
+				   GAsyncReadyCallback   callback,
+				   gpointer              user_data)
 {
 	NautilusSendtoPluginInterface *iface;
 
-	g_return_val_if_fail (NAUTILUS_SENDTO_IS_PLUGIN (plugin), FALSE);
+	g_return_if_fail (NAUTILUS_SENDTO_IS_PLUGIN (plugin));
 
 	iface = NAUTILUS_SENDTO_PLUGIN_GET_IFACE (plugin);
 
 	if (G_LIKELY (iface->send_files != NULL))
-		return iface->send_files (plugin, file_list);
+		iface->send_files (plugin, file_list, callback, user_data);
+}
+
+/**
+ * nautilus_sendto_plugin_send_files_finish:
+ * @plugin: a #NautilusSendtoPlugin instance
+ * @res: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Returns: the #NautilusSendtoSendStatus representing the
+ * result of the operation.
+ */
+NautilusSendtoSendStatus
+nautilus_sendto_plugin_send_files_finish (NautilusSendtoPlugin *plugin,
+					  GAsyncResult         *res,
+					  GError              **error)
+{
+	GSimpleAsyncResult *simple;
+	NautilusSendtoSendStatus status;
+
+	g_return_val_if_fail (g_simple_async_result_is_valid (res,
+							      G_OBJECT (plugin),
+							      nautilus_sendto_plugin_send_files),
+			      NST_SEND_STATUS_FAILED);
 
-	return NST_SEND_STATUS_FAILED;
+	simple = (GSimpleAsyncResult *) res;
+
+	if (g_simple_async_result_propagate_error (simple, error))
+		return NST_SEND_STATUS_FAILED;
+
+	status = GPOINTER_TO_INT (g_simple_async_result_get_op_res_gpointer (simple));
+
+	return status;
 }
+
diff --git a/src/plugins/nautilus-sendto-plugin.h b/src/plugins/nautilus-sendto-plugin.h
index 8300fe0..9f9c1e9 100644
--- a/src/plugins/nautilus-sendto-plugin.h
+++ b/src/plugins/nautilus-sendto-plugin.h
@@ -38,7 +38,7 @@ typedef struct _NautilusSendtoPluginInterface  NautilusSendtoPluginInterface;
 
 typedef enum {
 	NST_SEND_STATUS_SUCCESS,
-	NST_SEND_STATUS_IN_PROGRESS,
+	NST_SEND_STATUS_SUCCESS_DONE,
 	NST_SEND_STATUS_FAILED
 } NautilusSendtoSendStatus;
 
@@ -48,9 +48,10 @@ struct _NautilusSendtoPluginInterface
 
 	gboolean    (*supports_mime_types) (NautilusSendtoPlugin *plugin,
 					    const char          **mime_types);
-	NautilusSendtoSendStatus
-		    (*send_files)  (NautilusSendtoPlugin *plugin,
-				    GList                *file_list);
+	void	    (*send_files)  (NautilusSendtoPlugin *plugin,
+				    GList                *file_list,
+				    GAsyncReadyCallback   callback,
+				    gpointer              user_data);
 	GtkWidget  *(*get_widget)  (NautilusSendtoPlugin *plugin,
 				    GList                *file_list);
 };
@@ -60,15 +61,19 @@ GtkWidget  *nautilus_sendto_plugin_get_widget (NautilusSendtoPlugin  *plugin,
 					       GList                 *file_list);
 gboolean    nautilus_sendto_plugin_supports_mime_types (NautilusSendtoPlugin *plugin,
 							const char          **mime_types);
-NautilusSendtoSendStatus
-	    nautilus_sendto_plugin_send_files (NautilusSendtoPlugin *plugin,
-					       GList                *file_list);
+void        nautilus_sendto_plugin_send_files (NautilusSendtoPlugin *plugin,
+					       GList                *file_list,
+					       GAsyncReadyCallback   callback,
+					       gpointer              user_data);
+NautilusSendtoSendStatus nautilus_sendto_plugin_send_files_finish (NautilusSendtoPlugin *plugin,
+								   GAsyncResult         *res,
+								   GError              **error);
 
 #define NAUTILUS_PLUGIN_REGISTER(TYPE_NAME, TypeName, type_name)					\
 	GType type_name##_get_type (void) G_GNUC_CONST;							\
 	G_MODULE_EXPORT void  peas_register_types (PeasObjectModule *module);				\
 	static GtkWidget *type_name##_get_widget (NautilusSendtoPlugin *plugin, GList *file_list);	\
-	static NautilusSendtoSendStatus type_name##_send_files (NautilusSendtoPlugin *plugin, GList *file_list); \
+	static void type_name##_send_files (NautilusSendtoPlugin *plugin, GList *file_list, GAsyncReadyCallback callback, gpointer user_data); \
 	static gboolean type_name##_supports_mime_types (NautilusSendtoPlugin *plugin, const char **mime_types); \
 	static void nautilus_sendto_plugin_iface_init (NautilusSendtoPluginInterface *iface);		\
 	static void type_name##_finalize (GObject *object);						\
diff --git a/src/plugins/removable-devices/removable-devices.c b/src/plugins/removable-devices/removable-devices.c
index 01723fa..0f0f13d 100644
--- a/src/plugins/removable-devices/removable-devices.c
+++ b/src/plugins/removable-devices/removable-devices.c
@@ -161,28 +161,44 @@ cb_mount_added (GVolumeMonitor         *volume_monitor,
 
 }
 
-static NautilusSendtoSendStatus
+static void
 removable_devices_plugin_send_files (NautilusSendtoPlugin *plugin,
-				     GList                *file_list)
+				     GList                *file_list,
+				     GAsyncReadyCallback   callback,
+				     gpointer              user_data)
 {
 	RemovableDevicesPlugin *p = REMOVABLE_DEVICES_PLUGIN (plugin);
 	GtkListStore *store;
 	GtkTreeIter iter;
 	GMount *dest_mount;
 	GFile *mount_root;
+	GSimpleAsyncResult *simple;
 
-	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (p->cb), &iter) == FALSE)
-		return TRUE;
+	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (p->cb), &iter) == FALSE) {
+		/* FIXME: This should not happen */
+		g_assert_not_reached ();
+		return;
+	}
 
 	store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (p->cb)));
 	gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, MOUNT_COL, &dest_mount, -1);
 	mount_root = g_mount_get_root (dest_mount);
 
+	simple = g_simple_async_result_new (G_OBJECT (plugin),
+					    callback,
+					    user_data,
+					    nautilus_sendto_plugin_send_files);
+
 	copy_files_to (file_list, mount_root);
 
 	g_object_unref (mount_root);
 
-	return NST_SEND_STATUS_SUCCESS;
+	/* FIXME: Report errors properly */
+	g_simple_async_result_set_op_res_gpointer (simple,
+						   GINT_TO_POINTER (NST_SEND_STATUS_SUCCESS_DONE),
+						   NULL);
+	g_simple_async_result_complete_in_idle (simple);
+	g_object_unref (simple);
 }
 
 static gboolean



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