gtktreestore.c 24.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* gtktreestore.c
 * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "gtktreemodel.h"
#include "gtktreestore.h"
#include "gtktreedatalist.h"
#include "gtksignal.h"
#include <string.h>
25
#include <gobject/gvaluecollector.h>
26
27
28

#define G_NODE(node) ((GNode *)node)

29
enum {
30
31
32
33
  CHANGED,
  INSERTED,
  CHILD_TOGGLED,
  DELETED,
34
35
36
37
38
  LAST_SIGNAL
};

static guint tree_store_signals[LAST_SIGNAL] = { 0 };

39

40
41
42
static void         gtk_tree_store_init            (GtkTreeStore      *tree_store);
static void         gtk_tree_store_class_init      (GtkTreeStoreClass *tree_store_class);
static void         gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
43
static guint        gtk_tree_store_get_flags       (GtkTreeModel      *tree_model);
44
static gint         gtk_tree_store_get_n_columns   (GtkTreeModel      *tree_model);
45
46
static GType        gtk_tree_store_get_column_type (GtkTreeModel      *tree_model,
						    gint               index);
47
48
static GtkTreePath *gtk_tree_store_get_path        (GtkTreeModel      *tree_model,
						    GtkTreeIter       *iter);
49
static void         gtk_tree_store_get_value       (GtkTreeModel      *tree_model,
50
51
52
53
54
55
56
57
58
59
60
61
62
63
						    GtkTreeIter       *iter,
						    gint               column,
						    GValue            *value);
static gboolean     gtk_tree_store_iter_next       (GtkTreeModel      *tree_model,
						    GtkTreeIter       *iter);
static gboolean     gtk_tree_store_iter_children   (GtkTreeModel      *tree_model,
						    GtkTreeIter       *iter,
						    GtkTreeIter       *parent);
static gboolean     gtk_tree_store_iter_has_child  (GtkTreeModel      *tree_model,
						    GtkTreeIter       *iter);
static gint         gtk_tree_store_iter_n_children (GtkTreeModel      *tree_model,
						    GtkTreeIter       *iter);
static gboolean     gtk_tree_store_iter_nth_child  (GtkTreeModel      *tree_model,
						    GtkTreeIter       *iter,
64
						    GtkTreeIter       *parent,
65
66
67
						    gint               n);
static gboolean     gtk_tree_store_iter_parent     (GtkTreeModel      *tree_model,
						    GtkTreeIter       *iter,
68
						    GtkTreeIter       *child);
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90


GtkType
gtk_tree_store_get_type (void)
{
  static GtkType tree_store_type = 0;

  if (!tree_store_type)
    {
      static const GTypeInfo tree_store_info =
      {
        sizeof (GtkTreeStoreClass),
	NULL,		/* base_init */
	NULL,		/* base_finalize */
        (GClassInitFunc) gtk_tree_store_class_init,
	NULL,		/* class_finalize */
	NULL,		/* class_data */
        sizeof (GtkTreeStore),
	0,              /* n_preallocs */
        (GInstanceInitFunc) gtk_tree_store_init
      };

91
92
93
94
95
96
97
      static const GInterfaceInfo tree_model_info =
      {
	(GInterfaceInitFunc) gtk_tree_store_tree_model_init,
	NULL,
	NULL
      };

98
      tree_store_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkTreeStore", &tree_store_info, 0);
99
100
101
      g_type_add_interface_static (tree_store_type,
				   GTK_TYPE_TREE_MODEL,
				   &tree_model_info);
102
103
104
105
106
107
    }

  return tree_store_type;
}

