mirror of
https://github.com/kennethreitz-archive/gitx.git
synced 2026-06-05 23:40:18 +00:00
Bug fix: Make QuickLook panel work by using the now public API.
Also implements Finder's fade transitions, handles preview icon creation through GCD block dispatch and does the right thing regarding events: Mouse events go to the panel, key events to the fileBrowser outline view.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Quartz/Quartz.h> /* for QLPreviewPanel */
|
||||
#import "PBGitRepository.h"
|
||||
|
||||
@class PBCLIProxy;
|
||||
@@ -35,4 +36,6 @@
|
||||
- (IBAction)saveAction:sender;
|
||||
- (IBAction) showHelp:(id) sender;
|
||||
|
||||
- (IBAction)togglePreviewPanel:(id)previewPanel;
|
||||
|
||||
@end
|
||||
|
||||
+18
-5
@@ -27,9 +27,11 @@
|
||||
#endif
|
||||
|
||||
if(self = [super init]) {
|
||||
if(![[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/QuickLookUI.framework"] load])
|
||||
NSLog(@"Could not load QuickLook");
|
||||
|
||||
/* Location of QuickLookUI.framework - it's public now */
|
||||
if(![[NSBundle bundleWithPath:@"/System/Library/Frameworks/Quartz.framework/Frameworks/QuickLookUI.framework"] load])
|
||||
{
|
||||
NSLog(@"Could not load QuickLook");
|
||||
}
|
||||
self.cliProxy = [PBCLIProxy new];
|
||||
}
|
||||
|
||||
@@ -191,7 +193,7 @@
|
||||
return managedObjectModel;
|
||||
}
|
||||
|
||||
managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
|
||||
managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
|
||||
return managedObjectModel;
|
||||
}
|
||||
|
||||
@@ -217,7 +219,7 @@
|
||||
fileManager = [NSFileManager defaultManager];
|
||||
applicationSupportFolder = [self applicationSupportFolder];
|
||||
if ( ![fileManager fileExistsAtPath:applicationSupportFolder isDirectory:NULL] ) {
|
||||
[fileManager createDirectoryAtPath:applicationSupportFolder attributes:nil];
|
||||
[fileManager createDirectoryAtPath:applicationSupportFolder withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
}
|
||||
|
||||
url = [NSURL fileURLWithPath: [applicationSupportFolder stringByAppendingPathComponent: @"GitTest.xml"]];
|
||||
@@ -324,6 +326,17 @@
|
||||
return reply;
|
||||
}
|
||||
|
||||
// QuickLook preview panel
|
||||
|
||||
- (IBAction)togglePreviewPanel:(id)previewPanel
|
||||
{
|
||||
if ([QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible]) {
|
||||
[[QLPreviewPanel sharedPreviewPanel] orderOut:nil];
|
||||
} else {
|
||||
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Implementation of dealloc, to release the retained variables.
|
||||
|
||||
+17
-14
@@ -11,22 +11,25 @@
|
||||
#import "PBGitTree.h"
|
||||
#import "PBViewController.h"
|
||||
#import "PBCollapsibleSplitView.h"
|
||||
#import <Quartz/Quartz.h> /* for the QLPreviewPanelDataSource et al. stuff */
|
||||
|
||||
@interface PBGitHistoryController : PBViewController {
|
||||
IBOutlet NSSearchField *searchField;
|
||||
IBOutlet NSArrayController* commitController;
|
||||
IBOutlet NSTreeController* treeController;
|
||||
IBOutlet NSOutlineView* fileBrowser;
|
||||
IBOutlet NSTableView* commitList;
|
||||
IBOutlet PBCollapsibleSplitView *historySplitView;
|
||||
@interface PBGitHistoryController : PBViewController <QLPreviewPanelDataSource, QLPreviewPanelDelegate> {
|
||||
IBOutlet NSSearchField *searchField;
|
||||
IBOutlet NSArrayController* commitController;
|
||||
IBOutlet NSTreeController* treeController;
|
||||
IBOutlet NSOutlineView* fileBrowser;
|
||||
IBOutlet NSTableView* commitList;
|
||||
IBOutlet PBCollapsibleSplitView *historySplitView;
|
||||
|
||||
IBOutlet id webView;
|
||||
int selectedTab;
|
||||
|
||||
PBGitTree* gitTree;
|
||||
PBGitCommit* webCommit;
|
||||
PBGitCommit* rawCommit;
|
||||
PBGitCommit* realCommit;
|
||||
IBOutlet id webView;
|
||||
int selectedTab;
|
||||
|
||||
PBGitTree* gitTree;
|
||||
PBGitCommit* webCommit;
|
||||
PBGitCommit* rawCommit;
|
||||
PBGitCommit* realCommit;
|
||||
|
||||
QLPreviewPanel * previewPanel;
|
||||
}
|
||||
|
||||
@property (assign) int selectedTab;
|
||||
|
||||
+133
-45
@@ -7,16 +7,96 @@
|
||||
//
|
||||
|
||||
#import "PBGitHistoryController.h"
|
||||
#import "CWQuickLook.h"
|
||||
#import "PBGitGrapher.h"
|
||||
#import "PBGitRevisionCell.h"
|
||||
#import "PBCommitList.h"
|
||||
#define QLPreviewPanel NSClassFromString(@"QLPreviewPanel")
|
||||
|
||||
#import "ApplicationController.h"
|
||||
|
||||
@implementation PBGitHistoryController
|
||||
@synthesize selectedTab, webCommit, rawCommit, gitTree, commitController;
|
||||
|
||||
// MARK: Quick Look panel support
|
||||
|
||||
- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel;
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)beginPreviewPanelControl:(QLPreviewPanel *)panel
|
||||
{
|
||||
// This document is now responsible of the preview panel
|
||||
// It is allowed to set the delegate, data source and refresh panel.
|
||||
previewPanel = panel;
|
||||
panel.delegate = self;
|
||||
panel.dataSource = self;
|
||||
}
|
||||
|
||||
- (void)endPreviewPanelControl:(QLPreviewPanel *)panel
|
||||
{
|
||||
// This document loses its responsisibility on the preview panel
|
||||
// Until the next call to -beginPreviewPanelControl: it must not
|
||||
// change the panel's delegate, data source or refresh it.
|
||||
[previewPanel release];
|
||||
previewPanel = nil;
|
||||
}
|
||||
|
||||
// MARK: Quick Look panel data source
|
||||
|
||||
- (NSInteger)numberOfPreviewItemsInPreviewPanel:(QLPreviewPanel *)panel
|
||||
{
|
||||
return [[fileBrowser selectedRowIndexes] count];
|
||||
}
|
||||
|
||||
- (id <QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel previewItemAtIndex:(NSInteger)index
|
||||
{
|
||||
return [[treeController selectedObjects] objectAtIndex:index];
|
||||
}
|
||||
|
||||
// MARK: Quick Look panel delegate
|
||||
|
||||
- (BOOL)previewPanel:(QLPreviewPanel *)panel handleEvent:(NSEvent *)event
|
||||
{
|
||||
// redirect all key down events to the table view
|
||||
if ([event type] == NSKeyDown) {
|
||||
[fileBrowser keyDown:event];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
// This delegate method provides the rect on screen from which the panel will zoom.
|
||||
- (NSRect)previewPanel:(QLPreviewPanel *)panel sourceFrameOnScreenForPreviewItem:(id <QLPreviewItem>)item
|
||||
{
|
||||
NSInteger index = [[treeController selectedObjects] indexOfObject:item];
|
||||
if (index == NSNotFound) {
|
||||
return NSZeroRect;
|
||||
}
|
||||
|
||||
NSRect iconRect = [fileBrowser frameOfOutlineCellAtRow:index];
|
||||
|
||||
// check that the icon rect is visible on screen
|
||||
// NSRect visibleRect = [fileBrowser visibleRect];
|
||||
//
|
||||
// if (!NSIntersectsRect(visibleRect, iconRect)) {
|
||||
// return NSZeroRect;
|
||||
// }
|
||||
|
||||
// convert icon rect to screen coordinates
|
||||
iconRect = [fileBrowser convertRectToBase:iconRect];
|
||||
iconRect.origin = [[fileBrowser window] convertBaseToScreen:iconRect.origin];
|
||||
|
||||
return iconRect;
|
||||
}
|
||||
|
||||
// This delegate method provides a transition image between the table view and the preview panel
|
||||
- (id)previewPanel:(QLPreviewPanel *)panel transitionImageForPreviewItem:(id <QLPreviewItem>)item contentRect:(NSRect *)contentRect
|
||||
{
|
||||
PBGitTree * treeItem = (PBGitTree *)item;
|
||||
return treeItem.iconImage;
|
||||
}
|
||||
|
||||
// MARK: PBGitHistoryController
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
self.selectedTab = [[NSUserDefaults standardUserDefaults] integerForKey:@"Repository Window Selected Tab Index"];;
|
||||
@@ -28,14 +108,14 @@
|
||||
[commitList setIntercellSpacing:cellSpacing];
|
||||
[fileBrowser setTarget:self];
|
||||
[fileBrowser setDoubleAction:@selector(openSelectedFile:)];
|
||||
|
||||
|
||||
if (!repository.currentBranch) {
|
||||
[repository reloadRefs];
|
||||
[repository readCurrentBranch];
|
||||
}
|
||||
else
|
||||
[repository lazyReload];
|
||||
|
||||
|
||||
// Set a sort descriptor for the subject column in the history list, as
|
||||
// It can't be sorted by default (because it's bound to a PBGitCommit)
|
||||
[[commitList tableColumnWithIdentifier:@"subject"] setSortDescriptorPrototype:[[NSSortDescriptor alloc] initWithKey:@"subject" ascending:YES]];
|
||||
@@ -103,7 +183,7 @@
|
||||
return;
|
||||
PBGitTree* tree = [selectedFiles objectAtIndex:0];
|
||||
NSString* name = [tree tmpFileNameForContents];
|
||||
[[NSWorkspace sharedWorkspace] openTempFile:name];
|
||||
[[NSWorkspace sharedWorkspace] openFile:name];
|
||||
}
|
||||
|
||||
- (IBAction) setDetailedView: sender {
|
||||
@@ -118,10 +198,22 @@
|
||||
|
||||
- (void)keyDown:(NSEvent*)event
|
||||
{
|
||||
if ([[event charactersIgnoringModifiers] isEqualToString: @"f"] && [event modifierFlags] & NSAlternateKeyMask && [event modifierFlags] & NSCommandKeyMask)
|
||||
[superController.window makeFirstResponder: searchField];
|
||||
else
|
||||
[super keyDown: event];
|
||||
if ([[event charactersIgnoringModifiers] isEqualToString: @"f"]
|
||||
&& [event modifierFlags] & NSAlternateKeyMask
|
||||
&& [event modifierFlags] & NSCommandKeyMask)
|
||||
{
|
||||
// command+alt+f
|
||||
[superController.window makeFirstResponder: searchField];
|
||||
}
|
||||
else if ([[event charactersIgnoringModifiers] isEqualToString: @" "])
|
||||
{
|
||||
// space
|
||||
[[NSApp delegate] togglePreviewPanel:self];
|
||||
}
|
||||
else
|
||||
{
|
||||
[super keyDown: event];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) copyCommitInfo
|
||||
@@ -130,7 +222,7 @@
|
||||
if (!commit)
|
||||
return;
|
||||
NSString *info = [NSString stringWithFormat:@"%@ (%@)", [[commit realSha] substringToIndex:10], [commit subject]];
|
||||
|
||||
|
||||
NSPasteboard *a =[NSPasteboard generalPasteboard];
|
||||
[a declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self];
|
||||
[a setString:info forType: NSStringPboardType];
|
||||
@@ -139,34 +231,29 @@
|
||||
|
||||
- (IBAction) toggleQuickView: sender
|
||||
{
|
||||
id panel = [QLPreviewPanel sharedPreviewPanel];
|
||||
if ([panel isOpen]) {
|
||||
[panel closePanel];
|
||||
} else {
|
||||
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFrontWithEffect:1];
|
||||
[self updateQuicklookForce: YES];
|
||||
}
|
||||
[[NSApp delegate] togglePreviewPanel:sender];
|
||||
}
|
||||
|
||||
- (void) updateQuicklookForce: (BOOL) force
|
||||
{
|
||||
if (!force && ![[QLPreviewPanel sharedPreviewPanel] isOpen])
|
||||
return;
|
||||
|
||||
NSArray* selectedFiles = [treeController selectedObjects];
|
||||
|
||||
if ([selectedFiles count] == 0)
|
||||
return;
|
||||
|
||||
NSMutableArray* fileNames = [NSMutableArray array];
|
||||
for (PBGitTree* tree in selectedFiles) {
|
||||
NSString* s = [tree tmpFileNameForContents];
|
||||
if (s)
|
||||
[fileNames addObject:[NSURL fileURLWithPath: s]];
|
||||
}
|
||||
|
||||
[[QLPreviewPanel sharedPreviewPanel] setURLs:fileNames currentIndex:0 preservingDisplayState:YES];
|
||||
if ((!force && ![[QLPreviewPanel sharedPreviewPanel] isVisible])
|
||||
|| ![QLPreviewPanel sharedPreviewPanelExists])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// NSArray* selectedFiles = [treeController selectedObjects];
|
||||
//
|
||||
// if ([selectedFiles count] == 0)
|
||||
// return;
|
||||
//
|
||||
// NSMutableArray* fileNames = [NSMutableArray array];
|
||||
// for (PBGitTree* tree in selectedFiles) {
|
||||
// NSString* s = [tree tmpFileNameForContents];
|
||||
// if (s)
|
||||
// [fileNames addObject:[NSURL fileURLWithPath: s]];
|
||||
// }
|
||||
[[QLPreviewPanel sharedPreviewPanel] reloadData];
|
||||
}
|
||||
|
||||
- (IBAction) refresh: sender
|
||||
@@ -205,7 +292,7 @@
|
||||
[commitController removeObserver:self forKeyPath:@"selection"];
|
||||
[treeController removeObserver:self forKeyPath:@"selection"];
|
||||
[repository removeObserver:self forKeyPath:@"currentBranch"];
|
||||
|
||||
|
||||
[super removeView];
|
||||
}
|
||||
|
||||
@@ -230,12 +317,12 @@
|
||||
- (void)showCommitsFromTree:(id)sender
|
||||
{
|
||||
// TODO: Enable this from webview as well!
|
||||
|
||||
|
||||
NSMutableArray *filePaths = [NSMutableArray arrayWithObjects:@"HEAD", @"--", NULL];
|
||||
[filePaths addObjectsFromArray:[sender representedObject]];
|
||||
|
||||
|
||||
PBGitRevSpecifier *revSpec = [[PBGitRevSpecifier alloc] initWithParameters:filePaths];
|
||||
|
||||
|
||||
repository.currentBranch = [repository addBranch:revSpec];
|
||||
}
|
||||
|
||||
@@ -244,12 +331,12 @@
|
||||
NSString *workingDirectory = [[repository workingDirectory] stringByAppendingString:@"/"];
|
||||
NSString *path;
|
||||
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
|
||||
|
||||
|
||||
for (NSString *filePath in [sender representedObject]) {
|
||||
path = [workingDirectory stringByAppendingPathComponent:filePath];
|
||||
[ws selectFile: path inFileViewerRootedAtPath:path];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (void)openFilesAction:(id)sender
|
||||
@@ -257,7 +344,7 @@
|
||||
NSString *workingDirectory = [[repository workingDirectory] stringByAppendingString:@"/"];
|
||||
NSString *path;
|
||||
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
|
||||
|
||||
|
||||
for (NSString *filePath in [sender representedObject]) {
|
||||
path = [workingDirectory stringByAppendingPathComponent:filePath];
|
||||
[ws openFile:path];
|
||||
@@ -268,7 +355,7 @@
|
||||
- (NSMenu *)contextMenuForTreeView
|
||||
{
|
||||
NSArray *filePaths = [[treeController selectedObjects] valueForKey:@"fullPath"];
|
||||
|
||||
|
||||
NSMenu *menu = [[NSMenu alloc] init];
|
||||
for (NSMenuItem *item in [self menuItemsForPaths:filePaths])
|
||||
[menu addItem:item];
|
||||
@@ -280,20 +367,20 @@
|
||||
BOOL multiple = [paths count] != 1;
|
||||
NSMenuItem *historyItem = [[NSMenuItem alloc] initWithTitle:multiple? @"Show history of files" : @"Show history of file"
|
||||
action:@selector(showCommitsFromTree:)
|
||||
keyEquivalent:@""];
|
||||
keyEquivalent:@""];
|
||||
NSMenuItem *finderItem = [[NSMenuItem alloc] initWithTitle:@"Show in Finder"
|
||||
action:@selector(showInFinderAction:)
|
||||
keyEquivalent:@""];
|
||||
NSMenuItem *openFilesItem = [[NSMenuItem alloc] initWithTitle:multiple? @"Open Files" : @"Open File"
|
||||
action:@selector(openFilesAction:)
|
||||
keyEquivalent:@""];
|
||||
|
||||
|
||||
NSArray *menuItems = [NSArray arrayWithObjects:historyItem, finderItem, openFilesItem, nil];
|
||||
for (NSMenuItem *item in menuItems) {
|
||||
[item setTarget:self];
|
||||
[item setRepresentedObject:paths];
|
||||
}
|
||||
|
||||
|
||||
return menuItems;
|
||||
}
|
||||
|
||||
@@ -322,3 +409,4 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ extern NSString* PBGitRepositoryErrorDomain;
|
||||
|
||||
+ (NSURL*)gitDirForURL:(NSURL*)repositoryURL;
|
||||
+ (NSURL*)baseDirForURL:(NSURL*)repositoryURL;
|
||||
+ (NSString *) basePath;
|
||||
|
||||
- (id) initWithURL: (NSURL*) path;
|
||||
- (void) setup;
|
||||
@@ -72,4 +73,5 @@ extern NSString* PBGitRepositoryErrorDomain;
|
||||
@property (assign) NSMutableArray* branches;
|
||||
@property (assign) PBGitRevSpecifier *currentBranch;
|
||||
@property (retain) NSMutableDictionary* refs;
|
||||
|
||||
@end
|
||||
|
||||
+28
-16
@@ -17,6 +17,7 @@
|
||||
#import "PBGitRevSpecifier.h"
|
||||
|
||||
NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain";
|
||||
static NSString * repositoryBasePath = nil;
|
||||
|
||||
@implementation PBGitRepository
|
||||
|
||||
@@ -37,12 +38,23 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain";
|
||||
return [[PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:[NSArray arrayWithObjects:@"rev-parse", @"--is-bare-repository", nil] inDir:path] isEqualToString:@"true"];
|
||||
}
|
||||
|
||||
+ (NSString *) basePath {
|
||||
if (repositoryBasePath) {
|
||||
return repositoryBasePath;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
+ (NSURL*)gitDirForURL:(NSURL*)repositoryURL;
|
||||
{
|
||||
if (![PBGitBinary path])
|
||||
return nil;
|
||||
|
||||
NSString* repositoryPath = [repositoryURL path];
|
||||
|
||||
// save base path
|
||||
repositoryBasePath = [repositoryPath stringByDeletingLastPathComponent];
|
||||
|
||||
if ([self isBareRepository:repositoryPath])
|
||||
return repositoryURL;
|
||||
@@ -103,7 +115,7 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain";
|
||||
NSURL* gitDirURL = [PBGitRepository gitDirForURL:[self fileURL]];
|
||||
if (!gitDirURL) {
|
||||
if (outError) {
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"%@ does not appear to be a git repository.", [self fileName]]
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"%@ does not appear to be a git repository.", [[self fileURL] path]]
|
||||
forKey:NSLocalizedRecoverySuggestionErrorKey];
|
||||
*outError = [NSError errorWithDomain:PBGitRepositoryErrorDomain code:0 userInfo:userInfo];
|
||||
}
|
||||
@@ -118,7 +130,7 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain";
|
||||
|
||||
- (void) setup
|
||||
{
|
||||
config = [[PBGitConfig alloc] initWithRepository:self.fileURL.path];
|
||||
config = [[PBGitConfig alloc] initWithRepository:[[self fileURL] path]];
|
||||
self.branches = [NSMutableArray array];
|
||||
[self reloadRefs];
|
||||
revisionList = [[PBGitRevList alloc] initWithRepository:self];
|
||||
@@ -133,20 +145,20 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain";
|
||||
if (!gitDirURL)
|
||||
return nil;
|
||||
|
||||
self = [self init];
|
||||
[self setFileURL: gitDirURL];
|
||||
|
||||
[self setup];
|
||||
|
||||
// We don't want the window controller to display anything yet..
|
||||
// We'll leave that to the caller of this method.
|
||||
#ifndef CLI
|
||||
[self addWindowController:[[PBGitWindowController alloc] initWithRepository:self displayDefault:NO]];
|
||||
#endif
|
||||
|
||||
[self showWindows];
|
||||
|
||||
return self;
|
||||
if (self = [super init]) {
|
||||
[self setFileURL: gitDirURL];
|
||||
|
||||
[self setup];
|
||||
|
||||
// We don't want the window controller to display anything yet..
|
||||
// We'll leave that to the caller of this method.
|
||||
#ifndef CLI
|
||||
[self addWindowController:[[PBGitWindowController alloc] initWithRepository:self displayDefault:NO]];
|
||||
#endif
|
||||
|
||||
[self showWindows];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// The fileURL the document keeps is to the .git dir, but that’s pretty
|
||||
|
||||
+7
-1
@@ -7,9 +7,11 @@
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Quartz/Quartz.h>
|
||||
#import "PBGitRepository.h"
|
||||
|
||||
@interface PBGitTree : NSObject {
|
||||
|
||||
long long _fileSize;
|
||||
|
||||
NSString* sha;
|
||||
@@ -21,8 +23,10 @@
|
||||
|
||||
NSString* localFileName;
|
||||
NSDate* localMtime;
|
||||
|
||||
NSString * absolutePath;
|
||||
NSImage * iconImage;
|
||||
}
|
||||
|
||||
+ (PBGitTree*) rootForCommit: (id) commit;
|
||||
+ (PBGitTree*) treeForTree: (PBGitTree*) tree andPath: (NSString*) path;
|
||||
- (void) saveToFolder: (NSString *) directory;
|
||||
@@ -40,4 +44,6 @@
|
||||
@property(readonly) NSString* fullPath;
|
||||
@property(readonly) NSString* contents;
|
||||
|
||||
@property (copy) NSString *absolutePath;
|
||||
@property (retain) NSImage *iconImage;
|
||||
@end
|
||||
|
||||
+65
-11
@@ -11,10 +11,37 @@
|
||||
#import "NSFileHandleExt.h"
|
||||
#import "PBEasyPipe.h"
|
||||
#import "PBEasyFS.h"
|
||||
//#import "PBGitTreePreviewItem.h"
|
||||
|
||||
#define ICON_SIZE 48.0
|
||||
|
||||
static NSDictionary* quickLookOptions = nil;
|
||||
static NSOperationQueue* treeIconQueue = nil;
|
||||
|
||||
|
||||
@interface PBGitTree (QLPreviewItemProtocol) <QLPreviewItem>
|
||||
- (NSURL *) previewItemURL;
|
||||
- (NSString *) previewItemTitle;
|
||||
@end
|
||||
|
||||
@implementation PBGitTree (QLPreviewItemProtocol)
|
||||
|
||||
- (NSURL *) previewItemURL {
|
||||
NSString * absPath = self.absolutePath;
|
||||
if ([absPath isEqualToString:[PBGitRepository basePath]]) {
|
||||
absPath = [absPath stringByAppendingFormat:@"/%@", [self fullPath]];
|
||||
}
|
||||
return [NSURL fileURLWithPath:absPath];
|
||||
}
|
||||
|
||||
- (NSString *) previewItemTitle {
|
||||
return [self fullPath];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation PBGitTree
|
||||
|
||||
@synthesize sha, path, repository, leaf, parent;
|
||||
@synthesize sha, path, repository, leaf, parent, iconImage, absolutePath;
|
||||
|
||||
+ (PBGitTree*) rootForCommit:(id) commit
|
||||
{
|
||||
@@ -40,12 +67,39 @@
|
||||
|
||||
- init
|
||||
{
|
||||
children = nil;
|
||||
localFileName = nil;
|
||||
leaf = YES;
|
||||
if (self = [super init]) {
|
||||
children = nil;
|
||||
localFileName = nil;
|
||||
leaf = YES;
|
||||
absolutePath = [PBGitRepository basePath];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSImage *) iconImage {
|
||||
if (!iconImage) {
|
||||
iconImage = [[NSWorkspace sharedWorkspace] iconForFile:self.absolutePath ];
|
||||
[iconImage setSize:NSMakeSize(ICON_SIZE, ICON_SIZE)];
|
||||
|
||||
if (!treeIconQueue) {
|
||||
treeIconQueue = [[NSOperationQueue alloc] init];
|
||||
[treeIconQueue setMaxConcurrentOperationCount:2];
|
||||
quickLookOptions = [[NSDictionary alloc] initWithObjectsAndKeys:
|
||||
(id)kCFBooleanTrue, (id)kQLThumbnailOptionIconModeKey,
|
||||
nil];
|
||||
}
|
||||
[treeIconQueue addOperationWithBlock:^{
|
||||
CGImageRef quickLookIcon = QLThumbnailImageCreate(NULL, (CFURLRef)[NSURL fileURLWithPath:self.absolutePath], CGSizeMake(ICON_SIZE, ICON_SIZE), (CFDictionaryRef)quickLookOptions);
|
||||
if (quickLookIcon != NULL) {
|
||||
NSImage* betterIcon = [[NSImage alloc] initWithCGImage:quickLookIcon size:NSMakeSize(ICON_SIZE, ICON_SIZE)];
|
||||
[self performSelectorOnMainThread:@selector(setIconImage:) withObject:betterIcon waitUntilDone:NO];
|
||||
CFRelease(quickLookIcon);
|
||||
}
|
||||
}];
|
||||
}
|
||||
return iconImage;
|
||||
}
|
||||
|
||||
- (NSString*) refSpec
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@:%@", self.sha, self.fullPath];
|
||||
@@ -157,7 +211,7 @@
|
||||
NSData* data = [handle readDataToEndOfFile];
|
||||
[data writeToFile:newName atomically:YES];
|
||||
} else { // Directory
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:newName attributes:nil];
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:newName withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
for (PBGitTree* child in [self children])
|
||||
[child saveToFolder: newName];
|
||||
}
|
||||
@@ -215,10 +269,10 @@
|
||||
NSMutableArray* c = [NSMutableArray array];
|
||||
|
||||
NSString* p = [handle readLine];
|
||||
while (p.length > 0) {
|
||||
BOOL isLeaf = ([p characterAtIndex:p.length - 1] != '/');
|
||||
while ([p length] > 0) {
|
||||
BOOL isLeaf = ([p characterAtIndex:[p length]- 1] != '/');
|
||||
if (!isLeaf)
|
||||
p = [p substringToIndex:p.length -1];
|
||||
p = [p substringToIndex:[p length]-1];
|
||||
|
||||
PBGitTree* child = [PBGitTree treeForTree:self andPath:p];
|
||||
child.leaf = isLeaf;
|
||||
@@ -235,16 +289,16 @@
|
||||
if (!parent)
|
||||
return @"";
|
||||
|
||||
if ([parent.fullPath isEqualToString:@""])
|
||||
if ([[parent fullPath] isEqualToString:@""])
|
||||
return self.path;
|
||||
|
||||
return [parent.fullPath stringByAppendingPathComponent: self.path];
|
||||
return [[parent fullPath] stringByAppendingPathComponent: self.path];
|
||||
}
|
||||
|
||||
- (void) finalize
|
||||
{
|
||||
if (localFileName)
|
||||
[[NSFileManager defaultManager] removeFileAtPath:localFileName handler:nil];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:localFileName error:nil];
|
||||
[super finalize];
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
- (void)windowWillClose:(NSNotification *)notification
|
||||
{
|
||||
NSLog(@"Window will close!");
|
||||
//NSLog(@"Window will close!");
|
||||
if (historyViewController)
|
||||
[historyViewController removeView];
|
||||
if (commitViewController)
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@
|
||||
|
||||
/* Implemented to satisfy datasourcee protocol */
|
||||
- (BOOL) outlineView: (NSOutlineView *)ov
|
||||
isItemExpandable: (id)item { return NO; }
|
||||
isItemExpandable: (id)item { return YES; }
|
||||
|
||||
- (NSInteger) outlineView: (NSOutlineView *)ov
|
||||
numberOfChildrenOfItem:(id)item { return 0; }
|
||||
|
||||
Reference in New Issue
Block a user