Multiple selections are now handled correctly

This commit is contained in:
michael starke
2016-02-26 14:26:09 +01:00
parent c4eb499cf6
commit cbb98ff50f
8 changed files with 125 additions and 140 deletions

View File

@@ -75,10 +75,6 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
/* /*
State (active group/entry) State (active group/entry)
*/ */
//@property (nonatomic, weak) KPKEntry *selectedEntry;
//@property (nonatomic, weak) KPKGroup *selectedGroup;
//@property (nonatomic, weak) KPKNode *selectedItem;
@property (nonatomic, copy, readonly) NSArray<KPKNode *> *selectedNodes; @property (nonatomic, copy, readonly) NSArray<KPKNode *> *selectedNodes;
@property (nonatomic, copy) NSArray<KPKGroup *> *selectedGroups; @property (nonatomic, copy) NSArray<KPKGroup *> *selectedGroups;

View File

@@ -496,13 +496,6 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
[self _presentTrashAlertForItem:node]; [self _presentTrashAlertForItem:node];
return; return;
} }
// if(node.asGroup == self.selectedGroup) {
// self.selectedGroup = node.asGroup;
// }
// if(node.asEntry == self.selectedEntry) {
// self.selectedEntry = node.asEntry;
// }
if(!self.tree.metaData.useTrash) { if(!self.tree.metaData.useTrash) {
/* Display warning about permanently removing items! */ /* Display warning about permanently removing items! */
@@ -610,35 +603,21 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
} }
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)anItem { - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)anItem {
id<MPTargetNodeResolving> entryResolver = [NSApp targetForAction:@selector(currentTargetEntry)]; id<MPTargetNodeResolving> entryResolver = [NSApp targetForAction:@selector(currentTargetEntries)];
id<MPTargetNodeResolving> groupResolver = [NSApp targetForAction:@selector(currentTargetGroup)]; id<MPTargetNodeResolving> groupResolver = [NSApp targetForAction:@selector(currentTargetGroups)];
id<MPTargetNodeResolving> nodeResolver = [NSApp targetForAction:@selector(currentTargetNode)]; id<MPTargetNodeResolving> nodeResolver = [NSApp targetForAction:@selector(currentTargetNodes)];
/*
NSLog(@"entryResolver:%@", [entryResolver class]);
NSLog(@"groupResolver:%@", [groupResolver class]);
NSLog(@"nodeResolver:%@", [nodeResolver class]);
*/
KPKNode *targetNode = [nodeResolver currentTargetNode]; NSArray *targetNodes = [nodeResolver currentTargetNodes];
KPKEntry *targetEntry = [entryResolver currentTargetEntry]; NSArray *targetGroups = [groupResolver currentTargetGroups];
KPKGroup *targetGroup = [groupResolver currentTargetGroup]; NSArray *targetEntries = [entryResolver currentTargetEntries];
/* KPKEntry *targetEntry = targetEntries.count == 1 ? targetEntries.firstObject : nil;
if(targetNode.asGroup) { KPKGroup *targetGroup = targetGroups.count == 1 ? targetGroups.firstObject : nil;
NSLog(@"targetNode:%@", ((KPKGroup *)targetNode).name);
}
else if(targetNode.asEntry) {
NSLog(@"targetNode:%@", ((KPKEntry *)targetNode).title);
}
NSLog(@"targetGroup:%@", targetGroup.name);
NSLog(@"tagetEntry:%@", targetEntry.title );
*/
if(self.encrypted || self.isReadOnly) { return NO; } if(self.encrypted || self.isReadOnly) { return NO; }
BOOL valid = targetNode ? targetNode.isEditable : YES; BOOL valid = /*targetNode ? targetNode.isEditable : */YES;
switch([MPActionHelper typeForAction:[anItem action]]) { switch([MPActionHelper typeForAction:[anItem action]]) {
case MPActionAddGroup: case MPActionAddGroup:
valid &= (nil != targetGroup); valid &= (nil != targetGroup);
@@ -651,13 +630,17 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
valid &= !targetGroup.isTrashed; valid &= !targetGroup.isTrashed;
break; break;
case MPActionDelete: case MPActionDelete:
valid &= (nil != targetNode); valid &= targetNodes.count > 0;
valid &= (self.trash != targetNode); for(KPKNode *node in targetNodes) {
valid &= (targetNode != self.tree.root); valid &= (self.trash != node);
//valid &= ![self isItemTrashed:targetNode]; valid &= (node != self.tree.root);
if(!valid) {
break;
}
}
break; break;
case MPActionDuplicateEntry: case MPActionDuplicateEntry:
valid &= (nil != targetEntry); valid &= targetEntries.count > 0;
break; break;
case MPActionEmptyTrash: case MPActionEmptyTrash:
valid &= ([self.trash.groups count] + [self.trash.entries count]) > 0; valid &= ([self.trash.groups count] + [self.trash.entries count]) > 0;
@@ -726,13 +709,12 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
#pragma mark - #pragma mark -
#pragma mark MPTargetNodeResolving #pragma mark MPTargetNodeResolving
- (KPKEntry *)currentTargetEntry { - (NSArray<KPKEntry *> *)currentTargetEntries {
return self.selectedEntries.firstObject; return self.selectedEntries;
//return self.selectedEntry;
} }
- (KPKGroup *)currentTargetGroup { - (NSArray<KPKGroup *> *)currentTargetGroups {
return self.selectedGroups.firstObject; return self.selectedGroups;
} }
@end @end

View File

@@ -334,25 +334,31 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
} }
- (void)createGroup:(id)sender { - (void)createGroup:(id)sender {
id<MPTargetNodeResolving> target = [NSApp targetForAction:@selector(currentTargetGroup)]; id<MPTargetNodeResolving> target = [NSApp targetForAction:@selector(currentTargetGroups)];
KPKGroup *group = [target currentTargetGroup]; NSArray *groups = [target currentTargetGroups];
MPDocument *document = self.document; MPDocument *document = self.document;
if(!group) { if(groups.count == 1) {
group = document.root; [document createGroup:groups.firstObject];
}
else {
[document createGroup:document.root];
} }
[document createGroup:group];
} }
- (void)createEntry:(id)sender { - (void)createEntry:(id)sender {
id<MPTargetNodeResolving> target = [NSApp targetForAction:@selector(currentTargetGroup)]; id<MPTargetNodeResolving> target = [NSApp targetForAction:@selector(currentTargetGroups)];
KPKGroup *group = [target currentTargetGroup]; NSArray *groups = [target currentTargetGroups];
[(MPDocument *)self.document createEntry:group]; if(groups.count == 1) {
[(MPDocument *)self.document createEntry:groups.firstObject];
}
} }
- (void)delete:(id)sender { - (void)delete:(id)sender {
id<MPTargetNodeResolving> target = [NSApp targetForAction:@selector(currentTargetNode)]; id<MPTargetNodeResolving> target = [NSApp targetForAction:@selector(currentTargetNodes)];
KPKNode *node = [target currentTargetNode]; NSArray *nodes = [target currentTargetNodes];
[self.document deleteNode:node]; for(KPKNode *node in nodes) {
[self.document deleteNode:node];
}
} }
- (void)pickExpiryDate:(id)sender { - (void)pickExpiryDate:(id)sender {
@@ -377,9 +383,11 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
} }
- (void)performAutotypeForEntry:(id)sender { - (void)performAutotypeForEntry:(id)sender {
id<MPTargetNodeResolving> entryResolver = [NSApp targetForAction:@selector(currentTargetEntry)]; id<MPTargetNodeResolving> entryResolver = [NSApp targetForAction:@selector(currentTargetEntries)];
KPKEntry *targetEntry = [entryResolver currentTargetEntry]; NSArray *entries = [entryResolver currentTargetEntries];
[[MPAutotypeDaemon defaultDaemon] performAutotypeForEntry:targetEntry]; if(entries.count == 1) {
[[MPAutotypeDaemon defaultDaemon] performAutotypeForEntry:entries.firstObject];
}
} }
- (void)showInspector:(id)sender { - (void)showInspector:(id)sender {

View File

@@ -45,22 +45,25 @@ static NSUInteger const kMPAttachmentsMenuItem = 2000;
[menu removeItem:lastItem]; [menu removeItem:lastItem];
} }
/* since we can get opened on the non-selected entry, we have to resolve the target node */ /* since we can get opened on the non-selected entry, we have to resolve the target node */
id<MPTargetNodeResolving> entryResolver = [NSApp targetForAction:@selector(currentTargetEntry)]; id<MPTargetNodeResolving> entryResolver = [NSApp targetForAction:@selector(currentTargetEntries)];
KPKEntry *entry = [entryResolver currentTargetEntry]; NSArray *entries = [entryResolver currentTargetEntries];
if(entries.count != 1) {
if([entry.customAttributes count] > 0) { return;
}
KPKEntry *entry = entries.lastObject;
if(entry.customAttributes.count > 0) {
[menu addItem:[NSMenuItem separatorItem]]; [menu addItem:[NSMenuItem separatorItem]];
NSMenuItem *attributeItem = [[NSMenuItem alloc] init]; NSMenuItem *attributeItem = [[NSMenuItem alloc] init];
NSMenu *submenu = [[NSMenu alloc] initWithTitle:@"Fields"]; NSMenu *submenu = [[NSMenu alloc] initWithTitle:@"Fields"];
[attributeItem setTitle:NSLocalizedString(@"COPY_CUSTOM_FIELDS", "Submenu to Copy custom fields")]; attributeItem.title = NSLocalizedString(@"COPY_CUSTOM_FIELDS", "Submenu to Copy custom fields");
[attributeItem setTag:kMPCustomFieldMenuItem]; attributeItem.tag = kMPCustomFieldMenuItem;
for (KPKAttribute *attribute in entry.customAttributes) { for (KPKAttribute *attribute in entry.customAttributes) {
NSString *title = [NSString stringWithFormat:NSLocalizedString(@"COPY_FIELD_%@", "Mask for title to copy field value"), attribute.key]; NSString *title = [NSString stringWithFormat:NSLocalizedString(@"COPY_FIELD_%@", "Mask for title to copy field value"), attribute.key];
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title action:@selector(copyCustomAttribute:) keyEquivalent:@""]; NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title action:@selector(copyCustomAttribute:) keyEquivalent:@""];
[item setTag:[entry.customAttributes indexOfObject:attribute]]; item.tag = [entry.customAttributes indexOfObject:attribute];
[submenu addItem:item]; [submenu addItem:item];
} }
[attributeItem setSubmenu:submenu]; attributeItem.submenu = submenu;
[menu addItem:attributeItem]; [menu addItem:attributeItem];
} }
} }

