KMNHomeViewController.swift 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249
  1. //
  2. // KMNHomeViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by Niehaoyu on 2024/10/8.
  6. //
  7. import Cocoa
  8. import KMComponentLibrary
  9. class KMNHomeViewController: NSViewController {
  10. @IBOutlet var leftContendBox: NSBox!
  11. @IBOutlet var leftDivider: ComponentDivider!
  12. @IBOutlet var homeOpenView: KMHomeOpenView!
  13. @IBOutlet var homeRecommondView: KMHomeRecommondView!
  14. @IBOutlet var rightContendBox: NSBox!
  15. @IBOutlet var rightInfoView: KMHomeRightView!
  16. @IBOutlet var homeDragView: KMHomeDragView!
  17. var demoVC: WCCompWindowController = WCCompWindowController(windowNibName: "WCCompWindowController")
  18. //合并
  19. var mergeWindowController: KMMergeWindowController?
  20. override func viewDidLoad() {
  21. super.viewDidLoad()
  22. // Do view setup here.
  23. self.configLeftContendView()
  24. self.configRightContendView()
  25. self.initAdvertisementData()
  26. homeDragView.delegate = self
  27. }
  28. override func viewDidAppear() {
  29. super.viewDidAppear()
  30. rightInfoView.resetScrollerStyle()
  31. rightInfoView.reloadData()
  32. }
  33. func configLeftContendView() {
  34. leftContendBox.fillColor = ComponentLibrary.shared.getComponentColorFromKey("colorBg/layout-middle")
  35. leftDivider.properties = ComponentDividerProperty(type: .vertical, dash: false)
  36. homeOpenView.delegate = self
  37. self.homeRecommondView.reloadData()
  38. }
  39. func configRightContendView() {
  40. rightContendBox.fillColor = ComponentLibrary.shared.getComponentColorFromKey("colorBg/layout-low")
  41. rightInfoView.delegate = self
  42. rightInfoView.reloadData()
  43. }
  44. func initAdvertisementData() {
  45. KMAdvertisementManager.manager.fetchDataWithResponseObject { [weak self] data, responseObject, error in
  46. KMPrint("获取广告数据成功")
  47. if data != nil {
  48. let content = data!.recommondContent
  49. let item = content?.recommondContentPDFPro
  50. var infos: [KMAdvertisementItemInfo] = []
  51. for info in item?.content ?? [] {
  52. if info.version == "recommondPDF-PDFtoOfficePack" {
  53. if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() == false {
  54. infos.append(info)
  55. }
  56. } else {
  57. infos.append(info)
  58. }
  59. }
  60. item?.content = infos
  61. if KMAdvertisementManager.manager.infoDict.allKeys.count > 0 {
  62. if let adsInfo = KMAdvertisementManager.manager.infoDict["adsInfo"] {
  63. let infoDict: NSDictionary = KMAdvertisementManager.manager.infoDict["adsInfo"] as! NSDictionary
  64. let array: [[String: Any]] = infoDict["content"] as! [[String : Any]]
  65. let arrM = NSMutableArray.init()
  66. for dict in array {
  67. let adsInfo = KMAdsInfo.init()
  68. let mutableDictionary = NSMutableDictionary(dictionary: dict)
  69. adsInfo.infoDict = mutableDictionary
  70. arrM.add(adsInfo)
  71. }
  72. KMAdsInfoManager.shareInstance.adsInfoArrM = arrM
  73. }
  74. if let couponInfo = KMAdvertisementManager.manager.infoDict["couponContent"] {
  75. let infoDict: NSDictionary = KMAdvertisementManager.manager.infoDict["couponContent"] as! NSDictionary
  76. let array: [[String: Any]] = infoDict["content"] as! [[String : Any]]
  77. if array.isEmpty == false {
  78. let dict = array[0]
  79. let adsInfo = KMCouponInfo.init()
  80. let mutableDictionary = NSMutableDictionary(dictionary: dict)
  81. adsInfo.infoDict = mutableDictionary
  82. KMAdsInfoManager.shareInstance.couponInfo = adsInfo
  83. }
  84. }
  85. }
  86. }
  87. DispatchQueue.main.async {
  88. self?.homeRecommondView.reloadData()
  89. }
  90. }
  91. }
  92. @IBAction func showDemo(_ sender: Any) {
  93. demoVC.window?.center()
  94. demoVC.showWindow(nil)
  95. }
  96. }
  97. //MARK: - KMHomeOpenViewDelegate
  98. extension KMNHomeViewController: KMHomeOpenViewDelegate {
  99. func homeOpenViewDidChooseFileURL(_ view: KMHomeOpenView?, _ url: URL) {
  100. self.openFile(withFilePath: url)
  101. }
  102. func homeOpenViewDidChooseImageURLs(_ view: KMHomeOpenView?, _ urls: [URL]) {
  103. self.openImageToPdfWindow(urls: urls)
  104. }
  105. func homeOpenViewDidChooseCreateFromClipboard(_ view: KMHomeOpenView?) {
  106. var error: NSError?
  107. let pboard = NSPasteboard.general
  108. var document = openDocumentWithImageFromPasteboard(pboard, error: &error)
  109. if document == nil{
  110. document = openDocument(withURLFromPasteboard: pboard, showNotes: false, error: &error)
  111. }
  112. }
  113. }
  114. //MARK: - KMHomeRightViewDelegate
  115. extension KMNHomeViewController: KMHomeRightViewDelegate {
  116. //点击管理快捷工具按钮
  117. func homeRightViewDidManageQuickTools(_ view: KMHomeRightView) {
  118. let quickToolWindowController: KMNQuickToolWindowController = KMNQuickToolWindowController.init(windowNibName: "KMNQuickToolWindowController")
  119. quickToolWindowController.delegate = self
  120. quickToolWindowController.own_beginSheetModal(for: self.view.window) { string in
  121. }
  122. }
  123. //点击快捷工具列表中的某一项
  124. func homeRightViewDidQuickToolsItemClicked(_ view: KMHomeRightView, _ toolType: HomeQuickToolType) {
  125. self.quickToolsActionWith(toolType)
  126. }
  127. //最近文件列表删除更新结束后回调
  128. func homeRightViewDidRecentFilesUpdated(_ view: KMHomeRightView) {
  129. }
  130. //选择打开文件
  131. func homeRightViewDidChooseFileToOpen(_ view: KMHomeRightView, _ fileURL: URL) {
  132. self.openFile(withFilePath: fileURL)
  133. }
  134. }
  135. //MARK: - KMNQuickToolWindowDelegate
  136. extension KMNHomeViewController: KMNQuickToolWindowDelegate {
  137. func quickToolWindowControllerUpdate() {
  138. rightInfoView.reloadData()
  139. }
  140. }
  141. //MARK: - KMHomeDragViewDelegate
  142. extension KMNHomeViewController: KMHomeDragViewDelegate {
  143. func homeDragView(_ viewController: KMHomeDragView, filePath: URL) {
  144. self.openFile(withFilePath: filePath)
  145. }
  146. func homeDragView(_ viewController: KMHomeDragView, notSupport: Bool) {
  147. if notSupport {
  148. let alert = NSAlert()
  149. alert.alertStyle = .critical
  150. alert.messageText = NSLocalizedString("This file format is not supported. Please enter PDF, picture, or Office file", comment: "")
  151. alert.runModal()
  152. }
  153. }
  154. }
  155. //MARK: - Open Files
  156. extension KMNHomeViewController {
  157. func openFile(withFilePath path: URL) -> Void {
  158. let type = path.pathExtension.lowercased()
  159. if (type == "pdf") {
  160. self.openHistoryFilePath(url: path)
  161. } else if (type == "jpg") ||
  162. (type == "cur") ||
  163. (type == "bmp") ||
  164. (type == "jpeg") ||
  165. (type == "gif") ||
  166. (type == "png") ||
  167. (type == "tiff") ||
  168. (type == "tif") ||
  169. (type == "ico") ||
  170. (type == "icns") ||
  171. (type == "tga") ||
  172. (type == "psd") ||
  173. (type == "eps") ||
  174. (type == "hdr") ||
  175. (type == "jp2") ||
  176. (type == "jpc") ||
  177. (type == "pict") ||
  178. (type == "sgi") ||
  179. (type == "heic") {
  180. openImageFile(url: path)
  181. } else if (type == "doc") ||
  182. (type == "docx") ||
  183. (type == "xls") ||
  184. (type == "xlsx") ||
  185. (type == "ppt") ||
  186. (type == "pptx") ||
  187. (type == "pptx") {
  188. let fileName: NSString = String(format: "%@.pdf", NSLocalizedString("Untitled", comment: "")) as NSString
  189. let savePath = fetchUniquePath(fileName.kUrlToPDFFolderPath() as String)
  190. openOfficeFile(url: path)
  191. }
  192. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  193. self.rightInfoView.reloadData()
  194. }
  195. }
  196. func openHistoryFilePath(url: URL) -> Void {
  197. if !url.path.isPDFValid() {
  198. let alert = NSAlert()
  199. alert.alertStyle = .critical
  200. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  201. alert.beginSheetModal(for: view.window!) { [weak self] result in
  202. self?.rightInfoView.reloadData()
  203. }
  204. return
  205. }
  206. if url.pathExtension.lowercased() == "pdf" {
  207. let pdfDoc = CPDFDocument.init(url: url)
  208. if pdfDoc != nil {
  209. let document = NSDocumentController.shared.document(for: url)
  210. var alreadyOpen = false
  211. for openDocument in NSDocumentController.shared.documents {
  212. if document == openDocument {
  213. alreadyOpen = true
  214. }
  215. }
  216. if !alreadyOpen {
  217. let controll: KMBrowserWindowController? = self.view.window?.windowController as? KMBrowserWindowController
  218. if controll?.browser?.tabCount() ?? 0 > 1{
  219. if !IAPProductsManager.default().isAvailableAllFunction() {
  220. showLimitWindowAlert(url: url)
  221. return
  222. }else {
  223. }
  224. }
  225. }
  226. KMMainDocument().tryToUnlockDocument(pdfDoc!)
  227. var selectDocument: KMMainDocument? = nil
  228. if ((document?.isKind(of: KMMainDocument.self)) != nil) {
  229. selectDocument = (document as! KMMainDocument)
  230. }
  231. if selectDocument != nil {
  232. if selectDocument?.browser != nil {
  233. let currentIndex = selectDocument?.browser.tabStripModel.index(of: selectDocument) ?? 0
  234. selectDocument?.browser.tabStripModel.selectTabContents(at: Int32(currentIndex), userGesture: true)
  235. let isVisible: Bool = selectDocument?.browser.window.isVisible ?? false
  236. let isMiniaturized: Bool = selectDocument?.browser.window.isMiniaturized ?? false
  237. if isVisible {
  238. selectDocument?.browser.window.orderFront(nil)
  239. } else if isMiniaturized {
  240. selectDocument?.browser.window.orderFront(nil)
  241. }
  242. }
  243. } else {
  244. NSDocumentController.shared.km_safe_openDocument(withContentsOf: url, display: true) { _, _, _ in
  245. }
  246. }
  247. } else {
  248. let alert = NSAlert()
  249. alert.alertStyle = .critical
  250. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  251. alert.beginSheetModal(for: view.window!) { [weak self] result in
  252. self?.rightInfoView.reloadData()
  253. }
  254. }
  255. } else {
  256. NSWorkspace.shared.open(url)
  257. }
  258. }
  259. func openImageFile(url: URL) -> Void {
  260. var filePath = url.path
  261. let fileName: NSString = url.lastPathComponent as NSString
  262. let savePath = fetchUniquePath(fileName.kUrlToPDFFolderPath() as String).deletingLastPathComponent
  263. let imageName = NSString(string: NSString(string: filePath).lastPathComponent).deletingPathExtension
  264. let path = self.fetchDifferentFilePath(filePath: savePath + "/" + imageName + ".pdf")
  265. if (!FileManager.default.fileExists(atPath: path.deletingLastPathComponent as String)) {
  266. try?FileManager.default.createDirectory(atPath: path.deletingLastPathComponent as String, withIntermediateDirectories: true, attributes: nil)
  267. }
  268. if (!FileManager.default.fileExists(atPath: path as String)) {
  269. FileManager.default.createFile(atPath: path as String, contents: nil)
  270. }
  271. let document = CPDFDocument.init()
  272. var success = false
  273. if NSString(string: NSString(string: filePath).lastPathComponent).pathExtension == "png" ||
  274. NSString(string: NSString(string: filePath).lastPathComponent).pathExtension == "PNG" {
  275. let jpgPath = self.fetchDifferentFilePath(filePath: savePath + "/" + imageName + ".jpg")
  276. if (!FileManager.default.fileExists(atPath: jpgPath as String)) {
  277. FileManager.default.createFile(atPath: jpgPath as String, contents: nil)
  278. }
  279. // 加载 PNG 图像
  280. guard let pngImage = NSImage(contentsOfFile: filePath) else {
  281. KMPrint("Failed to load PNG image")
  282. return
  283. }
  284. // 创建 NSBitmapImageRep 对象,并将 PNG 图像绘制到其中
  285. let bitmap = NSBitmapImageRep(data: pngImage.tiffRepresentation!)
  286. guard let bitmap = bitmap else {
  287. return
  288. }
  289. let rect = NSRect(origin: .zero, size: bitmap.size)
  290. bitmap.draw(in: rect)
  291. // 将 PNG 图像数据转换为 JPG 图像数据
  292. guard let jpgData = bitmap.representation(using: .jpeg, properties: [:]) else {
  293. KMPrint("Failed to convert PNG to JPG")
  294. return
  295. }
  296. // 保存 JPG 图像数据到文件
  297. let fileURL = URL(fileURLWithPath: jpgPath)
  298. do {
  299. try jpgData.write(to: fileURL)
  300. filePath = fileURL.path
  301. KMPrint("JPG image saved successfully")
  302. } catch {
  303. KMPrint("Failed to save JPG image: \(error.localizedDescription)")
  304. }
  305. }
  306. let image = NSImage(contentsOfFile: filePath)
  307. let insertPageSuccess = document?.insertPage(image!.size, withImage: filePath, at: document!.pageCount)
  308. if insertPageSuccess != nil {
  309. //信号量控制异步
  310. let semaphore = DispatchSemaphore(value: 0)
  311. DispatchQueue.global().async {
  312. success = ((document?.write(toFile: path)) != nil)
  313. semaphore.signal()
  314. }
  315. semaphore.wait()
  316. } else {
  317. }
  318. if success {
  319. NSDocumentController.shared.km_safe_openDocument(withContentsOf: URL(fileURLWithPath: path), display: true) { document, isOpened, error in
  320. if error != nil {
  321. NSApp.presentError(error!)
  322. } else {
  323. if FileManager.default.fileExists(atPath: filePath) {
  324. try? FileManager.default.removeItem(atPath: filePath)
  325. }
  326. if document is KMMainDocument {
  327. let newDocument = document
  328. (newDocument as! KMMainDocument).isNewCreated = true
  329. }
  330. }
  331. }
  332. }
  333. }
  334. func openOfficeFile(url: URL) -> Void {
  335. let filePath = url.path
  336. let folderPath = "convertToPDF.pdf"
  337. let savePath: String? = folderPath.kUrlToPDFFolderPath() as String
  338. if (!FileManager.default.fileExists(atPath: savePath!.deletingLastPathComponent as String)) {
  339. try?FileManager.default.createDirectory(atPath: savePath!.deletingLastPathComponent as String, withIntermediateDirectories: true, attributes: nil)
  340. }
  341. if (!FileManager.default.fileExists(atPath: savePath! as String)) {
  342. FileManager.default.createFile(atPath: savePath! as String, contents: nil)
  343. }
  344. if savePath == nil {
  345. return
  346. }
  347. KMConvertPDFManager.convertFile(filePath, savePath: savePath!) { success, errorDic in
  348. if errorDic != nil || !success || !FileManager.default.fileExists(atPath: savePath!) {
  349. if FileManager.default.fileExists(atPath: savePath!) {
  350. try?FileManager.default.removeItem(atPath: savePath!)
  351. }
  352. let alert = NSAlert.init()
  353. alert.alertStyle = .critical
  354. var infoString = ""
  355. if errorDic != nil {
  356. for key in (errorDic! as Dictionary).keys {
  357. infoString = infoString.appendingFormat("%@\n", errorDic![key] as! CVarArg)
  358. }
  359. }
  360. alert.informativeText = NSLocalizedString("Please install Microsoft Office to create PDFs from Office files", comment: "")
  361. alert.messageText = NSLocalizedString("Failed to Create PDF", comment: "")
  362. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  363. alert.runModal()
  364. return
  365. }
  366. NSDocumentController.shared.km_safe_openDocument(withContentsOf: URL(fileURLWithPath: savePath!), display: true) { _, _, _ in
  367. }
  368. }
  369. }
  370. func openImageToPdfWindow(urls: Array<URL>) {
  371. self.showBatchWindow(type: .imageToPDF, files: urls)
  372. }
  373. func openDocumentWithImageFromPasteboard(_ pboard: NSPasteboard, error outError: AutoreleasingUnsafeMutablePointer<NSError?>?) -> Any? {
  374. var document: CPDFDocument? = nil
  375. var data: Data? = nil
  376. if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.pdf.rawValue]) {
  377. // pboard.types
  378. data = pboard.data(forType: NSPasteboard.PasteboardType.pdf)
  379. } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.postScript.rawValue]) {
  380. // pboard.types
  381. data = pboard.data(forType: NSPasteboard.PasteboardType.postScript)
  382. } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.tiff.rawValue]) {
  383. // pboard.types
  384. data = convertTIFFDataToPDF(pboard.data(forType: NSPasteboard.PasteboardType.tiff) ?? Data())
  385. } else {
  386. let images = pboard.readObjects(forClasses: [NSImage.self], options: [:])
  387. let strings = pboard.readObjects(forClasses: [NSAttributedString.self], options: [:])
  388. if images?.count ?? 0 > 0 {
  389. data = convertTIFFDataToPDF((images![0] as AnyObject).tiffRepresentation!)
  390. } else if strings?.count ?? 0 > 0 {
  391. data = KMOCTool.convertStringsToPDF(withString: strings ?? [""]) // convertStringsToPDF(strings!)
  392. }
  393. }
  394. if let data = data {
  395. _ = NSDocumentController.shared
  396. document = CPDFDocument(data: data)
  397. let fileName: NSString = String(format: "%@.pdf", NSLocalizedString("Untitled", comment: "")) as NSString
  398. let savePath = fetchUniquePath(fileName.kUrlToPDFFolderPath() as String)
  399. let filePath = savePath.deletingLastPathComponent
  400. if FileManager.default.fileExists(atPath: filePath) == false {
  401. try?FileManager.default.createDirectory(atPath: filePath, withIntermediateDirectories: false)
  402. }
  403. document?.write(to: URL(fileURLWithPath: savePath))
  404. NSDocumentController.shared.openDocument(withContentsOf: URL(fileURLWithPath: savePath), display: true) { document, documentWasAlreadyOpen, error in
  405. if error != nil {
  406. NSApp.presentError(error!)
  407. } else {
  408. if document is KMMainDocument {
  409. let newDocument = document
  410. (newDocument as! KMMainDocument).isNewCreated = true
  411. }
  412. }
  413. }
  414. } else if let outError = outError {
  415. outError.pointee = NSError(domain: "SKDocumentErrorDomain", code: 3, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Unable to load data from clipboard", comment: "Error description")])
  416. }
  417. return document
  418. }
  419. func openDocument(withURLFromPasteboard pboard: NSPasteboard, showNotes: Bool, error outError: inout NSError?) -> Any? {
  420. let theURLs = NSURL.readURLs(from: pboard)
  421. let url = theURLs?.count ?? 0 > 0 ? theURLs?[0] : nil
  422. let theURL: NSURL? = url as? NSURL
  423. let documentC = NSDocumentController.shared
  424. var document: NSDocument? = nil
  425. if (theURL as AnyObject).isFileURL == true {
  426. var _: NSError? = nil
  427. let type = try? documentC.typeForContents(of: theURL as! URL)//ForContents(ofURL: theURL, error: &error)
  428. if showNotes == false || NSDocument.readableTypes.contains(type ?? "") {
  429. documentC.openDocument(withContentsOf: theURL as! URL, display: true, completionHandler: { resultDocument, success, err in
  430. document = resultDocument
  431. })
  432. } else if NSDocument.readableTypes.contains(type ?? "") {
  433. for doc in documentC.documents {
  434. let sel = NSSelectorFromString("sourceFileURL")
  435. if doc.responds(to: sel) && doc.fileURL == theURL as? URL {
  436. document = doc
  437. break
  438. }
  439. }
  440. if let document: NSDocument = document {
  441. document.showWindows()
  442. } else {
  443. if let document = try? documentC.makeUntitledDocument(ofType: KMNotesDocumentType) {
  444. document.fileURL = URL(fileURLWithPath: theURL?.path ?? "")
  445. documentC.addDocument(document)
  446. document.makeWindowControllers()
  447. document.showWindows()
  448. }
  449. }
  450. }
  451. }
  452. return document
  453. }
  454. func showLimitWindowAlert(url: URL?) {
  455. if !KMDataManager.default.isTabbingWin{
  456. KMDataManager.default.isTabbingWin = true
  457. let tabbingWin: KMTabbingHintWindowController = KMTabbingHintWindowController()
  458. tabbingWin.selectCallBack = {[weak self] continueOrNot in
  459. KMDataManager.default.isTabbingWin = false
  460. if continueOrNot {
  461. self?.reopenDocument(forPaths: url)
  462. } else {
  463. }
  464. }
  465. self.km_beginSheet(windowC: tabbingWin)
  466. }
  467. }
  468. func reopenDocument(forPaths path: URL?) -> Void {
  469. if path == nil {
  470. let browser = KMBrowser.init() as KMBrowser
  471. browser.windowController = KMBrowserWindowController.init(browser: browser)
  472. browser.addHomeTabContents()
  473. browser.windowController.showWindow(self)
  474. }else {
  475. let browser = KMBrowser.init() as KMBrowser
  476. browser.windowController = KMBrowserWindowController.init(browser: browser)
  477. browser.addHomeTabContents()
  478. browser.windowController.showWindow(self)
  479. NSDocumentController.shared.km_safe_openDocument(withContentsOf: path!, display: true) { doc, open, err in
  480. }
  481. }
  482. }
  483. func fetchUniquePath(_ originalPath: String) -> String {
  484. var path = originalPath
  485. let dManager = FileManager.default
  486. if !dManager.fileExists(atPath: path) {
  487. if path.extension.count < 1 {
  488. path = path.stringByAppendingPathExtension("pdf")
  489. }
  490. return path
  491. } else {
  492. let originalFullFileName = path.lastPathComponent
  493. let originalFileName = path.lastPathComponent.deletingPathExtension.lastPathComponent
  494. let originalExtension = path.extension
  495. let startIndex: Int = 0
  496. let endIndex: Int = startIndex + originalPath.count - originalFullFileName.count - 1
  497. let fileLocatePath = originalPath.substring(to: endIndex)
  498. var i = 1
  499. while (1 != 0) {
  500. var newName = String(format: "%@%ld", originalFileName, i)
  501. newName = String(format: "%@%@", newName, originalExtension)
  502. let newPath = fileLocatePath.stringByAppendingPathComponent(newName)
  503. if !dManager.fileExists(atPath: newPath) {
  504. return newPath
  505. } else {
  506. i+=1
  507. continue
  508. }
  509. }
  510. }
  511. }
  512. func fetchDifferentFilePath(filePath: String) -> String {
  513. var resultFilePath = filePath
  514. var index: Int = 0
  515. while (FileManager.default.fileExists(atPath: resultFilePath)) {
  516. index += 1
  517. let path = NSString(string: filePath).deletingPathExtension + "(" + String(index) + ")"
  518. resultFilePath = NSString(string: path).appendingPathExtension(NSString(string: filePath).pathExtension)!
  519. }
  520. return resultFilePath;
  521. }
  522. func isDamageImage(image: NSImage?, path: String) -> Bool {
  523. if (image == nil) {
  524. return true
  525. }
  526. let addImageAnnotation = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).last!.appendingPathComponent(Bundle.main.bundleIdentifier!).appendingPathComponent("addImageAnnotation")
  527. if !FileManager.default.fileExists(atPath: addImageAnnotation.path) {
  528. try? FileManager.default.createDirectory(atPath: addImageAnnotation.path, withIntermediateDirectories: false, attributes: nil)
  529. }
  530. guard let data = image!.tiffRepresentation else { return false }
  531. guard let imageRep = NSBitmapImageRep(data: data) else { return false }
  532. imageRep.size = image!.size
  533. var imageData: Data?
  534. if path.lowercased() == "png" {
  535. imageData = imageRep.representation(using: .png, properties: [:])
  536. } else {
  537. imageData = imageRep.representation(using: .jpeg, properties: [:])
  538. }
  539. let rPath: URL = addImageAnnotation.appendingPathComponent(tagString()).appendingPathExtension("png")
  540. if let data = imageData {
  541. try?data.write(to: rPath)
  542. return false
  543. } else {
  544. return true
  545. }
  546. }
  547. func tagString() -> String {
  548. let dateFormatter = DateFormatter()
  549. dateFormatter.dateFormat = "yyMMddHHmmss"
  550. let currentDate = Date()
  551. let randomNum = Int(arc4random_uniform(10000))
  552. let str = String(format: "%@%04d", dateFormatter.string(from: Date()),randomNum)
  553. return str
  554. }
  555. func convertTIFFDataToPDF(_ tiffData: Data) -> Data? {
  556. guard let imsrc = CGImageSourceCreateWithData(tiffData as CFData, [kCGImageSourceTypeIdentifierHint: kUTTypeTIFF] as CFDictionary), CGImageSourceGetCount(imsrc) > 0, let cgImage = CGImageSourceCreateImageAtIndex(imsrc, 0, nil) else { return nil }
  557. let pdfData = NSMutableData(capacity: tiffData.count)
  558. let consumer = CGDataConsumer(data: pdfData! as CFMutableData)!
  559. var rect = CGRect(x: 0, y: 0, width: CGFloat(cgImage.width), height: CGFloat(cgImage.height))
  560. let ctxt = CGContext(consumer: consumer, mediaBox: &rect, nil)
  561. ctxt!.beginPDFPage(nil)
  562. ctxt!.draw(cgImage, in: rect)
  563. ctxt!.endPDFPage()
  564. ctxt!.closePDF()
  565. return pdfData as? Data
  566. }
  567. }
  568. //MARK: - Quick Tools Action
  569. extension KMNHomeViewController {
  570. func quickToolsActionWith(_ type: HomeQuickToolType) {
  571. switch type {
  572. case .Batch:
  573. fastTool_Batch()
  574. break
  575. case .MergePDF:
  576. fastTool_MergePDF()
  577. break
  578. case .ImageToPDF:
  579. imageToPDFAction()
  580. break
  581. case .OCR:
  582. fastTool_OCR()
  583. break
  584. case .ConvertPDF:
  585. fastTool_ConvertPDF()
  586. break
  587. case .PDFToWord:
  588. fastTool_ConvertPDF()
  589. break
  590. case .PDFToExcel:
  591. fastTool_PDFToExcel()
  592. break
  593. case .Compression:
  594. fastTool_Compression()
  595. break
  596. case .PDFToPPT:
  597. fastTool_PDFToPPT()
  598. break
  599. case .Security:
  600. fastTool_Security()
  601. break
  602. case .FileCompare:
  603. fastTool_FileCompare()
  604. break
  605. case .Watermark:
  606. fastTool_Watermark()
  607. break
  608. case .Insert:
  609. fastTool_Insert()
  610. break
  611. case .Extract:
  612. fastTool_Extract()
  613. break
  614. case .DigitalSignature:
  615. break
  616. case .Print:
  617. fastTool_Print()
  618. break
  619. }
  620. }
  621. func imageToPDFAction() {
  622. let openPanel = NSOpenPanel()
  623. openPanel.allowedFileTypes = KMImageToPDFMethod.supportedImageTypes()
  624. //MARK: 允许多选还是单选,如果是付费用户允许多选
  625. openPanel.allowsMultipleSelection = true
  626. openPanel.message = NSLocalizedString("Select images to create a new document. To select multiple files press cmd ⌘ button on keyboard and click on the target files one by one.", comment: "")
  627. if IAPProductsManager.default().isAvailableAllFunction(){
  628. openPanel.allowsMultipleSelection = true
  629. } else {
  630. openPanel.allowsMultipleSelection = false
  631. }
  632. openPanel.beginSheetModal(for: NSWindow.currentWindow()) {[weak self] result in
  633. if result == NSApplication.ModalResponse.OK {
  634. guard let weakSelf = self else { return }
  635. let urls = openPanel.urls as [URL]
  636. weakSelf.openImageToPdfWindow(urls: urls)
  637. }
  638. }
  639. }
  640. func fastTool_Batch() { // Batch
  641. if !IAPProductsManager.default().isAvailableAllFunction(){
  642. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  643. return
  644. }
  645. let batchWindowController = KMBatchWindowController(windowNibName: "KMBatchWindowController")
  646. batchWindowController.window?.makeKeyAndOrderFront("")
  647. }
  648. func fastTool_MergePDF() { // MergePDF
  649. mergeWindowController = KMMergeWindowController(windowNibName: "KMMergeWindowController")
  650. mergeWindowController!.type = .merge
  651. mergeWindowController!.cancelAction = { [unowned self] controller in
  652. self.view.window?.endSheet((self.mergeWindowController!.window)!)
  653. }
  654. view.window?.beginSheet(mergeWindowController!.window!)
  655. }
  656. func fastTool_OCR() { // OCR
  657. if !IAPProductsManager.default().isAvailableAllFunction(){
  658. let winC = KMPurchaseCompareWindowController.sharedInstance()
  659. winC?.showWindow(nil)
  660. return
  661. }
  662. let openPanel = NSOpenPanel()
  663. var arr = KMImageToPDFMethod.supportedImageTypes()
  664. arr.append("pdf")
  665. openPanel.allowedFileTypes = arr
  666. openPanel.allowsMultipleSelection = false
  667. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  668. if result == NSApplication.ModalResponse.OK {
  669. quickOcr(urls: openPanel.urls)
  670. }
  671. }
  672. }
  673. func quickOcr(urls: Array<URL>) {
  674. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  675. var document: CPDFDocument?
  676. for fileURL in urls {
  677. if fileURL.lastPathComponent.pathExtension == "pdf"{
  678. document = CPDFDocument(url: fileURL)
  679. }else{
  680. document = CPDFDocument()
  681. let image = NSImage(contentsOfFile: fileURL.path)
  682. _ = document?.km_insertPage(image!.size, withImage: fileURL.path, at: 0)
  683. }
  684. break
  685. }
  686. if document == nil{
  687. let alert = NSAlert()
  688. alert.alertStyle = .critical
  689. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  690. alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in
  691. if response == .alertFirstButtonReturn {
  692. // Handle cancel action
  693. }
  694. }
  695. return
  696. }
  697. let com = KMOCRPDFWindowController(cpdfDocument: document!, pwd: document!.password)
  698. self.km_beginSheet(windowC: com)
  699. }
  700. }
  701. func fastTool_ConvertPDF() { // 转换PDF
  702. let openPanel = NSOpenPanel()
  703. var arr = KMImageToPDFMethod.supportedImageTypes()
  704. arr.append("pdf")
  705. openPanel.allowedFileTypes = ["pdf","PDF"]
  706. //MARK: 允许多选还是单选,如果是付费用户允许多选
  707. openPanel.allowsMultipleSelection = false
  708. openPanel.beginSheetModal(for: self.view.window!) { [self] (result) in
  709. if result == NSApplication.ModalResponse.OK {
  710. quickConvertPdf(urls: openPanel.urls, type: .WordAdvance)
  711. }
  712. }
  713. }
  714. func quickConvertPdf(urls: Array<URL>, type: KMConvertWithPDFType) {
  715. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  716. // var arr: Array<KMBatchOperateFile> = Array()
  717. // for fileURL in urls {
  718. // let img = NSImage(contentsOfFile: fileURL.path)
  719. // if self.isDamageImage(image: img, path: fileURL.path) {
  720. // let alert = NSAlert()
  721. // alert.alertStyle = .critical
  722. // alert.messageText = String(format: NSLocalizedString("The file \"%@\" could not be opened.", comment: ""), fileURL.path.lastPathComponent)
  723. // alert.informativeText = NSLocalizedString("It may be damaged or use a file format that PDF Reader Pro doesn’t recognize.", comment: "")
  724. // alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
  725. // alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in
  726. // if response == .alertFirstButtonReturn {
  727. // // Handle cancel action
  728. // }
  729. // }
  730. // continue
  731. // }
  732. // let file = KMBatchOperateFile(filePath: fileURL.path, type: .Convert)
  733. // arr.append(file)
  734. // }
  735. self.showBatchWindow(type: .convertPDF, subType: type.rawValue,files: urls)
  736. }
  737. }
  738. func fastTool_PDFToPPT() {
  739. let openPanel = NSOpenPanel()
  740. openPanel.allowedFileTypes = ["pdf","PDF"]
  741. //MARK: 允许多选还是单选,如果是付费用户允许多选
  742. openPanel.allowsMultipleSelection = false
  743. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  744. if result == NSApplication.ModalResponse.OK {
  745. quickConvertPdf(urls: openPanel.urls, type: .PowerPoint)
  746. }
  747. }
  748. }
  749. func fastTool_PDFToExcel() {
  750. let openPanel = NSOpenPanel()
  751. openPanel.allowedFileTypes = ["pdf","PDF"]
  752. //MARK: 允许多选还是单选,如果是付费用户允许多选
  753. openPanel.allowsMultipleSelection = false
  754. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  755. if result == NSApplication.ModalResponse.OK {
  756. quickConvertPdf(urls: openPanel.urls, type: .Excel)
  757. }
  758. }
  759. }
  760. // 压缩
  761. func fastTool_Compression() {
  762. let openPanel = NSOpenPanel()
  763. openPanel.allowedFileTypes = ["pdf","PDF"]
  764. //MARK: 允许多选还是单选,如果是付费用户允许多选
  765. openPanel.allowsMultipleSelection = false
  766. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  767. if result == NSApplication.ModalResponse.OK {
  768. quickCompressPdf(urls: openPanel.urls)
  769. }
  770. }
  771. }
  772. func quickCompressPdf(urls: Array<URL>) {
  773. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  774. self.showBatchWindow(type: .compress, files: urls)
  775. }
  776. }
  777. // 安全
  778. func fastTool_Security() {
  779. let openPanel = NSOpenPanel()
  780. openPanel.allowedFileTypes = ["pdf","PDF"]
  781. //MARK: 允许多选还是单选,如果是付费用户允许多选
  782. openPanel.allowsMultipleSelection = true
  783. openPanel.message = NSLocalizedString("To select multiple files press cmd ⌘ button on keyboard and click on the target files one by one.", comment: "")
  784. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  785. if result == NSApplication.ModalResponse.OK {
  786. quickPassword(urls: openPanel.urls)
  787. }
  788. }
  789. }
  790. func quickPassword(urls: Array<URL>) {
  791. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  792. self.showBatchWindow(type: .security, files: urls)
  793. }
  794. }
  795. func fastTool_FileCompare() { // 文件对比
  796. if !IAPProductsManager.default().isAvailableAllFunction(){
  797. let winC = KMPurchaseCompareWindowController.sharedInstance()
  798. winC?.showWindow(nil)
  799. return
  800. }
  801. let openPanel = NSOpenPanel()
  802. openPanel.allowsMultipleSelection = false
  803. openPanel.allowedFileTypes = ["pdf"]
  804. openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in
  805. if result == .cancel {
  806. return
  807. }
  808. if !openPanel.url!.path.isPDFValid() {
  809. let alert = NSAlert()
  810. alert.alertStyle = .critical
  811. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  812. alert.runModal()
  813. return
  814. }
  815. KMBaseWindowController.checkPassword(url: URL(fileURLWithPath: openPanel.url!.path), type: .owner) { [unowned self] success, resultPassword in
  816. if success {
  817. DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
  818. let controller = KMCompareWindowController(windowNibName: "KMCompareWindowController")
  819. controller.password = resultPassword
  820. controller.filePath = openPanel.url!.path
  821. controller.cancelAction = { [unowned self] contr in
  822. self.view.window?.endSheet((controller.window)!)
  823. }
  824. controller.contentComplete = { [unowned self] controller, pdfCompareContent, result, oldDocument, document in
  825. DispatchQueue.main.async {
  826. self.view.window?.endSheet((controller.window)!)
  827. // self.openContentCompareVC(with: pdfCompareContent, results: result, oldDocument: oldDocument, document: document)
  828. }
  829. }
  830. controller.coveringComplete = { [unowned self] controller, document in
  831. self.view.window?.endSheet((controller.window)!)
  832. // self.openCoveringCompareVC(with: document)
  833. }
  834. controller.fileType = .content
  835. NSWindow.currentWindow().beginSheet(controller.window!)
  836. }
  837. } else {
  838. }
  839. }
  840. }
  841. }
  842. func fastTool_Watermark() { // 水印
  843. if !IAPProductsManager.default().isAvailableAllFunction(){
  844. let winC = KMPurchaseCompareWindowController.sharedInstance()
  845. winC?.showWindow(nil)
  846. return
  847. }
  848. let openPanel = NSOpenPanel()
  849. openPanel.allowedFileTypes = ["pdf","PDF"]
  850. //MARK: 允许多选还是单选,如果是付费用户允许多选
  851. openPanel.allowsMultipleSelection = false
  852. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  853. if result == NSApplication.ModalResponse.OK {
  854. quickWaterMark(urls: openPanel.urls)
  855. }
  856. }
  857. }
  858. func quickWaterMark(urls: Array<URL>) {
  859. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  860. self.showBatchWindow(type: .watermark, files: urls)
  861. }
  862. }
  863. func fastTool_Background() { // 背景
  864. if !IAPProductsManager.default().isAvailableAllFunction(){
  865. let winC = KMPurchaseCompareWindowController.sharedInstance()
  866. winC?.showWindow(nil)
  867. return
  868. }
  869. let openPanel = NSOpenPanel()
  870. openPanel.allowedFileTypes = ["pdf","PDF"]
  871. //MARK: 允许多选还是单选,如果是付费用户允许多选
  872. openPanel.allowsMultipleSelection = false
  873. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  874. if result == NSApplication.ModalResponse.OK {
  875. quickBackgroudMark(urls: openPanel.urls)
  876. }
  877. }
  878. }
  879. func quickBackgroudMark(urls: Array<URL>) {
  880. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  881. self.showBatchWindow(type: .background, files: urls)
  882. }
  883. }
  884. func fastTool_Print() { // 打印
  885. KMPrintWindowController.openFiles(window: self.view.window!)
  886. }
  887. func fastTool_Insert() { // 插入
  888. if !IAPProductsManager.default().isAvailableAllFunction(){
  889. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  890. return
  891. }
  892. let openPanel = NSOpenPanel()
  893. openPanel.prompt = NSLocalizedString("Insert", comment: "")
  894. openPanel.allowsMultipleSelection = false
  895. openPanel.allowedFileTypes = ["pdf"]
  896. openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in
  897. if result == .OK {
  898. let windowC = KMPDFInsertWindowController(fileURL: openPanel.url!)
  899. windowC.callback = { [weak self] idx, params in
  900. if params.count >= 4 {
  901. if let doc = params.first as? CPDFDocument {
  902. self?.savePDFDocument(doc, password: params[1] as? String ?? "")
  903. }
  904. }
  905. self?.km_endSheet()
  906. }
  907. self.km_beginSheet(windowC: windowC)
  908. }
  909. }
  910. }
  911. func savePDFDocument(_ pdf: CPDFDocument, password: String) -> Void {
  912. DispatchQueue.global(qos: .`default`).async {
  913. var isSuccessfully = false
  914. if pdf.isEncrypted {
  915. let dic = [
  916. CPDFDocumentWriteOption.userPasswordOption : password,
  917. CPDFDocumentWriteOption.ownerPasswordOption : password
  918. ]
  919. isSuccessfully = pdf.write(to: pdf.documentURL, withOptions: dic)
  920. } else {
  921. isSuccessfully = pdf.write(to: pdf.documentURL)
  922. }
  923. if !isSuccessfully {
  924. if let data = pdf.dataRepresentation() {
  925. isSuccessfully = NSData(data: data).write(to: pdf.documentURL, atomically: true)
  926. }
  927. }
  928. DispatchQueue.main.sync {
  929. if isSuccessfully {
  930. let workspace = NSWorkspace.shared
  931. let url = URL(fileURLWithPath: pdf.documentURL?.path ?? "")
  932. workspace.activateFileViewerSelecting([url])
  933. } else {
  934. let alert = NSAlert()
  935. alert.alertStyle = .critical
  936. alert.messageText = NSLocalizedString("Failed to insert page(s)!", comment: "")
  937. alert.runModal()
  938. }
  939. }
  940. }
  941. }
  942. func fastTool_Extract() { // 提取
  943. let openPanel = NSOpenPanel()
  944. openPanel.prompt = "提取"
  945. openPanel.allowsMultipleSelection = false
  946. openPanel.allowedFileTypes = ["pdf"]
  947. openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in
  948. if result == .OK {
  949. DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
  950. let insertWindowController: KMPDFInsertPageWindow = KMPDFInsertPageWindow.init(documentPath: openPanel.url!, toolType: .Extract)
  951. insertWindowController.beginSheetExtractModal(for: self.view.window!) { pdfDocument, pages, oneDocumentPerPage, isDeletePage in
  952. self.extractPageAction(pdfDocument, pages, oneDocumentPerPage, isDeletePage)
  953. }
  954. }
  955. }
  956. }
  957. }
  958. func extractPageAction(_ pdfDocument: CPDFDocument, _ pages: [CPDFPage], _ oneDocumentPerPage: Bool, _ isDeletePage: Bool) -> Void {
  959. if pages.count < 1 {
  960. let alert = NSAlert()
  961. alert.alertStyle = .critical
  962. alert.messageText = NSLocalizedString("Please select two or more pages first to organize.", comment: "")
  963. alert.runModal()
  964. return
  965. }
  966. if !oneDocumentPerPage {
  967. let fileName = pdfDocument.getFileNameAccordingSelctPages(pages)
  968. let outputSavePanel = NSSavePanel()
  969. outputSavePanel.allowedFileTypes = ["pdf"]
  970. outputSavePanel.nameFieldStringValue = fileName
  971. outputSavePanel.beginSheetModal(for: self.view.window!) { result in
  972. if result == .OK {
  973. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  974. let saveFilePath = outputSavePanel.url?.path
  975. DispatchQueue.global().async {
  976. var pdf = CPDFDocument.init()
  977. let success = (pdf!.extractAsOneDocument(withPages: pages, savePath: saveFilePath)) as Bool
  978. DispatchQueue.main.async {
  979. if success {
  980. let workspace = NSWorkspace.shared
  981. let url = URL(fileURLWithPath: saveFilePath!)
  982. workspace.activateFileViewerSelecting([url])
  983. if isDeletePage {
  984. for page in pages {
  985. let indexPage = pdfDocument.index(for: page)
  986. pdfDocument.removePage(at: indexPage)
  987. }
  988. }
  989. }
  990. }
  991. }
  992. }
  993. }
  994. }
  995. } else {
  996. let panel = NSOpenPanel()
  997. panel.canChooseFiles = false
  998. panel.canChooseDirectories = true
  999. panel.canCreateDirectories = true
  1000. panel.allowsMultipleSelection = false
  1001. panel.beginSheetModal(for: self.view.window!) { result in
  1002. if result == .OK {
  1003. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  1004. let outputURL = panel.url
  1005. DispatchQueue.global().async {
  1006. let folderName = String(pdfDocument.documentURL!.lastPathComponent.split(separator: ".")[0]) + "_extract"
  1007. var filePath = URL(fileURLWithPath: outputURL!.path).appendingPathComponent(folderName).path
  1008. var i = 1
  1009. let testFilePath = filePath
  1010. while FileManager.default.fileExists(atPath: filePath) {
  1011. filePath = testFilePath + "\(i)"
  1012. i += 1
  1013. }
  1014. try? FileManager.default.createDirectory(atPath: filePath, withIntermediateDirectories: false, attributes: nil)
  1015. let successArray = pdfDocument.extractPerPageDocument(withPages: pages, folerPath: filePath)
  1016. DispatchQueue.main.async {
  1017. if successArray!.count > 0 {
  1018. NSWorkspace.shared.activateFileViewerSelecting(successArray!)
  1019. if !isDeletePage {
  1020. for page in pages {
  1021. let indexPage = pdfDocument.index(for: page)
  1022. pdfDocument.removePage(at: indexPage)
  1023. }
  1024. }
  1025. }
  1026. }
  1027. }
  1028. }
  1029. }
  1030. }
  1031. }
  1032. }
  1033. //MARK: Batch
  1034. func showBatchWindow(type: KMBatchCollectionViewType, subType: Int = 0, files: [URL]?) {
  1035. let batchWindowController = KMBatchWindowController.init(windowNibName: "KMBatchWindowController")
  1036. batchWindowController.window?.makeKeyAndOrderFront("")
  1037. // var datas: [KMBatchProcessingTableViewModel] = []
  1038. // for file in files! {
  1039. // let data = KMBatchProcessingTableViewModel.initWithFilePath(url: file)
  1040. // datas.append(data)
  1041. // }
  1042. batchWindowController.inputData = files ?? []
  1043. batchWindowController.type = type
  1044. batchWindowController.inputSubType = subType
  1045. }
  1046. }