Skip to content

Commit

Permalink
Outline view now shows generic list of repo file system
Browse files Browse the repository at this point in the history
  • Loading branch information
Justin Palmer committed Oct 2, 2008
1 parent 0c47f4a commit 8f0f09f
Show file tree
Hide file tree
Showing 8 changed files with 598 additions and 23 deletions.
362 changes: 342 additions & 20 deletions English.lproj/MainMenu.xib

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions GNFileSystemItem.h
@@ -0,0 +1,27 @@
//
// GNFileSystemItem.h
//
// Based on code examples in NSOutlineView documentation.

#import <Cocoa/Cocoa.h>


@interface GNFileSystemItem : NSObject
{
NSString *relativePath;
GNFileSystemItem *parent;
NSMutableArray *children;
NSImage *image;
}

+ (GNFileSystemItem *)rootItem;
+ (NSString *)repoRoot;
- (int)numberOfChildren;// Returns -1 for leaf nodes
- (GNFileSystemItem *)childAtIndex:(int)n;// Invalid to call on leaf nodes
- (NSString *)fullPath;
- (NSString *)relativePath;
- (void)setRelativePath:(NSString *)aString;
- (NSImage*)icon;
- (BOOL)isLeafNode;
- (NSDictionary*)attributes;
@end
154 changes: 154 additions & 0 deletions GNFileSystemItem.m
@@ -0,0 +1,154 @@
//
// GNFileSystemItem.m
//
// Based on code examples in NSOutlineView documentation.

#import "GNFileSystemItem.h"


@implementation GNFileSystemItem

static GNFileSystemItem *rootItem = nil;
#define IsALeafNode ((id)-1)

- (id)initWithPath:(NSString *)path parent:(GNFileSystemItem *)obj
{
if (self = [super init])
{
relativePath = [[path lastPathComponent] copy];
parent = obj;
}
return self;
}


+ (GNFileSystemItem *)rootItem
{
if (rootItem == nil)
{
rootItem = [[GNFileSystemItem alloc] initWithPath:[GNFileSystemItem repoRoot] parent:nil];
}
return rootItem;
}

+ (NSString *)repoRoot {
return [[[NSApplication sharedApplication] delegate] repository_location];
}

// - (NSString *)ignoredByGit:(NSString *)fileItem
// {
// NSString *ret = [NSTask launchedTaskWithLaunchPath:@"/usr/bin/env" arguments:
// [NSArray arrayWithObjects:@"git", @"status", fileItem, nil]];
// NSLog(@"%s RET: %@", _cmd, ret);
// return ret;
// }

// Creates, caches, and returns the array of children
// Loads children incrementally
- (NSArray *)children
{
if (children == NULL)
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *fullPath = [self fullPath];
BOOL isDir, valid = [fileManager fileExistsAtPath:fullPath isDirectory:&isDir];

if (valid && isDir)
{
NSArray *array = [fileManager directoryContentsAtPath:fullPath];
int numChildren = [array count];
children = [[NSMutableArray alloc] initWithCapacity:numChildren];
for (NSString *sourceFile in array)
{
if([[sourceFile lastPathComponent] hasPrefix:@"."]) {
continue;
}

// if([self ignoredByGit:sourceFile]) {
// continue;
// }

GNFileSystemItem *newChild = [[GNFileSystemItem alloc] initWithPath:sourceFile parent:self];
[children addObject:newChild];
[newChild release];
}
}
else
{
children = IsALeafNode;
}
}
return children;
}


- (NSImage*)icon
{
if (image == nil)
{
image = [[[NSWorkspace sharedWorkspace] iconForFile: [self fullPath]] retain];
}

return image;
}


- (NSDictionary*)attributes
{
return [NSDictionary dictionaryWithDictionary: [[NSFileManager defaultManager] fileAttributesAtPath: [self fullPath] traverseLink: YES]];
}


- (NSString *)relativePath
{
return relativePath;
}


- (void)setRelativePath:(NSString *)aString
{
if (aString != relativePath)
{
[relativePath release];
[relativePath = aString copy];
}
}


