1 #include "stdafx.h"
2 
3 #include "common.h"
4 #include "sabbu.h"
5 
6 #include "gui_properties.h"
7 #include "gui_workspace.h"
8 #include "gui_export.h"
9 #include "gui_main_script.h"
10 #include "gui_main_video.h"
11 #include "gui_main_event.h"
12 #include "gui_main_karaoke.h"
13 #include "gui_main_navigation.h"
14 #include "gui_main_tool.h"
15 #include "gui_main_help.h"
16 //#include "gui_spell.h"
17 
18 #include "gui_menu.h"
19 
20 extern struct sabbu app;
21 
22 struct menu_item menu_script_export[] =
23 {
24   {
25     MENU_ITEM, _("Menu|Script|Export|_Text File"),
26     NULL,
27     0,         0,
28     (GCallback) gui_export_cb,              (void *) KRY_FORMAT_TEXT
29   },
30   {
31     MENU_ITEM, _("Menu|Script|Export|_Adobe Encore Text File"),
32     NULL,
33     0,         0,
34     (GCallback) gui_export_cb,              (void *) KRY_FORMAT_ENCORE
35   },
36   {
37     MENU_END,  NULL,
38     NULL,
39     0,         0,
40     NULL,                                                        0
41   }
42 };
43 
44 struct menu_item menu_script[] =
45 {
46   {
47     MENU_ITEM,       _("Menu|Script|_New"),
48     NULL,
49     0,               0,
50     (GCallback) gui_main_menu_script_new,                    0
51   },
52 	{
53     MENU_ITEM,       _("Menu|Script|_Open"),
54     NULL,
55     0,               0,
56     (GCallback) gui_main_menu_script_open,                   0
57   },
58 	{
59     MENU_BRANCH,     _("Menu|Script|Open _Recent"),
60     &app.ui.menu.script.open_recent,
61     0,               0,
62     (GCallback) NULL,                                        0
63   },
64 	{
65     MENU_SEPARATOR,  NULL,
66     NULL,
67     0,               0,
68     (GCallback) NULL,                                        0
69   },
70   {
71     MENU_ITEM,       _("Menu|Script|Proper_ties"),
72     NULL,
73     0,               0,
74     (GCallback) gui_properties_show,                         0
75   },
76 	{
77     MENU_SEPARATOR,  NULL,
78     NULL,
79     0,               0,
80     (GCallback) NULL,                                        0
81   },
82 	{
83     MENU_ITEM,       _("Menu|Script|_Save"),
84     NULL,
85     GDK_CONTROL_MASK, GDK_s,
86     (GCallback) gui_main_menu_script_save,                   0
87   },
88 	{
89     MENU_ITEM,       _("Menu|Script|Save _As"),
90     NULL,
91     0,               0,
92     (GCallback) gui_main_menu_script_save_as,                0
93   },
94 	{
95     MENU_ITEM,       _("Menu|Script|Save As _UTF16"),
96     &app.ui.menu.script.save_as_utf16,
97     0,               0,
98     (GCallback) gui_main_menu_script_save_as,      (void *)  1
99   },
100 	{
101     MENU_BRANCH,       _("Menu|Script|_Export"),
102     NULL,
103     0,               0,
104     (GCallback) NULL,      menu_script_export
105   },
106 	{
107     MENU_ITEM,       _("Menu|Script|_Close"),
108     &app.ui.menu.script.close,
109     0,               0,
110     (GCallback) gui_main_menu_script_close,                  0
111   },
112 	{
113     MENU_SEPARATOR,  NULL,
114     NULL,
115     0,               0,
116     (GCallback) NULL,                                        0
117   },
118 	{
119     MENU_ITEM,       _("Menu|Script|O_pen Workspace"),
120     NULL,
121     0,               0,
122     (GCallback) gui_workspace_open_cb,                0
123   },
124 	{
125     MENU_BRANCH,     _("Menu|Script|Op_en Recent Workspace"),
126     &app.ui.menu.script.open_recent_workspace,
127     0,               0,
128     (GCallback) NULL,                                        0
129   },
130 	{
131     MENU_ITEM,       _("Menu|Script|Save Wor_kspace"),
132     NULL,
133     0,               0,
134     (GCallback) gui_workspace_save_cb,                0
135   },
136 	{
137     MENU_ITEM,       _("Menu|Script|Sa_ve Workspace As"),
138     &app.ui.menu.script.save_workspace_as,
139     0,               0,
140     (GCallback) gui_workspace_save_as_cb,                0
141   },
142 	{
143     MENU_ITEM,       _("Menu|Script|Close _Workspace"),
144     &app.ui.menu.script.close_workspace,
145     0,               0,
146     (GCallback) gui_workspace_close_cb,               0
147   },
148   {
149     MENU_END,        NULL,
150     NULL,
151     0,               0,
152     (GCallback) NULL,                                        0
153   }
154 };
155 
156 struct menu_item menu_audio[] =
157 {
158   {
159     MENU_ITEM,       _("Menu|Audio|_Open"),
160     NULL,
161     0,                                0,
162     (GCallback) gui_main_menu_file_audio_open,           0},
163   {
164     MENU_BRANCH,     _("Menu|Audio|Open Recen_t"),
165     &app.ui.menu.audio.open_recent,
166     0,                                0,
167     (GCallback) NULL,                                    0},
168 	{
169     MENU_ITEM,       _("Menu|Audio|_Close"),
170     &app.ui.menu.audio.close,
171     0,                                0,
172     (GCallback) gui_main_menu_file_audio_close,          0},
173 	{
174     MENU_SEPARATOR,  NULL,
175     NULL,
176     0,                                0,
177     (GCallback) NULL,                                    0},
178   {
179     MENU_ITEM,       _("Menu|Audio|_Grab Times"),
180     &app.ui.menu.audio.grab_times,
181     GDK_MOD1_MASK,                    GDK_g,
182     (GCallback) gui_main_grab_times_cb,         (void *) 1},
183   {
184     MENU_ITEM,       _("Menu|Audio|Play _Selection"),
185     NULL,
186     GDK_MOD1_MASK,                    GDK_s,
187     (GCallback) gui_main_play_selected,                  0},
188   {
189     MENU_ITEM,       _("Menu|Audio|Play _From Start Marker"),
190     &app.ui.menu.audio.play_from_start_marker,
191     GDK_MOD1_MASK,                    GDK_p,
192     (GCallback) gui_main_menu_audio_play_start,          0},
193   {
194     MENU_ITEM,       _("Menu|Audio|Play _Previous Row"),
195     &app.ui.menu.audio.play_previous_row,
196     GDK_MOD1_MASK,                    GDK_v,
197     (GCallback) gui_main_menu_audio_play_previous_row,   0},
198   {
199     MENU_ITEM,       _("Menu|Audio|Play C_urrent Row"),
200     &app.ui.menu.audio.play_current_row,
201     GDK_MOD1_MASK,                    GDK_r,
202     (GCallback) gui_main_menu_audio_play_current_row,    0},
203   {
204     MENU_ITEM,       _("Menu|Audio|Play _Next Row"),
205     &app.ui.menu.audio.play_next_row,
206     GDK_MOD1_MASK,                    GDK_x,
207     (GCallback) gui_main_menu_audio_play_next_row,       0},
208 	{
209     MENU_ITEM,       _("Menu|Audio|Play _Last 0.5 seconds"),
210     NULL,
211     GDK_MOD1_MASK,                    GDK_z,
212     (GCallback) gui_main_menu_audio_play_last,           0},
213 	{
214     MENU_ITEM,       _("Menu|Audio|Play P_revious 0.25 seconds"),
215     NULL,
216     GDK_MOD1_MASK,                    GDK_a,
217     (GCallback) gui_main_menu_audio_play_previous,       0},
218 	{
219     MENU_ITEM,       _("Menu|Audio|Play N_ext 0.5 seconds"),
220     NULL,
221     GDK_MOD1_MASK | GDK_SHIFT_MASK,   GDK_z,
222     (GCallback) gui_main_menu_audio_play_next,           0},
223   {
224     MENU_ITEM,       _("Menu|Audio|Stop Pla_ying"),
225     NULL,
226     GDK_MOD1_MASK,                    GDK_q,
227     (GCallback) gui_main_menu_audio_stop,                0},
228 	{
229     MENU_ITEM,       _("Menu|Audio|_Advance Markers"),
230     &app.ui.menu.audio.advance_selection,
231     GDK_MOD1_MASK,                    GDK_e,
232     (GCallback) gui_main_advance_markers,                0},
233 	{
234     MENU_SEPARATOR,  NULL,
235     NULL,
236     0,                                0,
237     (GCallback) NULL,                                    0},
238 	{
239     MENU_ITEM,       _("Menu|Audio|Save Selection As _WAV"),
240     &app.ui.menu.audio.save_selection_as_wav,
241     0,                                0,
242     (GCallback) gui_main_save_selection_cb,              0},
243   {
244     MENU_END,        NULL,
245     NULL,
246     0,                                0,
247     NULL,                                                             0}
248 };
249 
250 struct menu_item menu_video_keyframes[] =
251 {
252   {
253     MENU_ITEM, _("Menu|Video|Key Frames|Load From _Video"),
254     NULL,
255     0,         0,
256     (GCallback) gui_main_menu_video_keyframes_mark,              0},
257   {
258     MENU_ITEM, _("Menu|Video|Key Frames|Load List _From File"),
259     NULL,
260     0,         0,
261     (GCallback) gui_main_menu_video_keyframes_load,              0},
262   {
263     MENU_ITEM, _("Menu|Video|Key Frames|Save List _To File"),
264     NULL,
265     0,         0,
266     (GCallback) gui_main_menu_video_keyframes_save,              0},
267   {
268     MENU_END,  NULL,
269     NULL,
270     0,         0,
271     NULL,                                                                     0}
272 };
273 
274 struct menu_item menu_video[] =
275 {
276   {
277     MENU_ITEM,       _("Menu|Video|_Open"),
278     NULL,
279     0,               0,
280     (GCallback) gui_main_menu_video_open,            0},
281   {
282     MENU_BRANCH,     _("Menu|Video|O_pen Recent"),
283     &app.ui.menu.video.open_recent,
284     0,               0,
285     (GCallback) NULL,                                0},
286   {
287     MENU_ITEM,       _("Menu|Video|_Close"),
288     &app.ui.menu.video.close,
289     0,               0,
290     (GCallback) gui_main_menu_video_close,           0},
291   {
292     MENU_SEPARATOR,  NULL,
293     NULL,
294     0,               0,
295     (GCallback) NULL,                                0},
296   {
297     MENU_BRANCH,     _("Menu|Video|_Key Frames"),
298     NULL,
299     0,               0,
300     (GCallback) NULL,                                menu_video_keyframes},
301   {
302     MENU_SEPARATOR,  NULL,
303     NULL,
304     0,               0,
305     (GCallback) NULL,                                0},
306   {
307     MENU_ITEM,       _("Menu|Video|_Show Grid"),
308     NULL,
309     0,               0,
310     (GCallback) gui_main_menu_video_ahow_grid,       0},
311   {
312     MENU_ITEM,       _("Menu|Video|Configure _Grid"),
313     NULL,
314     0,               0,
315     (GCallback) gui_main_menu_video_configure_grid,  0},
316   {
317     MENU_END,        NULL,
318     NULL,
319     0,               0,
320     NULL,                                                         0}
321 };
322 
323 struct menu_item menu_event[] =
324 {
325 	{
326     MENU_BRANCH,     _("Menu|Event|_Type"),
327     &app.ui.menu.event.type,
328     0,                                  0,
329     (GCallback) NULL,                                       0},
330 	{
331     MENU_ITEM,       _("Menu|Event|_Add Blank Above"),
332     &app.ui.menu.event.add_blank_above,
333     GDK_CONTROL_MASK,                   GDK_a,
334     (GCallback) gui_main_menu_event_add,           (void *) EVENT_ADD_BLANK_BEFORE
335   },
336 	{
337     MENU_ITEM,       _("Menu|Event|Add Blank _Below"),
338     &app.ui.menu.event.add_blank_below,
339     GDK_CONTROL_MASK | GDK_SHIFT_MASK,  GDK_a,
340     (GCallback) gui_main_menu_event_add,           (void *) EVENT_ADD_BLANK_AFTER
341   },
342 	{
343     MENU_ITEM,       _("Menu|Event|Add Se_parator Above"),
344     &app.ui.menu.event.add_separator_above,
345     0,  0,
346     (GCallback) gui_main_menu_event_add,           (void *) EVENT_ADD_SEPARATOR_BEFORE
347   },
348 	{
349     MENU_ITEM,       _("Menu|Event|Add Separat_or Below"),
350     &app.ui.menu.event.add_separator_below,
351     0,  0,
352     (GCallback) gui_main_menu_event_add,           (void *) EVENT_ADD_SEPARATOR_AFTER
353   },
354 	{
355     MENU_ITEM,       _("Menu|Event|_Delete"),
356     &app.ui.menu.event.event_delete,
357     GDK_CONTROL_MASK,                   GDK_l,
358     (GCallback) gui_main_menu_event_clipboard,     (void *) EVENT_DELETE},
359 	{
360     MENU_SEPARATOR,  NULL,
361     NULL,
362     0,                                  0,
363     (GCallback) NULL,                                       0},
364 	{
365     MENU_ITEM,       _("Menu|Event|_Find"),
366     NULL,
367     GDK_CONTROL_MASK,                   GDK_f,
368     (GCallback) gui_find_replace_show,                      0
369   },
370 	{
371     MENU_ITEM,       _("Menu|Event|Find _Next"),
372     NULL,
373     GDK_CONTROL_MASK,                   GDK_g,
374     (GCallback) gui_find_replace_find,                      0
375   },
376 /*	{
377     MENU_ITEM,       _("Menu|Event|Find Next Spelling Mistake"),
378     &app.ui.menu.event.find_spelling_mistake,
379     0,                   0,
380     (GCallback) gui_find_next_spelling_mistake,                      0
381   },*/
382 	{
383     MENU_ITEM,       _("Menu|Event|Set Spell Check Language"),
384     &app.ui.menu.event.spellcheck_language,
385     0,                   0,
386     NULL,                      0
387   },
388 	{
389     MENU_SEPARATOR,  NULL,
390     NULL,
391     0,                                  0,
392     (GCallback) NULL,                                       0},
393 	{
394     MENU_ITEM,       _("Menu|Event|_Join"),
395     &app.ui.menu.event.join,
396     GDK_CONTROL_MASK,                   GDK_j,
397     (GCallback) gui_main_menu_event_join,                   0},
398 	{
399     MENU_ITEM,       _("Menu|Event|_Split"),
400     &app.ui.menu.event.split,
401     GDK_CONTROL_MASK,                   GDK_k,
402     (GCallback) gui_main_menu_event_split,                  0},
403 	{
404     MENU_ITEM,       _("Menu|Event|Split at Cu_rsor"),
405     &app.ui.menu.event.split_at_cursor,
406     GDK_CONTROL_MASK | GDK_SHIFT_MASK,  GDK_k,
407     (GCallback) gui_main_menu_event_split,         (void *) 1},
408 	{
409     MENU_ITEM,       _("Menu|Event|Shift T_imes"),
410     &app.ui.menu.event.shift_times,
411     0,                                  0,
412     (GCallback) gui_main_menu_event_shift_times_cb,         0},
413 	{
414     MENU_SEPARATOR,  NULL,
415     NULL,
416     0,                                  0,
417     (GCallback) NULL,                                       0},
418 	{
419     MENU_ITEM,       _("Menu|Event|_Copy"),
420     &app.ui.menu.event.copy,
421     0,                                  0,
422     (GCallback) gui_main_menu_event_clipboard,     (void *) EVENT_COPY},
423 	{
424     MENU_ITEM,       _("Menu|Event|C_ut"),
425     &app.ui.menu.event.cut,
426     0,                                  0,
427     (GCallback) gui_main_menu_event_clipboard,     (void *) EVENT_CUT},
428 	{
429     MENU_ITEM,       _("Menu|Event|_Paste Above"),
430     &app.ui.menu.event.paste_above,
431     0,                                  0,
432     (GCallback) gui_main_menu_event_paste,         (void *) EVENT_PASTE_BEFORE},
433 	{
434     MENU_ITEM,       _("Menu|Event|Paste B_elow"),
435     &app.ui.menu.event.paste_below,
436     0,                                  0,
437     (GCallback) gui_main_menu_event_paste,         (void *) EVENT_PASTE_AFTER
438   },
439 #ifdef _DEBUG
440 	{
441     MENU_ITEM,       _("Menu|Event|Number Events"),
442     &app.ui.menu.event.number_events,
443     0,                                  0,
444     (GCallback) gui_main_menu_number_events,       0
445   },
446 #endif
447   {
448     MENU_END,        NULL,
449     NULL,
450     0,                                  0,
451     NULL,                                                                0}
452 };
453 
454 struct menu_item menu_karaoke[] =
455 {
456   {
457     MENU_ITEM,       _("Menu|Karaoke|_Box Mode"),
458     &app.ui.menu.karaoke.box_mode,
459     0,                0,
460     (GCallback) gui_main_karaoke_mode_on,                0
461   },
462   {
463     MENU_ITEM,       _("Menu|Karaoke|_Line Mode"),
464     &app.ui.menu.karaoke.script_mode,
465     0,                0,
466     (GCallback) gui_main_karaoke_mode_on,      (void *)  1
467   },
468   {
469     MENU_ITEM,       _("Menu|Karaoke|Sa_ve Changes"),
470     &app.ui.menu.karaoke.save_changes,
471     GDK_MOD1_MASK,    GDK_g,
472     (GCallback) gui_karaoke_grab_times_cb,     (void *)  1
473   },
474   {
475     MENU_ITEM,       _("Menu|Karaoke|Turn _Off"),
476     &app.ui.menu.karaoke.turn_off,
477     0,               0,
478     (GCallback) gui_main_karaoke_mode_off_cb,  (void *)  1
479   },
480 	{
481     MENU_SEPARATOR,  NULL,
482     NULL,
483     0,               0,
484     (GCallback) NULL,                                    0},
485   {
486     MENU_ITEM,       _("Menu|Karaoke|_Split Part"),
487     &app.ui.menu.karaoke.split_part,
488     GDK_CONTROL_MASK, GDK_k,
489     (GCallback) gui_main_karaoke_split_word_cb,          0},
490 	{
491     MENU_SEPARATOR,  NULL,
492     NULL,
493     0,               0,
494     (GCallback) NULL,                                    0},
495   {
496     MENU_ITEM,       _("Menu|Karaoke|_Previous Part"),
497     &app.ui.menu.karaoke.previous_part,
498     GDK_MOD1_MASK,    GDK_v,
499     (GCallback) gui_main_karaoke_prev_part_cb,           0},
500   {
501     MENU_ITEM,       _("Menu|Karaoke|_Next Part"),
502     &app.ui.menu.karaoke.next_part,
503     GDK_MOD1_MASK,    GDK_x,
504     (GCallback) gui_main_karaoke_next_part_cb,           0},
505   {
506     MENU_END,        NULL,
507     NULL,
508     0,               0,
509     NULL,                                                             0}
510 };
511 
512 struct menu_item menu_navigation[] =
513 {
514 	{
515     MENU_ITEM, _("Menu|Navigation|_Next Event"),
516     NULL,
517     GDK_CONTROL_MASK, GDK_n,
518     (GCallback) gui_main_menu_navigation_next_row,      (void *)   1},
519 	{
520     MENU_ITEM, _("Menu|Navigation|_Previous Event"),
521     NULL,
522     GDK_CONTROL_MASK, GDK_p,
523     (GCallback) gui_main_menu_navigation_previous_row,  (void *)  -1},
524 	{
525     MENU_ITEM, _("Menu|Navigation|Page _Up"),
526     NULL,
527     GDK_CONTROL_MASK, GDK_u,
528     (GCallback) gui_main_menu_navigation_page_up,                  0},
529 	{
530     MENU_ITEM, _("Menu|Navigation|Page _Down"),
531     NULL,
532     GDK_CONTROL_MASK, GDK_d,
533     (GCallback) gui_main_menu_navigation_page_down,                0},
534 	{
535     MENU_ITEM, _("Menu|Navigation|_Top of Script"),
536     NULL,
537     GDK_CONTROL_MASK, GDK_t,
538     (GCallback) gui_main_menu_navigation_top,                      0},
539 	{
540     MENU_ITEM, _("Menu|Navigation|_Bottom of Script"),
541     NULL,
542     GDK_CONTROL_MASK, GDK_b,
543     (GCallback) gui_main_menu_navigation_bottom,                   0},
544   {
545     MENU_END,  NULL,
546     NULL,
547     0,               0,
548     NULL,                                                                       0}
549 };
550 
551 struct menu_item menu_customize[] =
552 {
553 	{
554     MENU_ITEM, _("Menu|Customize|_Options"),
555     NULL,
556     0,         0,
557     (GCallback) gui_main_menu_tool_options,             0},
558 	{
559     MENU_ITEM, _("Menu|Customize|_Colors"),
560     NULL,
561     0,         0,
562     (GCallback) gui_main_menu_tool_colors,              0},
563 	{
564     MENU_ITEM, _("Menu|Customize|_Menu Shortcuts"),
565     NULL,
566     0,         0,
567     (GCallback) gui_main_menu_tool_menu_accels,              0},
568   {
569     MENU_END,  NULL,
570     NULL,
571     0,         0,
572     NULL,                                                            0}
573 };
574 
575 struct menu_item menu_sync_point[] =
576 {
577   {
578     MENU_ITEM, _("Menu|Sync|Sync Point|Set at Current _Time"),
579     NULL,
580     0,         0,
581     (GCallback) gui_main_sync_point_set,      0},
582   {
583     MENU_ITEM, _("Menu|Sync|Sync Point|Sync to Another _Script"),
584     NULL,
585     0,         0,
586     (GCallback) gui_main_sync_point_sync,     0},
587   {
588     MENU_END,  NULL,
589     NULL,
590     0,         0,
591     NULL,                                                  0}
592 };
593 
594 struct menu_item menu_sync[] =
595 {
596   {
597     MENU_BRANCH, _("Menu|Sync|_Sync Point"),
598     NULL,
599     0,           0,
600     (GCallback) gui_main_sync_point_set,      menu_sync_point},
601   {
602     MENU_ITEM,   _("Menu|Sync|Sync Event To _Wave"),
603     NULL,
604     0,           0,
605     (GCallback) gui_main_sync_event_to_wave,  0},
606   {
607     MENU_END,    NULL,
608     NULL,
609     0,           0,
610     NULL,                                                  0}
611 };
612 
613 struct menu_item menu_help[] =
614 {
615   {
616     MENU_ITEM, _("Menu|Help|_Keyboard Shortcuts"),
617     NULL,
618     0,         0,
619     (GCallback) gui_main_help_shortcuts,              0},
620   {
621     MENU_ITEM, _("Menu|Help|_About"),
622     NULL,
623     0,         0,
624     (GCallback) gui_main_help_about,                  0},
625   {
626     MENU_END,  NULL,
627     NULL,
628     0,         0,
629     NULL,                                                          0}
630 };
631 
632 struct menu_item menu_root[] =
633 {
634   {
635     MENU_BRANCH, _("Menu|S_cript"),
636     NULL,
637     0,           0,
638     NULL, menu_script},
639   {
640     MENU_BRANCH, _("Menu|A_udio"),
641     NULL,
642     0,           0,
643     NULL, menu_audio},
644   {
645     MENU_BRANCH, _("Menu|V_ideo"),
646     NULL,
647     0,           0,
648     NULL, menu_video},
649   {
650     MENU_BRANCH, _("Menu|Even_t"),
651     &app.ui.menu.event.me,
652     0,           0,
653     NULL, menu_event},
654 /*  {
655     MENU_BRANCH, _("Menu|_Karaoke"),
656     &app.ui.menu.karaoke.me,
657     0,           0,
658     NULL, menu_karaoke
659   },*/
660   {
661     MENU_BRANCH, _("Menu|_Navigation"),
662     NULL,
663     0,           0,
664     NULL, menu_navigation},
665   {
666     MENU_BRANCH, _("Menu|Cust_omize"),
667     NULL,
668     0,           0,
669     NULL, menu_customize},
670   {
671     MENU_BRANCH, _("Menu|S_ync"),
672     &app.ui.menu.sync.me,
673     0,           0,
674     NULL, menu_sync},
675   {
676     MENU_BRANCH, _("Menu|_Help"),
677     NULL,
678     0,           0,
679     NULL, menu_help},
680   {
681     MENU_END,    NULL,
682     NULL,
683     0,           0,
684     NULL, 0}
685 };
686 
gui_menu_get_data()687 struct menu_item *gui_menu_get_data()
688 {
689   return menu_root;
690 }
691 
gui_menu_create_widget(struct menu_item * items,char * path)692 GtkMenuShell *gui_menu_create_widget(struct menu_item *items, char *path)
693 {
694   gboolean submenu = (items != NULL);
695   GtkMenuShell *menu;
696   if(items == NULL)
697   {
698     menu = GTK_MENU_SHELL(gtk_menu_bar_new());
699     items = menu_root;
700   }
701   else
702   {
703     menu = GTK_MENU_SHELL(gtk_menu_new());
704     gtk_menu_set_accel_group(GTK_MENU(menu), app.ui.menu_accel_group);
705   }
706 
707   int index = 0;
708   while(items[index].type != MENU_END)
709   {
710     GtkMenuItem *item;
711     if(items[index].type == MENU_SEPARATOR)
712     {
713       item = GTK_MENU_ITEM(gtk_separator_menu_item_new());
714     }
715     else
716     {
717       item = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(__(items[index].text)));
718       if(submenu)
719       {
720         char *accel_path = kry_strdup_printf(KRY_LOC "%s/%s", path, sgettext_strip(items[index].text));
721 
722         char *key_key = kry_strdup_printf(KRY_LOC "%s//Key", accel_path);
723         int key = app.prefs->GetInt("MenuAccels", key_key, items[index].key);
724         kry_free(key_key);
725 
726         char *mod_key = kry_strdup_printf(KRY_LOC "%s//Mod", accel_path);
727         int mod = app.prefs->GetInt("MenuAccels", mod_key, items[index].modifier);
728         kry_free(mod_key);
729 
730         gtk_accel_map_add_entry(accel_path, key, (GdkModifierType) mod);
731         gtk_menu_item_set_accel_path(item, accel_path);
732         kry_free(accel_path);
733 
734         if(items[index].type != MENU_BRANCH && items[index].cb)
735           g_signal_connect(item, "activate", items[index].cb, items[index].param);
736       }
737 
738       if(items[index].var)
739         *(items[index].var) = item;
740 
741       if(items[index].type == MENU_BRANCH && items[index].param)
742       {
743         char *subpath = kry_strdup_printf(KRY_LOC "%s/%s", path, sgettext_strip(items[index].text));
744         gtk_menu_item_set_submenu(item, GTK_WIDGET(gui_menu_create_widget((struct menu_item *) items[index].param, subpath)));
745         kry_free(subpath);
746       }
747     }
748 
749 
750     gtk_menu_shell_append(GTK_MENU_SHELL(menu), GTK_WIDGET(item));
751 
752     index++;
753   }
754 
755   return menu;
756 }
757 
gui_menu_check_labels(struct menu_item * items=NULL)758 void gui_menu_check_labels(struct menu_item *items = NULL)
759 {
760   GList *accels = NULL;
761   if(items == NULL)
762   {
763     char *reserved[] = {"g", "s", "p", "v", "r", "x", "z", "a", "q", "e", NULL};
764     items = menu_root;
765     for(int i = 0; reserved[i]; i++)
766       accels = g_list_append(accels, kry_strdup(reserved[i]));
767   }
768 
769   for(int i = 0; items[i].type != MENU_END; i++)
770   {
771     if(items[i].type == MENU_BRANCH && items[i].param)
772     {
773       gui_menu_check_labels((struct menu_item *) items[i].param);
774       continue;
775     }
776 
777     if(items[i].type == MENU_SEPARATOR)
778       continue;
779 
780     char *text = __(items[i].text);
781     char *text_accel = strchr(text, '_');
782     if(text_accel)
783     {
784       char *shortcut = (char *) kry_malloc(2);
785       shortcut[0] = text_accel[1];
786       shortcut[1] = 0;
787 
788       if(g_list_find_custom(accels, shortcut, (GCompareFunc) strncmp))
789         g_warning("'%s' does not have a unique accelerator", text);
790       else
791         accels = g_list_append(accels, shortcut);
792     }
793     else
794     {
795       g_warning("'%s' does not have an accelerator", text);
796     }
797 
798   }
799 
800   g_list_foreach(accels, (GFunc) kry_free_minimal, NULL);
801   g_list_free(accels);
802 }
803 
804 
gui_menu_create()805 GtkWidget *gui_menu_create()
806 {
807   app.ui.menu_accel_group = gtk_accel_group_new();
808   gtk_window_add_accel_group(app.ui.window, app.ui.menu_accel_group);
809 
810 #ifdef _WINDOWS
811 #ifdef _DEBUG
812     gui_menu_check_labels();
813 #endif
814 #endif
815 
816   return GTK_WIDGET(gui_menu_create_widget(NULL, "<SabbuMenu>"));
817 }
818 
819