Skip to content

Commit 9335f0e

Browse files
committed
Split out the NSDocument parts of PBGitRepository to its own class.
1 parent 4316b67 commit 9335f0e

File tree

9 files changed

+355
-274
lines changed

9 files changed

+355
-274
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// PBGitRepositoryDocument.h
3+
// GitX
4+
//
5+
// Created by Etienne on 31/07/2014.
6+
//
7+
//
8+
9+
#import <Cocoa/Cocoa.h>
10+
11+
@class PBGitRepository;
12+
@class PBGitRevSpecifier;
13+
14+
extern NSString *PBGitRepositoryDocumentType;
15+
16+
@interface PBGitRepositoryDocument : NSDocument
17+
18+
@property (nonatomic, strong, readonly) PBGitRepository *repository;
19+
20+
21+
// Scripting Bridge
22+
- (void)findInModeScriptCommand:(NSScriptCommand *)command;
23+
24+
// Responder
25+
- (IBAction)showInFinderAction:(id)sender;
26+
- (IBAction)openFilesAction:(id)sender;
27+
28+
- (IBAction)showCommitView:(id)sender;
29+
- (IBAction)showHistoryView:(id)sender;
30+
31+
- (void)selectRevisionSpecifier:(PBGitRevSpecifier *)specifier;
32+
33+
@end
Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
//
2+
// PBGitRepositoryDocument.m
3+
// GitX
4+
//
5+
// Created by Etienne on 31/07/2014.
6+
//
7+
//
8+
9+
#import "PBGitRepositoryDocument.h"
10+
#import "PBGitRepository.h"
11+
#import "PBGitWindowController.h"
12+
#import "PBGitRevSpecifier.h"
13+
#import "PBGitBinary.h"
14+
#import "GitXScriptingConstants.h"
15+
#import "GitRepoFinder.h"
16+
#import "PBGitDefaults.h"
17+
18+
NSString *PBGitRepositoryDocumentType = @"Git Repository";
19+
20+
@implementation PBGitRepositoryDocument
21+
22+
- (id)init
23+
{
24+
self = [super init];
25+
if (!self) return nil;
26+
27+
return self;
28+
}
29+
30+
- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
31+
{
32+
if (![PBGitBinary path])
33+
{
34+
if (outError) {
35+
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:[PBGitBinary notFoundError]
36+
forKey:NSLocalizedRecoverySuggestionErrorKey];
37+
*outError = [NSError errorWithDomain:PBGitRepositoryErrorDomain code:0 userInfo:userInfo];
38+
}
39+
return NO;
40+
}
41+
42+
BOOL isDirectory = FALSE;
43+
[[NSFileManager defaultManager] fileExistsAtPath:[absoluteURL path] isDirectory:&isDirectory];
44+
if (!isDirectory) {
45+
if (outError) {
46+
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:@"Reading files is not supported."
47+
forKey:NSLocalizedRecoverySuggestionErrorKey];
48+
*outError = [NSError errorWithDomain:PBGitRepositoryErrorDomain code:0 userInfo:userInfo];
49+
}
50+
return NO;
51+
}
52+
53+
_repository = [[PBGitRepository alloc] initWithURL:absoluteURL error:outError];
54+
55+
return YES;
56+
}
57+
58+
- (void)close
59+
{
60+
/* FIXME: Check that this deallocs the repo */
61+
// [revisionList cleanup];
62+
63+
[super close];
64+
}
65+
66+
- (BOOL)isDocumentEdited
67+
{
68+
return NO;
69+
}
70+
71+
- (NSString *)displayName
72+
{
73+
// Build our display name depending on the current HEAD and whether it's detached or not
74+
if (self.repository.gtRepo.isHEADDetached)
75+
return [NSString localizedStringWithFormat:@"%@ (detached HEAD)", self.repository.projectName];
76+
77+
return [NSString localizedStringWithFormat:@"%@ (branch: %@)", self.repository.projectName, [self.repository.headRef description]];
78+
}
79+
80+
- (void)makeWindowControllers
81+
{
82+
// Create our custom window controller
83+
#ifndef CLI
84+
[self addWindowController: [[PBGitWindowController alloc] initWithRepository:self.repository displayDefault:YES]];
85+
#endif
86+
}
87+
88+
- (PBGitWindowController *)windowController
89+
{
90+
if ([[self windowControllers] count] == 0)
91+
return NULL;
92+
93+
return [[self windowControllers] objectAtIndex:0];
94+
}
95+
96+
- (IBAction)showCommitView:(id)sender {
97+
[[self windowController] showCommitView:sender];
98+
}
99+
100+
- (IBAction)showHistoryView:(id)sender {
101+
[[self windowController] showHistoryView:sender];
102+
}
103+
104+
- (void)selectRevisionSpecifier:(PBGitRevSpecifier *)specifier {
105+
PBGitRevSpecifier *spec = [self.repository addBranch:specifier];
106+
self.repository.currentBranch = spec;
107+
[self showHistoryView:self];
108+
}
109+
110+
- (void)showWindows
111+
{
112+
/* see if the current appleEvent has the command line arguments from the gitx cli
113+
* this could be from an openApplication or an openDocument apple event
114+
* when opening a repository this is called before the sidebar controller gets it's awakeFromNib: message
115+
* if the repository is already open then this is also a good place to catch the event as the window is about to be brought forward
116+
*/
117+
NSAppleEventDescriptor *currentAppleEvent = [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent];
118+
119+
if (currentAppleEvent) {
120+
NSAppleEventDescriptor *eventRecord = [currentAppleEvent paramDescriptorForKeyword:keyAEPropData];
121+
122+
// on app launch there may be many repositories opening, so double check that this is the right repo
123+
NSString *path = [[eventRecord paramDescriptorForKeyword:typeFileURL] stringValue];
124+
if (path) {
125+
NSURL *workingDirectory = [NSURL URLWithString:path];
126+
if ([[GitRepoFinder gitDirForURL:workingDirectory] isEqual:[self fileURL]]) {
127+
NSAppleEventDescriptor *argumentsList = [eventRecord paramDescriptorForKeyword:kGitXAEKeyArgumentsList];
128+
[self handleGitXScriptingArguments:argumentsList inWorkingDirectory:workingDirectory];
129+
130+
// showWindows may be called more than once during app launch so remove the CLI data after we handle the event
131+
[currentAppleEvent removeDescriptorWithKeyword:keyAEPropData];
132+
}
133+
}
134+
}
135+
136+
[[[self windowController] window] setTitle:[self displayName]];
137+
138+
[super showWindows];
139+
}
140+
141+
#pragma mark -
142+
#pragma mark NSResponder methods
143+
144+
- (NSArray *)selectedURLsFromSender:(id)sender {
145+
NSArray *selectedFiles = [sender representedObject];
146+
if ([selectedFiles count] == 0)
147+
return nil;
148+
149+
NSURL *workingDirectoryURL = self.repository.workingDirectoryURL;
150+
NSMutableArray *URLs = [NSMutableArray array];
151+
for (id file in selectedFiles) {
152+
NSString *path = file;
153+
// Those can be PBChangedFiles sent by PBGitIndexController. Get their path.
154+
if ([file respondsToSelector:@selector(path)]) {
155+
path = [file path];
156+
}
157+
158+
if (![path isKindOfClass:[NSString class]])
159+
continue;
160+
[URLs addObject:[workingDirectoryURL URLByAppendingPathComponent:path]];
161+
}
162+
163+
return URLs;
164+
}
165+
166+
- (IBAction)showInFinderAction:(id)sender {
167+
NSArray *URLs = [self selectedURLsFromSender:sender];
168+
if ([URLs count] == 0)
169+
return;
170+
171+
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:URLs];
172+
}
173+
174+
- (IBAction)openFilesAction:(id)sender {
175+
NSArray *URLs = [self selectedURLsFromSender:sender];
176+
177+
if ([URLs count] == 0)
178+
return;
179+
180+
[[NSWorkspace sharedWorkspace] openURLs:URLs
181+
withAppBundleIdentifier:nil
182+
options:0
183+
additionalEventParamDescriptor:nil
184+
launchIdentifiers:NULL];
185+
}
186+
187+
#pragma mark -
188+
#pragma mark AppleScript support
189+
190+
- (void)handleRevListArguments:(NSArray *)arguments inWorkingDirectory:(NSURL *)workingDirectory
191+
{
192+
if (![arguments count])
193+
return;
194+
195+
PBGitRevSpecifier *revListSpecifier = nil;
196+
197+
// the argument may be a branch or tag name but will probably not be the full reference
198+
if ([arguments count] == 1) {
199+
PBGitRef *refArgument = [self.repository refForName:[arguments lastObject]];
200+
if (refArgument) {
201+
revListSpecifier = [[PBGitRevSpecifier alloc] initWithRef:refArgument];
202+
revListSpecifier.workingDirectory = workingDirectory;
203+
}
204+
}
205+
206+
if (!revListSpecifier) {
207+
revListSpecifier = [[PBGitRevSpecifier alloc] initWithParameters:arguments];
208+
revListSpecifier.workingDirectory = workingDirectory;
209+
}
210+
211+
self.repository.currentBranch = [self.repository addBranch:revListSpecifier];
212+
[PBGitDefaults setShowStageView:NO];
213+
[self.windowController showHistoryView:self];
214+
}
215+
216+
- (void)handleBranchFilterEventForFilter:(PBGitXBranchFilterType)filter additionalArguments:(NSMutableArray *)arguments inWorkingDirectory:(NSURL *)workingDirectory
217+
{
218+
self.repository.currentBranchFilter = filter;
219+
[PBGitDefaults setShowStageView:NO];
220+
[self.windowController showHistoryView:self];
221+
222+
// treat any additional arguments as a rev-list specifier
223+
if ([arguments count] > 1) {
224+
[arguments removeObjectAtIndex:0];
225+
[self handleRevListArguments:arguments inWorkingDirectory:workingDirectory];
226+
}
227+
}
228+
229+
- (void)handleGitXScriptingArguments:(NSAppleEventDescriptor *)argumentsList inWorkingDirectory:(NSURL *)workingDirectory
230+
{
231+
NSMutableArray *arguments = [NSMutableArray array];
232+
uint argumentsIndex = 1; // AppleEvent list descriptor's are one based
233+
while(1) {
234+
NSAppleEventDescriptor *arg = [argumentsList descriptorAtIndex:argumentsIndex++];
235+
if (arg)
236+
[arguments addObject:[arg stringValue]];
237+
else
238+
break;
239+
}
240+
241+
if (![arguments count])
242+
return;
243+
244+
NSString *firstArgument = [arguments objectAtIndex:0];
245+
246+
if ([firstArgument isEqualToString:@"-c"] || [firstArgument isEqualToString:@"--commit"]) {
247+
[PBGitDefaults setShowStageView:YES];
248+
[self.windowController showCommitView:self];
249+
return;
250+
}
251+
252+
if ([firstArgument isEqualToString:@"--all"]) {
253+
[self handleBranchFilterEventForFilter:kGitXAllBranchesFilter additionalArguments:arguments inWorkingDirectory:workingDirectory];
254+
return;
255+
}
256+
257+
if ([firstArgument isEqualToString:@"--local"]) {
258+
[self handleBranchFilterEventForFilter:kGitXLocalRemoteBranchesFilter additionalArguments:arguments inWorkingDirectory:workingDirectory];
259+
return;
260+
}
261+
262+
if ([firstArgument isEqualToString:@"--branch"]) {
263+
[self handleBranchFilterEventForFilter:kGitXSelectedBranchFilter additionalArguments:arguments inWorkingDirectory:workingDirectory];
264+
return;
265+
}
266+
267+
// if the argument is not a known command then treat it as a rev-list specifier
268+
[self handleRevListArguments:arguments inWorkingDirectory:workingDirectory];
269+
}
270+
271+
// for the scripting bridge
272+
- (void)findInModeScriptCommand:(NSScriptCommand *)command
273+
{
274+
NSDictionary *arguments = [command arguments];
275+
NSString *searchString = [arguments objectForKey:kGitXFindSearchStringKey];
276+
if (searchString) {
277+
NSInteger mode = [[arguments objectForKey:kGitXFindInModeKey] integerValue];
278+
[PBGitDefaults setShowStageView:NO];
279+
[self.windowController showHistoryView:self];
280+
[self.windowController setHistorySearch:searchString mode:mode];
281+
}
282+
}
283+
284+
@end

