menus.cpp
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:32k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * menus.cpp : wxWindows plugin for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2000-2004 VideoLAN
  5.  * $Id: menus.cpp 8715 2004-09-16 14:31:14Z gbazin $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@videolan.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <stdlib.h>                                      /* malloc(), free() */
  27. #include <errno.h>                                                 /* ENOMEM */
  28. #include <string.h>                                            /* strerror() */
  29. #include <stdio.h>
  30. #include <vlc/vlc.h>
  31. #include <vlc/intf.h>
  32. #include "wxwindows.h"
  33. class wxMenuItemExt: public wxMenuItem
  34. {
  35. public:
  36.     /* Constructor */
  37.     wxMenuItemExt( wxMenu* parentMenu, int id, const wxString& text,
  38.                    const wxString& helpString, wxItemKind kind,
  39.                    char *_psz_var, int _i_object_id, vlc_value_t _val,
  40.                    int _i_val_type );
  41.     virtual ~wxMenuItemExt();
  42.     char *psz_var;
  43.     int  i_val_type;
  44.     int  i_object_id;
  45.     vlc_value_t val;
  46. private:
  47. };
  48. class Menu: public wxMenu
  49. {
  50. public:
  51.     /* Constructor */
  52.     Menu( intf_thread_t *p_intf, int i_start_id );
  53.     virtual ~Menu();
  54.     void Populate( int i_count, char **ppsz_names, int *pi_objects );
  55.     void Clear();
  56. private:
  57.     wxMenu *Menu::CreateDummyMenu();
  58.     void   Menu::CreateMenuItem( wxMenu *, char *, vlc_object_t * );
  59.     wxMenu *Menu::CreateChoicesMenu( char *, vlc_object_t *, bool );
  60.     DECLARE_EVENT_TABLE();
  61.     intf_thread_t *p_intf;
  62.     int i_start_id;
  63.     int i_item_id;
  64. };
  65. /*****************************************************************************
  66.  * Event Table.
  67.  *****************************************************************************/
  68. /* IDs for the controls and the menu commands */
  69. enum
  70. {
  71.     /* menu items */
  72.     MenuDummy_Event = wxID_HIGHEST + 1000,
  73.     OpenFileSimple_Event = wxID_HIGHEST + 1100,
  74.     OpenFile_Event,
  75.     OpenDisc_Event,
  76.     OpenNet_Event,
  77.     OpenCapture_Event,
  78.     MediaInfo_Event,
  79.     Messages_Event,
  80.     Preferences_Event,
  81.     Play_Event,
  82.     Pause_Event,
  83.     Previous_Event,
  84.     Next_Event,
  85.     Stop_Event,
  86.     FirstAutoGenerated_Event = wxID_HIGHEST + 1999,
  87.     SettingsMenu_Events = wxID_HIGHEST + 5000,
  88.     AudioMenu_Events = wxID_HIGHEST + 2000,
  89.     VideoMenu_Events = wxID_HIGHEST + 3000,
  90.     NavigMenu_Events = wxID_HIGHEST + 4000,
  91.     PopupMenu_Events = wxID_HIGHEST + 6000,
  92.     Hotkeys_Events = wxID_HIGHEST + 7000
  93. };
  94. BEGIN_EVENT_TABLE(Menu, wxMenu)
  95. END_EVENT_TABLE()
  96. BEGIN_EVENT_TABLE(MenuEvtHandler, wxEvtHandler)
  97.     EVT_MENU(OpenFileSimple_Event, MenuEvtHandler::OnShowDialog)
  98.     EVT_MENU(OpenFile_Event, MenuEvtHandler::OnShowDialog)
  99.     EVT_MENU(OpenDisc_Event, MenuEvtHandler::OnShowDialog)
  100.     EVT_MENU(OpenNet_Event, MenuEvtHandler::OnShowDialog)
  101.     EVT_MENU(OpenCapture_Event, MenuEvtHandler::OnShowDialog)
  102.     EVT_MENU(MediaInfo_Event, MenuEvtHandler::OnShowDialog)
  103.     EVT_MENU(Messages_Event, MenuEvtHandler::OnShowDialog)
  104.     EVT_MENU(Preferences_Event, MenuEvtHandler::OnShowDialog)
  105.     EVT_MENU(-1, MenuEvtHandler::OnMenuEvent)
  106. END_EVENT_TABLE()
  107. wxMenu *OpenStreamMenu( intf_thread_t *p_intf )
  108. {
  109.     wxMenu *menu = new wxMenu;
  110.     menu->Append( OpenFileSimple_Event, wxU(_("Quick &Open File...")) );
  111.     menu->Append( OpenFile_Event, wxU(_("Open &File...")) );
  112.     menu->Append( OpenDisc_Event, wxU(_("Open &Disc...")) );
  113.     menu->Append( OpenNet_Event, wxU(_("Open &Network Stream...")) );
  114.     menu->Append( OpenCapture_Event, wxU(_("Open &Capture Device...")) );
  115.     return menu;
  116. }
  117. wxMenu *MiscMenu( intf_thread_t *p_intf )
  118. {
  119.     wxMenu *menu = new wxMenu;
  120.     menu->Append( MediaInfo_Event, wxU(_("Media &Info...")) );
  121.     menu->Append( Messages_Event, wxU(_("&Messages...")) );
  122.     menu->Append( Preferences_Event, wxU(_("&Preferences...")) );
  123.     return menu;
  124. }
  125. void PopupMenu( intf_thread_t *p_intf, wxWindow *p_parent,
  126.                 const wxPoint& pos )
  127. {
  128. #define MAX_POPUP_ITEMS 45
  129.     vlc_object_t *p_object, *p_input;
  130.     char *ppsz_varnames[MAX_POPUP_ITEMS];
  131.     int pi_objects[MAX_POPUP_ITEMS];
  132.     int i = 0, i_last_separator = 0;
  133.     /* Initializations */
  134.     memset( pi_objects, 0, MAX_POPUP_ITEMS * sizeof(int) );
  135.     /* Input menu */
  136.     p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
  137.                                                 FIND_ANYWHERE );
  138.     if( p_object != NULL )
  139.     {
  140.         ppsz_varnames[i] = "bookmark";
  141.         pi_objects[i++] = p_object->i_object_id;
  142.         ppsz_varnames[i] = "title";
  143.         pi_objects[i++] = p_object->i_object_id;
  144.         ppsz_varnames[i] = "chapter";
  145.         pi_objects[i++] = p_object->i_object_id;
  146.         ppsz_varnames[i] = "program";
  147.         pi_objects[i++] = p_object->i_object_id;
  148.         ppsz_varnames[i] = "navigation";
  149.         pi_objects[i++] = p_object->i_object_id;
  150.         ppsz_varnames[i] = "dvd_menus";
  151.         pi_objects[i++] = p_object->i_object_id;
  152.         ppsz_varnames[i] = "video-es";
  153.         pi_objects[i++] = p_object->i_object_id;
  154.         ppsz_varnames[i] = "audio-es";
  155.         pi_objects[i++] = p_object->i_object_id;
  156.         ppsz_varnames[i] = "spu-es";
  157.         pi_objects[i++] = p_object->i_object_id;
  158.     }
  159.     p_input = p_object;
  160.     if( !p_input ) goto interfacemenu;
  161.     /* Video menu */
  162.     if( i != i_last_separator ) ppsz_varnames[i++] = NULL; /* Separator */
  163.     i_last_separator = i;
  164.     p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
  165.                                                 FIND_ANYWHERE );
  166.     if( p_object != NULL )
  167.     {
  168.         vlc_object_t *p_dec_obj;
  169.         ppsz_varnames[i] = "fullscreen";
  170.         pi_objects[i++] = p_object->i_object_id;
  171.         ppsz_varnames[i] = "zoom";
  172.         pi_objects[i++] = p_object->i_object_id;
  173.         ppsz_varnames[i] = "deinterlace";
  174.         pi_objects[i++] = p_object->i_object_id;
  175.         ppsz_varnames[i] = "aspect-ratio";
  176.         pi_objects[i++] = p_object->i_object_id;
  177.         ppsz_varnames[i] = "crop";
  178.         pi_objects[i++] = p_object->i_object_id;
  179.         ppsz_varnames[i] = "video-on-top";
  180.         pi_objects[i++] = p_object->i_object_id;
  181.         ppsz_varnames[i] = "directx-wallpaper";
  182.         pi_objects[i++] = p_object->i_object_id;
  183.         p_dec_obj = (vlc_object_t *)vlc_object_find( p_object,
  184.                                                      VLC_OBJECT_DECODER,
  185.                                                      FIND_PARENT );
  186.         if( p_dec_obj != NULL )
  187.         {
  188.             ppsz_varnames[i] = "ffmpeg-pp-q";
  189.             pi_objects[i++] = p_dec_obj->i_object_id;
  190.             vlc_object_release( p_dec_obj );
  191.         }
  192.         vlc_object_release( p_object );
  193.     }
  194.     /* Audio menu */
  195.     if( i != i_last_separator ) ppsz_varnames[i++] = NULL; /* Separator */
  196.     i_last_separator  = i;
  197.     p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
  198.                                                 FIND_ANYWHERE );
  199.     if( p_object != NULL )
  200.     {
  201.         ppsz_varnames[i] = "audio-device";
  202.         pi_objects[i++] = p_object->i_object_id;
  203.         ppsz_varnames[i] = "audio-channels";
  204.         pi_objects[i++] = p_object->i_object_id;
  205.         ppsz_varnames[i] = "visual";
  206.         pi_objects[i++] = p_object->i_object_id;
  207.         ppsz_varnames[i] = "equalizer";
  208.         pi_objects[i++] = p_object->i_object_id;
  209.         vlc_object_release( p_object );
  210.     }
  211.  interfacemenu:
  212.     /* Interface menu */
  213.     if( i != i_last_separator ) ppsz_varnames[i++] = NULL; /* Separator */
  214.     i_last_separator = i;
  215.     /* vlc_object_find is needed because of the dialogs provider case */
  216.     p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_INTF,
  217.                                                 FIND_PARENT );
  218.     if( p_object != NULL )
  219.     {
  220.         ppsz_varnames[i] = "intf-switch";
  221.         pi_objects[i++] = p_object->i_object_id;
  222.         ppsz_varnames[i] = "intf-add";
  223.         pi_objects[i++] = p_object->i_object_id;
  224.         ppsz_varnames[i] = "intf-skins";
  225.         pi_objects[i++] = p_object->i_object_id;
  226.         vlc_object_release( p_object );
  227.     }
  228.     /* Build menu */
  229.     Menu popupmenu( p_intf, PopupMenu_Events );
  230.     popupmenu.Populate( i, ppsz_varnames, pi_objects );
  231.     /* Add static entries */
  232.     if( p_input != NULL )
  233.     {
  234.         vlc_value_t val;
  235.         popupmenu.InsertSeparator( 0 );
  236.         popupmenu.Insert( 0, Stop_Event, wxU(_("Stop")) );
  237.         popupmenu.Insert( 0, Previous_Event, wxU(_("Previous")) );
  238.         popupmenu.Insert( 0, Next_Event, wxU(_("Next")) );
  239.         var_Get( p_input, "state", &val );
  240.         if( val.i_int == PAUSE_S )
  241.             popupmenu.Insert( 0, Play_Event, wxU(_("Play")) );
  242.         else
  243.             popupmenu.Insert( 0, Pause_Event, wxU(_("Pause")) );
  244.         vlc_object_release( p_input );
  245.     }
  246.     else
  247.     {
  248.         playlist_t * p_playlist =
  249.             (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
  250.                                            FIND_ANYWHERE );
  251.         if( p_playlist && p_playlist->i_size )
  252.         {
  253.             popupmenu.InsertSeparator( 0 );
  254.             popupmenu.Insert( 0, Play_Event, wxU(_("Play")) );
  255.         }
  256.         if( p_playlist ) vlc_object_release( p_playlist );
  257.     }
  258.     popupmenu.Append( MenuDummy_Event, wxU(_("Miscellaneous")),
  259.                       MiscMenu( p_intf ), wxT("") );
  260.     popupmenu.Append( MenuDummy_Event, wxU(_("Open")),
  261.                       OpenStreamMenu( p_intf ), wxT("") );
  262.     p_intf->p_sys->p_popup_menu = &popupmenu;
  263.     p_parent->PopupMenu( &popupmenu, pos.x, pos.y );
  264.     p_intf->p_sys->p_popup_menu = NULL;
  265. }
  266. wxMenu *AudioMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
  267. {
  268. #define MAX_AUDIO_ITEMS 10
  269.     vlc_object_t *p_object;
  270.     char *ppsz_varnames[MAX_AUDIO_ITEMS];
  271.     int pi_objects[MAX_AUDIO_ITEMS];
  272.     int i = 0;
  273.     /* Initializations */
  274.     memset( pi_objects, 0, MAX_AUDIO_ITEMS * sizeof(int) );
  275.     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
  276.                                                 FIND_ANYWHERE );
  277.     if( p_object != NULL )
  278.     {
  279.         ppsz_varnames[i] = "audio-es";
  280.         pi_objects[i++] = p_object->i_object_id;
  281.         vlc_object_release( p_object );
  282.     }
  283.     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_AOUT,
  284.                                                 FIND_ANYWHERE );
  285.     if( p_object != NULL )
  286.     {
  287.         ppsz_varnames[i] = "audio-device";
  288.         pi_objects[i++] = p_object->i_object_id;
  289.         ppsz_varnames[i] = "audio-channels";
  290.         pi_objects[i++] = p_object->i_object_id;
  291.         ppsz_varnames[i] = "visual";
  292.         pi_objects[i++] = p_object->i_object_id;
  293.         ppsz_varnames[i] = "equalizer";
  294.         pi_objects[i++] = p_object->i_object_id;
  295.         vlc_object_release( p_object );
  296.     }
  297.     /* Build menu */
  298.     Menu *p_vlc_menu = (Menu *)p_menu;
  299.     if( !p_vlc_menu )
  300.         p_vlc_menu = new Menu( _p_intf, AudioMenu_Events );
  301.     else
  302.         p_vlc_menu->Clear();
  303.     p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
  304.     return p_vlc_menu;
  305. }
  306. wxMenu *VideoMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
  307. {
  308. #define MAX_VIDEO_ITEMS 15
  309.     vlc_object_t *p_object;
  310.     char *ppsz_varnames[MAX_VIDEO_ITEMS];
  311.     int pi_objects[MAX_VIDEO_ITEMS];
  312.     int i = 0;
  313.     /* Initializations */
  314.     memset( pi_objects, 0, MAX_VIDEO_ITEMS * sizeof(int) );
  315.     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
  316.                                                 FIND_ANYWHERE );
  317.     if( p_object != NULL )
  318.     {
  319.         ppsz_varnames[i] = "video-es";
  320.         pi_objects[i++] = p_object->i_object_id;
  321.         ppsz_varnames[i] = "spu-es";
  322.         pi_objects[i++] = p_object->i_object_id;
  323.         vlc_object_release( p_object );
  324.     }
  325.     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_VOUT,
  326.                                                 FIND_ANYWHERE );
  327.     if( p_object != NULL )
  328.     {
  329.         vlc_object_t *p_dec_obj;
  330.         ppsz_varnames[i] = "fullscreen";
  331.         pi_objects[i++] = p_object->i_object_id;
  332.         ppsz_varnames[i] = "zoom";
  333.         pi_objects[i++] = p_object->i_object_id;
  334.         ppsz_varnames[i] = "deinterlace";
  335.         pi_objects[i++] = p_object->i_object_id;
  336.         ppsz_varnames[i] = "aspect-ratio";
  337.         pi_objects[i++] = p_object->i_object_id;
  338.         ppsz_varnames[i] = "crop";
  339.         pi_objects[i++] = p_object->i_object_id;
  340.         ppsz_varnames[i] = "video-on-top";
  341.         pi_objects[i++] = p_object->i_object_id;
  342.         ppsz_varnames[i] = "directx-wallpaper";
  343.         pi_objects[i++] = p_object->i_object_id;
  344.         p_dec_obj = (vlc_object_t *)vlc_object_find( p_object,
  345.                                                      VLC_OBJECT_DECODER,
  346.                                                      FIND_PARENT );
  347.         if( p_dec_obj != NULL )
  348.         {
  349.             ppsz_varnames[i] = "ffmpeg-pp-q";
  350.             pi_objects[i++] = p_dec_obj->i_object_id;
  351.             vlc_object_release( p_dec_obj );
  352.         }
  353.         vlc_object_release( p_object );
  354.     }
  355.     /* Build menu */
  356.     Menu *p_vlc_menu = (Menu *)p_menu;
  357.     if( !p_vlc_menu )
  358.         p_vlc_menu = new Menu( _p_intf, VideoMenu_Events );
  359.     else
  360.         p_vlc_menu->Clear();
  361.     p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
  362.     return p_vlc_menu;
  363. }
  364. wxMenu *NavigMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
  365. {
  366. #define MAX_NAVIG_ITEMS 15
  367.     vlc_object_t *p_object;
  368.     char *ppsz_varnames[MAX_NAVIG_ITEMS];
  369.     int pi_objects[MAX_NAVIG_ITEMS];
  370.     int i = 0;
  371.     /* Initializations */
  372.     memset( pi_objects, 0, MAX_NAVIG_ITEMS * sizeof(int) );
  373.     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
  374.                                                 FIND_ANYWHERE );
  375.     if( p_object != NULL )
  376.     {
  377.         ppsz_varnames[i] = "bookmark";
  378.         pi_objects[i++] = p_object->i_object_id;
  379.         ppsz_varnames[i] = "title";
  380.         pi_objects[i++] = p_object->i_object_id;
  381.         ppsz_varnames[i] = "chapter";
  382.         pi_objects[i++] = p_object->i_object_id;
  383.         ppsz_varnames[i] = "program";
  384.         pi_objects[i++] = p_object->i_object_id;
  385.         ppsz_varnames[i] = "navigation";
  386.         pi_objects[i++] = p_object->i_object_id;
  387.         ppsz_varnames[i] = "dvd_menus";
  388.         pi_objects[i++] = p_object->i_object_id;
  389.         ppsz_varnames[i] = "prev-title";
  390.         pi_objects[i++] = p_object->i_object_id;
  391.         ppsz_varnames[i] = "next-title";
  392.         pi_objects[i++] = p_object->i_object_id;
  393.         ppsz_varnames[i] = "prev-chapter";
  394.         pi_objects[i++] = p_object->i_object_id;
  395.         ppsz_varnames[i] = "next-chapter";
  396.         pi_objects[i++] = p_object->i_object_id;
  397.         vlc_object_release( p_object );
  398.     }
  399.     /* Build menu */
  400.     Menu *p_vlc_menu = (Menu *)p_menu;
  401.     if( !p_vlc_menu )
  402.         p_vlc_menu = new Menu( _p_intf, NavigMenu_Events );
  403.     else
  404.         p_vlc_menu->Clear();
  405.     p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
  406.     return p_vlc_menu;
  407. }
  408. wxMenu *SettingsMenu( intf_thread_t *_p_intf, wxWindow *p_parent,
  409.                       wxMenu *p_menu )
  410. {
  411. #define MAX_SETTINGS_ITEMS 10
  412.     vlc_object_t *p_object;
  413.     char *ppsz_varnames[MAX_SETTINGS_ITEMS];
  414.     int pi_objects[MAX_SETTINGS_ITEMS];
  415.     int i = 0;
  416.     /* Initializations */
  417.     memset( pi_objects, 0, MAX_SETTINGS_ITEMS * sizeof(int) );
  418.     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INTF,
  419.                                                 FIND_PARENT );
  420.     if( p_object != NULL )
  421.     {
  422.         ppsz_varnames[i] = "intf-switch";
  423.         pi_objects[i++] = p_object->i_object_id;
  424.         ppsz_varnames[i] = "intf-add";
  425.         pi_objects[i++] = p_object->i_object_id;
  426.         vlc_object_release( p_object );
  427.     }
  428.     /* Build menu */
  429.     Menu *p_vlc_menu = (Menu *)p_menu;
  430.     if( !p_vlc_menu )
  431.         p_vlc_menu = new Menu( _p_intf, SettingsMenu_Events );
  432.     else
  433.         p_vlc_menu->Clear();
  434.     p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
  435.     return p_vlc_menu;
  436. }
  437. /*****************************************************************************
  438.  * Constructor.
  439.  *****************************************************************************/
  440. Menu::Menu( intf_thread_t *_p_intf, int _i_start_id ) : wxMenu( )
  441. {
  442.     /* Initializations */
  443.     p_intf = _p_intf;
  444.     i_start_id = _i_start_id;
  445. }
  446. Menu::~Menu()
  447. {
  448. }
  449. /*****************************************************************************
  450.  * Public methods.
  451.  *****************************************************************************/
  452. void Menu::Populate( int i_count, char **ppsz_varnames, int *pi_objects )
  453. {
  454.     vlc_object_t *p_object;
  455.     vlc_bool_t b_section_empty = VLC_FALSE;
  456.     int i;
  457.     i_item_id = i_start_id;
  458.     for( i = 0; i < i_count; i++ )
  459.     {
  460.         if( !ppsz_varnames[i] )
  461.         {
  462.             if( b_section_empty )
  463.             {
  464.                 Append( MenuDummy_Event + i, wxU(_("Empty")) );
  465.                 Enable( MenuDummy_Event + i, FALSE );
  466.             }
  467.             AppendSeparator();
  468.             b_section_empty = VLC_TRUE;
  469.             continue;
  470.         }
  471.         if( !pi_objects[i] )
  472.         {
  473.             Append( MenuDummy_Event, wxU(ppsz_varnames[i]) );
  474.             b_section_empty = VLC_FALSE;
  475.             continue;
  476.         }
  477.         p_object = (vlc_object_t *)vlc_object_get( p_intf, pi_objects[i] );
  478.         if( p_object == NULL ) continue;
  479.         b_section_empty = VLC_FALSE;
  480.         CreateMenuItem( this, ppsz_varnames[i], p_object );
  481.         vlc_object_release( p_object );
  482.     }
  483.     /* Special case for empty menus */
  484.     if( GetMenuItemCount() == 0 || b_section_empty )
  485.     {
  486.         Append( MenuDummy_Event + i, wxU(_("Empty")) );
  487.         Enable( MenuDummy_Event + i, FALSE );
  488.     }
  489. }
  490. /* Work-around helper for buggy wxGTK */
  491. static void RecursiveDestroy( wxMenu *menu )
  492. {
  493.     wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
  494.     for( ; node; )
  495.     {
  496.         wxMenuItem *item = node->GetData();
  497.         node = node->GetNext();
  498.         /* Delete the submenus */
  499.         wxMenu *submenu = item->GetSubMenu();
  500.         if( submenu )
  501.         {
  502.             RecursiveDestroy( submenu );
  503.         }
  504.         menu->Delete( item );
  505.     }
  506. }
  507. void Menu::Clear( )
  508. {
  509.     RecursiveDestroy( this );
  510. }
  511. /*****************************************************************************
  512.  * Private methods.
  513.  *****************************************************************************/
  514. static bool IsMenuEmpty( char *psz_var, vlc_object_t *p_object,
  515.                          bool b_root = TRUE )
  516. {
  517.     vlc_value_t val, val_list;
  518.     int i_type, i_result, i;
  519.     /* Check the type of the object variable */
  520.     i_type = var_Type( p_object, psz_var );
  521.     /* Check if we want to display the variable */
  522.     if( !(i_type & VLC_VAR_HASCHOICE) ) return FALSE;
  523.     var_Change( p_object, psz_var, VLC_VAR_CHOICESCOUNT, &val, NULL );
  524.     if( val.i_int == 0 ) return TRUE;
  525.     if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE )
  526.     {
  527.         if( val.i_int == 1 && b_root ) return TRUE;
  528.         else return FALSE;
  529.     }
  530.     /* Check children variables in case of VLC_VAR_VARIABLE */
  531.     if( var_Change( p_object, psz_var, VLC_VAR_GETLIST, &val_list, NULL ) < 0 )
  532.     {
  533.         return TRUE;
  534.     }
  535.     for( i = 0, i_result = TRUE; i < val_list.p_list->i_count; i++ )
  536.     {
  537.         if( !IsMenuEmpty( val_list.p_list->p_values[i].psz_string,
  538.                           p_object, FALSE ) )
  539.         {
  540.             i_result = FALSE;
  541.             break;
  542.         }
  543.     }
  544.     /* clean up everything */
  545.     var_Change( p_object, psz_var, VLC_VAR_FREELIST, &val_list, NULL );
  546.     return i_result;
  547. }
  548. void Menu::CreateMenuItem( wxMenu *menu, char *psz_var,
  549.                            vlc_object_t *p_object )
  550. {
  551.     wxMenuItemExt *menuitem;
  552.     vlc_value_t val, text;
  553.     int i_type;
  554.     /* Check the type of the object variable */
  555.     i_type = var_Type( p_object, psz_var );
  556.     switch( i_type & VLC_VAR_TYPE )
  557.     {
  558.     case VLC_VAR_VOID:
  559.     case VLC_VAR_BOOL:
  560.     case VLC_VAR_VARIABLE:
  561.     case VLC_VAR_STRING:
  562.     case VLC_VAR_INTEGER:
  563.     case VLC_VAR_FLOAT:
  564.         break;
  565.     default:
  566.         /* Variable doesn't exist or isn't handled */
  567.         return;
  568.     }
  569.     /* Make sure we want to display the variable */
  570.     if( IsMenuEmpty( psz_var, p_object ) ) return;
  571.     /* Get the descriptive name of the variable */
  572.     var_Change( p_object, psz_var, VLC_VAR_GETTEXT, &text, NULL );
  573.     if( i_type & VLC_VAR_HASCHOICE )
  574.     {
  575.         menu->Append( MenuDummy_Event,
  576.                       wxU(text.psz_string ? text.psz_string : psz_var),
  577.                       CreateChoicesMenu( psz_var, p_object, TRUE ),
  578.                       wxT("")/* Nothing for now (maybe use a GETLONGTEXT) */ );
  579.         if( text.psz_string ) free( text.psz_string );
  580.         return;
  581.     }
  582.     switch( i_type & VLC_VAR_TYPE )
  583.     {
  584.     case VLC_VAR_VOID:
  585.         var_Get( p_object, psz_var, &val );
  586.         menuitem = new wxMenuItemExt( menu, ++i_item_id,
  587.                                       wxU(text.psz_string ?
  588.                                         text.psz_string : psz_var),
  589.                                       wxT(""), wxITEM_NORMAL, strdup(psz_var),
  590.                                       p_object->i_object_id, val, i_type );
  591.         menu->Append( menuitem );
  592.         break;
  593.     case VLC_VAR_BOOL:
  594.         var_Get( p_object, psz_var, &val );
  595.         val.b_bool = !val.b_bool;
  596.         menuitem = new wxMenuItemExt( menu, ++i_item_id,
  597.                                       wxU(text.psz_string ?
  598.                                         text.psz_string : psz_var),
  599.                                       wxT(""), wxITEM_CHECK, strdup(psz_var),
  600.                                       p_object->i_object_id, val, i_type );
  601.         menu->Append( menuitem );
  602.         Check( i_item_id, val.b_bool ? FALSE : TRUE );
  603.         break;
  604.     }
  605.     if( text.psz_string ) free( text.psz_string );
  606. }
  607. wxMenu *Menu::CreateChoicesMenu( char *psz_var, vlc_object_t *p_object,
  608.                                  bool b_root )
  609. {
  610.     vlc_value_t val, val_list, text_list;
  611.     int i_type, i;
  612.     /* Check the type of the object variable */
  613.     i_type = var_Type( p_object, psz_var );
  614.     /* Make sure we want to display the variable */
  615.     if( IsMenuEmpty( psz_var, p_object, b_root ) ) return NULL;
  616.     switch( i_type & VLC_VAR_TYPE )
  617.     {
  618.     case VLC_VAR_VOID:
  619.     case VLC_VAR_BOOL:
  620.     case VLC_VAR_VARIABLE:
  621.     case VLC_VAR_STRING:
  622.     case VLC_VAR_INTEGER:
  623.     case VLC_VAR_FLOAT:
  624.         break;
  625.     default:
  626.         /* Variable doesn't exist or isn't handled */
  627.         return NULL;
  628.     }
  629.     if( var_Change( p_object, psz_var, VLC_VAR_GETLIST,
  630.                     &val_list, &text_list ) < 0 )
  631.     {
  632.         return NULL;
  633.     }
  634.     wxMenu *menu = new wxMenu;
  635.     for( i = 0; i < val_list.p_list->i_count; i++ )
  636.     {
  637.         vlc_value_t another_val;
  638.         wxMenuItemExt *menuitem;
  639.         switch( i_type & VLC_VAR_TYPE )
  640.         {
  641.         case VLC_VAR_VARIABLE:
  642.           menu->Append( MenuDummy_Event,
  643.                         wxU(text_list.p_list->p_values[i].psz_string ?
  644.                         text_list.p_list->p_values[i].psz_string :
  645.                         val_list.p_list->p_values[i].psz_string),
  646.                         CreateChoicesMenu(
  647.                             val_list.p_list->p_values[i].psz_string,
  648.                             p_object, FALSE ), wxT("") );
  649.           break;
  650.         case VLC_VAR_STRING:
  651.           var_Get( p_object, psz_var, &val );
  652.           another_val.psz_string =
  653.               strdup(val_list.p_list->p_values[i].psz_string);
  654.           menuitem =
  655.               new wxMenuItemExt( menu, ++i_item_id,
  656.                                  wxU(text_list.p_list->p_values[i].psz_string ?
  657.                                  text_list.p_list->p_values[i].psz_string :
  658.                                  another_val.psz_string), wxT(""),
  659.                                  i_type & VLC_VAR_ISCOMMAND ?
  660.                                    wxITEM_NORMAL : wxITEM_RADIO,
  661.                                  strdup(psz_var),
  662.                                  p_object->i_object_id, another_val, i_type );
  663.           menu->Append( menuitem );
  664.           if( !(i_type & VLC_VAR_ISCOMMAND) && val.psz_string &&
  665.               !strcmp( val.psz_string,
  666.                        val_list.p_list->p_values[i].psz_string ) )
  667.               menu->Check( i_item_id, TRUE );
  668.           if( val.psz_string ) free( val.psz_string );
  669.           break;
  670.         case VLC_VAR_INTEGER:
  671.           var_Get( p_object, psz_var, &val );
  672.           menuitem =
  673.               new wxMenuItemExt( menu, ++i_item_id,
  674.                                  text_list.p_list->p_values[i].psz_string ?
  675.                                  (wxString)wxU(
  676.                                    text_list.p_list->p_values[i].psz_string) :
  677.                                  wxString::Format(wxT("%d"),
  678.                                  val_list.p_list->p_values[i].i_int), wxT(""),
  679.                                  i_type & VLC_VAR_ISCOMMAND ?
  680.                                    wxITEM_NORMAL : wxITEM_RADIO,
  681.                                  strdup(psz_var),
  682.                                  p_object->i_object_id,
  683.                                  val_list.p_list->p_values[i], i_type );
  684.           menu->Append( menuitem );
  685.           if( !(i_type & VLC_VAR_ISCOMMAND) &&
  686.               val_list.p_list->p_values[i].i_int == val.i_int )
  687.               menu->Check( i_item_id, TRUE );
  688.           break;
  689.         case VLC_VAR_FLOAT:
  690.           var_Get( p_object, psz_var, &val );
  691.           menuitem =
  692.               new wxMenuItemExt( menu, ++i_item_id,
  693.                                  text_list.p_list->p_values[i].psz_string ?
  694.                                  (wxString)wxU(
  695.                                    text_list.p_list->p_values[i].psz_string) :
  696.                                  wxString::Format(wxT("%.2f"),
  697.                                  val_list.p_list->p_values[i].f_float),wxT(""),
  698.                                  i_type & VLC_VAR_ISCOMMAND ?
  699.                                    wxITEM_NORMAL : wxITEM_RADIO,
  700.                                  strdup(psz_var),
  701.                                  p_object->i_object_id,
  702.                                  val_list.p_list->p_values[i], i_type );
  703.           menu->Append( menuitem );
  704.           if( !(i_type & VLC_VAR_ISCOMMAND) &&
  705.               val_list.p_list->p_values[i].f_float == val.f_float )
  706.               menu->Check( i_item_id, TRUE );
  707.           break;
  708.         default:
  709.           break;
  710.         }
  711.     }
  712.     /* clean up everything */
  713.     var_Change( p_object, psz_var, VLC_VAR_FREELIST, &val_list, &text_list );
  714.     return menu;
  715. }
  716. /*****************************************************************************
  717.  * A small helper class which intercepts all popup menu events
  718.  *****************************************************************************/
  719. MenuEvtHandler::MenuEvtHandler( intf_thread_t *_p_intf,
  720.                                 Interface *_p_main_interface )
  721. {
  722.     /* Initializations */
  723.     p_intf = _p_intf;
  724.     p_main_interface = _p_main_interface;
  725. }
  726. MenuEvtHandler::~MenuEvtHandler()
  727. {
  728. }
  729. void MenuEvtHandler::OnShowDialog( wxCommandEvent& event )
  730. {
  731.     if( p_intf->p_sys->pf_show_dialog )
  732.     {
  733.         int i_id;
  734.         switch( event.GetId() )
  735.         {
  736.         case OpenFileSimple_Event:
  737.             i_id = INTF_DIALOG_FILE_SIMPLE;
  738.             break;
  739.         case OpenFile_Event:
  740.             i_id = INTF_DIALOG_FILE;
  741.             break;
  742.         case OpenDisc_Event:
  743.             i_id = INTF_DIALOG_DISC;
  744.             break;
  745.         case OpenNet_Event:
  746.             i_id = INTF_DIALOG_NET;
  747.             break;
  748.         case OpenCapture_Event:
  749.             i_id = INTF_DIALOG_CAPTURE;
  750.             break;
  751.         case MediaInfo_Event:
  752.             i_id = INTF_DIALOG_FILEINFO;
  753.             break;
  754.         case Messages_Event:
  755.             i_id = INTF_DIALOG_MESSAGES;
  756.             break;
  757.         case Preferences_Event:
  758.             i_id = INTF_DIALOG_PREFS;
  759.             break;
  760.         default:
  761.             i_id = INTF_DIALOG_FILE;
  762.             break;
  763.         }
  764.         p_intf->p_sys->pf_show_dialog( p_intf, i_id, 1, 0 );
  765.     }
  766. }
  767. void MenuEvtHandler::OnMenuEvent( wxCommandEvent& event )
  768. {
  769.     wxMenuItem *p_menuitem = NULL;
  770.     int i_hotkey_event = p_intf->p_sys->i_first_hotkey_event;
  771.     int i_hotkeys = p_intf->p_sys->i_hotkeys;
  772.     if( event.GetId() >= Play_Event && event.GetId() <= Stop_Event )
  773.     {
  774.         input_thread_t *p_input;
  775.         playlist_t * p_playlist =
  776.             (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
  777.                                            FIND_ANYWHERE );
  778.         if( !p_playlist ) return;
  779.         switch( event.GetId() )
  780.         {
  781.         case Play_Event:
  782.         case Pause_Event:
  783.             p_input =
  784.                 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
  785.                                                    FIND_ANYWHERE );
  786.             if( !p_input ) playlist_Play( p_playlist );
  787.             else
  788.             {
  789.                 vlc_value_t val;
  790.                 var_Get( p_input, "state", &val );
  791.                 if( val.i_int != PAUSE_S ) val.i_int = PAUSE_S;
  792.                 else val.i_int = PLAYING_S;
  793.                 var_Set( p_input, "state", val );
  794.                 vlc_object_release( p_input );
  795.             }
  796.             break;
  797.         case Stop_Event:
  798.             playlist_Stop( p_playlist );
  799.             break;
  800.         case Previous_Event:
  801.             playlist_Prev( p_playlist );
  802.             break;
  803.         case Next_Event:
  804.             playlist_Next( p_playlist );
  805.             break;
  806.         }
  807.         vlc_object_release( p_playlist );
  808.         return;
  809.     }
  810.     /* Check if this is an auto generated menu item */
  811.     if( event.GetId() < FirstAutoGenerated_Event )
  812.     {
  813.         event.Skip();
  814.         return;
  815.     }
  816.     /* Check if this is an hotkey event */
  817.     if( event.GetId() >= i_hotkey_event &&
  818.         event.GetId() < i_hotkey_event + i_hotkeys )
  819.     {
  820.         vlc_value_t val;
  821.         val.i_int =
  822.             p_intf->p_vlc->p_hotkeys[event.GetId() - i_hotkey_event].i_key;
  823.         /* Get the key combination and send it to the hotkey handler */
  824.         var_Set( p_intf->p_vlc, "key-pressed", val );
  825.         return;
  826.     }
  827.     if( !p_main_interface ||
  828.         (p_menuitem = p_main_interface->GetMenuBar()->FindItem(event.GetId()))
  829.         == NULL )
  830.     {
  831.         if( p_intf->p_sys->p_popup_menu )
  832.         {
  833.             p_menuitem = 
  834.                 p_intf->p_sys->p_popup_menu->FindItem( event.GetId() );
  835.         }
  836.     }
  837.     if( p_menuitem )
  838.     {
  839.         wxMenuItemExt *p_menuitemext = (wxMenuItemExt *)p_menuitem;
  840.         vlc_object_t *p_object;
  841.         p_object = (vlc_object_t *)vlc_object_get( p_intf,
  842.                                        p_menuitemext->i_object_id );
  843.         if( p_object == NULL ) return;
  844.         wxMutexGuiLeave(); // We don't want deadlocks
  845.         var_Set( p_object, p_menuitemext->psz_var, p_menuitemext->val );
  846.         wxMutexGuiEnter();
  847.         vlc_object_release( p_object );
  848.     }
  849.     else
  850.         event.Skip();
  851. }
  852. /*****************************************************************************
  853.  * A small helper class which encapsulate wxMenuitem with some other useful
  854.  * things.
  855.  *****************************************************************************/
  856. wxMenuItemExt::wxMenuItemExt( wxMenu* parentMenu, int id, const wxString& text,
  857.     const wxString& helpString, wxItemKind kind,
  858.     char *_psz_var, int _i_object_id, vlc_value_t _val, int _i_val_type ):
  859.     wxMenuItem( parentMenu, id, text, helpString, kind )
  860. {
  861.     /* Initializations */
  862.     psz_var = _psz_var;
  863.     i_val_type = _i_val_type;
  864.     i_object_id = _i_object_id;
  865.     val = _val;
  866. };
  867. wxMenuItemExt::~wxMenuItemExt()
  868. {
  869.     if( psz_var ) free( psz_var );
  870.     if( ((i_val_type & VLC_VAR_TYPE) == VLC_VAR_STRING)
  871.         && val.psz_string ) free( val.psz_string );
  872. };