]> git.sesse.net Git - vlc/blob - modules/gui/macosx/prefs.m
lower case the module_* functions
[vlc] / modules / gui / macosx / prefs.m
1 /*****************************************************************************
2  * prefs.m: MacOS X module for vlc
3  *****************************************************************************
4  * Copyright (C) 2002-2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8  *          Derk-Jan Hartman <hartman at videolan dot 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /* VLCPrefs manages the main preferences dialog
26    the class is related to wxwindows intf, PrefsPanel */
27 /* VLCTreeItem should contain:
28    - the children of the treeitem
29    - the associated prefs widgets
30    - the documentview with all the prefs widgets in it
31    - a saveChanges action
32    - a revertChanges action
33    - a redraw view action
34    - the children action should generate a list of the treeitems children (to be used by VLCPrefs datasource)
35
36    The class is sort of a mix of wxwindows intfs, PrefsTreeCtrl and ConfigTreeData
37 */
38 /* VLCConfigControl are subclassed NSView's containing and managing individual config items
39    the classes are VERY closely related to wxwindows ConfigControls */
40
41 /*****************************************************************************
42  * Preamble
43  *****************************************************************************/
44 #include <stdlib.h>                                      /* malloc(), free() */
45 #include <sys/param.h>                                    /* for MAXPATHLEN */
46 #include <string.h>
47
48 #ifdef HAVE_CONFIG_H
49 # include "config.h"
50 #endif
51
52 #include <vlc_common.h>
53 #include <vlc_config_cat.h>
54
55 #import "intf.h"
56 #import "prefs.h"
57 #import "simple_prefs.h"
58 #import "prefs_widgets.h"
59 #import "vlc_keys.h"
60
61 /* /!\ Warning: Unreadable code :/ */
62
63 @interface VLCTreeItem : NSObject
64 {
65     NSString *o_name;
66     NSString *o_title;
67     NSString *o_help;
68     vlc_object_t * _vlc_object;
69     VLCTreeItem *o_parent;
70     NSMutableArray *o_children;
71     int i_object_category;
72     NSMutableArray *o_subviews;
73 }
74
75 - (id)initWithName: (NSString *)o_item_name
76     withTitle: (NSString *)o_item_title
77     withHelp: (NSString *)o_item_help
78     withObject: (vlc_object_t *)object
79     parent:(VLCTreeItem *)o_parent_item
80     children:(NSMutableArray *)o_children_array
81     whithCategory: (int) i_category;
82
83 + (VLCTreeItem *)rootItem;
84 - (int)numberOfChildren;
85 - (VLCTreeItem *)childAtIndex:(int)i_index;
86 - (vlc_object_t*)vlcObject;
87 - (NSString *)name;
88 - (NSString *)title;
89 - (NSString *)help;
90 - (BOOL)hasPrefs:(NSString *)o_module_name;
91 - (NSView *)showView:(NSScrollView *)o_prefs_view;
92 - (void)applyChanges;
93 - (void)resetView;
94
95 @end
96
97 #pragma mark -
98
99 /*****************************************************************************
100  * VLCPrefs implementation
101  *****************************************************************************/
102 @implementation VLCPrefs
103
104 static VLCPrefs *_o_sharedMainInstance = nil;
105
106 + (VLCPrefs *)sharedInstance
107 {
108     return _o_sharedMainInstance ? _o_sharedMainInstance : [[self alloc] init];
109 }
110
111 - (id)init
112 {
113     if( _o_sharedMainInstance ) {
114         [self dealloc];
115     }
116     else
117     {
118         _o_sharedMainInstance = [super init];
119         p_intf = VLCIntf;
120         o_empty_view = [[NSView alloc] init];
121     }
122
123     return _o_sharedMainInstance;
124 }
125
126 - (void)dealloc
127 {
128     [o_empty_view release];
129     [super dealloc];
130 }
131
132 - (void)awakeFromNib
133 {
134     p_intf = VLCIntf;
135
136     [self initStrings];
137     [o_prefs_view setBorderType: NSGrooveBorder];
138     [o_prefs_view setHasVerticalScroller: YES];
139     [o_prefs_view setDrawsBackground: NO];
140     [o_prefs_view setDocumentView: o_empty_view];
141     [o_tree selectRow:0 byExtendingSelection:NO];
142 }
143
144 - (void)setTitle: (NSString *) o_title_name
145 {
146     [o_title setStringValue: o_title_name];
147 }
148
149 - (void)showPrefs
150 {
151     [[o_basicFull_matrix cellAtRow:0 column:0] setState: NSOffState];
152     [[o_basicFull_matrix cellAtRow:0 column:1] setState: NSOnState];
153     
154     [o_prefs_window center];
155     [o_prefs_window makeKeyAndOrderFront:self];
156 }
157
158 - (void)initStrings
159 {
160     [o_prefs_window setTitle: _NS("Preferences")];
161     [o_save_btn setTitle: _NS("Save")];
162     [o_cancel_btn setTitle: _NS("Cancel")];
163     [o_reset_btn setTitle: _NS("Reset All")];
164     [[o_basicFull_matrix cellAtRow: 0 column: 0] setStringValue: _NS("Basic")];
165     [[o_basicFull_matrix cellAtRow: 0 column: 1] setStringValue: _NS("All")];
166 }
167
168 - (IBAction)savePrefs: (id)sender
169 {
170     /* TODO: call savePrefs on Root item */
171     [[VLCTreeItem rootItem] applyChanges];
172     config_SaveConfigFile( p_intf, NULL );
173     [o_prefs_window orderOut:self];
174 }
175
176 - (IBAction)closePrefs: (id)sender
177 {
178     [o_prefs_window orderOut:self];
179 }
180
181 - (IBAction)resetAll: (id)sender
182 {
183     NSBeginInformationalAlertSheet(_NS("Reset Preferences"), _NS("Cancel"),
184         _NS("Continue"), nil, o_prefs_window, self,
185         @selector(sheetDidEnd: returnCode: contextInfo:), NULL, nil,
186         _NS("Beware this will reset the VLC media player preferences.\n"
187             "Are you sure you want to continue?") );
188 }
189
190 - (void)sheetDidEnd:(NSWindow *)o_sheet returnCode:(int)i_return
191     contextInfo:(void *)o_context
192 {
193     if( i_return == NSAlertAlternateReturn )
194     {
195         [o_prefs_view setDocumentView: o_empty_view];
196         config_ResetAll( p_intf );
197         [[VLCTreeItem rootItem] resetView];
198         [[o_tree itemAtRow:[o_tree selectedRow]]
199             showView:o_prefs_view];
200     }
201 }
202
203 - (IBAction)buttonAction: (id)sender
204 {
205     [o_prefs_window orderOut: self];
206     [[o_basicFull_matrix cellAtRow:0 column:0] setState: NSOnState];
207     [[o_basicFull_matrix cellAtRow:0 column:1] setState: NSOffState];
208     [[[VLCMain sharedInstance] getSimplePreferences] showSimplePrefs];
209 }
210
211 - (void)loadConfigTree
212 {
213 }
214
215 - (void)outlineViewSelectionIsChanging:(NSNotification *)o_notification
216 {
217 }
218
219 /* update the document view to the view of the selected tree item */
220 - (void)outlineViewSelectionDidChange:(NSNotification *)o_notification
221 {
222     [[o_tree itemAtRow:[o_tree selectedRow]] showView: o_prefs_view];
223 }
224
225 @end
226
227 @implementation VLCPrefs (NSTableDataSource)
228
229 - (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
230     return (item == nil) ? [[VLCTreeItem rootItem] numberOfChildren] :
231                             [item numberOfChildren];
232 }
233
234 - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
235 {
236     return (item == nil) ? YES : ( ([item numberOfChildren] != -1) &&
237                                    ([item numberOfChildren] != 0));
238 }
239
240 - (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item {
241     return (item == nil) ? [[VLCTreeItem rootItem] childAtIndex:index] :
242                             (id)[item childAtIndex:index];
243 }
244
245 - (id)outlineView:(NSOutlineView *)outlineView
246     objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
247 {
248     return (item == nil) ? @"" : (id)[item name];
249 }
250
251 @end
252
253 @implementation VLCTreeItem
254
255 static VLCTreeItem *o_root_item = nil;
256
257 #define IsALeafNode ((id)-1)
258
259 - (id)initWithName: (NSString *)o_item_name
260     withTitle: (NSString *)o_item_title
261     withHelp: (NSString *)o_item_help
262     withObject: (vlc_object_t *)object
263     parent:(VLCTreeItem *)o_parent_item
264     children:(NSMutableArray *)o_children_array
265     whithCategory: (int) i_category
266 {
267     self = [super init];
268
269     if( self != nil )
270     {
271         o_name = [o_item_name copy];
272         o_title= [o_item_title copy];
273         o_help= [o_item_help copy];
274         _vlc_object = object ? vlc_object_hold( object ) : NULL;
275         o_parent = o_parent_item;
276         o_children = o_children_array;
277         i_object_category = i_category;
278         o_subviews = nil;
279     }
280     return( self );
281 }
282
283 + (VLCTreeItem *)rootItem
284 {
285    if (o_root_item == nil)
286         o_root_item = [[VLCTreeItem alloc] initWithName:@"main" withTitle:@"main" withHelp:@"" withObject:NULL
287             parent:nil children:[[NSMutableArray alloc] initWithCapacity:10]
288             whithCategory: -1];
289    return o_root_item;
290 }
291
292 - (void)dealloc
293 {
294     if(_vlc_object) vlc_object_release( _vlc_object );
295     if (o_children != IsALeafNode) [o_children release];
296     [o_name release];
297     [o_title release];
298     [o_help release];
299     [super dealloc];
300 }
301
302 /* Creates and returns the array of children
303  * Loads children incrementally */
304 - (NSArray *)children
305 {
306     if( o_children == IsALeafNode )
307         return o_children;
308     if( [ o_children count] == 0 )
309     {
310         intf_thread_t   *p_intf = VLCIntf;
311         vlc_list_t      *p_list;
312         module_t        *p_module = NULL;
313         module_t        *p_main_module;
314         module_config_t *p_items;
315         int             i = 0;
316         if( [[self name] isEqualToString: @"main"] )
317         {
318             p_main_module = module_get_main( p_intf );
319             assert( p_main_module );
320
321             /* We found the main module */
322             /* Enumerate config categories and store a reference so we can
323              * generate their config panel them when it is asked by the user. */
324             VLCTreeItem *p_last_category = NULL;
325             unsigned int i_confsize;
326             p_items = module_config_get( p_main_module, &i_confsize );
327             o_children = [[NSMutableArray alloc] initWithCapacity:10];
328             for( int i = 0; i < i_confsize; i++ )
329             {
330                 NSString *o_child_name;
331                 NSString *o_child_title;
332                 NSString *o_child_help;
333
334                 switch( p_items[i].i_type )
335                 {
336                     case CONFIG_CATEGORY:
337                         if( p_items[i].value.i == -1 ) break;
338
339                         o_child_name = [[VLCMain sharedInstance]
340                             localizedString: config_CategoryNameGet( p_items[i].value.i )];
341                         o_child_title = o_child_name;
342                         o_child_help = [[VLCMain sharedInstance]
343                             localizedString: config_CategoryHelpGet( p_items[i].value.i )];
344                         p_last_category = [VLCTreeItem alloc];
345                         [o_children addObject:[p_last_category
346                             initWithName: o_child_name
347                             withTitle: o_child_title
348                             withHelp: o_child_help
349                             withObject: (vlc_object_t*)p_main_module
350                             parent:self
351                             children:[[NSMutableArray alloc]
352                                 initWithCapacity:10]
353                             whithCategory: p_items[i].value.i]];
354                         break;
355                     case CONFIG_SUBCATEGORY:
356                         if( p_items[i].value.i == -1 ) break;
357
358                         if( p_items[i].value.i != SUBCAT_PLAYLIST_GENERAL &&
359                             p_items[i].value.i != SUBCAT_VIDEO_GENERAL &&
360                             p_items[i].value.i != SUBCAT_INPUT_GENERAL &&
361                             p_items[i].value.i != SUBCAT_INTERFACE_GENERAL &&
362                             p_items[i].value.i != SUBCAT_SOUT_GENERAL &&
363                             p_items[i].value.i != SUBCAT_ADVANCED_MISC &&
364                             p_items[i].value.i != SUBCAT_AUDIO_GENERAL )
365                         {
366                             o_child_name = [[VLCMain sharedInstance]
367                                 localizedString: config_CategoryNameGet( p_items[i].value.i ) ];
368                             o_child_title = o_child_name;
369                             o_child_help = [[VLCMain sharedInstance]
370                                 localizedString: config_CategoryHelpGet( p_items[i].value.i ) ];
371
372                             [p_last_category->o_children
373                                 addObject:[[VLCTreeItem alloc]
374                                 initWithName: o_child_name
375                                 withTitle: o_child_title
376                                 withHelp: o_child_help
377                                 withObject: (vlc_object_t*)p_main_module
378                                 parent:p_last_category
379                                 children:[[NSMutableArray alloc]
380                                     initWithCapacity:10]
381                                 whithCategory: p_items[i].value.i]];
382                         }
383
384                         break;
385                     default:
386                         break;
387                 }
388             }
389
390             vlc_object_release( (vlc_object_t *)p_main_module );
391
392             /* List the modules */
393             p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
394             if( !p_list ) return nil;
395
396             /* Build a tree of the plugins */
397             /* Add the capabilities */
398             for( i = 0; i < p_list->i_count; i++ )
399             {
400                 unsigned int confsize;
401                 p_module = (module_t *)p_list->p_values[i].p_object;
402
403                 /* Exclude the main module */
404                 if( module_is_main( p_module ) )
405                     continue;
406
407                 /* Exclude empty plugins (submodules don't have config */
408                 /* options, they are stored in the parent module) */
409                 p_items = module_config_get( p_module, &confsize );
410
411                 unsigned int j;
412
413                 int i_category = -1;
414                 int i_subcategory = -1;
415                 bool b_item = false;
416
417                 for( j = 0; j < confsize; j++ )
418                 {
419                     if( p_items[j].i_type == CONFIG_CATEGORY )
420                         i_category = p_items[j].value.i;
421                     else if( p_items[j].i_type == CONFIG_SUBCATEGORY )
422                         i_subcategory = p_items[j].value.i;
423
424                     if( p_items[j].i_type & CONFIG_ITEM )
425                         b_item = true;
426             
427                     if( b_item && i_category >= 0 && i_subcategory >= 0 )
428                         break;
429                 }
430     
431                 if( !b_item ) continue;
432
433                 /* Find the right category item */
434
435                 long cookie;
436                 bool b_found = false;
437
438                 VLCTreeItem* p_category_item, * p_subcategory_item;
439                 for (j = 0 ; j < [o_children count] ; j++)
440                 {
441                     p_category_item = [o_children objectAtIndex: j];
442                     if( p_category_item->i_object_category == i_category )
443                     {
444                         b_found = true;
445                         break;
446                     }
447                 }
448                 if( !b_found ) continue;
449
450                 /* Find subcategory item */
451                 b_found = false;
452                 cookie = -1;
453                 for (j = 0 ; j < [p_category_item->o_children count] ; j++)
454                 {
455                     p_subcategory_item = [p_category_item->o_children
456                                             objectAtIndex: j];
457                     if( p_subcategory_item->i_object_category == i_subcategory )
458                     {
459                         b_found = true;
460                         break;
461                     }
462                 }
463                 if( !b_found )
464                     p_subcategory_item = p_category_item;
465
466                 [p_subcategory_item->o_children addObject:[[VLCTreeItem alloc]
467                     initWithName:[[VLCMain sharedInstance]
468                         localizedString: module_get_name( p_module, false ) ]
469                     withTitle:[[VLCMain sharedInstance]
470                         localizedString:  module_GetLongName( p_module ) ]
471                     withHelp: @""
472                     withObject: (vlc_object_t*)p_main_module
473                     parent:p_subcategory_item
474                     children:IsALeafNode
475                     whithCategory: -1]];
476                 }
477             vlc_list_release( p_list );
478         }
479     }
480     return o_children;
481 }
482
483 - (vlc_object_t *)vlcObject
484 {
485     return vlc_object_hold(_vlc_object);
486 }
487
488 - (NSString *)name
489 {
490     return [[o_name retain] autorelease];
491 }
492
493 - (NSString *)title
494 {
495     return [[o_title retain] autorelease];
496 }
497
498 - (NSString *)help
499 {
500     return [[o_help retain] autorelease];
501 }
502
503 - (VLCTreeItem *)childAtIndex:(int)i_index
504 {
505     return [[self children] objectAtIndex:i_index];
506 }
507
508 - (int)numberOfChildren {
509     id i_tmp = [self children];
510     return (i_tmp == IsALeafNode) ? (-1) : (int)[i_tmp count];
511 }
512
513 - (BOOL)hasPrefs:(NSString *)o_module_name
514 {
515     intf_thread_t *p_intf = VLCIntf;
516     module_t *p_parser;
517     vlc_list_t *p_list;
518     char *psz_module_name;
519     int i_index;
520
521     psz_module_name = (char *)[o_module_name UTF8String];
522
523     /* look for module */
524     p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
525
526     for( i_index = 0; i_index < p_list->i_count; i_index++ )
527     {
528         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
529
530         if( !strcmp( module_get_object( p_parser ), psz_module_name ) )
531         {
532             unsigned int confsize;
533             module_config_get( p_parser, &confsize );
534             BOOL b_has_prefs = confsize != 0;
535             vlc_list_release( p_list );
536             return( b_has_prefs );
537         }
538     }
539
540     vlc_list_release( p_list );
541
542     return( NO );
543 }
544
545 - (NSView *)showView:(NSScrollView *)o_prefs_view
546 {
547     NSRect          s_vrc;
548     NSView          *o_view;
549
550     [[VLCPrefs sharedInstance] setTitle: [self title]];
551     /* NSLog( [self getHelp] ); */
552     s_vrc = [[o_prefs_view contentView] bounds]; s_vrc.size.height -= 4;
553     o_view = [[VLCFlippedView alloc] initWithFrame: s_vrc];
554     [o_view setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin |
555                                     NSViewMaxYMargin];
556
557 /* Create all subviews if it isn't already done because we cannot use */
558 /* setHiden for MacOS < 10.3*/
559     if( o_subviews == nil )
560     {
561         intf_thread_t   *p_intf = VLCIntf;
562         vlc_list_t      *p_list;
563         module_t        *p_module = NULL;
564         module_t        *p_main_module;
565         module_config_t *p_items;
566         unsigned int confsize;
567
568         o_subviews = [[NSMutableArray alloc] initWithCapacity:10];
569         /* Get a pointer to the module */
570         if( i_object_category == -1 )
571         {
572             p_module = (module_t *) [self vlcObject];
573             assert( p_module );
574
575             p_items = module_config_get( p_module, &confsize );
576
577             for( unsigned int i = 0; i < confsize; i++ )
578             {
579                 switch( p_items[i].i_type )
580                 {
581                     case CONFIG_SUBCATEGORY:
582                     case CONFIG_CATEGORY:
583                     case CONFIG_SECTION:
584                     case CONFIG_HINT_USAGE:
585                         break;
586                     default:
587                     {
588                         VLCConfigControl *o_control = nil;
589                         o_control = [VLCConfigControl newControl:&p_items[i]
590                                                       withView:o_view];
591                         if( o_control )
592                         {
593                             [o_control setAutoresizingMask: NSViewMaxYMargin |
594                                 NSViewWidthSizable];
595                             [o_subviews addObject: o_control];
596                         }
597                     }
598                     break;
599                 }
600             }
601             vlc_object_release( (vlc_object_t*)p_module );
602         }
603         else
604         {
605             p_main_module = module_get_main( p_intf );
606             assert( p_main_module );
607             module_config_t *p_items;
608
609             unsigned int i, confsize;
610             p_items = module_config_get( p_main_module, &confsize );
611
612             /* We need to first, find the right (sub)category,
613              * and then abort when we find a new (sub)category. Part of the Ugliness. */
614             bool in_right_category = false;
615             bool in_subcategory = false;
616             bool done = false;
617             for( i = 0; i < confsize; i++ )
618             {
619                 if( !p_items[i].i_type )
620                 {
621                     msg_Err( p_intf, "invalid preference item found" );
622                     break;
623                 }
624
625                 switch( p_items[i].i_type )
626                 {
627                     case CONFIG_CATEGORY:
628                         if(!in_right_category && p_items[i].value.i == i_object_category)
629                             in_right_category = true;
630                         else if(in_right_category)
631                             done = true;
632                         break;
633                     case CONFIG_SUBCATEGORY:
634                         if(!in_right_category && p_items[i].value.i == i_object_category)
635                         {
636                             in_right_category = true;
637                             in_subcategory = true;
638                         }
639                         else if(in_right_category && in_subcategory)
640                             done = true;
641                         break;
642                     case CONFIG_SECTION:
643                     case CONFIG_HINT_USAGE:
644                         break;
645                     default:
646                     {
647                         if(!in_right_category) break;
648
649                         VLCConfigControl *o_control = nil;
650                         o_control = [VLCConfigControl newControl:&p_items[i]
651                                                       withView:o_view];
652                         if( o_control != nil )
653                         {
654                             [o_control setAutoresizingMask: NSViewMaxYMargin |
655                                                             NSViewWidthSizable];
656                             [o_subviews addObject: o_control];
657                         }
658                         break;
659                     }
660                 }
661                 if( done ) break;
662             }
663             vlc_object_release( (vlc_object_t*)p_main_module );
664         }
665     }
666
667     if( o_view != nil )
668     {
669         int i_lastItem = 0;
670         int i_yPos = -2;
671         int i_max_label = 0;
672
673         NSEnumerator *enumerator = [o_subviews objectEnumerator];
674         VLCConfigControl *o_widget;
675         NSRect o_frame;
676  
677         while( ( o_widget = [enumerator nextObject] ) )
678             if( i_max_label < [o_widget getLabelSize] )
679                 i_max_label = [o_widget getLabelSize];
680
681         enumerator = [o_subviews objectEnumerator];
682         while( ( o_widget = [enumerator nextObject] ) )
683         {
684             int i_widget;
685
686             i_widget = [o_widget getViewType];
687             i_yPos += [VLCConfigControl calcVerticalMargin:i_widget
688                 lastItem:i_lastItem];
689             [o_widget setYPos:i_yPos];
690             o_frame = [o_widget frame];
691             o_frame.size.width = [o_view frame].size.width -
692                                     LEFTMARGIN - RIGHTMARGIN;
693             [o_widget setFrame:o_frame];
694             [o_widget alignWithXPosition: i_max_label];
695             i_yPos += [o_widget frame].size.height;
696             i_lastItem = i_widget;
697             [o_view addSubview:o_widget];
698          }
699
700         o_frame = [o_view frame];
701         o_frame.size.height = i_yPos;
702         [o_view setFrame:o_frame];
703         [o_prefs_view setDocumentView:o_view];
704
705     }
706     return o_view;
707 }
708
709 - (void)applyChanges
710 {
711     unsigned int i;
712     if( o_subviews != nil )
713         //Item has been shown
714         for( i = 0 ; i < [o_subviews count] ; i++ )
715             [[o_subviews objectAtIndex:i] applyChanges];
716
717     if( o_children != IsALeafNode )
718         for( i = 0 ; i < [o_children count] ; i++ )
719             [[o_children objectAtIndex:i] applyChanges];
720 }
721
722 - (void)resetView
723 {
724     unsigned int i;
725     if( o_subviews != nil )
726     {
727         //Item has been shown
728         [o_subviews release];
729         o_subviews = nil;
730     }
731
732     if( o_children != IsALeafNode )
733         for( i = 0 ; i < [o_children count] ; i++ )
734             [[o_children objectAtIndex:i] resetView];
735 }
736
737 @end
738
739
740 @implementation VLCFlippedView
741
742 - (BOOL)isFlipped
743 {
744     return( YES );
745 }
746
747 @end