diff options
Diffstat (limited to 'widgets/table/e-tree-table-adapter.c')
-rw-r--r-- | widgets/table/e-tree-table-adapter.c | 1174 |
1 files changed, 0 insertions, 1174 deletions
diff --git a/widgets/table/e-tree-table-adapter.c b/widgets/table/e-tree-table-adapter.c deleted file mode 100644 index e1bda25eba..0000000000 --- a/widgets/table/e-tree-table-adapter.c +++ /dev/null @@ -1,1174 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-tree-table-adapter.c - * Copyright 2000, 2001, Ximian, Inc. - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Chris Toshok <toshok@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include <libxml/tree.h> -#include <libxml/parser.h> -#include "gal/util/e-util.h" -#include "gal/util/e-xml-utils.h" -#include "e-tree-table-adapter.h" -#include "e-table-sorting-utils.h" - -#define PARENT_TYPE E_TABLE_MODEL_TYPE -#define d(x) - -#define INCREMENT_AMOUNT 100 - -static ETableModelClass *parent_class; - -typedef struct { - ETreePath path; - guint32 num_visible_children; - guint32 index; - - guint expanded : 1; - guint expandable : 1; - guint expandable_set : 1; -} node_t; - -struct ETreeTableAdapterPriv { - ETreeModel *source; - ETableSortInfo *sort_info; - ETableHeader *header; - - int n_map; - int n_vals_allocated; - node_t **map_table; - GHashTable *nodes; - GNode *root; - - guint root_visible : 1; - guint remap_needed : 1; - - int last_access; - - int pre_change_id; - int no_change_id; - int node_changed_id; - int node_data_changed_id; - int node_col_changed_id; - int node_inserted_id; - int node_removed_id; - int node_request_collapse_id; - int sort_info_changed_id; -}; - -static GNode * -lookup_gnode(ETreeTableAdapter *etta, ETreePath path) -{ - GNode *gnode; - - if (!path) - return NULL; - - gnode = g_hash_table_lookup(etta->priv->nodes, path); - - return gnode; -} - -static void -resize_map(ETreeTableAdapter *etta, int size) -{ - if (size > etta->priv->n_vals_allocated) { - etta->priv->n_vals_allocated = MAX(etta->priv->n_vals_allocated + INCREMENT_AMOUNT, size); - etta->priv->map_table = g_renew (node_t *, etta->priv->map_table, etta->priv->n_vals_allocated); - } - - etta->priv->n_map = size; -} - -static void -move_map_elements(ETreeTableAdapter *etta, int to, int from, int count) -{ - if (count <= 0 || from >= etta->priv->n_map) - return; - memmove(etta->priv->map_table + to, etta->priv->map_table + from, count * sizeof (node_t *)); - etta->priv->remap_needed = TRUE; -} - -static gint -fill_map(ETreeTableAdapter *etta, gint index, GNode *gnode) -{ - GNode *p; - - if ((gnode != etta->priv->root) || etta->priv->root_visible) - etta->priv->map_table[index++] = gnode->data; - - for (p = gnode->children; p; p = p->next) - index = fill_map(etta, index, p); - - etta->priv->remap_needed = TRUE; - return index; -} - -static void -remap_indices(ETreeTableAdapter *etta) -{ - int i; - for (i = 0; i < etta->priv->n_map; i++) - etta->priv->map_table[i]->index = i; - etta->priv->remap_needed = FALSE; -} - -static node_t * -get_node(ETreeTableAdapter *etta, ETreePath path) -{ - GNode *gnode = lookup_gnode(etta, path); - - if (!gnode) - return NULL; - - return (node_t *)gnode->data; -} - -static void -resort_node(ETreeTableAdapter *etta, GNode *gnode, gboolean recurse) -{ - node_t *node = (node_t *)gnode->data; - ETreePath *paths, path; - GNode *prev, *curr; - int i, count; - gboolean sort_needed; - - if (node->num_visible_children == 0) - return; - - sort_needed = etta->priv->sort_info && e_table_sort_info_sorting_get_count (etta->priv->sort_info) > 0; - - for (i = 0, path = e_tree_model_node_get_first_child(etta->priv->source, node->path); path; - path = e_tree_model_node_get_next(etta->priv->source, path), i++); - - count = i; - if (count <= 1) - return; - - paths = g_new0(ETreePath, count); - - for (i = 0, path = e_tree_model_node_get_first_child(etta->priv->source, node->path); path; - path = e_tree_model_node_get_next(etta->priv->source, path), i++) - paths[i] = path; - - if (count > 1 && sort_needed) - e_table_sorting_utils_tree_sort(etta->priv->source, etta->priv->sort_info, etta->priv->header, paths, count); - - prev = NULL; - for (i = 0; i < count; i++) { - curr = lookup_gnode(etta, paths[i]); - if (!curr) - continue; - - if (prev) - prev->next = curr; - else - gnode->children = curr; - - curr->prev = prev; - curr->next = NULL; - prev = curr; - if (recurse) - resort_node(etta, curr, recurse); - } - - g_free(paths); -} - -static gint -get_row(ETreeTableAdapter *etta, ETreePath path) -{ - node_t *node = get_node(etta, path); - if (!node) - return -1; - - if (etta->priv->remap_needed) - remap_indices(etta); - - return node->index; -} - -static ETreePath -get_path (ETreeTableAdapter *etta, int row) -{ - if (row == -1 && etta->priv->n_map > 0) - row = etta->priv->n_map - 1; - else if (row < 0 || row >= etta->priv->n_map) - return NULL; - - return etta->priv->map_table [row]->path; -} - -static void -kill_gnode(GNode *node, ETreeTableAdapter *etta) -{ - g_hash_table_remove(etta->priv->nodes, ((node_t *)node->data)->path); - - while (node->children) { - GNode *next = node->children->next; - kill_gnode(node->children, etta); - node->children = next; - } - - g_free(node->data); - if (node == etta->priv->root) - etta->priv->root = NULL; - g_node_destroy(node); -} - -static void -update_child_counts(GNode *gnode, gint delta) -{ - while (gnode) { - node_t *node = (node_t *) gnode->data; - node->num_visible_children += delta; - gnode = gnode->parent; - } -} - -static int -delete_children(ETreeTableAdapter *etta, GNode *gnode) -{ - node_t *node = (node_t *)gnode->data; - int to_remove = node ? node->num_visible_children : 0; - - if (to_remove == 0) - return 0; - - while (gnode->children) { - GNode *next = gnode->children->next; - kill_gnode(gnode->children, etta); - gnode->children = next; - } - - return to_remove; -} - -static void -delete_node(ETreeTableAdapter *etta, ETreePath parent, ETreePath path) -{ - int to_remove = 1; - int parent_row = get_row(etta, parent); - int row = get_row(etta, path); - GNode *gnode = lookup_gnode(etta, path); - GNode *parent_gnode = lookup_gnode(etta, parent); - - e_table_model_pre_change(E_TABLE_MODEL(etta)); - - if (row == -1) { - e_table_model_no_change(E_TABLE_MODEL(etta)); - return; - } - - to_remove += delete_children(etta, gnode); - kill_gnode(gnode, etta); - - move_map_elements(etta, row, row + to_remove, etta->priv->n_map - row - to_remove); - resize_map(etta, etta->priv->n_map - to_remove); - - if (parent_gnode != NULL) { - node_t *parent_node = parent_gnode->data; - gboolean expandable = e_tree_model_node_is_expandable(etta->priv->source, parent); - - update_child_counts(parent_gnode, - to_remove); - if (parent_node->expandable != expandable) { - e_table_model_pre_change(E_TABLE_MODEL(etta)); - parent_node->expandable = expandable; - e_table_model_row_changed(E_TABLE_MODEL(etta), parent_row); - } - - resort_node (etta, parent_gnode, FALSE); - } - - e_table_model_rows_deleted(E_TABLE_MODEL(etta), row, to_remove); -} - -static GNode * -create_gnode(ETreeTableAdapter *etta, ETreePath path) -{ - GNode *gnode; - node_t *node; - - node = g_new0(node_t, 1); - node->path = path; - node->index = -1; - node->expanded = e_tree_model_get_expanded_default(etta->priv->source); - node->expandable = e_tree_model_node_is_expandable(etta->priv->source, path); - node->expandable_set = 1; - node->num_visible_children = 0; - gnode = g_node_new(node); - g_hash_table_insert(etta->priv->nodes, path, gnode); - return gnode; -} - -static gint -insert_children(ETreeTableAdapter *etta, GNode *gnode) -{ - ETreePath path, tmp; - int count = 0; - int pos = 0; - - path = ((node_t *)gnode->data)->path; - for (tmp = e_tree_model_node_get_first_child(etta->priv->source, path); - tmp; - tmp = e_tree_model_node_get_next(etta->priv->source, tmp), pos++) { - GNode *child = create_gnode(etta, tmp); - node_t *node = (node_t *) child->data; - if (node->expanded) - node->num_visible_children = insert_children(etta, child); - g_node_prepend(gnode, child); - count += node->num_visible_children + 1; - } - g_node_reverse_children(gnode); - return count; -} - -static void -generate_tree(ETreeTableAdapter *etta, ETreePath path) -{ - GNode *gnode; - node_t *node; - int size; - - e_table_model_pre_change(E_TABLE_MODEL(etta)); - - g_assert(e_tree_model_node_is_root(etta->priv->source, path)); - - if (etta->priv->root) - kill_gnode(etta->priv->root, etta); - resize_map(etta, 0); - - gnode = create_gnode(etta, path); - node = (node_t *) gnode->data; - node->expanded = TRUE; - node->num_visible_children = insert_children(etta, gnode); - if (etta->priv->sort_info && e_table_sort_info_sorting_get_count(etta->priv->sort_info) > 0) - resort_node(etta, gnode, TRUE); - - etta->priv->root = gnode; - size = etta->priv->root_visible ? node->num_visible_children + 1 : node->num_visible_children; - resize_map(etta, size); - fill_map(etta, 0, gnode); - e_table_model_changed(E_TABLE_MODEL(etta)); -} - -static void -insert_node(ETreeTableAdapter *etta, ETreePath parent, ETreePath path) -{ - GNode *gnode, *parent_gnode; - node_t *node, *parent_node; - gboolean expandable; - int size, row; - - e_table_model_pre_change(E_TABLE_MODEL(etta)); - - if (get_node(etta, path)) { - e_table_model_no_change(E_TABLE_MODEL(etta)); - return; - } - - parent_gnode = lookup_gnode(etta, parent); - if (!parent_gnode) { - ETreePath grandparent = e_tree_model_node_get_parent(etta->priv->source, parent); - if (e_tree_model_node_is_root(etta->priv->source, parent)) - generate_tree(etta, parent); - else - insert_node(etta, grandparent, parent); - e_table_model_changed(E_TABLE_MODEL(etta)); - return; - } - - parent_node = (node_t *) parent_gnode->data; - - if (parent_gnode != etta->priv->root) { - expandable = e_tree_model_node_is_expandable(etta->priv->source, parent); - if (parent_node->expandable != expandable) { - e_table_model_pre_change(E_TABLE_MODEL(etta)); - parent_node->expandable = expandable; - parent_node->expandable_set = 1; - e_table_model_row_changed(E_TABLE_MODEL(etta), parent_node->index); - } - } - - if (!e_tree_table_adapter_node_is_expanded (etta, parent)) { - e_table_model_no_change(E_TABLE_MODEL(etta)); - return; - } - - gnode = create_gnode(etta, path); - node = (node_t *) gnode->data; - - if (node->expanded) - node->num_visible_children = insert_children(etta, gnode); - - g_node_append(parent_gnode, gnode); - update_child_counts(parent_gnode, node->num_visible_children + 1); - resort_node(etta, parent_gnode, FALSE); - resort_node(etta, gnode, TRUE); - - size = node->num_visible_children + 1; - resize_map(etta, etta->priv->n_map + size); - if (parent_gnode == etta->priv->root) - row = 0; - else { - gint new_size = parent_node->num_visible_children + 1; - gint old_size = new_size - size; - row = parent_node->index; - move_map_elements(etta, row + new_size, row + old_size, etta->priv->n_map - row - new_size); - } - fill_map(etta, row, parent_gnode); - e_table_model_rows_inserted(E_TABLE_MODEL(etta), get_row(etta, path), size); -} - -typedef struct { - GSList *paths; - gboolean expanded; -} check_expanded_closure; - -static gboolean -check_expanded(GNode *gnode, gpointer data) -{ - check_expanded_closure *closure = (check_expanded_closure *) data; - node_t *node = (node_t *) gnode->data; - - if (node->expanded != closure->expanded) - closure->paths = g_slist_prepend(closure->paths, node->path); - - return FALSE; -} - -static void -update_node(ETreeTableAdapter *etta, ETreePath path) -{ - check_expanded_closure closure; - ETreePath parent = e_tree_model_node_get_parent(etta->priv->source, path); - GNode *gnode = lookup_gnode(etta, path); - GSList *l; - - closure.expanded = e_tree_model_get_expanded_default (etta->priv->source); - closure.paths = NULL; - - if (gnode) - g_node_traverse(gnode, G_POST_ORDER, G_TRAVERSE_ALL, -1, check_expanded, &closure); - - if (e_tree_model_node_is_root(etta->priv->source, path)) - generate_tree(etta, path); - else { - delete_node(etta, parent, path); - insert_node(etta, parent, path); - } - - for (l = closure.paths; l; l = l->next) - if (lookup_gnode(etta, l->data)) - e_tree_table_adapter_node_set_expanded (etta, l->data, !closure.expanded); - - g_slist_free(closure.paths); -} - -static void -etta_finalize (GObject *object) -{ - ETreeTableAdapter *etta = E_TREE_TABLE_ADAPTER (object); - - if (etta->priv->root) { - kill_gnode(etta->priv->root, etta); - etta->priv->root = NULL; - } - - g_hash_table_destroy (etta->priv->nodes); - - g_free (etta->priv->map_table); - - g_free (etta->priv); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -etta_dispose (GObject *object) -{ - ETreeTableAdapter *etta = E_TREE_TABLE_ADAPTER (object); - - if (etta->priv->sort_info) { - g_signal_handler_disconnect(G_OBJECT (etta->priv->sort_info), - etta->priv->sort_info_changed_id); - g_object_unref(etta->priv->sort_info); - etta->priv->sort_info = NULL; - } - - if (etta->priv->header) { - g_object_unref(etta->priv->header); - etta->priv->header = NULL; - } - - if (etta->priv->source) { - g_signal_handler_disconnect (G_OBJECT (etta->priv->source), - etta->priv->pre_change_id); - g_signal_handler_disconnect (G_OBJECT (etta->priv->source), - etta->priv->no_change_id); - g_signal_handler_disconnect (G_OBJECT (etta->priv->source), - etta->priv->node_changed_id); - g_signal_handler_disconnect (G_OBJECT (etta->priv->source), - etta->priv->node_data_changed_id); - g_signal_handler_disconnect (G_OBJECT (etta->priv->source), - etta->priv->node_col_changed_id); - g_signal_handler_disconnect (G_OBJECT (etta->priv->source), - etta->priv->node_inserted_id); - g_signal_handler_disconnect (G_OBJECT (etta->priv->source), - etta->priv->node_removed_id); - g_signal_handler_disconnect (G_OBJECT (etta->priv->source), - etta->priv->node_request_collapse_id); - - g_object_unref (etta->priv->source); - etta->priv->source = NULL; - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static int -etta_column_count (ETableModel *etm) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - return e_tree_model_column_count (etta->priv->source); -} - -static gboolean -etta_has_save_id (ETableModel *etm) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - return e_tree_model_has_save_id (etta->priv->source); -} - -static gchar * -etta_get_save_id (ETableModel *etm, int row) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - return e_tree_model_get_save_id (etta->priv->source, get_path(etta, row)); -} - -static gboolean -etta_has_change_pending (ETableModel *etm) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - return e_tree_model_has_change_pending (etta->priv->source); -} - - -static int -etta_row_count (ETableModel *etm) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - return etta->priv->n_map; -} - -static void * -etta_value_at (ETableModel *etm, int col, int row) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - switch (col) { - case -1: - if (row == -1) - return NULL; - return get_path (etta, row); - case -2: - return etta->priv->source; - case -3: - return etta; - default: - return e_tree_model_value_at (etta->priv->source, get_path (etta, row), col); - } -} - -static void -etta_set_value_at (ETableModel *etm, int col, int row, const void *val) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - e_tree_model_set_value_at (etta->priv->source, get_path (etta, row), col, val); -} - -static gboolean -etta_is_cell_editable (ETableModel *etm, int col, int row) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - return e_tree_model_node_is_editable (etta->priv->source, get_path (etta, row), col); -} - -static void -etta_append_row (ETableModel *etm, ETableModel *source, int row) -{ -} - -static void * -etta_duplicate_value (ETableModel *etm, int col, const void *value) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - return e_tree_model_duplicate_value (etta->priv->source, col, value); -} - -static void -etta_free_value (ETableModel *etm, int col, void *value) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - e_tree_model_free_value (etta->priv->source, col, value); -} - -static void * -etta_initialize_value (ETableModel *etm, int col) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - return e_tree_model_initialize_value (etta->priv->source, col); -} - -static gboolean -etta_value_is_empty (ETableModel *etm, int col, const void *value) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - return e_tree_model_value_is_empty (etta->priv->source, col, value); -} - -static char * -etta_value_to_string (ETableModel *etm, int col, const void *value) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *)etm; - - return e_tree_model_value_to_string (etta->priv->source, col, value); -} - -static void -etta_class_init (ETreeTableAdapterClass *klass) -{ - ETableModelClass *table_class = (ETableModelClass *) klass; - GObjectClass *object_class = (GObjectClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = etta_dispose; - object_class->finalize = etta_finalize; - - table_class->column_count = etta_column_count; - table_class->row_count = etta_row_count; - table_class->append_row = etta_append_row; - - table_class->value_at = etta_value_at; - table_class->set_value_at = etta_set_value_at; - table_class->is_cell_editable = etta_is_cell_editable; - - table_class->has_save_id = etta_has_save_id; - table_class->get_save_id = etta_get_save_id; - - table_class->has_change_pending = etta_has_change_pending; - table_class->duplicate_value = etta_duplicate_value; - table_class->free_value = etta_free_value; - table_class->initialize_value = etta_initialize_value; - table_class->value_is_empty = etta_value_is_empty; - table_class->value_to_string = etta_value_to_string; -} - -static void -etta_init (ETreeTableAdapter *etta) -{ - etta->priv = g_new(ETreeTableAdapterPriv, 1); - - etta->priv->source = NULL; - etta->priv->sort_info = NULL; - - etta->priv->n_map = 0; - etta->priv->n_vals_allocated = 0; - etta->priv->map_table = NULL; - etta->priv->nodes = NULL; - etta->priv->root = NULL; - - etta->priv->root_visible = TRUE; - etta->priv->remap_needed = TRUE; - - etta->priv->pre_change_id = 0; - etta->priv->no_change_id = 0; - etta->priv->node_changed_id = 0; - etta->priv->node_data_changed_id = 0; - etta->priv->node_col_changed_id = 0; - etta->priv->node_inserted_id = 0; - etta->priv->node_removed_id = 0; - etta->priv->node_request_collapse_id = 0; -} - -E_MAKE_TYPE(e_tree_table_adapter, "ETreeTableAdapter", ETreeTableAdapter, etta_class_init, etta_init, PARENT_TYPE) - -static void -etta_proxy_pre_change (ETreeModel *etm, ETreeTableAdapter *etta) -{ - e_table_model_pre_change(E_TABLE_MODEL(etta)); -} - -static void -etta_proxy_no_change (ETreeModel *etm, ETreeTableAdapter *etta) -{ - e_table_model_no_change(E_TABLE_MODEL(etta)); -} - -static void -etta_proxy_node_changed (ETreeModel *etm, ETreePath path, ETreeTableAdapter *etta) -{ - update_node(etta, path); - - e_table_model_changed(E_TABLE_MODEL(etta)); -} - -static void -etta_proxy_node_data_changed (ETreeModel *etm, ETreePath path, ETreeTableAdapter *etta) -{ - int row = get_row(etta, path); - - if (row == -1) { - e_table_model_no_change(E_TABLE_MODEL(etta)); - return; - } - - e_table_model_row_changed(E_TABLE_MODEL(etta), row); -} - -static void -etta_proxy_node_col_changed (ETreeModel *etm, ETreePath path, int col, ETreeTableAdapter *etta) -{ - int row = get_row(etta, path); - - if (row == -1) { - e_table_model_no_change(E_TABLE_MODEL(etta)); - return; - } - - e_table_model_cell_changed(E_TABLE_MODEL(etta), col, row); -} - -static void -etta_proxy_node_inserted (ETreeModel *etm, ETreePath parent, ETreePath child, ETreeTableAdapter *etta) -{ - if (e_tree_model_node_is_root(etm, child)) - generate_tree(etta, child); - else - insert_node(etta, parent, child); - - e_table_model_changed(E_TABLE_MODEL(etta)); -} - -static void -etta_proxy_node_removed (ETreeModel *etm, ETreePath parent, ETreePath child, int old_position, ETreeTableAdapter *etta) -{ - delete_node(etta, parent, child); - e_table_model_changed(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); -} - -static void -etta_sort_info_changed (ETableSortInfo *sort_info, ETreeTableAdapter *etta) -{ - if (!etta->priv->root) - return; - - e_table_model_pre_change(E_TABLE_MODEL(etta)); - resort_node(etta, etta->priv->root, TRUE); - fill_map(etta, 0, etta->priv->root); - e_table_model_changed(E_TABLE_MODEL(etta)); -} - -ETableModel * -e_tree_table_adapter_construct (ETreeTableAdapter *etta, ETreeModel *source, ETableSortInfo *sort_info, ETableHeader *header) -{ - ETreePath root; - - etta->priv->source = source; - g_object_ref (source); - - etta->priv->sort_info = sort_info; - if (sort_info) { - g_object_ref(sort_info); - etta->priv->sort_info_changed_id = g_signal_connect (G_OBJECT (sort_info), "sort_info_changed", - G_CALLBACK (etta_sort_info_changed), etta); - } - - etta->priv->header = header; - if (header) - g_object_ref(header); - - etta->priv->nodes = g_hash_table_new(NULL, NULL); - - root = e_tree_model_get_root (source); - - if (root) - generate_tree(etta, root); - - etta->priv->pre_change_id = g_signal_connect(G_OBJECT(source), "pre_change", - G_CALLBACK (etta_proxy_pre_change), etta); - etta->priv->no_change_id = g_signal_connect (G_OBJECT (source), "no_change", - G_CALLBACK (etta_proxy_no_change), etta); - etta->priv->node_changed_id = g_signal_connect (G_OBJECT (source), "node_changed", - G_CALLBACK (etta_proxy_node_changed), etta); - etta->priv->node_data_changed_id = g_signal_connect (G_OBJECT (source), "node_data_changed", - G_CALLBACK (etta_proxy_node_data_changed), etta); - etta->priv->node_col_changed_id = g_signal_connect (G_OBJECT (source), "node_col_changed", - G_CALLBACK (etta_proxy_node_col_changed), etta); - etta->priv->node_inserted_id = g_signal_connect (G_OBJECT (source), "node_inserted", - G_CALLBACK (etta_proxy_node_inserted), etta); - etta->priv->node_removed_id = g_signal_connect (G_OBJECT (source), "node_removed", - G_CALLBACK (etta_proxy_node_removed), etta); - etta->priv->node_request_collapse_id = g_signal_connect (G_OBJECT (source), "node_request_collapse", - G_CALLBACK (etta_proxy_node_request_collapse), etta); - - return E_TABLE_MODEL (etta); -} - -ETableModel * -e_tree_table_adapter_new (ETreeModel *source, ETableSortInfo *sort_info, ETableHeader *header) -{ - ETreeTableAdapter *etta = g_object_new (E_TREE_TABLE_ADAPTER_TYPE, NULL); - - e_tree_table_adapter_construct (etta, source, sort_info, header); - - return (ETableModel *) etta; -} - -typedef struct { - xmlNode *root; - gboolean expanded_default; - ETreeModel *model; -} TreeAndRoot; - -static void -save_expanded_state_func (gpointer keyp, gpointer value, gpointer data) -{ - ETreePath path = keyp; - node_t *node = ((GNode *)value)->data; - TreeAndRoot *tar = data; - xmlNode *xmlnode; - - if (node->expanded != tar->expanded_default) { - gchar *save_id = e_tree_model_get_save_id(tar->model, path); - xmlnode = xmlNewChild (tar->root, NULL, "node", NULL); - e_xml_set_string_prop_by_name(xmlnode, "id", save_id); - g_free(save_id); - } -} - -void -e_tree_table_adapter_save_expanded_state (ETreeTableAdapter *etta, const char *filename) -{ - TreeAndRoot tar; - xmlDocPtr doc; - xmlNode *root; - - g_return_if_fail(etta != NULL); - - doc = xmlNewDoc ("1.0"); - root = xmlNewDocNode (doc, NULL, (xmlChar *) "expanded_state", NULL); - xmlDocSetRootElement (doc, root); - - tar.model = etta->priv->source; - tar.root = root; - tar.expanded_default = e_tree_model_get_expanded_default(etta->priv->source); - - e_xml_set_integer_prop_by_name (root, "vers", 2); - e_xml_set_bool_prop_by_name (root, "default", tar.expanded_default); - - g_hash_table_foreach (etta->priv->nodes, save_expanded_state_func, &tar); - - e_xml_save_file (filename, doc); - xmlFreeDoc (doc); -} - -static xmlDoc * -open_file (ETreeTableAdapter *etta, const char *filename) -{ - xmlDoc *doc; - xmlNode *root; - int vers; - gboolean model_default, saved_default; - - if (!g_file_test (filename, G_FILE_TEST_EXISTS)) - return NULL; - - doc = xmlParseFile (filename); - if (!doc) - return NULL; - - root = xmlDocGetRootElement (doc); - if (root == NULL || strcmp (root->name, "expanded_state")) { - xmlFreeDoc (doc); - return NULL; - } - - vers = e_xml_get_integer_prop_by_name_with_default (root, "vers", 0); - if (vers > 2) { - xmlFreeDoc (doc); - return NULL; - } - model_default = e_tree_model_get_expanded_default (etta->priv->source); - saved_default = e_xml_get_bool_prop_by_name_with_default (root, "default", !model_default); - if (saved_default != model_default) { - xmlFreeDoc (doc); - return NULL; - } - - return doc; -} - -void -e_tree_table_adapter_load_expanded_state (ETreeTableAdapter *etta, const char *filename) -{ - xmlDoc *doc; - xmlNode *root, *child; - gboolean model_default; - - g_return_if_fail(etta != NULL); - - doc = open_file(etta, filename); - if (!doc) - return; - - root = xmlDocGetRootElement (doc); - - e_table_model_pre_change(E_TABLE_MODEL(etta)); - - model_default = e_tree_model_get_expanded_default(etta->priv->source); - - for (child = root->xmlChildrenNode; child; child = child->next) { - char *id; - ETreePath path; - - if (strcmp (child->name, "node")) { - d(g_warning ("unknown node '%s' in %s", child->name, filename)); - continue; - } - - id = e_xml_get_string_prop_by_name_with_default (child, "id", ""); - - if (!strcmp(id, "")) { - g_free(id); - continue; - } - - path = e_tree_model_get_node_by_id(etta->priv->source, id); - if (path) - e_tree_table_adapter_node_set_expanded(etta, path, !model_default); - - g_free (id); - } - - xmlFreeDoc (doc); - - e_table_model_changed (E_TABLE_MODEL (etta)); -} - -void -e_tree_table_adapter_root_node_set_visible (ETreeTableAdapter *etta, gboolean visible) -{ - int size; - - if (etta->priv->root_visible == visible) - return; - - e_table_model_pre_change (E_TABLE_MODEL(etta)); - - etta->priv->root_visible = visible; - if (!visible) { - ETreePath root = e_tree_model_get_root(etta->priv->source); - if (root) - e_tree_table_adapter_node_set_expanded(etta, root, TRUE); - } - size = (visible ? 1 : 0) + (etta->priv->root ? ((node_t *)etta->priv->root->data)->num_visible_children : 0); - resize_map(etta, size); - if (etta->priv->root) - fill_map(etta, 0, etta->priv->root); - e_table_model_changed(E_TABLE_MODEL(etta)); -} - -void -e_tree_table_adapter_node_set_expanded (ETreeTableAdapter *etta, ETreePath path, gboolean expanded) -{ - GNode *gnode = lookup_gnode(etta, path); - node_t *node; - int row; - - if (!expanded && (!gnode || (e_tree_model_node_is_root (etta->priv->source, path) && !etta->priv->root_visible))) - return; - - if (!gnode && expanded) { - ETreePath parent = e_tree_model_node_get_parent(etta->priv->source, path); - g_return_if_fail(parent != NULL); - e_tree_table_adapter_node_set_expanded(etta, parent, expanded); - gnode = lookup_gnode(etta, path); - } - g_return_if_fail(gnode != NULL); - - node = (node_t *) gnode->data; - - if (expanded == node->expanded) - return; - - node->expanded = expanded; - - row = get_row(etta, path); - if (row == -1) - return; - - e_table_model_pre_change (E_TABLE_MODEL(etta)); - e_table_model_pre_change (E_TABLE_MODEL(etta)); - e_table_model_row_changed(E_TABLE_MODEL(etta), row); - - - if (expanded) { - int num_children = insert_children(etta, gnode); - update_child_counts(gnode, num_children); - if (etta->priv->sort_info && e_table_sort_info_sorting_get_count(etta->priv->sort_info) > 0) - resort_node(etta, gnode, TRUE); - resize_map(etta, etta->priv->n_map + num_children); - move_map_elements(etta, row + 1 + num_children, row + 1, etta->priv->n_map - row - 1 - num_children); - fill_map(etta, row, gnode); - if (num_children != 0) { - e_table_model_rows_inserted(E_TABLE_MODEL(etta), row + 1, num_children); - } else - e_table_model_no_change(E_TABLE_MODEL(etta)); - } else { - int num_children = delete_children(etta, gnode); - if (num_children == 0) { - e_table_model_no_change(E_TABLE_MODEL(etta)); - return; - } - move_map_elements(etta, row + 1, row + 1 + num_children, etta->priv->n_map - row - 1 - num_children); - update_child_counts(gnode, - num_children); - resize_map(etta, etta->priv->n_map - num_children); - e_table_model_rows_deleted(E_TABLE_MODEL(etta), row + 1, num_children); - } -} - -void -e_tree_table_adapter_node_set_expanded_recurse (ETreeTableAdapter *etta, ETreePath path, gboolean expanded) -{ - ETreePath children; - - e_tree_table_adapter_node_set_expanded(etta, path, expanded); - - for (children = e_tree_model_node_get_first_child(etta->priv->source, path); - children; - children = e_tree_model_node_get_next(etta->priv->source, children)) { - e_tree_table_adapter_node_set_expanded_recurse(etta, children, expanded); - } -} - -ETreePath -e_tree_table_adapter_node_at_row (ETreeTableAdapter *etta, int row) -{ - return get_path(etta, row); -} - -int -e_tree_table_adapter_row_of_node (ETreeTableAdapter *etta, ETreePath path) -{ - return get_row(etta, path); -} - -gboolean -e_tree_table_adapter_root_node_is_visible(ETreeTableAdapter *etta) -{ - return etta->priv->root_visible; -} - -void -e_tree_table_adapter_show_node (ETreeTableAdapter *etta, ETreePath path) -{ - ETreePath parent; - - parent = e_tree_model_node_get_parent(etta->priv->source, path); - - while (parent) { - e_tree_table_adapter_node_set_expanded(etta, parent, TRUE); - parent = e_tree_model_node_get_parent(etta->priv->source, parent); - } -} - -gboolean -e_tree_table_adapter_node_is_expanded (ETreeTableAdapter *etta, ETreePath path) -{ - node_t *node = get_node(etta, path); - if (!e_tree_model_node_is_expandable (etta->priv->source, path) || !node) - return FALSE; - - return node->expanded; -} - -void -e_tree_table_adapter_set_sort_info (ETreeTableAdapter *etta, ETableSortInfo *sort_info) -{ - if (etta->priv->sort_info) { - g_signal_handler_disconnect(G_OBJECT(etta->priv->sort_info), - etta->priv->sort_info_changed_id); - g_object_unref(etta->priv->sort_info); - } - - etta->priv->sort_info = sort_info; - if (sort_info) { - g_object_ref(sort_info); - etta->priv->sort_info_changed_id = g_signal_connect(G_OBJECT(sort_info), "sort_info_changed", - G_CALLBACK(etta_sort_info_changed), etta); - } - - if (!etta->priv->root) - return; - - e_table_model_pre_change(E_TABLE_MODEL(etta)); - resort_node(etta, etta->priv->root, TRUE); - fill_map(etta, 0, etta->priv->root); - e_table_model_changed(E_TABLE_MODEL(etta)); -} - -ETreePath -e_tree_table_adapter_node_get_next (ETreeTableAdapter *etta, ETreePath path) -{ - GNode *node = lookup_gnode (etta, path); - - if (node && node->next) - return ((node_t *)node->next->data)->path; - - return NULL; -} |