Re: [Rhythmbox-devel] Re: Rhythmbox library stuff



On Wed, 2005-12-07 at 01:34 +0100, Martin Jeppesen wrote:
> > Perhaps we could new child sources to the Library, one for each watched
> > directory. That way if people did want them treated as separate, they
> > could click the expander and have separate sources; and if people wanted
> > them unified they would just use the normal Library source and not open
> > the expander. Implementing this would be fairly easy.

Attached is a patch that implements this, and also adds "Starts with"
and "Ends with" as options for string criteria in auto playlists. It
will only add the "child" library sources if you have more than one
location defined (which you can't do from the UI, only gconf-editor).

There are a few known caveats, namely you don't get the browsers or
search box (because auto playlists don't have them yet) and the sorting
order isn't stored between sessions.


> Does this mean, that
> 
> A second Library in the Source list
> http://bugzilla.gnome.org/show_bug.cgi?id=139256
> 
> could be resolved?
> 
> I would so much like that feature =)

This would probably satisfy that. The biggest issue is telling Rhythmbox
that you have multiple libraries. I'm not sure if there is a nice way to
add this to the UI, which doesn't make it more complication for everyone
else.


Cheers,

James "Doc" Livingston
-- 
"Symbol table full - fatal heap error; please go buy a RAM upgrade from
your local Apple dealer" -- MPW C error message
Index: rhythmdb/rhythmdb-tree.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/rhythmdb/rhythmdb-tree.c,v
retrieving revision 1.83
diff -u -u -r1.83 rhythmdb-tree.c
--- rhythmdb/rhythmdb-tree.c	30 Nov 2005 08:47:22 -0000	1.83
+++ rhythmdb/rhythmdb-tree.c	7 Dec 2005 02:11:36 -0000
@@ -1479,6 +1479,24 @@
 		case RHYTHMDB_QUERY_PROP_LESS:
 			RHYTHMDB_PROPERTY_COMPARE (>)
 			break;
+		case RHYTHMDB_QUERY_PROP_PREFIX:
+		{
+			const gchar *value_string = g_value_get_string (data->val);
+			const char *entry_string = rhythmdb_entry_get_string (entry, data->propid);
+
+			if (!g_str_has_prefix (entry_string, value_string))
+				return FALSE;
+			break;
+		}
+		case RHYTHMDB_QUERY_PROP_SUFFIX:
+		{
+			const gchar *value_string = g_value_get_string (data->val);
+			const char *entry_string = rhythmdb_entry_get_string (entry, data->propid);
+
+			if (!g_str_has_suffix (entry_string, value_string))
+				return FALSE;
+			break;
+		}
 		case RHYTHMDB_QUERY_END:
 		case RHYTHMDB_QUERY_DISJUNCTION:
 			g_assert_not_reached ();
Index: rhythmdb/rhythmdb.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/rhythmdb/rhythmdb.c,v
retrieving revision 1.144
diff -u -u -r1.144 rhythmdb.c
--- rhythmdb/rhythmdb.c	6 Dec 2005 09:07:02 -0000	1.144
+++ rhythmdb/rhythmdb.c	7 Dec 2005 02:11:39 -0000
@@ -61,6 +61,8 @@
 #define RB_PARSE_LESS (xmlChar *) "less"
 #define RB_PARSE_CURRENT_TIME_WITHIN (xmlChar *) "current-time-within"
 #define RB_PARSE_CURRENT_TIME_NOT_WITHIN (xmlChar *) "current-time-not-within"
+#define RB_PARSE_PREFIX (xmlChar *) "prefix"
+#define RB_PARSE_SUFFIX (xmlChar *) "suffix"
 
 #define RB_PARSE_NICK_START (xmlChar *) "["
 #define RB_PARSE_NICK_END (xmlChar *) "]"
@@ -2719,6 +2721,8 @@
 		case RHYTHMDB_QUERY_PROP_LESS:
 		case RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN:
 		case RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN:
+		case RHYTHMDB_QUERY_PROP_PREFIX:
+		case RHYTHMDB_QUERY_PROP_SUFFIX:
 			data->propid = va_arg (args, guint);
 			data->val = g_new0 (GValue, 1);
 			g_value_init (data->val, rhythmdb_get_property_type (db, data->propid));
@@ -2849,6 +2853,8 @@
 		case RHYTHMDB_QUERY_PROP_LESS:
 		case RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN:
 		case RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN:
+		case RHYTHMDB_QUERY_PROP_PREFIX:
+		case RHYTHMDB_QUERY_PROP_SUFFIX:
 			g_value_unset (data->val);
 			g_free (data->val);
 			break;
@@ -3018,6 +3024,16 @@
 			xmlSetProp (subnode, RB_PARSE_PROP, rhythmdb_nice_elt_name_from_propid (db, data->propid));
 			write_encoded_gvalue (subnode, data->val);
 			break;
+		case RHYTHMDB_QUERY_PROP_PREFIX:
+			subnode = xmlNewChild (node, NULL, RB_PARSE_PREFIX, NULL);
+			xmlSetProp (subnode, RB_PARSE_PROP, rhythmdb_nice_elt_name_from_propid (db, data->propid));
+			write_encoded_gvalue (subnode, data->val);
+			break;
+		case RHYTHMDB_QUERY_PROP_SUFFIX:
+			subnode = xmlNewChild (node, NULL, RB_PARSE_SUFFIX, NULL);
+			xmlSetProp (subnode, RB_PARSE_PROP, rhythmdb_nice_elt_name_from_propid (db, data->propid));
+			write_encoded_gvalue (subnode, data->val);
+			break;
 		}		
 	}
 }
