From 9c939e7a9964b860fcfa5bdc0ca13aeaa2d74f36 Mon Sep 17 00:00:00 2001 From: Christopher James Lahey Date: Fri, 8 Mar 2002 21:45:03 +0000 Subject: Handle a collapse request by marking all descendents of that node as 2002-03-08 Christopher James Lahey * e-tree-memory.c (etmm_node_request_collapse): Handle a collapse request by marking all descendents of that node as needing their children recomputed. * e-tree-model.c, e-tree-model.h (e_tree_model_node_request_collapse): Added this signal to request that the view of your tree collapse this node. * e-tree-selection-model.c (etsm_selected_count): Pass the root of the sorted model here instead of the root of the base model. * e-tree-table-adapter.c (etta_proxy_node_request_collapse): Handle a collapse request by collapsing the node in the tree. svn path=/trunk/; revision=15990 --- widgets/table/e-tree-memory.c | 48 ++++++++++---- widgets/table/e-tree-model.c | 114 ++++++++++++++++++++------------- widgets/table/e-tree-model.h | 81 ++++++++++++----------- widgets/table/e-tree-selection-model.c | 2 +- widgets/table/e-tree-table-adapter.c | 73 ++++++++++++--------- 5 files changed, 193 insertions(+), 125 deletions(-) diff --git a/widgets/table/e-tree-memory.c b/widgets/table/e-tree-memory.c index 74c160ab9f..27948727f7 100644 --- a/widgets/table/e-tree-memory.c +++ b/widgets/table/e-tree-memory.c @@ -329,6 +329,26 @@ etmm_get_expanded_default (ETreeModel *etm) return priv->expanded_default; } +static void +etmm_clear_children_computed (ETreeMemoryPath *path) +{ + for (path = path->first_child; path; path = path->next_sibling) { + path->children_computed = FALSE; + etmm_clear_children_computed (path); + } +} + +static void +etmm_node_request_collapse (ETreeModel *etm, ETreePath node) +{ + if (node) + etmm_clear_children_computed (node); + + if (parent_class->node_request_collapse) { + parent_class->node_request_collapse (etm, node); + } +} + static void e_tree_memory_class_init (ETreeMemoryClass *klass) @@ -350,22 +370,24 @@ e_tree_memory_class_init (ETreeMemoryClass *klass) E_OBJECT_CLASS_ADD_SIGNALS (object_class, signals, LAST_SIGNAL); - object_class->destroy = etmm_destroy; + object_class->destroy = etmm_destroy; + + tree_class->get_root = etmm_get_root; + tree_class->get_prev = etmm_get_prev; + tree_class->get_next = etmm_get_next; + tree_class->get_first_child = etmm_get_first_child; + tree_class->get_last_child = etmm_get_last_child; + tree_class->get_parent = etmm_get_parent; - tree_class->get_root = etmm_get_root; - tree_class->get_prev = etmm_get_prev; - tree_class->get_next = etmm_get_next; - tree_class->get_first_child = etmm_get_first_child; - tree_class->get_last_child = etmm_get_last_child; - tree_class->get_parent = etmm_get_parent; + tree_class->is_root = etmm_is_root; + tree_class->is_expandable = etmm_is_expandable; + tree_class->get_children = etmm_get_children; + tree_class->depth = etmm_depth; + tree_class->get_expanded_default = etmm_get_expanded_default; - tree_class->is_root = etmm_is_root; - tree_class->is_expandable = etmm_is_expandable; - tree_class->get_children = etmm_get_children; - tree_class->depth = etmm_depth; - tree_class->get_expanded_default = etmm_get_expanded_default; + tree_class->node_request_collapse = etmm_node_request_collapse; - klass->fill_in_children = NULL; + klass->fill_in_children = NULL; } static void diff --git a/widgets/table/e-tree-model.c b/widgets/table/e-tree-model.c index ed15f28f8c..9b205bbc51 100644 --- a/widgets/table/e-tree-model.c +++ b/widgets/table/e-tree-model.c @@ -53,6 +53,7 @@ enum { NODE_INSERTED, NODE_REMOVED, NODE_DELETED, + NODE_REQUEST_COLLAPSE, LAST_SIGNAL }; @@ -130,51 +131,60 @@ e_tree_model_class_init (GtkObjectClass *klass) gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER); + e_tree_model_signals [NODE_REQUEST_COLLAPSE] = + gtk_signal_new ("node_request_collapse", + GTK_RUN_LAST, + E_OBJECT_CLASS_TYPE (klass), + GTK_SIGNAL_OFFSET (ETreeModelClass, node_request_collapse), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, GTK_TYPE_POINTER); + E_OBJECT_CLASS_ADD_SIGNALS (klass, e_tree_model_signals, LAST_SIGNAL); - tree_class->get_root = NULL; - - tree_class->get_parent = NULL; - tree_class->get_first_child = NULL; - tree_class->get_last_child = NULL; - tree_class->get_next = NULL; - tree_class->get_prev = NULL; - - tree_class->is_root = NULL; - tree_class->is_expandable = NULL; - tree_class->get_children = NULL; - tree_class->depth = NULL; - - tree_class->icon_at = NULL; - - tree_class->get_expanded_default = NULL; - tree_class->column_count = NULL; - - tree_class->has_save_id = NULL; - tree_class->get_save_id = NULL; - tree_class->has_get_node_by_id = NULL; - tree_class->get_node_by_id = NULL; - - tree_class->has_change_pending = NULL; - - tree_class->value_at = NULL; - tree_class->set_value_at = NULL; - tree_class->is_editable = NULL; - - tree_class->duplicate_value = NULL; - tree_class->free_value = NULL; - tree_class->initialize_value = NULL; - tree_class->value_is_empty = NULL; - tree_class->value_to_string = NULL; - - tree_class->pre_change = NULL; - tree_class->no_change = NULL; - tree_class->node_changed = NULL; - tree_class->node_data_changed = NULL; - tree_class->node_col_changed = NULL; - tree_class->node_inserted = NULL; - tree_class->node_removed = NULL; - tree_class->node_deleted = NULL; + tree_class->get_root = NULL; + + tree_class->get_parent = NULL; + tree_class->get_first_child = NULL; + tree_class->get_last_child = NULL; + tree_class->get_next = NULL; + tree_class->get_prev = NULL; + + tree_class->is_root = NULL; + tree_class->is_expandable = NULL; + tree_class->get_children = NULL; + tree_class->depth = NULL; + + tree_class->icon_at = NULL; + + tree_class->get_expanded_default = NULL; + tree_class->column_count = NULL; + + tree_class->has_save_id = NULL; + tree_class->get_save_id = NULL; + tree_class->has_get_node_by_id = NULL; + tree_class->get_node_by_id = NULL; + + tree_class->has_change_pending = NULL; + + tree_class->value_at = NULL; + tree_class->set_value_at = NULL; + tree_class->is_editable = NULL; + + tree_class->duplicate_value = NULL; + tree_class->free_value = NULL; + tree_class->initialize_value = NULL; + tree_class->value_is_empty = NULL; + tree_class->value_to_string = NULL; + + tree_class->pre_change = NULL; + tree_class->no_change = NULL; + tree_class->node_changed = NULL; + tree_class->node_data_changed = NULL; + tree_class->node_col_changed = NULL; + tree_class->node_inserted = NULL; + tree_class->node_removed = NULL; + tree_class->node_deleted = NULL; + tree_class->node_request_collapse = NULL; } static void @@ -340,6 +350,24 @@ e_tree_model_node_deleted (ETreeModel *tree_model, ETreePath deleted_node) deleted_node); } +/** + * e_tree_model_node_request_collapse: + * @tree_model: + * @collapsed_node: + * + * + **/ +void +e_tree_model_node_request_collapse (ETreeModel *tree_model, ETreePath collapsed_node) +{ + g_return_if_fail (tree_model != NULL); + g_return_if_fail (E_IS_TREE_MODEL (tree_model)); + + gtk_signal_emit (GTK_OBJECT (tree_model), + e_tree_model_signals [NODE_REQUEST_COLLAPSE], + collapsed_node); +} + /** diff --git a/widgets/table/e-tree-model.h b/widgets/table/e-tree-model.h index bd3714b847..cf4a7ac68c 100644 --- a/widgets/table/e-tree-model.h +++ b/widgets/table/e-tree-model.h @@ -27,10 +27,9 @@ #include #include +#include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +BEGIN_GNOME_DECLS #define E_TREE_MODEL_TYPE (e_tree_model_get_type ()) @@ -63,53 +62,59 @@ struct ETreeModelClass { ETreePath (*get_next) (ETreeModel *etm, ETreePath node); ETreePath (*get_prev) (ETreeModel *etm, ETreePath node); - gboolean (*is_root) (ETreeModel *etm, ETreePath node); - gboolean (*is_expandable) (ETreeModel *etm, ETreePath node); - guint (*get_children) (ETreeModel *etm, ETreePath node, ETreePath **paths); - guint (*depth) (ETreeModel *etm, ETreePath node); + gboolean (*is_root) (ETreeModel *etm, ETreePath node); + gboolean (*is_expandable) (ETreeModel *etm, ETreePath node); + guint (*get_children) (ETreeModel *etm, ETreePath node, ETreePath **paths); + guint (*depth) (ETreeModel *etm, ETreePath node); - GdkPixbuf *(*icon_at) (ETreeModel *etm, ETreePath node); + GdkPixbuf *(*icon_at) (ETreeModel *etm, ETreePath node); - gboolean (*get_expanded_default) (ETreeModel *etm); - gint (*column_count) (ETreeModel *etm); + gboolean (*get_expanded_default) (ETreeModel *etm); + gint (*column_count) (ETreeModel *etm); - gboolean (*has_save_id) (ETreeModel *etm); - gchar *(*get_save_id) (ETreeModel *etm, ETreePath node); + gboolean (*has_save_id) (ETreeModel *etm); + gchar *(*get_save_id) (ETreeModel *etm, ETreePath node); - gboolean (*has_get_node_by_id) (ETreeModel *etm); - ETreePath (*get_node_by_id) (ETreeModel *etm, const char *save_id); + gboolean (*has_get_node_by_id) (ETreeModel *etm); + ETreePath (*get_node_by_id) (ETreeModel *etm, const char *save_id); - gboolean (*has_change_pending) (ETreeModel *etm); + gboolean (*has_change_pending) (ETreeModel *etm); /* * ETable analogs */ - void *(*value_at) (ETreeModel *etm, ETreePath node, int col); - void (*set_value_at) (ETreeModel *etm, ETreePath node, int col, const void *val); - gboolean (*is_editable) (ETreeModel *etm, ETreePath node, int col); - - void *(*duplicate_value) (ETreeModel *etm, int col, const void *value); - void (*free_value) (ETreeModel *etm, int col, void *value); - void *(*initialize_value) (ETreeModel *etm, int col); - gboolean (*value_is_empty) (ETreeModel *etm, int col, const void *value); - char *(*value_to_string) (ETreeModel *etm, int col, const void *value); + void *(*value_at) (ETreeModel *etm, ETreePath node, int col); + void (*set_value_at) (ETreeModel *etm, ETreePath node, int col, const void *val); + gboolean (*is_editable) (ETreeModel *etm, ETreePath node, int col); + + void *(*duplicate_value) (ETreeModel *etm, int col, const void *value); + void (*free_value) (ETreeModel *etm, int col, void *value); + void *(*initialize_value) (ETreeModel *etm, int col); + gboolean (*value_is_empty) (ETreeModel *etm, int col, const void *value); + char *(*value_to_string) (ETreeModel *etm, int col, const void *value); /* * Signals */ - /* During remove, the ETreePath of the child is removed from - * the tree but is still valid. At node_deleted, the - * ETreePath is no longer valid. + + /* During node_remove, the ETreePath of the child is removed + * from the tree but is still a valid ETreePath. At + * node_deleted, the ETreePath is no longer valid. */ - void (*pre_change) (ETreeModel *etm); - void (*no_change) (ETreeModel *etm); - void (*node_changed) (ETreeModel *etm, ETreePath node); - void (*node_data_changed) (ETreeModel *etm, ETreePath node); - void (*node_col_changed) (ETreeModel *etm, ETreePath node, int col); - void (*node_inserted) (ETreeModel *etm, ETreePath parent, ETreePath inserted_node); - void (*node_removed) (ETreeModel *etm, ETreePath parent, ETreePath removed_node, int old_position); - void (*node_deleted) (ETreeModel *etm, ETreePath deleted_node); + void (*pre_change) (ETreeModel *etm); + void (*no_change) (ETreeModel *etm); + void (*node_changed) (ETreeModel *etm, ETreePath node); + void (*node_data_changed) (ETreeModel *etm, ETreePath node); + void (*node_col_changed) (ETreeModel *etm, ETreePath node, int col); + void (*node_inserted) (ETreeModel *etm, ETreePath parent, ETreePath inserted_node); + void (*node_removed) (ETreeModel *etm, ETreePath parent, ETreePath removed_node, int old_position); + void (*node_deleted) (ETreeModel *etm, ETreePath deleted_node); + + /* This signal requests that any viewers of the tree that + * collapse and expand nodes collapse this node. + */ + void (*node_request_collapse) (ETreeModel *etm, ETreePath node); }; @@ -212,9 +217,9 @@ void e_tree_model_node_removed (ETreeModel *tree_model, int old_position); void e_tree_model_node_deleted (ETreeModel *tree_model, ETreePath deleted_node); +void e_tree_model_node_request_collapse (ETreeModel *tree_model, + ETreePath deleted_node); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +END_GNOME_DECLS #endif /* _E_TREE_MODEL_H */ diff --git a/widgets/table/e-tree-selection-model.c b/widgets/table/e-tree-selection-model.c index f139653ab5..7b0e306be0 100644 --- a/widgets/table/e-tree-selection-model.c +++ b/widgets/table/e-tree-selection-model.c @@ -920,7 +920,7 @@ etsm_selected_count (ESelectionModel *selection) ETreePath model_root; model_root = e_tree_model_get_root(etsm->priv->model); etsm_selected_count_recurse(etsm, etsm->priv->root, model_root, &count); - if (!e_tree_table_adapter_root_node_is_visible (etsm->priv->etta) && etsm_is_path_selected (etsm, e_tree_model_get_root(etsm->priv->model))) { + if (!e_tree_table_adapter_root_node_is_visible (etsm->priv->etta) && etsm_is_path_selected (etsm, e_tree_model_get_root(E_TREE_MODEL (etsm->priv->ets)))) { count --; } } diff --git a/widgets/table/e-tree-table-adapter.c b/widgets/table/e-tree-table-adapter.c index 634240d8f7..a907efa56b 100644 --- a/widgets/table/e-tree-table-adapter.c +++ b/widgets/table/e-tree-table-adapter.c @@ -58,6 +58,7 @@ struct ETreeTableAdapterPriv { int tree_model_node_col_changed_id; int tree_model_node_inserted_id; int tree_model_node_removed_id; + int tree_model_node_request_collapse_id; }; typedef struct ETreeTableAdapterNode { @@ -404,6 +405,8 @@ etta_destroy (GtkObject *object) etta->priv->tree_model_node_inserted_id); gtk_signal_disconnect (GTK_OBJECT (etta->priv->source), etta->priv->tree_model_node_removed_id); + gtk_signal_disconnect (GTK_OBJECT (etta->priv->source), + etta->priv->tree_model_node_request_collapse_id); gtk_object_unref (GTK_OBJECT (etta->priv->source)); etta->priv->source = NULL; @@ -415,6 +418,7 @@ etta_destroy (GtkObject *object) etta->priv->tree_model_node_col_changed_id = 0; etta->priv->tree_model_node_inserted_id = 0; etta->priv->tree_model_node_removed_id = 0; + etta->priv->tree_model_node_request_collapse_id = 0; } g_free (etta->priv->map_table); @@ -608,26 +612,27 @@ etta_class_init (ETreeTableAdapterClass *klass) static void etta_init (ETreeTableAdapter *etta) { - etta->priv = g_new(ETreeTableAdapterPriv, 1); + etta->priv = g_new(ETreeTableAdapterPriv, 1); - etta->priv->source = NULL; + etta->priv->source = NULL; - etta->priv->n_map = 0; - etta->priv->n_vals_allocated = 0; - etta->priv->map_table = NULL; - etta->priv->attributes = NULL; + etta->priv->n_map = 0; + etta->priv->n_vals_allocated = 0; + etta->priv->map_table = NULL; + etta->priv->attributes = NULL; - etta->priv->root_visible = TRUE; + etta->priv->root_visible = TRUE; - etta->priv->last_access = 0; + etta->priv->last_access = 0; - etta->priv->tree_model_pre_change_id = 0; - etta->priv->tree_model_no_change_id = 0; - etta->priv->tree_model_node_changed_id = 0; - etta->priv->tree_model_node_data_changed_id = 0; - etta->priv->tree_model_node_col_changed_id = 0; - etta->priv->tree_model_node_inserted_id = 0; - etta->priv->tree_model_node_removed_id = 0; + etta->priv->tree_model_pre_change_id = 0; + etta->priv->tree_model_no_change_id = 0; + etta->priv->tree_model_node_changed_id = 0; + etta->priv->tree_model_node_data_changed_id = 0; + etta->priv->tree_model_node_col_changed_id = 0; + etta->priv->tree_model_node_inserted_id = 0; + etta->priv->tree_model_node_removed_id = 0; + etta->priv->tree_model_node_request_collapse_id = 0; } E_MAKE_TYPE(e_tree_table_adapter, "ETreeTableAdapter", ETreeTableAdapter, etta_class_init, etta_init, PARENT_TYPE); @@ -784,7 +789,7 @@ etta_proxy_node_inserted (ETreeModel *etm, ETreePath parent, ETreePath child, ET } static void -etta_proxy_node_removed (ETableModel *etm, ETreePath parent, ETreePath child, int old_position, ETreeTableAdapter *etta) +etta_proxy_node_removed (ETreeModel *etm, ETreePath parent, ETreePath child, int old_position, ETreeTableAdapter *etta) { int parent_row = find_row_num(etta, parent); int row = find_child_row_num_maybe_deleted(etta, parent_row, child); @@ -825,6 +830,12 @@ etta_proxy_node_removed (ETableModel *etm, ETreePath parent, ETreePath child, in e_table_model_no_change(E_TABLE_MODEL(etta)); } +static void +etta_proxy_node_request_collapse (ETreeModel *etm, ETreePath node, ETreeTableAdapter *etta) +{ + e_tree_table_adapter_node_set_expanded(etta, node, FALSE); +} + ETableModel * e_tree_table_adapter_construct (ETreeTableAdapter *etta, ETreeModel *source) { @@ -847,20 +858,22 @@ e_tree_table_adapter_construct (ETreeTableAdapter *etta, ETreeModel *source) fill_array_from_path(etta, etta->priv->map_table, root); } - etta->priv->tree_model_pre_change_id = gtk_signal_connect (GTK_OBJECT (source), "pre_change", - GTK_SIGNAL_FUNC (etta_proxy_pre_change), etta); - etta->priv->tree_model_no_change_id = gtk_signal_connect (GTK_OBJECT (source), "no_change", - GTK_SIGNAL_FUNC (etta_proxy_no_change), etta); - etta->priv->tree_model_node_changed_id = gtk_signal_connect (GTK_OBJECT (source), "node_changed", - GTK_SIGNAL_FUNC (etta_proxy_node_changed), etta); - etta->priv->tree_model_node_data_changed_id = gtk_signal_connect (GTK_OBJECT (source), "node_data_changed", - GTK_SIGNAL_FUNC (etta_proxy_node_data_changed), etta); - etta->priv->tree_model_node_col_changed_id = gtk_signal_connect (GTK_OBJECT (source), "node_col_changed", - GTK_SIGNAL_FUNC (etta_proxy_node_col_changed), etta); - etta->priv->tree_model_node_inserted_id = gtk_signal_connect (GTK_OBJECT (source), "node_inserted", - GTK_SIGNAL_FUNC (etta_proxy_node_inserted), etta); - etta->priv->tree_model_node_removed_id = gtk_signal_connect (GTK_OBJECT (source), "node_removed", - GTK_SIGNAL_FUNC (etta_proxy_node_removed), etta); + etta->priv->tree_model_pre_change_id = gtk_signal_connect (GTK_OBJECT (source), "pre_change", + GTK_SIGNAL_FUNC (etta_proxy_pre_change), etta); + etta->priv->tree_model_no_change_id = gtk_signal_connect (GTK_OBJECT (source), "no_change", + GTK_SIGNAL_FUNC (etta_proxy_no_change), etta); + etta->priv->tree_model_node_changed_id = gtk_signal_connect (GTK_OBJECT (source), "node_changed", + GTK_SIGNAL_FUNC (etta_proxy_node_changed), etta); + etta->priv->tree_model_node_data_changed_id = gtk_signal_connect (GTK_OBJECT (source), "node_data_changed", + GTK_SIGNAL_FUNC (etta_proxy_node_data_changed), etta); + etta->priv->tree_model_node_col_changed_id = gtk_signal_connect (GTK_OBJECT (source), "node_col_changed", + GTK_SIGNAL_FUNC (etta_proxy_node_col_changed), etta); + etta->priv->tree_model_node_inserted_id = gtk_signal_connect (GTK_OBJECT (source), "node_inserted", + GTK_SIGNAL_FUNC (etta_proxy_node_inserted), etta); + etta->priv->tree_model_node_removed_id = gtk_signal_connect (GTK_OBJECT (source), "node_removed", + GTK_SIGNAL_FUNC (etta_proxy_node_removed), etta); + etta->priv->tree_model_node_request_collapse_id = gtk_signal_connect (GTK_OBJECT (source), "node_request_collapse", + GTK_SIGNAL_FUNC (etta_proxy_node_request_collapse), etta); return E_TABLE_MODEL (etta); } -- cgit v1.2.3