KMCompareWindowController.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. //
  2. // KMCompareWindowController.swift
  3. // PDF Master
  4. //
  5. // Created by lizhe on 2023/11/14.
  6. //
  7. import Cocoa
  8. typealias KMCompareWindowControllerContentComplete = (_ controller: KMCompareWindowController, _ pdfCompareContent: CPDFCompareContent, _ results: [CPDFCompareResults] ,_ oldDocument: CPDFDocument, _ document: CPDFDocument) -> Void
  9. typealias KMCompareWindowControllerCoveringComplete = (_ controller: KMCompareWindowController, _ document: CPDFDocument) -> Void
  10. class KMCompareWindowController: KMBaseWindowController {
  11. @IBOutlet weak var compareView: KMCompareView!
  12. var pdfCompareContent: CPDFCompareContent?
  13. var filePath: String = "" {
  14. didSet {
  15. if compareView != nil {
  16. compareView.filePath = filePath
  17. }
  18. }
  19. }
  20. var fileType: KMCompareFilesType = .content {
  21. didSet {
  22. if compareView != nil {
  23. compareView.fileType = fileType
  24. }
  25. }
  26. }
  27. var contentComplete: KMCompareWindowControllerContentComplete?
  28. var coveringComplete :KMCompareWindowControllerCoveringComplete?
  29. override func windowDidLoad() {
  30. super.windowDidLoad()
  31. // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
  32. compareView.filePath = filePath
  33. compareView.fileType = fileType
  34. compareView.cancelAction = { [unowned self] view in
  35. cancelAction?(self)
  36. }
  37. compareView.doneAction = { [unowned self] view, config in
  38. // self.compareAction(config: config)
  39. }
  40. }
  41. func compareAction(config: KMCompareFilesConfig) {
  42. guard let pdfOldDocument = config.fileOldAttribute.pdfDocument, let pdfNewDocument = config.fileNewAttribute.pdfDocument else {
  43. let alert = NSAlert()
  44. alert.alertStyle = .critical
  45. alert.messageText = NSLocalizedString("Please select two files to compare", comment: "")
  46. alert.runModal()
  47. return
  48. }
  49. let fileManager = FileManager.default
  50. let fileOldPath = config.fileOldAttribute.pdfDocument?.documentURL.path
  51. let fileNewPath = config.fileNewAttribute.pdfDocument?.documentURL.path
  52. if !fileManager.fileExists(atPath: fileOldPath!) || !fileManager.fileExists(atPath: fileNewPath!){
  53. let alert = NSAlert()
  54. alert.alertStyle = .critical
  55. alert.messageText = NSLocalizedString("The file has been deleted, please reselect a file.", comment: "")
  56. alert.runModal()
  57. return
  58. }
  59. if (config.fileNewAttribute.fetchSelectPages().count == 0) ||
  60. (!config.fileNewAttribute.bAllPage && config.fileNewAttribute.pagesString.count < 1) {
  61. let alert = NSAlert()
  62. alert.alertStyle = .critical
  63. alert.messageText = String(format: "%@ %@", (config.fileNewAttribute.pdfDocument?.documentURL.path.lastPathComponent.lastPathComponent)!, NSLocalizedString("Invalid page range. Please reselect the page range.", comment: ""))
  64. alert.runModal()
  65. config.fileNewAttribute.bAllPage = true
  66. config.fileNewAttribute.pagesType = .all
  67. compareView.reloadData()
  68. return
  69. }
  70. if (config.fileOldAttribute.fetchSelectPages().count == 0) || (!config.fileOldAttribute.bAllPage && config.fileOldAttribute.pagesString.count < 1) {
  71. let alert = NSAlert()
  72. alert.alertStyle = .critical
  73. alert.messageText = String(format: "%@ %@", (config.fileOldAttribute.pdfDocument?.documentURL.path.lastPathComponent.lastPathComponent)!, NSLocalizedString("Invalid page range. Please reselect the page range.", comment: ""))
  74. alert.runModal()
  75. config.fileOldAttribute.bAllPage = true
  76. config.fileOldAttribute.pagesType = .all
  77. compareView.reloadData()
  78. return
  79. }
  80. let filePath = config.fileOldAttribute.pdfDocument?.documentURL.path
  81. let pdfDocument = CPDFDocument(url: URL(fileURLWithPath: filePath!))
  82. // if pdfDocument!.isLocked && self.pdfOldDocument?.isLocked == true {
  83. // DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
  84. // let passwordWC = PasswordWindowController(windowNibName: "PasswordWindowController")
  85. // passwordWC.fileURL = URL(fileURLWithPath: filePath)
  86. // passwordWC.beginSheetModalForWindow(self.window) { password in
  87. // if let password = password {
  88. // pdfDocument.unlock(withPassword: password)
  89. // config.fileOldAttribute.pdfDocument = pdfDocument
  90. // config.fileOldAttribute.password = password
  91. // config.fileOldAttribute.bAllPage = true
  92. // config.fileOldAttribute.pagesType = PDFSeleectPageType_AllPages
  93. // self.pdfOldDocument = PDFDocument(url: URL(fileURLWithPath: filePath))
  94. // if self.pdfOldDocument?.isLocked == true {
  95. // self.pdfOldDocument?.unlock(withPassword: password)
  96. // }
  97. // self.oldPDFView.document = self.pdfOldDocument
  98. // self.oldPDFView.autoScales = true
  99. // self.oldPDFView.delegate = self
  100. // self.updateOldFileQKSelectedPathsWithPath(self.pdfOldDocument?.documentURL?.path ?? "")
  101. // self.reloadOldPDFData()
  102. // }
  103. // }
  104. // }
  105. // return
  106. // }
  107. let filePath1 = config.fileNewAttribute.pdfDocument?.documentURL.path
  108. let pdfDocument1 = CPDFDocument(url: URL(fileURLWithPath: filePath1!))
  109. // if pdfDocument1.isLocked && self.pdfNewDocument?.isLocked == true {
  110. // DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
  111. // let passwordWC = PasswordWindowController(windowNibName: "PasswordWindowController")
  112. // passwordWC.fileURL = URL(fileURLWithPath: filePath1)
  113. // passwordWC.beginSheetModalForWindow(self.window) { password in
  114. // if let password = password {
  115. // pdfDocument.unlock(withPassword: password)
  116. // config.fileNewAttribute.pdfDocument = pdfDocument1
  117. // config.fileNewAttribute.password = password
  118. // config.fileNewAttribute.bAllPage = true
  119. // config.fileNewAttribute.pagesType = PDFSeleectPageType_AllPages
  120. // self.pdfNewDocument = PDFDocument(url: URL(fileURLWithPath: filePath1))
  121. // if self.pdfNewDocument?.isLocked == true {
  122. // self.pdfNewDocument?.unlock(withPassword: password)
  123. // }
  124. // self.pdfNewView.document = self.pdfNewDocument
  125. // self.pdfNewView.autoScales = true
  126. // self.pdfNewView.delegate = self
  127. // self.addFileContentView.isHidden = true
  128. // self.updateNewFileQKSelectedPathsWithPath(self.pdfNewDocument?.documentURL?.path ?? "")
  129. // self.reloadNewPDFData()
  130. // }
  131. // }
  132. // }
  133. // return
  134. // }
  135. DispatchQueue.global().async {
  136. let oldDoc = CPDFDocument(url: config.fileOldAttribute.pdfDocument?.documentURL)
  137. if let password = config.fileOldAttribute.password {
  138. oldDoc!.unlock(withPassword: password)
  139. }
  140. let doc = CPDFDocument(url: config.fileNewAttribute.pdfDocument?.documentURL)
  141. if let password = config.fileNewAttribute.password {
  142. doc!.unlock(withPassword: password)
  143. }
  144. // if let compareLoadingWVC = self.compareLoadingWVC {
  145. // compareLoadingWVC.maxPageCount = config.fileOldAttribute.pdfDocument.pageCount + config.fileNewAttribute.pdfDocument.pageCount
  146. // }
  147. // if self._compareCancel {
  148. // return
  149. // }
  150. if self.compareView.fileType == .coverting {
  151. let pdfCompareOverlay = CPDFCompareOverlay(oldDocument: oldDoc, oldPageRange: config.fileOldAttribute.pagesString, newDocument: doc, newPageRange: config.fileNewAttribute.pagesString)
  152. let oldStrokeColor = config.oldStrokeColor
  153. pdfCompareOverlay?.setOldDocumentStroke(oldStrokeColor())
  154. pdfCompareOverlay?.setOldDocumentStrokeOpacity(config.oldStrokeOpacity())
  155. let newStrokeColor = config.newStrokeColor
  156. pdfCompareOverlay?.setNewDocumentStroke(newStrokeColor())
  157. pdfCompareOverlay?.setNewDocumentStrokeOpacity(config.newStrokeOpacity())
  158. pdfCompareOverlay?.setNewDocumentFillOpacity(config.newFillOpacity())
  159. pdfCompareOverlay?.setOldDocumentFillOpacity(config.oldFillOpacity())
  160. pdfCompareOverlay?.setNoFill(config.isNOFill())
  161. pdfCompareOverlay?.setBlendMod(config.blendMod())
  162. if (pdfCompareOverlay?.compare() == true) {
  163. guard let document = pdfCompareOverlay?.comparisonDocument() else {
  164. DispatchQueue.main.async {
  165. let alert = NSAlert()
  166. alert.alertStyle = .critical
  167. alert.messageText = NSLocalizedString("Failure", comment: "")
  168. alert.runModal()
  169. }
  170. return
  171. }
  172. DispatchQueue.main.async {
  173. self.coveringComplete?(self, document)
  174. }
  175. debugPrint("合并成功")
  176. }
  177. } else {
  178. var results: [CPDFCompareResults] = []
  179. var pdfCompareContent: CPDFCompareContent? = nil
  180. // if let _pdfCompareContent = self._pdfCompareContent {
  181. // pdfCompareContent = _pdfCompareContent
  182. // }
  183. //
  184. // if self._compareCancel {
  185. // return
  186. // }
  187. pdfCompareContent = CPDFCompareContent(oldDocument: oldDoc, newDocument: doc)
  188. pdfCompareContent?.setDelete(config.deleteColor())
  189. pdfCompareContent?.setReplace(config.replaceColor())
  190. pdfCompareContent?.setInsert(config.insertColor())
  191. pdfCompareContent?.setDeleteOpacity(config.deleteOpacity())
  192. pdfCompareContent?.setReplaceOpacity(config.replaceOpacity())
  193. pdfCompareContent?.setInsertOpacity(config.insertOpacity())
  194. let maxIndex = max(config.fileOldAttribute.fetchSelectPages().count, config.fileNewAttribute.fetchSelectPages().count)
  195. var compareType: CPDFCompareType = .all
  196. if config.isCompareText() && !config.isCompareImage() {
  197. compareType = .text
  198. } else if !config.isCompareText() && config.isCompareImage() {
  199. compareType = .image
  200. }
  201. // if self._compareCancel {
  202. // return
  203. // }
  204. for i in 0..<maxIndex {
  205. let oldPageIndex: Int
  206. if i >= config.fileOldAttribute.fetchSelectPages().count {
  207. oldPageIndex = Int(oldDoc!.pageCount) + i
  208. } else {
  209. oldPageIndex = Int(truncating: config.fileOldAttribute.fetchSelectPages()[i]) - 1
  210. }
  211. let newPageIndex: Int
  212. if i >= config.fileNewAttribute.fetchSelectPages().count {
  213. newPageIndex = Int(doc!.pageCount) + i
  214. } else {
  215. newPageIndex = Int(truncating: config.fileNewAttribute.fetchSelectPages()[i]) - 1
  216. }
  217. if let compareResults = pdfCompareContent?.compareOldPageIndex(oldPageIndex, newPageIndex: newPageIndex, type: compareType, isDrawHighlight: true) {
  218. results.append(compareResults)
  219. }
  220. // DispatchQueue.main.async {
  221. // if let compareLoadingWVC = self.compareLoadingWVC {
  222. // compareLoadingWVC.progress = CGFloat(i) / CGFloat(maxIndex)
  223. // }
  224. // }
  225. }
  226. // DispatchQueue.main.async {
  227. self.contentComplete?(self, pdfCompareContent!, results, oldDoc!, doc!)
  228. if results.count > 0 {
  229. // Handle success case
  230. } else {
  231. let alert = NSAlert()
  232. alert.alertStyle = .critical
  233. alert.messageText = NSLocalizedString("There is no difference between the two documents.", comment: "")
  234. alert.runModal()
  235. }
  236. // }
  237. }
  238. }
  239. }
  240. }