[Rhythmbox-devel] sync patches



Hello,

Here are some patches to sync up parts of the rb and netrb trees.

The first is some fixes to the node stuff.  I fixed a double-free in the
rbglistwrapper decode path, and also changed the type tests to allow for
inheritance (so RBNodeStation works).

The second patch re-adds the "get_random_node" method to the RBNodeView,
since I need it, and I think the future RB will too.  It also adds the
concept of "allowed-columns".  Basically now in the netrb HEAD the
individual view column selectors are gone, and when you enable a column,
it affects all node views where possible.  The idea behind
allowed-columns is that the iradio nodeview can say it can't display
artist/album, for example.

The third patch just syncs the rb iradio tree with the netrb one.


--- rhythmbox-HEAD/library/rb-node.c	2003-01-19 15:21:26.000000000 -0500
+++ net-rhythmbox/library/rb-node.c	2003-05-03 05:34:11.000000000 -0400
@@ -1015,7 +1015,7 @@
 
 			xmlSetProp (value_xml_node, "object_type", g_type_name (obj_type));
 
-			if (obj_type == RB_TYPE_GLIST_WRAPPER) {
+			if (RB_IS_GLIST_WRAPPER (obj)) {
 				RBGListWrapper *listwrap = RB_GLIST_WRAPPER (obj);
 				GList *cur;
 
@@ -1026,9 +1026,7 @@
 					xmlNodeSetContent (subnode, xml);
 					g_free (xml);
 				}
-
-				break;
-			} else if (obj_type == RB_TYPE_NODE) {
+			} else if (RB_IS_NODE (obj)) {
 				RBNode *prop_node;
 
 				prop_node = RB_NODE (obj);
@@ -1042,12 +1040,10 @@
 				g_free (xml);
 
 				g_static_rw_lock_reader_unlock (prop_node->priv->lock);
-
-				break;
 			} else {
 				g_assert_not_reached ();
-				break;
 			}
+			break;
 		}
 		default:
 			g_assert_not_reached ();
@@ -1166,33 +1162,27 @@
 				 * we could do something truly evil
 				 * using dlopen(), but let's not think
 				 * about that. */
-				if (obj_type == RB_TYPE_GLIST_WRAPPER) {
+				if (g_type_is_a (obj_type, RB_TYPE_GLIST_WRAPPER)) {
 					GList *newlist = NULL;
 					xmlNodePtr list_child;
 					RBGListWrapper *listwrapper = rb_glist_wrapper_new (NULL);
 
-					/* Free the unneeded string allocated above */
-					g_free (xml);
-
 					for (list_child = xml_child; list_child; list_child = list_child->next)
-						newlist = g_list_prepend (newlist, xmlNodeGetContent (xml_child));
+						newlist = g_list_prepend (newlist, xmlNodeGetContent (list_child));
 
 					rb_glist_wrapper_set_list (listwrapper, newlist);
 
 					g_value_set_pointer (value, listwrapper);
 
-					break;
-				} else if (obj_type == RB_TYPE_NODE) {
+				} else if (g_type_is_a (obj_type, RB_TYPE_NODE)) {
 					RBNode *property_node;
 
 					property_node = node_from_id_real (atol (xml));
 
 					g_value_set_pointer (value, property_node);
 
-					break;
 				} else {
 					g_assert_not_reached ();
-					break;
 				}
 
 				break;
--- rhythmbox-HEAD/lib/widgets/rb-node-view.h	2003-01-05 09:38:09.000000000 -0500
+++ net-rhythmbox/lib/widgets/rb-node-view.h	2003-05-03 13:54:28.000000000 -0400
@@ -94,6 +94,8 @@
 				                   RBNode *start,
 				                   RBDirection direction);
 
+RBNode *    rb_node_view_get_random_node	  (RBNodeView *view);
+
 void	    rb_node_view_enable_drag_source       (RBNodeView *view,
 					           const GtkTargetEntry *targets,
 					           int n_targets);
--- rhythmbox-HEAD/lib/widgets/rb-node-view.c	2003-01-24 18:49:43.000000000 -0500
+++ net-rhythmbox/lib/widgets/rb-node-view.c	2003-05-03 05:07:51.000000000 -0400
@@ -37,9 +37,11 @@
 #include "rb-tree-model-sort.h"
 #include "rb-node-view.h"
 #include "rb-dialog.h"
+#include "rb-debug.h"
 #include "rb-cell-renderer-pixbuf.h"
 #include "rb-cell-renderer-rating.h"
 #include "rb-node-song.h"
+#include "rb-node-station.h"
 #include "rb-string-helpers.h"
 #include "rb-library-dnd-types.h"
 #include "rb-stock-icons.h"
@@ -140,6 +142,7 @@
 	char *columns_key;
 	guint gconf_notification_id;
 	GHashTable *columns;
+	GHashTable *allowed_columns;
 
 	RBNodeFilter *filter;
 
@@ -578,6 +581,28 @@
 	return retval;
 }
 
+GList *
+parse_columns_as_glist (const char *str)
+{
+	GList *ret = NULL;
+	char **parts = g_strsplit (str, ",", 0);
+	int i;
+	GEnumClass *class = g_type_class_ref (RB_TYPE_TREE_MODEL_NODE_COLUMN);
+	GEnumValue *ev;
+	
+	for (i = 0; parts != NULL && parts[i] != NULL; i++)
+	{
+		RBTreeModelNodeColumn col;
+		ev = g_enum_get_value_by_name (class, parts[i]);
+		col = ev->value;
+		ret = g_list_append (ret, GINT_TO_POINTER (col));
+	}
+	
+	g_strfreev (parts);
+	g_type_class_unref (class);
+	return ret;
+}
+
 static void
 rb_node_view_construct (RBNodeView *view)
 {
@@ -592,6 +617,7 @@
 				 0);
 
 	view->priv->columns = g_hash_table_new (NULL, NULL);
