// // KMNAlertTipViewController.swift // PDF Reader Pro // // Created by 丁林圭 on 2024/12/18. // import Cocoa import KMComponentLibrary typealias FormFieldHighlightCallback = () -> () typealias EnterPasswordCallback = () -> () typealias DigitalDetailsCallback = () -> () typealias RedactApplyCallback = () -> () typealias OCRApplyCallback = () -> () @objc public enum CPromptDignSignaturesState: NSInteger { case failure = 0 case Unknown = 1 case Success = 2 } class KMNAlertTipViewController: KMNBaseViewController { //Form提示 @IBOutlet var formComponentAlert: ComponentAlert! //Secure提示 @IBOutlet var secureComponentAlert: ComponentAlert! //数字签名提示 @IBOutlet var digitalComponentAlert: ComponentAlert! //密文提示 @IBOutlet var redactComponentAlert: ComponentAlert! //OCR提示 @IBOutlet var OCRComponentAlert: ComponentAlert! var type:CPromptDignSignaturesState = .failure var isShowFormAlert = true var isShowDigitalAlert = true var isShowSecureAlert = true var isShowRedactAlert = true var isShowOCRAlert = true weak var listView:CPDFListView? var formFieldHighlightCallback: FormFieldHighlightCallback? var enterPasswordCallback: EnterPasswordCallback? var digitalDetailsCallback: DigitalDetailsCallback? var redactApplyCallback: RedactApplyCallback? var OCRApplyCallback: OCRApplyCallback? override func viewDidLoad() { super.viewDidLoad() // Do view setup here. } override func initContentView() { super.initContentView() } override func updateUIThemeColor() { super.updateUIThemeColor() } override func updateUILanguage() { super.updateUILanguage() let highlightFormFiled = CPDFKitConfig.sharedInstance().enableFormFieldHighlight() var detailButtonString = "" if highlightFormFiled { detailButtonString = KMLocalizedString("Disable Highlight Effect") } else { detailButtonString = KMLocalizedString("Highlight Form Fields") } formComponentAlert.properties = ComponentAlertProperty(subTitle: KMLocalizedString("This document contains interactive form fields."),detailButtonString: detailButtonString) formComponentAlert.delegate = self secureComponentAlert.properties = ComponentAlertProperty(subTitle: KMLocalizedString("This document has a permission password."),detailButtonString: KMLocalizedString("Enter Password")) secureComponentAlert.delegate = self digitalComponentAlert.properties = ComponentAlertProperty(subTitle: KMLocalizedString("Signature is valid."),detailButtonString:nil) digitalComponentAlert.delegate = self redactComponentAlert.properties = ComponentAlertProperty(subTitle: KMLocalizedString("There are unapplied redactions in this file"),detailButtonString:KMLocalizedString("Apply")) redactComponentAlert.delegate = self OCRComponentAlert.properties = ComponentAlertProperty(subTitle: KMLocalizedString("This document contains scanned pages and requires OCR recognition before editing."),detailButtonString:KMLocalizedString("OCR")) OCRComponentAlert.delegate = self } public func reloadFormAlertUI() { if isShowFormAlert == true { var isContainsForm = false for i in 0..<(listView?.document?.pageCount ?? 0) { guard i < listView?.document?.pageCount ?? 0 else { continue } let page = listView?.document.page(at: i) if let annotations = page?.annotations, !annotations.isEmpty { for annotation in annotations { if annotation is CPDFWidgetAnnotation { isContainsForm = true break } } } if isContainsForm { break } } if isContainsForm { if formComponentAlert.superview == nil { formComponentAlert.frame = CGRect(x: 0, y: 0, width: listView?.frame.width ?? 0, height: 32.0) formComponentAlert.autoresizingMask = .width self.view.addSubview(formComponentAlert) } formComponentAlert.reloadData() } else { if formComponentAlert.superview != nil { formComponentAlert.removeFromSuperview() } } } else { if formComponentAlert.superview != nil { formComponentAlert.removeFromSuperview() } } } public func reloadSecureAlertUI() { if isShowSecureAlert == true { if listView?.document.permissionsStatus == .user { if secureComponentAlert.superview == nil { secureComponentAlert.frame = CGRect(x: 0, y: 0, width: listView?.frame.width ?? 0, height: 32.0) secureComponentAlert.autoresizingMask = .width self.view.addSubview(secureComponentAlert) } secureComponentAlert.reloadData() } else { if secureComponentAlert.superview != nil { secureComponentAlert.removeFromSuperview() } } } else { if secureComponentAlert.superview != nil { secureComponentAlert.removeFromSuperview() } } } public func reloadDigitalAlertUI() { if isShowDigitalAlert == true { let signatures:[CPDFSignature] = listView?.signatures as? [CPDFSignature] ?? [] if signatures.count > 0 { if digitalComponentAlert.superview == nil { digitalComponentAlert.frame = CGRect(x: 0, y: 0, width: listView?.frame.width ?? 0, height: 32.0) digitalComponentAlert.autoresizingMask = .width self.view.addSubview(digitalComponentAlert) } var isSignVerified = false var isCertTrusted = false for item in signatures { let signature: CPDFSignature = item if signature.signers != nil { let signer = signature.signers.first if signer?.isCertTrusted == false { isCertTrusted = false break } else { isCertTrusted = true } } } for item in signatures { let signature: CPDFSignature = item if signature.signers != nil { let signer = signature.signers.first if signer?.isSignVerified == false { isSignVerified = false break } else { isSignVerified = true } } } if (isSignVerified && isCertTrusted) { self.type = .Success; } else if(isSignVerified && !isCertTrusted) { self.type = .Unknown; } else { self.type = .failure; } if (.Success == self.type) { digitalComponentAlert.properties.messageType = .success digitalComponentAlert.properties.iconImage = NSImage(named: "KMNImageNameSigntureVerifySuccess") digitalComponentAlert.properties.subTitle = KMLocalizedString("Signature is valid.") } else if(.Unknown == self.type) { digitalComponentAlert.properties.messageType = .warning digitalComponentAlert.properties.iconImage = NSImage(named: "KMNImageNameSigntureTrustedFailure") if(signatures.count > 1) { digitalComponentAlert.properties.subTitle = KMLocalizedString("At least one signature is invalid.") } else { digitalComponentAlert.properties.subTitle = KMLocalizedString("Signature is invalid") } } else { digitalComponentAlert.properties.messageType = .error digitalComponentAlert.properties.iconImage = NSImage(named: "KMNImageNameSigntureVerifyFailures") if(signatures.count > 1) { digitalComponentAlert.properties.subTitle = KMLocalizedString("At least one signature is invalid.") } else { digitalComponentAlert.properties.subTitle = KMLocalizedString("Signature is invalid") } } digitalComponentAlert.reloadData() } else { if digitalComponentAlert.superview != nil { digitalComponentAlert.removeFromSuperview() } } } else { if digitalComponentAlert.superview != nil { digitalComponentAlert.removeFromSuperview() } } } public func reloadRedactAlertUI() { if isShowRedactAlert == true { var isContainsRedact = false for i in 0..<(listView?.document?.pageCount ?? 0) { guard i < listView?.document?.pageCount ?? 0 else { continue } let page = listView?.document.page(at: i) if let annotations = page?.annotations, !annotations.isEmpty { for annotation in annotations { if annotation is CPDFRedactAnnotation { isContainsRedact = true break } } } if isContainsRedact { break } } if isContainsRedact { if redactComponentAlert.superview == nil { redactComponentAlert.frame = CGRect(x: 0, y: 0, width: listView?.frame.width ?? 0, height: 32.0) redactComponentAlert.autoresizingMask = .width self.view.addSubview(redactComponentAlert) } redactComponentAlert.reloadData() } else { if redactComponentAlert.superview != nil { redactComponentAlert.removeFromSuperview() } } } else { if redactComponentAlert.superview != nil { redactComponentAlert.removeFromSuperview() } } } public func reloadOCRAlertUI() { if isShowOCRAlert == true && self.listView?.toolMode == .CEditPDFToolMode { var isContainsImagePage = false for i in 0..<(listView?.document?.pageCount ?? 0) { guard i < listView?.document?.pageCount ?? 0 else { continue } let page = listView?.document.page(at: i) if (page?.isImagePage() == true) { isContainsImagePage = true break } } if isContainsImagePage { if OCRComponentAlert.superview == nil { OCRComponentAlert.frame = CGRect(x: 0, y: 0, width: listView?.frame.width ?? 0, height: 40.0) OCRComponentAlert.autoresizingMask = .width self.view.addSubview(OCRComponentAlert) } OCRComponentAlert.reloadData() } else { if OCRComponentAlert.superview != nil { OCRComponentAlert.removeFromSuperview() } } } else { if OCRComponentAlert.superview != nil { OCRComponentAlert.removeFromSuperview() } } } public func reloadAlertUIFrame() { var alertHeight = 0.0 if digitalComponentAlert.superview != nil { digitalComponentAlert.frame = CGRect(x: 0, y: alertHeight, width: listView?.frame.width ?? 0, height: 32.0) alertHeight += 32.0 } if formComponentAlert.superview != nil { if alertHeight > 0 { alertHeight += 1 } formComponentAlert.frame = CGRect(x: 0, y: alertHeight, width: listView?.frame.width ?? 0, height: 32.0) alertHeight += 32.0 } if secureComponentAlert.superview != nil { if alertHeight > 0 { alertHeight += 1 } secureComponentAlert.frame = CGRect(x: 0, y: alertHeight, width: listView?.frame.width ?? 0, height: 32.0) alertHeight += 32.0 } if redactComponentAlert.superview != nil { if alertHeight > 0 { alertHeight += 1 } redactComponentAlert.frame = CGRect(x: 0, y: alertHeight, width: listView?.frame.width ?? 0, height: 32.0) alertHeight += 32.0 } if OCRComponentAlert.superview != nil { if alertHeight > 0 { alertHeight += 1 } OCRComponentAlert.frame = CGRect(x: 0, y: alertHeight, width: listView?.frame.width ?? 0, height: 40.0) alertHeight += 40.0 } if(alertHeight > 0) { var rect = self.view.frame rect.size.height = alertHeight rect.size.width = listView?.frame.size.width ?? 0 rect.origin.y = (listView?.frame.size.height ?? 0) - alertHeight self.view.frame = rect } else { if self.view.superview != nil { self.view.removeFromSuperview() } } } func showInView(_ listView: CPDFListView?) { self.listView = listView self.view.frame = CGRect(x: 0, y: 0, width: listView?.frame.size.width ?? 0 , height: 0) self.view.autoresizingMask = [.width, .minYMargin] listView?.addSubview(self.view) reloadSecureAlertUI() reloadFormAlertUI() reloadDigitalAlertUI() reloadRedactAlertUI() reloadFormAlertUI() reloadOCRAlertUI() } } //MARK: - ComponentAlertDelegate extension KMNAlertTipViewController: ComponentAlertDelegate { func componentAlertDidCloseButtonClick(inputView: ComponentAlert) { if inputView == formComponentAlert { isShowFormAlert = false reloadFormAlertUI() } else if inputView == secureComponentAlert { isShowSecureAlert = false reloadSecureAlertUI() } else if inputView == digitalComponentAlert { isShowDigitalAlert = false reloadDigitalAlertUI() } else if inputView == redactComponentAlert { isShowRedactAlert = false reloadRedactAlertUI() } else if inputView == OCRComponentAlert { isShowOCRAlert = false reloadOCRAlertUI() } reloadAlertUIFrame() } func componentAlertDidButtonClick(inputView: ComponentAlert, buttonIndex: Int) { if buttonIndex == 1 { if inputView == formComponentAlert { formFieldHighlightCallback?() let highlightFormFiled = CPDFKitConfig.sharedInstance().enableFormFieldHighlight() var detailButtonString = "" if highlightFormFiled { detailButtonString = KMLocalizedString("Disable Highlight Effect") } else { detailButtonString = KMLocalizedString("Highlight Form Fields") } formComponentAlert.properties.detailButtonString = detailButtonString formComponentAlert.reloadData() } else if inputView == secureComponentAlert { enterPasswordCallback?() } else if inputView == digitalComponentAlert { digitalDetailsCallback?() } else if inputView == redactComponentAlert { redactApplyCallback?() } else if inputView == OCRComponentAlert { OCRApplyCallback?() } } } }