Merge branch 'fix_interspacing'
[GitX.git] / ApplicationController.m
blob704be1faa3e186150a8454746006f1ab4347ad69
1 //
2 //  GitTest_AppDelegate.m
3 //  GitTest
4 //
5 //  Created by Pieter de Bie on 13-06-08.
6 //  Copyright __MyCompanyName__ 2008 . All rights reserved.
7 //
9 #import "ApplicationController.h"
10 #import "PBGitRevisionCell.h"
11 #import "PBDetailController.h"
12 #import "PBRepositoryDocumentController.h"
13 #import "PBCLIProxy.h"
15 @implementation ApplicationController
16 @synthesize cliProxy;
18 - (ApplicationController*)init
20 #ifndef NDEBUG
21         [NSApp activateIgnoringOtherApps:YES];
22 #endif
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];
29         }
31         return self;
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
41                 NSURL *url = nil;
42                 if([[[NSProcessInfo processInfo] environment] objectForKey:@"PWD"])
43                         url = [NSURL fileURLWithPath:[[[NSProcessInfo processInfo] environment] objectForKey:@"PWD"]];
44                 NSError *error = nil;
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];
49                 }
50         }
53 - (void) windowWillClose: sender
55         [firstResponder terminate: sender];
58 - (IBAction)installCliTool:(id)sender;
60         BOOL success               = NO;
61         NSString* installationPath = @"/usr/bin/gitx";
62         NSString* toolPath         = [[NSBundle mainBundle] pathForResource:@"gitx" ofType:@""];
63         if (toolPath) {
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) {
69                                 int status;
70                                 int pid = wait(&status);
71                                 if (pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0)
72                                         success = true;
73                                 else
74                                         errno = WEXITSTATUS(status);
75                         }
77                         AuthorizationFree(auth, kAuthorizationFlagDefaults);
78                 }
79         }
81         if (success) {
82                 [[NSAlert alertWithMessageText:@"Installation Complete"
83                             defaultButton:nil
84                           alternateButton:nil
85                               otherButton:nil
86                 informativeTextWithFormat:@"The gitx tool has been installed to %@", installationPath] runModal];
87         } else {
88                 [[NSAlert alertWithMessageText:@"Installation Failed"
89                             defaultButton:nil
90                           alternateButton:nil
91                               otherButton:nil
92                 informativeTextWithFormat:@"Installation to %@ failed", installationPath] runModal];
93         }
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.
106  */
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.
119  */
121 - (NSManagedObjectModel *)managedObjectModel {
123     if (managedObjectModel != nil) {
124         return managedObjectModel;
125     }
126         
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, 
136     if necessary.)
137  */
139 - (NSPersistentStoreCoordinator *) persistentStoreCoordinator {
141     if (persistentStoreCoordinator != nil) {
142         return persistentStoreCoordinator;
143     }
145     NSFileManager *fileManager;
146     NSString *applicationSupportFolder = nil;
147     NSURL *url;
148     NSError *error;
149     
150     fileManager = [NSFileManager defaultManager];
151     applicationSupportFolder = [self applicationSupportFolder];
152     if ( ![fileManager fileExistsAtPath:applicationSupportFolder isDirectory:NULL] ) {
153         [fileManager createDirectoryAtPath:applicationSupportFolder attributes:nil];
154     }
155     
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];
160     }    
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.) 
169  */
171 - (NSManagedObjectContext *) managedObjectContext {
173     if (managedObjectContext != nil) {
174         return managedObjectContext;
175     }
177     NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
178     if (coordinator != nil) {
179         managedObjectContext = [[NSManagedObjectContext alloc] init];
180         [managedObjectContext setPersistentStoreCoordinator: coordinator];
181     }
182     
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.
190  */
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.
201  */
203 - (IBAction) saveAction:(id)sender {
205     NSError *error = nil;
206     if (![[self managedObjectContext] save:&error]) {
207         [[NSApplication sharedApplication] presentError:error];
208     }
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.
216  */
218 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
220     NSError *error;
221     int reply = NSTerminateNow;
222     
223     if (managedObjectContext != nil) {
224         if ([managedObjectContext commitEditing]) {
225             if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
226                                 
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 
234                 // recovery steps.  
236                 BOOL errorResult = [[NSApplication sharedApplication] presentError:error];
237                                 
238                 if (errorResult == YES) {
239                     reply = NSTerminateCancel;
240                 } 
242                 else {
243                                         
244                     int alertReturn = NSRunAlertPanel(nil, @"Could not save changes while quitting. Quit anyway?" , @"Quit anyway", @"Cancel", nil);
245                     if (alertReturn == NSAlertAlternateReturn) {
246                         reply = NSTerminateCancel;      
247                     }
248                 }
249             }
250         } 
251         
252         else {
253             reply = NSTerminateCancel;
254         }
255     }
256     
257     return reply;
262     Implementation of dealloc, to release the retained variables.
263  */
265 - (void) dealloc {
267     [managedObjectContext release], managedObjectContext = nil;
268     [persistentStoreCoordinator release], persistentStoreCoordinator = nil;
269     [managedObjectModel release], managedObjectModel = nil;
270     [super dealloc];
272 @end