jens@20: // jens@20: // URLFormatter.m jens@20: // Murky jens@20: // jens@20: // Copyright 2008 Jens Alfke. All rights reserved. jens@20: // jens@20: jens@20: #import "MYURLFormatter.h" jens@20: jens@20: jens@20: @implementation MYURLFormatter jens@20: jens@20: @synthesize allowedSchemes=_allowedSchemes; jens@20: jens@20: jens@20: - (id) init jens@20: { jens@20: self = [super init]; jens@20: if (self != nil) { jens@20: _allowedSchemes = [[NSArray alloc] initWithObjects: @"http",@"https",@"file",@"ssh",nil]; jens@20: } jens@20: return self; jens@20: } jens@20: jens@20: - (void) dealloc jens@20: { jens@20: [_allowedSchemes release]; jens@20: [super dealloc]; jens@20: } jens@20: jens@20: jens@20: - (NSString *)stringForObjectValue:(id)obj jens@20: { jens@20: if( ! [obj isKindOfClass: [NSURL class]] ) jens@20: return @""; jens@20: else if( [obj isFileURL] ) jens@20: return [obj path]; jens@20: else jens@20: return [obj absoluteString]; jens@20: } jens@20: jens@20: jens@20: - (BOOL)getObjectValue:(id *)obj forString:(NSString *)str errorDescription:(NSString **)outError jens@20: { jens@20: *obj = nil; jens@20: NSString *error = nil; jens@20: if( str.length==0 ) { jens@20: } else if( [str hasPrefix: @"/"] ) { jens@20: *obj = [NSURL fileURLWithPath: str]; jens@20: if( ! *obj ) jens@20: error = @"Invalid filesystem path"; jens@20: } else { jens@20: NSURL *url = [NSURL URLWithString: str]; jens@20: NSString *scheme = [url scheme]; jens@20: if( url && scheme == nil ) { jens@20: if( [str rangeOfString: @"."].length > 0 ) { jens@20: // Turn "foo.com/bar" into "http://foo.com/bar": jens@20: str = [@"http://" stringByAppendingString: str]; jens@20: url = [NSURL URLWithString: str]; jens@20: scheme = [url scheme]; jens@20: } else jens@20: url = nil; jens@20: } jens@20: if( ! url || ! [url path] || url.host.length==0 ) { jens@20: error = @"Invalid URL"; jens@20: } else if( _allowedSchemes && ! [_allowedSchemes containsObject: scheme] ) { jens@20: error = [@"URL protocol must be %@" stringByAppendingString: jens@20: [_allowedSchemes componentsJoinedByString: @", "]]; jens@20: } jens@20: *obj = url; jens@20: } jens@20: if( outError ) *outError = error; jens@20: return (error==nil); jens@20: } jens@20: jens@20: jens@20: + (void) beginFilePickerFor: (NSTextField*)field jens@20: { jens@20: NSParameterAssert(field); jens@20: NSOpenPanel *open = [NSOpenPanel openPanel]; jens@20: open.canChooseDirectories = YES; jens@20: open.canChooseFiles = NO; jens@20: open.requiredFileType = (id)kUTTypeDirectory; jens@20: [open beginSheetForDirectory: nil jens@20: file: nil jens@20: modalForWindow: field.window jens@20: modalDelegate: self jens@20: didEndSelector: @selector(_filePickerDidEnd:returnCode:context:) jens@20: contextInfo: field]; jens@20: } jens@20: jens@20: + (void) beginNewFilePickerFor: (NSTextField*)field jens@20: { jens@20: NSParameterAssert(field); jens@20: NSSavePanel *save = [NSSavePanel savePanel]; jens@20: [save beginSheetForDirectory: nil jens@20: file: nil jens@20: modalForWindow: field.window jens@20: modalDelegate: self jens@20: didEndSelector: @selector(_filePickerDidEnd:returnCode:context:) jens@20: contextInfo: field]; jens@20: } jens@20: jens@20: + (void) _filePickerDidEnd: (NSSavePanel*)save returnCode: (int)returnCode context: (void*)context jens@20: { jens@20: [save orderOut: self]; jens@20: if( returnCode == NSOKButton ) { jens@20: NSTextField *field = context; jens@20: field.objectValue = [NSURL fileURLWithPath: save.filename]; jens@20: } jens@20: } jens@20: jens@20: jens@20: @end