[rhythmbox] removable-media: convert can_eject and eject into vmethods



commit 4c0b134f57ad6bbbb13933632379b56cf72f201f
Author: Jonathan Matthew <jonathan d14n org>
Date:   Fri May 21 17:49:34 2010 +1000

    removable-media: convert can_eject and eject into vmethods
    
    This allows a source to determine how to eject itself, and to prompt the
    user if a track transfer or sync operation is in progress.

 shell/rb-removable-media-manager.c  |  143 +------------------------------
 sources/rb-removable-media-source.c |  159 +++++++++++++++++++++++++++++++++++
 sources/rb-removable-media-source.h |    5 +
 3 files changed, 169 insertions(+), 138 deletions(-)
---
diff --git a/shell/rb-removable-media-manager.c b/shell/rb-removable-media-manager.c
index 134afe2..14ae616 100644
--- a/shell/rb-removable-media-manager.c
+++ b/shell/rb-removable-media-manager.c
@@ -61,17 +61,6 @@
 #include "rb-util.h"
 #include "rb-encoder.h"
 
-#if !GLIB_CHECK_VERSION(2,22,0)
-#define g_mount_unmount_with_operation_finish g_mount_unmount_finish
-#define g_mount_unmount_with_operation(m,f,mo,ca,cb,ud) g_mount_unmount(m,f,ca,cb,ud)
-
-#define g_mount_eject_with_operation_finish g_mount_eject_finish
-#define g_mount_eject_with_operation(m,f,mo,ca,cb,ud) g_mount_eject(m,f,ca,cb,ud)
-
-#define g_volume_eject_with_operation_finish g_volume_eject_finish
-#define g_volume_eject_with_operation(v,f,mo,ca,cb,ud) g_volume_eject(v,f,ca,cb,ud)
-#endif
-
 static void rb_removable_media_manager_class_init (RBRemovableMediaManagerClass *klass);
 static void rb_removable_media_manager_init (RBRemovableMediaManager *mgr);
 static void rb_removable_media_manager_dispose (GObject *object);
@@ -852,152 +841,30 @@ rb_removable_media_manager_set_uimanager (RBRemovableMediaManager *mgr,
 					    0);
 }
 
