open.m 26.6 KB
Newer Older
1
/*****************************************************************************
2
 * open.m: MacOS X module for vlc
3
 *****************************************************************************
4
 * Copyright (C) 2002-2006 the VideoLAN team
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
 *          Benjamin Pracht <bigben at videolan dot org>
11
 *          Felix Khne <fkuehne at videolan dot org>
12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * 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
dionoea's avatar
dionoea committed
25
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
 *****************************************************************************/

/*****************************************************************************
 * 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>

42 43 44
#include "intf.h"
#include "playlist.h"
#include "open.h"
45
#include "output.h"
46
#import <vlc/intf.h>
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

/*****************************************************************************
 * 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 );
    }
    
73
    CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ), 
74 75 76 77 78 79 80 81 82 83 84 85
                          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 );
86
    if( next_media != nil )
87 88 89 90 91 92 93 94
    {
        char psz_buf[0x32];
        size_t dev_path_length;
        CFTypeRef str_bsd_path;
    
        do
        {
            str_bsd_path = IORegistryEntryCreateCFProperty( next_media,
95
                                                            CFSTR( kIOBSDNameKey ),
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
                                                            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 );
        
119
        } while( ( next_media = IOIteratorNext( media_iterator ) ) != nil );
120 121 122 123 124 125 126 127 128 129 130 131 132 133
    }
    
    IOObjectRelease( media_iterator );

    o_devices = [NSArray arrayWithArray: p_list];

    return( o_devices );
}

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

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
static VLCOpen *_o_sharedMainInstance = nil;

+ (VLCOpen *)sharedInstance
{
    return _o_sharedMainInstance ? _o_sharedMainInstance : [[self alloc] init];
}

- (id)init
{
    if( _o_sharedMainInstance) {
        [self dealloc];
    } else {
        _o_sharedMainInstance = [super init];
    }
    
    return _o_sharedMainInstance;
}

152 153
- (void)awakeFromNib
{
hartman's avatar
hartman committed
154
    intf_thread_t * p_intf = VLCIntf;
155

156
    [o_panel setTitle: _NS("Open Source")];
157
    [o_mrl_lbl setTitle: _NS("Media Resource Locator (MRL)")];
158 159 160 161 162 163 164 165 166

    [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...")];
167
    [o_file_stream setTitle: _NS("Treat as a pipe rather than as a file")];
168 169 170 171

    [o_disc_device_lbl setStringValue: _NS("Device name")];
    [o_disc_title_lbl setStringValue: _NS("Title")];
    [o_disc_chapter_lbl setStringValue: _NS("Chapter")];
172
    [o_disc_videots_btn_browse setTitle: _NS("Browse...")];
173
    [o_disc_dvd_menus setTitle: _NS("Use DVD menus")];
174

175
    [[o_disc_type cellAtRow:0 column:0] setTitle: _NS("VIDEO_TS directory")];
176
    [[o_disc_type cellAtRow:1 column:0] setTitle: _NS("DVD")];
177
    [[o_disc_type cellAtRow:2 column:0] setTitle: _NS("VCD")];
hartman's avatar
hartman committed
178
    [[o_disc_type cellAtRow:3 column:0] setTitle: _NS("Audio CD")];
179 180 181 182 183 184

    [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")];

185 186
    [[o_net_mode cellAtRow:0 column:0] setTitle: _NS("UDP/RTP")];
    [[o_net_mode cellAtRow:1 column:0] setTitle: _NS("UDP/RTP Multicast")];
187
    [[o_net_mode cellAtRow:2 column:0] setTitle: _NS("HTTP/FTP/MMS/RTSP")];
188
    [o_net_timeshift_ckbox setTitle: _NS("Allow timeshifting")];
189 190 191 192

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

193 194 195
    [self setSubPanel];


196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
    [[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];
213 214 215 216
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openDiscInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_disc_videots_folder];
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233

    [[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];
234 235
}

236 237 238 239 240 241 242 243 244
- (void)setSubPanel
{
    intf_thread_t * p_intf = VLCIntf;
    int i_index;
    module_config_t * p_item;

    [o_file_sub_ckbox setTitle: _NS("Load subtitles file:")];
    [o_file_sub_btn_settings setTitle: _NS("Settings...")];
    [o_file_sub_btn_browse setTitle: _NS("Browse...")];
245
    [o_file_sub_override setTitle: _NS("Override parametters")];
246
    [o_file_sub_delay_lbl setStringValue: _NS("Delay")];
247
    [o_file_sub_delay_stp setEnabled: NO];
248
    [o_file_sub_fps_lbl setStringValue: _NS("FPS")];
249
    [o_file_sub_fps_stp setEnabled: NO];
bigben's avatar
bigben committed
250
    [o_file_sub_encoding_lbl setStringValue: _NS("Subtitles encoding")];
251 252 253
    [o_file_sub_encoding_pop removeAllItems];
    [o_file_sub_size_lbl setStringValue: _NS("Font size")];
    [o_file_sub_size_pop removeAllItems];
254
    [o_file_sub_align_lbl setStringValue: _NS("Subtitles alignment")];
255 256
    [o_file_sub_align_pop removeAllItems];
    [o_file_sub_ok_btn setStringValue: _NS("OK")];
257 258
    [o_file_sub_font_box setTitle: _NS("Font Properties")];
    [o_file_sub_file_box setTitle: _NS("Subtitle File")];
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305

    p_item = config_FindConfig( VLC_OBJECT(p_intf), "subsdec-encoding" );

    if( p_item )
    {
        for( i_index = 0; p_item->ppsz_list && p_item->ppsz_list[i_index];
             i_index++ )
        {
            [o_file_sub_encoding_pop addItemWithTitle:
                [NSString stringWithCString:
                p_item->ppsz_list[i_index]]];
        }
        [o_file_sub_encoding_pop selectItemWithTitle:
                [NSString stringWithCString:
                p_item->psz_value]];
    }

    p_item = config_FindConfig( VLC_OBJECT(p_intf), "subsdec-align" );

    if ( p_item )
    {
        for ( i_index = 0; i_index < p_item->i_list; i_index++ )
        {
            [o_file_sub_align_pop addItemWithTitle:
                [NSString stringWithUTF8String:
                p_item->ppsz_list_text[i_index]]];
        }
        [o_file_sub_align_pop selectItemAtIndex: p_item->i_value];
    }

    p_item = config_FindConfig( VLC_OBJECT(p_intf), "freetype-rel-fontsize" );

    if ( p_item )
    {
        for ( i_index = 0; i_index < p_item->i_list; i_index++ )
        {
            [o_file_sub_size_pop addItemWithTitle:
                [NSString stringWithUTF8String:
                p_item->ppsz_list_text[i_index]]];
            if ( p_item->i_value == p_item->pi_list[i_index] )
            {
                [o_file_sub_size_pop selectItemAtIndex: i_index];
            }
        }
    }
}

306
- (void)openTarget:(int)i_type
307 308
{
    int i_result;
309 310 311
    intf_thread_t * p_intf = VLCIntf;

    b_autoplay = (BOOL *)config_GetInt( VLCIntf, "macosx-autoplay" );
312

313
    [o_tabview selectTabViewItemAtIndex: i_type];
314
    [o_file_sub_ckbox setState: NSOffState];
315
    
316 317
    i_result = [NSApp runModalForWindow: o_panel];
    [o_panel close];
318 319 320

    if( i_result )
    {
321 322
        NSMutableDictionary *o_dic;
        NSMutableArray *o_options = [NSMutableArray array];
bigben's avatar
bigben committed
323 324
        unsigned int i;

325 326
        o_dic = [NSMutableDictionary dictionaryWithObject: [o_mrl stringValue] forKey: @"ITEM_URL"];
        if( [o_file_sub_ckbox state] == NSOnState )
327
        {
328 329
            module_config_t * p_item;

330
            [o_options addObject: [NSString stringWithFormat: @"sub-file=%@", [o_file_sub_path stringValue]]];
331
            if( [o_file_sub_override state] == NSOnState )
332
            {
333 334
                [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]]];
335
            }
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
            [o_options addObject: [NSString stringWithFormat:
                    @"subsdec-encoding=%@",
                    [o_file_sub_encoding_pop titleOfSelectedItem]]];
            [o_options addObject: [NSString stringWithFormat:
                    @"subsdec-align=%i",
                    [o_file_sub_align_pop indexOfSelectedItem]]];

            p_item = config_FindConfig( VLC_OBJECT(p_intf),
                                            "freetype-rel-fontsize" );

            if ( p_item )
            {
                [o_options addObject: [NSString stringWithFormat:
                    @"freetype-rel-fontsize=%i",
                    p_item->pi_list[[o_file_sub_size_pop indexOfSelectedItem]]]];
            }
352
        }
353
        if( [o_output_ckbox state] == NSOnState )
354
        {
bigben's avatar
bigben committed
355 356 357 358 359
            for (i = 0 ; i < [[o_sout_options getMRL] count] ; i++)
            {
                [o_options addObject: [NSString stringWithString:
                      [[(VLCOutput *)o_sout_options getMRL] objectAtIndex: i]]];
            }
360
        }
361 362 363 364 365
        if( [o_net_timeshift_ckbox state] == NSOnState )
        {
            [o_options addObject: [NSString stringWithString:
                                                @"access-filter=timeshift"]];
        }
366
        [o_dic setObject: (NSArray *)[o_options copy] forKey: @"ITEM_OPTIONS"];
367 368 369 370
        if( b_autoplay )
            [o_playlist appendArray: [NSArray arrayWithObject: o_dic] atPos: -1 enqueue:NO];
        else
            [o_playlist appendArray: [NSArray arrayWithObject: o_dic] atPos: -1 enqueue:YES];
371 372 373
    }
}

374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
- (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];
    }  
}

392
- (void)openFileGeneric
393 394 395 396 397
{
    [self openFilePathChanged: nil];
    [self openTarget: 0];
}

398
- (void)openDisc
399 400 401 402 403
{
    [self openDiscTypeChanged: nil];
    [self openTarget: 1];
}

404
- (void)openNet
405 406 407 408 409 410 411 412 413
{
    [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
414
    NSString *o_ext = [o_filename pathExtension];
415
    vlc_bool_t b_stream = [o_file_stream state];
416 417 418
    BOOL b_dir = NO;
    
    [[NSFileManager defaultManager] fileExistsAtPath:o_filename isDirectory:&b_dir];
419

420 421 422 423 424
    if( b_dir )
    {
        o_mrl_string = [NSString stringWithFormat: @"dir:%@", o_filename];
    }
    else if( [o_ext isEqualToString: @"bin"] ||
hartman's avatar
hartman committed
425 426
        [o_ext isEqualToString: @"cue"] ||
        [o_ext isEqualToString: @"vob"] ||
427
        [o_ext isEqualToString: @"iso"] )
hartman's avatar
hartman committed
428 429 430 431 432 433 434 435 436
    {
        o_mrl_string = o_filename;
    }
    else
    {
        o_mrl_string = [NSString stringWithFormat: @"%s://%@",
                        b_stream ? "stream" : "file",
                        o_filename];
    }
437 438 439
    [o_mrl setStringValue: o_mrl_string]; 
}

Christophe Massiot's avatar
Christophe Massiot committed
440 441 442 443 444
- (IBAction)openFileBrowse:(id)sender
{
    NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
    
    [o_open_panel setAllowsMultipleSelection: NO];
445
    [o_open_panel setCanChooseDirectories: YES];
Christophe Massiot's avatar
Christophe Massiot committed
446 447 448
    [o_open_panel setTitle: _NS("Open File")];
    [o_open_panel setPrompt: _NS("Open")];

449 450 451 452 453 454 455 456 457 458 459 460 461 462
    [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
463
    {
464
        NSString *o_filename = [[sheet filenames] objectAtIndex: 0];
Christophe Massiot's avatar
Christophe Massiot committed
465 466 467 468 469
        [o_file_path setStringValue: o_filename];
        [self openFilePathChanged: nil];
    }
}

470 471 472 473 474
- (IBAction)openFileStreamChanged:(id)sender
{
    [self openFilePathChanged: nil];
}

475 476 477
- (IBAction)openDiscTypeChanged:(id)sender
{
    NSString *o_type;
478
    vlc_bool_t b_device, b_menus, b_title_chapter;
479 480
    
    [o_disc_device removeAllItems];
481
    b_title_chapter = ![o_disc_dvd_menus state];
482 483 484
    
    o_type = [[o_disc_type selectedCell] title];

485
    if ( [o_type isEqualToString: _NS("VIDEO_TS directory")] )
486
    {
487
        b_device = 0; b_menus = 1;
488 489 490
    }
    else
    {
491 492 493
        NSArray *o_devices;
        NSString *o_disc;
        const char *psz_class = NULL;
494
        b_device = 1;
495 496 497 498 499

        if ( [o_type isEqualToString: _NS("VCD")] )
        {
            psz_class = kIOCDMediaClass;
            o_disc = o_type;
500 501
            b_menus = 0; b_title_chapter = 1;
            [o_disc_dvd_menus setState: FALSE];
502
        }
hartman's avatar
hartman committed
503 504 505 506 507 508 509
        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];
        }
510
        else
511 512 513
        {
            psz_class = kIODVDMediaClass;
            o_disc = o_type;
514
            b_menus = 1;
515
        }
516
    
517 518
        o_devices = GetEjectableMediaOfClass( psz_class );
        if ( o_devices != nil )
519
        {
520
            int i_devices = [o_devices count];
521
        
522
            if ( i_devices )
523
            {
524 525 526 527 528 529 530 531 532 533 534 535 536 537
                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]];
538 539 540
            }
        }
    }
541

542 543 544 545 546
    [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];
547 548 549
    [o_disc_videots_folder setEnabled: !b_device];
    [o_disc_videots_btn_browse setEnabled: !b_device];
    [o_disc_dvd_menus setEnabled: b_menus];
550

551
    [self openDiscInfoChanged: nil];
552 553
}

554
- (IBAction)openDiscStepperChanged:(id)sender
555
{
556
    int i_tag = [sender tag];
557

558
    if( i_tag == 0 )
559
    {
560
        [o_disc_title setIntValue: [o_disc_title_stp intValue]];
561
    }
562
    else if( i_tag == 1 )
563
    {
564 565
        [o_disc_chapter setIntValue: [o_disc_chapter_stp intValue]];
    }
566

567 568
    [self openDiscInfoChanged: nil];
}
569

570 571 572 573
- (void)openDiscInfoChanged:(NSNotification *)o_notification
{
    NSString *o_type;
    NSString *o_device;
574
    NSString *o_videots;
575 576
    NSString *o_mrl_string;
    int i_title, i_chapter;
577
    vlc_bool_t b_menus;
578

579 580 581 582
    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];
583
    o_videots = [o_disc_videots_folder stringValue];
584
    b_menus = [o_disc_dvd_menus state];
585

586
    if ( [o_type isEqualToString: _NS("VCD")] )
587
    {
588 589 590
        if ( [o_device isEqualToString:
                [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
            o_device = @"";
591
        o_mrl_string = [NSString stringWithFormat: @"vcd://%@@%i:%i",
592
                        o_device, i_title, i_chapter]; 
593
    }
hartman's avatar
hartman committed
594 595 596 597 598 599 600 601
    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]; 
    }
602
    else if ( [o_type isEqualToString: _NS("DVD")] )
603
    {
604 605 606
        if ( [o_device isEqualToString:
                [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
            o_device = @"";
607
        if ( b_menus )
608
            o_mrl_string = [NSString stringWithFormat: @"dvdnav://%@",
609 610
                            o_device]; 
        else
611
            o_mrl_string = [NSString stringWithFormat: @"dvdread://%@@%i:%i-",
612
                            o_device, i_title, i_chapter]; 
613 614 615
    }
    else /* VIDEO_TS folder */
    {
616
        if ( b_menus )
617
            o_mrl_string = [NSString stringWithFormat: @"dvdnav://%@",
618 619
                            o_videots]; 
        else
620
            o_mrl_string = [NSString stringWithFormat: @"dvdread://%@@%i:%i",
621
                            o_videots, i_title, i_chapter]; 
622
    }
