Updated APL plugin to use new protocol

Added support for behavior modifiers on addition/opening of files
Added Command+Control as modifier for open/enqueue
CQTexperiment
vasfed 2008-05-09 21:24:49 +00:00
parent 23124f7792
commit e063790e93
16 changed files with 4926 additions and 2010 deletions

View File

@ -171,7 +171,8 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
{
if (returnCode == NSOKButton)
{
[playlistLoader addURLs:[panel URLs] sort:YES];
[playlistLoader willInsertFiles:[panel URLs] origin:OpenFromOpenPanel];
[playlistLoader didInsertFiles:[playlistLoader addURLs:[panel URLs] sort:YES] origin:OpenFromOpenPanel];
}
}
@ -206,7 +207,8 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
{
if (returnCode == NSOKButton)
{
[playlistLoader addURLs:[NSArray arrayWithObject:[panel url]] sort:NO];
[playlistLoader willInsertFiles:[NSArray arrayWithObject:[panel url]] origin:OpenFromOpenUrlPanel];
[playlistLoader didInsertFiles:[playlistLoader addURLs:[NSArray arrayWithObject:[panel url]] sort:NO] origin:OpenFromOpenUrlPanel];
}
}
@ -286,8 +288,9 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
[playlistLoader addURLs:[NSArray arrayWithObject:[NSURL fileURLWithPath:filename]] sort:NO];
NSArray* urls = [NSArray arrayWithObject:[NSURL fileURLWithPath:filename]];
[playlistLoader willInsertFiles:urls origin:OpenFromFinder];
[playlistLoader didInsertFiles:[playlistLoader addURLs:urls sort:NO] origin:OpenFromFinder];
return YES;
}
@ -300,8 +303,8 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
{
[urls addObject:[NSURL fileURLWithPath:filename]];
}
[playlistLoader addURLs:urls sort:YES];
[playlistLoader willInsertFiles:urls origin:OpenFromFinder];
[playlistLoader didInsertFiles:[playlistLoader addURLs:urls sort:YES] origin:OpenFromFinder];
[theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
}
@ -357,6 +360,10 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
[userDefaultsValuesDict setObject:@"http://cogx.org/appcast/stable.xml" forKey:@"SUFeedURL"];
[userDefaultsValuesDict setObject:[NSNumber numberWithBool:YES] forKey:@"clearOnAdd"];
[userDefaultsValuesDict setObject:[NSNumber numberWithBool:YES] forKey:@"playOnAdd"];
//Register and sync defaults
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];
[[NSUserDefaults standardUserDefaults] synchronize];

View File

