2 * Copyright (C) 2001 Red Hat, Inc
3 * Author: Jonathan Blandford
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.
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.
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.
21 #undef GTK_DISABLE_DEPRECATED
23 #include "prop-editor.h"
27 /* Don't copy this bad example; inline RGB data is always a better
28 * idea than inline XPMs.
30 static char *book_closed_xpm
[] = {
56 static void run_automated_tests (void);
58 /* This custom model is to test custom model use. */
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))
66 typedef struct _GtkTreeModelTypes GtkTreeModelTypes
;
67 typedef struct _GtkTreeModelTypesClass GtkTreeModelTypesClass
;
69 struct _GtkTreeModelTypes
76 struct _GtkTreeModelTypesClass
78 GObjectClass parent_class
;
80 guint (* get_flags
) (GtkTreeModel
*tree_model
);
81 gint (* get_n_columns
) (GtkTreeModel
*tree_model
);
82 GType (* get_column_type
) (GtkTreeModel
*tree_model
,
84 gboolean (* get_iter
) (GtkTreeModel
*tree_model
,
87 GtkTreePath
*(* get_path
) (GtkTreeModel
*tree_model
,
89 void (* get_value
) (GtkTreeModel
*tree_model
,
93 gboolean (* iter_next
) (GtkTreeModel
*tree_model
,
95 gboolean (* iter_children
) (GtkTreeModel
*tree_model
,
98 gboolean (* iter_has_child
) (GtkTreeModel
*tree_model
,
100 gint (* iter_n_children
) (GtkTreeModel
*tree_model
,
102 gboolean (* iter_nth_child
) (GtkTreeModel
*tree_model
,
106 gboolean (* iter_parent
) (GtkTreeModel
*tree_model
,
109 void (* ref_iter
) (GtkTreeModel
*tree_model
,
111 void (* unref_iter
) (GtkTreeModel
*tree_model
,
114 /* These will be moved into the GtkTreeModelIface eventually */
115 void (* changed
) (GtkTreeModel
*tree_model
,
118 void (* inserted
) (GtkTreeModel
*tree_model
,
121 void (* child_toggled
) (GtkTreeModel
*tree_model
,
124 void (* deleted
) (GtkTreeModel
*tree_model
,
128 GType
gtk_tree_model_types_get_type (void) G_GNUC_CONST
;
129 GtkTreeModelTypes
*gtk_tree_model_types_new (void);
139 static gchar
*column_type_names
[] = {
148 get_model_types (void)
150 static GType column_types
[N_COLUMNS
] = { 0 };
152 if (column_types
[0] == 0)
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
;
170 col_clicked_cb (GtkTreeViewColumn
*col
, gpointer data
)
174 win
= GTK_WINDOW (create_prop_editor (G_OBJECT (col
), GTK_TYPE_TREE_VIEW_COLUMN
));
176 gtk_window_set_title (win
, gtk_tree_view_column_get_title (col
));
180 setup_column (GtkTreeViewColumn
*col
)
182 gtk_tree_view_column_set_clickable (col
, TRUE
);
183 g_signal_connect (col
,
185 G_CALLBACK (col_clicked_cb
),
190 toggled_callback (GtkCellRendererToggle
*celltoggle
,
192 GtkTreeView
*tree_view
)
194 GtkTreeModel
*model
= NULL
;
195 GtkTreeModelSort
*sort_model
= NULL
;
198 gboolean active
= FALSE
;
200 g_return_if_fail (GTK_IS_TREE_VIEW (tree_view
));
202 model
= gtk_tree_view_get_model (tree_view
);
204 if (GTK_IS_TREE_MODEL_SORT (model
))
206 sort_model
= GTK_TREE_MODEL_SORT (model
);
207 model
= gtk_tree_model_sort_get_model (sort_model
);
215 g_warning ("FIXME implement conversion from TreeModelSort iter to child model iter");
219 path
= gtk_tree_path_new_from_string (path_string
);
220 if (!gtk_tree_model_get_iter (model
,
223 g_warning ("%s: bad path?", G_STRLOC
);
226 gtk_tree_path_free (path
);
228 if (GTK_IS_LIST_STORE (model
))
230 gtk_tree_model_get (GTK_TREE_MODEL (model
),
236 gtk_list_store_set (GTK_LIST_STORE (model
),
242 else if (GTK_IS_TREE_STORE (model
))
244 gtk_tree_model_get (GTK_TREE_MODEL (model
),
250 gtk_tree_store_set (GTK_TREE_STORE (model
),
257 g_warning ("don't know how to actually toggle value for model type %s",
258 g_type_name (G_TYPE_FROM_INSTANCE (model
)));
262 edited_callback (GtkCellRendererText
*renderer
,
263 const gchar
*path_string
,
264 const gchar
*new_text
,
265 GtkTreeView
*tree_view
)
267 GtkTreeModel
*model
= NULL
;
268 GtkTreeModelSort
*sort_model
= NULL
;
271 guint value
= atoi (new_text
);
273 g_return_if_fail (GTK_IS_TREE_VIEW (tree_view
));
275 model
= gtk_tree_view_get_model (tree_view
);
277 if (GTK_IS_TREE_MODEL_SORT (model
))
279 sort_model
= GTK_TREE_MODEL_SORT (model
);
280 model
= gtk_tree_model_sort_get_model (sort_model
);
288 g_warning ("FIXME implement conversion from TreeModelSort iter to child model iter");
292 path
= gtk_tree_path_new_from_string (path_string
);
293 if (!gtk_tree_model_get_iter (model
,
296 g_warning ("%s: bad path?", G_STRLOC
);
299 gtk_tree_path_free (path
);
301 if (GTK_IS_LIST_STORE (model
))
303 gtk_list_store_set (GTK_LIST_STORE (model
),
309 else if (GTK_IS_TREE_STORE (model
))
311 gtk_tree_store_set (GTK_TREE_STORE (model
),
318 g_warning ("don't know how to actually toggle value for model type %s",
319 g_type_name (G_TYPE_FROM_INSTANCE (model
)));
322 static ColumnsType current_column_type
= COLUMNS_LOTS
;
325 set_columns_type (GtkTreeView
*tree_view
, ColumnsType type
)
327 GtkTreeViewColumn
*col
;
328 GtkCellRenderer
*rend
;
331 GtkObject
*adjustment
;
333 current_column_type
= type
;
335 col
= gtk_tree_view_get_column (tree_view
, 0);
338 gtk_tree_view_remove_column (tree_view
, col
);
340 col
= gtk_tree_view_get_column (tree_view
, 0);
343 gtk_tree_view_set_rules_hint (tree_view
, FALSE
);
351 /* with lots of columns we need to turn on rules */
352 gtk_tree_view_set_rules_hint (tree_view
, TRUE
);
354 rend
= gtk_cell_renderer_text_new ();
356 col
= gtk_tree_view_column_new_with_attributes ("Column 1",
362 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view
), col
);
364 col
= gtk_tree_view_column_new();
365 gtk_tree_view_column_set_title (col
, "Column 2");
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);
377 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view
), col
);
378 gtk_tree_view_set_expander_column (tree_view
, col
);
380 rend
= gtk_cell_renderer_toggle_new ();
382 g_signal_connect (rend
, "toggled",
383 G_CALLBACK (toggled_callback
), tree_view
);
385 col
= gtk_tree_view_column_new_with_attributes ("Column 3",
387 "active", BOOL_COLUMN
,
392 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view
), col
);
394 pixbuf
= gdk_pixbuf_new_from_xpm_data ((const char **)book_closed_xpm
);
396 image
= gtk_image_new_from_pixbuf (pixbuf
);
398 g_object_unref (pixbuf
);
400 gtk_widget_show (image
);
402 gtk_tree_view_column_set_widget (col
, image
);
404 rend
= gtk_cell_renderer_toggle_new ();
406 /* you could also set this per-row by tying it to a column
407 * in the model of course.
409 g_object_set (rend
, "radio", TRUE
, NULL
);
411 g_signal_connect (rend
, "toggled",
412 G_CALLBACK (toggled_callback
), tree_view
);
414 col
= gtk_tree_view_column_new_with_attributes ("Column 4",
416 "active", BOOL_COLUMN
,
421 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view
), col
);
423 rend
= gtk_cell_renderer_spin_new ();
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
);
429 g_signal_connect (rend
, "edited",
430 G_CALLBACK (edited_callback
), tree_view
);
432 col
= gtk_tree_view_column_new_with_attributes ("Column 5",
439 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view
), col
);
442 rend
= gtk_cell_renderer_text_new ();
444 col
= gtk_tree_view_column_new_with_attributes ("Column 6",
451 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view
), col
);
453 rend
= gtk_cell_renderer_text_new ();
455 col
= gtk_tree_view_column_new_with_attributes ("Column 7",
462 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view
), col
);
464 rend
= gtk_cell_renderer_text_new ();
466 col
= gtk_tree_view_column_new_with_attributes ("Column 8",
473 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view
), col
);
475 rend
= gtk_cell_renderer_text_new ();
477 col
= gtk_tree_view_column_new_with_attributes ("Column 9",
484 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view
), col
);
486 rend
= gtk_cell_renderer_text_new ();
488 col
= gtk_tree_view_column_new_with_attributes ("Column 10",
495 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view
), col
);
502 rend
= gtk_cell_renderer_text_new ();
504 col
= gtk_tree_view_column_new_with_attributes ("Column 0",
511 gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view
), col
, 0);
518 get_columns_type (void)
520 return current_column_type
;
523 static GdkPixbuf
*our_pixbuf
;
538 /* FIXME add a custom model to test */
539 static GtkTreeModel
*models
[MODEL_LAST
];
540 static const char *model_names
[MODEL_LAST
] = {
543 "GtkTreeModelSort wrapping GtkTreeStore",
544 "GtkTreeModelSort wrapping GtkListStore",
545 "Empty GtkListStore",
546 "Empty GtkTreeStore",
551 create_list_model (void)
558 t
= get_model_types ();
560 store
= gtk_list_store_new (N_COLUMNS
,
570 gtk_list_store_append (store
, &iter
);
572 msg
= g_strdup_printf ("%d", i
);
574 gtk_list_store_set (store
, &iter
, 0, msg
, 1, "Foo! Foo! Foo!",
576 3, 7.0, 4, (guint
) 9000,
578 7, TRUE
, 8, 23245454,
586 return GTK_TREE_MODEL (store
);
590 typesystem_recurse (GType type
,
591 GtkTreeIter
*parent_iter
,
595 guint n_children
= 0;
600 gtk_tree_store_append (store
, &iter
, parent_iter
);
602 str
= g_strdup_printf ("%ld", (glong
)type
);
603 gtk_tree_store_set (store
, &iter
, 0, str
, 1, g_type_name (type
),
605 3, 7.0, 4, (guint
) 9000,
607 7, TRUE
, 8, 23245454,
611 children
= g_type_children (type
, &n_children
);
614 while (i
< n_children
)
616 typesystem_recurse (children
[i
], &iter
, store
);
625 create_tree_model (void)
630 volatile GType dummy
; /* G_GNUC_CONST makes the optimizer remove
631 * get_type calls if you don't do something
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 ();
642 t
= get_model_types ();
644 store
= gtk_tree_store_new (N_COLUMNS
,
650 while (i
< G_TYPE_FUNDAMENTAL_MAX
)
652 typesystem_recurse (i
, NULL
, store
);
657 return GTK_TREE_MODEL (store
);
661 model_selected (GtkOptionMenu
*om
, gpointer data
)
663 GtkTreeView
*tree_view
= GTK_TREE_VIEW (data
);
666 hist
= gtk_option_menu_get_history (om
);
668 if (models
[hist
] != gtk_tree_view_get_model (tree_view
))
670 gtk_tree_view_set_model (tree_view
, models
[hist
]);
675 columns_selected (GtkOptionMenu
*om
, gpointer data
)
677 GtkTreeView
*tree_view
= GTK_TREE_VIEW (data
);
680 hist
= gtk_option_menu_get_history (om
);
682 if (hist
!= get_columns_type ())
684 set_columns_type (tree_view
, hist
);
691 TARGET_GTK_TREE_MODEL_ROW
694 static GtkTargetEntry row_targets
[] = {
695 { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_APP
,
696 TARGET_GTK_TREE_MODEL_ROW
}
712 gtk_init (&argc
, &argv
);
714 our_pixbuf
= gdk_pixbuf_new_from_xpm_data ((const char **) book_closed_xpm
);
717 models
[MODEL_TYPES
] = GTK_TREE_MODEL (gtk_tree_model_types_new ());
719 models
[MODEL_LIST
] = create_list_model ();
720 models
[MODEL_TREE
] = create_tree_model ();
722 model
= create_list_model ();
723 models
[MODEL_SORTED_LIST
] = gtk_tree_model_sort_new_with_model (model
);
724 g_object_unref (model
);
726 model
= create_tree_model ();
727 models
[MODEL_SORTED_TREE
] = gtk_tree_model_sort_new_with_model (model
);
728 g_object_unref (model
);
730 models
[MODEL_EMPTY_LIST
] = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_INT
));
731 models
[MODEL_EMPTY_TREE
] = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT
));
733 models
[MODEL_NULL
] = NULL
;
735 run_automated_tests ();
737 window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
738 g_signal_connect (window
, "destroy", G_CALLBACK (gtk_main_quit
), NULL
);
739 gtk_window_set_default_size (GTK_WINDOW (window
), 430, 400);
741 table
= gtk_table_new (3, 1, FALSE
);
743 gtk_container_add (GTK_CONTAINER (window
), table
);
745 tv
= gtk_tree_view_new_with_model (models
[0]);
747 gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (tv
),
750 G_N_ELEMENTS (row_targets
),
751 GDK_ACTION_MOVE
| GDK_ACTION_COPY
);
753 gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (tv
),
755 G_N_ELEMENTS (row_targets
),
756 GDK_ACTION_MOVE
| GDK_ACTION_COPY
);
760 menu
= gtk_menu_new ();
763 while (i
< MODEL_LAST
)
768 name
= model_names
[i
];
770 mi
= gtk_menu_item_new_with_label (name
);
772 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), mi
);
775 window
= create_prop_editor (G_OBJECT (models
[i
]));
777 gtk_window_set_title (GTK_WINDOW (window
),
783 gtk_widget_show_all (menu
);
785 om
= gtk_option_menu_new ();
786 gtk_option_menu_set_menu (GTK_OPTION_MENU (om
), menu
);
788 gtk_table_attach (GTK_TABLE (table
), om
,
793 g_signal_connect (om
,
795 G_CALLBACK (model_selected
),
800 menu
= gtk_menu_new ();
803 while (i
< COLUMNS_LAST
)
808 name
= column_type_names
[i
];
810 mi
= gtk_menu_item_new_with_label (name
);
812 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), mi
);
816 gtk_widget_show_all (menu
);
818 om
= gtk_option_menu_new ();
819 gtk_option_menu_set_menu (GTK_OPTION_MENU (om
), menu
);
821 gtk_table_attach (GTK_TABLE (table
), om
,
826 set_columns_type (GTK_TREE_VIEW (tv
), COLUMNS_LOTS
);
827 gtk_option_menu_set_history (GTK_OPTION_MENU (om
), COLUMNS_LOTS
);
829 g_signal_connect (om
,
831 G_CALLBACK (columns_selected
),
834 sw
= gtk_scrolled_window_new (NULL
, NULL
);
835 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw
),
836 GTK_POLICY_AUTOMATIC
,
837 GTK_POLICY_AUTOMATIC
);
839 gtk_table_attach (GTK_TABLE (table
), sw
,
841 GTK_EXPAND
| GTK_FILL
,
842 GTK_EXPAND
| GTK_FILL
,
845 gtk_container_add (GTK_CONTAINER (sw
), tv
);
847 gtk_widget_show_all (window
);
858 static void gtk_tree_model_types_init (GtkTreeModelTypes
*model_types
);
859 static void gtk_tree_model_types_tree_model_init (GtkTreeModelIface
*iface
);
860 static gint
gtk_real_model_types_get_n_columns (GtkTreeModel
*tree_model
);
861 static GType
gtk_real_model_types_get_column_type (GtkTreeModel
*tree_model
,
863 static GtkTreePath
*gtk_real_model_types_get_path (GtkTreeModel
*tree_model
,
865 static void gtk_real_model_types_get_value (GtkTreeModel
*tree_model
,
869 static gboolean
gtk_real_model_types_iter_next (GtkTreeModel
*tree_model
,
871 static gboolean
gtk_real_model_types_iter_children (GtkTreeModel
*tree_model
,
873 GtkTreeIter
*parent
);
874 static gboolean
gtk_real_model_types_iter_has_child (GtkTreeModel
*tree_model
,
876 static gint
gtk_real_model_types_iter_n_children (GtkTreeModel
*tree_model
,
878 static gboolean
gtk_real_model_types_iter_nth_child (GtkTreeModel
*tree_model
,
882 static gboolean
gtk_real_model_types_iter_parent (GtkTreeModel
*tree_model
,
888 gtk_tree_model_types_get_type (void)
890 static GType model_types_type
= 0;
892 if (!model_types_type
)
894 static const GTypeInfo model_types_info
=
896 sizeof (GtkTreeModelTypesClass
),
897 NULL
, /* base_init */
898 NULL
, /* base_finalize */
899 NULL
, /* class_init */
900 NULL
, /* class_finalize */
901 NULL
, /* class_data */
902 sizeof (GtkTreeModelTypes
),
904 (GInstanceInitFunc
) gtk_tree_model_types_init
907 static const GInterfaceInfo tree_model_info
=
909 (GInterfaceInitFunc
) gtk_tree_model_types_tree_model_init
,
914 model_types_type
= g_type_register_static (G_TYPE_OBJECT
,
916 &model_types_info
, 0);
917 g_type_add_interface_static (model_types_type
,
922 return model_types_type
;
926 gtk_tree_model_types_new (void)
928 GtkTreeModelTypes
*retval
;
930 retval
= g_object_new (GTK_TYPE_MODEL_TYPES
, NULL
);
936 gtk_tree_model_types_tree_model_init (GtkTreeModelIface
*iface
)
938 iface
->get_n_columns
= gtk_real_model_types_get_n_columns
;
939 iface
->get_column_type
= gtk_real_model_types_get_column_type
;
940 iface
->get_path
= gtk_real_model_types_get_path
;
941 iface
->get_value
= gtk_real_model_types_get_value
;
942 iface
->iter_next
= gtk_real_model_types_iter_next
;
943 iface
->iter_children
= gtk_real_model_types_iter_children
;
944 iface
->iter_has_child
= gtk_real_model_types_iter_has_child
;
945 iface
->iter_n_children
= gtk_real_model_types_iter_n_children
;
946 iface
->iter_nth_child
= gtk_real_model_types_iter_nth_child
;
947 iface
->iter_parent
= gtk_real_model_types_iter_parent
;
951 gtk_tree_model_types_init (GtkTreeModelTypes
*model_types
)
953 model_types
->stamp
= g_random_int ();
956 static GType column_types
[] = {
957 G_TYPE_STRING
, /* GType */
958 G_TYPE_STRING
/* type name */
962 gtk_real_model_types_get_n_columns (GtkTreeModel
*tree_model
)
964 return G_N_ELEMENTS (column_types
);
968 gtk_real_model_types_get_column_type (GtkTreeModel
*tree_model
,
971 g_return_val_if_fail (index
< G_N_ELEMENTS (column_types
), G_TYPE_INVALID
);
973 return column_types
[index
];
977 /* Use default implementation of this */
979 gtk_real_model_types_get_iter (GtkTreeModel
*tree_model
,
987 /* The toplevel nodes of the tree are the reserved types, G_TYPE_NONE through
988 * G_TYPE_RESERVED_FUNDAMENTAL.
992 gtk_real_model_types_get_path (GtkTreeModel
*tree_model
,
999 g_return_val_if_fail (GTK_IS_TREE_MODEL_TYPES (tree_model
), NULL
);
1000 g_return_val_if_fail (iter
!= NULL
, NULL
);
1002 type
= GPOINTER_TO_INT (iter
->user_data
);
1004 retval
= gtk_tree_path_new ();
1006 parent
= g_type_parent (type
);
1007 while (parent
!= G_TYPE_INVALID
)
1009 GType
* children
= g_type_children (parent
, NULL
);
1012 if (!children
|| children
[0] == G_TYPE_INVALID
)
1014 g_warning ("bad iterator?");
1018 while (children
[i
] != type
)
1021 gtk_tree_path_prepend_index (retval
, i
);
1026 parent
= g_type_parent (parent
);
1029 /* The fundamental type itself is the index on the toplevel */
1030 gtk_tree_path_prepend_index (retval
, type
);
1036 gtk_real_model_types_get_value (GtkTreeModel
*tree_model
,
1043 type
= GPOINTER_TO_INT (iter
->user_data
);
1051 g_value_init (value
, G_TYPE_STRING
);
1053 str
= g_strdup_printf ("%ld", (long int) type
);
1054 g_value_set_string (value
, str
);
1060 g_value_init (value
, G_TYPE_STRING
);
1061 g_value_set_string (value
, g_type_name (type
));
1065 g_warning ("Bad column %d requested", column
);
1070 gtk_real_model_types_iter_next (GtkTreeModel
*tree_model
,
1077 type
= GPOINTER_TO_INT (iter
->user_data
);
1079 parent
= g_type_parent (type
);
1081 if (parent
== G_TYPE_INVALID
)
1083 /* find next _valid_ fundamental type */
1086 while (!g_type_name (type
) && type
<= G_TYPE_FUNDAMENTAL_MAX
);
1087 if (type
<= G_TYPE_FUNDAMENTAL_MAX
)
1090 iter
->user_data
= GINT_TO_POINTER (type
);
1098 GType
* children
= g_type_children (parent
, NULL
);
1101 g_assert (children
!= NULL
);
1103 while (children
[i
] != type
)
1108 if (children
[i
] != G_TYPE_INVALID
)
1111 iter
->user_data
= GINT_TO_POINTER (children
[i
]);
1123 gtk_real_model_types_iter_children (GtkTreeModel
*tree_model
,
1125 GtkTreeIter
*parent
)
1130 type
= GPOINTER_TO_INT (parent
->user_data
);
1132 children
= g_type_children (type
, NULL
);
1134 if (!children
|| children
[0] == G_TYPE_INVALID
)
1141 iter
->user_data
= GINT_TO_POINTER (children
[0]);
1148 gtk_real_model_types_iter_has_child (GtkTreeModel
*tree_model
,
1154 type
= GPOINTER_TO_INT (iter
->user_data
);
1156 children
= g_type_children (type
, NULL
);
1158 if (!children
|| children
[0] == G_TYPE_INVALID
)
1171 gtk_real_model_types_iter_n_children (GtkTreeModel
*tree_model
,
1176 return G_TYPE_FUNDAMENTAL_MAX
;
1182 guint n_children
= 0;
1184 type
= GPOINTER_TO_INT (iter
->user_data
);
1186 children
= g_type_children (type
, &n_children
);
1195 gtk_real_model_types_iter_nth_child (GtkTreeModel
*tree_model
,
1197 GtkTreeIter
*parent
,
1202 /* fundamental type */
1203 if (n
< G_TYPE_FUNDAMENTAL_MAX
)
1205 iter
->user_data
= GINT_TO_POINTER (n
);
1213 GType type
= GPOINTER_TO_INT (parent
->user_data
);
1214 guint n_children
= 0;
1215 GType
* children
= g_type_children (type
, &n_children
);
1217 if (n_children
== 0)
1222 else if (n
>= n_children
)
1229 iter
->user_data
= GINT_TO_POINTER (children
[n
]);
1238 gtk_real_model_types_iter_parent (GtkTreeModel
*tree_model
,
1245 type
= GPOINTER_TO_INT (child
->user_data
);
1247 parent
= g_type_parent (type
);
1249 if (parent
== G_TYPE_INVALID
)
1251 if (type
> G_TYPE_FUNDAMENTAL_MAX
)
1252 g_warning ("no parent for %ld %s\n",
1254 g_type_name (type
));
1259 iter
->user_data
= GINT_TO_POINTER (parent
);
1270 treestore_torture_recurse (GtkTreeStore
*store
,
1274 GtkTreeModel
*model
;
1278 model
= GTK_TREE_MODEL (store
);
1285 gtk_tree_store_append (store
, &iter
, root
);
1287 gtk_tree_model_iter_children (model
, &iter
, root
);
1292 gtk_tree_store_append (store
, &iter
, root
);
1296 while (gtk_tree_model_iter_children (model
, &iter
, root
))
1297 gtk_tree_store_remove (store
, &iter
);
1299 gtk_tree_store_append (store
, &iter
, root
);
1301 /* inserts before last node in tree */
1305 gtk_tree_store_insert_before (store
, &iter
, root
, &iter
);
1309 /* inserts after the node before the last node */
1313 gtk_tree_store_insert_after (store
, &iter
, root
, &iter
);
1317 /* inserts after the last node */
1318 gtk_tree_store_append (store
, &iter
, root
);
1323 gtk_tree_store_insert_after (store
, &iter
, root
, &iter
);
1327 /* remove everything again */
1328 while (gtk_tree_model_iter_children (model
, &iter
, root
))
1329 gtk_tree_store_remove (store
, &iter
);
1333 gtk_tree_store_prepend (store
, &iter
, root
);
1338 gtk_tree_store_prepend (store
, &iter
, root
);
1342 /* remove everything again */
1343 while (gtk_tree_model_iter_children (model
, &iter
, root
))
1344 gtk_tree_store_remove (store
, &iter
);
1346 gtk_tree_store_append (store
, &iter
, root
);
1347 gtk_tree_store_append (store
, &iter
, root
);
1348 gtk_tree_store_append (store
, &iter
, root
);
1349 gtk_tree_store_append (store
, &iter
, root
);
1351 while (gtk_tree_model_iter_children (model
, &iter
, root
))
1353 treestore_torture_recurse (store
, &iter
, depth
);
1354 gtk_tree_store_remove (store
, &iter
);
1359 run_automated_tests (void)
1361 g_print ("Running automated tests...\n");
1363 /* FIXME TreePath basic verification */
1365 /* FIXME generic consistency checks on the models */
1368 /* Make sure list store mutations don't crash anything */
1369 GtkListStore
*store
;
1370 GtkTreeModel
*model
;
1374 store
= gtk_list_store_new (1, G_TYPE_INT
);
1376 model
= GTK_TREE_MODEL (store
);
1381 gtk_list_store_append (store
, &iter
);
1385 while (gtk_tree_model_get_iter_first (model
, &iter
))
1386 gtk_list_store_remove (store
, &iter
);
1388 gtk_list_store_append (store
, &iter
);
1390 /* inserts before last node in list */
1394 gtk_list_store_insert_before (store
, &iter
, &iter
);
1398 /* inserts after the node before the last node */
1402 gtk_list_store_insert_after (store
, &iter
, &iter
);
1406 /* inserts after the last node */
1407 gtk_list_store_append (store
, &iter
);
1412 gtk_list_store_insert_after (store
, &iter
, &iter
);
1416 /* remove everything again */
1417 while (gtk_tree_model_get_iter_first (model
, &iter
))
1418 gtk_list_store_remove (store
, &iter
);
1422 gtk_list_store_prepend (store
, &iter
);
1427 gtk_list_store_prepend (store
, &iter
);
1431 /* remove everything again */
1432 while (gtk_tree_model_get_iter_first (model
, &iter
))
1433 gtk_list_store_remove (store
, &iter
);
1435 g_object_unref (store
);
1439 /* Make sure tree store mutations don't crash anything */
1440 GtkTreeStore
*store
;
1443 store
= gtk_tree_store_new (1, G_TYPE_INT
);
1444 gtk_tree_store_append (GTK_TREE_STORE (store
), &root
, NULL
);
1445 /* Remove test until it is rewritten to work */
1446 /* treestore_torture_recurse (store, &root, 0);*/
1448 g_object_unref (store
);
1451 g_print ("Passed.\n");