diff --git a/Commands/PBCommand.h b/Commands/PBCommand.h new file mode 100644 index 0000000..ee92b27 --- /dev/null +++ b/Commands/PBCommand.h @@ -0,0 +1,28 @@ +// +// PBCommand.h +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface PBCommand : NSObject { + // for the user to see what it triggers + NSString *displayName; + // shown during command execution + NSString *commandTitle; + NSString *commandDescription; + + NSArray *parameters; +} +@property (nonatomic, retain) NSString *commandTitle; +@property (nonatomic, retain) NSString *commandDescription; +@property (nonatomic, copy) NSString *displayName; +@property (nonatomic, retain, readonly) NSArray *parameters; + +- (id) initWithDisplayName:(NSString *) aDisplayName parameters:(NSArray *) params; +- (void) invoke; +@end diff --git a/Commands/PBCommand.m b/Commands/PBCommand.m new file mode 100644 index 0000000..db7a563 --- /dev/null +++ b/Commands/PBCommand.m @@ -0,0 +1,44 @@ +// +// PBCommand.m +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "PBCommand.h" + + +@implementation PBCommand +@synthesize displayName; +@synthesize parameters; +@synthesize commandDescription; +@synthesize commandTitle; + +- (id) initWithDisplayName:(NSString *) aDisplayName parameters:(NSArray *) params { + self = [super init]; + if (self != nil) { + self.displayName = aDisplayName; + parameters = [params retain]; + + // default values + self.commandTitle = @""; + self.commandDescription = @""; + } + return self; +} + + +- (void) dealloc { + [commandDescription release]; + [commandTitle release]; + [parameters release]; + [displayName release]; + [super dealloc]; +} + +- (void) invoke { + NSLog(@"Warning: Empty/abstrac command has been fired!"); +} + +@end diff --git a/Commands/PBCommandFactory.h b/Commands/PBCommandFactory.h new file mode 100644 index 0000000..a613c7b --- /dev/null +++ b/Commands/PBCommandFactory.h @@ -0,0 +1,13 @@ +// +// PBCommandFactory.h +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "PBGitRepository.h" + +@protocol PBCommandFactory ++ (NSArray *) commandsForObject:(NSObject *) object repository:(PBGitRepository *) repository; +@end diff --git a/Commands/PBStashCommand.h b/Commands/PBStashCommand.h new file mode 100644 index 0000000..bf9d40d --- /dev/null +++ b/Commands/PBStashCommand.h @@ -0,0 +1,19 @@ +// +// PBStashCommand.h +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import +#import "PBCommand.h" +#import "PBGitRepository.h" + +@interface PBStashCommand : PBCommand { + PBGitRepository *repository; + NSArray *arguments; +} + +- initWithDisplayName:(NSString *) aDisplayName arguments:(NSArray *) args repository:(PBGitRepository *) repo; +@end diff --git a/Commands/PBStashCommand.m b/Commands/PBStashCommand.m new file mode 100644 index 0000000..53f9839 --- /dev/null +++ b/Commands/PBStashCommand.m @@ -0,0 +1,44 @@ +// +// PBStashCommand.m +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "PBStashCommand.h" +#import "PBRemoteProgressSheet.h" + +@interface PBStashCommand() +@property (nonatomic, retain) PBGitRepository *repository; +@property (nonatomic, retain) NSArray *arguments; +@end + + +@implementation PBStashCommand +@synthesize repository; +@synthesize arguments; + +- initWithDisplayName:(NSString *) aDisplayName arguments:(NSArray *) args repository:(PBGitRepository *) repo { + if (self = [super initWithDisplayName:aDisplayName parameters:[NSArray arrayWithObject:@"stash"]]) { + self.arguments = args; + self.repository = repo; + } + return self; +} + +- (void) dealloc { + [parameters release]; + [repository release]; + [super dealloc]; +} + + +- (void) invoke { + NSMutableArray *args = [[NSMutableArray alloc] initWithArray:super.parameters]; + [args addObjectsFromArray:self.arguments]; + [PBRemoteProgressSheet beginRemoteProgressSheetForArguments:args title:self.commandTitle description:self.commandDescription inRepository:self.repository]; + [args release]; +} + +@end diff --git a/Commands/PBStashCommandFactory.h b/Commands/PBStashCommandFactory.h new file mode 100644 index 0000000..291c47b --- /dev/null +++ b/Commands/PBStashCommandFactory.h @@ -0,0 +1,16 @@ +// +// PBStashCommandFactory.h +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import +#import "PBCommandFactory.h" + +@interface PBStashCommandFactory : NSObject { + +} + +@end diff --git a/Commands/PBStashCommandFactory.m b/Commands/PBStashCommandFactory.m new file mode 100644 index 0000000..83f8e0f --- /dev/null +++ b/Commands/PBStashCommandFactory.m @@ -0,0 +1,46 @@ +// +// PBStashCommandFactory.m +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "PBStashCommandFactory.h" +#import "PBStashCommand.h" + +// model +#import "PBGitStash.h" + +@implementation PBStashCommandFactory + ++ (NSArray *) commandsForObject:(NSObject *) object repository:(PBGitRepository *) repository { + if (![object isKindOfClass:[PBGitStash class]]) { + return nil; + } + PBGitStash *stash = (PBGitStash *) object; + NSMutableArray *commands = [[NSMutableArray alloc] init]; + + NSArray *args = [NSArray arrayWithObjects:@"apply", [stash name], nil]; + PBStashCommand *command = [[PBStashCommand alloc] initWithDisplayName:@"Apply" arguments:args repository:repository]; + command.commandTitle = command.displayName; + command.commandDescription = [NSString stringWithFormat:@"Applying stash: '%@'", stash]; + [commands addObject:command]; + + args = [NSArray arrayWithObjects:@"pop", [stash name], nil]; + command = [[PBStashCommand alloc] initWithDisplayName:@"Pop" arguments:args repository:repository]; + command.commandTitle = command.displayName; + command.commandDescription = [NSString stringWithFormat:@"Poping stash: '%@'", stash]; + [commands addObject:command]; + + args = [NSArray arrayWithObjects:@"drop", [stash name], nil]; + command = [[PBStashCommand alloc] initWithDisplayName:@"Drop" arguments:args repository:repository]; + command.commandTitle = command.displayName; + command.commandDescription = [NSString stringWithFormat:@"Dropping stash: '%@'", stash]; + [commands addObject:command]; + + + return [commands autorelease]; +} + +@end diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index 65ea4fa..015e0f1 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -24,6 +24,13 @@ 02B41A5E123E307200DFC531 /* PBCommitHookFailedSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 02B41A5D123E307200DFC531 /* PBCommitHookFailedSheet.m */; }; 02B41A60123E307F00DFC531 /* PBCommitHookFailedSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 02B41A5F123E307F00DFC531 /* PBCommitHookFailedSheet.xib */; }; 056438B70ED0C40B00985397 /* DetailViewTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = 056438B60ED0C40B00985397 /* DetailViewTemplate.png */; }; + 21230CB11284B26A0046E5A1 /* PBGitSVStashItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 21230CB01284B26A0046E5A1 /* PBGitSVStashItem.m */; }; + 21230D351284C5080046E5A1 /* PBGitStash.m in Sources */ = {isa = PBXBuildFile; fileRef = 21230D341284C5080046E5A1 /* PBGitStash.m */; }; + 21230D821284D1CC0046E5A1 /* stash-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 21230D811284D1CC0046E5A1 /* stash-icon.png */; }; + 21230D9C128552720046E5A1 /* PBCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 21230D9B128552720046E5A1 /* PBCommand.m */; }; + 21230D9F128552FA0046E5A1 /* PBStashCommandFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 21230D9E128552FA0046E5A1 /* PBStashCommandFactory.m */; }; + 21230DAA1285550B0046E5A1 /* PBCommandMenuItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 21230DA91285550B0046E5A1 /* PBCommandMenuItem.m */; }; + 21230DEE12855A990046E5A1 /* PBStashCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 21230DED12855A990046E5A1 /* PBStashCommand.m */; }; 310DC1D81240599E0017A0F7 /* GLFileView.m in Sources */ = {isa = PBXBuildFile; fileRef = 310DC1D71240599E0017A0F7 /* GLFileView.m */; }; 31460CD2124185BA00B90AED /* MGRecessedPopUpButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 31460CA7124185BA00B90AED /* MGRecessedPopUpButtonCell.m */; }; 31460CD3124185BA00B90AED /* MGScopeBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 31460CA9124185BA00B90AED /* MGScopeBar.m */; }; @@ -251,6 +258,21 @@ 056438B60ED0C40B00985397 /* DetailViewTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = DetailViewTemplate.png; path = Images/DetailViewTemplate.png; sourceTree = ""; }; 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 21230CAF1284B26A0046E5A1 /* PBGitSVStashItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitSVStashItem.h; sourceTree = ""; }; + 21230CB01284B26A0046E5A1 /* PBGitSVStashItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitSVStashItem.m; sourceTree = ""; }; + 21230D331284C5080046E5A1 /* PBGitStash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitStash.h; sourceTree = ""; }; + 21230D341284C5080046E5A1 /* PBGitStash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitStash.m; sourceTree = ""; }; + 21230D4D1284C92E0046E5A1 /* PBPresentable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBPresentable.h; sourceTree = ""; }; + 21230D811284D1CC0046E5A1 /* stash-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "stash-icon.png"; sourceTree = ""; }; + 21230D9A128552720046E5A1 /* PBCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBCommand.h; sourceTree = ""; }; + 21230D9B128552720046E5A1 /* PBCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBCommand.m; sourceTree = ""; }; + 21230D9D128552FA0046E5A1 /* PBStashCommandFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBStashCommandFactory.h; sourceTree = ""; }; + 21230D9E128552FA0046E5A1 /* PBStashCommandFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBStashCommandFactory.m; sourceTree = ""; }; + 21230DA0128553120046E5A1 /* PBCommandFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBCommandFactory.h; sourceTree = ""; }; + 21230DA81285550B0046E5A1 /* PBCommandMenuItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBCommandMenuItem.h; sourceTree = ""; }; + 21230DA91285550B0046E5A1 /* PBCommandMenuItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBCommandMenuItem.m; sourceTree = ""; }; + 21230DEC12855A990046E5A1 /* PBStashCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBStashCommand.h; sourceTree = ""; }; + 21230DED12855A990046E5A1 /* PBStashCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBStashCommand.m; sourceTree = ""; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; @@ -544,6 +566,8 @@ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( + 21230D991285524C0046E5A1 /* Commands */, + 21230D321284C4F10046E5A1 /* Model */, ); name = Classes; sourceTree = ""; @@ -584,6 +608,30 @@ name = Products; sourceTree = ""; }; + 21230D321284C4F10046E5A1 /* Model */ = { + isa = PBXGroup; + children = ( + 21230D331284C5080046E5A1 /* PBGitStash.h */, + 21230D341284C5080046E5A1 /* PBGitStash.m */, + 21230D4D1284C92E0046E5A1 /* PBPresentable.h */, + ); + path = Model; + sourceTree = ""; + }; + 21230D991285524C0046E5A1 /* Commands */ = { + isa = PBXGroup; + children = ( + 21230D9A128552720046E5A1 /* PBCommand.h */, + 21230D9B128552720046E5A1 /* PBCommand.m */, + 21230DEC12855A990046E5A1 /* PBStashCommand.h */, + 21230DED12855A990046E5A1 /* PBStashCommand.m */, + 21230D9D128552FA0046E5A1 /* PBStashCommandFactory.h */, + 21230D9E128552FA0046E5A1 /* PBStashCommandFactory.m */, + 21230DA0128553120046E5A1 /* PBCommandFactory.h */, + ); + path = Commands; + sourceTree = ""; + }; 29B97314FDCFA39411CA2CEA /* GitTest */ = { isa = PBXGroup; children = ( @@ -629,6 +677,7 @@ F56ADDD70ED19F9E002AC78F /* AddBranchTemplate.png */, F56ADDD80ED19F9E002AC78F /* AddLabelTemplate.png */, 056438B60ED0C40B00985397 /* DetailViewTemplate.png */, + 21230D811284D1CC0046E5A1 /* stash-icon.png */, F57240BA0E9678EA00D8EE66 /* deleted_file.png */, F5E92A1A0E88550E00056E75 /* empty_file.png */, 32CA4F630368D1EE00C91783 /* GitX_Prefix.pch */, @@ -786,6 +835,8 @@ D8FDDA63114335E8005647F6 /* PBGitSVRemoteBranchItem.m */, D8FDDA68114335E8005647F6 /* PBGitSVTagItem.h */, D8FDDA69114335E8005647F6 /* PBGitSVTagItem.m */, + 21230CAF1284B26A0046E5A1 /* PBGitSVStashItem.h */, + 21230CB01284B26A0046E5A1 /* PBGitSVStashItem.m */, D8FDDA60114335E8005647F6 /* PBGitSVOtherRevItem.h */, D8FDDA61114335E8005647F6 /* PBGitSVOtherRevItem.m */, D8FDDA5E114335E8005647F6 /* PBGitSVFolderItem.h */, @@ -982,6 +1033,8 @@ F5FC43C30EBD050800191D80 /* PBRefContextDelegate.h */, F5FC43FC0EBD08EE00191D80 /* PBRefMenuItem.h */, F5FC43FD0EBD08EE00191D80 /* PBRefMenuItem.m */, + 21230DA81285550B0046E5A1 /* PBCommandMenuItem.h */, + 21230DA91285550B0046E5A1 /* PBCommandMenuItem.m */, ); name = History; sourceTree = ""; @@ -1158,7 +1211,14 @@ isa = PBXProject; buildConfigurationList = 26FC0A880875C7B200E6366F /* Build configuration list for PBXProject "GitX" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* GitTest */; projectDirPath = ""; projectRoot = ""; @@ -1228,6 +1288,7 @@ 31460CD5124185BA00B90AED /* Source Code License.rtf in Resources */, 31460CD6124185BA00B90AED /* TODO in Resources */, 02B41A60123E307F00DFC531 /* PBCommitHookFailedSheet.xib in Resources */, + 21230D821284D1CC0046E5A1 /* stash-icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1381,6 +1442,12 @@ 31460CD2124185BA00B90AED /* MGRecessedPopUpButtonCell.m in Sources */, 31460CD3124185BA00B90AED /* MGScopeBar.m in Sources */, 02B41A5E123E307200DFC531 /* PBCommitHookFailedSheet.m in Sources */, + 21230CB11284B26A0046E5A1 /* PBGitSVStashItem.m in Sources */, + 21230D351284C5080046E5A1 /* PBGitStash.m in Sources */, + 21230D9C128552720046E5A1 /* PBCommand.m in Sources */, + 21230D9F128552FA0046E5A1 /* PBStashCommandFactory.m in Sources */, + 21230DAA1285550B0046E5A1 /* PBCommandMenuItem.m in Sources */, + 21230DEE12855A990046E5A1 /* PBStashCommand.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Model/PBGitStash.h b/Model/PBGitStash.h new file mode 100644 index 0000000..9d5eba5 --- /dev/null +++ b/Model/PBGitStash.h @@ -0,0 +1,25 @@ +// +// PBGitStash.h +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import +#import "PBPresentable.h" + +@interface PBGitStash : NSObject { + NSString *stashRawString; + + NSString *stashSourceMessage; + NSString *name; + NSString *message; +} +@property (nonatomic, retain, readonly) NSString *name; +@property (nonatomic, retain, readonly) NSString *message; +@property (nonatomic, retain, readonly) NSString *stashSourceMessage; +@property (nonatomic, retain, readonly) NSString *stashRawString; + +- initWithRawStashLine:(NSString *) stashLineFromStashListOutput; +@end diff --git a/Model/PBGitStash.m b/Model/PBGitStash.m new file mode 100644 index 0000000..e2f08c6 --- /dev/null +++ b/Model/PBGitStash.m @@ -0,0 +1,51 @@ +// +// PBGitStash.m +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "PBGitStash.h" + + +@implementation PBGitStash +@synthesize name; +@synthesize message; +@synthesize stashRawString; +@synthesize stashSourceMessage; + +- initWithRawStashLine:(NSString *) stashLineFromStashListOutput { + if (self = [super init]) { + stashRawString = [stashLineFromStashListOutput retain]; + NSArray *lineComponents = [stashLineFromStashListOutput componentsSeparatedByString:@":"]; + name = [[lineComponents objectAtIndex:0] retain]; + stashSourceMessage = [[[lineComponents objectAtIndex:1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] retain]; + message = [[[lineComponents objectAtIndex:2] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] retain]; + } + return self; +} + +- (void) dealloc { + [stashSourceMessage release]; + [stashRawString release]; + [name release]; + [message release]; + [super dealloc]; +} + +- (NSString *) description { + return self.stashRawString; +} + +#pragma mark Presentable + +- (NSString *) displayDescription { + return self.name; +} + +- (NSString *) popupDescription { + return [self description]; +} + +@end diff --git a/Model/PBPresentable.h b/Model/PBPresentable.h new file mode 100644 index 0000000..299d208 --- /dev/null +++ b/Model/PBPresentable.h @@ -0,0 +1,13 @@ +// +// PBPresentable.h +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + + +@protocol PBPresentable +- (NSString *) displayDescription; +- (NSString *) popupDescription; +@end diff --git a/PBCommandMenuItem.h b/PBCommandMenuItem.h new file mode 100644 index 0000000..62ac0fd --- /dev/null +++ b/PBCommandMenuItem.h @@ -0,0 +1,19 @@ +// +// PBCommandMenuItem.h +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import +#import "PBCommand.h" + +@interface PBCommandMenuItem : NSMenuItem { + PBCommand *command; +} +@property (nonatomic, retain, readonly) PBCommand *command; + +- initWithCommand:(PBCommand *) aCommand; + +@end diff --git a/PBCommandMenuItem.m b/PBCommandMenuItem.m new file mode 100644 index 0000000..3a080dd --- /dev/null +++ b/PBCommandMenuItem.m @@ -0,0 +1,36 @@ +// +// PBCommandMenuItem.m +// GitX +// +// Created by Tomasz Krasnyk on 10-11-06. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "PBCommandMenuItem.h" + +@interface PBCommandMenuItem() +@property (nonatomic, retain) PBCommand *command; +@end + + + +@implementation PBCommandMenuItem +@synthesize command; + +- initWithCommand:(PBCommand *) aCommand { + if (self = [super init]) { + self.command = aCommand; + super.title = [aCommand displayName]; + [self setTarget:aCommand]; + [self setAction:@selector(invoke)]; + } + return self; +} + +- (void) dealloc { + [command release]; + [super dealloc]; +} + + +@end diff --git a/PBGitRepository.h b/PBGitRepository.h index b72d247..f5669e2 100644 --- a/PBGitRepository.h +++ b/PBGitRepository.h @@ -52,6 +52,8 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { PBGitRevSpecifier *_headRef; // Caching PBGitSHA* _headSha; + + NSArray *stashes; } - (void) cloneRepositoryToPath:(NSString *)path bare:(BOOL)isBare; @@ -96,6 +98,7 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { - (NSString *)gitIgnoreFilename; - (BOOL)isBareRepository; +- (void) reloadStashes; - (void) reloadRefs; - (void) addRef:(PBGitRef *)ref fromParameters:(NSArray *)params; - (void) lazyReload; diff --git a/PBGitRepository.m b/PBGitRepository.m index 7b5ea16..3c92559 100644 --- a/PBGitRepository.m +++ b/PBGitRepository.m @@ -21,10 +21,18 @@ #import "GitXScriptingConstants.h" #import "PBHistorySearchController.h" +#import "PBGitStash.h" + NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; -@implementation PBGitRepository +@interface PBGitRepository() +@property (nonatomic, retain) NSArray *stashes; +@end + + +@implementation PBGitRepository +@synthesize stashes; @synthesize revisionList, branches, currentBranch, refs, hasChanged, config; @synthesize currentBranchFilter; @@ -247,6 +255,23 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; [refs setObject:[NSMutableArray arrayWithObject:ref] forKey:sha]; } +- (void) reloadStashes { + NSArray *arguments = [NSArray arrayWithObjects:@"stash", @"list", nil]; + NSString *output = [self outputInWorkdirForArguments:arguments]; + NSArray *lines = [output componentsSeparatedByString:@"\n"]; + + NSMutableArray *loadedStashes = [[NSMutableArray alloc] init]; + + for (NSString *stashLine in lines) { + PBGitStash *stash = [[PBGitStash alloc] initWithRawStashLine:stashLine]; + [loadedStashes addObject:stash]; + [stash release]; + } + + self.stashes = loadedStashes; + [loadedStashes release]; +} + - (void) reloadRefs { _headRef = nil; @@ -280,6 +305,8 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; [self willChangeValueForKey:@"refs"]; [self didChangeValueForKey:@"refs"]; + + [self reloadStashes]; [[[self windowController] window] setTitle:[self displayName]]; } @@ -1146,7 +1173,8 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; - (NSString*) outputInWorkdirForArguments:(NSArray*) arguments { - return [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:arguments inDir: [self workingDirectory]]; + NSString *output = [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:arguments inDir: [self workingDirectory]]; + return [output length] > 0 ? output : nil; } - (NSString*) outputInWorkdirForArguments:(NSArray *)arguments retValue:(int *)ret @@ -1223,6 +1251,11 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; return nil; } +- (void) dealloc { + [stashes release]; + [super dealloc]; +} + - (void) finalize { NSLog(@"Dealloc of repository"); diff --git a/PBGitSVStashItem.h b/PBGitSVStashItem.h new file mode 100644 index 0000000..e3cd134 --- /dev/null +++ b/PBGitSVStashItem.h @@ -0,0 +1,20 @@ +// +// PBGitSVStashItem.h +// GitX +// +// Created by Tomasz Krasnyk on 10-11-05. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import +#import "PBSourceViewItem.h" +#import "PBGitStash.h" + + +@interface PBGitSVStashItem : PBSourceViewItem { + PBGitStash *stash; +} +@property (nonatomic, retain, readonly) PBGitStash *stash; + +- initWithStash:(PBGitStash *) aStash; +@end diff --git a/PBGitSVStashItem.m b/PBGitSVStashItem.m new file mode 100644 index 0000000..d91d069 --- /dev/null +++ b/PBGitSVStashItem.m @@ -0,0 +1,45 @@ +// +// PBGitSVStashItem.m +// GitX +// +// Created by Tomasz Krasnyk on 10-11-05. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "PBGitSVStashItem.h" + + +@implementation PBGitSVStashItem +@synthesize stash; + +#pragma mark - +#pragma mark Inits/dealloc +//--------------------------------------------------------------------------------------------- + +- initWithStash:(PBGitStash *) aStash { + if (self = [super init]) { + NSString *displayTitle = [NSString stringWithFormat:@"%@ (%@)", [aStash message], [aStash stashSourceMessage]]; + super.title = displayTitle; + stash = [aStash retain]; + } + return self; +} + +- (void) dealloc { + [stash release]; + [super dealloc]; +} + +//--------------------------------------------------------------------------------------------- +#pragma mark - + + +- (NSImage *) icon { + static NSImage *tagImage = nil; + if (!tagImage) + tagImage = [NSImage imageNamed:@"stash-icon.png"]; + + return tagImage; +} + +@end diff --git a/PBGitSidebarController.h b/PBGitSidebarController.h index ec26569..352302a 100644 --- a/PBGitSidebarController.h +++ b/PBGitSidebarController.h @@ -29,7 +29,7 @@ /* Specific things */ PBSourceViewItem *stage; - PBSourceViewItem *branches, *remotes, *tags, *others; + PBSourceViewItem *branches, *remotes, *tags, *others, *stashes; PBGitHistoryController *historyViewController; PBGitCommitController *commitViewController; diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m index 679e2dc..5e76b26 100644 --- a/PBGitSidebarController.m +++ b/PBGitSidebarController.m @@ -16,6 +16,12 @@ #import "PBAddRemoteSheet.h" #import "PBGitDefaults.h" #import "PBHistorySearchController.h" +#import "PBGitSVStashItem.h" + +#import "PBStashCommandFactory.h" +#import "PBCommandMenuItem.h" + +static NSString * const kObservingContextStashes = @"stashesChanged"; @interface PBGitSidebarController () @@ -51,6 +57,7 @@ [repository addObserver:self forKeyPath:@"currentBranch" options:0 context:@"currentBranchChange"]; [repository addObserver:self forKeyPath:@"branches" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:@"branchesModified"]; + [repository addObserver:self forKeyPath:@"stashes" options:NSKeyValueObservingOptionNew context:@"stashesChanged"]; [self menuNeedsUpdate:[actionButton menu]]; @@ -67,6 +74,7 @@ [repository removeObserver:self forKeyPath:@"currentBranch"]; [repository removeObserver:self forKeyPath:@"branches"]; + [repository removeObserver:self forKeyPath:@"stashes"]; [super closeView]; } @@ -76,10 +84,7 @@ if ([@"currentBranchChange" isEqualToString:context]) { [sourceView reloadData]; [self selectCurrentBranch]; - return; - } - - if ([@"branchesModified" isEqualToString:context]) { + } else if ([@"branchesModified" isEqualToString:context]) { NSInteger changeKind = [(NSNumber *)[change objectForKey:NSKeyValueChangeKindKey] intValue]; if (changeKind == NSKeyValueChangeInsertion) { @@ -95,10 +100,19 @@ for (PBGitRevSpecifier *rev in removedRevSpecs) [self removeRevSpec:rev]; } - return; + } else if ([@"stashesChanged" isEqualToString:context]) { // isEqualToString: is not needed here + [stashes.children removeAllObjects]; + NSArray *newStashes = [change objectForKey:NSKeyValueChangeNewKey]; + + for (PBGitStash *stash in newStashes) { + PBGitSVStashItem *item = [[PBGitSVStashItem alloc] initWithStash:stash]; + [stashes addChild:item]; + [item release]; + } + [sourceView reloadData]; + } else { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } - - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } - (PBSourceViewItem *) selectedItem @@ -170,6 +184,7 @@ [tags addRev:rev toPath:[pathComponents subarrayWithRange:NSMakeRange(2, [pathComponents count] - 2)]]; else if ([[rev simpleRef] hasPrefix:@"refs/remotes/"]) [remotes addRev:rev toPath:[pathComponents subarrayWithRange:NSMakeRange(2, [pathComponents count] - 2)]]; + [sourceView reloadData]; } @@ -252,6 +267,7 @@ remotes = [PBSourceViewItem groupItemWithTitle:@"Remotes"]; tags = [PBSourceViewItem groupItemWithTitle:@"Tags"]; others = [PBSourceViewItem groupItemWithTitle:@"Other"]; + stashes = [PBSourceViewItem groupItemWithTitle:@"Stashes"]; for (PBGitRevSpecifier *rev in repository.branches) [self addRevSpec:rev]; @@ -261,6 +277,7 @@ [items addObject:remotes]; [items addObject:tags]; [items addObject:others]; + [items addObject:stashes]; [sourceView reloadData]; [sourceView expandItem:project]; @@ -328,7 +345,22 @@ - (NSMenu *) menuForRow:(NSInteger)row { PBSourceViewItem *viewItem = [sourceView itemAtRow:row]; - + if ([viewItem isKindOfClass:[PBGitSVStashItem class]]) { + PBGitSVStashItem *stashItem = (PBGitSVStashItem *) viewItem; + NSArray *commands = [PBStashCommandFactory commandsForObject:[stashItem stash] repository:historyViewController.repository]; + if (!commands) { + return nil; + } + NSMenu *menu = [[NSMenu alloc] init]; + for (PBCommand *command in commands) { + PBCommandMenuItem *item = [[PBCommandMenuItem alloc] initWithCommand:command]; + [item setEnabled:YES]; + [menu addItem:item]; + [item release]; + } + return menu; + } + PBGitRef *ref = [viewItem ref]; if (!ref) return nil; diff --git a/stash-icon.png b/stash-icon.png new file mode 100644 index 0000000..d861fb2 Binary files /dev/null and b/stash-icon.png differ