open.m 26.1 KB
Newer Older
1
/*****************************************************************************
2
 * open.m: MacOS X module for vlc
3
 *****************************************************************************
4
 * Copyright (C) 2002-2005 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 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * 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
24
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
 *****************************************************************************/

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

41 42 43
#include "intf.h"
#include "playlist.h"
#include "open.h"
44
#include "output.h"
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 70

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

    o_devices = [NSArray arrayWithArray: p_list];

    return( o_devices );
}

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

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
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;
}

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

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

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

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

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

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

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

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

191 192 193
    [self setSubPanel];


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

    [[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];
232 233
}

234 235 236 237 238 239 240 241 242 243 244 245 246 247
- (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...")];
    [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];
bigben's avatar
bigben committed
248
    [o_file_sub_encoding_lbl setStringValue: _NS("Subtitles encoding")];
249 250 251 252 253 254
    [o_file_sub_encoding_pop removeAllItems];
    [o_file_sub_size_lbl setStringValue: _NS("Font size")];
    [o_file_sub_size_pop removeAllItems];
    [o_file_sub_align_lbl setStringValue: _NS("Subtitles justification")];
    [o_file_sub_align_pop removeAllItems];
    [o_file_sub_ok_btn setStringValue: _NS("OK")];
255 256
    [o_file_sub_font_box setTitle: _NS("Font Properties")];
    [o_file_sub_file_box setTitle: _NS("Subtitle File")];
257 258 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

    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];
            }
        }
    }
}

304
- (void)openTarget:(int)i_type
305 306 307
{
    int i_result;

308
    [o_tabview selectTabViewItemAtIndex: i_type];
309
    [o_file_sub_ckbox setState: NSOffState];
310
    
311 312
    i_result = [NSApp runModalForWindow: o_panel];
    [o_panel close];
313 314 315

    if( i_result )
    {
316 317
        NSMutableDictionary *o_dic;
        NSMutableArray *o_options = [NSMutableArray array];
bigben's avatar
bigben committed
318 319
        unsigned int i;

320 321
        o_dic = [NSMutableDictionary dictionaryWithObject: [o_mrl stringValue] forKey: @"ITEM_URL"];
        if( [o_file_sub_ckbox state] == NSOnState )
322
        {
323 324 325
            intf_thread_t * p_intf = VLCIntf;
            module_config_t * p_item;

326
            [o_options addObject: [NSString stringWithFormat: @"sub-file=%@", [o_file_sub_path stringValue]]];
327
            if( [o_file_sub_override state] == NSOnState )
328
            {
329 330
                [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]]];
331
            }
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
            [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]]]];
            }
348
        }
349
        if( [o_output_ckbox state] == NSOnState )
350
        {
bigben's avatar
bigben committed
351 352 353 354 355
            for (i = 0 ; i < [[o_sout_options getMRL] count] ; i++)
            {
                [o_options addObject: [NSString stringWithString:
                      [[(VLCOutput *)o_sout_options getMRL] objectAtIndex: i]]];
            }
356
        }
357 358 359 360 361
        if( [o_net_timeshift_ckbox state] == NSOnState )
        {
            [o_options addObject: [NSString stringWithString:
                                                @"access-filter=timeshift"]];
        }
362
        [o_dic setObject: (NSArray *)[o_options copy] forKey: @"ITEM_OPTIONS"];
hartman's avatar
hartman committed
363
        [o_playlist appendArray: [NSArray arrayWithObject: o_dic] atPos: -1 enqueue:NO];
364 365 366
    }
}

367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
- (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];
    }  
}

385
- (void)openFileGeneric
386 387 388 389 390
{
    [self openFilePathChanged: nil];
    [self openTarget: 0];
}

391
- (void)openDisc
392 393 394 395 396
{
    [self openDiscTypeChanged: nil];
    [self openTarget: 1];
}

