Files
gitx/PBGitSidebarController.m
T
2010-03-13 22:12:33 -07:00

208 lines
5.6 KiB
Objective-C

//
// PBGitSidebar.m
// GitX
//
// Created by Pieter de Bie on 9/8/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import "PBGitSidebarController.h"
#import "PBSourceViewItem.h"
#import "NSOutlineViewExt.h"
#import "PBSourceViewAction.h"
@interface PBGitSidebarController ()
- (void)populateList;
- (void)updateSelection;
- (void)addRevSpec:(PBGitRevSpecifier *)revSpec;
@end
@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
{
[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;
if (!item) {
[self addRevSpec:rev];
// Try to find the just added item again.
// TODO: refactor with above.
for (PBSourceViewItem *it in items)
if (item = [it findRev:rev])
break;
}
[sourceView PBExpandItem:item expandParents:YES];
NSIndexSet *index = [NSIndexSet indexSetWithIndex:[sourceView rowForItem:item]];
[sourceView selectRowIndexes: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
{
NSInteger index = [sourceView selectedRow];
PBSourceViewItem *item = [sourceView itemAtRow:index];
if ([item revSpecifier]) {
[[repository windowController] showHistoryView:self];
repository.currentBranch = [item revSpecifier];
return;
}
if (item == commitAction)
[[repository windowController] showCommitView:self];
/* ... */
/* Handle Remotes */
}
#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
{
[cell setImage:[item icon]];
}
- (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"];
actions.isUncollapsible = YES;
commitAction = [PBSourceViewAction itemWithTitle:@"Index / Commit"];
commitAction.icon = [NSImage imageNamed:@"CommitViewTemplate"];
[actions addChild:commitAction];
branches = [PBSourceViewItem groupItemWithTitle:@"Branches"];
remotes = [PBSourceViewItem groupItemWithTitle:@"Remotes"];
tags = [PBSourceViewItem groupItemWithTitle:@"Tags"];
custom = [PBSourceViewItem groupItemWithTitle:@"Custom"];
for (PBGitRevSpecifier *rev in repository.branches)
[self addRevSpec: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(branches == [sourceView itemAtRow:0], @"First item is not the Branches");
[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