View File

@@ -32,17 +32,13 @@
@implementation MPEntryTableDataSource @implementation MPEntryTableDataSource
- (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard { - (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard {
NSArray *entries = self.viewController.entryArrayController.selectedObjects;
if([rowIndexes count] != 1) { for(KPKEntry *entry in entries) {
return NO; // No valid drag if(![entry isKindOfClass:[KPKEntry class]]) {
return NO;
}
} }
[pboard writeObjects:entries];
id item = [self.viewController.entryArrayController arrangedObjects][[rowIndexes firstIndex]];
if(![item isKindOfClass:[KPKEntry class]]) {
return NO;
}
KPKEntry *draggedEntry = (KPKEntry *)item;
[pboard writeObjects:@[draggedEntry]];
return YES; return YES;
} }

View File

@@ -256,9 +256,9 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
NSAssert(entry.parent != nil, @"Entry needs to have a parent"); NSAssert(entry.parent != nil, @"Entry needs to have a parent");
NSString *parentTitleKeyPath = [NSString stringWithFormat:@"%@.%@.%@", NSString *parentTitleKeyPath = [NSString stringWithFormat:@"%@.%@.%@",
NSStringFromSelector(@selector(objectValue)), NSStringFromSelector(@selector(objectValue)),
NSStringFromSelector(@selector(parent)), NSStringFromSelector(@selector(parent)),
NSStringFromSelector(@selector(title))]; NSStringFromSelector(@selector(title))];
NSString *parentIconImageKeyPath = [NSString stringWithFormat:@"%@.%@.%@", NSString *parentIconImageKeyPath = [NSString stringWithFormat:@"%@.%@.%@",
NSStringFromSelector(@selector(objectValue)), NSStringFromSelector(@selector(objectValue)),
NSStringFromSelector(@selector(parent)), NSStringFromSelector(@selector(parent)),
@@ -317,14 +317,14 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
else if(isNotesColumn) { else if(isNotesColumn) {
NSDictionary *options = @{ NSValueTransformerNameBindingOption : MPStripLineBreaksTransformerName }; NSDictionary *options = @{ NSValueTransformerNameBindingOption : MPStripLineBreaksTransformerName };
NSString *notesKeyPath = [NSString stringWithFormat:@"%@.%@", NSString *notesKeyPath = [NSString stringWithFormat:@"%@.%@",
NSStringFromSelector(@selector(objectValue)), NSStringFromSelector(@selector(objectValue)),
NSStringFromSelector(@selector(notes))]; NSStringFromSelector(@selector(notes))];
[view.textField bind:NSValueBinding toObject:view withKeyPath:notesKeyPath options:options]; [view.textField bind:NSValueBinding toObject:view withKeyPath:notesKeyPath options:options];
} }
else if(isAttachmentColumn) { else if(isAttachmentColumn) {
NSString *binariesCoundKeyPath = [NSString stringWithFormat:@"%@.%@.@count", NSString *binariesCoundKeyPath = [NSString stringWithFormat:@"%@.%@.@count",
NSStringFromSelector(@selector(objectValue)), NSStringFromSelector(@selector(objectValue)),
NSStringFromSelector(@selector(binaries))]; NSStringFromSelector(@selector(binaries))];
[view.textField bind:NSValueBinding toObject:view withKeyPath:binariesCoundKeyPath options:nil]; [view.textField bind:NSValueBinding toObject:view withKeyPath:binariesCoundKeyPath options:nil];
} }
} }
@@ -348,25 +348,22 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
} }
#pragma mark MPTargetItemResolving #pragma mark MPTargetItemResolving
- (KPKEntry *)currentTargetEntry { - (NSArray<KPKEntry *> *)currentTargetEntries {
NSInteger activeRow = self.entryTable.clickedRow; /*NSInteger activeRow = self.entryTable.clickedRow;
/* Fall back to selection e.g. for toolbar actions */ if(activeRow > -1) {
if(activeRow < 0 ) { return @[ [self.entryArrayController arrangedObjects][activeRow] ];
activeRow = self.entryTable.selectedRow;
} }
if(activeRow >= 0 && activeRow <= [self.entryArrayController.arrangedObjects count]) { */
return [self.entryArrayController arrangedObjects][activeRow]; return self.entryArrayController.selectedObjects;
}
return nil;
} }
- (KPKNode *)currentTargetNode { - (NSArray<KPKNode *> *)currentTargetNodes {
KPKEntry *entry = [self currentTargetEntry]; NSArray *entries = [self currentTargetEntries];
if(entry) { if(entries.count > 0) {
return entry; return entries;
} }
MPDocument *document = self.windowController.document; MPDocument *document = self.windowController.document;
return document.selectedNodes.firstObject; return document.selectedNodes;
} }
#pragma mark MPDocument Notifications #pragma mark MPDocument Notifications
@@ -403,13 +400,13 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
document.selectedEntries = self.entryArrayController.selectedObjects; document.selectedEntries = self.entryArrayController.selectedObjects;
/* /*
if(document.selectedEntry.parent == document.selectedGroup || document.hasSearch) { if(document.selectedEntry.parent == document.selectedGroup || document.hasSearch) {
document.selectedItem = document.selectedEntry; document.selectedItem = document.selectedEntry;
} }
else { else {
document.selectedEntry = nil; document.selectedEntry = nil;
} }
*/ */
} }
- (void)_didAddItem:(NSNotification *)notification { - (void)_didAddItem:(NSNotification *)notification {
@@ -433,13 +430,13 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
- (void)_didExitSearch:(NSNotification *)notification { - (void)_didExitSearch:(NSNotification *)notification {
[[self.entryTable tableColumnWithIdentifier:MPEntryTableParentColumnIdentifier] setHidden:YES]; [[self.entryTable tableColumnWithIdentifier:MPEntryTableParentColumnIdentifier] setHidden:YES];
// MPDocument *document = [[self windowController] document]; // MPDocument *document = [[self windowController] document];
// document.selectedItem = document.selectedGroup; // document.selectedItem = document.selectedGroup;
// // TODO: really necessary? // // TODO: really necessary?
// if( nil == document.selectedItem && nil == document.selectedGroup ) { // if( nil == document.selectedItem && nil == document.selectedGroup ) {
// [self.entryArrayController unbind:NSContentArrayBinding]; // [self.entryArrayController unbind:NSContentArrayBinding];
// [self.entryArrayController setContent:nil]; // [self.entryArrayController setContent:nil];
// } // }
[self _updateContextBar]; [self _updateContextBar];
} }
@@ -452,8 +449,8 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
/* If the document was locked and unlocked we do not need to recheck */ /* If the document was locked and unlocked we do not need to recheck */
if(document.unlockCount != 1) { if(document.unlockCount != 1) {
/* TODO add another method to display this! /* TODO add another method to display this!
[self.footerInfoText setHidden:![document hasMalformedAutotypeItems]]; [self.footerInfoText setHidden:![document hasMalformedAutotypeItems]];
[self.footerInfoText setStringValue:NSLocalizedString(@"DOCUMENT_AUTOTYPE_CORRUPTION_WARNING", "")]; [self.footerInfoText setStringValue:NSLocalizedString(@"DOCUMENT_AUTOTYPE_CORRUPTION_WARNING", "")];
*/ */
} }
} }
@@ -623,21 +620,24 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
#pragma mark Actions #pragma mark Actions
- (void)copyPassword:(id)sender { - (void)copyPassword:(id)sender {
KPKEntry *selectedEntry = [self currentTargetNode].asEntry; NSArray *nodes = [self currentTargetNodes];
KPKEntry *selectedEntry = nodes.count == 1 ? [nodes.firstObject asEntry] : nil;
if(selectedEntry) { if(selectedEntry) {
[self _copyToPasteboard:[selectedEntry.password finalValueForEntry:selectedEntry] overlayInfo:MPOverlayInfoPassword name:nil]; [self _copyToPasteboard:[selectedEntry.password finalValueForEntry:selectedEntry] overlayInfo:MPOverlayInfoPassword name:nil];
} }
} }
- (void)copyUsername:(id)sender { - (void)copyUsername:(id)sender {
KPKEntry *selectedEntry = [self currentTargetNode].asEntry; NSArray *nodes = [self currentTargetNodes];
KPKEntry *selectedEntry = nodes.count == 1 ? [nodes.firstObject asEntry] : nil;
if(selectedEntry) { if(selectedEntry) {
[self _copyToPasteboard:[selectedEntry.username finalValueForEntry:selectedEntry] overlayInfo:MPOverlayInfoUsername name:nil]; [self _copyToPasteboard:[selectedEntry.username finalValueForEntry:selectedEntry] overlayInfo:MPOverlayInfoUsername name:nil];
} }
} }
- (void)copyCustomAttribute:(id)sender { - (void)copyCustomAttribute:(id)sender {
KPKEntry *selectedEntry = [self currentTargetNode].asEntry; NSArray *nodes = [self currentTargetNodes];
KPKEntry *selectedEntry = nodes.count == 1 ? [nodes.firstObject asEntry] : nil;
if(selectedEntry && [selectedEntry isKindOfClass:[KPKEntry class]]) { if(selectedEntry && [selectedEntry isKindOfClass:[KPKEntry class]]) {
NSUInteger index = [sender tag]; NSUInteger index = [sender tag];
NSAssert((index >= 0) && (index < [selectedEntry.customAttributes count]), @"Index for custom field needs to be valid"); NSAssert((index >= 0) && (index < [selectedEntry.customAttributes count]), @"Index for custom field needs to be valid");
@@ -647,14 +647,16 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
} }
- (void)copyURL:(id)sender { - (void)copyURL:(id)sender {
KPKEntry *selectedEntry = [self currentTargetNode].asEntry; NSArray *nodes = [self currentTargetNodes];
KPKEntry *selectedEntry = nodes.count == 1 ? [nodes.firstObject asEntry] : nil;
if(selectedEntry) { if(selectedEntry) {
[self _copyToPasteboard:[selectedEntry.url finalValueForEntry:selectedEntry] overlayInfo:MPOverlayInfoURL name:nil]; [self _copyToPasteboard:[selectedEntry.url finalValueForEntry:selectedEntry] overlayInfo:MPOverlayInfoURL name:nil];
} }
} }
- (void)openURL:(id)sender { - (void)openURL:(id)sender {
KPKEntry *selectedEntry = [self currentTargetNode].asEntry; NSArray *nodes = [self currentTargetNodes];
KPKEntry *selectedEntry = nodes.count == 1 ? [nodes.firstObject asEntry] : nil;
NSString *expandedURL = [selectedEntry.url finalValueForEntry:selectedEntry]; NSString *expandedURL = [selectedEntry.url finalValueForEntry:selectedEntry];
if(expandedURL.length > 0) { if(expandedURL.length > 0) {
NSURL *webURL = [NSURL URLWithString:[expandedURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSURL *webURL = [NSURL URLWithString:[expandedURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
@@ -680,13 +682,11 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
} }
- (void)delete:(id)sender { - (void)delete:(id)sender {
KPKEntry *entry = [self currentTargetNode].asEntry; NSArray *entries = [self currentTargetEntries];
if(!entry) {
return;
}
MPDocument *document = self.windowController.document; MPDocument *document = self.windowController.document;
[document deleteNode:entry]; for(KPKEntry *entry in entries) {
[document deleteNode:entry];
}
} }

View File

@@ -134,21 +134,21 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
} }
#pragma mark MPTargetNodeResolving #pragma mark MPTargetNodeResolving
- (KPKGroup *)currentTargetGroup { - (NSArray<KPKGroup *> *)currentTargetGroups {
NSInteger row = self.outlineView.clickedRow; // NSInteger row = self.outlineView.clickedRow;
if( row < 0 ) { // if( row > -1 ) {
row = self.outlineView.selectedRow; // return @[ [[self.outlineView itemAtRow:row] representedObject] ];
} // }
return [[self.outlineView itemAtRow:row] representedObject]; return self.treeController.selectedObjects;
} }
- (KPKNode *)currentTargetNode { - (NSArray<KPKNode *> *)currentTargetNodes {
KPKGroup *group = [self currentTargetGroup]; NSArray *groups = [self currentTargetGroups];
if(group) { if(groups.count > 0) {
return group; return groups;
} }
MPDocument *document = self.windowController.document; MPDocument *document = self.windowController.document;
return document.selectedNodes.firstObject; return document.selectedNodes;
} }
#pragma mark Notifications #pragma mark Notifications
@@ -184,7 +184,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
} }
- (id)itemUnderMouse { - (id)itemUnderMouse {
NSPoint mouseLocation = [[self.outlineView window] mouseLocationOutsideOfEventStream]; NSPoint mouseLocation = [self.outlineView.window mouseLocationOutsideOfEventStream];
NSPoint localPoint = [self.outlineView convertPoint:mouseLocation fromView:[[self.outlineView window] contentView]]; NSPoint localPoint = [self.outlineView convertPoint:mouseLocation fromView:[[self.outlineView window] contentView]];
NSInteger row = [self.outlineView rowAtPoint:localPoint]; NSInteger row = [self.outlineView rowAtPoint:localPoint];
if(row == -1) { if(row == -1) {
@@ -278,7 +278,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
if(![document validateUserInterfaceItem:menuItem]) { if(![document validateUserInterfaceItem:menuItem]) {
return NO; return NO;
} }
KPKGroup *group = [self currentTargetNode].asGroup; KPKGroup *group = [self currentTargetNodes].firstObject.asGroup;
return group.isTrash && group.isTrashed; return group.isTrash && group.isTrashed;
} }

View File

@@ -14,8 +14,8 @@
@protocol MPTargetNodeResolving <NSObject> @protocol MPTargetNodeResolving <NSObject>
@optional @optional
- (KPKNode *)currentTargetNode; - (NSArray<KPKNode *> *)currentTargetNodes;
- (KPKGroup *)currentTargetGroup; - (NSArray<KPKGroup *> *)currentTargetGroups;
- (KPKEntry *)currentTargetEntry; - (NSArray<KPKEntry *> *)currentTargetEntries;
@end @end