// // RelatedFilesArrayController.m // Pennyworth Punch Clock // // Created by Chris Karr on 8/6/08. // Copyright 2008 Northwestern University. All rights reserved. // #import "RelatedFilesArrayController.h" #import "DocumentManager.h" #import "AppDelegate.h" @implementation RelatedFilesArrayController @synthesize state; - (NSString *) commentForPath:(NSString *) path { NSString * scriptString = [NSString stringWithFormat:@"tell application \"Finder\" to return the comment of alias (POSIX file \"%@\" as text)", path]; NSAppleScript * script = [[NSAppleScript alloc] initWithSource:scriptString]; NSAppleEventDescriptor * desc = [script executeAndReturnError:nil]; [script release]; return [desc stringValue]; } - (void) setComment:(NSString *) comment forPath:(NSString *) path { NSString * scriptString = [NSString stringWithFormat:@"tell application \"Finder\" to set the comment of alias (POSIX file \"%@\" as text) to \"%@\"", path, comment]; NSAppleScript * script = [[NSAppleScript alloc] initWithSource:scriptString]; [script executeAndReturnError:nil]; [script release]; } - (void) update:(NSNotification *) theNote { [[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateState:) userInfo:nil repeats:NO] retain]; } - (void) updateState:(NSTimer *) theTimer { [theTimer release]; self.state = [((AppDelegate *) [NSApp delegate]) getActiveState]; NSMutableString * predicateString = [NSMutableString string]; for (NSString * key in [self.state allKeys]) { NSString * queryString = [NSString stringWithFormat:@"kMDItemFinderComment = '*%@ = %@*'", key, [self.state valueForKey:key], nil]; if ([predicateString length] > 0) [predicateString appendString:@" || "]; [predicateString appendString:queryString]; } NSTask * searchTask = [[NSTask alloc] init]; NSPipe * stdoutPipe = [NSPipe pipe]; [searchTask setStandardOutput:stdoutPipe]; [searchTask setLaunchPath:@"/usr/bin/mdfind"]; [searchTask setArguments:[NSArray arrayWithObject:predicateString]]; NSFileHandle * out = [[stdoutPipe fileHandleForReading] retain]; [searchTask launch]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(findDone:) name:NSFileHandleReadToEndOfFileCompletionNotification object:nil]; [out readToEndOfFileInBackgroundAndNotify]; } - (IBAction) clearSelectedObjects:(id) sender { for (NSDictionary * item in [self selectedObjects]) { NSString * path = [item valueForKey:PATH]; NSMutableString * comment = [NSMutableString stringWithString:[self commentForPath:path]]; for (NSString * key in [self.state allKeys]) { NSString * tag = [NSString stringWithFormat:@"%@ = %@;", key, [self.state valueForKey:key], nil]; if ([comment rangeOfString:tag].location != NSNotFound) [comment replaceOccurrencesOfString:tag withString:@"" options:0 range:NSMakeRange (0, [comment length])]; } [self setComment:comment forPath:path]; } [self update:nil]; } - (IBAction) revealInFinder:(id) sender { NSWorkspace * workspace = [NSWorkspace sharedWorkspace]; for (NSDictionary * item in [self selectedObjects]) { NSString * path = [item valueForKey:PATH]; [workspace selectFile:path inFileViewerRootedAtPath:nil]; } } - (void) awakeFromNib { [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(update:) name:PREDICTION_FETCHED object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update:) name:PREDICTION_FETCHED object:nil]; } - (void) findDone: (NSNotification *) notification { [self willChangeValueForKey:@"arrangedObjects"]; [[NSNotificationCenter defaultCenter] removeObserver:self name:NSFileHandleReadToEndOfFileCompletionNotification object:nil]; NSDictionary * userInfo = [notification userInfo]; NSData * importData = [userInfo valueForKey:NSFileHandleNotificationDataItem]; NSString * results = [[NSString alloc] initWithData:importData encoding:NSUTF8StringEncoding]; [self removeObjects:[self arrangedObjects]]; for (NSString * path in [results componentsSeparatedByString:@"\n"]) { if (path != nil && ![path isEqual:@""]) { NSString * fileApp = nil; NSString * fileType = nil; if ([[NSWorkspace sharedWorkspace] getInfoForFile:path application:&fileApp type:&fileType]) { NSMutableDictionary * fileDict = [NSMutableDictionary dictionary]; [fileDict setValue:path forKey:PATH]; [fileDict setValue:fileApp forKey:APP]; [fileDict setValue:fileType forKey:TYPE]; [fileDict setValue:[path lastPathComponent] forKey:NAME]; [self addObject:fileDict]; } } } [results release]; [self didChangeValueForKey:@"arrangedObjects"]; } - (BOOL)tableView:(NSTableView *) tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard { return NO; } - (NSDragOperation) tableView:(NSTableView *) tv validateDrop:(id )info proposedRow:(int) row proposedDropOperation:(NSTableViewDropOperation) op { NSArray * paths = [[info draggingPasteboard] propertyListForType:NSFilenamesPboardType]; for (NSString * path in paths) { BOOL found = NO; for (NSDictionary * file in [self arrangedObjects]) { if ([[file valueForKey:PATH] isEqual:path]) found = YES; } if (!found) return NSDragOperationEvery; } return NSDragOperationNone; } - (BOOL) tableView:(NSTableView *) tableView acceptDrop:(id ) info row:(int) row dropOperation:(NSTableViewDropOperation) operation { NSArray * paths = [[info draggingPasteboard] propertyListForType:NSFilenamesPboardType]; for (NSString * path in paths) { NSString * fileApp = nil; NSString * fileType = nil; if ([[NSWorkspace sharedWorkspace] getInfoForFile:path application:&fileApp type:&fileType]) { NSMutableDictionary * fileDict = [NSMutableDictionary dictionary]; [fileDict setValue:path forKey:PATH]; [fileDict setValue:fileApp forKey:APP]; [fileDict setValue:fileType forKey:TYPE]; [fileDict setValue:[path lastPathComponent] forKey:NAME]; [self addObject:fileDict]; NSMutableString * comment = [NSMutableString string]; NSString * currentComment = [self commentForPath:path]; if (currentComment != nil) [comment appendString:currentComment]; for (NSString * key in [self.state allKeys]) { for (NSString * value in [self.state valueForKey:key]) { NSString * tag = [NSString stringWithFormat:@"%@ = %@; ", key, value, nil]; if ([comment rangeOfString:tag].location == NSNotFound) [comment appendString:tag]; } } [self setComment:comment forPath:path]; } } return YES; } @end