aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/table/e-tree-selection-model.c
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/table/e-tree-selection-model.c')
-rw-r--r--widgets/table/e-tree-selection-model.c649
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