KMNAlertTipViewController.swift 16 KB

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