2 // GitTest_AppDelegate.m
5 // Created by Pieter de Bie on 13-06-08.
6 // Copyright __MyCompanyName__ 2008 . All rights reserved.
9 #import "ApplicationController.h"
10 #import "PBGitRevisionCell.h"
11 #import "PBDetailController.h"
12 #import "PBRepositoryDocumentController.h"
13 #import "PBCLIProxy.h"
15 @implementation ApplicationController
18 - (ApplicationController*)init
21 [NSApp activateIgnoringOtherApps:YES];
24 if(self = [super init]) {
25 if([[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/QuickLookUI.framework"] load])
26 NSLog(@"Quick Look loaded!");
28 self.cliProxy = [PBCLIProxy new];
34 - (void)applicationDidFinishLaunching:(NSNotification*)notification
36 // Only try to open a default document if there are no documents open already.
37 // For example, the application might have been launched by double-clicking a .git repository,
38 // or by dragging a folder to the app icon
39 if ([[[PBRepositoryDocumentController sharedDocumentController] documents] count] == 0) {
40 // Try to open the current directory as a git repository
42 if([[[NSProcessInfo processInfo] environment] objectForKey:@"PWD"])
43 url = [NSURL fileURLWithPath:[[[NSProcessInfo processInfo] environment] objectForKey:@"PWD"]];
45 if (!url || [[PBRepositoryDocumentController sharedDocumentController] openDocumentWithContentsOfURL:url display:YES error:&error] == NO) {
46 // The current directory could not be opened (most likely it’s not a git repository)
47 // so show an open panel for the user to select a repository to view
48 [[PBRepositoryDocumentController sharedDocumentController] openDocument:self];
53 - (void) windowWillClose: sender
55 [firstResponder terminate: sender];
58 - (IBAction)installCliTool:(id)sender;
61 NSString* installationPath = @"/usr/bin/gitx";
62 NSString* toolPath = [[NSBundle mainBundle] pathForResource:@"gitx" ofType:@""];
64 AuthorizationRef auth;
65 if (AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth) == errAuthorizationSuccess) {
66 char const* arguments[] = { "-s", [toolPath UTF8String], [installationPath UTF8String], NULL };
67 char const* helperTool = "/bin/ln";
68 if (AuthorizationExecuteWithPrivileges(auth, helperTool, kAuthorizationFlagDefaults, (char**)arguments, NULL) == errAuthorizationSuccess) {
70 int pid = wait(&status);
71 if (pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0)
74 errno = WEXITSTATUS(status);
77 AuthorizationFree(auth, kAuthorizationFlagDefaults);
82 [[NSAlert alertWithMessageText:@"Installation Complete"
86 informativeTextWithFormat:@"The gitx tool has been installed to %@", installationPath] runModal];
88 [[NSAlert alertWithMessageText:@"Installation Failed"
92 informativeTextWithFormat:@"Installation to %@ failed", installationPath] runModal];
96 - (IBAction) switchBranch: sender
98 [[NSAlert alertWithMessageText:@"Not Supported" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"Sorry, switching branches is not supported yet"] runModal];
102 Returns the support folder for the application, used to store the Core Data
103 store file. This code uses a folder named "GitTest" for
104 the content, either in the NSApplicationSupportDirectory location or (if the
105 former cannot be found), the system's temporary directory.
108 - (NSString *)applicationSupportFolder {
110 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
111 NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
112 return [basePath stringByAppendingPathComponent:@"GitTest"];
117 Creates, retains, and returns the managed object model for the application
118 by merging all of the models found in the application bundle.
121 - (NSManagedObjectModel *)managedObjectModel {
123 if (managedObjectModel != nil) {
124 return managedObjectModel;
127 managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
128 return managedObjectModel;
133 Returns the persistent store coordinator for the application. This
134 implementation will create and return a coordinator, having added the
135 store for the application to it. (The folder for the store is created,
139 - (NSPersistentStoreCoordinator *) persistentStoreCoordinator {
141 if (persistentStoreCoordinator != nil) {
142 return persistentStoreCoordinator;
145 NSFileManager *fileManager;
146 NSString *applicationSupportFolder = nil;
150 fileManager = [NSFileManager defaultManager];
151 applicationSupportFolder = [self applicationSupportFolder];
152 if ( ![fileManager fileExistsAtPath:applicationSupportFolder isDirectory:NULL] ) {
153 [fileManager createDirectoryAtPath:applicationSupportFolder attributes:nil];
156 url = [NSURL fileURLWithPath: [applicationSupportFolder stringByAppendingPathComponent: @"GitTest.xml"]];
157 persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
158 if (![persistentStoreCoordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error]){
159 [[NSApplication sharedApplication] presentError:error];
162 return persistentStoreCoordinator;
167 Returns the managed object context for the application (which is already
168 bound to the persistent store coordinator for the application.)
171 - (NSManagedObjectContext *) managedObjectContext {
173 if (managedObjectContext != nil) {
174 return managedObjectContext;
177 NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
178 if (coordinator != nil) {
179 managedObjectContext = [[NSManagedObjectContext alloc] init];
180 [managedObjectContext setPersistentStoreCoordinator: coordinator];
183 return managedObjectContext;
188 Returns the NSUndoManager for the application. In this case, the manager
189 returned is that of the managed object context for the application.
192 - (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window {
193 return [[self managedObjectContext] undoManager];
198 Performs the save action for the application, which is to send the save:
199 message to the application's managed object context. Any encountered errors
200 are presented to the user.
203 - (IBAction) saveAction:(id)sender {
205 NSError *error = nil;
206 if (![[self managedObjectContext] save:&error]) {
207 [[NSApplication sharedApplication] presentError:error];
213 Implementation of the applicationShouldTerminate: method, used here to
214 handle the saving of changes in the application managed object context
215 before the application terminates.
218 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
221 int reply = NSTerminateNow;
223 if (managedObjectContext != nil) {
224 if ([managedObjectContext commitEditing]) {
225 if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
227 // This error handling simply presents error information in a panel with an
228 // "Ok" button, which does not include any attempt at error recovery (meaning,
229 // attempting to fix the error.) As a result, this implementation will
230 // present the information to the user and then follow up with a panel asking
231 // if the user wishes to "Quit Anyway", without saving the changes.
233 // Typically, this process should be altered to include application-specific
236 BOOL errorResult = [[NSApplication sharedApplication] presentError:error];
238 if (errorResult == YES) {
239 reply = NSTerminateCancel;
244 int alertReturn = NSRunAlertPanel(nil, @"Could not save changes while quitting. Quit anyway?" , @"Quit anyway", @"Cancel", nil);
245 if (alertReturn == NSAlertAlternateReturn) {
246 reply = NSTerminateCancel;
253 reply = NSTerminateCancel;
262 Implementation of dealloc, to release the retained variables.
267 [managedObjectContext release], managedObjectContext = nil;
268 [persistentStoreCoordinator release], persistentStoreCoordinator = nil;
269 [managedObjectModel release], managedObjectModel = nil;