KMAIOpenPDFFilesVC.swift 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. //
  2. // KMAIOpenPDFFilesVC.swift
  3. // PDF Master
  4. //
  5. // Created by wanjun on 2023/5/22.
  6. //
  7. import Cocoa
  8. class KMAIOpenPDFFilesVC: NSViewController {
  9. @IBOutlet weak var openPDFFilesLabel: NSTextField!
  10. @IBOutlet weak var openPDFFilesImageView: NSImageView!
  11. @IBOutlet weak var selectYourFilesBox: KMBox!
  12. @IBOutlet weak var selectYourFilesLabel: NSTextField!
  13. @IBOutlet weak var selectYourFilesImageView: NSImageView!
  14. @IBOutlet weak var orDropFilesHereToOpenLabel: NSTextField!
  15. @IBOutlet weak var creatPDFLabel: NSTextField!
  16. @IBOutlet weak var newFromFilesLabel: NSTextField!
  17. @IBOutlet weak var newFromFilesImageView: NSImageView!
  18. @IBOutlet weak var newBlankPageLabel: NSTextField!
  19. @IBOutlet weak var newBlankPageImageView: NSImageView!
  20. @IBOutlet weak var importFromScannerLabel: NSTextField!
  21. @IBOutlet weak var importFromScannerImageView: NSImageView!
  22. var deviceBrowserWC: KMDeviceBrowserWindowController?
  23. override func viewDidLoad() {
  24. super.viewDidLoad()
  25. // Do view setup here.
  26. self.initLocalization()
  27. self.initializeUI()
  28. }
  29. // MARK: initialize
  30. func initializeUI() -> Void {
  31. self.openPDFFilesLabel.textColor = NSColor(hex: "#252629")
  32. self.openPDFFilesLabel.font = NSFont.SFProTextSemibold(20.0)
  33. self.openPDFFilesImageView.image = NSImage(named: "icon_empty_addFiles")
  34. self.selectYourFilesBox.cornerRadius = 4.0
  35. self.selectYourFilesBox.fillColor = NSColor(hex: "#1770F4")
  36. self.selectYourFilesLabel.textColor = NSColor(hex: "#FFFFFF")
  37. self.selectYourFilesLabel.font = NSFont.SFProTextRegular(16.0)
  38. self.selectYourFilesImageView.image = NSImage(named: "icon_SelectYourFiles")
  39. self.orDropFilesHereToOpenLabel.textColor = NSColor(hex: "#616469")
  40. self.orDropFilesHereToOpenLabel.font = NSFont.SFProTextRegular(14.0)
  41. self.creatPDFLabel.textColor = NSColor(hex: "#252629")
  42. self.creatPDFLabel.font = NSFont.SFProTextSemibold(20.0)
  43. self.newFromFilesLabel.textColor = NSColor(hex: "#252629")
  44. self.newFromFilesLabel.font = NSFont.SFProTextRegular(16.0)
  45. self.newFromFilesImageView.image = NSImage(named: "icon_empty_NewFromFiles")
  46. self.newBlankPageLabel.textColor = NSColor(hex: "#252629")
  47. self.newBlankPageLabel.font = NSFont.SFProTextRegular(16.0)
  48. self.newBlankPageImageView.image = NSImage(named: "icon_empty_NewBlackPage")
  49. self.importFromScannerLabel.textColor = NSColor(hex: "#252629")
  50. self.importFromScannerLabel.font = NSFont.SFProTextRegular(16.0)
  51. self.importFromScannerImageView.image = NSImage(named: "icon_empty_ImportFromScanner")
  52. self.selectYourFilesBox.moveCallback = { [unowned self](mouseEntered: Bool, mouseBox: KMBox) -> Void in
  53. if mouseEntered {
  54. self.selectYourFilesBox.fillColor = NSColor(hex: "#3F8FF6")
  55. } else {
  56. self.selectYourFilesBox.fillColor = NSColor(hex: "#1770F4")
  57. }
  58. }
  59. self.selectYourFilesBox.downCallback = { [unowned self](downEntered: Bool, mouseBox: KMBox, event) -> Void in
  60. if downEntered {
  61. self.openPDFButtonAction()
  62. }
  63. }
  64. }
  65. func initLocalization() -> Void {
  66. self.openPDFFilesLabel.stringValue = NSLocalizedString("Open PDF Files", comment: "")
  67. self.selectYourFilesLabel.stringValue = NSLocalizedString("Select Your Files", comment: "")
  68. self.orDropFilesHereToOpenLabel.stringValue = NSLocalizedString("or drop files here to open", comment: "")
  69. self.creatPDFLabel.stringValue = NSLocalizedString("Create PDF", comment: "")
  70. self.newFromFilesLabel.stringValue = NSLocalizedString("New From Files", comment: "")
  71. self.newBlankPageLabel.stringValue = NSLocalizedString("New Blank Page", comment: "")
  72. self.importFromScannerLabel.stringValue = NSLocalizedString("Import From Scanner", comment: "")
  73. }
  74. // MARK: Private Methods
  75. func imageToJPG(filePath: String, savePath: String) -> String {
  76. if NSString(string: NSString(string: filePath).lastPathComponent).pathExtension == "png" ||
  77. NSString(string: NSString(string: filePath).lastPathComponent).pathExtension == "PNG" {
  78. let imageName = NSString(string: NSString(string: filePath).lastPathComponent).deletingPathExtension
  79. let jpgPath = self.fetchDifferentFilePath(filePath: savePath + "/" + imageName + ".jpg")
  80. if (!FileManager.default.fileExists(atPath: jpgPath as String)) {
  81. FileManager.default.createFile(atPath: jpgPath as String, contents: nil)
  82. }
  83. // 加载 PNG 图像
  84. guard let pngImage = NSImage(contentsOfFile: filePath) else {
  85. print("Failed to load PNG image")
  86. return filePath
  87. }
  88. // 创建 NSBitmapImageRep 对象,并将 PNG 图像绘制到其中
  89. let bitmap = NSBitmapImageRep(data: pngImage.tiffRepresentation!)
  90. let rect = NSRect(origin: .zero, size: bitmap!.size)
  91. bitmap?.draw(in: rect)
  92. // 将 PNG 图像数据转换为 JPG 图像数据
  93. guard let jpgData = bitmap?.representation(using: .jpeg, properties: [:]) else {
  94. print("Failed to convert PNG to JPG")
  95. return filePath
  96. }
  97. // 保存 JPG 图像数据到文件
  98. let fileURL = URL(fileURLWithPath: jpgPath)
  99. do {
  100. try jpgData.write(to: fileURL)
  101. print("JPG image saved successfully")
  102. return fileURL.path
  103. } catch {
  104. print("Failed to save JPG image: \(error.localizedDescription)")
  105. return filePath
  106. }
  107. }
  108. return filePath
  109. }
  110. func openImageFile(url: URL) -> Void {
  111. let filePath = url.path
  112. let fileName: NSString = url.lastPathComponent as NSString
  113. let savePath = fetchUniquePath(fileName.kUrlToPDFFolderPath()).deletingLastPathComponent
  114. let imageName = NSString(string: NSString(string: filePath).lastPathComponent).deletingPathExtension
  115. let path = self.fetchDifferentFilePath(filePath: savePath + "/" + imageName + ".pdf")
  116. if (!FileManager.default.fileExists(atPath: path.deletingLastPathComponent as String)) {
  117. try?FileManager.default.createDirectory(atPath: path.deletingLastPathComponent as String, withIntermediateDirectories: true, attributes: nil)
  118. }
  119. if (!FileManager.default.fileExists(atPath: path as String)) {
  120. FileManager.default.createFile(atPath: path as String, contents: nil)
  121. }
  122. let document = CPDFDocument.init()
  123. var success = false
  124. let jpgPath = self.imageToJPG(filePath: filePath, savePath: savePath)
  125. //FIXME: 无法插入图片
  126. let image = NSImage(contentsOfFile: jpgPath)
  127. let insertPageSuccess = document?.insertPage(image!.size, withImage: jpgPath, at: document!.pageCount)
  128. if insertPageSuccess != nil {
  129. //信号量控制异步
  130. let semaphore = DispatchSemaphore(value: 0)
  131. DispatchQueue.global().async {
  132. success = ((document?.write(toFile: path)) != nil)
  133. semaphore.signal()
  134. }
  135. semaphore.wait()
  136. } else {
  137. }
  138. if success {
  139. if !path.isPDFValid() {
  140. let alert = NSAlert()
  141. alert.alertStyle = .critical
  142. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  143. alert.runModal()
  144. return
  145. }
  146. NSDocumentController.shared.openDocument(withContentsOf: URL(fileURLWithPath: path), display: true) { document, documentWasAlreadyOpen, error in
  147. if error != nil {
  148. NSApp.presentError(error!)
  149. return
  150. }
  151. }
  152. }
  153. }
  154. func openOfficeFile(url: URL) -> Void {
  155. let filePath = url.path
  156. let folderPath = "convertToPDF.pdf"
  157. let savePath = folderPath.kUrlToPDFFolderPath()
  158. if (!FileManager.default.fileExists(atPath: savePath!.deletingLastPathComponent as String)) {
  159. try?FileManager.default.createDirectory(atPath: savePath!.deletingLastPathComponent as String, withIntermediateDirectories: true, attributes: nil)
  160. }
  161. if (!FileManager.default.fileExists(atPath: savePath! as String)) {
  162. FileManager.default.createFile(atPath: savePath! as String, contents: nil)
  163. }
  164. if savePath == nil {
  165. return
  166. }
  167. KMConvertPDFManagerOC.convertFile(filePath, savePath: savePath!) { success, errorDic in
  168. if errorDic != nil || !success || !FileManager.default.fileExists(atPath: savePath!) {
  169. if FileManager.default.fileExists(atPath: savePath!) {
  170. try?FileManager.default.removeItem(atPath: savePath!)
  171. }
  172. let alert = NSAlert.init()
  173. alert.alertStyle = .critical
  174. var infoString = ""
  175. if errorDic != nil {
  176. for key in (errorDic! as Dictionary).keys {
  177. infoString = infoString.appendingFormat("%@\n", errorDic![key] as! CVarArg)
  178. }
  179. }
  180. alert.informativeText = NSLocalizedString("Please install Microsoft Office to create PDFs from Office files", comment: "")
  181. alert.messageText = NSLocalizedString("Failed to Create PDF", comment: "")
  182. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  183. alert.runModal()
  184. return
  185. }
  186. if !savePath!.isPDFValid() {
  187. let alert = NSAlert()
  188. alert.alertStyle = .critical
  189. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  190. alert.runModal()
  191. return
  192. }
  193. NSDocumentController.shared.openDocument(withContentsOf: URL(fileURLWithPath: savePath!), display: true) { document, documentWasAlreadyOpen, error in
  194. if error != nil {
  195. NSApp.presentError(error!)
  196. return
  197. }
  198. }
  199. }
  200. }
  201. func fetchUniquePath(_ originalPath: String) -> String {
  202. var path = originalPath
  203. let dManager = FileManager.default
  204. if !dManager.fileExists(atPath: path) {
  205. if path.extension.count < 1 {
  206. path = path.stringByAppendingPathExtension("pdf")
  207. }
  208. return path
  209. } else {
  210. let originalFullFileName = path.lastPathComponent
  211. let originalFileName = path.lastPathComponent.deletingPathExtension.lastPathComponent
  212. let originalExtension = path.extension
  213. let startIndex: Int = 0
  214. let endIndex: Int = startIndex + originalPath.count - originalFullFileName.count - 1
  215. let fileLocatePath = originalPath.substring(to: endIndex)
  216. var i = 1
  217. while (1 != 0) {
  218. var newName = String(format: "%@%ld", originalFileName, i)
  219. newName = String(format: "%@%@", newName, originalExtension)
  220. let newPath = fileLocatePath.stringByAppendingPathComponent(newName)
  221. if !dManager.fileExists(atPath: newPath) {
  222. return newPath
  223. } else {
  224. i+=1
  225. continue
  226. }
  227. }
  228. }
  229. }
  230. func fetchDifferentFilePath(filePath: String) -> String {
  231. var resultFilePath = filePath
  232. var index: Int = 0
  233. while (FileManager.default.fileExists(atPath: resultFilePath)) {
  234. index += 1
  235. let path = NSString(string: filePath).deletingPathExtension + "(" + String(index) + ")"
  236. resultFilePath = NSString(string: path).appendingPathExtension(NSString(string: filePath).pathExtension)!
  237. }
  238. return resultFilePath;
  239. }
  240. func openFile(withFilePath path: URL) -> Void {
  241. let type = path.pathExtension.lowercased()
  242. if (type == "pdf") {
  243. if !path.path.isPDFValid() {
  244. let alert = NSAlert()
  245. alert.alertStyle = .critical
  246. alert.messageText = NSLocalizedString("This file format is not supported, please drag in PDF, picture, Office format files", comment: "")
  247. alert.runModal()
  248. return
  249. }
  250. NSDocumentController.shared.openDocument(withContentsOf: path, display: true) { document, documentWasAlreadyOpen, error in
  251. if error != nil {
  252. NSApp.presentError(error!)
  253. return
  254. }
  255. }
  256. } else if (type == "jpg") ||
  257. (type == "cur") ||
  258. (type == "bmp") ||
  259. (type == "jpeg") ||
  260. (type == "gif") ||
  261. (type == "png") ||
  262. (type == "tiff") ||
  263. (type == "tif") ||
  264. (type == "ico") ||
  265. (type == "icns") ||
  266. (type == "tga") ||
  267. (type == "psd") ||
  268. (type == "eps") ||
  269. (type == "hdr") ||
  270. (type == "jp2") ||
  271. (type == "jpc") ||
  272. (type == "pict") ||
  273. (type == "sgi") ||
  274. (type == "heic") {
  275. openImageFile(url: path)
  276. } else if (type == "doc") ||
  277. (type == "docx") ||
  278. (type == "xls") ||
  279. (type == "xlsx") ||
  280. (type == "ppt") ||
  281. (type == "pptx") ||
  282. (type == "pptx") {
  283. let fileName: NSString = String(format: "%@.pdf", NSLocalizedString("Untitled", comment: "")) as NSString
  284. let savePath = fetchUniquePath(fileName.kUrlToPDFFolderPath())
  285. openOfficeFile(url: path)
  286. }
  287. }
  288. // MARK: Action
  289. @IBAction func createPDFAction(_ sender: NSButton) {
  290. let tag = sender.tag;
  291. if tag == 0 {
  292. // New From Files
  293. self.openSupportPDFButtonAction()
  294. } else if tag == 1 {
  295. // New Blank Page
  296. self.openBlankPage("")
  297. } else if tag == 2 {
  298. // Import From Scanner
  299. self.importFromScanner("")
  300. }
  301. }
  302. func openPDFButtonAction() {
  303. let openPanel = NSOpenPanel()
  304. openPanel.allowedFileTypes = ["pdf", "PDF"]
  305. openPanel.allowsMultipleSelection = true
  306. openPanel.beginSheetModal(for: self.view.window!) { result in
  307. if result == .OK {
  308. for url in openPanel.urls {
  309. if !url.path.isPDFValid() {
  310. let alert = NSAlert()
  311. alert.alertStyle = .critical
  312. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  313. alert.runModal()
  314. } else {
  315. NSDocumentController.shared.openDocument(withContentsOf: url, display: true) { document, documentWasAlreadyOpen, error in
  316. if error != nil {
  317. NSApp.presentError(error!)
  318. } else {
  319. }
  320. }
  321. }
  322. }
  323. }
  324. }
  325. }
  326. func openSupportPDFButtonAction() {
  327. let openPanel = NSOpenPanel()
  328. openPanel.allowedFileTypes = ["pdf", "PDF", "jpg", "cur", "bmp", "jpeg", "gif", "png", "tiff", "tif", "ico", "icns", "tga", "psd", "eps", "hdr", "jp2", "jpc", "pict", "sgi", "heic", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "pptx"]
  329. openPanel.allowsMultipleSelection = true
  330. var window = self.view.window
  331. if (window == nil) {
  332. window = NSApp.mainWindow
  333. }
  334. openPanel.beginSheetModal(for: window!) { [self] result in
  335. if result == .OK {
  336. var imageUrl: [URL] = []
  337. for url in openPanel.urls {
  338. let type = url.pathExtension.lowercased()
  339. if (type == "pdf" || type == "PDF") {
  340. if !url.path.isPDFValid() {
  341. let alert = NSAlert()
  342. alert.alertStyle = .critical
  343. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  344. alert.runModal()
  345. } else {
  346. NSDocumentController.shared.openDocument(withContentsOf: url, display: true) { document, documentWasAlreadyOpen, error in
  347. if error != nil {
  348. NSApp.presentError(error!)
  349. return
  350. }
  351. }
  352. }
  353. } else if (type == "jpg") ||
  354. (type == "cur") ||
  355. (type == "bmp") ||
  356. (type == "jpeg") ||
  357. (type == "gif") ||
  358. (type == "png") ||
  359. (type == "tiff") ||
  360. (type == "tif") ||
  361. (type == "ico") ||
  362. (type == "icns") ||
  363. (type == "tga") ||
  364. (type == "psd") ||
  365. (type == "eps") ||
  366. (type == "hdr") ||
  367. (type == "jp2") ||
  368. (type == "jpc") ||
  369. (type == "pict") ||
  370. (type == "sgi") ||
  371. (type == "heic") {
  372. openImageFile(url: url)
  373. } else if (type == "doc") ||
  374. (type == "docx") ||
  375. (type == "xls") ||
  376. (type == "xlsx") ||
  377. (type == "ppt") ||
  378. (type == "pptx") ||
  379. (type == "pptx") {
  380. self.openOfficeFile(url: url)
  381. }
  382. }
  383. }
  384. }
  385. }
  386. @IBAction func openBlankPage(_ sender: Any) {
  387. let fileName: NSString = String(format: "%@.pdf", NSLocalizedString("Untitled", comment: "")) as NSString
  388. let savePath = fetchUniquePath(fileName.kUrlToPDFFolderPath())
  389. if (!FileManager.default.fileExists(atPath: savePath.deletingLastPathComponent as String)) {
  390. try?FileManager.default.createDirectory(atPath: savePath.deletingLastPathComponent as String, withIntermediateDirectories: true, attributes: nil)
  391. }
  392. if (!FileManager.default.fileExists(atPath: savePath as String)) {
  393. FileManager.default.createFile(atPath: savePath as String, contents: nil)
  394. }
  395. let pdfDocument = CPDFDocument()
  396. pdfDocument?.insertPage(CGSize(width: 595, height: 842), at: 0)
  397. pdfDocument?.write(to: URL(fileURLWithPath: savePath))
  398. NSDocumentController.shared.openDocument(withContentsOf: URL(fileURLWithPath: savePath), display: true) { document, documentWasAlreadyOpen, error in
  399. if error != nil {
  400. NSApp.presentError(error!)
  401. } else {
  402. if document is KMMainDocument {
  403. let newDocument = document
  404. (newDocument as! KMMainDocument).isNewCreated = true
  405. }
  406. }
  407. }
  408. }
  409. @IBAction func importFromScanner(_ sender: Any) {
  410. deviceBrowserWC = KMDeviceBrowserWindowController.init(windowNibName: "KMDeviceBrowserWindowController")
  411. deviceBrowserWC!.type = .scanner
  412. deviceBrowserWC!.importScannerFileCallback = { [unowned self](url: NSURL) -> Void in
  413. openFile(withFilePath: url as URL)
  414. }
  415. deviceBrowserWC!.showWindow(NSApp.mainWindow)
  416. }
  417. }