]> git.sesse.net Git - vlc/blob - modules/gui/wxwidgets/dialogs/preferences_widgets.cpp
57f8d012d209b506cea96e9a3cb2c4674fee54c8
[vlc] / modules / gui / wxwidgets / dialogs / preferences_widgets.cpp
1 /*****************************************************************************
2  * preferences_widgets.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *          Sigmund Augdal Helberg <dnumgis@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #include "wxwidgets.hpp"
26 #include "preferences_widgets.h"
27 #include <vlc_keys.h>
28 #include <vlc_config_cat.h>
29
30 #include <wx/statline.h>
31 #include <wx/spinctrl.h>
32
33 /*****************************************************************************
34  * CreateConfigControl wrapper
35  *****************************************************************************/
36 ConfigControl *CreateConfigControl( vlc_object_t *p_this,
37                                     module_config_t *p_item, wxWindow *parent )
38 {
39     ConfigControl *p_control = NULL;
40
41     /*Skip deprecated options */
42     if( p_item->psz_current || p_item->b_unsaveable )
43     {
44         return NULL;
45     }
46
47     switch( p_item->i_type )
48     {
49     case CONFIG_ITEM_MODULE:
50         p_control = new ModuleConfigControl( p_this, p_item, parent );
51         break;
52     case CONFIG_ITEM_MODULE_CAT:
53         p_control = new ModuleCatConfigControl( p_this, p_item, parent );
54         break;
55     case CONFIG_ITEM_MODULE_LIST_CAT:
56         p_control = new ModuleListCatConfigControl( p_this, p_item, parent );
57         break;
58
59     case CONFIG_ITEM_STRING:
60         if( !p_item->i_list )
61         {
62             p_control = new StringConfigControl( p_this, p_item, parent );
63         }
64         else
65         {
66             p_control = new StringListConfigControl( p_this, p_item, parent );
67         }
68         break;
69
70     case CONFIG_ITEM_FILE:
71     case CONFIG_ITEM_DIRECTORY:
72         p_control = new FileConfigControl( p_this, p_item, parent );
73         break;
74
75     case CONFIG_ITEM_INTEGER:
76         if( p_item->i_list )
77         {
78             p_control = new IntegerListConfigControl( p_this, p_item, parent );
79         }
80         else if( p_item->min.i != 0 || p_item->max.i != 0 )
81         {
82             p_control = new RangedIntConfigControl( p_this, p_item, parent );
83         }
84         else
85         {
86             p_control = new IntegerConfigControl( p_this, p_item, parent );
87         }
88         break;
89
90     case CONFIG_ITEM_KEY:
91         p_control = new KeyConfigControl( p_this, p_item, parent );
92         break;
93
94     case CONFIG_ITEM_FLOAT:
95         p_control = new FloatConfigControl( p_this, p_item, parent );
96         break;
97
98     case CONFIG_ITEM_BOOL:
99         p_control = new BoolConfigControl( p_this, p_item, parent );
100         break;
101
102     case CONFIG_SECTION:
103         p_control = new SectionConfigControl( p_this, p_item, parent );
104         break;
105
106     default:
107         break;
108     }
109
110     return p_control;
111 }
112
113 /*****************************************************************************
114  * ConfigControl implementation
115  *****************************************************************************/
116 ConfigControl::ConfigControl( vlc_object_t *_p_this,
117                               module_config_t *p_item, wxWindow *parent )
118   : wxPanel( parent ), p_this( _p_this ),
119     pf_update_callback( NULL ), p_update_data( NULL ),
120     name( wxU(p_item->psz_name) ), i_type( p_item->i_type ),
121     b_advanced( p_item->b_advanced )
122
123 {
124     sizer = new wxBoxSizer( wxHORIZONTAL );
125 }
126
127 ConfigControl::~ConfigControl()
128 {
129 }
130
131 wxSizer *ConfigControl::Sizer()
132 {
133     return sizer;
134 }
135
136 wxString ConfigControl::GetName()
137 {
138     return name;
139 }
140
141 int ConfigControl::GetType()
142 {
143     return i_type;
144 }
145
146 vlc_bool_t ConfigControl::IsAdvanced()
147 {
148     return b_advanced;
149 }
150
151 void ConfigControl::SetUpdateCallback( void (*p_callback)( void * ),
152                                              void *p_data )
153 {
154     pf_update_callback = p_callback;
155     p_update_data = p_data;
156 }
157
158 void ConfigControl::OnUpdate( wxCommandEvent& WXUNUSED(event) )
159 {
160     if( pf_update_callback )
161     {
162         pf_update_callback( p_update_data );
163     }
164 }
165
166 void ConfigControl::OnUpdateScroll( wxScrollEvent& WXUNUSED(event) )
167 {
168     wxCommandEvent cevent;
169     OnUpdate(cevent);
170 }
171
172
173 /*****************************************************************************
174  * KeyConfigControl implementation
175  *****************************************************************************/
176 wxString *KeyConfigControl::m_keysList = NULL;
177
178 KeyConfigControl::KeyConfigControl( vlc_object_t *p_this,
179                                     module_config_t *p_item, wxWindow *parent )
180   : ConfigControl( p_this, p_item, parent )
181 {
182     // Number of keys descriptions
183     unsigned int i_keys = sizeof(vlc_keys)/sizeof(key_descriptor_t);
184
185     // Init the keys decriptions array
186     if( m_keysList == NULL )
187     {
188         m_keysList = new wxString[i_keys];
189         for( unsigned int i = 0; i < i_keys; i++ )
190         {
191             m_keysList[i] = wxU(vlc_keys[i].psz_key_string);
192         }
193     }
194
195     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
196     alt = new wxCheckBox( this, -1, wxU(_("Alt")) );
197     alt->SetValue( p_item->value.i & KEY_MODIFIER_ALT );
198     ctrl = new wxCheckBox( this, -1, wxU(_("Ctrl")) );
199     ctrl->SetValue( p_item->value.i & KEY_MODIFIER_CTRL );
200     shift = new wxCheckBox( this, -1, wxU(_("Shift")) );
201     shift->SetValue( p_item->value.i & KEY_MODIFIER_SHIFT );
202     combo = new wxComboBox( this, -1, wxT(""), wxDefaultPosition,
203                             wxDefaultSize, i_keys, m_keysList,
204                             wxCB_READONLY );
205     for( unsigned int i = 0; i < i_keys; i++ )
206     {
207         combo->SetClientData( i, (void*)vlc_keys[i].i_key_code );
208         if( (unsigned int)vlc_keys[i].i_key_code ==
209             ( ((unsigned int)p_item->value.i) & ~KEY_MODIFIER ) )
210         {
211             combo->SetSelection( i );
212             combo->SetValue( wxU(_(vlc_keys[i].psz_key_string)) );
213         }
214     }
215
216     sizer->Add( label, 2, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
217     sizer->Add( alt,   1, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
218     sizer->Add( ctrl,  1, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
219     sizer->Add( shift, 1, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
220     sizer->Add( combo, 2, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
221     sizer->Layout();
222     this->SetSizerAndFit( sizer );
223 }
224
225 KeyConfigControl::~KeyConfigControl()
226 {
227     if( m_keysList )
228     {
229         delete[] m_keysList;
230         m_keysList = NULL;
231     }
232 }
233
234 int KeyConfigControl::GetIntValue()
235 {
236     int result = 0;
237     if( alt->IsChecked() )
238     {
239         result |= KEY_MODIFIER_ALT;
240     }
241     if( ctrl->IsChecked() )
242     {
243         result |= KEY_MODIFIER_CTRL;
244     }
245     if( shift->IsChecked() )
246     {
247         result |= KEY_MODIFIER_SHIFT;
248     }
249     int selected = combo->GetSelection();
250     if( selected != -1 )
251     {
252         result |= (int)combo->GetClientData( selected );
253     }
254     return result;
255 }
256
257 /*****************************************************************************
258  * ModuleConfigControl implementation
259  *****************************************************************************/
260 ModuleConfigControl::ModuleConfigControl( vlc_object_t *p_this,
261                                           module_config_t *p_item,
262                                           wxWindow *parent )
263   : ConfigControl( p_this, p_item, parent )
264 {
265     vlc_list_t *p_list;
266     module_t *p_parser;
267
268     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
269     combo = new wxComboBox( this, -1, wxL2U(p_item->value.psz),
270                             wxDefaultPosition, wxDefaultSize,
271                             0, NULL, wxCB_READONLY | wxCB_SORT );
272
273     /* build a list of available modules */
274     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
275     combo->Append( wxU(_("Default")), (void *)NULL );
276     combo->SetSelection( 0 );
277     for( int i_index = 0; i_index < p_list->i_count; i_index++ )
278     {
279         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
280
281         if( module_IsCapable( p_parser, p_item->psz_type ) )
282         {
283             combo->Append( wxU(module_GetLongName(p_parser)),
284                            (char *)module_GetObjName(p_parser) );
285             if( p_item->value.psz && !strcmp(p_item->value.psz,
286                                              module_GetObjName(p_parser)) )
287                 combo->SetValue( wxU(module_GetLongName(p_parser)) );
288         }
289     }
290     vlc_list_release( p_list );
291
292     combo->SetToolTip( wxU(p_item->psz_longtext) );
293     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
294     sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
295     sizer->Layout();
296     this->SetSizerAndFit( sizer );
297 }
298
299 ModuleCatConfigControl::~ModuleCatConfigControl()
300 {
301     ;
302 }
303
304 wxString ModuleCatConfigControl::GetPszValue()
305 {
306     return wxU( (char *)combo->GetClientData( combo->GetSelection() ));
307 }
308
309 /*****************************************************************************
310  * ModuleCatConfigControl implementation
311  *****************************************************************************/
312 ModuleCatConfigControl::ModuleCatConfigControl( vlc_object_t *p_this,
313                                                 module_config_t *p_item,
314                                                 wxWindow *parent )
315   : ConfigControl( p_this, p_item, parent )
316 {
317     vlc_list_t *p_list;
318     module_t *p_parser;
319
320     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
321     combo = new wxComboBox( this, -1, wxL2U(p_item->value.psz),
322                             wxDefaultPosition, wxDefaultSize,
323                             0, NULL, wxCB_READONLY | wxCB_SORT );
324
325     combo->Append( wxU(_("Default")), (void *)NULL );
326     combo->SetSelection( 0 );
327
328     /* build a list of available modules */
329     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
330     for(  int i_index = 0; i_index < p_list->i_count; i_index++ )
331     {
332         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
333
334         if( !strcmp( module_GetObjName(p_parser), "main" ) )
335               continue;
336
337         unsigned int i_confsize;
338         module_config_t *p_config, *p_start, *p_end;
339         p_start = module_GetConfig( p_parser, &i_confsize );
340         p_end = p_start + i_confsize;
341
342         for( p_config = p_start; p_config < p_end; p_config++ )
343         {
344             /* Hack: required subcategory is stored in min.i */
345             if( p_config->i_type == CONFIG_SUBCATEGORY &&
346                 p_config->value.i == p_item->min.i )
347             {
348                 combo->Append( wxU(module_GetLongName(p_parser)),
349                                (char *)module_GetObjName(p_parser) );
350                 if( p_item->value.psz &&
351                     !strcmp(p_item->value.psz, module_GetObjName(p_parser)) )
352                     combo->SetValue( wxU(module_GetLongName(p_parser)) );
353             }
354         }
355
356         module_PutConfig( p_start );
357     }
358     vlc_list_release( p_list );
359
360     combo->SetToolTip( wxU(p_item->psz_longtext) );
361     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
362     sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
363     sizer->Layout();
364     this->SetSizerAndFit( sizer );
365 }
366
367 ModuleConfigControl::~ModuleConfigControl()
368 {
369     ;
370 }
371
372 wxString ModuleConfigControl::GetPszValue()
373 {
374     return wxU( (char *)combo->GetClientData( combo->GetSelection() ));
375 }
376
377
378 /*****************************************************************************
379  * ModuleListCatonfigControl implementation
380  *****************************************************************************/
381 BEGIN_EVENT_TABLE(ModuleListCatConfigControl, wxPanel)
382     EVT_CHECKBOX( wxID_HIGHEST , ModuleListCatConfigControl::OnUpdate )
383 END_EVENT_TABLE()
384
385
386 ModuleListCatConfigControl::ModuleListCatConfigControl( vlc_object_t *p_this,
387                                                      module_config_t *p_item,
388                                                      wxWindow *parent )
389   : ConfigControl( p_this, p_item, parent )
390 {
391     vlc_list_t *p_list;
392     module_t *p_parser;
393
394     delete sizer;
395     sizer = new wxBoxSizer( wxVERTICAL );
396     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
397     sizer->Add( label );
398
399     text = new wxTextCtrl( this, -1, wxU(p_item->value.psz),
400                            wxDefaultPosition,wxSize( 300, 20 ) );
401
402
403     /* build a list of available modules */
404     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
405     for(  int i_index = 0; i_index < p_list->i_count; i_index++ )
406     {
407         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
408
409         if( !strcmp( module_GetObjName(p_parser), "main" ) )
410               continue;
411
412         unsigned int i_confsize;
413         module_config_t *p_config, *p_start, *p_end;
414
415         p_start = module_GetConfig( p_parser, &i_confsize );
416         p_end = p_start + i_confsize;
417
418         for( p_config = p_start; p_config < p_end; p_config++ )
419         {
420             /* Hack: required subcategory is stored in min.i */
421             if( p_config->i_type == CONFIG_SUBCATEGORY &&
422                 p_config->value.i == p_item->min.i )
423             {
424                 moduleCheckBox *mc = new moduleCheckBox;
425                 mc->checkbox =
426                     new wxCheckBox( this, wxID_HIGHEST,
427                                     wxU(module_GetLongName(p_parser)) );
428
429                 mc->psz_module = strdup( module_GetObjName(p_parser) );
430                 pp_checkboxes.push_back( mc );
431
432                 if( p_item->value.psz &&
433                     strstr( p_item->value.psz, mc->psz_module ) )
434                 {
435                     mc->checkbox->SetValue( true );
436                 }
437                 sizer->Add( mc->checkbox );
438             }
439         }
440
441         module_PutConfig( p_start );
442     }
443     vlc_list_release( p_list );
444
445     text->SetToolTip( wxU(p_item->psz_longtext) );
446     sizer->Add(text, 0, wxEXPAND|wxALL, 5 );
447
448     sizer->Add (new wxStaticText( this, -1, wxU( vlc_wraptext( _("Select "
449         "the desired modules. For more advanced control, the "
450         "resulting \"chain\" can be modified.") , 72 ) ) ) );
451
452     sizer->Layout();
453     this->SetSizerAndFit( sizer );
454 }
455
456 ModuleListCatConfigControl::~ModuleListCatConfigControl()
457 {
458     ;
459 }
460
461 wxString ModuleListCatConfigControl::GetPszValue()
462 {
463     return text->GetValue() ;
464 }
465
466 void  ModuleListCatConfigControl::OnUpdate( wxCommandEvent &event )
467 {
468     bool b_waschecked = false;
469     wxString newtext =  text->GetValue();
470
471     for( unsigned int i = 0 ; i< pp_checkboxes.size() ; i++ )
472     {
473         b_waschecked = newtext.Find( wxT(":")+wxU(pp_checkboxes[i]->psz_module)+wxT(":")) != -1 || newtext.BeforeFirst( ':' ) == wxString(wxU(pp_checkboxes[i]->psz_module)) || newtext.AfterLast( ':' ) == wxString(wxU(pp_checkboxes[i]->psz_module));
474         /* For some reasons, ^^ doesn't compile :( */
475         if( (pp_checkboxes[i]->checkbox->IsChecked() && ! b_waschecked )||
476             (! pp_checkboxes[i]->checkbox->IsChecked() && b_waschecked) )
477         {
478             if( b_waschecked )
479             {
480                 /* Maybe not the clest solution */
481                 if( ! newtext.Replace(wxString(wxT(":"))
482                                       +wxU(pp_checkboxes[i]->psz_module)+wxT(":"),
483                                       wxT(":")))
484                 {
485                     if( newtext.BeforeFirst( ':' ) == wxString(wxU(pp_checkboxes[i]->psz_module)) )
486                     {
487                         newtext = newtext.AfterFirst( ':' );
488                     }
489                     else if( newtext.AfterLast( ':' ) == wxString(wxU(pp_checkboxes[i]->psz_module)) )
490                     {
491                         newtext = newtext.BeforeLast( ':' );
492                     }
493                     else if( newtext == wxString(wxU(pp_checkboxes[i]->psz_module)) )
494                     {
495                         newtext = wxT("");
496                     }
497                     else
498                     {
499                         newtext.Replace(wxU(pp_checkboxes[i]->psz_module),wxU(""));
500                     }
501                 }
502             }
503             else
504             {
505                 if( newtext.Len() == 0 )
506                 {
507                     newtext = wxU(pp_checkboxes[i]->psz_module);
508                 }
509                 else
510                 {
511                     newtext += wxU( ":" );
512                     newtext += wxU(pp_checkboxes[i]->psz_module);
513                 }
514             }
515         }
516     }
517     text->SetValue( newtext );
518 }
519
520 /*****************************************************************************
521  * StringConfigControl implementation
522  *****************************************************************************/
523 StringConfigControl::StringConfigControl( vlc_object_t *p_this,
524                                           module_config_t *p_item,
525                                           wxWindow *parent )
526   : ConfigControl( p_this, p_item, parent )
527 {
528     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
529     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
530     textctrl = new wxTextCtrl( this, -1,
531                                wxL2U(p_item->value.psz),
532                                wxDefaultPosition,
533                                wxDefaultSize,
534                                wxTE_PROCESS_ENTER);
535     textctrl->SetToolTip( wxU(p_item->psz_longtext) );
536     sizer->Add( textctrl, 1, wxALL, 5 );
537     sizer->Layout();
538     this->SetSizerAndFit( sizer );
539 }
540
541 StringConfigControl::~StringConfigControl()
542 {
543     ;
544 }
545
546 wxString StringConfigControl::GetPszValue()
547 {
548     return textctrl->GetValue();
549 }
550
551 BEGIN_EVENT_TABLE(StringConfigControl, wxPanel)
552     /* Text events */
553     EVT_TEXT(-1, StringConfigControl::OnUpdate)
554 END_EVENT_TABLE()
555
556 /*****************************************************************************
557  * StringListConfigControl implementation
558  *****************************************************************************/
559 StringListConfigControl::StringListConfigControl( vlc_object_t *p_this,
560                                                   module_config_t *p_item,
561                                                   wxWindow *parent )
562   : ConfigControl( p_this, p_item, parent )
563 {
564     psz_default_value = (char *)p_item->value.psz;
565     if( psz_default_value ) psz_default_value = strdup( psz_default_value );
566
567     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
568     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
569     combo = new wxComboBox( this, -1, wxT(""),
570                             wxDefaultPosition, wxDefaultSize,
571                             0, NULL, wxCB_READONLY );
572     UpdateCombo( p_item );
573
574     combo->SetToolTip( wxU(p_item->psz_longtext) );
575     sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
576
577     for( int i = 0; i < p_item->i_action; i++ )
578     {
579         wxButton *button =
580             new wxButton( this, wxID_HIGHEST+i,
581                           wxU(_(p_item->ppsz_action_text[i])) );
582         sizer->Add( button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
583     }
584
585     sizer->Layout();
586     this->SetSizerAndFit( sizer );
587 }
588
589 StringListConfigControl::~StringListConfigControl()
590 {
591     if( psz_default_value ) free( psz_default_value );
592 }
593
594 void StringListConfigControl::UpdateCombo( module_config_t *p_item )
595 {
596     vlc_bool_t b_found = VLC_FALSE;
597     int i_index;
598
599     /* build a list of available options */
600     for( i_index = 0; i_index < p_item->i_list; i_index++ )
601     {
602         combo->Append( ( p_item->ppsz_list_text &&
603                          p_item->ppsz_list_text[i_index] ) ?
604                        wxU(p_item->ppsz_list_text[i_index]) :
605                        wxL2U(p_item->ppsz_list[i_index]) );
606         combo->SetClientData( i_index, (void *)p_item->ppsz_list[i_index] );
607         if( ( p_item->value.psz &&
608               !strcmp( p_item->value.psz, p_item->ppsz_list[i_index] ) ) ||
609              ( !p_item->value.psz && !*p_item->ppsz_list[i_index] ) )
610         {
611             combo->SetSelection( i_index );
612             combo->SetValue( ( p_item->ppsz_list_text &&
613                                p_item->ppsz_list_text[i_index] ) ?
614                              wxU(p_item->ppsz_list_text[i_index]) :
615                              wxL2U(p_item->ppsz_list[i_index]) );
616             b_found = VLC_TRUE;
617         }
618     }
619
620     if( p_item->value.psz && !b_found )
621     {
622         /* Add custom entry to list */
623         combo->Append( wxL2U(p_item->value.psz) );
624         combo->SetClientData( i_index, (void *)psz_default_value );
625         combo->SetSelection( i_index );
626         combo->SetValue( wxL2U(p_item->value.psz) );
627     }
628 }
629
630 BEGIN_EVENT_TABLE(StringListConfigControl, wxPanel)
631     /* Button events */
632     EVT_BUTTON(-1, StringListConfigControl::OnAction)
633
634     /* Text events */
635     EVT_TEXT(-1, StringListConfigControl::OnUpdate)
636 END_EVENT_TABLE()
637
638 void StringListConfigControl::OnAction( wxCommandEvent& event )
639 {
640     int i_action = event.GetId() - wxID_HIGHEST;
641
642     module_config_t *p_item = config_FindConfig( p_this, GetName().mb_str(wxConvUTF8) );
643     if( !p_item ) return;
644
645     if( i_action < 0 || i_action >= p_item->i_action ) return;
646
647     vlc_value_t val;
648     wxString value = GetPszValue();
649     *((const char **)&val.psz_string) = value.mb_str(wxConvUTF8);
650     p_item->ppf_action[i_action]( p_this, GetName().mb_str(wxConvUTF8), val, val, 0 );
651
652     if( p_item->b_dirty )
653     {
654         combo->Clear();
655         UpdateCombo( p_item );
656         p_item->b_dirty = VLC_FALSE;
657     }
658 }
659
660 wxString StringListConfigControl::GetPszValue()
661 {
662     int selected = combo->GetSelection();
663     if( selected != -1 )
664     {
665         return wxL2U((char *)combo->GetClientData( selected ));
666     }
667     return wxString();
668 }
669
670 /*****************************************************************************
671  * FileConfigControl implementation
672  *****************************************************************************/
673 FileConfigControl::FileConfigControl( vlc_object_t *p_this,
674                                       module_config_t *p_item,
675                                       wxWindow *parent )
676   : ConfigControl( p_this, p_item, parent )
677 {
678     directory = p_item->i_type == CONFIG_ITEM_DIRECTORY;
679     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
680     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
681     textctrl = new wxTextCtrl( this, -1,
682                                wxL2U(p_item->value.psz),
683                                wxDefaultPosition,
684                                wxDefaultSize,
685                                wxTE_PROCESS_ENTER);
686     textctrl->SetToolTip( wxU(p_item->psz_longtext) );
687     sizer->Add( textctrl, 1, wxALL, 5 );
688     browse = new wxButton( this, wxID_HIGHEST, wxU(_("Browse...")) );
689     sizer->Add( browse, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
690     sizer->Layout();
691     this->SetSizerAndFit( sizer );
692 }
693
694 BEGIN_EVENT_TABLE(FileConfigControl, wxPanel)
695     /* Button events */
696     EVT_BUTTON(wxID_HIGHEST, FileConfigControl::OnBrowse)
697 END_EVENT_TABLE()
698
699 void FileConfigControl::OnBrowse( wxCommandEvent& event )
700 {
701     if( directory )
702     {
703         wxDirDialog dialog( this, wxU(_("Choose directory")) );
704
705         if( dialog.ShowModal() == wxID_OK )
706         {
707             textctrl->SetValue( dialog.GetPath() );
708         }
709     }
710     else
711     {
712         wxFileDialog dialog( this, wxU(_("Choose file")),
713                              wxT(""), wxT(""), wxT("*.*"),
714 #if defined( __WXMSW__ )
715                              wxOPEN
716 #else
717                              wxOPEN
718 #endif
719                            );
720         if( dialog.ShowModal() == wxID_OK )
721         {
722             textctrl->SetValue( dialog.GetPath() );
723         }
724     }
725 }
726
727 FileConfigControl::~FileConfigControl()
728 {
729     ;
730 }
731
732 wxString FileConfigControl::GetPszValue()
733 {
734     return textctrl->GetValue();
735 }
736
737 /*****************************************************************************
738  * IntegerConfigControl implementation
739  *****************************************************************************/
740 BEGIN_EVENT_TABLE(IntegerConfigControl, wxPanel)
741     EVT_TEXT(-1, IntegerConfigControl::OnUpdate)
742     EVT_COMMAND_SCROLL(-1, IntegerConfigControl::OnUpdateScroll)
743 END_EVENT_TABLE()
744
745 IntegerConfigControl::IntegerConfigControl( vlc_object_t *p_this,
746                                             module_config_t *p_item,
747                                             wxWindow *parent )
748   : ConfigControl( p_this, p_item, parent )
749 {
750     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
751     spin = new wxSpinCtrl( this, -1,
752                            wxString::Format(wxT("%d"),
753                                             p_item->value.i),
754                            wxDefaultPosition, wxDefaultSize,
755                            wxSP_ARROW_KEYS,
756                            -100000000, 100000000, p_item->value.i);
757     spin->SetToolTip( wxU(p_item->psz_longtext) );
758     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
759     sizer->Add( spin, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
760     sizer->Layout();
761     this->SetSizerAndFit( sizer );
762     i_value = p_item->value.i;
763 }
764
765 IntegerConfigControl::~IntegerConfigControl()
766 {
767     ;
768 }
769
770 int IntegerConfigControl::GetIntValue()
771 {
772     /* We avoid using GetValue because of a recursion bug with wxSpinCtrl with
773      * wxGTK. */
774     return spin->GetValue();
775 }
776
777 void IntegerConfigControl::OnUpdate( wxCommandEvent &event )
778 {
779     ConfigControl::OnUpdate( event );
780 }
781 void IntegerConfigControl::OnUpdateScroll( wxScrollEvent &event )
782 {
783     wxCommandEvent cevent;
784     cevent.SetInt(event.GetPosition());
785     OnUpdate(cevent);
786 }
787
788 /*****************************************************************************
789  * IntegerListConfigControl implementation
790  *****************************************************************************/
791 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *p_this,
792                                                     module_config_t *p_item,
793                                                     wxWindow *parent )
794   : ConfigControl( p_this, p_item, parent )
795 {
796     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
797     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
798     combo = new wxComboBox( this, -1, wxT(""),
799                             wxDefaultPosition, wxDefaultSize,
800                             0, NULL, wxCB_READONLY );
801
802     UpdateCombo( p_item );
803
804     combo->SetToolTip( wxU(p_item->psz_longtext) );
805     sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
806
807     sizer->Layout();
808     this->SetSizerAndFit( sizer );
809 }
810
811 IntegerListConfigControl::~IntegerListConfigControl()
812 {
813 }
814
815 void IntegerListConfigControl::UpdateCombo( module_config_t *p_item )
816 {
817     /* build a list of available options */
818     for( int i_index = 0; i_index < p_item->i_list; i_index++ )
819     {
820         if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
821         {
822             combo->Append( wxU(p_item->ppsz_list_text[i_index]) );
823         }
824         else
825         {
826             combo->Append( wxString::Format(wxT("%i"),
827                                             p_item->pi_list[i_index]) );
828         }
829         combo->SetClientData( i_index, (void *)p_item->pi_list[i_index] );
830         if( p_item->value.i == p_item->pi_list[i_index] )
831         {
832             combo->SetSelection( i_index );
833             if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
834             {
835                 combo->SetValue( wxU(p_item->ppsz_list_text[i_index]) );
836             }
837             else
838             {
839                 combo->SetValue( wxString::Format(wxT("%i"),
840                                                   p_item->pi_list[i_index]) );
841             }
842         }
843     }
844 }
845
846 BEGIN_EVENT_TABLE(IntegerListConfigControl, wxPanel)
847     /* Button events */
848     EVT_BUTTON(-1, IntegerListConfigControl::OnAction)
849
850     /* Update events */
851     EVT_TEXT(-1, IntegerListConfigControl::OnUpdate)
852 END_EVENT_TABLE()
853
854 void IntegerListConfigControl::OnAction( wxCommandEvent& event )
855 {
856     int i_action = event.GetId() - wxID_HIGHEST;
857
858     module_config_t *p_item;
859     p_item = config_FindConfig( p_this, GetName().mb_str(wxConvUTF8) );
860     if( !p_item ) return;
861
862     if( i_action < 0 || i_action >= p_item->i_action ) return;
863
864     vlc_value_t val;
865     val.i_int = GetIntValue();
866     p_item->ppf_action[i_action]( p_this, GetName().mb_str(wxConvUTF8), val, val, 0 );
867
868     if( p_item->b_dirty )
869     {
870         combo->Clear();
871         UpdateCombo( p_item );
872         p_item->b_dirty = VLC_FALSE;
873     }
874 }
875
876 int IntegerListConfigControl::GetIntValue()
877 {
878     int selected = combo->GetSelection();
879     if( selected != -1 )
880     {
881         return (int)combo->GetClientData( selected );
882     }
883     return -1;
884 }
885
886 /*****************************************************************************
887  * RangedIntConfigControl implementation
888  *****************************************************************************/
889 BEGIN_EVENT_TABLE(RangedIntConfigControl, wxPanel)
890     EVT_COMMAND_SCROLL(-1, RangedIntConfigControl::OnUpdateScroll)
891 END_EVENT_TABLE()
892
893 RangedIntConfigControl::RangedIntConfigControl( vlc_object_t *p_this,
894                                                 module_config_t *p_item,
895                                                 wxWindow *parent )
896   : ConfigControl( p_this, p_item, parent )
897 {
898     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
899     slider = new wxSlider( this, -1, p_item->value.i, p_item->min.i,
900                            p_item->max.i, wxDefaultPosition, wxDefaultSize,
901                            wxSL_LABELS | wxSL_HORIZONTAL );
902     slider->SetToolTip( wxU(p_item->psz_longtext) );
903     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
904     sizer->Add( slider, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
905     sizer->Layout();
906     this->SetSizerAndFit( sizer );
907 }
908
909 RangedIntConfigControl::~RangedIntConfigControl()
910 {
911     ;
912 }
913
914 int RangedIntConfigControl::GetIntValue()
915 {
916     return slider->GetValue();
917 }
918
919
920 /*****************************************************************************
921  * FloatConfigControl implementation
922  *****************************************************************************/
923 BEGIN_EVENT_TABLE(FloatConfigControl, wxPanel)
924     EVT_TEXT(-1, FloatConfigControl::OnUpdate)
925 END_EVENT_TABLE()
926
927 FloatConfigControl::FloatConfigControl( vlc_object_t *p_this,
928                                         module_config_t *p_item,
929                                         wxWindow *parent )
930   : ConfigControl( p_this, p_item, parent )
931 {
932     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
933     textctrl = new wxTextCtrl( this, -1,
934                                wxString::Format(wxT("%f"),
935                                                 p_item->value.f),
936                                wxDefaultPosition, wxDefaultSize,
937                                wxTE_PROCESS_ENTER );
938     textctrl->SetToolTip( wxU(p_item->psz_longtext) );
939     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
940     sizer->Add( textctrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
941     sizer->Layout();
942     this->SetSizerAndFit( sizer );
943 }
944
945 FloatConfigControl::~FloatConfigControl()
946 {
947     ;
948 }
949
950 float FloatConfigControl::GetFloatValue()
951 {
952     float f_value;
953     if( (wxSscanf(textctrl->GetValue(), wxT("%f"), &f_value) == 1) )
954         return f_value;
955     else return 0.0;
956 }
957
958 /*****************************************************************************
959  * BoolConfigControl implementation
960  *****************************************************************************/
961 BEGIN_EVENT_TABLE(BoolConfigControl, wxPanel)
962     EVT_CHECKBOX(-1, BoolConfigControl::OnUpdate)
963 END_EVENT_TABLE()
964
965 BoolConfigControl::BoolConfigControl( vlc_object_t *p_this,
966                                       module_config_t *p_item,
967                                       wxWindow *parent )
968   : ConfigControl( p_this, p_item, parent )
969 {
970     checkbox = new wxCheckBox( this, -1, wxU(p_item->psz_text) );
971     if( p_item->value.i ) checkbox->SetValue(TRUE);
972     checkbox->SetToolTip( wxU(p_item->psz_longtext) );
973     sizer->Add( checkbox, 0, wxALL, 5 );
974     sizer->Layout();
975     this->SetSizerAndFit( sizer );
976 }
977
978 BoolConfigControl::~BoolConfigControl()
979 {
980     ;
981 }
982
983 int BoolConfigControl::GetIntValue()
984 {
985     if( checkbox->IsChecked() ) return 1;
986     else return 0;
987 }
988
989 /*****************************************************************************
990  * SectionConfigControl implementation
991  *****************************************************************************/
992 SectionConfigControl::SectionConfigControl( vlc_object_t *p_this,
993                                             module_config_t *p_item,
994                                             wxWindow *parent )
995   : ConfigControl( p_this, p_item, parent )
996 {
997     delete sizer;
998     sizer = new wxBoxSizer( wxVERTICAL );
999     sizer->Add( new wxStaticText( this, -1, wxU( p_item->psz_text ) ) );
1000     sizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND, 5 );
1001     sizer->Layout();
1002     this->SetSizerAndFit( sizer );
1003 }
1004
1005 SectionConfigControl::~SectionConfigControl()
1006 {
1007     ;
1008 }