~ubuntu-branches/debian/experimental/gtk+2.0/experimental

« back to all changes in this revision

Viewing changes to tests/testtreeview.c

  • Committer: Package Import Robot
  • Author(s): Josselin Mouette
  • Date: 2011-09-02 17:17:47 UTC
  • mto: (72.4.15 sid)
  • mto: This revision was merged to the branch mainline in revision 102.
  • Revision ID: package-import@ubuntu.com-20110902171747-i8dr3czswn2sk7tu
Tags: upstream-2.24.6
ImportĀ upstreamĀ versionĀ 2.24.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* testtreeview.c
2
 
 * Copyright (C) 2001 Red Hat, Inc
3
 
 * Author: Jonathan Blandford
4
 
 *
5
 
 * This library is free software; you can redistribute it and/or
6
 
 * modify it under the terms of the GNU Library General Public
7
 
 * License as published by the Free Software Foundation; either
8
 
 * version 2 of the License, or (at your option) any later version.
9
 
 *
10
 
 * This library is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 
 * Library General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU Library General Public
16
 
 * License along with this library; if not, write to the
17
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
 
 * Boston, MA 02111-1307, USA.
19
 
 */
20
 
 
21
 
#undef GTK_DISABLE_DEPRECATED
22
 
#include <string.h>
23
 
#include "prop-editor.h"
24
1
#include <gtk/gtk.h>
25
 
#include <stdlib.h>
26
 
 
27
 
/* Don't copy this bad example; inline RGB data is always a better
28
 
 * idea than inline XPMs.
29
 
 */
30
 
static char  *book_closed_xpm[] = {
31
 
"16 16 6 1",
32
 
"       c None s None",
33
 
".      c black",
34
 
"X      c red",
35
 
"o      c yellow",
36
 
"O      c #808080",
37
 
"#      c white",
38
 
"                ",
39
 
"       ..       ",
40
 
"     ..XX.      ",
41
 
"   ..XXXXX.     ",
42
 
" ..XXXXXXXX.    ",
43
 
".ooXXXXXXXXX.   ",
44
 
"..ooXXXXXXXXX.  ",
45
 
".X.ooXXXXXXXXX. ",
46
 
".XX.ooXXXXXX..  ",
47
 
" .XX.ooXXX..#O  ",
48
 
"  .XX.oo..##OO. ",
49
 
"   .XX..##OO..  ",
50
 
"    .X.#OO..    ",
51
 
"     ..O..      ",
52
 
"      ..        ",
53
 
"                "
54
 
};
55
 
 
56
 
static void run_automated_tests (void);
57
 
 
58
 
/* This custom model is to test custom model use. */
59
 
 
60
 
#define GTK_TYPE_MODEL_TYPES                            (gtk_tree_model_types_get_type ())
61
 
#define GTK_TREE_MODEL_TYPES(obj)                       (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MODEL_TYPES, GtkTreeModelTypes))
62
 
#define GTK_TREE_MODEL_TYPES_CLASS(klass)               (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MODEL_TYPES, GtkTreeModelTypesClass))
63
 
#define GTK_IS_TREE_MODEL_TYPES(obj)                    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MODEL_TYPES))
64
 
#define GTK_IS_TREE_MODEL_TYPES_GET_CLASS(klass)        (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MODEL_TYPES))
65
 
 
66
 
typedef struct _GtkTreeModelTypes       GtkTreeModelTypes;
67
 
typedef struct _GtkTreeModelTypesClass  GtkTreeModelTypesClass;
68
 
 
69
 
struct _GtkTreeModelTypes
70
 
{
71
 
  GObject parent;
72
 
 
73
 
  gint stamp;
74
 
};
75
 
 
76
 
struct _GtkTreeModelTypesClass
77
 
{
78
 
  GObjectClass parent_class;
79
 
 
80
 
  guint        (* get_flags)       (GtkTreeModel *tree_model);   
81
 
  gint         (* get_n_columns)   (GtkTreeModel *tree_model);
82
 
  GType        (* get_column_type) (GtkTreeModel *tree_model,
83
 
                                    gint          index);
84
 
  gboolean     (* get_iter)        (GtkTreeModel *tree_model,
85
 
                                    GtkTreeIter  *iter,
86
 
                                    GtkTreePath  *path);
87
 
  GtkTreePath *(* get_path)        (GtkTreeModel *tree_model,
88
 
                                    GtkTreeIter  *iter);
89
 
  void         (* get_value)       (GtkTreeModel *tree_model,
90
 
                                    GtkTreeIter  *iter,
91
 
                                    gint          column,
92
 
                                    GValue       *value);
93
 
  gboolean     (* iter_next)       (GtkTreeModel *tree_model,
94
 
                                    GtkTreeIter  *iter);
95
 
  gboolean     (* iter_children)   (GtkTreeModel *tree_model,
96
 
                                    GtkTreeIter  *iter,
97
 
                                    GtkTreeIter  *parent);
98
 
  gboolean     (* iter_has_child)  (GtkTreeModel *tree_model,
99
 
                                    GtkTreeIter  *iter);
100
 
  gint         (* iter_n_children) (GtkTreeModel *tree_model,
101
 
                                    GtkTreeIter  *iter);
102
 
  gboolean     (* iter_nth_child)  (GtkTreeModel *tree_model,
103
 
                                    GtkTreeIter  *iter,
104
 
                                    GtkTreeIter  *parent,
105
 
                                    gint          n);
106
 
  gboolean     (* iter_parent)     (GtkTreeModel *tree_model,
107
 
                                    GtkTreeIter  *iter,
108
 
                                    GtkTreeIter  *child);
109
 
  void         (* ref_iter)        (GtkTreeModel *tree_model,
110
 
                                    GtkTreeIter  *iter);
111
 
  void         (* unref_iter)      (GtkTreeModel *tree_model,
112
 
                                    GtkTreeIter  *iter);
113
 
 
114
 
  /* These will be moved into the GtkTreeModelIface eventually */
115
 
  void         (* changed)         (GtkTreeModel *tree_model,
116
 
                                    GtkTreePath  *path,
117
 
                                    GtkTreeIter  *iter);
118
 
  void         (* inserted)        (GtkTreeModel *tree_model,
119
 
                                    GtkTreePath  *path,
120
 
                                    GtkTreeIter  *iter);
121
 
  void         (* child_toggled)   (GtkTreeModel *tree_model,
122
 
                                    GtkTreePath  *path,
123
 
                                    GtkTreeIter  *iter);
124
 
  void         (* deleted)         (GtkTreeModel *tree_model,
125
 
                                    GtkTreePath  *path);
126
 
};
127
 
 
128
 
GType              gtk_tree_model_types_get_type      (void) G_GNUC_CONST;
129
 
GtkTreeModelTypes *gtk_tree_model_types_new           (void);
130
 
 
131
 
typedef enum
132
 
{
133
 
  COLUMNS_NONE,
134
 
  COLUMNS_ONE,
135
 
  COLUMNS_LOTS,
136
 
  COLUMNS_LAST
137
 
} ColumnsType;
138
 
 
139
 
static gchar *column_type_names[] = {
140
 
  "No columns",
141
 
  "One column",
142
 
  "Many columns"
143
 
};
144
 
 
145
 
#define N_COLUMNS 9
146
 
 
147
 
static GType*
148
 
get_model_types (void)
149
 
{
150
 
  static GType column_types[N_COLUMNS] = { 0 };
151
 
  
152
 
  if (column_types[0] == 0)
153
 
    {
154
 
      column_types[0] = G_TYPE_STRING;
155
 
      column_types[1] = G_TYPE_STRING;
156
 
      column_types[2] = GDK_TYPE_PIXBUF;
157
 
      column_types[3] = G_TYPE_FLOAT;
158
 
      column_types[4] = G_TYPE_UINT;
159
 
      column_types[5] = G_TYPE_UCHAR;
160
 
      column_types[6] = G_TYPE_CHAR;
161
 
#define BOOL_COLUMN 7
162
 
      column_types[BOOL_COLUMN] = G_TYPE_BOOLEAN;
163
 
      column_types[8] = G_TYPE_INT;
164
 
    }
165
 
 
166
 
  return column_types;
167
 
}
168
 
 
169
 
static void
170
 
col_clicked_cb (GtkTreeViewColumn *col, gpointer data)
171
 
{
172
 
  GtkWindow *win;
173
 
 
174
 
  win = GTK_WINDOW (create_prop_editor (G_OBJECT (col), GTK_TYPE_TREE_VIEW_COLUMN));
175
 
 
176
 
  gtk_window_set_title (win, gtk_tree_view_column_get_title (col));
177
 
}
178
 
 
179
 
static void
180
 
setup_column (GtkTreeViewColumn *col)
181
 
{
182
 
  gtk_tree_view_column_set_clickable (col, TRUE);
183
 
  g_signal_connect (col,
184
 
                    "clicked",
185
 
                    G_CALLBACK (col_clicked_cb),
186
 
                    NULL);
187
 
}
188
 
 
189
 
static void
190
 
toggled_callback (GtkCellRendererToggle *celltoggle,
191
 
                  gchar                 *path_string,
192
 
                  GtkTreeView           *tree_view)
193
 
{
194
 
  GtkTreeModel *model = NULL;
195
 
  GtkTreeModelSort *sort_model = NULL;
196
 
  GtkTreePath *path;
197
 
  GtkTreeIter iter;
198
 
  gboolean active = FALSE;
199
 
  
200
 
  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
201
 
 
202
 
  model = gtk_tree_view_get_model (tree_view);
203
 
  
204
 
  if (GTK_IS_TREE_MODEL_SORT (model))
205
 
    {
206
 
      sort_model = GTK_TREE_MODEL_SORT (model);
207
 
      model = gtk_tree_model_sort_get_model (sort_model);
208
 
    }
209
 
 
210
 
  if (model == NULL)
211
 
    return;
212
 
 
213
 
  if (sort_model)
214
 
    {
215
 
      g_warning ("FIXME implement conversion from TreeModelSort iter to child model iter");
216
 
      return;
217
 
    }
218
 
      
219
 
  path = gtk_tree_path_new_from_string (path_string);
220
 
  if (!gtk_tree_model_get_iter (model,
221
 
                                &iter, path))
222
 
    {
223
 
      g_warning ("%s: bad path?", G_STRLOC);
224
 
      return;
225
 
    }
226
 
  gtk_tree_path_free (path);
227
 
  
228
 
  if (GTK_IS_LIST_STORE (model))
229
 
    {
230
 
      gtk_tree_model_get (GTK_TREE_MODEL (model),
231
 
                          &iter,
232
 
                          BOOL_COLUMN,
233
 
                          &active,
234
 
                          -1);
235
 
      
236
 
      gtk_list_store_set (GTK_LIST_STORE (model),
237
 
                          &iter,
238
 
                          BOOL_COLUMN,
239
 
                          !active,
240
 
                          -1);
241
 
    }
242
 
  else if (GTK_IS_TREE_STORE (model))
243
 
    {
244
 
      gtk_tree_model_get (GTK_TREE_MODEL (model),
245
 
                          &iter,
246
 
                          BOOL_COLUMN,
247
 
                          &active,
248
 
                          -1);
249
 
            
250
 
      gtk_tree_store_set (GTK_TREE_STORE (model),
251
 
                          &iter,
252
 
                          BOOL_COLUMN,
253
 
                          !active,
254
 
                          -1);
255
 
    }
256
 
  else
257
 
    g_warning ("don't know how to actually toggle value for model type %s",
258
 
               g_type_name (G_TYPE_FROM_INSTANCE (model)));
259
 
}
260
 
 
261
 
static void
262
 
edited_callback (GtkCellRendererText *renderer,
263
 
                 const gchar   *path_string,
264
 
                 const gchar   *new_text,
265
 
                 GtkTreeView  *tree_view)
266
 
{
267
 
  GtkTreeModel *model = NULL;
268
 
  GtkTreeModelSort *sort_model = NULL;
269
 
  GtkTreePath *path;
270
 
  GtkTreeIter iter;
271
 
  guint value = atoi (new_text);
272
 
  
273
 
  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
274
 
 
275
 
  model = gtk_tree_view_get_model (tree_view);
276
 
  
277
 
  if (GTK_IS_TREE_MODEL_SORT (model))
278
 
    {
279
 
      sort_model = GTK_TREE_MODEL_SORT (model);
280
 
      model = gtk_tree_model_sort_get_model (sort_model);
281
 
    }
282
 
 
283
 
  if (model == NULL)
284
 
    return;
285
 
 
286
 
  if (sort_model)
287
 
    {
288
 
      g_warning ("FIXME implement conversion from TreeModelSort iter to child model iter");
289
 
      return;
290
 
    }
291
 
      
292
 
  path = gtk_tree_path_new_from_string (path_string);
293
 
  if (!gtk_tree_model_get_iter (model,
294
 
                                &iter, path))
295
 
    {
296
 
      g_warning ("%s: bad path?", G_STRLOC);
297
 
      return;
298
 
    }
299
 
  gtk_tree_path_free (path);
300
 
 
301
 
  if (GTK_IS_LIST_STORE (model))
302
 
    {
303
 
      gtk_list_store_set (GTK_LIST_STORE (model),
304
 
                          &iter,
305
 
                          4,
306
 
                          value,
307
 
                          -1);
308
 
    }
309
 
  else if (GTK_IS_TREE_STORE (model))
310
 
    {
311
 
      gtk_tree_store_set (GTK_TREE_STORE (model),
312
 
                          &iter,
313
 
                          4,
314
 
                          value,
315
 
                          -1);
316
 
    }
317
 
  else
318
 
    g_warning ("don't know how to actually toggle value for model type %s",
319
 
               g_type_name (G_TYPE_FROM_INSTANCE (model)));
320
 
}
321
 
 
322
 
