open.m 22.7 KB
Newer Older
1
/*****************************************************************************
2
 * open.m: MacOS X module for vlc
3
 *****************************************************************************
hartman's avatar
hartman committed
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
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#include <stdlib.h>                                      /* malloc(), free() */
#include <sys/param.h>                                    /* for MAXPATHLEN */
#include <string.h>

#include <paths.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/IOCDMedia.h>
#include <IOKit/storage/IODVDMedia.h>

40
41
42
#include "intf.h"
#include "playlist.h"
#include "open.h"
43
#include "output.h"
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

/*****************************************************************************
 * GetEjectableMediaOfClass 
 *****************************************************************************/
NSArray *GetEjectableMediaOfClass( const char *psz_class )
{
    io_object_t next_media;
    mach_port_t master_port;
    kern_return_t kern_result;
    NSArray *o_devices = nil;
    NSMutableArray *p_list = nil;
    io_iterator_t media_iterator;
    CFMutableDictionaryRef classes_to_match;

    kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );
    if( kern_result != KERN_SUCCESS )
    {
        return( nil );
    }
    
    classes_to_match = IOServiceMatching( psz_class );
    if( classes_to_match == NULL )
    {
        return( nil );
    }
    
70
    CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ), 
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
                          kCFBooleanTrue );
    
    kern_result = IOServiceGetMatchingServices( master_port, classes_to_match, 
                                                &media_iterator );
    if( kern_result != KERN_SUCCESS )
    {
        return( nil );
    }

    p_list = [NSMutableArray arrayWithCapacity: 1];
    
    next_media = IOIteratorNext( media_iterator );
    if( next_media != NULL )
    {
        char psz_buf[0x32];
        size_t dev_path_length;
        CFTypeRef str_bsd_path;
    
        do
        {
            str_bsd_path = IORegistryEntryCreateCFProperty( next_media,
92
                                                            CFSTR( kIOBSDNameKey ),
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
                                                            kCFAllocatorDefault,
                                                            0 );
            if( str_bsd_path == NULL )
            {
                IOObjectRelease( next_media );
                continue;
            }
            
            snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );
            dev_path_length = strlen( psz_buf );
            
            if( CFStringGetCString( str_bsd_path,
                                    (char*)&psz_buf + dev_path_length,
                                    sizeof(psz_buf) - dev_path_length,
                                    kCFStringEncodingASCII ) )
            {
                [p_list addObject: [NSString stringWithCString: psz_buf]];
            }
            
            CFRelease( str_bsd_path );
            
            IOObjectRelease( next_media );
        
        } while( ( next_media = IOIteratorNext( media_iterator ) ) != NULL );
    }
    
    IOObjectRelease( media_iterator );

    o_devices = [NSArray arrayWithArray: p_list];

    return( o_devices );
}

/*****************************************************************************
 * VLCOpen implementation 
 *****************************************************************************/
@implementation VLCOpen

