|
@@ -0,0 +1,867 @@
|
|
|
+//
|
|
|
+// KMOCRPDFWindowController.swift
|
|
|
+// PDF Master
|
|
|
+//
|
|
|
+// Created by liujiajie on 2023/11/14.
|
|
|
+//
|
|
|
+
|
|
|
+import Cocoa
|
|
|
+import PDFKit
|
|
|
+
|
|
|
+class KMOCRPDFWindowController: NSWindowController, NSWindowDelegate, KMGOCRManagerDelegate, NSPopoverDelegate,NSTextFieldDelegate{
|
|
|
+ var resultString: String = ""
|
|
|
+ var ocrDictionary: NSMutableDictionary?
|
|
|
+ var currentIndexPage: Int = 0{
|
|
|
+ didSet {
|
|
|
+ if PDFView.document.pageCount > currentIndexPage {
|
|
|
+ currentIndexPage = 0
|
|
|
+ self.currentPageLabel.stringValue = "\(currentIndexPage + 1)"
|
|
|
+ // let page = self.PDFView.document.page(at: UInt(currentIndexPage))
|
|
|
+ self.PDFView.go(toPageIndex: currentIndexPage, animated: true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var PDFView: CPDFView!
|
|
|
+
|
|
|
+ @IBOutlet var prePdfBGView: NSView!
|
|
|
+ @IBOutlet var currentPageLabel: NSTextField!
|
|
|
+ @IBOutlet var totalPageLabel: NSTextField!
|
|
|
+
|
|
|
+ @IBOutlet var pageLabel: NSTextField!
|
|
|
+ @IBOutlet var planLabel: NSTextField!
|
|
|
+
|
|
|
+ @IBOutlet var ocrCopyButton: NSButton!
|
|
|
+
|
|
|
+ @IBOutlet var pageRangeBox: NSComboBox!
|
|
|
+ @IBOutlet var planComboBox: NSPopUpButton!
|
|
|
+
|
|
|
+ //@IBOutlet var NSProgressIndicator *progressIndicator;
|
|
|
+ @IBOutlet var progressControl: NSProgressIndicator!
|
|
|
+ @IBOutlet var failedBox: NSBox!
|
|
|
+ @IBOutlet var failedLabel: NSTextField!
|
|
|
+
|
|
|
+ @IBOutlet var cancelButton: NSButton!
|
|
|
+ @IBOutlet var startButton: NSButton!
|
|
|
+
|
|
|
+ @IBOutlet var languageLabel: NSTextField!
|
|
|
+ @IBOutlet var ocrResultLabel: NSTextField!
|
|
|
+
|
|
|
+ @IBOutlet var languageButton: NSButton!
|
|
|
+ @IBOutlet var txtTextView: NSTextView!
|
|
|
+
|
|
|
+ @IBOutlet var deleteButton: NSButton!
|
|
|
+
|
|
|
+ @IBOutlet var emptyBox: NSBox!
|
|
|
+
|
|
|
+ @IBOutlet var emptyLabel: NSTextField!
|
|
|
+
|
|
|
+ var errorOCRArrays: Array<Any>?
|
|
|
+
|
|
|
+ var pageIndexs: Array<Any>?
|
|
|
+
|
|
|
+ var password: String = ""
|
|
|
+ var pathFile: String = ""
|
|
|
+
|
|
|
+ var pdfDocument: CPDFDocument?
|
|
|
+
|
|
|
+ @IBOutlet var saveButton: NSButton!
|
|
|
+ @IBOutlet var box1: NSBox!
|
|
|
+ @IBOutlet var boxLabel1: NSTextField!
|
|
|
+ @IBOutlet var previewLabel: NSTextField!
|
|
|
+ @IBOutlet var savePDFButton: NSButton!
|
|
|
+
|
|
|
+ var ocrCurrentIndex: Int = 0
|
|
|
+ var appleOCRManger: KMGOCRManager?
|
|
|
+ var googleOCRManger: KMGOCRManager?
|
|
|
+
|
|
|
+ var savedFileName: String = ""
|
|
|
+
|
|
|
+ func getOCRResrultsFolderPath() -> String {
|
|
|
+ var path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last
|
|
|
+ path?.append("/")
|
|
|
+ path?.append(Bundle.main.bundleIdentifier!)
|
|
|
+ if (FileManager.default.fileExists(atPath: path!) == false) {
|
|
|
+ try?FileManager.default.createDirectory(atPath: path!, withIntermediateDirectories: false)
|
|
|
+ }
|
|
|
+
|
|
|
+ path?.append("/")
|
|
|
+ path?.append("OCR_Resrults")
|
|
|
+
|
|
|
+ return path!
|
|
|
+ }
|
|
|
+
|
|
|
+ convenience init(cpdfDocument: CPDFDocument, pwd: String) {
|
|
|
+ self.init(windowNibName: "KMOCRPDFWindowController")
|
|
|
+ self.pdfDocument = cpdfDocument
|
|
|
+ self.password = pwd
|
|
|
+ if let lastPathComponent = cpdfDocument.documentURL?.lastPathComponent {
|
|
|
+ let str = lastPathComponent.deletingPathExtension
|
|
|
+ if str.count > 0 {
|
|
|
+ self.pathFile = str
|
|
|
+ }else {
|
|
|
+ self.pathFile = NSLocalizedString("Untitled", comment: "")
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ self.pathFile = NSLocalizedString("Untitled", comment: "")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ convenience init(filePath: String, pwd: String) {
|
|
|
+ self.init(windowNibName: "KMOCRPDFWindowController")
|
|
|
+ self.password = pwd
|
|
|
+ let pathExtension = filePath.lastPathComponent.customPathExtension
|
|
|
+ if pathExtension.count > 0{
|
|
|
+ if pathExtension.lowercased() == "pdf" {
|
|
|
+ pdfDocument = CPDFDocument(url: URL(fileURLWithPath: filePath))
|
|
|
+ } else {
|
|
|
+ if let image = NSImage(contentsOf: URL(fileURLWithPath: filePath)) {
|
|
|
+ self.pdfDocument = CPDFDocument()
|
|
|
+ _ = pdfDocument?.km_insertPage(image.size, withImage: filePath, at: pdfDocument?.pageCount ?? 0)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ self.pathFile = filePath.lastPathComponent.deletingPathExtension
|
|
|
+ }
|
|
|
+ deinit {
|
|
|
+ NotificationCenter.default.removeObserver(self)
|
|
|
+ KMGOCRManager.default().delegate = nil
|
|
|
+ appleOCRManger?.cancelRecognition()
|
|
|
+ appleOCRManger?.delegate = nil
|
|
|
+ googleOCRManger?.cancelRecognition()
|
|
|
+ googleOCRManger?.delegate = nil
|
|
|
+ }
|
|
|
+ override func windowDidLoad() {
|
|
|
+ super.windowDidLoad()
|
|
|
+ self.pageLabel.stringValue = NSLocalizedString("Page Range", comment: "")
|
|
|
+ self.planLabel.stringValue = NSLocalizedString("OCR Plan", comment: "")
|
|
|
+
|
|
|
+ self.planComboBox.removeAllItems()
|
|
|
+ self.planComboBox.addItems(withTitles: [NSLocalizedString("Plan 1 (Online)", comment: ""), NSLocalizedString("Plan 2 (Offline)", comment: "")])
|
|
|
+ let plan = UserDefaults.standard.integer(forKey: "KMOCRCurrentPlanKey")
|
|
|
+ if plan == 0 {
|
|
|
+ KMGOCRManager.default().ocrType = .google
|
|
|
+ self.planComboBox.selectItem(at: 0)
|
|
|
+ } else {
|
|
|
+ KMGOCRManager.default().ocrType = .apple
|
|
|
+ self.planComboBox.selectItem(at: 1)
|
|
|
+ }
|
|
|
+ self.pageRangeBox.addItems(withObjectValues: [NSLocalizedString("All Pages", comment: ""), NSLocalizedString("Current Page", comment: ""), NSLocalizedString("Odd Pages Only", comment: ""), NSLocalizedString("Even Pages Only", comment: ""), NSLocalizedString("e.g. 1,3-5,10", comment: "")])
|
|
|
+ self.pageRangeBox.placeholderString = NSLocalizedString("e.g. 1,3-5,10", comment: "")
|
|
|
+
|
|
|
+ self.pageRangeBox.selectItem(at: 0)
|
|
|
+ self.pageRangeBox.isEditable = false
|
|
|
+ if self.pageRangeBox.indexOfSelectedItem == 4 {
|
|
|
+ self.window?.makeFirstResponder(self.pageRangeBox)
|
|
|
+ self.pageRangeBox.stringValue = ""
|
|
|
+ self.pageRangeBox.isEditable = true
|
|
|
+ }
|
|
|
+ self.emptyLabel.stringValue = NSLocalizedString("Recognize text from Image-based or Scanned PDF with OCR", comment: "")
|
|
|
+ self.failedLabel.stringValue = NSLocalizedString("OCR failed. Please try to change the OCR Plan to \"Plan 2 (Offline)\"", comment: "")
|
|
|
+ self.txtTextView.textColor = NSColor.textColor
|
|
|
+ self.txtTextView.enclosingScrollView?.autohidesScrollers = true
|
|
|
+ self.ocrResultLabel.stringValue = NSLocalizedString("OCR Results", comment: "")
|
|
|
+ self.ocrCopyButton?.toolTip = KMLocalizedString("Copy and edit text from documents with OCR.", nil)
|
|
|
+ self.deleteButton?.toolTip = NSLocalizedString("Delete", comment: "")
|
|
|
+ self.deleteButton?.title = NSLocalizedString("Delete", comment: "")
|
|
|
+ self.ocrCopyButton?.title = NSLocalizedString("Copy", comment: "")
|
|
|
+ self.errorOCRArrays = []
|
|
|
+ self.pageIndexs = []
|
|
|
+ self.ocrCopyButton.isEnabled = false
|
|
|
+ self.deleteButton.isEnabled = false
|
|
|
+ self.saveButton.isEnabled = false
|
|
|
+ self.savePDFButton.isEnabled = false
|
|
|
+ self.boxLabel1.stringValue = NSLocalizedString("Settings", comment: "")
|
|
|
+ self.previewLabel.stringValue = NSLocalizedString("Preview", comment: "")
|
|
|
+
|
|
|
+ self.saveButton.title = NSLocalizedString("Save as TXT", comment: "")
|
|
|
+ self.savePDFButton.title = NSLocalizedString("Save as PDF", comment: "")
|
|
|
+ self.saveButton.toolTip = NSLocalizedString("Export as a searchable PDF or text file.", comment: "")
|
|
|
+ self.savePDFButton.toolTip = NSLocalizedString("Export as a searchable PDF or text file.", comment: "")
|
|
|
+
|
|
|
+ self.cancelButton.title = NSLocalizedString("Cancel", comment: "")
|
|
|
+ self.startButton.title = NSLocalizedString("OCR", comment: "")
|
|
|
+ self.languageLabel.stringValue = NSLocalizedString("Select OCR Language:", comment: "")
|
|
|
+
|
|
|
+ self.updateLanguageButton(KMGOCRManager.default().selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey) as! [String])
|
|
|
+
|
|
|
+ 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)
|
|
|
+
|
|
|
+ self.progressControl.isHidden = true
|
|
|
+ emptyBox.isHidden = false
|
|
|
+ failedBox.isHidden = true
|
|
|
+
|
|
|
+ self.PDFView.document = self.pdfDocument
|
|
|
+ self.PDFView.autoScales = true
|
|
|
+ self.reloadPDFData()
|
|
|
+ if !(self.pdfDocument?.isLocked ?? false) && ((self.pdfDocument?.unlock(withPassword: self.password)) != nil) {
|
|
|
+
|
|
|
+ } else {
|
|
|
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
|
|
+
|
|
|
+ let com = PasswordWindowController(windowNibName: "PasswordWindowController")
|
|
|
+ com.fileURL = self.pdfDocument?.documentURL
|
|
|
+ NSWindow.currentWindow().km_beginSheet(windowC: com)
|
|
|
+ com.closeCallBack = { passwordString in
|
|
|
+ if passwordString.count > 0 {
|
|
|
+ self.pdfDocument?.unlock(withPassword: passwordString)
|
|
|
+ self.password = passwordString
|
|
|
+ self.reloadPDFData()
|
|
|
+ } else {
|
|
|
+ self.close()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ NotificationCenter.default.addObserver(self, selector: #selector(PDFViewDocumentChangedNotification(notification:)), name: NSNotification.Name.PDFViewPageChanged, object: nil)
|
|
|
+ }
|
|
|
+
|
|
|
+ func windowShouldClose(_ sender: NSWindow) -> Bool {
|
|
|
+ close()
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ override func close() {
|
|
|
+ if ((self.window?.isSheet) != nil) {
|
|
|
+ self.km_endSheet()
|
|
|
+ } else {
|
|
|
+ super.close()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func reloadPDFData() { // 隐藏PDFView滑动条
|
|
|
+ self.PDFView.documentView().enclosingScrollView?.hasVerticalScroller = false
|
|
|
+ self.PDFView.documentView().enclosingScrollView?.hasHorizontalScroller = false
|
|
|
+ let pageCount: Int = Int(self.pdfDocument?.pageCount ?? 0)
|
|
|
+ let currentPageIndex = self.pdfDocument?.index(for: self.PDFView.currentPage())
|
|
|
+ self.currentPageLabel.stringValue = "\((currentPageIndex ?? 0) + 1)"
|
|
|
+ self.totalPageLabel.stringValue = "/ \(pageCount)"
|
|
|
+ }
|
|
|
+ //MARK: KMOCRSelectedLanguagesChangeNotification
|
|
|
+ @objc func OCRSelectedLanguagesChangeNotification(notification: NSNotification) {
|
|
|
+ if let selectedLanguages = notification.object as? [String] {
|
|
|
+ updateLanguageButton(selectedLanguages)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func OCRSelectedPlanChangeNotification(notification: NSNotification) {
|
|
|
+ let plan = UserDefaults.standard.integer(forKey: "KMOCRCurrentPlanKey")
|
|
|
+ if plan == 0 {
|
|
|
+ self.planComboBox.selectItem(at: 0)
|
|
|
+ } else {
|
|
|
+ self.planComboBox.selectItem(at: 1)
|
|
|
+ }
|
|
|
+ KMGOCRManager.default().selectedLanguages = NSMutableArray()
|
|
|
+ updateLanguageButton(KMGOCRManager.default().selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey) as! [String])
|
|
|
+ }
|
|
|
+ @objc func PDFViewDocumentChangedNotification(notification: NSNotification) {
|
|
|
+ let page: CPDFPage = self.PDFView.currentPage()
|
|
|
+ let pageIndex = self.PDFView.document.index(for: page)
|
|
|
+ self.currentPageLabel.stringValue = "\(pageIndex + 1)"
|
|
|
+ }
|
|
|
+
|
|
|
+ func updateLanguageButton(_ languages: [String]) {
|
|
|
+ if languages.count < 1 {
|
|
|
+ self.languageButton.title = NSLocalizedString("Auto Detection", comment: "")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var languageName: String? = nil
|
|
|
+ if languages.count > 0 {
|
|
|
+ for i in 0..<languages.count {
|
|
|
+ let language = languages[i]
|
|
|
+ if i == 0 {
|
|
|
+ languageName = language
|
|
|
+ } else {
|
|
|
+ languageName = languageName?.appendingFormat(",%@", language)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ languageName = ""
|
|
|
+ }
|
|
|
+
|
|
|
+ self.languageButton.title = languageName ?? ""
|
|
|
+ }
|
|
|
+ func imageRep(withSize size: NSSize, scale: CGFloat, drawingHandler: (NSRect) -> Void) -> Any? {
|
|
|
+ let bmpImageRep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(size.width * scale), pixelsHigh: Int(size.height * scale), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: .calibratedRGB, bitmapFormat: .alphaFirst, bytesPerRow: 0, bitsPerPixel: 0)
|
|
|
+ // bmpImageRep?.bitmapImageRepByRetaggingWithColorSpace = .sRGB
|
|
|
+ bmpImageRep?.size = size
|
|
|
+ NSGraphicsContext.saveGraphicsState()
|
|
|
+ NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: bmpImageRep!)
|
|
|
+ // drawingHandler(.zero, size)
|
|
|
+ drawingHandler(NSRect(origin: NSZeroPoint, size: size))
|
|
|
+ NSGraphicsContext.restoreGraphicsState()
|
|
|
+ return bmpImageRep
|
|
|
+ }
|
|
|
+ func bitmapImage(withSize size: NSSize, drawingHandler: (NSRect) -> Void) -> NSImage? {
|
|
|
+ let image = NSImage(size: size)
|
|
|
+ let scale = KMImageScale
|
|
|
+ image.addRepresentation(imageRep(withSize: size, scale: scale, drawingHandler: drawingHandler) as! NSBitmapImageRep)
|
|
|
+ return image
|
|
|
+ }
|
|
|
+ func thumbnail(with page: CPDFPage) -> NSImage? {
|
|
|
+ let bounds = page.bounds(for: .cropBox)
|
|
|
+ var pageSize = bounds.size
|
|
|
+ var scale: CGFloat = 1.0
|
|
|
+ var thumbnailSize: NSSize
|
|
|
+ var pageRect = NSZeroRect
|
|
|
+ var image: NSImage?
|
|
|
+ let aSize = pageSize.width
|
|
|
+ if page.rotation % 180 == 90 {
|
|
|
+ pageSize = NSSize(width: pageSize.height, height: pageSize.width)
|
|
|
+ }
|
|
|
+
|
|
|
+ if aSize > 0.0 {
|
|
|
+ if pageSize.height > pageSize.width {
|
|
|
+ thumbnailSize = NSSize(width: round(aSize * pageSize.width / pageSize.height), height: aSize)
|
|
|
+ } else {
|
|
|
+ thumbnailSize = NSSize(width: aSize, height: round(aSize * pageSize.height / pageSize.width))
|
|
|
+ }
|
|
|
+ let kKMMaxPixelsLimit = 75000000
|
|
|
+ let totalPixelNumber = Int((thumbnailSize.width * KMImageScale) * (thumbnailSize.height * KMImageScale))
|
|
|
+ if totalPixelNumber >= kKMMaxPixelsLimit {
|
|
|
+ let sizeScale = sqrt(Float(kKMMaxPixelsLimit - 1000) / Float(totalPixelNumber))
|
|
|
+ thumbnailSize = NSSize(width: floor(thumbnailSize.width * CGFloat(sizeScale)), height: floor(thumbnailSize.height * CGFloat(sizeScale)))
|
|
|
+ }
|
|
|
+ scale = max(thumbnailSize.width / pageSize.width, (thumbnailSize.height) / pageSize.height)
|
|
|
+ } else {
|
|
|
+ thumbnailSize = NSSize(width: pageSize.width, height: pageSize.height)
|
|
|
+ }
|
|
|
+
|
|
|
+ if thumbnailSize.width.isNaN || thumbnailSize.height.isNaN || thumbnailSize.width == 0.0 || thumbnailSize.height == 0.0 {
|
|
|
+ thumbnailSize = NSSize(width: 186.0, height: 256.0)
|
|
|
+ }
|
|
|
+
|
|
|
+ pageRect.size = thumbnailSize
|
|
|
+
|
|
|
+ image = bitmapImage(withSize: thumbnailSize) { rect in
|
|
|
+ NSGraphicsContext.current?.imageInterpolation = .high
|
|
|
+
|
|
|
+ NSGraphicsContext.saveGraphicsState()
|
|
|
+ NSColor.white.setFill()
|
|
|
+ pageRect.fill()
|
|
|
+ NSGraphicsContext.restoreGraphicsState()
|
|
|
+
|
|
|
+ if abs(scale - 1.0) > 0.0 {
|
|
|
+ let transform = NSAffineTransform()
|
|
|
+ transform.scale(by: scale)
|
|
|
+ transform.concat()
|
|
|
+ }
|
|
|
+
|
|
|
+ page.draw(with: .cropBox, to: (NSGraphicsContext.current as! CGContext))
|
|
|
+
|
|
|
+ NSGraphicsContext.current?.imageInterpolation = .default
|
|
|
+ }
|
|
|
+
|
|
|
+ return image
|
|
|
+ }
|
|
|
+ func savedName() -> String {
|
|
|
+ var resultArrays: Array<Any> = []
|
|
|
+ var ocrIndexArrays: Array<Any> = []
|
|
|
+
|
|
|
+ let sortedKeys = self.ocrDictionary?.allKeys.sorted(by: {
|
|
|
+ ($0 as? String)?.compare($1 as? String ?? "") == .orderedAscending
|
|
|
+ })
|
|
|
+ for i in 0 ..< (sortedKeys?.count ?? 0) {
|
|
|
+ let keyS = sortedKeys?[i]
|
|
|
+ ocrIndexArrays.append(keyS as Any)
|
|
|
+ resultArrays.append(self.ocrDictionary?[keyS as Any] as Any)
|
|
|
+ }
|
|
|
+
|
|
|
+ var fileName = self.savedFileName
|
|
|
+ if fileName.count > 50 {
|
|
|
+ fileName = String(fileName.prefix(50))
|
|
|
+ }
|
|
|
+
|
|
|
+ if sortedKeys?.count ?? 0 > 1 {
|
|
|
+ fileName = "\(self.pathFile) Pages \(fileName) _OCR"
|
|
|
+ } else {
|
|
|
+ fileName = "\(self.pathFile) Page \(fileName) _OCR"
|
|
|
+ }
|
|
|
+
|
|
|
+ var returnName = fileName
|
|
|
+ switch self.pageRangeBox.indexOfSelectedItem {
|
|
|
+ case 0:
|
|
|
+ returnName = "\(self.pathFile)_OCR"
|
|
|
+ case 2:
|
|
|
+ returnName = "\(self.pathFile) Odd_OCR"
|
|
|
+ case 3:
|
|
|
+ returnName = "\(self.pathFile) Even_OCR"
|
|
|
+ default:
|
|
|
+ break
|
|
|
+ }
|
|
|
+
|
|
|
+ return returnName
|
|
|
+ }
|
|
|
+ func savePDF() {
|
|
|
+ var resultArrays: Array<Any> = []
|
|
|
+ var ocrIndexArrays: Array<Any> = []
|
|
|
+ let sortedKeys = self.ocrDictionary?.allKeys.sorted(by: { ($0 as? String)?.compare($1 as? String ?? "") == .orderedAscending })
|
|
|
+ for i in 0 ..< (sortedKeys?.count ?? 0) {
|
|
|
+ let keyS = sortedKeys?[i]
|
|
|
+ ocrIndexArrays.append(keyS as Any)
|
|
|
+ resultArrays.append(self.ocrDictionary?[keyS as Any] as Any)
|
|
|
+ }
|
|
|
+
|
|
|
+ let fileName = self.savedFileName
|
|
|
+
|
|
|
+ let saveAccessCtr = KMSavePanelAccessoryController()
|
|
|
+ let outputSavePanel = NSSavePanel()
|
|
|
+ outputSavePanel.allowedFileTypes = ["pdf"]
|
|
|
+ outputSavePanel.nameFieldStringValue = fileName
|
|
|
+ outputSavePanel.accessoryView = saveAccessCtr.view
|
|
|
+ outputSavePanel.beginSheetModal(for: self.window!) { [self] (result) in
|
|
|
+ if result == .OK {
|
|
|
+
|
|
|
+ let savePDFPath = outputSavePanel.url?.path ?? ""
|
|
|
+ if !FileManager.default.fileExists(atPath: getOCRResrultsFolderPath()) {
|
|
|
+ try? FileManager.default.createDirectory(atPath: getOCRResrultsFolderPath(), withIntermediateDirectories: false, attributes: nil)
|
|
|
+ }
|
|
|
+ var imagePath = [Any]()
|
|
|
+ for i in 0..<ocrIndexArrays.count {
|
|
|
+ let rPath = (getOCRResrultsFolderPath() as NSString).appendingPathComponent("\(i).png")
|
|
|
+ if let index = ocrIndexArrays[i] as? NSNumber, let page = self.pdfDocument?.page(at: UInt(index.intValue)), let image = self.thumbnail(with: page) {
|
|
|
+ try? image.tiffRepresentation?.write(to: URL(fileURLWithPath: rPath), options: .atomic)
|
|
|
+ }
|
|
|
+ imagePath.append(rPath)
|
|
|
+ }
|
|
|
+
|
|
|
+ KMGOCRManager.default().createPDFFile(savePDFPath, imagePaths: imagePath, results: resultArrays, scale: KMImageScale)
|
|
|
+ if saveAccessCtr.openAutomaticButton.state == .on {
|
|
|
+ self.cancelButtonAction("")
|
|
|
+ NSDocumentController.shared.openDocument(withContentsOf: URL(fileURLWithPath: savePDFPath), display: true, completionHandler: {document,documentWasAlreadyOpen,error in
|
|
|
+
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ self.viewFileAtFinder(savePDFPath)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ func viewFileAtFinder(_ fileName: String) {
|
|
|
+ let workspace = NSWorkspace.shared
|
|
|
+ let url = URL(fileURLWithPath: fileName)
|
|
|
+ workspace.activateFileViewerSelecting([url])
|
|
|
+ }
|
|
|
+ func saveText() {
|
|
|
+ let sortedKeys = self.ocrDictionary?.allKeys.sorted(by: { ($0 as? String)?.compare($1 as? String ?? "") == .orderedAscending })
|
|
|
+ let fileName = self.savedFileName
|
|
|
+
|
|
|
+ let saveAccessCtr = KMSavePanelAccessoryController()
|
|
|
+ let outputSavePanel = NSSavePanel()
|
|
|
+ outputSavePanel.allowedFileTypes = ["txt"]
|
|
|
+ outputSavePanel.nameFieldStringValue = fileName
|
|
|
+ outputSavePanel.accessoryView = saveAccessCtr.view
|
|
|
+ outputSavePanel.beginSheetModal(for: self.window!) { (result) in
|
|
|
+ if result == .OK {
|
|
|
+ let outputURL = outputSavePanel.url
|
|
|
+ try? self.txtTextView?.string.write(to: outputURL!, atomically: true, encoding: .utf8)
|
|
|
+ if saveAccessCtr.openAutomaticButton?.state == .on {
|
|
|
+ NSWorkspace.shared.open(outputURL!)
|
|
|
+ } else {
|
|
|
+ self.viewFileAtFinder(outputURL?.path ?? "")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ func fileNameWithNums(_ nums: [NSNumber]) -> String {
|
|
|
+ var fileName: String? = nil
|
|
|
+ if nums.count > 0 {
|
|
|
+ if nums.count == 1 {
|
|
|
+ if let num = nums.first {
|
|
|
+ let idx = num.intValue + 1
|
|
|
+ return "\(idx)"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var sortIndex = NSSet()
|
|
|
+ for num in nums {
|
|
|
+ let idx = num.intValue + 1
|
|
|
+ // sortIndex.insert(NSNumber(value: idx))
|
|
|
+ sortIndex.adding(NSNumber(value: idx))
|
|
|
+ }
|
|
|
+ let sort = NSSortDescriptor(key: nil, ascending: true)
|
|
|
+ let sortDesc = [sort]
|
|
|
+ let sortArray = sortIndex.sortedArray(using: sortDesc)
|
|
|
+
|
|
|
+ var a = 0
|
|
|
+ var b = 0
|
|
|
+ if sortArray.count == 1 {
|
|
|
+ let num: NSNumber = sortArray.last as! NSNumber
|
|
|
+ fileName = "\(num.intValue)"
|
|
|
+ return fileName ?? ""
|
|
|
+ }
|
|
|
+
|
|
|
+ for i in 0 ..< sortArray.count {
|
|
|
+ let num = sortArray[i]
|
|
|
+ if fileName?.count ?? 0 > 0 {
|
|
|
+ if (num as AnyObject).intValue == b + 1 {
|
|
|
+ b = (num as AnyObject).intValue
|
|
|
+ if (i == sortArray.count - 1) {
|
|
|
+ fileName = (fileName ?? "") + "\(a)-\(b)"
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if a == b {
|
|
|
+ fileName = (fileName ?? "") + "\(a),"
|
|
|
+ } else {
|
|
|
+ fileName = (fileName ?? "") + "\(a)-\(b),"
|
|
|
+ }
|
|
|
+ a = (num as AnyObject).intValue
|
|
|
+ b = (num as AnyObject).intValue
|
|
|
+ if (i == sortArray.count - 1) {
|
|
|
+ fileName = (fileName ?? "") + "\(a)"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ fileName = ""
|
|
|
+ a = (num as AnyObject).intValue
|
|
|
+ b = (num as AnyObject).intValue
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return fileName ?? ""
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+
|
|
|
+ @IBAction func cancelButtonAction(_ sender: Any) {
|
|
|
+ KMGOCRManager.default().cancelRecognition()
|
|
|
+ self.close()
|
|
|
+ }
|
|
|
+ @IBAction func startButtonAction(_ sender: Any) {
|
|
|
+ self.ocrCurrentIndex = 0
|
|
|
+ txtTextView.string = ""
|
|
|
+ ocrDictionary = NSMutableDictionary()
|
|
|
+ let pdfDocument = self.pdfDocument
|
|
|
+ errorOCRArrays?.removeAll()
|
|
|
+ pageIndexs?.removeAll()
|
|
|
+ if self.pageRangeBox.indexOfSelectedItem == 0 {
|
|
|
+ for i in 0..<(pdfDocument?.pageCount ?? 0) {
|
|
|
+ pageIndexs?.append(NSNumber(value: i))
|
|
|
+ }
|
|
|
+ } else if self.pageRangeBox.indexOfSelectedItem == 1 {
|
|
|
+ let page = PDFView.currentPage()
|
|
|
+ let pageIndex = PDFView.document?.index(for: page)
|
|
|
+ pageIndexs?.append(NSNumber(value: pageIndex!))
|
|
|
+ } else if self.pageRangeBox.indexOfSelectedItem == 2 {
|
|
|
+ for i in 0..<(pdfDocument?.pageCount ?? 0) where i % 2 == 0 {
|
|
|
+ pageIndexs?.append(NSNumber(value: i))
|
|
|
+ }
|
|
|
+ } else if self.pageRangeBox.indexOfSelectedItem == 3 {
|
|
|
+ for i in 0..<(pdfDocument?.pageCount ?? 0) where i % 2 != 0 {
|
|
|
+ pageIndexs?.append(NSNumber(value: i))
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ let attribute = KMFileAttribute()
|
|
|
+ attribute.pdfDocument = pdfDocument
|
|
|
+ attribute.bAllPage = false
|
|
|
+ attribute.pagesString = self.pageRangeBox.stringValue
|
|
|
+ let selectPages = attribute.fetchSelectPages()
|
|
|
+ if selectPages.count > 0 {
|
|
|
+ for num in selectPages {
|
|
|
+ pageIndexs?.append(NSNumber(value: num.intValue - 1))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ batchesOCR()
|
|
|
+ }
|
|
|
+ func batchesOCR() { savedFileName = savedName()
|
|
|
+ let intervalOCR: UInt = 10
|
|
|
+ var selctPageImages = [AnyObject]()
|
|
|
+
|
|
|
+ for i in 0..<intervalOCR {
|
|
|
+ if ocrCurrentIndex + Int(i) >= self.pageIndexs?.count ?? 0 { continue }
|
|
|
+
|
|
|
+ autoreleasepool {
|
|
|
+ let index = self.pageIndexs?[self.ocrCurrentIndex + Int(i)] as! NSNumber
|
|
|
+ let page = self.pdfDocument?.page(at: UInt(index.intValue))
|
|
|
+ selctPageImages.append(thumbnail(with: page!)!/*.tiffRepresentation*/)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if selctPageImages.count < 1 && ocrCurrentIndex == 0 {
|
|
|
+ let alert = NSAlert()
|
|
|
+ alert.alertStyle = .critical
|
|
|
+ alert.messageText = NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "")
|
|
|
+
|
|
|
+ if #available(OSX 10.11, *) {
|
|
|
+ alert.beginSheetModal(for: self.window!, completionHandler: nil)
|
|
|
+ } else {
|
|
|
+ alert.runModal()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if selctPageImages.count < 1 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if appleOCRManger != nil {
|
|
|
+ appleOCRManger?.cancelRecognition()
|
|
|
+ appleOCRManger?.delegate = nil
|
|
|
+ appleOCRManger = nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if googleOCRManger != nil {
|
|
|
+ googleOCRManger?.cancelRecognition()
|
|
|
+ googleOCRManger?.delegate = nil
|
|
|
+ googleOCRManger = nil
|
|
|
+ }
|
|
|
+
|
|
|
+ ocrCopyButton.isEnabled = false
|
|
|
+ saveButton.isEnabled = false
|
|
|
+ savePDFButton.isEnabled = false
|
|
|
+ startButton.isEnabled = false
|
|
|
+ deleteButton.isEnabled = false
|
|
|
+ progressControl.isHidden = false
|
|
|
+ progressControl.startAnimation(nil)
|
|
|
+ emptyBox.isHidden = true
|
|
|
+ failedBox.isHidden = true
|
|
|
+
|
|
|
+ DispatchQueue.global(qos: .default).async {
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ if self.planComboBox.indexOfSelectedItem == 0 {
|
|
|
+ self.googleOCRManger = KMGOCRManager()
|
|
|
+ self.googleOCRManger?.ocrType = .google
|
|
|
+ let languages = KMGOCRManager.default().selectedLanguages.value(forKeyPath: KMGOCRLanguageCodeKey) as! [Any]
|
|
|
+ self.googleOCRManger?.delegate = self
|
|
|
+ self.googleOCRManger?.recognitionImages(selctPageImages, withLanguages: languages)
|
|
|
+ } else {
|
|
|
+ self.appleOCRManger = KMGOCRManager()
|
|
|
+ self.appleOCRManger?.ocrType = .apple
|
|
|
+ let languages = KMGOCRManager.default().selectedLanguages.value(forKeyPath: KMGOCRLanguageCodeKey) as! [Any]
|
|
|
+ self.appleOCRManger?.delegate = self
|
|
|
+ self.appleOCRManger?.recognitionImages(selctPageImages, withLanguages: languages)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ @IBAction func planSelectButtonAction(_ sender: NSPopUpButton) {
|
|
|
+ let plan = UserDefaults.standard.integer(forKey: "KMOCRCurrentPlanKey")
|
|
|
+ if plan != sender.indexOfSelectedItem {
|
|
|
+ KMGOCRManager.default().selectedLanguages = NSMutableArray()
|
|
|
+ updateLanguageButton(KMGOCRManager.default().selectedLanguages.value(forKeyPath: KMGOCRLanguageStringKey) as! [String])
|
|
|
+ }
|
|
|
+ UserDefaults.standard.set(sender.indexOfSelectedItem, forKey: "KMOCRCurrentPlanKey")
|
|
|
+ UserDefaults.standard.synchronize()
|
|
|
+ if self.planComboBox.indexOfSelectedItem == 0 {
|
|
|
+ KMGOCRManager.default().ocrType = .google
|
|
|
+ } else {
|
|
|
+ KMGOCRManager.default().ocrType = .apple
|
|
|
+ }
|
|
|
+ NotificationCenter.default.post(name: NSNotification.Name("KMOCRSelectedPlanChangeNotification"), object: nil)
|
|
|
+ }
|
|
|
+ @IBAction func languageButtonAction(_ sender: Any) {
|
|
|
+ // let popover = NSPopover()
|
|
|
+ // popover.delegate = self
|
|
|
+ // popover.contentViewController = KMLanguageViewController(nibName: "KMLanguageViewController", bundle: Bundle.main)
|
|
|
+ // popover.animates = true
|
|
|
+ // popover.behavior = .transient
|
|
|
+ // popover.show(relativeTo: (sender as! NSView).bounds, of: sender as! NSView, preferredEdge: .minX)
|
|
|
+ }
|
|
|
+ @IBAction func helpButtonAction(_ sender: Any) {
|
|
|
+ let helpController = NSViewController()
|
|
|
+ let textView = NSTextView(frame: NSRectToCGRect(NSMakeRect(0, 0, 300.0, 50.0)))
|
|
|
+ textView.backgroundColor = NSColor.clear
|
|
|
+ textView.isEditable = false
|
|
|
+ textView.layer?.cornerRadius = 6
|
|
|
+ let tStrAuto = NSLocalizedString("Choose automatic language detection for better OCR results.", comment: "")
|
|
|
+ textView.alignment = .justified
|
|
|
+ textView.string = "\n\(tStrAuto)"
|
|
|
+ helpController.view = textView
|
|
|
+ let popover = NSPopover()
|
|
|
+ popover.delegate = self
|
|
|
+ popover.contentViewController = helpController
|
|
|
+ popover.animates = true
|
|
|
+ popover.behavior = .transient
|
|
|
+ popover.show(relativeTo: (sender as! NSView).bounds, of: sender as! NSView, preferredEdge: .minY)
|
|
|
+ }
|
|
|
+ @IBAction func buttonItemClick_CopyTxt(_ sender: NSButton) {
|
|
|
+ let pasteboard = NSPasteboard.general
|
|
|
+ pasteboard.clearContents()
|
|
|
+ let str: NSPasteboardWriting = self.txtTextView.string as NSPasteboardWriting
|
|
|
+ pasteboard.writeObjects([str])
|
|
|
+ let _ = CustomAlertView.alertView(message: NSLocalizedString("Copy successful!", comment: ""), fromView: sender.superview!, withStyle: .black)
|
|
|
+ }
|
|
|
+ @IBAction func buttonItemClick_Delete(_ sender: NSButton) {
|
|
|
+ ocrCopyButton.isEnabled = false
|
|
|
+ saveButton.isEnabled = false
|
|
|
+ savePDFButton.isEnabled = false
|
|
|
+ deleteButton.isEnabled = false
|
|
|
+ emptyBox.isHidden = false
|
|
|
+ failedBox.isHidden = true
|
|
|
+ resultString = ""
|
|
|
+ txtTextView.string = ""
|
|
|
+ ocrDictionary = NSMutableDictionary()
|
|
|
+ }
|
|
|
+ @IBAction func boxItemClicked_PageRange(_ sender: NSButton) {
|
|
|
+ if 4 != pageRangeBox.indexOfSelectedItem {
|
|
|
+ self.window?.makeFirstResponder(self)
|
|
|
+ pageRangeBox.isEditable = false
|
|
|
+ } else {
|
|
|
+ pageRangeBox.stringValue = ""
|
|
|
+ pageRangeBox.isEditable = true
|
|
|
+ self.window?.makeFirstResponder(pageRangeBox)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @IBAction func nextButtonAction(_ sender: NSButton) {
|
|
|
+ self.PDFView.goToNextPage(nil)
|
|
|
+ self.reloadPDFData()
|
|
|
+ }
|
|
|
+ @IBAction func previousButtonAction(_ sender: NSButton) {
|
|
|
+ self.PDFView.goToPreviousPage(nil)
|
|
|
+ self.reloadPDFData()
|
|
|
+ }
|
|
|
+ @IBAction func buttonClicked_SaveButton(_ sender: NSButton) {
|
|
|
+ self.saveText()
|
|
|
+ }
|
|
|
+ @IBAction func savePDFButtonAction(_ sender: NSButton) {
|
|
|
+ self.savePDF()
|
|
|
+ }
|
|
|
+ func controlTextDidEndEditing(_ notification: Notification) {
|
|
|
+ guard let textField = notification.object as? NSTextField else { return }
|
|
|
+ if textField == currentPageLabel {
|
|
|
+ let index = Int(currentPageLabel.stringValue) ?? 0
|
|
|
+ let pageCount = pdfDocument?.pageCount
|
|
|
+ let currentPageIndex = pdfDocument?.index(for: PDFView.currentPage())
|
|
|
+ if index > 0 && index <= pageCount ?? 0 {
|
|
|
+ PDFView.go(to: pdfDocument?.page(at: UInt(index-1))!)
|
|
|
+ reloadPDFData()
|
|
|
+ } else {
|
|
|
+ currentPageLabel.stringValue = "(currentPageIndex+1)"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ func controlTextDidChange(_ notification: Notification) {
|
|
|
+ guard let textField = notification.object as? NSTextField else { return }
|
|
|
+ if textField == currentPageLabel {
|
|
|
+ let string = textField.formatter?.string(for: NSNumber(value: Int(textField.stringValue) ?? 0))
|
|
|
+ textField.stringValue = string ?? ""
|
|
|
+ }
|
|
|
+ }
|
|
|
+ func popoverDidClose(_ notification: Notification) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ func gocrManagerDidStartOCR(_ manager: KMGOCRManager!) {
|
|
|
+
|
|
|
+ }
|
|
|
+ //MARK: KMGOCRManagerDelegate
|
|
|
+ func gocrManagerDidFinishOCR(_ manager: KMGOCRManager!) {
|
|
|
+ self.batchesOCR()
|
|
|
+ }
|
|
|
+ func gocrManager(_ manager: KMGOCRManager!, didCancelOCRImageAt index: Int) {
|
|
|
+
|
|
|
+ }
|
|
|
+ func gocrManager(_ manager: KMGOCRManager!, didStartOCRImageAt index: Int) {
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ self.pageRangeBox.isEnabled = false
|
|
|
+ self.languageButton.isEnabled = false
|
|
|
+ self.planComboBox.isEnabled = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ func gocrManager(_ manager: KMGOCRManager!, didFinishOCRImageAt index: Int, results: [KMGOCRResult]!) {
|
|
|
+ self.dealWithResults(results, OCRImageAtIndex: index)
|
|
|
+ }
|
|
|
+ func gocrManager(_ manager: KMGOCRManager!, didFailureOCRImageAt index: Int, error: Error!) {
|
|
|
+ let pagenum = self.pageIndexs?[index] as! NSNumber
|
|
|
+ self.errorOCRArrays?.append(pagenum)
|
|
|
+ self.dealWithResults([], OCRImageAtIndex: index)
|
|
|
+ }
|
|
|
+
|
|
|
+ func dealWithResults(_ rlts: [KMGOCRResult]?, OCRImageAtIndex index: Int) {
|
|
|
+ if index >= self.pageIndexs?.count ?? 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ let key = self.pageIndexs?[self.ocrCurrentIndex] as! NSNumber
|
|
|
+
|
|
|
+ if ocrDictionary == nil {
|
|
|
+ ocrDictionary = NSMutableDictionary()
|
|
|
+ }
|
|
|
+
|
|
|
+ ocrDictionary?.setObject(rlts as Any, forKey: key)
|
|
|
+
|
|
|
+ let sortedKeys = self.ocrDictionary?.allKeys.sorted(by: { ($0 as! NSNumber).compare($1 as! NSNumber) == .orderedAscending })
|
|
|
+ var textString = ""
|
|
|
+
|
|
|
+ for key in sortedKeys! {
|
|
|
+ let results: Array<KMGOCRResult> = self.ocrDictionary?.object(forKey: key) as! Array<KMGOCRResult>
|
|
|
+ var rStr = ""
|
|
|
+ if results.count > 0 {
|
|
|
+ rStr = results[0].text
|
|
|
+ }
|
|
|
+ if textString.count > 0 {
|
|
|
+ textString += "\n\n"
|
|
|
+ }
|
|
|
+ textString += String(format: NSLocalizedString("Page %ld", comment: ""), (key as! NSNumber).intValue + 1)
|
|
|
+ textString += "\n"
|
|
|
+ textString += rStr
|
|
|
+ }
|
|
|
+
|
|
|
+ self.txtTextView.string = textString
|
|
|
+ self.resultString = textString
|
|
|
+
|
|
|
+ self.ocrCurrentIndex += 1
|
|
|
+
|
|
|
+ if self.ocrCurrentIndex >= (self.pageIndexs?.count ?? 0) - 1 {
|
|
|
+ self.progressControl.stopAnimation(nil)
|
|
|
+ self.progressControl.isHidden = true
|
|
|
+ self.saveButton.isEnabled = true
|
|
|
+ self.savePDFButton.isEnabled = true
|
|
|
+ self.ocrCopyButton.isEnabled = true
|
|
|
+ self.deleteButton.isEnabled = true
|
|
|
+ self.startButton.isEnabled = true
|
|
|
+ self.planComboBox.isEnabled = true
|
|
|
+ self.pageRangeBox.isEnabled = true
|
|
|
+ self.languageButton.isEnabled = true
|
|
|
+
|
|
|
+ if self.errorOCRArrays?.count ?? 0 < 1 {
|
|
|
+
|
|
|
+ } else if self.errorOCRArrays?.count == self.pageIndexs?.count {
|
|
|
+ if KMGOCRManager.default().ocrType == .google {
|
|
|
+ self.failedLabel.stringValue = NSLocalizedString("OCR failed.Please try to change the OCR Plan to \"Plan 2 (Offline)\"", comment: "")
|
|
|
+ self.failedBox.isHidden = false
|
|
|
+ } else {
|
|
|
+ let alert = NSAlert()
|
|
|
+ alert.alertStyle = NSAlert.Style.critical
|
|
|
+ alert.messageText = ""
|
|
|
+ if #available(macOS 10.15, *) {
|
|
|
+ alert.informativeText = NSLocalizedString("Unable to perform OCR on this document. Please try again later.", comment: "")
|
|
|
+ } else {
|
|
|
+ alert.informativeText = NSLocalizedString("OCR failed, please try again. Note: OCR Plan 2(Offline) is supported in macOS 10.15+.", comment: "")
|
|
|
+ self.failedLabel.stringValue = NSLocalizedString("OCR failed, please try again. Note: OCR Plan 2(Offline) is supported in macOS 10.15+.", comment: "")
|
|
|
+ self.failedBox.isHidden = false
|
|
|
+ }
|
|
|
+ alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
|
|
|
+ let response = alert.runModal()
|
|
|
+ if response == NSApplication.ModalResponse.alertFirstButtonReturn {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ var contextString = String(format: "%@", NSLocalizedString("Some problems occurred during the last operation:", comment: ""))
|
|
|
+ contextString += "\n"
|
|
|
+
|
|
|
+ if self.errorOCRArrays?.count ?? 0 > 1 {
|
|
|
+ contextString += NSLocalizedString("Pages", comment: "")
|
|
|
+ } else {
|
|
|
+ contextString += NSLocalizedString("Page", comment: "")
|
|
|
+ }
|
|
|
+ if self.errorOCRArrays?.count ?? 0 > 0 {
|
|
|
+ contextString += String(format: ": %@", self.fileNameWithNums(self.errorOCRArrays as! Array<NSNumber>))
|
|
|
+ }
|
|
|
+
|
|
|
+ let alert = NSAlert()
|
|
|
+ alert.alertStyle = NSAlert.Style.critical
|
|
|
+ alert.messageText = NSLocalizedString("Completed", comment: "")
|
|
|
+ alert.informativeText = contextString
|
|
|
+ alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
|
|
|
+ let response = alert.runModal()
|
|
|
+ if response == NSApplication.ModalResponse.alertFirstButtonReturn {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|