]> git.sesse.net Git - vlc/blob - modules/gui/wince/preferences.cpp
Copyright fixes
[vlc] / modules / gui / wince / preferences.cpp
1 /*****************************************************************************
2  * preferences.cpp : WinCE gui plugin for VLC
3  *****************************************************************************
4  * Copyright (C) 2000-2004 VideoLAN (Centrale Réseaux) and its contributors
5  * $Id$
6  *
7  * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>                                      /* malloc(), free() */
29 #include <string.h>                                            /* strerror() */
30 #include <stdio.h>
31 #include <vlc/vlc.h>
32 #include <vlc/intf.h>
33
34 #include "wince.h"
35
36 #include <winuser.h>
37 #include <windows.h>
38 #include <windowsx.h>
39 #include <commctrl.h>
40 #include <commdlg.h>
41
42 #include <vlc_config_cat.h>
43
44 #include "preferences_widgets.h"
45
46 #define GENERAL_ID 1242
47 #define PLUGIN_ID 1243
48 #define CAPABILITY_ID 1244
49
50 /*****************************************************************************
51  * Event Table.
52  *****************************************************************************/
53
54 /* IDs for the controls and the menu commands */
55 enum
56 {
57     Notebook_Event,
58     MRL_Event,
59     ResetAll_Event,
60     Advanced_Event
61 };
62
63 /*****************************************************************************
64  * Classes declarations.
65  *****************************************************************************/
66 class ConfigTreeData;
67 class PrefsTreeCtrl
68 {
69 public:
70
71     PrefsTreeCtrl() { }
72     PrefsTreeCtrl( intf_thread_t *_p_intf, PrefsDialog *p_prefs_dialog,
73                    HWND hwnd, HINSTANCE _hInst );
74     virtual ~PrefsTreeCtrl();
75
76     void ApplyChanges();
77     /*void CleanChanges();*/
78
79     void OnSelectTreeItem( LPNM_TREEVIEW pnmtv, HWND parent, HINSTANCE hInst );
80         
81     ConfigTreeData *FindModuleConfig( ConfigTreeData *config_data );
82
83     HWND hwndTV;
84
85 private:
86     intf_thread_t *p_intf;
87     PrefsDialog *p_prefs_dialog;
88     vlc_bool_t b_advanced;
89
90     HTREEITEM general_item;
91     HTREEITEM plugins_item;
92 };
93
94 class PrefsPanel
95 {
96 public:
97
98     PrefsPanel() { }
99     PrefsPanel( HWND parent, HINSTANCE hInst, intf_thread_t *_p_intf,
100                 PrefsDialog *, int i_object_id, char *, char * );
101     virtual ~PrefsPanel() {}
102
103     void Hide();
104     void Show();
105
106     HWND config_window;
107
108     int oldvalue;
109     int maxvalue;
110
111     void ApplyChanges();
112
113 private:
114     intf_thread_t *p_intf;
115     PrefsDialog *p_prefs_dialog;
116
117     vlc_bool_t b_advanced;
118
119     HWND label;
120
121     vector<ConfigControl *> config_array;
122 };
123
124 class ConfigTreeData
125 {
126 public:
127
128     ConfigTreeData() { b_submodule = 0; panel = NULL; psz_section = NULL;
129                        psz_help = NULL; }
130     virtual ~ConfigTreeData() { if( panel ) delete panel;
131                                 if( psz_section) free(psz_section);
132                                 if( psz_help) free(psz_help); }
133
134     vlc_bool_t b_submodule;
135
136     PrefsPanel *panel;
137     int i_object_id;
138     char *psz_section;
139     char *psz_help;
140 };
141
142 /*****************************************************************************
143  * Constructor.
144  *****************************************************************************/
145 PrefsDialog::PrefsDialog( intf_thread_t *p_intf, CBaseWindow *p_parent,
146                           HINSTANCE h_inst )
147   :  CBaseWindow( p_intf, p_parent, h_inst )
148 {
149     /* Initializations */
150     prefs_tree = NULL;
151 }
152
153 /***********************************************************************
154
155 FUNCTION: 
156   WndProc
157
158 PURPOSE: 
159   Processes messages sent to the main window.
160
161 ***********************************************************************/
162 LRESULT PrefsDialog::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
163 {
164     SHINITDLGINFO shidi;
165     SHMENUBARINFO mbi;
166     RECT rcClient;
167
168     switch( msg )
169     {
170     case WM_INITDIALOG:
171         shidi.dwMask = SHIDIM_FLAGS;
172         shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN |
173             SHIDIF_FULLSCREENNOMENUBAR;//SHIDIF_SIZEDLGFULLSCREEN;
174         shidi.hDlg = hwnd;
175         SHInitDialog( &shidi );
176
177         //Create the menubar
178         memset( &mbi, 0, sizeof (SHMENUBARINFO) );
179         mbi.cbSize     = sizeof (SHMENUBARINFO);
180         mbi.hwndParent = hwnd;
181         mbi.dwFlags    = SHCMBF_EMPTYBAR;
182         mbi.hInstRes   = hInst;
183
184         if( !SHCreateMenuBar(&mbi) )
185         {
186             MessageBox(hwnd, _T("SHCreateMenuBar Failed"), _T("Error"), MB_OK);
187             //return -1;
188         }
189
190         hwndCB = mbi.hwndMB;
191
192         // Get the client area rect to put the panels in
193         GetClientRect(hwnd, &rcClient);
194
195         /* Create the buttons */            
196         advanced_checkbox =
197             CreateWindow( _T("BUTTON"), _T("Advanced options"),
198                         WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
199                         5, 10, 15, 15, hwnd, NULL, hInst, NULL );
200         SendMessage( advanced_checkbox, BM_SETCHECK, BST_UNCHECKED, 0 );
201
202         advanced_label = CreateWindow( _T("STATIC"), _T("Advanced options"),
203                         WS_CHILD | WS_VISIBLE | SS_LEFT,
204                         5 + 15 + 5, 10, 110, 15,
205                         hwnd, NULL, hInst, NULL);
206
207         if( config_GetInt( p_intf, "advanced" ) )
208         {
209             SendMessage( advanced_checkbox, BM_SETCHECK, BST_CHECKED, 0 );
210             /*dummy_event.SetInt(TRUE);
211               OnAdvanced( dummy_event );*/
212         }
213
214         reset_button = CreateWindow( _T("BUTTON"), _T("Reset All"),
215                         WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
216                         rcClient.right - 5 - 80, 10 - 3, 80, 15 + 6,
217                         hwnd, NULL, hInst, NULL );
218
219         /* Create the preferences tree control */
220         prefs_tree = new PrefsTreeCtrl( p_intf, this, hwnd, hInst );
221
222         UpdateWindow( hwnd );
223         break;
224
225     case WM_CLOSE:
226         EndDialog( hwnd, LOWORD( wp ) );
227         break;
228
229     case WM_SETFOCUS:
230         SHFullScreen( hwnd, SHFS_SHOWSIPBUTTON );
231         break;
232
233     case WM_COMMAND:
234         if( LOWORD(wp) == IDOK )
235         {
236             OnOk();
237             EndDialog( hwnd, LOWORD( wp ) );
238         }
239         break;
240
241     case WM_NOTIFY:
242
243         if( lp && prefs_tree &&
244             ((LPNMHDR)lp)->hwndFrom == prefs_tree->hwndTV &&
245             ((LPNMHDR)lp)->code == TVN_SELCHANGED )
246         {
247             prefs_tree->OnSelectTreeItem( (NM_TREEVIEW FAR *)(LPNMHDR)lp,
248                                           hwnd, hInst );
249         }
250         break;
251
252     case WM_VSCROLL:
253     {
254         TVITEM tvi = {0};
255         tvi.mask = TVIF_PARAM;
256         tvi.hItem = TreeView_GetSelection( prefs_tree->hwndTV );
257         if( !tvi.hItem ) break;
258
259         if( !TreeView_GetItem( prefs_tree->hwndTV, &tvi ) ) break;
260
261         ConfigTreeData *config_data =
262             prefs_tree->FindModuleConfig( (ConfigTreeData *)tvi.lParam );
263         if( config_data && hwnd == config_data->panel->config_window ) 
264         {
265             int dy;
266             RECT rc;
267             GetWindowRect( hwnd, &rc);
268             int newvalue = config_data->panel->oldvalue;
269             switch ( GET_WM_VSCROLL_CODE(wp,lp) ) 
270             {
271             case SB_BOTTOM       : newvalue = 0; break;
272             case SB_TOP          : newvalue = config_data->panel->maxvalue; break;
273             case SB_LINEDOWN     : newvalue += 10; break;
274             case SB_PAGEDOWN     : newvalue += rc.bottom - rc.top - 25; break; // faux ! une page c'est la longueur réelle de notebook
275             case SB_LINEUP       : newvalue -= 10; break;
276             case SB_PAGEUP       : newvalue -= rc.bottom - rc.top - 25; break;
277             case SB_THUMBPOSITION:
278             case SB_THUMBTRACK   : newvalue = GET_WM_VSCROLL_POS(wp,lp); break;
279             }
280             newvalue = max(0,min(config_data->panel->maxvalue,newvalue));
281             SetScrollPos( hwnd,SB_VERT,newvalue,TRUE);//SB_CTL si hwnd=hwndScrollBar, SB_VERT si window
282             dy = config_data->panel->oldvalue - newvalue;
283
284             ScrollWindowEx( hwnd, 0, dy, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN );
285             UpdateWindow ( hwnd);
286
287             config_data->panel->oldvalue = newvalue;                                
288         }
289         break;
290     }
291
292     default:
293         break;
294     }
295
296     return FALSE;
297 }
298
299 /*****************************************************************************
300  * Private methods.
301  *****************************************************************************/
302
303 /*****************************************************************************
304  * Events methods.
305  *****************************************************************************/
306 void PrefsDialog::OnOk( void )
307 {
308     prefs_tree->ApplyChanges();
309     config_SaveConfigFile( p_intf, NULL );
310 }
311
312 /*****************************************************************************
313  * PrefsTreeCtrl class definition.
314  *****************************************************************************/
315 PrefsTreeCtrl::PrefsTreeCtrl( intf_thread_t *_p_intf,
316                               PrefsDialog *_p_prefs_dialog, HWND hwnd,
317                               HINSTANCE hInst )
318 {
319     vlc_list_t      *p_list;
320     module_t        *p_module;
321     module_config_t *p_item;
322     int i_index;
323
324     INITCOMMONCONTROLSEX iccex;
325     RECT rcClient;
326     TVITEM tvi = {0}; 
327     TVINSERTSTRUCT tvins = {0}; 
328     HTREEITEM hPrev;
329
330     size_t i_capability_count = 0;
331     size_t i_child_index;
332
333     HTREEITEM capability_item;
334
335     /* Initializations */
336     p_intf = _p_intf;
337     p_prefs_dialog = _p_prefs_dialog;
338     b_advanced = VLC_FALSE;
339
340     /* Create a tree view */
341     // Initialize the INITCOMMONCONTROLSEX structure.
342     iccex.dwSize = sizeof( INITCOMMONCONTROLSEX );
343     iccex.dwICC = ICC_TREEVIEW_CLASSES;
344
345     // Registers Statusbar control classes from the common control dll
346     InitCommonControlsEx( &iccex );
347
348     // Get the client area rect to put the tv in
349     GetClientRect(hwnd, &rcClient);
350
351     // Create the tree-view control.
352     hwndTV = CreateWindowEx( 0, WC_TREEVIEW, NULL,
353         WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES |
354         TVS_LINESATROOT | TVS_HASBUTTONS,
355         5, 10 + 2*(15 + 10) + 105 + 5, rcClient.right - 5 - 5, 6*15,
356         hwnd, NULL, hInst, NULL );
357
358     tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
359
360     /* List the plugins */
361     p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
362     if( !p_list ) return;
363
364     /*
365      * Build a tree of the main options
366      */
367     ConfigTreeData *config_data = new ConfigTreeData;
368     config_data->i_object_id = GENERAL_ID;
369     config_data->psz_help = strdup("nothing");//strdup( GENERAL_HELP );
370     config_data->psz_section = strdup( GENERAL_TITLE );
371     tvi.pszText = _T("General settings");
372     tvi.cchTextMax = lstrlen(_T("General settings"));
373     tvi.lParam = (long)config_data;
374     tvins.item = tvi;
375     tvins.hInsertAfter = TVI_FIRST;
376     tvins.hParent = TVI_ROOT;
377
378     // Add the item to the tree-view control.
379     hPrev = (HTREEITEM) TreeView_InsertItem( hwndTV, &tvins);
380     general_item = hPrev;
381
382     for( i_index = 0; i_index < p_list->i_count; i_index++ )
383     {
384         p_module = (module_t *)p_list->p_values[i_index].p_object;
385         if( !strcmp( p_module->psz_object_name, "main" ) )
386             break;
387     }
388     if( i_index < p_list->i_count )
389     {
390         /* We found the main module */
391
392         /* Enumerate config categories and store a reference so we can
393          * generate their config panel them when it is asked by the user. */
394         p_item = p_module->p_config;
395
396         if( p_item ) do
397         {
398             switch( p_item->i_type )
399             {
400             case CONFIG_HINT_CATEGORY:
401                 ConfigTreeData *config_data = new ConfigTreeData;
402                 config_data->psz_section = strdup( p_item->psz_text );
403                 if( p_item->psz_longtext )
404                 {
405                     config_data->psz_help =
406                         strdup( p_item->psz_longtext );
407                 }
408                 else
409                 {
410                     config_data->psz_help = NULL;
411                 }
412                 config_data->i_object_id = p_module->i_object_id;
413
414                 /* Add the category to the tree */
415                 // Set the text of the item. 
416                 tvi.pszText = _FROMMB(p_item->psz_text); 
417                 tvi.cchTextMax = _tcslen(tvi.pszText);
418                 tvi.lParam = (long)config_data;
419                 tvins.item = tvi;
420                 tvins.hInsertAfter = hPrev; 
421                 tvins.hParent = general_item; //level 3
422     
423                 // Add the item to the tree-view control. 
424                 hPrev = (HTREEITEM)TreeView_InsertItem( hwndTV, &tvins );
425
426                 break;
427             }
428         }
429         while( p_item->i_type != CONFIG_HINT_END && p_item++ );
430
431         TreeView_SortChildren( hwndTV, general_item, 0 );
432     }
433         
434     /*
435      * Build a tree of all the plugins
436      */
437     config_data = new ConfigTreeData;
438     config_data->i_object_id = PLUGIN_ID;
439     config_data->psz_help = strdup("nothing");//strdup( PLUGIN_HELP );
440     config_data->psz_section = strdup("nothing");//strdup( PLUGIN_TITLE );
441     tvi.pszText = _T("Modules");
442     tvi.cchTextMax = lstrlen(_T("Modules"));
443     tvi.lParam = (long)config_data;
444     tvins.item = tvi;
445     tvins.hInsertAfter = TVI_LAST;
446     tvins.hParent = TVI_ROOT;
447
448     // Add the item to the tree-view control.
449     hPrev = (HTREEITEM) TreeView_InsertItem( hwndTV, &tvins);
450     plugins_item = hPrev;
451
452     i_capability_count = 0;
453     for( i_index = 0; i_index < p_list->i_count; i_index++ )
454     {
455         i_child_index = 0;
456
457         p_module = (module_t *)p_list->p_values[i_index].p_object;
458
459         /* Exclude the main module */
460         if( !strcmp( p_module->psz_object_name, "main" ) )
461             continue;
462
463         /* Exclude empty plugins (submodules don't have config options, they
464          * are stored in the parent module) */
465         if( p_module->b_submodule )
466             p_item = ((module_t *)p_module->p_parent)->p_config;
467         else
468             p_item = p_module->p_config;
469
470         if( !p_item ) continue;
471         do
472         {
473             if( p_item->i_type & CONFIG_ITEM )
474                 break;
475         }
476         while( p_item->i_type != CONFIG_HINT_END && p_item++ );
477         if( p_item->i_type == CONFIG_HINT_END ) continue;
478
479         /* Find the capability child item */
480         /*long cookie; size_t i_child_index;*/
481         capability_item = TreeView_GetChild( hwndTV, plugins_item );
482         while( capability_item != 0 )
483         {
484             TVITEM capability_tvi = {0};
485             TCHAR psz_text[256];
486             i_child_index++;
487
488             capability_tvi.mask = TVIF_TEXT;
489             capability_tvi.pszText = psz_text;
490             capability_tvi.cchTextMax = 256;
491             capability_tvi.hItem = capability_item;
492             TreeView_GetItem( hwndTV, &capability_tvi );
493             if( !strcmp( _TOMB(capability_tvi.pszText),
494                          p_module->psz_capability ) ) break;
495  
496             capability_item =
497                 TreeView_GetNextSibling( hwndTV, capability_item );
498         }
499
500         if( i_child_index == i_capability_count &&
501             p_module->psz_capability && *p_module->psz_capability )
502         {
503             /* We didn't find it, add it */
504             ConfigTreeData *config_data = new ConfigTreeData;
505             config_data->psz_section =
506                 strdup( GetCapabilityHelp( p_module->psz_capability , 1 ) );
507             config_data->psz_help =
508                 strdup( GetCapabilityHelp( p_module->psz_capability , 2 ) );
509             config_data->i_object_id = CAPABILITY_ID;
510             tvi.pszText = _FROMMB(p_module->psz_capability);
511             tvi.cchTextMax = _tcslen(tvi.pszText);
512             tvi.lParam = (long)config_data;
513             tvins.item = tvi;
514             tvins.hInsertAfter = plugins_item; 
515             tvins.hParent = plugins_item;// level 3
516
517             // Add the item to the tree-view control. 
518             capability_item = (HTREEITEM) TreeView_InsertItem( hwndTV, &tvins);
519
520             i_capability_count++;
521         }
522
523         /* Add the plugin to the tree */
524         ConfigTreeData *config_data = new ConfigTreeData;
525         config_data->b_submodule = p_module->b_submodule;
526         config_data->i_object_id = p_module->b_submodule ?
527             ((module_t *)p_module->p_parent)->i_object_id :
528             p_module->i_object_id;
529         config_data->psz_help = NULL;
530         tvi.pszText = _FROMMB(p_module->psz_object_name);
531         tvi.cchTextMax = _tcslen(tvi.pszText);
532         tvi.lParam = (long)config_data;
533         tvins.item = tvi;
534         tvins.hInsertAfter = capability_item; 
535         tvins.hParent = capability_item;// level 4
536
537         // Add the item to the tree-view control. 
538         TreeView_InsertItem( hwndTV, &tvins );
539     }
540
541     /* Sort all this mess */
542     /*long cookie; size_t i_child_index;*/
543     TreeView_SortChildren( hwndTV, plugins_item, 0 );
544     capability_item = TreeView_GetChild( hwndTV, plugins_item );
545     while( capability_item != 0 )
546     {
547         TreeView_SortChildren( hwndTV, capability_item, 0 );
548         capability_item = TreeView_GetNextSibling( hwndTV, capability_item );
549     }
550
551     /* Clean-up everything */
552     vlc_list_release( p_list );
553
554     TreeView_Expand( hwndTV, general_item, TVE_EXPANDPARTIAL |TVE_EXPAND );
555 }
556
557 PrefsTreeCtrl::~PrefsTreeCtrl()
558 {
559 }
560
561 void PrefsTreeCtrl::ApplyChanges()
562 {
563     /*long cookie, cookie2;*/
564     ConfigTreeData *config_data;
565
566     /* Apply changes to the main module */
567     HTREEITEM item = TreeView_GetChild( hwndTV, general_item );
568     while( item != 0 )
569     {
570         TVITEM tvi = {0};
571         tvi.mask = TVIF_PARAM;
572         tvi.hItem = item;
573         TreeView_GetItem( hwndTV, &tvi );
574         config_data = (ConfigTreeData *)tvi.lParam;
575         if( config_data && config_data->panel )
576         {
577             config_data->panel->ApplyChanges();
578         }
579
580         item = TreeView_GetNextSibling( hwndTV, item );
581     }
582
583     /* Apply changes to the plugins */
584     item = TreeView_GetChild( hwndTV, plugins_item );
585     while( item != 0 )
586     {
587         HTREEITEM item2 = TreeView_GetChild( hwndTV, item );
588         while( item2 != 0 )
589         {       
590             TVITEM tvi = {0};
591             tvi.mask = TVIF_PARAM;
592             tvi.hItem = item2;
593             TreeView_GetItem( hwndTV, &tvi );
594             config_data = (ConfigTreeData *)tvi.lParam;
595             if( config_data && config_data->panel )
596             {
597                 config_data->panel->ApplyChanges();
598             }
599             item2 = TreeView_GetNextSibling( hwndTV, item2 );
600         }
601         item = TreeView_GetNextSibling( hwndTV, item );
602     }
603 }
604
605 ConfigTreeData *PrefsTreeCtrl::FindModuleConfig( ConfigTreeData *config_data )
606 {
607     /* We need this complexity because submodules don't have their own config
608      * options. They use the parent module ones. */
609
610     if( !config_data || !config_data->b_submodule )
611     {
612         return config_data;
613     }
614
615     /*long cookie, cookie2;*/
616     ConfigTreeData *config_new;
617     HTREEITEM item = TreeView_GetChild( hwndTV, plugins_item );
618     while( item != 0 )
619     {
620         HTREEITEM item2 = TreeView_GetChild( hwndTV, item );
621         while( item2 != 0 )
622         {       
623             TVITEM tvi = {0};
624             tvi.mask = TVIF_PARAM;
625             tvi.hItem = item2;
626             TreeView_GetItem( hwndTV, &tvi );
627             config_new = (ConfigTreeData *)tvi.lParam;
628             if( config_new && !config_new->b_submodule &&
629                 config_new->i_object_id == config_data->i_object_id )
630             {
631                 return config_new;
632             }
633             item2 = TreeView_GetNextSibling( hwndTV, item2 );
634         }
635         item = TreeView_GetNextSibling( hwndTV, item );
636     }
637
638     /* Found nothing */
639     return NULL;
640 }
641
642 void PrefsTreeCtrl::OnSelectTreeItem( LPNM_TREEVIEW pnmtv, HWND parent,
643                                       HINSTANCE hInst )
644 {
645     ConfigTreeData *config_data = NULL;
646
647     if( pnmtv->itemOld.hItem )
648         config_data = FindModuleConfig( (ConfigTreeData *)pnmtv->itemOld.lParam );
649
650     if( config_data && config_data->panel )
651     {
652         config_data->panel->Hide();
653     }
654
655     /* Don't use event.GetItem() because we also send fake events */
656     TVITEM tvi = {0};
657     tvi.mask = TVIF_PARAM;
658     tvi.hItem = TreeView_GetSelection( hwndTV );
659     TreeView_GetItem( hwndTV, &tvi );
660     config_data = FindModuleConfig( (ConfigTreeData *)tvi.lParam );
661     if( config_data )
662     {
663         if( !config_data->panel )
664         {
665             /* The panel hasn't been created yet. Let's do it. */
666             config_data->panel =
667                 new PrefsPanel( parent, hInst, p_intf, p_prefs_dialog,
668                                 config_data->i_object_id,
669                                 config_data->psz_section,
670                                 config_data->psz_help );
671         }
672         else
673         {
674             config_data->panel->Show();
675         }
676     }
677 }
678
679 /*****************************************************************************
680  * PrefsPanel class definition.
681  *****************************************************************************/
682 PrefsPanel::PrefsPanel( HWND parent, HINSTANCE hInst, intf_thread_t *_p_intf,
683                         PrefsDialog *_p_prefs_dialog,
684                         int i_object_id, char *psz_section, char *psz_help )
685 {
686     module_config_t *p_item;
687     module_t *p_module = NULL;
688
689     /* Initializations */
690     p_intf = _p_intf;
691     p_prefs_dialog = _p_prefs_dialog;
692
693     b_advanced = VLC_TRUE;
694
695     if( i_object_id == PLUGIN_ID || i_object_id == GENERAL_ID ||
696         i_object_id == CAPABILITY_ID )
697     {
698         label = CreateWindow( _T("STATIC"), _FROMMB(psz_section),
699                               WS_CHILD | WS_VISIBLE | SS_LEFT,
700                               5, 10 + (15 + 10), 200, 15,
701                               parent, NULL, hInst, NULL );
702         config_window = NULL;
703     }
704     else
705     {
706         /* Get a pointer to the module */
707         p_module = (module_t *)vlc_object_get( p_intf,  i_object_id );
708         if( p_module->i_object_type != VLC_OBJECT_MODULE )
709         {
710             /* 0OOoo something went really bad */
711             return;
712         }
713
714         /* Enumerate config options and add corresponding config boxes
715          * (submodules don't have config options, they are stored in the
716          *  parent module) */
717         if( p_module->b_submodule )
718             p_item = ((module_t *)p_module->p_parent)->p_config;
719         else
720             p_item = p_module->p_config;
721
722         /* Find the category if it has been specified */
723         if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY )
724         {
725             while( !(p_item->i_type == CONFIG_HINT_CATEGORY) ||
726                    strcmp( psz_section, p_item->psz_text ) )
727             {
728                 if( p_item->i_type == CONFIG_HINT_END ) break;
729                 p_item++;
730             }
731         }
732
733         /* Add a head title to the panel */
734         label = CreateWindow( _T("STATIC"), _FROMMB(psz_section ?
735                         p_item->psz_text : p_module->psz_longname),
736                         WS_CHILD | WS_VISIBLE | SS_LEFT,
737                         5, 10 + (15 + 10), 250, 15,
738                         parent, NULL, hInst, NULL );
739
740         WNDCLASS wc;
741         memset( &wc, 0, sizeof(wc) );
742         wc.style          = CS_HREDRAW | CS_VREDRAW;
743         wc.lpfnWndProc    = (WNDPROC) _p_prefs_dialog->BaseWndProc;
744         wc.cbClsExtra     = 0;
745         wc.cbWndExtra     = 0;
746         wc.hInstance      = hInst;
747         wc.hIcon          = 0;
748         wc.hCursor        = 0;
749         wc.hbrBackground  = (HBRUSH) GetStockObject(WHITE_BRUSH);
750         wc.lpszMenuName   = 0;
751         wc.lpszClassName  = _T("PrefsPanelClass");
752         RegisterClass(&wc);
753
754         RECT rc;
755         GetWindowRect( parent, &rc);
756         config_window = CreateWindow( _T("PrefsPanelClass"),
757                         _T("config_window"),
758                         WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER,
759                         5, 10 + 2*(15 + 10), rc.right - 5 - 7, 105,
760                         parent, NULL, hInst, (void *) _p_prefs_dialog );
761
762         int y_pos = 5;
763         if( p_item ) do
764         {
765             /* If a category has been specified, check we finished the job */
766             if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY &&
767                 strcmp( psz_section, p_item->psz_text ) )
768                 break;
769
770             ConfigControl *control =
771                 CreateConfigControl( VLC_OBJECT(p_intf),
772                                      p_item, config_window,
773                                      hInst, &y_pos );
774
775             /* Don't add items that were not recognized */
776             if( control == NULL ) continue;
777
778             /* Add the config data to our array so we can keep a trace of it */
779             config_array.push_back( control );
780         }
781         while( p_item->i_type != CONFIG_HINT_END && p_item++ );
782                 
783         GetWindowRect( config_window, &rc);
784         maxvalue = y_pos - (rc.bottom - rc.top) + 5;
785         oldvalue = 0;
786         SetScrollRange( config_window, SB_VERT, 0, maxvalue, TRUE );
787     }
788 }
789
790 void PrefsPanel::Hide()
791 {
792     ShowWindow( label, SW_HIDE );
793     if( config_window ) ShowWindow( config_window, SW_HIDE );
794 }
795
796 void PrefsPanel::Show()
797 {
798     ShowWindow( label, SW_SHOW );
799     if( config_window ) ShowWindow( config_window, SW_SHOW );
800 }
801
802 void PrefsPanel::ApplyChanges()
803 {
804     vlc_value_t val;
805
806     for( size_t i = 0; i < config_array.size(); i++ )
807     {
808         ConfigControl *control = config_array[i];
809
810         switch( control->GetType() )
811         {
812         case CONFIG_ITEM_STRING:
813         case CONFIG_ITEM_FILE:
814         case CONFIG_ITEM_DIRECTORY:
815         case CONFIG_ITEM_MODULE:
816             config_PutPsz( p_intf, control->GetName(),
817                            control->GetPszValue() );
818             break;
819         case CONFIG_ITEM_KEY:
820             /* So you don't need to restart to have the changes take effect */
821             val.i_int = control->GetIntValue();
822             var_Set( p_intf->p_vlc, control->GetName(), val );
823         case CONFIG_ITEM_INTEGER:
824         case CONFIG_ITEM_BOOL:
825             config_PutInt( p_intf, control->GetName(),
826                            control->GetIntValue() );
827             break;
828         case CONFIG_ITEM_FLOAT:
829             config_PutFloat( p_intf, control->GetName(),
830                              control->GetFloatValue() );
831             break;
832         }
833     }
834 }