Index: sources/rb-library-child-source.c
===================================================================
--- sources/rb-library-child-source.c	(Revision 0)
+++ sources/rb-library-child-source.c	(Revision 0)
@@ -0,0 +1,353 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ *  Copyright (C) 2008 Christian Becke <christianbecke@gmail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The Rhythmbox authors hereby grants permission for non-GPL compatible
+ *  GStreamer plugins to be used and distributed together with GStreamer
+ *  and Rhythmbox. This permission is above and beyond the permissions granted
+ *  by the GPL license by which Rhythmbox is covered. If you modify this code
+ *  you may extend this exception to your version of the code, but you are not
+ *  obligated to do so. If you do not wish to do so, delete this exception
+ *  statement from your version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gconf/gconf.h>
+
+#include "rhythmdb.h"
+#include "rb-debug.h"
+#include "rb-preferences.h"
+#include "rb-browser-source.h"
+#include "rb-library-child-source.h"
+
+static void rb_library_child_source_class_init (RBLibraryChildSourceClass *klass);
+static void rb_library_child_source_init (RBLibraryChildSource *source);
+static GObject *rb_library_child_source_constructor (GType type,
+							guint n_construct_properties,
+							GObjectConstructParam *construct_properties);
+static void rb_library_child_source_dispose (GObject *object);
+static void rb_library_child_source_finalize (GObject *object);
+static void rb_library_child_source_set_property (GObject *object,
+							guint prop_id,
+							const GValue *value,
+							GParamSpec *pspec);
+static void rb_library_child_source_get_property (GObject *object,
+							guint prop_id,
+							GValue *value,
+							GParamSpec *pspec);
+
+static char *get_state_dir (const char *path);
+static void construct_gconf_keys (RBLibraryChildSource *source);
+
+/* RBSource implementations */
+static char *impl_get_browser_key (RBSource *source);
+static char *impl_get_paned_key (RBBrowserSource *source);
+
+#define CONF_STATE_LIBRARY_DIR CONF_PREFIX "/state/library" /* Move this one to rb-preferences.h? */
+#define CONF_STATE_LIBRARY_CHILD_SORTING "/sorting"
+#define CONF_STATE_LIBRARY_CHILD_PANED_POSITION "/paned_position"
+#define CONF_STATE_LIBRARY_CHILD_SHOW_BROWSER "/show_browser"
+
+struct _RBLibraryChildSourcePrivate
+{
+	char *path;
+	
+	char *browser_key;
+	char *paned_key;
+
+	gboolean gconf_keys_constructed;
+};
+
+enum
+{
+	PROP_0,
+	PROP_PATH
+};
+
+#define RB_LIBRARY_CHILD_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_LIBRARY_CHILD_SOURCE, RBLibraryChildSourcePrivate))
+G_DEFINE_TYPE (RBLibraryChildSource, rb_library_child_source, RB_TYPE_BROWSER_SOURCE);
+
+static void
+rb_library_child_source_class_init (RBLibraryChildSourceClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	RBSourceClass *source_class = RB_SOURCE_CLASS (klass);
+	RBBrowserSourceClass *browser_source_class = RB_BROWSER_SOURCE_CLASS (klass);
+
+	object_class->constructor = rb_library_child_source_constructor;
+	object_class->dispose = rb_library_child_source_dispose;
+	object_class->finalize = rb_library_child_source_finalize;
+	object_class->get_property = rb_library_child_source_get_property;
+	object_class->set_property = rb_library_child_source_set_property;
+
+	source_class->impl_get_browser_key = impl_get_browser_key;
+
+	browser_source_class->impl_get_paned_key = impl_get_paned_key;
+
+	g_object_class_install_property (object_class,
+					PROP_PATH,
+					g_param_spec_string ("path",
+							"path",
+							"Path to library",
+							NULL,
+							G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	
+	g_type_class_add_private (klass, sizeof (RBLibraryChildSourcePrivate));
+}
+
+static void
+rb_library_child_source_init (RBLibraryChildSource *source)
+{
+	source->priv = RB_LIBRARY_CHILD_SOURCE_GET_PRIVATE (source);
+
+	source->priv->gconf_keys_constructed = FALSE;
+}
+
+
+static GObject *
+rb_library_child_source_constructor (GType type,
+					guint n_construct_properties,
+					GObjectConstructParam *construct_properties)
+{
+	RBLibraryChildSource *source;
+	RhythmDBQueryModel *query_model;
+	RhythmDBQuery *query;
+	RBShell *shell;
+	RhythmDB *db;
+	RhythmDBEntryType *entry_type;
+	char *path;
+
+	source = RB_LIBRARY_CHILD_SOURCE (G_OBJECT_CLASS (rb_library_child_source_parent_class)->
+			constructor (type, n_construct_properties, construct_properties));
+
+	g_object_get (source,
+			"shell", &shell,
+			"entry-type", &entry_type,
+			"path", &path,
+			"base-query-model", &query_model,
+			NULL);
+	g_object_get (shell, "db", &db, NULL);
+	g_object_unref (shell);
+
+	query = rhythmdb_query_parse (db,
+			RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, entry_type,
+			RHYTHMDB_QUERY_PROP_PREFIX, RHYTHMDB_PROP_LOCATION, path,
+			RHYTHMDB_QUERY_END);
+	g_object_set (query_model, "query", query, NULL);
+	rhythmdb_query_free (query);
+	g_object_unref (db);
+	g_object_unref (query_model);
+	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
+	g_free (path);
+
+	return G_OBJECT (source);
+}
+
+static void
+rb_library_child_source_dispose (GObject *object)
+{
+	RBLibraryChildSource *source;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (RB_IS_LIBRARY_CHILD_SOURCE (object));
+
+	source = RB_LIBRARY_CHILD_SOURCE (object);
+
+	g_return_if_fail (source->priv != NULL);
+
+	G_OBJECT_CLASS (rb_library_child_source_parent_class)->dispose (object);
+}
+
+static void
+rb_library_child_source_finalize (GObject *object)
+{
+	RBLibraryChildSource *source;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (RB_IS_LIBRARY_CHILD_SOURCE (object));
+
+	source = RB_LIBRARY_CHILD_SOURCE (object);
+
+	g_return_if_fail (source->priv != NULL);
+
+	if (source->priv->path != NULL) {
+		g_free (source->priv->path);
+		source->priv->path = NULL;
+	}
+
+	if (source->priv->browser_key != NULL) {
+		g_free (source->priv->browser_key);
+		source->priv->browser_key = NULL;
+	}
+
+	if (source->priv->paned_key != NULL) {
+		g_free (source->priv->paned_key);
+		source->priv->paned_key = NULL;
+	}
+
+	G_OBJECT_CLASS (rb_library_child_source_parent_class)->finalize (object);
+}
+
+static void
+rb_library_child_source_set_property (GObject *object,
+					guint prop_id,
+					const GValue *value,
+					GParamSpec *pspec)
+{
+	RBLibraryChildSource *source = RB_LIBRARY_CHILD_SOURCE (object);
+
+	switch (prop_id) {
+	case PROP_PATH:
+		source->priv->path = g_strdup (g_value_get_string (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+rb_library_child_source_get_property (GObject *object,
+					guint prop_id,
+					GValue *value,
+					GParamSpec *pspec)
+{
+	RBLibraryChildSource *source = RB_LIBRARY_CHILD_SOURCE (object);
+
+	switch (prop_id) {
+	case PROP_PATH:
+		g_value_set_string (value, source->priv->path);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+RBSource *
+rb_library_child_source_new (RBSource *parent_source, const char *path)
+{
+	RBSource *source;
+	RBShell *shell;
+	RhythmDBEntryType *entry_type;
+	GnomeVFSURI *uri;
+	GdkPixbuf *icon;
+	char *name;
+	char *state_dir;
+	char *sorting_key;
+
+	uri = gnome_vfs_uri_new (path);
+	name = gnome_vfs_uri_extract_short_name (uri);
+	gnome_vfs_uri_unref (uri);
+
+	g_object_get (parent_source,
+			"shell", &shell,
+			"entry-type", &entry_type,
+			"icon", &icon,
+			NULL);	
+	
+	state_dir = get_state_dir (path);
+	sorting_key = g_strconcat (state_dir, CONF_STATE_LIBRARY_CHILD_SORTING, NULL);
+	g_free (state_dir);
+
+	source = RB_SOURCE (g_object_new (RB_TYPE_LIBRARY_CHILD_SOURCE,
+					"name", name,
+					"shell", shell,
+					"path", path,
+					"entry-type", entry_type,
+					"sorting-key", sorting_key,
+					"source-group", RB_SOURCE_GROUP_LIBRARY,
+					"icon", icon,
+					NULL));
+	
+	g_free (name);
+	g_object_unref (shell);
+	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);	
+	g_free (sorting_key);
+	if (icon != NULL) {
+		g_object_unref (icon);
+	}
+
+	return source;
+}
+
+static char *
+get_state_dir (const char *path)
+{
+	char *state_dir;
+	char *path_escaped;
+
+	path_escaped = gconf_escape_key (path, strlen (path));
+	state_dir = g_strconcat (CONF_STATE_LIBRARY_DIR, "/", path_escaped, NULL);
+	g_free (path_escaped);
+	
+	return state_dir;
+}
+
+static void
+construct_gconf_keys (RBLibraryChildSource *source)
+{
+	RBLibraryChildSourcePrivate *priv;
+	priv = RB_LIBRARY_CHILD_SOURCE_GET_PRIVATE (source);
+
+	if (priv->gconf_keys_constructed == TRUE) {
+		return;
+	}
+
+	priv->gconf_keys_constructed = TRUE;
+
+	char *path;
+	char *state_dir;
+
+	g_object_get (source, "path", &path, NULL);
+	state_dir = get_state_dir (path);
+	g_free (path);
+
+	priv->browser_key = g_strconcat (state_dir, CONF_STATE_LIBRARY_CHILD_SHOW_BROWSER, NULL);
+	priv->paned_key = g_strconcat (state_dir, CONF_STATE_LIBRARY_CHILD_PANED_POSITION, NULL);
+	g_free (state_dir);
+}
+
+static char *
+impl_get_browser_key (RBSource *source)
+{
+	RBLibraryChildSourcePrivate *priv;
+	priv = RB_LIBRARY_CHILD_SOURCE_GET_PRIVATE (RB_LIBRARY_CHILD_SOURCE (source));
+
+	if (priv->gconf_keys_constructed == FALSE) {
+		construct_gconf_keys (RB_LIBRARY_CHILD_SOURCE (source));
+	}
+
+	return g_strdup (priv->browser_key);
+}
+
+static char *
+impl_get_paned_key (RBBrowserSource *source)
+{
+	RBLibraryChildSourcePrivate *priv;
+	priv = RB_LIBRARY_CHILD_SOURCE_GET_PRIVATE (RB_LIBRARY_CHILD_SOURCE (source));
+
+	if (priv->gconf_keys_constructed == FALSE) {
+		construct_gconf_keys (RB_LIBRARY_CHILD_SOURCE (source));
+	}
+
+	return g_strdup (priv->paned_key);
+}
+
Index: sources/rb-library-child-source.h
===================================================================
--- sources/rb-library-child-source.h	(Revision 0)
+++ sources/rb-library-child-source.h	(Revision 0)
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (C) 2008 Christian Becke <christianbecke@gmail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The Rhythmbox authors hereby grants permission for non-GPL compatible
+ *  GStreamer plugins to be used and distributed together with GStreamer
+ *  and Rhythmbox. This permission is above and beyond the permissions granted
+ *  by the GPL license by which Rhythmbox is covered. If you modify this code
+ *  you may extend this exception to your version of the code, but you are not
+ *  obligated to do so. If you do not wish to do so, delete this exception
+ *  statement from your version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ */
+
+#ifndef __RB_LIBRARY_CHILD_SOURCE_H
+#define __RB_LIBRARY_CHILD_SOURCE_H
+
+#include "rb-browser-source.h"
+
+G_BEGIN_DECLS
+
+#define RB_TYPE_LIBRARY_CHILD_SOURCE         (rb_library_child_source_get_type ())
+#define RB_LIBRARY_CHILD_SOURCE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_LIBRARY_CHILD_SOURCE, RBLibraryChildSource))
+#define RB_LIBRARY_CHILD_SOURCE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_LIBRARY_CHILD_SOURCE, RBLibraryChildSourceClass))
+#define RB_IS_LIBRARY_CHILD_SOURCE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_LIBRARY_CHILD_SOURCE))
+#define RB_IS_LIBRARY_CHILD_SOURCE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_LIBRARY_CHILD_SOURCE))
+#define RB_LIBRARY_CHILD_SOURCE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_LIBRARY_CHILD_SOURCE, RBLibraryChildSourceClass))
+
+typedef struct _RBLibraryChildSourcePrivate RBLibraryChildSourcePrivate;
+
+typedef struct
+{
+	RBBrowserSource parent;
+
+	RBLibraryChildSourcePrivate *priv;
+} RBLibraryChildSource;
+
+typedef struct
+{
+	RBBrowserSourceClass parent;
+} RBLibraryChildSourceClass;
+
+GType		rb_library_child_source_get_type 	(void);
+RBSource *	rb_library_child_source_new		(RBSource *parent_source, const char *path);
+
+G_END_DECLS
+
+#endif /* __RB_LIBRARY_CHILD_SOURCE_H */
Index: sources/rb-library-source.c
===================================================================
--- sources/rb-library-source.c	(Revision 5738)
+++ sources/rb-library-source.c	(Arbeitskopie)
@@ -52,6 +52,7 @@
 #include "rb-library-source.h"
 #include "rb-removable-media-manager.h"
 #include "rb-auto-playlist-source.h"
+#include "rb-library-child-source.h"
 
 static void rb_library_source_class_init (RBLibrarySourceClass *klass);
 static void rb_library_source_init (RBLibrarySource *source);
@@ -1333,55 +1334,18 @@
 rb_library_source_add_child_source (const char *path, RBLibrarySource *library_source)
 {
 	RBSource *source;
-	GPtrArray *query;
 	RBShell *shell;
-	GnomeVFSURI *uri;
-	char *name;
-	GdkPixbuf *icon;
-	RhythmDBEntryType entry_type;
-	char *sort_column;
-	int sort_order;
 
 	g_object_get (library_source,
 		      "shell", &shell,
-		      "entry-type", &entry_type,
 		      NULL);
-	uri = gnome_vfs_uri_new (path);
-	if (uri == NULL) {
-		g_object_unref (shell);
-		g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
-		return;
-	}
-
-	name = gnome_vfs_uri_extract_short_name (uri);
-	gnome_vfs_uri_unref (uri);
-
-	rb_entry_view_get_sorting_order (rb_source_get_entry_view (RB_SOURCE (library_source)),
-					 &sort_column, &sort_order);
-
-	source = rb_auto_playlist_source_new (shell, name, FALSE);
-	query = rhythmdb_query_parse (library_source->priv->db,
-				      RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, entry_type,
-				      RHYTHMDB_QUERY_PROP_PREFIX, RHYTHMDB_PROP_LOCATION, path,
-				      RHYTHMDB_QUERY_END);
-	rb_auto_playlist_source_set_query (RB_AUTO_PLAYLIST_SOURCE (source), query,
-					   RHYTHMDB_QUERY_MODEL_LIMIT_NONE, NULL,
-					   sort_column, sort_order);
-	rhythmdb_query_free (query);
-	g_free (sort_column);
-
-	g_object_get (library_source, "icon", &icon, NULL);
-	g_object_set (source, "icon", icon, NULL);
-	if (icon != NULL) {
-		g_object_unref (icon);
-	}
-
+	
+	source = rb_library_child_source_new (RB_SOURCE (library_source), path);
+	
 	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_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
 	g_object_unref (shell);
-	g_free (name);
 }
 
 static void
Index: sources/rb-browser-source.c
===================================================================
--- sources/rb-browser-source.c	(Revision 5738)
+++ sources/rb-browser-source.c	(Arbeitskopie)
@@ -864,8 +864,8 @@
 rb_browser_source_do_query (RBBrowserSource *source, gboolean subset)
 {
 	RhythmDBQueryModel *query_model;
+	GPtrArray *base_query;
 	GPtrArray *query;
-	RhythmDBEntryType entry_type;
 
 	/* use the cached 'all' query to optimise the no-search case */
 	if (!source->priv->search_text) {
@@ -875,16 +875,14 @@
 		return;
 	}
 
-	g_object_get (source, "entry-type", &entry_type, NULL);
-	query = rhythmdb_query_parse (source->priv->db,
-				      RHYTHMDB_QUERY_PROP_EQUALS,
-				      RHYTHMDB_PROP_TYPE,
-				      entry_type,
-				      RHYTHMDB_QUERY_PROP_LIKE,
-				      source->priv->search_prop,
-				      source->priv->search_text,
-				      RHYTHMDB_QUERY_END);
-	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
+	g_object_get (source->priv->cached_all_query, "query", &base_query, NULL);
+	query = rhythmdb_query_copy (base_query);
+	rhythmdb_query_append (source->priv->db,
+				query,
+				RHYTHMDB_QUERY_PROP_LIKE,
+				source->priv->search_prop,
+				source->priv->search_text,
+				RHYTHMDB_QUERY_END);
 
 	if (subset) {
 		/* if we're appending text to an existing search string, the results will be a subset
Index: sources/Makefile.am
===================================================================
--- sources/Makefile.am	(Revision 5738)
+++ sources/Makefile.am	(Arbeitskopie)
@@ -37,6 +37,8 @@
 	rb-missing-files-source.h	\
 	rb-import-errors-source.c	\
 	rb-import-errors-source.h	\
+	rb-library-child-source.c	\
+	rb-library-child-source.h	\
 	$(NULL)
 
 INCLUDES =						\