+	view->priv->allowed_columns = g_hash_table_new (NULL, NULL);
 	view->priv->nodemodel = rb_tree_model_node_new (view->priv->root,
 							view->priv->filter);
 	view->priv->filtermodel = egg_tree_model_filter_new (GTK_TREE_MODEL (view->priv->nodemodel),
@@ -646,6 +672,7 @@
 	gtk_container_add (GTK_CONTAINER (view), view->priv->treeview);
 
 	/* load layout */
+	rb_debug ("loading layout from %s", view->priv->view_desc_file);
 	doc = xmlParseFile (view->priv->view_desc_file);
 
 	if (doc == NULL)
@@ -677,23 +704,19 @@
 
 	tmp = xmlGetProp (doc->children, "search-order");
 	if (tmp != NULL)
-	{
-		char **parts = g_strsplit (tmp, " ", 0);
-		int i;
-		GEnumClass *class = g_type_class_ref (RB_TYPE_TREE_MODEL_NODE_COLUMN);
-		GEnumValue *ev;
+		view->priv->search_columns = parse_columns_as_glist (tmp);
+	g_free (tmp);
 
-		for (i = 0; parts != NULL && parts[i] != NULL; i++)
-		{
-			RBTreeModelNodeColumn col;
-			ev = g_enum_get_value_by_name (class, parts[i]);
-			col = ev->value;
-			view->priv->search_columns = g_list_append (view->priv->search_columns, GINT_TO_POINTER (col));
+	tmp = xmlGetProp (doc->children, "allowed-columns");
+	if (tmp != NULL) {
+		GList *l = parse_columns_as_glist (tmp);
+		for (; l != NULL; l = g_list_next (l)) {
+			g_hash_table_insert (view->priv->allowed_columns,
+					     l->data, GINT_TO_POINTER (1));
 		}
-
-		g_strfreev (parts);
-		g_type_class_unref (class);
+		g_list_free (l);
 	}
+	rb_debug ("allowed columns: %s", tmp);
 	g_free (tmp);
 
 	tmp = xmlGetProp (doc->children, "keep-selection");
@@ -884,6 +907,7 @@
 
 		rb_tree_view_column_set_expand (RB_TREE_VIEW_COLUMN (gcolumn), expand);
 
+		rb_debug ("appending column; %s", xmlGetProp (child, "column"));
 		gtk_tree_view_append_column (GTK_TREE_VIEW (view->priv->treeview),
 					     gcolumn);
 
@@ -1025,7 +1049,8 @@
 	GValue val = {0, };
 	gboolean visible;
 
-	g_assert (start != NULL);
+	if (start == NULL)
+		return NULL;
 
 	rb_tree_model_node_iter_from_node (RB_TREE_MODEL_NODE (view->priv->nodemodel),
 					   start, &iter);
@@ -1156,6 +1181,68 @@
 }
 
 static int
+rb_node_view_get_n_rows (RBNodeView *view)
+{
+	GPtrArray *kids;
+	int n_rows = 0, i;
+
+	kids = rb_node_get_children (view->priv->root);
+	
+	for (i = 0; i < kids->len; i++)
+	{
+		RBNode *node;
+
+		node = g_ptr_array_index (kids, i);
+
+		if (view->priv->filter != NULL &&
+		    rb_node_filter_evaluate (view->priv->filter, node) == FALSE)
+			continue;
+
+		n_rows++;
+	}
+
+	rb_node_thaw (view->priv->root);
+
+	return n_rows;
+}
+
+RBNode *
+rb_node_view_get_random_node (RBNodeView *view)
+{
+	RBNode *node;
+	GtkTreePath *path;
+	GtkTreeIter iter, iter2;
+	char *path_str;
+	int index, n_rows;
+
+	n_rows = rb_node_view_get_n_rows (view);
+	if (n_rows == 0)
+		return NULL;
+	else if ((n_rows - 1) > 0)
+		index = g_random_int_range (0, n_rows - 1);
+	else
+		index = 0;
+
+	path_str = g_strdup_printf ("%d", index);
+	path = gtk_tree_path_new_from_string (path_str);
+	g_free (path_str);
+
+	gtk_tree_model_get_iter (GTK_TREE_MODEL (view->priv->sortmodel),
+				 &iter, path);
+
+	gtk_tree_path_free (path);
+
+	gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (view->priv->sortmodel),
+							&iter2, &iter);
+	egg_tree_model_filter_convert_iter_to_child_iter (EGG_TREE_MODEL_FILTER (view->priv->filtermodel),
+							  &iter, &iter2);
+
+	node = rb_tree_model_node_node_from_iter (RB_TREE_MODEL_NODE (view->priv->nodemodel), &iter);
+
+	return node;
+}
+
+static int
 rb_node_view_sort_func (GtkTreeModel *model,
 			GtkTreeIter *a,
 			GtkTreeIter *b,
@@ -1577,6 +1664,11 @@
 			    && (ev->value >= 0)
 			    && (ev->value < RB_TREE_MODEL_NODE_NUM_COLUMNS))
 			{
+				if (g_hash_table_lookup (view->priv->allowed_columns,
+							 GINT_TO_POINTER (ev->value)) == NULL) {
+					rb_debug ("column %s is not allowed", items[i]);
+					continue;
+				}
 				visible_columns = g_list_append (visible_columns,
 								 GINT_TO_POINTER (ev->value));
 			}
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/.cvsignore net-rhythmbox/iradio/.cvsignore
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/Makefile.am net-rhythmbox/iradio/Makefile.am
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/rb-iradio-backend.c net-rhythmbox/iradio/rb-iradio-backend.c
--- rhythmbox-HEAD/iradio/rb-iradio-backend.c	2002-12-10 23:27:15.000000000 -0500
+++ net-rhythmbox/iradio/rb-iradio-backend.c	2003-05-03 04:53:34.000000000 -0400
@@ -1,5 +1,5 @@
 /* 
- *  Copyright (C) 2002 Colin Walters <walters@gnu.org>
+ *  Copyright (C) 2002,2003 Colin Walters <walters@gnu.org>
  *
  *  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
@@ -15,7 +15,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- *  $Id: rb-iradio-backend.c,v 1.2 2002/12/11 04:27:15 cwalters Exp $
+ *  $Id: rb-iradio-backend.c,v 1.1 2002/12/10 22:30:52 cwalters Exp $
  */
 
 #include <config.h>
@@ -34,6 +34,7 @@
 #include "rb-iradio-yp-xmlfile.h"
 #include "rb-debug.h"
 #include "rb-dialog.h"
+#include "rb-echo-area.h"
 #include "rb-file-helpers.h"
 #include "rb-stock-icons.h"
 #include "rb-node-station.h"
@@ -43,6 +44,14 @@
 static void rb_iradio_backend_class_init (RBIRadioBackendClass *klass);
 static void rb_iradio_backend_init (RBIRadioBackend *view);
 static void rb_iradio_backend_finalize (GObject *object);
+static void rb_iradio_backend_set_property (GObject *object,
+					    guint prop_id,
+					    const GValue *value,
+					    GParamSpec *pspec);
+static void rb_iradio_backend_get_property (GObject *object,
+					    guint prop_id,
+					    GValue *value,
+					    GParamSpec *pspec);
 
 static void rb_iradio_backend_save (RBIRadioBackend *backend);
 static void genre_added_cb (RBNode *node, RBNode *child, RBIRadioBackend *backend);
@@ -60,11 +69,27 @@
 	GHashTable *genre_hash;
 	GStaticRWLock *genre_hash_lock;
 
+	RBEchoArea *echoarea;
+
 	char *xml_file;
 };
 
