// // KMPasswordInputWindowController.swift // PDF Reader Pro // // Created by Niehaoyu on 2024/12/31. // import Cocoa import KMComponentLibrary class KMPasswordInputWindowController: NSWindowController { @IBOutlet weak var titleLabel: NSTextField! @IBOutlet weak var despLabel: NSTextField! @IBOutlet var passwordInputView: ComponentPasswordView! @IBOutlet var passwordErrorLabel: NSTextField! @IBOutlet var cancelButton: ComponentButton! @IBOutlet var confirmButton: ComponentButton! static var permissionsStatus: CPDFDocumentPermissions = .none var confirmButtonVC: KMDesignButton? var documentURL: URL? var itemClick: KMPasswordInputWindowItemClick? var canEncrpty = false var type: KMPasswordInputWindowType = .open { didSet { var fileName = KMLocalizedString("") if (self.documentURL != nil) { fileName.append("\(self.documentURL!.lastPathComponent)") } titleLabel?.stringValue = KMLocalizedString("Permission Password") despLabel?.maximumNumberOfLines = 3 despLabel?.lineBreakMode = .byTruncatingTail despLabel?.cell?.truncatesLastVisibleLine = true let ps = NSMutableParagraphStyle() ps.lineSpacing = 5 let despLabelString = "\"\(fileName)\"\(KMLocalizedString("This PDF is password protected. Please enter the password below to access this PDF."))" despLabel?.attributedStringValue = NSAttributedString(string: despLabelString, attributes: [.foregroundColor : ComponentLibrary.shared.getComponentColorFromKey("colorText/1"), .font : ComponentLibrary.shared.getFontFromKey("mac/body-m-bold"), .paragraphStyle : ps]) } } override func windowDidLoad() { super.windowDidLoad() // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. titleLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorPicture/empty-textDefault") titleLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-m-medium") despLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorPicture/empty-textSecondary") despLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-regular") despLabel.isSelectable = false passwordInputView.properties = ComponentPasswordProperty(size: .m, state: .normal, isError: false, placeholderString: "Please enter password", text: "", isDisabled: false, errorText: "Here is the error message description.") passwordInputView.delegate = self passwordErrorLabel.stringValue = KMLocalizedString("Incorrect password. Please try again.") passwordErrorLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-xs-regular") passwordErrorLabel.wantsLayer = true passwordErrorLabel.isHidden = true cancelButton.properties = ComponentButtonProperty(type: .default_tertiary, size: .s, buttonText: KMLocalizedString("Cancel"), keepPressState: false) cancelButton.setTarget(self, action: #selector(cancelButtonAction(_:))) confirmButton.properties = ComponentButtonProperty(type: .primary, size: .s, buttonText: KMLocalizedString("Unlock"), keepPressState: false) confirmButton.setTarget(self, action: #selector(confirmButtonAction(_:))) dealConfirmButtonEnabledState(enabled: true) } // MARK: - Actions @objc func cancelButtonAction(_ sender: NSView) { // guard let callback = self.itemClick else { // return // } // // callback(self, 1, "") } @objc func confirmButtonAction(_ sender: NSView) { if (!self.canEncrpty) { return } guard let documentURL = self.documentURL else { return } if (self.type == .open) { let document: CPDFDocument = CPDFDocument(url: documentURL) if document.permissionsStatus == .none { let reuslt = document.unlock(withPassword: passwordInputView.properties.text) /// CPDFDocumentPermissionsNone 解锁失败 /// CPDFDocumentPermissionsUser 输入的开启密码 /// CPDFDocumentPermissionsOwner 输入的权限密码 KMPasswordInputWindow.permissionsStatus = document.permissionsStatus if document.permissionsStatus != CPDFDocumentPermissions.none { /// 密码正确 // guard let callback = self.itemClick else { // return // } // // callback(self ,2, passwordInputView.properties.text) } else { /// 密码错误 passwordErrorLabel.isHidden = false passwordErrorLabel.stringValue = KMLocalizedString("Incorrect password. Please try again.") } } return } /// 权限密码类型 let document: CPDFDocument = CPDFDocument(url: documentURL) if (document.isLocked) { if document.permissionsStatus == CPDFDocumentPermissions.none { let reuslt = document.unlock(withPassword: passwordInputView.properties.text) KMPasswordInputWindow.permissionsStatus = document.permissionsStatus if document.permissionsStatus == .owner { /// 密码正确 // guard let callback = self.itemClick else { // return // } // // callback(self, 2, passwordInputView.properties.text) } else { /// 密码错误 passwordErrorLabel.isHidden = false passwordErrorLabel.stringValue = KMLocalizedString("Incorrect password. Please try again.") } } } else { if document.permissionsStatus == CPDFDocumentPermissions.user { document.unlock(withPassword: passwordInputView.properties.text) KMPasswordInputWindow.permissionsStatus = document.permissionsStatus if document.permissionsStatus == .owner { /// 密码正确 // guard let callback = self.itemClick else { // return // } // // callback(self, 2, passwordInputView.properties.text) } else { /// 密码错误 passwordErrorLabel.isHidden = false passwordErrorLabel.stringValue = KMLocalizedString("Incorrect password. Please try again.") } } } } func dealConfirmButtonEnabledState(enabled: Bool) { canEncrpty = enabled confirmButton.properties.isDisabled = enabled ? false : true confirmButton.reloadData() } func updatePasswordState() { passwordErrorLabel.isHidden = true if passwordInputView.properties.text.isEmpty { dealConfirmButtonEnabledState(enabled: false) } else { dealConfirmButtonEnabledState(enabled: true) } } override func mouseUp(with event: NSEvent) { super.mouseUp(with: event) self.window?.makeFirstResponder(nil) passwordErrorLabel.isHidden = true } } extension KMPasswordInputWindowController { @objc class func openWindow(window: NSWindow, type: KMPasswordInputWindowType = .open, url: URL, callback: @escaping (KMPasswordInputWindowResult, String?)->Void) -> KMPasswordInputWindowController { let passwordWindow = KMPasswordInputWindowController.init(windowNibName: "KMPasswordInputWindowController") passwordWindow.documentURL = url passwordWindow.type = type passwordWindow.itemClick = { pwdWin, index, string in if let sheetParent = pwdWin.sheetParent { sheetParent.endSheet(pwdWin) } if index == 1 { /// 关闭 callback(.cancel, "") return } /// 解密成功 callback(.success, string) } window.beginSheet(passwordWindow.window!) return passwordWindow } } extension KMPasswordInputWindowController: ComponentPasswordViewDelegate { func componentPasswordViewDidChanged(inputView: ComponentPasswordView) { self.updatePasswordState() } func componentPasswordViewDidEndEditing(inputView: ComponentPasswordView) { self.updatePasswordState() } }