Permalink
Browse files

Completing the document-based app setup.

Multiple repositories can now be opened by using the File → Open… menu option.
Each document is a PBGitRepository with a PBDetailController controlling the window. PBRepositoryDocumentController is the document controller.
When launched, the application will attempt to open a repository with the current directory as its path. If this fails it will display an open panel to allow the user to select one.
  • Loading branch information...
1 parent 0def8d3 commit b85a2056985e841f404d0f1ea1ceabd6992e014a @ciaran ciaran committed Aug 18, 2008
View
@@ -11,12 +11,11 @@
@interface ApplicationController : NSObject
{
- IBOutlet NSWindow *window;
- IBOutlet PBGitRepository* repository;
+ IBOutlet NSWindow *window;
IBOutlet id firstResponder;
- NSPersistentStoreCoordinator *persistentStoreCoordinator;
- NSManagedObjectModel *managedObjectModel;
- NSManagedObjectContext *managedObjectContext;
+ NSPersistentStoreCoordinator *persistentStoreCoordinator;
+ NSManagedObjectModel *managedObjectModel;
+ NSManagedObjectContext *managedObjectContext;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator;
View
@@ -9,41 +9,41 @@
#import "ApplicationController.h"
#import "PBGitRevisionCell.h"
#import "PBDetailController.h"
+#import "PBRepositoryDocumentController.h"
@implementation ApplicationController
-@synthesize repository;
-
-- (ApplicationController*) init
+- (ApplicationController*)init
{
#ifndef NDEBUG
[NSApp activateIgnoringOtherApps:YES];
#endif
- if([[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/QuickLookUI.framework"] load])
- NSLog(@"Quick Look loaded!");
-
- // Find the current repository
- char* a = getenv("PWD");
- NSString* path;
- if (a != nil)
- path = [NSString stringWithCString:a];
- else {
- // Show an open dialog
- NSOpenPanel* openDlg = [NSOpenPanel openPanel];
- [openDlg setCanChooseFiles:NO];
- [openDlg setCanChooseDirectories:YES];
- if ( [openDlg runModalForDirectory:nil file:nil] == NSOKButton )
- path = [openDlg filename];
- else
- exit(1);
+ if(self = [super init]) {
+ if([[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/QuickLookUI.framework"] load])
+ NSLog(@"Quick Look loaded!");
}
-
- self.repository = [PBGitRepository repositoryWithPath:path];
- [[PBDetailController alloc] initWithRepository:self.repository];
+
return self;
}
+- (void)applicationDidFinishLaunching:(NSNotification*)notification
+{
+ // Only try to open a default document if there are no documents open already.
+ // For example, the application might have been launched by double-clicking a .git repository,
+ // or by dragging a folder to the app icon
+ if ([[[PBRepositoryDocumentController sharedDocumentController] documents] count] == 0) {
+ // Try to open the current directory as a git repository
+ NSURL *url = [NSURL fileURLWithPath:[[NSFileManager defaultManager] currentDirectoryPath]];
+ NSError *error = nil;
+ if (!url || [[PBRepositoryDocumentController sharedDocumentController] openDocumentWithContentsOfURL:url display:YES error:&error] == NO) {
+ // The current directory could not be opened (most likely it’s not a git repository)
+ // so show an open panel for the user to select a repository to view
+ [[PBRepositoryDocumentController sharedDocumentController] openDocument:self];
+ }
+ }
+}
+
- (void) windowWillClose: sender
{
[firstResponder terminate: sender];
View

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -13,6 +13,7 @@
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
911111E20E58BD5A00BF76B4 /* RepositoryWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 911111E00E58BD5A00BF76B4 /* RepositoryWindow.xib */; };
+ 911111F80E594F3F00BF76B4 /* PBRepositoryDocumentController.m in Sources */ = {isa = PBXBuildFile; fileRef = 911111F70E594F3F00BF76B4 /* PBRepositoryDocumentController.m */; };
F50FE0E30E07BE9600854FCD /* PBGitRevisionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F50FE0E20E07BE9600854FCD /* PBGitRevisionCell.m */; };
F513085B0E0740F2000C8BCD /* PBQLOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = F513085A0E0740F2000C8BCD /* PBQLOutlineView.m */; };
F561727F0E056A11001DCD79 /* diff_style.css in Resources */ = {isa = PBXBuildFile; fileRef = F561727C0E056A11001DCD79 /* diff_style.css */; };
@@ -49,6 +50,8 @@
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
8D1107320486CEB800E47090 /* GitX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GitX.app; sourceTree = BUILT_PRODUCTS_DIR; };
911111E10E58BD5A00BF76B4 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/RepositoryWindow.xib; sourceTree = "<group>"; };
+ 911111F60E594F3F00BF76B4 /* PBRepositoryDocumentController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBRepositoryDocumentController.h; sourceTree = "<group>"; };
+ 911111F70E594F3F00BF76B4 /* PBRepositoryDocumentController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBRepositoryDocumentController.m; sourceTree = "<group>"; };
F50FE0E10E07BE9600854FCD /* PBGitRevisionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitRevisionCell.h; sourceTree = "<group>"; };
F50FE0E20E07BE9600854FCD /* PBGitRevisionCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitRevisionCell.m; sourceTree = "<group>"; };
F51308590E0740F2000C8BCD /* PBQLOutlineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBQLOutlineView.h; sourceTree = "<group>"; };
@@ -209,6 +212,8 @@
77C8280C06725ACE000B614F /* ApplicationController.m */,
F57CC43F0E05E496000472E2 /* PBDetailController.h */,
F57CC4400E05E496000472E2 /* PBDetailController.m */,
+ 911111F60E594F3F00BF76B4 /* PBRepositoryDocumentController.h */,
+ 911111F70E594F3F00BF76B4 /* PBRepositoryDocumentController.m */,
);
name = Controllers;
sourceTree = "<group>";
@@ -321,6 +326,7 @@
F5DFFA6C0E075D8800617813 /* PBEasyFS.m in Sources */,
F50FE0E30E07BE9600854FCD /* PBGitRevisionCell.m in Sources */,
F5FF4E180E0829C20006317A /* PBGitRevList.m in Sources */,
+ 911111F80E594F3F00BF76B4 /* PBRepositoryDocumentController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
@@ -9,6 +9,8 @@
#import <Cocoa/Cocoa.h>
#import "PBGitRevList.h"
+extern NSString* PBGitRepositoryErrorDomain;
+
@interface PBGitRepository : NSDocument {
NSString* path;
PBGitRevList* revisionList;
View
@@ -8,10 +8,13 @@
#import "PBGitRepository.h"
#import "PBGitCommit.h"
+#import "PBDetailController.h"
#import "NSFileHandleExt.h"
#import "PBEasyPipe.h"
+NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain";
+
@implementation PBGitRepository
@synthesize path, revisionList;
@@ -43,9 +46,63 @@ + (void) initialize
NSLog(@"Could not find a git binary!");
}
-+ (PBGitRepository*) repositoryWithPath:(NSString*) path
+- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
+{
+ if (outError) {
+ *outError = [NSError errorWithDomain:PBGitRepositoryErrorDomain
+ code:0
+ userInfo:[NSDictionary dictionaryWithObject:@"Reading files is not supported." forKey:NSLocalizedFailureReasonErrorKey]];
+ }
+ return NO;
+}
+
+- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper ofType:(NSString *)typeName error:(NSError **)outError
+{
+ self.path = nil;
+
+ if (![fileWrapper isDirectory]) {
+ if (outError) {
+ NSDictionary* userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Reading files is not supported.", [fileWrapper filename]]
+ forKey:NSLocalizedRecoverySuggestionErrorKey];
+ *outError = [NSError errorWithDomain:PBGitRepositoryErrorDomain code:0 userInfo:userInfo];
+ }
+ } else {
+ NSString* repositoryPath = [[self fileURL] path];
+
+ if ([repositoryPath hasSuffix:@".git"]) {
+ self.path = repositoryPath;
+ } else {
+ // Use rev-parse to find the .git dir for the repository being opened
+ NSString* newPath = [PBEasyPipe outputForCommand:gitPath withArgs:[NSArray arrayWithObjects:@"rev-parse", @"--git-dir", nil] inDir:repositoryPath];
+ if ([newPath isEqualToString:@".git"]) {
+ self.path = [repositoryPath stringByAppendingPathComponent:@".git"];
+ } else if ([newPath length] > 0) {
+ self.path = newPath;
+ } else if (outError) {
+ NSDictionary* userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"%@ does not appear to be a git repository.", [fileWrapper filename]]
+ forKey:NSLocalizedRecoverySuggestionErrorKey];
+ *outError = [NSError errorWithDomain:PBGitRepositoryErrorDomain code:0 userInfo:userInfo];
+ }
+ }
+
+ if (self.path) {
+ revisionList = [[PBGitRevList alloc] initWithRepository:self andRevListParameters:[NSArray array]];
+ }
+ }
+
+ return self.path != nil;
+}
+
+// Overridden to create our custom window controller
+- (void)makeWindowControllers
{
+ PBDetailController* controller = [[PBDetailController alloc] initWithRepository:self];
+ [self addWindowController:controller];
+ [controller release];
+}
++ (PBGitRepository*) repositoryWithPath:(NSString*) path
+{
PBGitRepository* repo = [[PBGitRepository alloc] initWithPath: path];
return repo;
}
@@ -0,0 +1,17 @@
+//
+// PBRepositoryDocumentController.h
+// GitX
+//
+// Created by Ciarán Walsh on 15/08/2008.
+// Copyright 2008 __MyCompanyName__. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface PBRepositoryDocumentController : NSDocumentController
+{
+
+}
+
+@end
@@ -0,0 +1,21 @@
+//
+// PBRepositoryDocumentController.mm
+// GitX
+//
+// Created by Ciarán Walsh on 15/08/2008.
+// Copyright 2008 __MyCompanyName__. All rights reserved.
+//
+
+#import "PBRepositoryDocumentController.h"
+
+
+@implementation PBRepositoryDocumentController
+// This method is overridden to configure the open panel to only allow
+// selection of directories
+- (NSInteger)runModalOpenPanel:(NSOpenPanel *)openPanel forTypes:(NSArray *)extensions
+{
+ [openPanel setCanChooseFiles:NO];
+ [openPanel setCanChooseDirectories:YES];
+ return [openPanel runModalForDirectory:nil file:nil types:nil];
+}
+@end

0 comments on commit b85a205

Please sign in to comment.