static void
108
gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class)
109
110
{
  GtkObjectClass *object_class;
111
112
113

  object_class = (GtkObjectClass *) tree_store_class;

114
115
  tree_store_signals[CHANGED] =
    gtk_signal_new ("changed",
116
117
                    GTK_RUN_FIRST,
                    GTK_CLASS_TYPE (object_class),
118
                    GTK_SIGNAL_OFFSET (GtkTreeStoreClass, changed),
119
120
121
122
                    gtk_marshal_VOID__BOXED_BOXED,
                    G_TYPE_NONE, 2,
		    GTK_TYPE_TREE_PATH,
		    GTK_TYPE_TREE_ITER);
123
124
  tree_store_signals[INSERTED] =
    gtk_signal_new ("inserted",
125
126
                    GTK_RUN_FIRST,
                    GTK_CLASS_TYPE (object_class),
127
                    GTK_SIGNAL_OFFSET (GtkTreeStoreClass, inserted),
128
129
130
131
                    gtk_marshal_VOID__BOXED_BOXED,
                    G_TYPE_NONE, 2,
		    GTK_TYPE_TREE_PATH,
		    GTK_TYPE_TREE_ITER);
132
133
  tree_store_signals[CHILD_TOGGLED] =
    gtk_signal_new ("child_toggled",
134
135
                    GTK_RUN_FIRST,
                    GTK_CLASS_TYPE (object_class),
136
                    GTK_SIGNAL_OFFSET (GtkTreeStoreClass, child_toggled),
137
138
139
140
                    gtk_marshal_VOID__BOXED_BOXED,
                    G_TYPE_NONE, 2,
		    GTK_TYPE_TREE_PATH,
		    GTK_TYPE_TREE_ITER);
141
142
  tree_store_signals[DELETED] =
    gtk_signal_new ("deleted",
143
144
                    GTK_RUN_FIRST,
                    GTK_CLASS_TYPE (object_class),
145
                    GTK_SIGNAL_OFFSET (GtkTreeStoreClass, deleted),
146
147
148
                    gtk_marshal_VOID__BOXED,
                    G_TYPE_NONE, 1,
		    GTK_TYPE_TREE_PATH);
149
150
151
152
153
154
155

  gtk_object_class_add_signals (object_class, tree_store_signals, LAST_SIGNAL);
}

static void
gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
{
156
  iface->get_flags = gtk_tree_store_get_flags;
157
  iface->get_n_columns = gtk_tree_store_get_n_columns;
158
  iface->get_column_type = gtk_tree_store_get_column_type;
159
  iface->get_path = gtk_tree_store_get_path;
160
  iface->get_value = gtk_tree_store_get_value;
161
162
163
164
165
166
  iface->iter_next = gtk_tree_store_iter_next;
  iface->iter_children = gtk_tree_store_iter_children;
  iface->iter_has_child = gtk_tree_store_iter_has_child;
  iface->iter_n_children = gtk_tree_store_iter_n_children;
  iface->iter_nth_child = gtk_tree_store_iter_nth_child;
  iface->iter_parent = gtk_tree_store_iter_parent;
167
168
169
170
171
}

static void
gtk_tree_store_init (GtkTreeStore *tree_store)
{
172
  tree_store->root = g_node_new (NULL);
173
  tree_store->stamp = g_random_int ();
174
175
}

176
GtkTreeStore *
177
178
gtk_tree_store_new (void)
{
179
  return GTK_TREE_STORE (gtk_type_new (gtk_tree_store_get_type ()));
180
181
}

182
GtkTreeStore *
183
184
gtk_tree_store_new_with_types (gint n_columns,
			       ...)
185
{
186
  GtkTreeStore *retval;
187
188
189
190
191
192
  va_list args;
  gint i;

  g_return_val_if_fail (n_columns > 0, NULL);

  retval = gtk_tree_store_new ();
193
  gtk_tree_store_set_n_columns (retval, n_columns);
194
195

  va_start (args, n_columns);
196

197
  for (i = 0; i < n_columns; i++)
198
    gtk_tree_store_set_column_type (retval, i, va_arg (args, GType));
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

  va_end (args);

  return retval;
}

void
gtk_tree_store_set_n_columns (GtkTreeStore *tree_store,
			      gint          n_columns)
{
  GType *new_columns;

  g_return_if_fail (tree_store != NULL);
  g_return_if_fail (GTK_IS_TREE_STORE (tree_store));

  if (tree_store->n_columns == n_columns)
    return;

  new_columns = g_new0 (GType, n_columns);
  if (tree_store->column_headers)
    {
      /* copy the old header orders over */
      if (n_columns >= tree_store->n_columns)
	memcpy (new_columns, tree_store->column_headers, tree_store->n_columns * sizeof (gchar *));
      else
	memcpy (new_columns, tree_store->column_headers, n_columns * sizeof (GType));

      g_free (tree_store->column_headers);
    }

  tree_store->column_headers = new_columns;
  tree_store->n_columns = n_columns;
}

void
gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
				gint          column,
				GType         type)
{
  g_return_if_fail (tree_store != NULL);
  g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
  g_return_if_fail (column >=0 && column < tree_store->n_columns);

  tree_store->column_headers[column] = type;
}