static ColumnsType current_column_type = COLUMNS_LOTS;
323
 
 
324
 
static void
325
 
set_columns_type (GtkTreeView *tree_view, ColumnsType type)
326
 
{
327
 
  GtkTreeViewColumn *col;
328
 
  GtkCellRenderer *rend;
329
 
  GdkPixbuf *pixbuf;
330
 
  GtkWidget *image;
331
 
  GtkObject *adjustment;
332
 
    
333
 
  current_column_type = type;
334
 
  
335
 
  col = gtk_tree_view_get_column (tree_view, 0);
336
 
  while (col)
337
 
    {
338
 
      gtk_tree_view_remove_column (tree_view, col);
339
 
 
340
 
      col = gtk_tree_view_get_column (tree_view, 0);
341
 
    }
342
 
 
343
 
  gtk_tree_view_set_rules_hint (tree_view, FALSE);
344
 
  
345
 
  switch (type)
346
 
    {
347
 
    case COLUMNS_NONE:
348
 
      break;
349
 
 
350
 
    case COLUMNS_LOTS:
351
 
      /* with lots of columns we need to turn on rules */
352
 
      gtk_tree_view_set_rules_hint (tree_view, TRUE);
353
 
      
354
 
      rend = gtk_cell_renderer_text_new ();
355
 
      
356
 
      col = gtk_tree_view_column_new_with_attributes ("Column 1",
357
 
                                                      rend,
358
 
                                                      "text", 1,
359
 
                                                      NULL);
360
 
      setup_column (col);
361
 
      
362
 
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
363
 
      
364
 
      col = gtk_tree_view_column_new();
365
 
      gtk_tree_view_column_set_title (col, "Column 2");
366
 
      
367
 
      rend = gtk_cell_renderer_pixbuf_new ();
368
 
      gtk_tree_view_column_pack_start (col, rend, FALSE);
369
 
      gtk_tree_view_column_add_attribute (col, rend, "pixbuf", 2);
370
 
      rend = gtk_cell_renderer_text_new ();
371
 
      gtk_tree_view_column_pack_start (col, rend, TRUE);
372
 
      gtk_tree_view_column_add_attribute (col, rend, "text", 0);
373
 
 
374
 
      setup_column (col);
375
 
      
376
 
      
377
 
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
378
 
      gtk_tree_view_set_expander_column (tree_view, col);
379
 
      
380
 
      rend = gtk_cell_renderer_toggle_new ();
381
 
 
382
 
      g_signal_connect (rend, "toggled",
383
 
                        G_CALLBACK (toggled_callback), tree_view);
384
 
      
385
 
      col = gtk_tree_view_column_new_with_attributes ("Column 3",
386
 
                                                      rend,
387
 
                                                      "active", BOOL_COLUMN,
388
 
                                                      NULL);
389
 
 
390
 
      setup_column (col);
391
 
      
392
 
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
393
 
 
394
 
      pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **)book_closed_xpm);
395
 
 
396
 
      image = gtk_image_new_from_pixbuf (pixbuf);
397
 
 
398
 
      g_object_unref (pixbuf);
399
 
      
400
 
      gtk_widget_show (image);
401
 
      
402
 
      gtk_tree_view_column_set_widget (col, image);
403
 
      
404
 
      rend = gtk_cell_renderer_toggle_new ();
405
 
 
406
 
      /* you could also set this per-row by tying it to a column
407
 
       * in the model of course.
408
 
       */
409
 
      g_object_set (rend, "radio", TRUE, NULL);
410
 
      
411
 
      g_signal_connect (rend, "toggled",
412
 
                        G_CALLBACK (toggled_callback), tree_view);
413
 
      
414
 
      col = gtk_tree_view_column_new_with_attributes ("Column 4",
415
 
                                                      rend,
416
 
                                                      "active", BOOL_COLUMN,
417
 
                                                      NULL);
418
 
 
419
 
      setup_column (col);
420
 
      
421
 
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
422
 
 
423
 
      rend = gtk_cell_renderer_spin_new ();
424
 
 
425
 
      adjustment = gtk_adjustment_new (0, 0, 10000, 100, 100, 100);
426
 
      g_object_set (rend, "editable", TRUE, NULL);
427
 
      g_object_set (rend, "adjustment", adjustment, NULL);
428
 
 
429
 
      g_signal_connect (rend, "edited",
430
 
                        G_CALLBACK (edited_callback), tree_view);
431
 
 
432
 
      col = gtk_tree_view_column_new_with_attributes ("Column 5",
433
 
                                                      rend,
434
 
                                                      "text", 4,
435
 
                                                      NULL);
436
 
 
437
 
      setup_column (col);
438
 
      
439
 
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
440
 
#if 0
441
 
      
442
 
      rend = gtk_cell_renderer_text_new ();
443
 
      
444
 
      col = gtk_tree_view_column_new_with_attributes ("Column 6",
445
 
                                                      rend,
446
 
                                                      "text", 4,
447
 
                                                      NULL);
448
 
 
449
 
      setup_column (col);
450
 
      
451
 
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
452
 
      
453
 
      rend = gtk_cell_renderer_text_new ();
454
 
      
455
 
      col = gtk_tree_view_column_new_with_attributes ("Column 7",
456
 
                                                      rend,
457
 
                                                      "text", 5,
458
 
                                                      NULL);
459
 
 
460
 
      setup_column (col);
461
 
      
462
 
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
463
 
      
464
 
      rend = gtk_cell_renderer_text_new ();
465
 
      
466
 
      col = gtk_tree_view_column_new_with_attributes ("Column 8",
467
 
                                                      rend,
468
 
                                                      "text", 6,
469
 
                                                      NULL);
470
 
 
471
 
      setup_column (col);
472
 
      
473
 
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
474
 
      
475
 
      rend = gtk_cell_renderer_text_new ();
476
 
      
477
 
      col = gtk_tree_view_column_new_with_attributes ("Column 9",
478
 
                                                      rend,
479
 
                                                      "text", 7,
480
 
                                                      NULL);
481
 
 
482
 
      setup_column (col);
483
 
      
484
 
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
485
 
      
486
 
      rend = gtk_cell_renderer_text_new ();
487
 
      
488
 
      col = gtk_tree_view_column_new_with_attributes ("Column 10",
489
 
                                                      rend,
490
 
                                                      "text", 8,
491
 
                                                      NULL);
492
 
 
493
 
      setup_column (col);
494
 
      
495
 
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
496
 
      
497
 
#endif
498
 
      
499
 
      /* FALL THRU */
500
 
      
501
 
    case COLUMNS_ONE:
502
 
      rend = gtk_cell_renderer_text_new ();
503
 
      
504
 
      col = gtk_tree_view_column_new_with_attributes ("Column 0",
505
 
                                                      rend,
506
 
                                                      "text", 0,
507
 
                                                      NULL);
508
 
 
509
 
      setup_column (col);
510
 
      
511
 
      gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), col, 0);
512
 
    default:
513
 
      break;
514
 
    }
