aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'widgets')
-rw-r--r--widgets/table/e-tree-memory.c52
-rw-r--r--widgets/table/e-tree-memory.h3
2 files changed, 50 insertions, 5 deletions
diff --git a/widgets/table/e-tree-memory.c b/widgets/table/e-tree-memory.c
index 330dac93fb..74c160ab9f 100644
--- a/widgets/table/e-tree-memory.c
+++ b/widgets/table/e-tree-memory.c
@@ -42,14 +42,23 @@
#define TREEPATH_CHUNK_AREA_SIZE (30 * sizeof (ETreeMemoryPath))
-static ETreeModel *parent_class;
+static ETreeModelClass *parent_class;
static GMemChunk *node_chunk;
+enum {
+ FILL_IN_CHILDREN,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
typedef struct ETreeMemoryPath ETreeMemoryPath;
struct ETreeMemoryPath {
gpointer node_data;
+ guint children_computed : 1;
+
/* parent/child/sibling pointers */
ETreeMemoryPath *parent;
ETreeMemoryPath *next_sibling;
@@ -71,6 +80,17 @@ struct ETreeMemoryPriv {
/* ETreeMemoryPath functions */
+static inline void
+check_children (ETreeMemory *memory, ETreePath node)
+{
+ ETreeMemoryPath *path = node;
+ if (!path->children_computed) {
+ gtk_signal_emit (GTK_OBJECT (memory),
+ signals[FILL_IN_CHILDREN], node);
+ path->children_computed = TRUE;
+ }
+}
+
static int
e_tree_memory_path_depth (ETreeMemoryPath *path)
{
@@ -227,6 +247,8 @@ static ETreePath
etmm_get_first_child (ETreeModel *etm, ETreePath node)
{
ETreeMemoryPath *path = node;
+
+ check_children (E_TREE_MEMORY (etm), node);
return path->first_child;
}
@@ -234,6 +256,8 @@ static ETreePath
etmm_get_last_child (ETreeModel *etm, ETreePath node)
{
ETreeMemoryPath *path = node;
+
+ check_children (E_TREE_MEMORY (etm), node);
return path->last_child;
}
@@ -262,6 +286,8 @@ static gboolean
etmm_is_expandable (ETreeModel *etm, ETreePath node)
{
ETreeMemoryPath *path = node;
+
+ check_children (E_TREE_MEMORY (etm), node);
return path->first_child != NULL;
}
@@ -271,13 +297,15 @@ etmm_get_children (ETreeModel *etm, ETreePath node, ETreePath **nodes)
ETreeMemoryPath *path = node;
guint n_children;
+ check_children (E_TREE_MEMORY (etm), node);
+
n_children = path->num_children;
if (nodes) {
ETreeMemoryPath *p;
int i = 0;
- (*nodes) = g_malloc (sizeof (ETreePath) * n_children);
+ (*nodes) = g_new (ETreePath, n_children);
for (p = path->first_child; p; p = p->next_sibling) {
(*nodes)[i++] = p;
}
@@ -303,15 +331,26 @@ etmm_get_expanded_default (ETreeModel *etm)
static void
-e_tree_memory_class_init (GtkObjectClass *klass)
+e_tree_memory_class_init (ETreeMemoryClass *klass)
{
- ETreeModelClass *tree_class = (ETreeModelClass *) klass;
+ ETreeModelClass *tree_class = (ETreeModelClass *) klass;
+ GtkObjectClass *object_class = (GtkObjectClass *) klass;
parent_class = gtk_type_class (PARENT_TYPE);
node_chunk = g_mem_chunk_create (ETreeMemoryPath, TREEPATH_CHUNK_AREA_SIZE, G_ALLOC_AND_FREE);
- klass->destroy = etmm_destroy;
+ signals [FILL_IN_CHILDREN] =
+ gtk_signal_new ("fill_in_children",
+ GTK_RUN_LAST,
+ E_OBJECT_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (ETreeMemoryClass, fill_in_children),
+ gtk_marshal_NONE__POINTER,
+ GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+
+ E_OBJECT_CLASS_ADD_SIGNALS (object_class, signals, LAST_SIGNAL);
+
+ object_class->destroy = etmm_destroy;
tree_class->get_root = etmm_get_root;
tree_class->get_prev = etmm_get_prev;
@@ -325,6 +364,8 @@ e_tree_memory_class_init (GtkObjectClass *klass)
tree_class->get_children = etmm_get_children;
tree_class->depth = etmm_depth;
tree_class->get_expanded_default = etmm_get_expanded_default;
+
+ klass->fill_in_children = NULL;
}
static void
@@ -456,6 +497,7 @@ e_tree_memory_node_insert (ETreeMemory *tree_model,
new_path = g_chunk_new0 (ETreeMemoryPath, node_chunk);
new_path->node_data = node_data;
+ new_path->children_computed = FALSE;
if (parent_path != NULL) {
e_tree_memory_path_insert (parent_path, position, new_path);
diff --git a/widgets/table/e-tree-memory.h b/widgets/table/e-tree-memory.h
index e07271221c..bd43c97fde 100644
--- a/widgets/table/e-tree-memory.h
+++ b/widgets/table/e-tree-memory.h
@@ -52,6 +52,9 @@ struct ETreeMemory {
struct ETreeMemoryClass {
ETreeModelClass parent_class;
+
+ /* signals */
+ void (*fill_in_children) (ETreeMemory *model, ETreePath node);
};