ARC: Update OakFilterList framework

This commit is contained in:
Allan Odgaard
2012-12-27 01:17:43 +01:00
parent 701c9a0541
commit 0dfb5d3116
17 changed files with 255 additions and 373 deletions

View File

@@ -1,9 +1,4 @@
@interface OakAbbreviations : NSObject
{
@private
NSString* name;
NSMutableArray* bindings;
}
+ (OakAbbreviations*)abbreviationsForName:(NSString*)aName;
- (NSArray*)stringsForAbbreviation:(NSString*)anAbbreviation;

View File

@@ -8,6 +8,8 @@ static NSString* const FCAbbreviationKey = @"short";
static NSString* const FCExpandedStringKey = @"long";
@interface OakAbbreviations ()
@property (nonatomic, copy) NSString* name;
@property (nonatomic, retain) NSMutableArray* bindings;
- (id)initWithName:(NSString*)aName;
@end
@@ -15,18 +17,18 @@ static NSString* const FCExpandedStringKey = @"long";
+ (OakAbbreviations*)abbreviationsForName:(NSString*)aName
{
static NSMutableDictionary* SharedInstances = [NSMutableDictionary new];
if(![SharedInstances objectForKey:aName])
[SharedInstances setObject:[[[self alloc] initWithName:aName] autorelease] forKey:aName];
return [SharedInstances objectForKey:aName];
if(!SharedInstances[aName])
SharedInstances[aName] = [[self alloc] initWithName:aName];
return SharedInstances[aName];
}
- (id)initWithName:(NSString*)aName
{
if(self = [self init])
{
name = [aName copy];
bindings = [[[NSUserDefaults standardUserDefaults] arrayForKey:name] mutableCopy] ?: [NSMutableArray new];
D(DBF_FilterList_Abbreviations, bug("%s\n", [[bindings description] UTF8String]););
self.name = aName;
self.bindings = [[[NSUserDefaults standardUserDefaults] arrayForKey:self.name] mutableCopy] ?: [NSMutableArray new];
D(DBF_FilterList_Abbreviations, bug("%s\n", [[self.bindings description] UTF8String]););
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:NSApplicationWillTerminateNotification object:NSApp];
}
return self;
@@ -36,17 +38,14 @@ static NSString* const FCExpandedStringKey = @"long";
{
[self applicationWillTerminate:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillTerminateNotification object:NSApp];
[bindings release];
[name release];
[super dealloc];
}
- (void)applicationWillTerminate:(NSNotification*)aNotification
{
D(DBF_FilterList_Abbreviations, bug("%s\n", [[bindings description] UTF8String]););
if([bindings count] > 50)
[bindings setArray:[bindings subarrayWithRange:NSMakeRange(0, 50)]];
[[NSUserDefaults standardUserDefaults] setObject:bindings forKey:name];
D(DBF_FilterList_Abbreviations, bug("%s\n", [[self.bindings description] UTF8String]););
if([self.bindings count] > 50)
[self.bindings setArray:[self.bindings subarrayWithRange:NSMakeRange(0, 50)]];
[[NSUserDefaults standardUserDefaults] setObject:self.bindings forKey:self.name];
}
- (NSArray*)stringsForAbbreviation:(NSString*)anAbbreviation
@@ -57,10 +56,10 @@ static NSString* const FCExpandedStringKey = @"long";
if(NSIsEmptyString(anAbbreviation))
return exactMatches;
for(NSDictionary* binding in bindings)
for(NSDictionary* binding in self.bindings)
{
NSString* abbr = [binding objectForKey:FCAbbreviationKey];
NSString* path = [binding objectForKey:FCExpandedStringKey];
NSString* abbr = binding[FCAbbreviationKey];
NSString* path = binding[FCExpandedStringKey];
if([abbr isEqualToString:anAbbreviation])
[exactMatches addObject:path];
@@ -80,12 +79,8 @@ static NSString* const FCExpandedStringKey = @"long";
if(NSIsEmptyString(anAbbreviation) || NSIsEmptyString(aString))
return;
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
anAbbreviation, FCAbbreviationKey,
aString, FCExpandedStringKey,
nil];
[bindings removeObject:dict];
[bindings insertObject:dict atIndex:0];
NSDictionary* dict = @{ FCAbbreviationKey : anAbbreviation, FCExpandedStringKey : aString };
[self.bindings removeObject:dict];
[self.bindings insertObject:dict atIndex:0];
}
@end

View File

@@ -7,11 +7,6 @@ PUBLIC @interface OakFilterWindowController : NSWindowController
OBJC_WATCH_LEAKS(OakFilterWindowController);
IBOutlet OakFilterListView* filterView;
IBOutlet NSView* filterControlsView;
SEL action;
SEL accessoryAction;
id target;
BOOL sendActionOnSingleClick;
BOOL retainedSelf;
}
+ (id)filterWindow;
- (void)showWindowRelativeToWindow:(NSWindow*)parentWindow;

View File