515
 
}
516
 
 
517
 
static ColumnsType
518
 
get_columns_type (void)
519
 
{
520
 
  return current_column_type;
521
 
}
522
 
 
523
 
static GdkPixbuf *our_pixbuf;
524
 
  
525
 
typedef enum
526
 
{
527
 
  /*   MODEL_TYPES, */
528
 
  MODEL_TREE,
529
 
  MODEL_LIST,
530
 
  MODEL_SORTED_TREE,
531
 
  MODEL_SORTED_LIST,
532
 
  MODEL_EMPTY_LIST,
533
 
  MODEL_EMPTY_TREE,
534
 
  MODEL_NULL,
535
 
  MODEL_LAST
536
 
} ModelType;
537
 
 
538
 
/* FIXME add a custom model to test */
539
 
static GtkTreeModel *models[MODEL_LAST];
540
 
static const char *model_names[MODEL_LAST] = {
541
 
  "GtkTreeStore",
542
 
  "GtkListStore",
543
 
  "GtkTreeModelSort wrapping GtkTreeStore",
544
 
  "GtkTreeModelSort wrapping GtkListStore",
545
 
  "Empty GtkListStore",
546
 
  "Empty GtkTreeStore",
547
 
  "NULL (no model)"
548
 
};
549
 
 
550
 
static GtkTreeModel*
551
 
create_list_model (void)
552
 
{
553
 
  GtkListStore *store;
554
 
  GtkTreeIter iter;
555
 
  gint i;
556
 
  GType *t;
557
 
 
558
 
  t = get_model_types ();
559
 
  
560
 
  store = gtk_list_store_new (N_COLUMNS,
561
 
                              t[0], t[1], t[2],
562
 
                              t[3], t[4], t[5],
563
 
                              t[6], t[7], t[8]);
564
 
 
565
 
  i = 0;
566
 
  while (i < 200)
567
 
    {
568
 
      char *msg;
569
 
      
570
 
      gtk_list_store_append (store, &iter);
571
 
 
572
 
      msg = g_strdup_printf ("%d", i);
573
 
      
574
 
      gtk_list_store_set (store, &iter, 0, msg, 1, "Foo! Foo! Foo!",
575
 
                          2, our_pixbuf,
576
 
                          3, 7.0, 4, (guint) 9000,
577
 
                          5, 'f', 6, 'g',
578
 
                          7, TRUE, 8, 23245454,
579
 
                          -1);
580
 
 
581
 
      g_free (msg);
582
 
      
583
 
      ++i;
584
 
    }
585
 
 
586
 
  return GTK_TREE_MODEL (store);
587
 
}
588
 
 
589
 
static void
590
 
typesystem_recurse (GType        type,
591
 
                    GtkTreeIter *parent_iter,
592
 
                    GtkTreeStore *store)
593
 
{
594
 
  GType* children;
595
 
  guint n_children = 0;
596
 
  gint i;
597
 
  GtkTreeIter iter;
598
 
  gchar *str;
599
 
  
600
 
  gtk_tree_store_append (store, &iter, parent_iter);
601
 
 
602
 
  str = g_strdup_printf ("%ld", (glong)type);
603
 
  gtk_tree_store_set (store, &iter, 0, str, 1, g_type_name (type),
604
 
                      2, our_pixbuf,
605
 
                      3, 7.0, 4, (guint) 9000,
606
 
                      5, 'f', 6, 'g',
607
 
                      7, TRUE, 8, 23245454,
608
 
                      -1);
609
 
  g_free (str);
610
 
  
611
 
  children = g_type_children (type, &n_children);
612
 
 
613
 
  i = 0;
614
 
  while (i < n_children)
615
 
    {
616
 
      typesystem_recurse (children[i], &iter, store);
617
 
 
618
 
      ++i;
619
 
    }
620
 
  
621
 
  g_free (children);
622
 
}
623
 
 
624
 
static GtkTreeModel*
625
 
create_tree_model (void)
626
 
{
627
 
  GtkTreeStore *store;
628
 
  gint i;
629
 
  GType *t;
630
 
  volatile GType dummy; /* G_GNUC_CONST makes the optimizer remove
631
 
                         * get_type calls if you don't do something
632
 
                         * like this
633
 
                         */
634
 
  
635
 
  /* Make the tree more interesting */
636
 
  dummy = gtk_scrolled_window_get_type ();
637
 
  dummy = gtk_label_get_type ();
638
 
  dummy = gtk_hscrollbar_get_type ();
639
 
  dummy = gtk_vscrollbar_get_type ();
640
 
  dummy = pango_layout_get_type ();
641
 
 
642
 
  t = get_model_types ();
643
 
  
644
 
  store = gtk_tree_store_new (N_COLUMNS,
645
 
                              t[0], t[1], t[2],
646
 
                              t[3], t[4], t[5],
647
 
                              t[6], t[7], t[8]);
648
 
 
649
 
  i = 0;
650
 
  while (i < G_TYPE_FUNDAMENTAL_MAX)
651
 
    {
652
 
      typesystem_recurse (i, NULL, store);
653
 
      
654
 
      ++i;
655
 
    }
656
 
 
657
 
  return GTK_TREE_MODEL (store);
658
 
}
659
 
 
660
 
static void
661
 
model_selected (GtkComboBox *combo_box, gpointer data)
662
 
{
663
 
  GtkTreeView *tree_view = GTK_TREE_VIEW (data);
664
 
  gint hist;
665
 
 
666
 
  hist = gtk_combo_box_get_active (combo_box);
667
 
 
668
 
  if (models[hist] != gtk_tree_view_get_model (tree_view))
669
 
    {
670
 
      gtk_tree_view_set_model (tree_view, models[hist]);
671
 
    }
672
 
}
673
 
 
674
 
static void
675
 
columns_selected (GtkComboBox *combo_box, gpointer data)
676
 
{
677
 
  GtkTreeView *tree_view = GTK_TREE_VIEW (data);
678
 
  gint hist;
679
 
 
680
 
  hist = gtk_combo_box_get_active (combo_box);
681
 
 
682
 
  if (hist != get_columns_type ())
683
 
    {
684
 
      set_columns_type (tree_view, hist);
685
 
    }
686
 
}
687
 
 
688
 
 
689
 
enum
690
 
{
691
 
  TARGET_GTK_TREE_MODEL_ROW
692
 
};
693
 
 
694
 
static GtkTargetEntry row_targets[] = {
695
 
  { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_APP,
696
 
    TARGET_GTK_TREE_MODEL_ROW }
697
 
};
698
2
 
699
3
int
700
 
main (int    argc,
701
 
      char **argv)
 
4
main (int argc, char *argv[])
702
5
{
703
 
  GtkWidget *window;
704
 
  GtkWidget *sw;
705
 
  GtkWidget *tv;
706
 
  GtkWidget *table;
707
 
  GtkWidget *combo_box;
708
 
  GtkTreeModel *model;
709
 
  gint i;
710
 
  
 
6
  GtkWidget *w;
 
7
  GdkWindow *win;
 
8
  GdkRegion *region;
 
9
  GdkRectangle rect = { 10, 10, 100, 100 };
 
10
 
711
11
  gtk_init (&argc, &argv);
712
12
 
713
 
  our_pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) book_closed_xpm);  
