? shell/hrrmm
? shell/hrrrm.xml
? shell/iradio.xml
Index: shell/rb-shell.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/shell/rb-shell.c,v
retrieving revision 1.310
diff -u -r1.310 rb-shell.c
--- shell/rb-shell.c	14 Aug 2005 02:49:07 -0000	1.310
+++ shell/rb-shell.c	14 Aug 2005 13:17:12 -0000
@@ -176,6 +176,7 @@
 static void rb_shell_view_smalldisplay_changed_cb (GtkAction *action,
 						 RBShell *shell);
 static void rb_shell_load_complete_cb (RhythmDB *db, RBShell *shell);
+static void rb_shell_source_load_complete_cb (RBSource *source, RBShell *shell);
 static void rb_shell_sync_sourcelist_visibility (RBShell *shell);
 static void rb_shell_sync_smalldisplay (RBShell *shell);
 static void sourcelist_visibility_changed_cb (GConfClient *client,
@@ -190,7 +191,7 @@
 			      guint cnxn_id,
 			      GConfEntry *entry,
 			      RBShell *shell);
-static void rb_shell_sync_selected_source (RBShell *shell);
+static gboolean rb_shell_sync_selected_source (RBShell *shell);
 
 static void selected_source_changed_cb (GConfClient *client,
 					guint cnxn_id,
@@ -322,6 +323,7 @@
 
 	gboolean shutting_down;
 	gboolean load_complete;
+	gboolean source_loaded;
 
 	int argc;
 	char **argv;
@@ -332,6 +334,7 @@
 
 	RhythmDB *db;
 	char *pending_entry;
+	gboolean play_when_loaded;
 
 	RBShellPlayer *player_shell;
 	RBShellClipboard *clipboard_shell;
@@ -1049,7 +1052,8 @@
 	
 	rb_shell_sync_window_state (shell);
 
-	rb_shell_select_source_internal (shell, library_source);
+	if (shell->priv->selected_source == NULL)
+		rb_shell_select_source_internal (shell, library_source);
 
 #ifdef HAVE_AUDIOCD
         if (rb_audiocd_is_any_device_available () == TRUE) {
@@ -1278,6 +1282,7 @@
 			RBSource *source)
 {
 	char *search_text;
+	char *selected_source;
 	
 	shell->priv->sources
 		= g_list_append (shell->priv->sources, source);
@@ -1298,6 +1303,21 @@
 		rb_source_search (source, search_text);
 		g_free (search_text);
 	}
+
+	if (!shell->priv->source_loaded) {
+		selected_source = eel_gconf_get_string (CONF_STATE_SELECTED_SOURCE);
+		if (selected_source) {
+			char *tmpname;
+			g_object_get (G_OBJECT (source), "internal-name", &tmpname, NULL);
+			if (!strcmp (selected_source, tmpname)) {
+				rb_debug ("initial selected source found");
+				rb_shell_select_source_internal (shell, source);
+				g_signal_connect (G_OBJECT (source), "loaded",
+						  G_CALLBACK (rb_shell_source_load_complete_cb),
+						  shell);
+			}
+		}
+	}
 }
 
 static void
@@ -1772,7 +1792,6 @@
 	rb_debug ("load complete");
 
 	rb_playlist_manager_load_playlists (shell->priv->playlist_manager);
-	rb_shell_sync_selected_source (shell);
 	shell->priv->load_complete = TRUE;
 
 	GDK_THREADS_LEAVE ();
@@ -1786,6 +1805,26 @@
 	g_idle_add ((GSourceFunc) idle_handle_load_complete, shell);
 }
 
+static gboolean
+idle_handle_source_load_complete (RBShell *shell)
+{
+	GDK_THREADS_ENTER ();
+	
+	rb_debug ("selected source load complete");
+	shell->priv->source_loaded = TRUE;
+	if (shell->priv->play_when_loaded)
+		rb_shell_player_playpause (shell->priv->player_shell, TRUE);
+
+	GDK_THREADS_LEAVE ();
+
+	return FALSE;
+}
+static void
+rb_shell_source_load_complete_cb (RBSource *source, RBShell *shell)
+{
+	g_idle_add ((GSourceFunc) idle_handle_source_load_complete, shell);
+}
+
 static void
 rb_shell_sync_sourcelist_visibility (RBShell *shell)
 {
@@ -1916,14 +1955,14 @@
 	rb_shell_sync_paned (shell);
 }
 
