aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/e-table/e-tree-model.c
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/e-table/e-tree-model.c')
-rw-r--r--widgets/e-table/e-tree-model.c760
1 files changed, 0 insertions, 760 deletions
diff --git a/widgets/e-table/e-tree-model.c b/widgets/e-table/e-tree-model.c
deleted file mode 100644
index c57bf2d683..0000000000
--- a/widgets/e-table/e-tree-model.c
+++ /dev/null
@@ -1,760 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-tree-model.c: a Tree Model
- *
- * Author:
- * Chris Toshok (toshok@helixcode.com)
- *
- * Adapted from the gtree code and ETableModel.
- *
- * (C) 2000 Helix Code, Inc.
- */
-#include <config.h>
-#include <gtk/gtksignal.h>
-#include <stdlib.h>
-#include "e-util/e-util.h"
-#include "e-tree-model.h"
-
-#define ETM_CLASS(e) ((ETreeModelClass *)((GtkObject *)e)->klass)
-
-#define PARENT_TYPE E_TABLE_MODEL_TYPE
-
-static ETableModel *e_tree_model_parent_class;
-
-typedef struct {
- gboolean expanded;
- guint visible_descendents;
- gpointer node_data;
-} ENode;
-
-enum {
- NODE_CHANGED,
- NODE_INSERTED,
- NODE_REMOVED,
- LAST_SIGNAL
-};
-
-static guint e_tree_model_signals [LAST_SIGNAL] = {0, };
-
-static void add_visible_descendents_to_array (ETreeModel *etm, GNode *gnode, int *row, int *count);
-
-
-/* virtual methods */
-
-static void
-etree_destroy (GtkObject *object)
-{
- ETreeModel *etree = E_TREE_MODEL (object);
-
- /* XXX lots of stuff to free here */
- g_array_free (etree->row_array, TRUE);
-
- GTK_OBJECT_CLASS (e_tree_model_parent_class)->destroy (object);
-}
-
-static ETreePath*
-etree_get_root (ETreeModel *etm)
-{
- return etm->root;
-}
-
-static ETreePath*
-etree_get_parent (ETreeModel *etm, ETreePath *path)
-{
- g_return_val_if_fail (path, NULL);
-
- return path->parent;
-}
-
-static ETreePath*
-etree_get_next (ETreeModel *etm, ETreePath *node)
-{
- g_return_val_if_fail (node, NULL);
-
- return g_node_next_sibling(node);
-}
-
-static ETreePath*
-etree_get_prev (ETreeModel *etm, ETreePath *node)
-{
- g_return_val_if_fail (node, NULL);
-
- return g_node_prev_sibling (node);
-}
-
-static guint
-etree_get_children (ETreeModel *etm, ETreePath* node, ETreePath ***paths)
-{
- guint n_children;
-
- g_return_val_if_fail (node, 0);
-
- n_children = g_node_n_children (node);
-
- if (paths) {
- int i;
- (*paths) = g_malloc (sizeof (ETreePath*) * n_children);
- for (i = 0; i < n_children; i ++) {
- (*paths)[i] = g_node_nth_child (node, i);
- }
- }
-
- return n_children;
-}
-
-static gboolean
-etree_is_expanded (ETreeModel *etm, ETreePath* node)
-{
- g_return_val_if_fail (node && node->data, FALSE);
-
- return ((ENode*)node->data)->expanded;
-}
-
-static gboolean
-etree_is_visible (ETreeModel *etm, ETreePath* node)
-{
- g_return_val_if_fail (node, FALSE);
-
- for (node = node->parent; node; node = node->parent) {
- if (!((ENode*)node->data)->expanded)
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-etree_set_expanded (ETreeModel *etm, ETreePath* node, gboolean expanded)
-{
- GNode *child;
- ENode *enode;
- int row;
-
- g_return_if_fail (node && node->data);
-
- enode = ((ENode*)node->data);
-
- if (enode->expanded == expanded)
- return;
-
- enode->expanded = expanded;
-
- /* if the node wasn't visible at present */
- if ((row = e_tree_model_row_of_node (etm, node)) == -1)
- return;
-
- row++;
-
- if (expanded) {
- GNode *parent;
-
- if (e_tree_model_node_is_visible (etm, node)) {
- enode->visible_descendents = 0;
- for (child = g_node_first_child (node); child;
- child = g_node_next_sibling (child)) {
- add_visible_descendents_to_array (etm, child, &row, &enode->visible_descendents);
- }
- }
- /* now iterate back up the tree, adding to our
- ancestors' visible descendents */
-
- for (parent = node->parent; parent; parent = parent->parent) {
- ENode *parent_enode = (ENode*)parent->data;
- parent_enode->visible_descendents += enode->visible_descendents;
- }
- }
- else {
- int i;
- GNode *parent;
-
- if (e_tree_model_node_is_visible (etm, node)) {
- for (i = 0; i < enode->visible_descendents; i ++) {
- etm->row_array = g_array_remove_index (etm->row_array, row);
- e_table_model_row_deleted (E_TABLE_MODEL (etm), row);
- }
- }
- /* now iterate back up the tree, subtracting from our
- ancestors' visible descendents */
-
- for (parent = node->parent; parent; parent = parent->parent) {
- ENode *parent_enode = (ENode*)parent->data;
-
- parent_enode->visible_descendents -= enode->visible_descendents;
- }
-
- enode->visible_descendents = 0;
- }
-}
-
-/* fairly naive implementation */
-static void
-etree_set_expanded_recurse (ETreeModel *etm, ETreePath* node, gboolean expanded)
-{
- ETreePath **paths;
- guint num_children;
- int i;
-
- e_tree_model_node_set_expanded (etm, node, expanded);
-
- num_children = e_tree_model_node_get_children (etm, node, &paths);
- if (num_children) {
- for (i = 0; i < num_children; i ++) {
- e_tree_model_node_set_expanded_recurse (etm, paths[i], expanded);
- }
-
- g_free (paths);
- }
-}
-
-static ETreePath *
-etree_node_at_row (ETreeModel *etree, int row)
-{
- g_return_val_if_fail (row < etree->row_array->len, NULL);
-
- return g_array_index (etree->row_array, GNode*, row);
-}
-
-
-/* ETable analogs */
-static void*
-etree_value_at (ETreeModel *etm, ETreePath* node, int col)
-{
- /* shouldn't be called */
- g_assert (0);
- return NULL;
-}
-
-static GdkPixbuf*
-etree_icon_at (ETreeModel *etm, ETreePath* node)
-{
- /* shouldn't be called */
- g_assert (0);
- return NULL;
-}
-
-static void
-etree_set_value_at (ETreeModel *etm, ETreePath* node, int col, const void *val)
-{
- /* shouldn't be called */
- g_assert (0);
-}
-
-static gboolean
-etree_is_editable (ETreeModel *etm, ETreePath* node, int col)
-{
- /* shouldn't be called */
- g_assert(0);
- return FALSE;
-}
-
-
-/* ETable virtual functions we map */
-static int
-etable_row_count (ETableModel *etm)
-{
- ETreeModel *tree = E_TREE_MODEL (etm);
- return tree->row_array->len;
-}
-
-static void *
-etable_value_at (ETableModel *etm, int col, int row)
-{
- ETreeModel *etree = E_TREE_MODEL(etm);
- ETreeModelClass *et_class = ETM_CLASS(etm);
- ETreePath* node = e_tree_model_node_at_row (etree, row);
-
- g_return_val_if_fail (node, NULL);
-
- if (col == -1)
- return node;
- else if (col == -2)
- return etm;
- else
- return et_class->value_at (etree, node, col);
-}
-
-static void
-etable_set_value_at (ETableModel *etm, int col, int row, const void *val)
-{
- ETreeModel *etree = E_TREE_MODEL(etm);
- ETreeModelClass *et_class = ETM_CLASS(etm);
- ETreePath* node = e_tree_model_node_at_row (etree, row);
-
- g_return_if_fail (node);
-
- et_class->set_value_at (etree, node, col, val);
-}
-
-static gboolean
-etable_is_cell_editable (ETableModel *etm, int col, int row)
-{
- ETreeModel *etree = E_TREE_MODEL(etm);
- ETreeModelClass *et_class = ETM_CLASS(etm);
- ETreePath* node = e_tree_model_node_at_row (etree, row);
-
- g_return_val_if_fail (node, FALSE);
-
- return et_class->is_editable (etree, node, col);
-}
-
-
-static void
-e_tree_model_class_init (GtkObjectClass *klass)
-{
- ETableModelClass *table_class = (ETableModelClass *) klass;
- ETreeModelClass *tree_class = (ETreeModelClass *) klass;
-
- e_tree_model_parent_class = gtk_type_class (PARENT_TYPE);
-
- klass->destroy = etree_destroy;
-
- e_tree_model_signals [NODE_CHANGED] =
- gtk_signal_new ("node_changed",
- GTK_RUN_LAST,
- klass->type,
- GTK_SIGNAL_OFFSET (ETreeModelClass, node_changed),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
-
- e_tree_model_signals [NODE_INSERTED] =
- gtk_signal_new ("node_inserted",
- GTK_RUN_LAST,
- klass->type,
- GTK_SIGNAL_OFFSET (ETreeModelClass, node_inserted),
- gtk_marshal_NONE__POINTER_POINTER,
- GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
-
- e_tree_model_signals [NODE_REMOVED] =
- gtk_signal_new ("node_removed",
- GTK_RUN_LAST,
- klass->type,
- GTK_SIGNAL_OFFSET (ETreeModelClass, node_removed),
- gtk_marshal_NONE__POINTER_POINTER,
- GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
-
- gtk_object_class_add_signals (klass, e_tree_model_signals, LAST_SIGNAL);
-
- table_class->row_count = etable_row_count;
- table_class->value_at = etable_value_at;
- table_class->set_value_at = etable_set_value_at;
- table_class->is_cell_editable = etable_is_cell_editable;
-#if 0
- /* XX need to pass these through */
- table_class->duplicate_value = etable_duplicate_value;
- table_class->free_value = etable_free_value;
- table_class->initialize_value = etable_initialize_value;
- table_class->value_is_empty = etable_value_is_empty;
- table_class->value_to_string = etable_value_to_string;
- table_class->thaw = etable_thaw;
-#endif
-
- tree_class->get_root = etree_get_root;
- tree_class->get_prev = etree_get_prev;
- tree_class->get_next = etree_get_next;
- tree_class->get_parent = etree_get_parent;
-
- tree_class->value_at = etree_value_at;
- tree_class->icon_at = etree_icon_at;
- tree_class->set_value_at = etree_set_value_at;
- tree_class->is_editable = etree_is_editable;
-
- tree_class->get_children = etree_get_children;
- tree_class->is_expanded = etree_is_expanded;
- tree_class->is_visible = etree_is_visible;
- tree_class->set_expanded = etree_set_expanded;
- tree_class->set_expanded_recurse = etree_set_expanded_recurse;
- tree_class->node_at_row = etree_node_at_row;
-}
-
-E_MAKE_TYPE(e_tree_model, "ETreeModel", ETreeModel, e_tree_model_class_init, NULL, PARENT_TYPE)
-
-
-/* signals */
-void
-e_tree_model_node_changed (ETreeModel *tree_model, ETreePath *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_CHANGED]);
-}
-
-void
-e_tree_model_node_inserted (ETreeModel *tree_model,
- ETreePath *parent_node,
- ETreePath *inserted_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_INSERTED],
- parent_node, inserted_node);
-}
-
-void
-e_tree_model_node_removed (ETreeModel *tree_model, ETreePath *parent_node, ETreePath *removed_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_REMOVED],
- parent_node, removed_node);
-}
-
-
-void
-e_tree_model_construct (ETreeModel *etree)
-{
- etree->root = NULL;
- etree->root_visible = TRUE;
- etree->row_array = g_array_new (FALSE, FALSE, sizeof(GNode*));
-}
-
-ETreeModel *
-e_tree_model_new ()
-{
- ETreeModel *et;
-
- et = gtk_type_new (e_tree_model_get_type ());
-
- return et;
-}
-
-ETreePath *
-e_tree_model_get_root (ETreeModel *etree)
-{
- return ETM_CLASS(etree)->get_root(etree);
-}
-
-ETreePath *
-e_tree_model_node_at_row (ETreeModel *etree, int row)
-{
- return ETM_CLASS(etree)->node_at_row (etree, row);
-}
-
-GdkPixbuf *
-e_tree_model_icon_of_node (ETreeModel *etree, ETreePath *path)
-{
- return ETM_CLASS(etree)->icon_at (etree, path);
-}
-
-int
-e_tree_model_row_of_node (ETreeModel *etree, ETreePath *node)
-{
- int i;
-
- for (i = 0; i < etree->row_array->len; i ++)
- if (g_array_index (etree->row_array, GNode*, i) == node)
- return i;
-
- g_warning ("e_tree_model_row_of_node failed for node %p\n", node);
-
- return -1;
-}
-
-void
-e_tree_model_root_node_set_visible (ETreeModel *etm, gboolean visible)
-{
- if (visible != etm->root_visible) {
- etm->root_visible = visible;
- if (etm->root) {
- if (visible) {
- etm->row_array = g_array_insert_val (etm->row_array, 0, etm->root);
- }
- else {
- ETreePath *root_path = e_tree_model_get_root (etm);
- e_tree_model_node_set_expanded (etm, root_path, TRUE);
- etm->row_array = g_array_remove_index (etm->row_array, 0);
- }
-
- e_table_model_changed (E_TABLE_MODEL (etm));
- }
- }
-}
-
-gboolean
-e_tree_model_root_node_is_visible (ETreeModel *etm)
-{
- return etm->root_visible;
-}
-
-
-ETreePath *
-e_tree_model_node_get_next (ETreeModel *etree, ETreePath *node)
-{
- return ETM_CLASS(etree)->get_next(etree, node);
-}
-
-ETreePath *
-e_tree_model_node_get_prev (ETreeModel *etree, ETreePath *node)
-{
- return ETM_CLASS(etree)->get_prev(etree, node);
-}
-
-guint
-e_tree_model_node_depth (ETreeModel *etree, ETreePath *path)
-{
- return g_node_depth (path) - 1;
-}
-
-ETreePath *
-e_tree_model_node_get_parent (ETreeModel *etree, ETreePath *path)
-{
- return ETM_CLASS(etree)->get_parent(etree, path);
-}
-
-gboolean
-e_tree_model_node_is_root (ETreeModel *etree, ETreePath *path)
-{
- return (e_tree_model_node_depth (etree, path) == 0);
-}
-
-gboolean
-e_tree_model_node_is_expandable (ETreeModel *etree, ETreePath *path)
-{
- return (e_tree_model_node_get_children (etree, path, NULL) > 0);
-}
-
-gboolean
-e_tree_model_node_is_expanded (ETreeModel *etree, ETreePath *path)
-{
- return ETM_CLASS(etree)->is_expanded (etree, path);
-}
-
-gboolean
-e_tree_model_node_is_visible (ETreeModel *etree, ETreePath *path)
-{
- return ETM_CLASS(etree)->is_visible (etree, path);
-}
-
-void
-e_tree_model_node_set_expanded (ETreeModel *etree, ETreePath *path, gboolean expanded)
-{
- ETM_CLASS(etree)->set_expanded (etree, path, expanded);
-}
-
-void
-e_tree_model_node_set_expanded_recurse (ETreeModel *etree, ETreePath *path, gboolean expanded)
-{
- ETM_CLASS(etree)->set_expanded_recurse (etree, path, expanded);
-}
-
-guint
-e_tree_model_node_get_children (ETreeModel *etree, ETreePath *path, ETreePath ***paths)
-{
- return ETM_CLASS(etree)->get_children (etree, path, paths);
-}
-
-guint
-e_tree_model_node_num_visible_descendents (ETreeModel *etm, ETreePath *node)
-{
- ENode *enode = (ENode*)node->data;
-
- return enode->visible_descendents;
-}
-
-gpointer
-e_tree_model_node_get_data (ETreeModel *etm, ETreePath *node)
-{
- ENode *enode;
-
- g_return_val_if_fail (node && node->data, NULL);
-
- enode = (ENode*)node->data;
-
- return enode->node_data;
-}
-
-void
-e_tree_model_node_set_data (ETreeModel *etm, ETreePath *node, gpointer node_data)
-{
- ENode *enode;
-
- g_return_if_fail (node && node->data);
-
- enode = (ENode*)node->data;
-
- enode->node_data = node_data;
-}
-
-ETreePath*
-e_tree_model_node_insert (ETreeModel *tree_model,
- ETreePath *parent_path,
- int position,
- gpointer node_data)
-{
- ENode *node;
- ETreePath *new_path;
-
- g_return_val_if_fail (parent_path != NULL || tree_model->root == NULL, NULL);
-
- node = g_new0 (ENode, 1);
-
- node->expanded = FALSE;
- node->node_data = node_data;
-
- if (parent_path != NULL) {
-
- new_path = g_node_new (node);
-
- g_node_insert (parent_path, position, new_path);
-
- if (e_tree_model_node_is_visible (tree_model, new_path)) {
- int parent_row;
- GNode *n;
-
- /* we need to iterate back up to the root, incrementing the number of visible
- descendents */
- for (n = parent_path; n; n = n->parent) {
- ENode *parent_enode = (ENode*)n->data;
-
- parent_enode->visible_descendents ++;
- }
-
- /* finally, insert a row into the table */
- if (position == -1)
- position = e_tree_model_node_num_visible_descendents (tree_model, parent_path) - 1;
-
- parent_row = e_tree_model_row_of_node (tree_model, parent_path);
-
- tree_model->row_array = g_array_insert_val (tree_model->row_array,
- parent_row + position + 1, new_path);
-
- e_table_model_row_inserted (E_TABLE_MODEL(tree_model), parent_row + position + 1);
- }
- }
- else {
- tree_model->root = g_node_new (node);
- if (tree_model->root_visible) {
- tree_model->row_array = g_array_insert_val (tree_model->row_array, 0, tree_model->root);
- e_table_model_row_inserted (E_TABLE_MODEL (tree_model), 0);
- }
- else {
- /* need to mark the new node as expanded or
- we'll never see it's children */
- node->expanded = TRUE;
- }
- new_path = tree_model->root;
- }
-
- return new_path;
-}
-
-ETreePath *
-e_tree_model_node_insert_before (ETreeModel *etree,
- ETreePath *parent,
- ETreePath *sibling,
- gpointer node_data)
-{
- return e_tree_model_node_insert (etree, parent,
- g_node_child_position (parent, sibling),
- node_data);
-}
-
-static void
-child_remove (GNode *node, gpointer etree)
-{
- e_tree_model_node_remove (etree, node);
-}
-
-gpointer
-e_tree_model_node_remove (ETreeModel *etree, ETreePath *path)
-{
- GNode *parent = path->parent;
- ENode *enode = (ENode*)path->data;
- gpointer ret = enode->node_data;
-
- /* remove children */
- g_node_children_foreach (path, G_TRAVERSE_ALL, child_remove, etree);
-
- /* clean up the display */
- if (parent) {
- if (e_tree_model_node_is_visible (etree, path)) {
- int row = e_tree_model_row_of_node (etree, path);
- e_table_model_row_deleted (E_TABLE_MODEL (etree), row);
- etree->row_array = g_array_remove_index (etree->row_array, row);
-
- /* we need to iterate back up to the root, incrementing the number of visible
- descendents */
- for (; parent; parent = parent->parent) {
- ENode *parent_enode = (ENode*)parent->data;
-
- parent_enode->visible_descendents --;
- }
- }
- }
- else if (path == etree->root) {
- etree->root = NULL;
- if (etree->root_visible) {
- etree->row_array = g_array_remove_index (etree->row_array, 0);
- e_table_model_row_deleted (E_TABLE_MODEL (etree), 0);
- }
- }
- else {
- /* XXX invalid path */
- return NULL;
- }
-
-
- /* now free up the storage from that path */
- g_node_destroy (path);
- g_free (enode);
-
- return ret;
-}
-
-
-static void
-add_visible_descendents_to_array (ETreeModel *etm, GNode *gnode, int *row, int *count)
-{
- GNode *child;
- ENode *enode;
-
- /* add a row for this node */
- etm->row_array = g_array_insert_val (etm->row_array, (*row), gnode);
- e_table_model_row_inserted (E_TABLE_MODEL (etm), (*row)++);
- (*count) ++;
-
- /* then loop over its children, calling this routine for each
- of them */
- enode = (ENode*)gnode->data;
- if (enode->expanded) {
- for (child = g_node_first_child (gnode); child;
- child = g_node_next_sibling (child)) {
- add_visible_descendents_to_array (etm, child, row, count);
- }
- }
-}
-
-void
-e_tree_model_node_sort (ETreeModel *tree_model,
- ETreePath *node,
- GCompareFunc compare)
-{
- int num_nodes = g_node_n_children (node);
- ETreePath **path_array;
- int i;
-
- if (num_nodes == 0)
- return;
-
- path_array = g_new (ETreePath*, num_nodes);
-
- for (i = 0; i < num_nodes; i ++) {
- path_array[i] = g_node_first_child(node);
- g_node_unlink (path_array[i]);
- }
-
- qsort (path_array, num_nodes, sizeof(ETreePath*), compare);
-
- for (i = 0; i < num_nodes; i ++) {
- g_node_append (node, path_array[i]);
- }
-
- g_free (path_array);
-
- e_table_model_changed (E_TABLE_MODEL (tree_model));
-}