[rhythmbox] rework missing-plugin helper to use direct function calls, not signals



commit cd98d3aa4fcdc59d554586b5346b99370894efe0
Author: Jonathan Matthew <jonathan d14n org>
Date:   Thu Jun 24 22:27:41 2010 +1000

    rework missing-plugin helper to use direct function calls, not signals
    
    Now it gets initialized with a GtkWindow on startup, but after that it can
    be called directly from anywhere with just a list of plugin details and
    a closure to call on completion.  This simplifies using it in import jobs,
    and allows us to trigger plugin installation from the import error source.

 lib/Makefile.am                                   |    4 +-
 {shell => lib}/rb-missing-plugins.c               |   85 +++++----------------
 {shell => lib}/rb-missing-plugins.h               |    5 +-
 plugins/generic-player/rb-generic-player-source.c |    4 -
 podcast/rb-podcast-manager.c                      |   16 +---
 rhythmdb/rhythmdb-import-job.c                    |   28 +------
 shell/Makefile.am                                 |    2 -
 shell/rb-shell-player.c                           |   28 +------
 shell/rb-shell.c                                  |    2 +-
 sources/rb-library-source.c                       |    5 -
 10 files changed, 32 insertions(+), 147 deletions(-)
---
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 0cd73da..6d787ff 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -44,7 +44,9 @@ librb_la_SOURCES =					\
 	rb-async-queue-watch.c				\
 	rb-async-queue-watch.h				\
 	rb-text-helpers.c				\
-	rb-text-helpers.h
+	rb-text-helpers.h				\
+	rb-missing-plugins.c				\
+	rb-missing-plugins.h
 
 INCLUDES =						\
 	-DGNOMELOCALEDIR=\""$(datadir)/locale"\"        \
diff --git a/shell/rb-missing-plugins.c b/lib/rb-missing-plugins.c
similarity index 82%
rename from shell/rb-missing-plugins.c
rename to lib/rb-missing-plugins.c
index 0ec0ff7..c273d1b 100644
--- a/shell/rb-missing-plugins.c
+++ b/lib/rb-missing-plugins.c
@@ -25,10 +25,7 @@
 
 #include "rb-missing-plugins.h"
 
-#include "rhythmdb.h"
-#include "rb-shell-player.h"
 #include "rb-debug.h"
-#include "rb-podcast-manager.h"
 #include "gseal-gtk-compat.h"
 
 #include <gst/pbutils/pbutils.h>
@@ -47,11 +44,13 @@
 /* list of blacklisted detail strings */
 static GList *blacklisted_plugins = NULL;
 
+/* parent window for installer */
+static gpointer parent_window = NULL;
+
 typedef struct
 {
 	GClosure   *closure;
 	gchar     **details;
-	RBShell    *shell;
 } RBPluginInstallContext;
 
 static gboolean
@@ -80,7 +79,6 @@ rb_plugin_install_context_free (RBPluginInstallContext *ctx)
 {
 	rb_debug ("cleaning up plugin install context %p", ctx);
 	g_strfreev (ctx->details);
-	g_object_unref (ctx->shell);
 	g_closure_unref (ctx->closure);
 	g_free (ctx);
 }
@@ -178,17 +176,24 @@ on_plugin_installation_done (GstInstallPluginsReturn res, gpointer user_data)
 	rb_plugin_install_context_free (ctx);
 }
 
