aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/e-table/e-tree-gnode.c
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/e-table/e-tree-gnode.c')
-rw-r--r--widgets/e-table/e-tree-gnode.c210
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;
+}