diff --git a/Base.lproj/MainMenu.xib b/Base.lproj/MainMenu.xib index 162b36657..9181ad62f 100644 --- a/Base.lproj/MainMenu.xib +++ b/Base.lproj/MainMenu.xib @@ -32,7 +32,7 @@ - + @@ -130,11 +130,11 @@ - + - + @@ -169,11 +169,11 @@ - + - + @@ -210,11 +210,11 @@ - + - + @@ -250,11 +250,11 @@ - + - + @@ -289,11 +289,11 @@ - + - + @@ -329,11 +329,11 @@ - + - + @@ -366,7 +366,7 @@ - + @@ -402,11 +402,11 @@ - + - + @@ -438,11 +438,11 @@ - + - + @@ -478,11 +478,11 @@ - + - + @@ -518,11 +518,11 @@ - + - + @@ -1568,14 +1568,26 @@ CA + + + + + + + NSIsNotNil + + - + + + + NSIsNotNil @@ -1584,7 +1596,7 @@ CA - + @@ -1595,6 +1607,21 @@ CA + + + + + + + + + + + NSIsNotNil + + + + @@ -1611,8 +1638,32 @@ CA - - + + + + + + + + + NSIsNotNil + + + + + + + + + + + + + NSIsNotNil + + + + @@ -2135,6 +2186,21 @@ Gw + + + + + + + + + + + NSIsNotNil + + + + diff --git a/Playlist/PlaylistController.h b/Playlist/PlaylistController.h index 45837123e..5763c0eeb 100644 --- a/Playlist/PlaylistController.h +++ b/Playlist/PlaylistController.h @@ -84,6 +84,9 @@ typedef NS_ENUM(NSInteger, URLOrigin) { - (IBAction)removeDuplicates:(id _Nullable)sender; - (IBAction)removeDeadItems:(id _Nullable)sender; +- (IBAction)remove:(id _Nullable)sender; +- (IBAction)trash:(id _Nullable)sender; + - (IBAction)showEntryInFinder:(id _Nullable)sender; - (IBAction)clearFilterPredicate:(id _Nullable)sender; - (IBAction)clear:(id _Nullable)sender; diff --git a/Playlist/PlaylistController.m b/Playlist/PlaylistController.m index b87378a60..0f9870ea5 100644 --- a/Playlist/PlaylistController.m +++ b/Playlist/PlaylistController.m @@ -591,6 +591,11 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc [self rearrangeObjects]; } +- (void)untrashObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexes { + [self untrashObjects:objects atArrangedObjectIndexes:indexes]; + [self rearrangeObjects]; +} + - (void)insertObjectsUnsynced:(NSArray *)objects atArrangedObjectIndexes:(NSIndexSet *)indexes { [super insertObjects:objects atArrangedObjectIndexes:indexes]; @@ -619,10 +624,41 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc if([self shuffle] != ShuffleOff) [self resetShuffleList]; } +- (void)untrashObjects:(NSArray *)objects atArrangedObjectIndexes:(NSIndexSet *)indexes { + [[[self undoManager] prepareWithInvocationTarget:self] + trashObjectsAtIndexes:[self disarrangeIndexes:indexes]]; + NSString *actionName = + [NSString stringWithFormat:@"Restoring %lu entries from trash", (unsigned long)[objects count]]; + [[self undoManager] setActionName:actionName]; + + for(PlaylistEntry *pe in objects) { + if(pe.deleted && pe.trashURL) { + NSError *error = nil; + [[NSFileManager defaultManager] moveItemAtURL:pe.trashURL toURL:pe.URL error:&error]; + } + pe.deleted = NO; + pe.trashURL = nil; + } + + [[SQLiteStore sharedStore] playlistInsertTracks:objects + atObjectIndexes:indexes + progressCall:^(double progress) { + [self setProgressBarStatus:progress]; + }]; + + [super insertObjects:objects atArrangedObjectIndexes:indexes]; + + if([self shuffle] != ShuffleOff) [self resetShuffleList]; +} + - (void)removeObjectsAtIndexes:(NSIndexSet *)indexes { [self removeObjectsAtArrangedObjectIndexes:[self rearrangeIndexes:indexes]]; } +- (void)trashObjectsAtIndexes:(NSIndexSet *)indexes { + [self trashObjectsAtArrangedObjectIndexes:[self rearrangeIndexes:indexes]]; +} + - (void)removeObjectsAtArrangedObjectIndexes:(NSIndexSet *)indexes { NSArray *objects = [[self arrangedObjects] objectsAtIndexes:indexes]; [[[self undoManager] prepareWithInvocationTarget:self] @@ -679,6 +715,49 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc [playbackController playlistDidChange:self]; } +- (void)trashObjectsAtArrangedObjectIndexes:(NSIndexSet *)indexes { + NSArray *objects = [[self arrangedObjects] objectsAtIndexes:indexes]; + [[[self undoManager] prepareWithInvocationTarget:self] + untrashObjects:[self disarrangeObjects:objects] + atIndexes:[self disarrangeIndexes:indexes]]; + NSString *actionName = + [NSString stringWithFormat:@"Trashing %lu entries", (unsigned long)[indexes count]]; + [[self undoManager] setActionName:actionName]; + + DLog(@"Trashing indexes: %@", indexes); + DLog(@"Current index: %li", currentEntry.index); + + NSMutableIndexSet *unarrangedIndexes = [[NSMutableIndexSet alloc] init]; + for(PlaylistEntry *pe in objects) { + [unarrangedIndexes addIndex:[pe index]]; + pe.deleted = YES; + } + + if([indexes containsIndex:currentEntry.index]) { + [self updateNextAfterDeleted:currentEntry withDeleteIndexes:indexes]; + [playbackController playEntry:nextEntryAfterDeleted]; + nextEntryAfterDeleted = nil; + } + + [[SQLiteStore sharedStore] playlistRemoveTracksAtIndexes:unarrangedIndexes + progressCall:^(double progress) { + [self setProgressBarStatus:progress]; + }]; + + [super removeObjectsAtArrangedObjectIndexes:indexes]; + + if([self shuffle] != ShuffleOff) [self resetShuffleList]; + + [playbackController playlistDidChange:self]; + + for(PlaylistEntry *pe in objects) { + NSURL *removed = nil; + NSError *error = nil; + [[NSFileManager defaultManager] trashItemAtURL:pe.URL resultingItemURL:&removed error:&error]; + pe.trashURL = removed; + } +} + - (void)setSortDescriptors:(NSArray *)sortDescriptors { DLog(@"Current: %@, setting: %@", [self sortDescriptors], sortDescriptors); @@ -755,7 +834,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc return [[self arrangedObjects] objectAtIndex:i]; } -- (void)remove:(id)sender { +- (IBAction)remove:(id)sender { // It's a kind of magic. // Plain old NSArrayController's remove: isn't working properly for some reason. // The method is definitely called but (overridden) removeObjectsAtArrangedObjectIndexes: isn't @@ -769,6 +848,16 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc } } +- (IBAction)trash:(id)sender { + // Someone asked for this, so they're getting it. + // Trash the selection, and advance playback to the next untrashed file if necessary. + + NSIndexSet *selected = [self selectionIndexes]; + if([selected count] > 0) { + [self trashObjectsAtArrangedObjectIndexes:selected]; + } +} + - (IBAction)removeDuplicates:(id)sender { NSMutableArray *originals = [[NSMutableArray alloc] init]; NSMutableArray *duplicates = [[NSMutableArray alloc] init]; diff --git a/Playlist/PlaylistEntry.h b/Playlist/PlaylistEntry.h index 93e098d38..6e90c31b6 100644 --- a/Playlist/PlaylistEntry.h +++ b/Playlist/PlaylistEntry.h @@ -26,6 +26,7 @@ NSString *errorMessage; NSURL *URL; + NSURL *trashURL; NSString *artist; NSString *albumartist; @@ -121,6 +122,7 @@ @property(retain) NSString *errorMessage; @property(retain) NSURL *URL; +@property(retain) NSURL *trashURL; @property(retain) NSString *artist; @property(retain) NSString *albumartist;