[gtk+] treeview: Redo row tracking
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] treeview: Redo row tracking
- Date: Wed, 16 Nov 2011 03:42:10 +0000 (UTC)
commit e927a5b2c7d0be1467f11b37353568862b4e95ec
Author: Benjamin Otte <otte redhat com>
Date: Sat Nov 12 03:39:48 2011 +0100
treeview: Redo row tracking
Track the RBNode/RBTree instead of keeping a TreeRowReference. This is a
whole lot faster and less error-prone.
Also, notify the accessible of removal of rows before actually removing
them, so we have a chance to clean up.
gtk/a11y/gtktreeviewaccessible.c | 82 +++++++++++++++++++++++++++++++++++---
gtk/a11y/gtktreeviewaccessible.h | 6 +++
gtk/gtktreeview.c | 4 ++
3 files changed, 86 insertions(+), 6 deletions(-)
---
diff --git a/gtk/a11y/gtktreeviewaccessible.c b/gtk/a11y/gtktreeviewaccessible.c
index 92505cc..d0798c3 100644
--- a/gtk/a11y/gtktreeviewaccessible.c
+++ b/gtk/a11y/gtktreeviewaccessible.c
@@ -25,6 +25,7 @@
#endif
#include "gtktreeprivate.h"
+#include "gtkwidgetprivate.h"
#include "gtktreeviewaccessible.h"
#include "gtkrenderercellaccessible.h"
@@ -38,7 +39,8 @@ typedef struct _GtkTreeViewAccessibleCellInfo GtkTreeViewAccessibleCellInfo;
struct _GtkTreeViewAccessibleCellInfo
{
GtkCellAccessible *cell;
- GtkTreeRowReference *cell_row_ref;
+ GtkRBTree *tree;
+ GtkRBNode *node;
GtkTreeViewColumn *cell_col_ref;
GtkTreeViewAccessible *view;
};
@@ -228,16 +230,15 @@ cell_info_free (GtkTreeViewAccessibleCellInfo *cell_info)
_gtk_cell_accessible_add_state (cell_info->cell, ATK_STATE_DEFUNCT, FALSE);
}
- /* g_object_unref (cell_info->cell); */
- if (cell_info->cell_row_ref)
- gtk_tree_row_reference_free (cell_info->cell_row_ref);
g_free (cell_info);
}
static GtkTreePath *
cell_info_get_path (GtkTreeViewAccessibleCellInfo *cell_info)
{
- return gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+ return _gtk_tree_view_find_path (NULL,
+ cell_info->tree,
+ cell_info->node);
}
static void
@@ -3079,7 +3080,16 @@ cell_info_new (GtkTreeViewAccessible *accessible,
GtkTreeViewAccessibleCellInfo *cell_info;
cell_info = g_new (GtkTreeViewAccessibleCellInfo, 1);
- cell_info->cell_row_ref = gtk_tree_row_reference_new (tree_model, path);
+
+ if (!_gtk_tree_view_find_node (GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible))),
+ path,
+ &cell_info->tree,
+ &cell_info->node))
+ {
+ /* This check needs to happen way earlier */
+ g_free (cell_info);
+ return;
+ }
cell_info->cell_col_ref = tv_col;
cell_info->cell = cell;
@@ -3504,3 +3514,63 @@ get_header_from_column (GtkTreeViewColumn *tv_col)
return rc;
}
+
+/**
+ * _gtk_rbtree_get_ancestor_node:
+ * @ancestor: the ancestor tree
+ * @child_tree: the potential child's tree
+ * @child_node: the potential child's node
+ *
+ * Finds the node that is the ancestor of @child_tree and @child_node
+ * and belongs to @ancestor. If @ancestor is not an ancestor tree
+ * of @child_node, %NULL is returned.
+ *
+ * Returns: the ancestor node or %NULL if @ancestor is not an ancestor.
+ **/
+static GtkRBNode *
+_gtk_rbtree_get_ancestor_node (GtkRBTree *ancestor,
+ GtkRBTree *child_tree,
+ GtkRBNode *child_node)
+{
+ while (child_tree != NULL)
+ {
+ if (child_tree == ancestor)
+ return child_node;
+
+ child_node = child_tree->parent_node;
+ child_tree = child_tree->parent_tree;
+ }
+
+ return NULL;
+}
+
+void
+_gtk_tree_view_accessible_remove (GtkTreeView *treeview,
+ GtkRBTree *tree,
+ GtkRBNode *node)
+{
+ GtkTreeViewAccessibleCellInfo *cell_info;
+ GHashTableIter iter;
+ GtkTreeViewAccessible *accessible;
+
+ accessible = GTK_TREE_VIEW_ACCESSIBLE (_gtk_widget_peek_accessible (GTK_WIDGET (treeview)));
+ if (accessible == NULL)
+ return;
+
+ /* if this shows up in profiles, special-case node->children == NULL */
+
+ g_hash_table_iter_init (&iter, accessible->cell_infos);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&cell_info))
+ {
+ GtkRBNode *child_node = _gtk_rbtree_get_ancestor_node (tree,
+ cell_info->tree,
+ cell_info->node);
+
+ if (child_node == NULL)
+ continue;
+
+ if (node == NULL || node == child_node)
+ g_hash_table_iter_remove (&iter);
+ }
+}
+
diff --git a/gtk/a11y/gtktreeviewaccessible.h b/gtk/a11y/gtktreeviewaccessible.h
index c04a816..e7de687 100644
--- a/gtk/a11y/gtktreeviewaccessible.h
+++ b/gtk/a11y/gtktreeviewaccessible.h
@@ -21,6 +21,7 @@
#define __GTK_TREE_VIEW_ACCESSIBLE_H__
#include "gtkcontaineraccessible.h"
+#include "gtktreeprivate.h"
G_BEGIN_DECLS
@@ -58,6 +59,11 @@ struct _GtkTreeViewAccessibleClass
GType _gtk_tree_view_accessible_get_type (void);
+/* called by treeview code */
+void _gtk_tree_view_accessible_remove (GtkTreeView *treeview,
+ GtkRBTree *tree,
+ GtkRBNode *node);
+
G_END_DECLS
#endif /* __GTK_TREE_VIEW_ACCESSIBLE_H__ */
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 62aec17..2da21a6 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -9043,10 +9043,12 @@ gtk_tree_view_row_deleted (GtkTreeModel *model,
if (tree_view->priv->tree == tree)
tree_view->priv->tree = NULL;
+ _gtk_tree_view_accessible_remove (tree_view, tree, NULL);
_gtk_rbtree_remove (tree);
}
else
{
+ _gtk_tree_view_accessible_remove (tree_view, tree, node);
_gtk_rbtree_remove_node (tree, node);
}
@@ -12900,6 +12902,8 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
tree_view->priv->last_button_x = -1;
tree_view->priv->last_button_y = -1;
+ _gtk_tree_view_accessible_remove (tree_view, node->children, NULL);
+
if (gtk_tree_view_unref_and_check_selection_tree (tree_view, node->children))
{
_gtk_rbtree_remove (node->children);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]