// // KMEditPDfHanddler.swift // PDF Reader Pro // // Created by tangchao on 2024/6/16. // import Cocoa @objc enum KMRightSideLastState: Int { case none = 0 case open = 1 case close = 2 } @objc enum KMSubscribeWaterMarkType: Int { case none = 0 case stamp = 1 case link case sign case editText case editImage case insert case extract case replace case split case delete case rotate case copy case toWord case toExcel case toPPT case toRTF case toCSV case toHTML case toText case toImage case compress case merge case setPassword case removePassword case crop case aiTranslate case aiRewrite case aiCorrect case save func isConvertType() -> Bool { if (self == .toWord || self == .toExcel || self == .toPPT || self == .toRTF || self == .toCSV || self == .toHTML || self == .toText || self == .toImage) { return true } return false } } // EditPDF处理对象 class KMEditPDfHanddler: NSObject { weak var viewC: KMMainViewController? static let kRightSideLastStateKey = "KMRightSideLastStateKey" // 正在新增文本块 var addTextAreaing = false var fontSizeChanging = false var textAlignChanging = false weak var listView: CPDFListView? { get { return self.viewC?.listView } } var annotationType: CAnnotationType { get { return self.listView?.annotationType ?? .unkown } } weak var rightViewC: KMRightSideViewController? { get { return self.viewC?.rightSideViewController } } var subViewType: RightSubViewType { get { return self.rightViewC?.subViewType ?? .None } } // var toolMode: CToolMode { // get { // return // } // } var isEditImage: Bool { get { return self.listView?.isEditImage ?? false } } var isEditing: Bool { get { return self.listView?.isEditing() ?? false } } var editingConfig: CPDFEditingConfig? { get { return self.listView?.editingConfig() } } var editingAreas: [CPDFEditArea] { get { return self.listView?.editingAreas() as? [CPDFEditArea] ?? [] } } var editingImageAreas: [CPDFEditImageArea] { get { var areas: [CPDFEditImageArea] = [] for area in self.editingAreas { if let data = area as? CPDFEditImageArea { areas.append(data) } } return areas } } var editingTextAreas: [CPDFEditTextArea] { get { var areas: [CPDFEditTextArea] = [] for area in self.editingAreas { if let data = area as? CPDFEditTextArea { areas.append(data) } } return areas } } var rightSideLastState: KMRightSideLastState { get { let state = KMDataManager.ud_integer(forKey: Self.kRightSideLastStateKey) return KMRightSideLastState(rawValue: state) ?? .none } set { KMDataManager.ud_set(newValue.rawValue, forKey: Self.kRightSideLastStateKey) } } private var startPoint_: NSPoint = .zero func enterEditPDF() { let cnt = self.viewC?.leftSideViewController.leftView.segmentedControl.selectedSegment ?? UInt8.max if cnt == 0 { self.viewC?.search(searchString: "", isCase: false, display: true, needShowAll: false) self.viewC?.leftSideViewController.showSearchMode("") } let toolMode = self.listView?.toolMode ?? .none if toolMode != .editPDFToolMode { // 退出 self.listView?.updateActiveAnnotations([]) self.listView?.setNeedsDisplayForVisiblePages() self.listView?.commitEditFormText() self.listView?.commitEditing() self.listView?.layoutDocumentView() KMThumbnailCache.shared.clearCache() NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "CPDFDocumentPageCountChangedNotification"), object: self.listView?.document) self.closeRightPane() self.clearData() return } self._addNotification() if self.rightSideLastState == .open { self.openRightPane() } else { self.closeRightPane() } self.listView?.updateActiveAnnotations([]) self.listView?.setNeedsDisplayForVisiblePages() self.listView?.commitEditFormText() self.listView?.annotationType = .editTextImage // 设置边框颜色 self.editingConfig?.editingBorderColor = .clear // 设置边框宽度 // self.editingConfig?.editingBorderWidth = 10 // 内容与边框的间距 // self.editingConfig?.editAreaMargin = .init(floatLiteral: 5) // 设置选中块边框颜色 // self.editingConfig?.editingSelectionBorderColor = .red // 显示hover边框 self.editingConfig?.isShowMouseAreaHover = true // hover // 边框宽度 // self.editingConfig?.mouseHoverBorderWidth = 1 // 边框颜色 self.editingConfig?.mouseHoverBorderColor = NSColor(hex: "#999999") // 边框虚线设置 self.editingConfig?.mouseHoverBorderDashPattern = [3,3,3] // 块填充颜色(拖拽中) // self.editingConfig?.editAreaMoveFillColor = .cyan // 是否显示位置辅助线 self.editingConfig?.isShowEditingAreaHover = true // 辅助线颜色 // self.editingConfig?.editingHoverBorderColor = .brown // 支持多选 self.editingConfig?.isSupportMultipleSelectEditingArea = true // 图片是否显示8个操作点 self.editingConfig?.isDrawRectWithDot = true // self.editingConfig?.editingMouseSelectionBorderColor self.editingConfig?.editingMouseSelectionBorderWidth = 1 self.editingConfig?.editingMouseSelectionBorderDashPattern = [3, 3, 3] } func commitEditing() { let isEdited = self.listView?.isEdited() ?? false let isPDFTextImageEdited = self.viewC?.model.isPDFTextImageEdited ?? false if isEdited || isPDFTextImageEdited { self.viewC?.model.isPDFTextImageEdited = false self.listView?.commitEditing() self.listView?.layoutDocumentView() } self.clearData() } func openRightPane() { let state = self.rightSideLastState if state == .none || state == .open { self.viewC?.openRightPane() } } func closeRightPane() { self.rightViewC?.isHidden = true self.viewC?.closeRightPane() } func showPopWindow(positionRect: NSRect, showGuide: Bool) { if self.editAreasIsEmpty() { return } let show = KMPreference.shared.editPDFPopWindowIsShow if !show { return } let win = KMEditPDFPopToolBarWindow.shared self._kRemoveChildWindow(win) let areas = self.editingAreas win.isMultiple = areas.count > 1 var hasText = false var hasImage = false var fontColors: [NSColor] = [] for area in areas { if let data = area as? CPDFEditTextArea { hasText = true if let color = self.listView?.editingSelectionFontColor(with: data) { fontColors.append(color) } } if area is CPDFEditImageArea { hasImage = true } } var style: KMEditPDFToolbarStyle = [] if hasText { style.insert(.text) } if hasImage { style.insert(.image) } win.style = style win.model.editingAreas = areas win.model.fontColors = fontColors win.model.fontNames = self._editAreasFontNames() win.model.fontSizes = self._editAreasFontSizes() win.model.fontBolds = self._editAreasFontBolds() win.model.fontItalics = self._editAreasFontItalics() win.model.textAlignments = self._editAreasTextAlignments() win.model.rotates = self._editAreasRotates() win.model.opacitys = self._editAreasOpacitys() let area = (self.listView?.editingAreas().first as? CPDFEditArea) var areaBounds = (self.listView?.convert(area!.bounds, from: area!.page) as? NSRect) ?? .zero var maxX = NSMaxX(areaBounds) var maxY = NSMaxY(areaBounds) for area in self.editingAreas { // let bounds = area.bounds let bounds = (self.listView?.convert(area.bounds, from: area.page) as? NSRect) ?? .zero areaBounds.origin.x = min(areaBounds.origin.x, bounds.origin.x) areaBounds.origin.y = min(areaBounds.origin.y, bounds.origin.y) maxX = max(maxX, NSMaxX(bounds)) areaBounds.size.width = maxX-areaBounds.origin.x maxY = max(maxY, NSMaxY(bounds)) areaBounds.size.height = maxY-areaBounds.origin.y } self.startPoint_ = self.listView?.documentView().documentVisibleRect.origin ?? .zero win.show(relativeTo: areaBounds, of: self.viewC!.listView, preferredEdge: .maxY) win.animator().alphaValue = 1 self._kAddchildwindow(win) win.itemClick = { [weak self] itemKey, obj in if itemKey == .color { self?.fontColorAction(color: obj as? NSColor) } else if itemKey == .fontStyle { self?.fontStyleAction(fontName: obj as? String) } else if itemKey == .fontAdd { self?.fontAddAction() } else if itemKey == .fontReduce { self?.fontReduceAction() } else if itemKey == .fontBold { self?.fontBoldAction() } else if itemKey == .fontItalic { self?.fontItalicAction() } else if itemKey == .textAlignment { self?.textAlignmentAction(align: obj as? NSTextAlignment ?? .left) } // 图片 else if itemKey == .leftRotate { self?.leftRotateAction() } else if itemKey == .rightRotate { self?.rightRotateAction() } else if itemKey == .reverseX { self?.reverseXAction() } else if itemKey == .reverseY { self?.reverseYAction() } else if itemKey == .crop { self?.cropAction() } else if itemKey == .replace { self?.replaceAction() } else if itemKey == .export { if let data = obj as? NSView { self?.showExportMenu(data) } } // 对齐 else if itemKey == .alignmentLeft { self?.alignmentAction(align: .Left) } else if itemKey == .alignmentCenterX { self?.alignmentAction(align: .Horizontally) } else if itemKey == .alignmentRight { self?.alignmentAction(align: .Right) } else if itemKey == .alignmentjustifiedX { self?.alignmentAction(align: .DisHorizontally) } else if itemKey == .alignmentTop { self?.alignmentAction(align: .Top) } else if itemKey == .alignmentCenterY { self?.alignmentAction(align: .Vertical) } else if itemKey == .alignmentBottom { self?.alignmentAction(align: .Bottom) } else if itemKey == .alignmentjustifiedY { self?.alignmentAction(align: .DisVertical) } } // 显示新手引导 if let toolbarView = (win.contentViewController as? KMEditPDFPopToolBarController)?.toolbarView { if showGuide { self.showGuideView(toolbarView) } } } func hiddenPopWindow() { let win = KMEditPDFPopToolBarWindow.shared win.orderOut(nil) win.setIsVisible(false) self._kRemoveChildWindow(win) } func showCropComfirmWindow() { let winC = KMEditPDFCropComfirmWindowController.shared if KMEditPDFPopToolBarWindow.shared.isVisible { let winFrame = KMEditPDFPopToolBarWindow.shared.frame let x = winFrame.origin.x + (NSWidth(winFrame)-84) * 0.5 let frame = NSMakeRect(x, winFrame.origin.y, 84, 44) winC.window?.setFrame(frame, display: true) } else { let area = (self.listView?.editingAreas().first as? CPDFEditArea) let areaBounds = (self.listView?.convert(area!.bounds, from: area!.page) as? NSRect) ?? .zero let positioningView = self.listView let winFrame = positioningView?.window?.frame ?? .zero let toView: NSView? = nil var position = positioningView?.convert(areaBounds.origin, to: toView) ?? .zero position.x += winFrame.origin.x position.y += winFrame.origin.y position.y += areaBounds.size.height position.y += 26 let x = position.x + (NSWidth(areaBounds)-84) * 0.5 let frame = NSMakeRect(x, position.y, 84, 44) winC.window?.setFrame(frame, display: true) } winC.showWindow(nil) self._kAddchildwindow(winC.window!) winC.itemAction = { [weak self] idx, _ in if idx == 0 { // 确认 self?.cropComfirmAction() } else if idx == 1 { // 取消 self?.cropCancelAction() } } } func hiddenCropComfirmWindow() { let winC = KMEditPDFCropComfirmWindowController.shared winC.window?.orderOut(nil) winC.window?.setIsVisible(false) self._kRemoveChildWindow(winC.window) } func showGuideView(_ view: NSView) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { if KMGuideInfoWindowController.availableShow(.editPDFPopWindow) { var winFrame = self.viewC?.view.window?.frame ?? .zero winFrame.size.height -= 20 guard let area = (self.listView?.editingAreas().first as? CPDFEditArea) else { return } var areaBounds = (self.listView?.convert(area.bounds, from: area.page) as? NSRect) ?? .zero var maxX = NSMaxX(areaBounds) var maxY = NSMaxY(areaBounds) for area in self.editingAreas { // let bounds = area.bounds let bounds = (self.listView?.convert(area.bounds, from: area.page) as? NSRect) ?? .zero areaBounds.origin.x = min(areaBounds.origin.x, bounds.origin.x) areaBounds.origin.y = min(areaBounds.origin.y, bounds.origin.y) maxX = max(maxX, NSMaxX(bounds)) areaBounds.size.width = maxX-areaBounds.origin.x maxY = max(maxY, NSMaxY(bounds)) areaBounds.size.height = maxY-areaBounds.origin.y } let guideWC = KMGuideInfoWindowController.currentWC() guideWC.type = .editPDFPopWindow var viewFrame = areaBounds let tmpY = areaBounds.origin.y+(areaBounds.size.height-KMEditPDFPopGuideView.kHeight+80) if tmpY < 50 { guideWC.editPDFPopWindowFlag = true viewFrame.origin.y += (areaBounds.size.height) viewFrame.origin.x += (areaBounds.size.width*0.5+KMEditPDFPopGuideView.kWidth*0.5) viewFrame.origin.y += 20 } else { guideWC.editPDFPopWindowFlag = false viewFrame.origin.y += (areaBounds.size.height-KMEditPDFPopGuideView.kHeight+80) viewFrame.origin.x += (areaBounds.size.width*0.5+KMEditPDFPopGuideView.kWidth*0.5) viewFrame.size.height = KMEditPDFPopGuideView.kHeight+80 let offsetY = NSMaxY(winFrame)-NSMaxY(viewFrame)-NSMinY(winFrame) if offsetY <= 0 { viewFrame.origin.y += offsetY } } guideWC.digitalBoxRect = viewFrame var beh = view.window?.collectionBehavior ?? [] beh.insert(.canJoinAllSpaces) guideWC.window?.collectionBehavior = beh guideWC.window?.setFrame(winFrame, display: false) guideWC.window?.minSize = winFrame.size guideWC.window?.maxSize = winFrame.size self._kAddchildwindow(guideWC.window!) guideWC.show() DispatchQueue.main.async { guideWC.interfaceThemeDidChanged(NSApp.appearance?.name ?? .aqua) } guideWC.settingCallback = { KMPreferenceController.shared.showWindow(nil) } } } } func clearData() { self.hiddenWindows() self._removeNotification() } func hiddenWindows() { self.hiddenPopWindow() self.hiddenCropComfirmWindow() KMColorPanelCloseIfNeed() } } // MARK: - Private Methods extension KMEditPDfHanddler { private func _kAddchildwindow(_ childW: NSWindow?) { guard let win = childW else { return } self.viewC?.view.window?.addChildWindow(win, ordered: .above) } private func _kRemoveChildWindow(_ childW: NSWindow?) { guard let win = childW else { return } let contains = self.viewC?.view.window?.childWindows?.contains(win) ?? false if contains { self.viewC?.view.window?.removeChildWindow(win) } } private func _addNotification() { NotificationCenter.default.addObserver(self, selector: #selector(_scrollViewDidScroll), name: NSScrollView.didLiveScrollNotification, object: self.listView?.documentView()) } private func _removeNotification() { NotificationCenter.default.removeObserver(self, name: NSScrollView.didLiveScrollNotification, object: self.listView?.documentView()) } @objc private func _scrollViewDidScroll(_ noti: Notification) { if let data = self.listView?.documentView().isEqual(to: noti.object), data { let win = KMEditPDFPopToolBarWindow.shared if win.isVisible == false { // return } guard let area = (self.listView?.editingAreas()?.first as? CPDFEditArea) else { self.hiddenPopWindow() self.hiddenCropComfirmWindow() return } let isEditImage = self.listView?.isEditImage ?? false if isEditImage { let winC = KMEditPDFCropComfirmWindowController.shared let winW: CGFloat = 84 let areaBounds = (self.listView?.convert(area.bounds, from: area.page) as? NSRect) ?? .zero let winFrame = self.listView?.window?.frame ?? .zero let view: NSView? = nil var position = self.listView?.convert(areaBounds.origin, to: view) ?? .zero position.x += winFrame.origin.x position.y += winFrame.origin.y position.y += areaBounds.size.height position.y += 26 var x = position.x + (NSWidth(areaBounds)-84) * 0.5 // let frame = NSMakeRect(x, position.y, 84, 44) // position.x += (areaBounds.size.width*0.5-win.frame.size.width*0.5) x = max(0, x) var y = max(0, position.y) let screenFrame = NSScreen.main?.frame ?? .zero if y + 44 + 40 >= screenFrame.size.height { y = screenFrame.size.height - 44 - 40 } let wframe = NSMakeRect(x, y, winW, 44) winC.window?.setFrame(wframe, display: true) if winFrame.contains(wframe) == false { self.hiddenCropComfirmWindow() } else { self.showCropComfirmWindow() } return } var areaBounds = (self.listView?.convert(area.bounds, from: area.page) as? NSRect) ?? .zero var maxX = NSMaxX(areaBounds) var maxY = NSMaxY(areaBounds) for area in self.editingAreas { // let bounds = area.bounds let bounds = (self.listView?.convert(area.bounds, from: area.page) as? NSRect) ?? .zero areaBounds.origin.x = min(areaBounds.origin.x, bounds.origin.x) areaBounds.origin.y = min(areaBounds.origin.y, bounds.origin.y) maxX = max(maxX, NSMaxX(bounds)) areaBounds.size.width = maxX-areaBounds.origin.x maxY = max(maxY, NSMaxY(bounds)) areaBounds.size.height = maxY-areaBounds.origin.y } let winFrame = self.listView?.window?.frame ?? .zero let view: NSView? = nil var position = self.listView?.convert(areaBounds.origin, to: view) ?? .zero if position.y > winFrame.height { self.hiddenPopWindow() return } position.x += winFrame.origin.x position.y += winFrame.origin.y position.y += areaBounds.size.height position.y += 26 position.x += (areaBounds.size.width*0.5-win.frame.size.width*0.5) // var x = max(0, position.x) var x = max(winFrame.origin.x, position.x) let width = win.frame.size.width let offsetX = x + width - NSMaxX(winFrame) if offsetX > 0 { // 超出右编辑 x -= offsetX } var y = max(0, position.y) // let screenFrame = NSScreen.main?.frame ?? .zero // let winMaxY = NSMaxY(winFrame) let height = NSHeight(winFrame) if y + 44 + 40-20 >= height { // if y + 44 + 40 + 40 >= screenFrame.size.height { // y = screenFrame.size.height - 44 - 40 - 40 y = height - 44 - 40 + 20 } let wframe = NSMakeRect(x, y, width, 44) win.setFrame(wframe, display: true) if winFrame.contains(wframe) == false { self.hiddenPopWindow() } } } private func _reloadData_right_text() { self.rightViewC?.eidtPDFTextProperty.handdler = self self.rightViewC?.eidtPDFTextProperty.reloadData() } private func _reloadData_right_image() { self.rightViewC?.eidtPDFImageProperty.handdler = self self.rightViewC?.eidtPDFImageProperty.reloadData() } } // MARK: - Tools extension KMEditPDfHanddler { func editAreasIsEmpty() -> Bool { return self.editingAreas.isEmpty } func editAreasHavTextArea() -> Bool { return self.editingTextAreas.isEmpty == false } func editAreasHavImageArea() -> Bool { return self.editingImageAreas.isEmpty == false } func editAreasFontColorIsEqual() -> Bool { if self.editAreasIsEmpty() { return false } let datas = self._editAreasFontColors() if datas.count == 1 { return true } let color = datas.first for (i, d) in datas.enumerated() { if i == 0 { continue } if d != color { return false } } return true } func editAreasFontNameIsEqual() -> Bool { if self.editAreasIsEmpty() { return false } let datas = self._editAreasFontNames() if datas.count == 1 { return true } let data = datas.first for (i, d) in datas.enumerated() { if i == 0 { continue } if d != data { return false } } return true } func editAreasFontStyleIsEqual() -> Bool { if self.editAreasIsEmpty() { return false } let datas = self._editAreasFontStyles() if datas.count == 1 { return true } let data = datas.first for (i, d) in datas.enumerated() { if i == 0 { continue } if d != data { return false } } return true } func editAreasFontSizeIsEqual() -> Bool { if self.editAreasIsEmpty() { return false } let datas = self._editAreasFontSizes() if datas.count == 1 { return true } let data = datas.first for (i, d) in datas.enumerated() { if i == 0 { continue } if d != data { return false } } return true } func editAreasFontBoldIsEqual() -> Bool { if self.editAreasIsEmpty() { return false } let datas = self._editAreasFontBolds() if datas.count == 1 { return true } let data = datas.first for (i, d) in datas.enumerated() { if i == 0 { continue } if d != data { return false } } return true } func editAreasFontItalicIsEqual() -> Bool { if self.editAreasIsEmpty() { return false } let datas = self._editAreasFontItalics() if datas.count == 1 { return true } let data = datas.first for (i, d) in datas.enumerated() { if i == 0 { continue } if d != data { return false } } return true } func editAreasTextAlignmentIsEqual() -> Bool { if self.editAreasIsEmpty() { return false } let datas = self._editAreasTextAlignments() if datas.count == 1 { return true } let data = datas.first?.rawValue ?? 0 for (i, d) in datas.enumerated() { if i == 0 { continue } if d.rawValue != data { return false } } return true } func editAreasBoundsIsEqualForWidth() -> Bool { if self.editAreasIsEmpty() { return false } let rects = self._editAreasBounds() if rects.count == 1 { return true } let width = rects.first?.width ?? 0 for (i, rect) in rects.enumerated() { if i == 0 { continue } if abs(width-rect.size.width) > 0.01 { // if width != rect.size.width { return false } } return true } func editAreasBoundsIsEqualForHeight() -> Bool { if self.editAreasIsEmpty() { return false } let rects = self._editAreasBounds() if rects.count == 1 { return true } let height = rects.first?.height ?? 0 for (i, rect) in rects.enumerated() { if i == 0 { continue } // if height != rect.size.height { if abs(height-rect.size.height) > 0.01 { return false } } return true } func editAreasRotateIsEqual() -> Bool { if self.editAreasIsEmpty() { return false } if self.editAreasHavTextArea() { return false } let datas = self._editAreasRotates() if datas.count == 1 { return true } let data = datas.first ?? 0 for (i, d) in datas.enumerated() { if i == 0 { continue } if data != d { return false } } return true } func editAreasOpacityIsEqual() -> Bool { if self.editAreasIsEmpty() { return false } let datas = self._editAreasOpacitys() if datas.count == 1 { return true } let data = datas.first ?? 0 for (i, d) in datas.enumerated() { if i == 0 { continue } if data != d { return false } } return true } private func _editAreasFontColors() -> [NSColor] { var datas: [NSColor] = [] for area in self.editingTextAreas { if let data = self.listView?.editingSelectionFontColor(with: area) { // if let data = self.listView?.editingSelectionFontColor(byRangeEdit: area) { datas.append(data) } } return datas } private func _editAreasFontStyles() -> [String] { var datas: [String] = [] for area in self.editingTextAreas { if let data = self.listView?.editingSelectionCFont(byRangeEdit: area)?.styleName { // if let data = self.listView?.editingSelectionCFont(with: area)?.familyName { datas.append(data) } } return datas } private func _editAreasFontNames() -> [String] { var datas: [String] = [] for area in self.editingTextAreas { if let data = self.listView?.editingSelectionCFont(byRangeEdit: area)?.familyName { // if let data = self.listView?.editingSelectionCFont(with: area)?.familyName { datas.append(data) } } return datas } private func _editAreasFontSizes() -> [CGFloat] { var datas: [CGFloat] = [] for area in self.editingTextAreas { if let data = self.listView?.editingSelectionFontSize(byRangeEdit: area) { datas.append(data) } } return datas } private func _editAreasFontBolds() -> [Bool] { var datas: [Bool] = [] for area in self.editingTextAreas { if let data = self.listView?.isBoldCurrentSelection(byRangeEdit: area) { datas.append(data) } } return datas } private func _editAreasFontItalics() -> [Bool] { var datas: [Bool] = [] for area in self.editingTextAreas { if let data = self.listView?.isItalicCurrentSelection(byRangeEdit: area) { datas.append(data) } } return datas } private func _editAreasTextAlignments() -> [NSTextAlignment] { var datas: [NSTextAlignment] = [] for area in self.editingTextAreas { if let data = self.listView?.currentSelectionAlignment(byRangeEdit: area) { datas.append(data) } } return datas } private func _editAreasBounds() -> [NSRect] { var rects: [NSRect] = [] for area in self.editingAreas { rects.append(area.bounds) } return rects } private func _editAreasRotates() -> [CGFloat] { var arr: [CGFloat] = [] for area in self.editingImageAreas { if let data = self.listView?.getRotateWith(area) { arr.append(data) } } return arr } private func _editAreasOpacitys() -> [CGFloat] { var arr: [CGFloat] = [] for area in self.editingAreas { if let data = self.listView?.opacityByRange(for: area) { arr.append(data) } } return arr } } // MARK: - Action extension KMEditPDfHanddler { func fontColorAction(color: NSColor?) { guard let theColor = color else { return } let areas = self.editingTextAreas for area in areas { self.listView?.setEditingSelectionFontColor(theColor, with: area) } self._reloadData_right_text() } func fontStyleAction(fontName: String?) { guard let font = CPDFFont.mappingFont(withFontString: fontName) else { return } let areas = self.editingTextAreas for area in areas { self.listView?.setEditSelectionCFont(font, with: area) } self._reloadData_right_text() } func fontAddAction() { let areas = self.editingTextAreas for area in areas { if let fontSize = self.listView?.editingSelectionFontSize(byRangeEdit: area) { self.fontSizeChanging = true self.listView?.setEditingSelectionFontSize(fontSize+1, with: area, isAutoSize: false) self.fontSizeChanging = false } } self._reloadData_right_text() } func fontReduceAction() { let areas = self.editingTextAreas for area in areas { if let fontSize = self.listView?.editingSelectionFontSize(byRangeEdit: area) { self.fontSizeChanging = true self.listView?.setEditingSelectionFontSize(fontSize-1, with: area, isAutoSize: false) self.fontSizeChanging = false } } self._reloadData_right_text() } func fontBoldAction() { let areas = self.editingTextAreas var needTip = false for area in areas { if let data = self.listView?.isBoldCurrentSelection(byRangeEdit: area) { let result = self.listView?.setCurrentSelectionIsBold(!data, with: area) if (result == nil || result == false) && needTip == false { needTip = true } } } if needTip { if let data = self.viewC?.view { _ = CustomAlertView.alertView(message: NSLocalizedString("Please reset the font weight via the drop-down box", comment: ""), fromView: data, withStyle: .black) } } self._reloadData_right_text() } func fontItalicAction() { let areas = self.editingTextAreas var needTip = false for area in areas { if let data = self.listView?.isItalicCurrentSelection(byRangeEdit: area) { let result = self.listView?.setCurrentSelectionIsItalic(!data, with: area) if (result == nil || result == false) && needTip == false { needTip = true } } } if needTip { if let data = self.viewC?.view { _ = CustomAlertView.alertView(message: NSLocalizedString("Please reset the font weight via the drop-down box", comment: ""), fromView: data, withStyle: .black) } } self._reloadData_right_text() } func textAlignmentAction(align: NSTextAlignment) { let areas = self.editingTextAreas self.textAlignChanging = true for area in areas { self.listView?.setCurrentSelectionAlignment(align, with: area) } self.textAlignChanging = false self._reloadData_right_text() } func leftRotateAction() { let areas = self.editingImageAreas for area in areas { self.listView?.rotate(with: area, rotate: -90) } } func rightRotateAction() { let areas = self.editingImageAreas for area in areas { self.listView?.rotate(with: area, rotate: 90) } } func reverseXAction() { let areas = self.editingImageAreas for area in areas { self.listView?.horizontalMirror(with: area) } } func reverseYAction() { let areas = self.editingImageAreas for area in areas { self.listView?.verticalMirror(with: area) } } func cropAction() { let areas = self.editingImageAreas if areas.isEmpty { return } self.listView?.isEditImage = true for area in areas { self.listView?.enterCrop(with: area) } self.hiddenPopWindow() Task { @MainActor in self.showCropComfirmWindow() } self.rightViewC?.eidtPDFImageProperty.handdler = self self.rightViewC?.eidtPDFImageProperty.updateButtonState(hidden: false) self.viewC?.view.window?.makeFirstResponder(self.listView) } func cropCancelAction() { self.hiddenCropComfirmWindow() let areas = self.editingImageAreas if areas.isEmpty { return } for area in areas { self.listView?.exitCrop(with: area) } self.listView?.cropAreas = nil self.listView?.isEditImage = false self.rightViewC?.eidtPDFImageProperty.handdler = self self.rightViewC?.eidtPDFImageProperty.updateButtonState(hidden: true) Task { @MainActor [weak self] in if let data = self?.listView?.selectImageAreas { self?.showPopWindow(positionRect:data.bounds, showGuide: false) } } } func cropComfirmAction() { guard let selectImageAreas = self.listView?.selectImageAreas else { self.cropCancelAction() return } self.listView?.cropEditImageArea(selectImageAreas, withBounds: self.listView?.cropAreas.cropRect ?? .zero) self.cropCancelAction() } func replaceAction() { let areas = self.editingImageAreas if areas.isEmpty { return } let panel = NSOpenPanel() panel.allowsMultipleSelection = false panel.allowedFileTypes = ["png","jpg"] panel.beginSheetModal(for: NSApp.mainWindow!) { response in if response == .OK { let openPath = panel.url?.path for area in areas { // , rect: data.bounds self.listView?.replace(area, imagePath: openPath!) } } } } func showExportMenu(_ sender: NSView) { // let menuI = NSMenuItem() let submenu = NSMenu(title: "") let jpgMI = submenu.addItem(withTitle: "jpg", action: #selector(exportMenuItemAction), keyEquivalent: "") jpgMI.target = self jpgMI.tag = 1 let pngMI = submenu.addItem(withTitle: "png", action: #selector(exportMenuItemAction), keyEquivalent: "") pngMI.target = self pngMI.tag = 2 let pdfMI = submenu.addItem(withTitle: "pdf", action: #selector(exportMenuItemAction), keyEquivalent: "") pdfMI.target = self pdfMI.tag = 3 let p = NSPoint(x: NSMidX(sender.frame), y: NSMidY(sender.frame)) submenu.popUp(positioning: nil, at: p, in: sender.superview) } @objc func exportMenuItemAction(_ sender: NSMenuItem) { var format = "" if sender.tag == 1 { format = "jpg" } else if sender.tag == 2 { format = "png" } else if sender.tag == 3 { format = "pdf" } self.exportAction(format: format) } func exportAction(format: String) { let areas = self.editingImageAreas if areas.isEmpty { return } if areas.count == 1 { if KMTools.isPDFType(format) { guard let image = areas.first?.thumbnailImage else { NSSound.beep() return } let pdfdocument = CPDFDocument() pdfdocument?.km_insert(image: image, at: 0) let savePanel = NSSavePanel() savePanel.allowedFileTypes = ["pdf"] savePanel.beginSheetModal(for: self.viewC!.view.window!) { response in if (response != .OK) { return } if let data = pdfdocument?.write(to: savePanel.url!), data { NSWorkspace.shared.selectFile(savePanel.url?.path, inFileViewerRootedAtPath: ""); } } return } let panel = NSSavePanel() panel.nameFieldStringValue = "\(NSLocalizedString("Untitled", comment: "")).\(format)" panel.isExtensionHidden = true let response = panel.runModal() if response == .OK { let url = panel.url if FileManager.default.fileExists(atPath: url!.path) { try?FileManager.default.removeItem(atPath: url!.path) } let result = self.listView?.extractImage(with: areas.first, toImagePath: url!.path) ?? false if result { NSWorkspace.shared.activateFileViewerSelecting([url!]) } } } else if areas.count > 1 { let panel = NSOpenPanel() panel.canChooseFiles = false panel.canChooseDirectories = true panel.canCreateDirectories = true panel.allowsMultipleSelection = false panel.beginSheetModal(for: NSApp.mainWindow!) { response in if response == .OK { let outputURL = panel.url let s = self.listView?.document?.documentURL.lastPathComponent let folderPath = (self.listView?.document?.documentURL.deletingPathExtension().lastPathComponent ?? "") + "_extract" var filePath = outputURL?.path.stringByAppendingPathComponent(folderPath) var i = 1 let testFilePath = filePath while FileManager.default.fileExists(atPath: filePath!) { filePath = testFilePath! + "\(i)" i = i + 1 } try? FileManager.default.createDirectory(atPath: filePath!, withIntermediateDirectories: false, attributes: nil) var saveURLs : [URL] = [] let pageIndex = self.listView?.currentPageIndex ?? 0 for j in 0 ..< areas.count { let documentFileName = self.listView?.document?.documentURL.deletingPathExtension().lastPathComponent ?? "" var outPath = filePath! outPath = outPath.stringByAppendingPathComponent(documentFileName) outPath = outPath + "_page\(pageIndex+1)_\(j+1)" outPath = outPath.stringByAppendingPathExtension(format) if KMTools.isPDFType(format) { if let image = areas[j].thumbnailImage { let pdfdocument = CPDFDocument() pdfdocument?.km_insert(image: image, at: 0) let suc = pdfdocument?.write(toFile: outPath) ?? false if suc { saveURLs.append(URL(fileURLWithPath: outPath)) } } } else { let result = self.listView?.extractImage(with: areas[j], toImagePath: outPath) ?? false if result { saveURLs.append(URL(fileURLWithPath: outPath)) } } } NSWorkspace.shared.activateFileViewerSelecting(saveURLs) } } } } func alignmentAction(align: CPDFActiveAreasAlignType) { KMPrint("updateFormAearsAlignMangent") let stype = align let editingAreas = self.editingAreas if editingAreas.count >= 2 { var zeroRect = NSRect.null var highestRect = NSZeroRect var widthestRect = NSZeroRect let fristArea : CPDFEditArea = editingAreas.first as! CPDFEditArea var leftestRect = fristArea.bounds var rightestRect = fristArea.bounds var topestRect = fristArea.bounds var bottomestRect = fristArea.bounds var leftestArea : CPDFEditArea = fristArea var rightestArea : CPDFEditArea = fristArea var topestArea : CPDFEditArea = fristArea var bottomestArea : CPDFEditArea = fristArea var totalWidth = 0.0 var totalHeight = 0.0 for i in 0 ... editingAreas.count-1 { let area : CPDFEditArea = editingAreas[i] as! CPDFEditArea zeroRect = zeroRect.union(area.bounds) totalWidth = totalWidth + area.bounds.width totalHeight = totalHeight + area.bounds.height if area.bounds.height > highestRect.height { highestRect = area.bounds } if area.bounds.width > widthestRect.width { widthestRect = area.bounds } if leftestRect.minX > area.bounds.minX { leftestRect = area.bounds leftestArea = area } if area.bounds.maxX > rightestRect.maxX { rightestRect = area.bounds rightestArea = area } if area.bounds.maxY > topestRect.maxY { topestRect = area.bounds topestArea = area } if bottomestRect.minY > area.bounds.minY { bottomestRect = area.bounds bottomestArea = area } } var resultAreasArray: [Any] = [] var newBoundsArray: [String] = [] if stype == .Left { for i in 0 ... editingAreas.count-1 { let areas = editingAreas[i] as! CPDFEditArea var bounds = areas.bounds bounds.origin.x = zeroRect.origin.x newBoundsArray.append(NSStringFromRect(bounds)) } resultAreasArray = editingAreas } else if stype == .Right { for i in 0 ... editingAreas.count-1 { let areas = editingAreas[i] as! CPDFEditArea var bounds = areas.bounds bounds.origin.x = zeroRect.maxX - bounds.size.width newBoundsArray.append(NSStringFromRect(bounds)) } resultAreasArray = editingAreas } else if stype == .Top { for i in 0 ... editingAreas.count-1 { let areas = editingAreas[i] as! CPDFEditArea var bounds = areas.bounds bounds.origin.y = zeroRect.maxY - bounds.size.height newBoundsArray.append(NSStringFromRect(bounds)) } resultAreasArray = editingAreas } else if stype == .Bottom { for i in 0 ... editingAreas.count-1 { let areas = editingAreas[i] as! CPDFEditArea var bounds = areas.bounds bounds.origin.y = zeroRect.minY newBoundsArray.append(NSStringFromRect(bounds)) } resultAreasArray = editingAreas } else if stype == .Horizontally { for i in 0 ... editingAreas.count-1 { let areas = editingAreas[i] as! CPDFEditArea var bounds = areas.bounds bounds.origin.y = highestRect.midY - bounds.height/2 newBoundsArray.append(NSStringFromRect(bounds)) } resultAreasArray = editingAreas } else if stype == .Vertical { for i in 0 ... editingAreas.count-1 { let areas = editingAreas[i] as! CPDFEditArea var bounds = areas.bounds bounds.origin.x = widthestRect.midX - bounds.width/2 newBoundsArray.append(NSStringFromRect(bounds)) } resultAreasArray = editingAreas } else if stype == .DisHorizontally { let middleGap = zeroRect.width - leftestRect.width - rightestRect.width let otherAreasTotalWidth = totalWidth - leftestRect.width - rightestRect.width let gap = (middleGap - otherAreasTotalWidth)/CGFloat(editingAreas.count - 1) var areasCopyArray : [CPDFEditArea] = editingAreas as! [CPDFEditArea] areasCopyArray.sorted(by: { obj1, obj2 in let area1 = obj1 let area2 = obj2 if area1.bounds.origin.x < area2.bounds.origin.x { return true } else { return false } }) if let index = areasCopyArray.firstIndex(of: leftestArea) { areasCopyArray.remove(at: index) } if let index = areasCopyArray.firstIndex(of: rightestArea) { areasCopyArray.remove(at: index) } var leftStartX = leftestRect.maxX + gap for i in 0 ..< areasCopyArray.count { let areas = areasCopyArray[i] var bounds = areas.bounds bounds.origin.x = leftStartX newBoundsArray.append(NSStringFromRect(bounds)) leftStartX = leftStartX + bounds.width + gap } resultAreasArray = areasCopyArray } else if stype == .DisVertical { let middleGap = zeroRect.height - topestRect.height - bottomestRect.height let otherAreasTotalHeight = totalHeight - topestRect.height - bottomestRect.height let gap = (middleGap - otherAreasTotalHeight)/CGFloat(editingAreas.count - 1) var areasCopyArray : [CPDFEditArea] = editingAreas as! [CPDFEditArea] areasCopyArray.sorted(by: { obj1, obj2 in let area1 = obj1 let area2 = obj2 if area1.bounds.origin.x < area2.bounds.origin.x { return true } else { return false } }) if let index = areasCopyArray.firstIndex(of: topestArea) { areasCopyArray.remove(at: index) } if let index = areasCopyArray.firstIndex(of: bottomestArea) { areasCopyArray.remove(at: index) } var bottomStartY = bottomestRect.maxY + gap for i in 0 ... areasCopyArray.count-1 { let areas = areasCopyArray[i] var bounds = areas.bounds bounds.origin.y = bottomStartY newBoundsArray.append(NSStringFromRect(bounds)) bottomStartY = bottomStartY + bounds.height + gap } resultAreasArray = areasCopyArray } var oldBounds : [String] = [] for i in 0 ..< resultAreasArray.count { let area : CPDFEditArea = resultAreasArray[i] as! CPDFEditArea oldBounds.append(NSStringFromRect(area.bounds)) self.listView?.setBoundsEditArea(area, withBounds: NSRectFromString(newBoundsArray[i])) } self.listView?.setNeedsDisplayForVisiblePages() } } } // MARK: - CPDFViewDelegate extension KMEditPDfHanddler: CPDFViewDelegate { // 编辑区块已经改变 func pdfViewEditingAreaDidChanged(_ pdfView: CPDFView!) { let isEdited = self.listView?.isEdited() ?? false if isEdited { // 记录编辑状态 self.viewC?.recordIsPDFDocumentEdited(type: .editText) } if annotationType != .addText { NotificationCenter.default.post(name: NSNotification.Name(rawValue: "kPDFViewEditingAreaDidChanged"), object: self.listView?.document) } let areas = self.listView?.editingAreas() as? [CPDFEditArea] ?? [] if areas.isEmpty { self.hiddenPopWindow() self.hiddenCropComfirmWindow() let toolMode = self.listView?.toolMode ?? .none let annotationType = self.annotationType if toolMode == .editPDFToolMode { if annotationType == .addImage || annotationType == .addText { if self.isEditImage { self.viewC?.menuItemEditingClick_CropImage(sender: NSMenuItem()) } else { // if self.listView.annotationType == .addImage { // self.closeRightPane() // } if annotationType == .addImage { if self.rightViewC?.eidtPDFImageProperty != nil { self.rightViewC?.eidtPDFImageProperty.handdler = self self.rightViewC?.eidtPDFImageProperty.reloadData() } } // self.openRightPane() } } else { // self.viewC?.closeRightPane() self.rightViewC?.isHidden = true } self.listView?.isEditImage = false } else { self.rightViewC?.isHidden = true self.viewC?.closeRightPane() if self.subViewType == .EditPDFAddText && annotationType == .addText { self.rightViewC?.eidtPDFTextProperty.handdler = self self.rightViewC?.eidtPDFTextProperty.initData() } } return } self.hiddenCropComfirmWindow() self.viewC?.model.isPDFTextImageEdited = true let subViewType = self.rightViewC?.subViewType ?? .None if self.annotationType == .addImage { var isImageArea = false for i in 0 ..< areas.count { if areas[i] is CPDFEditImageArea { isImageArea = true } } if isImageArea { self.rightViewC?.isHidden = false if self.subViewType == .EditPDFAddImage { self.rightViewC?.subViewType = .EditPDFAddImage self.rightViewC?.eidtPDFImageProperty.handdler = self self.rightViewC?.eidtPDFImageProperty.reloadData() } self.openRightPane() } else { self.rightViewC?.isHidden = true // self.viewC?.closeRightPane() } } else if self.subViewType == .EditPDFAddText && annotationType == .addText { self.rightViewC?.isHidden = false let count = self.listView?.editingSelectionString()?.count ?? 0 self.rightViewC?.eidtPDFTextProperty.handdler = self if count != 0 { self.rightViewC?.eidtPDFTextProperty.reloadData() } else { self.rightViewC?.eidtPDFTextProperty.refreshSelectAreaProperty(needDefaultData: true) } self.openRightPane() } else { var textsAreas : [CPDFEditTextArea] = [] var imagesAreas : [CPDFEditImageArea] = [] let count = self.listView?.editingAreas()?.count ?? 0 if count < 1 { return } for i in 0 ..< areas.count { if areas[i] is CPDFEditTextArea { textsAreas.append(areas[i] as! CPDFEditTextArea) } if areas[i] is CPDFEditImageArea { imagesAreas.append(areas[i] as! CPDFEditImageArea) } } if textsAreas.count > 0 && textsAreas.count == areas.count { self.rightViewC?.isHidden = false self.rightViewC?.subViewType = .EditPDFAddText self.rightViewC?.eidtPDFTextProperty.handdler = self self.rightViewC?.eidtPDFTextProperty?.reloadData() self.openRightPane() } else if imagesAreas.count > 0 { self.rightViewC?.isHidden = false self.rightViewC?.subViewType = .EditPDFAddImage self.rightViewC?.eidtPDFImageProperty.handdler = self self.rightViewC?.eidtPDFImageProperty?.reloadData() self.openRightPane() } } if self.addTextAreaing == false { var flag: CPDFEditArea? for area in areas { if flag == nil { flag = area continue } if let data = flag, data.bounds.maxY < area.bounds.maxY { flag = area } } if let data = flag { self.showPopWindow(positionRect: data.bounds, showGuide: true) } } } func pdfViewEditingCropBoundsDidChanged(_ pdfView: CPDFView!, editing editArea: CPDFEditArea!) { if editArea != nil && (editArea is CPDFEditImageArea){ self.listView?.cropAreas = editArea as? CPDFEditImageArea } } func pdfViewEditingAddImageArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) { if self.isEditImage { self.viewC?.menuItemEditingClick_CropImage(sender: NSMenuItem()) } else { let window = KMEditPDFPopToolBarWindow.shared if (window.isVisible) { self.listView?.updateEditing([]) self.hiddenPopWindow() self.hiddenCropComfirmWindow() return } let panel = NSOpenPanel() panel.allowsMultipleSelection = false panel.allowedFileTypes = ["png","jpg"] panel.beginSheetModal(for: NSApp.mainWindow!) { response in if response == .OK { var filePath = panel.url?.path var image = NSImage.init(contentsOf: panel.url!) //图片自适应范围 if image != nil { var imageRect = rect let imageSize = image!.size var previewSize = rect.size var isChangeSize = false if previewSize.width == 0 && previewSize.height == 0 { previewSize = CGSize(width: 500, height: 500) isChangeSize = true } var scale = min(previewSize.width / imageSize.width, previewSize.height / imageSize.height) if scale < 1 { // 大于 500 } else { let wh = max(imageSize.width, imageSize.height) if wh >= 72 { scale = min(scale, 1) } else { scale = min(72 / imageSize.width, 72 / imageSize.height) } } let newSize = CGSize(width: imageSize.width * scale, height: imageSize.height * scale) if isChangeSize { imageRect.origin.x = imageRect.origin.x - newSize.width / 2 imageRect.origin.y = imageRect.origin.y - newSize.height / 2 } else { imageRect.origin.x = imageRect.origin.x + imageRect.width / 2 - newSize.width / 2 imageRect.origin.y = imageRect.origin.y + imageRect.height / 2 - newSize.height / 2 } imageRect.size = newSize let limitWidth = 1920.0 if imageSize.width > limitWidth || imageSize.height > limitWidth { filePath = KMImageOptimization.needCompressImageLosslessly(image: image!, targetSize: CGSize(width: limitWidth, height: limitWidth), maxSizeInBytes: 1024 * 1024 * 5, targetCompression: 1.0) } //自适应page let pageRect = self.listView?.currentPage().bounds ?? .zero if imageRect.width > pageRect.width || imageRect.height > pageRect.height { let pageScale = min(pageRect.width / imageSize.width, pageRect.height / imageSize.height) imageRect = CGRect(x: imageRect.origin.x, y: imageRect.origin.y, width: imageRect.width * pageScale, height: imageRect.height * pageScale) } if imageRect.origin.x < 0 { imageRect.origin.x = 5 } if imageRect.origin.y < 0 { imageRect.origin.y = 5 } if imageRect.origin.x + imageRect.width > pageRect.width || imageRect.origin.y + imageRect.height > pageRect.height { let offsetX = imageRect.origin.x + imageRect.width - pageRect.width let offsetY = imageRect.origin.y + imageRect.height - pageRect.height imageRect.origin.x = imageRect.origin.x - offsetX - 5 imageRect.origin.y = imageRect.origin.y - offsetY - 5 } DispatchQueue.main.async { self.listView?.createImagePath(filePath, rect: imageRect, page: pdfView.currentPage()) self.viewC?.model.isPDFTextImageEdited = true self.viewC?.recordIsPDFDocumentEdited(type: .editImage) self.showPopWindow(positionRect: imageRect, showGuide: true) } } } } } } func pdfViewEditingAddTextArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) { let window = KMEditPDFPopToolBarWindow.shared if (window.isVisible) { self.hiddenPopWindow() let areas = self.listView?.editingAreas() as? [CPDFEditArea] ?? [] if let area = areas.last { if let data = area as? CPDFEditTextArea { if let str = data.editTextAreaString(), str.isEmpty { self.listView?.remove(with: [area]) } else { self.listView?.updateEditing([]) } } } return } var newRect = rect if rect.size.equalTo(.zero) { newRect = CGRect(x: rect.origin.x, y: rect.origin.y - 12, width: 20, height: 12) } else { newRect = CGRect(x: rect.origin.x, y: rect.origin.y + rect.size.height - 12, width: rect.size.width, height: 12) } let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .commonly) // let fontName = KMEditPDFTextManager.manager.fetchFontName(fontName: model.fontName) let fontSize = model.fontSize let fontColor = model.color let fontAlign = model.alignment // let fontStyle = KMEditPDFTextManager.manager.fetchFontStyle(fontName: model.fontName) NSColorPanel.shared.color = fontColor // let font = KMEditPDFTextManager.manager.fetchFont(fontName: fontName, style: fontStyle, size: fontSize) let cfont = CPDFFont(familyName: model.fontName, fontStyle: model.fontStyle) let fontNameZ = CPDFFont.convertAppleFont(cfont) let font = NSFont(name: fontNameZ ?? "Helvetica", size: fontSize) let attri = CEditAttributes() attri.font = font! attri.fontColor = fontColor attri.alignment = fontAlign attri.isBold = model.bold attri.isItalic = model.italic self.addTextAreaing = true self.listView?.createStringBounds(newRect, with: attri, page: page) self.addTextAreaing = false // self.rightViewC != nil && if self.subViewType == .EditPDFAddText && self.annotationType == .addText { self.rightViewC?.eidtPDFTextProperty.handdler = self self.rightViewC?.eidtPDFTextProperty.refreshSelectAreaProperty(needDefaultData: true) } self.showPopWindow(positionRect: newRect, showGuide: true) } // 文本区块 选中文本已经变化 func pdfViewEditingSelectionDidChanged(_ pdfView: CPDFView!) { // self.viewC?.rightSideViewController != nil && if self.subViewType == .EditPDFAddText { self.rightViewC?.eidtPDFTextProperty.handdler = self self.rightViewC?.eidtPDFTextProperty.reloadData() self.rightViewC?.eidtPDFTextProperty.updateTextTextPresuppositionState() self.showPopWindow(positionRect: .zero, showGuide: false) } } func pdfViewEditingOperationDidChanged(_ pdfView: CPDFView!) { let areas = self.editingAreas if areas.count == 1 { if let data = areas.first as? CPDFEditImageArea { let updating = self.listView?.editAreaBoundUpdating ?? false if updating { self.listView?.editAreaBoundUpdating = false } else { self.rightViewC?.eidtPDFImageProperty.handdler = self self.rightViewC?.eidtPDFImageProperty.reloadData() } } } } func pdfViewEditingDoubleClick(_ pdfView: CPDFView!, imageArea editArea: CPDFEditArea!) { } func pdfViewMobileEditingBegan(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) { self.hiddenPopWindow() } func pdfViewMobileEditingMove(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) { } func pdfViewMobileEditingEnd(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) { self.showPopWindow(positionRect: .zero, showGuide: false) } func pdfViewEditingSelectCharDidChanged(_ pdfView: CPDFView!) { let areas = self.editingTextAreas if areas.isEmpty { return } if self.subViewType == .EditPDFAddText { // self.rightViewC?.eidtPDFTextProperty.reloadData() // self.rightViewC?.eidtPDFTextProperty.updateTextTextPresuppositionState() if self.addTextAreaing == false && self.fontSizeChanging == false && self.textAlignChanging == false { self.showPopWindow(positionRect: .zero, showGuide: false) self._reloadData_right_text() } } } func pdfViewEditingExitCropMode(_ pdfView: CPDFView!, forEditing editingArea: CPDFEditImageArea!) { self.cropCancelAction() } }