/* fulfill the GtkTreeModel requirements */
/* NOTE: GtkTreeStore::root is a GNode, that acts as the parent node.  However,
 * it is not visible to the tree or to the user., and the path "1" refers to the
 * first child of GtkTreeStore::root.
 */
250
251
252
253
254
255
256
257
258
259


static guint
gtk_tree_store_get_flags (GtkTreeModel *tree_model)
{
  g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);

  return GTK_TREE_MODEL_ITERS_PERSIST;
}

260
261
262
263
264
265
266
267
static gint
gtk_tree_store_get_n_columns (GtkTreeModel *tree_model)
{
  g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);

  return GTK_TREE_STORE (tree_model)->n_columns;
}

268
269
270
271
272
273
274
275
276
277
278
static GType
gtk_tree_store_get_column_type (GtkTreeModel *tree_model,
				gint          index)
{
  g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), G_TYPE_INVALID);
  g_return_val_if_fail (index < GTK_TREE_STORE (tree_model)->n_columns &&
			index >= 0, G_TYPE_INVALID);

  return GTK_TREE_STORE (tree_model)->column_headers[index];
}

279
280
static GtkTreePath *
gtk_tree_store_get_path (GtkTreeModel *tree_model,
281
			 GtkTreeIter  *iter)
282
283
284
285
286
287
{
  GtkTreePath *retval;
  GNode *tmp_node;
  gint i = 0;

  g_return_val_if_fail (tree_model != NULL, NULL);
288
289
290
291
  g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), NULL);
  g_return_val_if_fail (iter != NULL, NULL);
  g_return_val_if_fail (GTK_TREE_STORE (tree_model)->stamp == iter->stamp, NULL);
  if (iter->tree_node == NULL)
292
293
    return NULL;

294
  if (G_NODE (iter->tree_node)->parent == G_NODE (GTK_TREE_STORE (tree_model)->root))
295
296
297
298
299
300
    {
      retval = gtk_tree_path_new ();
      tmp_node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
    }
  else
    {
301
302
303
      GtkTreeIter tmp_iter = *iter;
      tmp_iter.tree_node = G_NODE (tmp_iter.tree_node)->parent;

304
      retval = gtk_tree_store_get_path (tree_model,
305
306
					&tmp_iter);
      tmp_node = G_NODE (iter->tree_node)->parent->children;
307
308
309
310
    }

  if (retval == NULL)
    return NULL;
311

312
313
314
315
316
317
318
319
  if (tmp_node == NULL)
    {
      gtk_tree_path_free (retval);
      return NULL;
    }

  for (; tmp_node; tmp_node = tmp_node->next)
    {
320
      if (tmp_node == G_NODE (iter->tree_node))
321
322
323
	break;
      i++;
    }
324

325
326
327
  if (tmp_node == NULL)
    {
      /* We couldn't find node, meaning it's prolly not ours */
328
      /* Perhaps I should do a g_return_if_fail here. */
329
330
331
332
333
334
335
336
337
338
339
      gtk_tree_path_free (retval);
      return NULL;
    }

  gtk_tree_path_append_index (retval, i);

  return retval;
}


static void
340
341
342
343
gtk_tree_store_get_value (GtkTreeModel *tree_model,
			  GtkTreeIter  *iter,
			  gint          column,
			  GValue       *value)
344
345
346
347
348
349
{
  GtkTreeDataList *list;
  gint tmp_column = column;

  g_return_if_fail (tree_model != NULL);
  g_return_if_fail (GTK_IS_TREE_STORE (tree_model));
350
351
  g_return_if_fail (iter != NULL);
  g_return_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp);
352
353
  g_return_if_fail (column < GTK_TREE_STORE (tree_model)->n_columns);

354
  list = G_NODE (iter->tree_node)->data;
355
356
357
358

  while (tmp_column-- > 0 && list)
    list = list->next;

359
360
  if (list)
    {
361
362
363
      _gtk_tree_data_list_node_to_value (list,
					 GTK_TREE_STORE (tree_model)->column_headers[column],
					 value);
364
365
366
367
368
369
    }
  else
    {
      /* We want to return an initialized but empty (default) value */
      g_value_init (value, GTK_TREE_STORE (tree_model)->column_headers[column]);
    }
370
371
372
}

static gboolean
373
374
gtk_tree_store_iter_next (GtkTreeModel  *tree_model,
			  GtkTreeIter   *iter)
