This is File.m in view mode; [Download] [Up]
#pragma .h #import <Foundation/NSString.h>
#pragma .h #import <IconKit/iconkit.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSPathUtilities.h>
#import <Foundation/NSProcessInfo.h>
#import <AppKit/NSWorkspace.h>
#import "File.h"
#import "FileList.h"
#pragma .h typedef struct _FileFlags {
#pragma .h unsigned int imageLoaded:1;
#pragma .h unsigned int acceptingDragImageLoaded:1;
#pragma .h unsigned int parentLoaded:1;
#pragma .h unsigned int childrenLoaded:1;
#pragma .h } FileFlags;
@implementation File: IKFolder
{
NSString *path;
FileFlags fileFlags;
}
static NSImage *draggedImage = nil;
static NSMutableDictionary *fileMap = nil;
+ (void)initialize
{
if (self == [File class]) {
fileMap = [[NSMutableDictionary alloc] init];
}
return;
}
+ multipleSelectionClass
{
return [FileList class];
}
+ (NSArray *) pasteTypes
{
static NSMutableArray *pasteTypes = nil;
if(pasteTypes == nil) {
pasteTypes = [[NSMutableArray alloc] init];
[pasteTypes addObject:NSFilenamesPboardType];
[pasteTypes addObject:IKidPboardType()];
}
return pasteTypes;
}
+ fileForPath: (NSString *) thePath
{
// <<HACK>> This is really bad since files which we fetched once will never go away !
// But right now we have bigger fish to fry...so ignor this ugly piece of code.
id file = [fileMap objectForKey: thePath];
if( !file )
{
file = [[File alloc] initPath: thePath];
[fileMap setObject:file forKey:thePath];
}
else
{
// Just retain it once more so taht we can release it again
[file retain];
}
return [file autorelease];
}
- initPath: (NSString *) thePath
{
// <<HACK>> Method name should be changed ! initWithPath or initWithFile etc...
NSString * title = [thePath lastPathComponent];
NSDictionary * dict;
if( !title )
return nil;
// <<HACK>> This does not work properly with WindowsNT !!! Too hardcoded !
else if( [title isEqual:@""] ||
[title isEqual:@"/"] )
title = [[NSProcessInfo processInfo] hostName];
// Now we can be sure that the title is what we expect it to be...
self = [super init:title];
if( !self ) return nil;
path = [thePath retain];
// This could be wrapped in "isDictionray" on the MiscKit..
dict = [[NSFileManager defaultManager] fileAttributesAtPath:path traverseLink:NO];
flags.dragAccepting = [[dict fileType] isEqual:NSFileTypeDirectory];
flags.leaf = !flags.dragAccepting;
flags.hidden = NO;
fileFlags.imageLoaded = NO;
fileFlags.acceptingDragImageLoaded = NO;
fileFlags.parentLoaded = NO;
fileFlags.childrenLoaded = !flags.dragAccepting;
return self;
}
- copyWithZone: (NSZone *) zone;
{
File *copy = [super copyWithZone: zone];
copy->path = [path copyWithZone:zone];
copy->fileFlags = fileFlags;
return copy;
}
- (void)dealloc
{
[path release];
[super dealloc];
}
- image
{
if (!fileFlags.imageLoaded)
image = draggedImage
? [draggedImage retain]
: [[[NSWorkspace sharedWorkspace] iconForFile:path] retain];
fileFlags.imageLoaded = 1;
return image;
}
- (NSString *) path
{
return path;
}
- parents
{
NSString *directory;
if (!fileFlags.parentLoaded) {
fileFlags.parentLoaded = 1;
directory = [path stringByDeletingLastPathComponent];
if([directory isEqual:@""]) {
[[File fileForPath:@"/"] addChild: self];
} else {
[[File fileForPath:directory] addChild: self];
}
}
return parents;
}
- (void)addParent: parent
{
fileFlags.parentLoaded = 1;
[super addParent: parent];
}
- (void)removeChild:child withAnnouncement:(BOOL)yesNo
{
NSEnumerator *enumerator = [fileMap keyEnumerator];
NSString *key, *p = [child path];
fileFlags.childrenLoaded = 0;
while(key = [enumerator nextObject]) {
if([key hasPrefix:p]) {
[fileMap removeObjectForKey:key];
}
}
[fileMap removeObjectForKey:p];
[super removeChild:child withAnnouncement:yesNo];
}
- children
{
int i, count;
if (!fileFlags.childrenLoaded) {
NSArray *files = [[NSFileManager defaultManager] directoryContentsAtPath:path];
fileFlags.childrenLoaded = 1;
[users setSendAnnouncements: NO];
for(i = 0, count = [files count]; i < count; i++) {
NSString *s = [files objectAtIndex:i];
[self addChild: [File fileForPath:[path stringByAppendingPathComponent:s]]];
}
[users setSendAnnouncements: YES];
}
return children;
}
- (void)copyToPasteboard: (NSPasteboard *) pboard
{
[super copyToPasteboard: pboard];
[pboard addTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil];
[pboard setPropertyList:[NSArray arrayWithObject:path] forType:NSFilenamesPboardType];
}
+ readFromPasteboard: (NSPasteboard *) pboard
{
id file = nil;
if ((file = [super readFromPasteboard: pboard]) == nil && [pboard availableTypeFromArray:[NSArray arrayWithObject:NSFilenamesPboardType]] != NULL) {
id a = [pboard propertyListForType:NSFilenamesPboardType];
if([a isKindOfClass:[NSString class]]) {
file = [File fileForPath:a];
} else if([a isKindOfClass:[NSArray class]]) {
if([a count] > 1) {
file = [FileList readFromPasteboard:pboard];
} else {
file = [File fileForPath:[a objectAtIndex:0]];
}
}
}
return file;
}
/* shelf listener methods */
+ (void)shelf:sender dragWillEnter: (id <NSDraggingInfo>) source
{
draggedImage = [[source draggedImage] copy];
}
+ (void)shelf:sender dragWillExit: (id <NSDraggingInfo>) source
{
[draggedImage release];
draggedImage = nil;
}
+ (void)shelf:sender dragWillComplete: (id <NSDraggingInfo>) source
{
[draggedImage release];
draggedImage = nil;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.