KMLeftSideViewController.swift 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. //
  2. // KMLeftSideViewController.swift
  3. // PDF Master
  4. //
  5. // Created by lxy on 2022/10/10.
  6. //
  7. import Cocoa
  8. @objc protocol KMLeftSideViewControllerDelegate {
  9. @objc optional func controlStateChange(_ obj: KMLeftSideViewController,show:Bool)
  10. @objc optional func enterEditMode(_ obj: KMLeftSideViewController, _ pages: [Int])
  11. @objc optional func searchAction(searchString:String, isCase:Bool)
  12. @objc optional func controller(_ controller: KMLeftSideViewController, dispayDidChange dispay: KMPDFDisplayType)
  13. @objc optional func controller(controller: KMLeftSideViewController, itemClick item: Any?, itemKey: KMItemKey, params: Any?)
  14. @objc optional func controller(controller: KMLeftSideViewController, bookMarkDidChange bookMarks: [KMBookMarkItem])
  15. }
  16. class KMLeftSideViewController: NSViewController {
  17. var listView : CPDFListView!
  18. @IBOutlet weak var leftTableview: NSTableView!
  19. @IBOutlet weak var contentBox: NSBox!
  20. @IBOutlet weak var leftBox: NSBox!
  21. lazy var thumbnailViewController : KMThumbnailViewController = {
  22. let thumbnailViewController = KMThumbnailViewController()
  23. return thumbnailViewController
  24. }()
  25. lazy var outlineViewController : KMOutlineViewController = {
  26. let outlineViewController = KMOutlineViewController()
  27. return outlineViewController
  28. }()
  29. lazy var annotationViewController : KMAnnotationViewController = {
  30. let annotationViewController = KMAnnotationViewController()
  31. return annotationViewController
  32. }()
  33. lazy var bookViewController : KMBookMarkViewController = {
  34. let bookViewController = KMBookMarkViewController()
  35. bookViewController.bookMarkDidChange = { [unowned self] (controller, bookMarks) in
  36. self.delegate?.controller?(controller: self, bookMarkDidChange: bookMarks)
  37. }
  38. return bookViewController
  39. }()
  40. lazy var fromViewController : KMFromViewController = {
  41. let fromViewController = KMFromViewController()
  42. return fromViewController
  43. }()
  44. lazy var searchViewController : KMSearchViewController = {
  45. let searchViewController = KMSearchViewController()
  46. return searchViewController
  47. }()
  48. lazy var signatureViewController : KMSignatureViewController = {
  49. let signatureViewController = KMSignatureViewController()
  50. return signatureViewController
  51. }()
  52. lazy var panelSetViewController : KMPDFViewPanelSetViewController = {
  53. let panelSetViewController = KMPDFViewPanelSetViewController()
  54. panelSetViewController.delegate = self
  55. return panelSetViewController
  56. }()
  57. var dataSource : [KMLeftMethodMode] = [KMLeftMethodMode]()
  58. var type : KMLeftMethodMode = KMLeftMethodMode()
  59. var isShowPanel : Bool = false
  60. var norImage : [String] = []
  61. var selectImage : [String] = []
  62. var mainVC: KMMainViewController?
  63. //select page
  64. var selectPages: [Int]?
  65. open weak var delegate: KMLeftSideViewControllerDelegate?
  66. convenience init(type : KMLeftMethodMode) {
  67. self.init()
  68. self.type = type
  69. }
  70. override func viewDidLoad() {
  71. super.viewDidLoad()
  72. self.leftBox.backgroundColor(NSColor(hex: "#F7F8FA"))
  73. self.leftTableview.backgroundColor(NSColor(hex: "#F7F8FA"))
  74. self.leftTableview.border(NSColor(hex: "#EDEEF0"),1 , 0)
  75. self.addMenuTitle()
  76. self.refreshShowMethod()
  77. }
  78. func showPanelView(show: Bool) {
  79. self.isShowPanel = show
  80. if show {
  81. self.panelSetViewController.listView = self.listView
  82. self.panelSetViewController.view.frame = self.view.frame
  83. self.view.addSubview(self.panelSetViewController.view)
  84. self.panelSetViewController.reloadListViewModel()
  85. self.panelSetViewController.view.autoresizingMask = [.height]
  86. } else {
  87. self.contentBox.isHidden = false
  88. self.panelSetViewController.view.removeFromSuperview()
  89. if self.type.methodType == .None {
  90. self.delegate?.controlStateChange?(self, show: false)
  91. }
  92. }
  93. }
  94. func refreshMethodType(methodType: BotaType) {
  95. if (self.isShowPanel) {
  96. self.showPanelView(show: false)
  97. return
  98. }
  99. let newType = KMLeftMethodMode()
  100. var show = true
  101. if self.type.methodType != methodType {
  102. newType.methodType = methodType
  103. }
  104. if self.type.methodType == methodType {
  105. show = false
  106. }
  107. self.type = newType;
  108. self.refreshShowMethod()
  109. self.delegate?.controlStateChange?(self,show:show)
  110. }
  111. private func updateViewButtonState() {
  112. switch self.type.methodType {
  113. case .None: do {
  114. self.contentBox.contentView = NSView()
  115. self.delegate?.controlStateChange?(self,show:false)
  116. }
  117. break
  118. case .Thumbnail: do {
  119. self.thumbnailViewController.listView = self.listView
  120. self.thumbnailViewController.delegate = self
  121. self.contentBox.contentView = self.thumbnailViewController.view
  122. self.thumbnailViewController.reloadData()
  123. }
  124. break
  125. case .Outline: do {
  126. self.outlineViewController.listView = self.listView
  127. self.contentBox.contentView = self.outlineViewController.view
  128. }
  129. break
  130. case .BookMark: do {
  131. self.bookViewController.listView = self.listView
  132. self.contentBox.contentView = self.bookViewController.view
  133. self.bookViewController.reloadData()
  134. }
  135. break
  136. case .Annotation: do {
  137. self.annotationViewController.listView = self.listView
  138. self.contentBox.contentView = self.annotationViewController.view
  139. // self.annotationViewController.reloadData()
  140. }
  141. break
  142. case .From: do {
  143. self.fromViewController.listView = self.listView
  144. self.contentBox.contentView = self.fromViewController.view
  145. self.fromViewController.reloadData()
  146. }
  147. break
  148. case .Search: do {
  149. self.searchViewController.listView = self.listView
  150. self.searchViewController.delegate = self
  151. self.contentBox.contentView = self.searchViewController.view
  152. // self.searchViewController.reloadData()
  153. }
  154. break
  155. case .Signature: do {
  156. self.signatureViewController.listView = self.listView
  157. self.contentBox.contentView = self.signatureViewController.view
  158. self.signatureViewController.reloadData()
  159. }
  160. break
  161. }
  162. }
  163. func refreshShowMethod() {
  164. self.dataSource = [KMLeftMethodMode]()
  165. norImage = []
  166. selectImage = []
  167. if KMBOTAManagerClass.shard.getMethodShow(key: thumbnailMethodKey) {
  168. let mode = KMLeftMethodMode()
  169. mode.methodName = thumbnailMethodKey
  170. mode.methodType = .Thumbnail
  171. self.dataSource.insert(mode, at: self.dataSource.count)
  172. norImage.append("KMImageNameSidebarThumbailNor")
  173. selectImage.append("KMImageNameSidebarThumbailSelect")
  174. }
  175. if KMBOTAManagerClass.shard.getMethodShow(key: outlineMethodKey) {
  176. let mode = KMLeftMethodMode()
  177. mode.methodName = outlineMethodKey
  178. mode.methodType = .Outline
  179. self.dataSource.insert(mode, at: self.dataSource.count)
  180. norImage.append("KMImageNameSidebarOutlineNor")
  181. selectImage.append("KMImageNameSidebarOutlineSelect")
  182. }
  183. if KMBOTAManagerClass.shard.getMethodShow(key: bookMarkMethodKey) {
  184. let mode = KMLeftMethodMode()
  185. mode.methodName = bookMarkMethodKey
  186. mode.methodType = .BookMark
  187. self.dataSource.insert(mode, at: self.dataSource.count)
  188. norImage.append("KMImageNameSidebarBookMarkNor")
  189. selectImage.append("KMImageNameSidebarBookMarkSelect")
  190. }
  191. if KMBOTAManagerClass.shard.getMethodShow(key: anntationMethodKey) {
  192. let mode = KMLeftMethodMode()
  193. mode.methodName = anntationMethodKey
  194. mode.methodType = .Annotation
  195. self.dataSource.insert(mode, at: self.dataSource.count)
  196. norImage.append("KMImageNameSidebarAnnotationNor")
  197. selectImage.append("KMImageNameSidebarAnnotationSelect")
  198. }
  199. if KMBOTAManagerClass.shard.getMethodShow(key: searchMethodKey) {
  200. let mode = KMLeftMethodMode()
  201. mode.methodName = searchMethodKey
  202. mode.methodType = .Search
  203. self.dataSource.insert(mode, at: self.dataSource.count)
  204. norImage.append("KMImageNameSidebarSearchNor")
  205. selectImage.append("KMImageNameSidebarSearchSelect")
  206. }
  207. // if KMBOTAManagerClass.shard.getMethodShow(key: formMethodKey) {
  208. // let mode = KMLeftMethodMode()
  209. // mode.methodName = formMethodKey
  210. // mode.methodType = .From
  211. // self.dataSource.insert(mode, at: self.dataSource.count)
  212. // }
  213. // if KMBOTAManagerClass.shard.getMethodShow(key: signatureMethodKey) {
  214. // let mode = KMLeftMethodMode()
  215. // mode.methodName = signatureMethodKey
  216. // mode.methodType = .Signature
  217. // self.dataSource.insert(mode, at: self.dataSource.count)
  218. // }
  219. var isConstant = false
  220. for source in dataSource {
  221. if self.type.methodType == source.methodType {
  222. isConstant = true
  223. }
  224. }
  225. if(!isConstant) {
  226. self.type = KMLeftMethodMode()
  227. }
  228. self.leftTableview.reloadData()
  229. var typeIndex = -1
  230. for (index,value) in self.dataSource.enumerated() {
  231. if value.methodType == self.type.methodType {
  232. typeIndex = index
  233. }
  234. }
  235. self.leftTableview.selectRowIndexes([typeIndex], byExtendingSelection: true)
  236. if self.dataSource.count > 0 && typeIndex >= 0 {
  237. self.type = self.dataSource[typeIndex]
  238. }
  239. self.updateViewButtonState()
  240. }
  241. //MARK: menu
  242. private func addMenuTitle() {
  243. let menus : NSMenu = NSMenu(title: "")
  244. let addItem = self.menuItemWithTitle(title: NSLocalizedString("Thumbnails", comment: ""),type:thumbnailMethodKey,action: #selector(renameBookAction),tag: 1)
  245. let outlineItem = self.menuItemWithTitle(title: NSLocalizedString("Outline", comment: ""),type:outlineMethodKey,action: #selector(renameBookAction),tag: 2)
  246. let bookItem = self.menuItemWithTitle(title: NSLocalizedString("Bookmarks", comment: ""), type:bookMarkMethodKey,action: #selector(renameBookAction),tag: 3)
  247. let annationItem = self.menuItemWithTitle(title: NSLocalizedString("Annotations", comment: ""), type:anntationMethodKey,action: #selector(renameBookAction),tag: 4)
  248. let searchItem = self.menuItemWithTitle(title: NSLocalizedString("Search", comment: ""), type:searchMethodKey,action: #selector(renameBookAction),tag: 5)
  249. // let formItem = self.menuItemWithTitle(title: NSLocalizedString("域", comment: ""), type:formMethodKey,action: #selector(renameBookAction),tag: 6)
  250. // let signatureItem = self.menuItemWithTitle(title: NSLocalizedString("签名", comment: ""), type:signatureMethodKey,action: #selector(renameBookAction),tag: 7)
  251. menus.addItem(addItem)
  252. menus.addItem(outlineItem)
  253. menus.addItem(bookItem)
  254. menus.addItem(annationItem)
  255. menus.addItem(searchItem)
  256. // menus.addItem(formItem)
  257. // menus.addItem(signatureItem)
  258. self.leftTableview.menu = menus
  259. }
  260. func menuItemWithTitle(title:String,type:String,action:Selector?,tag:Int) -> NSMenuItem {
  261. let menuItem = NSMenuItem.init(title: title as String, action: action, keyEquivalent: "")
  262. menuItem.target = self
  263. menuItem.tag = tag
  264. if KMBOTAManagerClass.shard.getMethodShow(key: type) {
  265. menuItem.state = NSControl.StateValue.on
  266. } else {
  267. menuItem.state = NSControl.StateValue.off
  268. }
  269. return menuItem
  270. }
  271. @objc func renameBookAction(menuItem:NSMenuItem) {
  272. var show = true
  273. if menuItem.state == NSControl.StateValue.on {
  274. menuItem.state = NSControl.StateValue.off
  275. show = false
  276. } else {
  277. menuItem.state = NSControl.StateValue.on
  278. show = true
  279. }
  280. switch menuItem.tag {
  281. case 1: do {
  282. KMBOTAManagerClass.shard.setLeftMethod(show: show, key: thumbnailMethodKey)
  283. }
  284. case 2: do {
  285. KMBOTAManagerClass.shard.setLeftMethod(show: show, key: outlineMethodKey)
  286. }
  287. case 3: do {
  288. KMBOTAManagerClass.shard.setLeftMethod(show: show, key: bookMarkMethodKey)
  289. }
  290. case 4: do {
  291. KMBOTAManagerClass.shard.setLeftMethod(show: show, key: anntationMethodKey)
  292. }
  293. case 5: do {
  294. KMBOTAManagerClass.shard.setLeftMethod(show: show, key: searchMethodKey)
  295. }
  296. case 6: do {
  297. KMBOTAManagerClass.shard.setLeftMethod(show: show, key: formMethodKey)
  298. }
  299. case 7: do {
  300. KMBOTAManagerClass.shard.setLeftMethod(show: show, key: signatureMethodKey)
  301. }
  302. break
  303. default:
  304. break
  305. }
  306. self.refreshShowMethod()
  307. }
  308. }
  309. extension KMLeftSideViewController: KMThumbnailViewControllerDelegate {
  310. func gotoPageEdit(thumbnailViewController: KMThumbnailViewController, pages: [Int]) {
  311. self.delegate?.enterEditMode?(self, pages)
  312. }
  313. func pageDidSelect(controller: KMThumbnailViewController, pages: [Int]) {
  314. self.selectPages = pages
  315. }
  316. func controller(controller: KMThumbnailViewController, itemClick item: Any?, itemKey: KMItemKey, params: Any?) {
  317. self.delegate?.controller?(controller: self, itemClick: item, itemKey: itemKey, params: params)
  318. }
  319. }
  320. extension KMLeftSideViewController : KMSearchViewControllerDelegate {
  321. func searchAction(searchString: String,isCase:Bool) {
  322. self.delegate?.searchAction?(searchString: searchString, isCase: isCase)
  323. }
  324. func searchDoneAction(viewController: KMSearchViewController) {
  325. self.type = KMLeftMethodMode()
  326. self.updateViewButtonState()
  327. self.delegate?.controlStateChange?(self,show:false)
  328. self.leftTableview.reloadData()
  329. }
  330. }
  331. //MARK: NSTableViewDelegate,NSTableViewDataSource
  332. extension KMLeftSideViewController: NSTableViewDelegate,NSTableViewDataSource {
  333. func numberOfRows(in tableView: NSTableView) -> Int {
  334. return self.dataSource.count
  335. }
  336. func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
  337. let cell : KMLiftSideCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMLiftSideCellView"), owner: self) as! KMLiftSideCellView
  338. if row <= selectImage.count-1 {
  339. if self.dataSource[row] == self.type {
  340. cell.isSelect = true
  341. cell.mothedImage.image = NSImage(named: selectImage[row])
  342. cell.backgroundColor(NSColor(hex: "#DFE1E5"))
  343. } else {
  344. cell.isSelect = false
  345. cell.mothedImage.image = NSImage(named: norImage[row])
  346. cell.backgroundColor(NSColor.clear)
  347. }
  348. }
  349. cell.index = row
  350. cell.buttonClick = { [unowned self] index in
  351. if ((index < self.dataSource.count) && (index > -1)) {
  352. let isSearch = self.type.methodType == .Search
  353. var show = true
  354. if( self.type == self.dataSource[index]) {
  355. self.type = KMLeftMethodMode()
  356. show = false
  357. } else {
  358. self.type = self.dataSource[index]
  359. show = true
  360. }
  361. self.updateViewButtonState()
  362. self.delegate?.controlStateChange?(self,show:show)
  363. self.leftTableview.selectRowIndexes([index], byExtendingSelection: true)
  364. self.leftTableview.reloadData()
  365. UserDefaults.standard.set(index, forKey: "KMBOTASelectedIndexKey")
  366. UserDefaults.standard.synchronize()
  367. if (isSearch && show == false) {
  368. self.view.window?.makeFirstResponder(self)
  369. } else if (isSearch && self.type.methodType != .Search) { // 切换
  370. self.view.window?.makeFirstResponder(self)
  371. }
  372. }
  373. }
  374. return cell
  375. }
  376. func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
  377. return 48
  378. }
  379. func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
  380. let rowView = KMCustomTableRowView()
  381. rowView.selectionColor = NSColor(calibratedRed: 223.0/255.0, green: 225.0/255.0, blue: 229.0/255.0, alpha: 1.0)
  382. rowView.color = NSColor(hex: "#F7F8FA")
  383. return rowView
  384. }
  385. func tableViewSelectionDidChange(_ notification: Notification) {
  386. }
  387. }
  388. extension KMLeftSideViewController: KMPDFViewPanelSetViewControllerDelegate {
  389. func controller(_ controller: KMPDFViewPanelSetViewController, dispayDidChange dispay: KMPDFDisplayType) {
  390. self.delegate?.controller?(self, dispayDidChange: dispay)
  391. }
  392. func controller(_ controller: KMPDFViewPanelSetViewController, pageBreaksClick pageBreaks: Bool) {
  393. self.listView?.displaysPageBreaks = pageBreaks
  394. self.listView?.layoutDocumentView()
  395. }
  396. func controller(_ controller: KMPDFViewPanelSetViewController, rotateClick rotateType: KMRotateType) {
  397. if (rotateType == .clockwise) { /// 顺时针
  398. let page : CPDFPage = self.listView?.currentPage() ?? CPDFPage()
  399. if page.rotation == 0 {
  400. page.rotation = 90
  401. } else if page.rotation == 90 {
  402. page.rotation = 180
  403. } else if page.rotation == 180 {
  404. page.rotation = 270
  405. } else if page.rotation == 270 {
  406. page.rotation = 0
  407. }
  408. self.listView?.layoutDocumentView()
  409. } else if (rotateType == .anticlockwise) { /// 逆时针
  410. let page : CPDFPage = self.listView?.currentPage() ?? CPDFPage()
  411. if page.rotation == 0 {
  412. page.rotation = 270
  413. } else if page.rotation == 90 {
  414. page.rotation = 0
  415. } else if page.rotation == 180 {
  416. page.rotation = 90
  417. } else if page.rotation == 270 {
  418. page.rotation = 180
  419. }
  420. self.listView?.layoutDocumentView()
  421. }
  422. }
  423. }
  424. // MARK: -
  425. // MARK: - 扩展
  426. extension KMLeftSideViewController {
  427. public func selectType(_ type: BotaType) {
  428. // 更新 type
  429. var show = true
  430. if (self.type.methodType == .None) {
  431. show = true
  432. } else {
  433. if (self.type.methodType == type) {
  434. show = false
  435. } else {
  436. show = true
  437. }
  438. }
  439. var index: Int = NSNotFound
  440. switch type {
  441. case .None:
  442. index = NSNotFound
  443. break
  444. case .Thumbnail:
  445. index = 0
  446. break
  447. case .Outline:
  448. index = 1
  449. break
  450. case .BookMark:
  451. index = 2
  452. break
  453. case .Annotation:
  454. index = 3
  455. break
  456. case .Search:
  457. index = 4
  458. break
  459. case .From:
  460. index = 5
  461. break
  462. case .Signature:
  463. index = 6
  464. break
  465. }
  466. self.type = self.getMethodMode(show ? type : .None)
  467. // 更新按钮状态
  468. self.updateViewButtonState()
  469. // 将事件传递出去
  470. self.delegate?.controlStateChange?(self,show:show)
  471. if (index != NSNotFound) {
  472. self.leftTableview.selectRowIndexes([index], byExtendingSelection: true)
  473. // 记录当前选中
  474. UserDefaults.standard.set(index, forKey: "KMBOTASelectedIndexKey")
  475. UserDefaults.standard.synchronize()
  476. }
  477. self.leftTableview.reloadData()
  478. }
  479. private func getMethodMode(_ type: BotaType) -> KMLeftMethodMode {
  480. let mode = KMLeftMethodMode()
  481. mode.methodType = type
  482. switch type {
  483. case .None:
  484. mode.methodName = ""
  485. break
  486. case .Thumbnail:
  487. mode.methodName = thumbnailMethodKey
  488. break
  489. case .Outline:
  490. mode.methodName = outlineMethodKey
  491. break
  492. case .BookMark:
  493. mode.methodName = bookMarkMethodKey
  494. break
  495. case .Annotation:
  496. mode.methodName = anntationMethodKey
  497. break
  498. case .Search:
  499. mode.methodName = searchMethodKey
  500. break
  501. case .From:
  502. mode.methodName = formMethodKey
  503. break
  504. case .Signature:
  505. mode.methodName = signatureMethodKey
  506. break
  507. }
  508. return mode
  509. }
  510. }
  511. //MARK: Cache
  512. extension KMLeftSideViewController {
  513. func clearAnnotationFilterData() {
  514. let userDefaults = UserDefaults.standard
  515. let typeData = try?NSKeyedArchiver.archivedData(withRootObject: [Any](), requiringSecureCoding: false)
  516. userDefaults.set(typeData, forKey: "KMNoteOutlineFilterSelectArray_Type" + self.listView.document.documentURL.path)
  517. let colorData = try?NSKeyedArchiver.archivedData(withRootObject: [Any](), requiringSecureCoding: false)
  518. userDefaults.set(colorData, forKey: "KMNoteOutlineFilterSelectArray_Color" + self.listView.document.documentURL.path)
  519. let authorData = try?NSKeyedArchiver.archivedData(withRootObject: [Any](), requiringSecureCoding: false)
  520. userDefaults.set(authorData, forKey: "KMNoteOutlineFilterSelectArray_Author" + self.listView.document.documentURL.path)
  521. userDefaults.synchronize()
  522. }
  523. func clearNotification() {
  524. self.bookViewController.removeNotification()
  525. self.annotationViewController.removeNotification()
  526. self.outlineViewController.removeNotification()
  527. self.thumbnailViewController.removeNotification()
  528. }
  529. }