-static gboolean
-missing_plugins_event (RBShell *shell, RBPluginInstallContext *ctx)
+gboolean
+rb_missing_plugins_install (const char **details, gboolean ignore_blacklist, GClosure *closure)
 {
+	RBPluginInstallContext *ctx;
 	GstInstallPluginsContext *install_ctx;
 	GstInstallPluginsReturn status;
 	int i, num;
-	GtkWindow *window;
+
+	num = g_strv_length ((char **)details);
+	g_return_val_if_fail (num > 0, FALSE);
+
+	ctx = g_new0 (RBPluginInstallContext, 1);
+	ctx->closure = g_closure_ref (closure);
+	ctx->details = g_strdupv ((char **)details);
 
 	num = g_strv_length (ctx->details);
 	for (i = 0; i < num; ++i) {
-		if (rb_plugin_install_plugin_is_blacklisted (ctx->details[i])) {
+		if (ignore_blacklist == FALSE && rb_plugin_install_plugin_is_blacklisted (ctx->details[i])) {
 			g_message ("Missing plugin: %s (ignoring)", ctx->details[i]);
 			g_free (ctx->details[i]);
 			ctx->details[i] = ctx->details[num-1];
@@ -208,14 +213,12 @@ missing_plugins_event (RBShell *shell, RBPluginInstallContext *ctx)
 
 	install_ctx = gst_install_plugins_context_new ();
 
-	g_object_get (shell, "window", &window, NULL);
-	if (gtk_widget_get_realized (GTK_WIDGET (window))) {
+	if (parent_window != NULL && gtk_widget_get_realized (GTK_WIDGET (parent_window))) {
 #ifdef GDK_WINDOWING_X11
 		gulong xid = 0;
-		xid = gdk_x11_drawable_get_xid (gtk_widget_get_window (GTK_WIDGET (window)));
+		xid = gdk_x11_drawable_get_xid (gtk_widget_get_window (GTK_WIDGET (parent_window)));
 		gst_install_plugins_context_set_xid (install_ctx, xid);
 #endif
-		g_object_unref (window);
 	}
 
 	status = gst_install_plugins_async (ctx->details, install_ctx,
@@ -241,63 +244,13 @@ missing_plugins_event (RBShell *shell, RBPluginInstallContext *ctx)
 	return TRUE;
 }
 
-static gboolean
-missing_plugins_cb (gpointer instance,
-		    const char **details,
-		    GClosure *closure,
-		    RBShell *shell)
-{
-	RBPluginInstallContext *ctx;
-	guint num;
-
-	num = g_strv_length ((char **)details);
-	g_return_val_if_fail (num > 0, FALSE);
-
-	ctx = g_new0 (RBPluginInstallContext, 1);
-	ctx->closure = g_closure_ref (closure);
-	ctx->details = g_strdupv ((char **)details);
-	ctx->shell = g_object_ref (shell);
-
-	return missing_plugins_event (shell, ctx);
-}
-
 void
-rb_missing_plugins_init (RBShell *shell)
+rb_missing_plugins_init (GtkWindow *window)
 {
-	RBShellPlayer *player;
-	RBSource *podcast_source;
-	RBPodcastManager *podcast_mgr;
-
-	g_object_get (shell,
-		      "shell-player", &player,
-		      NULL);
-	g_signal_connect (player,
-			  "missing-plugins",
-			  G_CALLBACK (missing_plugins_cb),
-			  shell);
-
-	g_object_unref (player);
-
-	podcast_source = rb_shell_get_source_by_entry_type (shell, RHYTHMDB_ENTRY_TYPE_PODCAST_FEED);
-	g_object_get (podcast_source, "podcast-manager", &podcast_mgr, NULL);
-
-	g_signal_connect (podcast_mgr,
-			  "missing-plugins",
-			  G_CALLBACK (missing_plugins_cb),
-			  shell);
-
-	g_object_unref (podcast_mgr);
+	parent_window = window;
+	g_object_add_weak_pointer (G_OBJECT (parent_window), &parent_window);
 
 	gst_pb_utils_init ();
 
 	GST_INFO ("Set up support for automatic missing plugin installation");
 }
-
-void
-rb_missing_plugins_init_import_job (RBShell *shell, RhythmDBImportJob *job)
-{
-	g_signal_connect (job,
-			  "missing-plugins",
-			  G_CALLBACK (missing_plugins_cb),
-			  shell);
-}
diff --git a/shell/rb-missing-plugins.h b/lib/rb-missing-plugins.h
similarity index 86%
rename from shell/rb-missing-plugins.h
rename to lib/rb-missing-plugins.h
index 20aa9e7..85e8685 100644
--- a/shell/rb-missing-plugins.h
+++ b/lib/rb-missing-plugins.h
@@ -25,13 +25,12 @@
 #define RB_MISSING_PLUGINS_H
 
 #include <shell/rb-shell.h>
-#include <rhythmdb/rhythmdb-import-job.h>
 
 G_BEGIN_DECLS
 
-void rb_missing_plugins_init (RBShell *shell);
+void rb_missing_plugins_init (GtkWindow *parent_window);
 
-void rb_missing_plugins_init_import_job (RBShell *shell, RhythmDBImportJob *job);
+gboolean rb_missing_plugins_install (const char **details, gboolean ignore_blacklist, GClosure *closure);
 
 G_END_DECLS
 
diff --git a/plugins/generic-player/rb-generic-player-source.c b/plugins/generic-player/rb-generic-player-source.c
index 323abc0..d83ea68 100644
--- a/plugins/generic-player/rb-generic-player-source.c
+++ b/plugins/generic-player/rb-generic-player-source.c
@@ -467,20 +467,16 @@ load_songs (RBGenericPlayerSource *source)
 	RhythmDBEntryType entry_type;
 	char **audio_folders;
 	char *mount_path;
-	RBShell *shell;
 
 	mount_path = rb_generic_player_source_get_mount_path (source);
 	g_object_get (source,
 		      "entry-type", &entry_type,
-		      "shell", &shell,
 		      NULL);
 
 	/* if we have a set of folders on the device containing audio files,
 	 * load only those folders, otherwise add the whole volume.
 	 */
 	priv->import_job = rhythmdb_import_job_new (priv->db, entry_type, priv->ignore_type, priv->error_type);
-	rb_missing_plugins_init_import_job (shell, priv->import_job);
-	g_object_unref (shell);
 
 	g_signal_connect_object (priv->import_job, "complete", G_CALLBACK (import_complete_cb), source, 0);
 	g_signal_connect_object (priv->import_job, "status-changed", G_CALLBACK (import_status_changed_cb), source, 0);
diff --git a/podcast/rb-podcast-manager.c b/podcast/rb-podcast-manager.c
index c220bf2..8930b5e 100644
--- a/podcast/rb-podcast-manager.c
+++ b/podcast/rb-podcast-manager.c
@@ -49,6 +49,7 @@
 #include "rb-dialog.h"
 #include "rb-metadata.h"
 #include "rb-util.h"
+#include "rb-missing-plugins.h"
 
 #define CONF_STATE_PODCAST_PREFIX		CONF_PREFIX "/state/podcast"
 #define CONF_STATE_PODCAST_DOWNLOAD_DIR		CONF_STATE_PODCAST_PREFIX "/download_prefix"
@@ -76,7 +77,6 @@ enum
 	FINISH_DOWNLOAD,
 	PROCESS_ERROR,
 	FEED_UPDATES_AVAILABLE,
-	MISSING_PLUGINS,
 	LAST_SIGNAL
 };
 
@@ -265,17 +265,6 @@ rb_podcast_manager_class_init (RBPodcastManagerClass *klass)
 				G_TYPE_STRING,
 				G_TYPE_BOOLEAN);
 
-	rb_podcast_manager_signals[MISSING_PLUGINS] =
-		g_signal_new ("missing-plugins",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      0,		/* no internal handler */
-			      NULL, NULL,
-			      rb_marshal_BOOLEAN__POINTER_POINTER,
-			      G_TYPE_BOOLEAN,
-			      2,
-			      G_TYPE_STRV, G_TYPE_CLOSURE);
-
 	g_type_class_add_private (klass, sizeof (RBPodcastManagerPrivate));
 }
 
@@ -1293,7 +1282,8 @@ rb_podcast_manager_save_metadata (RBPodcastManager *pd, RhythmDBEntry *entry)
 					  data,
 					  (GClosureNotify) missing_plugins_retry_cleanup);
 		g_closure_set_marshal (closure, g_cclosure_marshal_VOID__BOOLEAN);
-		g_signal_emit (pd, rb_podcast_manager_signals[MISSING_PLUGINS], 0, missing_plugins, plugin_descriptions, closure, &processing);
+
+		processing = rb_missing_plugins_install ((const char **)missing_plugins, FALSE, closure);
 		g_closure_sink (closure);
 
 		if (processing) {
diff --git a/rhythmdb/rhythmdb-import-job.c b/rhythmdb/rhythmdb-import-job.c
index 2c8b633..5f5d5a5 100644
--- a/rhythmdb/rhythmdb-import-job.c
+++ b/rhythmdb/rhythmdb-import-job.c
@@ -33,6 +33,7 @@
 #include "rb-file-helpers.h"
 #include "rb-marshal.h"
 #include "rb-debug.h"
+#include "rb-missing-plugins.h"
 
 enum
 {
@@ -49,7 +50,6 @@ enum
 	STATUS_CHANGED,
 	SCAN_COMPLETE,
 	COMPLETE,
-	MISSING_PLUGINS,
 	LAST_SIGNAL
 };
 
@@ -237,8 +237,7 @@ emit_status_changed (RhythmDBImportJob *job)
 						(GClosureNotify)g_object_unref);
 			g_closure_set_marshal (retry, g_cclosure_marshal_VOID__BOOLEAN);
 
-			rb_debug ("emitting missing-plugins");
-			g_signal_emit (job, signals[MISSING_PLUGINS], 0, details, retry, &processing);
+			processing = rb_missing_plugins_install ((const char **)details, FALSE, retry);
 			g_strfreev (details);
 			if (processing) {
 				rb_debug ("plugin installation is in progress");
@@ -668,29 +667,6 @@ rhythmdb_import_job_class_init (RhythmDBImportJobClass *klass)
 			      g_cclosure_marshal_VOID__INT,
 			      G_TYPE_NONE,
 			      1, G_TYPE_INT);
-	/**
-	 * RhythmDBImportJob::missing-plugins:
-	 * @job: the #RhythmDBImportJob
-	 * @details: NULL-terminated array of installer detail strings
-	 * @closure: a closure to invoke once the installer has finished
-	 *
-	 * Emitted when the whole import job is complete (but before the
-	 * 'complete' signal) but additional plugins are required to
-	 * import some of the files.
-	 *
-	 * If a handler initiates plugin installation, it should return TRUE
-	 * and invoke the closure when the installation finishes.
-	 * Otherwise it should return FALSE.
-	 */
-	signals[MISSING_PLUGINS] =
-		g_signal_new ("missing-plugins",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      0, /* no internal handler */
-			      NULL, NULL,
-			      rb_marshal_BOOLEAN__POINTER_POINTER,
-			      G_TYPE_BOOLEAN,
-			      2, G_TYPE_STRV, G_TYPE_CLOSURE);
 
 	g_type_class_add_private (klass, sizeof (RhythmDBImportJobPrivate));
 }
