]> git.sesse.net Git - vlc/blob - plugins/win32/preferences.cpp
* ALL: the first libvlc commit.
[vlc] / plugins / win32 / preferences.cpp
1 /*****************************************************************************\r
2  * preferences.cpp: the "Preferences" dialog box\r
3  *****************************************************************************\r
4  * Copyright (C) 2002 VideoLAN\r
5  *\r
6  * Authors: Olivier Teuliere <ipkiss@via.ecp.fr>\r
7  *\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
12  *\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
17  *\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
22 \r
23 #include <vcl.h>\r
24 #pragma hdrstop\r
25 \r
26 #include <stdlib.h>                                      /* malloc(), free() */\r
27 #include <string.h>                                                /* strcmp */\r
28 \r
29 #include <vlc/vlc.h>\r
30 #include <vlc/intf.h>\r
31 \r
32 #include "preferences.h"\r
33 #include "win32_common.h"\r
34 \r
35 //---------------------------------------------------------------------------\r
36 //#pragma package(smart_init)\r
37 #pragma link "CSPIN"\r
38 #pragma resource "*.dfm"\r
39 \r
40 extern intf_thread_t *p_intfGlobal;\r
41 \r
42 \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
48 {\r
49     p_config = p_config_arg;\r
50     Caption = p_config->psz_text;\r
51 }\r
52 //---------------------------------------------------------------------------\r
53 TListView * __fastcall TGroupBoxPref::CreateListView( TWinControl *Parent,\r
54             int Left, int Width, int Top, int Height, TViewStyle ViewStyle )\r
55 {\r
56     TListView *ListView = new TListView( Parent );\r
57     ListView->Parent = Parent;\r
58     ListView->ViewStyle = ViewStyle;\r
59     ListView->Left = Left;\r
60     ListView->Width = Width;\r
61     ListView->Top = Top;\r
62     ListView->Height = Height;\r
63     return ListView;\r
64 }\r
65 //---------------------------------------------------------------------------\r
66 TButton * __fastcall TGroupBoxPref::CreateButton( TWinControl *Parent,\r
67             int Left, int Width, int Top, int Height, AnsiString Caption )\r
68 {\r
69     TButton *Button = new TButton( Parent );\r
70     Button->Parent = Parent;\r
71     Button->Left = Left;\r
72     Button->Width = Width;\r
73     Button->Top = Top;\r
74     Button->Height = Height;\r
75     Button->Caption = Caption;\r
76     return Button;\r
77 }\r
78 //---------------------------------------------------------------------------\r
79 TCheckBox * __fastcall TGroupBoxPref::CreateCheckBox( TWinControl *Parent,\r
80             int Left, int Width, int Top, int Height, AnsiString Caption )\r
81 {\r
82     TCheckBox *CheckBox = new TCheckBox( Parent );\r
83     CheckBox->Parent = Parent;\r
84     CheckBox->Left = Left;\r
85     CheckBox->Width = Width;\r
86     CheckBox->Top = Top;\r
87     CheckBox->Height = Height;\r
88     CheckBox->Caption = Caption;\r
89     return CheckBox;\r
90 }\r
91 //---------------------------------------------------------------------------\r
92 TLabel * __fastcall TGroupBoxPref::CreateLabel( TWinControl *Parent,\r
93             int Left, int Width, int Top, int Height, AnsiString Caption,\r
94             bool WordWrap )\r
95 {\r
96     TLabel *Label = new TLabel( Parent );\r
97     Label->Parent = Parent;\r
98     Label->Caption = Caption;\r
99     Label->Left = Left;\r
100     Label->Width = Width;\r
101     Label->Top = Top;\r
102     Label->Height = Height;\r
103     Label->WordWrap = WordWrap;\r
104     return Label;\r
105 }\r
106 //---------------------------------------------------------------------------\r
107 TEdit * __fastcall TGroupBoxPref::CreateEdit( TWinControl *Parent,\r
108             int Left, int Width, int Top, int Height, AnsiString Text )\r
109 {\r
110     TEdit *Edit = new TEdit( Parent );\r
111     Edit->Parent = Parent;\r
112     Edit->Left = Left;\r
113     Edit->Width = Width;\r
114     Edit->Top = Top;\r
115     Edit->Height = Height;\r
116     Edit->Text = Text;\r
117     return Edit;\r
118 }\r
119 //---------------------------------------------------------------------------\r
120 TCSpinEdit * __fastcall TGroupBoxPref::CreateSpinEdit( TWinControl *Parent,\r
121             int Left, int Width, int Top, int Height,\r
122             long Min, long Max, long Value )\r
123 {\r
124     TCSpinEdit *SpinEdit = new TCSpinEdit( Parent );\r
125     SpinEdit->Parent = Parent;\r
126     SpinEdit->Left = Left;\r
127     SpinEdit->Width = Width;\r
128     SpinEdit->Top = Top;\r
129     SpinEdit->Height = Height;\r
130     SpinEdit->MinValue = Min;\r
131     SpinEdit->MaxValue = Max;\r
132     SpinEdit->Value = Value;\r
133     return SpinEdit;\r
134 }\r
135 //---------------------------------------------------------------------------\r
136 void __fastcall TGroupBoxPref::UpdateChanges()\r
137 {\r
138 }\r
139 \r
140 \r
141 /****************************************************************************\r
142  * GroupBox for module management\r
143  ****************************************************************************/\r
144 __fastcall TGroupBoxPlugin::TGroupBoxPlugin( TComponent* Owner,\r
145             module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )\r
146 {\r
147     /* init listview */\r
148     ListView = CreateListView( this, 16, 164, 24, 160, vsReport );\r
149     ListView->ReadOnly = true;\r
150     ListView->Columns->Add();\r
151     ListView->Columns->Items[0]->Width = 160;\r
152     ListView->Columns->Items[0]->Caption = "Name";//p_config->psz_text;\r
153     ListView->OnSelectItem = ListViewSelectItem;\r
154 \r
155     /* init description label */\r
156     LabelDesc = CreateLabel( this, 230, 225, 50, 52,\r
157                              p_config->psz_longtext, true );\r
158 \r
159     /* init hint label */\r
160     LabelHint = CreateLabel( this, 230, 225, 135, 13, "", false );\r
161 \r
162     /* init configure button */\r
163     ButtonConfig = CreateButton( this, 16, 70, 192, 25, "Configure" );\r
164     ButtonConfig->Enabled = false;\r
165     ButtonConfig->OnClick = ButtonConfigClick;\r
166 \r
167     /* init select button */\r
168     ButtonSelect = CreateButton( this, 110, 70, 192, 25, "Select" );\r
169     ButtonSelect->OnClick = ButtonSelectClick;\r
170 \r
171     /* init 'Selected' label */\r
172     LabelSelected = CreateLabel( this, 230, 45, 198, 13, "Selected", false );\r
173 \r
174     /* init 'Selected' edit */\r
175     Edit = CreateEdit( this, 280, 164, 194, 21, "" );\r
176     vlc_mutex_lock( p_config->p_lock );\r
177     Edit->Text = p_config->psz_value ? p_config->psz_value : "";\r
178     vlc_mutex_unlock( p_config->p_lock );\r
179 \r
180     Height = 233;\r
181 };\r
182 //---------------------------------------------------------------------------\r
183 void __fastcall TGroupBoxPlugin::ListViewSelectItem( TObject *Sender,\r
184         TListItem *Item, bool Selected )\r
185 {\r
186     module_t *p_module;\r
187     AnsiString Name;\r
188 \r
189     Name = Item->Caption;\r
190     if( Name != "" )\r
191     {\r
192         /* look for module 'Name' */\r
193         for( p_module = p_intfGlobal->p_vlc->module_bank.first ;\r
194              p_module != NULL ;\r
195              p_module = p_module->next )\r
196         {\r
197             if( strcmp( p_module->psz_name, Name.c_str() ) == 0 )\r
198             {\r
199                 ModuleSelected = p_module;\r
200                 LabelHint->Caption = p_module->psz_longname ?\r
201                                      p_module->psz_longname : "";\r
202                 ButtonConfig->Enabled = p_module->i_config_items ? true : false;\r
203 \r
204                 break;\r
205             }\r
206         }\r
207     }\r
208 }\r
209 //---------------------------------------------------------------------------\r
210 void __fastcall TGroupBoxPlugin::ButtonSelectClick( TObject *Sender )\r
211 {\r
212     if( !ModuleSelected ) return;\r
213     Edit->Text = ModuleSelected->psz_name;\r
214 }\r
215 //---------------------------------------------------------------------------\r
216 void __fastcall TGroupBoxPlugin::ButtonConfigClick( TObject *Sender )\r
217 {\r
218     p_intfGlobal->p_sys->p_window->CreatePreferences( ModuleSelected->psz_name );\r
219 }\r
220 //---------------------------------------------------------------------------\r
221 void __fastcall TGroupBoxPlugin::UpdateChanges()\r
222 {\r
223     /* XXX: Necessary, since c_str() returns only a temporary pointer... */\r
224     free( p_config->psz_value );\r
225     p_config->psz_value = (char *)malloc( Edit->Text.Length() + 1 );\r
226     strcpy( p_config->psz_value, Edit->Text.c_str() );\r
227 }\r
228 \r
229 \r
230 /****************************************************************************\r
231  * GroupBox for string management\r
232  ****************************************************************************/\r
233 __fastcall TGroupBoxString::TGroupBoxString( TComponent* Owner,\r
234             module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )\r
235 {\r
236     /* init description label */\r
237     LabelDesc = CreateLabel( this, 230, 225, 24, 26,\r
238                              p_config->psz_longtext, true );\r
239 \r
240     /* init edit */\r
241     Edit = CreateEdit( this, 16, 164, 24, 21, "" );\r
242     vlc_mutex_lock( p_config->p_lock );\r
243     Edit->Text = p_config->psz_value ? p_config->psz_value : "";\r
244     vlc_mutex_unlock( p_config->p_lock );\r
245 \r
246     /* vertical alignment */\r
247     Height = LabelDesc->Height + 24;\r
248     LabelDesc->Top = Top + ( Height - LabelDesc->Height ) / 2 + 4;\r
249     Edit->Top = Top + ( Height - Edit->Height ) / 2 + 4;\r
250 };\r
251 //---------------------------------------------------------------------------\r
252 void __fastcall TGroupBoxString::UpdateChanges()\r
253 {\r
254     /* XXX: Necessary, since c_str() returns only a temporary pointer... */\r
255     free( p_config->psz_value );\r
256     p_config->psz_value = (char *)malloc( Edit->Text.Length() + 1 );\r
257     strcpy( p_config->psz_value, Edit->Text.c_str() );\r
258 }\r
259 \r
260 \r
261 /****************************************************************************\r
262  * GroupBox for integer management\r
263  ****************************************************************************/\r
264 __fastcall TGroupBoxInteger::TGroupBoxInteger( TComponent* Owner,\r
265             module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )\r
266 {\r
267     /* init description label */\r
268     LabelDesc = CreateLabel( this, 230, 225, 19, 26,\r
269                              p_config->psz_longtext, true );\r
270 \r
271     /* init spinedit */\r
272     SpinEdit = CreateSpinEdit( this, 16, 164, 24, 21,\r
273                                -1, 100000, p_config->i_value );\r
274 \r
275     /* init updown */\r
276     UpDown = CreateUpDown( this, -1, 32767, p_config->i_value, false );\r
277     UpDown->Associate = Edit;\r
278 \r
279     /* vertical alignment */\r
280     Height = LabelDesc->Height + 24;\r
281     LabelDesc->Top = Top + ( Height - LabelDesc->Height ) / 2 + 4;\r
282     SpinEdit->Top = Top + ( Height - SpinEdit->Height ) / 2 + 4;\r
283 };\r
284 //---------------------------------------------------------------------------\r
285 void __fastcall TGroupBoxInteger::UpdateChanges()\r
286 {\r
287     /* Warning: we're casting from long to int */\r
288     p_config->i_value = (int)SpinEdit->Value;\r
289 }\r
290 \r
291 \r
292 /****************************************************************************\r
293  * GroupBox for boolean management\r
294  ****************************************************************************/\r
295 __fastcall TGroupBoxBool::TGroupBoxBool( TComponent* Owner,\r
296             module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )\r
297 {\r
298     /* init description label */\r
299     LabelDesc = CreateLabel( this, 230, 225, 19, 26,\r
300                              p_config->psz_longtext, true );\r
301 \r
302     /* init checkbox */\r
303     CheckBox = CreateCheckBox( this, 16, 184, 28, 17, p_config->psz_text );\r
304     CheckBox->Checked = p_config->i_value;\r
305 \r
306     /* vertical alignment */\r
307     Height = LabelDesc->Height + 24;\r
308     LabelDesc->Top = Top + ( Height - LabelDesc->Height ) / 2 + 4;\r
309     CheckBox->Top = Top + ( Height - CheckBox->Height ) / 2 + 4;\r
310 };\r
311 //---------------------------------------------------------------------------\r
312 void __fastcall TGroupBoxBool::UpdateChanges()\r
313 {\r
314     p_config->i_value = CheckBox->Checked ? 1 : 0;\r
315 }\r
316 \r
317 \r
318 /****************************************************************************\r
319  * Callbacks for the dialog\r
320  ****************************************************************************/\r
321 //---------------------------------------------------------------------------\r
322 __fastcall TPreferencesDlg::TPreferencesDlg( TComponent* Owner )\r
323         : TForm( Owner )\r
324 {\r
325     Icon = p_intfGlobal->p_sys->p_window->Icon;\r
326 }\r
327 //---------------------------------------------------------------------------\r
328 void __fastcall TPreferencesDlg::FormClose( TObject *Sender,\r
329       TCloseAction &Action )\r
330 {\r
331     Action = caHide;\r
332 }\r
333 //---------------------------------------------------------------------------\r
334 void __fastcall TPreferencesDlg::FormShow( TObject *Sender )\r
335 {\r
336 /*\r
337     p_intfGlobal->p_sys->p_window->MenuPreferences->Checked = true;\r
338     p_intfGlobal->p_sys->p_window->PopupPreferences->Checked = true;\r
339 */\r
340 }\r
341 //---------------------------------------------------------------------------\r
342 void __fastcall TPreferencesDlg::FormHide( TObject *Sender )\r
343 {\r
344 /*\r
345     p_intfGlobal->p_sys->p_window->MenuPreferences->Checked = false;\r
346     p_intfGlobal->p_sys->p_window->PopupPreferences->Checked = false;\r
347 */\r
348 }\r
349 \r
350 \r
351 /****************************************************************************\r
352  * CreateConfigDialog: dynamically creates the configuration dialog\r
353  * box from all the configuration data provided by the selected module.\r
354  ****************************************************************************/\r
355 #define ADD_PANEL                               \\r
356 {                                               \\r
357             Panel = new TPanel( this );         \\r
358             Panel->Parent = ScrollBox;          \\r
359             Panel->Caption = "";                \\r
360             Panel->BevelOuter = bvNone;         \\r
361             Panel->Height = 12;                 \\r
362 }\r
363 \r
364 void __fastcall TPreferencesDlg::CreateConfigDialog( char *psz_module_name )\r
365 {\r
366     module_t           *p_module, *p_module_plugins;\r
367     module_config_t    *p_item;\r
368     int                 i_pages, i_ctrl;\r
369     \r
370     TTabSheet          *TabSheet;\r
371     TScrollBox         *ScrollBox;\r
372     TPanel             *Panel;\r
373     TGroupBoxPlugin    *GroupBoxPlugin;\r
374     TGroupBoxString    *GroupBoxString;\r
375     TGroupBoxInteger   *GroupBoxInteger;\r
376     TGroupBoxBool      *GroupBoxBool;\r
377     TListItem          *ListItem;\r
378 \r
379     /* Look for the selected module */\r
380     for( p_module = p_intfGlobal->p_vlc->module_bank.first ; p_module != NULL ;\r
381          p_module = p_module->next )\r
382     {\r
383         if( psz_module_name && !strcmp( psz_module_name, p_module->psz_name ) )\r
384             break;\r
385     }\r
386     if( !p_module ) return;\r
387 \r
388     /*\r
389      * We found it, now we can start building its configuration interface\r
390      */\r
391 \r
392     /* Enumerate config options and add corresponding config boxes */\r
393     p_item = p_module->p_config;\r
394     do\r
395     {\r
396         switch( p_item->i_type )\r
397         {\r
398         case MODULE_CONFIG_HINT_CATEGORY:\r
399 \r
400             /* create a new tabsheet. */\r
401             TabSheet = new TTabSheet( this );\r
402             TabSheet->PageControl = PageControlPref;\r
403             TabSheet->Caption = p_item->psz_text;\r
404             TabSheet->Visible = true;\r
405 \r
406             /* pack a scrollbox into the tabsheet */\r
407             ScrollBox = new TScrollBox( this );\r
408             ScrollBox->Parent = TabSheet;\r
409             ScrollBox->Align = alClient;\r
410             ScrollBox->BorderStyle = bsNone;\r
411             ScrollBox->HorzScrollBar->Tracking = true;\r
412             ScrollBox->VertScrollBar->Tracking = true;\r
413 \r
414             break;\r
415 \r
416         case MODULE_CONFIG_ITEM_MODULE:\r
417 \r
418             /* add new groupbox for the config option */\r
419             GroupBoxPlugin = new TGroupBoxPlugin( this, p_item );\r
420             GroupBoxPlugin->Parent = ScrollBox;\r
421 \r
422             /* add panel as separator */\r
423             ADD_PANEL;\r
424 \r
425             /* build a list of available plugins */\r
426             for( p_module_plugins = p_intfGlobal->p_vlc->module_bank.first ;\r
427                  p_module_plugins != NULL ;\r
428                  p_module_plugins = p_module_plugins->next )\r
429             {\r
430                 if( p_module_plugins->i_capabilities &\r
431                     ( 1 << p_item->i_value ) )\r
432                 {\r
433                     ListItem = GroupBoxPlugin->ListView->Items->Add();\r
434                     ListItem->Caption = p_module_plugins->psz_name;\r
435                 }\r
436             }\r
437 \r
438             break;\r
439 \r
440         case MODULE_CONFIG_ITEM_FILE:\r
441 \r
442         case MODULE_CONFIG_ITEM_STRING:\r
443 \r
444             /* add new groupbox for the config option */\r
445             GroupBoxString = new TGroupBoxString( this, p_item );\r
446             GroupBoxString->Parent = ScrollBox;\r
447 \r
448             /* add panel as separator */\r
449             ADD_PANEL;\r
450 \r
451             break;\r
452 \r
453         case MODULE_CONFIG_ITEM_INTEGER:\r
454 \r
455             /* add new groupbox for the config option */\r
456             GroupBoxInteger = new TGroupBoxInteger( this, p_item );\r
457             GroupBoxInteger->Parent = ScrollBox;\r
458 \r
459             /* add panel as separator */\r
460             ADD_PANEL;\r
461 \r
462             break;\r
463 \r
464         case MODULE_CONFIG_ITEM_BOOL:\r
465 \r
466             /* add new groupbox for the config option */\r
467             GroupBoxBool = new TGroupBoxBool( this, p_item );\r
468             GroupBoxBool->Parent = ScrollBox;\r
469 \r
470             /* add panel as separator */\r
471             ADD_PANEL;\r
472 \r
473             break;\r
474         }\r
475         \r
476         p_item++;\r
477     }\r
478     while( p_item->i_type != MODULE_CONFIG_HINT_END );\r
479 \r
480     /* Reorder groupboxes inside the tabsheets */\r
481     for( i_pages = 0; i_pages < PageControlPref->PageCount; i_pages++ )\r
482     {\r
483         /* get scrollbox from the tabsheet */\r
484         ScrollBox = (TScrollBox *)PageControlPref->Pages[i_pages]->Controls[0];\r
485 \r
486         for( i_ctrl = ScrollBox->ControlCount - 1; i_ctrl >= 0 ; i_ctrl-- )\r
487         {\r
488             ScrollBox->Controls[i_ctrl]->Align = alTop;\r
489         }\r
490     }\r
491 \r
492     /* set active tabsheet\r
493      * FIXME: i don't know why, but both lines are necessary */\r
494     PageControlPref->ActivePageIndex = 1;\r
495     PageControlPref->ActivePageIndex = 0;\r
496 }\r
497 #undef ADD_PANEL\r
498 //---------------------------------------------------------------------------\r
499 void __fastcall TPreferencesDlg::ButtonOkClick( TObject *Sender )\r
500 {\r
501     ButtonApplyClick( Sender );\r
502     Hide();\r
503 }\r
504 //---------------------------------------------------------------------------\r
505 void __fastcall TPreferencesDlg::ButtonApplyClick( TObject *Sender )\r
506 {\r
507     TScrollBox *ScrollBox;\r
508     TGroupBoxPref *GroupBox;\r
509     int i, j;\r
510 \r
511     for( i = 0; i < PageControlPref->PageCount; i++ )\r
512     {\r
513         /* get scrollbox from the tabsheet */\r
514         ScrollBox = (TScrollBox *)PageControlPref->Pages[i]->Controls[0];\r
515 \r
516         for( j = 0; j < ScrollBox->ControlCount ; j++ )\r
517         {\r
518             /* skip the panels */\r
519             if( ScrollBox->Controls[j]->InheritsFrom( __classid( TGroupBoxPref ) ) )\r
520             {\r
521                 GroupBox = (TGroupBoxPref *)ScrollBox->Controls[j];\r
522                 GroupBox->UpdateChanges();\r
523                 SaveValue( GroupBox->p_config );\r
524             }\r
525         }\r
526     }\r
527 }\r
528 //---------------------------------------------------------------------------\r
529 void __fastcall TPreferencesDlg::ButtonSaveClick( TObject *Sender )\r
530 {\r
531     ButtonApplyClick( Sender );\r
532     config_SaveConfigFile( p_intfGlobal->p_this, NULL );\r
533 }\r
534 //---------------------------------------------------------------------------\r
535 void __fastcall TPreferencesDlg::ButtonCancelClick( TObject *Sender )\r
536 {\r
537     Hide();\r
538 }\r
539 //---------------------------------------------------------------------------\r
540 void __fastcall TPreferencesDlg::SaveValue( module_config_t *p_config )\r
541 {\r
542     switch( p_config->i_type )\r
543     {\r
544         case MODULE_CONFIG_ITEM_STRING:\r
545         case MODULE_CONFIG_ITEM_FILE:\r
546         case MODULE_CONFIG_ITEM_MODULE:\r
547             config_PutPsz( p_intfGlobal, p_config->psz_name,\r
548                            *p_config->psz_value ? p_config->psz_value : NULL );\r
549             break;\r
550         case MODULE_CONFIG_ITEM_INTEGER:\r
551         case MODULE_CONFIG_ITEM_BOOL:\r
552             config_PutInt( p_intfGlobal, p_config->psz_name,\r
553                            p_config->i_value );\r
554             break;\r
555     }\r
556 }\r
557 //---------------------------------------------------------------------------\r
558 \r