@ -146,6 +146,8 @@
8E9A2E860BA78B500091081B /* SecondsFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A2E840BA78B500091081B /* SecondsFormatter.m */; };
8E9A2EDA0BA78D9D0091081B /* IndexFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A2ED80BA78D9D0091081B /* IndexFormatter.m */; };
8E9A30160BA792DC0091081B /* NSFileHandle+CreateFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A30140BA792DC0091081B /* NSFileHandle+CreateFile.m */; };
99EAACA20DD1B9DB00423C38 /* APL.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 566D321B0D538550004466A5 /* APL.bundle */; };
99EAACA80DD1BB7A00423C38 /* APL.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 566D321B0D538550004466A5 /* APL.bundle */; };
B09E96630D74A7BC0064F138 /* stop_current.png in Resources */ = {isa = PBXBuildFile; fileRef = B09E96620D74A7BC0064F138 /* stop_current.png */; };
/* End PBXBuildFile section */
@ -446,6 +448,7 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
99EAACA80DD1BB7A00423C38 /* APL.bundle in CopyFiles */,
17C8F7D80CBEF3EF008D969D /* Dumb.bundle in CopyFiles */,
17C8F3CF0CBED66C008D969D /* GME.bundle in CopyFiles */,
17F3BB890CBC565900864489 /* CueSheet.bundle in CopyFiles */,
@ -1659,6 +1662,7 @@
17A8F6870D6A7FCA0095DA13 /* repeat_one.png in Resources */,
17A8F71A0D6A89730095DA13 /* repeat_album.png in Resources */,
B09E96630D74A7BC0064F138 /* stop_current.png in Resources */,
99EAACA20DD1B9DB00423C38 /* APL.bundle in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "PlaylistController.h"
#import "FileTreeWindowController.h"
@ -42,7 +43,8 @@
[urls addObject:[[outlineView itemAtRow:index] URL]];
}
[playlistLoader addURLs:urls sort:NO];
[playlistLoader willInsertFiles:urls origin:OpenFromFiletree];
[playlistLoader didInsertFiles:[playlistLoader addURLs:urls sort:NO] origin:OpenFromFiletree];
[urls release];
}

View File

@ -413,7 +413,23 @@
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
</array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>apl</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>cue.icns</string>
<key>CFBundleTypeName</key>
<string>APL Link File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSTypeIsPackage</key>
<false/>
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>Cog</string>
<key>CFBundleHelpBookFolder</key>

View File

@ -14,6 +14,7 @@
NSMutableArray *playlistEntries;
}
- (NSUndoManager *)undoManager;
- (NSMutableArray *)entries;
- (void)setEntries:(NSMutableArray *)array;
- (void)insertObject:(PlaylistEntry *)pe inEntriesAtIndex:(int)index;

View File

@ -14,6 +14,7 @@
@class PlaylistEntry;
@class EntriesController;
@class SpotlightWindowController;
@class PlaybackController;
typedef enum {
RepeatNone = 0,
@ -22,10 +23,26 @@ typedef enum {
RepeatAll
} RepeatMode;
typedef enum {
OpenPlaylist_related = 0,
LoadPlaylist,
DropOnPlaylist,
OpenFromOpenPanel,
OpenFromOpenUrlPanel,
OpenPlaylist_related_end,
OpenFinder_Related, //meta-value
OpenFromFinder,
OpenFromFiletree,
OpenFromSpotlight, //?
OpenFinder_Related_end,
} AddedFilesSource;
@interface PlaylistController : DNDArrayController {
IBOutlet PlaylistLoader *playlistLoader;
IBOutlet EntriesController *entriesController;
IBOutlet SpotlightWindowController *spotlightWindowController;
IBOutlet PlaybackController *playbackController;
NSMutableArray *shuffleList;
NSMutableArray *queueList;
@ -86,6 +103,10 @@ typedef enum {
- (PlaylistEntry *)shuffledEntryAtIndex:(int)i;
- (PlaylistEntry *)entryAtIndex:(int)i;
// Event inlets:
- (void)willInsertFiles:(NSArray*)urls origin:(AddedFilesSource)src;
- (void)didInsertFiles:(NSArray*)entries origin:(AddedFilesSource)src;
// queue methods
- (IBAction)toggleQueued:(id)sender;
- (IBAction)emptyQueueList:(id)sender;

View File

@ -8,6 +8,8 @@
#import "PlaylistLoader.h"
#import "PlaylistController.h"
#import "PlaybackController.h"
#import "EntriesController.h"
#import "PlaylistEntry.h"
#import "Shuffle.h"
#import "SpotlightWindowController.h"
@ -178,17 +180,21 @@
if (row < 0)
row = 0;
// Determine the type of object that was dropped
NSArray *supportedtypes = [NSArray arrayWithObjects:CogUrlsPboardType, NSFilenamesPboardType, iTunesDropType, nil];
NSPasteboard *pboard = [info draggingPasteboard];
NSString *bestType = [pboard availableTypeFromArray:supportedtypes];
NSMutableArray *accept_urls = [[NSMutableArray alloc] init];
// Get files from an file drawer drop
if ([bestType isEqualToString:CogUrlsPboardType]) {
NSArray *urls = [NSUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:CogUrlsPboardType]];
NSLog(@"URLS: %@", urls);
[playlistLoader insertURLs: urls atIndex:row sort:YES];
//[playlistLoader insertURLs: urls atIndex:row sort:YES];
[accept_urls addObjectsFromArray:urls];
}
// Get files from a normal file drop (such as from Finder)
@ -200,8 +206,8 @@
[urls addObject:[NSURL fileURLWithPath:file]];
}
[playlistLoader insertURLs:urls atIndex:row sort:YES];
//[playlistLoader insertURLs:urls atIndex:row sort:YES];
[accept_urls addObjectsFromArray:urls];
[urls release];
}
@ -217,10 +223,22 @@
[urls addObject:[NSURL URLWithString:[trackInfo valueForKey:@"Location"]]];
}
[playlistLoader insertURLs:urls atIndex:row sort:YES];
//[playlistLoader insertURLs:urls atIndex:row sort:YES];
[accept_urls addObjectsFromArray:urls];
[urls release];
}
if ([accept_urls count])
{
[self willInsertFiles:accept_urls origin:DropOnPlaylist];
if (![[entriesController entries] count])
row = 0;
NSArray* entries = [playlistLoader insertURLs:accept_urls atIndex:row sort:YES];
[self didInsertFiles:entries origin:DropOnPlaylist];
}
[accept_urls release];
if (shuffle == YES)
[self resetShuffleList];
@ -726,5 +744,50 @@
return YES;
}
// Event inlets:
- (void)willInsertFiles:(NSArray*)urls origin:(AddedFilesSource)src
{
if (![urls count])
return;
CGEventRef event = CGEventCreate(NULL /*default event source*/);
CGEventFlags mods = CGEventGetFlags(event);
CFRelease(event);
bool modifier1_pressed = ((mods & kCGEventFlagMaskCommand)!=0)&((mods & kCGEventFlagMaskControl)!=0);
bool should_clean = false;
if (src >= OpenFinder_Related && src <= OpenFinder_Related_end)
should_clean = [[NSUserDefaults standardUserDefaults] boolForKey:@"clearOnAdd"] ^ modifier1_pressed;
if (src >= OpenPlaylist_related && src <= OpenPlaylist_related_end)
should_clean = modifier1_pressed;
if (should_clean)
[self clear:self];
}
- (void)didInsertFiles:(NSArray*)entries origin:(AddedFilesSource)src
{
if (![entries count])
return;
CGEventRef event = CGEventCreate(NULL);
CGEventFlags mods = CGEventGetFlags(event);
CFRelease(event);
bool modifier1_pressed = ((mods & kCGEventFlagMaskCommand)!=0)&((mods & kCGEventFlagMaskControl)!=0);
bool should_autoplay = false;
if (src >= OpenFinder_Related && src <= OpenFinder_Related_end)
should_autoplay = [[NSUserDefaults standardUserDefaults] boolForKey:@"playOnAdd"] ^ modifier1_pressed;
if (src >= OpenPlaylist_related && src <= OpenPlaylist_related_end)
should_autoplay = modifier1_pressed;
//Auto start playback
if (should_autoplay && [[entriesController entries] count] > 0) {
[[entries objectAtIndex:0] setValuesForKeysWithDictionary:[playlistLoader readEntryInfo:[entries objectAtIndex:0]]];
[playbackController playEntry: [entries objectAtIndex:0]];
}
}
@end

