#import #import #import #import "AppKit/NSRaise.h" @implementation NSPathCell -initWithCoder: (NSCoder *) coder { self = [super initWithCoder: coder]; if (self) { if (![coder allowsKeyedCoding]) { [NSException raise:NSInvalidArgumentException format:@"%@ can not initWithCoder:%@",[self class],[coder class]]; } [self setPlaceholderString: [coder decodeObjectForKey: @"NSPlaceholderString"]]; [self setBackgroundColor: [coder decodeObjectForKey: @"NSBackgroundColor"]]; [self setPathComponentCells: [coder decodeObjectForKey: @"NSPathComponentCells"]]; [self setPathStyle: [coder decodeIntForKey: @"NSPathStyle"]]; _delegate=[coder decodeObjectForKey: @"NSDelegate"]; [self setAllowedTypes: [coder decodeObjectForKey: @"NSAllowedTypes"]]; } return self; } - (void) dealloc { [_URL release]; [_pathComponentCells release]; [_backgroundColor release]; [_allowedTypes release]; [_placeholder release]; [super dealloc]; } - (void)mouseEntered:(NSEvent *)event withFrame:(NSRect)frame inView:(NSView *)view { NSUnimplementedMethod(); } - (void)mouseExited:(NSEvent *)event withFrame:(NSRect)frame inView:(NSView *)view { NSUnimplementedMethod(); } - (NSArray *)allowedTypes { return _allowedTypes; } - (void)setAllowedTypes:(NSArray *)value { value=[value copy]; [_allowedTypes release]; _allowedTypes=value; } -(NSPathStyle)pathStyle { return _pathStyle; } -(void)setPathStyle:(NSPathStyle)style { _pathStyle = style; [[self controlView] setNeedsDisplay: YES]; } - objectValue { return [self URL]; } - (void)setObjectValue:(id )valueX { id value=(id)valueX; if([(id)value isKindOfClass: [NSURL class]]) [self setURL:(id)value]; else if([(id)value isKindOfClass: [NSString class]]) [self setURL:[NSURL fileURLWithPath:(id)value]]; [NSException raise:NSInvalidArgumentException format:@"-[%@ %s] only accepts URL's and strings, class=%@",[self class],_cmd,[(id)value class]]; } -(NSAttributedString *)placeholderAttributedString { return _placeholder; } -(void)setPlaceholderAttributedString:(NSAttributedString *)value { value=[value copy]; [_placeholder release]; _placeholder=value; } -(NSString *)placeholderString { return [_placeholder string]; } -(void)setPlaceholderString:(NSString *)string { [self setPlaceholderAttributedString: [[[NSAttributedString alloc] initWithString: string] autorelease]]; } -(NSColor *)backgroundColor { return _backgroundColor; } -(void)setBackgroundColor:(NSColor *)color { color=[color copy]; [_backgroundColor release]; _backgroundColor=color; } +(Class)pathComponentCellClass { return [NSPathComponentCell class]; } -(NSRect)rectOfPathComponentCell:(NSPathComponentCell *)cell withFrame:(NSRect)frame inView:(NSView *)view { NSRect rect=frame; for(NSPathComponentCell *check in _pathComponentCells){ rect.size.width = [check cellSize].width; if(cell==check) return rect; switch([self pathStyle]){ case NSPathStyleStandard: rect.origin.x += rect.size.width; break; case NSPathStyleNavigationBar: // Navigation style components butt up against each other rect.origin.x+=rect.size.width; break; case NSPathStylePopUp: break; } } return NSZeroRect; } -(NSPathComponentCell *)pathComponentCellAtPoint:(NSPoint)point withFrame:(NSRect)frame inView:(NSView *)view { for (NSPathComponentCell *cell in _pathComponentCells) { NSRect checkFrame=[self rectOfPathComponentCell: cell withFrame: frame inView: view]; if(NSMouseInRect(point,checkFrame,[view isFlipped] )) return cell; } return nil; } -(BOOL)trackMouse:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp { do { NSPoint point=[controlView convertPoint:[event locationInWindow] fromView:nil]; [_clickPathComponentCell release]; _clickPathComponentCell=[[self pathComponentCellAtPoint:point withFrame:cellFrame inView:controlView] retain]; [controlView setNeedsDisplay:YES]; event=[[controlView window] nextEventMatchingMask:NSLeftMouseUpMask|NSLeftMouseDraggedMask]; } while ([event type] != NSLeftMouseUp); return (_clickPathComponentCell!=nil); } - (NSPathComponentCell *)clickedPathComponentCell { return _clickPathComponentCell; } -(NSArray *)pathComponentCells { return _pathComponentCells; } - (void)setPathComponentCells:(NSArray *)cells { cells=[cells retain]; [_pathComponentCells release]; _pathComponentCells=cells; [_clickPathComponentCell release]; _clickPathComponentCell=nil; [[self controlView] setNeedsDisplay: YES]; } - (SEL)doubleAction { return _doubleAction; } - (void)setDoubleAction:(SEL)action { _doubleAction = action; } -(NSURL *)URL { return _URL; } -(void)setURL:(NSURL *)url { url=[url copy]; [_URL release]; _URL=url; NSMutableArray *cells=[NSMutableArray array]; if (url!=nil) { NSFileManager *fm = [NSFileManager defaultManager]; NSWorkspace *ws = [NSWorkspace sharedWorkspace]; BOOL isFileURL = [url isFileURL]; NSString *host = [url host]; NSString *path = [url path]; NSString *scheme = [url scheme]; Class pcClass = [[self class] pathComponentCellClass]; NSArray *pathComponents = [path pathComponents]; NSMutableString *currentPath = [NSMutableString string]; for (NSString *path in pathComponents) { [currentPath appendString: @"/"]; [currentPath appendString: path]; NSURL *currentURL = [[[NSURL alloc] initWithScheme: scheme host: host path: currentPath] autorelease]; NSString *title; NSImage *image; if (isFileURL) { title = [fm displayNameAtPath: currentPath]; image = [ws iconForFile: currentPath]; } else { title=[path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; image=nil; } NSPathComponentCell *cell = [[[pcClass alloc] initTextCell: nil] autorelease]; [cell setURL: currentURL]; [cell setImage: image]; [cell setStringValue: title]; [cells addObject: cell]; } } [self setPathComponentCells: cells]; } -delegate { return _delegate; } -(void)setDelegate:(id)delegate { _delegate = delegate; } -(void)drawWithFrame:(NSRect)frame inView:(NSView *)view { [_backgroundColor set]; [NSBezierPath fillRect: frame]; // Draw them last to first to get the proper overlapping arrows drawing NSInteger count=[_pathComponentCells count]; while(--count>=0){ NSPathComponentCell *cell=[_pathComponentCells objectAtIndex:count]; NSRect cellFrame = [self rectOfPathComponentCell: cell withFrame: frame inView: view]; [cell drawWithFrame: cellFrame inView: view]; } } @end