- (void)awakeFromNib
{
hartman's avatar
hartman committed
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
139
140
141
142
143
144
145

    [o_btn_ok setTitle: _NS("OK")];
    [o_btn_cancel setTitle: _NS("Cancel")];

    [[o_tabview tabViewItemAtIndex: 0] setLabel: _NS("File")];
    [[o_tabview tabViewItemAtIndex: 1] setLabel: _NS("Disc")];
    [[o_tabview tabViewItemAtIndex: 2] setLabel: _NS("Network")];

    [o_file_btn_browse setTitle: _NS("Browse...")];
146
    [o_file_stream setTitle: _NS("Treat as a pipe rather than as a file")];
147
148
149
150

    [o_disc_device_lbl setStringValue: _NS("Device name")];
    [o_disc_title_lbl setStringValue: _NS("Title")];
    [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
155
    [[o_disc_type cellAtRow:0 column:0] setTitle: _NS("VIDEO_TS folder")];
    [[o_disc_type cellAtRow:1 column:0] setTitle: _NS("DVD")];
156
    [[o_disc_type cellAtRow:2 column:0] setTitle: _NS("VCD")];
hartman's avatar
hartman committed
157
    [[o_disc_type cellAtRow:3 column:0] setTitle: _NS("Audio CD")];
158
159
160
161
162
163

    [o_net_udp_port_lbl setStringValue: _NS("Port")];
    [o_net_udpm_addr_lbl setStringValue: _NS("Address")];
    [o_net_udpm_port_lbl setStringValue: _NS("Port")];
    [o_net_http_url_lbl setStringValue: _NS("URL")];

164
165
    [[o_net_mode cellAtRow:0 column:0] setTitle: _NS("UDP/RTP")];
    [[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
169
170

    [o_net_udp_port setIntValue: config_GetInt( p_intf, "server-port" )];
    [o_net_udp_port_stp setIntValue: config_GetInt( p_intf, "server-port" )];

171
    [o_file_sub_ckbox setTitle: _NS("Load subtitles file:")];
172
    [o_file_sub_btn_settings setTitle: _NS("Settings...")];
173
174
175
176
177
178
179
180
    [o_file_sub_btn_browse setTitle: _NS("Browse...")];
    [o_file_sub_override setTitle: _NS("Override")];
    [o_file_sub_delay_lbl setStringValue: _NS("delay")];
    [o_file_sub_delay_stp setEnabled: NO];
    [o_file_sub_fps_lbl setStringValue: _NS("fps")];
    [o_file_sub_fps_stp setEnabled: NO];
    [o_file_sub_ok_btn setStringValue: _NS("OK")];
    
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openFilePathChanged:)
        name: NSControlTextDidChangeNotification
        object: o_file_path];

    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openDiscInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_disc_device];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openDiscInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_disc_title];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openDiscInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_disc_chapter];
198
199
200
201
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openDiscInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_disc_videots_folder];
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openNetInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_net_udp_port];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openNetInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_net_udpm_addr];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openNetInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_net_udpm_port];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openNetInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_net_http_url];
219
220
}

221
- (void)openTarget:(int)i_type
222
223
224
{
    int i_result;

225
    [o_tabview selectTabViewItemAtIndex: i_type];
226
    [o_file_sub_ckbox setState: NSOffState];
227
    
228
229
    i_result = [NSApp runModalForWindow: o_panel];
    [o_panel close];
230
231
232

    if( i_result )
    {
233
234
        NSMutableDictionary *o_dic;
        NSMutableArray *o_options = [NSMutableArray array];
bigben's avatar
bigben committed
235
236
        unsigned int i;

237
238
        o_dic = [NSMutableDictionary dictionaryWithObject: [o_mrl stringValue] forKey: @"ITEM_URL"];
        if( [o_file_sub_ckbox state] == NSOnState )
239
        {
240
            [o_options addObject: [NSString stringWithFormat: @"sub-file=%s", [[o_file_sub_path stringValue] fileSystemRepresentation]]];
241
            if( [o_file_sub_override state] == NSOnState )
242
            {
243
244
                [o_options addObject: [NSString stringWithFormat: @"sub-delay=%i", (int)( [o_file_sub_delay intValue] * 10 )]];
                [o_options addObject: [NSString stringWithFormat: @"sub-fps=%f", [o_file_sub_fps floatValue]]];
245
246
            }
        }
247
        if( [o_output_ckbox state] == NSOnState )
248
        {
bigben's avatar
bigben committed
249
250
251
252
253
            for (i = 0 ; i < [[o_sout_options getMRL] count] ; i++)
            {
                [o_options addObject: [NSString stringWithString:
                      [[(VLCOutput *)o_sout_options getMRL] objectAtIndex: i]]];
            }
254
        }
255
        [o_dic setObject: (NSArray *)[o_options copy] forKey: @"ITEM_OPTIONS"];
hartman's avatar
hartman committed
256
        [o_playlist appendArray: [NSArray arrayWithObject: o_dic] atPos: -1 enqueue:NO];
257
258
259
    }
}

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
- (void)tabView:(NSTabView *)o_tv didSelectTabViewItem:(NSTabViewItem *)o_tvi
{
    NSString *o_label = [o_tvi label];

    if( [o_label isEqualToString: _NS("File")] )
    {
        [self openFilePathChanged: nil];
    }
    else if( [o_label isEqualToString: _NS("Disc")] )
    {
        [self openDiscTypeChanged: nil];
    }
    else if( [o_label isEqualToString: _NS("Network")] )
    {
        [self openNetModeChanged: nil];
    }  
}

