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