// // KMNSearchHanddler.swift // PDF Reader Pro // // Created by User-Tangchao on 2024/12/1. // import Cocoa class KMNSearchHanddler: NSObject { weak var pdfView: CPDFView? var type: KMNBotaSearchType = .search var searchKey: String? var replaceKey: String? var showIdx = 0 var searchSectionResults: [KMBotaSearchSectionModel] = [] var searchResults: [KMSearchMode] = [] func hideNotes() -> Bool { let listView = pdfView as? CPDFListView return listView?.hideNotes ?? false } func allowsNotes() -> Bool { let listView = pdfView as? CPDFListView return listView?.allowsNotes() ?? false } func pdfDocument() -> CPDFDocument? { return pdfView?.document } func scaleFactor() -> CGFloat? { return pdfView?.scaleFactor } func search(keyword: String, isCase: Bool, isWholeWord: Bool, callback: @escaping (([KMBotaSearchSectionModel]?) -> Void)) { guard let document = self.pdfView?.document else { NSSound.beep() callback(nil) return } if document.isFinding { document.cancelFindString() } if keyword.isEmpty { callback(nil) return } let theKeyword = keyword.decomposedStringWithCompatibilityMapping searchKey = theKeyword var opt = CPDFSearchOptions() if isCase { opt.insert(.caseSensitive) } if isWholeWord { opt.insert(.matchWholeWord) } DispatchQueue.global().async { let result = document.findString(theKeyword, with: opt) self.searchResults.removeAll() self.searchSectionResults.removeAll() for sels in result ?? [] { let sectionM = KMBotaSearchSectionModel() sectionM.pageIndex = Int(sels.first?.page.pageIndex() ?? 0) for sel in sels { let mode : KMSearchMode = KMSearchMode() mode.selection = sel mode.attributedString = KMOCToolClass.getAttributedString(selection: sel, keyword: theKeyword) mode.selectionPageIndex = document.index(for: sel.page) sectionM.items.append(mode) sel.setColor(NSColor(red: 236/255.0, green: 241/255.0, blue: 83/255.0, alpha: 0.5)) self.searchResults.append(mode) } self.searchSectionResults.append(sectionM) } DispatchQueue.main.async { callback(self.searchSectionResults) } } } func replace(searchS: String, replaceS: String?, sel: CPDFSelection, callback: @escaping ((CPDFSelection?)->Void)) -> Bool { return self.pdfView?.document.replace(with: sel, search: searchS, toReplace: replaceS, completionHandler: { newSel in callback(newSel) }) ?? false } func showSelection(_ sel: CPDFSelection?) { guard let theSel = sel else { let isEditing = self.pdfView?.isEditing() ?? false if isEditing { self.pdfView?.setHighlightedSelection(nil, animated: true) } else { self.pdfView?.setHighlightedSelections([]) } self.pdfView?.setNeedsDisplayAnnotationViewForVisiblePages() return } guard let document = self.pdfView?.document else { return } theSel.setColor(NSColor(red: 236/255.0, green: 241/255.0, blue: 83/255.0, alpha: 0.5)) let pageIdx = document.index(for: theSel.page) self.pdfView?.go(toPageIndex: Int(pageIdx), animated: false) self.pdfView?.go(to: theSel.bounds, on: theSel.page) let isEditing = self.pdfView?.isEditing() ?? false if isEditing { self.pdfView?.setHighlightedSelection(theSel, animated: true) } else { self.pdfView?.setHighlightedSelections([theSel]) } self.pdfView?.setNeedsDisplayAnnotationViewForVisiblePages() } func clearData() { let isEditing = self.pdfView?.isEditing() ?? false if isEditing { self.pdfView?.setHighlightedSelection(nil, animated: false) } else { self.pdfView?.setHighlightedSelections([]) } self.pdfView?.setNeedsDisplayAnnotationViewForVisiblePages() } }