// // Proteus_AppDelegate.m // Proteus // // Created by Julian Cain on 2/15/10. // Copyright __MyCompanyName__ 2010 . All rights reserved. // #import "Proteus_AppDelegate.h" #import "PreferencesWindowController.h" @implementation Proteus_AppDelegate @synthesize window; @synthesize purple = _purple; @synthesize accounts = _accounts; @synthesize buddyController = _buddyController; @synthesize preferencesWindowController = _preferencesWindowController; - (void)awakeFromNib { [[self window] setAutorecalculatesContentBorderThickness:YES forEdge:NSMinYEdge ]; [[self window] setContentBorderThickness:32.0 forEdge:NSMinYEdge]; } - (NSString *)applicationSupportDirectory { NSArray * paths = NSSearchPathForDirectoriesInDomains( NSApplicationSupportDirectory, NSUserDomainMask, YES ); NSString * basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory() ; return [basePath stringByAppendingPathComponent:@"Proteus"]; } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { /** * Allocate the purple library. */ _purple = [[Purple alloc] init]; /** * Allocate the accounts. */ _accounts = [[NSMutableArray alloc] initWithCapacity:0]; /** * Load NSUserDefaults. */ NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults]; NSMutableArray * savedAccounts = [userDefaults mutableArrayValueForKey:@"accounts" ]; /** * Add accounts from NSUserDefaults */ [_accounts addObjectsFromArray:savedAccounts]; /** * Print supported protocols. */ NSLog(@"Supported protocols: %@", [[_purple protocols] description]); for (NSDictionary * account in self.accounts) { NSUInteger aType = [[account objectForKey:@"protocol"] unsignedIntValue ]; NSString * username = [account objectForKey:@"username"]; NSString * password = [account objectForKey:@"password"]; [self.purple enableAccountType:aType username:username password:password ]; } } /** Creates, retains, and returns the managed object model for the application by merging all of the models found in the application bundle. */ - (NSManagedObjectModel *)managedObjectModel { if (managedObjectModel) return managedObjectModel; managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; return managedObjectModel; } /** Returns the persistent store coordinator for the application. This implementation will create and return a coordinator, having added the store for the application to it. (The directory for the store is created, if necessary.) */ - (NSPersistentStoreCoordinator *) persistentStoreCoordinator { if (persistentStoreCoordinator) return persistentStoreCoordinator; NSManagedObjectModel *mom = [self managedObjectModel]; if (!mom) { NSAssert(NO, @"Managed object model is nil"); NSLog(@"%@:%s No model to generate a store from", [self class], _cmd); return nil; } NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *applicationSupportDirectory = [self applicationSupportDirectory]; NSError *error = nil; if ( ![fileManager fileExistsAtPath:applicationSupportDirectory isDirectory:NULL] ) { if (![fileManager createDirectoryAtPath:applicationSupportDirectory withIntermediateDirectories:NO attributes:nil error:&error]) { NSAssert(NO, ([NSString stringWithFormat:@"Failed to create App Support directory %@ : %@", applicationSupportDirectory,error])); NSLog(@"Error creating application support directory at %@ : %@",applicationSupportDirectory,error); return nil; } } NSURL *url = [NSURL fileURLWithPath: [applicationSupportDirectory stringByAppendingPathComponent: @"storedata"]]; persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: mom]; if (![persistentStoreCoordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error]){ [[NSApplication sharedApplication] presentError:error]; [persistentStoreCoordinator release], persistentStoreCoordinator = nil; return nil; } return persistentStoreCoordinator; } /** Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) */ - (NSManagedObjectContext *) managedObjectContext { if (managedObjectContext) return managedObjectContext; NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (!coordinator) { NSMutableDictionary *dict = [NSMutableDictionary dictionary]; [dict setValue:@"Failed to initialize the store" forKey:NSLocalizedDescriptionKey]; [dict setValue:@"There was an error building up the data file." forKey:NSLocalizedFailureReasonErrorKey]; NSError *error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict]; [[NSApplication sharedApplication] presentError:error]; return nil; } managedObjectContext = [[NSManagedObjectContext alloc] init]; [managedObjectContext setPersistentStoreCoordinator: coordinator]; return managedObjectContext; } /** Returns the NSUndoManager for the application. In this case, the manager returned is that of the managed object context for the application. */ - (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window { return [[self managedObjectContext] undoManager]; } - (NSArray *)supportedProtocols { /* * Possible keys * plugin_info_name * plugin_info_id */ return [_purple protocols]; } /** Performs the save action for the application, which is to send the save: message to the application's managed object context. Any encountered errors are presented to the user. */ - (IBAction)saveAction:(id)sender { NSError *error = nil; if (![[self managedObjectContext] commitEditing]) { NSLog(@"%@:%s unable to commit editing before saving", [self class], _cmd); } if (![[self managedObjectContext] save:&error]) { [[NSApplication sharedApplication] presentError:error]; } } - (IBAction)preferencesAction:(id)sender { if (!self.preferencesWindowController) { self.preferencesWindowController = [[[PreferencesWindowController alloc] init] autorelease ]; } [self.preferencesWindowController.window center]; [self.preferencesWindowController showWindow:nil]; } - (void)applicationWillTerminate:(NSApplication *)sender { /** * Stop the purple library. */ [self.purple stop]; } - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { if (!managedObjectContext) return NSTerminateNow; if (![managedObjectContext commitEditing]) { NSLog(@"%@:%s unable to commit editing to terminate", [self class], _cmd); return NSTerminateCancel; } if (![managedObjectContext hasChanges]) return NSTerminateNow; NSError *error = nil; if (![managedObjectContext save:&error]) { // This error handling simply presents error information in a panel with an // "Ok" button, which does not include any attempt at error recovery (meaning, // attempting to fix the error.) As a result, this implementation will // present the information to the user and then follow up with a panel asking // if the user wishes to "Quit Anyway", without saving the changes. // Typically, this process should be altered to include application-specific // recovery steps. BOOL result = [sender presentError:error]; if (result) return NSTerminateCancel; NSString *question = NSLocalizedString(@"Could not save changes while quitting. Quit anyway?", @"Quit without saves error question message"); NSString *info = NSLocalizedString(@"Quitting now will lose any changes you have made since the last successful save", @"Quit without saves error question info"); NSString *quitButton = NSLocalizedString(@"Quit anyway", @"Quit anyway button title"); NSString *cancelButton = NSLocalizedString(@"Cancel", @"Cancel button title"); NSAlert *alert = [[NSAlert alloc] init]; [alert setMessageText:question]; [alert setInformativeText:info]; [alert addButtonWithTitle:quitButton]; [alert addButtonWithTitle:cancelButton]; NSInteger answer = [alert runModal]; [alert release]; alert = nil; if (answer == NSAlertAlternateReturn) return NSTerminateCancel; } return NSTerminateNow; } /** Implementation of dealloc, to release the retained variables. */ - (void)dealloc { [window release]; [_accounts release], _accounts = nil; [_buddyController release], _buddyController = nil; [_preferencesWindowController release], _preferencesWindowController = nil; [managedObjectContext release]; [persistentStoreCoordinator release]; [managedObjectModel release]; [super dealloc]; } @end