KMNHomeViewController.swift 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  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: KMNBaseViewController {
  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. var createWC: KMURLCreatePDFWindowController = KMURLCreatePDFWindowController(windowNibName: "KMURLCreatePDFWindowController")
  19. //合并
  20. var mergeWindowController: KMMergeWindowController?
  21. override func viewDidLoad() {
  22. super.viewDidLoad()
  23. // Do view setup here.
  24. self.configLeftContendView()
  25. self.configRightContendView()
  26. self.initAdvertisementData()
  27. homeDragView.delegate = self
  28. }
  29. override func viewDidAppear() {
  30. super.viewDidAppear()
  31. rightInfoView.resetScrollerStyle()
  32. rightInfoView.reloadData()
  33. }
  34. override func updateUIThemeColor() {
  35. super.updateUIThemeColor()
  36. leftContendBox.fillColor = ComponentLibrary.shared.getComponentColorFromKey("colorBg/layout-middle")
  37. rightContendBox.fillColor = ComponentLibrary.shared.getComponentColorFromKey("colorBg/layout-low")
  38. }
  39. func configLeftContendView() {
  40. leftDivider.properties = ComponentDividerProperty(type: .vertical, dash: false)
  41. homeOpenView.delegate = self
  42. self.homeRecommondView.reloadData()
  43. }
  44. func configRightContendView() {
  45. rightInfoView.delegate = self
  46. rightInfoView.reloadData()
  47. }
  48. func initAdvertisementData() {
  49. KMAdvertisementManager.manager.fetchDataWithResponseObject { [weak self] data, responseObject, error in
  50. KMPrint("获取广告数据成功")
  51. if data != nil {
  52. let content = data!.recommondContent
  53. let item = content?.recommondContentPDFPro
  54. var infos: [KMAdvertisementItemInfo] = []
  55. for info in item?.content ?? [] {
  56. if info.version == "recommondPDF-PDFtoOfficePack" {
  57. if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() == false {
  58. infos.append(info)
  59. }
  60. } else {
  61. infos.append(info)
  62. }
  63. }
  64. item?.content = infos
  65. if KMAdvertisementManager.manager.infoDict.allKeys.count > 0 {
  66. if let adsInfo = KMAdvertisementManager.manager.infoDict["adsInfo"] {
  67. let infoDict: NSDictionary = KMAdvertisementManager.manager.infoDict["adsInfo"] as! NSDictionary
  68. let array: [[String: Any]] = infoDict["content"] as! [[String : Any]]
  69. let arrM = NSMutableArray.init()
  70. for dict in array {
  71. let adsInfo = KMAdsInfo.init()
  72. let mutableDictionary = NSMutableDictionary(dictionary: dict)
  73. adsInfo.infoDict = mutableDictionary
  74. arrM.add(adsInfo)
  75. }
  76. KMAdsInfoManager.shareInstance.adsInfoArrM = arrM
  77. }
  78. if let couponInfo = KMAdvertisementManager.manager.infoDict["couponContent"] {
  79. let infoDict: NSDictionary = KMAdvertisementManager.manager.infoDict["couponContent"] as! NSDictionary
  80. let array: [[String: Any]] = infoDict["content"] as! [[String : Any]]
  81. if array.isEmpty == false {
  82. let dict = array[0]
  83. let adsInfo = KMCouponInfo.init()
  84. let mutableDictionary = NSMutableDictionary(dictionary: dict)
  85. adsInfo.infoDict = mutableDictionary
  86. KMAdsInfoManager.shareInstance.couponInfo = adsInfo
  87. }
  88. }
  89. }
  90. }
  91. DispatchQueue.main.async {
  92. self?.homeRecommondView.reloadData()
  93. }
  94. }
  95. }
  96. @IBAction func showDemo(_ sender: Any) {
  97. demoVC.window?.center()
  98. demoVC.showWindow(nil)
  99. }
  100. func loadOpenFileFunctionGuide(_ showType: KMGuideInfoType) -> Void {
  101. if showType == .messageDiscount && KMGuideInfoWindowController.availableShow(.messageDiscount) {
  102. let guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  103. guideInfoWindowController.type = .messageDiscount
  104. let winC = self.view.window?.windowController as? KMBrowserWindowController
  105. guard let item = winC?.rightMessageVC.discountItemView, item.isHidden == false else {
  106. return
  107. }
  108. guard let win = self.view.window else {
  109. return
  110. }
  111. guideInfoWindowController.targetRect = (win.contentView?.convert(item.frame, from: item.superview)) ?? .zero
  112. guideInfoWindowController.finishHandle = { [weak self] winC, type in
  113. if type == .getIt {
  114. // self?.showAITypeChooseView(aiConfigType: .none)
  115. return
  116. }
  117. }
  118. guideInfoWindowController.autoClose = true
  119. guideInfoWindowController.autoCloseTimeInterval = 5
  120. guideInfoWindowController.window?.collectionBehavior = [.canJoinAllSpaces]
  121. var rect = self.view.window!.frame
  122. rect.size.height += 20
  123. guideInfoWindowController.window?.setFrame(rect, display: false)
  124. guideInfoWindowController.window?.minSize = rect.size
  125. guideInfoWindowController.window?.maxSize = rect.size
  126. self.view.window?.addChildWindow(guideInfoWindowController.window!, ordered: .above)
  127. guideInfoWindowController.show()
  128. }
  129. }
  130. }
  131. //MARK: - KMHomeOpenViewDelegate
  132. extension KMNHomeViewController: KMHomeOpenViewDelegate {
  133. func homeOpenViewDidChooseFileURL(_ view: KMHomeOpenView?, _ url: URL) {
  134. self.openFile(withFilePath: url)
  135. }
  136. }
  137. //MARK: - KMHomeRightViewDelegate
  138. extension KMNHomeViewController: KMHomeRightViewDelegate {
  139. //点击管理快捷工具按钮
  140. func homeRightViewDidManageQuickTools(_ view: KMHomeRightView) {
  141. let quickToolWindowController: KMNQuickToolWindowController = KMNQuickToolWindowController.init(windowNibName: "KMNQuickToolWindowController")
  142. quickToolWindowController.delegate = self
  143. quickToolWindowController.own_beginSheetModal(for: self.view.window) { string in
  144. }
  145. }
  146. //点击快捷工具列表中的某一项
  147. func homeRightViewDidQuickToolsItemClicked(_ view: KMHomeRightView, _ toolType: HomeQuickToolType) {
  148. self.quickToolsActionWith(toolType)
  149. }
  150. //最近文件列表删除更新结束后回调
  151. func homeRightViewDidRecentFilesUpdated(_ view: KMHomeRightView) {
  152. }
  153. //选择打开文件
  154. func homeRightViewDidChooseFileToOpen(_ view: KMHomeRightView, _ fileURL: URL) {
  155. self.openFile(withFilePath: fileURL)
  156. }
  157. }
  158. //MARK: - KMNQuickToolWindowDelegate
  159. extension KMNHomeViewController: KMNQuickToolWindowDelegate {
  160. func quickToolWindowControllerUpdate() {
  161. rightInfoView.reloadData()
  162. }
  163. }
  164. //MARK: - KMHomeDragViewDelegate
  165. extension KMNHomeViewController: KMHomeDragViewDelegate {
  166. func homeDragView(_ viewController: KMHomeDragView, filePath: URL) {
  167. self.openFile(withFilePath: filePath)
  168. }
  169. func homeDragView(_ viewController: KMHomeDragView, notSupport: Bool) {
  170. if notSupport {
  171. let alert = NSAlert()
  172. alert.alertStyle = .critical
  173. alert.messageText = KMLocalizedString("This file format is not supported. Please enter PDF, picture, or Office file")
  174. alert.runModal()
  175. }
  176. }
  177. }
  178. //MARK: - Open Files
  179. extension KMNHomeViewController {
  180. func openFile(withFilePath path: URL) -> Void {
  181. if let _windowC = NSApp.mainWindow?.windowController as? KMBrowserWindowController {
  182. _windowC.openFile(withFilePath: path)
  183. } else {
  184. for window in NSApp.windows {
  185. if let browseWindow = window as? KMBrowserWindow {
  186. if let browseWC = browseWindow.windowController as? KMBrowserWindowController {
  187. browseWC.openFile(withFilePath: path)
  188. break
  189. }
  190. }
  191. }
  192. }
  193. }
  194. func openImageToPdfWindow(urls: Array<URL>) {
  195. if let _windowC = NSApp.mainWindow?.windowController as? KMBrowserWindowController {
  196. _windowC.showBatchWindow(type: .imageToPDF, files: urls)
  197. } else {
  198. for window in NSApp.windows {
  199. if let browseWindow = window as? KMBrowserWindow {
  200. if let browseWC = browseWindow.windowController as? KMBrowserWindowController {
  201. browseWC.showBatchWindow(type: .imageToPDF, files: urls)
  202. break
  203. }
  204. }
  205. }
  206. }
  207. }
  208. func showLimitWindowAlert(url: URL?) {
  209. if !KMDataManager.default.isTabbingWin{
  210. KMDataManager.default.isTabbingWin = true
  211. let tabbingWin: KMTabbingHintWindowController = KMTabbingHintWindowController()
  212. tabbingWin.selectCallBack = {[weak self] continueOrNot in
  213. KMDataManager.default.isTabbingWin = false
  214. if continueOrNot {
  215. self?.reopenDocument(forPaths: url)
  216. } else {
  217. }
  218. }
  219. self.km_beginSheet(windowC: tabbingWin)
  220. }
  221. }
  222. func reopenDocument(forPaths path: URL?) -> Void {
  223. if path == nil {
  224. let browser = KMBrowser.init() as KMBrowser
  225. browser.windowController = KMBrowserWindowController.init(browser: browser)
  226. browser.addHomeTabContents()
  227. browser.windowController.showWindow(self)
  228. }else {
  229. let browser = KMBrowser.init() as KMBrowser
  230. browser.windowController = KMBrowserWindowController.init(browser: browser)
  231. browser.addHomeTabContents()
  232. browser.windowController.showWindow(self)
  233. NSDocumentController.shared.km_safe_openDocument(withContentsOf: path!, display: true) { doc, open, err in
  234. }
  235. }
  236. }
  237. func fetchUniquePath(_ originalPath: String) -> String {
  238. var path = originalPath
  239. let dManager = FileManager.default
  240. if !dManager.fileExists(atPath: path) {
  241. if path.extension.count < 1 {
  242. path = path.stringByAppendingPathExtension("pdf")
  243. }
  244. return path
  245. } else {
  246. let originalFullFileName = path.lastPathComponent
  247. let originalFileName = path.lastPathComponent.deletingPathExtension.lastPathComponent
  248. let originalExtension = path.extension
  249. let startIndex: Int = 0
  250. let endIndex: Int = startIndex + originalPath.count - originalFullFileName.count - 1
  251. let fileLocatePath = originalPath.substring(to: endIndex)
  252. var i = 1
  253. while (1 != 0) {
  254. var newName = String(format: "%@%ld", originalFileName, i)
  255. newName = String(format: "%@%@", newName, originalExtension)
  256. let newPath = fileLocatePath.stringByAppendingPathComponent(newName)
  257. if !dManager.fileExists(atPath: newPath) {
  258. return newPath
  259. } else {
  260. i+=1
  261. continue
  262. }
  263. }
  264. }
  265. }
  266. func fetchDifferentFilePath(filePath: String) -> String {
  267. var resultFilePath = filePath
  268. var index: Int = 0
  269. while (FileManager.default.fileExists(atPath: resultFilePath)) {
  270. index += 1
  271. let path = NSString(string: filePath).deletingPathExtension + "(" + String(index) + ")"
  272. resultFilePath = NSString(string: path).appendingPathExtension(NSString(string: filePath).pathExtension)!
  273. }
  274. return resultFilePath;
  275. }
  276. func isDamageImage(image: NSImage?, path: String) -> Bool {
  277. if (image == nil) {
  278. return true
  279. }
  280. let addImageAnnotation = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).last!.appendingPathComponent(Bundle.main.bundleIdentifier!).appendingPathComponent("addImageAnnotation")
  281. if !FileManager.default.fileExists(atPath: addImageAnnotation.path) {
  282. try? FileManager.default.createDirectory(atPath: addImageAnnotation.path, withIntermediateDirectories: false, attributes: nil)
  283. }
  284. guard let data = image!.tiffRepresentation else { return false }
  285. guard let imageRep = NSBitmapImageRep(data: data) else { return false }
  286. imageRep.size = image!.size
  287. var imageData: Data?
  288. if path.lowercased() == "png" {
  289. imageData = imageRep.representation(using: .png, properties: [:])
  290. } else {
  291. imageData = imageRep.representation(using: .jpeg, properties: [:])
  292. }
  293. let rPath: URL = addImageAnnotation.appendingPathComponent(tagString()).appendingPathExtension("png")
  294. if let data = imageData {
  295. try?data.write(to: rPath)
  296. return false
  297. } else {
  298. return true
  299. }
  300. }
  301. func tagString() -> String {
  302. let dateFormatter = DateFormatter()
  303. dateFormatter.dateFormat = "yyMMddHHmmss"
  304. let currentDate = Date()
  305. let randomNum = Int(arc4random_uniform(10000))
  306. let str = String(format: "%@%04d", dateFormatter.string(from: Date()),randomNum)
  307. return str
  308. }
  309. func convertTIFFDataToPDF(_ tiffData: Data) -> Data? {
  310. guard let imsrc = CGImageSourceCreateWithData(tiffData as CFData, [kCGImageSourceTypeIdentifierHint: kUTTypeTIFF] as CFDictionary), CGImageSourceGetCount(imsrc) > 0, let cgImage = CGImageSourceCreateImageAtIndex(imsrc, 0, nil) else { return nil }
  311. let pdfData = NSMutableData(capacity: tiffData.count)
  312. let consumer = CGDataConsumer(data: pdfData! as CFMutableData)!
  313. var rect = CGRect(x: 0, y: 0, width: CGFloat(cgImage.width), height: CGFloat(cgImage.height))
  314. let ctxt = CGContext(consumer: consumer, mediaBox: &rect, nil)
  315. ctxt!.beginPDFPage(nil)
  316. ctxt!.draw(cgImage, in: rect)
  317. ctxt!.endPDFPage()
  318. ctxt!.closePDF()
  319. return pdfData as? Data
  320. }
  321. }
  322. //MARK: - Quick Tools Action
  323. extension KMNHomeViewController {
  324. func quickToolsActionWith(_ type: HomeQuickToolType) {
  325. switch type {
  326. case .Batch:
  327. fastTool_Batch()
  328. break
  329. case .MergePDF:
  330. fastTool_MergePDF()
  331. break
  332. case .ImageToPDF:
  333. imageToPDFAction()
  334. break
  335. case .OCR:
  336. fastTool_OCR()
  337. break
  338. case .ConvertPDF:
  339. fastTool_ConvertPDF()
  340. break
  341. case .PDFToWord:
  342. fastTool_ConvertPDF()
  343. break
  344. case .PDFToExcel:
  345. fastTool_PDFToExcel()
  346. break
  347. case .Compression:
  348. fastTool_Compression()
  349. break
  350. case .PDFToPPT:
  351. fastTool_PDFToPPT()
  352. break
  353. case .Security:
  354. fastTool_Security()
  355. break
  356. case .FileCompare:
  357. fastTool_FileCompare()
  358. break
  359. case .Watermark:
  360. fastTool_Watermark()
  361. break
  362. case .Insert:
  363. fastTool_Insert()
  364. break
  365. case .Extract:
  366. fastTool_Extract()
  367. break
  368. case .DigitalSignature:
  369. break
  370. case .Print:
  371. fastTool_Print()
  372. break
  373. }
  374. }
  375. func imageToPDFAction() {
  376. let openPanel = NSOpenPanel()
  377. openPanel.allowedFileTypes = KMBatchManager.supportedImageTypes()
  378. //MARK: 允许多选还是单选,如果是付费用户允许多选
  379. openPanel.allowsMultipleSelection = true
  380. 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: "")
  381. if IAPProductsManager.default().isAvailableAllFunction(){
  382. openPanel.allowsMultipleSelection = true
  383. } else {
  384. openPanel.allowsMultipleSelection = false
  385. }
  386. openPanel.beginSheetModal(for: NSWindow.currentWindow()) {[weak self] result in
  387. if result == NSApplication.ModalResponse.OK {
  388. guard let weakSelf = self else { return }
  389. let urls = openPanel.urls as [URL]
  390. weakSelf.openImageToPdfWindow(urls: urls)
  391. }
  392. }
  393. }
  394. func fastTool_Batch() { // Batch
  395. if !IAPProductsManager.default().isAvailableAllFunction(){
  396. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  397. return
  398. }
  399. let batchWindowController = KMBatchWindowController.manager
  400. batchWindowController.window?.makeKeyAndOrderFront("")
  401. }
  402. func fastTool_MergePDF() { // MergePDF
  403. mergeWindowController = KMMergeWindowController(windowNibName: "KMMergeWindowController")
  404. mergeWindowController!.type = .merge
  405. mergeWindowController!.cancelAction = { [unowned self] controller in
  406. self.view.window?.endSheet((self.mergeWindowController!.window)!)
  407. }
  408. view.window?.beginSheet(mergeWindowController!.window!)
  409. }
  410. func fastTool_OCR() { // OCR
  411. if !IAPProductsManager.default().isAvailableAllFunction(){
  412. let winC = KMPurchaseCompareWindowController.sharedInstance()
  413. winC?.showWindow(nil)
  414. return
  415. }
  416. let openPanel = NSOpenPanel()
  417. var arr = KMBatchManager.supportedImageTypes()
  418. arr.append("pdf")
  419. openPanel.allowedFileTypes = arr
  420. openPanel.allowsMultipleSelection = false
  421. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  422. if result == NSApplication.ModalResponse.OK {
  423. quickOcr(urls: openPanel.urls)
  424. }
  425. }
  426. }
  427. func quickOcr(urls: Array<URL>) {
  428. showBatchWindow(type: .OCR, files: urls)
  429. }
  430. func fastTool_ConvertPDF() { // 转换PDF
  431. let openPanel = NSOpenPanel()
  432. var arr = KMBatchManager.supportedImageTypes()
  433. arr.append("pdf")
  434. openPanel.allowedFileTypes = ["pdf","PDF"]
  435. //MARK: 允许多选还是单选,如果是付费用户允许多选
  436. openPanel.allowsMultipleSelection = false
  437. openPanel.beginSheetModal(for: self.view.window!) { [self] (result) in
  438. if result == NSApplication.ModalResponse.OK {
  439. quickConvertPdf(urls: openPanel.urls, type: .WordAdvance)
  440. }
  441. }
  442. }
  443. func quickConvertPdf(urls: Array<URL>, type: KMConvertWithPDFType) {
  444. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  445. self.showBatchWindow(type: .convertPDF, subType: type.rawValue,files: urls)
  446. }
  447. }
  448. func fastTool_PDFToPPT() {
  449. let openPanel = NSOpenPanel()
  450. openPanel.allowedFileTypes = ["pdf","PDF"]
  451. //MARK: 允许多选还是单选,如果是付费用户允许多选
  452. openPanel.allowsMultipleSelection = false
  453. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  454. if result == NSApplication.ModalResponse.OK {
  455. quickConvertPdf(urls: openPanel.urls, type: .PowerPoint)
  456. }
  457. }
  458. }
  459. func fastTool_PDFToExcel() {
  460. let openPanel = NSOpenPanel()
  461. openPanel.allowedFileTypes = ["pdf","PDF"]
  462. //MARK: 允许多选还是单选,如果是付费用户允许多选
  463. openPanel.allowsMultipleSelection = false
  464. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  465. if result == NSApplication.ModalResponse.OK {
  466. quickConvertPdf(urls: openPanel.urls, type: .Excel)
  467. }
  468. }
  469. }
  470. // 压缩
  471. func fastTool_Compression() {
  472. let openPanel = NSOpenPanel()
  473. openPanel.allowedFileTypes = ["pdf","PDF"]
  474. //MARK: 允许多选还是单选,如果是付费用户允许多选
  475. openPanel.allowsMultipleSelection = false
  476. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  477. if result == NSApplication.ModalResponse.OK {
  478. quickCompressPdf(urls: openPanel.urls)
  479. }
  480. }
  481. }
  482. func quickCompressPdf(urls: Array<URL>) {
  483. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  484. self.showBatchWindow(type: .compress, files: urls)
  485. }
  486. }
  487. // 安全
  488. func fastTool_Security() {
  489. let openPanel = NSOpenPanel()
  490. openPanel.allowedFileTypes = ["pdf","PDF"]
  491. //MARK: 允许多选还是单选,如果是付费用户允许多选
  492. openPanel.allowsMultipleSelection = true
  493. openPanel.message = NSLocalizedString("To select multiple files press cmd ⌘ button on keyboard and click on the target files one by one.", comment: "")
  494. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  495. if result == NSApplication.ModalResponse.OK {
  496. quickPassword(urls: openPanel.urls)
  497. }
  498. }
  499. }
  500. func quickPassword(urls: Array<URL>) {
  501. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  502. self.showBatchWindow(type: .security, files: urls)
  503. }
  504. }
  505. func fastTool_FileCompare() { // 文件对比
  506. if !IAPProductsManager.default().isAvailableAllFunction(){
  507. let winC = KMPurchaseCompareWindowController.sharedInstance()
  508. winC?.showWindow(nil)
  509. return
  510. }
  511. let openPanel = NSOpenPanel()
  512. openPanel.allowsMultipleSelection = false
  513. openPanel.allowedFileTypes = ["pdf"]
  514. openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in
  515. if result == .cancel {
  516. return
  517. }
  518. if !openPanel.url!.path.isPDFValid() {
  519. let alert = NSAlert()
  520. alert.alertStyle = .critical
  521. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  522. alert.runModal()
  523. return
  524. }
  525. NSWindowController.checkPassword(url: URL(fileURLWithPath: openPanel.url!.path), type: .owner) { [unowned self] success, resultPassword in
  526. if success {
  527. DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
  528. let controller = KMCompareWindowController(windowNibName: "KMCompareWindowController")
  529. controller.password = resultPassword
  530. controller.filePath = openPanel.url!.path
  531. controller.cancelAction = { [unowned self] contr in
  532. self.view.window?.endSheet((controller.window)!)
  533. }
  534. controller.contentComplete = { [unowned self] controller, pdfCompareContent, result, oldDocument, document in
  535. DispatchQueue.main.async {
  536. self.view.window?.endSheet((controller.window)!)
  537. }
  538. }
  539. controller.coveringComplete = { [unowned self] controller, document in
  540. self.view.window?.endSheet((controller.window)!)
  541. }
  542. controller.fileType = .content
  543. NSWindow.currentWindow().beginSheet(controller.window!)
  544. }
  545. } else {
  546. }
  547. }
  548. }
  549. }
  550. func fastTool_Watermark() { // 水印
  551. if !IAPProductsManager.default().isAvailableAllFunction(){
  552. let winC = KMPurchaseCompareWindowController.sharedInstance()
  553. winC?.showWindow(nil)
  554. return
  555. }
  556. let openPanel = NSOpenPanel()
  557. openPanel.allowedFileTypes = ["pdf","PDF"]
  558. //MARK: 允许多选还是单选,如果是付费用户允许多选
  559. openPanel.allowsMultipleSelection = false
  560. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  561. if result == NSApplication.ModalResponse.OK {
  562. quickWaterMark(urls: openPanel.urls)
  563. }
  564. }
  565. }
  566. func quickWaterMark(urls: Array<URL>) {
  567. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  568. self.showBatchWindow(type: .watermark, files: urls)
  569. }
  570. }
  571. func fastTool_Background() { // 背景
  572. if !IAPProductsManager.default().isAvailableAllFunction(){
  573. let winC = KMPurchaseCompareWindowController.sharedInstance()
  574. winC?.showWindow(nil)
  575. return
  576. }
  577. let openPanel = NSOpenPanel()
  578. openPanel.allowedFileTypes = ["pdf","PDF"]
  579. //MARK: 允许多选还是单选,如果是付费用户允许多选
  580. openPanel.allowsMultipleSelection = false
  581. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  582. if result == NSApplication.ModalResponse.OK {
  583. quickBackgroudMark(urls: openPanel.urls)
  584. }
  585. }
  586. }
  587. func quickBackgroudMark(urls: Array<URL>) {
  588. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  589. self.showBatchWindow(type: .background, files: urls)
  590. }
  591. }
  592. //MARK: 打印
  593. func fastTool_Print() {
  594. let openPanel = NSOpenPanel()
  595. openPanel.allowedFileTypes = ["pdf","PDF"]
  596. openPanel.allowsMultipleSelection = false
  597. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in
  598. if result == NSApplication.ModalResponse.OK {
  599. if let url = openPanel.url {
  600. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  601. self.showPrintWindowWithURL(url)
  602. }
  603. }
  604. }
  605. }
  606. }
  607. func showPrintWindowWithURL(_ url: URL) {
  608. if let cPDFDocument = CPDFDocument(url: url) {
  609. KMPrintWindowController.openDocument(inputDocument: cPDFDocument, inputPageRange: KMPrintPageRange(type: .allPage, selectPages: []))
  610. }
  611. }
  612. func fastTool_Insert() { // 插入
  613. if !IAPProductsManager.default().isAvailableAllFunction(){
  614. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  615. return
  616. }
  617. let openPanel = NSOpenPanel()
  618. openPanel.prompt = NSLocalizedString("Insert", comment: "")
  619. openPanel.allowsMultipleSelection = false
  620. openPanel.allowedFileTypes = ["pdf"]
  621. openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in
  622. if result == .OK {
  623. let windowC = KMPDFInsertWindowController(fileURL: openPanel.url!)
  624. windowC.callback = { [weak self] idx, params in
  625. if params.count >= 4 {
  626. if let doc = params.first as? CPDFDocument {
  627. self?.savePDFDocument(doc, password: params[1] as? String ?? "")
  628. }
  629. }
  630. windowC.own_closeEndSheet()
  631. }
  632. windowC.own_beginSheetModal(for: self.view.window) { result in
  633. }
  634. }
  635. }
  636. }
  637. func savePDFDocument(_ pdf: CPDFDocument, password: String) -> Void {
  638. DispatchQueue.global(qos: .`default`).async {
  639. var isSuccessfully = false
  640. if pdf.isEncrypted {
  641. let dic = [
  642. CPDFDocumentWriteOption.userPasswordOption : password,
  643. CPDFDocumentWriteOption.ownerPasswordOption : password
  644. ]
  645. isSuccessfully = pdf.write(to: pdf.documentURL, withOptions: dic)
  646. } else {
  647. isSuccessfully = pdf.write(to: pdf.documentURL)
  648. }
  649. if !isSuccessfully {
  650. if let data = pdf.dataRepresentation() {
  651. isSuccessfully = NSData(data: data).write(to: pdf.documentURL, atomically: true)
  652. }
  653. }
  654. DispatchQueue.main.sync {
  655. if isSuccessfully {
  656. let workspace = NSWorkspace.shared
  657. let url = URL(fileURLWithPath: pdf.documentURL?.path ?? "")
  658. workspace.activateFileViewerSelecting([url])
  659. } else {
  660. let alert = NSAlert()
  661. alert.alertStyle = .critical
  662. alert.messageText = NSLocalizedString("Failed to insert page(s)!", comment: "")
  663. alert.runModal()
  664. }
  665. }
  666. }
  667. }
  668. func fastTool_Extract() { // 提取
  669. let openPanel = NSOpenPanel()
  670. openPanel.prompt = "提取"
  671. openPanel.allowsMultipleSelection = false
  672. openPanel.allowedFileTypes = ["pdf"]
  673. openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in
  674. if result == .OK {
  675. DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
  676. let insertWindowController: KMPDFInsertPageWindow = KMPDFInsertPageWindow.init(documentPath: openPanel.url!, toolType: .Extract)
  677. insertWindowController.beginSheetExtractModal(for: self.view.window!) { pdfDocument, pages, oneDocumentPerPage, isDeletePage in
  678. self.extractPageAction(pdfDocument, pages, oneDocumentPerPage, isDeletePage)
  679. }
  680. }
  681. }
  682. }
  683. }
  684. func extractPageAction(_ pdfDocument: CPDFDocument, _ pages: [CPDFPage], _ oneDocumentPerPage: Bool, _ isDeletePage: Bool) -> Void {
  685. if pages.count < 1 {
  686. let alert = NSAlert()
  687. alert.alertStyle = .critical
  688. alert.messageText = NSLocalizedString("Please select two or more pages first to organize.", comment: "")
  689. alert.runModal()
  690. return
  691. }
  692. if !oneDocumentPerPage {
  693. let fileName = pdfDocument.getFileNameAccordingSelctPages(pages)
  694. let outputSavePanel = NSSavePanel()
  695. outputSavePanel.allowedFileTypes = ["pdf"]
  696. outputSavePanel.nameFieldStringValue = fileName
  697. outputSavePanel.beginSheetModal(for: self.view.window!) { result in
  698. if result == .OK {
  699. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  700. let saveFilePath = outputSavePanel.url?.path
  701. DispatchQueue.global().async {
  702. let pdf = CPDFDocument.init()
  703. let success = (pdf!.extractAsOneDocument(withPages: pages, savePath: saveFilePath)) as Bool
  704. DispatchQueue.main.async {
  705. if success {
  706. let workspace = NSWorkspace.shared
  707. let url = URL(fileURLWithPath: saveFilePath!)
  708. workspace.activateFileViewerSelecting([url])
  709. if isDeletePage {
  710. for page in pages {
  711. let indexPage = pdfDocument.index(for: page)
  712. pdfDocument.removePage(at: indexPage)
  713. }
  714. }
  715. }
  716. }
  717. }
  718. }
  719. }
  720. }
  721. } else {
  722. let panel = NSOpenPanel()
  723. panel.canChooseFiles = false
  724. panel.canChooseDirectories = true
  725. panel.canCreateDirectories = true
  726. panel.allowsMultipleSelection = false
  727. panel.beginSheetModal(for: self.view.window!) { result in
  728. if result == .OK {
  729. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  730. let outputURL = panel.url
  731. DispatchQueue.global().async {
  732. let folderName = String(pdfDocument.documentURL!.lastPathComponent.split(separator: ".")[0]) + "_extract"
  733. var filePath = URL(fileURLWithPath: outputURL!.path).appendingPathComponent(folderName).path
  734. var i = 1
  735. let testFilePath = filePath
  736. while FileManager.default.fileExists(atPath: filePath) {
  737. filePath = testFilePath + "\(i)"
  738. i += 1
  739. }
  740. try? FileManager.default.createDirectory(atPath: filePath, withIntermediateDirectories: false, attributes: nil)
  741. let successArray = pdfDocument.extractPerPageDocument(withPages: pages, folerPath: filePath)
  742. DispatchQueue.main.async {
  743. if successArray!.count > 0 {
  744. NSWorkspace.shared.activateFileViewerSelecting(successArray!)
  745. if !isDeletePage {
  746. for page in pages {
  747. let indexPage = pdfDocument.index(for: page)
  748. pdfDocument.removePage(at: indexPage)
  749. }
  750. }
  751. }
  752. }
  753. }
  754. }
  755. }
  756. }
  757. }
  758. }
  759. //MARK: Batch
  760. func showBatchWindow(type: KMBatchCollectionViewType, subType: Int = 0, files: [URL]?) {
  761. let batchWindowController = KMBatchWindowController.manager
  762. batchWindowController.window?.makeKeyAndOrderFront("")
  763. // var datas: [KMBatchProcessingTableViewModel] = []
  764. // for file in files! {
  765. // let data = KMBatchProcessingTableViewModel.initWithFilePath(url: file)
  766. // datas.append(data)
  767. // }
  768. batchWindowController.inputData = files ?? []
  769. batchWindowController.type = type
  770. batchWindowController.inputSubType = subType
  771. }
  772. }