From c8cfe7acaa2c72d729ab3196b0e7ed1c307f1ba9 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Tue, 8 Sep 2009 13:09:40 +0200 Subject: [PATCH 001/451] Add start of a sourceview list This shows in a separate window for now, so we don't mess up the xibs. Once I'm satisfied with the result, I can put it into the main view with a single change :) --- GitX.xcodeproj/project.pbxproj | 24 ++ PBGitSidebarController.h | 20 ++ PBGitSidebarController.m | 29 +++ PBGitSidebarView.xib | 459 +++++++++++++++++++++++++++++++++ PBGitWindowController.h | 5 +- PBGitWindowController.m | 26 +- PBSourceViewItem.h | 20 ++ PBSourceViewItem.m | 29 +++ 8 files changed, 600 insertions(+), 12 deletions(-) create mode 100644 PBGitSidebarController.h create mode 100644 PBGitSidebarController.m create mode 100644 PBGitSidebarView.xib create mode 100644 PBSourceViewItem.h create mode 100644 PBSourceViewItem.m diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index be97512..a07e078 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -93,6 +93,9 @@ F5886A330ED5D5580066E74C /* PBGitRevSpecifier.m in Sources */ = {isa = PBXBuildFile; fileRef = F53FF2040E7ABB5300389171 /* PBGitRevSpecifier.m */; }; F5886A340ED5D55D0066E74C /* PBGitBinary.m in Sources */ = {isa = PBXBuildFile; fileRef = F53C4DF60E97FC630022AD59 /* PBGitBinary.m */; }; F5886A360ED5D56E0066E74C /* PBGitTree.m in Sources */ = {isa = PBXBuildFile; fileRef = F56174560E058893001DCD79 /* PBGitTree.m */; }; + F58DB55910566D3500CFDF4A /* PBGitSidebarController.m in Sources */ = {isa = PBXBuildFile; fileRef = F58DB55810566D3500CFDF4A /* PBGitSidebarController.m */; }; + F58DB56010566E3900CFDF4A /* PBGitSidebarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F58DB55F10566E3900CFDF4A /* PBGitSidebarView.xib */; }; + F58DB5E8105671B600CFDF4A /* PBSourceViewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = F58DB5E7105671B600CFDF4A /* PBSourceViewItem.m */; }; F59116E60E843BB50072CCB1 /* PBGitCommitView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F59116E50E843BB50072CCB1 /* PBGitCommitView.xib */; }; F59116E90E843BCB0072CCB1 /* PBGitCommitController.m in Sources */ = {isa = PBXBuildFile; fileRef = F59116E80E843BCB0072CCB1 /* PBGitCommitController.m */; }; F593DF780E9E636C003A8559 /* PBFileChangesTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = F593DF770E9E636C003A8559 /* PBFileChangesTableView.m */; }; @@ -243,6 +246,11 @@ F5886A0A0ED5D27A0066E74C /* speedtest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = speedtest.m; sourceTree = ""; }; F5886A100ED5D33D0066E74C /* SpeedTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpeedTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; F5886A120ED5D33D0066E74C /* SpeedTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SpeedTest-Info.plist"; sourceTree = ""; }; + F58DB55710566D3500CFDF4A /* PBGitSidebarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitSidebarController.h; sourceTree = ""; }; + F58DB55810566D3500CFDF4A /* PBGitSidebarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitSidebarController.m; sourceTree = ""; }; + F58DB55F10566E3900CFDF4A /* PBGitSidebarView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PBGitSidebarView.xib; sourceTree = ""; }; + F58DB5E6105671B600CFDF4A /* PBSourceViewItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBSourceViewItem.h; sourceTree = ""; }; + F58DB5E7105671B600CFDF4A /* PBSourceViewItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBSourceViewItem.m; sourceTree = ""; }; F59116E50E843BB50072CCB1 /* PBGitCommitView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PBGitCommitView.xib; sourceTree = ""; }; F59116E70E843BCB0072CCB1 /* PBGitCommitController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitCommitController.h; sourceTree = ""; }; F59116E80E843BCB0072CCB1 /* PBGitCommitController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitCommitController.m; sourceTree = ""; }; @@ -415,6 +423,7 @@ F59116E50E843BB50072CCB1 /* PBGitCommitView.xib */, 47DBDB680E94EF6500671A1E /* Preferences.xib */, F569AE920F2CBD7C00C2FFA7 /* Credits.html */, + F58DB55F10566E3900CFDF4A /* PBGitSidebarView.xib */, ); name = Resources; sourceTree = ""; @@ -482,6 +491,7 @@ F57CC3850E05DDC1000472E2 /* Controllers */ = { isa = PBXGroup; children = ( + F58DB55610566D1F00CFDF4A /* Sidebar */, F5B161BB0EAB6E0C005A1DE1 /* Diff */, F5EF8C880E9D498F0050906B /* History */, F5E927F90E883EF600056E75 /* Commit */, @@ -549,6 +559,17 @@ name = SpeedTest; sourceTree = ""; }; + F58DB55610566D1F00CFDF4A /* Sidebar */ = { + isa = PBXGroup; + children = ( + F58DB55710566D3500CFDF4A /* PBGitSidebarController.h */, + F58DB55810566D3500CFDF4A /* PBGitSidebarController.m */, + F58DB5E6105671B600CFDF4A /* PBSourceViewItem.h */, + F58DB5E7105671B600CFDF4A /* PBSourceViewItem.m */, + ); + name = Sidebar; + sourceTree = ""; + }; F5B161BB0EAB6E0C005A1DE1 /* Diff */ = { isa = PBXGroup; children = ( @@ -743,6 +764,7 @@ 47DBDB6A0E94EF6500671A1E /* Preferences.xib in Resources */, 47DBDBB10E94F6CA00671A1E /* Updates.png in Resources */, F569AE930F2CBD7C00C2FFA7 /* Credits.html in Resources */, + F58DB56010566E3900CFDF4A /* PBGitSidebarView.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -854,6 +876,8 @@ 47DBDBCA0E95016F00671A1E /* PBNSURLPathUserDefaultsTransfomer.m in Sources */, F562C8870FE1766C000EC528 /* NSString_RegEx.m in Sources */, EB2A734A0FEE3F09006601CF /* PBCollapsibleSplitView.m in Sources */, + F58DB55910566D3500CFDF4A /* PBGitSidebarController.m in Sources */, + F58DB5E8105671B600CFDF4A /* PBSourceViewItem.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PBGitSidebarController.h b/PBGitSidebarController.h new file mode 100644 index 0000000..a2e180c --- /dev/null +++ b/PBGitSidebarController.h @@ -0,0 +1,20 @@ +// +// PBGitSidebar.h +// GitX +// +// Created by Pieter de Bie on 9/8/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import +#import "PBViewController.h" + +@interface PBGitSidebarController : PBViewController { + IBOutlet NSWindow *window; + IBOutlet NSOutlineView *sourceView; + + NSMutableArray *items; +} + +@property(readonly) NSMutableArray *items; +@end diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m new file mode 100644 index 0000000..8f325ac --- /dev/null +++ b/PBGitSidebarController.m @@ -0,0 +1,29 @@ +// +// PBGitSidebar.m +// GitX +// +// Created by Pieter de Bie on 9/8/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "PBGitSidebarController.h" +#import "PBSourceViewItem.h" + +@implementation PBGitSidebarController +@synthesize items; + +- (id)initWithRepository:(PBGitRepository *)theRepository superController:(PBGitWindowController *)controller +{ + self = [super initWithRepository:theRepository superController:controller]; + [sourceView setDelegate:self]; + items = [NSMutableArray array]; + return self; +} + +- (void)awakeFromNib +{ + window.contentView = self.view; + [super awakeFromNib]; +} + +@end diff --git a/PBGitSidebarView.xib b/PBGitSidebarView.xib new file mode 100644 index 0000000..c264858 --- /dev/null +++ b/PBGitSidebarView.xib @@ -0,0 +1,459 @@ + + + + 1050 + 9L31a + 677 + 949.54 + 353.00 + + YES + + + + + YES + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + YES + + + YES + + + + YES + + PBGitSidebarController + + + FirstResponder + + + NSApplication + + + 15 + 2 + {{196, 106}, {186, 404}} + 603979776 + Window + NSWindow + + {3.40282e+38, 3.40282e+38} + + + 274 + {186, 404} + + + {{0, 0}, {1280, 1002}} + {3.40282e+38, 3.40282e+38} + + + + 4370 + + YES + + + 2304 + + YES + + + 4352 + {151, 352} + + YES + + + 256 + {{197, 0}, {16, 17}} + + + YES + + 1.500000e+02 + 1.600000e+01 + 1.000000e+03 + + 75628032 + 0 + + + LucidaGrande + 1.100000e+01 + 3100 + + + 3 + MC4zMzMzMzI5OQA + + + 6 + System + headerTextColor + + 3 + MAA + + + + + 337772096 + 2048 + Text Cell + + LucidaGrande + 1.300000e+01 + 1044 + + + + 6 + System + controlBackgroundColor + + 3 + MC42NjY2NjY2OQA + + + + 6 + System + controlTextColor + + + + 3 + YES + YES + + + + 3.000000e+00 + + 6 + System + _sourceListBackgroundColor + + 1 + MC44MzkyMTU3IDAuODY2NjY2NjcgMC44OTgwMzkyMgA + + + + 6 + System + gridColor + + 3 + MC41AA + + + 2.000000e+01 + -767557632 + 4 + 15 + 0 + YES + 1 + 1.400000e+01 + + + {153, 354} + + + + + 4 + + + + -2147483392 + {{137, 1}, {15, 338}} + + + _doScroller: + 9.969879e-01 + + + + 256 + {{-100, -100}, {196, 15}} + + 1 + + _doScroller: + 5.714286e-01 + + + {153, 354} + + + 528 + + + + QSAAAEEgAABBoAAAQaAAAA + + + YES + + + + + YES + + + window + + + + 5 + + + + view + + + + 25 + + + + sourceView + + + + 26 + + + + dataSource + + + + 34 + + + + delegate + + + + 35 + + + + + YES + + 0 + + YES + + + + + + -2 + + + RmlsZSdzIE93bmVyA + + + -1 + + + First Responder + + + -3 + + + Application + + + 2 + + + YES + + + + + + 3 + + + + + 8 + + + YES + + + + + + + + 9 + + + + + 10 + + + + + 11 + + + YES + + + + + + 13 + + + YES + + + + + + 16 + + + + + 21 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + -3.IBPluginDependency + 10.IBPluginDependency + 11.IBPluginDependency + 13.IBPluginDependency + 16.CustomClassName + 16.IBPluginDependency + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.IBWindowTemplateEditedContentRect + 2.NSWindowTemplate.visibleAtLaunch + 3.IBPluginDependency + 8.IBEditorWindowLastContentRect + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + PBIconAndTextCell + com.apple.InterfaceBuilder.CocoaPlugin + {{297, 477}, {186, 404}} + com.apple.InterfaceBuilder.CocoaPlugin + {{297, 477}, {186, 404}} + + com.apple.InterfaceBuilder.CocoaPlugin + {{105, 545}, {153, 354}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 35 + + + + YES + + PBGitSidebarController + PBViewController + + YES + + YES + sourceView + window + + + YES + NSOutlineView + NSWindow + + + + IBProjectSource + PBGitSidebarController.h + + + + PBIconAndTextCell + NSTextFieldCell + + IBProjectSource + PBIconAndTextCell.h + + + + PBViewController + NSViewController + + viewToolbar + NSToolbar + + + IBProjectSource + PBViewController.h + + + + + 0 + GitX.xcodeproj + 3 + + diff --git a/PBGitWindowController.h b/PBGitWindowController.h index ae2298b..5dcf5e0 100644 --- a/PBGitWindowController.h +++ b/PBGitWindowController.h @@ -9,7 +9,8 @@ #import #import "PBGitRepository.h" -@class PBViewController; +@class PBViewController, PBGitSidebarController; + @interface PBGitWindowController : NSWindowController { __weak PBGitRepository* repository; int selectedViewIndex; @@ -19,6 +20,8 @@ PBViewController *commitViewController; PBViewController* viewController; + + PBGitSidebarController *sidebarController; } @property (assign) __weak PBGitRepository *repository; diff --git a/PBGitWindowController.m b/PBGitWindowController.m index aba1987..087e3ad 100644 --- a/PBGitWindowController.m +++ b/PBGitWindowController.m @@ -9,6 +9,7 @@ #import "PBGitWindowController.h" #import "PBGitHistoryController.h" #import "PBGitCommitController.h" +#import "PBGitSidebarController.h" @implementation PBGitWindowController @@ -17,18 +18,21 @@ - (id)initWithRepository:(PBGitRepository*)theRepository displayDefault:(BOOL)displayDefault { - if(self = [self initWithWindowNibName:@"RepositoryWindow"]) - { - self.repository = theRepository; - [self showWindow:nil]; - } - - if (displayDefault) { - self.selectedViewIndex = [[NSUserDefaults standardUserDefaults] integerForKey:@"selectedViewIndex"]; - } else { - self.selectedViewIndex = -1; - } + if (!(self = [self initWithWindowNibName:@"RepositoryWindow"])) + return nil; + self.repository = theRepository; + [self showWindow:nil]; + + if (displayDefault) + self.selectedViewIndex = [[NSUserDefaults standardUserDefaults] integerForKey:@"selectedViewIndex"]; + else + self.selectedViewIndex = -1; + + // Sidebar + sidebarController = [[PBGitSidebarController alloc] initWithRepository:repository superController:self]; + // Hack for now + [sidebarController view]; return self; } diff --git a/PBSourceViewItem.h b/PBSourceViewItem.h new file mode 100644 index 0000000..3b722c7 --- /dev/null +++ b/PBSourceViewItem.h @@ -0,0 +1,20 @@ +// +// PBSourceViewItem.h +// GitX +// +// Created by Pieter de Bie on 9/8/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface PBSourceViewItem : NSObject { + NSString *name; +} + +- (id)initWithName:(NSString *)name; + +@property(retain) NSString *name; +@property(readonly) NSArray *children; +@end diff --git a/PBSourceViewItem.m b/PBSourceViewItem.m new file mode 100644 index 0000000..8629a50 --- /dev/null +++ b/PBSourceViewItem.m @@ -0,0 +1,29 @@ +// +// PBSourceViewItem.m +// GitX +// +// Created by Pieter de Bie on 9/8/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "PBSourceViewItem.h" + + +@implementation PBSourceViewItem +@synthesize name; +@dynamic children; + +- (id)initWithName:(NSString *)aName +{ + if (!(self = [super init])) + return nil; + + name = aName; + return self; +} + +- (NSArray *)children +{ + return [NSArray array]; +} +@end From 462e90dfc835519065f3866487b472c707663a14 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Tue, 8 Sep 2009 14:06:31 +0200 Subject: [PATCH 002/451] Sidebar: populate with branches This is far from perfect, but should indicate which direction this is going in --- PBGitSidebarController.m | 109 ++++++++++++++++++++++++++++++++++++++- PBSourceViewItem.h | 20 +++++-- PBSourceViewItem.m | 38 +++++++++++--- 3 files changed, 155 insertions(+), 12 deletions(-) diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m index 8f325ac..e8ca450 100644 --- a/PBGitSidebarController.m +++ b/PBGitSidebarController.m @@ -9,6 +9,12 @@ #import "PBGitSidebarController.h" #import "PBSourceViewItem.h" +@interface PBGitSidebarController () + +- (void)populateList; + +@end + @implementation PBGitSidebarController @synthesize items; @@ -17,13 +23,114 @@ self = [super initWithRepository:theRepository superController:controller]; [sourceView setDelegate:self]; items = [NSMutableArray array]; + return self; } - (void)awakeFromNib { - window.contentView = self.view; [super awakeFromNib]; + window.contentView = self.view; + [self populateList]; +} + +#pragma mark NSOutlineView delegate methods +- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item +{ + return [item isGroupItem]; +} + +- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item +{ + if ([item isGroupItem]) + [cell setImage:nil]; + else + [cell setImage:[NSImage imageNamed:@"new_file"]]; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item +{ + return ![item isGroupItem]; +} + +// +// The next two methods are necessary to hide the triangle for uncollapsible items +// That is, items which should always be displayed, such as the action items. +// +- (BOOL)outlineView:(NSOutlineView *)outlineView shouldCollapseItem:(id)item +{ + return !([item isUncollapsible]); +} + +- (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item +{ + [cell setTransparent:[item isUncollapsible]]; +} + +- (void)populateList +{ + PBSourceViewItem *actions = [PBSourceViewItem groupItemWithTitle:@"Actions"]; + + PBSourceViewItem *branches = [PBSourceViewItem groupItemWithTitle:@"Branches"]; + PBSourceViewItem *remotes = [PBSourceViewItem groupItemWithTitle:@"Remotes"]; + PBSourceViewItem *tags = [PBSourceViewItem groupItemWithTitle:@"Tags"]; + PBSourceViewItem *custom = [PBSourceViewItem groupItemWithTitle:@"Custom"]; + + for (PBGitRevSpecifier *rev in repository.branches) + { + if (![rev isSimpleRef]) + [custom addChild:[PBSourceViewItem itemWithRevSpec:rev]]; + else if ([[rev simpleRef] hasPrefix:@"refs/heads/"]) + [branches addChild:[PBSourceViewItem itemWithRevSpec:rev]]; + else if ([[rev simpleRef] hasPrefix:@"refs/tags/"]) + [tags addChild:[PBSourceViewItem itemWithRevSpec:rev]]; + else if ([[rev simpleRef] hasPrefix:@"refs/remotes/"]) + [remotes addChild:[PBSourceViewItem itemWithRevSpec:rev]]; + + } + + [items addObject:actions]; + + [items addObject:branches]; + [items addObject:remotes]; + [items addObject:tags]; + [items addObject:custom]; + + [sourceView reloadData]; + [sourceView expandItem:branches expandChildren:YES]; + [sourceView expandItem:actions]; + + NSAssert(actions == [sourceView itemAtRow:0], @"First item is not the Action"); + [sourceView reloadItem:nil reloadChildren:YES]; + +} + +#pragma mark NSOutlineView Datasource methods + +- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item +{ + if (!item) + return [items objectAtIndex:index]; + + return [[(PBSourceViewItem *)item children] objectAtIndex:index]; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item +{ + return [[(PBSourceViewItem *)item children] count]; +} + +- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item +{ + if (!item) + return [items count]; + + return [[(PBSourceViewItem *)item children] count]; +} + +- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item +{ + return [(PBSourceViewItem *)item title]; } @end diff --git a/PBSourceViewItem.h b/PBSourceViewItem.h index 3b722c7..5825bc8 100644 --- a/PBSourceViewItem.h +++ b/PBSourceViewItem.h @@ -8,13 +8,25 @@ #import +@class PBGitRevSpecifier; @interface PBSourceViewItem : NSObject { - NSString *name; + NSMutableArray *children; + + NSString *title; + PBGitRevSpecifier *revSpecifier; + + BOOL isGroupItem; } -- (id)initWithName:(NSString *)name; ++ (PBSourceViewItem *)groupItemWithTitle:(NSString *)title; ++ (PBSourceViewItem *)itemWithRevSpec:(PBGitRevSpecifier *)revSpecifier; + +- (void)addChild:(PBSourceViewItem *)child; + +@property(retain) NSString *title; +@property(readonly) NSMutableArray *children; +@property(assign) BOOL isGroupItem; +@property(retain) PBGitRevSpecifier *revSpecifier; -@property(retain) NSString *name; -@property(readonly) NSArray *children; @end diff --git a/PBSourceViewItem.m b/PBSourceViewItem.m index 8629a50..dfbd7de 100644 --- a/PBSourceViewItem.m +++ b/PBSourceViewItem.m @@ -7,23 +7,47 @@ // #import "PBSourceViewItem.h" - +#import "PBGitRevSpecifier.h" @implementation PBSourceViewItem -@synthesize name; -@dynamic children; +@synthesize title, isGroupItem, children, revSpecifier; -- (id)initWithName:(NSString *)aName +- (id)init { if (!(self = [super init])) return nil; - name = aName; + children = [NSMutableArray array]; return self; } -- (NSArray *)children ++ (PBSourceViewItem *)groupItemWithTitle:(NSString *)title { - return [NSArray array]; + PBSourceViewItem *item = [[PBSourceViewItem alloc] init]; + item.title = title; + item.isGroupItem = YES; + return item; } + ++ (PBSourceViewItem *)itemWithRevSpec:(PBGitRevSpecifier *)revSpecifier +{ + PBSourceViewItem *item = [[PBSourceViewItem alloc] init]; + item.revSpecifier = revSpecifier; + + return item; +} + +- (void)addChild:(PBSourceViewItem *)child +{ + [self.children addObject:child]; +} + +- (NSString *)title +{ + if (title) + return title; + + return [revSpecifier description]; +} + @end From bff93631d53af130d32ec2ec993e044c64981c61 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Tue, 8 Sep 2009 14:23:14 +0200 Subject: [PATCH 003/451] SideBar: Add branches as children This makes a nice tree, which should be more readable than the existing list. The local branches are expanded by default. --- PBGitSidebarController.m | 13 ++++++++----- PBSourceViewItem.h | 6 ++++++ PBSourceViewItem.m | 31 ++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m index e8ca450..5bb4854 100644 --- a/PBGitSidebarController.m +++ b/PBGitSidebarController.m @@ -78,14 +78,17 @@ for (PBGitRevSpecifier *rev in repository.branches) { - if (![rev isSimpleRef]) + if (![rev isSimpleRef]) { [custom addChild:[PBSourceViewItem itemWithRevSpec:rev]]; - else if ([[rev simpleRef] hasPrefix:@"refs/heads/"]) - [branches addChild:[PBSourceViewItem itemWithRevSpec:rev]]; + continue; + } + NSArray *pathComponents = [[rev simpleRef] componentsSeparatedByString:@"/"]; + if ([[pathComponents objectAtIndex:1] isEqualToString:@"heads"]) + [branches addRev:rev toPath:[pathComponents subarrayWithRange:NSMakeRange(2, [pathComponents count] - 2)]]; else if ([[rev simpleRef] hasPrefix:@"refs/tags/"]) - [tags addChild:[PBSourceViewItem itemWithRevSpec:rev]]; + [tags addRev:rev toPath:[pathComponents subarrayWithRange:NSMakeRange(2, [pathComponents count] - 2)]]; else if ([[rev simpleRef] hasPrefix:@"refs/remotes/"]) - [remotes addChild:[PBSourceViewItem itemWithRevSpec:rev]]; + [remotes addRev:rev toPath:[pathComponents subarrayWithRange:NSMakeRange(2, [pathComponents count] - 2)]]; } diff --git a/PBSourceViewItem.h b/PBSourceViewItem.h index 5825bc8..c6d5f4e 100644 --- a/PBSourceViewItem.h +++ b/PBSourceViewItem.h @@ -21,9 +21,15 @@ + (PBSourceViewItem *)groupItemWithTitle:(NSString *)title; + (PBSourceViewItem *)itemWithRevSpec:(PBGitRevSpecifier *)revSpecifier; ++ (PBSourceViewItem *)itemWithTitle:(NSString *)title; - (void)addChild:(PBSourceViewItem *)child; +// This adds the ref to the path, which should match the item's title, +// so "refs/heads/pu/pb/sidebar" would have the path [@"pu", @"pb", @"sidebare"] +// to the 'local' branch thing +- (void)addRev:(PBGitRevSpecifier *)revSpecifier toPath:(NSArray *)path; + @property(retain) NSString *title; @property(readonly) NSMutableArray *children; @property(assign) BOOL isGroupItem; diff --git a/PBSourceViewItem.m b/PBSourceViewItem.m index dfbd7de..cd11084 100644 --- a/PBSourceViewItem.m +++ b/PBSourceViewItem.m @@ -37,17 +37,46 @@ return item; } ++ (PBSourceViewItem *)itemWithTitle:(NSString *)title; +{ + PBSourceViewItem *item = [[PBSourceViewItem alloc] init]; + item.title = title; + return item; +} + - (void)addChild:(PBSourceViewItem *)child { [self.children addObject:child]; } +- (void)addRev:(PBGitRevSpecifier *)theRevSpecifier toPath:(NSArray *)path +{ + if ([path count] == 1) { + PBSourceViewItem *item = [PBSourceViewItem itemWithRevSpec:theRevSpecifier]; + [self addChild:item]; + return; + } + + NSString *firstTitle = [path objectAtIndex:0]; + PBSourceViewItem *node = nil; + for (PBSourceViewItem *child in [self children]) + if ([child.title isEqualToString:firstTitle]) + node = child; + + if (!node) { + node = [PBSourceViewItem itemWithTitle:firstTitle]; + [self addChild:node]; + } + + [node addRev:theRevSpecifier toPath:[path subarrayWithRange:NSMakeRange(1, [path count] - 1)]]; +} + - (NSString *)title { if (title) return title; - return [revSpecifier description]; + return [[revSpecifier description] lastPathComponent]; } @end From ca479c79e95cdbaaef00b08dd3ec5b205a3e0145 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Tue, 8 Sep 2009 14:50:20 +0200 Subject: [PATCH 004/451] Sidebar: display a custom icon These are based on a contribution by Vincent Esche, but we'll probably have to change them a bit. --- GitX.xcodeproj/project.pbxproj | 16 ++++++++++++++++ Images/branch.tiff | Bin 0 -> 4418 bytes Images/folder.tiff | Bin 0 -> 4418 bytes Images/remote.tiff | Bin 0 -> 4418 bytes Images/tag.tiff | Bin 0 -> 4418 bytes PBGitSidebarController.m | 5 +---- PBSourceViewItem.h | 5 ++++- PBSourceViewItem.m | 20 +++++++++++++++++++- 8 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 Images/branch.tiff create mode 100644 Images/folder.tiff create mode 100644 Images/remote.tiff create mode 100644 Images/tag.tiff diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index a07e078..11fb6a7 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -96,6 +96,10 @@ F58DB55910566D3500CFDF4A /* PBGitSidebarController.m in Sources */ = {isa = PBXBuildFile; fileRef = F58DB55810566D3500CFDF4A /* PBGitSidebarController.m */; }; F58DB56010566E3900CFDF4A /* PBGitSidebarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F58DB55F10566E3900CFDF4A /* PBGitSidebarView.xib */; }; F58DB5E8105671B600CFDF4A /* PBSourceViewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = F58DB5E7105671B600CFDF4A /* PBSourceViewItem.m */; }; + F58DB7711056860900CFDF4A /* branch.tiff in Resources */ = {isa = PBXBuildFile; fileRef = F58DB76D1056860900CFDF4A /* branch.tiff */; }; + F58DB7721056860900CFDF4A /* remote.tiff in Resources */ = {isa = PBXBuildFile; fileRef = F58DB76E1056860900CFDF4A /* remote.tiff */; }; + F58DB7731056860900CFDF4A /* folder.tiff in Resources */ = {isa = PBXBuildFile; fileRef = F58DB76F1056860900CFDF4A /* folder.tiff */; }; + F58DB7741056860900CFDF4A /* tag.tiff in Resources */ = {isa = PBXBuildFile; fileRef = F58DB7701056860900CFDF4A /* tag.tiff */; }; F59116E60E843BB50072CCB1 /* PBGitCommitView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F59116E50E843BB50072CCB1 /* PBGitCommitView.xib */; }; F59116E90E843BCB0072CCB1 /* PBGitCommitController.m in Sources */ = {isa = PBXBuildFile; fileRef = F59116E80E843BCB0072CCB1 /* PBGitCommitController.m */; }; F593DF780E9E636C003A8559 /* PBFileChangesTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = F593DF770E9E636C003A8559 /* PBFileChangesTableView.m */; }; @@ -251,6 +255,10 @@ F58DB55F10566E3900CFDF4A /* PBGitSidebarView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PBGitSidebarView.xib; sourceTree = ""; }; F58DB5E6105671B600CFDF4A /* PBSourceViewItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBSourceViewItem.h; sourceTree = ""; }; F58DB5E7105671B600CFDF4A /* PBSourceViewItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBSourceViewItem.m; sourceTree = ""; }; + F58DB76D1056860900CFDF4A /* branch.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = branch.tiff; path = Images/branch.tiff; sourceTree = ""; }; + F58DB76E1056860900CFDF4A /* remote.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = remote.tiff; path = Images/remote.tiff; sourceTree = ""; }; + F58DB76F1056860900CFDF4A /* folder.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = folder.tiff; path = Images/folder.tiff; sourceTree = ""; }; + F58DB7701056860900CFDF4A /* tag.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = tag.tiff; path = Images/tag.tiff; sourceTree = ""; }; F59116E50E843BB50072CCB1 /* PBGitCommitView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PBGitCommitView.xib; sourceTree = ""; }; F59116E70E843BCB0072CCB1 /* PBGitCommitController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitCommitController.h; sourceTree = ""; }; F59116E80E843BCB0072CCB1 /* PBGitCommitController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitCommitController.m; sourceTree = ""; }; @@ -394,6 +402,10 @@ 29B97315FDCFA39411CA2CEA /* Other Sources */ = { isa = PBXGroup; children = ( + F58DB76D1056860900CFDF4A /* branch.tiff */, + F58DB76E1056860900CFDF4A /* remote.tiff */, + F58DB76F1056860900CFDF4A /* folder.tiff */, + F58DB7701056860900CFDF4A /* tag.tiff */, 3BC07F4A0ED5A5C5009A7768 /* HistoryViewTemplate.png */, 3BC07F4B0ED5A5C5009A7768 /* CommitViewTemplate.png */, F56ADDD70ED19F9E002AC78F /* AddBranchTemplate.png */, @@ -765,6 +777,10 @@ 47DBDBB10E94F6CA00671A1E /* Updates.png in Resources */, F569AE930F2CBD7C00C2FFA7 /* Credits.html in Resources */, F58DB56010566E3900CFDF4A /* PBGitSidebarView.xib in Resources */, + F58DB7711056860900CFDF4A /* branch.tiff in Resources */, + F58DB7721056860900CFDF4A /* remote.tiff in Resources */, + F58DB7731056860900CFDF4A /* folder.tiff in Resources */, + F58DB7741056860900CFDF4A /* tag.tiff in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Images/branch.tiff b/Images/branch.tiff new file mode 100644 index 0000000000000000000000000000000000000000..dc35b5b8ded3e2bbfb65f98445b79ffe4a030184 GIT binary patch literal 4418 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 literal 0 HcmV?d00001 diff --git a/Images/folder.tiff b/Images/folder.tiff new file mode 100644 index 0000000000000000000000000000000000000000..c6a7b144c9425d22b7a15dea5c8687cc4bc3b859 GIT binary patch literal 4418 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 J0TzK_{{R7CC!zoV literal 0 HcmV?d00001 diff --git a/Images/remote.tiff b/Images/remote.tiff new file mode 100644 index 0000000000000000000000000000000000000000..24f81d4c16d34d8b421ced13ed1f38dcec172848 GIT binary patch literal 4418 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 literal 0 HcmV?d00001 diff --git a/Images/tag.tiff b/Images/tag.tiff new file mode 100644 index 0000000000000000000000000000000000000000..0532a45d36fff7722b88d229d025c93bdfcacb09 GIT binary patch literal 4418 zcmbuB2|SeB8^_Q4&Wf?lShI|EEZM^#WnV(pD5)?rm@qW9v{F)0DM>;^Qqtw#x+qtY zwMCQ)l|rtI>XsI1fB)|g&AtEI{r^Arp81^fe&6RjzjL1RoO5Qz-5qEHfF&j;Cxd@m z!QT`we|Pm4$fKnGr=6DC^J#zZoSpX%M!pw&XB+(o6U~qMCTft!?^@p;DoXdlVzF}` zf2ZeZ@4svu=zehqxjtHkbc~%qe*N4!m2)h^3x~r^kMTXdy|cA`??l}|$Ft)|+ejhO zK2n6%LX-=Tp-+ud2l97%5QqfuS9+fI_V3jLZDYAeK^Txt~LFsNcr6uq_D>yIo`$TQ&Lf& z@auWnYhxz|st1yhs=iIgPxrSXm3Y+ydl zXk7YgbG-?&rQQtL{EI2Fy_t?2x)S(bT7LcZqVTL^H#y@9O7aRm;a1VR+H8@eS|em@ zgDH~Lw(>8v{CZBBe|&Kt`^$l2DM8sk$DK&3Ge$OFG)4Bed|%72SJ9NGrIaskE9*&| z%)1f#Ci9BljB7@lVIx?%4_n6Gx!8Nz>M7-ez5yN;+85FrUZAIYzb_CiuKOyoIA z&-!BlBnNoc5Y=KIL-XeN2_(-qj^!uM~y|D zc>J}XF~9AZ9vs}(b@rrEXFLASr#K^q8;3^ciTWEeS+NY1Q&EmgjEmvfCs3w@MDQ5q z<(I-m14LPd$6+%(f7)k;t$ECh;xJJkUd%DfC?=0vP~Mdg&q5jFhH_d0o0W+29hB7~ z71om=O`oWm4^;qhf+NNdU~OnWq90yxdaJB%2zVo0{qx z>7nVLD}UQL=k@o%+uIqB*Iv_m21#{%vwhQkvqhHxK%Yc&v;UhdgzYl!#>G9^9%N^C86&f5L z8As(Ml@T2o9nYo4#so81RNX%x;(sjU3yUv~`QEHh7MI0Ar}9Hj8JiP^Za0U?j$=o2 zsBF&ncK9F4_+sGU%(+H^T>1r2*60DTE(*Z>-T|;=A%F=iM0=pQeRC7=1H7B(uQWPy z?omejr`ta?a3=Z+$FjqyJhPp*FO?C`P2e$lCwL7G2m(<+0kS|5r~*x(3ygpnumsk? z0W1L?z!$6ls{sRqgDAiSiC_~*0cjuu><5QH9w-8(pd3_!v!E8#gUg@|Tn9J7UGM-5 zf)Vf(On|rGBLqPNNEjkRvXBy_4(UKf5FJ_sIY4fZH?#r@g2EsU6c25JwnG_E7L*4S zL*>v<&;{r+bQQV<-Ghdpap)EF0mi^2m;x)n8n8Z0hizb2*cV;}hr#RM4R9*F56*>4 z;4^Ryd>OtD--QR^r|=~Dr7wh$!YE^OF?5U_#sd?83B_tn1$K1vY zVxD2%WARurmWtKIT4J5C%diaWI_wtg9&8@=6t)K2g1wC$!cJhn;DmAVI31h?&IPv| z7lup3rQvdLWw>fwEAB3C1osyG6_mo$@Md^t{0jV9{6_p9{84-rz7c;5Ka8Iw5D2ma z9fB3XgAh!JBcu_I5Y7-T5xNN@gm*+Cq7u=F=tvA8a){fAImFY%24XjHl=x9VOh8@0 zLcl|SDUc+PDNrgvh_?QGiLPNqqf+>+Iaa^KVVwj8}tCH==4DxnzDY=zALcvpL z6c@@`N(SWzN+)GPQbKZpq@Uz^$$ZI+l7mthDGezXsYt0zsk2f&QXixhq-~^G(z~TA zrMso4Wai0O%dlk9WvXQE%6yQe$~wqK$R3cbm3=6OmD85QJq`!ar4dRbLN-K@6{#g+UO?eR_G4tN$I)i zZPTmOd#(8!?RXjqVr=8#@|rH9l|r za)HhQ)`G$XeI{fRcaxnaO(vgB%}lwbm8RonYGy%Z1!lc;3f+^whknHzXKri0)x6&P zy@jbooW)s-7nZt~5tgSd#}?8SvKE#u9JW%i3brb?8eBwO6tw8rqQS+=i-Q-JEPiaQ zYR$ARvmUk4vRP|$#^$-Lfi2gz+IGs$!fvx&qdmsn$v)k_(?P;vnM0n#BS#g-FvkkV z2`3Y$jZTfuIA>Sq1J1oJ3N8$na+irEW=l3NX>ldF`ncw~K6cY~{~^G`t76Z`QP4kA9r2p+JK~2D7A52-yi4>; zJhxtaJ!gGKl6KPWq|ptI8%}J*Ze(n1+N8WGWz*1Ro6W^rpe-R=nzpKLP2D<@?38>e zMKC2I<;FIHZCTsiZ1>+@m#UDOoI1S2X-7qxNE$b-cc|LF^jdvf}{Ux25 zel5cwBPZk29>$()dky#I?nU;6?(57n%`DuH-_P0Kb71j-Q(59!8?uHEx*x2`re>#S zzd5w#(AAs;IYoyB562%K%yr8>e?;xb{v)6A!t?It+vZml$QSG`m^#Wl+FfW}SXrb{ zlu`8I82eaXu~TtPiAG7zas2UwqmA0RtpC~VrE6XVRe3El=@RawdmU6T5^3(FC zGb`YV_=@o}foE?1VE@DUO5MuhDygcBAHk3DKR)>>=%=2uu4kLh(a%->tp0OBHMu&y z2C7M_nWzn~9X!9{{H+U1E;Q9y)>Z$a_shw8<@)@Kk{2@@1RGKtkV_jbO*Y0fKD!)t zdAMm!(}U*a&39V7S~^=@Td%Y^wl%lgv|qYnb*28Q#nlVf=+|nmn_jQ!FzKkiVRECo z)3mdu%dG4CP4k;|w-(-N=w94?`L_M-wmU9&uHRjH_g2rcp1$6|-oZX*-`Ks#doS-N z-2eC>xgXb`{!r{;&LjCpB?DRmRfDF37l-VJIv)ExelW}!e)?FRoJxNu`|i|x`up||{vSp^CVnD(%KfbMx$cYWmwqG)LH+|*7<}dc literal 0 HcmV?d00001 diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m index 5bb4854..097aade 100644 --- a/PBGitSidebarController.m +++ b/PBGitSidebarController.m @@ -42,10 +42,7 @@ - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item { - if ([item isGroupItem]) - [cell setImage:nil]; - else - [cell setImage:[NSImage imageNamed:@"new_file"]]; + [cell setImage:[item icon]]; } - (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item diff --git a/PBSourceViewItem.h b/PBSourceViewItem.h index c6d5f4e..8b1c160 100644 --- a/PBSourceViewItem.h +++ b/PBSourceViewItem.h @@ -15,6 +15,7 @@ NSString *title; PBGitRevSpecifier *revSpecifier; + PBSourceViewItem *parent; BOOL isGroupItem; } @@ -30,9 +31,11 @@ // to the 'local' branch thing - (void)addRev:(PBGitRevSpecifier *)revSpecifier toPath:(NSArray *)path; +- (NSImage *)icon; + @property(retain) NSString *title; @property(readonly) NSMutableArray *children; @property(assign) BOOL isGroupItem; @property(retain) PBGitRevSpecifier *revSpecifier; - +@property(retain) PBSourceViewItem *parent; @end diff --git a/PBSourceViewItem.m b/PBSourceViewItem.m index cd11084..2f3b416 100644 --- a/PBSourceViewItem.m +++ b/PBSourceViewItem.m @@ -10,7 +10,7 @@ #import "PBGitRevSpecifier.h" @implementation PBSourceViewItem -@synthesize title, isGroupItem, children, revSpecifier; +@synthesize parent, title, isGroupItem, children, revSpecifier; - (id)init { @@ -47,6 +47,7 @@ - (void)addChild:(PBSourceViewItem *)child { [self.children addObject:child]; + child.parent = self; } - (void)addRev:(PBGitRevSpecifier *)theRevSpecifier toPath:(NSArray *)path @@ -79,4 +80,21 @@ return [[revSpecifier description] lastPathComponent]; } +- (NSImage *)icon +{ + if ([self isGroupItem]) + return nil; + + if (self.parent && !self.parent.parent && [self.parent.title isEqualToString:@"Remotes"]) + return [NSImage imageNamed:@"remote"]; + + if (self.parent && !self.parent.parent && [self.parent.title isEqualToString:@"Tags"]) + return [NSImage imageNamed:@"tag"]; + + if ([[self children] count]) + return [NSImage imageNamed:@"folder"]; + + return [NSImage imageNamed:@"branch"]; +} + @end From 23d5c01a3da9d63919a84f32ebf59fb2002823c6 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Thu, 10 Sep 2009 01:18:12 +0200 Subject: [PATCH 005/451] Sidebar: hook up branch switching This is far from perfect, but at least you can use it to navigate the stuff a bit now :) --- GitX.xcodeproj/project.pbxproj | 6 ++++++ NSOutlineViewExt.h | 15 ++++++++++++++ NSOutlineViewExt.m | 25 +++++++++++++++++++++++ PBGitSidebarController.m | 36 ++++++++++++++++++++++++++++++++++ PBSourceViewItem.h | 1 + PBSourceViewItem.m | 13 ++++++++++++ 6 files changed, 96 insertions(+) create mode 100644 NSOutlineViewExt.h create mode 100644 NSOutlineViewExt.m diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index 11fb6a7..235b8ae 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -65,6 +65,7 @@ F56524F00E02D45200F03B52 /* PBGitCommit.m in Sources */ = {isa = PBXBuildFile; fileRef = F56524EF0E02D45200F03B52 /* PBGitCommit.m */; }; F56526240E03D85900F03B52 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F56526230E03D85900F03B52 /* WebKit.framework */; }; F565262B0E03D89B00F03B52 /* PBWebHistoryController.m in Sources */ = {isa = PBXBuildFile; fileRef = F565262A0E03D89B00F03B52 /* PBWebHistoryController.m */; }; + F567B88D1057FA9F000DB976 /* NSOutlineViewExt.m in Sources */ = {isa = PBXBuildFile; fileRef = F567B88C1057FA9F000DB976 /* NSOutlineViewExt.m */; }; F569AE930F2CBD7C00C2FFA7 /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = F569AE920F2CBD7C00C2FFA7 /* Credits.html */; }; F56ADDD90ED19F9E002AC78F /* AddBranchTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = F56ADDD70ED19F9E002AC78F /* AddBranchTemplate.png */; }; F56ADDDA0ED19F9E002AC78F /* AddLabelTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = F56ADDD80ED19F9E002AC78F /* AddLabelTemplate.png */; }; @@ -233,6 +234,8 @@ F56526230E03D85900F03B52 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = /System/Library/Frameworks/WebKit.framework; sourceTree = ""; }; F56526290E03D89B00F03B52 /* PBWebHistoryController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBWebHistoryController.h; sourceTree = ""; }; F565262A0E03D89B00F03B52 /* PBWebHistoryController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBWebHistoryController.m; sourceTree = ""; }; + F567B88B1057FA9F000DB976 /* NSOutlineViewExt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSOutlineViewExt.h; sourceTree = ""; }; + F567B88C1057FA9F000DB976 /* NSOutlineViewExt.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSOutlineViewExt.m; sourceTree = ""; }; F569AE920F2CBD7C00C2FFA7 /* Credits.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = Credits.html; sourceTree = ""; }; F56ADDD70ED19F9E002AC78F /* AddBranchTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AddBranchTemplate.png; path = Images/AddBranchTemplate.png; sourceTree = ""; }; F56ADDD80ED19F9E002AC78F /* AddLabelTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AddLabelTemplate.png; path = Images/AddLabelTemplate.png; sourceTree = ""; }; @@ -559,6 +562,8 @@ EB2A73490FEE3F09006601CF /* PBCollapsibleSplitView.m */, F5FC41F20EBCBD4300191D80 /* PBGitXProtocol.h */, F5FC41F30EBCBD4300191D80 /* PBGitXProtocol.m */, + F567B88B1057FA9F000DB976 /* NSOutlineViewExt.h */, + F567B88C1057FA9F000DB976 /* NSOutlineViewExt.m */, ); name = Aux; sourceTree = ""; @@ -894,6 +899,7 @@ EB2A734A0FEE3F09006601CF /* PBCollapsibleSplitView.m in Sources */, F58DB55910566D3500CFDF4A /* PBGitSidebarController.m in Sources */, F58DB5E8105671B600CFDF4A /* PBSourceViewItem.m in Sources */, + F567B88D1057FA9F000DB976 /* NSOutlineViewExt.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/NSOutlineViewExt.h b/NSOutlineViewExt.h new file mode 100644 index 0000000..64c0186 --- /dev/null +++ b/NSOutlineViewExt.h @@ -0,0 +1,15 @@ +// +// NSOutlineViewExit.h +// GitX +// +// Created by Pieter de Bie on 9/9/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface NSOutlineView (PBExpandParents) + +- (void)PBExpandItem:(id)item expandParents:(BOOL)expand; +@end diff --git a/NSOutlineViewExt.m b/NSOutlineViewExt.m new file mode 100644 index 0000000..57531f8 --- /dev/null +++ b/NSOutlineViewExt.m @@ -0,0 +1,25 @@ +// +// NSOutlineViewExit.m +// GitX +// +// Created by Pieter de Bie on 9/9/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "NSOutlineViewExt.h" + + +@implementation NSOutlineView (PBExpandParents) + +- (void)PBExpandItem:(id)item expandParents:(BOOL)expand +{ + NSMutableArray *parents = [NSMutableArray array]; + while (item) { + [parents insertObject:item atIndex:0]; + item = [item parent]; + } + + for (id p in parents) + [self expandItem:p]; +} +@end diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m index 097aade..6e5bd43 100644 --- a/PBGitSidebarController.m +++ b/PBGitSidebarController.m @@ -8,10 +8,12 @@ #import "PBGitSidebarController.h" #import "PBSourceViewItem.h" +#import "NSOutlineViewExt.h" @interface PBGitSidebarController () - (void)populateList; +- (void)updateSelection; @end @@ -32,8 +34,42 @@ [super awakeFromNib]; window.contentView = self.view; [self populateList]; + + [repository addObserver:self forKeyPath:@"currentBranch" options:0 context:@"currentBranchChange"]; + [self updateSelection]; } +- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if ([@"currentBranchChange" isEqualTo:context]) + [self updateSelection]; +} + +- (void)updateSelection +{ + PBGitRevSpecifier *rev = repository.currentBranch; + if (!rev) + return; + + PBSourceViewItem *item = nil; + for (PBSourceViewItem *it in items) + if (item = [it findRev:rev]) + break; + + // TODO: We should add the current branch, or something :) + + if (!item) { + [sourceView deselectAll:self]; + return; + } + + [sourceView PBExpandItem:item expandParents:YES]; + NSInteger index = [sourceView rowForItem:item]; + + [sourceView selectRow:index byExtendingSelection:NO]; +} + + #pragma mark NSOutlineView delegate methods - (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item { diff --git a/PBSourceViewItem.h b/PBSourceViewItem.h index 8b1c160..13e0e08 100644 --- a/PBSourceViewItem.h +++ b/PBSourceViewItem.h @@ -30,6 +30,7 @@ // so "refs/heads/pu/pb/sidebar" would have the path [@"pu", @"pb", @"sidebare"] // to the 'local' branch thing - (void)addRev:(PBGitRevSpecifier *)revSpecifier toPath:(NSArray *)path; +- (PBSourceViewItem *)findRev:(PBGitRevSpecifier *)rev; - (NSImage *)icon; diff --git a/PBSourceViewItem.m b/PBSourceViewItem.m index 2f3b416..b5a28df 100644 --- a/PBSourceViewItem.m +++ b/PBSourceViewItem.m @@ -72,6 +72,19 @@ [node addRev:theRevSpecifier toPath:[path subarrayWithRange:NSMakeRange(1, [path count] - 1)]]; } +- (PBSourceViewItem *)findRev:(PBGitRevSpecifier *)rev +{ + if (rev == revSpecifier) + return self; + + PBSourceViewItem *item = nil; + for (PBSourceViewItem *child in children) + if (item = [child findRev:rev]) + return item; + + return nil; +} + - (NSString *)title { if (title) From c59d68bb3ec415880b3186e77990ba08428602e6 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Thu, 10 Sep 2009 01:42:13 +0200 Subject: [PATCH 006/451] Sidebar: Handle selection changes --- PBGitSidebarController.m | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m index 6e5bd43..6fbf58c 100644 --- a/PBGitSidebarController.m +++ b/PBGitSidebarController.m @@ -69,6 +69,21 @@ [sourceView selectRow:index byExtendingSelection:NO]; } +#pragma mark NSOutlineView delegate methods + +- (void)outlineViewSelectionDidChange:(NSNotification *)notification +{ + NSInteger index = [sourceView selectedRow]; + PBSourceViewItem *item = [sourceView itemAtRow:index]; + + if ([item revSpecifier]) { + [[repository windowController] showHistoryView:self]; + repository.currentBranch = [item revSpecifier]; + return; + } + + /* Handle Remotes etc */ +} #pragma mark NSOutlineView delegate methods - (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item From fb3a1705e35f7948d6dd65d429f754b032a4d47b Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Tue, 8 Sep 2009 17:11:20 +0200 Subject: [PATCH 007/451] SideBar: Add ViewAction and ViewRemote objects These two new classes can represent items in our SourceList that refer to specific actions (such as comitting), or specific Remotes. --- GitX.xcodeproj/project.pbxproj | 12 ++++++++++++ PBSourceViewAction.h | 17 +++++++++++++++++ PBSourceViewAction.m | 15 +++++++++++++++ PBSourceViewItem.h | 6 +++--- PBSourceViewItem.m | 12 ++++++------ PBSourceViewRemote.h | 16 ++++++++++++++++ PBSourceViewRemote.m | 18 ++++++++++++++++++ 7 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 PBSourceViewAction.h create mode 100644 PBSourceViewAction.m create mode 100644 PBSourceViewRemote.h create mode 100644 PBSourceViewRemote.m diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index 235b8ae..b90117e 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -52,6 +52,8 @@ F513085B0E0740F2000C8BCD /* PBQLOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = F513085A0E0740F2000C8BCD /* PBQLOutlineView.m */; }; F5140DC90E8A8EB20091E9F3 /* RoundedRectangle.m in Sources */ = {isa = PBXBuildFile; fileRef = F5140DC80E8A8EB20091E9F3 /* RoundedRectangle.m */; }; F523CEB60ED3399200DDD714 /* PBGitIndexController.m in Sources */ = {isa = PBXBuildFile; fileRef = F523CEB50ED3399200DDD714 /* PBGitIndexController.m */; }; + F528210A1056A7C1001D1511 /* PBSourceViewRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = F52821091056A7C1001D1511 /* PBSourceViewRemote.m */; }; + F528210D1056A7EB001D1511 /* PBSourceViewAction.m in Sources */ = {isa = PBXBuildFile; fileRef = F528210C1056A7EB001D1511 /* PBSourceViewAction.m */; }; F52BCE030E84208300AA3741 /* PBGitHistoryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F52BCE020E84208300AA3741 /* PBGitHistoryView.xib */; }; F52BCE070E84211300AA3741 /* PBGitHistoryController.m in Sources */ = {isa = PBXBuildFile; fileRef = F52BCE060E84211300AA3741 /* PBGitHistoryController.m */; }; F53C4DF70E97FC630022AD59 /* PBGitBinary.m in Sources */ = {isa = PBXBuildFile; fileRef = F53C4DF60E97FC630022AD59 /* PBGitBinary.m */; }; @@ -213,6 +215,10 @@ F5140DC80E8A8EB20091E9F3 /* RoundedRectangle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoundedRectangle.m; sourceTree = ""; }; F523CEB40ED3399100DDD714 /* PBGitIndexController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitIndexController.h; sourceTree = ""; }; F523CEB50ED3399200DDD714 /* PBGitIndexController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitIndexController.m; sourceTree = ""; }; + F52821081056A7C1001D1511 /* PBSourceViewRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBSourceViewRemote.h; sourceTree = ""; }; + F52821091056A7C1001D1511 /* PBSourceViewRemote.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBSourceViewRemote.m; sourceTree = ""; }; + F528210B1056A7EB001D1511 /* PBSourceViewAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBSourceViewAction.h; sourceTree = ""; }; + F528210C1056A7EB001D1511 /* PBSourceViewAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBSourceViewAction.m; sourceTree = ""; }; F52BCE020E84208300AA3741 /* PBGitHistoryView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PBGitHistoryView.xib; sourceTree = ""; }; F52BCE050E84211300AA3741 /* PBGitHistoryController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitHistoryController.h; sourceTree = ""; }; F52BCE060E84211300AA3741 /* PBGitHistoryController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitHistoryController.m; sourceTree = ""; }; @@ -583,6 +589,10 @@ F58DB55810566D3500CFDF4A /* PBGitSidebarController.m */, F58DB5E6105671B600CFDF4A /* PBSourceViewItem.h */, F58DB5E7105671B600CFDF4A /* PBSourceViewItem.m */, + F52821081056A7C1001D1511 /* PBSourceViewRemote.h */, + F52821091056A7C1001D1511 /* PBSourceViewRemote.m */, + F528210B1056A7EB001D1511 /* PBSourceViewAction.h */, + F528210C1056A7EB001D1511 /* PBSourceViewAction.m */, ); name = Sidebar; sourceTree = ""; @@ -900,6 +910,8 @@ F58DB55910566D3500CFDF4A /* PBGitSidebarController.m in Sources */, F58DB5E8105671B600CFDF4A /* PBSourceViewItem.m in Sources */, F567B88D1057FA9F000DB976 /* NSOutlineViewExt.m in Sources */, + F528210A1056A7C1001D1511 /* PBSourceViewRemote.m in Sources */, + F528210D1056A7EB001D1511 /* PBSourceViewAction.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PBSourceViewAction.h b/PBSourceViewAction.h new file mode 100644 index 0000000..763d254 --- /dev/null +++ b/PBSourceViewAction.h @@ -0,0 +1,17 @@ +// +// PBSourceViewAction.h +// GitX +// +// Created by Pieter de Bie on 9/8/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import +#import "PBSourceViewItem.h" + +@interface PBSourceViewAction : PBSourceViewItem { + NSImage *icon; +} + +@property(retain) NSImage *icon; +@end diff --git a/PBSourceViewAction.m b/PBSourceViewAction.m new file mode 100644 index 0000000..344b967 --- /dev/null +++ b/PBSourceViewAction.m @@ -0,0 +1,15 @@ +// +// PBSourceViewAction.m +// GitX +// +// Created by Pieter de Bie on 9/8/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "PBSourceViewAction.h" + + +@implementation PBSourceViewAction +@synthesize icon; + +@end diff --git a/PBSourceViewItem.h b/PBSourceViewItem.h index 13e0e08..17b6670 100644 --- a/PBSourceViewItem.h +++ b/PBSourceViewItem.h @@ -20,9 +20,9 @@ BOOL isGroupItem; } -+ (PBSourceViewItem *)groupItemWithTitle:(NSString *)title; -+ (PBSourceViewItem *)itemWithRevSpec:(PBGitRevSpecifier *)revSpecifier; -+ (PBSourceViewItem *)itemWithTitle:(NSString *)title; ++ (id)groupItemWithTitle:(NSString *)title; ++ (id)itemWithRevSpec:(PBGitRevSpecifier *)revSpecifier; ++ (id)itemWithTitle:(NSString *)title; - (void)addChild:(PBSourceViewItem *)child; diff --git a/PBSourceViewItem.m b/PBSourceViewItem.m index b5a28df..bac9099 100644 --- a/PBSourceViewItem.m +++ b/PBSourceViewItem.m @@ -21,25 +21,25 @@ return self; } -+ (PBSourceViewItem *)groupItemWithTitle:(NSString *)title ++ (id)groupItemWithTitle:(NSString *)title { - PBSourceViewItem *item = [[PBSourceViewItem alloc] init]; + PBSourceViewItem *item = [[[self class] alloc] init]; item.title = title; item.isGroupItem = YES; return item; } -+ (PBSourceViewItem *)itemWithRevSpec:(PBGitRevSpecifier *)revSpecifier ++ (id)itemWithRevSpec:(PBGitRevSpecifier *)revSpecifier { - PBSourceViewItem *item = [[PBSourceViewItem alloc] init]; + PBSourceViewItem *item = [[[self class] alloc] init]; item.revSpecifier = revSpecifier; return item; } -+ (PBSourceViewItem *)itemWithTitle:(NSString *)title; ++ (id)itemWithTitle:(NSString *)title; { - PBSourceViewItem *item = [[PBSourceViewItem alloc] init]; + PBSourceViewItem *item = [[[self class] alloc] init]; item.title = title; return item; } diff --git a/PBSourceViewRemote.h b/PBSourceViewRemote.h new file mode 100644 index 0000000..edb5d98 --- /dev/null +++ b/PBSourceViewRemote.h @@ -0,0 +1,16 @@ +// +// PBSourceViewRemote.h +// GitX +// +// Created by Pieter de Bie on 9/8/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import +#import "PBSourceViewItem.h" + +@interface PBSourceViewRemote : PBSourceViewItem { + +} + +@end diff --git a/PBSourceViewRemote.m b/PBSourceViewRemote.m new file mode 100644 index 0000000..b8ccd84 --- /dev/null +++ b/PBSourceViewRemote.m @@ -0,0 +1,18 @@ +// +// PBSourceViewRemote.m +// GitX +// +// Created by Pieter de Bie on 9/8/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "PBSourceViewRemote.h" + + +@implementation PBSourceViewRemote + +- (NSImage *)icon +{ + return [NSImage imageNamed:@"remote"]; +} +@end From 692a79c3ad0bea07e394713bfc75f60e1aaa94c1 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Thu, 10 Sep 2009 01:18:26 +0200 Subject: [PATCH 008/451] Sidebar: Add "Commit" action When this tree leaf is selected, the view switches to the commit view. --- PBGitSidebarController.h | 5 +++++ PBGitSidebarController.m | 15 ++++++++++++++- PBSourceViewItem.h | 3 ++- PBSourceViewItem.m | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/PBGitSidebarController.h b/PBGitSidebarController.h index a2e180c..9f568ac 100644 --- a/PBGitSidebarController.h +++ b/PBGitSidebarController.h @@ -9,11 +9,16 @@ #import #import "PBViewController.h" +@class PBSourceViewAction; + @interface PBGitSidebarController : PBViewController { IBOutlet NSWindow *window; IBOutlet NSOutlineView *sourceView; NSMutableArray *items; + + /* Specific things */ + PBSourceViewAction *commitAction; } @property(readonly) NSMutableArray *items; diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m index 6fbf58c..803a19e 100644 --- a/PBGitSidebarController.m +++ b/PBGitSidebarController.m @@ -9,6 +9,7 @@ #import "PBGitSidebarController.h" #import "PBSourceViewItem.h" #import "NSOutlineViewExt.h" +#import "PBSourceViewAction.h" @interface PBGitSidebarController () @@ -82,7 +83,13 @@ return; } - /* Handle Remotes etc */ + if (item == commitAction) + [[repository windowController] showCommitView:self]; + + /* ... */ + + + /* Handle Remotes */ } #pragma mark NSOutlineView delegate methods @@ -119,6 +126,12 @@ { PBSourceViewItem *actions = [PBSourceViewItem groupItemWithTitle:@"Actions"]; + actions.isUncollapsible = YES; + + commitAction = [PBSourceViewAction itemWithTitle:@"Index / Commit"]; + commitAction.icon = [NSImage imageNamed:@"CommitViewTemplate"]; + [actions addChild:commitAction]; + PBSourceViewItem *branches = [PBSourceViewItem groupItemWithTitle:@"Branches"]; PBSourceViewItem *remotes = [PBSourceViewItem groupItemWithTitle:@"Remotes"]; PBSourceViewItem *tags = [PBSourceViewItem groupItemWithTitle:@"Tags"]; diff --git a/PBSourceViewItem.h b/PBSourceViewItem.h index 17b6670..1748f5a 100644 --- a/PBSourceViewItem.h +++ b/PBSourceViewItem.h @@ -18,6 +18,7 @@ PBSourceViewItem *parent; BOOL isGroupItem; + BOOL isUncollapsible; } + (id)groupItemWithTitle:(NSString *)title; @@ -36,7 +37,7 @@ @property(retain) NSString *title; @property(readonly) NSMutableArray *children; -@property(assign) BOOL isGroupItem; +@property(assign) BOOL isGroupItem, isUncollapsible; @property(retain) PBGitRevSpecifier *revSpecifier; @property(retain) PBSourceViewItem *parent; @end diff --git a/PBSourceViewItem.m b/PBSourceViewItem.m index bac9099..b7f4045 100644 --- a/PBSourceViewItem.m +++ b/PBSourceViewItem.m @@ -10,7 +10,7 @@ #import "PBGitRevSpecifier.h" @implementation PBSourceViewItem -@synthesize parent, title, isGroupItem, children, revSpecifier; +@synthesize parent, title, isGroupItem, children, revSpecifier, isUncollapsible; - (id)init { From ff1d30571b81862951c52b3efc858a693a7f46fb Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 22:44:26 +0200 Subject: [PATCH 009/451] WIP: Move the sidebar to the history view instead I'm not sure what we should do with the commit stuff, but this seems more reasonable --- PBGitHistoryController.h | 3 +++ PBGitHistoryController.m | 14 ++++++++++++++ PBGitWindowController.h | 2 -- PBGitWindowController.m | 4 ---- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/PBGitHistoryController.h b/PBGitHistoryController.h index fadb6cd..586180b 100644 --- a/PBGitHistoryController.h +++ b/PBGitHistoryController.h @@ -12,7 +12,10 @@ #import "PBViewController.h" #import "PBCollapsibleSplitView.h" +@class PBGitSidebarController; + @interface PBGitHistoryController : PBViewController { + PBGitSidebarController *sidebarController; IBOutlet NSSearchField *searchField; IBOutlet NSArrayController* commitController; IBOutlet NSTreeController* treeController; diff --git a/PBGitHistoryController.m b/PBGitHistoryController.m index f8ad04a..10d5098 100644 --- a/PBGitHistoryController.m +++ b/PBGitHistoryController.m @@ -11,6 +11,7 @@ #import "PBGitGrapher.h" #import "PBGitRevisionCell.h" #import "PBCommitList.h" +#import "PBGitSidebarController.h" #define QLPreviewPanel NSClassFromString(@"QLPreviewPanel") @@ -29,6 +30,19 @@ [fileBrowser setTarget:self]; [fileBrowser setDoubleAction:@selector(openSelectedFile:)]; + [historySplitView removeFromSuperview]; + NSSplitView *newView = [[NSSplitView alloc] initWithFrame:[historySplitView frame]]; + + sidebarController = [[PBGitSidebarController alloc] initWithRepository:repository superController:superController]; + [newView setDividerStyle:NSSplitViewDividerStyleThin]; + [newView addSubview:[sidebarController view]]; + [newView addSubview:historySplitView]; + [newView setVertical:YES]; + [newView adjustSubviews]; + [newView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + + [[self view] addSubview:newView]; + if (!repository.currentBranch) { [repository reloadRefs]; [repository readCurrentBranch]; diff --git a/PBGitWindowController.h b/PBGitWindowController.h index 5dcf5e0..0fc969c 100644 --- a/PBGitWindowController.h +++ b/PBGitWindowController.h @@ -20,8 +20,6 @@ PBViewController *commitViewController; PBViewController* viewController; - - PBGitSidebarController *sidebarController; } @property (assign) __weak PBGitRepository *repository; diff --git a/PBGitWindowController.m b/PBGitWindowController.m index 087e3ad..91b95af 100644 --- a/PBGitWindowController.m +++ b/PBGitWindowController.m @@ -29,10 +29,6 @@ else self.selectedViewIndex = -1; - // Sidebar - sidebarController = [[PBGitSidebarController alloc] initWithRepository:repository superController:self]; - // Hack for now - [sidebarController view]; return self; } From 1c3ee96e7c1b27655f6a5cac5c993bd641aa21b7 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 22:46:22 +0200 Subject: [PATCH 010/451] Don't show the Actions menu for now --- PBGitSidebarController.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m index 803a19e..4e779a7 100644 --- a/PBGitSidebarController.m +++ b/PBGitSidebarController.m @@ -153,7 +153,7 @@ } - [items addObject:actions]; + //[items addObject:actions]; [items addObject:branches]; [items addObject:remotes]; @@ -164,7 +164,7 @@ [sourceView expandItem:branches expandChildren:YES]; [sourceView expandItem:actions]; - NSAssert(actions == [sourceView itemAtRow:0], @"First item is not the Action"); + NSAssert(branches == [sourceView itemAtRow:0], @"First item is not the Branches"); [sourceView reloadItem:nil reloadChildren:YES]; } From d05deb95484665d5d465bdc9651ab1b79f13126f Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 23:04:48 +0200 Subject: [PATCH 011/451] PBGitRevSpecifier: tweak "isSimpleRef" a bit For example, HEAD is a simple ref, but "stable..HEAD" isn't. --- PBGitRevSpecifier.m | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/PBGitRevSpecifier.m b/PBGitRevSpecifier.m index ded8575..2865fd7 100644 --- a/PBGitRevSpecifier.m +++ b/PBGitRevSpecifier.m @@ -47,9 +47,19 @@ [revspec setDescription:@"Local branches"]; return revspec; } + - (BOOL) isSimpleRef { - return ([parameters count] == 1 && ![[parameters objectAtIndex:0] hasPrefix:@"-"]); + if ([parameters count] > 1) + return NO; + + NSString *param = [parameters objectAtIndex:0]; + if ([param hasPrefix:@"-"] || + [param rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"^@{}~:"]].location != NSNotFound || + [param rangeOfString:@".."].location != NSNotFound) + return NO; + + return YES; } - (NSString*) simpleRef From cd381a459c298333f019104aa15f89f11d98f109 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 23:05:07 +0200 Subject: [PATCH 012/451] Sidebar: Check if we have enough path components --- PBGitSidebarController.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m index 4e779a7..c9b5656 100644 --- a/PBGitSidebarController.m +++ b/PBGitSidebarController.m @@ -144,7 +144,9 @@ continue; } NSArray *pathComponents = [[rev simpleRef] componentsSeparatedByString:@"/"]; - if ([[pathComponents objectAtIndex:1] isEqualToString:@"heads"]) + if ([pathComponents count] < 2) + [branches addChild:[PBSourceViewItem itemWithRevSpec:rev]]; + else if ([[pathComponents objectAtIndex:1] isEqualToString:@"heads"]) [branches addRev:rev toPath:[pathComponents subarrayWithRange:NSMakeRange(2, [pathComponents count] - 2)]]; else if ([[rev simpleRef] hasPrefix:@"refs/tags/"]) [tags addRev:rev toPath:[pathComponents subarrayWithRange:NSMakeRange(2, [pathComponents count] - 2)]]; From 468e6bbb4025427c6f18a8c1b64623c19b7b56cf Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 23:10:31 +0200 Subject: [PATCH 013/451] Sidebar: add a new ref if it can't be found --- PBGitSidebarController.h | 4 ++- PBGitSidebarController.m | 55 ++++++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/PBGitSidebarController.h b/PBGitSidebarController.h index 9f568ac..9bc7581 100644 --- a/PBGitSidebarController.h +++ b/PBGitSidebarController.h @@ -9,7 +9,7 @@ #import #import "PBViewController.h" -@class PBSourceViewAction; +@class PBSourceViewAction, PBSourceViewItem; @interface PBGitSidebarController : PBViewController { IBOutlet NSWindow *window; @@ -19,6 +19,8 @@ /* Specific things */ PBSourceViewAction *commitAction; + + PBSourceViewItem *branches, *remotes, *tags, *custom; } @property(readonly) NSMutableArray *items; diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m index c9b5656..b19eaaa 100644 --- a/PBGitSidebarController.m +++ b/PBGitSidebarController.m @@ -15,7 +15,7 @@ - (void)populateList; - (void)updateSelection; - +- (void)addRevSpec:(PBGitRevSpecifier *)revSpec; @end @implementation PBGitSidebarController @@ -57,11 +57,13 @@ if (item = [it findRev:rev]) break; - // TODO: We should add the current branch, or something :) - if (!item) { - [sourceView deselectAll:self]; - return; + [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]) + break; } [sourceView PBExpandItem:item expandParents:YES]; @@ -70,6 +72,24 @@ [sourceView selectRow:index byExtendingSelection:NO]; } +- (void)addRevSpec:(PBGitRevSpecifier *)rev +{ + if (![rev isSimpleRef]) { + [custom addChild:[PBSourceViewItem itemWithRevSpec:rev]]; + return; + } + + NSArray *pathComponents = [[rev simpleRef] componentsSeparatedByString:@"/"]; + if ([pathComponents count] < 2) + [branches addChild:[PBSourceViewItem itemWithRevSpec:rev]]; + else if ([[pathComponents objectAtIndex:1] isEqualToString:@"heads"]) + [branches addRev:rev toPath:[pathComponents subarrayWithRange:NSMakeRange(2, [pathComponents count] - 2)]]; + else if ([[rev simpleRef] hasPrefix:@"refs/tags/"]) + [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)]]; +} + #pragma mark NSOutlineView delegate methods - (void)outlineViewSelectionDidChange:(NSNotification *)notification @@ -132,28 +152,13 @@ commitAction.icon = [NSImage imageNamed:@"CommitViewTemplate"]; [actions addChild:commitAction]; - PBSourceViewItem *branches = [PBSourceViewItem groupItemWithTitle:@"Branches"]; - PBSourceViewItem *remotes = [PBSourceViewItem groupItemWithTitle:@"Remotes"]; - PBSourceViewItem *tags = [PBSourceViewItem groupItemWithTitle:@"Tags"]; - PBSourceViewItem *custom = [PBSourceViewItem groupItemWithTitle:@"Custom"]; + branches = [PBSourceViewItem groupItemWithTitle:@"Branches"]; + remotes = [PBSourceViewItem groupItemWithTitle:@"Remotes"]; + tags = [PBSourceViewItem groupItemWithTitle:@"Tags"]; + custom = [PBSourceViewItem groupItemWithTitle:@"Custom"]; for (PBGitRevSpecifier *rev in repository.branches) - { - if (![rev isSimpleRef]) { - [custom addChild:[PBSourceViewItem itemWithRevSpec:rev]]; - continue; - } - NSArray *pathComponents = [[rev simpleRef] componentsSeparatedByString:@"/"]; - if ([pathComponents count] < 2) - [branches addChild:[PBSourceViewItem itemWithRevSpec:rev]]; - else if ([[pathComponents objectAtIndex:1] isEqualToString:@"heads"]) - [branches addRev:rev toPath:[pathComponents subarrayWithRange:NSMakeRange(2, [pathComponents count] - 2)]]; - else if ([[rev simpleRef] hasPrefix:@"refs/tags/"]) - [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)]]; - - } + [self addRevSpec:rev]; //[items addObject:actions]; From 6c2675c9cd1348f64a929dc39b56e144dc359f88 Mon Sep 17 00:00:00 2001 From: Bernard Leach Date: Fri, 25 Sep 2009 12:27:45 +1000 Subject: [PATCH 014/451] Unescape the filename to ensure that filenames containing '&' are displayed correctly --- html/views/history/history.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/views/history/history.js b/html/views/history/history.js index 6cd7540..ffe74c8 100644 --- a/html/views/history/history.js +++ b/html/views/history/history.js @@ -244,7 +244,7 @@ var showDiff = function() { p.insertBefore(document.createTextNode(name1 + " -> "), link); } - link.appendChild(document.createTextNode(finalFile)); + link.appendChild(document.createTextNode(finalFile.unEscapeHTML())); button.setAttribute("representedFile", finalFile); link.setAttribute("representedFile", finalFile); From a7ce2abb062c549d9d59b55eb39b59acacc0336c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Berg?= Date: Tue, 20 Oct 2009 03:34:07 +0200 Subject: [PATCH 015/451] Bug fix: Context lines slider can now update diff views in real time. NOTE: Using this feature needs cookies enabled, which may sub-optimal in corporate controlled environments. TODO: The dependency on jQuery is overkill for something as simple as updating tracking mouse-ups on a input element. --- html/css/diff.css | 6 +++-- html/js/jquery-1.3.2.min.js | 19 ++++++++++++++++ html/lib/GitX.js | 43 ++++++++++++++++++++++++++++++++++++ html/views/commit/commit.js | 3 +-- html/views/commit/index.html | 30 +++++++++++++++++++------ 5 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 html/js/jquery-1.3.2.min.js diff --git a/html/css/diff.css b/html/css/diff.css index ca46216..84c627e 100644 --- a/html/css/diff.css +++ b/html/css/diff.css @@ -14,7 +14,8 @@ .diff .file .diffContent { white-space: pre; - font-family: Monaco; + font-family: Meslo, "Andale Mono", Menlo, Monaco; + font-size: 11px; } .diff .file .diffcontent .lineno { @@ -48,7 +49,8 @@ } .diff .file .diffcontent .lines .whitespace { - background-color: rgba(255,0,0,0.5); + /* background-color: rgba(255,0,0,0.5); */ + background-color: transparent; } #CurrentHunk { diff --git a/html/js/jquery-1.3.2.min.js b/html/js/jquery-1.3.2.min.js new file mode 100644 index 0000000..b1ae21d --- /dev/null +++ b/html/js/jquery-1.3.2.min.js @@ -0,0 +1,19 @@ +/* + * jQuery JavaScript Library v1.3.2 + * http://jquery.com/ + * + * Copyright (c) 2009 John Resig + * Dual licensed under the MIT and GPL licenses. + * http://docs.jquery.com/License + * + * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) + * Revision: 6246 + */ +(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!O.indexOf("",""]||(!O.indexOf("",""]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div
","
"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); +/* + * Sizzle CSS Selector Engine - v0.9.3 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="

