123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897 |
- //
- // KMBookMarkViewController.swift
- // PDF Reader Pro
- //
- // Created by lxy on 2022/10/10.
- //
- import Cocoa
- import KMComponentLibrary
- typealias KMBookMarkViewControllerBookMarkDidChange = (_ controller: KMBookMarkViewController, _ bookMarks: [KMBookMarkItem]) -> Void
- @objc protocol KMBookMarkViewControllerDelegate: NSObjectProtocol {
- @objc optional func bkControllerAddAction(controller: KMBookMarkViewController, bookmark: CPDFBookmark?, info: [String : Any]?)
- }
- extension KMNSearchKey.wholeWords {
- static let bookmark = "BookmarkSearchWholeWordsKey"
- }
- extension KMNSearchKey.caseSensitive {
- static let bookmark = "BookmarkSearchCaseSensitiveKey"
- }
- class KMBookMarkViewController: KMNBotaBaseViewController {
- @IBOutlet weak var topView: NSView!
- @IBOutlet weak var addBookButton: NSButton!
- @IBOutlet weak var titleTextField: NSTextField!
- @IBOutlet weak var sortButton: NSButton!
-
- @IBOutlet var topSeplineView: NSView!
-
- @IBOutlet weak var bookTableView: KMBotaTableView!
- @IBOutlet weak var emptyView: NSView!
- @IBOutlet weak var bigTipLabel: NSTextField!
- @IBOutlet weak var tipLabel: NSTextField!
-
- var dataSource: [KMBookMarkItem] = []
- var renameTextField: NSTextField?
- var renamePDFBook: KMBookMarkItem?
- var renameCellView: KMBookCellView?
-
- weak var document: CPDFDocument?
-
- var isLocalEvent: Bool = false //区分外部点击还是内部点击
-
- var selectItems: [KMBookMarkItem] = []
-
- var bookMarkDidChange: KMBookMarkViewControllerBookMarkDidChange?
-
- weak var delegate: KMBookMarkViewControllerDelegate?
-
- private lazy var handdler_ = KMNBookmarkHanddler()
- // 升序
- private var sortType_: KMSortMode = .ascending
-
- private lazy var addButton_: ComponentButton = {
- let view = ComponentButton()
- view.properties = ComponentButtonProperty(type: .text_gray, size: .xxs, onlyIcon: true, icon: NSImage(named: "KMBookmarkAdd"))
- return view
- }()
-
- private var emptyView_: ComponentEmpty = {
- let view = ComponentEmpty()
- view.properties = ComponentEmptyProperty(emptyType: .noBookmark, state: .normal, image: NSImage(named: "KMBookmarkEmpty"), text: KMLocalizedString("No Bookmark"), subText: KMLocalizedString("Here is the description."))
- return view
- }()
-
- var handdler: KMNBookmarkHanddler {
- get {
- return handdler_
- }
- }
-
- private var groupView: ComponentGroup? = ComponentGroup.createFromNib(in: ComponentLibrary.shared.componentBundle())
-
- convenience init() {
- self.init(nibName: "KMBookMarkViewController", bundle: nil)
- }
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- handdler.delegate = self
- titleTextField.font = ComponentLibrary.shared.getFontFromKey("mac/body-m-bold")
-
- addBookButton.addSubview(addButton_)
- addButton_.frame = addBookButton.bounds
- addButton_.autoresizingMask = [.width, .height]
- addButton_.setTarget(self, action: #selector(addBookmarkAction))
-
- bookTableView.style = NSTableView.Style.plain
- bookTableView.allowsMultipleSelection = true
- bookTableView.doubleAction = #selector(renameBookAction)
-
- bookTableView.hasImageToolTips = true
- bookTableView.botaDelegate = self
-
- sortButton.image = NSImage(named: "KMImageNameBotaBookmarkSortIcon")
- sortButton.target = self
- sortButton.action = #selector(sortAction)
-
- topView.addSubview(searchButton)
- searchButton.km_add_size_constraint(size: NSMakeSize(24, 24))
- searchButton.km_add_centerY_constraint(constant: 1)
- searchButton.km_add_trailing_constraint(equalTo: addBookButton, attribute: .leading, constant: -4)
- searchButton.setTarget(self, action: #selector(_searchAction))
-
- emptyView.addSubview(emptyView_)
- emptyView_.km_add_top_constraint(constant: 232)
- emptyView_.km_add_bottom_constraint()
- emptyView_.km_add_leading_constraint()
- emptyView_.km_add_trailing_constraint()
-
- if let data = headerSearchView {
- topView.addSubview(data)
- headerSearchView?.frame = topView.bounds
- headerSearchView?.autoresizingMask = [.width, .height]
- }
- hideHeaderSearch()
- headerSearchView?.itemClick = { [weak self] idx, params in
- if idx == 1 { // 显示搜索限制条件
- guard let button = params.first as? ComponentButton else {
- return
- }
- self?.showSearchGroupView(sender: button)
- } else if idx == 2 { // 关闭搜索
- self?.hideHeaderSearch()
-
- self?.reloadData()
- }
- }
- headerSearchView?.valueDidChange = { [weak self] sender, info in
- let value = info?[.newKey] as? String ?? ""
-
- self?.handdler.searchKey = value
- self?.reloadData()
- }
-
- self.reloadData()
- }
-
- override func updateUILanguage() {
- super.updateUILanguage()
-
- KMMainThreadExecute {
- self.titleTextField.stringValue = KMLocalizedString("Bookmarks")
- }
- }
-
- override func updateUIThemeColor() {
- super.updateUIThemeColor()
-
- KMMainThreadExecute {
- self.view.wantsLayer = true
- let color = ComponentLibrary.shared.getComponentColorFromKey("colorBg/layout-middle")
- self.view.layer?.backgroundColor = color.cgColor
-
- self.topSeplineView.wantsLayer = true
- self.topSeplineView.layer?.backgroundColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/divider").cgColor
-
- self.titleTextField.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/2")
-
- self.headerSearchView?.wantsLayer = true
- self.headerSearchView?.layer?.backgroundColor = color.cgColor
- self.headerSearchView?.bottomLine.wantsLayer = true
- self.headerSearchView?.bottomLine.layer?.backgroundColor = KMNColorTools.colorPrimary_border1().cgColor
-
- self.addButton_.properties.icon = NSImage(named: "KMBookmarkAdd")
- self.addButton_.reloadData()
-
- self.searchButton.properties.icon = NSImage(named: "KMImageNameOutlineSearch")
- self.searchButton.reloadData()
- }
- }
-
- func reloadData() {
- let array = document?.bookmarks() ?? [CPDFBookmark]()
- var bookMarks: [KMBookMarkItem] = []
- for bookMark in array {
- let item = KMBookMarkItem()
- item.bookMark = bookMark
- item.index = UInt(bookMark.pageIndex)
- item.label = bookMark.label
- bookMarks.append(item)
- }
- self.dataSource = bookMarks
-
- if self.sortType_ == .descending {
- self.dataSource.sort(){$0.bookMark.pageIndex >= $1.bookMark.pageIndex}
- } else {
- self.dataSource.sort(){$0.bookMark.pageIndex < $1.bookMark.pageIndex}
- }
-
- if handdler.isValidSearchMode() {
- var items: [KMBookMarkItem] = []
- for item in dataSource {
- if hasContainString(handdler.searchKey, bookmark: item.bookMark) {
- items.append(item)
- }
- }
- self.dataSource = items
- }
-
- self.bookTableView.reloadData()
-
- self.updateAddBookMarkState()
- }
-
- func addBookMarkAndEdit(newBookMark: KMBookMarkItem) {
- _ = self.dataSource.contains { KMBookMarkItem in
- if KMBookMarkItem.bookMark == newBookMark.bookMark {
- let index = KMOCToolClass.arrayIndexOf(array: self.dataSource, item: KMBookMarkItem) ?? 0
- self.didSelectItem(row: index, event: NSEvent())
- self.renameBookWithRow(row: index)
- return true
- }
- return false
- }
- }
-
- override func addNotifations() {
- super.addNotifations()
- NotificationCenter.default.addObserver(self, selector: #selector(KMPDFViewCurrentPageDidChangedNotification), name: NSNotification.Name.init(rawValue: "KMPDFViewCurrentPageDidChanged"), object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(documentPageCountChangedNotification), name: NSNotification.Name.init(rawValue: "CPDFDocumentPageCountChangedNotification"), object: nil)
- }
-
- func showSearchGroupView(sender: ComponentButton) {
- var viewHeight: CGFloat = 8
- var menuItemArr: [ComponentMenuitemProperty] = []
- let titles = ["Whole Words","Case Sensitive"]
- for i in titles {
- let menuI = ComponentMenuitemProperty(text: KMLocalizedString(i))
- menuItemArr.append(menuI)
- viewHeight += 36
- }
-
- if let info = menuItemArr.first {
- if KMDataManager.ud_bool(forKey: KMNSearchKey.wholeWords.bookmark) {
- info.righticon = NSImage(named: "KMNImageNameMenuSelect")
- }
- }
- if let info = menuItemArr.last {
- if KMDataManager.ud_bool(forKey: KMNSearchKey.caseSensitive.bookmark) {
- info.righticon = NSImage(named: "KMNImageNameMenuSelect")
- }
- }
-
- let groupView = ComponentGroup.createFromNib(in: ComponentLibrary.shared.componentBundle())
- searchGroupView = groupView
- groupView?.groupDelegate = self
- groupView?.frame = CGRectMake(310, 0, 200, viewHeight)
- groupView?.updateGroupInfo(menuItemArr)
-
- var point = sender.convert(sender.frame.origin, to: nil)
- point.y -= viewHeight
- groupView?.showWithPoint(point, relativeTo: sender)
- searchGroupTarget = sender
- }
-
- override func showHeaderSearch() {
- super.showHeaderSearch()
-
- handdler.isSearchMode = true
- }
-
- override func hideHeaderSearch() {
- super.hideHeaderSearch()
-
- handdler.isSearchMode = false
- }
-
- func hasContainString(_ searchString: String, bookmark: CPDFBookmark) -> Bool {
- var label = bookmark.label ?? ""
- var searchLabel = searchString
- if handdler.caseSensitive == false {
- label = label.lowercased()
- searchLabel = searchLabel.lowercased()
- }
-
- if label.contains(searchLabel) {
- if handdler.wholeWords {
- let words = label.words()
- return words.contains(searchLabel)
- }
- return true
- }
- return false
- }
-
- //MARK: - Menu Action
-
- @objc func renameBookAction() {
- if self.bookTableView.selectedRowIndexes.count == 1 {
- self.renameBookWithRow(row: self.bookTableView.selectedRowIndexes.first!)
- } else {
- __NSBeep()
- }
- }
-
-
- @IBAction func escButtonAction(_ sender: Any) {
- self.bookTableView.deselectAll(nil)
- }
-
- @IBAction func addBookmarkAction(_ sender: Any) {
- let currentPageIndex = handdler.currentPageIndex
- if let data = handdler.bookmark(for: currentPageIndex) {
- delegate?.bkControllerAddAction?(controller: self, bookmark: data, info: ["result" : false])
- return
- }
-
- handdler.addCurrentBookmark(callback: { [unowned self] bookmark in
- self.delegate?.bkControllerAddAction?(controller: self, bookmark: bookmark, info: nil)
- self.reloadData()
- })
- }
-
- @objc func changeLocationAction() {
- if self.bookTableView.selectedRowIndexes.count == 1 {
- let item = self.dataSource[self.bookTableView.selectedRowIndexes.first!]
- let alter = NSAlert()
- alter.alertStyle = NSAlert.Style.informational
- alter.messageText = KMLocalizedString("Are you sure you want to set the selected page as the bookmark location?", comment: "")
- alter.addButton(withTitle: KMLocalizedString("Yes", comment:""))
- alter.addButton(withTitle: KMLocalizedString("No", comment:""))
- let modlres = alter.runModal()
- if modlres == NSApplication.ModalResponse.alertFirstButtonReturn {
- let bookMark = KMBookMarkItem()
- bookMark.bookMark = item.bookMark
- bookMark.label = item.label
- bookMark.index = UInt(handdler.currentPageIndex)
- self.changeLocation(oldBookMark: item,
- newBookMark: bookMark)
- }
- } else {
- __NSBeep()
- }
- }
-
- @objc func deleteBookAction() {
- if self.bookTableView.selectedRowIndexes.count != 0 {
- var bookMarks:[KMBookMarkItem] = []
- for index in self.bookTableView.selectedRowIndexes {
- let item = self.dataSource[index]
- bookMarks.append(item)
- }
- self.deleteBookMark(bookMarks: bookMarks)
- } else {
- __NSBeep()
- }
- }
-
- private func renameBookWithRow(row: Int) {
- self.renamePDFBook = self.dataSource[row]
- self.renameCellView = self.bookTableView.view(atColumn: 0, row: row, makeIfNecessary: true) as? KMBookCellView
- self.renameTextField = self.renameCellView?.inputTF
- self.renameTextField?.delegate = self
- self.renameTextField?.isEditable = true
- self.renameTextField?.becomeFirstResponder()
- }
-
- @objc func sortAction(_ sender: NSButton) {
- let type = self.sortType_
- if type == .ascending {
- self.sortType_ = .descending
- } else {
- self.sortType_ = .ascending
- }
-
- self.reloadData()
- }
-
- @objc private func _searchAction() {
- searchButton.properties.state = .normal
- searchButton.reloadData()
-
- showHeaderSearch()
- }
-
- //MARK: - Noti
-
- @objc func KMPDFViewCurrentPageDidChangedNotification(notification: NSNotification) {
- if notification.object is CPDFDocument {
- let pdfdocument : CPDFDocument = notification.object as! CPDFDocument
- if pdfdocument.isEqual(document) {
- if !isLocalEvent {
- var containSelIndex:Bool = false
- for (index, value) in self.dataSource.enumerated() {
- if value.bookMark == document?.bookmark(forPageIndex: UInt(handdler.currentPageIndex)) {
- containSelIndex = true
- self.didSelectItem(row: index, event: NSEvent())
- break
- }
- }
- if !containSelIndex {
- self.cancelSelect()
- }
- }
- isLocalEvent = false
- }
- self.updateAddBookMarkState()
- }
- }
-
- @objc func documentPageCountChangedNotification(notification: NSNotification) {
- if notification.object is CPDFDocument {
- DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { [weak self] in
- let pdfdocument : CPDFDocument = notification.object as! CPDFDocument
- if pdfdocument.isEqual(self?.document) {
- self?.reloadData()
- }
- }
- }
- }
- }
- // MARK: - NSTextFieldDelegate
- extension KMBookMarkViewController: NSTextFieldDelegate {
- func controlTextDidEndEditing(_ obj: Notification) {
- if (self.renameTextField!.isEqual(obj.object)) {
- let textField : NSTextField = obj.object as! NSTextField
- handdler.rename(bookmark: renamePDFBook!.bookMark, label: textField.stringValue)
- self.renameTextField?.isEditable = false
- }
- }
- }
- // MARK: - NSTableViewDelegate,NSTableViewDataSource
- extension KMBookMarkViewController : NSTableViewDelegate,NSTableViewDataSource {
- func numberOfRows(in tableView: NSTableView) -> Int {
- let count = self.dataSource.count
- if count == 0 {
- self.emptyView.isHidden = false
- } else {
- self.emptyView.isHidden = true
- }
- return count
- }
-
- func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
- if row < self.dataSource.count {
- let item: KMBookMarkItem = self.dataSource[row]
- let cell : KMBookCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMBookCellView"), owner: self) as! KMBookCellView
- if handdler.isValidSearchMode() {
- var label = item.bookMark.label ?? ""
- let attri = NSMutableAttributedString(string: label, attributes: [
- .font : NSFont.SFProTextRegularFont(13),
- .foregroundColor : KMNColorTools.colorText_1()])
-
- var _searchKey = handdler.searchKey
- if handdler.caseSensitive == false {
- label = label.lowercased()
- _searchKey = _searchKey.lowercased()
- }
-
- let ranges = label.ranges(of: _searchKey)
- for range in ranges.nsRnage {
- attri.addAttributes([.font : NSFont.SFProTextBoldFont(13), .foregroundColor: KMNColorTools.colorPrimary_textLight()], range: range)
- }
- cell.inputTF.attributedStringValue = attri
- } else {
- cell.inputTF.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-regular")
- cell.inputTF.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/1")
-
- cell.inputTF.stringValue = item.bookMark.label
- cell.bookTitle.stringValue = "\(item.bookMark.pageIndex + 1)"
- cell.inputBox.borderWidth = 0
- if let data = item.bookMark.date {
- cell.dateLabel.stringValue = KMTools.timeString(timeDate: data)
- } else {
- cell.dateLabel.stringValue = ""
- }
- }
-
- cell.textFieldDidEndEditingCallback = { [weak self] textF in
- self?.renameCellView = cell
- self?.handdler.rename(bookmark: item.bookMark, label: textF.stringValue)
- }
- return cell
- }
- return nil
- }
-
- func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
- let rowView = KMBookMarkTableRowView()
- rowView.selectionHighlightStyle = .none
- if row < self.dataSource.count {
- rowView.model = self.dataSource[row]
-
- rowView.menuClickedAction = { [weak self] point in
- let idxs = self?.bookTableView.selectedRowIndexes.count ?? 0
-
- let tempView = self?.bookTableView.rowView(atRow: row, makeIfNecessary: false)
- var viewHeight: CGFloat = 0
- let items: [String] = ["Delete", "Add", "Rename", "Delete All"]
- var menuItemArr: [ComponentMenuitemProperty] = []
- for value in items {
- let properties_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
- itemSelected: false,
- isDisabled: false,
- keyEquivalent: nil,
- text: KMLocalizedString(value),
- identifier: value)
-
- menuItemArr.append(properties_Menuitem)
- viewHeight += 36
- }
- if idxs > 1 {
- (menuItemArr.safe_element(for: 1) as? ComponentMenuitemProperty)?.isDisabled = true
- (menuItemArr.safe_element(for: 2) as? ComponentMenuitemProperty)?.isDisabled = true
- }
-
- if self?.groupView != nil {
- self?.groupView?.clickedAutoHide = false
- self?.groupView?.groupDelegate = self
- self?.groupView?.frame = CGRectMake(0, 0, 180, viewHeight)
- self?.groupView?.updateGroupInfo(menuItemArr)
-
- self?.groupView?.showWithPoint(CGPoint(x: point.x, y: point.y - viewHeight), relativeTo: tempView)
- }
- return NSMenu()
- }
-
- rowView.mouseDownAction = { [unowned self] (view, event) in
- self.didSelectItem(row: row, event: event)
- }
-
- rowView.rightMouseDownAction = { [unowned self] (view, event) in
- if !KMOCToolClass.arrayContains(array: self.selectItems, annotation: rowView.model) ||
- self.selectItems.count == 1 {
- self.selectIndex(index: row)
- }
-
- if row < 0 || row >= self.dataSource.count {
- return
- }
- }
-
- rowView.hoverCallback = { [unowned self] (mouseEntered, mouseBox) in
- if let value = ComponentLibrary.shared.getComponentValueFromKey("radius/xs") {
- let currentValue = value as? CGFloat ?? 0
- rowView.box?.cornerRadius = currentValue
- }
-
- self.bookTableView.enumerateAvailableRowViews { view, row in
- if let data = view as? KMBookMarkTableRowView {
- data.model.hover = false
- data.reloadData()
- }
- }
- if mouseEntered {
- rowView.model.hover = true
- rowView.reloadData()
- } else {
- rowView.model.hover = false
- rowView.reloadData()
- }
- }
- }
- return rowView
- }
-
- func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
- return 36
- }
-
- func tableView(_ tableView: NSTableView, shouldSelect tableColumn: NSTableColumn?) -> Bool {
- self.isLocalEvent = true
- return true
- }
-
- func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
- self.isLocalEvent = true
- return true
- }
-
- func tableViewSelectionDidChange(_ notification: Notification) {
- // if self.bookTableView.selectedRow == -1 {
- // self.cancelSelect()
- // }
- }
-
- func selectIndex(index: Int) {
- if index < 0 || index >= self.dataSource.count {
- return
- }
- self.bookTableView.selectRowIndexes(IndexSet(integer: IndexSet.Element(index)), byExtendingSelection: false)
- self.didSelectItem(row: index, event: NSEvent(), needJump: false)
- }
- func didSelectItem(row: Int, event: NSEvent?, needJump: Bool = true) {
- //当选中一个时
- if self.bookTableView.selectedRowIndexes.count == 1 || (event != nil &&
- (!event!.modifierFlags.contains(NSEvent.ModifierFlags.command) &&
- !event!.modifierFlags.contains(NSEvent.ModifierFlags.shift))) {
- self.bookTableView.selectRowIndexes(IndexSet(integer: IndexSet.Element(row)), byExtendingSelection: false)
- }
-
- //原始数据置空
- for model in self.selectItems {
- self.dataSource.contains { KMBookMarkItem in
- if KMBookMarkItem.bookMark == model.bookMark {
- let index = KMOCToolClass.arrayIndexOf(array: self.dataSource, item: KMBookMarkItem) ?? 0
- if index != nil {
- KMBookMarkItem.select = false
- if self.bookTableView.rowView(atRow: index, makeIfNecessary: false) != nil {
- let rowView: KMBookMarkTableRowView = self.bookTableView.rowView(atRow: index, makeIfNecessary: false) as! KMBookMarkTableRowView
- rowView.reloadData()
- }
- }
- return true
- }
- return false
- }
- }
-
- //获取最新数据
- var items: [KMBookMarkItem] = []
- for index in self.bookTableView.selectedRowIndexes {
- if index < self.dataSource.count {
- let model: KMBookMarkItem = self.dataSource[index]
- model.select = true
- if self.bookTableView.rowView(atRow: index, makeIfNecessary: false) != nil {
- let rowView: KMBookMarkTableRowView = self.bookTableView.rowView(atRow: index, makeIfNecessary: false) as! KMBookMarkTableRowView
- rowView.reloadData()
- }
- items.append(model)
- }
- }
- self.selectItems = items
-
- //刷新数据
- if needJump {
- self.updateListViewData()
- }
- }
-
- func updateListViewData() {
- if self.bookTableView.selectedRowIndexes.count == 1 &&
- self.bookTableView.selectedRowIndexes.first! < self.dataSource.count {
- let index = self.bookTableView.selectedRowIndexes.first
- let selectBookMark = self.dataSource[index!]
- // self.listView.go(toPageIndex: selectBookMark.bookMark.pageIndex, animated: true)
- }
- }
-
- func cancelSelect() {
- self.bookTableView.deselectAll(nil)
- for model in self.selectItems {
- model.select = false
- let index = self.dataSource.firstIndex(of: model)
- if index != nil {
- if (self.bookTableView.rowView(atRow: index!, makeIfNecessary: false) != nil) {
- let rowView: KMBookMarkTableRowView = self.bookTableView.rowView(atRow: index!, makeIfNecessary: false) as! KMBookMarkTableRowView
- rowView.reloadData()
- }
- }
- }
- }
-
- func updateAddBookMarkState() {
- addButton_.properties.isDisabled = !canAddBorkMark()
- addButton_.reloadData()
- }
-
- func canAddBorkMark() -> Bool {
- if document?.bookmarks() != nil && document?.bookmarks()?.count != 0 {
- for bookMark in document?.bookmarks() ?? [] {
- if bookMark.pageIndex == handdler.currentPageIndex {
- return false
- }
- }
- }
- return true
- }
- }
- // MARK: - KMBotaTableViewDelegate
- extension KMBookMarkViewController: KMBotaTableViewDelegate {
- func tableView(_ aTableView: NSTableView, imageContextForRow rowIndex: Int) -> AnyObject? {
- if aTableView.isEqual(to: self.bookTableView) {
- let cnt = self.dataSource.count
- if rowIndex >= cnt {
- return nil
- }
- let model = self.dataSource[rowIndex]
- return model.bookMark
-
- }
- return nil
- }
- }
- //MARK: - undoRedo
- extension KMBookMarkViewController {
- func changeLocation(oldBookMark: KMBookMarkItem, newBookMark: KMBookMarkItem) {
- document?.removeBookmark(forPageIndex: oldBookMark.index)
- document?.addBookmark(newBookMark.label, forPageIndex: newBookMark.index)
-
- reloadData()
- }
-
- func renamePDFBook(bookmark : KMBookMarkItem! , label:String) {
- if bookmark.bookMark.label == label {
- return
- }
- let temp = bookmark.bookMark.label
-
- bookmark.bookMark.label = label
- self.reloadData()
-
- var indexSet = IndexSet()
- indexSet.insert(self.bookTableView.row(for: self.renameCellView!))
- self.bookTableView.selectRowIndexes(indexSet, byExtendingSelection: false)
- }
-
- func deleteBookMark(bookMarks: [KMBookMarkItem]) {
- for bookMark in bookMarks {
- if ((document?.removeBookmark(forPageIndex: bookMark.index)) != nil) {
- KMPrint("删除标签成功")
- }
- }
- self.reloadData()
-
- guard let callBack = bookMarkDidChange else { return }
-
- callBack(self, bookMarks)
- }
-
- func addBookMark(bookMarks: [KMBookMarkItem]) {
- for bookMark in bookMarks {
- document?.addBookmark(bookMark.label, forPageIndex: UInt(bookMark.index))
- }
- self.reloadData()
-
- if bookMarks.count == 1 {
- DispatchQueue.main.async { [self] in
- if document?.bookmark(forPageIndex: UInt(bookMarks.first!.index)) != nil {
- let item = KMBookMarkItem()
- item.bookMark = (document?.bookmark(forPageIndex: UInt(bookMarks.first!.index)))!
- item.label = item.bookMark.label
- item.index = UInt(item.bookMark.pageIndex)
- self.addBookMarkAndEdit(newBookMark: item)
- }
- }
- }
-
- guard let callBack = bookMarkDidChange else { return }
-
- callBack(self, bookMarks)
- }
-
- @IBAction func undo(_ sender: Any) {
- handdler.undo()
- }
-
- @IBAction func redo(_ sender: Any) {
- handdler.redo()
- }
- }
- // MARK: - NSMenuDelegate, NSMenuItemValidation
- extension KMBookMarkViewController: NSMenuDelegate, NSMenuItemValidation {
- func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
- let action = menuItem.action
- if (action == #selector(undo)) {
- return handdler.canUndo()
- }
- if (action == #selector(redo)) {
- return handdler.canRedo()
- }
-
- if action == #selector(renameBookAction) ||
- action == #selector(changeLocationAction) ||
- action == #selector(deleteBookAction) {
- if self.bookTableView.selectedRowIndexes.count > 1 {
- if action == #selector(changeLocationAction) {
- return false
- } else if action == #selector(renameBookAction) {
- return false
- }
- } else if self.bookTableView.selectedRowIndexes.count == 1 {
- return true
- } else {
- if self.bookTableView.selectedRowIndexes.count == 0 {
- if action == #selector(changeLocationAction) {}
- } else {
- return false
- }
- }
- }
- return true
- }
- }
- extension KMBookMarkViewController: KMNBookmarkHanddlerDelegate {
- func handdler(_ handdler: KMNBookmarkHanddler, didAdd bookmark: CPDFBookmark?, info: [String : Any]?) {
- KMMainThreadExecute {
- self.reloadData()
- }
- }
-
- func handdler(_ handdler: KMNBookmarkHanddler, didRemove bookmark: CPDFBookmark?, info: [String : Any]?) {
- KMMainThreadExecute {
- self.reloadData()
- }
- }
-
- func handdler(_ handdler: KMNBookmarkHanddler, didRemoveAll info: [String : Any]?) {
- KMMainThreadExecute {
- self.reloadData()
- }
- }
-
- func handdler(_ handdler: KMNBookmarkHanddler, didRename bookmark: CPDFBookmark?, info: [String : Any]?) {
- KMMainThreadExecute {
- self.reloadData()
- }
- }
- }
- extension KMBookMarkViewController: ComponentGroupDelegate {
- func componentGroupDidSelect(group: ComponentGroup?, menuItemProperty: ComponentMenuitemProperty?) {
- if group == groupView {
- if let selItem = menuItemProperty {
- let index = group?.menuItemArr.firstIndex(of: selItem)
- if index == 0 {
- group?.removeFromSuperview()
- var pageIndexs = IndexSet()
- for i in bookTableView.selectedRowIndexes {
- if let item = dataSource.safe_element(for: i) as? KMBookMarkItem {
- pageIndexs.insert(item.bookMark.pageIndex)
- }
- }
- _ = handdler.removeBookmarks(for: pageIndexs)
- } else if index == 1 {
-
- } else if index == 2 {
- group?.removeFromSuperview()
-
- renameBookAction()
- } else if index == 3 {
- Task {
- let resp = await KMAlertTool.runModel(message: KMLocalizedString("此操作将删除文档中的所有书签,是否继续?"), buttons: [KMLocalizedString("OK"), KMLocalizedString("No")])
- if resp == .alertFirstButtonReturn {
- _ = handdler.removeAllBookmarks()
- }
- }
- }
- }
- } else if group == searchGroupView {
- guard let menuI = menuItemProperty else {
- return
- }
- let idx = group?.menuItemArr.firstIndex(of: menuI)
- if idx == 0 {
- let key = KMNSearchKey.wholeWords.bookmark
- let value = KMDataManager.ud_bool(forKey: key)
- KMDataManager.ud_set(!value, forKey: key)
-
- handdler.wholeWords = !value
- } else if idx == 1 {
- let key = KMNSearchKey.caseSensitive.bookmark
- let value = KMDataManager.ud_bool(forKey: key)
- KMDataManager.ud_set(!value, forKey: key)
-
- handdler.caseSensitive = !value
- }
- }
- }
-
- func componentGroupDidDismiss(group: ComponentGroup?) {
- if group == groupView {
- groupView?.removeFromSuperview()
- } else if group == searchGroupView {
- searchGroupTarget?.properties.state = .normal
- searchGroupTarget?.reloadData()
- searchGroupTarget = nil
- }
- }
- }
- class KMBookMarkItem: NSObject {
- var label: String = ""
- var index: UInt = 0
- var bookMark: CPDFBookmark = CPDFBookmark()
- var select: Bool = false
- var hover: Bool = false
- }
|