open.m
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:44k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * open.m: Open dialogues for VLC's MacOS X port
  3.  *****************************************************************************
  4.  * Copyright (C) 2002-2009 the VideoLAN team
  5.  * $Id: 618b5e16d7db9d725dbaff155c04f3b87fb27218 $
  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 Paul Kühne <fkuehne at videolan dot org>
  12.  *
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2 of the License, or
  16.  * (at your option) any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; if not, write to the Free Software
  25.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  26.  *****************************************************************************/
  27. /*****************************************************************************
  28.  * Preamble
  29.  *****************************************************************************/
  30. #include <stdlib.h>                                      /* malloc(), free() */
  31. #include <sys/param.h>                                    /* for MAXPATHLEN */
  32. #include <string.h>
  33. #include <paths.h>
  34. #include <IOKit/IOKitLib.h>
  35. #include <IOKit/IOBSD.h>
  36. #include <IOKit/storage/IOMedia.h>
  37. #include <IOKit/storage/IOCDMedia.h>
  38. #include <IOKit/storage/IODVDMedia.h>
  39. #import "intf.h"
  40. #import "playlist.h"
  41. #import "open.h"
  42. #import "output.h"
  43. #import "eyetv.h"
  44. #include <vlc_url.h>
  45. #define setEyeTVUnconnected 
  46. [o_capture_lbl setStringValue: _NS("No device connected")]; 
  47. [o_capture_long_lbl setStringValue: _NS("VLC could not detect any EyeTV compatible device.nnCheck the device's connection, make sure that the latest EyeTV software is installed and try again.")]; 
  48. [o_capture_lbl displayIfNeeded]; 
  49. [o_capture_long_lbl displayIfNeeded]; 
  50. [self showCaptureView: o_capture_label_view]
  51. /*****************************************************************************
  52.  * GetEjectableMediaOfClass
  53.  *****************************************************************************/
  54. NSArray *GetEjectableMediaOfClass( const char *psz_class )
  55. {
  56.     io_object_t next_media;
  57.     mach_port_t master_port;
  58.     kern_return_t kern_result;
  59.     NSArray *o_devices = nil;
  60.     NSMutableArray *p_list = nil;
  61.     io_iterator_t media_iterator;
  62.     CFMutableDictionaryRef classes_to_match;
  63.     kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );
  64.     if( kern_result != KERN_SUCCESS )
  65.     {
  66.         return( nil );
  67.     }
  68.  
  69.     classes_to_match = IOServiceMatching( psz_class );
  70.     if( classes_to_match == NULL )
  71.     {
  72.         return( nil );
  73.     }
  74.  
  75.     CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ),
  76.                           kCFBooleanTrue );
  77.  
  78.     kern_result = IOServiceGetMatchingServices( master_port, classes_to_match,
  79.                                                 &media_iterator );
  80.     if( kern_result != KERN_SUCCESS )
  81.     {
  82.         return( nil );
  83.     }
  84.     p_list = [NSMutableArray arrayWithCapacity: 1];
  85.  
  86.     next_media = IOIteratorNext( media_iterator );
  87.     if( next_media )
  88.     {
  89.         char psz_buf[0x32];
  90.         size_t dev_path_length;
  91.         CFTypeRef str_bsd_path;
  92.  
  93.         do
  94.         {
  95.             str_bsd_path = IORegistryEntryCreateCFProperty( next_media,
  96.                                                             CFSTR( kIOBSDNameKey ),
  97.                                                             kCFAllocatorDefault,
  98.                                                             0 );
  99.             if( str_bsd_path == NULL )
  100.             {
  101.                 IOObjectRelease( next_media );
  102.                 continue;
  103.             }
  104.  
  105.             snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );
  106.             dev_path_length = strlen( psz_buf );
  107.  
  108.             if( CFStringGetCString( str_bsd_path,
  109.                                     (char*)&psz_buf + dev_path_length,
  110.                                     sizeof(psz_buf) - dev_path_length,
  111.                                     kCFStringEncodingASCII ) )
  112.             {
  113.                 [p_list addObject: [NSString stringWithUTF8String: psz_buf]];
  114.             }
  115.  
  116.             CFRelease( str_bsd_path );
  117.  
  118.             IOObjectRelease( next_media );
  119.  
  120.         } while( ( next_media = IOIteratorNext( media_iterator ) ) );
  121.     }
  122.  
  123.     IOObjectRelease( media_iterator );
  124.     o_devices = [NSArray arrayWithArray: p_list];
  125.     return( o_devices );
  126. }
  127. /*****************************************************************************
  128.  * VLCOpen implementation
  129.  *****************************************************************************/
  130. @implementation VLCOpen
  131. static VLCOpen *_o_sharedMainInstance = nil;
  132. + (VLCOpen *)sharedInstance
  133. {
  134.     return _o_sharedMainInstance ? _o_sharedMainInstance : [[self alloc] init];
  135. }
  136. - (id)init
  137. {
  138.     if( _o_sharedMainInstance) {
  139.         [self dealloc];
  140.     } else {
  141.         _o_sharedMainInstance = [super init];
  142.         p_intf = VLCIntf;
  143.     }
  144.  
  145.     return _o_sharedMainInstance;
  146. }
  147. - (void)dealloc
  148. {
  149.     if( o_file_slave_path )
  150.         [o_file_slave_path release];
  151.     [super dealloc];
  152. }
  153. - (void)awakeFromNib
  154. {
  155.     [o_panel setTitle: _NS("Open Source")];
  156.     [o_mrl_lbl setStringValue: _NS("Media Resource Locator (MRL)")];
  157.     [o_btn_ok setTitle: _NS("Open")];
  158.     [o_btn_cancel setTitle: _NS("Cancel")];
  159.     [[o_tabview tabViewItemAtIndex: 0] setLabel: _NS("File")];
  160.     [[o_tabview tabViewItemAtIndex: 1] setLabel: _NS("Disc")];
  161.     [[o_tabview tabViewItemAtIndex: 2] setLabel: _NS("Network")];
  162.     [[o_tabview tabViewItemAtIndex: 3] setLabel: _NS("Capture")];
  163.     [o_file_btn_browse setTitle: _NS("Browse...")];
  164.     [o_file_stream setTitle: _NS("Treat as a pipe rather than as a file")];
  165.     [o_file_slave_ckbox setTitle: _NS("Play another media synchronously")];
  166.     [o_file_slave_select_btn setTitle: _NS("Choose...")];
  167.     [o_file_slave_filename_txt setStringValue: @""];
  168.     [o_disc_device_lbl setStringValue: _NS("Device name")];
  169.     [o_disc_title_lbl setStringValue: _NS("Title")];
  170.     [o_disc_chapter_lbl setStringValue: _NS("Chapter")];
  171.     [o_disc_videots_btn_browse setTitle: _NS("Browse...")];
  172.     [o_disc_dvd_menus setTitle: _NS("No DVD menus")];
  173.     [[o_disc_type cellAtRow:0 column:0] setTitle: _NS("VIDEO_TS folder")];
  174.     [[o_disc_type cellAtRow:1 column:0] setTitle: _NS("DVD")];
  175.     [[o_disc_type cellAtRow:2 column:0] setTitle: _NS("VCD")];
  176.     [[o_disc_type cellAtRow:3 column:0] setTitle: _NS("Audio CD")];
  177.     [o_net_udp_port_lbl setStringValue: _NS("Port")];
  178.     [o_net_udpm_addr_lbl setStringValue: _NS("IP Address")];
  179.     [o_net_udpm_port_lbl setStringValue: _NS("Port")];
  180.     [o_net_http_url_lbl setStringValue: _NS("URL")];
  181.     [o_net_help_lbl setStringValue: _NS("To Open a usual network stream (HTTP, RTSP, RTMP, MMS, FTP, etc.), just enter the URL in the field above. If you want to open a RTP or UDP stream, press the button below.")];
  182.     [o_net_help_udp_lbl setStringValue: _NS("If you want to open a multicast stream, enter the respective IP address given by the stream provider. In unicast mode, VLC will use your machine's IP automatically.nnTo open a stream using a different protocol, just press Cancel to close this sheet.")];
  183.     [o_net_udp_cancel_btn setTitle: _NS("Cancel")];
  184.     [o_net_udp_ok_btn setTitle: _NS("Open")];
  185.     [o_net_openUDP_btn setTitle: _NS("Open RTP/UDP Stream")];
  186.     [o_net_udp_mode_lbl setStringValue: _NS("Mode")];
  187.     [o_net_udp_protocol_lbl setStringValue: _NS("Protocol")];
  188.     [o_net_udp_address_lbl setStringValue: _NS("Address")];
  189.     [[o_net_mode cellAtRow:0 column:0] setTitle: _NS("Unicast")];
  190.     [[o_net_mode cellAtRow:1 column:0] setTitle: _NS("Multicast")];
  191.     [o_net_udp_port setIntValue: config_GetInt( p_intf, "server-port" )];
  192.     [o_net_udp_port_stp setIntValue: config_GetInt( p_intf, "server-port" )];
  193.     [o_eyetv_chn_bgbar setUsesThreadedAnimation: YES];
  194.     [o_capture_mode_pop removeAllItems];
  195.     [o_capture_mode_pop addItemWithTitle: @"iSight"];
  196.     [o_capture_mode_pop addItemWithTitle: _NS("Screen")];
  197.     [o_capture_mode_pop addItemWithTitle: @"EyeTV"];
  198.     [o_screen_lbl setStringValue: _NS("Screen Capture Input")];
  199.     [o_screen_long_lbl setStringValue: _NS("This facility allows you to process your screen's output.")];
  200.     [o_screen_fps_lbl setStringValue: _NS("Frames per Second:")];
  201.     [o_screen_left_lbl setStringValue: _NS("Subscreen left:")];
  202.     [o_screen_top_lbl setStringValue: _NS("Subscreen top:")];
  203.     [o_screen_width_lbl setStringValue: _NS("Subscreen width:")];
  204.     [o_screen_height_lbl setStringValue: _NS("Subscreen height:")];
  205.     [o_screen_follow_mouse_ckb setTitle: _NS("Follow the mouse")];
  206.     [o_eyetv_currentChannel_lbl setStringValue: _NS("Current channel:")];
  207.     [o_eyetv_previousProgram_btn setTitle: _NS("Previous Channel")];
  208.     [o_eyetv_nextProgram_btn setTitle: _NS("Next Channel")];
  209.     [o_eyetv_chn_status_txt setStringValue: _NS("Retrieving Channel Info...")];
  210.     [o_eyetv_noInstance_lbl setStringValue: _NS("EyeTV is not launched")];
  211.     [o_eyetv_noInstanceLong_lbl setStringValue: _NS("VLC could not connect to EyeTV.nMake sure that you installed VLC's EyeTV plugin.")];
  212.     [o_eyetv_launchEyeTV_btn setTitle: _NS("Launch EyeTV now")];
  213.     [o_eyetv_getPlugin_btn setTitle: _NS("Download Plugin")];
  214.     [self setSubPanel];
  215.     [[NSNotificationCenter defaultCenter] addObserver: self
  216.         selector: @selector(openFilePathChanged:)
  217.         name: NSControlTextDidChangeNotification
  218.         object: o_file_path];
  219.     [[NSNotificationCenter defaultCenter] addObserver: self
  220.         selector: @selector(openDiscInfoChanged:)
  221.         name: NSControlTextDidChangeNotification
  222.         object: o_disc_device];
  223.     [[NSNotificationCenter defaultCenter] addObserver: self
  224.         selector: @selector(openDiscInfoChanged:)
  225.         name: NSControlTextDidChangeNotification
  226.         object: o_disc_title];
  227.     [[NSNotificationCenter defaultCenter] addObserver: self
  228.         selector: @selector(openDiscInfoChanged:)
  229.         name: NSControlTextDidChangeNotification
  230.         object: o_disc_chapter];
  231.     [[NSNotificationCenter defaultCenter] addObserver: self
  232.         selector: @selector(openDiscInfoChanged:)
  233.         name: NSControlTextDidChangeNotification
  234.         object: o_disc_videots_folder];
  235.     [[NSNotificationCenter defaultCenter] addObserver: self
  236.         selector: @selector(openNetInfoChanged:)
  237.         name: NSControlTextDidChangeNotification
  238.         object: o_net_udp_port];
  239.     [[NSNotificationCenter defaultCenter] addObserver: self
  240.         selector: @selector(openNetInfoChanged:)
  241.         name: NSControlTextDidChangeNotification
  242.         object: o_net_udpm_addr];
  243.     [[NSNotificationCenter defaultCenter] addObserver: self
  244.         selector: @selector(openNetInfoChanged:)
  245.         name: NSControlTextDidChangeNotification
  246.         object: o_net_udpm_port];
  247.     [[NSNotificationCenter defaultCenter] addObserver: self
  248.         selector: @selector(openNetInfoChanged:)
  249.         name: NSControlTextDidChangeNotification
  250.         object: o_net_http_url];
  251.     [[NSDistributedNotificationCenter defaultCenter] addObserver: self
  252.                                                         selector: @selector(eyetvChanged:)
  253.                                                             name: NULL
  254.                                                           object: @"VLCEyeTVSupport"
  255.                                               suspensionBehavior: NSNotificationSuspensionBehaviorDeliverImmediately];
  256.     [[NSNotificationCenter defaultCenter] addObserver: self
  257.                                              selector: @selector(screenFPSfieldChanged:)
  258.                                                  name: NSControlTextDidChangeNotification
  259.                                                object: o_screen_fps_fld];
  260.     /* register clicks on text fields */
  261.     [[NSNotificationCenter defaultCenter] addObserver: self
  262.                                              selector: @selector(textFieldWasClicked:)
  263.                                                  name: @"VLCOpenTextFieldWasClicked"
  264.                                                object: nil];
  265. }
  266. - (void)setSubPanel
  267. {
  268.     int i_index;
  269.     module_config_t * p_item;
  270.     [o_file_sub_ckbox setTitle: _NS("Load subtitles file:")];
  271.     [o_file_sub_btn_settings setTitle: _NS("Settings...")];
  272.     [o_file_sub_btn_browse setTitle: _NS("Browse...")];
  273.     [o_file_sub_override setTitle: _NS("Override parametters")];
  274.     [o_file_sub_delay_lbl setStringValue: _NS("Delay")];
  275.     [o_file_sub_delay_stp setEnabled: NO];
  276.     [o_file_sub_fps_lbl setStringValue: _NS("FPS")];
  277.     [o_file_sub_fps_stp setEnabled: NO];
  278.     [o_file_sub_encoding_lbl setStringValue: _NS("Subtitles encoding")];
  279.     [o_file_sub_encoding_pop removeAllItems];
  280.     [o_file_sub_size_lbl setStringValue: _NS("Font size")];
  281.     [o_file_sub_size_pop removeAllItems];
  282.     [o_file_sub_align_lbl setStringValue: _NS("Subtitles alignment")];
  283.     [o_file_sub_align_pop removeAllItems];
  284.     [o_file_sub_ok_btn setStringValue: _NS("OK")];
  285.     [o_file_sub_font_box setTitle: _NS("Font Properties")];
  286.     [o_file_sub_file_box setTitle: _NS("Subtitle File")];
  287.     p_item = config_FindConfig( VLC_OBJECT(p_intf), "subsdec-encoding" );
  288.     if( p_item )
  289.     {
  290.         for( i_index = 0; p_item->ppsz_list && p_item->ppsz_list[i_index];
  291.              i_index++ )
  292.         {
  293.             [o_file_sub_encoding_pop addItemWithTitle:
  294.                 [NSString stringWithUTF8String: p_item->ppsz_list[i_index]]];
  295.         }
  296.         [o_file_sub_encoding_pop selectItemWithTitle:
  297.                 [NSString stringWithUTF8String: p_item->value.psz]];
  298.     }
  299.     p_item = config_FindConfig( VLC_OBJECT(p_intf), "subsdec-align" );
  300.     if ( p_item )
  301.     {
  302.         for ( i_index = 0; i_index < p_item->i_list; i_index++ )
  303.         {
  304.             [o_file_sub_align_pop addItemWithTitle:
  305.                 [NSString stringWithUTF8String:
  306.                 p_item->ppsz_list_text[i_index]]];
  307.         }
  308.         [o_file_sub_align_pop selectItemAtIndex: p_item->value.i];
  309.     }
  310.     p_item = config_FindConfig( VLC_OBJECT(p_intf), "freetype-rel-fontsize" );
  311.     if ( p_item )
  312.     {
  313.         for ( i_index = 0; i_index < p_item->i_list; i_index++ )
  314.         {
  315.             [o_file_sub_size_pop addItemWithTitle:
  316.                 [NSString stringWithUTF8String:
  317.                 p_item->ppsz_list_text[i_index]]];
  318.             if ( p_item->value.i == p_item->pi_list[i_index] )
  319.             {
  320.                 [o_file_sub_size_pop selectItemAtIndex: i_index];
  321.             }
  322.         }
  323.     }
  324. }
  325. - (void)openTarget:(int)i_type
  326. {
  327.     int i_result;
  328.     b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
  329.     [o_tabview selectTabViewItemAtIndex: i_type];
  330.     [o_file_sub_ckbox setState: NSOffState];
  331.  
  332.     i_result = [NSApp runModalForWindow: o_panel];
  333.     [o_panel close];
  334.     if( i_result )
  335.     {
  336.         NSMutableDictionary *o_dic;
  337.         NSMutableArray *o_options = [NSMutableArray array];
  338.         unsigned int i;
  339.         o_dic = [NSMutableDictionary dictionaryWithObject: [o_mrl stringValue] forKey: @"ITEM_URL"];
  340.         if( [o_file_sub_ckbox state] == NSOnState )
  341.         {
  342.             module_config_t * p_item;
  343.             [o_options addObject: [NSString stringWithFormat: @"sub-file=%@", [o_file_sub_path stringValue]]];
  344.             if( [o_file_sub_override state] == NSOnState )
  345.             {
  346.                 [o_options addObject: [NSString stringWithFormat: @"sub-delay=%i", (int)( [o_file_sub_delay intValue] * 10 )]];
  347.                 [o_options addObject: [NSString stringWithFormat: @"sub-fps=%f", [o_file_sub_fps floatValue]]];
  348.             }
  349.             [o_options addObject: [NSString stringWithFormat:
  350.                     @"subsdec-encoding=%@",
  351.                     [o_file_sub_encoding_pop titleOfSelectedItem]]];
  352.             [o_options addObject: [NSString stringWithFormat:
  353.                     @"subsdec-align=%i",
  354.                     [o_file_sub_align_pop indexOfSelectedItem]]];
  355.             p_item = config_FindConfig( VLC_OBJECT(p_intf),
  356.                                             "freetype-rel-fontsize" );
  357.             if ( p_item )
  358.             {
  359.                 [o_options addObject: [NSString stringWithFormat:
  360.                     @"freetype-rel-fontsize=%i",
  361.                     p_item->pi_list[[o_file_sub_size_pop indexOfSelectedItem]]]];
  362.             }
  363.         }
  364.         if( [o_output_ckbox state] == NSOnState )
  365.         {
  366.             for (i = 0 ; i < [[o_sout_options mrl] count] ; i++)
  367.             {
  368.                 [o_options addObject: [NSString stringWithString:
  369.                       [[(VLCOutput *)o_sout_options mrl] objectAtIndex: i]]];
  370.             }
  371.         }
  372.         if( [o_file_slave_ckbox state] && o_file_slave_path )
  373.             [o_options addObject: [NSString stringWithFormat: @"input-slave=%@", o_file_slave_path]];
  374.         if( [[[o_tabview selectedTabViewItem] label] isEqualToString: _NS("Capture")] )
  375.         {
  376.             if( [[[o_capture_mode_pop selectedItem] title] isEqualToString: _NS("Screen")] )
  377.                 [o_options addObject: [NSString stringWithFormat: @"screen-fps=%f", [o_screen_fps_fld floatValue]]];
  378.                 [o_options addObject: [NSString stringWithFormat: @"screen-left=%i", [o_screen_left_fld intValue]]];
  379.                 [o_options addObject: [NSString stringWithFormat: @"screen-top=%i", [o_screen_top_fld intValue]]];
  380.                 [o_options addObject: [NSString stringWithFormat: @"screen-width=%i", [o_screen_width_fld intValue]]];
  381.                 [o_options addObject: [NSString stringWithFormat: @"screen-height=%i", [o_screen_height_fld intValue]]];
  382.                 if( [o_screen_follow_mouse_ckb intValue] == YES )
  383.                     [o_options addObject: @"screen-follow-mouse"];
  384.                 else
  385.                     [o_options addObject: @"no-screen-follow-mouse"];
  386.         }
  387.         /* apply the options to our item(s) */
  388.         [o_dic setObject: (NSArray *)[o_options copy] forKey: @"ITEM_OPTIONS"];
  389.         if( b_autoplay )
  390.             [o_playlist appendArray: [NSArray arrayWithObject: o_dic] atPos: -1 enqueue:NO];
  391.         else
  392.             [o_playlist appendArray: [NSArray arrayWithObject: o_dic] atPos: -1 enqueue:YES];
  393.     }
  394. }
  395. - (void)tabView:(NSTabView *)o_tv didSelectTabViewItem:(NSTabViewItem *)o_tvi
  396. {
  397.     NSString *o_label = [o_tvi label];
  398.     if( [o_label isEqualToString: _NS("File")] )
  399.     {
  400.         [self openFilePathChanged: nil];
  401.     }
  402.     else if( [o_label isEqualToString: _NS("Disc")] )
  403.     {
  404.         [self openDiscTypeChanged: nil];
  405.     }
  406.     else if( [o_label isEqualToString: _NS("Network")] )
  407.     {
  408.         [self openNetInfoChanged: nil];
  409.     }
  410.     else if( [o_label isEqualToString: _NS("Capture")] )
  411.     {
  412.         [self openCaptureModeChanged: nil];
  413.     }
  414. }
  415. - (IBAction)expandMRLfieldAction:(id)sender
  416. {
  417.     NSRect o_win_rect, o_view_rect;
  418.     o_win_rect = [o_panel frame];
  419.     o_view_rect = [o_mrl_view frame];
  420.     if( [o_mrl_btn state] == NSOffState )
  421.     {
  422.         /* we need to collaps, restore the panel size */
  423.         o_win_rect.size.height = o_win_rect.size.height - o_view_rect.size.height;
  424.         o_win_rect.origin.y = ( o_win_rect.origin.y + o_view_rect.size.height ) - o_view_rect.size.height;
  425.         /* remove the MRL view */
  426.         [o_mrl_view removeFromSuperviewWithoutNeedingDisplay];
  427.     } else {
  428.         /* we need to expand */
  429.         [o_mrl_view setFrame: NSMakeRect( 0,
  430.                                          [o_mrl_btn frame].origin.y,
  431.                                          o_view_rect.size.width,
  432.                                          o_view_rect.size.height )];
  433.         [o_mrl_view setNeedsDisplay: YES];
  434.         [o_mrl_view setAutoresizesSubviews: YES];
  435.         /* add the MRL view */
  436.         [[o_panel contentView] addSubview: o_mrl_view];
  437.         o_win_rect.size.height = o_win_rect.size.height + o_view_rect.size.height;
  438.     }
  439.     [o_panel setFrame: o_win_rect display:YES animate: YES];
  440.     [o_panel displayIfNeeded];
  441. }
  442. - (IBAction)inputSlaveAction:(id)sender
  443. {
  444.     if( sender == o_file_slave_ckbox )
  445.         [o_file_slave_select_btn setEnabled: [o_file_slave_ckbox state]];
  446.     else
  447.     {
  448.         NSOpenPanel *o_open_panel;
  449.         o_open_panel = [NSOpenPanel openPanel];
  450.         [o_open_panel setCanChooseFiles: YES];
  451.         [o_open_panel setCanChooseDirectories: NO];
  452.         if( [o_open_panel runModalForDirectory: nil file: nil types: nil] == NSOKButton )
  453.             {
  454.                 if( o_file_slave_path )
  455.                         [o_file_slave_path release];
  456.                 o_file_slave_path = [[o_open_panel filenames] objectAtIndex: 0];
  457.                 [o_file_slave_path retain];
  458.             }
  459.         else
  460.             [o_file_slave_filename_txt setStringValue: @""];
  461.     }
  462.     if( o_file_slave_path )
  463.     {
  464.         NSFileWrapper *o_file_wrapper;
  465.         o_file_wrapper = [[NSFileWrapper alloc] initWithPath: o_file_slave_path];
  466.         [o_file_slave_filename_txt setStringValue: [NSString stringWithFormat: @""%@"", [o_file_wrapper preferredFilename]]];
  467.         [o_file_wrapper release];
  468.     }
  469. }
  470. - (void)openFileGeneric
  471. {
  472.     [self openFilePathChanged: nil];
  473.     [self openTarget: 0];
  474. }
  475. - (void)openDisc
  476. {
  477.     [self openDiscTypeChanged: nil];
  478.     [self openTarget: 1];
  479. }
  480. - (void)openNet
  481. {
  482.     [self openNetInfoChanged: nil];
  483.     [self openTarget: 2];
  484. }
  485. - (void)openCapture
  486. {
  487.     [self openCaptureModeChanged: nil];
  488.     [self showCaptureView: o_capture_label_view];
  489.     [self openTarget: 3];
  490. }
  491. - (void)openFilePathChanged:(NSNotification *)o_notification
  492. {
  493.     NSString *o_filename = [o_file_path stringValue];
  494.     bool b_stream = [o_file_stream state];
  495.     BOOL b_dir = NO;
  496.     [[NSFileManager defaultManager] fileExistsAtPath:o_filename isDirectory:&b_dir];
  497.     char *psz_uri = make_URI([o_filename UTF8String]);
  498.     if( !psz_uri ) return;
  499.     NSMutableString *o_mrl_string = [NSMutableString stringWithUTF8String: psz_uri ];
  500.     NSRange offile = [o_mrl_string rangeOfString:@"file"];
  501.     free( psz_uri );
  502.     if( b_dir )
  503.     {
  504.         [o_mrl_string replaceCharactersInRange:offile withString: @"directory"];
  505.     }
  506.     else if( b_stream )
  507.     {
  508.         [o_mrl_string replaceCharactersInRange:offile withString: @"stream"];
  509.     }
  510.     [o_mrl setStringValue: o_mrl_string];
  511. }
  512. - (IBAction)openFileBrowse:(id)sender
  513. {
  514.     NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
  515.  
  516.     [o_open_panel setAllowsMultipleSelection: NO];
  517.     [o_open_panel setCanChooseDirectories: YES];
  518.     [o_open_panel setTitle: _NS("Open File")];
  519.     [o_open_panel setPrompt: _NS("Open")];
  520.     [o_open_panel beginSheetForDirectory:nil
  521.         file:nil
  522.         types:nil
  523.         modalForWindow:[sender window]
  524.         modalDelegate: self
  525.         didEndSelector: @selector(pathChosenInPanel:
  526.                         withReturn:
  527.                         contextInfo:)
  528.         contextInfo: nil];
  529. }
  530. - (void)pathChosenInPanel: (NSOpenPanel *) sheet withReturn:(int)returnCode contextInfo:(void  *)contextInfo
  531. {
  532.     if (returnCode == NSFileHandlingPanelOKButton)
  533.     {
  534.         NSString *o_filename = [[sheet filenames] objectAtIndex: 0];
  535.         [o_file_path setStringValue: o_filename];
  536.         [self openFilePathChanged: nil];
  537.     }
  538. }
  539. - (IBAction)openFileStreamChanged:(id)sender
  540. {
  541.     [self openFilePathChanged: nil];
  542. }
  543. - (IBAction)openDiscTypeChanged:(id)sender
  544. {
  545.     NSString *o_type;
  546.     BOOL b_device, b_no_menus, b_title_chapter;
  547.  
  548.     [o_disc_device removeAllItems];
  549.     b_title_chapter = ![o_disc_dvd_menus state];
  550.  
  551.     o_type = [[o_disc_type selectedCell] title];
  552.     if ( [o_type isEqualToString: _NS("VIDEO_TS folder")] )
  553.     {
  554.         b_device = NO; b_no_menus = YES;
  555.     }
  556.     else
  557.     {
  558.         NSArray *o_devices;
  559.         NSString *o_disc;
  560.         const char *psz_class = NULL;
  561.         b_device = YES;
  562.         if ( [o_type isEqualToString: _NS("VCD")] )
  563.         {
  564.             psz_class = kIOCDMediaClass;
  565.             o_disc = o_type;
  566.             b_no_menus = NO; b_title_chapter = YES;
  567. }
  568.         else if ( [o_type isEqualToString: _NS("Audio CD")])
  569.         {
  570.             psz_class = kIOCDMediaClass;
  571.             o_disc = o_type;
  572.             b_no_menus = NO; b_title_chapter = NO;
  573.         }
  574.         else
  575.         {
  576.             psz_class = kIODVDMediaClass;
  577.             o_disc = o_type;
  578.             b_no_menus = YES;
  579.         }
  580.  
  581.         o_devices = GetEjectableMediaOfClass( psz_class );
  582.         if ( o_devices != nil )
  583.         {
  584.             int i_devices = [o_devices count];
  585.  
  586.             if ( i_devices )
  587.             {
  588. for( int i = 0; i < i_devices; i++ )
  589.                 {
  590.                     [o_disc_device
  591.                         addItemWithObjectValue: [o_devices objectAtIndex: i]];
  592.                 }
  593.                 [o_disc_device selectItemAtIndex: 0];
  594.             }
  595.             else
  596.             {
  597.                 [o_disc_device setStringValue:
  598.                     [NSString stringWithFormat: _NS("No %@s found"), o_disc]];
  599.             }
  600.         }
  601.     }
  602.     [o_disc_device setEnabled: b_device];
  603.     [o_disc_title setEnabled: b_title_chapter];
  604.     [o_disc_title_stp setEnabled: b_title_chapter];
  605.     [o_disc_chapter setEnabled: b_title_chapter];
  606.     [o_disc_chapter_stp setEnabled: b_title_chapter];
  607.     [o_disc_videots_folder setEnabled: !b_device];
  608.     [o_disc_videots_btn_browse setEnabled: !b_device];
  609.     [o_disc_dvd_menus setEnabled: b_no_menus];
  610.     [self openDiscInfoChanged: nil];
  611. }
  612. - (IBAction)openDiscStepperChanged:(id)sender
  613. {
  614.     int i_tag = [sender tag];
  615.     if( i_tag == 0 )
  616.     {
  617.         [o_disc_title setIntValue: [o_disc_title_stp intValue]];
  618.     }
  619.     else if( i_tag == 1 )
  620.     {
  621.         [o_disc_chapter setIntValue: [o_disc_chapter_stp intValue]];
  622.     }
  623.     [self openDiscInfoChanged: nil];
  624. }
  625. - (void)openDiscInfoChanged:(NSNotification *)o_notification
  626. {
  627.     NSString *o_type;
  628.     NSString *o_device;
  629.     NSString *o_videots;
  630.     NSString *o_mrl_string;
  631.     int i_title, i_chapter;
  632.     BOOL b_no_menus;
  633.     o_type = [[o_disc_type selectedCell] title];
  634.     o_device = [o_disc_device stringValue];
  635.     i_title = [o_disc_title intValue];
  636.     i_chapter = [o_disc_chapter intValue];
  637.     o_videots = [o_disc_videots_folder stringValue];
  638.     b_no_menus = [o_disc_dvd_menus state];
  639.     if ( [o_type isEqualToString: _NS("VCD")] )
  640.     {
  641.         if ( [o_device isEqualToString:
  642.                 [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
  643.             o_device = @"";
  644.         o_mrl_string = [NSString stringWithFormat: @"vcd://%@@%i:%i",
  645.                         o_device, i_title, i_chapter];
  646.     }
  647.     else if ( [o_type isEqualToString: _NS("Audio CD")] )
  648.     {
  649.         if ( [o_device isEqualToString:
  650.                 [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
  651.             o_device = @"";
  652.         o_mrl_string = [NSString stringWithFormat: @"cdda://%@",
  653.                         o_device];
  654.     }
  655.     else if ( [o_type isEqualToString: _NS("DVD")] )
  656.     {
  657.         if ( [o_device isEqualToString:
  658.                 [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
  659.             o_device = @"";
  660.         if ( b_no_menus )
  661.             o_mrl_string = [NSString stringWithFormat: @"dvdread://%@@%i:%i-",
  662.                             o_device, i_title, i_chapter];
  663.         else
  664. o_mrl_string = [NSString stringWithFormat: @"dvdnav://%@",
  665.                             o_device];
  666.             
  667.     }
  668.     else /* VIDEO_TS folder */
  669.     {
  670.         if ( b_no_menus )
  671.             o_mrl_string = [NSString stringWithFormat: @"dvdread://%@@%i:%i",
  672.                             o_videots, i_title, i_chapter];
  673.         else
  674. o_mrl_string = [NSString stringWithFormat: @"dvdnav://%@",
  675.                             o_videots];            
  676.     }
  677.     [o_mrl setStringValue: o_mrl_string];
  678. }
  679. - (IBAction)openDiscMenusChanged:(id)sender
  680. {
  681.     [self openDiscInfoChanged: nil];
  682.     [self openDiscTypeChanged: nil];
  683. }
  684. - (IBAction)openVTSBrowse:(id)sender
  685. {
  686.     NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
  687.     [o_open_panel setAllowsMultipleSelection: NO];
  688.     [o_open_panel setCanChooseFiles: NO];
  689.     [o_open_panel setCanChooseDirectories: YES];
  690.     [o_open_panel setTitle: _NS("Open VIDEO_TS Directory")];
  691.     [o_open_panel setPrompt: _NS("Open")];
  692.     if( [o_open_panel runModalForDirectory: nil
  693.             file: nil types: nil] == NSOKButton )
  694.     {
  695.         NSString *o_dirname = [[o_open_panel filenames] objectAtIndex: 0];
  696.         [o_disc_videots_folder setStringValue: o_dirname];
  697.         [self openDiscInfoChanged: nil];
  698.     }
  699. }
  700. - (void)textFieldWasClicked:(NSNotification *)o_notification
  701. {
  702.     if( [o_notification object] == o_net_udp_port )
  703.         [o_net_mode selectCellAtRow: 0 column: 0];
  704.     else if( [o_notification object] == o_net_udpm_addr ||
  705.              [o_notification object] == o_net_udpm_port )
  706.         [o_net_mode selectCellAtRow: 1 column: 0];
  707.     else
  708.         [o_net_mode selectCellAtRow: 2 column: 0];
  709.     [self openNetInfoChanged: nil];
  710. }
  711. - (IBAction)openNetModeChanged:(id)sender
  712. {
  713.     if( sender == o_net_mode )
  714.     {
  715.         if( [[sender selectedCell] tag] == 0 )
  716.             [o_panel makeFirstResponder: o_net_udp_port];
  717.         else if ( [[sender selectedCell] tag] == 1 )
  718.             [o_panel makeFirstResponder: o_net_udpm_addr];
  719.         else
  720.             msg_Warn( p_intf, "Unknown sender tried to change UDP/RTP mode" );
  721.     }
  722.     [self openNetInfoChanged: nil];
  723. }
  724. - (IBAction)openNetStepperChanged:(id)sender
  725. {
  726.     int i_tag = [sender tag];
  727.     if( i_tag == 0 )
  728.     {
  729.         [o_net_udp_port setIntValue: [o_net_udp_port_stp intValue]];
  730.         [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCOpenTextFieldWasClicked"
  731.                                                             object: o_net_udp_port];
  732.         [o_panel makeFirstResponder: o_net_udp_port];
  733.     }
  734.     else if( i_tag == 1 )
  735.     {
  736.         [o_net_udpm_port setIntValue: [o_net_udpm_port_stp intValue]];
  737.         [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCOpenTextFieldWasClicked"
  738.                                                             object: o_net_udpm_port];
  739.         [o_panel makeFirstResponder: o_net_udpm_port];
  740.     }
  741.     [self openNetInfoChanged: nil];
  742. }
  743. - (void)openNetInfoChanged:(NSNotification *)o_notification
  744. {
  745.     NSString *o_mrl_string = [NSString string];
  746.     if( [o_net_udp_panel isVisible] )
  747.     {
  748.         NSString *o_mode;
  749.         o_mode = [[o_net_mode selectedCell] title];
  750.         if( [o_mode isEqualToString: _NS("Unicast")] )
  751.         {
  752.             int i_port = [o_net_udp_port intValue];
  753.             if( [[o_net_udp_protocol_mat selectedCell] tag] == 0 )
  754.                 o_mrl_string = [NSString stringWithString: @"udp://"];
  755.             else
  756.                 o_mrl_string = [NSString stringWithString: @"rtp://"];
  757.             if( i_port != config_GetInt( p_intf, "server-port" ) )
  758.             {
  759.                 o_mrl_string =
  760.                     [o_mrl_string stringByAppendingFormat: @"@:%i", i_port];
  761.             }
  762.         }
  763.         else if( [o_mode isEqualToString: _NS("Multicast")] )
  764.         {
  765.             NSString *o_addr = [o_net_udpm_addr stringValue];
  766.             int i_port = [o_net_udpm_port intValue];
  767.             if( [[o_net_udp_protocol_mat selectedCell] tag] == 0 )
  768.                 o_mrl_string = [NSString stringWithFormat: @"udp://@%@", o_addr];
  769.             else
  770.                 o_mrl_string = [NSString stringWithFormat: @"rtp://@%@", o_addr];
  771.             if( i_port != config_GetInt( p_intf, "server-port" ) )
  772.             {
  773.                 o_mrl_string =
  774.                     [o_mrl_string stringByAppendingFormat: @":%i", i_port];
  775.             }
  776.         }
  777.     }
  778.     else
  779.     {
  780.         NSString *o_url = [o_net_http_url stringValue];
  781.         if ( ![o_url hasPrefix:@"http:"] && ![o_url hasPrefix:@"ftp:"]
  782.               && ![o_url hasPrefix:@"mms"] && ![o_url hasPrefix:@"rtsp"] && ![o_url hasPrefix:@"rtmp"] )
  783.             o_mrl_string = [NSString stringWithFormat: @"http://%@", o_url];
  784.         else
  785.             o_mrl_string = o_url;
  786.     }
  787.     [o_mrl setStringValue: o_mrl_string];
  788. }
  789. - (IBAction)openNetUDPButtonAction:(id)sender
  790. {
  791.     if( sender == o_net_openUDP_btn )
  792.     {
  793.         [NSApp beginSheet: o_net_udp_panel
  794.            modalForWindow: o_panel
  795.             modalDelegate: self
  796.            didEndSelector: NULL
  797.               contextInfo: nil];
  798.         [self openNetInfoChanged: nil];
  799.     }
  800.     else if( sender == o_net_udp_cancel_btn )
  801.     {
  802.         [o_net_udp_panel orderOut: sender];
  803.         [NSApp endSheet: o_net_udp_panel];
  804.     }
  805.     else if( sender == o_net_udp_ok_btn )
  806.     {
  807.         NSString *o_mrl_string = [NSString string];
  808.         if( [[[o_net_mode selectedCell] title] isEqualToString: _NS("Unicast")] )
  809.         {
  810.             int i_port = [o_net_udp_port intValue];
  811.             
  812.             if( [[o_net_udp_protocol_mat selectedCell] tag] == 0 )
  813.                 o_mrl_string = [NSString stringWithString: @"udp://"];
  814.             else
  815.                 o_mrl_string = [NSString stringWithString: @"rtp://"];
  816.             if( i_port != config_GetInt( p_intf, "server-port" ) )
  817.             {
  818.                 o_mrl_string =
  819.                 [o_mrl_string stringByAppendingFormat: @"@:%i", i_port];
  820.             }
  821.         }
  822.         else if( [[[o_net_mode selectedCell] title] isEqualToString: _NS("Multicast")] )
  823.         {
  824.             NSString *o_addr = [o_net_udpm_addr stringValue];
  825.             int i_port = [o_net_udpm_port intValue];
  826.             
  827.             if( [[o_net_udp_protocol_mat selectedCell] tag] == 0 )
  828.                 o_mrl_string = [NSString stringWithFormat: @"udp://@%@", o_addr];
  829.             else
  830.                 o_mrl_string = [NSString stringWithFormat: @"rtp://@%@", o_addr];
  831.             if( i_port != config_GetInt( p_intf, "server-port" ) )
  832.             {
  833.                 o_mrl_string =
  834.                 [o_mrl_string stringByAppendingFormat: @":%i", i_port];
  835.             }
  836.         }
  837.         [o_mrl setStringValue: o_mrl_string];
  838.         [o_net_http_url setStringValue: o_mrl_string];
  839.         [o_net_udp_panel orderOut: sender];
  840.         [NSApp endSheet: o_net_udp_panel];
  841.     }
  842. }
  843.     
  844. - (void)openFile
  845. {
  846.     NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
  847.     int i;
  848.     b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
  849.  
  850.     [o_open_panel setAllowsMultipleSelection: YES];
  851.     [o_open_panel setCanChooseDirectories: YES];
  852.     [o_open_panel setTitle: _NS("Open File")];
  853.     [o_open_panel setPrompt: _NS("Open")];
  854.  
  855.     if( [o_open_panel runModalForDirectory: nil
  856.             file: nil types: nil] == NSOKButton )
  857.     {
  858.         NSArray *o_array = [NSArray array];
  859.         NSArray *o_values = [[o_open_panel filenames]
  860.                 sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
  861.         for( i = 0; i < (int)[o_values count]; i++)
  862.         {
  863.             NSDictionary *o_dic;
  864.             o_dic = [NSDictionary dictionaryWithObject:[o_values objectAtIndex:i] forKey:@"ITEM_URL"];
  865.             o_array = [o_array arrayByAddingObject: o_dic];
  866.         }
  867.         if( b_autoplay )
  868.             [o_playlist appendArray: o_array atPos: -1 enqueue:NO];
  869.         else
  870.             [o_playlist appendArray: o_array atPos: -1 enqueue:YES];
  871.     }
  872. }
  873. - (void)showCaptureView: theView
  874. {
  875.     NSRect o_view_rect;
  876.     o_view_rect = [theView frame];
  877.     if( o_currentCaptureView )
  878.     {
  879.         [o_currentCaptureView removeFromSuperviewWithoutNeedingDisplay];
  880.         [o_currentCaptureView release];
  881.     }
  882.     [theView setFrame: NSMakeRect( 0, -10, o_view_rect.size.width, o_view_rect.size.height)];
  883.     [theView setNeedsDisplay: YES];
  884.     [theView setAutoresizesSubviews: YES];
  885.     [[[o_tabview tabViewItemAtIndex: 3] view] addSubview: theView];
  886.     [theView displayIfNeeded];
  887.     o_currentCaptureView = theView;
  888.     [o_currentCaptureView retain];
  889. }
  890. - (IBAction)openCaptureModeChanged:(id)sender
  891. {
  892.     if( [[[o_capture_mode_pop selectedItem] title] isEqualToString: @"EyeTV"] )
  893.     {
  894.         if( [[[VLCMain sharedInstance] eyeTVController] isEyeTVrunning] == YES )
  895.         {
  896.             if( [[[VLCMain sharedInstance] eyeTVController] isDeviceConnected] == YES )
  897.             {
  898.                 [self showCaptureView: o_eyetv_running_view];
  899.                 [self setupChannelInfo];
  900.             }
  901.             else
  902.             {
  903.                 setEyeTVUnconnected;
  904.             }
  905.         }
  906.         else
  907.             [self showCaptureView: o_eyetv_notLaunched_view];
  908.         [o_mrl setStringValue: @""];
  909.     } 
  910.     else if( [[[o_capture_mode_pop selectedItem] title] isEqualToString: _NS("Screen")] )
  911.     {
  912.         [self showCaptureView: o_screen_view];
  913.         [o_mrl setStringValue: @"screen://"];
  914.         [o_screen_height_fld setIntValue: config_GetInt( p_intf, "screen-height" )];
  915.         [o_screen_width_fld setIntValue: config_GetInt( p_intf, "screen-width" )];
  916.         [o_screen_fps_fld setFloatValue: config_GetFloat( p_intf, "screen-fps" )];
  917.         [o_screen_left_fld setIntValue: config_GetInt( p_intf, "screen-left" )];
  918.         [o_screen_top_fld setIntValue: config_GetInt( p_intf, "screen-top" )];
  919.         [o_screen_follow_mouse_ckb setIntValue: config_GetInt( p_intf, "screen-follow-mouse" )];
  920.     }
  921.     else if( [[[o_capture_mode_pop selectedItem] title] isEqualToString: @"iSight"] )
  922.     {
  923.         [o_capture_lbl setStringValue: _NS("iSight Capture Input")];
  924.         [o_capture_long_lbl setStringValue: _NS("This facility allows you to process your iSight's input signal.nnNo settings are available in this version, so you will be provided a 640px*480px raw video stream.nnLive Audio input is not supported.")];
  925.         [o_capture_lbl displayIfNeeded];
  926.         [o_capture_long_lbl displayIfNeeded];
  927.         
  928.         [self showCaptureView: o_capture_label_view];
  929.         [o_mrl setStringValue: @"qtcapture://"];
  930.     }
  931. }
  932. - (IBAction)screenStepperChanged:(id)sender
  933. {
  934.     [o_screen_fps_fld setFloatValue: [o_screen_fps_stp floatValue]];
  935.     [o_panel makeFirstResponder: o_screen_fps_fld];
  936.     [o_mrl setStringValue: @"screen://"];
  937. }
  938. - (void)screenFPSfieldChanged:(NSNotification *)o_notification
  939. {
  940.     [o_screen_fps_stp setFloatValue: [o_screen_fps_fld floatValue]];
  941.     if( [[o_screen_fps_fld stringValue] isEqualToString: @""] )
  942.         [o_screen_fps_fld setFloatValue: 1.0];
  943.     [o_mrl setStringValue: @"screen://"];
  944. }
  945. - (IBAction)eyetvSwitchChannel:(id)sender
  946. {
  947.     if( sender == o_eyetv_nextProgram_btn )
  948.     {
  949.         int chanNum = [[[VLCMain sharedInstance] eyeTVController] switchChannelUp: YES];
  950.         [o_eyetv_channels_pop selectItemWithTag:chanNum];
  951.         [o_mrl setStringValue: [NSString stringWithFormat:@"eyetv:// :eyetv-channel=%d", chanNum]];
  952.     }
  953.     else if( sender == o_eyetv_previousProgram_btn )
  954.     {
  955.         int chanNum = [[[VLCMain sharedInstance] eyeTVController] switchChannelUp: NO];
  956.         [o_eyetv_channels_pop selectItemWithTag:chanNum];
  957.         [o_mrl setStringValue: [NSString stringWithFormat:@"eyetv:// :eyetv-channel=%d", chanNum]];
  958.     }
  959.     else if( sender == o_eyetv_channels_pop )
  960.     {
  961.         int chanNum = [[sender selectedItem] tag];
  962.         [[[VLCMain sharedInstance] eyeTVController] selectChannel:chanNum];
  963.         [o_mrl setStringValue: [NSString stringWithFormat:@"eyetv:// :eyetv-channel=%d", chanNum]];
  964.     }
  965.     else
  966.         msg_Err( VLCIntf, "eyetvSwitchChannel sent by unknown object" );
  967. }
  968. - (IBAction)eyetvLaunch:(id)sender
  969. {
  970.     [[[VLCMain sharedInstance] eyeTVController] launchEyeTV];
  971. }
  972. - (IBAction)eyetvGetPlugin:(id)sender
  973. {
  974.     [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: @"http://www.videolan.org/vlc/eyetv"]];
  975. }
  976. - (void)eyetvChanged:(NSNotification *)o_notification
  977. {
  978.     if( [[o_notification name] isEqualToString: @"DeviceAdded"] )
  979.     {
  980.         msg_Dbg( VLCIntf, "eyetv device was added" );
  981.         [self showCaptureView: o_eyetv_running_view];
  982.         [self setupChannelInfo];
  983.     }
  984.     else if( [[o_notification name] isEqualToString: @"DeviceRemoved"] )
  985.     {
  986.         /* leave the channel selection like that,
  987.          * switch to our "no device" tab */
  988.         msg_Dbg( VLCIntf, "eyetv device was removed" );
  989.         setEyeTVUnconnected;
  990.     }
  991.     else if( [[o_notification name] isEqualToString: @"PluginQuit"] )
  992.     {
  993.         /* switch to the "launch eyetv" tab */
  994.         msg_Dbg( VLCIntf, "eyetv was terminated" );
  995.         [self showCaptureView: o_eyetv_notLaunched_view];
  996.     }
  997.     else if( [[o_notification name] isEqualToString: @"PluginInit"] )
  998.     {
  999.         /* we got no device yet */
  1000.         msg_Dbg( VLCIntf, "eyetv was launched, no device yet" );
  1001.         setEyeTVUnconnected;
  1002.     }
  1003.     else
  1004.         msg_Warn( VLCIntf, "unknown external notify '%s' received", [[o_notification name] UTF8String] );
  1005. }    
  1006. /* little helper method, since this code needs to be run by multiple objects */
  1007. - (void)setupChannelInfo
  1008. {
  1009.     /* set up channel selection */
  1010.     [o_eyetv_channels_pop removeAllItems];
  1011.     [o_eyetv_chn_bgbar setHidden: NO];
  1012.     [o_eyetv_chn_bgbar animate: self];
  1013.     [o_eyetv_chn_status_txt setStringValue: _NS("Retrieving Channel Info...")];
  1014.     [o_eyetv_chn_status_txt setHidden: NO];
  1015.  
  1016.     /* retrieve info */
  1017.     NSEnumerator *channels = [[[VLCMain sharedInstance] eyeTVController] allChannels];
  1018.     int x = -2;
  1019.     [[[o_eyetv_channels_pop menu] addItemWithTitle: _NS("Composite input")
  1020.                                                action: nil
  1021.                                         keyEquivalent: @""] setTag:x++];
  1022.     [[[o_eyetv_channels_pop menu] addItemWithTitle: _NS("S-Video input")
  1023.                                                action: nil
  1024.                                         keyEquivalent: @""] setTag:x++];
  1025.     if( channels ) 
  1026.     {
  1027.         NSString *channel;
  1028.         [[o_eyetv_channels_pop menu] addItem: [NSMenuItem separatorItem]];
  1029.         while( channel = [channels nextObject] )
  1030.         {
  1031.             /* we have to add items this way, because we accept duplicates
  1032.              * additionally, we save a bit of time */
  1033.             [[[o_eyetv_channels_pop menu] addItemWithTitle: channel
  1034.                                                    action: nil
  1035.                                             keyEquivalent: @""] setTag:++x];
  1036.         }
  1037.         /* make Tuner the default */
  1038.         [o_eyetv_channels_pop selectItemWithTag:[[[VLCMain sharedInstance] eyeTVController] currentChannel]];
  1039.     }
  1040.  
  1041.     /* clean up GUI */
  1042.     [o_eyetv_chn_bgbar setHidden: YES];
  1043.     [o_eyetv_chn_status_txt setHidden: YES];
  1044. }
  1045. - (IBAction)subsChanged:(id)sender
  1046. {
  1047.     if ([o_file_sub_ckbox state] == NSOnState)
  1048.     {
  1049.         [o_file_sub_btn_settings setEnabled:YES];
  1050.     }
  1051.     else
  1052.     {
  1053.         [o_file_sub_btn_settings setEnabled:NO];
  1054.     }
  1055. }
  1056. - (IBAction)subSettings:(id)sender
  1057. {
  1058.     [NSApp beginSheet: o_file_sub_sheet
  1059.         modalForWindow: [sender window]
  1060.         modalDelegate: self
  1061.         didEndSelector: NULL
  1062.         contextInfo: nil];
  1063. }
  1064. - (IBAction)subCloseSheet:(id)sender
  1065. {
  1066.     [o_file_sub_sheet orderOut:sender];
  1067.     [NSApp endSheet: o_file_sub_sheet];
  1068. }
  1069.     
  1070. - (IBAction)subFileBrowse:(id)sender
  1071. {
  1072.     NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
  1073.  
  1074.     [o_open_panel setAllowsMultipleSelection: NO];
  1075.     [o_open_panel setTitle: _NS("Open File")];
  1076.     [o_open_panel setPrompt: _NS("Open")];
  1077.     if( [o_open_panel runModalForDirectory: nil
  1078.             file: nil types: nil] == NSOKButton )
  1079.     {
  1080.         NSString *o_filename = [[o_open_panel filenames] objectAtIndex: 0];
  1081.         [o_file_sub_path setStringValue: o_filename];
  1082.     }
  1083. }
  1084. - (IBAction)subOverride:(id)sender
  1085. {
  1086.     BOOL b_state = [o_file_sub_override state];
  1087.     [o_file_sub_delay setEnabled: b_state];
  1088.     [o_file_sub_delay_stp setEnabled: b_state];
  1089.     [o_file_sub_fps setEnabled: b_state];
  1090.     [o_file_sub_fps_stp setEnabled: b_state];
  1091. }
  1092. - (IBAction)subDelayStepperChanged:(id)sender
  1093. {
  1094.     [o_file_sub_delay setIntValue: [o_file_sub_delay_stp intValue]];
  1095. }
  1096. - (IBAction)subFpsStepperChanged:(id)sender;
  1097. {
  1098.     [o_file_sub_fps setFloatValue: [o_file_sub_fps_stp floatValue]];
  1099. }
  1100. - (IBAction)panelCancel:(id)sender
  1101. {
  1102.     [NSApp stopModalWithCode: 0];
  1103. }
  1104. - (IBAction)panelOk:(id)sender
  1105. {
  1106.     if( [[o_mrl stringValue] length] )
  1107.     {
  1108.         [NSApp stopModalWithCode: 1];
  1109.     }
  1110.     else
  1111.     {
  1112.         NSBeep();
  1113.     }
  1114. }
  1115. @end
  1116. @implementation VLCOpenTextField
  1117. - (void)mouseDown:(NSEvent *)theEvent
  1118. {
  1119.     [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCOpenTextFieldWasClicked"
  1120.                                                         object: self];
  1121.     [super mouseDown: theEvent];
  1122. }
  1123. @end