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 $
7 * Authors: Gildas Bazin <gbazin@netcourrier.com>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
28 #include <errno.h> /* ENOMEM */
29 #include <string.h> /* strerror() */
34 #ifdef WIN32 /* mingw32 hack */
39 /* Let vlc take care of the i18n stuff */
40 #define WXINTL_NO_GETTEXT_MACRO
42 #include <wx/wxprec.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>
53 #include "wxwindows.h"
56 # define wxRB_SINGLE 0
59 /*****************************************************************************
60 * Classes declarations.
61 *****************************************************************************/
62 class PrefsTreeCtrl : public wxTreeCtrl
67 PrefsTreeCtrl( wxWindow *parent, intf_thread_t *_p_intf,
68 PrefsDialog *p_prefs_dialog, wxBoxSizer *_p_sizer );
69 virtual ~PrefsTreeCtrl();
72 /* Event handlers (these functions should _not_ be virtual) */
73 void OnSelectTreeItem( wxTreeEvent& event );
77 intf_thread_t *p_intf;
78 PrefsDialog *p_prefs_dialog;
83 class PrefsPanel : public wxScrolledWindow
88 PrefsPanel( wxWindow *parent, intf_thread_t *_p_intf,
89 module_t *p_module, char * );
90 virtual ~PrefsPanel() {}
93 void OnFileBrowse( wxCommandEvent& WXUNUSED(event) );
94 void OnDirectoryBrowse( wxCommandEvent& WXUNUSED(event) );
97 intf_thread_t *p_intf;
100 class ConfigData : public wxTreeItemData
104 ConfigData() { panel == NULL; }
105 virtual ~ConfigData() { if( panel ) delete panel; }
111 /*****************************************************************************
113 *****************************************************************************/
115 /* IDs for the controls and the menu commands */
118 Notebook_Event = wxID_HIGHEST,
123 BEGIN_EVENT_TABLE(PrefsDialog, wxDialog)
125 EVT_BUTTON(wxID_OK, PrefsDialog::OnOk)
126 EVT_BUTTON(wxID_CANCEL, PrefsDialog::OnCancel)
130 // menu and control ids
133 PrefsTree_Ctrl = wxID_HIGHEST
136 BEGIN_EVENT_TABLE(PrefsTreeCtrl, wxTreeCtrl)
137 EVT_TREE_SEL_CHANGED(PrefsTree_Ctrl, PrefsTreeCtrl::OnSelectTreeItem)
142 FileBrowse_Event = wxID_HIGHEST,
143 DirectoryBrowse_Event,
147 BEGIN_EVENT_TABLE(PrefsPanel, wxScrolledWindow)
149 EVT_BUTTON(FileBrowse_Event, PrefsPanel::OnFileBrowse)
150 EVT_BUTTON(DirectoryBrowse_Event, PrefsPanel::OnDirectoryBrowse)
154 /*****************************************************************************
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 )
161 /* Initializations */
163 p_main_interface = _p_main_interface;
165 /* Create a panel to put everything in */
166 wxPanel *panel = new wxPanel( this, -1 );
167 panel->SetAutoLayout( TRUE );
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 );
175 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
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") );
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();
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 |
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 );
201 PrefsDialog::~PrefsDialog()
205 /*****************************************************************************
207 *****************************************************************************/
210 /*****************************************************************************
212 *****************************************************************************/
213 void PrefsDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
218 void PrefsDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
223 void PrefsTreeCtrl::OnSelectTreeItem( wxTreeEvent& event )
225 ConfigData *config_data;
227 config_data = (ConfigData *)GetItemData( event.GetOldItem() );
228 if( config_data && config_data->panel )
230 config_data->panel->Hide();
231 p_sizer->Remove( config_data->panel );
234 config_data = (ConfigData *)GetItemData( event.GetItem() );
235 if( config_data && config_data->panel )
237 config_data->panel->Show();
238 config_data->panel->FitInside();
239 p_sizer->Add( config_data->panel, 2, wxEXPAND | wxALL, 0 );
244 void PrefsPanel::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
246 wxFileDialog dialog( this, _("Open file"), "", "", "*.*",
249 if( dialog.ShowModal() == wxID_OK )
252 file_combo->SetValue( dialog.GetPath() );
257 void PrefsPanel::OnDirectoryBrowse( wxCommandEvent& WXUNUSED(event) )
259 wxFileDialog dialog( this, _("Open file"), "", "", "*.*",
262 if( dialog.ShowModal() == wxID_OK )
265 file_combo->SetValue( dialog.GetPath() );
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 )
283 module_config_t *p_item;
286 /* Initializations */
288 p_prefs_dialog = _p_prefs_dialog;
290 p_parent = _p_parent;
292 wxTreeItemId root_item = AddRoot( "" );
294 /* List the plugins */
295 p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
296 if( !p_list ) return;
299 * Build a tree of the main options
301 for( i_index = 0; i_index < p_list->i_count; i_index++ )
303 p_module = (module_t *)p_list->p_values[i_index].p_object;
304 if( !strcmp( p_module->psz_object_name, "main" ) )
307 if( i_index < p_list->i_count )
309 /* We found the main module */
311 /* Enumerate config options and add corresponding config boxes */
312 p_item = p_module->p_config;
316 if( p_item->b_advanced && !config_GetInt( p_intf, "advanced" ))
320 switch( p_item->i_type )
322 case CONFIG_HINT_CATEGORY:
323 ConfigData *config_data = new ConfigData;
325 new PrefsPanel( p_parent, p_intf,
326 p_module, p_item->psz_text );
327 config_data->panel->Hide();
329 /* Add the category to the tree */
330 AppendItem( root_item, p_item->psz_text, -1, -1, config_data );
334 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
336 SortChildren( root_item );
340 * Build a tree of all the plugins
343 wxTreeItemId plugins_item = AppendItem( root_item, _("Plugins") );
345 for( i_index = 0; i_index < p_list->i_count; i_index++ )
347 p_module = (module_t *)p_list->p_values[i_index].p_object;
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 );
356 if( !GetItemText(capability_item).Cmp(p_module->psz_capability) )
360 capability_item = GetNextChild( plugins_item, cookie );
363 if( i_child_index == GetChildrenCount( plugins_item, FALSE ) )
365 /* We didn't find it, add it */
366 capability_item = AppendItem( plugins_item,
367 p_module->psz_capability );
370 /* Add the plugin to the tree */
371 ConfigData *config_data = new ConfigData;
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,
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 );
387 capability_item = GetNextChild( plugins_item, cookie );
388 SortChildren( capability_item );
391 /* Clean-up everything */
392 vlc_list_release( p_list );
394 p_sizer->Add( this, 1, wxEXPAND | wxALL, 0 );
399 PrefsTreeCtrl::~PrefsTreeCtrl()
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 )
410 module_config_t *p_item;
413 wxRadioButton *radio;
415 wxCheckBox *checkbox;
416 wxTextCtrl *textctrl;
418 wxStaticLine *static_line;
419 wxBoxSizer *horizontal_sizer;
421 /* Initializations */
423 SetAutoLayout( TRUE );
424 SetScrollRate( 5, 5 );
426 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
428 /* Enumerate config options and add corresponding config boxes */
429 p_item = p_module->p_config;
431 /* Find the category if it has been specified */
432 if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY )
434 while( !p_item->i_type == CONFIG_HINT_CATEGORY ||
435 strcmp( psz_section, p_item->psz_text ) )
437 if( p_item->i_type == CONFIG_HINT_END )
443 /* Add a head title to the panel */
444 wxStaticBox *static_box = new wxStaticBox( this, -1, "" );
445 wxStaticBoxSizer *box_sizer = new wxStaticBoxSizer( static_box,
447 label = new wxStaticText( this, -1,
448 psz_section ? p_item->psz_text :
449 p_module->psz_longname );
451 box_sizer->Add( label, 1, wxALL, 5 );
452 sizer->Add( box_sizer, 0, wxEXPAND | wxALL, 5 );
456 if( p_item->b_advanced && !config_GetInt( p_intf, "advanced" ) )
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 ) )
466 switch( p_item->i_type )
468 case CONFIG_HINT_CATEGORY:
470 label = new wxStaticText(this, -1, p_item->psz_text);
471 sizer->Add( label, 0, wxALL, 5 );
475 case CONFIG_ITEM_MODULE:
476 /* build a list of available modules */
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 );
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,
495 combo = new wxComboBox( this, -1, "", wxPoint(20,25),
496 wxSize(120, -1), 0, NULL );
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 )
504 button = new wxButton( this, -1, _("Browse...") );
505 horizontal_sizer->Add( button, 0, wxALL, 5 );
507 sizer->Add( horizontal_sizer, 0, wxALL, 5 );
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,
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 );
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,
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 );
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 );
545 while( p_item->i_type != CONFIG_HINT_END && p_item++ );