From 75e8a5b9b10aeb28008114983efbaa4a5eb8aad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Berg?= Date: Tue, 20 Oct 2009 04:12:06 +0200 Subject: [PATCH] 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. --- ApplicationController.h | 3 + ApplicationController.m | 23 +++-- PBGitHistoryController.h | 31 ++++--- PBGitHistoryController.m | 178 +++++++++++++++++++++++++++++---------- PBGitRepository.h | 2 + PBGitRepository.m | 44 ++++++---- PBGitTree.h | 8 +- PBGitTree.m | 76 ++++++++++++++--- PBGitWindowController.m | 2 +- PBQLOutlineView.m | 2 +- 10 files changed, 275 insertions(+), 94 deletions(-) diff --git a/ApplicationController.h b/ApplicationController.h index 1c8e5f4..428f72a 100644 --- a/ApplicationController.h +++ b/ApplicationController.h @@ -7,6 +7,7 @@ // #import +#import /* for QLPreviewPanel */ #import "PBGitRepository.h" @class PBCLIProxy; @@ -35,4 +36,6 @@ - (IBAction)saveAction:sender; - (IBAction) showHelp:(id) sender; +- (IBAction)togglePreviewPanel:(id)previewPanel; + @end diff --git a/ApplicationController.m b/ApplicationController.m index 3bc6724..4e20a62 100644 --- a/ApplicationController.m +++ b/ApplicationController.m @@ -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. diff --git a/PBGitHistoryController.h b/PBGitHistoryController.h index fadb6cd..76e322f 100644 --- a/PBGitHistoryController.h +++ b/PBGitHistoryController.h @@ -11,22 +11,25 @@ #import "PBGitTree.h" #import "PBViewController.h" #import "PBCollapsibleSplitView.h" +#import /* 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 { + 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; diff --git a/PBGitHistoryController.m b/PBGitHistoryController.m index a9fde36..177262b 100644 --- a/PBGitHistoryController.m +++ b/PBGitHistoryController.m @@ -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 )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 )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 )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 + diff --git a/PBGitRepository.h b/PBGitRepository.h index 93c38c9..96aec78 100644 --- a/PBGitRepository.h +++ b/PBGitRepository.h @@ -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 diff --git a/PBGitRepository.m b/PBGitRepository.m index 821cd2a..106b5a3 100644 --- a/PBGitRepository.m +++ b/PBGitRepository.m @@ -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 diff --git a/PBGitTree.h b/PBGitTree.h index d48ab6e..28f7ba7 100644 --- a/PBGitTree.h +++ b/PBGitTree.h @@ -7,9 +7,11 @@ // #import +#import #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 diff --git a/PBGitTree.m b/PBGitTree.m index c8003d1..5837e92 100644 --- a/PBGitTree.m +++ b/PBGitTree.m @@ -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) +- (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 diff --git a/PBGitWindowController.m b/PBGitWindowController.m index aba1987..359e7f5 100644 --- a/PBGitWindowController.m +++ b/PBGitWindowController.m @@ -34,7 +34,7 @@ - (void)windowWillClose:(NSNotification *)notification { - NSLog(@"Window will close!"); + //NSLog(@"Window will close!"); if (historyViewController) [historyViewController removeView]; if (commitViewController) diff --git a/PBQLOutlineView.m b/PBQLOutlineView.m index 459d908..d4f6bd7 100644 --- a/PBQLOutlineView.m +++ b/PBQLOutlineView.m @@ -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; }