// // STAppDelegate.m // Safe Terminal // // Created by Nir on 22/02/06. // Copyright 2006 Nir Soffer. All rights reserved. // #import "STAppDelegate.h" #define LocalizedString(key, comment) \ [[NSBundle bundleForClass:[STAppDelegate class]] \ localizedStringForKey:(key) value:@"" table:nil] @implementation STAppDelegate - (id)init; { if ((self = [super init])) { NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; if (! [bundleIdentifier isEqualToString:@"com.apple.Terminal"]) { [self dealloc]; return nil; } [self install]; applicationDidFinishLounching = NO; applicationDidOpenFile = NO; } return self; } - (void)install; { /* Set me as Terminal.app application delegate, and the original delegate as my delegate. This allow overiding or extending original delegate methods. */ [self setDelegate:[NSApp delegate]]; [NSApp setDelegate:self]; NSLog(@"Safe Terminal loaded."); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidFinishLounching:) name:NSApplicationDidFinishLaunchingNotification object:NSApp]; } - (void)applicationDidFinishLounching:(NSNotification *)notification; { applicationDidFinishLounching = YES; [[NSNotificationCenter defaultCenter] removeObserver:self]; if (! applicationDidOpenFile) /* Remind the application to open a new shell. I don't know why it will not open one without this call. */ [NSApp sendAction:@selector(new:) to:nil from:self]; } - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { /* Extend the original method with confirmation dialog */ int returnCode = [[self alertForFilename:filename] runModal]; if ((returnCode == NSAlertSecondButtonReturn) && ([delegate respondsToSelector:@selector(application:openFile:)])) { applicationDidOpenFile = [delegate application:theApplication openFile:filename]; return applicationDidOpenFile; } else if (! applicationDidFinishLounching) /* Terminal was launched by opening a script and the user canceled. It is likely that the user is not interested in switching to the Terminal. */ [NSApp terminate:self]; return NO; } - (NSAlert *)alertForFilename:(NSString *)filename; { /* Create an alert for filename */ NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSCriticalAlertStyle]; [alert setMessageText:[NSString stringWithFormat: LocalizedString(@"Are you sure you want to execute %@?", @"Script execution warning title"), [[NSFileManager defaultManager] displayNameAtPath:filename]]]; [alert setInformativeText: LocalizedString(@"Executing scripts might harm your computer.", @"Script execution warning informative text")]; [alert addButtonWithTitle:LocalizedString(@"Cancel", @"Script execution warning button")]; [alert addButtonWithTitle:LocalizedString(@"Execute Script", @"Script execution warning button")]; return [alert autorelease]; } - (void)setDelegate:(id)anObject; { /* By convention Cocoa objects do not retain their delegates. */ delegate = anObject; } /* Delegate implementaion */ - (void)forwardInvocation:(NSInvocation *)invocation { /* Forward anything I don't implement to the delegate */ SEL aSelector = [invocation selector]; if ([delegate respondsToSelector:aSelector]) [invocation invokeWithTarget:delegate]; else [self doesNotRecognizeSelector:aSelector]; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { /* Rquired to implement a delegate */ return [delegate methodSignatureForSelector:aSelector]; } @end