diff --git a/shell/Makefile.am b/shell/Makefile.am
index ac879be..225b43c 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -65,8 +65,6 @@ shellinclude_HEADERS =					\
 librhythmbox_core_la_SOURCES =				\
 	$(shellinclude_HEADERS)				\
 	rb-history.c					\
-	rb-missing-plugins.h				\
-	rb-missing-plugins.c				\
 	rb-play-order.c					\
 	rb-play-order-linear.c				\
 	rb-play-order-linear.h				\
diff --git a/shell/rb-shell-player.c b/shell/rb-shell-player.c
index 7a36201..4570d14 100644
--- a/shell/rb-shell-player.c
+++ b/shell/rb-shell-player.c
@@ -85,6 +85,7 @@
 #include "rhythmdb.h"
 #include "rb-podcast-manager.h"
 #include "rb-marshal.h"
+#include "rb-missing-plugins.h"
 
 /* Play Orders */
 #include "rb-play-order-linear.h"
@@ -298,7 +299,6 @@ enum
 	PLAYING_SONG_CHANGED,
 	PLAYING_URI_CHANGED,
 	PLAYING_SONG_PROPERTY_CHANGED,
-	MISSING_PLUGINS,
 	ELAPSED_NANO_CHANGED,
 	LAST_SIGNAL
 };
