rhythmbox r5690 - in trunk: . plugins/daap plugins/ipod shell sources widgets



Author: jmatthew
Date: Sun Apr 27 14:07:32 2008
New Revision: 5690
URL: http://svn.gnome.org/viewvc/rhythmbox?rev=5690&view=rev

Log:
2008-04-28  Jonathan Matthew  <jonathan d14n org>

	patch by:  Jay Cornwall  <jay jcornwall me uk>

	* sources/rb-playlist-source.c: (rb_playlist_source_class_init),
	(rb_playlist_source_constructor),
	(rb_playlist_source_set_property),
	(rb_playlist_source_get_property),
	(rb_playlist_source_songs_sort_order_changed_cb),
	(rb_playlist_source_make_sorting_key):
	Add a 'sorting-name' property that is used to construct the GConf key
	in which to store the playlist sort order.

	* sources/rb-static-playlist-source.c:
	(rb_static_playlist_source_new),
	(rb_static_playlist_source_new_from_xml):
	* sources/rb-static-playlist-source.h:
	Add sorting name as a parameter when creating new static playlists.

	* widgets/rb-entry-view.c: (rb_entry_view_class_init),
	(rb_entry_view_set_property), (rb_entry_view_constructor):
	Allow the sort order GConf key to be changed after the widget is
	constructed.
	
	* plugins/daap/rb-daap-source.c: (rb_daap_source_connection_cb):
	Construct sorting names for DAAP playlist based on the DAAP share name
	combined with the playlist name.

	* plugins/ipod/rb-ipod-source.c: (add_rb_playlist):
	* shell/rb-playlist-manager.c: (rb_playlist_manager_new_playlist):
	Don't provide sorting keys for playlists created here.

	This allows DAAP playlists to be sorted by the user.  From #327042.


Modified:
   trunk/ChangeLog
   trunk/plugins/daap/rb-daap-source.c
   trunk/plugins/ipod/rb-ipod-source.c
   trunk/shell/rb-playlist-manager.c
   trunk/sources/rb-playlist-source.c
   trunk/sources/rb-static-playlist-source.c
   trunk/sources/rb-static-playlist-source.h
   trunk/widgets/rb-entry-view.c

Modified: trunk/plugins/daap/rb-daap-source.c
==============================================================================
--- trunk/plugins/daap/rb-daap-source.c	(original)
+++ trunk/plugins/daap/rb-daap-source.c	Sun Apr 27 14:07:32 2008
@@ -542,8 +542,14 @@
 	for (l = playlists; l != NULL; l = g_slist_next (l)) {
 		RBDAAPPlaylist *playlist = l->data;
 		RBSource *playlist_source;
+		char *sorting_name;
+
+		/* Construct a unique sorting name for this playlist, as <Share Name>_<Playlist> */
+		sorting_name = g_strjoin (NULL, daap_source->priv->service_name, "_", playlist->name, NULL);
+
+		playlist_source = rb_static_playlist_source_new (shell, playlist->name, sorting_name, FALSE, entry_type);
+		g_free (sorting_name);
 
-		playlist_source = rb_static_playlist_source_new (shell, playlist->name, FALSE, entry_type);
 		g_list_foreach (playlist->uris, (GFunc)_add_location_to_playlist, playlist_source);
 
 		rb_shell_append_source (shell, playlist_source, RB_SOURCE (daap_source));

Modified: trunk/plugins/ipod/rb-ipod-source.c
==============================================================================
--- trunk/plugins/ipod/rb-ipod-source.c	(original)
+++ trunk/plugins/ipod/rb-ipod-source.c	Sun Apr 27 14:07:32 2008
@@ -390,6 +390,7 @@
 
 	playlist_source = rb_static_playlist_source_new (shell,
 							 playlist->name,
+							 NULL,
 							 FALSE,
 							 entry_type);
 	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);

Modified: trunk/shell/rb-playlist-manager.c
==============================================================================
--- trunk/shell/rb-playlist-manager.c	(original)
+++ trunk/shell/rb-playlist-manager.c	Sun Apr 27 14:07:32 2008
@@ -924,6 +924,7 @@
 	else
 		playlist = rb_static_playlist_source_new (mgr->priv->shell,
 							  suggested_name,
+							  NULL,
 							  TRUE,
 							  RHYTHMDB_ENTRY_TYPE_SONG);
 

Modified: trunk/sources/rb-playlist-source.c
==============================================================================
--- trunk/sources/rb-playlist-source.c	(original)
+++ trunk/sources/rb-playlist-source.c	Sun Apr 27 14:07:32 2008
@@ -117,7 +117,11 @@
 						     GtkTreeModel *tree_model, GtkTreeIter *iter,
 						     RBPlaylistSource *source);
 static void default_mark_dirty (RBPlaylistSource *source);
+static void rb_playlist_source_songs_sort_order_changed_cb (RBEntryView *view,
+						RBStaticPlaylistSource *source);
+static char *rb_playlist_source_make_sorting_key (RBPlaylistSource *source);
 