375
{
376
  if (iter->tree_node == NULL)
377
378
    return FALSE;

379
380
381
  iter->tree_node = G_NODE (iter->tree_node)->next;

  return (iter->tree_node != NULL);
382
383
}

384
385
386
387
static gboolean
gtk_tree_store_iter_children (GtkTreeModel *tree_model,
			      GtkTreeIter  *iter,
			      GtkTreeIter  *parent)
388
{
389
  iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
390
391
392
393
  if (parent)
    iter->tree_node = G_NODE (parent->tree_node)->children;
  else
    iter->tree_node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
394
395

  return iter->tree_node != NULL;
396
397
398
}

static gboolean
399
400
gtk_tree_store_iter_has_child (GtkTreeModel *tree_model,
			       GtkTreeIter  *iter)
401
{
402
403
404
405
406
407
  g_return_val_if_fail (tree_model != NULL, FALSE);
  g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, FALSE);

  return G_NODE (iter->tree_node)->children != NULL;
408
409
410
}

static gint
411
412
gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
				GtkTreeIter  *iter)
413
{
414
  GNode *node;
415
416
  gint i = 0;

417
418
  g_return_val_if_fail (tree_model != NULL, 0);
  g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
419
420
  if (iter)
    g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, 0);
421

422
423
424
425
  if (iter == NULL)
    node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
  else
    node = G_NODE (iter->tree_node)->children;
426
  while (node)
427
428
    {
      i++;
429
      node = node->next;
430
431
432
433
434
    }

  return i;
}

435
436
437
438
static gboolean
gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
			       GtkTreeIter  *iter,
			       GtkTreeIter  *parent,
439
440
			       gint          n)
{
441
  GNode *parent_node;
442

443
444
445
446
447
  g_return_val_if_fail (tree_model != NULL, FALSE);
  g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
  g_return_val_if_fail (iter != NULL, FALSE);
  if (parent)
    g_return_val_if_fail (parent->stamp == GTK_TREE_STORE (tree_model)->stamp, FALSE);
448

449
450
451
452
453
454
455
456
457
458
459
460
461
  if (parent == NULL)
    parent_node = GTK_TREE_STORE (tree_model)->root;
  else
    parent_node = parent->tree_node;

  iter->tree_node = g_node_nth_child (parent_node, n);

  if (iter->tree_node == NULL)
    iter->stamp = 0;
  else
    iter->stamp = GTK_TREE_STORE (tree_model)->stamp;

  return (iter->tree_node != NULL);
462
463
}

464
465
466
467
static gboolean
gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
			    GtkTreeIter  *iter,
			    GtkTreeIter  *child)
468
{
469
470
  iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
  iter->tree_node = G_NODE (child->tree_node)->parent;
471

472
473
474
475
476
477
478
  if (iter->tree_node == GTK_TREE_STORE (tree_model)->root)
    {
      iter->stamp = 0;
      return FALSE;
    }

  return TRUE;
479
480
481
482
483
484
485
}

/*
 * This is a somewhat inelegant function that does a lot of list
 * manipulations on it's own.
 */
void
486
487
488
489
gtk_tree_store_set_cell (GtkTreeStore *tree_store,
			 GtkTreeIter  *iter,
			 gint          column,
			 GValue       *value)
490
491
492
493
494
495
496
497
{
  GtkTreeDataList *list;
  GtkTreeDataList *prev;

  g_return_if_fail (tree_store != NULL);
  g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
  g_return_if_fail (column >= 0 && column < tree_store->n_columns);

498
  prev = list = G_NODE (iter->tree_node)->data;
499
500
501
502
503

  while (list != NULL)
    {
      if (column == 0)
	{
504
	  _gtk_tree_data_list_value_to_node (list, value);
505
506
507
	  gtk_signal_emit_by_name (GTK_OBJECT (tree_store),
				   "changed",
				   NULL, iter);
508
509
510
511
512
513
514
515
	  return;
	}

      column--;
      prev = list;
      list = list->next;
    }

516
  if (G_NODE (iter->tree_node)->data == NULL)
517
    {
518
      G_NODE (iter->tree_node)->data = list = _gtk_tree_data_list_alloc ();
519
520
521
522
      list->next = NULL;
    }
  else
    {
523
      list = prev->next = _gtk_tree_data_list_alloc ();
524
525
526
527
528
      list->next = NULL;
    }

  while (column != 0)
    {
529
      list->next = _gtk_tree_data_list_alloc ();
530
531
532
533
      list = list->next;
      list->next = NULL;
      column --;
    }
534
535
536
537
  _gtk_tree_data_list_value_to_node (list, value);
  gtk_signal_emit_by_name (GTK_OBJECT (tree_store),
			   "changed",
			   NULL, iter);
538
539
540
}

