KMBookMarkViewController.swift 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. //
  2. // KMBookMarkViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by lxy on 2022/10/10.
  6. //
  7. import Cocoa
  8. import PDFKit
  9. typealias KMBookMarkViewControllerBookMarkDidChange = (_ controller: KMBookMarkViewController, _ bookMarks: [KMBookMarkItem]) -> Void
  10. class KMBookMarkViewController: NSViewController, NSTextFieldDelegate {
  11. @IBOutlet weak var addBookButton: NSButton!
  12. @IBOutlet weak var titleTextField: NSTextField!
  13. @IBOutlet var topSeplineView: NSView!
  14. @IBOutlet weak var bookTableView: NSTableView!
  15. @IBOutlet weak var emptyView: NSView!
  16. @IBOutlet weak var bigTipLabel: NSTextField!
  17. @IBOutlet weak var tipLabel: NSTextField!
  18. var dataSource: [KMBookMarkItem]!
  19. var renameTextField: NSTextField!
  20. var renamePDFBook: KMBookMarkItem!
  21. var renameCellView: KMBookCellView!
  22. var listView: CPDFListView!
  23. let pdfView = PDFView.init()
  24. var isLocalEvent: Bool = false //区分外部点击还是内部点击
  25. var selectItems: [KMBookMarkItem] = []
  26. var bookMarkDidChange: KMBookMarkViewControllerBookMarkDidChange?
  27. func dealloc() {
  28. NotificationCenter.default.removeObserver(self)
  29. }
  30. deinit {
  31. NotificationCenter.default.removeObserver(self)
  32. }
  33. override func viewDidLoad() {
  34. super.viewDidLoad()
  35. self.view.wantsLayer = true
  36. self.view.layer?.backgroundColor = NSColor(red: 247.0/255.0, green: 248.0/255.0, blue: 250.0/255.0, alpha: 1).cgColor
  37. self.topSeplineView.wantsLayer = true
  38. self.topSeplineView.layer?.backgroundColor = NSColor.black.withAlphaComponent(0.1).cgColor
  39. self.bookTableView.backgroundColor = NSColor.km_init(hex: "#F7F8FA")
  40. if #available(macOS 11, *) {
  41. self.bookTableView.style = NSTableView.Style.plain
  42. }
  43. self.bookTableView.allowsMultipleSelection = true
  44. self.bookTableView.doubleAction = #selector(renameBookAction)
  45. // self.bookTableView.selectionHighlightStyle = NSTableView.SelectionHighlightStyle.none;
  46. self.refreshUI()
  47. self.reloadData()
  48. self.initNotification()
  49. }
  50. func refreshUI() {
  51. self.titleTextField.font = NSFont.SFProTextSemiboldFont(14.0)
  52. self.titleTextField.textColor = NSColor.km_init(hex: "#252629")
  53. self.titleTextField.stringValue = NSLocalizedString("Bookmarks", comment: "")
  54. self.addBookButton.toolTip = NSLocalizedString("Add Bookmark", comment: "")
  55. self.bigTipLabel.font = NSFont.SFProTextRegularFont(14.0)
  56. self.bigTipLabel.textColor = NSColor.km_init(hex: "#616469")
  57. self.bigTipLabel.stringValue = NSLocalizedString("No Bookmarks", comment: "")
  58. let title = NSLocalizedString("To create a bookmark, please right-click on the selected page and choose \"Add Bookmark\", or click \"Add\" button in the upper right corner.", comment: "")
  59. let paragraphStyle = NSMutableParagraphStyle()
  60. paragraphStyle.lineHeightMultiple = 1.32
  61. paragraphStyle.alignment = .center
  62. self.tipLabel.attributedStringValue = NSMutableAttributedString(string: title, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle, .foregroundColor : NSColor.km_init(hex: "#94989C")])
  63. }
  64. func reloadData() {
  65. let array = self.listView.document.bookmarks() ?? [CPDFBookmark]()
  66. var bookMarks: [KMBookMarkItem] = []
  67. for bookMark in array {
  68. let item = KMBookMarkItem()
  69. item.bookMark = bookMark
  70. item.index = UInt(bookMark.pageIndex)
  71. item.label = bookMark.label
  72. bookMarks.append(item)
  73. }
  74. self.dataSource = bookMarks
  75. self.dataSource.sort(){$0.bookMark.pageIndex < $1.bookMark.pageIndex}
  76. self.bookTableView.reloadData()
  77. self.updateAddBookMarkState()
  78. }
  79. func addBookMarkAndEdit(newBookMark: KMBookMarkItem) {
  80. _ = self.dataSource.contains { KMBookMarkItem in
  81. if KMBookMarkItem.bookMark == newBookMark.bookMark {
  82. let index = KMOCToolClass.arrayIndexOf(array: self.dataSource, item: KMBookMarkItem) ?? 0
  83. self.didSelectItem(row: index, event: NSEvent())
  84. self.renameBookWithRow(row: index)
  85. return true
  86. }
  87. return false
  88. }
  89. }
  90. func initNotification() {
  91. NotificationCenter.default.addObserver(self, selector: #selector(KMPDFViewCurrentPageDidChangedNotification), name: NSNotification.Name.init(rawValue: "KMPDFViewCurrentPageDidChanged"), object: nil)
  92. NotificationCenter.default.addObserver(self, selector: #selector(documentPageCountChangedNotification), name: NSNotification.Name.init(rawValue: "CPDFDocumentPageCountChangedNotification"), object: nil)
  93. }
  94. func removeNotification() {
  95. NotificationCenter.default.removeObserver(self)
  96. }
  97. private func addMenuTitle(view: NSView, event: NSEvent) {
  98. let menus : NSMenu = NSMenu(title: "")
  99. menus.delegate = self
  100. let addItem = self.menuItemWithTitle(title: NSLocalizedString("Rename", comment: ""), action: #selector(renameBookAction))
  101. let addChildItem = self.menuItemWithTitle(title: NSLocalizedString("Change Destination", comment: ""), action: #selector(changeLocationAction))
  102. let addHigherItem = self.menuItemWithTitle(title: NSLocalizedString("Delete", comment: ""), action: #selector(deleteBookAction))
  103. menus.addItem(addItem)
  104. menus.addItem(addChildItem)
  105. menus.addItem(addHigherItem)
  106. let point = view.convert(event.locationInWindow, from: nil)
  107. menus.popUp(positioning: nil, at: point, in: view)
  108. // self.bookTableView.menu = menus
  109. }
  110. func menuItemWithTitle(title:String, action:Selector?) -> NSMenuItem {
  111. let menuItem = NSMenuItem.init(title: title as String, action: action, keyEquivalent: "")
  112. menuItem.target = self
  113. return menuItem
  114. }
  115. //MARK: Menu Action
  116. @objc func renameBookAction() {
  117. if self.bookTableView.selectedRowIndexes.count == 1 {
  118. self.renameBookWithRow(row: self.bookTableView.selectedRowIndexes.first!)
  119. } else {
  120. __NSBeep()
  121. }
  122. }
  123. @IBAction func escButtonAction(_ sender: Any) {
  124. self.bookTableView.deselectAll(nil)
  125. }
  126. @IBAction func addBookmarkAction(_ sender: Any) {
  127. if self.listView.document.bookmark(forPageIndex: UInt(self.listView.currentPageIndex)) == nil {
  128. let label = "\(NSLocalizedString("Page", comment:"")) \(self.listView.currentPageIndex + 1)"
  129. let bookMark = KMBookMarkItem()
  130. bookMark.label = label
  131. bookMark.index = UInt(self.listView.currentPageIndex)
  132. self.addBookMark(bookMarks: [bookMark])
  133. } else {
  134. let bookMark = self.listView.document.bookmark(forPageIndex: UInt(self.listView.currentPageIndex))
  135. self.dataSource.contains { KMBookMarkItem in
  136. if KMBookMarkItem.bookMark == bookMark {
  137. let index = Int(KMBookMarkItem.index)
  138. self.bookTableView.selectRowIndexes(IndexSet(integer: index), byExtendingSelection: false)
  139. self.didSelectItem(row: index, event: NSEvent())
  140. return true
  141. }
  142. return false
  143. }
  144. }
  145. }
  146. @objc func changeLocationAction() {
  147. if self.bookTableView.selectedRowIndexes.count == 1 {
  148. let item = self.dataSource[self.bookTableView.selectedRowIndexes.first!]
  149. let alter = NSAlert()
  150. alter.alertStyle = NSAlert.Style.informational
  151. alter.messageText = NSLocalizedString("Are you sure you want to set the target location of the selected outline to the current location", comment: "")
  152. alter.addButton(withTitle: NSLocalizedString("YES", comment:""))
  153. alter.addButton(withTitle: NSLocalizedString("NO", comment:""))
  154. let modlres = alter.runModal()
  155. if modlres == NSApplication.ModalResponse.alertFirstButtonReturn {
  156. let bookMark = KMBookMarkItem()
  157. bookMark.bookMark = item.bookMark
  158. bookMark.label = item.label
  159. bookMark.index = UInt(self.listView.currentPageIndex)
  160. self.changeLocation(oldBookMark: item,
  161. newBookMark: bookMark)
  162. }
  163. } else {
  164. __NSBeep()
  165. }
  166. }
  167. @objc func deleteBookAction() {
  168. if self.bookTableView.selectedRowIndexes.count != 0 {
  169. var bookMarks:[KMBookMarkItem] = []
  170. for index in self.bookTableView.selectedRowIndexes {
  171. let item = self.dataSource[index]
  172. bookMarks.append(item)
  173. }
  174. self.deleteBookMark(bookMarks: bookMarks)
  175. } else {
  176. __NSBeep()
  177. }
  178. }
  179. private func renameBookWithRow(row: Int) {
  180. self.renamePDFBook = self.dataSource[row]
  181. self.renameCellView = self.bookTableView.view(atColumn: 0, row: row, makeIfNecessary: true) as! KMBookCellView
  182. self.renameTextField = self.renameCellView.bookTitle
  183. self.renameTextField.delegate = self
  184. self.renameTextField.isEditable = true
  185. self.renameTextField.becomeFirstResponder()
  186. }
  187. //MARK: Noti
  188. @objc func KMPDFViewCurrentPageDidChangedNotification(notification: NSNotification) {
  189. if notification.object is CPDFDocument {
  190. let pdfdocument : CPDFDocument = notification.object as! CPDFDocument
  191. if pdfdocument.isEqual(self.listView.document) {
  192. if !isLocalEvent {
  193. var containSelIndex:Bool = false
  194. for (index, value) in self.dataSource.enumerated() {
  195. if value.bookMark == self.listView.document.bookmark(forPageIndex: UInt(self.listView.currentPageIndex)) {
  196. containSelIndex = true
  197. self.didSelectItem(row: index, event: NSEvent())
  198. break
  199. }
  200. }
  201. if !containSelIndex {
  202. self.cancelSelect()
  203. }
  204. }
  205. isLocalEvent = false
  206. }
  207. self.updateAddBookMarkState()
  208. }
  209. }
  210. @objc func documentPageCountChangedNotification(notification: NSNotification) {
  211. if notification.object is CPDFDocument {
  212. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { [unowned self] in
  213. let pdfdocument : CPDFDocument = notification.object as! CPDFDocument
  214. if pdfdocument.isEqual(self.listView.document) {
  215. self.reloadData()
  216. }
  217. }
  218. }
  219. }
  220. //MARK: - NSTextFieldDelegate
  221. func controlTextDidEndEditing(_ obj: Notification) {
  222. if (self.renameTextField.isEqual(obj.object)) {
  223. let textField : NSTextField = obj.object as! NSTextField
  224. self.renamePDFBook(bookmark: self.renamePDFBook, label: textField.stringValue)
  225. self.renameTextField.isEditable = false
  226. }
  227. }
  228. }
  229. extension KMBookMarkViewController : NSTableViewDelegate,NSTableViewDataSource {
  230. func numberOfRows(in tableView: NSTableView) -> Int {
  231. let count = self.dataSource?.count ?? 0
  232. if count == 0 {
  233. self.emptyView.isHidden = false
  234. } else {
  235. self.emptyView.isHidden = true
  236. }
  237. return count
  238. }
  239. func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
  240. if row < self.dataSource.count {
  241. let item: KMBookMarkItem = self.dataSource[row]
  242. let cell : KMBookCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMBookCellView"), owner: self) as! KMBookCellView
  243. cell.bookTitle.stringValue = item.bookMark.label
  244. return cell
  245. }
  246. return nil
  247. }
  248. func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
  249. let rowView = KMBookMarkTableRowView()
  250. if row < self.dataSource.count {
  251. rowView.model = self.dataSource[row]
  252. rowView.mouseDownAction = { [unowned self] (view, event) in
  253. self.didSelectItem(row: row, event: event)
  254. }
  255. rowView.rightMouseDownAction = { [unowned self] (view, event) in
  256. if !KMOCToolClass.arrayContains(array: self.selectItems, annotation: rowView.model) ||
  257. self.selectItems.count == 1 {
  258. self.selectIndex(index: row)
  259. }
  260. if self.bookTableView.rowView(atRow: row, makeIfNecessary: false) != nil {
  261. let tempView = self.bookTableView.rowView(atRow: row, makeIfNecessary: false)
  262. self.addMenuTitle(view: tempView!, event: event)
  263. }
  264. }
  265. rowView.hoverCallback = { [unowned self] (mouseEntered, mouseBox) in
  266. self.bookTableView.enumerateAvailableRowViews { view, row in
  267. if view is KMBookMarkTableRowView {
  268. (view as? KMBookMarkTableRowView)?.model.hover = false
  269. (view as? KMBookMarkTableRowView)?.reloadData()
  270. }
  271. }
  272. if mouseEntered {
  273. rowView.model.hover = true
  274. } else {
  275. rowView.model.hover = false
  276. }
  277. }
  278. }
  279. return rowView
  280. }
  281. func tableView(_ tableView: NSTableView, shouldSelect tableColumn: NSTableColumn?) -> Bool {
  282. self.isLocalEvent = true
  283. return true
  284. }
  285. func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
  286. self.isLocalEvent = true
  287. return true
  288. }
  289. func tableViewSelectionDidChange(_ notification: Notification) {
  290. // if self.bookTableView.selectedRow == -1 {
  291. // self.cancelSelect()
  292. // }
  293. }
  294. func selectIndex(index: Int) {
  295. self.bookTableView.selectRowIndexes(IndexSet(integer: IndexSet.Element(index)), byExtendingSelection: false)
  296. self.didSelectItem(row: index, event: NSEvent(), needJump: false)
  297. }
  298. func didSelectItem(row: Int, event: NSEvent?, needJump: Bool = true) {
  299. //当选中一个时
  300. if self.bookTableView.selectedRowIndexes.count == 1 || (event != nil &&
  301. (!event!.modifierFlags.contains(NSEvent.ModifierFlags.command) &&
  302. !event!.modifierFlags.contains(NSEvent.ModifierFlags.shift))) {
  303. self.bookTableView.selectRowIndexes(IndexSet(integer: IndexSet.Element(row)), byExtendingSelection: false)
  304. }
  305. //原始数据置空
  306. for model in self.selectItems {
  307. self.dataSource.contains { KMBookMarkItem in
  308. if KMBookMarkItem.bookMark == model.bookMark {
  309. let index = KMOCToolClass.arrayIndexOf(array: self.dataSource, item: KMBookMarkItem) ?? 0
  310. if index != nil {
  311. KMBookMarkItem.select = false
  312. if self.bookTableView.rowView(atRow: index, makeIfNecessary: false) != nil {
  313. let rowView: KMBookMarkTableRowView = self.bookTableView.rowView(atRow: index, makeIfNecessary: false) as! KMBookMarkTableRowView
  314. rowView.reloadData()
  315. }
  316. }
  317. return true
  318. }
  319. return false
  320. }
  321. }
  322. //获取最新数据
  323. var items: [KMBookMarkItem] = []
  324. for index in self.bookTableView.selectedRowIndexes {
  325. if index < self.dataSource.count {
  326. let model: KMBookMarkItem = self.dataSource[index]
  327. model.select = true
  328. if self.bookTableView.rowView(atRow: index, makeIfNecessary: false) != nil {
  329. let rowView: KMBookMarkTableRowView = self.bookTableView.rowView(atRow: index, makeIfNecessary: false) as! KMBookMarkTableRowView
  330. rowView.reloadData()
  331. }
  332. items.append(model)
  333. }
  334. }
  335. self.selectItems = items
  336. //刷新数据
  337. if needJump {
  338. self.updateListViewData()
  339. }
  340. }
  341. func updateListViewData() {
  342. if self.bookTableView.selectedRowIndexes.count == 1 &&
  343. self.bookTableView.selectedRowIndexes.first! < self.dataSource.count {
  344. let index = self.bookTableView.selectedRowIndexes.first
  345. let selectBookMark = self.dataSource[index!]
  346. self.listView.go(toPageIndex: selectBookMark.bookMark.pageIndex, animated: true)
  347. }
  348. }
  349. func cancelSelect() {
  350. self.bookTableView.deselectAll(nil)
  351. for model in self.selectItems {
  352. model.select = false
  353. let index = self.dataSource.firstIndex(of: model)
  354. if index != nil {
  355. if (self.bookTableView.rowView(atRow: index!, makeIfNecessary: false) != nil) {
  356. let rowView: KMBookMarkTableRowView = self.bookTableView.rowView(atRow: index!, makeIfNecessary: false) as! KMBookMarkTableRowView
  357. rowView.reloadData()
  358. }
  359. }
  360. }
  361. }
  362. func updateAddBookMarkState() {
  363. // self.addBookButton.isEnabled = self.canAddBorkMark()
  364. }
  365. func canAddBorkMark() -> Bool {
  366. if self.listView.document.bookmarks() != nil && self.listView.document.bookmarks()?.count != 0 {
  367. for bookMark in self.listView.document.bookmarks() {
  368. if bookMark.pageIndex == self.listView.currentPageIndex {
  369. return false
  370. }
  371. }
  372. }
  373. return true
  374. }
  375. }
  376. //MARK: undoRedo
  377. extension KMBookMarkViewController {
  378. func changeLocation(oldBookMark: KMBookMarkItem, newBookMark: KMBookMarkItem) {
  379. self.listView.document.removeBookmark(forPageIndex: oldBookMark.index)
  380. self.listView.document.addBookmark(newBookMark.label, forPageIndex: newBookMark.index)
  381. self.reloadData()
  382. self.listView.setNeedsDisplayForVisiblePages()
  383. self.listView.undoManager?.registerUndo(withTarget: self) { [unowned self] targetType in
  384. self.changeLocation(oldBookMark: newBookMark, newBookMark: oldBookMark)
  385. }
  386. }
  387. func renamePDFBook(bookmark : KMBookMarkItem! , label:String) {
  388. if bookmark.bookMark.label == label {
  389. return
  390. }
  391. let temp = bookmark.bookMark.label
  392. bookmark.bookMark.label = label
  393. self.reloadData()
  394. var indexSet = IndexSet()
  395. indexSet.insert(self.bookTableView.row(for: self.renameCellView))
  396. self.bookTableView.selectRowIndexes(indexSet, byExtendingSelection: false)
  397. self.listView.undoManager?.registerUndo(withTarget: self) { [unowned self] targetType in
  398. bookmark.bookMark.label = label
  399. self.renamePDFBook(bookmark: bookmark, label: temp ?? bookmark.label)
  400. }
  401. }
  402. func deleteBookMark(bookMarks: [KMBookMarkItem]) {
  403. for bookMark in bookMarks {
  404. if self.listView.document.removeBookmark(forPageIndex: bookMark.index) {
  405. KMPrint("删除标签成功")
  406. }
  407. }
  408. self.listView.setNeedsDisplayForVisiblePages()
  409. self.reloadData()
  410. //undo redo
  411. var saveBooks:[KMBookMarkItem] = bookMarks
  412. self.listView.undoManager?.registerUndo(withTarget: self) { [unowned self] targetType in
  413. saveBooks.sort(){$0.index > $1.index}
  414. self.addBookMark(bookMarks: bookMarks)
  415. }
  416. guard let callBack = bookMarkDidChange else { return }
  417. callBack(self, bookMarks)
  418. }
  419. func addBookMark(bookMarks: [KMBookMarkItem]) {
  420. for bookMark in bookMarks {
  421. self.listView.document.addBookmark(bookMark.label, forPageIndex: UInt(bookMark.index))
  422. }
  423. self.listView.setNeedsDisplayForVisiblePages()
  424. self.reloadData()
  425. if bookMarks.count == 1 {
  426. DispatchQueue.main.async {
  427. if self.listView.document.bookmark(forPageIndex: UInt(bookMarks.first!.index)) != nil {
  428. let item = KMBookMarkItem()
  429. item.bookMark = self.listView.document.bookmark(forPageIndex: UInt(bookMarks.first!.index))
  430. item.label = item.bookMark.label
  431. item.index = UInt(item.bookMark.pageIndex)
  432. self.addBookMarkAndEdit(newBookMark: item)
  433. }
  434. }
  435. }
  436. //undo redo
  437. var saveBooks:[KMBookMarkItem] = bookMarks
  438. self.listView.undoManager?.registerUndo(withTarget: self) { [unowned self] targetType in
  439. saveBooks.sort(){$0.index > $1.index}
  440. self.deleteBookMark(bookMarks: saveBooks)
  441. }
  442. guard let callBack = bookMarkDidChange else { return }
  443. callBack(self, bookMarks)
  444. }
  445. @IBAction func undo(_ sender: Any) {
  446. if (self.listView.undoManager?.canUndo ?? false) {
  447. self.listView.undoManager?.undo()
  448. }
  449. }
  450. @IBAction func redo(_ sender: Any) {
  451. if (self.listView.undoManager?.canRedo ?? false) {
  452. self.listView.undoManager?.redo()
  453. }
  454. }
  455. }
  456. extension KMBookMarkViewController: NSMenuDelegate, NSMenuItemValidation {
  457. func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
  458. let action = menuItem.action
  459. if (action == #selector(undo)) {
  460. return self.listView.undoManager?.canUndo ?? false
  461. }
  462. if (action == #selector(redo)) {
  463. return self.listView.undoManager?.canRedo ?? false
  464. }
  465. if action == #selector(renameBookAction) ||
  466. action == #selector(changeLocationAction) ||
  467. action == #selector(deleteBookAction) {
  468. if self.bookTableView.selectedRowIndexes.count > 1 {
  469. if action == #selector(changeLocationAction) {
  470. return false
  471. } else if action == #selector(renameBookAction) {
  472. return false
  473. }
  474. } else if self.bookTableView.selectedRowIndexes.count == 1 {
  475. return true
  476. } else {
  477. if self.bookTableView.selectedRowIndexes.count == 0 {
  478. if action == #selector(changeLocationAction) {
  479. // if self.listView.document.bookmark(forPageIndex: UInt(self.listView.currentPageIndex)) != nil {
  480. // return false
  481. // }
  482. }
  483. } else {
  484. return false
  485. }
  486. }
  487. }
  488. return true
  489. }
  490. }
  491. class KMBookMarkItem: NSObject {
  492. var label: String = ""
  493. var index: UInt = 0
  494. var bookMark: CPDFBookmark = CPDFBookmark()
  495. var select: Bool = false
  496. var hover: Bool = false
  497. }