[rhythmbox] display-page-model: allow children to be added before their parents (bug #649020)



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 deletions(-)
---
diff --git a/sources/rb-display-page-model.c b/sources/rb-display-page-model.c
index 1780323..3f43aa5 100644
--- a/sources/rb-display-page-model.c
+++ b/sources/rb-display-page-model.c
@@ -638,6 +638,7 @@ rb_display_page_model_add_page (RBDisplayPageModel *page_model, RBDisplayPage *p
 	GtkTreeIter *parent_iter_ptr;
 	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));
@@ -646,8 +647,17 @@ rb_display_page_model_add_page (RBDisplayPageModel *page_model, RBDisplayPage *p
 
 	model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (page_model));
 	if (parent != NULL) {
+		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));
 		parent_iter_ptr = &parent_iter;
 	} else {
 		rb_debug ("appending page %s with no parent", name);
@@ -667,6 +677,12 @@ rb_display_page_model_add_page (RBDisplayPageModel *page_model, RBDisplayPage *p
 
 	walk_up_to_page_group (model, &group_iter, &iter);
 	update_group_visibility (model, &group_iter, page_model);
+
+	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);
 }
 
 /**
diff --git a/sources/rb-display-page.c b/sources/rb-display-page.c
index ed0cad3..2576c6d 100644
--- 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
diff --git a/sources/rb-display-page.h b/sources/rb-display-page.h
index ca16cf4..4046601 100644
--- a/sources/rb-display-page.h
+++ b/sources/rb-display-page.h
@@ -109,4 +109,9 @@ void		_rb_action_group_add_display_page_actions (GtkActionGroup *group,
 							 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 */



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