1 /*****************************************************************************
2 * simple_prefs.m: Simple Preferences for Mac OS X
3 *****************************************************************************
4 * Copyright (C) 2008 the VideoLAN team
7 * Authors: Felix Paul Kühne <fkuehne at videolan dot org>
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #import "simple_prefs.h"
28 static NSString* VLCSPrefsToolbarIdentifier = @"Our Simple Preferences Toolbar Identifier";
29 static NSString* VLCIntfSettingToolbarIdentifier = @"Intf Settings Item Identifier";
30 static NSString* VLCAudioSettingToolbarIdentifier = @"Audio Settings Item Identifier";
31 static NSString* VLCVideoSettingToolbarIdentifier = @"Video Settings Item Identifier";
32 static NSString* VLCOSDSettingToolbarIdentifier = @"Subtitles Settings Item Identifier";
33 static NSString* VLCInputSettingToolbarIdentifier = @"Input Settings Item Identifier";
34 static NSString* VLCHotkeysSettingToolbarIdentifier = @"Hotkeys Settings Item Identifier";
36 @implementation VLCSimplePrefs
38 static VLCSimplePrefs *_o_sharedInstance = nil;
40 + (VLCSimplePrefs *)sharedInstance
42 return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
47 if (_o_sharedInstance) {
51 _o_sharedInstance = [super init];
54 return _o_sharedInstance;
59 [o_currentlyShownCategoryView release];
60 [o_sprefs_toolbar release];
62 [o_hotkeySettings release];
63 [o_hotkeyDescriptions release];
69 - (NSString *)OSXKeyToString:(int)val
71 NSMutableString *o_temp_str = [[[NSMutableString alloc] init] autorelease];
72 if( val & KEY_MODIFIER_CTRL )
73 [o_temp_str appendString: @"Ctrl+"];
74 if( val & KEY_MODIFIER_ALT )
75 [o_temp_str appendString: @"Alt+"];
76 if( val & KEY_MODIFIER_SHIFT )
77 [o_temp_str appendString: @"Shift+"];
78 if( val & KEY_MODIFIER_COMMAND )
79 [o_temp_str appendString: @"Command+"];
81 unsigned int i_keys = sizeof(vlc_keys)/sizeof(key_descriptor_t);
82 for( unsigned int i = 0; i< i_keys; i++ )
84 if( vlc_keys[i].i_key_code == (val& ~KEY_MODIFIER) )
86 [o_temp_str appendString: [NSString stringWithUTF8String: vlc_keys[i].psz_key_string]];
96 /* setup the toolbar */
97 o_sprefs_toolbar = [[[NSToolbar alloc] initWithIdentifier: VLCSPrefsToolbarIdentifier] autorelease];
98 [o_sprefs_toolbar setAllowsUserCustomization: NO];
99 [o_sprefs_toolbar setAutosavesConfiguration: NO];
100 [o_sprefs_toolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
101 [o_sprefs_toolbar setSizeMode: NSToolbarSizeModeRegular];
102 [o_sprefs_toolbar setDelegate: self];
103 [o_sprefs_win setToolbar: o_sprefs_toolbar];
106 - (NSToolbarItem *) toolbar: (NSToolbar *)o_sprefs_toolbar
107 itemForItemIdentifier: (NSString *)o_itemIdent
108 willBeInsertedIntoToolbar: (BOOL)b_willBeInserted
110 NSToolbarItem *o_toolbarItem = nil;
112 #define CreateToolbarItem( o_name, o_desc, o_img, sel ) \
113 o_toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: o_itemIdent] autorelease]; \
115 [o_toolbarItem setLabel: o_name]; \
116 [o_toolbarItem setPaletteLabel: o_desc]; \
118 [o_toolbarItem setToolTip: o_desc]; \
119 [o_toolbarItem setImage: [NSImage imageNamed: o_img]]; \
121 [o_toolbarItem setTarget: self]; \
122 [o_toolbarItem setAction: @selector( sel )]; \
124 [o_toolbarItem setEnabled: YES]; \
125 [o_toolbarItem setAutovalidates: YES]
127 if( [o_itemIdent isEqual: VLCIntfSettingToolbarIdentifier] )
129 CreateToolbarItem( _NS("Interface"), _NS("Interface Settings"), @"spref_cone_Interface_64", showInterfaceSettings );
131 else if( [o_itemIdent isEqual: VLCAudioSettingToolbarIdentifier] )
133 CreateToolbarItem( _NS("Audio"), _NS("General Audio Settings"), @"spref_cone_Audio_64", showAudioSettings );
135 else if( [o_itemIdent isEqual: VLCVideoSettingToolbarIdentifier] )
137 CreateToolbarItem( _NS("Video"), _NS("General Video Settings"), @"spref_cone_Video_64", showVideoSettings );
139 else if( [o_itemIdent isEqual: VLCOSDSettingToolbarIdentifier] )
141 CreateToolbarItem( _NS("Subtitles & OSD"), _NS("Subtitles & OSD Settings"), @"spref_cone_Subtitles_64", showOSDSettings );
143 else if( [o_itemIdent isEqual: VLCInputSettingToolbarIdentifier] )
145 CreateToolbarItem( _NS("Input & Codecs"), _NS("Input & Codec settings"), @"spref_cone_Input_64", showInputSettings );
147 else if( [o_itemIdent isEqual: VLCHotkeysSettingToolbarIdentifier] )
149 CreateToolbarItem( _NS("Hotkeys"), _NS("Hotkeys settings"), @"spref_cone_Hotkeys_64", showHotkeySettings );
152 return o_toolbarItem;
155 - (NSArray *)toolbarDefaultItemIdentifiers: (NSToolbar *)toolbar
157 return [NSArray arrayWithObjects: VLCIntfSettingToolbarIdentifier, VLCAudioSettingToolbarIdentifier, VLCVideoSettingToolbarIdentifier,
158 VLCOSDSettingToolbarIdentifier, VLCInputSettingToolbarIdentifier, VLCHotkeysSettingToolbarIdentifier, NSToolbarFlexibleSpaceItemIdentifier, nil];
161 - (NSArray *)toolbarAllowedItemIdentifiers: (NSToolbar *)toolbar
163 return [NSArray arrayWithObjects: VLCIntfSettingToolbarIdentifier, VLCAudioSettingToolbarIdentifier, VLCVideoSettingToolbarIdentifier,
164 VLCOSDSettingToolbarIdentifier, VLCInputSettingToolbarIdentifier, VLCHotkeysSettingToolbarIdentifier, NSToolbarFlexibleSpaceItemIdentifier, nil];
167 - (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
169 return [NSArray arrayWithObjects: VLCIntfSettingToolbarIdentifier, VLCAudioSettingToolbarIdentifier, VLCVideoSettingToolbarIdentifier,
170 VLCOSDSettingToolbarIdentifier, VLCInputSettingToolbarIdentifier, VLCHotkeysSettingToolbarIdentifier, nil];
175 msg_Warn( p_intf, "localisation of the simple preferences is not implemented!" );
178 - (void)resetControls
180 module_config_t *p_item;
184 #define SetupIntList( object, name ) \
185 [object removeAllItems]; \
186 p_item = config_FindConfig( VLC_OBJECT(p_intf), name ); \
187 for( i = 0; i < p_item->i_list; i++ ) \
189 if( p_item->ppsz_list_text[i] != NULL) \
190 [object addItemWithTitle: _NS( p_item->ppsz_list_text[i] )]; \
192 [object addItemWithTitle: [NSString stringWithUTF8String: p_item->ppsz_list[i]]]; \
194 if( p_item->value.i < [object numberOfItems] ) \
195 [object selectItemAtIndex: p_item->value.i]; \
197 [object selectItemAtIndex: 0]
199 #define SetupStringList( object, name ) \
200 [object removeAllItems]; \
202 p_item = config_FindConfig( VLC_OBJECT(p_intf), name ); \
203 for( i = 0; p_item->ppsz_list[i] != nil; i++ ) \
205 [object addItemWithTitle: _NS( p_item->ppsz_list_text[i] )]; \
206 if( p_item->value.psz && !strcmp( p_item->value.psz, p_item->ppsz_list[i] ) ) \
209 [object selectItemAtIndex: y]
211 /**********************
212 * interface settings *
213 **********************/
214 SetupStringList( o_intf_lang_pop, "language" );
215 SetupIntList( o_intf_art_pop, "album-art" );
217 [o_intf_meta_ckb setState: config_GetInt( p_intf, "fetch-meta" )];
218 [o_intf_fspanel_ckb setState: config_GetInt( p_intf, "macosx-fspanel" )];
219 [o_intf_embedded_ckb setState: config_GetInt( p_intf, "embedded-video" )];
224 [o_audio_enable_ckb setState: config_GetInt( p_intf, "audio" )];
225 [o_audio_vol_fld setIntValue: config_GetInt( p_intf, "volume" )];
226 [o_audio_vol_sld setIntValue: config_GetInt( p_intf, "volume" )];
228 [o_audio_spdif_ckb setState: config_GetInt( p_intf, "spdif" )];
230 SetupIntList( o_audio_dolby_pop, "force-dolby-surround" );
232 [o_audio_lang_fld setStringValue: [NSString stringWithUTF8String: config_GetPsz( p_intf, "audio-language" )]];
234 [o_audio_headphone_ckb setState: config_GetInt( p_intf, "headphone-dolby" )];
236 psz_tmp = config_GetPsz( p_intf, "audio-filter" );
238 [o_audio_norm_ckb setState: (int)strstr( psz_tmp, "normvol" )];
239 [o_audio_norm_fld setFloatValue: config_GetFloat( p_intf, "norm-max-level" )];
242 msg_Warn( p_intf, "visualizer not implemented!" );
244 /* Last.FM is optional */
245 if( module_Exists( p_intf, "audioscrobbler" ) )
247 [o_audio_lastuser_fld setStringValue: [NSString stringWithUTF8String: config_GetPsz( p_intf, "lastfm-username" )]];
248 [o_audio_lastpwd_fld setStringValue: [NSString stringWithUTF8String: config_GetPsz( p_intf, "lastfm-password" )]];
250 if( config_ExistIntf( VLC_OBJECT( p_intf ), "audioscrobbler" ) )
251 [o_audio_last_ckb setState: NSOnState];
253 [o_audio_last_ckb setState: NSOffState];
259 [o_video_enable_ckb setState: config_GetInt( p_intf, "video" )];
260 [o_video_fullscreen_ckb setState: config_GetInt( p_intf, "fullscreen" )];
261 [o_video_onTop_ckb setState: config_GetInt( p_intf, "video-on-top" )];
262 [o_video_skipFrames_ckb setState: config_GetInt( p_intf, "skip-frames" )];
263 [o_video_black_ckb setState: config_GetInt( p_intf, "macosx-black" )];
265 msg_Warn( p_intf, "vout module and display device selectors not implemented!" );
267 if( config_GetPsz( p_intf, "snapshot-path" ) != NULL )
268 [o_video_snap_folder_fld setStringValue: [NSString stringWithUTF8String: config_GetPsz( p_intf, "snapshot-path" )]];
269 [o_video_snap_prefix_fld setStringValue: [NSString stringWithUTF8String: config_GetPsz( p_intf, "snapshot-prefix" )]];
270 [o_video_snap_seqnum_ckb setState: config_GetInt( p_intf, "snapshot-sequential" )];
272 p_item = config_FindConfig( VLC_OBJECT(p_intf), "snapshot-format" );
273 for( i = 0; p_item->ppsz_list[i] != nil; i++ )
275 [o_video_snap_format_pop addItemWithTitle: [NSString stringWithUTF8String: p_item->ppsz_list[i]]];
276 if( p_item->value.psz && !strcmp( p_item->value.psz, p_item->ppsz_list[i] ) )
279 [o_video_snap_format_pop selectItemAtIndex: y];
281 /***************************
282 * input & codecs settings *
283 ***************************/
284 [o_input_serverport_fld setIntValue: config_GetInt( p_intf, "server-port" )];
285 if( config_GetPsz( p_intf, "http-proxy" ) != NULL )
286 [o_input_httpproxy_fld setStringValue: [NSString stringWithUTF8String: config_GetPsz( p_intf, "http-proxy" )]];
287 [o_input_postproc_fld setIntValue: config_GetInt( p_intf, "ffmpeg-pp-q" )];
289 SetupIntList( o_input_avi_pop, "avi-index" );
291 [o_input_rtsp_ckb setState: config_GetInt( p_intf, "rtsp-tcp" )];
293 psz_tmp = config_GetPsz( p_intf, "access-filter" );
296 [o_input_record_ckb setState: (int)strstr( psz_tmp, "record" )];
297 [o_input_dump_ckb setState: (int)strstr( psz_tmp, "dump" )];
298 [o_input_bandwidth_ckb setState: (int)strstr( psz_tmp, "bandwidth" )];
299 [o_input_timeshift_ckb setState: (int)strstr( psz_tmp, "timeshift" )];
302 [o_input_cachelevel_pop removeAllItems];
303 [o_input_cachelevel_pop addItemsWithTitles:
304 [NSArray arrayWithObjects: _NS("Custom"), _NS("Lowest latency"), _NS("Low latency"), _NS("Normal"),
305 _NS("High latency"), _NS("Higher latency"), nil]];
306 [[o_input_cachelevel_pop itemAtIndex: 0] setTag: 0];
307 [[o_input_cachelevel_pop itemAtIndex: 1] setTag: 100];
308 [[o_input_cachelevel_pop itemAtIndex: 2] setTag: 200];
309 [[o_input_cachelevel_pop itemAtIndex: 3] setTag: 300];
310 [[o_input_cachelevel_pop itemAtIndex: 4] setTag: 400];
311 [[o_input_cachelevel_pop itemAtIndex: 5] setTag: 500];
313 #define TestCaC( name ) \
314 b_cache_equal = b_cache_equal && \
315 ( i_cache == config_GetInt( p_intf, name ) )
317 #define TestCaCi( name, int ) \
318 b_cache_equal = b_cache_equal && \
319 ( ( i_cache * int ) == config_GetInt( p_intf, name ) )
321 /* Select the accurate value of the PopupButton */
322 bool b_cache_equal = true;
323 int i_cache = config_GetInt( p_intf, "file-caching");
325 TestCaC( "udp-caching" );
326 if( module_Exists (p_intf, "dvdread") )
327 TestCaC( "dvdread-caching" );
328 if( module_Exists (p_intf, "dvdnav") )
329 TestCaC( "dvdnav-caching" );
330 TestCaC( "tcp-caching" );
331 TestCaC( "fake-caching" );
332 TestCaC( "cdda-caching" );
333 TestCaC( "screen-caching" );
334 TestCaC( "vcd-caching" );
335 TestCaCi( "rtsp-caching", 4 );
336 TestCaCi( "ftp-caching", 2 );
337 TestCaCi( "http-caching", 4 );
338 if(module_Exists (p_intf, "access_realrtsp"))
339 TestCaCi( "realrtsp-caching", 10 );
340 TestCaCi( "mms-caching", 19 );
342 [o_input_cachelevel_pop selectItemWithTag: i_cache];
344 [o_input_cachelevel_pop selectItemWithTitle: _NS("Custom")];
346 /*********************
347 * subtitle settings *
348 *********************/
349 [o_osd_osd_ckb setState: config_GetInt( p_intf, "osd" )];
351 [o_osd_encoding_pop removeAllItems];
353 p_item = config_FindConfig( VLC_OBJECT(p_intf), "subsdec-encoding" );
354 for( i = 0; p_item->ppsz_list[i] != nil; i++ )
356 if( p_item->ppsz_list[i] != "" )
357 [o_osd_encoding_pop addItemWithTitle: _NS( p_item->ppsz_list[i] )];
359 [o_osd_encoding_pop addItemWithTitle: @" "];
361 if( p_item->value.psz && !strcmp( p_item->value.psz, p_item->ppsz_list[i] ) )
364 [o_osd_encoding_pop selectItemAtIndex: y];
366 [o_osd_lang_fld setStringValue: [NSString stringWithUTF8String: config_GetPsz( p_intf, "sub-language" )]];
367 if( config_GetPsz( p_intf, "freetype-font" ) != NULL )
368 [o_osd_font_fld setStringValue: [NSString stringWithUTF8String: config_GetPsz( p_intf, "freetype-font" )]];
370 SetupIntList( o_osd_font_color_pop, "freetype-color" );
371 SetupIntList( o_osd_font_size_pop, "freetype-rel-fontsize" );
372 SetupIntList( o_osd_font_effect_pop, "freetype-effect" );
374 /********************
376 ********************/
377 struct hotkey *p_hotkeys = p_intf->p_libvlc->p_hotkeys;
378 o_hotkeySettings = [[NSMutableArray alloc] init];
379 NSMutableArray *o_tempArray_desc = [[NSMutableArray alloc] init];
384 p_item = config_FindConfig( VLC_OBJECT(p_intf), p_hotkeys[i].psz_action );
388 [o_tempArray_desc addObject: _NS( p_item->psz_text )];
389 [o_hotkeySettings addObject: [self OSXKeyToString: p_item->value.i]];
393 o_hotkeyDescriptions = [[NSArray alloc] initWithArray: o_tempArray_desc copyItems: YES];
394 [o_tempArray_desc release];
395 [o_hotkeys_listbox reloadData];
398 - (void)showSimplePrefs
400 /* we want to show the interface settings, if no category was chosen */
401 if( [o_sprefs_toolbar selectedItemIdentifier] == nil )
403 [o_sprefs_toolbar setSelectedItemIdentifier: VLCIntfSettingToolbarIdentifier];
404 [self showInterfaceSettings];
407 [self resetControls];
409 [o_sprefs_win makeKeyAndOrderFront: self];
412 - (IBAction)buttonAction:(id)sender
414 if( sender == o_sprefs_cancel_btn )
415 [o_sprefs_win orderOut: sender];
416 else if( sender == o_sprefs_save_btn )
418 [self saveChangedSettings];
419 [o_sprefs_win orderOut: sender];
421 else if( sender == o_sprefs_reset_btn )
422 NSBeginInformationalAlertSheet( _NS("Reset Preferences"), _NS("Cancel"),
423 _NS("Continue"), nil, o_sprefs_win, self,
424 @selector(sheetDidEnd: returnCode: contextInfo:), NULL, nil,
425 _NS("Beware this will reset the VLC media player preferences.\n"
426 "Are you sure you want to continue?") );
427 else if( sender == o_sprefs_basicFull_matrix )
429 [o_sprefs_win orderOut: self];
430 [[[VLCMain sharedInstance] getPreferences] showPrefs];
431 [self resetControls];
434 msg_Err( p_intf, "unknown buttonAction sender" );
437 - (void)sheetDidEnd:(NSWindow *)o_sheet
438 returnCode:(int)i_return
439 contextInfo:(void *)o_context
441 if( i_return == NSAlertAlternateReturn )
443 config_ResetAll( p_intf );
444 b_intfSettingChanged = b_videoSettingChanged = b_audioSettingChanged = YES;
445 [self resetControls];
449 - (void)saveChangedSettings
451 module_config_t *p_item;
455 #define SaveIntList( object, name ) \
456 p_item = config_FindConfig( VLC_OBJECT(p_intf), name ); \
457 if( [object indexOfSelectedItem] >= 0 ) \
458 config_PutInt( p_intf, name, p_item->pi_list[[object indexOfSelectedItem]] ); \
460 config_PutInt( p_intf, name, [object intValue] ) \
462 #define SaveStringList( object, name ) \
463 p_item = config_FindConfig( VLC_OBJECT(p_intf), name ); \
464 if( [object indexOfSelectedItem] >= 0 ) \
465 config_PutPsz( p_intf, name, strdup( p_item->ppsz_list[[object indexOfSelectedItem]] ) ); \
467 config_PutPsz( p_intf, name, strdup( [[VLCMain sharedInstance] delocalizeString: [object stringValue]] ) )
469 /**********************
470 * interface settings *
471 **********************/
472 if( b_intfSettingChanged )
474 SaveStringList( o_intf_lang_pop, "language" );
475 SaveIntList( o_intf_art_pop, "album-art" );
477 config_PutInt( p_intf, "fetch-meta", [o_intf_meta_ckb state] );
478 config_PutInt( p_intf, "macosx-fspanel", [o_intf_fspanel_ckb state] );
479 config_PutInt( p_intf, "embedded-video", [o_intf_embedded_ckb state] );
481 /* okay, let's save our changes to vlcrc */
482 i = config_SaveConfigFile( p_intf, "main" );
483 i = config_SaveConfigFile( p_intf, "macosx" );
487 msg_Err( p_intf, "An error occured while saving the Interface settings using SimplePrefs" );
491 b_intfSettingChanged = NO;
497 if( b_audioSettingChanged )
499 config_PutInt( p_intf, "audio", [o_audio_enable_ckb state] );
500 config_PutInt( p_intf, "volume", [o_audio_vol_sld intValue] );
501 config_PutInt( p_intf, "spdif", [o_audio_spdif_ckb state] );
503 SaveIntList( o_audio_dolby_pop, "force-dolby-surround" );
505 config_PutPsz( p_intf, "audio-language", [[o_audio_lang_fld stringValue] UTF8String] );
506 config_PutInt( p_intf, "headphone-dolby", [o_audio_headphone_ckb state] );
508 psz_tmp = config_GetPsz( p_intf, "audio-filter" );
510 config_PutPsz( p_intf, "audio-filter", "volnorm" );
511 else if( (int)strstr( psz_tmp, "normvol" ) == NO )
513 /* work-around a GCC 4.0.1 bug */
514 psz_tmp = (char *)[[NSString stringWithFormat: @"%s:volnorm", psz_tmp] UTF8String];
515 config_PutPsz( p_intf, "audio-filter", psz_tmp );
519 psz_tmp = (char *)[[[NSString stringWithUTF8String: psz_tmp] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@":volnorm"]] UTF8String];
520 psz_tmp = (char *)[[[NSString stringWithUTF8String: psz_tmp] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"volnorm:"]] UTF8String];
521 psz_tmp = (char *)[[[NSString stringWithUTF8String: psz_tmp] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"volnorm"]] UTF8String];
522 config_PutPsz( p_intf, "audio-filter", psz_tmp );
524 config_PutFloat( p_intf, "norm-max-level", [o_audio_norm_fld floatValue] );
526 msg_Warn( p_intf, "visualizer not implemented!" );
528 /* Last.FM is optional */
529 if( module_Exists( p_intf, "audioscrobbler" ) )
531 if( [o_audio_last_ckb state] == NSOnState )
532 config_AddIntf( VLC_OBJECT( p_intf ), "audioscrobbler" );
534 config_RemoveIntf( VLC_OBJECT( p_intf ), "audioscrobbler" );
536 config_PutPsz( p_intf, "lastfm-username", [[o_audio_lastuser_fld stringValue] UTF8String] );
537 config_PutPsz( p_intf, "lastfm-password", [[o_audio_lastuser_fld stringValue] UTF8String] );
540 /* okay, let's save our changes to vlcrc */
541 i = config_SaveConfigFile( p_intf, "main" );
542 i = i + config_SaveConfigFile( p_intf, "audioscrobbler" );
543 i = i + config_SaveConfigFile( p_intf, "volnorm" );
547 msg_Err( p_intf, "An error occured while saving the Audio settings using SimplePrefs" );
550 b_audioSettingChanged = NO;
556 if( b_videoSettingChanged )
558 config_PutInt( p_intf, "video", [o_video_enable_ckb state] );
559 config_PutInt( p_intf, "fullscreen", [o_video_fullscreen_ckb state] );
560 config_PutInt( p_intf, "video-on-top", [o_video_onTop_ckb state] );
561 config_PutInt( p_intf, "skip-frames", [o_video_skipFrames_ckb state] );
562 config_PutInt( p_intf, "macosx-black", [o_video_black_ckb state] );
564 msg_Warn( p_intf, "vout module and display device selectors not implemented!" );
566 config_PutPsz( p_intf, "snapshot-path", [[o_video_snap_folder_fld stringValue] UTF8String] );
567 config_PutPsz( p_intf, "snapshot-prefix", [[o_video_snap_prefix_fld stringValue] UTF8String] );
568 config_PutInt( p_intf, "snapshot-sequential", [o_video_snap_seqnum_ckb state] );
570 if( [o_video_snap_format_pop indexOfSelectedItem] >= 0 )
571 config_PutPsz( p_intf, "snapshot-format", [[[o_video_snap_format_pop selectedItem] title] UTF8String] );
573 i = config_SaveConfigFile( p_intf, "main" );
574 i = i + config_SaveConfigFile( p_intf, "macosx" );
578 msg_Err( p_intf, "An error occured while saving the Video settings using SimplePrefs" );
581 b_videoSettingChanged = NO;
584 /***************************
585 * input & codecs settings *
586 ***************************/
587 if( b_inputSettingChanged )
589 config_PutInt( p_intf, "server-port", [o_input_serverport_fld intValue] );
590 config_PutPsz( p_intf, "http-proxy", [[o_input_httpproxy_fld stringValue] UTF8String] );
591 config_PutInt( p_intf, "ffmpeg-pp-q", [o_input_postproc_fld intValue] );
593 SaveIntList( o_input_avi_pop, "avi-index" );
595 config_PutInt( p_intf, "rtsp-tcp", [o_input_rtsp_ckb state] );
597 #define CaCi( name, int ) config_PutInt( p_intf, name, int * [[o_input_cachelevel_pop selectedItem] tag] )
598 #define CaC( name ) CaCi( name, 1 )
599 msg_Dbg( p_intf, "Adjusting all cache values at: %i", [[o_input_cachelevel_pop selectedItem] tag] );
600 CaC( "udp-caching" );
601 if( module_Exists (p_intf, "dvdread" ) )
603 CaC( "dvdread-caching" );
604 i = i + config_SaveConfigFile( p_intf, "dvdread" );
606 if( module_Exists (p_intf, "dvdnav" ) )
608 CaC( "dvdnav-caching" );
609 i = i + config_SaveConfigFile( p_intf, "dvdnav" );
611 CaC( "tcp-caching" ); CaC( "vcd-caching" );
612 CaC( "fake-caching" ); CaC( "cdda-caching" ); CaC( "file-caching" );
613 CaC( "screen-caching" );
614 CaCi( "rtsp-caching", 4 ); CaCi( "ftp-caching", 2 );
615 CaCi( "http-caching", 4 );
616 if( module_Exists (p_intf, "access_realrtsp" ) )
618 CaCi( "realrtsp-caching", 10 );
619 i = i + config_SaveConfigFile( p_intf, "access_realrtsp" );
621 CaCi( "mms-caching", 19 );
623 #define SaveAccessFilter( object, name ) \
624 if( [object state] == NSOnState ) \
628 [o_temp appendString: name]; \
632 [o_temp appendFormat: @":%@", name]; \
636 NSMutableString *o_temp = [[NSMutableString alloc] init];
637 SaveAccessFilter( o_input_record_ckb, @"record" );
638 SaveAccessFilter( o_input_dump_ckb, @"dump" );
639 SaveAccessFilter( o_input_bandwidth_ckb, @"bandwidth" );
640 SaveAccessFilter( o_input_timeshift_ckb, @"timeshift" );
641 config_PutPsz( p_intf, "access-filter", [o_temp UTF8String] );
644 i = config_SaveConfigFile( p_intf, "main" );
645 i = i + config_SaveConfigFile( p_intf, "ffmpeg" );
646 i = i + config_SaveConfigFile( p_intf, "access_http" );
647 i = i + config_SaveConfigFile( p_intf, "access_file" );
648 i = i + config_SaveConfigFile( p_intf, "access_tcp" );
649 i = i + config_SaveConfigFile( p_intf, "access_fake" );
650 i = i + config_SaveConfigFile( p_intf, "cdda" );
651 i = i + config_SaveConfigFile( p_intf, "screen" );
652 i = i + config_SaveConfigFile( p_intf, "vcd" );
653 i = i + config_SaveConfigFile( p_intf, "access_ftp" );
654 i = i + config_SaveConfigFile( p_intf, "access_mms" );
655 i = i + config_SaveConfigFile( p_intf, "live555" );
659 msg_Err( p_intf, "An error occured while saving the Input settings using SimplePrefs" );
662 b_inputSettingChanged = NO;
665 /**********************
666 * subtitles settings *
667 **********************/
668 if( b_osdSettingChanged )
670 config_PutInt( p_intf, "osd", [o_osd_osd_ckb state] );
672 if( [o_osd_encoding_pop indexOfSelectedItem] >= 0 )
673 config_PutPsz( p_intf, "subsdec-encoding", [[[o_osd_encoding_pop selectedItem] title] UTF8String] );
675 config_PutPsz( p_intf, "sub-language", [[o_osd_lang_fld stringValue] UTF8String] );
676 config_PutPsz( p_intf, "freetype-font", [[o_osd_font_fld stringValue] UTF8String] );
678 SaveIntList( o_osd_font_color_pop, "freetype-color" );
679 SaveIntList( o_osd_font_size_pop, "freetype-rel-fontsize" );
680 SaveIntList( o_osd_font_effect_pop, "freetype-effect" );
682 i = config_SaveConfigFile( p_intf, NULL );
686 msg_Err( p_intf, "An error occured while saving the OSD/Subtitle settings using SimplePrefs" );
689 b_osdSettingChanged = NO;
692 /********************
694 ********************/
695 if( b_hotkeyChanged )
697 struct hotkey *p_hotkeys = p_intf->p_libvlc->p_hotkeys;
699 while( i < [o_hotkeySettings count] ) // FIXME: this is ugly!
701 /* FIXME: this does only work for single keys!!! */
702 config_PutInt( p_intf, p_hotkeys[i].psz_action, StringToKey( (char *)[[o_hotkeySettings objectAtIndex: i] UTF8String] ) );
707 i = config_SaveConfigFile( p_intf, "main" );
711 msg_Err( p_intf, "An error occured while saving the Hotkey settings using SimplePrefs" );
714 b_hotkeyChanged = NO;
718 - (void)showSettingsForCategory: (id)o_new_category_view
720 NSRect o_win_rect, o_view_rect, o_old_view_rect;
721 o_win_rect = [o_sprefs_win frame];
722 o_view_rect = [o_new_category_view frame];
724 if( o_currentlyShownCategoryView != nil )
726 /* restore our window's height, if we've shown another category previously */
727 o_old_view_rect = [o_currentlyShownCategoryView frame];
728 o_win_rect.size.height = o_win_rect.size.height - o_old_view_rect.size.height;
730 /* remove our previous category view */
731 [o_currentlyShownCategoryView removeFromSuperviewWithoutNeedingDisplay];
734 o_win_rect.size.height = o_win_rect.size.height + o_view_rect.size.height;
736 [o_sprefs_win displayIfNeeded];
737 [o_sprefs_win setFrame: o_win_rect display:YES animate: YES];
739 [o_new_category_view setFrame: NSMakeRect( 0,
740 [o_sprefs_controls_box frame].size.height,
741 o_view_rect.size.width,
742 o_view_rect.size.height )];
743 [o_new_category_view setNeedsDisplay: YES];
744 [o_new_category_view setAutoresizesSubviews: YES];
745 [[o_sprefs_win contentView] addSubview: o_new_category_view];
747 /* keep our current category for further reference */
748 [o_currentlyShownCategoryView release];
749 o_currentlyShownCategoryView = o_new_category_view;
750 [o_currentlyShownCategoryView retain];
753 - (IBAction)interfaceSettingChanged:(id)sender
755 b_intfSettingChanged = YES;
758 - (void)showInterfaceSettings
760 msg_Dbg( p_intf, "showing interface settings" );
761 [self showSettingsForCategory: o_intf_view];
764 - (IBAction)audioSettingChanged:(id)sender
766 if( sender == o_audio_vol_sld )
767 [o_audio_vol_fld setIntValue: [o_audio_vol_sld intValue]];
769 if( sender == o_audio_vol_fld )
770 [o_audio_vol_sld setIntValue: [o_audio_vol_fld intValue]];
772 b_audioSettingChanged = YES;
775 - (void)showAudioSettings
777 msg_Dbg( p_intf, "showing audio settings" );
778 [self showSettingsForCategory: o_audio_view];
781 - (IBAction)videoSettingChanged:(id)sender
783 if( sender == o_video_snap_folder_btn )
785 o_selectFolderPanel = [[NSOpenPanel alloc] init];
786 [o_selectFolderPanel setCanChooseDirectories: YES];
787 [o_selectFolderPanel setCanChooseFiles: NO];
788 [o_selectFolderPanel setResolvesAliases: YES];
789 [o_selectFolderPanel setAllowsMultipleSelection: NO];
790 [o_selectFolderPanel setMessage: _NS("Choose the folder to save your video snapshots to.")];
791 [o_selectFolderPanel setCanCreateDirectories: YES];
792 [o_selectFolderPanel setPrompt: _NS("Choose")];
793 [o_selectFolderPanel beginSheetForDirectory: nil file: nil modalForWindow: o_sprefs_win
795 didEndSelector: @selector(savePanelDidEnd:returnCode:contextInfo:)
796 contextInfo: o_video_snap_folder_btn];
799 b_videoSettingChanged = YES;
802 - (void)savePanelDidEnd:(NSOpenPanel * )panel returnCode: (int)returnCode contextInfo: (void *)contextInfo
804 if( returnCode == NSOKButton )
806 if( contextInfo == o_video_snap_folder_btn )
808 [o_video_snap_folder_fld setStringValue: [o_selectFolderPanel filename]];
809 b_videoSettingChanged = YES;
811 else if( contextInfo == o_osd_font_btn )
813 [o_osd_font_fld setStringValue: [o_selectFolderPanel filename]];
814 b_osdSettingChanged = YES;
818 [o_selectFolderPanel release];
821 - (void)showVideoSettings
823 msg_Dbg( p_intf, "showing video settings" );
824 [self showSettingsForCategory: o_video_view];
827 - (IBAction)osdSettingChanged:(id)sender
829 if( sender == o_osd_font_btn )
831 o_selectFolderPanel = [[NSOpenPanel alloc] init];
832 [o_selectFolderPanel setCanChooseDirectories: NO];
833 [o_selectFolderPanel setCanChooseFiles: YES];
834 [o_selectFolderPanel setResolvesAliases: YES];
835 [o_selectFolderPanel setAllowsMultipleSelection: NO];
836 [o_selectFolderPanel setMessage: _NS("Choose the font to display your Subtitles with.")];
837 [o_selectFolderPanel setCanCreateDirectories: NO];
838 [o_selectFolderPanel setPrompt: _NS("Choose")];
839 [o_selectFolderPanel setAllowedFileTypes: [NSArray arrayWithObjects: @"dfont", @"ttf", @"otf", @"FFIL", nil]];
840 [o_selectFolderPanel beginSheetForDirectory: @"/System/Library/Fonts/" file: nil modalForWindow: o_sprefs_win
842 didEndSelector: @selector(savePanelDidEnd:returnCode:contextInfo:)
843 contextInfo: o_osd_font_btn];
846 b_osdSettingChanged = YES;
849 - (void)showOSDSettings
851 msg_Dbg( p_intf, "showing OSD settings" );
852 [self showSettingsForCategory: o_osd_view];
855 - (IBAction)inputSettingChanged:(id)sender
857 b_inputSettingChanged = YES;
860 - (void)showInputSettings
862 msg_Dbg( p_intf, "showing Input Settings" );
863 [self showSettingsForCategory: o_input_view];
866 - (IBAction)hotkeySettingChanged:(id)sender
868 if( sender == o_hotkeys_change_btn || sender == o_hotkeys_listbox )
870 [o_hotkeys_change_lbl setStringValue: [NSString stringWithFormat: _NS("Press new keys for\n\"%@\""),
871 [o_hotkeyDescriptions objectAtIndex: [o_hotkeys_listbox selectedRow]]]];
872 [o_hotkeys_change_keys_lbl setStringValue: [o_hotkeySettings objectAtIndex: [o_hotkeys_listbox selectedRow]]];
873 [o_hotkeys_change_taken_lbl setStringValue: @""];
874 [o_hotkeys_change_win setInitialFirstResponder: [o_hotkeys_change_win contentView]];
875 [o_hotkeys_change_win makeFirstResponder: [o_hotkeys_change_win contentView]];
876 [NSApp runModalForWindow: o_hotkeys_change_win];
878 else if( sender == o_hotkeys_change_cancel_btn )
881 [o_hotkeys_change_win close];
883 else if( sender == o_hotkeys_change_ok_btn )
886 b_hotkeyChanged = YES;
888 i_returnValue = [o_hotkeySettings indexOfObject: [o_hotkeys_change_keys_lbl stringValue]];
889 if( i_returnValue != NSNotFound )
890 [o_hotkeySettings replaceObjectAtIndex: i_returnValue withObject: @"Unset"];
892 [o_hotkeySettings replaceObjectAtIndex: [o_hotkeys_listbox selectedRow] withObject: [o_hotkeys_change_keys_lbl stringValue]];
895 [o_hotkeys_change_win close];
897 [o_hotkeys_listbox reloadData];
899 else if( sender == o_hotkeys_clear_btn )
901 [o_hotkeySettings replaceObjectAtIndex: [o_hotkeys_listbox selectedRow] withObject: @"Unset"];
902 [o_hotkeys_listbox reloadData];
903 b_hotkeyChanged = YES;
907 - (void)showHotkeySettings
909 msg_Dbg( p_intf, "showing HotKey Settings" );
910 [self showSettingsForCategory: o_hotkeys_view];
913 - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
915 return [o_hotkeySettings count];
918 - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
920 if( [[aTableColumn identifier] isEqualToString: @"action"] )
921 return [o_hotkeyDescriptions objectAtIndex: rowIndex];
922 else if( [[aTableColumn identifier] isEqualToString: @"shortcut"] )
923 return [o_hotkeySettings objectAtIndex: rowIndex];
926 NSLog(@"unknown TableColumn identifier (%@)!", [aTableColumn identifier] );
931 - (void)changeHotkeyTo: (NSString *)o_theNewKey
934 if( o_theNewKey == @"invalid" || o_theNewKey == @"" )
936 [o_hotkeys_change_keys_lbl setStringValue: _NS("Invalid combination")];
937 [o_hotkeys_change_taken_lbl setStringValue: _NS("Regrettably, these keys cannot be assigned as hotkey shortcuts.")];
938 [o_hotkeys_change_ok_btn setEnabled: NO];
942 [o_hotkeys_change_keys_lbl setStringValue: o_theNewKey];
944 i_returnValue = [o_hotkeySettings indexOfObject: o_theNewKey];
945 if( i_returnValue != NSNotFound )
946 [o_hotkeys_change_taken_lbl setStringValue: [NSString stringWithFormat:
947 _NS("This combination is already taken by \"%@\"."),
948 [o_hotkeyDescriptions objectAtIndex: i_returnValue]]];
950 [o_hotkeys_change_taken_lbl setStringValue: @""];
952 [o_hotkeys_change_ok_btn setEnabled: YES];
958 /********************
960 ********************/
962 @implementation VLCHotkeyChangeWindow
964 - (void)keyDown:(NSEvent *)o_theEvent
966 NSMutableString *o_temp = [[NSMutableString alloc] init];
968 if( [o_theEvent modifierFlags] & NSShiftKeyMask )
969 [o_temp appendString: @"Shift+"];
971 if( [o_theEvent modifierFlags] & NSControlKeyMask )
972 [o_temp appendString: @"Ctrl+"];
974 if( [o_theEvent modifierFlags] & NSCommandKeyMask )
975 [o_temp appendString: @"Command+"];
977 if( [o_theEvent modifierFlags] & NSAlternateKeyMask )
978 [o_temp appendString: @"Alt+"];
980 if( [o_theEvent modifierFlags] & NSFunctionKeyMask )
983 key = [[o_theEvent charactersIgnoringModifiers] characterAtIndex: 0];
988 [o_temp appendString: @"Esc"];
990 case NSF1FunctionKey:
991 [o_temp appendString: @"F1"];
993 case NSF2FunctionKey:
994 [o_temp appendString: @"F2"];
996 case NSF3FunctionKey:
997 [o_temp appendString: @"F3"];
999 case NSF4FunctionKey:
1000 [o_temp appendString: @"F4"];
1002 case NSF5FunctionKey:
1003 [o_temp appendString: @"F5"];
1005 case NSF6FunctionKey:
1006 [o_temp appendString: @"F6"];
1008 case NSF7FunctionKey:
1009 [o_temp appendString: @"F7"];
1011 case NSF8FunctionKey:
1012 [o_temp appendString: @"F8"];
1014 case NSF9FunctionKey:
1015 [o_temp appendString: @"F9"];
1017 case NSF10FunctionKey:
1018 [o_temp appendString: @"F10"];
1020 case NSF11FunctionKey:
1021 [o_temp appendString: @"F11"];
1023 case NSF12FunctionKey:
1024 [o_temp appendString: @"F12"];
1026 case NSInsertFunctionKey:
1027 [o_temp appendString: @"Insert"];
1029 case NSHomeFunctionKey:
1030 [o_temp appendString: @"Home"];
1032 case NSEndFunctionKey:
1033 [o_temp appendString: @"End"];
1035 case NSPageUpFunctionKey:
1036 [o_temp appendString: @"Page Up"];
1038 case NSPageDownFunctionKey:
1039 [o_temp appendString: @"Page Down"];
1041 case NSMenuFunctionKey:
1042 [o_temp appendString: @"Menu"];
1044 case NSTabCharacter:
1045 [o_temp appendString: @"Tab"];
1047 case NSDeleteCharacter:
1048 [o_temp appendString: @"Delete"];
1050 case NSBackspaceCharacter:
1051 [o_temp appendString: @"Backspace"];
1053 case NSUpArrowFunctionKey:
1054 [o_temp appendString: @"Up"];
1056 case NSDownArrowFunctionKey:
1057 [o_temp appendString: @"Down"];
1059 case NSRightArrowFunctionKey:
1060 [o_temp appendString: @"Right"];
1062 case NSLeftArrowFunctionKey:
1063 [o_temp appendString: @"Left"];
1065 case NSEnterCharacter:
1066 [o_temp appendString: @"Enter"];
1070 msg_Warn( VLCIntf, "user pressed unknown function key" );
1071 o_temp = @"invalid";
1078 if( [[o_theEvent charactersIgnoringModifiers] isEqualToString: @" "] )
1079 [o_temp appendString: @"Space"];
1081 [o_temp appendString: [o_theEvent charactersIgnoringModifiers]];
1084 /* FIXME: implement sanity checks here as we don't want the user to interfere with hard shortcuts in our main menu */
1085 [[[VLCMain sharedInstance] getSimplePreferences] changeHotkeyTo: o_temp];
1087 NSLog( @"user pressed %@", o_temp );