@@ -3062,6 +3078,10 @@
 			data->type = RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN;
 		} else if (!xmlStrcmp (child->name, RB_PARSE_CURRENT_TIME_NOT_WITHIN)) {
 			data->type = RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN;
+		} else if (!xmlStrcmp (child->name, RB_PARSE_PREFIX)) {
+			data->type = RHYTHMDB_QUERY_PROP_PREFIX;
+		} else if (!xmlStrcmp (child->name, RB_PARSE_SUFFIX)) {
+			data->type = RHYTHMDB_QUERY_PROP_SUFFIX;
 		} else
  			g_assert_not_reached ();
 
@@ -3071,7 +3091,9 @@
 		    || !xmlStrcmp (child->name, RB_PARSE_GREATER)
 		    || !xmlStrcmp (child->name, RB_PARSE_LESS)
 		    || !xmlStrcmp (child->name, RB_PARSE_CURRENT_TIME_WITHIN)
-		    || !xmlStrcmp (child->name, RB_PARSE_CURRENT_TIME_NOT_WITHIN)) {
+		    || !xmlStrcmp (child->name, RB_PARSE_CURRENT_TIME_NOT_WITHIN)
+		    || !xmlStrcmp (child->name, RB_PARSE_PREFIX)
+		    || !xmlStrcmp (child->name, RB_PARSE_SUFFIX)) {
 			xmlChar *propstr = xmlGetProp (child, RB_PARSE_PROP);
 			gint propid = rhythmdb_propid_from_nice_elt_name (db, propstr);
 			g_free (propstr);
@@ -3291,6 +3313,8 @@
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_LESS, "True if property1 <= property2"),
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN, "True if property1 is within property2 of the current time"),
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN, "True if property1 is not within property2 of the current time"),
+			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_PREFIX, "Trug is propety1 starts with property2"),
+			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_SUFFIX, "Trug is propety1 ends with property2"),
 			{ 0, 0, 0 }
 		};
 
Index: rhythmdb/rhythmdb.h
===================================================================
RCS file: /cvs/gnome/rhythmbox/rhythmdb/rhythmdb.h,v
retrieving revision 1.61
diff -u -u -r1.61 rhythmdb.h
--- rhythmdb/rhythmdb.h	30 Nov 2005 22:18:27 -0000	1.61
+++ rhythmdb/rhythmdb.h	7 Dec 2005 02:11:39 -0000
@@ -62,6 +62,8 @@
 	RHYTHMDB_QUERY_PROP_LESS,
 	RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN,
 	RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN,
+	RHYTHMDB_QUERY_PROP_PREFIX,
+	RHYTHMDB_QUERY_PROP_SUFFIX,
 } RhythmDBQueryType;
 
 /* If you modify this enum, don't forget to modify rhythmdb_prop_get_type */
Index: shell/rb-playlist-manager.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/shell/rb-playlist-manager.c,v
retrieving revision 1.75
diff -u -u -r1.75 rb-playlist-manager.c
--- shell/rb-playlist-manager.c	2 Dec 2005 12:42:33 -0000	1.75
+++ shell/rb-playlist-manager.c	7 Dec 2005 02:11:40 -0000
@@ -425,7 +425,7 @@
 		g_object_set (G_OBJECT (action), "sensitive", playlist_local, NULL);
 		action = gtk_action_group_get_action (mgr->priv->actiongroup,
  						      "EditAutomaticPlaylist");
