123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- //
- // KMTableView.swift
- // PDF Reader Pro
- //
- // Created by tangchao on 2023/11/16.
- //
- import Cocoa
- /*
- @protocol SKTableViewDelegate <NSTableViewDelegate>
- - (NSArray *)tableView:(NSTableView *)aTableView typeSelectHelperSelectionStrings:(SKTypeSelectHelper *)aTypeSelectHelper;
- - (void)tableView:(NSTableView *)aTableView typeSelectHelper:(SKTypeSelectHelper *)aTypeSelectHelper didFailToFindMatchForSearchString:(NSString *)searchString;
- - (void)tableView:(NSTableView *)aTableView typeSelectHelper:(SKTypeSelectHelper *)aTypeSelectHelper updateSearchString:(NSString *)searchString;
- @end
- */
- @objc protocol KMBotaTableViewDelegate: NSTableViewDelegate {
- @objc optional func tableView(_ aTableView: NSTableView, deleteRowsWithIndexes rowIndexes: IndexSet)
- @objc optional func tableView(_ aTableView: NSTableView, canDeleteRowsWithIndexes rowIndexes: IndexSet) -> Bool
-
- @objc optional func tableView(_ aTableView: NSTableView, copyRowsWithIndexes rowIndexes: IndexSet)
- @objc optional func tableView(_ aTableView: NSTableView, canCopyRowsWithIndexes rowIndexes: IndexSet) -> Bool
-
- @objc optional func tableView(_ aTableView: NSTableView, pasteFromPasteboard pboard: NSPasteboard)
- @objc optional func tableView(_ aTableView: NSTableView, canPasteFromPasteboard pboard: NSPasteboard) -> Bool
-
- @objc optional func tableViewMoveLeft(_ aTableView: NSTableView)
- @objc optional func tableViewMoveRight(_ aTableView: NSTableView)
-
- @objc optional func tableView(_ aTableView: NSTableView, imageContextForRow rowIndex: Int) -> AnyObject?
- }
- class KMBotaTableView: NSTableView {
- var kmTrackingAreas: NSMutableSet?
-
- /*
- @interface SKTableView : NSTableView <SKTypeSelectDelegate> {
- SKTypeSelectHelper *typeSelectHelper;
- }
- @property (nonatomic) supportsQuickLook;
- @property (nonatomic, retain) SKTypeSelectHelper *typeSelectHelper;
- */
-
- weak var botaDelegate: KMBotaTableViewDelegate? {
- didSet {
- self._rebuildTrackingAreas()
- }
- }
-
- var hasImageToolTips: Bool {
- get {
- return self.kmTrackingAreas != nil
- }
- set {
- if self.kmTrackingAreas == nil && newValue {
- self.kmTrackingAreas = NSMutableSet()
- if self.window != nil {
- self._rebuildTrackingAreas()
- }
- } else if self.kmTrackingAreas != nil && newValue == false {
- if self.window != nil {
- self._removeTrackingAreas()
- }
- }
- }
- }
-
- override func draw(_ dirtyRect: NSRect) {
- super.draw(dirtyRect)
- // Drawing code here.
- }
-
- override func reloadData() {
- super.reloadData()
-
- self._rebuildTrackingAreas()
- // [typeSelectHelper rebuildTypeSelectSearchCache];
- }
-
- // MARK: - Tracking
-
- override func updateTrackingAreas() {
- super.updateTrackingAreas()
-
- self._rebuildTrackingAreas()
- }
-
- override func noteNumberOfRowsChanged() {
- super.noteNumberOfRowsChanged()
-
- self._rebuildTrackingAreas()
- }
-
- override func mouseEntered(with event: NSEvent) {
- if (self.kmTrackingAreas == nil) {
- return
- }
-
- // let userInfo = event.userData as? [String : Any]
- let userInfo = event.trackingArea?.userInfo as? [String : Any]
- let row = userInfo?["row"] as? Int
- if row != nil {
- let context = self.botaDelegate?.tableView?(self, imageContextForRow: row!)
- if context is KMImageToolTipContext {
- KMImageToolTipWindow.shared.showForImageContext(context as! KMImageToolTipContext, at: .zero)
- }
- }
- }
-
- override func mouseExited(with event: NSEvent) {
- if (self.kmTrackingAreas == nil) {
- return
- }
-
- let userInfo = event.userData as? [String : Any]
- let row = userInfo?["row"] as? Int
- if row != nil {
- KMImageToolTipWindow.shared.fadeOut()
- }
- }
-
- 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 moveLeft(_ sender: AnyObject?) {
- self.botaDelegate?.tableViewMoveLeft?(self)
- }
- func moveRight(_ sender: AnyObject?) {
- self.botaDelegate?.tableViewMoveRight?(self)
- }
-
- func canDelete() -> Bool {
- let indexes = self.selectedRowIndexes
- if indexes.isEmpty {
- return false
- }
-
- return self.botaDelegate?.tableView?(self, canDeleteRowsWithIndexes: indexes) ?? false
- }
-
- @objc func delete(_ sender: AnyObject?) {
- if self.canDelete() {
- self.botaDelegate?.tableView?(self, deleteRowsWithIndexes: self.selectedRowIndexes)
- }
- }
-
- func canCopy() -> Bool {
- let indexes = self.selectedRowIndexes
- if indexes.isEmpty {
- return false
- }
-
- return self.botaDelegate?.tableView?(self, canCopyRowsWithIndexes: indexes) ?? false
- }
-
- @objc func copy(_ sender: AnyObject?) {
- if self.canCopy() {
- self.botaDelegate?.tableView?(self, copyRowsWithIndexes: self.selectedRowIndexes)
- }
- }
-
- func canPaste() -> Bool {
- return self.botaDelegate?.tableView?(self, canPasteFromPasteboard: NSPasteboard.general) ?? false
- }
-
- @objc func paste(_ sender: AnyObject?) {
- if self.canPaste() {
- self.botaDelegate?.tableView?(self, pasteFromPasteboard: NSPasteboard.general)
- }
- }
-
- override func keyDown(with event: NSEvent) {
- // let eventChar = event.PDFListViewFirstCharacter()
- // let modifierFlags = event.deviceIndependen
- // NSUInteger modifierFlags = [theEvent deviceIndependentModifierFlags];
- //
- // 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 == NSDeleteCharacter || eventChar == NSDeleteFunctionKey) && modifierFlags == 0 && [self canDelete]) {
- // [self delete:self];
- // } else if ((eventChar == SKSpaceCharacter) && 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 == SKSpaceCharacter) && 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 == NSLeftArrowFunctionKey && modifierFlags == 0) {
- // [self moveLeft:nil];
- // } else if (eventChar == NSRightArrowFunctionKey && modifierFlags == 0) {
- // [self moveRight:nil];
- // } else if ([typeSelectHelper handleEvent:theEvent] == NO) {
- // [super keyDown:theEvent];
- // }
-
- super.keyDown(with: event)
- }
-
- 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))
- }
- }
-
- /*
- - (void)setTypeSelectHelper:(SKTypeSelectHelper *)newTypeSelectHelper {
- if (typeSelectHelper != newTypeSelectHelper) {
- if ([typeSelectHelper delegate] == self)
- [typeSelectHelper setDelegate:nil];
- [typeSelectHelper release];
- typeSelectHelper = [newTypeSelectHelper retain];
- [typeSelectHelper setDelegate:self];
- }
- }
- - (NSImage *)dragImageForRowsWithIndexes:(NSIndexSet *)dragRows tableColumns:(NSArray *)tableColumns event:(NSEvent *)dragEvent offset:(NSPointPointer)dragImageOffset{
- return [super dragImageForRowsWithIndexes:dragRows tableColumns:[[self tableColumns] subarrayWithRange:NSMakeRange(0, 1)] event:dragEvent offset:dragImageOffset];
- }
- #pragma mark SKTypeSelectHelper datasource protocol
- - (NSArray *)typeSelectHelperSelectionStrings:(SKTypeSelectHelper *)aTypeSelectHelper {
- if ([[self delegate] respondsToSelector:@selector(tableView:typeSelectHelperSelectionStrings:)])
- return [[self delegate] tableView: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(tableView:typeSelectHelper:didFailToFindMatchForSearchString:)])
- [[self delegate] tableView:self typeSelectHelper:aTypeSelectHelper didFailToFindMatchForSearchString:searchString];
- }
- - (void)typeSelectHelper:(SKTypeSelectHelper *)aTypeSelectHelper updateSearchString:(NSString *)searchString {
- if ([[self delegate] respondsToSelector:@selector(tableView:typeSelectHelper:updateSearchString:)])
- [[self delegate] tableView:self typeSelectHelper:aTypeSelectHelper updateSearchString:searchString];
- }
- */
-
-
- }
- // MARK: - Private Methods
- extension KMBotaTableView {
- private func _rebuildTrackingAreas() {
- if self.kmTrackingAreas == nil {
- return
- }
-
- let context = self.botaDelegate?.tableView?(self, imageContextForRow: 0)
- if context == nil {
- return
- }
-
- self._removeTrackingAreas()
- if self.window != nil {
- let visibleRect = self.visibleRect
- let rowRange = self.rows(in: visibleRect)
- var row: UInt = 0
- for i in rowRange.location ..< NSMaxRange(rowRange) {
- self._addTrackingAreaForRow(Int(i))
- }
- }
- }
-
- private func _removeTrackingAreas() {
- if (self.kmTrackingAreas == nil) {
- return
- }
-
- for area in self.kmTrackingAreas! {
- self.removeTrackingArea(area as! NSTrackingArea)
- }
- self.kmTrackingAreas?.removeAllObjects()
- }
-
- private func _addTrackingAreaForRow(_ row: Int) {
- if (self.kmTrackingAreas == nil) {
- return
- }
- let userInfo = ["row" : row]
- let area = NSTrackingArea(rect: self.rect(ofRow: row), options: [.mouseEnteredAndExited, .activeInActiveApp], owner: self, userInfo: userInfo)
- self.addTrackingArea(area)
- self.kmTrackingAreas?.add(area)
- }
-
- /*
- */
-
- }
- extension KMBotaTableView: NSMenuItemValidation {
- 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 ([[SKTableView superclass] instancesRespondToSelector:@selector(validateMenuItem:)])
- // return [super validateMenuItem:menuItem];
-
- return true
- }
- }
|