From 0da73789eba4e699ad7aa3987cfbf160b7e2adb8 Mon Sep 17 00:00:00 2001 From: David Catmull Date: Fri, 10 Jun 2011 17:12:50 -0600 Subject: [PATCH 01/16] saner method name --- PBWebHistoryController.h | 4 ++-- PBWebHistoryController.m | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/PBWebHistoryController.h b/PBWebHistoryController.h index f7a7cf8..a692aad 100644 --- a/PBWebHistoryController.h +++ b/PBWebHistoryController.h @@ -1,5 +1,5 @@ // -// PBWebGitController.h +// PBWebHistoryController.h // GitTest // // Created by Pieter de Bie on 14-06-08. @@ -28,7 +28,7 @@ - (void) sendKey: (NSString*) key; - (NSString *)parseHeader:(NSString *)txt withRefs:(NSString *)badges; - (NSMutableDictionary *)parseStats:(NSString *)txt; -- (NSString *) someMethodThatReturnsSomeHashForSomeString:(NSString*)concat; +- (NSString *) arbitraryHashForString:(NSString*)concat; - (void) openFileMerge:(NSString*)file sha:(NSString *)sha sha2:(NSString *)sha2; @property (readonly) NSString* diff; diff --git a/PBWebHistoryController.m b/PBWebHistoryController.m index f8ccead..85599f8 100644 --- a/PBWebHistoryController.m +++ b/PBWebHistoryController.m @@ -1,5 +1,5 @@ // -// PBWebGitController.m +// PBWebHistoryController.m // GitTest // // Created by Pieter de Bie on 14-06-08. @@ -189,7 +189,7 @@ if(![email isEqualToString:last_mail]){ [auths appendString:[NSString stringWithFormat:@"
",rol]]; if([self isFeatureEnabled:@"gravatar"]){ - NSString *hash=[self someMethodThatReturnsSomeHashForSomeString:email]; + NSString *hash=[self arbitraryHashForString:email]; [auths appendString:[NSString stringWithFormat:@"",hash]]; } [auths appendString:[NSString stringWithFormat:@"

%@ (%@)

",name,rol]]; @@ -204,7 +204,7 @@ return [NSString stringWithFormat:@"",refs,subject,auths,badges]; } -- (NSString *) someMethodThatReturnsSomeHashForSomeString:(NSString*)concat { +- (NSString *) arbitraryHashForString:(NSString*)concat { const char *concat_str = [concat UTF8String]; unsigned char result[CC_MD5_DIGEST_LENGTH]; CC_MD5(concat_str, strlen(concat_str), result); From 9f983766ddd00b3e3ba49668683653ae7c956301 Mon Sep 17 00:00:00 2001 From: David Catmull Date: Fri, 10 Jun 2011 17:35:31 -0600 Subject: [PATCH 02/16] start on refactoring PBWebHistoryController --- PBWebCommitController.h | 31 +++++ PBWebCommitController.m | 286 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 317 insertions(+) create mode 100644 PBWebCommitController.h create mode 100644 PBWebCommitController.m diff --git a/PBWebCommitController.h b/PBWebCommitController.h new file mode 100644 index 0000000..0cd4af4 --- /dev/null +++ b/PBWebCommitController.h @@ -0,0 +1,31 @@ +// +// PBWebCommitController.h +// +// Created by David Catmull on 10-06-11. +// + +#import +#import "PBWebController.h" + +#import "PBRefContextDelegate.h" + + +@class NSString; +@class PBGitCommit; + +@interface PBWebCommitController : PBWebController { + IBOutlet id contextMenuDelegate; + + NSString* currentSha; + NSString* diff; +} + +- (void) changeContentTo: (PBGitCommit *) content; +- (void) sendKey: (NSString*) key; +- (NSString *)parseHeader:(NSString *)txt withRefs:(NSString *)badges; +- (NSMutableDictionary *)parseStats:(NSString *)txt; +- (NSString *) arbitraryHashForString:(NSString*)concat; +- (void) openFileMerge:(NSString*)file sha:(NSString *)sha sha2:(NSString *)sha2; + +@property (readonly) NSString* diff; +@end diff --git a/PBWebCommitController.m b/PBWebCommitController.m new file mode 100644 index 0000000..cb955db --- /dev/null +++ b/PBWebCommitController.m @@ -0,0 +1,286 @@ +// +// PBWebCommitController.m +// +// Created by David Catmull on 10-06-11. +// + +#import "PBWebCommitController.h" +#import "PBGitCommit.h" +#import "PBGitDefaults.h" +#import "GLFileView.h" +#import + +@implementation PBWebCommitController + +@synthesize diff; + +- (void) awakeFromNib +{ + startFile = @"history"; + [super awakeFromNib]; +} + +- (void)closeView +{ + [[self script] setValue:nil forKey:@"commit"]; + + [super closeView]; +} + +- (void) didLoad +{ + currentSha = nil; +} + +- (void) changeContentTo: (PBGitCommit *) content +{ + if (content == nil || !finishedLoading) + return; + + currentSha = [content sha]; + + // Now we load the extended details. We used to do this in a separate thread, + // but this caused some funny behaviour because NSTask's and NSThread's don't really + // like each other. Instead, just do it async. + + NSMutableArray *taskArguments = [NSMutableArray arrayWithObjects:@"show", @"--numstat", @"--summary", @"--pretty=raw", currentSha, nil]; + if (![PBGitDefaults showWhitespaceDifferences]) + [taskArguments insertObject:@"-w" atIndex:1]; + + NSFileHandle *handle = [repository handleForArguments:taskArguments]; + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + // Remove notification, in case we have another one running + [nc removeObserver:self name:NSFileHandleReadToEndOfFileCompletionNotification object:nil]; + [nc addObserver:self selector:@selector(commitDetailsLoaded:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; + [handle readToEndOfFileInBackgroundAndNotify]; +} + +- (void)commitDetailsLoaded:(NSNotification *)notification +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSFileHandleReadToEndOfFileCompletionNotification object:nil]; + + NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem]; + if (!data) + return; + + NSString *details = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (!details) + details = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding]; + + if (!details) + return; + + // Header + NSString *header = [self parseHeader:details withRefs:[self refsForCurrentCommit]]; + + // File Stats + NSMutableDictionary *stats = [self parseStats:details]; + + // File list + NSString *dt = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"-r", @"-C90%", @"-M90%", currentSha, nil]]; + NSString *fileList = [GLFileView parseDiffTree:dt withStats:stats]; + + // Diffs list + NSString *d = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"--cc", @"-C90%", @"-M90%", currentSha, nil]]; + NSString *diffs = [GLFileView parseDiff:d]; + + NSString *html = [NSString stringWithFormat:@"%@%@
%@
",header,fileList,diffs]; + + html = [html stringByReplacingOccurrencesOfString:@"{SHA_PREV}" withString:[NSString stringWithFormat:@"%@^",currentSha]]; + html = [html stringByReplacingOccurrencesOfString:@"{SHA}" withString:currentSha]; + + [[view windowScriptObject] callWebScriptMethod:@"showCommit" withArguments:[NSArray arrayWithObject:html]]; + +#ifdef DEBUG_BUILD + NSString *dom = [(DOMHTMLElement*)[[[view mainFrame] DOMDocument] documentElement] outerHTML]; + NSString *tmpFile = @"~/tmp/test2.html"; + [dom writeToFile:[tmpFile stringByExpandingTildeInPath] atomically:true encoding:NSUTF8StringEncoding error:nil]; +#endif +} + +- (NSString*) refsForCurrentCommit +{ + return @""; +} + +- (NSMutableDictionary *)parseStats:(NSString *)txt +{ + NSArray *lines = [txt componentsSeparatedByString:@"\n"]; + NSMutableDictionary *stats=[NSMutableDictionary dictionary]; + int black=0; + for(NSString *line in lines){ + if([line length]==0){ + black++; + }else if(black==2){ + NSArray *file=[line componentsSeparatedByString:@"\t"]; + if([file count]==3){ + [stats setObject:file forKey:[file objectAtIndex:2]]; + } + } + } + return stats; +} + +- (NSString *)parseHeader:(NSString *)txt withRefs:(NSString *)badges +{ + NSArray *lines = [txt componentsSeparatedByString:@"\n"]; + NSString *line; + NSString *last_mail=@""; + NSMutableString *auths=[NSMutableString string]; + NSMutableString *refs=[NSMutableString string]; + NSMutableString *subject=[NSMutableString string]; + BOOL subj=FALSE; + + int i; + for (i=0; i<[lines count]; i++) { + line=[lines objectAtIndex:i]; + if([line length]==0){ + if(!subj){ + subj=TRUE; + }else{ + i=[lines count]; + } + }else{ + if (subj) { + NSString *trimmedLine = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + [subject appendString:[NSString stringWithFormat:@"%@
",[GLFileView escapeHTML:trimmedLine]]]; + }else{ + NSArray *comps=[line componentsSeparatedByString:@" "]; + if([comps count]==2){ + [refs appendString:[NSString stringWithFormat:@"%@%@",[comps objectAtIndex:0],[comps objectAtIndex:1]]]; + }else if([comps count]>2){ + NSRange r_email_i = [line rangeOfString:@"<"]; + NSRange r_email_e = [line rangeOfString:@">"]; + NSRange r_name_i = [line rangeOfString:@" "]; + + NSString *rol=[line substringToIndex:r_name_i.location]; + NSString *name=[line substringWithRange:NSMakeRange(r_name_i.location,(r_email_i.location-r_name_i.location))]; + NSString *email=[line substringWithRange:NSMakeRange(r_email_i.location+1,((r_email_e.location-1)-r_email_i.location))]; + + NSArray *t=[[line substringFromIndex:r_email_e.location+2] componentsSeparatedByString:@" "]; + NSDate *date=[NSDate dateWithTimeIntervalSince1970:[[t objectAtIndex:0] doubleValue]]; + NSDateFormatter* theDateFormatter = [[NSDateFormatter alloc] init]; + [theDateFormatter setDateStyle:NSDateFormatterMediumStyle]; + [theDateFormatter setTimeStyle:NSDateFormatterMediumStyle]; + NSString *dateString=[theDateFormatter stringForObjectValue:date]; + + if(![email isEqualToString:last_mail]){ + [auths appendString:[NSString stringWithFormat:@"
",rol]]; + if([self isFeatureEnabled:@"gravatar"]){ + NSString *hash=[self arbitraryHashForString:email]; + [auths appendString:[NSString stringWithFormat:@"",hash]]; + } + [auths appendString:[NSString stringWithFormat:@"

