|
@@ -6,13 +6,29 @@
|
|
|
//
|
|
|
|
|
|
import Cocoa
|
|
|
+import KMComponentLibrary
|
|
|
|
|
|
-class KMBotaSearchViewController: NSViewController {
|
|
|
+extension KMNSearchKey.wholeWords {
|
|
|
+ static let botaSearch = "BotaSearchWholeWordsKey"
|
|
|
+}
|
|
|
+
|
|
|
+extension KMNSearchKey.caseSensitive {
|
|
|
+ static let botaSearch = "BotaSearchCaseSensitiveKey"
|
|
|
+}
|
|
|
+
|
|
|
+enum KMNBotaSearchType: Int {
|
|
|
+ case search = 1
|
|
|
+ case replace = 2
|
|
|
+}
|
|
|
+
|
|
|
+class KMBotaSearchViewController: KMNBotaBaseViewController {
|
|
|
@IBOutlet weak var searchField: NSSearchField!
|
|
|
@IBOutlet weak var segmentedControl: KMSegmentedControl!
|
|
|
|
|
|
@IBOutlet weak var topView: NSBox!
|
|
|
|
|
|
+ @IBOutlet weak var topHeightConst: NSLayoutConstraint!
|
|
|
+
|
|
|
var contentView: NSView? {
|
|
|
didSet {
|
|
|
if let view = self.contentView {
|
|
@@ -35,6 +51,8 @@ class KMBotaSearchViewController: NSViewController {
|
|
|
@IBOutlet var scrollView: NSScrollView!
|
|
|
@IBOutlet weak var tableView: KMBotaTableView!
|
|
|
|
|
|
+
|
|
|
+
|
|
|
private lazy var topContentView_: KMNBotaSearchTopView? = {
|
|
|
let view = KMNBotaSearchTopView.createFromNib()
|
|
|
return view
|
|
@@ -57,61 +75,96 @@ class KMBotaSearchViewController: NSViewController {
|
|
|
override func loadView() {
|
|
|
super.loadView()
|
|
|
|
|
|
- if let data = topContentView_ {
|
|
|
-// topView.contentView = topContentView_
|
|
|
- topContentView_?.wantsLayer = true
|
|
|
- topContentView_?.layer?.backgroundColor = NSColor.red.cgColor
|
|
|
+ topView.borderWidth = 0
|
|
|
+ topView.fillColor = .clear
|
|
|
+ topView.contentView = topContentView_
|
|
|
+ topContentView_?.itemClick = { [unowned self] idx, params in
|
|
|
+ if idx == KMNBotaSearchTopItemKey.search.rawValue {
|
|
|
+ if let data = params.first as? ComponentButton {
|
|
|
+ showSearchGroupView(sender: data)
|
|
|
+ }
|
|
|
+ } else if idx == KMNBotaSearchTopItemKey.replace.rawValue {
|
|
|
+ if handdler.type == .search {
|
|
|
+ handdler.type = .replace
|
|
|
+ showReplaceView()
|
|
|
+ } else {
|
|
|
+ handdler.type = .search
|
|
|
+ showSearchView()
|
|
|
+ }
|
|
|
+ } else if idx == KMNBotaSearchTopItemKey.switch.rawValue {
|
|
|
+
|
|
|
+ } else if idx == KMNBotaSearchTopItemKey.previous.rawValue {
|
|
|
+ tableViewMoveUp(tableView)
|
|
|
+ } else if idx == KMNBotaSearchTopItemKey.next.rawValue {
|
|
|
+ tableViewMoveDown(tableView)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ showSearchView()
|
|
|
+ topContentView_?.valueDidChange = { [unowned self] sender, info in
|
|
|
+ guard let string = info?[.newKey] as? String else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ let isCase = KMDataManager.ud_bool(forKey: KMNSearchKey.caseSensitive.botaSearch)
|
|
|
+ let isWholeWord = KMDataManager.ud_bool(forKey: KMNSearchKey.wholeWords.botaSearch)
|
|
|
+ handdler.search(keyword: string, isCase: isCase, isWholeWord: isWholeWord) { [unowned self] results in
|
|
|
+ searchResults = results ?? []
|
|
|
+
|
|
|
+ showResult()
|
|
|
+ tableView.reloadData()
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
self.emptySearchLabel.stringValue = KMLocalizedString("No Results")
|
|
|
self.emptySearchLabel.textColor = KMAppearance.Layout.h1Color()
|
|
|
self.emptyBox.fillColor = KMAppearance.Layout.l0Color()
|
|
|
- self.searchLabel.stringValue = KMLocalizedString("Search")
|
|
|
- self.searchLabel.textColor = KMAppearance.Layout.h0Color()
|
|
|
- self.searchTips.stringValue = KMLocalizedString("Search")
|
|
|
- self.searchTips.textColor = KMAppearance.Layout.h2Color()
|
|
|
- self.searchResultsLabel.textColor = KMAppearance.Layout.h1Color()
|
|
|
- self.pageLabel.stringValue = KMLocalizedString("Page")
|
|
|
- self.pageLabel.textColor = KMAppearance.Layout.h1Color()
|
|
|
- self.searchResultsView.isHidden = true
|
|
|
+// self.searchLabel.stringValue = KMLocalizedString("Search")
|
|
|
+// self.searchLabel.textColor = KMAppearance.Layout.h0Color()
|
|
|
+// self.searchTips.stringValue = KMLocalizedString("Search")
|
|
|
+// self.searchTips.textColor = KMAppearance.Layout.h2Color()
|
|
|
+// self.searchResultsLabel.textColor = KMAppearance.Layout.h1Color()
|
|
|
+// self.pageLabel.stringValue = KMLocalizedString("Page")
|
|
|
+// self.pageLabel.textColor = KMAppearance.Layout.h1Color()
|
|
|
+// self.searchResultsView.isHidden = true
|
|
|
|
|
|
- self.searchDomeButton.title = KMLocalizedString("Done")
|
|
|
- self.searchDomeButton.toolTip = KMLocalizedString("Done")
|
|
|
- self.searchDomeButton.setTitleColor(KMAppearance.Layout.w0Color())
|
|
|
- self.searchDomeButton.wantsLayer = true
|
|
|
- self.searchDomeButton.layer?.backgroundColor = KMAppearance.Interactive.a0Color().cgColor
|
|
|
- self.searchDomeButton.layer?.cornerRadius = 4.0
|
|
|
+// self.searchDomeButton.title = KMLocalizedString("Done")
|
|
|
+// self.searchDomeButton.toolTip = KMLocalizedString("Done")
|
|
|
+// self.searchDomeButton.setTitleColor(KMAppearance.Layout.w0Color())
|
|
|
+// self.searchDomeButton.wantsLayer = true
|
|
|
+// self.searchDomeButton.layer?.backgroundColor = KMAppearance.Interactive.a0Color().cgColor
|
|
|
+// self.searchDomeButton.layer?.cornerRadius = 4.0
|
|
|
// self.searchDomeButton.hidden = YES;
|
|
|
|
|
|
- self.searchField.wantsLayer = true
|
|
|
+// self.searchField.wantsLayer = true
|
|
|
// self.searchField.layer.backgroundColor = [KMAppearance KMColor_Layout_L1].CGColor;
|
|
|
- self.searchField.layer?.cornerRadius = 1.0
|
|
|
- self.searchField.layer?.borderWidth = 1.0
|
|
|
- self.searchField.layer?.borderColor = KMAppearance.Interactive.a0Color().cgColor
|
|
|
+// self.searchField.layer?.cornerRadius = 1.0
|
|
|
+// self.searchField.layer?.borderWidth = 1.0
|
|
|
+// self.searchField.layer?.borderColor = KMAppearance.Interactive.a0Color().cgColor
|
|
|
|
|
|
- self.searchBox.fillColor = KMAppearance.Interactive.s0Color()
|
|
|
+// self.searchBox.fillColor = KMAppearance.Interactive.s0Color()
|
|
|
// self.searchField.hidden = YES;
|
|
|
- self.searchBox.downCallback = { [unowned self] downEntered, box, _ in
|
|
|
- if (downEntered) {
|
|
|
- self.searchField.isHidden = false
|
|
|
- self.searchDomeButton.isHidden = false
|
|
|
- self.searchBox.isHidden = true
|
|
|
- self.searchField.becomeFirstResponder()
|
|
|
- }
|
|
|
- }
|
|
|
+// self.searchBox.downCallback = { [unowned self] downEntered, box, _ in
|
|
|
+// if (downEntered) {
|
|
|
+// self.searchField.isHidden = false
|
|
|
+// self.searchDomeButton.isHidden = false
|
|
|
+// self.searchBox.isHidden = true
|
|
|
+// self.searchField.becomeFirstResponder()
|
|
|
+// }
|
|
|
+// }
|
|
|
|
|
|
- self.searchBox.isHidden = true
|
|
|
+// self.searchBox.isHidden = true
|
|
|
|
|
|
contentView = tableView.enclosingScrollView
|
|
|
|
|
|
- let menu = NSMenu()
|
|
|
- _ = menu.addItem(title: KMLocalizedString("Whole Words Only"), action: #selector(toggleWholeWordSearch), target: self)
|
|
|
- _ = menu.addItem(title: KMLocalizedString("Ignore Case"), action: #selector(toggleCaseInsensitiveSearch), target: self)
|
|
|
- (self.searchField.cell as? NSSearchFieldCell)?.searchMenuTemplate = menu
|
|
|
- (self.searchField.cell as? NSSearchFieldCell)?.placeholderString = KMLocalizedString("Search PDF")
|
|
|
-
|
|
|
- self.searchField.target = self
|
|
|
- self.searchField.action = #selector(searchAction)
|
|
|
+// let menu = NSMenu()
|
|
|
+// _ = menu.addItem(title: KMLocalizedString("Whole Words Only"), action: #selector(toggleWholeWordSearch), target: self)
|
|
|
+// _ = menu.addItem(title: KMLocalizedString("Ignore Case"), action: #selector(toggleCaseInsensitiveSearch), target: self)
|
|
|
+// (self.searchField.cell as? NSSearchFieldCell)?.searchMenuTemplate = menu
|
|
|
+// (self.searchField.cell as? NSSearchFieldCell)?.placeholderString = KMLocalizedString("Search PDF")
|
|
|
+//
|
|
|
+// self.searchField.target = self
|
|
|
+// self.searchField.action = #selector(searchAction)
|
|
|
}
|
|
|
|
|
|
override func viewDidLoad() {
|
|
@@ -125,24 +178,112 @@ class KMBotaSearchViewController: NSViewController {
|
|
|
// self.mwcFlags.wholeWordSearch = KMDataManager.ud_integer(forKey: SKWholeWordSearchKey)
|
|
|
// self.mwcFlags.caseInsensitiveSearch = KMDataManager.ud_integer(forKey: SKCaseInsensitiveSearchKey)
|
|
|
|
|
|
- self.tableView.backgroundColor = KMAppearance.Layout.l0Color()
|
|
|
+// self.tableView.backgroundColor = KMAppearance.Layout.l0Color()
|
|
|
self.tableView.tableColumn(withIdentifier: kPageColumnId)?.headerCell.title = KMLocalizedString("Page")
|
|
|
}
|
|
|
|
|
|
override func viewDidAppear() {
|
|
|
super.viewDidAppear()
|
|
|
|
|
|
- self.searchField.becomeFirstResponder()
|
|
|
+// self.searchField.becomeFirstResponder()
|
|
|
self.updateViewColor()
|
|
|
DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged), name: NSApplication.interfaceThemeChangedNotification, object: nil)
|
|
|
}
|
|
|
|
|
|
+ override func updateUILanguage() {
|
|
|
+ super.updateUILanguage()
|
|
|
+
|
|
|
+ KMMainThreadExecute {
|
|
|
+ self.topContentView_?.resultLabel.stringValue = KMLocalizedString("Result:") + " " + "\(self.handdler.searchResults.count)"
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override func updateUIThemeColor() {
|
|
|
+ super.updateUIThemeColor()
|
|
|
+
|
|
|
+ KMMainThreadExecute {
|
|
|
+ self.view.wantsLayer = true
|
|
|
+ let color = KMNColorTools.colorBg_layoutMiddle()
|
|
|
+ self.view.layer?.backgroundColor = color.cgColor
|
|
|
+
|
|
|
+ self.tableView.backgroundColor = color
|
|
|
+
|
|
|
+ self.topContentView_?.resultLabel.textColor = KMNColorTools.colorText_3()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
func updateViewColor() {
|
|
|
if (KMAppearance.isDarkMode()) {
|
|
|
- self.searchField.layer?.backgroundColor = NSColor(red: 57.0/255.0, green: 60.0/255.0, blue: 62.0/255.0, alpha: 1).cgColor
|
|
|
+// self.searchField.layer?.backgroundColor = NSColor(red: 57.0/255.0, green: 60.0/255.0, blue: 62.0/255.0, alpha: 1).cgColor
|
|
|
} else {
|
|
|
- self.searchField.layer?.backgroundColor = .white
|
|
|
+// self.searchField.layer?.backgroundColor = .white
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func showSearchView() {
|
|
|
+ topContentView_?.showSearch()
|
|
|
+
|
|
|
+ topHeightConst.constant = topContentView_?.fetchContentHeight(type: handdler.type, hasResult: handdler.searchResults.isEmpty == false) ?? 0
|
|
|
+ }
|
|
|
+
|
|
|
+ func showReplaceView() {
|
|
|
+ topContentView_?.showReplace()
|
|
|
+
|
|
|
+ topHeightConst.constant = topContentView_?.fetchContentHeight(type: handdler.type, hasResult: handdler.searchResults.isEmpty == false) ?? 0
|
|
|
+ }
|
|
|
+
|
|
|
+ func showResult() {
|
|
|
+ topContentView_?.showResult(type: handdler.type)
|
|
|
+
|
|
|
+ topContentView_?.resultLabel.stringValue = KMLocalizedString("Result:") + " " + "\(self.handdler.searchResults.count)"
|
|
|
+ topHeightConst.constant = topContentView_?.fetchContentHeight(type: handdler.type, hasResult: searchResults.isEmpty == false) ?? 0
|
|
|
+ }
|
|
|
+
|
|
|
+ // 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)
|
|
|
+
|
|
|
+ var point = sender.convert(sender.frame.origin, to: nil)
|
|
|
+ point.y -= viewHeight
|
|
|
+ groupView?.showWithPoint(point, relativeTo: sender)
|
|
|
+ searchGroupTarget = sender
|
|
|
}
|
|
|
|
|
|
@objc func themeChanged(_ notification: NSNotification) {
|
|
@@ -205,11 +346,11 @@ class KMBotaSearchViewController: NSViewController {
|
|
|
func updataLeftSideFindView() {
|
|
|
if (self.searchResults.count > 0) {
|
|
|
self.emptyBox.isHidden = true
|
|
|
- self.searchResultsView.isHidden = false
|
|
|
- self.searchResultsLabel.stringValue = String(format: KMLocalizedString("%ld Results"), self.searchResults.count)
|
|
|
+// self.searchResultsView.isHidden = false
|
|
|
+// self.searchResultsLabel.stringValue = String(format: KMLocalizedString("%ld Results"), self.searchResults.count)
|
|
|
} else {
|
|
|
self.emptyBox.isHidden = false
|
|
|
- self.searchResultsView.isHidden = true
|
|
|
+// self.searchResultsView.isHidden = true
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -328,3 +469,89 @@ extension KMBotaSearchViewController: KMBotaTableViewDelegate {
|
|
|
}
|
|
|
|
|
|
}
|
|
|
+
|
|
|
+//MARK: - ComponentGroupDelegate
|
|
|
+
|
|
|
+extension KMBotaSearchViewController: ComponentGroupDelegate {
|
|
|
+ func componentGroupDidDismiss(group: ComponentGroup?) {
|
|
|
+// if group == groupView_ {
|
|
|
+// removeGroupView()
|
|
|
+// } else if group == menuGroupView_ {
|
|
|
+// group?.removeFromSuperview()
|
|
|
+// menuGroupView_ = nil
|
|
|
+// } else
|
|
|
+ if group == searchGroupView {
|
|
|
+// searchGroupView_ = nil
|
|
|
+ searchGroupTarget?.properties.state = .normal
|
|
|
+ searchGroupTarget?.reloadData()
|
|
|
+ searchGroupTarget = nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func componentGroupDidSelect(group: ComponentGroup?, menuItemProperty: ComponentMenuitemProperty?) {
|
|
|
+// if group == groupView_ {
|
|
|
+// if let selItem = menuItemProperty {
|
|
|
+// let index = group?.menuItemArr.firstIndex(of: selItem)
|
|
|
+// if index == 0 {
|
|
|
+// expandAllComments(item: NSMenuItem())
|
|
|
+// } else if index == 1 {
|
|
|
+// collapseAllComments(item: NSMenuItem())
|
|
|
+// } else if index == 2 {
|
|
|
+// removeAllOutlineItem(item: NSMenuItem())
|
|
|
+// }
|
|
|
+// }
|
|
|
+// } else if group == menuGroupView_ {
|
|
|
+// if let selItem = menuItemProperty {
|
|
|
+// let index = group?.menuItemArr.firstIndex(of: selItem)
|
|
|
+// if index == 0 {
|
|
|
+// addItemAction()
|
|
|
+// } else if index == 1 {
|
|
|
+// addChildItemAction()
|
|
|
+// } else if index == 2 {
|
|
|
+// addHigherItemAction()
|
|
|
+// } else if index == 4 {
|
|
|
+// deleteItemAction()
|
|
|
+// } else if index == 6 {
|
|
|
+// group?.removeFromSuperview()
|
|
|
+//
|
|
|
+// editItemAction()
|
|
|
+// } else if index == 7 {
|
|
|
+// renameItemAction()
|
|
|
+// } else if index == 8 {
|
|
|
+// changeItemAction()
|
|
|
+// } else if index == 10 {
|
|
|
+// promoteItemAction()
|
|
|
+// } else if index == 11 {
|
|
|
+// demoteItemAction()
|
|
|
+// }
|
|
|
+//
|
|
|
+// group?.removeFromSuperview()
|
|
|
+// }
|
|
|
+// } else
|
|
|
+ if group == searchGroupView {
|
|
|
+ guard let menuI = menuItemProperty else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let idx = group?.menuItemArr.firstIndex(of: menuI)
|
|
|
+ if idx == 0 { // search
|
|
|
+
|
|
|
+ } else if idx == 1 { // replace
|
|
|
+
|
|
|
+ } else if idx == 3 {
|
|
|
+ let key = KMNSearchKey.wholeWords.botaSearch
|
|
|
+ let value = KMDataManager.ud_bool(forKey: key)
|
|
|
+ KMDataManager.ud_set(!value, forKey: key)
|
|
|
+
|
|
|
+// BOTAOutlineView.wholeWords = !value
|
|
|
+ } else if idx == 4 {
|
|
|
+ let key = KMNSearchKey.caseSensitive.botaSearch
|
|
|
+ let value = KMDataManager.ud_bool(forKey: key)
|
|
|
+ KMDataManager.ud_set(!value, forKey: key)
|
|
|
+
|
|
|
+// BOTAOutlineView.caseSensitive = !value
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|