Mercurial > mplayer.hg
annotate gui/dialog/menu.c @ 36316:139f2b064ef9
Don't subsequently calculate original_aspect from last movie_aspect.
Instead, differentiate between the original aspect ratio stored in or
determined from the video file and the forced, i.e. current, aspect
ratio (e.g. forced by command line override).
This enables multiple independent instances of vd.c again which has
been broken by introducing a static variable in r36401.
Without the subsequent calculation of original_aspect it now contains
nothing but the pure video file aspect ratio which makes it possible
to use movie_aspect -1 to set the original aspect ratio which explains
the changes in command.c and gui/dialog/menu.c.
The changes in vd_mpegpes due to the impact of original_aspect will
fix a bug there at the same time where the condition in order to call
mpcodecs_config_vo() should only trigger once when the encoded aspect
changes. So far, the forced, i.e. current, aspect has been checked.
The whole is related to enabling special argument -1 to switch_ratio
started in r36391.
author | ib |
---|---|
date | Wed, 07 Aug 2013 20:41:34 +0000 |
parents | 6fc430e33c76 |
children | 28ea255e40ce |
rev | line source |
---|---|
33572 | 1 /* |
2 * This file is part of MPlayer. | |
3 * | |
4 * MPlayer is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; either version 2 of the License, or | |
7 * (at your option) any later version. | |
8 * | |
9 * MPlayer is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License along | |
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
17 */ | |
18 | |
19 #include <stdio.h> | |
20 #include <stdlib.h> | |
21 #include <string.h> | |
22 | |
23 #include "config.h" | |
24 #include "help_mp.h" | |
25 #include "access_mpcontext.h" | |
26 #include "mixer.h" | |
27 #include "mpcommon.h" | |
28 | |
29 #include "menu.h" | |
35529 | 30 #include "dialog.h" |
35772 | 31 #include "gui/ui/actions.h" |
35525 | 32 #include "gui/app/app.h" |
33 #include "gui/app/gui.h" | |
33738 | 34 #include "gui/interface.h" |
33572 | 35 |
36 #include "stream/stream.h" | |
36273 | 37 #include "libavutil/common.h" |
38 #include "libmpcodecs/vd.h" | |
33572 | 39 #include "libmpdemux/demuxer.h" |
40 #include "libmpdemux/stheader.h" | |
41 #include "libavutil/avstring.h" | |
42 | |
35526 | 43 #include "pixmaps/about.xpm" |
44 #include "pixmaps/half.xpm" | |
45 #include "pixmaps/normal.xpm" | |
46 #include "pixmaps/double.xpm" | |
47 #include "pixmaps/full.xpm" | |
48 #include "pixmaps/exit.xpm" | |
49 #include "pixmaps/prefs.xpm" | |
50 #include "pixmaps/equalizer.xpm" | |
51 #include "pixmaps/playlist.xpm" | |
52 #include "pixmaps/skin.xpm" | |
53 #include "pixmaps/sound.xpm" | |
54 #include "pixmaps/open.xpm" | |
55 #include "pixmaps/play.xpm" | |
56 #include "pixmaps/stop.xpm" | |
57 #include "pixmaps/pause.xpm" | |
58 #include "pixmaps/prev.xpm" | |
59 #include "pixmaps/next.xpm" | |
60 #include "pixmaps/aspect.xpm" | |
61 #include "pixmaps/aspect11.xpm" | |
62 #include "pixmaps/aspect169.xpm" | |
63 #include "pixmaps/aspect235.xpm" | |
64 #include "pixmaps/aspect43.xpm" | |
65 #include "pixmaps/file2.xpm" | |
66 #include "pixmaps/url.xpm" | |
67 #include "pixmaps/sub.xpm" | |
68 #include "pixmaps/nosub.xpm" | |
69 #include "pixmaps/empty.xpm" | |
70 #include "pixmaps/loadeaf.xpm" | |
71 #include "pixmaps/title.xpm" | |
72 #include "pixmaps/subtitle.xpm" | |
34387 | 73 #ifdef CONFIG_CDDA |
35526 | 74 #include "pixmaps/cd.xpm" |
75 #include "pixmaps/playcd.xpm" | |
34387 | 76 #endif |
34077 | 77 #ifdef CONFIG_VCD |
35526 | 78 #include "pixmaps/vcd.xpm" |
79 #include "pixmaps/playvcd.xpm" | |
34077 | 80 #endif |
33572 | 81 #ifdef CONFIG_DVDREAD |
35526 | 82 #include "pixmaps/dvd.xpm" |
83 #include "pixmaps/playdvd.xpm" | |
84 #include "pixmaps/chapter.xpm" | |
85 #include "pixmaps/dolby.xpm" | |
86 #include "pixmaps/audiolang.xpm" | |
87 #include "pixmaps/sublang.xpm" | |
34422
b1f2949ca18d
Use empty1px.xpm instead of empty.xpm for check item (and similar) menus.
ib
parents:
34421
diff
changeset
|
88 #endif |
35526 | 89 #include "pixmaps/empty1px.xpm" |
33572 | 90 |
36029
49be954ad61a
Move variable declarations and definitions where they belong.
ib
parents:
36028
diff
changeset
|
91 int gtkPopupMenu; |
49be954ad61a
Move variable declarations and definitions where they belong.
ib
parents:
36028
diff
changeset
|
92 int gtkPopupMenuParam; |
49be954ad61a
Move variable declarations and definitions where they belong.
ib
parents:
36028
diff
changeset
|
93 |
33572 | 94 static void ActivateMenuItem( int Item ) |
95 { | |
96 // fprintf( stderr,"[menu] item: %d.%d\n",Item&0xffff,Item>>16 ); | |
97 gtkPopupMenu=Item & 0x0000ffff; | |
98 gtkPopupMenuParam=Item >> 16; | |
35773 | 99 uiEvent( Item & 0x0000ffff,Item >> 16 ); |
33572 | 100 } |
101 | |
102 static GtkWidget * AddMenuCheckItem(GtkWidget *window1, const char * immagine_xpm, GtkWidget* Menu,const char* label, gboolean state, int Number) | |
103 { | |
104 GtkWidget * Label = NULL; | |
105 GtkWidget * Pixmap = NULL; | |
106 GtkWidget * hbox = NULL; | |
107 GtkWidget * Item = NULL; | |
108 | |
109 GdkPixmap *PixmapIcon = NULL; | |
110 GdkColor transparent; | |
111 GdkBitmap *MaskIcon = NULL; | |
112 | |
113 PixmapIcon = gdk_pixmap_create_from_xpm_d (window1->window, &MaskIcon, &transparent,(gchar **)immagine_xpm ); | |
114 Pixmap = gtk_pixmap_new (PixmapIcon, MaskIcon); | |
115 gdk_pixmap_unref (PixmapIcon); | |
116 | |
117 Item=gtk_check_menu_item_new(); | |
118 Label = gtk_label_new (label); | |
119 | |
120 hbox = gtk_hbox_new (FALSE, 8); | |
121 gtk_box_pack_start (GTK_BOX (hbox), Pixmap, FALSE, FALSE, 0); | |
122 gtk_box_pack_start (GTK_BOX (hbox), Label, FALSE, FALSE, 0); | |
123 gtk_container_add (GTK_CONTAINER (Item), hbox); | |
124 | |
125 gtk_menu_append( GTK_MENU( Menu ),Item ); | |
126 | |
127 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(Item),state); | |
128 gtk_signal_connect_object( GTK_OBJECT(Item),"activate", | |
129 GTK_SIGNAL_FUNC(ActivateMenuItem),(gpointer)Number ); | |
130 gtk_menu_item_right_justify (GTK_MENU_ITEM (Item)); | |
131 gtk_widget_show_all(Item); | |
132 | |
133 return Item; | |
134 } | |
135 GtkWidget * AddMenuItem( GtkWidget *window1, const char * immagine_xpm, GtkWidget * SubMenu,const char * label,int Number ) | |
136 { | |
137 GtkWidget * Label = NULL; | |
138 GtkWidget * Pixmap = NULL; | |
139 GtkWidget * hbox = NULL; | |
140 GtkWidget * Item = NULL; | |
141 GdkPixmap * PixmapIcon = NULL; | |
142 GdkColor transparent; | |
143 GdkBitmap * MaskIcon = NULL; | |
144 | |
145 PixmapIcon = gdk_pixmap_create_from_xpm_d (window1->window, &MaskIcon, &transparent,(gchar **)immagine_xpm ); | |
146 Pixmap = gtk_pixmap_new (PixmapIcon, MaskIcon); | |
147 gdk_pixmap_unref (PixmapIcon); | |
148 | |
149 Item=gtk_menu_item_new(); | |
150 Label = gtk_label_new (label); | |
151 | |
152 hbox = gtk_hbox_new (FALSE, 8); | |
153 gtk_box_pack_start (GTK_BOX (hbox), Pixmap, FALSE, FALSE, 0); | |
154 gtk_box_pack_start (GTK_BOX (hbox), Label, FALSE, FALSE, 0); | |
155 gtk_container_add (GTK_CONTAINER (Item), hbox); | |
156 | |
157 | |
158 gtk_menu_append( GTK_MENU( SubMenu ),Item ); | |
159 gtk_signal_connect_object( GTK_OBJECT(Item),"activate", | |
160 GTK_SIGNAL_FUNC(ActivateMenuItem),(gpointer)Number ); | |
161 | |
162 gtk_menu_item_right_justify (GTK_MENU_ITEM (Item)); | |
163 gtk_widget_show_all(Item); | |
164 return Item; | |
165 } | |
166 | |
167 | |
168 GtkWidget * AddSubMenu( GtkWidget *window1, const char * immagine_xpm, GtkWidget * Menu,const char * label ) | |
169 { | |
170 GtkWidget * Label = NULL; | |
171 GtkWidget * Pixmap = NULL; | |
172 GtkWidget * hbox = NULL; | |
173 GtkWidget * Item = NULL; | |
174 GtkWidget * SubItem = NULL; | |
175 GdkPixmap * PixmapIcon = NULL; | |
176 GdkColor transparent; | |
177 GdkBitmap * MaskIcon = NULL; | |
178 | |
179 PixmapIcon = gdk_pixmap_create_from_xpm_d (window1->window, &MaskIcon, &transparent,(gchar **)immagine_xpm); | |
180 Pixmap = gtk_pixmap_new (PixmapIcon, MaskIcon); | |
181 gdk_pixmap_unref (PixmapIcon); | |
182 | |
183 SubItem=gtk_menu_item_new(); | |
184 Item=gtk_menu_new(); | |
185 Label = gtk_label_new (label); | |
186 | |
187 hbox = gtk_hbox_new (FALSE, 8); | |
188 gtk_box_pack_start (GTK_BOX (hbox), Pixmap, FALSE, FALSE, 0); | |
189 gtk_box_pack_start (GTK_BOX (hbox), Label, FALSE, FALSE, 0); | |
190 gtk_container_add (GTK_CONTAINER (SubItem), hbox); | |
191 | |
192 gtk_menu_append( GTK_MENU( Menu ),SubItem ); | |
193 gtk_menu_item_set_submenu( GTK_MENU_ITEM( SubItem ),Item ); | |
194 | |
195 gtk_widget_show_all( SubItem ); | |
196 return Item; | |
197 } | |
198 | |
199 GtkWidget * AddSeparator( GtkWidget * Menu ) | |
200 { | |
201 GtkWidget * Item = NULL; | |
202 | |
203 Item=gtk_menu_item_new (); | |
204 gtk_widget_show( Item ); | |
205 gtk_container_add( GTK_CONTAINER( Menu ),Item ); | |
206 gtk_widget_set_sensitive( Item,FALSE ); | |
207 | |
208 return Item; | |
209 } | |
210 | |
211 typedef struct | |
212 { | |
213 int id; | |
214 const char * name; | |
215 } Languages_t; | |
216 | |
34454 | 217 #ifdef CONFIG_DVDREAD |
33572 | 218 #define lng( a,b ) ( (int)(a) * 256 + b ) |
219 static Languages_t Languages[] = | |
220 { | |
221 { lng( 'a','b' ), "Abkhazian" }, | |
222 { lng( 'a','a' ), "Afar" }, | |
223 { lng( 'a','f' ), "Afrikaans" }, | |
224 { lng( 's','q' ), "Albanian" }, | |
225 { lng( 'a','m' ), "Amharic" }, | |
226 { lng( 'a','r' ), "Arabic" }, | |
227 { lng( 'h','y' ), "Armenian" }, | |
228 { lng( 'a','s' ), "Assamese" }, | |
229 { lng( 'a','e' ), "Avestan" }, | |
230 { lng( 'a','y' ), "Aymara" }, | |
231 { lng( 'a','z' ), "Azerbaijani" }, | |
232 { lng( 'b','a' ), "Bashkir" }, | |
233 { lng( 'e','u' ), "Basque" }, | |
234 { lng( 'b','e' ), "Belarusian" }, | |
235 { lng( 'b','n' ), "Bengali" }, | |
236 { lng( 'b','h' ), "Bihari" }, | |
237 { lng( 'b','i' ), "Bislama" }, | |
238 { lng( 'b','s' ), "Bosnian" }, | |
239 { lng( 'b','r' ), "Breton" }, | |
240 { lng( 'b','g' ), "Bulgarian" }, | |
241 { lng( 'm','y' ), "Burmese" }, | |
242 { lng( 'c','a' ), "Catalan" }, | |
243 { lng( 'c','h' ), "Chamorro" }, | |
244 { lng( 'c','e' ), "Chechen" }, | |
245 { lng( 'n','y' ), "Chichewa;Nyanja" }, | |
246 { lng( 'z','h' ), "Chinese" }, | |
247 { lng( 'c','u' ), "ChurchSlavic" }, | |
248 { lng( 'c','v' ), "Chuvash" }, | |
249 { lng( 'k','w' ), "Cornish" }, | |
250 { lng( 'c','o' ), "Corsican" }, | |
251 { lng( 'h','r' ), "Croatian" }, | |
252 { lng( 'c','s' ), "Czech" }, | |
253 { lng( 'd','a' ), "Danish" }, | |
254 { lng( 'n','l' ), "Dutch" }, | |
255 { lng( 'd','z' ), "Dzongkha" }, | |
256 { lng( 'e','n' ), "English" }, | |
257 { lng( 'e','o' ), "Esperanto" }, | |
258 { lng( 'e','t' ), "Estonian" }, | |
259 { lng( 'f','o' ), "Faroese" }, | |
260 { lng( 'f','j' ), "Fijian" }, | |
261 { lng( 'f','i' ), "Finnish" }, | |
262 { lng( 'f','r' ), "French" }, | |
263 { lng( 'f','y' ), "Frisian" }, | |
264 { lng( 'g','d' ), "Gaelic(Scots" }, | |
265 { lng( 'g','l' ), "Gallegan" }, | |
266 { lng( 'k','a' ), "Georgian" }, | |
267 { lng( 'd','e' ), "German" }, | |
268 { lng( 'e','l' ), "Greek" }, | |
269 { lng( 'g','n' ), "Guarani" }, | |
270 { lng( 'g','u' ), "Gujarati" }, | |
271 { lng( 'h','a' ), "Hausa" }, | |
272 { lng( 'h','e' ), "Hebrew" }, | |
273 { lng( 'i','w' ), "Hebrew" }, | |
274 { lng( 'h','z' ), "Herero" }, | |
275 { lng( 'h','i' ), "Hindi" }, | |
276 { lng( 'h','o' ), "HiriMotu" }, | |
277 { lng( 'h','u' ), "Hungarian" }, | |
278 { lng( 'i','s' ), "Icelandic" }, | |
279 { lng( 'i','d' ), "Indonesian" }, | |
280 { lng( 'i','n' ), "Indonesian" }, | |
281 { lng( 'i','a' ), "Interlingua" }, | |
282 { lng( 'i','e' ), "Interlingue" }, | |
283 { lng( 'i','u' ), "Inuktitut" }, | |
284 { lng( 'i','k' ), "Inupiaq" }, | |
285 { lng( 'g','a' ), "Irish" }, | |
286 { lng( 'i','t' ), "Italian" }, | |
287 { lng( 'j','a' ), "Japanese" }, | |
288 { lng( 'j','v' ), "Javanese" }, | |
289 { lng( 'j','w' ), "Javanese" }, | |
290 { lng( 'k','l' ), "Kalaallisut" }, | |
291 { lng( 'k','n' ), "Kannada" }, | |
292 { lng( 'k','s' ), "Kashmiri" }, | |
293 { lng( 'k','k' ), "Kazakh" }, | |
294 { lng( 'k','m' ), "Khmer" }, | |
295 { lng( 'k','i' ), "Kikuyu" }, | |
296 { lng( 'r','w' ), "Kinyarwanda" }, | |
297 { lng( 'k','y' ), "Kirghiz" }, | |
298 { lng( 'k','v' ), "Komi" }, | |
299 { lng( 'k','o' ), "Korean" }, | |
300 { lng( 'k','j' ), "Kuanyama" }, | |
301 { lng( 'k','u' ), "Kurdish" }, | |
302 { lng( 'l','o' ), "Lao" }, | |
303 { lng( 'l','a' ), "Latin" }, | |
304 { lng( 'l','v' ), "Latvian" }, | |
305 { lng( 'l','b' ), "Letzeburgesch" }, | |
306 { lng( 'l','n' ), "Lingala" }, | |
307 { lng( 'l','t' ), "Lithuanian" }, | |
308 { lng( 'm','k' ), "Macedonian" }, | |
309 { lng( 'm','g' ), "Malagasy" }, | |
310 { lng( 'm','s' ), "Malay" }, | |
311 { lng( 'm','l' ), "Malayalam" }, | |
312 { lng( 'm','t' ), "Maltese" }, | |
313 { lng( 'g','v' ), "Manx" }, | |
314 { lng( 'm','i' ), "Maori" }, | |
315 { lng( 'm','r' ), "Marathi" }, | |
316 { lng( 'm','h' ), "Marshall" }, | |
317 { lng( 'm','o' ), "Moldavian" }, | |
318 { lng( 'm','n' ), "Mongolian" }, | |
319 { lng( 'n','a' ), "Nauru" }, | |
320 { lng( 'n','v' ), "Navajo" }, | |
321 { lng( 'n','d' ), "North Ndebele" }, | |
322 { lng( 'n','r' ), "South Ndebele" }, | |
323 { lng( 'n','g' ), "Ndonga" }, | |
324 { lng( 'n','e' ), "Nepali" }, | |
325 { lng( 's','e' ), "NorthernSami" }, | |
326 { lng( 'n','o' ), "Norwegian" }, | |
327 { lng( 'n','b' ), "NorwegianBokmål" }, | |
328 { lng( 'n','n' ), "NorwegianNynorsk" }, | |
329 { lng( 'n','y' ), "Nyanja;Chichewa" }, | |
330 { lng( 'o','c' ), "Occitan(post1500;Provençal" }, | |
331 { lng( 'o','r' ), "Oriya" }, | |
332 { lng( 'o','m' ), "Oromo" }, | |
333 { lng( 'o','s' ), "Ossetian;Ossetic" }, | |
334 { lng( 'p','i' ), "Pali" }, | |
335 { lng( 'p','a' ), "Panjabi" }, | |
336 { lng( 'f','a' ), "Persian" }, | |
337 { lng( 'p','l' ), "Polish" }, | |
338 { lng( 'p','t' ), "Portuguese" }, | |
339 { lng( 'o','c' ), "Provençal;Occitan(post1500" }, | |
340 { lng( 'p','s' ), "Pushto" }, | |
341 { lng( 'q','u' ), "Quechua" }, | |
342 { lng( 'r','m' ), "Raeto-Romance" }, | |
343 { lng( 'r','o' ), "Romanian" }, | |
344 { lng( 'r','n' ), "Rundi" }, | |
345 { lng( 'r','u' ), "Russian" }, | |
346 { lng( 's','m' ), "Samoan" }, | |
347 { lng( 's','g' ), "Sango" }, | |
348 { lng( 's','a' ), "Sanskrit" }, | |
349 { lng( 's','c' ), "Sardinian" }, | |
350 { lng( 's','r' ), "Serbian" }, | |
351 { lng( 's','n' ), "Shona" }, | |
352 { lng( 's','d' ), "Sindhi" }, | |
353 { lng( 's','i' ), "Sinhalese" }, | |
354 { lng( 's','k' ), "Slovak" }, | |
355 { lng( 's','l' ), "Slovenian" }, | |
356 { lng( 's','o' ), "Somali" }, | |
357 { lng( 's','t' ), "Sotho" }, | |
358 { lng( 'e','s' ), "Spanish" }, | |
359 { lng( 's','u' ), "Sundanese" }, | |
360 { lng( 's','w' ), "Swahili" }, | |
361 { lng( 's','s' ), "Swati" }, | |
362 { lng( 's','v' ), "Swedish" }, | |
363 { lng( 't','l' ), "Tagalog" }, | |
364 { lng( 't','y' ), "Tahitian" }, | |
365 { lng( 't','g' ), "Tajik" }, | |
366 { lng( 't','a' ), "Tamil" }, | |
367 { lng( 't','t' ), "Tatar" }, | |
368 { lng( 't','e' ), "Telugu" }, | |
369 { lng( 't','h' ), "Thai" }, | |
370 { lng( 'b','o' ), "Tibetan" }, | |
371 { lng( 't','i' ), "Tigrinya" }, | |
372 { lng( 't','o' ), "Tonga" }, | |
373 { lng( 't','s' ), "Tsonga" }, | |
374 { lng( 't','n' ), "Tswana" }, | |
375 { lng( 't','r' ), "Turkish" }, | |
376 { lng( 't','k' ), "Turkmen" }, | |
377 { lng( 't','w' ), "Twi" }, | |
378 { lng( 'u','g' ), "Uighur" }, | |
379 { lng( 'u','k' ), "Ukrainian" }, | |
380 { lng( 'u','r' ), "Urdu" }, | |
381 { lng( 'u','z' ), "Uzbek" }, | |
382 { lng( 'v','i' ), "Vietnamese" }, | |
383 { lng( 'v','o' ), "Volapük" }, | |
384 { lng( 'c','y' ), "Welsh" }, | |
385 { lng( 'w','o' ), "Wolof" }, | |
386 { lng( 'x','h' ), "Xhosa" }, | |
387 { lng( 'y','i' ), "Yiddish" }, | |
388 { lng( 'j','i' ), "Yiddish" }, | |
389 { lng( 'y','o' ), "Yoruba" }, | |
390 { lng( 'z','a' ), "Zhuang" }, | |
391 { lng( 'z','u' ), "Zulu" }, | |
392 }; | |
393 #undef lng | |
394 | |
395 static char * ChannelTypes[] = | |
396 { "Dolby Digital","","Mpeg1","Mpeg2","PCM","","Digital Theatre System" }; | |
397 static char * ChannelNumbers[] = | |
398 { "","Stereo","","","","5.1" }; | |
399 | |
400 static const char * GetLanguage( int language ) | |
401 { | |
402 unsigned int i; | |
403 for ( i=0;i<sizeof( Languages ) / sizeof( Languages_t );i++ ) | |
404 if ( Languages[i].id == language ) return Languages[i].name; | |
35158 | 405 return "Unknown"; |
33572 | 406 } |
34454 | 407 #endif |
33572 | 408 |
409 | |
36028 | 410 static GtkWidget * DVDSubMenu; |
33572 | 411 GtkWidget * DVDTitleMenu; |
412 GtkWidget * DVDChapterMenu; | |
413 GtkWidget * DVDAudioLanguageMenu; | |
414 GtkWidget * DVDSubtitleLanguageMenu; | |
415 GtkWidget * AspectMenu; | |
416 GtkWidget * VCDSubMenu; | |
417 GtkWidget * VCDTitleMenu; | |
34387 | 418 GtkWidget * CDSubMenu; |
419 GtkWidget * CDTitleMenu; | |
33572 | 420 |
35996 | 421 GtkWidget * CreatePopUpMenu( void ) |
33572 | 422 { |
423 GtkWidget * window1; | |
424 GtkWidget * Menu = NULL; | |
425 GtkWidget * SubMenu = NULL; | |
426 GtkWidget * MenuItem = NULL; | |
427 GtkWidget * H, * N, * D, * F; | |
33657 | 428 demuxer_t *demuxer = mpctx_get_demuxer(guiInfo.mpcontext); |
33572 | 429 mixer_t *mixer = mpctx_get_mixer(guiInfo.mpcontext); |
430 int global_sub_size = mpctx_get_global_sub_size(guiInfo.mpcontext); | |
431 | |
432 Menu=gtk_menu_new(); | |
433 gtk_widget_realize (Menu); | |
434 window1 = gtk_widget_get_toplevel(Menu); | |
435 | |
436 | |
437 AddMenuItem( window1, (const char*)about_xpm, Menu,MSGTR_MENU_AboutMPlayer" ", evAbout ); | |
438 AddSeparator( Menu ); | |
439 SubMenu=AddSubMenu( window1, (const char*)open_xpm, Menu,MSGTR_MENU_Open ); | |
440 AddMenuItem( window1, (const char*)file2_xpm, SubMenu,MSGTR_MENU_PlayFile" ", evLoadPlay ); | |
34387 | 441 #ifdef CONFIG_CDDA |
442 AddMenuItem( window1, (const char*)playcd_xpm, SubMenu,MSGTR_MENU_PlayCD, evPlayCD ); | |
34419 | 443 CDSubMenu=AddSubMenu( window1, (const char*)cd_xpm, Menu,MSGTR_MENU_CD ); |
34387 | 444 AddMenuItem( window1, (const char*)playcd_xpm, CDSubMenu,MSGTR_MENU_PlayDisc,evPlayCD ); |
445 AddSeparator( CDSubMenu ); | |
446 CDTitleMenu=AddSubMenu( window1, (const char*)title_xpm, CDSubMenu,MSGTR_MENU_Titles ); | |
34420 | 447 if ( guiInfo.Tracks && ( guiInfo.StreamType == STREAMTYPE_CDDA ) ) |
34387 | 448 { |
449 char tmp[32]; int i; | |
450 for ( i=1;i <= guiInfo.Tracks;i++ ) | |
451 { | |
452 snprintf( tmp,32,MSGTR_MENU_Title,i ); | |
453 //AddMenuItem( CDTitleMenu,tmp,( i << 16 ) + ivSetCDTrack ); | |
34422
b1f2949ca18d
Use empty1px.xpm instead of empty.xpm for check item (and similar) menus.
ib
parents:
34421
diff
changeset
|
454 AddMenuCheckItem(window1, (const char*)empty1px_xpm, CDTitleMenu,tmp, guiInfo.Track == i, ( i << 16 ) + ivSetCDTrack ); |
34387 | 455 } |
456 } | |
457 else | |
458 { | |
34422
b1f2949ca18d
Use empty1px.xpm instead of empty.xpm for check item (and similar) menus.
ib
parents:
34421
diff
changeset
|
459 MenuItem=AddMenuItem( window1, (const char*)empty1px_xpm, CDTitleMenu,MSGTR_MENU_None,evNone ); |
34387 | 460 gtk_widget_set_sensitive( MenuItem,FALSE ); |
461 } | |
462 #endif | |
33572 | 463 #ifdef CONFIG_VCD |
34419 | 464 AddMenuItem( window1, (const char*)playvcd_xpm, SubMenu,MSGTR_MENU_PlayVCD, evPlayVCD ); |
465 VCDSubMenu=AddSubMenu( window1, (const char*)vcd_xpm, Menu,MSGTR_MENU_VCD ); | |
33572 | 466 AddMenuItem( window1, (const char*)playvcd_xpm, VCDSubMenu,MSGTR_MENU_PlayDisc,evPlayVCD ); |
467 AddSeparator( VCDSubMenu ); | |
468 VCDTitleMenu=AddSubMenu( window1, (const char*)title_xpm, VCDSubMenu,MSGTR_MENU_Titles ); | |
34420 | 469 if ( guiInfo.Tracks && ( guiInfo.StreamType == STREAMTYPE_VCD ) ) |
33572 | 470 { |
471 char tmp[32]; int i; | |
33876
4789b8eed97e
Get rid of a bunch of needless or redundant guiInfo members.
ib
parents:
33874
diff
changeset
|
472 for ( i=1;i < guiInfo.Tracks;i++ ) |
33572 | 473 { |
474 snprintf( tmp,32,MSGTR_MENU_Title,i ); | |
34333 | 475 //AddMenuItem( VCDTitleMenu,tmp,( i << 16 ) + ivSetVCDTrack ); |
34422
b1f2949ca18d
Use empty1px.xpm instead of empty.xpm for check item (and similar) menus.
ib
parents:
34421
diff
changeset
|
476 AddMenuCheckItem(window1, (const char*)empty1px_xpm, VCDTitleMenu,tmp, guiInfo.Track == i + 1, ( ( i + 1 ) << 16 ) + ivSetVCDTrack ); |
33572 | 477 } |
478 } | |
479 else | |
480 { | |
34422
b1f2949ca18d
Use empty1px.xpm instead of empty.xpm for check item (and similar) menus.
ib
parents:
34421
diff
changeset
|
481 MenuItem=AddMenuItem( window1, (const char*)empty1px_xpm, VCDTitleMenu,MSGTR_MENU_None,evNone ); |
33572 | 482 gtk_widget_set_sensitive( MenuItem,FALSE ); |
483 } | |
484 #endif | |
485 #ifdef CONFIG_DVDREAD | |
34419 | 486 AddMenuItem( window1, (const char*)playdvd_xpm, SubMenu,MSGTR_MENU_PlayDVD, evPlayDVD ); |
487 DVDSubMenu=AddSubMenu( window1, (const char*)dvd_xpm, Menu,MSGTR_MENU_DVD ); | |
33572 | 488 AddMenuItem( window1, (const char*)playdvd_xpm, DVDSubMenu,MSGTR_MENU_PlayDisc" ", evPlayDVD ); |
489 // AddMenuItem( DVDSubMenu,MSGTR_MENU_ShowDVDMenu, evNone ); | |
490 AddSeparator( DVDSubMenu ); | |
491 DVDTitleMenu=AddSubMenu( window1, (const char*)title_xpm, DVDSubMenu,MSGTR_MENU_Titles ); | |
34420 | 492 if ( guiInfo.Tracks && ( guiInfo.StreamType == STREAMTYPE_DVD ) ) |
33572 | 493 { |
494 char tmp[32]; int i; | |
33876
4789b8eed97e
Get rid of a bunch of needless or redundant guiInfo members.
ib
parents:
33874
diff
changeset
|
495 for ( i=1 ; i<= guiInfo.Tracks;i++ ) |
33572 | 496 { |
497 snprintf( tmp,32,MSGTR_MENU_Title,i); | |
498 AddMenuCheckItem( window1, (const char*)empty1px_xpm, DVDTitleMenu,tmp, | |
33876
4789b8eed97e
Get rid of a bunch of needless or redundant guiInfo members.
ib
parents:
33874
diff
changeset
|
499 guiInfo.Track == i, |
34333 | 500 (i << 16) + ivSetDVDTitle ); |
33572 | 501 } |
502 } | |
503 else | |
504 { | |
34422
b1f2949ca18d
Use empty1px.xpm instead of empty.xpm for check item (and similar) menus.
ib
parents:
34421
diff
changeset
|
505 MenuItem=AddMenuItem( window1, (const char*)empty1px_xpm, DVDTitleMenu,MSGTR_MENU_None,evNone ); |
33572 | 506 gtk_widget_set_sensitive( MenuItem,FALSE ); |
507 } | |
508 DVDChapterMenu=AddSubMenu( window1, (const char*)chapter_xpm, DVDSubMenu,MSGTR_MENU_Chapters ); | |
34420 | 509 if ( guiInfo.Chapters && ( guiInfo.StreamType == STREAMTYPE_DVD ) ) |
33572 | 510 { |
511 char tmp[32]; int i; | |
33876
4789b8eed97e
Get rid of a bunch of needless or redundant guiInfo members.
ib
parents:
33874
diff
changeset
|
512 for ( i=1;i <= guiInfo.Chapters;i++ ) |
33572 | 513 { |
514 snprintf( tmp,32,MSGTR_MENU_Chapter,i ); | |
33876
4789b8eed97e
Get rid of a bunch of needless or redundant guiInfo members.
ib
parents:
33874
diff
changeset
|
515 AddMenuCheckItem( window1, (const char*)empty1px_xpm, DVDChapterMenu,tmp,guiInfo.Chapter == i, |
34333 | 516 ( i << 16 ) + ivSetDVDChapter ); |
33572 | 517 } |
518 } | |
519 else | |
520 { | |
34422
b1f2949ca18d
Use empty1px.xpm instead of empty.xpm for check item (and similar) menus.
ib
parents:
34421
diff
changeset
|
521 MenuItem=AddMenuItem( window1, (const char*)empty1px_xpm, DVDChapterMenu,MSGTR_MENU_None,evNone ); |
33572 | 522 gtk_widget_set_sensitive( MenuItem,FALSE ); |
523 } | |
524 DVDAudioLanguageMenu=AddSubMenu( window1, (const char*)audiolang_xpm, DVDSubMenu,MSGTR_MENU_AudioLanguages ); | |
34420 | 525 if ( guiInfo.AudioStreams && ( guiInfo.StreamType == STREAMTYPE_DVD ) ) |
33572 | 526 { |
33657 | 527 char tmp[64]; int i, id = demuxer ? demuxer->audio->id : audio_id; |
33902 | 528 for ( i=0;i < guiInfo.AudioStreams;i++ ) |
33572 | 529 { |
33902 | 530 snprintf( tmp,64,"%s - %s %s",GetLanguage( guiInfo.AudioStream[i].language ), |
531 ChannelTypes[ guiInfo.AudioStream[i].type ], | |
532 ChannelNumbers[ guiInfo.AudioStream[i].channels ] ); | |
533 // if ( id == -1 ) id=audio_id; //guiInfo.AudioStream[i].id; | |
33572 | 534 AddMenuCheckItem( window1, (const char*)dolby_xpm, DVDAudioLanguageMenu,tmp, |
33902 | 535 id == guiInfo.AudioStream[i].id, |
34333 | 536 ( guiInfo.AudioStream[i].id << 16 ) + ivSetDVDAudio ); |
33572 | 537 } |
538 } | |
539 else | |
540 { | |
34422
b1f2949ca18d
Use empty1px.xpm instead of empty.xpm for check item (and similar) menus.
ib
parents:
34421
diff
changeset
|
541 MenuItem=AddMenuItem( window1, (const char*)empty1px_xpm, DVDAudioLanguageMenu,MSGTR_MENU_None,evNone ); |
33572 | 542 gtk_widget_set_sensitive( MenuItem,FALSE ); |
543 } | |
544 DVDSubtitleLanguageMenu=AddSubMenu( window1, (const char*)sublang_xpm, DVDSubMenu,MSGTR_MENU_SubtitleLanguages ); | |
34420 | 545 if ( guiInfo.Subtitles && ( guiInfo.StreamType == STREAMTYPE_DVD ) ) |
33572 | 546 { |
547 char tmp[64]; int i; | |
34333 | 548 AddMenuItem( window1, (const char*)empty1px_xpm, DVDSubtitleLanguageMenu,MSGTR_MENU_None,( (unsigned short)-1 << 16 ) + ivSetDVDSubtitle ); |
33902 | 549 for ( i=0;i < guiInfo.Subtitles;i++ ) |
33572 | 550 { |
33902 | 551 av_strlcpy( tmp,GetLanguage( guiInfo.Subtitle[i].language ),sizeof(tmp) ); |
33572 | 552 AddMenuCheckItem( window1, (const char*)empty1px_xpm, DVDSubtitleLanguageMenu,tmp, |
33902 | 553 dvdsub_id == guiInfo.Subtitle[i].id, |
34333 | 554 ( guiInfo.Subtitle[i].id << 16 ) + ivSetDVDSubtitle ); |
33572 | 555 } |
556 } | |
557 else | |
558 { | |
34422
b1f2949ca18d
Use empty1px.xpm instead of empty.xpm for check item (and similar) menus.
ib
parents:
34421
diff
changeset
|
559 MenuItem=AddMenuItem( window1, (const char*)empty1px_xpm, DVDSubtitleLanguageMenu,MSGTR_MENU_None,evNone ); |
33572 | 560 gtk_widget_set_sensitive( MenuItem,FALSE ); |
561 } | |
562 #endif | |
34419 | 563 AddMenuItem( window1, (const char*)url_xpm, SubMenu,MSGTR_MENU_PlayURL, evLoadURL ); |
564 AddMenuItem( window1, (const char*)sub_xpm, SubMenu,MSGTR_MENU_LoadSubtitle" ", evLoadSubtitle ); | |
565 AddMenuItem( window1, (const char*)nosub_xpm, SubMenu,MSGTR_MENU_DropSubtitle,evDropSubtitle ); | |
566 AddMenuItem( window1, (const char*)loadeaf_xpm, SubMenu,MSGTR_MENU_LoadExternAudioFile, evLoadAudioFile ); | |
567 SubMenu=AddSubMenu(window1, (const char*)play_xpm, Menu,MSGTR_MENU_Playing ); | |
568 AddMenuItem( window1, (const char*)play_xpm, SubMenu,MSGTR_MENU_Play" ", evPlay ); | |
569 AddMenuItem( window1, (const char*)pause_xpm, SubMenu,MSGTR_MENU_Pause, evPause ); | |
570 AddMenuItem( window1, (const char*)stop_xpm, SubMenu,MSGTR_MENU_Stop, evStop ); | |
571 AddMenuItem( window1, (const char*)next_xpm, SubMenu,MSGTR_MENU_NextStream, evNext ); | |
572 AddMenuItem( window1, (const char*)prev_xpm, SubMenu,MSGTR_MENU_PrevStream, evPrev ); | |
573 // AddSeparator( SubMenu ); | |
574 // AddMenuItem( SubMenu,"Back 10 sec", evBackward10sec ); | |
575 // AddMenuItem( SubMenu,"Fwd 10 sec", evForward10sec ); | |
576 // AddMenuItem( SubMenu,"Back 1 min", evBackward1min ); | |
577 // AddMenuItem( SubMenu,"Fwd 1 min", evForward1min ); | |
578 // SubMenu=AddSubMenu( Menu,MSGTR_MENU_Size ); | |
579 // AddMenuItem( SubMenu,MSGTR_MENU_NormalSize" ", evNormalSize ); | |
580 // AddMenuItem( SubMenu,MSGTR_MENU_DoubleSize, evDoubleSize ); | |
35605
71f19d352561
Fix bug with wrong video window size after end of fullscreen playback.
ib
parents:
35529
diff
changeset
|
581 // AddMenuItem( SubMenu,MSGTR_MENU_FullScreen, evFullScreen + ( True << 16 ) ); |
33572 | 582 |
36261
ca1d4a7bb751
Disable aspect ratio menu in the absence of video playback.
ib
parents:
36029
diff
changeset
|
583 if ( guiInfo.VideoWindow ) |
33572 | 584 { |
36273 | 585 int a11 = False, a169 = False, a43 = False, a235 = False; |
586 | |
36316
139f2b064ef9
Don't subsequently calculate original_aspect from last movie_aspect.
ib
parents:
36297
diff
changeset
|
587 if (movie_aspect == -1.0f) a11 = True; |
36273 | 588 else |
589 { | |
590 a169 = (FFABS(movie_aspect - 16.0f / 9.0f) <= 0.01f); | |
591 a43 = (FFABS(movie_aspect - 4.0f / 3.0f) <= 0.01f); | |
36276 | 592 a235 = (FFABS(movie_aspect - 2.35f) <= 0.01f); |
36273 | 593 } |
594 | |
33572 | 595 AspectMenu=AddSubMenu( window1, (const char*)aspect_xpm, Menu,MSGTR_MENU_AspectRatio ); |
36273 | 596 H=AddMenuCheckItem( window1, (const char*)aspect11_xpm, AspectMenu,MSGTR_MENU_Original, a11, evSetAspect + ( 1 << 16 ) ); |
597 N=AddMenuCheckItem( window1, (const char*)aspect169_xpm, AspectMenu,"16:9", a169, evSetAspect + ( 2 << 16 ) ); | |
598 D=AddMenuCheckItem( window1, (const char*)aspect43_xpm, AspectMenu,"4:3", a43, evSetAspect + ( 3 << 16 ) ); | |
36278 | 599 F=AddMenuCheckItem( window1, (const char*)aspect235_xpm, AspectMenu,MSGTR_MENU_235, a235, evSetAspect + ( 4 << 16 ) ); |
36261
ca1d4a7bb751
Disable aspect ratio menu in the absence of video playback.
ib
parents:
36029
diff
changeset
|
600 |
ca1d4a7bb751
Disable aspect ratio menu in the absence of video playback.
ib
parents:
36029
diff
changeset
|
601 if ( !guiInfo.Playing ) |
ca1d4a7bb751
Disable aspect ratio menu in the absence of video playback.
ib
parents:
36029
diff
changeset
|
602 { |
ca1d4a7bb751
Disable aspect ratio menu in the absence of video playback.
ib
parents:
36029
diff
changeset
|
603 gtk_widget_set_sensitive( H,FALSE ); |
ca1d4a7bb751
Disable aspect ratio menu in the absence of video playback.
ib
parents:
36029
diff
changeset
|
604 gtk_widget_set_sensitive( N,FALSE ); |
ca1d4a7bb751
Disable aspect ratio menu in the absence of video playback.
ib
parents:
36029
diff
changeset
|
605 gtk_widget_set_sensitive( D,FALSE ); |
ca1d4a7bb751
Disable aspect ratio menu in the absence of video playback.
ib
parents:
36029
diff
changeset
|
606 gtk_widget_set_sensitive( F,FALSE ); |
ca1d4a7bb751
Disable aspect ratio menu in the absence of video playback.
ib
parents:
36029
diff
changeset
|
607 } |
33572 | 608 } |
609 | |
33657 | 610 if ( guiInfo.Playing && demuxer && guiInfo.StreamType != STREAMTYPE_DVD ) |
33572 | 611 { |
612 int i,c = 0; | |
613 | |
614 for ( i=0;i < MAX_A_STREAMS;i++ ) | |
33657 | 615 if ( demuxer->a_streams[i] ) c++; |
33572 | 616 |
617 if ( c > 1 ) | |
618 { | |
619 SubMenu=AddSubMenu( window1, (const char*)empty_xpm, Menu,MSGTR_MENU_AudioTrack ); | |
620 for ( i=0;i < MAX_A_STREAMS;i++ ) | |
33657 | 621 if ( demuxer->a_streams[i] ) |
33572 | 622 { |
33657 | 623 int aid = ((sh_audio_t *)demuxer->a_streams[i])->aid; |
34555
da67e2df97be
Emphasize the default audio track in the selection list.
ib
parents:
34479
diff
changeset
|
624 int selected_id = (audio_id == aid || (audio_id == -1 && aid == demuxer_default_audio_track(mpctx_get_demuxer(guiInfo.mpcontext)))); |
33572 | 625 char tmp[32]; |
626 snprintf( tmp,32,MSGTR_MENU_Track,aid ); | |
34555
da67e2df97be
Emphasize the default audio track in the selection list.
ib
parents:
34479
diff
changeset
|
627 AddMenuCheckItem( window1, (const char*)empty1px_xpm, SubMenu,tmp,selected_id,( aid << 16 ) + ivSetAudio ); |
33572 | 628 } |
629 } | |
630 | |
631 for ( c=0,i=0;i < MAX_V_STREAMS;i++ ) | |
33657 | 632 if ( demuxer->v_streams[i] ) c++; |
33572 | 633 |
634 if ( c > 1 ) | |
635 { | |
636 SubMenu=AddSubMenu( window1, (const char*)empty_xpm, Menu,MSGTR_MENU_VideoTrack ); | |
637 for ( i=0;i < MAX_V_STREAMS;i++ ) | |
33657 | 638 if ( demuxer->v_streams[i] ) |
33572 | 639 { |
33657 | 640 int vid = ((sh_video_t *)demuxer->v_streams[i])->vid; |
33572 | 641 char tmp[32]; |
642 snprintf( tmp,32,MSGTR_MENU_Track,vid ); | |
34479 | 643 AddMenuCheckItem( window1, (const char*)empty1px_xpm, SubMenu,tmp,video_id == vid,( vid << 16 ) + ivSetVideo ); |
33572 | 644 } |
645 } | |
646 } | |
647 | |
648 /* cheap subtitle switching for non-DVD streams */ | |
649 if ( global_sub_size && guiInfo.StreamType != STREAMTYPE_DVD ) | |
650 { | |
651 int i; | |
34903 | 652 SubMenu=AddSubMenu( window1, (const char*)subtitle_xpm, Menu, MSGTR_MENU_Subtitles ); |
34902 | 653 AddMenuCheckItem( window1, (const char*)empty1px_xpm, SubMenu, MSGTR_MENU_None, guiInfo.mpcontext->global_sub_pos == -1, (-1 << 16) + ivSetSubtitle ); |
33572 | 654 for ( i=0;i < global_sub_size;i++ ) |
655 { | |
656 char tmp[32]; | |
657 snprintf( tmp, 32, MSGTR_MENU_Track, i ); | |
34479 | 658 AddMenuCheckItem( window1,(const char*)empty1px_xpm,SubMenu,tmp,guiInfo.mpcontext->global_sub_pos == i,( i << 16 ) + ivSetSubtitle ); |
33572 | 659 } |
660 } | |
661 | |
662 AddSeparator( Menu ); | |
663 MenuItem=AddMenuCheckItem( window1, (const char*)sound_xpm, Menu,MSGTR_MENU_Mute,mixer->muted,evMute ); | |
33646 | 664 if ( !guiInfo.AudioChannels ) gtk_widget_set_sensitive( MenuItem,FALSE ); |
34321
daebf766dea6
Cosmetic: Synchronize evPlaylist event and message names.
ib
parents:
34077
diff
changeset
|
665 AddMenuItem( window1, (const char*)playlist_xpm, Menu,MSGTR_MENU_PlayList, evPlaylist ); |
33572 | 666 AddMenuItem( window1, (const char*)skin_xpm, Menu,MSGTR_MENU_SkinBrowser, evSkinBrowser ); |
667 AddMenuItem( window1, (const char*)prefs_xpm, Menu,MSGTR_MENU_Preferences, evPreferences ); | |
668 AddMenuItem( window1, (const char*)equalizer_xpm, Menu,MSGTR_Equalizer, evEqualizer ); | |
669 | |
33901 | 670 if ( guiInfo.VideoWindow ) |
33572 | 671 { |
35493 | 672 int b1 = False, b2 = False, b_half = False; |
33572 | 673 AddSeparator( Menu ); |
34697 | 674 if ( !guiApp.videoWindow.isFullScreen && guiInfo.Playing ) |
33572 | 675 { |
34697 | 676 if ( ( guiApp.videoWindow.Width == guiInfo.VideoWidth * 2 )&& |
35493 | 677 ( guiApp.videoWindow.Height == guiInfo.VideoHeight * 2 ) ) b2=True; |
34697 | 678 else if ( ( guiApp.videoWindow.Width == guiInfo.VideoWidth / 2 ) && |
35493 | 679 ( guiApp.videoWindow.Height == guiInfo.VideoHeight / 2 ) ) b_half=True; |
35686
e56df184e118
Don't set "normal size" check mark in menu by default.
ib
parents:
35606
diff
changeset
|
680 else b1=( guiApp.videoWindow.Width == guiInfo.VideoWidth && guiApp.videoWindow.Height == guiInfo.VideoHeight ); |
34697 | 681 } else b1=!guiApp.videoWindow.isFullScreen; |
33572 | 682 H=AddMenuCheckItem( window1, (const char*)half_xpm, Menu,MSGTR_MENU_HalfSize,b_half,evHalfSize ); |
683 N=AddMenuCheckItem( window1, (const char*)normal_xpm, Menu,MSGTR_MENU_NormalSize" ",b1,evNormalSize ); | |
684 D=AddMenuCheckItem( window1, (const char*)double_xpm, Menu,MSGTR_MENU_DoubleSize,b2,evDoubleSize ); | |
35605
71f19d352561
Fix bug with wrong video window size after end of fullscreen playback.
ib
parents:
35529
diff
changeset
|
685 F=AddMenuCheckItem( window1, (const char*)full_xpm, Menu,MSGTR_MENU_FullScreen,guiApp.videoWindow.isFullScreen,evFullScreen + ( True << 16 ) ); |
33951 | 686 if ( !guiInfo.Playing ) |
33572 | 687 { |
688 gtk_widget_set_sensitive( H,FALSE ); | |
689 gtk_widget_set_sensitive( N,FALSE ); | |
690 gtk_widget_set_sensitive( D,FALSE ); | |
691 gtk_widget_set_sensitive( F,FALSE ); | |
692 } | |
693 } | |
694 | |
695 AddSeparator( Menu ); | |
696 AddMenuItem( window1, (const char*)exit_xpm, Menu,MSGTR_MENU_Exit, evExit ); | |
697 | |
698 return Menu; | |
699 } |