%@ (%@)

",name,rol]]; + [auths appendString:[NSString stringWithFormat:@"

%@

",dateString]]; + } + last_mail=email; + } + } + } + } + + return [NSString stringWithFormat:@"",refs,subject,auths,badges]; +} + +- (NSString *) arbitraryHashForString:(NSString*)concat { + const char *concat_str = [concat UTF8String]; + unsigned char result[CC_MD5_DIGEST_LENGTH]; + CC_MD5(concat_str, strlen(concat_str), result); + + NSMutableString *hash = [NSMutableString string]; + + int i; + for (i = 0; i < 16; i++) + [hash appendFormat:@"%02x", result[i]]; + + return hash; +} + +- (void)selectCommit:(NSString *)sha +{ +} + +// TODO: need to be refactoring +- (void) openFileMerge:(NSString*)file sha:(NSString *)sha sha2:(NSString *)sha2 +{ + NSArray *args=[NSArray arrayWithObjects:@"difftool",@"--no-prompt",@"--tool=opendiff",sha,sha2,@"--",file,nil]; + [repository handleInWorkDirForArguments:args]; +} + + +- (void) sendKey: (NSString*) key +{ + id script = [view windowScriptObject]; + [script callWebScriptMethod:@"handleKeyFromCocoa" withArguments: [NSArray arrayWithObject:key]]; +} + +- (void) copySource +{ + NSString *source = [(DOMHTMLElement *)[[[view mainFrame] DOMDocument] documentElement] outerHTML]; + NSPasteboard *a =[NSPasteboard generalPasteboard]; + [a declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self]; + [a setString:source forType: NSStringPboardType]; +} + +- (NSArray *) webView:(WebView *)sender +contextMenuItemsForElement:(NSDictionary *)element + defaultMenuItems:(NSArray *)defaultMenuItems +{ + DOMNode *node = [element valueForKey:@"WebElementDOMNode"]; + + while (node) { + // Every ref has a class name of 'refs' and some other class. We check on that to see if we pressed on a ref. + if ([[node className] hasPrefix:@"refs "]) { + NSString *selectedRefString = [[[node childNodes] item:0] textContent]; + for (PBGitRef *ref in historyController.webCommit.refs) + { + if ([[ref shortName] isEqualToString:selectedRefString]) + return [contextMenuDelegate menuItemsForRef:ref]; + } + DLog(@"Could not find selected ref!"); + return defaultMenuItems; + } + if ([node hasAttributes] && [[node attributes] getNamedItem:@"representedFile"]) + return [historyController menuItemsForPaths:[NSArray arrayWithObject:[[[node attributes] getNamedItem:@"representedFile"] value]]]; + else if ([[node class] isEqual:[DOMHTMLImageElement class]]) { + // Copy Image is the only menu item that makes sense here since we don't need + // to download the image or open it in a new window (besides with the + // current implementation these two entries can crash GitX anyway) + for (NSMenuItem *item in defaultMenuItems) + if ([item tag] == WebMenuItemTagCopyImageToClipboard) + return [NSArray arrayWithObject:item]; + return nil; + } + + node = [node parentNode]; + } + + return defaultMenuItems; +} + + +// Open external links in the default browser +- (void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation + request:(NSURLRequest *)request + newFrameName:(NSString *)frameName + decisionListener:(id < WebPolicyDecisionListener >)listener +{ + [[NSWorkspace sharedWorkspace] openURL:[request URL]]; +} + +- getConfig:(NSString *)config +{ + return [repository valueForKeyPath:[@"config." stringByAppendingString:config]]; +} + +- (void)finalize +{ + [super finalize]; +} + +- (void) preferencesChanged +{ + [[self script] callWebScriptMethod:@"enableFeatures" withArguments:nil]; +} + +@end From 91026f857e606e96d9f686491660f6b38049c8ee Mon Sep 17 00:00:00 2001 From: David Catmull Date: Sat, 11 Jun 2011 15:06:11 -0600 Subject: [PATCH 03/16] base PBWebHistoryController on PBWebCommitController --- GitX.xcodeproj/project.pbxproj | 6 + PBStashContentController.m | 1 + PBWebCommitController.h | 8 +- PBWebCommitController.m | 31 ++-- PBWebHistoryController.h | 21 +-- PBWebHistoryController.m | 250 ++------------------------------- 6 files changed, 45 insertions(+), 272 deletions(-) diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index cf4a4af..6d96bab 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -80,6 +80,7 @@ 65D58BC7132D48C2003F7290 /* PBResetSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 65D58BC6132D48C0003F7290 /* PBResetSheet.m */; }; 770B37ED0679A11B001EADE2 /* GitTest_DataModel.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 770B37EC0679A11B001EADE2 /* GitTest_DataModel.xcdatamodel */; }; 77C8280E06725ACE000B614F /* ApplicationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 77C8280C06725ACE000B614F /* ApplicationController.m */; }; + 89087CA613A3E46B00911503 /* PBWebCommitController.m in Sources */ = {isa = PBXBuildFile; fileRef = 89087CA513A3E46B00911503 /* PBWebCommitController.m */; }; 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; @@ -335,6 +336,8 @@ 77C82804067257F0000B614F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 77C8280B06725ACE000B614F /* ApplicationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplicationController.h; sourceTree = ""; }; 77C8280C06725ACE000B614F /* ApplicationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ApplicationController.m; sourceTree = ""; }; + 89087CA413A3E46500911503 /* PBWebCommitController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBWebCommitController.h; sourceTree = ""; }; + 89087CA513A3E46B00911503 /* PBWebCommitController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBWebCommitController.m; sourceTree = ""; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 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 = ""; }; @@ -953,6 +956,8 @@ 911111F70E594F3F00BF76B4 /* PBRepositoryDocumentController.m */, F5E926040E8827D300056E75 /* PBViewController.h */, F5E926050E8827D300056E75 /* PBViewController.m */, + 89087CA413A3E46500911503 /* PBWebCommitController.h */, + 89087CA513A3E46B00911503 /* PBWebCommitController.m */, F5EF8C8C0E9D4A5D0050906B /* PBWebController.h */, F5EF8C8D0E9D4A5D0050906B /* PBWebController.m */, F5FE6C010EB13BC900F30D12 /* PBServicesController.h */, @@ -1457,6 +1462,7 @@ 65D58BC7132D48C2003F7290 /* PBResetSheet.m in Sources */, 31776089133569350025876E /* SearchWebView.m in Sources */, DDB8FE0113998CE2001A9EE2 /* PBStashContentController.m in Sources */, + 89087CA613A3E46B00911503 /* PBWebCommitController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PBStashContentController.m b/PBStashContentController.m index 8432872..e6a3fe3 100644 --- a/PBStashContentController.m +++ b/PBStashContentController.m @@ -7,6 +7,7 @@ // #import "PBStashContentController.h" +#import "PBGitCommit.h" #import "PBGitDefaults.h" #import "PBGitStash.h" diff --git a/PBWebCommitController.h b/PBWebCommitController.h index 0cd4af4..e392cb5 100644 --- a/PBWebCommitController.h +++ b/PBWebCommitController.h @@ -13,6 +13,7 @@ @class NSString; @class PBGitCommit; +// Displays the diff from a commit in the repository. @interface PBWebCommitController : PBWebController { IBOutlet id contextMenuDelegate; @@ -22,10 +23,15 @@ - (void) changeContentTo: (PBGitCommit *) content; - (void) sendKey: (NSString*) key; -- (NSString *)parseHeader:(NSString *)txt withRefs:(NSString *)badges; +- (NSString *) parseHeader:(NSString *)txt withRefs:(NSString *)badges; - (NSMutableDictionary *)parseStats:(NSString *)txt; - (NSString *) arbitraryHashForString:(NSString*)concat; - (void) openFileMerge:(NSString*)file sha:(NSString *)sha sha2:(NSString *)sha2; +- (void) didLoad; +- (NSString*) refsForCurrentCommit; +- (PBGitRef*) refFromString:(NSString*)refString; +- (NSArray*) menuItemsForPath:(NSString*)path; + @property (readonly) NSString* diff; @end diff --git a/PBWebCommitController.m b/PBWebCommitController.m index cb955db..9d2b3a1 100644 --- a/PBWebCommitController.m +++ b/PBWebCommitController.m @@ -200,7 +200,7 @@ { } -// TODO: need to be refactoring +// TODO: this is duplicated in PBWebDiffController - (void) openFileMerge:(NSString*)file sha:(NSString *)sha sha2:(NSString *)sha2 { NSArray *args=[NSArray arrayWithObjects:@"difftool",@"--no-prompt",@"--tool=opendiff",sha,sha2,@"--",file,nil]; @@ -222,9 +222,19 @@ [a setString:source forType: NSStringPboardType]; } -- (NSArray *) webView:(WebView *)sender +- (PBGitRef*) refFromString:(NSString*)refString +{ + return nil; +} + +- (NSArray*) menuItemsForPath:(NSString*)path +{ + return nil; +} + +- (NSArray *) webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element - defaultMenuItems:(NSArray *)defaultMenuItems + defaultMenuItems:(NSArray *)defaultMenuItems { DOMNode *node = [element valueForKey:@"WebElementDOMNode"]; @@ -232,16 +242,14 @@ contextMenuItemsForElement:(NSDictionary *)element // Every ref has a class name of 'refs' and some other class. We check on that to see if we pressed on a ref. if ([[node className] hasPrefix:@"refs "]) { NSString *selectedRefString = [[[node childNodes] item:0] textContent]; - for (PBGitRef *ref in historyController.webCommit.refs) - { - if ([[ref shortName] isEqualToString:selectedRefString]) - return [contextMenuDelegate menuItemsForRef:ref]; - } + PBGitRef *ref = [self refFromString:selectedRefString]; + if (ref != nil) + return [contextMenuDelegate menuItemsForRef:ref]; DLog(@"Could not find selected ref!"); return defaultMenuItems; } if ([node hasAttributes] && [[node attributes] getNamedItem:@"representedFile"]) - return [historyController menuItemsForPaths:[NSArray arrayWithObject:[[[node attributes] getNamedItem:@"representedFile"] value]]]; + return [self menuItemsForPath:[[[node attributes] getNamedItem:@"representedFile"] value]]; else if ([[node class] isEqual:[DOMHTMLImageElement class]]) { // Copy Image is the only menu item that makes sense here since we don't need // to download the image or open it in a new window (besides with the @@ -273,11 +281,6 @@ contextMenuItemsForElement:(NSDictionary *)element return [repository valueForKeyPath:[@"config." stringByAppendingString:config]]; } -- (void)finalize -{ - [super finalize]; -} - - (void) preferencesChanged { [[self script] callWebScriptMethod:@"enableFeatures" withArguments:nil]; diff --git a/PBWebHistoryController.h b/PBWebHistoryController.h index a692aad..1b9d26f 100644 --- a/PBWebHistoryController.h +++ b/PBWebHistoryController.h @@ -7,29 +7,14 @@ // #import -#import "PBWebController.h" - -#import "PBGitCommit.h" -#import "PBGitHistoryController.h" -#import "PBRefContextDelegate.h" +#import "PBWebCommitController.h" +@class PBGitHistoryController; @class NSString; -@interface PBWebHistoryController : PBWebController { +@interface PBWebHistoryController : PBWebCommitController { IBOutlet PBGitHistoryController* historyController; - IBOutlet id contextMenuDelegate; - - NSString* currentSha; - NSString* diff; } -- (void) changeContentTo: (PBGitCommit *) content; -- (void) sendKey: (NSString*) key; -- (NSString *)parseHeader:(NSString *)txt withRefs:(NSString *)badges; -- (NSMutableDictionary *)parseStats:(NSString *)txt; -- (NSString *) arbitraryHashForString:(NSString*)concat; -- (void) openFileMerge:(NSString*)file sha:(NSString *)sha sha2:(NSString *)sha2; - -@property (readonly) NSString* diff; @end diff --git a/PBWebHistoryController.m b/PBWebHistoryController.m index 85599f8..c08f1ed 100644 --- a/PBWebHistoryController.m +++ b/PBWebHistoryController.m @@ -8,13 +8,10 @@ #import "PBWebHistoryController.h" #import "PBGitDefaults.h" -#import "GLFileView.h" -#import +#import "PBGitHistoryController.h" @implementation PBWebHistoryController -@synthesize diff; - - (void) awakeFromNib { startFile = @"history"; @@ -33,7 +30,7 @@ - (void) didLoad { - currentSha = nil; + [super didLoad]; [self changeContentTo: historyController.webCommit]; } @@ -45,45 +42,8 @@ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } -- (void) changeContentTo: (PBGitCommit *) content +- (NSString*) refsForCurrentCommit { - if (content == nil || !finishedLoading) - return; - - currentSha = [content sha]; - - // Now we load the extended details. We used to do this in a separate thread, - // but this caused some funny behaviour because NSTask's and NSThread's don't really - // like each other. Instead, just do it async. - - NSMutableArray *taskArguments = [NSMutableArray arrayWithObjects:@"show", @"--numstat", @"--summary", @"--pretty=raw", currentSha, nil]; - if (![PBGitDefaults showWhitespaceDifferences]) - [taskArguments insertObject:@"-w" atIndex:1]; - - NSFileHandle *handle = [repository handleForArguments:taskArguments]; - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - // Remove notification, in case we have another one running - [nc removeObserver:self name:NSFileHandleReadToEndOfFileCompletionNotification object:nil]; - [nc addObserver:self selector:@selector(commitDetailsLoaded:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; - [handle readToEndOfFileInBackgroundAndNotify]; -} - -- (void)commitDetailsLoaded:(NSNotification *)notification -{ - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSFileHandleReadToEndOfFileCompletionNotification object:nil]; - - NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem]; - if (!data) - return; - - NSString *details = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - if (!details) - details = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding]; - - if (!details) - return; - - NSMutableString *refs = [NSMutableString string]; NSArray *refsA = [historyController.webCommit refs]; NSString *currentRef = [[[historyController repository] headRef] simpleRef]; @@ -97,125 +57,7 @@ [refs appendString:[NSString stringWithFormat:@"%@",style,[ref shortName]]]; } - // Header - NSString *header = [self parseHeader:details withRefs:refs]; - - // File Stats - NSMutableDictionary *stats = [self parseStats:details]; - - // File list - NSString *dt = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"-r", @"-C90%", @"-M90%", currentSha, nil]]; - NSString *fileList = [GLFileView parseDiffTree:dt withStats:stats]; - - // Diffs list - NSString *d = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"--cc", @"-C90%", @"-M90%", currentSha, nil]]; - NSString *diffs = [GLFileView parseDiff:d]; - - NSString *html = [NSString stringWithFormat:@"%@%@
%@
",header,fileList,diffs]; - - html = [html stringByReplacingOccurrencesOfString:@"{SHA_PREV}" withString:[NSString stringWithFormat:@"%@^",currentSha]]; - html = [html stringByReplacingOccurrencesOfString:@"{SHA}" withString:currentSha]; - - [[view windowScriptObject] callWebScriptMethod:@"showCommit" withArguments:[NSArray arrayWithObject:html]]; - -#ifdef DEBUG_BUILD - NSString *dom = [(DOMHTMLElement*)[[[view mainFrame] DOMDocument] documentElement] outerHTML]; - NSString *tmpFile = @"~/tmp/test2.html"; - [dom writeToFile:[tmpFile stringByExpandingTildeInPath] atomically:true encoding:NSUTF8StringEncoding error:nil]; -#endif -} - -- (NSMutableDictionary *)parseStats:(NSString *)txt -{ - NSArray *lines = [txt componentsSeparatedByString:@"\n"]; - NSMutableDictionary *stats=[NSMutableDictionary dictionary]; - int black=0; - for(NSString *line in lines){ - if([line length]==0){ - black++; - }else if(black==2){ - NSArray *file=[line componentsSeparatedByString:@"\t"]; - if([file count]==3){ - [stats setObject:file forKey:[file objectAtIndex:2]]; - } - } - } - return stats; -} - -- (NSString *)parseHeader:(NSString *)txt withRefs:(NSString *)badges -{ - NSArray *lines = [txt componentsSeparatedByString:@"\n"]; - NSString *line; - NSString *last_mail=@""; - NSMutableString *auths=[NSMutableString string]; - NSMutableString *refs=[NSMutableString string]; - NSMutableString *subject=[NSMutableString string]; - BOOL subj=FALSE; - - int i; - for (i=0; i<[lines count]; i++) { - line=[lines objectAtIndex:i]; - if([line length]==0){ - if(!subj){ - subj=TRUE; - }else{ - i=[lines count]; - } - }else{ - if (subj) { - NSString *trimmedLine = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - [subject appendString:[NSString stringWithFormat:@"%@
",[GLFileView escapeHTML:trimmedLine]]]; - }else{ - NSArray *comps=[line componentsSeparatedByString:@" "]; - if([comps count]==2){ - [refs appendString:[NSString stringWithFormat:@"%@%@",[comps objectAtIndex:0],[comps objectAtIndex:1]]]; - }else if([comps count]>2){ - NSRange r_email_i = [line rangeOfString:@"<"]; - NSRange r_email_e = [line rangeOfString:@">"]; - NSRange r_name_i = [line rangeOfString:@" "]; - - NSString *rol=[line substringToIndex:r_name_i.location]; - NSString *name=[line substringWithRange:NSMakeRange(r_name_i.location,(r_email_i.location-r_name_i.location))]; - NSString *email=[line substringWithRange:NSMakeRange(r_email_i.location+1,((r_email_e.location-1)-r_email_i.location))]; - - NSArray *t=[[line substringFromIndex:r_email_e.location+2] componentsSeparatedByString:@" "]; - NSDate *date=[NSDate dateWithTimeIntervalSince1970:[[t objectAtIndex:0] doubleValue]]; - NSDateFormatter* theDateFormatter = [[NSDateFormatter alloc] init]; - [theDateFormatter setDateStyle:NSDateFormatterMediumStyle]; - [theDateFormatter setTimeStyle:NSDateFormatterMediumStyle]; - NSString *dateString=[theDateFormatter stringForObjectValue:date]; - - if(![email isEqualToString:last_mail]){ - [auths appendString:[NSString stringWithFormat:@"
",rol]]; - if([self isFeatureEnabled:@"gravatar"]){ - NSString *hash=[self arbitraryHashForString:email]; - [auths appendString:[NSString stringWithFormat:@"",hash]]; - } - [auths appendString:[NSString stringWithFormat:@"

