diff options
Diffstat (limited to 'widgets/table/e-tree-selection-model.c')
-rw-r--r-- | widgets/table/e-tree-selection-model.c | 649 |
1 files changed, 403 insertions, 246 deletions
diff --git a/widgets/table/e-tree-selection-model.c b/widgets/table/e-tree-selection-model.c index ac34653362..6198973395 100644 --- a/widgets/table/e-tree-selection-model.c +++ b/widgets/table/e-tree-selection-model.c @@ -10,9 +10,12 @@ #include <config.h> #include <gtk/gtksignal.h> #include "e-tree-selection-model.h" -#include "gal/util/e-bit-array.h" -#include "gal/util/e-util.h" +#include <gal/util/e-bit-array.h> +#include <gal/util/e-sorter.h> +#include <gal/util/e-util.h> #include <gdk/gdkkeysyms.h> +#include <gal/e-table/e-tree-sorted.h> +#include <gal/e-table/e-tree-table-adapter.h> #define ETSM_CLASS(e) ((ETreeSelectionModelClass *)((GtkObject *)e)->klass) @@ -29,14 +32,40 @@ enum { ARG_ETS, }; -struct ETreeSelectionModelNode { +typedef struct ETreeSelectionModelNode { guint selected : 1; guint all_children_selected : 1; guint any_children_selected : 1; EBitArray *all_children_selected_array; EBitArray *any_children_selected_array; - ETreeSelectionModelNode **children; + struct ETreeSelectionModelNode **children; int num_children; +} ETreeSelectionModelNode; + +struct ETreeSelectionModelPriv { + ETreeTableAdapter *etta; + ETreeSorted *ets; + ETreeModel *model; + + ETreeSelectionModelNode *root; + + ETreePath cursor_path; + gint cursor_col; + gint selection_start_row; + + guint model_changed_id; + guint model_row_inserted_id, model_row_deleted_id; + + guint frozen : 1; + guint selection_model_changed : 1; + guint group_info_changed : 1; + + int tree_model_pre_change_id; + int tree_model_node_changed_id; + int tree_model_node_data_changed_id; + int tree_model_node_col_changed_id; + int tree_model_node_inserted_id; + int tree_model_node_removed_id; }; /* ETreeSelectionModelNode helpers */ @@ -61,7 +90,7 @@ static void e_tree_selection_model_node_fill_children(ETreeSelectionModel *etsm, ETreePath path, ETreeSelectionModelNode *selection_node) { int i; - selection_node->num_children = e_tree_sorted_node_num_children(etsm->ets, path); + selection_node->num_children = e_tree_sorted_node_num_children(etsm->priv->ets, path); selection_node->children = g_new(ETreeSelectionModelNode *, selection_node->num_children); for (i = 0; i < selection_node->num_children; i++) { selection_node->children[i] = NULL; @@ -87,15 +116,16 @@ e_tree_selection_model_node_free(ETreeSelectionModelNode *node) } +/* Other helper functions */ static ETreePath etsm_node_at_row(ETreeSelectionModel *etsm, int row) { ETreePath path; - path = e_tree_table_adapter_node_at_row(etsm->etta, row); + path = e_tree_table_adapter_node_at_row(etsm->priv->etta, row); if (path) - path = e_tree_sorted_view_to_model_path(etsm->ets, path); + path = e_tree_sorted_view_to_model_path(etsm->priv->ets, path); return path; } @@ -103,10 +133,10 @@ etsm_node_at_row(ETreeSelectionModel *etsm, int row) static int etsm_row_of_node(ETreeSelectionModel *etsm, ETreePath path) { - path = e_tree_sorted_model_to_view_path(etsm->ets, path); + path = e_tree_sorted_model_to_view_path(etsm->priv->ets, path); if (path) - return e_tree_table_adapter_row_of_node(etsm->etta, path); + return e_tree_table_adapter_row_of_node(etsm->priv->etta, path); else return 0; } @@ -114,8 +144,8 @@ etsm_row_of_node(ETreeSelectionModel *etsm, ETreePath path) static int etsm_cursor_row_real (ETreeSelectionModel *etsm) { - if (etsm->cursor_path) - return etsm_row_of_node(etsm, etsm->cursor_path); + if (etsm->priv->cursor_path) + return etsm_row_of_node(etsm, etsm->priv->cursor_path); else return -1; } @@ -123,13 +153,287 @@ etsm_cursor_row_real (ETreeSelectionModel *etsm) static void etsm_real_clear (ETreeSelectionModel *etsm) { - if (etsm->root) { - e_tree_selection_model_node_free(etsm->root); - etsm->root = NULL; + if (etsm->priv->root) { + e_tree_selection_model_node_free(etsm->priv->root); + etsm->priv->root = NULL; + } +} + +static ETreeSelectionModelNode * +etsm_find_node_unless_equals (ETreeSelectionModel *etsm, + ETreePath path, + gboolean grow) +{ + ETreeSelectionModelNode *selection_node; + ETreeSorted *ets = etsm->priv->ets; + ETreePath parent; + + parent = e_tree_model_node_get_parent(E_TREE_MODEL(ets), path); + + if (parent) { + selection_node = etsm_find_node_unless_equals(etsm, parent, grow); + if (selection_node) { + int position = e_tree_sorted_orig_position(ets, path); + if (selection_node->all_children_selected && grow) + return NULL; + if (!(selection_node->any_children_selected || grow)) + return NULL; + if (selection_node->all_children_selected_array && e_bit_array_value_at(selection_node->all_children_selected_array, position) && grow) + return NULL; + if (selection_node->any_children_selected_array && ! (e_bit_array_value_at(selection_node->any_children_selected_array, position) || grow)) + return NULL; + if (selection_node->children == NULL) { + e_tree_selection_model_node_fill_children(etsm, parent, selection_node); + } + if (!selection_node->children[position]) + selection_node->children[position] = e_tree_selection_model_node_new(); + + return selection_node->children[position]; + } else + return NULL; + } else { + if (!etsm->priv->root) + etsm->priv->root = e_tree_selection_model_node_new(); + return etsm->priv->root; + } +} + +#if 0 +static ETreeSelectionModelNode * +find_or_create_node (ETreeSelectionModel *etsm, + ETreePath path) +{ + ETreeSelectionModelNode *selection_node; + ETreeSelectionModelNode **place = NULL; + ETreeSorted *ets = etsm->priv->ets; + ETreePath parent; + + parent = e_tree_model_node_get_parent(E_TREE_MODEL(ets), path); + + if (parent) { + selection_node = find_or_create_node(etsm, parent); + if (selection_node) { + int position = e_tree_sorted_orig_position(ets, path); + if (!selection_node->children) { + e_tree_selection_model_node_fill_children(etsm, parent, selection_node); + } + if (!selection_node->children[position]) + slection_node->children[position] = e_tree_selection_model_node_new(); + + return selection_node->children[position]; + } else + return NULL; + } else { + if (!etsm->priv->root) + etsm->priv->root = e_tree_selection_model_node_new(); + return etsm->priv->root; + } +} +#endif + +static void +update_parents (ETreeSelectionModel *etsm, ETreePath path) +{ + int i; + int depth; + ETreeSorted *ets = etsm->priv->ets; + int *orig_position_sequence; + ETreeSelectionModelNode **node_sequence; + ETreePath parents; + + if (!etsm->priv->root) + return; + + depth = e_tree_model_node_depth (E_TREE_MODEL(ets), path); + + orig_position_sequence = g_new(int, depth + 1); + node_sequence = g_new(ETreeSelectionModelNode *, depth + 1); + + parents = path; + + for (i = depth; i > 0; i--) { + if (!parents) { + g_free(orig_position_sequence); + g_free(node_sequence); + return; + } + orig_position_sequence[i] = e_tree_sorted_orig_position(etsm->priv->ets, parents); + parents = e_tree_model_node_get_parent(E_TREE_MODEL(etsm->priv->ets), parents); + } + + node_sequence[0] = etsm->priv->root; + for (i = 0; i < depth; i++) { + node_sequence[i + 1] = NULL; + + if (node_sequence[i]->children) + node_sequence[i + 1] = node_sequence[i]->children[orig_position_sequence[i + 1]]; + + if (node_sequence[i + 1] == NULL) { + g_free(orig_position_sequence); + g_free(node_sequence); + return; + } + } + + if (node_sequence[depth]->num_children == -1) + e_tree_selection_model_node_fill_children(etsm, path, node_sequence[depth]); + + if (!node_sequence[depth]->all_children_selected_array) + node_sequence[depth]->all_children_selected_array = e_bit_array_new(node_sequence[depth]->num_children); + if (!node_sequence[depth]->any_children_selected_array) + node_sequence[depth]->any_children_selected_array = e_bit_array_new(node_sequence[depth]->num_children); + + node_sequence[depth]->all_children_selected = + e_bit_array_cross_and(node_sequence[depth]->all_children_selected_array) && + node_sequence[depth]->selected; + + node_sequence[depth]->any_children_selected = + e_bit_array_cross_or(node_sequence[depth]->any_children_selected_array) || + node_sequence[depth]->selected; + + for (i = depth - 1; i >= 0; i--) { + gboolean all_children, any_children; + + if (!node_sequence[i]->all_children_selected_array) + node_sequence[i]->all_children_selected_array = e_bit_array_new(node_sequence[i]->num_children); + if (!node_sequence[i]->any_children_selected_array) + node_sequence[i]->any_children_selected_array = e_bit_array_new(node_sequence[i]->num_children); + + e_bit_array_change_one_row(node_sequence[i]->all_children_selected_array, + orig_position_sequence[i + 1], node_sequence[i + 1]->all_children_selected); + e_bit_array_change_one_row(node_sequence[i]->any_children_selected_array, + orig_position_sequence[i + 1], node_sequence[i + 1]->any_children_selected); + + all_children = node_sequence[i]->all_children_selected; + any_children = node_sequence[i]->any_children_selected; + + node_sequence[i]->all_children_selected = + e_bit_array_cross_and(node_sequence[i]->all_children_selected_array) && + node_sequence[i]->selected; + node_sequence[i]->any_children_selected = + e_bit_array_cross_or(node_sequence[i]->any_children_selected_array) || + node_sequence[i]->selected; + + if (all_children == node_sequence[i]->all_children_selected && + any_children == node_sequence[i]->any_children_selected) + break; } + + g_free(orig_position_sequence); + g_free(node_sequence); +} + + +/* Signal handlers */ + +static void +etsm_pre_change (ETreeModel *etm, ETreeSelectionModel *etsm) +{ +} + +static void +etsm_node_changed (ETreeModel *etm, ETreePath node, ETreeSelectionModel *etsm) +{ + etsm_real_clear (etsm); +} + +static void +etsm_node_data_changed (ETreeModel *etm, ETreePath node, ETreeSelectionModel *etsm) +{ } static void +etsm_node_col_changed (ETreeModel *etm, ETreePath node, int col, ETreeSelectionModel *etsm) +{ +} + +static void +etsm_node_inserted (ETreeModel *etm, ETreePath parent, ETreePath child, ETreeSelectionModel *etsm) +{ + etsm_node_changed(etm, parent, etsm); +#if 0 + ETreeSelectionModelNode *node; + ETreePath path; + + path = e_tree_sorted_model_to_view_path(etsm->priv->ets, parent); + + if (!path) + return; + + node = etsm_find_node_unless_equals (etsm, path, FALSE); + + if (node) { + node->selected = FALSE; + update_parents(etsm, path); + } +#endif +} + +static void +etsm_node_removed (ETreeModel *etm, ETreePath parent, ETreePath child, int old_position, ETreeSelectionModel *etsm) +{ + etsm_node_changed(etm, parent, etsm); +} + + +static void +add_model(ETreeSelectionModel *etsm, ETreeModel *model) +{ + ETreeSelectionModelPriv *priv = etsm->priv; + priv->model = model; + + if (!priv->model) + return; + + gtk_object_ref(GTK_OBJECT(priv->model)); + priv->tree_model_pre_change_id = gtk_signal_connect (GTK_OBJECT (priv->model), "pre_change", + GTK_SIGNAL_FUNC (etsm_pre_change), etsm); + priv->tree_model_node_changed_id = gtk_signal_connect (GTK_OBJECT (priv->model), "node_changed", + GTK_SIGNAL_FUNC (etsm_node_changed), etsm); + priv->tree_model_node_data_changed_id = gtk_signal_connect (GTK_OBJECT (priv->model), "node_data_changed", + GTK_SIGNAL_FUNC (etsm_node_data_changed), etsm); + priv->tree_model_node_col_changed_id = gtk_signal_connect (GTK_OBJECT (priv->model), "node_col_changed", + GTK_SIGNAL_FUNC (etsm_node_col_changed), etsm); + priv->tree_model_node_inserted_id = gtk_signal_connect (GTK_OBJECT (priv->model), "node_inserted", + GTK_SIGNAL_FUNC (etsm_node_inserted), etsm); + priv->tree_model_node_removed_id = gtk_signal_connect (GTK_OBJECT (priv->model), "node_removed", + GTK_SIGNAL_FUNC (etsm_node_removed), etsm); +} + +static void +drop_model(ETreeSelectionModel *etsm) +{ + ETreeSelectionModelPriv *priv = etsm->priv; + + if (!priv->model) + return; + + gtk_signal_disconnect (GTK_OBJECT (priv->model), + priv->tree_model_pre_change_id); + gtk_signal_disconnect (GTK_OBJECT (priv->model), + priv->tree_model_node_changed_id); + gtk_signal_disconnect (GTK_OBJECT (priv->model), + priv->tree_model_node_data_changed_id); + gtk_signal_disconnect (GTK_OBJECT (priv->model), + priv->tree_model_node_col_changed_id); + gtk_signal_disconnect (GTK_OBJECT (priv->model), + priv->tree_model_node_inserted_id); + gtk_signal_disconnect (GTK_OBJECT (priv->model), + priv->tree_model_node_removed_id); + + gtk_object_unref (GTK_OBJECT (priv->model)); + priv->model = NULL; + + priv->tree_model_pre_change_id = 0; + priv->tree_model_node_changed_id = 0; + priv->tree_model_node_data_changed_id = 0; + priv->tree_model_node_col_changed_id = 0; + priv->tree_model_node_inserted_id = 0; + priv->tree_model_node_removed_id = 0; +} + +/* Virtual functions */ +static void etsm_destroy (GtkObject *object) { ETreeSelectionModel *etsm; @@ -137,6 +441,8 @@ etsm_destroy (GtkObject *object) etsm = E_TREE_SELECTION_MODEL (object); etsm_real_clear (etsm); + drop_model(etsm); + g_free(etsm->priv); } static void @@ -150,19 +456,19 @@ etsm_get_arg (GtkObject *o, GtkArg *arg, guint arg_id) break; case ARG_CURSOR_COL: - GTK_VALUE_INT(*arg) = etsm->cursor_col; + GTK_VALUE_INT(*arg) = etsm->priv->cursor_col; break; case ARG_MODEL: - GTK_VALUE_OBJECT(*arg) = (GtkObject *) etsm->model; + GTK_VALUE_OBJECT(*arg) = (GtkObject *) etsm->priv->model; break; case ARG_ETTA: - GTK_VALUE_OBJECT(*arg) = (GtkObject *) etsm->etta; + GTK_VALUE_OBJECT(*arg) = (GtkObject *) etsm->priv->etta; break; case ARG_ETS: - GTK_VALUE_OBJECT(*arg) = (GtkObject *) etsm->ets; + GTK_VALUE_OBJECT(*arg) = (GtkObject *) etsm->priv->ets; break; } } @@ -175,7 +481,7 @@ etsm_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) switch (arg_id){ case ARG_CURSOR_ROW: - e_selection_model_do_something(esm, GTK_VALUE_INT(*arg), etsm->cursor_col, 0); + e_selection_model_do_something(esm, GTK_VALUE_INT(*arg), etsm->priv->cursor_col, 0); break; case ARG_CURSOR_COL: @@ -183,15 +489,16 @@ etsm_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) break; case ARG_MODEL: - etsm->model = (ETreeModel *) GTK_VALUE_OBJECT(*arg); + drop_model(etsm); + add_model(etsm, (ETreeModel *) GTK_VALUE_OBJECT(*arg)); break; case ARG_ETTA: - etsm->etta = (ETreeTableAdapter *) GTK_VALUE_OBJECT(*arg); + etsm->priv->etta = (ETreeTableAdapter *) GTK_VALUE_OBJECT(*arg); break; case ARG_ETS: - etsm->ets = (ETreeSorted *) GTK_VALUE_OBJECT(*arg); + etsm->priv->ets = (ETreeSorted *) GTK_VALUE_OBJECT(*arg); break; } } @@ -203,7 +510,7 @@ etsm_recurse_is_path_selected (ESelectionModel *selection, { ETreeSelectionModelNode *selection_node; ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection); - ETreeSorted *ets = etsm->ets; + ETreeSorted *ets = etsm->priv->ets; ETreePath parent; parent = e_tree_model_node_get_parent(E_TREE_MODEL(ets), path); @@ -240,8 +547,8 @@ etsm_recurse_is_path_selected (ESelectionModel *selection, } else return NULL; } else { - if (etsm->root) { - return etsm->root; + if (etsm->priv->root) { + return etsm->priv->root; } else { *is_selected = FALSE; return NULL; @@ -268,7 +575,7 @@ etsm_is_row_selected (ESelectionModel *selection, gboolean ret_val; - path = e_tree_table_adapter_node_at_row(etsm->etta, row); + path = e_tree_table_adapter_node_at_row(etsm->priv->etta, row); selection_node = etsm_recurse_is_path_selected (selection, path, &ret_val); @@ -330,8 +637,8 @@ etsm_clear(ESelectionModel *selection) etsm_real_clear (etsm); - etsm->cursor_path = NULL; - etsm->cursor_col = -1; + etsm->priv->cursor_path = NULL; + etsm->priv->cursor_col = -1; e_selection_model_selection_changed(E_SELECTION_MODEL(etsm)); e_selection_model_cursor_changed(E_SELECTION_MODEL(etsm), -1, -1); } @@ -350,7 +657,7 @@ etsm_selected_count (ESelectionModel *selection) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection); - return g_hash_table_size(etsm->data); + return g_hash_table_size(etsm->priv->data); } #endif @@ -368,24 +675,24 @@ etsm_select_all (ESelectionModel *selection) etsm_real_clear (etsm); - etsm->root = e_tree_selection_model_node_new(); - etsm->root->selected = TRUE; - etsm->root->all_children_selected = TRUE; - etsm->root->any_children_selected = TRUE; - - e_tree_selection_model_node_fill_children(etsm, e_tree_model_get_root(E_TREE_MODEL(etsm->ets)), etsm->root); - etsm->root->all_children_selected_array = e_bit_array_new(etsm->root->num_children); - etsm->root->any_children_selected_array = e_bit_array_new(etsm->root->num_children); - e_bit_array_select_all(etsm->root->all_children_selected_array); - e_bit_array_select_all(etsm->root->any_children_selected_array); - - if (etsm->cursor_col == -1) - etsm->cursor_col = 0; - if (etsm->cursor_path == NULL) - etsm->cursor_path = etsm_node_at_row(etsm, 0); - etsm->selection_start_row = 0; + etsm->priv->root = e_tree_selection_model_node_new(); + etsm->priv->root->selected = TRUE; + etsm->priv->root->all_children_selected = TRUE; + etsm->priv->root->any_children_selected = TRUE; + + e_tree_selection_model_node_fill_children(etsm, e_tree_model_get_root(E_TREE_MODEL(etsm->priv->ets)), etsm->priv->root); + etsm->priv->root->all_children_selected_array = e_bit_array_new(etsm->priv->root->num_children); + etsm->priv->root->any_children_selected_array = e_bit_array_new(etsm->priv->root->num_children); + e_bit_array_select_all(etsm->priv->root->all_children_selected_array); + e_bit_array_select_all(etsm->priv->root->any_children_selected_array); + + if (etsm->priv->cursor_col == -1) + etsm->priv->cursor_col = 0; + if (etsm->priv->cursor_path == NULL) + etsm->priv->cursor_path = etsm_node_at_row(etsm, 0); + etsm->priv->selection_start_row = 0; e_selection_model_selection_changed(E_SELECTION_MODEL(etsm)); - e_selection_model_cursor_changed(E_SELECTION_MODEL(etsm), etsm_cursor_row_real(etsm), etsm->cursor_col); + e_selection_model_cursor_changed(E_SELECTION_MODEL(etsm), etsm_cursor_row_real(etsm), etsm->priv->cursor_col); } static void @@ -428,12 +735,12 @@ etsm_invert_selection (ESelectionModel *selection) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection); - if (etsm->root) - etsm_invert_selection_recurse (etsm, etsm->root); + if (etsm->priv->root) + etsm_invert_selection_recurse (etsm, etsm->priv->root); - etsm->cursor_col = -1; - etsm->cursor_path = NULL; - etsm->selection_start_row = 0; + etsm->priv->cursor_col = -1; + etsm->priv->cursor_path = NULL; + etsm->priv->selection_start_row = 0; e_selection_model_selection_changed(E_SELECTION_MODEL(etsm)); e_selection_model_cursor_changed(E_SELECTION_MODEL(etsm), -1, -1); } @@ -442,171 +749,7 @@ static int etsm_row_count (ESelectionModel *selection) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection); - return e_table_model_row_count(E_TABLE_MODEL(etsm->etta)); -} - -static ETreeSelectionModelNode * -etsm_find_node_unless_equals (ETreeSelectionModel *etsm, - ETreePath path, - gboolean grow) -{ - ETreeSelectionModelNode *selection_node; - ETreeSorted *ets = etsm->ets; - ETreePath parent; - - parent = e_tree_model_node_get_parent(E_TREE_MODEL(ets), path); - - if (parent) { - selection_node = etsm_find_node_unless_equals(etsm, parent, grow); - if (selection_node) { - int position = e_tree_sorted_orig_position(ets, path); - if (selection_node->all_children_selected && grow) - return NULL; - if (!(selection_node->any_children_selected || grow)) - return NULL; - if (selection_node->all_children_selected_array && e_bit_array_value_at(selection_node->all_children_selected_array, position) && grow) - return NULL; - if (selection_node->any_children_selected_array && ! (e_bit_array_value_at(selection_node->any_children_selected_array, position) || grow)) - return NULL; - if (selection_node->children == NULL) { - e_tree_selection_model_node_fill_children(etsm, parent, selection_node); - } - if (!selection_node->children[position]) - selection_node->children[position] = e_tree_selection_model_node_new(); - - return selection_node->children[position]; - } else - return NULL; - } else { - if (!etsm->root) - etsm->root = e_tree_selection_model_node_new(); - return etsm->root; - } -} - -#if 0 -static ETreeSelectionModelNode * -find_or_create_node (ETreeSelectionModel *etsm, - ETreePath path) -{ - ETreeSelectionModelNode *selection_node; - ETreeSelectionModelNode **place = NULL; - ETreeSorted *ets = etsm->ets; - ETreePath parent; - - parent = e_tree_model_node_get_parent(E_TREE_MODEL(ets), path); - - if (parent) { - selection_node = find_or_create_node(etsm, parent); - if (selection_node) { - int position = e_tree_sorted_orig_position(ets, path); - if (!selection_node->children) { - e_tree_selection_model_node_fill_children(etsm, parent, selection_node); - } - if (!selection_node->children[position]) - slection_node->children[position] = e_tree_selection_model_node_new(); - - return selection_node->children[position]; - } else - return NULL; - } else { - if (!etsm->root) - etsm->root = e_tree_selection_model_node_new(); - return etsm->root; - } -} -#endif - -static void -update_parents (ETreeSelectionModel *etsm, ETreePath path) -{ - int i; - int depth; - ETreeSorted *ets = etsm->ets; - int *orig_position_sequence; - ETreeSelectionModelNode **node_sequence; - ETreePath parents; - - if (!etsm->root) - return; - - depth = e_tree_model_node_depth (E_TREE_MODEL(ets), path); - - orig_position_sequence = g_new(int, depth + 1); - node_sequence = g_new(ETreeSelectionModelNode *, depth + 1); - - parents = path; - - for (i = depth; i > 0; i--) { - if (!parents) { - g_free(orig_position_sequence); - g_free(node_sequence); - return; - } - orig_position_sequence[i] = e_tree_sorted_orig_position(etsm->ets, parents); - parents = e_tree_model_node_get_parent(E_TREE_MODEL(etsm->ets), parents); - } - - node_sequence[0] = etsm->root; - for (i = 0; i < depth; i++) { - node_sequence[i + 1] = NULL; - - if (node_sequence[i]->children) - node_sequence[i + 1] = node_sequence[i]->children[orig_position_sequence[i + 1]]; - - if (node_sequence[i + 1] == NULL) { - g_free(orig_position_sequence); - g_free(node_sequence); - return; - } - } - - if (node_sequence[depth]->num_children == -1) - e_tree_selection_model_node_fill_children(etsm, path, node_sequence[depth]); - - if (!node_sequence[depth]->all_children_selected_array) - node_sequence[depth]->all_children_selected_array = e_bit_array_new(node_sequence[depth]->num_children); - if (!node_sequence[depth]->any_children_selected_array) - node_sequence[depth]->any_children_selected_array = e_bit_array_new(node_sequence[depth]->num_children); - - node_sequence[depth]->all_children_selected = - e_bit_array_cross_and(node_sequence[depth]->all_children_selected_array) && - node_sequence[depth]->selected; - - node_sequence[depth]->any_children_selected = - e_bit_array_cross_or(node_sequence[depth]->any_children_selected_array) || - node_sequence[depth]->selected; - - for (i = depth - 1; i >= 0; i--) { - gboolean all_children, any_children; - - if (!node_sequence[i]->all_children_selected_array) - node_sequence[i]->all_children_selected_array = e_bit_array_new(node_sequence[i]->num_children); - if (!node_sequence[i]->any_children_selected_array) - node_sequence[i]->any_children_selected_array = e_bit_array_new(node_sequence[i]->num_children); - - e_bit_array_change_one_row(node_sequence[i]->all_children_selected_array, - orig_position_sequence[i + 1], node_sequence[i + 1]->all_children_selected); - e_bit_array_change_one_row(node_sequence[i]->any_children_selected_array, - orig_position_sequence[i + 1], node_sequence[i + 1]->any_children_selected); - - all_children = node_sequence[i]->all_children_selected; - any_children = node_sequence[i]->any_children_selected; - - node_sequence[i]->all_children_selected = - e_bit_array_cross_and(node_sequence[i]->all_children_selected_array) && - node_sequence[i]->selected; - node_sequence[i]->any_children_selected = - e_bit_array_cross_or(node_sequence[i]->any_children_selected_array) || - node_sequence[i]->selected; - - if (all_children == node_sequence[i]->all_children_selected && - any_children == node_sequence[i]->any_children_selected) - break; - } - - g_free(orig_position_sequence); - g_free(node_sequence); + return e_table_model_row_count(E_TABLE_MODEL(etsm->priv->etta)); } static void @@ -614,7 +757,7 @@ etsm_change_one_row(ESelectionModel *selection, int row, gboolean grow) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection); ETreeSelectionModelNode *node; - ETreePath path = e_tree_table_adapter_node_at_row(etsm->etta, row); + ETreePath path = e_tree_table_adapter_node_at_row(etsm->priv->etta, row); if (!path) return; @@ -638,11 +781,11 @@ etsm_change_cursor (ESelectionModel *selection, int row, int col) etsm = E_TREE_SELECTION_MODEL(selection); if (row == -1) { - etsm->cursor_path = NULL; + etsm->priv->cursor_path = NULL; } else { - etsm->cursor_path = etsm_node_at_row(etsm, row); + etsm->priv->cursor_path = etsm_node_at_row(etsm, row); } - etsm->cursor_col = col; + etsm->priv->cursor_col = col; } static void @@ -672,7 +815,7 @@ static int etsm_cursor_col (ESelectionModel *selection) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection); - return etsm->cursor_col; + return etsm->priv->cursor_col; } static void @@ -682,7 +825,7 @@ etsm_select_single_row (ESelectionModel *selection, int row) etsm_real_clear (etsm); etsm_change_one_row(selection, row, TRUE); - etsm->selection_start_row = row; + etsm->priv->selection_start_row = row; e_selection_model_selection_changed(E_SELECTION_MODEL(etsm)); } @@ -692,7 +835,7 @@ etsm_toggle_single_row (ESelectionModel *selection, int row) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection); - etsm->selection_start_row = row; + etsm->priv->selection_start_row = row; etsm_change_one_row(selection, row, !etsm_is_row_selected(selection, row)); @@ -708,19 +851,19 @@ etsm_move_selection_end (ESelectionModel *selection, int row) int new_start; int new_end; if (selection->sorter && e_sorter_needs_sorting(selection->sorter)) { - old_start = MIN (e_sorter_model_to_sorted(selection->sorter, etsm->selection_start_row), + old_start = MIN (e_sorter_model_to_sorted(selection->sorter, etsm->priv->selection_start_row), e_sorter_model_to_sorted(selection->sorter, etsm_cursor_row_real(etsm))); - old_end = MAX (e_sorter_model_to_sorted(selection->sorter, etsm->selection_start_row), + old_end = MAX (e_sorter_model_to_sorted(selection->sorter, etsm->priv->selection_start_row), e_sorter_model_to_sorted(selection->sorter, etsm_cursor_row_real(etsm))) + 1; - new_start = MIN (e_sorter_model_to_sorted(selection->sorter, etsm->selection_start_row), + new_start = MIN (e_sorter_model_to_sorted(selection->sorter, etsm->priv->selection_start_row), e_sorter_model_to_sorted(selection->sorter, row)); - new_end = MAX (e_sorter_model_to_sorted(selection->sorter, etsm->selection_start_row), + new_end = MAX (e_sorter_model_to_sorted(selection->sorter, etsm->priv->selection_start_row), e_sorter_model_to_sorted(selection->sorter, row)) + 1; } else { - old_start = MIN (etsm->selection_start_row, etsm_cursor_row_real(etsm)); - old_end = MAX (etsm->selection_start_row, etsm_cursor_row_real(etsm)) + 1; - new_start = MIN (etsm->selection_start_row, row); - new_end = MAX (etsm->selection_start_row, row) + 1; + old_start = MIN (etsm->priv->selection_start_row, etsm_cursor_row_real(etsm)); + old_end = MAX (etsm->priv->selection_start_row, etsm_cursor_row_real(etsm)) + 1; + new_start = MIN (etsm->priv->selection_start_row, row); + new_end = MAX (etsm->priv->selection_start_row, row) + 1; } /* This wouldn't work nearly so smoothly if one end of the selection weren't held in place. */ if (old_start < new_start) @@ -738,14 +881,16 @@ static void etsm_set_selection_end (ESelectionModel *selection, int row) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection); - etsm_select_single_row(selection, etsm->selection_start_row); - if (etsm->selection_start_row != -1) - etsm->cursor_path = etsm_node_at_row(etsm, etsm->selection_start_row); + etsm_select_single_row(selection, etsm->priv->selection_start_row); + if (etsm->priv->selection_start_row != -1) + etsm->priv->cursor_path = etsm_node_at_row(etsm, etsm->priv->selection_start_row); else - etsm->cursor_path = NULL; + etsm->priv->cursor_path = NULL; e_selection_model_move_selection_end(selection, row); } + +/* Standard functions */ static void etsm_foreach_all_recurse (ETreeSelectionModel *etsm, ETreePath path, @@ -755,11 +900,11 @@ etsm_foreach_all_recurse (ETreeSelectionModel *etsm, ETreePath model_path; ETreePath child; - model_path = e_tree_sorted_view_to_model_path(etsm->ets, path); + model_path = e_tree_sorted_view_to_model_path(etsm->priv->ets, path); callback(model_path, closure); - child = e_tree_model_node_get_first_child(E_TREE_MODEL(etsm->ets), path); - for ( ; child; child = e_tree_model_node_get_next(E_TREE_MODEL(etsm->ets), child)) + child = e_tree_model_node_get_first_child(E_TREE_MODEL(etsm->priv->ets), path); + for ( ; child; child = e_tree_model_node_get_next(E_TREE_MODEL(etsm->priv->ets), child)) if (child) etsm_foreach_all_recurse (etsm, child, callback, closure); } @@ -780,14 +925,14 @@ etsm_foreach_recurse (ETreeSelectionModel *etsm, return; if (selection_node->selected) { - ETreePath model_path = e_tree_sorted_view_to_model_path(etsm->ets, path); + ETreePath model_path = e_tree_sorted_view_to_model_path(etsm->priv->ets, path); callback(model_path, closure); } if (selection_node->children) { - ETreePath child = e_tree_model_node_get_first_child(E_TREE_MODEL(etsm->ets), path); + ETreePath child = e_tree_model_node_get_first_child(E_TREE_MODEL(etsm->priv->ets), path); int i; - for (i = 0; i < selection_node->num_children; i++, child = e_tree_model_node_get_next(E_TREE_MODEL(etsm->ets), child)) + for (i = 0; i < selection_node->num_children; i++, child = e_tree_model_node_get_next(E_TREE_MODEL(etsm->priv->ets), child)) if (selection_node->children[i]) etsm_foreach_recurse (etsm, selection_node->children[i], child, callback, closure); } @@ -798,8 +943,8 @@ e_tree_selection_model_foreach (ETreeSelectionModel *etsm, ETreeForeachFunc callback, gpointer closure) { - if (etsm->root) { - etsm_foreach_recurse(etsm, etsm->root, e_tree_model_get_root(E_TREE_MODEL(etsm->ets)), callback, closure); + if (etsm->priv->root) { + etsm_foreach_recurse(etsm, etsm->priv->root, e_tree_model_get_root(E_TREE_MODEL(etsm->priv->ets)), callback, closure); } } @@ -807,9 +952,21 @@ e_tree_selection_model_foreach (ETreeSelectionModel *etsm, static void e_tree_selection_model_init (ETreeSelectionModel *etsm) { - etsm->root = NULL; - etsm->cursor_path = NULL; - etsm->cursor_col = -1; + ETreeSelectionModelPriv *priv; + priv = g_new(ETreeSelectionModelPriv, 1); + etsm->priv = priv; + + priv->root = NULL; + priv->cursor_path = NULL; + priv->cursor_col = -1; + + priv->tree_model_pre_change_id = 0; + priv->tree_model_node_changed_id = 0; + priv->tree_model_node_data_changed_id = 0; + priv->tree_model_node_col_changed_id = 0; + priv->tree_model_node_inserted_id = 0; + priv->tree_model_node_removed_id = 0; + } static void |