714
 
  
715
 
#if 0
716
 
  models[MODEL_TYPES] = GTK_TREE_MODEL (gtk_tree_model_types_new ());
717
 
#endif
718
 
  models[MODEL_LIST] = create_list_model ();
719
 
  models[MODEL_TREE] = create_tree_model ();
720
 
 
721
 
  model = create_list_model ();
722
 
  models[MODEL_SORTED_LIST] = gtk_tree_model_sort_new_with_model (model);
723
 
  g_object_unref (model);
724
 
 
725
 
  model = create_tree_model ();
726
 
  models[MODEL_SORTED_TREE] = gtk_tree_model_sort_new_with_model (model);
727
 
  g_object_unref (model);
728
 
 
729
 
  models[MODEL_EMPTY_LIST] = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_INT));
730
 
  models[MODEL_EMPTY_TREE] = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
731
 
  
732
 
  models[MODEL_NULL] = NULL;
733
 
 
734
 
  run_automated_tests ();
735
 
  
736
 
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
737
 
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
738
 
  gtk_window_set_default_size (GTK_WINDOW (window), 430, 400);
739
 
 
740
 
  table = gtk_table_new (3, 1, FALSE);
741
 
 
742
 
  gtk_container_add (GTK_CONTAINER (window), table);
743
 
 
744
 
  tv = gtk_tree_view_new_with_model (models[0]);
745
 
  
746
 
  gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (tv),
747
 
                                          GDK_BUTTON1_MASK,
748
 
                                          row_targets,
749
 
                                          G_N_ELEMENTS (row_targets),
750
 
                                          GDK_ACTION_MOVE | GDK_ACTION_COPY);
751
 
 
752
 
  gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (tv),
753
 
                                        row_targets,
754
 
                                        G_N_ELEMENTS (row_targets),
755
 
                                        GDK_ACTION_MOVE | GDK_ACTION_COPY);
756
 
  
757
 
  /* Model menu */
758
 
  combo_box = gtk_combo_box_text_new ();
759
 
  for (i = 0; i < MODEL_LAST; i++)
760
 
      gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), model_names[i]);
761
 
 
762
 
  gtk_table_attach (GTK_TABLE (table), combo_box,
763
 
                    0, 1, 0, 1,
764
 
                    0, 0, 
765
 
                    0, 0);
766
 
 
767
 
  g_signal_connect (combo_box,
768
 
                    "changed",
769
 
                    G_CALLBACK (model_selected),
770
 
                    tv);
771
 
  
772
 
  /* Columns menu */
773
 
  combo_box = gtk_combo_box_text_new ();
774
 
  for (i = 0; i < COLUMNS_LAST; i++)
775
 
      gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), column_type_names[i]);
776
 
 
777
 
  gtk_table_attach (GTK_TABLE (table), combo_box,
778
 
                    0, 1, 1, 2,
779
 
                    0, 0, 
780
 
                    0, 0);
781
 
 
782
 
  set_columns_type (GTK_TREE_VIEW (tv), COLUMNS_LOTS);
783
 
  gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), COLUMNS_LOTS);
784
 
  
785
 
  g_signal_connect (combo_box,
786
 
                    "changed",
787
 
                    G_CALLBACK (columns_selected),
788
 
                    tv);
789
 
  
790
 
  sw = gtk_scrolled_window_new (NULL, NULL);
791
 
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
792
 
                                  GTK_POLICY_AUTOMATIC,
793
 
                                  GTK_POLICY_AUTOMATIC);
794
 
  
795
 
  gtk_table_attach (GTK_TABLE (table), sw,
796
 
                    0, 1, 2, 3,
797
 
                    GTK_EXPAND | GTK_FILL,
798
 
                    GTK_EXPAND | GTK_FILL,
799
 
                    0, 0);
800
 
  
801
 
  gtk_container_add (GTK_CONTAINER (sw), tv);
802
 
  
803
 
  gtk_widget_show_all (window);
804
 
  
 
13
  w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
14
 
 
15
  gtk_widget_show (w);
 
16
 
 
17
  win = gtk_widget_get_window (w);
 
18
 
 
19
  region = gdk_region_rectangle (&rect);
 
20
  gdk_window_shape_combine_region (win, region, 0, 0);
 
21
 
 
22
  if (argc < 2)
 
23
    region = NULL;
 
24
  else if (strcmp (argv[1], "--empty") == 0)
 
25
    region = gdk_region_new ();
 
26
  else if (strcmp (argv[1], "--nonempty") == 0)
 
27
    region = gdk_region_rectangle (&rect);
 
28
 
 
29
  gdk_window_shape_combine_region (win, region, 0, 0);
 
30
 
 
31
  if (region)
 
32
    gdk_region_destroy (region);
 
33
 
805
34
  gtk_main ();
806
35
 
807
36
  return 0;
808
37
}
809
38
 
810
 
/*
811
 
 * GtkTreeModelTypes
812
 
 */
813
 
 
814
 
static void         gtk_tree_model_types_init                 (GtkTreeModelTypes      *model_types);
815
 
static void         gtk_tree_model_types_tree_model_init      (GtkTreeModelIface   *iface);
816
 
static gint         gtk_real_model_types_get_n_columns   (GtkTreeModel        *tree_model);
817
 
static GType        gtk_real_model_types_get_column_type (GtkTreeModel        *tree_model,
818
 
                                                           gint                 index);
819
 
static GtkTreePath *gtk_real_model_types_get_path        (GtkTreeModel        *tree_model,
820
 
                                                           GtkTreeIter         *iter);
821
 
static void         gtk_real_model_types_get_value       (GtkTreeModel        *tree_model,
822
 
                                                           GtkTreeIter         *iter,
823
 
                                                           gint                 column,
824
 
                                                           GValue              *value);
825
 
static gboolean     gtk_real_model_types_iter_next       (GtkTreeModel        *tree_model,
826
 
                                                           GtkTreeIter         *iter);
827
 
static gboolean     gtk_real_model_types_iter_children   (GtkTreeModel        *tree_model,
828
 
                                                           GtkTreeIter         *iter,
829
 
                                                           GtkTreeIter         *parent);
830
 
static gboolean     gtk_real_model_types_iter_has_child  (GtkTreeModel        *tree_model,
831
 
                                                           GtkTreeIter         *iter);
832
 
static gint         gtk_real_model_types_iter_n_children (GtkTreeModel        *tree_model,
833
 
                                                           GtkTreeIter         *iter);
834
 
static gboolean     gtk_real_model_types_iter_nth_child  (GtkTreeModel        *tree_model,
835
 
                                                           GtkTreeIter         *iter,
836
 
                                                           GtkTreeIter         *parent,
837
 
                                                           gint                 n);
838
 
