// // PasswordWindowController.swift // PDF Reader Pro // // Created by kdanmobile on 2023/11/2. // import Cocoa typealias closePwdCallBack = (_ password: String) -> () @objc protocol PasswordWindowDelegate: AnyObject { @objc optional func didFinshedUnlockFile(_ passwordWindowCtr: PasswordWindowController, password: String) @objc optional func didCancelUnlockFile(_ passwordWindowCtr: PasswordWindowController) } @objc class PasswordWindowController: NSWindowController{ var fileURL: URL? var delegate: PasswordWindowDelegate? var tag: Int = 0 var password: String? var closeCallBack: closePwdCallBack? @IBOutlet var passwordTextField: NSSecureTextField! @IBOutlet var titleTextField: NSTextField! @IBOutlet var textField: NSTextField! @IBOutlet var openButton: NSButton! @IBOutlet var cancelButton: NSButton! override init(window: NSWindow?) { super.init(window: window) } required init?(coder: NSCoder) { super.init(coder: coder) } override func windowDidLoad() { super.windowDidLoad() self.titleTextField.stringValue = fileURL?.lastPathComponent ?? "" self.textField.stringValue = NSLocalizedString("This PDF is password protected. Please enter the password below to access this PDF.", comment: "") self.openButton.title = NSLocalizedString("Open", comment: "") self.cancelButton.title = NSLocalizedString("Cancel", comment: "") } @IBAction func cancelAction(_ sender: NSButton) { self.close() } @IBAction func OKAction(_ sender: NSButton) { guard let pdfDoc = CPDFDocument(url: self.fileURL) else { __NSBeep() return } let isOk = pdfDoc.unlock(withPassword: self.passwordTextField.stringValue) if isOk { if pdfDoc.permissionsStatus == .owner { self.password = self.passwordTextField.stringValue self.close() } else{ self.incorrectPasswordAlert() } } else { self.incorrectPasswordAlert() } } func incorrectPasswordAlert() { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Incorrect password. Please check your password and try again.", comment: "") alert.runModal() } @objc func didEndSheet(_ sheet: NSWindow, returnCode: NSInteger, contextInfo: UnsafeMutableRawPointer?) { if contextInfo != nil { let handler = contextInfo!.assumingMemoryBound(to: ((String) -> Void).self).pointee handler(password ?? "") } } func beginSheetModal(for window: NSWindow, completionHandler handler: ((String) -> Void)?) { struct Context { var handler: ((String) -> Void)? } var context = Context(handler: handler) // Pass the address of the struct as contextInfo let contextPointer = UnsafeMutableRawPointer(&context) NSApp.beginSheet(self.window!, modalFor: window, modalDelegate: self, didEnd: #selector(didEndSheet(_:returnCode:contextInfo:)), contextInfo: contextPointer) } override func close() { if (self.closeCallBack != nil) { closeCallBack!(password ?? "") } } }