Updated file drawer so it expands containers.

This commit is contained in:
vspader 2007-10-16 01:22:57 +00:00
parent 4cb4f5e32c
commit 7582bbef02
16 changed files with 209 additions and 77 deletions

View file

@ -4,6 +4,7 @@
#import "PlaylistController.h"
#import "PlaylistView.h"
#import "FileOutlineView.h"
#import "FileTreeDataSource.h"
#import "NDHotKeyEvent.h"
#import "AppleRemote.h"
#import "PlaylistLoader.h"

View file

@ -72,6 +72,10 @@
1791FF900CB43A2C0070BC5C /* MediaKeysApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 1791FF8E0CB43A2C0070BC5C /* MediaKeysApplication.m */; };
179790E10C087AB7001D6996 /* OpenURLPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = 179790DF0C087AB7001D6996 /* OpenURLPanel.m */; };
179790F20C087B46001D6996 /* OpenURLPanel.nib in Resources */ = {isa = PBXBuildFile; fileRef = 179790F00C087B46001D6996 /* OpenURLPanel.nib */; };
17BA9FBE0CC431890015F804 /* ContainerNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17BA9FBC0CC431890015F804 /* ContainerNode.h */; };
17BA9FBF0CC431890015F804 /* ContainerNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BA9FBD0CC431890015F804 /* ContainerNode.m */; };
17BA9FC70CC432060015F804 /* ContainedNode.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17BA9FC50CC432060015F804 /* ContainedNode.h */; };
17BA9FC80CC432060015F804 /* ContainedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BA9FC60CC432060015F804 /* ContainedNode.m */; };
17BB5CED0B8A86010009ACB1 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17BB5CEC0B8A86010009ACB1 /* AudioToolbox.framework */; };
17BB5CF90B8A86350009ACB1 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17BB5CF60B8A86350009ACB1 /* AudioUnit.framework */; };
17BB5CFA0B8A86350009ACB1 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17BB5CF70B8A86350009ACB1 /* CoreAudio.framework */; };
@ -418,6 +422,8 @@
17F94CCD0B8D090800A34E87 /* Sparkle.framework in CopyFiles */,
1791FF8F0CB43A2C0070BC5C /* MediaKeysApplication.h in CopyFiles */,
1769D7D10CC2BFF7003F455B /* FileTreeDataSource.h in CopyFiles */,
17BA9FBE0CC431890015F804 /* ContainerNode.h in CopyFiles */,
17BA9FC70CC432060015F804 /* ContainedNode.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -533,6 +539,10 @@
179790DE0C087AB7001D6996 /* OpenURLPanel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = OpenURLPanel.h; sourceTree = "<group>"; };
179790DF0C087AB7001D6996 /* OpenURLPanel.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = OpenURLPanel.m; sourceTree = "<group>"; };
179790F10C087B46001D6996 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/OpenURLPanel.nib; sourceTree = "<group>"; };
17BA9FBC0CC431890015F804 /* ContainerNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContainerNode.h; sourceTree = "<group>"; };
17BA9FBD0CC431890015F804 /* ContainerNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContainerNode.m; sourceTree = "<group>"; };
17BA9FC50CC432060015F804 /* ContainedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContainedNode.h; sourceTree = "<group>"; };
17BA9FC60CC432060015F804 /* ContainedNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContainedNode.m; sourceTree = "<group>"; };
17BB5CEC0B8A86010009ACB1 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
17BB5CF60B8A86350009ACB1 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = "<absolute>"; };
17BB5CF70B8A86350009ACB1 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
@ -1154,6 +1164,10 @@
8EFFCD530AA093AF00C458A5 /* PathNode.m */,
171678BD0AC8C39E00C28CF3 /* SmartFolderNode.h */,
171678BE0AC8C39E00C28CF3 /* SmartFolderNode.m */,
17BA9FBC0CC431890015F804 /* ContainerNode.h */,
17BA9FBD0CC431890015F804 /* ContainerNode.m */,
17BA9FC50CC432060015F804 /* ContainedNode.h */,
17BA9FC60CC432060015F804 /* ContainedNode.m */,
);
path = FileDrawer;
sourceTree = "<group>";
@ -1529,6 +1543,8 @@
179790E10C087AB7001D6996 /* OpenURLPanel.m in Sources */,
1791FF900CB43A2C0070BC5C /* MediaKeysApplication.m in Sources */,
1769D7D20CC2BFF7003F455B /* FileTreeDataSource.m in Sources */,
17BA9FBF0CC431890015F804 /* ContainerNode.m in Sources */,
17BA9FC80CC432060015F804 /* ContainedNode.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View file

@ -0,0 +1,18 @@
//
// ContainedNode.h
// Cog
//
// Created by Vincent Spader on 10/15/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "PathNode.h"
@interface ContainedNode : PathNode {
}
@end

View file

@ -0,0 +1,41 @@
//
// ContainedNode.m
// Cog
//
// Created by Vincent Spader on 10/15/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "ContainedNode.h"
@implementation ContainedNode
- (BOOL)isLeaf
{
return YES;
}
- (void)setURL:(NSURL *)u
{
[super setURL:u];
if ([u fragment])
{
[display release];
display = [[u fragment] retain];
}
}
//Disable watching for us, it doesn't matter.
- (void)startWatching
{
}
- (void)stopWatching
{
}
- (void)updatePathNotification:(NSNotification *)notification
{
}
@end

View file

@ -0,0 +1,17 @@
//
// ContainerNode.h
// Cog
//
// Created by Vincent Spader on 10/15/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "PathNode.h"
@interface ContainerNode : PathNode {
}
@end

View file

@ -0,0 +1,40 @@
//
// ContainerNode.m
// Cog
//
// Created by Vincent Spader on 10/15/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "ContainerNode.h"
#import "CogAudio/AudioContainer.h"
#import "ContainedNode.h"
@implementation ContainerNode
- (BOOL)isLeaf
{
return NO;
}
- (void)updatePath
{
NSArray *urls = [AudioContainer urlsForContainerURL:url];
NSURL *u;
NSEnumerator *e = [urls objectEnumerator];
NSMutableArray *paths = [[NSMutableArray alloc] init];
while (u = [e nextObject])
{
ContainedNode *node = [[ContainedNode alloc] initWithDataSource:dataSource url:u];
NSLog(@"Node: %@", u);
[paths addObject:node];
}
[self setSubpaths:paths];
[paths release];
}
@end

View file

@ -20,13 +20,13 @@
- (void)updatePath
{
NSArray *contents = [[[NSFileManager defaultManager] directoryContentsAtPath:path] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
NSArray *contents = [[[NSFileManager defaultManager] directoryContentsAtPath:[url path]] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
NSMutableArray *fullPaths = [[NSMutableArray alloc] init];
NSString *s;
NSEnumerator *e = [contents objectEnumerator];
while (s = [e nextObject])
{
[fullPaths addObject:[path stringByAppendingPathComponent: s]];
[fullPaths addObject:[[url path] stringByAppendingPathComponent: s]];
}
[self processPaths: fullPaths];

View file

@ -11,14 +11,14 @@
@implementation FileIconCell
- (void)setObjectValue:(id)o
- (void)setObjectValue:(PathNode *)o
{
if ([o respondsToSelector:@selector(icon)] && [o respondsToSelector:@selector(displayPath)]) {
[super setObjectValue:[o displayPath]];
if ([o respondsToSelector:@selector(icon)] && [o respondsToSelector:@selector(display)]) {
[super setObjectValue:[o display]];
[super setImage: [o icon]];
}
else {
[super setObjectValue:o];
[super setObjectValue:(id)o];
}
}

View file

@ -10,7 +10,6 @@
#import "FileIconCell.h"
#import "FileTreeDataSource.h"
@interface FileOutlineView (KFTypeSelectTableViewSupport)
- (void)findPrevious:(id)sender;
- (void)findNext:(id)sender;

View file

@ -14,25 +14,25 @@
{
FileTreeDataSource *dataSource;
NSString *path;
NSString *displayPath; //The pretty path to display.
NSURL *url;
NSString *display; //The pretty path to display.
NSImage *icon;
NSArray *subpaths;
}
- (id)initWithDataSource:(FileTreeDataSource *)ds path:(NSString *)p;
- (id)initWithDataSource:(FileTreeDataSource *)ds url:(NSURL *)u;
- (NSString *)path;
- (void)setPath:(NSString *)p;
- (NSURL *)url;
- (void)setURL:(NSURL *)url;
- (void)processPaths: (NSArray *)contents;
- (NSArray *)subpaths;
- (void)setSubpaths:(NSArray *)s;
- (NSString *)displayPath;
- (NSString *)display;
- (NSImage *)icon;
- (BOOL)isLeaf;

View file

@ -17,56 +17,42 @@
@class FileNode;
@class DirectoryNode;
@class SmartFolderNode;
@class ContainerNode;
@implementation PathNode
//From http://developer.apple.com/documentation/Cocoa/Conceptual/LowLevelFileMgmt/Tasks/ResolvingAliases.html
NSString *resolveAliases(NSString *path)
NSURL *resolveAliases(NSURL *url)
{
NSString *resolvedPath = nil;
CFURLRef url;
url = CFURLCreateWithFileSystemPath(NULL /*allocator*/, (CFStringRef)path, kCFURLPOSIXPathStyle, NO /*isDirectory*/);
if (url != NULL)
FSRef fsRef;
if (CFURLGetFSRef((CFURLRef)url, &fsRef))
{
FSRef fsRef;
if (CFURLGetFSRef(url, &fsRef))
{
Boolean targetIsFolder, wasAliased;
Boolean targetIsFolder, wasAliased;
if (FSResolveAliasFile (&fsRef, true /*resolveAliasChains*/, &targetIsFolder, &wasAliased) == noErr && wasAliased)
if (FSResolveAliasFile (&fsRef, true /*resolveAliasChains*/, &targetIsFolder, &wasAliased) == noErr && wasAliased)
{
CFURLRef resolvedUrl = CFURLCreateFromFSRef(NULL, &fsRef);
if (resolvedUrl != NULL)
{
CFURLRef resolvedUrl = CFURLCreateFromFSRef(NULL, &fsRef);
if (resolvedUrl != NULL)
{
resolvedPath = (NSString*)
CFURLCopyFileSystemPath(resolvedUrl, kCFURLPOSIXPathStyle);
CFRelease(resolvedUrl);
}
NSLog(@"Resolved...");
return [(NSURL *)resolvedUrl autorelease];
}
}
CFRelease(url);
}
if (resolvedPath==nil)
resolvedPath = [[NSString alloc] initWithString:path];
return resolvedPath;
NSLog(@"Not resolved");
return url;
}
- (id)initWithDataSource:(FileTreeDataSource *)ds path:(NSString *)p
- (id)initWithDataSource:(FileTreeDataSource *)ds url:(NSURL *)u
{
self = [super init];
if (self)
{
dataSource = ds;
[self setPath: p];
[self setURL: u];
}
return self;
@ -74,22 +60,22 @@ NSString *resolveAliases(NSString *path)
- (void)stopWatching
{
if (path)
if (url)
{
NSLog(@"Stopped watching...: %@", path);
NSLog(@"Stopped watching...: %@", [url path]);
//Remove all in one go
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
[[UKKQueue sharedFileWatcher] removePath:path];
[[UKKQueue sharedFileWatcher] removePath:[url path]];
}
}
- (void)startWatching
{
if (path)
if (url)
{
NSLog(@"WATCHING! %@ %i", path, path);
NSLog(@"WATCHING! %@", [url path]);
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(updatePathNotification:) name:UKFileWatcherRenameNotification object:nil];
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(updatePathNotification:) name:UKFileWatcherWriteNotification object:nil];
@ -99,36 +85,36 @@ NSString *resolveAliases(NSString *path)
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(updatePathNotification:) name:UKFileWatcherLinkCountChangeNotification object:nil];
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(updatePathNotification:) name:UKFileWatcherAccessRevocationNotification object:nil];
[[UKKQueue sharedFileWatcher] addPath:path];
[[UKKQueue sharedFileWatcher] addPath:[url path]];
}
}
- (void)setPath:(NSString *)p
- (void)setURL:(NSURL *)u
{
[p retain];
[u retain];
[self stopWatching];
[path release];
[url release];
path = p;
url = u;
[self startWatching];
[displayPath release];
displayPath = [[NSFileManager defaultManager] displayNameAtPath:path];
[displayPath retain];
[display release];
display = [[NSFileManager defaultManager] displayNameAtPath:[url path]];
[display retain];
[icon release];
icon = [[NSWorkspace sharedWorkspace] iconForFile:path];
icon = [[NSWorkspace sharedWorkspace] iconForFile:[url path]];
[icon retain];
[icon setSize: NSMakeSize(16.0, 16.0)];
}
- (NSString *)path
- (NSURL *)url
{
return path;
return url;
}
- (void)updatePath
@ -143,10 +129,8 @@ NSString *resolveAliases(NSString *path)
- (void)updatePathNotificationMainThread:(NSNotification *)notification
{
NSString *p = [[notification userInfo] objectForKey:@"path"];
if (p == path)
if ([p isEqualToString:[url path]])
{
NSLog(@"Update path notification: %@", [NSThread currentThread]);
[self updatePath];
[dataSource reloadPathNode:self];
@ -166,33 +150,41 @@ NSString *resolveAliases(NSString *path)
continue;
}
NSURL *u = [NSURL fileURLWithPath:s];
PathNode *newNode;
s = resolveAliases(s);
NSLog(@"Before: %@", u);
u = resolveAliases(u);
NSLog(@"After: %@", u);
if ([[s pathExtension] caseInsensitiveCompare:@"savedSearch"] == NSOrderedSame)
{
NSLog(@"Smart folder!");
newNode = [[SmartFolderNode alloc] initWithDataSource:dataSource path:s];
newNode = [[SmartFolderNode alloc] initWithDataSource:dataSource url:u];
}
else
{
BOOL isDir;
[[NSFileManager defaultManager] fileExistsAtPath:s isDirectory:&isDir];
if (!isDir && ![[AudioPlayer fileTypes] containsObject:[s pathExtension]])
[[NSFileManager defaultManager] fileExistsAtPath:[u path] isDirectory:&isDir];
if (!isDir && ![[AudioPlayer fileTypes] containsObject:[[u path] pathExtension]])
{
continue;
}
if (isDir)
{
newNode = [[DirectoryNode alloc] initWithDataSource:dataSource path: s];
newNode = [[DirectoryNode alloc] initWithDataSource:dataSource url:u];
}
else if ([[AudioPlayer containerTypes] containsObject:[[[u path] pathExtension] lowercaseString]])
{
newNode = [[ContainerNode alloc] initWithDataSource:dataSource url:u];
}
else
{
newNode = [[FileNode alloc] initWithDataSource:dataSource path: s];
newNode = [[FileNode alloc] initWithDataSource:dataSource url:u];
}
}
@ -229,9 +221,9 @@ NSString *resolveAliases(NSString *path)
return YES;
}
- (NSString *)displayPath
- (NSString *)display
{
return displayPath;
return display;
}
- (NSImage *)icon
@ -243,7 +235,7 @@ NSString *resolveAliases(NSString *path)
{
[self stopWatching];
[path release];
[url release];
[icon release];
[subpaths release];

View file

@ -20,7 +20,7 @@
- (void)updatePath
{
NSDictionary *doc = [NSDictionary dictionaryWithContentsOfFile:path];
NSDictionary *doc = [NSDictionary dictionaryWithContentsOfFile:[url path]];
NSString *rawQuery = [doc objectForKey:@"RawQuery"];
NSArray *searchPaths = [[doc objectForKey:@"SearchCriteria"] objectForKey:@"CurrentFolderPath"];

View file

@ -2,6 +2,7 @@
#import <Cocoa/Cocoa.h>
extern NSString *MovedRowsType;
extern NSString *CogUrlsPbboardType;
extern NSString *iTunesDropType;
@interface DNDArrayController : NSArrayController

View file

@ -4,6 +4,7 @@
@implementation DNDArrayController
NSString *MovedRowsType = @"MOVED_ROWS_TYPE";
NSString *CogUrlsPbboardType = @"COG_URLS_TYPE";
// @"CorePasteboardFlavorType 0x6974756E" is the "itun" type representing an iTunes plist
NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E";
@ -11,8 +12,7 @@ NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E";
- (void)awakeFromNib
{
// register for drag and drop
[tableView registerForDraggedTypes:[NSArray arrayWithObjects:MovedRowsType, NSFilenamesPboardType,
iTunesDropType, nil]];
[tableView registerForDraggedTypes:[NSArray arrayWithObjects:MovedRowsType, CogUrlsPbboardType, NSFilenamesPboardType, iTunesDropType, nil]];
}

View file

@ -66,10 +66,17 @@
row = 0;
// Determine the type of object that was dropped
NSArray *supportedtypes = [NSArray arrayWithObjects:NSFilenamesPboardType, iTunesDropType, nil];
NSArray *supportedtypes = [NSArray arrayWithObjects:CogUrlsPbboardType, NSFilenamesPboardType, iTunesDropType, nil];
NSPasteboard *pboard = [info draggingPasteboard];
NSString *bestType = [pboard availableTypeFromArray:supportedtypes];
// Get files from an file drawer drop
if ([bestType isEqualToString:CogUrlsPbboardType]) {
NSArray *urls = [NSUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:CogUrlsPbboardType]];
NSLog(@"URLS: %@", urls);
[playlistLoader insertURLs: urls atIndex:row sort:YES];
}
// Get files from a normal file drop (such as from Finder)
if ([bestType isEqualToString:NSFilenamesPboardType]) {
NSMutableArray *urls = [[NSMutableArray alloc] init];

View file

@ -200,7 +200,7 @@
while (url = [urlEnumerator nextObject])
{
//File url
if ([[self acceptableContainerTypes] containsObject:[[[url path] pathExtension] lowercaseString]]) {
if ([[self acceptableContainerTypes] containsObject:[[[url path] pathExtension] lowercaseString]] && ([url fragment] == nil)) {
if ([url isFileURL] ) {
[allURLs addObjectsFromArray:[AudioContainer urlsForContainerURL:url]];