static void
restore_selection (RBLibraryBrowser *widget,
		   gint property_index,
		   gboolean query_pending)
{
	RBLibraryBrowserPrivate *priv = RB_LIBRARY_BROWSER_GET_PRIVATE (widget);
	RBPropertyView *view;
	GList *selections;
	SelectionRestoreData *data;

	view = g_hash_table_lookup (priv->property_views, (gpointer)browser_properties[property_index].type);
	selections = g_hash_table_lookup (priv->selections, (gpointer)browser_properties[property_index].type);

	if (query_pending) {
		g_object_ref (widget);

		data = g_new0 (SelectionRestoreData, 1);
		data->widget = widget;
		data->view = view;
		data->selections = selections;
		data->model = priv->input_model;

		data->handler_id =
			g_signal_connect_data (priv->input_model,
					       "complete",
					       G_CALLBACK (query_complete_cb),
					       data,
					       (GClosureNotify) selection_restore_data_destroy,
					       0);
	} else {
		ignore_selection_changes (widget, view, FALSE);
		rb_property_view_set_selection (view, selections);
	}
}
static void
reset_view_cb (RhythmDBPropType prop,
	       RBPropertyView *view,
	       RBLibraryBrowser *widget)
{
	rb_property_view_set_selection (view, NULL);
}
static void
query_complete_cb (RhythmDBQueryModel *model,
		   SelectionRestoreData *data)
{
	ignore_selection_changes (data->widget, data->view, FALSE);
	rb_property_view_set_selection (data->view, data->selections);

	g_signal_handler_disconnect (data->model, data->handler_id);
}
static void
update_browser_property_visibilty (RhythmDBPropType prop,
				   RBPropertyView *view,
				   GList *properties)
{
	gboolean old_vis, new_vis;

	old_vis = GTK_WIDGET_VISIBLE (view);
	new_vis = (g_list_find (properties, (gpointer)prop) != NULL);

	if (old_vis != new_vis) {
		if (new_vis) {
			gtk_widget_show (GTK_WIDGET (view));
		} else {
			gtk_widget_hide (GTK_WIDGET (view));
			rb_property_view_set_selection (view, NULL);
		}
	}
}
static void
rb_iradio_source_do_query (RBIRadioSource *source)
{
	RhythmDBQueryModel *genre_query_model = NULL;
	RhythmDBQueryModel *station_query_model = NULL;
	RhythmDBPropertyModel *genre_model;
	GPtrArray *query;
	RhythmDBEntryType *entry_type;

	/* don't update the selection while we're rebuilding the query */
	source->priv->setting_new_query = TRUE;

	/* construct and run the query for the search box.
	 * this is used as the model for the genre view.
	 */

	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_END);
	g_object_unref (entry_type);

	if (source->priv->search_query != NULL) {
		rhythmdb_query_append (source->priv->db,
				       query,
				       RHYTHMDB_QUERY_SUBQUERY,
				       source->priv->search_query,
				       RHYTHMDB_QUERY_END);
	}

	genre_model = rb_property_view_get_model (source->priv->genres);

	genre_query_model = rhythmdb_query_model_new_empty (source->priv->db);
	g_object_set (genre_model, "query-model", genre_query_model, NULL);

	rhythmdb_do_full_query_parsed (source->priv->db,
				       RHYTHMDB_QUERY_RESULTS (genre_query_model),
				       query);

	rhythmdb_query_free (query);
	query = NULL;

	/* check the selected genre is still available, and if not, select 'all' */
	if (source->priv->selected_genre != NULL) {
		GList *sel = NULL;

		if (!rhythmdb_property_model_iter_from_string (genre_model,
							       source->priv->selected_genre,
							       NULL)) {
			g_free (source->priv->selected_genre);
			source->priv->selected_genre = NULL;
		}

		sel = g_list_prepend (sel, source->priv->selected_genre);
		rb_property_view_set_selection (source->priv->genres, sel);
		g_list_free (sel);
	}

	/* if a genre is selected, construct a new query for it, and create
	 * a new model based on the search box query model.  otherwise, just
	 * reuse the search box query model.
	 */

	if (source->priv->selected_genre != NULL) {
		rb_debug ("matching on genre \"%s\"", source->priv->selected_genre);

		station_query_model = rhythmdb_query_model_new_empty (source->priv->db);
		query = rhythmdb_query_parse (source->priv->db,
					      RHYTHMDB_QUERY_PROP_EQUALS,
					      RHYTHMDB_PROP_GENRE,
					      source->priv->selected_genre,
					      RHYTHMDB_QUERY_END);

		g_object_set (station_query_model,
			      "query", query,
			      "base-model", genre_query_model,
			      NULL);

		rhythmdb_query_free (query);
		query = NULL;
	} else {
		station_query_model = g_object_ref (genre_query_model);
	}

	rb_entry_view_set_model (source->priv->stations, station_query_model);
	g_object_set (source, "query-model", station_query_model, NULL);

	g_object_unref (genre_query_model);
	g_object_unref (station_query_model);

	source->priv->setting_new_query = FALSE;
}