📄 playlist.m
字号:
/***************************************************************************** * playlist.m: MacOS X interface module ****************************************************************************** Copyright (C) 2002-2006 the VideoLAN team * $Id: playlist.m 17568 2006-11-09 13:31:33Z fkuehne $ * * Authors: Jon Lech Johansen <jon-vl@nanocrew.net> * Derk-Jan Hartman <hartman at videola/n dot org> * Benjamin Pracht <bigben at videolab dot org> * Felix K焗ne <fkuehne at videolan dot org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//* TODO * add 'icons' for different types of nodes? (http://www.cocoadev.com/index.pl?IconAndTextInTableCell) * reimplement enable/disable item * create a new 'tool' button (see the gear button in the Finder window) for 'actions' (adding service discovery, other views, new node/playlist, save node/playlist) stuff like that *//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h> /* malloc(), free() */#include <sys/param.h> /* for MAXPATHLEN */#include <string.h>#include <math.h>#include <sys/mount.h>#include <vlc_keys.h>#import "intf.h"#import "wizard.h"#import "bookmarks.h"#import "playlistinfo.h"#import "playlist.h"#import "controls.h"#import "vlc_osd.h"#import "misc.h"/***************************************************************************** * VLCPlaylistView implementation *****************************************************************************/@implementation VLCPlaylistView- (NSMenu *)menuForEvent:(NSEvent *)o_event{ return( [[self delegate] menuForEvent: o_event] );}- (void)keyDown:(NSEvent *)o_event{ unichar key = 0; if( [[o_event characters] length] ) { key = [[o_event characters] characterAtIndex: 0]; } switch( key ) { case NSDeleteCharacter: case NSDeleteFunctionKey: case NSDeleteCharFunctionKey: case NSBackspaceCharacter: [[self delegate] deleteItem:self]; break; case NSEnterCharacter: case NSCarriageReturnCharacter: [(VLCPlaylist *)[[VLCMain sharedInstance] getPlaylist] playItem:self]; break; default: [super keyDown: o_event]; break; }}@end/***************************************************************************** * VLCPlaylistCommon implementation * * This class the superclass of the VLCPlaylist and VLCPlaylistWizard. * It contains the common methods and elements of these 2 entities. *****************************************************************************/@implementation VLCPlaylistCommon- (id)init{ self = [super init]; if ( self != nil ) { o_outline_dict = [[NSMutableDictionary alloc] init]; } return self;}- (void)awakeFromNib{ playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); i_current_view = VIEW_CATEGORY; playlist_ViewUpdate( p_playlist, i_current_view ); [o_outline_view setTarget: self]; [o_outline_view setDelegate: self]; [o_outline_view setDataSource: self]; vlc_object_release( p_playlist ); [self initStrings];}- (void)initStrings{ [[o_tc_name headerCell] setStringValue:_NS("Name")]; [[o_tc_author headerCell] setStringValue:_NS("Author")]; [[o_tc_duration headerCell] setStringValue:_NS("Duration")];}- (NSOutlineView *)outlineView{ return o_outline_view;}- (playlist_item_t *)selectedPlaylistItem{ return [[o_outline_view itemAtRow: [o_outline_view selectedRow]] pointerValue];}@end@implementation VLCPlaylistCommon (NSOutlineViewDataSource)/* return the number of children for Obj-C pointer item */ /* DONE */- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item{ int i_return = 0; playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( p_playlist == NULL ) return 0; if( outlineView != o_outline_view ) { vlc_object_release( p_playlist ); return 0; } if( item == nil ) { /* root object */ playlist_view_t *p_view; p_view = playlist_ViewFind( p_playlist, i_current_view ); if( p_view && p_view->p_root ) { i_return = p_view->p_root->i_children; if( i_current_view == VIEW_CATEGORY ) { i_return--; /* remove the GENERAL item from the list */ i_return += p_playlist->p_general->i_children; /* add the items of the general node */ } } } else { playlist_item_t *p_item = (playlist_item_t *)[item pointerValue]; if( p_item ) i_return = p_item->i_children; } vlc_object_release( p_playlist ); if( i_return <= 0 ) i_return = 0; return i_return;}/* return the child at index for the Obj-C pointer item */ /* DONE */- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item{ playlist_item_t *p_return = NULL; playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); NSValue *o_value; if( p_playlist == NULL ) return nil; if( item == nil ) { /* root object */ playlist_view_t *p_view; p_view = playlist_ViewFind( p_playlist, i_current_view ); if( p_view && p_view->p_root ) p_return = p_view->p_root->pp_children[index]; if( i_current_view == VIEW_CATEGORY ) { if( p_playlist->p_general->i_children && index >= 0 && index < p_playlist->p_general->i_children ) { p_return = p_playlist->p_general->pp_children[index]; } else if( p_view && p_view->p_root && index >= 0 && index - p_playlist->p_general->i_children < p_view->p_root->i_children ) { p_return = p_view->p_root->pp_children[index - p_playlist->p_general->i_children + 1]; } } } else { playlist_item_t *p_item = (playlist_item_t *)[item pointerValue]; if( p_item && index < p_item->i_children && index >= 0 ) p_return = p_item->pp_children[index]; } vlc_object_release( p_playlist ); o_value = [o_outline_dict objectForKey:[NSString stringWithFormat: @"%p", p_return]]; if( o_value == nil ) { o_value = [[NSValue valueWithPointer: p_return] retain]; } return o_value;}/* is the item expandable */- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item{ int i_return = 0; playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( p_playlist == NULL ) return NO; if( item == nil ) { /* root object */ playlist_view_t *p_view; p_view = playlist_ViewFind( p_playlist, i_current_view ); if( p_view && p_view->p_root ) i_return = p_view->p_root->i_children; if( i_current_view == VIEW_CATEGORY ) { i_return--; i_return += p_playlist->p_general->i_children; } } else { playlist_item_t *p_item = (playlist_item_t *)[item pointerValue]; if( p_item ) i_return = p_item->i_children; } vlc_object_release( p_playlist ); if( i_return <= 0 ) return NO; else return YES;}/* retrieve the string values for the cells */- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)o_tc byItem:(id)item{ id o_value = nil; intf_thread_t *p_intf = VLCIntf; playlist_t *p_playlist; playlist_item_t *p_item; if( item == nil || ![item isKindOfClass: [NSValue class]] ) return( @"error" ); p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( p_playlist == NULL ) { return( @"error" ); } p_item = (playlist_item_t *)[item pointerValue]; if( p_item == NULL ) { vlc_object_release( p_playlist ); return( @"error"); }//NSLog( @"values for %p", p_item ); if( [[o_tc identifier] isEqualToString:@"1"] ) { /* sanity check to prevent the NSString class from crashing */ if( p_item->input.psz_name != NULL ) { o_value = [NSString stringWithUTF8String: p_item->input.psz_name]; if( o_value == NULL ) o_value = [NSString stringWithCString: p_item->input.psz_name]; } } else if( [[o_tc identifier] isEqualToString:@"2"] ) { char *psz_temp; psz_temp = vlc_input_item_GetInfo( &p_item->input ,_("Meta-information"),_("Artist") ); if( psz_temp == NULL ) o_value = @""; else { o_value = [NSString stringWithUTF8String: psz_temp]; if( o_value == NULL ) { o_value = [NSString stringWithCString: psz_temp]; } free( psz_temp ); } } else if( [[o_tc identifier] isEqualToString:@"3"] ) { char psz_duration[MSTRTIME_MAX_SIZE]; mtime_t dur = p_item->input.i_duration; if( dur != -1 ) { secstotimestr( psz_duration, dur/1000000 ); o_value = [NSString stringWithUTF8String: psz_duration]; } else { o_value = @"-:--:--"; } } vlc_object_release( p_playlist ); return( o_value );}@end/***************************************************************************** * VLCPlaylistWizard implementation *****************************************************************************/@implementation VLCPlaylistWizard- (IBAction)reloadOutlineView{ /* Only reload the outlineview if the wizard window is open since this can be quite long on big playlists */ if( [[o_outline_view window] isVisible] ) { [o_outline_view reloadData]; }}@end/****************************************************************************** extension to NSOutlineView's interface to fix compilation warnings* and let us access these 2 functions properly* this uses a private Apple-API, but works finely on all current OSX releases* keep checking for compatiblity with future releases though*****************************************************************************/@interface NSOutlineView (UndocumentedSortImages)+ (NSImage *)_defaultTableHeaderSortImage;+ (NSImage *)_defaultTableHeaderReverseSortImage;@end/***************************************************************************** * VLCPlaylist implementation *****************************************************************************/@implementation VLCPlaylist- (id)init{ self = [super init]; if ( self != nil ) { o_nodes_array = [[NSMutableArray alloc] init]; o_items_array = [[NSMutableArray alloc] init]; } return self;}- (void)awakeFromNib{ playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); vlc_list_t *p_list = vlc_list_find( p_playlist, VLC_OBJECT_MODULE, FIND_ANYWHERE ); int i_index; [super awakeFromNib]; [o_outline_view setDoubleAction: @selector(playItem:)]; [o_outline_view registerForDraggedTypes: [NSArray arrayWithObjects: NSFilenamesPboardType, @"VLCPlaylistItemPboardType", nil]]; [o_outline_view setIntercellSpacing: NSMakeSize (0.0, 1.0)]; /* this uses private Apple API which works fine on all releases incl. 10.4, * but keep checking in the future! * These methods were added artificially to NSOutlineView's public interface above */ o_ascendingSortingImage = [[NSOutlineView class] _defaultTableHeaderSortImage]; o_descendingSortingImage = [[NSOutlineView class] _defaultTableHeaderReverseSortImage]; o_tc_sortColumn = nil; for( i_index = 0; i_index < p_list->i_count; i_index++ ) { vlc_bool_t b_enabled; char *objectname; NSMenuItem *o_lmi; module_t *p_parser = (module_t *)p_list->p_values[i_index].p_object ; if( !strcmp( p_parser->psz_capability, "services_discovery" ) ) { /* Check for submodules */ int i = -1; while( p_parser->pp_shortcuts[++i] != NULL ); i--; /* Check whether to enable these menuitems */ objectname = i>=0 ? p_parser->pp_shortcuts[i] : p_parser->psz_object_name; b_enabled = playlist_IsServicesDiscoveryLoaded( p_playlist, objectname ); /* Create the menu entries used in the playlist menu */ o_lmi = [[o_mi_services submenu] addItemWithTitle: [NSString stringWithUTF8String: p_parser->psz_longname ? p_parser->psz_longname : ( p_parser->psz_shortname ? p_parser->psz_shortname: objectname)] action: @selector(servicesChange:) keyEquivalent: @""]; [o_lmi setTarget: self]; [o_lmi setRepresentedObject: [NSString stringWithCString: objectname]]; if( b_enabled ) [o_lmi setState: NSOnState];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -