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.
This commit is contained in:
Ciarán Walsh
2008-08-18 07:57:18 +01:00
parent 0def8d34d7
commit b85a205698
8 changed files with 760 additions and 584 deletions
+4 -5
View File
@@ -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;
+23 -23
View File
@@ -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 its 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];
+629 -555
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -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;
};
+2
View File
@@ -9,6 +9,8 @@
#import <Cocoa/Cocoa.h>
#import "PBGitRevList.h"
extern NSString* PBGitRepositoryErrorDomain;
@interface PBGitRepository : NSDocument {
NSString* path;
PBGitRevList* revisionList;
+58 -1
View File
@@ -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 @@ static NSString* gitPath;
NSLog(@"Could not find a git binary!");
}
- (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;
}
+17
View File
@@ -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
+21
View File
@@ -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