]> git.sesse.net Git - vlc/blob - modules/gui/beos/PreferencesWindow.cpp
beos/: finished fixing Preferences
[vlc] / modules / gui / beos / PreferencesWindow.cpp
1 /*****************************************************************************
2  * PreferencesWindow.cpp: beos interface
3  *****************************************************************************
4  * Copyright (C) 1999, 2000, 2001 VideoLAN
5  * $Id$
6  *
7  * Authors: Eric Petit <titer@m0k.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #include <stdlib.h> /* atoi(), strtod() */
25
26 #include <String.h>
27
28 #include <vlc/vlc.h>
29 #include <vlc/intf.h>
30 #include <vlc_keys.h>
31 #include <vlc_config_cat.h>
32
33 #include "PreferencesWindow.h"
34
35 #define TYPE_CATEGORY 0
36 #define TYPE_SUBCATEGORY 2
37 #define TYPE_MODULE 3
38
39 /*****************************************************************************
40  * PreferencesWindow::PreferencesWindow
41  *****************************************************************************/
42 PreferencesWindow::PreferencesWindow( intf_thread_t * _p_intf,
43                                       BRect frame, const char * name )
44     : BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
45                B_NOT_ZOOMABLE )
46 {
47     p_intf   = _p_intf;
48     fCurrent = NULL;
49
50     BRect rect;
51
52     SetSizeLimits( PREFS_WINDOW_WIDTH, 2000, PREFS_WINDOW_HEIGHT, 2000 );
53
54     /* The "background" view */
55     fPrefsView = new BView( Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW );
56     fPrefsView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
57     AddChild( fPrefsView );
58
59     /* Create a scrollable outline view for the preferences tree */
60     rect = Bounds();
61     rect.InsetBy( 10, 10 );
62     rect.right = rect.left + 150;
63     fOutline = new BOutlineListView( rect, "preferences tree",
64                                      B_SINGLE_SELECTION_LIST,
65                                      B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM );
66     BScrollView * scrollview =
67         new BScrollView( "scrollview", fOutline,
68                          B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM,
69                          0, false, true );
70     fPrefsView->AddChild( scrollview );
71
72     /* We need to be informed if the user selects an item */
73     fOutline->SetSelectionMessage( new BMessage( PREFS_ITEM_SELECTED ) );
74
75     /* Create a dummy, empty view so we can correctly place the real
76        config views later */
77     rect.bottom -= 40;
78     rect.left = rect.right + 15 + B_V_SCROLL_BAR_WIDTH;
79     rect.right = Bounds().right - 15;
80     fDummyView = new BView( rect, "", B_FOLLOW_ALL_SIDES, B_WILL_DRAW );
81     fDummyView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
82     fPrefsView->AddChild( fDummyView );
83
84     /* Fill the tree */
85     vlc_list_t * p_list;
86     p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
87     if( !p_list )
88     {
89         msg_Warn( p_intf, "couldn't find any module !" );
90         return;
91     }
92
93     /* Find the main module */
94     module_t * p_module = NULL;
95     module_config_t * p_item = NULL;
96     for( int i = 0; i < p_list->i_count; i++ )
97     {
98         p_module = (module_t*) p_list->p_values[i].p_object;
99
100         if( !strcmp( p_module->psz_object_name, "main" ) &&
101             ( p_item = p_module->p_config ) )
102             break;
103         else
104             p_module = NULL;
105     }
106
107     ConfigItem * catItem = NULL, * subcatItem, * otherItem;
108
109     if( p_module )
110     {
111         /* We found the main module, build the category tree */
112         for( ; p_item->i_type != CONFIG_HINT_END; p_item++ )
113         {
114             switch( p_item->i_type )
115             {
116                 case CONFIG_CATEGORY:
117                     catItem = new ConfigItem( p_intf,
118                         config_CategoryNameGet( p_item->i_value ),
119                         false,
120                         p_item->i_value,
121                         TYPE_CATEGORY,
122                         config_CategoryHelpGet( p_item->i_value ) );
123                     fOutline->AddItem( catItem );
124                     break;
125
126                 case CONFIG_SUBCATEGORY:
127                     if( catItem )
128                     {
129                         subcatItem = new ConfigItem( p_intf,
130                             config_CategoryNameGet( p_item->i_value ),
131                             false,
132                             p_item->i_value,
133                             TYPE_SUBCATEGORY,
134                             config_CategoryHelpGet( p_item->i_value ) );
135                         fOutline->AddUnder( subcatItem, catItem );
136                     }
137                     else
138                     {
139                         msg_Warn( p_intf, "subcategory without a category" );
140                     }
141                     break;
142             }
143         }
144     }
145
146     /* Now parse all others modules */
147
148     int category, subcategory, options;
149
150     for( int i = 0; i < p_list->i_count; i++ )
151     {
152         category    = -1;
153         subcategory = -1;
154         options     = 0;
155
156         p_module = (module_t*) p_list->p_values[i].p_object;
157
158         if( !strcmp( p_module->psz_object_name, "main" ) )
159             continue;
160
161         if( p_module->b_submodule ||
162             !( p_item = p_module->p_config ) )
163             continue;
164
165         for( ; p_item->i_type != CONFIG_HINT_END; p_item++ )
166         {
167             switch( p_item->i_type )
168             {
169                 case CONFIG_CATEGORY:
170                     category = p_item->i_value;
171                     break;
172                 case CONFIG_SUBCATEGORY:
173                     subcategory = p_item->i_value;
174                     break;
175                 default:
176                     if( p_item->i_type & CONFIG_ITEM )
177                         options++;
178             }
179             if( options > 0 && category >= 0 && subcategory >= 0 )
180             {
181                 break;
182             }
183         }
184
185         if( options < 1 || category < 0 || subcategory < 0 )
186             continue;
187
188         catItem = NULL;
189         for( int j = 0; j < fOutline->CountItemsUnder( NULL, true ); j++ )
190         {
191             catItem = (ConfigItem*)
192                 fOutline->ItemUnderAt( NULL, true, j );
193             if( catItem->ObjectId() == category )
194                 break;
195             else
196                 catItem = NULL;
197         }
198
199         if( !catItem )
200             continue;
201
202         subcatItem = NULL;
203         for( int j = 0; j < fOutline->CountItemsUnder( catItem, true ); j++ )
204         {
205             subcatItem = (ConfigItem*)
206                 fOutline->ItemUnderAt( catItem, true, j );
207             if( subcatItem->ObjectId() == subcategory )
208                 break;
209             else
210                 subcatItem = NULL;
211         }
212
213         if( !subcatItem )
214             subcatItem = catItem;
215
216         otherItem = new ConfigItem( p_intf,
217             p_module->psz_shortname ?
218               p_module->psz_shortname : p_module->psz_object_name,
219             p_module->b_submodule,
220             p_module->b_submodule ?
221               ((module_t *)p_module->p_parent)->i_object_id :
222               p_module->i_object_id,
223             TYPE_MODULE,
224             NULL );
225         fOutline->AddUnder( otherItem, subcatItem );
226     }
227
228     vlc_list_release( p_list );
229
230     /* Collapse the whole tree */
231     for( int i = 0; i < fOutline->FullListCountItems(); i++ )
232     {
233         otherItem = (ConfigItem *) fOutline->FullListItemAt( i );
234         fOutline->Collapse( otherItem );
235     }
236
237     /* Set the correct values */
238     Apply( false );
239
240     /* Select the first item */
241     fOutline->Select( 0 );
242
243     /* Add the buttons */
244     BButton * button;
245     rect = Bounds();
246     rect.InsetBy( 10, 10 );
247     rect.left = rect.right - 80;
248     rect.top = rect.bottom - 25;
249     button = new BButton( rect, "", _("Apply"), new BMessage( PREFS_APPLY ),
250                           B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM );
251     button->MakeDefault( true );
252     fPrefsView->AddChild( button );
253     rect.OffsetBy( -90, 0 );
254     button = new BButton( rect, "", _("Save"), new BMessage( PREFS_SAVE ),
255                           B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM );
256     fPrefsView->AddChild( button );
257     rect.OffsetBy( -90, 0 );
258     button = new BButton( rect, "", _("Defaults"),
259                           new BMessage( PREFS_DEFAULTS ),
260                           B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM );
261     fPrefsView->AddChild( button );
262
263     Hide();
264     Show();
265 }
266
267 /*****************************************************************************
268  * PreferencesWindow::~PreferencesWindow
269  *****************************************************************************/
270 PreferencesWindow::~PreferencesWindow()
271 {
272 }
273
274 /*****************************************************************************
275  * PreferencesWindow::QuitRequested
276  *****************************************************************************/
277 bool PreferencesWindow::QuitRequested()
278 {
279     if( !IsHidden() )
280     {
281         Hide();
282     }
283     return false;
284 }
285
286 /*****************************************************************************
287  * PreferencesWindow::MessageReceived
288  *****************************************************************************/
289 void PreferencesWindow::MessageReceived( BMessage * message )
290 {
291     switch( message->what )
292     {
293         case PREFS_ITEM_SELECTED:
294             Update();
295             break;
296
297         case PREFS_DEFAULTS:
298             config_ResetAll( p_intf );
299             config_SaveConfigFile( p_intf, NULL );
300             Apply( false );
301             break;
302
303         case PREFS_APPLY:
304             Apply( true );
305             break;
306
307         case PREFS_SAVE:
308             Apply( true );
309             config_SaveConfigFile( p_intf, NULL );
310             break;
311
312         default:
313             BWindow::MessageReceived( message );
314     }
315 }
316
317 /*****************************************************************************
318  * PreferencesWindow::FrameResized
319  *****************************************************************************/
320 void PreferencesWindow::FrameResized( float width, float height )
321 {
322     BWindow::FrameResized( width, height );
323     fCurrent->UpdateScrollBar();
324 }
325
326 /*****************************************************************************
327  * PreferencesWindow::Update
328  *****************************************************************************/
329 void PreferencesWindow::Update()
330 {
331     /* Get the selected item, if any */
332     if( fOutline->CurrentSelection() < 0 )
333         return;
334
335     /* Detach the old box if any */
336     if( fCurrent )
337     {
338         fCurrent->ResetScroll();
339         fDummyView->RemoveChild( fCurrent->Box() );
340     }
341
342     /* Add the new one... */
343     fCurrent = (ConfigItem *)
344         fOutline->ItemAt( fOutline->CurrentSelection() );
345     fDummyView->AddChild( fCurrent->Box() );
346
347     /* ...then resize it (we must resize it after it's attached or the
348        children don't get adjusted) */
349     fCurrent->Box()->ResizeTo( fDummyView->Bounds().Width(),
350                                fDummyView->Bounds().Height() );
351     fCurrent->UpdateScrollBar();
352 }
353
354 /*****************************************************************************
355  * PreferencesWindow::Apply
356  * Apply changes if doIt is true, revert them otherwise
357  *****************************************************************************/
358 void PreferencesWindow::Apply( bool doIt )
359 {
360     ConfigItem * item;
361
362     for( int i = 0; i < fOutline->FullListCountItems(); i++ )
363     {
364         item = (ConfigItem*) fOutline->FullListItemAt( i );
365         item->Apply( doIt );
366     }
367 }
368
369 /*****************************************************************************
370  * PreferencesWindow::ReallyQuit
371  *****************************************************************************/
372 void PreferencesWindow::ReallyQuit()
373 {
374     Lock();
375     Hide();
376     Quit();
377 }
378
379 /***********************************************************************
380  * ConfigItem::ConfigItem
381  ***********************************************************************
382  *
383  **********************************************************************/
384 ConfigItem::ConfigItem( intf_thread_t * _p_intf, char * name,
385                         bool subModule, int objectId,
386                         int type, char * help )
387     : BStringItem( name )
388 {
389     p_intf     = _p_intf;
390     fSubModule = subModule;
391     fObjectId  = objectId;
392     fType      = type;
393     fHelp      = strdup( help );
394
395     BRect r;
396     r = BRect( 0, 0, 100, 100 );
397     fBox = new BBox( r, NULL, B_FOLLOW_ALL );
398     fBox->SetLabel( name );
399
400     fTextView = NULL;
401     fScroll   = NULL;
402     fView     = NULL;
403
404     if( fType == TYPE_CATEGORY )
405     {
406         /* Category: we just show the help text */
407         r = fBox->Bounds();
408         r.InsetBy( 10, 10 );
409         r.top += 5;
410
411         fTextView = new VTextView( r, NULL, B_FOLLOW_ALL, B_WILL_DRAW);
412         fTextView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
413         fTextView->MakeEditable( false );
414         fTextView->MakeSelectable( false );
415         fTextView->Insert( fHelp );
416         fBox->AddChild( fTextView );
417
418         return;
419     }
420
421     vlc_list_t * p_list = NULL;
422     module_t * p_module = NULL;
423     if( fType == TYPE_MODULE )
424     {
425         p_module = (module_t *) vlc_object_get( p_intf, fObjectId );
426     }
427     else
428     {
429         if( !( p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE,
430                                        FIND_ANYWHERE ) ) )
431         {
432             return;
433         }
434         for( int i = 0; i < p_list->i_count; i++ )
435         {
436             p_module = (module_t*) p_list->p_values[i].p_object;
437
438             if( !strcmp( p_module->psz_object_name, "main" ) )
439                 break;
440             else
441                 p_module = NULL;
442         }
443     }
444
445     if( !p_module || p_module->i_object_type != VLC_OBJECT_MODULE )
446     {
447         /* Shouldn't happen */
448         return;
449     }
450
451     module_config_t * p_item;
452     p_item = fSubModule ? ((module_t *)p_module->p_parent)->p_config :
453                p_module->p_config;
454
455     if( fType == TYPE_SUBCATEGORY )
456     {
457         for( ; p_item->i_type != CONFIG_HINT_END; p_item++ )
458         {
459             if( p_item->i_type == CONFIG_SUBCATEGORY &&
460                 p_item->i_value == fObjectId )
461             {
462                 break;
463             }
464         }
465     }
466
467     r = fBox->Bounds();
468     r = BRect( 10,20,fBox->Bounds().right-B_V_SCROLL_BAR_WIDTH-10,
469                fBox->Bounds().bottom-10 );
470     fView = new BView( r, NULL, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
471                        B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE );
472     fView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
473
474     r = fView->Bounds();
475     r.InsetBy( 10,10 );
476
477     fprintf( stderr, "start\n" );
478     ConfigWidget * widget;
479     for( ; p_item->i_type != CONFIG_HINT_END; p_item++ )
480     {
481         if( ( p_item->i_type == CONFIG_CATEGORY ||
482               p_item->i_type == CONFIG_SUBCATEGORY ) &&
483             fType == TYPE_SUBCATEGORY &&
484             p_item->i_value != fObjectId )
485         {
486             break;
487         }
488
489         widget = new ConfigWidget( p_intf, r, p_item );
490         if( !widget->InitCheck() )
491         {
492             delete widget;
493             continue;
494         }
495         fView->AddChild( widget );
496         fprintf( stderr, "+ %f\n", widget->Bounds().Height() );
497         r.top += widget->Bounds().Height();
498     }
499     fprintf( stderr, "stop\n" );
500
501     if( fType == TYPE_MODULE )
502     {
503         vlc_object_release( p_module );
504     }
505     else
506     {
507         vlc_list_release( p_list );
508     }
509
510     /* Create a scroll view around our fView */
511     fScroll = new BScrollView( NULL, fView, B_FOLLOW_ALL, 0, false,
512                                true, B_FANCY_BORDER );
513     fScroll->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
514     fBox->AddChild( fScroll );
515
516     /* Adjust fView's height to the size it actually needs (we do this
517        only now so the BScrollView fits the BBox) */
518     fView->ResizeTo( fView->Bounds().Width(), r.top + 10 );
519 }
520
521 /***********************************************************************
522  * ConfigItem::~ConfigItem
523  ***********************************************************************
524  *
525  **********************************************************************/
526 ConfigItem::~ConfigItem()
527 {
528     if( fHelp )
529     {
530         free( fHelp );
531     }
532 }
533
534 /*****************************************************************************
535  * ConfigItem::UpdateScrollBar
536  *****************************************************************************/
537 void ConfigItem::UpdateScrollBar()
538 {
539     /* We have to fix the scrollbar manually because it doesn't handle
540        correctly simple BViews */
541
542     if( !fScroll )
543     {
544         return;
545     }
546
547     /* Get the available BRect for display */
548     BRect display = fScroll->Bounds();
549     display.right -= B_V_SCROLL_BAR_WIDTH;
550
551     /* Fix the scrollbar */
552     BScrollBar * scrollBar;
553     BRect visible = display & fView->Bounds();
554     BRect total   = display | fView->Bounds();
555     scrollBar = fScroll->ScrollBar( B_VERTICAL );
556     long max = (long)( fView->Bounds().Height() - visible.Height() );
557     if( max < 0 ) max = 0;
558     scrollBar->SetRange( 0, max );
559     scrollBar->SetProportion( visible.Height() / total.Height() );
560     scrollBar->SetSteps( 10, 100 );
561
562     /* We have to force redraw to avoid visual bugs when resizing
563        (BeOS bug?) */
564     fScroll->Invalidate();
565     fView->Invalidate();
566 }
567
568 /*****************************************************************************
569  * ConfigItem::ResetScroll
570  *****************************************************************************/
571 void ConfigItem::ResetScroll()
572 {
573     if( !fScroll )
574     {
575         return;
576     }
577
578     fView->ScrollTo( 0, 0 );
579 }
580
581 /***********************************************************************
582  * ConfigItem::Apply
583  ***********************************************************************
584  *
585  **********************************************************************/
586 void ConfigItem::Apply( bool doIt )
587 {
588     if( !fScroll )
589     {
590         return;
591     }
592
593     /* Call ConfigWidget::Apply for every child of your fView */
594     ConfigWidget * widget;
595     for( int i = 0; i < fView->CountChildren(); i++ )
596     {
597         widget = (ConfigWidget*) fView->ChildAt( i );
598         widget->Apply( doIt );
599     }
600 }
601
602 /***********************************************************************
603  * ConfigWidget::ConfigWidget
604  ***********************************************************************
605  * Builds a view with the right controls for the given config variable.
606  *  rect: the BRect where we place ourselves. All we care is its width
607  *    and its top coordinate, since we adapt our height to take only
608  *    the place we need
609  **********************************************************************/
610 ConfigWidget::ConfigWidget( intf_thread_t * _p_intf, BRect rect,
611                             module_config_t * p_item )
612     : BView( rect, NULL, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
613              B_WILL_DRAW )
614 {
615     p_intf = _p_intf;
616
617     SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
618
619     BRect r;
620     BMenuItem * menuItem;
621     /* Skip deprecated options */
622     if( p_item->psz_current )
623     {
624         fInitOK = false;
625         return;
626     }
627
628     fInitOK = true;
629
630     fType = p_item->i_type;
631     fName = strdup( p_item->psz_name );
632
633     switch( fType )
634     {
635         case CONFIG_ITEM_MODULE:
636         case CONFIG_ITEM_MODULE_CAT:
637         case CONFIG_ITEM_MODULE_LIST_CAT:
638         case CONFIG_ITEM_STRING:
639         case CONFIG_ITEM_FILE:
640         case CONFIG_ITEM_DIRECTORY:
641         case CONFIG_ITEM_INTEGER:
642         case CONFIG_ITEM_FLOAT:
643             ResizeTo( Bounds().Width(), 25 );
644             fTextControl = new VTextControl( Bounds(), NULL,
645                 p_item->psz_text, NULL, new BMessage(),
646                 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
647             AddChild( fTextControl );
648             fprintf( stderr, "adding text %s at %f\n", p_item->psz_text,
649                      rect.top );
650             break;
651         case CONFIG_ITEM_KEY:
652             ResizeTo( Bounds().Width(), 25 );
653             r = Bounds();
654             r.left = r.right - 100;
655             fPopUpMenu = new BPopUpMenu( "" );
656             fMenuField = new BMenuField( r, NULL, NULL, fPopUpMenu,
657                 B_FOLLOW_RIGHT | B_FOLLOW_TOP );
658             for( unsigned i = 0;
659                  i < sizeof( vlc_keys ) / sizeof( key_descriptor_t );
660                  i++ )
661             {
662                 menuItem = new BMenuItem( vlc_keys[i].psz_key_string, NULL );
663                 fPopUpMenu->AddItem( menuItem );
664             }
665             r.right = r.left - 10; r.left = r.left - 60;
666             fShiftCheck = new BCheckBox( r, NULL, "Shift",
667                 new BMessage(), B_FOLLOW_RIGHT | B_FOLLOW_TOP );
668             r.right = r.left - 10; r.left = r.left - 60;
669             fCtrlCheck = new BCheckBox( r, NULL, "Ctrl",
670                 new BMessage(), B_FOLLOW_RIGHT | B_FOLLOW_TOP );
671             r.right = r.left - 10; r.left = r.left - 60;
672             fAltCheck = new BCheckBox( r, NULL, "Alt",
673                 new BMessage(), B_FOLLOW_RIGHT | B_FOLLOW_TOP );
674             r.right = r.left - 10; r.left = 0; r.bottom -= 10;
675             fStringView = new BStringView( r, NULL, p_item->psz_text,
676                 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
677             AddChild( fStringView );
678             AddChild( fAltCheck );
679             AddChild( fCtrlCheck );
680             AddChild( fShiftCheck );
681             AddChild( fMenuField );
682             fprintf( stderr, "adding key %s at %f\n", p_item->psz_text,
683                      rect.top );
684             break;
685         case CONFIG_ITEM_BOOL:
686             ResizeTo( Bounds().Width(), 25 );
687             fCheckBox = new BCheckBox( Bounds(), NULL, p_item->psz_text,
688                 new BMessage(), B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
689             AddChild( fCheckBox );
690             fprintf( stderr, "adding bool %s at %f\n", p_item->psz_text,
691                      rect.top );
692             break;
693         case CONFIG_SECTION:
694             fInitOK = false;
695             break;
696         default:
697             fInitOK = false;
698     }
699 }
700
701 ConfigWidget::~ConfigWidget()
702 {
703     free( fName );
704 }
705
706 /***********************************************************************
707  * ConfigWidget::Apply
708  ***********************************************************************
709  *
710  **********************************************************************/
711 void ConfigWidget::Apply( bool doIt )
712 {
713     BMenuItem * menuItem;
714     char string[256];
715     vlc_value_t val;
716
717     switch( fType )
718     {
719         case CONFIG_ITEM_STRING:
720         case CONFIG_ITEM_FILE:
721         case CONFIG_ITEM_MODULE:
722         case CONFIG_ITEM_MODULE_CAT:
723         case CONFIG_ITEM_MODULE_LIST_CAT:
724         case CONFIG_ITEM_DIRECTORY:
725             if( doIt )
726             {
727                 config_PutPsz( p_intf, fName, fTextControl->Text() );
728             }
729             else
730             {
731                 fTextControl->SetText( config_GetPsz( p_intf, fName ) );
732             }
733             break;
734
735         case CONFIG_ITEM_INTEGER:
736             if( doIt )
737             {
738                 config_PutInt( p_intf, fName, atoi( fTextControl->Text() ) );
739             }
740             else
741             {
742                 snprintf( string, 256, "%d", config_GetInt( p_intf, fName ) );
743                 fTextControl->SetText( string );
744             }
745             break;
746
747         case CONFIG_ITEM_FLOAT:
748             if( doIt )
749             {
750                 config_PutFloat( p_intf, fName, atof( fTextControl->Text() ) );
751             }
752             else
753             {
754                 snprintf( string, 256, "%f", config_GetFloat( p_intf, fName ) );
755                 fTextControl->SetText( string );
756             }
757             break;
758
759         case CONFIG_ITEM_KEY:
760             if( doIt )
761             {
762                 menuItem = fPopUpMenu->FindMarked();
763                 if( menuItem )
764                 {
765                     val.i_int = vlc_keys[fPopUpMenu->IndexOf( menuItem )].i_key_code;
766                     if( fAltCheck->Value() )
767                     {
768                         val.i_int |= KEY_MODIFIER_ALT;
769                     }
770                     if( fCtrlCheck->Value() )
771                     {
772                         val.i_int |= KEY_MODIFIER_CTRL;
773                     }
774                     if( fShiftCheck->Value() )
775                     {
776                         val.i_int |= KEY_MODIFIER_SHIFT;
777                     }
778                     var_Set( p_intf->p_vlc, fName, val );
779                 }
780             }
781             else
782             {
783                 val.i_int = config_GetInt( p_intf, fName );
784                 fAltCheck->SetValue( val.i_int & KEY_MODIFIER_ALT );
785                 fCtrlCheck->SetValue( val.i_int & KEY_MODIFIER_CTRL );
786                 fShiftCheck->SetValue( val.i_int & KEY_MODIFIER_SHIFT );
787         
788                 for( unsigned i = 0;
789                      i < sizeof( vlc_keys ) / sizeof( key_descriptor_t ); i++ )
790                 {
791                     if( (unsigned) vlc_keys[i].i_key_code ==
792                             ( val.i_int & ~KEY_MODIFIER ) )
793                     {
794                         menuItem = fPopUpMenu->ItemAt( i );
795                         menuItem->SetMarked( true );
796                         break;
797                     }
798                 }
799             }
800             break;
801
802         case CONFIG_ITEM_BOOL:
803             if( doIt )
804             {
805                 config_PutInt( p_intf, fName, fCheckBox->Value() );
806             }
807             else
808             {
809                 fCheckBox->SetValue( config_GetInt( p_intf, fName ) );
810             }
811             break;
812
813         default:
814             break;
815     }
816 }
817
818 VTextView::VTextView( BRect frame, const char *name,
819                       uint32 resizingMode, uint32 flags )
820     : BTextView( frame, name, BRect( 10,10,10,10 ), resizingMode, flags )
821 {
822     FrameResized( Bounds().Width(), Bounds().Height() );
823 }
824
825 void VTextView::FrameResized( float width, float height )
826 {
827     BTextView::FrameResized( width, height );
828     SetTextRect( BRect( 10,10, width-11, height-11 ) );
829 }
830
831 VTextControl::VTextControl( BRect frame, const char *name,
832                             const char *label, const char *text,
833                             BMessage * message, uint32 resizingMode )
834     : BTextControl( frame, name, label, text, message, resizingMode )
835 {
836     FrameResized( Bounds().Width(), Bounds().Height() );
837 }
838
839 void VTextControl::FrameResized( float width, float height )
840 {
841     BTextControl::FrameResized( width, height );
842     SetDivider( width / 2 );
843 }