X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fmacosx%2Fplaylist.m;h=9f800961a19b265a5c4d33beefe86a49787ec010;hb=6ee1e193fd896ab9a4729fde14f009d9ce629815;hp=c3aba6cb691781a84a9f775c6ac8e462d43ba30f;hpb=799b2826ee321796c8c4695c5a7b7489ed5da851;p=vlc diff --git a/modules/gui/macosx/playlist.m b/modules/gui/macosx/playlist.m index c3aba6cb69..9f800961a1 100644 --- a/modules/gui/macosx/playlist.m +++ b/modules/gui/macosx/playlist.m @@ -50,10 +50,10 @@ #import "controls.h" #import "vlc_osd.h" #import "misc.h" -#import +#import /***************************************************************************** - * VLCPlaylistView implementation + * VLCPlaylistView implementation *****************************************************************************/ @implementation VLCPlaylistView @@ -172,7 +172,7 @@ if( i_return <= 0 ) i_return = 0; -NSLog( @"%d children for %s", i_return, p_item->p_input->psz_name ); + return i_return; } @@ -190,17 +190,15 @@ NSLog( @"%d children for %s", i_return, p_item->p_input->psz_name ); } else { - p_item = (playlist_item_t *)[item pointerValue]; + 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 0 - NSLog( @"%s", p_return->p_input->psz_name); - #endif + if( o_value == nil ) { o_value = [[NSValue valueWithPointer: p_return] retain]; @@ -231,59 +229,92 @@ NSLog( @"%d children for %s", i_return, p_item->p_input->psz_name ); } vlc_object_release( p_playlist ); -NSLog( @"expandable" ); - if( i_return <= 0 ) - return NO; - else - return YES; + return (i_return > 0); } /* 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_item_t *p_item; - - if( item == nil || ![item isKindOfClass: [NSValue class]] ) return( @"error" ); - - p_item = (playlist_item_t *)[item pointerValue]; - if( p_item == NULL ) + + /* For error handling */ + static BOOL attempted_reload = NO; + + if( item == nil || ![item isKindOfClass: [NSValue class]] ) { - return( @"error"); + /* Attempt to fix the error by asking for a data redisplay + * This might cause infinite loop, so add a small check */ + if( !attempted_reload ) + { + attempted_reload = YES; + [outlineView reloadData]; + } + return @"error" ; } -//NSLog( @"values for %p", p_item ); - - if( [[o_tc identifier] isEqualToString:@"1"] ) + + p_item = (playlist_item_t *)[item pointerValue]; + if( !p_item || !p_item->p_input ) { - o_value = [NSString stringWithUTF8String: - p_item->p_input->psz_name]; - if( o_value == NULL ) - o_value = [NSString stringWithCString: - p_item->p_input->psz_name]; + /* Attempt to fix the error by asking for a data redisplay + * This might cause infinite loop, so add a small check */ + if( !attempted_reload ) + { + attempted_reload = YES; + [outlineView reloadData]; + } + return @"error"; } - else if( [[o_tc identifier] isEqualToString:@"2"] && p_item->p_input->p_meta && - p_item->p_input->p_meta->psz_artist && *p_item->p_input->p_meta->psz_artist ) + + attempted_reload = NO; + + if( [[o_tc identifier] isEqualToString:@"1"] ) { - o_value = [NSString stringWithUTF8String: - p_item->p_input->p_meta->psz_artist]; - if( o_value == NULL ) - o_value = [NSString stringWithCString: - p_item->p_input->p_meta->psz_artist]; + /* sanity check to prevent the NSString class from crashing */ + char *psz_title = input_item_GetTitle( p_item->p_input ); + if( !EMPTY_STR( psz_title ) ) + { + o_value = [NSString stringWithUTF8String: psz_title]; + if( o_value == NULL ) + o_value = [NSString stringWithCString: psz_title]; + } + else + { + char *psz_name = input_item_GetName( p_item->p_input ); + if( psz_name != NULL ) + { + o_value = [NSString stringWithUTF8String: psz_name]; + if( o_value == NULL ) + o_value = [NSString stringWithCString: psz_name]; + } + free( psz_name ); + } + free( psz_title ); } - else if( [[o_tc identifier] isEqualToString:@"3"] ) + else { - char psz_duration[MSTRTIME_MAX_SIZE]; - mtime_t dur = p_item->p_input->i_duration; - if( dur != -1 ) + char *psz_artist = input_item_GetArtist( p_item->p_input ); + if( [[o_tc identifier] isEqualToString:@"2"] && !EMPTY_STR( psz_artist ) ) { - secstotimestr( psz_duration, dur/1000000 ); - o_value = [NSString stringWithUTF8String: psz_duration]; + o_value = [NSString stringWithUTF8String: psz_artist]; + if( o_value == NULL ) + o_value = [NSString stringWithCString: psz_artist]; } - else + else if( [[o_tc identifier] isEqualToString:@"3"] ) { - o_value = @"-:--:--"; + char psz_duration[MSTRTIME_MAX_SIZE]; + mtime_t dur = input_item_GetDuration( p_item->p_input ); + if( dur != -1 ) + { + secstotimestr( psz_duration, dur/1000000 ); + o_value = [NSString stringWithUTF8String: psz_duration]; + } + else + { + o_value = @"-:--:--"; + } } + free( psz_artist ); } return( o_value ); @@ -354,7 +385,7 @@ NSLog( @"expandable" ); @"VLCPlaylistItemPboardType", nil]]; [o_outline_view setIntercellSpacing: NSMakeSize (0.0, 1.0)]; - /* this uses private Apple API which works fine until 10.4, + /* this uses private Apple API which works fine until 10.4, * but keep checking in the future! * These methods are being added artificially to NSOutlineView's interface above */ o_ascendingSortingImage = [[NSOutlineView class] _defaultTableHeaderSortImage]; @@ -376,9 +407,9 @@ NSLog( @"expandable" ); 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; + objectname = i>=0 ? (char *)p_parser->pp_shortcuts[i] : (char *)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: @@ -390,7 +421,7 @@ NSLog( @"expandable" ); [o_lmi setTarget: self]; [o_lmi setRepresentedObject: [NSString stringWithCString: objectname]]; if( b_enabled ) [o_lmi setState: NSOnState]; - + /* Create the menu entries for the main menu */ o_lmi = [[o_mm_mi_services submenu] addItemWithTitle: [NSString stringWithUTF8String: @@ -464,22 +495,18 @@ NSLog( @"expandable" ); playlist_t *p_playlist = pl_Yield( VLCIntf ); - /** \todo fix i_size use */ - if( p_playlist->items.i_size >= 2 ) + if( playlist_CurrentSize( p_playlist ) >= 2 ) { [o_status_field setStringValue: [NSString stringWithFormat: - _NS("%i items in the playlist"), p_playlist->items.i_size]]; + _NS("%i items in the playlist"), + playlist_CurrentSize( p_playlist )]]; } else { if( playlist_IsEmpty( p_playlist ) ) - { [o_status_field setStringValue: _NS("No items in the playlist")]; - } else - { [o_status_field setStringValue: _NS("1 item in the playlist")]; - } } vlc_object_release( p_playlist ); } @@ -598,10 +625,10 @@ NSLog( @"expandable" ); /* Since outlineView: willDisplayCell:... may call this function with p_items that don't exist anymore, first check if the item is still in the playlist. Any cleaner solution welcomed. */ - for( i = 0; i < p_playlist->i_all_size; i++ ) + for( i = 0; i < p_playlist->all_items.i_size; i++ ) { - if( p_playlist->pp_all_items[i] == p_item ) break; - else if ( i == p_playlist->i_all_size - 1 ) + if( ARRAY_VAL( p_playlist->all_items, i) == p_item ) break; + else if ( i == p_playlist->all_items.i_size - 1 ) { vlc_object_release( p_playlist ); vlc_mutex_unlock( &p_playlist->object_lock ); @@ -689,8 +716,8 @@ NSLog( @"expandable" ); { o_real_filename = o_filename; } - playlist_Export( p_playlist, - [o_real_filename fileSystemRepresentation], + playlist_Export( p_playlist, + [o_real_filename fileSystemRepresentation], p_playlist->p_local_category, "export-xspf" ); } else @@ -709,7 +736,7 @@ NSLog( @"expandable" ); { o_real_filename = o_filename; } - playlist_Export( p_playlist, + playlist_Export( p_playlist, [o_real_filename fileSystemRepresentation], p_playlist->p_local_category, "export-m3u" ); } @@ -747,7 +774,7 @@ NSLog( @"expandable" ); p_item = NULL; } } - playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, p_node, p_item ); + playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, p_node, p_item ); } vlc_object_release( p_playlist ); } @@ -759,7 +786,7 @@ NSLog( @"expandable" ); NSMutableArray *o_to_preparse; intf_thread_t * p_intf = VLCIntf; playlist_t * p_playlist = pl_Yield( p_intf ); - + o_to_preparse = [NSMutableArray arrayWithArray:[[o_outline_view selectedRowEnumerator] allObjects]]; i_count = [o_to_preparse count]; @@ -796,13 +823,13 @@ NSLog( @"expandable" ); NSMenuItem *o_mi = (NSMenuItem *)sender; NSString *o_string = [o_mi representedObject]; playlist_t * p_playlist = pl_Yield( VLCIntf ); - if( !playlist_IsServicesDiscoveryLoaded( p_playlist, [o_string cString] ) ) - playlist_ServicesDiscoveryAdd( p_playlist, [o_string cString] ); + if( !playlist_IsServicesDiscoveryLoaded( p_playlist, [o_string UTF8String] ) ) + playlist_ServicesDiscoveryAdd( p_playlist, [o_string UTF8String] ); else - playlist_ServicesDiscoveryRemove( p_playlist, [o_string cString] ); + playlist_ServicesDiscoveryRemove( p_playlist, [o_string UTF8String] ); [o_mi setState: playlist_IsServicesDiscoveryLoaded( p_playlist, - [o_string cString] ) ? YES : NO]; + [o_string UTF8String] ) ? YES : NO]; vlc_object_release( p_playlist ); [self playlistUpdated]; @@ -855,7 +882,7 @@ NSLog( @"expandable" ); } else { - playlist_LockDelete( p_playlist, p_item->i_id ); + playlist_DeleteFromInput( p_playlist, p_item->p_input->i_id, VLC_FALSE ); } } [self playlistUpdated]; @@ -1011,20 +1038,21 @@ NSLog( @"expandable" ); } /* Add the item */ - playlist_PlaylistAddInput( p_playlist, p_input, PLAYLIST_INSERT, - i_position == -1 ? PLAYLIST_END : i_position + i_item ); + playlist_AddInput( p_playlist, p_input, PLAYLIST_INSERT, + i_position == -1 ? PLAYLIST_END : i_position + i_item, VLC_TRUE, + VLC_FALSE ); if( i_item == 0 && !b_enqueue ) { playlist_item_t *p_item; - p_item = playlist_ItemGetByInput( p_playlist, p_input ); - playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, NULL, p_item ); + p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE ); + playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, p_item ); } else { playlist_item_t *p_item; - p_item = playlist_ItemGetByInput( p_playlist, p_input ); - playlist_Control( p_playlist, PLAYLIST_PREPARSE, p_item ); + p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE ); + playlist_Control( p_playlist, PLAYLIST_SKIP, VLC_TRUE, p_item ); } } [self playlistUpdated]; @@ -1053,20 +1081,20 @@ NSLog( @"expandable" ); playlist_NodeAddInput( p_playlist, p_input, p_node, PLAYLIST_INSERT, i_position == -1 ? - PLAYLIST_END : i_position + i_item ); + PLAYLIST_END : i_position + i_item, VLC_FALSE ); if( i_item == 0 && !b_enqueue ) { playlist_item_t *p_item; - p_item = playlist_ItemGetByInput( p_playlist, p_input ); - playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, NULL, p_item ); + p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE ); + playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, p_item ); } else { playlist_item_t *p_item; - p_item = playlist_ItemGetByInput( p_playlist, p_input ); - playlist_Control( p_playlist, PLAYLIST_PREPARSE, p_item ); + p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE ); + playlist_Control( p_playlist, PLAYLIST_SKIP, VLC_TRUE, p_item ); } } [self playlistUpdated]; @@ -1324,7 +1352,7 @@ NSLog( @"expandable" ); /* we have to create a new thread here because otherwise we would block the * interface since the interaction-stuff and this code would run in the same * thread */ - [NSThread detachNewThreadSelector: @selector(addNodeThreadedly) + [NSThread detachNewThreadSelector: @selector(addNodeThreadedly) toTarget: self withObject:nil]; [self playlistUpdated]; } @@ -1340,17 +1368,21 @@ NSLog( @"expandable" ); int ret_v; char *psz_name = NULL; playlist_item_t * p_item; - ret_v = intf_UserStringInput( p_playlist, _("New Node"), + ret_v = intf_UserStringInput( p_playlist, _("New Node"), _("Please enter a name for the new node."), &psz_name ); + if( psz_name != NULL && psz_name != "" ) - p_item = playlist_NodeCreate( p_playlist, psz_name, - p_playlist->p_local_category ); - else - p_item = playlist_NodeCreate( p_playlist, _("Empty Folder"), - p_playlist->p_local_category ); + p_item = playlist_NodeCreate( p_playlist, psz_name, + p_playlist->p_local_category, 0 ); + else if(! config_GetInt( p_playlist, "interact" ) ) + { + /* in case that the interaction is disabled, just give it a bogus name */ + p_item = playlist_NodeCreate( p_playlist, _("Empty Folder"), + p_playlist->p_local_category, 0 ); + } if(! p_item ) - msg_Warn( VLCIntf, "node creation failed" ); + msg_Warn( VLCIntf, "node creation failed or cancelled by user" ); vlc_object_release( p_playlist ); [ourPool release]; @@ -1365,13 +1397,11 @@ NSLog( @"expandable" ); id o_value = [super outlineView: outlineView child: index ofItem: item]; playlist_t *p_playlist = pl_Yield( VLCIntf ); - /* FIXME: playlist->i_size doesn't provide the correct number of items anymore - * check the playlist API for the fixed function, once zorglub implemented it -- fpk, 9/17/06 */ - /** \todo fix i_size use */ - if( p_playlist->items.i_size >= 2 ) + if( playlist_CurrentSize( p_playlist ) >= 2 ) { [o_status_field setStringValue: [NSString stringWithFormat: - _NS("%i items in the playlist"), p_playlist->items.i_size]]; + _NS("%i items in the playlist"), + playlist_CurrentSize( p_playlist )]]; } else { @@ -1457,6 +1487,13 @@ NSLog( @"expandable" ); } } + /* Don't allow on drop on playlist root element's child */ + if( !item && index != NSOutlineViewDropOnItemIndex) + { + vlc_object_release( p_playlist ); + return NSDragOperationNone; + } + /* We refuse to drop an item in anything else than a child of the General Node. We still accept items that would be root nodes of the outlineview however, to allow drop in an empty playlist. */