123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- //
- // SKOutlineView.m
- // Skim
- //
- // Created by Christiaan Hofman on 8/22/07.
- /*
- This software is Copyright (c) 2007-2018
- Christiaan Hofman. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- - Neither the name of Christiaan Hofman nor the names of any
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #import "SKOutlineView.h"
- #import <Quartz/Quartz.h>
- //#import "SKTypeSelectHelper.h"
- //#import "NSEvent_SKExtensions.h"
- //#import "NSFont_SKExtensions.h"
- @implementation SKOutlineView
- - (void)dealloc {
- // [typeSelectHelper setDelegate:nil];
- // SKDESTROY(typeSelectHelper);
- // [super dealloc];
- }
- - (NSArray *)itemsAtRowIndexes:(NSIndexSet *)indexes {
- NSMutableArray *items = [NSMutableArray array];
- [indexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
- [items addObject:[self itemAtRow:idx]];
- }];
- return items;
- }
- - (NSArray *)selectedItems {
- return [self itemsAtRowIndexes:[self selectedRowIndexes]];
- }
- //- (void)setTypeSelectHelper:(SKTypeSelectHelper *)newTypeSelectHelper {
- // if (typeSelectHelper != newTypeSelectHelper) {
- // if ([typeSelectHelper delegate] == self)
- // [typeSelectHelper setDelegate:nil];
- // [typeSelectHelper release];
- // typeSelectHelper = [newTypeSelectHelper retain];
- // [typeSelectHelper setDelegate:self];
- // }
- //}
- - (void)expandItem:(id)item expandChildren:(BOOL)collapseChildren {
- [super expandItem:item expandChildren:collapseChildren];
- // [typeSelectHelper rebuildTypeSelectSearchCache];
- }
- - (void)collapseItem:(id)item collapseChildren:(BOOL)collapseChildren {
- [super collapseItem:item collapseChildren:collapseChildren];
- // [typeSelectHelper rebuildTypeSelectSearchCache];
- }
- - (void)reloadData{
- [super reloadData];
- // [typeSelectHelper rebuildTypeSelectSearchCache];
- }
- - (void)keyDown:(NSEvent *)theEvent {
- NSString *characters = [theEvent charactersIgnoringModifiers];
- unichar eventChar = [characters length] > 0 ? [characters characterAtIndex:0] : 0;
-
- NSUInteger modifierFlags = [theEvent modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
-
- if ((eventChar == NSNewlineCharacter || eventChar == NSEnterCharacter || eventChar == NSCarriageReturnCharacter) && modifierFlags == 0) {
- if ([self doubleAction] == NULL || [self sendAction:[self doubleAction] to:[self target]] == NO)
- NSBeep();
- } else if ((eventChar == NSTabCharacter) && modifierFlags == 0) {
- if (supportsQuickLook == NO)
- [[self enclosingScrollView] pageDown:nil];
- else if ([QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible])
- [[QLPreviewPanel sharedPreviewPanel] orderOut:nil];
- else
- [[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];
- } else if ((eventChar == NSTabCharacter) && modifierFlags == NSShiftKeyMask) {
- if (supportsQuickLook == NO)
- [[self enclosingScrollView] pageUp:nil];
- } else if (eventChar == NSHomeFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) {
- [self scrollToBeginningOfDocument:nil];
- } else if (eventChar == NSEndFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) {
- [self scrollToEndOfDocument:nil];
- } else if ((eventChar == NSDeleteCharacter || eventChar == NSDeleteFunctionKey) && modifierFlags == 0 && [self canDelete]) {
- [self delete:self];
- }
- // else if ([typeSelectHelper handleEvent:theEvent] == NO) {
- // [super keyDown:theEvent];
- // }
- }
- - (void)scrollToBeginningOfDocument:(id)sender {
- if ([self numberOfRows])
- [self scrollRowToVisible:0];
- }
- - (void)scrollToEndOfDocument:(id)sender {
- if ([self numberOfRows])
- [self scrollRowToVisible:[self numberOfRows] - 1];
- }
- - (BOOL)canDelete {
- NSArray *items = [self selectedItems];
- if ([items count] && [[self delegate] respondsToSelector:@selector(outlineView:deleteItems:)]) {
- if ([[self delegate] respondsToSelector:@selector(outlineView:canDeleteItems:)])
- return [[self delegate] outlineView:self canDeleteItems:items];
- else
- return YES;
- }
- return NO;
- }
- - (void)delete:(id)sender {
- if ([self canDelete])
- [[self delegate] outlineView:self deleteItems:[self selectedItems]];
- else
- NSBeep();
- }
- - (BOOL)canCopy {
- NSArray *items = [self selectedItems];
- if ([items count] && [[self delegate] respondsToSelector:@selector(outlineView:copyItems:)]) {
- if ([[self delegate] respondsToSelector:@selector(outlineView:canCopyItems:)])
- return [[self delegate] outlineView:self canCopyItems:items];
- else
- return YES;
- }
- return NO;
- }
- - (void)copy:(id)sender {
- if ([self canCopy])
- [[self delegate] outlineView:self copyItems:[self selectedItems]];
- else
- NSBeep();
- }
- - (BOOL)canPaste {
- if ([[self delegate] respondsToSelector:@selector(outlineView:pasteFromPasteboard:)]) {
- if ([[self delegate] respondsToSelector:@selector(outlineView:canPasteFromPasteboard:)])
- return [[self delegate] outlineView:self canPasteFromPasteboard:[NSPasteboard generalPasteboard]];
- else
- return YES;
- }
- return NO;
- }
- - (void)paste:(id)sender {
- if ([self canPaste])
- [[self delegate] outlineView:self pasteFromPasteboard:[NSPasteboard generalPasteboard]];
- else
- NSBeep();
- }
- - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
- if ([menuItem action] == @selector(delete:))
- return [self canDelete];
- else if ([menuItem action] == @selector(copy:))
- return [self canCopy];
- else if ([menuItem action] == @selector(paste:))
- return [self canPaste];
- else if ([menuItem action] == @selector(selectAll:))
- return [self allowsMultipleSelection];
- else if ([menuItem action] == @selector(deselectAll:))
- return [self allowsEmptySelection];
- else if ([[SKOutlineView superclass] instancesRespondToSelector:@selector(validateMenuItem:)])
- return [super validateMenuItem:menuItem];
- return YES;
- }
- - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation {
- if ([[SKOutlineView superclass] instancesRespondToSelector:_cmd])
- [super draggedImage:anImage endedAt:aPoint operation:operation];
- if ([[self dataSource] respondsToSelector:@selector(outlineView:dragEndedWithOperation:)])
- [[self dataSource] outlineView:self dragEndedWithOperation:operation];
- }
- - (NSFont *)font {
- for (NSTableColumn *tc in [self tableColumns]) {
- NSCell *cell = [tc dataCell];
- if ([cell type] == NSTextCellType)
- return [cell font];
- }
- return nil;
- }
- - (void)setFont:(NSFont *)font {
- for (NSTableColumn *tc in [self tableColumns]) {
- NSCell *cell = [tc dataCell];
- if ([cell type] == NSTextCellType)
- [cell setFont:font];
- }
-
- CGFloat rowHeight = [self defaultViewLineHeight:font];
- if ([self selectionHighlightStyle] == NSTableViewSelectionHighlightStyleSourceList)
- rowHeight += 2.0;
- [self setRowHeight:rowHeight];
- [self noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [self numberOfRows])]];
- }
- - (CGFloat)defaultViewLineHeight:(NSFont *)font {
- static NSLayoutManager *layoutManager = nil;
- if (layoutManager == nil) {
- layoutManager = [[NSLayoutManager alloc] init];
- [layoutManager setTypesetterBehavior:NSTypesetterBehavior_10_2_WithCompatibility];
- }
- return [layoutManager defaultLineHeightForFont:font];
- }
- #pragma mark SKTypeSelectHelper datasource protocol
- //- (NSArray *)typeSelectHelperSelectionStrings:(SKTypeSelectHelper *)aTypeSelectHelper {
- // if ([[self delegate] respondsToSelector:@selector(outlineView:typeSelectHelperSelectionStrings:)])
- // return [[self delegate] outlineView:self typeSelectHelperSelectionStrings:aTypeSelectHelper];
- // return nil;
- //}
- //- (NSUInteger)typeSelectHelperCurrentlySelectedIndex:(SKTypeSelectHelper *)aTypeSelectHelper {
- // return [[self selectedRowIndexes] lastIndex];
- //}
- //- (void)typeSelectHelper:(SKTypeSelectHelper *)aTypeSelectHelper selectItemAtIndex:(NSUInteger)itemIndex {
- // [self selectRowIndexes:[NSIndexSet indexSetWithIndex:itemIndex] byExtendingSelection:NO];
- // [self scrollRowToVisible:itemIndex];
- //}
- //
- //- (void)typeSelectHelper:(SKTypeSelectHelper *)aTypeSelectHelper didFailToFindMatchForSearchString:(NSString *)searchString {
- // if ([[self delegate] respondsToSelector:@selector(outlineView:typeSelectHelper:didFailToFindMatchForSearchString:)])
- // [[self delegate] outlineView:self typeSelectHelper:aTypeSelectHelper didFailToFindMatchForSearchString:searchString];
- //}
- //
- //- (void)typeSelectHelper:(SKTypeSelectHelper *)aTypeSelectHelper updateSearchString:(NSString *)searchString {
- // if ([[self delegate] respondsToSelector:@selector(outlineView:typeSelectHelper:updateSearchString:)])
- // [[self delegate] outlineView:self typeSelectHelper:aTypeSelectHelper updateSearchString:searchString];
- //}
- - (id <SKOutlineViewDelegate>)delegate { return (id <SKOutlineViewDelegate>)[super delegate]; }
- - (void)setDelegate:(id <SKOutlineViewDelegate>)newDelegate { [super setDelegate:newDelegate]; }
- - (id <SKOutlineViewDataSource>)dataSource { return (id <SKOutlineViewDataSource>)[super dataSource]; }
- - (void)setDataSource:(id <SKOutlineViewDataSource>)newDataSource { [super setDataSource:newDataSource]; }
- @end
|