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