From 0a3b60066c0662c4097e2d1db22e95fb1080abb9 Mon Sep 17 00:00:00 2001 From: krt Date: Sat, 6 Nov 2010 13:20:13 +0100 Subject: [PATCH] Stashes are shown on in Side controlle --- Commands/PBCommand.h | 28 +++++++++++++ Commands/PBCommand.m | 44 ++++++++++++++++++++ Commands/PBCommandFactory.h | 13 ++++++ Commands/PBStashCommand.h | 19 +++++++++ Commands/PBStashCommand.m | 44 ++++++++++++++++++++ Commands/PBStashCommandFactory.h | 16 ++++++++ Commands/PBStashCommandFactory.m | 46 +++++++++++++++++++++ GitX.xcodeproj/project.pbxproj | 67 +++++++++++++++++++++++++++++++ Model/PBGitStash.h | 25 ++++++++++++ Model/PBGitStash.m | 51 +++++++++++++++++++++++ Model/PBPresentable.h | 13 ++++++ PBCommandMenuItem.h | 19 +++++++++ PBCommandMenuItem.m | 36 +++++++++++++++++ PBGitRepository.h | 3 ++ PBGitRepository.m | 37 ++++++++++++++++- PBGitSVStashItem.h | 20 +++++++++ PBGitSVStashItem.m | 45 +++++++++++++++++++++ PBGitSidebarController.h | 2 +- PBGitSidebarController.m | 48 ++++++++++++++++++---- stash-icon.png | Bin 0 -> 3395 bytes 20 files changed, 565 insertions(+), 11 deletions(-) create mode 100644 Commands/PBCommand.h create mode 100644 Commands/PBCommand.m create mode 100644 Commands/PBCommandFactory.h create mode 100644 Commands/PBStashCommand.h create mode 100644 Commands/PBStashCommand.m create mode 100644 Commands/PBStashCommandFactory.h create mode 100644 Commands/PBStashCommandFactory.m create mode 100644 Model/PBGitStash.h create mode 100644 Model/PBGitStash.m create mode 100644 Model/PBPresentable.h create mode 100644 PBCommandMenuItem.h create mode 100644 PBCommandMenuItem.m create mode 100644 PBGitSVStashItem.h create mode 100644 PBGitSVStashItem.m create mode 100644 stash-icon.png 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 71a441a..28ef783 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 */; }; 3BC07F4C0ED5A5C5009A7768 /* HistoryViewTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = 3BC07F4A0ED5A5C5009A7768 /* HistoryViewTemplate.png */; }; 3BC07F4D0ED5A5C5009A7768 /* CommitViewTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = 3BC07F4B0ED5A5C5009A7768 /* CommitViewTemplate.png */; }; 47DBDB580E94EDE700671A1E /* DBPrefsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 47DBDB570E94EDE700671A1E /* DBPrefsWindowController.m */; }; @@ -245,6 +252,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 = ""; }; @@ -527,6 +549,8 @@ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( + 21230D991285524C0046E5A1 /* Commands */, + 21230D321284C4F10046E5A1 /* Model */, ); name = Classes; sourceTree = ""; @@ -567,6 +591,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 = ( @@ -612,6 +660,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 */, @@ -744,6 +793,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 */, @@ -938,6 +989,8 @@ F5FC43C30EBD050800191D80 /* PBRefContextDelegate.h */, F5FC43FC0EBD08EE00191D80 /* PBRefMenuItem.h */, F5FC43FD0EBD08EE00191D80 /* PBRefMenuItem.m */, + 21230DA81285550B0046E5A1 /* PBCommandMenuItem.h */, + 21230DA91285550B0046E5A1 /* PBCommandMenuItem.m */, ); name = History; sourceTree = ""; @@ -1114,7 +1167,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 = ""; @@ -1181,6 +1241,7 @@ D8F01C4B12182F19007F729F /* GitX.sdef in Resources */, D8F4AB7912298CE200D6D53C /* rewindImage.pdf in Resources */, 02B41A60123E307F00DFC531 /* PBCommitHookFailedSheet.xib in Resources */, + 21230D821284D1CC0046E5A1 /* stash-icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1331,6 +1392,12 @@ D8B4DC571220D1E4004166D6 /* PBHistorySearchController.m in Sources */, D8712A00122B14EC00012334 /* GitXTextFieldCell.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 7599c6c..986c0aa 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; @@ -90,6 +92,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 3d4489b..2d18d5d 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]]; } @@ -1061,7 +1088,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 @@ -1138,6 +1166,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 e2f712f..68b5405 100644 --- a/PBGitSidebarController.h +++ b/PBGitSidebarController.h @@ -25,7 +25,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 efcf6f1..81b696f 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 0000000000000000000000000000000000000000..d861fb23973ca802c42b9d8d1c715ea70435daf1 GIT binary patch literal 3395 zcmV-J4ZQM+P)5r000U^X+uL$Nkc;* zP;zf(X>4Tx0C)kNmUmPX*B8g%%xo{TU6vwc>AklFq%OTkl_mFQv@x1^BM1TV}0C2duqR=S6Xn?LjUp6xrb&~O43j*Nv zEr418u3H3zGns$s|L;SQD-ufpfWpxLJ03rmi*g~#S@{x?OrJ!Vo{}kJ7$ajbnjp%m zGEV!%=70KpVow?KvV}a4moSaFCQKV= zXBIPnpP$8-NG!rR+)R#`$7JVZi#Wn10DSspSrkx`)s~4C+0n+?(b2-z5-tDd^^cpM zz5W?wz5V3zGUCskL5!X++LzcbT23thtSPiMTfS&1I{|204}j|3FPi>70OSh+Xzlyz zdl<5LNtZ}OE>>3g`T3RtKG#xK(9i3CI(+v0d-&=+OWAp!Ysd8Ar*foO5~i%E+?=c& zshF87;&Ay)i~kOm zCIB-Z!^JGdti+UJsxgN!t(Y#%b<8kk67vyD#cE*9urAm@Y#cTXn~yERR$}Y1E!Yd# zo7hq8Ya9;8z!~A3Z~?e@Tn26#t`xT$*Ni)h>&K1Yrto;Y8r}@=h7ZGY@Dh9xekcA2 z{tSKqKZ<`tAQQ9+wgf*y0zpVvOQ<9qCY&Y=5XJ~ILHOG0j2XwBQ%7jM`P2tv~{#P+6CGu9Y;5!2hua>CG_v;z4S?CC1rc%807-x z8s$^ULkxsr$OvR)G0GUn7`GVjR5Vq*RQM{JRGL%DRgX~5SKp(4L49HleU9rK?wsN|$L8GCfHh1tA~lw29MI^|n9|hJ z^w$(=?$kW5IibbS^3=-Es?a*EHLgw5cGnhYS7@Kne#%s4dNH$@Rm?8tq>hG8fR0pW zzfP~tjINRHeBHIW&AJctNO~;2RJ{tlPQ6KeZT(RF<@$~KcMXUJEQ54|9R}S7(}qTd zv4$HA+YFx=sTu_uEj4O1x^GN1_Ap*-Tx)#81ZToB$u!w*a?KPrbudjgtugI0gUuYx z1ZKO<`pvQC&gMe%TJu2*iiMX&o<*a@uqDGX#B!}=o8@yWeX9hktybMuAFUm%v#jf^ z@7XBX1lg>$>9G0T*3_13TVs2}j%w#;x5}>F?uEUXJ>Pzh{cQ)DL#V?BhfaqNj!uqZ z$0o;dCw-@6r(I5iEIKQkRm!^LjCJ;QUgdn!`K^nii^S!a%Wtk0u9>cfU7yS~n#-SC zH+RHM*Nx-0-)+d9>7MMq&wa>4$AjZh>+#4_&y(j_?>XjW;+5fb#Ot}YwYS*2#e16V z!d}5X>x20C`xN{1`YQR(_pSDQ=%?$K=GW*q>F?mb%>QfvHXt})YrtTjW*|4PA#gIt zDQHDdS1=_wD!4lMQHW`XIHV&K4h;(37J7f4!93x-wlEMD7`83!LAX));_x3Ma1r4V zH4%>^Z6cRPc1O{olA;bry^i*dE{nc5-*~=serJq)Okzw!%yg_zYWi`#ol25V;v^kU#wN!mA5MPH z3FFjqrcwe^cBM>m+1wr6XFN|{1#g`1#xLiOrMjh-r#?w@OWT$Wgg6&&5F%x&L(6hXP*!%2{VOVIa)adIsGCtQITk9vCHD^izmgw;`&@D zcVTY3gpU49^+=7S>!rha?s+wNZ}MaEj~6Hw2n%|am@e70WNfM5(r=exmT{MLF4tMU zX8G_6uNC`OLMu~NcCOM}Rk&(&wg2ivYe;J{*Zj2BdTsgISLt?eJQu}$~QLORDCnMIdyYynPb_W zEx0YhEw{FMY&}%2SiZD;WLxOA)(U1tamB0cN!u@1+E?z~LE0hRF;o>&)xJ}I=a!xC ztJAA*)_B)6@6y<{Y1i~_-tK`to_m`1YVIxB`);3L-|hYW`&(-bYby`n4&)tpTo+T< z{VnU;hI;k-lKKw^g$IWYMIP#EaB65ctZ}%k5pI+=jvq-pa_u{x@7kLzn)Wv{noEv? zqtc^Kzfb=D*0JDYoyS?nn|?6(VOI;SrMMMpUD7()mfkkh9^c-7BIrbChiga6kCs0k zJgIZC=9KcOveTr~g{NoFEIl)IR&;jaT-v#j&ZN$J=i|=b=!)p-y%2oi(nY_E=exbS z&s=i5bn>#xz3Ke>~2=f&N;yEFGz-^boBexUH6@}b7V+Mi8+ZXR+R zIyLMw-18{v(Y+Dw$g^K^e|bMz_?Y^*a!h-y;fd{&ljDBl*PbqTI{HlXY-Xb9SH)j< zJvV;-!*8Cy^-RW1j=m7TnEk!M3&di(lymvt5O`3Q6?m74CTw#pC)$?j$p|Rg?KaS7h z(nPIRRZ1nt$Gt(NGTwJQ=XJB$Y+uD&{AX@%&Y7Q|ciFC8zxk|G9=#KlqTSZV*3#zI z=9+ZfJ;#;z8jZ#xV;IXEw#AFZ=Pw5*gN9{W31w4bqht58H2acf$9+yJ`tbYGb^SDEK6nmX}Sga|n(m1O}(4a2*GhZDTl0>D54zZCL_onxRx0 z!QZwSFTefRg;H70bn@_3w8iChdwruag=>{D;du_U)(p{1NO<8gdvQjQCpP2Aw8KvB^#sp zBSrG!*E>GJ`>mZq+L(ycH&UgF1k_@|VXpkA8I6@=WqFQak`|dg&!uS_