+enum
+{
+	PROP_0,
+	PROP_ECHO_AREA,
+};
+
+enum
+{
+	CHANGED,
+	LAST_SIGNAL,
+};
+
 static GObjectClass *parent_class = NULL;
 
+static guint rb_iradio_backend_signals[LAST_SIGNAL] = { 0 };
+
 GType
 rb_iradio_backend_get_type (void)
 {
@@ -101,6 +126,27 @@
 	
 	parent_class = g_type_class_peek_parent (klass);
 	
+	object_class->set_property = rb_iradio_backend_set_property;
+	object_class->get_property = rb_iradio_backend_get_property;
+
+	g_object_class_install_property (object_class,
+					 PROP_ECHO_AREA,
+					 g_param_spec_object ("echoarea",
+							      "Echo area",
+							      "Echo area",
+							      RB_TYPE_ECHO_AREA,
+							      G_PARAM_READWRITE));
+
+	rb_iradio_backend_signals[CHANGED] =
+		g_signal_new ("changed",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (RBIRadioBackendClass, changed),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
+
 	object_class->finalize = rb_iradio_backend_finalize;
 
 }
@@ -108,6 +154,7 @@
 static void
 rb_iradio_backend_init (RBIRadioBackend *backend)
 {
+	char *libname = g_strdup_printf ("iradio-%s.xml", RB_IRADIO_BACKEND_XML_VERSION);
 	GValue value = { 0, };
 
 	/* ensure these types have been registered: */
@@ -117,9 +164,11 @@
 
 	backend->priv = g_new0(RBIRadioBackendPrivate, 1);
 	backend->priv->xml_file = g_build_filename (rb_dot_dir (),
-						    "iradio.xml",
+						    libname,
 						    NULL);
 
+	g_free (libname);
+
 	backend->priv->genre_hash = g_hash_table_new (g_str_hash,
 						      g_str_equal);
 
@@ -170,7 +219,45 @@
 
 	rb_node_add_child (backend->priv->all_genres,
 			   backend->priv->all_stations);
-	fprintf(stderr, "backend: created\n");
+}
+
+static void
+rb_iradio_backend_set_property (GObject *object,
+				guint prop_id,
+				const GValue *value,
+				GParamSpec *pspec)
+{
+	RBIRadioBackend *backend = RB_IRADIO_BACKEND (object);
+
+	switch (prop_id)
+	{
+	case PROP_ECHO_AREA:
+		backend->priv->echoarea = g_value_get_object (value);
+		g_object_ref (backend->priv->echoarea);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+rb_iradio_backend_get_property (GObject *object,
+				guint prop_id,
+				GValue *value,
+				GParamSpec *pspec)
+{
+	RBIRadioBackend *backend = RB_IRADIO_BACKEND (object);
+
+	switch (prop_id)
+	{
+	case PROP_ECHO_AREA:
+		g_value_set_object (value, backend->priv->echoarea);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
 }
 
 static void
@@ -187,19 +274,13 @@
 
 	g_return_if_fail (backend->priv != NULL);
 
-	fprintf (stderr, "backend: finalizing\n");
+	rb_iradio_backend_save (backend);
 
-	fprintf (stderr, "FIXME: iradio saving disabled because it's broken right now\n");
-/*  	rb_iradio_backend_save (backend); */
-
-/* 	children = rb_node_get_children (backend->priv->all_stations); */
-/* 	rb_node_thaw (backend->priv->all_stations); */
-/* 	for (i = children->len - 1; i >= 0; i--) { */
-/* 		rb_node_unref (g_ptr_array_index (children, i)); */
-/* 	} */
-
-	g_hash_table_destroy (backend->priv->genre_hash);
-	g_static_rw_lock_free (backend->priv->genre_hash_lock);
+	children = rb_node_get_children (backend->priv->all_stations);
+	rb_node_thaw (backend->priv->all_stations);
+	for (i = children->len - 1; i >= 0; i--) {
+		rb_node_unref (g_ptr_array_index (children, i));
+	}
 	
 	rb_node_unref (backend->priv->all_stations);
 	rb_node_unref (backend->priv->all_genres);
@@ -261,7 +342,6 @@
 {
 	g_static_rw_lock_writer_lock (backend->priv->genre_hash_lock);
 
-	fprintf(stderr, "inserting genre %s\n", rb_node_get_property_string (child, RB_NODE_PROP_NAME));
 	g_hash_table_insert (backend->priv->genre_hash,
 			     (char *) rb_node_get_property_string (child, RB_NODE_PROP_NAME),
 			     child);
@@ -276,7 +356,6 @@
 {
 	g_static_rw_lock_writer_lock (backend->priv->genre_hash_lock);
 	
-	fprintf(stderr, "removing genre %s\n", rb_node_get_property_string (child, RB_NODE_PROP_NAME));
 	g_hash_table_remove (backend->priv->genre_hash,
 			     rb_node_get_property_string (child, RB_NODE_PROP_NAME));
 	
@@ -285,39 +364,61 @@
 static void
 load_initial (RBIRadioBackend *backend)
 {
+	guint taskid;
 	const char *initial_file = rb_file ("iradio-initial.xml");
-	RBIRadioYPIterator *it = RB_IRADIO_YP_ITERATOR (g_object_new (RB_TYPE_IRADIO_YP_XMLFILE,
-								      "filename", initial_file,
-								      NULL));
+	RBIRadioYPIterator *it;
 	RBIRadioStation *station;
 
-	fprintf(stderr, "loading %s\n", initial_file);
+	if (!initial_file)
+	{
+		rb_error_dialog (_("Unable to find file \"iradio-initial.xml\""));
+		return;
+	}
+	
+	it = RB_IRADIO_YP_ITERATOR (g_object_new (RB_TYPE_IRADIO_YP_XMLFILE,
+						  "filename", initial_file,
+						  NULL));
+
+	taskid = rb_echo_area_begin_task (backend->priv->echoarea,
+					  _("Loading Internet Radio stations..."));
+
+	rb_debug ("iradio-backend: loading initial stations");
 	while ((station = rb_iradio_yp_iterator_get_next_station (it)) != NULL) {
-		const char *genre;
-		const char *name;
+		const char *genre = NULL;
+		const char *name = NULL;
 		GList *locations;
 		RBNodeStation *nodestation;
 
 		g_assert (RB_IS_IRADIO_STATION (station));
 
-		g_object_get(G_OBJECT(station), "genre", &genre, NULL);
-		g_object_get(G_OBJECT(station), "name", &name, NULL);
-		g_object_get(G_OBJECT(station), "locations", &locations, NULL);
+		g_object_get (G_OBJECT(station), "genre", &genre, NULL);
+		g_assert (genre != NULL);
+		g_object_get (G_OBJECT(station), "name", &name, NULL);
+		g_assert (name != NULL);
+		g_object_get (G_OBJECT(station), "locations", &locations, NULL);
 
-		fprintf(stderr, "adding station: %s %s\n", genre, name);
-		
+		g_assert (G_IS_OBJECT (backend));
+		g_assert (RB_IS_IRADIO_BACKEND (backend));
 		nodestation = rb_node_station_new (locations, name, genre, "initial", backend);
 	}
+	rb_echo_area_end_task (backend->priv->echoarea, taskid);
+	rb_debug ("iradio-backend: done loading initial stations");
 	g_free ((char *) initial_file);
 	g_object_unref (G_OBJECT (it));
+	g_signal_emit (G_OBJECT (backend), rb_iradio_backend_signals[CHANGED], 0);
 }
 	
-
 void rb_iradio_backend_load (RBIRadioBackend *backend)
 {
 	xmlDocPtr doc;
 	xmlNodePtr root, child;
 	char *tmp;
+	guint taskid;
+
+	rb_debug ("iradio-backend: loading");
+
+	taskid = rb_echo_area_begin_task (backend->priv->echoarea,
+					  _("Loading Internet Radio stations..."));
 
 	if (g_file_test (backend->priv->xml_file, G_FILE_TEST_EXISTS) == FALSE)
 		goto loadinitial;
@@ -331,6 +432,7 @@
 		goto loadinitial;
 	}
 
+
 	root = xmlDocGetRootElement (doc);
 
 	tmp = xmlGetProp (root, "version");
@@ -347,17 +449,22 @@
 	for (child = root->children; child != NULL; child = child->next)
 	{
 		/* This automagically sets up the tree structure */
-		rb_node_new_from_xml (child);
-
-		if (RB_IS_NODE_STATION (child))
+		RBNode *node = rb_node_new_from_xml (child);
+		rb_debug ("iradio-backend: loaded node %p", node);
+		if (node != NULL)
 		{
-/* 			rb_node_station_sync (child, backend); */
+			if (RB_IS_NODE_STATION (node))
+			{
+/* 			rb_node_station_sync (node, backend); */
+			}
 		}
 	}
-
+	rb_echo_area_end_task (backend->priv->echoarea, taskid);
 	xmlFreeDoc (doc);
+	g_signal_emit (G_OBJECT (backend), rb_iradio_backend_signals[CHANGED], 0);
 	return;
  loadinitial:
+	rb_echo_area_end_task (backend->priv->echoarea, taskid);
 	load_initial (backend);
 }
 
@@ -369,7 +476,7 @@
 	GPtrArray *children;
 	int i;
 
-	fprintf(stderr, "writing %s\n", backend->priv->xml_file);
+	rb_debug ("iradio-backend: saving");
 
 	/* save nodes to xml */
 	xmlIndentTreeOutput = TRUE;
@@ -388,8 +495,6 @@
 		
 		if (kid != backend->priv->all_stations)
 		{
-			fprintf(stderr, "Saving child %p (id %d) (name: %s) of genre root %p\n", kid, i,
-				rb_node_get_property_string (kid, RB_NODE_PROP_NAME), backend->priv->all_genres);
 			rb_node_save_to_xml (kid, root);
 		}
 	}
@@ -402,14 +507,12 @@
 
 		kid = g_ptr_array_index (children, i);
 		
-		fprintf(stderr, "Saving child %p (id %d) (name: %s) of stations root %p\n", kid, i,
-			rb_node_get_property_string (kid, RB_NODE_PROP_NAME), backend->priv->all_stations);
 		rb_node_save_to_xml (kid, root);
 	}
 	rb_node_thaw (backend->priv->all_stations);
 
 	xmlSaveFormatFile (backend->priv->xml_file, doc, 1);
-	fprintf(stderr, "writing %s: done\n", backend->priv->xml_file);
+	rb_debug ("iradio-backend: done saving");
 }
 
 void
@@ -419,6 +522,30 @@
 	rb_node_unref (RB_NODE (node));
 }
 
+/* Returns a locked RBNode */
+static RBNode *
+rb_iradio_backend_lookup_station_by_title (RBIRadioBackend *backend,
+					  const char *title)
+{
+	int i;
+	RBNode *retval = NULL;
+	GPtrArray *children = rb_node_get_children (backend->priv->all_stations);
+	for (i = 0; retval == NULL && i < children->len; i++)
+	{
+		RBNode *kid = g_ptr_array_index (children, i);
+		if (!strcmp (title, rb_node_get_property_string (kid, RB_NODE_PROP_NAME)))
+		{
+			retval = kid;
+			break;
+		}
+	}
+	if (retval)
+		rb_node_freeze (retval);
+	rb_node_thaw (backend->priv->all_stations);
+	return retval;
+}
+
+/* Returns a locked RBNode */
 static RBNode *
 rb_iradio_backend_lookup_station_by_location (RBIRadioBackend *backend,
 					      const char *uri)
@@ -429,7 +556,8 @@
 	for (i = 0; retval == NULL && i < children->len; i++)
 	{
 		RBNode *kid = g_ptr_array_index (children, i);
-		RBGListWrapper *listwrapper = RB_GLIST_WRAPPER (rb_node_get_property_object (kid, RB_NODE_PROP_ALT_LOCATIONS));
+		RBGListWrapper *listwrapper
+		  = RB_GLIST_WRAPPER (rb_node_get_property_object (kid, RB_NODE_PROP_ALT_LOCATIONS));
 		GList *cur, *locations = rb_glist_wrapper_get_list (listwrapper);
 		for (cur = locations; cur != NULL; cur = cur->next)
 		{
@@ -440,39 +568,74 @@
 			}
 		}
 	}