%@ (%@)

",name,rol]]; - [auths appendString:[NSString stringWithFormat:@"

%@

",dateString]]; - } - last_mail=email; - } - } - } - } - - return [NSString stringWithFormat:@"",refs,subject,auths,badges]; -} - -- (NSString *) arbitraryHashForString:(NSString*)concat { - const char *concat_str = [concat UTF8String]; - unsigned char result[CC_MD5_DIGEST_LENGTH]; - CC_MD5(concat_str, strlen(concat_str), result); - - NSMutableString *hash = [NSMutableString string]; - - int i; - for (i = 0; i < 16; i++) - [hash appendFormat:@"%02x", result[i]]; - - return hash; + return refs; } - (void)selectCommit:(NSString *)sha @@ -223,87 +65,17 @@ [historyController selectCommit:sha]; } -// TODO: need to be refactoring -- (void) openFileMerge:(NSString*)file sha:(NSString *)sha sha2:(NSString *)sha2 +- (PBGitRef*) refFromString:(NSString*)refString { - NSArray *args=[NSArray arrayWithObjects:@"difftool",@"--no-prompt",@"--tool=opendiff",sha,sha2,@"--",file,nil]; - [historyController.repository handleInWorkDirForArguments:args]; + for (PBGitRef *ref in historyController.webCommit.refs) + if ([[ref shortName] isEqualToString:refString]) + return ref; + return nil; } - -- (void) sendKey: (NSString*) key +- (NSArray*) menuItemsForPath:(NSString*)path { - id script = [view windowScriptObject]; - [script callWebScriptMethod:@"handleKeyFromCocoa" withArguments: [NSArray arrayWithObject:key]]; -} - -- (void) copySource -{ - NSString *source = [(DOMHTMLElement *)[[[view mainFrame] DOMDocument] documentElement] outerHTML]; - NSPasteboard *a =[NSPasteboard generalPasteboard]; - [a declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self]; - [a setString:source forType: NSStringPboardType]; -} - -- (NSArray *) webView:(WebView *)sender -contextMenuItemsForElement:(NSDictionary *)element - defaultMenuItems:(NSArray *)defaultMenuItems -{ - DOMNode *node = [element valueForKey:@"WebElementDOMNode"]; - - while (node) { - // Every ref has a class name of 'refs' and some other class. We check on that to see if we pressed on a ref. - if ([[node className] hasPrefix:@"refs "]) { - NSString *selectedRefString = [[[node childNodes] item:0] textContent]; - for (PBGitRef *ref in historyController.webCommit.refs) - { - if ([[ref shortName] isEqualToString:selectedRefString]) - return [contextMenuDelegate menuItemsForRef:ref]; - } - DLog(@"Could not find selected ref!"); - return defaultMenuItems; - } - if ([node hasAttributes] && [[node attributes] getNamedItem:@"representedFile"]) - return [historyController menuItemsForPaths:[NSArray arrayWithObject:[[[node attributes] getNamedItem:@"representedFile"] value]]]; - else if ([[node class] isEqual:[DOMHTMLImageElement class]]) { - // Copy Image is the only menu item that makes sense here since we don't need - // to download the image or open it in a new window (besides with the - // current implementation these two entries can crash GitX anyway) - for (NSMenuItem *item in defaultMenuItems) - if ([item tag] == WebMenuItemTagCopyImageToClipboard) - return [NSArray arrayWithObject:item]; - return nil; - } - - node = [node parentNode]; - } - - return defaultMenuItems; -} - - -// Open external links in the default browser -- (void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation - request:(NSURLRequest *)request - newFrameName:(NSString *)frameName - decisionListener:(id < WebPolicyDecisionListener >)listener -{ - [[NSWorkspace sharedWorkspace] openURL:[request URL]]; -} - -- getConfig:(NSString *)config -{ - return [historyController valueForKeyPath:[@"repository.config." stringByAppendingString:config]]; -} - -- (void)finalize -{ - [super finalize]; -} - -- (void) preferencesChanged -{ - [[self script] callWebScriptMethod:@"enableFeatures" withArguments:nil]; + return [historyController menuItemsForPaths:[NSArray arrayWithObject:path]]; } @end From 10274aef55f9e3071959cf0bb4e84fabcde57a8c Mon Sep 17 00:00:00 2001 From: David Catmull Date: Sun, 12 Jun 2011 15:23:30 -0600 Subject: [PATCH 04/16] PBViewController.superController accessor --- PBViewController.h | 1 + PBViewController.m | 1 + 2 files changed, 2 insertions(+) diff --git a/PBViewController.h b/PBViewController.h index ec5dbd4..ad6e3d5 100644 --- a/PBViewController.h +++ b/PBViewController.h @@ -20,6 +20,7 @@ } @property (readonly) __weak PBGitRepository *repository; +@property (readonly) __weak PBGitWindowController *superController; @property(copy) NSString *status; @property(assign) BOOL isBusy; diff --git a/PBViewController.m b/PBViewController.m index a0de1da..c926c19 100644 --- a/PBViewController.m +++ b/PBViewController.m @@ -12,6 +12,7 @@ @implementation PBViewController @synthesize repository; +@synthesize superController; @synthesize status; @synthesize isBusy; From 60503ba19f29992fdec759840c7a69f4d1ca0225 Mon Sep 17 00:00:00 2001 From: David Catmull Date: Sun, 12 Jun 2011 15:24:01 -0600 Subject: [PATCH 05/16] fix file name comments --- PBGitHistoryController.h | 2 +- PBGitHistoryController.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PBGitHistoryController.h b/PBGitHistoryController.h index 228e2a2..36f0cfd 100644 --- a/PBGitHistoryController.h +++ b/PBGitHistoryController.h @@ -1,5 +1,5 @@ // -// PBGitHistoryView.h +// PBGitHistoryController.h // GitX // // Created by Pieter de Bie on 19-09-08. diff --git a/PBGitHistoryController.m b/PBGitHistoryController.m index 64630e1..d86e16d 100644 --- a/PBGitHistoryController.m +++ b/PBGitHistoryController.m @@ -1,5 +1,5 @@ // -// PBGitHistoryView.m +// PBGitHistoryController.m // GitX // // Created by Pieter de Bie on 19-09-08. From 8053f57fbc8275aeb4e193b82bb43d863f70c6f1 Mon Sep 17 00:00:00 2001 From: David Catmull Date: Sun, 12 Jun 2011 21:46:30 -0600 Subject: [PATCH 06/16] add PBWebStashController --- GitX.xcodeproj/project.pbxproj | 19 ++++++++++++++++--- PBGitSidebarController.h | 2 +- PBGitWindowController.h | 1 + PBGitWindowController.m | 7 +++++++ PBWebCommitController.h | 5 +++++ PBWebHistoryController.h | 2 -- PBWebStashController.h | 16 ++++++++++++++++ PBWebStashController.m | 23 +++++++++++++++++++++++ 8 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 PBWebStashController.h create mode 100644 PBWebStashController.m diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index 6d96bab..132fb0d 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -81,6 +81,7 @@ 770B37ED0679A11B001EADE2 /* GitTest_DataModel.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 770B37EC0679A11B001EADE2 /* GitTest_DataModel.xcdatamodel */; }; 77C8280E06725ACE000B614F /* ApplicationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 77C8280C06725ACE000B614F /* ApplicationController.m */; }; 89087CA613A3E46B00911503 /* PBWebCommitController.m in Sources */ = {isa = PBXBuildFile; fileRef = 89087CA513A3E46B00911503 /* PBWebCommitController.m */; }; + 8998B1C613A55B3500121729 /* PBWebStashController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8998B1C513A55B3500121729 /* PBWebStashController.m */; }; 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; @@ -338,6 +339,8 @@ 77C8280C06725ACE000B614F /* ApplicationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ApplicationController.m; sourceTree = ""; }; 89087CA413A3E46500911503 /* PBWebCommitController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBWebCommitController.h; sourceTree = ""; }; 89087CA513A3E46B00911503 /* PBWebCommitController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBWebCommitController.m; sourceTree = ""; }; + 8998B1AC13A55AC100121729 /* PBWebStashController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBWebStashController.h; sourceTree = ""; }; + 8998B1C513A55B3500121729 /* PBWebStashController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBWebStashController.m; sourceTree = ""; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 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 = ""; }; @@ -849,6 +852,17 @@ name = Models; sourceTree = ""; }; + 8998B1AB13A55A9B00121729 /* Stash */ = { + isa = PBXGroup; + children = ( + DDB8FDFF13998CE2001A9EE2 /* PBStashContentController.h */, + DDB8FE0013998CE2001A9EE2 /* PBStashContentController.m */, + 8998B1AC13A55AC100121729 /* PBWebStashController.h */, + 8998B1C513A55B3500121729 /* PBWebStashController.m */, + ); + name = Stash; + sourceTree = ""; + }; 913D5E420E5563FD00CECEA2 /* cli */ = { isa = PBXGroup; children = ( @@ -944,12 +958,11 @@ F5EF8C880E9D498F0050906B /* History */, F5E927F90E883EF600056E75 /* Commit */, D82F435F111B9C6D00A25A39 /* Sheets */, + 8998B1AB13A55A9B00121729 /* Stash */, 77C8280B06725ACE000B614F /* ApplicationController.h */, 77C8280C06725ACE000B614F /* ApplicationController.m */, 93CB42C00EAB7B2200530609 /* PBGitDefaults.h */, 93CB42C10EAB7B2200530609 /* PBGitDefaults.m */, - DDB8FDFF13998CE2001A9EE2 /* PBStashContentController.h */, - DDB8FE0013998CE2001A9EE2 /* PBStashContentController.m */, F57CC43F0E05E496000472E2 /* PBGitWindowController.h */, F57CC4400E05E496000472E2 /* PBGitWindowController.m */, 911111F60E594F3F00BF76B4 /* PBRepositoryDocumentController.h */, @@ -1209,7 +1222,6 @@ isa = PBXProject; buildConfigurationList = 26FC0A880875C7B200E6366F /* Build configuration list for PBXProject "GitX" */; compatibilityVersion = "Xcode 3.1"; - developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, @@ -1463,6 +1475,7 @@ 31776089133569350025876E /* SearchWebView.m in Sources */, DDB8FE0113998CE2001A9EE2 /* PBStashContentController.m in Sources */, 89087CA613A3E46B00911503 /* PBWebCommitController.m in Sources */, + 8998B1C613A55B3500121729 /* PBWebStashController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PBGitSidebarController.h b/PBGitSidebarController.h index a2eb106..40e89ed 100644 --- a/PBGitSidebarController.h +++ b/PBGitSidebarController.h @@ -34,7 +34,7 @@ PBGitHistoryController *historyViewController; PBGitCommitController *commitViewController; - PBStashContentController *stashViewController; + PBStashContentController *stashViewController; } - (void) selectStage; diff --git a/PBGitWindowController.h b/PBGitWindowController.h index a3bb3cb..b00482d 100644 --- a/PBGitWindowController.h +++ b/PBGitWindowController.h @@ -56,6 +56,7 @@ - (IBAction) cloneTo:(id)sender; - (IBAction) refresh:(id)sender; +- (void)selectCommitForSha:(NSString*)sha; - (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode; @end diff --git a/PBGitWindowController.m b/PBGitWindowController.m index e156c85..89eba03 100644 --- a/PBGitWindowController.m +++ b/PBGitWindowController.m @@ -234,6 +234,13 @@ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } +- (void) selectCommitForSha:(NSString *)sha +{ + if (contentController != sidebarController.historyViewController) + [sidebarController selectCurrentBranch]; + [sidebarController.historyViewController selectCommit:sha]; +} + - (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode { [sidebarController setHistorySearch:searchString mode:mode]; diff --git a/PBWebCommitController.h b/PBWebCommitController.h index e392cb5..945dbbb 100644 --- a/PBWebCommitController.h +++ b/PBWebCommitController.h @@ -29,8 +29,13 @@ - (void) openFileMerge:(NSString*)file sha:(NSString *)sha sha2:(NSString *)sha2; - (void) didLoad; +// Called when a commit or parent link is clicked. +- (void)selectCommit:(NSString *)sha; +// HTML listing refs (branch name, etc) for the displayed commit. - (NSString*) refsForCurrentCommit; +// Look up a PBGitRef based on its SHA. - (PBGitRef*) refFromString:(NSString*)refString; +// Context menu items to be displayed for a file. - (NSArray*) menuItemsForPath:(NSString*)path; @property (readonly) NSString* diff; diff --git a/PBWebHistoryController.h b/PBWebHistoryController.h index 1b9d26f..5a99ca0 100644 --- a/PBWebHistoryController.h +++ b/PBWebHistoryController.h @@ -11,8 +11,6 @@ @class PBGitHistoryController; -@class NSString; - @interface PBWebHistoryController : PBWebCommitController { IBOutlet PBGitHistoryController* historyController; } diff --git a/PBWebStashController.h b/PBWebStashController.h new file mode 100644 index 0000000..7abcb93 --- /dev/null +++ b/PBWebStashController.h @@ -0,0 +1,16 @@ +// +// PBWebStashController.h +// +// Created by David Catmull on 12-06-11. +// + +#import +#import "PBWebCommitController.h" + +@class PBStashContentController; + +@interface PBWebStashController : PBWebCommitController { + IBOutlet PBStashContentController *stashController; +} + +@end diff --git a/PBWebStashController.m b/PBWebStashController.m new file mode 100644 index 0000000..ea347f0 --- /dev/null +++ b/PBWebStashController.m @@ -0,0 +1,23 @@ +// +// PBWebStashController.m +// +// Created by David Catmull on 12-06-11. +// + +#import "PBWebStashController.h" +#import "PBStashContentController.h" + +@implementation PBWebStashController + +- (void)selectCommit:(NSString *)sha +{ + [[stashController superController] selectCommitForSha:sha]; +} + +- (NSArray*) menuItemsForPath:(NSString*)path +{ + // return [[stashController superController] menuItemsForPaths:[NSArray arrayWithObject:path]]; + return nil; +} + +@end From 0ec89f165c7bfc68bd053e8bf7d5bd665b395efa Mon Sep 17 00:00:00 2001 From: David Catmull Date: Mon, 13 Jun 2011 17:51:16 -0600 Subject: [PATCH 07/16] plug in PBWebStashController --- PBStashContentController.h | 2 +- PBStashContentView.xib | 226 +++++++------------------------------ PBWebDiffController.h | 1 + 3 files changed, 42 insertions(+), 187 deletions(-) diff --git a/PBStashContentController.h b/PBStashContentController.h index 3ec6061..5ce1510 100644 --- a/PBStashContentController.h +++ b/PBStashContentController.h @@ -15,7 +15,7 @@ // Controls the view displaying a stash diff @interface PBStashContentController : PBViewController { IBOutlet id webView; - IBOutlet PBWebHistoryController *webController; + IBOutlet PBWebStashController *webController; } - (void) showStash:(PBGitStash*)stash; diff --git a/PBStashContentView.xib b/PBStashContentView.xib index 5dfb786..5230212 100644 --- a/PBStashContentView.xib +++ b/PBStashContentView.xib @@ -109,7 +109,7 @@ NSView - PBWebHistoryController + PBWebStashController @@ -171,6 +171,14 @@ 10 + + + stashController + + + + 11 + @@ -268,7 +276,7 @@ - 10 + 11 @@ -280,158 +288,6 @@ NSApplication+GitXScripting.h - - PBGitHistoryController - PBViewController - - YES - - YES - cherryPick: - createBranch: - createTag: - merge: - openFilesAction: - openSelectedFile: - rebase: - refresh: - selectNext: - selectPrevious: - setBranchFilter: - setDetailedView: - setTreeView: - showAddRemoteSheet: - showCommitsFromTree: - showInFinderAction: - toggleQLPreviewPanel: - updateSearch: - - - YES - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - - - - YES - - YES - cherryPick: - createBranch: - createTag: - merge: - openFilesAction: - openSelectedFile: - rebase: - refresh: - selectNext: - selectPrevious: - setBranchFilter: - setDetailedView: - setTreeView: - showAddRemoteSheet: - showCommitsFromTree: - showInFinderAction: - toggleQLPreviewPanel: - updateSearch: - - - YES - - cherryPick: - id - - - createBranch: - id - - - createTag: - id - - - merge: - id - - - openFilesAction: - id - - - openSelectedFile: - id - - - rebase: - id - - - refresh: - id - - - selectNext: - id - - - selectPrevious: - id - - - setBranchFilter: - id - - - setDetailedView: - id - - - setTreeView: - id - - - showAddRemoteSheet: - id - - - showCommitsFromTree: - id - - - showInFinderAction: - id - - - toggleQLPreviewPanel: - id - - - updateSearch: - id - - - - - IBProjectSource - PBGitHistoryController.h - - PBGitRepository NSDocument @@ -452,7 +308,7 @@ YES - PBWebHistoryController + PBWebStashController id @@ -467,7 +323,7 @@ YES webController - PBWebHistoryController + PBWebStashController webView @@ -499,6 +355,25 @@ PBViewController.h + + PBWebCommitController + PBWebController + + contextMenuDelegate + id + + + contextMenuDelegate + + contextMenuDelegate + id + + + + IBProjectSource + PBWebCommitController.h + + PBWebController NSObject @@ -540,43 +415,22 @@ - PBWebHistoryController - PBWebController + PBWebStashController + PBWebCommitController - YES - - YES - contextMenuDelegate - historyController - - - YES - id - PBGitHistoryController - + stashController + PBStashContentController - YES - - YES - contextMenuDelegate - historyController - - - YES - - contextMenuDelegate - id - - - historyController - PBGitHistoryController - + stashController + + stashController + PBStashContentController IBProjectSource - PBWebHistoryController.h + PBWebStashController.h diff --git a/PBWebDiffController.h b/PBWebDiffController.h index bda6014..67738d3 100644 --- a/PBWebDiffController.h +++ b/PBWebDiffController.h @@ -10,6 +10,7 @@ #import "PBWebController.h" #import "PBDiffWindowController.h" +// Instantiated in PBDiffWindow.xib, used by PBDiffWindowController @interface PBWebDiffController : PBWebController { IBOutlet PBDiffWindowController *diffController; } From 93212a6efd45741487229c7a721db1c4cc9c76f8 Mon Sep 17 00:00:00 2001 From: David Catmull Date: Mon, 13 Jun 2011 17:52:11 -0600 Subject: [PATCH 08/16] WIP refactor parsing --- PBWebCommitController.h | 3 - PBWebCommitController.m | 130 +++++++++++++++++++++++++++------------- 2 files changed, 90 insertions(+), 43 deletions(-) diff --git a/PBWebCommitController.h b/PBWebCommitController.h index 945dbbb..20893b2 100644 --- a/PBWebCommitController.h +++ b/PBWebCommitController.h @@ -23,9 +23,6 @@ - (void) changeContentTo: (PBGitCommit *) content; - (void) sendKey: (NSString*) key; -- (NSString *) parseHeader:(NSString *)txt withRefs:(NSString *)badges; -- (NSMutableDictionary *)parseStats:(NSString *)txt; -- (NSString *) arbitraryHashForString:(NSString*)concat; - (void) openFileMerge:(NSString*)file sha:(NSString *)sha sha2:(NSString *)sha2; - (void) didLoad; diff --git a/PBWebCommitController.m b/PBWebCommitController.m index 9d2b3a1..54d04b0 100644 --- a/PBWebCommitController.m +++ b/PBWebCommitController.m @@ -10,6 +10,16 @@ #import "GLFileView.h" #import +@interface PBWebCommitController (Private) + +- (NSArray *)parseHeader:(NSString *)text; +- (NSString *)htmlForHeader:(NSArray *)header withRefs:(NSString *)badges; +- (NSMutableDictionary *)parseStats:(NSString *)txt; +- (NSString *) arbitraryHashForString:(NSString*)concat; + +@end + + @implementation PBWebCommitController @synthesize diff; @@ -71,7 +81,8 @@ return; // Header - NSString *header = [self parseHeader:details withRefs:[self refsForCurrentCommit]]; + NSArray *headerItems = [self parseHeader:details]; + NSString *header = [self htmlForHeader:details withRefs:[self refsForCurrentCommit]]; // File Stats NSMutableDictionary *stats = [self parseStats:details]; @@ -121,60 +132,99 @@ return stats; } -- (NSString *)parseHeader:(NSString *)txt withRefs:(NSString *)badges +// -parseHeader: returns an array of dictionaries with these keys +const NSString *kHeaderKeyName = @"name"; +const NSString *kHeaderKeyContent = @"content"; + +// Keys for the author/committer dictionary +const NSString *kAuthorKeyName = @"name"; +const NSString *kAuthorKeyEmail = @"email"; +const NSString *kAuthorKeyDate = @"date"; + +- (NSArray *)parseHeader:(NSString *)text { - NSArray *lines = [txt componentsSeparatedByString:@"\n"]; - NSString *line; - NSString *last_mail=@""; - NSMutableString *auths=[NSMutableString string]; - NSMutableString *refs=[NSMutableString string]; - NSMutableString *subject=[NSMutableString string]; - BOOL subj=FALSE; + NSMutableArray *result = [NSMutableArray array]; + NSArray *lines = [text componentsSeparatedByString:@"\n"]; + BOOL parsingSubject = NO; - int i; - for (i=0; i<[lines count]; i++) { - line=[lines objectAtIndex:i]; - if([line length]==0){ - if(!subj){ - subj=TRUE; - }else{ - i=[lines count]; - } - }else{ - if (subj) { - NSString *trimmedLine = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - [subject appendString:[NSString stringWithFormat:@"%@
",[GLFileView escapeHTML:trimmedLine]]]; - }else{ - NSArray *comps=[line componentsSeparatedByString:@" "]; - if([comps count]==2){ - [refs appendString:[NSString stringWithFormat:@"%@%@",[comps objectAtIndex:0],[comps objectAtIndex:1]]]; - }else if([comps count]>2){ + for (NSString *line in lines) { + if ([line length] == 0) { + if (!parsingSubject) + parsingSubject = TRUE; + else + break; + } else { + if (parsingSubject) { + NSString *trimmedLine = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + [result addObject:[NSDictionary dictionaryWithObjectsAndKeys: + @"subject", kHeaderKeyName, trimmedLine, kHeaderKeyContent, nil]]; + } else { + NSArray *comps = [line componentsSeparatedByString:@" "]; + if ([comps count] == 2) { + [result addObject:[NSDictionary dictionaryWithObjectsAndKeys: + [comps objectAtIndex:0], kHeaderKeyName, + [comps objectAtIndex:1], kHeaderKeyContent, nil]]; + } else if ([comps count] > 2) { NSRange r_email_i = [line rangeOfString:@"<"]; NSRange r_email_e = [line rangeOfString:@">"]; NSRange r_name_i = [line rangeOfString:@" "]; - NSString *rol=[line substringToIndex:r_name_i.location]; - NSString *name=[line substringWithRange:NSMakeRange(r_name_i.location,(r_email_i.location-r_name_i.location))]; - NSString *email=[line substringWithRange:NSMakeRange(r_email_i.location+1,((r_email_e.location-1)-r_email_i.location))]; + NSString *name = [line substringWithRange:NSMakeRange(r_name_i.location,(r_email_i.location-r_name_i.location))]; + NSString *email = [line substringWithRange:NSMakeRange(r_email_i.location+1,((r_email_e.location-1)-r_email_i.location))]; NSArray *t=[[line substringFromIndex:r_email_e.location+2] componentsSeparatedByString:@" "]; NSDate *date=[NSDate dateWithTimeIntervalSince1970:[[t objectAtIndex:0] doubleValue]]; + + [result addObject:[NSDictionary dictionaryWithObjectsAndKeys: + [comps objectAtIndex:0], kHeaderKeyName, + [NSDictionary dictionaryWithObjectsAndKeys: + name, kAuthorKeyName, + email, kAuthorKeyEmail, + date, kAuthorKeyDate, + nil], + nil]]; + } + } + } + } + + return result; +} + +- (NSString *)htmlForHeader:(NSArray *)header withRefs:(NSString *)badges +{ + NSString *last_mail = @""; + NSMutableString *auths=[NSMutableString string]; + NSMutableString *refs=[NSMutableString string]; + NSMutableString *subject=[NSMutableString string]; + + for (NSDictionary *item in header) { + if ([[item objectForKey:kHeaderKeyName] isEqualToString:@"subject"]) { + [subject appendString:[NSString stringWithFormat:@"%@
",[GLFileView escapeHTML:[item objectForKey:kHeaderKeyContent]]]]; + }else{ + if([[item objectForKey:kHeaderKeyContent] isKindOfClass:[NSString class]]){ + [refs appendString:[NSString stringWithFormat:@"%@%@",[item objectForKey:kHeaderKeyName],[item objectForKey:kHeaderKeyContent]]]; + }else{ // NSDictionary: author or committer + NSDictionary *content = [item objectForKey:kHeaderKeyContent]; + NSString *email = [content objectForKey:kAuthorKeyEmail]; + + if(![email isEqualToString:last_mail]){ + NSString *name = [content objectForKey:kAuthorKeyName]; + NSDate *date = [content objectForKey:kAuthorKeyDate]; NSDateFormatter* theDateFormatter = [[NSDateFormatter alloc] init]; [theDateFormatter setDateStyle:NSDateFormatterMediumStyle]; [theDateFormatter setTimeStyle:NSDateFormatterMediumStyle]; NSString *dateString=[theDateFormatter stringForObjectValue:date]; - - if(![email isEqualToString:last_mail]){ - [auths appendString:[NSString stringWithFormat:@"
",rol]]; - if([self isFeatureEnabled:@"gravatar"]){ - NSString *hash=[self arbitraryHashForString:email]; - [auths appendString:[NSString stringWithFormat:@"",hash]]; - } - [auths appendString:[NSString stringWithFormat:@"