397
- (void)openNet
398 399 400 401 402 403 404 405 406
{
    [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
407
    NSString *o_ext = [o_filename pathExtension];
408
    vlc_bool_t b_stream = [o_file_stream state];
409 410 411
    BOOL b_dir = NO;
    
    [[NSFileManager defaultManager] fileExistsAtPath:o_filename isDirectory:&b_dir];
412

413 414 415 416 417
    if( b_dir )
    {
        o_mrl_string = [NSString stringWithFormat: @"dir:%@", o_filename];
    }
    else if( [o_ext isEqualToString: @"bin"] ||
hartman's avatar
hartman committed
418 419
        [o_ext isEqualToString: @"cue"] ||
        [o_ext isEqualToString: @"vob"] ||
420
        [o_ext isEqualToString: @"iso"] )
hartman's avatar
hartman committed
421 422 423 424 425 426 427 428 429
    {
        o_mrl_string = o_filename;
    }
    else
    {
        o_mrl_string = [NSString stringWithFormat: @"%s://%@",
                        b_stream ? "stream" : "file",
                        o_filename];
    }
430 431 432
    [o_mrl setStringValue: o_mrl_string]; 
}

Christophe Massiot's avatar
Christophe Massiot committed
433 434 435 436 437
- (IBAction)openFileBrowse:(id)sender
{
    NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
    
    [o_open_panel setAllowsMultipleSelection: NO];
438
    [o_open_panel setCanChooseDirectories: YES];
Christophe Massiot's avatar
Christophe Massiot committed
439 440 441
    [o_open_panel setTitle: _NS("Open File")];
    [o_open_panel setPrompt: _NS("Open")];

442 443 444 445 446 447 448 449 450 451 452 453 454 455
    [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
456
    {
457
        NSString *o_filename = [[sheet filenames] objectAtIndex: 0];
Christophe Massiot's avatar
Christophe Massiot committed
458 459 460 461 462
        [o_file_path setStringValue: o_filename];
        [self openFilePathChanged: nil];
    }
}

463 464 465 466 467
- (IBAction)openFileStreamChanged:(id)sender
{
    [self openFilePathChanged: nil];
}

468 469 470
- (IBAction)openDiscTypeChanged:(id)sender
{
    NSString *o_type;
471
    vlc_bool_t b_device, b_menus, b_title_chapter;
472 473
    
    [o_disc_device removeAllItems];
474
    b_title_chapter = ![o_disc_dvd_menus state];
475 476 477
    
    o_type = [[o_disc_type selectedCell] title];

478
    if ( [o_type isEqualToString: _NS("VIDEO_TS folder")] )
479
    {
480
        b_device = 0; b_menus = 1;
481 482 483
    }
    else
    {
484 485 486
        NSArray *o_devices;
        NSString *o_disc;
        const char *psz_class = NULL;
487
        b_device = 1;
488 489 490 491 492

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

535 536 537 538 539
    [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];
540 541 542
    [o_disc_videots_folder setEnabled: !b_device];
    [o_disc_videots_btn_browse setEnabled: !b_device];
    [o_disc_dvd_menus setEnabled: b_menus];
543

544
    [self openDiscInfoChanged: nil];
545 546
}

547
- (IBAction)openDiscStepperChanged:(id)sender
548
{
549
    int i_tag = [sender tag];
550

551
    if( i_tag == 0 )
552
    {
553
        [o_disc_title setIntValue: [o_disc_title_stp intValue]];
554
    }
555
    else if( i_tag == 1 )
556
    {
557 558
        [o_disc_chapter setIntValue: [o_disc_chapter_stp intValue]];
    }
559

560 561
    [self openDiscInfoChanged: nil];
}
562

563 564 565 566
- (void)openDiscInfoChanged:(NSNotification *)o_notification
{
    NSString *o_type;
    NSString *o_device;
567
    NSString *o_videots;
568 569
    NSString *o_mrl_string;
    int i_title, i_chapter;
570
    vlc_bool_t b_menus;
571

572 573 574 575
    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];
576
    o_videots = [o_disc_videots_folder stringValue];
577
    b_menus = [o_disc_dvd_menus state];
578

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

617
    [o_mrl setStringValue: o_mrl_string]; 
618 619
}

620 621 622 623 624 625
- (IBAction)openDiscMenusChanged:(id)sender
{
    [self openDiscInfoChanged: nil];
    [self openDiscTypeChanged: nil];
}

Christophe Massiot's avatar
Christophe Massiot committed
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
- (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];
    }
}

