[totem] Use the new totem_playlist_add_mrls() API to add multiple playlist entries



commit 8a810680960f0e7d2d9e10b6f21da21332a5bbfe
Author: Philip Withnall <philip tecnocode co uk>
Date:   Wed Dec 15 16:31:04 2010 +0000

    Use the new totem_playlist_add_mrls() API to add multiple playlist entries
    
    As described in the previous commit, this new API ensures that when adding
    multiple playlist entries asynchronously, they're not added to Totem's
    playlist out of order. Closes: bgo#636686

 src/plugins/publish/totem-publish.c |    7 +++-
 src/totem-object.c                  |   70 ++++++++++++++--------------------
 src/totem-playlist.c                |   28 ++++++++------
 src/totem-video-list.c              |    7 +++-
 4 files changed, 57 insertions(+), 55 deletions(-)
---
diff --git a/src/plugins/publish/totem-publish.c b/src/plugins/publish/totem-publish.c
index 6049f6c..357b249 100644
--- a/src/plugins/publish/totem-publish.c
+++ b/src/plugins/publish/totem-publish.c
@@ -383,6 +383,7 @@ totem_publish_plugin_load_playlist (TotemPublishPlugin   *self,
 
 	if (contents && g_key_file_load_from_data (keyfile, contents, length, G_KEY_FILE_NONE, &error)) {
 		gint i, n_entries;
+		GList *mrl_list = NULL;
 
 		/* returns zero in case of errors */
 		n_entries = g_key_file_get_integer (keyfile, "playlist", "NumberOfEntries", &error);
@@ -405,11 +406,15 @@ totem_publish_plugin_load_playlist (TotemPublishPlugin   *self,
 			g_free (key);
 
 			if (mrl)
-				totem_playlist_add_mrl (self->priv->totem->playlist, mrl, title, FALSE, NULL, NULL, NULL);
+				mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (mrl, title));
 
 			g_free (title);
 			g_free (mrl);
 		}
+
+		/* Add the MRLs to the playlist asynchronously and in order */
+		if (mrl_list != NULL)
+			totem_playlist_add_mrls (self->priv->totem->playlist, g_list_reverse (mrl_list), FALSE, NULL, NULL, NULL);
 	}
 
 out:
diff --git a/src/totem-object.c b/src/totem-object.c
index 7732197..711e068 100644
--- a/src/totem-object.c
+++ b/src/totem-object.c
@@ -2187,31 +2187,20 @@ totem_action_show_help (TotemObject *totem)
 	}
 }
 
-typedef struct {
-	gint add_mrl_complete;
-	TotemObject *totem;
-} DropFilesData;
-
 /* This is called in the main thread */
 static void
-totem_action_drop_files_finished (TotemPlaylist *playlist, GAsyncResult *result, DropFilesData *data)
+totem_action_drop_files_finished (TotemPlaylist *playlist, GAsyncResult *result, TotemObject *totem)
 {
-	/* When add_mrl_complete reaches 0, this is the last callback to occur and we can safely reconnect the playlist's changed signal (which was
-	 * disconnected below in totem_action_drop_files(). We can also free the data struct and generally clean up. */
-	if (g_atomic_int_dec_and_test (&(data->add_mrl_complete)) == TRUE) {
-		char *mrl, *subtitle;
+	char *mrl, *subtitle;
 
-		/* Reconnect the signal */
-		g_signal_connect (G_OBJECT (playlist), "changed", G_CALLBACK (playlist_changed_cb), data->totem);
-		mrl = totem_playlist_get_current_mrl (playlist, &subtitle);
-		totem_action_set_mrl_and_play (data->totem, mrl, subtitle);
-		g_free (mrl);
-		g_free (subtitle);
+	/* Reconnect the playlist's changed signal (which was disconnected below in totem_action_drop_files(). */
+	g_signal_connect (G_OBJECT (playlist), "changed", G_CALLBACK (playlist_changed_cb), totem);
+	mrl = totem_playlist_get_current_mrl (playlist, &subtitle);
+	totem_action_set_mrl_and_play (totem, mrl, subtitle);
+	g_free (mrl);
+	g_free (subtitle);
 
-		/* Free the data struct */
-		g_object_unref (data->totem);
-		g_slice_free (DropFilesData, data);
-	}
+	g_object_unref (totem);
 }
 
 static gboolean