623

624
    [o_mrl setStringValue: o_mrl_string]; 
625 626
}

627 628 629 630 631 632
- (IBAction)openDiscMenusChanged:(id)sender
{
    [self openDiscInfoChanged: nil];
    [self openDiscTypeChanged: nil];
}

Christophe Massiot's avatar
Christophe Massiot committed
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
- (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];
    }
}

652 653
- (IBAction)openNetModeChanged:(id)sender
{
654 655 656 657
    NSString *o_mode;
    BOOL b_udp = FALSE;
    BOOL b_udpm = FALSE;
    BOOL b_http = FALSE;
658 659 660

    o_mode = [[o_net_mode selectedCell] title];

661
    if( [o_mode isEqualToString: _NS("UDP/RTP")] ) b_udp = TRUE;
662
    else if( [o_mode isEqualToString: _NS("UDP/RTP Multicast")] ) b_udpm = TRUE;
663
    else if( [o_mode isEqualToString: _NS("HTTP/FTP/MMS/RTSP")] ) b_http = TRUE;
664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679

    [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 )
680
    {
681
        [o_net_udp_port setIntValue: [o_net_udp_port_stp intValue]];
682
    }
683
    else if( i_tag == 1 )
684
    {
685
        [o_net_udpm_port setIntValue: [o_net_udpm_port_stp intValue]];
686 687
    }

688 689 690 691 692 693 694
    [self openNetInfoChanged: nil];
}

