// // KMLeftSideViewController.swift // PDF Master // // Created by lxy on 2022/10/10. // import Cocoa @objc protocol KMLeftSideViewControllerDelegate { @objc optional func controlStateChange(_ obj: KMLeftSideViewController,show:Bool) @objc optional func enterEditMode(_ obj: KMLeftSideViewController, _ pages: [Int]) @objc optional func searchAction(searchString:String, isCase:Bool) @objc optional func controller(_ controller: KMLeftSideViewController, dispayDidChange dispay: KMPDFDisplayType) @objc optional func controller(controller: KMLeftSideViewController, itemClick item: Any?, itemKey: KMItemKey, params: Any?) @objc optional func controller(controller: KMLeftSideViewController, bookMarkDidChange bookMarks: [KMBookMarkItem]) @objc optional func controller(controller: KMLeftSideViewController, rotateType: KMRotateType) } class KMLeftSideViewController: KMSideViewController { // @IBOutlet weak var leftTableview: NSTableView! // @IBOutlet weak var leftBox: NSBox! lazy var annotationViewController : KMAnnotationViewController = { let annotationViewController = KMAnnotationViewController() return annotationViewController }() lazy var bookViewController : KMBookMarkViewController = { let bookViewController = KMBookMarkViewController() bookViewController.bookMarkDidChange = { [unowned self] (controller, bookMarks) in self.delegate?.controller?(controller: self, bookMarkDidChange: bookMarks) } return bookViewController }() // lazy var signatureViewController : KMSignatureViewController = { // let signatureViewController = KMSignatureViewController() // return signatureViewController // }() lazy var panelSetViewController : KMPDFViewPanelSetViewController = { let panelSetViewController = KMPDFViewPanelSetViewController() // panelSetViewController.delegate = self return panelSetViewController }() var dataSource : [KMLeftMethodMode] = [KMLeftMethodMode]() var type : KMLeftMethodMode = KMLeftMethodMode() var isShowPanel : Bool = false var norImage : [String] = [] var selectImage : [String] = [] var mainVC: KMMainViewController? var selectPages: [Int]? open weak var delegate: KMLeftSideViewControllerDelegate? deinit { KMPrint("KMLeftSideViewController deinit.") NotificationCenter.default.removeObserver(self) } override var nibName: NSNib.Name? { return "LeftSideView" } convenience init(type : KMLeftMethodMode) { self.init() self.type = type } override func viewDidLoad() { super.viewDidLoad() // self.leftBox.backgroundColor(NSColor.km_init(hex: "#F7F8FA")) // self.leftTableview.backgroundColor(NSColor.km_init(hex: "#F7F8FA")) // self.leftTableview.border(NSColor.km_init(hex: "#EDEEF0"),1 , 0) // self.addMenuTitle() // self.refreshShowMethod() DistributedNotificationCenter.default().addObserver(self, selector: #selector(_themeChanged), name: NSApplication.interfaceThemeChangedNotification, object: nil) } func showPanelView(show: Bool) { self.isShowPanel = show if show { // self.panelSetViewController.listView = self.listView // self.panelSetViewController.view.frame = self.view.frame // self.view.addSubview(self.panelSetViewController.view) // self.panelSetViewController.reloadListViewModel() // self.panelSetViewController.view.autoresizingMask = [.height] } else { // self.contentBox.isHidden = false // self.panelSetViewController.view.removeFromSuperview() // if self.type.methodType == .None { // self.delegate?.controlStateChange?(self, show: false) // } } } func refreshMethodType(methodType: BotaType) { if (self.isShowPanel) { self.showPanelView(show: false) return } let newType = KMLeftMethodMode() var show = true if self.type.methodType != methodType { newType.methodType = methodType } if self.type.methodType == methodType { show = false } self.type = newType; // self.refreshShowMethod() self.delegate?.controlStateChange?(self,show:show) } // // private func updateViewButtonState() { // switch self.type.methodType { // case .None: do { //// self.contentBox.contentView = NSView() // self.delegate?.controlStateChange?(self,show:false) // } // break // case .Thumbnail: do { // self.thumbnailViewController.listView = self.listView // self.thumbnailViewController.delegate = self //// self.contentBox.contentView = self.thumbnailViewController.view //// self.thumbnailViewController.reloadData() // } // break // case .Outline: do { // } // break // case .BookMark: do { // self.bookViewController.listView = self.listView //// self.contentBox.contentView = self.bookViewController.view // self.bookViewController.reloadData() // } // break // case .Annotation: do { // self.annotationViewController.listView = self.listView //// self.contentBox.contentView = self.annotationViewController.view //// self.annotationViewController.reloadData() // } // break // break // case .Signature: do { // self.signatureViewController.listView = self.listView //// self.contentBox.contentView = self.signatureViewController.view // self.signatureViewController.reloadData() // } // break // } // } // func refreshShowMethod() { // self.dataSource = [KMLeftMethodMode]() // norImage = [] // selectImage = [] // if KMBOTAManagerClass.shard.getMethodShow(key: thumbnailMethodKey) { // let mode = KMLeftMethodMode() // mode.methodName = thumbnailMethodKey // mode.methodType = .Thumbnail // self.dataSource.insert(mode, at: self.dataSource.count) // norImage.append("KMImageNameSidebarThumbailNor") // selectImage.append("KMImageNameSidebarThumbailSelect") // } // if KMBOTAManagerClass.shard.getMethodShow(key: outlineMethodKey) { // let mode = KMLeftMethodMode() // mode.methodName = outlineMethodKey // mode.methodType = .Outline // self.dataSource.insert(mode, at: self.dataSource.count) // norImage.append("KMImageNameSidebarOutlineNor") // selectImage.append("KMImageNameSidebarOutlineSelect") // } // if KMBOTAManagerClass.shard.getMethodShow(key: bookMarkMethodKey) { // let mode = KMLeftMethodMode() // mode.methodName = bookMarkMethodKey // mode.methodType = .BookMark // self.dataSource.insert(mode, at: self.dataSource.count) // norImage.append("KMImageNameSidebarBookMarkNor") // selectImage.append("KMImageNameSidebarBookMarkSelect") // } // if KMBOTAManagerClass.shard.getMethodShow(key: anntationMethodKey) { // let mode = KMLeftMethodMode() // mode.methodName = anntationMethodKey // mode.methodType = .Annotation // self.dataSource.insert(mode, at: self.dataSource.count) // norImage.append("KMImageNameSidebarAnnotationNor") // selectImage.append("KMImageNameSidebarAnnotationSelect") // } // if KMBOTAManagerClass.shard.getMethodShow(key: searchMethodKey) { // let mode = KMLeftMethodMode() // mode.methodName = searchMethodKey // mode.methodType = .Search // self.dataSource.insert(mode, at: self.dataSource.count) // norImage.append("KMImageNameSidebarSearchNor") // selectImage.append("KMImageNameSidebarSearchSelect") // } //// if KMBOTAManagerClass.shard.getMethodShow(key: formMethodKey) { //// let mode = KMLeftMethodMode() //// mode.methodName = formMethodKey //// mode.methodType = .From //// self.dataSource.insert(mode, at: self.dataSource.count) //// } //// if KMBOTAManagerClass.shard.getMethodShow(key: signatureMethodKey) { //// let mode = KMLeftMethodMode() //// mode.methodName = signatureMethodKey //// mode.methodType = .Signature //// self.dataSource.insert(mode, at: self.dataSource.count) //// } // var isConstant = false // for source in dataSource { // if self.type.methodType == source.methodType { // isConstant = true // } // } // if(!isConstant) { // self.type = KMLeftMethodMode() // } //// self.leftTableview.reloadData() // var typeIndex = -1 // for (index,value) in self.dataSource.enumerated() { // if value.methodType == self.type.methodType { // typeIndex = index // } // } // //// self.leftTableview.selectRowIndexes([typeIndex], byExtendingSelection: true) // if self.dataSource.count > 0 && typeIndex >= 0 { // self.type = self.dataSource[typeIndex] // } // self.updateViewButtonState() // // } // //MARK: menu // private func addMenuTitle() { // let menus : NSMenu = NSMenu(title: "") // // let addItem = self.menuItemWithTitle(title: NSLocalizedString("Thumbnails", comment: ""),type:thumbnailMethodKey,action: #selector(renameBookAction),tag: 1) // let outlineItem = self.menuItemWithTitle(title: NSLocalizedString("Outline", comment: ""),type:outlineMethodKey,action: #selector(renameBookAction),tag: 2) // let bookItem = self.menuItemWithTitle(title: NSLocalizedString("Bookmarks", comment: ""), type:bookMarkMethodKey,action: #selector(renameBookAction),tag: 3) // let annationItem = self.menuItemWithTitle(title: NSLocalizedString("Annotations", comment: ""), type:anntationMethodKey,action: #selector(renameBookAction),tag: 4) // let searchItem = self.menuItemWithTitle(title: NSLocalizedString("Search", comment: ""), type:searchMethodKey,action: #selector(renameBookAction),tag: 5) //// let formItem = self.menuItemWithTitle(title: NSLocalizedString("域", comment: ""), type:formMethodKey,action: #selector(renameBookAction),tag: 6) //// let signatureItem = self.menuItemWithTitle(title: NSLocalizedString("签名", comment: ""), type:signatureMethodKey,action: #selector(renameBookAction),tag: 7) // // menus.addItem(addItem) // menus.addItem(outlineItem) // menus.addItem(bookItem) // menus.addItem(annationItem) // menus.addItem(searchItem) //// menus.addItem(formItem) //// menus.addItem(signatureItem) //// self.leftTableview.menu = menus // } // func menuItemWithTitle(title:String,type:String,action:Selector?,tag:Int) -> NSMenuItem { // let menuItem = NSMenuItem.init(title: title as String, action: action, keyEquivalent: "") // menuItem.target = self // menuItem.tag = tag // if KMBOTAManagerClass.shard.getMethodShow(key: type) { // menuItem.state = NSControl.StateValue.on // } else { // menuItem.state = NSControl.StateValue.off // } // return menuItem // } // @objc func renameBookAction(menuItem:NSMenuItem) { // var show = true // if menuItem.state == NSControl.StateValue.on { // menuItem.state = NSControl.StateValue.off // show = false // } else { // menuItem.state = NSControl.StateValue.on // show = true // } // switch menuItem.tag { // case 1: do { // KMBOTAManagerClass.shard.setLeftMethod(show: show, key: thumbnailMethodKey) // } // case 2: do { // KMBOTAManagerClass.shard.setLeftMethod(show: show, key: outlineMethodKey) // } // case 3: do { // KMBOTAManagerClass.shard.setLeftMethod(show: show, key: bookMarkMethodKey) // } // case 4: do { // KMBOTAManagerClass.shard.setLeftMethod(show: show, key: anntationMethodKey) // } // case 5: do { // KMBOTAManagerClass.shard.setLeftMethod(show: show, key: searchMethodKey) // } // case 6: do { // KMBOTAManagerClass.shard.setLeftMethod(show: show, key: formMethodKey) // } // case 7: do { // KMBOTAManagerClass.shard.setLeftMethod(show: show, key: signatureMethodKey) // } // break // default: // break // } // self.refreshShowMethod() // } // MARK: - New /* typedef NS_ENUM(NSInteger, KMNoteSortType) { KMNoteSortType_None = 0, KMNoteSortType_Time, KMNoteSortType_Page, }; NSArrayController *thumbnailArrayController; NSArrayController *findArrayController; NSArrayController *groupedFindArrayController; } @property (nonatomic, assign) BOOL isAscendSort; @property (nonatomic, assign) KMNoteSortType noteSortType; @property (nonatomic, retain) NSView *filterButtonLayer; @property (nonatomic, retain) KMButtonLayer *moreButtonLayer; - (void)applySearchTableHeader:(NSString *)message; - (void)displayFindState; */ // @property (nonatomic, retain) IBOutlet NSArrayController *thumbnailArrayController, *findArrayController, *groupedFindArrayController; @IBOutlet var segmentedControl: KMSegmentedControl! @IBOutlet var thumbnailTableView: KMThumbnailTableView! @IBOutlet var tocOutlineView: KMTocOutlineView! @IBOutlet var noteOutlineView: KMNoteOutlineView! @IBOutlet var findTableView: KMBotaTableView! @IBOutlet var groupedFindTableView: KMBotaTableView! @IBOutlet var snapshotTableView: KMBotaTableView! @IBOutlet weak var leftListView: NSView! @IBOutlet var searchViewController: KMBotaSearchViewController! @IBOutlet weak var toolButtonBox: NSBox! @IBOutlet weak var toolButtonBoxLayoutConstraint: NSLayoutConstraint! @IBOutlet weak var snapshotNormalView: NSView! @IBOutlet weak var snapshotLabel: NSTextField! @IBOutlet weak var snapshotNormalMoreButton: NSButton! @IBOutlet weak var snapshotNormalSearchButton: NSButton! @IBOutlet weak var snapshotNormalZoomOutButton: NSButton! @IBOutlet weak var snapshotNormalZoomInButton: NSButton! @IBOutlet weak var snapshotSearchZoomOutButton: NSButton! @IBOutlet weak var snapshotSearchZoomInButton: NSButton! @IBOutlet weak var snapshotSearchField: KMLeftSideViewSearchField! @IBOutlet weak var snapshotDoneButton: NSButton! @IBOutlet weak var outlineView: NSView! @IBOutlet weak var outlineMoreButton: NSButton! @IBOutlet weak var outlineAddButton: NSButton! @IBOutlet weak var outlineSearchButton: NSButton! @IBOutlet weak var outlineLabel: NSTextField! @IBOutlet weak var outlineSearchField: KMLeftSideViewSearchField! @IBOutlet weak var outlineDoneButton: NSButton! @IBOutlet weak var noteView: NSView! @IBOutlet weak var noteMoreButton: NSButton! @IBOutlet weak var noteFilterButton: NSButton! @IBOutlet weak var noteSearchButton: NSButton! @IBOutlet weak var noteSearchField: KMLeftSideViewSearchField! @IBOutlet weak var noteTitleLabel: NSTextField! @IBOutlet weak var noteHeaderView: NSView! @IBOutlet weak var sortTypeBox: KMBox! @IBOutlet weak var sortTypeLabel: NSTextField! @IBOutlet weak var noteSortButton: NSButton! @IBOutlet weak var noteDoneButton: NSButton! @IBOutlet weak var thumbnailView: NSView! @IBOutlet weak var thumbnailZoomOutButton: NSButton! @IBOutlet weak var thumbnailZoomInButton: NSButton! @IBOutlet weak var thumbnailTitleLabel: NSTextField! @IBOutlet weak var emptySearchBox: NSBox! @IBOutlet weak var emptySearchLabel: NSTextField! var thumbnails: [KMThumbnail] = [] var isDisplayPageSize = false var thumbnailCacheSize: CGFloat = 0 var findState: KMFindState = .content var searchResults: [CPDFSelection] = [] var findPaneState: KMFindPaneState = .singular var isSearchOutlineMode = false var outlineIgnoreCaseFlag = false private let MIN_SIDE_PANE_WIDTH: CGFloat = 270 private let LABEL_COLUMNID = "label" override func loadView() { super.loadView() self.view.wantsLayer = true self.view.layer?.backgroundColor = KMAppearance.Layout.l0Color().cgColor self.outlineView.wantsLayer = true self.outlineView.layer?.backgroundColor = KMAppearance.Layout.l0Color().cgColor self.noteView.wantsLayer = true self.noteView.layer?.backgroundColor = KMAppearance.Layout.l0Color().cgColor self.thumbnailView.wantsLayer = true self.thumbnailView.layer?.backgroundColor = KMAppearance.Layout.l0Color().cgColor self.snapshotNormalView.wantsLayer = true self.snapshotNormalView.layer?.backgroundColor = KMAppearance.Layout.l0Color().cgColor self.tocOutlineView.backgroundColor = KMAppearance.Layout.l0Color() self.noteOutlineView.backgroundColor = KMAppearance.Layout.l0Color() self.findTableView.backgroundColor = KMAppearance.Layout.l0Color() self.groupedFindTableView.backgroundColor = KMAppearance.Layout.l0Color() self.snapshotTableView.backgroundColor = KMAppearance.Layout.l0Color() self.thumbnailTableView.backgroundColor = KMAppearance.Layout.l0Color() self.leftListView.wantsLayer = true self.leftListView.layer?.backgroundColor = KMAppearance.Layout.l0Color().cgColor self.emptySearchLabel.stringValue = KMLocalizedString("No Results",nil) self.emptySearchLabel.textColor = KMAppearance.Layout.h0Color() self.emptySearchBox.isHidden = true self.thumbnailTitleLabel.stringValue = KMLocalizedString("Thumbnails", nil) self.thumbnailTitleLabel.textColor = KMAppearance.Layout.h0Color() // self.thumbnailZoomInButton.action = #selector(thumbnailSizeScaling) // [_thumbnailZoomInButton setTarget:mainController]; // _thumbnailZoomInButton.tag = 1; // [_thumbnailZoomOutButton setAction:@selector(thumbnailSizeScaling:)]; // [_thumbnailZoomOutButton setTarget:mainController]; // _thumbnailZoomOutButton.tag = 0; self.snapshotTableView.delegate = self self.snapshotTableView.dataSource = self // [[snapshotTableView menu] setDelegate:mainController]; // [snapshotTableView setDoubleAction:@selector(toggleSelectedSnapshots:)]; // [snapshotTableView setTarget:mainController]; self.snapshotTableView.backgroundColor = .clear // [snapshotTableView setDraggingSourceOperationMask:NSDragOperationEvery forLocal:NO]; self.snapshotLabel.stringValue = KMLocalizedString("Snapshots", nil) self.snapshotLabel.textColor = KMAppearance.Layout.h0Color() // [_snapshotNormalZoomInButton setAction:@selector(thumbnailSizeScaling:)]; // [_snapshotNormalZoomInButton setTarget:mainController]; // _snapshotNormalZoomInButton.tag = 2; // [_snapshotNormalZoomOutButton setAction:@selector(thumbnailSizeScaling:)]; // [_snapshotNormalZoomOutButton setTarget:mainController]; // _snapshotNormalZoomOutButton.tag = 3; self.snapshotNormalSearchButton.toolTip = KMLocalizedString("Search", nil) // [_snapshotNormalMoreButton setAction:@selector(leftSideViewMoreButtonAction:)]; // [_snapshotNormalMoreButton setTarget:mainController]; // [_snapshotNormalMoreButton setTag:300]; // [_snapshotSearchZoomInButton setAction:@selector(thumbnailSizeScaling:)]; // [_snapshotSearchZoomInButton setTarget:mainController]; // _snapshotSearchZoomInButton.tag = 2; // [_snapshotSearchZoomOutButton setAction:@selector(thumbnailSizeScaling:)]; // [_snapshotSearchZoomOutButton setTarget:mainController]; // _snapshotSearchZoomOutButton.tag = 3; self.snapshotDoneButton.title = KMLocalizedString("Done", nil) self.snapshotDoneButton.toolTip = KMLocalizedString("Done", nil) self.snapshotDoneButton.setTitleColor(KMAppearance.Layout.w0Color()) self.snapshotDoneButton.wantsLayer = true self.snapshotDoneButton.layer?.backgroundColor = KMAppearance.Interactive.a0Color().cgColor self.snapshotDoneButton.layer?.cornerRadius = 4.0 // [self.snapshotDoneButton setAction:@selector(leftSideViewDoneButtonAction:)]; // [self.snapshotDoneButton setTarget:mainController]; // [self.snapshotDoneButton setTag:312]; // self.snapshotDoneButton.hidden = YES; // [noteOutlineView setAutoresizesOutlineColumn: NO]; self.noteOutlineView.delegate = self self.noteOutlineView.dataSource = self // [[noteOutlineView menu] setDelegate:mainController]; // [noteOutlineView setTypeSelectHelper:[SKTypeSelectHelper typeSelectHelperWithMatchOption:SKSubstringMatch]]; // [noteOutlineView setIndentationPerLevel:0.0]; // [noteOutlineView registerForDraggedTypes:[NSColor readableTypesForPasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]]]; self.snapshotSearchField.backgroundColor = KMAppearance.Layout.l_1Color() self.outlineSearchField.backgroundColor = KMAppearance.Layout.l_1Color() self.noteSearchField.backgroundColor = KMAppearance.Layout.l_1Color() self.snapshotSearchField.wantsLayer = true self.outlineSearchField.wantsLayer = true self.noteSearchField.wantsLayer = true self.snapshotSearchField.layer?.backgroundColor = KMAppearance.Layout.l_1Color().cgColor self.outlineSearchField.layer?.backgroundColor = KMAppearance.Layout.l_1Color().cgColor self.noteSearchField.layer?.backgroundColor = KMAppearance.Layout.l_1Color().cgColor self.snapshotSearchField.layer?.borderWidth = 1.0 self.outlineSearchField.layer?.borderWidth = 1.0 self.noteSearchField.layer?.borderWidth = 1.0 self.snapshotSearchField.layer?.borderColor = KMAppearance.Interactive.a0Color().cgColor self.outlineSearchField.layer?.borderColor = KMAppearance.Interactive.a0Color().cgColor self.noteSearchField.layer?.borderColor = KMAppearance.Interactive.a0Color().cgColor // __block typeof(self) blockSelf = self; // _snapshotSearchField.changeCallBack = ^(NSString *changeContent) { // NSString *editContent = @""; // if (changeContent) { // editContent = changeContent; // } // [blockSelf.mainController searchFieldChangeAction:editContent]; // }; self.snapshotSearchField.isHidden = true self.snapshotSearchZoomOutButton.isHidden = true self.snapshotSearchZoomInButton.isHidden = true // _snapshotSearchField.endEditCallBack = ^(BOOL isEndEdit) { // if (isEndEdit/* && searchViewController.segmentedControl.segmentCount == 3*/) { // _snapshotSearchField.hidden = YES; // _snapshotSearchZoomOutButton.hidden = YES; // _snapshotSearchZoomInButton.hidden = YES; // _snapshotLabel.hidden = NO; // _snapshotNormalZoomOutButton.hidden = NO; // _snapshotNormalZoomInButton.hidden = NO; // } // }; self.thumbnailZoomInButton.toolTip = KMLocalizedString("Zoom In", nil) self.snapshotNormalZoomInButton.toolTip = KMLocalizedString("Zoom In", nil) self.snapshotSearchZoomInButton.toolTip = KMLocalizedString("Zoom In", nil) self.thumbnailZoomOutButton.toolTip = KMLocalizedString("Zoom Out", nil) self.snapshotNormalZoomOutButton.toolTip = KMLocalizedString("Zoom Out", nil) self.snapshotSearchZoomOutButton.toolTip = KMLocalizedString("Zoom Out", nil) self.outlineLabel.stringValue = KMLocalizedString("Outline", nil); self.outlineLabel.textColor = KMAppearance.Layout.h0Color() // self.outlineAddButton.toolTip = NSLocalizedString(@"Add Item", nil); // [self.outlineAddButton setAction:@selector(outlineContextMenuItemClicked_AddEntry:)]; // [self.outlineAddButton setTarget:mainController]; // self.outlineSearchButton.toolTip = NSLocalizedString(@"Search", nil); // [self.outlineMoreButton setAction:@selector(leftSideViewMoreButtonAction:)]; // [self.outlineMoreButton setTarget:mainController]; // [self.outlineMoreButton setTag:302]; self.outlineDoneButton.title = KMLocalizedString("Done", nil); self.outlineDoneButton.toolTip = KMLocalizedString("Done", nil); self.outlineDoneButton.setTitleColor(KMAppearance.Layout.w0Color()) self.outlineDoneButton.wantsLayer = true self.outlineDoneButton.layer?.backgroundColor = KMAppearance.Interactive.a0Color().cgColor self.outlineDoneButton.layer?.cornerRadius = 4.0 // [self.outlineDoneButton setAction:@selector(leftSideViewDoneButtonAction:)]; // [self.outlineDoneButton setTarget:mainController]; // [self.outlineDoneButton setTag:310]; // self.outlineDoneButton.hidden = YES; self.outlineSearchField.isHidden = true // _outlineSearchField.endEditCallBack = ^(BOOL isEndEdit) { // if (isEndEdit) { // _outlineSearchField.hidden = YES; // _outlineLabel.hidden = NO; // _outlineSearchButton.hidden = NO; // } // }; // NSMenu *menuOutline = [NSMenu menu]; // [menuOutline addItemWithTitle:NSLocalizedString(@"Ignore Case", @"Menu item title") action:@selector(toggleOutlineCaseInsensitiveSearch:) target:mainController]; // [[_outlineSearchField cell] setSearchMenuTemplate:menuOutline]; // [[_outlineSearchField cell] setPlaceholderString:NSLocalizedString(@"Search Outline", nil)]; // [_outlineSearchField setTarget:mainController]; let sud = UserDefaults.standard self.noteTitleLabel.stringValue = KMLocalizedString("Notes", nil); self.noteTitleLabel.textColor = KMAppearance.KMColor_Layout_H0() // [self.noteMoreButton setAction:@selector(leftSideViewMoreButtonAction:)]; // [self.noteMoreButton setTarget:mainController]; // [self.noteMoreButton setTag:304]; // self.noteMoreButton.wantsLayer = YES; // _moreButtonLayer = [KMButtonLayer layer]; // [self.noteMoreButton.layer addSublayer:_moreButtonLayer]; // _moreButtonLayer.frame = CGRectMake(0, 0, CGRectGetWidth(self.noteMoreButton.bounds), CGRectGetHeight(self.noteMoreButton.bounds)); // _moreButtonLayer.layerType = KMNoteFilerButtonLayerType_None; // _moreButtonLayer.hidden = YES; // [self.noteFilterButton setAction:@selector(noteFilterAction:)]; // [self.noteFilterButton setTarget:mainController]; // [self.noteFilterButton setToolTip:NSLocalizedString(@"Sort", nil)]; // self.noteFilterButton.wantsLayer = YES; // _filterButtonLayer = [[NSView alloc] init]; // [self.noteFilterButton addSubview:_filterButtonLayer]; // _filterButtonLayer.frame = CGRectMake(14, 2, 8, 8); // _filterButtonLayer.layerType = KMNoteFilerButtonLayerType_Dot; // _filterButtonLayer.hidden = YES; // _filterButtonLayer.wantsLayer = YES; // _filterButtonLayer.layer.backgroundColor = [KMAppearance KMColor_Interactive_A0].CGColor; // _filterButtonLayer.layer.cornerRadius = 4.0; self.noteDoneButton.title = KMLocalizedString("Done", nil) self.noteDoneButton.toolTip = KMLocalizedString("Done", nil) self.noteDoneButton.setTitleColor(KMAppearance.Layout.w0Color()) self.noteDoneButton.wantsLayer = true self.noteDoneButton.layer?.backgroundColor = KMAppearance.Interactive.a0Color().cgColor self.noteDoneButton.layer?.cornerRadius = 4.0 // [self.noteDoneButton setAction:@selector(leftSideViewDoneButtonAction:)] // [self.noteDoneButton setTarget:mainController]; // [self.noteDoneButton setTag:311]; // self.noteDoneButton.hidden = YES; self.noteSearchButton.toolTip = KMLocalizedString("Search", nil) self.noteSearchField.isHidden = true // _noteSearchField.endEditCallBack = ^(BOOL isEndEdit) { // if (isEndEdit) { // _noteSearchField.hidden = YES; // _noteSearchButton.hidden = NO; // _noteTitleLabel.hidden = NO; // } // }; self.noteHeaderView.wantsLayer = true self.noteHeaderView.layer?.backgroundColor = KMAppearance.Else.textTagColor().cgColor self.noteHeaderView.layer?.cornerRadius = 1.0 // let sortType = sud.integer(forKey: KMLeftSideViewNoteSortTypeKey) // if (sortType) { // _noteSortType = sortType; // if (sortType == KMNoteSortType_Time) { // self.sortTypeLabel.stringValue = NSLocalizedString(@"Time", nil); // self.sortTypeBox.toolTip = NSLocalizedString(@"Time", nil); // } else if (sortType == KMNoteSortType_Page) { // self.sortTypeLabel.stringValue = NSLocalizedString(@"Page", nil); // self.sortTypeBox.toolTip = NSLocalizedString(@"Page", nil); // } // } else { // _noteSortType = KMNoteSortType_Time; // self.sortTypeLabel.stringValue = NSLocalizedString(@"Time", nil); // } self.sortTypeLabel.textColor = KMAppearance.Layout.h1Color() // _isAscendSort = [sud boolForKey:KMLeftSideViewAscendSortBoolKey]; // if (_isAscendSort) { // [_noteSortButton setImage:[NSImage imageNamed:KMImageNameBtnSidebarRankReverse]]; // [_noteSortButton setToolTip:NSLocalizedString(@"ascending sort", nil)]; // } else { // [_noteSortButton setImage:[NSImage imageNamed:KMImageNameBtnSidebarRankPositive]]; // [_noteSortButton setToolTip:NSLocalizedString(@"descending sort", nil)]; // } // self.sortTypeBox.mouseDownCallback = ^(BOOL downEntered, KMBox *mouseBox) { // if (downEntered) { // NSMenu *menu = [[[NSMenu alloc] init] autorelease]; // NSMenuItem *timeItem = [menu addItemWithTitle:NSLocalizedString(@"Time", nil) action:@selector(sortTypeAction:) target:self]; // [timeItem setRepresentedObject:self]; // timeItem.tag = 0; // NSMenuItem *pageItem = [menu addItemWithTitle:NSLocalizedString(@"Page", nil) action:@selector(sortTypeAction:) target:self]; // [pageItem setRepresentedObject:self]; // timeItem.tag = 1; // if (self.noteSortType == KMNoteSortType_Time) { // timeItem.state = NSControlStateValueOn; // pageItem.state = NSControlStateValueOff; // } else if (self.noteSortType == KMNoteSortType_Page) { // timeItem.state = NSControlStateValueOff; // pageItem.state = NSControlStateValueOn; // } // [menu popUpMenuPositioningItem:nil atLocation:CGPointMake(-10, 0) inView:self.sortTypeBox]; // } // }; self.searchViewController.loadView() self.searchViewController.contentView = self.findTableView.enclosingScrollView self.searchField = self.searchViewController.searchField self.searchViewController.segmentedControl.setSegmentCount(2, with: 25) self.searchViewController.segmentedControl.setImage(NSImage(named: KMImageNameUXIconBtnSidebarListNor)!, for: 0) self.searchViewController.segmentedControl.setImage(NSImage(named: KMImageNameUXIconBtnSidebarPageNor)!, for: 1) self.searchViewController.segmentedControl.setToolTip(KMLocalizedString("Separate search results", nil), for: 0) self.searchViewController.segmentedControl.setToolTip(KMLocalizedString("Group search results by page", nil), for: 1) self.searchViewController.segmentedControl.isBackgroundHighlighted = true self.searchViewController.segmentedControl.selectedSegment = 0 // [mainController bind:@"findPaneState" toObject:searchViewController.segmentedControl withKeyPath:@"selectedSegment" options:nil]; self.segmentedControl.segmentCount = 5 self.segmentedControl.setImage(NSImage(named: KMImageNameUXIconSidetabbarThumbnailNor)!, for: 0) self.segmentedControl.setImage(NSImage(named: KMImageNameUXIconSidetabbarOutlineNor)!, for: 1) self.segmentedControl.setImage(NSImage(named: KMImageNameUXIconSidetabbarAnnotationNor)!, for: 2) self.segmentedControl.setImage(NSImage(named: KMImageNameUXIconSidetabbarSnapshotNor)!, for: 3) self.segmentedControl.setImage(NSImage(named: KMImageNameUXIconSidetabbarSearchNor)!, for: 4) self.segmentedControl.setToolTip(KMLocalizedString("View Thumbnails", nil), for: 0) self.segmentedControl.setToolTip(KMLocalizedString("View Outline", nil), for: 1) self.segmentedControl.setToolTip(KMLocalizedString("View Notes", nil), for: 2) self.segmentedControl.setToolTip(KMLocalizedString("View Snapshots", nil), for: 3) self.segmentedControl.setToolTip(KMLocalizedString("Search", nil), for: 4) self.segmentedControl.selectedSegment = 0 // [segmentedControl bind:@"selectedSegment" toObject:mainController withKeyPath:@"leftSidePaneState" options:nil]; // [mainController bind:@"leftSidePaneState" toObject:segmentedControl withKeyPath:@"selectedSegment" options:nil]; self.segmentedControl.wantsLayer = true self.segmentedControl.layer?.backgroundColor = KMAppearance.Layout.l_1Color().cgColor self.segmentedControl.block = { [unowned self] segIndex in self.toolButtonBox.isHidden = false self.toolButtonBoxLayoutConstraint.constant = 40.0 if (segIndex == 0) { self.toolButtonBox.contentView = self.thumbnailView self.displayThumbnailViewAnimating(true) } else if (segIndex == 1) { self.toolButtonBox.contentView = self.outlineView self.displayTocViewAnimating(false) } else if (segIndex == 2) { self.toolButtonBox.contentView = self.noteView self.displayNoteViewAnimating(false) } else if (segIndex == 3) { self.toolButtonBox.contentView = self.snapshotNormalView self.displaySnapshotViewAnimating(false) } else if (segIndex == 4) { self.toolButtonBox.isHidden = true self.toolButtonBoxLayoutConstraint.constant = 0 self.displayFindViewAnimating(false) } } // self.button.setHelp(KMLocalizedString("View Thumbnails", "Tool tip message"), for: KMLeftSidePaneState.thumbnail.rawValue) // self.button.setHelp(KMLocalizedString("View Outline", "Tool tip message"), for: KMLeftSidePaneState.outline.rawValue) // self.alternateButton.setHelp(KMLocalizedString("Separate search results", "Tool tip message"), for: KMFindPaneState.singular.rawValue) // self.alternateButton.setHelp(KMLocalizedString("Group search results by page", "Tool tip message"), for: KMFindPaneState.grouped.rawValue) // NSMenu *menu = [NSMenu menu]; // [menu addItemWithTitle:NSLocalizedString(@"Whole Words Only", @"Menu item title") action:@selector(toggleWholeWordSearch:) target:mainController]; // [menu addItemWithTitle:NSLocalizedString(@"Ignore Case", @"Menu item title") action:@selector(toggleCaseInsensitiveSearch:) target:mainController]; // [[searchField cell] setSearchMenuTemplate:menu]; // [[searchField cell] setPlaceholderString:NSLocalizedString(@"Search PDF", @"placeholder")]; // [searchField setAction:@selector(search:)]; // [searchField setTarget:mainController]; self.tocOutlineView.autoresizesOutlineColumn = false self.tocOutlineView.allowsMultipleSelection = true self.tocOutlineView.allowsEmptySelection = true self.tocOutlineView.delegate = self self.tocOutlineView.dataSource = self self.thumbnailTableView.delegate = self self.thumbnailTableView.dataSource = self self.thumbnailTableView.allowsMultipleSelection = true self.findTableView.delegate = self // [groupedFindTableView setDelegate:mainController]; self.groupedFindTableView.dataSource = self // [[thumbnailTableView menu] setDelegate:mainController]; // [[findTableView menu] setDelegate:mainController]; // [[groupedFindTableView menu] setDelegate:mainController]; // [tocOutlineView setDoubleAction:@selector(goToSelectedOutlineItem:)]; // [tocOutlineView setTarget:mainController]; // [findTableView setDoubleAction:@selector(goToSelectedFindResults:)]; // [findTableView setTarget:mainController]; // [groupedFindTableView setDoubleAction:@selector(goToSelectedFindResults:)]; // [groupedFindTableView setTarget:mainController]; // [thumbnailTableView setTypeSelectHelper:[SKTypeSelectHelper typeSelectHelperWithMatchOption:SKFullStringMatch]]; // //支持拖拽的文字类型 // [thumbnailTableView registerForDraggedTypes:@[KPDFThumbnailLocalForDraggedTypes,NSFilenamesPboardType]]; // [tocOutlineView setTypeSelectHelper:[SKTypeSelectHelper typeSelectHelperWithMatchOption:SKSubstringMatch]]; // [tocOutlineView registerForDraggedTypes:[NSArray arrayWithObject:kKMPDFViewOutlineDragDataType]]; // [[[findTableView tableColumnWithIdentifier:PAGE_COLUMNID] headerCell] setTitle:NSLocalizedString(@"Page", @"Table header title")]; // [[[groupedFindTableView tableColumnWithIdentifier:PAGE_COLUMNID] headerCell] setTitle:NSLocalizedString(@"Page", @"Table header title")]; // [[[groupedFindTableView tableColumnWithIdentifier:RELEVANCE_COLUMNID] dataCell] setEnabled:NO]; // if (RUNNING_AFTER(10_9)) { // [thumbnailTableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone]; // [(SKSourceListTextFieldCell *)[[thumbnailTableView tableColumnWithIdentifier:PAGE_COLUMNID] dataCell] setSimulatesSourceList:YES]; // } // NSSortDescriptor *countDescriptor = [[[NSSortDescriptor alloc] initWithKey:SKGroupedSearchResultCountKey ascending:NO] autorelease]; // [groupedFindArrayController setSortDescriptors:[NSArray arrayWithObjects:countDescriptor, nil]]; // // [thumbnailTableView setDraggingSourceOperationMask:NSDragOperationEvery forLocal:NO]; // if (NO == [[NSUserDefaults standardUserDefaults] boolForKey:SKDisableTableToolTipsKey]) { // [tocOutlineView setHasImageToolTips:YES]; // [findTableView setHasImageToolTips:YES]; // [groupedFindTableView setHasImageToolTips:YES]; // } // [self updateViewColor]; } func displayThumbnailViewAnimating(_ animate: Bool) { self.replaceSideView(self.thumbnailTableView.enclosingScrollView!, animate: animate) var frame = self.thumbnailTableView.enclosingScrollView?.frame ?? .zero frame.origin.y = 0 frame.size.height = self.thumbnailTableView.enclosingScrollView?.superview?.frame.size.height ?? 0 self.thumbnailTableView.enclosingScrollView?.frame = frame self.resetThumbnails() // frame = rightSideController.noteOutlineView.enclosingScrollView.frame; // frame.origin.y = 0; // frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height; // rightSideController.noteOutlineView.enclosingScrollView.frame = frame; // frame = rightSideController.snapshotTableView.enclosingScrollView.frame; // frame.origin.y = 0; // frame.size.height = rightSideController.snapshotTableView.enclosingScrollView.superview.frame.size.height; // rightSideController.snapshotTableView.enclosingScrollView.frame = frame; // [self updateThumbnailSelection]; } func displayFindViewAnimating(_ animate: Bool) { self.replaceSideView(self.searchViewController.view, animate: animate) if (self.findState != .content) { self.findState = .content } else { self.displayFindState() } var frame = self.searchViewController.view.frame frame.origin.y = 0 frame.size.height = self.searchViewController.view.superview?.frame.size.height ?? .zero self.searchViewController.view.frame = frame // frame = rightSideController.noteOutlineView.enclosingScrollView.frame; // frame.origin.y = 0; // frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height; // rightSideController.noteOutlineView.enclosingScrollView.frame = frame; // frame = rightSideController.snapshotTableView.enclosingScrollView.frame; // frame.origin.y = 0; // frame.size.height = rightSideController.snapshotTableView.enclosingScrollView.superview.frame.size.height; // rightSideController.snapshotTableView.enclosingScrollView.frame = frame; // [self.leftSideEmptyVC.emptySnapView removeFromSuperview]; // [self updataLeftSideSnapView]; } func displayFindState() { if (self.findState == .content) { self.displayFind() } else if (self.findState == .note) { // [self displayNoteFind]; } else if (self.findState == .snapshot) { // [self displaySnapshotFind]; } } /* - (void) { } - (void)displayGroupedFindViewAnimating:(BOOL)animate { [leftSideController replaceSideView:leftSideController.searchViewController.view animate:animate]; if (self.findState != SKFindStateContent) { self.findState = SKFindStateContent; } else { [leftSideController displayFindState]; } NSRect frame = leftSideController.searchViewController.view.frame; frame.origin.y = 0; frame.size.height = leftSideController.searchViewController.view.superview.frame.size.height; leftSideController.searchViewController.view.frame = frame; frame = rightSideController.noteOutlineView.enclosingScrollView.frame; frame.origin.y = 0; frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height; rightSideController.noteOutlineView.enclosingScrollView.frame = frame; frame = rightSideController.snapshotTableView.enclosingScrollView.frame; frame.origin.y = 0; frame.size.height = rightSideController.snapshotTableView.enclosingScrollView.superview.frame.size.height; rightSideController.snapshotTableView.enclosingScrollView.frame = frame; [self updataLeftSideSnapView]; } */ func displayNoteViewAnimating(_ animate: Bool) { self.searchViewController.contentView = nil self.replaceSideView(self.noteOutlineView.enclosingScrollView!, animate: animate) if (self.findState != .note) { self.findState = .note } else { self.displayFindState() } var frame = self.noteOutlineView.enclosingScrollView?.frame ?? .zero frame.origin.y = 0 frame.size.height = self.noteOutlineView.enclosingScrollView?.superview?.frame.size.height ?? 0 self.noteOutlineView.enclosingScrollView?.frame = frame frame = self.noteOutlineView.enclosingScrollView?.frame ?? .zero frame.origin.y = 0 frame.size.height = self.noteOutlineView.enclosingScrollView?.superview?.frame.size.height ?? 0 self.noteOutlineView.enclosingScrollView?.frame = frame frame = self.snapshotTableView.enclosingScrollView?.frame ?? .zero frame.origin.y = 0 frame.size.height = self.snapshotTableView.enclosingScrollView?.superview?.frame.size.height ?? 0 self.snapshotTableView.enclosingScrollView?.frame = frame let view = self.noteOutlineView.enclosingScrollView // CGSize emptyVcSize = self.leftSideEmptyVC.emptyAnnotationView.frame.size; // self.leftSideEmptyVC.emptyAnnotationView.frame = NSMakeRect((view.frame.size.width-emptyVcSize.width)/2.0,(view.frame.size.height-emptyVcSize.height)/2.0, emptyVcSize.width, emptyVcSize.height); } func displaySnapshotViewAnimating(_ animate: Bool) { self.searchViewController.contentView = nil self.replaceSideView(self.snapshotTableView.enclosingScrollView!, animate: animate) if (self.findState != .snapshot) { self.findState = .snapshot; } else { self.displayFindState() } var frame = self.snapshotTableView.enclosingScrollView?.frame ?? .zero frame.origin.y = 0 frame.size.height = self.snapshotTableView.enclosingScrollView?.superview?.frame.size.height ?? 0 self.snapshotTableView.enclosingScrollView?.frame = frame // frame = rightSideController.noteOutlineView.enclosingScrollView.frame; // frame.origin.y = 0; // frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height; // rightSideController.noteOutlineView.enclosingScrollView.frame = frame; frame = self.tocOutlineView.enclosingScrollView?.frame ?? .zero frame.origin.y = 0 frame.size.height = self.tocOutlineView.enclosingScrollView?.superview?.frame.size.height ?? 0 self.tocOutlineView.enclosingScrollView?.frame = frame // [self updateSnapshotsIfNeeded]; } func displayFind() { self.searchField = self.searchViewController.searchField let menu = NSMenu() // menu.addItem(title: <#T##String#>, action: <#T##Selector?#>, target: <#T##AnyObject?#>) // [menu addItemWithTitle:NSLocalizedString(@"Whole Words Only", @"Menu item title") action:@selector(toggleWholeWordSearch:) target:mainController]; // [menu addItemWithTitle:NSLocalizedString(@"Ignore Case", @"Menu item title") action:@selector(toggleCaseInsensitiveSearch:) target:mainController]; // [[searchViewController.searchField cell] setSearchMenuTemplate:menu]; (self.searchViewController.searchField.cell as? NSSearchFieldCell)?.placeholderString = KMLocalizedString("Search PDF", "placeholder") // self.searchViewController.searchField.target = // [searchViewController.searchField setAction:@selector(search:)]; // [searchViewController.searchField setTarget:mainController]; if (self.findPaneState == .singular) { self.searchViewController.contentView = self.findTableView.enclosingScrollView } else if (self.findPaneState == .grouped) { self.searchViewController.contentView = self.groupedFindTableView.enclosingScrollView } } func displayTocViewAnimating(_ animate: Bool) { self.replaceSideView(self.tocOutlineView.enclosingScrollView!, animate: animate) var frame = self.tocOutlineView.enclosingScrollView?.frame ?? .zero frame.origin.y = 0 frame.size.height = self.tocOutlineView.enclosingScrollView?.superview?.frame.size.height ?? 0 self.tocOutlineView.enclosingScrollView?.frame = frame // frame = rightSideController.noteOutlineView.enclosingScrollView.frame; // frame.origin.y = 0; // frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height; // rightSideController.noteOutlineView.enclosingScrollView.frame = frame; frame = self.snapshotTableView.enclosingScrollView?.frame ?? .zero frame.origin.y = 0 frame.size.height = self.snapshotTableView.enclosingScrollView?.superview?.frame.size.height ?? 0 self.snapshotTableView.enclosingScrollView?.frame = frame // [self updateOutlineSelection]; let view = self.tocOutlineView.enclosingScrollView // CGSize emptyVcSize = self.leftSideEmptyVC.emptyOutlineView.frame.size; // self.leftSideEmptyVC.emptyOutlineView.frame = NSMakeRect((view.frame.size.width-emptyVcSize.width)/2.0,(view.frame.size.height-emptyVcSize.height)/2.0, emptyVcSize.width, emptyVcSize.height); } /* @implementation SKLeftSideViewController @synthesize thumbnailArrayController, findArrayController, groupedFindArrayController; - (BOOL)requiresAlternateButtonForView:(NSView *)aView { return NO; return [findTableView isDescendantOf:aView] || [groupedFindTableView isDescendantOf:aView]; } - (void)applySearchTableHeader:(NSString *)message { [[[findTableView tableColumnWithIdentifier:RESULTS_COLUMNID] headerCell] setStringValue:message]; [[findTableView headerView] setNeedsDisplay:YES]; [[[groupedFindTableView tableColumnWithIdentifier:RELEVANCE_COLUMNID] headerCell] setStringValue:message]; [[groupedFindTableView headerView] setNeedsDisplay:YES]; } - (void)displayFindState { if (mainController.findState == SKFindStateContent) { [self displayFind]; } else if (mainController.findState == SKFindStateNote) { [self displayNoteFind]; } else if (mainController.findState == SKFindStateSnapshot) { [self displaySnapshotFind]; } } - (void)displayNoteFind { mainController.rightSideController.searchField = self.noteSearchField; NSMenu *menu = [NSMenu menu]; [menu addItemWithTitle:NSLocalizedString(@"Ignore Case", @"Menu item title") action:@selector(toggleCaseInsensitiveNoteSearch:) target:mainController]; [[self.noteSearchField cell] setSearchMenuTemplate:menu]; [[self.noteSearchField cell] setPlaceholderString:NSLocalizedString(@"Search Notes", @"placeholder")]; [self.noteSearchField setAction:@selector(searchNotes:)]; [self.noteSearchField setTarget:mainController]; } - (void)displaySnapshotFind { mainController.rightSideController.searchField = self.snapshotSearchField; NSMenu *menu = [NSMenu menu]; [menu addItemWithTitle:NSLocalizedString(@"Ignore Case", @"Menu item title") action:@selector(toggleCaseInsensitiveNoteSearch:) target:mainController]; [[self.snapshotSearchField cell] setSearchMenuTemplate:menu]; [[self.snapshotSearchField cell] setPlaceholderString:NSLocalizedString(@"Search Snapshots", @"placeholder")]; [self.snapshotSearchField setAction:@selector(searchNotes:)]; [self.snapshotSearchField setTarget:mainController]; [self.snapshotSearchField setDelegate:mainController]; } #pragma mark - UI Action - (IBAction)snapshotNormalSearchButtonAction:(NSButton *)sender { _snapshotSearchField.hidden = NO; // _snapshotSearchZoomOutButton.hidden = YES; _snapshotSearchZoomInButton.hidden = YES; _snapshotNormalSearchButton.hidden = YES; _snapshotDoneButton.hidden = NO; _snapshotLabel.hidden = YES; _snapshotNormalZoomOutButton.hidden = YES; _snapshotNormalZoomInButton.hidden = YES; [_snapshotSearchField becomeFirstResponder]; } - (IBAction)outlineNormalSearchButtonAction:(NSButton *)sender { _outlineSearchField.hidden = NO; _outlineDoneButton.hidden = NO; _outlineLabel.hidden = YES; _outlineSearchButton.hidden = YES; _outlineMoreButton.hidden = YES; _outlineAddButton.hidden = YES; [_outlineSearchField becomeFirstResponder]; } - (IBAction)noteSearchAction:(NSButton *)sender { self.noteSearchField.hidden = NO; self.noteTitleLabel.hidden = YES; self.noteSearchButton.hidden = YES; self.noteDoneButton.hidden = NO; self.noteFilterButton.hidden = YES; self.noteMoreButton.hidden = YES; [self.noteSearchField becomeFirstResponder]; } - (IBAction)noteSortAction:(id)sender { if (self.isAscendSort) { self.isAscendSort = NO; [self.noteSortButton setImage:[NSImage imageNamed:KMImageNameBtnSidebarRankPositive]]; [self.noteSortButton setToolTip:NSLocalizedString(@"descending sort", nil)]; } else { self.isAscendSort = YES; [self.noteSortButton setImage:[NSImage imageNamed:KMImageNameBtnSidebarRankReverse]]; [self.noteSortButton setToolTip:NSLocalizedString(@"ascending sort", nil)]; } [[NSUserDefaults standardUserDefaults] setBool:self.isAscendSort forKey:KMLeftSideViewAscendSortBoolKey]; } - (IBAction)sortTypeAction:(id)sender { NSMenuItem *item = (NSMenuItem *)sender; NSInteger tag = item.tag; if (item.state == NSControlStateValueOn) { item.state = NSControlStateValueOff; } else { item.state = NSControlStateValueOn; } if (tag == 0) { self.noteSortType = KMNoteSortType_Page; _sortTypeLabel.stringValue = NSLocalizedString(@"Page", nil); _sortTypeBox.toolTip = NSLocalizedString(@"Page", nil); } else if (tag == 1) { self.noteSortType = KMNoteSortType_Time; _sortTypeLabel.stringValue = NSLocalizedString(@"Time", nil); _sortTypeBox.toolTip = NSLocalizedString(@"Time", nil); } [[NSUserDefaults standardUserDefaults] setInteger:self.noteSortType forKey:KMLeftSideViewNoteSortTypeKey]; [[NSUserDefaults standardUserDefaults] synchronize]; } #pragma mark - get && set - (void)setIsAscendSort:(BOOL)isAscendSort { _isAscendSort = isAscendSort; [[NSNotificationCenter defaultCenter] postNotificationName:@"KMAnnotationSortTypeKeyNotification" object:self userInfo:nil]; } - (void)setNoteSortType:(KMNoteSortType)noteSortType { _noteSortType = noteSortType; [[NSNotificationCenter defaultCenter] postNotificationName:@"KMAnnotationSortTypeKeyNotification" object:self userInfo:nil]; } */ func resetThumbnails() { // [self willChangeValueForKey:THUMBNAILS_KEY]; self.thumbnailCacheSize = 400 self.thumbnails.removeAll() let pageLabels = self.listView.document.pageLabels() if (pageLabels.isEmpty == false) { let isLocked = self.listView.document.isLocked let firstPage = self.listView.document.page(at: 0) // SKPDFPage let emptyPage = CPDFPage() let firstFrame = firstPage?.bounds(for: .cropBox) ?? .zero let firstFrame2 = firstPage?.bounds(for: .mediaBox) ?? .zero emptyPage.setBounds(firstFrame, for: .cropBox) emptyPage.setBounds(firstFrame2, for: .mediaBox) emptyPage.rotation = firstPage?.rotation ?? 0 let pageImage = firstPage!.thumbnail(of: NSMakeSize(self.thumbnailCacheSize, self.thumbnailCacheSize)) // NSImage * = [emptyPage thumbnailWithSize:thumbnailCacheSize forBox:[pdfView displayBox]]; var rect: NSRect = .zero rect.size = pageImage?.size ?? .zero let width = 1.2 * fmin(NSWidth(rect), NSHeight(rect)) rect = NSInsetRect(rect, 0.5 * (NSWidth(rect) - width), 0.5 * (NSHeight(rect) - width)); pageImage?.lockFocus() NSImage(named: NSImage.applicationIconName)?.draw(in: rect, from: .zero, operation: .sourceOver, fraction: 0.5) if (isLocked) { NSWorkspace.shared.icon(forFileType: NSFileTypeForHFSTypeCode(OSType(kLockedBadgeIcon))).draw(in: rect, from: .zero, operation: .sourceOver, fraction: 0.5) // [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kLockedBadgeIcon)] drawInRect:rect fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:0.5]; } pageImage?.unlockFocus() // __block typeof(self) blockSelf = self; for (i, label) in pageLabels.enumerated() { let thumbnail = KMThumbnail(image: pageImage, label: label, pageIndex: i) // thumbnail.delegate = self thumbnail.dirty = true self.thumbnails.append(thumbnail) } } // [self didChangeValueForKey:THUMBNAILS_KEY]; // [self allThumbnailsNeedUpdate]; DispatchQueue.main.async { self.thumbnailTableView.reloadData() } } /* */ } //MARK: NSTableViewDelegate,NSTableViewDataSource //extension KMLeftSideViewController: NSTableViewDelegate,NSTableViewDataSource { // func numberOfRows(in tableView: NSTableView) -> Int { // return self.dataSource.count // } // // func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { // let cell : KMLiftSideCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMLiftSideCellView"), owner: self) as! KMLiftSideCellView // if row <= selectImage.count-1 { // if self.dataSource[row] == self.type { // cell.isSelect = true // cell.mothedImage.image = NSImage(named: selectImage[row]) // cell.backgroundColor(NSColor.km_init(hex: "#DFE1E5")) // } else { // cell.isSelect = false // cell.mothedImage.image = NSImage(named: norImage[row]) // cell.backgroundColor(NSColor.clear) // } // } // cell.index = row // cell.buttonClick = { [unowned self] index in // if ((index < self.dataSource.count) && (index > -1)) { // // let isSearch = self.type.methodType == .Search // // var show = true // if( self.type == self.dataSource[index]) { // self.type = KMLeftMethodMode() // show = false // } else { // self.type = self.dataSource[index] // show = true // } // // self.trackEvent(type: self.type.methodType) // // self.updateViewButtonState() // self.delegate?.controlStateChange?(self,show:show) //// self.leftTableview.selectRowIndexes([index], byExtendingSelection: true) //// self.leftTableview.reloadData() // // UserDefaults.standard.set(index, forKey: "KMBOTASelectedIndexKey") // UserDefaults.standard.synchronize() // // if (isSearch && show == false) { // self.view.window?.makeFirstResponder(self) // } else if (isSearch && self.type.methodType != .Search) { // 切换 // self.view.window?.makeFirstResponder(self) // } // } // } // return cell // } // // func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { // return 48 // } // // func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? { // let rowView = KMCustomTableRowView() // rowView.selectionColor = NSColor(calibratedRed: 223.0/255.0, green: 225.0/255.0, blue: 229.0/255.0, alpha: 1.0) // rowView.color = NSColor.km_init(hex: "#F7F8FA") // return rowView // } // // func tableViewSelectionDidChange(_ notification: Notification) { // // } //} //extension KMLeftSideViewController: KMPDFViewPanelSetViewControllerDelegate { // func controller(_ controller: KMPDFViewPanelSetViewController, dispayDidChange dispay: KMPDFDisplayType) { // self.delegate?.controller?(self, dispayDidChange: dispay) // } // // func controller(_ controller: KMPDFViewPanelSetViewController, pageBreaksClick pageBreaks: Bool) { // self.listView?.displaysPageBreaks = pageBreaks // self.listView?.layoutDocumentView() // } // // func controller(_ controller: KMPDFViewPanelSetViewController, rotateClick rotateType: KMRotateType) { //// if (rotateType == .clockwise) { /// 顺时针 //// let page : CPDFPage = self.listView?.currentPage() ?? CPDFPage() //// if page.rotation == 0 { //// page.rotation = 90 //// } else if page.rotation == 90 { //// page.rotation = 180 //// } else if page.rotation == 180 { //// page.rotation = 270 //// } else if page.rotation == 270 { //// page.rotation = 0 //// } //// self.listView?.layoutDocumentView() //// } else if (rotateType == .anticlockwise) { /// 逆时针 //// let page : CPDFPage = self.listView?.currentPage() ?? CPDFPage() //// if page.rotation == 0 { //// page.rotation = 270 //// } else if page.rotation == 90 { //// page.rotation = 0 //// } else if page.rotation == 180 { //// page.rotation = 90 //// } else if page.rotation == 270 { //// page.rotation = 180 //// } //// self.listView?.layoutDocumentView() //// } //// // self.delegate?.controller?(controller: self, rotateType: rotateType) // } //} // MARK: - // MARK: - 扩展 extension KMLeftSideViewController { public func selectType(_ type: BotaType) { // 更新 type var show = true if (self.type.methodType == .None) { show = true } else { if (self.type.methodType == type) { show = false } else { show = true } } var index: Int = NSNotFound switch type { case .None: index = NSNotFound break case .Thumbnail: index = 0 break case .Outline: index = 1 break case .BookMark: index = 2 break case .Annotation: index = 3 break case .Search: index = 4 break case .From: index = 5 break case .Signature: index = 6 break } self.type = self.getMethodMode(show ? type : .None) // 更新按钮状态 // self.updateViewButtonState() // 将事件传递出去 self.delegate?.controlStateChange?(self,show:show) if (index != NSNotFound) { // self.leftTableview.selectRowIndexes([index], byExtendingSelection: true) // 记录当前选中 UserDefaults.standard.set(index, forKey: "KMBOTASelectedIndexKey") UserDefaults.standard.synchronize() } // self.leftTableview.reloadData() } private func getMethodMode(_ type: BotaType) -> KMLeftMethodMode { let mode = KMLeftMethodMode() mode.methodType = type switch type { case .None: mode.methodName = "" break case .Thumbnail: mode.methodName = thumbnailMethodKey break case .Outline: mode.methodName = outlineMethodKey break case .BookMark: mode.methodName = bookMarkMethodKey break case .Annotation: mode.methodName = anntationMethodKey break case .Search: mode.methodName = searchMethodKey break case .From: mode.methodName = formMethodKey break case .Signature: mode.methodName = signatureMethodKey break } return mode } } //MARK: Cache extension KMLeftSideViewController { func clearAnnotationFilterData() { if let _key = self.listView?.document?.documentURL?.path { let userDefaults = UserDefaults.standard let typeData = try?NSKeyedArchiver.archivedData(withRootObject: [Any](), requiringSecureCoding: false) userDefaults.set(typeData, forKey: "KMNoteOutlineFilterSelectArray_Type" + _key) let colorData = try?NSKeyedArchiver.archivedData(withRootObject: [Any](), requiringSecureCoding: false) userDefaults.set(colorData, forKey: "KMNoteOutlineFilterSelectArray_Color" + _key) let authorData = try?NSKeyedArchiver.archivedData(withRootObject: [Any](), requiringSecureCoding: false) userDefaults.set(authorData, forKey: "KMNoteOutlineFilterSelectArray_Author" + _key) userDefaults.synchronize() } } func clearNotification() { self.bookViewController.removeNotification() self.annotationViewController.removeNotification() } } // MARK: - Analytics (埋点) extension KMLeftSideViewController { func trackEvent(type: BotaType) -> Void { if (type == .Thumbnail) { KMAnalytics.trackEvent(eventName: "Btn_LeftSideBar_Thumbnail", parameters: [ KMAnalytics.Parameter.categoryKey : KMAnalytics.Category.leftSideBar, KMAnalytics.Parameter.labelKey : KMAnalytics.Label.leftSideBar_Btn], platform: .AppCenter, appTarget: .all) } else if (type == .Outline) { KMAnalytics.trackEvent(eventName: "Btn_LeftSideBar_Outline", parameters: [ KMAnalytics.Parameter.categoryKey : KMAnalytics.Category.leftSideBar, KMAnalytics.Parameter.labelKey : KMAnalytics.Label.leftSideBar_Btn], platform: .AppCenter, appTarget: .all) } else if (type == .BookMark) { KMAnalytics.trackEvent(eventName: "Btn_LeftSideBar_BookMark", parameters: [ KMAnalytics.Parameter.categoryKey : KMAnalytics.Category.leftSideBar, KMAnalytics.Parameter.labelKey : KMAnalytics.Label.leftSideBar_Btn], platform: .AppCenter, appTarget: .all) } else if (type == .Annotation) { KMAnalytics.trackEvent(eventName: "Btn_LeftSideBar_Annotation", parameters: [ KMAnalytics.Parameter.categoryKey : KMAnalytics.Category.leftSideBar, KMAnalytics.Parameter.labelKey : KMAnalytics.Label.leftSideBar_Btn], platform: .AppCenter, appTarget: .all) } else if (type == .Search) { KMAnalytics.trackEvent(eventName: "Btn_LeftSideBar_Search", parameters: [ KMAnalytics.Parameter.categoryKey : KMAnalytics.Category.leftSideBar, KMAnalytics.Parameter.labelKey : KMAnalytics.Label.leftSideBar_Btn], platform: .AppCenter, appTarget: .all) } } } // MARK: - Private Methods extension KMLeftSideViewController { @objc private func _themeChanged(_ notification: NSNotification) { DispatchQueue.main.asyncAfter(deadline: .now()+0.3) { self._updateViewColor() } } private func _updateViewColor() { if(KMAppearance.isDarkMode()){ self.leftListView.layer?.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1).cgColor self.snapshotNormalView.layer?.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1).cgColor self.thumbnailView.layer?.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1).cgColor self.noteView.layer?.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1).cgColor self.outlineView.layer?.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1).cgColor self.view.layer?.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1).cgColor self.thumbnailTableView.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1) self.groupedFindTableView.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1) self.tocOutlineView.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1) self.findTableView.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1) self.snapshotSearchField.layer?.backgroundColor = NSColor(red: 0.224, green: 0.235, blue: 0.243, alpha: 1).cgColor self.outlineSearchField.layer?.backgroundColor = NSColor(red: 0.224, green: 0.235, blue: 0.243, alpha: 1).cgColor self.noteSearchField.layer?.backgroundColor = NSColor(red: 0.224, green: 0.235, blue: 0.243, alpha: 1).cgColor self.segmentedControl.layer?.backgroundColor = NSColor(red: 0.224, green: 0.235, blue: 0.243, alpha: 1).cgColor self.snapshotSearchField.backgroundColor = NSColor(red: 0.224, green: 0.235, blue: 0.243, alpha: 1) self.outlineSearchField.backgroundColor = NSColor(red: 0.224, green: 0.235, blue: 0.243, alpha: 1) self.noteSearchField.backgroundColor = NSColor(red: 0.224, green: 0.235, blue: 0.243, alpha: 1) } else { self.leftListView.layer?.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1, alpha: 1).cgColor self.snapshotNormalView.layer?.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1, alpha: 1).cgColor self.thumbnailView.layer?.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1, alpha: 1).cgColor self.noteView.layer?.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1, alpha: 1).cgColor self.outlineView.layer?.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1, alpha: 1).cgColor self.view.layer?.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1, alpha: 1).cgColor self.thumbnailTableView.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1.000, alpha: 1) self.groupedFindTableView.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1.000, alpha: 1) self.tocOutlineView.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1.000, alpha: 1) self.findTableView.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1.000, alpha: 1) self.snapshotSearchField.layer?.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1).cgColor self.outlineSearchField.layer?.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1).cgColor self.noteSearchField.layer?.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1).cgColor self.segmentedControl.layer?.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1).cgColor self.snapshotSearchField.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1) self.outlineSearchField.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1) self.noteSearchField.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1) } } private func _hasContainString(_ searchString: String, rootOutline outline: CPDFOutline) -> Bool { // if ([outline.label rangeOfString:searchString options:self.outlineIgnoreCaseFlag?NSCaseInsensitiveSearch:0].location != NSNotFound){ // return YES; // } else { // BOOL subHas = NO; // for (NSUInteger i = 0; i < outline.numberOfChildren; i ++) { // PDFOutline *subOutline = [outline childAtIndex:i]; // subHas = [self hasContainString:searchString rootOutline:subOutline]; // if (subHas) { // break; // } // } // return subHas; // } return false } } // MARK: - KMThumbnailTableViewDelegate, NSTableViewDataSource extension KMLeftSideViewController: NSTableViewDelegate, NSTableViewDataSource { func numberOfRows(in tableView: NSTableView) -> Int { if tableView.isEqual(to: self.thumbnailTableView) { return self.thumbnails.count } else if tableView.isEqual(to: self.findTableView) { return self.searchResults.count } return 0 } func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { if tableView.isEqual(to: self.thumbnailTableView) { let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMThumbnailTableviewCell"), owner: self) as! KMThumbnailTableviewCell let thumbnail = self.thumbnails[row] cell.pageNumLabel.stringValue = thumbnail.label cell.thumImage.image = thumbnail.image if let _image = thumbnail.image { let multiplierHToW = _image.size.height / (_image.size.width == 0 ? 1 : _image.size.width) let multiplierWToH = _image.size.width / (_image.size.height == 0 ? 1 : _image.size.height) if (_image.size.height > _image.size.width) { NSLayoutConstraint.deactivate([cell.imageAspectRatioLayout]) cell.imageAspectRatioLayout = NSLayoutConstraint(item: cell.thumImage, attribute: .height, relatedBy: .equal, toItem: cell.thumImage, attribute: .width, multiplier: multiplierHToW, constant: 0) NSLayoutConstraint.activate([cell.imageAspectRatioLayout]) } else { NSLayoutConstraint.deactivate([cell.imageAspectRatioLayout]) cell.imageAspectRatioLayout = NSLayoutConstraint(item: cell.thumImage, attribute: .width, relatedBy: .equal, toItem: cell.thumImage, attribute: .height, multiplier: multiplierWToH, constant: 0) NSLayoutConstraint.activate([cell.imageAspectRatioLayout]) } } if (self.isDisplayPageSize) { cell.sizeLabel.isHidden = false //获取Page的真实尺寸 let page = self.listView.document.page(at: UInt(row)) let rect = page?.bounds(for: .cropBox) ?? .zero let w = KMPageSizeTool.conversion(withUnit: "mm", value: (CGRectGetWidth(rect)/595 * 210)) let h = KMPageSizeTool.conversion(withUnit: "mm", value: (CGRectGetHeight(rect)/842 * 297)) if let data = page?.rotation, data == 90 || data == 270 { cell.sizeLabel.stringValue = String(format: "%.f × %.f %@", h.stringToCGFloat(), w.stringToCGFloat(), KMLocalizedString("mm", nil)) } else { cell.sizeLabel.stringValue = String(format: "%.f × %.f %@", w.stringToCGFloat(), h.stringToCGFloat(), KMLocalizedString("mm", nil)) } } else { cell.sizeLabel.isHidden = true } cell.sizeTopConstant.constant = cell.sizeLabel.isHidden ? -cell.sizeLabel.frame.size.height : 0 if(self.thumbnailTableView.selectedRowIndexes.contains(row)) { cell.isSelectCell = true } else { cell.isSelectCell = false } return cell } else if (tableView.isEqual(to: self.findTableView)) { let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMFindTableviewCell"), owner: self) as! KMFindTableviewCell let selection = searchResults[row] if let data = tableColumn?.identifier.rawValue, data == "results" { cell.resultLabel.attributedStringValue = selection.attributedString() cell.resultLabel.textColor = KMAppearance.Layout.h0Color() } else if let data = tableColumn?.identifier.rawValue, data == "page" { cell.resultLabel.stringValue = selection.pages().first?.label ?? "" cell.resultLabel.textColor = KMAppearance.Layout.h2Color() } return cell } else if tableView.isEqual(to: self.snapshotTableView) { let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMSnapshotTableViewCell"), owner: self) as! KMSnapshotTableViewCell // SKSnapshotWindowController *snapshot = snapshots[row]; // cell.snapshotImage.image = snapshot.thumbnail; // cell.snapshotLabel.stringValue = snapshot.pageLabel; // if (snapshot.hasWindow) { // cell.snapshotImageView.hidden = NO; // } else { // cell.snapshotImageView.hidden = YES; // } // if(selectCellList.count > 0 && [selectCellList.firstObject integerValue]< 0 && (NSUInteger)row == self.snapshots.count - 1) { // cell.isSelectCell = YES; // } else { // cell.isSelectCell = NO; // } // for (NSUInteger i = 0; i < selectCellList.count; i ++) { // NSInteger selectCell = [selectCellList[i] integerValue]; // if (selectCell == row) { // cell.isSelectCell = YES; // } // } // if (row == tableView.selectedRow) { // [cell.snapshotImageView setImage:[NSImage imageNamed:KMImageNameUXIconSidebarSnapshotWindowSel]]; // } else { // [cell.snapshotImageView setImage:[NSImage imageNamed:KMImageNameUXIconSidebarSnapshotWindowNor]]; // } return cell } return nil } func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { if tableView.isEqual(to: self.thumbnailTableView) { let scaling = UserDefaults.standard.float(forKey: "KMThumbnailSizeScalingKey") let thumbnailSize = self.thumbnails[row].size let newScaling: CGFloat = scaling.cgFloat + 0.1 let newThumbnailHeight = thumbnailSize.width * newScaling if (newThumbnailHeight > MIN_SIDE_PANE_WIDTH) { self.thumbnailZoomOutButton.isEnabled = false } else { self.thumbnailZoomOutButton.isEnabled = true } if ((scaling - 0.1) < 0.3) { self.thumbnailZoomInButton.isEnabled = false } else { self.thumbnailZoomInButton.isEnabled = true } var labelHeight = 0.0 if (self.isDisplayPageSize) { labelHeight = 56.0 } else { labelHeight = 41.5 } let cellHeight = thumbnailSize.height + labelHeight var thumbSize: NSSize = .zero if (scaling != nil && scaling > 0) { thumbSize = NSMakeSize(thumbnailSize.width * scaling.cgFloat, cellHeight * scaling.cgFloat) } else { thumbSize = NSMakeSize(thumbnailSize.width, cellHeight) } return thumbSize.height // NSSize cellSize = NSMakeSize([[tv tableColumnWithIdentifier:IMAGE_COLUMNID] width], fmin(thumbSize.height, roundedThumbnailSize)); // if (thumbSize.height < [tv rowHeight]) // return [tv rowHeight]; // else if (thumbSize.width / thumbSize.height < cellSize.width / cellSize.height) // return cellSize.height; // else // return fmax([tv rowHeight], fmin(cellSize.width, thumbSize.width) * thumbSize.height / thumbSize.width); } else if tableView.isEqual(to: self.snapshotTableView) { let scaling = UserDefaults.standard.float(forKey: "KMSnapshotSizeScalingKey") // NSSize snapshotSize = [[[[rightSideController.snapshotArrayController arrangedObjects] objectAtIndex:row] thumbnail] size]; let snapshotSize = CGSizeMake(120, 63) var newScaling = scaling + 0.1 let newSnapshotHeight = snapshotSize.width * newScaling.cgFloat; if (newSnapshotHeight > MIN_SIDE_PANE_WIDTH) { self.snapshotNormalZoomInButton.isEnabled = false } else { self.snapshotNormalZoomInButton.isEnabled = true } if ((scaling - 0.1) < 0.3 || (newSnapshotHeight < 150.0)) { self.snapshotNormalZoomOutButton.isEnabled = false } else { self.snapshotNormalZoomOutButton.isEnabled = true } let cellHeight = snapshotSize.height + 24.0 var thumbSize: NSSize = .zero if (scaling > 0) { thumbSize = NSMakeSize(snapshotSize.width * scaling.cgFloat, cellHeight * scaling.cgFloat) } else { thumbSize = NSMakeSize(snapshotSize.width, cellHeight) } return thumbSize.height } else if (tableView.isEqual(to: self.findTableView)) { return 40.0 } return tableView.rowHeight } func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? { if (tableView.isEqual(to: self.findTableView) || tableView.isEqual(to: self.groupedFindTableView)) { let rowView = KMCustomTableRowView() return rowView } return nil } /* //- (id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { // return nil; //} - (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard { if ([tv isEqual:leftSideController.thumbnailTableView]) { NSUInteger idx = [rowIndexes firstIndex]; if (idx != NSNotFound && [[pdfView document] isLocked] == NO) { PDFPage *page = [[pdfView document] pageAtIndex:idx]; NSString *fileExt = nil; NSData *tiffData = [page TIFFDataForRect:[page boundsForBox:[pdfView displayBox]]]; if ([[pdfView document] allowsPrinting]) { NSData *pdfData = [page dataRepresentation]; fileExt = @"pdf"; [pboard declareTypes:[NSArray arrayWithObjects:NSPasteboardTypePDF, NSPasteboardTypeTIFF,NSFilenamesPboardType, NSFilesPromisePboardType, KPDFThumbnailLocalForDraggedTypes,KPDFThumbnailDoucumentURLForDraggedTypes,nil] owner:self]; [pboard setData:pdfData forType:NSPasteboardTypePDF]; NSData *zNSIndexSetData = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes]; [pboard setData:zNSIndexSetData forType:KPDFThumbnailLocalForDraggedTypes]; NSData *documentURL = [NSKeyedArchiver archivedDataWithRootObject:[[pdfView document].documentURL absoluteString]]; NSString *docmentName = [[[pdfView.document.documentURL path] lastPathComponent] stringByDeletingPathExtension]; __block NSMutableString *pagesName = nil; if (rowIndexes.count > 1) { pagesName = [NSMutableString stringWithString:@" pages"]; } else { pagesName = [NSMutableString stringWithString:@" page"]; } NSString * tFileName = [NSString stringWithFormat:@"%@ %@",pagesName,[self fileNameWithSelectedPages:rowIndexes]]; PDFDocument * pdf = [[[PDFDocument alloc] init] autorelease]; [rowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { PDFPage *copyPage = [[pdfView.document pageAtIndex:idx] copy]; [pdf insertPage:copyPage atIndex:pdf.pageCount]; [copyPage release]; }]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSString *cachesDir = [paths objectAtIndex:0]; docmentName = [NSString stringWithFormat:@"%@%@",docmentName,tFileName]; if (docmentName.length > 50) { [docmentName substringWithRange:NSMakeRange(0, 50)]; } cachesDir = [[cachesDir stringByAppendingPathComponent:docmentName] stringByAppendingPathExtension:@"pdf"]; BOOL success = [pdf writeToFile:cachesDir]; if (success) { [pboard setPropertyList:@[cachesDir] forType:NSFilenamesPboardType]; }else{ [pboard setPropertyList:@[@""] forType:NSFilenamesPboardType]; } [pboard setData:documentURL forType:KPDFThumbnailDoucumentURLForDraggedTypes]; } else { fileExt = @"tiff"; [pboard declareTypes:[NSArray arrayWithObjects:NSPasteboardTypeTIFF, NSFilesPromisePboardType, nil] owner:self]; } [pboard setData:tiffData forType:NSPasteboardTypeTIFF]; [pboard setPropertyList:[NSArray arrayWithObject:fileExt] forType:NSFilesPromisePboardType]; return YES; } } else if ([tv isEqual:rightSideController.snapshotTableView]) { NSUInteger idx = [rowIndexes firstIndex]; if (idx != NSNotFound) { SKSnapshotWindowController *snapshot = [self objectInSnapshotsAtIndex:idx]; [pboard declareTypes:[NSArray arrayWithObjects:NSPasteboardTypeTIFF, NSFilesPromisePboardType, nil] owner:self]; [pboard setData:[[snapshot thumbnailWithSize:0.0] TIFFRepresentation] forType:NSPasteboardTypeTIFF]; [pboard setPropertyList:[NSArray arrayWithObject:@"tiff"] forType:NSFilesPromisePboardType]; return YES; } } return NO; } - (NSArray *)tableView:(NSTableView *)tv namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes { if ([tv isEqual:leftSideController.thumbnailTableView]) { __block NSMutableArray *fileURLArray = [NSMutableArray array]; if (rowIndexes.count > 1) { NSString *docmentName = @""; NSString * tFileName = [NSString stringWithFormat:@"%@",[self fileNameWithSelectedPages:rowIndexes]]; PDFDocument *pdf = [[[PDFDocument alloc] init] autorelease]; [rowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { if (idx != NSNotFound && [[pdfView document] isLocked] == NO) { PDFPage *copyPage = [[[pdfView document] pageAtIndex:idx] copy]; [pdf insertPage:copyPage atIndex:pdf.pageCount]; [copyPage release]; } }]; NSURL *fileURL = [[[dropDestination URLByAppendingPathComponent:tFileName] URLByAppendingPathExtension:@"pdf"] uniqueFileURL]; docmentName = fileURL.path; BOOL success = [pdf writeToFile:docmentName]; if(success) { [fileURLArray addObject:[fileURL lastPathComponent]]; } } else { PDFPage *page = [[pdfView document] pageAtIndex:rowIndexes.firstIndex]; NSURL *fileURL = [dropDestination URLByAppendingPathComponent:[self draggedFileNameForPage:page]]; NSString *pathExt = nil; NSData *data = nil; if ([[pdfView document] allowsPrinting]) { pathExt = @"pdf"; data = [page dataRepresentation]; } else { pathExt = @"tiff"; data = [page TIFFDataForRect:[page boundsForBox:[pdfView displayBox]]]; } fileURL = [[fileURL URLByAppendingPathExtension:pathExt] uniqueFileURL]; if ([data writeToURL:fileURL atomically:YES]) { [fileURLArray addObject:[fileURL lastPathComponent]]; } } return fileURLArray; } else if ([tv isEqual:rightSideController.snapshotTableView]) { NSUInteger idx = [rowIndexes firstIndex]; if (idx != NSNotFound) { SKSnapshotWindowController *snapshot = [self objectInSnapshotsAtIndex:idx]; PDFPage *page = [[pdfView document] pageAtIndex:[snapshot pageIndex]]; NSURL *fileURL = [[dropDestination URLByAppendingPathComponent:[self draggedFileNameForPage:page]] URLByAppendingPathExtension:@"tiff"]; fileURL = [fileURL uniqueFileURL]; if ([[[snapshot thumbnailWithSize:0.0] TIFFRepresentation] writeToURL:fileURL atomically:YES]) return [NSArray arrayWithObjects:[fileURL lastPathComponent], nil]; } } return [NSArray array]; } - (void)tableView:(NSTableView *)tv sortDescriptorsDidChange:(NSArray *)oldDescriptors { if ([tv isEqual:leftSideController.groupedFindTableView]) { [leftSideController.groupedFindArrayController setSortDescriptors:[tv sortDescriptors]]; } } #pragma mark NSTableView delegate protocol - (void)tableViewSelectionDidChange:(NSNotification *)aNotification { if ([[aNotification object] isEqual:leftSideController.findTableView] || [[aNotification object] isEqual:leftSideController.groupedFindTableView]) { [self updateFindResultHighlightsForDirection:NSDirectSelection]; if ([self interactionMode] == SKPresentationMode && [[NSUserDefaults standardUserDefaults] boolForKey:SKAutoHidePresentationContentsKey]) [self hideLeftSideWindow]; } else if ([[aNotification object] isEqual:leftSideController.thumbnailTableView]) { if (mwcFlags.updatingThumbnailSelection == 0) { NSInteger row = [leftSideController.thumbnailTableView selectedRow]; NSInteger curPage = [pdfView.document indexForPage:pdfView.currentPage]; if (row != -1 && row != curPage) [pdfView goToPage:[[pdfView document] pageAtIndex:row]]; if ([self interactionMode] == SKPresentationMode && [[NSUserDefaults standardUserDefaults] boolForKey:SKAutoHidePresentationContentsKey]) [self hideLeftSideWindow]; thumbnailSelectCount = row; NSMutableIndexSet *rowIndexSet = [[[NSMutableIndexSet alloc] init] autorelease]; for (NSInteger i = 0; i < leftSideController.thumbnailTableView.numberOfRows; i ++) { [rowIndexSet addIndex:i]; } NSMutableIndexSet *columnIndexSet = [[[NSMutableIndexSet alloc] init] autorelease]; [columnIndexSet addIndex:0]; [leftSideController.thumbnailTableView reloadDataForRowIndexes:rowIndexSet columnIndexes:columnIndexSet]; } } else if ([[aNotification object] isEqual:rightSideController.snapshotTableView]) { NSInteger row = [rightSideController.snapshotTableView selectedRow]; [selectCellList removeAllObjects]; [selectCellList addObject:[NSString stringWithFormat:@"%ld",row]]; if (row != -1) { SKSnapshotWindowController *controller = [[rightSideController.snapshotArrayController arrangedObjects] objectAtIndex:row]; if ([[controller window] isVisible]) [[controller window] orderFront:self]; } NSMutableIndexSet *rowIndexSet = [[[NSMutableIndexSet alloc] init] autorelease]; for (NSInteger i = 0; i < rightSideController.snapshotTableView.numberOfRows; i ++) { [rowIndexSet addIndex:i]; } NSMutableIndexSet *columnIndexSet = [[[NSMutableIndexSet alloc] init] autorelease]; [columnIndexSet addIndex:0]; [rightSideController.snapshotTableView reloadDataForRowIndexes:rowIndexSet columnIndexes:columnIndexSet]; } } - (BOOL)tableView:(NSTableView *)tv commandSelectRow:(NSInteger)row { if ([tv isEqual:leftSideController.thumbnailTableView]) { // NSRect rect = [[[pdfView document] pageAtIndex:row] boundsForBox:kPDFDisplayBoxCropBox]; // // rect.origin.y = NSMidY(rect) - 0.5 * SNAPSHOT_HEIGHT; // rect.size.height = SNAPSHOT_HEIGHT; // [self showSnapshotAtPageNumber:row forRect:rect scaleFactor:[pdfView scaleFactor] autoFits:NO]; KMThumbnailTableviewCell *thumbailTabCell = [tv viewAtColumn:0 row:row makeIfNecessary:YES]; thumbailTabCell.isSelectCell = YES; NSMutableIndexSet *rowIndexSet = [[[NSMutableIndexSet alloc] init] autorelease]; [leftSideController.thumbnailTableView.selectedRowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { [rowIndexSet addIndex:idx]; }]; [rowIndexSet addIndex:row]; [leftSideController.thumbnailTableView selectRowIndexes:rowIndexSet byExtendingSelection:YES]; return YES; } return NO; } - (BOOL)tableView:(NSTableView *)tv shiftSelectRow:(NSInteger)row { if ([tv isEqual:leftSideController.thumbnailTableView]) { if(leftSideController.thumbnailTableView.selectedRowIndexes.count == 0) { KMThumbnailTableviewCell *thumbailTabCell = [tv viewAtColumn:0 row:row makeIfNecessary:YES]; thumbailTabCell.isSelectCell = YES; NSMutableIndexSet *rowIndexSet = [[[NSMutableIndexSet alloc] initWithIndex:row] autorelease]; [leftSideController.thumbnailTableView selectRowIndexes:rowIndexSet byExtendingSelection:YES]; return YES; } else if (leftSideController.thumbnailTableView.selectedRowIndexes.count == 1 && leftSideController.thumbnailTableView.selectedRowIndexes.firstIndex == (NSUInteger)row) { return NO; } else { __block NSInteger fristIndex = leftSideController.thumbnailTableView.selectedRowIndexes.firstIndex; __block NSInteger lastIndex = leftSideController.thumbnailTableView.selectedRowIndexes.lastIndex; [leftSideController.thumbnailTableView.selectedRowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { if(idx < (NSUInteger)fristIndex) { fristIndex = idx; } if(idx > (NSUInteger)lastIndex) { lastIndex = idx; } }]; if(row < fristIndex) { fristIndex = row; } else if (row > lastIndex) { lastIndex = row; } NSMutableIndexSet *rowIndexSet = [[[NSMutableIndexSet alloc] init] autorelease]; for (NSInteger i = fristIndex; i<=lastIndex;i++) { [rowIndexSet addIndex:i]; } [leftSideController.thumbnailTableView selectRowIndexes:rowIndexSet byExtendingSelection:YES]; return YES; } } return NO; } - (void)tableViewColumnDidResize:(NSNotification *)aNotification { if ([[[[aNotification userInfo] objectForKey:@"NSTableColumn"] identifier] isEqualToString:IMAGE_COLUMNID]) { if ([[aNotification object] isEqual:leftSideController.thumbnailTableView]) { [leftSideController.thumbnailTableView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [leftSideController.thumbnailTableView numberOfRows])]]; } else if ([[aNotification object] isEqual:rightSideController.snapshotTableView]) { [rightSideController.snapshotTableView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [rightSideController.snapshotTableView numberOfRows])]]; } } } - (void)tableView:(NSTableView *)tv deleteRowsWithIndexes:(NSIndexSet *)rowIndexes { if (![[IAPProductsManager defaultManager] isAvailableAllFunction]) { [[KMPurchaseCompareWindowController sharedInstance] showWindow:nil]; return; } if ([tv isEqual:rightSideController.snapshotTableView]) { NSArray *controllers = [[rightSideController.snapshotArrayController arrangedObjects] objectsAtIndexes:rowIndexes]; [controllers makeObjectsPerformSelector:@selector(close)]; } else if ([tv isEqual:leftSideController.thumbnailTableView]) { [rowIndexes enumerateIndexesWithOptions:NSEnumerationReverse usingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { if (idx >= [[pdfView document] pageCount]) { return; } for (PDFAnnotation *item in [[[pdfView document] pageAtIndex:idx] notes]){ [pdfView removeAnnotation:item]; } PDFPage *page = [[pdfView document] pageAtIndex:idx]; [[[[self document] undoManager] prepareWithInvocationTarget:self] insertPage:page pageAtIndex:idx]; [[pdfView document] removePageAtIndex:idx]; }]; [pdfView layoutDocumentView]; [pageLabels setArray:[[pdfView document] pageLabels]]; [self resetThumbnails]; NSUInteger idx = [rowIndexes firstIndex]; NSInteger index = MIN(idx, [[pdfView document] pageCount]-1); [pdfView goToPage:[[pdfView document] pageAtIndex:index]]; } } - (void)insertPage:(PDFPage*)page pageAtIndex:(NSInteger)index { [[[[self document] undoManager] prepareWithInvocationTarget:self] tableView:leftSideController.thumbnailTableView deleteRowsWithIndexes:[NSIndexSet indexSetWithIndex:index]]; [[pdfView document] insertPage:page atIndex:index]; [pdfView layoutDocumentView]; [pageLabels setArray:[[pdfView document] pageLabels]]; [self resetThumbnails]; NSInteger pageIndex = MIN((NSUInteger)index, [[pdfView document] pageCount]-1); [pdfView goToPage:[[pdfView document] pageAtIndex:pageIndex]]; } - (BOOL)tableView:(NSTableView *)tv canDeleteRowsWithIndexes:(NSIndexSet *)rowIndexes { if ([tv isEqual:rightSideController.snapshotTableView]) { return [rowIndexes count] > 0; } else if ([tv isEqual:leftSideController.thumbnailTableView]){ if (self.pdfDocument.pageCount <= 1) { return NO; } return YES; } return NO; } - (void)tableView:(NSTableView *)tv copyRowsWithIndexes:(NSIndexSet *)rowIndexes { if (![IAPProductsManager defaultManager].isAvailableAllFunction) { [[KMPurchaseCompareWindowController sharedInstance] showWindow:nil]; return; } if ([tv isEqual:leftSideController.thumbnailTableView]) { self.copysPages = [NSMutableArray array]; if ([[pdfView document] isLocked] == NO) { [rowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { PDFPage *page = [[pdfView document] pageAtIndex:idx]; [self.copysPages addObject:page]; }]; // NSData *tiffData = [page TIFFDataForRect:[page boundsForBox:[pdfView displayBox]]]; // NSPasteboard *pboard = [NSPasteboard generalPasteboard]; // NSPasteboardItem *pboardItem = [[[NSPasteboardItem alloc] init] autorelease]; // if ([[pdfView document] allowsPrinting]) // [pboardItem setData:[page dataRepresentation] forType:NSPasteboardTypePDF]; // [pboardItem setData:tiffData forType:NSPasteboardTypeTIFF]; // [pboard clearContents]; // [pboard writeObjects:[NSArray arrayWithObjects:pboardItem, nil]]; } } else if ([tv isEqual:leftSideController.findTableView]) { NSMutableString *string = [NSMutableString string]; [rowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { PDFSelection *match = [searchResults objectAtIndex:idx]; [string appendString:@"* "]; [string appendFormat:NSLocalizedString(@"Page %@", @""), [match firstPageLabel]]; [string appendFormat:@": %@\n", [[match contextString] string]]; }]; NSPasteboard *pboard = [NSPasteboard generalPasteboard]; [pboard clearContents]; [pboard writeObjects:[NSArray arrayWithObjects:string, nil]]; } else if ([tv isEqual:leftSideController.groupedFindTableView]) { NSMutableString *string = [NSMutableString string]; [rowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { SKGroupedSearchResult *result = [groupedSearchResults objectAtIndex:idx]; NSArray *matches = [result matches]; [string appendString:@"* "]; [string appendFormat:NSLocalizedString(@"Page %@", @""), [[result page] displayLabel]]; [string appendString:@": "]; [string appendFormat:NSLocalizedString(@"%ld Results", @""), (long)[matches count]]; [string appendFormat:@":\n\t%@\n", [[matches valueForKeyPath:@"contextString.string"] componentsJoinedByString:@"\n\t"]]; }]; NSPasteboard *pboard = [NSPasteboard generalPasteboard]; [pboard clearContents]; [pboard writeObjects:[NSArray arrayWithObjects:string, nil]]; } } - (BOOL)tableView:(NSTableView *)tv canCopyRowsWithIndexes:(NSIndexSet *)rowIndexes { if ([tv isEqual:leftSideController.thumbnailTableView] || [tv isEqual:leftSideController.findTableView] || [tv isEqual:leftSideController.groupedFindTableView]) { return [rowIndexes count] > 0; } return NO; } - (void)tableView:(NSTableView *)tv cutRowsWithIndexes:(NSIndexSet *)rowIndexes { if ([tv isEqual:leftSideController.thumbnailTableView]) { self.copysPages = [NSMutableArray array]; [rowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { if (idx != NSNotFound) { PDFPage *page = [[pdfView document] pageAtIndex:idx]; [self.copysPages addObject:page];; } }]; [self tableView:tv deleteRowsWithIndexes:rowIndexes]; } } - (void)tableView:(NSTableView *)tv rotateRowsWithIndexes:(NSIndexSet *)rowIndexes { if ([tv isEqual:leftSideController.thumbnailTableView]) { [rowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { if (idx != NSNotFound) { PDFPage *page = [[pdfView document] pageAtIndex:idx]; [[[[self document] undoManager] prepareWithInvocationTarget:self] rotatePage:page pageAtIndex:idx]; if (page.rotation == 0) { [page setRotation:90]; } else if (page.rotation == 90){ [page setRotation:180]; } else if (page.rotation == 180){ [page setRotation:270]; } else if (page.rotation == 270){ [page setRotation:0]; } [pdfView layoutDocumentView]; [self resetThumbnails]; NSInteger pageIndex = MIN(idx, [[pdfView document] pageCount]-1); [pdfView goToPage:[[pdfView document] pageAtIndex:pageIndex]]; } [leftSideController.thumbnailTableView selectRowIndexes:rowIndexes byExtendingSelection:YES]; }]; } } - (void)rotatePage:(PDFPage*)page pageAtIndex:(NSInteger)index { [[[[self document] undoManager] prepareWithInvocationTarget:self] tableView:leftSideController.thumbnailTableView rotateRowsWithIndexes:[NSIndexSet indexSetWithIndex:index]]; if (page.rotation == 0) { [page setRotation:270]; } else if (page.rotation == 90){ [page setRotation:0]; } else if (page.rotation == 180){ [page setRotation:90]; } else if (page.rotation == 270){ [page setRotation:180]; } [pdfView layoutDocumentView]; [self resetThumbnails]; } - (void)tableView:(NSTableView *)tv shareRowsWithIndexes:(NSIndexSet *)rowIndexes { if ([tv isEqual:leftSideController.thumbnailTableView]) { NSUInteger idx = [rowIndexes firstIndex]; if (idx != NSNotFound) { PDFPage *page = [[pdfView document] pageAtIndex:idx]; NSString *fileName = [[[pdfView document] documentURL] lastPathComponent]; NSString *folderPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *filePath = [folderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"Untitled"]]; filePath = [filePath stringByAppendingPathExtension:[fileName pathExtension]]; [self fileWithPage:page atPath:filePath]; if (rint(NSAppKitVersionNumber) < NSAppKitVersionNumber10_8) { [KMMailHelper sendFileWithPaths:[NSArray arrayWithObject:filePath]]; } else { NSSharingService *service = [NSSharingService sharingServiceNamed:NSSharingServiceNameComposeEmail]; [service performWithItems:[NSArray arrayWithObject:[NSURL fileURLWithPath:filePath]]]; } } } } - (void)tableView:(NSTableView *)tv extractRowsWithIndexes:(NSIndexSet *)rowIndexes { if ([tv isEqual:leftSideController.thumbnailTableView]) { NSMutableArray *pages = [NSMutableArray array]; [leftSideController.thumbnailTableView.selectedRowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { if (idx < self.pdfView.document.pageCount) { [pages addObject:[self.pdfView.document pageAtIndex:idx]]; } }]; NSString * fileName = [self.pdfView.document getFileNameAccordingSelctPages:pages]; KMSavePanelAccessoryController *saveAccessCtr = [[KMSavePanelAccessoryController alloc] init]; NSSavePanel * outputSavePanel = [NSSavePanel savePanel]; [outputSavePanel setAllowedFileTypes:[NSArray arrayWithObject:@"pdf"]]; outputSavePanel.accessoryView = saveAccessCtr.view; [outputSavePanel setNameFieldStringValue:fileName]; [outputSavePanel beginSheetModalForWindow:[self window]completionHandler:^(NSInteger result) { if (result == NSModalResponseOK) { [saveAccessCtr retain]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ KMProgressWindowController * vc = [[[KMProgressWindowController alloc] init] autorelease]; // [NSApp beginSheet:[vc window] // modalForWindow:self.window // modalDelegate:nil // didEndSelector:nil // contextInfo:NULL]; [self.window beginSheet:[vc window] completionHandler:^(NSModalResponse returnCode) { }]; NSString *saveFilePath = [[outputSavePanel URL] path]; dispatch_async(dispatch_get_global_queue(0, 0), ^{ PDFDocument * pdf = [[[PDFDocument alloc] init] autorelease]; BOOL success = [pdf extractAsOneDocumentWithPages:pages savePath:saveFilePath]; dispatch_async(dispatch_get_main_queue(), ^{ if (success) { if (saveAccessCtr.openAutomaticButton.state == NSControlStateValueOn) { [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:[outputSavePanel URL] display:YES completionHandler:^(NSDocument * _Nullable document, BOOL documentWasAlreadyOpen, NSError * _Nullable error) { }]; } else { NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; NSURL *url = [NSURL fileURLWithPath:saveFilePath]; [workspace activateFileViewerSelectingURLs:[NSArray arrayWithObject:url]]; } } [NSApp endSheet:vc.window]; [vc close]; [saveAccessCtr release]; }); }); }); } [saveAccessCtr release]; }]; } } - (void)fileWithPage:(PDFPage *)page atPath:(NSString *)filePath { NSData *data = [page dataRepresentation]; PDFDocument *document = [[PDFDocument alloc] initWithData:data]; [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil]; BOOL success = [document writeToURL:[NSURL fileURLWithPath:filePath]]; if (success) { NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; NSURL *url = [NSURL fileURLWithPath:filePath]; [workspace activateFileViewerSelectingURLs:[NSArray arrayWithObject:url]]; } [document release]; } - (BOOL)tableView:(NSTableView *)aTableView canPasteFromPasteboard:(NSPasteboard *)pboard { if ([aTableView isEqual:leftSideController.thumbnailTableView]) { if(self.copysPages.count > 0){ return YES; } } return NO; } - (void)tableView:(NSTableView *)aTableView pasteFromPasteboard:(NSPasteboard *)pboard { if (![IAPProductsManager defaultManager].isAvailableAllFunction) { [[KMPurchaseCompareWindowController sharedInstance] showWindow:nil]; return; } if ([aTableView isEqual:leftSideController.thumbnailTableView]) { if (self.copysPages.count > 0) { NSUInteger index = [[pdfView document] indexForPage:[pdfView currentPage]] + 1; if (index == NSNotFound) { return; } [self.copysPages enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(PDFPage * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { PDFPage *page = [obj copy]; [[pdfView document] insertPage:page atIndex:index]; [page release]; [pdfView layoutDocumentView]; [pageLabels setArray:[[pdfView document] pageLabels]]; [self resetThumbnails]; NSInteger pageIndex = MIN(index, [[pdfView document] pageCount]-1); [pdfView goToPage:[[pdfView document] pageAtIndex:pageIndex]]; [[[[self document] undoManager] prepareWithInvocationTarget:self] tableView:leftSideController.thumbnailTableView deleteRowsWithIndexes:[NSIndexSet indexSetWithIndex:index]]; }]; } } } - (NSUInteger)tableView:(NSTableView *)tv highlightLevelForRow:(NSInteger)row { if ([tv isEqual:leftSideController.thumbnailTableView]) { NSUInteger i, iMax = [lastViewedPages count]; for (i = 0; i < iMax; i++) { if (row == (NSInteger)[lastViewedPages pointerAtIndex:i]) return i; } } return NSNotFound; } - (void)tableViewMoveLeft:(NSTableView *)tv { if (([tv isEqual:leftSideController.findTableView] || [tv isEqual:leftSideController.groupedFindTableView])) { [self updateFindResultHighlightsForDirection:NSSelectingPrevious]; } } - (void)tableViewMoveRight:(NSTableView *)tv { if (([tv isEqual:leftSideController.findTableView] || [tv isEqual:leftSideController.groupedFindTableView])) { [self updateFindResultHighlightsForDirection:NSSelectingNext]; } } - (id )tableView:(NSTableView *)tv imageContextForRow:(NSInteger)row { if ([tv isEqual:leftSideController.findTableView]) return [[[leftSideController.findArrayController arrangedObjects] objectAtIndex:row] destination]; else if ([tv isEqual:leftSideController.groupedFindTableView]) return [[[[[leftSideController.groupedFindArrayController arrangedObjects] objectAtIndex:row] matches] objectAtIndex:0] destination]; return nil; } - (NSArray *)tableView:(NSTableView *)tv typeSelectHelperSelectionStrings:(SKTypeSelectHelper *)typeSelectHelper { if ([tv isEqual:leftSideController.thumbnailTableView]) { return pageLabels; } return nil; } - (void)tableView:(NSTableView *)tv typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper didFailToFindMatchForSearchString:(NSString *)searchString { if ([tv isEqual:leftSideController.thumbnailTableView]) { [statusBar setLeftStringValue:[NSString stringWithFormat:NSLocalizedString(@"No match: \"%@\"", @"Status message"), searchString]]; } } - (void)tableView:(NSTableView *)tv typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper updateSearchString:(NSString *)searchString { if ([tv isEqual:leftSideController.thumbnailTableView]) { if (searchString.length > 0) [statusBar setLeftStringValue:[NSString stringWithFormat:NSLocalizedString(@"Go to page: %@", @"Status message"), searchString]]; else [self updateLeftStatus]; } } #pragma mark dragging - (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id )info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation { if (dropOperation == NSTableViewDropOn || ![tableView isEqual:leftSideController.thumbnailTableView]) { return NSDragOperationNone; } NSPasteboard *pboard = [info draggingPasteboard]; if ([pboard availableTypeFromArray:[NSArray arrayWithObject:KPDFThumbnailLocalForDraggedTypes]]) { return NSDragOperationMove; } else if ([pboard availableTypeFromArray:[NSArray arrayWithObject:NSFilenamesPboardType]] && [tableView isEqual:leftSideController.thumbnailTableView]){ NSArray *fileNames = [pboard propertyListForType:NSFilenamesPboardType]; if (fileNames.count == 1) { NSString *path = fileNames.firstObject; NSString *pathExtension = [path.pathExtension lowercaseString]; if ([pathExtension isEqualToString:@"pdf"] || [[KMImageToPDFMethod supportedImageTypes] containsObject:pathExtension]) { return NSDragOperationMove; } } else { return NSDragOperationNone; } } return NSDragOperationNone; } - (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id )info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation { __block BOOL result = NO; if (![tableView isEqual:leftSideController.thumbnailTableView]) { return result; } NSPasteboard *pasteboard = [info draggingPasteboard]; if ([pasteboard availableTypeFromArray:[NSArray arrayWithObject:KPDFThumbnailLocalForDraggedTypes]]) { result = YES; NSData *rowData = [pasteboard dataForType:KPDFThumbnailLocalForDraggedTypes]; NSIndexSet *rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:rowData]; NSData *urlData = [pasteboard dataForType:KPDFThumbnailDoucumentURLForDraggedTypes]; NSString *url = [NSKeyedUnarchiver unarchiveObjectWithData:urlData]; if(![url isEqualToString:[pdfView document].documentURL.absoluteString] && url) { if ([pasteboard availableTypeFromArray:[NSArray arrayWithObject:NSFilenamesPboardType]]){ NSArray *fileNames = [pasteboard propertyListForType:NSFilenamesPboardType]; if (fileNames.count == 1) { NSString *path = fileNames.firstObject; NSString *pathExtension = [path.pathExtension lowercaseString]; if ([pathExtension isEqualToString:@"pdf"]) { __block NSInteger index = row; __block NSMutableIndexSet *insertIndexSet = [[[NSMutableIndexSet alloc] init] autorelease]; PDFDocument *pdf = [[[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:path]] autorelease]; if ([pdf isEncrypted]) { KMDecryptWindowController *vc = [[KMDecryptWindowController alloc] init]; vc.filePath = url; [vc beginSheetModalForWindow:self.window completionHandler:^(NSString *password) { if (password) { [pdf unlockWithPassword:password]; for(NSUInteger i=0; i Int { if outlineView.isEqual(to: self.tocOutlineView) { if item == nil && self.listView.document.isLocked == false { // if (item == nil && [[pdfView document] isLocked] == NO) { // item = [[pdfView document] outlineRoot]; var item = self.listView.document.outlineRoot() if let data = item?.numberOfChildren, data == 0 && !self.isSearchOutlineMode { let view = self.tocOutlineView.enclosingScrollView // CGSize emptyVcSize = self.leftSideEmptyVC.emptyOutlineView.frame.size; // self.leftSideEmptyVC.emptyOutlineView.frame = NSMakeRect((view.frame.size.width-emptyVcSize.width)/2.0,(view.frame.size.height-emptyVcSize.height)/2.0, emptyVcSize.width, emptyVcSize.height); // self.leftSideEmptyVC.emptyOutlineView.autoresizingMask = NSViewMinXMargin | NSViewMaxXMargin| NSViewMaxYMargin | NSViewMinYMargin; // [leftSideController.tocOutlineView.enclosingScrollView.documentView addSubview:self.leftSideEmptyVC.emptyOutlineView]; // self.leftSideEmptyVC.deleteOutlineBtn.enabled = NO; } else { // [self.leftSideEmptyVC.emptyOutlineView removeFromSuperview]; // self.leftSideEmptyVC.deleteOutlineBtn.enabled = YES; } // PDFOutline *item = [[pdfView document] outlineRoot]; if let data = item?.numberOfChildren, data > 0 { self.outlineSearchButton.isEnabled = true } else { self.outlineSearchButton.isEnabled = false } if (self.isSearchOutlineMode) { if self._hasContainString(self.outlineSearchField.stringValue, rootOutline: item!) { // [self showSearchOutlineBlankState:NO]; } else { // [self showSearchOutlineBlankState:YES]; } } return Int(item?.numberOfChildren ?? 0) } if (self.isSearchOutlineMode) { // var num = 0 // for (NSUInteger i = 0; i < [(PDFOutline *)item numberOfChildren]; i++) { // PDFOutline *outline = [(PDFOutline *)item childAtIndex:i]; // if ([self hasContainString:self.leftSideController.outlineSearchField.stringValue rootOutline:outline]) { // num ++; // } // } // return num; } else { // return [(PDFOutline *)item numberOfChildren]; } return Int((item as? CPDFOutline)?.numberOfChildren ?? 0) } else if outlineView.isEqual(to: self.noteOutlineView) { if (item == nil){ // NSInteger count = [[rightSideController.noteArrayController arrangedObjects] count]; // if (count < 1) { // if (notes.count < 1) { // leftSideController.noteSearchButton.enabled = NO; // leftSideController.noteFilterButton.enabled = NO; // } // // rightSideController.noteOutlineView.usesAlternatingRowBackgroundColors = NO; // NSView *view = rightSideController.noteOutlineView.enclosingScrollView; // CGSize emptyVcSize = self.leftSideEmptyVC.emptyAnnotationView.frame.size; // self.leftSideEmptyVC.emptyAnnotationView.frame = NSMakeRect((view.frame.size.width-emptyVcSize.width)/2.0,(view.frame.size.height-emptyVcSize.height)/2.0, emptyVcSize.width, emptyVcSize.height); // self.leftSideEmptyVC.emptyAnnotationView.autoresizingMask = NSViewMinXMargin | NSViewMaxXMargin | NSViewMaxYMargin | NSViewMinYMargin; // [rightSideController.noteOutlineView.enclosingScrollView.documentView addSubview:self.leftSideEmptyVC.emptyAnnotationView]; // self.leftSideEmptyVC.exportAnnotationBtn.enabled = NO; // self.leftSideEmptyVC.deleteAnnotationBtn.enabled = NO; // // if (leftSideController.segmentedControl.selectedSegment == KMSelectedSegmentType_Annotation) { // leftSideController.noteHeaderView.hidden = YES; // leftSideController.toolButtonBoxLayoutConstraint.constant = 40.0; // } // } else { // leftSideController.noteSearchButton.enabled = YES; // leftSideController.noteFilterButton.enabled = YES; // // rightSideController.noteOutlineView.usesAlternatingRowBackgroundColors = NO; // // [self.leftSideEmptyVC.emptyAnnotationView removeFromSuperview]; // self.leftSideEmptyVC.exportAnnotationBtn.enabled = YES; // self.leftSideEmptyVC.deleteAnnotationBtn.enabled = YES; // // if (leftSideController.segmentedControl.selectedSegment == KMSelectedSegmentType_Annotation) { // leftSideController.noteHeaderView.hidden = NO; // leftSideController.toolButtonBoxLayoutConstraint.constant = 64.0; // } // } // return count; } else { // return [item hasNoteText]; } } return 0 } // child func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any { if outlineView.isEqual(to: self.tocOutlineView) { var _item: CPDFOutline? if item == nil && self.listView.document.isLocked == false { _item = self.listView.document.outlineRoot() } var obj = _item?.child(at: UInt(index)) // if (self.isSearchOutlineMode) { // NSMutableArray *array = [NSMutableArray array]; // for (NSUInteger i = 0; i < [(PDFOutline *)item numberOfChildren]; i ++) { // PDFOutline *subOutline = [(PDFOutline *)item childAtIndex:i]; // if ([self hasContainString:self.leftSideController.outlineSearchField.stringValue rootOutline:subOutline]) { // [array addObject:subOutline]; // } // } // return [array objectAtIndex:anIndex]; // } else { // return obj; // } return obj as Any } else if outlineView.isEqual(to: self.noteOutlineView) { // if (item == nil) // { // return [[rightSideController.noteArrayController arrangedObjects] objectAtIndex:anIndex]; // // return [self.notes objectAtIndex:anIndex]; // } // else // return [item noteText]; } return item } func outlineView(_ outlineView: NSOutlineView, objectValueFor tableColumn: NSTableColumn?, byItem item: Any?) -> Any? { if outlineView.isEqual(to: self.tocOutlineView) { let tcID = tableColumn?.identifier.rawValue ?? "" var ol = item as? CPDFOutline if(tcID == LABEL_COLUMNID) { if (self.isSearchOutlineMode) { // NSString *roughString = [[ol label] stringByCollapsingWhitespaceAndNewlinesAndRemovingSurroundingWhitespaceAndNewlines]? : @""; // NSArray *arr = [self allRangeOfRoughString:roughString searchString:self.leftSideController.outlineSearchField.stringValue]; // NSMutableAttributedString *attributeString = [[[NSMutableAttributedString alloc] initWithString:roughString] autorelease]; // for (NSUInteger i = 0; i NSView? { if outlineView.isEqual(to: self.tocOutlineView) { let cell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMTocTableCellView"), owner: self) as! KMTocTableCellView let tcID = tableColumn?.identifier.rawValue var ol = item as? CPDFOutline if tcID == LABEL_COLUMNID { if (self.isSearchOutlineMode) { // NSString *roughString = [[ol label] stringByCollapsingWhitespaceAndNewlinesAndRemovingSurroundingWhitespaceAndNewlines]; // NSArray *arr = [self allRangeOfRoughString:roughString searchString:self.leftSideController.outlineSearchField.stringValue]; // NSMutableAttributedString *attributeString = [[[NSMutableAttributedString alloc] initWithString:roughString] autorelease]; // // for (NSUInteger i = 0; i 0) { // cell.foldButton.hidden = NO; // } // NSMutableAttributedString *attributeStr = [[NSMutableAttributedString alloc]initWithString:noteTextString]; // if (markup.markupType == kPDFMarkupTypeHighlight) { // [attributeStr addAttribute:NSBackgroundColorAttributeName value:noteColor range:NSMakeRange(0, noteTextString.length)]; // } else if (markup.markupType == kPDFMarkupTypeStrikeOut) { // [attributeStr addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInt:NSUnderlineStyleSingle] range:NSMakeRange(0, noteTextString.length)]; // [attributeStr addAttribute:NSStrikethroughColorAttributeName value:noteColor range:NSMakeRange(0, noteTextString.length)]; // } else if (markup.markupType == kPDFMarkupTypeUnderline) { // [attributeStr addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:NSUnderlineStyleSingle] range:NSMakeRange(0, noteTextString.length)]; // [attributeStr addAttribute:NSUnderlineColorAttributeName value:noteColor range:NSMakeRange(0, noteTextString.length)]; // } // cell.annotationContentLabel.attributedStringValue = attributeStr; // // if (self.foldType == KMFoldAllAnnotationType_Unfold) { // cell.isFold = NO; // } else if (self.foldType == KMFoldAllAnnotationType_Fold) { // cell.isFold = YES; // } else { // if (rightSideController.allFoldNotes.count > 0 && [rightSideController.allFoldNotes containsObject:note]) { // cell.isFold = NO; // } else { // cell.isFold = YES; // } // } // if (noteString.length > 0 && noteTextString.length > 0) // [cell contentViewHidden:NO]; // else // [cell contentViewHidden:YES]; // } // // else if ([note isKindOfClass:[PDFAnnotationLine class]] || // [noteType isEqualToString:SKNSquareString] || // [noteType isEqualToString:SKNCircleString] || // [noteType isEqualToString:SKNInkString]) { // cell.annotationContentLabel.stringValue = noteString ? : @""; // if (noteString.length > 0) // [cell contentViewHidden:NO]; // else // [cell contentViewHidden:YES]; // } else if([note isKindOfClass:[PDFAnnotationStamp class]]) { // if ([note isKindOfClass:[KMSelfSignAnnotation class]]) { // KMSelfSignAnnotation *newAnnotation = (KMSelfSignAnnotation *)note; // KMSelfSignType type = newAnnotation.annotationType; // NSString *returnString = @""; // if (type == KMSelfSignTypeFalse) { // returnString = NSLocalizedString(@"X", nil); // } else if (type == KMSelfSignTypeTure) { // returnString = NSLocalizedString(@"Check mark", nil); // } else if (type == KMSelfSignTypeCircle) { // returnString = NSLocalizedString(@"Circle", nil); // } else if (type == KMSelfSignTypeLine) { // returnString = NSLocalizedString(@"Line", nil); // } else if (type == KMSelfSignTypeDot) { // returnString = NSLocalizedString(@"Dot", nil); // } else if (type == KMSelfSignTypeText) { // returnString = NSLocalizedString(@"Text", nil); // } // cell.annotationContentLabel.stringValue = returnString; // } else { // cell.annotationContentLabel.hidden = YES; // // cell.noteImageView.hidden = NO; // PDFAnnotation *annotation = note; // NSImage *stampImage = [self stampCreateImage:annotation]; // if (stampImage) { // cell.noteImageView.image = [self stampCreateImage:annotation]; // } else { // cell.noteImageView.hidden = YES; // [cell contentViewHidden:YES]; // } // } // } else if ([note isKindOfClass:[SKNPDFAnnotationNote class]]) { // cell.foldButton.hidden = NO; // if (!noteString || noteString.length < 1){ // cell.annotationContentLabel.stringValue = noteTextString; // }else{ // cell.annotationContentLabel.stringValue = noteString; // cell.noteContentLabel.stringValue = noteTextString; // } // // if (self.foldType == KMFoldAllAnnotationType_Unfold) { // cell.isFold = NO; // } else if (self.foldType == KMFoldAllAnnotationType_Fold) { // cell.isFold = YES; // } else { // if (rightSideController.allFoldNotes.count > 0 && [rightSideController.allFoldNotes containsObject:note]) { // cell.isFold = NO; // } else { // cell.isFold = YES; // } // } // if (noteString.length > 0 || noteTextString.length > 0) { // cell.contentView.hidden = NO; // } else { // cell.contentView.hidden = YES; // [cell contentViewHidden:YES]; // } // if (noteString.length > 0 && noteTextString.length > 0) { // cell.foldButton.hidden = NO; // }else{ // cell.foldButton.hidden = YES; // } // // } else { // cell.annotationContentLabel.stringValue = noteString; // cell.imageViewHeightConstraint.constant = cell.contentView.frame.size.height; // if (noteString.length > 0) // [cell contentViewHidden:NO]; // else // [cell contentViewHidden:YES]; // } // // cell.autherLayoutConstraint.constant = cell.autherLabel.hidden ? -(cell.autherLabel.bounds.size.width) + 10.0f : 10.0f; // cell.typeImageViewLayoutConstraint.constant = cell.typeImageView.hidden ? -(cell.typeImageView.bounds.size.width) : 0.0f; // cell.contentBoxLayoutConstraint.constant = cell.noteContentBox.hidden ? -(cell.noteContentBox.bounds.size.height+8.0) : 8.0f; // if ([note isKindOfClass:[PDFAnnotationStamp class]] && ![note isKindOfClass:[KMSelfSignAnnotation class]]) { // // } else { // if ([note isKindOfClass:[PDFAnnotationMarkup class]]) { // if (!cell.isFold) { // [rightSideController.allFoldNotes addObject:note]; // } else { // cell.imageViewHeightConstraint.constant = 18.0 + 8; // } // } else { // cell.imageViewHeightConstraint.constant = 18.0 + 8; // } // } // cell.isUnFoldNote = ^(PDFAnnotation *cellNote, BOOL isUnfold) { // if (isUnfold) { // if ([rightSideController.allFoldNotes containsObject:note]) { // [rightSideController.allFoldNotes removeObject:note]; // } // // if (rightSideController.allFoldNotes.count == 0) { // self.foldType = KMFoldAllAnnotationType_Fold; // } else { // self.foldType = KMFoldAllAnnotationType_None; // } // } else { // if (![rightSideController.allFoldNotes containsObject:note]) { // [rightSideController.allFoldNotes addObject:note]; // } // // if (rightSideController.allFoldNotes.count == rightSideController.canFoldNotes.count) { // self.foldType = KMFoldAllAnnotationType_Unfold; // } else { // self.foldType = KMFoldAllAnnotationType_None; // } // } // }; // // if (@available(macOS 10.13, *)) { // // } else { // cell.foldButton.hidden = YES; // } return cell } return nil } /* #pragma mark NSOutlineView datasource protocol - (BOOL)outlineView:(NSOutlineView *)ov isItemExpandable:(id)item{ if ([ov isEqual:leftSideController.tocOutlineView]) { if (item == nil && [[pdfView document] isLocked] == NO) item = [[pdfView document] outlineRoot]; if (self.isSearchOutlineMode) { return [self subOutLineContainString:self.leftSideController.outlineSearchField.stringValue rootOutline:(PDFOutline *)item]; } else { return ([(PDFOutline *)item numberOfChildren] > 0); } } else if ([ov isEqual:rightSideController.noteOutlineView]) { // return [item hasNoteText]; return NO; } return NO; } - (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item { } - (void)outlineView:(NSOutlineView *)ov setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item{ if ([ov isEqual:rightSideController.noteOutlineView]) { PDFAnnotation *note = item; if ([note type]) { if ([[tableColumn identifier] isEqualToString:NOTE_COLUMNID]) { if ([(object ?: @"") isEqualToString:([note string] ?: @"")] == NO) [note setString:object]; } else if ([[tableColumn identifier] isEqualToString:AUTHOR_COLUMNID]) { if ([(object ?: @"") isEqualToString:([note userName] ?: @"")] == NO) [note setUserName:object]; } } } } - (NSTableRowView *)outlineView:(NSOutlineView *)outlineView rowViewForItem:(id)item { if ([outlineView isEqual:leftSideController.tocOutlineView]) { KMCustomTableRowView *itemView = [[[KMCustomTableRowView alloc] init] autorelease]; return itemView; } else if ([outlineView isEqual:rightSideController.noteOutlineView]) { KMCustomTableRowView *itemView = [[[KMCustomTableRowView alloc] init] autorelease]; return itemView; } return nil; } #pragma mark Drag - (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pasteboard{ if ([outlineView isEqual:leftSideController.tocOutlineView]) { if (leftSideController.tocOutlineView.selectedRowIndexes.count > 1) { return NO; } NSIndexSet *tIndex = [[[NSIndexSet alloc] initWithIndex:leftSideController.tocOutlineView.clickedRow] autorelease]; [leftSideController.tocOutlineView deselectRow:tIndex.firstIndex]; self.dragPDFOutline = items.firstObject; NSIndexSet *set = [NSIndexSet indexSetWithIndex:0]; NSData *zNSIndexSetData = [NSKeyedArchiver archivedDataWithRootObject:set]; [pasteboard declareTypes:[NSArray arrayWithObject:kKMPDFViewOutlineDragDataType] owner:self]; [pasteboard setData:zNSIndexSetData forType:kKMPDFViewOutlineDragDataType]; return YES; } return NO; } - (NSDragOperation)outlineView:(NSOutlineView *)ov validateDrop:(id )info proposedItem:(id)item proposedChildIndex:(NSInteger)anIndex { NSDragOperation dragOp = NSDragOperationNone; if ([ov isEqual:rightSideController.noteOutlineView]) { NSPasteboard *pboard = [info draggingPasteboard]; if ([pboard canReadObjectForClasses:[NSArray arrayWithObject:[NSColor class]] options:[NSDictionary dictionary]] && anIndex == NSOutlineViewDropOnItemIndex && [(PDFAnnotation *)item type] != nil) dragOp = NSDragOperationEvery; } else if ([ov isEqual:leftSideController.tocOutlineView]) { if (anIndex == -1) { dragOp = NSDragOperationNone; } else { dragOp = NSDragOperationMove; } } return dragOp; } - (BOOL)outlineView:(NSOutlineView *)ov acceptDrop:(id )info item:(id)item childIndex:(NSInteger)anIndex { if ([ov isEqual:rightSideController.noteOutlineView]) { NSPasteboard *pboard = [info draggingPasteboard]; if ([pboard canReadObjectForClasses:[NSArray arrayWithObject:[NSColor class]] options:[NSDictionary dictionary]]) { BOOL isShift = ([NSEvent standardModifierFlags] & NSEventModifierFlagShift) != 0; BOOL isAlt = ([NSEvent standardModifierFlags] & NSEventModifierFlagOption) != 0; [item setColor:[NSColor colorFromPasteboard:pboard] alternate:isAlt updateDefaults:isShift]; return YES; } } else if ([ov isEqual:leftSideController.tocOutlineView]) { if (anIndex < 0) { return NO; } PDFOutline *outline = item; //root,drag item to root if (!outline.parent) { //fetch root PDFOutline *root = self.dragPDFOutline; while (root.parent) { root = root.parent; } if ([self.dragPDFOutline.parent isEqual:root]) { if (self.dragPDFOutline.index > (NSUInteger)anIndex) { [self dragPDFOutline:self.dragPDFOutline toIndex:anIndex newParentOutline:root]; } else { [self dragPDFOutline:self.dragPDFOutline toIndex:anIndex - 1 newParentOutline:root]; } } else { [self dragPDFOutline:self.dragPDFOutline toIndex:anIndex newParentOutline:root]; } } else { //在同一个层级内移动 if ([self.dragPDFOutline.parent isEqual:item]) { if (self.dragPDFOutline.index) { if (self.dragPDFOutline.index > (NSUInteger)anIndex) { [self dragPDFOutline:self.dragPDFOutline toIndex:anIndex newParentOutline:outline]; }else{ [self dragPDFOutline:self.dragPDFOutline toIndex:anIndex - 1 newParentOutline:outline]; } } else { return NO; } } else { PDFOutline *tOutlline = outline; BOOL isContains = NO; while (tOutlline) { if ([tOutlline isEqual:self.dragPDFOutline]) { isContains = YES; break; } tOutlline = tOutlline.parent; } if (!isContains) { [self dragPDFOutline:self.dragPDFOutline toIndex:anIndex newParentOutline:outline]; } } } return YES; } return NO; } #pragma mark NSOutlineView delegate protocol - (NSCell *)outlineView:(NSOutlineView *)ov dataCellForTableColumn:(NSTableColumn *)tableColumn item:(id)item { if ([ov isEqual:rightSideController.noteOutlineView] && tableColumn == nil && [(PDFAnnotation *)item type] == nil) { return [[ov tableColumnWithIdentifier:NOTE_COLUMNID] dataCellForRow:[ov rowForItem:item]]; } return [tableColumn dataCellForRow:[ov rowForItem:item]]; } - (void)outlineView:(NSOutlineView *)ov willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item { if ([ov isEqual:leftSideController.tocOutlineView] && [ov selectionHighlightStyle] == NSTableViewSelectionHighlightStyleRegular && [ov isRowSelected:[ov rowForItem:item]]) { [cell setBackgroundStyle:NSBackgroundStyleLowered]; } } - (BOOL)outlineView:(NSOutlineView *)ov shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item{ if ([ov isEqual:rightSideController.noteOutlineView]) { if (tableColumn == nil) { if ([pdfView hideNotes] == NO && [[(SKNoteText *)item note] isNote]) { PDFAnnotation *annotation = [(SKNoteText *)item note]; [pdfView scrollAnnotationToVisible:annotation]; [pdfView setActiveAnnotation:annotation]; [self showNote:annotation]; SKNoteWindowController *noteController = (SKNoteWindowController *)[self windowControllerForNote:annotation]; [[noteController window] makeFirstResponder:[noteController textView]]; [[noteController textView] selectAll:nil]; } return NO; } else if ([[tableColumn identifier] isEqualToString:NOTE_COLUMNID] || [[tableColumn identifier] isEqualToString:AUTHOR_COLUMNID]) { return YES; } } return NO; } - (void)outlineView:(NSOutlineView *)ov didClickTableColumn:(NSTableColumn *)tableColumn { if ([ov isEqual:rightSideController.noteOutlineView]) { NSTableColumn *oldTableColumn = [ov highlightedTableColumn]; NSTableColumn *newTableColumn = ([NSEvent modifierFlags] & NSEventModifierFlagCommand) ? nil : tableColumn; NSMutableArray *sortDescriptors = nil; BOOL ascending = YES; if ([oldTableColumn isEqual:newTableColumn]) { sortDescriptors = [[[rightSideController.noteArrayController sortDescriptors] mutableCopy] autorelease]; [sortDescriptors replaceObjectAtIndex:0 withObject:[[sortDescriptors firstObject] reversedSortDescriptor]]; ascending = [[sortDescriptors firstObject] ascending]; } else { NSString *tcID = [newTableColumn identifier]; NSSortDescriptor *pageIndexSortDescriptor = [[[NSSortDescriptor alloc] initWithKey:SKNPDFAnnotationPageIndexKey ascending:ascending] autorelease]; NSSortDescriptor *boundsSortDescriptor = [[[NSSortDescriptor alloc] initWithKey:SKPDFAnnotationBoundsOrderKey ascending:ascending selector:@selector(compare:)] autorelease]; sortDescriptors = [NSMutableArray arrayWithObjects:pageIndexSortDescriptor, boundsSortDescriptor, nil]; if ([tcID isEqualToString:TYPE_COLUMNID]) { [sortDescriptors insertObject:[[[NSSortDescriptor alloc] initWithKey:SKNPDFAnnotationTypeKey ascending:YES selector:@selector(noteTypeCompare:)] autorelease] atIndex:0]; } else if ([tcID isEqualToString:COLOR_COLUMNID]) { [sortDescriptors insertObject:[[[NSSortDescriptor alloc] initWithKey:SKNPDFAnnotationColorKey ascending:YES selector:@selector(colorCompare:)] autorelease] atIndex:0]; } else if ([tcID isEqualToString:NOTE_COLUMNID]) { [sortDescriptors insertObject:[[[NSSortDescriptor alloc] initWithKey:SKNPDFAnnotationStringKey ascending:YES selector:@selector(localizedCaseInsensitiveNumericCompare:)] autorelease] atIndex:0]; } else if ([tcID isEqualToString:AUTHOR_COLUMNID]) { [sortDescriptors insertObject:[[[NSSortDescriptor alloc] initWithKey:SKNPDFAnnotationUserNameKey ascending:YES selector:@selector(localizedCaseInsensitiveNumericCompare:)] autorelease] atIndex:0]; } else if ([tcID isEqualToString:DATE_COLUMNID]) { [sortDescriptors insertObject:[[[NSSortDescriptor alloc] initWithKey:SKNPDFAnnotationModificationDateKey ascending:YES] autorelease] atIndex:0]; } if (oldTableColumn) [ov setIndicatorImage:nil inTableColumn:oldTableColumn]; [ov setHighlightedTableColumn:newTableColumn]; } [rightSideController.noteArrayController setSortDescriptors:sortDescriptors]; if (newTableColumn) [ov setIndicatorImage:[NSImage imageNamed:ascending ? @"NSAscendingSortIndicator" : @"NSDescendingSortIndicator"] inTableColumn:newTableColumn]; [ov reloadData]; } } - (void)outlineViewSelectionDidChange:(NSNotification *)notification{ // Get the destination associated with the search result list. Tell the PDFView to go there. if ([[notification object] isEqual:leftSideController.tocOutlineView] && (mwcFlags.updatingOutlineSelection == 0)){ mwcFlags.updatingOutlineSelection = 1; [self goToSelectedOutlineItem:nil]; mwcFlags.updatingOutlineSelection = 0; if ([self interactionMode] == SKPresentationMode && [[NSUserDefaults standardUserDefaults] boolForKey:SKAutoHidePresentationContentsKey]) [self hideLeftSideWindow]; } } - (NSString *)outlineView:(NSOutlineView *)ov toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn item:(id)item mouseLocation:(NSPoint)mouseLocation { if ([ov isEqual:rightSideController.noteOutlineView] && (tableColumn == nil || [[tableColumn identifier] isEqualToString:NOTE_COLUMNID])) { return [item string]; } return @""; } - (void)outlineViewItemDidExpand:(NSNotification *)notification{ if ([[notification object] isEqual:leftSideController.tocOutlineView]) { [self updateOutlineSelection]; } } - (void)outlineViewItemDidCollapse:(NSNotification *)notification{ if ([[notification object] isEqual:leftSideController.tocOutlineView]) { [self updateOutlineSelection]; } } - (void)outlineViewColumnDidResize:(NSNotification *)notification{ if (mwcFlags.autoResizeNoteRows && [[notification object] isEqual:rightSideController.noteOutlineView] && [[[[notification userInfo] objectForKey:@"NSTableColumn"] identifier] isEqualToString:NOTE_COLUMNID] && [(SKScrollView *)[[notification object] enclosingScrollView] isResizingSubviews] == NO) { [rowHeights removeAllFloats]; [rightSideController.noteOutlineView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [rightSideController.noteOutlineView numberOfRows])]]; } } - (void)outlineView:(NSOutlineView *)ov didChangeHiddenOfTableColumn:(NSTableColumn *)tableColumn { if (mwcFlags.autoResizeNoteRows && [ov isEqual:rightSideController.noteOutlineView] && [[tableColumn identifier] isEqualToString:NOTE_COLUMNID]) { [rowHeights removeAllFloats]; [rightSideController.noteOutlineView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [rightSideController.noteOutlineView numberOfRows])]]; } } - (CGFloat)outlineView:(NSOutlineView *)ov heightOfRowByItem:(id)item { if ([ov isEqual:rightSideController.noteOutlineView]) { CGFloat rowHeight = [rowHeights floatForKey:item]; if (rowHeight <= 0.0) { if (mwcFlags.autoResizeNoteRows) { NSTableColumn *tableColumn = [ov tableColumnWithIdentifier:NOTE_COLUMNID]; id cell = [tableColumn dataCell]; [cell setObjectValue:[item objectValue]]; if ([(PDFAnnotation *)item type] == nil) { rowHeight = [cell cellSizeForBounds:NSMakeRect(0.0, 0.0, fmax(10.0, NSWidth([ov frame]) - COLUMN_INDENTATION - [ov indentationPerLevel]), CGFLOAT_MAX)].height; } else if ([tableColumn isHidden] == NO) { rowHeight = [cell cellSizeForBounds:NSMakeRect(0.0, 0.0, [tableColumn width] - COLUMN_INDENTATION, CGFLOAT_MAX)].height; } rowHeight = fmax(rowHeight, [ov rowHeight]) + EXTRA_ROW_HEIGHT; [rowHeights setFloat:rowHeight forKey:item]; } else { rowHeight = [(PDFAnnotation *)item type] ? [ov rowHeight] + EXTRA_ROW_HEIGHT : ([[(SKNoteText *)item note] isNote] ? DEFAULT_TEXT_ROW_HEIGHT : DEFAULT_MARKUP_ROW_HEIGHT); } } if (@available(macOS 10.13, *)) { } else { rowHeight = 75.0; } return rowHeight; } else if ([ov isEqual:leftSideController.tocOutlineView]){ CGFloat rowHeight = [rowHeights floatForKey:item]; if (rowHeight <= 0.0) { PDFOutline *ol = item; NSMutableAttributedString *attributedString = [[[NSMutableAttributedString alloc]init] autorelease]; NSString *roughString = [[ol label] stringByCollapsingWhitespaceAndNewlinesAndRemovingSurroundingWhitespaceAndNewlines]? : @""; NSDictionary *dictAttr1 = @{NSForegroundColorAttributeName:[KMAppearance KMColor_Layout_H0]}; NSAttributedString *attr1 = [[NSAttributedString alloc]initWithString:roughString attributes:dictAttr1]; [attributedString appendAttributedString:attr1]; NSTableColumn *tableColumn = [ov tableColumnWithIdentifier:LABEL_COLUMNID]; id cell = [tableColumn dataCell]; [cell setObjectValue:attributedString]; CGFloat w = leftSideController.view.frame.size.width - 86;//[tableColumn width] > 260 ? [tableColumn width] : 260; NSInteger num = [self getNum:ol]; CGFloat gap = [ov indentationPerLevel]; rowHeight = [cell cellSizeForBounds:NSMakeRect(0.0, 0.0, w - (num > 0?16:0) - gap*num, CGFLOAT_MAX)].height; rowHeight = fmax(rowHeight, [ov rowHeight]) + 25; [rowHeights setFloat:rowHeight forKey:item]; } if (@available(macOS 10.13, *)) { } else { rowHeight = 40.0; } return rowHeight < 40 ?40.0:rowHeight;//60.0; } return [ov rowHeight]; } - (void)updateSelectRowHeight{ CGFloat rowHeight = 0; PDFOutline *outline = [leftSideController.tocOutlineView itemAtRow:leftSideController.tocOutlineView.selectedRow]; if (!outline){ return; } NSMutableAttributedString *attributedString = [[[NSMutableAttributedString alloc]init] autorelease]; NSDictionary *dictAttr1 = @{NSForegroundColorAttributeName:[KMAppearance KMColor_Layout_H0]}; NSAttributedString *attr1 = [[NSAttributedString alloc]initWithString:outline.label attributes:dictAttr1]; [attributedString appendAttributedString:attr1]; NSInteger *row = [leftSideController.tocOutlineView selectedRow]; NSTableCellView *viewS = [leftSideController.tocOutlineView viewAtColumn:0 row:row makeIfNecessary:YES]; NSTableColumn *tableColumn = [leftSideController.tocOutlineView tableColumnWithIdentifier:LABEL_COLUMNID]; // id cell = [tableColumn dataCell]; id cell = [tableColumn dataCellForRow:row]; [cell setObjectValue:attributedString]; CGFloat w = leftSideController.view.frame.size.width - 86;//[tableColumn width] > 260 ? [tableColumn width] : 260; NSInteger num = [self getNum:outline]; CGFloat gap = [leftSideController.tocOutlineView indentationPerLevel]; rowHeight = [cell cellSizeForBounds:NSMakeRect(0.0, 0.0, w - (num > 0?16:0) - gap*num, CGFLOAT_MAX)].height; rowHeight = fmax(rowHeight, [leftSideController.tocOutlineView rowHeight]) + 25; [rowHeights setFloat:rowHeight forKey:outline]; if (@available(macOS 10.13, *)) { } else { rowHeight = 40.0; } CGRect fram = viewS.frame; viewS.frame = CGRectMake(fram.origin.x, fram.origin.y, fram.size.width, rowHeight); [leftSideController.tocOutlineView reloadData]; } - (NSInteger)getNum:(PDFOutline *)ol{ NSInteger num = 0; PDFOutline *outLine = [ol parent]; do { outLine = [outLine parent]; if (outLine){ num ++; } } while (outLine); return num; } - (void)sizeOutlineViewToContents:(NSOutlineView*) outlineView; { NSInteger rowCount = [outlineView numberOfRows]; for (NSInteger i = 0; i < rowCount; i++){ CGFloat rowHeight = 0; PDFOutline *outline = [leftSideController.tocOutlineView itemAtRow:i]; if (!outline){ continue; } NSMutableAttributedString *attributedString = [[[NSMutableAttributedString alloc]init] autorelease]; NSDictionary *dictAttr1 = @{NSForegroundColorAttributeName:[KMAppearance KMColor_Layout_H0]}; NSAttributedString *attr1 = [[NSAttributedString alloc]initWithString:outline.label attributes:dictAttr1]; [attributedString appendAttributedString:attr1]; // NSTableCellView *viewS = [leftSideController.tocOutlineView viewAtColumn:0 row:i makeIfNecessary:YES]; NSTableColumn *tableColumn = [leftSideController.tocOutlineView tableColumnWithIdentifier:LABEL_COLUMNID]; // id cell = [tableColumn dataCell]; id cell = [tableColumn dataCellForRow:i]; [cell setObjectValue:attributedString]; CGFloat w = leftSideController.view.frame.size.width - 86;//[tableColumn width] > 260 ? [tableColumn width] : 260; NSInteger num = [self getNum:outline]; CGFloat gap = [leftSideController.tocOutlineView indentationPerLevel]; rowHeight = [cell cellSizeForBounds:NSMakeRect(0.0, 0.0, w - (num > 0?16:0) - gap*num, CGFLOAT_MAX)].height; rowHeight = fmax(rowHeight, [leftSideController.tocOutlineView rowHeight]) + 25; [rowHeights setFloat:rowHeight forKey:outline]; if (@available(macOS 10.13, *)) { } else { rowHeight = 40.0; } // CGRect fram = viewS.frame; // viewS.frame = CGRectMake(fram.origin.x, fram.origin.y, fram.size.width, rowHeight); } [leftSideController.tocOutlineView reloadData]; } - (BOOL)outlineView:(NSOutlineView *)ov canResizeRowByItem:(id)item { if ([ov isEqual:rightSideController.noteOutlineView]) { return YES; } return NO; } - (void)outlineView:(NSOutlineView *)ov setHeight:(CGFloat)newHeight ofRowByItem:(id)item { [rowHeights setFloat:newHeight forKey:item]; } - (NSArray *)noteItems:(NSArray *)items { NSMutableArray *noteItems = [NSMutableArray array]; for (PDFAnnotation *item in items) { if ([item type] == nil) { item = [(SKNoteText *)item note]; } if ([noteItems containsObject:item] == NO) [noteItems addObject:item]; } return noteItems; } - (void)outlineView:(NSOutlineView *)ov deleteItems:(NSArray *)items { if ([ov isEqual:rightSideController.noteOutlineView] && [items count]) { for (PDFAnnotation *item in [self noteItems:items]) [pdfView removeAnnotation:item]; [[[self document] undoManager] setActionName:NSLocalizedString(@"Remove Note", @"Undo action name")]; } else if ([ov isEqual:leftSideController.tocOutlineView]) { [self outlineContextMenuItemClicked_RemoveEntry:nil]; } } - (BOOL)outlineView:(NSOutlineView *)ov canDeleteItems:(NSArray *)items { if ([ov isEqual:rightSideController.noteOutlineView]) { return [[self pdfDocument] allowsNotes] && [items count] > 0; } else if ([ov isEqual:leftSideController.tocOutlineView]) { return [items count] > 0; } return NO; } - (void)outlineView:(NSOutlineView *)ov copyItems:(NSArray *)items { if ([ov isEqual:rightSideController.noteOutlineView] && [items count]) { NSPasteboard *pboard = [NSPasteboard generalPasteboard]; NSMutableArray *copiedItems = [NSMutableArray array]; NSMutableAttributedString *attrString = [[[NSMutableAttributedString alloc] init] autorelease]; BOOL isAttributed = NO; id item; for (item in [self noteItems:items]) { if ([item isMovable]) [copiedItems addObject:item]; } for (item in items) { if ([attrString length]) [attrString replaceCharactersInRange:NSMakeRange([attrString length], 0) withString:@"\n\n"]; if ([(PDFAnnotation *)item type] == nil && [[(SKNoteText *)item note] isNote]) { [attrString appendAttributedString:[(SKNoteText *)item text]]; isAttributed = YES; } else { [attrString replaceCharactersInRange:NSMakeRange([attrString length], 0) withString:[item string] ?: @""]; } } [pboard clearContents]; if (isAttributed) [pboard writeObjects:[NSArray arrayWithObjects:attrString, nil]]; else [pboard writeObjects:[NSArray arrayWithObjects:[attrString string], nil]]; if ([copiedItems count] > 0) [pboard writeObjects:copiedItems]; } } - (BOOL)outlineView:(NSOutlineView *)ov canCopyItems:(NSArray *)items { if ([ov isEqual:rightSideController.noteOutlineView]) { if ([items count] == 1) { PDFAnnotation *annotation = [[self noteItems:items] lastObject]; if ([annotation isKindOfClass:[PDFAnnotationStamp class]] || [annotation isKindOfClass:[PDFAnnotationLink class]]) { return NO; } } return [items count] > 0; } return NO; } - (NSUInteger)outlineView:(NSOutlineView *)ov highlightLevelForRow:(NSInteger)row { if ([ov isEqual:leftSideController.tocOutlineView]) { NSInteger numRows = [ov numberOfRows]; NSUInteger firstPage = [[[ov itemAtRow:row] page] pageIndex]; NSUInteger lastPage = row + 1 < numRows ? [[[ov itemAtRow:row + 1] page] pageIndex] : [[self pdfDocument] pageCount]; NSRange range = NSMakeRange(firstPage, MAX(1LU, lastPage - firstPage)); NSUInteger i, iMax = [lastViewedPages count]; for (i = 0; i < iMax; i++) { if (NSLocationInRange((NSUInteger)[lastViewedPages pointerAtIndex:i], range)) return i; } } return NSNotFound; } - (id )outlineView:(NSOutlineView *)ov imageContextForItem:(id)item { if ([ov isEqual:leftSideController.tocOutlineView]) return [item destination]; return nil; } - (void)outlineViewCommandKeyPressedDuringNavigation:(NSOutlineView *)ov { PDFAnnotation *annotation = [[self selectedNotes] lastObject]; if (annotation) { [pdfView scrollAnnotationToVisible:annotation]; [pdfView setActiveAnnotation:annotation]; } } - (NSArray *)outlineView:(NSOutlineView *)ov typeSelectHelperSelectionStrings:(SKTypeSelectHelper *)typeSelectHelper { if ([ov isEqual:rightSideController.noteOutlineView]) { NSInteger i, count = [rightSideController.noteOutlineView numberOfRows]; NSMutableArray *texts = [NSMutableArray arrayWithCapacity:count]; for (i = 0; i < count; i++) { id item = [rightSideController.noteOutlineView itemAtRow:i]; NSString *string = [item string]; [texts addObject:string ?: @""]; } return texts; } else if ([ov isEqual:leftSideController.tocOutlineView]) { NSInteger i, count = [leftSideController.tocOutlineView numberOfRows]; NSMutableArray *array = [NSMutableArray arrayWithCapacity:count]; for (i = 0; i < count; i++) [array addObject:[[(PDFOutline *)[leftSideController.tocOutlineView itemAtRow:i] label] lossyStringUsingEncoding:NSASCIIStringEncoding]]; return array; } return nil; } - (void)outlineView:(NSOutlineView *)ov typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper didFailToFindMatchForSearchString:(NSString *)searchString { if ([ov isEqual:rightSideController.noteOutlineView]) { [statusBar setRightStringValue:[NSString stringWithFormat:NSLocalizedString(@"No match: \"%@\"", @"Status message"), searchString]]; } else if ([ov isEqual:leftSideController.tocOutlineView]) { [statusBar setLeftStringValue:[NSString stringWithFormat:NSLocalizedString(@"No match: \"%@\"", @"Status message"), searchString]]; } } - (void)outlineView:(NSOutlineView *)ov typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper updateSearchString:(NSString *)searchString { if ([typeSelectHelper isEqual:[leftSideController.thumbnailTableView typeSelectHelper]] || [typeSelectHelper isEqual:[pdfView typeSelectHelper]]) { if (searchString) [statusBar setLeftStringValue:[NSString stringWithFormat:NSLocalizedString(@"Go to page: %@", @"Status message"), searchString]]; else [self updateLeftStatus]; } else if ([typeSelectHelper isEqual:[rightSideController.noteOutlineView typeSelectHelper]]) { if (searchString) [statusBar setRightStringValue:[NSString stringWithFormat:NSLocalizedString(@"Finding note: \"%@\"", @"Status message"), searchString]]; else [self updateRightStatus]; } else if ([typeSelectHelper isEqual:[leftSideController.tocOutlineView typeSelectHelper]]) { if (searchString) [statusBar setLeftStringValue:[NSString stringWithFormat:NSLocalizedString(@"Finding: \"%@\"", @"Status message"), searchString]]; else [self updateLeftStatus]; } } */ }