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