Classes/Controllers/PBHistorySearchController.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ - (void)startBackgroundSearch
423423
return;
424424
}
425425

426-
backgroundSearchTask = [PBEasyPipe taskForCommand:[PBGitBinary path] withArgs:searchArguments inDir:[[historyController.repository fileURL] path]];
426+
backgroundSearchTask = [PBEasyPipe taskForCommand:[PBGitBinary path] withArgs:searchArguments inDir:[[historyController.repository workingDirectoryURL] path]];
427427
[backgroundSearchTask launch];
428428

429429
NSFileHandle *handle = [[backgroundSearchTask standardOutput] fileHandleForReading];

Classes/Controllers/PBRepositoryDocumentController.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//
88

99
#import "PBRepositoryDocumentController.h"
10-
#import "PBGitRepository.h"
10+
#import "PBGitRepositoryDocument.h"
1111
#import "PBGitRevList.h"
1212
#import "PBEasyPipe.h"
1313
#import "PBGitBinary.h"
@@ -45,7 +45,7 @@ - (id)makeUntitledDocumentOfType:(NSString *)typeName error:(NSError *__autorele
4545
if (!success)
4646
return nil; // Repo creation failed
4747

48-
return [[PBGitRepository alloc] initWithContentsOfURL:[op URL] ofType:PBGitRepositoryDocumentType error:outError];
48+
return [[PBGitRepositoryDocument alloc] initWithContentsOfURL:[op URL] ofType:PBGitRepositoryDocumentType error:outError];
4949
}
5050