@@ -2220,8 +2209,7 @@ totem_action_drop_files (TotemObject *totem, GtkSelectionData *data,
 {
 	char **list;
 	guint i, len;
-	DropFilesData *drop_files_data = NULL /* shut up gcc */;
-	GList *p, *file_list;
+	GList *p, *file_list, *mrl_list = NULL;
 	gboolean cleared = FALSE;
 
 	list = g_uri_list_extract_uris ((const char *) gtk_selection_data_get_data (data));
@@ -2261,18 +2249,11 @@ totem_action_drop_files (TotemObject *totem, GtkSelectionData *data,
 		g_signal_handlers_disconnect_by_func (G_OBJECT (totem->playlist), playlist_changed_cb, totem);
 		totem_playlist_clear (totem->playlist);
 		cleared = TRUE;
-
-		/* Allocate some shared memory to count how many add_mrl operations have completed (see the comment below).
-		 * It's freed in totem_action_drop_files_cb() once all add_mrl operations have finished. */
-		drop_files_data = g_slice_new (DropFilesData);
-		drop_files_data->add_mrl_complete = len;
-		drop_files_data->totem = g_object_ref (totem);
 	}
 
 	/* Add each MRL to the playlist asynchronously */
 	for (p = file_list; p != NULL; p = p->next) {
-		const char *filename;
-		char *title;
+		const char *filename, *title;
 
 		filename = p->data;
 		title = NULL;
@@ -2288,15 +2269,17 @@ totem_action_drop_files (TotemObject *totem, GtkSelectionData *data,
 			}
 		}
 
-		/* Add the MRL to the playlist. We need to reconnect playlist's "changed" signal once all of the add_mrl operations have completed,
-		 * so we use a piece of allocated memory shared between the async operations to count how many have completed.
-		 * If we haven't cleared the playlist, there's no need to do this. */
-		if (cleared == TRUE) {
-			totem_playlist_add_mrl (totem->playlist, filename, title, TRUE, NULL,
-			                        (GAsyncReadyCallback) totem_action_drop_files_finished, drop_files_data);
-		} else {
-			totem_playlist_add_mrl (totem->playlist, filename, title, TRUE, NULL, NULL, NULL);
-		}
+		/* Add the MRL data to the list of MRLs to add to the playlist */
+		mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (filename, title));
+	}
+
+	/* Add the MRLs to the playlist asynchronously and in order. We need to reconnect playlist's "changed" signal once all of the add-MRL
+	 * operations have completed. If we haven't cleared the playlist, there's no need to do this. */
+	if (mrl_list != NULL && cleared == TRUE) {
+		totem_playlist_add_mrls (totem->playlist, g_list_reverse (mrl_list), TRUE, NULL,
+		                         (GAsyncReadyCallback) totem_action_drop_files_finished, g_object_ref (totem));
+	} else if (mrl_list != NULL) {
+		totem_playlist_add_mrls (totem->playlist, g_list_reverse (mrl_list), TRUE, NULL, NULL, NULL);
 	}
 
 bail:
@@ -2806,6 +2789,7 @@ static gboolean
 totem_action_open_files_list (TotemObject *totem, GSList *list)
 {
 	GSList *l;
+	GList *mrl_list = NULL;
 	gboolean changed;
 	gboolean cleared;
 
@@ -2859,10 +2843,10 @@ totem_action_open_files_list (TotemObject *totem, GSList *list)
 				totem_action_load_media_device (totem, data);
 				changed = TRUE;
 			} else if (g_str_has_prefix (filename, "dvb:/") != FALSE) {
-				totem_playlist_add_mrl (totem->playlist, data, NULL, FALSE, NULL, NULL, NULL);
+				mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (data, NULL));
 				changed = TRUE;
 			} else {
-				totem_playlist_add_mrl (totem->playlist, filename, NULL, FALSE, NULL, NULL, NULL);
+				mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (filename, NULL));
 				changed = TRUE;
 			}
 		}
@@ -2870,6 +2854,10 @@ totem_action_open_files_list (TotemObject *totem, GSList *list)
 		g_free (filename);
 	}
 
+	/* Add the MRLs to the playlist asynchronously and in order */
+	if (mrl_list != NULL)
+		totem_playlist_add_mrls (totem->playlist, g_list_reverse (mrl_list), FALSE, NULL, NULL, NULL);
+
 	gdk_window_set_cursor (gtk_widget_get_window (totem->win), NULL);
 
 	/* ... and reconnect because we're nice people */