View File

@ -7,6 +7,7 @@
//
#import <Cocoa/Cocoa.h>
#import "PlaylistController.h"
@class PlaylistController;
@class PlaybackController;
@ -19,15 +20,14 @@ typedef enum {
@interface PlaylistLoader : NSObject {
IBOutlet PlaylistController *playlistController;
IBOutlet PlaybackController *playbackController;
}
- (void)initDefaults;
//load arrays of urls...
- (void)addURLs:(NSArray *)urls sort:(BOOL)sort;
- (void)addURL:(NSURL *)url;
- (void)insertURLs:(NSArray *)urls atIndex:(int)index sort:(BOOL)sort;
- (NSArray*)addURLs:(NSArray *)urls sort:(BOOL)sort;
- (NSArray*)addURL:(NSURL *)url;
- (NSArray*)insertURLs:(NSArray *)urls atIndex:(int)index sort:(BOOL)sort;
//save playlist, auto-determines type based on extension. Uses m3u if it cannot be determined.
- (BOOL)save:(NSString *)filename;
@ -38,8 +38,14 @@ typedef enum {
//read info for a playlist entry
- (NSDictionary *)readEntryInfo:(PlaylistEntry *)pe;
- (void)loadInfoForEntries:(NSArray *)entries;
- (NSArray *)acceptableFileTypes;
- (NSArray *)acceptablePlaylistTypes; //Only m3u and pls saving
- (NSArray *)acceptableContainerTypes;
// Event inlets (passed to playlist controler):
- (void)willInsertFiles:(NSArray*)urls origin:(AddedFilesSource)src;
- (void)didInsertFiles:(NSArray*)entries origin:(AddedFilesSource)src;
@end

View File

@ -8,7 +8,6 @@
#import "PlaylistLoader.h"
#import "PlaylistController.h"
#import "PlaybackController.h"
#import "PlaylistEntry.h"
#import "FilePlaylistEntry.h"
#import "AppController.h"
@ -35,14 +34,7 @@
- (void)initDefaults
{
NSLog(@"INITIIALIZING PLAYLIST LOADER DEFAULTS");
NSMutableDictionary *userDefaultsValuesDict = [NSMutableDictionary dictionary];
[userDefaultsValuesDict setObject:[NSNumber numberWithBool:NO] forKey:@"playOnAdd"];
[userDefaultsValuesDict setObject:[NSNumber numberWithBool:NO] forKey:@"clearOnAdd"];
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];
[[NSUserDefaults standardUserDefaults] synchronize];
}
@ -164,7 +156,7 @@
return urls;
}
- (void)insertURLs:(NSArray *)urls atIndex:(int)index sort:(BOOL)sort
- (NSArray*)insertURLs:(NSArray *)urls atIndex:(int)index sort:(BOOL)sort
{
NSMutableSet *uniqueURLs = [NSMutableSet set];
@ -174,17 +166,11 @@
NSMutableArray *validURLs = [NSMutableArray array];
if (!urls)
return;
return [NSArray array];
if (index < 0)
index = 0;
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"clearOnAdd"]) {
[playlistController clear:self];
index = 0;
}
NSURL *url;
for (url in urls)
{
@ -305,12 +291,7 @@
//Select the first entry in the group that was just added
[playlistController setSelectionIndex:index];
[self performSelectorInBackground:@selector(loadInfoForEntries:) withObject:entries];
//Auto start playback
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"playOnAdd"] && [entries count] > 0) {
[playbackController playEntry: [entries objectAtIndex:0]];
}
return entries;
}
- (void)loadInfoForEntries:(NSArray *)entries
@ -404,14 +385,14 @@
}
}
- (void)addURLs:(NSArray *)urls sort:(BOOL)sort
- (NSArray*)addURLs:(NSArray *)urls sort:(BOOL)sort
{
[self insertURLs:urls atIndex:[[playlistController content] count] sort:sort];
return [self insertURLs:urls atIndex:[[playlistController content] count] sort:sort];
}
- (void)addURL:(NSURL *)url
- (NSArray*)addURL:(NSURL *)url
{
[self insertURLs:[NSArray arrayWithObject:url] atIndex:[[playlistController content] count] sort:NO];
return [self insertURLs:[NSArray arrayWithObject:url] atIndex:[[playlistController content] count] sort:NO];
}
- (NSArray *)acceptableFileTypes
@ -429,4 +410,13 @@
return [AudioPlayer containerTypes];
}
- (void)willInsertFiles:(NSArray*)urls origin:(AddedFilesSource)src
{
[playlistController willInsertFiles:urls origin:src];
}
- (void)didInsertFiles:(NSArray*)entries origin:(AddedFilesSource)src
{
[playlistController didInsertFiles:entries origin:src];
}
@end

