open.m
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:26k
源码类别:

多媒体

开发平台:

MultiPlatform

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