|
@@ -56,7 +56,6 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
private var _modalSession: NSApplication.ModalSession?
|
|
|
|
|
|
private var handdler = KMNSearchHanddler()
|
|
|
- private var type_: KMNBotaSearchType = .search
|
|
|
|
|
|
private var currentSel: CPDFSelection?
|
|
|
private var finding_ = false
|
|
@@ -95,18 +94,20 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private var searchGroupView_: ComponentGroup?
|
|
|
+
|
|
|
convenience init(with pdfView: CPDFView?, type: KMNBotaSearchType) {
|
|
|
self.init(windowNibName: "KMSearchReplaceWindowController")
|
|
|
|
|
|
self.handdler.pdfView = pdfView
|
|
|
- self.type_ = type
|
|
|
+ handdler.type = type
|
|
|
}
|
|
|
|
|
|
override func windowDidLoad() {
|
|
|
super.windowDidLoad()
|
|
|
|
|
|
self.initDefaultValue()
|
|
|
- self.switchType(self.type_)
|
|
|
+ self.switchType(handdler.type)
|
|
|
|
|
|
// NotificationCenter.default.addObserver(self, selector: #selector(didMoveNotification), name: NSWindow.didMoveNotification, object: self.window)
|
|
|
// NotificationCenter.default.addObserver(self, selector: #selector(didMoveNotification), name: NSWindow.willMoveNotification, object: self.window)
|
|
@@ -157,6 +158,8 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
_previousAction(NSButton())
|
|
|
} else if idx == 2 { // next
|
|
|
_nextAction(NSButton())
|
|
|
+ } else if idx == 3 {
|
|
|
+ showSearchGroupView(sender: ComponentButton())
|
|
|
}
|
|
|
}
|
|
|
searchItemView_.valueDidChange = { [unowned self] value, _ in
|
|
@@ -173,6 +176,8 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
currentSel = nil
|
|
|
}
|
|
|
}
|
|
|
+ searchItemView_.input.properties.showSuffix = false
|
|
|
+ searchItemView_.input.reloadData()
|
|
|
|
|
|
replaceBox.borderWidth = 0
|
|
|
replaceBox.contentView = replaceItemView_
|
|
@@ -210,6 +215,11 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
KMMainThreadExecute {
|
|
|
self.titleBarView_.titleLabel.textColor = KMNColorTools.colorText_1()
|
|
|
|
|
|
+ self.searchItemView_.input.properties.leftIcon = NSImage(named: "KMImageNameBotaSearch")
|
|
|
+ self.searchItemView_.input.reloadData()
|
|
|
+ self.replaceItemView_.input.properties.leftIcon = NSImage(named: "KMImagenameBotaSearchInputPrefiex")
|
|
|
+ self.replaceItemView_.input.reloadData()
|
|
|
+
|
|
|
self.updateViewColor()
|
|
|
}
|
|
|
}
|
|
@@ -255,6 +265,55 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
updateButtonStatus()
|
|
|
}
|
|
|
|
|
|
+ // MARK: - Group View
|
|
|
+
|
|
|
+ func showSearchGroupView(sender: ComponentButton) {
|
|
|
+ var viewHeight: CGFloat = 8
|
|
|
+ var menuItemArr: [ComponentMenuitemProperty] = []
|
|
|
+ let titles = ["Search", "Find and Replace", "", "Whole Words", "Case Sensitive"]
|
|
|
+ for i in titles {
|
|
|
+ if i.isEmpty {
|
|
|
+ let menuI = ComponentMenuitemProperty.divider()
|
|
|
+ menuItemArr.append(menuI)
|
|
|
+ viewHeight += 8
|
|
|
+ } else {
|
|
|
+ let menuI = ComponentMenuitemProperty(text: KMLocalizedString(i))
|
|
|
+ menuItemArr.append(menuI)
|
|
|
+ viewHeight += 36
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if handdler.type == .search {
|
|
|
+ menuItemArr.first?.righticon = NSImage(named: "KMNImageNameMenuSelect")
|
|
|
+ } else if handdler.type == .replace {
|
|
|
+ let info = menuItemArr.safe_element(for: 1) as? ComponentMenuitemProperty
|
|
|
+ info?.righticon = NSImage(named: "KMNImageNameMenuSelect")
|
|
|
+ }
|
|
|
+ if let info = menuItemArr.safe_element(for: 3) as? ComponentMenuitemProperty {
|
|
|
+ if KMDataManager.ud_bool(forKey: KMNSearchKey.wholeWords.botaSearch) {
|
|
|
+ info.righticon = NSImage(named: "KMNImageNameMenuSelect")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if let info = menuItemArr.last {
|
|
|
+ if KMDataManager.ud_bool(forKey: KMNSearchKey.caseSensitive.botaSearch) {
|
|
|
+ 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)
|
|
|
+
|
|
|
+ let senderView = self.searchItemView_.input
|
|
|
+ var point = senderView.convert(senderView.frame.origin, to: nil)
|
|
|
+ point.y -= viewHeight
|
|
|
+ point.y -= 30
|
|
|
+ groupView?.showWithPoint(point, relativeTo: senderView)
|
|
|
+// searchGroupTarget = sender
|
|
|
+ }
|
|
|
+
|
|
|
// MARK: - Actions
|
|
|
|
|
|
@objc private func _closeAction(_ sender: NSButton) {
|
|
@@ -270,11 +329,14 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
}
|
|
|
self.handdler.showIdx -= 1
|
|
|
self.handdler.showSelection(model.selection)
|
|
|
+ self._showIndexTip()
|
|
|
} else {
|
|
|
if let _ = self.currentSel {
|
|
|
self.currentSel = self.handdler.pdfView?.document.findForwardEditText()
|
|
|
if let sel = self.currentSel {
|
|
|
+ self.handdler.showIdx -= 1
|
|
|
self.handdler.showSelection(sel)
|
|
|
+ self._showIndexTip()
|
|
|
} else {
|
|
|
_showNoResultsAlert()
|
|
|
return
|
|
@@ -298,6 +360,13 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
return
|
|
|
}
|
|
|
self.currentSel = sel
|
|
|
+ self.handdler.showIdx = 0
|
|
|
+ var count = 0
|
|
|
+ for i in datas ?? [] {
|
|
|
+ count += i.count
|
|
|
+ }
|
|
|
+ self.handdler.resultCount = count
|
|
|
+ self._showIndexTip()
|
|
|
self.handdler.showSelection(sel)
|
|
|
}
|
|
|
}
|
|
@@ -313,11 +382,14 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
}
|
|
|
self.handdler.showIdx += 1
|
|
|
self.handdler.showSelection(model.selection)
|
|
|
+ self._showIndexTip()
|
|
|
} else {
|
|
|
if let _ = self.currentSel {
|
|
|
self.currentSel = self.handdler.pdfView?.document.findBackwordEditText()
|
|
|
if let sel = self.currentSel {
|
|
|
+ self.handdler.showIdx += 1
|
|
|
self.handdler.showSelection(sel)
|
|
|
+ self._showIndexTip()
|
|
|
} else {
|
|
|
_showNoResultsAlert()
|
|
|
}
|
|
@@ -340,6 +412,13 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
self._showNoResultsAlert()
|
|
|
return
|
|
|
}
|
|
|
+ self.handdler.showIdx = 0
|
|
|
+ var count = 0
|
|
|
+ for i in datas ?? [] {
|
|
|
+ count += i.count
|
|
|
+ }
|
|
|
+ self.handdler.resultCount = count
|
|
|
+ self._showIndexTip()
|
|
|
self.currentSel = sel
|
|
|
self.handdler.showSelection(sel)
|
|
|
}
|
|
@@ -448,6 +527,17 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
return alert.runModal()
|
|
|
}
|
|
|
|
|
|
+ private func _showIndexTip() {
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ if self.handdler.resultCount == 0 {
|
|
|
+ self.searchItemView_.input.properties.rightText = ""
|
|
|
+ } else {
|
|
|
+ self.searchItemView_.input.properties.rightText = "\(self.handdler.showIdx+1)/\(self.handdler.resultCount)"
|
|
|
+ }
|
|
|
+ self.searchItemView_.input.reloadData()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private func fetchSearchOptions() -> CPDFSearchOptions {
|
|
|
var opt = CPDFSearchOptions()
|
|
|
let isCase = KMDataManager.ud_bool(forKey: KMNSearchKey.caseSensitive.botaSearch)
|
|
@@ -471,7 +561,7 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
self.window?.contentView?.layer?.backgroundColor = .white
|
|
|
}
|
|
|
|
|
|
- self.switchType(self.type_)
|
|
|
+ self.switchType(handdler.type)
|
|
|
}
|
|
|
|
|
|
func switchType(_ type: KMNBotaSearchType, animate: Bool = false) {
|
|
@@ -487,7 +577,7 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- self.type_ = type
|
|
|
+ handdler.type = type
|
|
|
|
|
|
if type == .search { // 248 112
|
|
|
self.replaceBox.isHidden = true
|
|
@@ -570,6 +660,8 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
}
|
|
|
if let sel = sels.first?.selection {
|
|
|
self?.handdler.showIdx = 0
|
|
|
+ self?.handdler.resultCount = sels.count
|
|
|
+ self?._showIndexTip()
|
|
|
self?.handdler.showSelection(sel)
|
|
|
}
|
|
|
})
|
|
@@ -591,6 +683,13 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
return
|
|
|
}
|
|
|
self.currentSel = datas.first?.first
|
|
|
+ self.handdler.showIdx = 0
|
|
|
+ var count = 0
|
|
|
+ for i in datas {
|
|
|
+ count += i.count
|
|
|
+ }
|
|
|
+ self.handdler.resultCount = count
|
|
|
+ self._showIndexTip()
|
|
|
if let sel = self.currentSel {
|
|
|
self.handdler.showSelection(sel)
|
|
|
}
|
|
@@ -600,3 +699,43 @@ class KMSearchReplaceWindowController: KMNBaseWindowController {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+extension KMSearchReplaceWindowController: ComponentGroupDelegate {
|
|
|
+ func componentGroupDidSelect(group: ComponentGroup?, menuItemProperty: ComponentMenuitemProperty?) {
|
|
|
+ if group == searchGroupView_ {
|
|
|
+ guard let menuI = menuItemProperty else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let idx = group?.menuItemArr.firstIndex(of: menuI)
|
|
|
+ if idx == 0 { // search
|
|
|
+ switchType(.search)
|
|
|
+ } else if idx == 1 { // replace
|
|
|
+ switchType(.replace)
|
|
|
+
|
|
|
+ } else if idx == 3 {
|
|
|
+ let key = KMNSearchKey.wholeWords.botaSearch
|
|
|
+ let value = KMDataManager.ud_bool(forKey: key)
|
|
|
+ KMDataManager.ud_set(!value, forKey: key)
|
|
|
+
|
|
|
+ currentSel = nil
|
|
|
+// currentModel_ = nil
|
|
|
+ let data = searchItemView_.inputValue
|
|
|
+ if data.isEmpty {
|
|
|
+ search(keyboard: data)
|
|
|
+ }
|
|
|
+ } else if idx == 4 {
|
|
|
+ let key = KMNSearchKey.caseSensitive.botaSearch
|
|
|
+ let value = KMDataManager.ud_bool(forKey: key)
|
|
|
+ KMDataManager.ud_set(!value, forKey: key)
|
|
|
+
|
|
|
+ currentSel = nil
|
|
|
+// currentModel_ = nil
|
|
|
+
|
|
|
+ let data = searchItemView_.inputValue
|
|
|
+ if data.isEmpty {
|
|
|
+ search(keyboard: data)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|