// // KMMainViewController+UI.swift // PDF Reader Pro // // Created by wanjun on 2022/12/15. // import Foundation extension KMMainViewController { // MARK: - 退出全屏 @IBAction func exitFullScreen(_ sender: Any) { if (self.view.window == nil) { return } if (KMTools.isFullScreen(self.view.window!)) { self.view.window?.toggleFullScreen(nil) } } @IBAction func startSpeaking(_ sender: Any) { self.showTTSWindow() let ttsView = KMTTSWindowController.share ttsView.buttonItemClick_Play(ttsView.playButton) } @IBAction func stopSpeaking(_ sender: Any) { let ttsWindowC = KMTTSWindowController.share if ttsWindowC.pdfView?.document?.documentURL.path == self.listView.document?.documentURL.path { if let data = ttsWindowC.window?.isVisible, data { ttsWindowC.stopSpeaking() ttsWindowC.close() } } } } extension KMMainViewController { //通知 func preferenceDidChangeNotification(notification:Notification) { let info : [AnyHashable : Any] = notification.userInfo ?? [:] if info.keys.contains(KMPreference.viewZoomScaleTypeKey) { self.selectZoom(KMPreferenceManager.shared.viewZoomScaleType) } if notification.name.rawValue == "pdfViewDocumentDidLoaded" || info.keys.contains(KMPreference.viewPageDisplayTypeKey) { self.selectDisplay(display: KMPreferenceManager.shared.viewPageDisplayType) } if info.keys.contains(KMPreference.displayBackgroundNormalColorKey) || notification.name.rawValue == "pdfViewDocumentDidLoaded" { self.listView.backgroundColor = KMPreferenceManager.shared.displayBackgroundNormalColor self.listView.layoutDocumentView() } self.updatePageIndicatoreType() if (info.keys.contains(KMPreference.generalAuthorNameKey)) { // 作者名称 CPDFKitConfig.sharedInstance().setAnnotationAuthor((info[KMPreference.generalAuthorNameKey] as! String)) } if (info.keys.contains(KMPreference.highlightLinksKey)) { let hlLink = info[KMPreference.highlightLinksKey] as? Bool CPDFKitConfig.sharedInstance().setEnableLinkFieldHighlight(hlLink == nil ? false : hlLink!) self.listView.setNeedsDisplayForVisiblePages() } if info.keys.contains(KMPreference.thumbPageSizeKey) { self.leftSideViewController.refreshUIOfThumbnailIfNeed(preference: true) } if info.keys.contains(KMPreference.thumbSnapshotSizeKey) { self.leftSideViewController.refreshUIOfSnapshotIfNeed(preference: true) } if info.keys.contains(KMPreference.outlineFontSizeKey) { self.leftSideViewController.updateTableFont() } if info.keys.contains(KMPreference.greekThresholdKey) { let value = KMPreference.shared.greekThreshold.cgFloat self.listView.setGreekingThreshold(value) self.secondaryPdfView?.setGreekingThreshold(value) } if info.keys.contains(KMPreference.antiAliasTextKey) { self.listView.setShouldAntiAlias(KMPreference.shared.antiAliasText) self.listView.applyDefaultInterpolationQuality() self.secondaryPdfView?.setShouldAntiAlias(KMPreference.shared.antiAliasText) self.secondaryPdfView?.applyDefaultInterpolationQuality() } if info.keys.contains(KMPreference.markupColorHighlightKey) { if let item = self.toolbarController.findItem(KMToolbarHighlightAnnotationItemIdentifier) { if item.isSelected { let color = KMPreference.shared.markupHighlightColor let imageV = KMNoteTypeImageView() item.image = imageV.noteTypeImage(withType: SKNHighlightString, color: color) } } if let item = self.toolbarController.findItem(KMToolbarSquigglyAnnotationItemIdentifier) { if item.isSelected { if let color = UserDefaults.standard.PDFListViewColor(forKey: CSquigglyNoteColorKey) { let imageV = KMNoteTypeImageView() item.image = imageV.noteTypeImage(withType: "Squiggly", color: color) } } } } if info.keys.contains(KMPreference.markupColorUnderlineKey) { if let item = self.toolbarController.findItem(KMToolbarUnderlineAnnotationItemIdentifier) { if item.isSelected { let color = KMPreference.shared.markupUnderlineColor let imageV = KMNoteTypeImageView() item.image = imageV.noteTypeImage(withType: SKNUnderlineString, color: color) } } } if info.keys.contains(KMPreference.markupColorStrikthroughKey) { if let item = self.toolbarController.findItem(KMToolbarStrikeOutAnnotationItemIdentifier) { if item.isSelected { let color = KMPreference.shared.markupStrikthroughColor let imageV = KMNoteTypeImageView() item.image = imageV.noteTypeImage(withType: SKNStrikeOutString, color: color) } } } if info.keys.contains(KMPreference.markupColorPenKey) { if let item = self.toolbarController.findItem(KMToolbarInkAnnotationItemIdentifier) { if item.isSelected { let color = KMPreference.shared.markupPenColor let imageV = KMNoteTypeImageView() item.image = imageV.noteTypeImage(withType: SKNInkString, color: color) } } } if info.keys.contains(KMPreference.editPDFPopWindowShowKey) { let show = KMPreference.shared.editPDFPopWindowIsShow let win = KMEditPDFPopToolBarWindow.shared if !show && win.isVisible { win.orderOut(nil) win.setIsVisible(false) } } } //刷新页面显示器 func updatePageIndicatoreType () { if self.isReadMode { self.pageNumberDisplayView.outView() } else { if self.listView.document != nil { self.pageNumberDisplayView.totalPagesCount = Int(self.listView.document.pageCount) } self.pageNumberDisplayView.currentPageIndex = self.listView.currentPageIndex self.pageNumberDisplayView.displayType = KMPreferenceManager.shared.pageIndicatorType self.readContentView.addSubview(self.tipCurrentPageBox, positioned: .above, relativeTo: self.readContentView) } } func showConvertNotesProgress() { guard let pdfDocument = self.document else { return } guard let _ = self.listView?.document else { return } guard let _ = self.view.window else { return } let isNewCreated = (self.myDocument as? KMMainDocument)?.isNewCreated ?? false if isNewCreated { return } self.model.needConvertNotes = false Task { @MainActor in self.convertNotesUsingPDFDocument(pdfDocument) } } func convertNotesUsingPDFDocument(_ pdfDocument: CPDFDocument) { guard let doc = self.listView?.document else { return } DispatchQueue.main.async { self.beginProgressSheet(withMessage: "", maxValue: 0) let count = pdfDocument.pageCount DispatchQueue.global().async { // var addAnnotations = [CPDFAnnotation]() // var removeAnnotations = [CPDFAnnotation]() self.model.addAnnotations.removeAll() self.model.removeAnnotations.removeAll() for i in 0..") { let table = KMTableAnnotation(KMNoteBounds: inkAnnotation.bounds, document: doc) table.border = inkAnnotation.border table.color = inkAnnotation.color table.createForm(withList: inkAnnotation.contents, andPaths: inkAnnotation.bezierPaths()) table.updateAppearanceInk(withIsAdd: false) table.contents = annotation.contents newAnnotation = table } if let newAnnotation = newAnnotation { self.model.addAnnotations.append(newAnnotation) self.model.removeAnnotations.append(annotation) } } // for i in 0.. Bool { if splitView == self.mianSplitView { // return (subview == self.listView) == false } else if splitView == self.newPDFSplitView { return subview.isEqual(to: self.secondaryPdfContentView) } return false } func splitView(_ splitView: NSSplitView, shouldCollapseSubview subview: NSView, forDoubleClickOnDividerAt dividerIndex: Int) -> Bool { if splitView == self.newPDFSplitView { if subview.isEqual(to: self.secondaryPdfContentView) { var position = self.newPDFSplitView.maxPossiblePositionOfDivider(at: dividerIndex) if self.newPDFSplitView.isSubviewCollapsed(subview) { if self.lastSplitPDFHeight <= 0.0 { let DEFAULT_SPLIT_PANE_HEIGHT: Float = 200.0 self.lastSplitPDFHeight = DEFAULT_SPLIT_PANE_HEIGHT } if self.lastSplitPDFHeight.cgFloat > NSHeight(self.pdfContentView.frame) { self.lastSplitPDFHeight = floorf(0.5 * Float(NSHeight(self.pdfContentView.frame))) } position += self.lastSplitPDFHeight.cgFloat } else { self.lastSplitPDFHeight = Float(NSHeight(subview.frame)) } self.pdfSplitView.setPosition(position, ofDividerAt: dividerIndex, animate: true) } return false } return false } func splitView(_ splitView: NSSplitView, shouldHideDividerAt dividerIndex: Int) -> Bool { if splitView == self.mianSplitView { return splitView == self.mianSplitView } else if splitView == self.newPDFSplitView { return false } return false } func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat { if splitView == mianSplitView { let splitViewWidth = splitView.frame.width let dividerIndexX0 = self.model.panelWidth + functionWidth if dividerIndex == 0 { if self.model.leftPanelOpen { return CGFloat(dividerIndexX0 * 1.5) } else { return functionWidth } } else if dividerIndex == 1 { return splitViewWidth } } else if splitView == self.newPDFSplitView { if dividerIndex == 0 { let MIN_SIDE_PANE_WIDTH = 270 return proposedMaximumPosition + MIN_SIDE_PANE_WIDTH.cgFloat } } return proposedMaximumPosition } func splitView(_ splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat { if splitView == mianSplitView { let splitViewWidth = splitView.frame.width let dividerIndexX1 = splitViewWidth - self.model.defaultRightWidth if dividerIndex == 0 { return functionWidth } else if dividerIndex == 1 { return dividerIndexX1 } } else if splitView == self.newPDFSplitView { } return proposedMinimumPosition } func splitView(_ splitView: NSSplitView, resizeSubviewsWithOldSize oldSize: NSSize) { if splitView.isEqual(to: mianSplitView) { let leftView = splitView.subviews[0] let centerView = splitView.subviews[1] let rightView = splitView.subviews[2] // let centerView = self.pdfSplitView ?? splitView.subviews[1] // let rightView = self.rightView ?? splitView.subviews[2] // 左边是否收起 let leftCollapsed = splitView.isSubviewCollapsed(leftView) // 右边是否收起 let rightCollapsed = splitView.isSubviewCollapsed(rightView) var leftSize = leftView.frame.size var mainSize = centerView.frame.size var rightSize = rightView.frame.size var contentWidth = splitView.frame.width if leftCollapsed { leftSize.width = 0.0 } else { contentWidth = contentWidth - splitView.dividerThickness } if rightCollapsed { rightSize.width = 0.0 } else { contentWidth = contentWidth - splitView.dividerThickness } if contentWidth < leftSize.width + rightSize.width { var oldContentWidth = oldSize.width if leftCollapsed == false { oldContentWidth = oldContentWidth - splitView.dividerThickness } if rightCollapsed == false { oldContentWidth = oldContentWidth - splitView.dividerThickness } let resizeFactor = contentWidth / oldContentWidth leftSize.width = floor(resizeFactor*leftSize.width) rightSize.width = floor(resizeFactor*rightSize.width) } mainSize.width = contentWidth - leftSize.width - rightSize.width leftSize.height = splitView.frame.height rightSize.height = splitView.frame.height mainSize.height = splitView.frame.height if leftCollapsed == false { leftView.setFrameSize(leftSize) } if rightCollapsed == false { rightView.setFrameSize(rightSize) } centerView.setFrameSize(mainSize) } else if splitView == self.newPDFSplitView { // let firstV = splitView.subviews.first // let lastV = splitView.subviews.last // if firstV == lastV{ // splitView.adjustSubviews() // return // } // if self.newPDFSplitView.isVertical { // 横向 // // 左边是否收起 // let leftCollapsed = splitView.isSubviewCollapsed(firstV!) // // 右边是否收起 // let rightCollapsed = splitView.isSubviewCollapsed(lastV!) // // var contentSize = splitView.frame.size // firstV?.setFrameSize(NSMakeSize(contentSize.width * 0.5, contentSize.height)) // lastV?.setFrameSize(NSMakeSize(contentSize.width * 0.5, contentSize.height)) // } else { // 纵向 // // 左边是否收起 // let leftCollapsed = splitView.isSubviewCollapsed(firstV!) // // 右边是否收起 // let rightCollapsed = splitView.isSubviewCollapsed(lastV!) // // var contentSize = splitView.frame.size // firstV?.setFrameSize(NSMakeSize(contentSize.width, contentSize.height * 0.5)) // lastV?.setFrameSize(NSMakeSize(contentSize.width, contentSize.height * 0.5)) // } } splitView.adjustSubviews() } func splitViewWillResizeSubviews(_ notification: Notification) { let defaultView = KMSplitView() let sender : NSSplitView = notification.object as? NSSplitView ?? defaultView if (sender == self.mianSplitView || sender == defaultView) && self.view.window?.frameAutosaveName != nil{ // let leftWidth = self.mianSplitView.isSubviewCollapsed(self.leftView) ? 0.0 : leftSideViewController.view.frame.width // if leftPanelOpen { // if leftWidth < 100 && lastLeftPanWidth > functionWidth{ // self.closeLeftPane() // } // } } else { if sender == self.pdfSplitView { KMPrint("") } } } func splitViewDidResizeSubviews(_ notification: Notification) { self.locationPageView.frame = CGRect(x: 0, y: self.listView.frame.maxY-32, width: self.listView.frame.width, height: 32) let defaultView = KMSplitView() let sender : NSSplitView = notification.object as? NSSplitView ?? defaultView if (sender == self.mianSplitView || sender == defaultView) && self.view.window?.frameAutosaveName != nil{ let leftWidth = self.mianSplitView.isSubviewCollapsed(self.leftView) ? 0.0 : leftSideViewController.view.frame.width let rightWidth = self.mianSplitView.isSubviewCollapsed(self.rightView) ? 0.0 : rightSideViewController.view.frame.width UserDefaults.standard.set(leftWidth, forKey: CPDFOfficeLeftSidePaneWidthKey) UserDefaults.standard.set(rightWidth, forKey: CPDFOfficeRightSidePaneWidthKey) } else { if sender == self.pdfSplitView { KMPrint("") } } } func splitView(_ splitView: NSSplitView, constrainSplitPosition proposedPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat { if splitView == self.mianSplitView { if dividerIndex == 0 { if self.model.leftPanelOpen { //当左边栏开启式,拖拽时不改变宽度,当宽度达到原宽度的一半时关闭窗口 //如果 isShowPanel 为 true 那么将不会收缩 if (proposedPosition < functionWidth + self.model.panelWidth * 0.5) && !self.leftSideViewController.isShowPanel { self.closeLeftPane() self.leftSideViewController.refreshMethodType(methodType: .None) return functionWidth } else if proposedPosition > self.model.panelWidth + functionWidth { return proposedPosition } else { return self.model.panelWidth + functionWidth } } else { return functionWidth } } } else if splitView == self.newPDFSplitView { } return proposedPosition } } // MARK: - KMLeftSideViewControllerDelegate extension KMMainViewController: KMLeftSideViewControllerDelegate { func controlStateChange(_ obj: KMLeftSideViewController, show: Bool) { if show { self.openLeftPane() } else { self.closeLeftPane() } } func enterEditMode(_ obj: KMLeftSideViewController, _ pages: [Int]) { let item : KMToolbarItemView = (self.toolbarController.mainToolBarView?.toolbarItemFindItemIdentifiers(value: KMDocumentPageToolbarItemIdentifier))! self.toolbarController.mainToolBarView?.delegate?.toolbarViewController?(self.toolbarController.mainToolBarView!, clickMode: .Page, toolbar: item, pages) } func searchAction(searchString: String,isCase:Bool) { self.search(searchString: searchString,isCase: isCase) } func controller(_ controller: KMLeftSideViewController, dispayDidChange dispay: KMPDFDisplayType) { self.selectDisplay(display: dispay, viewSettingIsReload: false) } func controller(controller: KMLeftSideViewController, itemClick item: Any?, itemKey: KMItemKey, params: Any?) { if (itemKey == .print) { // 打印 if params is NSImage { KMPrintWindowController.cpdf_printImage(image: params as! NSImage) return } var pageRange: KMPrintPageRange = KMPrintPageRange(type: .allPage, selectPages: [], reversePrintOrder: false) if (params != nil) { pageRange.type = .custom pageRange.selectPages = params as! [Int] } self.showPrintWindow(pageRange: pageRange) } else if (itemKey == .cut || itemKey == .paste || itemKey == .delete || itemKey == .leftRotate || itemKey == .rightRotate) { self.recordIsPDFDocumentEdited(type: itemKey.toSubscribeWaterMarkType()) } else if itemKey == .pageEdit { self.toolbarController.clickItem(KMDocumentPageToolbarItemIdentifier) } else if itemKey == .demote { // 大纲降级 guard let currentOutline: CPDFOutline = controller.tocOutlineView.km.clickedItem() else { return } self.listView?.demote(outline: currentOutline) } else if itemKey == .promote { // 大纲升级 guard let currentOutline: CPDFOutline = controller.tocOutlineView.km.clickedItem() else { return } self.listView?.promote(outline: currentOutline) } } func controller(controller: KMLeftSideViewController, bookMarkDidChange bookMarks: [KMBookMarkItem]) { self.needSave = true self.recordIsPDFDocumentEdited() } func controller(controller: KMLeftSideViewController, rotateType: KMRotateType) { if rotateType == .clockwise { self.menuItemAction_rotateRight((Any).self) } else if rotateType == .anticlockwise { self.menuItemAction_rotateLeft((Any).self) } } func controller(controller: KMLeftSideViewController, listViewSelectionDidChange object: Any?, info: [String : Any]?) { if controller.thumbnailTableView.isEqual(to: object) { let row = controller.thumbnailTableView.selectedRow let curIndex = self.listView.currentPageIndex if (row != -1 && row != curIndex) { self.listView?.go(toPageIndex: row, animated: true) } } } } //MARK: - ReadModel extension KMMainViewController { @objc func openReadModel() { //保存进入阅读模式之前的状态 readLeftMethodType = self.leftSideViewController.type.methodType readLeftPanelOpen = self.model.leftPanelOpen readLastLeftPanWidth = self.model.lastLeftPanWidth readLeftViewShowPanel = self.leftSideViewController.isShowPanel readRightPanelOpen = self.model.rightPanelIsOpen readToolbarType = self.toolbarController.toolbarType readToolMode = self.listView.toolMode readAnnotationType = self.listView.annotationType readSubViewType = self.rightSideViewController?.subViewType ?? .None if self.toolbarController.lastItemBox.isSelected { readToolbarItemIdentifier = self.toolbarController.lastItemBox.itemIdentifier ?? "" } else { readToolbarItemIdentifier = "" } if readToolMode == .editPDFToolMode { // 内容编辑 // 退出内容编辑模式 self.editPDFHanddler.clearData() } //设置阅读模式 self.isReadMode = true self.readModelView.isHidden = false // //顶部菜单栏状态清空 self.toolbarController.toolbarType = .None // self.toolbarController.view.isHidden = true self.toolbarController.cancelSelected(KMLeftControlToolbarItemIdentifier) self.toolbarController.cancelSelected(KMRightControlToolbarItemIdentifier) self.toolbarController.lastItemBox.isSelected = false //左侧菜单栏情况 self.model.leftPanelOpen = false self.model.lastLeftPanWidth = 0 self.leftSideViewController.refreshMethodType(methodType: .None) //阅读界面初始化 self.readModelView.isHidden = false self.readModelView.currentPageIndex = self.listView.currentPageIndex self.readModelView.totalPagesCount = Int(self.listView?.document?.pageCount ?? 0) self.readModelView.beginTimer() // self.listView.autoScales = true // self.readModelView.scaleType = .autoSize self.readModelView.zoomButton.stringValue = (NSString(format: "%.0f", self.listView.scaleFactor * 100) as String) + "%" //关闭左侧右侧菜单栏 self.closeLeftPane() self.closeRightPane() self.leftSideViewController.showPanelView(show: false) self.leftView.isHidden = true //弹出提示框 if readAlertView != nil { readAlertView?.removeFromSuperview() } readAlertView = CustomAlertView.alertView(message: NSLocalizedString("Read Mode On", comment: ""), fromView: self.view, withStyle: .blue, backgroundColor: NSColor.km_init(hex: "#36383B")) UserDefaults.standard.set(isReadMode, forKey: "kKMPDFViewIsReadMode") UserDefaults.standard.synchronize() self.updatePageIndicatoreType() } @objc func closeReadModel() { if self.isReadMode { self.model.isShowBOTA = false self.readModelView.isHidden = true self.isReadMode = false self.readModelView.isHidden = true self.leftSideViewController.refreshMethodType(methodType: readLeftMethodType) self.model.leftPanelOpen = readLeftPanelOpen self.model.rightPanelIsOpen = readRightPanelOpen self.model.lastLeftPanWidth = readLastLeftPanWidth if self.model.leftPanelOpen { self.openLeftPane() } self.closeRightPane() self.toolbarController.toolbarType = .None self.toolbarController.cancelSelected(KMDocumentViewDisplayToolbarItemIdentifier) // if self.rightPanelIsOpen { // self.rightPanelIsOpen = false //// self.toolbarController.selectItem(KMRightControlToolbarItemIdentifier) // self.openRightPane() // } // // if readToolbarItemIdentifier.count == 0 { // self.toolbarController.toolbarType = .None // } else { // self.toolbarController.selectItem(readToolbarItemIdentifier) // } // self.toolbarController.selectItem(KMDocumentViewDisplayToolbarItemIdentifier) self.leftSideViewController.showPanelView(show: readLeftViewShowPanel) if readLeftViewShowPanel { self.toolbarController.selectItem(KMLeftControlToolbarItemIdentifier) } if self.readToolMode == .editPDFToolMode { // 内容编辑 self.toolbarController.selectItem(KMDocumentEditToolbarItemIdentifier) } else { self.toolbarController.view.isHidden = false self.listView.toolMode = readToolMode self.listView.annotationType = readAnnotationType // self.toolbarController.toolbarType = .viewSetting } } else { self.toolbarController.toolbarType = .None } if readAlertView != nil { readAlertView?.removeFromSuperview() } readAlertView = CustomAlertView.alertView(message: NSLocalizedString("Read Mode Off", comment: ""), fromView: self.view, withStyle: .blue, backgroundColor: NSColor.km_init(hex: "#36383B")) UserDefaults.standard.set(isReadMode, forKey: "kKMPDFViewIsReadMode") UserDefaults.standard.synchronize() } @objc func addOutLineItemAction() { let labelString = "\(KMLocalizedString("Page", nil)) \((self.listView?.currentPageIndex ?? 0) + 1)" let label = self.listView?.currentSelection?.string() ?? labelString let dest = self.listView?.currentDestination if let row = self.leftSideViewController.selectedRowIndexes().last { if let ol = self.leftSideViewController.tocOutlineView.item(atRow: row) as? CPDFOutline { _ = self.listView.addOutline(for: ol.parent, label: label, dest: dest, at: ol.index+1) } else { let idx = self.listView?.document?.outlineRoot()?.numberOfChildren ?? 0 _ = self.listView.addOutlineForRoot(label: label, dest:dest, at: idx) } } else { let idx = self.listView?.document?.outlineRoot()?.numberOfChildren ?? 0 _ = self.listView.addOutlineForRoot(label: label, dest:dest, at: idx) } } @objc func showTTSView() { self.showTTSWindow() } @objc func showShareAction() { } @objc func lookUpAction() { let label = self.listView?.currentSelection?.string() ?? "" self.toolbarController.showFindBar() self.toolbarController.findSearchView.searchString(label) // self.toolbarController.findSearchView.find(Any.self) } @objc func searchBaiduAction() { let label = self.listView?.currentSelection?.string() ?? "" let query = label.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "" if let url = URL(string: "https://www.baidu.com/s?wd=\(query)") { NSWorkspace.shared.open(url) } } @objc func showInfoInFinder() { } @objc func NextPageAction() { } @objc func PreviousPageAction() { } @objc func TranslateItemAction() { // 获取选中的文本 if let selection = self.listView?.currentSelection?.string() { // 进行翻译 let escapedText = selection.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! let urlStr = "https://translate.google.com/?sl=auto&tl=zh-CN&text=\(escapedText)" if let url = URL(string: urlStr) { NSWorkspace.shared.open(url) } } else { print("No text selected.") } } @objc func AutoScrollItemAction() { //增加判断,如果是正在滚动,就停止,否则就开始滚动 self.listView.autoFlow() } @objc func shareFromService(sender: NSMenuItem) { if ((NSApp.mainWindow?.windowController is KMBrowserWindowController) == false) { return } var string = "" if let freeTextAnnotation = listView.activeAnnotation as? CPDFFreeTextAnnotation { string = freeTextAnnotation.contents ?? "" } else if let markupAnnotation = listView.activeAnnotation as? CPDFMarkupAnnotation { if let page = markupAnnotation.page { if let selection = page.selection(for: markupAnnotation.bounds) { string = selection.string() ?? "" } } } else { string = listView.currentSelection?.string() ?? "" } let windowControler = NSApp.mainWindow?.windowController as! KMBrowserWindowController let model = windowControler.browser?.tabStripModel if let cnt = model?.count(), cnt <= 0 { return } if let data = model?.activeTabContents().isHome, data { return } let document: KMMainDocument = model?.activeTabContents() as! KMMainDocument if string.count > 0 { let represent : NSSharingService = sender.representedObject as! NSSharingService represent.perform(withItems: [string]) return } let represent = sender.representedObject as? NSSharingService represent?.perform(withItems: [string]) } @objc func cutAction(sender: NSMenuItem) { } @objc func deleteAction(sender: NSMenuItem) { } @objc func ColorsItemAction(sender: NSMenuItem) { } @objc func LinesItemAction(sender: NSMenuItem) { } @objc func EditNoteItemAction(sender: NSMenuItem) { } @objc func AITranslateItemAction(sender: NSMenuItem) { self.showAITypeChooseView(aiConfigType: .translate) } @objc func AIProofreadItemAction(sender: NSMenuItem) { self.showAITypeChooseView(aiConfigType: .proofreading) } @objc func AIRewriteItemAction(sender: NSMenuItem) { self.showAITypeChooseView(aiConfigType: .reWriting) } // @objc func highlightLinks() { // let highlightLinks = KMPreferenceManager.shared.highlightLinks // KMPreferenceManager.shared.highlightLinks = !highlightLinks // } } // MARK: - KMEditImagePropertyViewControllerDelegate extension KMMainViewController: KMEditImagePropertyViewControllerDelegate { func editImagePropertyViewControllerDidChanged(controller: KMEditImagePropertyViewController, type: KMEditImagePropertyViewControllerChangeType) { self.model.isPDFTextImageEdited = true } } // MARK: - KMSnapshotWindowControllerDelegate extension KMMainViewController: KMSnapshotWindowControllerDelegate { func snapshotControllerWillClose(_ controller: KMSnapshotWindowController) { self.leftSideViewController.snapshotControllerWillClose(controller) } func snapshotController(_ controller: KMSnapshotWindowController, miniaturizedRect isMiniaturize: Bool) -> NSRect { if isMiniaturize && self.interactionMode != .presentation { if self.interactionMode != .legacyFullScreen && self.model.leftPanelOpen == false { self.toggleLeftPane() } else if self.interactionMode == .legacyFullScreen { // else if ([self interactionMode] == SKLegacyFullScreenMode && ([rightSideWindow state] == NSDrawerClosedState || [rightSideWindow state] == NSDrawerClosingState)) { // [rightSideWindow expand]; // [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(hideRightSideWindow:) userInfo:NULL repeats:NO]; } var row = NSNotFound for (i,sp) in self.leftSideViewController.snapshots.enumerated() { if controller.isEqual(sp.windowC) { row = i } } if (row != NSNotFound) { if self.leftSideViewController.type.methodType != .snapshot { self.leftSideViewController.leftView.segmentedControl.selectedSegment = 4 } else { self.leftSideViewController.refreshUIOfSnapshotIfNeed() } self.leftSideViewController.snapshotTableView.scrollRowToVisible(row) } } return self.leftSideViewController.snapshotController(controller, miniaturizedRect: isMiniaturize) } func snapshotControllerDidFinishSetup(_ controller: KMSnapshotWindowController) { self.leftSideViewController.snapshotControllerDidFinishSetup(controller) } } // MARK: - CPDFDocumentDelegate extension KMMainViewController: CPDFDocumentDelegate { func documentDidBeginDocumentFind(_ document: CPDFDocument!) { self.leftSideViewController.documentDidBeginFind() // [statusBar setProgressIndicatorStyle:SKProgressIndicatorBarStyle]; // [[statusBar progressIndicator] setMaxValue:[[note object] pageCount]]; // [[statusBar progressIndicator] setDoubleValue:0.0]; // [statusBar startAnimation:self]; // [self willChangeValueForKey:SEARCHRESULTS_KEY]; // [self willChangeValueForKey:GROUPEDSEARCHRESULTS_KEY]; } func documentDidEndDocumentFind(_ document: CPDFDocument!) { self.leftSideViewController.documentDidEndFind() // [self didChangeValueForKey:GROUPEDSEARCHRESULTS_KEY]; // [self didChangeValueForKey:SEARCHRESULTS_KEY]; // [statusBar stopAnimation:self]; // [statusBar setProgressIndicatorStyle:SKProgressIndicatorNone]; // NSArray *highlights = [[NSArray alloc] initWithArray:searchResults copyItems:YES]; // [highlights setValue:[NSColor yellowColor] forKey:@"color"]; // [self.pdfView setHighlightedSelections:highlights]; // [highlights release]; } } // MAKR: - CPDFViewDelegate,CPDFListViewDelegate extension KMMainViewController: CPDFViewDelegate,CPDFListViewDelegate { func pdfViewDocumentDidLoaded(_ pdfView: CPDFView!) { self.dealDocumentDidLoaded() let notification = Notification(name: Notification.Name(rawValue: "pdfViewDocumentDidLoaded")) self.preferenceDidChangeNotification(notification:notification) let leftWidthNumber = UserDefaults.standard.object(forKey: CPDFOfficeLeftSidePaneWidthKey) as? NSNumber ?? NSNumber(value: self.model.panelWidth + functionWidth) let rightWidthNumber = UserDefaults.standard.object(forKey: CPDFOfficeRightSidePaneWidthKey) as? NSNumber ?? NSNumber(value: self.model.defaultRightWidth) applyLeftSideWidth(leftWidthNumber.doubleValue, rightSideWidth: rightWidthNumber.doubleValue) self.updatePageIndicatoreType() } func pdfViewCurrentPageDidChanged(_ pdfView: CPDFView!) { self.updatePageIndicatoreType() NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "KMPDFViewCurrentPageDidChanged"), object: self.document) // KMPrint("KMPDFViewCurrentPageDidChanged") } func pdfViewScaleDidChanged(_ pdfView: CPDFView!) { self.toolbarController.mainToolBarView?.zoomTextField.stringValue = "\(Int(self.listView.scaleFactor * 100))%" } func pdfViewDidClick(onLink pdfView: CPDFView!, withURL url: String!) { if let urlString = url, urlString == kKMPurchaseProductURLString { //跳转订阅比较表 let _ = KMComparativeTableViewController.show(window: NSApp.mainWindow ?? NSWindow()) return } KMTools.openURL(urlString: url) } func pdfViewPerformURL(_ pdfView: CPDFView!, withContent content: String!) { KMPrint("pdfViewPerformURL") if content != nil { NSWorkspace.shared.open(URL(string: content)!) } else { let alert = NSAlert() alert.alertStyle = .critical alert.informativeText = NSLocalizedString("The hyperlink is invalid.", comment: "") alert.messageText = "" alert.addButton(withTitle: NSLocalizedString("OK", comment: "")) alert.runModal() return } } func pdfViewPerformPrint(_ pdfView: CPDFView!) { KMPrint("pdfViewPerformPrint") self.showPrintWindow() } func pdfViewPerformGo(toPage pdfView: CPDFView!) { KMPrint("pdfViewPerformGo") } func pdfViewOpenPDF(_ pdfView: CPDFView!, forRemoteGoTo action: CPDFAction!) { KMPrint("pdfViewOpenPDF") } func pdfViewPerformReset(_ pdfView: CPDFView!) { KMPrint("pdfViewPerformReset") // self.listView.resetFormAnnotation() pdfView.document?.resetForm() } func pdfViewEditingBlockDidChanged(_ pdfView: CPDFView!) { KMPrint("pdfViewEditingBlockDidChanged") } func pdfViewAsBookBookmark() -> NSImage! { return NSImage(named: "KMImageNameBookmarkIcon")! } func pdfViewEditingSelectionDidChanged(_ pdfView: CPDFView!) { self.editPDFHanddler.pdfViewEditingSelectionDidChanged(pdfView) } func pdfViewEditingAreaDidChanged(_ pdfView: CPDFView!) { self.editPDFHanddler.pdfViewEditingAreaDidChanged(pdfView) } func pdfViewEditingCropBoundsDidChanged(_ pdfView: CPDFView!, editing editArea: CPDFEditArea!) { self.editPDFHanddler.pdfViewEditingCropBoundsDidChanged(pdfView, editing: editArea) } //编辑PDF 创建图片区域回调 func pdfViewEditingAddImageArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) { self.editPDFHanddler.pdfViewEditingAddImageArea(pdfView, add: page, add: rect) } func pdfViewEditingAddTextArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) { self.editPDFHanddler.pdfViewEditingAddTextArea(pdfView, add: page, add: rect) } func pdfViewMobileEditingBegan(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) { self.editPDFHanddler.pdfViewMobileEditingBegan(point, for: pdfView, forEditing: editingAreas) } func pdfViewMobileEditingMove(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) { self.editPDFHanddler.pdfViewMobileEditingMove(point, for: pdfView, forEditing: editingAreas) } func pdfViewMobileEditingEnd(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) { self.editPDFHanddler.pdfViewMobileEditingEnd(point, for: pdfView, forEditing: editingAreas) } func pdfViewEditingSelectCharDidChanged(_ pdfView: CPDFView!) { self.editPDFHanddler.pdfViewEditingSelectCharDidChanged(pdfView) } func pdfViewEditingExitCropMode(_ pdfView: CPDFView!, forEditing editingArea: CPDFEditImageArea!) { self.editPDFHanddler.pdfViewEditingExitCropMode(pdfView, forEditing: editingArea) } func pdfListViewKeyDownIsContinue(_ pdfListView: CPDFListView!, theEvent: NSEvent!) -> Bool { let command = theEvent.modifierFlags.contains(.command) let control = theEvent.modifierFlags.contains(.control) KMPrint(theEvent.keyCode) if self.listView.isEditing() { if control && theEvent.keyCode == 11 { // ctr + b self.editPDFHanddler.fontBoldAction() return false } else if control && theEvent.keyCode == 34 { // ctr +i self.editPDFHanddler.fontItalicAction() return false } else if theEvent.keyCode == 36 { // enter if self.listView.isCropMode { self.editPDFHanddler.cropComfirmAction() return false } } } if (theEvent.keyCode == 11 && command) { // command + B [添加书签] self.menuItemBookMarkClick_add(sender: NSMenuItem()) return false } else if (command && control && theEvent.keyCode == 14) { // command + control + E [注释 橡皮擦] return false } else if (theEvent.keyCode == 123) { // 向左 if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) { return false } else { if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToPreviousPage()) { self.listView.goToPreviousPage(nil) return false } } } else if (theEvent.keyCode == 126) { // 向上 if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) { return false } else { if (self.listView.isContinousScroll()) { return true } if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToPreviousPage()) { self.listView.goToPreviousPage(nil) return false } } } else if (theEvent.keyCode == 124) { // 向右 if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) { return false } else { if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToNextPage()) { self.listView.goToNextPage(nil) return false } } } else if (theEvent.keyCode == 125) { // 向下 if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) { return false } else { if (self.listView.isContinousScroll()) { return true } if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToNextPage()) { self.listView.goToNextPage(nil) return false } } } else if (theEvent.keyCode == 36) { if self.listView.annotationType == .addImage || self.listView.annotationType == .addText { if self.listView.isEditImage { self.menuItemEditingClick_CropImage(sender: NSMenuItem()) } } } if theEvent.keyCode == 53 { self.exitFullScreen(Any.self) if self.isReadMode { self.closeReadModel() } self.leftSideViewCancelSelect() if (self.toolbarController.toolbarType.isToolMode()) { self.toolbarController.selectItem(self.toolbarController.toolbarType.itemIdentifier()) } } return true } func pdfListViewMenuValidate(_ pdfListView: CPDFListView!, menuItem: NSMenuItem!, isTakesEffect: UnsafeMutablePointer!) -> Bool { guard let action = menuItem.action else { isTakesEffect.pointee = false return false } if (KMSystemMenu.isEditSelector(sel: action)) { if (KMSystemMenu.Edit.deleteSelector == action) { isTakesEffect.pointee = true return self.listView.activeAnnotations.count > 0 } else if (KMSystemMenu.Edit.copySelector == action) { isTakesEffect.pointee = true return true//self.listView.canCopy() } else if (KMSystemMenu.Edit.cutSelector == action) { isTakesEffect.pointee = true return self.listView.canCopy() } else if (KMSystemMenu.Edit.pasteSelector == action) { isTakesEffect.pointee = true return self.listView.canPaste() } } isTakesEffect.pointee = false return false } func pdfViewEditingOperationDidChanged(_ pdfView: CPDFView!) { self.editPDFHanddler.pdfViewEditingOperationDidChanged(pdfView) } func pdfViewEditingDoubleClick(_ pdfView: CPDFView!, imageArea editArea: CPDFEditArea!) { self.editPDFHanddler.pdfViewEditingDoubleClick(pdfView, imageArea: editArea) } //MARK: -CPDFListViewDelegate func cPDFListView(_ pdfListView: CPDFListView, didDelete annotation: CPDFAnnotation, in pdfPage: CPDFPage) { self.leftSideViewController.updateThumbnail(at: Int(pdfPage.pageIndex())) } func pdfListViewChangeatioActiveAnnotations(_ pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!, isRightMenu: Bool) { self.view.window?.makeFirstResponder(self.listView) if isRightMenu { } else if annotations.count > 0 { if annotations.count > 1 { let fristAnnotation = annotations.first var isSameAnnotation = true let className = NSStringFromClass(fristAnnotation!.classForCoder) for annotation in annotations { let cunrrentClassName = NSStringFromClass(annotation.classForCoder) if (className == "CPDFSquareAnnotation") || (className == "CPDFCircleAnnotation") || (className == "CPDFLineAnnotation") { if (cunrrentClassName != "CPDFSquareAnnotation") && (cunrrentClassName != "CPDFCircleAnnotation") && (cunrrentClassName != "CPDFLineAnnotation") { isSameAnnotation = false } } else { if className != cunrrentClassName { isSameAnnotation = false } } } if isSameAnnotation == false { self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false) // self.closeRightPane() } else { self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true) self.openRightPane() } } else { let fristAnnotation = annotations.first let className = NSStringFromClass(fristAnnotation!.classForCoder) if self.isReadMode { self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false) self.closeRightPane() } else { self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true) if className != "CPDFStampAnnotation" && className != "CPDFSignatureAnnotation" && className != "CPDFListStampAnnotation" { self.openRightPane() } // if let lineAnnotation = fristAnnotation as? CPDFLineAnnotation { // handleLineAnnotation(lineAnnotation) // } else if let polylineAnnotation = fristAnnotation as? CPDFPolylineAnnotation { // handlePolylineAnnotation(polylineAnnotation) // } else if let polygonAnnotation = fristAnnotation as? CPDFPolygonAnnotation { // handlePolygonAnnotation(polygonAnnotation) // } } } if (listView.activeAnnotation.isKind(of: CPDFLineAnnotation.self)) { if (!(listView.activeAnnotation as! CPDFLineAnnotation).isMeasure) { cancelMeasureType() } else { if distanceMeasureInfoWindowController == nil { let measureInfo = CPDFDistanceMeasureInfo() distanceMeasureInfoWindowController = CDistanceMeasureInfoWindowController() distanceMeasureInfoWindowController?.measureInfo = measureInfo distanceMeasureInfoWindowController?.delegate = self } } } else if (!listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) && !listView.activeAnnotation.isKind(of: CPDFPolylineAnnotation.self)) { cancelMeasureType() } else if (listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) || listView.activeAnnotation.isKind(of: CPDFPolylineAnnotation.self)) { if perimeterMeasureInfoWindowController == nil { let measureInfo = CPDFPerimeterMeasureInfo() perimeterMeasureInfoWindowController = CPerimeterMeasureInfoWindowController() perimeterMeasureInfoWindowController?.measureInfo = measureInfo perimeterMeasureInfoWindowController?.delegate = self } if areaMeasureInfoWindowController == nil { let measureInfo = CPDFAreaMeasureInfo() areaMeasureInfoWindowController = CAreaMeasureInfoWindowController() areaMeasureInfoWindowController?.measureInfo = measureInfo areaMeasureInfoWindowController?.delegate = self } } } else if (annotations.count == 0){ if pdfListView.annotationType == .unkown { self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false) self.closeRightPane() } else { if self.isReadMode { self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false) self.closeRightPane() } else { self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true) self.openRightPane() } } } } func pdfListViewChangedAnnotationType(_ pdfListView: CPDFListView!, for annotationType: CAnnotationType) { if(annotationType == .unkown) { // self.rightSideViewController.view.isHidden = true self.rightSideViewController.isHidden = true self.closeRightPane() } let aType = annotationType if aType.isMarkup() || aType == .anchored || aType == .freeText || aType.isSquare() || aType == .link { KMDataManager.ud_set(annotationType.rawValue, forKey: SKLastAnnotationModeKey) } } ///开始定位链接注释 func pdfListViewLinkDestinationStart(_ pdfListView: CPDFListView!, withActiveAnnotation annotation: CPDFAnnotation!) { if self.locationPageView.superview == nil { self.locationPageView.frame = CGRect(x: 0, y: pdfListView.frame.maxY-32, width: pdfListView.frame.width, height: 32) pdfListView.addSubview(self.locationPageView) } } ///刷新链接注释 func pdfListViewLinkDestinationEnd(_ pdfListView: CPDFListView!, withActiveAnnotation annotation: CPDFAnnotation!) { if self.locationPageView.superview != nil { self.locationPageView.removeFromSuperview() } if self.rightSideViewController.subViewType == .AnnotationProperts && pdfListView.annotationType == .link { self.rightSideViewController.reloadDataWithPDFView(pdfView: pdfListView, isShow: true) } } func pdfListViewMenuItemsEditing(at point: CGPoint, for page: CPDFPage!, menuItems: [NSMenuItem]!) -> [NSMenuItem]! { if (listView.toolMode != CToolMode.editPDFToolMode) { return menuItems } var tMenuItems = menuItems; if(listView.isSelectEditCharRange() || listView.isSelecteditArea(with: point)) { tMenuItems?.append(NSMenuItem.separator()) // tMenuItems?.append(self.fontColorMenuItem()) // tMenuItems?.append(self.fontSizeMenuItem()) } let areas = self.listView.editingAreas() ?? [] if areas.count == 1 { let fristAreas = areas.first if fristAreas is CPDFEditImageArea { self.listView.selectImageAreas = fristAreas as? CPDFEditImageArea if self.listView.isEditImage { tMenuItems?.removeAll() tMenuItems?.append(self.corpImageMenuItem()) tMenuItems?.append(self.cancelCorpImageMenuItem()) tMenuItems?.append(self.restoreCorpImageMenuItem()) } else { tMenuItems?.append(NSMenuItem.separator()) tMenuItems?.append(self.cutImageArea()) tMenuItems?.append(self.replaceImageArea()) tMenuItems?.append(self.exportImageArea()) } } else { if tMenuItems?.count != 1 { tMenuItems?.swapAt(0, 1) } } } else if areas.count == 0 { tMenuItems?.append(NSMenuItem.separator()) tMenuItems?.append(self.addText()) tMenuItems?.append(self.addImage()) } return tMenuItems } func tableMenu(_ menu: NSMenu, withTable table: KMTableAnnotation, point: CGPoint) -> NSMenu { if table.currentCell.row >= 0 && table.currentCell.column >= 0 { let itemTitles = ["Edit", "", "Add Row Above", "Add Row Below", "", "Add Column Before", "Add Column After", "", "Delete Row", "Delete Column", "Delete Table", "Cut", "Copy", "Paste", "Paste and Match Style", "Delete Cell Contents", "Clear All"] let actions = ["formAnnotTextEdit:", "", "addRowAbove:", "addRowBelow:", "", "addColumnBefore:", "addColumnAfter:", "", "deleteRow:", "deleteColumn:", "deleteTabel", "cutCell:", "copyCell:", "pasteCell:", "pasteAndMatchStyle:", "deleteCellContents:", "clearAll:"] for i in 0..= 5 { item!.action = nil } else if (path2 as AnyObject).lineJoinStyle == NSBezierPath.LineJoinStyle.bevel && table.footerCount() >= 5 { item!.action = nil } } item!.title = NSLocalizedString(item!.title, comment: "") item!.representedObject = NSValue(point: point) menu.insertItem(item!, at: i) } } } else { let itemTitles = ["Cut", "Copy", "Paste", "Delete"] let actions = ["cut:", "copy:", "paste:", "delete:"] for i in 0..!, isMoveSelectAnno: Bool) { self.mouseRightMenuEvent = theEvent var currentMenu : NSMenu = menu.pointee! if let activeAnno = listView.activeAnnotation as? KMTableAnnotation {//Table var pagePoint = NSPoint() _ = self.listView.pageAndPoint(&pagePoint, for: theEvent, nearest: true) currentMenu.removeAllItems() let annotation = activeAnno annotation.completeEditCellText() if !(NSIsEmptyRect(annotation.drawRect)) { annotation.drawLine(pagePoint) NotificationCenter.default.post(name: NSNotification.Name.KMPDFViewTableAnnotationDidChange, object: self, userInfo: ["point": NSValue(point: pagePoint)]) } if (annotation.rowNumber - annotation.currentCell.row - 1) < 0 { return } currentMenu = tableMenu(currentMenu, withTable: listView.activeAnnotation as! KMTableAnnotation, point: pagePoint) listView.needsDisplay = true return } var pagePoint: NSPoint = .zero if let page = self.listView.pageAndPoint(&pagePoint, for: theEvent, nearest: true) { let anno = page.annotation(at: pagePoint) let item1 = NSMenuItem(title: NSLocalizedString("Delete", comment: ""), action: #selector(menuItemActionMeasureDelete), target: self) item1.representedObject = anno let item2 = NSMenuItem(title: NSLocalizedString("Edit Note", comment: ""), action: #selector(menuItemActionMeasureEditNote), target: self) item2.representedObject = anno let item3 = NSMenuItem(title: NSLocalizedString("Settings", comment: ""), action: #selector(menuItemActionMeasureSetting), target: self) item3.representedObject = anno if let data = anno as? CPDFPolygonAnnotation { // 多变形 currentMenu.removeAllItems() currentMenu.insertItem(item1, at: 0) currentMenu.insertItem(item2, at: 1) currentMenu.insertItem(item3, at: 2) return } if let data = anno as? CPDFPolylineAnnotation { currentMenu.removeAllItems() currentMenu.insertItem(item1, at: 0) currentMenu.insertItem(item2, at: 1) currentMenu.insertItem(item3, at: 2) return } if let data = anno as? CPDFLineAnnotation, data.isMeasure { currentMenu.removeAllItems() currentMenu.insertItem(item1, at: 0) currentMenu.insertItem(item2, at: 1) currentMenu.insertItem(item3, at: 2) return } } if (listView.toolMode == .selectToolMode){ currentMenu.insertItem(NSMenuItem.separator(), at: 3) currentMenu.insertItem(self.printingMenu(), at: 3) currentMenu.insertItem(self.setTTSStype(), at: 3) currentMenu.insertItem(self.setCropStype(), at: 3) currentMenu.insertItem(self.setSnapshotStype(), at: 3) let export = NSMenuItem(title: NSLocalizedString("Export", comment: ""), action: nil, target: self) export.submenu = self.exportMenu() currentMenu.insertItem(export, at: 3) currentMenu.insertItem(NSMenuItem.separator(), at: 3) if listView.activeAnnotation == nil{ currentMenu.insertItem(self.setAnnotationToolStype(), at: 3) currentMenu.insertItem(NSMenuItem.separator(), at: 3) } currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 3) currentMenu.insertItem(self.addReadModelStype(), at: currentMenu.items.count - 3) currentMenu.insertItem(NSMenuItem.separator(), at: 0) currentMenu.insertItem(self.setAITranslateStype(), at: 0) currentMenu.insertItem(self.setAIProofreadStype(), at: 0) currentMenu.insertItem(self.setAIRewriteStype(), at: 0) return } if (listView.toolMode == .moveToolMode || listView.toolMode == .magnifyToolMode){ currentMenu.insertItem(NSMenuItem.separator(), at: 0) currentMenu.insertItem(self.setTTSStype(), at: 0) currentMenu.insertItem(self.setCropStype(), at: 0) currentMenu.insertItem(self.setSnapshotStype(), at: 0) currentMenu.insertItem(NSMenuItem.separator(), at: 0) currentMenu.insertItem(self.addOutlineStype(), at: 0) currentMenu.insertItem(self.addBookmarkMenu(), at: 0) if listView.activeAnnotation == nil{ currentMenu.insertItem(NSMenuItem.separator(), at: 0) currentMenu.insertItem(self.setAnnotationToolStype(), at: 0) } currentMenu.insertItem(NSMenuItem.separator(), at: 0) currentMenu.insertItem(self.setAITranslateStype(), at: 0) currentMenu.insertItem(self.setAIProofreadStype(), at: 0) currentMenu.insertItem(self.setAIRewriteStype(), at: 0) return } if currentMenu.items.count > 3 { currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 3) currentMenu.insertItem(self.addReadModelStype(), at: currentMenu.items.count - 3) } if listView.currentSelection != nil && listView.activeAnnotations.count < 1{ if listView.currentSelection.selectionType() == .text { currentMenu.insertItem(NSMenuItem.separator(), at: 3) currentMenu.insertItem(self.setSearchBaiduStype(), at: 3) currentMenu.insertItem(NSMenuItem.separator(), at: 3) currentMenu.insertItem(self.setLookUpStype(), at: 3) currentMenu.insertItem(NSMenuItem.separator(), at: 3) currentMenu.insertItem(self.addOutlineStype(), at: 3) currentMenu.insertItem(NSMenuItem.separator(), at: 3) // if listView.activeAnnotation == nil{ currentMenu.insertItem(self.setAnnotationToolStype(), at: 3) // } currentMenu.insertItem(self.setTTSStype(), at: 3) currentMenu.insertItem(NSMenuItem.separator(), at: 3) currentMenu.insertItem(self.setShareStype(), at: 3) currentMenu.insertItem(NSMenuItem.separator(), at: 3) } currentMenu.insertItem(self.enterAnnotationStype(), at: 3) currentMenu.insertItem(NSMenuItem.separator(), at: 3) if listView.currentSelection.selectionType() == .image{ // // currentMenu.insertItem(self.setCutStype(), at: 1) // } // if listView.activeAnnotations.count > 0 { // currentMenu.insertItem(self.setDeleteStype(), at: 3) currentMenu.insertItem(NSMenuItem.separator(), at: 6) currentMenu.insertItem(self.addOutlineStype(), at: 6) currentMenu.insertItem(NSMenuItem.separator(), at: 6) currentMenu.insertItem(self.setAnnotationToolStype(), at: 6) // currentMenu.insertItem(self.setEditNoteStype(), at: 6) // currentMenu.insertItem(self.setRotateStype(), at: 6) // currentMenu.insertItem(self.setLinesStype(), at: 6) // currentMenu.insertItem(self.setColorsStype(), at: 6) // } } if listView.currentSelection.selectionType() == .text { currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count) currentMenu.insertItem(self.setTranslateStype(), at: currentMenu.items.count) currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count) // currentMenu.insertItem(self.setServicesStype(), at: currentMenu.items.count) } } if listView.activeAnnotation != nil || isMoveSelectAnno { if let data = self.listView?.activeAnnotation?.type?.lowercased(), data == "stamp"{ currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15) currentMenu.insertItem(self.enterAnnotationStype(), at: currentMenu.items.count - 15) currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15) }else{ currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15) currentMenu.insertItem(self.enterAnnotationStype(), at: currentMenu.items.count - 15) // currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15) // currentMenu.insertItem(self.setAnnotationToolStype(), at: currentMenu.items.count - 15) // currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15) // currentMenu.insertItem(self.addBookmarkMenu(), at: currentMenu.items.count - 15) // currentMenu.insertItem(self.addOutlineStype(), at: currentMenu.items.count - 15) // currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15) // currentMenu.insertItem(self.setSnapshotStype(), at: currentMenu.items.count - 15) // currentMenu.insertItem(self.setCropStype(), at: currentMenu.items.count - 15) // currentMenu.insertItem(self.setTTSStype(), at: currentMenu.items.count - 15) if let anno = self.listView.activeAnnotation, anno.isKind(of: CPDFStampAnnotation.self) { // currentMenu.insertItem(self.setRotateStype(), at: currentMenu.items.count - 15) } else { currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15) currentMenu.insertItem(self.setShareStype(), at: currentMenu.items.count - 15) } currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15) } } if listView.activeAnnotation == nil && listView.currentSelection == nil{ currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count) if(listView.toolMode == .selectToolMode) { if NSIsEmptyRect(listView.currentSelectionRect()) { currentMenu.insertItem(self.zoomSelectionMenuItem(), at: 0) currentMenu.insertItem(NSMenuItem.separator(), at: 0) } currentMenu.insertItem(self.printingMenu(), at: 0) currentMenu.insertItem(self.setTTSStype(), at: 0) currentMenu.insertItem(self.setCropStype(), at: 0) currentMenu.insertItem(self.setSnapshotStype(), at: 0) let export = NSMenuItem(title: NSLocalizedString("Export", comment: ""), action: nil, target: self) export.submenu = self.exportMenu() currentMenu.insertItem(export, at: currentMenu.items.count) }else{ currentMenu.insertItem(NSMenuItem.separator(), at: 2) currentMenu.insertItem(self.setTTSStype(), at: 2) currentMenu.insertItem(self.setCropStype(), at: 2) currentMenu.insertItem(self.setSnapshotStype(), at: 2) currentMenu.insertItem(NSMenuItem.separator(), at: 2) currentMenu.insertItem(self.addOutlineStype(), at: 2) currentMenu.insertItem(NSMenuItem.separator(), at: 2) currentMenu.insertItem(self.enterAnnotationStype(), at: 2) currentMenu.insertItem(NSMenuItem.separator(), at: 2) if(currentMenu.items.count > 4) { currentMenu.insertItem(NSMenuItem.separator(), at: 5) } if(currentMenu.items.count > 5) { currentMenu.insertItem(self.addBookmarkMenu(), at: 6) } // if (currentMenu.items.count > 6 && self.isReadMode) { // currentMenu.removeItem(currentMenu.item(withTitle: "Zoom")!) // } // currentMenu.insertItem(self.findStringMenu(), at: currentMenu.items.count) currentMenu.insertItem(self.setAutoScrollStype(), at: currentMenu.items.count) } currentMenu.insertItem(self.setAnnotationToolStype(), at: 5) } currentMenu.insertItem(NSMenuItem.separator(), at: 0) currentMenu.insertItem(self.setAITranslateStype(), at: 0) currentMenu.insertItem(self.setAIProofreadStype(), at: 0) currentMenu.insertItem(self.setAIRewriteStype(), at: 0) for item in currentMenu.items { if (item.action == NSSelectorFromString("menuItemClick_HidenorShowNote:")) { // 显示与隐藏注释 item action 截取 item.action = #selector(menuItemClick_HidenorShowNote) item.target = self break } } } func pdfListViewAddAnnotations(_ pdfListView: CPDFListView!, forAdd annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) { var addRedact = false for anno in annotations { if (anno.isKind(of: CPDFRedactAnnotation.self)) { addRedact = true } else if anno is CPDFSquareAnnotation || anno is CPDFCircleAnnotation { anno.contents = pdfPage?.string(for: anno.bounds) ?? "" } } self.model.hasAddRedact = addRedact if /*self.isReadMode || */self.listView.toolMode == .moveToolMode { self.listView.toolMode = .textToolMode self.listView.annotationType = .unkown self.toolbarController.toolbarType = .Annatiton } if (self.model.rightMouseEventing) { self.model.rightMouseEventing = false if (self.toolbarController.ignoreCurrentAnnotationTypeChange && self.listView.annotationType == .ink) { self.listView.toolMode = .textToolMode self.listView.annotationType = .unkown } } self.toolbarController.ignoreCurrentAnnotationTypeChange = false self.leftSideViewController.refreshUIForAddAnnotation(annos: annotations, page: pdfPage) } func pdfListViewRemoveAnnotations(_ pdfListView: CPDFListView!, forRemove annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) { self.leftSideViewController.annoList_refreshUIForDeleteAnnotations(annos: annotations, page: pdfPage) } func pdfListViewDidSelectionEnd(_ pdfListView: CPDFListView!) { if (!self.listView.isEqual(to: pdfListView)) { return } if (self.listView.toolMode != .selectToolMode) { return } if (self.topTipBox.isHidden || self.topTipBox.contentView?.subviews.count == 0) { return } let tipView = self.topTipBox.contentView?.subviews.first if (tipView?.isKind(of: KMCropTipView.self) == false) { return } (tipView as! KMCropTipView).setString(string: "请按 Enter 键确定裁剪区域") } func pdfListViewKeyDowClosePanel(_ speedy: CPDFViewSidebarSpeedMode, event theEvent: NSEvent!) { if(speedy == .right) { self.toggleRightPane() } else if (speedy == .left) { self.menuItemAction_hiddenLeftSide(speedy) } } func pdfListViewEventMarkupColor(with annotation: CPDFAnnotation!) -> [NSColor]! { if (annotation.isKind(of: CPDFMarkupAnnotation.self)) { if (annotation as! CPDFMarkupAnnotation).markupType() == .highlight { return KMAnnotationPropertiesColorManager.manager.markHighlightColors } else { return KMAnnotationPropertiesColorManager.manager.markOtherColors } } else { return KMAnnotationPropertiesColorManager.manager.markOtherColors } } func pdfListViewHaveDocumentAttribute() -> Bool { if(!self.listView.document.allowsCopying) { self.removeOwnerPassword() return false } return true } func pdfListView(_ sender: CPDFListView!, showSnapshotAtPageNumber pageNum: Int, for rect: NSRect, scaleFactor: CGFloat, autoFits: Bool) { let swc = KMSnapshotWindowController(windowNibName: "SnapshotWindow") swc.delegate = self swc.setPdfDocument(self.listView.document, goToPageNumber: pageNum, rect: rect, scaleFactor: scaleFactor, autoFits: autoFits) swc.forceOnTop = self.interactionMode != .normal self.myDocument?.addWindowController(swc) } func pdfListView(_ pdfView: CPDFListView!, documentDataDidChanged docData: Any!, withInfo info: [AnyHashable : Any]!) { if let data = info?[CPDFListView.outlineKey] as? Bool, data { // 大纲改变 guard let ol = docData as? CPDFOutline else { return } let add = info?[CPDFListView.outlineAddKey] as? Bool ?? false let remove = info?[CPDFListView.outlineRemoveKey] as? Bool ?? false if add { self.leftSideViewController.addOutlineAfter(ol) } if remove { self.leftSideViewController.removeOutlineAfter(ol) } let demote = info?[CPDFListView.outlineDemoteKey] as? Bool ?? false let promote = info?[CPDFListView.outlinePromoteKey] as? Bool ?? false if demote { self.leftSideViewController.demoteOutlineAfter(ol) } if promote { self.leftSideViewController.promoteOutlineAfter(ol) } } } //TextEdit func pdfListViewDidTextFontChanged(_ pdfListView: CPDFListView!) { self.rightSideViewController.eidtPDFTextProperty.reloadData() } func pdfListViewDidTextColorChanged(_ pdfListView: CPDFListView!, with color: NSColor!) { self.rightSideViewController.eidtPDFTextProperty.fontColorChangeAction() } func pdfListViewAnnotationMeasureInfoChange(_ pdfListView: CPDFListView!, with annotation: CPDFAnnotation!) { guard let data = annotation else { if distanceMeasureInfoWindowController?.window?.isVisible == true { distanceMeasureInfoWindowController?.clearData() } // else if perimeterMeasureInfoWindowController?.window?.isVisible == true { // perimeterMeasureInfoWindowController?.hideFloatingWindow() // } else if areaMeasureInfoWindowController?.window?.isVisible == true { // areaMeasureInfoWindowController?.hideFloatingWindow() // } return } if let lineAnnotation = annotation as? CPDFLineAnnotation { handleLineAnnotation(lineAnnotation) } else if let polylineAnnotation = annotation as? CPDFPolylineAnnotation { handlePolylineAnnotation(polylineAnnotation) } else if let polygonAnnotation = annotation as? CPDFPolygonAnnotation { handlePolygonAnnotation(polygonAnnotation) } } func pdfListViewMeasureCancel(_ pdfListView: CPDFListView!) { cancelMeasureType() } private func handleLineAnnotation(_ annotation: CPDFLineAnnotation) { if perimeterMeasureInfoWindowController?.window?.isVisible == true { perimeterMeasureInfoWindowController?.hideFloatingWindow() distanceMeasureInfoWindowController?.showWindow(self) } else if areaMeasureInfoWindowController?.window?.isVisible == true { areaMeasureInfoWindowController?.hideFloatingWindow() distanceMeasureInfoWindowController?.showWindow(self) } else if distanceMeasureInfoWindowController?.window?.isVisible == false { distanceMeasureInfoWindowController?.showWindow(self) } let measureInfo = annotation.measureInfo let startPoint = annotation.startPoint let endPoint = annotation.endPoint let angle = atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x) * (180.0 / .pi) distanceMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle)) distanceMeasureInfoWindowController?.xLabel.stringValue = String(format: "%.0f", abs(endPoint.x - startPoint.x)) distanceMeasureInfoWindowController?.yLabel.stringValue = String(format: "%.0f", abs(endPoint.y - startPoint.y)) distanceMeasureInfoWindowController?.reloadData(with: measureInfo!) } private func handlePolylineAnnotation(_ annotation: CPDFPolylineAnnotation) { if distanceMeasureInfoWindowController?.window?.isVisible == true { distanceMeasureInfoWindowController?.hideFloatingWindow() perimeterMeasureInfoWindowController?.showWindow(self) } else if areaMeasureInfoWindowController?.window?.isVisible == true { areaMeasureInfoWindowController?.hideFloatingWindow() perimeterMeasureInfoWindowController?.showWindow(self) } else if perimeterMeasureInfoWindowController?.window?.isVisible == false { perimeterMeasureInfoWindowController?.showWindow(self) } let measureInfo = annotation.measureInfo let savePoints = annotation.savePoints() var angle: CGFloat = 0 if savePoints.count >= 3 { let count = savePoints.count let startPoint = savePoints[count - 3].pointValue let midPoint = savePoints[count - 2].pointValue let endPoint = savePoints.last!.pointValue angle = angleBetweenPoints(startPoint, midPoint, endPoint) } angle = 180 - angle perimeterMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle)) perimeterMeasureInfoWindowController?.reloadData(with: measureInfo!) } private func handlePolygonAnnotation(_ annotation: CPDFPolygonAnnotation) { if distanceMeasureInfoWindowController?.window?.isVisible == true { distanceMeasureInfoWindowController?.hideFloatingWindow() areaMeasureInfoWindowController?.showWindow(self) } else if perimeterMeasureInfoWindowController?.window?.isVisible == true { perimeterMeasureInfoWindowController?.hideFloatingWindow() areaMeasureInfoWindowController?.showWindow(self) } else if areaMeasureInfoWindowController?.window?.isVisible == false { areaMeasureInfoWindowController?.showWindow(self) } let measureInfo = annotation.measureInfo let savePoints = annotation.savePoints var angle: CGFloat = 0 if savePoints.count >= 3 { let count = savePoints.count let startPoint = (savePoints[count - 3] as AnyObject).pointValue let midPoint = (savePoints[count - 2] as AnyObject).pointValue let endPoint = (savePoints.lastObject as AnyObject).pointValue angle = angleBetweenPoints(startPoint!, midPoint!, endPoint!) } angle = 180 - angle areaMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle)) areaMeasureInfoWindowController?.reloadData(measureInfo!) } private func angleBetweenPoints(_ startPoint: CGPoint, _ midPoint: CGPoint, _ endPoint: CGPoint) -> CGFloat { let vector1 = CGPoint(x: midPoint.x - startPoint.x, y: midPoint.y - startPoint.y) let vector2 = CGPoint(x: endPoint.x - midPoint.x, y: endPoint.y - midPoint.y) let dotProduct = vector1.x * vector2.x + vector1.y * vector2.y let magnitude1 = sqrt(vector1.x * vector1.x + vector1.y * vector1.y) let magnitude2 = sqrt(vector2.x * vector2.x + vector2.y * vector2.y) return acos(dotProduct / (magnitude1 * magnitude2)) * (180.0 / .pi) } }