- (NSString *)fullPath
{
// If no parent, return our own relative path
if (parent == nil) {
return [GNFileSystemItem repoRoot];
}
// recurse up the hierarchy, prepending each parent’s path
return [[parent fullPath] stringByAppendingPathComponent:relativePath];
}


- (GNFileSystemItem *)childAtIndex:(int)n
{
return [[self children] objectAtIndex:n];
}


- (BOOL)isLeafNode
{
return [self children] == IsALeafNode;
}

- (int)numberOfChildren
{
id tmp = [self children];
return (tmp == IsALeafNode) ? (-1) : [tmp count];
}

- (void)dealloc
{
[image release];
if (children != IsALeafNode) [children release];
[relativePath release];
[super dealloc];
}

@end
4 changes: 4 additions & 0 deletions GNTreeDataSource.h
@@ -0,0 +1,4 @@
#import <Cocoa/Cocoa.h>

@interface GNTreeDataSource : NSObject
@end
27 changes: 27 additions & 0 deletions GNTreeDataSource.m
@@ -0,0 +1,27 @@
#import "GNTreeDataSource.h"
#import "GNFileSystemItem.h"

@implementation GNTreeDataSource

// Data Source methods

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
return (item == nil) ? 1 : [item numberOfChildren];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
return (item == nil) ? YES : ([item numberOfChildren] != -1);
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
return (item == nil) ? [GNFileSystemItem rootItem] : [(GNFileSystemItem *)item childAtIndex:index];
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
return (item == nil) ? @"/" : (id)[item relativePath];
}

// Delegate methods

@end

