]> Pileus Git - ~andy/gtk/blob - gtk/tests/builder.c
Merge branch 'button-box-orientable-584598'
[~andy/gtk] / gtk / tests / builder.c
1 /* buildertest.c
2  * Copyright (C) 2006-2007 Async Open Source
3  * Authors: Johan Dahlin
4  *          Henrique Romano
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <string.h>
23 #include <libintl.h>
24 #include <locale.h>
25 #include <math.h>
26
27 #include <gtk/gtk.h>
28 #include <gdk/gdkkeysyms.h>
29
30 /* Copied from gtkiconfactory.c; keep in sync! */
31 struct _GtkIconSet
32 {
33   guint ref_count;
34   GSList *sources;
35   GSList *cache;
36   guint cache_size;
37   guint cache_serial;
38 };
39
40
41 static GtkBuilder *
42 builder_new_from_string (const gchar *buffer,
43                          gsize length,
44                          const gchar *domain)
45 {
46   GtkBuilder *builder;
47   GError *error = NULL;
48
49   builder = gtk_builder_new ();
50   if (domain)
51     gtk_builder_set_translation_domain (builder, domain);
52   gtk_builder_add_from_string (builder, buffer, length, &error);
53   if (error)
54     {
55       g_print ("ERROR: %s", error->message);
56       g_error_free (error);
57     }
58
59   return builder;
60 }
61
62 static void
63 test_parser (void)
64 {
65   GtkBuilder *builder;
66   GError *error;
67   
68   builder = gtk_builder_new ();
69
70   error = NULL;
71   gtk_builder_add_from_string (builder, "<xxx/>", -1, &error);
72   g_assert (g_error_matches (error, 
73                              GTK_BUILDER_ERROR,
74                              GTK_BUILDER_ERROR_UNHANDLED_TAG));
75   g_error_free (error);
76   
77   error = NULL;
78   gtk_builder_add_from_string (builder, "<interface invalid=\"X\"/>", -1, &error);
79   g_assert (g_error_matches (error,
80                              GTK_BUILDER_ERROR,
81                              GTK_BUILDER_ERROR_INVALID_ATTRIBUTE));
82   g_error_free (error);
83
84   error = NULL;
85   gtk_builder_add_from_string (builder, "<interface><child/></interface>", -1, &error);
86   g_assert (g_error_matches (error,
87                              GTK_BUILDER_ERROR, 
88                              GTK_BUILDER_ERROR_INVALID_TAG));
89   g_error_free (error);
90
91   error = NULL;
92   gtk_builder_add_from_string (builder, "<interface><object class=\"GtkVBox\" id=\"a\"><object class=\"GtkHBox\" id=\"b\"/></object></interface>", -1, &error);
93   g_assert (g_error_matches (error,
94                              GTK_BUILDER_ERROR,
95                              GTK_BUILDER_ERROR_INVALID_TAG));
96   g_error_free (error);
97
98   error = NULL;
99   gtk_builder_add_from_string (builder, "<interface><object class=\"Unknown\" id=\"a\"></object></interface>", -1, &error);
100   g_assert (g_error_matches (error,
101                              GTK_BUILDER_ERROR,
102                              GTK_BUILDER_ERROR_INVALID_VALUE));
103   g_error_free (error);
104
105   error = NULL;
106   gtk_builder_add_from_string (builder, "<interface><object class=\"GtkWidget\" id=\"a\" constructor=\"none\"></object></interface>", -1, &error);
107   g_assert (g_error_matches (error,
108                              GTK_BUILDER_ERROR,
109                              GTK_BUILDER_ERROR_INVALID_VALUE));
110   g_error_free (error);
111
112   error = NULL;
113   gtk_builder_add_from_string (builder, "<interface><object class=\"GtkButton\" id=\"a\"><child internal-child=\"foobar\"><object class=\"GtkButton\" id=\"int\"/></child></object></interface>", -1, &error);
114   g_assert (g_error_matches (error,
115                              GTK_BUILDER_ERROR,
116                              GTK_BUILDER_ERROR_INVALID_VALUE));
117   g_error_free (error);
118
119   g_object_unref (builder);
120 }
121
122 static int normal = 0;
123 static int after = 0;
124 static int object = 0;
125 static int object_after = 0;
126
127 void /* exported for GtkBuilder */
128 signal_normal (GtkWindow *window, GParamSpec spec)
129 {
130   g_assert (GTK_IS_WINDOW (window));
131   g_assert (normal == 0);
132   g_assert (after == 0);
133
134   normal++;
135 }
136
137 void /* exported for GtkBuilder */
138 signal_after (GtkWindow *window, GParamSpec spec)
139 {
140   g_assert (GTK_IS_WINDOW (window));
141   g_assert (normal == 1);
142   g_assert (after == 0);
143   
144   after++;
145 }
146
147 void /* exported for GtkBuilder */
148 signal_object (GtkButton *button, GParamSpec spec)
149 {
150   g_assert (GTK_IS_BUTTON (button));
151   g_assert (object == 0);
152   g_assert (object_after == 0);
153
154   object++;
155 }
156
157 void /* exported for GtkBuilder */
158 signal_object_after (GtkButton *button, GParamSpec spec)
159 {
160   g_assert (GTK_IS_BUTTON (button));
161   g_assert (object == 1);
162   g_assert (object_after == 0);
163
164   object_after++;
165 }
166
167 void /* exported for GtkBuilder */
168 signal_first (GtkButton *button, GParamSpec spec)
169 {
170   g_assert (normal == 0);
171   normal = 10;
172 }
173
174 void /* exported for GtkBuilder */
175 signal_second (GtkButton *button, GParamSpec spec)
176 {
177   g_assert (normal == 10);
178   normal = 20;
179 }
180
181 void /* exported for GtkBuilder */
182 signal_extra (GtkButton *button, GParamSpec spec)
183 {
184   g_assert (normal == 20);
185   normal = 30;
186 }
187
188 void /* exported for GtkBuilder */
189 signal_extra2 (GtkButton *button, GParamSpec spec)
190 {
191   g_assert (normal == 30);
192   normal = 40;
193 }
194
195 static void
196 test_connect_signals (void)
197 {
198   GtkBuilder *builder;
199   GObject *window;
200   const gchar buffer[] =
201     "<interface>"
202     "  <object class=\"GtkButton\" id=\"button\"/>"
203     "  <object class=\"GtkWindow\" id=\"window1\">"
204     "    <signal name=\"notify::title\" handler=\"signal_normal\"/>"
205     "    <signal name=\"notify::title\" handler=\"signal_after\" after=\"yes\"/>"
206     "    <signal name=\"notify::title\" handler=\"signal_object\""
207     "            object=\"button\"/>"
208     "    <signal name=\"notify::title\" handler=\"signal_object_after\""
209     "            object=\"button\" after=\"yes\"/>"
210     "  </object>"
211     "</interface>";
212   const gchar buffer_order[] =
213     "<interface>"
214     "  <object class=\"GtkWindow\" id=\"window1\">"
215     "    <signal name=\"notify::title\" handler=\"signal_first\"/>"
216     "    <signal name=\"notify::title\" handler=\"signal_second\"/>"
217     "  </object>"
218     "</interface>";
219   const gchar buffer_extra[] =
220     "<interface>"
221     "  <object class=\"GtkWindow\" id=\"window2\">"
222     "    <signal name=\"notify::title\" handler=\"signal_extra\"/>"
223     "  </object>"
224     "</interface>";
225   const gchar buffer_extra2[] =
226     "<interface>"
227     "  <object class=\"GtkWindow\" id=\"window3\">"
228     "    <signal name=\"notify::title\" handler=\"signal_extra2\"/>"
229     "  </object>"
230     "</interface>";
231   const gchar buffer_after_child[] =
232     "<interface>"
233     "  <object class=\"GtkWindow\" id=\"window1\">"
234     "    <child>"
235     "      <object class=\"GtkButton\" id=\"button1\"/>"
236     "    </child>"
237     "    <signal name=\"notify::title\" handler=\"signal_normal\"/>"
238     "  </object>"
239     "</interface>";
240
241   builder = builder_new_from_string (buffer, -1, NULL);
242   gtk_builder_connect_signals (builder, NULL);
243
244   window = gtk_builder_get_object (builder, "window1");
245   gtk_window_set_title (GTK_WINDOW (window), "test");
246
247   g_assert_cmpint (normal, ==, 1);
248   g_assert_cmpint (after, ==, 1);
249   g_assert_cmpint (object, ==, 1);
250   g_assert_cmpint (object_after, ==, 1);
251
252   gtk_widget_destroy (GTK_WIDGET (window));
253   g_object_unref (builder);
254   
255   builder = builder_new_from_string (buffer_order, -1, NULL);
256   gtk_builder_connect_signals (builder, NULL);
257   window = gtk_builder_get_object (builder, "window1");
258   normal = 0;
259   gtk_window_set_title (GTK_WINDOW (window), "test");
260   g_assert (normal == 20);
261
262   gtk_widget_destroy (GTK_WIDGET (window));
263
264   gtk_builder_add_from_string (builder, buffer_extra,
265                                strlen (buffer_extra), NULL);
266   gtk_builder_add_from_string (builder, buffer_extra2,
267                                strlen (buffer_extra2), NULL);
268   gtk_builder_connect_signals (builder, NULL);
269   window = gtk_builder_get_object (builder, "window2");
270   gtk_window_set_title (GTK_WINDOW (window), "test");
271   g_assert (normal == 30);
272
273   gtk_widget_destroy (GTK_WIDGET (window));
274   window = gtk_builder_get_object (builder, "window3");
275   gtk_window_set_title (GTK_WINDOW (window), "test");
276   g_assert (normal == 40);
277   gtk_widget_destroy (GTK_WIDGET (window));
278   
279   g_object_unref (builder);
280
281   /* new test, reset globals */
282   after = 0;
283   normal = 0;
284   
285   builder = builder_new_from_string (buffer_after_child, -1, NULL);
286   window = gtk_builder_get_object (builder, "window1");
287   gtk_builder_connect_signals (builder, NULL);
288   gtk_window_set_title (GTK_WINDOW (window), "test");
289
290   g_assert (normal == 1);
291   gtk_widget_destroy (GTK_WIDGET (window));
292   g_object_unref (builder);
293 }
294
295 static void
296 test_uimanager_simple (void)
297 {
298   GtkBuilder *builder;
299   GObject *window, *uimgr, *menubar;
300   GObject *menu, *label;
301   GList *children;
302   const gchar buffer[] =
303     "<interface>"
304     "  <object class=\"GtkUIManager\" id=\"uimgr1\"/>"
305     "</interface>";
306     
307   const gchar buffer2[] =
308     "<interface>"
309     "  <object class=\"GtkUIManager\" id=\"uimgr1\">"
310     "    <child>"
311     "      <object class=\"GtkActionGroup\" id=\"ag1\">"
312     "        <child>"
313     "          <object class=\"GtkAction\" id=\"file\">"
314     "            <property name=\"label\">_File</property>"
315     "          </object>"
316     "          <accelerator key=\"n\" modifiers=\"GDK_CONTROL_MASK\"/>"
317     "        </child>"
318     "      </object>"
319     "    </child>"
320     "    <ui>"
321     "      <menubar name=\"menubar1\">"
322     "        <menu action=\"file\">"
323     "        </menu>"
324     "      </menubar>"
325     "    </ui>"
326     "  </object>"
327     "  <object class=\"GtkWindow\" id=\"window1\">"
328     "    <child>"
329     "      <object class=\"GtkMenuBar\" id=\"menubar1\" constructor=\"uimgr1\"/>"
330     "    </child>"
331     "  </object>"
332     "</interface>";
333
334   builder = builder_new_from_string (buffer, -1, NULL);
335
336   uimgr = gtk_builder_get_object (builder, "uimgr1");
337   g_assert (GTK_IS_UI_MANAGER (uimgr));
338   g_object_unref (builder);
339   
340   builder = builder_new_from_string (buffer2, -1, NULL);
341
342   menubar = gtk_builder_get_object (builder, "menubar1");
343   g_assert (GTK_IS_MENU_BAR (menubar));
344
345   children = gtk_container_get_children (GTK_CONTAINER (menubar));
346   menu = children->data;
347   g_assert (GTK_IS_MENU_ITEM (menu));
348   g_assert (strcmp (GTK_WIDGET (menu)->name, "file") == 0);
349   g_list_free (children);
350   
351   label = G_OBJECT (GTK_BIN (menu)->child);
352   g_assert (GTK_IS_LABEL (label));
353   g_assert (strcmp (gtk_label_get_text (GTK_LABEL (label)), "File") == 0);
354
355   window = gtk_builder_get_object (builder, "window1");
356   gtk_widget_destroy (GTK_WIDGET (window));
357   g_object_unref (builder);
358 }
359
360 static void
361 test_domain (void)
362 {
363   GtkBuilder *builder;
364   const gchar buffer1[] = "<interface/>";
365   const gchar buffer2[] = "<interface domain=\"domain\"/>";
366   const gchar *domain;
367   
368   builder = builder_new_from_string (buffer1, -1, NULL);
369   domain = gtk_builder_get_translation_domain (builder);
370   g_assert (domain == NULL);
371   g_object_unref (builder);
372   
373   builder = builder_new_from_string (buffer1, -1, "domain-1");
374   domain = gtk_builder_get_translation_domain (builder);
375   g_assert (domain);
376   g_assert (strcmp (domain, "domain-1") == 0);
377   g_object_unref (builder);
378
379   builder = builder_new_from_string (buffer2, -1, NULL);
380   domain = gtk_builder_get_translation_domain (builder);
381   g_assert (domain == NULL);
382   g_object_unref (builder);
383 }
384
385 #if 0
386 static void
387 test_translation (void)
388 {
389   GtkBuilder *builder;
390   const gchar buffer[] =
391     "<interface>"
392     "  <object class=\"GtkWindow\" id=\"window1\">"
393     "    <child>"
394     "      <object class=\"GtkLabel\" id=\"label\">"
395     "        <property name=\"label\" translatable=\"yes\">File</property>"
396     "      </object>"
397     "    </child>"
398     "  </object>"
399     "</interface>";
400   GtkLabel *window, *label;
401
402   setlocale (LC_ALL, "sv_SE");
403   textdomain ("builder");
404   bindtextdomain ("builder", "tests");
405
406   builder = builder_new_from_string (buffer, -1, NULL);
407   label = GTK_LABEL (gtk_builder_get_object (builder, "label"));
408   g_assert (strcmp (gtk_label_get_text (label), "Arkiv") == 0);
409
410   window = gtk_builder_get_object (builder, "window1");
411   gtk_widget_destroy (GTK_WIDGET (window));
412   g_object_unref (builder);
413 }
414 #endif
415
416 static void
417 test_sizegroup (void)
418 {
419   GtkBuilder * builder;
420   const gchar buffer1[] =
421     "<interface domain=\"test\">"
422     "  <object class=\"GtkSizeGroup\" id=\"sizegroup1\">"
423     "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
424     "    <widgets>"
425     "      <widget name=\"radio1\"/>"
426     "      <widget name=\"radio2\"/>"
427     "    </widgets>"
428     "  </object>"
429     "  <object class=\"GtkWindow\" id=\"window1\">"
430     "    <child>"
431     "      <object class=\"GtkVBox\" id=\"vbox1\">"
432     "        <child>"
433     "          <object class=\"GtkRadioButton\" id=\"radio1\"/>"
434     "        </child>"
435     "        <child>"
436     "          <object class=\"GtkRadioButton\" id=\"radio2\"/>"
437     "        </child>"
438     "      </object>"
439     "    </child>"
440     "  </object>"
441     "</interface>";
442   const gchar buffer2[] =
443     "<interface domain=\"test\">"
444     "  <object class=\"GtkSizeGroup\" id=\"sizegroup1\">"
445     "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
446     "    <widgets>"
447     "    </widgets>"
448     "   </object>"
449     "</interface>";
450   const gchar buffer3[] =
451     "<interface domain=\"test\">"
452     "  <object class=\"GtkSizeGroup\" id=\"sizegroup1\">"
453     "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
454     "    <widgets>"
455     "      <widget name=\"radio1\"/>"
456     "      <widget name=\"radio2\"/>"
457     "    </widgets>"
458     "  </object>"
459     "  <object class=\"GtkSizeGroup\" id=\"sizegroup2\">"
460     "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
461     "    <widgets>"
462     "      <widget name=\"radio1\"/>"
463     "      <widget name=\"radio2\"/>"
464     "    </widgets>"
465     "  </object>"
466     "  <object class=\"GtkWindow\" id=\"window1\">"
467     "    <child>"
468     "      <object class=\"GtkVBox\" id=\"vbox1\">"
469     "        <child>"
470     "          <object class=\"GtkRadioButton\" id=\"radio1\"/>"
471     "        </child>"
472     "        <child>"
473     "          <object class=\"GtkRadioButton\" id=\"radio2\"/>"
474     "        </child>"
475     "      </object>"
476     "    </child>"
477     "  </object>"
478     "</interface>";
479   GObject *sizegroup;
480   GSList *widgets;
481
482   builder = builder_new_from_string (buffer1, -1, NULL);
483   sizegroup = gtk_builder_get_object (builder, "sizegroup1");
484   widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
485   g_assert (g_slist_length (widgets) == 2);
486   g_slist_free (widgets);
487   g_object_unref (builder);
488
489   builder = builder_new_from_string (buffer2, -1, NULL);
490   sizegroup = gtk_builder_get_object (builder, "sizegroup1");
491   widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
492   g_assert (g_slist_length (widgets) == 0);
493   g_slist_free (widgets);
494   g_object_unref (builder);
495
496   builder = builder_new_from_string (buffer3, -1, NULL);
497   sizegroup = gtk_builder_get_object (builder, "sizegroup1");
498   widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
499   g_assert (g_slist_length (widgets) == 2);
500   g_slist_free (widgets);
501   sizegroup = gtk_builder_get_object (builder, "sizegroup2");
502   widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
503   g_assert (g_slist_length (widgets) == 2);
504   g_slist_free (widgets);
505
506 #if 0
507   {
508     GObject *window;
509     window = gtk_builder_get_object (builder, "window1");
510     gtk_widget_destroy (GTK_WIDGET (window));
511   }
512 #endif  
513   g_object_unref (builder);
514 }
515
516 static void
517 test_list_store (void)
518 {
519   const gchar buffer1[] =
520     "<interface>"
521     "  <object class=\"GtkListStore\" id=\"liststore1\">"
522     "    <columns>"
523     "      <column type=\"gchararray\"/>"
524     "      <column type=\"guint\"/>"
525     "    </columns>"
526     "  </object>"
527     "</interface>";
528   const char buffer2[] = 
529     "<interface>"
530     "  <object class=\"GtkListStore\" id=\"liststore1\">"
531     "    <columns>"
532     "      <column type=\"gchararray\"/>"
533     "      <column type=\"gchararray\"/>"
534     "      <column type=\"gint\"/>"
535     "    </columns>"
536     "    <data>"
537     "      <row>"
538     "        <col id=\"0\" translatable=\"yes\">John</col>"
539     "        <col id=\"1\" context=\"foo\">Doe</col>"
540     "        <col id=\"2\" comment=\"foobar\">25</col>"
541     "      </row>"
542     "      <row>"
543     "        <col id=\"0\">Johan</col>"
544     "        <col id=\"1\">Dole</col>"
545     "        <col id=\"2\">50</col>"
546     "      </row>"
547     "    </data>"
548     "  </object>"
549     "</interface>";
550   const char buffer3[] = 
551     "<interface>"
552     "  <object class=\"GtkListStore\" id=\"liststore1\">"
553     "    <columns>"
554     "      <column type=\"gchararray\"/>"
555     "      <column type=\"gchararray\"/>"
556     "      <column type=\"gint\"/>"
557     "    </columns>"
558     "    <data>"
559     "      <row>"
560     "        <col id=\"1\" context=\"foo\">Doe</col>"
561     "        <col id=\"0\" translatable=\"yes\">John</col>"
562     "        <col id=\"2\" comment=\"foobar\">25</col>"
563     "      </row>"
564     "      <row>"
565     "        <col id=\"2\">50</col>"
566     "        <col id=\"1\">Dole</col>"
567     "        <col id=\"0\">Johan</col>"
568     "      </row>"
569     "      <row>"
570     "        <col id=\"2\">19</col>"
571     "      </row>"
572     "    </data>"
573     "  </object>"
574     "</interface>";
575   GtkBuilder *builder;
576   GObject *store;
577   GtkTreeIter iter;
578   gchar *surname, *lastname;
579   int age;
580   
581   builder = builder_new_from_string (buffer1, -1, NULL);
582   store = gtk_builder_get_object (builder, "liststore1");
583   g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 2);
584   g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
585   g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_UINT);
586   g_object_unref (builder);
587   
588   builder = builder_new_from_string (buffer2, -1, NULL);
589   store = gtk_builder_get_object (builder, "liststore1");
590   g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 3);
591   g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
592   g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_STRING);
593   g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 2) == G_TYPE_INT);
594   
595   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter) == TRUE);
596   gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
597                       0, &surname,
598                       1, &lastname,
599                       2, &age,
600                       -1);
601   g_assert (surname != NULL);
602   g_assert (strcmp (surname, "John") == 0);
603   g_free (surname);
604   g_assert (lastname != NULL);
605   g_assert (strcmp (lastname, "Doe") == 0);
606   g_free (lastname);
607   g_assert (age == 25);
608   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == TRUE);
609   
610   gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
611                       0, &surname,
612                       1, &lastname,
613                       2, &age,
614                       -1);
615   g_assert (surname != NULL);
616   g_assert (strcmp (surname, "Johan") == 0);
617   g_free (surname);
618   g_assert (lastname != NULL);
619   g_assert (strcmp (lastname, "Dole") == 0);
620   g_free (lastname);
621   g_assert (age == 50);
622   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == FALSE);
623
624   g_object_unref (builder);  
625
626   builder = builder_new_from_string (buffer3, -1, NULL);
627   store = gtk_builder_get_object (builder, "liststore1");
628   g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 3);
629   g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
630   g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_STRING);
631   g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 2) == G_TYPE_INT);
632   
633   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter) == TRUE);
634   gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
635                       0, &surname,
636                       1, &lastname,
637                       2, &age,
638                       -1);
639   g_assert (surname != NULL);
640   g_assert (strcmp (surname, "John") == 0);
641   g_free (surname);
642   g_assert (lastname != NULL);
643   g_assert (strcmp (lastname, "Doe") == 0);
644   g_free (lastname);
645   g_assert (age == 25);
646   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == TRUE);
647   
648   gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
649                       0, &surname,
650                       1, &lastname,
651                       2, &age,
652                       -1);
653   g_assert (surname != NULL);
654   g_assert (strcmp (surname, "Johan") == 0);
655   g_free (surname);
656   g_assert (lastname != NULL);
657   g_assert (strcmp (lastname, "Dole") == 0);
658   g_free (lastname);
659   g_assert (age == 50);
660   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == TRUE);
661   
662   gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
663                       0, &surname,
664                       1, &lastname,
665                       2, &age,
666                       -1);
667   g_assert (surname == NULL);
668   g_assert (lastname == NULL);
669   g_assert (age == 19);
670   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == FALSE);
671
672   g_object_unref (builder);
673 }
674
675 static void
676 test_tree_store (void)
677 {
678   const gchar buffer[] =
679     "<interface domain=\"test\">"
680     "  <object class=\"GtkTreeStore\" id=\"treestore1\">"
681     "    <columns>"
682     "      <column type=\"gchararray\"/>"
683     "      <column type=\"guint\"/>"
684     "    </columns>"
685     "  </object>"
686     "</interface>";
687   GtkBuilder *builder;
688   GObject *store;
689   
690   builder = builder_new_from_string (buffer, -1, NULL);
691   store = gtk_builder_get_object (builder, "treestore1");
692   g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 2);
693   g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
694   g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_UINT);
695   
696   g_object_unref (builder);
697 }
698
699 static void
700 test_types (void)
701 {
702   const gchar buffer[] = 
703     "<interface>"
704     "  <object class=\"GtkAction\" id=\"action\"/>"
705     "  <object class=\"GtkActionGroup\" id=\"actiongroup\"/>"
706     "  <object class=\"GtkAlignment\" id=\"alignment\"/>"
707     "  <object class=\"GtkArrow\" id=\"arrow\"/>"
708     "  <object class=\"GtkButton\" id=\"button\"/>"
709     "  <object class=\"GtkCheckButton\" id=\"checkbutton\"/>"
710     "  <object class=\"GtkDialog\" id=\"dialog\"/>"
711     "  <object class=\"GtkDrawingArea\" id=\"drawingarea\"/>"
712     "  <object class=\"GtkEventBox\" id=\"eventbox\"/>"
713     "  <object class=\"GtkEntry\" id=\"entry\"/>"
714     "  <object class=\"GtkFontButton\" id=\"fontbutton\"/>"
715     "  <object class=\"GtkHButtonBox\" id=\"hbuttonbox\"/>"
716     "  <object class=\"GtkHBox\" id=\"hbox\"/>"
717     "  <object class=\"GtkHPaned\" id=\"hpaned\"/>"
718     "  <object class=\"GtkHRuler\" id=\"hruler\"/>"
719     "  <object class=\"GtkHScale\" id=\"hscale\"/>"
720     "  <object class=\"GtkHScrollbar\" id=\"hscrollbar\"/>"
721     "  <object class=\"GtkHSeparator\" id=\"hseparator\"/>"
722     "  <object class=\"GtkImage\" id=\"image\"/>"
723     "  <object class=\"GtkLabel\" id=\"label\"/>"
724     "  <object class=\"GtkListStore\" id=\"liststore\"/>"
725     "  <object class=\"GtkMenuBar\" id=\"menubar\"/>"
726     "  <object class=\"GtkNotebook\" id=\"notebook\"/>"
727     "  <object class=\"GtkProgressBar\" id=\"progressbar\"/>"
728     "  <object class=\"GtkRadioButton\" id=\"radiobutton\"/>"
729     "  <object class=\"GtkSizeGroup\" id=\"sizegroup\"/>"
730     "  <object class=\"GtkScrolledWindow\" id=\"scrolledwindow\"/>"
731     "  <object class=\"GtkSpinButton\" id=\"spinbutton\"/>"
732     "  <object class=\"GtkStatusbar\" id=\"statusbar\"/>"
733     "  <object class=\"GtkTextView\" id=\"textview\"/>"
734     "  <object class=\"GtkToggleAction\" id=\"toggleaction\"/>"
735     "  <object class=\"GtkToggleButton\" id=\"togglebutton\"/>"
736     "  <object class=\"GtkToolbar\" id=\"toolbar\"/>"
737     "  <object class=\"GtkTreeStore\" id=\"treestore\"/>"
738     "  <object class=\"GtkTreeView\" id=\"treeview\"/>"
739     "  <object class=\"GtkTable\" id=\"table\"/>"
740     "  <object class=\"GtkVBox\" id=\"vbox\"/>"
741     "  <object class=\"GtkVButtonBox\" id=\"vbuttonbox\"/>"
742     "  <object class=\"GtkVScrollbar\" id=\"vscrollbar\"/>"
743     "  <object class=\"GtkVSeparator\" id=\"vseparator\"/>"
744     "  <object class=\"GtkViewport\" id=\"viewport\"/>"
745     "  <object class=\"GtkVRuler\" id=\"vruler\"/>"
746     "  <object class=\"GtkVPaned\" id=\"vpaned\"/>"
747     "  <object class=\"GtkVScale\" id=\"vscale\"/>"
748     "  <object class=\"GtkWindow\" id=\"window\"/>"
749     "  <object class=\"GtkUIManager\" id=\"uimanager\"/>"
750     "</interface>";
751   const gchar buffer2[] = 
752     "<interface>"
753     "  <object type-func=\"gtk_window_get_type\" id=\"window\"/>"
754     "</interface>";
755   const gchar buffer3[] = 
756     "<interface>"
757     "  <object type-func=\"xxx_invalid_get_type_function\" id=\"window\"/>"
758     "</interface>";
759   GtkBuilder *builder;
760   GObject *window;
761   GError *error;
762
763   builder = builder_new_from_string (buffer, -1, NULL);
764   gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "dialog")));
765   gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "window")));
766   g_object_unref (builder);
767
768   builder = builder_new_from_string (buffer2, -1, NULL);
769   window = gtk_builder_get_object (builder, "window");
770   g_assert (GTK_IS_WINDOW (window));
771   gtk_widget_destroy (GTK_WIDGET (window));
772   g_object_unref (builder);
773   
774   error = NULL;
775   builder = gtk_builder_new ();
776   gtk_builder_add_from_string (builder, buffer3, -1, &error);
777   g_assert (g_error_matches (error,
778                              GTK_BUILDER_ERROR,
779                              GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION));
780   g_error_free (error);
781   g_object_unref (builder);
782 }
783
784 static void
785 test_spin_button (void)
786 {
787   GtkBuilder *builder;
788   const gchar buffer[] =
789     "<interface>"
790     "<object class=\"GtkAdjustment\" id=\"adjustment1\">"
791     "<property name=\"lower\">0</property>"
792     "<property name=\"upper\">10</property>"
793     "<property name=\"step-increment\">2</property>"
794     "<property name=\"page-increment\">3</property>"
795     "<property name=\"page-size\">0</property>"
796     "<property name=\"value\">1</property>"
797     "</object>"
798     "<object class=\"GtkSpinButton\" id=\"spinbutton1\">"
799     "<property name=\"visible\">True</property>"
800     "<property name=\"adjustment\">adjustment1</property>"
801     "</object>"
802     "</interface>";
803   GObject *obj;
804   GtkAdjustment *adjustment;
805   gdouble value;
806   
807   builder = builder_new_from_string (buffer, -1, NULL);
808   obj = gtk_builder_get_object (builder, "spinbutton1");
809   g_assert (GTK_IS_SPIN_BUTTON (obj));
810   adjustment = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (obj));
811   g_assert (GTK_IS_ADJUSTMENT (adjustment));
812   g_object_get (adjustment, "value", &value, NULL);
813   g_assert (value == 1);
814   g_object_get (adjustment, "lower", &value, NULL);
815   g_assert (value == 0);
816   g_object_get (adjustment, "upper", &value, NULL);
817   g_assert (value == 10);
818   g_object_get (adjustment, "step-increment", &value, NULL);
819   g_assert (value == 2);
820   g_object_get (adjustment, "page-increment", &value, NULL);
821   g_assert (value == 3);
822   g_object_get (adjustment, "page-size", &value, NULL);
823   g_assert (value == 0);
824   
825   g_object_unref (builder);
826 }
827
828 static void
829 test_notebook (void)
830 {
831   GtkBuilder *builder;
832   const gchar buffer[] =
833     "<interface>"
834     "  <object class=\"GtkNotebook\" id=\"notebook1\">"
835     "    <child>"
836     "      <object class=\"GtkLabel\" id=\"label1\">"
837     "        <property name=\"label\">label1</property>"
838     "      </object>"
839     "    </child>"
840     "    <child type=\"tab\">"
841     "      <object class=\"GtkLabel\" id=\"tablabel1\">"
842     "        <property name=\"label\">tab_label1</property>"
843     "      </object>"
844     "    </child>"
845     "    <child>"
846     "      <object class=\"GtkLabel\" id=\"label2\">"
847     "        <property name=\"label\">label2</property>"
848     "      </object>"
849     "    </child>"
850     "    <child type=\"tab\">"
851     "      <object class=\"GtkLabel\" id=\"tablabel2\">"
852     "        <property name=\"label\">tab_label2</property>"
853     "      </object>"
854     "    </child>"
855     "  </object>"
856     "</interface>";
857   GObject *notebook;
858   GtkWidget *label;
859
860   builder = builder_new_from_string (buffer, -1, NULL);
861   notebook = gtk_builder_get_object (builder, "notebook1");
862   g_assert (notebook != NULL);
863   g_assert (gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) == 2);
864
865   label = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 0);
866   g_assert (GTK_IS_LABEL (label));
867   g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "label1") == 0);
868   label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), label);
869   g_assert (GTK_IS_LABEL (label));
870   g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "tab_label1") == 0);
871
872   label = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1);
873   g_assert (GTK_IS_LABEL (label));
874   g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "label2") == 0);
875   label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), label);
876   g_assert (GTK_IS_LABEL (label));
877   g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "tab_label2") == 0);
878
879   g_object_unref (builder);
880 }
881
882 static void
883 test_construct_only_property (void)
884 {
885   GtkBuilder *builder;
886   const gchar buffer[] =
887     "<interface>"
888     "  <object class=\"GtkWindow\" id=\"window1\">"
889     "    <property name=\"type\">GTK_WINDOW_POPUP</property>"
890     "  </object>"
891     "</interface>";
892   const gchar buffer2[] =
893     "<interface>"
894     "  <object class=\"GtkTextTagTable\" id=\"tagtable1\"/>"
895     "  <object class=\"GtkTextBuffer\" id=\"textbuffer1\">"
896     "    <property name=\"tag-table\">tagtable1</property>"
897     "  </object>"
898     "</interface>";
899   GObject *widget, *tagtable, *textbuffer;
900   GtkWindowType type;
901   
902   builder = builder_new_from_string (buffer, -1, NULL);
903   widget = gtk_builder_get_object (builder, "window1");
904   g_object_get (widget, "type", &type, NULL);
905   g_assert (type == GTK_WINDOW_POPUP);
906
907   gtk_widget_destroy (GTK_WIDGET (widget));
908   g_object_unref (builder);
909
910   builder = builder_new_from_string (buffer2, -1, NULL);
911   textbuffer = gtk_builder_get_object (builder, "textbuffer1");
912   g_assert (textbuffer != NULL);
913   g_object_get (textbuffer, "tag-table", &tagtable, NULL);
914   g_assert (tagtable == gtk_builder_get_object (builder, "tagtable1"));
915   g_object_unref (tagtable);
916   g_object_unref (builder);
917 }
918
919 static void
920 test_object_properties (void)
921 {
922   GtkBuilder *builder;
923   const gchar buffer[] =
924     "<interface>"
925     "  <object class=\"GtkWindow\" id=\"window1\">"
926     "    <child>"
927     "      <object class=\"GtkVBox\" id=\"vbox\">"
928     "        <property name=\"border-width\">10</property>"
929     "        <child>"
930     "          <object class=\"GtkLabel\" id=\"label1\">"
931     "            <property name=\"mnemonic-widget\">spinbutton1</property>"
932     "          </object>"
933     "        </child>"
934     "        <child>"
935     "          <object class=\"GtkSpinButton\" id=\"spinbutton1\"/>"
936     "        </child>"
937     "      </object>"
938     "    </child>"
939     "  </object>"
940     "</interface>";
941   const gchar buffer2[] =
942     "<interface>"
943     "  <object class=\"GtkWindow\" id=\"window2\"/>"
944     "</interface>";
945   GObject *label, *spinbutton, *window;
946   
947   builder = builder_new_from_string (buffer, -1, NULL);
948   label = gtk_builder_get_object (builder, "label1");
949   g_assert (label != NULL);
950   spinbutton = gtk_builder_get_object (builder, "spinbutton1");
951   g_assert (spinbutton != NULL);
952   g_assert (spinbutton == (GObject*)gtk_label_get_mnemonic_widget (GTK_LABEL (label)));
953
954   gtk_builder_add_from_string (builder, buffer2, -1, NULL);
955   window = gtk_builder_get_object (builder, "window2");
956   g_assert (window != NULL);
957   gtk_widget_destroy (GTK_WIDGET (window));
958
959   g_object_unref (builder);
960 }
961
962 static void
963 test_children (void)
964 {
965   GtkBuilder * builder;
966   GList *children;
967   const gchar buffer1[] =
968     "<interface>"
969     "  <object class=\"GtkWindow\" id=\"window1\">"
970     "    <child>"
971     "      <object class=\"GtkButton\" id=\"button1\">"
972     "        <property name=\"label\">Hello</property>"
973     "      </object>"
974     "    </child>"
975     "  </object>"
976     "</interface>";
977   const gchar buffer2[] =
978     "<interface>"
979     "  <object class=\"GtkDialog\" id=\"dialog1\">"
980     "    <child internal-child=\"vbox\">"
981     "      <object class=\"GtkVBox\" id=\"dialog1-vbox\">"
982     "        <property name=\"border-width\">10</property>"
983     "          <child internal-child=\"action_area\">"
984     "            <object class=\"GtkHButtonBox\" id=\"dialog1-action_area\">"
985     "              <property name=\"border-width\">20</property>"
986     "            </object>"
987     "          </child>"
988     "      </object>"
989     "    </child>"
990     "  </object>"
991     "</interface>";
992
993   GObject *window, *button;
994   GObject *dialog, *vbox, *action_area;
995   
996   builder = builder_new_from_string (buffer1, -1, NULL);
997   window = gtk_builder_get_object (builder, "window1");
998   g_assert (window != NULL);
999   g_assert (GTK_IS_WINDOW (window));
1000
1001   button = gtk_builder_get_object (builder, "button1");
1002   g_assert (button != NULL);
1003   g_assert (GTK_IS_BUTTON (button));
1004   g_assert (strcmp (GTK_WIDGET (GTK_WIDGET (button)->parent)->name, "window1") == 0);
1005
1006   gtk_widget_destroy (GTK_WIDGET (window));
1007   g_object_unref (builder);
1008   
1009   builder = builder_new_from_string (buffer2, -1, NULL);
1010   dialog = gtk_builder_get_object (builder, "dialog1");
1011   g_assert (dialog != NULL);
1012   g_assert (GTK_IS_DIALOG (dialog));
1013   children = gtk_container_get_children (GTK_CONTAINER (dialog));
1014   g_assert (g_list_length (children) == 1);
1015   g_list_free (children);
1016   
1017   vbox = gtk_builder_get_object (builder, "dialog1-vbox");
1018   g_assert (vbox != NULL);
1019   g_assert (GTK_IS_VBOX (vbox));
1020   g_assert (GTK_WIDGET (vbox)->parent != NULL);
1021   g_assert (strcmp (GTK_WIDGET (GTK_WIDGET (vbox)->parent)->name, "dialog1") == 0);
1022   g_assert (GTK_CONTAINER (vbox)->border_width == 10);
1023   g_assert (strcmp (GTK_WIDGET (GTK_DIALOG (dialog)->vbox)->name, "dialog1-vbox") == 0);
1024
1025   action_area = gtk_builder_get_object (builder, "dialog1-action_area");
1026   g_assert (action_area != NULL);
1027   g_assert (GTK_IS_HBUTTON_BOX (action_area));
1028   g_assert (GTK_WIDGET (action_area)->parent != NULL);
1029   g_assert (GTK_CONTAINER (action_area)->border_width == 20);
1030   g_assert (GTK_DIALOG (dialog)->action_area != NULL);
1031   g_assert (GTK_WIDGET (GTK_DIALOG (dialog)->action_area)->name != NULL);
1032   g_assert (strcmp (GTK_WIDGET (GTK_DIALOG (dialog)->action_area)->name, "dialog1-action_area") == 0);
1033   gtk_widget_destroy (GTK_WIDGET (dialog));
1034   g_object_unref (builder);
1035 }
1036
1037 static void
1038 test_child_properties (void)
1039 {
1040   GtkBuilder * builder;
1041   const gchar buffer1[] =
1042     "<interface>"
1043     "  <object class=\"GtkVBox\" id=\"vbox1\">"
1044     "    <child>"
1045     "      <object class=\"GtkLabel\" id=\"label1\"/>"
1046     "      <packing>"
1047     "        <property name=\"pack-type\">start</property>"
1048     "      </packing>"
1049     "    </child>"
1050     "    <child>"
1051     "      <object class=\"GtkLabel\" id=\"label2\"/>"
1052     "      <packing>"
1053     "        <property name=\"pack-type\">end</property>"
1054     "      </packing>"
1055     "    </child>"
1056     "  </object>"
1057     "</interface>";
1058
1059   GObject *label, *vbox;
1060   GtkPackType pack_type;
1061   
1062   builder = builder_new_from_string (buffer1, -1, NULL);
1063   vbox = gtk_builder_get_object (builder, "vbox1");
1064   g_assert (GTK_IS_VBOX (vbox));
1065
1066   label = gtk_builder_get_object (builder, "label1");
1067   g_assert (GTK_IS_LABEL (label));
1068   gtk_container_child_get (GTK_CONTAINER (vbox),
1069                            GTK_WIDGET (label),
1070                            "pack-type",
1071                            &pack_type,
1072                            NULL);
1073   g_assert (pack_type == GTK_PACK_START);
1074   
1075   label = gtk_builder_get_object (builder, "label2");
1076   g_assert (GTK_IS_LABEL (label));
1077   gtk_container_child_get (GTK_CONTAINER (vbox),
1078                            GTK_WIDGET (label),
1079                            "pack-type",
1080                            &pack_type,
1081                            NULL);
1082   g_assert (pack_type == GTK_PACK_END);
1083
1084   g_object_unref (builder);
1085 }
1086
1087 static void
1088 test_treeview_column (void)
1089 {
1090   GtkBuilder *builder;
1091   const gchar buffer[] =
1092     "<interface>"
1093     "<object class=\"GtkListStore\" id=\"liststore1\">"
1094     "  <columns>"
1095     "    <column type=\"gchararray\"/>"
1096     "    <column type=\"guint\"/>"
1097     "  </columns>"
1098     "  <data>"
1099     "    <row>"
1100     "      <col id=\"0\">John</col>"
1101     "      <col id=\"1\">25</col>"
1102     "    </row>"
1103     "  </data>"
1104     "</object>"
1105     "<object class=\"GtkWindow\" id=\"window1\">"
1106     "  <child>"
1107     "    <object class=\"GtkTreeView\" id=\"treeview1\">"
1108     "      <property name=\"visible\">True</property>"
1109     "      <property name=\"model\">liststore1</property>"
1110     "      <child>"
1111     "        <object class=\"GtkTreeViewColumn\" id=\"column1\">"
1112     "          <property name=\"title\">Test</property>"
1113     "          <child>"
1114     "            <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
1115     "            <attributes>"
1116     "              <attribute name=\"text\">1</attribute>"
1117     "            </attributes>"
1118     "          </child>"
1119     "        </object>"
1120     "      </child>"
1121     "      <child>"
1122     "        <object class=\"GtkTreeViewColumn\" id=\"column2\">"
1123     "          <property name=\"title\">Number</property>"
1124     "          <child>"
1125     "            <object class=\"GtkCellRendererText\" id=\"renderer2\"/>"
1126     "            <attributes>"
1127     "              <attribute name=\"text\">0</attribute>"
1128     "            </attributes>"
1129     "          </child>"
1130     "        </object>"
1131     "      </child>"
1132     "    </object>"
1133     "  </child>"
1134     "</object>"
1135     "</interface>";
1136   GObject *window, *treeview;
1137   GtkTreeViewColumn *column;
1138   GList *renderers;
1139   GObject *renderer;
1140   gchar *text;
1141
1142   builder = builder_new_from_string (buffer, -1, NULL);
1143   treeview = gtk_builder_get_object (builder, "treeview1");
1144   g_assert (treeview);
1145   g_assert (GTK_IS_TREE_VIEW (treeview));
1146   column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 0);
1147   g_assert (GTK_IS_TREE_VIEW_COLUMN (column));
1148   g_assert (strcmp (gtk_tree_view_column_get_title (column), "Test") == 0);
1149
1150   renderers = gtk_tree_view_column_get_cell_renderers (column);
1151   g_assert (g_list_length (renderers) == 1);
1152   renderer = g_list_nth_data (renderers, 0);
1153   g_assert (renderer);
1154   g_assert (GTK_IS_CELL_RENDERER_TEXT (renderer));
1155   g_list_free (renderers);
1156
1157   gtk_widget_realize (GTK_WIDGET (treeview));
1158
1159   renderer = gtk_builder_get_object (builder, "renderer1");
1160   g_object_get (renderer, "text", &text, NULL);
1161   g_assert (text);
1162   g_assert (strcmp (text, "25") == 0);
1163   g_free (text);
1164   
1165   renderer = gtk_builder_get_object (builder, "renderer2");
1166   g_object_get (renderer, "text", &text, NULL);
1167   g_assert (text);
1168   g_assert (strcmp (text, "John") == 0);
1169   g_free (text);
1170
1171   gtk_widget_unrealize (GTK_WIDGET (treeview));
1172
1173   window = gtk_builder_get_object (builder, "window1");
1174   gtk_widget_destroy (GTK_WIDGET (window));
1175   
1176   g_object_unref (builder);
1177 }
1178
1179 static void
1180 test_icon_view (void)
1181 {
1182   GtkBuilder *builder;
1183   const gchar buffer[] =
1184     "<interface>"
1185     "  <object class=\"GtkListStore\" id=\"liststore1\">"
1186     "    <columns>"
1187     "      <column type=\"gchararray\"/>"
1188     "      <column type=\"GdkPixbuf\"/>"
1189     "    </columns>"
1190     "    <data>"
1191     "      <row>"
1192     "        <col id=\"0\">test</col>"
1193     "      </row>"
1194     "    </data>"
1195     "  </object>"
1196     "  <object class=\"GtkWindow\" id=\"window1\">"
1197     "    <child>"
1198     "      <object class=\"GtkIconView\" id=\"iconview1\">"
1199     "        <property name=\"model\">liststore1</property>"
1200     "        <property name=\"text-column\">0</property>"
1201     "        <property name=\"pixbuf-column\">1</property>"
1202     "        <property name=\"visible\">True</property>"
1203     "        <child>"
1204     "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
1205     "          <attributes>"
1206     "            <attribute name=\"text\">0</attribute>"
1207     "          </attributes>"
1208     "        </child>"
1209     "      </object>"
1210     "    </child>"
1211     "  </object>"
1212     "</interface>";
1213   GObject *window, *iconview, *renderer;
1214   gchar *text;
1215   
1216   builder = builder_new_from_string (buffer, -1, NULL);
1217   iconview = gtk_builder_get_object (builder, "iconview1");
1218   g_assert (iconview);
1219   g_assert (GTK_IS_ICON_VIEW (iconview));
1220
1221   gtk_widget_realize (GTK_WIDGET (iconview));
1222
1223   renderer = gtk_builder_get_object (builder, "renderer1");
1224   g_object_get (renderer, "text", &text, NULL);
1225   g_assert (text);
1226   g_assert (strcmp (text, "test") == 0);
1227   g_free (text);
1228     
1229   window = gtk_builder_get_object (builder, "window1");
1230   gtk_widget_destroy (GTK_WIDGET (window));
1231   g_object_unref (builder);
1232 }
1233
1234 static void
1235 test_combo_box (void)
1236 {
1237   GtkBuilder *builder;
1238   const gchar buffer[] =
1239     "<interface>"
1240     "  <object class=\"GtkListStore\" id=\"liststore1\">"
1241     "    <columns>"
1242     "      <column type=\"guint\"/>"
1243     "      <column type=\"gchararray\"/>"
1244     "    </columns>"
1245     "    <data>"
1246     "      <row>"
1247     "        <col id=\"0\">1</col>"
1248     "        <col id=\"1\">Foo</col>"
1249     "      </row>"
1250     "      <row>"
1251     "        <col id=\"0\">2</col>"
1252     "        <col id=\"1\">Bar</col>"
1253     "      </row>"
1254     "    </data>"
1255     "  </object>"
1256     "  <object class=\"GtkWindow\" id=\"window1\">"
1257     "    <child>"
1258     "      <object class=\"GtkComboBox\" id=\"combobox1\">"
1259     "        <property name=\"model\">liststore1</property>"
1260     "        <property name=\"visible\">True</property>"
1261     "        <child>"
1262     "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
1263     "          <attributes>"
1264     "            <attribute name=\"text\">0</attribute>"
1265     "          </attributes>"
1266     "        </child>"
1267     "        <child>"
1268     "          <object class=\"GtkCellRendererText\" id=\"renderer2\"/>"
1269     "          <attributes>"
1270     "            <attribute name=\"text\">1</attribute>"
1271     "          </attributes>"
1272     "        </child>"
1273     "      </object>"
1274     "    </child>"
1275     "  </object>"
1276     "</interface>";
1277   GObject *window, *combobox, *renderer;
1278   gchar *text;
1279
1280   builder = builder_new_from_string (buffer, -1, NULL);
1281   combobox = gtk_builder_get_object (builder, "combobox1");
1282   g_assert (combobox);
1283   gtk_widget_realize (GTK_WIDGET (combobox));
1284
1285   renderer = gtk_builder_get_object (builder, "renderer2");
1286   g_assert (renderer);
1287   g_object_get (renderer, "text", &text, NULL);
1288   g_assert (text);
1289   g_assert (strcmp (text, "Bar") == 0);
1290   g_free (text);
1291
1292   renderer = gtk_builder_get_object (builder, "renderer1");
1293   g_assert (renderer);
1294   g_object_get (renderer, "text", &text, NULL);
1295   g_assert (text);
1296   g_assert (strcmp (text, "2") == 0);
1297   g_free (text);
1298
1299   window = gtk_builder_get_object (builder, "window1");
1300   gtk_widget_destroy (GTK_WIDGET (window));
1301
1302   g_object_unref (builder);
1303 }
1304
1305 static void
1306 test_combo_box_entry (void)
1307 {
1308   GtkBuilder *builder;
1309   const gchar buffer[] =
1310     "<interface>"
1311     "  <object class=\"GtkListStore\" id=\"liststore1\">"
1312     "    <columns>"
1313     "      <column type=\"guint\"/>"
1314     "      <column type=\"gchararray\"/>"
1315     "    </columns>"
1316     "    <data>"
1317     "      <row>"
1318     "        <col id=\"0\">1</col>"
1319     "        <col id=\"1\">Foo</col>"
1320     "      </row>"
1321     "      <row>"
1322     "        <col id=\"0\">2</col>"
1323     "        <col id=\"1\">Bar</col>"
1324     "      </row>"
1325     "    </data>"
1326     "  </object>"
1327     "  <object class=\"GtkWindow\" id=\"window1\">"
1328     "    <child>"
1329     "      <object class=\"GtkComboBoxEntry\" id=\"comboboxentry1\">"
1330     "        <property name=\"model\">liststore1</property>"
1331     "        <property name=\"visible\">True</property>"
1332     "        <child>"
1333     "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
1334     "            <attributes>"
1335     "              <attribute name=\"text\">0</attribute>"
1336     "            </attributes>"
1337     "        </child>"
1338     "        <child>"
1339     "          <object class=\"GtkCellRendererText\" id=\"renderer2\"/>"
1340     "            <attributes>"
1341     "              <attribute name=\"text\">1</attribute>"
1342     "            </attributes>"
1343     "        </child>"
1344     "      </object>"
1345     "    </child>"
1346     "  </object>"
1347     "</interface>";
1348   GObject *window, *combobox, *renderer;
1349   gchar *text;
1350
1351   builder = builder_new_from_string (buffer, -1, NULL);
1352   combobox = gtk_builder_get_object (builder, "comboboxentry1");
1353   g_assert (combobox);
1354
1355   renderer = gtk_builder_get_object (builder, "renderer2");
1356   g_assert (renderer);
1357   g_object_get (renderer, "text", &text, NULL);
1358   g_assert (text);
1359   g_assert (strcmp (text, "Bar") == 0);
1360   g_free (text);
1361
1362   renderer = gtk_builder_get_object (builder, "renderer1");
1363   g_assert (renderer);
1364   g_object_get (renderer, "text", &text, NULL);
1365   g_assert (text);
1366   g_assert (strcmp (text, "2") == 0);
1367   g_free (text);
1368
1369   window = gtk_builder_get_object (builder, "window1");
1370   gtk_widget_destroy (GTK_WIDGET (window));
1371
1372   g_object_unref (builder);
1373 }
1374
1375 static void
1376 test_cell_view (void)
1377 {
1378   GtkBuilder *builder;
1379   const gchar *buffer =
1380     "<interface>"
1381     "  <object class=\"GtkListStore\" id=\"liststore1\">"
1382     "    <columns>"
1383     "      <column type=\"gchararray\"/>"
1384     "    </columns>"
1385     "    <data>"
1386     "      <row>"
1387     "        <col id=\"0\">test</col>"
1388     "      </row>"
1389     "    </data>"
1390     "  </object>"
1391     "  <object class=\"GtkWindow\" id=\"window1\">"
1392     "    <child>"
1393     "      <object class=\"GtkCellView\" id=\"cellview1\">"
1394     "        <property name=\"visible\">True</property>"
1395     "        <property name=\"model\">liststore1</property>"
1396     "        <accelerator key=\"f\" modifiers=\"GDK_CONTROL_MASK\" signal=\"grab_focus\"/>"
1397     "        <child>"
1398     "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
1399     "          <attributes>"
1400     "            <attribute name=\"text\">0</attribute>"
1401     "          </attributes>"
1402     "        </child>"
1403     "      </object>"
1404     "    </child>"
1405     "  </object>"
1406     "</interface>";
1407   GObject *cellview;
1408   GObject *model, *window;
1409   GtkTreePath *path;
1410   GList *renderers;
1411   GObject *renderer;
1412   gchar *text;
1413   
1414   builder = builder_new_from_string (buffer, -1, NULL);
1415   cellview = gtk_builder_get_object (builder, "cellview1");
1416   g_assert (builder);
1417   g_assert (cellview);
1418   g_assert (GTK_IS_CELL_VIEW (cellview));
1419   g_object_get (cellview, "model", &model, NULL);
1420   g_assert (model);
1421   g_assert (GTK_IS_TREE_MODEL (model));
1422   g_object_unref (model);
1423   path = gtk_tree_path_new_first ();
1424   gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (cellview), path);
1425   
1426   renderers = gtk_cell_view_get_cell_renderers (GTK_CELL_VIEW (cellview));
1427   g_assert (renderers);
1428   g_assert (g_list_length (renderers) == 1);
1429   
1430   gtk_widget_realize (GTK_WIDGET (cellview));
1431
1432   renderer = g_list_nth_data (renderers, 0);
1433   g_list_free (renderers);
1434   g_assert (renderer);
1435   g_object_get (renderer, "text", &text, NULL);
1436   g_assert (strcmp (text, "test") == 0);
1437   g_free (text);
1438   gtk_tree_path_free (path);
1439
1440   window = gtk_builder_get_object (builder, "window1");
1441   gtk_widget_destroy (GTK_WIDGET (window));
1442   
1443   g_object_unref (builder);
1444 }
1445
1446 static void
1447 test_dialog (void)
1448 {
1449   GtkBuilder * builder;
1450   const gchar buffer1[] =
1451     "<interface>"
1452     "  <object class=\"GtkDialog\" id=\"dialog1\">"
1453     "    <child internal-child=\"vbox\">"
1454     "      <object class=\"GtkVBox\" id=\"dialog1-vbox\">"
1455     "          <child internal-child=\"action_area\">"
1456     "            <object class=\"GtkHButtonBox\" id=\"dialog1-action_area\">"
1457     "              <child>"
1458     "                <object class=\"GtkButton\" id=\"button_cancel\"/>"
1459     "              </child>"
1460     "              <child>"
1461     "                <object class=\"GtkButton\" id=\"button_ok\"/>"
1462     "              </child>"
1463     "            </object>"
1464     "          </child>"
1465     "      </object>"
1466     "    </child>"
1467     "    <action-widgets>"
1468     "      <action-widget response=\"3\">button_ok</action-widget>"
1469     "      <action-widget response=\"-5\">button_cancel</action-widget>"
1470     "    </action-widgets>"
1471     "  </object>"
1472     "</interface>";
1473
1474   GObject *dialog1;
1475   GObject *button_ok;
1476   GObject *button_cancel;
1477   
1478   builder = builder_new_from_string (buffer1, -1, NULL);
1479   dialog1 = gtk_builder_get_object (builder, "dialog1");
1480   button_ok = gtk_builder_get_object (builder, "button_ok");
1481   g_assert (gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog1), GTK_WIDGET (button_ok)) == 3);
1482   button_cancel = gtk_builder_get_object (builder, "button_cancel");
1483   g_assert (gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog1), GTK_WIDGET (button_cancel)) == -5);
1484   
1485   gtk_widget_destroy (GTK_WIDGET (dialog1));
1486   g_object_unref (builder);
1487 }
1488
1489 static void
1490 test_accelerators (void)
1491 {
1492   GtkBuilder *builder;
1493   const gchar *buffer =
1494     "<interface>"
1495     "  <object class=\"GtkWindow\" id=\"window1\">"
1496     "    <child>"
1497     "      <object class=\"GtkButton\" id=\"button1\">"
1498     "        <accelerator key=\"q\" modifiers=\"GDK_CONTROL_MASK\" signal=\"clicked\"/>"
1499     "      </object>"
1500     "    </child>"
1501     "  </object>"
1502     "</interface>";
1503   const gchar *buffer2 =
1504     "<interface>"
1505     "  <object class=\"GtkWindow\" id=\"window1\">"
1506     "    <child>"
1507     "      <object class=\"GtkTreeView\" id=\"treeview1\">"
1508     "        <signal name=\"cursor-changed\" handler=\"gtk_main_quit\"/>"
1509     "        <accelerator key=\"f\" modifiers=\"GDK_CONTROL_MASK\" signal=\"grab_focus\"/>"
1510     "      </object>"
1511     "    </child>"
1512     "  </object>"
1513     "</interface>";
1514   GObject *window1;
1515   GSList *accel_groups;
1516   GObject *accel_group;
1517   
1518   builder = builder_new_from_string (buffer, -1, NULL);
1519   window1 = gtk_builder_get_object (builder, "window1");
1520   g_assert (window1);
1521   g_assert (GTK_IS_WINDOW (window1));
1522
1523   accel_groups = gtk_accel_groups_from_object (window1);
1524   g_assert (g_slist_length (accel_groups) == 1);
1525   accel_group = g_slist_nth_data (accel_groups, 0);
1526   g_assert (accel_group);
1527
1528   gtk_widget_destroy (GTK_WIDGET (window1));
1529   g_object_unref (builder);
1530
1531   builder = builder_new_from_string (buffer2, -1, NULL);
1532   window1 = gtk_builder_get_object (builder, "window1");
1533   g_assert (window1);
1534   g_assert (GTK_IS_WINDOW (window1));
1535
1536   accel_groups = gtk_accel_groups_from_object (window1);
1537   g_assert (g_slist_length (accel_groups) == 1);
1538   accel_group = g_slist_nth_data (accel_groups, 0);
1539   g_assert (accel_group);
1540
1541   gtk_widget_destroy (GTK_WIDGET (window1));
1542   g_object_unref (builder);
1543 }
1544
1545 static void
1546 test_widget (void)
1547 {
1548   const gchar *buffer =
1549     "<interface>"
1550     "  <object class=\"GtkWindow\" id=\"window1\">"
1551     "    <child>"
1552     "      <object class=\"GtkButton\" id=\"button1\">"
1553     "         <property name=\"can-focus\">True</property>"
1554     "         <property name=\"has-focus\">True</property>"
1555     "      </object>"
1556     "    </child>"
1557     "  </object>"
1558    "</interface>";
1559   const gchar *buffer2 =
1560     "<interface>"
1561     "  <object class=\"GtkWindow\" id=\"window1\">"
1562     "    <child>"
1563     "      <object class=\"GtkButton\" id=\"button1\">"
1564     "         <property name=\"can-default\">True</property>"
1565     "         <property name=\"has-default\">True</property>"
1566     "      </object>"
1567     "    </child>"
1568     "  </object>"
1569    "</interface>";
1570   const gchar *buffer3 =
1571     "<interface>"
1572     "  <object class=\"GtkWindow\" id=\"window1\">"
1573     "    <child>"
1574     "      <object class=\"GtkVBox\" id=\"vbox1\">"
1575     "        <child>"
1576     "          <object class=\"GtkLabel\" id=\"label1\">"
1577     "            <child internal-child=\"accessible\">"
1578     "              <object class=\"AtkObject\" id=\"a11y-label1\">"
1579     "                <property name=\"AtkObject::accessible-name\">A Label</property>"
1580     "              </object>"
1581     "            </child>"
1582     "            <accessibility>"
1583     "              <relation target=\"button1\" type=\"label-for\"/>"
1584     "            </accessibility>"
1585     "          </object>"
1586     "        </child>"
1587     "        <child>"
1588     "          <object class=\"GtkButton\" id=\"button1\">"
1589     "            <accessibility>"
1590     "              <action action_name=\"click\" description=\"Sliff\"/>"
1591     "              <action action_name=\"clack\" translatable=\"yes\">Sniff</action>"
1592     "            </accessibility>"
1593     "          </object>"
1594     "        </child>"
1595     "      </object>"
1596     "    </child>"
1597     "  </object>"
1598     "</interface>";
1599   GtkBuilder *builder;
1600   GObject *window1, *button1, *label1;
1601   AtkObject *accessible;
1602   AtkRelationSet *relation_set;
1603   AtkRelation *relation;
1604   char *name;
1605   
1606   builder = builder_new_from_string (buffer, -1, NULL);
1607   button1 = gtk_builder_get_object (builder, "button1");
1608
1609 #if 0
1610   g_assert (GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (button1)));
1611 #endif
1612   window1 = gtk_builder_get_object (builder, "window1");
1613   gtk_widget_destroy (GTK_WIDGET (window1));
1614   
1615   g_object_unref (builder);
1616   
1617   builder = builder_new_from_string (buffer2, -1, NULL);
1618   button1 = gtk_builder_get_object (builder, "button1");
1619
1620   g_assert (GTK_WIDGET_RECEIVES_DEFAULT (GTK_WIDGET (button1)));
1621   
1622   g_object_unref (builder);
1623   
1624   builder = builder_new_from_string (buffer3, -1, NULL);
1625
1626   window1 = gtk_builder_get_object (builder, "window1");
1627   label1 = gtk_builder_get_object (builder, "label1");
1628
1629   accessible = gtk_widget_get_accessible (GTK_WIDGET (label1));
1630   relation_set = atk_object_ref_relation_set (accessible);
1631   g_return_if_fail (atk_relation_set_get_n_relations (relation_set) == 1);
1632   relation = atk_relation_set_get_relation (relation_set, 0);
1633   g_return_if_fail (relation != NULL);
1634   g_return_if_fail (ATK_IS_RELATION (relation));
1635   g_return_if_fail (atk_relation_get_relation_type (relation) != ATK_RELATION_LABELLED_BY);
1636   g_object_unref (relation_set);
1637
1638   g_object_get (G_OBJECT (accessible), "accessible-name", &name, NULL);
1639   g_return_if_fail (strcmp (name, "A Label") == 0);
1640   g_free (name);
1641   
1642   gtk_widget_destroy (GTK_WIDGET (window1));
1643   g_object_unref (builder);
1644 }
1645
1646 static void
1647 test_window (void)
1648 {
1649   const gchar *buffer1 =
1650     "<interface>"
1651     "  <object class=\"GtkWindow\" id=\"window1\">"
1652     "     <property name=\"title\"></property>"
1653     "  </object>"
1654    "</interface>";
1655   const gchar *buffer2 =
1656     "<interface>"
1657     "  <object class=\"GtkWindow\" id=\"window1\">"
1658     "  </object>"
1659    "</interface>";
1660   GtkBuilder *builder;
1661   GObject *window1;
1662   gchar *title;
1663   
1664   builder = builder_new_from_string (buffer1, -1, NULL);
1665   window1 = gtk_builder_get_object (builder, "window1");
1666   g_object_get (window1, "title", &title, NULL);
1667   g_assert (strcmp (title, "") == 0);
1668   g_free (title);
1669   gtk_widget_destroy (GTK_WIDGET (window1));
1670   g_object_unref (builder);
1671
1672   builder = builder_new_from_string (buffer2, -1, NULL);
1673   window1 = gtk_builder_get_object (builder, "window1");
1674   gtk_widget_destroy (GTK_WIDGET (window1));
1675   g_object_unref (builder);
1676 }
1677
1678 static void
1679 test_value_from_string (void)
1680 {
1681   GValue value = { 0 };
1682   GError *error = NULL;
1683   GtkBuilder *builder;
1684
1685   builder = gtk_builder_new ();
1686   
1687   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_STRING, "test", &value, &error));
1688   g_assert (G_VALUE_HOLDS_STRING (&value));
1689   g_assert (strcmp (g_value_get_string (&value), "test") == 0);
1690   g_value_unset (&value);
1691
1692   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "true", &value, &error));
1693   g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
1694   g_assert (g_value_get_boolean (&value) == TRUE);
1695   g_value_unset (&value);
1696
1697   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "false", &value, &error));
1698   g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
1699   g_assert (g_value_get_boolean (&value) == FALSE);
1700   g_value_unset (&value);
1701
1702   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "yes", &value, &error));
1703   g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
1704   g_assert (g_value_get_boolean (&value) == TRUE);
1705   g_value_unset (&value);
1706
1707   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "no", &value, &error));
1708   g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
1709   g_assert (g_value_get_boolean (&value) == FALSE);
1710   g_value_unset (&value);
1711
1712   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "0", &value, &error));
1713   g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
1714   g_assert (g_value_get_boolean (&value) == FALSE);
1715   g_value_unset (&value);
1716
1717   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "1", &value, &error));
1718   g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
1719   g_assert (g_value_get_boolean (&value) == TRUE);
1720   g_value_unset (&value);
1721
1722   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "tRuE", &value, &error));
1723   g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
1724   g_assert (g_value_get_boolean (&value) == TRUE);
1725   g_value_unset (&value);
1726   
1727   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "blaurgh", &value, &error) == FALSE);
1728   g_value_unset (&value);
1729   g_assert (g_error_matches (error,
1730                              GTK_BUILDER_ERROR,
1731                              GTK_BUILDER_ERROR_INVALID_VALUE));
1732   g_error_free (error);
1733   error = NULL;
1734
1735   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "yess", &value, &error) == FALSE);
1736   g_value_unset (&value);
1737   g_assert (g_error_matches (error,
1738                              GTK_BUILDER_ERROR,
1739                              GTK_BUILDER_ERROR_INVALID_VALUE));
1740   g_error_free (error);
1741   error = NULL;
1742   
1743   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "trueee", &value, &error) == FALSE);
1744   g_value_unset (&value);
1745   g_assert (g_error_matches (error,
1746                              GTK_BUILDER_ERROR,
1747                              GTK_BUILDER_ERROR_INVALID_VALUE));
1748   g_error_free (error);
1749   error = NULL;
1750   
1751   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "", &value, &error) == FALSE);
1752   g_value_unset (&value);
1753   g_assert (g_error_matches (error,
1754                              GTK_BUILDER_ERROR,
1755                              GTK_BUILDER_ERROR_INVALID_VALUE));
1756   g_error_free (error);
1757   error = NULL;
1758   
1759   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_INT, "12345", &value, &error));
1760   g_assert (G_VALUE_HOLDS_INT (&value));
1761   g_assert (g_value_get_int (&value) == 12345);
1762   g_value_unset (&value);
1763
1764   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_LONG, "9912345", &value, &error));
1765   g_assert (G_VALUE_HOLDS_LONG (&value));
1766   g_assert (g_value_get_long (&value) == 9912345);
1767   g_value_unset (&value);
1768
1769   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_UINT, "2345", &value, &error));
1770   g_assert (G_VALUE_HOLDS_UINT (&value));
1771   g_assert (g_value_get_uint (&value) == 2345);
1772   g_value_unset (&value);
1773
1774   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_FLOAT, "1.454", &value, &error));
1775   g_assert (G_VALUE_HOLDS_FLOAT (&value));
1776   g_assert (fabs (g_value_get_float (&value) - 1.454) < 0.00001);
1777   g_value_unset (&value);
1778
1779   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_FLOAT, "abc", &value, &error) == FALSE);
1780   g_value_unset (&value);
1781   g_assert (g_error_matches (error,
1782                              GTK_BUILDER_ERROR,
1783                              GTK_BUILDER_ERROR_INVALID_VALUE));
1784   g_error_free (error);
1785   error = NULL;
1786
1787   g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_INT, "/-+,abc", &value, &error) == FALSE);
1788   g_value_unset (&value);
1789   g_assert (g_error_matches (error,
1790                              GTK_BUILDER_ERROR,
1791                              GTK_BUILDER_ERROR_INVALID_VALUE));
1792   g_error_free (error);
1793   error = NULL;
1794
1795   g_assert (gtk_builder_value_from_string_type (builder, GTK_TYPE_WINDOW_TYPE, "toplevel", &value, &error) == TRUE);
1796   g_assert (G_VALUE_HOLDS_ENUM (&value));
1797   g_assert (g_value_get_enum (&value) == GTK_WINDOW_TOPLEVEL);
1798   g_value_unset (&value);
1799
1800   g_assert (gtk_builder_value_from_string_type (builder, GTK_TYPE_WINDOW_TYPE, "sliff", &value, &error) == FALSE);
1801   g_value_unset (&value);
1802   g_assert (g_error_matches (error,
1803                              GTK_BUILDER_ERROR,
1804                              GTK_BUILDER_ERROR_INVALID_VALUE));
1805   g_error_free (error);
1806   error = NULL;
1807   
1808   g_assert (gtk_builder_value_from_string_type (builder, GTK_TYPE_WIDGET_FLAGS, "mapped", &value, &error) == TRUE);
1809   g_assert (G_VALUE_HOLDS_FLAGS (&value));
1810   g_assert (g_value_get_flags (&value) == GTK_MAPPED);
1811   g_value_unset (&value);
1812
1813   g_assert (gtk_builder_value_from_string_type (builder, GTK_TYPE_WIDGET_FLAGS, "GTK_VISIBLE | GTK_REALIZED", &value, &error) == TRUE);
1814   g_assert (G_VALUE_HOLDS_FLAGS (&value));
1815   g_assert (g_value_get_flags (&value) == (GTK_VISIBLE | GTK_REALIZED));
1816   g_value_unset (&value);
1817   
1818   g_assert (gtk_builder_value_from_string_type (builder, GTK_TYPE_WINDOW_TYPE, "foobar", &value, &error) == FALSE);
1819   g_value_unset (&value);
1820   g_assert (g_error_matches (error,
1821                              GTK_BUILDER_ERROR,
1822                              GTK_BUILDER_ERROR_INVALID_VALUE));
1823   g_error_free (error);
1824   error = NULL;
1825   
1826   g_object_unref (builder);
1827 }
1828
1829 static gboolean model_freed = FALSE;
1830
1831 static void
1832 model_weakref (gpointer data,
1833                GObject *model)
1834 {
1835   model_freed = TRUE;
1836 }
1837
1838 static void
1839 test_reference_counting (void)
1840 {
1841   GtkBuilder *builder;
1842   const gchar buffer1[] =
1843     "<interface>"
1844     "  <object class=\"GtkListStore\" id=\"liststore1\"/>"
1845     "  <object class=\"GtkListStore\" id=\"liststore2\"/>"
1846     "  <object class=\"GtkWindow\" id=\"window1\">"
1847     "    <child>"
1848     "      <object class=\"GtkTreeView\" id=\"treeview1\">"
1849     "        <property name=\"model\">liststore1</property>"
1850     "      </object>"
1851     "    </child>"
1852     "  </object>"
1853     "</interface>";
1854   const gchar buffer2[] =
1855     "<interface>"
1856     "  <object class=\"GtkVBox\" id=\"vbox1\">"
1857     "    <child>"
1858     "      <object class=\"GtkLabel\" id=\"label1\"/>"
1859     "      <packing>"
1860     "        <property name=\"pack-type\">start</property>"
1861     "      </packing>"
1862     "    </child>"
1863     "  </object>"
1864     "</interface>";
1865   GObject *window, *treeview, *model;
1866   
1867   builder = builder_new_from_string (buffer1, -1, NULL);
1868   window = gtk_builder_get_object (builder, "window1");
1869   treeview = gtk_builder_get_object (builder, "treeview1");
1870   model = gtk_builder_get_object (builder, "liststore1");
1871   g_object_unref (builder);
1872
1873   g_object_weak_ref (model, (GWeakNotify)model_weakref, NULL);
1874
1875   g_assert (model_freed == FALSE);
1876   gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), NULL);
1877   g_assert (model_freed == TRUE);
1878   
1879   gtk_widget_destroy (GTK_WIDGET (window));
1880
1881   builder = builder_new_from_string (buffer2, -1, NULL);
1882   g_object_unref (builder);
1883 }
1884
1885 static void
1886 test_icon_factory (void)
1887 {
1888   GtkBuilder *builder;
1889   const gchar buffer1[] =
1890     "<interface>"
1891     "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
1892     "    <sources>"
1893     "      <source stock-id=\"apple-red\" filename=\"apple-red.png\"/>"
1894     "    </sources>"
1895     "  </object>"
1896     "</interface>";
1897   const gchar buffer2[] =
1898     "<interface>"
1899     "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
1900     "    <sources>"
1901     "      <source stock-id=\"sliff\" direction=\"rtl\" state=\"active\""
1902     "              size=\"menu\" filename=\"sloff.png\"/>"
1903     "      <source stock-id=\"sliff\" direction=\"ltr\" state=\"selected\""
1904     "              size=\"dnd\" filename=\"slurf.png\"/>"
1905     "    </sources>"
1906     "  </object>"
1907     "</interface>";
1908 #if 0
1909   const gchar buffer3[] =
1910     "<interface>"
1911     "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
1912     "    <invalid/>"
1913     "  </object>"
1914     "</interface>";
1915   const gchar buffer4[] =
1916     "<interface>"
1917     "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
1918     "    <sources>"
1919     "      <invalid/>"
1920     "    </sources>"
1921     "  </object>"
1922     "</interface>";
1923   const gchar buffer5[] =
1924     "<interface>"
1925     "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
1926     "    <sources>"
1927     "      <source/>"
1928     "    </sources>"
1929     "  </object>"
1930     "</interface>";
1931   GError *error = NULL;
1932 #endif  
1933   GObject *factory;
1934   GtkIconSet *icon_set;
1935   GtkIconSource *icon_source;
1936   GtkWidget *image;
1937   
1938   builder = builder_new_from_string (buffer1, -1, NULL);
1939   factory = gtk_builder_get_object (builder, "iconfactory1");
1940   g_assert (factory != NULL);
1941
1942   icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (factory), "apple-red");
1943   g_assert (icon_set != NULL);
1944   gtk_icon_factory_add_default (GTK_ICON_FACTORY (factory));
1945   image = gtk_image_new_from_stock ("apple-red", GTK_ICON_SIZE_BUTTON);
1946   g_assert (image != NULL);
1947
1948   g_object_unref (builder);
1949
1950   builder = builder_new_from_string (buffer2, -1, NULL);
1951   factory = gtk_builder_get_object (builder, "iconfactory1");
1952   g_assert (factory != NULL);
1953
1954   icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (factory), "sliff");
1955   g_assert (icon_set != NULL);
1956   g_assert (g_slist_length (icon_set->sources) == 2);
1957
1958   icon_source = icon_set->sources->data;
1959   g_assert (gtk_icon_source_get_direction (icon_source) == GTK_TEXT_DIR_RTL);
1960   g_assert (gtk_icon_source_get_state (icon_source) == GTK_STATE_ACTIVE);
1961   g_assert (gtk_icon_source_get_size (icon_source) == GTK_ICON_SIZE_MENU);
1962   g_assert (g_str_has_suffix (gtk_icon_source_get_filename (icon_source), "sloff.png"));
1963   
1964   icon_source = icon_set->sources->next->data;
1965   g_assert (gtk_icon_source_get_direction (icon_source) == GTK_TEXT_DIR_LTR);
1966   g_assert (gtk_icon_source_get_state (icon_source) == GTK_STATE_SELECTED);
1967   g_assert (gtk_icon_source_get_size (icon_source) == GTK_ICON_SIZE_DND);
1968   g_assert (g_str_has_suffix (gtk_icon_source_get_filename (icon_source), "slurf.png"));
1969
1970   g_object_unref (builder);
1971
1972 #if 0
1973   error = NULL;
1974   gtk_builder_add_from_string (builder, buffer3, -1, &error);
1975   g_assert (g_error_matches (error,
1976                              GTK_BUILDER_ERROR,
1977                              GTK_BUILDER_ERROR_INVALID_TAG));
1978   g_error_free (error);
1979
1980   error = NULL;
1981   gtk_builder_add_from_string (builder, buffer4, -1, &error);
1982   g_assert (g_error_matches (error,
1983                              GTK_BUILDER_ERROR,
1984                              GTK_BUILDER_ERROR_INVALID_TAG));
1985   g_error_free (error);
1986
1987   error = NULL;
1988   gtk_builder_add_from_string (builder, buffer5, -1, &error);
1989   g_assert (g_error_matches (error,
1990                              GTK_BUILDER_ERROR,
1991                              GTK_BUILDER_ERROR_INVALID_ATTRIBUTE));
1992   g_error_free (error);
1993 #endif
1994
1995 }
1996
1997 typedef struct {
1998   gboolean weight;
1999   gboolean foreground;
2000   gboolean underline;
2001   gboolean size;
2002   gboolean font_desc;
2003   gboolean language;
2004 } FoundAttrs;
2005
2006 static gboolean 
2007 filter_pango_attrs (PangoAttribute *attr, 
2008                     gpointer        data)
2009 {
2010   FoundAttrs *found = (FoundAttrs *)data;
2011
2012   if (attr->klass->type == PANGO_ATTR_WEIGHT)
2013     found->weight = TRUE;
2014   else if (attr->klass->type == PANGO_ATTR_FOREGROUND)
2015     found->foreground = TRUE;
2016   else if (attr->klass->type == PANGO_ATTR_UNDERLINE)
2017     found->underline = TRUE;
2018   /* Make sure optional start/end properties are working */
2019   else if (attr->klass->type == PANGO_ATTR_SIZE && 
2020            attr->start_index == 5 &&
2021            attr->end_index   == 10)
2022     found->size = TRUE;
2023   else if (attr->klass->type == PANGO_ATTR_FONT_DESC)
2024     found->font_desc = TRUE;
2025   else if (attr->klass->type == PANGO_ATTR_LANGUAGE)
2026     found->language = TRUE;
2027
2028   return TRUE;
2029 }
2030
2031 static void
2032 test_pango_attributes (void)
2033 {
2034   GtkBuilder *builder;
2035   FoundAttrs found = { 0, };
2036   const gchar buffer[] =
2037     "<interface>"
2038     "  <object class=\"GtkLabel\" id=\"label1\">"
2039     "    <attributes>"
2040     "      <attribute name=\"weight\" value=\"PANGO_WEIGHT_BOLD\"/>"
2041     "      <attribute name=\"foreground\" value=\"DarkSlateGray\"/>"
2042     "      <attribute name=\"underline\" value=\"True\"/>"
2043     "      <attribute name=\"size\" value=\"4\" start=\"5\" end=\"10\"/>"
2044     "      <attribute name=\"font-desc\" value=\"Sans Italic 22\"/>"
2045     "      <attribute name=\"language\" value=\"pt_BR\"/>"
2046     "    </attributes>"
2047     "  </object>"
2048     "</interface>";
2049   const gchar err_buffer1[] =
2050     "<interface>"
2051     "  <object class=\"GtkLabel\" id=\"label1\">"
2052     "    <attributes>"
2053     "      <attribute name=\"weight\"/>"
2054     "    </attributes>"
2055     "  </object>"
2056     "</interface>";
2057   const gchar err_buffer2[] =
2058     "<interface>"
2059     "  <object class=\"GtkLabel\" id=\"label1\">"
2060     "    <attributes>"
2061     "      <attribute name=\"weight\" value=\"PANGO_WEIGHT_BOLD\" unrecognized=\"True\"/>"
2062     "    </attributes>"
2063     "  </object>"
2064     "</interface>";
2065
2066   GObject *label;
2067   GError  *error = NULL;
2068   PangoAttrList *attrs, *filtered;
2069   
2070   /* Test attributes are set */
2071   builder = builder_new_from_string (buffer, -1, NULL);
2072   label = gtk_builder_get_object (builder, "label1");
2073   g_assert (label != NULL);
2074
2075   attrs = gtk_label_get_attributes (GTK_LABEL (label));
2076   g_assert (attrs != NULL);
2077
2078   filtered = pango_attr_list_filter (attrs, filter_pango_attrs, &found);
2079   g_assert (filtered);
2080   pango_attr_list_unref (filtered);
2081
2082   g_assert (found.weight);
2083   g_assert (found.foreground);
2084   g_assert (found.underline);
2085   g_assert (found.size);
2086   g_assert (found.language);
2087   g_assert (found.font_desc);
2088
2089   g_object_unref (builder);
2090
2091   /* Test errors are set */
2092   builder = gtk_builder_new ();
2093   gtk_builder_add_from_string (builder, err_buffer1, -1, &error);
2094   label = gtk_builder_get_object (builder, "label1");
2095   g_assert (g_error_matches (error,
2096                              GTK_BUILDER_ERROR,
2097                              GTK_BUILDER_ERROR_MISSING_ATTRIBUTE));
2098   g_object_unref (builder);
2099   g_error_free (error);
2100   error = NULL;
2101
2102   builder = gtk_builder_new ();
2103   gtk_builder_add_from_string (builder, err_buffer2, -1, &error);
2104   label = gtk_builder_get_object (builder, "label1");
2105
2106   g_assert (g_error_matches (error,
2107                              GTK_BUILDER_ERROR,
2108                              GTK_BUILDER_ERROR_INVALID_ATTRIBUTE));
2109   g_object_unref (builder);
2110   g_error_free (error);
2111 }
2112
2113 static void
2114 test_requires (void)
2115 {
2116   GtkBuilder *builder;
2117   GError     *error = NULL;
2118   gchar      *buffer;
2119   const gchar buffer_fmt[] =
2120     "<interface>"
2121     "  <requires lib=\"gtk+\" version=\"%d.%d\"/>"
2122     "</interface>";
2123
2124   buffer = g_strdup_printf (buffer_fmt, GTK_MAJOR_VERSION, GTK_MINOR_VERSION + 1);
2125   builder = gtk_builder_new ();
2126   gtk_builder_add_from_string (builder, buffer, -1, &error);
2127   g_assert (g_error_matches (error,
2128                              GTK_BUILDER_ERROR,
2129                              GTK_BUILDER_ERROR_VERSION_MISMATCH));
2130   g_object_unref (builder);
2131   g_error_free (error);
2132 }
2133
2134 static void
2135 test_add_objects (void)
2136 {
2137   GtkBuilder *builder;
2138   GError *error;
2139   gint ret;
2140   GObject *obj;
2141   GtkUIManager *manager;
2142   GtkWidget *menubar;
2143   GObject *menu, *label;
2144   GList *children;
2145   gchar *objects[2] = {"mainbox", NULL};
2146   gchar *objects2[3] = {"mainbox", "window2", NULL};
2147   gchar *objects3[3] = {"uimgr1", "menubar1"};
2148   gchar *objects4[2] = {"uimgr1", NULL};
2149   const gchar buffer[] =
2150     "<interface>"
2151     "  <object class=\"GtkWindow\" id=\"window\">"
2152     "    <child>"
2153     "      <object class=\"GtkVBox\" id=\"mainbox\">"
2154     "        <property name=\"visible\">True</property>"
2155     "        <child>"
2156     "          <object class=\"GtkLabel\" id=\"label1\">"
2157     "            <property name=\"visible\">True</property>"
2158     "            <property name=\"label\" translatable=\"no\">first label</property>"
2159     "          </object>"
2160     "        </child>"
2161     "        <child>"
2162     "          <object class=\"GtkLabel\" id=\"label2\">"
2163     "            <property name=\"visible\">True</property>"
2164     "            <property name=\"label\" translatable=\"no\">second label</property>"
2165     "          </object>"
2166     "          <packing>"
2167     "            <property name=\"position\">1</property>"
2168     "          </packing>"
2169     "        </child>"
2170     "      </object>"
2171     "    </child>"
2172     "  </object>"
2173     "  <object class=\"GtkWindow\" id=\"window2\">"
2174     "    <child>"
2175     "      <object class=\"GtkLabel\" id=\"label1\">"
2176     "        <property name=\"label\" translatable=\"no\">second label</property>"
2177     "      </object>"
2178     "    </child>"
2179     "  </object>"
2180     "<interface/>";
2181   const gchar buffer2[] =
2182     "<interface>"
2183     "  <object class=\"GtkUIManager\" id=\"uimgr1\">"
2184     "    <child>"
2185     "      <object class=\"GtkActionGroup\" id=\"ag1\">"
2186     "        <child>"
2187     "          <object class=\"GtkAction\" id=\"file\">"
2188     "            <property name=\"label\">_File</property>"
2189     "          </object>"
2190     "          <accelerator key=\"n\" modifiers=\"GDK_CONTROL_MASK\"/>"
2191     "        </child>"
2192     "      </object>"
2193     "    </child>"
2194     "    <ui>"
2195     "      <menubar name=\"menubar1\">"
2196     "        <menu action=\"file\">"
2197     "        </menu>"
2198     "      </menubar>"
2199     "    </ui>"
2200     "  </object>"
2201     "  <object class=\"GtkWindow\" id=\"window1\">"
2202     "    <child>"
2203     "      <object class=\"GtkMenuBar\" id=\"menubar1\" constructor=\"uimgr1\"/>"
2204     "    </child>"
2205     "  </object>"
2206     "</interface>";
2207
2208   error = NULL;
2209   builder = gtk_builder_new ();
2210   ret = gtk_builder_add_objects_from_string (builder, buffer, -1, objects, &error);
2211   g_assert (ret);
2212   g_assert (error == NULL);
2213   obj = gtk_builder_get_object (builder, "window");
2214   g_assert (obj == NULL);
2215   obj = gtk_builder_get_object (builder, "window2");
2216   g_assert (obj == NULL);
2217   obj = gtk_builder_get_object (builder, "mainbox");  
2218   g_assert (GTK_IS_WIDGET (obj));
2219   g_object_unref (builder);
2220
2221   error = NULL;
2222   builder = gtk_builder_new ();
2223   ret = gtk_builder_add_objects_from_string (builder, buffer, -1, objects2, &error);
2224   g_assert (ret);
2225   g_assert (error == NULL);
2226   obj = gtk_builder_get_object (builder, "window");
2227   g_assert (obj == NULL);
2228   obj = gtk_builder_get_object (builder, "window2");
2229   g_assert (GTK_IS_WINDOW (obj));
2230   gtk_widget_destroy (GTK_WIDGET (obj));
2231   obj = gtk_builder_get_object (builder, "mainbox");  
2232   g_assert (GTK_IS_WIDGET (obj));
2233   g_object_unref (builder);
2234
2235   /* test cherry picking a ui manager and menubar that depends on it */
2236   error = NULL;
2237   builder = gtk_builder_new ();
2238   ret = gtk_builder_add_objects_from_string (builder, buffer2, -1, objects3, &error);
2239   g_assert (ret);
2240   obj = gtk_builder_get_object (builder, "uimgr1");
2241   g_assert (GTK_IS_UI_MANAGER (obj));
2242   obj = gtk_builder_get_object (builder, "file");
2243   g_assert (GTK_IS_ACTION (obj));
2244   obj = gtk_builder_get_object (builder, "menubar1");
2245   g_assert (GTK_IS_MENU_BAR (obj));
2246   menubar = GTK_WIDGET (obj);
2247
2248   children = gtk_container_get_children (GTK_CONTAINER (menubar));
2249   menu = children->data;
2250   g_assert (menu != NULL);
2251   g_assert (GTK_IS_MENU_ITEM (menu));
2252   g_assert (strcmp (GTK_WIDGET (menu)->name, "file") == 0);
2253   g_list_free (children);
2254  
2255   label = G_OBJECT (GTK_BIN (menu)->child);
2256   g_assert (label != NULL);
2257   g_assert (GTK_IS_LABEL (label));
2258   g_assert (strcmp (gtk_label_get_text (GTK_LABEL (label)), "File") == 0);
2259
2260   g_object_unref (builder);
2261
2262   /* test cherry picking just the ui manager */
2263   error = NULL;
2264   builder = gtk_builder_new ();
2265   ret = gtk_builder_add_objects_from_string (builder, buffer2, -1, objects4, &error);
2266   g_assert (ret);
2267   obj = gtk_builder_get_object (builder, "uimgr1");
2268   g_assert (GTK_IS_UI_MANAGER (obj));
2269   manager = GTK_UI_MANAGER (obj);
2270   obj = gtk_builder_get_object (builder, "file");
2271   g_assert (GTK_IS_ACTION (obj));
2272   menubar = gtk_ui_manager_get_widget (manager, "/menubar1");
2273   g_assert (GTK_IS_MENU_BAR (menubar));
2274
2275   children = gtk_container_get_children (GTK_CONTAINER (menubar));
2276   menu = children->data;
2277   g_assert (menu != NULL);
2278   g_assert (GTK_IS_MENU_ITEM (menu));
2279   g_assert (strcmp (GTK_WIDGET (menu)->name, "file") == 0);
2280   g_list_free (children);
2281  
2282   label = G_OBJECT (GTK_BIN (menu)->child);
2283   g_assert (label != NULL);
2284   g_assert (GTK_IS_LABEL (label));
2285   g_assert (strcmp (gtk_label_get_text (GTK_LABEL (label)), "File") == 0);
2286
2287   g_object_unref (builder);
2288 }
2289
2290 static GtkWidget *
2291 get_parent_menubar (GtkWidget *menuitem)
2292 {
2293   GtkMenuShell *menu_shell = (GtkMenuShell *)menuitem->parent;
2294   GtkWidget *attach = NULL;
2295
2296   g_assert (GTK_IS_MENU_SHELL (menu_shell));
2297
2298   while (menu_shell && !GTK_IS_MENU_BAR (menu_shell))
2299     {
2300       if (GTK_IS_MENU (menu_shell) && 
2301           (attach = gtk_menu_get_attach_widget (GTK_MENU (menu_shell))) != NULL)
2302         menu_shell = (GtkMenuShell *)attach->parent;
2303       else
2304         menu_shell = NULL;
2305     }
2306
2307   return menu_shell ? GTK_WIDGET (menu_shell) : NULL;
2308 }
2309
2310 static void
2311 test_menus (void)
2312 {
2313   const gchar *buffer =
2314     "<interface>"
2315     "  <object class=\"GtkWindow\" id=\"window1\">"
2316     "    <accel-groups>"
2317     "      <group name=\"accelgroup1\"/>"
2318     "    </accel-groups>"
2319     "    <child>"
2320     "      <object class=\"GtkVBox\" id=\"vbox1\">"
2321     "        <property name=\"visible\">True</property>"
2322     "        <property name=\"orientation\">vertical</property>"
2323     "        <child>"
2324     "          <object class=\"GtkMenuBar\" id=\"menubar1\">"
2325     "            <property name=\"visible\">True</property>"
2326     "            <child>"
2327     "              <object class=\"GtkMenuItem\" id=\"menuitem1\">"
2328     "                <property name=\"visible\">True</property>"
2329     "                <property name=\"label\" translatable=\"yes\">_File</property>"
2330     "                <property name=\"use_underline\">True</property>"
2331     "                <child type=\"submenu\">"
2332     "                  <object class=\"GtkMenu\" id=\"menu1\">"
2333     "                    <property name=\"visible\">True</property>"
2334     "                    <child>"
2335     "                      <object class=\"GtkImageMenuItem\" id=\"imagemenuitem1\">"
2336     "                        <property name=\"label\">gtk-new</property>"
2337     "                        <property name=\"visible\">True</property>"
2338     "                        <property name=\"use_stock\">True</property>"
2339     "                        <property name=\"accel_group\">accelgroup1</property>"
2340     "                      </object>"
2341     "                    </child>"
2342     "                  </object>"
2343     "                </child>"
2344     "              </object>"
2345     "            </child>"
2346     "          </object>"
2347     "        </child>"
2348     "      </object>"
2349     "    </child>"
2350     "  </object>"
2351     "<object class=\"GtkAccelGroup\" id=\"accelgroup1\"/>"
2352     "</interface>";
2353
2354   const gchar *buffer1 =
2355     "<interface>"
2356     "  <object class=\"GtkWindow\" id=\"window1\">"
2357     "    <accel-groups>"
2358     "      <group name=\"accelgroup1\"/>"
2359     "    </accel-groups>"
2360     "    <child>"
2361     "      <object class=\"GtkVBox\" id=\"vbox1\">"
2362     "        <property name=\"visible\">True</property>"
2363     "        <property name=\"orientation\">vertical</property>"
2364     "        <child>"
2365     "          <object class=\"GtkMenuBar\" id=\"menubar1\">"
2366     "            <property name=\"visible\">True</property>"
2367     "            <child>"
2368     "              <object class=\"GtkImageMenuItem\" id=\"imagemenuitem1\">"
2369     "                <property name=\"visible\">True</property>"
2370     "                <child>"
2371     "                  <object class=\"GtkLabel\" id=\"custom1\">"
2372     "                    <property name=\"visible\">True</property>"
2373     "                    <property name=\"label\">a label</property>"
2374     "                  </object>"
2375     "                </child>"
2376     "              </object>"
2377     "            </child>"
2378     "          </object>"
2379     "        </child>"
2380     "      </object>"
2381     "    </child>"
2382     "  </object>"
2383     "<object class=\"GtkAccelGroup\" id=\"accelgroup1\"/>"
2384     "</interface>";
2385   GtkBuilder *builder;
2386   GtkWidget *window, *item;
2387   GtkAccelGroup *accel_group;
2388   GtkWidget *item_accel_label, *sample_accel_label, *sample_menu_item, *custom;
2389
2390   /* Check that the item has the correct accel label string set
2391    */
2392   builder = builder_new_from_string (buffer, -1, NULL);
2393   window = (GtkWidget *)gtk_builder_get_object (builder, "window1");
2394   item = (GtkWidget *)gtk_builder_get_object (builder, "imagemenuitem1");
2395   accel_group = (GtkAccelGroup *)gtk_builder_get_object (builder, "accelgroup1");
2396
2397   gtk_widget_show_all (window);
2398
2399   sample_menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, accel_group);
2400
2401   g_assert (GTK_BIN (sample_menu_item)->child);
2402   g_assert (GTK_IS_ACCEL_LABEL (GTK_BIN (sample_menu_item)->child));
2403   sample_accel_label = GTK_WIDGET (GTK_BIN (sample_menu_item)->child);
2404   gtk_widget_show (sample_accel_label);
2405
2406   g_assert (GTK_BIN (item)->child);
2407   g_assert (GTK_IS_ACCEL_LABEL (GTK_BIN (item)->child));
2408   item_accel_label = GTK_WIDGET (GTK_BIN (item)->child);
2409
2410   gtk_accel_label_refetch (GTK_ACCEL_LABEL (sample_accel_label));
2411   gtk_accel_label_refetch (GTK_ACCEL_LABEL (item_accel_label));
2412
2413   g_assert (GTK_ACCEL_LABEL (sample_accel_label)->accel_string != NULL);
2414   g_assert (GTK_ACCEL_LABEL (item_accel_label)->accel_string != NULL);
2415   g_assert (strcmp (GTK_ACCEL_LABEL (item_accel_label)->accel_string, 
2416                     GTK_ACCEL_LABEL (sample_accel_label)->accel_string) == 0);
2417
2418   /* Check the menu hierarchy worked here  */
2419   g_assert (get_parent_menubar (item));
2420
2421   gtk_widget_destroy (GTK_WIDGET (window));
2422   gtk_widget_destroy (sample_menu_item);
2423   g_object_unref (builder);
2424
2425
2426   /* Check that we can add alien children to menu items via normal
2427    * GtkContainer apis.
2428    */
2429   builder = builder_new_from_string (buffer1, -1, NULL);
2430   window = (GtkWidget *)gtk_builder_get_object (builder, "window1");
2431   item = (GtkWidget *)gtk_builder_get_object (builder, "imagemenuitem1");
2432   custom = (GtkWidget *)gtk_builder_get_object (builder, "custom1");
2433
2434   g_assert (custom->parent == item);
2435
2436   gtk_widget_destroy (GTK_WIDGET (window));
2437   g_object_unref (builder);
2438
2439 }
2440
2441
2442 static void 
2443 test_file (const gchar *filename)
2444 {
2445   GtkBuilder *builder;
2446   GError *error = NULL;
2447   GSList *l, *objects;
2448
2449   builder = gtk_builder_new ();
2450
2451   if (!gtk_builder_add_from_file (builder, filename, &error))
2452     {
2453       g_error ("%s", error->message);
2454       g_error_free (error);
2455       return;
2456     }
2457
2458   objects = gtk_builder_get_objects (builder);
2459   for (l = objects; l; l = l->next)
2460     {
2461       GObject *obj = (GObject*)l->data;
2462
2463       if (GTK_IS_DIALOG (obj))
2464         {
2465           int response;
2466
2467           g_print ("Running dialog %s.\n",
2468                    gtk_widget_get_name (GTK_WIDGET (obj)));
2469           response = gtk_dialog_run (GTK_DIALOG (obj));
2470         }
2471       else if (GTK_IS_WINDOW (obj))
2472         {
2473           g_signal_connect (obj, "destroy", G_CALLBACK (gtk_main_quit), NULL);
2474           g_print ("Showing %s.\n",
2475                    gtk_widget_get_name (GTK_WIDGET (obj)));
2476           gtk_widget_show_all (GTK_WIDGET (obj));
2477         }
2478     }
2479
2480   gtk_main ();
2481
2482   g_object_unref (builder);
2483   builder = NULL;
2484 }
2485
2486 static void
2487 test_message_area (void)
2488 {
2489   GtkBuilder *builder;
2490   GError *error;
2491   GObject *obj, *obj1;
2492   const gchar buffer[] =
2493     "<interface>"
2494     "  <object class=\"GtkInfoBar\" id=\"infobar1\">"
2495     "    <child internal-child=\"content_area\">"
2496     "      <object class=\"GtkHBox\" id=\"contentarea1\">"
2497     "        <child>"
2498     "          <object class=\"GtkLabel\" id=\"content\">"
2499     "            <property name=\"label\" translatable=\"yes\">Message</property>"
2500     "          </object>"
2501     "        </child>"
2502     "      </object>"
2503     "    </child>"
2504     "    <child internal-child=\"action_area\">"
2505     "      <object class=\"GtkVButtonBox\" id=\"actionarea1\">"
2506     "        <child>"
2507     "          <object class=\"GtkButton\" id=\"button_ok\">"
2508     "            <property name=\"label\">gtk-ok</property>"
2509     "            <property name=\"use-stock\">yes</property>"
2510     "          </object>"
2511     "        </child>"
2512     "      </object>"
2513     "    </child>"
2514     "    <action-widgets>"
2515     "      <action-widget response=\"1\">button_ok</action-widget>"
2516     "    </action-widgets>"
2517     "  </object>"
2518     "</interface>";
2519
2520   error = NULL;
2521   builder = builder_new_from_string (buffer, -1, &error);
2522   g_assert (error == NULL);
2523   obj = gtk_builder_get_object (builder, "infobar1");
2524   g_assert (GTK_IS_INFO_BAR (obj));
2525   obj1 = gtk_builder_get_object (builder, "content");
2526   g_assert (GTK_IS_LABEL (obj1));
2527   g_assert (gtk_widget_get_parent (gtk_widget_get_parent (obj1)) == obj);
2528
2529   obj1 = gtk_builder_get_object (builder, "button_ok");
2530   g_assert (GTK_IS_BUTTON (obj1));
2531   g_assert (gtk_widget_get_parent (gtk_widget_get_parent (obj1)) == obj);
2532
2533   g_object_unref (builder);
2534 }
2535
2536 int
2537 main (int argc, char **argv)
2538 {
2539   /* initialize test program */
2540   gtk_test_init (&argc, &argv);
2541
2542   if (argc > 1)
2543     {
2544       test_file (argv[1]);
2545       return 0;
2546     }
2547
2548   g_test_add_func ("/Builder/Parser", test_parser);
2549   g_test_add_func ("/Builder/Types", test_types);
2550   g_test_add_func ("/Builder/Construct-Only Properties", test_construct_only_property);
2551   g_test_add_func ("/Builder/Children", test_children);
2552   g_test_add_func ("/Builder/Child Properties", test_child_properties);
2553   g_test_add_func ("/Builder/Object Properties", test_object_properties);
2554   g_test_add_func ("/Builder/Notebook", test_notebook);
2555   g_test_add_func ("/Builder/Domain", test_domain);
2556   g_test_add_func ("/Builder/Signal Autoconnect", test_connect_signals);
2557   g_test_add_func ("/Builder/UIManager Simple", test_uimanager_simple);
2558   g_test_add_func ("/Builder/Spin Button", test_spin_button);
2559   g_test_add_func ("/Builder/SizeGroup", test_sizegroup);
2560   g_test_add_func ("/Builder/ListStore", test_list_store);
2561   g_test_add_func ("/Builder/TreeStore", test_tree_store);
2562   g_test_add_func ("/Builder/TreeView Column", test_treeview_column);
2563   g_test_add_func ("/Builder/IconView", test_icon_view);
2564   g_test_add_func ("/Builder/ComboBox", test_combo_box);
2565   g_test_add_func ("/Builder/ComboBox Entry", test_combo_box_entry);
2566   g_test_add_func ("/Builder/CellView", test_cell_view);
2567   g_test_add_func ("/Builder/Dialog", test_dialog);
2568   g_test_add_func ("/Builder/Accelerators", test_accelerators);
2569   g_test_add_func ("/Builder/Widget", test_widget);
2570   g_test_add_func ("/Builder/Value From String", test_value_from_string);
2571   g_test_add_func ("/Builder/Reference Counting", test_reference_counting);
2572   g_test_add_func ("/Builder/Window", test_window);
2573   g_test_add_func ("/Builder/IconFactory", test_icon_factory);
2574   g_test_add_func ("/Builder/PangoAttributes", test_pango_attributes);
2575   g_test_add_func ("/Builder/Requires", test_requires);
2576   g_test_add_func ("/Builder/AddObjects", test_add_objects);
2577   g_test_add_func ("/Builder/Menus", test_menus);
2578   g_test_add_func ("/Builder/MessageArea", test_message_area);
2579
2580   return g_test_run();
2581 }