Improve search UI

Previously searching would filter the commits in the commit tableview to only show the commits that matched the search. However the context of where those commits exist in the history is lost.

With this patch all the commits are shown but the commits that match the search are highlighted with a light blue background. In addition there is a forward/back button to step through the matches.

A new search controller:
    - keeps track of the matching results
    - finds the next or previous result
    - displays the number of matches found or "Not found"
    - shows/hides the # of matches text and the next/last stepper button
    - shows a small bezel style window with a rewind icon indicating that the selection has cycled (pressing next when at the last match or previous when at the first)
    - sets up the search predicate which covers Subject, Author and SHA (previously this was three different searches)
    - stores search results in an NSIndexSet to make finding if a row is in the set faster (needed at drawing time)

Highlighting of search result rows is done in PBCommitList -drawRow:clipRect:

PBGitTextFieldCell is a subclass of NSTextFieldCell that disables the cell's selection highlighting.

Supporting Find Next and Find Previous (cmd-g and cmd-shift-g) menu commands required changing the action method of the menu items because NSTextFields (seem to) actively disable items in the Find menu.

rewindImage.pdf created by Nathan Kinsinger
This commit is contained in:
Nathan Kinsinger
2010-08-29 00:00:34 -06:00
parent 80596add94
commit 4fad6b60a3
13 changed files with 1057 additions and 148 deletions
+149 -21
View File
@@ -3,16 +3,15 @@
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10F569</string>
<string key="IBDocument.InterfaceBuilderVersion">804</string>
<string key="IBDocument.InterfaceBuilderVersion">788</string>
<string key="IBDocument.AppKitVersion">1038.29</string>
<string key="IBDocument.HIToolboxVersion">461.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">804</string>
<string key="NS.object.0">788</string>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="169"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1104,22 +1103,6 @@
</object>
<int key="connectionID">199</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">performFindPanelAction:</string>
<reference key="source" ref="954860085"/>
<reference key="destination" ref="416521231"/>
</object>
<int key="connectionID">200</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">performFindPanelAction:</string>
<reference key="source" ref="954860085"/>
<reference key="destination" ref="219112383"/>
</object>
<int key="connectionID">201</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">performFindPanelAction:</string>
@@ -1368,6 +1351,22 @@
</object>
<int key="connectionID">966</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">selectNext:</string>
<reference key="source" ref="954860085"/>
<reference key="destination" ref="416521231"/>
</object>
<int key="connectionID">967</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">selectPrevious:</string>
<reference key="source" ref="954860085"/>
<reference key="destination" ref="219112383"/>
</object>
<int key="connectionID">968</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -2332,7 +2331,7 @@
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>{{864, 473}, {238, 103}}</string>
<string>{{762, 747}, {238, 103}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -2498,7 +2497,7 @@
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">966</int>
<int key="maxID">968</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -2665,6 +2664,13 @@
<string key="minorKey"/>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">NSApplication+GitXScripting.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSOutlineView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -2688,12 +2694,14 @@
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>controller</string>
<string>searchController</string>
<string>webController</string>
<string>webView</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>PBGitHistoryController</string>
<string>PBHistorySearchController</string>
<string>PBWebHistoryController</string>
<string>WebView</string>
</object>
@@ -2703,6 +2711,7 @@
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>controller</string>
<string>searchController</string>
<string>webController</string>
<string>webView</string>
</object>
@@ -2712,6 +2721,10 @@
<string key="name">controller</string>
<string key="candidateClassName">PBGitHistoryController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">searchController</string>
<string key="candidateClassName">PBHistorySearchController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">webController</string>
<string key="candidateClassName">PBWebHistoryController</string>
@@ -3148,6 +3161,7 @@
<string>rebaseButton</string>
<string>refController</string>
<string>scopeBarView</string>
<string>searchController</string>
<string>searchField</string>
<string>selectedBranchFilterItem</string>
<string>treeController</string>
@@ -3168,6 +3182,7 @@
<string>NSButton</string>
<string>PBRefController</string>
<string>PBGitGradientBarView</string>
<string>PBHistorySearchController</string>
<string>NSSearchField</string>
<string>NSButton</string>
<string>NSTreeController</string>
@@ -3191,6 +3206,7 @@
<string>rebaseButton</string>
<string>refController</string>
<string>scopeBarView</string>
<string>searchController</string>
<string>searchField</string>
<string>selectedBranchFilterItem</string>
<string>treeController</string>
@@ -3244,6 +3260,10 @@
<string key="name">scopeBarView</string>
<string key="candidateClassName">PBGitGradientBarView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">searchController</string>
<string key="candidateClassName">PBHistorySearchController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">searchField</string>
<string key="candidateClassName">NSSearchField</string>
@@ -3617,6 +3637,78 @@
<string key="minorKey"/>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PBHistorySearchController</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">stepperPressed:</string>
<string key="NS.object.0">id</string>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<string key="NS.key.0">stepperPressed:</string>
<object class="IBActionInfo" key="NS.object.0">
<string key="name">stepperPressed:</string>
<string key="candidateClassName">id</string>
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>commitController</string>
<string>historyController</string>
<string>numberOfMatchesField</string>
<string>searchField</string>
<string>stepper</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSArrayController</string>
<string>PBGitHistoryController</string>
<string>NSTextField</string>
<string>NSSearchField</string>
<string>NSSegmentedControl</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>commitController</string>
<string>historyController</string>
<string>numberOfMatchesField</string>
<string>searchField</string>
<string>stepper</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">commitController</string>
<string key="candidateClassName">NSArrayController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">historyController</string>
<string key="candidateClassName">PBGitHistoryController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">numberOfMatchesField</string>
<string key="candidateClassName">NSTextField</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">searchField</string>
<string key="candidateClassName">NSSearchField</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">stepper</string>
<string key="candidateClassName">NSSegmentedControl</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">PBHistorySearchController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PBNiceSplitView</string>
<string key="superclassName">NSSplitView</string>
@@ -4542,6 +4634,34 @@
<string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzCore.framework/Headers/CIImageProvider.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">ScriptingBridge.framework/Headers/SBApplication.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -4678,6 +4798,14 @@
<string key="minorKey">AppKit.framework/Headers/NSSearchField.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSSegmentedControl</string>
<string key="superclassName">NSControl</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSSegmentedControl.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSSplitView</string>
<string key="superclassName">NSView</string>
+20
View File
@@ -68,18 +68,22 @@
D858108411274D28007F254B /* RemoteBranch.png in Resources */ = {isa = PBXBuildFile; fileRef = D858108111274D28007F254B /* RemoteBranch.png */; };
D858108511274D28007F254B /* Tag.png in Resources */ = {isa = PBXBuildFile; fileRef = D858108211274D28007F254B /* Tag.png */; };
D85B939310E3D8B4007F3C28 /* PBCreateBranchSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = D85B939210E3D8B4007F3C28 /* PBCreateBranchSheet.xib */; };
D87127011229A21C00012334 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D87127001229A21C00012334 /* QuartzCore.framework */; };
D8712A00122B14EC00012334 /* GitXTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D87129FF122B14EC00012334 /* GitXTextFieldCell.m */; };
D889EB3110E6BCBB00F08413 /* PBCreateTagSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = D889EB3010E6BCBB00F08413 /* PBCreateTagSheet.xib */; };
D89E9B141218BA260097A90B /* ScriptingBridge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D89E9AB21218A9DA0097A90B /* ScriptingBridge.framework */; };
D8A4BB6F11337D5C00E92D51 /* PBGitGradientBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = D8A4BB6E11337D5C00E92D51 /* PBGitGradientBarView.m */; };
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 */; };
D8B4DC571220D1E4004166D6 /* PBHistorySearchController.m in Sources */ = {isa = PBXBuildFile; fileRef = D8B4DC561220D1E4004166D6 /* PBHistorySearchController.m */; };
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 */; };
D8EB616A122F643E00FCCAF4 /* GitXRelativeDateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = D8EB6169122F643E00FCCAF4 /* GitXRelativeDateFormatter.m */; };
D8F01C4B12182F19007F729F /* GitX.sdef in Resources */ = {isa = PBXBuildFile; fileRef = D8F01C4A12182F19007F729F /* GitX.sdef */; };
D8F01D531218A164007F729F /* NSApplication+GitXScripting.m in Sources */ = {isa = PBXBuildFile; fileRef = D8F01D521218A164007F729F /* NSApplication+GitXScripting.m */; };
D8F4AB7912298CE200D6D53C /* rewindImage.pdf in Resources */ = {isa = PBXBuildFile; fileRef = D8F4AB7812298CE200D6D53C /* rewindImage.pdf */; };
D8FBCF19115FA20C0098676A /* PBGitSHA.m in Sources */ = {isa = PBXBuildFile; fileRef = D8FBCF18115FA20C0098676A /* PBGitSHA.m */; };
D8FDD9F711432A12005647F6 /* PBCloneRepositoryPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = D8FDD9F511432A12005647F6 /* PBCloneRepositoryPanel.xib */; };
D8FDDA6A114335E8005647F6 /* PBGitSVBranchItem.m in Sources */ = {isa = PBXBuildFile; fileRef = D8FDDA5D114335E8005647F6 /* PBGitSVBranchItem.m */; };
@@ -307,6 +311,9 @@
D858108111274D28007F254B /* RemoteBranch.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = RemoteBranch.png; path = Images/RemoteBranch.png; sourceTree = "<group>"; };
D858108211274D28007F254B /* Tag.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Tag.png; path = Images/Tag.png; sourceTree = "<group>"; };
D85B93F610E51279007F3C28 /* PBGitRefish.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitRefish.h; sourceTree = "<group>"; };
D87127001229A21C00012334 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
D87129FE122B14EC00012334 /* GitXTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GitXTextFieldCell.h; sourceTree = "<group>"; };
D87129FF122B14EC00012334 /* GitXTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GitXTextFieldCell.m; sourceTree = "<group>"; };
D89E9AB21218A9DA0097A90B /* ScriptingBridge.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ScriptingBridge.framework; path = System/Library/Frameworks/ScriptingBridge.framework; sourceTree = SDKROOT; };
D89E9B4F1218C2750097A90B /* GitXScriptingConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GitXScriptingConstants.h; sourceTree = "<group>"; };
D8A4BB6D11337D5C00E92D51 /* PBGitGradientBarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitGradientBarView.h; sourceTree = "<group>"; };
@@ -314,6 +321,8 @@
D8A4BD041134AD2900E92D51 /* CherryPickTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = CherryPickTemplate.png; path = Images/CherryPickTemplate.png; sourceTree = "<group>"; };
D8A4BD051134AD2900E92D51 /* MergeTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = MergeTemplate.png; path = Images/MergeTemplate.png; sourceTree = "<group>"; };
D8A4BD061134AD2900E92D51 /* RebaseTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = RebaseTemplate.png; path = Images/RebaseTemplate.png; sourceTree = "<group>"; };
D8B4DC551220D1E4004166D6 /* PBHistorySearchController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBHistorySearchController.h; sourceTree = "<group>"; };
D8B4DC561220D1E4004166D6 /* PBHistorySearchController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBHistorySearchController.m; sourceTree = "<group>"; };
D8C1B77210E875CF009B7F8B /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/PBRemoteProgressSheet.xib; sourceTree = "<group>"; };
D8E105451157C18200FC28A4 /* PBQLTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBQLTextView.h; sourceTree = "<group>"; };
D8E105461157C18200FC28A4 /* PBQLTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBQLTextView.m; sourceTree = "<group>"; };
@@ -327,6 +336,7 @@
D8F01D511218A164007F729F /* NSApplication+GitXScripting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSApplication+GitXScripting.h"; sourceTree = "<group>"; };
D8F01D521218A164007F729F /* NSApplication+GitXScripting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSApplication+GitXScripting.m"; sourceTree = "<group>"; };
D8F01D841218A406007F729F /* GitX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GitX.h; sourceTree = "<group>"; };
D8F4AB7812298CE200D6D53C /* rewindImage.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = rewindImage.pdf; path = Images/rewindImage.pdf; sourceTree = "<group>"; };
D8FBCF17115FA20C0098676A /* PBGitSHA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitSHA.h; sourceTree = "<group>"; };
D8FBCF18115FA20C0098676A /* PBGitSHA.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitSHA.m; sourceTree = "<group>"; };
D8FDD9F611432A12005647F6 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/PBCloneRepositoryPanel.xib; sourceTree = "<group>"; };
@@ -477,6 +487,7 @@
F5E4DBFB0EAB58D90013FAFC /* SystemConfiguration.framework in Frameworks */,
F5C580E50EDA250900995434 /* libgit2.a in Frameworks */,
D8E3B2B810DC9FB2001096A3 /* ScriptingBridge.framework in Frameworks */,
D87127011229A21C00012334 /* QuartzCore.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -534,6 +545,7 @@
29B97325FDCFA39411CA2CEA /* Foundation.framework */,
29B97324FDCFA39411CA2CEA /* AppKit.framework */,
D8E3B2B710DC9FB2001096A3 /* ScriptingBridge.framework */,
D87127001229A21C00012334 /* QuartzCore.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
@@ -580,6 +592,7 @@
D858108011274D28007F254B /* Branch.png */,
D858108111274D28007F254B /* RemoteBranch.png */,
D858108211274D28007F254B /* Tag.png */,
D8F4AB7812298CE200D6D53C /* rewindImage.pdf */,
D85810541127476E007F254B /* StageView.png */,
D8FDDBF31143F318005647F6 /* AddRemote.png */,
D828A5EF1128AE7200F09D11 /* FetchTemplate.png */,
@@ -825,6 +838,8 @@
D8A4BB6E11337D5C00E92D51 /* PBGitGradientBarView.m */,
D8EB6168122F643E00FCCAF4 /* GitXRelativeDateFormatter.h */,
D8EB6169122F643E00FCCAF4 /* GitXRelativeDateFormatter.m */,
D87129FE122B14EC00012334 /* GitXTextFieldCell.h */,
D87129FF122B14EC00012334 /* GitXTextFieldCell.m */,
);
name = Aux;
sourceTree = "<group>";
@@ -952,6 +967,8 @@
F52BCE060E84211300AA3741 /* PBGitHistoryController.m */,
F574A2830EAE2EAC003F2CB1 /* PBRefController.h */,
F574A2840EAE2EAC003F2CB1 /* PBRefController.m */,
D8B4DC551220D1E4004166D6 /* PBHistorySearchController.h */,
D8B4DC561220D1E4004166D6 /* PBHistorySearchController.m */,
);
name = History;
sourceTree = "<group>";
@@ -1154,6 +1171,7 @@
D828AEEC112F411100F09D11 /* CloneRepositoryTemplate.png in Resources */,
D8022FE811E124A0003C21F6 /* PBGitXMessageSheet.xib in Resources */,
D8F01C4B12182F19007F729F /* GitX.sdef in Resources */,
D8F4AB7912298CE200D6D53C /* rewindImage.pdf in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1301,6 +1319,8 @@
D8022FED11E124C8003C21F6 /* PBGitXMessageSheet.m in Sources */,
D8EB616A122F643E00FCCAF4 /* GitXRelativeDateFormatter.m in Sources */,
D8F01D531218A164007F729F /* NSApplication+GitXScripting.m in Sources */,
D8B4DC571220D1E4004166D6 /* PBHistorySearchController.m in Sources */,
D8712A00122B14EC00012334 /* GitXTextFieldCell.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+16
View File
@@ -0,0 +1,16 @@
//
// GitXTextFieldCell.h
// GitX
//
// Created by Nathan Kinsinger on 8/27/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface GitXTextFieldCell : NSTextFieldCell {
}
@end
+20
View File
@@ -0,0 +1,20 @@
//
// GitXTextFieldCell.m
// GitX
//
// Created by Nathan Kinsinger on 8/27/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import "GitXTextFieldCell.h"
@implementation GitXTextFieldCell
- (NSColor *)highlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
// disables the cell's selection highlight
return nil;
}
@end
Binary file not shown.
+2
View File
@@ -16,6 +16,8 @@
IBOutlet WebView* webView;
IBOutlet PBWebHistoryController *webController;
IBOutlet PBGitHistoryController *controller;
IBOutlet PBHistorySearchController *searchController;
BOOL useAdjustScroll;
NSPoint mouseDownPoint;
}
+63
View File
@@ -9,6 +9,7 @@
#import "PBCommitList.h"
#import "PBGitRevisionCell.h"
#import "PBWebHistoryController.h"
#import "PBHistorySearchController.h"
@implementation PBCommitList
@@ -122,4 +123,66 @@
return newImage;
}
#pragma mark Row highlighting
- (NSColor *)searchResultHighlightColorForRow:(NSInteger)rowIndex
{
// if the row is selected use default colors
if ([self isRowSelected:rowIndex]) {
if ([[self window] isKeyWindow]) {
if ([[self window] firstResponder] == self) {
return [NSColor alternateSelectedControlColor];
}
return [NSColor selectedControlColor];
}
return [NSColor secondarySelectedControlColor];
}
// light blue color highlighting search results
return [NSColor colorWithCalibratedRed:0.751f green:0.831f blue:0.943f alpha:0.800f];
}
- (NSColor *)searchResultHighlightStrokeColorForRow:(NSInteger)rowIndex
{
if ([self isRowSelected:rowIndex])
return [NSColor colorWithCalibratedWhite:0.0f alpha:0.30f];
return [NSColor colorWithCalibratedWhite:0.0f alpha:0.05f];
}
- (void)drawRow:(NSInteger)rowIndex clipRect:(NSRect)tableViewClipRect
{
NSRect rowRect = [self rectOfRow:rowIndex];
BOOL isRowVisible = NSIntersectsRect(rowRect, tableViewClipRect);
// draw special highlighting if the row is part of search results
if (isRowVisible && [searchController isRowInSearchResults:rowIndex]) {
NSRect highlightRect = NSInsetRect(rowRect, 1.0f, 1.0f);
float radius = highlightRect.size.height / 2.0f;
NSBezierPath *highlightPath = [NSBezierPath bezierPathWithRoundedRect:highlightRect xRadius:radius yRadius:radius];
[[self searchResultHighlightColorForRow:rowIndex] set];
[highlightPath fill];
[[self searchResultHighlightStrokeColorForRow:rowIndex] set];
[highlightPath stroke];
}
// draws the content inside the row
[super drawRow:rowIndex clipRect:tableViewClipRect];
}
- (void)highlightSelectionInClipRect:(NSRect)tableViewClipRect
{
// disable highlighting if the selected row is part of search results
// instead do the highlighting in drawRow:clipRect: above
if ([searchController isRowInSearchResults:[self selectedRow]])
return;
[super highlightSelectionInClipRect:tableViewClipRect];
}
@end
+9
View File
@@ -20,6 +20,8 @@
@class PBCommitList;
@class PBGitSHA;
@class PBHistorySearchController;
@interface PBGitHistoryController : PBViewController {
IBOutlet PBRefController *refController;
IBOutlet NSSearchField *searchField;
@@ -31,6 +33,7 @@
IBOutlet PBCollapsibleSplitView *historySplitView;
IBOutlet PBWebHistoryController *webHistoryController;
QLPreviewPanel* previewPanel;
IBOutlet PBHistorySearchController *searchController;
IBOutlet PBGitGradientBarView *upperToolbarView;
IBOutlet NSButton *mergeButton;
@@ -56,6 +59,8 @@
@property (retain) PBGitTree* gitTree;
@property (readonly) NSArrayController *commitController;
@property (readonly) PBRefController *refController;
@property (readonly) PBHistorySearchController *searchController;
@property (readonly) PBCommitList *commitList;
- (IBAction) setDetailedView:(id)sender;
- (IBAction) setTreeView:(id)sender;
@@ -82,6 +87,10 @@
- (IBAction) cherryPick:(id)sender;
- (IBAction) rebase:(id)sender;
// Find/Search methods
- (IBAction)selectNext:(id)sender;
- (IBAction)selectPrevious:(id)sender;
- (void) copyCommitInfo;
- (void) copyCommitSHA;
+29 -2
View File
@@ -20,7 +20,9 @@
#import "PBDiffWindowController.h"
#import "PBGitDefaults.h"
#import "PBGitRevList.h"
#import "PBHistorySearchController.h"
#define QLPreviewPanel NSClassFromString(@"QLPreviewPanel")
#import "PBQLTextView.h"
#define kHistorySelectedDetailIndexKey @"PBHistorySelectedDetailIndex"
@@ -38,6 +40,8 @@
@implementation PBGitHistoryController
@synthesize selectedCommitDetailsIndex, webCommit, gitTree, commitController, refController;
@synthesize searchController;
@synthesize commitList;
- (void)awakeFromNib
{
@@ -298,6 +302,30 @@
[super keyDown: event];
}
// NSSearchField (actually textfields in general) prevent the normal Find operations from working. Setup custom actions for the
// next and previous menuitems (in MainMenu.nib) so they will work when the search field is active. When searching for text in
// a file make sure to call the Find panel's action method instead.
- (IBAction)selectNext:(id)sender
{
NSResponder *firstResponder = [[[self view] window] firstResponder];
if ([firstResponder isKindOfClass:[PBQLTextView class]]) {
[(PBQLTextView *)firstResponder performFindPanelAction:sender];
return;
}
[searchController selectNextResult];
}
- (IBAction)selectPrevious:(id)sender
{
NSResponder *firstResponder = [[[self view] window] firstResponder];
if ([firstResponder isKindOfClass:[PBQLTextView class]]) {
[(PBQLTextView *)firstResponder performFindPanelAction:sender];
return;
}
[searchController selectPreviousResult];
}
- (void) copyCommitInfo
{
PBGitCommit *commit = [[commitController selectedObjects] objectAtIndex:0];
@@ -436,8 +464,7 @@
NSArray *selectedCommits = [self selectedObjectsForSHA:commitSHA];
[commitController setSelectedObjects:selectedCommits];
if (repository.currentBranchFilter != kGitXSelectedBranchFilter)
[self scrollSelectionToTopOfViewFrom:oldIndex];
[self scrollSelectionToTopOfViewFrom:oldIndex];
forceSelectionUpdate = NO;
}
+388 -124
View File
@@ -21,7 +21,7 @@
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="27"/>
<integer value="311"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -702,31 +702,6 @@
<int key="NSvFlags">266</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSButton" id="832955200">
<reference key="NSNextResponder" ref="428755155"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{49, 2}, {57, 17}}</string>
<reference key="NSSuperview" ref="428755155"/>
<int key="NSTag">1</int>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="819755658">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134348800</int>
<string key="NSContents">Remote</string>
<object class="NSFont" key="NSSupport" id="689970718">
<string key="NSName">LucidaGrande-Bold</string>
<double key="NSSize">11</double>
<int key="NSfFlags">16</int>
</object>
<reference key="NSControlView" ref="832955200"/>
<int key="NSButtonFlags">-1232846593</int>
<int key="NSButtonFlags2">173</int>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
</object>
<object class="NSSearchField" id="354285291">
<reference key="NSNextResponder" ref="428755155"/>
<int key="NSvFlags">265</int>
@@ -737,7 +712,6 @@
<int key="NSCellFlags">343014976</int>
<int key="NSCellFlags2">268567552</int>
<reference key="NSSupport" ref="26"/>
<string key="NSPlaceholderString">Subject</string>
<reference key="NSControlView" ref="354285291"/>
<bool key="NSDrawsBackground">YES</bool>
<int key="NSTextBezelStyle">1</int>
@@ -788,6 +762,88 @@
<int key="NSMaximumRecents">255</int>
</object>
</object>
<object class="NSSegmentedControl" id="563692607">
<reference key="NSNextResponder" ref="428755155"/>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{611, 3}, {43, 18}}</string>
<reference key="NSSuperview" ref="428755155"/>
<bool key="NSEnabled">YES</bool>
<object class="NSSegmentedCell" key="NSCell" id="657989793">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">131072</int>
<object class="NSFont" key="NSSupport">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">9</double>
<int key="NSfFlags">16</int>
</object>
<reference key="NSControlView" ref="563692607"/>
<object class="NSMutableArray" key="NSSegmentImages">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSSegmentItem">
<double key="NSSegmentItemWidth">18</double>
<string key="NSSegmentItemLabel">◀</string>
<string key="NSSegmentItemTooltip">Previous search result</string>
<int key="NSSegmentItemImageScaling">0</int>
</object>
<object class="NSSegmentItem">
<double key="NSSegmentItemWidth">18</double>
<string key="NSSegmentItemLabel">▶</string>
<string key="NSSegmentItemTooltip">Next search result</string>
<int key="NSSegmentItemTag">1</int>
<int key="NSSegmentItemImageScaling">0</int>
</object>
</object>
<int key="NSSelectedSegment">1</int>
<int key="NSTrackingMode">2</int>
<int key="NSSegmentStyle">3</int>
</object>
</object>
<object class="NSTextField" id="627778713">
<reference key="NSNextResponder" ref="428755155"/>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{527, 5}, {80, 14}}</string>
<reference key="NSSuperview" ref="428755155"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="349876124">
<int key="NSCellFlags">68288064</int>
<int key="NSCellFlags2">71435264</int>
<string key="NSContents"># of matches</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="627778713"/>
<object class="NSColor" key="NSBackgroundColor" id="457244339">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlColor</string>
<reference key="NSColor" ref="827382333"/>
</object>
<reference key="NSTextColor" ref="57062640"/>
</object>
</object>
<object class="NSButton" id="832955200">
<reference key="NSNextResponder" ref="428755155"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{49, 2}, {57, 17}}</string>
<reference key="NSSuperview" ref="428755155"/>
<int key="NSTag">1</int>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="819755658">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134348800</int>
<string key="NSContents">Remote</string>
<object class="NSFont" key="NSSupport" id="689970718">
<string key="NSName">LucidaGrande-Bold</string>
<double key="NSSize">11</double>
<int key="NSfFlags">16</int>
</object>
<reference key="NSControlView" ref="832955200"/>
<int key="NSButtonFlags">-1232846593</int>
<int key="NSButtonFlags2">173</int>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
</object>
<object class="NSButton" id="1055854415">
<reference key="NSNextResponder" ref="428755155"/>
<int key="NSvFlags">268</int>
@@ -912,12 +968,7 @@
<string key="NSFrameSize">{852, 232}</string>
</object>
<string key="NSLabel">Details</string>
<object class="NSColor" key="NSColor" id="457244339">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlColor</string>
<reference key="NSColor" ref="827382333"/>
</object>
<reference key="NSColor" ref="457244339"/>
<reference key="NSTabView" ref="135073984"/>
</object>
<object class="NSTabViewItem" id="529992882">
@@ -1328,6 +1379,9 @@
<object class="NSCustomObject" id="246205303">
<string key="NSClassName">GitXRelativeDateFormatter</string>
</object>
<object class="NSCustomObject" id="596748029">
<string key="NSClassName">PBHistorySearchController</string>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
@@ -1709,95 +1763,6 @@
</object>
<int key="connectionID">291</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">predicate: filterPredicate</string>
<reference key="source" ref="1022125543"/>
<reference key="destination" ref="391209158"/>
<object class="NSNibBindingConnector" key="connector" id="705794394">
<reference key="NSSource" ref="1022125543"/>
<reference key="NSDestination" ref="391209158"/>
<string key="NSLabel">predicate: filterPredicate</string>
<string key="NSBinding">predicate</string>
<string key="NSKeyPath">filterPredicate</string>
<object class="NSDictionary" key="NSOptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSDisplayName</string>
<string>NSPredicateFormat</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>Subject</string>
<string>subject contains[c] $value</string>
</object>
</object>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">301</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">predicate2: filterPredicate</string>
<reference key="source" ref="1022125543"/>
<reference key="destination" ref="391209158"/>
<object class="NSNibBindingConnector" key="connector" id="727925491">
<reference key="NSSource" ref="1022125543"/>
<reference key="NSDestination" ref="391209158"/>
<string key="NSLabel">predicate2: filterPredicate</string>
<string key="NSBinding">predicate2</string>
<string key="NSKeyPath">filterPredicate</string>
<object class="NSDictionary" key="NSOptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSDisplayName</string>
<string>NSPredicateFormat</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>Author</string>
<string>author contains[c] $value</string>
</object>
</object>
<reference key="NSPreviousConnector" ref="705794394"/>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">304</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">predicate3: filterPredicate</string>
<reference key="source" ref="1022125543"/>
<reference key="destination" ref="391209158"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="1022125543"/>
<reference key="NSDestination" ref="391209158"/>
<string key="NSLabel">predicate3: filterPredicate</string>
<string key="NSBinding">predicate3</string>
<string key="NSKeyPath">filterPredicate</string>
<object class="NSDictionary" key="NSOptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSDisplayName</string>
<string>NSPredicateFormat</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>SHA</string>
<string>realSha contains[c] $value</string>
</object>
</object>
<reference key="NSPreviousConnector" ref="727925491"/>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">308</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">searchField</string>
@@ -2050,6 +2015,86 @@
</object>
<int key="connectionID">422</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">commitController</string>
<reference key="source" ref="596748029"/>
<reference key="destination" ref="391209158"/>
</object>
<int key="connectionID">424</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">historyController</string>
<reference key="source" ref="596748029"/>
<reference key="destination" ref="1001"/>
</object>
<int key="connectionID">425</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">searchField</string>
<reference key="source" ref="596748029"/>
<reference key="destination" ref="354285291"/>
</object>
<int key="connectionID">426</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">stepper</string>
<reference key="source" ref="596748029"/>
<reference key="destination" ref="563692607"/>
</object>
<int key="connectionID">429</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">numberOfMatchesField</string>
<reference key="source" ref="596748029"/>
<reference key="destination" ref="627778713"/>
</object>
<int key="connectionID">432</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="354285291"/>
<reference key="destination" ref="596748029"/>
</object>
<int key="connectionID">433</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">updateSearch:</string>
<reference key="source" ref="596748029"/>
<reference key="destination" ref="1022125543"/>
</object>
<int key="connectionID">434</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">stepperPressed:</string>
<reference key="source" ref="596748029"/>
<reference key="destination" ref="563692607"/>
</object>
<int key="connectionID">435</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">searchController</string>
<reference key="source" ref="254268962"/>
<reference key="destination" ref="596748029"/>
</object>
<int key="connectionID">436</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">searchController</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="596748029"/>
</object>
<int key="connectionID">437</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -2387,10 +2432,12 @@
<reference key="object" ref="428755155"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="354285291"/>
<reference ref="884073279"/>
<reference ref="1055854415"/>
<reference ref="832955200"/>
<reference ref="627778713"/>
<reference ref="354285291"/>
<reference ref="563692607"/>
</object>
<reference key="parent" ref="24227530"/>
<string key="objectName">Commits Scope Bar</string>
@@ -2614,6 +2661,39 @@
<reference key="object" ref="493129112"/>
<reference key="parent" ref="760984800"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">423</int>
<reference key="object" ref="596748029"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">427</int>
<reference key="object" ref="563692607"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="657989793"/>
</object>
<reference key="parent" ref="428755155"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">428</int>
<reference key="object" ref="657989793"/>
<reference key="parent" ref="563692607"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">430</int>
<reference key="object" ref="627778713"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="349876124"/>
</object>
<reference key="parent" ref="428755155"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">431</int>
<reference key="object" ref="349876124"/>
<reference key="parent" ref="627778713"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -2650,6 +2730,7 @@
<string>28.IBPluginDependency</string>
<string>28.IBShouldRemoveOnLegacySave</string>
<string>287.IBPluginDependency</string>
<string>288.CustomClassName</string>
<string>288.IBPluginDependency</string>
<string>29.IBPluginDependency</string>
<string>29.IBShouldRemoveOnLegacySave</string>
@@ -2680,6 +2761,7 @@
<string>337.IBAttributePlaceholdersKey</string>
<string>337.IBPluginDependency</string>
<string>338.IBPluginDependency</string>
<string>34.CustomClassName</string>
<string>34.IBPluginDependency</string>
<string>340.IBAttributePlaceholdersKey</string>
<string>340.IBPluginDependency</string>
@@ -2695,6 +2777,7 @@
<string>356.IBPluginDependency</string>
<string>359.IBAttributePlaceholdersKey</string>
<string>359.IBPluginDependency</string>
<string>36.CustomClassName</string>
<string>36.IBPluginDependency</string>
<string>36.ImportedFromIB2</string>
<string>360.IBPluginDependency</string>
@@ -2707,11 +2790,18 @@
<string>4.IBAttributePlaceholdersKey</string>
<string>4.IBPluginDependency</string>
<string>409.IBPluginDependency</string>
<string>410.CustomClassName</string>
<string>410.IBPluginDependency</string>
<string>414.IBDateFormatterBehaviorMetadataKey</string>
<string>414.IBPluginDependency</string>
<string>418.IBPluginDependency</string>
<string>419.CustomClassName</string>
<string>419.IBPluginDependency</string>
<string>427.IBPluginDependency</string>
<string>428.IBPluginDependency</string>
<string>428.IBSegmentedControlInspectorSelectedSegmentMetadataKey</string>
<string>430.IBPluginDependency</string>
<string>431.IBPluginDependency</string>
<string>46.IBEditorWindowLastContentRect</string>
<string>46.IBPluginDependency</string>
<string>48.IBPluginDependency</string>
@@ -2762,6 +2852,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>GitXTextFieldCell</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
@@ -2813,6 +2904,7 @@
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>GitXTextFieldCell</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSMutableDictionary">
<string key="NS.key.0">ToolTip</string>
@@ -2856,6 +2948,7 @@
</object>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>GitXTextFieldCell</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -2881,10 +2974,17 @@
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>GitXTextFieldCell</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>GitXTextFieldCell</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="0"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{9, 486}, {852, 432}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -2922,7 +3022,7 @@
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">422</int>
<int key="maxID">437</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -2935,6 +3035,21 @@
<string key="minorKey">GitXRelativeDateFormatter.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">GitXTextFieldCell</string>
<string key="superclassName">NSTextFieldCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">GitXTextFieldCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">NSApplication+GitXScripting.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSOutlineView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -2958,12 +3073,14 @@
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>controller</string>
<string>searchController</string>
<string>webController</string>
<string>webView</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>PBGitHistoryController</string>
<string>PBHistorySearchController</string>
<string>PBWebHistoryController</string>
<string>WebView</string>
</object>
@@ -2973,6 +3090,7 @@
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>controller</string>
<string>searchController</string>
<string>webController</string>
<string>webView</string>
</object>
@@ -2982,6 +3100,10 @@
<string key="name">controller</string>
<string key="candidateClassName">PBGitHistoryController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">searchController</string>
<string key="candidateClassName">PBHistorySearchController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">webController</string>
<string key="candidateClassName">PBWebHistoryController</string>
@@ -3028,6 +3150,8 @@
<string>openSelectedFile:</string>
<string>rebase:</string>
<string>refresh:</string>
<string>selectNext:</string>
<string>selectPrevious:</string>
<string>setBranchFilter:</string>
<string>setDetailedView:</string>
<string>setTreeView:</string>
@@ -3053,6 +3177,8 @@
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
@@ -3067,6 +3193,8 @@
<string>openSelectedFile:</string>
<string>rebase:</string>
<string>refresh:</string>
<string>selectNext:</string>
<string>selectPrevious:</string>
<string>setBranchFilter:</string>
<string>setDetailedView:</string>
<string>setTreeView:</string>
@@ -3109,6 +3237,14 @@
<string key="name">refresh:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">selectNext:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">selectPrevious:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">setBranchFilter:</string>
<string key="candidateClassName">id</string>
@@ -3154,6 +3290,7 @@
<string>rebaseButton</string>
<string>refController</string>
<string>scopeBarView</string>
<string>searchController</string>
<string>searchField</string>
<string>selectedBranchFilterItem</string>
<string>treeController</string>
@@ -3174,6 +3311,7 @@
<string>NSButton</string>
<string>PBRefController</string>
<string>PBGitGradientBarView</string>
<string>PBHistorySearchController</string>
<string>NSSearchField</string>
<string>NSButton</string>
<string>NSTreeController</string>
@@ -3197,6 +3335,7 @@
<string>rebaseButton</string>
<string>refController</string>
<string>scopeBarView</string>
<string>searchController</string>
<string>searchField</string>
<string>selectedBranchFilterItem</string>
<string>treeController</string>
@@ -3250,6 +3389,10 @@
<string key="name">scopeBarView</string>
<string key="candidateClassName">PBGitGradientBarView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">searchController</string>
<string key="candidateClassName">PBHistorySearchController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">searchField</string>
<string key="candidateClassName">NSSearchField</string>
@@ -3329,6 +3472,99 @@
<string key="minorKey">PBGitRevisionCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PBHistorySearchController</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="actions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>stepperPressed:</string>
<string>updateSearch:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>id</string>
<string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>stepperPressed:</string>
<string>updateSearch:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBActionInfo">
<string key="name">stepperPressed:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">updateSearch:</string>
<string key="candidateClassName">id</string>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>commitController</string>
<string>historyController</string>
<string>numberOfMatchesField</string>
<string>searchField</string>
<string>stepper</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSArrayController</string>
<string>PBGitHistoryController</string>
<string>NSTextField</string>
<string>NSSearchField</string>
<string>NSSegmentedControl</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>commitController</string>
<string>historyController</string>
<string>numberOfMatchesField</string>
<string>searchField</string>
<string>stepper</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">commitController</string>
<string key="candidateClassName">NSArrayController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">historyController</string>
<string key="candidateClassName">PBGitHistoryController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">numberOfMatchesField</string>
<string key="candidateClassName">NSTextField</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">searchField</string>
<string key="candidateClassName">NSSearchField</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">stepper</string>
<string key="candidateClassName">NSSegmentedControl</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">PBHistorySearchController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PBNiceSplitView</string>
<string key="superclassName">NSSplitView</string>
@@ -4102,6 +4338,34 @@
<string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzCore.framework/Headers/CIImageProvider.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">ScriptingBridge.framework/Headers/SBApplication.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
+2 -1
View File
@@ -9,6 +9,7 @@
#import "PBGitRevisionCell.h"
#import "PBGitRef.h"
#import "RoundedRectangle.h"
#import "GitXTextFieldCell.h"
@implementation PBGitRevisionCell
@@ -16,7 +17,7 @@
- (id) initWithCoder: (id) coder
{
self = [super initWithCoder:coder];
textCell = [[NSTextFieldCell alloc] initWithCoder:coder];
textCell = [[GitXTextFieldCell alloc] initWithCoder:coder];
return self;
}
+46
View File
@@ -0,0 +1,46 @@
//
// PBHistorySearchController.h
// GitX
//
// Created by Nathan Kinsinger on 8/21/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@class PBGitHistoryController;
@interface PBHistorySearchController : NSObject {
PBGitHistoryController *historyController;
NSArrayController *commitController;
NSIndexSet *results;
NSSearchField *searchField;
NSSegmentedControl *stepper;
NSTextField *numberOfMatchesField;
NSPanel *rewindPanel;
}
@property (assign) IBOutlet PBGitHistoryController *historyController;
@property (assign) IBOutlet NSArrayController *commitController;
@property (assign) IBOutlet NSSearchField *searchField;
@property (assign) IBOutlet NSSegmentedControl *stepper;
@property (assign) IBOutlet NSTextField *numberOfMatchesField;
- (BOOL)isRowInSearchResults:(NSInteger)rowIndex;
- (BOOL)hasSearchResults;
- (void)selectNextResult;
- (void)selectPreviousResult;
- (IBAction)stepperPressed:(id)sender;
- (void)clearSearch;
- (IBAction)updateSearch:(id)sender;
@end
+313
View File
@@ -0,0 +1,313 @@
//
// PBHistorySearchController.m
// GitX
//
// Created by Nathan Kinsinger on 8/21/10.
// Copyright 2010 Nathan Kinsinger. All rights reserved.
//
#import "PBHistorySearchController.h"
#import "PBGitHistoryController.h"
#import "PBGitRepository.h"
#import <QuartzCore/CoreAnimation.h>
@interface PBHistorySearchController ()
- (void)selectNextResultInDirection:(NSInteger)direction;
- (void)updateUI;
- (void)startBasicSearch;
- (void)showSearchRewindPanelReverse:(BOOL)isReversed;
@end
#define kGitXSearchDirectionNext 1
#define kGitXSearchDirectionPrevious -1
#define kGitXBasicSearchLabel @"Subject, Author, SHA"
#define kGitXSearchArrangedObjectsContext @"GitXSearchArrangedObjectsContext"
@implementation PBHistorySearchController
@synthesize historyController;
@synthesize commitController;
@synthesize searchField;
@synthesize stepper;
@synthesize numberOfMatchesField;
#pragma mark -
#pragma mark Public methods
- (BOOL)isRowInSearchResults:(NSInteger)rowIndex
{
return [results containsIndex:rowIndex];
}
- (BOOL)hasSearchResults
{
return ([results count] > 0);
}
- (void)selectNextResult
{
[self selectNextResultInDirection:kGitXSearchDirectionNext];
}
- (void)selectPreviousResult
{
[self selectNextResultInDirection:kGitXSearchDirectionPrevious];
}
- (IBAction)stepperPressed:(id)sender
{
NSInteger selectedSegment = [sender selectedSegment];
if (selectedSegment == 0)
[self selectPreviousResult];
else
[self selectNextResult];
}
- (void)clearSearch
{
[searchField setStringValue:@""];
if (results) {
results = nil;
[historyController.commitList reloadData];
}
[self updateUI];
}
- (IBAction)updateSearch:(id)sender
{
[self startBasicSearch];
}
- (void)awakeFromNib
{
[[searchField cell] setPlaceholderString:@"Subject, Author, SHA"];
[self updateUI];
[commitController addObserver:self forKeyPath:@"arrangedObjects" options:0 context:kGitXSearchArrangedObjectsContext];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([(NSString *)context isEqualToString:kGitXSearchArrangedObjectsContext]) {
// the objects in the commitlist changed so the result indexes are no longer valid
[self clearSearch];
return;
}
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
#pragma mark -
#pragma mark Private methods
- (void)selectIndex:(NSUInteger)index
{
if ([[commitController arrangedObjects] count] > index) {
PBGitCommit *commit = [[commitController arrangedObjects] objectAtIndex:index];
[historyController selectCommit:[commit sha]];
}
}
- (void)selectNextResultInDirection:(NSInteger)direction
{
if (![results count])
return;
NSUInteger selectedRow = [historyController.commitList selectedRow];
if (selectedRow == NSNotFound) {
[self selectIndex:[results firstIndex]];
return;
}
NSUInteger currentResult = NSNotFound;
if (direction == kGitXSearchDirectionNext)
currentResult = [results indexGreaterThanIndex:selectedRow];
else
currentResult = [results indexLessThanIndex:selectedRow];
if (currentResult == NSNotFound) {
if (direction == kGitXSearchDirectionNext)
currentResult = [results firstIndex];
else
currentResult = [results lastIndex];
[self showSearchRewindPanelReverse:(direction != kGitXSearchDirectionNext)];
}
[self selectIndex:currentResult];
}
- (NSString *)numberOfMatchesString
{
NSUInteger numberOfMatches = [results count];
if (numberOfMatches == 0)
return @"Not found";
if (numberOfMatches == 1)
return @"1 match";
return [NSString stringWithFormat:@"%d matches", numberOfMatches];
}
- (void)updateUI
{
if ([[searchField stringValue] isEqualToString:@""]) {
[numberOfMatchesField setHidden:YES];
[stepper setHidden:YES];
}
else {
[numberOfMatchesField setStringValue:[self numberOfMatchesString]];
[numberOfMatchesField setHidden:NO];
[stepper setHidden:NO];
[historyController.commitList reloadData];
}
}
// changes the selection to the next match after the current selected row unless the current row is already a match
- (void)updateSelectedResult
{
NSString *searchString = [searchField stringValue];
if ([searchString isEqualToString:@""]) {
[self clearSearch];
return;
}
if (![self isRowInSearchResults:[historyController.commitList selectedRow]])
[self selectNextResult];
[self updateUI];
}
#pragma mark Basic Search
- (void)startBasicSearch
{
NSString *searchString = [searchField stringValue];
if ([searchString isEqualToString:@""]) {
[self clearSearch];
return;
}
NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"subject CONTAINS[cd] %@ OR author CONTAINS[cd] %@ OR realSha BEGINSWITH[c] %@", searchString, searchString, searchString];
NSUInteger index = 0;
for (PBGitCommit *commit in [commitController arrangedObjects]) {
if ([searchPredicate evaluateWithObject:commit])
[indexes addIndex:index];
index++;
}
results = indexes;
[self updateSelectedResult];
}
#pragma mark -
#pragma mark Rewind Panel
#define kRewindPanelSize 125.0f
- (void)closeRewindPanel
{
[[[historyController view] window] removeChildWindow:rewindPanel];
[rewindPanel close];
rewindPanel = nil;
}
- (NSPanel *)rewindPanelReverse:(BOOL)isReversed
{
NSRect windowFrame = [[[historyController view] window] frame];
NSRect historyFrame = [[historyController view] convertRectToBase:[[historyController view] frame]];
NSRect panelRect = NSMakeRect(0.0f, 0.0f, kRewindPanelSize, kRewindPanelSize);
panelRect.origin.x = windowFrame.origin.x + historyFrame.origin.x + ((historyFrame.size.width - kRewindPanelSize) / 2.0f);
panelRect.origin.y = windowFrame.origin.y + historyFrame.origin.y + ((historyFrame.size.height - kRewindPanelSize) / 2.0f);
NSPanel *panel = [[NSPanel alloc] initWithContentRect:panelRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:YES];
[panel setIgnoresMouseEvents:YES];
[panel setOneShot:YES];
[panel setOpaque:NO];
[panel setBackgroundColor:[NSColor clearColor]];
[panel setHasShadow:NO];
[panel useOptimizedDrawing:YES];
[panel setAlphaValue:0.0f];
NSBox *box = [[NSBox alloc] initWithFrame:[[panel contentView] frame]];
[box setBoxType:NSBoxCustom];
[box setBorderType:NSLineBorder];
[box setFillColor:[NSColor colorWithCalibratedWhite:0.0f alpha:0.5f]];
[box setBorderColor:[NSColor colorWithCalibratedWhite:0.5f alpha:0.5f]];
[box setCornerRadius:12.0f];
[[panel contentView] addSubview:box];
NSImage *rewindImage = [[NSImage imageNamed:@"rewindImage"] copy];
[rewindImage setFlipped:isReversed];
NSSize imageSize = [rewindImage size];
NSRect imageViewFrame = NSMakeRect(21.0f, 5.0f, imageSize.width, imageSize.height);
NSImageView *rewindImageView = [[NSImageView alloc] initWithFrame:imageViewFrame];
[rewindImageView setImage:rewindImage];
[[box contentView] addSubview:rewindImageView];
return panel;
}
- (CAKeyframeAnimation *)rewindPanelFadeOutAnimation
{
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.duration = 1.0f;
animation.values = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:1.0f],
[NSNumber numberWithFloat:1.0f],
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:0.0f], nil];
animation.keyTimes = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.1f],
[NSNumber numberWithFloat:0.3f],
[NSNumber numberWithFloat:0.7f],
[NSNumber numberWithFloat:animation.duration], nil];
return animation;
}
- (void)showSearchRewindPanelReverse:(BOOL)isReversed
{
if (rewindPanel)
[self closeRewindPanel];
rewindPanel = [self rewindPanelReverse:isReversed];
[[[historyController view] window] addChildWindow:rewindPanel ordered:NSWindowAbove];
CAKeyframeAnimation *alphaAnimation = [self rewindPanelFadeOutAnimation];
[rewindPanel setAnimations:[NSDictionary dictionaryWithObject:alphaAnimation forKey:@"alphaValue"]];
[[rewindPanel animator] setAlphaValue:0.0f];
[self performSelector:@selector(closeRewindPanel) withObject:nil afterDelay:0.7f];
}
@end