void
541
542
543
gtk_tree_store_setv (GtkTreeStore *tree_store,
		     GtkTreeIter  *iter,
		     va_list	var_args)
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
{
  gint column;

  g_return_if_fail (GTK_IS_TREE_STORE (tree_store));

  column = va_arg (var_args, gint);

  while (column >= 0)
    {
      GValue value = { 0, };
      gchar *error = NULL;

      if (column >= tree_store->n_columns)
	{
	  g_warning ("Invalid column number %d added to iter", column);
	  break;
	}
      g_value_init (&value, tree_store->column_headers[column]);

      G_VALUE_COLLECT (&value, var_args, &error);
      if (error)
	{
	  g_warning ("%s: %s", G_STRLOC, error);
	  g_free (error);

 	  /* we purposely leak the value here, it might not be
	   * in a sane state if an error condition occoured
	   */
	  break;
	}

575
576
577
578
      gtk_tree_store_set_cell (tree_store,
			       iter,
			       column,
			       &value);
579
580
581
582
583
584
585
586

      g_value_unset (&value);

      column = va_arg (var_args, gint);
    }
}

void
587
588
589
gtk_tree_store_set (GtkTreeStore *tree_store,
		    GtkTreeIter  *iter,
		    ...)
590
591
592
593
594
595
{
  va_list var_args;

  g_return_if_fail (GTK_IS_TREE_STORE (tree_store));

  va_start (var_args, iter);
596
  gtk_tree_store_setv (tree_store, iter, var_args);
597
598
599
600
  va_end (var_args);
}

void
601
602
603
gtk_tree_store_getv (GtkTreeStore *tree_store,
		     GtkTreeIter  *iter,
		     va_list	var_args)
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
{
  gint column;

  g_return_if_fail (GTK_IS_TREE_STORE (tree_store));

  column = va_arg (var_args, gint);

  while (column >= 0)
    {
      GValue value = { 0, };
      gchar *error = NULL;

      if (column >= tree_store->n_columns)
	{
	  g_warning ("Invalid column number %d accessed", column);
	  break;
	}

622
      gtk_tree_store_get_value (GTK_TREE_MODEL (tree_store), iter, column, &value);
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642

      G_VALUE_LCOPY (&value, var_args, &error);
      if (error)
	{
	  g_warning ("%s: %s", G_STRLOC, error);
	  g_free (error);

 	  /* we purposely leak the value here, it might not be
	   * in a sane state if an error condition occoured
	   */
	  break;
	}

      g_value_unset (&value);

      column = va_arg (var_args, gint);
    }
}

void
643
644
645
gtk_tree_store_get (GtkTreeStore *tree_store,
		    GtkTreeIter  *iter,
		    ...)
646
647
648
649
650
651
{
  va_list var_args;

  g_return_if_fail (GTK_IS_TREE_STORE (tree_store));

  va_start (var_args, iter);
652
  gtk_tree_store_getv (tree_store, iter, var_args);
653
654
655
656
  va_end (var_args);
}

void
657
658
gtk_tree_store_remove (GtkTreeStore *model,
		       GtkTreeIter  *iter)
659
660
{
  GtkTreePath *path;
661

662
663
664
665
666
  GNode *parent;

  g_return_if_fail (model != NULL);
  g_return_if_fail (GTK_IS_TREE_STORE (model));

667
  parent = G_NODE (iter->tree_node)->parent;
668

669
670
671
672
  if (G_NODE (iter->tree_node)->data)
    _gtk_tree_data_list_free ((GtkTreeDataList *) G_NODE (iter->tree_node)->data,
			      model->column_headers);

673
674
  path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
  g_node_destroy (G_NODE (iter->tree_node));
675
676

  model->stamp++;
677
  gtk_signal_emit_by_name (GTK_OBJECT (model),
678
			   "deleted",
679
680
681
682
683
			   path);
  if (parent != G_NODE (model->root) && parent->children == NULL)
    {
      gtk_tree_path_up (path);
      gtk_signal_emit_by_name (GTK_OBJECT (model),
684
			       "child_toggled",
685
686
687
688
689
690
			       path,
			       parent);
    }
  gtk_tree_path_free (path);
}

