1 /*****************************************************************************
\r
2 * preferences.cpp: the "Preferences" dialog box
\r
3 *****************************************************************************
\r
4 * Copyright (C) 2002 VideoLAN
\r
6 * Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
\r
8 * This program is free software; you can redistribute it and/or modify
\r
9 * it under the terms of the GNU General Public License as published by
\r
10 * the Free Software Foundation; either version 2 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU General Public License
\r
19 * along with this program; if not, write to the Free Software
\r
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
\r
21 *****************************************************************************/
\r
26 #include <stdlib.h> /* malloc(), free() */
\r
27 #include <string.h> /* strcmp */
\r
29 #include <vlc/vlc.h>
\r
30 #include <vlc/intf.h>
\r
32 #include "preferences.h"
\r
33 #include "win32_common.h"
\r
35 //---------------------------------------------------------------------------
\r
36 //#pragma package(smart_init)
\r
37 #pragma link "CSPIN"
\r
38 #pragma resource "*.dfm"
\r
40 extern intf_thread_t *p_intfGlobal;
\r
43 /****************************************************************************
\r
44 * Functions to help components creation
\r
45 ****************************************************************************/
\r
46 __fastcall TGroupBoxPref::TGroupBoxPref( TComponent* Owner,
\r
47 module_config_t *p_config_arg ) : TGroupBox( Owner )
\r
49 p_config = p_config_arg;
\r
50 Caption = p_config->psz_text;
\r
52 //---------------------------------------------------------------------------
\r
53 TCheckListBox * __fastcall TGroupBoxPref::CreateCheckListBox(
\r
54 TWinControl *Parent, int Left, int Width, int Top, int Height )
\r
56 TCheckListBox *CheckListBox = new TCheckListBox( Parent );
\r
57 CheckListBox->Parent = Parent;
\r
58 CheckListBox->Left = Left;
\r
59 CheckListBox->Width = Width;
\r
60 CheckListBox->Top = Top;
\r
61 CheckListBox->Height = Height;
\r
62 return CheckListBox;
\r
64 //---------------------------------------------------------------------------
\r
65 TButton * __fastcall TGroupBoxPref::CreateButton( TWinControl *Parent,
\r
66 int Left, int Width, int Top, int Height, AnsiString Caption )
\r
68 TButton *Button = new TButton( Parent );
\r
69 Button->Parent = Parent;
\r
70 Button->Left = Left;
\r
71 Button->Width = Width;
\r
73 Button->Height = Height;
\r
74 Button->Caption = Caption;
\r
77 //---------------------------------------------------------------------------
\r
78 TCheckBox * __fastcall TGroupBoxPref::CreateCheckBox( TWinControl *Parent,
\r
79 int Left, int Width, int Top, int Height, AnsiString Caption )
\r
81 TCheckBox *CheckBox = new TCheckBox( Parent );
\r
82 CheckBox->Parent = Parent;
\r
83 CheckBox->Left = Left;
\r
84 CheckBox->Width = Width;
\r
85 CheckBox->Top = Top;
\r
86 CheckBox->Height = Height;
\r
87 CheckBox->Caption = Caption;
\r
90 //---------------------------------------------------------------------------
\r
91 TLabel * __fastcall TGroupBoxPref::CreateLabel( TWinControl *Parent,
\r
92 int Left, int Width, int Top, int Height, AnsiString Caption,
\r
95 TLabel *Label = new TLabel( Parent );
\r
96 Label->Parent = Parent;
\r
97 Label->Caption = Caption;
\r
99 Label->Width = Width;
\r
101 Label->Height = Height;
\r
102 Label->WordWrap = WordWrap;
\r
105 //---------------------------------------------------------------------------
\r
106 TEdit * __fastcall TGroupBoxPref::CreateEdit( TWinControl *Parent,
\r
107 int Left, int Width, int Top, int Height, AnsiString Text )
\r
109 TEdit *Edit = new TEdit( Parent );
\r
110 Edit->Parent = Parent;
\r
112 Edit->Width = Width;
\r
114 Edit->Height = Height;
\r
118 //---------------------------------------------------------------------------
\r
119 TCSpinEdit * __fastcall TGroupBoxPref::CreateSpinEdit( TWinControl *Parent,
\r
120 int Left, int Width, int Top, int Height,
\r
121 long Min, long Max, long Value )
\r
123 TCSpinEdit *SpinEdit = new TCSpinEdit( Parent );
\r
124 SpinEdit->Parent = Parent;
\r
125 SpinEdit->Left = Left;
\r
126 SpinEdit->Width = Width;
\r
127 SpinEdit->Top = Top;
\r
128 SpinEdit->Height = Height;
\r
129 SpinEdit->MinValue = Min;
\r
130 SpinEdit->MaxValue = Max;
\r
131 SpinEdit->Value = Value;
\r
134 //---------------------------------------------------------------------------
\r
135 void __fastcall TGroupBoxPref::UpdateChanges()
\r
140 /****************************************************************************
\r
141 * GroupBox for module management
\r
142 ****************************************************************************/
\r
143 __fastcall TGroupBoxPlugin::TGroupBoxPlugin( TComponent* Owner,
\r
144 module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )
\r
146 /* init checklistbox */
\r
147 CheckListBox = CreateCheckListBox( this, 16, 164, 24, 160 );
\r
148 CheckListBox->OnClick = CheckListBoxClick;
\r
149 CheckListBox->OnClickCheck = CheckListBoxClickCheck;
\r
151 /* init description label */
\r
152 LabelDesc = CreateLabel( this, 230, 225, 50, 52,
\r
153 p_config->psz_longtext, true );
\r
155 /* init hint label */
\r
156 LabelHint = CreateLabel( this, 230, 225, 135, 13, "", false );
\r
158 /* init configure button */
\r
159 ButtonConfig = CreateButton( this, 16, 70, 192, 25, "Configure" );
\r
160 ButtonConfig->Enabled = false;
\r
161 ButtonConfig->OnClick = ButtonConfigClick;
\r
165 //---------------------------------------------------------------------------
\r
166 void __fastcall TGroupBoxPlugin::CheckListBoxClick( TObject *Sender )
\r
168 module_t **pp_parser;
\r
169 vlc_list_t *p_list;
\r
171 /* check that the click is valid (we are on an item, and the click
\r
172 * started on an item */
\r
173 if( CheckListBox->ItemIndex == -1 )
\r
176 AnsiString Name = CheckListBox->Items->Strings[CheckListBox->ItemIndex];
\r
180 /* look for module 'Name' */
\r
181 p_list = vlc_list_find( p_intfGlobal, VLC_OBJECT_MODULE, FIND_ANYWHERE );
\r
183 for( pp_parser = (module_t **)p_list->pp_objects ;
\r
187 if( strcmp( (*pp_parser)->psz_object_name, Name.c_str() ) == 0 )
\r
189 ModuleSelected = (*pp_parser);
\r
190 LabelHint->Caption = (*pp_parser)->psz_longname ?
\r
191 (*pp_parser)->psz_longname : "";
\r
192 ButtonConfig->Enabled =
\r
193 (*pp_parser)->i_config_items ? true : false;
\r
199 //---------------------------------------------------------------------------
\r
200 void __fastcall TGroupBoxPlugin::CheckListBoxClickCheck( TObject *Sender )
\r
202 /* one item maximum must be checked */
\r
203 if( CheckListBox->Checked[CheckListBox->ItemIndex] )
\r
205 for( int item = 0; item < CheckListBox->Items->Count; item++ )
\r
207 if( item != CheckListBox->ItemIndex )
\r
209 CheckListBox->Checked[item] = false;
\r
214 //---------------------------------------------------------------------------
\r
215 void __fastcall TGroupBoxPlugin::ButtonConfigClick( TObject *Sender )
\r
217 p_intfGlobal->p_sys->p_window->
\r
218 CreatePreferences( ModuleSelected->psz_object_name );
\r
220 //---------------------------------------------------------------------------
\r
221 void __fastcall TGroupBoxPlugin::UpdateChanges()
\r
223 AnsiString Name = "";
\r
225 /* find the selected plugin (if any) */
\r
226 for( int item = 0; item < CheckListBox->Items->Count; item++ )
\r
228 if( CheckListBox->Checked[item] )
\r
230 Name = CheckListBox->Items->Strings[item];
\r
235 /* XXX: Necessary, since c_str() returns only a temporary pointer... */
\r
236 free( p_config->psz_value );
\r
237 p_config->psz_value = (char *)malloc( Name.Length() + 1 );
\r
238 strcpy( p_config->psz_value, Name.c_str() );
\r
242 /****************************************************************************
\r
243 * GroupBox for string management
\r
244 ****************************************************************************/
\r
245 __fastcall TGroupBoxString::TGroupBoxString( TComponent* Owner,
\r
246 module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )
\r
248 /* init description label */
\r
249 LabelDesc = CreateLabel( this, 230, 225, 24, 26,
\r
250 p_config->psz_longtext, true );
\r
253 Edit = CreateEdit( this, 16, 164, 24, 21, "" );
\r
254 vlc_mutex_lock( p_config->p_lock );
\r
255 Edit->Text = p_config->psz_value ? p_config->psz_value : "";
\r
256 vlc_mutex_unlock( p_config->p_lock );
\r
258 /* vertical alignment */
\r
259 Height = LabelDesc->Height + 24;
\r
260 LabelDesc->Top = Top + ( Height - LabelDesc->Height ) / 2 + 4;
\r
261 Edit->Top = Top + ( Height - Edit->Height ) / 2 + 4;
\r
263 //---------------------------------------------------------------------------
\r
264 void __fastcall TGroupBoxString::UpdateChanges()
\r
266 /* XXX: Necessary, since c_str() returns only a temporary pointer... */
\r
267 free( p_config->psz_value );
\r
268 p_config->psz_value = (char *)malloc( Edit->Text.Length() + 1 );
\r
269 strcpy( p_config->psz_value, Edit->Text.c_str() );
\r
273 /****************************************************************************
\r
274 * GroupBox for integer management
\r
275 ****************************************************************************/
\r
276 __fastcall TGroupBoxInteger::TGroupBoxInteger( TComponent* Owner,
\r
277 module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )
\r
279 /* init description label */
\r
280 LabelDesc = CreateLabel( this, 230, 225, 19, 26,
\r
281 p_config->psz_longtext, true );
\r
283 /* init spinedit */
\r
284 SpinEdit = CreateSpinEdit( this, 16, 164, 24, 21,
\r
285 -1, 100000, p_config->i_value );
\r
287 /* vertical alignment */
\r
288 Height = LabelDesc->Height + 24;
\r
289 LabelDesc->Top = Top + ( Height - LabelDesc->Height ) / 2 + 4;
\r
290 SpinEdit->Top = Top + ( Height - SpinEdit->Height ) / 2 + 4;
\r
292 //---------------------------------------------------------------------------
\r
293 void __fastcall TGroupBoxInteger::UpdateChanges()
\r
295 /* Warning: we're casting from long to int */
\r
296 p_config->i_value = (int)SpinEdit->Value;
\r
300 /****************************************************************************
\r
301 * GroupBox for boolean management
\r
302 ****************************************************************************/
\r
303 __fastcall TGroupBoxBool::TGroupBoxBool( TComponent* Owner,
\r
304 module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )
\r
306 /* init description label */
\r
307 LabelDesc = CreateLabel( this, 230, 225, 19, 26,
\r
308 p_config->psz_longtext, true );
\r
310 /* init checkbox */
\r
311 CheckBox = CreateCheckBox( this, 16, 184, 28, 17, p_config->psz_text );
\r
312 CheckBox->Checked = p_config->i_value;
\r
314 /* vertical alignment */
\r
315 Height = LabelDesc->Height + 24;
\r
316 LabelDesc->Top = Top + ( Height - LabelDesc->Height ) / 2 + 4;
\r
317 CheckBox->Top = Top + ( Height - CheckBox->Height ) / 2 + 4;
\r
319 //---------------------------------------------------------------------------
\r
320 void __fastcall TGroupBoxBool::UpdateChanges()
\r
322 p_config->i_value = CheckBox->Checked ? 1 : 0;
\r
326 /****************************************************************************
\r
327 * Callbacks for the dialog
\r
328 ****************************************************************************/
\r
329 __fastcall TPreferencesDlg::TPreferencesDlg( TComponent* Owner )
\r
332 Icon = p_intfGlobal->p_sys->p_window->Icon;
\r
334 //---------------------------------------------------------------------------
\r
335 void __fastcall TPreferencesDlg::FormClose( TObject *Sender,
\r
336 TCloseAction &Action )
\r
342 /****************************************************************************
\r
343 * CreateConfigDialog: dynamically creates the configuration dialog
\r
344 * box from all the configuration data provided by the selected module.
\r
345 ****************************************************************************/
\r
346 #define ADD_PANEL \
\r
348 Panel = new TPanel( this ); \
\r
349 Panel->Parent = ScrollBox; \
\r
350 Panel->Caption = ""; \
\r
351 Panel->BevelOuter = bvNone; \
\r
352 Panel->Height = 12; \
\r
355 void __fastcall TPreferencesDlg::CreateConfigDialog( char *psz_module_name )
\r
357 module_t **pp_parser;
\r
358 vlc_list_t *p_list;
\r
360 module_config_t *p_item;
\r
361 int i_pages, i_ctrl;
\r
363 TTabSheet *TabSheet;
\r
364 TScrollBox *ScrollBox;
\r
366 TGroupBoxPlugin *GroupBoxPlugin;
\r
367 TGroupBoxString *GroupBoxString;
\r
368 TGroupBoxInteger *GroupBoxInteger;
\r
369 TGroupBoxBool *GroupBoxBool;
\r
371 /* Look for the selected module */
\r
372 p_list = vlc_list_find( p_intfGlobal, VLC_OBJECT_MODULE, FIND_ANYWHERE );
\r
374 for( pp_parser = (module_t **)p_list->pp_objects ;
\r
378 if( psz_module_name
\r
379 && !strcmp( psz_module_name, (*pp_parser)->psz_object_name ) )
\r
384 if( !(*pp_parser) )
\r
386 vlc_list_release( p_list );
\r
391 * We found it, now we can start building its configuration interface
\r
394 /* Enumerate config options and add corresponding config boxes */
\r
395 p_item = (*pp_parser)->p_config;
\r
398 switch( p_item->i_type )
\r
400 case CONFIG_HINT_CATEGORY:
\r
402 /* create a new tabsheet. */
\r
403 TabSheet = new TTabSheet( this );
\r
404 TabSheet->PageControl = PageControlPref;
\r
405 TabSheet->Caption = p_item->psz_text;
\r
406 TabSheet->Visible = true;
\r
408 /* pack a scrollbox into the tabsheet */
\r
409 ScrollBox = new TScrollBox( this );
\r
410 ScrollBox->Parent = TabSheet;
\r
411 ScrollBox->Align = alClient;
\r
412 ScrollBox->BorderStyle = bsNone;
\r
413 ScrollBox->HorzScrollBar->Tracking = true;
\r
414 ScrollBox->VertScrollBar->Tracking = true;
\r
418 case CONFIG_ITEM_MODULE:
\r
420 /* add new groupbox for the config option */
\r
421 GroupBoxPlugin = new TGroupBoxPlugin( this, p_item );
\r
422 GroupBoxPlugin->Parent = ScrollBox;
\r
424 /* add panel as separator */
\r
427 /* Look for valid modules */
\r
428 pp_parser = (module_t **)p_list->pp_objects;
\r
430 for( ; *pp_parser ; pp_parser++ )
\r
432 if( !strcmp( (*pp_parser)->psz_capability, p_item->psz_type ) )
\r
434 int item = GroupBoxPlugin->CheckListBox->Items->Add(
\r
435 (*pp_parser)->psz_object_name );
\r
437 /* check the box if it's the default module */
\r
438 AnsiString Name = p_item->psz_value ?
\r
439 p_item->psz_value : "";
\r
440 if( !strcmp( (*pp_parser)->psz_object_name, Name.c_str()) )
\r
442 GroupBoxPlugin->CheckListBox->Checked[item] = true;
\r
449 case CONFIG_ITEM_FILE:
\r
451 case CONFIG_ITEM_STRING:
\r
453 /* add new groupbox for the config option */
\r
454 GroupBoxString = new TGroupBoxString( this, p_item );
\r
455 GroupBoxString->Parent = ScrollBox;
\r
457 /* add panel as separator */
\r
462 case CONFIG_ITEM_INTEGER:
\r
464 /* add new groupbox for the config option */
\r
465 GroupBoxInteger = new TGroupBoxInteger( this, p_item );
\r
466 GroupBoxInteger->Parent = ScrollBox;
\r
468 /* add panel as separator */
\r
473 case CONFIG_ITEM_BOOL:
\r
475 /* add new groupbox for the config option */
\r
476 GroupBoxBool = new TGroupBoxBool( this, p_item );
\r
477 GroupBoxBool->Parent = ScrollBox;
\r
479 /* add panel as separator */
\r
487 while( p_item->i_type != CONFIG_HINT_END );
\r
489 /* Reorder groupboxes inside the tabsheets */
\r
490 for( i_pages = 0; i_pages < PageControlPref->PageCount; i_pages++ )
\r
492 /* get scrollbox from the tabsheet */
\r
493 ScrollBox = (TScrollBox *)PageControlPref->Pages[i_pages]->Controls[0];
\r
495 for( i_ctrl = ScrollBox->ControlCount - 1; i_ctrl >= 0 ; i_ctrl-- )
\r
497 ScrollBox->Controls[i_ctrl]->Align = alTop;
\r
501 vlc_list_release( p_list );
\r
503 /* set active tabsheet
\r
504 * FIXME: i don't know why, but both lines are necessary */
\r
505 PageControlPref->ActivePageIndex = 1;
\r
506 PageControlPref->ActivePageIndex = 0;
\r
509 //---------------------------------------------------------------------------
\r
510 void __fastcall TPreferencesDlg::ButtonOkClick( TObject *Sender )
\r
512 ButtonApplyClick( Sender );
\r
515 //---------------------------------------------------------------------------
\r
516 void __fastcall TPreferencesDlg::ButtonApplyClick( TObject *Sender )
\r
518 TScrollBox *ScrollBox;
\r
519 TGroupBoxPref *GroupBox;
\r
522 for( i = 0; i < PageControlPref->PageCount; i++ )
\r
524 /* get scrollbox from the tabsheet */
\r
525 ScrollBox = (TScrollBox *)PageControlPref->Pages[i]->Controls[0];
\r
527 for( j = 0; j < ScrollBox->ControlCount ; j++ )
\r
529 /* skip the panels */
\r
530 if( ScrollBox->Controls[j]->InheritsFrom( __classid( TGroupBoxPref ) ) )
\r
532 GroupBox = (TGroupBoxPref *)ScrollBox->Controls[j];
\r
533 GroupBox->UpdateChanges();
\r
534 SaveValue( GroupBox->p_config );
\r
539 //---------------------------------------------------------------------------
\r
540 void __fastcall TPreferencesDlg::ButtonSaveClick( TObject *Sender )
\r
542 ButtonApplyClick( Sender );
\r
543 config_SaveConfigFile( p_intfGlobal, NULL );
\r
545 //---------------------------------------------------------------------------
\r
546 void __fastcall TPreferencesDlg::ButtonCancelClick( TObject *Sender )
\r
550 //---------------------------------------------------------------------------
\r
551 void __fastcall TPreferencesDlg::SaveValue( module_config_t *p_config )
\r
553 switch( p_config->i_type )
\r
555 case CONFIG_ITEM_STRING:
\r
556 case CONFIG_ITEM_FILE:
\r
557 case CONFIG_ITEM_MODULE:
\r
558 config_PutPsz( p_intfGlobal, p_config->psz_name,
\r
559 *p_config->psz_value ? p_config->psz_value : NULL );
\r
561 case CONFIG_ITEM_INTEGER:
\r
562 case CONFIG_ITEM_BOOL:
\r
563 config_PutInt( p_intfGlobal, p_config->psz_name,
\r
564 p_config->i_value );
\r
568 //---------------------------------------------------------------------------
\r