+#define CONF_STATE_SORTING_PREFIX CONF_PREFIX "/state/sorting/"
 #define PLAYLIST_SOURCE_SONGS_POPUP_PATH "/PlaylistViewPopup"
 #define PLAYLIST_SOURCE_POPUP_PATH "/PlaylistSourcePopup"
 
@@ -136,6 +140,7 @@
 	gboolean dispose_has_run;
 
 	char *title;
+	char *sorting_name;
 };
 
 #define RB_PLAYLIST_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_PLAYLIST_SOURCE, RBPlaylistSourcePrivate))
@@ -146,6 +151,7 @@
 	PROP_DB,
 	PROP_DIRTY,
 	PROP_LOCAL,
+	PROP_SORTING_NAME
 };
 
 static const GtkTargetEntry target_uri [] = { { "text/uri-list", 0, 0 } };
@@ -219,6 +225,19 @@
 							       "whether this playlist is attached to the local library",
 							       TRUE,
 							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	/**
+	 * RBPlaylistSource:sorting-name:
+	 *
+	 * A unique-ish name for the playlist, used to construct gconf keys
+	 * to store information relating to the playlist.
+	 */
+	g_object_class_install_property (object_class,
+					 PROP_SORTING_NAME,
+					 g_param_spec_string ("sorting-name",
+					 		      "sorting-name",
+							      "globally unique name for storing sort-order",
+					 		      NULL,
+							      G_PARAM_READWRITE));
 
 	g_type_class_add_private (klass, sizeof (RBPlaylistSourcePrivate));
 }
@@ -263,6 +282,7 @@
 	RBShell *shell;
 	RhythmDB *db;
 	RhythmDBQueryModel *query_model;
+	char *sorting_key;
 
 	klass = RB_PLAYLIST_SOURCE_CLASS (g_type_class_peek (RB_TYPE_PLAYLIST_SOURCE));
 
@@ -279,9 +299,18 @@
 	source->priv->entries = g_hash_table_new_full (rb_refstring_hash, rb_refstring_equal,
 						       (GDestroyNotify)rb_refstring_unref, NULL);
 
+	/* If a sorting key is available at construction time, use it. This may be
+	 * NULL in which case a key may be assigned later through a set property. */
+	sorting_key = rb_playlist_source_make_sorting_key (source);
 	source->priv->songs = rb_entry_view_new (source->priv->db,
 						 shell_player,
-					 	 NULL, TRUE, TRUE);
+					 	 sorting_key, TRUE, TRUE);
+	g_free (sorting_key);
+
+	g_signal_connect_object (source->priv->songs,
+				 "sort-order-changed",
+				 G_CALLBACK (rb_playlist_source_songs_sort_order_changed_cb),
+				 source, 0);
 
 	query_model = rhythmdb_query_model_new_empty (source->priv->db);
 	rb_playlist_source_set_query_model (source, query_model);
@@ -396,11 +425,21 @@
 				 GParamSpec *pspec)
 {
 	RBPlaylistSource *source = RB_PLAYLIST_SOURCE (object);
+	char *sorting_key;
 
 	switch (prop_id) {
 	case PROP_LOCAL:
 		source->priv->is_local = g_value_get_boolean (value);
 		break;
+	case PROP_SORTING_NAME:
+		g_free (source->priv->sorting_name);
+		source->priv->sorting_name = g_value_dup_string (value);
+
+		/* propagate sorting key to the entry view */
+		sorting_key = rb_playlist_source_make_sorting_key (source);
+		g_object_set (source->priv->songs, "sort-key", sorting_key, NULL);
+		g_free (sorting_key);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -425,6 +464,9 @@
 	case PROP_LOCAL:
 		g_value_set_boolean (value, source->priv->is_local);
 		break;
+	case PROP_SORTING_NAME:
+		g_value_set_string (value, source->priv->sorting_name);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -980,3 +1022,39 @@
 	return TRUE;
 }
 
+static void
+rb_playlist_source_songs_sort_order_changed_cb (RBEntryView *view,
+						RBStaticPlaylistSource *source)
+{
+	rb_debug ("sort order changed");
+	rb_entry_view_resort_model (view);
+}
+
+/* takes the 'sorting-name' property and produces a full GConf key for storing
+ * the playlist's column sort order
+ */
+static char *
+rb_playlist_source_make_sorting_key (RBPlaylistSource *source)
+{
+	char *sorting_name;
+	char *sorting_key;
+	char *sorting_key_tail;
+	g_object_get (source, "sorting-name", &sorting_name, NULL);
+
+	if (sorting_name && sorting_name[0] != '\0') {
+		/* escape invalid characters in the key name */
+		sorting_key_tail = gconf_escape_key (sorting_name, -1);
+
+		/* bind column sort order to a full gconf key */
+		sorting_key = g_strjoin (NULL, CONF_STATE_SORTING_PREFIX, 
+					sorting_key_tail, NULL);
+
+		g_free (sorting_key_tail);
+	} else {
+		sorting_key = NULL;
+	}
+	g_free (sorting_name);
+
+	return sorting_key;
+}
+

Modified: trunk/sources/rb-static-playlist-source.c
==============================================================================
--- trunk/sources/rb-static-playlist-source.c	(original)
+++ trunk/sources/rb-static-playlist-source.c	Sun Apr 27 14:07:32 2008
@@ -325,13 +325,17 @@
 }
 
 RBSource *