-		g_object_set (G_OBJECT (action), "sensitive", playlist_automatic, NULL);
+		g_object_set (G_OBJECT (action), "sensitive", playlist_automatic && playlist_local, NULL);
 		action = gtk_action_group_get_action (mgr->priv->actiongroup,
  						      "MusicPlaylistRenamePlaylist");
 		g_object_set (G_OBJECT (action), "sensitive", playlist_local, NULL);
@@ -906,6 +906,7 @@
 	guint limit, limit_count = 0, limit_size = 0, limit_time = 0;
 	const char *sort_key;
 	gint sort_direction;
+	GPtrArray *query;
 
 	rb_query_creator_get_limit (creator, &type, &limit);
 	if (type == RB_QUERY_CREATOR_LIMIT_COUNT)
@@ -918,11 +919,12 @@
 		g_assert_not_reached ();
 
 	rb_query_creator_get_sort_order (creator, &sort_key, &sort_direction);
+	query = rb_query_creator_get_query (creator);
 
-	rb_playlist_source_set_query (playlist,
-				      rb_query_creator_get_query (creator),
+	rb_playlist_source_set_query (playlist, query,
 				      limit_count, limit_size, limit_time,
 				      sort_key, sort_direction);
+	rhythmdb_query_free (query);
 }
 
 static void
Index: sources/rb-library-source.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-library-source.c,v
retrieving revision 1.134
diff -u -u -r1.134 rb-library-source.c
--- sources/rb-library-source.c	5 Dec 2005 13:01:04 -0000	1.134
+++ sources/rb-library-source.c	7 Dec 2005 02:11:44 -0000
@@ -48,6 +48,7 @@
 #include "rb-search-entry.h"
 #include "rb-preferences.h"
 #include "rb-shell-preferences.h"
+#include "rb-playlist-source.h"
 
 typedef enum
 {
@@ -147,6 +148,7 @@
 					      RBLibrarySource *source);
 static void rb_library_source_watch_toggled_cb (GtkToggleButton *button,
 						RBLibrarySource *source);
+static void rb_library_source_sync_child_sources (RBLibrarySource *source);
 
 
 #define CONF_UI_LIBRARY_DIR CONF_PREFIX "/ui/library"
@@ -200,6 +202,7 @@
 	GtkFileChooser *library_location_widget;
 	GtkWidget *watch_library_check;
 	gboolean library_location_change_pending, library_location_handle_pending;
+	GList *child_sources;
 	
 	RhythmDBEntryType entry_type;
 
@@ -389,6 +392,8 @@
 {
 	if (source->priv->config_widget)
 		rb_library_source_preferences_sync (source);
+
+	rb_library_source_sync_child_sources (source);
 }
 
 static void
@@ -513,6 +518,14 @@
 
 }
 
+static gboolean
+add_child_sources_idle (RBLibrarySource *source)
+{
+	rb_library_source_sync_child_sources (source);
+
+	return FALSE;
+}
+
 static GObject *
 rb_library_source_constructor (GType type, guint n_construct_properties,
 			       GObjectConstructParam *construct_properties)
@@ -667,6 +680,9 @@
 				    (GConfClientNotifyFunc) rb_library_source_library_location_changed, source);
 
 	rb_library_source_do_query (source, RB_LIBRARY_QUERY_TYPE_ALL);
+
+	g_idle_add ((GSourceFunc)add_child_sources_idle, source);
+
 	return G_OBJECT (source);
 }
 
@@ -1730,5 +1746,54 @@
 
 	active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (source->priv->watch_library_check));
 	eel_gconf_set_boolean (CONF_MONITOR_LIBRARY, active);