691
void
692
693
694
695
gtk_tree_store_insert (GtkTreeStore *model,
		       GtkTreeIter  *iter,
		       GtkTreeIter  *parent,
		       gint          position)
696
697
698
{
  GtkTreePath *path;

699
700
  g_return_if_fail (model != NULL);
  g_return_if_fail (GTK_IS_TREE_STORE (model));
701

702
703
  if (parent->tree_node == NULL)
    parent->tree_node = model->root;
704

705
706
707
708
709
  iter->stamp = model->stamp;
  iter->tree_node = g_node_new (NULL);
  g_node_insert (G_NODE (parent->tree_node), position, G_NODE (iter->tree_node));
  
  path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
710
  gtk_signal_emit_by_name (GTK_OBJECT (model),
711
712
			   "inserted",
			   path, iter);
713
714
715
  gtk_tree_path_free (path);
}

716
void
717
718
719
720
gtk_tree_store_insert_before (GtkTreeStore *model,
			      GtkTreeIter  *iter,
			      GtkTreeIter  *parent,
			      GtkTreeIter  *sibling)
721
722
{
  GtkTreePath *path;
723
  GNode *parent_node = NULL;
724

725
726
727
728
729
730
731
  g_return_if_fail (model != NULL);
  g_return_if_fail (GTK_IS_TREE_STORE (model));
  g_return_if_fail (iter != NULL);
  if (parent != NULL)
    g_return_if_fail (parent->stamp == model->stamp);
  if (sibling != NULL)
    g_return_if_fail (sibling->stamp == model->stamp);
732

733
734
  iter->stamp = model->stamp;
  iter->tree_node = g_node_new (NULL);
735

736
737
738
739
740
741
  if (parent == NULL && sibling == NULL)
    parent_node = model->root;
  else if (parent == NULL)
    parent_node = G_NODE (sibling->tree_node)->parent;
  else
    parent_node = G_NODE (parent->tree_node);
742

743
744
745
  g_node_insert_before (parent_node,
			sibling ? G_NODE (sibling->tree_node) : NULL,
			G_NODE (iter->tree_node));
746

747
  path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
748
  gtk_signal_emit_by_name (GTK_OBJECT (model),
749
750
			   "inserted",
			   path, iter);
751
752
753
  gtk_tree_path_free (path);
}

754
void
755
756
757
758
gtk_tree_store_insert_after (GtkTreeStore *model,
			     GtkTreeIter  *iter,
			     GtkTreeIter  *parent,
			     GtkTreeIter  *sibling)
759
760
{
  GtkTreePath *path;
761
  GNode *parent_node;
762

763
764
765
766
767
768
769
  g_return_if_fail (model != NULL);
  g_return_if_fail (GTK_IS_TREE_STORE (model));
  g_return_if_fail (iter != NULL);
  if (parent != NULL)
    g_return_if_fail (parent->stamp == model->stamp);
  if (sibling != NULL)
    g_return_if_fail (sibling->stamp == model->stamp);
770

771
772
  iter->stamp = model->stamp;
  iter->tree_node = g_node_new (NULL);
773

774
775
776
777
778
779
  if (parent == NULL && sibling == NULL)
    parent_node = model->root;
  else if (parent == NULL)
    parent_node = G_NODE (sibling->tree_node)->parent;
  else
    parent_node = G_NODE (parent->tree_node);
780

781
782
783
  g_node_insert_after (parent_node,
		       sibling ? G_NODE (sibling->tree_node) : NULL,
		       G_NODE (iter->tree_node));
784

785
  path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
786
  gtk_signal_emit_by_name (GTK_OBJECT (model),
787
788
			   "inserted",
			   path, iter);
789
790
791
  gtk_tree_path_free (path);
}

792
void
793
794
795
gtk_tree_store_prepend (GtkTreeStore *model,
			GtkTreeIter  *iter,
			GtkTreeIter  *parent)
