aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/table/e-tree-table-adapter.c
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/table/e-tree-table-adapter.c')
-rw-r--r--widgets/table/e-tree-table-adapter.c1193
1 files changed, 544 insertions, 649 deletions
diff --git a/widgets/table/e-tree-table-adapter.c b/widgets/table/e-tree-table-adapter.c
index 42366ebd21..16411c19ec 100644
--- a/widgets/table/e-tree-table-adapter.c
+++ b/widgets/table/e-tree-table-adapter.c
@@ -1,5 +1,5 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
+/*
* e-tree-table-adapter.c
* Copyright 2000, 2001, Ximian, Inc.
*
@@ -35,367 +35,416 @@
#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;
+ ETreeModel *source;
+ ETableSortInfo *sort_info;
+ ETableHeader *header;
+
int n_map;
int n_vals_allocated;
- ETreePath *map_table;
- GHashTable *attributes;
+ node_t **map_table;
+ GHashTable *nodes;
+ GNode *root;
guint root_visible : 1;
+ guint remap_needed : 1;
int last_access;
- int tree_model_pre_change_id;
- int tree_model_no_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;
- int tree_model_node_request_collapse_id;
+ 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;
};
-typedef struct ETreeTableAdapterNode {
- guint expanded : 1;
- guint expandable : 1;
- guint expandable_set : 1;
-
- /* parent/child/sibling pointers */
- guint32 num_visible_children;
-} ETreeTableAdapterNode;
-
-static ETreeTableAdapterNode *
-find_node(ETreeTableAdapter *adapter, ETreePath path)
+static GNode *
+lookup_gnode(ETreeTableAdapter *etta, ETreePath path)
{
- ETreeTableAdapterNode *node;
+ GNode *gnode;
- if (path == NULL)
+ if (!path)
return NULL;
- if (e_tree_model_has_save_id(adapter->priv->source)) {
- char *save_id;
- save_id = e_tree_model_get_save_id(adapter->priv->source, path);
- node = g_hash_table_lookup(adapter->priv->attributes, save_id);
- g_free(save_id);
- } else {
- node = g_hash_table_lookup(adapter->priv->attributes, path);
- }
- if (node && !node->expandable_set) {
- node->expandable = e_tree_model_node_is_expandable(adapter->priv->source, path);
- node->expandable_set = 1;
- }
+ gnode = g_hash_table_lookup(etta->priv->nodes, path);
- return node;
+ return gnode;
}
-static ETreeTableAdapterNode *
-find_or_create_node(ETreeTableAdapter *etta, ETreePath path)
+static void
+resize_map(ETreeTableAdapter *etta, int size)
{
- ETreeTableAdapterNode *node;
-
- node = find_node(etta, path);
+ 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);
+ }
- if (!node) {
- node = g_new(ETreeTableAdapterNode, 1);
- if (e_tree_model_node_is_root(etta->priv->source, path))
- node->expanded = TRUE;
- else
- 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;
-
- if (e_tree_model_has_save_id(etta->priv->source)) {
- char *save_id;
- save_id = e_tree_model_get_save_id(etta->priv->source, path);
- g_hash_table_insert(etta->priv->attributes, save_id, node);
- } else {
- g_hash_table_insert(etta->priv->attributes, path, node);
- }
- }
+ etta->priv->n_map = size;
+}
- return node;
+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 *));
}
-static gboolean
-e_tree_table_adapter_node_would_be_expanded (ETreeTableAdapter *etta, ETreePath path)
+static gint
+fill_map(ETreeTableAdapter *etta, gint index, GNode *gnode)
{
- ETreeTableAdapterNode *node;
-
- if (e_tree_model_node_is_root(etta->priv->source, path) &&
- !etta->priv->root_visible)
- return TRUE;
-
- node = find_node (etta, path);
- if (node)
- return node->expanded;
- else {
- if (e_tree_model_node_is_root(etta->priv->source, path))
- return TRUE;
- else
- return e_tree_model_get_expanded_default(etta->priv->source);
- }
+ 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
-add_expanded_node(ETreeTableAdapter *etta, char *save_id, gboolean expanded)
+remap_indices(ETreeTableAdapter *etta)
{
- ETreeTableAdapterNode *node;
+ int i;
+ for (i = 0; i < etta->priv->n_map; i++)
+ etta->priv->map_table[i]->index = i;
+ etta->priv->remap_needed = FALSE;
+}
- node = g_hash_table_lookup(etta->priv->attributes, save_id);
+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;
- if (node) {
- node->expandable_set = 0;
- node->expanded = expanded;
+ if (node->num_visible_children == 0 || !gnode->children)
+ return;
+ else if (node->num_visible_children == 1 && recurse) {
+ resort_node(etta, gnode->children, recurse);
return;
}
- node = g_new(ETreeTableAdapterNode, 1);
+ paths = g_new0(ETreePath, node->num_visible_children);
+
+ g_return_if_fail(paths != NULL);
- node->expanded = expanded;
- node->expandable = 0;
- node->expandable_set = 0;
- node->num_visible_children = 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++)
+ paths[i] = path;
- g_hash_table_insert(etta->priv->attributes, save_id, node);
-}
+ if (etta->priv->sort_info && e_table_sort_info_sorting_get_count > 0)
+ e_table_sorting_utils_tree_sort(etta->priv->source, etta->priv->sort_info, etta->priv->header, paths, node->num_visible_children);
-static void
-etta_expand_to(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 (ETreePath, etta->priv->map_table, etta->priv->n_vals_allocated);
+ prev = NULL;
+ for (i = 0; paths[i]; 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 void
-etta_update_parent_child_counts(ETreeTableAdapter *etta, ETreePath path, int change)
+static node_t *
+get_node(ETreeTableAdapter *etta, ETreePath path)
{
- for (path = e_tree_model_node_get_parent(etta->priv->source, path);
- path;
- path = e_tree_model_node_get_parent(etta->priv->source, path)) {
- ETreeTableAdapterNode *node = find_or_create_node(etta, path);
- node->num_visible_children += change;
- }
- etta->priv->n_map += change;
+ GNode *gnode = lookup_gnode(etta, path);
+
+ if (!gnode)
+ return NULL;
+
+ return (node_t *)gnode->data;
}
-static int
-find_next_node_maybe_deleted(ETreeTableAdapter *adapter, int row)
+static gint
+get_row(ETreeTableAdapter *etta, ETreePath path)
{
- ETreePath path = adapter->priv->map_table[row];
- if (path) {
- ETreeTableAdapterNode *current = find_node (adapter, path);
-
- row += (current ? current->num_visible_children : 0) + 1;
- if (row >= adapter->priv->n_map)
- return -1;
- return row;
- } else
+ node_t *node = get_node(etta, path);
+ if (!node)
return -1;
+
+ if (etta->priv->remap_needed)
+ remap_indices(etta);
+
+ return node->index;
}
-static int
-find_first_child_node_maybe_deleted(ETreeTableAdapter *adapter, int row)
+static ETreePath
+get_path (ETreeTableAdapter *etta, int row)
{
- if (row != -1) {
- ETreePath path = adapter->priv->map_table[row];
- if (e_tree_table_adapter_node_would_be_expanded (adapter, path)) {
- row ++;
- if (row >= adapter->priv->n_map)
- return -1;
- return row;
- } else
- return -1;
- } else
- return 0;
+ 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 int
-find_next_node(ETreeTableAdapter *adapter, int row)
+static void
+kill_gnode(GNode *node, ETreeTableAdapter *etta)
{
- ETreePath path = adapter->priv->map_table[row];
- if (path) {
- ETreePath next_sibling = e_tree_model_node_get_next(adapter->priv->source, path);
- ETreeTableAdapterNode *current = find_node (adapter, path);
- if (next_sibling) {
- row += (current ? current->num_visible_children : 0) + 1;
- if (row > adapter->priv->n_map)
- return -1;
- return row;
- } else
- return -1;
- } else
- return -1;
+ 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);
+ g_node_destroy(node);
}
-static int
-find_first_child_node(ETreeTableAdapter *adapter, int row)
+static void
+update_child_counts(GNode *gnode, gint delta)
{
- if (row != -1) {
- ETreePath path = adapter->priv->map_table[row];
- ETreePath first_child = e_tree_model_node_get_first_child(adapter->priv->source, path);
- if (first_child && e_tree_table_adapter_node_is_expanded (adapter, path)) {
- row ++;
- if (row > adapter->priv->n_map)
- return -1;
- return row;
- } else
- return -1;
- } else
- return 0;
+ while (gnode) {
+ node_t *node = (node_t *) gnode->data;
+ node->num_visible_children += delta;
+ gnode = gnode->parent;
+ }
}
static int
-find_child_row_num_maybe_deleted(ETreeTableAdapter *etta, int row, ETreePath path)
+delete_children(ETreeTableAdapter *etta, GNode *gnode)
{
- row = find_first_child_node_maybe_deleted(etta, row);
+ node_t *node = (node_t *)gnode->data;
+ int to_remove = node ? node->num_visible_children : 0;
- while (row != -1 && path != etta->priv->map_table[row]) {
- row = find_next_node_maybe_deleted(etta, row);
+ if (to_remove == 0)
+ return 0;
+
+ while (gnode->children) {
+ GNode *next = gnode->children->next;
+ kill_gnode(gnode->children, etta);
+ gnode->children = next;
}
- return row;
+ return to_remove;
}
-static int
-find_row_num(ETreeTableAdapter *etta, ETreePath path)
+static void
+delete_node(ETreeTableAdapter *etta, ETreePath parent, ETreePath path)
{
- int depth;
- ETreePath *sequence;
- int i;
- int row;
-
- if (etta->priv->map_table == NULL)
- return -1;
- if (etta->priv->n_map == 0)
- return -1;
+ int to_remove = 1;
+ int parent_row = get_row(etta, parent);
+ int row = get_row(etta, path);
+ GNode *gnode = lookup_gnode(etta, path);
- if (path == NULL)
- return -1;
+ e_table_model_pre_change(E_TABLE_MODEL(etta));
- if (etta->priv->last_access != -1) {
- int end = MIN(etta->priv->n_map, etta->priv->last_access + 10);
- int start = MAX(0, etta->priv->last_access - 10);
- int initial = MAX (MIN (etta->priv->last_access, end), start);
- for (i = initial; i < end; i++) {
- if(etta->priv->map_table[i] == path) {
- d(g_print("Found last access %d at row %d. (find_row_num)\n", etta->priv->last_access, i));
- return i;
- }
- }
- for (i = initial - 1; i >= start; i--) {
- if(etta->priv->map_table[i] == path) {
- d(g_print("Found last access %d at row %d. (find_row_num)\n", etta->priv->last_access, i));
- return i;
- }
- }
+ if (row == -1) {
+ e_table_model_no_change(E_TABLE_MODEL(etta));
+ return;
}
+ to_remove += delete_children(etta, gnode);
+ kill_gnode(gnode, etta);
- depth = e_tree_model_node_depth(etta->priv->source, path);
-
- sequence = g_new(ETreePath, depth + 1);
-
- sequence[0] = path;
+ move_map_elements(etta, row, row + to_remove, etta->priv->n_map - row - to_remove);
+ resize_map(etta, etta->priv->n_map - to_remove);
- for (i = 0; i < depth; i++) {
- sequence[i + 1] = e_tree_model_node_get_parent(etta->priv->source, sequence[i]);
-
- if (!e_tree_table_adapter_node_is_expanded (etta, sequence[i + 1])) {
- g_free(sequence);
- return -1;
+ if (parent_row != -1) {
+ node_t *parent_node = etta->priv->map_table[parent_row];
+ GNode *parent_gnode = lookup_gnode(etta, parent);
+ 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);
}
}
- row = 0;
-
- for (i = depth; i >= 0; i --) {
- while (row != -1 && row < etta->priv->n_map && sequence[i] != etta->priv->map_table[row]) {
- row = find_next_node(etta, row);
- }
- if (row >= etta->priv->n_map)
- break;
- if (row == -1)
- break;
- if (i == 0)
- break;
- row = find_first_child_node(etta, row);
- }
- g_free (sequence);
+ e_table_model_rows_deleted(E_TABLE_MODEL(etta), row, to_remove);
+}
- if (row >= etta->priv->n_map)
- row = -1;
+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;
+}
- d(g_print("Didn't find last access %d. Setting to %d. (find_row_num)\n", etta->priv->last_access, row));
- etta->priv->last_access = row;
- return row;
+static gint
+insert_children(ETreeTableAdapter *etta, GNode *gnode)
+{
+ ETreePath path, tmp;
+ int count = 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)) {
+ 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_append(gnode, child);
+ count += node->num_visible_children + 1;
+ }
+ return count;
}
-static int
-array_size_from_path(ETreeTableAdapter *etta, ETreePath path)
+static void
+generate_tree(ETreeTableAdapter *etta, ETreePath path)
{
- int size = 1;
+ GNode *gnode;
+ node_t *node;
+ int size;
- if (e_tree_table_adapter_node_is_expanded (etta, path)) {
- ETreePath children;
+ e_table_model_pre_change(E_TABLE_MODEL(etta));
- 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)) {
- size += array_size_from_path(etta, children);
- }
- }
+ g_assert(e_tree_model_node_is_root(etta->priv->source, path));
+
+ if (etta->priv->root)
+ kill_gnode(etta->priv->root, etta);
+
+ 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);
- return size;
+ 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 int
-fill_array_from_path(ETreeTableAdapter *etta, ETreePath *array, ETreePath path)
+static void
+insert_node(ETreeTableAdapter *etta, ETreePath parent, ETreePath path)
{
- ETreeTableAdapterNode *node = NULL;
- int index = 0;
+ GNode *gnode, *parent_gnode;
+ node_t *node, *parent_node;
+ gboolean expandable;
+ int size, row;
- array[index] = path;
+ e_table_model_pre_change(E_TABLE_MODEL(etta));
- index ++;
+ if (get_node(etta, path)) {
+ e_table_model_no_change(E_TABLE_MODEL(etta));
+ return;
+ }
- node = find_node(etta, path);
+ parent_gnode = lookup_gnode(etta, parent);
- if (e_tree_table_adapter_node_is_expanded (etta, path)) {
- ETreePath children;
+ g_return_if_fail(parent_gnode != NULL);
- if (!node)
- node = find_or_create_node(etta, path);
+ parent_node = (node_t *) parent_gnode->data;
+ 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);
+ }
- 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)) {
- index += fill_array_from_path(etta, array + index, children);
- }
+ if (!e_tree_table_adapter_node_is_expanded (etta, parent)) {
+ e_table_model_no_change(E_TABLE_MODEL(etta));
+ return;
}
- if (node)
- node->num_visible_children = index - 1;
+ gnode = create_gnode(etta, path);
+ node = (node_t *) gnode->data;
- return index;
+ if (node->expanded)
+ node->num_visible_children = insert_children(etta, gnode);
+
+ row = parent_node->index + parent_node->num_visible_children + 1;
+ g_node_append(parent_gnode, gnode);
+ update_child_counts(parent_gnode, node->num_visible_children + 1);
+ if (etta->priv->sort_info && e_table_sort_info_sorting_get_count(etta->priv->sort_info) > 0)
+ resort_node(etta, parent_gnode, TRUE);
+ size = node->num_visible_children + 1;
+
+ resize_map(etta, etta->priv->n_map + size);
+ if (etta->priv->n_map > 0)
+ move_map_elements(etta, row + size, row, etta->priv->n_map - row - size);
+ fill_map(etta, row, gnode);
+ e_table_model_rows_inserted(E_TABLE_MODEL(etta), row, size);
}
static void
-free_string (gpointer key, gpointer value, gpointer data)
+update_node(ETreeTableAdapter *etta, ETreePath path)
{
- g_free(key);
+ ETreePath parent = e_tree_model_node_get_parent(etta->priv->source, path);
+ delete_node(etta, parent, path);
+ if (e_tree_model_node_is_root(etta->priv->source, path))
+ generate_tree(etta, path);
+ else
+ insert_node(etta, parent, path);
+}
+
+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
@@ -403,57 +452,43 @@ etta_dispose (GObject *object)
{
ETreeTableAdapter *etta = E_TREE_TABLE_ADAPTER (object);
- if (etta->priv->source) {
- if (e_tree_model_has_save_id(etta->priv->source))
- g_hash_table_foreach(etta->priv->attributes, free_string, NULL);
+ 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->tree_model_pre_change_id);
+ etta->priv->pre_change_id);
g_signal_handler_disconnect (G_OBJECT (etta->priv->source),
- etta->priv->tree_model_no_change_id);
+ etta->priv->no_change_id);
g_signal_handler_disconnect (G_OBJECT (etta->priv->source),
- etta->priv->tree_model_node_changed_id);
+ etta->priv->node_changed_id);
g_signal_handler_disconnect (G_OBJECT (etta->priv->source),
- etta->priv->tree_model_node_data_changed_id);
+ etta->priv->node_data_changed_id);
g_signal_handler_disconnect (G_OBJECT (etta->priv->source),
- etta->priv->tree_model_node_col_changed_id);
+ etta->priv->node_col_changed_id);
g_signal_handler_disconnect (G_OBJECT (etta->priv->source),
- etta->priv->tree_model_node_inserted_id);
+ etta->priv->node_inserted_id);
g_signal_handler_disconnect (G_OBJECT (etta->priv->source),
- etta->priv->tree_model_node_removed_id);
+ etta->priv->node_removed_id);
g_signal_handler_disconnect (G_OBJECT (etta->priv->source),
- etta->priv->tree_model_node_request_collapse_id);
+ etta->priv->node_request_collapse_id);
g_object_unref (etta->priv->source);
etta->priv->source = NULL;
-
- 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;
}
G_OBJECT_CLASS (parent_class)->dispose (object);
}
-static void
-etta_finalize (GObject *object)
-{
- ETreeTableAdapter *etta = (ETreeTableAdapter *) object;
-
- g_hash_table_destroy (etta->priv->attributes);
- g_free (etta->priv->map_table);
-
- g_free (etta->priv);
- etta->priv = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
static int
etta_column_count (ETableModel *etm)
{
@@ -475,10 +510,7 @@ etta_get_save_id (ETableModel *etm, int row)
{
ETreeTableAdapter *etta = (ETreeTableAdapter *)etm;
- if (etta->priv->root_visible)
- return e_tree_model_get_save_id (etta->priv->source, etta->priv->map_table [row]);
- else
- return e_tree_model_get_save_id (etta->priv->source, etta->priv->map_table [row + 1]);
+ return e_tree_model_get_save_id (etta->priv->source, get_path(etta, row));
}
static gboolean
@@ -495,14 +527,7 @@ etta_row_count (ETableModel *etm)
{
ETreeTableAdapter *etta = (ETreeTableAdapter *)etm;
- if (etta->priv->root_visible)
- return etta->priv->n_map;
- else {
- if (etta->priv->n_map > 0)
- return etta->priv->n_map - 1;
- else
- return 0;
- }
+ return etta->priv->n_map;
}
static void *
@@ -512,19 +537,15 @@ etta_value_at (ETableModel *etm, int col, int row)
switch (col) {
case -1:
- if (etta->priv->root_visible)
- return etta->priv->map_table [row];
- else
- return etta->priv->map_table [row + 1];
+ if (row == -1)
+ return NULL;
+ return get_path (etta, row);
case -2:
return etta->priv->source;
case -3:
return etta;
default:
- if (etta->priv->root_visible)
- return e_tree_model_value_at (etta->priv->source, etta->priv->map_table [row], col);
- else
- return e_tree_model_value_at (etta->priv->source, etta->priv->map_table [row + 1], col);
+ return e_tree_model_value_at (etta->priv->source, get_path (etta, row), col);
}
}
@@ -533,12 +554,7 @@ etta_set_value_at (ETableModel *etm, int col, int row, const void *val)
{
ETreeTableAdapter *etta = (ETreeTableAdapter *)etm;
- etta->priv->last_access = row;
- d(g_print("h) Setting last_access to %d\n", row));
- if (etta->priv->root_visible)
- e_tree_model_set_value_at (etta->priv->source, etta->priv->map_table [row], col, val);
- else
- e_tree_model_set_value_at (etta->priv->source, etta->priv->map_table [row + 1], col, val);
+ e_tree_model_set_value_at (etta->priv->source, get_path (etta, row), col, val);
}
static gboolean
@@ -546,19 +562,12 @@ etta_is_cell_editable (ETableModel *etm, int col, int row)
{
ETreeTableAdapter *etta = (ETreeTableAdapter *)etm;
- if (etta->priv->root_visible)
- return e_tree_model_node_is_editable (etta->priv->source, etta->priv->map_table [row], col);
- else
- return e_tree_model_node_is_editable (etta->priv->source, etta->priv->map_table [row + 1], col);
+ 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)
{
-#if 0
- ETreeTableAdapter *etta = (ETreeTableAdapter *)etm;
- e_table_model_append_row (etta->priv->source, source, row);
-#endif
}
static void *
@@ -634,30 +643,31 @@ etta_class_init (ETreeTableAdapterClass *klass)
static void
etta_init (ETreeTableAdapter *etta)
{
- etta->priv = g_new(ETreeTableAdapterPriv, 1);
-
- 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->root_visible = TRUE;
-
- 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_node_request_collapse_id = 0;
+ 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, E_TABLE_MODEL_TYPE)
+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)
@@ -674,40 +684,7 @@ etta_proxy_no_change (ETreeModel *etm, ETreeTableAdapter *etta)
static void
etta_proxy_node_changed (ETreeModel *etm, ETreePath path, ETreeTableAdapter *etta)
{
- if (e_tree_model_node_is_root(etm, path)) {
- int size;
-
- size = array_size_from_path(etta, path);
- etta_expand_to(etta, size);
- etta->priv->n_map = size;
- fill_array_from_path(etta, etta->priv->map_table, path);
- } else {
- int row = find_row_num(etta, path);
- int size;
- int old_size;
- ETreeTableAdapterNode *node;
-
- if (row == -1) {
- e_table_model_no_change(E_TABLE_MODEL(etta));
- return;
- }
-
- size = array_size_from_path(etta, path);
-
- node = find_node(etta, path);
- if (node)
- old_size = node->num_visible_children + 1;
- else
- old_size = 1;
-
- etta_expand_to(etta, etta->priv->n_map + size - old_size);
-
- memmove(etta->priv->map_table + row + size,
- etta->priv->map_table + row + old_size,
- (etta->priv->n_map - row - old_size) * sizeof (ETreePath));
- fill_array_from_path(etta, etta->priv->map_table + row, path);
- etta_update_parent_child_counts(etta, path, size - old_size);
- }
+ update_node(etta, path);
e_table_model_changed(E_TABLE_MODEL(etta));
}
@@ -715,145 +692,38 @@ etta_proxy_node_changed (ETreeModel *etm, ETreePath path, ETreeTableAdapter *ett
static void
etta_proxy_node_data_changed (ETreeModel *etm, ETreePath path, ETreeTableAdapter *etta)
{
- int row = find_row_num(etta, path);
- if (row != -1) {
- if (etta->priv->root_visible)
- e_table_model_row_changed(E_TABLE_MODEL(etta), row);
- else if (row != 0)
- e_table_model_row_changed(E_TABLE_MODEL(etta), row - 1);
- else
- e_table_model_no_change(E_TABLE_MODEL(etta));
- } else
+ int row = get_row(etta, path);
+
+ if (row == -1)
e_table_model_no_change(E_TABLE_MODEL(etta));
+
+ 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 = find_row_num(etta, path);
- if (row != -1) {
- if (etta->priv->root_visible)
- e_table_model_cell_changed(E_TABLE_MODEL(etta), col, row);
- else if (row != 0)
- e_table_model_cell_changed(E_TABLE_MODEL(etta), col, row - 1);
- else
- e_table_model_no_change(E_TABLE_MODEL(etta));
- } else
+ int row = get_row(etta, path);
+
+ if (row == -1)
e_table_model_no_change(E_TABLE_MODEL(etta));
+
+ 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)
{
- int row;
-
- if (e_tree_model_node_is_root(etm, child)) {
- row = 0;
- } else {
- ETreePath children;
- int parent_row;
- ETreeTableAdapterNode *parent_node;
-
- parent_row = find_row_num(etta, parent);
- if (parent_row == -1) {
- e_table_model_no_change(E_TABLE_MODEL(etta));
- return;
- }
-
- parent_node = find_or_create_node(etta, parent);
- if (parent_node->expandable != e_tree_model_node_is_expandable(etta->priv->source, parent)) {
- e_table_model_pre_change(E_TABLE_MODEL(etta));
- parent_node->expandable = e_tree_model_node_is_expandable(etta->priv->source, parent);
- parent_node->expandable_set = 1;
- if (etta->priv->root_visible)
- e_table_model_row_changed(E_TABLE_MODEL(etta), parent_row);
- else if (parent_row != 0)
- e_table_model_row_changed(E_TABLE_MODEL(etta), parent_row - 1);
- else
- e_table_model_no_change(E_TABLE_MODEL(etta));
- }
-
- if (!e_tree_table_adapter_node_is_expanded (etta, parent)) {
- e_table_model_no_change(E_TABLE_MODEL(etta));
- return;
- }
-
- row = find_first_child_node(etta, parent_row);
- children = e_tree_model_node_get_first_child(etta->priv->source, parent);
-
- while (row != -1 &&
- row <= parent_row + parent_node->num_visible_children &&
- children != NULL &&
- children == etta->priv->map_table[row]) {
- children = e_tree_model_node_get_next(etta->priv->source, children);
- row = find_next_node(etta, row);
- }
- }
-
- if (row != -1) {
- int size;
-
- size = array_size_from_path(etta, child);
-
- etta_expand_to(etta, etta->priv->n_map + size);
-
- memmove(etta->priv->map_table + row + size,
- etta->priv->map_table + row,
- (etta->priv->n_map - row) * sizeof (ETreePath));
-
- fill_array_from_path(etta, etta->priv->map_table + row, child);
- etta_update_parent_child_counts(etta, child, size);
-
- if (etta->priv->root_visible)
- e_table_model_rows_inserted(E_TABLE_MODEL(etta), row, size);
- else if (row != 0)
- e_table_model_rows_inserted(E_TABLE_MODEL(etta), row - 1, size);
- else
- e_table_model_rows_inserted(E_TABLE_MODEL(etta), 0, size - 1);
- } else
- e_table_model_no_change(E_TABLE_MODEL(etta));
+ if (e_tree_model_node_is_root(etm, child))
+ generate_tree(etta, child);
+ else
+ insert_node(etta, parent, child);
}
static void
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);
- ETreeTableAdapterNode *parent_node = find_node(etta, parent);
- if (parent_row != -1 && parent_node) {
- if (parent_node->expandable != e_tree_model_node_is_expandable(etta->priv->source, parent)) {
- e_table_model_pre_change(E_TABLE_MODEL(etta));
- parent_node->expandable = e_tree_model_node_is_expandable(etta->priv->source, parent);
- if (etta->priv->root_visible)
- e_table_model_row_changed(E_TABLE_MODEL(etta), parent_row);
- else if (parent_row != 0)
- e_table_model_row_changed(E_TABLE_MODEL(etta), parent_row - 1);
- else
- e_table_model_no_change(E_TABLE_MODEL(etta));
- }
- }
-
- if (row != -1) {
- ETreeTableAdapterNode *node = find_node(etta, child);
- int to_remove = (node ? node->num_visible_children : 0) + 1;
-
- memmove(etta->priv->map_table + row,
- etta->priv->map_table + row + to_remove,
- (etta->priv->n_map - row - to_remove) * sizeof (ETreePath));
-
- if (parent_node)
- parent_node->num_visible_children -= to_remove;
- if (parent)
- etta_update_parent_child_counts(etta, parent, - to_remove);
-
- if (etta->priv->root_visible)
- e_table_model_rows_deleted(E_TABLE_MODEL(etta), row, to_remove);
- else if (row != 0)
- e_table_model_rows_deleted(E_TABLE_MODEL(etta), row - 1, to_remove);
- else
- e_table_model_rows_deleted(E_TABLE_MODEL(etta), 0, to_remove - 1);
- } else
- e_table_model_no_change(E_TABLE_MODEL(etta));
+ delete_node(etta, parent, child);
}
static void
@@ -862,154 +732,174 @@ etta_proxy_node_request_collapse (ETreeModel *etm, ETreePath node, ETreeTableAda
e_tree_table_adapter_node_set_expanded(etta, node, FALSE);
}
+static void
+etta_sort_info_changed (ETableSortInfo *sort_info, ETreeTableAdapter *etta)
+{
+ 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)
+e_tree_table_adapter_construct (ETreeTableAdapter *etta, ETreeModel *source, ETableSortInfo *sort_info, ETableHeader *header)
{
ETreePath root;
etta->priv->source = source;
g_object_ref (source);
- if (e_tree_model_has_save_id(source))
- etta->priv->attributes = g_hash_table_new(g_str_hash, g_str_equal);
- else
- etta->priv->attributes = g_hash_table_new(NULL, NULL);
+ 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);
+ }
- root = e_tree_model_get_root (source);
+ etta->priv->header = header;
+ if (header)
+ g_object_ref(header);
- if (root) {
- etta->priv->n_map = array_size_from_path(etta, root);
- etta->priv->n_vals_allocated = etta->priv->n_map;
- etta->priv->map_table = g_new(ETreePath, etta->priv->n_map);
- fill_array_from_path(etta, etta->priv->map_table, root);
- }
+ etta->priv->nodes = g_hash_table_new(NULL, NULL);
- etta->priv->tree_model_pre_change_id = g_signal_connect (G_OBJECT (source), "pre_change",
- G_CALLBACK (etta_proxy_pre_change), etta);
- etta->priv->tree_model_no_change_id = g_signal_connect (G_OBJECT (source), "no_change",
- G_CALLBACK (etta_proxy_no_change), etta);
- etta->priv->tree_model_node_changed_id = g_signal_connect (G_OBJECT (source), "node_changed",
- G_CALLBACK (etta_proxy_node_changed), etta);
- etta->priv->tree_model_node_data_changed_id = g_signal_connect (G_OBJECT (source), "node_data_changed",
- G_CALLBACK (etta_proxy_node_data_changed), etta);
- etta->priv->tree_model_node_col_changed_id = g_signal_connect (G_OBJECT (source), "node_col_changed",
- G_CALLBACK (etta_proxy_node_col_changed), etta);
- etta->priv->tree_model_node_inserted_id = g_signal_connect (G_OBJECT (source), "node_inserted",
- G_CALLBACK (etta_proxy_node_inserted), etta);
- etta->priv->tree_model_node_removed_id = g_signal_connect (G_OBJECT (source), "node_removed",
- G_CALLBACK (etta_proxy_node_removed), etta);
- etta->priv->tree_model_node_request_collapse_id = g_signal_connect (G_OBJECT (source), "node_request_collapse",
- G_CALLBACK (etta_proxy_node_request_collapse), etta);
+ 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)
+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);
+ e_tree_table_adapter_construct (etta, source, sort_info, header);
return (ETableModel *) etta;
}
typedef struct {
xmlNode *root;
- ETreeModel *tree;
+ gboolean expanded_default;
+ ETreeModel *model;
} TreeAndRoot;
static void
save_expanded_state_func (gpointer keyp, gpointer value, gpointer data)
{
- gchar *key = keyp;
- ETreeTableAdapterNode *node = value;
+ ETreePath path = keyp;
+ node_t *node = ((GNode *)value)->data;
TreeAndRoot *tar = data;
- xmlNode *root = tar->root;
- ETreeModel *etm = tar->tree;
xmlNode *xmlnode;
- if (node->expanded != e_tree_model_get_expanded_default(etm)) {
- xmlnode = xmlNewChild (root, NULL, "node", NULL);
- e_xml_set_string_prop_by_name(xmlnode, "id", key);
+ 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)
{
- ETreeTableAdapterPriv *priv;
TreeAndRoot tar;
xmlDocPtr doc;
xmlNode *root;
g_return_if_fail(etta != NULL);
- priv = etta->priv;
-
doc = xmlNewDoc ("1.0");
- root = xmlNewDocNode (doc, NULL,
- (xmlChar *) "expanded_state",
- NULL);
+ root = xmlNewDocNode (doc, NULL, (xmlChar *) "expanded_state", NULL);
xmlDocSetRootElement (doc, root);
- e_xml_set_integer_prop_by_name (root, "vers", 2);
- e_xml_set_bool_prop_by_name (root, "default", e_tree_model_get_expanded_default (priv->source));
-
+ tar.model = etta->priv->source;
tar.root = root;
- tar.tree = etta->priv->source;
+ tar.expanded_default = e_tree_model_get_expanded_default(etta->priv->source);
- g_hash_table_foreach (priv->attributes,
- save_expanded_state_func,
- &tar);
+ 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);
}
-void
-e_tree_table_adapter_load_expanded_state (ETreeTableAdapter *etta, const char *filename)
+static xmlDoc *
+open_file (ETreeTableAdapter *etta, const char *filename)
{
- ETreeTableAdapterPriv *priv;
xmlDoc *doc;
xmlNode *root;
- xmlNode *child;
int vers;
gboolean model_default, saved_default;
- int size;
- ETreePath path;
-
- g_return_if_fail(etta != NULL);
-
- priv = etta->priv;
doc = xmlParseFile (filename);
if (!doc)
- return;
+ return NULL;
root = xmlDocGetRootElement (doc);
if (root == NULL || strcmp (root->name, "expanded_state")) {
xmlFreeDoc (doc);
- return;
+ return NULL;
}
vers = e_xml_get_integer_prop_by_name_with_default (root, "vers", 0);
if (vers > 2) {
xmlFreeDoc (doc);
- return;
+ return NULL;
}
- model_default = e_tree_model_get_expanded_default (priv->source);
+ 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;
+ 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));
@@ -1023,23 +913,22 @@ e_tree_table_adapter_load_expanded_state (ETreeTableAdapter *etta, const char *f
continue;
}
- add_expanded_node(etta, id, !model_default);
+ path = e_tree_model_get_node_by_id(etta->priv->source, id);
+ e_tree_table_adapter_node_set_expanded(etta, path, !model_default);
}
-
xmlFreeDoc (doc);
- path = e_tree_model_get_root (etta->priv->source);
- size = array_size_from_path(etta, path);
- etta_expand_to(etta, size);
- etta->priv->n_map = size;
- fill_array_from_path(etta, etta->priv->map_table, path);
+ update_node(etta, e_tree_model_get_root (etta->priv->source));
e_table_model_changed (E_TABLE_MODEL (etta));
}
-void e_tree_table_adapter_root_node_set_visible (ETreeTableAdapter *etta, gboolean visible)
+void
+e_tree_table_adapter_root_node_set_visible (ETreeTableAdapter *etta, gboolean visible)
{
+ int size;
+
if (etta->priv->root_visible == visible)
return;
@@ -1051,71 +940,68 @@ void e_tree_table_adapter_root_node_set_visible (ETreeTableAdapter *etta
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)
+void
+e_tree_table_adapter_node_set_expanded (ETreeTableAdapter *etta, ETreePath path, gboolean expanded)
{
- ETreeTableAdapterNode *node;
+ GNode *gnode = lookup_gnode(etta, path);
+ node_t *node;
int row;
if (!expanded && e_tree_model_node_is_root (etta->priv->source, path) && !etta->priv->root_visible)
return;
- node = find_or_create_node(etta, path);
+ g_return_if_fail(gnode != NULL);
+
+ node = (node_t *) gnode->data;
if (expanded == node->expanded)
return;
node->expanded = expanded;
- row = find_row_num(etta, path);
- if (row != -1) {
- e_table_model_pre_change (E_TABLE_MODEL(etta));
-
- if (etta->priv->root_visible) {
- e_table_model_pre_change (E_TABLE_MODEL(etta));
- e_table_model_row_changed(E_TABLE_MODEL(etta), row);
- } else if (row != 0) {
- e_table_model_pre_change (E_TABLE_MODEL(etta));
- e_table_model_row_changed(E_TABLE_MODEL(etta), row - 1);
- }
+ row = get_row(etta, path);
+ if (row == -1)
+ return;
- if (expanded) {
- int num_children = array_size_from_path(etta, path) - 1;
- etta_expand_to(etta, etta->priv->n_map + num_children);
- memmove(etta->priv->map_table + row + 1 + num_children,
- etta->priv->map_table + row + 1,
- (etta->priv->n_map - row - 1) * sizeof (ETreePath));
- fill_array_from_path(etta, etta->priv->map_table + row, path);
- etta_update_parent_child_counts(etta, path, num_children);
- if (num_children != 0) {
- if (etta->priv->root_visible)
- e_table_model_rows_inserted(E_TABLE_MODEL(etta), row + 1, num_children);
- else
- e_table_model_rows_inserted(E_TABLE_MODEL(etta), row, num_children);
- } else
- e_table_model_no_change(E_TABLE_MODEL(etta));
- } else {
- int num_children = node->num_visible_children;
- g_assert (etta->priv->n_map >= row + 1 + num_children);
- memmove(etta->priv->map_table + row + 1,
- etta->priv->map_table + row + 1 + num_children,
- (etta->priv->n_map - row - 1 - num_children) * sizeof (ETreePath));
- node->num_visible_children = 0;
- etta_update_parent_child_counts(etta, path, - num_children);
- if (num_children != 0) {
- if (etta->priv->root_visible)
- e_table_model_rows_deleted(E_TABLE_MODEL(etta), row + 1, num_children);
- else
- e_table_model_rows_deleted(E_TABLE_MODEL(etta), row, num_children);
- } else
- e_table_model_no_change(E_TABLE_MODEL(etta));
+ 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)
+void
+e_tree_table_adapter_node_set_expanded_recurse (ETreeTableAdapter *etta, ETreePath path, gboolean expanded)
{
ETreePath children;
@@ -1128,39 +1014,26 @@ void e_tree_table_adapter_node_set_expanded_recurse (ETreeTableAdapter *
}
}
-ETreePath e_tree_table_adapter_node_at_row (ETreeTableAdapter *etta, int row)
+ETreePath
+e_tree_table_adapter_node_at_row (ETreeTableAdapter *etta, int row)
{
- if (row < 0)
- return NULL;
- if (etta->priv->root_visible) {
- if (row < etta->priv->n_map)
- return etta->priv->map_table[row];
- } else {
- if (row + 1 < etta->priv->n_map)
- return etta->priv->map_table[row + 1];
- }
- return NULL;
+ return get_path(etta, row);
}
-int e_tree_table_adapter_row_of_node (ETreeTableAdapter *etta, ETreePath path)
+int
+e_tree_table_adapter_row_of_node (ETreeTableAdapter *etta, ETreePath path)
{
- if (etta->priv->root_visible)
- return find_row_num(etta, path);
- else {
- int row_num = find_row_num (etta, path);
- if (row_num != -1)
- return row_num - 1;
- else
- return row_num;
- }
+ return get_row(etta, path);
}
-gboolean e_tree_table_adapter_root_node_is_visible(ETreeTableAdapter *etta)
+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)
+void
+e_tree_table_adapter_show_node (ETreeTableAdapter *etta, ETreePath path)
{
ETreePath parent;
@@ -1172,10 +1045,32 @@ void e_tree_table_adapter_show_node (ETreeTableAdapter *etta, ETreePath
}
}
-gboolean e_tree_table_adapter_node_is_expanded (ETreeTableAdapter *etta, ETreePath path)
+gboolean
+e_tree_table_adapter_node_is_expanded (ETreeTableAdapter *etta, ETreePath path)
{
if (!e_tree_model_node_is_expandable (etta->priv->source, path))
return FALSE;
- return e_tree_table_adapter_node_would_be_expanded (etta, path);
+ return get_node(etta, path)->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);
+ }
+ 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));
}