KMOCToolClass.swift 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. //
  2. // KMOCToolClass.swift
  3. // PDF Master
  4. //
  5. // Created by lizhe on 2023/9/26.
  6. //
  7. import Cocoa
  8. struct MwcFlags {
  9. var caseInsensitiveSearch: Int = 1
  10. var wholeWordSearch: Int = 1
  11. var settingUpWindow: Int = 1
  12. }
  13. class KMOCToolClass {
  14. class func filterAnnotation(annotations: [Any], types: [Any]) -> [Any] {
  15. let array = annotations
  16. let leftExpression = NSExpression(forKeyPath: "type")
  17. let rightExpression = NSExpression(forConstantValue: types)
  18. let predicate = NSComparisonPredicate(
  19. leftExpression: leftExpression,
  20. rightExpression: rightExpression,
  21. modifier: .direct,
  22. type: .in,
  23. options: .diacriticInsensitive
  24. )
  25. return (array as NSArray).filtered(using: predicate)
  26. }
  27. class func filterAnnotation(annotations: [Any], colors: [Any]) -> [Any] {
  28. var array = annotations
  29. if array.contains(where: { $0 is NSColor && ($0 as! NSColor) == NSColor.clear }) {
  30. array.removeAll { $0 is NSColor && ($0 as! NSColor) == NSColor.clear }
  31. }
  32. let leftExpression = NSExpression(forKeyPath: "color")
  33. let rightExpression = NSExpression(forConstantValue: colors)
  34. let predicate = NSComparisonPredicate(
  35. leftExpression: leftExpression,
  36. rightExpression: rightExpression,
  37. modifier: .direct,
  38. type: .in,
  39. options: .diacriticInsensitive
  40. )
  41. return (array as NSArray).filtered(using: predicate)
  42. }
  43. class func filterAnnotation(annotations: [Any], authors: [Any]) -> [Any] {
  44. let array = annotations
  45. let leftExpression = NSExpression(forKeyPath: "userName")
  46. let rightExpression = NSExpression(forConstantValue: authors)
  47. let predicate = NSComparisonPredicate(
  48. leftExpression: leftExpression,
  49. rightExpression: rightExpression,
  50. modifier: .direct,
  51. type: .in,
  52. options: .diacriticInsensitive
  53. )
  54. return (array as NSArray).filtered(using: predicate)
  55. }
  56. class func arrayContains(array: [Any]?, annotation item: Any?) -> Bool {
  57. return array?.contains { $0 as AnyObject === item as AnyObject } ?? false
  58. }
  59. class func arrayIndexOf<T: Equatable>(array: [T], item: T) -> Int? {
  60. guard let index = array.firstIndex(of: item) else {
  61. return nil // Return nil to indicate that the item was not found
  62. }
  63. return index
  64. }
  65. class func exproString(annotation: CPDFAnnotation) -> String {
  66. var exproString = ""
  67. if let markupAnnotation = annotation as? CPDFMarkupAnnotation,
  68. let page = markupAnnotation.page,
  69. let points = markupAnnotation.quadrilateralPoints as? [CGPoint], // Cast to [CGPoint]
  70. points.count % 4 == 0 {
  71. for i in stride(from: 0, to: points.count, by: 4) {
  72. let ptlt = points[i]
  73. let ptrt = points[i + 1]
  74. let ptlb = points[i + 2]
  75. let ptrb = points[i + 3]
  76. let rect = CGRect(x: ptlt.x, y: ptlt.y, width: ptrt.x - ptlt.x, height: ptrt.y - ptlt.y)
  77. if let string = page.string(for: rect), !string.isEmpty {
  78. if !exproString.isEmpty {
  79. exproString += "\n"
  80. }
  81. exproString += string
  82. }
  83. }
  84. }
  85. return exproString
  86. }
  87. class func getAttributedString(selection: CPDFSelection, keyword: String) -> NSMutableAttributedString {
  88. guard let currentPage = selection.page else {
  89. return NSMutableAttributedString()
  90. }
  91. let range = selection.range
  92. var startLocation = 0
  93. let maxLocation: UInt = 10
  94. let maxEndLocation: UInt = 50
  95. var keyLocation = 0
  96. if range.location > maxLocation {
  97. startLocation = range.location - Int(maxLocation)
  98. keyLocation = Int(maxLocation)
  99. } else {
  100. startLocation = 0
  101. keyLocation = range.location
  102. }
  103. var endLocation: UInt = 0
  104. if range.location + Int(maxEndLocation) > currentPage.numberOfCharacters {
  105. endLocation = UInt(currentPage.numberOfCharacters)
  106. } else {
  107. endLocation = UInt(range.location + Int(maxEndLocation))
  108. }
  109. var attributed: NSMutableAttributedString = NSMutableAttributedString()
  110. if endLocation > UInt(startLocation) {
  111. let string = currentPage.string(for: NSRange(location: startLocation, length: Int(endLocation) - startLocation))
  112. var currentString = "..."
  113. let stringArr = string?.components(separatedBy: CharacterSet.newlines) ?? []
  114. for s in stringArr {
  115. if s.isEmpty {
  116. currentString += " "
  117. } else {
  118. currentString += s
  119. }
  120. }
  121. let tRange = NSRange(location: keyLocation + 3, length: keyword.count)
  122. if tRange.location != NSNotFound {
  123. attributed = NSMutableAttributedString(string: currentString)
  124. let paragraphStyle = NSMutableParagraphStyle()
  125. paragraphStyle.firstLineHeadIndent = 10.0
  126. paragraphStyle.headIndent = 10.0
  127. paragraphStyle.lineBreakMode = .byCharWrapping
  128. paragraphStyle.lineHeightMultiple = 1.32
  129. let dic: [NSAttributedString.Key: Any] = [
  130. .font: NSFont(name: "SFProText-Regular", size: 14.0)!,
  131. .foregroundColor: NSColor(red: 0.145, green: 0.149, blue: 0.161, alpha: 1),
  132. .paragraphStyle: paragraphStyle
  133. ]
  134. let fullRange = NSRange(location: 0, length: attributed.length)
  135. attributed.setAttributes(dic, range: fullRange)
  136. // Highlight string
  137. let highlightDic: [NSAttributedString.Key: Any] = [
  138. .backgroundColor: NSColor(red: 1.0, green: 0.9, blue: 0.0, alpha: 1.0)
  139. ]
  140. if attributed.length > tRange.length + tRange.location {
  141. attributed.addAttributes(highlightDic, range: tRange)
  142. }
  143. }
  144. }
  145. return attributed
  146. }
  147. }