diff --git a/src/totem-playlist.c b/src/totem-playlist.c
index ed17ad0..3f06b15 100644
--- a/src/totem-playlist.c
+++ b/src/totem-playlist.c
@@ -489,6 +489,8 @@ gtk_tree_selection_has_selected (GtkTreeSelection *selection)
 static void
 drop_finished_cb (TotemPlaylist *playlist, GAsyncResult *result, gpointer user_data)
 {
+	totem_playlist_add_mrls_finish (playlist, result, NULL);
+
 	/* Emit the "changed" signal once the last dropped MRL has been added to the playlist */
 	g_signal_emit (G_OBJECT (playlist),
 	               totem_playlist_table_signals[CHANGED], 0,
@@ -506,7 +508,7 @@ drop_cb (GtkWidget        *widget,
 	 TotemPlaylist    *playlist)
 {
 	char **list;
-	GList *p, *file_list;
+	GList *p, *file_list, *mrl_list = NULL;
 	guint i;
 	GdkDragAction action;
 
@@ -570,16 +572,16 @@ drop_cb (GtkWidget        *widget,
 			}
 		}
 
-		/* Add the MRL to the playlist asynchronously. If it's the last MRL, emit the "changed"
-		 * signal once we're done adding it */
-		if (p->next == NULL)
-			totem_playlist_add_mrl (playlist, filename, title, TRUE, NULL, (GAsyncReadyCallback) drop_finished_cb, NULL);
-		else
-			totem_playlist_add_mrl (playlist, filename, title, TRUE, NULL, NULL, NULL);
-
+		/* Add the MRL to the list of MRLs to be added to the playlist */
+		mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (filename, title));
 		g_free (filename);
 	}
 
+	/* Add all the MRLs to the playlist asynchronously, emitting the "changed" signal once we're done.
+	 * Note that this takes ownership of @mrl_list. */
+	if (mrl_list != NULL)
+		totem_playlist_add_mrls (playlist, g_list_reverse (mrl_list), TRUE, NULL, (GAsyncReadyCallback) drop_finished_cb, NULL);
+
 	g_strfreev (list);
 	g_list_free (file_list);
 	gtk_drag_finish (context, TRUE, FALSE, _time);
@@ -853,20 +855,22 @@ void
 totem_playlist_add_files (GtkWidget *widget, TotemPlaylist *playlist)
 {
 	GSList *filenames, *l;
+	GList *mrl_list = NULL;
 
 	filenames = totem_add_files (totem_playlist_get_toplevel (playlist), NULL);
 	if (filenames == NULL)
 		return;
 
 	for (l = filenames; l != NULL; l = l->next) {
-		char *mrl;
-
-		mrl = l->data;
-		totem_playlist_add_mrl (playlist, mrl, NULL, TRUE, NULL, NULL, NULL);
+		char *mrl = l->data;
+		mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (mrl, NULL));
 		g_free (mrl);
 	}
 
 	g_slist_free (filenames);
+
+	if (mrl_list != NULL)
+		totem_playlist_add_mrls (playlist, g_list_reverse (mrl_list), TRUE, NULL, NULL, NULL);
 }
 
 static void
diff --git a/src/totem-video-list.c b/src/totem-video-list.c
index a485f2d..caa4295 100644
--- a/src/totem-video-list.c
+++ b/src/totem-video-list.c
@@ -485,6 +485,7 @@ add_to_playlist_action_callback (GtkAction *action, TotemVideoList *self)
 	GtkTreePath *path;
 	GtkTreeIter iter;
 	gchar *mrl, *display_name;
+	GList *mrl_list = NULL;
 	GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
 	GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
 	GList *l = gtk_tree_selection_get_selected_rows (selection, NULL);
@@ -506,7 +507,7 @@ add_to_playlist_action_callback (GtkAction *action, TotemVideoList *self)
 			continue;
 		}
 
-		totem_playlist_add_mrl (playlist, mrl, display_name, TRUE, NULL, NULL, NULL);
+		mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (mrl, display_name));
 
 		g_free (mrl);
 		g_free (display_name);
@@ -514,6 +515,10 @@ add_to_playlist_action_callback (GtkAction *action, TotemVideoList *self)
 
 	g_list_foreach (l, (GFunc) gtk_tree_path_free, NULL);
 	g_list_free (l);
+
+	/* Asynchronously add all the MRLs to the playlist in order */
+	if (mrl_list != NULL)
+		totem_playlist_add_mrls (playlist, g_list_reverse (mrl_list), TRUE, NULL, NULL, NULL);
 }
 
 void



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