00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <stdlib.h>
00046 #include <sys/param.h>
00047 #include <string.h>
00048
00049 #include <vlc/vlc.h>
00050 #include <vlc_config_cat.h>
00051
00052 #include "intf.h"
00053 #include "prefs.h"
00054 #include "prefs_widgets.h"
00055 #include "vlc_keys.h"
00056
00057
00058
00059
00060 @implementation VLCPrefs
00061
00062 static VLCPrefs *_o_sharedMainInstance = nil;
00063
00064 + (VLCPrefs *)sharedInstance
00065 {
00066 return _o_sharedMainInstance ? _o_sharedMainInstance : [[self alloc] init];
00067 }
00068
00069 - (id)init
00070 {
00071 if( _o_sharedMainInstance ) {
00072 [self dealloc];
00073 }
00074 else
00075 {
00076 _o_sharedMainInstance = [super init];
00077 p_intf = VLCIntf;
00078 o_empty_view = [[NSView alloc] init];
00079 }
00080
00081 return _o_sharedMainInstance;
00082 }
00083
00084 - (void)dealloc
00085 {
00086 [o_empty_view release];
00087 [super dealloc];
00088 }
00089
00090 - (void)awakeFromNib
00091 {
00092 p_intf = VLCIntf;
00093 b_advanced = config_GetInt( p_intf, "advanced" );
00094
00095 [self initStrings];
00096 [o_advanced_ckb setState: b_advanced];
00097 [o_prefs_view setBorderType: NSGrooveBorder];
00098 [o_prefs_view setHasVerticalScroller: YES];
00099 [o_prefs_view setDrawsBackground: NO];
00100 [o_prefs_view setDocumentView: o_empty_view];
00101 [o_tree selectRow:0 byExtendingSelection:NO];
00102 }
00103
00104 - (void)setTitle: (NSString *) o_title_name
00105 {
00106 [o_title setStringValue: o_title_name];
00107 }
00108
00109 - (void)showPrefs
00110 {
00111
00112 [NSBundle loadNibNamed:@"Preferences" owner:self];
00113
00114 [o_prefs_window center];
00115 [o_prefs_window makeKeyAndOrderFront:self];
00116 }
00117
00118 - (void)initStrings
00119 {
00120 [o_prefs_window setTitle: _NS("Preferences")];
00121 [o_save_btn setTitle: _NS("Save")];
00122 [o_cancel_btn setTitle: _NS("Cancel")];
00123 [o_reset_btn setTitle: _NS("Reset All")];
00124 [o_advanced_ckb setTitle: _NS("Advanced")];
00125 }
00126
00127 - (IBAction)savePrefs: (id)sender
00128 {
00129
00130 [[VLCTreeItem rootItem] applyChanges];
00131 config_SaveConfigFile( p_intf, NULL );
00132 [o_prefs_window orderOut:self];
00133 }
00134
00135 - (IBAction)closePrefs: (id)sender
00136 {
00137 [o_prefs_window orderOut:self];
00138 }
00139
00140 - (IBAction)resetAll: (id)sender
00141 {
00142 NSBeginInformationalAlertSheet(_NS("Reset Preferences"), _NS("Cancel"),
00143 _NS("Continue"), nil, o_prefs_window, self,
00144 @selector(sheetDidEnd: returnCode: contextInfo:), NULL, nil,
00145 _NS("Beware this will reset your VLC media player preferences.\n"
00146 "Are you sure you want to continue?") );
00147 }
00148
00149 - (void)sheetDidEnd:(NSWindow *)o_sheet returnCode:(int)i_return
00150 contextInfo:(void *)o_context
00151 {
00152 if( i_return == NSAlertAlternateReturn )
00153 {
00154 [o_prefs_view setDocumentView: o_empty_view];
00155 config_ResetAll( p_intf );
00156 [[VLCTreeItem rootItem] resetView];
00157 [[o_tree itemAtRow:[o_tree selectedRow]]
00158 showView:o_prefs_view advancedView:
00159 ( [o_advanced_ckb state] == NSOnState ) ? VLC_TRUE : VLC_FALSE];
00160 }
00161 }
00162
00163 - (IBAction)advancedToggle: (id)sender
00164 {
00165 b_advanced = !b_advanced;
00166 [o_advanced_ckb setState: b_advanced];
00167
00168 [[o_tree itemAtRow:[o_tree selectedRow]] showView:o_prefs_view advancedView:
00169 ( [o_advanced_ckb state] == NSOnState ) ? VLC_TRUE : VLC_FALSE];
00170 }
00171
00172 - (void)loadConfigTree
00173 {
00174 }
00175
00176 - (void)outlineViewSelectionIsChanging:(NSNotification *)o_notification
00177 {
00178 }
00179
00180
00181 - (void)outlineViewSelectionDidChange:(NSNotification *)o_notification
00182 {
00183 [[o_tree itemAtRow:[o_tree selectedRow]] showView: o_prefs_view
00184 advancedView:( [o_advanced_ckb state] == NSOnState ) ?
00185 VLC_TRUE : VLC_FALSE];
00186 }
00187
00188 @end
00189
00190 @implementation VLCPrefs (NSTableDataSource)
00191
00192 - (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
00193 return (item == nil) ? [[VLCTreeItem rootItem] numberOfChildren] :
00194 [item numberOfChildren];
00195 }
00196
00197 - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
00198 {
00199 return (item == nil) ? YES : ( ([item numberOfChildren] != -1) &&
00200 ([item numberOfChildren] != 0));
00201 }
00202
00203 - (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item {
00204 return (item == nil) ? [[VLCTreeItem rootItem] childAtIndex:index] :
00205 [item childAtIndex:index];
00206 }
00207
00208 - (id)outlineView:(NSOutlineView *)outlineView
00209 objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
00210 {
00211 return (item == nil) ? @"" : (id)[item getName];
00212 }
00213
00214 @end
00215
00216 @implementation VLCTreeItem
00217
00218 static VLCTreeItem *o_root_item = nil;
00219
00220 #define IsALeafNode ((id)-1)
00221
00222 - (id)initWithName: (NSString *)o_item_name
00223 withTitle: (NSString *)o_item_title
00224 withHelp: (NSString *)o_item_help
00225 ID: (int)i_id
00226 parent:(VLCTreeItem *)o_parent_item
00227 children:(NSMutableArray *)o_children_array
00228 whithCategory: (int) i_category
00229 {
00230 self = [super init];
00231
00232 if( self != nil )
00233 {
00234 o_name = [o_item_name copy];
00235 o_title= [o_item_title copy];
00236 o_help= [o_item_help copy];
00237 i_object_id = i_id;
00238 o_parent = o_parent_item;
00239 o_children = o_children_array;
00240 i_object_category = i_category;
00241 o_subviews = nil;
00242 }
00243 return( self );
00244 }
00245
00246 + (VLCTreeItem *)rootItem
00247 {
00248 if (o_root_item == nil)
00249 o_root_item = [[VLCTreeItem alloc] initWithName:@"main" withTitle:@"main" withHelp:@"" ID:0
00250 parent:nil children:[[NSMutableArray alloc] initWithCapacity:10]
00251 whithCategory: -1];
00252 return o_root_item;
00253 }
00254
00255 - (void)dealloc
00256 {
00257 if (o_children != IsALeafNode) [o_children release];
00258 [o_name release];
00259 [o_title release];
00260 [o_help release];
00261 [super dealloc];
00262 }
00263
00264
00265
00266 - (NSArray *)children
00267 {
00268 if( o_children == IsALeafNode )
00269 return o_children;
00270 if( [ o_children count] == 0 )
00271 {
00272 intf_thread_t *p_intf = VLCIntf;
00273 vlc_list_t *p_list;
00274 module_t *p_module = NULL;
00275 module_config_t *p_item;
00276 int i_index;
00277
00278
00279 p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
00280 if( !p_list ) return nil;
00281
00282 if( [[self getName] isEqualToString: @"main"] )
00283 {
00284
00285
00286
00287 for( i_index = 0; i_index < p_list->i_count; i_index++ )
00288 {
00289 p_module = (module_t *)p_list->p_values[i_index].p_object;
00290 if( !strcmp( p_module->psz_object_name, "main" ) )
00291 break;
00292 }
00293 if( p_module == NULL )
00294 {
00295 msg_Err( p_intf,
00296 "could not find the main module in our preferences" );
00297 return nil;
00298 }
00299 if( i_index < p_list->i_count )
00300 {
00301
00302
00303
00304 VLCTreeItem *p_last_category = NULL;
00305 p_item = p_module->p_config;
00306 o_children = [[NSMutableArray alloc] initWithCapacity:10];
00307 if( p_item ) do
00308 {
00309 NSString *o_child_name;
00310 NSString *o_child_title;
00311 NSString *o_child_help;
00312 switch( p_item->i_type )
00313 {
00314 case CONFIG_CATEGORY:
00315 o_child_name = [[VLCMain sharedInstance]
00316 localizedString: config_CategoryNameGet( p_item->i_value ) ];
00317 o_child_title = o_child_name;
00318 o_child_help = [[VLCMain sharedInstance]
00319 localizedString: config_CategoryHelpGet( p_item->i_value ) ];
00320 p_last_category = [VLCTreeItem alloc];
00321 [o_children addObject:[p_last_category
00322 initWithName: o_child_name
00323 withTitle: o_child_title
00324 withHelp: o_child_help
00325 ID: p_item->i_value
00326 parent:self
00327 children:[[NSMutableArray alloc]
00328 initWithCapacity:10]
00329 whithCategory: p_item - p_module->p_config]];
00330 break;
00331 case CONFIG_SUBCATEGORY:
00332 o_child_name = [[VLCMain sharedInstance]
00333 localizedString: config_CategoryNameGet( p_item->i_value ) ];
00334 o_child_title = o_child_name;
00335 o_child_help = [[VLCMain sharedInstance]
00336 localizedString: config_CategoryHelpGet( p_item->i_value ) ];
00337 if( p_item->i_value != SUBCAT_PLAYLIST_GENERAL &&
00338 p_item->i_value != SUBCAT_VIDEO_GENERAL &&
00339 p_item->i_value != SUBCAT_AUDIO_GENERAL )
00340 [p_last_category->o_children
00341 addObject:[[VLCTreeItem alloc]
00342 initWithName: o_child_name
00343 withTitle: o_child_title
00344 withHelp: o_child_help
00345 ID: p_item->i_value
00346 parent:p_last_category
00347 children:[[NSMutableArray alloc]
00348 initWithCapacity:10]
00349 whithCategory: p_item - p_module->p_config]];
00350 break;
00351 default:
00352 break;
00353 }
00354 } while( p_item->i_type != CONFIG_HINT_END && p_item++ );
00355 }
00356
00357
00358
00359 for( i_index = 0; i_index < p_list->i_count; i_index++ )
00360 {
00361 p_module = (module_t *)p_list->p_values[i_index].p_object;
00362
00363
00364 if( !strcmp( p_module->psz_object_name, "main" ) )
00365 continue;
00366
00367
00368
00369 if( p_module->b_submodule )
00370 continue;
00371 else
00372 p_item = p_module->p_config;
00373
00374 if( !p_item ) continue;
00375 int i_category = -1;
00376 int i_subcategory = -1;
00377 int i_options = 0;
00378 do
00379 {
00380 if( p_item->i_type == CONFIG_CATEGORY )
00381 i_category = p_item->i_value;
00382 else if( p_item->i_type == CONFIG_SUBCATEGORY )
00383 i_subcategory = p_item->i_value;
00384
00385 if( p_item->i_type & CONFIG_ITEM )
00386 i_options ++;
00387 if( i_options > 0 && i_category >= 0 && i_subcategory >= 0 )
00388 break;
00389 } while( p_item->i_type != CONFIG_HINT_END && p_item++ );
00390 if( !i_options ) continue;
00391
00392
00393
00394 long cookie;
00395 vlc_bool_t b_found = VLC_FALSE;
00396 unsigned int i;
00397 VLCTreeItem* p_category_item, * p_subcategory_item;
00398 for (i = 0 ; i < [o_children count] ; i++)
00399 {
00400 p_category_item = [o_children objectAtIndex: i];
00401 if( p_category_item->i_object_id == i_category )
00402 {
00403 b_found = VLC_TRUE;
00404 break;
00405 }
00406 }
00407 if( !b_found ) continue;
00408
00409
00410 b_found = VLC_FALSE;
00411 cookie = -1;
00412 for (i = 0 ; i < [p_category_item->o_children count] ; i++)
00413 {
00414 p_subcategory_item = [p_category_item->o_children
00415 objectAtIndex: i];
00416 if( p_subcategory_item->i_object_id == i_subcategory )
00417 {
00418 b_found = VLC_TRUE;
00419 break;
00420 }
00421 }
00422 if( !b_found )
00423 p_subcategory_item = p_category_item;
00424
00425 [p_subcategory_item->o_children addObject:[[VLCTreeItem alloc]
00426 initWithName:[[VLCMain sharedInstance]
00427 localizedString: p_module->psz_shortname ?
00428 p_module->psz_shortname : p_module->psz_object_name ]
00429 withTitle:[[VLCMain sharedInstance]
00430 localizedString: p_module->psz_longname ?
00431 p_module->psz_longname : p_module->psz_object_name ]
00432 withHelp: @""
00433 ID: p_module->i_object_id
00434 parent:p_subcategory_item
00435 children:IsALeafNode
00436 whithCategory: -1]];
00437 }
00438 }
00439 vlc_list_release( p_list );
00440 }
00441 return o_children;
00442 }
00443
00444 - (int)getObjectID
00445 {
00446 return i_object_id;
00447 }
00448
00449 - (NSString *)getName
00450 {
00451 return o_name;
00452 }
00453
00454 - (NSString *)getTitle
00455 {
00456 return o_title;
00457 }
00458
00459 - (NSString *)getHelp
00460 {
00461 return o_help;
00462 }
00463
00464 - (VLCTreeItem *)childAtIndex:(int)i_index
00465 {
00466 return [[self children] objectAtIndex:i_index];
00467 }
00468
00469 - (int)numberOfChildren {
00470 id i_tmp = [self children];
00471 return (i_tmp == IsALeafNode) ? (-1) : (int)[i_tmp count];
00472 }
00473
00474 - (BOOL)hasPrefs:(NSString *)o_module_name
00475 {
00476 intf_thread_t *p_intf = VLCIntf;
00477 module_t *p_parser;
00478 vlc_list_t *p_list;
00479 char *psz_module_name;
00480 int i_index;
00481
00482 psz_module_name = (char *)[o_module_name UTF8String];
00483
00484
00485 p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
00486
00487 for( i_index = 0; i_index < p_list->i_count; i_index++ )
00488 {
00489 p_parser = (module_t *)p_list->p_values[i_index].p_object ;
00490
00491 if( !strcmp( p_parser->psz_object_name, psz_module_name ) )
00492 {
00493 BOOL b_has_prefs = p_parser->i_config_items != 0;
00494 vlc_list_release( p_list );
00495 return( b_has_prefs );
00496 }
00497 }
00498
00499 vlc_list_release( p_list );
00500
00501 return( NO );
00502 }
00503
00504 - (NSView *)showView:(NSScrollView *)o_prefs_view
00505 advancedView:(vlc_bool_t) b_advanced
00506 {
00507 NSRect s_vrc;
00508 NSView *o_view;
00509
00510 [[VLCPrefs sharedInstance] setTitle: [self getTitle]];
00511
00512 s_vrc = [[o_prefs_view contentView] bounds]; s_vrc.size.height -= 4;
00513 o_view = [[VLCFlippedView alloc] initWithFrame: s_vrc];
00514 [o_view setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin |
00515 NSViewMaxYMargin];
00516
00517
00518
00519 if( o_subviews == nil )
00520 {
00521 intf_thread_t *p_intf = VLCIntf;
00522 vlc_list_t *p_list;
00523 module_t *p_parser = NULL;
00524 module_config_t *p_item;
00525
00526 o_subviews = [[NSMutableArray alloc] initWithCapacity:10];
00527
00528 if( i_object_category == -1 )
00529 {
00530 p_parser = (module_t *) vlc_object_get( p_intf, i_object_id );
00531 if( !p_parser || p_parser->i_object_type != VLC_OBJECT_MODULE )
00532 {
00533
00534 return nil;
00535 }
00536 p_item = p_parser->p_config;
00537 int i = 0;
00538
00539 p_item = p_parser->p_config + 1;
00540
00541 do
00542 {
00543 if( !p_item )
00544 {
00545 msg_Err( p_intf, "null item found" );
00546 break;
00547 }
00548 switch(p_item->i_type)
00549 {
00550 case CONFIG_SUBCATEGORY:
00551 break;
00552 case CONFIG_CATEGORY:
00553 break;
00554 case CONFIG_SECTION:
00555 break;
00556 case CONFIG_HINT_END:
00557 break;
00558 case CONFIG_HINT_USAGE:
00559 break;
00560 default:
00561 {
00562 VLCConfigControl *o_control = nil;
00563 o_control = [VLCConfigControl newControl:p_item
00564 withView:o_view];
00565 if( o_control != nil )
00566 {
00567 [o_control setAutoresizingMask: NSViewMaxYMargin |
00568 NSViewWidthSizable];
00569 [o_subviews addObject: o_control];
00570 }
00571 }
00572 break;
00573 }
00574 } while( p_item++->i_type != CONFIG_HINT_END );
00575
00576 vlc_object_release( p_parser );
00577 }
00578 else
00579 {
00580 int i = 0;
00581 int i_index;
00582 p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
00583 if( !p_list ) return o_view;
00584
00585
00586
00587
00588 for( i_index = 0; i_index < p_list->i_count; i_index++ )
00589 {
00590 p_parser = (module_t *)p_list->p_values[i_index].p_object;
00591 if( !strcmp( p_parser->psz_object_name, "main" ) )
00592 break;
00593 }
00594 if( p_parser == NULL )
00595 {
00596 msg_Err( p_intf, "could not find the main module in our "
00597 "preferences" );
00598 return o_view;
00599 }
00600 p_item = (p_parser->p_config + i_object_category);
00601 if( ( p_item->i_type == CONFIG_CATEGORY ) &&
00602 ( ( p_item->i_value == CAT_PLAYLIST ) ||
00603 ( p_item->i_value == CAT_AUDIO ) ||
00604 ( p_item->i_value == CAT_VIDEO ) ) )
00605 p_item++;
00606
00607 do
00608 {
00609 p_item++;
00610 if( !p_item )
00611 {
00612 msg_Err( p_intf, "null item found" );
00613 break;
00614 }
00615 switch( p_item->i_type )
00616 {
00617 case CONFIG_SUBCATEGORY:
00618 break;
00619 case CONFIG_CATEGORY:
00620 break;
00621 case CONFIG_SECTION:
00622 break;
00623 case CONFIG_HINT_END:
00624 break;
00625 case CONFIG_HINT_USAGE:
00626 break;
00627 default:
00628 {
00629 VLCConfigControl *o_control = nil;
00630 o_control = [VLCConfigControl newControl:p_item
00631 withView:o_view];
00632 if( o_control != nil )
00633 {
00634 [o_control setAutoresizingMask: NSViewMaxYMargin |
00635 NSViewWidthSizable];
00636 [o_subviews addObject: o_control];
00637 }
00638 break;
00639 }
00640 }
00641 } while ( ( p_item->i_type != CONFIG_HINT_END ) &&
00642 ( p_item->i_type != CONFIG_SUBCATEGORY ) );
00643
00644 vlc_list_release( p_list );
00645 }
00646 }
00647
00648 if( o_view != nil )
00649 {
00650 int i_lastItem = 0;
00651 int i_yPos = -2;
00652 int i_max_label = 0;
00653 int i_show_advanced = 0;
00654
00655 NSEnumerator *enumerator = [o_subviews objectEnumerator];
00656 VLCConfigControl *o_widget;
00657 NSRect o_frame;
00658
00659 while( ( o_widget = [enumerator nextObject] ) )
00660 if( ( [o_widget isAdvanced] ) && (! b_advanced) )
00661 continue;
00662 else if( i_max_label < [o_widget getLabelSize] )
00663 i_max_label = [o_widget getLabelSize];
00664
00665 enumerator = [o_subviews objectEnumerator];
00666 while( ( o_widget = [enumerator nextObject] ) )
00667 {
00668 int i_widget;
00669 if( ( [o_widget isAdvanced] ) && (! b_advanced) )
00670 {
00671 i_show_advanced++;
00672 continue;
00673 }
00674
00675 i_widget = [o_widget getViewType];
00676 i_yPos += [VLCConfigControl calcVerticalMargin:i_widget
00677 lastItem:i_lastItem];
00678 [o_widget setYPos:i_yPos];
00679 o_frame = [o_widget frame];
00680 o_frame.size.width = [o_view frame].size.width -
00681 LEFTMARGIN - RIGHTMARGIN;
00682 [o_widget setFrame:o_frame];
00683 [o_widget alignWithXPosition: i_max_label];
00684 i_yPos += [o_widget frame].size.height;
00685 i_lastItem = i_widget;
00686 [o_view addSubview:o_widget];
00687 }
00688 if( i_show_advanced != 0 )
00689 {
00690
00691 NSRect s_rc = [o_view frame];
00692 NSTextField *o_label;
00693 s_rc.size.height = 17;
00694 s_rc.origin.x = LEFTMARGIN;
00695 s_rc.origin.y = i_yPos += [VLCConfigControl
00696 calcVerticalMargin:CONFIG_ITEM_STRING
00697 lastItem:i_lastItem];
00698 o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];
00699 [o_label setDrawsBackground: NO];
00700 [o_label setBordered: NO];
00701 [o_label setEditable: NO];
00702 [o_label setSelectable: NO];
00703 [o_label setStringValue: _NS("Some options are available but " \
00704 "hidden. Check \"Advanced\" to see them.")];
00705 [o_label setFont:[NSFont systemFontOfSize:10]];
00706 [o_label sizeToFit];
00707 [o_view addSubview:o_label];
00708 i_yPos += [o_label frame].size.height;
00709 }
00710 o_frame = [o_view frame];
00711 o_frame.size.height = i_yPos;
00712 [o_view setFrame:o_frame];
00713 [o_prefs_view setDocumentView:o_view];
00714
00715 }
00716 return o_view;
00717 }
00718
00719 - (void)applyChanges
00720 {
00721 unsigned int i;
00722 if( o_subviews != nil )
00723
00724 for( i = 0 ; i < [o_subviews count] ; i++ )
00725 [[o_subviews objectAtIndex:i] applyChanges];
00726
00727 if( o_children != IsALeafNode )
00728 for( i = 0 ; i < [o_children count] ; i++ )
00729 [[o_children objectAtIndex:i] applyChanges];
00730 }
00731
00732 - (void)resetView
00733 {
00734 unsigned int i;
00735 if( o_subviews != nil )
00736 {
00737
00738 [o_subviews release];
00739 o_subviews = nil;
00740 }
00741
00742 if( o_children != IsALeafNode )
00743 for( i = 0 ; i < [o_children count] ; i++ )
00744 [[o_children objectAtIndex:i] resetView];
00745 }
00746
00747 @end
00748
00749
00750 @implementation VLCFlippedView
00751
00752 - (BOOL)isFlipped
00753 {
00754 return( YES );
00755 }
00756
00757 @end