File rhythmbox-allow-children-added-before-parent.patch of Package rhythmbox.688

commit 8b158c834a4f5972aa5839bddb1e160d5fcdfab4
Author: Jonathan Matthew <jonathan@d14n.org>
Date:   Tue Sep 20 23:46:14 2011 +1000

    display-page-model: allow children to be added before their parents (bug #649020)
    
    This is a bit ugly, but it means pages can create and insert their own children
    as part of their construction, which seems useful and right.  The specific
    example here is the library creating child sources for multiple library
    locations.

---
 sources/rb-display-page-model.c |   18 +++++++++++++++++-
 sources/rb-display-page.c       |   16 ++++++++++++++++
 sources/rb-display-page.h       |    5 +++++
 3 files changed, 38 insertions(+), 1 deletion(-)

--- a/sources/rb-display-page-model.c
+++ b/sources/rb-display-page-model.c
@@ -601,6 +601,7 @@ rb_display_page_model_add_page (RBDispla
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	char *name;
+	GList *child, *children;
 
 	g_return_if_fail (RB_IS_DISPLAY_PAGE_MODEL (page_model));
 	g_return_if_fail (RB_IS_DISPLAY_PAGE (page));
@@ -610,9 +611,18 @@ rb_display_page_model_add_page (RBDispla
 	model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (page_model));
 	if (parent != NULL) {
 		GtkTreeIter parent_iter;
+		if (find_in_real_model (page_model, parent, &parent_iter) == FALSE) {
+			/* it's okay for a page to create and add its own children
+			 * in its constructor, but we need to defer adding the children
+			 * until the parent is added.
+			 */
+			rb_debug ("parent %p for source %s isn't in the model yet", parent, name);
+			_rb_display_page_add_pending_child (parent, page);
+			g_free (name);
+			return;
+		}
 
 		rb_debug ("inserting source %s with parent %p", name, parent);
-		g_assert (find_in_real_model (page_model, parent, &parent_iter));
 		gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent_iter);
 	} else {
 		rb_debug ("appending page %s with no parent", name);
@@ -629,6 +639,12 @@ rb_display_page_model_add_page (RBDispla
 	g_signal_connect_object (page, "notify::name", G_CALLBACK (page_notify_cb), page_model, 0);
 	g_signal_connect_object (page, "notify::visibility", G_CALLBACK (page_notify_cb), page_model, 0);
 	g_signal_connect_object (page, "notify::pixbuf", G_CALLBACK (page_notify_cb), page_model, 0);
+
+	children = _rb_display_page_get_pending_children (page);
+	for (child = children; child != NULL; child = child->next) {
+		rb_display_page_model_add_page (page_model, RB_DISPLAY_PAGE (child->data), page);
+	}
+	g_list_free (children);
 }
 
 /**
--- a/sources/rb-display-page.c
+++ b/sources/rb-display-page.c
@@ -62,6 +62,8 @@ struct _RBDisplayPagePrivate
 	RBShell *shell;
 
 	gboolean deleted;
+
+	GList *pending_children;
 };
 
 enum
@@ -85,6 +87,20 @@ enum
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+void
+_rb_display_page_add_pending_child (RBDisplayPage *page, RBDisplayPage *child)
+{
+	page->priv->pending_children = g_list_append (page->priv->pending_children, child);
+}
+
+GList *
+_rb_display_page_get_pending_children (RBDisplayPage *page)
+{
+	GList *c = page->priv->pending_children;
+	page->priv->pending_children = NULL;
+	return c;
+}
+
 /**
  * rb_display_age_receive_drag:
  * @page: a #RBDisplayPage
--- a/sources/rb-display-page.h
+++ b/sources/rb-display-page.h
@@ -109,4 +109,9 @@ void		_rb_action_group_add_display_page_
 							 GtkActionEntry *actions,
 							 int num_actions);
 
+/* things for the display page model */
+
+void		_rb_display_page_add_pending_child	(RBDisplayPage *page, RBDisplayPage *child);
+GList *		_rb_display_page_get_pending_children	(RBDisplayPage *page);
+
 #endif /* RB_DISPLAY_PAGE_H */
openSUSE Build Service is sponsored by