@@ -639,27 +639,6 @@ rb_shell_player_class_init (RBShellPlayerClass *klass)
 			      G_TYPE_VALUE, G_TYPE_VALUE);
 
 	/**
-	 * RBShellPlayer::missing-plugins:
-	 * @player: the #RBShellPlayer
-	 * @details: the list of plugin detail strings describing the missing plugins
-	 * @closure: a #GClosure to be called when the plugin installation is complete
-	 *
-	 * Emitted when the player backend requires some plugins to be installed in
-	 * order to play the current playing song.  When the closure included in the
-	 * signal args is called, playback will be attempted again.
-	 */
-	rb_shell_player_signals[MISSING_PLUGINS] =
-		g_signal_new ("missing-plugins",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      0,	/* no need for an internal handler */
-			      NULL, NULL,
-			      rb_marshal_BOOLEAN__POINTER_POINTER,
-			      G_TYPE_BOOLEAN,
-			      2,
-			      G_TYPE_STRV, G_TYPE_CLOSURE);
-
-	/**
 	 * RBShellPlayer::elapsed-nano-changed:
 	 * @player: the #RBShellPlayer
 	 * @elapsed: the new playback position in nanoseconds
@@ -3679,10 +3658,7 @@ missing_plugins_cb (RBPlayer *player,
 				retry_data,
 				(GClosureNotify) missing_plugins_retry_cleanup);
 	g_closure_set_marshal (retry, g_cclosure_marshal_VOID__BOOLEAN);
-	g_signal_emit (sp,
-		       rb_shell_player_signals[MISSING_PLUGINS], 0,
-		       details, retry,
-		       &processing);
+	processing = rb_missing_plugins_install (details, FALSE, retry);
 	if (processing) {
 		/* don't handle any further errors */
 		sp->priv->handling_error = TRUE;
