]> git.sesse.net Git - vlc/blob - plugins/win32/preferences.cpp
* Added a win32 interface plugin, developed with Borland C++ Builder.
[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 <videolan/vlc.h>\r
27 \r
28 #include "interface.h"\r
29 \r
30 #include "preferences.h"\r
31 #include "win32_common.h"\r
32 \r
33 //---------------------------------------------------------------------------\r
34 //#pragma package(smart_init)\r
35 #pragma resource "*.dfm"\r
36 \r
37 extern struct intf_thread_s *p_intfGlobal;\r
38 \r
39 /****************************************************************************\r
40  * Functions to help components creation\r
41  ****************************************************************************/\r
42 __fastcall TGroupBoxPref::TGroupBoxPref( TComponent* Owner,\r
43             module_config_t *p_config_arg ) : TGroupBox( Owner )\r
44 {\r
45     p_config = p_config_arg;\r
46     Caption = p_config->psz_text;\r
47 }\r
48 //---------------------------------------------------------------------------\r
49 TListView * __fastcall TGroupBoxPref::CreateListView( TWinControl *Parent,\r
50             int Left, int Width, int Top, int Height, TViewStyle ViewStyle )\r
51 {\r
52     TListView *ListView = new TListView( Parent );\r
53     ListView->Parent = Parent;\r
54     ListView->ViewStyle = ViewStyle;\r
55     ListView->Left = Left;\r
56     ListView->Width = Width;\r
57     ListView->Top = Top;\r
58     ListView->Height = Height;\r
59     return ListView;\r
60 }\r
61 //---------------------------------------------------------------------------\r
62 TButton * __fastcall TGroupBoxPref::CreateButton( TWinControl *Parent,\r
63             int Left, int Width, int Top, int Height, AnsiString Caption )\r
64 {\r
65     TButton *Button = new TButton( Parent );\r
66     Button->Parent = Parent;\r
67     Button->Left = Left;\r
68     Button->Width = Width;\r
69     Button->Top = Top;\r
70     Button->Height = Height;\r
71     Button->Caption = Caption;\r
72     return Button;\r
73 }\r
74 //---------------------------------------------------------------------------\r
75 TCheckBox * __fastcall TGroupBoxPref::CreateCheckBox( TWinControl *Parent,\r
76             int Left, int Width, int Top, int Height, AnsiString Caption )\r
77 {\r
78     TCheckBox *CheckBox = new TCheckBox( Parent );\r
79     CheckBox->Parent = Parent;\r
80     CheckBox->Left = Left;\r
81     CheckBox->Width = Width;\r
82     CheckBox->Top = Top;\r
83     CheckBox->Height = Height;\r
84     CheckBox->Caption = Caption;\r
85     return CheckBox;\r
86 }\r
87 //---------------------------------------------------------------------------\r
88 TLabel * __fastcall TGroupBoxPref::CreateLabel( TWinControl *Parent,\r
89             int Left, int Width, int Top, int Height, AnsiString Caption,\r
90             bool WordWrap )\r
91 {\r
92     TLabel *Label = new TLabel( Parent );\r
93     Label->Parent = Parent;\r
94     Label->Caption = Caption;\r
95     Label->Left = Left;\r
96     Label->Width = Width;\r
97     Label->Top = Top;\r
98     Label->Height = Height;\r
99     Label->WordWrap = WordWrap;\r
100     return Label;\r
101 }\r
102 //---------------------------------------------------------------------------\r
103 TEdit * __fastcall TGroupBoxPref::CreateEdit( TWinControl *Parent,\r
104             int Left, int Width, int Top, int Height, AnsiString Text )\r
105 {\r
106     TEdit *Edit = new TEdit( Parent );\r
107     Edit->Parent = Parent;\r
108     Edit->Left = Left;\r
109     Edit->Width = Width;\r
110     Edit->Top = Top;\r
111     Edit->Height = Height;\r
112     Edit->Text = Text;\r
113     return Edit;\r
114 }\r
115 //---------------------------------------------------------------------------\r
116 TUpDown * __fastcall TGroupBoxPref::CreateUpDown( TWinControl *Parent,\r
117             int Min, int Max, int Position, bool Thousands )\r
118 {\r
119     TUpDown *UpDown = new TUpDown( Parent );\r
120     UpDown->Parent = Parent;\r
121     UpDown->Min = Min;\r
122     UpDown->Max = Max;\r
123     UpDown->Position = Position;\r
124     UpDown->Thousands = Thousands;\r
125     return UpDown;\r
126 }\r
127 \r
128 \r
129 /****************************************************************************\r
130  * GroupBox for plugin management\r
131  ****************************************************************************/\r
132 __fastcall TGroupBoxPlugin::TGroupBoxPlugin( TComponent* Owner,\r
133             module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )\r
134 {\r
135     /* init listview */\r
136     ListView = CreateListView( this, 16, 164, 24, 160, vsReport );\r
137     ListView->Columns->Add();\r
138     ListView->Columns->Items[0]->Width = 160;\r
139     ListView->Columns->Items[0]->Caption = "Name";//p_config->psz_text;\r
140     ListView->OnSelectItem = ListViewSelectItem;\r
141 \r
142     /* init description label */\r
143     LabelDesc = CreateLabel( this, 230, 225, 50, 52,\r
144                              p_config->psz_longtext, true );\r
145 \r
146     /* init hint label */\r
147     LabelHint = CreateLabel( this, 230, 225, 135, 13, "", false );\r
148 \r
149     /* init configure button */\r
150     ButtonConfig = CreateButton( this, 16, 70, 192, 25, "Configure" );\r
151     ButtonConfig->Enabled = false;\r
152 \r
153     /* init select button */\r
154     ButtonSelect = CreateButton( this, 110, 70, 192, 25, "Select" );\r
155     ButtonSelect->OnClick = ButtonSelectClick;\r
156 \r
157     /* init 'Selected' label */\r
158     LabelSelected = CreateLabel( this, 230, 45, 198, 13, "Selected", false );\r
159 \r
160     /* init 'Selected' edit */\r
161     Edit = CreateEdit( this, 280, 164, 194, 21, "" );\r
162     vlc_mutex_lock( p_config->p_lock );\r
163     Edit->Text = p_config->psz_value ? p_config->psz_value : "";\r
164     vlc_mutex_unlock( p_config->p_lock );\r
165     Edit->OnChange = EditChange;\r
166 \r
167     Height = 233;\r
168 };\r
169 //---------------------------------------------------------------------------\r
170 void __fastcall TGroupBoxPlugin::ListViewSelectItem( TObject *Sender,\r
171         TListItem *Item, bool Selected )\r
172 {\r
173     module_t *p_module;\r
174     AnsiString Name;\r
175 \r
176     Name = Item->Caption;\r
177     if( Name != "" )\r
178     {\r
179         /* look for plugin 'Name' */\r
180         for( p_module = p_module_bank->first ;\r
181              p_module != NULL ;\r
182              p_module = p_module->next )\r
183         {\r
184             if( !strcmp( p_module->psz_name, Name.c_str() ) )\r
185             {\r
186                 ModuleSelected = p_module;\r
187                 LabelHint->Caption = p_module->psz_longname ?\r
188                                      p_module->psz_longname : "";\r
189                 ButtonConfig->Enabled = p_module->i_config_items ? true : false;\r
190 \r
191                 break;\r
192             }\r
193         }\r
194     }\r
195 }\r
196 //---------------------------------------------------------------------------\r
197 void __fastcall TGroupBoxPlugin::ButtonSelectClick( TObject *Sender )\r
198 {\r
199     if( !ModuleSelected ) return;\r
200     Edit->Text = ModuleSelected->psz_name;\r
201 }\r
202 //---------------------------------------------------------------------------\r
203 void __fastcall TGroupBoxPlugin::ButtonConfigClick( TObject *Sender )\r
204 {\r
205     /* FIWME: TODO */\r
206 }\r
207 //---------------------------------------------------------------------------\r
208 void __fastcall TGroupBoxPlugin::EditChange( TObject *Sender )\r
209 {\r
210     TEdit *Edit = (TEdit *)Sender;\r
211     p_config->psz_value = Edit->Text.c_str();\r
212 }\r
213 \r
214 \r
215 /****************************************************************************\r
216  * GroupBox for string management\r
217  ****************************************************************************/\r
218 __fastcall TGroupBoxString::TGroupBoxString( TComponent* Owner,\r
219             module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )\r
220 {\r
221     /* init description label */\r
222     LabelDesc = CreateLabel( this, 230, 225, 24, 26,\r
223                              p_config->psz_longtext, true );\r
224 \r
225     /* init edit */\r
226     Edit = CreateEdit( this, 16, 164, 24, 21, "" );\r
227     vlc_mutex_lock( p_config->p_lock );\r
228     Edit->Text = p_config->psz_value ? p_config->psz_value : "";\r
229     vlc_mutex_unlock( p_config->p_lock );\r
230     Edit->OnChange = EditChange;\r
231 \r
232     /* vertical alignment */\r
233     Height = LabelDesc->Height + 24;\r
234     LabelDesc->Top = Top + ( Height - LabelDesc->Height ) / 2 + 4;\r
235     Edit->Top = Top + ( Height - Edit->Height ) / 2 + 4;\r
236 };\r
237 //---------------------------------------------------------------------------\r
238 void __fastcall TGroupBoxString::EditChange( TObject *Sender )\r
239 {\r
240     TEdit *Edit = (TEdit *)Sender;\r
241     p_config->psz_value = Edit->Text.c_str();\r
242 }\r
243 \r
244 \r
245 /****************************************************************************\r
246  * GroupBox for integer management\r
247  ****************************************************************************/\r
248 __fastcall TGroupBoxInteger::TGroupBoxInteger( TComponent* Owner,\r
249             module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )\r
250 {\r
251     /* init description label */\r
252     LabelDesc = CreateLabel( this, 230, 225, 19, 26,\r
253                              p_config->psz_longtext, true );\r
254 \r
255     /* init edit */\r
256     Edit = CreateEdit( this, 16, 148, 24, 21, "" );\r
257     Edit->OnChange = EditChange;\r
258 \r
259     /* init updown */\r
260     UpDown = CreateUpDown( this, -1, 32767, p_config->i_value, false );\r
261     UpDown->Associate = Edit;\r
262 \r
263     /* vertical alignment */\r
264     Height = LabelDesc->Height + 24;\r
265     LabelDesc->Top = Top + ( Height - LabelDesc->Height ) / 2 + 4;\r
266     Edit->Top = Top + ( Height - Edit->Height ) / 2 + 4;\r
267 };\r
268 //---------------------------------------------------------------------------\r
269 void __fastcall TGroupBoxInteger::EditChange( TObject *Sender )\r
270 {\r
271     TEdit *Edit = (TEdit *)Sender;\r
272     p_config->i_value = StrToInt( Edit->Text );\r
273 }\r
274 \r
275 \r
276 /****************************************************************************\r
277  * GroupBox for boolean management\r
278  ****************************************************************************/\r
279 __fastcall TGroupBoxBool::TGroupBoxBool( TComponent* Owner,\r
280             module_config_t *p_config ) : TGroupBoxPref( Owner, p_config )\r
281 {\r
282     /* init description label */\r
283     LabelDesc = CreateLabel( this, 230, 225, 19, 26,\r
284                              p_config->psz_longtext, true );\r
285 \r
286     /* init checkbox */\r
287     CheckBox = CreateCheckBox( this, 16, 184, 28, 17, p_config->psz_text );\r
288     CheckBox->Checked = p_config->i_value;\r
289     CheckBox->OnClick = CheckBoxClick;\r
290 \r
291     /* vertical alignment */\r
292     Height = LabelDesc->Height + 24;\r
293     LabelDesc->Top = Top + ( Height - LabelDesc->Height ) / 2 + 4;\r
294     CheckBox->Top = Top + ( Height - CheckBox->Height ) / 2 + 4;\r
295 };\r
296 //---------------------------------------------------------------------------\r
297 void __fastcall TGroupBoxBool::CheckBoxClick( TObject *Sender )\r
298 {\r
299     TCheckBox *CheckBox = (TCheckBox *)Sender;\r
300     p_config->i_value = CheckBox->Checked ? 1 : 0;\r
301 }\r
302 \r
303 \r
304 /****************************************************************************\r
305  * Callbacks for the dialog\r
306  ****************************************************************************/\r
307 //---------------------------------------------------------------------------\r
308 __fastcall TPreferencesDlg::TPreferencesDlg( TComponent* Owner )\r
309         : TForm( Owner )\r
310 {\r
311     Icon = p_intfGlobal->p_sys->p_window->Icon;\r
312 }\r
313 //---------------------------------------------------------------------------\r
314 void __fastcall TPreferencesDlg::FormClose( TObject *Sender,\r
315       TCloseAction &Action )\r
316 {\r
317     Action = caHide;\r
318 }\r
319 //---------------------------------------------------------------------------\r
320 void __fastcall TPreferencesDlg::FormShow( TObject *Sender )\r
321 {\r
322     p_intfGlobal->p_sys->p_window->MenuPreferences->Checked = true;\r
323     p_intfGlobal->p_sys->p_window->PopupPreferences->Checked = true;\r
324 }\r
325 //---------------------------------------------------------------------------\r
326 void __fastcall TPreferencesDlg::FormHide( TObject *Sender )\r
327 {\r
328     p_intfGlobal->p_sys->p_window->MenuPreferences->Checked = false;\r
329     p_intfGlobal->p_sys->p_window->PopupPreferences->Checked = false;\r
330 }\r
331 \r
332 \r
333 /****************************************************************************\r
334  * CreateConfigDialog: dynamically creates the configuration dialog\r
335  * box from all the configuration data provided by the selected module.\r
336  ****************************************************************************/\r
337 #define ADD_PANEL                               \\r
338 {                                               \\r
339             Panel = new TPanel( this );         \\r
340             Panel->Parent = ScrollBox;          \\r
341             Panel->Caption = "";                \\r
342             Panel->BevelOuter = bvNone;         \\r
343             Panel->Height = 12;                 \\r
344 }\r
345 \r
346 void __fastcall TPreferencesDlg::CreateConfigDialog( char *psz_module_name )\r
347 {\r
348     bool config_dialog;\r
349     module_t *p_module;\r
350     module_t *p_module_plugins;\r
351     int i, j;\r
352 \r
353     TTabSheet *TabSheet;\r
354     TScrollBox *ScrollBox;\r
355     TPanel *Panel;\r
356     TGroupBoxPlugin *GroupBoxPlugin;\r
357     TGroupBoxString *GroupBoxString;\r
358     TGroupBoxInteger *GroupBoxInteger;\r
359     TGroupBoxBool *GroupBoxBool;\r
360     TListItem *ListItem;\r
361 \r
362     /* Check if the dialog box is already opened, if so this will save us\r
363      * quite a bit of work. (the interface will be destroyed when you actually\r
364      * close the main window, but remember that it is only hidden if you\r
365      * clicked on the action buttons). This trick also allows us not to\r
366      * duplicate identical dialog windows. */\r
367 \r
368     /* FIXME: we must find a way of really checking whether the dialog\r
369      * box is already opened */\r
370     config_dialog = false;\r
371 \r
372     if( config_dialog )\r
373     {\r
374         /* Yeah it was open */\r
375         Show();\r
376         return;\r
377     }\r
378 \r
379     /* Look for the selected module */\r
380     for( p_module = p_module_bank->first ; p_module != NULL ;\r
381          p_module = p_module->next )\r
382     {\r
383 \r
384         if( psz_module_name && !strcmp( psz_module_name, p_module->psz_name ) )\r
385             break;\r
386     }\r
387     if( !p_module ) return;\r
388 \r
389     /*\r
390      * We found it, now we can start building its configuration interface\r
391      */\r
392 \r
393     /* Enumerate config options and add corresponding config boxes */\r
394     for( i = 0; i < p_module->i_config_lines; i++ )\r
395     {\r
396         switch( p_module->p_config[i].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_module->p_config[i].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_PLUGIN:\r
417 \r
418             /* add new groupbox for the config option */\r
419             GroupBoxPlugin = new TGroupBoxPlugin( this, &p_module->p_config[i] );\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_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_module->p_config[i].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_module->p_config[i] );\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_module->p_config[i] );\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_module->p_config[i] );\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 \r
477     /* Reorder groupboxes inside the tabsheets */\r
478     for( i = 0; i < PageControlPref->PageCount; i++ )\r
479     {\r
480         /* get scrollbox from the tabsheet */\r
481         ScrollBox = (TScrollBox *)PageControlPref->Pages[i]->Controls[0];\r
482 \r
483         for( j = ScrollBox->ControlCount - 1; j >= 0 ; j-- )\r
484         {\r
485             ScrollBox->Controls[j]->Align = alTop;\r
486         }\r
487     }\r
488 \r
489     /* set active tabsheet\r
490      * FIXME: i don't know why, but both lines are necessary */\r
491     PageControlPref->ActivePageIndex = 1;\r
492     PageControlPref->ActivePageIndex = 0;\r
493 \r
494     /* Ok, job done successfully. Let's keep a reference to the dialog box*/\r
495     /* FIXME: TODO */\r
496 \r
497     /* we want this ref to be destroyed if the object is destroyed */\r
498     /* FIXME: TODO */\r
499     \r
500     Show();\r
501 }\r
502 #undef ADD_PANEL\r
503 //---------------------------------------------------------------------------\r
504 void __fastcall TPreferencesDlg::ButtonOkClick( TObject *Sender )\r
505 {\r
506     ButtonApplyClick( Sender );\r
507     Hide();\r
508 }\r
509 //---------------------------------------------------------------------------\r
510 void __fastcall TPreferencesDlg::ButtonApplyClick( TObject *Sender )\r
511 {\r
512     TScrollBox *ScrollBox;\r
513     TGroupBoxPref *GroupBox;\r
514     int i, j;\r
515 \r
516     for( i = 0; i < PageControlPref->PageCount; i++ )\r
517     {\r
518         /* get scrollbox from the tabsheet */\r
519         ScrollBox = (TScrollBox *)PageControlPref->Pages[i]->Controls[0];\r
520 \r
521         for( j = 0; j < ScrollBox->ControlCount ; j++ )\r
522         {\r
523             /* skip the panels */\r
524             if( ScrollBox->Controls[j]->InheritsFrom( __classid( TGroupBoxPref ) ) )\r
525             {\r
526                 GroupBox = (TGroupBoxPref *)ScrollBox->Controls[j];\r
527                 SaveValue( GroupBox->p_config );\r
528             }\r
529         }\r
530     }\r
531 }\r
532 //---------------------------------------------------------------------------\r
533 void __fastcall TPreferencesDlg::ButtonSaveClick( TObject *Sender )\r
534 {\r
535     ButtonApplyClick( Sender );\r
536     config_SaveConfigFile( NULL );\r
537 }\r
538 //---------------------------------------------------------------------------\r
539 void __fastcall TPreferencesDlg::ButtonCancelClick( TObject *Sender )\r
540 {\r
541     Hide();\r
542 }\r
543 //---------------------------------------------------------------------------\r
544 void __fastcall TPreferencesDlg::SaveValue( module_config_t *p_config )\r
545 {\r
546     switch( p_config->i_type )\r
547     {\r
548         case MODULE_CONFIG_ITEM_STRING:\r
549         case MODULE_CONFIG_ITEM_FILE:\r
550         case MODULE_CONFIG_ITEM_PLUGIN:\r
551             config_PutPszVariable( p_config->psz_name, p_config->psz_value );\r
552             break;\r
553         case MODULE_CONFIG_ITEM_INTEGER:\r
554         case MODULE_CONFIG_ITEM_BOOL:\r
555             config_PutIntVariable( p_config->psz_name, p_config->i_value );\r
556             break;\r
557     }\r
558 }\r
559 //---------------------------------------------------------------------------\r
560 \r