-static void
+static gboolean
 rb_shell_sync_selected_source (RBShell *shell)
 {
 	char *internalname;
 	GList *tmp;
 
 	internalname = eel_gconf_get_string (CONF_STATE_SELECTED_SOURCE);
-	g_return_if_fail (internalname);
+	g_return_val_if_fail (internalname, FALSE);
 
 	for (tmp = shell->priv->sources; tmp ; tmp = tmp->next) {
 		const char *tmpname;
@@ -1936,15 +1975,19 @@
 				      NULL);
 			if (visible != FALSE) {
 				g_free (internalname);
-				rb_shell_select_source_internal (shell,
-								 tmp->data);
-				return;
-
+				if (tmp->data != shell->priv->selected_source) {
+					rb_shell_select_source_internal (shell,
+									 tmp->data);
+					return TRUE;
+				} else {
+					return FALSE;
+				}
 			}
 		}
 	}
 	rb_shell_select_source_internal (shell, rb_shell_get_source_by_entry_type (shell, RHYTHMDB_ENTRY_TYPE_SONG));
 	g_free (internalname);
+	return FALSE;
 }
 
 
@@ -2295,8 +2338,13 @@
 static void
 rb_shell_play_impl (RBRemoteProxy *proxy)
 {
-	RBShellPlayer *player = RB_SHELL (proxy)->priv->player_shell;
-	rb_shell_player_playpause (player, TRUE);
+	RBShell *shell = RB_SHELL (proxy);
+	RBShellPlayer *player = shell->priv->player_shell;
+
+	if (shell->priv->source_loaded)
+		rb_shell_player_playpause (player, TRUE);
+	else
+		shell->priv->play_when_loaded = TRUE;
 }
 
 static void
Index: sources/rb-iradio-source.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-iradio-source.c,v
retrieving revision 1.77
diff -u -r1.77 rb-iradio-source.c
--- sources/rb-iradio-source.c	4 Aug 2005 15:13:29 -0000	1.77
+++ sources/rb-iradio-source.c	14 Aug 2005 13:17:14 -0000
@@ -100,8 +100,8 @@
 static gboolean impl_show_popup (RBSource *source);
 static void rb_iradio_source_do_query (RBIRadioSource *source, RBIRadioQueryType type);
 