-rb_static_playlist_source_new (RBShell *shell, const char *name, gboolean local, RhythmDBEntryType entry_type)
+rb_static_playlist_source_new (RBShell *shell, const char *name, const char *sorting_name, gboolean local, RhythmDBEntryType entry_type)
 {
 	if (name == NULL)
 		name = "";
 
+	if (sorting_name == NULL)
+		sorting_name = "";
+
 	return RB_SOURCE (g_object_new (RB_TYPE_STATIC_PLAYLIST_SOURCE,
 					"name", name,
+					"sorting-name", sorting_name,
 					"shell", shell,
 					"is-local", local,
 					"entry-type", entry_type,
@@ -398,6 +402,7 @@
 {
 	RBSource *psource = rb_static_playlist_source_new (shell,
 							   NULL,
+							   NULL,
 							   TRUE,
 							   RHYTHMDB_ENTRY_TYPE_SONG);
 	RBStaticPlaylistSource *source = RB_STATIC_PLAYLIST_SOURCE (psource);

Modified: trunk/sources/rb-static-playlist-source.h
==============================================================================
--- trunk/sources/rb-static-playlist-source.h	(original)
+++ trunk/sources/rb-static-playlist-source.h	Sun Apr 27 14:07:32 2008
@@ -59,6 +59,7 @@
 
 RBSource *	rb_static_playlist_source_new		(RBShell *shell,
 							 const char *name,
+							 const char *sorting_name,
 							 gboolean local,
 							 RhythmDBEntryType entry_type);
 

Modified: trunk/widgets/rb-entry-view.c
==============================================================================
--- trunk/widgets/rb-entry-view.c	(original)
+++ trunk/widgets/rb-entry-view.c	Sun Apr 27 14:07:32 2008
@@ -328,7 +328,7 @@
 							      "sorting key",
 							      "sorting key",
 							      "",
-							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+							      G_PARAM_READWRITE));
 	/**
 	 * RBEntryView:is-drag-source:
 	 *
@@ -712,6 +712,7 @@
 			    const GValue *value,
 			    GParamSpec *pspec)
 {
+	char *old_sorting_key;
 	RBEntryView *view = RB_ENTRY_VIEW (object);
 
 	switch (prop_id) {
@@ -722,8 +723,42 @@
 		rb_entry_view_set_shell_player_internal (view, g_value_get_object (value));
 		break;
 	case PROP_SORTING_KEY:
-		g_free (view->priv->sorting_key);
+		/* Remove notification on old key, if any. */
+		if (view->priv->sorting_key) {
+			eel_gconf_notification_remove (view->priv->sorting_gconf_notification_id);
+			view->priv->sorting_gconf_notification_id = 0;
+		}
+
+		old_sorting_key = view->priv->sorting_key;
 		view->priv->sorting_key = g_value_dup_string (value);
+
+		if (view->priv->sorting_key && view->priv->sorting_key[0] != '\0') {
+			char *new_sorting_type;
+
+			/* Set up notification on the new key. */
+			view->priv->sorting_gconf_notification_id =
+				eel_gconf_notification_add (view->priv->sorting_key,
+							    rb_entry_view_sort_key_changed_cb,
+							    view);
+
+			rb_entry_view_set_columns_clickable (view, TRUE);
+
+			/* If there was already a sorting key, assume this is a rename. */
+			if (old_sorting_key && old_sorting_key[0] != '\0') {
+				/* Propagate existing sort order into the new GConf key. */
+				eel_gconf_set_string (view->priv->sorting_key,
+						      rb_entry_view_get_sorting_type (view));
+
+				eel_gconf_unset (old_sorting_key);
+			}
+
+			/* Synchronise UI sorting order with the new key. */
+			new_sorting_type = eel_gconf_get_string (view->priv->sorting_key);
+			rb_entry_view_set_sorting_type (view, new_sorting_type);
+			g_free (new_sorting_type);
+		}
+
+		g_free (old_sorting_key);
 		break;
 	case PROP_MODEL:
 		rb_entry_view_set_model_internal (view, g_value_get_object (value));
@@ -1718,18 +1753,6 @@
 		eel_gconf_notification_add (CONF_UI_COLUMNS_SETUP,
 					    rb_entry_view_columns_config_changed_cb,
 					    view);
-	if (view->priv->sorting_key) {
-		view->priv->sorting_gconf_notification_id =
-			eel_gconf_notification_add (view->priv->sorting_key,
-						    rb_entry_view_sort_key_changed_cb,
-						    view);
-	}
-
-	if (view->priv->sorting_key) {
-		char *s = eel_gconf_get_string (view->priv->sorting_key);
-		rb_entry_view_set_sorting_type (view, s);
-		g_free (s);
-	}
 
 	{
 		RhythmDBQueryModel *query_model;



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