Fix bug #8908: Strange behavior of tree expand/collapse in packet details
authorJakub Zawadzki <darkjames-ws@darkjames.pl>
Wed, 10 Jul 2013 01:50:27 +0000 (01:50 -0000)
committerJakub Zawadzki <darkjames-ws@darkjames.pl>
Wed, 10 Jul 2013 01:50:27 +0000 (01:50 -0000)
Only expand subtree when parent was also expanded

svn path=/trunk/; revision=50479

ui/gtk/packet_panes.c

index 15a8ec5736d1dadcdee90d00791e826879421e18..1e92d1ce8e929afb85491f8613fcb0deaa55539a 100644 (file)
@@ -1360,37 +1360,61 @@ tree_view_select(GtkWidget *widget, GdkEventButton *event)
     return TRUE;
 }
 
-static gboolean
-expand_finfos(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
+static void
+expand_finfos(GtkTreeView *tree_view, GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gboolean scroll_it)
 {
-    GtkTreeView *tree_view = (GtkTreeView *) data;
+    /* code inspired by gtk_tree_model_foreach_helper */
+
     field_info *fi;
 
-    if (!gtk_tree_model_iter_has_child(model, iter))
-        return FALSE;
+    do {
+        GtkTreeIter child;
 
-    gtk_tree_model_get(model, iter, 1, &fi, -1);
+        if (gtk_tree_model_iter_children(model, &child, iter)) {
+            gtk_tree_model_get(model, iter, 1, &fi, -1);
 
-    g_assert(fi->tree_type >= 0 && fi->tree_type < num_tree_types);
+            if (tree_expanded(fi->tree_type)) {
+                gtk_tree_view_expand_row(tree_view, path, FALSE);
 
-    if (tree_expanded(fi->tree_type))
-        gtk_tree_view_expand_to_path(tree_view, path);
-    else
-        gtk_tree_view_collapse_row(tree_view, path);
-    return FALSE;
+                /* from expand_tree() */
+                if (scroll_it)
+                     gtk_tree_view_scroll_to_cell(tree_view, path, NULL, TRUE, (prefs.gui_auto_scroll_percentage/100.0f), 0.0f);
+
+                /* try to expand children only when parent is expanded */
+                gtk_tree_path_down(path);
+                expand_finfos(tree_view, model, path, &child, scroll_it);
+                gtk_tree_path_up(path);
+
+            } else
+                gtk_tree_view_collapse_row(tree_view, path);
+        }
+
+        gtk_tree_path_next(path);
+    } while (gtk_tree_model_iter_next(model, iter));
 }
 
 void
 proto_tree_draw_resolve(proto_tree *protocol_tree, GtkWidget *tree_view, const e_addr_resolve *resolv)
 {
     ProtoTreeModel *model;
+    GtkTreePath *path;
+    GtkTreeIter iter;
 
     model = proto_tree_model_new(protocol_tree, prefs.display_hidden_proto_items);
     if (resolv)
         proto_tree_model_force_resolv(PROTO_TREE_MODEL(model), resolv);
     gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view), GTK_TREE_MODEL(model));
 
-    gtk_tree_model_foreach(GTK_TREE_MODEL(model), expand_finfos, GTK_TREE_VIEW(tree_view));
+    g_signal_handlers_block_by_func(tree_view, expand_tree, NULL);
+
+    /* modified version of gtk_tree_model_foreach */
+    path = gtk_tree_path_new_first();
+    if (gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path))
+        expand_finfos(GTK_TREE_VIEW(tree_view), GTK_TREE_MODEL(model), path, &iter, prefs.gui_auto_scroll_on_expand);
+    gtk_tree_path_free(path);
+
+    g_signal_handlers_unblock_by_func(tree_view, expand_tree, NULL);
+
     g_object_unref(G_OBJECT(model));
 }