278
- (IBAction)openFileGeneric:(id)sender
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
{
    [self openFilePathChanged: nil];
    [self openTarget: 0];
}

- (IBAction)openDisc:(id)sender
{
    [self openDiscTypeChanged: nil];
    [self openTarget: 1];
}

- (IBAction)openNet:(id)sender
{
    [self openNetModeChanged: nil];
    [self openTarget: 2];
}

- (void)openFilePathChanged:(NSNotification *)o_notification
{
    NSString *o_mrl_string;
    NSString *o_filename = [o_file_path stringValue];
hartman's avatar
hartman committed
300
    NSString *o_ext = [o_filename pathExtension];
301
    vlc_bool_t b_stream = [o_file_stream state];
302
303
304
    BOOL b_dir = NO;
    
    [[NSFileManager defaultManager] fileExistsAtPath:o_filename isDirectory:&b_dir];
305

306
307
308
309
310
    if( b_dir )
    {
        o_mrl_string = [NSString stringWithFormat: @"dir:%@", o_filename];
    }
    else if( [o_ext isEqualToString: @"bin"] ||
hartman's avatar
hartman committed
311
312
        [o_ext isEqualToString: @"cue"] ||
        [o_ext isEqualToString: @"vob"] ||
313
        [o_ext isEqualToString: @"iso"] )
hartman's avatar
hartman committed
314
315
316
317
318
319
320
321
322
    {
        o_mrl_string = o_filename;
    }
    else
    {
        o_mrl_string = [NSString stringWithFormat: @"%s://%@",
                        b_stream ? "stream" : "file",
                        o_filename];
    }
323
324
325
    [o_mrl setStringValue: o_mrl_string]; 
}

Christophe Massiot's avatar
Christophe Massiot committed
326
327
328
329
330
- (IBAction)openFileBrowse:(id)sender
{
    NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
    
    [o_open_panel setAllowsMultipleSelection: NO];
331
    [o_open_panel setCanChooseDirectories: YES];
Christophe Massiot's avatar
Christophe Massiot committed
332
333
334
    [o_open_panel setTitle: _NS("Open File")];
    [o_open_panel setPrompt: _NS("Open")];

335
336
337
338
339
340
341
342
343
344
345
346
347
348
    [o_open_panel beginSheetForDirectory:nil
        file:nil
        types:nil
        modalForWindow:[sender window]
        modalDelegate: self
        didEndSelector: @selector(pathChosenInPanel: 
                        withReturn:
                        contextInfo:)
        contextInfo: nil];
}

- (void)pathChosenInPanel: (NSOpenPanel *) sheet withReturn:(int)returnCode contextInfo:(void  *)contextInfo
{
    if (returnCode == NSFileHandlingPanelOKButton)
Christophe Massiot's avatar
Christophe Massiot committed
349
    {
350
        NSString *o_filename = [[sheet filenames] objectAtIndex: 0];
Christophe Massiot's avatar
Christophe Massiot committed
351
352
353
354
355
        [o_file_path setStringValue: o_filename];
        [self openFilePathChanged: nil];
    }
}

356
357
358
359
360
- (IBAction)openFileStreamChanged:(id)sender
{
    [self openFilePathChanged: nil];
}

