KMNHomeViewController.swift 56 KB

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