+	if (retval)
+		rb_node_freeze (retval);
 	rb_node_thaw (backend->priv->all_stations);
 	return retval;
 }
 
-void rb_iradio_backend_add_station_from_uri (RBIRadioBackend *backend,
-					     const char *uri)
+void
+rb_iradio_backend_add_station_from_uri (RBIRadioBackend *backend,
+					const char *uri)
 {
 	RBNode *station = rb_iradio_backend_lookup_station_by_location (backend, uri);
 	if (station == NULL)
 	{
 		GList *locations = g_list_append (NULL, g_strdup (uri));
-		station = rb_iradio_backend_add_station_full (backend, locations,
-							      _("(Unknown)"), _("(Unknown)"));
+		rb_iradio_backend_add_station_full (backend, locations,
+						    _("(Unknown)"), _("(Unknown)"));
 	}
 	else
-	{
-		/* FIXME: queue station to be played here? or somewhere else?
-		 * like return a handle and have the caller queue it? */
-	}
+		rb_node_thaw (station);
 }
 
 
-RBNode *
+void
 rb_iradio_backend_add_station_full (RBIRadioBackend *backend,
-					 GList *locations,
-					 const char *name,
-					 const char *genre)
-{
-	RBNode *ret = RB_NODE (rb_node_station_new (locations,
-						    name ? name : _("(Unknown)"),
-						    genre ? genre : _("(Unknown)"),
-						    "user", backend));
-	/* FIXME: queue station to be played here? or somewhere else?
-	 * like return a handle and have the caller queue it? */
-	return ret;
+				    GList *locations,
+				    const char *name,
+				    const char *genre)
+{
+	RBNode *node = rb_iradio_backend_lookup_station_by_title (backend, name);
+
+	if (node == NULL)
+	{
+		rb_debug ("iradio-backend: adding station; name: %s genre: %s",
+			  name, genre);
+		node = RB_NODE (rb_node_station_new (locations,
+						     name ? name : _("(Unknown)"),
+						     genre ? genre : _("(Unknown)"),
+						     "user", backend));
+	}
+	else
+	{
+		rb_debug ("iradio-backend: station %s already exists", name);
+		rb_node_thaw (node);
+	}
+}
+
+GList *
+rb_iradio_backend_get_genre_names (RBIRadioBackend *backend)
+{
+	GList *genrenames = NULL;
+	RBNode *genres = rb_iradio_backend_get_all_genres (backend);
+	GPtrArray *children = rb_node_get_children (backend->priv->all_genres);
+	int i;
+	for (i = 0; i < children->len; i++)
+	{
+		RBNode *kid;
+		const char *name;
+		
+		kid = g_ptr_array_index (children, i);
+		
+		name = rb_node_get_property_string (kid, RB_NODE_PROP_NAME);
+		if (strcmp (name, "All"))
+		{
+			/* FIXME memory leak here? */
+			genrenames = g_list_append (genrenames,
+						    g_strdup (name));
+		}
+	}
+	rb_node_thaw (genres);
+	return genrenames;
 }
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/rb-iradio-backend.h net-rhythmbox/iradio/rb-iradio-backend.h
--- rhythmbox-HEAD/iradio/rb-iradio-backend.h	2002-12-10 17:30:52.000000000 -0500
+++ net-rhythmbox/iradio/rb-iradio-backend.h	2003-02-09 03:11:07.000000000 -0500
@@ -58,6 +58,7 @@
 
 	/* Signals */
 	void (*genre_added)(const char *genre);
