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