-void rb_iradio_source_show_columns_changed_cb (GtkToggleButton *button,
-					     RBIRadioSource *source);
+static void rb_iradio_source_all_query_complete_cb (RhythmDBQueryModel *model,
+						    RBIRadioSource *source);
 static void stations_view_drag_data_received_cb (GtkWidget *widget,
 						 GdkDragContext *dc,
 						 gint x, gint y,
@@ -134,12 +134,8 @@
 	RBPropertyView *genres;
 	RBEntryView *stations;
 
-	char *title, *song, *name;
-
 	gboolean initialized;
 
-	char *status;
-
 	GtkWidget *paned;
 
 	char *search_text;
@@ -245,10 +241,6 @@
 
 	gtk_container_add (GTK_CONTAINER (source), source->priv->vbox);
 	
-	source->priv->song = g_strdup (_("Unknown"));
-	source->priv->name = g_strdup (_("Unknown"));
-	source->priv->title = g_strdup (_("Unknown"));
-
 	source->priv->pixbuf = gtk_widget_render_icon (dummy,
 						       RB_STOCK_IRADIO,
 						       GTK_ICON_SIZE_LARGE_TOOLBAR,
@@ -284,11 +276,6 @@
 
 	rb_debug ("finalizing iradio source");
 
-	g_free (source->priv->name);
-	g_free (source->priv->song);
-	g_free (source->priv->title);
-	g_free (source->priv->status);
-
 	g_free (source->priv);
 
 	G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -742,6 +729,9 @@
 		g_object_set (G_OBJECT (genre_model), "query-model", query_model, NULL);
 
 		source->priv->all_query = query_model;
+		g_signal_connect (G_OBJECT (query_model), "complete",
+				  G_CALLBACK (rb_iradio_source_all_query_complete_cb),
+				  source);
 	} else {
 		if (source->priv->search_text) {
 			GPtrArray *subquery = rhythmdb_query_parse (source->priv->db,
@@ -870,6 +860,14 @@
 	return;
 }
 
+static void 
+rb_iradio_source_all_query_complete_cb (RhythmDBQueryModel *model,
+					RBIRadioSource *source)
+{
+	rb_debug ("'all' query complete");
+	rb_source_notify_loaded (RB_SOURCE (source));
+}
+
 static gboolean
 impl_show_popup (RBSource *source)
 {
Index: sources/rb-library-source.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-library-source.c,v
retrieving revision 1.108
diff -u -r1.108 rb-library-source.c
--- sources/rb-library-source.c	23 Jul 2005 12:41:07 -0000	1.108
+++ sources/rb-library-source.c	14 Aug 2005 13:17:16 -0000
@@ -130,6 +130,8 @@
 void rb_library_source_browser_views_activated_cb (GtkWidget *widget,
 						 RBLibrarySource *source);
 static GPtrArray * construct_query_from_selection (RBLibrarySource *source);
+static void rb_library_source_all_query_complete_cb (RhythmDBQueryModel *model,
+						     RBLibrarySource *source);
 static void songs_view_drag_data_received_cb (GtkWidget *widget,
 					      GdkDragContext *dc,
 					      gint x, gint y,
@@ -1546,6 +1548,11 @@
 		g_object_ref (G_OBJECT (source->priv->cached_genres_model));
 		g_object_ref (G_OBJECT (source->priv->cached_artists_model));
 		g_object_ref (G_OBJECT (source->priv->cached_albums_model));
+
+		g_signal_connect_object (G_OBJECT (query_model), "complete",
+					 G_CALLBACK (rb_library_source_all_query_complete_cb),
+					 source, 0);
+					 
 	} else {
 		rb_debug ("query is not special");
 		source->priv->active_query = source->priv->model = 
@@ -1617,6 +1624,14 @@
 }
 
 static void
+rb_library_source_all_query_complete_cb (RhythmDBQueryModel *model,
+					 RBLibrarySource *source)
+{
+	rb_debug ("'all' query complete");
+	rb_source_notify_loaded (RB_SOURCE (source));
+}
+
+static void
 songs_view_drag_data_received_cb (GtkWidget *widget,
 				  GdkDragContext *dc,
 				  gint x, gint y,
Index: sources/rb-playlist-source.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-playlist-source.c,v
retrieving revision 1.63
diff -u -r1.63 rb-playlist-source.c
--- sources/rb-playlist-source.c	14 Aug 2005 02:49:06 -0000	1.63
+++ sources/rb-playlist-source.c	14 Aug 2005 13:17:17 -0000
@@ -100,6 +100,8 @@
 				     gpointer user_data);
 static void rb_playlist_source_add_list_uri (RBPlaylistSource *source,
 					  GList *list);
+static void rb_playlist_source_query_complete_cb (RhythmDBQueryModel *model,
+						  RBPlaylistSource *source);
 
 #define PLAYLIST_SOURCE_SONGS_POPUP_PATH "/PlaylistViewPopup"
 #define PLAYLIST_SOURCE_POPUP_PATH "/PlaylistSourcePopup"
@@ -114,6 +116,7 @@
 	gboolean automatic;
 	GHashTable *entries;
 
+	gboolean initial_done;
 	RhythmDBQueryModel *model;
 
 	GtkWidget *vbox;
@@ -123,8 +126,6 @@
 	RBEntryView *songs;
 
 	gboolean dirty;
-
-	char *title;
 };
 
 enum
@@ -366,8 +367,6 @@
 
 	g_hash_table_destroy (source->priv->entries);
 
-	g_free (source->priv->title);
-
 	g_free (source->priv);
 
 	G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -469,6 +468,13 @@
 				"max-size", limit_mb, 
 				NULL);
 
+	if (!source->priv->initial_done) {
+		g_signal_connect (G_OBJECT (query_model), "complete",
+				  G_CALLBACK (rb_playlist_source_query_complete_cb),
+				  source);
+		source->priv->initial_done = TRUE;
+	}
+
 	model = GTK_TREE_MODEL (query_model);
 
 	rb_entry_view_set_model (source->priv->songs, RHYTHMDB_QUERY_MODEL (query_model));
@@ -902,6 +908,11 @@
 			rb_playlist_source_add_location (source,
 							 (char *) location);
 		}
+
+		g_signal_connect (G_OBJECT (source->priv->model), "complete",
+				  G_CALLBACK (rb_playlist_source_query_complete_cb),
+				  source);
+		rhythmdb_query_model_signal_complete (source->priv->model);
 	}
 
 	return RB_SOURCE (source);