20 changes: 20 additions & 0 deletions GitNub.xcodeproj/project.pbxproj
Expand Up @@ -27,6 +27,11 @@
281AECA70E6662B000B48530 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 281AECA60E6662B000B48530 /* WebKit.framework */; };
281AED6C0E6677B500B48530 /* GitNubWebView.rb in Resources */ = {isa = PBXBuildFile; fileRef = 281AED6B0E6677B500B48530 /* GitNubWebView.rb */; };
283254680D8B792500D99366 /* lib in Resources */ = {isa = PBXBuildFile; fileRef = 283254650D8B792500D99366 /* lib */; };
283E2EC20E932E9E00E33E25 /* TreeController.rb in Resources */ = {isa = PBXBuildFile; fileRef = 283E2EC10E932E9E00E33E25 /* TreeController.rb */; };
283E2ECB0E9332AD00E33E25 /* GNFileSystemItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 283E2EC90E9332AD00E33E25 /* GNFileSystemItem.m */; };
283E2ECC0E9332AD00E33E25 /* GNFileSystemItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 283E2ECA0E9332AD00E33E25 /* GNFileSystemItem.h */; };
283E2ECF0E9332B700E33E25 /* GNTreeDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 283E2ECD0E9332B700E33E25 /* GNTreeDataSource.m */; };
283E2ED00E9332B700E33E25 /* GNTreeDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 283E2ECE0E9332B700E33E25 /* GNTreeDataSource.h */; };
288853050D7CE2E500862D67 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 288853040D7CE2E500862D67 /* LICENSE */; };
288CB41A0D8789DD0092B5CC /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 288CB4180D8789DD0092B5CC /* MainMenu.xib */; };
4DDCA7070ACC9A6100E082CE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
Expand Down Expand Up @@ -74,6 +79,11 @@
281AECA60E6662B000B48530 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = /System/Library/Frameworks/WebKit.framework; sourceTree = "<absolute>"; };
281AED6B0E6677B500B48530 /* GitNubWebView.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = GitNubWebView.rb; sourceTree = "<group>"; };
283254650D8B792500D99366 /* lib */ = {isa = PBXFileReference; lastKnownFileType = folder; path = lib; sourceTree = "<group>"; };
283E2EC10E932E9E00E33E25 /* TreeController.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = TreeController.rb; sourceTree = "<group>"; };
283E2EC90E9332AD00E33E25 /* GNFileSystemItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNFileSystemItem.m; sourceTree = "<group>"; };
283E2ECA0E9332AD00E33E25 /* GNFileSystemItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNFileSystemItem.h; sourceTree = "<group>"; };
283E2ECD0E9332B700E33E25 /* GNTreeDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNTreeDataSource.m; sourceTree = "<group>"; };
283E2ECE0E9332B700E33E25 /* GNTreeDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNTreeDataSource.h; sourceTree = "<group>"; };
288853040D7CE2E500862D67 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
288CB4190D8789DD0092B5CC /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; };
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -145,6 +155,7 @@
281AEAAF0E65410600B48530 /* CommitsController.rb */,
281AEAB00E65410600B48530 /* InfoWindowController.rb */,
281AEAB10E65410600B48530 /* NetworkController.rb */,
283E2EC10E932E9E00E33E25 /* TreeController.rb */,
);
path = controllers;
sourceTree = "<group>";
Expand Down Expand Up @@ -195,6 +206,10 @@
29B97315FDCFA39411CA2CEA /* Other Sources */ = {
isa = PBXGroup;
children = (
283E2ECD0E9332B700E33E25 /* GNTreeDataSource.m */,
283E2ECE0E9332B700E33E25 /* GNTreeDataSource.h */,
283E2EC90E9332AD00E33E25 /* GNFileSystemItem.m */,
283E2ECA0E9332AD00E33E25 /* GNFileSystemItem.h */,
283254650D8B792500D99366 /* lib */,
29B97316FDCFA39411CA2CEA /* main.m */,
E8F5E25803AEB7C803A81C6F /* rb_main.rb */,
Expand Down Expand Up @@ -228,6 +243,8 @@
buildActionMask = 2147483647;
files = (
281AEAB90E65411300B48530 /* CommitSummaryCell.h in Headers */,
283E2ECC0E9332AD00E33E25 /* GNFileSystemItem.h in Headers */,
283E2ED00E9332B700E33E25 /* GNTreeDataSource.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -297,6 +314,7 @@
281AEACC0E65418500B48530 /* ImageLoadOperation.rb in Resources */,
281AEACE0E6541AB00B48530 /* Info.xib in Resources */,
281AED6C0E6677B500B48530 /* GitNubWebView.rb in Resources */,
283E2EC20E932E9E00E33E25 /* TreeController.rb in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -309,6 +327,8 @@
files = (
4DDCA70A0ACC9A6100E082CE /* main.m in Sources */,
281AEABA0E65411300B48530 /* CommitSummaryCell.m in Sources */,
283E2ECB0E9332AD00E33E25 /* GNFileSystemItem.m in Sources */,
283E2ECF0E9332B700E33E25 /* GNTreeDataSource.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
6 changes: 3 additions & 3 deletions controllers/ApplicationController.rb
Expand Up @@ -86,8 +86,8 @@ def repo
end
end

def draggingEntered(sender)
puts sender
def repository_location
REPOSITORY_LOCATION.to_s.gsub('.git', '')
end

ib_action :show_info_panel
Expand All @@ -98,7 +98,7 @@ def show_info_panel(sender)

ib_action :swap_tab
def swap_tab(segment)
tag = %w(commits network)[segment.cell.tagForSegment(segment.selectedSegment)]
tag = %w(commits network browser)[segment.cell.tagForSegment(segment.selectedSegment)]
@tab_panel.selectTabViewItemWithIdentifier(tag)
end

Expand Down
21 changes: 21 additions & 0 deletions controllers/TreeController.rb
@@ -0,0 +1,21 @@
#
# TreeController.rb
# GitNub
#
# Created by Justin Palmer on 9/30/08.
# Copyright (c) 2008 ENTP <http://hoth.entp.com>. All rights reserved.
#

require 'osx/cocoa'
OSX.ns_import 'GNFileSystemItem'
OSX.ns_import 'GNTreeDataSource'


class TreeController < OSX::NSObject
ib_outlet :tree_outline
ib_outlet :file_canvas

def awakeFromNib
#@tree_outline.setDelegate(self)
end
end

0 comments on commit 8f0f09f

Please sign in to comment.