KMPDFViewController.swift 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. //
  2. // KMPDFViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by Niehaoyu on 2024/10/18.
  6. //
  7. import Cocoa
  8. class KMPDFViewController: NSViewController {
  9. @IBOutlet var contendBox: NSBox!
  10. @IBOutlet var toolbarBox: NSBox! //工具栏Box
  11. @IBOutlet var bottomContendBox: NSBox! //
  12. @IBOutlet var sidebarBox: NSBox! //左侧边栏Box
  13. @IBOutlet var infoContendSplitView: KMPDFSplitView!
  14. @IBOutlet var infoSplitLeftView: NSView!
  15. @IBOutlet var infoSplitRightView: NSView!
  16. @IBOutlet var infoSplitCenterView: NSView!
  17. @IBOutlet var pdfSplitView: NSSplitView!
  18. @IBOutlet var pdfSplitTopView: NSView!
  19. @IBOutlet var pdfSplitBottomView: NSView!
  20. @IBOutlet var toolbarBoxHeightConst: NSLayoutConstraint!
  21. @IBOutlet var infoSplitViewLeftConst: NSLayoutConstraint!
  22. var viewManager: KMPDFViewManager = KMPDFViewManager.init()
  23. var toolbarManager: KMPDFToolbarManager = KMPDFToolbarManager.init()
  24. var pdfView: CPDFListView!
  25. var document: CPDFDocument?
  26. var myDocument: NSDocument?
  27. var insertDocuments: Set<CPDFDocument> = [] //插入新文档时,SDK会出现崩溃,临时记录
  28. //工具栏
  29. private var pdfToolbarController: KMPDFToolbarController?
  30. //BOTA SideBar
  31. private var sideBarController: KMPDFSideBarController?
  32. //页面编辑
  33. private var pageEditViewController: KMNPageEditViewController?
  34. //DisplaySetting
  35. private var displaySettingController: KMNDisplayViewController?
  36. private var splitPDFController: KMSplitPDFViewController?
  37. override func viewDidLoad() {
  38. super.viewDidLoad()
  39. // Do view setup here.
  40. toolbarManager.pdfViewManager = viewManager
  41. }
  42. override func viewDidAppear() {
  43. super.viewDidAppear()
  44. setupUI()
  45. }
  46. func setupUI() {
  47. initPDFView()
  48. initToolbar()
  49. initSideBar()
  50. setUpSplitView()
  51. }
  52. //MARK: - PDFView
  53. func initPDFView() {
  54. if pdfView == nil {
  55. pdfView = CPDFListView.init(frame: CGRectMake(0, 0, 100, 100))
  56. pdfView?.autoresizingMask = [.width, .height]
  57. }
  58. pdfView.document = self.document
  59. pdfView.delegate = self
  60. pdfView.pdfListViewDelegate = self
  61. reloadPDFSplitInfo()
  62. }
  63. //MARK: - SplitView
  64. func setUpSplitView() {
  65. infoContendSplitView.wantsLayer = true
  66. infoContendSplitView.layer?.backgroundColor = NSColor.clear.cgColor
  67. infoContendSplitView.delegate = self
  68. infoContendSplitView.layer?.masksToBounds = true
  69. infoContendSplitView.setPosition(-10, ofDividerAt: 0)
  70. infoContendSplitView.setPosition(CGRectGetWidth(infoContendSplitView.frame), ofDividerAt: 1)
  71. }
  72. func setupSplitPDFController() {
  73. if splitPDFController == nil {
  74. splitPDFController = KMSplitPDFViewController.init()
  75. }
  76. splitPDFController?.view.frame = pdfSplitBottomView.bounds
  77. splitPDFController?.view.autoresizingMask = [.height, .width]
  78. splitPDFController?.viewManager = self.viewManager
  79. splitPDFController?.delegate = self
  80. pdfSplitBottomView.addSubview(splitPDFController!.view)
  81. }
  82. //MARK: - 工具栏
  83. func initToolbar() {
  84. toolbarBox.borderWidth = 0
  85. if pdfToolbarController == nil {
  86. pdfToolbarController = KMPDFToolbarController.init()
  87. }
  88. pdfToolbarController?.view.frame = toolbarBox.bounds
  89. pdfToolbarController?.view.autoresizingMask = [.width, .height]
  90. pdfToolbarController?.delegate = self
  91. toolbarBox.contentView = pdfToolbarController?.view
  92. pdfToolbarController?.viewManager = viewManager
  93. pdfToolbarController?.toolbarManager = toolbarManager
  94. pdfToolbarController?.pdfView = pdfView
  95. pdfToolbarController?.setUpData()
  96. refreshToolbarView()
  97. }
  98. func refreshToolbarView() {
  99. let _manager = viewManager
  100. if _manager.toolMode == .Markup ||
  101. _manager.toolMode == .Edit ||
  102. _manager.toolMode == .Form ||
  103. _manager.toolMode == .Fill ||
  104. _manager.toolMode == .Convert ||
  105. _manager.toolMode == .Protect ||
  106. _manager.toolMode == .Tools {
  107. toolbarBoxHeightConst.constant = 80
  108. } else {
  109. if _manager.isPageEditMode {
  110. toolbarBoxHeightConst.constant = 80
  111. } else {
  112. toolbarBoxHeightConst.constant = 40
  113. }
  114. }
  115. }
  116. //MARK: - 侧边栏
  117. func initSideBar() {
  118. sidebarBox.borderWidth = 0
  119. if sideBarController == nil {
  120. sideBarController = KMPDFSideBarController.init()
  121. }
  122. sideBarController?.view.frame = sidebarBox.bounds
  123. sideBarController?.view.autoresizingMask = [.width, .height]
  124. sidebarBox.contentView = sideBarController?.view
  125. sideBarController?.pdfView = pdfView
  126. sideBarController?.delegate = self
  127. sideBarController?.pdfViewManager = viewManager
  128. sideBarController?.reloadData()
  129. }
  130. //MARK: - PDFDisplayView
  131. func updatePDFDisplaySettingView() {
  132. if viewManager.showDisplayView {
  133. infoSplitViewLeftConst.constant = 264
  134. } else {
  135. infoSplitViewLeftConst.constant = 44
  136. }
  137. if viewManager.showDisplayView {
  138. if displaySettingController == nil {
  139. displaySettingController = KMNDisplayViewController.init()
  140. }
  141. displaySettingController?.view.frame = CGRectMake(0, 0, 264, CGRectGetHeight(bottomContendBox.frame))
  142. displaySettingController?.view.autoresizingMask = [.height, .maxXMargin]
  143. bottomContendBox.addSubview(displaySettingController!.view)
  144. displaySettingController?.pdfView = self.pdfView
  145. displaySettingController?.viewManager = self.viewManager
  146. displaySettingController?.delegate = self
  147. displaySettingController?.reloadData()
  148. } else {
  149. displaySettingController?.view.removeFromSuperview()
  150. displaySettingController = nil
  151. }
  152. }
  153. //MARK: - 页面编辑
  154. func enterPageEditMode() {
  155. pageEditViewController = KMNPageEditViewController(self.document)
  156. if(pageEditViewController != nil) {
  157. bottomContendBox.addSubview(pageEditViewController!.view)
  158. pageEditViewController?.view.frame = bottomContendBox.bounds
  159. pageEditViewController?.thumbnailBaseViewDelegate = self
  160. pageEditViewController?.view.autoresizingMask = [.width,.height]
  161. }
  162. }
  163. func exitPageEditMode() {
  164. if pageEditViewController != nil {
  165. pageEditViewController?.view.removeFromSuperview()
  166. pageEditViewController = nil
  167. }
  168. }
  169. //MARK: - 阅读模式
  170. func openPDFReadMode() {
  171. if viewManager.showDisplayView {
  172. viewManager.showDisplayView = false
  173. pdfToolbarController?.reloadLeftIconView()
  174. updatePDFDisplaySettingView()
  175. }
  176. infoSplitViewLeftConst.constant = 0
  177. toolbarBoxHeightConst.constant = 0
  178. }
  179. func exitPDFReadMode() {
  180. viewManager.isPDFReadMode = false
  181. infoSplitViewLeftConst.constant = 44
  182. refreshToolbarView()
  183. }
  184. //MARK: - PPT
  185. //MARK: - PDF分割
  186. func reloadPDFSplitInfo() {
  187. if pdfView?.viewSplitMode == .disable {
  188. pdfSplitView.isHidden = true
  189. pdfView.frame = infoSplitCenterView.bounds
  190. infoSplitCenterView.addSubview(pdfView)
  191. if splitPDFController != nil {
  192. splitPDFController = nil
  193. }
  194. } else {
  195. pdfSplitView.isHidden = false
  196. pdfView.frame = pdfSplitTopView.bounds
  197. pdfSplitTopView.addSubview(pdfView)
  198. setupSplitPDFController()
  199. if pdfView.viewSplitMode == .horizontal {
  200. pdfSplitView.isVertical = true
  201. } else if pdfView.viewSplitMode == .vertical {
  202. pdfSplitView.isVertical = false
  203. }
  204. }
  205. }
  206. }
  207. //MARK: - NSSplitViewDelegate
  208. extension KMPDFViewController: NSSplitViewDelegate {
  209. func splitView(_ splitView: NSSplitView, shouldHideDividerAt dividerIndex: Int) -> Bool {
  210. return true
  211. }
  212. func splitView(_ splitView: NSSplitView, canCollapseSubview subview: NSView) -> Bool {
  213. return true
  214. }
  215. func splitView(_ splitView: NSSplitView, constrainSplitPosition proposedPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  216. if dividerIndex == 0 {
  217. if proposedPosition > CGRectGetWidth(infoContendSplitView.frame)/2 - 10 {
  218. print(CGRectGetWidth(infoContendSplitView.frame)/2 - 10, NSDate())
  219. return CGRectGetWidth(infoContendSplitView.frame)/2 - 10
  220. }
  221. } else if dividerIndex == 1 {
  222. print(CGRectGetWidth(infoContendSplitView.frame)/2 - 10, NSDate())
  223. }
  224. return proposedPosition
  225. }
  226. func splitViewDidResizeSubviews(_ notification: Notification) {
  227. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(splitViewResizeFinish), object: nil)
  228. self.perform(#selector(splitViewResizeFinish), with: nil, afterDelay: 0.15)
  229. }
  230. @objc func splitViewResizeFinish() {
  231. if infoContendSplitView.isSubviewCollapsed(infoSplitLeftView) {
  232. if viewManager.pdfSideBarType != .none {
  233. viewManager.pdfSideBarType = .none
  234. sideBarController?.reloadBOTAData()
  235. }
  236. }
  237. }
  238. }
  239. //MARK: - KMPDFSideBarControllerDelegate 左侧Sidebar代理
  240. extension KMPDFViewController: KMPDFSideBarControllerDelegate {
  241. func kmPDFSideBarControllerDidSidebarTypeUpdated(_ view: KMPDFSideBarController) {
  242. if viewManager.pdfSideBarType == .none {
  243. infoContendSplitView.setPosition(-20, ofDividerAt: 0)
  244. } else if viewManager.pdfSideBarType == .search {
  245. infoContendSplitView.setPosition(264, ofDividerAt: 0)
  246. } else if viewManager.pdfSideBarType == .thumbnail {
  247. infoContendSplitView.setPosition(264, ofDividerAt: 0)
  248. } else if viewManager.pdfSideBarType == .outline {
  249. infoContendSplitView.setPosition(264, ofDividerAt: 0)
  250. } else if viewManager.pdfSideBarType == .bookmark {
  251. infoContendSplitView.setPosition(264, ofDividerAt: 0)
  252. } else if viewManager.pdfSideBarType == .annotation {
  253. infoContendSplitView.setPosition(264, ofDividerAt: 0)
  254. }
  255. }
  256. func kmPDFSideBarControllerDidGotoPage(_ view: KMPDFSideBarController, _ pageIndex: Int) {
  257. pdfView.go(toPageIndex: pageIndex, animated: true)
  258. }
  259. }
  260. //MARK: - KMPDFToolbarControllerDelegate 工具栏代理
  261. extension KMPDFViewController: KMPDFToolbarControllerDelegate {
  262. func kmPDFToolbarControllerDidToolbarItemClicked(_ controller: KMPDFToolbarController, _ itemIdentifier: String) {
  263. print("toolbar点击", itemIdentifier)
  264. if itemIdentifier == KMPDFToolbar_ViewDisplay_Identifier {
  265. updatePDFDisplaySettingView()
  266. } else if itemIdentifier == KMPDFToolbar_PageEdit_Identifier {
  267. if viewManager.isPageEditMode == true {
  268. enterPageEditMode()
  269. } else {
  270. exitPageEditMode()
  271. }
  272. } else if itemIdentifier == KMPDFToolbar_convert_word_Identifier {
  273. let winC = KMConvertWordWindowController()
  274. let model = KMDocumentModel(url: self.pdfView.document.documentURL)
  275. winC.documentModel = model
  276. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  277. } else if itemIdentifier == KMPDFToolbar_convert_ppt_Identifier {
  278. let winC = KMConvertPPTsWindowController()
  279. winC.subType = 1
  280. let model = KMDocumentModel(url: self.pdfView.document.documentURL)
  281. winC.documentModel = model
  282. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  283. } else if itemIdentifier == KMPDFToolbar_convert_RTF_Identifier {
  284. let winC = KMConvertPPTsWindowController()
  285. winC.subType = 2
  286. let model = KMDocumentModel(url: self.pdfView.document.documentURL)
  287. winC.documentModel = model
  288. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  289. } else if itemIdentifier == KMPDFToolbar_convert_Text_Identifier {
  290. let winC = KMConvertPPTsWindowController()
  291. winC.subType = 4
  292. let model = KMDocumentModel(url: self.pdfView.document.documentURL)
  293. winC.documentModel = model
  294. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  295. } else if itemIdentifier == KMPDFToolbar_convert_CSV_Identifier {
  296. let winC = KMConvertPPTsWindowController()
  297. winC.subType = 5
  298. let model = KMDocumentModel(url: self.pdfView.document.documentURL)
  299. winC.documentModel = model
  300. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  301. } else if itemIdentifier == KMPDFToolbar_convert_excel_Identifier {
  302. let winC = KMConvertExcelWindowController()
  303. let model = KMDocumentModel(url: self.pdfView.document.documentURL)
  304. winC.documentModel = model
  305. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  306. } else if itemIdentifier == KMPDFToolbar_convert_image_Identifier {
  307. let winC = KMConvertImageWindowController()
  308. let model = KMDocumentModel(url: self.pdfView.document.documentURL)
  309. winC.documentModel = model
  310. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  311. } else if itemIdentifier == KMPDFToolbar_convert_HTML_Identifier {
  312. let winC = KMConvertHtmlWindowController()
  313. let model = KMDocumentModel(url: self.pdfView.document.documentURL)
  314. winC.documentModel = model
  315. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  316. } else if itemIdentifier == KMPDFToolbar_convert_Json_Identifier {
  317. let winC = KMConvertJsonWindowController()
  318. let model = KMDocumentModel(url: self.pdfView.document.documentURL)
  319. winC.documentModel = model
  320. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  321. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertFile_Identifier {
  322. pageEditViewController?.insertFromPDFAction()
  323. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertBlank_Identifier {
  324. pageEditViewController?.insertFromBlankAction()
  325. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertClip_Identifier {
  326. pageEditViewController?.insertFromClipboardAction()
  327. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertScanner_Identifier {
  328. pageEditViewController?.insertFromScannerAction()
  329. } else if itemIdentifier == KMPDFToolbar_PageEdit_Extract_Identifier {
  330. pageEditViewController?.extractPDFAction()
  331. } else if itemIdentifier == KMPDFToolbar_PageEdit_Replace_Identifier {
  332. pageEditViewController?.replacePDFAction()
  333. } else if itemIdentifier == KMPDFToolbar_PageEdit_Split_Identifier {
  334. pageEditViewController?.splitPDFAction()
  335. } else if itemIdentifier == KMPDFToolbar_PageEdit_Reverse_Identifier {
  336. pageEditViewController?.reversePDFAction()
  337. } else if itemIdentifier == KMPDFToolbar_PageEdit_LeftRotate_Identifier {
  338. pageEditViewController?.rotatePageLeftAction()
  339. } else if itemIdentifier == KMPDFToolbar_PageEdit_RightRotate_Identifier{
  340. pageEditViewController?.rotatePageRightAction()
  341. } else if itemIdentifier == KMPDFToolbar_PageEdit_Delete_Identifier {
  342. pageEditViewController?.deletePageAction()
  343. } else if itemIdentifier == KMPDFToolbar_PageEdit_Reduce_Identifier {
  344. pageEditViewController?.zoomOutPageAction()
  345. } else if itemIdentifier == KMPDFToolbar_PageEdit_Increase_Identifier {
  346. pageEditViewController?.zoomInPageAction()
  347. }
  348. refreshToolbarView()
  349. }
  350. }
  351. //MARK: - KMNDisplayViewControllerDelegate代理
  352. extension KMPDFViewController: KMNDisplayViewControllerDelegate {
  353. //Display Mode
  354. func displayViewControllerDidDisplayModeChanged(_ controller: KMNDisplayViewController) {
  355. pdfView.layoutDocumentView()
  356. }
  357. //阅读模式
  358. func displayViewControllerDidReadModeUpdated(_ controller: KMNDisplayViewController) {
  359. if viewManager.isPDFReadMode {
  360. openPDFReadMode()
  361. } else {
  362. exitPDFReadMode()
  363. }
  364. }
  365. //PPT
  366. func displayViewControllerDidGotoSlideShow(_ controller: KMNDisplayViewController) {
  367. }
  368. //SplitView
  369. func displayViewControllerDidSplitModeChanged(_ controller: KMNDisplayViewController) {
  370. reloadPDFSplitInfo()
  371. }
  372. func displayViewControllerDidSplitFileChanged(_ controller: KMNDisplayViewController) {
  373. splitPDFController?.reloadData()
  374. }
  375. }
  376. //MARK: - KMSplitPDFViewControllerDelegate SplitPDFView
  377. extension KMPDFViewController: KMSplitPDFViewControllerDelegate {
  378. func splitPDFViewControllerDidUpdateFilePath(_ controller: KMSplitPDFViewController) {
  379. displaySettingController?.reloadData()
  380. }
  381. }
  382. //MARK: - CPDFViewDelegate PDFView代理
  383. extension KMPDFViewController: CPDFViewDelegate {
  384. func pdfViewDocumentDidLoaded(_ pdfView: CPDFView!) {
  385. sideBarController?.reloadPageTurnerData()
  386. }
  387. func pdfViewCurrentPageDidChanged(_ pdfView: CPDFView!) {
  388. sideBarController?.reloadPageTurnerData()
  389. }
  390. func pdfViewScaleDidChanged(_ pdfView: CPDFView!) {
  391. pdfToolbarController?.reloadSelectZoomView()
  392. }
  393. }
  394. extension KMPDFViewController: CPDFListViewDelegate {
  395. func pdfListViewKeyDownIsContinue(_ pdfListView: CPDFListView!, theEvent: NSEvent!) -> Bool {
  396. let command = theEvent.modifierFlags.contains(.command)
  397. let control = theEvent.modifierFlags.contains(.control)
  398. KMPrint(theEvent.keyCode)
  399. if pdfView.isEditing() {
  400. if control && theEvent.keyCode == 11 { // ctr + b
  401. return false
  402. } else if control && theEvent.keyCode == 34 { // ctr +i
  403. return false
  404. } else if theEvent.keyCode == 36 { // enter
  405. if pdfView.isCropMode {
  406. return false
  407. }
  408. }
  409. }
  410. if (theEvent.keyCode == 11 && command) { // command + B [添加书签]
  411. return false
  412. } else if (command && control && theEvent.keyCode == 14) { // command + control + E [注释 橡皮擦]
  413. return false
  414. } else if (theEvent.keyCode == 123) { // 向左
  415. if(self.pdfView.isEditing() && !self.pdfView.isSelecteditAreaNotEdit()) {
  416. return false
  417. } else {
  418. }
  419. } else if (theEvent.keyCode == 126) { // 向上
  420. if(self.pdfView.isEditing() && !self.pdfView.isSelecteditAreaNotEdit()) {
  421. return false
  422. } else {
  423. if (self.pdfView.isContinousScroll()) {
  424. return true
  425. }
  426. }
  427. } else if (theEvent.keyCode == 124) { // 向右
  428. if(self.pdfView.isEditing() && !self.pdfView.isSelecteditAreaNotEdit()) {
  429. return false
  430. } else {
  431. }
  432. } else if (theEvent.keyCode == 125) { // 向下
  433. if(self.pdfView.isEditing() && !self.pdfView.isSelecteditAreaNotEdit()) {
  434. return false
  435. } else {
  436. if (self.pdfView.isContinousScroll()) {
  437. return true
  438. }
  439. }
  440. } else if (theEvent.keyCode == 36) {
  441. if pdfView.annotationType == .addImage || pdfView.annotationType == .addText {
  442. if self.pdfView.isEditImage {
  443. }
  444. }
  445. }
  446. if theEvent.keyCode == 53 {
  447. //ESC
  448. if view.window?.styleMask.contains(.fullScreen) == true {
  449. view.window?.toggleFullScreen(nil)
  450. }
  451. //阅读模式
  452. if viewManager.isPDFReadMode {
  453. exitPDFReadMode()
  454. viewManager.isPDFReadMode = false
  455. return true
  456. }
  457. }
  458. return true
  459. }
  460. }
  461. //MARK: - KMNThumbnailBaseViewDelegate
  462. extension KMPDFViewController: KMNThumbnailBaseViewDelegate {
  463. func clickThumbnailViewControlle(pageEditVC:KMNThumbnailBaseViewController?,currentIndex:Int) {
  464. exitPageEditMode()
  465. viewManager.isPageEditMode = false
  466. pdfToolbarController?.reloadPageEditView()
  467. }
  468. func insertPDFThumbnailViewControlle(pageEditVC: KMNThumbnailBaseViewController?, pdfDocment: CPDFDocument?) {
  469. if(pdfDocment != nil) {
  470. insertDocuments.insert(pdfDocment!)
  471. }
  472. }
  473. }