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 */