796
{
797
798
799
800
801
802
803
  GNode *parent_node;

  g_return_if_fail (model != NULL);
  g_return_if_fail (GTK_IS_TREE_STORE (model));
  g_return_if_fail (iter != NULL);
  if (parent != NULL)
    g_return_if_fail (parent->stamp == model->stamp);
804
805

  if (parent == NULL)
806
807
808
    parent_node = model->root;
  else
    parent_node = parent->tree_node;
809

810
811
812
813
  iter->stamp = model->stamp;
  iter->tree_node = g_node_new (NULL);

  if (parent_node->children == NULL)
814
815
    {
      GtkTreePath *path;
816
817
818
819

      g_node_prepend (parent_node, G_NODE (iter->tree_node));

      if (parent_node != model->root)
820
821
822
	{
	  path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent);
	  gtk_signal_emit_by_name (GTK_OBJECT (model),
823
				   "child_toggled",
824
825
				   path,
				   parent);
826
	  gtk_tree_path_append_index (path, 0);
827
828
829
	}
      else
	{
830
	  path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
831
832
	}
      gtk_signal_emit_by_name (GTK_OBJECT (model),
833
			       "inserted",
834
			       path,
835
			       iter);
836
837
838
839
      gtk_tree_path_free (path);
    }
  else
    {
840
      gtk_tree_store_insert_after (model, iter, parent, NULL);
841
842
843
    }
}

844
void
845
846
847
gtk_tree_store_append (GtkTreeStore *model,
		       GtkTreeIter  *iter,
		       GtkTreeIter  *parent)
848
{
849
850
851
852
853
854
855
  GNode *parent_node;

  g_return_if_fail (model != NULL);
  g_return_if_fail (GTK_IS_TREE_STORE (model));
  g_return_if_fail (iter != NULL);
  if (parent != NULL)
    g_return_if_fail (parent->stamp == model->stamp);
856
857

  if (parent == NULL)
858
859
860
    parent_node = model->root;
  else
    parent_node = parent->tree_node;
861

862
863
864
865
  iter->stamp = model->stamp;
  iter->tree_node = g_node_new (NULL);

  if (parent_node->children == NULL)
866
867
    {
      GtkTreePath *path;
868
869
870
871

      g_node_append (parent_node, G_NODE (iter->tree_node));

      if (parent_node != model->root)
872
873
874
	{
	  path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent);
	  gtk_signal_emit_by_name (GTK_OBJECT (model),
875
				   "child_toggled",
876
877
				   path,
				   parent);
878
	  gtk_tree_path_append_index (path, 0);
879
880
881
	}
      else
	{
882
	  path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
883
884
	}
      gtk_signal_emit_by_name (GTK_OBJECT (model),
885
			       "inserted",
886
			       path,
887
			       iter);
888
889
890
891
      gtk_tree_path_free (path);
    }
  else
    {
892
      gtk_tree_store_insert_before (model, iter, parent, NULL);
893
894
895
    }
}

896
void
897
898
gtk_tree_store_get_root_iter (GtkTreeStore *model,
			      GtkTreeIter  *iter)
899
{
900
901
902
  g_return_if_fail (model != NULL);
  g_return_if_fail (GTK_IS_TREE_STORE (model));
  g_return_if_fail (iter != NULL);
903

904
905
  iter->stamp = model->stamp;
  iter->tree_node = G_NODE (model->root)->children;
906
907
908
909
}


gboolean
910
911
912
gtk_tree_store_is_ancestor (GtkTreeStore *model,
			    GtkTreeIter  *iter,
			    GtkTreeIter  *descendant)
913
914
915
{
  g_return_val_if_fail (model != NULL, FALSE);
  g_return_val_if_fail (GTK_IS_TREE_STORE (model), FALSE);
916
  g_return_val_if_fail (iter != NULL, FALSE);
917
  g_return_val_if_fail (descendant != NULL, FALSE);
918
919
  g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
  g_return_val_if_fail (descendant->stamp == model->stamp, FALSE);
920

921
922
  return g_node_is_ancestor (G_NODE (iter->tree_node),
			     G_NODE (descendant->tree_node));
923
924
925
926
}


gint
927
928
gtk_tree_store_iter_depth (GtkTreeStore *model,
			   GtkTreeIter  *iter)
929
930
931
{
  g_return_val_if_fail (model != NULL, 0);
  g_return_val_if_fail (GTK_IS_TREE_STORE (model), 0);
932
933
  g_return_val_if_fail (iter != NULL, 0);
  g_return_val_if_fail (iter->stamp == model->stamp, 0);
934

935
  return g_node_depth (G_NODE (iter->tree_node)) - 1;
936
}