KMNAlertTipViewController.swift 18 KB

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