diff --git a/Playlist/PlaylistController.h b/Playlist/PlaylistController.h index 8a508a37f..45837123e 100644 --- a/Playlist/PlaylistController.h +++ b/Playlist/PlaylistController.h @@ -49,6 +49,8 @@ typedef NS_ENUM(NSInteger, URLOrigin) { PlaylistEntry *currentEntry; + PlaylistEntry *nextEntryAfterDeleted; + NSUndoManager *undoManager; } diff --git a/Playlist/PlaylistController.m b/Playlist/PlaylistController.m index 5296aa7ec..6b48b3fc2 100644 --- a/Playlist/PlaylistController.m +++ b/Playlist/PlaylistController.m @@ -362,6 +362,31 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc if(currentEntry != nil) [self.tableView scrollRowToVisible:currentEntry.index]; } +- (void)updateNextAfterDeleted:(PlaylistEntry *)lastEntry withDeleteIndexes:(NSIndexSet *)indexes { + __block PlaylistEntry *pe = nil; + NSArray *allObjects = [self arrangedObjects]; + [indexes enumerateRangesUsingBlock:^(NSRange range, BOOL *_Nonnull stop) { + if(range.location <= lastEntry.index && + range.location + range.length > lastEntry.index) { + NSUInteger index = range.location + range.length; + if(index < [allObjects count]) + pe = [allObjects objectAtIndex:index]; + else + pe = nil; + } else if(pe && range.location <= [pe index] && + range.location + range.length > [pe index]) { + NSUInteger index = range.location + range.length; + if(index < [allObjects count]) + pe = [allObjects objectAtIndex:index]; + else + pe = nil; + } else if(pe && range.location > [pe index]) { + *stop = YES; + } + }]; + nextEntryAfterDeleted = pe; +} + - (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn { if([self shuffle] != ShuffleOff) [self resetShuffleList]; } @@ -577,6 +602,10 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc [NSString stringWithFormat:@"Adding %lu entries", (unsigned long)[objects count]]; [[self undoManager] setActionName:actionName]; + for(PlaylistEntry *pe in objects) { + pe.deleted = NO; + } + [[SQLiteStore sharedStore] playlistInsertTracks:objects atObjectIndexes:indexes progressCall:^(double progress) { @@ -607,11 +636,14 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc NSMutableIndexSet *unarrangedIndexes = [[NSMutableIndexSet alloc] init]; for(PlaylistEntry *pe in objects) { [unarrangedIndexes addIndex:[pe index]]; + pe.deleted = YES; } if([indexes containsIndex:currentEntry.index]) { - // Safety check. The player doesn't like committing actions on a removed track - [playbackController stop:nil]; + [self updateNextAfterDeleted:currentEntry withDeleteIndexes:indexes]; + } else if(nextEntryAfterDeleted && + [indexes containsIndex:nextEntryAfterDeleted.index]) { + [self updateNextAfterDeleted:nextEntryAfterDeleted withDeleteIndexes:indexes]; } if(currentEntry.index >= 0 && [unarrangedIndexes containsIndex:currentEntry.index]) { @@ -828,9 +860,14 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc return [self shuffledEntryAtIndex:(pe.shuffleIndex + 1)]; } else { NSInteger i; - if(pe.index < 0) // Was a current entry, now removed. + + if(pe.deleted) // Was a current entry, now removed. { - i = -pe.index - 1; + if(nextEntryAfterDeleted) + i = nextEntryAfterDeleted.index; + else + i = 0; + nextEntryAfterDeleted = nil; } else { i = pe.index + 1; } @@ -1038,7 +1075,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc NSMutableIndexSet *refreshSet = [[NSMutableIndexSet alloc] init]; - if(currentEntry != nil) [refreshSet addIndex:currentEntry.index]; + if(currentEntry != nil && !currentEntry.deleted) [refreshSet addIndex:currentEntry.index]; if(pe != nil) [refreshSet addIndex:pe.index]; // Refresh entire row to refresh tooltips diff --git a/Playlist/PlaylistEntry.h b/Playlist/PlaylistEntry.h index 8e019c907..93e098d38 100644 --- a/Playlist/PlaylistEntry.h +++ b/Playlist/PlaylistEntry.h @@ -66,6 +66,8 @@ BOOL seekable; BOOL metadataLoaded; + + BOOL deleted; } + (NSSet *)keyPathsForValuesAffectingDisplay; @@ -167,6 +169,8 @@ @property BOOL metadataLoaded; +@property BOOL deleted; + - (void)setMetadata:(NSDictionary *)metadata; @end diff --git a/Playlist/PlaylistEntry.m b/Playlist/PlaylistEntry.m index 0685168ab..317da72bb 100644 --- a/Playlist/PlaylistEntry.m +++ b/Playlist/PlaylistEntry.m @@ -66,6 +66,8 @@ @synthesize metadataLoaded; +@synthesize deleted; + // The following read-only keys depend on the values of other properties + (NSSet *)keyPathsForValuesAffectingDisplay { @@ -139,6 +141,7 @@ self.replayGainTrackGain = 0; self.replayGainTrackPeak = 0; self.volume = 1; + self.deleted = NO; } return self; } @@ -507,6 +510,8 @@ pe->seekable = seekable; pe->metadataLoaded = metadataLoaded; + + pe->deleted = deleted; } return pe;