]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/mathml_editor/test/guiGTK.c
* using non-diffing mathml factory
[helm.git] / helm / DEVEL / mathml_editor / test / guiGTK.c
1 /* This file is part of EdiTeX, an editor of mathematical
2  * expressions based on TeX syntax.
3  * 
4  * Copyright (C) 2002-2003 Luca Padovani <lpadovan@cs.unibo.it>,
5  *                    2003 Paolo Marinelli <pmarinel@cs.unibo.it>.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * For more information, please visit the project's home page
22  * http://helm.cs.unibo.it/editex/
23  * or send an email to <lpadovan@cs.unibo.it>
24  */
25
26 #include <config.h>
27 #include <stdio.h>
28 #include <gtk/gtk.h>
29 #include <gdk/gdkkeysyms.h>
30
31 #include <gtkmathview.h>
32 #include "guiGTK.h"
33
34 #define XLINK_NS_URI "http://www.w3.org/1999/xlink"
35
36 static GtkWidget* window;
37 static GtkWidget* main_area;
38 static GtkWidget* scrolled_area;
39
40 static gpointer context = NULL;
41 static gchar* doc_name = NULL;
42 static GdomeElement* first_selected = NULL;
43 static GdomeElement* root_selected = NULL;
44
45 static void create_widget_set(gpointer);
46 static GtkWidget* get_main_menu(void);
47 static void file_open(GtkWidget*, gpointer);
48 static void file_re_open(GtkWidget*, gpointer);
49 static void file_close(GtkWidget*, gpointer);
50 static void file_output_tex(GtkWidget*, gpointer);
51 static void options_set_font_size(GtkWidget*, gpointer);
52 static void options_change_font_size(GtkWidget*, gboolean);
53 static void options_verbosity(GtkWidget*, guint);
54 static void edit_delete_selection(GtkWidget*, gpointer);
55 static void edit_select_parent(GtkWidget*, gpointer);
56 static void edit_reset_selection(GtkWidget*, gpointer);
57 static void edit_reset(GtkWidget*, gpointer);
58 static void edit_insert(GtkWidget*, gpointer);
59 static void help_about(GtkWidget*, gpointer);
60
61 static GtkItemFactoryEntry menu_items[] = {
62   { "/_File",                          NULL,         NULL,          0, "<Branch>" },
63   { "/File/_Open...",                  "<control>O", file_open,     0, NULL },
64   { "/File/_Reopen",                   NULL,         file_re_open,  0, NULL },
65   { "/File/_Close",                    "<control>W", file_close,    0, NULL },
66   { "/File/Output _TeX",               NULL,         file_output_tex, 0, NULL },
67   { "/File/sep1",                      NULL,         NULL,          0, "<Separator>" },
68   { "/File/_Quit",                     "<control>Q", gtk_main_quit, 0, NULL },
69
70   { "/_Edit",                          NULL, NULL,                  0,  "<Branch>" },
71   { "/Edit/Reset Selection",           NULL, edit_reset_selection,  0, NULL },
72   { "/Edit/Delete Selection",          NULL, edit_delete_selection, 0, NULL },
73   { "/Edit/Select Parent",             NULL, edit_select_parent,    0, NULL },
74   { "/Edit/sep1",                      NULL,         NULL,          0, "<Separator>" },
75   { "/Edit/_Reset",                    NULL, edit_reset,            0, NULL },
76   { "/Edit/Insert...",                 "<control>I", edit_insert,   0, NULL },
77
78   { "/_Options",                       NULL, NULL,                  0,  "<Branch>" },
79   { "/Options/Default _Font Size",     NULL, NULL,                  0,  "<Branch>" },
80   { "/Options/Default Font Size/Set...", NULL, options_set_font_size, 0,  NULL },
81   { "/Options/Default Font Size/sep1", NULL, NULL,                  0,  "<Separator>" },
82   { "/Options/Default Font Size/Larger", NULL, options_change_font_size, TRUE, NULL },
83   { "/Options/Default Font Size/Smaller", NULL, options_change_font_size, FALSE, NULL },
84   { "/Options/Verbosity",              NULL, NULL,                  0,  "<Branch>" },
85   { "/Options/Verbosity/_Errors",      NULL, options_verbosity,     0,  "<RadioItem>" },
86   { "/Options/Verbosity/_Warnings",    NULL, options_verbosity,     1,  "/Options/Verbosity/Errors" },
87   { "/Options/Verbosity/_Info",        NULL, options_verbosity,     2,  "/Options/Verbosity/Errors" },
88   { "/Options/Verbosity/_Debug",       NULL, options_verbosity,     3,  "/Options/Verbosity/Errors" },
89   { "/Options/sep1",                   NULL, NULL,                  0,  "<Separator>" },
90
91   { "/_Help" ,        NULL,         NULL,          0, "<LastBranch>" },
92   { "/Help/About...", NULL,         help_about,    0, NULL }
93 };
94
95 static void
96 quick_message(const char* msg)
97 {
98   GtkWidget* dialog;
99   GtkWidget* label;
100   GtkWidget* okay_button;
101      
102   /* Create the widgets */
103      
104   dialog = gtk_dialog_new();
105   label = gtk_label_new (msg);
106   okay_button = gtk_button_new_with_label("OK");
107
108   gtk_widget_set_usize(dialog, 300, 100);
109
110   /* Ensure that the dialog box is destroyed when the user clicks ok. */
111      
112   gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked",
113                              GTK_SIGNAL_FUNC (gtk_widget_destroy), dialog);
114   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
115                      okay_button);
116   
117   /* Add the label, and show everything we've added to the dialog. */
118   
119   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
120   gtk_widget_show_all (dialog);
121 }
122
123 static void
124 load_error_msg(const char* name)
125 {
126   char* msg = g_strdup_printf("Could not load\n`%s'", name);
127   quick_message(msg);
128   g_free(msg);
129 }
130
131 static guint edit_timeout_id;
132 extern void edit_timeout(gpointer);
133
134 void
135 GUI_init(int* argc, char*** argv, char* title, guint width, guint height, gpointer c)
136 {
137   gtk_init(argc, argv);
138
139   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
140   gtk_window_set_title(GTK_WINDOW(window), title);
141   gtk_window_set_default_size(GTK_WINDOW(window), width, height);
142   gtk_signal_connect(GTK_OBJECT(window), "delete_event", (GtkSignalFunc) gtk_main_quit, NULL);
143   create_widget_set(context);
144
145   gtk_widget_show(window);
146
147   context = c;
148   /*edit_timeout_id = gtk_timeout_add(50, edit_timeout, context);*/
149 }
150
151 void
152 GUI_uninit()
153 {
154   GdomeException exc = 0;
155
156   if (first_selected != NULL)
157     {
158       gdome_el_unref(first_selected, &exc);
159       g_assert(exc == 0);
160       first_selected = NULL;
161     }
162
163   if (root_selected != NULL)
164     {
165       gdome_el_unref(root_selected, &exc);
166       g_assert(exc == 0);
167       root_selected = NULL;
168     }
169
170   context = NULL;
171 }
172
173 int
174 GUI_load_document(GdomeDocument* doc)
175 {
176   GtkMathView* math_view;
177
178   g_return_val_if_fail(doc != NULL, -1);
179   g_return_val_if_fail(main_area != NULL, -1);
180   g_return_val_if_fail(GTK_IS_MATH_VIEW(main_area), -1);
181
182   math_view = GTK_MATH_VIEW(main_area);
183
184   if (!gtk_math_view_load_doc(math_view, doc)) return -1;
185
186   return 0;
187 }
188
189 void
190 GUI_freeze()
191 {
192   gtk_math_view_freeze(GTK_MATH_VIEW(main_area));
193 }
194
195 void
196 GUI_thaw()
197 {
198   gtk_math_view_thaw(GTK_MATH_VIEW(main_area));
199 }
200
201 void
202 GUI_unload_document()
203 {
204   GtkMathView* math_view;
205
206   g_return_if_fail(main_area != NULL);
207   g_return_if_fail(GTK_IS_MATH_VIEW(main_area));
208
209   math_view = GTK_MATH_VIEW(main_area);
210
211   gtk_math_view_load_root(math_view, 0);
212
213   if (doc_name != NULL) g_free(doc_name);
214   doc_name = NULL;
215 }
216
217 void
218 GUI_run()
219 {
220   gtk_main();
221 }
222
223 #if 0
224 void
225 GUI_set_font_manager(FontManagerId id)
226 {
227   gboolean t1;
228   GtkMathView* math_view;
229
230   g_return_if_fail(id != FONT_MANAGER_UNKNOWN);
231   g_return_if_fail(main_area != NULL);
232   g_return_if_fail(GTK_IS_MATH_VIEW(main_area));
233
234   t1 = id == FONT_MANAGER_T1;
235
236   math_view = GTK_MATH_VIEW(main_area);
237
238   gtk_math_view_freeze(math_view);
239
240   if (id != gtk_math_view_get_font_manager_type(math_view))
241     gtk_math_view_set_font_manager_type(math_view, id);
242
243   gtk_widget_set_sensitive(anti_aliasing(math_view, GTK_CHECK_MENU_ITEM(anti_aliasing_item)->active);
244       gtk_math_view_set_transparency(math_view, GTK_CHECK_MENU_ITEM(transparency_item)->active);
245     }
246
247   gtk_math_view_thaw(math_view);
248 }
249 #endif
250
251 static void
252 store_filename(GtkFileSelection* selector, GtkWidget* user_data)
253 {
254   gchar* selected_filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION(user_data));
255   if (selected_filename != NULL)
256     GUI_load_document(selected_filename);
257 }
258
259 static void
260 file_close(GtkWidget* widget, gpointer data)
261 {
262   GUI_unload_document();
263 }
264
265 static void
266 file_re_open(GtkWidget* widget, gpointer data)
267 {
268   if (doc_name != NULL) {
269     GUI_load_document(doc_name);
270   }
271 }
272
273 static void
274 file_open(GtkWidget* widget, gpointer data)
275 {
276   GtkWidget* fs = gtk_file_selection_new("Open File");
277
278   gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button),
279                       "clicked", GTK_SIGNAL_FUNC (store_filename), (gpointer) fs);
280                              
281   /* Ensure that the dialog box is destroyed when the user clicks a button. */
282      
283   gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button),
284                              "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
285                              (gpointer) fs);
286
287   gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(fs)->cancel_button),
288                              "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
289                              (gpointer) fs);
290      
291   /* Display that dialog */
292      
293   gtk_widget_show (fs);
294 }
295
296 static void
297 file_output_tex(GtkWidget* widget, gpointer data)
298 {
299   g_assert(context != NULL);
300   edit_output_tex(context);
301 }
302
303 #if 0
304 static void
305 options_font_manager(GtkWidget* widget, FontManagerId id)
306 {
307   g_return_if_fail(id != FONT_MANAGER_UNKNOWN);
308   GUI_set_font_manager(id);
309 }
310 #endif
311
312 static void
313 options_verbosity(GtkWidget* widget, guint level)
314 {
315   gtk_math_view_set_log_verbosity(GTK_MATH_VIEW(main_area), level);
316 }
317
318 static void
319 edit_delete_selection(GtkWidget* widget, gpointer data)
320 {
321   if (root_selected != NULL)
322     {
323       GdomeException exc;
324       gtk_math_view_freeze(GTK_MATH_VIEW(main_area));
325       printf("about to remove element %p\n", root_selected);
326       delete_element(root_selected);
327       gdome_el_unref(root_selected, &exc);
328       g_assert(exc == 0);
329       root_selected = NULL;
330       gtk_math_view_thaw(GTK_MATH_VIEW(main_area));
331     }
332 }
333
334 static void
335 edit_select_parent(GtkWidget* widget, gpointer data)
336 {
337   if (root_selected != NULL)
338     {
339       GdomeException exc = 0;
340       GdomeElement* parent = gdome_n_parentNode(root_selected, &exc);
341       g_assert(exc == 0);
342       gdome_el_unref(root_selected, &exc);
343       g_assert(exc == 0);
344       root_selected = parent;
345       /* gtk_math_view_set_selection(GTK_MATH_VIEW(main_area), root_selected); */
346     }
347 }
348
349 static void
350 edit_reset_selection(GtkWidget* widget, gpointer data)
351 {
352   if (root_selected != NULL)
353     {
354       GdomeException exc = 0;
355       /* gtk_math_view_reset_selection(GTK_MATH_VIEW(main_area), root_selected); */
356       gdome_el_unref(root_selected, &exc);
357       g_assert(exc == 0);
358       root_selected = NULL;
359     }
360 }
361
362 static void
363 edit_reset(GtkWidget* widget, gpointer data)
364 {
365   g_assert(context != NULL);
366   edit_reset_tex(context);
367 }
368
369 static void
370 insert_tex(GtkWidget* widget, GtkEntry* entry)
371 {
372   gchar* text;
373   g_return_if_fail(entry != NULL);
374
375   text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
376   edit_push_string(context, text);
377   g_free(text);
378 }
379
380 static void
381 edit_insert(GtkWidget* widget, gpointer data)
382 {
383   GtkWidget* dialog;
384   GtkWidget* entry;
385   GtkWidget* ok;
386   GtkWidget* cancel;
387
388   dialog = gtk_dialog_new();
389   entry = gtk_entry_new();
390   ok = gtk_button_new_with_label("OK");
391   cancel = gtk_button_new_with_label("Cancel");
392
393   gtk_signal_connect (GTK_OBJECT (ok), "clicked",
394                       GTK_SIGNAL_FUNC (insert_tex), (gpointer) entry);
395
396   gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
397                              GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
398
399   gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
400                              GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
401
402   gtk_signal_connect_object (GTK_OBJECT (cancel), "clicked",
403                              GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
404
405   gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), 5);
406
407   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), entry);
408   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), ok);
409   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), cancel);
410
411   gtk_widget_show_all (dialog);
412 }
413
414 static void
415 help_about(GtkWidget* widget, gpointer data)
416 {
417   GtkWidget* dialog;
418   GtkWidget* label;
419   GtkWidget* ok;
420
421   dialog = gtk_dialog_new();
422   label = gtk_label_new("\n    MathML Editor    \n    Copyright (C) 2003 Luca Padovani    \n");
423   ok = gtk_button_new_with_label("Close");
424
425   gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
426                              GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
427   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
428                      ok);
429
430   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
431
432   gtk_widget_show_all (dialog);
433 }
434
435 static void
436 change_default_font_size(GtkWidget* widget, GtkSpinButton* spin)
437 {
438   g_return_if_fail(spin != NULL);
439   gtk_math_view_set_font_size( GTK_MATH_VIEW(main_area), gtk_spin_button_get_value_as_int(spin));
440 }
441
442 static void
443 options_change_font_size(GtkWidget* widget, gboolean larger)
444 {
445   gfloat size = gtk_math_view_get_font_size (GTK_MATH_VIEW(main_area));
446   if (larger) size = size / 0.71;
447   else size = size * 0.71;
448   if (size < 1) size = 1;
449   gtk_math_view_set_font_size (GTK_MATH_VIEW(main_area), (gint) size + 0.5);
450 }
451
452 static void
453 options_set_font_size(GtkWidget* widget, gpointer data)
454 {
455   GtkWidget* dialog;
456   GtkWidget* label;
457   GtkWidget* ok;
458   GtkWidget* cancel;
459   GtkWidget* spin;
460   GtkObject* adj;
461
462   dialog = gtk_dialog_new();
463   label = gtk_label_new("Default font size:");
464   ok = gtk_button_new_with_label("OK");
465   cancel = gtk_button_new_with_label("Cancel");
466
467   adj = gtk_adjustment_new (gtk_math_view_get_font_size (GTK_MATH_VIEW(main_area)), 1, 200, 1, 1, 1);
468   spin = gtk_spin_button_new (GTK_ADJUSTMENT(adj), 1, 0);
469   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spin), TRUE);
470
471   gtk_signal_connect (GTK_OBJECT (ok), "clicked",
472                       GTK_SIGNAL_FUNC (change_default_font_size), (gpointer) spin);
473
474   gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
475                              GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
476
477   gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
478                              GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
479
480   gtk_signal_connect_object (GTK_OBJECT (cancel), "clicked",
481                              GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
482
483   gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), 5);
484
485   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), ok);
486   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), cancel);
487   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
488   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), spin);
489
490   gtk_widget_show_all (dialog);
491 }
492
493 static void
494 select_begin(GtkMathView* math_view, GdomeElement* first, gint state)
495 {
496   GdomeException exc = 0;
497
498   g_return_if_fail(math_view != NULL);
499   g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
500   g_return_if_fail(first != NULL);
501
502   gtk_math_view_freeze(math_view);
503
504   if (root_selected != NULL)
505     {
506       gtk_math_view_unselect(math_view, root_selected);
507       gdome_el_unref(root_selected, &exc);
508       g_assert(exc == 0);
509     }
510
511   root_selected = first_selected = find_element_with_ref(first);
512
513   if (root_selected != NULL)
514     {
515       gtk_math_view_select(math_view, root_selected);
516       gdome_el_ref(root_selected, &exc);
517       g_assert(exc == 0);
518     }
519
520   gtk_math_view_thaw(math_view);
521 }
522
523 static void
524 select_over(GtkMathView* math_view, GdomeElement* elem, gint state)
525 {
526   GdomeElement* new_selected = NULL;
527   GdomeException exc = 0;
528
529   g_return_if_fail(math_view != NULL);
530   g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
531   g_return_if_fail(elem != NULL);
532
533   if (first_selected == NULL || elem == NULL)
534     new_selected = NULL;
535   else
536     new_selected = find_common_ancestor_with_ref(first_selected, elem);
537
538   if (new_selected != root_selected)
539     {
540       gtk_math_view_freeze(math_view);
541       if (root_selected != NULL)
542         {
543           gtk_math_view_unselect(math_view, root_selected);
544           gdome_el_unref(root_selected, &exc);
545           g_assert(exc == 0);
546         }
547       root_selected = new_selected;
548       if (root_selected != NULL)
549         gtk_math_view_select(math_view, root_selected);
550       gtk_math_view_thaw(math_view);
551     }
552   else if (new_selected != NULL)
553     {
554       gdome_el_unref(new_selected, &exc);
555       g_assert(exc == 0);
556     }
557
558 }
559
560 static gboolean
561 key_press_event(gpointer c,
562                 GdkEventKey* event,
563                 GtkWidget* widget)
564 {
565   g_return_val_if_fail(widget != NULL, FALSE);
566   g_return_val_if_fail(event != NULL, FALSE);
567   g_return_val_if_fail(context != NULL, FALSE);
568
569   if (event->type != GDK_KEY_PRESS) return FALSE;
570
571   switch (event->keyval)
572     {
573     case GDK_BackSpace:
574       edit_drop(context, event->state & GDK_MOD1_MASK, event->state & GDK_CONTROL_MASK);
575       break;
576     case GDK_Tab:
577       edit_complete(context);
578       break;
579     default:
580       if ((event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) == 0 && event->keyval < 0x80)
581         edit_push_char(context, event->keyval);
582       return FALSE;
583     }
584
585   return TRUE;
586 }
587
588 static void
589 create_widget_set(gpointer context)
590 {
591   GtkWidget* main_vbox;
592   GtkWidget* menu_bar;
593
594   main_vbox = gtk_vbox_new(FALSE, 1);
595   gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
596   gtk_container_add(GTK_CONTAINER(window), main_vbox);
597   gtk_widget_show(main_vbox);
598
599   menu_bar = get_main_menu();
600   gtk_box_pack_start(GTK_BOX(main_vbox), menu_bar, FALSE, TRUE, 0);
601   gtk_widget_show(menu_bar);
602
603   main_area = gtk_math_view_new(NULL, NULL);
604   gtk_widget_show(main_area);
605
606   //gtk_math_view_set_log_verbosity(GTK_MATH_VIEW(main_area), 3);
607
608   gtk_signal_connect_object (GTK_OBJECT (main_area),
609                              "select_begin", GTK_SIGNAL_FUNC (select_begin),
610                              (gpointer) main_area);
611
612   gtk_signal_connect_object (GTK_OBJECT (main_area),
613                              "select_over", GTK_SIGNAL_FUNC (select_over),
614                              (gpointer) main_area);
615
616   gtk_signal_connect_object (GTK_OBJECT(window),
617                              "key_press_event", GTK_SIGNAL_FUNC(key_press_event),
618                              context);
619
620   gtk_widget_add_events(GTK_WIDGET(main_area), GDK_KEY_PRESS_MASK);
621
622   scrolled_area = gtk_scrolled_window_new(NULL, NULL);
623   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_area),
624                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
625
626   gtk_widget_show(scrolled_area);
627   gtk_container_add(GTK_CONTAINER(scrolled_area), main_area);
628   gtk_box_pack_start(GTK_BOX(main_vbox), scrolled_area, TRUE, TRUE, 0);
629
630   gtk_widget_show(main_vbox);
631
632 }
633
634 GtkWidget*
635 get_main_menu()
636 {
637   GtkItemFactory* item_factory;
638   GtkAccelGroup* accel_group;
639   GtkWidget* menu_item;
640
641   gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
642
643   accel_group = gtk_accel_group_new();
644
645   item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
646
647   gtk_item_factory_create_items(item_factory, nmenu_items, menu_items, NULL);
648
649   gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
650
651   return gtk_item_factory_get_widget(item_factory, "<main>");
652 }