dupeguru-cocoa/cocoalib/views/NSTableViewAdditions.m

119 lines
4.2 KiB
Objective-C

/*
Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at
http://www.gnu.org/licenses/gpl-3.0.html
*/
#import "NSTableViewAdditions.h"
#import "NSEventAdditions.h"
#import "Utils.h"
@implementation NSTableView(NSTableViewAdditions)
/* Private methods */
// Alright, this is a hack. It has been added to put in common some table and outline code, but the
// thing is an outline view delegate doesn't use tableView:shouldEditTableColumn:row:. Anyway, for
// the outline, just using [column isEditable] works in moneyGuru for now, so we can keep it that way.
- (BOOL)shouldEditTableColumn:(NSTableColumn *)column row:(NSInteger)row
{
if (![column isEditable])
return NO;
id delegate = [self delegate];
if ([delegate respondsToSelector:@selector(tableView:shouldEditTableColumn:row:)])
{
return [delegate tableView:self shouldEditTableColumn:column row:row];
}
else
{
return YES;
}
}
/* Public Methods */
// Returns whether the responder chain should be stopeed or not
- (BOOL)dispatchSpecialKeys:(NSEvent *)event
{
id delegate = [self delegate];
if ([delegate respondsToSelector:@selector(tableView:receivedKeyEvent:)]) {
if ([delegate tableView:self receivedKeyEvent:event]) {
return YES;
}
}
BOOL stopChain = NO;
if ([event isDeleteOrBackspace] && [delegate respondsToSelector:@selector(tableViewHadDeletePressed:)])
{
stopChain = [delegate tableViewHadDeletePressed:self];
}
if ([event isReturnOrEnter] && [delegate respondsToSelector:@selector(tableViewHadReturnPressed:)])
{
stopChain = [delegate tableViewHadReturnPressed:self];
}
if ([event isSpace] && [delegate respondsToSelector:@selector(tableViewHadSpacePressed:)])
{
stopChain = [delegate tableViewHadSpacePressed:self];
}
if ([event isTab])
{
stopChain = YES;
[[self window] makeFirstResponder:[self nextValidKeyView]];
}
if ([event isBackTab])
{
stopChain = YES;
// Ok, this is a big hack. the normal handling of NSTableView must handle this, but we must skip over
// a NSClipView and a NSScrollView before getting to the actual previousValidKeyView.
// However, when we are not in Full Keyboard Access mode, there's no problem. Thus, we assume that
// when previousValidKeyView's class is a NSClipView, it means we must perform the hack
NSView *previous = [self previousValidKeyView];
if ([[previous className] isEqualTo:@"NSClipView"]) // Can't use isKindOfClass, we don't want to test for a subclass
previous = [[previous previousValidKeyView] previousValidKeyView];
[[self window] makeFirstResponder:previous];
}
return stopChain;
}
- (NSNotification *)processTextDidEndEditing:(NSNotification *)notification;
{
NSDictionary *userInfo = [notification userInfo];
int textMovement = [[userInfo valueForKey:@"NSTextMovement"] intValue];
if (textMovement == NSReturnTextMovement)
{
// Stop editing
NSMutableDictionary *newInfo;
newInfo = [NSMutableDictionary dictionaryWithDictionary:userInfo];
[newInfo setObject:[NSNumber numberWithInt:NSIllegalTextMovement] forKey:@"NSTextMovement"];
notification = [NSNotification notificationWithName:[notification name] object:[notification object] userInfo:newInfo];
}
return notification;
}
- (void)startEditing
{
// Make sure one row is selected
if ([self selectedRow] == -1)
{
return;
}
// We only want to edit columns that are editable. If there aren't any, don't edit.
for (NSInteger i=0;i<[[self tableColumns] count];i++) {
NSTableColumn *col = [[self tableColumns] objectAtIndex:i];
if ([col isHidden]) {
continue;
}
if (![self shouldEditTableColumn:col row:[self selectedRow]]) {
continue;
}
// We only want one row to be selected.
NSIndexSet *selection = [NSIndexSet indexSetWithIndex:[self selectedRow]];
[self selectRowIndexes:selection byExtendingSelection:NO];
[self editColumn:i row:[self selectedRow] withEvent:nil select:YES];
break;
}
}
@end