static gboolean     gtk_real_model_types_iter_parent     (GtkTreeModel        *tree_model,
839
 
                                                           GtkTreeIter         *iter,
840
 
                                                           GtkTreeIter         *child);
841
 
 
842
 
 
843
 
GType
844
 
gtk_tree_model_types_get_type (void)
845
 
{
846
 
  static GType model_types_type = 0;
847
 
 
848
 
  if (!model_types_type)
849
 
    {
850
 
      const GTypeInfo model_types_info =
851
 
      {
852
 
        sizeof (GtkTreeModelTypesClass),
853
 
        NULL,           /* base_init */
854
 
        NULL,           /* base_finalize */
855
 
        NULL,           /* class_init */
856
 
        NULL,           /* class_finalize */
857
 
        NULL,           /* class_data */
858
 
        sizeof (GtkTreeModelTypes),
859
 
        0,
860
 
        (GInstanceInitFunc) gtk_tree_model_types_init
861
 
      };
862
 
 
863
 
      const GInterfaceInfo tree_model_info =
864
 
      {
865
 
        (GInterfaceInitFunc) gtk_tree_model_types_tree_model_init,
866
 
        NULL,
867
 
        NULL
868
 
      };
869
 
 
870
 
      model_types_type = g_type_register_static (G_TYPE_OBJECT,
871
 
                                                 "GtkTreeModelTypes",
872
 
                                                 &model_types_info, 0);
873
 
      g_type_add_interface_static (model_types_type,
874
 
                                   GTK_TYPE_TREE_MODEL,
875
 
                                   &tree_model_info);
876
 
    }
877
 
 
878
 
  return model_types_type;
879
 
}
880
 
 
881
 
GtkTreeModelTypes *
882
 
gtk_tree_model_types_new (void)
883
 
{
884
 
  GtkTreeModelTypes *retval;
885
 
 
886
 
  retval = g_object_new (GTK_TYPE_MODEL_TYPES, NULL);
887
 
 
888
 
  return retval;
889
 
}
890
 
 
891
 
static void
892
 
gtk_tree_model_types_tree_model_init (GtkTreeModelIface *iface)
893
 
{
894
 
  iface->get_n_columns = gtk_real_model_types_get_n_columns;
895
 
  iface->get_column_type = gtk_real_model_types_get_column_type;
896
 
  iface->get_path = gtk_real_model_types_get_path;
897
 
  iface->get_value = gtk_real_model_types_get_value;
898
 
  iface->iter_next = gtk_real_model_types_iter_next;
899
 
  iface->iter_children = gtk_real_model_types_iter_children;
900
 
  iface->iter_has_child = gtk_real_model_types_iter_has_child;
901
 
  iface->iter_n_children = gtk_real_model_types_iter_n_children;
902
 
  iface->iter_nth_child = gtk_real_model_types_iter_nth_child;
903
 
  iface->iter_parent = gtk_real_model_types_iter_parent;
904
 
}
905
 
 
906
 
static void
907
 
gtk_tree_model_types_init (GtkTreeModelTypes *model_types)
908
 
{
909
 
  model_types->stamp = g_random_int ();
910
 
}
911
 
 
912
 
static GType column_types[] = {
913
 
  G_TYPE_STRING, /* GType */
914
 
  G_TYPE_STRING  /* type name */
915
 
};
916
 
  
917
 
static gint
918
 
gtk_real_model_types_get_n_columns (GtkTreeModel *tree_model)
919
 
{
920
 
  return G_N_ELEMENTS (column_types);
921
 
}
922
 
 
923
 
static GType
924
 
gtk_real_model_types_get_column_type (GtkTreeModel *tree_model,
925
 
                                      gint          index)
926
 
{
927
 
  g_return_val_if_fail (index < G_N_ELEMENTS (column_types), G_TYPE_INVALID);
928
 
  
929
 
  return column_types[index];
930
 
}
931
 
 
932
 
#if 0
933
 
/* Use default implementation of this */
934
 
static gboolean
935
 
gtk_real_model_types_get_iter (GtkTreeModel *tree_model,
936
 
                               GtkTreeIter  *iter,
937
 
                               GtkTreePath  *path)
938
 
{
939
 
  
940
 
}
941
 
#endif
942
 
 
943
 
/* The toplevel nodes of the tree are the reserved types, G_TYPE_NONE through
944
 
 * G_TYPE_RESERVED_FUNDAMENTAL.
945
 
 */
946
 
 
947
 
static GtkTreePath *
948
 
gtk_real_model_types_get_path (GtkTreeModel *tree_model,
949
 
                               GtkTreeIter  *iter)
950
 
{
951
 
  GtkTreePath *retval;
952
 
  GType type;
953
 
  GType parent;
954
 
  
955
 
  g_return_val_if_fail (GTK_IS_TREE_MODEL_TYPES (tree_model), NULL);
956
 
  g_return_val_if_fail (iter != NULL, NULL);
957
 
 
958
 
  type = GPOINTER_TO_INT (iter->user_data);
959
 
  
960
 
  retval = gtk_tree_path_new ();
961
 
  
962
 
  parent = g_type_parent (type);
963
 
  while (parent != G_TYPE_INVALID)
964
 
    {
965
 
      GType* children = g_type_children (parent, NULL);
966
 
      gint i = 0;
967
 
 
968
 
      if (!children || children[0] == G_TYPE_INVALID)
969
 
        {
970
 
          g_warning ("bad iterator?");
971
 
          return NULL;
972
 
        }
973
 
      
974
 
      while (children[i] != type)
975
 
        ++i;
976
 
 
977
 
      gtk_tree_path_prepend_index (retval, i);
978
 
 
979
 
      g_free (children);
980
 
      
981
 
      type = parent;
982
 
      parent = g_type_parent (parent);
983
 
    }
984
 
 
985
 
  /* The fundamental type itself is the index on the toplevel */
986
 
  gtk_tree_path_prepend_index (retval, type);
987
 
 
988
 
  return retval;
989
 
}
990
 
 
991
 
static void
992
 
gtk_real_model_types_get_value (GtkTreeModel *tree_model,
993
 
                                GtkTreeIter  *iter,
994
 
                                gint          column,
995
 
                                GValue       *value)
996
 
{
997
 
  GType type;
998
 
 
999
 
  type = GPOINTER_TO_INT (iter->user_data);
1000
 
 
1001
 
  switch (column)
1002
 
    {
1003
 
    case 0:
1004
 
      {
1005
 
        gchar *str;
1006
 
        
1007
 
        g_value_init (value, G_TYPE_STRING);
1008
 
 
1009
 
        str = g_strdup_printf ("%ld", (long int) type);
1010
 
        g_value_set_string (value, str);
1011
 
        g_free (str);
1012
 
      }
1013
 
      break;
1014
 
 
1015
 
    case 1:
1016
 
      g_value_init (value, G_TYPE_STRING);
1017
 
      g_value_set_string (value, g_type_name (type));
1018
 
      break;
1019
 
 
1020
 
    default:
1021
 
      g_warning ("Bad column %d requested", column);
1022
 
    }
1023
 
}
1024
 
 
1025
 
