]> Pileus Git - ~andy/gtk/blob - tests/testmerge.c
Make this work for inserting before/after an existing menuitem or
[~andy/gtk] / tests / testmerge.c
1 #include <config.h>
2
3 #include <stdio.h>
4 #include <string.h>
5 #ifdef HAVE_UNISTD_H
6 #include <unistd.h>
7 #endif
8 #include <gtk/gtk.h>
9
10 #ifndef STDOUT_FILENO
11 #define STDOUT_FILENO 1 
12 #endif
13
14 struct { const gchar *filename; guint merge_id; } merge_ids[] = {
15   { "merge-1.ui", 0 },
16   { "merge-2.ui", 0 },
17   { "merge-3.ui", 0 }
18 };
19
20 static void
21 dump_tree (GtkWidget    *button, 
22            GtkUIManager *merge)
23 {
24   gchar *dump;
25
26   dump = gtk_ui_manager_get_ui (merge);
27   g_message (dump);
28   g_free (dump);
29 }
30
31 static void
32 dump_accels (void)
33 {
34   gtk_accel_map_save_fd (STDOUT_FILENO);
35 }
36
37 static void
38 print_toplevel (GtkWidget *widget, gpointer user_data)
39 {
40   g_print ("%s\n", G_OBJECT_TYPE_NAME (widget));
41 }
42
43 static void
44 dump_toplevels (GtkWidget    *button, 
45                 GtkUIManager *merge)
46 {
47   GSList *toplevels;
48
49   toplevels = gtk_ui_manager_get_toplevels (merge, 
50                                             GTK_UI_MANAGER_MENUBAR |
51                                             GTK_UI_MANAGER_TOOLBAR |
52                                             GTK_UI_MANAGER_POPUP);
53
54   g_slist_foreach (toplevels, (GFunc) print_toplevel, NULL);
55   g_slist_free (toplevels);
56 }
57
58 static void
59 toggle_tearoffs (GtkWidget    *button, 
60                  GtkUIManager *merge)
61 {
62   gboolean add_tearoffs;
63
64   add_tearoffs = gtk_ui_manager_get_add_tearoffs (merge);
65   
66   gtk_ui_manager_set_add_tearoffs (merge, !add_tearoffs);
67 }
68
69 static gint
70 delayed_toggle_dynamic (GtkUIManager *merge)
71 {
72   GtkAction *dyn;
73   static GtkActionGroup *dynamic = NULL;
74   static guint merge_id = 0;
75
76   if (!dynamic)
77     {
78       dynamic = gtk_action_group_new ("dynamic");
79       gtk_ui_manager_insert_action_group (merge, dynamic, 0);
80       dyn = g_object_new (GTK_TYPE_ACTION,
81                           "name", "dyn1",
82                           "label", "Dynamic action 1",
83                           "stock_id", GTK_STOCK_COPY,
84                           NULL);
85       gtk_action_group_add_action (dynamic, dyn);
86       dyn = g_object_new (GTK_TYPE_ACTION,
87                           "name", "dyn2",
88                           "label", "Dynamic action 2",
89                           "stock_id", GTK_STOCK_EXECUTE,
90                           NULL);
91       gtk_action_group_add_action (dynamic, dyn);
92     }
93   
94   if (merge_id == 0)
95     {
96       merge_id = gtk_ui_manager_new_merge_id (merge);
97       gtk_ui_manager_add_ui (merge, merge_id, "/toolbar1/ToolbarPlaceholder", 
98                              "dyn1", "dyn1", 0, 0);
99       gtk_ui_manager_add_ui (merge, merge_id, "/toolbar1/ToolbarPlaceholder", 
100                              "dynsep", NULL, GTK_UI_MANAGER_SEPARATOR, 0);
101       gtk_ui_manager_add_ui (merge, merge_id, "/toolbar1/ToolbarPlaceholder", 
102                              "dyn2", "dyn2", 0, 0);
103
104       gtk_ui_manager_add_ui (merge, merge_id, "/menubar/EditMenu", 
105                              "dyn1menu", "dyn1", GTK_UI_MANAGER_MENU, 0);
106       gtk_ui_manager_add_ui (merge, merge_id, "/menubar/EditMenu/dyn1menu", 
107                              "dyn1", "dyn1", GTK_UI_MANAGER_MENUITEM, 0);
108       gtk_ui_manager_add_ui (merge, merge_id, "/menubar/EditMenu/dyn1menu/dyn1", 
109                              "dyn2", "dyn2", GTK_UI_MANAGER_AUTO, FALSE);
110     }
111   else 
112     {
113       gtk_ui_manager_remove_ui (merge, merge_id);
114       merge_id = 0;
115     }
116
117   return FALSE;
118 }
119
120 static void
121 toggle_dynamic (GtkWidget    *button, 
122                 GtkUIManager *merge)
123 {
124   g_timeout_add (2000, (GSourceFunc)delayed_toggle_dynamic, merge);
125 }
126
127 static void
128 activate_action (GtkAction *action)
129 {
130   const gchar *name = gtk_action_get_name (action);
131   const gchar *typename = G_OBJECT_TYPE_NAME (action);
132
133   g_message ("Action %s (type=%s) activated", name, typename);
134 }
135
136 static void
137 toggle_action (GtkAction *action)
138 {
139   const gchar *name = gtk_action_get_name (action);
140   const gchar *typename = G_OBJECT_TYPE_NAME (action);
141
142   g_message ("ToggleAction %s (type=%s) toggled (active=%d)", name, typename,
143              gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
144 }
145
146
147 static void
148 radio_action_changed (GtkAction *action, GtkRadioAction *current)
149 {
150   g_message ("RadioAction %s (type=%s) activated (active=%d) (value %d)", 
151              gtk_action_get_name (GTK_ACTION (current)), 
152              G_OBJECT_TYPE_NAME (GTK_ACTION (current)),
153              gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (current)),
154              gtk_radio_action_get_current_value (current));
155 }
156
157 static GtkActionEntry entries[] = {
158   { "FileMenuAction", NULL, "_File" },
159   { "EditMenuAction", NULL, "_Edit" },
160   { "HelpMenuAction", NULL, "_Help" },
161   { "JustifyMenuAction", NULL, "_Justify" },
162   { "EmptyMenu1Action", NULL, "Empty 1" },
163   { "EmptyMenu2Action", NULL, "Empty 2" },
164   { "Test", NULL, "Test" },
165
166   { "QuitAction",  GTK_STOCK_QUIT,  NULL,     "<control>q", "Quit", G_CALLBACK (gtk_main_quit) },
167   { "NewAction",   GTK_STOCK_NEW,   NULL,     "<control>n", "Create something", G_CALLBACK (activate_action) },
168   { "New2Action",  GTK_STOCK_NEW,   NULL,     "<control>m", "Create something else", G_CALLBACK (activate_action) },
169   { "OpenAction",  GTK_STOCK_OPEN,  NULL,     NULL,         "Open it", G_CALLBACK (activate_action) },
170   { "CutAction",   GTK_STOCK_CUT,   NULL,     "<control>x", "Knive", G_CALLBACK (activate_action) },
171   { "CopyAction",  GTK_STOCK_COPY,  NULL,     "<control>c", "Copy", G_CALLBACK (activate_action) },
172   { "PasteAction", GTK_STOCK_PASTE, NULL,     "<control>v", "Paste", G_CALLBACK (activate_action) },
173   { "AboutAction", NULL,            "_About", NULL,         "About", G_CALLBACK (activate_action) },
174 };
175 static guint n_entries = G_N_ELEMENTS (entries);
176
177 static GtkToggleActionEntry toggle_entries[] = {
178   { "BoldAction",  GTK_STOCK_BOLD,  "_Bold",  "<control>b", "Make it bold", G_CALLBACK (toggle_action), 
179     TRUE },
180 };
181 static guint n_toggle_entries = G_N_ELEMENTS (toggle_entries);
182
183 enum {
184   JUSTIFY_LEFT,
185   JUSTIFY_CENTER,
186   JUSTIFY_RIGHT,
187   JUSTIFY_FILL
188 };
189
190 static GtkRadioActionEntry radio_entries[] = {
191   { "justify-left", GTK_STOCK_JUSTIFY_LEFT, NULL, "<control>L", 
192     "Left justify the text", JUSTIFY_LEFT },
193   { "justify-center", GTK_STOCK_JUSTIFY_CENTER, NULL, "<control>E",
194     "Center justify the text", JUSTIFY_CENTER },
195   { "justify-right", GTK_STOCK_JUSTIFY_RIGHT, NULL, "<control>R",
196     "Right justify the text", JUSTIFY_RIGHT },
197   { "justify-fill", GTK_STOCK_JUSTIFY_FILL, NULL, "<control>J",
198     "Fill justify the text", JUSTIFY_FILL },
199 };
200 static guint n_radio_entries = G_N_ELEMENTS (radio_entries);
201
202 static void
203 add_widget (GtkUIManager *merge, 
204             GtkWidget    *widget, 
205             GtkBox       *box)
206 {
207   GtkWidget *handle_box;
208
209   if (GTK_IS_TOOLBAR (widget))
210     {
211       handle_box = gtk_handle_box_new ();
212       gtk_widget_show (handle_box);
213       gtk_container_add (GTK_CONTAINER (handle_box), widget);
214       gtk_box_pack_start (box, handle_box, FALSE, FALSE, 0);
215       g_signal_connect_swapped (widget, "destroy", 
216                                 G_CALLBACK (gtk_widget_destroy), handle_box);
217     }
218   else
219     gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
220     
221   gtk_widget_show (widget);
222 }
223
224 static void
225 toggle_merge (GtkWidget    *button, 
226               GtkUIManager *merge)
227 {
228   gint mergenum;
229
230   mergenum = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), "mergenum"));
231
232   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
233     {
234       GError *err = NULL;
235
236       g_message ("merging %s", merge_ids[mergenum].filename);
237       merge_ids[mergenum].merge_id =
238         gtk_ui_manager_add_ui_from_file (merge, merge_ids[mergenum].filename, &err);
239       if (err != NULL)
240         {
241           GtkWidget *dialog;
242
243           dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (button)),
244                                            0, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
245                                            "could not merge %s: %s", merge_ids[mergenum].filename,
246                                            err->message);
247
248           g_signal_connect (dialog, "response", G_CALLBACK (gtk_object_destroy), NULL);
249           gtk_widget_show (dialog);
250
251           g_clear_error (&err);
252         }
253     }
254   else
255     {
256       g_message ("unmerging %s (merge_id=%u)", merge_ids[mergenum].filename,
257                  merge_ids[mergenum].merge_id);
258       gtk_ui_manager_remove_ui (merge, merge_ids[mergenum].merge_id);
259     }
260 }
261
262 static void  
263 set_name_func (GtkTreeViewColumn *tree_column,
264                GtkCellRenderer   *cell,
265                GtkTreeModel      *tree_model,
266                GtkTreeIter       *iter,
267                gpointer           data)
268 {
269   GtkAction *action;
270   char *name;
271   
272   gtk_tree_model_get (tree_model, iter, 0, &action, -1);
273   g_object_get (action, "name", &name, NULL);
274   g_object_set (cell, "text", name, NULL);
275   g_free (name);
276   g_object_unref (action);
277 }
278
279 static void
280 set_sensitive_func (GtkTreeViewColumn *tree_column,
281                     GtkCellRenderer   *cell,
282                     GtkTreeModel      *tree_model,
283                     GtkTreeIter       *iter,
284                     gpointer           data)
285 {
286   GtkAction *action;
287   gboolean sensitive;
288   
289   gtk_tree_model_get (tree_model, iter, 0, &action, -1);
290   g_object_get (action, "sensitive", &sensitive, NULL);
291   g_object_set (cell, "active", sensitive, NULL);
292   g_object_unref (action);
293 }
294
295
296 static void
297 set_visible_func (GtkTreeViewColumn *tree_column,
298                   GtkCellRenderer   *cell,
299                   GtkTreeModel      *tree_model,
300                   GtkTreeIter       *iter,
301                   gpointer           data)
302 {
303   GtkAction *action;
304   gboolean visible;
305   
306   gtk_tree_model_get (tree_model, iter, 0, &action, -1);
307   g_object_get (action, "visible", &visible, NULL);
308   g_object_set (cell, "active", visible, NULL);
309   g_object_unref (action);
310 }
311
312 static void
313 sensitivity_toggled (GtkCellRendererToggle *cell, 
314                      const gchar           *path_str,
315                      GtkTreeModel          *model)
316 {
317   GtkTreePath *path;
318   GtkTreeIter iter;
319   GtkAction *action;
320   gboolean sensitive;
321
322   path = gtk_tree_path_new_from_string (path_str);
323   gtk_tree_model_get_iter (model, &iter, path);
324
325   gtk_tree_model_get (model, &iter, 0, &action, -1);
326   g_object_get (action, "sensitive", &sensitive, NULL);
327   g_object_set (action, "sensitive", !sensitive, NULL);
328   gtk_tree_model_row_changed (model, path, &iter);
329   gtk_tree_path_free (path);
330 }
331
332 static void
333 visibility_toggled (GtkCellRendererToggle *cell, 
334                     const gchar           *path_str, 
335                     GtkTreeModel          *model)
336 {
337   GtkTreePath *path;
338   GtkTreeIter iter;
339   GtkAction *action;
340   gboolean visible;
341
342   path = gtk_tree_path_new_from_string (path_str);
343   gtk_tree_model_get_iter (model, &iter, path);
344
345   gtk_tree_model_get (model, &iter, 0, &action, -1);
346   g_object_get (action, "visible", &visible, NULL);
347   g_object_set (action, "visible", !visible, NULL);
348   gtk_tree_model_row_changed (model, path, &iter);
349   gtk_tree_path_free (path);
350 }
351
352 static gint
353 iter_compare_func (GtkTreeModel *model, 
354                    GtkTreeIter  *a, 
355                    GtkTreeIter  *b,
356                    gpointer      user_data)
357 {
358   GValue a_value = { 0, }, b_value = { 0, };
359   GtkAction *a_action, *b_action;
360   const gchar *a_name, *b_name;
361   gint retval = 0;
362
363   gtk_tree_model_get_value (model, a, 0, &a_value);
364   gtk_tree_model_get_value (model, b, 0, &b_value);
365   a_action = GTK_ACTION (g_value_get_object (&a_value));
366   b_action = GTK_ACTION (g_value_get_object (&b_value));
367
368   a_name = gtk_action_get_name (a_action);
369   b_name = gtk_action_get_name (b_action);
370   if (a_name == NULL && b_name == NULL) 
371     retval = 0;
372   else if (a_name == NULL)
373     retval = -1;
374   else if (b_name == NULL) 
375     retval = 1;
376   else 
377     retval = strcmp (a_name, b_name);
378
379   g_value_unset (&b_value);
380   g_value_unset (&a_value);
381
382   return retval;
383 }
384
385 static GtkWidget *
386 create_tree_view (GtkUIManager *merge)
387 {
388   GtkWidget *tree_view, *sw;
389   GtkListStore *store;
390   GList *p;
391   GtkCellRenderer *cell;
392   
393   store = gtk_list_store_new (1, GTK_TYPE_ACTION);
394   gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store), 0,
395                                    iter_compare_func, NULL, NULL);
396   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), 0,
397                                         GTK_SORT_ASCENDING);
398   
399   for (p = gtk_ui_manager_get_action_groups (merge); p; p = p->next)
400     {
401       GList *actions, *l;
402
403       actions = gtk_action_group_list_actions (p->data);
404
405       for (l = actions; l; l = l->next)
406         {
407           GtkTreeIter iter;
408
409           gtk_list_store_append (store, &iter);
410           gtk_list_store_set (store, &iter, 0, l->data, -1);
411         }
412     }
413   
414   tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
415   g_object_unref (store);
416
417   gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (tree_view),
418                                               -1, "Action",
419                                               gtk_cell_renderer_text_new (),
420                                               set_name_func, NULL, NULL);
421
422   gtk_tree_view_column_set_sort_column_id (gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), 0), 0);
423
424   cell = gtk_cell_renderer_toggle_new ();
425   g_signal_connect (cell, "toggled", G_CALLBACK (sensitivity_toggled), store);
426   gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (tree_view),
427                                               -1, "Sensitive",
428                                               cell,
429                                               set_sensitive_func, NULL, NULL);
430
431   cell = gtk_cell_renderer_toggle_new ();
432   g_signal_connect (cell, "toggled", G_CALLBACK (visibility_toggled), store);
433   gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (tree_view),
434                                               -1, "Visible",
435                                               cell,
436                                               set_visible_func, NULL, NULL);
437
438   sw = gtk_scrolled_window_new (NULL, NULL);
439   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
440                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
441   gtk_container_add (GTK_CONTAINER (sw), tree_view);
442   
443   return sw;
444 }
445
446 static gboolean
447 area_press (GtkWidget      *drawing_area,
448             GdkEventButton *event,
449             GtkUIManager   *merge)
450 {
451   gtk_widget_grab_focus (drawing_area);
452
453   if (event->button == 3 &&
454       event->type == GDK_BUTTON_PRESS)
455     {
456       GtkWidget *menu = gtk_ui_manager_get_widget (merge, "/FileMenu");
457       
458       if (GTK_IS_MENU (menu)) 
459         {
460           gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
461                           NULL, drawing_area,
462                           3, event->time);
463           return TRUE;
464         }
465     }
466
467   return FALSE;
468   
469 }
470
471 static void
472 activate_path (GtkWidget      *button,
473                GtkUIManager   *merge)
474 {
475   GtkAction *action = gtk_ui_manager_get_action (merge, 
476                                                  "/menubar/HelpMenu/About");
477   if (action)
478     gtk_action_activate (action);
479   else 
480     g_message ("no action found");
481 }
482
483 typedef struct _ActionStatus ActionStatus;
484
485 struct _ActionStatus {
486   GtkAction *action;
487   GtkWidget *statusbar;
488 };
489
490 static void
491 action_status_destroy (gpointer data)
492 {
493   ActionStatus *action_status = data;
494
495   g_object_unref (action_status->action);
496   g_object_unref (action_status->statusbar);
497
498   g_free (action_status);
499 }
500
501 static void
502 set_tip (GtkWidget *widget)
503 {
504   ActionStatus *data;
505   gchar *tooltip;
506   
507   data = g_object_get_data (G_OBJECT (widget), "action-status");
508   
509   if (data) 
510     {
511       g_object_get (data->action, "tooltip", &tooltip, NULL);
512       
513       gtk_statusbar_push (GTK_STATUSBAR (data->statusbar), 0, 
514                           tooltip ? tooltip : "");
515       
516       g_free (tooltip);
517     }
518 }
519
520 static void
521 unset_tip (GtkWidget *widget)
522 {
523   ActionStatus *data;
524
525   data = g_object_get_data (G_OBJECT (widget), "action-status");
526
527   if (data)
528     gtk_statusbar_pop (GTK_STATUSBAR (data->statusbar), 0);
529 }
530                     
531 static void
532 connect_proxy (GtkUIManager *merge,
533                GtkAction    *action,
534                GtkWidget    *proxy,
535                GtkWidget    *statusbar)
536 {
537   if (GTK_IS_MENU_ITEM (proxy)) 
538     {
539       ActionStatus *data;
540
541       data = g_object_get_data (G_OBJECT (proxy), "action-status");
542       if (data)
543         {
544           g_object_unref (data->action);
545           g_object_unref (data->statusbar);
546
547           data->action = g_object_ref (action);
548           data->statusbar = g_object_ref (statusbar);
549         }
550       else
551         {
552           data = g_new0 (ActionStatus, 1);
553
554           data->action = g_object_ref (action);
555           data->statusbar = g_object_ref (statusbar);
556
557           g_object_set_data_full (G_OBJECT (proxy), "action-status", 
558                                   data, action_status_destroy);
559           
560           g_signal_connect (proxy, "select",  G_CALLBACK (set_tip), NULL);
561           g_signal_connect (proxy, "deselect", G_CALLBACK (unset_tip), NULL);
562         }
563     }
564 }
565
566 int
567 main (int argc, char **argv)
568 {
569   GtkActionGroup *action_group;
570   GtkAction *action;
571   GtkUIManager *merge;
572   GtkWidget *window, *table, *frame, *menu_box, *vbox, *view;
573   GtkWidget *button, *area, *statusbar;
574   gint i;
575   
576   gtk_init (&argc, &argv);
577
578   action_group = gtk_action_group_new ("TestActions");
579   gtk_action_group_add_actions (action_group, 
580                                 entries, n_entries, 
581                                 NULL);
582   action = gtk_action_group_get_action (action_group, "EmptyMenu1Action");
583   g_object_set (action, "hide_if_empty", FALSE, NULL);
584   action = gtk_action_group_get_action (action_group, "EmptyMenu2Action");
585   g_object_set (action, "hide_if_empty", TRUE, NULL);
586   gtk_action_group_add_toggle_actions (action_group, 
587                                        toggle_entries, n_toggle_entries, 
588                                        NULL);
589   gtk_action_group_add_radio_actions (action_group, 
590                                       radio_entries, n_radio_entries, 
591                                       JUSTIFY_RIGHT,
592                                       G_CALLBACK (radio_action_changed), NULL);
593
594   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
595   gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
596   g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
597
598   table = gtk_table_new (2, 2, FALSE);
599   gtk_table_set_row_spacings (GTK_TABLE (table), 2);
600   gtk_table_set_col_spacings (GTK_TABLE (table), 2);
601   gtk_container_set_border_width (GTK_CONTAINER (table), 2);
602   gtk_container_add (GTK_CONTAINER (window), table);
603
604   frame = gtk_frame_new ("Menus and Toolbars");
605   gtk_table_attach (GTK_TABLE (table), frame, 0,2, 1,2,
606                     GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
607   
608   menu_box = gtk_vbox_new (FALSE, 0);
609   gtk_container_set_border_width (GTK_CONTAINER (menu_box), 2);
610   gtk_container_add (GTK_CONTAINER (frame), menu_box);
611
612   statusbar = gtk_statusbar_new ();
613   gtk_box_pack_end (GTK_BOX (menu_box), statusbar, FALSE, FALSE, 0);
614     
615   area = gtk_drawing_area_new ();
616   gtk_widget_set_events (area, GDK_BUTTON_PRESS_MASK);
617   gtk_widget_set_size_request (area, -1, 40);
618   gtk_box_pack_end (GTK_BOX (menu_box), area, FALSE, FALSE, 0);
619   gtk_widget_show (area);
620
621   button = gtk_button_new ();
622   gtk_box_pack_end (GTK_BOX (menu_box), button, FALSE, FALSE, 0);
623   gtk_action_connect_proxy (gtk_action_group_get_action (action_group, "AboutAction"), 
624                             button);
625   gtk_widget_show (button);
626
627   button = gtk_check_button_new ();
628   gtk_box_pack_end (GTK_BOX (menu_box), button, FALSE, FALSE, 0);
629   gtk_action_connect_proxy (gtk_action_group_get_action (action_group, "BoldAction"), 
630                             button);
631   gtk_widget_show (button);
632
633   merge = gtk_ui_manager_new ();
634
635   g_signal_connect (merge, "connect-proxy", G_CALLBACK (connect_proxy), statusbar);
636   g_signal_connect (area, "button_press_event", G_CALLBACK (area_press), merge);
637
638   gtk_ui_manager_insert_action_group (merge, action_group, 0);
639   g_signal_connect (merge, "add_widget", G_CALLBACK (add_widget), menu_box);
640
641   gtk_window_add_accel_group (GTK_WINDOW (window), 
642                               gtk_ui_manager_get_accel_group (merge));
643   
644   frame = gtk_frame_new ("UI Files");
645   gtk_table_attach (GTK_TABLE (table), frame, 0,1, 0,1,
646                     GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
647
648   vbox = gtk_vbox_new (FALSE, 2);
649   gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
650   gtk_container_add (GTK_CONTAINER (frame), vbox);
651
652   for (i = 0; i < G_N_ELEMENTS (merge_ids); i++)
653     {
654       button = gtk_check_button_new_with_label (merge_ids[i].filename);
655       g_object_set_data (G_OBJECT (button), "mergenum", GINT_TO_POINTER (i));
656       g_signal_connect (button, "toggled", G_CALLBACK (toggle_merge), merge);
657       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
658       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
659     }
660
661   button = gtk_check_button_new_with_label ("Tearoffs");
662   g_signal_connect (button, "clicked", G_CALLBACK (toggle_tearoffs), merge);
663   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
664
665   button = gtk_check_button_new_with_label ("Dynamic");
666   g_signal_connect (button, "clicked", G_CALLBACK (toggle_dynamic), merge);
667   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
668
669   button = gtk_button_new_with_label ("Activate path");
670   g_signal_connect (button, "clicked", G_CALLBACK (activate_path), merge);
671   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
672
673   button = gtk_button_new_with_label ("Dump Tree");
674   g_signal_connect (button, "clicked", G_CALLBACK (dump_tree), merge);
675   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
676
677   button = gtk_button_new_with_label ("Dump Toplevels");
678   g_signal_connect (button, "clicked", G_CALLBACK (dump_toplevels), merge);
679   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
680
681   button = gtk_button_new_with_label ("Dump Accels");
682   g_signal_connect (button, "clicked", G_CALLBACK (dump_accels), NULL);
683   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
684
685   view = create_tree_view (merge);
686   gtk_table_attach (GTK_TABLE (table), view, 1,2, 0,1,
687                     GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
688
689   gtk_widget_show_all (window);
690   gtk_main ();
691
692 #ifdef DEBUG_UI_MANAGER
693   {
694     GList *action;
695     
696     g_print ("\n> before unreffing the ui manager <\n");
697     for (action = gtk_action_group_list_actions (action_group);
698          action; 
699          action = action->next)
700       {
701         GtkAction *a = action->data;
702         g_print ("  action %s ref count %d\n", 
703                  gtk_action_get_name (a), G_OBJECT (a)->ref_count);
704       }
705   }
706 #endif
707
708   g_object_unref (merge);
709
710 #ifdef DEBUG_UI_MANAGER
711   {
712     GList *action;
713
714     g_print ("\n> after unreffing the ui manager <\n");
715     for (action = gtk_action_group_list_actions (action_group);
716          action; 
717          action = action->next)
718       {
719         GtkAction *a = action->data;
720         g_print ("  action %s ref count %d\n", 
721                  gtk_action_get_name (a), G_OBJECT (a)->ref_count);
722       }
723   }
724 #endif
725
726   g_object_unref (action_group);
727
728   return 0;
729 }