KMNAlertTipViewController.swift 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. //
  2. // KMNAlertTipViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by 丁林圭 on 2024/12/18.
  6. //
  7. import Cocoa
  8. import KMComponentLibrary
  9. typealias FormFieldHighlightCallback = () -> ()
  10. typealias EnterPasswordCallback = () -> ()
  11. typealias DigitalDetailsCallback = () -> ()
  12. typealias RedactApplyCallback = () -> ()
  13. @objc public enum CPromptDignSignaturesState: NSInteger {
  14. case failure = 0
  15. case Unknown = 1
  16. case Success = 2
  17. }
  18. class KMNAlertTipViewController: KMNBaseViewController {
  19. //Form提示
  20. @IBOutlet var formComponentAlert: ComponentAlert!
  21. //Secure提示
  22. @IBOutlet var secureComponentAlert: ComponentAlert!
  23. //数字签名提示
  24. @IBOutlet var digitalComponentAlert: ComponentAlert!
  25. //密文提示
  26. @IBOutlet var redactComponentAlert: ComponentAlert!
  27. var type:CPromptDignSignaturesState = .failure
  28. var isShowFormAlert = true
  29. var isShowDigitalAlert = true
  30. var isShowSecureAlert = true
  31. var isShowRedactAlert = true
  32. weak var listView:CPDFListView?
  33. var formFieldHighlightCallback: FormFieldHighlightCallback?
  34. var enterPasswordCallback: EnterPasswordCallback?
  35. var digitalDetailsCallback: DigitalDetailsCallback?
  36. var redactApplyCallback: RedactApplyCallback?
  37. override func viewDidLoad() {
  38. super.viewDidLoad()
  39. // Do view setup here.
  40. }
  41. override func initContentView() {
  42. super.initContentView()
  43. }
  44. override func updateUIThemeColor() {
  45. super.updateUIThemeColor()
  46. }
  47. override func updateUILanguage() {
  48. super.updateUILanguage()
  49. let highlightFormFiled = CPDFKitConfig.sharedInstance().enableFormFieldHighlight()
  50. var detailButtonString = ""
  51. if highlightFormFiled {
  52. detailButtonString = KMLocalizedString("Disable Highlight Effect")
  53. } else {
  54. detailButtonString = KMLocalizedString("Highlight Form Fields")
  55. }
  56. formComponentAlert.properties = ComponentAlertProperty(subTitle: KMLocalizedString("This document contains interactive form fields."),detailButtonString: detailButtonString)
  57. formComponentAlert.delegate = self
  58. secureComponentAlert.properties = ComponentAlertProperty(subTitle: KMLocalizedString("This document has a permission password."),detailButtonString: KMLocalizedString("Enter Password"))
  59. secureComponentAlert.delegate = self
  60. digitalComponentAlert.properties = ComponentAlertProperty(subTitle: KMLocalizedString("Signature is valid."),detailButtonString:nil)
  61. digitalComponentAlert.delegate = self
  62. redactComponentAlert.properties = ComponentAlertProperty(subTitle: KMLocalizedString("There are unapplied redactions in this file"),detailButtonString:KMLocalizedString("Apply"))
  63. redactComponentAlert.delegate = self
  64. }
  65. public func reloadFormAlertUI() {
  66. if isShowFormAlert == true {
  67. var isContainsForm = false
  68. for i in 0..<(listView?.document?.pageCount ?? 0) {
  69. guard i < listView?.document?.pageCount ?? 0 else { continue }
  70. let page = listView?.document.page(at: i)
  71. if let annotations = page?.annotations, !annotations.isEmpty {
  72. for annotation in annotations {
  73. if annotation is CPDFWidgetAnnotation {
  74. isContainsForm = true
  75. break
  76. }
  77. }
  78. }
  79. if isContainsForm {
  80. break
  81. }
  82. }
  83. if isContainsForm {
  84. if formComponentAlert.superview == nil {
  85. formComponentAlert.frame = CGRect(x: 0, y: 0, width: listView?.frame.width ?? 0, height: 32.0)
  86. formComponentAlert.autoresizingMask = .width
  87. self.view.addSubview(formComponentAlert)
  88. }
  89. formComponentAlert.reloadData()
  90. } else {
  91. if formComponentAlert.superview != nil {
  92. formComponentAlert.removeFromSuperview()
  93. }
  94. }
  95. } else {
  96. if formComponentAlert.superview != nil {
  97. formComponentAlert.removeFromSuperview()
  98. }
  99. }
  100. }
  101. public func reloadSecureAlertUI() {
  102. if isShowSecureAlert == true {
  103. if listView?.document.permissionsStatus == .user {
  104. if secureComponentAlert.superview == nil {
  105. secureComponentAlert.frame = CGRect(x: 0, y: 0, width: listView?.frame.width ?? 0, height: 32.0)
  106. secureComponentAlert.autoresizingMask = .width
  107. self.view.addSubview(secureComponentAlert)
  108. }
  109. secureComponentAlert.reloadData()
  110. } else {
  111. if secureComponentAlert.superview != nil {
  112. secureComponentAlert.removeFromSuperview()
  113. }
  114. }
  115. } else {
  116. if secureComponentAlert.superview != nil {
  117. secureComponentAlert.removeFromSuperview()
  118. }
  119. }
  120. }
  121. public func reloadDigitalAlertUI() {
  122. if isShowDigitalAlert == true {
  123. let signatures:[CPDFSignature] = listView?.signatures as? [CPDFSignature] ?? []
  124. if signatures.count > 0 {
  125. if digitalComponentAlert.superview == nil {
  126. digitalComponentAlert.frame = CGRect(x: 0, y: 0, width: listView?.frame.width ?? 0, height: 32.0)
  127. digitalComponentAlert.autoresizingMask = .width
  128. self.view.addSubview(digitalComponentAlert)
  129. }
  130. var isSignVerified = false
  131. var isCertTrusted = false
  132. for item in signatures {
  133. let signature: CPDFSignature = item
  134. if signature.signers != nil {
  135. let signer = signature.signers.first
  136. if signer?.isCertTrusted == false {
  137. isCertTrusted = false
  138. break
  139. } else {
  140. isCertTrusted = true
  141. }
  142. }
  143. }
  144. for item in signatures {
  145. let signature: CPDFSignature = item
  146. if signature.signers != nil {
  147. let signer = signature.signers.first
  148. if signer?.isSignVerified == false {
  149. isSignVerified = false
  150. break
  151. } else {
  152. isSignVerified = true
  153. }
  154. }
  155. }
  156. if (isSignVerified && isCertTrusted) {
  157. self.type = .Success;
  158. } else if(isSignVerified && !isCertTrusted) {
  159. self.type = .Unknown;
  160. } else {
  161. self.type = .failure;
  162. }
  163. if (.Success == self.type) {
  164. digitalComponentAlert.properties.messageType = .success
  165. digitalComponentAlert.properties.iconImage = NSImage(named: "KMNImageNameSigntureVerifySuccess")
  166. digitalComponentAlert.properties.subTitle = KMLocalizedString("Signature is valid.")
  167. } else if(.Unknown == self.type) {
  168. digitalComponentAlert.properties.messageType = .warning
  169. digitalComponentAlert.properties.iconImage = NSImage(named: "KMNImageNameSigntureTrustedFailure")
  170. if(signatures.count > 1) {
  171. digitalComponentAlert.properties.subTitle = KMLocalizedString("At least one signature is invalid.")
  172. } else {
  173. digitalComponentAlert.properties.subTitle = KMLocalizedString("Signature is invalid")
  174. }
  175. } else {
  176. digitalComponentAlert.properties.messageType = .error
  177. digitalComponentAlert.properties.iconImage = NSImage(named: "KMNImageNameSigntureVerifyFailures")
  178. if(signatures.count > 1) {
  179. digitalComponentAlert.properties.subTitle = KMLocalizedString("At least one signature is invalid.")
  180. } else {
  181. digitalComponentAlert.properties.subTitle = KMLocalizedString("Signature is invalid")
  182. }
  183. }
  184. digitalComponentAlert.reloadData()
  185. } else {
  186. if digitalComponentAlert.superview != nil {
  187. digitalComponentAlert.removeFromSuperview()
  188. }
  189. }
  190. } else {
  191. if digitalComponentAlert.superview != nil {
  192. digitalComponentAlert.removeFromSuperview()
  193. }
  194. }
  195. }
  196. public func reloadRedactAlertUI() {
  197. if isShowRedactAlert == true {
  198. var isContainsRedact = false
  199. for i in 0..<(listView?.document?.pageCount ?? 0) {
  200. guard i < listView?.document?.pageCount ?? 0 else { continue }
  201. let page = listView?.document.page(at: i)
  202. if let annotations = page?.annotations, !annotations.isEmpty {
  203. for annotation in annotations {
  204. if annotation is CPDFRedactAnnotation {
  205. isContainsRedact = true
  206. break
  207. }
  208. }
  209. }
  210. if isContainsRedact {
  211. break
  212. }
  213. }
  214. if isContainsRedact {
  215. if redactComponentAlert.superview == nil {
  216. redactComponentAlert.frame = CGRect(x: 0, y: 0, width: listView?.frame.width ?? 0, height: 32.0)
  217. redactComponentAlert.autoresizingMask = .width
  218. self.view.addSubview(redactComponentAlert)
  219. }
  220. redactComponentAlert.reloadData()
  221. } else {
  222. if redactComponentAlert.superview != nil {
  223. redactComponentAlert.removeFromSuperview()
  224. }
  225. }
  226. } else {
  227. if redactComponentAlert.superview != nil {
  228. redactComponentAlert.removeFromSuperview()
  229. }
  230. }
  231. }
  232. public func reloadAlertUIFrame() {
  233. var alertHeight = 0.0
  234. if digitalComponentAlert.superview != nil {
  235. digitalComponentAlert.frame = CGRect(x: 0, y: alertHeight, width: listView?.frame.width ?? 0, height: 32.0)
  236. alertHeight += 32.0
  237. }
  238. if formComponentAlert.superview != nil {
  239. if alertHeight > 0 {
  240. alertHeight += 1
  241. }
  242. formComponentAlert.frame = CGRect(x: 0, y: alertHeight, width: listView?.frame.width ?? 0, height: 32.0)
  243. alertHeight += 32.0
  244. }
  245. if secureComponentAlert.superview != nil {
  246. if alertHeight > 0 {
  247. alertHeight += 1
  248. }
  249. secureComponentAlert.frame = CGRect(x: 0, y: alertHeight, width: listView?.frame.width ?? 0, height: 32.0)
  250. alertHeight += 32.0
  251. }
  252. if redactComponentAlert.superview != nil {
  253. if alertHeight > 0 {
  254. alertHeight += 1
  255. }
  256. redactComponentAlert.frame = CGRect(x: 0, y: alertHeight, width: listView?.frame.width ?? 0, height: 32.0)
  257. alertHeight += 32.0
  258. }
  259. if(alertHeight > 0) {
  260. var rect = self.view.frame
  261. rect.size.height = alertHeight
  262. rect.origin.y = (listView?.frame.size.height ?? 0) - alertHeight
  263. self.view.frame = rect
  264. } else {
  265. if self.view.superview != nil {
  266. self.view.removeFromSuperview()
  267. }
  268. }
  269. }
  270. func showInView(_ listView: CPDFListView?) {
  271. self.listView = listView
  272. self.view.frame = CGRect(x: 0, y: 0, width: listView?.frame.size.width ?? 0 , height: 0)
  273. self.view.autoresizingMask = [.width, .minYMargin]
  274. listView?.addSubview(self.view)
  275. reloadSecureAlertUI()
  276. reloadFormAlertUI()
  277. reloadDigitalAlertUI()
  278. reloadRedactAlertUI()
  279. reloadAlertUIFrame()
  280. }
  281. }
  282. //MARK: - ComponentAlertDelegate
  283. extension KMNAlertTipViewController: ComponentAlertDelegate {
  284. func componentAlertDidCloseButtonClick(inputView: ComponentAlert) {
  285. if inputView == formComponentAlert {
  286. isShowFormAlert = false
  287. reloadFormAlertUI()
  288. } else if inputView == secureComponentAlert {
  289. isShowSecureAlert = false
  290. reloadSecureAlertUI()
  291. } else if inputView == digitalComponentAlert {
  292. isShowDigitalAlert = false
  293. reloadDigitalAlertUI()
  294. } else if inputView == redactComponentAlert {
  295. isShowRedactAlert = false
  296. reloadRedactAlertUI()
  297. }
  298. reloadAlertUIFrame()
  299. }
  300. func componentAlertDidButtonClick(inputView: ComponentAlert, buttonIndex: Int) {
  301. if buttonIndex == 1 {
  302. if inputView == formComponentAlert {
  303. formFieldHighlightCallback?()
  304. let highlightFormFiled = CPDFKitConfig.sharedInstance().enableFormFieldHighlight()
  305. var detailButtonString = ""
  306. if highlightFormFiled {
  307. detailButtonString = KMLocalizedString("Disable Highlight Effect")
  308. } else {
  309. detailButtonString = KMLocalizedString("Highlight Form Fields")
  310. }
  311. formComponentAlert.properties.detailButtonString = detailButtonString
  312. formComponentAlert.reloadData()
  313. } else if inputView == secureComponentAlert {
  314. enterPasswordCallback?()
  315. } else if inputView == digitalComponentAlert {
  316. digitalDetailsCallback?()
  317. } else if inputView == redactComponentAlert {
  318. redactApplyCallback?()
  319. }
  320. }
  321. }
  322. }