@@ -7,20 +7,13 @@
- (IBAction)accept:(id)sender;
- (IBAction)cancel:(id)sender;
@property (nonatomic, retain) NSView* filterControls;
@property (nonatomic, retain) OakFilterWindowController* retainedSelf;
@end
@implementation OakFilterWindowController
@synthesize target, action, accessoryAction, sendActionOnSingleClick;
+ (id)filterWindow
{
return [[[self alloc] initWithWindowNibName:@"FilterWindow"] autorelease];
}
- (void)dealloc
{
self.dataSource = nil;
[super dealloc];
return [[self alloc] initWithWindowNibName:@"FilterWindow"];
}
- (void)windowDidLoad
@@ -29,11 +22,7 @@
filterView.action = @selector(singleClick:);
filterView.doubleAction = @selector(accept:);
if(!retainedSelf)
{
[self retain];
retainedSelf = YES;
}
self.retainedSelf = self;
}
- (void)showWindowRelativeToWindow:(NSWindow*)parentWindow
@@ -93,7 +82,7 @@
NSWindow* window = [self window]; // loads filterView from nib
filterView.filterDataSource = dataSource;
self.accessoryAction = self.accessoryAction; // trigger accessory button creation if necessary
self.accessoryAction = _accessoryAction; // trigger accessory button creation if necessary
if(dataSource)
[window setFrameAutosaveName:[NSString stringWithFormat:@"Filter Window %@ Saved Frame", [dataSource className]]];
@@ -115,8 +104,8 @@
- (void)setSendActionOnSingleClick:(BOOL)newSendActionOnSingleClick
{
sendActionOnSingleClick = newSendActionOnSingleClick;
[(NSPanel*)self.window setBecomesKeyOnlyIfNeeded:sendActionOnSingleClick];
_sendActionOnSingleClick = newSendActionOnSingleClick;
[(NSPanel*)self.window setBecomesKeyOnlyIfNeeded:_sendActionOnSingleClick];
}
- (BOOL)allowsMultipleSelection
@@ -136,21 +125,20 @@
- (void)setTarget:(id)newTarget
{
if(newTarget != target)
if(_target != newTarget)
{
[target release];
target = [newTarget retain];
self.accessoryAction = self.accessoryAction; // update accessory button target
_target = newTarget;
self.accessoryAction = _accessoryAction; // update accessory button target
}
}
- (void)setAccessoryAction:(SEL)selector
{
accessoryAction = selector;
if(accessoryAction && [filterView.filterDataSource respondsToSelector:@selector(accessoryButton)])
_accessoryAction = selector;
if(_accessoryAction && [filterView.filterDataSource respondsToSelector:@selector(accessoryButton)])
{
NSButtonCell* button = [filterView.filterDataSource accessoryButton];
[button setAction:accessoryAction];
[button setAction:_accessoryAction];
[button setTarget:self.target];
filterView.accessoryButton = button;
}
@@ -206,7 +194,7 @@
{
static std::set<SEL> const forward = { @selector(moveUp:), @selector(moveDown:), @selector(moveUpAndModifySelection:), @selector(moveDownAndModifySelection:), @selector(pageUp:), @selector(pageDown:), @selector(movePageUp:), @selector(movePageDown:), @selector(scrollPageUp:), @selector(scrollPageDown:), @selector(moveToBeginningOfDocument:), @selector(moveToEndOfDocument:), @selector(insertNewline:), @selector(insertNewlineIgnoringFieldEditor:), @selector(cancelOperation:) };
if(forward.find(aCommand) != forward.end() && [self respondsToSelector:aCommand])
return [self performSelector:aCommand withObject:aControl], YES;
return [NSApp sendAction:aCommand to:self from:aControl];
return NO;
}
@@ -216,11 +204,9 @@
- (void)windowWillClose:(NSNotification*)aNotification
{
if(retainedSelf)
{
retainedSelf = NO;
[self autorelease];
}
filterView.target = nil;
filterView.accessoryButton.target = nil;
self.retainedSelf = nil;
}
- (IBAction)cancel:(id)sender
@@ -259,7 +245,7 @@
- (IBAction)singleClick:(id)sender
{
if(!sendActionOnSingleClick)
if(!_sendActionOnSingleClick)
return;
if([[[filterView.tableColumns objectAtIndex:filterView.clickedColumn] identifier] isEqualToString:@"accessoryColumn"])

View File

@@ -2,14 +2,6 @@
#import <text/ranker.h>
@interface OakFilterListView : NSTableView <NSTableViewDataSource, NSTableViewDelegate>
{
OBJC_WATCH_LEAKS(OakFilterListView)
NSArray* items;
NSAttributedString* infoString;
id <FilterListDataSource> filterDataSource;
BOOL isWaitingForItems;
NSUInteger sourceIndex;
}
@property (nonatomic, retain) id <FilterListDataSource> filterDataSource;
@property (nonatomic, retain, readonly) NSAttributedString* infoString;
@property (nonatomic, readonly) NSArray* selectedItems;

View File

@@ -23,12 +23,6 @@ NSString* const FLDataSourceItemsShouldAscendNotification = @"FLDataSourceItems
@end
@implementation OakFilterListView
@synthesize filterDataSource, isWaitingForItems, items, infoString, sourceIndex;
// ==================
// = Setup/Teardown =
// ==================
- (void)setup
{
self.dataSource = self;
@@ -54,15 +48,12 @@ NSString* const FLDataSourceItemsShouldAscendNotification = @"FLDataSourceItems
- (void)dealloc
{
self.filterDataSource = nil;
self.items = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (void)awakeFromNib
{
self.infoString = [[[NSAttributedString alloc] initWithString:@""] autorelease];
self.infoString = [[NSAttributedString alloc] initWithString:@""];
}
- (void)viewFrameDidChange:(NSNotification*)notification
@@ -76,31 +67,32 @@ NSString* const FLDataSourceItemsShouldAscendNotification = @"FLDataSourceItems
- (void)setFilterDataSource:(id <FilterListDataSource>)aDataSource
{
if(aDataSource != filterDataSource)
if(aDataSource != _filterDataSource)
{
if(filterDataSource)
if(_filterDataSource)
{
if([filterDataSource respondsToSelector:@selector(stopLoading)])
[filterDataSource stopLoading];
[[NSNotificationCenter defaultCenter] removeObserver:self name:FLDataSourceItemsDidChangeNotification object:filterDataSource];
[[NSNotificationCenter defaultCenter] removeObserver:self name:FLDataSourceItemsShouldDescendNotification object:filterDataSource];
[[NSNotificationCenter defaultCenter] removeObserver:self name:FLDataSourceItemsShouldAscendNotification object:filterDataSource];
[filterDataSource autorelease];
if([_filterDataSource respondsToSelector:@selector(stopLoading)])
[_filterDataSource stopLoading];
[[NSNotificationCenter defaultCenter] removeObserver:self name:FLDataSourceItemsDidChangeNotification object:_filterDataSource];
[[NSNotificationCenter defaultCenter] removeObserver:self name:FLDataSourceItemsShouldDescendNotification object:_filterDataSource];
[[NSNotificationCenter defaultCenter] removeObserver:self name:FLDataSourceItemsShouldAscendNotification object:_filterDataSource];
}
if(filterDataSource = [aDataSource retain])
if(_filterDataSource = aDataSource)
{
ASSERT([filterDataSource conformsToProtocol:@protocol(FilterListDataSource)]);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataSourceHasMoreData:) name:FLDataSourceItemsDidChangeNotification object:filterDataSource];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataSourceShouldDescend:) name:FLDataSourceItemsShouldDescendNotification object:filterDataSource];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataSourceShouldAscend:) name:FLDataSourceItemsShouldAscendNotification object:filterDataSource];
ASSERT([_filterDataSource conformsToProtocol:@protocol(FilterListDataSource)]);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataSourceHasMoreData:) name:FLDataSourceItemsDidChangeNotification object:_filterDataSource];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataSourceShouldDescend:) name:FLDataSourceItemsShouldDescendNotification object:_filterDataSource];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataSourceShouldAscend:) name:FLDataSourceItemsShouldAscendNotification object:_filterDataSource];
NSTextFieldCell* dataCell = nil;
if([filterDataSource respondsToSelector:@selector(itemDataCell)])
dataCell = [filterDataSource itemDataCell];
if([_filterDataSource respondsToSelector:@selector(itemDataCell)])
dataCell = [_filterDataSource itemDataCell];
if(!dataCell)
dataCell = [[[NSTextFieldCell alloc] initTextCell:@""] autorelease];
dataCell = [[NSTextFieldCell alloc] initTextCell:@""];
[[self.tableColumns objectAtIndex:0] setDataCell:dataCell];
self.allowsMultipleSelection = [filterDataSource respondsToSelector:@selector(allowsMultipleSelection)] && [filterDataSource allowsMultipleSelection];
self.allowsMultipleSelection = [_filterDataSource respondsToSelector:@selector(allowsMultipleSelection)] && [_filterDataSource allowsMultipleSelection];
}
[self reloadData];
}
@@ -130,12 +122,12 @@ NSString* const FLDataSourceItemsShouldAscendNotification = @"FLDataSourceItems
- (void)dataSourceShouldDescend:(NSNotification*)aNotification
{
[filterDataSource descendIntoItem:[self.selectedItems lastObject]];
[_filterDataSource descendIntoItem:[self.selectedItems lastObject]];
}
- (void)dataSourceShouldAscend:(NSNotification*)aNotification
{
[filterDataSource descendIntoItem:nil];
[_filterDataSource descendIntoItem:nil];
}
- (void)dataSourceHasMoreData:(NSNotification*)notification
@@ -146,15 +138,18 @@ NSString* const FLDataSourceItemsShouldAscendNotification = @"FLDataSourceItems
- (void)reloadData
{
NSArray* selectedItems = nil;
if([filterDataSource respondsToSelector:@selector(preservesSelectionWhenFiltering)] && [filterDataSource preservesSelectionWhenFiltering])
if([_filterDataSource respondsToSelector:@selector(preservesSelectionWhenFiltering)] && [_filterDataSource preservesSelectionWhenFiltering])
selectedItems = [self.items objectsAtIndexes:self.selectedRowIndexes];
self.items = [filterDataSource items];
if(![filterDataSource respondsToSelector:@selector(infoStringForItem:)])
self.items = [_filterDataSource items];
if(![_filterDataSource respondsToSelector:@selector(infoStringForItem:)])
{
NSMutableParagraphStyle* style = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
NSMutableParagraphStyle* style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setAlignment:NSCenterTextAlignment];
NSAttributedString* text = [[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%lu items", self.items.count]
attributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSColor darkGrayColor], NSForegroundColorAttributeName, [NSFont controlContentFontOfSize:11], NSFontAttributeName, style, NSParagraphStyleAttributeName, nil]] autorelease];
NSAttributedString* text = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%lu items", self.items.count] attributes:@{
NSForegroundColorAttributeName : [NSColor darkGrayColor],
NSFontAttributeName : [NSFont controlContentFontOfSize:11],
NSParagraphStyleAttributeName : style
}];
self.infoString = text;
}
[super reloadData];
@@ -173,7 +168,7 @@ NSString* const FLDataSourceItemsShouldAscendNotification = @"FLDataSourceItems
[self selectRowIndexes:indexesToSelect byExtendingSelection:NO];
[self scrollRowToVisible:indexesToSelect.firstIndex];
[self tableViewSelectionDidChange:nil];
self.isWaitingForItems = [filterDataSource respondsToSelector:@selector(moreItemsToCome)] && [filterDataSource moreItemsToCome];
self.isWaitingForItems = [_filterDataSource respondsToSelector:@selector(moreItemsToCome)] && [_filterDataSource moreItemsToCome];
}
// ======================
@@ -182,55 +177,61 @@ NSString* const FLDataSourceItemsShouldAscendNotification = @"FLDataSourceItems
- (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView
{
return [items count];
return [_items count];
}
- (id)tableView:(NSTableView*)tableView objectValueForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)rowIndex
{
if([tableColumn.identifier isEqualToString:@"accessoryColumn"])
return [items objectAtIndex:rowIndex];
if([filterDataSource respondsToSelector:@selector(displayStringForItem:)])
return [_items objectAtIndex:rowIndex];
if([_filterDataSource respondsToSelector:@selector(displayStringForItem:)])
{
NSMutableParagraphStyle* pStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
NSMutableParagraphStyle* pStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[pStyle setLineBreakMode:NSLineBreakByTruncatingMiddle];
NSMutableAttributedString* text = [[[filterDataSource displayStringForItem:[items objectAtIndex:rowIndex]] mutableCopy] autorelease];
[text addAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSColor darkGrayColor], NSForegroundColorAttributeName, [NSFont controlContentFontOfSize:13], NSFontAttributeName, pStyle, NSParagraphStyleAttributeName, nil] range:NSMakeRange(0, [text length])];
NSDictionary* highlightAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
@1, NSUnderlineStyleAttributeName,
[NSColor blackColor], NSForegroundColorAttributeName,
[[NSFontManager sharedFontManager] convertFont:[NSFont controlContentFontOfSize:13] toHaveTrait:NSBoldFontMask], NSFontAttributeName,
nil];
NSFont* baseFont = [NSFont controlContentFontOfSize:13];
NSFont* boldFont = [[NSFontManager sharedFontManager] convertFont:baseFont toHaveTrait:NSBoldFontMask];
NSDictionary* baseAttributes = @{ NSForegroundColorAttributeName : [NSColor darkGrayColor], NSFontAttributeName : baseFont, NSParagraphStyleAttributeName : pStyle };
NSDictionary* highlightAttributes = @{ NSForegroundColorAttributeName : [NSColor blackColor], NSFontAttributeName : boldFont, NSUnderlineStyleAttributeName : @1 };
NSMutableAttributedString* text = [[_filterDataSource displayStringForItem:[_items objectAtIndex:rowIndex]] mutableCopy];
[text addAttributes:baseAttributes range:NSMakeRange(0, [text length])];
HighlightRangesWithAttribute(text, FLMatchingTextAttributeName, highlightAttributes);
return text;
}
else
return [items objectAtIndex:rowIndex];
{
return [_items objectAtIndex:rowIndex];
}
}
- (void)tableViewSelectionDidChange:(NSNotification*)notification
{
if([filterDataSource respondsToSelector:@selector(infoStringForItem:)])
if([_filterDataSource respondsToSelector:@selector(infoStringForItem:)])
{
if(self.selectedRow != -1 && [items count] > 0)
if(self.selectedRow != -1 && [_items count] > 0)
{
NSMutableAttributedString* text = [[[filterDataSource infoStringForItem:[items objectAtIndex:self.selectedRow]] mutableCopy] autorelease];
NSMutableParagraphStyle* style = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
[style setLineBreakMode:NSLineBreakByTruncatingHead];
[text addAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSColor darkGrayColor], NSForegroundColorAttributeName, [NSFont controlContentFontOfSize:11], NSFontAttributeName, style, NSParagraphStyleAttributeName, nil]
range:NSMakeRange(0, [text length])];
NSDictionary* highlightAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
@1, NSUnderlineStyleAttributeName,
[NSColor blackColor], NSForegroundColorAttributeName,
[[NSFontManager sharedFontManager] convertFont:[NSFont controlContentFontOfSize:11] toHaveTrait:NSBoldFontMask], NSFontAttributeName,
nil];
NSMutableParagraphStyle* pStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[pStyle setLineBreakMode:NSLineBreakByTruncatingHead];
NSFont* baseFont = [NSFont controlContentFontOfSize:11];
NSFont* boldFont = [[NSFontManager sharedFontManager] convertFont:baseFont toHaveTrait:NSBoldFontMask];
NSDictionary* baseAttributes = @{ NSForegroundColorAttributeName : [NSColor darkGrayColor], NSFontAttributeName : baseFont, NSParagraphStyleAttributeName : pStyle };
NSDictionary* highlightAttributes = @{ NSForegroundColorAttributeName : [NSColor blackColor], NSFontAttributeName : boldFont, NSUnderlineStyleAttributeName : @1 };
NSMutableAttributedString* text = [[_filterDataSource infoStringForItem:[_items objectAtIndex:self.selectedRow]] mutableCopy];
[text addAttributes:baseAttributes range:NSMakeRange(0, [text length])];
HighlightRangesWithAttribute(text, FLMatchingTextAttributeName, highlightAttributes);
NSUInteger tabIndex = [text.mutableString rangeOfString:@"\t"].location;
if(tabIndex != NSNotFound)
{
CGFloat width = self.window.frame.size.width - [text attributedSubstringFromRange:NSMakeRange(tabIndex, text.length - tabIndex)].size.width - 10;
NSMutableParagraphStyle* rightAlignStyle = [[[text attribute:NSParagraphStyleAttributeName atIndex:tabIndex effectiveRange:NULL] mutableCopy] autorelease];
[rightAlignStyle setTabStops:@[ [[[NSTextTab alloc] initWithType:NSLeftTabStopType location:width + 1.0] autorelease] ]];
NSMutableParagraphStyle* rightAlignStyle = [[text attribute:NSParagraphStyleAttributeName atIndex:tabIndex effectiveRange:NULL] mutableCopy];
[rightAlignStyle setTabStops:@[ [[NSTextTab alloc] initWithType:NSLeftTabStopType location:width + 1.0] ]];
[text addAttribute:NSParagraphStyleAttributeName value:rightAlignStyle range:NSMakeRange(0, text.length)];
}
@@ -238,15 +239,15 @@ NSString* const FLDataSourceItemsShouldAscendNotification = @"FLDataSourceItems
}
else
{
self.infoString = [[[NSAttributedString alloc] initWithString:@""] autorelease];
self.infoString = [[NSAttributedString alloc] initWithString:@""];
}
}
}
- (void)tableView:(NSTableView*)tableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)rowIndex
{
if([filterDataSource respondsToSelector:@selector(willDisplayCell:forItem:)] && ![tableColumn.identifier isEqualToString:@"accessoryColumn"])
[filterDataSource willDisplayCell:aCell forItem:[self.items objectAtIndex:rowIndex]];
if([_filterDataSource respondsToSelector:@selector(willDisplayCell:forItem:)] && ![tableColumn.identifier isEqualToString:@"accessoryColumn"])
[_filterDataSource willDisplayCell:aCell forItem:[self.items objectAtIndex:rowIndex]];
}
// ===========
@@ -260,14 +261,14 @@ NSString* const FLDataSourceItemsShouldAscendNotification = @"FLDataSourceItems
- (void)waitForAllItems
{
if([filterDataSource respondsToSelector:@selector(waitForAllItems)])
[filterDataSource waitForAllItems];
if([_filterDataSource respondsToSelector:@selector(waitForAllItems)])
[_filterDataSource waitForAllItems];
}
- (void)makeSelectedItemsBestMatch
{
if([filterDataSource respondsToSelector:@selector(makeItemsBestFitForCurrentSearch:)])
[filterDataSource makeItemsBestFitForCurrentSearch:self.selectedItems];
if([_filterDataSource respondsToSelector:@selector(makeItemsBestFitForCurrentSearch:)])
[_filterDataSource makeItemsBestFitForCurrentSearch:self.selectedItems];
}
- (BOOL)acceptsFirstResponder

View File

@@ -3,9 +3,7 @@
#else
#import "../OakFilterList.h"
#endif
#import <plist/uuid.h>
#import <scope/scope.h>
#import <bundles/bundles.h>
#import <oak/misc.h>
namespace search
@@ -19,19 +17,6 @@ namespace search
}
PUBLIC @interface BundleItemChooser : NSObject <FilterListDataSource>
{
OBJC_WATCH_LEAKS(BundleItemChooser);
scope::context_t scope;
BOOL hasSelection;
std::vector<bundles::item_ptr> all_items;
std::set<oak::uuid_t> items_filtered_by_scope;
BOOL searchAllScopes;
std::string originalFilterString;
std::string filterString;
NSViewController* viewController;
BOOL keyEquivalentSearch;
search::type searchType;
}
+ (id)bundleItemChooserForScope:(scope::context_t const&)aScope;
@property (nonatomic, retain) NSString* filterString;
@property (nonatomic, assign) BOOL keyEquivalentSearch;

View File

@@ -80,37 +80,28 @@ OAK_DEBUG_VAR(FilterList_BundleItemChooser);
OakKeyEquivalentView* keyEquivField;
NSSegmentedControl* sourceSelector;
MGScopeBar* scopeBar;
BundleItemChooser* itemChooser;
}
@property (nonatomic, assign) BundleItemChooser* itemChooser;
@property (nonatomic, weak) BundleItemChooser* itemChooser;
@end
@interface BundleItemChooserView : NSView
{
BundleItemChooserViewController* viewController;
}
@property (nonatomic, assign) BundleItemChooserViewController* viewController;
@property (nonatomic, weak) BundleItemChooserViewController* viewController;
@end
@implementation BundleItemChooserView
@synthesize viewController;
- (void)viewDidMoveToWindow
{
[self.window makeFirstResponder:[self.viewController valueForKey:self.viewController.itemChooser.keyEquivalentSearch ? @"keyEquivField" : @"searchField"]];
self.viewController = nil;
}
@end
@implementation BundleItemChooserViewController
@synthesize itemChooser;
static NSString* const TitleSearchMode = @"TitleSearchMode";
static NSString* const KeyEquivalentSearchMode = @"KeyEquivalentSearchMode";
static NSString* const CurrentScope = @"CurrentScope";
static NSString* const AllScopes = @"AllScopes";
@implementation BundleItemChooserViewController
- (id)initWithBundleItemChooser:(BundleItemChooser*)chooser
{
if((self = [super init]))
@@ -119,21 +110,21 @@ static NSString* const AllScopes = @"AllScopes";
static const CGFloat initialViewWidth = 1200;
searchField = [[[NSSearchField alloc] initWithFrame:NSMakeRect(7, 8, initialViewWidth-14, 22)] autorelease];
searchField = [[NSSearchField alloc] initWithFrame:NSMakeRect(7, 8, initialViewWidth-14, 22)];
searchField.action = @selector(didChangeFilterString:);
searchField.target = self;
searchField.autoresizingMask = NSViewWidthSizable|NSViewMinYMargin;
[searchField.cell setScrollable:YES];
keyEquivField = [[[OakKeyEquivalentView alloc] initWithFrame:searchField.frame] autorelease];
keyEquivField = [[OakKeyEquivalentView alloc] initWithFrame:searchField.frame];
keyEquivField.autoresizingMask = NSViewWidthSizable|NSViewMinYMargin;
keyEquivField.disableGlobalHotkeys = NO;
[keyEquivField setHidden:YES];
scopeBar = [[[OakScopeBar alloc] initWithFrame:NSMakeRect(0, NSMaxY(searchField.frame) + 6, initialViewWidth, 25)] autorelease];
scopeBar = [[OakScopeBar alloc] initWithFrame:NSMakeRect(0, NSMaxY(searchField.frame) + 6, initialViewWidth, 25)];
scopeBar.autoresizingMask = NSViewWidthSizable|NSViewMinYMargin;
self.view = [[[BundleItemChooserView alloc] initWithFrame:NSMakeRect(0, 0, initialViewWidth, NSMaxY(scopeBar.frame))] autorelease];
self.view = [[BundleItemChooserView alloc] initWithFrame:NSMakeRect(0, 0, initialViewWidth, NSMaxY(scopeBar.frame))];
((BundleItemChooserView*)self.view).viewController = self;
self.view.autoresizingMask = NSViewWidthSizable;
[self.view addSubview:searchField];
@@ -141,10 +132,10 @@ static NSString* const AllScopes = @"AllScopes";
[self.view addSubview:scopeBar];
BOOL searchAllScopes = itemChooser.searchAllScopes;
BOOL keyEquivalentSearch = itemChooser.keyEquivalentSearch;
search::type searchType = itemChooser.searchType;
NSString* filterString = itemChooser.filterString;
BOOL searchAllScopes = chooser.searchAllScopes;
BOOL keyEquivalentSearch = chooser.keyEquivalentSearch;
search::type searchType = chooser.searchType;
NSString* filterString = chooser.filterString;
scopeBar.delegate = self;
[scopeBar reloadData];
@@ -159,9 +150,9 @@ static NSString* const AllScopes = @"AllScopes";
case search::themes: [scopeBar setSelected:YES forItem:@"Themes" inGroup:2]; break;
}
itemChooser.filterString = filterString;
chooser.filterString = filterString;
if(itemChooser.keyEquivalentSearch)
if(chooser.keyEquivalentSearch)
keyEquivField.eventString = filterString;
else searchField.stringValue = filterString;
@@ -174,11 +165,8 @@ static NSString* const AllScopes = @"AllScopes";
- (void)dealloc
{
searchField.target = nil;
searchField.action = NULL;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[keyEquivField unbind:@"value"];
self.itemChooser = nil;
[super dealloc];
}
- (int)numberOfGroupsInScopeBar:(MGScopeBar*)theScopeBar
@@ -228,26 +216,26 @@ static NSString* const AllScopes = @"AllScopes";
[searchField setHidden:NO];
[keyEquivField setHidden:YES];
[self.view.window makeFirstResponder:searchField];
itemChooser.keyEquivalentSearch = NO;
self.itemChooser.keyEquivalentSearch = NO;
}
else if(identifier == KeyEquivalentSearchMode)
{
[searchField setHidden:YES];
[keyEquivField setHidden:NO];
[self.view.window makeFirstResponder:keyEquivField];
itemChooser.keyEquivalentSearch = YES;
self.itemChooser.keyEquivalentSearch = YES;
keyEquivField.recording = YES;
}
}
else if(groupNumber == 0)
{
itemChooser.searchAllScopes = identifier == AllScopes;
self.itemChooser.searchAllScopes = identifier == AllScopes;
}
else if(groupNumber == 2)
{
if([identifier isEqualToString:@"Actions"]) itemChooser.searchType = search::actions;
else if([identifier isEqualToString:@"Grammars"]) itemChooser.searchType = search::grammars;
else if([identifier isEqualToString:@"Themes"]) itemChooser.searchType = search::themes;
if([identifier isEqualToString:@"Actions"]) self.itemChooser.searchType = search::actions;
else if([identifier isEqualToString:@"Grammars"]) self.itemChooser.searchType = search::grammars;
else if([identifier isEqualToString:@"Themes"]) self.itemChooser.searchType = search::themes;
}
}
@@ -286,7 +274,7 @@ static NSString* const AllScopes = @"AllScopes";
[scopeBar setSelected:YES forItem:identifier inGroup:groupIndex];
}
- (void)didChangeFilterString:(NSSearchField*)sender { itemChooser.filterString = sender.stringValue; }
- (void)didChangeFilterString:(NSSearchField*)sender { self.itemChooser.filterString = sender.stringValue; }
- (void)setSearchFieldDelegate:(id)aDelegate { searchField.delegate = aDelegate; }
- (void)viewFrameDidChange:(NSNotification*)notification
@@ -298,6 +286,19 @@ static NSString* const AllScopes = @"AllScopes";
@end
@implementation BundleItemChooser
{
OBJC_WATCH_LEAKS(BundleItemChooser);
scope::context_t scope;
BOOL hasSelection;
std::vector<bundles::item_ptr> all_items;
std::set<oak::uuid_t> items_filtered_by_scope;
BOOL searchAllScopes;
std::string originalFilterString;
std::string filterString;
NSViewController* viewController;
BOOL keyEquivalentSearch;
search::type searchType;
}
@synthesize keyEquivalentSearch, textViewHasSelection = hasSelection, searchAllScopes, searchType;
static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type searchType, scope::context_t const& scope, bool hasSelection)
@@ -332,13 +333,7 @@ static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type sear
+ (id)bundleItemChooserForScope:(scope::context_t const&)aScope
{
return [[[self alloc] initWithScope:aScope] autorelease];
}
- (void)dealloc
{
[viewController release];
[super dealloc];
return [[self alloc] initWithScope:aScope];
}
- (NSString*)title
@@ -348,7 +343,7 @@ static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type sear
- (NSTextFieldCell*)itemDataCell
{
return [[[OakBundleItemCell alloc] initTextCell:@""] autorelease];
return [[OakBundleItemCell alloc] initTextCell:@""];
}
- (void)setSearchType:(search::type)newType
@@ -408,7 +403,7 @@ static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type sear
- (NSButtonCell*)accessoryButton
{
NSButtonCell* button = [[NSButtonCell new] autorelease];
NSButtonCell* button = [NSButtonCell new];
[button setButtonType:NSSwitchButton];
[button setBezelStyle:NSSmallSquareBezelStyle];
[button setImagePosition:NSImageOnly];
@@ -432,7 +427,7 @@ static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type sear
if(!filterString.empty() && key_equivalent(all_items[index]) != originalFilterString)
continue;
BundleItemChooserItem* item = [[BundleItemChooserItem new] autorelease];
BundleItemChooserItem* item = [BundleItemChooserItem new];
[item setIndex:index];
[item setUuid:all_items[index]->uuid()];
rankedItems.insert(std::make_pair(0, item));
@@ -461,7 +456,7 @@ static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type sear
rank = 1 - std::max(nameRank, triggerRank);
}
BundleItemChooserItem* item = [[BundleItemChooserItem new] autorelease];
BundleItemChooserItem* item = [BundleItemChooserItem new];
[item setIndex:index];
[item setUuid:all_items[index]->uuid()];
rankedItems.insert(std::make_pair(rank, item));

View File

@@ -1,8 +1,4 @@
@interface OakBundleItemCell : NSTextFieldCell
{
NSString* keyEquivalent;
NSAttributedString* attributedTabTrigger;
}
@property (nonatomic, retain) NSString* keyEquivalent;
@property (nonatomic, retain) NSString* tabTrigger;
@property (nonatomic, retain) NSAttributedString* attributedTabTrigger;

View File

@@ -5,87 +5,72 @@
#import "../highlight_ranges.h"
@implementation OakBundleItemCell
@synthesize keyEquivalent, attributedTabTrigger;
- (id)copyWithZone:(NSZone*)zone
{
OakBundleItemCell* cell = [super copyWithZone:zone];
cell->keyEquivalent = [self.keyEquivalent copy];
cell->attributedTabTrigger = [self.attributedTabTrigger copy];
OakBundleItemCell* cell = [super copyWithZone:zone];
cell.keyEquivalent = [self.keyEquivalent copy];
cell.attributedTabTrigger = [self.attributedTabTrigger copy];
return cell;
}
- (void)dealloc
{
self.keyEquivalent = nil;
self.attributedTabTrigger = nil;
[super dealloc];
}
- (NSString*)tabTrigger
{
return attributedTabTrigger.string;
return self.attributedTabTrigger.string;
}
- (void)setTabTrigger:(NSString*)tabTrigger
{
self.attributedTabTrigger = tabTrigger ? [[[NSAttributedString alloc] initWithString:tabTrigger attributes:nil] autorelease] : nil;
self.attributedTabTrigger = tabTrigger ? [[NSAttributedString alloc] initWithString:tabTrigger attributes:nil] : nil;
}
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView
{
if(NSNotEmptyString(attributedTabTrigger.string))
if(NSNotEmptyString(self.attributedTabTrigger.string))
{
NSMutableAttributedString* attrStr = [[attributedTabTrigger mutableCopy] autorelease];
NSMutableAttributedString* attrStr = [self.attributedTabTrigger mutableCopy];
NSDictionary* highlightAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
@1, NSUnderlineStyleAttributeName,
[NSFont boldSystemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]], NSFontAttributeName,
nil];
NSDictionary* highlightAttributes = @{ NSUnderlineStyleAttributeName : @1, NSFontAttributeName : [NSFont boldSystemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]] };
HighlightRangesWithAttribute(attrStr, FLMatchingTextAttributeName, highlightAttributes);
[attrStr appendAttributedString:[[[NSAttributedString alloc] initWithString:@"⇥" attributes:nil] autorelease]];
CFTypeRef str = (CFAttributedStringRef)attrStr;
[attrStr appendAttributedString:[[NSAttributedString alloc] initWithString:@"⇥" attributes:nil]];
CFTypeRef str = (CFAttributedStringRef)CFBridgingRetain(attrStr);
HIThemeTextInfo textInfo = { kHIThemeTextInfoVersionZero, kThemeStateActive, kThemeSmallSystemFont, kHIThemeTextHorizontalFlushRight, kHIThemeTextVerticalFlushCenter, 0, kHIThemeTextTruncationNone, 1, 0 };
CGFloat width = 0.0;
CGFloat width = 0;
HIThemeGetTextDimensions(str, 0, &textInfo, &width, NULL, NULL);
NSRect triggerFrame;
NSDivideRect(cellFrame, &triggerFrame, &cellFrame, width + 12.0, NSMaxXEdge);
cellFrame.size.width -= 10.0;
triggerFrame.size.width -= 2.0;
NSDivideRect(cellFrame, &triggerFrame, &cellFrame, width + 12, NSMaxXEdge);
cellFrame.size.width -= 10;
triggerFrame.size.width -= 2;
[[NSColor colorWithCalibratedRed:0.0 green:0.0 blue:0.0 alpha:0.15] set];
[[NSColor colorWithCalibratedRed:0 green:0 blue:0 alpha:0.15] set];
NSRect podRect = triggerFrame;
[[NSBezierPath bezierPathWithRoundedRect:podRect xRadius:4 yRadius:4] fill];
HIRect bounds = { { NSMinX(podRect) - 5.0f, NSMinY(podRect) }, { NSWidth(podRect), NSHeight(podRect) } };
HIRect bounds = { { NSMinX(podRect) - 5, NSMinY(podRect) }, { NSWidth(podRect), NSHeight(podRect) } };
[[NSColor textColor] set];
if([self isHighlighted] && ([[controlView window] firstResponder] == controlView || ([[[controlView window] firstResponder] respondsToSelector:@selector(delegate)] && [[[controlView window] firstResponder] performSelector:@selector(delegate)] == controlView)) && [[controlView window] isKeyWindow])
[[NSColor alternateSelectedControlTextColor] set];
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
HIThemeDrawTextBox(str, &bounds, &textInfo, context, kHIThemeOrientationNormal);
CFRelease(str);
}
else if(NSNotEmptyString(keyEquivalent))
else if(NSNotEmptyString(self.keyEquivalent))
{
size_t keyStartsAt = 0;
std::string const glyphString = ns::glyphs_for_event_string(to_s(keyEquivalent), &keyStartsAt);
std::string const glyphString = ns::glyphs_for_event_string(to_s(self.keyEquivalent), &keyStartsAt);
NSString* modifiers = [NSString stringWithCxxString:glyphString.substr(0, keyStartsAt)];
NSString* key = [NSString stringWithCxxString:glyphString.substr(keyStartsAt)];
NSDictionary* fontAttr = @{ NSFontAttributeName : [self font] };
CGFloat width = std::max<CGFloat>(1, [modifiers sizeWithAttributes:fontAttr].width);
NSMutableAttributedString* aStr = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"\t%@\t%@", modifiers, key] attributes:fontAttr] autorelease];
NSMutableParagraphStyle* pStyle = [[NSMutableParagraphStyle new] autorelease];
[pStyle setTabStops:
[NSArray arrayWithObjects:
[[[NSTextTab alloc] initWithType:NSRightTabStopType location:width] autorelease],
[[[NSTextTab alloc] initWithType:NSLeftTabStopType location:width + 1] autorelease],
nil]];
NSMutableAttributedString* aStr = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"\t%@\t%@", modifiers, key] attributes:fontAttr];
NSMutableParagraphStyle* pStyle = [NSMutableParagraphStyle new];
[pStyle setTabStops:@[ [[NSTextTab alloc] initWithType:NSRightTabStopType location:width], [[NSTextTab alloc] initWithType:NSLeftTabStopType location:width + 1] ]];
[aStr addAttributes:@{ NSParagraphStyleAttributeName : pStyle } range:NSMakeRange(0, [aStr length])];
if([self isHighlighted] && ([[controlView window] firstResponder] == controlView || ([[[controlView window] firstResponder] respondsToSelector:@selector(delegate)] && [[[controlView window] firstResponder] performSelector:@selector(delegate)] == controlView)) && [[controlView window] isKeyWindow])
@@ -104,7 +89,7 @@
- (NSSize)cellSize
{
NSSize cellSize = [super cellSize];
cellSize.width += 55.0;
cellSize.width += 55;
return cellSize;
}
@end

