merge to master

This commit is contained in:
German Laullom
2010-09-27 11:45:33 -07:00
238 changed files with 31092 additions and 4674 deletions
+2 -5
View File
@@ -1,8 +1,5 @@
build
build/revision
*.xcodeproj/*.pbxuser
*.xcodeproj/*.perspectivev3
*.xcodeproj/*.mode1v3
*.xcodeproj/*.tm_build_errors
*.tmproj
*.xcodeproj/
!*.xcodeproj/project.pbxproj
Nightly.app.zip
+1 -16
View File
@@ -9,10 +9,9 @@
#import <Cocoa/Cocoa.h>
#import "PBGitRepository.h"
@class PBCLIProxy;
@class PBCloneRepositoryPanel;
@interface ApplicationController : NSObject <NSWindowDelegate>
@interface ApplicationController : NSObject
{
IBOutlet NSWindow *window;
IBOutlet id firstResponder;
@@ -20,22 +19,8 @@
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
PBCLIProxy *cliProxy;
NSString * cliArgs;
// CLI set state
BOOL launchedFromGitx;
NSString * deferredSelectSha;
NSArray * launchedDocuments;
PBCloneRepositoryPanel *cloneRepositoryPanel;
}
@property (retain) PBCLIProxy* cliProxy;
@property (copy) NSString *cliArgs;
@property (assign) BOOL launchedFromGitx;
@property (copy) NSString *deferredSelectSha;
+ (ApplicationController *) sharedApplicationController;
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator;
- (NSManagedObjectModel *)managedObjectModel;
+27 -157
View File
@@ -10,82 +10,36 @@
#import "PBGitRevisionCell.h"
#import "PBGitWindowController.h"
#import "PBRepositoryDocumentController.h"
#import "PBCLIProxy.h"
#import "PBServicesController.h"
#import "PBGitXProtocol.h"
#import "PBPrefsWindowController.h"
#import "PBNSURLPathUserDefaultsTransfomer.h"
#import "PBGitDefaults.h"
#import "Sparkle/SUUpdater.h"
#import "PBCloneRepositoryPanel.h"
#import "BMScript.h"
#import "PBGitSidebarController.h"
#import "Sparkle/SUUpdater.h"
@implementation ApplicationController
@synthesize cliProxy;
@synthesize cliArgs;
@synthesize launchedFromGitx;
@synthesize deferredSelectSha;
static ApplicationController * sharedApplicationControllerInstance = nil;
+ (void) initialize {
if (sharedApplicationControllerInstance == nil)
sharedApplicationControllerInstance = [[self alloc] init];
}
+ (ApplicationController *) sharedApplicationController {
//Already set by +initialize.
return sharedApplicationControllerInstance;
}
+ (id) allocWithZone:(NSZone *) zone {
//Usually already set by +initialize.
if (sharedApplicationControllerInstance) {
//The caller expects to receive a new object, so implicitly retain it
//to balance out the eventual release message.
return [sharedApplicationControllerInstance retain];
} else {
//When not already set, +initialize is our caller.
//It's creating the shared instance, let this go through.
return [super allocWithZone: zone];
}
}
- (id) copyWithZone:(NSZone *) zone {
return self;
}
- (NSUInteger) retainCount {
return UINT_MAX; // denotes an object that cannot be released
}
- (ApplicationController *) init
- (ApplicationController*)init
{
//If sharedApplicationControllerInstance is nil, +initialize is our caller, so initialize the instance.
//If it is not nil, simply return the instance without re-initializing it.
if (sharedApplicationControllerInstance == nil) {
#ifdef DEBUG_BUILD
[NSApp activateIgnoringOtherApps:YES];
[NSApp activateIgnoringOtherApps:YES];
#endif
if(self = [super init]) {
if(![[NSBundle bundleWithPath:@"/System/Library/Frameworks/Quartz.framework/Frameworks/QuickLookUI.framework"] load])
if(![[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/QuickLookUI.framework"] load])
NSLog(@"Could not load QuickLook");
self.cliProxy = [PBCLIProxy new];
launchedFromGitx = NO;
cliArgs = nil;
deferredSelectSha = nil;
}
/* Value Transformers */
NSValueTransformer *transformer = [[PBNSURLPathUserDefaultsTransfomer alloc] init];
[NSValueTransformer setValueTransformer:transformer forName:@"PBNSURLPathUserDefaultsTransfomer"];
// Make sure the PBGitDefaults is initialized, by calling a random method
[PBGitDefaults class];
return self;
}
return self;
if(!(self = [super init]))
return nil;
if(![[NSBundle bundleWithPath:@"/System/Library/Frameworks/Quartz.framework/Frameworks/QuickLookUI.framework"] load])
if(![[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/QuickLookUI.framework"] load])
NSLog(@"Could not load QuickLook");
/* Value Transformers */
NSValueTransformer *transformer = [[PBNSURLPathUserDefaultsTransfomer alloc] init];
[NSValueTransformer setValueTransformer:transformer forName:@"PBNSURLPathUserDefaultsTransfomer"];
// Make sure the PBGitDefaults is initialized, by calling a random method
[PBGitDefaults class];
return self;
}
- (void)registerServices
@@ -109,34 +63,16 @@ static ApplicationController * sharedApplicationControllerInstance = nil;
- (void)applicationDidFinishLaunching:(NSNotification*)notification
{
[[SUUpdater sharedUpdater] setSendsSystemProfile:YES];
// Make sure Git's SSH password requests get forwarded to our little UI tool:
setenv( "SSH_ASKPASS", [[[NSBundle mainBundle] pathForResource: @"gitx_askpasswd" ofType: @""] UTF8String], 1 );
setenv( "DISPLAY", "localhost:0", 1 );
char * launchedfromgitx = getenv("GITX_LAUNCHED_FROM_CLI");
char * cliargs = getenv("GITX_CLI_ARGUMENTS");
self.launchedFromGitx = (launchedfromgitx ? YES : NO);
if (cliargs) {
self.cliArgs = [NSString stringWithUTF8String:(cliargs)];
}
// NSLog(@"[%@ %s] launchedFromGitx = %@", [self class], _cmd, (launchedFromGitx ? @"YES" : @"NO"));
// NSLog(@"[%@ %s] cliArgs = %@", [self class], _cmd, cliArgs);
[self registerServices];
if ([cliArgs isEqualToString:@"--all"]) {
[PBGitDefaults setBranchFilter:kGitXAllBranchesFilter];
[[NSUserDefaults standardUserDefaults] synchronize];
} else if ([cliArgs isEqualToString:@"--local"]) {
[PBGitDefaults setBranchFilter:kGitXLocalRemoteBranchesFilter];
[[NSUserDefaults standardUserDefaults] synchronize];
}
BOOL hasOpenedDocuments = NO;
launchedDocuments = [[[PBRepositoryDocumentController sharedDocumentController] documents] copy];
NSArray *launchedDocuments = [[[PBRepositoryDocumentController sharedDocumentController] documents] copy];
// 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,
@@ -154,7 +90,7 @@ static ApplicationController * sharedApplicationControllerInstance = nil;
}
}
// Try to find the current directory, to open that as a repository...
// Try to find the current directory, to open that as a repository
if ([PBGitDefaults openCurDirOnLaunch] && !hasOpenedDocuments) {
NSString *curPath = [[[NSProcessInfo processInfo] environment] objectForKey:@"PWD"];
NSURL *url = nil;
@@ -166,47 +102,9 @@ static ApplicationController * sharedApplicationControllerInstance = nil;
hasOpenedDocuments = YES;
}
launchedDocuments = [[[PBRepositoryDocumentController sharedDocumentController] documents] copy];
// ...to bring the launched documents to the front
for (PBGitRepository *document in launchedDocuments) {
PBGitWindowController * wc = [(PBGitRepository *)document windowController];
PBGitHistoryController * historyViewController = wc.historyController;
NSArrayController * ccontroller = historyViewController.commitController;
// determine what to show right after start - stage or standard history view?
if ([cliArgs isEqualToString:@"--commit"] || [cliArgs isEqualToString:@"-c"]) {
[wc showCommitView:self];
launchedFromGitx = NO;
} else {
[wc showHistoryView:self];
}
if ([cliArgs hasPrefix:@"--author"]) {
NSArray * components = [cliArgs componentsSeparatedByString:@"="];
NSString * author = [components objectAtIndex:1];
[ccontroller setFilterPredicate:[NSPredicate predicateWithFormat:@"author contains[c] %@", author]];
[historyViewController.commitList selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO];
} else if ([cliArgs hasPrefix:@"--subject"]) {
NSArray * components = [cliArgs componentsSeparatedByString:@"="];
NSString * subject = [components objectAtIndex:1];
[ccontroller setFilterPredicate:[NSPredicate predicateWithFormat:@"subject contains[c] %@", subject]];
} else if ([cliArgs hasPrefix:@"--sha"]) {
NSArray * components = [cliArgs componentsSeparatedByString:@"="];
NSString * sha = [components objectAtIndex:1];
[ccontroller setFilterPredicate:[NSPredicate predicateWithFormat:@"realSha contains[c] %@", sha]];
} else if ([cliArgs hasPrefix:@"-S"]) {
NSString * subject = [cliArgs substringFromIndex:2];
[ccontroller setFilterPredicate:[NSPredicate predicateWithFormat:@"subject contains[c] %@", subject]];
}
// to bring the launched documents to the front
for (PBGitRepository *document in launchedDocuments)
[document showWindows];
}
if (launchedFromGitx) {
[self performSelector:@selector(finalizeCLILaunch:) withObject:self afterDelay:0.5];
}
if (![[NSApplication sharedApplication] isActive])
return;
@@ -217,42 +115,14 @@ static ApplicationController * sharedApplicationControllerInstance = nil;
[[PBRepositoryDocumentController sharedDocumentController] openDocument:self];
}
- (void) finalizeCLILaunch:(id)object {
for (PBGitRepository * document in launchedDocuments) {
BOOL success = [[[(PBGitRepository *)document windowController] historyController] selectCommit:self.deferredSelectSha];
// NSLog(@"[%@ %s] trying to select commit with sha %@ (success = %@)", [self class], _cmd, self.deferredSelectSha, BMStringFromBOOL(success));
if (success) {
PBGitWindowController * wc = [(PBGitRepository *)document windowController];
PBGitHistoryController * histController = wc.historyController;
PBCommitList * clist = histController.commitList;
// updating the selection with the selection seems redundant but it also updates the row select indicator
[clist selectRowIndexes:[clist selectedRowIndexes] byExtendingSelection:NO];
[histController scrollSelectionToTopOfViewFrom:0];
[histController updateKeys];
}
}
// Reset CLI indication status so KVO all over the controllers can go the intended ways again...
self.deferredSelectSha = nil;
self.launchedFromGitx = NO;
}
- (void) windowWillClose:(id)sender
- (void) windowWillClose: sender
{
if ([[[sender object] windowController] isKindOfClass:[PBPrefsWindowController class]] ) {
for (PBGitRepository * doc in [[PBRepositoryDocumentController sharedDocumentController] documents]) {
[[[doc windowForSheet] contentView] setNeedsDisplay:YES];
}
} else {
[firstResponder terminate: sender];
}
[firstResponder terminate: sender];
}
- (IBAction)openPreferencesWindow:(id)sender
{
DBPrefsWindowController * prefsWindowController = [PBPrefsWindowController sharedPrefsWindowController];
[[prefsWindowController window] setDelegate:self];
[prefsWindowController showWindow:nil];
[[PBPrefsWindowController sharedPrefsWindowController] showWindow:nil];
}
- (IBAction)showAboutPanel:(id)sender
@@ -376,7 +246,7 @@ static ApplicationController * sharedApplicationControllerInstance = nil;
fileManager = [NSFileManager defaultManager];
applicationSupportFolder = [self applicationSupportFolder];
if ( ![fileManager fileExistsAtPath:applicationSupportFolder isDirectory:NULL] ) {
[fileManager createDirectoryAtPath:applicationSupportFolder withIntermediateDirectories:YES attributes:nil error:nil];
[fileManager createDirectoryAtPath:applicationSupportFolder attributes:nil];
}
url = [NSURL fileURLWithPath: [applicationSupportFolder stringByAppendingPathComponent: @"GitTest.xml"]];
+1 -3
View File
@@ -1,4 +1,3 @@
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
@interface QLPreviewPanel : NSPanel
+ (id)sharedPreviewPanel;
@@ -90,5 +89,4 @@
- (void)setShowsAddToiPhoto:(BOOL)fp8;
- (void)setShowsiChatTheater:(BOOL)fp8;
- (void)setShowsFullscreen:(BOOL)fp8;
@end
#endif
@end
+1 -1
View File
@@ -42,7 +42,7 @@
#import <Cocoa/Cocoa.h>
@interface DBPrefsWindowController : NSWindowController <NSAnimationDelegate, NSToolbarDelegate> {
@interface DBPrefsWindowController : NSWindowController {
NSMutableArray *toolbarIdentifiers;
NSMutableDictionary *toolbarViews;
NSMutableDictionary *toolbarItems;
+2 -2
View File
@@ -74,13 +74,13 @@ static DBPrefsWindowController *_sharedPrefsWindowController = nil;
// Create a new window to display the preference views.
// If the developer attached a window to this controller
// in Interface Builder, it gets replaced with this one.
NSWindow *window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,1000,1000)
NSPanel *panel = [[[NSPanel alloc] initWithContentRect:NSMakeRect(0,0,1000,1000)
styleMask:(NSTitledWindowMask |
NSClosableWindowMask |
NSMiniaturizableWindowMask)
backing:NSBackingStoreBuffered
defer:YES] autorelease];
[self setWindow:window];
[self setWindow:panel];
contentSubview = [[[NSView alloc] initWithFrame:[[[self window] contentView] frame]] autorelease];
[contentSubview setAutoresizingMask:(NSViewMinYMargin | NSViewWidthSizable)];
[[[self window] contentView] addSubview:contentSubview];
+1196 -160
View File
File diff suppressed because it is too large Load Diff
+41 -14
View File
@@ -2,13 +2,13 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10C540</string>
<string key="IBDocument.InterfaceBuilderVersion">740</string>
<string key="IBDocument.AppKitVersion">1038.25</string>
<string key="IBDocument.HIToolboxVersion">458.00</string>
<string key="IBDocument.SystemVersion">10F569</string>
<string key="IBDocument.InterfaceBuilderVersion">788</string>
<string key="IBDocument.AppKitVersion">1038.29</string>
<string key="IBDocument.HIToolboxVersion">461.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">740</string>
<string key="NS.object.0">788</string>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -41,12 +41,12 @@
<object class="NSWindowTemplate" id="1005">
<int key="NSWindowStyleMask">1</int>
<int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{196, 408}, {397, 102}}</string>
<string key="NSWindowRect">{{196, 417}, {397, 93}}</string>
<int key="NSWTFlags">544736256</int>
<string key="NSWindowTitle">Window</string>
<string key="NSWindowClass">NSWindow</string>
<nil key="NSViewClass"/>
<string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
<string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
<object class="NSView" key="NSWindowView" id="1006">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
@@ -56,7 +56,7 @@
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">1314</int>
<object class="NSPSMatrix" key="NSDrawMatrix"/>
<string key="NSFrame">{{23, 24}, {351, 20}}</string>
<string key="NSFrame">{{18, 16}, {361, 20}}</string>
<reference key="NSSuperview" ref="1006"/>
<int key="NSpiFlags">16394</int>
<double key="NSMaxValue">100</double>
@@ -64,7 +64,7 @@
<object class="NSTextField" id="939163389">
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{17, 52}, {363, 30}}</string>
<string key="NSFrame">{{17, 56}, {363, 17}}</string>
<reference key="NSSuperview" ref="1006"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="476186767">
@@ -83,7 +83,7 @@
<string key="NSColorName">controlColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2ODY1AA</bytes>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor">
@@ -98,11 +98,11 @@
</object>
</object>
</object>
<string key="NSFrameSize">{397, 102}</string>
<string key="NSFrameSize">{397, 93}</string>
<reference key="NSSuperview"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1680, 1028}}</string>
<string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
@@ -220,9 +220,9 @@
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>{{814, 826}, {397, 102}}</string>
<string>{{814, 835}, {397, 93}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{814, 826}, {397, 102}}</string>
<string>{{814, 835}, {397, 93}}</string>
<boolean value="NO"/>
<string>{196, 240}</string>
<string>{{202, 428}, {480, 270}}</string>
@@ -271,6 +271,25 @@
<string>NSProgressIndicator</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>progressDescription</string>
<string>progressIndicator</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">progressDescription</string>
<string key="candidateClassName">NSTextField</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">progressIndicator</string>
<string key="candidateClassName">NSProgressIndicator</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">PBRemoteProgressSheet.h</string>
@@ -833,6 +852,13 @@
<string key="NS.key.0">showWindow:</string>
<string key="NS.object.0">id</string>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<string key="NS.key.0">showWindow:</string>
<object class="IBActionInfo" key="NS.object.0">
<string key="name">showWindow:</string>
<string key="candidateClassName">id</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string>
@@ -841,6 +867,7 @@
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1050" key="NS.object.0"/>
+97 -448
View File
@@ -3,19 +3,18 @@
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10C540</string>
<string key="IBDocument.InterfaceBuilderVersion">740</string>
<string key="IBDocument.InterfaceBuilderVersion">759</string>
<string key="IBDocument.AppKitVersion">1038.25</string>
<string key="IBDocument.HIToolboxVersion">458.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">740</string>
<string key="NS.object.0">759</string>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="87"/>
<integer value="62"/>
<integer value="87"/>
<integer value="1"/>
<integer value="4"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -46,56 +45,24 @@
<int key="NSvFlags">268</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSTextField" id="543928764">
<object class="NSTextField" id="25030403">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{294, 160}, {38, 17}}</string>
<string key="NSFrame">{{248, 100}, {41, 22}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="120199148">
<int key="NSCellFlags">68288064</int>
<object class="NSTextFieldCell" key="NSCell" id="1045854608">
<int key="NSCellFlags">-1804468671</int>
<int key="NSCellFlags2">272630784</int>
<string key="NSContents">chars</string>
<string key="NSContents"/>
<object class="NSFont" key="NSSupport" id="734450335">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">13</double>
<int key="NSfFlags">1044</int>
</object>
<reference key="NSControlView" ref="543928764"/>
<object class="NSColor" key="NSBackgroundColor" id="124675276">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2ODY1AA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor" id="716218002">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlTextColor</string>
<object class="NSColor" key="NSColor" id="367847822">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
</object>
</object>
</object>
</object>
<object class="NSTextField" id="449839240">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{248, 158}, {41, 22}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="517738538">
<int key="NSCellFlags">-1804468671</int>
<int key="NSCellFlags2">272630784</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="734450335"/>
<reference key="NSControlView" ref="449839240"/>
<reference key="NSControlView" ref="25030403"/>
<bool key="NSDrawsBackground">YES</bool>
<object class="NSColor" key="NSBackgroundColor" id="813784454">
<object class="NSColor" key="NSBackgroundColor">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">textBackgroundColor</string>
@@ -104,122 +71,21 @@
<bytes key="NSWhite">MQA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor" id="864701288">
<object class="NSColor" key="NSTextColor">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">textColor</string>
<reference key="NSColor" ref="367847822"/>
<object class="NSColor" key="NSColor" id="367847822">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
</object>
</object>
</object>
</object>
<object class="NSTextField" id="111525609">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{121, 160}, {122, 17}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="983379410">
<int key="NSCellFlags">68288064</int>
<int key="NSCellFlags2">71304192</int>
<string key="NSContents">Truncate to:</string>
<reference key="NSSupport" ref="734450335"/>
<reference key="NSControlView" ref="111525609"/>
<reference key="NSBackgroundColor" ref="124675276"/>
<reference key="NSTextColor" ref="716218002"/>
</object>
</object>
<object class="NSButton" id="433528106">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 185}, {273, 18}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="535185596">
<int key="NSCellFlags">-2080244224</int>
<int key="NSCellFlags2">0</int>
<string key="NSContents">Truncate large info sheet messages</string>
<reference key="NSSupport" ref="734450335"/>
<reference key="NSControlView" ref="433528106"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<object class="NSCustomResource" key="NSNormalImage" id="683824380">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSSwitch</string>
</object>
<object class="NSButtonImageSource" key="NSAlternateImage" id="690089052">
<string key="NSImageName">NSSwitch</string>
</object>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
</object>
<object class="NSButton" id="863978541">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 210}, {144, 18}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="145167696">
<int key="NSCellFlags">-2080244224</int>
<int key="NSCellFlags2">0</int>
<string key="NSContents">Show relative dates</string>
<reference key="NSSupport" ref="734450335"/>
<reference key="NSControlView" ref="863978541"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSAlternateImage" ref="690089052"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
</object>
<object class="NSButton" id="1023447188">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 235}, {233, 18}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="113310181">
<int key="NSCellFlags">-2080244224</int>
<int key="NSCellFlags2">0</int>
<string key="NSContents">Auto refresh on application focus</string>
<reference key="NSSupport" ref="734450335"/>
<reference key="NSControlView" ref="1023447188"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSAlternateImage" ref="690089052"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
</object>
<object class="NSTextField" id="25030403">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{248, 101}, {41, 22}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="1045854608">
<int key="NSCellFlags">-1804468671</int>
<int key="NSCellFlags2">272630784</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="734450335"/>
<reference key="NSControlView" ref="25030403"/>
<bool key="NSDrawsBackground">YES</bool>
<reference key="NSBackgroundColor" ref="813784454"/>
<reference key="NSTextColor" ref="864701288"/>
</object>
</object>
<object class="NSTextField" id="258144035">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{121, 103}, {122, 17}}</string>
<string key="NSFrame">{{121, 102}, {122, 17}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="1031567029">
@@ -228,14 +94,27 @@
<string key="NSContents">Display at column:</string>
<reference key="NSSupport" ref="734450335"/>
<reference key="NSControlView" ref="258144035"/>
<reference key="NSBackgroundColor" ref="124675276"/>
<reference key="NSTextColor" ref="716218002"/>
<object class="NSColor" key="NSBackgroundColor" id="124675276">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor" id="716218002">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlTextColor</string>
<reference key="NSColor" ref="367847822"/>
</object>
</object>
</object>
<object class="NSButton" id="968361983">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 130}, {273, 18}}</string>
<string key="NSFrame">{{18, 125}, {273, 18}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="782438225">
@@ -246,8 +125,13 @@
<reference key="NSControlView" ref="968361983"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSAlternateImage" ref="690089052"/>
<object class="NSCustomResource" key="NSNormalImage" id="114317419">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSSwitch</string>
</object>
<object class="NSButtonImageSource" key="NSAlternateImage" id="690089052">
<string key="NSImageName">NSSwitch</string>
</object>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">200</int>
@@ -344,7 +228,7 @@
<object class="NSButton" id="910887184">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 261}, {203, 18}}</string>
<string key="NSFrame">{{18, 150}, {203, 18}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="709654045">
@@ -355,7 +239,7 @@
<reference key="NSControlView" ref="910887184"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSNormalImage" ref="114317419"/>
<reference key="NSAlternateImage" ref="690089052"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
@@ -366,7 +250,7 @@
<object class="NSButton" id="160081910">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 286}, {279, 18}}</string>
<string key="NSFrame">{{18, 175}, {279, 18}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="876763316">
@@ -377,7 +261,7 @@
<reference key="NSControlView" ref="160081910"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSNormalImage" ref="114317419"/>
<reference key="NSAlternateImage" ref="690089052"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
@@ -388,7 +272,7 @@
<object class="NSButton" id="68472633">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 311}, {207, 18}}</string>
<string key="NSFrame">{{18, 200}, {207, 18}}</string>
<reference key="NSSuperview" ref="1005"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="456188813">
@@ -399,7 +283,7 @@
<reference key="NSControlView" ref="68472633"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSNormalImage" ref="114317419"/>
<reference key="NSAlternateImage" ref="690089052"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
@@ -408,7 +292,7 @@
</object>
</object>
</object>
<string key="NSFrameSize">{378, 347}</string>
<string key="NSFrameSize">{400, 236}</string>
<reference key="NSSuperview"/>
<string key="NSClassName">NSView</string>
</object>
@@ -422,6 +306,7 @@
<int key="NSvFlags">268</int>
<string key="NSFrame">{{39, 45}, {82, 14}}</string>
<reference key="NSSuperview" ref="970459672"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="439589942">
<int key="NSCellFlags">68288064</int>
@@ -438,6 +323,7 @@
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 103}, {260, 18}}</string>
<reference key="NSSuperview" ref="970459672"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="853304857">
<int key="NSCellFlags">-2080244224</int>
@@ -447,7 +333,7 @@
<reference key="NSControlView" ref="250497668"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSNormalImage" ref="114317419"/>
<reference key="NSAlternateImage" ref="690089052"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
@@ -460,6 +346,7 @@
<int key="NSvFlags">268</int>
<string key="NSFrame">{{130, 78}, {102, 22}}</string>
<reference key="NSSuperview" ref="970459672"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="646744412">
<int key="NSCellFlags">-2076049856</int>
@@ -547,6 +434,7 @@
<int key="NSvFlags">268</int>
<string key="NSFrame">{{39, 80}, {89, 17}}</string>
<reference key="NSSuperview" ref="970459672"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="642787685">
<int key="NSCellFlags">68288064</int>
@@ -563,6 +451,7 @@
<int key="NSvFlags">268</int>
<string key="NSFrame">{{130, 45}, {251, 14}}</string>
<reference key="NSSuperview" ref="970459672"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="617642330">
<int key="NSCellFlags">68288064</int>
@@ -587,7 +476,7 @@
<integer value="2"/>
</object>
</object>
<string key="NS.format">EEEE, d. MMMM yyyy HH:mm:ss</string>
<string key="NS.format">EEEE, MMMM d, yyyy h:mm:ss a</string>
<bool key="NS.natural">NO</bool>
</object>
<reference key="NSControlView" ref="1045127964"/>
@@ -600,6 +489,7 @@
<int key="NSvFlags">268</int>
<string key="NSFrame">{{128, 13}, {96, 28}}</string>
<reference key="NSSuperview" ref="970459672"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="329053853">
<int key="NSCellFlags">67239424</int>
@@ -616,8 +506,9 @@
</object>
</object>
</object>
<string key="NSFrameSize">{378, 139}</string>
<string key="NSFrameSize">{400, 139}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<string key="NSClassName">NSView</string>
</object>
<object class="NSCustomView" id="351117501">
@@ -639,7 +530,7 @@
<reference key="NSControlView" ref="890810109"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSNormalImage" ref="114317419"/>
<reference key="NSAlternateImage" ref="690089052"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
@@ -656,6 +547,11 @@
<string key="NSClassName">SUUpdater</string>
</object>
<object class="NSUserDefaultsController" id="557723770">
<object class="NSMutableArray" key="NSDeclaredKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>PBCommitMessageViewHasVerticalLine</string>
<string>PBCommitMessageViewVerticalLineLength</string>
</object>
<bool key="NSSharedInstance">YES</bool>
</object>
<object class="NSCustomView" id="263788152">
@@ -677,7 +573,7 @@
<reference key="NSControlView" ref="237556568"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSNormalImage" ref="114317419"/>
<reference key="NSAlternateImage" ref="690089052"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
@@ -699,7 +595,7 @@
<reference key="NSControlView" ref="485413225"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSNormalImage" ref="114317419"/>
<reference key="NSAlternateImage" ref="690089052"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
@@ -721,7 +617,7 @@
<reference key="NSControlView" ref="933582906"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSNormalImage" ref="114317419"/>
<reference key="NSAlternateImage" ref="690089052"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
@@ -743,7 +639,7 @@
<reference key="NSControlView" ref="766070942"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="683824380"/>
<reference key="NSNormalImage" ref="114317419"/>
<reference key="NSAlternateImage" ref="690089052"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
@@ -752,7 +648,7 @@
</object>
</object>
</object>
<string key="NSFrameSize">{378, 116}</string>
<string key="NSFrameSize">{400, 116}</string>
<reference key="NSSuperview"/>
<string key="NSClassName">NSView</string>
</object>
@@ -1075,6 +971,22 @@
</object>
<int key="connectionID">113</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: values.PBShowWhitespaceDifferences</string>
<reference key="source" ref="910887184"/>
<reference key="destination" ref="557723770"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="910887184"/>
<reference key="NSDestination" ref="557723770"/>
<string key="NSLabel">value: values.PBShowWhitespaceDifferences</string>
<string key="NSBinding">value</string>
<string key="NSKeyPath">values.PBShowWhitespaceDifferences</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">117</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: values.PBShowOpenPanelOnLaunch</string>
@@ -1139,94 +1051,6 @@
</object>
<int key="connectionID">135</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: values.PBShowWhitespaceDifferences</string>
<reference key="source" ref="910887184"/>
<reference key="destination" ref="557723770"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="910887184"/>
<reference key="NSDestination" ref="557723770"/>
<string key="NSLabel">value: values.PBShowWhitespaceDifferences</string>
<string key="NSBinding">value</string>
<string key="NSKeyPath">values.PBShowWhitespaceDifferences</string>
<object class="NSDictionary" key="NSOptions">
<string key="NS.key.0">NSValidatesImmediately</string>
<boolean value="YES" key="NS.object.0"/>
</object>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">136</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: values.PBRefreshAutomatically</string>
<reference key="source" ref="1023447188"/>
<reference key="destination" ref="557723770"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="1023447188"/>
<reference key="NSDestination" ref="557723770"/>
<string key="NSLabel">value: values.PBRefreshAutomatically</string>
<string key="NSBinding">value</string>
<string key="NSKeyPath">values.PBRefreshAutomatically</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">143</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: values.PBShowRelativeDates</string>
<reference key="source" ref="863978541"/>
<reference key="destination" ref="557723770"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="863978541"/>
<reference key="NSDestination" ref="557723770"/>
<string key="NSLabel">value: values.PBShowRelativeDates</string>
<string key="NSBinding">value</string>
<string key="NSKeyPath">values.PBShowRelativeDates</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">147</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: values.PBTruncateInfoText</string>
<reference key="source" ref="433528106"/>
<reference key="destination" ref="557723770"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="433528106"/>
<reference key="NSDestination" ref="557723770"/>
<string key="NSLabel">value: values.PBTruncateInfoText</string>
<string key="NSBinding">value</string>
<string key="NSKeyPath">values.PBTruncateInfoText</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">156</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: values.PBTruncateInfoTextSize</string>
<reference key="source" ref="449839240"/>
<reference key="destination" ref="557723770"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="449839240"/>
<reference key="NSDestination" ref="557723770"/>
<string key="NSLabel">value: values.PBTruncateInfoTextSize</string>
<string key="NSBinding">value</string>
<string key="NSKeyPath">values.PBTruncateInfoTextSize</string>
<object class="NSDictionary" key="NSOptions">
<string key="NS.key.0">NSValidatesImmediately</string>
<boolean value="YES" key="NS.object.0"/>
</object>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">158</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -1261,21 +1085,15 @@
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="910887184"/>
<reference ref="441589300"/>
<reference ref="525163949"/>
<reference ref="617839596"/>
<reference ref="1032928366"/>
<reference ref="68472633"/>
<reference ref="160081910"/>
<reference ref="1023447188"/>
<reference ref="863978541"/>
<reference ref="1032928366"/>
<reference ref="617839596"/>
<reference ref="525163949"/>
<reference ref="441589300"/>
<reference ref="968361983"/>
<reference ref="258144035"/>
<reference ref="25030403"/>
<reference ref="433528106"/>
<reference ref="449839240"/>
<reference ref="111525609"/>
<reference ref="543928764"/>
</object>
<reference key="parent" ref="0"/>
<string key="objectName">General</string>
@@ -1667,90 +1485,6 @@
<reference key="object" ref="1045854608"/>
<reference key="parent" ref="25030403"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">137</int>
<reference key="object" ref="1023447188"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="113310181"/>
</object>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">138</int>
<reference key="object" ref="113310181"/>
<reference key="parent" ref="1023447188"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">144</int>
<reference key="object" ref="863978541"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="145167696"/>
</object>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">145</int>
<reference key="object" ref="145167696"/>
<reference key="parent" ref="863978541"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">148</int>
<reference key="object" ref="433528106"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="535185596"/>
</object>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">149</int>
<reference key="object" ref="111525609"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="983379410"/>
</object>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">150</int>
<reference key="object" ref="449839240"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="517738538"/>
</object>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">151</int>
<reference key="object" ref="517738538"/>
<reference key="parent" ref="449839240"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">152</int>
<reference key="object" ref="983379410"/>
<reference key="parent" ref="111525609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">153</int>
<reference key="object" ref="535185596"/>
<reference key="parent" ref="433528106"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">159</int>
<reference key="object" ref="543928764"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="120199148"/>
</object>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">160</int>
<reference key="object" ref="120199148"/>
<reference key="parent" ref="543928764"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -1781,22 +1515,10 @@
<string>13.IBPluginDependency</string>
<string>130.IBPluginDependency</string>
<string>131.IBPluginDependency</string>
<string>137.IBPluginDependency</string>
<string>138.IBPluginDependency</string>
<string>14.IBPluginDependency</string>
<string>144.IBPluginDependency</string>
<string>145.IBPluginDependency</string>
<string>148.IBPluginDependency</string>
<string>149.IBPluginDependency</string>
<string>15.IBEditorWindowLastContentRect</string>
<string>15.IBPluginDependency</string>
<string>150.IBPluginDependency</string>
<string>151.IBPluginDependency</string>
<string>152.IBPluginDependency</string>
<string>153.IBPluginDependency</string>
<string>159.IBPluginDependency</string>
<string>16.IBPluginDependency</string>
<string>160.IBPluginDependency</string>
<string>17.IBPluginDependency</string>
<string>18.IBPluginDependency</string>
<string>19.IBPluginDependency</string>
@@ -1836,25 +1558,15 @@
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{610, 627}, {378, 347}}</string>
<string>{{845, 648}, {400, 236}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSMutableArray">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUserGuide">
<reference key="view" ref="1005"/>
<double key="location">20</double>
<double key="location">121</double>
<int key="affinity">0</int>
</object>
<object class="IBUserGuide">
<reference key="view" ref="1005"/>
<double key="location">358</double>
<int key="affinity">0</int>
</object>
<object class="IBUserGuide">
<reference key="view" ref="1005"/>
<double key="location">26</double>
<int key="affinity">1</int>
</object>
</object>
<string>{628, 654}</string>
<string>{{217, 442}, {480, 272}}</string>
@@ -1877,12 +1589,6 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{443, 712}, {103, 71}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1896,13 +1602,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{610, 741}, {378, 139}}</string>
<string>{{324, 683}, {400, 139}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSMutableArray">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1925,7 +1625,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{610, 763}, {378, 116}}</string>
<string>{{474, 352}, {400, 116}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1952,7 +1652,7 @@
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">160</int>
<int key="maxID">135</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -1965,13 +1665,6 @@
<string key="minorKey">DBPrefsWindowController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">BMScript.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PBPrefsWindowController</string>
<string key="superclassName">DBPrefsWindowController</string>
@@ -2432,55 +2125,6 @@
<string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">ImageKit.framework/Headers/IKImageBrowserView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">ImageKit.framework/Headers/ImageKitDeprecated.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">PDFKit.framework/Headers/PDFDocument.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">PDFKit.framework/Headers/PDFView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzComposer.framework/Headers/QCCompositionParameterView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzComposer.framework/Headers/QCCompositionPickerView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzFilters.framework/Headers/QuartzFilterManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -2709,6 +2353,7 @@
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1050" key="NS.object.0"/>
@@ -2724,5 +2369,9 @@
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<string key="IBDocument.LastKnownRelativeProjectPath">../GitX.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="NS.key.0">NSStopProgressFreestandingTemplate</string>
<string key="NS.object.0">{83, 83}</string>
</object>
</data>
</archive>
+28 -66
View File
@@ -3,16 +3,16 @@
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10C540</string>
<string key="IBDocument.InterfaceBuilderVersion">740</string>
<string key="IBDocument.InterfaceBuilderVersion">759</string>
<string key="IBDocument.AppKitVersion">1038.25</string>
<string key="IBDocument.HIToolboxVersion">458.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">740</string>
<string key="NS.object.0">759</string>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="351"/>
<integer value="3"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -97,9 +97,11 @@
<string key="NSToolbarItemPaletteLabel">Clone Repository To</string>
<nil key="NSToolbarItemToolTip"/>
<object class="NSButton" key="NSToolbarItemView" id="703553818">
<nil key="NSNextResponder"/>
<reference key="NSNextResponder"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{38, 14}, {40, 25}}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="64590231">
<int key="NSCellFlags">-2080244224</int>
@@ -142,9 +144,11 @@
<string key="NSToolbarItemPaletteLabel">Refresh</string>
<nil key="NSToolbarItemToolTip"/>
<object class="NSButton" key="NSToolbarItemView" id="438380428">
<nil key="NSNextResponder"/>
<reference key="NSNextResponder"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{8, 14}, {32, 25}}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="604536609">
<int key="NSCellFlags">-2080244224</int>
@@ -304,7 +308,7 @@
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
<string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
<string key="NSWindowContentMinSize">{600, 450}</string>
<object class="NSView" key="NSWindowView" id="751230759">
<reference key="NSNextResponder"/>
@@ -380,7 +384,7 @@
<string key="NSColorName">controlColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2ODY1AA</bytes>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor">
@@ -405,7 +409,7 @@
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
<string key="NSMinSize">{600, 528}</string>
<string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
<string key="NSFrameAutosaveName">GitX</string>
<double key="NSContentBorderThicknessMinY">31</double>
</object>
@@ -763,9 +767,9 @@
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{486, 348}, {890, 514}}</string>
<string>{{210, 655}, {890, 514}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{486, 348}, {890, 514}}</string>
<string>{{210, 655}, {890, 514}}</string>
<integer value="1"/>
<integer value="1"/>
<string>{{15, 196}, {850, 418}}</string>
@@ -816,13 +820,6 @@
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">BMScript.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PBGitWindowController</string>
<string key="superclassName">NSWindowController</string>
@@ -1231,55 +1228,6 @@
<string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">ImageKit.framework/Headers/IKImageBrowserView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">ImageKit.framework/Headers/ImageKitDeprecated.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">PDFKit.framework/Headers/PDFDocument.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">PDFKit.framework/Headers/PDFView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzComposer.framework/Headers/QCCompositionParameterView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzComposer.framework/Headers/QCCompositionPickerView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzFilters.framework/Headers/QuartzFilterManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -1487,6 +1435,7 @@
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1050" key="NS.object.0"/>
@@ -1502,5 +1451,18 @@
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<string key="IBDocument.LastKnownRelativeProjectPath">../GitX.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>CloneRepositoryTemplate</string>
<string>NSRefreshTemplate</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>{26, 15}</string>
<string>{10, 12}</string>
</object>
</object>
</data>
</archive>
+34
View File
@@ -0,0 +1,34 @@
//
// GLFileView.h
// GitX
//
// Created by German Laullon on 14/09/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "PBWebController.h"
#import "MGScopeBarDelegateProtocol.h"
#import "PBGitCommit.h"
#import "PBGitHistoryController.h"
#import "PBRefContextDelegate.h"
@class PBGitGradientBarView;
@interface GLFileView : PBWebController <MGScopeBarDelegate> {
IBOutlet PBGitHistoryController* historyController;
IBOutlet MGScopeBar *typeBar;
NSMutableArray *groups;
NSString *logFormat;
IBOutlet NSView *accessoryView;
}
- (void)showFile;
- (void)didLoad;
- (NSString *)parseBlame:(NSString *)txt;
- (NSString *)parseHTML:(NSString *)txt;
@property(retain) NSMutableArray *groups;
@property(retain) NSString *logFormat;
@end
+240
View File
@@ -0,0 +1,240 @@
//
// GLFileView.m
// GitX
//
// Created by German Laullon on 14/09/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "GLFileView.h"
#import "PBGitGradientBarView.h"
#define GROUP_LABEL @"Label" // string
#define GROUP_SEPARATOR @"HasSeparator" // BOOL as NSNumber
#define GROUP_SELECTION_MODE @"SelectionMode" // MGScopeBarGroupSelectionMode (int) as NSNumber
#define GROUP_ITEMS @"Items" // array of dictionaries, each containing the following keys:
#define ITEM_IDENTIFIER @"Identifier" // string
#define ITEM_NAME @"Name" // string
@implementation GLFileView
- (void) awakeFromNib
{
NSString *formatFile = [[NSBundle mainBundle] pathForResource:@"format" ofType:@"html" inDirectory:@"html/views/log"];
if(formatFile!=nil)
logFormat=[NSString stringWithContentsOfURL:[NSURL fileURLWithPath:formatFile] encoding:NSUTF8StringEncoding error:nil];
startFile = @"fileview";
//repository = historyController.repository;
[super awakeFromNib];
[historyController.treeController addObserver:self forKeyPath:@"selection" options:0 context:@"treeController"];
self.groups = [NSMutableArray arrayWithCapacity:0];
NSArray *items = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
startFile, ITEM_IDENTIFIER,
@"Source", ITEM_NAME,
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
@"blame", ITEM_IDENTIFIER,
@"Blame", ITEM_NAME,
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
@"log", ITEM_IDENTIFIER,
@"History", ITEM_NAME,
nil],
nil];
[self.groups addObject:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], GROUP_SEPARATOR,
[NSNumber numberWithInt:MGRadioSelectionMode], GROUP_SELECTION_MODE, // single selection group.
items, GROUP_ITEMS,
nil]];
[typeBar reloadData];
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
//NSLog(@"keyPath=%@ change=%@ context=%@ object=%@ \n %@",keyPath,change,context,object,[historyController.treeController selectedObjects]);
[self showFile];
}
- (void) showFile
{
NSArray *files=[historyController.treeController selectedObjects];
if ([files count]>0) {
PBGitTree *file=[files objectAtIndex:0];
NSString *fileTxt=@"";
if(startFile==@"fileview")
fileTxt=[self parseHTML:[file textContents]];
else if(startFile==@"blame")
fileTxt=[self parseBlame:[file blame]];
else if(startFile==@"log")
fileTxt=[file log:logFormat];
id script = [view windowScriptObject];
[script callWebScriptMethod:@"showFile" withArguments:[NSArray arrayWithObject:fileTxt]];
}
#ifdef DEBUG
NSString *dom=[[[[view mainFrame] DOMDocument] documentElement] outerHTML];
NSString *tmpFile=@"~/tmp/test.html";
[dom writeToFile:[tmpFile stringByExpandingTildeInPath] atomically:true encoding:NSUTF8StringEncoding error:nil];
#endif
}
#pragma mark JavaScript log.js methods
- (void) selectCommit:(NSString*)c
{
[historyController selectCommit:[PBGitSHA shaWithString:c]];
}
#pragma mark MGScopeBarDelegate methods
- (int)numberOfGroupsInScopeBar:(MGScopeBar *)theScopeBar
{
return [self.groups count];
}
- (NSArray *)scopeBar:(MGScopeBar *)theScopeBar itemIdentifiersForGroup:(int)groupNumber
{
return [[self.groups objectAtIndex:groupNumber] valueForKeyPath:[NSString stringWithFormat:@"%@.%@", GROUP_ITEMS, ITEM_IDENTIFIER]];
}
- (NSString *)scopeBar:(MGScopeBar *)theScopeBar labelForGroup:(int)groupNumber
{
return [[self.groups objectAtIndex:groupNumber] objectForKey:GROUP_LABEL]; // might be nil, which is fine (nil means no label).
}
- (NSString *)scopeBar:(MGScopeBar *)theScopeBar titleOfItem:(NSString *)identifier inGroup:(int)groupNumber
{
NSArray *items = [[self.groups objectAtIndex:groupNumber] objectForKey:GROUP_ITEMS];
if (items) {
for (NSDictionary *item in items) {
if ([[item objectForKey:ITEM_IDENTIFIER] isEqualToString:identifier]) {
return [item objectForKey:ITEM_NAME];
break;
}
}
}
return nil;
}
- (MGScopeBarGroupSelectionMode)scopeBar:(MGScopeBar *)theScopeBar selectionModeForGroup:(int)groupNumber
{
return [[[self.groups objectAtIndex:groupNumber] objectForKey:GROUP_SELECTION_MODE] intValue];
}
- (void)scopeBar:(MGScopeBar *)theScopeBar selectedStateChanged:(BOOL)selected forItem:(NSString *)identifier inGroup:(int)groupNumber
{
startFile=identifier;
NSString *path = [NSString stringWithFormat:@"html/views/%@", identifier];
NSString *html = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:path];
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:html]];
[[view mainFrame] loadRequest:request];
}
- (NSView *)accessoryViewForScopeBar:(MGScopeBar *)scopeBar
{
return accessoryView;
}
- (void) didLoad
{
[self showFile];
}
- (NSString *) parseHTML:(NSString *)txt
{
txt=[txt stringByReplacingOccurrencesOfString:@"&" withString:@"&amp;"];
txt=[txt stringByReplacingOccurrencesOfString:@"<" withString:@"&lt;"];
txt=[txt stringByReplacingOccurrencesOfString:@">" withString:@"&gt;"];
return txt;
}
- (NSString *) parseBlame:(NSString *)txt
{
txt=[self parseHTML:txt];
NSArray *lines = [txt componentsSeparatedByString:@"\n"];
NSString *line;
NSMutableDictionary *headers=[NSMutableDictionary dictionary];
NSMutableString *res=[NSMutableString string];
[res appendString:@"<table class='blocks'>\n"];
int i=0;
while(i<[lines count]){
line=[lines objectAtIndex:i];
NSArray *header=[line componentsSeparatedByString:@" "];
if([header count]==4){
int nLines=[(NSString *)[header objectAtIndex:3] intValue];
[res appendFormat:@"<tr class='block l%d'>\n",nLines];
line=[lines objectAtIndex:++i];
if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"author"]){
NSString *author=[line stringByReplacingOccurrencesOfString:@"author" withString:@""];
NSString *summary=nil;
while(summary==nil){
line=[lines objectAtIndex:i++];
if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"summary"]){
summary=[line stringByReplacingOccurrencesOfString:@"summary" withString:@""];
}
}
NSRange trunc={0,30};
NSString *truncate_a=author;
if([author length]>30){
truncate_a=[author substringWithRange:trunc];
}
NSString *truncate_s=summary;
if([summary length]>30){
truncate_s=[summary substringWithRange:trunc];
}
NSString *block=[NSString stringWithFormat:@"<td><p class='author'>%@</p><p class='summary'>%@</p></td>\n<td>\n",truncate_a,truncate_s];
[headers setObject:block forKey:[header objectAtIndex:0]];
}
[res appendString:[headers objectForKey:[header objectAtIndex:0]]];
NSMutableString *code=[NSMutableString string];
do{
line=[lines objectAtIndex:i++];
}while([line characterAtIndex:0]!='\t');
line=[line substringFromIndex:1];
line=[line stringByReplacingOccurrencesOfString:@"\t" withString:@"&nbsp;&nbsp;&nbsp;&nbsp;"];
[code appendString:line];
[code appendString:@"\n"];
int n;
for(n=1;n<nLines;n++){
line=[lines objectAtIndex:i++];
do{
line=[lines objectAtIndex:i++];
}while([line characterAtIndex:0]!='\t');
line=[line substringFromIndex:1];
line=[line stringByReplacingOccurrencesOfString:@"\t" withString:@"&nbsp;&nbsp;&nbsp;&nbsp;"];
[code appendString:line];
[code appendString:@"\n"];
}
[res appendFormat:@"<pre class='first-line: %@;brush: objc'>%@</pre>",[header objectAtIndex:2],code];
[res appendString:@"</td>\n"];
}else{
break;
}
[res appendString:@"</tr>\n"];
}
[res appendString:@"</table>\n"];
//NSLog(@"%@",res);
return (NSString *)res;
}
@synthesize groups;
@synthesize logFormat;
@end
+89
View File
@@ -0,0 +1,89 @@
/*
* GitX.h
*/
#import <AppKit/AppKit.h>
#import <ScriptingBridge/ScriptingBridge.h>
@class GitXApplication, GitXDocument, GitXWindow;
/*
* Standard Suite
*/
// The application's top-level scripting object.
@interface GitXApplication : SBApplication
- (SBElementArray *) documents;
- (SBElementArray *) windows;
@property (copy, readonly) NSString *name; // The name of the application.
@property (readonly) BOOL frontmost; // Is this the active application?
@property (copy, readonly) NSString *version; // The version number of the application.
- (void) open:(NSArray *)x; // Open a document.
- (void) quit; // Quit the application.
- (BOOL) exists:(id)x; // Verify that an object exists.
- (void) showDiff:(NSString *)x; // Show the supplied diff output in a GitX window.
- (void) initRepository:(NSURL *)x; // Create a git repository at the given filesystem URL.
- (void) cloneRepository:(NSString *)x to:(NSURL *)to isBare:(BOOL)isBare; // Clone a repository.
@end
// A document.
@interface GitXDocument : SBObject
@property (copy, readonly) NSString *name; // Its name.
@property (copy, readonly) NSURL *file; // Its location on disk, if it has one.
- (void) close; // Close a document.
- (void) delete; // Delete an object.
- (void) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy an object.
- (void) moveTo:(SBObject *)to; // Move an object to a new location.
- (void) searchString:(NSString *)string inMode:(NSInteger)inMode; // Highlight commits that match the given search string.
@end
// A window.
@interface GitXWindow : SBObject
@property (copy, readonly) NSString *name; // The title of the window.
- (NSInteger) id; // The unique identifier of the window.
@property NSInteger index; // The index of the window, ordered front to back.
@property NSRect bounds; // The bounding rectangle of the window.
@property (readonly) BOOL closeable; // Does the window have a close button?
@property (readonly) BOOL miniaturizable; // Does the window have a minimize button?
@property BOOL miniaturized; // Is the window minimized right now?
@property (readonly) BOOL resizable; // Can the window be resized?
@property BOOL visible; // Is the window visible right now?
@property (readonly) BOOL zoomable; // Does the window have a zoom button?
@property BOOL zoomed; // Is the window zoomed right now?
@property (copy, readonly) GitXDocument *document; // The document whose contents are displayed in the window.
- (void) close; // Close a document.
- (void) delete; // Delete an object.
- (void) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy an object.
- (void) moveTo:(SBObject *)to; // Move an object to a new location.
- (void) searchString:(NSString *)string inMode:(NSInteger)inMode; // Highlight commits that match the given search string.
@end
/*
* GitX Suite
*/
// The GitX application.
@interface GitXApplication (GitXSuite)
@end
// A document.
@interface GitXDocument (GitXSuite)
@end
+207
View File
@@ -0,0 +1,207 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="GitX Terminology">
<suite name="Standard Suite" code="????" description="Common classes and commands for all applications.">
<command name="open" code="aevtodoc" description="Open a document.">
<direct-parameter description="The file(s) to be opened.">
<type type="file" list="yes"/>
</direct-parameter>
</command>
<command name="close" code="coreclos" description="Close a document.">
<cocoa class="NSCloseCommand"/>
<direct-parameter type="specifier" description="the document(s) or window(s) to close."/>
</command>
<command name="quit" code="aevtquit" description="Quit the application.">
<cocoa class="NSQuitCommand"/>
</command>
<command name="count" code="corecnte" description="Return the number of elements of a particular class within an object.">
<cocoa class="NSCountCommand"/>
<direct-parameter type="specifier" description="The objects to be counted."/>
<parameter name="each" code="kocl" type="type" optional="yes" description="The class of objects to be counted." hidden="yes">
<cocoa key="ObjectClass"/>
</parameter>
<result type="integer" description="The count."/>
</command>
<command name="delete" code="coredelo" description="Delete an object.">
<cocoa class="NSDeleteCommand"/>
<direct-parameter type="specifier" description="The object(s) to delete."/>
</command>
<command name="duplicate" code="coreclon" description="Copy an object.">
<cocoa class="NSCloneCommand"/>
<direct-parameter type="specifier" description="The object(s) to copy."/>
<parameter name="to" code="insh" type="location specifier" description="The location for the new copy or copies." optional="yes">
<cocoa key="ToLocation"/>
</parameter>
<parameter name="with properties" code="prdt" type="record" description="Properties to set in the new copy or copies right away." optional="yes">
<cocoa key="WithProperties"/>
</parameter>
</command>
<command name="exists" code="coredoex" description="Verify that an object exists.">
<cocoa class="NSExistsCommand"/>
<direct-parameter type="any" description="The object(s) to check."/>
<result type="boolean" description="Did the object(s) exist?"/>
</command>
<command name="make" code="corecrel" description="Create a new object.">
<cocoa class="NSCreateCommand"/>
<parameter name="new" code="kocl" type="type" description="The class of the new object.">
<cocoa key="ObjectClass"/>
</parameter>
<parameter name="at" code="insh" type="location specifier" optional="yes" description="The location at which to insert the object.">
<cocoa key="Location"/>
</parameter>
<parameter name="with data" code="data" type="any" optional="yes" description="The initial contents of the object.">
<cocoa key="ObjectData"/>
</parameter>
<parameter name="with properties" code="prdt" type="record" optional="yes" description="The initial values for properties of the object.">
<cocoa key="KeyDictionary"/>
</parameter>
<result type="specifier" description="The new object."/>
</command>
<command name="move" code="coremove" description="Move an object to a new location.">
<cocoa class="NSMoveCommand"/>
<direct-parameter type="specifier" description="The object(s) to move."/>
<parameter name="to" code="insh" type="location specifier" description="The new location for the object(s).">
<cocoa key="ToLocation"/>
</parameter>
</command>
<class name="application" code="capp" description="The application's top-level scripting object.">
<cocoa class="NSApplication"/>
<property name="name" code="pnam" type="text" access="r" description="The name of the application."/>
<property name="frontmost" code="pisf" type="boolean" access="r" description="Is this the active application?">
<cocoa key="isActive"/>
</property>
<property name="version" code="vers" type="text" access="r" description="The version number of the application."/>
<element type="document">
<cocoa key="orderedDocuments"/>
</element>
<element type="window" access="r">
<cocoa key="orderedWindows"/>
</element>
<responds-to name="open">
<cocoa method="handleOpenScriptCommand:"/>
</responds-to>
<responds-to name="quit">
<cocoa method="handleQuitScriptCommand:"/>
</responds-to>
</class>
<class name="document" code="docu" description="A document.">
<cocoa class="NSDocument"/>
<property name="name" code="pnam" type="text" access="r" description="Its name.">
<cocoa key="displayName"/>
</property>
<property name="file" code="file" type="file" access="r" description="Its location on disk, if it has one.">
<cocoa key="fileURL"/>
</property>
<responds-to command="close">
<cocoa method="handleCloseScriptCommand:"/>
</responds-to>
</class>
<class name="window" code="cwin" description="A window.">
<cocoa class="NSWindow"/>
<property name="name" code="pnam" type="text" access="r" description="The title of the window.">
<cocoa key="title"/>
</property>
<property name="id" code="ID " type="integer" access="r" description="The unique identifier of the window.">
<cocoa key="uniqueID"/>
</property>
<property name="index" code="pidx" type="integer" description="The index of the window, ordered front to back.">
<cocoa key="orderedIndex"/>
</property>
<property name="bounds" code="pbnd" type="rectangle" description="The bounding rectangle of the window.">
<cocoa key="boundsAsQDRect"/>
</property>
<property name="closeable" code="hclb" type="boolean" access="r" description="Does the window have a close button?">
<cocoa key="hasCloseBox"/>
</property>
<property name="miniaturizable" code="ismn" type="boolean" access="r" description="Does the window have a minimize button?">
<cocoa key="isMiniaturizable"/>
</property>
<property name="miniaturized" code="pmnd" type="boolean" description="Is the window minimized right now?">
<cocoa key="isMiniaturized"/>
</property>
<property name="resizable" code="prsz" type="boolean" access="r" description="Can the window be resized?">
<cocoa key="isResizable"/>
</property>
<property name="visible" code="pvis" type="boolean" description="Is the window visible right now?">
<cocoa key="isVisible"/>
</property>
<property name="zoomable" code="iszm" type="boolean" access="r" description="Does the window have a zoom button?">
<cocoa key="isZoomable"/>
</property>
<property name="zoomed" code="pzum" type="boolean" description="Is the window zoomed right now?">
<cocoa key="isZoomed"/>
</property>
<property name="document" code="docu" type="document" access="r" description="The document whose contents are displayed in the window."/>
<responds-to name="close">
<cocoa method="handleCloseScriptCommand:"/>
</responds-to>
</class>
</suite>
<suite name="GitX Suite" code="GitX" description="Classes for GitX.">
<command name="show diff" code="GitXShDf" description="Show the supplied diff output in a GitX window.">
<direct-parameter type="text" description="The textual output from a diff tool."/>
</command>
<command name="init repository" code="GitXInit" description="Create a git repository at the given filesystem URL.">
<direct-parameter type="file" description="The URL of the repository to clone."/>
</command>
<command name="clone repository" code="GitXClon" description="Clone a repository.">
<direct-parameter type="text" description="The URL of the repository to clone."/>
<parameter name="to" code="URL " type="file" description="The location for the new repository.">
<cocoa key="destinationURL"/>
</parameter>
<parameter name="is bare" code="Bare" type="boolean" optional="yes" description="Indicates whether the created repository should be a bare repository.">
<cocoa key="isBare"/>
</parameter>
</command>
<command name="search" code="GitXSrch" description="Highlight commits that match the given search string.">
<direct-parameter type="specifier" description="The repository document to search."/>
<parameter name="string" code="SRCH" type="text" optional="yes" description="The string to search for.">
<cocoa key="searchString"/>
</parameter>
<parameter name="in mode" code="Mode" type="integer" optional="yes" description="The type of search (defalts to basic [Subject, Author, SHA]).">
<cocoa key="inMode"/>
</parameter>
</command>
<class-extension extends="application" description="The GitX application.">
<responds-to name="show diff">
<cocoa method="showDiffScriptCommand:"/>
</responds-to>
<responds-to name="init repository">
<cocoa method="initRepositoryScriptCommand:"/>
</responds-to>
<responds-to name="clone repository">
<cocoa method="cloneRepositoryScriptCommand:"/>
</responds-to>
</class-extension>
<class-extension extends="document" code="docu" description="A document.">
<cocoa class="PBGitRepository"/>
<responds-to name="search">
<cocoa method="findInModeScriptCommand:"/>
</responds-to>
</class-extension>
</suite>
</dictionary>
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
//
// GitXRelativeDateFormatter.h
// GitX
//
// Created by Nathan Kinsinger on 9/1/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface GitXRelativeDateFormatter : NSFormatter {
}
@end
+93
View File
@@ -0,0 +1,93 @@
//
// GitXRelativeDateFormatter.m
// GitX
//
// Created by Nathan Kinsinger on 9/1/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import "GitXRelativeDateFormatter.h"
#define MINUTE 60
#define HOUR (60 * MINUTE)
#define WEEK 7
@implementation GitXRelativeDateFormatter
- (NSString *)stringForObjectValue:(id)date
{
if (![date isKindOfClass:[NSDate class]])
return nil;
NSDate *now = [NSDate date];
NSInteger secondsAgo = lround([now timeIntervalSinceDate:date]);
if (secondsAgo < 0)
return @"In the future!";
if (secondsAgo < MINUTE)
return @"seconds ago";
if (secondsAgo < (2 * MINUTE))
return @"1 minute ago";
if (secondsAgo < HOUR)
return [NSString stringWithFormat:@"%d minutes ago", (secondsAgo / MINUTE)];
if (secondsAgo < (2 * HOUR))
return @"1 hour ago";
// figure out # of days ago based on calender days (so yesterday is the day before today not 24 hours ago)
NSDateFormatter *midnightFormmatter = [[NSDateFormatter alloc] init];
[midnightFormmatter setDateFormat:@"yyyy-MM-dd"];
NSDate *midnightOnTargetDate = [midnightFormmatter dateFromString:[midnightFormmatter stringFromDate:date]];
NSDate *midnightToday = [midnightFormmatter dateFromString:[midnightFormmatter stringFromDate:now]];
// use NSCalendar so it will handle things like leap years correctly
NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
fromDate:midnightOnTargetDate
toDate:midnightToday
options:0];
NSInteger yearsAgo = [components year];
NSInteger monthsAgo = [components month];
NSInteger daysAgo = [components day];
if (yearsAgo == 0) {
if (monthsAgo == 0) {
// return "hours ago" if it's still today, but "Yesterday" only if more than 6 hours ago
// gives people a little time to get used to the idea that yesterday is over :)
if ((daysAgo == 0) || (secondsAgo < (6 * HOUR)))
return [NSString stringWithFormat:@"%d hours ago", (secondsAgo / HOUR)];
if (daysAgo == 1)
return @"Yesterday";
if (daysAgo >= (2 * WEEK))
return [NSString stringWithFormat:@"%d weeks ago", (daysAgo / WEEK)];
return [NSString stringWithFormat:@"%d days ago", daysAgo];
}
if (monthsAgo == 1)
return @"1 month ago";
return [NSString stringWithFormat:@"%d months ago", monthsAgo];
}
if (yearsAgo == 1) {
if (monthsAgo == 0)
return @"1 year ago";
if (monthsAgo == 1)
return @"1 year 1 month ago";
return [NSString stringWithFormat:@"1 year %d months ago", monthsAgo];
}
return [NSString stringWithFormat:@"%d years ago", yearsAgo];
}
@end
+18
View File
@@ -0,0 +1,18 @@
//
// GitXScriptingConstants.h
// GitX
//
// Created by Nathan Kinsinger on 8/15/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#define kGitXBundleIdentifier @"nl.frim.GitX"
#define kGitXAEKeyArgumentsList 'ARGS'
#define kGitXCloneDestinationURLKey @"destinationURL"
#define kGitXCloneIsBareKey @"isBare"
#define kGitXFindSearchStringKey @"searchString"
#define kGitXFindInModeKey @"inMode"
+17
View File
@@ -0,0 +1,17 @@
//
// GitXTextFieldCell.h
// GitX
//
// Created by Nathan Kinsinger on 8/27/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "PBRefContextDelegate.h"
@interface GitXTextFieldCell : NSTextFieldCell {
IBOutlet id<PBRefContextDelegate> contextMenuDelegate;
}
@end
+37
View File
@@ -0,0 +1,37 @@
//
// GitXTextFieldCell.m
// GitX
//
// Created by Nathan Kinsinger on 8/27/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import "GitXTextFieldCell.h"
#import "PBGitCommit.h"
#import "PBRefController.h"
@implementation GitXTextFieldCell
- (NSColor *)highlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
// disables the cell's selection highlight
return nil;
}
- (NSMenu *)menuForEvent:(NSEvent *)anEvent inRect:(NSRect)cellFrame ofView:(NSTableView *)commitList
{
NSInteger rowIndex = [commitList rowAtPoint:(cellFrame.origin)];
NSArray *items = [contextMenuDelegate menuItemsForRow:rowIndex];
if (!items)
return nil;
NSMenu *menu = [[NSMenu alloc] init];
[menu setAutoenablesItems:NO];
for (NSMenuItem *item in items)
[menu addItem:item];
return menu;
}
@end
Binary file not shown.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 546 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.
+4
View File
@@ -89,5 +89,9 @@
</dict>
</dict>
</array>
<key>NSAppleScriptEnabled</key>
<true/>
<key>OSAScriptingDefinition</key>
<string>GitX.sdef</string>
</dict>
</plist>
Binary file not shown.
File diff suppressed because it is too large Load Diff
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.${PRODUCT_NAME:identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
+12 -6
View File
@@ -150,7 +150,8 @@
NSRect ctrlRect = NSZeroRect;
BOOL providesImages = [delegate respondsToSelector:@selector(scopeBar:imageForItem:inGroup:)];
for (int groupNum = 0; groupNum < numGroups; groupNum++) {
int groupNum;
for (groupNum = 0; groupNum < numGroups; groupNum++) {
// Add separator if appropriate.
BOOL addSeparator = (groupNum > 0); // default behavior.
if ([delegate respondsToSelector:@selector(scopeBar:showSeparatorBeforeGroup:)]) {
@@ -494,7 +495,8 @@
//NSLog(@"Got %@ - modifying groups %@", ((narrower) ? @"narrower" : @"wider"), NSStringFromRange(changedRange));
NSInteger nextXCoord = NSNotFound;
if (adjusting) {
for (int i = changedRange.location; i < NSMaxRange(changedRange); i++) {
int i;
for (i = changedRange.location; i < NSMaxRange(changedRange); i++) {
NSMutableDictionary *groupInfo = [_groups objectAtIndex:i];
if (nextXCoord == NSNotFound) {
@@ -547,7 +549,8 @@
float buttonX = nextXCoord;
NSMutableArray *menuItems = [groupInfo objectForKey:GROUP_BUTTONS];
NSArray *selectedItems = [_selectedItems objectAtIndex:i];
for (int i = 0; i < [menuItems count]; i++) {
int i;
for (i = 0; i < [menuItems count]; i++) {
NSMenuItem *menuItem = [menuItems objectAtIndex:i];
NSString *itemIdentifier = [menuItem representedObject];
NSButton *button = [self buttonForItem:itemIdentifier
@@ -579,7 +582,8 @@
if (shouldAdjustPopups) {
perGroupDelta = ((_totalGroupsWidthForPopups - availableWidth) / [_groups count]);
}
for (int i = startIndex; i < [_groups count]; i++) {
int i;
for (i = startIndex; i < [_groups count]; i++) {
NSDictionary *groupInfo = [_groups objectAtIndex:i];
BOOL menuMode = [[groupInfo objectForKey:GROUP_MENU_MODE] boolValue];
@@ -760,7 +764,8 @@
// Add appropriate items.
[popup removeAllItems];
NSMutableArray *buttons = [group objectForKey:GROUP_BUTTONS];
for (int i = 0; i < [buttons count]; i++) {
int i;
for (i = 0; i < [buttons count]; i++) {
NSButton *button = (NSButton *)[buttons objectAtIndex:i];
NSMenuItem *menuItem = [self menuItemForItem:[[button cell] representedObject]
inGroup:[button tag]
@@ -798,7 +803,8 @@
int count = [identArray count];
if (groupNumber >= count) {
// Pad identArray with nulls if appropriate, so this control lies at index groupNumber.
for (int i = count; i < groupNumber; i++) {
int i;
for (i = count; i < groupNumber; i++) {
[identArray addObject:[NSNull null]];
}
[identArray addObject:control];
+9
View File
@@ -0,0 +1,9 @@
MGScopeBar TODO
- Maybe properly support a blue gradient appearance (like Mail in Tiger)?
- Easy to change background gradient, but buttons/popups still highlight gray.
- Accessibility support
- The control needs to indicate which groups it contains, what selection-mode those groups support, etc.
- Otherwise it's just an opaque group of buttons to VoiceOver.
+18
View File
@@ -0,0 +1,18 @@
//
// NSApplication+GitXScripting.h
// GitX
//
// Created by Nathan Kinsinger on 8/15/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface NSApplication (GitXScripting)
- (void)showDiffScriptCommand:(NSScriptCommand *)command;
- (void)initRepositoryScriptCommand:(NSScriptCommand *)command;
- (void)cloneRepositoryScriptCommand:(NSScriptCommand *)command;
@end
+49
View File
@@ -0,0 +1,49 @@
//
// NSApplication+GitXScripting.m
// GitX
//
// Created by Nathan Kinsinger on 8/15/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import "NSApplication+GitXScripting.h"
#import "GitXScriptingConstants.h"
#import "PBDiffWindowController.h"
#import "PBRepositoryDocumentController.h"
#import "PBCloneRepositoryPanel.h"
@implementation NSApplication (GitXScripting)
- (void)showDiffScriptCommand:(NSScriptCommand *)command
{
NSString *diffText = [command directParameter];
if (diffText) {
PBDiffWindowController *diffController = [[PBDiffWindowController alloc] initWithDiff:diffText];
[diffController showWindow:nil];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
}
}
- (void)initRepositoryScriptCommand:(NSScriptCommand *)command
{
NSURL *repositoryURL = [command directParameter];
if (repositoryURL)
[[PBRepositoryDocumentController sharedDocumentController] initNewRepositoryAtURL:repositoryURL];
}
- (void)cloneRepositoryScriptCommand:(NSScriptCommand *)command
{
NSString *repository = [command directParameter];
if (repository) {
NSDictionary *arguments = [command arguments];
NSURL *destinationURL = [arguments objectForKey:kGitXCloneDestinationURLKey];
if (destinationURL) {
BOOL isBare = [[arguments objectForKey:kGitXCloneIsBareKey] boolValue];
[PBCloneRepositoryPanel beginCloneRepository:repository toURL:destinationURL isBare:isBare];
}
}
}
@end
+22 -32
View File
@@ -13,12 +13,9 @@
#define CONN_TIMEOUT 5
#define BUFFER_SIZE 256
#import <objc/objc-auto.h> /* for objc_collect */
@implementation NSFileHandle(NSFileHandleExt)
-(NSString*)readLine {
// If the socket is closed, return an empty string
if ([self fileDescriptor] <= 0)
return @"";
@@ -30,28 +27,26 @@
char *buffer = (char*)malloc(bufferSize + 1);
if (buffer == NULL)
[[NSException exceptionWithName:@"No memory left" reason:@"No more memory for allocating buffer" userInfo:nil] raise];
buffer[0] = '\0';
buffer[0] = '\0';
int bytesReceived = 0, n = 1;
int bytesReceived = 0, n = 0;
while (n > 0) {
while (1) {
n = read(fd, buffer + bytesReceived, 1);
if (n == 0)
break;
if (n < 0) {
if (errno == EINTR) {
n = 1;
continue;
} else {
free(buffer);
NSString *reason = [NSString stringWithFormat:@"%s:%d: read() error: %s", __PRETTY_FUNCTION__, __LINE__, strerror(errno)];
[[NSException exceptionWithName:@"Socket error" reason:reason userInfo:nil] raise];
}
}
bytesReceived++;
break;
if (n < 0) {
if (errno == EINTR)
continue;
free(buffer);
NSString *reason = [NSString stringWithFormat:@"%s:%d: read() error: %s", __PRETTY_FUNCTION__, __LINE__, strerror(errno)];
[[NSException exceptionWithName:@"Socket error" reason:reason userInfo:nil] raise];
}
bytesReceived++;
if (bytesReceived >= bufferSize) {
// Make buffer bigger
@@ -61,17 +56,14 @@
[[NSException exceptionWithName:@"No memory left" reason:@"No more memory for allocating buffer" userInfo:nil] raise];
}
switch (*(buffer + bytesReceived - 1)) {
case '\n':
buffer[bytesReceived-1] = '\0';
NSString* s = [NSString stringWithCString: buffer encoding: NSUTF8StringEncoding];
if ([s length] == 0)
s = [NSString stringWithCString: buffer encoding: NSISOLatin1StringEncoding];
free(buffer);
return s;
case '\r':
bytesReceived--;
char receivedByte = buffer[bytesReceived-1];
if (receivedByte == '\n') {
bytesReceived--;
break;
}
if (receivedByte == '\r')
bytesReceived--;
}
buffer[bytesReceived] = '\0';
@@ -80,8 +72,6 @@
retVal = [NSString stringWithCString: buffer encoding: NSISOLatin1StringEncoding];
free(buffer);
[[NSGarbageCollector defaultCollector] collectExhaustively];
return retVal;
}
-1
View File
@@ -85,7 +85,6 @@ catch_exit:
if (pmatch)
free(pmatch);
regfree(&preg);
[[NSGarbageCollector defaultCollector] collectIfNeeded];
return outMatches;
}
+4 -6
View File
@@ -7,7 +7,7 @@
//
#import <Cocoa/Cocoa.h>
#import "PBGitXErrors.h"
@interface PBCLIProxy : NSObject
{
@@ -16,12 +16,10 @@
@property (retain) NSConnection* connection;
@end
#define PBDOConnectionName @"GitXDOConnection"
#define ConnectionName @"GitX DO Connection"
#define PBCLIProxyErrorDomain @"PBCLIProxyErrorDomain"
@protocol GitXCliToolProtocol
- (BOOL) openRepository:(in bycopy NSString *)repositoryPath arguments:(in bycopy NSArray *) args error:(byref NSError**)error;
- (oneway void) openDiffWindowWithDiff:(in bycopy NSString *)diff;
- (BOOL)openRepository:(NSURL*)repositoryPath arguments: (NSArray*) args error:(NSError**)error;
- (void)openDiffWindowWithDiff:(NSString *)diff;
@end
+23 -53
View File
@@ -20,82 +20,52 @@
- (id)init
{
if (self = [super init]) {
connection = [NSConnection new];
[connection setRootObject:self];
self.connection = [NSConnection new];
[self.connection setRootObject:self];
if ([connection registerName:PBDOConnectionName] == NO)
if ([self.connection registerName:ConnectionName] == NO)
NSBeep();
}
return self;
}
- (BOOL) openRepository:(in bycopy NSString *)repositoryPath arguments:(in bycopy NSArray *)args error:(byref NSError **)error
- (BOOL)openRepository:(NSURL*)repositoryPath arguments: (NSArray*) args error:(NSError**)error;
{
// NSLog(@"============================== PBCLIProxy START ==============================");
if (!repositoryPath || !args) {
return NO;
}
// FIXME I found that creating this redundant NSURL reference was necessary to
// work around an apparent bug with GC and Distributed Objects
// I am not familiar with GC though, so perhaps I was doing something wrong.
//
// !!! Andre Berg 20100326: This is because NSURL objects are passed as proxies
// See also http://jens.mooseyard.com/2009/07/the-subtle-dangers-of-distributed-objects/#comment-3069
// We should be able to adjust this by using bycopy modifiers.
//
NSURL* url = [NSURL fileURLWithPath:repositoryPath isDirectory:YES];
NSString * fullargs = [args componentsJoinedByString:@" "];
PBGitRepository *document = [[PBRepositoryDocumentController sharedDocumentController] documentForLocation:url];
NSURL* url = [NSURL fileURLWithPath:[repositoryPath path]];
NSArray* arguments = [NSArray arrayWithArray:args];
if (!document) {
PBGitRepository *document = [[PBRepositoryDocumentController sharedDocumentController] documentForLocation:url];
if (!document) {
if (error) {
NSString *suggestion = nil;
NSInteger errCode = -1;
if ([PBGitBinary path]) {
suggestion = @"this isn't a git repository";
errCode = PBNotAGitRepositoryErrorCode;
} else {
suggestion = @"GitX can't find your git binary";
errCode = PBGitBinaryNotFoundErrorCode;
}
NSString *suggestion = [PBGitBinary path] ? @"this isn't a git repository" : @"GitX can't find your git binary";
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Could not create document. Perhaps %@", suggestion]
forKey:NSLocalizedFailureReasonErrorKey];
*error = [NSError errorWithDomain:PBCLIProxyErrorDomain code:errCode userInfo:userInfo];
*error = [NSError errorWithDomain:PBGitRepositoryErrorDomain code:2 userInfo:userInfo];
}
// NSLog(@"============================== PBCLIProxy Abort ==============================");
return NO;
} else if (![document checkRefFormat:fullargs] &&
![document checkRefFormatForBranch:fullargs]) {
}
NSString * suggestion = @"the arguments passed do not constitute a valid ref format";
NSString * recoveryInfo = @"(see git help check-ref-format)";
NSInteger errCode = PBNotAValidRefFormatErrorCode;
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat: @"Ignoring parameters passed to gitx. It appears %@.",
suggestion], NSLocalizedFailureReasonErrorKey,
recoveryInfo, NSLocalizedRecoverySuggestionErrorKey, nil];
if (error)
{
*error = [NSError errorWithDomain:PBCLIProxyErrorDomain code:errCode userInfo:userInfo];
fprintf(stderr, "\t%s\n", [[*error localizedFailureReason] UTF8String]);
}
}
// NSLog(@"document = %@ at path = %@", document, repositoryPath);
if ([arguments count] > 0 && ([[arguments objectAtIndex:0] isEqualToString:@"--commit"] ||
[[arguments objectAtIndex:0] isEqualToString:@"-c"]))
[document.windowController showCommitView:self];
else {
PBGitRevSpecifier* rev = [[PBGitRevSpecifier alloc] initWithParameters:arguments];
rev.workingDirectory = url;
document.currentBranch = [document addBranch: rev];
[document.windowController showHistoryView:self];
}
[NSApp activateIgnoringOtherApps:YES];
// NSLog(@"============================== PBCLIProxy END ==============================");
return YES;
}
- (oneway void) openDiffWindowWithDiff:(in bycopy NSString *)diff
- (void)openDiffWindowWithDiff:(NSString *)diff
{
PBDiffWindowController *diffController = [[PBDiffWindowController alloc] initWithDiff:[diff copy]];
[diffController showWindow:nil];
+3
View File
@@ -23,6 +23,7 @@
}
+ (id) panel;
+ (void)beginCloneRepository:(NSString *)repository toURL:(NSURL *)targetURL isBare:(BOOL)bare;
- (void)showMessageSheet:(NSString *)messageText infoText:(NSString *)infoText;
- (void)showErrorSheet:(NSError *)error;
@@ -38,4 +39,6 @@
@property (assign) IBOutlet NSTextField *errorMessage;
@property (assign) IBOutlet NSView *repositoryAccessoryView;
@property (assign) BOOL isBare;
@end
+17
View File
@@ -21,6 +21,8 @@
@synthesize errorMessage;
@synthesize repositoryAccessoryView;
@synthesize isBare;
#pragma mark -
@@ -31,6 +33,21 @@
return [[self alloc] initWithWindowNibName:@"PBCloneRepositoryPanel"];
}
+ (void)beginCloneRepository:(NSString *)repository toURL:(NSURL *)targetURL isBare:(BOOL)bare
{
if (!repository || [repository isEqualToString:@""] || !targetURL || [[targetURL path] isEqualToString:@""])
return;
PBCloneRepositoryPanel *clonePanel = [PBCloneRepositoryPanel panel];
[clonePanel showWindow:self];
[clonePanel.repositoryURL setStringValue:repository];
[clonePanel.destinationPath setStringValue:[targetURL path]];
clonePanel.isBare = bare;
[clonePanel clone:self];
}
- (void) awakeFromNib
{
+25
View File
@@ -0,0 +1,25 @@
//
// PBCommitHookFailedSheet.h
// GitX
//
// Created by Sebastian Staudt on 9/12/10.
// Copyright 2010 Sebastian Staudt. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "PBGitCommitController.h"
#import "PBGitXMessageSheet.h"
@interface PBCommitHookFailedSheet : PBGitXMessageSheet
{
PBGitCommitController *commitController;
}
+ (void)beginMessageSheetForWindow:(NSWindow *)parentWindow withMessageText:(NSString *)message infoText:(NSString *)info commitController:(PBGitCommitController *)controller;
- (id)initWithWindowNibName:(NSString *)windowNibName andController:(PBGitCommitController *)controller;
- (IBAction)forceCommit:(id)sender;
@end
+38
View File
@@ -0,0 +1,38 @@
//
// PBCommitHookFailedSheet.m
// GitX
//
// Created by Sebastian Staudt on 9/12/10.
// Copyright 2010 Sebastian Staudt. All rights reserved.
//
#import "PBCommitHookFailedSheet.h"
#import "PBGitWindowController.h"
@implementation PBCommitHookFailedSheet
#pragma mark -
#pragma mark PBCommitHookFailedSheet
+ (void)beginMessageSheetForWindow:(NSWindow *)parentWindow withMessageText:(NSString *)message infoText:(NSString *)info commitController:(PBGitCommitController *)controller
{
PBCommitHookFailedSheet *sheet = [[self alloc] initWithWindowNibName:@"PBCommitHookFailedSheet" andController:controller];
[sheet beginMessageSheetForWindow:parentWindow withMessageText:message infoText:info];
}
- (id)initWithWindowNibName:(NSString *)windowNibName andController:(PBGitCommitController *)controller;
{
self = [self initWithWindowNibName:windowNibName];
commitController = controller;
return self;
}
- (IBAction)forceCommit:(id)sender
{
[self closeMessageSheet:self];
[commitController forceCommit:sender];
}
@end
File diff suppressed because it is too large Load Diff
+2
View File
@@ -16,6 +16,8 @@
IBOutlet WebView* webView;
IBOutlet PBWebHistoryController *webController;
IBOutlet PBGitHistoryController *controller;
IBOutlet PBHistorySearchController *searchController;
BOOL useAdjustScroll;
NSPoint mouseDownPoint;
}
+70 -2
View File
@@ -9,6 +9,7 @@
#import "PBCommitList.h"
#import "PBGitRevisionCell.h"
#import "PBWebHistoryController.h"
#import "PBHistorySearchController.h"
@implementation PBCommitList
@@ -23,13 +24,13 @@
- (void)keyDown:(NSEvent *)event
{
NSString* character = [event charactersIgnoringModifiers];
// Pass on command-shift up/down to the responder. We want the splitview to capture this.
if ([event modifierFlags] & NSShiftKeyMask && [event modifierFlags] & NSCommandKeyMask && ([event keyCode] == 0x7E || [event keyCode] == 0x7D)) {
[self.nextResponder keyDown:event];
return;
}
if ([character isEqualToString:@" "]) {
if (controller.selectedCommitDetailsIndex == 0) {
if ([event modifierFlags] & NSShiftKeyMask)
@@ -51,6 +52,11 @@
[controller copyCommitInfo];
}
- (void) copySHA:(id)sender
{
[controller copyCommitSHA];
}
// !!! Andre Berg 20100330: Used from -scrollSelectionToTopOfViewFrom: of PBGitHistoryController
// so that when the history controller udpates the branch filter the origin of the superview gets
// shifted into multiples of the row height. Otherwise the top selected row will always be off by
@@ -117,4 +123,66 @@
return newImage;
}
#pragma mark Row highlighting
- (NSColor *)searchResultHighlightColorForRow:(NSInteger)rowIndex
{
// if the row is selected use default colors
if ([self isRowSelected:rowIndex]) {
if ([[self window] isKeyWindow]) {
if ([[self window] firstResponder] == self) {
return [NSColor alternateSelectedControlColor];
}
return [NSColor selectedControlColor];
}
return [NSColor secondarySelectedControlColor];
}
// light blue color highlighting search results
return [NSColor colorWithCalibratedRed:0.751f green:0.831f blue:0.943f alpha:0.800f];
}
- (NSColor *)searchResultHighlightStrokeColorForRow:(NSInteger)rowIndex
{
if ([self isRowSelected:rowIndex])
return [NSColor colorWithCalibratedWhite:0.0f alpha:0.30f];
return [NSColor colorWithCalibratedWhite:0.0f alpha:0.05f];
}
- (void)drawRow:(NSInteger)rowIndex clipRect:(NSRect)tableViewClipRect
{
NSRect rowRect = [self rectOfRow:rowIndex];
BOOL isRowVisible = NSIntersectsRect(rowRect, tableViewClipRect);
// draw special highlighting if the row is part of search results
if (isRowVisible && [searchController isRowInSearchResults:rowIndex]) {
NSRect highlightRect = NSInsetRect(rowRect, 1.0f, 1.0f);
float radius = highlightRect.size.height / 2.0f;
NSBezierPath *highlightPath = [NSBezierPath bezierPathWithRoundedRect:highlightRect xRadius:radius yRadius:radius];
[[self searchResultHighlightColorForRow:rowIndex] set];
[highlightPath fill];
[[self searchResultHighlightStrokeColorForRow:rowIndex] set];
[highlightPath stroke];
}
// draws the content inside the row
[super drawRow:rowIndex clipRect:tableViewClipRect];
}
- (void)highlightSelectionInClipRect:(NSRect)tableViewClipRect
{
// disable highlighting if the selected row is part of search results
// instead do the highlighting in drawRow:clipRect: above
if ([searchController isRowInSearchResults:[self selectedRow]])
return;
[super highlightSelectionInClipRect:tableViewClipRect];
}
@end
+10
View File
@@ -51,6 +51,16 @@
[self.errorMessageField setStringValue:@""];
self.shouldCheckoutBranch = [PBGitDefaults shouldCheckoutBranch];
// when creating a local branch tracking a remote branch preset the branch name to the name of the remote branch
if ([self.startRefish refishType] == kGitXRemoteBranchType) {
NSMutableArray *components = [[[self.startRefish shortName] componentsSeparatedByString:@"/"] mutableCopy];
if ([components count] > 1) {
[components removeObjectAtIndex:0];
NSString *branchName = [components componentsJoinedByString:@"/"];
[self.branchNameField setStringValue:branchName];
}
}
[NSApp beginSheet:[self window] modalForWindow:[self.repository.windowController window] modalDelegate:self didEndSelector:nil contextInfo:NULL];
}
+5
View File
@@ -9,6 +9,7 @@
#import "PBDiffWindowController.h"
#import "PBGitRepository.h"
#import "PBGitCommit.h"
#import "PBGitDefaults.h"
@implementation PBDiffWindowController
@@ -34,6 +35,10 @@
NSString *commitSelector = [NSString stringWithFormat:@"%@..%@", [startCommit realSha], [diffCommit realSha]];
NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"diff", commitSelector, nil];
if (![PBGitDefaults showWhitespaceDifferences])
[arguments insertObject:@"-w" atIndex:1];
if (filePaths) {
[arguments addObject:@"--"];
[arguments addObjectsFromArray:filePaths];
+19 -7
View File
@@ -14,14 +14,26 @@
}
+ (NSTask *) taskForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir;
+ (NSFileHandle *) handleForCommand:(NSString *)cmd withArgs:(NSArray *)args;
+ (NSFileHandle *) handleForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir;
+ (NSFileHandle*) handleForCommand: (NSString*) cmd withArgs: (NSArray*) args;
+ (NSFileHandle*) handleForCommand: (NSString*) cmd withArgs: (NSArray*) args inDir: (NSString*) dir;
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args;
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir;
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir retValue:(int *)ret;
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir inputString:(NSString *)input retValue:(int *)ret;
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir byExtendingEnvironment:(NSDictionary *)dict inputString:(NSString *)input retValue:(int *)ret;
+ (NSString*) outputForCommand: (NSString*) cmd withArgs: (NSArray*) args;
+ (NSString*) outputForCommand: (NSString*) cmd withArgs: (NSArray*) args inDir: (NSString*) dir;
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
retValue:(int *) ret;
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
inputString:(NSString *)input
retValue:(int *) ret;
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
byExtendingEnvironment:(NSDictionary *)dict
inputString:(NSString *)input
retValue:(int *) ret;
@end
+74 -68
View File
@@ -16,6 +16,26 @@
return [self handleForCommand:cmd withArgs:args inDir:nil];
}
+ (NSTask *) taskForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir
{
NSTask* task = [[NSTask alloc] init];
[task setLaunchPath:cmd];
[task setArguments:args];
if (dir)
[task setCurrentDirectoryPath:dir];
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"Show Debug Messages"])
NSLog(@"Starting command `%@ %@` in dir %@", cmd, [args componentsJoinedByString:@" "], dir);
#ifdef CLI
NSLog(@"Starting command `%@ %@` in dir %@", cmd, [args componentsJoinedByString:@" "], dir);
#endif
NSPipe* pipe = [NSPipe pipe];
[task setStandardOutput:pipe];
[task setStandardError:pipe];
return task;
}
+ (NSFileHandle*) handleForCommand: (NSString*) cmd withArgs: (NSArray*) args inDir: (NSString*) dir
{
NSTask *task = [self taskForCommand:cmd withArgs:args inDir:dir];
@@ -25,76 +45,64 @@
return handle;
}
+ (NSTask *) taskForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
retValue:(int *) ret
{
NSTask* task = [[NSTask alloc] init];
[task setLaunchPath:cmd];
[task setArguments:args];
if (dir) {
// check if the dir exists and is really a folder
BOOL isDir = NO;
if ([[NSFileManager defaultManager] fileExistsAtPath:dir isDirectory:&isDir] && isDir) {
[task setCurrentDirectoryPath:dir];
}
}
/* use getenv too so we can easily use Xcodes executable environment */
if (([[NSUserDefaults standardUserDefaults] boolForKey:@"Show Debug Messages"]) || (getenv("PBDebugEnabled")))
{
NSLog(@"Starting command `%@ %@` in dir %@", cmd, [args componentsJoinedByString:@" "], dir);
}
#ifdef CLI
NSLog(@"Starting command `%@ %@` in dir %@", cmd, [args componentsJoinedByString:@" "], dir);
#endif
NSPipe* pipe = [[NSPipe alloc] init];
[task setStandardOutput:pipe];
[task setStandardError:pipe];
return task;
return [self outputForCommand:cmd withArgs:args inDir:dir byExtendingEnvironment:nil inputString:nil retValue:ret];
}
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
inputString:(NSString *) input
retValue:(int *) ret
{
return [self outputForCommand:cmd withArgs:args inDir:dir byExtendingEnvironment:nil inputString:input retValue:ret];
}
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir retValue:(int *)ret {
return [self outputForCommand:cmd withArgs:args inDir:dir byExtendingEnvironment:nil inputString:nil retValue:ret];
}
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
byExtendingEnvironment:(NSDictionary *)dict
inputString:(NSString *) input
retValue:(int *) ret
{
NSTask *task = [self taskForCommand:cmd withArgs:args inDir:dir];
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir inputString:(NSString *)input retValue:(int *)ret {
return [self outputForCommand:cmd withArgs:args inDir:dir byExtendingEnvironment:nil inputString:input retValue:ret];
}
if (dict) {
NSMutableDictionary *env = [[[NSProcessInfo processInfo] environment] mutableCopy];
[env addEntriesFromDictionary:dict];
[task setEnvironment:env];
}
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir byExtendingEnvironment:(NSDictionary *)dict inputString:(NSString *)input retValue:(int *)ret {
NSTask * task = [self taskForCommand:cmd withArgs:args inDir:dir];
NSFileHandle* handle = [[task standardOutput] fileHandleForReading];
if (dict) {
NSMutableDictionary * env = [[[NSProcessInfo processInfo] environment] mutableCopy];
[env addEntriesFromDictionary:dict];
[task setEnvironment:env];
}
NSFileHandle * handle = [[task standardOutput] fileHandleForReading];
if (input) {
[task setStandardInput:[[NSPipe alloc] init]];
NSFileHandle * inHandle = [[task standardInput] fileHandleForWriting];
[inHandle writeData:[input dataUsingEncoding:NSUTF8StringEncoding]];
[inHandle closeFile];
}
[task launch];
NSData * data = [handle readDataToEndOfFile];
NSString * string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (!string)
string = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
// Strip trailing newline
if ([string hasSuffix:@"\n"])
string = [string substringToIndex:[string length] - 1];
[task waitUntilExit];
if (ret)
*ret = [task terminationStatus];
return string;
if (input) {
[task setStandardInput:[NSPipe pipe]];
NSFileHandle *inHandle = [[task standardInput] fileHandleForWriting];
[inHandle writeData:[input dataUsingEncoding:NSUTF8StringEncoding]];
[inHandle closeFile];
}
[task launch];
NSData* data = [handle readDataToEndOfFile];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (!string)
string = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
// Strip trailing newline
if ([string hasSuffix:@"\n"])
string = [string substringToIndex:[string length]-1];
[task waitUntilExit];
if (ret)
*ret = [task terminationStatus];
return string;
}
// We don't use the above function because then we'd have to wait until the program was finished
@@ -102,18 +110,17 @@
+ (NSString*) outputForCommand: (NSString*) cmd withArgs: (NSArray*) args inDir: (NSString*) dir
{
NSLog(@"cmd=%@ args=%@ dir=%@",cmd,args,dir);
NSTask *task = [self taskForCommand:cmd withArgs:args inDir:dir];
NSFileHandle* handle = [[task standardOutput] fileHandleForReading];
[task launch];
// This can cause a "Bad file descriptor"... when?
NSData *data;
@try {
data = [handle readDataToEndOfFile];
}
@catch (NSException * e) {
NSLog(@"Got a bad file descriptor in %s!", _cmd);
NSLog(@"Got a bad file descriptor in %@!", NSStringFromSelector(_cmd));
if ([NSThread currentThread] != [NSThread mainThread])
[task waitUntilExit];
@@ -130,7 +137,6 @@
if ([NSThread currentThread] != [NSThread mainThread])
[task waitUntilExit];
//NSLog(@"%@",string);
return string;
}
+10 -11
View File
@@ -10,22 +10,21 @@
#import "PBGitRepository.h"
#import "PBGitTree.h"
#import "PBGitRefish.h"
#include "git/oid.h"
#import "PBGitSHA.h"
extern NSString * const kGitXCommitType;
@interface PBGitCommit : NSObject <PBGitRefish> {
git_oid sha;
git_oid *parentShas;
int nParents;
PBGitSHA *sha;
NSString* subject;
NSString* author;
NSString *committer;
NSString* details;
NSString *_patch;
NSArray* parents;
NSArray *parents;
NSString *realSHA;
int timestamp;
@@ -34,8 +33,8 @@ extern NSString * const kGitXCommitType;
PBGitRepository* repository;
}
+ (id) commitWithRepository:(PBGitRepository*)repo andSha:(git_oid)newSha;
- (id) initWithRepository:(PBGitRepository *)repo andSha:(git_oid)sha;
+ (PBGitCommit *)commitWithRepository:(PBGitRepository*)repo andSha:(PBGitSHA *)newSha;
- (id)initWithRepository:(PBGitRepository *)repo andSha:(PBGitSHA *)newSha;
- (void) addRef:(PBGitRef *)ref;
- (void) removeRef:(id)ref;
@@ -50,13 +49,13 @@ extern NSString * const kGitXCommitType;
- (NSString *) shortName;
- (NSString *) refishType;
@property (readonly) git_oid *sha;
@property (readonly) PBGitSHA *sha;
@property (copy) NSString* subject;
@property (copy) NSString* author;
@property (readonly) NSArray* parents; // TODO: remove this and its uses
@property (copy) NSString *committer;
@property (retain) NSArray *parents;
@property (assign) git_oid *parentShas;
@property (assign) int nParents, timestamp;
@property (assign) int timestamp;
@property (retain) NSMutableArray* refs;
@property (readonly) NSDate *date;
+35 -107
View File
@@ -7,6 +7,7 @@
//
#import "PBGitCommit.h"
#import "PBGitSHA.h"
#import "PBGitDefaults.h"
@@ -15,95 +16,21 @@ NSString * const kGitXCommitType = @"commit";
@implementation PBGitCommit
@synthesize repository, subject, timestamp, author, parentShas, nParents, sign, lineInfo;
@synthesize repository, subject, timestamp, author, sign, lineInfo;
@synthesize sha;
@synthesize parents;
@synthesize committer;
- (NSArray *) parents
{
if (nParents == 0)
return NULL;
int i;
NSMutableArray *p = [NSMutableArray arrayWithCapacity:nParents];
for (i = 0; i < nParents; ++i)
{
char buff[GIT_OID_HEXSZ+1];
char * s = git_oid_to_string(buff, GIT_OID_HEXSZ+1, parentShas + i);
[p addObject:[NSString stringWithUTF8String:s]];
}
return p;
}
- (NSString *) description {
return [NSString stringWithFormat:@"%@, realSha = %@, %d parent(s), repository = %@",
[super description], [self realSha], nParents, repository];
}
- (NSDate *)date
{
return [NSDate dateWithTimeIntervalSince1970:timestamp];
}
-(NSString *)dateString {
if ([PBGitDefaults showRelativeDates]) {
// Code modified from Gilean ( http://stackoverflow.com/users/6305/gilean ).
// Copied from stackoverflow's accepted answer for Objective C relative dates.
// http://stackoverflow.com/questions/902950/iphone-convert-date-string-to-a-relative-time-stamp
// Modified the seconds constants with compile time math to aid in ease of adjustment of "Majic" numbers.
//
NSDate *todayDate = [NSDate date];
double ti = [self.date timeIntervalSinceDate:todayDate];
ti = ti * -1;
if(ti < 1) {
return @"In the future!";
} else if ( ti < 60 ) {
return @"less than a minute ago";
} else if ( ti < (60 * 60) ) {
int diff = round(ti / 60);
if ( diff < 2 ) {
return @"1 minute ago";
} else {
return [NSString stringWithFormat:@"%d minutes ago", diff];
}
} else if ( ti < ( 60 * 60 * 24 ) ) {
int diff = round(ti / 60 / 60);
if ( diff < 2 ) {
return @"1 hour ago";
} else {
return[NSString stringWithFormat:@"%d hours ago", diff];
}
} else if ( ti < ( 60 * 60 * 24 * 7 ) ) {
int diff = round(ti / 60 / 60 / 24);
if ( diff < 2 ) {
return @"1 day ago";
} else {
return[NSString stringWithFormat:@"%d days ago", diff];
}
} else if ( ti < ( 60 * 60 * 24 * 31.5 ) ) {
int diff = round(ti / 60 / 60 / 24 / 7);
if ( diff < 2 ) {
return @"1 week ago";
} else {
return[NSString stringWithFormat:@"%d weeks ago", diff];
}
} else if ( ti < ( 60 * 60 * 24 * 365 ) ) {
int diff = round(ti / 60 / 60 / 24 / 30);
if ( diff < 2 ) {
return @"1 month ago";
} else {
return[NSString stringWithFormat:@"%d months ago", diff];
}
} else {
float diff = round(ti / 60 / 60 / 24 / 365 * 4) / 4.0;
if ( diff < 1.25 ) {
return @"1 year ago";
} else {
return[NSString stringWithFormat:@"%g years ago", diff];
}
}
} else {
NSDateFormatter* formatter = [[NSDateFormatter alloc] initWithDateFormat:@"%Y-%m-%d %H:%M:%S" allowNaturalLanguage:NO];
return [formatter stringFromDate: self.date];
}
- (NSString *) dateString
{
NSDateFormatter* formatter = [[NSDateFormatter alloc] initWithDateFormat:@"%Y-%m-%d %H:%M:%S" allowNaturalLanguage:NO];
return [formatter stringFromDate: self.date];
}
- (NSArray*) treeContents
@@ -111,17 +38,12 @@ NSString * const kGitXCommitType = @"commit";
return self.tree.children;
}
- (git_oid *)sha
+ (PBGitCommit *)commitWithRepository:(PBGitRepository*)repo andSha:(PBGitSHA *)newSha
{
return &sha;
return [[self alloc] initWithRepository:repo andSha:newSha];
}
+ commitWithRepository:(PBGitRepository*)repo andSha:(git_oid)newSha
{
return [[[self alloc] initWithRepository:repo andSha:newSha] autorelease];
}
- initWithRepository:(PBGitRepository*) repo andSha:(git_oid)newSha
- (id)initWithRepository:(PBGitRepository*) repo andSha:(PBGitSHA *)newSha
{
details = nil;
repository = repo;
@@ -131,27 +53,18 @@ NSString * const kGitXCommitType = @"commit";
- (NSString *)realSha
{
if (!realSHA) {
char buff[GIT_OID_HEXSZ+1];
char * hex = git_oid_to_string(buff, GIT_OID_HEXSZ+1, &sha);
realSHA = [NSString stringWithUTF8String:hex];
}
return realSHA;
return sha.string;
}
- (BOOL) isOnSameBranchAs:(PBGitCommit *)other
- (BOOL) isOnSameBranchAs:(PBGitCommit *)otherCommit
{
if (!other)
if (!otherCommit)
return NO;
NSString *mySHA = [self realSha];
NSString *otherSHA = [other realSha];
if ([otherSHA isEqualToString:mySHA])
if ([self isEqual:otherCommit])
return YES;
return [repository isOnSameBranch:otherSHA asSHA:mySHA];
return [repository isOnSameBranch:otherCommit.sha asSHA:self.sha];
}
- (BOOL) isOnHeadBranch
@@ -159,6 +72,22 @@ NSString * const kGitXCommitType = @"commit";
return [self isOnSameBranchAs:[repository headCommit]];
}
- (BOOL)isEqual:(id)otherCommit
{
if (self == otherCommit)
return YES;
if (![otherCommit isMemberOfClass:[PBGitCommit class]])
return NO;
return [self.sha isEqual:[(PBGitCommit *)otherCommit sha]];
}
- (NSUInteger)hash
{
return [self.sha hash];
}
// FIXME: Remove this method once it's unused.
- (NSString*) details
{
@@ -211,17 +140,16 @@ NSString * const kGitXCommitType = @"commit";
- (NSMutableArray *)refs
{
return [[repository refs] objectForKey:[self realSha]];
return [[repository refs] objectForKey:[self sha]];
}
- (void) setRefs:(NSMutableArray *)refs
{
[[repository refs] setObject:refs forKey:[self realSha]];
[[repository refs] setObject:refs forKey:[self sha]];
}
- (void)finalize
{
free(parentShas);
[super finalize];
}
+1 -4
View File
@@ -8,7 +8,6 @@
#import <Cocoa/Cocoa.h>
#import "PBViewController.h"
#import "FileViewerController.h"
@class PBGitIndexController, PBIconAndTextCell, PBWebChangesController, PBGitIndex;
@@ -22,9 +21,6 @@
IBOutlet NSArrayController *cachedFilesController;
IBOutlet NSButton *commitButton;
IBOutlet NSView *fileViewer;
FileViewerController *fileViewerController;
IBOutlet PBGitIndexController *indexController;
IBOutlet PBWebChangesController *webController;
}
@@ -33,5 +29,6 @@
- (IBAction) refresh:(id) sender;
- (IBAction) commit:(id) sender;
- (IBAction) forceCommit:(id) sender;
- (IBAction)signOff:(id)sender;
@end
+26 -18
View File
@@ -14,9 +14,11 @@
@interface PBGitCommitController ()
- (void)refreshFinished:(NSNotification *)notification;
- (void)commitWithVerification:(BOOL) doVerify;
- (void)commitStatusUpdated:(NSNotification *)notification;
- (void)commitFinished:(NSNotification *)notification;
- (void)commitFailed:(NSNotification *)notification;
- (void)commitHookFailed:(NSNotification *)notification;
- (void)amendCommit:(NSNotification *)notification;
- (void)indexChanged:(NSNotification *)notification;
- (void)indexOperationFailed:(NSNotification *)notification;
@@ -38,6 +40,7 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitStatusUpdated:) name:PBGitIndexCommitStatus object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFinished:) name:PBGitIndexFinishedCommit object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFailed:) name:PBGitIndexCommitFailed object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitHookFailed:) name:PBGitIndexCommitHookFailed object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(amendCommit:) name:PBGitIndexAmendMessageAvailable object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(indexChanged:) name:PBGitIndexIndexUpdated object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(indexOperationFailed:) name:PBGitIndexOperationFailed object:index];
@@ -62,25 +65,11 @@
[cachedFilesController setAutomaticallyRearrangesObjects:NO];
[unstagedFilesController setAutomaticallyRearrangesObjects:NO];
fileViewerController=[[FileViewerController alloc] retain];
[fileViewerController setCommit:true];
[fileViewerController initWithRepository:repository andController:webController];
[fileViewerController loadView];
// XXXX :( ?
NSMutableArray *sv=[NSMutableArray arrayWithArray:[[fileViewer superview] subviews]];
[sv removeObjectAtIndex:0];
[sv insertObject:[fileViewerController view] atIndex:0];
[[fileViewer superview] setSubviews:sv];
webController.fileViewerController=fileViewerController;
}
- (void) removeView
- (void)closeView
{
[webController closeView];
[super finalize];
}
- (NSResponder *)firstResponder;
@@ -121,7 +110,17 @@
- (IBAction) commit:(id) sender
{
if ([[NSFileManager defaultManager] fileExistsAtPath:[[[repository fileURL] path] stringByAppendingPathComponent:@"MERGE_HEAD"]]) {
[self commitWithVerification:YES];
}
- (IBAction) forceCommit:(id) sender
{
[self commitWithVerification:NO];
}
- (void) commitWithVerification:(BOOL) doVerify
{
if ([[NSFileManager defaultManager] fileExistsAtPath:[repository.fileURL.path stringByAppendingPathComponent:@"MERGE_HEAD"]]) {
[[repository windowController] showMessageSheet:@"Cannot commit merges" infoText:@"GitX cannot commit merges yet. Please commit your changes from the command line."];
return;
}
@@ -143,7 +142,7 @@
self.isBusy = YES;
[commitMessageView setEditable:NO];
[index commitWithMessage:commitMessage];
[index commitWithMessage:commitMessage andVerify:doVerify];
}
@@ -163,7 +162,7 @@
{
[commitMessageView setEditable:YES];
[commitMessageView setString:@""];
[webController setStateMessage:[NSString stringWithString:[[notification userInfo] objectForKey:@"description"]]];
[webController setStateMessage:[NSString stringWithFormat:[[notification userInfo] objectForKey:@"description"]]];
}
- (void)commitFailed:(NSNotification *)notification
@@ -175,6 +174,15 @@
[[repository windowController] showMessageSheet:@"Commit failed" infoText:reason];
}
- (void)commitHookFailed:(NSNotification *)notification
{
self.isBusy = NO;
NSString *reason = [[notification userInfo] objectForKey:@"description"];
self.status = [@"Commit hook failed: " stringByAppendingString:reason];
[commitMessageView setEditable:YES];
[[repository windowController] showCommitHookFailedSheet:@"Commit hook failed" infoText:reason commitController:self];
}
- (void)amendCommit:(NSNotification *)notification
{
// Replace commit message with the old one if it's less than 3 characters long.
+114 -83
View File
@@ -2,13 +2,22 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10D573</string>
<string key="IBDocument.SystemVersion">10C540</string>
<string key="IBDocument.InterfaceBuilderVersion">762</string>
<string key="IBDocument.AppKitVersion">1038.29</string>
<string key="IBDocument.HIToolboxVersion">460.00</string>
<string key="IBDocument.AppKitVersion">1038.25</string>
<string key="IBDocument.HIToolboxVersion">458.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">762</string>
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.WebKitIBPlugin</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>762</string>
<string>762</string>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -17,6 +26,7 @@
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.WebKitIBPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -48,13 +58,55 @@
<int key="NSvFlags">274</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomView" id="33610104">
<object class="WebView" id="79644284">
<reference key="NSNextResponder" ref="812432808"/>
<int key="NSvFlags">4370</int>
<string key="NSFrameSize">{1351, 234}</string>
<int key="NSvFlags">274</int>
<object class="NSMutableSet" key="NSDragTypes">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="set.sortedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>Apple HTML pasteboard type</string>
<string>Apple PDF pasteboard type</string>
<string>Apple PICT pasteboard type</string>
<string>Apple URL pasteboard type</string>
<string>Apple Web Archive pasteboard type</string>
<string>NSColor pasteboard type</string>
<string>NSFilenamesPboardType</string>
<string>NSStringPboardType</string>
<string>NeXT RTFD pasteboard type</string>
<string>NeXT Rich Text Format v1.0 pasteboard type</string>
<string>NeXT TIFF v4.0 pasteboard type</string>
<string>WebURLsWithTitlesPboardType</string>
<string>public.png</string>
<string>public.url</string>
<string>public.url-name</string>
</object>
</object>
<string key="NSFrameSize">{852, 181}</string>
<reference key="NSSuperview" ref="812432808"/>
<bool key="NSViewCanDrawConcurrently">YES</bool>
<string key="NSClassName">NSView</string>
<reference key="NSNextKeyView"/>
<string key="FrameName"/>
<string key="GroupName"/>
<object class="WebPreferences" key="Preferences">
<string key="Identifier"/>
<object class="NSMutableDictionary" key="Values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>WebKitDefaultFixedFontSize</string>
<string>WebKitDefaultFontSize</string>
<string>WebKitMinimumFontSize</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="12"/>
<integer value="12"/>
<integer value="1"/>
</object>
</object>
</object>
<bool key="UseBackForwardList">YES</bool>
<bool key="AllowsUndo">YES</bool>
</object>
<object class="NSSplitView" id="217294340">
<reference key="NSNextResponder" ref="812432808"/>
@@ -84,7 +136,7 @@
<object class="NSTableView" id="588180404">
<reference key="NSNextResponder" ref="614437325"/>
<int key="NSvFlags">4352</int>
<string key="NSFrameSize">{302, 310}</string>
<string key="NSFrameSize">{189, 221}</string>
<reference key="NSSuperview" ref="614437325"/>
<bool key="NSEnabled">YES</bool>
<object class="_NSCornerView" key="NSCornerView">
@@ -95,7 +147,7 @@
<object class="NSMutableArray" key="NSTableColumns">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSTableColumn" id="746911078">
<double key="NSWidth">299</double>
<double key="NSWidth">186</double>
<double key="NSMinWidth">10</double>
<double key="NSMaxWidth">3.4028229999999999e+38</double>
<object class="NSTableHeaderCell" key="NSHeaderCell">
@@ -176,7 +228,7 @@
<int key="NSTableViewDraggingDestinationStyle">0</int>
</object>
</object>
<string key="NSFrame">{{1, 1}, {302, 310}}</string>
<string key="NSFrame">{{1, 1}, {189, 221}}</string>
<reference key="NSSuperview" ref="563607114"/>
<reference key="NSNextKeyView" ref="588180404"/>
<reference key="NSDocView" ref="588180404"/>
@@ -203,7 +255,7 @@
<double key="NSPercent">0.99470899999999995</double>
</object>
</object>
<string key="NSFrame">{{-1, -1}, {304, 312}}</string>
<string key="NSFrame">{{-1, -1}, {191, 223}}</string>
<reference key="NSSuperview" ref="663963274"/>
<reference key="NSNextKeyView" ref="614437325"/>
<int key="NSsFlags">562</int>
@@ -213,11 +265,11 @@
<bytes key="NSScrollAmts">QSAAAEEgAABBiAAAQYgAAA</bytes>
</object>
</object>
<string key="NSFrameSize">{303, 316}</string>
<string key="NSFrameSize">{190, 227}</string>
<reference key="NSSuperview" ref="208180574"/>
</object>
</object>
<string key="NSFrameSize">{303, 331}</string>
<string key="NSFrameSize">{190, 242}</string>
<reference key="NSSuperview" ref="217294340"/>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
@@ -255,7 +307,7 @@
<object class="NSButton" id="792511503">
<reference key="NSNextResponder" ref="154221104"/>
<int key="NSvFlags">289</int>
<string key="NSFrame">{{596, 0}, {96, 32}}</string>
<string key="NSFrame">{{339, 0}, {96, 32}}</string>
<reference key="NSSuperview" ref="154221104"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="767461980">
@@ -299,6 +351,7 @@
<string>Apple PNG pasteboard type</string>
<string>Apple URL pasteboard type</string>
<string>CorePasteboardFlavorType 0x6D6F6F76</string>
<string>CorePasteboardFlavorType 0x75726C20</string>
<string>NSColor pasteboard type</string>
<string>NSFilenamesPboardType</string>
<string>NSStringPboardType</string>
@@ -312,7 +365,7 @@
<string>public.url</string>
</object>
</object>
<string key="NSFrameSize">{684, 15}</string>
<string key="NSFrameSize">{427, 41}</string>
<reference key="NSSuperview" ref="245211955"/>
<object class="NSTextContainer" key="NSTextContainer" id="311869542">
<object class="NSLayoutManager" key="NSLayoutManager">
@@ -330,7 +383,7 @@
<nil key="NSDelegate"/>
</object>
<reference key="NSTextView" ref="1023793991"/>
<double key="NSWidth">684</double>
<double key="NSWidth">427</double>
<int key="NSTCFlags">1</int>
</object>
<object class="NSTextViewSharedData" key="NSSharedData">
@@ -382,11 +435,11 @@
</object>
<int key="NSTVFlags">6</int>
<string key="NSMaxSize">{1161, 1e+07}</string>
<string key="NSMinize">{216, 0}</string>
<string key="NSMinize">{223, 0}</string>
<nil key="NSDelegate"/>
</object>
</object>
<string key="NSFrame">{{1, 1}, {684, 273}}</string>
<string key="NSFrame">{{1, 1}, {427, 184}}</string>
<reference key="NSSuperview" ref="227052526"/>
<reference key="NSNextKeyView" ref="1023793991"/>
<reference key="NSDocView" ref="1023793991"/>
@@ -418,7 +471,7 @@
<double key="NSPercent">0.94565220000000005</double>
</object>
</object>
<string key="NSFrame">{{0, 33}, {686, 275}}</string>
<string key="NSFrame">{{0, 36}, {429, 186}}</string>
<reference key="NSSuperview" ref="154221104"/>
<reference key="NSNextKeyView" ref="245211955"/>
<int key="NSsFlags">530</int>
@@ -456,7 +509,7 @@
<object class="NSButton" id="1042222292">
<reference key="NSNextResponder" ref="154221104"/>
<int key="NSvFlags">289</int>
<string key="NSFrame">{{500, 0}, {96, 32}}</string>
<string key="NSFrame">{{243, 0}, {96, 32}}</string>
<reference key="NSSuperview" ref="154221104"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="964972443">
@@ -474,11 +527,11 @@
</object>
</object>
</object>
<string key="NSFrameSize">{686, 316}</string>
<string key="NSFrameSize">{429, 227}</string>
<reference key="NSSuperview" ref="635871052"/>
</object>
</object>
<string key="NSFrame">{{312, 0}, {686, 331}}</string>
<string key="NSFrame">{{199, 0}, {429, 242}}</string>
<reference key="NSSuperview" ref="217294340"/>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
@@ -521,7 +574,7 @@
<object class="NSTableView" id="638535043">
<reference key="NSNextResponder" ref="551030904"/>
<int key="NSvFlags">4352</int>
<string key="NSFrameSize">{343, 310}</string>
<string key="NSFrameSize">{214, 221}</string>
<reference key="NSSuperview" ref="551030904"/>
<int key="NSTag">1</int>
<bool key="NSEnabled">YES</bool>
@@ -533,7 +586,7 @@
<object class="NSMutableArray" key="NSTableColumns">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSTableColumn" id="79177434">
<double key="NSWidth">340</double>
<double key="NSWidth">211</double>
<double key="NSMinWidth">10</double>
<double key="NSMaxWidth">3.4028229999999999e+38</double>
<object class="NSTableHeaderCell" key="NSHeaderCell">
@@ -574,7 +627,7 @@
<int key="NSTableViewDraggingDestinationStyle">0</int>
</object>
</object>
<string key="NSFrame">{{1, 1}, {343, 310}}</string>
<string key="NSFrame">{{1, 1}, {214, 221}}</string>
<reference key="NSSuperview" ref="617511385"/>
<reference key="NSNextKeyView" ref="638535043"/>
<reference key="NSDocView" ref="638535043"/>
@@ -601,7 +654,7 @@
<double key="NSPercent">0.90033220000000003</double>
</object>
</object>
<string key="NSFrame">{{0, -1}, {345, 312}}</string>
<string key="NSFrame">{{0, -1}, {216, 223}}</string>
<reference key="NSSuperview" ref="559277910"/>
<reference key="NSNextKeyView" ref="551030904"/>
<int key="NSsFlags">562</int>
@@ -611,11 +664,11 @@
<bytes key="NSScrollAmts">QSAAAEEgAABBiAAAQYgAAA</bytes>
</object>
</object>
<string key="NSFrameSize">{344, 316}</string>
<string key="NSFrameSize">{215, 227}</string>
<reference key="NSSuperview" ref="955377287"/>
</object>
</object>
<string key="NSFrame">{{1007, 0}, {344, 331}}</string>
<string key="NSFrame">{{637, 0}, {215, 242}}</string>
<reference key="NSSuperview" ref="217294340"/>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
@@ -636,17 +689,17 @@
<bool key="NSTransparent">NO</bool>
</object>
</object>
<string key="NSFrame">{{0, 243}, {1351, 331}}</string>
<string key="NSFrame">{{0, 190}, {852, 242}}</string>
<reference key="NSSuperview" ref="812432808"/>
<bool key="NSIsVertical">YES</bool>
</object>
</object>
<string key="NSFrameSize">{1351, 574}</string>
<string key="NSFrameSize">{852, 432}</string>
<reference key="NSSuperview" ref="750704519"/>
<string key="NSAutosaveName">CommitViewSplitView</string>
</object>
</object>
<string key="NSFrameSize">{1351, 574}</string>
<string key="NSFrameSize">{852, 432}</string>
<reference key="NSSuperview"/>
<string key="NSClassName">NSView</string>
</object>
@@ -738,6 +791,22 @@
</object>
<int key="connectionID">122</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="1007648253"/>
<reference key="destination" ref="79644284"/>
</object>
<int key="connectionID">136</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">frameLoadDelegate</string>
<reference key="source" ref="79644284"/>
<reference key="destination" ref="1007648253"/>
</object>
<int key="connectionID">137</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: arrangedObjects.path</string>
@@ -962,14 +1031,6 @@
</object>
<int key="connectionID">307</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">fileViewer</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="33610104"/>
</object>
<int key="connectionID">361</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -1035,11 +1096,16 @@
<reference key="object" ref="812432808"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="79644284"/>
<reference ref="217294340"/>
<reference ref="33610104"/>
</object>
<reference key="parent" ref="750704519"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">125</int>
<reference key="object" ref="79644284"/>
<reference key="parent" ref="812432808"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">209</int>
<reference key="object" ref="217294340"/>
@@ -1065,10 +1131,10 @@
<reference key="object" ref="635871052"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="227052526"/>
<reference ref="792511503"/>
<reference ref="18874447"/>
<reference ref="1042222292"/>
<reference ref="227052526"/>
</object>
<reference key="parent" ref="217294340"/>
</object>
@@ -1242,15 +1308,6 @@
<reference key="object" ref="964972443"/>
<reference key="parent" ref="1042222292"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">360</int>
<reference key="object" ref="33610104"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="parent" ref="812432808"/>
<string key="objectName">File viewer</string>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -1268,6 +1325,7 @@
<string>113.IBPluginDependency</string>
<string>114.CustomClassName</string>
<string>114.IBPluginDependency</string>
<string>125.IBPluginDependency</string>
<string>130.IBPluginDependency</string>
<string>131.IBPluginDependency</string>
<string>132.IBPluginDependency</string>
@@ -1285,7 +1343,6 @@
<string>248.IBPluginDependency</string>
<string>278.IBPluginDependency</string>
<string>279.IBPluginDependency</string>
<string>360.IBPluginDependency</string>
<string>45.IBPluginDependency</string>
<string>46.IBPluginDependency</string>
<string>47.IBPluginDependency</string>
@@ -1303,7 +1360,7 @@
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{54, 9}, {1351, 574}}</string>
<string>{{1091, 655}, {852, 432}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="0"/>
<integer value="0"/>
@@ -1313,6 +1370,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>PBIconAndTextCell</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.WebKitIBPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1333,7 +1391,6 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>PBFileChangesTableView</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1362,7 +1419,7 @@
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">363</int>
<int key="maxID">311</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -1408,7 +1465,6 @@
<string>cachedFilesController</string>
<string>commitButton</string>
<string>commitMessageView</string>
<string>fileViewer</string>
<string>indexController</string>
<string>unstagedFilesController</string>
<string>webController</string>
@@ -1418,7 +1474,6 @@
<string>NSArrayController</string>
<string>NSButton</string>
<string>NSTextView</string>
<string>NSView</string>
<string>PBGitIndexController</string>
<string>NSArrayController</string>
<string>PBWebChangesController</string>
@@ -1429,14 +1484,6 @@
<string key="minorKey">PBGitCommitController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PBGitGradientBarView</string>
<string key="superclassName">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">PBGitGradientBarView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PBGitIndexController</string>
<string key="superclassName">NSObject</string>
@@ -1462,7 +1509,6 @@
<string>stagedTable</string>
<string>unstagedFilesController</string>
<string>unstagedTable</string>
<string>upperToolbarView</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1471,7 +1517,6 @@
<string>NSTableView</string>
<string>NSArrayController</string>
<string>NSTableView</string>
<string>PBGitGradientBarView</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -1510,17 +1555,12 @@
<object class="IBPartialClassDescription">
<string key="className">PBWebChangesController</string>
<string key="superclassName">PBWebController</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">displayControlChanged:</string>
<string key="NS.object.0">id</string>
</object>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>cachedFilesController</string>
<string>controller</string>
<string>displayControl</string>
<string>indexController</string>
<string>unstagedFilesController</string>
</object>
@@ -1528,7 +1568,6 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSArrayController</string>
<string>PBGitCommitController</string>
<string>NSSegmentedCell</string>
<string>PBGitIndexController</string>
<string>NSArrayController</string>
</object>
@@ -2060,14 +2099,6 @@
<string key="minorKey">AppKit.framework/Headers/NSScroller.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSSegmentedCell</string>
<string key="superclassName">NSActionCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSSegmentedCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSSplitView</string>
<string key="superclassName">NSView</string>
+3 -3
View File
@@ -13,7 +13,7 @@
@interface PBGitConfig : NSObject {
NSString *repositoryPath;
}
@property (copy) NSString *repositoryPath;
- (id) init;
- (id) initWithRepositoryPath:(NSString *)path;
- init;
- initWithRepositoryPath:(NSString *)path;
@end
+2 -3
View File
@@ -10,15 +10,14 @@
@implementation PBGitConfig
@synthesize repositoryPath;
- (id) init
- init
{
repositoryPath = nil;
return self;
}
- (id) initWithRepositoryPath:(NSString *)path
- initWithRepositoryPath:(NSString *)path
{
repositoryPath = path;
return self;
+3 -5
View File
@@ -12,16 +12,12 @@
}
+ (int) commitMessageViewVerticalLineLength;
+ (NSInteger) truncateInfoTextSize;
+ (BOOL) truncateInfoText;
+ (BOOL) commitMessageViewHasVerticalLine;
+ (BOOL) isGistEnabled;
+ (BOOL) isGravatarEnabled;
+ (BOOL) confirmPublicGists;
+ (BOOL) isGistPublic;
+ (BOOL) showWhitespaceDifferences;
+ (BOOL) showRelativeDates;
+ (BOOL) refreshAutomatically;
+ (BOOL)showWhitespaceDifferences;
+ (BOOL)openCurDirOnLaunch;
+ (BOOL)showOpenPanelOnLaunch;
+ (BOOL) shouldCheckoutBranch;
@@ -38,5 +34,7 @@
+ (void) removePreviousDocumentPaths;
+ (NSInteger) branchFilter;
+ (void) setBranchFilter:(NSInteger)state;
+ (NSInteger)historySearchMode;
+ (void)setHistorySearchMode:(NSInteger)mode;
@end
+46 -86
View File
@@ -7,65 +7,57 @@
//
#import "PBGitDefaults.h"
#import "PBHistorySearchController.h"
#define kDefaultVerticalLineLength 50
#define kDefaultVerticalLineLength 50
#define kCommitMessageViewVerticalLineLength @"PBCommitMessageViewVerticalLineLength"
#define kCommitMessageViewHasVerticalLine @"PBCommitMessageViewHasVerticalLine"
#define kEnableGist @"PBEnableGist"
#define kEnableGravatar @"PBEnableGravatar"
#define kConfirmPublicGists @"PBConfirmPublicGists"
#define kPublicGist @"PBGistPublic"
#define kShowWhitespaceDifferences @"PBShowWhitespaceDifferences"
#define kRefreshAutomatically @"PBRefreshAutomatically"
#define kOpenCurDirOnLaunch @"PBOpenCurDirOnLaunch"
#define kShowOpenPanelOnLaunch @"PBShowOpenPanelOnLaunch"
#define kShouldCheckoutBranch @"PBShouldCheckoutBranch"
#define kRecentCloneDestination @"PBRecentCloneDestination"
#define kSuppressAcceptDropRef @"PBSuppressAcceptDropRef"
#define kShowStageView @"PBShowStageView"
#define kOpenPreviousDocumentsOnLaunch @"PBOpenPreviousDocumentsOnLaunch"
#define kPreviousDocumentPaths @"PBPreviousDocumentPaths"
#define kBranchFilterState @"PBBranchFilter"
#define kShowRelativeDates @"PBShowRelativeDates"
#define kTruncateInfoText @"PBTruncateInfoText"
#define kTruncateInfoTextSize @"PBTruncateInfoTextSize"
#define kCommitMessageViewHasVerticalLine @"PBCommitMessageViewHasVerticalLine"
#define kEnableGist @"PBEnableGist"
#define kEnableGravatar @"PBEnableGravatar"
#define kConfirmPublicGists @"PBConfirmPublicGists"
#define kPublicGist @"PBGistPublic"
#define kShowWhitespaceDifferences @"PBShowWhitespaceDifferences"
#define kOpenCurDirOnLaunch @"PBOpenCurDirOnLaunch"
#define kShowOpenPanelOnLaunch @"PBShowOpenPanelOnLaunch"
#define kShouldCheckoutBranch @"PBShouldCheckoutBranch"
#define kRecentCloneDestination @"PBRecentCloneDestination"
#define kSuppressAcceptDropRef @"PBSuppressAcceptDropRef"
#define kShowStageView @"PBShowStageView"
#define kOpenPreviousDocumentsOnLaunch @"PBOpenPreviousDocumentsOnLaunch"
#define kPreviousDocumentPaths @"PBPreviousDocumentPaths"
#define kBranchFilterState @"PBBranchFilter"
#define kHistorySearchMode @"PBHistorySearchMode"
@implementation PBGitDefaults
+ (void) initialize {
NSMutableDictionary * defaultValues = [NSMutableDictionary dictionary];
[defaultValues setObject:[NSNumber numberWithInt:kDefaultVerticalLineLength]
+ (void)initialize
{
NSMutableDictionary *defaultValues = [NSMutableDictionary dictionary];
[defaultValues setObject:[NSNumber numberWithInt:kDefaultVerticalLineLength]
forKey:kCommitMessageViewVerticalLineLength];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kCommitMessageViewHasVerticalLine];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kEnableGist];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kEnableGravatar];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kConfirmPublicGists];
[defaultValues setObject:[NSNumber numberWithBool:NO]
forKey:kPublicGist];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kShowWhitespaceDifferences];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kOpenCurDirOnLaunch];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kShowOpenPanelOnLaunch];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kRefreshAutomatically];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kShouldCheckoutBranch];
[defaultValues setObject:[NSNumber numberWithBool:NO]
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kEnableGist];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kEnableGravatar];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kConfirmPublicGists];
[defaultValues setObject:[NSNumber numberWithBool:NO]
forKey:kPublicGist];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kShowWhitespaceDifferences];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kOpenCurDirOnLaunch];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kShowOpenPanelOnLaunch];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kShouldCheckoutBranch];
[defaultValues setObject:[NSNumber numberWithBool:NO]
forKey:kOpenPreviousDocumentsOnLaunch];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kShowRelativeDates];
[defaultValues setObject:[NSNumber numberWithBool:YES]
forKey:kTruncateInfoText];
[defaultValues setObject:[NSNumber numberWithInteger:1000]
forKey:kTruncateInfoTextSize];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultValues];
[defaultValues setObject:[NSNumber numberWithInteger:kGitXBasicSeachMode]
forKey:kHistorySearchMode];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultValues];
}
+ (int) commitMessageViewVerticalLineLength
@@ -73,16 +65,6 @@
return [[NSUserDefaults standardUserDefaults] integerForKey:kCommitMessageViewVerticalLineLength];
}
+ (BOOL) truncateInfoText
{
return [[NSUserDefaults standardUserDefaults] boolForKey:kTruncateInfoText];
}
+ (NSInteger) truncateInfoTextSize
{
return [[NSUserDefaults standardUserDefaults] integerForKey:kTruncateInfoTextSize];
}
+ (BOOL) commitMessageViewHasVerticalLine
{
return [[NSUserDefaults standardUserDefaults] boolForKey:kCommitMessageViewHasVerticalLine];
@@ -108,21 +90,11 @@
return [[NSUserDefaults standardUserDefaults] boolForKey:kPublicGist];
}
+ (BOOL) refreshAutomatically
{
return [[NSUserDefaults standardUserDefaults] boolForKey:kRefreshAutomatically];
}
+ (BOOL)showWhitespaceDifferences
{
return [[NSUserDefaults standardUserDefaults] boolForKey:kShowWhitespaceDifferences];
}
+ (BOOL)showRelativeDates
{
return [[NSUserDefaults standardUserDefaults] boolForKey:kShowRelativeDates];
}
+ (BOOL)openCurDirOnLaunch
{
return [[NSUserDefaults standardUserDefaults] boolForKey:kOpenCurDirOnLaunch];
@@ -202,26 +174,14 @@
[[NSUserDefaults standardUserDefaults] setInteger:state forKey:kBranchFilterState];
}
- (BOOL) isFeatureEnabled:(NSString *)feature
+ (NSInteger)historySearchMode
{
if([feature isEqualToString:@"gravatar"])
return [PBGitDefaults isGravatarEnabled];
else if([feature isEqualToString:@"gist"])
return [PBGitDefaults isGistEnabled];
else if([feature isEqualToString:@"confirmGist"])
return [PBGitDefaults confirmPublicGists];
else if([feature isEqualToString:@"publicGist"])
return [PBGitDefaults isGistPublic];
else if ([feature isEqualToString:@"showWhitespaceDifferences"])
return [PBGitDefaults showWhitespaceDifferences];
else
return YES;
return [[NSUserDefaults standardUserDefaults] integerForKey:kHistorySearchMode];
}
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)sel
+ (void)setHistorySearchMode:(NSInteger)mode
{
NSLog(@"[%@ %s]: self = %@ (%i)", [self class], _cmd, self,[self respondsToSelector:sel]);
return NO;
[[NSUserDefaults standardUserDefaults] setInteger:mode forKey:kHistorySearchMode];
}
+1 -1
View File
@@ -14,7 +14,7 @@
@interface PBGitGrapher : NSObject {
PBGraphCellInfo *previous;
void *pl;
void *endLane;
int curLane;
}
- (id) initWithRepository:(PBGitRepository *)repo;
+25 -20
View File
@@ -39,13 +39,16 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in
int i = 0, newPos = -1;
std::list<PBGitLane *> *currentLanes = new std::list<PBGitLane *>;
std::list<PBGitLane *> *previousLanes = (std::list<PBGitLane *> *)pl;
NSArray *parents = [commit parents];
int nParents = [parents count];
int maxLines = (previousLanes->size() + commit.nParents + 2) * 2;
int maxLines = (previousLanes->size() + nParents + 2) * 2;
struct PBGitGraphLine *lines = (struct PBGitGraphLine *)malloc(sizeof(struct PBGitGraphLine) * maxLines);
int currentLine = 0;
PBGitLane *currentLane = NULL;
BOOL didFirst = NO;
git_oid commit_oid = [[commit sha] oid];
// First, iterate over earlier columns and pass through any that don't want this commit
if (previous != nil) {
@@ -53,21 +56,16 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in
std::list<PBGitLane *>::iterator it = previousLanes->begin();
for (; it != previousLanes->end(); ++it) {
i++;
if(*it == (PBGitLane *)endLane) {
delete *it;
endLane = NULL;
continue;
}
// This is our commit! We should do a "merge": move the line from
// our upperMapping to their lowerMapping
if ((*it)->isCommit([commit sha])) {
if ((*it)->isCommit(commit_oid)) {
if (!didFirst) {
didFirst = YES;
currentLanes->push_back(*it);
currentLane = currentLanes->back();
newPos = currentLanes->size();
add_line(lines, &currentLine, 1, i, newPos,(*it)->index());
if (commit.nParents)
if (nParents)
add_line(lines, &currentLine, 0, newPos, newPos,(*it)->index());
}
else {
@@ -89,8 +87,9 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in
//Add your own parents
// If we already did the first parent, don't do so again
if (!didFirst && currentLanes->size() < MAX_LANES && commit.nParents) {
PBGitLane *newLane = new PBGitLane(commit.parentShas);
if (!didFirst && currentLanes->size() < MAX_LANES && nParents) {
git_oid parentOID = [[parents objectAtIndex:0] oid];
PBGitLane *newLane = new PBGitLane(&parentOID);
currentLanes->push_back(newLane);
newPos = currentLanes->size();
add_line(lines, &currentLine, 0, newPos, newPos, newLane->index());
@@ -102,15 +101,15 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in
// This boolean will tell us if that happened
BOOL addedParent = NO;
int parentIndex;
for (parentIndex = 1; parentIndex < commit.nParents; ++parentIndex) {
git_oid *parent = commit.parentShas + parentIndex;
int parentIndex = 0;
for (parentIndex = 1; parentIndex < nParents; ++parentIndex) {
git_oid parentOID = [[parents objectAtIndex:parentIndex] oid];
int i = 0;
BOOL was_displayed = NO;
std::list<PBGitLane *>::iterator it = currentLanes->begin();
for (; it != currentLanes->end(); ++it) {
i++;
if ((*it)->isCommit(parent)) {
if ((*it)->isCommit(parentOID)) {
add_line(lines, &currentLine, 0, i, newPos,(*it)->index());
was_displayed = YES;
break;
@@ -124,12 +123,19 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in
// Really add this parent
addedParent = YES;
PBGitLane *newLane = new PBGitLane(parent);
PBGitLane *newLane = new PBGitLane(&parentOID);
currentLanes->push_back(newLane);
add_line(lines, &currentLine, 0, currentLanes->size(), newPos, newLane->index());
}
previous = [[PBGraphCellInfo alloc] initWithPosition:newPos andLines:lines];
if (commit.lineInfo) {
previous = commit.lineInfo;
previous.position = newPos;
previous.lines = lines;
}
else
previous = [[PBGraphCellInfo alloc] initWithPosition:newPos andLines:lines];
if (currentLine > maxLines)
NSLog(@"Number of lines: %i vs allocated: %i", currentLine, maxLines);
@@ -143,11 +149,10 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in
previous.numColumns = currentLanes->size();
// Update the current lane to point to the new parent
if (currentLane && commit.nParents > 0)
currentLane->setSha(commit.parentShas[0]);
if (currentLane && nParents > 0)
currentLane->setSha([[parents objectAtIndex:0] oid]);
else
endLane = currentLane;
// currentLanes->remove(currentLane); // must be leaked without this changes
currentLanes->remove(currentLane);
delete previousLanes;
+27 -43
View File
@@ -7,92 +7,72 @@
//
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
#import "PBGitCommit.h"
#import "PBGitTree.h"
#import "PBViewController.h"
#import "PBCollapsibleSplitView.h"
#import "FileViewerController.h"
@class PBQLOutlineView;
@class PBGitSidebarController;
@class PBWebHistoryController;
@class PBGitGradientBarView;
@class PBRefController;
@class QLPreviewPanel;
@class PBCommitList;
@class PBSourceViewItem;
@class PBGitSHA;
@interface PBGitHistoryController : PBViewController <MGScopeBarDelegate>{
@class PBHistorySearchController;
@interface PBGitHistoryController : PBViewController {
IBOutlet PBRefController *refController;
IBOutlet PBCommitList* commitList;
IBOutlet PBCollapsibleSplitView *historySplitView;
IBOutlet PBGitGradientBarView *upperToolbarView;
IBOutlet PBGitGradientBarView *scopeBarView;
IBOutlet NSSearchField *searchField;
IBOutlet NSArrayController* commitController;
IBOutlet NSTreeController* treeController;
IBOutlet NSOutlineView* fileBrowser;
NSArray *currentFileBrowserSelectionPath;
IBOutlet PBCommitList* commitList;
IBOutlet PBCollapsibleSplitView *historySplitView;
IBOutlet PBWebHistoryController *webHistoryController;
QLPreviewPanel* previewPanel;
IBOutlet PBHistorySearchController *searchController;
IBOutlet PBGitGradientBarView *upperToolbarView;
IBOutlet NSButton *mergeButton;
IBOutlet NSButton *cherryPickButton;
IBOutlet NSButton *rebaseButton;
IBOutlet PBGitGradientBarView *scopeBarView;
IBOutlet NSButton *allBranchesFilterItem;
IBOutlet NSButton *localRemoteBranchesFilterItem;
IBOutlet NSButton *selectedBranchFilterItem;
IBOutlet NSView *fileViewer;
FileViewerController *fileViewerController;
IBOutlet id webView;
// moved from PBGitSidebarController
IBOutlet NSSegmentedControl * remoteControls;
__weak QLPreviewPanel* previewPanel;
int selectedCommitDetailsIndex;
BOOL forceSelectionUpdate;
NSArray *currentFileBrowserSelectionPath;
IBOutlet MGScopeBar *treeStyle;
NSArray *treeOpts;
PBGitTree *gitTree;
PBGitCommit *webCommit;
PBGitCommit *selectedCommit;
PBSourceViewItem * sidebarRemotes;
NSOutlineView * sidebarSourceView;
}
@property (readonly) NSTreeController* treeController;
@property (assign) int selectedCommitDetailsIndex;
@property (retain) PBGitCommit *webCommit;
@property (retain) PBGitTree* gitTree;
@property (readonly) NSArrayController *commitController;
@property (readonly) PBCommitList *commitList;
@property (readonly) PBRefController *refController;
@property (assign) NSOutlineView * sidebarSourceView;
@property (assign) PBSourceViewItem * sidebarRemotes;
@property (readonly) NSSearchField *searchField;
@property (retain) IBOutlet id webView;
@property (readonly) PBHistorySearchController *searchController;
@property (readonly) PBCommitList *commitList;
- (IBAction) setDetailedView:(id)sender;
- (IBAction) setTreeView:(id)sender;
- (IBAction) setBranchFilter:(id)sender;
- (void)selectCommit:(PBGitSHA *)commit;
- (IBAction) refresh:(id)sender;
- (IBAction) toggleQLPreviewPanel:(id)sender;
- (IBAction) openSelectedFile:(id)sender;
- (BOOL) selectCommit: (NSString*) commit;
- (void) updateKeys;
- (void) updateQuicklookForce: (BOOL) force;
- (void) scrollSelectionToTopOfViewFrom:(NSInteger)oldIndex;
// Moved over Sidebar methods
- (IBAction) fetchPullPushAction:(id)sender;
- (void) updateRemoteControls:(PBGitRef *)forRef;
// Context menu methods
- (NSMenu *)contextMenuForTreeView;
- (NSArray *)menuItemsForPaths:(NSArray *)paths;
@@ -108,7 +88,12 @@
- (IBAction) cherryPick:(id)sender;
- (IBAction) rebase:(id)sender;
// Find/Search methods
- (IBAction)selectNext:(id)sender;
- (IBAction)selectPrevious:(id)sender;
- (void) copyCommitInfo;
- (void) copyCommitSHA;
- (BOOL) hasNonlinearPath;
@@ -119,5 +104,4 @@
- (CGFloat)splitView:(NSSplitView *)sender constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)offset;
- (CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)offset;
- (IBAction)updateFileViwer:(id)sender;
@end
+125 -263
View File
@@ -7,12 +7,11 @@
//
#import "PBGitHistoryController.h"
#import "PBWebHistoryController.h"
#import "CWQuickLook.h"
#import "PBGitGrapher.h"
#import "PBGitRevisionCell.h"
#import "PBCommitList.h"
#import "ApplicationController.h"
#import "PBQLOutlineView.h"
#import "PBCreateBranchSheet.h"
#import "PBCreateTagSheet.h"
#import "PBAddRemoteSheet.h"
@@ -21,11 +20,11 @@
#import "PBDiffWindowController.h"
#import "PBGitDefaults.h"
#import "PBGitRevList.h"
#import "PBCommitList.h"
#import "PBSourceViewItem.h"
#import "PBRefController.h"
#import "PBHistorySearchController.h"
#define QLPreviewPanel NSClassFromString(@"QLPreviewPanel")
#import "PBQLTextView.h"
#define kHistorySelectedDetailIndexKey @"PBHistorySelectedDetailIndex"
#define kHistoryDetailViewIndex 0
#define kHistoryTreeViewIndex 1
@@ -40,34 +39,10 @@
@implementation PBGitHistoryController
@synthesize selectedCommitDetailsIndex, webCommit, gitTree;
@synthesize commitController, refController;
@synthesize sidebarSourceView, sidebarRemotes;
@synthesize searchField;
@synthesize selectedCommitDetailsIndex, webCommit, gitTree, commitController, refController;
@synthesize searchController;
@synthesize commitList;
@synthesize webView;
#pragma mark NSToolbarItemValidation Methods
- (BOOL) validateToolbarItem:(NSToolbarItem *)theItem {
NSString * curBranchDesc = [[repository currentBranch] description];
NSArray * candidates = [NSArray arrayWithObjects:@"Push", @"Pull", @"Rebase", nil];
BOOL res;
if (([candidates containsObject:[theItem label]]) &&
(([curBranchDesc isEqualToString:@"All branches"]) ||
([curBranchDesc isEqualToString:@"Local branches"])))
{
res = NO;
} else {
res = YES;
}
return res;
}
#pragma mark PBGitHistoryController
@synthesize treeController;
- (void)awakeFromNib
{
@@ -78,15 +53,9 @@
[treeController addObserver:self forKeyPath:@"selection" options:0 context:@"treeChange"];
[repository.revisionList addObserver:self forKeyPath:@"isUpdating" options:0 context:@"revisionListUpdating"];
[repository.revisionList addObserver:self forKeyPath:@"updatedGraph" options:0 context:@"revisionListUpdatedGraph"];
[repository addObserver:self forKeyPath:@"currentBranch" options:0 context:@"branchChange"];
[repository addObserver:self forKeyPath:@"refs" options:0 context:@"updateRefs"];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(preferencesChangedWithNotification:)
name:NSUserDefaultsDidChangeNotification
object:nil];
[repository addObserver:self forKeyPath:@"currentBranchFilter" options:0 context:@"branchFilterChange"];
forceSelectionUpdate = YES;
NSSize cellSpacing = [commitList intercellSpacing];
@@ -94,17 +63,17 @@
[commitList setIntercellSpacing:cellSpacing];
[fileBrowser setTarget:self];
[fileBrowser setDoubleAction:@selector(openSelectedFile:)];
if (!repository.currentBranch) {
[repository reloadRefs];
[repository readCurrentBranch];
}
else
[repository lazyReload];
// Set a sort descriptor for the subject column in the history list, as
// It can't be sorted by default (because it's bound to a PBGitCommit)
[[commitList tableColumnWithIdentifier:@"subject"] setSortDescriptorPrototype:[[NSSortDescriptor alloc] initWithKey:@"subject" ascending:YES]];
[[commitList tableColumnWithIdentifier:@"SubjectColumn"] setSortDescriptorPrototype:[[NSSortDescriptor alloc] initWithKey:@"subject" ascending:YES]];
// Add a menu that allows a user to select which columns to view
[[commitList headerView] setMenu:[self tableColumnMenu]];
[historySplitView setTopMin:58.0 andBottomMin:100.0];
@@ -116,48 +85,37 @@
//[scopeBarView setTopShade:207/255.0 bottomShade:180/255.0];
[self updateBranchFilterMatrix];
// [webViewFileViwer setFrameLoadDelegate:self];
fileViewerController=[[FileViewerController alloc] retain];
[fileViewerController initWithRepository:repository andController:self];
[fileViewerController loadView];
//[fileViewer setAutoresizesSubviews:YES];
//[fileViewer addSubview:[fileViewerController view]];
// XXXX :( ?
NSMutableArray *sv=[NSMutableArray arrayWithArray:[[fileViewer superview] subviews]];
[sv removeObjectAtIndex:1];
[sv insertObject:[fileViewerController view] atIndex:1];
[[fileViewer superview] setSubviews:sv];
[super awakeFromNib];
}
- (void) updateKeys
- (void)updateKeys
{
PBGitCommit * lastObject = [[commitController selectedObjects] lastObject];
if (lastObject) {
selectedCommit = lastObject;
}
PBGitCommit *lastObject = [[commitController selectedObjects] lastObject];
if (lastObject) {
if (![selectedCommit isEqual:lastObject]) {
selectedCommit = lastObject;
BOOL isOnHeadBranch = [selectedCommit isOnHeadBranch];
[mergeButton setEnabled:!isOnHeadBranch];
[cherryPickButton setEnabled:!isOnHeadBranch];
[rebaseButton setEnabled:!isOnHeadBranch];
}
}
else {
[mergeButton setEnabled:NO];
[cherryPickButton setEnabled:NO];
[rebaseButton setEnabled:NO];
}
if (self.selectedCommitDetailsIndex == kHistoryTreeViewIndex) {
PBGitTree *pt = selectedCommit.tree;
NSString *show=[[[treeStyle selectedItems] objectAtIndex:0] objectAtIndex:0];
pt.onlyCommit=[show isEqualToString:@"Only Commit"];
self.gitTree=pt;
self.gitTree = selectedCommit.tree;
[self restoreFileBrowserSelection];
}
else // kHistoryDetailViewIndex
else {
// kHistoryDetailViewIndex
if (![self.webCommit isEqual:selectedCommit])
self.webCommit = selectedCommit;
BOOL isOnHeadBranch = [selectedCommit isOnHeadBranch];
[mergeButton setEnabled:!isOnHeadBranch];
[cherryPickButton setEnabled:!isOnHeadBranch];
[rebaseButton setEnabled:!isOnHeadBranch];
}
}
- (void) updateBranchFilterMatrix
@@ -196,6 +154,11 @@
return nil;
}
- (BOOL)isCommitSelected
{
return [selectedCommit isEqual:[[commitController selectedObjects] lastObject]];
}
- (void) setSelectedCommitDetailsIndex:(int)detailsIndex
{
if (selectedCommitDetailsIndex == detailsIndex)
@@ -213,10 +176,6 @@
self.status = [NSString stringWithFormat:@"%d commits loaded", [[commitController arrangedObjects] count]];
}
- (void) preferencesChangedWithNotification:(NSNotification *)notification {
[[[repository windowForSheet] contentView] setNeedsDisplay:YES];
}
- (void) restoreFileBrowserSelection
{
if (self.selectedCommitDetailsIndex != kHistoryTreeViewIndex)
@@ -262,10 +221,6 @@
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([ApplicationController sharedApplicationController].launchedFromGitx) {
return;
}
if ([(NSString *)context isEqualToString: @"commitChange"]) {
[self updateKeys];
[self restoreFileBrowserSelection];
@@ -275,15 +230,6 @@
if ([(NSString *)context isEqualToString: @"treeChange"]) {
[self updateQuicklookForce: NO];
[self saveFileBrowserSelection];
NSLog(@"---> %@",object);
NSArray *objects = [(NSTreeController *)object selectedObjects];
if([objects count]){
PBGitTree *tree=(PBGitTree *)[objects objectAtIndex:0];
NSLog(@"---> %@",tree.fullPath);
[fileViewerController showFile:tree.fullPath sha:tree.sha];
}
//[self updateFileViwer:nil];
return;
}
@@ -300,16 +246,19 @@
return;
}
if([(NSString *)context isEqualToString:@"updateCommitCount"] || [(NSString *)context isEqualToString:@"revisionListUpdating"]) {
[self updateStatus];
if ([(NSString *)context isEqualToString:@"branchFilterChange"]) {
[PBGitDefaults setBranchFilter:repository.currentBranchFilter];
[self updateBranchFilterMatrix];
return;
}
if([(NSString *)context isEqualToString:@"revisionListUpdatedGraph"]) {
if([(NSString *)context isEqualToString:@"updateCommitCount"] || [(NSString *)context isEqualToString:@"revisionListUpdating"]) {
[self updateStatus];
if ([repository.currentBranch isSimpleRef])
[self selectCommit:[repository shaForRef:[repository.currentBranch ref]]];
else
[self selectCommit:[[self firstCommit] realSha]];
[self selectCommit:[[self firstCommit] sha]];
return;
}
@@ -323,7 +272,7 @@
return;
PBGitTree* tree = [selectedFiles objectAtIndex:0];
NSString* name = [tree tmpFileNameForContents];
[[NSWorkspace sharedWorkspace] openFile:name];
[[NSWorkspace sharedWorkspace] openTempFile:name];
}
- (IBAction) setDetailedView:(id)sender
@@ -348,17 +297,34 @@
- (void)keyDown:(NSEvent*)event
{
if ([[event charactersIgnoringModifiers] isEqualToString: @"f"]
&& [event modifierFlags] & NSAlternateKeyMask
&& [event modifierFlags] & NSCommandKeyMask)
{
// command+alt+f
[[superController window] makeFirstResponder: searchField];
}
else
{
[super keyDown: event];
}
if ([[event charactersIgnoringModifiers] isEqualToString: @"f"] && [event modifierFlags] & NSAlternateKeyMask && [event modifierFlags] & NSCommandKeyMask)
[superController.window makeFirstResponder: searchField];
else
[super keyDown: event];
}
// NSSearchField (actually textfields in general) prevent the normal Find operations from working. Setup custom actions for the
// next and previous menuitems (in MainMenu.nib) so they will work when the search field is active. When searching for text in
// a file make sure to call the Find panel's action method instead.
- (IBAction)selectNext:(id)sender
{
NSResponder *firstResponder = [[[self view] window] firstResponder];
if ([firstResponder isKindOfClass:[PBQLTextView class]]) {
[(PBQLTextView *)firstResponder performFindPanelAction:sender];
return;
}
[searchController selectNextResult];
}
- (IBAction)selectPrevious:(id)sender
{
NSResponder *firstResponder = [[[self view] window] firstResponder];
if ([firstResponder isKindOfClass:[PBQLTextView class]]) {
[(PBQLTextView *)firstResponder performFindPanelAction:sender];
return;
}
[searchController selectPreviousResult];
}
- (void) copyCommitInfo
@@ -367,13 +333,26 @@
if (!commit)
return;
NSString *info = [NSString stringWithFormat:@"%@ (%@)", [[commit realSha] substringToIndex:10], [commit subject]];
NSPasteboard *a =[NSPasteboard generalPasteboard];
[a declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self];
[a setString:info forType: NSStringPboardType];
}
- (void) copyCommitSHA
{
PBGitCommit *commit = [[commitController selectedObjects] objectAtIndex:0];
if (!commit)
return;
NSString *info = [[commit realSha] substringWithRange:NSMakeRange(0, 7)];
NSPasteboard *a =[NSPasteboard generalPasteboard];
[a declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self];
[a setString:info forType: NSStringPboardType];
}
- (IBAction) toggleQLPreviewPanel:(id)sender
{
if ([[QLPreviewPanel sharedPreviewPanel] respondsToSelector:@selector(setDataSource:)]) {
@@ -398,7 +377,7 @@
{
if (!force && ![[QLPreviewPanel sharedPreviewPanel] isOpen])
return;
if ([[QLPreviewPanel sharedPreviewPanel] respondsToSelector:@selector(setDataSource:)]) {
// Public QL API
[previewPanel reloadData];
@@ -406,14 +385,14 @@
else {
// Private QL API (10.5 only)
NSArray *selectedFiles = [treeController selectedObjects];
NSMutableArray *fileNames = [NSMutableArray array];
for (PBGitTree *tree in selectedFiles) {
NSString *filePath = [tree tmpFileNameForContents];
if (filePath)
[fileNames addObject:[NSURL fileURLWithPath:filePath]];
}
if ([fileNames count])
[[QLPreviewPanel sharedPreviewPanel] setURLs:fileNames currentIndex:0 preservingDisplayState:YES];
}
@@ -461,15 +440,13 @@
commitList.useAdjustScroll = YES;
}
// NSLog(@"[%@ %s] newIndex = %d, oldIndex = %d", [self class], _cmd, newIndex, oldIndex);
[commitList scrollRowToVisible:newIndex];
commitList.useAdjustScroll = NO;
}
- (NSArray *) selectedObjectsForSHA:(NSString *)commitSHA
- (NSArray *) selectedObjectsForSHA:(PBGitSHA *)commitSHA
{
NSPredicate *selection = [NSPredicate predicateWithFormat:@"realSha == %@", commitSHA];
NSPredicate *selection = [NSPredicate predicateWithFormat:@"sha == %@", commitSHA];
NSArray *selectedCommits = [[commitController content] filteredArrayUsingPredicate:selection];
if (([selectedCommits count] == 0) && [self firstCommit])
@@ -478,32 +455,19 @@
return selectedCommits;
}
- (BOOL) selectCommit:(NSString *)commitSHA
- (void)selectCommit:(PBGitSHA *)commitSHA
{
ApplicationController * appController = [ApplicationController sharedApplicationController];
if (appController.launchedFromGitx && [appController.cliArgs isEqualToString:@"--commit"]) {
return NO;
}
NSLog(@"[%@ %s]: SHA = %@", [self class], _cmd, commitSHA);
if (!forceSelectionUpdate && [[selectedCommit realSha] isEqualToString:commitSHA])
return NO;
if (!forceSelectionUpdate && [[[[commitController selectedObjects] lastObject] sha] isEqual:commitSHA])
return;
NSInteger oldIndex = [[commitController selectionIndexes] firstIndex];
if (oldIndex == NSNotFound) {
oldIndex = [[commitController content] indexOfObject:selectedCommit];
}
NSArray *selectedCommits = [self selectedObjectsForSHA:commitSHA];
selectedCommit = [selectedCommits objectAtIndex:0];
[commitController setSelectedObjects:selectedCommits];
if (repository.currentBranchFilter != kGitXSelectedBranchFilter) {
NSLog(@"[%@ %s] currentBranchFilter = %@", [self class], _cmd, PBStringFromBranchFilterType(repository.currentBranchFilter));
[self scrollSelectionToTopOfViewFrom:oldIndex];
}
[self scrollSelectionToTopOfViewFrom:oldIndex];
return YES;
forceSelectionUpdate = NO;
}
- (BOOL) hasNonlinearPath
@@ -511,17 +475,26 @@
return [commitController filterPredicate] || [[commitController sortDescriptors] count] > 0;
}
- (void) removeView
- (void)closeView
{
float position = [[[historySplitView subviews] objectAtIndex:0] frame].size.height;
[[NSUserDefaults standardUserDefaults] setFloat:position forKey:@"PBGitSplitViewPosition"];
[[NSUserDefaults standardUserDefaults] synchronize];
[webView close];
[commitController removeObserver:self forKeyPath:@"selection"];
[treeController removeObserver:self forKeyPath:@"selection"];
[repository removeObserver:self forKeyPath:@"currentBranch"];
[super removeView];
if (commitController) {
[commitController removeObserver:self forKeyPath:@"selection"];
[commitController removeObserver:self forKeyPath:@"arrangedObjects.@count"];
[treeController removeObserver:self forKeyPath:@"selection"];
[repository.revisionList removeObserver:self forKeyPath:@"isUpdating"];
[repository removeObserver:self forKeyPath:@"currentBranch"];
[repository removeObserver:self forKeyPath:@"refs"];
[repository removeObserver:self forKeyPath:@"currentBranchFilter"];
}
[webHistoryController closeView];
[super closeView];
}
#pragma mark Table Column Methods
@@ -544,14 +517,8 @@
- (void)showCommitsFromTree:(id)sender
{
// TODO: Enable this from webview as well!
NSMutableArray *filePaths = [NSMutableArray arrayWithObjects:@"HEAD", @"--", NULL];
[filePaths addObjectsFromArray:[sender representedObject]];
PBGitRevSpecifier *revSpec = [[PBGitRevSpecifier alloc] initWithParameters:filePaths];
repository.currentBranch = [repository addBranch:revSpec];
NSString *searchString = [(NSArray *)[sender representedObject] componentsJoinedByString:@" "];
[searchController setHistorySearch:searchString mode:kGitXPathSearchMode];
}
- (void)showInFinderAction:(id)sender
@@ -559,12 +526,12 @@
NSString *workingDirectory = [[repository workingDirectory] stringByAppendingString:@"/"];
NSString *path;
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
for (NSString *filePath in [sender representedObject]) {
path = [workingDirectory stringByAppendingPathComponent:filePath];
[ws selectFile: path inFileViewerRootedAtPath:path];
}
}
- (void)openFilesAction:(id)sender
@@ -572,7 +539,7 @@
NSString *workingDirectory = [[repository workingDirectory] stringByAppendingString:@"/"];
NSString *path;
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
for (NSString *filePath in [sender representedObject]) {
path = [workingDirectory stringByAppendingPathComponent:filePath];
[ws openFile:path];
@@ -596,7 +563,7 @@
- (NSMenu *)contextMenuForTreeView
{
NSArray *filePaths = [[treeController selectedObjects] valueForKey:@"fullPath"];
NSMenu *menu = [[NSMenu alloc] init];
for (NSMenuItem *item in [self menuItemsForPaths:filePaths])
[menu addItem:item];
@@ -617,7 +584,7 @@
PBGitRef *headRef = [[repository headRef] ref];
NSString *headRefName = [headRef shortName];
NSString *diffTitle = [NSString stringWithFormat:@"Diff %@ with %@", multiple ? @"files" : @"file", headRefName];
BOOL isHead = [[selectedCommit realSha] isEqualToString:[repository headSHA]];
BOOL isHead = [[selectedCommit sha] isEqual:[repository headSHA]];
NSMenuItem *diffItem = [[NSMenuItem alloc] initWithTitle:diffTitle
action:isHead ? nil : @selector(diffFilesAction:)
keyEquivalent:@""];
@@ -637,7 +604,7 @@
[item setTarget:self];
[item setRepresentedObject:filePaths];
}
return menuItems;
}
@@ -705,71 +672,8 @@
- (IBAction) rebase:(id)sender
{
if (selectedCommit) {
PBGitRef *headRef = [[repository headRef] ref];
[repository rebaseBranch:headRef onRefish:selectedCommit];
}
}
#pragma mark Remote controls
// !!! Andre Berg 20100330: moved these over from the PBGitSidebarController
// since I grew tired of having to go all the way down with the mouse just
// to do some basic actions I need to frequently (YMMV) =)
enum {
kAddRemoteSegment = 0,
kFetchSegment,
kPullSegment,
kPushSegment
};
- (void) updateRemoteControls:(PBGitRef *)forRef
{
BOOL hasRemote = NO;
PBGitRef *ref = forRef;
if ([ref isRemote] || ([ref isBranch] && [[repository remoteRefForBranch:ref error:NULL] remoteName]))
hasRemote = YES;
[remoteControls setEnabled:hasRemote forSegment:kFetchSegment];
[remoteControls setEnabled:hasRemote forSegment:kPullSegment];
[remoteControls setEnabled:hasRemote forSegment:kPushSegment];
}
- (IBAction) fetchPullPushAction:(id)sender
{
NSInteger selectedSegment = [sender selectedSegment];
if (selectedSegment == kAddRemoteSegment) {
[PBAddRemoteSheet beginAddRemoteSheetForRepository:repository];
return;
}
NSOutlineView * sourceView = sidebarSourceView;
NSInteger index = [sourceView selectedRow];
PBSourceViewItem *item = [sourceView itemAtRow:index];
PBGitRef *ref = [[item revSpecifier] ref];
if (!ref && (item.parent == sidebarRemotes))
ref = [PBGitRef refFromString:[kGitXRemoteRefPrefix stringByAppendingString:[item title]]];
if (![ref isRemote] && ![ref isBranch])
return;
PBGitRef *remoteRef = [repository remoteRefForBranch:ref error:NULL];
if (!remoteRef)
return;
if (selectedSegment == kFetchSegment)
[repository beginFetchFromRemoteForRef:ref];
else if (selectedSegment == kPullSegment)
[repository beginPullFromRemote:remoteRef forRef:ref];
else if (selectedSegment == kPushSegment) {
if ([ref isRemote])
[refController showConfirmPushRefSheet:nil remote:remoteRef];
else if ([ref isBranch])
[refController showConfirmPushRefSheet:ref remote:remoteRef];
}
if (selectedCommit)
[repository rebaseBranch:nil onRefish:selectedCommit];
}
#pragma mark -
@@ -852,46 +756,4 @@ enum {
return iconRect;
}
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)sel
{
NSLog(@"[%@ %s]: self = %@ (%i)", [self class], _cmd, self,[self respondsToSelector:sel]);
//return NO; //![controller respondsToSelector:sel];
if (sel == @selector(selectCommit:)) return NO;
return YES;
}
#pragma mark <MGScopeBarDelegate>
- (int)numberOfGroupsInScopeBar:(MGScopeBar *)theScopeBar
{
return 1;
}
- (NSArray *)scopeBar:(MGScopeBar *)theScopeBar itemIdentifiersForGroup:(int)groupNumber
{
return [NSArray arrayWithObjects:@"Only Commit",@"All Files",nil];
}
- (NSString *)scopeBar:(MGScopeBar *)theScopeBar labelForGroup:(int)groupNumber
{
return nil;
}
- (MGScopeBarGroupSelectionMode)scopeBar:(MGScopeBar *)theScopeBar selectionModeForGroup:(int)groupNumber
{
return MGRadioSelectionMode;
}
- (NSString *)scopeBar:(MGScopeBar *)theScopeBar titleOfItem:(NSString *)identifier inGroup:(int)groupNumber
{
return identifier;
}
- (void)scopeBar:(MGScopeBar *)theScopeBar selectedStateChanged:(BOOL)selected forItem:(NSString *)identifier inGroup:(int)groupNumber
{
[self updateKeys];
}
@end
+6 -1
View File
@@ -9,18 +9,23 @@
#import <Cocoa/Cocoa.h>
#define kCurrentQueueKey @"kCurrentQueueKey"
#define kNewCommitsKey @"kNewCommitsKey"
@class PBGitGrapher;
@interface PBGitHistoryGrapher : NSObject {
id delegate;
NSOperationQueue *currentQueue;
NSMutableSet *searchSHAs;
PBGitGrapher *grapher;
BOOL viewAllBranches;
}
- (id) initWithBaseCommits:(NSSet *)commits viewAllBranches:(BOOL)viewAll delegate:(id)theDelegate;
- (id) initWithBaseCommits:(NSSet *)commits viewAllBranches:(BOOL)viewAll queue:(NSOperationQueue *)queue delegate:(id)theDelegate;
- (void) graphCommits:(NSArray *)revList;
@end
+26 -7
View File
@@ -8,14 +8,16 @@
#import "PBGitHistoryGrapher.h"
#import "PBGitGrapher.h"
#import "PBGitSHA.h"
@implementation PBGitHistoryGrapher
- (id) initWithBaseCommits:(NSSet *)commits viewAllBranches:(BOOL)viewAll delegate:(id)theDelegate
- (id) initWithBaseCommits:(NSSet *)commits viewAllBranches:(BOOL)viewAll queue:(NSOperationQueue *)queue delegate:(id)theDelegate
{
delegate = theDelegate;
currentQueue = queue;
searchSHAs = [NSMutableSet setWithSet:commits];
grapher = [[PBGitGrapher alloc] initWithRepository:nil];
viewAllBranches = viewAll;
@@ -24,31 +26,48 @@
}
- (void)sendCommits:(NSArray *)commits
{
NSDictionary *commitData = [NSDictionary dictionaryWithObjectsAndKeys:currentQueue, kCurrentQueueKey, commits, kNewCommitsKey, nil];
[delegate performSelectorOnMainThread:@selector(updateCommitsFromGrapher:) withObject:commitData waitUntilDone:NO];
}
- (void) graphCommits:(NSArray *)revList
{
if (!revList || [revList count] == 0)
return;
//NSDate *start = [NSDate date];
NSThread *currentThread = [NSThread currentThread];
NSDate *lastUpdate = [NSDate date];
NSMutableArray *commits = [NSMutableArray array];
NSInteger counter = 0;
for (PBGitCommit *commit in revList) {
NSString *commitSHA = [commit realSha];
if ([currentThread isCancelled])
return;
PBGitSHA *commitSHA = [commit sha];
if (viewAllBranches || [searchSHAs containsObject:commitSHA]) {
[grapher decorateCommit:commit];
[commits addObject:commit];
if (!viewAllBranches) {
[searchSHAs removeObject:commitSHA];
[searchSHAs addObjectsFromArray:commit.parents];
[searchSHAs addObjectsFromArray:[commit parents]];
}
}
if (++counter % 2000 == 0) {
[delegate performSelectorOnMainThread:@selector(addCommitsFromArray:) withObject:[commits copy] waitUntilDone:NO];
commits = [NSMutableArray array];
if (++counter % 100 == 0) {
if ([[NSDate date] timeIntervalSinceDate:lastUpdate] > 0.1) {
[self sendCommits:commits];
commits = [NSMutableArray array];
lastUpdate = [NSDate date];
}
}
}
//NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:start];
//NSLog(@"Graphed %i commits in %f seconds (%f/sec)", counter, duration, counter/duration);
[delegate performSelectorOnMainThread:@selector(addCommitsFromArray:) withObject:commits waitUntilDone:YES];
[self sendCommits:commits];
[delegate performSelectorOnMainThread:@selector(finishedGraphing) withObject:nil waitUntilDone:NO];
}
+4 -5
View File
@@ -14,6 +14,7 @@
@class PBGitRef;
@class PBGitRevList;
@class PBGitHistoryGrapher;
@class PBGitSHA;
@interface PBGitHistoryList : NSObject {
PBGitRepository *repository;
@@ -21,17 +22,15 @@
PBGitRevList *projectRevList;
PBGitRevList *currentRevList;
NSString *lastSHA;
PBGitSHA *lastSHA;
NSSet *lastRefSHAs;
NSInteger lastBranchFilter;
PBGitRef *lastRemoteRef;
BOOL resetCommits;
BOOL shouldReloadProjectHistory;
NSDate *updatedGraph;
PBGitHistoryGrapher *grapher;
NSOperationQueue *graphQueue;
NSInvocationOperation *lastOperation;
NSMutableArray *commits;
BOOL isUpdating;
@@ -40,14 +39,14 @@
- (id) initWithRepository:(PBGitRepository *)repo;
- (void) forceUpdate;
- (void) updateHistory;
- (void)cleanup;
- (void) addCommitsFromArray:(NSArray *)array;
- (void) updateCommitsFromGrapher:(NSDictionary *)commitData;
@property (retain) PBGitRevList *projectRevList;
@property (retain) NSMutableArray *commits;
@property (readonly) NSArray *projectCommits;
@property (assign) BOOL isUpdating;
@property (retain) NSDate *updatedGraph;
@end
+39 -44
View File
@@ -11,6 +11,7 @@
#import "PBGitRevList.h"
#import "PBGitGrapher.h"
#import "PBGitHistoryGrapher.h"
#import "PBGitSHA.h"
@@ -35,7 +36,6 @@
@synthesize projectRevList;
@synthesize commits;
@synthesize isUpdating;
@synthesize updatedGraph;
@dynamic projectCommits;
@@ -81,6 +81,20 @@
}
- (void)cleanup
{
if (currentRevList) {
[currentRevList removeObserver:self forKeyPath:@"commits"];
[currentRevList cancel];
}
[graphQueue cancelAllOperations];
[repository removeObserver:self forKeyPath:@"currentBranch"];
[repository removeObserver:self forKeyPath:@"currentBranchFilter"];
[repository removeObserver:self forKeyPath:@"hasChanged"];
}
- (NSArray *) projectCommits
{
return [projectRevList.commits copy];
@@ -95,6 +109,7 @@
{
if (!array || [array count] == 0)
return;
if (resetCommits) {
self.commits = [NSMutableArray array];
resetCommits = NO;
@@ -109,11 +124,18 @@
}
- (void) updateCommitsFromGrapher:(NSDictionary *)commitData
{
if ([commitData objectForKey:kCurrentQueueKey] != graphQueue)
return;
[self addCommitsFromArray:[commitData objectForKey:kNewCommitsKey]];
}
- (void) finishedGraphing
{
if (!currentRevList.isParsing && ([[graphQueue operations] count] == 0)) {
self.isUpdating = NO;
[self performSelector:@selector(setUpdatedGraph:) withObject:[NSDate date] afterDelay:0];
}
}
@@ -127,12 +149,9 @@
resetCommits = YES;
self.isUpdating = YES;
[graphQueue setSuspended:YES];
if (graphQueue)
[graphQueue removeObserver:self forKeyPath:@"operations"];
[graphQueue cancelAllOperations];
graphQueue = [[NSOperationQueue alloc] init];
[graphQueue addObserver:self forKeyPath:@"operations" options:0 context:@"operations"];
lastOperation = nil;
[graphQueue setMaxConcurrentOperationCount:1];
grapher = [self grapher];
}
@@ -140,12 +159,7 @@
- (NSInvocationOperation *) operationForCommits:(NSArray *)newCommits
{
NSInvocationOperation *graphOperation = [[NSInvocationOperation alloc] initWithTarget:grapher selector:@selector(graphCommits:) object:newCommits];
if (lastOperation)
[graphOperation addDependency:lastOperation];
lastOperation = graphOperation;
return graphOperation;
return [[NSInvocationOperation alloc] initWithTarget:grapher selector:@selector(graphCommits:) object:newCommits];
}
@@ -154,11 +168,14 @@
NSMutableSet *baseCommitSHAs = [NSMutableSet set];
NSDictionary *refs = repository.refs;
for (NSString *sha in refs)
for (PBGitSHA *sha in refs)
for (PBGitRef *ref in [refs objectForKey:sha])
if ([ref isBranch] || [ref isTag])
[baseCommitSHAs addObject:sha];
if (![[PBGitRef refFromString:[[repository headRef] simpleRef]] type])
[baseCommitSHAs addObject:[repository headSHA]];
return baseCommitSHAs;
}
@@ -170,7 +187,7 @@
PBGitRef *remoteRef = [[repository.currentBranch ref] remoteRef];
for (NSString *sha in refs)
for (PBGitSHA *sha in refs)
for (PBGitRef *ref in [refs objectForKey:sha])
if ([remoteRef isEqualToRef:[ref remoteRef]])
[baseCommitSHAs addObject:sha];
@@ -186,7 +203,7 @@
return [NSMutableSet setWithObject:lastSHA];
else if ([repository.currentBranch isSimpleRef]) {
PBGitRef *currentRef = [repository.currentBranch ref];
NSString *sha = [repository shaForRef:currentRef];
PBGitSHA *sha = [repository shaForRef:currentRef];
if (sha)
return [NSMutableSet setWithObject:sha];
}
@@ -206,7 +223,7 @@
{
BOOL viewAllBranches = (repository.currentBranchFilter == kGitXAllBranchesFilter);
return [[PBGitHistoryGrapher alloc] initWithBaseCommits:[self baseCommits] viewAllBranches:viewAllBranches delegate:self];
return [[PBGitHistoryGrapher alloc] initWithBaseCommits:[self baseCommits] viewAllBranches:viewAllBranches queue:graphQueue delegate:self];
}
@@ -215,15 +232,12 @@
if (currentRevList == parser)
return;
if (currentRevList) {
if (currentRevList)
[currentRevList removeObserver:self forKeyPath:@"commits"];
[currentRevList removeObserver:self forKeyPath:@"isParsing"];
}
currentRevList = parser;
[currentRevList addObserver:self forKeyPath:@"commits" options:NSKeyValueObservingOptionNew context:@"commitsUpdated"];
[currentRevList addObserver:self forKeyPath:@"isParsing" options:0 context:@"revListParsing"];
}
@@ -256,12 +270,11 @@
lastRemoteRef = [[rev ref] remoteRef];
lastSHA = nil;
self.isUpdating = NO;
self.updatedGraph = [NSDate date];
return NO;
}
NSString *revSHA = [repository shaForRef:[rev ref]];
if ([revSHA isEqualToString:lastSHA] && (lastBranchFilter == repository.currentBranchFilter))
PBGitSHA *revSHA = [repository shaForRef:[rev ref]];
if ([revSHA isEqual:lastSHA] && (lastBranchFilter == repository.currentBranchFilter))
return NO;
lastBranchFilter = repository.currentBranchFilter;
@@ -303,6 +316,7 @@
lastBranchFilter = -1;
lastRemoteRef = nil;
lastSHA = nil;
self.commits = [NSMutableArray array];
[projectRevList loadRevisons];
return;
}
@@ -320,6 +334,7 @@
lastBranchFilter = -1;
lastRemoteRef = nil;
lastSHA = nil;
self.commits = [NSMutableArray array];
[otherRevListParser loadRevisons];
}
@@ -329,21 +344,6 @@
#pragma mark -
#pragma mark Key Value Observing
- (void) removeObservers
{
[repository removeObserver:self forKeyPath:@"currentBranch"];
[repository removeObserver:self forKeyPath:@"hasChanged"];
if (currentRevList) {
[currentRevList removeObserver:self forKeyPath:@"commits"];
[currentRevList removeObserver:self forKeyPath:@"isParsing"];
}
if (graphQueue)
[graphQueue removeObserver:self forKeyPath:@"operations"];
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([@"currentBranch" isEqualToString:context]) {
@@ -368,11 +368,6 @@
return;
}
if ([@"revListParsing" isEqualToString:context] || [@"operations" isEqualToString:context]) {
[self finishedGraphing];
return;
}
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
+1606 -614
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -26,6 +26,7 @@ extern NSString *PBGitIndexIndexUpdated;
// Committing files
extern NSString *PBGitIndexCommitStatus;
extern NSString *PBGitIndexCommitFailed;
extern NSString *PBGitIndexCommitHookFailed;
extern NSString *PBGitIndexFinishedCommit;
// Changing to amend
@@ -66,7 +67,7 @@ extern NSString *PBGitIndexOperationFailed;
// Refresh the index
- (void)refresh;
- (void)commitWithMessage:(NSString *)commitMessage;
- (void)commitWithMessage:(NSString *)commitMessage andVerify:(BOOL) doVerify;
// Inter-file changes:
- (BOOL)stageFiles:(NSArray *)stageFiles;
@@ -75,7 +76,6 @@ extern NSString *PBGitIndexOperationFailed;
// Intra-file changes
- (BOOL)applyPatch:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse;
- (NSString *)blameFile:(PBChangedFile *)file;
- (NSString *)diffForFile:(PBChangedFile *)file staged:(BOOL)staged contextLines:(NSUInteger)context;
@end
+133 -58
View File
@@ -21,6 +21,7 @@ NSString *PBGitIndexIndexUpdated = @"GBGitIndexIndexUpdated";
NSString *PBGitIndexCommitStatus = @"PBGitIndexCommitStatus";
NSString *PBGitIndexCommitFailed = @"PBGitIndexCommitFailed";
NSString *PBGitIndexCommitHookFailed = @"PBGitIndexCommitHookFailed";
NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit";
NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable";
@@ -48,6 +49,7 @@ NSString *PBGitIndexOperationFailed = @"PBGitIndexOperationFailed";
- (NSString *) parentTree;
- (void)postCommitUpdate:(NSString *)update;
- (void)postCommitFailure:(NSString *)reason;
- (void)postCommitHookFailure:(NSString *)reason;
- (void)postIndexChange;
- (void)postOperationFailed:(NSString *)description;
@end
@@ -145,7 +147,7 @@ NSString *PBGitIndexOperationFailed = @"PBGitIndexOperationFailed";
}
// TODO: make Asynchronous
- (void)commitWithMessage:(NSString *)commitMessage
- (void)commitWithMessage:(NSString *)commitMessage andVerify:(BOOL) doVerify
{
NSMutableString *commitSubject = [@"commit: " mutableCopy];
NSRange newLine = [commitMessage rangeOfString:@"\n"];
@@ -155,7 +157,7 @@ NSString *PBGitIndexOperationFailed = @"PBGitIndexOperationFailed";
[commitSubject appendString:[commitMessage substringToIndex:newLine.location]];
NSString *commitMessageFile;
commitMessageFile = [[[repository fileURL] path] stringByAppendingPathComponent:@"COMMIT_EDITMSG"];
commitMessageFile = [repository.fileURL.path stringByAppendingPathComponent:@"COMMIT_EDITMSG"];
[commitMessage writeToFile:commitMessageFile atomically:YES encoding:NSUTF8StringEncoding error:nil];
@@ -175,6 +177,30 @@ NSString *PBGitIndexOperationFailed = @"PBGitIndexOperationFailed";
[self postCommitUpdate:@"Creating commit"];
int ret = 1;
if (doVerify) {
[self postCommitUpdate:@"Running hooks"];
NSString *hookFailureMessage = nil;
NSString *hookOutput = nil;
if (![repository executeHook:@"pre-commit" output:&hookOutput]) {
hookFailureMessage = [NSString stringWithFormat:@"Pre-commit hook failed%@%@",
[hookOutput length] > 0 ? @":\n" : @"",
hookOutput];
}
if (![repository executeHook:@"commit-msg" withArgs:[NSArray arrayWithObject:commitMessageFile] output:nil]) {
hookFailureMessage = [NSString stringWithFormat:@"Commit-msg hook failed%@%@",
[hookOutput length] > 0 ? @":\n" : @"",
hookOutput];
}
if (hookFailureMessage != nil) {
return [self postCommitHookFailure:hookFailureMessage];
}
}
commitMessage = [NSString stringWithContentsOfFile:commitMessageFile encoding:NSUTF8StringEncoding error:nil];
NSString *commit = [repository outputForArguments:arguments
inputString:commitMessage
byExtendingEnvironment:amendEnvironment
@@ -183,13 +209,6 @@ NSString *PBGitIndexOperationFailed = @"PBGitIndexOperationFailed";
if (ret || [commit length] != 40)
return [self postCommitFailure:@"Could not create a commit object"];
[self postCommitUpdate:@"Running hooks"];
if (![repository executeHook:@"pre-commit" output:nil])
return [self postCommitFailure:@"Pre-commit hook failed"];
if (![repository executeHook:@"commit-msg" withArgs:[NSArray arrayWithObject:commitMessageFile] output:nil])
return [self postCommitFailure:@"Commit-msg hook failed"];
[self postCommitUpdate:@"Updating HEAD"];
[repository outputForArguments:[NSArray arrayWithObjects:@"update-ref", @"-m", commitSubject, @"HEAD", commit, nil]
retValue: &ret];
@@ -239,6 +258,13 @@ NSString *PBGitIndexOperationFailed = @"PBGitIndexOperationFailed";
userInfo:[NSDictionary dictionaryWithObject:reason forKey:@"description"]];
}
- (void)postCommitHookFailure:(NSString *)reason
{
[[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexCommitHookFailed
object:self
userInfo:[NSDictionary dictionaryWithObject:reason forKey:@"description"]];
}
- (void)postOperationFailed:(NSString *)description
{
[[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexOperationFailed
@@ -248,30 +274,57 @@ NSString *PBGitIndexOperationFailed = @"PBGitIndexOperationFailed";
- (BOOL)stageFiles:(NSArray *)stageFiles
{
// Input string for update-index
// This will be a list of filenames that
// should be updated. It's similar to
// "git add -- <files>
NSMutableString *input = [NSMutableString string];
for (PBChangedFile *file in stageFiles) {
[input appendFormat:@"%@\0", file.path];
}
// Do staging files by chunks of 1000 files each, to prevent program freeze (because NSPipe has limited capacity)
int ret = 1;
[repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"--add", @"--remove", @"-z", @"--stdin", nil]
inputString:input
retValue:&ret];
int filesCount = [stageFiles count];
// Prepare first iteration
int loopFrom = 0;
int loopTo = 1000;
if (loopTo > filesCount)
loopTo = filesCount;
int loopCount = 0;
int i = 0;
// Staging
while (loopCount < filesCount) {
// Input string for update-index
// This will be a list of filenames that
// should be updated. It's similar to
// "git add -- <files>
NSMutableString *input = [NSMutableString string];
if (ret) {
[self postOperationFailed:[NSString stringWithFormat:@"Error in staging files. Return value: %i", ret]];
return NO;
}
for (i = loopFrom; i < loopTo; i++) {
loopCount++;
PBChangedFile *file = [stageFiles objectAtIndex:i];
[input appendFormat:@"%@\0", file.path];
}
int ret = 1;
[repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"--add", @"--remove", @"-z", @"--stdin", nil]
inputString:input
retValue:&ret];
for (PBChangedFile *file in stageFiles)
{
file.hasUnstagedChanges = NO;
file.hasStagedChanges = YES;
if (ret) {
[self postOperationFailed:[NSString stringWithFormat:@"Error in staging files. Return value: %i", ret]];
return NO;
}
for (i = loopFrom; i < loopTo; i++) {
PBChangedFile *file = [stageFiles objectAtIndex:i];
file.hasUnstagedChanges = NO;
file.hasStagedChanges = YES;
}
// Prepare next iteration
loopFrom = loopCount;
loopTo = loopFrom + 1000;
if (loopTo > filesCount)
loopTo = filesCount;
}
[self postIndexChange];
@@ -281,27 +334,53 @@ NSString *PBGitIndexOperationFailed = @"PBGitIndexOperationFailed";
// TODO: Refactor with above. What's a better name for this?
- (BOOL)unstageFiles:(NSArray *)unstageFiles
{
NSMutableString *input = [NSMutableString string];
for (PBChangedFile *file in unstageFiles) {
[input appendString:[file indexInfo]];
}
int ret = 1;
[repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"-z", @"--index-info", nil]
inputString:input
retValue:&ret];
if (ret)
{
[self postOperationFailed:[NSString stringWithFormat:@"Error in unstaging files. Return value: %i", ret]];
return NO;
}
for (PBChangedFile *file in unstageFiles)
{
file.hasUnstagedChanges = YES;
file.hasStagedChanges = NO;
// Do unstaging files by chunks of 1000 files each, to prevent program freeze (because NSPipe has limited capacity)
int filesCount = [unstageFiles count];
// Prepare first iteration
int loopFrom = 0;
int loopTo = 1000;
if (loopTo > filesCount)
loopTo = filesCount;
int loopCount = 0;
int i = 0;
// Unstaging
while (loopCount < filesCount) {
NSMutableString *input = [NSMutableString string];
for (i = loopFrom; i < loopTo; i++) {
loopCount++;
PBChangedFile *file = [unstageFiles objectAtIndex:i];
[input appendString:[file indexInfo]];
}
int ret = 1;
[repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"-z", @"--index-info", nil]
inputString:input
retValue:&ret];
if (ret)
{
[self postOperationFailed:[NSString stringWithFormat:@"Error in unstaging files. Return value: %i", ret]];
return NO;
}
for (i = loopFrom; i < loopTo; i++) {
PBChangedFile *file = [unstageFiles objectAtIndex:i];
file.hasUnstagedChanges = YES;
file.hasStagedChanges = NO;
}
// Prepare next iteration
loopFrom = loopCount;
loopTo = loopFrom + 1000;
if (loopTo > filesCount)
loopTo = filesCount;
}
[self postIndexChange];
@@ -324,14 +403,15 @@ NSString *PBGitIndexOperationFailed = @"PBGitIndexOperationFailed";
}
for (PBChangedFile *file in discardFiles)
file.hasUnstagedChanges = NO;
if (file.status != NEW)
file.hasUnstagedChanges = NO;
[self postIndexChange];
}
- (BOOL)applyPatch:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse;
{
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"apply", nil];
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"apply", @"--unidiff-zero", nil];
if (stage)
[array addObject:@"--cached"];
if (reverse)
@@ -353,11 +433,6 @@ NSString *PBGitIndexOperationFailed = @"PBGitIndexOperationFailed";
}
- (NSString *)blameFile:(PBChangedFile *)file
{
return [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"blame", file.path, nil]];
}
- (NSString *)diffForFile:(PBChangedFile *)file staged:(BOOL)staged contextLines:(NSUInteger)context
{
NSString *parameter = [NSString stringWithFormat:@"-U%u", context];
-2
View File
@@ -9,7 +9,6 @@
#import <Cocoa/Cocoa.h>
#import "PBGitCommitController.h"
#import "PBChangedFile.h"
#import "PBGitGradientBarView.h"
@interface PBGitIndexController : NSObject {
IBOutlet NSArrayController *stagedFilesController, *unstagedFilesController;
@@ -17,7 +16,6 @@
IBOutlet NSTableView *unstagedTable;
IBOutlet NSTableView *stagedTable;
IBOutlet PBGitGradientBarView *upperToolbarView;
}
- (IBAction) rowClicked:(NSCell *) sender;
-3
View File
@@ -29,9 +29,6 @@
[unstagedTable registerForDraggedTypes: [NSArray arrayWithObject:FileChangesTableViewType]];
[stagedTable registerForDraggedTypes: [NSArray arrayWithObject:FileChangesTableViewType]];
[upperToolbarView setTopShade:237/255.0 bottomShade:216/255.0];
}
// FIXME: Find a proper place for this method -- this is not it.
+2 -2
View File
@@ -33,9 +33,9 @@ public:
d_index = s_colorIndex++;
}
bool isCommit(git_oid *sha) const
bool isCommit(git_oid sha) const
{
return !git_oid_cmp(&d_sha, sha);
return !git_oid_cmp(&d_sha, &sha);
}
void setSha(git_oid sha);
-3
View File
@@ -42,9 +42,6 @@ extern NSString * const kGitXRemoteRefPrefix;
- (PBGitRef *) remoteRef;
- (NSString *)description;
- (NSString *)debugDescription;
- (BOOL) isEqualToRef:(PBGitRef *)otherRef;
+ (PBGitRef*) refFromString: (NSString*) s;
-9
View File
@@ -66,15 +66,6 @@ NSString * const kGitXRemoteRefPrefix = @"refs/remotes/";
return nil;
}
- (NSString *) description {
return [NSString stringWithFormat:@"<PBGitRef: %p> ref = %@", self, self.ref];
}
- (NSString *)debugDescription {
return [NSString stringWithFormat:@"<PBGitRef: %p>, ref = %@, type = %@", self, ref, [self type]];
}
- (BOOL) isBranch
{
return [ref hasPrefix:kGitXBranchRefPrefix];
+19 -20
View File
@@ -10,9 +10,9 @@
#import "PBGitHistoryList.h"
#import "PBGitRevSpecifier.h"
#import "PBGitConfig.h"
#import "PBGitXErrors.h"
#import "PBGitRefish.h"
extern NSString* PBGitRepositoryErrorDomain;
typedef enum branchFilterTypes {
kGitXAllBranchesFilter = 0,
kGitXLocalRemoteBranchesFilter,
@@ -38,6 +38,7 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) {
@class PBGitWindowController;
@class PBGitCommit;
@class PBGitSHA;
@interface PBGitRepository : NSDocument {
PBGitHistoryList* revisionList;
@@ -50,6 +51,7 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) {
NSMutableDictionary *refs;
PBGitRevSpecifier *_headRef; // Caching
PBGitSHA* _headSha;
}
- (void) cloneRepositoryToPath:(NSString *)path bare:(BOOL)isBare;
@@ -80,8 +82,6 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) {
- (NSString*) outputForArguments:(NSArray*) args retValue:(int *)ret;
- (NSString *)outputInWorkdirForArguments:(NSArray*) arguments;
- (NSString *)outputInWorkdirForArguments:(NSArray*) arguments retValue:(int *)ret;
- (NSString *) outputForShellScriptTemplate:(NSString *)scriptTemplate keywordDict:(NSDictionary *)keywordDict retValue:(NSInteger *)retValue;
- (NSString *) outputForShellScript:(NSString *)script retValue:(NSInteger *)retValue;
- (BOOL)executeHook:(NSString *)name output:(NSString **)output;
- (BOOL)executeHook:(NSString *)name withArgs:(NSArray*) arguments output:(NSString **)output;
@@ -93,21 +93,18 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) {
- (void) reloadRefs;
- (void) addRef:(PBGitRef *)ref fromParameters:(NSArray *)params;
- (void) lazyReload;
- (PBGitRevSpecifier*) headRef;
- (NSString *) headSHA;
- (PBGitCommit *) headCommit;
- (NSString *) shaForRef:(PBGitRef *)ref;
- (PBGitCommit *) commitForRef:(PBGitRef *)ref;
- (PBGitCommit *) commitForSHA:(NSString *)sha;
- (BOOL) isOnSameBranch:(NSString *)baseSHA asSHA:(NSString *)testSHA;
- (BOOL) isSHAOnHeadBranch:(NSString *)testSHA;
- (BOOL) isRefOnHeadBranch:(PBGitRef *)testRef;
- (BOOL) checkRefFormat:(NSString *)refName;
- (BOOL) checkRefFormatForBranch:(NSString *)shaOrRefName;
- (PBGitRef *) completeRefForString:(NSString *)partialRefString;
- (BOOL) refExists:(PBGitRef *)ref;
// checks to see if the ref or sha exists - returns nil if not found and the complete sha if found
- (NSString *) shaExists:(NSString *)sha;
- (PBGitRevSpecifier*)headRef;
- (PBGitSHA *)headSHA;
- (PBGitCommit *)headCommit;
- (PBGitSHA *)shaForRef:(PBGitRef *)ref;
- (PBGitCommit *)commitForRef:(PBGitRef *)ref;
- (PBGitCommit *)commitForSHA:(PBGitSHA *)sha;
- (BOOL)isOnSameBranch:(PBGitSHA *)baseSHA asSHA:(PBGitSHA *)testSHA;
- (BOOL)isSHAOnHeadBranch:(PBGitSHA *)testSHA;
- (BOOL)isRefOnHeadBranch:(PBGitRef *)testRef;
- (BOOL)checkRefFormat:(NSString *)refName;
- (BOOL)refExists:(PBGitRef *)ref;
- (PBGitRef *)refForName:(NSString *)name;
- (NSArray *) remotes;
- (BOOL) hasRemotes;
@@ -123,12 +120,15 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) {
+ (NSURL*)gitDirForURL:(NSURL*)repositoryURL;
+ (NSURL*)baseDirForURL:(NSURL*)repositoryURL;
+ (NSString *) basePath;
- (id) initWithURL: (NSURL*) path;
- (void) setup;
- (void) forceUpdateRevisions;
// for the scripting bridge
- (void)findInModeScriptCommand:(NSScriptCommand *)command;
@property (assign) BOOL hasChanged;
@property (readonly) PBGitWindowController *windowController;
@property (readonly) PBGitConfig *config;
@@ -137,5 +137,4 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) {
@property (assign) PBGitRevSpecifier *currentBranch;
@property (assign) NSInteger currentBranchFilter;
@property (retain) NSMutableDictionary* refs;
@end
+226 -157
View File
@@ -10,6 +10,7 @@
#import "PBGitCommit.h"
#import "PBGitWindowController.h"
#import "PBGitBinary.h"
#import "NSFileHandleExt.h"
#import "PBEasyPipe.h"
#import "PBGitRef.h"
@@ -17,25 +18,21 @@
#import "PBRemoteProgressSheet.h"
#import "PBGitRevList.h"
#import "PBGitDefaults.h"
#import "BMScript.h"
#import "GitXScriptingConstants.h"
#import "PBHistorySearchController.h"
static NSString * repositoryBasePath = nil;
NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain";
@implementation PBGitRepository
@synthesize revisionList;
@synthesize branches;
@synthesize currentBranch;
@synthesize refs;
@synthesize hasChanged;
@synthesize config;
@synthesize revisionList, branches, currentBranch, refs, hasChanged, config;
@synthesize currentBranchFilter;
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
if (outError) {
*outError = [NSError errorWithDomain:PBGitXErrorDomain
code:PBFileReadingUnsupportedErrorCode
*outError = [NSError errorWithDomain:PBGitRepositoryErrorDomain
code:0
userInfo:[NSDictionary dictionaryWithObject:@"Reading files is not supported." forKey:NSLocalizedFailureReasonErrorKey]];
}
return NO;
@@ -46,36 +43,28 @@ static NSString * repositoryBasePath = nil;
return [[PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:[NSArray arrayWithObjects:@"rev-parse", @"--is-bare-repository", nil] inDir:path] isEqualToString:@"true"];
}
// can be used to return the basePath of a repo when [self fileURL] is unavailable yet
+ (NSString *) basePath {
if (repositoryBasePath) {
return repositoryBasePath;
}
return nil;
}
+ (NSURL*)gitDirForURL:(NSURL*)repositoryURL;
+ (NSURL *)gitDirForURL:(NSURL *)repositoryURL;
{
if (![PBGitBinary path])
return nil;
NSString* repositoryPath = [repositoryURL path];
// save base path
repositoryBasePath = [repositoryPath stringByDeletingLastPathComponent];
if ([self isBareRepository:repositoryPath])
return repositoryURL;
// Use rev-parse to find the .git dir for the repository being opened
NSString* newPath = [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:[NSArray arrayWithObjects:@"rev-parse", @"--git-dir", nil] inDir:repositoryPath];
if ([newPath rangeOfString:@"fatal:"].length != 0)
return nil;
if ([newPath isEqualToString:@".git"])
int retValue = 1;
NSString *newPath = [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:[NSArray arrayWithObjects:@"rev-parse", @"--git-dir", nil] inDir:repositoryPath retValue:&retValue];
if (retValue) {
// The current directory does not contain a git repository
return nil;
}
if ([newPath isEqualToString:@".git"])
return [NSURL fileURLWithPath:[repositoryPath stringByAppendingPathComponent:@".git"]];
if ([newPath isEqualToString:@"."])
return [NSURL fileURLWithPath:repositoryPath];
if ([newPath length] > 0)
return [NSURL fileURLWithPath:newPath];
@@ -107,7 +96,7 @@ static NSString * repositoryBasePath = nil;
if (outError) {
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:[PBGitBinary notFoundError]
forKey:NSLocalizedRecoverySuggestionErrorKey];
*outError = [NSError errorWithDomain:PBGitXErrorDomain code:PBGitBinaryNotFoundErrorCode userInfo:userInfo];
*outError = [NSError errorWithDomain:PBGitRepositoryErrorDomain code:0 userInfo:userInfo];
}
return NO;
}
@@ -118,7 +107,7 @@ static NSString * repositoryBasePath = nil;
if (outError) {
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:@"Reading files is not supported."
forKey:NSLocalizedRecoverySuggestionErrorKey];
*outError = [NSError errorWithDomain:PBGitXErrorDomain code:PBFileReadingUnsupportedErrorCode userInfo:userInfo];
*outError = [NSError errorWithDomain:PBGitRepositoryErrorDomain code:0 userInfo:userInfo];
}
return NO;
}
@@ -127,9 +116,9 @@ static NSString * repositoryBasePath = nil;
NSURL* gitDirURL = [PBGitRepository gitDirForURL:[self fileURL]];
if (!gitDirURL) {
if (outError) {
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"%@ does not appear to be a git repository.", [[self fileURL] path]]
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"%@ does not appear to be a git repository.", [self fileName]]
forKey:NSLocalizedRecoverySuggestionErrorKey];
*outError = [NSError errorWithDomain:PBGitXErrorDomain code:PBNotAGitRepositoryErrorCode userInfo:userInfo];
*outError = [NSError errorWithDomain:PBGitRepositoryErrorDomain code:0 userInfo:userInfo];
}
return NO;
}
@@ -148,6 +137,13 @@ static NSString * repositoryBasePath = nil;
revisionList = [[PBGitHistoryList alloc] initWithRepository:self];
}
- (void)close
{
[revisionList cleanup];
[super close];
}
- (id) initWithURL: (NSURL*) path
{
if (![PBGitBinary path])
@@ -157,20 +153,20 @@ static NSString * repositoryBasePath = nil;
if (!gitDirURL)
return nil;
if (self = [super init]) {
[self setFileURL: gitDirURL];
[self setup];
// We don't want the window controller to display anything yet..
// We'll leave that to the caller of this method.
#ifndef CLI
[self addWindowController:[[PBGitWindowController alloc] initWithRepository:self displayDefault:NO]];
#endif
[self showWindows];
}
return self;
self = [self init];
[self setFileURL: gitDirURL];
[self setup];
// We don't want the window controller to display anything yet..
// We'll leave that to the caller of this method.
#ifndef CLI
[self addWindowController:[[PBGitWindowController alloc] initWithRepository:self displayDefault:NO]];
#endif
[self showWindows];
return self;
}
- (void) forceUpdateRevisions
@@ -185,7 +181,6 @@ static NSString * repositoryBasePath = nil;
// The fileURL the document keeps is to the .git dir, but thats pretty
// useless for display in the window title bar, so we show the directory above
- (NSString *) displayName
{
if (![[PBGitRef refFromString:[[self headRef] simpleRef]] type])
@@ -239,14 +234,14 @@ static NSString * repositoryBasePath = nil;
{
NSString* type = [components objectAtIndex:1];
NSString* sha;
PBGitSHA *sha;
if ([type isEqualToString:@"tag"] && [components count] == 4)
sha = [components objectAtIndex:3];
sha = [PBGitSHA shaWithString:[components objectAtIndex:3]];
else
sha = [components objectAtIndex:2];
sha = [PBGitSHA shaWithString:[components objectAtIndex:2]];
NSMutableArray* curRefs;
if (curRefs = [refs objectForKey:sha])
if ( (curRefs = [refs objectForKey:sha]) != nil )
[curRefs addObject:ref];
else
[refs setObject:[NSMutableArray arrayWithObject:ref] forKey:sha];
@@ -254,7 +249,9 @@ static NSString * repositoryBasePath = nil;
- (void) reloadRefs
{
_headRef = nil;
_headRef = nil;
_headSha = nil;
refs = [NSMutableDictionary dictionary];
NSMutableArray *oldBranches = [branches mutableCopy];
@@ -307,32 +304,30 @@ static NSString * repositoryBasePath = nil;
else
_headRef = [[PBGitRevSpecifier alloc] initWithRef:[PBGitRef refFromString:@"HEAD"]];
_headSha = [self shaForRef:[_headRef ref]];
return _headRef;
}
- (NSString *) headSHA
- (PBGitSHA *)headSHA
{
return [self shaForRef:[[self headRef] ref]];
if (! _headSha)
[self headRef];
return _headSha;
}
- (NSString *) headRefForSHA:(NSString *)sha
{
// TODO: move code over
// from PBGitSidebarController populateList
// that deals with getting the head refs path
}
- (PBGitCommit *) headCommit
- (PBGitCommit *)headCommit
{
return [self commitForSHA:[self headSHA]];
}
- (NSString *) shaForRef:(PBGitRef *)ref
- (PBGitSHA *)shaForRef:(PBGitRef *)ref
{
if (!ref)
return nil;
for (NSString *sha in refs)
for (PBGitSHA *sha in refs)
for (PBGitRef *existingRef in [refs objectForKey:sha])
if ([existingRef isEqualToRef:ref])
return sha;
@@ -343,10 +338,10 @@ static NSString * repositoryBasePath = nil;
if (retValue || [shaForRef isEqualToString:@""])
return nil;
return shaForRef;
return [PBGitSHA shaWithString:shaForRef];
}
- (PBGitCommit *) commitForRef:(PBGitRef *)ref
- (PBGitCommit *)commitForRef:(PBGitRef *)ref
{
if (!ref)
return nil;
@@ -354,7 +349,7 @@ static NSString * repositoryBasePath = nil;
return [self commitForSHA:[self shaForRef:ref]];
}
- (PBGitCommit *) commitForSHA:(NSString *)sha
- (PBGitCommit *)commitForSHA:(PBGitSHA *)sha
{
if (!sha)
return nil;
@@ -365,18 +360,18 @@ static NSString * repositoryBasePath = nil;
revList = revisionList.projectCommits;
}
for (PBGitCommit *commit in revList)
if ([[commit realSha] isEqualToString:sha])
if ([[commit sha] isEqual:sha])
return commit;
return nil;
}
- (BOOL) isOnSameBranch:(NSString *)branchSHA asSHA:(NSString *)testSHA
- (BOOL)isOnSameBranch:(PBGitSHA *)branchSHA asSHA:(PBGitSHA *)testSHA
{
if (!branchSHA || !testSHA)
return NO;
if ([testSHA isEqualToString:branchSHA])
if ([testSHA isEqual:branchSHA])
return YES;
NSArray *revList = revisionList.projectCommits;
@@ -384,34 +379,34 @@ static NSString * repositoryBasePath = nil;
NSMutableSet *searchSHAs = [NSMutableSet setWithObject:branchSHA];
for (PBGitCommit *commit in revList) {
NSString *commitSHA = [commit realSha];
PBGitSHA *commitSHA = [commit sha];
if ([searchSHAs containsObject:commitSHA]) {
if ([testSHA isEqualToString:commitSHA])
if ([testSHA isEqual:commitSHA])
return YES;
[searchSHAs removeObject:commitSHA];
[searchSHAs addObjectsFromArray:commit.parents];
}
else if ([testSHA isEqualToString:commitSHA])
else if ([testSHA isEqual:commitSHA])
return NO;
}
return NO;
}
- (BOOL) isSHAOnHeadBranch:(NSString *)testSHA
- (BOOL)isSHAOnHeadBranch:(PBGitSHA *)testSHA
{
if (!testSHA)
return NO;
NSString *headSHA = [self headSHA];
PBGitSHA *headSHA = [self headSHA];
if ([testSHA isEqualToString:headSHA])
if ([testSHA isEqual:headSHA])
return YES;
return [self isOnSameBranch:headSHA asSHA:testSHA];
}
- (BOOL) isRefOnHeadBranch:(PBGitRef *)testRef
- (BOOL)isRefOnHeadBranch:(PBGitRef *)testRef
{
if (!testRef)
return NO;
@@ -428,32 +423,6 @@ static NSString * repositoryBasePath = nil;
return YES;
}
- (BOOL) checkRefFormatForBranch:(NSString *)shaOrRefName
{
int retValue = 1;
[self outputInWorkdirForArguments:[NSArray arrayWithObjects:@"check-ref-format", @"--branch", shaOrRefName, nil] retValue:&retValue];
if (retValue)
return NO;
return YES;
}
- (PBGitRef *) completeRefForString:(NSString *)partialRefString {
if (![self checkRefFormat:partialRefString] &&
![self checkRefFormatForBranch:partialRefString]) {
return nil;
}
NSArray * prefixes = [NSArray arrayWithObjects:kGitXBranchRefPrefix, kGitXRemoteRefPrefix, kGitXTagRefPrefix, nil];
PBGitRef * completeRef = nil;
for (NSString * prefix in prefixes) {
PBGitRef * tryref = [PBGitRef refFromString:[NSString stringWithFormat:@"%@%@", prefix, partialRefString]];
if ([self refExists:tryref]) {
completeRef = tryref;
break;
}
}
return completeRef;
}
- (BOOL) refExists:(PBGitRef *)ref
{
int retValue = 1;
@@ -463,13 +432,29 @@ static NSString * repositoryBasePath = nil;
return YES;
}
- (NSString *) shaExists:(NSString *)sha
// useful for getting the full ref for a user entered name
// EX: name: master
// ref: refs/heads/master
- (PBGitRef *)refForName:(NSString *)name
{
if (!name)
return nil;
int retValue = 1;
NSString *output = [self outputInWorkdirForArguments:[NSArray arrayWithObjects:@"rev-parse", sha, nil] retValue:&retValue];
if (retValue || [output isEqualToString:@""])
return nil;
return output;
NSString *output = [self outputInWorkdirForArguments:[NSArray arrayWithObjects:@"show-ref", name, nil] retValue:&retValue];
if (retValue)
return nil;
// the output is in the format: <SHA-1 ID> <space> <reference name>
// with potentially multiple lines if there are multiple matching refs (ex: refs/remotes/origin/master)
// here we only care about the first match
NSArray *refList = [output componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([refList count] > 1) {
NSString *refName = [refList objectAtIndex:1];
return [PBGitRef refFromString:refName];
}
return nil;
}
// Returns either this object, or an existing, equal object
@@ -515,9 +500,8 @@ static NSString * repositoryBasePath = nil;
- (NSString *) workingDirectory
{
NSString * dotGitSuffix = @"/.git";
if ([[[self fileURL] path] hasSuffix:dotGitSuffix])
return [[[self fileURL] path] substringToIndex:[[[self fileURL] path] length] - [dotGitSuffix length]];
if ([self.fileURL.path hasSuffix:@"/.git"])
return [self.fileURL.path substringToIndex:[self.fileURL.path length] - 5];
else if ([[self outputForCommand:@"rev-parse --is-inside-work-tree"] isEqualToString:@"true"])
return [PBGitBinary path];
@@ -641,24 +625,7 @@ static NSString * repositoryBasePath = nil;
NSString *remoteName = [remoteRef remoteName];
[arguments addObject:remoteName];
NSString *branchName = nil;
NSString *refSpec = nil;
if ([ref isRemoteBranch]) {
branchName = [ref shortName];
refSpec = [ref remoteBranchName];
}
else if ([ref isRemote] || !ref) {
branchName = @"all tracking branches";
}
else {
branchName = [ref shortName];
refSpec = [NSString stringWithFormat:@"%@:%@", branchName, branchName];
}
if (refSpec)
[arguments addObject:refSpec];
NSString *headRefName = [[[self headRef] ref] shortName];
NSString *description = [NSString stringWithFormat:@"Pulling %@ from %@ and updating %@", branchName, remoteName, headRefName];
NSString *description = [NSString stringWithFormat:@"Pulling all tracking branches from %@", remoteName];
NSString *title = @"Pulling from remote";
[PBRemoteProgressSheet beginRemoteProgressSheetForArguments:arguments title:title description:description inRepository:self];
}
@@ -919,6 +886,131 @@ static NSString * repositoryBasePath = nil;
}
#pragma mark GitX Scripting
- (void)handleRevListArguments:(NSArray *)arguments inWorkingDirectory:(NSURL *)workingDirectory
{
if (![arguments count])
return;
PBGitRevSpecifier *revListSpecifier = nil;
// the argument may be a branch or tag name but will probably not be the full reference
if ([arguments count] == 1) {
PBGitRef *refArgument = [self refForName:[arguments lastObject]];
if (refArgument) {
revListSpecifier = [[PBGitRevSpecifier alloc] initWithRef:refArgument];
revListSpecifier.workingDirectory = workingDirectory;
}
}
if (!revListSpecifier) {
revListSpecifier = [[PBGitRevSpecifier alloc] initWithParameters:arguments];
revListSpecifier.workingDirectory = workingDirectory;
}
self.currentBranch = [self addBranch:revListSpecifier];
[PBGitDefaults setShowStageView:NO];
[self.windowController showHistoryView:self];
}
- (void)handleBranchFilterEventForFilter:(PBGitXBranchFilterType)filter additionalArguments:(NSMutableArray *)arguments inWorkingDirectory:(NSURL *)workingDirectory
{
self.currentBranchFilter = filter;
[PBGitDefaults setShowStageView:NO];
[self.windowController showHistoryView:self];
// treat any additional arguments as a rev-list specifier
if ([arguments count] > 1) {
[arguments removeObjectAtIndex:0];
[self handleRevListArguments:arguments inWorkingDirectory:workingDirectory];
}
}
- (void)handleGitXScriptingArguments:(NSAppleEventDescriptor *)argumentsList inWorkingDirectory:(NSURL *)workingDirectory
{
NSMutableArray *arguments = [NSMutableArray array];
uint argumentsIndex = 1; // AppleEvent list descriptor's are one based
while(1) {
NSAppleEventDescriptor *arg = [argumentsList descriptorAtIndex:argumentsIndex++];
if (arg)
[arguments addObject:[arg stringValue]];
else
break;
}
if (![arguments count])
return;
NSString *firstArgument = [arguments objectAtIndex:0];
if ([firstArgument isEqualToString:@"-c"] || [firstArgument isEqualToString:@"--commit"]) {
[PBGitDefaults setShowStageView:YES];
[self.windowController showCommitView:self];
return;
}
if ([firstArgument isEqualToString:@"--all"]) {
[self handleBranchFilterEventForFilter:kGitXAllBranchesFilter additionalArguments:arguments inWorkingDirectory:workingDirectory];
return;
}
if ([firstArgument isEqualToString:@"--local"]) {
[self handleBranchFilterEventForFilter:kGitXLocalRemoteBranchesFilter additionalArguments:arguments inWorkingDirectory:workingDirectory];
return;
}
if ([firstArgument isEqualToString:@"--branch"]) {
[self handleBranchFilterEventForFilter:kGitXSelectedBranchFilter additionalArguments:arguments inWorkingDirectory:workingDirectory];
return;
}
// if the argument is not a known command then treat it as a rev-list specifier
[self handleRevListArguments:arguments inWorkingDirectory:workingDirectory];
}
// see if the current appleEvent has the command line arguments from the gitx cli
// this could be from an openApplication or an openDocument apple event
// when opening a repository this is called before the sidebar controller gets it's awakeFromNib: message
// 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
- (void)showWindows
{
NSAppleEventDescriptor *currentAppleEvent = [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent];
if (currentAppleEvent) {
NSAppleEventDescriptor *eventRecord = [currentAppleEvent paramDescriptorForKeyword:keyAEPropData];
// on app launch there may be many repositories opening, so double check that this is the right repo
NSString *path = [[eventRecord paramDescriptorForKeyword:typeFileURL] stringValue];
if (path) {
NSURL *workingDirectory = [NSURL URLWithString:path];
if ([[PBGitRepository gitDirForURL:workingDirectory] isEqual:[self fileURL]]) {
NSAppleEventDescriptor *argumentsList = [eventRecord paramDescriptorForKeyword:kGitXAEKeyArgumentsList];
[self handleGitXScriptingArguments:argumentsList inWorkingDirectory:workingDirectory];
// showWindows may be called more than once during app launch so remove the CLI data after we handle the event
[currentAppleEvent removeDescriptorWithKeyword:keyAEPropData];
}
}
}
[super showWindows];
}
// for the scripting bridge
- (void)findInModeScriptCommand:(NSScriptCommand *)command
{
NSDictionary *arguments = [command arguments];
NSString *searchString = [arguments objectForKey:kGitXFindSearchStringKey];
if (searchString) {
NSInteger mode = [[arguments objectForKey:kGitXFindInModeKey] integerValue];
[PBGitDefaults setShowStageView:NO];
[self.windowController showHistoryView:self];
[self.windowController setHistorySearch:searchString mode:mode];
}
}
#pragma mark low level
- (int) returnValueForCommand:(NSString *)cmd
@@ -930,7 +1022,7 @@ static NSString * repositoryBasePath = nil;
- (NSFileHandle*) handleForArguments:(NSArray *)args
{
NSString* gitDirArg = [@"--git-dir=" stringByAppendingString:[[self fileURL] path]];
NSString* gitDirArg = [@"--git-dir=" stringByAppendingString:self.fileURL.path];
NSMutableArray* arguments = [NSMutableArray arrayWithObject: gitDirArg];
[arguments addObjectsFromArray: args];
return [PBEasyPipe handleForCommand:[PBGitBinary path] withArgs:arguments];
@@ -938,7 +1030,7 @@ static NSString * repositoryBasePath = nil;
- (NSFileHandle*) handleInWorkDirForArguments:(NSArray *)args
{
NSString* gitDirArg = [@"--git-dir=" stringByAppendingString:[[self fileURL] path]];
NSString* gitDirArg = [@"--git-dir=" stringByAppendingString:self.fileURL.path];
NSMutableArray* arguments = [NSMutableArray arrayWithObject: gitDirArg];
[arguments addObjectsFromArray: args];
return [PBEasyPipe handleForCommand:[PBGitBinary path] withArgs:arguments inDir:[self workingDirectory]];
@@ -962,32 +1054,9 @@ static NSString * repositoryBasePath = nil;
return [self outputForArguments: arguments retValue: ret];
}
- (NSString *) outputForShellScriptTemplate:(NSString *)scriptTemplate keywordDict:(NSDictionary *)keywordDict retValue:(NSInteger *)retValue {
BMScript * script = [[BMScript alloc] initWithTemplateSource:scriptTemplate
options:BMSynthesizeOptions(@"/bin/sh", @"-c")];
[script saturateTemplateWithDictionary:keywordDict];
if (*retValue) {
*retValue = [script execute];
} else {
[script execute];
}
return [script lastResult];
}
- (NSString *) outputForShellScript:(NSString *)script retValue:(NSInteger *)retValue {
BMScript * shellScript = [BMScript shellScriptWithSource:script];
if (*retValue) {
*retValue = [shellScript execute];
} else {
[shellScript execute];
}
return [shellScript lastResult];
}
- (NSString*) outputForArguments:(NSArray*) arguments
{
return [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:arguments inDir: [[self fileURL] path]];
return [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:arguments inDir: self.fileURL.path];
}
- (NSString*) outputInWorkdirForArguments:(NSArray*) arguments
@@ -1002,7 +1071,7 @@ static NSString * repositoryBasePath = nil;
- (NSString*) outputForArguments:(NSArray *)arguments retValue:(int *)ret
{
return [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:arguments inDir: [[self fileURL] path] retValue: ret];
return [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:arguments inDir: self.fileURL.path retValue: ret];
}
- (NSString*) outputForArguments:(NSArray *)arguments inputString:(NSString *)input retValue:(int *)ret
+1
View File
@@ -25,6 +25,7 @@
- (id) initWithRepository:(PBGitRepository *)repo rev:(PBGitRevSpecifier *)rev shouldGraph:(BOOL)graph;
- (void) loadRevisons;
- (void)cancel;
@property (retain) NSMutableArray *commits;
@property (readonly) BOOL isParsing;
+34 -44
View File
@@ -12,7 +12,6 @@
#import "PBGitGrapher.h"
#import "PBGitRevSpecifier.h"
#include "git/oid.h"
#include <ext/stdio_filebuf.h>
#include <iostream>
#include <string>
@@ -59,6 +58,12 @@ using namespace std;
}
- (void)cancel
{
[parseThread cancel];
}
- (void) finishedParsing
{
self.isParsing = NO;
@@ -91,28 +96,29 @@ using namespace std;
- (void) walkRevisionListWithSpecifier:(PBGitRevSpecifier*)rev
{
NSDate *start = [NSDate date];
NSDate *lastUpdate = [NSDate date];
NSMutableArray *revisions = [NSMutableArray array];
PBGitGrapher *g = [[PBGitGrapher alloc] initWithRepository:repository];
std::map<string, NSStringEncoding> encodingMap;
NSThread *currentThread = [NSThread currentThread];
NSString *formatString = @"--pretty=format:%H\01%e\01%an\01%s\01%P\01%at";
NSString *formatString = @"--pretty=format:%H\01%e\01%aN\01%cN\01%s\01%P\01%at";
BOOL showSign = [rev hasLeftRight];
if (showSign)
formatString = [formatString stringByAppendingString:@"\01%m"];
NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"log", @"-z", @"--early-output", @"--topo-order", @"--children", formatString, nil];
NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"log", @"-z", @"--topo-order", @"--children", formatString, nil];
if (!rev)
[arguments addObject:@"HEAD"];
else
[arguments addObjectsFromArray:[rev parameters]];
NSString *directory = rev.workingDirectory ? [rev.workingDirectory path] : [[repository fileURL] path];
NSString *directory = rev.workingDirectory ? rev.workingDirectory.path : repository.fileURL.path;
NSTask *task = [PBEasyPipe taskForCommand:[PBGitBinary path] withArgs:arguments inDir:directory];
[task launch];
NSFileHandle* handle = [[task standardOutput] fileHandleForReading];
NSFileHandle *handle = [task.standardOutput fileHandleForReading];
int fd = [handle fileDescriptor];
__gnu_cxx::stdio_filebuf<char> buf(fd, std::ios::in);
@@ -120,34 +126,13 @@ using namespace std;
int num = 0;
while (true) {
if ([currentThread isCancelled])
break;
string sha;
if (!getline(stream, sha, '\1'))
break;
// We reached the end of some temporary output. Show what we have
// until now, and then start again. The sha of the next thing is still
// in this buffer. So, we use a substring of current input.
if (sha[1] == 'i') // Matches 'Final output'
{
num = 0;
if ([currentThread isCancelled])
break;
NSDictionary *update = [NSDictionary dictionaryWithObjectsAndKeys:currentThread, kRevListThreadKey, revisions, kRevListRevisionsKey, nil];
[self performSelectorOnMainThread:@selector(updateCommits:) withObject:update waitUntilDone:NO];
revisions = [NSMutableArray array];
if (isGraphing)
g = [[PBGitGrapher alloc] initWithRepository:repository];
revisions = [NSMutableArray array];
// If the length is < 40, then there are no commits.. quit now
if (sha.length() < 40)
break;
sha = sha.substr(sha.length() - 40, 40);
}
// From now on, 1.2 seconds
string encoding_str;
getline(stream, encoding_str, '\1');
@@ -164,11 +149,14 @@ using namespace std;
git_oid oid;
git_oid_mkstr(&oid, sha.c_str());
PBGitCommit* newCommit = [[PBGitCommit alloc] initWithRepository:repository andSha:oid];
PBGitCommit *newCommit = [PBGitCommit commitWithRepository:repository andSha:[PBGitSHA shaWithOID:oid]];
string author;
getline(stream, author, '\1');
string committer;
getline(stream, committer, '\1');
string subject;
getline(stream, subject, '\1');
@@ -177,17 +165,16 @@ using namespace std;
if (parentString.size() != 0)
{
if (((parentString.size() + 1) % 41) != 0) {
NSLog(@"invalid parents: %i", parentString.size());
NSLog(@"invalid parents: %zu", parentString.size());
continue;
}
int nParents = (parentString.size() + 1) / 41;
git_oid *parents = (git_oid *)malloc(sizeof(git_oid) * nParents);
NSMutableArray *parents = [NSMutableArray arrayWithCapacity:nParents];
int parentIndex;
for (parentIndex = 0; parentIndex < nParents; ++parentIndex)
git_oid_mkstr(parents + parentIndex, parentString.substr(parentIndex * 41, 40).c_str());
newCommit.parentShas = parents;
newCommit.nParents = nParents;
[parents addObject:[PBGitSHA shaWithCString:parentString.substr(parentIndex * 41, 40).c_str()]];
[newCommit setParents:parents];
}
int time;
@@ -195,6 +182,7 @@ using namespace std;
[newCommit setSubject:[NSString stringWithCString:subject.c_str() encoding:encoding]];
[newCommit setAuthor:[NSString stringWithCString:author.c_str() encoding:encoding]];
[newCommit setCommitter:[NSString stringWithCString:committer.c_str() encoding:encoding]];
[newCommit setTimestamp:time];
if (showSign)
@@ -216,18 +204,19 @@ using namespace std;
if (isGraphing)
[g decorateCommit:newCommit];
if (++num % 1000 == 0) {
if ([currentThread isCancelled])
break;
NSDictionary *update = [NSDictionary dictionaryWithObjectsAndKeys:currentThread, kRevListThreadKey, revisions, kRevListRevisionsKey, nil];
[self performSelectorOnMainThread:@selector(updateCommits:) withObject:update waitUntilDone:NO];
revisions = [NSMutableArray array];
if (++num % 100 == 0) {
if ([[NSDate date] timeIntervalSinceDate:lastUpdate] > 0.1) {
NSDictionary *update = [NSDictionary dictionaryWithObjectsAndKeys:currentThread, kRevListThreadKey, revisions, kRevListRevisionsKey, nil];
[self performSelectorOnMainThread:@selector(updateCommits:) withObject:update waitUntilDone:NO];
revisions = [NSMutableArray array];
lastUpdate = [NSDate date];
}
}
}
if (![currentThread isCancelled]) {
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:start];
NSLog(@"Loaded %i commits in %f seconds", num, duration);
NSLog(@"Loaded %i commits in %f seconds (%f/sec)", num, duration, num/duration);
// Make sure the commits are stored before exiting.
NSDictionary *update = [NSDictionary dictionaryWithObjectsAndKeys:currentThread, kRevListThreadKey, revisions, kRevListRevisionsKey, nil];
@@ -236,9 +225,10 @@ using namespace std;
[self performSelectorOnMainThread:@selector(finishedParsing) withObject:nil waitUntilDone:NO];
}
else {
NSLog(@"[%@ %s] thread has been canceled", [self class], _cmd);
NSLog(@"[%@ %s] thread has been canceled", [self class], NSStringFromSelector(_cmd));
}
[task terminate];
[task waitUntilExit];
}
+12 -20
View File
@@ -21,23 +21,18 @@
parameters = params;
description = descrip;
if (([parameters count] > 1) || ([parameters count] == 0)) {
isSimpleRef = NO;
} else {
NSString *param = [parameters objectAtIndex:0];
if (([parameters count] > 1) || ([parameters count] == 0))
isSimpleRef = NO;
else {
NSString *param = [parameters objectAtIndex:0];
if ([param hasPrefix:@"-"] ||
[param rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"^@{}~:"]].location != NSNotFound ||
[param rangeOfString:@".."].location != NSNotFound) {
isSimpleRef = NO;
} else {
if ([param hasPrefix:@"refs/"]) {
isSimpleRef = YES;
} else {
isSimpleRef = NO;
}
}
[param rangeOfString:@".."].location != NSNotFound)
isSimpleRef = NO;
else
isSimpleRef = YES;
}
// NSLog(@"paramters = %@, isSimpleRef = %@", parameters, (isSimpleRef ? @"YES" : @"NO"));
return self;
}
@@ -49,7 +44,7 @@
- (id) initWithRef:(PBGitRef *)ref
{
[self initWithParameters:[NSArray arrayWithObject:ref.ref] description:[ref shortName]];
[self initWithParameters:[NSArray arrayWithObject:ref.ref] description:ref.shortName];
return self;
}
@@ -92,11 +87,6 @@
return description;
}
- (NSString *) debugDescription {
return [NSString stringWithFormat:@"<%@: %p> description = %@, parameters = %@",
NSStringFromClass([self class]), self, description, parameters];
}
- (NSString *) title
{
NSString *title = nil;
@@ -105,6 +95,8 @@
title = @"detached HEAD";
else if ([self isSimpleRef])
title = [[self ref] shortName];
else if ([self.description hasPrefix:@"-S"])
title = [self.description substringFromIndex:[@"-S" length]];
else if ([self.description hasPrefix:@"HEAD -- "])
title = [self.description substringFromIndex:[@"HEAD -- " length]];
else if ([self.description hasPrefix:@"-- "])
+33 -13
View File
@@ -9,6 +9,7 @@
#import "PBGitRevisionCell.h"
#import "PBGitRef.h"
#import "RoundedRectangle.h"
#import "GitXTextFieldCell.h"
@implementation PBGitRevisionCell
@@ -16,20 +17,24 @@
- (id) initWithCoder: (id) coder
{
self = [super initWithCoder:coder];
textCell = [[NSTextFieldCell alloc] initWithCoder:coder];
textCell = [[GitXTextFieldCell alloc] initWithCoder:coder];
return self;
}
- (NSArray*) colors
+ (NSArray *)laneColors
{
return [NSArray arrayWithObjects:
[NSColor colorWithCalibratedRed: 0X4e/256.0 green:0X9A/256.0 blue: 0X06/256.0 alpha: 1.0],
[NSColor colorWithCalibratedRed: 0X20/256.0 green:0X4A/256.0 blue: 0X87/256.0 alpha: 1.0],
[NSColor colorWithCalibratedRed: 0XC4/256.0 green:0XA0/256.0 blue: 0 alpha: 1.0],
[NSColor colorWithCalibratedRed: 0X5C/256.0 green:0X35/256.0 blue: 0X66/256.0 alpha: 1.0],
[NSColor colorWithCalibratedRed: 0XA4/256.0 green:0X00/256.0 blue: 0X00/256.0 alpha: 1.0],
[NSColor colorWithCalibratedRed: 0XCE/256.0 green:0X5C/256.0 blue: 0 alpha: 1.0],
nil];
static NSArray *laneColors = nil;
if (!laneColors)
laneColors = [NSArray arrayWithObjects:
[NSColor colorWithCalibratedRed: 0X4e/256.0 green:0X9A/256.0 blue: 0X06/256.0 alpha: 1.0],
[NSColor colorWithCalibratedRed: 0X20/256.0 green:0X4A/256.0 blue: 0X87/256.0 alpha: 1.0],
[NSColor colorWithCalibratedRed: 0XC4/256.0 green:0XA0/256.0 blue: 0 alpha: 1.0],
[NSColor colorWithCalibratedRed: 0X5C/256.0 green:0X35/256.0 blue: 0X66/256.0 alpha: 1.0],
[NSColor colorWithCalibratedRed: 0XA4/256.0 green:0X00/256.0 blue: 0X00/256.0 alpha: 1.0],
[NSColor colorWithCalibratedRed: 0XCE/256.0 green:0X5C/256.0 blue: 0 alpha: 1.0],
nil];
return laneColors;
}
- (void) drawLineFromColumn: (int) from toColumn: (int) to inRect: (NSRect) r offset: (int) offset color: (int) c
@@ -41,8 +46,7 @@
NSPoint source = NSMakePoint(origin.x + columnWidth* from, origin.y + offset);
NSPoint center = NSMakePoint( origin.x + columnWidth * to, origin.y + r.size.height * 0.5 + 0.5);
// Just use red for now.
NSArray* colors = [self colors];
NSArray* colors = [PBGitRevisionCell laneColors];
[[colors objectAtIndex: c % [colors count]] set];
NSBezierPath * path = [NSBezierPath bezierPath];
@@ -54,6 +58,16 @@
}
- (BOOL) isCurrentCommit
{
PBGitSHA *thisSha = [self.objectValue sha];
PBGitRepository* repository = [self.objectValue repository];
PBGitSHA *currentSha = [repository headSHA];
return [currentSha isEqual:thisSha];
}
- (void) drawCircleInRect: (NSRect) r
{
@@ -71,7 +85,13 @@
[path fill];
NSRect smallOval = { columnOrigin.x - 3, columnOrigin.y + r.size.height * 0.5 - 3, 6, 6};
[[NSColor whiteColor] set];
if ( [self isCurrentCommit ] ) {
[[NSColor colorWithCalibratedRed: 0Xfc/256.0 green:0Xa6/256.0 blue: 0X4f/256.0 alpha: 1.0] set];
} else {
[[NSColor whiteColor] set];
}
path = [NSBezierPath bezierPathWithOvalInRect:smallOval];
[path fill];
}
+28
View File
@@ -0,0 +1,28 @@
//
// PBGitSHA.h
// GitX
//
// Created by BrotherBard on 3/28/10.
// Copyright 2010 BrotherBard. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#include "git/oid.h"
@interface PBGitSHA : NSObject <NSCopying> {
git_oid oid;
NSString *string;
}
+ (PBGitSHA *)shaWithOID:(git_oid)oid;
+ (PBGitSHA *)shaWithString:(NSString *)shaString;
+ (PBGitSHA *)shaWithCString:(const char *)shaCString;
- (BOOL)isEqualToOID:(git_oid)other_oid;
@property (readonly) git_oid oid;
@property (readonly) NSString *string;
@end
+139
View File
@@ -0,0 +1,139 @@
//
// PBGitSHA.m
// GitX
//
// Created by BrotherBard on 3/28/10.
// Copyright 2010 BrotherBard. All rights reserved.
//
#import "PBGitSHA.h"
@interface PBGitSHA ()
- (id)initWithOID:(git_oid)g_oid;
@end
@implementation PBGitSHA
@synthesize oid;
@synthesize string;
+ (PBGitSHA *)shaWithOID:(git_oid)oid
{
return [[PBGitSHA alloc] initWithOID:oid];
}
+ (PBGitSHA *)shaWithString:(NSString *)shaString
{
git_oid oid;
int err = git_oid_mkstr(&oid, [shaString UTF8String]);
if (err == GIT_ENOTOID)
return nil;
return [self shaWithOID:oid];
}
+ (PBGitSHA *)shaWithCString:(const char *)shaCString
{
git_oid oid;
int err = git_oid_mkstr(&oid, shaCString);
if (err == GIT_ENOTOID)
return nil;
return [self shaWithOID:oid];
}
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
return NO;
}
+ (BOOL)isKeyExcludedFromWebScript:(const char *)name
{
return NO;
}
#pragma mark -
#pragma mark PBGitSHA
- (id)initWithOID:(git_oid)g_oid
{
self = [super init];
if (!self)
return nil;
oid = g_oid;
return self;
}
- (NSString *)string
{
if (!string) {
char *hex = git_oid_mkhex(&oid);
if (hex == NULL)
return nil;
string = [NSString stringWithUTF8String:hex];
free(hex);
}
return string;
}
- (BOOL)isEqual:(id)otherSHA
{
if (self == otherSHA)
return YES;
git_oid other_oid = [(PBGitSHA *)otherSHA oid];
return git_oid_cmp(&oid, &other_oid) == 0;
}
- (BOOL)isEqualToOID:(git_oid)other_oid
{
return git_oid_cmp(&oid, &other_oid) == 0;
}
- (NSUInteger)hash
{
NSUInteger hash;
memcpy(&hash, &(oid.id), sizeof(NSUInteger));
return hash;
}
- (NSString *)description
{
return [self string];
}
#pragma mark <NSCopying>
- (id)copyWithZone:(NSZone *)zone
{
git_oid oidCopy;
git_oid_cpy(&oidCopy, &oid);
PBGitSHA *copy = [[[self class] allocWithZone:zone] initWithOID:oidCopy];
return copy;
}
@end
+6 -9
View File
@@ -12,13 +12,13 @@
@class PBSourceViewItem;
@class PBGitHistoryController;
@class PBGitCommitController;
@class ApplicationController;
@interface PBGitSidebarController : PBViewController <NSOutlineViewDelegate> {
@interface PBGitSidebarController : PBViewController {
IBOutlet NSWindow *window;
IBOutlet NSOutlineView *sourceView;
IBOutlet NSView *sourceListControlsView;
IBOutlet NSPopUpButton *actionButton;
IBOutlet NSSegmentedControl *remoteControls;
NSMutableArray *items;
@@ -26,23 +26,20 @@
PBSourceViewItem *stage;
PBSourceViewItem *branches, *remotes, *tags, *others;
PBSourceViewItem * deferredSelectObject;
PBGitHistoryController *historyViewController;
PBGitCommitController *commitViewController;
}
- (void) selectStage;
- (void) selectBranch:(PBSourceViewItem *)branchItem;
- (void) selectCurrentBranch;
- (PBSourceViewItem *) selectedItem;
- (NSMenu *) menuForRow:(NSInteger)row;
- (IBAction) fetchPullPushAction:(id)sender;
- (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode;
@property(readonly) NSMutableArray *items;
@property(readonly) NSView *sourceListControlsView;
@property(readonly) PBSourceViewItem * remotes;
@property(readonly) NSOutlineView * sourceView;
@property(assign) PBSourceViewItem * deferredSelectObject;
@end
+140 -180
View File
@@ -15,8 +15,7 @@
#import "NSOutlineViewExt.h"
#import "PBAddRemoteSheet.h"
#import "PBGitDefaults.h"
#import "BMScript.h"
#import "ApplicationController.h"
#import "PBHistorySearchController.h"
@interface PBGitSidebarController ()
@@ -25,38 +24,32 @@
- (PBSourceViewItem *) itemForRev:(PBGitRevSpecifier *)rev;
- (void) removeRevSpec:(PBGitRevSpecifier *)rev;
- (void) updateActionMenu;
- (void) updateRemoteControls;
@end
@implementation PBGitSidebarController
@synthesize items;
@synthesize sourceListControlsView, sourceView, remotes;
@synthesize deferredSelectObject;
@synthesize sourceListControlsView;
- (id)initWithRepository:(PBGitRepository *)theRepository superController:(PBGitWindowController *)controller
{
self = [super initWithRepository:theRepository superController:controller];
[sourceView setDelegate:self];
items = [NSMutableArray array];
deferredSelectObject = nil;
return self;
}
- (void)awakeFromNib
{
[super awakeFromNib];
window.contentView = [self view];
window.contentView = self.view;
[self populateList];
historyViewController = [[PBGitHistoryController alloc] initWithRepository:repository superController:superController];
commitViewController = [[PBGitCommitController alloc] initWithRepository:repository superController:superController];
superController.historyController = historyViewController;
historyViewController.sidebarSourceView = self.sourceView;
historyViewController.sidebarRemotes = self.remotes;
[repository addObserver:self forKeyPath:@"currentBranch" options:0 context:@"currentBranchChange"];
[repository addObserver:self forKeyPath:@"currentBranch" options:0 context:@"currentBranchChange"];
[repository addObserver:self forKeyPath:@"branches" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:@"branchesModified"];
[self menuNeedsUpdate:[actionButton menu]];
@@ -64,123 +57,22 @@
if ([PBGitDefaults showStageView])
[self selectStage];
else
[self selectCurrentBranch];
[self selectCurrentBranch];
}
- (void)populateList
- (void)closeView
{
// NSLog(@"[%@ %s]", [self class], _cmd);
[historyViewController closeView];
[commitViewController closeView];
PBSourceViewItem *project = [PBSourceViewItem groupItemWithTitle:[repository projectName]];
project.isUncollapsible = YES;
[repository removeObserver:self forKeyPath:@"currentBranch"];
[repository removeObserver:self forKeyPath:@"branches"];
stage = [PBGitSVStageItem stageItem];
[project addChild:stage];
branches = [PBSourceViewItem groupItemWithTitle:@"Branches"];
remotes = [PBSourceViewItem groupItemWithTitle:@"Remotes"];
tags = [PBSourceViewItem groupItemWithTitle:@"Tags"];
others = [PBSourceViewItem groupItemWithTitle:@"Other"];
for (PBGitRevSpecifier *branchRev in repository.branches)
[self addRevSpec:branchRev];
[items addObject:project];
[items addObject:branches];
[items addObject:remotes];
[items addObject:tags];
[items addObject:others];
[sourceView reloadData];
[sourceView expandItem:project];
[sourceView expandItem:branches expandChildren:YES];
[sourceView expandItem:remotes];
[sourceView reloadItem:nil reloadChildren:YES];
// figure out if args passed to gitx are meaningful enough to describe a source view branch
// and a selectable commit on the history view controller...
ApplicationController * appController = [ApplicationController sharedApplicationController];
PBGitRevSpecifier * resolvedRev = nil;
// if (YES) {
// //appController.cliArgs = @"rdi/master";
// //appController.cliArgs = @"d12b92349bb89bc83b8eab45a4bed88d50547aeb";
// appController.cliArgs = @"--commit";
// appController.launchedFromGitx = YES;
// }
NSString * cliargs = appController.cliArgs;
// if the cliArgs have a "-" prefix it might be one of the "--all", "--local", "--commit", "-S..." etc.
// parameters (see ApplicationController.m and gitx.m) then don't set the deferredSelectObject and continue
// as normal
if (appController.launchedFromGitx && cliargs && !([cliargs hasPrefix:@"-"])) {
repository.currentBranchFilter = [PBGitDefaults branchFilter];
// is it a partial ref ? (like xyz/master) - try to complete the rev
PBGitRef * ref;
if (ref = [repository completeRefForString:cliargs]) {
NSLog(@"[%@ %s] completed ref for %@ = %@", [self class], _cmd, cliargs, ref);
if (ref) {
resolvedRev = [[PBGitRevSpecifier alloc] initWithRef:ref];
}
} else {
// is it a SHA ? - figure out the branch the SHA lives in
if ((appController.deferredSelectSha = [repository shaExists:cliargs])) {
NSLog(@"[%@ %s] appController.deferredSelectSha = %@", [self class], _cmd, appController.deferredSelectSha);
// this little shell script looks up the rev for a SHA and gets the refs/... path
// for its most recent commit (aka head commit (but not _the_ HEAD)
NSString * headRefPathForShaTemplate = [NSString stringWithString:@"#!/bin/sh\n"
@"cd \"%{DIR}\"\n"
@"br=`%{GITPATH} name-rev \"%{SHA}\" | awk '{gsub(/~.*/,\"\",$2);print $2}'`\n"
@"headsha=`%{GITPATH} rev-parse $br`\n"
@"%{GITPATH} show-ref | grep $headsha | awk '{print $2}'\n"];
NSDictionary * kwds = [NSDictionary dictionaryWithObjectsAndKeys:[PBGitBinary path], @"GITPATH",
[repository workingDirectory], @"DIR",
cliargs, @"SHA", nil];
TerminationStatus retVal = BMScriptNotExecuted;
NSString * output = [repository outputForShellScriptTemplate:headRefPathForShaTemplate
keywordDict:kwds
retValue:&retVal];
if (BMScriptFinishedSuccessfully == retVal) {
output = [output substringToIndex:[output length] - 1]; // trim \n
if ([output rangeOfString:@"\n"].location != NSNotFound) {
NSArray * lines = [output componentsSeparatedByString:@"\n"];
resolvedRev = [[PBGitRevSpecifier alloc] initWithRef:[PBGitRef refFromString:[lines objectAtIndex:0]]];
} else {
resolvedRev = [[PBGitRevSpecifier alloc] initWithRef:[PBGitRef refFromString:output]];
}
}
}
}
// now try to find resolvedRev in the sourceView and store it
// in defereredSelectObject so we can select it later
if (resolvedRev) {
repository.currentBranch = resolvedRev;
//repository.currentBranch.isSimpleRef = YES;
// NSLog(@"[%@ %s] currentBranch = %@", [self class], _cmd, repository.currentBranch);
// NSLog(@"[%@ %s] items = %@", [self class], _cmd, [items description]);
for (PBSourceViewItem * item in items) {
if (deferredSelectObject = [item findRev:resolvedRev])
break;
}
// NSLog(@"[%@ %s] deferredSelectObject = %@", [self class], _cmd, deferredSelectObject);
}
}
[super closeView];
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
// NSLog(@"[%@ %s]", [self class], _cmd);
if ([@"currentBranchChange" isEqualToString:context]) {
[sourceView reloadData];
[self selectCurrentBranch];
@@ -223,73 +115,47 @@
[sourceView selectRowIndexes:index byExtendingSelection:NO];
}
- (void) selectBranch:(PBSourceViewItem *)branchItem
{
[sourceView PBExpandItem:branchItem expandParents:YES];
NSInteger row = [sourceView rowForItem:branchItem];
// NSLog(@"[%@ %s] rowForItem (%@) = %d", [self class], _cmd, branchItem, row);
NSIndexSet *index = [NSIndexSet indexSetWithIndex:row];
[sourceView selectRowIndexes:index byExtendingSelection:NO];
}
- (PBSourceViewItem *) itemForRev:(PBGitRevSpecifier *)rev {
PBSourceViewItem *foundItem = nil;
for (PBSourceViewItem *item in items) {
if (foundItem = [item findRev:rev]) {
//NSLog(@"[%@ %s]: found item! Item = %@ for rev = %@", [self class], _cmd, item, rev);
return foundItem;
}
}
return nil;
}
- (BOOL) selectCommitWithSha:(NSString *)refSHA {
NSArray *revList = repository.revisionList.commits;
// NSLog(@"[%@ %s] revList = %@", [self class], _cmd, revList);
for (PBGitCommit *commit in revList) {
// NSLog(@"[%@ %s] commit = %@", [self class], _cmd, commit);
if ([[commit realSha] isEqualToString:refSHA]) {
[historyViewController selectCommit:refSHA];
return YES;
}
}
return NO;
}
- (void) selectCurrentBranch
{
PBGitRevSpecifier *rev = repository.currentBranch;
// NSLog(@"[%@ %s] rev = %@", [self class], _cmd, rev);
if (deferredSelectObject) {
NSString * sha = [ApplicationController sharedApplicationController].deferredSelectSha;
if (!sha) {
sha = [repository shaForRef:[deferredSelectObject.revSpecifier ref]];
}
[self selectBranch:deferredSelectObject];
deferredSelectObject = nil;
return;
}
if (!rev) {
[repository reloadRefs];
[repository readCurrentBranch];
return;
}
PBSourceViewItem *item = [self itemForRev:rev];
[self selectBranch:item];
if (!rev) {
[repository reloadRefs];
[repository readCurrentBranch];
return;
}
PBSourceViewItem *item = nil;
for (PBSourceViewItem *it in items)
if ( (item = [it findRev:rev]) != nil )
break;
if (!item) {
[self addRevSpec:rev];
// Try to find the just added item again.
// TODO: refactor with above.
for (PBSourceViewItem *it in items)
if ( (item = [it findRev:rev]) != nil )
break;
}
[sourceView PBExpandItem:item expandParents:YES];
NSIndexSet *index = [NSIndexSet indexSetWithIndex:[sourceView rowForItem:item]];
[sourceView selectRowIndexes:index byExtendingSelection:NO];
}
- (PBSourceViewItem *) itemForRev:(PBGitRevSpecifier *)rev
{
PBSourceViewItem *foundItem = nil;
for (PBSourceViewItem *item in items)
if ( (foundItem = [item findRev:rev]) != nil )
return foundItem;
return nil;
}
- (void)addRevSpec:(PBGitRevSpecifier *)rev
{
if (![rev isSimpleRef]) {
NSLog(@"[%@ %s]: rev = %@", [self class], _cmd, rev);
[others addChild:[PBSourceViewItem itemWithRevSpec:rev]];
[sourceView reloadData];
return;
@@ -319,6 +185,11 @@
[sourceView reloadData];
}
- (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode
{
[historyViewController.searchController setHistorySearch:searchString mode:mode];
}
#pragma mark NSOutlineView delegate methods
- (void)outlineViewSelectionDidChange:(NSNotification *)notification
@@ -339,7 +210,7 @@
}
[self updateActionMenu];
[historyViewController updateRemoteControls:[[self selectedItem] ref]];
[self updateRemoteControls];
}
#pragma mark NSOutlineView delegate methods
@@ -369,6 +240,36 @@
return ![item isUncollapsible];
}
- (void)populateList
{
PBSourceViewItem *project = [PBSourceViewItem groupItemWithTitle:[repository projectName]];
project.isUncollapsible = YES;
stage = [PBGitSVStageItem stageItem];
[project addChild:stage];
branches = [PBSourceViewItem groupItemWithTitle:@"Branches"];
remotes = [PBSourceViewItem groupItemWithTitle:@"Remotes"];
tags = [PBSourceViewItem groupItemWithTitle:@"Tags"];
others = [PBSourceViewItem groupItemWithTitle:@"Other"];
for (PBGitRevSpecifier *rev in repository.branches)
[self addRevSpec:rev];
[items addObject:project];
[items addObject:branches];
[items addObject:remotes];
[items addObject:tags];
[items addObject:others];
[sourceView reloadData];
[sourceView expandItem:project];
[sourceView expandItem:branches expandChildren:YES];
[sourceView expandItem:remotes];
[sourceView reloadItem:nil reloadChildren:YES];
}
#pragma mark NSOutlineView Datasource methods
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
@@ -449,4 +350,63 @@
[self addMenuItemsForRef:ref toMenu:menu];
}
#pragma mark Remote controls
enum {
kAddRemoteSegment = 0,
kFetchSegment,
kPullSegment,
kPushSegment
};
- (void) updateRemoteControls
{
BOOL hasRemote = NO;
PBGitRef *ref = [[self selectedItem] ref];
if ([ref isRemote] || ([ref isBranch] && [[repository remoteRefForBranch:ref error:NULL] remoteName]))
hasRemote = YES;
[remoteControls setEnabled:hasRemote forSegment:kFetchSegment];
[remoteControls setEnabled:hasRemote forSegment:kPullSegment];
[remoteControls setEnabled:hasRemote forSegment:kPushSegment];
}
- (IBAction) fetchPullPushAction:(id)sender
{
NSInteger selectedSegment = [sender selectedSegment];
if (selectedSegment == kAddRemoteSegment) {
[PBAddRemoteSheet beginAddRemoteSheetForRepository:repository];
return;
}
NSInteger index = [sourceView selectedRow];
PBSourceViewItem *item = [sourceView itemAtRow:index];
PBGitRef *ref = [[item revSpecifier] ref];
if (!ref && (item.parent == remotes))
ref = [PBGitRef refFromString:[kGitXRemoteRefPrefix stringByAppendingString:[item title]]];
if (![ref isRemote] && ![ref isBranch])
return;
PBGitRef *remoteRef = [repository remoteRefForBranch:ref error:NULL];
if (!remoteRef)
return;
if (selectedSegment == kFetchSegment)
[repository beginFetchFromRemoteForRef:ref];
else if (selectedSegment == kPullSegment)
[repository beginPullFromRemote:remoteRef forRef:ref];
else if (selectedSegment == kPushSegment) {
if ([ref isRemote])
[historyViewController.refController showConfirmPushRefSheet:nil remote:remoteRef];
else if ([ref isBranch])
[historyViewController.refController showConfirmPushRefSheet:ref remote:remoteRef];
}
}
@end
+124 -68
View File
@@ -3,15 +3,16 @@
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10C540</string>
<string key="IBDocument.InterfaceBuilderVersion">740</string>
<string key="IBDocument.InterfaceBuilderVersion">759</string>
<string key="IBDocument.AppKitVersion">1038.25</string>
<string key="IBDocument.HIToolboxVersion">458.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">740</string>
<string key="NS.object.0">759</string>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="38"/>
<integer value="36"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
@@ -81,7 +82,7 @@
</object>
<object class="NSColor" key="NSBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC4zMzMzMzI5ODU2AA</bytes>
<bytes key="NSWhite">MC4zMzMzMzI5OQA</bytes>
</object>
<object class="NSColor" key="NSTextColor">
<int key="NSColorSpace">6</int>
@@ -109,7 +110,7 @@
<string key="NSColorName">controlBackgroundColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2ODY1AA</bytes>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor">
@@ -172,7 +173,7 @@
<reference key="NSSuperview" ref="631607481"/>
<reference key="NSTarget" ref="631607481"/>
<string key="NSAction">_doScroller:</string>
<double key="NSPercent">0.99698787927627563</double>
<double key="NSPercent">0.99698790000000004</double>
</object>
<object class="NSScroller" id="46429660">
<reference key="NSNextResponder" ref="631607481"/>
@@ -182,7 +183,7 @@
<int key="NSsFlags">1</int>
<reference key="NSTarget" ref="631607481"/>
<string key="NSAction">_doScroller:</string>
<double key="NSPercent">0.57142859697341919</double>
<double key="NSPercent">0.57142859999999995</double>
</object>
</object>
<string key="NSFrameSize">{153, 354}</string>
@@ -200,10 +201,74 @@
<string key="NSClassName">NSView</string>
</object>
<object class="NSCustomView" id="790712736">
<nil key="NSNextResponder"/>
<reference key="NSNextResponder"/>
<int key="NSvFlags">268</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSSegmentedControl" id="200965348">
<reference key="NSNextResponder" ref="790712736"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{52, 2}, {141, 25}}</string>
<reference key="NSSuperview" ref="790712736"/>
<bool key="NSEnabled">YES</bool>
<object class="NSSegmentedCell" key="NSCell" id="431684212">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">0</int>
<object class="NSFont" key="NSSupport">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">13</double>
<int key="NSfFlags">16</int>
</object>
<reference key="NSControlView" ref="200965348"/>
<object class="NSMutableArray" key="NSSegmentImages">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSSegmentItem">
<double key="NSSegmentItemWidth">33</double>
<object class="NSCustomResource" key="NSSegmentItemImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">AddRemote</string>
</object>
<string key="NSSegmentItemLabel"/>
<string key="NSSegmentItemTooltip">Add remote</string>
<int key="NSSegmentItemImageScaling">0</int>
</object>
<object class="NSSegmentItem">
<double key="NSSegmentItemWidth">33</double>
<object class="NSCustomResource" key="NSSegmentItemImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">FetchTemplate</string>
</object>
<string key="NSSegmentItemLabel"/>
<string key="NSSegmentItemTooltip">Fetch from default remote</string>
<int key="NSSegmentItemTag">1</int>
<int key="NSSegmentItemImageScaling">0</int>
</object>
<object class="NSSegmentItem">
<double key="NSSegmentItemWidth">33</double>
<object class="NSCustomResource" key="NSSegmentItemImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">PullTemplate</string>
</object>
<string key="NSSegmentItemTooltip">Pull from default remote</string>
<int key="NSSegmentItemTag">2</int>
<int key="NSSegmentItemImageScaling">0</int>
</object>
<object class="NSSegmentItem">
<double key="NSSegmentItemWidth">33</double>
<object class="NSCustomResource" key="NSSegmentItemImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">PushTemplate</string>
</object>
<string key="NSSegmentItemTooltip">Push to default remote</string>
<int key="NSSegmentItemTag">3</int>
<int key="NSSegmentItemImageScaling">0</int>
</object>
</object>
<int key="NSSelectedSegment">1</int>
<int key="NSTrackingMode">2</int>
<int key="NSSegmentStyle">2</int>
</object>
</object>
<object class="NSPopUpButton" id="962175484">
<reference key="NSNextResponder" ref="790712736"/>
<int key="NSvFlags">268</int>
@@ -289,6 +354,7 @@
</object>
</object>
<string key="NSFrameSize">{200, 31}</string>
<reference key="NSSuperview"/>
<string key="NSClassName">NSView</string>
</object>
</object>
@@ -343,6 +409,22 @@
</object>
<int key="connectionID">46</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">remoteControls</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="200965348"/>
</object>
<int key="connectionID">49</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">fetchPullPushAction:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="200965348"/>
</object>
<int key="connectionID">50</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
@@ -439,6 +521,7 @@
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="962175484"/>
<reference ref="200965348"/>
</object>
<reference key="parent" ref="0"/>
<string key="objectName">Source List Controls View</string>
@@ -487,6 +570,20 @@
<reference key="object" ref="84422544"/>
<reference key="parent" ref="137688401"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">47</int>
<reference key="object" ref="200965348"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="431684212"/>
</object>
<reference key="parent" ref="790712736"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">48</int>
<reference key="object" ref="431684212"/>
<reference key="parent" ref="200965348"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -509,6 +606,9 @@
<string>42.IBPluginDependency</string>
<string>43.IBPluginDependency</string>
<string>44.IBPluginDependency</string>
<string>47.IBPluginDependency</string>
<string>48.IBPluginDependency</string>
<string>48.IBSegmentedControlInspectorSelectedSegmentMetadataKey</string>
<string>8.IBEditorWindowLastContentRect</string>
<string>8.IBPluginDependency</string>
<string>9.IBPluginDependency</string>
@@ -523,7 +623,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{482, 590}, {153, 354}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{695, 521}, {200, 31}}</string>
<string>{{626, 507}, {200, 31}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -531,6 +631,9 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="0"/>
<string>{{105, 545}, {153, 354}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -557,13 +660,6 @@
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">BMScript.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSOutlineView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -621,10 +717,6 @@
<object class="IBPartialClassDescription">
<string key="className">PBViewController</string>
<string key="superclassName">NSViewController</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">refresh:</string>
<string key="NS.object.0">id</string>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">PBViewController.h</string>
@@ -992,55 +1084,6 @@
<string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">ImageKit.framework/Headers/IKImageBrowserView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">ImageKit.framework/Headers/ImageKitDeprecated.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">PDFKit.framework/Headers/PDFDocument.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">PDFKit.framework/Headers/PDFView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzComposer.framework/Headers/QCCompositionParameterView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzComposer.framework/Headers/QCCompositionPickerView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzFilters.framework/Headers/QuartzFilterManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -1177,6 +1220,14 @@
<string key="minorKey">AppKit.framework/Headers/NSScroller.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSSegmentedCell</string>
<string key="superclassName">NSActionCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSSegmentedCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSSegmentedControl</string>
<string key="superclassName">NSControl</string>
@@ -1266,6 +1317,7 @@
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1050" key="NS.object.0"/>
@@ -1281,5 +1333,9 @@
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<string key="IBDocument.LastKnownRelativeProjectPath">GitX.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="NS.key.0">NSActionTemplate</string>
<string key="NS.object.0">{15, 15}</string>
</object>
</data>
</archive>
+4 -12
View File
@@ -7,11 +7,9 @@
//
#import <Cocoa/Cocoa.h>
#import <Quartz/Quartz.h>
#import "PBGitRepository.h"
@interface PBGitTree : NSObject {
long long _fileSize;
NSString* sha;
@@ -23,14 +21,14 @@
NSString* localFileName;
NSDate* localMtime;
NSString * absolutePath;
NSImage * iconImage;
}
+ (PBGitTree*) rootForCommit: (id) commit;
+ (PBGitTree*) treeForTree: (PBGitTree*) tree andPath: (NSString*) path;
- (void) saveToFolder: (NSString *) directory;
- (NSString *)textContents;
- (NSString *)blame;
- (NSString *) log:(NSString *)format;
- (NSString*) tmpFileNameForContents;
- (long long)fileSize;
@@ -38,17 +36,11 @@
@property(copy) NSString* sha;
@property(copy) NSString* path;
@property(assign) BOOL leaf;
@property(assign) BOOL onlyCommit;
@property(retain) PBGitRepository* repository;
@property(assign) __weak PBGitTree* parent;
@property(readonly) NSArray* children;
@property(readonly) NSString* fullPath;
@property(readonly) NSString* contents;
- (NSString*) contents:(NSInteger)option;
+(NSString *)parseBlame:(NSString *)blame;
@property (copy) NSString *absolutePath;
@property (retain) NSImage *iconImage;
@end
+47 -108
View File
@@ -14,7 +14,7 @@
@implementation PBGitTree
@synthesize sha, path, repository, leaf, parent, iconImage, absolutePath, onlyCommit;
@synthesize sha, path, repository, leaf, parent;
+ (PBGitTree*) rootForCommit:(id) commit
{
@@ -38,15 +38,11 @@
return tree;
}
- (id) init
- init
{
if (self = [super init]) {
children = nil;
localFileName = nil;
leaf = YES;
absolutePath = [PBGitRepository basePath];
}
onlyCommit=true;
children = nil;
localFileName = nil;
leaf = YES;
return self;
}
@@ -69,10 +65,12 @@
- (BOOL)hasBinaryHeader:(NSString*)contents
{
if(!contents)
if (!contents)
return NO;
return [contents rangeOfString:@"\0" options:0 range:NSMakeRange(0, ([contents length] >= 8000) ? 7999 : [contents length])].location != NSNotFound;
return [contents rangeOfString:@"\0"
options:0
range:NSMakeRange(0, ([contents length] >= 8000) ? 7999 : [contents length])].location != NSNotFound;
}
- (BOOL)hasBinaryAttributes
@@ -105,7 +103,7 @@
{
if (!leaf)
return [NSString stringWithFormat:@"This is a tree with path %@", [self fullPath]];
if ([self isLocallyCached]) {
NSData *data = [NSData dataWithContentsOfFile:localFileName];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
@@ -114,15 +112,11 @@
return string;
}
//return [repository outputForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
return [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"blame", self.path, nil]];
return [repository outputForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
}
// XXX: create img tag for images.
- (NSString*) contents:(NSInteger)option
- (NSString *) blame
{
NSString* contents;
if (!leaf)
return [NSString stringWithFormat:@"This is a tree with path %@", [self fullPath]];
@@ -132,9 +126,32 @@
if ([self fileSize] > 52428800) // ~50MB
return [NSString stringWithFormat:@"%@ is too big to be displayed (%d bytes)", [self fullPath], [self fileSize]];
NSString *contents=[repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"blame", @"-p", sha, @"--", [self fullPath], nil]];
if ([self hasBinaryHeader:contents])
return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], [self fileSize]];
return contents;
}
- (NSString *) log:(NSString *)format
{
if (!leaf)
return [NSString stringWithFormat:@"This is a tree with path %@", [self fullPath]];
if ([self hasBinaryAttributes])
return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], [self fileSize]];
if ([self fileSize] > 52428800) // ~50MB
return [NSString stringWithFormat:@"%@ is too big to be displayed (%d bytes)", [self fullPath], [self fileSize]];
NSString *contents=[repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"log", [NSString stringWithFormat:@"--pretty=format:%@",format], @"--", [self fullPath], nil]];
if ([self hasBinaryHeader:contents])
return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], [self fileSize]];
return contents;
}
@@ -182,7 +199,7 @@
NSData* data = [handle readDataToEndOfFile];
[data writeToFile:newName atomically:YES];
} else { // Directory
[[NSFileManager defaultManager] createDirectoryAtPath:newName withIntermediateDirectories:YES attributes:nil error:nil];
[[NSFileManager defaultManager] createDirectoryAtPath:newName attributes:nil];
for (PBGitTree* child in [self children])
[child saveToFolder: newName];
}
@@ -231,28 +248,19 @@
if (children != nil)
return children;
NSString* ref = [self refSpec];
NSFileHandle* handle;
if(onlyCommit){
handle = [repository handleForArguments:[NSArray arrayWithObjects:@"show",@"--pretty=format:",@"--name-only", self.sha,nil]];
}else{
NSString* ref = [self refSpec];
handle = [repository handleForArguments:[NSArray arrayWithObjects:@"show", ref, nil]];
[handle readLine];
}
NSFileHandle* handle = [repository handleForArguments:[NSArray arrayWithObjects:@"show", ref, nil]];
[handle readLine];
[handle readLine];
NSMutableArray* c = [NSMutableArray array];
NSString* p = [handle readLine];
while ([p length] > 0) {
if ([p isEqualToString:@"\r"])
break;
while (p.length > 0) {
BOOL isLeaf = ([p characterAtIndex:p.length - 1] != '/');
if (!isLeaf)
p = [p substringToIndex:[p length]-1];
p = [p substringToIndex:p.length -1];
PBGitTree* child = [PBGitTree treeForTree:self andPath:p];
child.leaf = isLeaf;
@@ -269,85 +277,16 @@
if (!parent)
return @"";
if ([[parent fullPath] isEqualToString:@""])
if ([parent.fullPath isEqualToString:@""])
return self.path;
return [[parent fullPath] stringByAppendingPathComponent: self.path];
return [parent.fullPath stringByAppendingPathComponent: self.path];
}
// !!! Andre Berg 20100324: finalize seldomly causes the following error message:
// malloc: resurrection error for object 0x12b1110 while assigning NSFilesystemItemRemoveOperation._removePath[32](0x12a0170)[16] = NSPathStore2[240](0x12b1110)
// garbage pointer stored into reachable memory, break on auto_zone_resurrection_error to debug
// objc[40604]: **resurrected** object 0x12b1110 of class NSPathStore2 being finalized
// - (void) finalize
// {
// if (localFileName)
// [[NSFileManager defaultManager] removeItemAtPath:localFileName error:nil];
// [super finalize];
// }
+(NSString *)parseBlame:(NSString *)string
- (void) finalize
{
string=[string stringByReplacingOccurrencesOfString:@"<" withString:@"&lt;"];
string=[string stringByReplacingOccurrencesOfString:@">" withString:@"&gt;"];
NSArray *lines = [string componentsSeparatedByString:@"\n"];
NSString *line;
NSMutableDictionary *headers=[NSMutableDictionary dictionary];
NSMutableString *res=[NSMutableString string];
[res appendString:@"<table class='blocks'>\n"];
int i=0;
while(i<[lines count]){
line=[lines objectAtIndex:i];
NSArray *header=[line componentsSeparatedByString:@" "];
if([header count]==4){
int nLines=[(NSString *)[header objectAtIndex:3] intValue];
[res appendFormat:@"<tr class='block l%d'>\n",nLines];
line=[lines objectAtIndex:++i];
if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"author"]){
NSString *author=line;
NSString *summary=nil;
while(summary==nil){
line=[lines objectAtIndex:i++];
if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"summary"]){
summary=line;
}
}
NSString *block=[NSString stringWithFormat:@"<td><p class='author'>%@</p><p class='summary'>%@</p></td>\n<td>\n",author,summary];
[headers setObject:block forKey:[header objectAtIndex:0]];
}
[res appendString:[headers objectForKey:[header objectAtIndex:0]]];
NSMutableString *code=[NSMutableString string];
do{
line=[lines objectAtIndex:i++];
}while([line characterAtIndex:0]!='\t');
line=[line stringByReplacingOccurrencesOfString:@"\t" withString:@"&nbsp;&nbsp;&nbsp;&nbsp;"];
[code appendString:line];
[code appendString:@"\n"];
int n;
for(n=1;n<nLines;n++){
line=[lines objectAtIndex:i++];
NSArray *h=[line componentsSeparatedByString:@" "];
do{
line=[lines objectAtIndex:i++];
}while([line characterAtIndex:0]!='\t');
line=[line stringByReplacingOccurrencesOfString:@"\t" withString:@"&nbsp;&nbsp;&nbsp;&nbsp;"];
[code appendString:line];
[code appendString:@"\n"];
}
[res appendFormat:@"<pre class='first-line: %@;brush: objc'>%@</pre>",[header objectAtIndex:2],code];
[res appendString:@"</td>\n"];
}else{
break;
}
[res appendString:@"</tr>\n"];
}
[res appendString:@"</table>\n"];
//NSLog(@"%@",res);
return (NSString *)res;
if (localFileName)
[[NSFileManager defaultManager] removeFileAtPath:localFileName handler:nil];
[super finalize];
}
@end
+10 -10
View File
@@ -9,16 +9,14 @@
#import <Cocoa/Cocoa.h>
#import "PBGitRepository.h"
@class PBViewController, PBGitSidebarController, PBGitHistoryController;
@class PBViewController, PBGitSidebarController, PBGitCommitController;
@interface PBGitWindowController : NSWindowController <NSWindowDelegate> {
@interface PBGitWindowController : NSWindowController {
__weak PBGitRepository* repository;
__weak PBViewController *contentController;
__weak PBViewController* viewController;
__weak PBGitSidebarController *sidebarController;
__weak PBGitHistoryController *historyController;
PBViewController *contentController;
PBGitSidebarController *sidebarController;
IBOutlet NSView *sourceListControlsView;
IBOutlet NSSplitView *splitView;
IBOutlet NSView *sourceSplitView;
@@ -27,20 +25,19 @@
IBOutlet NSTextField *statusField;
IBOutlet NSProgressIndicator *progressIndicator;
PBViewController* viewController;
IBOutlet NSToolbarItem *terminalItem;
IBOutlet NSToolbarItem *finderItem;
}
@property (assign) __weak PBGitRepository *repository;
@property (assign) __weak PBViewController * viewController;
@property (assign) __weak PBViewController * contentController;
@property (assign) __weak PBGitSidebarController * sidebarController;
@property (assign) __weak PBGitHistoryController * historyController;
- (id)initWithRepository:(PBGitRepository*)theRepository displayDefault:(BOOL)display;
- (void)changeContentController:(PBViewController *)controller;
- (void)showCommitHookFailedSheet:(NSString *)messageText infoText:(NSString *)infoText commitController:(PBGitCommitController *)controller;
- (void)showMessageSheet:(NSString *)messageText infoText:(NSString *)infoText;
- (void)showErrorSheet:(NSError *)error;
- (void)showErrorSheetTitle:(NSString *)title message:(NSString *)message arguments:(NSArray *)arguments output:(NSString *)output;
@@ -51,4 +48,7 @@
- (IBAction) openInTerminal:(id)sender;
- (IBAction) cloneTo:(id)sender;
- (IBAction) refresh:(id)sender;
- (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode;
@end
+23 -26
View File
@@ -9,19 +9,16 @@
#import "PBGitWindowController.h"
#import "PBGitHistoryController.h"
#import "PBGitCommitController.h"
#import "PBGitDefaults.h"
#import "Terminal.h"
#import "PBCloneRepsitoryToSheet.h"
#import "PBCommitHookFailedSheet.h"
#import "PBGitXMessageSheet.h"
#import "PBGitSidebarController.h"
#import "NSString_Truncate.h"
@implementation PBGitWindowController
@synthesize repository;
@synthesize viewController;
@synthesize contentController;
@synthesize sidebarController;
@synthesize historyController;
- (id)initWithRepository:(PBGitRepository*)theRepository displayDefault:(BOOL)displayDefault
{
@@ -35,10 +32,13 @@
- (void)windowWillClose:(NSNotification *)notification
{
//NSLog(@"Window will close!");
NSLog(@"Window will close!");
if (sidebarController)
[sidebarController removeView];
[sidebarController closeView];
if (contentController)
[contentController removeObserver:self forKeyPath:@"status"];
}
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
@@ -110,30 +110,22 @@
[sidebarController selectCurrentBranch];
}
- (void)showCommitHookFailedSheet:(NSString *)messageText infoText:(NSString *)infoText commitController:(PBGitCommitController *)controller
{
[PBCommitHookFailedSheet beginMessageSheetForWindow:[self window] withMessageText:messageText infoText:infoText commitController:controller];
}
- (void)showMessageSheet:(NSString *)messageText infoText:(NSString *)infoText
{
if ([PBGitDefaults truncateInfoText] && ([infoText length] > [PBGitDefaults truncateInfoTextSize])) {
infoText = [infoText truncateToLength:[PBGitDefaults truncateInfoTextSize] mode:PBNSStringTruncateModeCenter indicator:@" ... "];
}
[[NSAlert alertWithMessageText:messageText
defaultButton:nil
alternateButton:nil
otherButton:nil
informativeTextWithFormat:infoText] beginSheetModalForWindow: [self window] modalDelegate:self didEndSelector:nil contextInfo:nil];
[PBGitXMessageSheet beginMessageSheetForWindow:[self window] withMessageText:messageText infoText:infoText];
}
- (void)showErrorSheet:(NSError *)error
{
[[NSAlert alertWithError:error] beginSheetModalForWindow: [self window] modalDelegate:self didEndSelector:nil contextInfo:nil];
}
- (void)windowDidBecomeMain:(NSNotification *)notification {
/* Using ...didBecomeMain is better than ...didBecomeKey here because the QuickLook panel will count as key state change
and the outline view window will trigger a refresh in the middle of the QuickLook panel's closing animation which
causes a half second freeze with left over artifacts. */
if (self.contentController && [PBGitDefaults refreshAutomatically]) {
[self.contentController refresh:nil];
}
if ([[error domain] isEqualToString:PBGitRepositoryErrorDomain])
[PBGitXMessageSheet beginMessageSheetForWindow:[self window] withError:error];
else
[[NSAlert alertWithError:error] beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:nil contextInfo:nil];
}
- (void)showErrorSheetTitle:(NSString *)title message:(NSString *)message arguments:(NSArray *)arguments output:(NSString *)output
@@ -205,6 +197,11 @@
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
- (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode
{
[sidebarController setHistorySearch:searchString mode:mode];
}
#pragma mark -
+33
View File
@@ -0,0 +1,33 @@
//
// PBGitXMessageSheet.h
// GitX
//
// Created by BrotherBard on 7/4/10.
// Copyright 2010 BrotherBard. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface PBGitXMessageSheet : NSWindowController
{
NSImageView *iconView;
NSTextField *messageField;
NSTextView *infoView;
NSScrollView *scrollView;
}
+ (void)beginMessageSheetForWindow:(NSWindow *)parentWindow withMessageText:(NSString *)message infoText:(NSString *)info;
+ (void)beginMessageSheetForWindow:(NSWindow *)parentWindow withError:(NSError *)error;
- (void)beginMessageSheetForWindow:(NSWindow *)parentWindow withMessageText:(NSString *)message infoText:(NSString *)info;
- (IBAction)closeMessageSheet:(id)sender;
@property (assign) IBOutlet NSImageView *iconView;
@property (assign) IBOutlet NSTextField *messageField;
@property (assign) IBOutlet NSTextView *infoView;
@property (assign) IBOutlet NSScrollView *scrollView;
@end
+122
View File
@@ -0,0 +1,122 @@
//
// PBGitXMessageSheet.m
// GitX
//
// Created by BrotherBard on 7/4/10.
// Copyright 2010 BrotherBard. All rights reserved.
//
#import "PBGitXMessageSheet.h"
#define MaxScrollViewHeight 125.0f
@interface PBGitXMessageSheet ()
- (void)setInfoString:(NSString *)info;
- (void)resizeWindow;
@end
@implementation PBGitXMessageSheet
@synthesize iconView;
@synthesize messageField;
@synthesize infoView;
@synthesize scrollView;
#pragma mark -
#pragma mark PBGitXMessageSheet
+ (void)beginMessageSheetForWindow:(NSWindow *)parentWindow withMessageText:(NSString *)message infoText:(NSString *)info
{
PBGitXMessageSheet *sheet = [[self alloc] initWithWindowNibName:@"PBGitXMessageSheet"];
[sheet beginMessageSheetForWindow:parentWindow withMessageText:message infoText:info];
}
+ (void)beginMessageSheetForWindow:(NSWindow *)parentWindow withError:(NSError *)error
{
PBGitXMessageSheet *sheet = [[self alloc] initWithWindowNibName:@"PBGitXMessageSheet"];
[sheet beginMessageSheetForWindow:parentWindow withMessageText:[error localizedDescription] infoText:[error localizedRecoverySuggestion]];
}
- (IBAction)closeMessageSheet:(id)sender
{
[NSApp endSheet:[self window]];
[[self window] orderOut:self];
}
#pragma mark Private
- (void)beginMessageSheetForWindow:(NSWindow *)parentWindow withMessageText:(NSString *)message infoText:(NSString *)info;
{
[self window];
[self.messageField setStringValue:message];
[self setInfoString:info];
[self resizeWindow];
[NSApp beginSheet:[self window] modalForWindow:parentWindow modalDelegate:self didEndSelector:nil contextInfo:NULL];
}
- (void)setInfoString:(NSString *)info
{
NSDictionary *attributes = [NSDictionary dictionaryWithObject:[NSFont labelFontOfSize:[NSFont smallSystemFontSize]]
forKey:NSFontAttributeName];
NSAttributedString *attributedInfoString = [[NSAttributedString alloc] initWithString:info attributes:attributes];
[[self.infoView textStorage] setAttributedString:attributedInfoString];
}
- (void)resizeWindow
{
// resize for message text
NSRect messageFrame = [self.messageField frame];
NSSize boundingSize = messageFrame.size;
boundingSize.height = 0.0f;
NSAttributedString *attributedTitle = [self.messageField attributedStringValue];
NSRect boundingRect = [attributedTitle boundingRectWithSize:boundingSize options:NSStringDrawingUsesLineFragmentOrigin];
CGFloat heightDelta = boundingRect.size.height - messageFrame.size.height;
if (heightDelta > 0.0f) {
messageFrame.size.height += heightDelta;
messageFrame.origin.y -= heightDelta;
[self.messageField setFrame:messageFrame];
NSRect scrollFrame = [self.scrollView frame];
scrollFrame.size.height -= heightDelta;
[self.scrollView setFrame:scrollFrame];
NSRect windowFrame = [[self window] frame];
windowFrame.size.height += heightDelta;
[[self window] setFrame:windowFrame display:NO];
}
// resize for info text
NSRect scrollFrame = [self.scrollView frame];
boundingSize = [self.scrollView bounds].size;
boundingSize.height = 0.0f;
NSAttributedString *attributedInfo = [[self.infoView layoutManager] attributedString];
boundingRect = [attributedInfo boundingRectWithSize:boundingSize options:NSStringDrawingUsesLineFragmentOrigin];
heightDelta = boundingRect.size.height - scrollFrame.size.height;
if (heightDelta > MaxScrollViewHeight)
heightDelta = MaxScrollViewHeight;
if (heightDelta > 0.0f) {
NSRect windowFrame = [[self window] frame];
windowFrame.size.height += heightDelta;
[[self window] setFrame:windowFrame display:NO];
}
[self.infoView scrollRangeToVisible:NSMakeRange(0, 0)];
}
@end
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -18,7 +18,7 @@
char sign;
}
@property(readonly) struct PBGitGraphLine *lines;
@property(assign) struct PBGitGraphLine *lines;
@property(assign) int nLines;
@property(assign) int position, numColumns;
@property(assign) char sign;
+6
View File
@@ -19,6 +19,12 @@
return self;
}
- (void)setLines:(struct PBGitGraphLine *)l
{
free(lines);
lines = l;
}
-(void) finalize
{
free(lines);
+66
View File
@@ -0,0 +1,66 @@
//
// PBHistorySearchController.h
// GitX
//
// Created by Nathan Kinsinger on 8/21/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import <Cocoa/Cocoa.h>
typedef enum historySearchModes {
kGitXBasicSeachMode = 1,
kGitXPickaxeSearchMode,
kGitXRegexSearchMode,
kGitXPathSearchMode,
kGitXMaxSearchMode // always keep this item last
} PBHistorySearchMode;
@class PBGitHistoryController;
@interface PBHistorySearchController : NSObject {
PBGitHistoryController *historyController;
NSArrayController *commitController;
PBHistorySearchMode searchMode;
NSIndexSet *results;
NSSearchField *searchField;
NSSegmentedControl *stepper;
NSTextField *numberOfMatchesField;
NSProgressIndicator *progressIndicator;
NSTimer *searchTimer;
NSTask *backgroundSearchTask;
NSPanel *rewindPanel;
}
@property (assign) IBOutlet PBGitHistoryController *historyController;
@property (assign) IBOutlet NSArrayController *commitController;
@property (assign) IBOutlet NSSearchField *searchField;
@property (assign) IBOutlet NSSegmentedControl *stepper;
@property (assign) IBOutlet NSTextField *numberOfMatchesField;
@property (assign) IBOutlet NSProgressIndicator *progressIndicator;
@property (assign) PBHistorySearchMode searchMode;
- (BOOL)isRowInSearchResults:(NSInteger)rowIndex;
- (BOOL)hasSearchResults;
- (void)selectSearchMode:(id)sender;
- (void)selectNextResult;
- (void)selectPreviousResult;
- (IBAction)stepperPressed:(id)sender;
- (void)clearSearch;
- (IBAction)updateSearch:(id)sender;
- (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode;
@end
+544
View File
@@ -0,0 +1,544 @@
//
// PBHistorySearchController.m
// GitX
//
// Created by Nathan Kinsinger on 8/21/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import "PBHistorySearchController.h"
#import "PBGitHistoryController.h"
#import "PBGitRepository.h"
#import "PBGitDefaults.h"
#import <QuartzCore/CoreAnimation.h>
@interface PBHistorySearchController ()
- (void)selectNextResultInDirection:(NSInteger)direction;
- (void)updateUI;
- (void)setupSearchMenuTemplate;
- (void)startBasicSearch;
- (void)startBackgroundSearch;
- (void)clearProgressIndicator;
- (void)showSearchRewindPanelReverse:(BOOL)isReversed;
@end
#define kGitXSearchDirectionNext 1
#define kGitXSearchDirectionPrevious -1
#define kGitXBasicSearchLabel @"Subject, Author, SHA"
#define kGitXPickaxeSearchLabel @"Commit (pickaxe)"
#define kGitXRegexSearchLabel @"Commit (pickaxe regex)"
#define kGitXPathSearchLabel @"File path"
#define kGitXSearchArrangedObjectsContext @"GitXSearchArrangedObjectsContext"
@implementation PBHistorySearchController
@synthesize historyController;
@synthesize commitController;
@synthesize searchField;
@synthesize stepper;
@synthesize numberOfMatchesField;
@synthesize progressIndicator;
@synthesize searchMode;
#pragma mark -
#pragma mark Public methods
- (BOOL)isRowInSearchResults:(NSInteger)rowIndex
{
return [results containsIndex:rowIndex];
}
- (BOOL)hasSearchResults
{
return ([results count] > 0);
}
- (void)selectSearchMode:(id)sender
{
self.searchMode = [sender tag];
[self updateSearch:self];
}
- (void)selectNextResult
{
[self selectNextResultInDirection:kGitXSearchDirectionNext];
}
- (void)selectPreviousResult
{
[self selectNextResultInDirection:kGitXSearchDirectionPrevious];
}
- (IBAction)stepperPressed:(id)sender
{
NSInteger selectedSegment = [sender selectedSegment];
if (selectedSegment == 0)
[self selectPreviousResult];
else
[self selectNextResult];
}
- (void)clearSearch
{
[searchField setStringValue:@""];
if (results) {
results = nil;
[historyController.commitList reloadData];
}
[self updateUI];
}
- (IBAction)updateSearch:(id)sender
{
if (self.searchMode == kGitXBasicSeachMode)
[self startBasicSearch];
else
[self startBackgroundSearch];
}
- (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode
{
if (searchString && ![searchString isEqualToString:@""]) {
self.searchMode = mode;
[searchField setStringValue:searchString];
// use performClick: so that the search field will save it as a recent search
[searchField performClick:self];
}
}
- (void)awakeFromNib
{
[self setupSearchMenuTemplate];
self.searchMode = [PBGitDefaults historySearchMode];
[self updateUI];
[commitController addObserver:self forKeyPath:@"arrangedObjects" options:0 context:kGitXSearchArrangedObjectsContext];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([(NSString *)context isEqualToString:kGitXSearchArrangedObjectsContext]) {
// the objects in the commitlist changed so the result indexes are no longer valid
[self clearSearch];
return;
}
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
#pragma mark -
#pragma mark Private methods
- (void)selectIndex:(NSUInteger)index
{
if ([[commitController arrangedObjects] count] > index) {
PBGitCommit *commit = [[commitController arrangedObjects] objectAtIndex:index];
[historyController selectCommit:[commit sha]];
}
}
- (void)selectNextResultInDirection:(NSInteger)direction
{
if (![results count])
return;
NSUInteger selectedRow = [historyController.commitList selectedRow];
if (selectedRow == NSNotFound) {
[self selectIndex:[results firstIndex]];
return;
}
NSUInteger currentResult = NSNotFound;
if (direction == kGitXSearchDirectionNext)
currentResult = [results indexGreaterThanIndex:selectedRow];
else
currentResult = [results indexLessThanIndex:selectedRow];
if (currentResult == NSNotFound) {
if (direction == kGitXSearchDirectionNext)
currentResult = [results firstIndex];
else
currentResult = [results lastIndex];
[self showSearchRewindPanelReverse:(direction != kGitXSearchDirectionNext)];
}
[self selectIndex:currentResult];
}
- (NSString *)numberOfMatchesString
{
NSUInteger numberOfMatches = [results count];
if (numberOfMatches == 0)
return @"Not found";
if (numberOfMatches == 1)
return @"1 match";
return [NSString stringWithFormat:@"%d matches", numberOfMatches];
}
- (void)updateUI
{
if ([[searchField stringValue] isEqualToString:@""]) {
[numberOfMatchesField setHidden:YES];
[stepper setHidden:YES];
}
else {
[numberOfMatchesField setStringValue:[self numberOfMatchesString]];
[numberOfMatchesField setHidden:NO];
[stepper setHidden:NO];
[historyController.commitList reloadData];
}
[self clearProgressIndicator];
}
// changes the selection to the next match after the current selected row unless the current row is already a match
- (void)updateSelectedResult
{
NSString *searchString = [searchField stringValue];
if ([searchString isEqualToString:@""]) {
[self clearSearch];
return;
}
if (![self isRowInSearchResults:[historyController.commitList selectedRow]])
[self selectNextResult];
[self updateUI];
}
- (void)setupSearchMenuTemplate
{
NSMenu *searchMenu = [[NSMenu alloc] initWithTitle:@"Search Menu"];
NSMenuItem *item;
item = [[NSMenuItem alloc] initWithTitle:kGitXBasicSearchLabel action:@selector(selectSearchMode:) keyEquivalent:@""];
[item setTarget:self];
[item setTag:kGitXBasicSeachMode];
[searchMenu addItem:item];
item = [[NSMenuItem alloc] initWithTitle:kGitXPickaxeSearchLabel action:@selector(selectSearchMode:) keyEquivalent:@""];
[item setTarget:self];
[item setTag:kGitXPickaxeSearchMode];
[searchMenu addItem:item];
item = [[NSMenuItem alloc] initWithTitle:kGitXRegexSearchLabel action:@selector(selectSearchMode:) keyEquivalent:@""];
[item setTarget:self];
[item setTag:kGitXRegexSearchMode];
[searchMenu addItem:item];
item = [[NSMenuItem alloc] initWithTitle:kGitXPathSearchLabel action:@selector(selectSearchMode:) keyEquivalent:@""];
[item setTarget:self];
[item setTag:kGitXPathSearchMode];
[searchMenu addItem:item];
item = [NSMenuItem separatorItem];
[searchMenu addItem:item];
item = [[NSMenuItem alloc] initWithTitle:@"Recent Searches" action:NULL keyEquivalent:@""];
[item setTag:NSSearchFieldRecentsTitleMenuItemTag];
[searchMenu addItem:item];
item = [[NSMenuItem alloc] initWithTitle:@"Recents" action:NULL keyEquivalent:@""];
[item setTag:NSSearchFieldRecentsMenuItemTag];
[searchMenu addItem:item];
item = [NSMenuItem separatorItem];
[item setTag:NSSearchFieldRecentsTitleMenuItemTag];
[searchMenu addItem:item];
item = [[NSMenuItem alloc] initWithTitle:@"Clear Recent Searches" action:NULL keyEquivalent:@""];
[item setTag:NSSearchFieldClearRecentsMenuItemTag];
[searchMenu addItem:item];
item = [[NSMenuItem alloc] initWithTitle:@"No Recent Searches" action:NULL keyEquivalent:@""];
[item setTag:NSSearchFieldNoRecentsMenuItemTag];
[searchMenu addItem:item];
[[searchField cell] setSearchMenuTemplate:searchMenu];
}
- (void)updateSearchMenuState
{
NSMenu *searchMenu = [[searchField cell] searchMenuTemplate];
if (!searchMenu)
return;
NSMenuItem *item;
item = [searchMenu itemWithTag:kGitXBasicSeachMode];
[item setState:(searchMode == kGitXBasicSeachMode) ? NSOnState : NSOffState];
item = [searchMenu itemWithTag:kGitXPickaxeSearchMode];
[item setState:(searchMode == kGitXPickaxeSearchMode) ? NSOnState : NSOffState];
item = [searchMenu itemWithTag:kGitXRegexSearchMode];
[item setState:(searchMode == kGitXRegexSearchMode) ? NSOnState : NSOffState];
item = [searchMenu itemWithTag:kGitXPathSearchMode];
[item setState:(searchMode == kGitXPathSearchMode) ? NSOnState : NSOffState];
[[searchField cell] setSearchMenuTemplate:searchMenu];
[PBGitDefaults setHistorySearchMode:searchMode];
}
- (void)updateSearchPlaceholderString
{
switch (self.searchMode) {
case kGitXPickaxeSearchMode:
[[searchField cell] setPlaceholderString:kGitXPickaxeSearchLabel];
break;
case kGitXRegexSearchMode:
[[searchField cell] setPlaceholderString:kGitXRegexSearchLabel];
break;
case kGitXPathSearchMode:
[[searchField cell] setPlaceholderString:kGitXPathSearchLabel];
break;
default:
[[searchField cell] setPlaceholderString:kGitXBasicSearchLabel];
break;
}
}
- (void)setSearchMode:(PBHistorySearchMode)mode
{
if ((mode < kGitXBasicSeachMode) || (mode >= kGitXMaxSearchMode))
mode = kGitXBasicSeachMode;
searchMode = mode;
[PBGitDefaults setHistorySearchMode:searchMode];
[self updateSearchMenuState];
[self updateSearchPlaceholderString];
}
- (void)searchTimerFired:(NSTimer*)theTimer
{
[self.progressIndicator setHidden:NO];
[self.progressIndicator startAnimation:self];
}
- (void)clearProgressIndicator
{
[searchTimer invalidate];
searchTimer = nil;
[self.progressIndicator setHidden:YES];
[self.progressIndicator stopAnimation:self];
}
- (void)startProgressIndicator
{
[self clearProgressIndicator];
[numberOfMatchesField setHidden:YES];
[stepper setHidden:YES];
searchTimer = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(searchTimerFired:) userInfo:nil repeats:NO];
}
#pragma mark Basic Search
- (void)startBasicSearch
{
NSString *searchString = [searchField stringValue];
if ([searchString isEqualToString:@""]) {
[self clearSearch];
return;
}
NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"subject CONTAINS[cd] %@ OR author CONTAINS[cd] %@ OR realSha BEGINSWITH[c] %@", searchString, searchString, searchString];
NSUInteger index = 0;
for (PBGitCommit *commit in [commitController arrangedObjects]) {
if ([searchPredicate evaluateWithObject:commit])
[indexes addIndex:index];
index++;
}
results = indexes;
[self updateSelectedResult];
}
#pragma mark Background Search
- (void)startBackgroundSearch
{
if (backgroundSearchTask) {
NSFileHandle *handle = [[backgroundSearchTask standardOutput] fileHandleForReading];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSFileHandleReadToEndOfFileCompletionNotification object:handle];
[backgroundSearchTask terminate];
}
NSString *searchString = [[searchField stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([searchString isEqualToString:@""]) {
[self clearSearch];
return;
}
results = nil;
NSMutableArray *searchArguments = [NSMutableArray arrayWithObjects:@"log", @"--pretty=format:%H", nil];
switch (self.searchMode) {
case kGitXRegexSearchMode:
[searchArguments addObject:@"--pickaxe-regex"];
case kGitXPickaxeSearchMode:
[searchArguments addObject:[NSString stringWithFormat:@"-S%@", searchString]];
break;
case kGitXPathSearchMode:
[searchArguments addObject:@"--"];
[searchArguments addObjectsFromArray:[searchString componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
break;
default:
return;
}
backgroundSearchTask = [PBEasyPipe taskForCommand:[PBGitBinary path] withArgs:searchArguments inDir:[[historyController.repository fileURL] path]];
[backgroundSearchTask launch];
NSFileHandle *handle = [[backgroundSearchTask standardOutput] fileHandleForReading];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(parseBackgroundSearchResults:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle];
[handle readToEndOfFileInBackgroundAndNotify];
[self startProgressIndicator];
}
- (void)parseBackgroundSearchResults:(NSNotification *)notification
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSFileHandleReadToEndOfFileCompletionNotification object:[notification object]];
backgroundSearchTask = nil;
NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem];
NSString *resultsString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSArray *resultsArray = [resultsString componentsSeparatedByString:@"\n"];
for (NSString *resultSHA in resultsArray) {
NSUInteger index = 0;
for (PBGitCommit *commit in [commitController arrangedObjects]) {
if ([resultSHA isEqualToString:commit.sha.string]) {
[indexes addIndex:index];
break;
}
index++;
}
}
results = indexes;
[self clearProgressIndicator];
[self updateSelectedResult];
}
#pragma mark -
#pragma mark Rewind Panel
#define kRewindPanelSize 125.0f
- (void)closeRewindPanel
{
[[[historyController view] window] removeChildWindow:rewindPanel];
[rewindPanel close];
rewindPanel = nil;
}
- (NSPanel *)rewindPanelReverse:(BOOL)isReversed
{
NSRect windowFrame = [[[historyController view] window] frame];
NSRect historyFrame = [[historyController view] convertRectToBase:[[historyController view] frame]];
NSRect panelRect = NSMakeRect(0.0f, 0.0f, kRewindPanelSize, kRewindPanelSize);
panelRect.origin.x = windowFrame.origin.x + historyFrame.origin.x + ((historyFrame.size.width - kRewindPanelSize) / 2.0f);
panelRect.origin.y = windowFrame.origin.y + historyFrame.origin.y + ((historyFrame.size.height - kRewindPanelSize) / 2.0f);
NSPanel *panel = [[NSPanel alloc] initWithContentRect:panelRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:YES];
[panel setIgnoresMouseEvents:YES];
[panel setOneShot:YES];
[panel setOpaque:NO];
[panel setBackgroundColor:[NSColor clearColor]];
[panel setHasShadow:NO];
[panel useOptimizedDrawing:YES];
[panel setAlphaValue:0.0f];
NSBox *box = [[NSBox alloc] initWithFrame:[[panel contentView] frame]];
[box setBoxType:NSBoxCustom];
[box setBorderType:NSLineBorder];
[box setFillColor:[NSColor colorWithCalibratedWhite:0.0f alpha:0.5f]];
[box setBorderColor:[NSColor colorWithCalibratedWhite:0.5f alpha:0.5f]];
[box setCornerRadius:12.0f];
[[panel contentView] addSubview:box];
NSImage *rewindImage = [[NSImage imageNamed:@"rewindImage"] copy];
[rewindImage setFlipped:isReversed];
NSSize imageSize = [rewindImage size];
NSRect imageViewFrame = NSMakeRect(21.0f, 5.0f, imageSize.width, imageSize.height);
NSImageView *rewindImageView = [[NSImageView alloc] initWithFrame:imageViewFrame];
[rewindImageView setImage:rewindImage];
[[box contentView] addSubview:rewindImageView];
return panel;
}
- (CAKeyframeAnimation *)rewindPanelFadeOutAnimation
{
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.duration = 1.0f;
animation.values = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:1.0f],
[NSNumber numberWithFloat:1.0f],
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:0.0f], nil];
animation.keyTimes = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.1f],
[NSNumber numberWithFloat:0.3f],
[NSNumber numberWithFloat:0.7f],
[NSNumber numberWithFloat:animation.duration], nil];
return animation;
}
- (void)showSearchRewindPanelReverse:(BOOL)isReversed
{
if (rewindPanel)
[self closeRewindPanel];
rewindPanel = [self rewindPanelReverse:isReversed];
[[[historyController view] window] addChildWindow:rewindPanel ordered:NSWindowAbove];
CAKeyframeAnimation *alphaAnimation = [self rewindPanelFadeOutAnimation];
[rewindPanel setAnimations:[NSDictionary dictionaryWithObject:alphaAnimation forKey:@"alphaValue"]];
[[rewindPanel animator] setAlphaValue:0.0f];
[self performSelector:@selector(closeRewindPanel) withObject:nil afterDelay:0.7f];
}
@end
+5 -8
View File
@@ -62,6 +62,8 @@
[openPanel setAllowsMultipleSelection:NO];
[openPanel setTreatsFilePackagesAsDirectories:YES];
[openPanel setAccessoryView:gitPathOpenAccessory];
[openPanel setResolvesAliases:NO];
//[[openPanel _navView] setShowsHiddenFiles:YES];
gitPathOpenPanel = openPanel;
}
@@ -71,14 +73,9 @@
- (IBAction) showHideAllFiles: sender
{
if ([gitPathOpenPanel respondsToSelector:@selector(setShowsHiddenFiles:)]) {
BOOL showHidden = ([sender state] == NSOnState);
[gitPathOpenPanel setShowsHiddenFiles:showHidden];
} else {
/* FIXME: This uses undocumented OpenPanel features to show hidden files! */
NSNumber *showHidden = [NSNumber numberWithBool:[sender state] == NSOnState];
[[gitPathOpenPanel valueForKey:@"_navView"] setValue:showHidden forKey:@"showsHiddenFiles"];
}
/* FIXME: This uses undocumented OpenPanel features to show hidden files! */
NSNumber *showHidden = [NSNumber numberWithBool:[sender state] == NSOnState];
[[gitPathOpenPanel valueForKey:@"_navView"] setValue:showHidden forKey:@"showsHiddenFiles"];
}
@end
+10 -12
View File
@@ -80,19 +80,17 @@
}
/* Implemented to satisfy datasourcee protocol */
- (BOOL) outlineView:(NSOutlineView *)ov isItemExpandable:(id)item {
return YES;
}
- (BOOL) outlineView: (NSOutlineView *)ov
isItemExpandable: (id)item { return NO; }
- (NSInteger) outlineView:(NSOutlineView *)ov numberOfChildrenOfItem:(id)item {
return 0;
}
- (NSInteger) outlineView: (NSOutlineView *)ov
numberOfChildrenOfItem:(id)item { return 0; }
- (id) outlineView:(NSOutlineView *)ov child:(NSInteger)index ofItem:(id)item {
return nil;
}
- (id) outlineView: (NSOutlineView *)ov
child:(NSInteger)index
ofItem:(id)item { return nil; }
- (id) outlineView:(NSOutlineView *)ov objectValueForTableColumn:(NSTableColumn *)col byItem:(id)item {
return nil;
}
- (id) outlineView: (NSOutlineView *)ov
objectValueForTableColumn:(NSTableColumn*)col
byItem:(id)item { return nil; }
@end
+4
View File
@@ -7,8 +7,12 @@
//
@class PBGitRef;
@class PBGitCommit;
@protocol PBRefContextDelegate
- (NSArray *) menuItemsForRef:(PBGitRef *)ref;
- (NSArray *) menuItemsForCommit:(PBGitCommit *)commit;
- (NSArray *)menuItemsForRow:(NSInteger)rowIndex;
@end

Some files were not shown because too many files have changed in this diff Show More