+	void (*changed)();
 	void (*done_loading)(void);
 } RBIRadioBackendClass;
 
@@ -84,10 +85,12 @@
 
 void    rb_iradio_backend_add_station_from_uri		(RBIRadioBackend *backend,
 							 const char *uri);
-RBNode *rb_iradio_backend_add_station_full		(RBIRadioBackend *backend,
+void	rb_iradio_backend_add_station_full		(RBIRadioBackend *backend,
 							 GList *locations,
 							 const char *name,
 							 const char *genre);
+GList  *rb_iradio_backend_get_genre_names		(RBIRadioBackend *backend);
+
      
 G_END_DECLS
 
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/rb-iradio-station.c net-rhythmbox/iradio/rb-iradio-station.c
--- rhythmbox-HEAD/iradio/rb-iradio-station.c	2002-12-10 17:30:52.000000000 -0500
+++ net-rhythmbox/iradio/rb-iradio-station.c	2003-02-09 03:11:06.000000000 -0500
@@ -23,7 +23,6 @@
 #include "rb-iradio-station.h"
 #include "rb-debug.h"
 #include <limits.h>
-#include <monkey-media-audio-stream.h>
 
 static void rb_iradio_station_class_init (RBIRadioStationClass *klass);
 static void rb_iradio_station_init (RBIRadioStation *view);
@@ -50,7 +49,6 @@
 	const char *genre;
 	const char *name;
 	GList *locations;
-	MonkeyMediaAudioStream *stream;
 };
 
 static GObjectClass *parent_class = NULL;
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/rb-iradio-yp-xmlfile.c net-rhythmbox/iradio/rb-iradio-yp-xmlfile.c
--- rhythmbox-HEAD/iradio/rb-iradio-yp-xmlfile.c	2002-12-10 17:30:52.000000000 -0500
+++ net-rhythmbox/iradio/rb-iradio-yp-xmlfile.c	2003-04-17 05:10:01.000000000 -0400
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <sys/types.h>
 
 static void rb_iradio_yp_xmlfile_class_init (RBIRadioYPXMLFileClass *klass);
 static void rb_iradio_yp_xmlfile_init (RBIRadioYPXMLFile *view);
@@ -167,7 +168,6 @@
 {
 	ypxml->priv = g_new(RBIRadioYPXMLFilePrivate, 1);
 	ypxml->priv->filename = NULL;
-	fprintf(stderr, "ypxmlfile: created %p\n", ypxml);
 }
 
 static void
@@ -181,7 +181,6 @@
 	ypxml = RB_IRADIO_YP_XMLFILE (object);
 
 	g_return_if_fail (ypxml->priv != NULL);
-	fprintf(stderr, "ypxmlfile: finalized\n");
 
 	g_free (ypxml->priv);
 
@@ -196,9 +195,9 @@
 
 static void
 rb_iradio_yp_xmlfile_set_property (GObject *object,
-				 guint prop_id,
-				 const GValue *value,
-				 GParamSpec *pspec)
+				   guint prop_id,
+				   const GValue *value,
+				   GParamSpec *pspec)
 {
 	RBIRadioYPXMLFile *ypxml = RB_IRADIO_YP_XMLFILE (object);
 
@@ -219,7 +218,7 @@
 		ypxml->priv->parsectx = g_markup_parse_context_new(&parser_impl, 0,
 								   ypxml->priv->parserdata,
 								   parse_ctx_destroy_notify);
-		if (!(ypxml->priv->parsingfile = fopen(ypxml->priv->filename, "r")))
+		if (!(ypxml->priv->parsingfile = fopen (ypxml->priv->filename, "r")))
 		{
 			fprintf(stderr, _("Failed to open %s: %s"), ypxml->priv->filename, g_strerror(errno));
 		}
@@ -365,6 +364,7 @@
 	{
 		statedata->locations = g_list_append (statedata->locations,
 						      g_string_free (statedata->tmp_url, FALSE));
+		statedata->tmp_url = g_string_new ("");
 		statedata->state = RB_IRADIO_YP_XMLFILE_STATE_IN_STATION;
 		break;
 	}
@@ -419,6 +419,7 @@
 		return;
 	}
 
+	g_assert (val);
 	g_string_append_len(val, text, text_len);
 	return;
 
