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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * preferences.cpp : wxWindows plugin for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2000-2004 VideoLAN
  5.  * $Id: preferences.cpp 8869 2004-09-30 22:17:54Z gbazin $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  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 <vlc_help.h>
  33. #include "wxwindows.h"
  34. #include "preferences_widgets.h"
  35. #include <wx/combobox.h>
  36. #include <wx/statline.h>
  37. #include <wx/clntdata.h>
  38. #include <wx/dynarray.h>
  39. #ifndef wxRB_SINGLE
  40. #   define wxRB_SINGLE 0
  41. #endif
  42. #define GENERAL_ID 1242
  43. #define PLUGIN_ID 1243
  44. #define CAPABILITY_ID 1244
  45. /*****************************************************************************
  46.  * Classes declarations.
  47.  *****************************************************************************/
  48. class ConfigTreeData;
  49. class PrefsTreeCtrl : public wxTreeCtrl
  50. {
  51. public:
  52.     PrefsTreeCtrl() { }
  53.     PrefsTreeCtrl( wxWindow *parent, intf_thread_t *_p_intf,
  54.                    PrefsDialog *p_prefs_dialog, wxBoxSizer *_p_sizer );
  55.     virtual ~PrefsTreeCtrl();
  56.     void ApplyChanges();
  57.     void CleanChanges();
  58. private:
  59.     /* Event handlers (these functions should _not_ be virtual) */
  60.     void OnSelectTreeItem( wxTreeEvent& event );
  61.     void OnAdvanced( wxCommandEvent& event );
  62.     ConfigTreeData *FindModuleConfig( ConfigTreeData *config_data );
  63.     DECLARE_EVENT_TABLE()
  64.     intf_thread_t *p_intf;
  65.     PrefsDialog *p_prefs_dialog;
  66.     wxBoxSizer *p_sizer;
  67.     wxWindow *p_parent;
  68.     vlc_bool_t b_advanced;
  69.     wxTreeItemId root_item;
  70.     wxTreeItemId general_item;
  71.     wxTreeItemId plugins_item;
  72. };
  73. WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
  74. class PrefsPanel : public wxPanel
  75. {
  76. public:
  77.     PrefsPanel() { }
  78.     PrefsPanel( wxWindow *parent, intf_thread_t *_p_intf,
  79.                 PrefsDialog *, int i_object_id, char *, char * );
  80.     virtual ~PrefsPanel() {}
  81.     void ApplyChanges();
  82.     void SwitchAdvanced( vlc_bool_t );
  83. private:
  84.     intf_thread_t *p_intf;
  85.     PrefsDialog *p_prefs_dialog;
  86.     vlc_bool_t b_advanced;
  87.     wxBoxSizer *config_sizer;
  88.     wxScrolledWindow *config_window;
  89.     ArrayOfConfigControls config_array;
  90. };
  91. class ConfigTreeData : public wxTreeItemData
  92. {
  93. public:
  94.     ConfigTreeData() { b_submodule = 0; panel = NULL; psz_section = NULL;
  95.                        psz_help = NULL; }
  96.     virtual ~ConfigTreeData() { if( panel ) delete panel;
  97.                                 if( psz_section) free(psz_section);
  98.                                 if( psz_help) free(psz_help); }
  99.     vlc_bool_t b_submodule;
  100.     PrefsPanel *panel;
  101.     wxBoxSizer *sizer;
  102.     int i_object_id;
  103.     char *psz_section;
  104.     char *psz_help;
  105. };
  106. /*****************************************************************************
  107.  * Event Table.
  108.  *****************************************************************************/
  109. /* IDs for the controls and the menu commands */
  110. enum
  111. {
  112.     Notebook_Event = wxID_HIGHEST,
  113.     MRL_Event,
  114.     ResetAll_Event,
  115.     Advanced_Event,
  116. };
  117. BEGIN_EVENT_TABLE(PrefsDialog, wxFrame)
  118.     /* Button events */
  119.     EVT_BUTTON(wxID_OK, PrefsDialog::OnOk)
  120.     EVT_BUTTON(wxID_CANCEL, PrefsDialog::OnCancel)
  121.     EVT_BUTTON(wxID_SAVE, PrefsDialog::OnSave)
  122.     EVT_BUTTON(ResetAll_Event, PrefsDialog::OnResetAll)
  123.     EVT_CHECKBOX(Advanced_Event, PrefsDialog::OnAdvanced)
  124.     /* Don't destroy the window when the user closes it */
  125.     EVT_CLOSE(PrefsDialog::OnCancel)
  126. END_EVENT_TABLE()
  127. // menu and control ids
  128. enum
  129. {
  130.     PrefsTree_Ctrl = wxID_HIGHEST
  131. };
  132. BEGIN_EVENT_TABLE(PrefsTreeCtrl, wxTreeCtrl)
  133.     EVT_TREE_SEL_CHANGED(PrefsTree_Ctrl, PrefsTreeCtrl::OnSelectTreeItem)
  134.     EVT_COMMAND(Advanced_Event, wxEVT_USER_FIRST, PrefsTreeCtrl::OnAdvanced)
  135. END_EVENT_TABLE()
  136. /*****************************************************************************
  137.  * Constructor.
  138.  *****************************************************************************/
  139. PrefsDialog::PrefsDialog( intf_thread_t *_p_intf, wxWindow *p_parent)
  140.   :  wxFrame( p_parent, -1, wxU(_("Preferences")), wxDefaultPosition,
  141.               wxSize(700,450), wxDEFAULT_FRAME_STYLE )
  142. {
  143.     /* Initializations */
  144.     p_intf = _p_intf;
  145.     SetIcon( *p_intf->p_sys->p_icon );
  146.     /* Create a panel to put everything in */
  147.     wxPanel *panel = new wxPanel( this, -1 );
  148.     panel->SetAutoLayout( TRUE );
  149.     /* Create the preferences tree control */
  150.     wxBoxSizer *controls_sizer = new wxBoxSizer( wxHORIZONTAL );
  151.     prefs_tree =
  152.         new PrefsTreeCtrl( panel, p_intf, this, controls_sizer );
  153.     /* Separation */
  154.     wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
  155.     /* Create the buttons */
  156.     wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("OK")) );
  157.     ok_button->SetDefault();
  158.     wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
  159.                                             wxU(_("Cancel")) );
  160.     wxButton *save_button = new wxButton( panel, wxID_SAVE, wxU(_("Save")) );
  161.     wxButton *reset_button = new wxButton( panel, ResetAll_Event,
  162.                                            wxU(_("Reset All")) );
  163.     wxPanel *dummy_panel = new wxPanel( this, -1 );
  164.     wxCheckBox *advanced_checkbox =
  165.         new wxCheckBox( panel, Advanced_Event, wxU(_("Advanced options")) );
  166.     if( config_GetInt( p_intf, "advanced" ) )
  167.     {
  168.         advanced_checkbox->SetValue(TRUE);
  169.         wxCommandEvent dummy_event;
  170.         dummy_event.SetInt(TRUE);
  171.         OnAdvanced( dummy_event );
  172.     }
  173.     /* Place everything in sizers */
  174.     wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
  175.     button_sizer->Add( ok_button, 0, wxALL, 5 );
  176.     button_sizer->Add( cancel_button, 0, wxALL, 5 );
  177.     button_sizer->Add( save_button, 0, wxALL, 5 );
  178.     button_sizer->Add( reset_button, 0, wxALL, 5 );
  179.     button_sizer->Add( dummy_panel, 1, wxALL, 5 );
  180.     button_sizer->Add( advanced_checkbox, 0, wxALL | wxALIGN_RIGHT |
  181.                        wxALIGN_CENTER_VERTICAL, 0 );
  182.     button_sizer->Layout();
  183.     wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
  184.     wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
  185.     panel_sizer->Add( controls_sizer, 1, wxEXPAND | wxALL, 5 );
  186.     panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
  187.     panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALIGN_BOTTOM |
  188.                       wxALL | wxEXPAND, 5 );
  189.     panel_sizer->Layout();
  190.     panel->SetSizer( panel_sizer );
  191.     main_sizer->Add( panel, 1, wxEXPAND, 0 );
  192.     main_sizer->Layout();
  193.     SetSizer( main_sizer );
  194. }
  195. PrefsDialog::~PrefsDialog()
  196. {
  197. }
  198. /*****************************************************************************
  199.  * Private methods.
  200.  *****************************************************************************/
  201. /*****************************************************************************
  202.  * Events methods.
  203.  *****************************************************************************/
  204. void PrefsDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
  205. {
  206.     prefs_tree->ApplyChanges();
  207.     this->Hide();
  208.     prefs_tree->CleanChanges();
  209. }
  210. void PrefsDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
  211. {
  212.     this->Hide();
  213.     prefs_tree->CleanChanges();
  214. }
  215. void PrefsDialog::OnSave( wxCommandEvent& WXUNUSED(event) )
  216. {
  217.     prefs_tree->ApplyChanges();
  218.     config_SaveConfigFile( p_intf, NULL );
  219.     this->Hide();
  220. }
  221. void PrefsDialog::OnResetAll( wxCommandEvent& WXUNUSED(event) )
  222. {
  223.     wxMessageDialog dlg( this,
  224.         wxU(_("Beware this will reset your VLC media player preferences.n"
  225.               "Are you sure you want to continue?")),
  226.         wxU(_("Reset Preferences")), wxYES_NO|wxNO_DEFAULT|wxCENTRE );
  227.     if ( dlg.ShowModal() == wxID_YES )
  228.     {
  229.         /* TODO: need to reset all the controls */
  230.         config_ResetAll( p_intf );
  231.         prefs_tree->CleanChanges();
  232.         config_SaveConfigFile( p_intf, NULL );
  233.     }
  234. }
  235. void PrefsDialog::OnAdvanced( wxCommandEvent& event )
  236. {
  237.     wxCommandEvent newevent( wxEVT_USER_FIRST, Advanced_Event );
  238.     newevent.SetInt( event.GetInt() );
  239.     prefs_tree->AddPendingEvent( newevent );
  240. }
  241. /*****************************************************************************
  242.  * PrefsTreeCtrl class definition.
  243.  *****************************************************************************/
  244. PrefsTreeCtrl::PrefsTreeCtrl( wxWindow *_p_parent, intf_thread_t *_p_intf,
  245.                               PrefsDialog *_p_prefs_dialog,
  246.                               wxBoxSizer *_p_sizer )
  247.   : wxTreeCtrl( _p_parent, PrefsTree_Ctrl, wxDefaultPosition, wxDefaultSize,
  248.                 wxTR_NO_LINES | wxTR_FULL_ROW_HIGHLIGHT |
  249.                 wxTR_LINES_AT_ROOT | wxTR_HIDE_ROOT |
  250.                 wxTR_HAS_BUTTONS | wxTR_TWIST_BUTTONS | wxSUNKEN_BORDER )
  251. {
  252.     vlc_list_t      *p_list;
  253.     module_t        *p_module;
  254.     module_config_t *p_item;
  255.     int i_index;
  256.     /* Initializations */
  257.     p_intf = _p_intf;
  258.     p_prefs_dialog = _p_prefs_dialog;
  259.     p_sizer = _p_sizer;
  260.     p_parent = _p_parent;
  261.     b_advanced = VLC_FALSE;
  262.     root_item = AddRoot( wxT("") );
  263.     /* List the plugins */
  264.     p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
  265.     if( !p_list ) return;
  266.     /*
  267.      * Build a tree of the main options
  268.      */
  269.     ConfigTreeData *config_data = new ConfigTreeData;
  270.     config_data->i_object_id = GENERAL_ID;
  271.     config_data->psz_help = wraptext( GENERAL_HELP, 72 , ISUTF8 );
  272.     config_data->psz_section = strdup( GENERAL_TITLE );
  273.     general_item = AppendItem( root_item, wxU(_("General settings")),
  274.                                 -1, -1, config_data );
  275.     for( i_index = 0; i_index < p_list->i_count; i_index++ )
  276.     {
  277.         p_module = (module_t *)p_list->p_values[i_index].p_object;
  278.         if( !strcmp( p_module->psz_object_name, "main" ) )
  279.             break;
  280.     }
  281.     if( i_index < p_list->i_count )
  282.     {
  283.         /* We found the main module */
  284.         /* Enumerate config categories and store a reference so we can
  285.          * generate their config panel them when it is asked by the user. */
  286.         p_item = p_module->p_config;
  287.         if( p_item ) do
  288.         {
  289.             switch( p_item->i_type )
  290.             {
  291.             case CONFIG_HINT_CATEGORY:
  292.                 ConfigTreeData *config_data = new ConfigTreeData;
  293.                 config_data->psz_section = strdup(p_item->psz_text);
  294.                 if( p_item->psz_longtext )
  295.                 {
  296.                     config_data->psz_help =
  297.                         wraptext( p_item->psz_longtext, 72 , ISUTF8 );
  298.                 }
  299.                 else
  300.                 {
  301.                     config_data->psz_help = NULL;
  302.                 }
  303.                 config_data->i_object_id = p_module->i_object_id;
  304.                 /* Add the category to the tree */
  305.                 AppendItem( general_item, wxU(p_item->psz_text),
  306.                             -1, -1, config_data );
  307.                 break;
  308.             }
  309.         }
  310.         while( p_item->i_type != CONFIG_HINT_END && p_item++ );
  311.         SortChildren( general_item );
  312.     }
  313.     /*
  314.      * Build a tree of all the plugins
  315.      */
  316.     config_data = new ConfigTreeData;
  317.     config_data->i_object_id = PLUGIN_ID;
  318.     config_data->psz_help = wraptext( PLUGIN_HELP, 72, ISUTF8 );
  319.     config_data->psz_section = strdup( PLUGIN_TITLE );
  320.     plugins_item = AppendItem( root_item, wxU(_("Modules")),
  321.                         -1, -1,config_data );
  322.     for( i_index = 0; i_index < p_list->i_count; i_index++ )
  323.     {
  324.         p_module = (module_t *)p_list->p_values[i_index].p_object;
  325.         /* Exclude the main module */
  326.         if( !strcmp( p_module->psz_object_name, "main" ) )
  327.             continue;
  328.         /* Exclude empty plugins (submodules don't have config options, they
  329.          * are stored in the parent module) */
  330.         if( p_module->b_submodule )
  331.             p_item = ((module_t *)p_module->p_parent)->p_config;
  332.         else
  333.             p_item = p_module->p_config;
  334.         if( !p_item ) continue;
  335.         do
  336.         {
  337.             if( p_item->i_type & CONFIG_ITEM )
  338.                 break;
  339.         }
  340.         while( p_item->i_type != CONFIG_HINT_END && p_item++ );
  341.         if( p_item->i_type == CONFIG_HINT_END ) continue;
  342.         /* Find the capability child item */
  343.         long cookie; size_t i_child_index;
  344.         wxTreeItemId capability_item = GetFirstChild( plugins_item, cookie);
  345.         for( i_child_index = 0;
  346.              i_child_index < GetChildrenCount( plugins_item, FALSE );
  347.              i_child_index++ )
  348.         {
  349.             if( !GetItemText(capability_item).Cmp(
  350.                     wxU(p_module->psz_capability ) ) )
  351.             {
  352.                 break;
  353.             }
  354.             capability_item = GetNextChild( plugins_item, cookie );
  355.         }
  356.         if( i_child_index == GetChildrenCount( plugins_item, FALSE ) &&
  357.             p_module->psz_capability && *p_module->psz_capability )
  358.         {
  359.             /* We didn't find it, add it */
  360.             ConfigTreeData *config_data = new ConfigTreeData;
  361.             config_data->psz_section =
  362.                 wraptext( GetCapabilityHelp( p_module->psz_capability , 1 ),
  363.                           72, ISUTF8 );
  364.             config_data->psz_help =
  365.                 wraptext( GetCapabilityHelp( p_module->psz_capability , 2 ),
  366.                           72, ISUTF8 );
  367.             config_data->i_object_id = CAPABILITY_ID;
  368.             capability_item = AppendItem( plugins_item,
  369.                                           wxU(p_module->psz_capability),
  370.                                           -1,-1,config_data );
  371.         }
  372.         /* Add the plugin to the tree */
  373.         ConfigTreeData *config_data = new ConfigTreeData;
  374.         config_data->b_submodule = p_module->b_submodule;
  375.         config_data->i_object_id = p_module->b_submodule ?
  376.             ((module_t *)p_module->p_parent)->i_object_id :
  377.             p_module->i_object_id;
  378.         config_data->psz_help = NULL;
  379.         AppendItem( capability_item, wxU(p_module->psz_object_name), -1, -1,
  380.                     config_data );
  381.     }
  382.     /* Sort all this mess */
  383.     long cookie; size_t i_child_index;
  384.     SortChildren( plugins_item );
  385.     wxTreeItemId capability_item = GetFirstChild( plugins_item, cookie);
  386.     for( i_child_index = 0;
  387.          i_child_index < GetChildrenCount( plugins_item, FALSE );
  388.          i_child_index++ )
  389.     {
  390.         SortChildren( capability_item );
  391.         capability_item = GetNextChild( plugins_item, cookie );
  392.     }
  393.     /* Clean-up everything */
  394.     vlc_list_release( p_list );
  395.     p_sizer->Add( this, 1, wxEXPAND | wxALL, 0 );
  396.     p_sizer->Layout();
  397.     /* Update Tree Ctrl */
  398. #ifndef WIN32 /* Workaround a bug in win32 implementation */
  399.     SelectItem( GetFirstChild( root_item, cookie ) );
  400. #endif
  401.     Expand( general_item );
  402. }
  403. PrefsTreeCtrl::~PrefsTreeCtrl()
  404. {
  405. }
  406. void PrefsTreeCtrl::ApplyChanges()
  407. {
  408.     long cookie, cookie2;
  409.     ConfigTreeData *config_data;
  410.     /* Apply changes to the main module */
  411.     wxTreeItemId item = GetFirstChild( general_item, cookie );
  412.     for( size_t i_child_index = 0;
  413.          i_child_index < GetChildrenCount( general_item, FALSE );
  414.          i_child_index++ )
  415.     {
  416.         config_data = (ConfigTreeData *)GetItemData( item );
  417.         if( config_data && config_data->panel )
  418.         {
  419.             config_data->panel->ApplyChanges();
  420.         }
  421.         item = GetNextChild( general_item, cookie );
  422.     }
  423.     /* Apply changes to the plugins */
  424.     item = GetFirstChild( plugins_item, cookie );
  425.     for( size_t i_child_index = 0;
  426.          i_child_index < GetChildrenCount( plugins_item, FALSE );
  427.          i_child_index++ )
  428.     {
  429.         wxTreeItemId item2 = GetFirstChild( item, cookie2 );
  430.         for( size_t i_child_index = 0;
  431.              i_child_index < GetChildrenCount( item, FALSE );
  432.              i_child_index++ )
  433.         {
  434.             config_data = (ConfigTreeData *)GetItemData( item2 );
  435.             if( config_data && config_data->panel )
  436.             {
  437.                 config_data->panel->ApplyChanges();
  438.             }
  439.             item2 = GetNextChild( item, cookie2 );
  440.         }
  441.         item = GetNextChild( plugins_item, cookie );
  442.     }
  443. }
  444. void PrefsTreeCtrl::CleanChanges()
  445. {
  446.     long cookie, cookie2;
  447.     ConfigTreeData *config_data;
  448.     config_data = !GetSelection() ? NULL :
  449.         FindModuleConfig( (ConfigTreeData *)GetItemData( GetSelection() ) );
  450.     if( config_data  )
  451.     {
  452.         config_data->panel->Hide();
  453.         p_sizer->Remove( config_data->panel );
  454.     }
  455.     /* Clean changes for the main module */
  456.     wxTreeItemId item = GetFirstChild( general_item, cookie );
  457.     for( size_t i_child_index = 0;
  458.          i_child_index < GetChildrenCount( general_item, FALSE );
  459.          i_child_index++ )
  460.     {
  461.         config_data = (ConfigTreeData *)GetItemData( item );
  462.         if( config_data && config_data->panel )
  463.         {
  464.             delete config_data->panel;
  465.             config_data->panel = NULL;
  466.         }
  467.         item = GetNextChild( general_item, cookie );
  468.     }
  469.     /* Clean changes for the plugins */
  470.     item = GetFirstChild( plugins_item, cookie );
  471.     for( size_t i_child_index = 0;
  472.          i_child_index < GetChildrenCount( plugins_item, FALSE );
  473.          i_child_index++ )
  474.     {
  475.         wxTreeItemId item2 = GetFirstChild( item, cookie2 );
  476.         for( size_t i_child_index = 0;
  477.              i_child_index < GetChildrenCount( item, FALSE );
  478.              i_child_index++ )
  479.         {
  480.             config_data = (ConfigTreeData *)GetItemData( item2 );
  481.             if( config_data && config_data->panel )
  482.             {
  483.                 delete config_data->panel;
  484.                 config_data->panel = NULL;
  485.             }
  486.             item2 = GetNextChild( item, cookie2 );
  487.         }
  488.         item = GetNextChild( plugins_item, cookie );
  489.     }
  490.     if( GetSelection() )
  491.     {
  492.         wxTreeEvent event;
  493.         OnSelectTreeItem( event );
  494.     }
  495. }
  496. ConfigTreeData *PrefsTreeCtrl::FindModuleConfig( ConfigTreeData *config_data )
  497. {
  498.     /* We need this complexity because submodules don't have their own config
  499.      * options. They use the parent module ones. */
  500.     if( !config_data || !config_data->b_submodule )
  501.     {
  502.         return config_data;
  503.     }
  504.     long cookie, cookie2;
  505.     ConfigTreeData *config_new;
  506.     wxTreeItemId item = GetFirstChild( plugins_item, cookie );
  507.     for( size_t i_child_index = 0;
  508.          i_child_index < GetChildrenCount( plugins_item, FALSE );
  509.          i_child_index++ )
  510.     {
  511.         wxTreeItemId item2 = GetFirstChild( item, cookie2 );
  512.         for( size_t i_child_index = 0;
  513.              i_child_index < GetChildrenCount( item, FALSE );
  514.              i_child_index++ )
  515.         {
  516.             config_new = (ConfigTreeData *)GetItemData( item2 );
  517.             if( config_new && !config_new->b_submodule &&
  518.                 config_new->i_object_id == config_data->i_object_id )
  519.             {
  520.                 return config_new;
  521.             }
  522.             item2 = GetNextChild( item, cookie2 );
  523.         }
  524.         item = GetNextChild( plugins_item, cookie );
  525.     }
  526.     /* Found nothing */
  527.     return NULL;
  528. }
  529. void PrefsTreeCtrl::OnSelectTreeItem( wxTreeEvent& event )
  530. {
  531.     ConfigTreeData *config_data = NULL;
  532.     if( event.GetOldItem() )
  533.         config_data = FindModuleConfig( (ConfigTreeData *)GetItemData(
  534.                                         event.GetOldItem() ) );
  535.     if( config_data && config_data->panel )
  536.     {
  537.         config_data->panel->Hide();
  538.         p_sizer->Remove( config_data->panel );
  539.     }
  540.     /* Don't use event.GetItem() because we also send fake events */
  541.     config_data = FindModuleConfig( (ConfigTreeData *)GetItemData(
  542.                                     GetSelection() ) );
  543.     if( config_data )
  544.     {
  545.         if( !config_data->panel )
  546.         {
  547.             /* The panel hasn't been created yet. Let's do it. */
  548.             config_data->panel =
  549.                 new PrefsPanel( p_parent, p_intf, p_prefs_dialog,
  550.                                 config_data->i_object_id,
  551.                                 config_data->psz_section,
  552.                                 config_data->psz_help );
  553.             config_data->panel->SwitchAdvanced( b_advanced );
  554.         }
  555.         else
  556.         {
  557.             config_data->panel->SwitchAdvanced( b_advanced );
  558.             config_data->panel->Show();
  559.         }
  560.         p_sizer->Add( config_data->panel, 3, wxEXPAND | wxALL, 0 );
  561.         p_sizer->Layout();
  562.     }
  563. }
  564. void PrefsTreeCtrl::OnAdvanced( wxCommandEvent& event )
  565. {
  566.     b_advanced = event.GetInt();
  567.     ConfigTreeData *config_data = !GetSelection() ? NULL :
  568.         FindModuleConfig( (ConfigTreeData *)GetItemData( GetSelection() ) );
  569.     if( config_data  )
  570.     {
  571.         config_data->panel->Hide();
  572.         p_sizer->Remove( config_data->panel );
  573.     }
  574.     if( GetSelection() )
  575.     {
  576.         wxTreeEvent event;
  577.         OnSelectTreeItem( event );
  578.     }
  579. }
  580. /*****************************************************************************
  581.  * PrefsPanel class definition.
  582.  *****************************************************************************/
  583. PrefsPanel::PrefsPanel( wxWindow* parent, intf_thread_t *_p_intf,
  584.                         PrefsDialog *_p_prefs_dialog,
  585.                         int i_object_id, char *psz_section, char *psz_help )
  586.   :  wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize )
  587. {
  588.     module_config_t *p_item;
  589.     wxStaticText *label;
  590.     wxStaticText *help;
  591.     wxArrayString array;
  592.     module_t *p_module = NULL;
  593.     /* Initializations */
  594.     p_intf = _p_intf;
  595.     p_prefs_dialog =_p_prefs_dialog,
  596.     b_advanced = VLC_TRUE;
  597.     SetAutoLayout( TRUE );
  598.     Hide();
  599.     wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
  600.     if( i_object_id == PLUGIN_ID || i_object_id == GENERAL_ID ||
  601.         i_object_id == CAPABILITY_ID )
  602.     {
  603.         label = new wxStaticText( this, -1,wxU(_( psz_section )));
  604.         wxFont heading_font = label->GetFont();
  605.         heading_font.SetPointSize( heading_font.GetPointSize() + 5 );
  606.         label->SetFont( heading_font );
  607.         sizer->Add( label, 0, wxEXPAND | wxLEFT, 10 );
  608.         sizer->Add( new wxStaticLine( this, 0 ), 0,
  609.                     wxEXPAND | wxLEFT | wxRIGHT, 2 );
  610.         help = new wxStaticText( this, -1, wxU(_( psz_help ) ) );
  611.         sizer->Add( help ,0 ,wxEXPAND | wxALL, 5 );
  612.         config_sizer = NULL; config_window = NULL;
  613.     }
  614.     else
  615.     {
  616.         /* Get a pointer to the module */
  617.         p_module = (module_t *)vlc_object_get( p_intf,  i_object_id );
  618.         if( p_module->i_object_type != VLC_OBJECT_MODULE )
  619.         {
  620.             /* 0OOoo something went really bad */
  621.             return;
  622.         }
  623.         /* Enumerate config options and add corresponding config boxes
  624.          * (submodules don't have config options, they are stored in the
  625.          *  parent module) */
  626.         if( p_module->b_submodule )
  627.             p_item = ((module_t *)p_module->p_parent)->p_config;
  628.         else
  629.             p_item = p_module->p_config;
  630.         /* Find the category if it has been specified */
  631.         if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY )
  632.         {
  633.             while( !p_item->i_type == CONFIG_HINT_CATEGORY ||
  634.                    strcmp( psz_section, p_item->psz_text ) )
  635.             {
  636.                 if( p_item->i_type == CONFIG_HINT_END )
  637.                     break;
  638.                 p_item++;
  639.             }
  640.         }
  641.         /* Add a head title to the panel */
  642.         label = new wxStaticText( this, -1,
  643.                                   wxU(_(psz_section ? p_item->psz_text :
  644.                                   p_module->psz_longname )));
  645.         wxFont heading_font = label->GetFont();
  646.         heading_font.SetPointSize( heading_font.GetPointSize() + 5 );
  647.         label->SetFont( heading_font );
  648.         sizer->Add( label, 0, wxEXPAND | wxLEFT, 10 );
  649.         sizer->Add( new wxStaticLine( this, 0 ), 0,
  650.                     wxEXPAND | wxLEFT | wxRIGHT, 2 );
  651.         /* Now put all the config options into a scrolled window */
  652.         config_sizer = new wxBoxSizer( wxVERTICAL );
  653.         config_window = new wxScrolledWindow( this, -1, wxDefaultPosition,
  654.             wxDefaultSize, wxBORDER_NONE | wxHSCROLL | wxVSCROLL );
  655.         config_window->SetAutoLayout( TRUE );
  656.         config_window->SetScrollRate( 5, 5 );
  657.         if( p_item ) do
  658.         {
  659.             /* If a category has been specified, check we finished the job */
  660.             if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY &&
  661.                 strcmp( psz_section, p_item->psz_text ) )
  662.                 break;
  663.             ConfigControl *control =
  664.                 CreateConfigControl( VLC_OBJECT(p_intf),
  665.                                      p_item, config_window );
  666.             /* Don't add items that were not recognized */
  667.             if( control == NULL ) continue;
  668.             /* Add the config data to our array so we can keep a trace of it */
  669.             config_array.Add( control );
  670.             config_sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
  671.         }
  672.         while( p_item->i_type != CONFIG_HINT_END && p_item++ );
  673.         config_sizer->Layout();
  674.         config_window->SetSizer( config_sizer );
  675.         sizer->Add( config_window, 1, wxEXPAND | wxALL, 5 );
  676.         /* And at last put a useful help string if available */
  677.         if( psz_help && *psz_help )
  678.         {
  679.             sizer->Add( new wxStaticLine( this, 0 ), 0,
  680.                         wxEXPAND | wxLEFT | wxRIGHT, 2 );
  681.             help = new wxStaticText( this, -1, wxU(_(psz_help)),
  682.                                      wxDefaultPosition, wxDefaultSize,
  683.                                      wxALIGN_LEFT,
  684.                                      wxT("") );
  685.             sizer->Add( help ,0 ,wxEXPAND | wxALL, 5 );
  686.         }
  687.         vlc_object_release( p_module );
  688.     }
  689.     sizer->Layout();
  690.     SetSizer( sizer );
  691.     Show();
  692. }
  693. void PrefsPanel::ApplyChanges()
  694. {
  695.     vlc_value_t val;
  696.     for( size_t i = 0; i < config_array.GetCount(); i++ )
  697.     {
  698.         ConfigControl *control = config_array.Item(i);
  699.         switch( control->GetType() )
  700.         {
  701.         case CONFIG_ITEM_STRING:
  702.         case CONFIG_ITEM_FILE:
  703.         case CONFIG_ITEM_DIRECTORY:
  704.         case CONFIG_ITEM_MODULE:
  705.             config_PutPsz( p_intf, control->GetName().mb_str(),
  706.                            control->GetPszValue().mb_str() );
  707.             break;
  708.         case CONFIG_ITEM_KEY:
  709.             /* So you don't need to restart to have the changes take effect */
  710.             val.i_int = control->GetIntValue();
  711.             var_Set( p_intf->p_vlc, control->GetName().mb_str(), val );
  712.         case CONFIG_ITEM_INTEGER:
  713.         case CONFIG_ITEM_BOOL:
  714.             config_PutInt( p_intf, control->GetName().mb_str(),
  715.                            control->GetIntValue() );
  716.             break;
  717.         case CONFIG_ITEM_FLOAT:
  718.             config_PutFloat( p_intf, control->GetName().mb_str(),
  719.                              control->GetFloatValue() );
  720.             break;
  721.         }
  722.     }
  723. }
  724. void PrefsPanel::SwitchAdvanced( vlc_bool_t b_new_advanced )
  725. {
  726.     if( b_advanced == b_new_advanced ) return;
  727.     if( config_sizer && config_window )
  728.     {
  729.         b_advanced = b_new_advanced;
  730.         for( size_t i = 0; i < config_array.GetCount(); i++ )
  731.         {
  732.             ConfigControl *control = config_array.Item(i);
  733.             if( control->IsAdvanced() )
  734.             {
  735.                 control->Show( b_advanced );
  736.                 config_sizer->Show( control, b_advanced );
  737.             }
  738.         }
  739.         config_sizer->Layout();
  740.         config_window->FitInside();
  741.         config_window->Refresh();
  742.     }
  743.     return;
  744. }