[gtk+] a11y: Improve get_selected_rows()



commit dc8f5effd4130226aba73969bc761911f54c322f
Author: Benjamin Otte <otte redhat com>
Date:   Mon Dec 12 18:00:19 2011 +0100

    a11y: Improve get_selected_rows()

 gtk/a11y/gtktreeviewaccessible.c |  251 +++++--------------------------------
 1 files changed, 34 insertions(+), 217 deletions(-)
---
diff --git a/gtk/a11y/gtktreeviewaccessible.c b/gtk/a11y/gtktreeviewaccessible.c
index d2eaaa5..e0255f2 100644
--- a/gtk/a11y/gtktreeviewaccessible.c
+++ b/gtk/a11y/gtktreeviewaccessible.c
@@ -57,14 +57,6 @@ static gboolean focus_out            (GtkWidget        *widget);
 static void             set_iter_nth_row                (GtkTreeView            *tree_view,
                                                          GtkTreeIter            *iter,
                                                          gint                   row);
-static gint             get_row_from_tree_path          (GtkTreeView            *tree_view,
-                                                         GtkTreePath            *path);
-static void             iterate_thru_children           (GtkTreeView            *tree_view,
-                                                         GtkTreeModel           *tree_model,
-                                                         GtkTreePath            *tree_path,
-                                                         GtkTreePath            *orig,
-                                                         gint                   *count,
-                                                         gint                   depth);
 static int              cell_info_get_index             (GtkTreeView                     *tree_view,
                                                          GtkTreeViewAccessibleCellInfo   *info);
 static gboolean         update_cell_value               (GtkRendererCellAccessible       *renderer_cell,
@@ -833,88 +825,60 @@ gtk_tree_view_accessible_is_selected (AtkTable *table,
   return gtk_tree_view_accessible_is_row_selected (table, row);
 }
 
+typedef struct {
+  GArray *array;
+  GtkTreeView *treeview;
+} SelectedRowsData;
+
 static void
 get_selected_rows (GtkTreeModel *model,
                    GtkTreePath  *path,
                    GtkTreeIter  *iter,
-                   gpointer      data)
+                   gpointer      datap)
 {
-  GPtrArray *array = (GPtrArray *)data;
+  SelectedRowsData *data = datap;
+  GtkRBTree *tree;
+  GtkRBNode *node;
+  int id;
+
+  if (_gtk_tree_view_find_node (data->treeview,
+                                path,
+                                &tree, &node))
+    {
+      g_assert_not_reached ();
+    }
 
-  g_ptr_array_add (array, gtk_tree_path_copy (path));
+  id = _gtk_rbtree_node_get_index (tree, node);
+
+  g_array_append_val (data->array, id);
 }
 
 static gint
 gtk_tree_view_accessible_get_selected_rows (AtkTable  *table,
                                             gint     **rows_selected)
 {
+  SelectedRowsData data;
   GtkWidget *widget;
-  GtkTreeView *tree_view;
-  GtkTreeModel *tree_model;
-  GtkTreeIter iter;
-  GtkTreeSelection *selection;
-  GtkTreePath *tree_path;
-  gint ret_val = 0;
+  gint n_rows;
 
   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
   if (widget == NULL)
     return 0;
 
-  tree_view = GTK_TREE_VIEW (widget);
-  selection = gtk_tree_view_get_selection (tree_view);
+  data.treeview = GTK_TREE_VIEW (widget);
+  data.array = g_array_new (FALSE, FALSE, sizeof (gint));
 
-  switch (gtk_tree_selection_get_mode (selection))
-    {
-    case GTK_SELECTION_SINGLE:
-    case GTK_SELECTION_BROWSE:
-      if (gtk_tree_selection_get_selected (selection, &tree_model, &iter))
-        {
-          gint row;
+  gtk_tree_selection_selected_foreach (gtk_tree_view_get_selection (data.treeview),
+                                       get_selected_rows,
+                                       &data);
 
-          if (rows_selected)
-            {
-              *rows_selected = g_new (gint, 1);
-              tree_path = gtk_tree_model_get_path (tree_model, &iter);
-              row = get_row_from_tree_path (tree_view, tree_path);
-              gtk_tree_path_free (tree_path);
-
-              /* shouldn't ever happen */
-              g_return_val_if_fail (row != -1, 0);
-
-              *rows_selected[0] = row;
-            }
-          ret_val = 1;
-        }
-      break;
-    case GTK_SELECTION_MULTIPLE:
-      {
-        GPtrArray *array = g_ptr_array_new();
-
-        gtk_tree_selection_selected_foreach (selection, get_selected_rows, array);
-        ret_val = array->len;
-
-        if (rows_selected && ret_val)
-          {
-            gint i;
-
-            *rows_selected = g_new (gint, ret_val);
-            for (i = 0; i < ret_val; i++)
-              {
-                gint row;
-
-                tree_path = (GtkTreePath *) g_ptr_array_index (array, i);
-                row = get_row_from_tree_path (tree_view, tree_path);
-                gtk_tree_path_free (tree_path);
-                (*rows_selected)[i] = row;
-              }
-          }
-        g_ptr_array_free (array, FALSE);
-      }
-      break;
-    case GTK_SELECTION_NONE:
-      break;
-    }
-  return ret_val;
+  n_rows = data.array->len;
+  if (rows_selected)
+    *rows_selected = (gint *) g_array_free (data.array, FALSE);
+  else
+    g_array_free (data.array, TRUE);
+  
+  return n_rows;
 }
 
 static gboolean
