|
@@ -35,6 +35,31 @@ class KMBOTAOutlineView: BaseXibView {
|
|
|
|
|
|
var isSearchMode = false
|
|
|
var searchKey = ""
|
|
|
+ var wholeWords = false {
|
|
|
+ didSet {
|
|
|
+ if isSearchMode == false {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if searchKey.isEmpty {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ reloadData()
|
|
|
+ outlineView.expandItem(nil, expandChildren: true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var caseSensitive = false {
|
|
|
+ didSet {
|
|
|
+ if isSearchMode == false {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if searchKey.isEmpty {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ reloadData()
|
|
|
+ outlineView.expandItem(nil, expandChildren: true)
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
override func draw(_ dirtyRect: NSRect) {
|
|
|
super.draw(dirtyRect)
|
|
@@ -89,25 +114,26 @@ class KMBOTAOutlineView: BaseXibView {
|
|
|
self.delegate?.BOTAOutlineView(self, didReloadData: self.data ?? KMBOTAOutlineItem())
|
|
|
}
|
|
|
|
|
|
+ // 递归处理
|
|
|
+
|
|
|
func reloadSearchChildren(item: KMBOTAOutlineItem?) {
|
|
|
guard let theItem = item else {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- if theItem.children.isEmpty {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- theItem.isSearchMode = true
|
|
|
+ // 处理当前 item
|
|
|
let models = self.fetchOutlines(for: theItem, searchString: searchKey)
|
|
|
- theItem.isSearchMode = true
|
|
|
+ // 搜索数据
|
|
|
theItem.searchChildren = models
|
|
|
|
|
|
+ theItem.isItemExpanded = true
|
|
|
+
|
|
|
+ if theItem.children.isEmpty { // 递归退出条件
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理 childItem
|
|
|
for childM in theItem.children {
|
|
|
- let models = self.fetchOutlines(for: childM, searchString: searchKey)
|
|
|
- childM.isSearchMode = true
|
|
|
- childM.searchChildren = models
|
|
|
-
|
|
|
self.reloadSearchChildren(item: childM)
|
|
|
}
|
|
|
}
|
|
@@ -145,12 +171,17 @@ class KMBOTAOutlineView: BaseXibView {
|
|
|
func hasContainString(_ searchString: String, rootOutline outline: CPDFOutline) -> Bool {
|
|
|
var label = outline.label ?? ""
|
|
|
var searchLabel = searchString
|
|
|
-// if self.outlineIgnoreCaseFlag {
|
|
|
-// label = label.lowercased()
|
|
|
-// searchLabel = searchLabel.lowercased()
|
|
|
-// }
|
|
|
+ if caseSensitive == false {
|
|
|
+ label = label.lowercased()
|
|
|
+ searchLabel = searchLabel.lowercased()
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
if label.contains(searchLabel) {
|
|
|
-// if ([outline.label rangeOfString:searchString options:self.outlineIgnoreCaseFlag?NSCaseInsensitiveSearch:0].location != NSNotFound){
|
|
|
+ if wholeWords {
|
|
|
+ let words = label.words()
|
|
|
+ return words.contains(searchLabel)
|
|
|
+ }
|
|
|
return true
|
|
|
} else {
|
|
|
var subHas = false
|
|
@@ -194,48 +225,15 @@ extension KMBOTAOutlineView : NSOutlineViewDataSource,NSOutlineViewDelegate {
|
|
|
}
|
|
|
|
|
|
// self.showSearchOutlineBlankState(false)
|
|
|
- rootModel.isItemExpanded = true
|
|
|
- rootModel.isSearchMode = true
|
|
|
-
|
|
|
-// let models = self.fetchOutlines(for: rootModel, searchString: searchKey)
|
|
|
-// for model in models {
|
|
|
-// model.isItemExpanded = true
|
|
|
-// model.isSearchMode = true
|
|
|
-// }
|
|
|
-
|
|
|
-// rootModel.searchChildren = models
|
|
|
-// return models.count
|
|
|
return rootModel.searchChildren.count
|
|
|
}
|
|
|
|
|
|
- rootModel.isSearchMode = false
|
|
|
-// rootModel.searchChildren = []
|
|
|
-// for model in rootModel.children {
|
|
|
-// model.isItemExpanded = true
|
|
|
-// model.isSearchMode = false
|
|
|
-// }
|
|
|
return Int(rootModel.outline.numberOfChildren)
|
|
|
}
|
|
|
if isSearchMode {
|
|
|
- model.isItemExpanded = true
|
|
|
- model.isSearchMode = true
|
|
|
-
|
|
|
-// let models = self.fetchOutlines(for: model, searchString: searchKey)
|
|
|
-// for model in models {
|
|
|
-// model.isItemExpanded = true
|
|
|
-// model.isSearchMode = true
|
|
|
-// }
|
|
|
-// model.searchChildren = models
|
|
|
-// return models.count
|
|
|
return model.searchChildren.count
|
|
|
}
|
|
|
|
|
|
- model.isSearchMode = false
|
|
|
-// model.searchChildren = []
|
|
|
-// for childM in model.children {
|
|
|
-// model.isItemExpanded = true
|
|
|
-// childM.isSearchMode = false
|
|
|
-// }
|
|
|
return model.children.count
|
|
|
}
|
|
|
|
|
@@ -251,35 +249,13 @@ extension KMBOTAOutlineView : NSOutlineViewDataSource,NSOutlineViewDelegate {
|
|
|
return ""
|
|
|
}
|
|
|
// self.showSearchOutlineBlankState(false)
|
|
|
- let models = self.fetchOutlines(for: rootModel, searchString: searchKey)
|
|
|
- for model in models {
|
|
|
- model.isItemExpanded = true
|
|
|
- model.isSearchMode = true
|
|
|
- }
|
|
|
-// rootModel.searchChildren = models
|
|
|
-// return models.safe_element(for: index) as Any
|
|
|
return rootModel.searchChildren.safe_element(for: index) as Any
|
|
|
}
|
|
|
- for model in rootModel.children {
|
|
|
- model.isSearchMode = false
|
|
|
- }
|
|
|
- rootModel.searchChildren = []
|
|
|
return rootModel.children[index] as Any
|
|
|
}
|
|
|
if isSearchMode {
|
|
|
- let models = self.fetchOutlines(for: model, searchString: searchKey)
|
|
|
- for model in models {
|
|
|
- model.isItemExpanded = true
|
|
|
- model.isSearchMode = true
|
|
|
- }
|
|
|
-// model.searchChildren = models
|
|
|
-// return models.safe_element(for: index) as Any
|
|
|
return model.searchChildren.safe_element(for: index) as Any
|
|
|
}
|
|
|
- for childM in model.children {
|
|
|
- childM.isSearchMode = false
|
|
|
- }
|
|
|
- model.searchChildren = []
|
|
|
return model.children[index] as Any
|
|
|
}
|
|
|
|
|
@@ -318,11 +294,14 @@ extension KMBOTAOutlineView : NSOutlineViewDataSource,NSOutlineViewDelegate {
|
|
|
}
|
|
|
|
|
|
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
|
|
|
+ guard let model = item as? KMBOTAOutlineItem else {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
let cell : KMBOTAOutlineCellView = KMBOTAOutlineCellView.init()
|
|
|
- let model = item as? KMBOTAOutlineItem
|
|
|
- cell.model = model
|
|
|
+
|
|
|
if isSearchMode {
|
|
|
- let label = model?.outline.label ?? ""
|
|
|
+ let label = model.outline.label ?? ""
|
|
|
var attri = NSMutableAttributedString(string: label, attributes: [
|
|
|
.font : NSFont.SFProTextRegularFont(13),
|
|
|
.foregroundColor : KMNColorTools.colorText_1()])
|
|
@@ -332,6 +311,23 @@ extension KMBOTAOutlineView : NSOutlineViewDataSource,NSOutlineViewDelegate {
|
|
|
attri.addAttributes([.font : NSFont.SFProTextBoldFont(13), .foregroundColor: KMNColorTools.colorPrimary_textLight()], range: range)
|
|
|
}
|
|
|
cell.titleLabel.attributedStringValue = attri
|
|
|
+
|
|
|
+ cell.iconButton.isHidden = model.searchChildren.isEmpty
|
|
|
+ } else {
|
|
|
+ cell.titleLabel.stringValue = model.outline.label ?? ""
|
|
|
+
|
|
|
+ if model.outline.numberOfChildren > 0 {
|
|
|
+ cell.iconButton.isHidden = false
|
|
|
+ } else {
|
|
|
+ cell.iconButton.isHidden = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let isItemExpanded = model.isItemExpanded
|
|
|
+ if isItemExpanded {
|
|
|
+ cell.iconButton.image = NSImage(named: "KMImageNameArrowDown")
|
|
|
+ } else {
|
|
|
+ cell.iconButton.image = NSImage(named: "KMImageNameArrowRight")
|
|
|
}
|
|
|
|
|
|
cell.iconAction = { [unowned self] view in
|