KMLanguageViewController.swift 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //
  2. // KMLanguageViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by liujiajie on 2023/11/16.
  6. //
  7. import Cocoa
  8. @objc(KMLanguageTableCellViewDelegate)
  9. protocol KMLanguageTableCellViewDelegate: AnyObject {
  10. @objc optional func tableCellViewCheckButtonDidChange(_ cell: KMLanguageTableCellView)
  11. }
  12. class KMLanguageTableCellView: NSTableCellView{
  13. var delegate: KMLanguageTableCellViewDelegate?
  14. var language: [String: String] = [:]
  15. @IBOutlet var checkButton: NSButton!
  16. @IBAction func checkButtonAction(_ sender: NSButton) {
  17. self.delegate?.tableCellViewCheckButtonDidChange?(self)
  18. }
  19. }
  20. class KMLanguageViewController: NSViewController,KMLanguageTableCellViewDelegate,NSOutlineViewDelegate,NSOutlineViewDataSource,NSTokenFieldDelegate{
  21. @IBOutlet var tokenField: NSTokenField!
  22. @IBOutlet var outlineView: NSOutlineView!
  23. var languages: NSArray?
  24. lazy var selectedLanguages: NSMutableArray = {
  25. if KMGOCRManager.default().selectedLanguages == nil {
  26. KMGOCRManager.default().selectedLanguages = NSMutableArray()
  27. }
  28. return KMGOCRManager.default().selectedLanguages!
  29. }()
  30. var builtInKeywords: Array<Any>?
  31. override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) {
  32. super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
  33. }
  34. required init?(coder: NSCoder) {
  35. super.init(coder: coder)
  36. }
  37. override func awakeFromNib() {
  38. super.awakeFromNib()
  39. self.languages = KMGOCRManager.languages() as NSArray
  40. self.outlineView.reloadData()
  41. self.builtInKeywords = self.languages?.value(forKeyPath: KMGOCRLanguageStringKey) as? [String]
  42. self.tokenField.cell?.lineBreakMode = .byTruncatingTail
  43. self.updateTokenField()
  44. }
  45. func updateTokenField() {
  46. self.tokenField.objectValue = self.selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey)
  47. // commit the edit change
  48. let fieldEditor = self.tokenField.currentEditor()
  49. fieldEditor?.selectedRange = NSRange(location: fieldEditor?.string.count ?? 0, length: 0)
  50. }
  51. func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
  52. return self.languages?.count ?? 0
  53. }
  54. func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
  55. return self.languages?[index] as Any
  56. }
  57. func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
  58. return false
  59. }
  60. func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
  61. if let itemDictionary = item as? NSDictionary {
  62. let result = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DataCell"), owner: self) as? KMLanguageTableCellView
  63. result?.textField?.stringValue = itemDictionary[KMGOCRLanguageStringKey] as? String ?? ""
  64. result?.checkButton.state = self.selectedLanguages.contains(itemDictionary) ? .on : .off
  65. result?.language = itemDictionary as! [String : String]
  66. result?.delegate = self
  67. return result
  68. }
  69. return nil
  70. }
  71. func outlineView(_ outlineView: NSOutlineView, shouldSelectItem item: Any) -> Bool {
  72. return false
  73. }
  74. func tableCellViewCheckButtonDidChange(_ cell: KMLanguageTableCellView) {
  75. if cell.checkButton.state == .on {
  76. if !self.selectedLanguages.contains(cell.language) {
  77. self.selectedLanguages.add(cell.language)
  78. }
  79. } else {
  80. if self.selectedLanguages.contains(cell.language) {
  81. self.selectedLanguages.remove(cell.language)
  82. }
  83. }
  84. self.updateTokenField()
  85. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "KMOCRSelectedLanguagesChangeNotification"), object: self.selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey))
  86. }
  87. //MARK: NSTokenFieldDelegate
  88. func tokenField(_ tokenField: NSTokenField, shouldAdd tokens: [Any], at index: Int) -> [Any] {
  89. let newTokens = NSMutableArray()
  90. for string in tokens {
  91. let arr: NSArray = self.builtInKeywords! as NSArray
  92. if arr.contains(string) {
  93. newTokens.add(string as! String)
  94. } else {
  95. continue
  96. }
  97. let ar: NSArray = self.selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey) as! NSArray
  98. if !ar.contains(string) {
  99. let index = (self.languages?.value(forKeyPath: KMGOCRLanguageStringKey) as AnyObject).index(of: string)
  100. if let OCRLanguage = self.languages?[index] as? NSDictionary {
  101. self.selectedLanguages.add(OCRLanguage)
  102. }
  103. }
  104. }
  105. self.outlineView.reloadData()
  106. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "KMOCRSelectedLanguagesChangeNotification"), object: self.selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey))
  107. return newTokens as! [String]
  108. }
  109. func tokenField(_ tokenField: NSTokenField, completionsForSubstring substring: String, indexOfToken tokenIndex: Int, indexOfSelectedItem selectedIndex: UnsafeMutablePointer<Int>?) -> [Any]? {
  110. let arrayFilter = self.selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey) as? NSArray
  111. // let str = String(format: "NOT (SELF in %@)", arrayFilter ?? "{}")
  112. let thePredicate = NSPredicate(format: "NOT (SELF in %@)", arrayFilter ?? [])
  113. let arr: NSArray = self.builtInKeywords! as NSArray
  114. let newBuiltInKeywords: NSArray = arr.filtered(using: thePredicate) as NSArray
  115. // let str1 = String(format: "SELF beginswith[cd] %@", substring)
  116. let matches = newBuiltInKeywords.filtered(using: NSPredicate(format: "SELF beginswith[cd] %@", substring))
  117. return matches
  118. }
  119. func controlTextDidEndEditing(_ obj: Notification) {
  120. let array: NSArray = self.tokenField.objectValue as! NSArray
  121. let string = array.lastObject
  122. let newArray = NSMutableArray.init(array: array)
  123. let arr: NSArray = self.builtInKeywords! as NSArray
  124. if !arr.contains(string ?? "") {
  125. newArray.remove(string ?? "")
  126. }
  127. self.tokenField.objectValue = newArray
  128. self.selectedLanguages.removeAllObjects()
  129. for string in self.tokenField.objectValue as? [String] ?? [] {
  130. if !(self.selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey) as? [String] ?? []).contains(string) {
  131. let index = (self.languages?.value(forKeyPath: KMGOCRLanguageStringKey) as AnyObject).index(of: string)
  132. if let OCRLanguage = self.languages?[index] as? NSDictionary {
  133. self.selectedLanguages.add(OCRLanguage)
  134. }
  135. }
  136. }
  137. self.outlineView.reloadData()
  138. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "KMOCRSelectedLanguagesChangeNotification"),
  139. object: self.selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey))
  140. }
  141. func controlTextDidChange(_ obj: Notification) {
  142. if selectedLanguages.count > (self.tokenField.objectValue as? [Any] ?? []).count {
  143. self.selectedLanguages.removeAllObjects()
  144. for string in self.tokenField.objectValue as? [String] ?? [] {
  145. if !(self.selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey) as? [String] ?? []).contains(string) {
  146. let index = (self.languages?.value(forKeyPath: KMGOCRLanguageStringKey) as AnyObject).index(of: string)
  147. if let OCRLanguage = self.languages?[index] as? NSDictionary {
  148. self.selectedLanguages.add(OCRLanguage)
  149. }
  150. }
  151. }
  152. self.outlineView.reloadData()
  153. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "KMOCRSelectedLanguagesChangeNotification"),
  154. object: self.selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey))
  155. }
  156. }
  157. }