@@ -432,7 +433,6 @@
 
 static void parse_ctx_destroy_notify(gpointer data)
 {
-	fprintf(stderr, "destroying parsing context\n");
 	g_free((RBIRadioYPXMLFileParserStateData *) data);
 }
 
@@ -451,10 +451,11 @@
 		ssize_t len;
 		if ((len = fread(buf, 1, sizeof(buf), ypxml->priv->parsingfile)) < 0)
 		{
-			fprintf(stderr, _("Failed to read %s: %s"), ypxml->priv->filename, g_strerror(errno));
+			fprintf(stderr, _("Failed to read %s: %s"), ypxml->priv->filename,
+				g_strerror(errno));
 			goto lose;
 		}
-		g_markup_parse_context_parse(ypxml->priv->parsectx, buf, len, &err);
+		g_markup_parse_context_parse (ypxml->priv->parsectx, buf, len, &err);
 		if (err != NULL)
 		{
 			fprintf(stderr, _("Failed to parse %s: %s"), ypxml->priv->filename, err->message);
@@ -462,17 +463,17 @@
 		}
 	}
 
-	if (ypxml->priv->parsingfile != NULL && feof(ypxml->priv->parsingfile))
+	if (ypxml->priv->parsingfile != NULL && feof (ypxml->priv->parsingfile))
 	{
 		/* FIXME error handling */
-		g_markup_parse_context_end_parse(ypxml->priv->parsectx, NULL);
+		g_markup_parse_context_end_parse (ypxml->priv->parsectx, NULL);
 	}
 
 	if (ypxml->priv->parserdata->result == NULL)
 	{
 		ret = NULL;
-		g_markup_parse_context_free(ypxml->priv->parsectx);
-		fclose(ypxml->priv->parsingfile);
+		g_markup_parse_context_free (ypxml->priv->parsectx);
+		fclose (ypxml->priv->parsingfile);
 		ypxml->priv->parsingfile = NULL;
 	}
 	else
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/rb-new-station-dialog.c net-rhythmbox/iradio/rb-new-station-dialog.c
--- rhythmbox-HEAD/iradio/rb-new-station-dialog.c	2002-12-10 17:30:52.000000000 -0500
+++ net-rhythmbox/iradio/rb-new-station-dialog.c	2003-04-23 04:56:49.000000000 -0400
@@ -23,6 +23,8 @@
 #include <libgnome/gnome-i18n.h>
 #include <gtk/gtkentry.h>
 #include <gtk/gtklabel.h>
+#include <gtk/gtkcombo.h>
+#include <gtk/gtkbox.h>
 #include <gtk/gtktable.h>
 #include <gtk/gtkdialog.h>
 #include <gtk/gtkstock.h>
@@ -54,7 +56,6 @@
 
 struct RBNewStationDialogPrivate
 {
-	RBNodeView *node_view;
 	RBIRadioBackend *backend;
 
 	GtkWidget   *title;
@@ -67,7 +68,6 @@
 enum 
 {
 	PROP_0,
-	PROP_NODE_VIEW,
 	PROP_BACKEND
 };
 
@@ -112,14 +112,6 @@
 	object_class->get_property = rb_new_station_dialog_get_property;
 
 	g_object_class_install_property (object_class,
-					 PROP_NODE_VIEW,
-					 g_param_spec_object ("node-view",
-					                      "RBNodeView",
-					                      "RBNodeView object",
-					                      RB_TYPE_NODE_VIEW,
-					                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
-	g_object_class_install_property (object_class,
 					 PROP_BACKEND,
 					 g_param_spec_object ("backend",
 					                      "RBIRadioBackend",
@@ -144,12 +136,21 @@
 			  dialog);
 
 	gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-	gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
+	gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 12);
 
 	gtk_dialog_set_default_response (GTK_DIALOG (dialog),
 					 GTK_RESPONSE_OK);
 	gtk_window_set_title (GTK_WINDOW (dialog), _("New Internet Radio Station"));
 
+	dialog->priv->cancelbutton = gtk_dialog_add_button (GTK_DIALOG (dialog),
+							    _("_Don't Add"),
+							    GTK_RESPONSE_CANCEL);
+	dialog->priv->okbutton = gtk_dialog_add_button (GTK_DIALOG (dialog),
+							GTK_STOCK_ADD,
+							GTK_RESPONSE_OK);
+	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
 	xml = rb_glade_xml_new ("station-new.glade",
 				"newstation",
 				dialog);
@@ -157,24 +158,17 @@
 
 	gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
 			   glade_xml_get_widget (xml, "newstation"));
-	dialog->priv->cancelbutton = gtk_dialog_add_button (GTK_DIALOG (dialog),
-							    GTK_STOCK_CANCEL,
-							    GTK_RESPONSE_CANCEL);
-	dialog->priv->okbutton = gtk_dialog_add_button (GTK_DIALOG (dialog),
-							GTK_STOCK_OK,
-							GTK_RESPONSE_OK);
-	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 
 	/* get the widgets from the XML */
 	dialog->priv->title = glade_xml_get_widget (xml, "titleEntry");
-	dialog->priv->genre = glade_xml_get_widget (xml, "genreEntry");
+	dialog->priv->genre = glade_xml_get_widget (xml, "genreCombo");
 	dialog->priv->location = glade_xml_get_widget (xml, "locationEntry");
 	g_signal_connect (G_OBJECT (dialog->priv->title),
 			  "changed",
 			  G_CALLBACK (rb_new_station_dialog_entry_changed_cb),
 			  dialog);
 
-	g_signal_connect (G_OBJECT (dialog->priv->genre),
+	g_signal_connect (G_OBJECT (GTK_COMBO (dialog->priv->genre)->entry),
 			  "changed",
 			  G_CALLBACK (rb_new_station_dialog_entry_changed_cb),
 			  dialog);
@@ -183,6 +177,10 @@
 			  "changed",
 			  G_CALLBACK (rb_new_station_dialog_entry_changed_cb),
 			  dialog);
+
+	gtk_combo_set_popdown_strings (GTK_COMBO (dialog->priv->genre),
+				       g_list_append (NULL, _("Unknown")));
+	
 	/* default focus */
 	gtk_widget_grab_focus (dialog->priv->title);
 	/* FIXME */
@@ -218,9 +216,6 @@
 
 	switch (prop_id)
 	{
-	case PROP_NODE_VIEW:
-		dialog->priv->node_view = g_value_get_object (value);
-		break;
 	case PROP_BACKEND:
 		dialog->priv->backend = g_value_get_object (value);
 		break;
@@ -240,9 +235,6 @@
 
 	switch (prop_id)
 	{
-	case PROP_NODE_VIEW:
-		g_value_set_object (value, dialog->priv->node_view);
-		break;
 	case PROP_BACKEND:
 		g_value_set_object (value, dialog->priv->backend);
 		break;
@@ -253,15 +245,18 @@
 }
 
 GtkWidget *
-rb_new_station_dialog_new (RBNodeView *node_view, RBIRadioBackend *backend)
+rb_new_station_dialog_new (RBIRadioBackend *backend)
 {
 	RBNewStationDialog *dialog;
+	GList *genrenames;
 
-	g_return_val_if_fail (RB_IS_NODE_VIEW (node_view), NULL);
 	g_return_val_if_fail (RB_IS_IRADIO_BACKEND (backend), NULL);
 
-	dialog = g_object_new (RB_TYPE_NEW_STATION_DIALOG, "node-view", node_view,
-			       "backend", backend, NULL);
+	dialog = g_object_new (RB_TYPE_NEW_STATION_DIALOG, "backend", backend, NULL);
+	
+	genrenames = rb_iradio_backend_get_genre_names (backend);
+	gtk_combo_set_popdown_strings (GTK_COMBO (dialog->priv->genre),
+				       genrenames);
 
 	g_return_val_if_fail (dialog->priv != NULL, NULL);
 
@@ -279,20 +274,19 @@
 	locations = g_list_prepend (locations, g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->priv->location))));
 	rb_node_station_new (locations,
 			     g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->priv->title))),