-static void
-rb_removable_media_manager_eject_cb (GObject *object,
-				     GAsyncResult *result,
-				     RBRemovableMediaManager *mgr)
-{
-	GError *error = NULL;
-
-	if (G_IS_VOLUME (object)) {
-		GVolume *volume = G_VOLUME (object);
-
-		rb_debug ("finishing ejection of volume");
-		g_volume_eject_with_operation_finish (volume, result, &error);
-		if (error == NULL) {
-			rb_removable_media_manager_remove_volume (mgr, volume);
-		}
-	} else if (G_IS_MOUNT (object)) {
-		GMount *mount = G_MOUNT (object);
-
-		rb_debug ("finishing ejection of mount");
-		g_mount_eject_with_operation_finish (mount, result, &error);
-		if (error == NULL) {
-			rb_removable_media_manager_remove_mount (mgr, mount);
-		}
-	}
-
-	if (error != NULL) {
-		if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED)) {
-			rb_error_dialog (NULL, _("Unable to eject"), "%s", error->message);
-		} else {
-			rb_debug ("eject failure has already been handled");
-		}
-		g_error_free (error);
-	}
-	g_object_unref (mgr);
-}
-
-static void
-rb_removable_media_manager_unmount_cb (GObject *object,
-				       GAsyncResult *result,
-				       RBRemovableMediaManager *mgr)
-{
-	GMount *mount = G_MOUNT (object);
-	GError *error = NULL;
-
-	rb_debug ("finishing unmount of mount");
-	g_mount_unmount_with_operation_finish (mount, result, &error);
-	if (error != NULL) {
-		if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED)) {
-			rb_error_dialog (NULL, _("Unable to unmount"), "%s", error->message);
-		} else {
-			rb_debug ("unmount failure has already been handled");
-		}
-		g_error_free (error);
-	} else {
-		rb_removable_media_manager_remove_mount (mgr, mount);
-	}
-	g_object_unref (mgr);
-}
-
 static gboolean
 rb_removable_media_manager_source_can_eject (RBRemovableMediaManager *mgr)
 {
 	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
-	GVolume *volume;
-	GMount *mount;
-	gboolean result;
 
 	if (RB_IS_REMOVABLE_MEDIA_SOURCE (priv->selected_source) == FALSE) {
 		return FALSE;
 	}
 
-	g_object_get (priv->selected_source, "volume", &volume, NULL);
-	if (volume != NULL) {
-		result = g_volume_can_eject (volume);
-		g_object_unref (volume);
-		return result;
-	}
-
-	g_object_get (priv->selected_source, "mount", &mount, NULL);
-	if (mount != NULL) {
-		result = g_mount_can_eject (mount) || g_mount_can_unmount (mount);
-		g_object_unref (mount);
-		return result;
-	}
-
-	return FALSE;
+	return rb_removable_media_source_can_eject (RB_REMOVABLE_MEDIA_SOURCE (priv->selected_source));
 }
 
 static void
 rb_removable_media_manager_cmd_eject_medium (GtkAction *action, RBRemovableMediaManager *mgr)
 {
 	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
-	RBRemovableMediaSource *source = RB_REMOVABLE_MEDIA_SOURCE (priv->selected_source);
-	GVolume *volume;
-	GMount *mount;
-
-	/* try ejecting based on volume first, then based on the mount,
-	 * and finally try unmounting.
-	 */
+	RBRemovableMediaSource *source;
 
-	g_object_get (source, "volume", &volume, NULL);
-	if (volume != NULL) {
-		if (g_volume_can_eject (volume)) {
-			rb_debug ("ejecting volume");
-			g_volume_eject_with_operation (volume,
-						       G_MOUNT_UNMOUNT_NONE,
-						       NULL,
-						       NULL,
-						       (GAsyncReadyCallback) rb_removable_media_manager_eject_cb,
-						       g_object_ref (mgr));
-		} else {
-			/* this should never happen; the eject command will be
-			 * insensitive if the selected source cannot be ejected.
-			 */
-			rb_debug ("don't know what to do with this volume");
-		}
-		g_object_unref (volume);
+	if (RB_IS_REMOVABLE_MEDIA_SOURCE (priv->selected_source) == FALSE) {
 		return;
 	}
 
-	g_object_get (source, "mount", &mount, NULL);
-	if (mount != NULL) {
-		if (g_mount_can_eject (mount)) {
-			rb_debug ("ejecting mount");
-			g_mount_eject_with_operation (mount,
-						      G_MOUNT_UNMOUNT_NONE,
-						      NULL,
-						      NULL,
-						      (GAsyncReadyCallback) rb_removable_media_manager_eject_cb,
-						      g_object_ref (mgr));
-		} else if (g_mount_can_unmount (mount)) {
-			rb_debug ("unmounting mount");
-			g_mount_unmount_with_operation (mount,
-							G_MOUNT_UNMOUNT_NONE,
-							NULL,
-							NULL,
-							(GAsyncReadyCallback) rb_removable_media_manager_unmount_cb,
-							g_object_ref (mgr));
-		} else {
-			/* this should never happen; the eject command will be
-			 * insensitive if the selected source cannot be ejected.
-			 */
-			rb_debug ("don't know what to do with this mount");
-		}
-		g_object_unref (mount);
-	}
+	source = RB_REMOVABLE_MEDIA_SOURCE (priv->selected_source);
+	rb_removable_media_source_eject (source);
 }
 
 static void
diff --git a/sources/rb-removable-media-source.c b/sources/rb-removable-media-source.c
index 1096b8a..7b32334 100644
--- a/sources/rb-removable-media-source.c
+++ b/sources/rb-removable-media-source.c
@@ -55,6 +55,18 @@
 #include "rb-util.h"
 #include "rb-file-helpers.h"
 
+#if !GLIB_CHECK_VERSION(2,22,0)
+#define g_mount_unmount_with_operation_finish g_mount_unmount_finish
+#define g_mount_unmount_with_operation(m,f,mo,ca,cb,ud) g_mount_unmount(m,f,ca,cb,ud)
+
+#define g_mount_eject_with_operation_finish g_mount_eject_finish
+#define g_mount_eject_with_operation(m,f,mo,ca,cb,ud) g_mount_eject(m,f,ca,cb,ud)
+
+#define g_volume_eject_with_operation_finish g_volume_eject_finish
+#define g_volume_eject_with_operation(v,f,mo,ca,cb,ud) g_volume_eject(v,f,ca,cb,ud)
+#endif
+
+
 /* arbitrary length limit for file extensions */
 #define EXTENSION_LENGTH_LIMIT	8
 
@@ -78,6 +90,8 @@ static gboolean impl_should_paste (RBRemovableMediaSource *source,
 static guint impl_want_uri (RBSource *source, const char *uri);
 static gboolean impl_uri_is_source (RBSource *source, const char *uri);
 static char *impl_get_delete_action (RBSource *source);
+static gboolean default_can_eject (RBRemovableMediaSource *source);
+static void default_eject (RBRemovableMediaSource *source);
 
 typedef struct
 {
@@ -126,6 +140,8 @@ rb_removable_media_source_class_init (RBRemovableMediaSourceClass *klass)
 	browser_source_class->impl_has_drop_support = (RBBrowserSourceFeatureFunc) rb_false_function;
 
 	klass->impl_should_paste = impl_should_paste;
+	klass->impl_can_eject = default_can_eject;
+	klass->impl_eject = default_eject;
 
 	/**
 	 * RBRemovableMediaSource:volume
@@ -901,3 +917,146 @@ impl_get_delete_action (RBSource *source)
 {
 	return g_strdup ("EditDelete");
 }
+
+static gboolean
+default_can_eject (RBRemovableMediaSource *source)
+{
+	RBRemovableMediaSourcePrivate *priv = REMOVABLE_MEDIA_SOURCE_GET_PRIVATE (source);
+	gboolean result;
+
+	if (priv->volume != NULL) {
+		result = g_volume_can_eject (priv->volume);
+		return result;
+	}
+
+	if (priv->mount != NULL) {
+		result = g_mount_can_eject (priv->mount) || g_mount_can_unmount (priv->mount);
+		return result;
+	}
+
+	return FALSE;
+}
+
+static void
+eject_cb (GObject *object,
+	  GAsyncResult *result,
+	  gpointer nothing)
+{
+	GError *error = NULL;
+
+	if (G_IS_VOLUME (object)) {
+		GVolume *volume = G_VOLUME (object);
+
+		rb_debug ("finishing ejection of volume");
+		g_volume_eject_with_operation_finish (volume, result, &error);
+	} else if (G_IS_MOUNT (object)) {
+		GMount *mount = G_MOUNT (object);
+
+		rb_debug ("finishing ejection of mount");
+		g_mount_eject_with_operation_finish (mount, result, &error);
+	}
+
+	if (error != NULL) {
+		if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED)) {
+			rb_error_dialog (NULL, _("Unable to eject"), "%s", error->message);
+		} else {
+			rb_debug ("eject failure has already been handled");
+		}
+		g_error_free (error);
+	}
+}
+
+static void
+unmount_cb (GObject *object, GAsyncResult *result, gpointer nothing)
+{
+	GMount *mount = G_MOUNT (object);
+	GError *error = NULL;
+
+	rb_debug ("finishing unmount of mount");
+	g_mount_unmount_with_operation_finish (mount, result, &error);
+	if (error != NULL) {
+		if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED)) {
+			rb_error_dialog (NULL, _("Unable to unmount"), "%s", error->message);
+		} else {
+			rb_debug ("unmount failure has already been handled");
+		}
+		g_error_free (error);
+	}
+}
+
+static void
+default_eject (RBRemovableMediaSource *source)
+{
+	RBRemovableMediaSourcePrivate *priv = REMOVABLE_MEDIA_SOURCE_GET_PRIVATE (source);
+
+	/* try ejecting based on volume first, then based on the mount,
+	 * and finally try unmounting.
+	 */
+	if (priv->volume != NULL) {
+		if (g_volume_can_eject (priv->volume)) {
+			rb_debug ("ejecting volume");
+			g_volume_eject_with_operation (priv->volume,
+						       G_MOUNT_UNMOUNT_NONE,
+						       NULL,
+						       NULL,
+						       (GAsyncReadyCallback) eject_cb,
+						       NULL);
+		} else {
+			/* this should never happen; the eject command will be
+			 * insensitive if the selected source cannot be ejected.
+			 */
+			rb_debug ("don't know what to do with this volume");
+		}
+	} else if (priv->mount != NULL) {
+		if (g_mount_can_eject (priv->mount)) {
+			rb_debug ("ejecting mount");
+			g_mount_eject_with_operation (priv->mount,
+						      G_MOUNT_UNMOUNT_NONE,
+						      NULL,
+						      NULL,
+						      (GAsyncReadyCallback) eject_cb,
+						      NULL);
+		} else if (g_mount_can_unmount (priv->mount)) {
+			rb_debug ("unmounting mount");
+			g_mount_unmount_with_operation (priv->mount,
+							G_MOUNT_UNMOUNT_NONE,
+							NULL,
+							NULL,
+							(GAsyncReadyCallback) unmount_cb,
+							NULL);
+		} else {
+			/* this should never happen; the eject command will be
+			 * insensitive if the selected source cannot be ejected.
+			 */
+			rb_debug ("don't know what to do with this mount");
+		}
+	}
+}
+
+/**
+ * rb_removable_media_source_can_eject:
+ * @source: a #RBRemovableMediaSource
+ *
+ * Checks if @source can be ejected.
+ *
+ * Return value: %TRUE if @source can be ejected
+ */
+gboolean
+rb_removable_media_source_can_eject (RBRemovableMediaSource *source)
+{
+	RBRemovableMediaSourceClass *klass = RB_REMOVABLE_MEDIA_SOURCE_GET_CLASS (source);
+	return klass->impl_can_eject (source);
+}
+
+/**
+ * rb_removable_media_source_eject:
+ * @source: a #RBRemovableMediaSource
+ *
+ * Attemsts to eject the media or device represented by @source.
+ */
+void
+rb_removable_media_source_eject (RBRemovableMediaSource *source)
+{
+	RBRemovableMediaSourceClass *klass = RB_REMOVABLE_MEDIA_SOURCE_GET_CLASS (source);
+	klass->impl_eject (source);
+}
diff --git a/sources/rb-removable-media-source.h b/sources/rb-removable-media-source.h
index 4f7670b..eed9b17 100644
--- a/sources/rb-removable-media-source.h
+++ b/sources/rb-removable-media-source.h
@@ -69,6 +69,8 @@ struct _RBRemovableMediaSourceClass
 						 GError *error);
 	gboolean	(*impl_should_paste)	(RBRemovableMediaSource *source,
 						 RhythmDBEntry *entry);
+	gboolean	(*impl_can_eject)	(RBRemovableMediaSource *source);
+	void		(*impl_eject)		(RBRemovableMediaSource *source);		/* return error? */
 };
 
 typedef gboolean	(*RBRemovableMediaSourceShouldPasteFunc) (RBRemovableMediaSource *source,
@@ -96,6 +98,9 @@ gboolean	rb_removable_media_source_should_paste		(RBRemovableMediaSource *source
 gboolean        rb_removable_media_source_should_paste_no_duplicate (RBRemovableMediaSource *source,
 								     RhythmDBEntry *entry);
 
+gboolean	rb_removable_media_source_can_eject		(RBRemovableMediaSource *source);
+void		rb_removable_media_source_eject			(RBRemovableMediaSource *source);
+
 G_END_DECLS
 
 #endif /* __RB_REMOVABLE_MEDIA_SOURCE_H */



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