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