static gboolean
1026
 
gtk_real_model_types_iter_next (GtkTreeModel  *tree_model,
1027
 
                                GtkTreeIter   *iter)
1028
 
{
1029
 
  
1030
 
  GType parent;
1031
 
  GType type;
1032
 
 
1033
 
  type = GPOINTER_TO_INT (iter->user_data);
1034
 
 
1035
 
  parent = g_type_parent (type);
1036
 
  
1037
 
  if (parent == G_TYPE_INVALID)
1038
 
    {
1039
 
      /* find next _valid_ fundamental type */
1040
 
      do
1041
 
        type++;
1042
 
      while (!g_type_name (type) && type <= G_TYPE_FUNDAMENTAL_MAX);
1043
 
      if (type <= G_TYPE_FUNDAMENTAL_MAX)
1044
 
        {
1045
 
          /* found one */
1046
 
          iter->user_data = GINT_TO_POINTER (type);
1047
 
          return TRUE;
1048
 
        }
1049
 
      else
1050
 
        return FALSE;
1051
 
    }
1052
 
  else
1053
 
    {
1054
 
      GType* children = g_type_children (parent, NULL);
1055
 
      gint i = 0;
1056
 
 
1057
 
      g_assert (children != NULL);
1058
 
      
1059
 
      while (children[i] != type)
1060
 
        ++i;
1061
 
  
1062
 
      ++i;
1063
 
 
1064
 
      if (children[i] != G_TYPE_INVALID)
1065
 
        {
1066
 
          g_free (children);
1067
 
          iter->user_data = GINT_TO_POINTER (children[i]);
1068
 
          return TRUE;
1069
 
        }
1070
 
      else
1071
 
        {
1072
 
          g_free (children);
1073
 
          return FALSE;
1074
 
        }
1075
 
    }
1076
 
}
1077
 
 
1078
 
static gboolean
1079
 
gtk_real_model_types_iter_children (GtkTreeModel *tree_model,
1080
 
                                    GtkTreeIter  *iter,
1081
 
                                    GtkTreeIter  *parent)
1082
 
{
1083
 
  GType type;
1084
 
  GType* children;
1085
 
  
1086
 
  type = GPOINTER_TO_INT (parent->user_data);
1087
 
 
1088
 
  children = g_type_children (type, NULL);
1089
 
 
1090
 
  if (!children || children[0] == G_TYPE_INVALID)
1091
 
    {
1092
 
      g_free (children);
1093
 
      return FALSE;
1094
 
    }
1095
 
  else
1096
 
    {
1097
 
      iter->user_data = GINT_TO_POINTER (children[0]);
1098
 
      g_free (children);
1099
 
      return TRUE;
1100
 
    }
1101
 
}
1102
 
 
1103
 
static gboolean
1104
 
gtk_real_model_types_iter_has_child (GtkTreeModel *tree_model,
1105
 
                                     GtkTreeIter  *iter)
1106
 
{
1107
 
  GType type;
1108
 
  GType* children;
1109
 
  
1110
 
  type = GPOINTER_TO_INT (iter->user_data);
1111
 
  
1112
 
  children = g_type_children (type, NULL);
1113
 
 
1114
 
  if (!children || children[0] == G_TYPE_INVALID)
1115
 
    {
1116
 
      g_free (children);
1117
 
      return FALSE;
1118
 
    }
1119
 
  else
1120
 
    {
1121
 
      g_free (children);
1122
 
      return TRUE;
1123
 
    }
1124
 
}
1125
 
 
1126
 
static gint
1127
 
gtk_real_model_types_iter_n_children (GtkTreeModel *tree_model,
1128
 
                                      GtkTreeIter  *iter)
1129
 
{
1130
 
  if (iter == NULL)
1131
 
    {
1132
 
      return G_TYPE_FUNDAMENTAL_MAX;
1133
 
    }
1134
 
  else
1135
 
    {
1136
 
      GType type;
1137
 
      GType* children;
1138
 
      guint n_children = 0;
1139
 
 
1140
 
      type = GPOINTER_TO_INT (iter->user_data);
1141
 
      
1142
 
      children = g_type_children (type, &n_children);
1143
 
      
1144
 
      g_free (children);
1145
 
      
1146
 
      return n_children;
1147
 
    }
1148
 
}
1149
 
 
1150
 
static gboolean
1151
 
gtk_real_model_types_iter_nth_child (GtkTreeModel *tree_model,
1152
 
                                     GtkTreeIter  *iter,
1153
 
                                     GtkTreeIter  *parent,
1154
 
                                     gint          n)
1155
 
{  
1156
 
  if (parent == NULL)
1157
 
    {
1158
 
      /* fundamental type */
1159
 
      if (n < G_TYPE_FUNDAMENTAL_MAX)
1160
 
        {
1161
 
          iter->user_data = GINT_TO_POINTER (n);
1162
 
          return TRUE;
1163
 
        }
1164
 
      else
1165
 
        return FALSE;
1166
 
    }
1167
 
  else
1168
 
    {
1169
 
      GType type = GPOINTER_TO_INT (parent->user_data);      
1170
 
      guint n_children = 0;
1171
 
      GType* children = g_type_children (type, &n_children);
1172
 
 
1173
 
      if (n_children == 0)
1174
 
        {
1175
 
          g_free (children);
1176
 
          return FALSE;
1177
 
        }
1178
 
      else if (n >= n_children)
1179
 
        {
1180
 
          g_free (children);
1181
 
          return FALSE;
1182
 
        }
1183
 
      else
1184
 
        {
1185
 
          iter->user_data = GINT_TO_POINTER (children[n]);
1186
 
          g_free (children);
1187
 
 
1188
 
          return TRUE;
1189
 
        }
1190
 
    }
1191
 
}
1192
 
 
1193
 
static gboolean
1194
 
gtk_real_model_types_iter_parent (GtkTreeModel *tree_model,
1195
 
                                  GtkTreeIter  *iter,
1196
 
                                  GtkTreeIter  *child)
1197
 
{
1198
 
  GType type;
1199
 
  GType parent;
1200
 
  
1201
 
  type = GPOINTER_TO_INT (child->user_data);
1202
 
  
1203
 
  parent = g_type_parent (type);
1204
 
  
1205
 
  if (parent == G_TYPE_INVALID)
1206
 
    {
1207
 
      if (type > G_TYPE_FUNDAMENTAL_MAX)
1208
 
        g_warning ("no parent for %ld %s\n",
1209
 
                   (long int) type,
1210
 
                   g_type_name (type));
1211
 
      return FALSE;
1212
 
    }
1213
 
  else
1214
 
    {
1215
 
      iter->user_data = GINT_TO_POINTER (parent);
1216
 
      
1217
 
      return TRUE;
1218
 
    }
1219
 
}
1220
 
 
1221
 
/*
1222
 
 * Automated testing
1223
 
 */
