diff --git a/ApplicationController.m b/ApplicationController.m index ddf66c2..d964bf6 100644 --- a/ApplicationController.m +++ b/ApplicationController.m @@ -28,8 +28,9 @@ #endif if(self = [super init]) { - if(![[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/QuickLookUI.framework"] load]) - NSLog(@"Could not load QuickLook"); + if(![[NSBundle bundleWithPath:@"/System/Library/Frameworks/Quartz.framework/Frameworks/QuickLookUI.framework"] load]) + if(![[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/QuickLookUI.framework"] load]) + NSLog(@"Could not load QuickLook"); self.cliProxy = [PBCLIProxy new]; } diff --git a/CWQuickLook.h b/CWQuickLook.h index df1de9c..21d0315 100644 --- a/CWQuickLook.h +++ b/CWQuickLook.h @@ -1,5 +1,12 @@ @interface QLPreviewPanel : NSPanel + (id)sharedPreviewPanel; + +// part of the public QL API ++ (BOOL)sharedPreviewPanelExists; +- (void)reloadData; +- (void)setDataSource:(id)source; + +// the private QL API + (id)_previewPanel; + (BOOL)isSharedPreviewPanelLoaded; - (id)initWithContentRect:(struct _NSRect)fp8 styleMask:(unsigned int)fp24 backing:(unsigned int)fp28 defer:(BOOL)fp32; diff --git a/English.lproj/MainMenu.xib b/English.lproj/MainMenu.xib index c35b2c1..bec5dd0 100644 --- a/English.lproj/MainMenu.xib +++ b/English.lproj/MainMenu.xib @@ -3,16 +3,15 @@ 1050 10C540 - 759 + 762 1038.25 458.00 com.apple.InterfaceBuilder.CocoaPlugin - 759 + 762 YES - YES @@ -2723,7 +2722,7 @@ showAddRemoteSheet: showCommitsFromTree: showInFinderAction: - toggleQuickView: + toggleQLPreviewPanel: YES @@ -3888,5 +3887,18 @@ YES ../GitX.xcodeproj 3 + + YES + + YES + NSMenuCheckmark + NSMenuMixedState + + + YES + {9, 8} + {7, 2} + + diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index 7d0196f..34a4edb 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -70,6 +70,7 @@ D8A4BD071134AD2900E92D51 /* CherryPickTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = D8A4BD041134AD2900E92D51 /* CherryPickTemplate.png */; }; D8A4BD081134AD2900E92D51 /* MergeTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = D8A4BD051134AD2900E92D51 /* MergeTemplate.png */; }; D8A4BD091134AD2900E92D51 /* RebaseTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = D8A4BD061134AD2900E92D51 /* RebaseTemplate.png */; }; + D8E105471157C18200FC28A4 /* PBQLTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = D8E105461157C18200FC28A4 /* PBQLTextView.m */; }; D8E3B2B810DC9FB2001096A3 /* ScriptingBridge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8E3B2B710DC9FB2001096A3 /* ScriptingBridge.framework */; }; D8E3B34D10DCA958001096A3 /* PBCreateTagSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = D8E3B34C10DCA958001096A3 /* PBCreateTagSheet.m */; }; D8FDD9F711432A12005647F6 /* PBCloneRepositoryPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = D8FDD9F511432A12005647F6 /* PBCloneRepositoryPanel.xib */; }; @@ -286,6 +287,8 @@ D8A4BD051134AD2900E92D51 /* MergeTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = MergeTemplate.png; path = Images/MergeTemplate.png; sourceTree = ""; }; D8A4BD061134AD2900E92D51 /* RebaseTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = RebaseTemplate.png; path = Images/RebaseTemplate.png; sourceTree = ""; }; D8C1B77210E875CF009B7F8B /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/PBRemoteProgressSheet.xib; sourceTree = ""; }; + D8E105451157C18200FC28A4 /* PBQLTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBQLTextView.h; sourceTree = ""; }; + D8E105461157C18200FC28A4 /* PBQLTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBQLTextView.m; sourceTree = ""; }; D8E3B2B710DC9FB2001096A3 /* ScriptingBridge.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ScriptingBridge.framework; path = /System/Library/Frameworks/ScriptingBridge.framework; sourceTree = ""; }; D8E3B34B10DCA958001096A3 /* PBCreateTagSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBCreateTagSheet.h; sourceTree = ""; }; D8E3B34C10DCA958001096A3 /* PBCreateTagSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBCreateTagSheet.m; sourceTree = ""; }; @@ -729,6 +732,8 @@ F53EE3590E06BBA00022B925 /* CWQuickLook.h */, F51308590E0740F2000C8BCD /* PBQLOutlineView.h */, F513085A0E0740F2000C8BCD /* PBQLOutlineView.m */, + D8E105451157C18200FC28A4 /* PBQLTextView.h */, + D8E105461157C18200FC28A4 /* PBQLTextView.m */, 91B103CA0E898EC300C84364 /* PBIconAndTextCell.h */, 91B103CB0E898EC300C84364 /* PBIconAndTextCell.m */, F5140DC70E8A8EB20091E9F3 /* RoundedRectangle.h */, @@ -1175,6 +1180,7 @@ D828A4111127B1C400F09D11 /* PBSourceViewBadge.m in Sources */, D8295D2A1130A1DC00C838E8 /* PBGitHistoryList.m in Sources */, D8295DE01130E43900C838E8 /* PBGitHistoryGrapher.m in Sources */, + D8E105471157C18200FC28A4 /* PBQLTextView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PBCommitList.m b/PBCommitList.m index 264b5e2..e2f6f23 100644 --- a/PBCommitList.m +++ b/PBCommitList.m @@ -28,12 +28,15 @@ return; } - if ([character isEqualToString:@" "]) - { - if ([event modifierFlags] & NSShiftKeyMask) - [webView scrollPageUp: self]; + if ([character isEqualToString:@" "]) { + if (controller.selectedCommitDetailsIndex == 0) { + if ([event modifierFlags] & NSShiftKeyMask) + [webView scrollPageUp:self]; + else + [webView scrollPageDown:self]; + } else - [webView scrollPageDown: self]; + [controller toggleQLPreviewPanel:self]; } else if ([character rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"jkcv"]].location == 0) [webController sendKey: character]; diff --git a/PBGitHistoryController.h b/PBGitHistoryController.h index 3b09d61..6dac4d4 100644 --- a/PBGitHistoryController.h +++ b/PBGitHistoryController.h @@ -15,6 +15,7 @@ @class PBGitSidebarController; @class PBGitGradientBarView; @class PBRefController; +@class QLPreviewPanel; @interface PBGitHistoryController : PBViewController { IBOutlet PBRefController *refController; @@ -24,6 +25,7 @@ IBOutlet NSOutlineView* fileBrowser; IBOutlet NSTableView* commitList; IBOutlet PBCollapsibleSplitView *historySplitView; + QLPreviewPanel* previewPanel; IBOutlet PBGitGradientBarView *upperToolbarView; IBOutlet NSButton *mergeButton; @@ -56,7 +58,7 @@ - (void) selectCommit: (NSString*) commit; - (IBAction) refresh: sender; -- (IBAction) toggleQuickView: sender; +- (IBAction) toggleQLPreviewPanel:(id)sender; - (IBAction) openSelectedFile: sender; - (void) updateQuicklookForce: (BOOL) force; diff --git a/PBGitHistoryController.m b/PBGitHistoryController.m index 7f950bf..5d04af9 100644 --- a/PBGitHistoryController.m +++ b/PBGitHistoryController.m @@ -245,36 +245,49 @@ } -- (IBAction) toggleQuickView: sender +- (IBAction) toggleQLPreviewPanel:(id)sender { - id panel = [QLPreviewPanel sharedPreviewPanel]; - if ([panel isOpen]) { - [panel closePanel]; - } else { - [[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFrontWithEffect:1]; - [self updateQuicklookForce: YES]; + if ([[QLPreviewPanel sharedPreviewPanel] respondsToSelector:@selector(setDataSource:)]) { + // Public QL API + if ([QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible]) + [[QLPreviewPanel sharedPreviewPanel] orderOut:nil]; + else + [[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil]; + } + else { + // Private QL API (10.5 only) + if ([[QLPreviewPanel sharedPreviewPanel] isOpen]) + [[QLPreviewPanel sharedPreviewPanel] closePanel]; + else { + [[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFrontWithEffect:1]; + [self updateQuicklookForce:YES]; + } } } -- (void) updateQuicklookForce: (BOOL) force +- (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]]; + + if ([[QLPreviewPanel sharedPreviewPanel] respondsToSelector:@selector(setDataSource:)]) { + // Public QL API + [previewPanel reloadData]; + } + else { + // Private QL API (10.5 only) + NSArray *selectedFiles = [treeController selectedObjects]; + + NSMutableArray *fileNames = [NSMutableArray array]; + for (PBGitTree *tree in selectedFiles) { + NSString *filePath = [tree tmpFileNameForContents]; + if (filePath) + [fileNames addObject:[NSURL fileURLWithPath:filePath]]; + } + + if ([fileNames count]) + [[QLPreviewPanel sharedPreviewPanel] setURLs:fileNames currentIndex:0 preservingDisplayState:YES]; } - - [[QLPreviewPanel sharedPreviewPanel] setURLs:fileNames currentIndex:0 preservingDisplayState:YES]; - } - (IBAction) refresh: sender @@ -535,6 +548,85 @@ [repository rebaseBranch:headRef onRefish:selectedCommit]; } } - + +#pragma mark - +#pragma mark Quick Look Public API support + +@protocol QLPreviewItem; + +#pragma mark (QLPreviewPanelController) + +- (BOOL) acceptsPreviewPanelControl:(id)panel +{ + return YES; +} + +- (void)beginPreviewPanelControl:(id)panel +{ + // This document is now responsible of the preview panel + // It is allowed to set the delegate, data source and refresh panel. + previewPanel = panel; + [previewPanel setDelegate:self]; + [previewPanel setDataSource:self]; +} + +- (void)endPreviewPanelControl:(id)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 = nil; +} + +#pragma mark + +- (NSInteger)numberOfPreviewItemsInPreviewPanel:(id)panel +{ + return [[fileBrowser selectedRowIndexes] count]; +} + +- (id )previewPanel:(id)panel previewItemAtIndex:(NSInteger)index +{ + PBGitTree *treeItem = (PBGitTree *)[[treeController selectedObjects] objectAtIndex:index]; + NSURL *previewURL = [NSURL fileURLWithPath:[treeItem tmpFileNameForContents]]; + + return ()previewURL; +} + +#pragma mark + +- (BOOL)previewPanel:(id)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:(id)panel sourceFrameOnScreenForPreviewItem:(id )item +{ + NSInteger index = [fileBrowser rowForItem:[[treeController selectedNodes] objectAtIndex:0]]; + if (index == NSNotFound) { + return NSZeroRect; + } + + NSRect iconRect = [fileBrowser frameOfCellAtColumn:0 row: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; +} @end diff --git a/PBGitHistoryView.xib b/PBGitHistoryView.xib index 6512013..179a855 100644 --- a/PBGitHistoryView.xib +++ b/PBGitHistoryView.xib @@ -3,7 +3,7 @@ 1050 10C540 - 759 + 762 1038.25 458.00 @@ -15,13 +15,13 @@ YES - 759 - 759 + 762 + 762 YES - + YES @@ -1400,14 +1400,6 @@ 62 - - - toggleQuickView: - - - - 66 - selectedIndex: selectedCommitDetailsIndex @@ -1926,6 +1918,38 @@ 393 + + + toggleQLPreviewPanel: + + + + 395 + + + + controller + + + + 396 + + + + enabled: selectedCommitDetailsIndex + + + + + + enabled: selectedCommitDetailsIndex + enabled + selectedCommitDetailsIndex + 2 + + + 398 + @@ -2480,6 +2504,7 @@ -3.IBPluginDependency 10.IBPluginDependency 11.IBPluginDependency + 12.CustomClassName 12.IBPluginDependency 13.IBPluginDependency 14.IBPluginDependency @@ -2568,6 +2593,7 @@ 46.IBEditorWindowLastContentRect 46.IBPluginDependency 48.IBPluginDependency + 49.IBAttributePlaceholdersKey 49.IBPluginDependency 50.IBPluginDependency 51.IBPluginDependency @@ -2581,6 +2607,7 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + PBQLTextView com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -2737,6 +2764,14 @@ {{627, 791}, {852, 432}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + ToolTip + + ToolTip + + Quick Look + + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -2762,7 +2797,7 @@ - 393 + 398 @@ -2842,7 +2877,7 @@ showAddRemoteSheet: showCommitsFromTree: showInFinderAction: - toggleQuickView: + toggleQLPreviewPanel: YES @@ -2958,6 +2993,18 @@ PBQLOutlineView.h + + PBQLTextView + NSTextView + + controller + PBGitHistoryController + + + IBProjectSource + PBQLTextView.h + + PBRefController NSObject @@ -3049,6 +3096,10 @@ PBViewController NSViewController + + refresh: + id + IBProjectSource PBViewController.h @@ -3847,7 +3898,9 @@ AddBranchTemplate AddLabelTemplate CherryPickTemplate + DetailViewTemplate MergeTemplate + NSPathTemplate NSQuickLookTemplate RebaseTemplate @@ -3856,7 +3909,9 @@ {20, 12} {23, 12} {18.5143, 12.3429} + {17, 17} {16.4571, 12.3429} + {16, 9} {19, 11} {16.4571, 13.3714} diff --git a/PBQLOutlineView.m b/PBQLOutlineView.m index c3dde23..05f9790 100644 --- a/PBQLOutlineView.m +++ b/PBQLOutlineView.m @@ -28,7 +28,7 @@ - (void) keyDown: (NSEvent *) event { if ([[event characters] isEqualToString:@" "]) { - [controller toggleQuickView:self]; + [controller toggleQLPreviewPanel:self]; return; } diff --git a/PBQLTextView.h b/PBQLTextView.h new file mode 100644 index 0000000..715e74e --- /dev/null +++ b/PBQLTextView.h @@ -0,0 +1,19 @@ +// +// PBQLTextView.h +// GitX +// +// Created by Nathan Kinsinger on 3/22/10. +// Copyright 2010 Nathan Kinsinger. All rights reserved. +// + +#import + + +@class PBGitHistoryController; + + +@interface PBQLTextView : NSTextView { + IBOutlet PBGitHistoryController *controller; +} + +@end diff --git a/PBQLTextView.m b/PBQLTextView.m new file mode 100644 index 0000000..fccb3ad --- /dev/null +++ b/PBQLTextView.m @@ -0,0 +1,25 @@ +// +// PBQLTextView.m +// GitX +// +// Created by Nathan Kinsinger on 3/22/10. +// Copyright 2010 Nathan Kinsinger. All rights reserved. +// + +#import "PBQLTextView.h" +#import "PBGitHistoryController.h" + + +@implementation PBQLTextView + +- (void) keyDown: (NSEvent *) event +{ + if ([[event characters] isEqualToString:@" "]) { + [controller toggleQLPreviewPanel:self]; + return; + } + + [super keyDown:event]; +} + +@end