%@ (%@)

",name,rol]]; - [auths appendString:[NSString stringWithFormat:@"

%@

",dateString]]; + + [auths appendString:[NSString stringWithFormat:@"
",rol]]; + if([self isFeatureEnabled:@"gravatar"]){ + NSString *hash=[self arbitraryHashForString:email]; + [auths appendString:[NSString stringWithFormat:@"",hash]]; } - last_mail=email; + [auths appendString:[NSString stringWithFormat:@"

%@ (%@)

",name,rol]]; + [auths appendString:[NSString stringWithFormat:@"

%@

",dateString]]; } + last_mail=email; } } } From fc3ef16e3a5c3b162fedf03b3234c47bd96d2b4a Mon Sep 17 00:00:00 2001 From: David Catmull Date: Tue, 14 Jun 2011 17:20:35 -0600 Subject: [PATCH 09/16] finish parser refactor --- PBWebCommitController.m | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/PBWebCommitController.m b/PBWebCommitController.m index 54d04b0..0fc2697 100644 --- a/PBWebCommitController.m +++ b/PBWebCommitController.m @@ -82,7 +82,7 @@ // Header NSArray *headerItems = [self parseHeader:details]; - NSString *header = [self htmlForHeader:details withRefs:[self refsForCurrentCommit]]; + NSString *header = [self htmlForHeader:headerItems withRefs:[self refsForCurrentCommit]]; // File Stats NSMutableDictionary *stats = [self parseStats:details]; @@ -175,13 +175,14 @@ const NSString *kAuthorKeyDate = @"date"; NSArray *t=[[line substringFromIndex:r_email_e.location+2] componentsSeparatedByString:@" "]; NSDate *date=[NSDate dateWithTimeIntervalSince1970:[[t objectAtIndex:0] doubleValue]]; + NSDictionary *content = [NSDictionary dictionaryWithObjectsAndKeys: + name, kAuthorKeyName, + email, kAuthorKeyEmail, + date, kAuthorKeyDate, + nil]; [result addObject:[NSDictionary dictionaryWithObjectsAndKeys: [comps objectAtIndex:0], kHeaderKeyName, - [NSDictionary dictionaryWithObjectsAndKeys: - name, kAuthorKeyName, - email, kAuthorKeyEmail, - date, kAuthorKeyDate, - nil], + content, kHeaderKeyContent, nil]]; } } @@ -216,12 +217,12 @@ const NSString *kAuthorKeyDate = @"date"; [theDateFormatter setTimeStyle:NSDateFormatterMediumStyle]; NSString *dateString=[theDateFormatter stringForObjectValue:date]; - [auths appendString:[NSString stringWithFormat:@"
",rol]]; + [auths appendString:[NSString stringWithFormat:@"
",[item objectForKey:kHeaderKeyName]]]; if([self isFeatureEnabled:@"gravatar"]){ NSString *hash=[self arbitraryHashForString:email]; [auths appendString:[NSString stringWithFormat:@"",hash]]; } - [auths appendString:[NSString stringWithFormat:@"

