[rhythmbox/mallard-help] property-view: don't reset selection during property renames



commit 7c305a4b2ce431aa672231ee109510d6a8037fc3
Author: Jonathan Matthew <jonathan d14n org>
Date:   Mon Mar 4 23:19:15 2013 +1000

    property-view: don't reset selection during property renames
    
    If we've only seen the delete half of a property rename (such as
    changing the genre of a radio stream where there are no other
    streams with that genre), we can't reset the selection yet as
    the property model is out of sync with its query model.  Use an
    idle handler to defer this until the change has been fully
    processed and everything is back in sync.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=692158

 widgets/rb-property-view.c |   47 +++++++++++++++++++++++++++++++++----------
 1 files changed, 36 insertions(+), 11 deletions(-)
---
diff --git a/widgets/rb-property-view.c b/widgets/rb-property-view.c
index 610cdad..931329a 100644
--- a/widgets/rb-property-view.c
+++ b/widgets/rb-property-view.c
@@ -88,6 +88,7 @@ struct RBPropertyViewPrivate
 
        gboolean draggable;
        gboolean handling_row_deletion;
+       guint reset_selection_id;
 };
 
 #define RB_PROPERTY_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_PROPERTY_VIEW, 
RBPropertyViewPrivate))
@@ -368,6 +369,11 @@ rb_property_view_dispose (GObject *object)
 
        view = RB_PROPERTY_VIEW (object);
 
+       if (view->priv->reset_selection_id != 0) {
+               g_source_remove (view->priv->reset_selection_id);
+               view->priv->reset_selection_id = 0;
+       }
+
        rb_property_view_set_model_internal (view, NULL);
 
        G_OBJECT_CLASS (rb_property_view_parent_class)->dispose (object);
@@ -566,6 +572,27 @@ rb_property_view_pre_row_deleted_cb (RhythmDBPropertyModel *model,
        rb_debug ("pre row deleted");
 }
 
+static gboolean
+reset_selection_cb (RBPropertyView *view)
+{
+       GtkTreeIter first_iter;
+       if ((gtk_tree_selection_count_selected_rows (view->priv->selection) == 0) &&
+           gtk_tree_model_get_iter_first (GTK_TREE_MODEL (view->priv->prop_model), &first_iter)) {
+               rb_debug ("no rows selected, signalling reset");
+               g_signal_handlers_block_by_func (G_OBJECT (view->priv->selection),
+                                                G_CALLBACK (rb_property_view_selection_changed_cb),
+                                                view);
+               gtk_tree_selection_select_iter (view->priv->selection, &first_iter);
+               g_signal_emit (G_OBJECT (view), rb_property_view_signals[SELECTION_RESET], 0);
+               g_signal_handlers_unblock_by_func (G_OBJECT (view->priv->selection),
+                                                  G_CALLBACK (rb_property_view_selection_changed_cb),
+                                                  view);
+       }
+
+       view->priv->reset_selection_id = 0;
+       return FALSE;
+}
+
 static void
 rb_property_view_post_row_deleted_cb (GtkTreeModel *model,
                                      GtkTreePath *path,
@@ -574,17 +601,15 @@ rb_property_view_post_row_deleted_cb (GtkTreeModel *model,
        view->priv->handling_row_deletion = FALSE;
        rb_debug ("post row deleted");
        if (gtk_tree_selection_count_selected_rows (view->priv->selection) == 0) {
-               GtkTreeIter first_iter;
-               rb_debug ("no rows selected, signalling reset");
-               if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (view->priv->prop_model), &first_iter)) {
-                       g_signal_handlers_block_by_func (G_OBJECT (view->priv->selection),
-                                                        G_CALLBACK (rb_property_view_selection_changed_cb),
-                                                        view);
-                       gtk_tree_selection_select_iter (view->priv->selection, &first_iter);
-                       g_signal_emit (G_OBJECT (view), rb_property_view_signals[SELECTION_RESET], 0);
-                       g_signal_handlers_unblock_by_func (G_OBJECT (view->priv->selection),
-                                                          G_CALLBACK (rb_property_view_selection_changed_cb),
-                                                          view);
+               if (view->priv->reset_selection_id == 0) {
+                       /* we could be in the middle of renaming a property.
+                        * we've seen it being removed, but we haven't seen the
+                        * new name being added yet, which means the property model
+                        * is out of sync with the query model, so we can't
+                        * reset the selection here.  wait until we've finished
+                        * processing the change.
+                        */
+                       view->priv->reset_selection_id = g_idle_add ((GSourceFunc) reset_selection_cb, view);
                }
        }
 }


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