Added undo functionality in playlist, undo works for removals, moves and adds.
parent
4bd896afb3
commit
9b05ce02d2
|
@ -236,9 +236,11 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
|
||||||
[remote startListening:self];
|
[remote startListening:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSUndoManager *undoManager = [playlistController undoManager];
|
||||||
|
[undoManager disableUndoRegistration];
|
||||||
NSString *filename = @"~/Library/Application Support/Cog/Default.m3u";
|
NSString *filename = @"~/Library/Application Support/Cog/Default.m3u";
|
||||||
[playlistLoader addURL:[NSURL fileURLWithPath:[filename stringByExpandingTildeInPath]]];
|
[playlistLoader addURL:[NSURL fileURLWithPath:[filename stringByExpandingTildeInPath]]];
|
||||||
|
[undoManager enableUndoRegistration];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
||||||
|
|
|
@ -130,6 +130,7 @@
|
||||||
8EFFCD630AA093AF00C458A5 /* FileNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFFCD470AA093AF00C458A5 /* FileNode.m */; };
|
8EFFCD630AA093AF00C458A5 /* FileNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFFCD470AA093AF00C458A5 /* FileNode.m */; };
|
||||||
8EFFCD650AA093AF00C458A5 /* FileOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFFCD490AA093AF00C458A5 /* FileOutlineView.m */; };
|
8EFFCD650AA093AF00C458A5 /* FileOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFFCD490AA093AF00C458A5 /* FileOutlineView.m */; };
|
||||||
8EFFCD6F0AA093AF00C458A5 /* PathNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFFCD530AA093AF00C458A5 /* PathNode.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 */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
@ -632,6 +633,8 @@
|
||||||
8EFFCD490AA093AF00C458A5 /* FileOutlineView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = FileOutlineView.m; sourceTree = "<group>"; };
|
8EFFCD490AA093AF00C458A5 /* FileOutlineView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = FileOutlineView.m; sourceTree = "<group>"; };
|
||||||
8EFFCD520AA093AF00C458A5 /* PathNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PathNode.h; sourceTree = "<group>"; };
|
8EFFCD520AA093AF00C458A5 /* PathNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PathNode.h; sourceTree = "<group>"; };
|
||||||
8EFFCD530AA093AF00C458A5 /* PathNode.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PathNode.m; sourceTree = "<group>"; };
|
8EFFCD530AA093AF00C458A5 /* PathNode.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PathNode.m; sourceTree = "<group>"; };
|
||||||
|
B01946050D5F5467001A2FB8 /* UndoObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UndoObject.h; sourceTree = "<group>"; };
|
||||||
|
B01946060D5F5467001A2FB8 /* UndoObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UndoObject.m; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -1116,6 +1119,8 @@
|
||||||
8E75752A09F31D5A0080F1EE /* Playlist */ = {
|
8E75752A09F31D5A0080F1EE /* Playlist */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
B01946050D5F5467001A2FB8 /* UndoObject.h */,
|
||||||
|
B01946060D5F5467001A2FB8 /* UndoObject.m */,
|
||||||
8E1296D80A2BA9CE00443124 /* PlaylistHeaderView.h */,
|
8E1296D80A2BA9CE00443124 /* PlaylistHeaderView.h */,
|
||||||
8E1296D90A2BA9CE00443124 /* PlaylistHeaderView.m */,
|
8E1296D90A2BA9CE00443124 /* PlaylistHeaderView.m */,
|
||||||
1755E1F60BA0D2B600CA3560 /* PlaylistLoader.h */,
|
1755E1F60BA0D2B600CA3560 /* PlaylistLoader.h */,
|
||||||
|
@ -1610,6 +1615,7 @@
|
||||||
178BAB9B0CD4E1B700B33D47 /* PopupButton.m in Sources */,
|
178BAB9B0CD4E1B700B33D47 /* PopupButton.m in Sources */,
|
||||||
17BBE5BC0CD95CFA00258F7A /* InvertedToolbarWindow.m in Sources */,
|
17BBE5BC0CD95CFA00258F7A /* InvertedToolbarWindow.m in Sources */,
|
||||||
569C52E20D5F347800BDBDC9 /* SpotlightWindowController.m in Sources */,
|
569C52E20D5F347800BDBDC9 /* SpotlightWindowController.m in Sources */,
|
||||||
|
B01946070D5F5467001A2FB8 /* UndoObject.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -114,7 +114,6 @@ NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (NSIndexSet *)indexSetFromRows:(NSArray *)rows
|
- (NSIndexSet *)indexSetFromRows:(NSArray *)rows
|
||||||
{
|
{
|
||||||
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
|
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
|
||||||
|
@ -127,7 +126,6 @@ NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E";
|
||||||
return indexSet;
|
return indexSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (int)rowsAboveRow:(int)row inIndexSet:(NSIndexSet *)indexSet
|
- (int)rowsAboveRow:(int)row inIndexSet:(NSIndexSet *)indexSet
|
||||||
{
|
{
|
||||||
unsigned currentIndex = [indexSet firstIndex];
|
unsigned currentIndex = [indexSet firstIndex];
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <Foundation/NSUndoManager.h>
|
||||||
|
#import "UndoObject.h"
|
||||||
#import "DNDArrayController.h"
|
#import "DNDArrayController.h"
|
||||||
|
|
||||||
@class PlaylistLoader;
|
@class PlaylistLoader;
|
||||||
|
@ -19,6 +21,8 @@
|
||||||
|
|
||||||
NSMutableArray *shuffleList;
|
NSMutableArray *shuffleList;
|
||||||
|
|
||||||
|
NSUndoManager *undoManager;
|
||||||
|
|
||||||
PlaylistEntry *currentEntry;
|
PlaylistEntry *currentEntry;
|
||||||
|
|
||||||
BOOL shuffle;
|
BOOL shuffle;
|
||||||
|
@ -38,6 +42,13 @@
|
||||||
- (void)setRepeat:(BOOL)r;
|
- (void)setRepeat:(BOOL)r;
|
||||||
- (BOOL)repeat;
|
- (BOOL)repeat;
|
||||||
|
|
||||||
|
/* Methods for undoing various actions */
|
||||||
|
- (NSUndoManager *)undoManager;
|
||||||
|
- (void)undoDelete:(NSMutableArray *)undoEntries;
|
||||||
|
- (void)undoMove:(NSMutableArray *) undoEntries;
|
||||||
|
- (void)doUndo:(id)sender;
|
||||||
|
- (void)doRedo:(id)sender;
|
||||||
|
|
||||||
- (IBAction)takeShuffleFromObject:(id)sender;
|
- (IBAction)takeShuffleFromObject:(id)sender;
|
||||||
- (IBAction)takeRepeatFromObject:(id)sender;
|
- (IBAction)takeRepeatFromObject:(id)sender;
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
//
|
//
|
||||||
// PlaylistController.m
|
// PlaylistController.m
|
||||||
// Cog
|
// Cog
|
||||||
//
|
//
|
||||||
// Created by Vincent Spader on 3/18/05.
|
// Created by Vincent Spader on 3/18/05.
|
||||||
// Copyright 2005 Vincent Spader All rights reserved.
|
// Copyright 2005 Vincent Spader All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "PlaylistLoader.h"
|
#import "PlaylistLoader.h"
|
||||||
#import "PlaylistController.h"
|
#import "PlaylistController.h"
|
||||||
#import "PlaylistEntry.h"
|
#import "PlaylistEntry.h"
|
||||||
#import "Shuffle.h"
|
#import "Shuffle.h"
|
||||||
|
#import "UndoObject.h"
|
||||||
|
|
||||||
#import "CogAudio/AudioPlayer.h"
|
#import "CogAudio/AudioPlayer.h"
|
||||||
|
|
||||||
@implementation PlaylistController
|
@implementation PlaylistController
|
||||||
|
|
||||||
#define SHUFFLE_HISTORY_SIZE 100
|
#define SHUFFLE_HISTORY_SIZE 100
|
||||||
|
#define UNDO_STACK_LIMIT 25
|
||||||
|
|
||||||
- (id)initWithCoder:(NSCoder *)decoder
|
- (id)initWithCoder:(NSCoder *)decoder
|
||||||
{
|
{
|
||||||
|
@ -24,6 +26,9 @@
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
shuffleList = [[NSMutableArray alloc] init];
|
shuffleList = [[NSMutableArray alloc] init];
|
||||||
|
undoManager = [[NSUndoManager alloc] init];
|
||||||
|
|
||||||
|
[undoManager setLevelsOfUndo:UNDO_STACK_LIMIT];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -44,19 +49,53 @@
|
||||||
dropOperation:(NSTableViewDropOperation)op
|
dropOperation:(NSTableViewDropOperation)op
|
||||||
{
|
{
|
||||||
[super tableView:tv acceptDrop:info row:row dropOperation:op];
|
[super tableView:tv acceptDrop:info row:row dropOperation:op];
|
||||||
|
|
||||||
|
UndoObject *undoEntry;
|
||||||
|
NSMutableArray *undoEntries = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
if ([info draggingSource] == tableView)
|
if ([info draggingSource] == tableView)
|
||||||
{
|
{
|
||||||
//DNDArrayController handles moving...still need to update the indexes
|
//DNDArrayController handles moving...still need to update the indexes
|
||||||
|
|
||||||
int i;
|
NSArray *rows = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType: MovedRowsType]];
|
||||||
NSArray *rows = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType: MovedRowsType]];
|
NSIndexSet *indexes = [self indexSetFromRows:rows];
|
||||||
int firstIndex = [[self indexSetFromRows:rows] firstIndex];
|
int firstIndex = [indexes firstIndex];
|
||||||
|
int indexesSize = [indexes count];
|
||||||
|
NSUInteger indexBuffer[indexesSize];
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int adjustment;
|
||||||
|
int counter;
|
||||||
|
|
||||||
if (firstIndex > row)
|
if (firstIndex > row)
|
||||||
i = row;
|
i = row;
|
||||||
else
|
else
|
||||||
i = firstIndex;
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
[undoManager registerUndoWithTarget:self
|
||||||
|
selector:@selector(undoMove:)
|
||||||
|
object:undoEntries];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[self updateIndexesFromRow:i];
|
[self updateIndexesFromRow:i];
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
|
@ -159,11 +198,144 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(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
|
||||||
|
[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 ([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 ([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)doUndo:(id)sender
|
||||||
|
{
|
||||||
|
[undoManager undo];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)doRedo:(id)sender
|
||||||
|
{
|
||||||
|
[undoManager redo];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)removeObjectsAtArrangedObjectIndexes:(NSIndexSet *)indexes
|
- (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(@"Removing indexes: %@", indexes);
|
||||||
NSLog(@"Current index: %i", [[currentEntry index] intValue]);
|
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
|
||||||
|
[undoManager registerUndoWithTarget:self
|
||||||
|
selector:@selector(undoDelete:)
|
||||||
|
object:undoEntries];
|
||||||
|
|
||||||
|
|
||||||
if ([[currentEntry index] intValue] >= 0 && [indexes containsIndex:[[currentEntry index] intValue]])
|
if ([[currentEntry index] intValue] >= 0 && [indexes containsIndex:[[currentEntry index] intValue]])
|
||||||
{
|
{
|
||||||
[currentEntry setIndex:[NSNumber numberWithInt:-[[currentEntry index] intValue] - 1]];
|
[currentEntry setIndex:[NSNumber numberWithInt:-[[currentEntry index] intValue] - 1]];
|
||||||
|
|
|
@ -23,7 +23,7 @@ typedef enum {
|
||||||
- (void)addURLs:(NSArray *)urls sort:(BOOL)sort;
|
- (void)addURLs:(NSArray *)urls sort:(BOOL)sort;
|
||||||
- (void)addURL:(NSURL *)url;
|
- (void)addURL:(NSURL *)url;
|
||||||
- (void)insertURLs:(NSArray *)urls atIndex:(int)index sort:(BOOL)sort;
|
- (void)insertURLs:(NSArray *)urls atIndex:(int)index sort:(BOOL)sort;
|
||||||
|
- (void)undoAdd:(NSIndexSet *)undoEntries;
|
||||||
//save playlist, auto-determines type based on extension. Uses m3u if it cannot be determined.
|
//save playlist, auto-determines type based on extension. Uses m3u if it cannot be determined.
|
||||||
- (BOOL)save:(NSString *)filename;
|
- (BOOL)save:(NSString *)filename;
|
||||||
- (BOOL)save:(NSString *)filename asType:(PlaylistType)type;
|
- (BOOL)save:(NSString *)filename asType:(PlaylistType)type;
|
||||||
|
|
|
@ -252,6 +252,7 @@
|
||||||
[validURLs addObject:url];
|
[validURLs addObject:url];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSUndoManager *undoManager = [playlistController undoManager];
|
||||||
|
|
||||||
//Create actual entries
|
//Create actual entries
|
||||||
int i;
|
int i;
|
||||||
|
@ -272,6 +273,10 @@
|
||||||
|
|
||||||
NSIndexSet *is = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, [entries count])];
|
NSIndexSet *is = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, [entries count])];
|
||||||
|
|
||||||
|
[undoManager registerUndoWithTarget:self
|
||||||
|
selector:@selector(undoAdd:)
|
||||||
|
object:is];
|
||||||
|
|
||||||
[playlistController insertObjects:entries atArrangedObjectIndexes:is];
|
[playlistController insertObjects:entries atArrangedObjectIndexes:is];
|
||||||
|
|
||||||
//Select the first entry in the group that was just added
|
//Select the first entry in the group that was just added
|
||||||
|
@ -283,6 +288,12 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(void)undoAdd:(NSIndexSet *)undoEntries
|
||||||
|
{
|
||||||
|
[playlistController removeObjectsAtArrangedObjectIndexes:undoEntries];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
- (void)readEntriesInfoThread:(NSArray *)entries
|
- (void)readEntriesInfoThread:(NSArray *)entries
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
|
@ -133,8 +133,8 @@
|
||||||
{
|
{
|
||||||
//Find which row is under the cursor
|
//Find which row is under the cursor
|
||||||
[[self window] makeFirstResponder:self];
|
[[self window] makeFirstResponder:self];
|
||||||
NSPoint menuPoint = [self convertPoint:[event locationInWindow] fromView:nil];
|
NSPoint menuPoint = [self convertPoint:[event locationInWindow] fromView:nil];
|
||||||
int row = [self rowAtPoint:menuPoint];
|
int row = [self rowAtPoint:menuPoint];
|
||||||
|
|
||||||
/* Update the table selection before showing menu
|
/* Update the table selection before showing menu
|
||||||
Preserves the selection if the row under the mouse is selected (to allow for
|
Preserves the selection if the row under the mouse is selected (to allow for
|
||||||
|
@ -171,11 +171,12 @@
|
||||||
|
|
||||||
- (void)keyDown:(NSEvent *)e
|
- (void)keyDown:(NSEvent *)e
|
||||||
{
|
{
|
||||||
unsigned int modifiers = [e modifierFlags] & (NSCommandKeyMask | NSShiftKeyMask | NSControlKeyMask | NSAlternateKeyMask);
|
unsigned int modifiers = [e modifierFlags] & (NSCommandKeyMask | NSShiftKeyMask | NSControlKeyMask | NSAlternateKeyMask);
|
||||||
NSString *characters = [e characters];
|
NSString *characters = [e characters];
|
||||||
unichar c;
|
unichar c;
|
||||||
|
|
||||||
if ([characters length] != 1) {
|
if ([characters length] != 1)
|
||||||
|
{
|
||||||
[super keyDown:e];
|
[super keyDown:e];
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -194,7 +195,9 @@
|
||||||
{
|
{
|
||||||
[playbackController play:self];
|
[playbackController play:self];
|
||||||
}
|
}
|
||||||
else if (modifiers == 0 && c == 0x1b) { //Escape
|
// Escape
|
||||||
|
else if (modifiers == 0 && c == 0x1b)
|
||||||
|
{
|
||||||
[playlistController clearFilterPredicate:self];
|
[playlistController clearFilterPredicate:self];
|
||||||
}
|
}
|
||||||
else if (modifiers == NSControlKeyMask && c == 0xf703) // right arrow
|
else if (modifiers == NSControlKeyMask && c == 0xf703) // right arrow
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// UndoObject.h
|
||||||
|
// Cog
|
||||||
|
//
|
||||||
|
// Created by Andre Reffhaug on 2/6/08.
|
||||||
|
// Copyright 2008 __MyCompanyName__. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
|
||||||
|
@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
|
|
@ -0,0 +1,53 @@
|
||||||
|
//
|
||||||
|
// 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
|
Loading…
Reference in New Issue