123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- //
- // KMCustomOutlineView.swift
- // PDF Reader Pro
- //
- // Created by tangchao on 2023/11/17.
- //
- import Cocoa
- @objc protocol KMCustomOutlineViewDelegate: NSOutlineViewDelegate {
- @objc optional func outlineView(_ anOutlineView: NSOutlineView, deleteItems items: [Any])
- @objc optional func outlineView(_ anOutlineView: NSOutlineView, canDeleteItems items: [Any]) -> Bool
-
- @objc optional func outlineView(_ anOutlineView: NSOutlineView, copyItems items: [Any])
- @objc optional func outlineView(_ anOutlineView: NSOutlineView, canCopyItems items: [Any]) -> Bool
-
- @objc optional func outlineView(_ anOutlineView: NSOutlineView, pasteFromPasteboard pboard: NSPasteboard)
- @objc optional func outlineView(_ anOutlineView: NSOutlineView, canPasteFromPasteboard pboard: NSPasteboard) -> Bool
-
- @objc optional func outlineView(_ anOutlineView: NSOutlineView, typeSelectHelperSelectionStrings aTypeSelectHelper: SKTypeSelectHelper) -> NSArray
- @objc optional func outlineView(_ anOutlineView: NSOutlineView, typeSelectHelper aTypeSelectHelper: SKTypeSelectHelper, didFailToFindMatchForSearchString searchString: String)
- @objc optional func outlineView(_ anOutlineView: NSOutlineView, typeSelectHelper aTypeSelectHelper: SKTypeSelectHelper, updateSearchString searchString: String)
- }
- @objc protocol KMCustomOutlineViewDataSource: NSOutlineViewDataSource {
- @objc optional func outlineView(_ anOutlineView: NSOutlineView, dragEndedWithOperation dragEndedO: NSDragOperation)
- }
- open class KMCustomOutlineView: NSOutlineView {
- var supportsQuickLook = false
- private var _typeSelectHelper: SKTypeSelectHelper?
- var typeSelectHelper: SKTypeSelectHelper? {
- get {
- return self._typeSelectHelper
- }
- set {
- if self._typeSelectHelper != newValue {
- if self.isEqual(to: self._typeSelectHelper?.delegate) {
- self._typeSelectHelper?.delegate = nil
- }
- self._typeSelectHelper = newValue
- self._typeSelectHelper?.delegate = self
- }
- }
- }
-
- weak var botaDelegate: KMCustomOutlineViewDelegate?
- weak var botaDataSource: KMCustomOutlineViewDataSource?
-
- open override func draw(_ dirtyRect: NSRect) {
- super.draw(dirtyRect)
- // Drawing code here.
- }
-
- open override func expandItem(_ item: Any?, expandChildren: Bool) {
- super.expandItem(item, expandChildren: expandChildren)
-
- self.typeSelectHelper?.rebuildTypeSelectSearchCache()
- }
-
- open override func collapseItem(_ item: Any?, collapseChildren: Bool) {
- super.collapseItem(item, collapseChildren: collapseChildren)
-
- self.typeSelectHelper?.rebuildTypeSelectSearchCache()
- }
-
- open override func reloadData() {
- super.reloadData()
-
- self.typeSelectHelper?.rebuildTypeSelectSearchCache()
- }
-
- open override func keyDown(with event: NSEvent) {
- let eventChar = event.firstCharacter()
- let modifierFlags = event.deviceIndependentModifierFlags()
- if ((eventChar == NSNewlineCharacter || eventChar == NSEnterCharacter || eventChar == NSCarriageReturnCharacter) && modifierFlags == 0) {
- if self.doubleValue == nil || self.sendAction(self.doubleAction, to: self.target) == false {
- NSSound.beep()
- }
- } else if ((eventChar == SKSpaceCharacter) && modifierFlags == 0) {
- if self.supportsQuickLook == false {
- self.enclosingScrollView?.pageDown(nil)
- } else if QLPreviewPanel.sharedPreviewPanelExists() && QLPreviewPanel.shared().isVisible {
- QLPreviewPanel.shared().orderOut(nil)
- } else {
- QLPreviewPanel.shared().makeKeyAndOrderFront(nil)
- }
- } else if ((eventChar == SKSpaceCharacter) && modifierFlags == NSEvent.ModifierFlags.shift.rawValue) {
- if self.supportsQuickLook == false {
- 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 let data = self.typeSelectHelper?.handleEvent(event), data == false {
- super.keyDown(with: event)
- }
- }
- /*
- - (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];
- }
-
- */
-
- open override var font: NSFont? {
- get {
- for tc in self.tableColumns {
- if let cell = tc.dataCell as? NSCell {
- if cell.type == .textCellType {
- return cell.font
- }
- }
- }
- return nil
- }
- set {
- for tc in self.tableColumns {
- if let cell = tc.dataCell as? NSCell {
- if cell.type == .textCellType {
- cell.font = newValue
- }
- }
- }
-
- var rowHeight = font?.defaultViewLineHeight() ?? 34
- if self.selectionHighlightStyle == .sourceList {
- rowHeight += 2.0
- }
- self.rowHeight = rowHeight
- self.noteHeightOfRows(withIndexesChanged: IndexSet(0..<self.numberOfRows))
- }
- }
-
- func scrollToBeginningOfDocument(_ sender: AnyObject?) {
- if self.numberOfRows > 0 {
- self.scrollRowToVisible(0)
- }
- }
- func scrollToEndOfDocument(_ sender: AnyObject?) {
- if self.numberOfRows > 0 {
- self.scrollRowToVisible(self.numberOfRows-1)
- }
- }
-
- func canPaste() -> Bool {
- return self.botaDelegate?.outlineView?(self, canPasteFromPasteboard: .general) ?? true
- }
- @objc func paste(_ sender: AnyObject?) {
- if self.canPaste() {
- self.botaDelegate?.outlineView?(self, pasteFromPasteboard: .general)
- }
- }
-
- func canCopy() -> Bool {
- let items = self.selectedItems()
- if items.count > 0 {
- return self.botaDelegate?.outlineView?(self, canCopyItems: items) ?? true
- }
- return false
- }
- @objc func copy(_ sender: AnyObject?) {
- if self.canCopy() {
- self.botaDelegate?.outlineView?(self, copyItems: self.selectedItems())
- }
- }
-
- open func canDelete() -> Bool {
- let items = self.selectedItems()
- if items.count > 0 {
- return self.botaDelegate?.outlineView?(self, canDeleteItems: items) ?? true
- }
- return false
- }
-
- @objc func delete(_ sender: Any) {
- if self.canDelete() {
- self.botaDelegate?.outlineView?(self, deleteItems: self.selectedItems())
- }
- }
-
- func selectedItems() -> [Any] {
- return self.itemsAtRowIndexes(self.selectedRowIndexes)
- }
-
- func itemsAtRowIndexes(_ indexes: IndexSet) -> [Any] {
- var items: [Any] = []
- for i in indexes {
- if let item = self.item(atRow: i) {
- items.append(item)
- }
- }
- return items
- }
- }
- extension KMCustomOutlineView: NSMenuItemValidation {
- public func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
- if (menuItem.action == #selector(delete)) {
- return self.canDelete()
- } else if (menuItem.action == KMSelectorCopy) {
- 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 true
- }
- }
- extension KMCustomOutlineView: SKTypeSelectHelperDelegate {
- func typeSelectHelperSelectionStrings(_ typeSelectHelper: SKTypeSelectHelper) -> NSArray {
- return self.botaDelegate?.outlineView?(self, typeSelectHelperSelectionStrings: typeSelectHelper) ?? NSArray()
- }
-
- func typeSelectHelperCurrentlySelectedIndex(_ typeSelectHelper: SKTypeSelectHelper) -> Int {
- return self.selectedRowIndexes.last ?? NSNotFound
- }
-
- func typeSelectHelper(_ typeSelectHelper: SKTypeSelectHelper, selectItemAtIndex itemIndex: Int) {
- self.selectRowIndexes(NSIndexSet(index: itemIndex) as IndexSet, byExtendingSelection: false)
- self.scrollRowToVisible(itemIndex)
- }
-
- func typeSelectHelper(_ typeSelectHelper: SKTypeSelectHelper, didFailToFindMatchForSearchString searchString: String) {
- self.botaDelegate?.outlineView?(self, typeSelectHelper: typeSelectHelper, didFailToFindMatchForSearchString: searchString)
- }
-
- func typeSelectHelper(_ typeSelectHelper: SKTypeSelectHelper, updateSearchString searchString: String) {
- self.botaDelegate?.outlineView?(self, typeSelectHelper: typeSelectHelper, updateSearchString: searchString)
- }
- }
|