1 /*****************************************************************************
2 * preferences.cpp : wxWindows plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2001 VideoLAN
5 * $Id: preferences.cpp,v 1.27 2003/09/21 17:52:43 gbazin Exp $
7 * Authors: Gildas Bazin <gbazin@netcourrier.com>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
28 #include <errno.h> /* ENOMEM */
29 #include <string.h> /* strerror() */
35 #include "wxwindows.h"
36 #include <wx/notebook.h>
37 #include <wx/textctrl.h>
38 #include <wx/combobox.h>
39 #include <wx/spinctrl.h>
40 #include <wx/statline.h>
41 #include <wx/treectrl.h>
42 #include <wx/clntdata.h>
43 #include <wx/dynarray.h>
46 # define wxRB_SINGLE 0
49 /*****************************************************************************
50 * Classes declarations.
51 *****************************************************************************/
53 class PrefsTreeCtrl : public wxTreeCtrl
58 PrefsTreeCtrl( wxWindow *parent, intf_thread_t *_p_intf,
59 PrefsDialog *p_prefs_dialog, wxBoxSizer *_p_sizer );
60 virtual ~PrefsTreeCtrl();
66 /* Event handlers (these functions should _not_ be virtual) */
67 void OnSelectTreeItem( wxTreeEvent& event );
68 void OnAdvanced( wxCommandEvent& event );
70 ConfigTreeData *FindModuleConfig( ConfigTreeData *config_data );
74 intf_thread_t *p_intf;
75 PrefsDialog *p_prefs_dialog;
78 vlc_bool_t b_advanced;
80 wxTreeItemId root_item;
81 wxTreeItemId plugins_item;
86 ConfigData( wxPanel *_panel, int _i_conf_type,
87 vlc_bool_t _b_advanced, char *psz_name )
88 { panel = _panel; b_advanced = _b_advanced; b_config_list = VLC_FALSE;
89 i_config_type = _i_conf_type; option_name = wxU(psz_name); }
91 vlc_bool_t b_advanced;
93 vlc_bool_t b_config_list;
100 wxCheckBox *checkbox;
101 wxTextCtrl *textctrl;
106 wxString option_name;
109 WX_DEFINE_ARRAY(ConfigData *, ArrayOfConfigData);
111 class PrefsPanel : public wxPanel
116 PrefsPanel( wxWindow *parent, intf_thread_t *_p_intf,
117 PrefsDialog *_p_prefs_dialog, int i_object_id, char * );
118 virtual ~PrefsPanel() {}
121 void SwitchAdvanced( vlc_bool_t );
124 intf_thread_t *p_intf;
125 PrefsDialog *p_prefs_dialog;
127 vlc_bool_t b_advanced;
129 wxBoxSizer *config_sizer;
130 wxScrolledWindow *config_window;
132 ArrayOfConfigData config_array;
135 class ConfigTreeData : public wxTreeItemData
139 ConfigTreeData() { b_submodule = 0; panel = NULL; psz_section = NULL; }
140 virtual ~ConfigTreeData() { if( panel ) delete panel; }
142 vlc_bool_t b_submodule;
150 class ConfigEvtHandler : public wxEvtHandler
153 ConfigEvtHandler( intf_thread_t *p_intf, PrefsDialog *p_prefs_dialog );
154 virtual ~ConfigEvtHandler();
156 void ConfigEvtHandler::OnCommandEvent( wxCommandEvent& event );
160 DECLARE_EVENT_TABLE()
162 intf_thread_t *p_intf;
163 PrefsDialog *p_prefs_dialog;
166 /*****************************************************************************
168 *****************************************************************************/
170 /* IDs for the controls and the menu commands */
173 Notebook_Event = wxID_HIGHEST,
179 BEGIN_EVENT_TABLE(PrefsDialog, wxFrame)
181 EVT_BUTTON(wxID_OK, PrefsDialog::OnOk)
182 EVT_BUTTON(wxID_CANCEL, PrefsDialog::OnCancel)
183 EVT_BUTTON(wxID_SAVE, PrefsDialog::OnSave)
184 EVT_BUTTON(ResetAll_Event, PrefsDialog::OnResetAll)
185 EVT_CHECKBOX(Advanced_Event, PrefsDialog::OnAdvanced)
187 /* Don't destroy the window when the user closes it */
188 EVT_CLOSE(PrefsDialog::OnCancel)
191 // menu and control ids
194 PrefsTree_Ctrl = wxID_HIGHEST
197 BEGIN_EVENT_TABLE(PrefsTreeCtrl, wxTreeCtrl)
198 EVT_TREE_SEL_CHANGED(PrefsTree_Ctrl, PrefsTreeCtrl::OnSelectTreeItem)
199 EVT_COMMAND(Advanced_Event, wxEVT_USER_FIRST, PrefsTreeCtrl::OnAdvanced)
202 BEGIN_EVENT_TABLE(ConfigEvtHandler, wxEvtHandler)
203 EVT_BUTTON(-1, ConfigEvtHandler::OnCommandEvent)
204 EVT_TEXT(-1, ConfigEvtHandler::OnCommandEvent)
205 EVT_RADIOBOX(-1, ConfigEvtHandler::OnCommandEvent)
206 EVT_SPINCTRL(-1, ConfigEvtHandler::OnCommandEvent)
209 /*****************************************************************************
211 *****************************************************************************/
212 PrefsDialog::PrefsDialog( intf_thread_t *_p_intf, wxWindow *p_parent)
213 : wxFrame( p_parent, -1, wxU(_("Preferences")), wxDefaultPosition,
214 wxSize(650,450), wxDEFAULT_FRAME_STYLE )
216 /* Initializations */
218 SetIcon( *p_intf->p_sys->p_icon );
220 /* Create a panel to put everything in */
221 wxPanel *panel = new wxPanel( this, -1 );
222 panel->SetAutoLayout( TRUE );
224 /* Create the preferences tree control */
225 wxBoxSizer *controls_sizer = new wxBoxSizer( wxHORIZONTAL );
227 new PrefsTreeCtrl( panel, p_intf, this, controls_sizer );
230 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
232 /* Create the buttons */
233 wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("OK")) );
234 ok_button->SetDefault();
235 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
237 wxButton *save_button = new wxButton( panel, wxID_SAVE, wxU(_("Save")) );
238 wxButton *reset_button = new wxButton( panel, ResetAll_Event,
239 wxU(_("Reset All")) );
241 wxPanel *dummy_panel = new wxPanel( this, -1 );
242 wxCheckBox *advanced_checkbox =
243 new wxCheckBox( panel, Advanced_Event, wxU(_("Advanced options")) );
245 if( config_GetInt( p_intf, "advanced" ) )
247 advanced_checkbox->SetValue(TRUE);
248 wxCommandEvent dummy_event;
249 dummy_event.SetInt(TRUE);
250 OnAdvanced( dummy_event );
253 /* Place everything in sizers */
254 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
255 button_sizer->Add( ok_button, 0, wxALL, 5 );
256 button_sizer->Add( cancel_button, 0, wxALL, 5 );
257 button_sizer->Add( save_button, 0, wxALL, 5 );
258 button_sizer->Add( reset_button, 0, wxALL, 5 );
259 button_sizer->Add( dummy_panel, 1, wxALL, 5 );
260 button_sizer->Add( advanced_checkbox, 0, wxALL | wxALIGN_RIGHT |
261 wxALIGN_CENTER_VERTICAL, 0 );
262 button_sizer->Layout();
264 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
265 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
266 panel_sizer->Add( controls_sizer, 1, wxEXPAND | wxALL, 5 );
267 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
268 panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALIGN_BOTTOM |
269 wxALL | wxEXPAND, 5 );
270 panel_sizer->Layout();
271 panel->SetSizer( panel_sizer );
272 main_sizer->Add( panel, 1, wxEXPAND, 0 );
273 main_sizer->Layout();
274 SetSizer( main_sizer );
277 PrefsDialog::~PrefsDialog()
281 /*****************************************************************************
283 *****************************************************************************/
286 /*****************************************************************************
288 *****************************************************************************/
289 void PrefsDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
291 prefs_tree->ApplyChanges();
293 prefs_tree->CleanChanges();
296 void PrefsDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
299 prefs_tree->CleanChanges();
302 void PrefsDialog::OnSave( wxCommandEvent& WXUNUSED(event) )
304 prefs_tree->ApplyChanges();
305 config_SaveConfigFile( p_intf, NULL );
308 void PrefsDialog::OnResetAll( wxCommandEvent& WXUNUSED(event) )
310 wxMessageDialog dlg( this,
311 wxU(_("Beware this will reset your VLC Media Player config file.\n"
312 "Are you sure you want to continue?")),
313 wxU(_("Reset config file")), wxYES_NO|wxNO_DEFAULT|wxCENTRE );
315 if ( dlg.ShowModal() == wxID_YES )
317 /* TODO: need to reset all the controls */
318 config_ResetAll( p_intf );
319 prefs_tree->CleanChanges();
320 config_SaveConfigFile( p_intf, NULL );
324 void PrefsDialog::OnAdvanced( wxCommandEvent& event )
326 wxCommandEvent newevent( wxEVT_USER_FIRST, Advanced_Event );
327 newevent.SetInt( event.GetInt() );
329 prefs_tree->AddPendingEvent( newevent );
332 /*****************************************************************************
333 * PrefsTreeCtrl class definition.
334 *****************************************************************************/
335 PrefsTreeCtrl::PrefsTreeCtrl( wxWindow *_p_parent, intf_thread_t *_p_intf,
336 PrefsDialog *_p_prefs_dialog,
337 wxBoxSizer *_p_sizer )
338 : wxTreeCtrl( _p_parent, PrefsTree_Ctrl, wxDefaultPosition, wxDefaultSize,
339 wxTR_NO_LINES | wxTR_FULL_ROW_HIGHLIGHT |
340 wxTR_LINES_AT_ROOT | wxTR_HIDE_ROOT |
341 wxTR_HAS_BUTTONS | wxTR_TWIST_BUTTONS | wxSUNKEN_BORDER )
345 module_config_t *p_item;
348 /* Initializations */
350 p_prefs_dialog = _p_prefs_dialog;
352 p_parent = _p_parent;
353 b_advanced = VLC_FALSE;
355 root_item = AddRoot( wxT("") );
357 /* List the plugins */
358 p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
359 if( !p_list ) return;
362 * Build a tree of the main options
364 for( i_index = 0; i_index < p_list->i_count; i_index++ )
366 p_module = (module_t *)p_list->p_values[i_index].p_object;
367 if( !strcmp( p_module->psz_object_name, "main" ) )
370 if( i_index < p_list->i_count )
372 /* We found the main module */
374 /* Enumerate config categories and store a reference so we can
375 * generate their config panel them when it is asked by the user. */
376 p_item = p_module->p_config;
380 switch( p_item->i_type )
382 case CONFIG_HINT_CATEGORY:
383 ConfigTreeData *config_data = new ConfigTreeData;
384 config_data->psz_section = strdup(p_item->psz_text);
385 config_data->i_object_id = p_module->i_object_id;
387 /* Add the category to the tree */
388 AppendItem( root_item, wxU(p_item->psz_text),
389 -1, -1, config_data );
393 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
395 SortChildren( root_item );
400 * Build a tree of all the plugins
402 plugins_item = AppendItem( root_item, wxU(_("Plugins")) );
404 for( i_index = 0; i_index < p_list->i_count; i_index++ )
406 p_module = (module_t *)p_list->p_values[i_index].p_object;
408 /* Exclude the main module */
409 if( !strcmp( p_module->psz_object_name, "main" ) )
412 /* Exclude empty plugins (submodules don't have config options, they
413 * are stored in the parent module) */
414 if( p_module->b_submodule )
415 p_item = ((module_t *)p_module->p_parent)->p_config;
417 p_item = p_module->p_config;
419 if( !p_item ) continue;
422 if( p_item->i_type & CONFIG_ITEM )
425 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
426 if( p_item->i_type == CONFIG_HINT_END ) continue;
428 /* Find the capability child item */
429 long cookie; size_t i_child_index;
430 wxTreeItemId capability_item = GetFirstChild( plugins_item, cookie);
431 for( i_child_index = 0;
432 i_child_index < GetChildrenCount( plugins_item, FALSE );
435 if( !GetItemText(capability_item).Cmp(
436 wxU(p_module->psz_capability ) ) )
440 capability_item = GetNextChild( plugins_item, cookie );
443 if( i_child_index == GetChildrenCount( plugins_item, FALSE ) &&
444 p_module->psz_capability && *p_module->psz_capability )
446 /* We didn't find it, add it */
447 capability_item = AppendItem( plugins_item,
448 wxU(p_module->psz_capability) );
451 /* Add the plugin to the tree */
452 ConfigTreeData *config_data = new ConfigTreeData;
453 config_data->b_submodule = p_module->b_submodule;
454 config_data->i_object_id = p_module->b_submodule ?
455 ((module_t *)p_module->p_parent)->i_object_id :
456 p_module->i_object_id;
457 AppendItem( capability_item, wxU(p_module->psz_object_name), -1, -1,
461 /* Sort all this mess */
462 long cookie; size_t i_child_index;
463 SortChildren( plugins_item );
464 wxTreeItemId capability_item = GetFirstChild( plugins_item, cookie);
465 for( i_child_index = 0;
466 i_child_index < GetChildrenCount( plugins_item, FALSE );
469 capability_item = GetNextChild( plugins_item, cookie );
470 SortChildren( capability_item );
473 /* Clean-up everything */
474 vlc_list_release( p_list );
476 p_sizer->Add( this, 1, wxEXPAND | wxALL, 0 );
479 /* Update Tree Ctrl */
480 #ifndef WIN32 /* Workaround a bug in win32 implementation */
481 SelectItem( GetFirstChild( root_item, cookie ) );
485 PrefsTreeCtrl::~PrefsTreeCtrl()
489 void PrefsTreeCtrl::ApplyChanges()
491 long cookie, cookie2;
492 ConfigTreeData *config_data;
494 /* Apply changes to the main module */
495 wxTreeItemId item = GetFirstChild( root_item, cookie );
496 for( size_t i_child_index = 0;
497 i_child_index < GetChildrenCount( root_item, FALSE );
500 config_data = (ConfigTreeData *)GetItemData( item );
501 if( config_data && config_data->panel )
503 config_data->panel->ApplyChanges();
506 item = GetNextChild( root_item, cookie );
509 /* Apply changes to the plugins */
510 item = GetFirstChild( plugins_item, cookie );
511 for( size_t i_child_index = 0;
512 i_child_index < GetChildrenCount( plugins_item, FALSE );
515 wxTreeItemId item2 = GetFirstChild( item, cookie2 );
516 for( size_t i_child_index = 0;
517 i_child_index < GetChildrenCount( item, FALSE );
520 config_data = (ConfigTreeData *)GetItemData( item2 );
521 if( config_data && config_data->panel )
523 config_data->panel->ApplyChanges();
526 item2 = GetNextChild( item, cookie2 );
529 item = GetNextChild( plugins_item, cookie );
533 void PrefsTreeCtrl::CleanChanges()
535 long cookie, cookie2;
536 ConfigTreeData *config_data;
538 config_data = !GetSelection() ? NULL :
539 FindModuleConfig( (ConfigTreeData *)GetItemData( GetSelection() ) );
542 config_data->panel->Hide();
543 p_sizer->Remove( config_data->panel );
546 /* Clean changes for the main module */
547 wxTreeItemId item = GetFirstChild( root_item, cookie );
548 for( size_t i_child_index = 0;
549 i_child_index < GetChildrenCount( root_item, FALSE );
552 config_data = (ConfigTreeData *)GetItemData( item );
553 if( config_data && config_data->panel )
555 delete config_data->panel;
556 config_data->panel = NULL;
559 item = GetNextChild( root_item, cookie );
562 /* Clean changes for the plugins */
563 item = GetFirstChild( plugins_item, cookie );
564 for( size_t i_child_index = 0;
565 i_child_index < GetChildrenCount( plugins_item, FALSE );
568 wxTreeItemId item2 = GetFirstChild( item, cookie2 );
569 for( size_t i_child_index = 0;
570 i_child_index < GetChildrenCount( item, FALSE );
573 config_data = (ConfigTreeData *)GetItemData( item2 );
575 if( config_data && config_data->panel )
577 delete config_data->panel;
578 config_data->panel = NULL;
581 item2 = GetNextChild( item, cookie2 );
584 item = GetNextChild( plugins_item, cookie );
590 OnSelectTreeItem( event );
594 ConfigTreeData *PrefsTreeCtrl::FindModuleConfig( ConfigTreeData *config_data )
596 /* We need this complexity because submodules don't have their own config
597 * options. They use the parent module ones. */
599 if( !config_data || !config_data->b_submodule )
604 long cookie, cookie2;
605 ConfigTreeData *config_new;
606 wxTreeItemId item = GetFirstChild( plugins_item, cookie );
607 for( size_t i_child_index = 0;
608 i_child_index < GetChildrenCount( plugins_item, FALSE );
611 wxTreeItemId item2 = GetFirstChild( item, cookie2 );
612 for( size_t i_child_index = 0;
613 i_child_index < GetChildrenCount( item, FALSE );
616 config_new = (ConfigTreeData *)GetItemData( item2 );
617 if( config_new && !config_new->b_submodule &&
618 config_new->i_object_id == config_data->i_object_id )
623 item2 = GetNextChild( item, cookie2 );
626 item = GetNextChild( plugins_item, cookie );
633 void PrefsTreeCtrl::OnSelectTreeItem( wxTreeEvent& event )
635 ConfigTreeData *config_data;
637 config_data = FindModuleConfig( (ConfigTreeData *)GetItemData(
638 event.GetOldItem() ) );
639 if( config_data && config_data->panel )
641 config_data->panel->Hide();
642 p_sizer->Remove( config_data->panel );
645 /* Don't use event.GetItem() because we also send fake events */
646 config_data = FindModuleConfig( (ConfigTreeData *)GetItemData(
650 if( !config_data->panel )
652 /* The panel hasn't been created yet. Let's do it. */
654 new PrefsPanel( p_parent, p_intf, p_prefs_dialog,
655 config_data->i_object_id,
656 config_data->psz_section );
657 config_data->panel->SwitchAdvanced( b_advanced );
661 config_data->panel->SwitchAdvanced( b_advanced );
662 config_data->panel->Show();
665 p_sizer->Add( config_data->panel, 2, wxEXPAND | wxALL, 0 );
670 void PrefsTreeCtrl::OnAdvanced( wxCommandEvent& event )
672 b_advanced = event.GetInt();
674 ConfigTreeData *config_data = !GetSelection() ? NULL :
675 FindModuleConfig( (ConfigTreeData *)GetItemData( GetSelection() ) );
678 config_data->panel->Hide();
679 p_sizer->Remove( config_data->panel );
685 OnSelectTreeItem( event );
689 /*****************************************************************************
690 * PrefsPanel class definition.
691 *****************************************************************************/
692 PrefsPanel::PrefsPanel( wxWindow* parent, intf_thread_t *_p_intf,
693 PrefsDialog *_p_prefs_dialog,
694 int i_object_id, char *psz_section )
695 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize )
697 module_config_t *p_item;
704 wxCheckBox *checkbox;
705 wxTextCtrl *textctrl;
709 /* Initializations */
711 p_prefs_dialog =_p_prefs_dialog,
713 b_advanced = VLC_TRUE;
714 SetAutoLayout( TRUE );
716 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
718 /* Get a pointer to the module */
719 module_t *p_module = (module_t *)vlc_object_get( p_intf, i_object_id );
720 if( p_module->i_object_type != VLC_OBJECT_MODULE )
722 /* 0OOoo something went really bad */
726 /* Enumerate config options and add corresponding config boxes
727 * (submodules don't have config options, they are stored in the
729 if( p_module->b_submodule )
730 p_item = ((module_t *)p_module->p_parent)->p_config;
732 p_item = p_module->p_config;
734 /* Find the category if it has been specified */
735 if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY )
737 while( !p_item->i_type == CONFIG_HINT_CATEGORY ||
738 strcmp( psz_section, p_item->psz_text ) )
740 if( p_item->i_type == CONFIG_HINT_END )
746 /* Add a head title to the panel */
747 wxStaticBox *static_box = new wxStaticBox( this, -1, wxT("") );
748 wxStaticBoxSizer *box_sizer = new wxStaticBoxSizer( static_box,
750 label = new wxStaticText( this, -1,
751 wxU(psz_section ? p_item->psz_text :
752 p_module->psz_longname) );
754 box_sizer->Add( label, 1, wxALL, 5 );
755 sizer->Add( box_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, 5 );
757 /* Now put all the config options into a scrolled window */
758 config_sizer = new wxBoxSizer( wxVERTICAL );
759 config_window = new wxScrolledWindow( this, -1, wxDefaultPosition,
760 wxDefaultSize, wxSTATIC_BORDER | wxHSCROLL | wxVSCROLL );
761 config_window->SetAutoLayout( TRUE );
762 config_window->SetScrollRate( 5, 5 );
766 /* If a category has been specified, check we finished the job */
767 if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY &&
768 strcmp( psz_section, p_item->psz_text ) )
771 /* put each config option in a separate panel so we can hide advanced
773 wxPanel *panel = new wxPanel( config_window, -1, wxDefaultPosition,
775 wxBoxSizer *panel_sizer = new wxBoxSizer( wxHORIZONTAL );
776 ConfigData *config_data =
777 new ConfigData( panel, p_item->i_type,
778 p_item->b_advanced, p_item->psz_name );
780 switch( p_item->i_type )
782 case CONFIG_ITEM_MODULE:
783 label = new wxStaticText(panel, -1, wxU(p_item->psz_text));
784 combo = new wxComboBox( panel, -1, wxU(p_item->psz_value),
785 wxDefaultPosition, wxDefaultSize,
786 0, NULL, wxCB_READONLY | wxCB_SORT );
788 /* build a list of available modules */
789 p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
790 combo->Append( wxU(_("Default")), (void *)NULL );
791 combo->SetSelection( 0 );
792 for( int i_index = 0; i_index < p_list->i_count; i_index++ )
794 p_parser = (module_t *)p_list->p_values[i_index].p_object ;
796 if( !strcmp( p_parser->psz_capability,
799 combo->Append( wxU(p_parser->psz_longname),
800 p_parser->psz_object_name );
801 if( p_item->psz_value &&
802 !strcmp(p_item->psz_value, p_parser->psz_object_name) )
803 combo->SetValue( wxU(p_parser->psz_longname) );
806 vlc_list_release( p_list );
808 combo->SetToolTip( wxU(p_item->psz_longtext) );
809 config_data->control.combobox = combo;
810 panel_sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
811 panel_sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
814 case CONFIG_ITEM_STRING:
815 case CONFIG_ITEM_FILE:
816 case CONFIG_ITEM_DIRECTORY:
817 label = new wxStaticText(panel, -1, wxU(p_item->psz_text));
818 panel_sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
820 if( !p_item->ppsz_list )
822 textctrl = new wxTextCtrl( panel, -1, wxU(p_item->psz_value),
823 wxDefaultPosition, wxDefaultSize,
825 textctrl->SetToolTip( wxU(p_item->psz_longtext) );
826 config_data->control.textctrl = textctrl;
827 panel_sizer->Add( textctrl, 1, wxALL, 5 );
831 combo = new wxComboBox( panel, -1, wxU(p_item->psz_value),
832 wxDefaultPosition, wxDefaultSize,
833 0, NULL, wxCB_READONLY | wxCB_SORT );
835 /* build a list of available options */
836 for( int i_index = 0; p_item->ppsz_list[i_index]; i_index++ )
838 combo->Append( wxU(p_item->ppsz_list[i_index]) );
839 if( p_item->psz_value && !strcmp( p_item->psz_value,
840 p_item->ppsz_list[i_index] ) )
841 combo->SetSelection( i_index );
844 if( p_item->psz_value )
845 combo->SetValue( wxU(p_item->psz_value) );
846 combo->SetToolTip( wxU(p_item->psz_longtext) );
847 config_data->control.combobox = combo;
848 config_data->b_config_list = VLC_TRUE;
849 panel_sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
852 if( p_item->i_type == CONFIG_ITEM_FILE )
854 button = new wxButton( panel, -1, wxU(_("Browse...")) );
855 panel_sizer->Add( button, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
856 button->SetClientData((void *)config_data);
860 case CONFIG_ITEM_INTEGER:
861 label = new wxStaticText(panel, -1, wxU(p_item->psz_text));
862 spin = new wxSpinCtrl( panel, -1,
863 wxString::Format(wxT("%d"),p_item->i_value),
864 wxDefaultPosition, wxDefaultSize,
866 -16000, 16000, p_item->i_value);
867 spin->SetToolTip( wxU(p_item->psz_longtext) );
868 config_data->control.spinctrl = spin;
869 panel_sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
870 panel_sizer->Add( spin, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
872 spin->SetClientData((void *)config_data);
875 case CONFIG_ITEM_KEY:
877 label = new wxStaticText(panel, -1, wxU(p_item->psz_text));
878 wxCheckBox *alt = new wxCheckBox( panel, -1, wxU(_("Alt")) );
879 alt->SetValue( p_item->i_value & KEY_MODIFIER_ALT );
880 wxCheckBox *ctrl = new wxCheckBox( panel, -1, wxU(_("Ctrl")) );
881 ctrl->SetValue( p_item->i_value & KEY_MODIFIER_CTRL );
882 wxCheckBox *shift = new wxCheckBox( panel, -1, wxU(_("Shift")) );
883 shift->SetValue( p_item->i_value & KEY_MODIFIER_SHIFT );
884 combo = new wxComboBox( panel, -1, wxU("f"), wxDefaultPosition,
885 wxDefaultSize, 0, NULL, wxCB_READONLY | wxCB_SORT );
886 for( int i = 0; i < sizeof(keys)/sizeof(key_descriptor_s); i++ )
888 combo->Append( wxU(_(keys[i].psz_key_string)),
889 (void*)&keys[i].i_key_code );
891 combo->SetValue( wxU( KeyToString( p_item->i_value &
893 config_data->control.combobox = combo;
894 panel_sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
895 panel_sizer->Add( alt, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
896 panel_sizer->Add( ctrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
897 panel_sizer->Add( shift, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
898 panel_sizer->Add( combo, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
902 case CONFIG_ITEM_FLOAT:
903 label = new wxStaticText(panel, -1, wxU(p_item->psz_text));
904 textctrl = new wxTextCtrl( panel, -1,
905 wxString::Format(wxT("%f"),p_item->f_value),
906 wxDefaultPosition, wxDefaultSize,
907 wxTE_PROCESS_ENTER );
908 textctrl->SetToolTip( wxU(p_item->psz_longtext) );
909 config_data->control.textctrl = textctrl;
910 panel_sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
911 panel_sizer->Add( textctrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
914 case CONFIG_ITEM_BOOL:
915 checkbox = new wxCheckBox( panel, -1, wxU(p_item->psz_text) );
916 if( p_item->i_value ) checkbox->SetValue(TRUE);
917 checkbox->SetToolTip( wxU(p_item->psz_longtext) );
918 config_data->control.checkbox = checkbox;
919 panel_sizer->Add( checkbox, 0, wxALL, 5 );
923 delete panel; panel = NULL;
929 /* Don't add items that were not recognized */
930 if( panel == NULL ) continue;
932 panel_sizer->Layout();
933 panel->SetSizerAndFit( panel_sizer );
935 /* Add the config data to our array so we can keep a trace of it */
936 config_array.Add( config_data );
938 config_sizer->Add( panel, 0, wxEXPAND | wxALL, 2 );
940 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
942 config_sizer->Layout();
943 config_window->SetSizer( config_sizer );
944 sizer->Add( config_window, 1, wxEXPAND | wxLEFT | wxRIGHT, 5 );
946 /* Intercept all menu events in our custom event handler */
947 config_window->PushEventHandler(
948 new ConfigEvtHandler( p_intf, p_prefs_dialog ) );
954 void PrefsPanel::ApplyChanges()
956 for( size_t i = 0; i < config_array.GetCount(); i++ )
958 ConfigData *config_data = config_array.Item(i);
960 switch( config_data->i_config_type )
962 case CONFIG_ITEM_MODULE:
963 config_PutPsz( p_intf, config_data->option_name.mb_str(), (char *)
964 config_data->control.combobox->GetClientData(
965 config_data->control.combobox->GetSelection() ) );
967 case CONFIG_ITEM_STRING:
968 case CONFIG_ITEM_FILE:
969 case CONFIG_ITEM_DIRECTORY:
970 if( !config_data->b_config_list )
971 config_PutPsz( p_intf, config_data->option_name.mb_str(),
972 config_data->control.textctrl->GetValue().mb_str() );
974 config_PutPsz( p_intf, config_data->option_name.mb_str(),
975 config_data->control.combobox->GetValue().mb_str() );
977 case CONFIG_ITEM_BOOL:
978 config_PutInt( p_intf, config_data->option_name.mb_str(),
979 config_data->control.checkbox->IsChecked() );
981 case CONFIG_ITEM_INTEGER:
982 config_PutInt( p_intf, config_data->option_name.mb_str(),
983 config_data->control.spinctrl->GetValue() );
985 case CONFIG_ITEM_FLOAT:
988 if( (wxSscanf(config_data->control.textctrl->GetValue(),
989 wxT("%f"), &f_value) == 1) )
990 config_PutFloat( p_intf, config_data->option_name.mb_str(),
998 void PrefsPanel::SwitchAdvanced( vlc_bool_t b_new_advanced )
1000 if( b_advanced == b_new_advanced ) return;
1002 b_advanced = b_new_advanced;
1004 for( size_t i = 0; i < config_array.GetCount(); i++ )
1006 ConfigData *config_data = config_array.Item(i);
1007 if( config_data->b_advanced )
1009 config_data->panel->Show( b_advanced );
1010 config_sizer->Show( config_data->panel, b_advanced );
1014 config_sizer->Layout();
1015 config_window->FitInside();
1016 config_window->Refresh();
1019 /*****************************************************************************
1020 * A small helper class which intercepts all events
1021 *****************************************************************************/
1022 ConfigEvtHandler::ConfigEvtHandler( intf_thread_t *_p_intf,
1023 PrefsDialog *_p_prefs_dialog )
1025 /* Initializations */
1027 p_prefs_dialog = _p_prefs_dialog;
1030 ConfigEvtHandler::~ConfigEvtHandler()
1034 void ConfigEvtHandler::OnCommandEvent( wxCommandEvent& event )
1036 if( !event.GetEventObject() )
1042 ConfigData *config_data = (ConfigData *)
1043 ((wxEvtHandler *)event.GetEventObject())->GetClientData();
1051 if( config_data->i_config_type == CONFIG_ITEM_FILE )
1053 wxFileDialog dialog( p_prefs_dialog, wxU(_("Open file")),
1054 wxT(""), wxT(""), wxT("*.*"),
1055 #if defined( __WXMSW__ )
1061 if( dialog.ShowModal() == wxID_OK )
1063 config_data->control.textctrl->SetValue( dialog.GetPath() );
1067 switch( config_data->i_config_type )
1069 case CONFIG_ITEM_MODULE:
1071 case CONFIG_ITEM_STRING:
1073 case CONFIG_ITEM_FILE:
1075 case CONFIG_ITEM_INTEGER:
1077 case CONFIG_ITEM_FLOAT:
1079 case CONFIG_ITEM_BOOL: