* src/libvlc.c, src/libvlc.h: added a config option to disable the translation of...
[vlc.git] / modules / gui / wxwindows / preferences.cpp
1 /*****************************************************************************
2  * preferences.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2001 VideoLAN
5  * $Id: preferences.cpp,v 1.1 2003/03/26 00:56:22 gbazin Exp $
6  *
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <errno.h>                                                 /* ENOMEM */
29 #include <string.h>                                            /* strerror() */
30 #include <stdio.h>
31
32 #include <vlc/vlc.h>
33
34 #ifdef WIN32                                                 /* mingw32 hack */
35 #undef Yield
36 #undef CreateDialog
37 #endif
38
39 /* Let vlc take care of the i18n stuff */
40 #define WXINTL_NO_GETTEXT_MACRO
41
42 #include <wx/wxprec.h>
43 #include <wx/wx.h>
44 #include <wx/notebook.h>
45 #include <wx/textctrl.h>
46 #include <wx/combobox.h>
47 #include <wx/spinctrl.h>
48 #include <wx/statline.h>
49 #include <wx/treectrl.h>
50
51 #include <vlc/intf.h>
52
53 #include "wxwindows.h"
54
55 #ifndef wxRB_SINGLE
56 #   define wxRB_SINGLE 0
57 #endif
58
59 /*****************************************************************************
60  * Classes declarations.
61  *****************************************************************************/
62 class PrefsTreeCtrl : public wxTreeCtrl
63 {
64 public:
65
66     PrefsTreeCtrl() { }
67     PrefsTreeCtrl( wxWindow *parent, intf_thread_t *_p_intf,
68                    PrefsDialog *p_prefs_dialog, wxBoxSizer *_p_sizer );
69     virtual ~PrefsTreeCtrl();
70
71 private:
72     /* Event handlers (these functions should _not_ be virtual) */
73     void OnSelectTreeItem( wxTreeEvent& event );
74
75     DECLARE_EVENT_TABLE()
76
77     intf_thread_t *p_intf;
78     PrefsDialog *p_prefs_dialog;
79     wxBoxSizer *p_sizer;
80     wxWindow *p_parent;
81 };
82
83 class PrefsPanel : public wxScrolledWindow
84 {
85 public:
86
87     PrefsPanel() { }
88     PrefsPanel( wxWindow *parent, intf_thread_t *_p_intf,
89                 module_t *p_module, char * );
90     virtual ~PrefsPanel() {}
91
92 private:
93     void OnFileBrowse( wxCommandEvent& WXUNUSED(event) );
94     void OnDirectoryBrowse( wxCommandEvent& WXUNUSED(event) );
95     DECLARE_EVENT_TABLE()
96
97     intf_thread_t *p_intf;
98 };
99
100 class ConfigData : public wxTreeItemData
101 {
102 public:
103
104     ConfigData() { panel == NULL; }
105     virtual ~ConfigData() { if( panel ) delete panel; }
106
107     wxWindow *panel;
108     wxBoxSizer *sizer;
109 };
110
111 /*****************************************************************************
112  * Event Table.
113  *****************************************************************************/
114
115 /* IDs for the controls and the menu commands */
116 enum
117 {
118     Notebook_Event = wxID_HIGHEST,
119     MRL_Event,
120
121 };
122
123 BEGIN_EVENT_TABLE(PrefsDialog, wxDialog)
124     /* Button events */
125     EVT_BUTTON(wxID_OK, PrefsDialog::OnOk)
126     EVT_BUTTON(wxID_CANCEL, PrefsDialog::OnCancel)
127
128 END_EVENT_TABLE()
129
130 // menu and control ids
131 enum
132 {
133     PrefsTree_Ctrl = wxID_HIGHEST
134 };
135
136 BEGIN_EVENT_TABLE(PrefsTreeCtrl, wxTreeCtrl)
137     EVT_TREE_SEL_CHANGED(PrefsTree_Ctrl, PrefsTreeCtrl::OnSelectTreeItem)
138 END_EVENT_TABLE()
139
140 enum
141 {
142     FileBrowse_Event = wxID_HIGHEST,
143     DirectoryBrowse_Event,
144
145 };
146
147 BEGIN_EVENT_TABLE(PrefsPanel, wxScrolledWindow)
148     /* Button events */
149     EVT_BUTTON(FileBrowse_Event, PrefsPanel::OnFileBrowse)
150     EVT_BUTTON(DirectoryBrowse_Event, PrefsPanel::OnDirectoryBrowse)
151
152 END_EVENT_TABLE()
153
154 /*****************************************************************************
155  * Constructor.
156  *****************************************************************************/
157 PrefsDialog::PrefsDialog( intf_thread_t *_p_intf, Interface *_p_main_interface)
158   :  wxDialog( _p_main_interface, -1, _("Preferences"), wxDefaultPosition,
159                wxSize(600,400), wxDEFAULT_FRAME_STYLE )
160 {
161     /* Initializations */
162     p_intf = _p_intf;
163     p_main_interface = _p_main_interface;
164
165     /* Create a panel to put everything in */
166     wxPanel *panel = new wxPanel( this, -1 );
167     panel->SetAutoLayout( TRUE );
168
169     /* Create the preferences tree control */
170     wxBoxSizer *controls_sizer = new wxBoxSizer( wxHORIZONTAL );
171     PrefsTreeCtrl *prefs_tree =
172         new PrefsTreeCtrl( panel, p_intf, this, controls_sizer );
173
174     /* Separation */
175     wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
176
177     /* Create the buttons */
178     wxButton *ok_button = new wxButton( panel, wxID_OK, _("OK") );
179     ok_button->SetDefault();
180     wxButton *cancel_button = new wxButton( panel, wxID_CANCEL, _("Cancel") );
181
182     /* Place everything in sizers */
183     wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
184     button_sizer->Add( ok_button, 0, wxALL, 5 );
185     button_sizer->Add( cancel_button, 0, wxALL, 5 );
186     button_sizer->Layout();
187
188     wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
189     wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
190     panel_sizer->Add( controls_sizer, 1, wxEXPAND | wxALL, 5 );
191     panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
192     panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALIGN_BOTTOM |
193                       wxALL, 5 );
194     panel_sizer->Layout();
195     panel->SetSizer( panel_sizer );
196     main_sizer->Add( panel, 1, wxEXPAND, 0 );
197     main_sizer->Layout();
198     SetSizer( main_sizer );
199 }
200
201 PrefsDialog::~PrefsDialog()
202 {
203 }
204
205 /*****************************************************************************
206  * Private methods.
207  *****************************************************************************/
208
209
210 /*****************************************************************************
211  * Events methods.
212  *****************************************************************************/
213 void PrefsDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
214 {
215     this->Hide();
216 }
217
218 void PrefsDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
219 {
220     this->Hide();
221 }
222
223 void PrefsTreeCtrl::OnSelectTreeItem( wxTreeEvent& event )
224 {
225     ConfigData *config_data;
226
227     config_data = (ConfigData *)GetItemData( event.GetOldItem() );
228     if( config_data && config_data->panel )
229     {
230         config_data->panel->Hide();
231         p_sizer->Remove( config_data->panel );
232     }
233
234     config_data = (ConfigData *)GetItemData( event.GetItem() );
235     if( config_data && config_data->panel )
236     {
237         config_data->panel->Show();
238         config_data->panel->FitInside();
239         p_sizer->Add( config_data->panel, 2, wxEXPAND | wxALL, 0 );
240         p_sizer->Layout();
241     }
242 }
243
244 void PrefsPanel::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
245 {
246     wxFileDialog dialog( this, _("Open file"), "", "", "*.*",
247                          wxOPEN );
248
249     if( dialog.ShowModal() == wxID_OK )
250     {
251 #if 0
252         file_combo->SetValue( dialog.GetPath() );      
253 #endif
254     }
255 }
256
257 void PrefsPanel::OnDirectoryBrowse( wxCommandEvent& WXUNUSED(event) )
258 {
259     wxFileDialog dialog( this, _("Open file"), "", "", "*.*",
260                          wxOPEN );
261
262     if( dialog.ShowModal() == wxID_OK )
263     {
264 #if 0
265         file_combo->SetValue( dialog.GetPath() );      
266 #endif
267     }
268 }
269
270 /*****************************************************************************
271  * PrefsTreeCtrl class definition.
272  *****************************************************************************/
273 PrefsTreeCtrl::PrefsTreeCtrl( wxWindow *_p_parent, intf_thread_t *_p_intf,
274                               PrefsDialog *_p_prefs_dialog,
275                               wxBoxSizer *_p_sizer )
276   : wxTreeCtrl( _p_parent, PrefsTree_Ctrl, wxDefaultPosition, wxDefaultSize,
277                 wxTR_NO_LINES | wxTR_FULL_ROW_HIGHLIGHT |
278                 wxTR_LINES_AT_ROOT | wxTR_HIDE_ROOT |
279                 wxTR_HAS_BUTTONS | wxTR_TWIST_BUTTONS | wxSUNKEN_BORDER )
280 {
281     vlc_list_t      *p_list;
282     module_t        *p_module;
283     module_config_t *p_item;
284     int i_index;
285
286     /* Initializations */
287     p_intf = _p_intf;
288     p_prefs_dialog = _p_prefs_dialog;
289     p_sizer = _p_sizer;
290     p_parent = _p_parent;
291
292     wxTreeItemId root_item = AddRoot( "" );
293
294     /* List the plugins */
295     p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
296     if( !p_list ) return;
297
298     /*
299      * Build a tree of the main options
300      */
301     for( i_index = 0; i_index < p_list->i_count; i_index++ )
302     {
303         p_module = (module_t *)p_list->p_values[i_index].p_object;
304         if( !strcmp( p_module->psz_object_name, "main" ) )
305             break;
306     }
307     if( i_index < p_list->i_count )
308     {
309         /* We found the main module */
310
311         /* Enumerate config options and add corresponding config boxes */
312         p_item = p_module->p_config;
313
314         if( p_item ) do
315         {
316             if( p_item->b_advanced && !config_GetInt( p_intf, "advanced" ))
317             {
318                 continue;
319             }
320             switch( p_item->i_type )
321             {
322             case CONFIG_HINT_CATEGORY:
323                 ConfigData *config_data = new ConfigData;
324                 config_data->panel =
325                     new PrefsPanel( p_parent, p_intf,
326                                     p_module, p_item->psz_text );
327                 config_data->panel->Hide();
328
329                 /* Add the category to the tree */
330                 AppendItem( root_item, p_item->psz_text, -1, -1, config_data );
331                 break;
332             }
333         }
334         while( p_item->i_type != CONFIG_HINT_END && p_item++ );
335
336         SortChildren( root_item );
337     }
338
339     /*
340      * Build a tree of all the plugins
341      */
342
343     wxTreeItemId plugins_item = AppendItem( root_item, _("Plugins") );
344
345     for( i_index = 0; i_index < p_list->i_count; i_index++ )
346     {
347         p_module = (module_t *)p_list->p_values[i_index].p_object;
348
349         /* Find the capabiltiy child item */
350         long cookie; size_t i_child_index;
351         wxTreeItemId capability_item = GetFirstChild( plugins_item, cookie);
352         for( i_child_index = 0;
353              i_child_index < GetChildrenCount( plugins_item, FALSE );
354              i_child_index++ )
355         {
356             if( !GetItemText(capability_item).Cmp(p_module->psz_capability) )
357             {
358                 break;
359             }
360             capability_item = GetNextChild( plugins_item, cookie );
361         }
362
363         if( i_child_index == GetChildrenCount( plugins_item, FALSE ) )
364         {
365             /* We didn't find it, add it */
366             capability_item = AppendItem( plugins_item,
367                                           p_module->psz_capability );
368         }
369
370         /* Add the plugin to the tree */
371         ConfigData *config_data = new ConfigData;
372         config_data->panel =
373             new PrefsPanel( p_parent, p_intf, p_module, NULL );
374         config_data->panel->Hide();
375         AppendItem( capability_item, p_module->psz_object_name, -1, -1,
376                     config_data );
377     }
378
379     /* Sort all this mess */
380     long cookie; size_t i_child_index;
381     SortChildren( plugins_item );
382     wxTreeItemId capability_item = GetFirstChild( plugins_item, cookie);
383     for( i_child_index = 0;
384          i_child_index < GetChildrenCount( plugins_item, FALSE );
385          i_child_index++ )
386     {
387         capability_item = GetNextChild( plugins_item, cookie );
388         SortChildren( capability_item );
389     }
390
391     /* Clean-up everything */
392     vlc_list_release( p_list );
393
394     p_sizer->Add( this, 1, wxEXPAND | wxALL, 0 );
395     p_sizer->Layout();
396
397 }
398
399 PrefsTreeCtrl::~PrefsTreeCtrl()
400 {
401 }
402
403 /*****************************************************************************
404  * PrefsPanel class definition.
405  *****************************************************************************/
406 PrefsPanel::PrefsPanel( wxWindow* parent, intf_thread_t *_p_intf,
407                         module_t *p_module, char *psz_section )
408   :  wxScrolledWindow( parent, -1, wxDefaultPosition, wxDefaultSize )
409 {
410     module_config_t *p_item;
411     wxStaticText *label;
412     wxComboBox *combo;
413     wxRadioButton *radio;
414     wxSpinCtrl *spin;
415     wxCheckBox *checkbox;
416     wxTextCtrl *textctrl;
417     wxButton *button;
418     wxStaticLine *static_line;
419     wxBoxSizer *horizontal_sizer;
420
421     /* Initializations */
422     p_intf = _p_intf;
423     SetAutoLayout( TRUE );
424     SetScrollRate( 5, 5 );
425
426     wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
427
428     /* Enumerate config options and add corresponding config boxes */
429     p_item = p_module->p_config;
430
431     /* Find the category if it has been specified */
432     if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY )
433     {
434         while( !p_item->i_type == CONFIG_HINT_CATEGORY ||
435                strcmp( psz_section, p_item->psz_text ) )
436         {
437             if( p_item->i_type == CONFIG_HINT_END )
438                 break;
439             p_item++;
440         }
441     }
442
443     /* Add a head title to the panel */
444     wxStaticBox *static_box = new wxStaticBox( this, -1, "" );
445     wxStaticBoxSizer *box_sizer = new wxStaticBoxSizer( static_box,
446                                                         wxHORIZONTAL );
447     label = new wxStaticText( this, -1,
448                               psz_section ? p_item->psz_text :
449                               p_module->psz_longname );
450
451     box_sizer->Add( label, 1, wxALL, 5 );
452     sizer->Add( box_sizer, 0, wxEXPAND | wxALL, 5 );
453
454     if( p_item ) do
455     {
456         if( p_item->b_advanced && !config_GetInt( p_intf, "advanced" ) )
457         {
458             continue;
459         }
460
461         /* If a category has been specified, check we finished the job */
462         if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY &&
463             strcmp( psz_section, p_item->psz_text ) )
464             break;
465
466         switch( p_item->i_type )
467         {
468         case CONFIG_HINT_CATEGORY:
469 #if 0
470             label = new wxStaticText(this, -1, p_item->psz_text);
471             sizer->Add( label, 0, wxALL, 5 );
472 #endif
473             break;
474
475         case CONFIG_ITEM_MODULE:
476             /* build a list of available modules */
477
478             label = new wxStaticText(this, -1, p_item->psz_text);
479             combo = new wxComboBox( this, -1, "", wxPoint(20,25),
480                                     wxSize(120, -1), 0, NULL );
481             combo->SetToolTip( p_item->psz_longtext );
482             horizontal_sizer = new wxBoxSizer( wxHORIZONTAL );
483             horizontal_sizer->Add( label, 0, wxALL, 5 );
484             horizontal_sizer->Add( combo, 0, wxALL, 5 );
485             sizer->Add( horizontal_sizer, 0, wxALL, 5 );
486             break;
487
488         case CONFIG_ITEM_STRING:
489         case CONFIG_ITEM_FILE:
490             label = new wxStaticText(this, -1, p_item->psz_text);
491             textctrl = new wxTextCtrl( this, -1, "",
492                                        wxDefaultPosition, wxDefaultSize,
493                                        wxTE_PROCESS_ENTER);
494 #if 0
495             combo = new wxComboBox( this, -1, "", wxPoint(20,25),
496                                     wxSize(120, -1), 0, NULL );
497 #endif
498             textctrl->SetToolTip( p_item->psz_longtext );
499             horizontal_sizer = new wxBoxSizer( wxHORIZONTAL );
500             horizontal_sizer->Add( label, 0, wxALL, 5 );
501             horizontal_sizer->Add( textctrl, 0, wxALL, 5 );
502             if( p_item->i_type == CONFIG_ITEM_FILE )
503             {
504                 button = new wxButton( this, -1, _("Browse...") );
505                 horizontal_sizer->Add( button, 0, wxALL, 5 );
506             }
507             sizer->Add( horizontal_sizer, 0, wxALL, 5 );
508             break;
509
510         case CONFIG_ITEM_INTEGER:
511             label = new wxStaticText(this, -1, p_item->psz_text);
512             spin = new wxSpinCtrl( this, -1, p_item->psz_text,
513                                    wxDefaultPosition, wxDefaultSize,
514                                    wxSP_ARROW_KEYS,
515                                    0, 16000, 8);
516             spin->SetToolTip( p_item->psz_longtext );
517             horizontal_sizer = new wxBoxSizer( wxHORIZONTAL );
518             horizontal_sizer->Add( label, 0, wxALL, 5 );
519             horizontal_sizer->Add( spin, 0, wxALL, 5 );
520             sizer->Add( horizontal_sizer, 0, wxALL, 5 );
521             break;
522
523         case CONFIG_ITEM_FLOAT:
524             label = new wxStaticText(this, -1, p_item->psz_text);
525             spin = new wxSpinCtrl( this, -1, p_item->psz_text,
526                                    wxDefaultPosition, wxDefaultSize,
527                                    wxSP_ARROW_KEYS,
528                                    0, 16000, 8);
529             spin->SetToolTip( p_item->psz_longtext );
530             horizontal_sizer = new wxBoxSizer( wxHORIZONTAL );
531             horizontal_sizer->Add( label, 0, wxALL, 5 );
532             horizontal_sizer->Add( spin, 0, wxALL, 5 );
533             sizer->Add( horizontal_sizer, 0, wxALL, 5 );
534             break;
535
536         case CONFIG_ITEM_BOOL:
537             checkbox = new wxCheckBox( this, -1, p_item->psz_text );
538             checkbox->SetToolTip( p_item->psz_longtext );
539             horizontal_sizer = new wxBoxSizer( wxHORIZONTAL );
540             horizontal_sizer->Add( checkbox, 0, wxALL, 5 );
541             sizer->Add( horizontal_sizer, 0, wxALL, 5 );
542             break;
543         }
544     }
545     while( p_item->i_type != CONFIG_HINT_END && p_item++ );
546
547
548     sizer->Layout();
549     SetSizer( sizer );
550 }