KMMainViewController+Action.swift 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. //
  2. // KMMainViewController+Action.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by wanjun on 2022/12/15.
  6. //
  7. import Foundation
  8. extension KMMainViewController {
  9. func search(searchString: String, isCase: Bool, display: Bool = true, needShowAll: Bool = false) {
  10. }
  11. func removeSignatures(signatures:[CPDFSignature]) {
  12. for signature in signatures {
  13. self.listView.document.removeSignature(signature)
  14. }
  15. for i in 0..<self.listView.document.pageCount {
  16. guard let page = self.listView.document.page(at: i) else {
  17. continue
  18. }
  19. let annotations : [CPDFAnnotation] = page.annotations
  20. for j in 0..<annotations.count {
  21. let annotation = annotations[j]
  22. if annotation is CPDFSignatureWidgetAnnotation {
  23. (annotation as! CPDFSignatureWidgetAnnotation).updateAppearanceStream()
  24. }
  25. }
  26. }
  27. self.listView.setNeedsDisplayForVisiblePages()
  28. let tSignatures : [CPDFSignature] = self.listView.document.signatures()
  29. var mSignatures : [CPDFSignature] = []
  30. for sign in tSignatures {
  31. if sign.signers.count > 0 {
  32. mSignatures.append(sign)
  33. }
  34. }
  35. }
  36. func numberOfChars(_ str: String) -> (num: Int, indexN: Int) {
  37. var number = 0
  38. var indexN = 0
  39. guard str.count > 0 else {return (0, 0)}
  40. for i in 0...str.count - 1 {
  41. let c: unichar = (str as NSString).character(at: i)
  42. if (c >= 0x4E00) {
  43. number += 2
  44. }else {
  45. number += 1
  46. }
  47. if number > 56{
  48. indexN = i
  49. number = 100
  50. break
  51. }
  52. }
  53. return (number, indexN)
  54. }
  55. func fontSizes()->NSArray {
  56. return ["6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "24", "36", "48", "72", "96", "144", "288"]
  57. }
  58. func handleRightMouseDown(theEvent: NSEvent) -> Bool {
  59. if interactionMode == .presentation {
  60. listView.goToPreviousPage(nil)
  61. return true
  62. }
  63. return false
  64. }
  65. func useNativeFullScreen() -> Bool {
  66. var isFull = false
  67. let sel = NSSelectorFromString("toggleFullscreen:")
  68. if NSWindow.instancesRespond(to: sel) && UserDefaults.standard.bool(forKey: "SKUseLegacyFullScreenKey"){
  69. isFull = true
  70. }
  71. return isFull
  72. }
  73. //MARK: menuItem Action
  74. @objc func menuItemEditingClick_FontColor(sender: NSMenuItem) {
  75. let color = listView.editingSelectionFontColor()
  76. let panel = NSColorPanel.shared
  77. panel.setTarget(self)
  78. panel.setAction(#selector(fontColorChangeAction))
  79. panel.orderFront(nil)
  80. panel.showsAlpha = false
  81. panel.color = color ?? NSColor.black
  82. }
  83. @objc func fontColorChangeAction(sender: NSColorPanel) {
  84. self.listView.setEditingSelectionFontColor(sender.color)
  85. }
  86. @objc func menuItemEditingClick_FontSize(sender: NSMenuItem) {
  87. let fontSize = self.fontSizes().object(at: sender.tag)
  88. self.listView.setEditingSelectionFontSize(CGFloat(Int(fontSize as! String)!))
  89. }
  90. @objc func addImageText(sender: NSMenuItem) {
  91. let event = NSApp.currentEvent
  92. let clickLocation = event?.locationInWindow
  93. var point = self.listView.convert(clickLocation!, from: NSApp.mainWindow?.contentView)
  94. var point2 = self.listView.convert(point, to: self.listView.currentPage())
  95. point2 = CGPoint(x: self.listView.bounds.width - point2.x, y: self.listView.bounds.height - point2.y)
  96. point = point2
  97. if sender.tag == 0 {
  98. KMPrint("添加文字")
  99. } else if sender.tag == 1 {
  100. } else if sender.tag == 2 {
  101. KMPrint("粘贴")
  102. }
  103. }
  104. @objc func menuItemEditingClick_CropImage(sender: NSMenuItem) {
  105. if self.listView.cropAreas != nil && self.listView.selectImageAreas != nil{
  106. self.listView.cropEditImageArea(self.listView.selectImageAreas, withBounds: self.listView.cropAreas.cropRect)
  107. }
  108. }
  109. @objc func menuItemAnnotationClick_toolModel(sender: NSMenuItem) {
  110. }
  111. @objc func changeAnnotationMode_itemAction(sender : NSMenuItem) {
  112. }
  113. @objc func menuItemAnnotationClick_add(sender : NSMenuItem) {
  114. var annotationType : CAnnotationType = .unkown
  115. switch sender.tag {
  116. case 0:
  117. annotationType = .highlight
  118. case 1:
  119. annotationType = .underline
  120. case 2:
  121. if sender.title == NSLocalizedString("Squiggly", comment: "") {
  122. annotationType = .squiggly
  123. } else {
  124. annotationType = .strikeOut
  125. }
  126. case 3:
  127. annotationType = .freeText
  128. case 4:
  129. annotationType = .anchored
  130. case 5:
  131. annotationType = .square
  132. case 6:
  133. annotationType = .circle
  134. case 7:
  135. annotationType = .line
  136. case 8:
  137. annotationType = .link
  138. case 9:
  139. return
  140. case 10:
  141. annotationType = .unkown
  142. default:
  143. break
  144. }
  145. if (annotationType != .link) {
  146. self.listView.addAnnotation(with: annotationType, selection: self.listView.currentSelection, page: self.listView.currentSelection.page, bounds: self.listView.currentSelection.bounds)
  147. self.listView.currentSelection = nil;
  148. return
  149. }
  150. // link
  151. let selection = self.listView.currentSelection
  152. DispatchQueue.main.async {
  153. Task { @MainActor in
  154. let annotation = self.listView.addAnnotation(with: annotationType, selection: selection, page: selection?.page, bounds: selection!.bounds)
  155. self.listView.currentSelection = nil;
  156. if (annotation != nil) {
  157. self.listView.updateActiveAnnotations([annotation!])
  158. }
  159. }
  160. }
  161. }
  162. @objc func menuItemAnnotationClick_addStype(sender: NSMenuItem) {
  163. Task { @MainActor in
  164. let idx = sender.tag
  165. if idx == 10 {
  166. if IAPProductsManager.default().isAvailableAllFunction() == false {
  167. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  168. return
  169. }
  170. }
  171. var point = mouseRightMenuEvent?.locationInWindow
  172. if (point == nil) {
  173. point = NSZeroPoint
  174. }
  175. let currentPoint: NSPoint = self.listView.convert(point!, from: self.listView.superview)
  176. let currentPage = self.listView.page(for: currentPoint, nearest: true)
  177. var pagePoint = self.listView.convert(currentPoint, to: currentPage)
  178. var annotation: CPDFAnnotation?
  179. if viewManager.isPDFReadMode {
  180. if (sender.tag == 0 || sender.tag == 7 || sender.tag == 8 || sender.tag == 9) { // Ink & Link & stamp & sign
  181. self.listView.toolMode = .CNoteToolMode
  182. }
  183. switch sender.tag {
  184. case 0:
  185. self.listView.annotationType = CAnnotationType.ink
  186. case 1:
  187. let defaultSize = self.listView.defaultSize(with: .freeText, in: currentPage)
  188. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  189. annotation = self.listView.addAnnotation(with: .freeText, selection: nil, page: currentPage, bounds: bounds)
  190. if ((annotation) != nil) {
  191. self.listView.updateActiveAnnotations([annotation!])
  192. self.listView.edit(annotation)
  193. }
  194. case 2:
  195. let defaultSize = self.listView.defaultSize(with: .anchored, in: currentPage)
  196. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  197. annotation = self.listView.addAnnotation(with: .anchored, selection: nil, page: currentPage, bounds: bounds)
  198. self.listView.edit(annotation)
  199. case 3:
  200. let defaultSize = self.listView.defaultSize(with: .square, in: currentPage)
  201. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  202. annotation = self.listView.addAnnotation(with: .square, selection: nil, page: currentPage, bounds: bounds)
  203. case 4:
  204. let defaultSize = self.listView.defaultSize(with: .circle, in: currentPage)
  205. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  206. annotation = self.listView.addAnnotation(with: .circle, selection: nil, page: currentPage, bounds: bounds)
  207. case 5:
  208. let defaultSize = self.listView.defaultSize(with: .arrow, in: currentPage)
  209. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  210. annotation = self.listView.addAnnotation(with: .arrow, selection: nil, page: currentPage, bounds: bounds)
  211. case 6:
  212. let defaultSize = self.listView.defaultSize(with: .line, in: currentPage)
  213. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  214. annotation = self.listView.addAnnotation(with: .line, selection: nil, page: currentPage, bounds: bounds)
  215. case 7:
  216. self.listView.annotationType = CAnnotationType.link
  217. toggleOpenRightSide()
  218. case 8:
  219. self.listView.annotationType = CAnnotationType.stamp
  220. toggleOpenRightSide()
  221. case 9:
  222. self.listView.annotationType = CAnnotationType.signSignature
  223. toggleOpenRightSide()
  224. default:
  225. break
  226. }
  227. } else {
  228. if (sender.tag == 7 || sender.tag == 8 || sender.tag == 9) { // Ink & Link & stamp & sign
  229. self.listView.toolMode = .CNoteToolMode
  230. }
  231. switch sender.tag {
  232. case 0:
  233. self.listView.toolMode = .CNoteToolMode
  234. self.listView.annotationType = CAnnotationType.ink
  235. case 1:
  236. let defaultSize = self.listView.defaultSize(with: .freeText, in: currentPage)
  237. if (pagePoint.x - defaultSize.width > 0){
  238. pagePoint.x -= defaultSize.width;
  239. }else{
  240. pagePoint.x = 0;
  241. }
  242. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  243. annotation = self.listView.addAnnotation(with: .freeText, selection: nil, page: currentPage, bounds: bounds)
  244. if ((annotation) != nil) {
  245. self.listView.edit(annotation)
  246. }
  247. case 2:
  248. let defaultSize = self.listView.defaultSize(with: .anchored, in: currentPage)
  249. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  250. annotation = self.listView.addAnnotation(with: .anchored, selection: nil, page: currentPage, bounds: bounds)
  251. self.listView.edit(annotation)
  252. case 3:
  253. let defaultSize = self.listView.defaultSize(with: .square, in: currentPage)
  254. if (pagePoint.x - defaultSize.width > 0){
  255. pagePoint.x -= defaultSize.width;
  256. }else{
  257. pagePoint.x = 0;
  258. }
  259. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  260. annotation = self.listView.addAnnotation(with: .square, selection: nil, page: currentPage, bounds: bounds)
  261. case 4:
  262. let defaultSize = self.listView.defaultSize(with: .circle, in: currentPage)
  263. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  264. annotation = self.listView.addAnnotation(with: .circle, selection: nil, page: currentPage, bounds: bounds)
  265. case 5:
  266. let defaultSize = self.listView.defaultSize(with: .arrow, in: currentPage)
  267. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  268. annotation = self.listView.addAnnotation(with: .arrow, selection: nil, page: currentPage, bounds: bounds)
  269. case 6:
  270. let defaultSize = self.listView.defaultSize(with: .line, in: currentPage)
  271. let bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize)
  272. annotation = self.listView.addAnnotation(with: .line, selection: nil, page: currentPage, bounds: bounds)
  273. case 7:
  274. self.listView.annotationType = CAnnotationType.link
  275. toggleOpenRightSide()
  276. case 8:
  277. self.listView.annotationType = CAnnotationType.stamp
  278. toggleOpenRightSide()
  279. case 9:
  280. self.listView.annotationType = CAnnotationType.signSignature
  281. toggleOpenRightSide()
  282. case 10:
  283. self.addImgAnnotationToView(center: pagePoint)
  284. default:
  285. break
  286. }
  287. if annotation != nil{
  288. self.listView.activeAnnotations.removeAllObjects()
  289. var newAnnonations : [CPDFAnnotation] = []
  290. newAnnonations.append(annotation!)
  291. self.listView.updateActiveAnnotations(newAnnonations)
  292. }
  293. }
  294. }
  295. }
  296. func addImgAnnotationToView(center: NSPoint) {
  297. let accessoryCtr = KMImageAccessoryController()
  298. let openPanel = NSOpenPanel()
  299. openPanel.allowedFileTypes = KMImageAccessoryController.supportedImageTypes()
  300. openPanel.allowsMultipleSelection = false
  301. openPanel.accessoryView = accessoryCtr.view
  302. openPanel.isAccessoryViewDisclosed = true
  303. openPanel.beginSheetModal(for: self.view.window!) { result in
  304. if result == .OK {
  305. let fileURL = openPanel.urls.first
  306. let filePath = fileURL!.path
  307. if filePath.pathExtension == "pdf" {
  308. let pdf = CPDFDocument(url: fileURL)
  309. if pdf!.isEncrypted {
  310. NSSound.beep()
  311. return
  312. }
  313. }
  314. let img = NSImage(contentsOfFile: filePath)
  315. let isRemoveBGColor = accessoryCtr.selectedButton.state == .on
  316. self.listView.addImageAnnotation(img, center: center, isRemoveBGColor: isRemoveBGColor)
  317. }
  318. }
  319. }
  320. // MARK: - Measure
  321. @objc func menuItemActionMeasureProperty(sender: NSMenuItem) {
  322. guard let anno = sender.representedObject as? CPDFAnnotation else {
  323. return
  324. }
  325. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  326. distanceMeasureInfoWindowController?.hideFloatingWindow()
  327. } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
  328. perimeterMeasureInfoWindowController?.hideFloatingWindow()
  329. } else if areaMeasureInfoWindowController?.window?.isVisible == true {
  330. areaMeasureInfoWindowController?.hideFloatingWindow()
  331. }
  332. self.listView.updateActiveAnnotations([anno])
  333. self.pdfListViewChangeatioActiveAnnotations(self.listView, forActiveAnnotations: [anno], isRightMenu: false)
  334. self.listView.setNeedsDisplayForVisiblePages()
  335. }
  336. @objc func menuItemActionMeasureEditNote(sender: NSMenuItem) {
  337. guard let anno = sender.representedObject as? CPDFAnnotation else {
  338. return
  339. }
  340. self.listView.edit(anno)
  341. }
  342. @objc func menuItemActionMeasureSetting(sender: NSMenuItem) {
  343. guard let anno = sender.representedObject as? CPDFAnnotation else {
  344. return
  345. }
  346. self.listView.updateActiveAnnotations([anno])
  347. self.listView.setNeedsDisplayForVisiblePages()
  348. if let data = anno as? CPDFLineAnnotation, data.isMeasure {
  349. self.showMeasureDistanceSettingWindow(measureInfo: data.measureInfo)
  350. } else if let data = anno as? CPDFPolylineAnnotation {
  351. self.showMeasurePerimeterSettingWindow(measureInfo: data.measureInfo)
  352. } else if let data = anno as? CPDFPolygonAnnotation {
  353. self.showMeasureAreaSettingWindow(measureInfo: data.measureInfo)
  354. }
  355. }
  356. @objc func menuItemActionMeasureDelete(sender: NSMenuItem) {
  357. guard let anno = sender.representedObject as? CPDFAnnotation else {
  358. return
  359. }
  360. self.listView.remove(anno)
  361. }
  362. func showMeasureDistanceSettingWindow(measureInfo: CPDFDistanceMeasureInfo?, hideInfoWindow: Bool = true) {
  363. guard let mInfo = measureInfo else {
  364. return
  365. }
  366. }
  367. func showMeasurePerimeterSettingWindow(measureInfo: CPDFPerimeterMeasureInfo?, hideInfoWindow: Bool = true) {
  368. guard let mInfo = measureInfo else {
  369. return
  370. }
  371. }
  372. func showMeasureAreaSettingWindow(measureInfo: CPDFAreaMeasureInfo?, hideInfoWindow: Bool = true) {
  373. guard let mInfo = measureInfo else {
  374. return
  375. }
  376. }
  377. // MARK: - 幻灯片
  378. func fadeInFullScreenWindow(with backgroundColor: NSColor, level: Int) {
  379. let view: NSView = self.view.window!.firstResponder as! NSView
  380. if view.isDescendant(of: pdfSplitView){
  381. self.view.window?.makeFirstResponder(nil)
  382. }
  383. self.mainWindow = self.view.window
  384. let fullScreenWindow = KMFullScreenWindow(screen: (self.mainWindow?.screen ?? NSScreen.main)!, bgColor: backgroundColor, level: NSWindow.Level.popUpMenu.rawValue, isMain: true)
  385. fullScreenWindow.interactionParent = self.view.window
  386. self.mainWindow?.delegate = nil
  387. fullScreenWindow.fadeInBlocking()
  388. self.browserWindowController?.window = fullScreenWindow
  389. fullScreenWindow.makeKey()
  390. let sel = NSSelectorFromString("setAnimationBehavior:")
  391. if self.mainWindow?.responds(to: sel) ?? false{
  392. self.mainWindow?.animationBehavior = .none
  393. }
  394. self.mainWindow?.orderOut(nil)
  395. if self.mainWindow?.responds(to: sel) ?? false{
  396. self.mainWindow?.animationBehavior = .default
  397. }
  398. fullScreenWindow.level = NSWindow.Level(rawValue: level)
  399. fullScreenWindow.orderFront(nil)
  400. }
  401. func fadeInFullScreenView(_ view: NSView, inset: CGFloat) {
  402. guard let fullScreenWindow = self.browserWindowController?.window as? KMFullScreenWindow else {
  403. return
  404. }
  405. let fadeWindow = KMFullScreenWindow(screen: fullScreenWindow.screen!, bgColor: fullScreenWindow.backgroundColor, level: fullScreenWindow.level.rawValue, isMain: false)
  406. fadeWindow.order(.above, relativeTo: fullScreenWindow.windowNumber)
  407. view.frame = NSInsetRect(fullScreenWindow.contentView?.bounds ?? .zero, inset, 0)
  408. fullScreenWindow.contentView?.addSubview(view)
  409. self.listView.layoutDocumentView()
  410. self.listView.requiresDisplay()
  411. fullScreenWindow.makeFirstResponder(self.listView)
  412. fullScreenWindow.recalculateKeyViewLoop()
  413. fullScreenWindow.delegate = self.browserWindowController
  414. fullScreenWindow.display()
  415. fadeWindow.fadeOut()
  416. }
  417. @IBAction func doZoomToAutoSelection(sender:NSMenuItem) {
  418. let rect = listView.currentSelectionRect()
  419. let page = listView.currentPage()
  420. if NSIsEmptyRect(rect) == false && page != nil {
  421. let isLegacy = NSScroller.responds(to: NSSelectorFromString("preferredScrollerStyle")) == false || NSScroller.preferredScrollerStyle == .legacy
  422. var bounds = listView.bounds
  423. var scale = 1.0
  424. if isLegacy {
  425. bounds.size.width -= NSScroller.scrollerWidth(for: .regular, scrollerStyle: listView.documentView().scrollerStyle)
  426. bounds.size.height -= NSScroller.scrollerWidth(for: .regular, scrollerStyle: listView.documentView().scrollerStyle)
  427. }
  428. if NSWidth(bounds) * NSHeight(rect) > NSWidth(rect) * NSHeight(bounds) {
  429. scale = NSHeight(bounds) / NSHeight(rect)
  430. } else {
  431. scale = NSWidth(bounds) / NSWidth(rect)
  432. }
  433. listView.setScaleFactor(scale, animated: false)
  434. let scrollView = listView.scroll()
  435. if isLegacy && scrollView?.hasHorizontalScroller == false || scrollView?.hasVerticalScroller == false {
  436. if ((scrollView?.hasVerticalScroller) != nil) {
  437. bounds.size.width -= NSScroller.scrollerWidth(for: .regular, scrollerStyle: listView.documentView().scrollerStyle)
  438. }
  439. if ((scrollView?.hasHorizontalScroller) != nil) {
  440. bounds.size.height -= NSScroller.scrollerWidth(for: .regular, scrollerStyle: listView.documentView().scrollerStyle)
  441. }
  442. if NSWidth(bounds) * NSHeight(rect) > NSWidth(rect) * NSHeight(bounds) {
  443. scale = NSHeight(bounds) / NSHeight(rect)
  444. } else {
  445. scale = NSWidth(bounds) / NSWidth(rect)
  446. }
  447. listView.setScaleFactor(scale, animated: false)
  448. }
  449. DispatchQueue.main.asyncAfter(deadline: .now() + 0.03) { [self] in
  450. let pagePoint = CGPoint(x: rect.origin.x, y: (rect.origin.y + rect.size.height))
  451. listView.go(toTargetPoint: pagePoint, on: page, at: .top)
  452. };
  453. }
  454. // 执行右键操作后,需要取消框选区域
  455. if self.listView.toolMode == .CSelectToolMode {
  456. objc_sync_enter(self)
  457. self.listView.selectionRect = NSZeroRect
  458. self.listView.selectionPageIndex = UInt(NSNotFound)
  459. objc_sync_exit(self)
  460. }
  461. }
  462. @IBAction func toggleSplitPDF(_ sender: Any) {
  463. }
  464. // MARK: - 图片注释
  465. @IBAction func imageAnnotation(_ sender: Any) {
  466. FMTrackEventManager.defaultManager.trackEvent(event: "SubTbr_Tools", withProperties: ["SubTbr_Btn": "Btn_SubTbr_Tools_Image"])
  467. guard IAPProductsManager.default().isAvailableAllFunction() else {
  468. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  469. return
  470. }
  471. let accessoryCtr = KMImageAccessoryController()
  472. let openPanel = NSOpenPanel()
  473. openPanel.allowedFileTypes = KMImageAccessoryController.supportedImageTypes()
  474. openPanel.allowsMultipleSelection = false
  475. openPanel.accessoryView = accessoryCtr.view
  476. openPanel.canSelectHiddenExtension = true
  477. openPanel.beginSheetModal(for: NSApp.mainWindow!) { [self] (result) in
  478. if result == .OK {
  479. guard let url = openPanel.url else {
  480. return
  481. }
  482. let filePath = url.path
  483. if filePath.pathExtension.lowercased() == "pdf" {
  484. if let pdf = PDFDocument(url: url), pdf.isEncrypted {
  485. NSSound.beep()
  486. return
  487. }
  488. }
  489. guard let image = NSImage(contentsOfFile: url.path) else {
  490. let alert = NSAlert()
  491. alert.alertStyle = .critical
  492. alert.messageText = String(format: NSLocalizedString("The file \"%@\" could not be opened.", comment: ""), url.lastPathComponent)
  493. alert.informativeText = NSLocalizedString("It may be damaged or use a file format that PDF Reader Pro doesn’t recognize.", comment: "")
  494. alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
  495. alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in
  496. if response == .alertFirstButtonReturn {
  497. // Handle cancel button clicked
  498. }
  499. }
  500. return
  501. }
  502. let isDamageImage: Bool = self.isDamageImage(image, imagePath: url.path)
  503. if isDamageImage {
  504. let alert = NSAlert()
  505. alert.alertStyle = .critical
  506. alert.messageText = String(format: NSLocalizedString("The file \"%@\" could not be opened.", comment: ""), url.lastPathComponent)
  507. alert.informativeText = NSLocalizedString("It may be damaged or use a file format that PDF Reader Pro doesn’t recognize.", comment: "")
  508. alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
  509. alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in
  510. if response == .alertFirstButtonReturn {
  511. // Handle cancel button clicked
  512. }
  513. }
  514. return
  515. }
  516. let isRemoveBGColor = accessoryCtr.selectedButton.state == .on
  517. listView.addAnnotation(with: image, isRemoveBGColor: isRemoveBGColor)
  518. if (self.listView.activeAnnotation != nil) && (self.listView.activeAnnotation.type == "Image") {
  519. }
  520. }
  521. }
  522. }
  523. @IBAction func tableAnnotation(_ sender: Any) {
  524. FMTrackEventManager.defaultManager.trackEvent(event: "SubTbr_Tools", withProperties: ["SubTbr_Btn": "Btn_SubTbr_Tools_Table"])
  525. guard IAPProductsManager.default().isAvailableAllFunction() else {
  526. let winC = KMPurchaseCompareWindowController.sharedInstance()
  527. winC?.kEventName = "Reading_Table_BuyNow"
  528. winC?.showWindow(nil)
  529. return
  530. }
  531. listView.addAnnotationWithTable()
  532. toggleOpenRightSide()
  533. }
  534. func isDamageImage(_ image: NSImage, imagePath path: String) -> Bool {
  535. let addImageAnnotation = (NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).last! as NSString).appendingPathComponent(Bundle.main.bundleIdentifier!)
  536. if !FileManager.default.fileExists(atPath: addImageAnnotation) {
  537. try? FileManager.default.createDirectory(atPath: addImageAnnotation, withIntermediateDirectories: false, attributes: nil)
  538. }
  539. if let data = image.tiffRepresentation,
  540. let imageRep = NSBitmapImageRep(data: data) {
  541. imageRep.size = image.size
  542. var imageData: Data?
  543. if path.lowercased() == "png" {
  544. imageData = imageRep.representation(using: .png, properties: [:])
  545. } else {
  546. imageData = imageRep.representation(using: .jpeg, properties: [:])
  547. }
  548. if let imageData = imageData {
  549. let rPath = (addImageAnnotation as NSString).appendingPathComponent((self.tagString() as NSString).appendingPathExtension("png")!)
  550. if !((try? imageData.write(to: URL(fileURLWithPath: rPath), options: .atomicWrite)) != nil) {
  551. return true
  552. } else {
  553. return false
  554. }
  555. }
  556. }
  557. return false
  558. }
  559. func tagString() -> String {
  560. let dateFormatter = DateFormatter()
  561. dateFormatter.dateFormat = "yyMMddHHmmss"
  562. return "\(dateFormatter.string(from: Date()))\(Int.random(in: 0..<10000))"
  563. }
  564. }
  565. extension KMMainViewController {
  566. func changeModelAction(mode: CToolMode) {
  567. self.listView.toolMode = mode
  568. if mode == .CEditPDFToolMode {
  569. }
  570. }
  571. func aiTranslationPDFFileAction() {
  572. self._aiTranslationPDFFileAction()
  573. }
  574. private func _aiTranslationPDFFileAction() {
  575. let isExceedsLimit = self.isPDFPageCountExceedsLimit(filePath: (self.document?.documentURL.path)!)
  576. if KMTools.isFileGreaterThan10MB(atPath: (self.document?.documentURL.path)!) {
  577. let alert = NSAlert()
  578. alert.alertStyle = .critical
  579. alert.messageText = NSLocalizedString("The uploaded file size cannot exceed 10MB", comment: "")
  580. alert.runModal()
  581. return
  582. } else if isExceedsLimit {
  583. let alert = NSAlert()
  584. alert.alertStyle = .critical
  585. alert.messageText = NSLocalizedString("Documents cannot exceed 30 pages", comment: "")
  586. alert.runModal()
  587. return
  588. }
  589. let alert = NSAlert()
  590. alert.messageText = NSLocalizedString("Processing times may be longer for larger documents. Thank you for your patience.", comment: "")
  591. alert.addButton(withTitle: NSLocalizedString("Continue", comment: ""))
  592. alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
  593. alert.beginSheetModal(for: view.window!) { [weak self] result in
  594. if (result == .alertFirstButtonReturn) {
  595. } else if result == .alertSecondButtonReturn {
  596. return
  597. }
  598. }
  599. }
  600. func openNewWindowAlertWindow() {
  601. var needShowChooseWindow = false
  602. //#if VERSION_FREE
  603. if (!IAPProductsManager.default().isAvailableAllFunction()) {
  604. needShowChooseWindow = true
  605. }
  606. //#endif
  607. if needShowChooseWindow {
  608. let preferenceNoteShow = UserDefaults.standard.bool(forKey: KMTabbingHintShowFlag)
  609. if preferenceNoteShow {
  610. } else {
  611. if !KMDataManager.default.isTabbingWin{
  612. KMDataManager.default.isTabbingWin = true
  613. let tabbingWin: KMTabbingHintWindowController = KMTabbingHintWindowController()
  614. tabbingWin.selectCallBack = {[weak self] continueOrNot in
  615. KMDataManager.default.isTabbingWin = false
  616. if continueOrNot {
  617. self?.reopenDocument(forPaths: [])
  618. } else {
  619. }
  620. }
  621. self.km_beginSheet(windowC: tabbingWin)
  622. }
  623. }
  624. }else{
  625. handleTabbingLogic()
  626. }
  627. }
  628. func reopenDocument(forPaths paths: [String]) -> Void {
  629. let browser = KMBrowser.init() as KMBrowser
  630. browser.windowController = KMBrowserWindowController.init(browser: browser)
  631. browser.addHomeTabContents()
  632. browser.windowController.showWindow(self)
  633. }
  634. func handleTabbingLogic() {
  635. self.browserWindowController?.browser?.selectTabContents(at: 0, userGesture: true)
  636. }
  637. }
  638. //MARK: LeftSideViewController
  639. extension KMMainViewController {
  640. func leftSideViewCancelSelect() {
  641. if self.listView.isEditing() == true {
  642. if self.listView.editingAreas() != nil &&
  643. self.listView.editingAreas().count != 0 {
  644. let areas = self.listView.editingAreas().first
  645. if areas is CPDFEditTextArea {
  646. self.listView.clearEditingSelectCharItem()
  647. self.listView.updateEditing([])
  648. KMPrint("取消选中")
  649. }
  650. }
  651. }
  652. }
  653. }
  654. extension KMMainViewController {
  655. func documentAllowsEdit() -> Bool {
  656. if (self.listView.document.allowsCopying == false || self.listView.document.allowsPrinting == false) {
  657. let alert = NSAlert()
  658. alert.alertStyle = .critical
  659. alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "")
  660. alert.runModal()
  661. return false
  662. } else {
  663. return true
  664. }
  665. }
  666. func currentSetup() -> [String: Any] {
  667. var setup: [String: Any] = [:]
  668. var point = NSZeroPoint
  669. if listView == nil {
  670. return setup
  671. }
  672. let pageIndex = listView.currentPageIndexAndPoint(&point, rotated: nil)
  673. setup[kWindowFrameKey] = NSStringFromRect(mainWindow?.frame ?? NSZeroRect)
  674. setup[KMMainModel.Key.pageIndex] = pageIndex
  675. return setup
  676. }
  677. }