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 =