1224
 
 
1225
 
#if 0
1226
 
 
1227
 
static void
1228
 
treestore_torture_recurse (GtkTreeStore *store,
1229
 
                           GtkTreeIter  *root,
1230
 
                           gint          depth)
1231
 
{
1232
 
  GtkTreeModel *model;
1233
 
  gint i;
1234
 
  GtkTreeIter iter;  
1235
 
  
1236
 
  model = GTK_TREE_MODEL (store);    
1237
 
 
1238
 
  if (depth > 2)
1239
 
    return;
1240
 
 
1241
 
  ++depth;
1242
 
 
1243
 
  gtk_tree_store_append (store, &iter, root);
1244
 
  
1245
 
  gtk_tree_model_iter_children (model, &iter, root);
1246
 
  
1247
 
  i = 0;
1248
 
  while (i < 100)
1249
 
    {
1250
 
      gtk_tree_store_append (store, &iter, root);
1251
 
      ++i;
1252
 
    }
1253
 
 
1254
 
  while (gtk_tree_model_iter_children (model, &iter, root))
1255
 
    gtk_tree_store_remove (store, &iter);
1256
 
 
1257
 
  gtk_tree_store_append (store, &iter, root);
1258
 
 
1259
 
  /* inserts before last node in tree */
1260
 
  i = 0;
1261
 
  while (i < 100)
1262
 
    {
1263
 
      gtk_tree_store_insert_before (store, &iter, root, &iter);
1264
 
      ++i;
1265
 
    }
1266
 
 
1267
 
  /* inserts after the node before the last node */
1268
 
  i = 0;
1269
 
  while (i < 100)
1270
 
    {
1271
 
      gtk_tree_store_insert_after (store, &iter, root, &iter);
1272
 
      ++i;
1273
 
    }
1274
 
 
1275
 
  /* inserts after the last node */
1276
 
  gtk_tree_store_append (store, &iter, root);
1277
 
    
1278
 
  i = 0;
1279
 
  while (i < 100)
1280
 
    {
1281
 
      gtk_tree_store_insert_after (store, &iter, root, &iter);
1282
 
      ++i;
1283
 
    }
1284
 
 
1285
 
  /* remove everything again */
1286
 
  while (gtk_tree_model_iter_children (model, &iter, root))
1287
 
    gtk_tree_store_remove (store, &iter);
1288
 
 
1289
 
 
1290
 
    /* Prepends */
1291
 
  gtk_tree_store_prepend (store, &iter, root);
1292
 
    
1293
 
  i = 0;
1294
 
  while (i < 100)
1295
 
    {
1296
 
      gtk_tree_store_prepend (store, &iter, root);
1297
 
      ++i;
1298
 
    }
1299
 
 
1300
 
  /* remove everything again */
1301
 
  while (gtk_tree_model_iter_children (model, &iter, root))
1302
 
    gtk_tree_store_remove (store, &iter);
1303
 
 
1304
 
  gtk_tree_store_append (store, &iter, root);
1305
 
  gtk_tree_store_append (store, &iter, root);
1306
 
  gtk_tree_store_append (store, &iter, root);
1307
 
  gtk_tree_store_append (store, &iter, root);
1308
 
 
1309
 
  while (gtk_tree_model_iter_children (model, &iter, root))
1310
 
    {
1311
 
      treestore_torture_recurse (store, &iter, depth);
1312
 
      gtk_tree_store_remove (store, &iter);
1313
 
    }
1314
 
}
1315
 
 
1316
 
#endif
1317
 
 
1318
 
static void
1319
 
run_automated_tests (void)
1320
 
{
1321
 
  g_print ("Running automated tests...\n");
1322
 
  
1323
 
  /* FIXME TreePath basic verification */
1324
 
 
1325
 
  /* FIXME generic consistency checks on the models */
1326
 
 
1327
 
  {
1328
 
    /* Make sure list store mutations don't crash anything */
1329
 
    GtkListStore *store;
1330
 
    GtkTreeModel *model;
1331
 
    gint i;
1332
 
    GtkTreeIter iter;
1333
 
    
1334
 
    store = gtk_list_store_new (1, G_TYPE_INT);
1335
 
 
1336
 
    model = GTK_TREE_MODEL (store);
1337
 
    
1338
 
    i = 0;
1339
 
    while (i < 100)
1340
 
      {
1341
 
        gtk_list_store_append (store, &iter);
1342
 
        ++i;
1343
 
      }
1344
 
 
1345
 
    while (gtk_tree_model_get_iter_first (model, &iter))
1346
 
      gtk_list_store_remove (store, &iter);
1347
 
 
1348
 
    gtk_list_store_append (store, &iter);
1349
 
 
1350
 
    /* inserts before last node in list */
1351
 
    i = 0;
1352
 
    while (i < 100)
1353
 
      {
1354
 
        gtk_list_store_insert_before (store, &iter, &iter);
1355
 
        ++i;
1356
 
      }
1357
 
 
1358
 
    /* inserts after the node before the last node */
1359
 
    i = 0;
1360
 
    while (i < 100)
1361
 
      {
1362
 
        gtk_list_store_insert_after (store, &iter, &iter);
1363
 
        ++i;
1364
 
      }
1365
 
 
1366
 
    /* inserts after the last node */
1367
 
    gtk_list_store_append (store, &iter);
1368
 
    
1369
 
    i = 0;
1370
 
    while (i < 100)
1371
 
      {
1372
 
        gtk_list_store_insert_after (store, &iter, &iter);
1373
 
        ++i;
1374
 
      }
1375
 
 
1376
 
    /* remove everything again */
1377
 
    while (gtk_tree_model_get_iter_first (model, &iter))
1378
 
      gtk_list_store_remove (store, &iter);
1379
 
 
1380
 
 
1381
 
    /* Prepends */
1382
 
    gtk_list_store_prepend (store, &iter);
1383
 
    
1384
 
    i = 0;
1385
 
    while (i < 100)
1386
 
      {
1387
 
        gtk_list_store_prepend (store, &iter);
1388
 
        ++i;
1389
 
      }
1390
 
 
1391
 
    /* remove everything again */
1392
 
    while (gtk_tree_model_get_iter_first (model, &iter))
1393
 
      gtk_list_store_remove (store, &iter);
1394
 
    
1395
 
    g_object_unref (store);
1396
 
  }
1397
 
 
1398
 
  {
1399
 
    /* Make sure tree store mutations don't crash anything */
1400
 
    GtkTreeStore *store;
1401
 
    GtkTreeIter root;
1402
 
 
1403
 
    store = gtk_tree_store_new (1, G_TYPE_INT);
1404
 
    gtk_tree_store_append (GTK_TREE_STORE (store), &root, NULL);
1405
 
    /* Remove test until it is rewritten to work */
1406
 
    /*    treestore_torture_recurse (store, &root, 0);*/
1407
 
    
1408
 
    g_object_unref (store);
1409
 
  }
1410
 
 
1411
 
  g_print ("Passed.\n");
1412
 
}