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