5151
- (BOOL)validateMenuItem:(NSMenuItem *)item

Classes/PBCLIProxy.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#import "PBGitWindowController.h"
1313
#import "PBGitBinary.h"
1414
#import "PBDiffWindowController.h"
15+
#import "PBGitRepositoryDocument.h"
1516

1617
@implementation PBCLIProxy
1718
@synthesize connection;
@@ -37,7 +38,7 @@ - (BOOL)openRepository:(NSURL*)repositoryPath arguments: (NSArray*) args error:(
3738
NSURL* url = [NSURL fileURLWithPath:[repositoryPath path]];
3839
NSArray* arguments = [NSArray arrayWithArray:args];
3940

40-
PBGitRepository *document = [[NSDocumentController sharedDocumentController] documentForURL:url];
41+
PBGitRepositoryDocument *document = [[NSDocumentController sharedDocumentController] documentForURL:url];
4142
if (!document) {
4243
if (error) {
4344
NSString *suggestion = [PBGitBinary path] ? @"this isn't a git repository" : @"GitX can't find your git binary";
@@ -52,12 +53,11 @@ - (BOOL)openRepository:(NSURL*)repositoryPath arguments: (NSArray*) args error:(
5253

5354
if ([arguments count] > 0 && ([[arguments objectAtIndex:0] isEqualToString:@"--commit"] ||
5455
[[arguments objectAtIndex:0] isEqualToString:@"-c"]))
55-
[document.windowController showCommitView:self];
56+
[document showCommitView:self];
5657
else {
5758
PBGitRevSpecifier* rev = [[PBGitRevSpecifier alloc] initWithParameters:arguments];
5859
rev.workingDirectory = url;
59-
document.currentBranch = [document addBranch: rev];
60-
[document.windowController showHistoryView:self];
60+
[document selectRevisionSpecifier:rev];
6161
}
6262
[NSApp activateIgnoringOtherApps:YES];
6363

0 commit comments

Comments
 (0)