@@ -1813,29 +1777,6 @@ update_cell_value (GtkRendererCellAccessible      *renderer_cell,
   return _gtk_renderer_cell_accessible_update_cache (renderer_cell, emit_change_signal);
 }
 
-static gint
-get_row_from_tree_path (GtkTreeView *tree_view,
-                        GtkTreePath *path)
-{
-  GtkTreeModel *tree_model;
-  GtkTreePath *root_tree;
-  gint row;
-
-  tree_model = gtk_tree_view_get_model (tree_view);
-
-  if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
-    row = gtk_tree_path_get_indices (path)[0];
-  else
-    {
-      root_tree = gtk_tree_path_new_first ();
-      row = 0;
-      iterate_thru_children (tree_view, tree_model, root_tree, path, &row, 0);
-      gtk_tree_path_free (root_tree);
-    }
-
-  return row;
-}
-
 /* Misc Private */
 
 /* Helper recursive function that returns an iter to nth row
@@ -1884,130 +1825,6 @@ set_iter_nth_row (GtkTreeView *tree_view,
   iter = return_iter_nth_row (tree_view, tree_model, iter, 0, row);
 }
 
-/* Recursively called until the row specified by orig is found.
- *
- * *count will be set to the visible row number of the child
- * relative to the row that was initially passed in as tree_path.
- * tree_path could be modified by this function.
- *
- * *count will be -1 if orig is not found as a child (a row that is
- * not visible will not be found, e.g. if the row is inside a
- * collapsed row).  If NULL is passed in as orig, *count will
- * be a count of the visible children.
- *
- * NOTE: the value for depth must be 0 when this recursive function
- * is initially called, or it may not function as expected.
- */
-static void
-iterate_thru_children (GtkTreeView  *tree_view,
-                       GtkTreeModel *tree_model,
-                       GtkTreePath  *tree_path,
-                       GtkTreePath  *orig,
-                       gint         *count,
-                       gint          depth)
-{
-  GtkTreeIter iter;
-
-  if (!gtk_tree_model_get_iter (tree_model, &iter, tree_path))
-    return;
-
-  if (tree_path && orig && !gtk_tree_path_compare (tree_path, orig))
-    /* Found it! */
-    return;
-
-  if (tree_path && orig && gtk_tree_path_compare (tree_path, orig) > 0)
-    {
-      /* Past it, so return -1 */
-      *count = -1;
-      return;
-    }
-  else if (gtk_tree_view_row_expanded (tree_view, tree_path) &&
-    gtk_tree_model_iter_has_child (tree_model, &iter))
-    {
-      (*count)++;
-      gtk_tree_path_append_index (tree_path, 0);
-      iterate_thru_children (tree_view, tree_model, tree_path,
-                             orig, count, (depth + 1));
-      return;
-    }
-  else if (gtk_tree_model_iter_next (tree_model, &iter))
-    {
-      (*count)++;
-      tree_path = gtk_tree_model_get_path (tree_model, &iter);
-       if (tree_path)
-         {
-           iterate_thru_children (tree_view, tree_model, tree_path,
-                                 orig, count, depth);
-           gtk_tree_path_free (tree_path);
-         }
-      return;
-  }
-  else if (gtk_tree_path_up (tree_path))
-    {
-      GtkTreeIter temp_iter;
-      gboolean exit_loop = FALSE;
-      gint new_depth = depth - 1;
-
-      (*count)++;
-
-     /* Make sure that we back up until we find a row
-      * where gtk_tree_path_next does not return NULL.
-      */
-      while (!exit_loop)
-        {
-          if (gtk_tree_path_get_depth (tree_path) == 0)
-              /* depth is now zero so */
-            return;
-          gtk_tree_path_next (tree_path);
-
-          /* Verify that the next row is a valid row! */
-          exit_loop = gtk_tree_model_get_iter (tree_model, &temp_iter, tree_path);
-
-          if (!exit_loop)
-            {
-              /* Keep going up until we find a row that has a valid next */
-              if (gtk_tree_path_get_depth(tree_path) > 1)
-                {
-                  new_depth--;
-                  gtk_tree_path_up (tree_path);
-                }
-              else
-                {
-                 /* If depth is 1 and gtk_tree_model_get_iter returns FALSE,
-                  * then we are at the last row, so just return.
-                  */
-                  if (orig != NULL)
-                    *count = -1;
-
-                  return;
-                }
-            }
-        }
-
-     /* This guarantees that we will stop when we hit the end of the
-      * children.
-      */
-      if (new_depth < 0)
-        return;
-
-      iterate_thru_children (tree_view, tree_model, tree_path,
-                             orig, count, new_depth);
-      return;
-    }
-
- /* If it gets here, then the path wasn't found.  Situations
-  * that would cause this would be if the path passed in is
-  * invalid or contained within the last row, but not visible
-  * because the last row is not expanded.  If NULL was passed
-  * in then a row count is desired, so only set count to -1
-  * if orig is not NULL.
-  */
-  if (orig != NULL)
-    *count = -1;
-
-  return;
-}
-
 static void
 cell_destroyed (gpointer data)
 {



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