- (void)openNetInfoChanged:(NSNotification *)o_notification
{
    NSString *o_mode;
    NSString *o_mrl_string = [NSString string];
hartman's avatar
hartman committed
695
    intf_thread_t * p_intf = VLCIntf;
696 697 698

    o_mode = [[o_net_mode selectedCell] title];

699
    if( [o_mode isEqualToString: _NS("UDP/RTP")] )
700
    {
701 702 703 704
        int i_port = [o_net_udp_port intValue];

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

705
        if( i_port != config_GetInt( p_intf, "server-port" ) )
706 707 708 709
        {
            o_mrl_string = 
                [o_mrl_string stringByAppendingFormat: @"@:%i", i_port]; 
        } 
710
    }
711
    else if( [o_mode isEqualToString: _NS("UDP/RTP Multicast")] ) 
712
    {
713 714 715 716
        NSString *o_addr = [o_net_udpm_addr stringValue];
        int i_port = [o_net_udpm_port intValue];

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

718
        if( i_port != config_GetInt( p_intf, "server-port" ) )
719 720 721 722 723
        {
            o_mrl_string = 
                [o_mrl_string stringByAppendingFormat: @":%i", i_port]; 
        } 
    }
724
    else if( [o_mode isEqualToString: _NS("HTTP/FTP/MMS/RTSP")] )
725
    {
726 727
        NSString *o_url = [o_net_http_url stringValue];

728
        if ( ![o_url hasPrefix:@"http:"] && ![o_url hasPrefix:@"ftp:"]
729
              && ![o_url hasPrefix:@"mms"] && ![o_url hasPrefix:@"rtsp"] )
730 731 732
            o_mrl_string = [NSString stringWithFormat: @"http://%@", o_url];
        else
            o_mrl_string = o_url;
733
    }
734
    [o_mrl setStringValue: o_mrl_string];
735 736
}