645 646
- (IBAction)openNetModeChanged:(id)sender
{
647 648 649 650
    NSString *o_mode;
    BOOL b_udp = FALSE;
    BOOL b_udpm = FALSE;
    BOOL b_http = FALSE;
651 652 653

    o_mode = [[o_net_mode selectedCell] title];

654
    if( [o_mode isEqualToString: _NS("UDP/RTP")] ) b_udp = TRUE;
655
    else if( [o_mode isEqualToString: _NS("UDP/RTP Multicast")] ) b_udpm = TRUE;
656
    else if( [o_mode isEqualToString: _NS("HTTP/FTP/MMS/RTSP")] ) b_http = TRUE;
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672

    [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 )
673
    {
674
        [o_net_udp_port setIntValue: [o_net_udp_port_stp intValue]];
675
    }
676
    else if( i_tag == 1 )
677
    {
678
        [o_net_udpm_port setIntValue: [o_net_udpm_port_stp intValue]];
679 680
    }

681 682 683 684 685 686 687
    [self openNetInfoChanged: nil];
}

- (void)openNetInfoChanged:(NSNotification *)o_notification
{
    NSString *o_mode;
    NSString *o_mrl_string = [NSString string];
hartman's avatar
hartman committed
688
    intf_thread_t * p_intf = VLCIntf;
689 690 691

    o_mode = [[o_net_mode selectedCell] title];

692
    if( [o_mode isEqualToString: _NS("UDP/RTP")] )
693
    {
694 695 696 697
        int i_port = [o_net_udp_port intValue];

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

698
        if( i_port != config_GetInt( p_intf, "server-port" ) )
699 700 701 702
        {
            o_mrl_string = 
                [o_mrl_string stringByAppendingFormat: @"@:%i", i_port]; 
        } 
703
    }
704
    else if( [o_mode isEqualToString: _NS("UDP/RTP Multicast")] ) 
705
    {
706 707 708 709
        NSString *o_addr = [o_net_udpm_addr stringValue];
        int i_port = [o_net_udpm_port intValue];

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

711
        if( i_port != config_GetInt( p_intf, "server-port" ) )
712 713 714 715 716
        {
            o_mrl_string = 
                [o_mrl_string stringByAppendingFormat: @":%i", i_port]; 
        } 
    }
717
    else if( [o_mode isEqualToString: _NS("HTTP/FTP/MMS/RTSP")] )
718
    {
719 720
        NSString *o_url = [o_net_http_url stringValue];

721
        if ( ![o_url hasPrefix:@"http:"] && ![o_url hasPrefix:@"ftp:"]
722
              && ![o_url hasPrefix:@"mms"] && ![o_url hasPrefix:@"rtsp"] )
723 724 725
            o_mrl_string = [NSString stringWithFormat: @"http://%@", o_url];
        else
            o_mrl_string = o_url;
726
    }
727
    [o_mrl setStringValue: o_mrl_string];
728 729
}

730
- (void)openFile
731
{
732
    NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
733
    int i;
hartman's avatar
hartman committed
734 735
    
    [o_open_panel setAllowsMultipleSelection: YES];
736
    [o_open_panel setCanChooseDirectories: YES];
737 738
    [o_open_panel setTitle: _NS("Open File")];
    [o_open_panel setPrompt: _NS("Open")];
hartman's avatar
hartman committed
739
    
740 741 742
    if( [o_open_panel runModalForDirectory: nil
            file: nil types: nil] == NSOKButton )
    {
743
        NSArray *o_array = [NSArray array];
hartman's avatar
hartman committed
744 745
        NSArray *o_values = [[o_open_panel filenames]
                sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
746

747
        for( i = 0; i < (int)[o_values count]; i++)
748 749 750 751 752 753
        {
            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];
754
    }
755 756
}

757 758 759 760 761 762 763 764 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
- (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];
}

819 820 821 822 823 824 825
- (IBAction)panelCancel:(id)sender
{
    [NSApp stopModalWithCode: 0];
}

- (IBAction)panelOk:(id)sender
{
826 827 828 829 830 831 832 833
    if( [[o_mrl stringValue] length] )
    {
        [NSApp stopModalWithCode: 1];
    }
    else
    {
        NSBeep();
    }
834 835 836
}

@end