View File

@@ -7,71 +7,7 @@
#import <document/document.h>
#import <oak/misc.h>
struct file_chooser_t
{
struct item_t
{
item_t () { }
item_t (document::document_ptr document, std::string const& matchName, double rank, std::vector< std::pair<size_t, size_t> > const& matchRanges) : _document(document), _match_name(matchName), _rank(rank), _match_ranges(matchRanges) { }
bool operator< (item_t const& rhs) const;
document::document_ptr _document;
std::string _match_name;
double _rank;
std::vector< std::pair<size_t, size_t> > _match_ranges;
size_t _parents = 0;
};
void setup (std::string const& path, std::string const& globString, std::string const& rankString);
void set_excluded_document (oak::uuid_t const& uuid);
void set_path (std::string const& path);
void set_filtering (std::string const& globString, std::string const& rankString);
void set_documents (std::vector<document::document_ptr> const& documents);
bool running () const;
bool poll_scanner ();
void wait () const;
void stop_scanner ();
std::string const& glob_string () const { return _glob_string; }
std::string const& rank_string () const { return _rank_string; }
std::vector<item_t> const& items () const { return _ranked_items; }
private:
void add_documents (std::vector<document::document_ptr> const& documents);
std::shared_ptr<document::scanner_t> _scanner;
std::string _path = NULL_STR;
std::string _glob_string = NULL_STR;
std::string _rank_string = NULL_STR;
oak::uuid_t _excluded_document;
std::vector<document::document_ptr> _all_documents;
std::vector<document::document_ptr> _filtered_documents;
std::vector<item_t> _ranked_items;
};
PUBLIC @interface OakFileChooser : NSObject <FilterListDataSource>
{
OBJC_WATCH_LEAKS(OakFileChooser)
NSString* _path;
NSString* projectPath;
NSViewController* viewController;
file_chooser_t helper;
document::document_ptr document;
OakTimer* scannerProbeTimer;
double pollInterval;
NSUInteger sourceIndex;
NSString* title;
}
+ (id)fileChooserWithPath:(NSString*)aPath projectPath:(NSString*)project;
@property (nonatomic, assign) NSUInteger sourceIndex;
@property (nonatomic, retain) NSString* path;