737
- (void)openFile
738
{
739
    NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
740
    int i;
741
    b_autoplay = (BOOL *)config_GetInt( VLCIntf, "macosx-autoplay" );
hartman's avatar
hartman committed
742 743
    
    [o_open_panel setAllowsMultipleSelection: YES];
744
    [o_open_panel setCanChooseDirectories: YES];
745 746
    [o_open_panel setTitle: _NS("Open File")];
    [o_open_panel setPrompt: _NS("Open")];
hartman's avatar
hartman committed
747
    
748 749 750
    if( [o_open_panel runModalForDirectory: nil
            file: nil types: nil] == NSOKButton )
    {
751
        NSArray *o_array = [NSArray array];
hartman's avatar
hartman committed
752 753
        NSArray *o_values = [[o_open_panel filenames]
                sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
754

755
        for( i = 0; i < (int)[o_values count]; i++)
756 757 758 759 760
        {
            NSDictionary *o_dic;
            o_dic = [NSDictionary dictionaryWithObject:[o_values objectAtIndex:i] forKey:@"ITEM_URL"];
            o_array = [o_array arrayByAddingObject: o_dic];
        }
761 762 763 764
        if( b_autoplay )
            [o_playlist appendArray: o_array atPos: -1 enqueue:NO];
        else
            [o_playlist appendArray: o_array atPos: -1 enqueue:YES];
765
    }
766 767
}

768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829
- (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];
}

830 831 832 833 834 835 836
- (IBAction)panelCancel:(id)sender
{
    [NSApp stopModalWithCode: 0];
}

- (IBAction)panelOk:(id)sender
{
837 838 839 840 841 842 843 844
    if( [[o_mrl stringValue] length] )
    {
        [NSApp stopModalWithCode: 1];
    }
    else
    {
        NSBeep();
    }
845 846 847
}

@end