KMNHomeViewController.swift 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340
  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. var arr: Array<KMBatchOperateFile> = Array()
  372. for fileURL in urls {
  373. let img = NSImage(contentsOfFile: fileURL.path)
  374. if self.isDamageImage(image: img, path: fileURL.path) {
  375. let alert = NSAlert()
  376. alert.alertStyle = .critical
  377. alert.messageText = String(format: NSLocalizedString("The file \"%@\" could not be opened.", comment: ""), fileURL.path.lastPathComponent)
  378. alert.informativeText = NSLocalizedString("It may be damaged or use a file format that PDF Reader Pro doesn’t recognize.", comment: "")
  379. alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
  380. alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in
  381. if response == .alertFirstButtonReturn {
  382. // Handle cancel action
  383. }
  384. }
  385. continue
  386. }
  387. let file = KMBatchOperateFile(filePath: fileURL.path, type: .CreatePDF)
  388. arr.append(file)
  389. }
  390. let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController")
  391. if #available(macOS 10.13, *) {
  392. baseWindowController.window?.makeKeyAndOrderFront(nil)
  393. } else {
  394. baseWindowController.showWindow(nil)
  395. }
  396. if arr.count > 0 {
  397. baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: .CreatePDF, files: arr)
  398. }
  399. }
  400. func openDocumentWithImageFromPasteboard(_ pboard: NSPasteboard, error outError: AutoreleasingUnsafeMutablePointer<NSError?>?) -> Any? {
  401. var document: CPDFDocument? = nil
  402. var data: Data? = nil
  403. if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.pdf.rawValue]) {
  404. // pboard.types
  405. data = pboard.data(forType: NSPasteboard.PasteboardType.pdf)
  406. } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.postScript.rawValue]) {
  407. // pboard.types
  408. data = pboard.data(forType: NSPasteboard.PasteboardType.postScript)
  409. } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.tiff.rawValue]) {
  410. // pboard.types
  411. data = convertTIFFDataToPDF(pboard.data(forType: NSPasteboard.PasteboardType.tiff) ?? Data())
  412. } else {
  413. let images = pboard.readObjects(forClasses: [NSImage.self], options: [:])
  414. let strings = pboard.readObjects(forClasses: [NSAttributedString.self], options: [:])
  415. if images?.count ?? 0 > 0 {
  416. data = convertTIFFDataToPDF((images![0] as AnyObject).tiffRepresentation!)
  417. } else if strings?.count ?? 0 > 0 {
  418. data = KMOCTool.convertStringsToPDF(withString: strings ?? [""]) // convertStringsToPDF(strings!)
  419. }
  420. }
  421. if let data = data {
  422. _ = NSDocumentController.shared
  423. document = CPDFDocument(data: data)
  424. let fileName: NSString = String(format: "%@.pdf", NSLocalizedString("Untitled", comment: "")) as NSString
  425. let savePath = fetchUniquePath(fileName.kUrlToPDFFolderPath() as String)
  426. let filePath = savePath.deletingLastPathComponent
  427. if FileManager.default.fileExists(atPath: filePath) == false {
  428. try?FileManager.default.createDirectory(atPath: filePath, withIntermediateDirectories: false)
  429. }
  430. document?.write(to: URL(fileURLWithPath: savePath))
  431. NSDocumentController.shared.openDocument(withContentsOf: URL(fileURLWithPath: savePath), display: true) { document, documentWasAlreadyOpen, error in
  432. if error != nil {
  433. NSApp.presentError(error!)
  434. } else {
  435. if document is KMMainDocument {
  436. let newDocument = document
  437. (newDocument as! KMMainDocument).isNewCreated = true
  438. }
  439. }
  440. }
  441. } else if let outError = outError {
  442. outError.pointee = NSError(domain: "SKDocumentErrorDomain", code: 3, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Unable to load data from clipboard", comment: "Error description")])
  443. }
  444. return document
  445. }
  446. func openDocument(withURLFromPasteboard pboard: NSPasteboard, showNotes: Bool, error outError: inout NSError?) -> Any? {
  447. let theURLs = NSURL.readURLs(from: pboard)
  448. let url = theURLs?.count ?? 0 > 0 ? theURLs?[0] : nil
  449. let theURL: NSURL? = url as? NSURL
  450. let documentC = NSDocumentController.shared
  451. var document: NSDocument? = nil
  452. if (theURL as AnyObject).isFileURL == true {
  453. var _: NSError? = nil
  454. let type = try? documentC.typeForContents(of: theURL as! URL)//ForContents(ofURL: theURL, error: &error)
  455. if showNotes == false || NSDocument.readableTypes.contains(type ?? "") {
  456. documentC.openDocument(withContentsOf: theURL as! URL, display: true, completionHandler: { resultDocument, success, err in
  457. document = resultDocument
  458. })
  459. } else if NSDocument.readableTypes.contains(type ?? "") {
  460. for doc in documentC.documents {
  461. let sel = NSSelectorFromString("sourceFileURL")
  462. if doc.responds(to: sel) && doc.fileURL == theURL as? URL {
  463. document = doc
  464. break
  465. }
  466. }
  467. if let document: NSDocument = document {
  468. document.showWindows()
  469. } else {
  470. if let document = try? documentC.makeUntitledDocument(ofType: KMNotesDocumentType) {
  471. document.fileURL = URL(fileURLWithPath: theURL?.path ?? "")
  472. documentC.addDocument(document)
  473. document.makeWindowControllers()
  474. document.showWindows()
  475. }
  476. }
  477. }
  478. }
  479. return document
  480. }
  481. func showLimitWindowAlert(url: URL?) {
  482. if !KMDataManager.default.isTabbingWin{
  483. KMDataManager.default.isTabbingWin = true
  484. let tabbingWin: KMTabbingHintWindowController = KMTabbingHintWindowController()
  485. tabbingWin.selectCallBack = {[weak self] continueOrNot in
  486. KMDataManager.default.isTabbingWin = false
  487. if continueOrNot {
  488. self?.reopenDocument(forPaths: url)
  489. } else {
  490. }
  491. }
  492. self.km_beginSheet(windowC: tabbingWin)
  493. }
  494. }
  495. func reopenDocument(forPaths path: URL?) -> Void {
  496. if path == nil {
  497. let browser = KMBrowser.init() as KMBrowser
  498. browser.windowController = KMBrowserWindowController.init(browser: browser)
  499. browser.addHomeTabContents()
  500. browser.windowController.showWindow(self)
  501. }else {
  502. let browser = KMBrowser.init() as KMBrowser
  503. browser.windowController = KMBrowserWindowController.init(browser: browser)
  504. browser.addHomeTabContents()
  505. browser.windowController.showWindow(self)
  506. NSDocumentController.shared.km_safe_openDocument(withContentsOf: path!, display: true) { doc, open, err in
  507. }
  508. }
  509. }
  510. func fetchUniquePath(_ originalPath: String) -> String {
  511. var path = originalPath
  512. let dManager = FileManager.default
  513. if !dManager.fileExists(atPath: path) {
  514. if path.extension.count < 1 {
  515. path = path.stringByAppendingPathExtension("pdf")
  516. }
  517. return path
  518. } else {
  519. let originalFullFileName = path.lastPathComponent
  520. let originalFileName = path.lastPathComponent.deletingPathExtension.lastPathComponent
  521. let originalExtension = path.extension
  522. let startIndex: Int = 0
  523. let endIndex: Int = startIndex + originalPath.count - originalFullFileName.count - 1
  524. let fileLocatePath = originalPath.substring(to: endIndex)
  525. var i = 1
  526. while (1 != 0) {
  527. var newName = String(format: "%@%ld", originalFileName, i)
  528. newName = String(format: "%@%@", newName, originalExtension)
  529. let newPath = fileLocatePath.stringByAppendingPathComponent(newName)
  530. if !dManager.fileExists(atPath: newPath) {
  531. return newPath
  532. } else {
  533. i+=1
  534. continue
  535. }
  536. }
  537. }
  538. }
  539. func fetchDifferentFilePath(filePath: String) -> String {
  540. var resultFilePath = filePath
  541. var index: Int = 0
  542. while (FileManager.default.fileExists(atPath: resultFilePath)) {
  543. index += 1
  544. let path = NSString(string: filePath).deletingPathExtension + "(" + String(index) + ")"
  545. resultFilePath = NSString(string: path).appendingPathExtension(NSString(string: filePath).pathExtension)!
  546. }
  547. return resultFilePath;
  548. }
  549. func isDamageImage(image: NSImage?, path: String) -> Bool {
  550. if (image == nil) {
  551. return true
  552. }
  553. let addImageAnnotation = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).last!.appendingPathComponent(Bundle.main.bundleIdentifier!).appendingPathComponent("addImageAnnotation")
  554. if !FileManager.default.fileExists(atPath: addImageAnnotation.path) {
  555. try? FileManager.default.createDirectory(atPath: addImageAnnotation.path, withIntermediateDirectories: false, attributes: nil)
  556. }
  557. guard let data = image!.tiffRepresentation else { return false }
  558. guard let imageRep = NSBitmapImageRep(data: data) else { return false }
  559. imageRep.size = image!.size
  560. var imageData: Data?
  561. if path.lowercased() == "png" {
  562. imageData = imageRep.representation(using: .png, properties: [:])
  563. } else {
  564. imageData = imageRep.representation(using: .jpeg, properties: [:])
  565. }
  566. let rPath: URL = addImageAnnotation.appendingPathComponent(tagString()).appendingPathExtension("png")
  567. if let data = imageData {
  568. try?data.write(to: rPath)
  569. return false
  570. } else {
  571. return true
  572. }
  573. }
  574. func tagString() -> String {
  575. let dateFormatter = DateFormatter()
  576. dateFormatter.dateFormat = "yyMMddHHmmss"
  577. let currentDate = Date()
  578. let randomNum = Int(arc4random_uniform(10000))
  579. let str = String(format: "%@%04d", dateFormatter.string(from: Date()),randomNum)
  580. return str
  581. }
  582. func convertTIFFDataToPDF(_ tiffData: Data) -> Data? {
  583. guard let imsrc = CGImageSourceCreateWithData(tiffData as CFData, [kCGImageSourceTypeIdentifierHint: kUTTypeTIFF] as CFDictionary), CGImageSourceGetCount(imsrc) > 0, let cgImage = CGImageSourceCreateImageAtIndex(imsrc, 0, nil) else { return nil }
  584. let pdfData = NSMutableData(capacity: tiffData.count)
  585. let consumer = CGDataConsumer(data: pdfData! as CFMutableData)!
  586. var rect = CGRect(x: 0, y: 0, width: CGFloat(cgImage.width), height: CGFloat(cgImage.height))
  587. let ctxt = CGContext(consumer: consumer, mediaBox: &rect, nil)
  588. ctxt!.beginPDFPage(nil)
  589. ctxt!.draw(cgImage, in: rect)
  590. ctxt!.endPDFPage()
  591. ctxt!.closePDF()
  592. return pdfData as? Data
  593. }
  594. }
  595. //MARK: - Quick Tools Action
  596. extension KMNHomeViewController {
  597. func quickToolsActionWith(_ type: HomeQuickToolType) {
  598. switch type {
  599. case .Batch:
  600. fastTool_Batch()
  601. break
  602. case .MergePDF:
  603. fastTool_MergePDF()
  604. break
  605. case .ImageToPDF:
  606. imageToPDFAction()
  607. break
  608. case .OCR:
  609. fastTool_OCR()
  610. break
  611. case .ConvertPDF:
  612. fastTool_ConvertPDF()
  613. break
  614. case .PDFToWord:
  615. fastTool_ConvertPDF()
  616. break
  617. case .PDFToExcel:
  618. fastTool_PDFToExcel()
  619. break
  620. case .Compression:
  621. fastTool_Compression()
  622. break
  623. case .PDFToPPT:
  624. fastTool_PDFToPPT()
  625. break
  626. case .Security:
  627. fastTool_Security()
  628. break
  629. case .FileCompare:
  630. fastTool_FileCompare()
  631. break
  632. case .Watermark:
  633. fastTool_Watermark()
  634. break
  635. case .Insert:
  636. fastTool_Insert()
  637. break
  638. case .Extract:
  639. fastTool_Extract()
  640. break
  641. case .DigitalSignature:
  642. break
  643. case .Print:
  644. fastTool_Print()
  645. break
  646. }
  647. }
  648. func imageToPDFAction() {
  649. let openPanel = NSOpenPanel()
  650. openPanel.allowedFileTypes = KMImageToPDFMethod.supportedImageTypes()
  651. //MARK: 允许多选还是单选,如果是付费用户允许多选
  652. openPanel.allowsMultipleSelection = true
  653. 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: "")
  654. if IAPProductsManager.default().isAvailableAllFunction(){
  655. openPanel.allowsMultipleSelection = true
  656. } else {
  657. openPanel.allowsMultipleSelection = false
  658. }
  659. openPanel.beginSheetModal(for: NSWindow.currentWindow()) {[weak self] result in
  660. if result == NSApplication.ModalResponse.OK {
  661. guard let weakSelf = self else { return }
  662. let urls = openPanel.urls as [URL]
  663. weakSelf.openImageToPdfWindow(urls: urls)
  664. }
  665. }
  666. }
  667. func fastTool_Batch() { // Batch
  668. if !IAPProductsManager.default().isAvailableAllFunction(){
  669. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  670. return
  671. }
  672. let batchWindowController = KMBatchOperateWindowController.sharedWindowController
  673. batchWindowController.window?.makeKeyAndOrderFront("")
  674. }
  675. func fastTool_MergePDF() { // MergePDF
  676. mergeWindowController = KMMergeWindowController(windowNibName: "KMMergeWindowController")
  677. mergeWindowController!.type = .merge
  678. mergeWindowController!.cancelAction = { [unowned self] controller in
  679. self.view.window?.endSheet((self.mergeWindowController!.window)!)
  680. }
  681. view.window?.beginSheet(mergeWindowController!.window!)
  682. }
  683. func fastTool_OCR() { // OCR
  684. if !IAPProductsManager.default().isAvailableAllFunction(){
  685. let winC = KMPurchaseCompareWindowController.sharedInstance()
  686. winC?.showWindow(nil)
  687. return
  688. }
  689. let openPanel = NSOpenPanel()
  690. var arr = KMImageToPDFMethod.supportedImageTypes()
  691. arr.append("pdf")
  692. openPanel.allowedFileTypes = arr
  693. openPanel.allowsMultipleSelection = false
  694. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  695. if result == NSApplication.ModalResponse.OK {
  696. quickOcr(urls: openPanel.urls)
  697. }
  698. }
  699. }
  700. func quickOcr(urls: Array<URL>) {
  701. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  702. var document: CPDFDocument?
  703. for fileURL in urls {
  704. if fileURL.lastPathComponent.pathExtension == "pdf"{
  705. document = CPDFDocument(url: fileURL)
  706. }else{
  707. document = CPDFDocument()
  708. let image = NSImage(contentsOfFile: fileURL.path)
  709. _ = document?.km_insertPage(image!.size, withImage: fileURL.path, at: 0)
  710. }
  711. break
  712. }
  713. if document == nil{
  714. let alert = NSAlert()
  715. alert.alertStyle = .critical
  716. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  717. alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in
  718. if response == .alertFirstButtonReturn {
  719. // Handle cancel action
  720. }
  721. }
  722. return
  723. }
  724. let com = KMOCRPDFWindowController(cpdfDocument: document!, pwd: document!.password)
  725. self.km_beginSheet(windowC: com)
  726. }
  727. }
  728. func fastTool_ConvertPDF() { // 转换PDF
  729. let openPanel = NSOpenPanel()
  730. var arr = KMImageToPDFMethod.supportedImageTypes()
  731. arr.append("pdf")
  732. openPanel.allowedFileTypes = ["pdf","PDF"]
  733. //MARK: 允许多选还是单选,如果是付费用户允许多选
  734. openPanel.allowsMultipleSelection = false
  735. openPanel.beginSheetModal(for: self.view.window!) { [self] (result) in
  736. if result == NSApplication.ModalResponse.OK {
  737. quickConvertPdf(urls: openPanel.urls, type: .WordAdvance)
  738. }
  739. }
  740. }
  741. func quickConvertPdf(urls: Array<URL>, type: KMConvertWithPDFType) {
  742. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  743. var arr: Array<KMBatchOperateFile> = Array()
  744. for fileURL in urls {
  745. let img = NSImage(contentsOfFile: fileURL.path)
  746. if self.isDamageImage(image: img, path: fileURL.path) {
  747. let alert = NSAlert()
  748. alert.alertStyle = .critical
  749. alert.messageText = String(format: NSLocalizedString("The file \"%@\" could not be opened.", comment: ""), fileURL.path.lastPathComponent)
  750. alert.informativeText = NSLocalizedString("It may be damaged or use a file format that PDF Reader Pro doesn’t recognize.", comment: "")
  751. alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
  752. alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in
  753. if response == .alertFirstButtonReturn {
  754. // Handle cancel action
  755. }
  756. }
  757. continue
  758. }
  759. let file = KMBatchOperateFile(filePath: fileURL.path, type: .Convert)
  760. arr.append(file)
  761. }
  762. let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController")
  763. if #available(macOS 10.13, *) {
  764. baseWindowController.window?.makeKeyAndOrderFront(nil)
  765. } else {
  766. baseWindowController.showWindow(nil)
  767. }
  768. if arr.count > 0 {
  769. baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: .Convert, files: arr)
  770. }
  771. baseWindowController.switchToConvertType(convertType: type)
  772. }
  773. }
  774. func fastTool_PDFToPPT() {
  775. let openPanel = NSOpenPanel()
  776. openPanel.allowedFileTypes = ["pdf","PDF"]
  777. //MARK: 允许多选还是单选,如果是付费用户允许多选
  778. openPanel.allowsMultipleSelection = false
  779. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  780. if result == NSApplication.ModalResponse.OK {
  781. quickConvertPdf(urls: openPanel.urls, type: .PowerPoint)
  782. }
  783. }
  784. }
  785. func fastTool_PDFToExcel() {
  786. let openPanel = NSOpenPanel()
  787. openPanel.allowedFileTypes = ["pdf","PDF"]
  788. //MARK: 允许多选还是单选,如果是付费用户允许多选
  789. openPanel.allowsMultipleSelection = false
  790. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  791. if result == NSApplication.ModalResponse.OK {
  792. quickConvertPdf(urls: openPanel.urls, type: .Excel)
  793. }
  794. }
  795. }
  796. // 压缩
  797. func fastTool_Compression() {
  798. let openPanel = NSOpenPanel()
  799. openPanel.allowedFileTypes = ["pdf","PDF"]
  800. //MARK: 允许多选还是单选,如果是付费用户允许多选
  801. openPanel.allowsMultipleSelection = false
  802. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  803. if result == NSApplication.ModalResponse.OK {
  804. quickCompressPdf(urls: openPanel.urls)
  805. }
  806. }
  807. }
  808. func quickCompressPdf(urls: Array<URL>) {
  809. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  810. var arr: Array<KMBatchOperateFile> = Array()
  811. for fileURL in urls {
  812. let file = KMBatchOperateFile(filePath: fileURL.path, type: .Compress)
  813. arr.append(file)
  814. }
  815. let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController")
  816. if #available(macOS 10.13, *) {
  817. baseWindowController.window?.makeKeyAndOrderFront(nil)
  818. } else {
  819. baseWindowController.showWindow(nil)
  820. }
  821. if arr.count > 0 {
  822. baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: .Compress, files: arr)
  823. }
  824. }
  825. }
  826. // 安全
  827. func fastTool_Security() {
  828. let openPanel = NSOpenPanel()
  829. openPanel.allowedFileTypes = ["pdf","PDF"]
  830. //MARK: 允许多选还是单选,如果是付费用户允许多选
  831. openPanel.allowsMultipleSelection = true
  832. openPanel.message = NSLocalizedString("To select multiple files press cmd ⌘ button on keyboard and click on the target files one by one.", comment: "")
  833. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  834. if result == NSApplication.ModalResponse.OK {
  835. quickPassword(urls: openPanel.urls)
  836. }
  837. }
  838. }
  839. func quickPassword(urls: Array<URL>) {
  840. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  841. var arr: Array<KMBatchOperateFile> = Array()
  842. for fileURL in urls {
  843. // let file = KMBatchOperateFile(filePath: fileURL.path, type: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddPassword : .RemovePassword)
  844. // arr.append(file)
  845. }
  846. let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController")
  847. if #available(macOS 10.13, *) {
  848. baseWindowController.window?.makeKeyAndOrderFront(nil)
  849. } else {
  850. baseWindowController.showWindow(nil)
  851. }
  852. if arr.count > 0 {
  853. // baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddPassword : .RemovePassword, files: arr)
  854. }
  855. }
  856. }
  857. func fastTool_FileCompare() { // 文件对比
  858. if !IAPProductsManager.default().isAvailableAllFunction(){
  859. let winC = KMPurchaseCompareWindowController.sharedInstance()
  860. winC?.showWindow(nil)
  861. return
  862. }
  863. let openPanel = NSOpenPanel()
  864. openPanel.allowsMultipleSelection = false
  865. openPanel.allowedFileTypes = ["pdf"]
  866. openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in
  867. if result == .cancel {
  868. return
  869. }
  870. if !openPanel.url!.path.isPDFValid() {
  871. let alert = NSAlert()
  872. alert.alertStyle = .critical
  873. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  874. alert.runModal()
  875. return
  876. }
  877. KMBaseWindowController.checkPassword(url: URL(fileURLWithPath: openPanel.url!.path), type: .owner) { [unowned self] success, resultPassword in
  878. if success {
  879. DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
  880. let controller = KMCompareWindowController(windowNibName: "KMCompareWindowController")
  881. controller.password = resultPassword
  882. controller.filePath = openPanel.url!.path
  883. controller.cancelAction = { [unowned self] contr in
  884. self.view.window?.endSheet((controller.window)!)
  885. }
  886. controller.contentComplete = { [unowned self] controller, pdfCompareContent, result, oldDocument, document in
  887. DispatchQueue.main.async {
  888. self.view.window?.endSheet((controller.window)!)
  889. // self.openContentCompareVC(with: pdfCompareContent, results: result, oldDocument: oldDocument, document: document)
  890. }
  891. }
  892. controller.coveringComplete = { [unowned self] controller, document in
  893. self.view.window?.endSheet((controller.window)!)
  894. // self.openCoveringCompareVC(with: document)
  895. }
  896. controller.fileType = .content
  897. NSWindow.currentWindow().beginSheet(controller.window!)
  898. }
  899. } else {
  900. }
  901. }
  902. }
  903. }
  904. func fastTool_Watermark() { // 水印
  905. if !IAPProductsManager.default().isAvailableAllFunction(){
  906. let winC = KMPurchaseCompareWindowController.sharedInstance()
  907. winC?.showWindow(nil)
  908. return
  909. }
  910. let openPanel = NSOpenPanel()
  911. openPanel.allowedFileTypes = ["pdf","PDF"]
  912. //MARK: 允许多选还是单选,如果是付费用户允许多选
  913. openPanel.allowsMultipleSelection = false
  914. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  915. if result == NSApplication.ModalResponse.OK {
  916. quickWaterMark(urls: openPanel.urls)
  917. }
  918. }
  919. }
  920. func quickWaterMark(urls: Array<URL>) {
  921. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  922. var arr: Array<KMBatchOperateFile> = Array()
  923. for fileURL in urls {
  924. let pdf = CPDFDocument(url: fileURL)
  925. if !pdf!.allowsPrinting || !pdf!.allowsCopying {
  926. let alert = NSAlert()
  927. alert.alertStyle = .critical
  928. alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "")
  929. alert.runModal()
  930. return
  931. }
  932. // let file = KMBatchOperateFile(filePath: fileURL.path, type: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddWatermark : .RemoveWatermark)
  933. // arr.append(file)
  934. }
  935. let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController")
  936. if #available(macOS 10.13, *) {
  937. baseWindowController.window?.makeKeyAndOrderFront(nil)
  938. } else {
  939. baseWindowController.showWindow(nil)
  940. }
  941. if arr.count > 0 {
  942. // baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddWatermark : .RemoveWatermark, files: arr)
  943. }
  944. }
  945. }
  946. func fastTool_Background() { // 背景
  947. if !IAPProductsManager.default().isAvailableAllFunction(){
  948. let winC = KMPurchaseCompareWindowController.sharedInstance()
  949. winC?.showWindow(nil)
  950. return
  951. }
  952. let openPanel = NSOpenPanel()
  953. openPanel.allowedFileTypes = ["pdf","PDF"]
  954. //MARK: 允许多选还是单选,如果是付费用户允许多选
  955. openPanel.allowsMultipleSelection = false
  956. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  957. if result == NSApplication.ModalResponse.OK {
  958. quickBackgroudMark(urls: openPanel.urls)
  959. }
  960. }
  961. }
  962. func quickBackgroudMark(urls: Array<URL>) {
  963. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  964. var arr: Array<KMBatchOperateFile> = Array()
  965. for fileURL in urls {
  966. let pdf = CPDFDocument(url: fileURL)
  967. if !pdf!.allowsPrinting || !pdf!.allowsCopying {
  968. let alert = NSAlert()
  969. alert.alertStyle = .critical
  970. alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "")
  971. alert.runModal()
  972. return
  973. }
  974. // let file = KMBatchOperateFile(filePath: fileURL.path, type: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddBackground : .RemoveBackground)
  975. // arr.append(file)
  976. }
  977. let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController")
  978. if #available(macOS 10.13, *) {
  979. baseWindowController.window?.makeKeyAndOrderFront(nil)
  980. } else {
  981. baseWindowController.showWindow(nil)
  982. }
  983. if arr.count > 0 {
  984. // baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddBackground : .RemoveBackground, files: arr)
  985. }
  986. }
  987. }
  988. func fastTool_Print() { // 打印
  989. KMPrintWindowController.openFiles(window: self.view.window!)
  990. }
  991. func fastTool_Insert() { // 插入
  992. if !IAPProductsManager.default().isAvailableAllFunction(){
  993. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  994. return
  995. }
  996. let openPanel = NSOpenPanel()
  997. openPanel.prompt = NSLocalizedString("Insert", comment: "")
  998. openPanel.allowsMultipleSelection = false
  999. openPanel.allowedFileTypes = ["pdf"]
  1000. openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in
  1001. if result == .OK {
  1002. let windowC = KMPDFInsertWindowController(fileURL: openPanel.url!)
  1003. windowC.callback = { [weak self] idx, params in
  1004. if params.count >= 4 {
  1005. if let doc = params.first as? CPDFDocument {
  1006. self?.savePDFDocument(doc, password: params[1] as? String ?? "")
  1007. }
  1008. }
  1009. self?.km_endSheet()
  1010. }
  1011. self.km_beginSheet(windowC: windowC)
  1012. }
  1013. }
  1014. }
  1015. func savePDFDocument(_ pdf: CPDFDocument, password: String) -> Void {
  1016. DispatchQueue.global(qos: .`default`).async {
  1017. var isSuccessfully = false
  1018. if pdf.isEncrypted {
  1019. let dic = [
  1020. CPDFDocumentWriteOption.userPasswordOption : password,
  1021. CPDFDocumentWriteOption.ownerPasswordOption : password
  1022. ]
  1023. isSuccessfully = pdf.write(to: pdf.documentURL, withOptions: dic)
  1024. } else {
  1025. isSuccessfully = pdf.write(to: pdf.documentURL)
  1026. }
  1027. if !isSuccessfully {
  1028. if let data = pdf.dataRepresentation() {
  1029. isSuccessfully = NSData(data: data).write(to: pdf.documentURL, atomically: true)
  1030. }
  1031. }
  1032. DispatchQueue.main.sync {
  1033. if isSuccessfully {
  1034. let workspace = NSWorkspace.shared
  1035. let url = URL(fileURLWithPath: pdf.documentURL?.path ?? "")
  1036. workspace.activateFileViewerSelecting([url])
  1037. } else {
  1038. let alert = NSAlert()
  1039. alert.alertStyle = .critical
  1040. alert.messageText = NSLocalizedString("Failed to insert page(s)!", comment: "")
  1041. alert.runModal()
  1042. }
  1043. }
  1044. }
  1045. }
  1046. func fastTool_Extract() { // 提取
  1047. let openPanel = NSOpenPanel()
  1048. openPanel.prompt = "提取"
  1049. openPanel.allowsMultipleSelection = false
  1050. openPanel.allowedFileTypes = ["pdf"]
  1051. openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in
  1052. if result == .OK {
  1053. DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
  1054. let insertWindowController: KMPDFInsertPageWindow = KMPDFInsertPageWindow.init(documentPath: openPanel.url!, toolType: .Extract)
  1055. insertWindowController.beginSheetExtractModal(for: self.view.window!) { pdfDocument, pages, oneDocumentPerPage, isDeletePage in
  1056. self.extractPageAction(pdfDocument, pages, oneDocumentPerPage, isDeletePage)
  1057. }
  1058. }
  1059. }
  1060. }
  1061. }
  1062. func extractPageAction(_ pdfDocument: CPDFDocument, _ pages: [CPDFPage], _ oneDocumentPerPage: Bool, _ isDeletePage: Bool) -> Void {
  1063. if pages.count < 1 {
  1064. let alert = NSAlert()
  1065. alert.alertStyle = .critical
  1066. alert.messageText = NSLocalizedString("Please select two or more pages first to organize.", comment: "")
  1067. alert.runModal()
  1068. return
  1069. }
  1070. if !oneDocumentPerPage {
  1071. let fileName = pdfDocument.getFileNameAccordingSelctPages(pages)
  1072. let outputSavePanel = NSSavePanel()
  1073. outputSavePanel.allowedFileTypes = ["pdf"]
  1074. outputSavePanel.nameFieldStringValue = fileName
  1075. outputSavePanel.beginSheetModal(for: self.view.window!) { result in
  1076. if result == .OK {
  1077. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  1078. let saveFilePath = outputSavePanel.url?.path
  1079. DispatchQueue.global().async {
  1080. var pdf = CPDFDocument.init()
  1081. let success = (pdf!.extractAsOneDocument(withPages: pages, savePath: saveFilePath)) as Bool
  1082. DispatchQueue.main.async {
  1083. if success {
  1084. let workspace = NSWorkspace.shared
  1085. let url = URL(fileURLWithPath: saveFilePath!)
  1086. workspace.activateFileViewerSelecting([url])
  1087. if isDeletePage {
  1088. for page in pages {
  1089. let indexPage = pdfDocument.index(for: page)
  1090. pdfDocument.removePage(at: indexPage)
  1091. }
  1092. }
  1093. }
  1094. }
  1095. }
  1096. }
  1097. }
  1098. }
  1099. } else {
  1100. let panel = NSOpenPanel()
  1101. panel.canChooseFiles = false
  1102. panel.canChooseDirectories = true
  1103. panel.canCreateDirectories = true
  1104. panel.allowsMultipleSelection = false
  1105. panel.beginSheetModal(for: self.view.window!) { result in
  1106. if result == .OK {
  1107. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  1108. let outputURL = panel.url
  1109. DispatchQueue.global().async {
  1110. let folderName = String(pdfDocument.documentURL!.lastPathComponent.split(separator: ".")[0]) + "_extract"
  1111. var filePath = URL(fileURLWithPath: outputURL!.path).appendingPathComponent(folderName).path
  1112. var i = 1
  1113. let testFilePath = filePath
  1114. while FileManager.default.fileExists(atPath: filePath) {
  1115. filePath = testFilePath + "\(i)"
  1116. i += 1
  1117. }
  1118. try? FileManager.default.createDirectory(atPath: filePath, withIntermediateDirectories: false, attributes: nil)
  1119. let successArray = pdfDocument.extractPerPageDocument(withPages: pages, folerPath: filePath)
  1120. DispatchQueue.main.async {
  1121. if successArray!.count > 0 {
  1122. NSWorkspace.shared.activateFileViewerSelecting(successArray!)
  1123. if !isDeletePage {
  1124. for page in pages {
  1125. let indexPage = pdfDocument.index(for: page)
  1126. pdfDocument.removePage(at: indexPage)
  1127. }
  1128. }
  1129. }
  1130. }
  1131. }
  1132. }
  1133. }
  1134. }
  1135. }
  1136. }
  1137. }