a11y: Improve get_selected_rows()
This commit is contained in:
parent
20b56689c5
commit
dc8f5effd4
@ -57,14 +57,6 @@ static gboolean focus_out (GtkWidget *widget);
|
|||||||
static void set_iter_nth_row (GtkTreeView *tree_view,
|
static void set_iter_nth_row (GtkTreeView *tree_view,
|
||||||
GtkTreeIter *iter,
|
GtkTreeIter *iter,
|
||||||
gint row);
|
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,
|
static int cell_info_get_index (GtkTreeView *tree_view,
|
||||||
GtkTreeViewAccessibleCellInfo *info);
|
GtkTreeViewAccessibleCellInfo *info);
|
||||||
static gboolean update_cell_value (GtkRendererCellAccessible *renderer_cell,
|
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);
|
return gtk_tree_view_accessible_is_row_selected (table, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GArray *array;
|
||||||
|
GtkTreeView *treeview;
|
||||||
|
} SelectedRowsData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_selected_rows (GtkTreeModel *model,
|
get_selected_rows (GtkTreeModel *model,
|
||||||
GtkTreePath *path,
|
GtkTreePath *path,
|
||||||
GtkTreeIter *iter,
|
GtkTreeIter *iter,
|
||||||
gpointer data)
|
gpointer datap)
|
||||||
{
|
{
|
||||||
GPtrArray *array = (GPtrArray *)data;
|
SelectedRowsData *data = datap;
|
||||||
|
GtkRBTree *tree;
|
||||||
|
GtkRBNode *node;
|
||||||
|
int id;
|
||||||
|
|
||||||
g_ptr_array_add (array, gtk_tree_path_copy (path));
|
if (_gtk_tree_view_find_node (data->treeview,
|
||||||
|
path,
|
||||||
|
&tree, &node))
|
||||||
|
{
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
id = _gtk_rbtree_node_get_index (tree, node);
|
||||||
|
|
||||||
|
g_array_append_val (data->array, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
gtk_tree_view_accessible_get_selected_rows (AtkTable *table,
|
gtk_tree_view_accessible_get_selected_rows (AtkTable *table,
|
||||||
gint **rows_selected)
|
gint **rows_selected)
|
||||||
{
|
{
|
||||||
|
SelectedRowsData data;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
GtkTreeView *tree_view;
|
gint n_rows;
|
||||||
GtkTreeModel *tree_model;
|
|
||||||
GtkTreeIter iter;
|
|
||||||
GtkTreeSelection *selection;
|
|
||||||
GtkTreePath *tree_path;
|
|
||||||
gint ret_val = 0;
|
|
||||||
|
|
||||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
|
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
|
||||||
if (widget == NULL)
|
if (widget == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
tree_view = GTK_TREE_VIEW (widget);
|
data.treeview = GTK_TREE_VIEW (widget);
|
||||||
selection = gtk_tree_view_get_selection (tree_view);
|
data.array = g_array_new (FALSE, FALSE, sizeof (gint));
|
||||||
|
|
||||||
switch (gtk_tree_selection_get_mode (selection))
|
gtk_tree_selection_selected_foreach (gtk_tree_view_get_selection (data.treeview),
|
||||||
{
|
get_selected_rows,
|
||||||
case GTK_SELECTION_SINGLE:
|
&data);
|
||||||
case GTK_SELECTION_BROWSE:
|
|
||||||
if (gtk_tree_selection_get_selected (selection, &tree_model, &iter))
|
|
||||||
{
|
|
||||||
gint row;
|
|
||||||
|
|
||||||
if (rows_selected)
|
n_rows = data.array->len;
|
||||||
{
|
if (rows_selected)
|
||||||
*rows_selected = g_new (gint, 1);
|
*rows_selected = (gint *) g_array_free (data.array, FALSE);
|
||||||
tree_path = gtk_tree_model_get_path (tree_model, &iter);
|
else
|
||||||
row = get_row_from_tree_path (tree_view, tree_path);
|
g_array_free (data.array, TRUE);
|
||||||
gtk_tree_path_free (tree_path);
|
|
||||||
|
return n_rows;
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -1813,29 +1777,6 @@ update_cell_value (GtkRendererCellAccessible *renderer_cell,
|
|||||||
return _gtk_renderer_cell_accessible_update_cache (renderer_cell, emit_change_signal);
|
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 */
|
/* Misc Private */
|
||||||
|
|
||||||
/* Helper recursive function that returns an iter to nth row
|
/* 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);
|
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
|
static void
|
||||||
cell_destroyed (gpointer data)
|
cell_destroyed (gpointer data)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user