KMAITranslationVC.swift 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. //
  2. // KMAITranslationVC.swift
  3. // PDF Master
  4. //
  5. // Created by wanjun on 2023/5/22.
  6. //
  7. import Cocoa
  8. class KMAITranslationVC: NSViewController {
  9. @IBOutlet weak var aiTranslationLabel: NSTextField!
  10. @IBOutlet weak var aiTranslationView: KMDottedLineView!
  11. @IBOutlet weak var supportPDFWordFileImageView: NSImageView!
  12. @IBOutlet weak var supportPDFWordFileLabel: NSTextField!
  13. @IBOutlet weak var supportPDFWordFileSubLabel: NSTextField!
  14. @IBOutlet weak var translationLanguageLabel: NSTextField!
  15. @IBOutlet weak var automaticBox: KMBox!
  16. @IBOutlet weak var automaticLabel: NSTextField!
  17. @IBOutlet weak var languageBox: KMBox!
  18. @IBOutlet weak var languageLabel: NSTextField!
  19. @IBOutlet weak var languageImageView: NSImageView!
  20. @IBOutlet weak var selectYourFilesBox: KMBox!
  21. @IBOutlet weak var selectYourFilesLabel: NSTextField!
  22. @IBOutlet weak var selectYourFilesImageView: NSImageView!
  23. @IBOutlet weak var orDropFileHereLabel: NSTextField!
  24. var fromStr: String = "auto"
  25. var toStr: String = "en"
  26. 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"]
  27. 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"]
  28. var popover: NSPopover?
  29. override func viewDidLoad() {
  30. super.viewDidLoad()
  31. // Do view setup here.
  32. self.initLocalization()
  33. self.initializeUI()
  34. }
  35. // MARK: initialize
  36. func initializeUI() -> Void {
  37. self.aiTranslationView.canHover = false
  38. self.aiTranslationLabel.textColor = NSColor(hex: "#252629")
  39. self.aiTranslationLabel.font = NSFont.SFProTextSemibold(20.0)
  40. self.supportPDFWordFileImageView.image = NSImage(named: "ic_function_other")
  41. self.supportPDFWordFileLabel.textColor = NSColor(hex: "#252629")
  42. self.supportPDFWordFileLabel.font = NSFont.SFProTextSemibold(20.0)
  43. self.supportPDFWordFileSubLabel.textColor = NSColor(hex: "#94989C")
  44. self.supportPDFWordFileSubLabel.font = NSFont.SFProTextRegular(14.0)
  45. self.translationLanguageLabel.textColor = NSColor(hex: "#252629")
  46. self.translationLanguageLabel.font = NSFont.SFProTextRegular(14.0)
  47. self.automaticLabel.textColor = NSColor(hex: "#252629")
  48. self.automaticLabel.font = NSFont.SFProTextRegular(16.0)
  49. self.languageLabel.textColor = NSColor(hex: "#252629")
  50. self.languageLabel.font = NSFont.SFProTextRegular(16.0)
  51. self.automaticBox.cornerRadius = 4.0
  52. self.automaticBox.borderColor = NSColor(hex: "#DFE1E5")
  53. self.languageBox.cornerRadius = 4.0
  54. self.languageBox.borderColor = NSColor(hex: "#DFE1E5")
  55. self.languageImageView.image = NSImage(named: "ic_transtate")
  56. self.automaticBox.downCallback = { [unowned self](downEntered: Bool, mouseBox: KMBox, event) -> Void in
  57. if downEntered {
  58. self.languageAction(true)
  59. }
  60. }
  61. self.languageBox.downCallback = { [unowned self](downEntered: Bool, mouseBox: KMBox, event) -> Void in
  62. if downEntered {
  63. self.languageAction(false)
  64. }
  65. }
  66. self.selectYourFilesBox.cornerRadius = 4.0
  67. self.selectYourFilesBox.fillColor = NSColor(hex: "#1770F4")
  68. self.selectYourFilesLabel.textColor = NSColor(hex: "#FFFFFF")
  69. self.selectYourFilesLabel.font = NSFont.SFProTextRegular(16.0)
  70. self.selectYourFilesImageView.image = NSImage(named: "icon_SelectYourFiles")
  71. self.orDropFileHereLabel.textColor = NSColor(hex: "#616469")
  72. self.orDropFileHereLabel.font = NSFont.SFProTextRegular(14.0)
  73. self.selectYourFilesBox.moveCallback = { [unowned self](mouseEntered: Bool, mouseBox: KMBox) -> Void in
  74. if mouseEntered {
  75. self.selectYourFilesBox.fillColor = NSColor(hex: "#3F8FF6")
  76. } else {
  77. self.selectYourFilesBox.fillColor = NSColor(hex: "#1770F4")
  78. }
  79. }
  80. self.selectYourFilesBox.downCallback = { [unowned self](downEntered: Bool, mouseBox: KMBox, event) -> Void in
  81. if downEntered {
  82. let openPanel = NSOpenPanel()
  83. openPanel.allowedFileTypes = ["pdf", "PDF", "docx", "doc"]
  84. openPanel.allowsMultipleSelection = false
  85. openPanel.beginSheetModal(for: self.view.window!) { result in
  86. if result == .OK {
  87. for url in openPanel.urls {
  88. if !url.path.isPDFValid() {
  89. let alert = NSAlert()
  90. alert.alertStyle = .critical
  91. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  92. alert.runModal()
  93. } else {
  94. let infoDictionary = Bundle .main.infoDictionary!
  95. let majorVersion = infoDictionary["CFBundleShortVersionString"]
  96. KMRequestServerManager.manager.aiTranslationFileUpload(file: url.path, version: "1.0.1") { [unowned self] success, result in
  97. if success {
  98. let result: NSDictionary = result!.result
  99. let fileKey = result["fileKey"]
  100. let fileName = result["fileName"]
  101. let pageCount = result["pageCount"]
  102. if fileKey != nil {
  103. self.fileTranslateHandle(fileKey as! String)
  104. }
  105. } else {
  106. }
  107. }
  108. }
  109. }
  110. }
  111. }
  112. }
  113. }
  114. }
  115. func initLocalization() -> Void {
  116. self.aiTranslationLabel.stringValue = NSLocalizedString("AI Translation", comment: "")
  117. self.supportPDFWordFileLabel.stringValue = NSLocalizedString("Support PDF, Word file", comment: "")
  118. self.supportPDFWordFileSubLabel.stringValue = NSLocalizedString("Limit document size to 10M, document page number to 30, 10w characters per month", comment: "")
  119. self.translationLanguageLabel.stringValue = NSLocalizedString("Translation Language:", comment: "")
  120. self.selectYourFilesLabel.stringValue = NSLocalizedString("Select your file", comment: "")
  121. self.orDropFileHereLabel.stringValue = NSLocalizedString("or drop file here", comment: "")
  122. self.automaticLabel.stringValue = NSLocalizedString("Automatic", comment: "")
  123. self.languageLabel.stringValue = NSLocalizedString("English", comment: "")
  124. }
  125. // MARK: Private Methods
  126. func fileTranslateHandle(_ fileKey: String) -> Void {
  127. let infoDictionary = Bundle .main.infoDictionary!
  128. let majorVersion = infoDictionary["CFBundleShortVersionString"]
  129. KMRequestServerManager.manager.aiTranslationFileTranslateHandle(fileKey: fileKey, from: self.fromStr, to: self.toStr, version: "1.0.1") { success, result in
  130. if success {
  131. let result: NSDictionary = result!.result
  132. let fileUrl: String = result["fileUrl"] as! String
  133. let downFileUrl: String = result["downFileUrl"] as! String
  134. let ossDownUrl: String = result["ossDownUrl"] as! String
  135. let fileName: String = result["fileName"] as! String
  136. let downFileName: String = result["downFileName"] as! String
  137. let from: String = result["from"] as! String
  138. let to: String = result["to"] as! String
  139. self.downloadFile(filePath: ossDownUrl, downFileName: downFileName)
  140. }
  141. }
  142. }
  143. func downloadFile(filePath: String, downFileName: String) -> Void {
  144. guard let fileURL = URL(string: filePath) else {
  145. let alert = NSAlert()
  146. alert.alertStyle = .critical
  147. alert.messageText = NSLocalizedString("Invalid file link", comment: "")
  148. alert.runModal()
  149. return
  150. }
  151. let destinationURL = FileManager.default.temporaryDirectory.appendingPathComponent(downFileName)
  152. if FileManager.default.fileExists(atPath: destinationURL.path) {
  153. do {
  154. try FileManager.default.removeItem(at: destinationURL)
  155. print("删除旧文件成功")
  156. } catch {
  157. print("删除旧文件失败:\(error)")
  158. }
  159. }
  160. let sessionConfiguration = URLSessionConfiguration.default
  161. let session = URLSession(configuration: sessionConfiguration)
  162. let downloadTask = session.downloadTask(with: fileURL) { (tempLocalURL, response, error) in
  163. if let error = error {
  164. let alert = NSAlert()
  165. alert.alertStyle = .critical
  166. alert.messageText = String(format: "%@:\(error)", NSLocalizedString("Download failure", comment: ""))
  167. alert.runModal()
  168. return
  169. }
  170. guard let tempLocalURL = tempLocalURL else {
  171. let alert = NSAlert()
  172. alert.alertStyle = .critical
  173. alert.messageText = NSLocalizedString("The download file temporary path is invalid", comment: "")
  174. alert.runModal()
  175. return
  176. }
  177. do {
  178. try FileManager.default.moveItem(at: tempLocalURL, to: destinationURL)
  179. NSDocumentController.shared.openDocument(withContentsOf: destinationURL, display: true) { document, documentWasAlreadyOpen, error in
  180. if error != nil {
  181. NSApp.presentError(error!)
  182. } else {
  183. }
  184. }
  185. } catch {
  186. let alert = NSAlert()
  187. alert.alertStyle = .critical
  188. alert.messageText = String(format: "%@:\(error)", NSLocalizedString("File saving failure", comment: ""))
  189. alert.runModal()
  190. }
  191. }
  192. downloadTask.resume()
  193. }
  194. func languageAbbreviation(_ language: String) -> String {
  195. if language == "Automatic Identification" {
  196. return "auto"
  197. } else if language == "English" {
  198. return "en"
  199. } else if language == "Simplified Chinese" {
  200. return "zh"
  201. } else if language == "Traditional Chinese" {
  202. return "cht"
  203. } else if language == "Japanese" {
  204. return "jp"
  205. } else if language == "Korean" {
  206. return "kor"
  207. } else if language == "French" {
  208. return "fra"
  209. } else if language == "Spanish" {
  210. return "spa"
  211. } else if language == "Italian" {
  212. return "it"
  213. } else if language == "German" {
  214. return "de"
  215. } else if language == "Portuguese" {
  216. return "pt"
  217. } else if language == "Russian" {
  218. return "ru"
  219. } else if language == "Vietnamese" {
  220. return "vie"
  221. } else if language == "Thai" {
  222. return "th"
  223. } else if language == "Arabic" {
  224. return "ara"
  225. } else if language == "Greek" {
  226. return "el"
  227. } else if language == "Bulgarian" {
  228. return "bul"
  229. } else if language == "Finnish" {
  230. return "fin"
  231. } else if language == "Slovene" {
  232. return "slo"
  233. } else if language == "Dutch" {
  234. return "nl"
  235. } else if language == "Czech" {
  236. return "cs"
  237. } else if language == "Swedish" {
  238. return "swe"
  239. } else if language == "Polish" {
  240. return "pl"
  241. } else if language == "Danish" {
  242. return "dan"
  243. } else if language == "Romanian" {
  244. return "rom"
  245. } else if language == "Hungarian" {
  246. return "hu"
  247. }
  248. return "auto"
  249. }
  250. // MARK: Action Methods
  251. func languageAction(_ isFromLanguage: Bool) -> Void {
  252. if (self.popover != nil && self.popover!.isShown) {
  253. self.popover?.close()
  254. self.popover = nil
  255. return
  256. }
  257. var languages = self.fromLanguages
  258. if !isFromLanguage {
  259. languages = self.toLanguages
  260. }
  261. let vc: KMAILanguagePopVC = KMAILanguagePopVC().initWithPopViewDataArr(self.fromLanguages)
  262. let createFilePopover: NSPopover = NSPopover.init()
  263. self.popover = createFilePopover
  264. createFilePopover.contentViewController = vc
  265. createFilePopover.animates = true
  266. createFilePopover.behavior = .semitransient
  267. createFilePopover.setValue(true, forKey: "shouldHideAnchor")
  268. vc.downCallback = { [unowned self] (language: String) -> Void in
  269. createFilePopover.close()
  270. if isFromLanguage {
  271. self.automaticLabel.stringValue = language
  272. self.fromStr = self.languageAbbreviation(language)
  273. } else {
  274. self.languageLabel.stringValue = language
  275. self.toStr = self.languageAbbreviation(language)
  276. }
  277. }
  278. if isFromLanguage {
  279. createFilePopover.show(relativeTo: CGRect(x: automaticBox.bounds.origin.x, y: 10, width: automaticBox.bounds.size.width, height: automaticBox.bounds.size.height), of: automaticBox, preferredEdge: .maxY)
  280. vc.customBoxWidthLayoutConstraint.constant = automaticBox.frame.width
  281. } else {
  282. createFilePopover.show(relativeTo: CGRect(x: languageBox.bounds.origin.x, y: 10, width: languageBox.bounds.size.width, height: languageBox.bounds.size.height), of: languageBox, preferredEdge: .maxY)
  283. vc.customBoxWidthLayoutConstraint.constant = languageBox.frame.width
  284. }
  285. }
  286. }