// // KMBatchOperateImageToPDFViewController.swift // PDF Reader Pro // // Created by liujiajie on 2023/12/5. // import Cocoa import KMComponentLibrary class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController { @IBOutlet weak var headerBox: NSBox! @IBOutlet weak var titleLabel: NSTextField! @IBOutlet weak var headerBottomLine: ComponentDivider! @IBOutlet var outputTypeLabel: NSTextField! @IBOutlet var createNewPDFBtn: NSButton! @IBOutlet var btnMerge: NSButton! @IBOutlet var appendPDFBtn: NSButton! @IBOutlet var appendTextField: NSTextField! @IBOutlet var appendOtherPDFBtn: NSButton! @IBOutlet var appendBackView: NSView! @IBOutlet var ocrLabel: NSTextField! @IBOutlet var ocrSelectBtn: NSButton! @IBOutlet var languaeBox: NSBox! @IBOutlet var languageButton: NSButton! @IBOutlet var saveAsButton: NSButton! @IBOutlet var planButton: NSButton! @IBOutlet var selectLanguageLabel: NSTextField! @IBOutlet var planBox: NSBox! @IBOutlet var actionButton: NSButton! @IBOutlet weak var newPDFBox: NSBox! @IBOutlet weak var mergeAllBox: NSBox! @IBOutlet weak var appendBox: NSBox! @IBOutlet weak var appendBackBox: NSBox! @IBOutlet weak var ocrSelectBox: NSBox! @IBOutlet weak var languageBox: NSBox! @IBOutlet weak var ocrPlanBox: NSBox! @IBOutlet weak var ocrPlan2Box: NSBox! @IBOutlet weak var hLine: NSView! @IBOutlet weak var extractTextBox: NSBox! @IBOutlet weak var bottomBox: NSBox! @IBOutlet weak var bottomTopLine: ComponentDivider! @IBOutlet weak var applyButton: ComponentButton! var password: String = "" lazy var method: KMImageToPDFMethod = { let method = KMImageToPDFMethod() method.imageTopdfDelegate = self return method }() private var createNewPDFRadio_: ComponentRadio = { let view = ComponentRadio() view.properties = ComponentCheckBoxProperty(size: .s, state: .normal, isDisabled: false, showhelp: false, text: NSLocalizedString("New PDF Document", comment: ""), checkboxType: .normal) return view }() private lazy var mergeAllCheckBox_: ComponentCheckBox = { let view = ComponentCheckBox() view.properties = ComponentCheckBoxProperty(size: .s, state: .normal, isDisabled: false, showhelp: false, text: NSLocalizedString("Merge All", comment: ""),checkboxType: .normal) return view }() private var appendRadio_: ComponentRadio = { let view = ComponentRadio() view.properties = ComponentCheckBoxProperty(size: .s, state: .normal, isDisabled: false, showhelp: false, text: NSLocalizedString("Append To Existing File", comment: ""), checkboxType: .normal) return view }() private var appendBackInput: ComponentInputWithAddon = { let view = ComponentInputWithAddon() view.properties = ComponentInputWithAddonProperty(size: .s, isDisabled: true, addonType: .button) return view }() private lazy var ocrCheckBox_: ComponentCheckBox = { let view = ComponentCheckBox() view.properties = ComponentCheckBoxProperty(size: .s, state: .normal, isDisabled: false, showhelp: false, text: NSLocalizedString("Recognize text if needed", comment: ""), checkboxType: .normal) return view }() private lazy var languageView_: ComponentSelect = { let view = ComponentSelect() view.properties = ComponentSelectProperties(size: .s, state: .normal, isDisabled: false, isError: false, leftIcon: false, placeholder: nil, errorText: nil, creatable: false, text: KMLocalizedString("", comment: "")) // view.delegate = self return view }() private var ocrPlanRadio_: ComponentRadio = { let view = ComponentRadio() view.properties = ComponentCheckBoxProperty(size: .s, state: .normal, isDisabled: false, showhelp: true, text: KMLocalizedString("OCR Plan 1-Online", comment: ""), checkboxType: .normal) return view }() private var ocrPlanRadio2_: ComponentRadio = { let view = ComponentRadio() view.properties = ComponentCheckBoxProperty(size: .s, state: .normal, isDisabled: false, showhelp: true, text: KMLocalizedString("OCR Plan 2-Online", comment: ""), checkboxType: .normal) return view }() private var vLine_: ComponentDivider = { let view = ComponentDivider() view.properties = ComponentDividerProperty(type: .horizontal, dash: false) return view }() private lazy var extractTextCheckBox_: ComponentCheckBox = { let view = ComponentCheckBox() view.properties = ComponentCheckBoxProperty(size: .s, state: .normal, isDisabled: false, showhelp: false, text: KMLocalizedString("Extract Text (.txt)", comment: ""), checkboxType: .normal) return view }() override var interfaceStatus: KMBatchOperateInterfaceStatus?{ set{ super.interfaceStatus = newValue if newValue == .PrepareProcess { DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) { let files = NSMutableArray() for url in self.successFilePathURLArray! { if FileManager.default.fileExists(atPath: url.path) { files.add(url) } } if files.count > 0 { let workspace = NSWorkspace.shared workspace.activateFileViewerSelecting(files as! [URL]) } } self._updateActionButtonEnable(true) } else { self._updateActionButtonEnable(false) } } get{ return super.interfaceStatus } } private func _updateActionButtonEnable(_ enabled: Bool) { if enabled { self.actionButton.tag = 1 applyButton.properties.isDisabled = false applyButton.reloadData() } else { self.actionButton.tag = 0 applyButton.properties.isDisabled = true applyButton.reloadData() } } deinit { NotificationCenter.default.removeObserver(self) DistributedNotificationCenter.default().removeObserver(self) } override func viewDidLoad() { super.viewDidLoad() headerBox.borderWidth = 0 titleLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-m-bold") createNewPDFRadio_.properties.checkboxType = .selected createNewPDFRadio_.reloadData() ocrLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-medium") ocrSelectBox.borderWidth = 0 ocrSelectBox.contentView = ocrCheckBox_ ocrCheckBox_.setTarget(self, action: #selector(buttonClicked_OCRSelect)) languageView_.properties.isDisabled = true languageView_.reloadData() ocrPlanRadio_.setTarget(self, action: #selector(ocrPlanAction)) ocrPlanRadio_.properties.isDisabled = true ocrPlanRadio_.reloadData() ocrPlanRadio2_.setTarget(self, action: #selector(ocrPlanAction)) ocrPlanRadio2_.properties.isDisabled = true ocrPlanRadio2_.reloadData() extractTextCheckBox_.properties.isDisabled = true extractTextCheckBox_.reloadData() bottomBox.borderWidth = 0 applyButton.properties = ComponentButtonProperty(type: .primary, size: .m, onlyIcon: false, buttonText: KMLocalizedString("Apply")) self.localizedLanguage() self.configuUI() if let cnt = self.files?.count, cnt > 0 { self._updateActionButtonEnable(true) } else { self._updateActionButtonEnable(false) } NotificationCenter.default.addObserver(self, selector: #selector(OCRSelectedLanguagesChangeNotification(notification:)), name: NSNotification.Name("KMOCRSelectedLanguagesChangeNotification"), object: nil) NotificationCenter.default.addObserver(self, selector: #selector(OCRSelectedPlanChangeNotification(notification:)), name: NSNotification.Name("KMOCRSelectedPlanChangeNotification"), object: nil) // NotificationCenter.default.addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil) DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil) NotificationCenter.default.addObserver(self, selector: #selector(batchFilesCountNotification(notification:)), name: NSNotification.Name("KMBatchFilesCountNotification"), object: nil) } override func updateUILanguage() { super.updateUILanguage() KMMainThreadExecute { self.titleLabel.stringValue = KMLocalizedString("Image to PDF") self.ocrLabel.stringValue = KMLocalizedString("Text Recognition Settings") } } override func updateUIThemeColor() { super.updateUIThemeColor() KMMainThreadExecute { let titleColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/2") self.titleLabel.textColor = titleColor self.headerBottomLine.properties = ComponentDividerProperty() self.ocrLabel.textColor = titleColor self.bottomTopLine.properties = ComponentDividerProperty() } } func localizedLanguage() { self.outputTypeLabel.stringValue = KMLocalizedString("Output") self.btnMerge.title = KMLocalizedString("Merge All") self.createNewPDFBtn.title = KMLocalizedString("New PDF Document") self.appendPDFBtn.title = KMLocalizedString("Append To Existing File") self.appendTextField.placeholderString = KMLocalizedString("Select a File") self.selectLanguageLabel.stringValue = KMLocalizedString("Select OCR Language:") self.selectLanguageLabel.isHidden = true self.ocrSelectBtn.title = KMLocalizedString("OCR Plan") let languages = KMGOCRManager.languages() as NSArray let strings = languages.value(forKeyPath: KMGOCRLanguageStringKey) as? [String] var menuItemArr: [ComponentMenuitemProperty] = [] for language in strings ?? [] { let itemProperty: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false, itemSelected: false, isDisabled: false, keyEquivalent: nil, text: language) menuItemArr.append(itemProperty) } languageView_.updateMenuItemsArr(menuItemArr) languageView_.selectItemAtIndex(0) languageView_.properties.creatable = false languageView_.properties.text = menuItemArr.first?.text languageView_.reloadData() self.updateLanguageButton((KMGOCRManager.default().selectedLanguages?.value(forKeyPath: KMGOCRLanguageStringKey) as? [String])) self.actionButton.title = KMLocalizedString("Save as PDF") self.saveAsButton.title = KMLocalizedString("Save as TXT") self.OCRSelectedPlanChangeAction() } func configuUI() { self.view.wantsLayer = true appendOtherPDFBtn.wantsLayer = true appendBackView.wantsLayer = true appendBackView.layer?.borderWidth = 0.5 self.appendOtherPDFBtn.layer?.backgroundColor = KMAppearance.Interactive.s0Color().withAlphaComponent(0.4).cgColor createNewPDFBtn.setTitleColor(KMAppearance.Layout.h0Color()) newPDFBox.borderWidth = 0 newPDFBox.contentView = createNewPDFRadio_ createNewPDFRadio_.setTarget(self, action: #selector(buttonClicked_CreateNewPDF)) createNewPDFBtn.isHidden = true self.btnMerge.setTitleColor(KMAppearance.Layout.h0Color()) self.appendPDFBtn.setTitleColor(KMAppearance.Layout.h0Color()) appendBackBox.contentView = appendBackInput btnMerge.isHidden = true mergeAllBox.borderWidth = 0 mergeAllBox.contentView = mergeAllCheckBox_ appendPDFBtn.isHidden = true appendBox.borderWidth = 0 appendBox.contentView = appendRadio_ appendRadio_.setTarget(self, action: #selector(buttonClicked_AppendOtherPDF)) self.ocrSelectBtn.setTitleColor(KMAppearance.Layout.h0Color()) self.saveAsButton.setTitleColor(KMAppearance.Layout.h0Color()) self.selectLanguageLabel.textColor = KMAppearance.Layout.h0Color() saveAsButton.isHidden = true ocrSelectBtn.isHidden = true languageBox.borderWidth = 0 languageBox.contentView = languageView_ ocrPlanBox.borderWidth = 0 ocrPlanBox.contentView = ocrPlanRadio_ ocrPlan2Box.borderWidth = 0 ocrPlan2Box.contentView = ocrPlanRadio2_ hLine.addSubview(vLine_) vLine_.frame = hLine.bounds vLine_.autoresizingMask = [.width, .height] extractTextBox.borderWidth = 0 extractTextBox.contentView = extractTextCheckBox_ appendTextField.backgroundColor = KMAppearance.Layout.l1Color() appendTextField.wantsLayer = true appendTextField.layer?.cornerRadius = 1.0 languageButton.layer?.backgroundColor = NSColor.clear.cgColor languaeBox.borderColor = KMAppearance.Interactive.s0Color() planBox.borderColor = KMAppearance.Interactive.s0Color() languaeBox.fillColor = KMAppearance.Layout.l1Color() planBox.fillColor = KMAppearance.Layout.l1Color() languaeBox.isHidden = true self.updateViewColor() } func updateViewColor() { if KMAppearance.isDarkMode() { self.view.layer?.backgroundColor = NSColor(red: 0.055, green: 0.067, blue: 0.078, alpha: 1).cgColor appendBackView.layer?.borderColor = NSColor(red: 86/255.0, green: 88/255.0, blue: 90/255.0, alpha: 1).cgColor appendBackView.layer?.backgroundColor = NSColor(red: 57/255.0, green: 60/255.0, blue: 62/255.0, alpha: 1).cgColor } else { self.view.layer?.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1).cgColor appendBackView.layer?.borderColor = NSColor(red: 218/255.0, green: 219/255.0, blue: 222/255.0, alpha: 1).cgColor appendBackView.layer?.backgroundColor = NSColor.white.cgColor; } } func updateLanguageButton(_ languages: [String]?) { if languages?.count ?? 0 < 1 { self.languageButton.title = " " + KMLocalizedString("Auto Detection") self.languageView_.properties.text = " " + KMLocalizedString("Auto Detection") self.languageView_.reloadData() return } var languageName: String = "" if languages?.count ?? 0 > 0 { for i in 0..<(languages?.count ?? 0) { let language = languages?[i] if i == 0 { languageName = language ?? "" } else { languageName = languageName.appendingFormat(",%@", language ?? "") } } } else { languageName = "" } self.languageButton.title = " " + languageName self.languageView_.properties.text = " " + languageName self.languageView_.reloadData() } func converArrType(arr: Array, keyString: String) -> [String] { let newArr = NSMutableArray() for item in arr { newArr.add(item.filePath) } return newArr as! [String] } func isConnectionAvailable() -> Bool { // var isExistenceNetwork = true // let reach = Reachability(hostname: "www.apple.com") // let status: NetworkStatus = NetworkStatus(rawValue: (reach?.currentReachabilityStatus())!.rawValue) // switch status.rawValue { // case 0: // isExistenceNetwork = false // case 1: // isExistenceNetwork = true // case 2: // isExistenceNetwork = true // default: // break // } if Reachability.forInternetConnection().currentReachabilityStatus().rawValue == 0 { return false } return true } func beginImageToPDF() { if self.files?.count ?? 0 < 1 { return } let photoArray = converArrType(arr: self.files!, keyString: "") var path: String = "" var isMerge = false var isCreatNewPDF = false var isOCR = false if ocrCheckBox_.properties.checkboxType == .selected { isOCR = true } var isSaveAs = false if extractTextCheckBox_.properties.checkboxType == .selected { isSaveAs = true } let plan = UserDefaults.standard.integer(forKey: "KMOCRCurrentPlanKey") if isOCR && !self.isConnectionAvailable() && plan == 0 { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Connection Error", comment: "") alert.informativeText = NSLocalizedString("Please make sure your internet connection is available.", comment: "") alert.addButton(withTitle: NSLocalizedString("OK", comment: "")) if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) { alert.beginSheetModal(for: self.view.window!, completionHandler: nil) } else { alert.runModal() } return } if createNewPDFRadio_.properties.checkboxType == .selected { if (self.choosePath.count < 1) { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = String(format: NSLocalizedString("Output Folder cannot be empty.", comment: "")) alert.runModal() return } path = self.choosePath if mergeAllCheckBox_.properties.checkboxType == .selected { isMerge = true } isCreatNewPDF = true } else { let appenString = self.appendTextField.stringValue if appenString.isEmpty { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = String(format: NSLocalizedString("Select a File", comment: "")) alert.runModal() return } path = self.appendTextField.stringValue isMerge = true isCreatNewPDF = false } self.languageButton.isEnabled = false ocrPlanRadio_.properties.isDisabled = true ocrPlanRadio_.reloadData() ocrPlanRadio2_.properties.isDisabled = true ocrPlanRadio2_.reloadData() self.method.password = self.password self.interfaceStatus = .Processing self.method.saveAsTestPath = self.choosePath self.method.exportPDFFile(fileArray: photoArray, savePath: path, isOCR: isOCR, isCreatPDF: isCreatNewPDF, isMerge: isMerge, isSaveAsText: isSaveAs) { [weak self] savePath, errorArr, errorOCRArray in self?.languageButton.isEnabled = true self?.ocrPlanRadio_.properties.isDisabled = false self?.ocrPlanRadio_.reloadData() self?.ocrPlanRadio2_.properties.isDisabled = false self?.ocrPlanRadio2_.reloadData() self?.interfaceStatus = .PrepareProcess if errorArr.count > 0 { let dict: [String: Any] = ["isMerge": false, "isSuccess": false] NotificationCenter.default.post(name: NSNotification.Name(rawValue: "KMBatchOperateImageToPDFSuccessNotification"), object: self, userInfo: dict) let alert = NSAlert() alert.messageText = NSLocalizedString("Conversion Failed", comment: "") alert.addButton(withTitle: NSLocalizedString("OK", comment: "")) alert.informativeText = "\(errorArr)" alert.alertStyle = .informational alert.runModal() } else { if errorOCRArray.count > 0 { var contextString = NSLocalizedString("Some problems occurred during the last operation:", comment: "") for filePath in errorOCRArray { contextString += "\n" + (filePath as AnyObject).lastPathComponent } let alert = NSAlert() alert.messageText = NSLocalizedString("Converted Successfully", comment: "") alert.addButton(withTitle: NSLocalizedString("OK", comment: "")) alert.informativeText = contextString alert.alertStyle = .informational let response = alert.runModal() if response == .OK { self?.viewFileAtFinder(fileName: savePath) } } else { self?.viewFileAtFinder(fileName: savePath) } } } } func viewFileAtFinder(fileName: String) { let dict = ["isMerge": true, "isSuccess": true] NotificationCenter.default.post(name: Notification.Name("KMBatchOperateImageToPDFSuccessNotification"), object: self, userInfo: dict) let workspace = NSWorkspace.shared let url = URL(fileURLWithPath: fileName) workspace.activateFileViewerSelecting([url]) } // MARK: - Actions @objc func ocrPlanAction(_ sender: ComponentRadio) { for radio in [ocrPlanRadio_, ocrPlanRadio2_] { if radio.isEqual(to: sender) { radio.properties.checkboxType = .selected radio.reloadData() } else { radio.properties.checkboxType = .normal radio.reloadData() } } } //MARK: Notification @objc func OCRSelectedLanguagesChangeNotification(notification: Notification) { let selectedLanguages = notification.object/* as? [KMBatchOperateFile]*/ self.updateLanguageButton(selectedLanguages as? [String]) } @objc func OCRSelectedPlanChangeNotification(notification: Notification) { self.OCRSelectedPlanChangeAction() } @objc func themeChanged(notification: Notification) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.updateViewColor() } } func OCRSelectedPlanChangeAction() { let plan = UserDefaults.standard.integer(forKey: "KMOCRCurrentPlanKey") if plan == 0 { // self.planButton.title = " " + KMLocalizedString("Plan 1 (Online)") ocrPlanRadio_.properties.checkboxType = .selected ocrPlanRadio_.reloadData() ocrPlanRadio2_.properties.checkboxType = .normal ocrPlanRadio2_.reloadData() } else { // self.planButton.title = " " + KMLocalizedString("Plan 2 (Offline)") ocrPlanRadio_.properties.checkboxType = .normal ocrPlanRadio_.reloadData() ocrPlanRadio2_.properties.checkboxType = .selected ocrPlanRadio2_.reloadData() } KMGOCRManager.default().selectedLanguages = NSMutableArray() self.updateLanguageButton(KMGOCRManager.default().selectedLanguages?.value(forKeyPath: KMGOCRLanguageStringKey) as? [String]) } @objc func batchFilesCountNotification(notification: Notification) { let files: Array? = notification.object as? [KMBatchOperateFile] self.files? = files ?? [] let cnt = self.files?.count ?? 0 if cnt > 0 { self._updateActionButtonEnable(true) } else { self._updateActionButtonEnable(false) } } @IBAction func buttonClicked_CreateNewPDF(_ sender: ComponentRadio) { if (sender.properties.checkboxType == .selected) { mergeAllCheckBox_.properties.isDisabled = false mergeAllCheckBox_.reloadData() appendRadio_.properties.checkboxType = .normal appendRadio_.reloadData() self.appendOtherPDFBtn.isEnabled = false } } @IBAction func buttonClicked_AppendOtherPDF(_ sender: ComponentRadio) { if (sender.properties.checkboxType == .selected) { createNewPDFRadio_.properties.checkboxType = .normal createNewPDFRadio_.reloadData() mergeAllCheckBox_.properties.checkboxType = .normal mergeAllCheckBox_.properties.isDisabled = true mergeAllCheckBox_.reloadData() self.appendOtherPDFBtn.isEnabled = true } } @IBAction func buttonClicked_OCRSelect(_ sender: ComponentCheckBox) { //MARK: 判断是否付费用户 if IAPProductsManager.default().isAvailableAllFunction() == false { KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) ocrCheckBox_.properties.checkboxType = .normal ocrCheckBox_.reloadData() return } if (sender.properties.checkboxType == .selected) { languageView_.properties.isDisabled = false languageView_.reloadData() ocrPlanRadio_.properties.isDisabled = false ocrPlanRadio_.reloadData() ocrPlanRadio2_.properties.isDisabled = false ocrPlanRadio2_.reloadData() extractTextCheckBox_.properties.isDisabled = false extractTextCheckBox_.reloadData() } else { languageView_.properties.isDisabled = true languageView_.reloadData() ocrPlanRadio_.properties.isDisabled = true ocrPlanRadio_.reloadData() ocrPlanRadio2_.properties.isDisabled = true ocrPlanRadio2_.reloadData() extractTextCheckBox_.properties.isDisabled = true extractTextCheckBox_.reloadData() } } @IBAction func buttonClicked_ChooseLanguage(_ sender: NSButton) { let plan = UserDefaults.standard.integer(forKey: "KMOCRCurrentPlanKey") if plan == 0 { KMGOCRManager.default().ocrType = .google } else { KMGOCRManager.default().ocrType = .apple } let popover = NSPopover() popover.delegate = self popover.contentViewController = KMLanguageViewController(nibName: "KMLanguageViewController", bundle: Bundle.main) popover.animates = true popover.behavior = .transient popover.show(relativeTo: sender.bounds, of: sender as NSView, preferredEdge: .minX) } @IBAction func buttonClicked_ChoosePlan(_ sender: NSButton) { let popover = NSPopover() popover.delegate = self popover.contentViewController = KMPlanViewController(nibName: "KMPlanViewController", bundle: Bundle.main) popover.animates = true popover.behavior = .transient popover.show(relativeTo: sender.bounds, of: sender as NSView, preferredEdge: .minX) } @IBAction func buttonClicked_ImageToPDF(_ sender: NSButton) { //MARK: 判断是否付费用户,展示iap界面 if self.files?.count ?? 0 < 1 { return } if IAPProductsManager.default().isAvailableAllFunction() == false && self.files?.count ?? 0 > 1{ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } if sender.tag == 1 { self.choosePath = "" var hasTask = false for i in 0..<(self.files?.count ?? 0) { let file = self.files?[i] file?.currentOperateInfo?.resetState() if file?.fileType == .Image { hasTask = true } } if !hasTask { NSSound.beep() return } var isOCR = false if ocrCheckBox_.properties.checkboxType == .selected { isOCR = true } var isSaveAs = false if extractTextCheckBox_.properties.checkboxType == .selected { isSaveAs = true } let plan = UserDefaults.standard.integer(forKey: "KMOCRCurrentPlanKey") if isOCR && !isConnectionAvailable() && plan == 0 { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Connection Error", comment: "") alert.informativeText = NSLocalizedString("Please make sure your internet connection is available.", comment: "") alert.addButton(withTitle: NSLocalizedString("OK", comment: "")) if let window = self.view.window { alert.beginSheetModal(for: window, completionHandler: nil) } else { alert.runModal() } return } if createNewPDFRadio_.properties.checkboxType != .selected { let appenString = self.appendTextField.stringValue if appenString.isEmpty { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Select a File", comment: "") alert.runModal() return } } let openPanel = NSOpenPanel() openPanel.canChooseFiles = false openPanel.canChooseDirectories = true openPanel.canCreateDirectories = true openPanel.beginSheetModal(for: self.view.window!) { (result) in if result == .OK { for fileURL in openPanel.urls { self.choosePath = fileURL.path self.beginImageToPDF() } } } } else { // Do something else } } } @IBAction func buttonItemClicked_AppendOtherPDF(_ sender: NSButton) { let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf"] openPanel.canChooseDirectories = false openPanel.allowsMultipleSelection = false openPanel.beginSheetModal(for: self.view.window!) { (result) in if result == .OK { guard let url = openPanel.url else { return } guard let document = PDFDocument(url: url) else { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "") alert.runModal() return } if !document.allowsCopying || !document.allowsPrinting { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "") alert.runModal() return } if document.isLocked { KMBaseWindowController.checkPassword(url: url, type: .owner) { [weak self] success, resultPassword in if success { self?.password = resultPassword self?.appendTextField.stringValue = url.path } } } else { self.appendTextField.stringValue = url.path } } } } @IBAction func buttonClicked_Help(_ sender: NSButton) { let helpController = NSViewController() let textView = NSTextView(frame: NSRect(x: 0, y: 0, width: 300.0, height: 100.0)) textView.backgroundColor = NSColor.clear textView.isEditable = false textView.layer?.cornerRadius = 6 let tStrAuto = NSLocalizedString("Choose automatic language detection for better OCR results.", comment: "") let tStrVPN = NSLocalizedString("The OCR service works via an internet connection. We would suggest you to perform OCR using a VPN connection while the service is limited.", comment: "") let plan = UserDefaults.standard.integer(forKey: "KMOCRCurrentPlanKey") if plan == 0 { textView.string = "\(tStrAuto)\n\n\(tStrVPN)" } else { textView.frame = NSRect(x: 0, y: 0, width: 300.0, height: 40.0) textView.string = tStrAuto } helpController.view = textView let popover = NSPopover() popover.delegate = self popover.contentViewController = helpController popover.animates = true popover.behavior = .transient popover.show(relativeTo: sender.bounds, of: sender as NSView, preferredEdge: .minY) } //MARK: KMImageToPDFMethodDelegate func imageToPDFMethod(_ method: KMImageToPDFMethod, progress: Float) { } } // MAKR: - NSPopoverDelegate extension KMBatchOperateImageToPDFViewController: NSPopoverDelegate { } // MARK: - KMImageToPDFMethodDelegate extension KMBatchOperateImageToPDFViewController: KMImageToPDFMethodDelegate { }