-			     g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->priv->genre))),
+			     g_strdup (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (dialog->priv->genre)->entry))),
 			     "user",
 			     dialog->priv->backend);
-cleanup:
-	gtk_widget_destroy (GTK_WIDGET (dialog));
+ cleanup:
+	return;
 }
 
 static void
 rb_new_station_dialog_entry_changed_cb (GtkEntry *entry,
 					RBNewStationDialog *dialog)
 {
-	fprintf (stderr, "handling insert/delete\n");
 	gtk_widget_set_sensitive (dialog->priv->okbutton,
 				  g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (dialog->priv->title)), -1) > 0
-				  && g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (dialog->priv->genre)), -1) > 0
+				  && g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (dialog->priv->genre)->entry)), -1) > 0
 				  && g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (dialog->priv->location)), -1) > 0);
 }
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/rb-new-station-dialog.h net-rhythmbox/iradio/rb-new-station-dialog.h
--- rhythmbox-HEAD/iradio/rb-new-station-dialog.h	2002-12-10 17:30:52.000000000 -0500
+++ net-rhythmbox/iradio/rb-new-station-dialog.h	2003-04-23 04:57:23.000000000 -0400
@@ -19,7 +19,6 @@
  */
 
 #include <gtk/gtkdialog.h>
-#include "rb-node-view.h"
 #include "rb-iradio-backend.h"
 
 #ifndef __RB_NEW_STATION_DIALOG_H
@@ -50,7 +49,7 @@
 
 GType      rb_new_station_dialog_get_type (void);
 
-GtkWidget *rb_new_station_dialog_new      (RBNodeView *view, RBIRadioBackend *backend);
+GtkWidget *rb_new_station_dialog_new      (RBIRadioBackend *backend);
 
 G_END_DECLS
 
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/rb-node-station.c net-rhythmbox/iradio/rb-node-station.c
--- rhythmbox-HEAD/iradio/rb-node-station.c	2002-12-10 17:30:52.000000000 -0500
+++ net-rhythmbox/iradio/rb-node-station.c	2003-05-02 01:07:09.000000000 -0400
@@ -37,9 +37,10 @@
 static void rb_node_station_class_init (RBNodeStationClass *klass);
 static void rb_node_station_init (RBNodeStation *node);
 static void rb_node_station_finalize (GObject *object);
+static void rb_node_station_restored (RBNode *node);
 
-static void rb_node_station_sync (RBNodeStation *node,
-				  RBIRadioBackend *backend);
+/* static void rb_node_station_sync (RBNodeStation *node, */
+/* 				  RBIRadioBackend *backend); */
 
 static GObjectClass *parent_class = NULL;
 
@@ -73,6 +74,9 @@
 rb_node_station_class_init (RBNodeStationClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	RBNodeClass *node_class = RB_NODE_CLASS (klass);
+
+	node_class->restored = rb_node_station_restored;
 
 	parent_class = g_type_class_peek_parent (klass);
 	
@@ -100,6 +104,31 @@
 }
 
 static void
+set_title_sort_key (RBNode *node)
+{
+	char *folded, *key;
+	GValue titleval = {0,};
+	GValue keyvalue = {0,};
+
+	g_assert (rb_node_get_property (node,
+					RB_NODE_PROP_NAME,
+					&titleval));
+
+	folded = g_utf8_casefold (g_value_get_string (&titleval), -1);
+	key = g_utf8_collate_key (folded, -1);
+	g_free (folded);
+	g_value_init (&keyvalue, G_TYPE_STRING);
+	g_value_set_string (&keyvalue, key);
+	g_free (key);
+
+	rb_node_set_property (node,
+			      RB_NODE_PROP_NAME_SORT_KEY,
+			      &keyvalue);
+
+	g_value_unset (&keyvalue);
+}
+
+static void
 set_genre (RBNodeStation *node,
 	   const char *genrename,
 	   RBIRadioBackend *backend)
@@ -113,9 +142,6 @@
 	genre = rb_iradio_backend_get_genre_by_name (backend,
 						     g_value_get_string (&val));
 	if (genre == NULL) {
-		GValue value = { 0, };
-		char *folded, *key;
-
 		genre = rb_node_new ();
 
 		rb_node_set_property (genre,
@@ -125,20 +151,9 @@
 				      RB_NODE_PROP_GENRE,
 				      &val);
 
-		folded = g_utf8_casefold (g_value_get_string (&val), -1);
-		key = g_utf8_collate_key (folded, -1);
-		g_free (folded);
-		g_value_init (&value, G_TYPE_STRING);
-		g_value_set_string (&value, key);
-		g_free (key);
-
-		rb_node_set_property (genre,
-				      RB_NODE_PROP_NAME_SORT_KEY,
-				      &value);
-
-		g_value_unset (&value);
-
+		set_title_sort_key (RB_NODE (genre));
 		rb_node_add_child (rb_iradio_backend_get_all_genres (backend), genre);
+		rb_node_ref (rb_iradio_backend_get_all_genres (backend));
 	}
 	
 	g_value_unset (&val);
@@ -180,6 +195,8 @@
 			      &value);
 	g_value_unset (&value);
 
+	set_title_sort_key (RB_NODE (node));
+
 	/* Source */
 	g_value_init (&value , G_TYPE_STRING);
 	g_value_set_string (&value, source);