%@ (%@)

",name,rol]]; + [auths appendString:[NSString stringWithFormat:@"

%@ (%@)

",name,[item objectForKey:kHeaderKeyName]]]; [auths appendString:[NSString stringWithFormat:@"

%@

",dateString]]; } last_mail=email; From c02046e64788eb08151f0f615f67260e20b7c8d4 Mon Sep 17 00:00:00 2001 From: David Catmull Date: Tue, 14 Jun 2011 17:20:56 -0600 Subject: [PATCH 10/16] JavaScript fix --- html/lib/SearchWebView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/lib/SearchWebView.js b/html/lib/SearchWebView.js index c09aa88..75321e7 100644 --- a/html/lib/SearchWebView.js +++ b/html/lib/SearchWebView.js @@ -32,7 +32,7 @@ function HighlightAllOccurencesOfStringForElement(element,keyword) { } else if (element.nodeType == 1) { // Element node if (element.style.display != "none" && element.nodeName.toLowerCase() != 'select') { for (var i=0; i"+element.childNodes[i].getAttribute('class')); HighlightAllOccurencesOfStringForElement(element.childNodes[i],keyword); } From 8676e86ea7ebf5fc99f91c7b4314f5b5fc7a8d25 Mon Sep 17 00:00:00 2001 From: David Catmull Date: Tue, 14 Jun 2011 17:38:55 -0600 Subject: [PATCH 11/16] fix display for merge commits, which stashes happen to be git diff-tree has to be explicitly given the list of parents --- PBWebCommitController.m | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/PBWebCommitController.m b/PBWebCommitController.m index 0fc2697..8d2be14 100644 --- a/PBWebCommitController.m +++ b/PBWebCommitController.m @@ -19,6 +19,14 @@ @end +// -parseHeader: returns an array of dictionaries with these keys +const NSString *kHeaderKeyName = @"name"; +const NSString *kHeaderKeyContent = @"content"; + +// Keys for the author/committer dictionary +const NSString *kAuthorKeyName = @"name"; +const NSString *kAuthorKeyEmail = @"email"; +const NSString *kAuthorKeyDate = @"date"; @implementation PBWebCommitController @@ -84,15 +92,29 @@ NSArray *headerItems = [self parseHeader:details]; NSString *header = [self htmlForHeader:headerItems withRefs:[self refsForCurrentCommit]]; + // In case the commit is a merge, we need to explicity give diff-tree the + // list of parents, or else it will yield an empty result. + // If it's not a merge, this won't hurt. + NSMutableArray *parentsArray = [NSMutableArray array]; + + for (NSDictionary *item in headerItems) { + if ([[item objectForKey:kHeaderKeyName] isEqualToString:@"parent"]) { + [parentsArray addObject:[item objectForKey:kHeaderKeyContent]]; + break; + } + } + + NSString *parents = [parentsArray componentsJoinedByString:@" "]; + // File Stats NSMutableDictionary *stats = [self parseStats:details]; // File list - NSString *dt = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"-r", @"-C90%", @"-M90%", currentSha, nil]]; + NSString *dt = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"-r", @"-C90%", @"-M90%", currentSha, parents, nil]]; NSString *fileList = [GLFileView parseDiffTree:dt withStats:stats]; // Diffs list - NSString *d = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"--cc", @"-C90%", @"-M90%", currentSha, nil]]; + NSString *d = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"--cc", @"-C90%", @"-M90%", currentSha, parents, nil]]; NSString *diffs = [GLFileView parseDiff:d]; NSString *html = [NSString stringWithFormat:@"%@%@
%@
",header,fileList,diffs]; @@ -132,15 +154,6 @@ return stats; } -// -parseHeader: returns an array of dictionaries with these keys -const NSString *kHeaderKeyName = @"name"; -const NSString *kHeaderKeyContent = @"content"; - -// Keys for the author/committer dictionary -const NSString *kAuthorKeyName = @"name"; -const NSString *kAuthorKeyEmail = @"email"; -const NSString *kAuthorKeyDate = @"date"; - - (NSArray *)parseHeader:(NSString *)text { NSMutableArray *result = [NSMutableArray array]; From 4a2c139fb9b63038e80626599b88d20c81445d04 Mon Sep 17 00:00:00 2001 From: David Catmull Date: Wed, 15 Jun 2011 21:16:02 -0600 Subject: [PATCH 12/16] menus for files in stash view --- PBGitWindowController.h | 3 ++- PBGitWindowController.m | 5 +++++ PBWebStashController.m | 3 +-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/PBGitWindowController.h b/PBGitWindowController.h index b00482d..266422c 100644 --- a/PBGitWindowController.h +++ b/PBGitWindowController.h @@ -56,7 +56,8 @@ - (IBAction) cloneTo:(id)sender; - (IBAction) refresh:(id)sender; -- (void)selectCommitForSha:(NSString*)sha; +- (void)selectCommitForSha:(NSString *)sha; +- (NSArray *)menuItemsForPaths:(NSArray *)paths; - (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode; @end diff --git a/PBGitWindowController.m b/PBGitWindowController.m index 89eba03..5579af2 100644 --- a/PBGitWindowController.m +++ b/PBGitWindowController.m @@ -241,6 +241,11 @@ [sidebarController.historyViewController selectCommit:sha]; } +- (NSArray *) menuItemsForPaths:(NSArray *)paths +{ + return [sidebarController.historyViewController menuItemsForPaths:paths]; +} + - (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode { [sidebarController setHistorySearch:searchString mode:mode]; diff --git a/PBWebStashController.m b/PBWebStashController.m index ea347f0..0ad6a94 100644 --- a/PBWebStashController.m +++ b/PBWebStashController.m @@ -16,8 +16,7 @@ - (NSArray*) menuItemsForPath:(NSString*)path { - // return [[stashController superController] menuItemsForPaths:[NSArray arrayWithObject:path]]; - return nil; + return [[stashController superController] menuItemsForPaths:[NSArray arrayWithObject:path]]; } @end From 0659d793a215a04bcfc5458521a06b51f6d8d380 Mon Sep 17 00:00:00 2001 From: David Catmull Date: Wed, 15 Jun 2011 21:42:29 -0600 Subject: [PATCH 13/16] split pane --- PBStashContentController.h | 3 +- PBStashContentController.m | 17 ++- PBStashContentView.xib | 283 ++++++++++++++++++++++++++++--------- 3 files changed, 232 insertions(+), 71 deletions(-) diff --git a/PBStashContentController.h b/PBStashContentController.h index 5ce1510..adf50ec 100644 --- a/PBStashContentController.h +++ b/PBStashContentController.h @@ -15,7 +15,8 @@ // Controls the view displaying a stash diff @interface PBStashContentController : PBViewController { IBOutlet id webView; - IBOutlet PBWebStashController *webController; + IBOutlet PBWebStashController *unstagedController; + IBOutlet PBWebStashController *stagedController; } - (void) showStash:(PBGitStash*)stash; diff --git a/PBStashContentController.m b/PBStashContentController.m index e6a3fe3..da0b2f4 100644 --- a/PBStashContentController.m +++ b/PBStashContentController.m @@ -11,11 +11,14 @@ #import "PBGitDefaults.h" #import "PBGitStash.h" +const CGFloat kMinPaneSize = 32.0; + @implementation PBStashContentController - (void) awakeFromNib { - [webController setRepository:repository]; + [unstagedController setRepository:repository]; + [stagedController setRepository:repository]; } - (void) showStash:(PBGitStash*)stash @@ -24,7 +27,17 @@ NSString *stashSha = [repository shaForRef:[PBGitRef refFromString:stashRef]]; PBGitCommit *commit = [PBGitCommit commitWithRepository:repository andSha:stashSha]; - [webController changeContentTo:commit]; + [unstagedController changeContentTo:commit]; +} + +- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex +{ + return kMinPaneSize; +} + +- (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)dividerIndex +{ + return [splitView frame].size.height - kMinPaneSize; } @end diff --git a/PBStashContentView.xib b/PBStashContentView.xib index 5230212..223b589 100644 --- a/PBStashContentView.xib +++ b/PBStashContentView.xib @@ -3,7 +3,7 @@ 1060 10J869 - 851 + 788 1038.35 461.00 @@ -15,18 +15,18 @@ YES - 851 - 851 + 788 + 788
YES - + YES - com.apple.WebKitIBPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin YES @@ -53,64 +53,110 @@ 274 YES - + 274 - + YES - - YES - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple URL pasteboard type - Apple Web Archive pasteboard type - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - WebURLsWithTitlesPboardType - public.png - public.url - public.url-name + + + 274 + + YES + + YES + Apple HTML pasteboard type + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple URL pasteboard type + Apple Web Archive pasteboard type + NSColor pasteboard type + NSFilenamesPboardType + NSStringPboardType + NeXT RTFD pasteboard type + NeXT Rich Text Format v1.0 pasteboard type + NeXT TIFF v4.0 pasteboard type + WebURLsWithTitlesPboardType + public.png + public.url + public.url-name + + + {480, 272} + + + + + + + + YES + + YES + WebKitDefaultFixedFontSize + WebKitDefaultFontSize + WebKitMinimumFontSize + + + YES + + + + + + + YES + YES + + + + 274 + + YES + + YES + Apple HTML pasteboard type + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple URL pasteboard type + Apple Web Archive pasteboard type + NSColor pasteboard type + NSFilenamesPboardType + NSStringPboardType + NeXT RTFD pasteboard type + NeXT Rich Text Format v1.0 pasteboard type + NeXT TIFF v4.0 pasteboard type + WebURLsWithTitlesPboardType + public.png + public.url + public.url-name + + + {{0, 282}, {480, 272}} + + + + + + YES + YES - {480, 272} + {480, 554} - - - - - - - YES - - YES - WebKitDefaultFixedFontSize - WebKitDefaultFontSize - WebKitMinimumFontSize - - - YES - - - - - - - YES - YES + 3 - {480, 272} + {480, 554} NSView PBWebStashController + + PBWebStashController + @@ -147,14 +193,6 @@ 7 - - - webController - - - - 8 - view @@ -179,6 +217,70 @@ 11 + + + unstagedController + + + + 12 + + + + stashController + + + + 15 + + + + stagedController + + + + 16 + + + + view + + + + 22 + + + + frameLoadDelegate + + + + 23 + + + + policyDelegate + + + + 24 + + + + UIDelegate + + + + 25 + + + + delegate + + + + 26 + @@ -212,20 +314,42 @@ YES - + Stash - - 2 - - - 3 + Unstaged Controller + + + 13 + + + Staged Controller + + + 21 + + + YES + + + + + + + 2 + + + + + 17 + + @@ -240,6 +364,9 @@ 1.IBPluginDependency 1.WindowOrigin 1.editorWindowContentRectSynchronizationRect + 13.IBPluginDependency + 17.IBPluginDependency + 17.IBViewBoundsToFrameTransform 2.IBPluginDependency 2.IBViewBoundsToFrameTransform 3.IBPluginDependency @@ -249,10 +376,15 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{14, 862}, {480, 272}} + {{786, 804}, {480, 554}} com.apple.InterfaceBuilder.CocoaPlugin {628, 654} {{357, 416}, {480, 272}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + + AUJwAABCFAAAA + com.apple.WebKitIBPlugin AUJwAABCFAAAA @@ -276,7 +408,7 @@
- 11 + 26 @@ -303,12 +435,14 @@ YES YES - webController + stagedController + unstagedController webView YES PBWebStashController + PBWebStashController id @@ -316,13 +450,18 @@ YES YES - webController + stagedController + unstagedController webView YES - webController + stagedController + PBWebStashController + + + unstagedController PBWebStashController @@ -968,6 +1107,14 @@ AppKit.framework/Headers/NSSearchField.h + + NSSplitView + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSSplitView.h + + NSTextField NSControl From 26ada648cc9e484638e4c10182a3f75e29f04917 Mon Sep 17 00:00:00 2001 From: David Catmull Date: Thu, 16 Jun 2011 17:54:42 -0600 Subject: [PATCH 14/16] show index in lower pane --- PBStashContentController.m | 7 +++++-- PBWebCommitController.h | 2 ++ PBWebCommitController.m | 7 ++++++- PBWebStashController.m | 5 +++++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/PBStashContentController.m b/PBStashContentController.m index da0b2f4..b7cc628 100644 --- a/PBStashContentController.m +++ b/PBStashContentController.m @@ -24,10 +24,13 @@ const CGFloat kMinPaneSize = 32.0; - (void) showStash:(PBGitStash*)stash { NSString *stashRef = [NSString stringWithFormat:@"refs/%@", [stash name]]; - NSString *stashSha = [repository shaForRef:[PBGitRef refFromString:stashRef]]; - PBGitCommit *commit = [PBGitCommit commitWithRepository:repository andSha:stashSha]; + NSString *stashSHA = [repository shaForRef:[PBGitRef refFromString:stashRef]]; + PBGitCommit *commit = [repository commitForSHA:stashSHA]; + NSString *indexSHA = [commit.parents objectAtIndex:1]; + PBGitCommit *indexCommit = [repository commitForSHA:indexSHA]; [unstagedController changeContentTo:commit]; + [stagedController changeContentTo:indexCommit]; } - (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex diff --git a/PBWebCommitController.h b/PBWebCommitController.h index 20893b2..2d53023 100644 --- a/PBWebCommitController.h +++ b/PBWebCommitController.h @@ -32,6 +32,8 @@ - (NSString*) refsForCurrentCommit; // Look up a PBGitRef based on its SHA. - (PBGitRef*) refFromString:(NSString*)refString; +// Choose which parents should be used for the diff +- (NSArray*) chooseDiffParents:(NSArray*)parents; // Context menu items to be displayed for a file. - (NSArray*) menuItemsForPath:(NSString*)path; diff --git a/PBWebCommitController.m b/PBWebCommitController.m index 8d2be14..f5002bd 100644 --- a/PBWebCommitController.m +++ b/PBWebCommitController.m @@ -104,7 +104,7 @@ const NSString *kAuthorKeyDate = @"date"; } } - NSString *parents = [parentsArray componentsJoinedByString:@" "]; + NSString *parents = [[self chooseDiffParents:parentsArray] componentsJoinedByString:@" "]; // File Stats NSMutableDictionary *stats = [self parseStats:details]; @@ -136,6 +136,11 @@ const NSString *kAuthorKeyDate = @"date"; return @""; } +- (NSArray*) chooseDiffParents:(NSArray *)parents +{ + return parents; +} + - (NSMutableDictionary *)parseStats:(NSString *)txt { NSArray *lines = [txt componentsSeparatedByString:@"\n"]; diff --git a/PBWebStashController.m b/PBWebStashController.m index 0ad6a94..ea39534 100644 --- a/PBWebStashController.m +++ b/PBWebStashController.m @@ -19,4 +19,9 @@ return [[stashController superController] menuItemsForPaths:[NSArray arrayWithObject:path]]; } +- (NSArray*) chooseDiffParents:(NSArray *)parents +{ + return [NSArray arrayWithObject:[parents objectAtIndex:0]]; +} + @end From 73b548cd6731bd73d2314b90f386c205aef8a384 Mon Sep 17 00:00:00 2001 From: David Catmull Date: Fri, 17 Jun 2011 12:12:48 -0600 Subject: [PATCH 15/16] fix inverted diff --- PBWebCommitController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PBWebCommitController.m b/PBWebCommitController.m index f5002bd..e442ee6 100644 --- a/PBWebCommitController.m +++ b/PBWebCommitController.m @@ -114,7 +114,7 @@ const NSString *kAuthorKeyDate = @"date"; NSString *fileList = [GLFileView parseDiffTree:dt withStats:stats]; // Diffs list - NSString *d = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"--cc", @"-C90%", @"-M90%", currentSha, parents, nil]]; + NSString *d = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"--cc", @"-C90%", @"-M90%", parents, currentSha, nil]]; NSString *diffs = [GLFileView parseDiff:d]; NSString *html = [NSString stringWithFormat:@"%@%@
%@
",header,fileList,diffs]; From ba51ae810bd5db60addc873c3ad6fbe97e2834ac Mon Sep 17 00:00:00 2001 From: David Catmull Date: Fri, 17 Jun 2011 13:52:33 -0600 Subject: [PATCH 16/16] fix parent handling --- PBWebCommitController.m | 23 +++++++++++++---------- PBWebStashController.m | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/PBWebCommitController.m b/PBWebCommitController.m index e442ee6..79fb31f 100644 --- a/PBWebCommitController.m +++ b/PBWebCommitController.m @@ -95,26 +95,29 @@ const NSString *kAuthorKeyDate = @"date"; // In case the commit is a merge, we need to explicity give diff-tree the // list of parents, or else it will yield an empty result. // If it's not a merge, this won't hurt. - NSMutableArray *parentsArray = [NSMutableArray array]; + NSMutableArray *allParents = [NSMutableArray array]; - for (NSDictionary *item in headerItems) { - if ([[item objectForKey:kHeaderKeyName] isEqualToString:@"parent"]) { - [parentsArray addObject:[item objectForKey:kHeaderKeyContent]]; - break; - } - } + for (NSDictionary *item in headerItems) + if ([[item objectForKey:kHeaderKeyName] isEqualToString:@"parent"]) + [allParents addObject:[item objectForKey:kHeaderKeyContent]]; - NSString *parents = [[self chooseDiffParents:parentsArray] componentsJoinedByString:@" "]; + NSArray *parents = [self chooseDiffParents:allParents]; // File Stats NSMutableDictionary *stats = [self parseStats:details]; // File list - NSString *dt = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"-r", @"-C90%", @"-M90%", currentSha, parents, nil]]; + NSMutableArray *args = [NSMutableArray arrayWithObjects:@"diff-tree", @"--root", @"-r", @"-C90%", @"-M90%", nil]; + [args addObjectsFromArray:parents]; + [args addObject:currentSha]; + NSString *dt = [repository outputInWorkdirForArguments:args]; NSString *fileList = [GLFileView parseDiffTree:dt withStats:stats]; // Diffs list - NSString *d = [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-tree", @"--root", @"--cc", @"-C90%", @"-M90%", parents, currentSha, nil]]; + args = [NSMutableArray arrayWithObjects:@"diff-tree", @"--root", @"--cc", @"-C90%", @"-M90%", nil]; + [args addObjectsFromArray:parents]; + [args addObject:currentSha]; + NSString *d = [repository outputInWorkdirForArguments:args]; NSString *diffs = [GLFileView parseDiff:d]; NSString *html = [NSString stringWithFormat:@"%@%@
%@
",header,fileList,diffs]; diff --git a/PBWebStashController.m b/PBWebStashController.m index ea39534..82bef0f 100644 --- a/PBWebStashController.m +++ b/PBWebStashController.m @@ -21,7 +21,7 @@ - (NSArray*) chooseDiffParents:(NSArray *)parents { - return [NSArray arrayWithObject:[parents objectAtIndex:0]]; + return [NSArray arrayWithObject:[parents lastObject]]; } @end