";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="
";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
").append(M.responseText.replace(//g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='
';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); \ No newline at end of file diff --git a/html/lib/GitX.js b/html/lib/GitX.js index 7a51f88..7050eb1 100644 --- a/html/lib/GitX.js +++ b/html/lib/GitX.js @@ -55,3 +55,46 @@ var notify = function(text, state) { var hideNotification = function() { $("notification").style.display = "none"; } + + +//cookie functions from quirksmode +function createCookie(name,value,days) { + if (days) { + var date = new Date(); + date.setTime(date.getTime()+(days*24*60*60*1000)); + var expires = "; expires="+date.toGMTString(); + } + else var expires = ""; + document.cookie = name+"="+value+expires+"; path=/"; +} +function readCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for(var i=0;i < ca.length;i++) { + var c = ca[i]; + while (c.charAt(0)==' ') c = c.substring(1,c.length); + if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); + } + return null; +} + +// cookie functions from W3C Schools +function setCookie(c_name, value, expiredays) { + var exdate = new Date(); + exdate.setDate(exdate.getDate() + expiredays); + document.cookie = c_name + "=" + escape(value) + + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString()); +} + +function getCookie(c_name) { + if (document.cookie.length > 0) { + c_start = document.cookie.indexOf(c_name + "="); + if (c_start != -1) { + c_start = c_start + c_name.length + 1; + c_end = document.cookie.indexOf(";", c_start); + if (c_end == -1) c_end = document.cookie.length; + return unescape(document.cookie.substring(c_start, c_end)); + } + } + return ""; +}; \ No newline at end of file diff --git a/html/views/commit/commit.js b/html/views/commit/commit.js index cdec998..e531311 100644 --- a/html/views/commit/commit.js +++ b/html/views/commit/commit.js @@ -1,8 +1,7 @@ /* Commit: Interface for selecting, staging, discarding, and unstaging hunks, individual lines, or ranges of lines. */ -var contextLines = 5; - +contextLines = getCookie("GitXContextLines"); var showNewFile = function(file) { setTitle("New file: " + file.path); diff --git a/html/views/commit/index.html b/html/views/commit/index.html index ef889de..6431a11 100644 --- a/html/views/commit/index.html +++ b/html/views/commit/index.html @@ -8,20 +8,36 @@ - - + + + + + - +

- + Context: Nothing to commit -

-