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