+}
+
+static void
+rb_library_source_remove_child_source (RBSource *source, RBLibrarySource *library_source)
+{
+	rb_source_delete_thyself (source);
+}
+
+static void
+rb_library_source_add_child_source (const char *path, RBLibrarySource *library_source)
+{
+	RBSource *source;
+	GPtrArray *query;
+	RBShell *shell;
+	GnomeVFSURI *uri;
+	char *name;
+
+	g_object_get (G_OBJECT (library_source), "shell", &shell, NULL);
+	uri = gnome_vfs_uri_new (path);
+	name = gnome_vfs_uri_extract_short_name (uri);
+	gnome_vfs_uri_unref (uri);
+	
+	source = rb_playlist_source_new (shell, TRUE, FALSE, RHYTHMDB_ENTRY_TYPE_SONG);
+	g_object_set (G_OBJECT (source), "name", name, NULL);
+	query = rhythmdb_query_parse (library_source->priv->db,
+				      RHYTHMDB_QUERY_PROP_PREFIX, RHYTHMDB_PROP_LOCATION, path,
+				      RHYTHMDB_QUERY_END);
+	rb_playlist_source_set_query (RB_PLAYLIST_SOURCE (source), query, 0, 0, 0, NULL, 0);
+	rhythmdb_query_free (query);
+
+	rb_shell_append_source (shell, source, RB_SOURCE (library_source));
+	library_source->priv->child_sources = g_list_prepend (library_source->priv->child_sources, source);
+
+	g_object_unref (shell);
+	g_free (name);
+}
+
+static void
+rb_library_source_sync_child_sources (RBLibrarySource *source)
+{
+	GSList *list = eel_gconf_get_string_list (CONF_LIBRARY_LOCATION);
+
+	g_list_foreach (source->priv->child_sources, (GFunc)rb_library_source_remove_child_source, source);
+	g_list_free (source->priv->child_sources);
+	source->priv->child_sources = NULL;
+
+	g_slist_foreach (list, (GFunc)rb_library_source_add_child_source, source);
+	g_slist_foreach (list, (GFunc) g_free, NULL);
+	g_slist_free (list);
 }
 
Index: sources/rb-playlist-source.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-playlist-source.c,v
retrieving revision 1.91
diff -u -u -r1.91 rb-playlist-source.c
--- sources/rb-playlist-source.c	2 Dec 2005 12:42:33 -0000	1.91
+++ sources/rb-playlist-source.c	7 Dec 2005 02:11:44 -0000
@@ -501,11 +501,10 @@
 	source->priv->query_resetting = TRUE;
 
 	/* playlists that aren't limited, with a particular sort order, are user-orderable */
-	rb_entry_view_set_columns_clickable (source->priv->songs, (limit_count == 0 && limit_mb == 0));
+	rb_entry_view_set_columns_clickable (source->priv->songs, (limit_count == 0 && limit_mb == 0 && limit_time == 0));
 	rb_entry_view_set_sorting_order (source->priv->songs, sort_key, sort_direction);
 
 	rb_playlist_source_do_query (source, query, limit_count, limit_mb, limit_time);
-	rhythmdb_query_free (query);
 	source->priv->query_resetting = FALSE;
 }
 
@@ -704,6 +703,7 @@
 						      subquery,
 						      RHYTHMDB_QUERY_END);
 			rb_playlist_source_set_query (source, query, 0, 0, 0, NULL, 0);
+			rhythmdb_query_free (query);
 		}
 	}
 
@@ -1034,6 +1034,7 @@
 					      limit_time,
 					      sort_key,
 					      sort_direction);
+		rhythmdb_query_free (query);
 		g_free (sort_key);
 	} else {
 		for (child = node->children; child; child = child->next) {
Index: widgets/rb-query-creator-properties.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/widgets/rb-query-creator-properties.c,v
retrieving revision 1.4
diff -u -u -r1.4 rb-query-creator-properties.c
--- widgets/rb-query-creator-properties.c	5 Nov 2005 05:03:19 -0000	1.4
+++ widgets/rb-query-creator-properties.c	7 Dec 2005 02:11:44 -0000
@@ -111,7 +111,9 @@
 {
 	{ N_("contains"), 0, RHYTHMDB_QUERY_PROP_LIKE },
 	{ N_("does not contain"), 0, RHYTHMDB_QUERY_PROP_NOT_LIKE },
-	{ N_("equals"), 1, RHYTHMDB_QUERY_PROP_EQUALS }
+	{ N_("equals"), 1, RHYTHMDB_QUERY_PROP_EQUALS },
+	{ N_("starts with"), 1, RHYTHMDB_QUERY_PROP_PREFIX },
+	{ N_("ends with"), 1, RHYTHMDB_QUERY_PROP_SUFFIX }
 };
 
 const RBQueryCreatorPropertyType string_property_type =

Attachment: signature.asc
Description: This is a digitally signed message part



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