View File

@ -12,14 +12,12 @@
id<CogDecoder> decoder;
int bytesPerFrame; //Number of bytes per frame, ie channels * (bitsPerSample/8)
int bytesPerSecond; //Number of bytes per second, ie bytesPerFrame * sampleRate
int bytePosition; //Current position in bytes.
long framePosition; //current position in frames
double trackStart;
double trackEnd; //miliseconds until end of track.
double trackLength; //track len in miliseconds
long trackStart;
long trackEnd; //frames until end of track.
long trackLength; //track len in frames
APLFile *apl;
}

View File

@ -23,13 +23,13 @@
NSMutableDictionary *properties = [[decoder properties] mutableCopy];
//Need to alter length
[properties setObject:[NSNumber numberWithDouble:trackLength] forKey:@"length"];
[properties setObject:[NSNumber numberWithLong:trackLength] forKey:@"totalFrames"];
return [properties autorelease];
}
- (BOOL)open:(id<CogSource>)s
{
NSLog(@"Loading apl...");
//NSLog(@"Loading apl...");
if (![[s url] isFileURL])
return NO;
@ -58,21 +58,20 @@
NSDictionary *properties = [decoder properties];
int bitsPerSample = [[properties objectForKey:@"bitsPerSample"] intValue];
int channels = [[properties objectForKey:@"channels"] intValue];
float sampleRate = [[properties objectForKey:@"sampleRate"] floatValue];
// float sampleRate = [[properties objectForKey:@"sampleRate"] floatValue];
bytesPerFrame = (bitsPerSample/8) * channels;
bytesPerSecond = (int)(bytesPerFrame * sampleRate);
if ([apl endBlock] > [apl startBlock])
trackEnd = ([apl endBlock] / sampleRate) * 1000.0;
trackEnd = [apl endBlock]; //([apl endBlock] / sampleRate) * 1000.0;
else
trackEnd = [[properties objectForKey:@"length"] doubleValue];
trackEnd = [[properties objectForKey:@"totalFrames"] doubleValue]; //!!? double?
trackStart = ([apl startBlock]/sampleRate) * 1000.0;
trackStart = [apl startBlock];
trackLength = trackEnd - trackStart;
[self seekToTime: 0.0];
[self seek: 0];
//Note: Should register for observations of the decoder, but laziness consumes all.
[self willChangeValueForKey:@"properties"];
@ -98,37 +97,32 @@
}
- (double)seekToTime:(double)time //milliseconds
- (long)seek:(long)frame
{
if (time > trackLength || time < 0) {
if (frame > trackEnd - trackStart) {
//need a better way of returning fail.
return -1.0;
return -1;
}
time += trackStart;
frame += trackStart;
bytePosition = (time/1000.0) * bytesPerSecond;
NSLog(@"Before: %li", bytePosition);
bytePosition -= bytePosition % bytesPerFrame;
NSLog(@"After: %li", bytePosition);
return [decoder seekToTime:time];
framePosition = [decoder seek:frame];
return framePosition;
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
- (int)readAudio:(void *)buf frames:(UInt32)frames
{
long trackByteEnd = (trackEnd/1000.0) * bytesPerSecond;
trackByteEnd -= trackByteEnd % (bytesPerFrame);
if (bytePosition + size > trackByteEnd)
size = trackByteEnd - bytePosition;
if (!size)
if (framePosition + frames > trackEnd)
frames = trackEnd - framePosition;
if (!frames) {
NSLog(@"APL readAudio Returning 0");
return 0;
int n = [decoder fillBuffer:buf ofSize:size];
bytePosition += n;
}
int n = [decoder readAudio:buf frames:frames];
framePosition += n;
return n;
}

View File

@ -100,19 +100,19 @@
{
[file release];
file = [self urlForPath:value relativeTo:filename];
NSLog(@"APL refers to file '%@'", file);
//NSLog(@"APL refers to file '%@'", file);
continue;
}
if (![field compare:@"Start Block" options:NSCaseInsensitiveSearch])
{
startBlock = [value intValue]; //!!! bugs with files over 2GB
NSLog(@"APL start block %d (%@)", startBlock, value);
//NSLog(@"APL start block %d (%@)", startBlock, value);
continue;
}
if (![field compare:@"Finish Block" options:NSCaseInsensitiveSearch])
{
endBlock = [value intValue]; //!!! bugs with files over 2GB
NSLog(@"APL start block %d (%@)", endBlock, value);
//NSLog(@"APL start block %d (%@)", endBlock, value);
continue;
}
}

View File

@ -143,7 +143,7 @@ The footer at the end of APE tagged files (can also optionally be at the front o
-(NSArray*) fields { return fields; }
-(NSDictionary*) convertToCogTag {
NSLog(@"Converting ape tag to cog tag");
//NSLog(@"Converting ape tag to cog tag");
NSMutableDictionary* d = [NSMutableDictionary dictionaryWithCapacity:6];
NSEnumerator *e = [fields objectEnumerator];
ApeTagItem* item;
@ -152,7 +152,7 @@ The footer at the end of APE tagged files (can also optionally be at the front o
if (![[item tag] compare:APE_TAG_FIELD_ARTIST]) { [d setObject:[item getString] forKey:@"artist"]; n++;}
if (![[item tag] compare:APE_TAG_FIELD_ALBUM]) {[d setObject:[item getString] forKey:@"album"]; n++;}
if (![[item tag] compare:APE_TAG_FIELD_TITLE]) {[d setObject:[item getString] forKey:@"title"]; n++;}
if (![[item tag] compare:APE_TAG_FIELD_TRACK]) {[d setObject:[item getString] forKey:@"track"]; n++;}
if (![[item tag] compare:APE_TAG_FIELD_TRACK]) {[d setObject:[NSNumber numberWithInt:[[item getString] intValue]] forKey:@"track"]; n++;}
if (![[item tag] compare:APE_TAG_FIELD_GENRE]) {[d setObject:[item getString] forKey:@"genre"]; n++;}
if (![[item tag] compare:APE_TAG_FIELD_YEAR]) {[d setObject:[item getString] forKey:@"year"]; n++;}
}
@ -234,7 +234,7 @@ The footer at the end of APE tagged files (can also optionally be at the front o
UInt32 flags = CFSwapInt32LittleToHost(*(uint32_t*)[f_flag bytes]);
NSData* data = [f readDataOfLength:len];
ApeTagItem* item = [ApeTagItem createTag:f_name flags:flags data:data];
NSLog(@"Read tag '%@'='%@'", [item tag], [item getString]);
//NSLog(@"Read tag '%@'='%@'", [item tag], [item getString]);
[fields addObject:item];
}
//here we should read footer and check number of fields etc. - but who cares? =)

View File

@ -219,16 +219,16 @@
if ([type isEqualToString:@"GENRE"])
{
NSLog(@"GENRE!");
//NSLog(@"GENRE!");
if ([scanner scanString:@"\"" intoString:nil]) {
NSLog(@"QUOTED");
//NSLog(@"QUOTED");
if (![scanner scanUpToString:@"\"" intoString:&genre]) {
NSLog(@"FAILED TO SCAN");
continue;
}
}
else {
NSLog(@"UNQUOTED");
//NSLog(@"UNQUOTED");
if ( ![scanner scanUpToCharactersFromSet:whitespace intoString:&genre]) {
continue;
}
@ -236,7 +236,7 @@
}
else if ([type isEqualToString:@"DATE"])
{
NSLog(@"DATE!");
//NSLog(@"DATE!");
if ( ![scanner scanUpToCharactersFromSet:whitespace intoString:&year]) {
continue;
}

View File

@ -276,9 +276,10 @@ static NSPredicate * musicOnlyPredicate = nil;
tracks = playlistController.selectedObjects;
if ([tracks count] == 0)
tracks = playlistController.arrangedObjects;
[playlistLoader addURLs:[tracks valueForKey:@"URL"] sort:NO];
[self.query enableUpdates];
[playlistLoader willInsertFiles:[tracks valueForKey:@"URL"] origin:OpenFromSpotlight];
[playlistLoader didInsertFiles:[playlistLoader addURLs:[tracks valueForKey:@"URL"] sort:NO] origin:OpenFromSpotlight];
[self.query enableUpdates];
}
#pragma mark NSMetadataQuery delegate methods