22a69081a94527d51eecd85b6f5d55482b340255
[vlc.git] / 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 )
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( !strcmp( p_parser->psz_capability, p_item->psz_type ) )
282         {
283             combo->Append( wxU(p_parser->psz_longname),
284                            (char *)p_parser->psz_object_name );
285             if( p_item->value.psz && !strcmp(p_item->value.psz,
286                                              p_parser->psz_object_name) )
287                 combo->SetValue( wxU(p_parser->psz_longname) );
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( p_parser->psz_object_name, "main" ) )
335               continue;
336
337         module_config_t *p_config = p_parser->p_config;
338         module_config_t *p_end = p_config + p_parser->confsize;
339
340         if( p_config ) do
341         {
342             /* Hack: required subcategory is stored in min.i */
343             if( p_config->i_type == CONFIG_SUBCATEGORY &&
344                 p_config->value.i == p_item->min.i )
345             {
346                 combo->Append( wxU(p_parser->psz_longname),
347                                (char *)p_parser->psz_object_name );
348                 if( p_item->value.psz && !strcmp(p_item->value.psz,
349                                         p_parser->psz_object_name) )
350                 combo->SetValue( wxU(p_parser->psz_longname) );
351             }
352         } while( p_config < p_end && p_config++ );
353     }
354     vlc_list_release( p_list );
355
356     combo->SetToolTip( wxU(p_item->psz_longtext) );
357     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
358     sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
359     sizer->Layout();
360     this->SetSizerAndFit( sizer );
361 }
362
363 ModuleConfigControl::~ModuleConfigControl()
364 {
365     ;
366 }
367
368 wxString ModuleConfigControl::GetPszValue()
369 {
370     return wxU( (char *)combo->GetClientData( combo->GetSelection() ));
371 }
372
373
374 /*****************************************************************************
375  * ModuleListCatonfigControl implementation
376  *****************************************************************************/
377 BEGIN_EVENT_TABLE(ModuleListCatConfigControl, wxPanel)
378     EVT_CHECKBOX( wxID_HIGHEST , ModuleListCatConfigControl::OnUpdate )
379 END_EVENT_TABLE()
380
381
382 ModuleListCatConfigControl::ModuleListCatConfigControl( vlc_object_t *p_this,
383                                                      module_config_t *p_item,
384                                                      wxWindow *parent )
385   : ConfigControl( p_this, p_item, parent )
386 {
387     vlc_list_t *p_list;
388     module_t *p_parser;
389
390     delete sizer;
391     sizer = new wxBoxSizer( wxVERTICAL );
392     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
393     sizer->Add( label );
394
395     text = new wxTextCtrl( this, -1, wxU(p_item->value.psz),
396                            wxDefaultPosition,wxSize( 300, 20 ) );
397
398
399     /* build a list of available modules */
400     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
401     for(  int i_index = 0; i_index < p_list->i_count; i_index++ )
402     {
403         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
404
405         if( !strcmp( p_parser->psz_object_name, "main" ) )
406               continue;
407
408         module_config_t *p_config, *p_end;
409         if( p_parser->b_submodule )
410             p_config = ((module_t*)p_parser->p_parent)->p_config;
411         else
412             p_config = p_parser->p_config;
413             p_end = p_config + p_parser->confsize;
414
415         if( p_config ) do
416         {
417             /* Hack: required subcategory is stored in min.i */
418             if( p_config->i_type == CONFIG_SUBCATEGORY &&
419                 p_config->value.i == p_item->min.i )
420             {
421                 moduleCheckBox *mc = new moduleCheckBox;
422                 mc->checkbox = new wxCheckBox( this, wxID_HIGHEST,
423                                                wxU(p_parser->psz_longname));
424                 /* hack to handle submodules properly */
425                 int i = -1;
426                 while( p_parser->pp_shortcuts[++i] != NULL );
427                 i--;
428                 mc->psz_module = strdup( i>=0?p_parser->pp_shortcuts[i]
429                                          :p_parser->psz_object_name );
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         } while( p_config < p_end && p_config++ );
440     }
441     vlc_list_release( p_list );
442
443     text->SetToolTip( wxU(p_item->psz_longtext) );
444     sizer->Add(text, 0, wxEXPAND|wxALL, 5 );
445
446     sizer->Add (new wxStaticText( this, -1, wxU( vlc_wraptext( _("Select "
447         "the desired modules. For more advanced control, the "
448         "resulting \"chain\" can be modified.") , 72 ) ) ) );
449
450     sizer->Layout();
451     this->SetSizerAndFit( sizer );
452 }
453
454 ModuleListCatConfigControl::~ModuleListCatConfigControl()
455 {
456     ;
457 }
458
459 wxString ModuleListCatConfigControl::GetPszValue()
460 {
461     return text->GetValue() ;
462 }
463
464 void  ModuleListCatConfigControl::OnUpdate( wxCommandEvent &event )
465 {
466     bool b_waschecked = false;
467     wxString newtext =  text->GetValue();
468
469     for( unsigned int i = 0 ; i< pp_checkboxes.size() ; i++ )
470     {
471         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));
472         /* For some reasons, ^^ doesn't compile :( */
473         if( (pp_checkboxes[i]->checkbox->IsChecked() && ! b_waschecked )||
474             (! pp_checkboxes[i]->checkbox->IsChecked() && b_waschecked) )
475         {
476             if( b_waschecked )
477             {
478                 /* Maybe not the clest solution */
479                 if( ! newtext.Replace(wxString(wxT(":"))
480                                       +wxU(pp_checkboxes[i]->psz_module)+wxT(":"),
481                                       wxT(":")))
482                 {
483                     if( newtext.BeforeFirst( ':' ) == wxString(wxU(pp_checkboxes[i]->psz_module)) )
484                     {
485                         newtext = newtext.AfterFirst( ':' );
486                     }
487                     else if( newtext.AfterLast( ':' ) == wxString(wxU(pp_checkboxes[i]->psz_module)) )
488                     {
489                         newtext = newtext.BeforeLast( ':' );
490                     }
491                     else if( newtext == wxString(wxU(pp_checkboxes[i]->psz_module)) )
492                     {
493                         newtext = wxT("");
494                     }
495                     else
496                     {
497                         newtext.Replace(wxU(pp_checkboxes[i]->psz_module),wxU(""));
498                     }
499                 }
500             }
501             else
502             {
503                 if( newtext.Len() == 0 )
504                 {
505                     newtext = wxU(pp_checkboxes[i]->psz_module);
506                 }
507                 else
508                 {
509                     newtext += wxU( ":" );
510                     newtext += wxU(pp_checkboxes[i]->psz_module);
511                 }
512             }
513         }
514     }
515     text->SetValue( newtext );
516 }
517
518 /*****************************************************************************
519  * StringConfigControl implementation
520  *****************************************************************************/
521 StringConfigControl::StringConfigControl( vlc_object_t *p_this,
522                                           module_config_t *p_item,
523                                           wxWindow *parent )
524   : ConfigControl( p_this, p_item, parent )
525 {
526     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
527     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
528     textctrl = new wxTextCtrl( this, -1,
529                                wxL2U(p_item->value.psz),
530                                wxDefaultPosition,
531                                wxDefaultSize,
532                                wxTE_PROCESS_ENTER);
533     textctrl->SetToolTip( wxU(p_item->psz_longtext) );
534     sizer->Add( textctrl, 1, wxALL, 5 );
535     sizer->Layout();
536     this->SetSizerAndFit( sizer );
537 }
538
539 StringConfigControl::~StringConfigControl()
540 {
541     ;
542 }
543
544 wxString StringConfigControl::GetPszValue()
545 {
546     return textctrl->GetValue();
547 }
548
549 BEGIN_EVENT_TABLE(StringConfigControl, wxPanel)
550     /* Text events */
551     EVT_TEXT(-1, StringConfigControl::OnUpdate)
552 END_EVENT_TABLE()
553
554 /*****************************************************************************
555  * StringListConfigControl implementation
556  *****************************************************************************/
557 StringListConfigControl::StringListConfigControl( vlc_object_t *p_this,
558                                                   module_config_t *p_item,
559                                                   wxWindow *parent )
560   : ConfigControl( p_this, p_item, parent )
561 {
562     psz_default_value = (char *)p_item->value.psz;
563     if( psz_default_value ) psz_default_value = strdup( psz_default_value );
564
565     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
566     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
567     combo = new wxComboBox( this, -1, wxT(""),
568                             wxDefaultPosition, wxDefaultSize,
569                             0, NULL, wxCB_READONLY );
570     UpdateCombo( p_item );
571
572     combo->SetToolTip( wxU(p_item->psz_longtext) );
573     sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
574
575     for( int i = 0; i < p_item->i_action; i++ )
576     {
577         wxButton *button =
578             new wxButton( this, wxID_HIGHEST+i,
579                           wxU(_(p_item->ppsz_action_text[i])) );
580         sizer->Add( button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
581     }
582
583     sizer->Layout();
584     this->SetSizerAndFit( sizer );
585 }
586
587 StringListConfigControl::~StringListConfigControl()
588 {
589     if( psz_default_value ) free( psz_default_value );
590 }
591
592 void StringListConfigControl::UpdateCombo( module_config_t *p_item )
593 {
594     vlc_bool_t b_found = VLC_FALSE;
595     int i_index;
596
597     /* build a list of available options */
598     for( i_index = 0; i_index < p_item->i_list; i_index++ )
599     {
600         combo->Append( ( p_item->ppsz_list_text &&
601                          p_item->ppsz_list_text[i_index] ) ?
602                        wxU(p_item->ppsz_list_text[i_index]) :
603                        wxL2U(p_item->ppsz_list[i_index]) );
604         combo->SetClientData( i_index, (void *)p_item->ppsz_list[i_index] );
605         if( ( p_item->value.psz &&
606               !strcmp( p_item->value.psz, p_item->ppsz_list[i_index] ) ) ||
607              ( !p_item->value.psz && !*p_item->ppsz_list[i_index] ) )
608         {
609             combo->SetSelection( i_index );
610             combo->SetValue( ( p_item->ppsz_list_text &&
611                                p_item->ppsz_list_text[i_index] ) ?
612                              wxU(p_item->ppsz_list_text[i_index]) :
613                              wxL2U(p_item->ppsz_list[i_index]) );
614             b_found = VLC_TRUE;
615         }
616     }
617
618     if( p_item->value.psz && !b_found )
619     {
620         /* Add custom entry to list */
621         combo->Append( wxL2U(p_item->value.psz) );
622         combo->SetClientData( i_index, (void *)psz_default_value );
623         combo->SetSelection( i_index );
624         combo->SetValue( wxL2U(p_item->value.psz) );
625     }
626 }
627
628 BEGIN_EVENT_TABLE(StringListConfigControl, wxPanel)
629     /* Button events */
630     EVT_BUTTON(-1, StringListConfigControl::OnAction)
631
632     /* Text events */
633     EVT_TEXT(-1, StringListConfigControl::OnUpdate)
634 END_EVENT_TABLE()
635
636 void StringListConfigControl::OnAction( wxCommandEvent& event )
637 {
638     int i_action = event.GetId() - wxID_HIGHEST;
639
640     module_config_t *p_item = config_FindConfig( p_this, GetName().mb_str(wxConvUTF8) );
641     if( !p_item ) return;
642
643     if( i_action < 0 || i_action >= p_item->i_action ) return;
644
645     vlc_value_t val;
646     wxString value = GetPszValue();
647     *((const char **)&val.psz_string) = value.mb_str(wxConvUTF8);
648     p_item->ppf_action[i_action]( p_this, GetName().mb_str(wxConvUTF8), val, val, 0 );
649
650     if( p_item->b_dirty )
651     {
652         combo->Clear();
653         UpdateCombo( p_item );
654         p_item->b_dirty = VLC_FALSE;
655     }
656 }
657
658 wxString StringListConfigControl::GetPszValue()
659 {
660     int selected = combo->GetSelection();
661     if( selected != -1 )
662     {
663         return wxL2U((char *)combo->GetClientData( selected ));
664     }
665     return wxString();
666 }
667
668 /*****************************************************************************
669  * FileConfigControl implementation
670  *****************************************************************************/
671 FileConfigControl::FileConfigControl( vlc_object_t *p_this,
672                                       module_config_t *p_item,
673                                       wxWindow *parent )
674   : ConfigControl( p_this, p_item, parent )
675 {
676     directory = p_item->i_type == CONFIG_ITEM_DIRECTORY;
677     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
678     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
679     textctrl = new wxTextCtrl( this, -1,
680                                wxL2U(p_item->value.psz),
681                                wxDefaultPosition,
682                                wxDefaultSize,
683                                wxTE_PROCESS_ENTER);
684     textctrl->SetToolTip( wxU(p_item->psz_longtext) );
685     sizer->Add( textctrl, 1, wxALL, 5 );
686     browse = new wxButton( this, wxID_HIGHEST, wxU(_("Browse...")) );
687     sizer->Add( browse, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
688     sizer->Layout();
689     this->SetSizerAndFit( sizer );
690 }
691
692 BEGIN_EVENT_TABLE(FileConfigControl, wxPanel)
693     /* Button events */
694     EVT_BUTTON(wxID_HIGHEST, FileConfigControl::OnBrowse)
695 END_EVENT_TABLE()
696
697 void FileConfigControl::OnBrowse( wxCommandEvent& event )
698 {
699     if( directory )
700     {
701         wxDirDialog dialog( this, wxU(_("Choose directory")) );
702
703         if( dialog.ShowModal() == wxID_OK )
704         {
705             textctrl->SetValue( dialog.GetPath() );
706         }
707     }
708     else
709     {
710         wxFileDialog dialog( this, wxU(_("Choose file")),
711                              wxT(""), wxT(""), wxT("*.*"),
712 #if defined( __WXMSW__ )
713                              wxOPEN
714 #else
715                              wxOPEN
716 #endif
717                            );
718         if( dialog.ShowModal() == wxID_OK )
719         {
720             textctrl->SetValue( dialog.GetPath() );
721         }
722     }
723 }
724
725 FileConfigControl::~FileConfigControl()
726 {
727     ;
728 }
729
730 wxString FileConfigControl::GetPszValue()
731 {
732     return textctrl->GetValue();
733 }
734
735 /*****************************************************************************
736  * IntegerConfigControl implementation
737  *****************************************************************************/
738 BEGIN_EVENT_TABLE(IntegerConfigControl, wxPanel)
739     EVT_TEXT(-1, IntegerConfigControl::OnUpdate)
740     EVT_COMMAND_SCROLL(-1, IntegerConfigControl::OnUpdateScroll)
741 END_EVENT_TABLE()
742
743 IntegerConfigControl::IntegerConfigControl( vlc_object_t *p_this,
744                                             module_config_t *p_item,
745                                             wxWindow *parent )
746   : ConfigControl( p_this, p_item, parent )
747 {
748     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
749     spin = new wxSpinCtrl( this, -1,
750                            wxString::Format(wxT("%d"),
751                                             p_item->value.i),
752                            wxDefaultPosition, wxDefaultSize,
753                            wxSP_ARROW_KEYS,
754                            -100000000, 100000000, p_item->value.i);
755     spin->SetToolTip( wxU(p_item->psz_longtext) );
756     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
757     sizer->Add( spin, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
758     sizer->Layout();
759     this->SetSizerAndFit( sizer );
760     i_value = p_item->value.i;
761 }
762
763 IntegerConfigControl::~IntegerConfigControl()
764 {
765     ;
766 }
767
768 int IntegerConfigControl::GetIntValue()
769 {
770     /* We avoid using GetValue because of a recursion bug with wxSpinCtrl with
771      * wxGTK. */
772     return spin->GetValue();
773 }
774
775 void IntegerConfigControl::OnUpdate( wxCommandEvent &event )
776 {
777     ConfigControl::OnUpdate( event );
778 }
779 void IntegerConfigControl::OnUpdateScroll( wxScrollEvent &event )
780 {
781     wxCommandEvent cevent;
782     cevent.SetInt(event.GetPosition());
783     OnUpdate(cevent);
784 }
785
786 /*****************************************************************************
787  * IntegerListConfigControl implementation
788  *****************************************************************************/
789 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *p_this,
790                                                     module_config_t *p_item,
791                                                     wxWindow *parent )
792   : ConfigControl( p_this, p_item, parent )
793 {
794     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
795     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
796     combo = new wxComboBox( this, -1, wxT(""),
797                             wxDefaultPosition, wxDefaultSize,
798                             0, NULL, wxCB_READONLY );
799
800     UpdateCombo( p_item );
801
802     combo->SetToolTip( wxU(p_item->psz_longtext) );
803     sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
804
805     sizer->Layout();
806     this->SetSizerAndFit( sizer );
807 }
808
809 IntegerListConfigControl::~IntegerListConfigControl()
810 {
811 }
812
813 void IntegerListConfigControl::UpdateCombo( module_config_t *p_item )
814 {
815     /* build a list of available options */
816     for( int i_index = 0; i_index < p_item->i_list; i_index++ )
817     {
818         if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
819         {
820             combo->Append( wxU(p_item->ppsz_list_text[i_index]) );
821         }
822         else
823         {
824             combo->Append( wxString::Format(wxT("%i"),
825                                             p_item->pi_list[i_index]) );
826         }
827         combo->SetClientData( i_index, (void *)p_item->pi_list[i_index] );
828         if( p_item->value.i == p_item->pi_list[i_index] )
829         {
830             combo->SetSelection( i_index );
831             if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
832             {
833                 combo->SetValue( wxU(p_item->ppsz_list_text[i_index]) );
834             }
835             else
836             {
837                 combo->SetValue( wxString::Format(wxT("%i"),
838                                                   p_item->pi_list[i_index]) );
839             }
840         }
841     }
842 }
843
844 BEGIN_EVENT_TABLE(IntegerListConfigControl, wxPanel)
845     /* Button events */
846     EVT_BUTTON(-1, IntegerListConfigControl::OnAction)
847
848     /* Update events */
849     EVT_TEXT(-1, IntegerListConfigControl::OnUpdate)
850 END_EVENT_TABLE()
851
852 void IntegerListConfigControl::OnAction( wxCommandEvent& event )
853 {
854     int i_action = event.GetId() - wxID_HIGHEST;
855
856     module_config_t *p_item;
857     p_item = config_FindConfig( p_this, GetName().mb_str(wxConvUTF8) );
858     if( !p_item ) return;
859
860     if( i_action < 0 || i_action >= p_item->i_action ) return;
861
862     vlc_value_t val;
863     val.i_int = GetIntValue();
864     p_item->ppf_action[i_action]( p_this, GetName().mb_str(wxConvUTF8), val, val, 0 );
865
866     if( p_item->b_dirty )
867     {
868         combo->Clear();
869         UpdateCombo( p_item );
870         p_item->b_dirty = VLC_FALSE;
871     }
872 }
873
874 int IntegerListConfigControl::GetIntValue()
875 {
876     int selected = combo->GetSelection();
877     if( selected != -1 )
878     {
879         return (int)combo->GetClientData( selected );
880     }
881     return -1;
882 }
883
884 /*****************************************************************************
885  * RangedIntConfigControl implementation
886  *****************************************************************************/
887 BEGIN_EVENT_TABLE(RangedIntConfigControl, wxPanel)
888     EVT_COMMAND_SCROLL(-1, RangedIntConfigControl::OnUpdateScroll)
889 END_EVENT_TABLE()
890
891 RangedIntConfigControl::RangedIntConfigControl( vlc_object_t *p_this,
892                                                 module_config_t *p_item,
893                                                 wxWindow *parent )
894   : ConfigControl( p_this, p_item, parent )
895 {
896     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
897     slider = new wxSlider( this, -1, p_item->value.i, p_item->min.i,
898                            p_item->max.i, wxDefaultPosition, wxDefaultSize,
899                            wxSL_LABELS | wxSL_HORIZONTAL );
900     slider->SetToolTip( wxU(p_item->psz_longtext) );
901     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
902     sizer->Add( slider, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
903     sizer->Layout();
904     this->SetSizerAndFit( sizer );
905 }
906
907 RangedIntConfigControl::~RangedIntConfigControl()
908 {
909     ;
910 }
911
912 int RangedIntConfigControl::GetIntValue()
913 {
914     return slider->GetValue();
915 }
916
917
918 /*****************************************************************************
919  * FloatConfigControl implementation
920  *****************************************************************************/
921 BEGIN_EVENT_TABLE(FloatConfigControl, wxPanel)
922     EVT_TEXT(-1, FloatConfigControl::OnUpdate)
923 END_EVENT_TABLE()
924
925 FloatConfigControl::FloatConfigControl( vlc_object_t *p_this,
926                                         module_config_t *p_item,
927                                         wxWindow *parent )
928   : ConfigControl( p_this, p_item, parent )
929 {
930     label = new wxStaticText(this, -1, wxU(p_item->psz_text));
931     textctrl = new wxTextCtrl( this, -1,
932                                wxString::Format(wxT("%f"),
933                                                 p_item->value.f),
934                                wxDefaultPosition, wxDefaultSize,
935                                wxTE_PROCESS_ENTER );
936     textctrl->SetToolTip( wxU(p_item->psz_longtext) );
937     sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
938     sizer->Add( textctrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
939     sizer->Layout();
940     this->SetSizerAndFit( sizer );
941 }
942
943 FloatConfigControl::~FloatConfigControl()
944 {
945     ;
946 }
947
948 float FloatConfigControl::GetFloatValue()
949 {
950     float f_value;
951     if( (wxSscanf(textctrl->GetValue(), wxT("%f"), &f_value) == 1) )
952         return f_value;
953     else return 0.0;
954 }
955
956 /*****************************************************************************
957  * BoolConfigControl implementation
958  *****************************************************************************/
959 BEGIN_EVENT_TABLE(BoolConfigControl, wxPanel)
960     EVT_CHECKBOX(-1, BoolConfigControl::OnUpdate)
961 END_EVENT_TABLE()
962
963 BoolConfigControl::BoolConfigControl( vlc_object_t *p_this,
964                                       module_config_t *p_item,
965                                       wxWindow *parent )
966   : ConfigControl( p_this, p_item, parent )
967 {
968     checkbox = new wxCheckBox( this, -1, wxU(p_item->psz_text) );
969     if( p_item->value.i ) checkbox->SetValue(TRUE);
970     checkbox->SetToolTip( wxU(p_item->psz_longtext) );
971     sizer->Add( checkbox, 0, wxALL, 5 );
972     sizer->Layout();
973     this->SetSizerAndFit( sizer );
974 }
975
976 BoolConfigControl::~BoolConfigControl()
977 {
978     ;
979 }
980
981 int BoolConfigControl::GetIntValue()
982 {
983     if( checkbox->IsChecked() ) return 1;
984     else return 0;
985 }
986
987 /*****************************************************************************
988  * SectionConfigControl implementation
989  *****************************************************************************/
990 SectionConfigControl::SectionConfigControl( vlc_object_t *p_this,
991                                             module_config_t *p_item,
992                                             wxWindow *parent )
993   : ConfigControl( p_this, p_item, parent )
994 {
995     delete sizer;
996     sizer = new wxBoxSizer( wxVERTICAL );
997     sizer->Add( new wxStaticText( this, -1, wxU( p_item->psz_text ) ) );
998     sizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND, 5 );
999     sizer->Layout();
1000     this->SetSizerAndFit( sizer );
1001 }
1002
1003 SectionConfigControl::~SectionConfigControl()
1004 {
1005     ;
1006 }