View File

@@ -20,6 +20,54 @@ OAK_DEBUG_VAR(FilterList_OakFileChooser);
// = Helper =
// ==========
struct file_chooser_t
{
struct item_t
{
item_t () { }
item_t (document::document_ptr document, std::string const& matchName, double rank, std::vector< std::pair<size_t, size_t> > const& matchRanges) : _document(document), _match_name(matchName), _rank(rank), _match_ranges(matchRanges) { }
bool operator< (item_t const& rhs) const;
document::document_ptr _document;
std::string _match_name;
double _rank;
std::vector< std::pair<size_t, size_t> > _match_ranges;
size_t _parents = 0;
};
void setup (std::string const& path, std::string const& globString, std::string const& rankString);
void set_excluded_document (oak::uuid_t const& uuid);
void set_path (std::string const& path);
void set_filtering (std::string const& globString, std::string const& rankString);
void set_documents (std::vector<document::document_ptr> const& documents);
bool running () const;
bool poll_scanner ();
void wait () const;
void stop_scanner ();
std::string const& glob_string () const { return _glob_string; }
std::string const& rank_string () const { return _rank_string; }
std::vector<item_t> const& items () const { return _ranked_items; }
private:
void add_documents (std::vector<document::document_ptr> const& documents);
std::shared_ptr<document::scanner_t> _scanner;
std::string _path = NULL_STR;
std::string _glob_string = NULL_STR;
std::string _rank_string = NULL_STR;
oak::uuid_t _excluded_document;
std::vector<document::document_ptr> _all_documents;
std::vector<document::document_ptr> _filtered_documents;
std::vector<item_t> _ranked_items;
};
bool file_chooser_t::item_t::operator< (item_t const& rhs) const
{
std::tuple<double, double, std::string> lhsValue(_rank, -_document->lru().value(), _match_name), rhsValue(rhs._rank, -rhs._document->lru().value(), rhs._match_name);
@@ -288,7 +336,7 @@ void file_chooser_t::wait () const
@implementation FileChooserItem
@synthesize selectionString;
+ (FileChooserItem*)fileChooserItemWithItem:(file_chooser_t::item_t const&)someItem selection:(NSString*)aSelection { return [[[FileChooserItem alloc] initWithItem:someItem selection:aSelection] autorelease]; }
+ (FileChooserItem*)fileChooserItemWithItem:(file_chooser_t::item_t const&)someItem selection:(NSString*)aSelection { return [[FileChooserItem alloc] initWithItem:someItem selection:aSelection]; }
- (id)copyWithZone:(NSZone*)zone { return [[FileChooserItem alloc] initWithItem:data selection:selectionString]; }
- (BOOL)isEqual:(FileChooserItem*)anotherItem { return [self.identifier isEqualToString:anotherItem.identifier]; }
- (id)objectForKey:(id)key { return [self valueForKey:key]; }
@@ -298,17 +346,11 @@ void file_chooser_t::wait () const
if(self = [super init])
{
data = someItem;
selectionString = [aSelection retain];
selectionString = aSelection;
}
return self;
}
- (void)dealloc
{
[selectionString release];
[super dealloc];
}
- (NSString*)path { return [NSString stringWithCxxString:data._document->path()]; }
- (NSString*)identifier { return [NSString stringWithCxxString:data._document->identifier()]; }
- (document::document_ptr const&)document { return data._document; }
@@ -318,8 +360,8 @@ void file_chooser_t::wait () const
NSAttributedString* res = AttributedStringWithMarkedUpRanges(data._match_name, data._match_ranges);
if(data._parents)
{
NSMutableAttributedString* prefix = [[res mutableCopy] autorelease];
NSAttributedString* suffix = [[[NSAttributedString alloc] initWithString:[NSString stringWithCxxString:parents(data._document->path(), data._parents)] attributes:nil] autorelease];
NSMutableAttributedString* prefix = [res mutableCopy];
NSAttributedString* suffix = [[NSAttributedString alloc] initWithString:[NSString stringWithCxxString:parents(data._document->path(), data._parents)] attributes:nil];
[prefix appendAttributedString:suffix];
res = prefix;
}
@@ -368,7 +410,7 @@ void file_chooser_t::wait () const
globHistoryList = [[OakHistoryList alloc] initWithName:[NSString stringWithFormat:@"Find in Folder Globs.%@", fileChooser.projectPath] stackSize:10 defaultItems:@"*", @"*.txt", @"*.{c,h}", nil];
fileChooser.globString = globHistoryList.head;
globComboBox = [[[NSComboBox alloc] initWithFrame:NSMakeRect(0, 0, 35, 26)] autorelease];
globComboBox = [[NSComboBox alloc] initWithFrame:NSMakeRect(0, 0, 35, 26)];
globComboBox.font = [NSFont userFixedPitchFontOfSize:12];
globComboBox.delegate = self;
globComboBox.autoresizingMask = NSViewWidthSizable;
@@ -376,14 +418,14 @@ void file_chooser_t::wait () const
[globComboBox bind:@"value" toObject:globHistoryList withKeyPath:@"head" options:nil];
[globComboBox bind:@"contentValues" toObject:globHistoryList withKeyPath:@"list" options:nil];
searchField = [[[NSSearchField alloc] initWithFrame:NSMakeRect(0, 0, splitViewWidth - NSWidth(globComboBox.frame), 0)] autorelease];
searchField = [[NSSearchField alloc] initWithFrame:NSMakeRect(0, 0, splitViewWidth - NSWidth(globComboBox.frame), 0)];
searchField.action = @selector(didChangeFilterString:);
searchField.target = self;
searchField.stringValue = fileChooser.filterString;
searchField.autoresizingMask = NSViewWidthSizable;
[searchField.cell setScrollable:YES];
NSSplitView* splitView = [[[NSSplitView alloc] initWithFrame:NSMakeRect((viewWidth-splitViewWidth)/2, 8, splitViewWidth, 26)] autorelease];
NSSplitView* splitView = [[NSSplitView alloc] initWithFrame:NSMakeRect((viewWidth-splitViewWidth)/2, 8, splitViewWidth, 26)];
splitView.delegate = self;
splitView.autoresizingMask = NSViewWidthSizable;
[splitView setVertical:YES];
@@ -391,7 +433,7 @@ void file_chooser_t::wait () const
[splitView addSubview:globComboBox];
splitView.autosaveName = @"File Chooser Splitter Position";
sourceSelector = [[[NSSegmentedControl alloc] initWithFrame:NSMakeRect(-1, NSMaxY(splitView.frame) + 5, viewWidth+2, 23)] autorelease];
sourceSelector = [[NSSegmentedControl alloc] initWithFrame:NSMakeRect(-1, NSMaxY(splitView.frame) + 5, viewWidth+2, 23)];
sourceSelector.refusesFirstResponder = YES;
sourceSelector.target = self;
sourceSelector.action = @selector(takeSourceIndexFrom:);
@@ -401,7 +443,7 @@ void file_chooser_t::wait () const
sourceSelector.selectedSegment = fileChooser.sourceIndex;
[sourceSelector setLabel:@"Open Files" forSegment:2];
self.view = [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, viewWidth, NSMaxY(sourceSelector.frame)-3)] autorelease];
self.view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, viewWidth, NSMaxY(sourceSelector.frame)-3)];
self.view.autoresizingMask = NSViewWidthSizable;
[self.view addSubview:splitView];
[self.view addSubview:sourceSelector];
@@ -469,19 +511,31 @@ void file_chooser_t::wait () const
- (void)dealloc
{
searchField.target = nil;
searchField.action = NULL;
[globComboBox unbind:@"value"];
[globComboBox unbind:@"contentValues"];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[globHistoryList dealloc];
[super dealloc];
}
@end
@implementation OakFileChooser
{
OBJC_WATCH_LEAKS(OakFileChooser)
NSString* _path;
NSString* projectPath;
NSViewController* viewController;
file_chooser_t helper;
document::document_ptr document;
OakTimer* scannerProbeTimer;
double pollInterval;
NSUInteger sourceIndex;
NSString* title;
}
@synthesize scannerProbeTimer, path = _path, projectPath, sourceIndex, title;
- (NSString*)effectivePath
@@ -529,8 +583,8 @@ void file_chooser_t::wait () const
{
if((self = [super init]))
{
_path = [aPath retain];
projectPath = [project retain];
_path = aPath;
projectPath = project;
[self updateTitle];
helper.setup([[self effectivePath] fileSystemRepresentation], "*", "");
@@ -541,7 +595,7 @@ void file_chooser_t::wait () const
+ (id)fileChooserWithPath:(NSString*)aPath projectPath:(NSString*)project
{
return [[[self alloc] initWithPath:aPath projectPath:project] autorelease];
return [[self alloc] initWithPath:aPath projectPath:project];
}
- (NSViewController*)viewController
@@ -553,7 +607,7 @@ void file_chooser_t::wait () const
- (NSButtonCell*)accessoryButton
{
NSButtonCell* button = [[NSButtonCell new] autorelease];
NSButtonCell* button = [NSButtonCell new];
[button setButtonType:NSSwitchButton];
[button setBezelStyle:NSSmallSquareBezelStyle];
[button setImagePosition:NSImageOnly];
@@ -565,15 +619,9 @@ void file_chooser_t::wait () const
- (void)dealloc
{
[viewController release];
[self stopProbing];
[projectPath release];
[_path release];
if(document)
document->close();
[super dealloc];
}
// ===========================
@@ -614,8 +662,7 @@ void file_chooser_t::wait () const
{
if(newPath != _path)
{
[_path release];
_path = [newPath retain];
_path = newPath;
if(sourceIndex == 1)
{
helper.set_path([[self effectivePath] fileSystemRepresentation]);
@@ -721,8 +768,8 @@ void file_chooser_t::wait () const
- (NSAttributedString*)infoStringForItem:(id)item
{
NSMutableAttributedString* str = [[[item infoString] mutableCopy] autorelease];
[str appendAttributedString:[[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"\t%zu item%s", helper.items().size(), helper.items().size() != 1 ? "s" : ""] attributes:nil] autorelease]];
NSMutableAttributedString* str = [[item infoString] mutableCopy];
[str appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"\t%zu item%s", helper.items().size(), helper.items().size() != 1 ? "s" : ""] attributes:nil]];
return str;
}

View File

@@ -22,13 +22,13 @@ OAK_DEBUG_VAR(FilterList_SymbolChooser);
{
symbolChooser = chooser;
searchField = [[[NSSearchField alloc] initWithFrame:NSMakeRect(10, 10, 180, 22)] autorelease];
searchField = [[NSSearchField alloc] initWithFrame:NSMakeRect(10, 10, 180, 22)];
searchField.target = symbolChooser;
searchField.action = @selector(search:);
searchField.autoresizingMask = NSViewWidthSizable|NSViewMinYMargin;
[searchField.cell setScrollable:YES];
self.view = [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 200, NSMaxY(searchField.frame) + 8)] autorelease];
self.view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 200, NSMaxY(searchField.frame) + 8)];
self.view.autoresizingMask = NSViewWidthSizable|NSViewMinYMargin;
[self.view addSubview:searchField];
}
@@ -39,8 +39,6 @@ OAK_DEBUG_VAR(FilterList_SymbolChooser);
{
searchField.delegate = nil;
searchField.target = nil;
searchField.action = NULL;
[super dealloc];
}
- (void)setSearchFieldDelegate:(id)aDelegate
@@ -92,7 +90,7 @@ OAK_DEBUG_VAR(FilterList_SymbolChooser);
+ (id)symbolChooserForDocument:(document::document_ptr)aDocument
{
return [[[self alloc] initWithDocument:aDocument] autorelease];
return [[self alloc] initWithDocument:aDocument];
}
- (NSString*)title
@@ -139,7 +137,5 @@ OAK_DEBUG_VAR(FilterList_SymbolChooser);
- (void)dealloc
{
document->close();
[viewController release];
[super dealloc];
}
@end

