diff options
Diffstat (limited to 'widgets/e-table/e-tree-gnode.c')
-rw-r--r-- | widgets/e-table/e-tree-gnode.c | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/widgets/e-table/e-tree-gnode.c b/widgets/e-table/e-tree-gnode.c new file mode 100644 index 0000000000..ce53751b56 --- /dev/null +++ b/widgets/e-table/e-tree-gnode.c @@ -0,0 +1,210 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * e-tree-gnode.c: a Tree Model that reflects a GNode structure visually. + * + * Author: + * Chris Toshok (toshok@helixcode.com) + * + * (C) 2000 Helix Code, Inc. + */ +#include <config.h> +#include <gtk/gtksignal.h> +#include "e-util/e-util.h" +#include "e-tree-gnode.h" + +#define PARENT_TYPE E_TREE_MODEL_TYPE + +static ETreePath * +gnode_get_root (ETreeModel *etm) +{ + ETreeGNode *etg = E_TREE_GNODE (etm); + ETreePath *path = NULL; + + path = g_list_append(path, etg->root); + + return path; +} + +static ETreePath * +gnode_get_prev (ETreeModel *etm, ETreePath *node) +{ + ETreePath *prev_path; + + GNode *gnode; + GNode *prev_sibling; + + g_return_val_if_fail (node && node->data, NULL); + + gnode = (GNode*)node->data; + prev_sibling = g_node_prev_sibling(gnode); + + if (!prev_sibling) + return NULL; + + prev_path = g_list_copy (node->next); + prev_path = g_list_prepend (prev_path, prev_sibling); + return prev_path; +} + +static ETreePath * +gnode_get_next (ETreeModel *etm, ETreePath *node) +{ + ETreePath *next_path; + GNode *gnode; + GNode *next_sibling; + + g_return_val_if_fail (node && node->data, NULL); + + gnode = (GNode*)node->data; + next_sibling = g_node_next_sibling(gnode); + + if (!next_sibling) + return NULL; + + next_path = g_list_copy (node->next); + next_path = g_list_prepend (next_path, next_sibling); + return next_path; +} + +static void * +gnode_value_at (ETreeModel *etm, ETreePath *node, int col) +{ + ETreeGNode *etg = E_TREE_GNODE (etm); + GNode *gnode; + + g_return_val_if_fail (node && node->data, NULL); + + gnode = (GNode*)node->data; + + return etg->value_at (etm, gnode, col, etg->data); +} + +static void +gnode_set_value_at (ETreeModel *etm, ETreePath *node, int col, const void *val) +{ + ETreeGNode *etg = E_TREE_GNODE (etm); + GNode *gnode; + + g_return_if_fail (node && node->data); + + gnode = (GNode*)node->data; + + /* XXX */ +} + +static gboolean +gnode_is_editable (ETreeModel *etm, ETreePath *node, int col) +{ + ETreeGNode *etg = E_TREE_GNODE (etm); + GNode *gnode; + + g_return_val_if_fail (node && node->data, FALSE); + + gnode = (GNode*)node->data; + + /* XXX */ + return FALSE; +} + +static guint +gnode_get_children (ETreeModel *etm, ETreePath *node, ETreePath ***paths) +{ + ETreeGNode *etg = E_TREE_GNODE (etm); + GNode *gnode; + guint n_children; + + g_return_val_if_fail (node && node->data, 0); + + gnode = (GNode*)node->data; + + n_children = g_node_n_children (gnode); + + if (paths) + { + int i; + (*paths) = g_malloc (sizeof (ETreePath*) * n_children); + for (i = 0; i < n_children; i ++) { + (*paths)[i] = g_list_copy (node); + (*paths)[i] = g_list_prepend ((*paths)[i], g_node_nth_child (gnode, i)); + } + } + + return n_children; +} + +static void +gnode_release_paths (ETreeModel *etm, ETreePath **paths, guint num_paths) +{ + guint i; + g_return_if_fail (paths); + + for (i = 0; i < num_paths; i ++) + g_list_free (paths[i]); + g_free (paths); +} + +static gboolean +gnode_is_expanded (ETreeModel *etm, ETreePath *node) +{ + ETreeGNode *etg = E_TREE_GNODE (etm); + GNode *gnode; + + g_return_val_if_fail (node && node->data, FALSE); + + gnode = (GNode*)node->data; + + return (gboolean)gnode->data; +} + +static void +gnode_set_expanded (ETreeModel *etm, ETreePath *node, gboolean expanded) +{ + ETreeGNode *etg = E_TREE_GNODE (etm); + GNode *gnode; + int num_descendents; + + g_return_if_fail (node && node->data); + + gnode = (GNode*)node->data; + + /* XXX */ + gnode->data = (gpointer)expanded; + + e_table_model_changed (E_TABLE_MODEL(etm)); +} + +static void +e_tree_gnode_class_init (GtkObjectClass *object_class) +{ + ETreeModelClass *model_class = (ETreeModelClass *) object_class; + + model_class->get_root = gnode_get_root; + model_class->get_next = gnode_get_next; + model_class->get_prev = gnode_get_prev; + model_class->value_at = gnode_value_at; + model_class->set_value_at = gnode_set_value_at; + model_class->is_editable = gnode_is_editable; + model_class->get_children = gnode_get_children; + model_class->release_paths = gnode_release_paths; + model_class->is_expanded = gnode_is_expanded; + model_class->set_expanded = gnode_set_expanded; +} + +E_MAKE_TYPE(e_tree_gnode, "ETreeGNode", ETreeGNode, e_tree_gnode_class_init, NULL, PARENT_TYPE) + +ETreeModel * +e_tree_gnode_new (GNode *root_node, + ETreeGNodeValueAtFn value_at, + void *data) +{ + ETreeGNode *etg; + + etg = gtk_type_new (e_tree_gnode_get_type ()); + + etg->root = root_node; + + etg->value_at = value_at; + etg->data = data; + + return (ETreeModel*)etg; +} |