]> git.sesse.net Git - vlc/blob - modules/gui/macosx/open.m
* demuxdump is working again
[vlc] / modules / gui / macosx / open.m
1 /*****************************************************************************
2  * open.m: MacOS X module for vlc
3  *****************************************************************************
4  * Copyright (C) 2002-2003 VideoLAN
5  * $Id$
6  *
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  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <stdlib.h>                                      /* malloc(), free() */
30 #include <sys/param.h>                                    /* for MAXPATHLEN */
31 #include <string.h>
32
33 #include <paths.h>
34 #include <IOKit/IOKitLib.h>
35 #include <IOKit/IOBSD.h>
36 #include <IOKit/storage/IOMedia.h>
37 #include <IOKit/storage/IOCDMedia.h>
38 #include <IOKit/storage/IODVDMedia.h>
39
40 #include "intf.h"
41 #include "playlist.h"
42 #include "open.h"
43 #include "output.h"
44
45 /*****************************************************************************
46  * GetEjectableMediaOfClass 
47  *****************************************************************************/
48 NSArray *GetEjectableMediaOfClass( const char *psz_class )
49 {
50     io_object_t next_media;
51     mach_port_t master_port;
52     kern_return_t kern_result;
53     NSArray *o_devices = nil;
54     NSMutableArray *p_list = nil;
55     io_iterator_t media_iterator;
56     CFMutableDictionaryRef classes_to_match;
57
58     kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );
59     if( kern_result != KERN_SUCCESS )
60     {
61         return( nil );
62     }
63     
64     classes_to_match = IOServiceMatching( psz_class );
65     if( classes_to_match == NULL )
66     {
67         return( nil );
68     }
69     
70     CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ), 
71                           kCFBooleanTrue );
72     
73     kern_result = IOServiceGetMatchingServices( master_port, classes_to_match, 
74                                                 &media_iterator );
75     if( kern_result != KERN_SUCCESS )
76     {
77         return( nil );
78     }
79
80     p_list = [NSMutableArray arrayWithCapacity: 1];
81     
82     next_media = IOIteratorNext( media_iterator );
83     if( next_media != NULL )
84     {
85         char psz_buf[0x32];
86         size_t dev_path_length;
87         CFTypeRef str_bsd_path;
88     
89         do
90         {
91             str_bsd_path = IORegistryEntryCreateCFProperty( next_media,
92                                                             CFSTR( kIOBSDNameKey ),
93                                                             kCFAllocatorDefault,
94                                                             0 );
95             if( str_bsd_path == NULL )
96             {
97                 IOObjectRelease( next_media );
98                 continue;
99             }
100             
101             snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );
102             dev_path_length = strlen( psz_buf );
103             
104             if( CFStringGetCString( str_bsd_path,
105                                     (char*)&psz_buf + dev_path_length,
106                                     sizeof(psz_buf) - dev_path_length,
107                                     kCFStringEncodingASCII ) )
108             {
109                 [p_list addObject: [NSString stringWithCString: psz_buf]];
110             }
111             
112             CFRelease( str_bsd_path );
113             
114             IOObjectRelease( next_media );
115         
116         } while( ( next_media = IOIteratorNext( media_iterator ) ) != NULL );
117     }
118     
119     IOObjectRelease( media_iterator );
120
121     o_devices = [NSArray arrayWithArray: p_list];
122
123     return( o_devices );
124 }
125
126 /*****************************************************************************
127  * VLCOpen implementation 
128  *****************************************************************************/
129 @implementation VLCOpen
130
131 - (void)awakeFromNib
132 {
133     intf_thread_t * p_intf = VLCIntf;
134
135     [o_panel setTitle: _NS("Open Source")];
136     [o_mrl_lbl setTitle: _NS("Media Resource Locator (MRL)")];
137
138     [o_btn_ok setTitle: _NS("OK")];
139     [o_btn_cancel setTitle: _NS("Cancel")];
140
141     [[o_tabview tabViewItemAtIndex: 0] setLabel: _NS("File")];
142     [[o_tabview tabViewItemAtIndex: 1] setLabel: _NS("Disc")];
143     [[o_tabview tabViewItemAtIndex: 2] setLabel: _NS("Network")];
144
145     [o_file_btn_browse setTitle: _NS("Browse...")];
146     [o_file_stream setTitle: _NS("Treat as a pipe rather than as a file")];
147
148     [o_disc_device_lbl setStringValue: _NS("Device name")];
149     [o_disc_title_lbl setStringValue: _NS("Title")];
150     [o_disc_chapter_lbl setStringValue: _NS("Chapter")];
151     [o_disc_videots_btn_browse setTitle: _NS("Browse...")];
152     [o_disc_dvd_menus setTitle: _NS("Use DVD menus")];
153
154     [[o_disc_type cellAtRow:0 column:0] setTitle: _NS("VIDEO_TS folder")];
155     [[o_disc_type cellAtRow:1 column:0] setTitle: _NS("DVD")];
156     [[o_disc_type cellAtRow:2 column:0] setTitle: _NS("VCD")];
157     [[o_disc_type cellAtRow:3 column:0] setTitle: _NS("Audio CD")];
158
159     [o_net_udp_port_lbl setStringValue: _NS("Port")];
160     [o_net_udpm_addr_lbl setStringValue: _NS("Address")];
161     [o_net_udpm_port_lbl setStringValue: _NS("Port")];
162     [o_net_http_url_lbl setStringValue: _NS("URL")];
163
164     [[o_net_mode cellAtRow:0 column:0] setTitle: _NS("UDP/RTP")];
165     [[o_net_mode cellAtRow:1 column:0] setTitle: _NS("UDP/RTP Multicast")];
166     [[o_net_mode cellAtRow:2 column:0] setTitle: _NS("HTTP/FTP/MMS")];
167
168     [o_net_udp_port setIntValue: config_GetInt( p_intf, "server-port" )];
169     [o_net_udp_port_stp setIntValue: config_GetInt( p_intf, "server-port" )];
170
171     [o_file_sub_ckbox setTitle: _NS("Load subtitles file:")];
172     [o_file_sub_btn_settings setTitle: _NS("Settings...")];
173     [o_file_sub_btn_browse setTitle: _NS("Browse...")];
174     [o_file_sub_override setTitle: _NS("Override")];
175     [o_file_sub_delay_lbl setStringValue: _NS("delay")];
176     [o_file_sub_delay_stp setEnabled: NO];
177     [o_file_sub_fps_lbl setStringValue: _NS("fps")];
178     [o_file_sub_fps_stp setEnabled: NO];
179     [o_file_sub_ok_btn setStringValue: _NS("OK")];
180     
181     [[NSNotificationCenter defaultCenter] addObserver: self
182         selector: @selector(openFilePathChanged:)
183         name: NSControlTextDidChangeNotification
184         object: o_file_path];
185
186     [[NSNotificationCenter defaultCenter] addObserver: self
187         selector: @selector(openDiscInfoChanged:)
188         name: NSControlTextDidChangeNotification
189         object: o_disc_device];
190     [[NSNotificationCenter defaultCenter] addObserver: self
191         selector: @selector(openDiscInfoChanged:)
192         name: NSControlTextDidChangeNotification
193         object: o_disc_title];
194     [[NSNotificationCenter defaultCenter] addObserver: self
195         selector: @selector(openDiscInfoChanged:)
196         name: NSControlTextDidChangeNotification
197         object: o_disc_chapter];
198     [[NSNotificationCenter defaultCenter] addObserver: self
199         selector: @selector(openDiscInfoChanged:)
200         name: NSControlTextDidChangeNotification
201         object: o_disc_videots_folder];
202
203     [[NSNotificationCenter defaultCenter] addObserver: self
204         selector: @selector(openNetInfoChanged:)
205         name: NSControlTextDidChangeNotification
206         object: o_net_udp_port];
207     [[NSNotificationCenter defaultCenter] addObserver: self
208         selector: @selector(openNetInfoChanged:)
209         name: NSControlTextDidChangeNotification
210         object: o_net_udpm_addr];
211     [[NSNotificationCenter defaultCenter] addObserver: self
212         selector: @selector(openNetInfoChanged:)
213         name: NSControlTextDidChangeNotification
214         object: o_net_udpm_port];
215     [[NSNotificationCenter defaultCenter] addObserver: self
216         selector: @selector(openNetInfoChanged:)
217         name: NSControlTextDidChangeNotification
218         object: o_net_http_url];
219 }
220
221 - (void)openTarget:(int)i_type
222 {
223     int i_result;
224
225     [o_tabview selectTabViewItemAtIndex: i_type];
226     [o_file_sub_ckbox setState: NSOffState];
227     
228     i_result = [NSApp runModalForWindow: o_panel];
229     [o_panel close];
230
231     if( i_result )
232     {
233         NSMutableDictionary *o_dic;
234         NSMutableArray *o_options = [NSMutableArray array];
235         unsigned int i;
236
237         o_dic = [NSMutableDictionary dictionaryWithObject: [o_mrl stringValue] forKey: @"ITEM_URL"];
238         if( [o_file_sub_ckbox state] == NSOnState )
239         {
240             [o_options addObject: [NSString stringWithFormat: @"sub-file=%s", [[o_file_sub_path stringValue] UTF8String]]];
241             if( [o_file_sub_override state] == NSOnState )
242             {
243                 [o_options addObject: [NSString stringWithFormat: @"sub-delay=%i", (int)( [o_file_sub_delay intValue] * 10 )]];
244                 [o_options addObject: [NSString stringWithFormat: @"sub-fps=%f", [o_file_sub_fps floatValue]]];
245             }
246         }
247         if( [o_output_ckbox state] == NSOnState )
248         {
249             for (i = 0 ; i < [[o_sout_options getMRL] count] ; i++)
250             {
251                 [o_options addObject: [NSString stringWithString:
252                       [[(VLCOutput *)o_sout_options getMRL] objectAtIndex: i]]];
253             }
254         }
255         [o_dic setObject: (NSArray *)[o_options copy] forKey: @"ITEM_OPTIONS"];
256         [o_playlist appendArray: [NSArray arrayWithObject: o_dic] atPos: -1 enqueue:NO];
257     }
258 }
259
260 - (void)tabView:(NSTabView *)o_tv didSelectTabViewItem:(NSTabViewItem *)o_tvi
261 {
262     NSString *o_label = [o_tvi label];
263
264     if( [o_label isEqualToString: _NS("File")] )
265     {
266         [self openFilePathChanged: nil];
267     }
268     else if( [o_label isEqualToString: _NS("Disc")] )
269     {
270         [self openDiscTypeChanged: nil];
271     }
272     else if( [o_label isEqualToString: _NS("Network")] )
273     {
274         [self openNetModeChanged: nil];
275     }  
276 }
277
278 - (IBAction)openFileGeneric:(id)sender
279 {
280     [self openFilePathChanged: nil];
281     [self openTarget: 0];
282 }
283
284 - (IBAction)openDisc:(id)sender
285 {
286     [self openDiscTypeChanged: nil];
287     [self openTarget: 1];
288 }
289
290 - (IBAction)openNet:(id)sender
291 {
292     [self openNetModeChanged: nil];
293     [self openTarget: 2];
294 }
295
296 - (void)openFilePathChanged:(NSNotification *)o_notification
297 {
298     NSString *o_mrl_string;
299     NSString *o_filename = [o_file_path stringValue];
300     NSString *o_ext = [o_filename pathExtension];
301     vlc_bool_t b_stream = [o_file_stream state];
302     BOOL b_dir = NO;
303     
304     [[NSFileManager defaultManager] fileExistsAtPath:o_filename isDirectory:&b_dir];
305
306     if( b_dir )
307     {
308         o_mrl_string = [NSString stringWithFormat: @"dir:%@", o_filename];
309     }
310     else if( [o_ext isEqualToString: @"bin"] ||
311         [o_ext isEqualToString: @"cue"] ||
312         [o_ext isEqualToString: @"vob"] ||
313         [o_ext isEqualToString: @"iso"] )
314     {
315         o_mrl_string = o_filename;
316     }
317     else
318     {
319         o_mrl_string = [NSString stringWithFormat: @"%s://%@",
320                         b_stream ? "stream" : "file",
321                         o_filename];
322     }
323     [o_mrl setStringValue: o_mrl_string]; 
324 }
325
326 - (IBAction)openFileBrowse:(id)sender
327 {
328     NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
329     
330     [o_open_panel setAllowsMultipleSelection: NO];
331     [o_open_panel setCanChooseDirectories: YES];
332     [o_open_panel setTitle: _NS("Open File")];
333     [o_open_panel setPrompt: _NS("Open")];
334
335     [o_open_panel beginSheetForDirectory:nil
336         file:nil
337         types:nil
338         modalForWindow:[sender window]
339         modalDelegate: self
340         didEndSelector: @selector(pathChosenInPanel: 
341                         withReturn:
342                         contextInfo:)
343         contextInfo: nil];
344 }
345
346 - (void)pathChosenInPanel: (NSOpenPanel *) sheet withReturn:(int)returnCode contextInfo:(void  *)contextInfo
347 {
348     if (returnCode == NSFileHandlingPanelOKButton)
349     {
350         NSString *o_filename = [[sheet filenames] objectAtIndex: 0];
351         [o_file_path setStringValue: o_filename];
352         [self openFilePathChanged: nil];
353     }
354 }
355
356 - (IBAction)openFileStreamChanged:(id)sender
357 {
358     [self openFilePathChanged: nil];
359 }
360
361 - (IBAction)openDiscTypeChanged:(id)sender
362 {
363     NSString *o_type;
364     vlc_bool_t b_device, b_menus, b_title_chapter;
365     
366     [o_disc_device removeAllItems];
367     b_title_chapter = ![o_disc_dvd_menus state];
368     
369     o_type = [[o_disc_type selectedCell] title];
370
371     if ( [o_type isEqualToString: _NS("VIDEO_TS folder")] )
372     {
373         b_device = 0; b_menus = 1;
374     }
375     else
376     {
377         NSArray *o_devices;
378         NSString *o_disc;
379         const char *psz_class = NULL;
380         b_device = 1;
381
382         if ( [o_type isEqualToString: _NS("VCD")] )
383         {
384             psz_class = kIOCDMediaClass;
385             o_disc = o_type;
386             b_menus = 0; b_title_chapter = 1;
387             [o_disc_dvd_menus setState: FALSE];
388         }
389         else if ( [o_type isEqualToString: _NS("Audio CD")])
390         {
391             psz_class = kIOCDMediaClass;
392             o_disc = o_type;
393             b_menus = 0; b_title_chapter = 0;
394             [o_disc_dvd_menus setState: FALSE];
395         }
396         else
397         {
398             psz_class = kIODVDMediaClass;
399             o_disc = o_type;
400             b_menus = 1;
401         }
402     
403         o_devices = GetEjectableMediaOfClass( psz_class );
404         if ( o_devices != nil )
405         {
406             int i_devices = [o_devices count];
407         
408             if ( i_devices )
409             {
410                 int i;
411         
412                 for( i = 0; i < i_devices; i++ )
413                 {
414                     [o_disc_device 
415                         addItemWithObjectValue: [o_devices objectAtIndex: i]];
416                 }
417
418                 [o_disc_device selectItemAtIndex: 0];
419             }
420             else
421             {
422                 [o_disc_device setStringValue: 
423                     [NSString stringWithFormat: _NS("No %@s found"), o_disc]];
424             }
425         }
426     }
427
428     [o_disc_device setEnabled: b_device];
429     [o_disc_title setEnabled: b_title_chapter];
430     [o_disc_title_stp setEnabled: b_title_chapter];
431     [o_disc_chapter setEnabled: b_title_chapter];
432     [o_disc_chapter_stp setEnabled: b_title_chapter];
433     [o_disc_videots_folder setEnabled: !b_device];
434     [o_disc_videots_btn_browse setEnabled: !b_device];
435     [o_disc_dvd_menus setEnabled: b_menus];
436
437     [self openDiscInfoChanged: nil];
438 }
439
440 - (IBAction)openDiscStepperChanged:(id)sender
441 {
442     int i_tag = [sender tag];
443
444     if( i_tag == 0 )
445     {
446         [o_disc_title setIntValue: [o_disc_title_stp intValue]];
447     }
448     else if( i_tag == 1 )
449     {
450         [o_disc_chapter setIntValue: [o_disc_chapter_stp intValue]];
451     }
452
453     [self openDiscInfoChanged: nil];
454 }
455
456 - (void)openDiscInfoChanged:(NSNotification *)o_notification
457 {
458     NSString *o_type;
459     NSString *o_device;
460     NSString *o_videots;
461     NSString *o_mrl_string;
462     int i_title, i_chapter;
463     vlc_bool_t b_menus;
464
465     o_type = [[o_disc_type selectedCell] title];
466     o_device = [o_disc_device stringValue];
467     i_title = [o_disc_title intValue];
468     i_chapter = [o_disc_chapter intValue];
469     o_videots = [o_disc_videots_folder stringValue];
470     b_menus = [o_disc_dvd_menus state];
471
472     if ( [o_type isEqualToString: _NS("VCD")] )
473     {
474         if ( [o_device isEqualToString:
475                 [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
476             o_device = @"";
477         o_mrl_string = [NSString stringWithFormat: @"vcd://%@@%i,%i",
478                         o_device, i_title, i_chapter]; 
479     }
480     else if ( [o_type isEqualToString: _NS("Audio CD")] )
481     {
482         if ( [o_device isEqualToString:
483                 [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
484             o_device = @"";
485         o_mrl_string = [NSString stringWithFormat: @"cdda://%@",
486                         o_device]; 
487     }
488     else if ( [o_type isEqualToString: _NS("DVD")] )
489     {
490         if ( [o_device isEqualToString:
491                 [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
492             o_device = @"";
493         if ( b_menus )
494             o_mrl_string = [NSString stringWithFormat: @"dvdnav://%@",
495                             o_device]; 
496         else
497             o_mrl_string = [NSString stringWithFormat: @"dvdread://%@@%i,%i",
498                             o_device, i_title, i_chapter]; 
499     }
500     else /* VIDEO_TS folder */
501     {
502         if ( b_menus )
503             o_mrl_string = [NSString stringWithFormat: @"dvdnav://%@",
504                             o_videots]; 
505         else
506             o_mrl_string = [NSString stringWithFormat: @"dvdread://%@@%i,%i",
507                             o_videots, i_title, i_chapter]; 
508     }
509
510     [o_mrl setStringValue: o_mrl_string]; 
511 }
512
513 - (IBAction)openDiscMenusChanged:(id)sender
514 {
515     [self openDiscInfoChanged: nil];
516     [self openDiscTypeChanged: nil];
517 }
518
519 - (IBAction)openVTSBrowse:(id)sender
520 {
521     NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
522
523     [o_open_panel setAllowsMultipleSelection: NO];
524     [o_open_panel setCanChooseFiles: NO];
525     [o_open_panel setCanChooseDirectories: YES];
526     [o_open_panel setTitle: _NS("Open VIDEO_TS Directory")];
527     [o_open_panel setPrompt: _NS("Open")];
528
529     if( [o_open_panel runModalForDirectory: nil
530             file: nil types: nil] == NSOKButton )
531     {
532         NSString *o_dirname = [[o_open_panel filenames] objectAtIndex: 0];
533         [o_disc_videots_folder setStringValue: o_dirname];
534         [self openDiscInfoChanged: nil];
535     }
536 }
537
538 - (IBAction)openNetModeChanged:(id)sender
539 {
540     NSString *o_mode;
541     BOOL b_udp = FALSE;
542     BOOL b_udpm = FALSE;
543     BOOL b_http = FALSE;
544
545     o_mode = [[o_net_mode selectedCell] title];
546
547     if( [o_mode isEqualToString: _NS("UDP/RTP")] ) b_udp = TRUE;   
548     else if( [o_mode isEqualToString: _NS("UDP/RTP Multicast")] ) b_udpm = TRUE;
549     else if( [o_mode isEqualToString: _NS("HTTP/FTP/MMS")] ) b_http = TRUE;
550
551     [o_net_udp_port setEnabled: b_udp];
552     [o_net_udp_port_stp setEnabled: b_udp];
553     [o_net_udpm_addr setEnabled: b_udpm];
554     [o_net_udpm_port setEnabled: b_udpm];
555     [o_net_udpm_port_stp setEnabled: b_udpm];
556     [o_net_http_url setEnabled: b_http];
557
558     [self openNetInfoChanged: nil];
559 }
560
561 - (IBAction)openNetStepperChanged:(id)sender
562 {
563     int i_tag = [sender tag];
564
565     if( i_tag == 0 )
566     {
567         [o_net_udp_port setIntValue: [o_net_udp_port_stp intValue]];
568     }
569     else if( i_tag == 1 )
570     {
571         [o_net_udpm_port setIntValue: [o_net_udpm_port_stp intValue]];
572     }
573
574     [self openNetInfoChanged: nil];
575 }
576
577 - (void)openNetInfoChanged:(NSNotification *)o_notification
578 {
579     NSString *o_mode;
580     NSString *o_mrl_string = [NSString string];
581     intf_thread_t * p_intf = VLCIntf;
582
583     o_mode = [[o_net_mode selectedCell] title];
584
585     if( [o_mode isEqualToString: _NS("UDP/RTP")] )
586     {
587         int i_port = [o_net_udp_port intValue];
588
589         o_mrl_string = [NSString stringWithString: @"udp://"]; 
590
591         if( i_port != config_GetInt( p_intf, "server-port" ) )
592         {
593             o_mrl_string = 
594                 [o_mrl_string stringByAppendingFormat: @"@:%i", i_port]; 
595         } 
596     }
597     else if( [o_mode isEqualToString: _NS("UDP/RTP Multicast")] ) 
598     {
599         NSString *o_addr = [o_net_udpm_addr stringValue];
600         int i_port = [o_net_udpm_port intValue];
601
602         o_mrl_string = [NSString stringWithFormat: @"udp://@%@", o_addr]; 
603
604         if( i_port != config_GetInt( p_intf, "server-port" ) )
605         {
606             o_mrl_string = 
607                 [o_mrl_string stringByAppendingFormat: @":%i", i_port]; 
608         } 
609     }
610     else if( [o_mode isEqualToString: _NS("HTTP/FTP/MMS")] )
611     {
612         NSString *o_url = [o_net_http_url stringValue];
613
614         if ( ![o_url hasPrefix:@"http:"] && ![o_url hasPrefix:@"ftp:"]
615               && ![o_url hasPrefix:@"mms"] )
616             o_mrl_string = [NSString stringWithFormat: @"http://%@", o_url];
617         else
618             o_mrl_string = o_url;
619     }
620
621     [o_mrl setStringValue: o_mrl_string];
622 }
623
624 - (IBAction)openFile:(id)sender
625 {
626     NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
627     int i;
628     
629     [o_open_panel setAllowsMultipleSelection: YES];
630     [o_open_panel setCanChooseDirectories: YES];
631     [o_open_panel setTitle: _NS("Open File")];
632     [o_open_panel setPrompt: _NS("Open")];
633     
634     if( [o_open_panel runModalForDirectory: nil
635             file: nil types: nil] == NSOKButton )
636     {
637         NSArray *o_array = [NSArray array];
638         NSArray *o_values = [[o_open_panel filenames]
639                 sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
640
641         for( i = 0; i < (int)[o_values count]; i++)
642         {
643             NSDictionary *o_dic;
644             o_dic = [NSDictionary dictionaryWithObject:[o_values objectAtIndex:i] forKey:@"ITEM_URL"];
645             o_array = [o_array arrayByAddingObject: o_dic];
646         }
647         [o_playlist appendArray: o_array atPos: -1 enqueue:NO];
648     }
649 }
650
651 - (IBAction)subsChanged:(id)sender
652 {
653     if ([o_file_sub_ckbox state] == NSOnState)
654     {
655         [o_file_sub_btn_settings setEnabled:YES];
656     }
657     else
658     {
659         [o_file_sub_btn_settings setEnabled:NO];
660     }
661 }
662
663 - (IBAction)subSettings:(id)sender
664 {
665     [NSApp beginSheet: o_file_sub_sheet
666         modalForWindow: [sender window]
667         modalDelegate: self
668         didEndSelector: NULL
669         contextInfo: nil];
670 }
671
672 - (IBAction)subFileBrowse:(id)sender
673 {
674     NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
675     
676     [o_open_panel setAllowsMultipleSelection: NO];
677     [o_open_panel setTitle: _NS("Open File")];
678     [o_open_panel setPrompt: _NS("Open")];
679
680     if( [o_open_panel runModalForDirectory: nil 
681             file: nil types: nil] == NSOKButton )
682     {
683         NSString *o_filename = [[o_open_panel filenames] objectAtIndex: 0];
684         [o_file_sub_path setStringValue: o_filename];
685     }
686 }
687
688 - (IBAction)subOverride:(id)sender
689 {
690     BOOL b_state = [o_file_sub_override state];
691     [o_file_sub_delay setEnabled: b_state];
692     [o_file_sub_delay_stp setEnabled: b_state];
693     [o_file_sub_fps setEnabled: b_state];
694     [o_file_sub_fps_stp setEnabled: b_state];
695 }
696
697 - (IBAction)subDelayStepperChanged:(id)sender
698 {
699     [o_file_sub_delay setIntValue: [o_file_sub_delay_stp intValue]];
700 }
701
702 - (IBAction)subFpsStepperChanged:(id)sender;
703 {
704     [o_file_sub_fps setFloatValue: [o_file_sub_fps_stp floatValue]];
705 }
706
707 - (IBAction)subCloseSheet:(id)sender
708 {
709     [o_file_sub_sheet orderOut:sender];
710     [NSApp endSheet: o_file_sub_sheet];
711 }
712
713 - (IBAction)panelCancel:(id)sender
714 {
715     [NSApp stopModalWithCode: 0];
716 }
717
718 - (IBAction)panelOk:(id)sender
719 {
720     if( [[o_mrl stringValue] length] )
721     {
722         [NSApp stopModalWithCode: 1];
723     }
724     else
725     {
726         NSBeep();
727     }
728 }
729
730 @end