123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551 |
- //
- // KMBatchOperateImageToPDFViewController.swift
- // PDF Reader Pro
- //
- // Created by liujiajie on 2023/12/5.
- //
- import Cocoa
- class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController, KMImageToPDFMethodDelegate, NSPopoverDelegate{
-
- @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!
-
- var password: String = ""
-
- lazy var method: KMImageToPDFMethod = {
- let method = KMImageToPDFMethod()
- method.imageTopdfDelegate = self
- return method
- }()
-
- 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.actionButton.tag = 1
- self.actionButton.title = NSLocalizedString("Save as PDF", comment: "")
- self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
- self.actionButton.isEnabled = true
- self.actionButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
- } else {
- self.actionButton.tag = 0
- self.actionButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
- self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
- self.actionButton.isEnabled = false
- }
- }
- get{
- return super.interfaceStatus
- }
- }
-
- deinit {
- NotificationCenter.default.removeObserver(self)
- DistributedNotificationCenter.default().removeObserver(self)
- }
-
- override func viewDidLoad() {
- super.viewDidLoad()
- self.localizedLanguage()
- self.configuUI()
-
- 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)
- }
- func localizedLanguage() {
- self.outputTypeLabel.stringValue = KMLocalizedString("Output",nil)
- self.btnMerge.title = KMLocalizedString("Merge All", nil)
- self.createNewPDFBtn.title = KMLocalizedString("New PDF Document", nil)
- self.appendPDFBtn.title = KMLocalizedString("Append To Existing File", nil)
- self.appendTextField.placeholderString = KMLocalizedString("Select a File", nil)
- self.selectLanguageLabel.stringValue = KMLocalizedString("Select OCR Language:",nil)
- self.ocrSelectBtn.title = KMLocalizedString("OCR Plan",nil)
- self.updateLanguageButton((KMGOCRManager.default().selectedLanguages?.value(forKeyPath: KMGOCRLanguageStringKey) as? [String]))
-
- self.actionButton.title = KMLocalizedString("Save as PDF", nil)
- self.saveAsButton.title = KMLocalizedString("Save as TXT", nil)
- self.OCRSelectedPlanChangeAction()
- }
- func configuUI() {
- self.view.wantsLayer = true
-
- appendOtherPDFBtn.wantsLayer = true
- appendBackView.wantsLayer = true
- appendBackView.layer?.borderWidth = 0.5
-
- self.actionButton.wantsLayer = true
- self.actionButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
- self.appendOtherPDFBtn.layer?.backgroundColor = KMAppearance.Interactive.s0Color().withAlphaComponent(0.4).cgColor
- self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
- self.actionButton.layer?.cornerRadius = 1.0
-
- self.createNewPDFBtn.setTitleColor(KMAppearance.Layout.h0Color())
- self.btnMerge.setTitleColor(KMAppearance.Layout.h0Color())
- self.appendPDFBtn.setTitleColor(KMAppearance.Layout.h0Color())
-
- self.ocrSelectBtn.setTitleColor(KMAppearance.Layout.h0Color())
- self.saveAsButton.setTitleColor(KMAppearance.Layout.h0Color())
- self.selectLanguageLabel.textColor = KMAppearance.Layout.h0Color()
- self.languageButton.isEnabled = false
- self.planButton.isEnabled = false
- self.saveAsButton.isEnabled = false
-
- appendTextField.backgroundColor = KMAppearance.Layout.l1Color()
- planButton.wantsLayer = true
- appendTextField.wantsLayer = true
- planButton.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()
-
- 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", nil)
- 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
- }
- func converArrType(arr: Array<KMBatchOperateFile>, 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 self.ocrSelectBtn.state == .on {
- isOCR = true
- }
-
- var isSaveAs = false
- if self.saveAsButton.state == .on {
- 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 self.createNewPDFBtn.state == .on {
- 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 self.btnMerge.state == .on {
- 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
- self.planButton.isEnabled = false
- self.method.password = self.password
- self.interfaceStatus = .Processing
-
- 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?.planButton.isEnabled = true
- 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: 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)", nil)
- } else {
- self.planButton.title = " " + KMLocalizedString("Plan 2 (Offline)", nil)
- }
- 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 ?? []
- // if files?.count ?? 0 > 0 {
- // haveFiles = true
- // } else {
- // haveFiles = false
- // }
- }
-
- @IBAction func buttonClicked_CreateNewPDF(_ sender: NSButton) {
- if (sender.state == .on) {
- self.btnMerge.isEnabled = true
- self.appendPDFBtn.state = .off
- self.appendOtherPDFBtn.isEnabled = false
- }
- }
-
- @IBAction func buttonClicked_AppendOtherPDF(_ sender: NSButton) {
- if (sender.state == .on) {
- self.createNewPDFBtn.state = .off
- self.btnMerge.isEnabled = false
- self.appendOtherPDFBtn.isEnabled = true
- }
- }
-
- @IBAction func buttonClicked_OCRSelect(_ sender: NSButton) {
- //MARK: 判断是否付费用户
- if IAPProductsManager.default().isAvailableAllFunction() == false {
- KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
- self.ocrSelectBtn.state = .off
- return
- }
- if (sender.state == .on) {
- self.languageButton.isEnabled = true
- self.planButton.isEnabled = true
- self.saveAsButton.isEnabled = true
- } else {
- self.languageButton.isEnabled = false
- self.planButton.isEnabled = false
- self.saveAsButton.isEnabled = false
- }
- }
-
- @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 self.ocrSelectBtn.state == .on {
- isOCR = true
- }
-
- var isSaveAs = false
- if self.saveAsButton.state == .on {
- 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 self.createNewPDFBtn.state == .off {
- 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) { [unowned self] success, resultPassword in
- if success {
- self.password = password
- 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) {
-
- }
- }
|