Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

menus.cpp

00001 /*****************************************************************************
00002  * menus.cpp : wxWidgets plugin for vlc
00003  *****************************************************************************
00004  * Copyright (C) 2000-2004 the VideoLAN team
00005  * $Id: menus.cpp 12056 2005-08-07 10:56:07Z ipkiss $
00006  *
00007  * Authors: Gildas Bazin <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <stdlib.h>                                      /* malloc(), free() */
00028 #include <errno.h>                                                 /* ENOMEM */
00029 #include <string.h>                                            /* strerror() */
00030 #include <stdio.h>
00031 
00032 #include <vlc/vlc.h>
00033 #include <vlc/intf.h>
00034 
00035 #include "wxwidgets.h"
00036 
00037 class wxMenuItemExt: public wxMenuItem
00038 {
00039 public:
00040     /* Constructor */
00041     wxMenuItemExt( wxMenu* parentMenu, int id, const wxString& text,
00042                    const wxString& helpString, wxItemKind kind,
00043                    char *_psz_var, int _i_object_id, vlc_value_t _val,
00044                    int _i_val_type );
00045 
00046     virtual ~wxMenuItemExt();
00047 
00048     char *psz_var;
00049     int  i_val_type;
00050     int  i_object_id;
00051     vlc_value_t val;
00052 
00053 private:
00054 
00055 };
00056 
00057 class Menu: public wxMenu
00058 {
00059 public:
00060     /* Constructor */
00061     Menu( intf_thread_t *p_intf, int i_start_id );
00062     virtual ~Menu();
00063 
00064     void Populate( int i_count, char **ppsz_names, int *pi_objects );
00065     void Clear();
00066 
00067 private:
00068     wxMenu *Menu::CreateDummyMenu();
00069     void   Menu::CreateMenuItem( wxMenu *, char *, vlc_object_t * );
00070     wxMenu *Menu::CreateChoicesMenu( char *, vlc_object_t *, bool );
00071 
00072     DECLARE_EVENT_TABLE();
00073 
00074     intf_thread_t *p_intf;
00075 
00076     int i_start_id;
00077     int i_item_id;
00078 };
00079 
00080 /*****************************************************************************
00081  * Event Table.
00082  *****************************************************************************/
00083 
00084 /* IDs for the controls and the menu commands */
00085 enum
00086 {
00087     /* menu items */
00088     MenuDummy_Event = wxID_HIGHEST + 1000,
00089     OpenFileSimple_Event = wxID_HIGHEST + 1100,
00090     OpenFile_Event,
00091     OpenDirectory_Event,
00092     OpenDisc_Event,
00093     OpenNet_Event,
00094     OpenCapture_Event,
00095     MediaInfo_Event,
00096     Messages_Event,
00097     Preferences_Event,
00098     Play_Event,
00099     Pause_Event,
00100     Previous_Event,
00101     Next_Event,
00102     Stop_Event,
00103     FirstAutoGenerated_Event = wxID_HIGHEST + 1999,
00104     SettingsMenu_Events = wxID_HIGHEST + 5000,
00105     AudioMenu_Events = wxID_HIGHEST + 2000,
00106     VideoMenu_Events = wxID_HIGHEST + 3000,
00107     NavigMenu_Events = wxID_HIGHEST + 4000,
00108     PopupMenu_Events = wxID_HIGHEST + 6000,
00109     Hotkeys_Events = wxID_HIGHEST + 7000
00110 };
00111 
00112 BEGIN_EVENT_TABLE(Menu, wxMenu)
00113 END_EVENT_TABLE()
00114 
00115 BEGIN_EVENT_TABLE(MenuEvtHandler, wxEvtHandler)
00116     EVT_MENU(OpenFileSimple_Event, MenuEvtHandler::OnShowDialog)
00117     EVT_MENU(OpenFile_Event, MenuEvtHandler::OnShowDialog)
00118     EVT_MENU(OpenDirectory_Event, MenuEvtHandler::OnShowDialog)
00119     EVT_MENU(OpenDisc_Event, MenuEvtHandler::OnShowDialog)
00120     EVT_MENU(OpenNet_Event, MenuEvtHandler::OnShowDialog)
00121     EVT_MENU(OpenCapture_Event, MenuEvtHandler::OnShowDialog)
00122     EVT_MENU(MediaInfo_Event, MenuEvtHandler::OnShowDialog)
00123     EVT_MENU(Messages_Event, MenuEvtHandler::OnShowDialog)
00124     EVT_MENU(Preferences_Event, MenuEvtHandler::OnShowDialog)
00125     EVT_MENU(-1, MenuEvtHandler::OnMenuEvent)
00126 END_EVENT_TABLE()
00127 
00128 wxMenu *OpenStreamMenu( intf_thread_t *p_intf )
00129 {
00130     wxMenu *menu = new wxMenu;
00131     menu->Append( OpenFileSimple_Event, wxU(_("Quick &Open File...")) );
00132     menu->Append( OpenFile_Event, wxU(_("Open &File...")) );
00133     menu->Append( OpenDirectory_Event, wxU(_("Open D&irectory...")) );
00134     menu->Append( OpenDisc_Event, wxU(_("Open &Disc...")) );
00135     menu->Append( OpenNet_Event, wxU(_("Open &Network Stream...")) );
00136     menu->Append( OpenCapture_Event, wxU(_("Open &Capture Device...")) );
00137     return menu;
00138 }
00139 
00140 wxMenu *MiscMenu( intf_thread_t *p_intf )
00141 {
00142     wxMenu *menu = new wxMenu;
00143     menu->Append( MediaInfo_Event, wxU(_("Media &Info...")) );
00144     menu->Append( Messages_Event, wxU(_("&Messages...")) );
00145     menu->Append( Preferences_Event, wxU(_("&Preferences...")) );
00146     return menu;
00147 }
00148 
00149 void PopupMenu( intf_thread_t *p_intf, wxWindow *p_parent,
00150                 const wxPoint& pos )
00151 {
00152 #define MAX_POPUP_ITEMS 45
00153 
00154     int minimal = config_GetInt( p_intf, "wx-minimal" );
00155 
00156     vlc_object_t *p_object, *p_input;
00157     char *ppsz_varnames[MAX_POPUP_ITEMS];
00158     int pi_objects[MAX_POPUP_ITEMS];
00159     int i = 0, i_last_separator = 0;
00160 
00161     /* Initializations */
00162     memset( pi_objects, 0, MAX_POPUP_ITEMS * sizeof(int) );
00163 
00164     /* Input menu */
00165     p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
00166                                                 FIND_ANYWHERE );
00167     if( p_object != NULL )
00168     {
00169         ppsz_varnames[i] = "bookmark";
00170         pi_objects[i++] = p_object->i_object_id;
00171         ppsz_varnames[i] = "title";
00172         pi_objects[i++] = p_object->i_object_id;
00173         ppsz_varnames[i] = "chapter";
00174         pi_objects[i++] = p_object->i_object_id;
00175         ppsz_varnames[i] = "program";
00176         pi_objects[i++] = p_object->i_object_id;
00177         ppsz_varnames[i] = "navigation";
00178         pi_objects[i++] = p_object->i_object_id;
00179         ppsz_varnames[i] = "dvd_menus";
00180         pi_objects[i++] = p_object->i_object_id;
00181 
00182         ppsz_varnames[i] = "video-es";
00183         pi_objects[i++] = p_object->i_object_id;
00184         ppsz_varnames[i] = "audio-es";
00185         pi_objects[i++] = p_object->i_object_id;
00186         ppsz_varnames[i] = "spu-es";
00187         pi_objects[i++] = p_object->i_object_id;
00188     }
00189     p_input = p_object;
00190     if( !p_input ) goto interfacemenu;
00191 
00192     /* Video menu */
00193     if( i != i_last_separator ) ppsz_varnames[i++] = NULL; /* Separator */
00194     i_last_separator = i;
00195 
00196     p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
00197                                                 FIND_ANYWHERE );
00198     if( p_object != NULL )
00199     {
00200         vlc_object_t *p_dec_obj;
00201 
00202         ppsz_varnames[i] = "fullscreen";
00203         pi_objects[i++] = p_object->i_object_id;
00204         ppsz_varnames[i] = "zoom";
00205         pi_objects[i++] = p_object->i_object_id;
00206         ppsz_varnames[i] = "deinterlace";
00207         pi_objects[i++] = p_object->i_object_id;
00208         ppsz_varnames[i] = "aspect-ratio";
00209         pi_objects[i++] = p_object->i_object_id;
00210         ppsz_varnames[i] = "crop";
00211         pi_objects[i++] = p_object->i_object_id;
00212         ppsz_varnames[i] = "video-on-top";
00213         pi_objects[i++] = p_object->i_object_id;
00214         ppsz_varnames[i] = "directx-wallpaper";
00215         pi_objects[i++] = p_object->i_object_id;
00216         ppsz_varnames[i] = "video-snapshot";
00217         pi_objects[i++] = p_object->i_object_id;
00218 
00219         p_dec_obj = (vlc_object_t *)vlc_object_find( p_object,
00220                                                      VLC_OBJECT_DECODER,
00221                                                      FIND_PARENT );
00222         if( p_dec_obj != NULL )
00223         {
00224             ppsz_varnames[i] = "ffmpeg-pp-q";
00225             pi_objects[i++] = p_dec_obj->i_object_id;
00226             vlc_object_release( p_dec_obj );
00227         }
00228 
00229         vlc_object_release( p_object );
00230     }
00231 
00232     /* Audio menu */
00233     if( i != i_last_separator ) ppsz_varnames[i++] = NULL; /* Separator */
00234     i_last_separator  = i;
00235 
00236     p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
00237                                                 FIND_ANYWHERE );
00238     if( p_object != NULL )
00239     {
00240         ppsz_varnames[i] = "audio-device";
00241         pi_objects[i++] = p_object->i_object_id;
00242         ppsz_varnames[i] = "audio-channels";
00243         pi_objects[i++] = p_object->i_object_id;
00244         ppsz_varnames[i] = "visual";
00245         pi_objects[i++] = p_object->i_object_id;
00246         ppsz_varnames[i] = "equalizer";
00247         pi_objects[i++] = p_object->i_object_id;
00248         vlc_object_release( p_object );
00249     }
00250 
00251  interfacemenu:
00252     /* Interface menu */
00253     if( i != i_last_separator ) ppsz_varnames[i++] = NULL; /* Separator */
00254     i_last_separator = i;
00255 
00256     /* vlc_object_find is needed because of the dialogs provider case */
00257     p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_INTF,
00258                                                 FIND_PARENT );
00259     if( p_object != NULL )
00260     {
00261 #if (wxCHECK_VERSION(2,5,0))
00262         ppsz_varnames[i] = "intf-switch";
00263         pi_objects[i++] = p_object->i_object_id;
00264 #endif
00265         ppsz_varnames[i] = "intf-add";
00266         pi_objects[i++] = p_object->i_object_id;
00267         ppsz_varnames[i] = "intf-skins";
00268         pi_objects[i++] = p_object->i_object_id;
00269 
00270         vlc_object_release( p_object );
00271     }
00272 
00273     /* Build menu */
00274     Menu popupmenu( p_intf, PopupMenu_Events );
00275     popupmenu.Populate( i, ppsz_varnames, pi_objects );
00276 
00277     /* Add static entries */
00278     if( p_input != NULL )
00279     {
00280         vlc_value_t val;
00281         popupmenu.InsertSeparator( 0 );
00282         if (!minimal)
00283         {
00284         popupmenu.Insert( 0, Stop_Event, wxU(_("Stop")) );
00285         popupmenu.Insert( 0, Previous_Event, wxU(_("Previous")) );
00286         popupmenu.Insert( 0, Next_Event, wxU(_("Next")) );
00287         }
00288 
00289         var_Get( p_input, "state", &val );
00290         if( val.i_int == PAUSE_S )
00291             popupmenu.Insert( 0, Play_Event, wxU(_("Play")) );
00292         else
00293             popupmenu.Insert( 0, Pause_Event, wxU(_("Pause")) );
00294 
00295         vlc_object_release( p_input );
00296     }
00297     else
00298     {
00299         playlist_t * p_playlist =
00300             (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00301                                            FIND_ANYWHERE );
00302         if( p_playlist && p_playlist->i_size )
00303         {
00304             popupmenu.InsertSeparator( 0 );
00305             popupmenu.Insert( 0, Play_Event, wxU(_("Play")) );
00306         }
00307         if( p_playlist ) vlc_object_release( p_playlist );
00308     }
00309 
00310     popupmenu.Append( MenuDummy_Event, wxU(_("Miscellaneous")),
00311                       MiscMenu( p_intf ), wxT("") );
00312     if (!minimal)
00313     {
00314     popupmenu.Append( MenuDummy_Event, wxU(_("Open")),
00315                       OpenStreamMenu( p_intf ), wxT("") );
00316     }
00317 
00318     p_intf->p_sys->p_popup_menu = &popupmenu;
00319     p_parent->PopupMenu( &popupmenu, pos.x, pos.y );
00320     p_intf->p_sys->p_popup_menu = NULL;
00321 }
00322 
00323 wxMenu *AudioMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
00324 {
00325 #define MAX_AUDIO_ITEMS 10
00326 
00327     vlc_object_t *p_object;
00328     char *ppsz_varnames[MAX_AUDIO_ITEMS];
00329     int pi_objects[MAX_AUDIO_ITEMS];
00330     int i = 0;
00331 
00332     /* Initializations */
00333     memset( pi_objects, 0, MAX_AUDIO_ITEMS * sizeof(int) );
00334 
00335     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
00336                                                 FIND_ANYWHERE );
00337     if( p_object != NULL )
00338     {
00339         ppsz_varnames[i] = "audio-es";
00340         pi_objects[i++] = p_object->i_object_id;
00341         vlc_object_release( p_object );
00342     }
00343 
00344     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_AOUT,
00345                                                 FIND_ANYWHERE );
00346     if( p_object != NULL )
00347     {
00348         ppsz_varnames[i] = "audio-device";
00349         pi_objects[i++] = p_object->i_object_id;
00350         ppsz_varnames[i] = "audio-channels";
00351         pi_objects[i++] = p_object->i_object_id;
00352         ppsz_varnames[i] = "visual";
00353         pi_objects[i++] = p_object->i_object_id;
00354         ppsz_varnames[i] = "equalizer";
00355         pi_objects[i++] = p_object->i_object_id;
00356         vlc_object_release( p_object );
00357     }
00358 
00359     /* Build menu */
00360     Menu *p_vlc_menu = (Menu *)p_menu;
00361     if( !p_vlc_menu )
00362         p_vlc_menu = new Menu( _p_intf, AudioMenu_Events );
00363     else
00364         p_vlc_menu->Clear();
00365 
00366     p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
00367 
00368     return p_vlc_menu;
00369 }
00370 
00371 wxMenu *VideoMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
00372 {
00373 #define MAX_VIDEO_ITEMS 15
00374 
00375     vlc_object_t *p_object;
00376     char *ppsz_varnames[MAX_VIDEO_ITEMS];
00377     int pi_objects[MAX_VIDEO_ITEMS];
00378     int i = 0;
00379 
00380     /* Initializations */
00381     memset( pi_objects, 0, MAX_VIDEO_ITEMS * sizeof(int) );
00382 
00383     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
00384                                                 FIND_ANYWHERE );
00385     if( p_object != NULL )
00386     {
00387         ppsz_varnames[i] = "video-es";
00388         pi_objects[i++] = p_object->i_object_id;
00389         ppsz_varnames[i] = "spu-es";
00390         pi_objects[i++] = p_object->i_object_id;
00391         vlc_object_release( p_object );
00392     }
00393 
00394     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_VOUT,
00395                                                 FIND_ANYWHERE );
00396     if( p_object != NULL )
00397     {
00398         vlc_object_t *p_dec_obj;
00399 
00400         ppsz_varnames[i] = "fullscreen";
00401         pi_objects[i++] = p_object->i_object_id;
00402         ppsz_varnames[i] = "zoom";
00403         pi_objects[i++] = p_object->i_object_id;
00404         ppsz_varnames[i] = "deinterlace";
00405         pi_objects[i++] = p_object->i_object_id;
00406         ppsz_varnames[i] = "aspect-ratio";
00407         pi_objects[i++] = p_object->i_object_id;
00408         ppsz_varnames[i] = "crop";
00409         pi_objects[i++] = p_object->i_object_id;
00410         ppsz_varnames[i] = "video-on-top";
00411         pi_objects[i++] = p_object->i_object_id;
00412         ppsz_varnames[i] = "directx-wallpaper";
00413         pi_objects[i++] = p_object->i_object_id;
00414         ppsz_varnames[i] = "video-snapshot";
00415         pi_objects[i++] = p_object->i_object_id;
00416 
00417         p_dec_obj = (vlc_object_t *)vlc_object_find( p_object,
00418                                                      VLC_OBJECT_DECODER,
00419                                                      FIND_PARENT );
00420         if( p_dec_obj != NULL )
00421         {
00422             ppsz_varnames[i] = "ffmpeg-pp-q";
00423             pi_objects[i++] = p_dec_obj->i_object_id;
00424             vlc_object_release( p_dec_obj );
00425         }
00426 
00427         vlc_object_release( p_object );
00428     }
00429 
00430     /* Build menu */
00431     Menu *p_vlc_menu = (Menu *)p_menu;
00432     if( !p_vlc_menu )
00433         p_vlc_menu = new Menu( _p_intf, VideoMenu_Events );
00434     else
00435         p_vlc_menu->Clear();
00436 
00437     p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
00438 
00439     return p_vlc_menu;
00440 }
00441 
00442 wxMenu *NavigMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
00443 {
00444 #define MAX_NAVIG_ITEMS 15
00445 
00446     vlc_object_t *p_object;
00447     char *ppsz_varnames[MAX_NAVIG_ITEMS];
00448     int pi_objects[MAX_NAVIG_ITEMS];
00449     int i = 0;
00450 
00451     /* Initializations */
00452     memset( pi_objects, 0, MAX_NAVIG_ITEMS * sizeof(int) );
00453 
00454     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
00455                                                 FIND_ANYWHERE );
00456     if( p_object != NULL )
00457     {
00458         ppsz_varnames[i] = "bookmark";
00459         pi_objects[i++] = p_object->i_object_id;
00460         ppsz_varnames[i] = "title";
00461         pi_objects[i++] = p_object->i_object_id;
00462         ppsz_varnames[i] = "chapter";
00463         pi_objects[i++] = p_object->i_object_id;
00464         ppsz_varnames[i] = "program";
00465         pi_objects[i++] = p_object->i_object_id;
00466         ppsz_varnames[i] = "navigation";
00467         pi_objects[i++] = p_object->i_object_id;
00468         ppsz_varnames[i] = "dvd_menus";
00469         pi_objects[i++] = p_object->i_object_id;
00470 
00471         ppsz_varnames[i] = "prev-title";
00472         pi_objects[i++] = p_object->i_object_id;
00473         ppsz_varnames[i] = "next-title";
00474         pi_objects[i++] = p_object->i_object_id;
00475         ppsz_varnames[i] = "prev-chapter";
00476         pi_objects[i++] = p_object->i_object_id;
00477         ppsz_varnames[i] = "next-chapter";
00478         pi_objects[i++] = p_object->i_object_id;
00479 
00480         vlc_object_release( p_object );
00481     }
00482 
00483     /* Build menu */
00484     Menu *p_vlc_menu = (Menu *)p_menu;
00485     if( !p_vlc_menu )
00486         p_vlc_menu = new Menu( _p_intf, NavigMenu_Events );
00487     else
00488         p_vlc_menu->Clear();
00489 
00490     p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
00491 
00492     return p_vlc_menu;
00493 }
00494 
00495 wxMenu *SettingsMenu( intf_thread_t *_p_intf, wxWindow *p_parent,
00496                       wxMenu *p_menu )
00497 {
00498 #define MAX_SETTINGS_ITEMS 10
00499 
00500     vlc_object_t *p_object;
00501     char *ppsz_varnames[MAX_SETTINGS_ITEMS];
00502     int pi_objects[MAX_SETTINGS_ITEMS];
00503     int i = 0;
00504 
00505     /* Initializations */
00506     memset( pi_objects, 0, MAX_SETTINGS_ITEMS * sizeof(int) );
00507 
00508     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INTF,
00509                                                 FIND_PARENT );
00510     if( p_object != NULL )
00511     {
00512 #if (wxCHECK_VERSION(2,5,0))
00513         ppsz_varnames[i] = "intf-switch";
00514         pi_objects[i++] = p_object->i_object_id;
00515 #endif
00516         ppsz_varnames[i] = "intf-add";
00517         pi_objects[i++] = p_object->i_object_id;
00518         vlc_object_release( p_object );
00519     }
00520 
00521     /* Build menu */
00522     Menu *p_vlc_menu = (Menu *)p_menu;
00523     if( !p_vlc_menu )
00524         p_vlc_menu = new Menu( _p_intf, SettingsMenu_Events );
00525     else
00526         p_vlc_menu->Clear();
00527 
00528     p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
00529 
00530     return p_vlc_menu;
00531 }
00532 
00533 /*****************************************************************************
00534  * Constructor.
00535  *****************************************************************************/
00536 Menu::Menu( intf_thread_t *_p_intf, int _i_start_id ) : wxMenu( )
00537 {
00538     /* Initializations */
00539     p_intf = _p_intf;
00540     i_start_id = _i_start_id;
00541 }
00542 
00543 Menu::~Menu()
00544 {
00545 }
00546 
00547 /*****************************************************************************
00548  * Public methods.
00549  *****************************************************************************/
00550 void Menu::Populate( int i_count, char **ppsz_varnames, int *pi_objects )
00551 {
00552     vlc_object_t *p_object;
00553     vlc_bool_t b_section_empty = VLC_FALSE;
00554     int i;
00555 
00556     i_item_id = i_start_id;
00557 
00558     for( i = 0; i < i_count; i++ )
00559     {
00560         if( !ppsz_varnames[i] )
00561         {
00562             if( b_section_empty )
00563             {
00564                 Append( MenuDummy_Event + i, wxU(_("Empty")) );
00565                 Enable( MenuDummy_Event + i, FALSE );
00566             }
00567 
00568             AppendSeparator();
00569             b_section_empty = VLC_TRUE;
00570             continue;
00571         }
00572 
00573         if( !pi_objects[i] )
00574         {
00575             Append( MenuDummy_Event, wxU(ppsz_varnames[i]) );
00576             b_section_empty = VLC_FALSE;
00577             continue;
00578         }
00579 
00580         p_object = (vlc_object_t *)vlc_object_get( p_intf, pi_objects[i] );
00581         if( p_object == NULL ) continue;
00582 
00583         b_section_empty = VLC_FALSE;
00584         CreateMenuItem( this, ppsz_varnames[i], p_object );
00585         vlc_object_release( p_object );
00586     }
00587 
00588     /* Special case for empty menus */
00589     if( GetMenuItemCount() == 0 || b_section_empty )
00590     {
00591         Append( MenuDummy_Event + i, wxU(_("Empty")) );
00592         Enable( MenuDummy_Event + i, FALSE );
00593     }
00594 }
00595 
00596 /* Work-around helper for buggy wxGTK */
00597 static void RecursiveDestroy( wxMenu *menu )
00598 {
00599     wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
00600     for( ; node; )
00601     {
00602         wxMenuItem *item = node->GetData();
00603         node = node->GetNext();
00604 
00605         /* Delete the submenus */
00606         wxMenu *submenu = item->GetSubMenu();
00607         if( submenu )
00608         {
00609             RecursiveDestroy( submenu );
00610         }
00611         menu->Delete( item );
00612     }
00613 }
00614 
00615 void Menu::Clear( )
00616 {
00617     RecursiveDestroy( this );
00618 }
00619 
00620 /*****************************************************************************
00621  * Private methods.
00622  *****************************************************************************/
00623 static bool IsMenuEmpty( char *psz_var, vlc_object_t *p_object,
00624                          bool b_root = TRUE )
00625 {
00626     vlc_value_t val, val_list;
00627     int i_type, i_result, i;
00628 
00629     /* Check the type of the object variable */
00630     i_type = var_Type( p_object, psz_var );
00631 
00632     /* Check if we want to display the variable */
00633     if( !(i_type & VLC_VAR_HASCHOICE) ) return FALSE;
00634 
00635     var_Change( p_object, psz_var, VLC_VAR_CHOICESCOUNT, &val, NULL );
00636     if( val.i_int == 0 ) return TRUE;
00637 
00638     if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE )
00639     {
00640         if( val.i_int == 1 && b_root ) return TRUE;
00641         else return FALSE;
00642     }
00643 
00644     /* Check children variables in case of VLC_VAR_VARIABLE */
00645     if( var_Change( p_object, psz_var, VLC_VAR_GETLIST, &val_list, NULL ) < 0 )
00646     {
00647         return TRUE;
00648     }
00649 
00650     for( i = 0, i_result = TRUE; i < val_list.p_list->i_count; i++ )
00651     {
00652         if( !IsMenuEmpty( val_list.p_list->p_values[i].psz_string,
00653                           p_object, FALSE ) )
00654         {
00655             i_result = FALSE;
00656             break;
00657         }
00658     }
00659 
00660     /* clean up everything */
00661     var_Change( p_object, psz_var, VLC_VAR_FREELIST, &val_list, NULL );
00662 
00663     return i_result;
00664 }
00665 
00666 void Menu::CreateMenuItem( wxMenu *menu, char *psz_var,
00667                            vlc_object_t *p_object )
00668 {
00669     wxMenuItemExt *menuitem;
00670     vlc_value_t val, text;
00671     int i_type;
00672 
00673     /* Check the type of the object variable */
00674     i_type = var_Type( p_object, psz_var );
00675 
00676     switch( i_type & VLC_VAR_TYPE )
00677     {
00678     case VLC_VAR_VOID:
00679     case VLC_VAR_BOOL:
00680     case VLC_VAR_VARIABLE:
00681     case VLC_VAR_STRING:
00682     case VLC_VAR_INTEGER:
00683     case VLC_VAR_FLOAT:
00684         break;
00685     default:
00686         /* Variable doesn't exist or isn't handled */
00687         return;
00688     }
00689 
00690     /* Make sure we want to display the variable */
00691     if( IsMenuEmpty( psz_var, p_object ) ) return;
00692 
00693     /* Get the descriptive name of the variable */
00694     var_Change( p_object, psz_var, VLC_VAR_GETTEXT, &text, NULL );
00695 
00696     if( i_type & VLC_VAR_HASCHOICE )
00697     {
00698         menu->Append( MenuDummy_Event,
00699                       wxU(text.psz_string ? text.psz_string : psz_var),
00700                       CreateChoicesMenu( psz_var, p_object, TRUE ),
00701                       wxT("")/* Nothing for now (maybe use a GETLONGTEXT) */ );
00702 
00703         if( text.psz_string ) free( text.psz_string );
00704         return;
00705     }
00706 
00707 
00708     switch( i_type & VLC_VAR_TYPE )
00709     {
00710     case VLC_VAR_VOID:
00711         var_Get( p_object, psz_var, &val );
00712         menuitem = new wxMenuItemExt( menu, ++i_item_id,
00713                                       wxU(text.psz_string ?
00714                                         text.psz_string : psz_var),
00715                                       wxT(""), wxITEM_NORMAL, strdup(psz_var),
00716                                       p_object->i_object_id, val, i_type );
00717         menu->Append( menuitem );
00718         break;
00719 
00720     case VLC_VAR_BOOL:
00721         var_Get( p_object, psz_var, &val );
00722         val.b_bool = !val.b_bool;
00723         menuitem = new wxMenuItemExt( menu, ++i_item_id,
00724                                       wxU(text.psz_string ?
00725                                         text.psz_string : psz_var),
00726                                       wxT(""), wxITEM_CHECK, strdup(psz_var),
00727                                       p_object->i_object_id, val, i_type );
00728         menu->Append( menuitem );
00729         Check( i_item_id, val.b_bool ? FALSE : TRUE );
00730         break;
00731     }
00732 
00733     if( text.psz_string ) free( text.psz_string );
00734 }
00735 
00736 wxMenu *Menu::CreateChoicesMenu( char *psz_var, vlc_object_t *p_object,
00737                                  bool b_root )
00738 {
00739     vlc_value_t val, val_list, text_list;
00740     int i_type, i;
00741 
00742     /* Check the type of the object variable */
00743     i_type = var_Type( p_object, psz_var );
00744 
00745     /* Make sure we want to display the variable */
00746     if( IsMenuEmpty( psz_var, p_object, b_root ) ) return NULL;
00747 
00748     switch( i_type & VLC_VAR_TYPE )
00749     {
00750     case VLC_VAR_VOID:
00751     case VLC_VAR_BOOL:
00752     case VLC_VAR_VARIABLE:
00753     case VLC_VAR_STRING:
00754     case VLC_VAR_INTEGER:
00755     case VLC_VAR_FLOAT:
00756         break;
00757     default:
00758         /* Variable doesn't exist or isn't handled */
00759         return NULL;
00760     }
00761 
00762     if( var_Change( p_object, psz_var, VLC_VAR_GETLIST,
00763                     &val_list, &text_list ) < 0 )
00764     {
00765         return NULL;
00766     }
00767 
00768     wxMenu *menu = new wxMenu;
00769     for( i = 0; i < val_list.p_list->i_count; i++ )
00770     {
00771         vlc_value_t another_val;
00772         wxMenuItemExt *menuitem;
00773 
00774         switch( i_type & VLC_VAR_TYPE )
00775         {
00776         case VLC_VAR_VARIABLE:
00777           menu->Append( MenuDummy_Event,
00778                         wxU(text_list.p_list->p_values[i].psz_string ?
00779                         text_list.p_list->p_values[i].psz_string :
00780                         val_list.p_list->p_values[i].psz_string),
00781                         CreateChoicesMenu(
00782                             val_list.p_list->p_values[i].psz_string,
00783                             p_object, FALSE ), wxT("") );
00784           break;
00785 
00786         case VLC_VAR_STRING:
00787           var_Get( p_object, psz_var, &val );
00788 
00789           another_val.psz_string =
00790               strdup(val_list.p_list->p_values[i].psz_string);
00791           menuitem =
00792               new wxMenuItemExt( menu, ++i_item_id,
00793                                  wxU(text_list.p_list->p_values[i].psz_string ?
00794                                  text_list.p_list->p_values[i].psz_string :
00795                                  another_val.psz_string), wxT(""),
00796                                  i_type & VLC_VAR_ISCOMMAND ?
00797                                    wxITEM_NORMAL : wxITEM_RADIO,
00798                                  strdup(psz_var),
00799                                  p_object->i_object_id, another_val, i_type );
00800 
00801           menu->Append( menuitem );
00802 
00803           if( !(i_type & VLC_VAR_ISCOMMAND) && val.psz_string &&
00804               !strcmp( val.psz_string,
00805                        val_list.p_list->p_values[i].psz_string ) )
00806               menu->Check( i_item_id, TRUE );
00807 
00808           if( val.psz_string ) free( val.psz_string );
00809           break;
00810 
00811         case VLC_VAR_INTEGER:
00812           var_Get( p_object, psz_var, &val );
00813 
00814           menuitem =
00815               new wxMenuItemExt( menu, ++i_item_id,
00816                                  text_list.p_list->p_values[i].psz_string ?
00817                                  (wxString)wxU(
00818                                    text_list.p_list->p_values[i].psz_string) :
00819                                  wxString::Format(wxT("%d"),
00820                                  val_list.p_list->p_values[i].i_int), wxT(""),
00821                                  i_type & VLC_VAR_ISCOMMAND ?
00822                                    wxITEM_NORMAL : wxITEM_RADIO,
00823                                  strdup(psz_var),
00824                                  p_object->i_object_id,
00825                                  val_list.p_list->p_values[i], i_type );
00826 
00827           menu->Append( menuitem );
00828 
00829           if( !(i_type & VLC_VAR_ISCOMMAND) &&
00830               val_list.p_list->p_values[i].i_int == val.i_int )
00831               menu->Check( i_item_id, TRUE );
00832           break;
00833 
00834         case VLC_VAR_FLOAT:
00835           var_Get( p_object, psz_var, &val );
00836 
00837           menuitem =
00838               new wxMenuItemExt( menu, ++i_item_id,
00839                                  text_list.p_list->p_values[i].psz_string ?
00840                                  (wxString)wxU(
00841                                    text_list.p_list->p_values[i].psz_string) :
00842                                  wxString::Format(wxT("%.2f"),
00843                                  val_list.p_list->p_values[i].f_float),wxT(""),
00844                                  i_type & VLC_VAR_ISCOMMAND ?
00845                                    wxITEM_NORMAL : wxITEM_RADIO,
00846                                  strdup(psz_var),
00847                                  p_object->i_object_id,
00848                                  val_list.p_list->p_values[i], i_type );
00849 
00850           menu->Append( menuitem );
00851 
00852           if( !(i_type & VLC_VAR_ISCOMMAND) &&
00853               val_list.p_list->p_values[i].f_float == val.f_float )
00854               menu->Check( i_item_id, TRUE );
00855           break;
00856 
00857         default:
00858           break;
00859         }
00860     }
00861 
00862     /* clean up everything */
00863     var_Change( p_object, psz_var, VLC_VAR_FREELIST, &val_list, &text_list );
00864 
00865     return menu;
00866 }
00867 
00868 /*****************************************************************************
00869  * A small helper class which intercepts all popup menu events
00870  *****************************************************************************/
00871 MenuEvtHandler::MenuEvtHandler( intf_thread_t *_p_intf,
00872                                 Interface *_p_main_interface )
00873 {
00874     /* Initializations */
00875     p_intf = _p_intf;
00876     p_main_interface = _p_main_interface;
00877 }
00878 
00879 MenuEvtHandler::~MenuEvtHandler()
00880 {
00881 }
00882 
00883 void MenuEvtHandler::OnShowDialog( wxCommandEvent& event )
00884 {
00885     if( p_intf->p_sys->pf_show_dialog )
00886     {
00887         int i_id;
00888 
00889         switch( event.GetId() )
00890         {
00891         case OpenFileSimple_Event:
00892             i_id = INTF_DIALOG_FILE_SIMPLE;
00893             break;
00894         case OpenFile_Event:
00895             i_id = INTF_DIALOG_FILE;
00896             break;
00897         case OpenDirectory_Event:
00898             i_id = INTF_DIALOG_DIRECTORY;
00899             break;
00900         case OpenDisc_Event:
00901             i_id = INTF_DIALOG_DISC;
00902             break;
00903         case OpenNet_Event:
00904             i_id = INTF_DIALOG_NET;
00905             break;
00906         case OpenCapture_Event:
00907             i_id = INTF_DIALOG_CAPTURE;
00908             break;
00909         case MediaInfo_Event:
00910             i_id = INTF_DIALOG_FILEINFO;
00911             break;
00912         case Messages_Event:
00913             i_id = INTF_DIALOG_MESSAGES;
00914             break;
00915         case Preferences_Event:
00916             i_id = INTF_DIALOG_PREFS;
00917             break;
00918         default:
00919             i_id = INTF_DIALOG_FILE;
00920             break;
00921 
00922         }
00923 
00924         p_intf->p_sys->pf_show_dialog( p_intf, i_id, 1, 0 );
00925     }
00926 }
00927 
00928 void MenuEvtHandler::OnMenuEvent( wxCommandEvent& event )
00929 {
00930     wxMenuItem *p_menuitem = NULL;
00931     int i_hotkey_event = p_intf->p_sys->i_first_hotkey_event;
00932     int i_hotkeys = p_intf->p_sys->i_hotkeys;
00933 
00934     if( event.GetId() >= Play_Event && event.GetId() <= Stop_Event )
00935     {
00936         input_thread_t *p_input;
00937         playlist_t * p_playlist =
00938             (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00939                                            FIND_ANYWHERE );
00940         if( !p_playlist ) return;
00941 
00942         switch( event.GetId() )
00943         {
00944         case Play_Event:
00945         case Pause_Event:
00946             p_input =
00947                 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
00948                                                    FIND_ANYWHERE );
00949             if( !p_input ) playlist_Play( p_playlist );
00950             else
00951             {
00952                 vlc_value_t val;
00953                 var_Get( p_input, "state", &val );
00954                 if( val.i_int != PAUSE_S ) val.i_int = PAUSE_S;
00955                 else val.i_int = PLAYING_S;
00956                 var_Set( p_input, "state", val );
00957                 vlc_object_release( p_input );
00958             }
00959             break;
00960         case Stop_Event:
00961             playlist_Stop( p_playlist );
00962             break;
00963         case Previous_Event:
00964             playlist_Prev( p_playlist );
00965             break;
00966         case Next_Event:
00967             playlist_Next( p_playlist );
00968             break;
00969         }
00970 
00971         vlc_object_release( p_playlist );
00972         return;
00973     }
00974 
00975     /* Check if this is an auto generated menu item */
00976     if( event.GetId() < FirstAutoGenerated_Event )
00977     {
00978         event.Skip();
00979         return;
00980     }
00981 
00982     /* Check if this is an hotkey event */
00983     if( event.GetId() >= i_hotkey_event &&
00984         event.GetId() < i_hotkey_event + i_hotkeys )
00985     {
00986         vlc_value_t val;
00987 
00988         val.i_int =
00989             p_intf->p_vlc->p_hotkeys[event.GetId() - i_hotkey_event].i_key;
00990 
00991         /* Get the key combination and send it to the hotkey handler */
00992         var_Set( p_intf->p_vlc, "key-pressed", val );
00993         return;
00994     }
00995 
00996     if( !p_main_interface ||
00997         (p_menuitem = p_main_interface->GetMenuBar()->FindItem(event.GetId()))
00998         == NULL )
00999     {
01000         if( p_intf->p_sys->p_popup_menu )
01001         {
01002             p_menuitem =
01003                 p_intf->p_sys->p_popup_menu->FindItem( event.GetId() );
01004         }
01005     }
01006 
01007     if( p_menuitem )
01008     {
01009         wxMenuItemExt *p_menuitemext = (wxMenuItemExt *)p_menuitem;
01010         vlc_object_t *p_object;
01011 
01012         p_object = (vlc_object_t *)vlc_object_get( p_intf,
01013                                        p_menuitemext->i_object_id );
01014         if( p_object == NULL ) return;
01015 
01016         wxMutexGuiLeave(); // We don't want deadlocks
01017         var_Set( p_object, p_menuitemext->psz_var, p_menuitemext->val );
01018         //wxMutexGuiEnter();
01019 
01020         vlc_object_release( p_object );
01021     }
01022     else
01023         event.Skip();
01024 }
01025 
01026 /*****************************************************************************
01027  * A small helper class which encapsulate wxMenuitem with some other useful
01028  * things.
01029  *****************************************************************************/
01030 wxMenuItemExt::wxMenuItemExt( wxMenu* parentMenu, int id, const wxString& text,
01031     const wxString& helpString, wxItemKind kind,
01032     char *_psz_var, int _i_object_id, vlc_value_t _val, int _i_val_type ):
01033     wxMenuItem( parentMenu, id, text, helpString, kind )
01034 {
01035     /* Initializations */
01036     psz_var = _psz_var;
01037     i_val_type = _i_val_type;
01038     i_object_id = _i_object_id;
01039     val = _val;
01040 };
01041 
01042 wxMenuItemExt::~wxMenuItemExt()
01043 {
01044     if( psz_var ) free( psz_var );
01045     if( ((i_val_type & VLC_VAR_TYPE) == VLC_VAR_STRING)
01046         && val.psz_string ) free( val.psz_string );
01047 };

Generated on Tue Dec 20 10:14:45 2005 for vlc-0.8.4a by  doxygen 1.4.2