@@ -960,3 +971,11 @@
 
 	source->priv->dirty = FALSE;
 }
+
+static void
+rb_playlist_source_query_complete_cb (RhythmDBQueryModel *model,
+				      RBPlaylistSource *source)
+{
+	rb_debug("initial query complete");
+	rb_source_notify_loaded (RB_SOURCE (source));
+}
Index: sources/rb-source.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-source.c,v
retrieving revision 1.36
diff -u -r1.36 rb-source.c
--- sources/rb-source.c	7 Jul 2005 14:30:20 -0000	1.36
+++ sources/rb-source.c	14 Aug 2005 13:17:18 -0000
@@ -84,6 +84,7 @@
 	STATUS_CHANGED,
 	FILTER_CHANGED,
 	DELETED,
+	LOADED,
 	LAST_SIGNAL
 };
 
@@ -198,7 +199,7 @@
 		g_signal_new ("deleted",
 			      RB_TYPE_SOURCE,
 			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (RBSourceClass, status_changed),
+			      G_STRUCT_OFFSET (RBSourceClass, deleted),
 			      NULL, NULL,
 			      g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE,
@@ -228,6 +229,20 @@
 			      g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE,
 			      0);
+
+	/*
+	 * fires when the source is fully loaded and all its entries are
+	 * present in the query model.
+	 */
+	rb_source_signals[LOADED] =
+		g_signal_new ("loaded",
+			      RB_TYPE_SOURCE,
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (RBSourceClass, loaded),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
 }
 
 static void
@@ -366,15 +381,21 @@
 }
 
 void
-rb_source_notify_status_changed (RBSource *status)
+rb_source_notify_status_changed (RBSource *source)
+{
+	g_signal_emit (G_OBJECT (source), rb_source_signals[STATUS_CHANGED], 0);
+}
+
+void
+rb_source_notify_filter_changed (RBSource *source)
 {
-	g_signal_emit (G_OBJECT (status), rb_source_signals[STATUS_CHANGED], 0);
+	g_signal_emit (G_OBJECT (source), rb_source_signals[FILTER_CHANGED], 0);
 }
 
 void
-rb_source_notify_filter_changed (RBSource *status)
+rb_source_notify_loaded (RBSource *source)
 {
-	g_signal_emit (G_OBJECT (status), rb_source_signals[FILTER_CHANGED], 0);
+	g_signal_emit (G_OBJECT (source), rb_source_signals[LOADED], 0);
 }
 
 void
Index: sources/rb-source.h
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-source.h,v
retrieving revision 1.22
diff -u -r1.22 rb-source.h
--- sources/rb-source.h	12 Jun 2005 16:02:15 -0000	1.22
+++ sources/rb-source.h	14 Aug 2005 13:17:18 -0000
@@ -60,6 +60,7 @@
 	void (*status_changed)	(RBSource *source);
 	void (*filter_changed)	(RBSource *source);
 	void (*deleted)		(RBSource *source);
+	void (*loaded)		(RBSource *source);
 
 	/* methods */
 	char *	        (*impl_get_status)	(RBSource *source);
@@ -112,6 +113,8 @@
 
 void		rb_source_notify_status_changed (RBSource *status);
 
+void		rb_source_notify_loaded		(RBSource *status);
+
 void		rb_source_update_play_statistics(RBSource *source, RhythmDB *db,
 						 RhythmDBEntry *entry);
 