diff --git a/shell/rb-shell.c b/shell/rb-shell.c
index bc0f4a4..9dd96ef 100644
--- a/shell/rb-shell.c
+++ b/shell/rb-shell.c
@@ -1597,7 +1597,7 @@ rb_shell_constructed (GObject *object)
 
 	rb_plugins_engine_init (shell);
 
-	rb_missing_plugins_init (shell);
+	rb_missing_plugins_init (GTK_WINDOW (shell->priv->window));
 
 	g_idle_add ((GSourceFunc)_scan_idle, shell);
 
diff --git a/sources/rb-library-source.c b/sources/rb-library-source.c
index 7c942a1..b00dba2 100644
--- a/sources/rb-library-source.c
+++ b/sources/rb-library-source.c
@@ -1395,7 +1395,6 @@ maybe_create_import_job (RBLibrarySource *source)
 {
 	RhythmDBImportJob *job;
 	if (source->priv->import_jobs == NULL || source->priv->start_import_job_id == 0) {
-		RBShell *shell;
 
 		rb_debug ("creating new import job");
 		job = rhythmdb_import_job_new (source->priv->db,
@@ -1403,10 +1402,6 @@ maybe_create_import_job (RBLibrarySource *source)
 					       RHYTHMDB_ENTRY_TYPE_IGNORE,
 					       RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR);
 
-		g_object_get (source, "shell", &shell, NULL);
-		rb_missing_plugins_init_import_job (shell, job);
-		g_object_unref (shell);
-
 		g_signal_connect_object (job,
 					 "status-changed",
 					 G_CALLBACK (import_job_status_changed_cb),



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