diff --git a/Cog.xcodeproj/project.pbxproj b/Cog.xcodeproj/project.pbxproj index 05f60a941..7f44fbaf6 100644 --- a/Cog.xcodeproj/project.pbxproj +++ b/Cog.xcodeproj/project.pbxproj @@ -130,7 +130,6 @@ 8EFFCD630AA093AF00C458A5 /* FileNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFFCD470AA093AF00C458A5 /* FileNode.m */; }; 8EFFCD650AA093AF00C458A5 /* FileOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFFCD490AA093AF00C458A5 /* FileOutlineView.m */; }; 8EFFCD6F0AA093AF00C458A5 /* PathNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFFCD530AA093AF00C458A5 /* PathNode.m */; }; - B01946070D5F5467001A2FB8 /* UndoObject.m in Sources */ = {isa = PBXBuildFile; fileRef = B01946060D5F5467001A2FB8 /* UndoObject.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -633,8 +632,6 @@ 8EFFCD490AA093AF00C458A5 /* FileOutlineView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = FileOutlineView.m; sourceTree = ""; }; 8EFFCD520AA093AF00C458A5 /* PathNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PathNode.h; sourceTree = ""; }; 8EFFCD530AA093AF00C458A5 /* PathNode.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PathNode.m; sourceTree = ""; }; - B01946050D5F5467001A2FB8 /* UndoObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UndoObject.h; sourceTree = ""; }; - B01946060D5F5467001A2FB8 /* UndoObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UndoObject.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1119,8 +1116,6 @@ 8E75752A09F31D5A0080F1EE /* Playlist */ = { isa = PBXGroup; children = ( - B01946050D5F5467001A2FB8 /* UndoObject.h */, - B01946060D5F5467001A2FB8 /* UndoObject.m */, 8E1296D80A2BA9CE00443124 /* PlaylistHeaderView.h */, 8E1296D90A2BA9CE00443124 /* PlaylistHeaderView.m */, 1755E1F60BA0D2B600CA3560 /* PlaylistLoader.h */, @@ -1615,7 +1610,6 @@ 178BAB9B0CD4E1B700B33D47 /* PopupButton.m in Sources */, 17BBE5BC0CD95CFA00258F7A /* InvertedToolbarWindow.m in Sources */, 569C52E20D5F347800BDBDC9 /* SpotlightWindowController.m in Sources */, - B01946070D5F5467001A2FB8 /* UndoObject.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Playlist/DNDArrayController.h b/Playlist/DNDArrayController.h index 319ce7c53..fae52c834 100755 --- a/Playlist/DNDArrayController.h +++ b/Playlist/DNDArrayController.h @@ -17,7 +17,10 @@ extern NSString *iTunesDropType; // utility methods --(void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet toIndex:(unsigned)index; +-(void)moveObjectsFromArrangedObjectIndexes:(NSArray *) sources toIndexes:(NSArray *)destinations; + +-(void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet*)indexSet toIndex:(unsigned int)insertIndex; + - (NSIndexSet *)indexSetFromRows:(NSArray *)rows; - (int)rowsAboveRow:(int)row inIndexSet:(NSIndexSet *)indexSet; diff --git a/Playlist/DNDArrayController.m b/Playlist/DNDArrayController.m index 2dc400a26..9f45aaf4f 100755 --- a/Playlist/DNDArrayController.m +++ b/Playlist/DNDArrayController.m @@ -69,11 +69,6 @@ NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E"; // set selected rows to those that were just moved // Need to work out what moved where to determine proper selection... - int rowsAbove = [self rowsAboveRow:row inIndexSet:indexSet]; - - NSRange range = NSMakeRange(row - rowsAbove, [indexSet count]); - indexSet = [NSIndexSet indexSetWithIndexesInRange:range]; - [self setSelectionIndexes:indexSet]; return YES; } @@ -82,16 +77,42 @@ NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E"; } --(void) moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet*)indexSet +-(void)moveObjectsFromArrangedObjectIndexes:(NSArray *) sources toIndexes:(NSArray *)destinations; +{ + //We expect [sources count] == [destinations count]. + NSMutableArray *selectedObjects = [[NSMutableArray alloc] init]; + + NSUInteger i = 0; + for (i = 0; i < [sources count]; i++) { + NSUInteger source = [[sources objectAtIndex:i] unsignedIntegerValue]; + NSUInteger dest = [[destinations objectAtIndex:i] unsignedIntegerValue]; + + id object = [[self arrangedObjects] objectAtIndex:source]; + + [object retain]; + + [self removeObjectAtArrangedObjectIndex:source]; + [self insertObject:object atArrangedObjectIndex:dest]; + + [selectedObjects addObject: object]; + + [object release]; + } + + [self setSelectedObjects:selectedObjects]; + + [selectedObjects release]; +} + +-(void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet*)indexSet toIndex:(unsigned int)insertIndex { - - NSArray *objects = [self arrangedObjects]; int index = [indexSet lastIndex]; - int aboveInsertIndexCount = 0; - id object; int removeIndex; + + NSMutableArray *sources = [NSMutableArray array]; + NSMutableArray *destinations = [NSMutableArray array]; while (NSNotFound != index) { @@ -104,14 +125,14 @@ NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E"; removeIndex = index; insertIndex -= 1; } - object = [objects objectAtIndex:removeIndex]; - [object retain]; - [self removeObjectAtArrangedObjectIndex:removeIndex]; - [self insertObject:object atArrangedObjectIndex:insertIndex]; - [object release]; + + [sources addObject:[NSNumber numberWithUnsignedInteger:removeIndex]]; + [destinations addObject: [NSNumber numberWithUnsignedInteger:insertIndex]]; index = [indexSet indexLessThanIndex:index]; } + + [self moveObjectsFromArrangedObjectIndexes:sources toIndexes:destinations]; } - (NSIndexSet *)indexSetFromRows:(NSArray *)rows @@ -126,16 +147,4 @@ NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E"; return indexSet; } -- (int)rowsAboveRow:(int)row inIndexSet:(NSIndexSet *)indexSet -{ - unsigned currentIndex = [indexSet firstIndex]; - int i = 0; - while (currentIndex != NSNotFound) - { - if (currentIndex < row) { i++; } - currentIndex = [indexSet indexGreaterThanIndex:currentIndex]; - } - return i; -} - @end diff --git a/Playlist/PlaylistController.h b/Playlist/PlaylistController.h index 9796b4bbd..6b7aa3489 100644 --- a/Playlist/PlaylistController.h +++ b/Playlist/PlaylistController.h @@ -8,7 +8,6 @@ #import #import -#import "UndoObject.h" #import "DNDArrayController.h" @class PlaylistLoader; @@ -44,8 +43,6 @@ /* Methods for undoing various actions */ - (NSUndoManager *)undoManager; -- (void)undoDelete:(NSMutableArray *)undoEntries; -- (void)undoMove:(NSMutableArray *) undoEntries; - (IBAction)takeShuffleFromObject:(id)sender; - (IBAction)takeRepeatFromObject:(id)sender; diff --git a/Playlist/PlaylistController.m b/Playlist/PlaylistController.m index bee1f695a..e4199da77 100644 --- a/Playlist/PlaylistController.m +++ b/Playlist/PlaylistController.m @@ -10,14 +10,13 @@ #import "PlaylistController.h" #import "PlaylistEntry.h" #import "Shuffle.h" -#import "UndoObject.h" #import "CogAudio/AudioPlayer.h" @implementation PlaylistController #define SHUFFLE_HISTORY_SIZE 100 -#define UNDO_STACK_LIMIT 25 +#define UNDO_STACK_LIMIT 100 - (id)initWithCoder:(NSCoder *)decoder { @@ -43,6 +42,42 @@ [self updateIndexesFromRow:0]; } +-(void)moveObjectsFromArrangedObjectIndexes:(NSArray *) sources toIndexes:(NSArray *)destinations +{ + NSLog(@"MOVING!: %@ %@", sources, destinations); + + NSMutableArray *undoSources = [NSMutableArray array]; + NSMutableArray *undoDests = [NSMutableArray array]; + + for (id s in sources) + { + [undoDests insertObject:s atIndex:0]; + } + for (id d in destinations) + { + [undoSources insertObject:d atIndex:0]; + } + [[[self undoManager] prepareWithInvocationTarget:self] moveObjectsFromArrangedObjectIndexes:undoSources toIndexes:undoDests]; + + [super moveObjectsFromArrangedObjectIndexes:sources toIndexes:destinations]; + + NSUInteger firstIndex = (NSUInteger)-1; + NSUInteger i = 0; + + for (i = 0; i < [sources count]; i++) { + NSUInteger source = [[sources objectAtIndex:i] unsignedIntegerValue]; + NSUInteger dest = [[destinations objectAtIndex:i] unsignedIntegerValue]; + + if (source < firstIndex) + firstIndex = source; + + if (dest < firstIndex) + firstIndex = dest; + } + + [self updateIndexesFromRow:firstIndex]; +} + - (BOOL)tableView:(NSTableView*)tv acceptDrop:(id )info row:(int)row @@ -50,53 +85,9 @@ { [super tableView:tv acceptDrop:info row:row dropOperation:op]; - UndoObject *undoEntry; - NSMutableArray *undoEntries = [[NSMutableArray alloc] init]; - if ([info draggingSource] == tableView) { - //DNDArrayController handles moving...still need to update the indexes - - NSArray *rows = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType: MovedRowsType]]; - NSIndexSet *indexes = [self indexSetFromRows:rows]; - int firstIndex = [indexes firstIndex]; - int indexesSize = [indexes count]; - NSUInteger indexBuffer[indexesSize]; - - int i; - int adjustment; - int counter; - - if (firstIndex > row) - i = row; - else - i = firstIndex; - - [indexes getIndexes:indexBuffer maxCount:indexesSize inIndexRange:nil]; - - if (row > firstIndex) - adjustment = 1; - else - adjustment = 0; - - // create an UndoObject for each entry being moved, and store it away - // in the undoEntries array - for (counter = 0; counter < indexesSize; counter++) - { - undoEntry = [[UndoObject alloc] init]; - - [undoEntry setOrigin: row - adjustment]; - [undoEntry setMovedTo: indexBuffer[counter]]; - [undoEntries addObject: undoEntry]; - } - - [[self undoManager] registerUndoWithTarget:self - selector:@selector(undoMove:) - object:undoEntries]; - - - - [self updateIndexesFromRow:i]; + //DNDArrayController handles moving... return YES; } @@ -198,132 +189,29 @@ } } --(void)undoDelete:(NSMutableArray *)undoEntries -{ - NSEnumerator *enumerator = [undoEntries objectEnumerator]; - UndoObject *current; - - while (current = [enumerator nextObject]) - { - [playlistLoader - insertURLs: [NSArray arrayWithObject:[current path]] - atIndex:[current origin] - sort:YES]; - // make sure to dealloc the undo object after reinserting it - [current dealloc]; - - } - [self updateIndexesFromRow: 0]; -} - --(void)undoMove:(NSMutableArray *) undoEntries -{ - NSArray *objects = [super arrangedObjects]; - NSEnumerator *enumerator = [undoEntries objectEnumerator]; - UndoObject *current; - id object; - int len = [undoEntries count]; - int iterations = 0; - int playlistLocation; - - // register an undo for the undo with the undoManager, - // so it knows what to do if a redo is requested - [[self undoManager] registerUndoWithTarget:self - selector:@selector(undoMove:) - object:undoEntries]; - - while (current = [enumerator nextObject]) - { - /* the exact opposite of an undo is required during a redo, hence - we have to check what we are dealing with and act accordingly */ - - // originally moved entry up the list - if (([current origin] > [current movedTo])) - { - if ([[self undoManager] isUndoing]) // we are undoing - { - playlistLocation = ([current origin] - (len - 1)) + iterations++; - object = [objects objectAtIndex: playlistLocation]; - [object retain]; - [super insertObject:object atArrangedObjectIndex:[current movedTo]]; - [super removeObjectAtArrangedObjectIndex:playlistLocation + 1]; - } - else // we are redoing the undo - { - playlistLocation = [current movedTo] - iterations++; - object = [objects objectAtIndex: playlistLocation]; - [object retain]; - [super removeObjectAtArrangedObjectIndex:playlistLocation]; - [super insertObject:object atArrangedObjectIndex:[current origin]]; - } - - } - // originally moved entry down the list - else - { - if ([[self undoManager] isUndoing]) - { - object = [objects objectAtIndex: [current origin]]; - [object retain]; - [super insertObject:object atArrangedObjectIndex:[current movedTo] + len--]; - [super removeObjectAtArrangedObjectIndex:[current origin]]; - } - else - { - object = [objects objectAtIndex: [current movedTo]]; - [object retain]; - [super removeObjectAtArrangedObjectIndex:[current movedTo]]; - [super insertObject:object atArrangedObjectIndex:[current origin] + iterations++]; - } - - } - [object release]; - - } - - [self updateIndexesFromRow: 0]; - -} - - (NSUndoManager *)undoManager { return undoManager; } +- (void)insertObjects:(NSArray *)objects atArrangedObjectIndexes:(NSIndexSet *)indexes +{ + [[[self undoManager] prepareWithInvocationTarget:self] removeObjectsAtArrangedObjectIndexes:indexes]; + [super insertObjects:objects atArrangedObjectIndexes:indexes]; + + [self updateIndexesFromRow:[indexes firstIndex]]; + [self updateTotalTime]; + + if (shuffle == YES) + [self resetShuffleList]; +} + + - (void)removeObjectsAtArrangedObjectIndexes:(NSIndexSet *)indexes { - int i; // loop counter - int indexesSize = [indexes count]; - NSUInteger indexBuffer[indexesSize]; - UndoObject *undoEntry; - PlaylistEntry *pre; - NSMutableArray *undoEntries = [[NSMutableArray alloc] init]; - NSLog(@"Removing indexes: %@", indexes); NSLog(@"Current index: %i", [[currentEntry index] intValue]); - // get indexes from IndexSet indexes and put them in indexBuffer - [indexes getIndexes:indexBuffer maxCount:indexesSize inIndexRange:nil]; - - // loop through the list of indexes, saving each entry away - // in an undo object - for (i = 0; i < indexesSize; i++) - { - // alllocate a new object for each undo entry - undoEntry = [[UndoObject alloc] init]; - - pre = [self entryAtIndex:indexBuffer[i]]; - - [undoEntry setOrigin:indexBuffer[i] andPath: [pre url]]; - [undoEntries addObject:undoEntry]; - } - - // register the removals with the undoManager - [[self undoManager] registerUndoWithTarget:self - selector:@selector(undoDelete:) - object:undoEntries]; - - if ([[currentEntry index] intValue] >= 0 && [indexes containsIndex:[[currentEntry index] intValue]]) { [currentEntry setIndex:[NSNumber numberWithInt:-[[currentEntry index] intValue] - 1]]; @@ -347,7 +235,9 @@ NSLog(@"UPDATING INDEX: %@", [currentEntry index]); } + [[[self undoManager] prepareWithInvocationTarget:self] insertObjects:[[self arrangedObjects] objectsAtIndexes:indexes] atArrangedObjectIndexes:indexes]; [super removeObjectsAtArrangedObjectIndexes:indexes]; + [self updateIndexesFromRow:[indexes firstIndex]]; [self updateTotalTime]; diff --git a/Playlist/PlaylistLoader.m b/Playlist/PlaylistLoader.m index 6385d8393..3fac0d92e 100755 --- a/Playlist/PlaylistLoader.m +++ b/Playlist/PlaylistLoader.m @@ -252,8 +252,6 @@ [validURLs addObject:url]; } - NSUndoManager *undoManager = [playlistController undoManager]; - //Create actual entries int i; NSMutableArray *entries = [NSMutableArray array]; @@ -273,10 +271,6 @@ NSIndexSet *is = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, [entries count])]; - [undoManager registerUndoWithTarget:self - selector:@selector(undoAdd:) - object:is]; - [playlistController insertObjects:entries atArrangedObjectIndexes:is]; //Select the first entry in the group that was just added @@ -288,12 +282,6 @@ return; } --(void)undoAdd:(NSIndexSet *)undoEntries -{ - [playlistController removeObjectsAtArrangedObjectIndexes:undoEntries]; - -} - - (void)readEntriesInfoThread:(NSArray *)entries { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; diff --git a/Playlist/PlaylistView.m b/Playlist/PlaylistView.m index 7e10e38ed..6461cccd9 100644 --- a/Playlist/PlaylistView.m +++ b/Playlist/PlaylistView.m @@ -233,17 +233,17 @@ [[playlistController undoManager] redo]; } --(BOOL)validateMenuItem:(NSMenuItem*)menuItem + +-(BOOL)validateUserInterfaceItem:(id )anItem { - SEL action = [menuItem action]; + SEL action = [anItem action]; if (action == @selector(undo:) && [[playlistController undoManager] canUndo]) return YES; - if (action == @selector(redo:) && [[playlistController undoManager] canRedo]) return YES; - - return NO; + + return [super validateUserInterfaceItem:anItem]; } @end diff --git a/Playlist/UndoObject.h b/Playlist/UndoObject.h deleted file mode 100644 index c191e1cc1..000000000 --- a/Playlist/UndoObject.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// UndoObject.h -// Cog -// -// Created by Andre Reffhaug on 2/6/08. -// Copyright 2008 __MyCompanyName__. All rights reserved. -// - -#import - - -@interface UndoObject : NSObject { - int origin; - int movedTo; - NSURL *path; -} - --(void)setPath:(NSURL *) p; --(void)setOrigin:(int) i; --(void)setMovedTo:(int) i; --(void)setOrigin:(int) i andPath:(NSURL *)path; - --(int)origin; --(int)movedTo; --(NSURL *)path; - -@end diff --git a/Playlist/UndoObject.m b/Playlist/UndoObject.m deleted file mode 100644 index a4fd129ac..000000000 --- a/Playlist/UndoObject.m +++ /dev/null @@ -1,53 +0,0 @@ -// -// UndoObject.m -// Cog -// -// Created by Andre Reffhaug on 2/6/08. -// Copyright 2008 __MyCompanyName__. All rights reserved. -// - -#import "UndoObject.h" - - -@implementation UndoObject - --(void)setPath:(NSURL *)p -{ - [p retain]; - [path release]; - path = p; -} - --(void)setOrigin:(int)i -{ - origin = i; -} - --(void)setMovedTo:(int)i -{ - movedTo = i; -} --(void)setOrigin:(int) i andPath:(NSURL *)p -{ - origin = i; - [p retain]; - [path release]; - path = p; -} - --(int) origin -{ - return origin; -} - --(int) movedTo -{ - return movedTo; -} - --(NSURL *) path -{ - return path; -} - -@end