// // KMAITranslationConfirmWindowController.swift // PDF Master // // Created by wanjun on 2023/5/25. // import Cocoa class KMAITranslationConfirmWindowController: NSWindowController { @IBOutlet weak var label: NSTextField! @IBOutlet weak var subLabel: NSTextField! @IBOutlet weak var cancelBox: NSBox! @IBOutlet weak var cancelLabel: NSTextField! @IBOutlet weak var cancelButton: NSButton! @IBOutlet weak var translateBox: NSBox! @IBOutlet weak var translateLabel: NSTextField! @IBOutlet weak var translateButton: NSButton! @IBOutlet weak var fromBox: NSBox! @IBOutlet weak var fromLabel: NSTextField! @IBOutlet weak var toBox: NSBox! @IBOutlet weak var toLabel: NSTextField! @IBOutlet weak var languageImageView: NSImageView! @IBOutlet weak var tipsLabel1: NSTextField! @IBOutlet weak var tipsLabel2: NSTextField! @IBOutlet weak var prePDFView: KMCustomPDFView? var filePath: String = "" var progressController: SKProgressController? var fromStr: String = "auto" var toStr: String = "en" var fromLanguages: [String] = ["Automatic", "English", "Simplified Chinese", "Traditional Chinese", "Japanese", "Korean", "French", "Spanish", "Italian", "German", "Portuguese", "Russian", "Vietnamese", "Thai", "Arabic", "Greek", "Bulgarian", "Finnish", "Slovene", "Dutch", "Czech", "Swedish", "Polish", "Danish", "Romanian", "Hungarian"] var toLanguages: [String] = ["English", "Simplified Chinese", "Traditional Chinese", "Japanese", "Korean", "French", "Spanish", "Italian", "German", "Portuguese", "Russian", "Vietnamese", "Thai", "Arabic", "Greek", "Bulgarian", "Finnish", "Slovene", "Dutch", "Czech", "Swedish", "Polish", "Danish", "Romanian", "Hungarian"] var popover: NSPopover? var saveFileUrl: URL = URL(fileURLWithPath: "") deinit { self.prePDFView?.removeFromSuperview() self.prePDFView = nil } override func windowDidLoad() { super.windowDidLoad() self.initLocalization() self.initializeUI() let document = CPDFDocument(url: URL(fileURLWithPath: self.filePath)) self.prePDFView?.document = document! if (self.prePDFView?.documentView() != nil) { self.prePDFView?.documentView().enclosingScrollView?.hasVerticalScroller = false self.prePDFView?.documentView().enclosingScrollView?.hasHorizontalScroller = false } } func initializeUI() -> Void { self.label.textColor = NSColor(hex: "#252629") self.label.font = NSFont.SFProTextSemibold(16.0) self.subLabel.textColor = NSColor(hex: "##616469") self.subLabel.font = NSFont.SFProTextRegular(12.0) self.fromBox.fillColor = NSColor(hex: "#FFFFFF") self.fromBox.borderColor = NSColor(hex: "#DFE1E5") self.fromLabel.textColor = NSColor(hex: "#252629") self.fromLabel.font = NSFont.SFProTextRegular(14.0) self.toBox.fillColor = NSColor(hex: "#FFFFFF") self.toBox.borderColor = NSColor(hex: "#DFE1E5") self.toLabel.textColor = NSColor(hex: "#252629") self.toLabel.font = NSFont.SFProTextRegular(14.0) self.languageImageView.image = NSImage(named: "ic_transtate") self.tipsLabel1.textColor = NSColor(hex: "#94989C") self.tipsLabel1.font = NSFont.SFProTextRegular(12.0) self.tipsLabel2.textColor = NSColor(hex: "#94989C") self.tipsLabel2.font = NSFont.SFProTextRegular(12.0) self.cancelBox.fillColor = NSColor(hex: "#F5F5F5") self.cancelBox.cornerRadius = 5.0 self.cancelBox.borderWidth = 0.0 self.cancelLabel.textColor = NSColor(hex: "#4D4D4D") self.cancelLabel.font = NSFont.SFProTextRegular(13.0) self.translateBox.fillColor = NSColor(hex: "#4B91F7") self.translateBox.cornerRadius = 5.0 self.translateBox.borderWidth = 0.0 self.translateLabel.textColor = NSColor(hex: "#FFFFFF") self.translateLabel.font = NSFont.SFProTextRegular(13.0) self.prePDFView?.backgroundColor = NSColor(hex: "#F7F8FA") } func initLocalization() -> Void { self.label.stringValue = NSLocalizedString("AI Translation", comment: "") self.subLabel.stringValue = NSLocalizedString("Translation Language", comment: "") self.cancelLabel.stringValue = NSLocalizedString("Cancel", comment: "") self.translateLabel.stringValue = NSLocalizedString("Translate", comment: "") self.fromLabel.stringValue = "Automatic" self.toLabel.stringValue = "English" self.tipsLabel1.stringValue = NSLocalizedString("Scanned PDF files are not supported", comment: "") self.tipsLabel2.stringValue = NSLocalizedString("Limit document size to 10M, document page number to 30, 10w characters per month.", comment: "") } override func mouseDown(with event: NSEvent) { if self.popover != nil { self.popover?.close() self.popover = nil } } // MARK: Private Methods // MARK: Action Methods @IBAction func translateAction(_ sender: NSButton) { if !KMLightMemberManager.manager.isLogin() { KMLoginWindowController.show(window: NSApp.mainWindow!) return } let filePathUrl = URL(fileURLWithPath: self.filePath) let fileNameWithoutExtension = filePathUrl.deletingPathExtension().lastPathComponent let newFileName = fileNameWithoutExtension + "_aiTranslation" let outputSavePanel = NSSavePanel() outputSavePanel.title = NSLocalizedString("Translate", comment: "") outputSavePanel.allowedFileTypes = ["pdf"] outputSavePanel.nameFieldStringValue = newFileName outputSavePanel.directoryURL = filePathUrl.deletingLastPathComponent() let result = outputSavePanel.runModal() if result == .OK { self.saveFileUrl = outputSavePanel.url! DispatchQueue.main.async { self.showProgressWindow() } let infoDictionary = Bundle .main.infoDictionary! let majorVersion = infoDictionary["CFBundleShortVersionString"] KMRequestServerManager.manager.aiTranslationFileUpload(file: self.filePath, version: "1.0.1") { [unowned self] success, result in if success { let result: NSDictionary = result!.result let fileKey = result["fileKey"] let fileName = result["fileName"] let pageCount = result["pageCount"] if fileKey != nil { self.fileTranslateHandle(fileKey as! String) } } else { let result: String = result!.message DispatchQueue.main.async { self.hiddenProgressWindow() let alert = NSAlert() alert.alertStyle = .critical alert.messageText = result alert.runModal() } } } } else { outputSavePanel.close() } } @IBAction func cancelAction(_ sender: NSButton) { NSApp.mainWindow!.endSheet(self.window!) self.window?.orderOut(self) } @IBAction func fromLanguageAction(_ sender: NSButton) { self.languageAction(true) } @IBAction func toLanguageAction(_ sender: NSButton) { self.languageAction(false) } func languageAction(_ isFromLanguage: Bool) -> Void { if (self.popover != nil && self.popover!.isShown) { self.popover?.close() self.popover = nil return } var languages = self.fromLanguages if !isFromLanguage { languages = self.toLanguages } let vc: KMAILanguagePopVC = KMAILanguagePopVC().initWithPopViewDataArr(languages) let createFilePopover: NSPopover = NSPopover.init() self.popover = createFilePopover createFilePopover.contentViewController = vc createFilePopover.animates = true createFilePopover.behavior = .semitransient createFilePopover.setValue(true, forKey: "shouldHideAnchor") if isFromLanguage { vc.selectString = self.fromLabel.stringValue } else { vc.selectString = self.toLabel.stringValue } vc.downCallback = { [unowned self] (language: String) -> Void in createFilePopover.close() if isFromLanguage { self.fromLabel.stringValue = language self.fromStr = self.languageAbbreviation(language) } else { self.toLabel.stringValue = language self.toStr = self.languageAbbreviation(language) } } if isFromLanguage { createFilePopover.show(relativeTo: CGRect(x: fromBox.bounds.origin.x, y: 10, width: fromBox.bounds.size.width, height: fromBox.bounds.size.height), of: fromBox, preferredEdge: .maxY) vc.customBoxWidthLayoutConstraint.constant = fromBox.frame.width } else { createFilePopover.show(relativeTo: CGRect(x: toBox.bounds.origin.x, y: 10, width: toBox.bounds.size.width, height: toBox.bounds.size.height), of: toBox, preferredEdge: .maxY) vc.customBoxWidthLayoutConstraint.constant = toBox.frame.width } } // MARK: Private Methods func showProgressWindow() { let progress = SKProgressController() progress.message = NSLocalizedString("Translating...", comment: "") progress.window?.backgroundColor = NSColor(hex: "#36383B") progress.window?.contentView?.wantsLayer = true progress.window?.contentView?.layer?.backgroundColor = NSColor(hex: "#36383B").cgColor progress.progressField.textColor = NSColor.white progress.closeBlock = { [unowned self] in } self.progressController = progress self.window?.beginSheet(progress.window!) } func hiddenProgressWindow() { if (self.progressController != nil) { self.window?.endSheet((self.progressController?.window)!) self.progressController = nil } } func fileTranslateHandle(_ fileKey: String) -> Void { let infoDictionary = Bundle .main.infoDictionary! let majorVersion = infoDictionary["CFBundleShortVersionString"] KMRequestServerManager.manager.aiTranslationFileTranslateHandle(fileKey: fileKey, from: self.fromStr, to: self.toStr, version: "1.0.1") { success, result in if success { let result: NSDictionary = result!.result let fileUrl: String = result["fileUrl"] as! String let downFileUrl: String = result["downFileUrl"] as! String let ossDownUrl: String = result["ossDownUrl"] as! String let fileName: String = result["fileName"] as! String let downFileName: String = result["downFileName"] as! String let from: String = result["from"] as! String let to: String = result["to"] as! String self.downloadFile(filePath: ossDownUrl, downFileName: downFileName) } else { let result: String = result!.message DispatchQueue.main.async { self.hiddenProgressWindow() let alert = NSAlert() alert.alertStyle = .critical alert.messageText = result alert.runModal() } } } } func downloadFile(filePath: String, downFileName: String) -> Void { guard let fileURL = URL(string: filePath) else { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Invalid file link", comment: "") alert.runModal() return } // let filePathUrl = URL(fileURLWithPath: self.filePath) // let fileNameWithoutExtension = filePathUrl.deletingPathExtension().lastPathComponent // let fileExtension = filePathUrl.pathExtension // let newFileName = fileNameWithoutExtension + "_aiTranslation" + "." + fileExtension // let destinationURL = filePathUrl.deletingLastPathComponent().appendingPathComponent(newFileName) if FileManager.default.fileExists(atPath: self.saveFileUrl.path) { do { try FileManager.default.removeItem(at: self.saveFileUrl) print("删除旧文件成功") } catch { print("删除旧文件失败:\(error)") } } let sessionConfiguration = URLSessionConfiguration.default let session = URLSession(configuration: sessionConfiguration) let downloadTask = session.downloadTask(with: fileURL) { (tempLocalURL, response, error) in if let error = error { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = String(format: "%@:\(error)", NSLocalizedString("Download failed", comment: "")) alert.runModal() return } guard let tempLocalURL = tempLocalURL else { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Invalid temporary directory", comment: "") alert.runModal() return } DispatchQueue.main.async { self.hiddenProgressWindow() // NSApp.mainWindow!.endSheet(self.window!) self.window?.orderOut(self) } do { try FileManager.default.moveItem(at: tempLocalURL, to: self.saveFileUrl) NSDocumentController.shared.openDocument(withContentsOf: self.saveFileUrl, display: true) { document, documentWasAlreadyOpen, error in if error != nil { NSApp.presentError(error!) } else { } } } catch { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = String(format: "%@:\(error)", NSLocalizedString("Failed to save file", comment: "")) alert.runModal() } } downloadTask.resume() } func languageAbbreviation(_ language: String) -> String { if language == "Automatic" { return "auto" } else if language == "English" { return "en" } else if language == "Simplified Chinese" { return "zh" } else if language == "Traditional Chinese" { return "cht" } else if language == "Japanese" { return "jp" } else if language == "Korean" { return "kor" } else if language == "French" { return "fra" } else if language == "Spanish" { return "spa" } else if language == "Italian" { return "it" } else if language == "German" { return "de" } else if language == "Portuguese" { return "pt" } else if language == "Russian" { return "ru" } else if language == "Vietnamese" { return "vie" } else if language == "Thai" { return "th" } else if language == "Arabic" { return "ara" } else if language == "Greek" { return "el" } else if language == "Bulgarian" { return "bul" } else if language == "Finnish" { return "fin" } else if language == "Slovene" { return "slo" } else if language == "Dutch" { return "nl" } else if language == "Czech" { return "cs" } else if language == "Swedish" { return "swe" } else if language == "Polish" { return "pl" } else if language == "Danish" { return "dan" } else if language == "Romanian" { return "rom" } else if language == "Hungarian" { return "hu" } return "auto" } }