View File

@@ -2,13 +2,6 @@
#import <document/document.h>
@interface FileChooserSymbolItem : NSObject
{
NSString* path;
NSString* selectionString;
NSString* identifier;
NSAttributedString* displayString;
NSAttributedString* infoString;
}
@property (nonatomic, retain) NSString* path;
@property (nonatomic, retain) NSString* selectionString;
@property (nonatomic, retain) NSString* identifier;

View File

@@ -4,8 +4,6 @@
#import <text/ranker.h>
@implementation FileChooserSymbolItem
@synthesize path, selectionString, identifier, displayString, infoString;
- (id)initWithPath:(NSString*)aPath selectionString:(NSString*)aSelectionString identifier:(NSString*)anIdentifier displayString:(NSAttributedString*)aDisplayString infoString:(NSAttributedString*)anInfoString
{
if((self = [super init]))
@@ -20,17 +18,6 @@
}
- (id)objectForKey:(id)key { return [self valueForKey:key]; }
- (void)dealloc
{
self.path = nil;
self.identifier = nil;
self.selectionString = nil;
self.displayString = nil;
self.infoString = nil;
[super dealloc];
}
@end
static FileChooserSymbolItem* CreateItem (document::document_ptr const& document, text::pos_t const& pos, std::string const& candidate, std::vector< std::pair<size_t, size_t> > const& ranges)
@@ -40,7 +27,7 @@ static FileChooserSymbolItem* CreateItem (document::document_ptr const& document
NSString* identifier = [NSString stringWithCxxString:document->identifier()];
NSAttributedString* display = AttributedStringWithMarkedUpRanges(candidate, ranges);
NSAttributedString* info = [[NSAttributedString alloc] initWithString:[NSString stringWithCxxString:document->display_name() + ":" + (std::string)pos]];
return [[[FileChooserSymbolItem alloc] initWithPath:path selectionString:selection identifier:identifier displayString:display infoString:info] autorelease];
return [[FileChooserSymbolItem alloc] initWithPath:path selectionString:selection identifier:identifier displayString:display infoString:info];
}
NSArray* SymbolListForDocument (document::document_ptr const& document, std::string const& filter)