361
362
363
- (IBAction)openDiscTypeChanged:(id)sender
{
    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
370
    
    o_type = [[o_disc_type selectedCell] title];

371
    if ( [o_type isEqualToString: _NS("VIDEO_TS folder")] )
372
    {
373
        b_device = 0; b_menus = 1;
374
375
376
    }
    else
    {
377
378
379
        NSArray *o_devices;
        NSString *o_disc;
        const char *psz_class = NULL;
380
        b_device = 1;
381
382
383
384
385

        if ( [o_type isEqualToString: _NS("VCD")] )
        {
            psz_class = kIOCDMediaClass;
            o_disc = o_type;
386
387
            b_menus = 0; b_title_chapter = 1;
            [o_disc_dvd_menus setState: FALSE];
388
        }
hartman's avatar
hartman committed
389
390
391
392
393
394
395
        else if ( [o_type isEqualToString: _NS("Audio CD")])
        {
            psz_class = kIOCDMediaClass;
            o_disc = o_type;
            b_menus = 0; b_title_chapter = 0;
            [o_disc_dvd_menus setState: FALSE];
        }
396
        else
397
398
399
        {
            psz_class = kIODVDMediaClass;
            o_disc = o_type;
400
            b_menus = 1;
401
        }
402
    
403
404
        o_devices = GetEjectableMediaOfClass( psz_class );
        if ( o_devices != nil )
405
        {
406
            int i_devices = [o_devices count];
407
        
408
            if ( i_devices )
409
            {
410
411
412
413
414
415
416
417
418
419
420
421
422
423
                int i;
        
                for( i = 0; i < i_devices; i++ )
                {
                    [o_disc_device 
                        addItemWithObjectValue: [o_devices objectAtIndex: i]];
                }

                [o_disc_device selectItemAtIndex: 0];
            }
            else
            {
                [o_disc_device setStringValue: 
                    [NSString stringWithFormat: _NS("No %@s found"), o_disc]];
424
425
426
            }
        }
    }
427

428
429
430
431
432
    [o_disc_device setEnabled: b_device];
    [o_disc_title setEnabled: b_title_chapter];
    [o_disc_title_stp setEnabled: b_title_chapter];
    [o_disc_chapter setEnabled: b_title_chapter];
    [o_disc_chapter_stp setEnabled: b_title_chapter];
433
434
435
    [o_disc_videots_folder setEnabled: !b_device];
    [o_disc_videots_btn_browse setEnabled: !b_device];
    [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
451
        [o_disc_chapter setIntValue: [o_disc_chapter_stp intValue]];
    }
452

453
454
    [self openDiscInfoChanged: nil];
}
455

