1 /*****************************************************************************
2 * open.m: Open dialogues for VLC's MacOS X port
3 *****************************************************************************
4 * Copyright (C) 2002-2012 VLC authors and VideoLAN
7 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8 * Christophe Massiot <massiot@via.ecp.fr>
9 * Derk-Jan Hartman <thedj@users.sourceforge.net>
10 * Benjamin Pracht <bigben at videolan dot org>
11 * Felix Paul Kühne <fkuehne at videolan dot org>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
28 /*****************************************************************************
30 *****************************************************************************/
31 #import <stdlib.h> /* malloc(), free() */
32 #import <sys/param.h> /* for MAXPATHLEN */
34 #import "CompatibilityFixes.h"
37 #import <IOKit/IOBSD.h>
38 #import <IOKit/storage/IOMedia.h>
39 #import <IOKit/storage/IOCDMedia.h>
40 #import <IOKit/storage/IODVDMedia.h>
41 #import <IOKit/storage/IOBDMedia.h>
42 #import <Cocoa/Cocoa.h>
43 #import <QTKit/QTKit.h>
53 NSArray *qtkvideoDevices;
54 #define setEyeTVUnconnected \
55 [o_capture_lbl setStringValue: _NS("No device is selected")]; \
56 [o_capture_long_lbl setStringValue: _NS("No device is selected.\n\nChoose available device in above pull-down menu\n.")]; \
57 [o_capture_lbl displayIfNeeded]; \
58 [o_capture_long_lbl displayIfNeeded]; \
59 [self showCaptureView: o_capture_label_view]
61 #define kVLCMediaAudioCD "AudioCD"
62 #define kVLCMediaDVD "DVD"
63 #define kVLCMediaVCD "VCD"
64 #define kVLCMediaSVCD "SVCD"
65 #define kVLCMediaBD "Bluray"
66 #define kVLCMediaVideoTSFolder "VIDEO_TS"
67 #define kVLCMediaBDMVFolder "BDMV"
68 #define kVLCMediaUnknown "Unknown"
71 /*****************************************************************************
72 * VLCOpen implementation
73 *****************************************************************************/
74 @implementation VLCOpen
76 static VLCOpen *_o_sharedMainInstance = nil;
78 + (VLCOpen *)sharedInstance
80 return _o_sharedMainInstance ? _o_sharedMainInstance : [[self alloc] init];
85 if( _o_sharedMainInstance) {
88 _o_sharedMainInstance = [super init];
92 return _o_sharedMainInstance;
97 [o_specialMediaFolders release];
98 [o_opticalDevices release];
99 if( o_file_slave_path )
100 [o_file_slave_path release];
103 [o_sub_path release];
104 [o_currentOpticalMediaIconView release];
105 [o_currentOpticalMediaView release];
112 [o_panel setCollectionBehavior: NSWindowCollectionBehaviorFullScreenAuxiliary];
114 [o_panel setTitle: _NS("Open Source")];
115 [o_mrl_lbl setStringValue: _NS("Media Resource Locator (MRL)")];
117 [o_btn_ok setTitle: _NS("Open")];
118 [o_btn_cancel setTitle: _NS("Cancel")];
120 [[o_tabview tabViewItemAtIndex: 0] setLabel: _NS("File")];
121 [[o_tabview tabViewItemAtIndex: 1] setLabel: _NS("Disc")];
122 [[o_tabview tabViewItemAtIndex: 2] setLabel: _NS("Network")];
123 [[o_tabview tabViewItemAtIndex: 3] setLabel: _NS("Capture")];
125 [o_file_name setStringValue: @""];
126 [o_file_name_stub setStringValue: _NS("Choose a file")];
127 [o_file_icon_well setImage: [NSImage imageNamed:@"generic"]];
128 [o_file_btn_browse setTitle: _NS("Browse...")];
129 [o_file_stream setTitle: _NS("Treat as a pipe rather than as a file")];
130 [o_file_stream setHidden: NO];
131 [o_file_slave_ckbox setTitle: _NS("Play another media synchronously")];
132 [o_file_slave_select_btn setTitle: _NS("Choose...")];
133 [o_file_slave_filename_lbl setStringValue: @""];
134 [o_file_slave_icon_well setImage: NULL];
135 [o_file_subtitles_filename_lbl setStringValue: @""];
136 [o_file_subtitles_icon_well setImage: NULL];
138 [o_disc_selector_pop removeAllItems];
139 [o_disc_selector_pop setHidden: NO];
140 NSString *o_videots = _NS("Open VIDEO_TS folder");
141 NSString *o_bdmv = _NS("Open BDMV folder");
142 [o_disc_nodisc_lbl setStringValue: _NS("Insert Disc")];
143 [o_disc_nodisc_videots_btn setTitle: o_videots];
144 [o_disc_nodisc_bdmv_btn setTitle: o_bdmv];
145 [o_disc_audiocd_lbl setStringValue: _NS("Audio CD")];
146 [o_disc_audiocd_trackcount_lbl setStringValue: @""];
147 [o_disc_audiocd_videots_btn setTitle: o_videots];
148 [o_disc_audiocd_bdmv_btn setTitle: o_bdmv];
149 [o_disc_dvd_lbl setStringValue: @""];
150 [o_disc_dvd_disablemenus_btn setTitle: _NS("Disable DVD menus")];
151 [o_disc_dvd_videots_btn setTitle: o_videots];
152 [o_disc_dvd_bdmv_btn setTitle: o_bdmv];
153 [o_disc_dvdwomenus_lbl setStringValue: @""];
154 [o_disc_dvdwomenus_enablemenus_btn setTitle: _NS("Enable DVD menus")];
155 [o_disc_dvdwomenus_videots_btn setTitle: o_videots];
156 [o_disc_dvdwomenus_bdmv_btn setTitle: o_bdmv];
157 [o_disc_dvdwomenus_title_lbl setStringValue: _NS("Title")];
158 [o_disc_dvdwomenus_chapter_lbl setStringValue: _NS("Chapter")];
159 [o_disc_vcd_title_lbl setStringValue: _NS("Title")];
160 [o_disc_vcd_chapter_lbl setStringValue: _NS("Chapter")];
161 [o_disc_vcd_videots_btn setTitle: o_videots];
162 [o_disc_vcd_bdmv_btn setTitle: o_bdmv];
163 [o_disc_bd_videots_btn setTitle: o_videots];
164 [o_disc_bd_bdmv_btn setTitle: o_bdmv];
166 [o_net_udp_port_lbl setStringValue: _NS("Port")];
167 [o_net_udpm_addr_lbl setStringValue: _NS("IP Address")];
168 [o_net_udpm_port_lbl setStringValue: _NS("Port")];
169 [o_net_http_url_lbl setStringValue: _NS("URL")];
170 [o_net_help_lbl setStringValue: _NS("To Open a usual network stream (HTTP, RTSP, RTMP, MMS, FTP, etc.), just enter the URL in the field above. If you want to open a RTP or UDP stream, press the button below.")];
171 [o_net_help_udp_lbl setStringValue: _NS("If you want to open a multicast stream, enter the respective IP address given by the stream provider. In unicast mode, VLC will use your machine's IP automatically.\n\nTo open a stream using a different protocol, just press Cancel to close this sheet.")];
172 [o_net_udp_cancel_btn setTitle: _NS("Cancel")];
173 [o_net_udp_ok_btn setTitle: _NS("Open")];
174 [o_net_openUDP_btn setTitle: _NS("Open RTP/UDP Stream")];
175 [o_net_udp_mode_lbl setStringValue: _NS("Mode")];
176 [o_net_udp_protocol_lbl setStringValue: _NS("Protocol")];
177 [o_net_udp_address_lbl setStringValue: _NS("Address")];
179 [[o_net_mode cellAtRow:0 column:0] setTitle: _NS("Unicast")];
180 [[o_net_mode cellAtRow:1 column:0] setTitle: _NS("Multicast")];
182 [o_net_udp_port setIntValue: config_GetInt( p_intf, "server-port" )];
183 [o_net_udp_port_stp setIntValue: config_GetInt( p_intf, "server-port" )];
185 [o_eyetv_chn_bgbar setUsesThreadedAnimation: YES];
187 [o_capture_mode_pop removeAllItems];
188 [o_capture_mode_pop addItemWithTitle: _NS("Capture Device")];
189 // our screen capture module isn't Lion-compatible, so let's hide it from the user if needed (trac #4799)
190 if( NSAppKitVersionNumber < 1115.2 )
191 [o_capture_mode_pop addItemWithTitle: _NS("Screen")];
192 [o_capture_mode_pop addItemWithTitle: @"EyeTV"];
193 [o_screen_long_lbl setStringValue: _NS("This input allows you to save, stream or display your current screen contents.")];
194 [o_screen_fps_lbl setStringValue: _NS("Frames per Second:")];
195 [o_screen_left_lbl setStringValue: _NS("Subscreen left:")];
196 [o_screen_top_lbl setStringValue: _NS("Subscreen top:")];
197 [o_screen_width_lbl setStringValue: _NS("Subscreen width:")];
198 [o_screen_height_lbl setStringValue: _NS("Subscreen height:")];
199 [o_screen_follow_mouse_ckb setTitle: _NS("Follow the mouse")];
200 [o_eyetv_currentChannel_lbl setStringValue: _NS("Current channel:")];
201 [o_eyetv_previousProgram_btn setTitle: _NS("Previous Channel")];
202 [o_eyetv_nextProgram_btn setTitle: _NS("Next Channel")];
203 [o_eyetv_chn_status_txt setStringValue: _NS("Retrieving Channel Info...")];
204 [o_eyetv_noInstance_lbl setStringValue: _NS("EyeTV is not launched")];
205 [o_eyetv_noInstanceLong_lbl setStringValue: _NS("VLC could not connect to EyeTV.\nMake sure that you installed VLC's EyeTV plugin.")];
206 [o_eyetv_launchEyeTV_btn setTitle: _NS("Launch EyeTV now")];
207 [o_eyetv_getPlugin_btn setTitle: _NS("Download Plugin")];
208 [o_qtk_long_lbl setStringValue: _NS("This input allows you to process input signals from QuickTime-compatible video devices.\nLive Audio input is not supported.")];
209 [o_capture_width_lbl setStringValue: _NS("Image width:")];
210 [o_capture_height_lbl setStringValue: _NS("Image height:")];
212 [self qtkvideoDevices];
213 [o_qtk_device_pop removeAllItems];
214 msg_Dbg( VLCIntf, "Found %lu capture devices", [qtkvideoDevices count] );
215 if([qtkvideoDevices count] >= 1)
217 if (!qtk_currdevice_uid) {
218 qtk_currdevice_uid = [[[QTCaptureDevice defaultInputDeviceWithMediaType: QTMediaTypeVideo] uniqueID]
219 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
221 NSUInteger deviceCount = [qtkvideoDevices count];
222 for(int ivideo = 0; ivideo < deviceCount; ivideo++){
223 QTCaptureDevice *qtk_device;
224 qtk_device = [qtkvideoDevices objectAtIndex:ivideo];
225 [o_qtk_device_pop addItemWithTitle: [qtk_device localizedDisplayName]];
226 if([[[qtk_device uniqueID]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] isEqualToString:qtk_currdevice_uid]){
227 [o_qtk_device_pop selectItemAtIndex:ivideo];
233 [o_qtk_device_pop addItemWithTitle: _NS("None")];
234 [qtk_currdevice_uid release];
240 [[NSNotificationCenter defaultCenter] addObserver: self
241 selector: @selector(openNetInfoChanged:)
242 name: NSControlTextDidChangeNotification
243 object: o_net_udp_port];
244 [[NSNotificationCenter defaultCenter] addObserver: self
245 selector: @selector(openNetInfoChanged:)
246 name: NSControlTextDidChangeNotification
247 object: o_net_udpm_addr];
248 [[NSNotificationCenter defaultCenter] addObserver: self
249 selector: @selector(openNetInfoChanged:)
250 name: NSControlTextDidChangeNotification
251 object: o_net_udpm_port];
252 [[NSNotificationCenter defaultCenter] addObserver: self
253 selector: @selector(openNetInfoChanged:)
254 name: NSControlTextDidChangeNotification
255 object: o_net_http_url];
257 [[NSDistributedNotificationCenter defaultCenter] addObserver: self
258 selector: @selector(eyetvChanged:)
260 object: @"VLCEyeTVSupport"
261 suspensionBehavior: NSNotificationSuspensionBehaviorDeliverImmediately];
263 [[NSNotificationCenter defaultCenter] addObserver: self
264 selector: @selector(screenFPSfieldChanged:)
265 name: NSControlTextDidChangeNotification
266 object: o_screen_fps_fld];
268 /* register clicks on text fields */
269 [[NSNotificationCenter defaultCenter] addObserver: self
270 selector: @selector(textFieldWasClicked:)
271 name: @"VLCOpenTextFieldWasClicked"
274 /* we want to be notified about removed or added media */
275 o_specialMediaFolders = [[NSMutableArray alloc] init];
276 o_opticalDevices = [[NSMutableArray alloc] init];
277 NSWorkspace *sharedWorkspace = [NSWorkspace sharedWorkspace];
278 [[sharedWorkspace notificationCenter] addObserver:self selector:@selector(scanOpticalMedia:) name:NSWorkspaceDidMountNotification object:nil];
279 [[sharedWorkspace notificationCenter] addObserver:self selector:@selector(scanOpticalMedia:) name:NSWorkspaceDidUnmountNotification object:nil];
280 [self scanOpticalMedia:nil];
281 [self qtkChanged:nil];
286 - (void)setMRL:(NSString *)newMRL
291 [o_mrl_fld setStringValue: newMRL];
292 if ([o_mrl length] > 0)
293 [o_btn_ok setEnabled: YES];
295 [o_btn_ok setEnabled: NO];
306 module_config_t * p_item;
308 [o_file_sub_ckbox setTitle: _NS("Load subtitles file:")];
309 [o_file_sub_path_lbl setStringValue: _NS("Choose a file")];
310 [o_file_sub_path_lbl setHidden: NO];
311 [o_file_sub_path_fld setStringValue: @""];
312 [o_file_sub_btn_settings setTitle: _NS("Choose...")];
313 [o_file_sub_btn_browse setTitle: _NS("Browse...")];
314 [o_file_sub_override setTitle: _NS("Override parameters")];
315 [o_file_sub_delay_lbl setStringValue: _NS("Delay")];
316 [o_file_sub_delay_stp setEnabled: NO];
317 [o_file_sub_fps_lbl setStringValue: _NS("FPS")];
318 [o_file_sub_fps_stp setEnabled: NO];
319 [o_file_sub_encoding_lbl setStringValue: _NS("Subtitles encoding")];
320 [o_file_sub_encoding_pop removeAllItems];
321 [o_file_sub_size_lbl setStringValue: _NS("Font size")];
322 [o_file_sub_size_pop removeAllItems];
323 [o_file_sub_align_lbl setStringValue: _NS("Subtitles alignment")];
324 [o_file_sub_align_pop removeAllItems];
325 [o_file_sub_ok_btn setStringValue: _NS("OK")];
326 [o_file_sub_font_box setTitle: _NS("Font Properties")];
327 [o_file_sub_file_box setTitle: _NS("Subtitle File")];
329 p_item = config_FindConfig( VLC_OBJECT(p_intf), "subsdec-encoding" );
333 for( i_index = 0; p_item->ppsz_list && p_item->ppsz_list[i_index];
336 [o_file_sub_encoding_pop addItemWithTitle:
337 [NSString stringWithUTF8String: p_item->ppsz_list[i_index]]];
339 [o_file_sub_encoding_pop selectItemWithTitle:
340 [NSString stringWithUTF8String: p_item->value.psz]];
343 p_item = config_FindConfig( VLC_OBJECT(p_intf), "subsdec-align" );
347 for ( i_index = 0; i_index < p_item->i_list; i_index++ )
349 [o_file_sub_align_pop addItemWithTitle:
350 _NS(p_item->ppsz_list_text[i_index])];
352 [o_file_sub_align_pop selectItemAtIndex: p_item->value.i];
355 p_item = config_FindConfig( VLC_OBJECT(p_intf), "freetype-rel-fontsize" );
359 for ( i_index = 0; i_index < p_item->i_list; i_index++ )
361 [o_file_sub_size_pop addItemWithTitle: _NS(p_item->ppsz_list_text[i_index])];
362 if ( p_item->value.i == p_item->pi_list[i_index] )
364 [o_file_sub_size_pop selectItemAtIndex: i_index];
370 - (void)openTarget:(int)i_type
374 b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
376 [o_tabview selectTabViewItemAtIndex: i_type];
377 [o_file_sub_ckbox setState: NSOffState];
379 i_result = [NSApp runModalForWindow: o_panel];
384 NSMutableDictionary *o_dic;
385 NSMutableArray *o_options = [NSMutableArray array];
387 o_dic = [NSMutableDictionary dictionaryWithObject: [self MRL] forKey: @"ITEM_URL"];
388 if( [o_file_sub_ckbox state] == NSOnState )
390 module_config_t * p_item;
392 [o_options addObject: [NSString stringWithFormat: @"sub-file=%@", o_sub_path]];
393 if( [o_file_sub_override state] == NSOnState )
395 [o_options addObject: [NSString stringWithFormat: @"sub-delay=%i", (int)( [o_file_sub_delay intValue] * 10 )]];
396 [o_options addObject: [NSString stringWithFormat: @"sub-fps=%f", [o_file_sub_fps floatValue]]];
398 [o_options addObject: [NSString stringWithFormat:
399 @"subsdec-encoding=%@",
400 [o_file_sub_encoding_pop titleOfSelectedItem]]];
401 [o_options addObject: [NSString stringWithFormat:
403 [o_file_sub_align_pop indexOfSelectedItem]]];
405 p_item = config_FindConfig( VLC_OBJECT(p_intf),
406 "freetype-rel-fontsize" );
410 [o_options addObject: [NSString stringWithFormat:
411 @"freetype-rel-fontsize=%i",
412 p_item->pi_list[[o_file_sub_size_pop indexOfSelectedItem]]]];
415 if( [o_output_ckbox state] == NSOnState )
417 NSUInteger count = [[o_sout_options mrl] count];
418 for (NSUInteger i = 0 ; i < count ; i++)
420 [o_options addObject: [NSString stringWithString: [[(VLCOutput *)o_sout_options mrl] objectAtIndex: i]]];
423 if( [o_file_slave_ckbox state] && o_file_slave_path )
424 [o_options addObject: [NSString stringWithFormat: @"input-slave=%@", o_file_slave_path]];
425 if( [[[o_tabview selectedTabViewItem] label] isEqualToString: _NS("Capture")] )
427 if( [[[o_capture_mode_pop selectedItem] title] isEqualToString: _NS("Screen")] )
429 [o_options addObject: [NSString stringWithFormat: @"screen-fps=%f", [o_screen_fps_fld floatValue]]];
430 [o_options addObject: [NSString stringWithFormat: @"screen-left=%i", [o_screen_left_fld intValue]]];
431 [o_options addObject: [NSString stringWithFormat: @"screen-top=%i", [o_screen_top_fld intValue]]];
432 [o_options addObject: [NSString stringWithFormat: @"screen-width=%i", [o_screen_width_fld intValue]]];
433 [o_options addObject: [NSString stringWithFormat: @"screen-height=%i", [o_screen_height_fld intValue]]];
434 if( [o_screen_follow_mouse_ckb intValue] == YES )
435 [o_options addObject: @"screen-follow-mouse"];
437 [o_options addObject: @"no-screen-follow-mouse"];
439 else if( [[[o_capture_mode_pop selectedItem] title] isEqualToString: _NS("Capture Device")] )
441 [o_options addObject: [NSString stringWithFormat: @"qtcapture-width=%i", [o_capture_width_fld intValue]]];
442 [o_options addObject: [NSString stringWithFormat: @"qtcapture-height=%i", [o_capture_height_fld intValue]]];
446 /* apply the options to our item(s) */
447 [o_dic setObject: (NSArray *)[o_options copy] forKey: @"ITEM_OPTIONS"];
449 [[[VLCMain sharedInstance] playlist] appendArray: [NSArray arrayWithObject: o_dic] atPos: -1 enqueue:NO];
451 [[[VLCMain sharedInstance] playlist] appendArray: [NSArray arrayWithObject: o_dic] atPos: -1 enqueue:YES];
455 - (IBAction)qtkChanged:(id)sender
457 NSInteger i_selectedDevice = [o_qtk_device_pop indexOfSelectedItem];
458 if (i_selectedDevice >= ([qtkvideoDevices count] - 1))
460 NSValue *sizes = [[[[qtkvideoDevices objectAtIndex:i_selectedDevice] formatDescriptions] objectAtIndex: 0] attributeForKey: QTFormatDescriptionVideoEncodedPixelsSizeAttribute];
462 [o_capture_width_fld setIntValue: [sizes sizeValue].width];
463 [o_capture_height_fld setIntValue: [sizes sizeValue].height];
464 [o_capture_width_stp setIntValue: [o_capture_width_fld intValue]];
465 [o_capture_height_stp setIntValue: [o_capture_height_fld intValue]];
466 qtk_currdevice_uid = [[(QTCaptureDevice *)[qtkvideoDevices objectAtIndex:i_selectedDevice] uniqueID]
467 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
468 [self setMRL:[NSString stringWithFormat:@"qtcapture://%@", qtk_currdevice_uid]];
472 - (void)tabView:(NSTabView *)o_tv didSelectTabViewItem:(NSTabViewItem *)o_tvi
474 NSString *o_label = [o_tvi label];
476 if( [o_label isEqualToString: _NS("File")] )
478 [self openFilePathChanged: nil];
480 else if( [o_label isEqualToString: _NS("Disc")] )
482 [self scanOpticalMedia: nil];
484 else if( [o_label isEqualToString: _NS("Network")] )
486 [self openNetInfoChanged: nil];
488 else if( [o_label isEqualToString: _NS("Capture")] )
490 [self openCaptureModeChanged: nil];
494 - (IBAction)expandMRLfieldAction:(id)sender
496 NSRect o_win_rect, o_view_rect;
497 o_win_rect = [o_panel frame];
498 o_view_rect = [o_mrl_view frame];
500 if( [o_mrl_btn state] == NSOffState )
502 /* we need to collaps, restore the panel size */
503 o_win_rect.size.height = o_win_rect.size.height - o_view_rect.size.height;
504 o_win_rect.origin.y = ( o_win_rect.origin.y + o_view_rect.size.height ) - o_view_rect.size.height;
506 /* remove the MRL view */
507 [o_mrl_view removeFromSuperview];
509 /* we need to expand */
510 [o_mrl_view setFrame: NSMakeRect( 0,
511 [o_mrl_btn frame].origin.y,
512 o_view_rect.size.width,
513 o_view_rect.size.height )];
514 [o_mrl_view setNeedsDisplay: NO];
515 [o_mrl_view setAutoresizesSubviews: YES];
517 /* enlarge panel size for MRL view */
518 o_win_rect.size.height = o_win_rect.size.height + o_view_rect.size.height;
521 [[o_panel animator] setFrame: o_win_rect display:YES];
522 // [o_panel displayIfNeeded];
523 if( [o_mrl_btn state] == NSOnState )
524 [[o_panel contentView] addSubview: o_mrl_view];
527 - (IBAction)inputSlaveAction:(id)sender
529 if( sender == o_file_slave_ckbox )
530 [o_file_slave_select_btn setEnabled: [o_file_slave_ckbox state]];
533 NSOpenPanel *o_open_panel;
534 o_open_panel = [NSOpenPanel openPanel];
535 [o_open_panel setCanChooseFiles: YES];
536 [o_open_panel setCanChooseDirectories: NO];
537 if( [o_open_panel runModal] == NSOKButton )
539 if( o_file_slave_path )
540 [o_file_slave_path release];
541 o_file_slave_path = [[[o_open_panel URLs] objectAtIndex: 0] path];
542 [o_file_slave_path retain];
545 if( o_file_slave_path && [o_file_slave_ckbox state] == NSOnState)
547 [o_file_slave_filename_lbl setStringValue: [[NSFileManager defaultManager] displayNameAtPath:o_file_slave_path]];
548 [o_file_slave_icon_well setImage: [[NSWorkspace sharedWorkspace] iconForFile: o_file_slave_path]];
552 [o_file_slave_filename_lbl setStringValue: @""];
553 [o_file_slave_icon_well setImage: NULL];
557 - (void)openFileGeneric
559 [self openFilePathChanged: nil];
560 [self openTarget: 0];
565 [o_specialMediaFolders removeAllObjects];
566 [o_opticalDevices removeAllObjects];
567 [self scanOpticalMedia: nil];
568 [self openTarget: 1];
573 [self openNetInfoChanged: nil];
574 [self openTarget: 2];
579 [self openCaptureModeChanged: nil];
580 [self openTarget: 3];
583 - (void)openFilePathChanged:(NSNotification *)o_notification
585 if ( o_file_path && [o_file_path length] > 0 )
587 bool b_stream = [o_file_stream state];
590 [[NSFileManager defaultManager] fileExistsAtPath:o_file_path isDirectory:&b_dir];
592 char *psz_uri = make_URI([o_file_path UTF8String], "file");
593 if( !psz_uri ) return;
595 NSMutableString *o_mrl_string = [NSMutableString stringWithUTF8String: psz_uri ];
596 NSRange offile = [o_mrl_string rangeOfString:@"file"];
600 [o_mrl_string replaceCharactersInRange:offile withString: @"directory"];
602 [o_mrl_string replaceCharactersInRange:offile withString: @"stream"];
604 [o_file_name setStringValue: [[NSFileManager defaultManager] displayNameAtPath:o_file_path]];
605 [o_file_name_stub setHidden: YES];
606 [o_file_stream setHidden: NO];
607 [o_file_icon_well setImage: [[NSWorkspace sharedWorkspace] iconForFile: o_file_path]];
608 [o_file_icon_well setHidden: NO];
609 [self setMRL: o_mrl_string];
613 [o_file_name setStringValue: @""];
614 [o_file_name_stub setHidden: NO];
615 [o_file_stream setHidden: YES];
616 [o_file_icon_well setImage: [NSImage imageNamed:@"generic"]];
621 - (IBAction)openFileBrowse:(id)sender
623 NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
625 [o_open_panel setAllowsMultipleSelection: NO];
626 [o_open_panel setCanChooseDirectories: YES];
627 [o_open_panel setTitle: _NS("Open File")];
628 [o_open_panel setPrompt: _NS("Open")];
630 [o_open_panel beginSheetForDirectory:nil
633 modalForWindow:[sender window]
635 didEndSelector: @selector(pathChosenInPanel:
641 - (void)pathChosenInPanel: (NSOpenPanel *) sheet withReturn:(int)returnCode contextInfo:(void *)contextInfo
643 if (returnCode == NSFileHandlingPanelOKButton)
646 [o_file_path release];
647 o_file_path = [[[sheet URLs] objectAtIndex: 0] path];
648 [o_file_path retain];
649 [self openFilePathChanged: nil];
653 - (IBAction)openFileStreamChanged:(id)sender
655 [self openFilePathChanged: nil];
658 - (void)showOpticalMediaView: theView withIcon:(NSImage *)icon
661 o_view_rect = [theView frame];
662 [theView setFrame: NSMakeRect( 233, 0, o_view_rect.size.width, o_view_rect.size.height)];
663 [theView setAutoresizesSubviews: YES];
664 if (o_currentOpticalMediaView)
666 [[[[o_tabview tabViewItemAtIndex: [o_tabview indexOfTabViewItemWithIdentifier:@"optical"]] view] animator] replaceSubview: o_currentOpticalMediaView with: theView];
667 [o_currentOpticalMediaView release];
670 [[[[o_tabview tabViewItemAtIndex: [o_tabview indexOfTabViewItemWithIdentifier:@"optical"]] view] animator] addSubview: theView];
671 o_currentOpticalMediaView = theView;
672 [o_currentOpticalMediaView retain];
674 NSImageView *imageView;
675 imageView = [[NSImageView alloc] init];
676 [imageView setFrame: NSMakeRect( 53, 61, 128, 128 )];
677 [icon setSize: NSMakeSize(128,128)];
678 [imageView setImage: icon];
679 if (o_currentOpticalMediaIconView)
681 [[[[o_tabview tabViewItemAtIndex: [o_tabview indexOfTabViewItemWithIdentifier:@"optical"]] view] animator] replaceSubview: o_currentOpticalMediaIconView with: imageView];
682 [o_currentOpticalMediaIconView release];
685 [[[[o_tabview tabViewItemAtIndex: [o_tabview indexOfTabViewItemWithIdentifier:@"optical"]] view] animator] addSubview: imageView];
686 o_currentOpticalMediaIconView = imageView;
687 [o_currentOpticalMediaIconView retain];
688 [o_currentOpticalMediaView setNeedsDisplay: YES];
689 [o_currentOpticalMediaIconView setNeedsDisplay: YES];
690 [[[o_tabview tabViewItemAtIndex: [o_tabview indexOfTabViewItemWithIdentifier:@"optical"]] view] setNeedsDisplay: YES];
691 [[[o_tabview tabViewItemAtIndex: [o_tabview indexOfTabViewItemWithIdentifier:@"optical"]] view] displayIfNeeded];
694 - (NSString *) getBSDNodeFromMountPath:(NSString *)mountPath
698 FSVolumeRefNum actualVolume;
699 err = FSPathMakeRef ( (const UInt8 *) [mountPath fileSystemRepresentation], &ref, NULL );
701 // get a FSVolumeRefNum from mountPath
702 if ( noErr == err ) {
703 FSCatalogInfo catalogInfo;
704 err = FSGetCatalogInfo ( &ref,
711 if ( noErr == err ) {
712 actualVolume = catalogInfo.volume;
716 GetVolParmsInfoBuffer volumeParms;
717 err = FSGetVolumeParms( actualVolume, &volumeParms, sizeof(volumeParms) );
718 if ( noErr != err ) {
719 msg_Err( p_intf, "error retrieving volume params, bailing out" );
723 NSString *bsdName = [NSString stringWithUTF8String:(char *)volumeParms.vMDeviceID];
724 return [NSString stringWithFormat:@"/dev/r%@", bsdName];
727 - (char *)getVolumeTypeFromMountPath:(NSString *)mountPath
731 FSVolumeRefNum actualVolume;
732 err = FSPathMakeRef ( (const UInt8 *) [mountPath fileSystemRepresentation], &ref, NULL );
734 // get a FSVolumeRefNum from mountPath
735 if ( noErr == err ) {
736 FSCatalogInfo catalogInfo;
737 err = FSGetCatalogInfo ( &ref,
744 if ( noErr == err ) {
745 actualVolume = catalogInfo.volume;
749 GetVolParmsInfoBuffer volumeParms;
750 err = FSGetVolumeParms( actualVolume, &volumeParms, sizeof(volumeParms) );
752 CFMutableDictionaryRef matchingDict;
753 io_service_t service;
755 matchingDict = IOBSDNameMatching(kIOMasterPortDefault, 0, volumeParms.vMDeviceID);
756 service = IOServiceGetMatchingService(kIOMasterPortDefault, matchingDict);
759 if (IO_OBJECT_NULL != service) {
760 if (IOObjectConformsTo(service, kIOCDMediaClass)) {
761 returnValue = kVLCMediaAudioCD;
763 else if(IOObjectConformsTo(service, kIODVDMediaClass))
764 returnValue = kVLCMediaDVD;
765 else if(IOObjectConformsTo(service, kIOBDMediaClass))
766 returnValue = kVLCMediaBD;
769 if ([mountPath rangeOfString:@"VIDEO_TS"].location != NSNotFound)
770 returnValue = kVLCMediaVideoTSFolder;
771 else if ([mountPath rangeOfString:@"BDMV"].location != NSNotFound)
772 returnValue = kVLCMediaBDMVFolder;
775 NSArray * topLevelItems;
776 topLevelItems = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath: mountPath error: NULL];
777 NSUInteger itemCount = [topLevelItems count];
778 for (int i = 0; i < itemCount; i++) {
779 if([[topLevelItems objectAtIndex:i] rangeOfString:@"SVCD"].location != NSNotFound) {
780 returnValue = kVLCMediaSVCD;
783 if([[topLevelItems objectAtIndex:i] rangeOfString:@"VCD"].location != NSNotFound) {
784 returnValue = kVLCMediaVCD;
789 returnValue = kVLCMediaUnknown;
793 IOObjectRelease(service);
798 - (void)showOpticalAtIndex: (NSNumber *)n_index
800 NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
802 if (!o_opticalDevices)
805 if ([o_opticalDevices count] == 0)
808 unsigned int index = [n_index intValue];
809 id o_currentOpticalDevice = [o_opticalDevices objectAtIndex: index];
810 char *diskType = [self getVolumeTypeFromMountPath:o_currentOpticalDevice];
812 if (diskType == kVLCMediaDVD || diskType == kVLCMediaVideoTSFolder)
814 [o_disc_dvd_lbl setStringValue: [[NSFileManager defaultManager] displayNameAtPath:o_currentOpticalDevice]];
815 [o_disc_dvdwomenus_lbl setStringValue: [o_disc_dvd_lbl stringValue]];
816 NSString *pathToOpen;
817 if (diskType == kVLCMediaVideoTSFolder)
818 pathToOpen = o_currentOpticalDevice;
820 pathToOpen = [self getBSDNodeFromMountPath: o_currentOpticalDevice];
822 [self setMRL: [NSString stringWithFormat: @"dvdnav://%@", pathToOpen]];
823 [self showOpticalMediaView: o_disc_dvd_view withIcon: [[NSWorkspace sharedWorkspace] iconForFile: o_currentOpticalDevice]];
825 [self setMRL: [NSString stringWithFormat: @"dvdread://%@@%i:%i-", pathToOpen, [o_disc_dvdwomenus_title intValue], [o_disc_dvdwomenus_chapter intValue]]];
826 [self showOpticalMediaView: o_disc_dvdwomenus_view withIcon: [[NSWorkspace sharedWorkspace] iconForFile: o_currentOpticalDevice]];
829 else if (diskType == kVLCMediaAudioCD)
831 [o_disc_audiocd_lbl setStringValue: [[NSFileManager defaultManager] displayNameAtPath: o_currentOpticalDevice]];
832 [o_disc_audiocd_trackcount_lbl setStringValue: [NSString stringWithFormat:_NS("%i tracks"), [[[NSFileManager defaultManager] subpathsOfDirectoryAtPath: o_currentOpticalDevice error:NULL] count] - 1]]; // minus .TOC.plist
833 [self showOpticalMediaView: o_disc_audiocd_view withIcon: [[NSWorkspace sharedWorkspace] iconForFile: o_currentOpticalDevice]];
834 [self setMRL: [NSString stringWithFormat: @"cdda://%@", [self getBSDNodeFromMountPath: o_currentOpticalDevice]]];
836 else if (diskType == kVLCMediaVCD)
838 [o_disc_vcd_lbl setStringValue: [[NSFileManager defaultManager] displayNameAtPath: o_currentOpticalDevice]];
839 [self showOpticalMediaView: o_disc_vcd_view withIcon: [[NSWorkspace sharedWorkspace] iconForFile: o_currentOpticalDevice]];
840 [self setMRL: [NSString stringWithFormat: @"vcd://%@#%i:%i", [self getBSDNodeFromMountPath: o_currentOpticalDevice], [o_disc_vcd_title intValue], [o_disc_vcd_chapter intValue]]];
842 else if (diskType == kVLCMediaSVCD)
844 [o_disc_vcd_lbl setStringValue: [[NSFileManager defaultManager] displayNameAtPath: o_currentOpticalDevice]];
845 [self showOpticalMediaView: o_disc_vcd_view withIcon: [[NSWorkspace sharedWorkspace] iconForFile: o_currentOpticalDevice]];
846 [self setMRL: [NSString stringWithFormat: @"vcd://%@@%i:%i", [self getBSDNodeFromMountPath: o_currentOpticalDevice], [o_disc_vcd_title intValue], [o_disc_vcd_chapter intValue]]];
848 else if (diskType == kVLCMediaBD || diskType == kVLCMediaBDMVFolder)
850 [o_disc_bd_lbl setStringValue: [[NSFileManager defaultManager] displayNameAtPath: o_currentOpticalDevice]];
851 [self showOpticalMediaView: o_disc_bd_view withIcon: [[NSWorkspace sharedWorkspace] iconForFile: o_currentOpticalDevice]];
852 [self setMRL: [NSString stringWithFormat: @"bluray://%@", o_currentOpticalDevice]];
856 msg_Warn( VLCIntf, "unknown disk type, no idea what to display" );
857 [self showOpticalMediaView: o_disc_nodisc_view withIcon: [NSImage imageNamed:@"NSApplicationIcon"]];
863 - (void)scanOpticalMedia:(NSNotification *)o_notification
865 [o_opticalDevices removeAllObjects];
866 [o_disc_selector_pop removeAllItems];
867 [o_opticalDevices addObjectsFromArray: [[NSWorkspace sharedWorkspace] mountedRemovableMedia]];
868 if ([o_specialMediaFolders count] > 0)
869 [o_opticalDevices addObjectsFromArray: o_specialMediaFolders];
870 if ([o_opticalDevices count] > 0) {
871 NSUInteger deviceCount = [o_opticalDevices count];
872 for (NSUInteger i = 0; i < deviceCount ; i++)
873 [o_disc_selector_pop addItemWithTitle: [[NSFileManager defaultManager] displayNameAtPath:[o_opticalDevices objectAtIndex: i]]];
875 if ([o_disc_selector_pop numberOfItems] <= 1)
876 [o_disc_selector_pop setHidden: YES];
878 [o_disc_selector_pop setHidden: NO];
880 [NSThread detachNewThreadSelector:@selector(showOpticalAtIndex:) toTarget:self withObject:[NSNumber numberWithInt:[o_disc_selector_pop indexOfSelectedItem]]];
884 msg_Dbg( VLCIntf, "no optical media found" );
885 [o_disc_selector_pop setHidden: YES];
886 [self showOpticalMediaView: o_disc_nodisc_view withIcon: [NSImage imageNamed: @"NSApplicationIcon"]];
890 - (IBAction)discSelectorChanged:(id)sender
892 [NSThread detachNewThreadSelector:@selector(showOpticalAtIndex:) toTarget:self withObject:[NSNumber numberWithInt:[o_disc_selector_pop indexOfSelectedItem]]];
895 - (IBAction)openSpecialMediaFolder:(id)sender
897 /* this is currently for VIDEO_TS and BDMV folders */
898 NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
900 [o_open_panel setAllowsMultipleSelection: NO];
901 [o_open_panel setCanChooseFiles: NO];
902 [o_open_panel setCanChooseDirectories: YES];
903 [o_open_panel setTitle: [sender title]];
904 [o_open_panel setPrompt: _NS("Open")];
906 if ([o_open_panel runModal] == NSOKButton)
908 NSString *o_path = [[[o_open_panel URLs] objectAtIndex: 0] path];
909 if ([o_path length] > 0 )
911 if ([o_path rangeOfString:@"VIDEO_TS"].location != NSNotFound || [o_path rangeOfString:@"BDMV"].location != NSNotFound)
913 [o_specialMediaFolders addObject: o_path];
914 [self scanOpticalMedia: nil];
917 msg_Dbg( VLCIntf, "chosen directory is no suitable special media folder" );
922 - (IBAction)dvdreadOptionChanged:(id)sender
924 if (sender == o_disc_dvdwomenus_enablemenus_btn) {
926 [self setMRL: [NSString stringWithFormat: @"dvdnav://%@", [self getBSDNodeFromMountPath:[o_opticalDevices objectAtIndex: [o_disc_selector_pop indexOfSelectedItem]]]]];
927 [self showOpticalMediaView: o_disc_dvd_view withIcon: [o_currentOpticalMediaIconView image]];
930 if (sender == o_disc_dvd_disablemenus_btn) {
932 [self showOpticalMediaView: o_disc_dvdwomenus_view withIcon: [o_currentOpticalMediaIconView image]];
935 if (sender == o_disc_dvdwomenus_title)
936 [o_disc_dvdwomenus_title_stp setIntValue: [o_disc_dvdwomenus_title intValue]];
937 if (sender == o_disc_dvdwomenus_title_stp)
938 [o_disc_dvdwomenus_title setIntValue: [o_disc_dvdwomenus_title_stp intValue]];
939 if (sender == o_disc_dvdwomenus_chapter)
940 [o_disc_dvdwomenus_chapter_stp setIntValue: [o_disc_dvdwomenus_chapter intValue]];
941 if (sender == o_disc_dvdwomenus_chapter_stp)
942 [o_disc_dvdwomenus_chapter setIntValue: [o_disc_dvdwomenus_chapter_stp intValue]];
944 [self setMRL: [NSString stringWithFormat: @"dvdread://%@@%i:%i-", [self getBSDNodeFromMountPath:[o_opticalDevices objectAtIndex: [o_disc_selector_pop indexOfSelectedItem]]], [o_disc_dvdwomenus_title intValue], [o_disc_dvdwomenus_chapter intValue]]];
947 - (IBAction)vcdOptionChanged:(id)sender
949 if (sender == o_disc_vcd_title)
950 [o_disc_vcd_title_stp setIntValue: [o_disc_vcd_title intValue]];
951 if (sender == o_disc_vcd_title_stp)
952 [o_disc_vcd_title setIntValue: [o_disc_vcd_title_stp intValue]];
953 if (sender == o_disc_vcd_chapter)
954 [o_disc_vcd_chapter_stp setIntValue: [o_disc_vcd_chapter intValue]];
955 if (sender == o_disc_vcd_chapter_stp)
956 [o_disc_vcd_chapter setIntValue: [o_disc_vcd_chapter_stp intValue]];
958 [self setMRL: [NSString stringWithFormat: @"vcd://%@@%i:%i", [self getBSDNodeFromMountPath:[o_opticalDevices objectAtIndex: [o_disc_selector_pop indexOfSelectedItem]]], [o_disc_vcd_title intValue], [o_disc_vcd_chapter intValue]]];
961 - (void)textFieldWasClicked:(NSNotification *)o_notification
963 if( [o_notification object] == o_net_udp_port )
964 [o_net_mode selectCellAtRow: 0 column: 0];
965 else if( [o_notification object] == o_net_udpm_addr ||
966 [o_notification object] == o_net_udpm_port )
967 [o_net_mode selectCellAtRow: 1 column: 0];
969 [o_net_mode selectCellAtRow: 2 column: 0];
971 [self openNetInfoChanged: nil];
974 - (IBAction)openNetModeChanged:(id)sender
976 if( sender == o_net_mode )
978 if( [[sender selectedCell] tag] == 0 )
979 [o_panel makeFirstResponder: o_net_udp_port];
980 else if ( [[sender selectedCell] tag] == 1 )
981 [o_panel makeFirstResponder: o_net_udpm_addr];
983 msg_Warn( p_intf, "Unknown sender tried to change UDP/RTP mode" );
986 [self openNetInfoChanged: nil];
989 - (IBAction)openNetStepperChanged:(id)sender
991 int i_tag = [sender tag];
995 [o_net_udp_port setIntValue: [o_net_udp_port_stp intValue]];
996 [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCOpenTextFieldWasClicked"
997 object: o_net_udp_port];
998 [o_panel makeFirstResponder: o_net_udp_port];
1000 else if( i_tag == 1 )
1002 [o_net_udpm_port setIntValue: [o_net_udpm_port_stp intValue]];
1003 [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCOpenTextFieldWasClicked"
1004 object: o_net_udpm_port];
1005 [o_panel makeFirstResponder: o_net_udpm_port];
1008 [self openNetInfoChanged: nil];
1011 - (void)openNetInfoChanged:(NSNotification *)o_notification
1013 NSString *o_mrl_string = [NSString string];
1015 if( [o_net_udp_panel isVisible] )
1018 o_mode = [[o_net_mode selectedCell] title];
1020 if( [o_mode isEqualToString: _NS("Unicast")] )
1022 int i_port = [o_net_udp_port intValue];
1024 if( [[o_net_udp_protocol_mat selectedCell] tag] == 0 )
1025 o_mrl_string = [NSString stringWithString: @"udp://"];
1027 o_mrl_string = [NSString stringWithString: @"rtp://"];
1029 if( i_port != config_GetInt( p_intf, "server-port" ) )
1032 [o_mrl_string stringByAppendingFormat: @"@:%i", i_port];
1035 else if( [o_mode isEqualToString: _NS("Multicast")] )
1037 NSString *o_addr = [o_net_udpm_addr stringValue];
1038 int i_port = [o_net_udpm_port intValue];
1040 if( [[o_net_udp_protocol_mat selectedCell] tag] == 0 )
1041 o_mrl_string = [NSString stringWithFormat: @"udp://@%@", o_addr];
1043 o_mrl_string = [NSString stringWithFormat: @"rtp://@%@", o_addr];
1045 if( i_port != config_GetInt( p_intf, "server-port" ) )
1048 [o_mrl_string stringByAppendingFormat: @":%i", i_port];
1054 o_mrl_string = [o_net_http_url stringValue];
1056 [self setMRL: o_mrl_string];
1059 - (IBAction)openNetUDPButtonAction:(id)sender
1061 if( sender == o_net_openUDP_btn )
1063 [NSApp beginSheet: o_net_udp_panel
1064 modalForWindow: o_panel
1066 didEndSelector: NULL
1068 [self openNetInfoChanged: nil];
1070 else if( sender == o_net_udp_cancel_btn )
1072 [o_net_udp_panel orderOut: sender];
1073 [NSApp endSheet: o_net_udp_panel];
1075 else if( sender == o_net_udp_ok_btn )
1077 NSString *o_mrl_string = [NSString string];
1078 if( [[[o_net_mode selectedCell] title] isEqualToString: _NS("Unicast")] )
1080 int i_port = [o_net_udp_port intValue];
1082 if( [[o_net_udp_protocol_mat selectedCell] tag] == 0 )
1083 o_mrl_string = [NSString stringWithString: @"udp://"];
1085 o_mrl_string = [NSString stringWithString: @"rtp://"];
1087 if( i_port != config_GetInt( p_intf, "server-port" ) )
1090 [o_mrl_string stringByAppendingFormat: @"@:%i", i_port];
1093 else if( [[[o_net_mode selectedCell] title] isEqualToString: _NS("Multicast")] )
1095 NSString *o_addr = [o_net_udpm_addr stringValue];
1096 int i_port = [o_net_udpm_port intValue];
1098 if( [[o_net_udp_protocol_mat selectedCell] tag] == 0 )
1099 o_mrl_string = [NSString stringWithFormat: @"udp://@%@", o_addr];
1101 o_mrl_string = [NSString stringWithFormat: @"rtp://@%@", o_addr];
1103 if( i_port != config_GetInt( p_intf, "server-port" ) )
1106 [o_mrl_string stringByAppendingFormat: @":%i", i_port];
1109 [self setMRL: o_mrl_string];
1110 [o_net_http_url setStringValue: o_mrl_string];
1111 [o_net_udp_panel orderOut: sender];
1112 [NSApp endSheet: o_net_udp_panel];
1118 NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
1119 b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
1121 [o_open_panel setAllowsMultipleSelection: YES];
1122 [o_open_panel setCanChooseDirectories: YES];
1123 [o_open_panel setTitle: _NS("Open File")];
1124 [o_open_panel setPrompt: _NS("Open")];
1126 if( [o_open_panel runModal] == NSOKButton )
1128 NSArray * o_urls = [o_open_panel URLs];
1129 NSUInteger count = [o_urls count];
1130 NSMutableArray *o_values = [NSMutableArray arrayWithCapacity:count];
1131 NSMutableArray *o_array = [NSMutableArray arrayWithCapacity:count];
1132 for( NSUInteger i = 0; i < count; i++ )
1134 [o_values addObject: [[o_urls objectAtIndex: i] path]];
1136 [o_values sortUsingSelector:@selector(caseInsensitiveCompare:)];
1138 for( NSUInteger i = 0; i < count; i++ )
1140 NSDictionary *o_dic;
1141 char *psz_uri = make_URI([[o_values objectAtIndex:i] UTF8String], "file");
1145 o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"];
1149 [o_array addObject: o_dic];
1152 [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:NO];
1154 [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:YES];
1158 - (void)showCaptureView: theView
1161 o_view_rect = [theView frame];
1162 [theView setFrame: NSMakeRect( 0, -10, o_view_rect.size.width, o_view_rect.size.height)];
1163 [theView setAutoresizesSubviews: YES];
1164 if (o_currentCaptureView)
1166 [[[[o_tabview tabViewItemAtIndex: 3] view] animator] replaceSubview: o_currentCaptureView with: theView];
1167 [o_currentCaptureView release];
1170 [[[[o_tabview tabViewItemAtIndex: 3] view] animator] addSubview: theView];
1171 o_currentCaptureView = theView;
1172 [o_currentCaptureView retain];
1175 - (IBAction)openCaptureModeChanged:(id)sender
1177 if( [[[o_capture_mode_pop selectedItem] title] isEqualToString: @"EyeTV"] )
1179 if( [[[VLCMain sharedInstance] eyeTVController] isEyeTVrunning] == YES )
1181 if( [[[VLCMain sharedInstance] eyeTVController] isDeviceConnected] == YES )
1183 [self showCaptureView: o_eyetv_running_view];
1184 [self setupChannelInfo];
1188 setEyeTVUnconnected;
1192 [self showCaptureView: o_eyetv_notLaunched_view];
1195 else if( [[[o_capture_mode_pop selectedItem] title] isEqualToString: _NS("Screen")] )
1197 [self showCaptureView: o_screen_view];
1198 [self setMRL: @"screen://"];
1199 [o_screen_height_fld setIntValue: config_GetInt( p_intf, "screen-height" )];
1200 [o_screen_width_fld setIntValue: config_GetInt( p_intf, "screen-width" )];
1201 [o_screen_fps_fld setFloatValue: config_GetFloat( p_intf, "screen-fps" )];
1202 [o_screen_left_fld setIntValue: config_GetInt( p_intf, "screen-left" )];
1203 [o_screen_top_fld setIntValue: config_GetInt( p_intf, "screen-top" )];
1204 [o_screen_follow_mouse_ckb setIntValue: config_GetInt( p_intf, "screen-follow-mouse" )];
1206 else if( [[[o_capture_mode_pop selectedItem] title] isEqualToString: _NS("Capture Device")] )
1208 [self showCaptureView: o_qtk_view];
1209 if ([o_capture_width_fld intValue] <= 0)
1210 [self qtkChanged:nil];
1212 if(!qtk_currdevice_uid)
1215 [self setMRL:[NSString stringWithFormat:@"qtcapture://%@", qtk_currdevice_uid]];
1219 - (IBAction)screenStepperChanged:(id)sender
1221 [o_screen_fps_fld setFloatValue: [o_screen_fps_stp floatValue]];
1222 [o_panel makeFirstResponder: o_screen_fps_fld];
1223 [self setMRL: @"screen://"];
1226 - (void)screenFPSfieldChanged:(NSNotification *)o_notification
1228 [o_screen_fps_stp setFloatValue: [o_screen_fps_fld floatValue]];
1229 if( [[o_screen_fps_fld stringValue] isEqualToString: @""] )
1230 [o_screen_fps_fld setFloatValue: 1.0];
1231 [self setMRL: @"screen://"];
1234 - (IBAction)eyetvSwitchChannel:(id)sender
1236 if( sender == o_eyetv_nextProgram_btn )
1238 int chanNum = [[[VLCMain sharedInstance] eyeTVController] switchChannelUp: YES];
1239 [o_eyetv_channels_pop selectItemWithTag:chanNum];
1240 [self setMRL: [NSString stringWithFormat:@"eyetv:// :eyetv-channel=%d", chanNum]];
1242 else if( sender == o_eyetv_previousProgram_btn )
1244 int chanNum = [[[VLCMain sharedInstance] eyeTVController] switchChannelUp: NO];
1245 [o_eyetv_channels_pop selectItemWithTag:chanNum];
1246 [self setMRL: [NSString stringWithFormat:@"eyetv:// :eyetv-channel=%d", chanNum]];
1248 else if( sender == o_eyetv_channels_pop )
1250 int chanNum = [[sender selectedItem] tag];
1251 [[[VLCMain sharedInstance] eyeTVController] selectChannel:chanNum];
1252 [self setMRL: [NSString stringWithFormat:@"eyetv:// :eyetv-channel=%d", chanNum]];
1255 msg_Err( VLCIntf, "eyetvSwitchChannel sent by unknown object" );
1258 - (IBAction)eyetvLaunch:(id)sender
1260 [[[VLCMain sharedInstance] eyeTVController] launchEyeTV];
1263 - (IBAction)eyetvGetPlugin:(id)sender
1265 [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: @"http://www.videolan.org/vlc/eyetv"]];
1268 - (void)eyetvChanged:(NSNotification *)o_notification
1270 if( [[o_notification name] isEqualToString: @"DeviceAdded"] )
1272 msg_Dbg( VLCIntf, "eyetv device was added" );
1273 [self showCaptureView: o_eyetv_running_view];
1274 [self setupChannelInfo];
1276 else if( [[o_notification name] isEqualToString: @"DeviceRemoved"] )
1278 /* leave the channel selection like that,
1279 * switch to our "no device" tab */
1280 msg_Dbg( VLCIntf, "eyetv device was removed" );
1281 setEyeTVUnconnected;
1283 else if( [[o_notification name] isEqualToString: @"PluginQuit"] )
1285 /* switch to the "launch eyetv" tab */
1286 msg_Dbg( VLCIntf, "eyetv was terminated" );
1287 [self showCaptureView: o_eyetv_notLaunched_view];
1289 else if( [[o_notification name] isEqualToString: @"PluginInit"] )
1291 /* we got no device yet */
1292 msg_Dbg( VLCIntf, "eyetv was launched, no device yet" );
1293 setEyeTVUnconnected;
1297 /* little helper method, since this code needs to be run by multiple objects */
1298 - (void)setupChannelInfo
1300 /* set up channel selection */
1301 [o_eyetv_channels_pop removeAllItems];
1302 [o_eyetv_chn_bgbar setHidden: NO];
1303 [o_eyetv_chn_bgbar animate: self];
1304 [o_eyetv_chn_status_txt setStringValue: _NS("Retrieving Channel Info...")];
1305 [o_eyetv_chn_status_txt setHidden: NO];
1308 NSEnumerator *channels = [[[VLCMain sharedInstance] eyeTVController] allChannels];
1310 [[[o_eyetv_channels_pop menu] addItemWithTitle: _NS("Composite input")
1312 keyEquivalent: @""] setTag:x++];
1313 [[[o_eyetv_channels_pop menu] addItemWithTitle: _NS("S-Video input")
1315 keyEquivalent: @""] setTag:x++];
1319 [[o_eyetv_channels_pop menu] addItem: [NSMenuItem separatorItem]];
1320 while( channel = [channels nextObject] )
1322 /* we have to add items this way, because we accept duplicates
1323 * additionally, we save a bit of time */
1324 [[[o_eyetv_channels_pop menu] addItemWithTitle: channel
1326 keyEquivalent: @""] setTag:++x];
1328 /* make Tuner the default */
1329 [o_eyetv_channels_pop selectItemWithTag:[[[VLCMain sharedInstance] eyeTVController] currentChannel]];
1333 [o_eyetv_chn_bgbar setHidden: YES];
1334 [o_eyetv_chn_status_txt setHidden: YES];
1337 - (IBAction)subsChanged:(id)sender
1339 if ([o_file_sub_ckbox state] == NSOnState)
1341 [o_file_sub_btn_settings setEnabled:YES];
1343 [o_file_subtitles_filename_lbl setStringValue: [[NSFileManager defaultManager] displayNameAtPath:o_sub_path]];
1344 [o_file_subtitles_icon_well setImage: [[NSWorkspace sharedWorkspace] iconForFile:o_sub_path]];
1349 [o_file_sub_btn_settings setEnabled:NO];
1350 [o_file_subtitles_filename_lbl setStringValue: @""];
1351 [o_file_subtitles_icon_well setImage: NULL];
1355 - (IBAction)subSettings:(id)sender
1357 [NSApp beginSheet: o_file_sub_sheet
1358 modalForWindow: [sender window]
1360 didEndSelector: NULL
1364 - (IBAction)subCloseSheet:(id)sender
1366 [self subsChanged: nil];
1367 [o_file_sub_sheet orderOut:sender];
1368 [NSApp endSheet: o_file_sub_sheet];
1371 - (IBAction)subFileBrowse:(id)sender
1373 NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
1375 [o_open_panel setAllowsMultipleSelection: NO];
1376 [o_open_panel setTitle: _NS("Open File")];
1377 [o_open_panel setPrompt: _NS("Open")];
1379 if( [o_open_panel runModal] == NSOKButton )
1381 o_sub_path = [[[o_open_panel URLs] objectAtIndex: 0] path];
1382 [o_sub_path retain];
1383 [o_file_subtitles_filename_lbl setStringValue: [[NSFileManager defaultManager] displayNameAtPath:o_sub_path]];
1384 [o_file_sub_path_fld setStringValue: [o_file_subtitles_filename_lbl stringValue]];
1385 [o_file_sub_path_lbl setHidden: YES];
1386 [o_file_subtitles_icon_well setImage: [[NSWorkspace sharedWorkspace] iconForFile:o_sub_path]];
1387 [o_file_sub_icon_view setImage: [o_file_subtitles_icon_well image]];
1391 [o_file_sub_path_lbl setHidden: NO];
1392 [o_file_sub_path_fld setStringValue:@""];
1393 [o_file_subtitles_filename_lbl setStringValue:@""];
1394 [o_file_subtitles_icon_well setImage: nil];
1395 [o_file_sub_icon_view setImage: nil];
1399 - (IBAction)subOverride:(id)sender
1401 BOOL b_state = [o_file_sub_override state];
1402 [o_file_sub_delay setEnabled: b_state];
1403 [o_file_sub_delay_stp setEnabled: b_state];
1404 [o_file_sub_fps setEnabled: b_state];
1405 [o_file_sub_fps_stp setEnabled: b_state];
1408 - (IBAction)subDelayStepperChanged:(id)sender
1410 [o_file_sub_delay setIntValue: [o_file_sub_delay_stp intValue]];
1413 - (IBAction)subFpsStepperChanged:(id)sender;
1415 [o_file_sub_fps setFloatValue: [o_file_sub_fps_stp floatValue]];
1418 - (IBAction)panelCancel:(id)sender
1420 [NSApp stopModalWithCode: 0];
1423 - (IBAction)panelOk:(id)sender
1425 if( [[self MRL] length] )
1426 [NSApp stopModalWithCode: 1];
1431 - (NSArray *)qtkvideoDevices
1433 if (!qtkvideoDevices)
1434 [self qtkrefreshDevices];
1435 return qtkvideoDevices;
1438 - (void)qtkrefreshDevices
1440 [qtkvideoDevices release];
1441 qtkvideoDevices = [[[QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo] arrayByAddingObjectsFromArray:[QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeMuxed]] retain];
1446 @implementation VLCOpenTextField
1448 - (void)mouseDown:(NSEvent *)theEvent
1450 [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCOpenTextFieldWasClicked"
1452 [super mouseDown: theEvent];