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