456
457
458
459
- (void)openDiscInfoChanged:(NSNotification *)o_notification
{
    NSString *o_type;
    NSString *o_device;
460
    NSString *o_videots;
461
462
    NSString *o_mrl_string;
    int i_title, i_chapter;
463
    vlc_bool_t b_menus;
464

465
466
467
468
    o_type = [[o_disc_type selectedCell] title];
    o_device = [o_disc_device stringValue];
    i_title = [o_disc_title intValue];
    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
475
476
477
478
        if ( [o_device isEqualToString:
                [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
            o_device = @"";
        o_mrl_string = [NSString stringWithFormat: @"vcd://%@@%i,%i",
                        o_device, i_title, i_chapter]; 
479
    }
hartman's avatar
hartman committed
480
481
482
483
484
485
486
487
    else if ( [o_type isEqualToString: _NS("Audio CD")] )
    {
        if ( [o_device isEqualToString:
                [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
            o_device = @"";
        o_mrl_string = [NSString stringWithFormat: @"cdda://%@",
                        o_device]; 
    }
488
    else if ( [o_type isEqualToString: _NS("DVD")] )
489
    {
490
491
492
        if ( [o_device isEqualToString:
                [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
            o_device = @"";
493
        if ( b_menus )
494
            o_mrl_string = [NSString stringWithFormat: @"dvdnav://%@",
495
496
                            o_device]; 
        else
497
            o_mrl_string = [NSString stringWithFormat: @"dvdread://%@@%i,%i",
498
                            o_device, i_title, i_chapter]; 
499
500
501
    }
    else /* VIDEO_TS folder */
    {
502
        if ( b_menus )
503
            o_mrl_string = [NSString stringWithFormat: @"dvdnav://%@",
504
505
506
507
                            o_videots]; 
        else
            o_mrl_string = [NSString stringWithFormat: @"dvdread://%@@%i,%i",
                            o_videots, i_title, i_chapter]; 
508
    }
509

510
    [o_mrl setStringValue: o_mrl_string]; 
511
512
}

513
514
515
516
517
518
- (IBAction)openDiscMenusChanged:(id)sender
{
    [self openDiscInfoChanged: nil];
    [self openDiscTypeChanged: nil];
}

Christophe Massiot's avatar
Christophe Massiot committed
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
- (IBAction)openVTSBrowse:(id)sender
{
    NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];

    [o_open_panel setAllowsMultipleSelection: NO];
    [o_open_panel setCanChooseFiles: NO];
    [o_open_panel setCanChooseDirectories: YES];
    [o_open_panel setTitle: _NS("Open VIDEO_TS Directory")];
    [o_open_panel setPrompt: _NS("Open")];

    if( [o_open_panel runModalForDirectory: nil
            file: nil types: nil] == NSOKButton )
    {
        NSString *o_dirname = [[o_open_panel filenames] objectAtIndex: 0];
        [o_disc_videots_folder setStringValue: o_dirname];
        [self openDiscInfoChanged: nil];
    }
}

538
539
- (IBAction)openNetModeChanged:(id)sender
{
540
541
542
543
    NSString *o_mode;
    BOOL b_udp = FALSE;
    BOOL b_udpm = FALSE;
    BOOL b_http = FALSE;
544
545
546

    o_mode = [[o_net_mode selectedCell] title];

547
548
549
    if( [o_mode isEqualToString: _NS("UDP/RTP")] ) b_udp = TRUE;   
    else if( [o_mode isEqualToString: _NS("UDP/RTP Multicast")] ) b_udpm = TRUE;
    else if( [o_mode isEqualToString: _NS("HTTP/FTP/MMS")] ) b_http = TRUE;
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565

    [o_net_udp_port setEnabled: b_udp];
    [o_net_udp_port_stp setEnabled: b_udp];
    [o_net_udpm_addr setEnabled: b_udpm];
    [o_net_udpm_port setEnabled: b_udpm];
    [o_net_udpm_port_stp setEnabled: b_udpm];
    [o_net_http_url setEnabled: b_http];

    [self openNetInfoChanged: nil];
}

- (IBAction)openNetStepperChanged:(id)sender
{
    int i_tag = [sender tag];

    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
575
576
577
578
579
580
    [self openNetInfoChanged: nil];
}

- (void)openNetInfoChanged:(NSNotification *)o_notification
{
    NSString *o_mode;
    NSString *o_mrl_string = [NSString string];
hartman's avatar
hartman committed
581
    intf_thread_t * p_intf = VLCIntf;
582
583
584

    o_mode = [[o_net_mode selectedCell] title];

585
    if( [o_mode isEqualToString: _NS("UDP/RTP")] )
586
    {
587
588
589
590
        int i_port = [o_net_udp_port intValue];

        o_mrl_string = [NSString stringWithString: @"udp://"]; 

591
        if( i_port != config_GetInt( p_intf, "server-port" ) )
592
593
594
595
        {
            o_mrl_string = 
                [o_mrl_string stringByAppendingFormat: @"@:%i", i_port]; 
        } 
596
    }
597
    else if( [o_mode isEqualToString: _NS("UDP/RTP Multicast")] ) 
598
    {
599
600
601
602
        NSString *o_addr = [o_net_udpm_addr stringValue];
        int i_port = [o_net_udpm_port intValue];

        o_mrl_string = [NSString stringWithFormat: @"udp://@%@", o_addr]; 
603

604
        if( i_port != config_GetInt( p_intf, "server-port" ) )
605
606
607
608
609
        {
            o_mrl_string = 
                [o_mrl_string stringByAppendingFormat: @":%i", i_port]; 
        } 
    }
610
    else if( [o_mode isEqualToString: _NS("HTTP/FTP/MMS")] )
611
    {
612
613
        NSString *o_url = [o_net_http_url stringValue];

614
615
616
617
618
        if ( ![o_url hasPrefix:@"http:"] && ![o_url hasPrefix:@"ftp:"]
              && ![o_url hasPrefix:@"mms"] )
            o_mrl_string = [NSString stringWithFormat: @"http://%@", o_url];
        else
            o_mrl_string = o_url;
619
    }
620
621

    [o_mrl setStringValue: o_mrl_string];
622
623
}

624
625
- (IBAction)openFile:(id)sender
{
626
    NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
627
    int i;
hartman's avatar
hartman committed
628
629
    
    [o_open_panel setAllowsMultipleSelection: YES];
630
    [o_open_panel setCanChooseDirectories: YES];
631
632
    [o_open_panel setTitle: _NS("Open File")];
    [o_open_panel setPrompt: _NS("Open")];
hartman's avatar
hartman committed
633
    
634
635
636
    if( [o_open_panel runModalForDirectory: nil
            file: nil types: nil] == NSOKButton )
    {
637
        NSArray *o_array = [NSArray array];
hartman's avatar
hartman committed
638
639
        NSArray *o_values = [[o_open_panel filenames]
                sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
640

641
        for( i = 0; i < (int)[o_values count]; i++)
642
643
644
645
646
647
        {
            NSDictionary *o_dic;
            o_dic = [NSDictionary dictionaryWithObject:[o_values objectAtIndex:i] forKey:@"ITEM_URL"];
            o_array = [o_array arrayByAddingObject: o_dic];
        }
        [o_playlist appendArray: o_array atPos: -1 enqueue:NO];
648
    }
649
650
}

651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
- (IBAction)subsChanged:(id)sender
{
    if ([o_file_sub_ckbox state] == NSOnState)
    {
        [o_file_sub_btn_settings setEnabled:YES];
    }
    else
    {
        [o_file_sub_btn_settings setEnabled:NO];
    }
}

- (IBAction)subSettings:(id)sender
{
    [NSApp beginSheet: o_file_sub_sheet
        modalForWindow: [sender window]
        modalDelegate: self
        didEndSelector: NULL
        contextInfo: nil];
}

- (IBAction)subFileBrowse:(id)sender
{
    NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
    
    [o_open_panel setAllowsMultipleSelection: NO];
    [o_open_panel setTitle: _NS("Open File")];
    [o_open_panel setPrompt: _NS("Open")];

    if( [o_open_panel runModalForDirectory: nil 
            file: nil types: nil] == NSOKButton )
    {
        NSString *o_filename = [[o_open_panel filenames] objectAtIndex: 0];
        [o_file_sub_path setStringValue: o_filename];
    }
}

- (IBAction)subOverride:(id)sender
{
    BOOL b_state = [o_file_sub_override state];
    [o_file_sub_delay setEnabled: b_state];
    [o_file_sub_delay_stp setEnabled: b_state];
    [o_file_sub_fps setEnabled: b_state];
    [o_file_sub_fps_stp setEnabled: b_state];
}

- (IBAction)subDelayStepperChanged:(id)sender
{
    [o_file_sub_delay setIntValue: [o_file_sub_delay_stp intValue]];
}

- (IBAction)subFpsStepperChanged:(id)sender;
{
    [o_file_sub_fps setFloatValue: [o_file_sub_fps_stp floatValue]];
}

- (IBAction)subCloseSheet:(id)sender
{
    [o_file_sub_sheet orderOut:sender];
    [NSApp endSheet: o_file_sub_sheet];
}

713
714
715
716
717
718
719
- (IBAction)panelCancel:(id)sender
{
    [NSApp stopModalWithCode: 0];
}

- (IBAction)panelOk:(id)sender
{
720
721
722
723
724
725
726
727
    if( [[o_mrl stringValue] length] )
    {
        [NSApp stopModalWithCode: 1];
    }
    else
    {
        NSBeep();
    }
728
729
730
}

@end