View File

@@ -7,7 +7,7 @@ NSString* const FLMatchingTextAttributeName = @"FLMatchingTextAttributeName";
NSAttributedString* AttributedStringWithMarkedUpRanges (std::string const& in, std::vector< std::pair<size_t, size_t> > const& ranges, size_t offset)
{
NSMutableAttributedString* res = [[[NSMutableAttributedString alloc] init] autorelease];
NSMutableAttributedString* res = [[NSMutableAttributedString alloc] init];
NSDictionary* highlightAttrs = @{ FLMatchingTextAttributeName : [NSNull null] };
ASSERT(offset >= 0 && offset < in.size());
@@ -21,12 +21,12 @@ NSAttributedString* AttributedStringWithMarkedUpRanges (std::string const& in, s
size_t from = 0;
iterate(it, ranges)
{
[res appendAttributedString:[[[NSAttributedString alloc] initWithString:[NSString stringWithCxxString:std::string(text.begin() + from, text.begin() + it->first)] attributes:nil] autorelease]];
[res appendAttributedString:[[[NSAttributedString alloc] initWithString:[NSString stringWithCxxString:std::string(text.begin() + it->first, text.begin() + it->second)] attributes:highlightAttrs] autorelease]];
[res appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithCxxString:std::string(text.begin() + from, text.begin() + it->first)] attributes:nil]];
[res appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithCxxString:std::string(text.begin() + it->first, text.begin() + it->second)] attributes:highlightAttrs]];
from = it->second;
}
if(from < text.size())
[res appendAttributedString:[[[NSAttributedString alloc] initWithString:[NSString stringWithCxxString:std::string(text.begin() + from, text.end())] attributes:nil] autorelease]];
[res appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithCxxString:std::string(text.begin() + from, text.end())] attributes:nil]];
return res;
}

View File

@@ -3,5 +3,3 @@ EXPORT = src/OakFilterList.h src/datasources/*.h
CP_Resources = resources/*
LINK += text bundles document io plist MGScopeBar ns OakAppKit OakFoundation OakSystem OakTextView regexp scope
FRAMEWORKS = Cocoa Carbon
OBJCXX_FLAGS += -fno-objc-arc