@@ -190,8 +207,8 @@
 
 	/* Location */
 	{
-		GList *first = g_list_first(locations);
-		locations = g_list_remove_link(locations, first);
+		GList *first = g_list_first (locations);
+		locations = g_list_remove_link (locations, first);
 		g_value_init (&value , G_TYPE_STRING);
 		g_value_set_string (&value, (char *) first->data);
 		rb_node_set_property (RB_NODE (node),
@@ -201,10 +218,9 @@
 	}
 
 	/* Alternate locations */
-	listwrapper = g_object_new (RB_TYPE_GLIST_WRAPPER, NULL);
-	rb_glist_wrapper_set_list (listwrapper, locations);
-	g_value_init (&value , G_TYPE_OBJECT);
-	g_value_set_object (&value, listwrapper);
+	listwrapper = rb_glist_wrapper_new (locations);
+	g_value_init (&value , G_TYPE_POINTER);
+	g_value_set_pointer (&value, listwrapper);
 	rb_node_set_property (RB_NODE (node),
 			      RB_NODE_PROP_ALT_LOCATIONS,
 			      &value);
@@ -224,7 +240,6 @@
 	rb_node_set_property (RB_NODE (node),
 			      RB_NODE_PROP_LAST_PLAYED_SIMPLE,
 			      &value);
-	fprintf(stderr, "setting last played for node %s\n", name);
 	g_value_unset (&value);
 
 	g_value_init (&value, G_TYPE_STRING);
@@ -236,18 +251,19 @@
 
 	set_genre (node, genre, iradio_backend);
 
-	rb_node_station_sync (node, iradio_backend);
+	rb_node_add_child (rb_iradio_backend_get_all_stations (iradio_backend), RB_NODE (node));
+	rb_node_ref (rb_iradio_backend_get_all_stations (iradio_backend));
 
 	return node;
 }
 
-static void
-rb_node_station_sync (RBNodeStation *node,
-		      RBIRadioBackend *backend)
-{
-	rb_node_add_child (rb_iradio_backend_get_all_stations (backend), RB_NODE (node));
-	rb_node_add_child (rb_node_station_get_genre (node), RB_NODE (node));
-}
+/* static void */
+/* rb_node_station_sync (RBNodeStation *node, */
+/* 		      RBIRadioBackend *backend) */
+/* { */
+/* 	rb_node_add_child (rb_iradio_backend_get_all_stations (backend), RB_NODE (node)); */
+/* 	rb_node_add_child (rb_node_station_get_genre (node), RB_NODE (node)); */
+/* } */
 
 RBNode *
 rb_node_station_get_genre (RBNodeStation *node)
@@ -257,3 +273,9 @@
 	return rb_node_get_property_node (RB_NODE (node),
 			                  RB_NODE_PROP_REAL_GENRE);
 }
+
+static void
+rb_node_station_restored (RBNode *node)
+{
+	rb_node_ref (rb_node_station_get_genre (RB_NODE_STATION (node)));
+}
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/rb-node-station.h net-rhythmbox/iradio/rb-node-station.h
--- rhythmbox-HEAD/iradio/rb-node-station.h	2002-12-10 17:30:52.000000000 -0500
+++ net-rhythmbox/iradio/rb-node-station.h	2003-02-09 03:11:06.000000000 -0500
@@ -28,7 +28,8 @@
 
 enum
 {
-	RB_NODE_STATION_PROP_SOURCE = 100,
+	/* Must be one more than the last RBNode property */
+	RB_NODE_STATION_PROP_SOURCE = 24,
 };
 
 #define RB_TYPE_NODE_STATION         (rb_node_station_get_type ())
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/rb-station-properties-dialog.c net-rhythmbox/iradio/rb-station-properties-dialog.c
--- rhythmbox-HEAD/iradio/rb-station-properties-dialog.c	2002-12-10 17:30:52.000000000 -0500
+++ net-rhythmbox/iradio/rb-station-properties-dialog.c	2003-02-09 03:11:06.000000000 -0500
@@ -28,6 +28,7 @@
 #include <gtk/gtkstock.h>
 #include <gtk/gtkliststore.h>
 #include <gtk/gtktreemodel.h>
+#include <gtk/gtkbox.h>
 #include <gtk/gtktreeselection.h>
 #include <gtk/gtkbutton.h>
 #include <gtk/gtkentry.h>
@@ -180,7 +181,8 @@
 			  dialog);
 
 	gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-	gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
+	gtk_container_set_border_width (GTK_CONTAINER (dialog), 7);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 8);
 
 	gtk_dialog_set_default_response (GTK_DIALOG (dialog),
 					 GTK_RESPONSE_OK);
@@ -319,10 +321,14 @@
 	dialog = g_object_new (RB_TYPE_STATION_PROPERTIES_DIALOG,
 			       "node-view", node_view,
 			       "backend", backend, NULL);
+	g_return_val_if_fail (dialog->priv != NULL, NULL);
 
-	rb_station_properties_dialog_get_current_node (dialog);
+	if (!rb_station_properties_dialog_get_current_node (dialog))
+	{
+		g_object_unref (G_OBJECT (dialog));
+		return NULL;
+	}
 	rb_station_properties_dialog_update (dialog);
-	g_return_val_if_fail (dialog->priv != NULL, NULL);
 
 	return GTK_WIDGET (dialog);
 }
@@ -353,7 +359,6 @@
 	    (RB_IS_NODE (selected_nodes->data) == FALSE))
 	{
 		dialog->priv->current_node = NULL;
-		gtk_widget_destroy (GTK_WIDGET (dialog));
 		return FALSE;
 	}
 
@@ -364,6 +369,8 @@
 static void
 rb_station_properties_dialog_update (RBStationPropertiesDialog *dialog)
 {
+	g_return_if_fail (dialog->priv->current_node != NULL);
+	g_return_if_fail (RB_IS_NODE (dialog->priv->current_node));
 	rb_station_properties_dialog_update_location (dialog);
 	rb_station_properties_dialog_update_title (dialog);
 	rb_station_properties_dialog_update_title_entry (dialog);
diff -x '*.la' -x .deps -x Makefile -x Makefile.in -x 'Rhythmbox*' -x '*.P' -x '*.o' -x '*.lo' -x '*.Plo' -x '*.al' -x configure -x po -x CVS -uNr rhythmbox-HEAD/iradio/TODO net-rhythmbox/iradio/TODO
--- rhythmbox-HEAD/iradio/TODO	2002-12-10 17:30:24.000000000 -0500
+++ net-rhythmbox/iradio/TODO	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-move iradio backend to view
-fix new station dialog
-fix saving
-fix tree wierdness (related to saving)
-fix indentation
-finish station properties dialog (mostly done)
-make move generic properties to rb node (halfway done).
-
-


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