// // KMCompareWindowController.swift // PDF Master // // Created by lizhe on 2023/11/14. // import Cocoa typealias KMCompareWindowControllerContentComplete = (_ controller: KMCompareWindowController, _ results: [CPDFCompareResults] ,_ oldDocument: CPDFDocument, _ document: CPDFDocument) -> Void typealias KMCompareWindowControllerCoveringComplete = (_ controller: KMCompareWindowController, _ document: CPDFDocument) -> Void class KMCompareWindowController: KMBaseWindowController { @IBOutlet weak var compareView: KMCompareView! var pdfCompareContent: CPDFCompareContent? var filePath: String = "" { didSet { if compareView != nil { compareView.filePath = filePath } } } var fileType: KMCompareFilesType = .content { didSet { if compareView != nil { compareView.fileType = fileType } } } var contentComplete: KMCompareWindowControllerContentComplete? var coveringComplete :KMCompareWindowControllerCoveringComplete? override func windowDidLoad() { super.windowDidLoad() // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. compareView.filePath = filePath compareView.fileType = fileType compareView.cancelAction = { [unowned self] view in cancelAction?(self) } compareView.doneAction = { [unowned self] view, config in } } func compareAction(config: KMCompareFilesConfig) { guard let pdfOldDocument = config.fileOldAttribute.pdfDocument, let pdfNewDocument = config.fileNewAttribute.pdfDocument else { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Please select two files to compare", comment: "") alert.runModal() return } let fileManager = FileManager.default let fileOldPath = config.fileOldAttribute.pdfDocument?.documentURL.path let fileNewPath = config.fileNewAttribute.pdfDocument?.documentURL.path if !fileManager.fileExists(atPath: fileOldPath!) || !fileManager.fileExists(atPath: fileNewPath!){ let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("The file has been deleted, please reselect a file.", comment: "") alert.runModal() return } if (config.fileNewAttribute.fetchSelectPages().count == 0) || (!config.fileNewAttribute.bAllPage && config.fileNewAttribute.pagesString.count < 1) { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = String(format: "%@ %@", (config.fileNewAttribute.pdfDocument?.documentURL.path.lastPathComponent.lastPathComponent)!, NSLocalizedString("Invalid page range. Please reselect the page range.", comment: "")) alert.runModal() config.fileNewAttribute.bAllPage = true config.fileNewAttribute.pagesType = .all compareView.reloadData() return } if (config.fileOldAttribute.fetchSelectPages().count == 0) || (!config.fileOldAttribute.bAllPage && config.fileOldAttribute.pagesString.count < 1) { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = String(format: "%@ %@", (config.fileOldAttribute.pdfDocument?.documentURL.path.lastPathComponent.lastPathComponent)!, NSLocalizedString("Invalid page range. Please reselect the page range.", comment: "")) alert.runModal() config.fileOldAttribute.bAllPage = true config.fileOldAttribute.pagesType = .all compareView.reloadData() return } let filePath = config.fileOldAttribute.pdfDocument?.documentURL.path let pdfDocument = CPDFDocument(url: URL(fileURLWithPath: filePath!)) // if pdfDocument!.isLocked && self.pdfOldDocument?.isLocked == true { // DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) { // let passwordWC = PasswordWindowController(windowNibName: "PasswordWindowController") // passwordWC.fileURL = URL(fileURLWithPath: filePath) // passwordWC.beginSheetModalForWindow(self.window) { password in // if let password = password { // pdfDocument.unlock(withPassword: password) // config.fileOldAttribute.pdfDocument = pdfDocument // config.fileOldAttribute.password = password // config.fileOldAttribute.bAllPage = true // config.fileOldAttribute.pagesType = PDFSeleectPageType_AllPages // self.pdfOldDocument = PDFDocument(url: URL(fileURLWithPath: filePath)) // if self.pdfOldDocument?.isLocked == true { // self.pdfOldDocument?.unlock(withPassword: password) // } // self.oldPDFView.document = self.pdfOldDocument // self.oldPDFView.autoScales = true // self.oldPDFView.delegate = self // self.updateOldFileQKSelectedPathsWithPath(self.pdfOldDocument?.documentURL?.path ?? "") // self.reloadOldPDFData() // } // } // } // return // } let filePath1 = config.fileNewAttribute.pdfDocument?.documentURL.path let pdfDocument1 = CPDFDocument(url: URL(fileURLWithPath: filePath1!)) // if pdfDocument1.isLocked && self.pdfNewDocument?.isLocked == true { // DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) { // let passwordWC = PasswordWindowController(windowNibName: "PasswordWindowController") // passwordWC.fileURL = URL(fileURLWithPath: filePath1) // passwordWC.beginSheetModalForWindow(self.window) { password in // if let password = password { // pdfDocument.unlock(withPassword: password) // config.fileNewAttribute.pdfDocument = pdfDocument1 // config.fileNewAttribute.password = password // config.fileNewAttribute.bAllPage = true // config.fileNewAttribute.pagesType = PDFSeleectPageType_AllPages // self.pdfNewDocument = PDFDocument(url: URL(fileURLWithPath: filePath1)) // if self.pdfNewDocument?.isLocked == true { // self.pdfNewDocument?.unlock(withPassword: password) // } // self.pdfNewView.document = self.pdfNewDocument // self.pdfNewView.autoScales = true // self.pdfNewView.delegate = self // self.addFileContentView.isHidden = true // self.updateNewFileQKSelectedPathsWithPath(self.pdfNewDocument?.documentURL?.path ?? "") // self.reloadNewPDFData() // } // } // } // return // } DispatchQueue.global().async { let oldDoc = CPDFDocument(url: config.fileOldAttribute.pdfDocument?.documentURL) if let password = config.fileOldAttribute.password { oldDoc!.unlock(withPassword: password) } let doc = CPDFDocument(url: config.fileNewAttribute.pdfDocument?.documentURL) if let password = config.fileNewAttribute.password { doc!.unlock(withPassword: password) } // if let compareLoadingWVC = self.compareLoadingWVC { // compareLoadingWVC.maxPageCount = config.fileOldAttribute.pdfDocument.pageCount + config.fileNewAttribute.pdfDocument.pageCount // } // if self._compareCancel { // return // } if self.compareView.fileType == .coverting { let pdfCompareOverlay = CPDFCompareOverlay(oldDocument: oldDoc, oldPageRange: config.fileOldAttribute.pagesString, newDocument: doc, newPageRange: config.fileNewAttribute.pagesString) let oldStrokeColor = config.oldStrokeColor pdfCompareOverlay?.setOldDocumentStroke(oldStrokeColor()) pdfCompareOverlay?.setOldDocumentStrokeOpacity(config.oldStrokeOpacity()) let newStrokeColor = config.newStrokeColor pdfCompareOverlay?.setNewDocumentStroke(newStrokeColor()) pdfCompareOverlay?.setNewDocumentStrokeOpacity(config.newStrokeOpacity()) pdfCompareOverlay?.setNewDocumentFillOpacity(config.newFillOpacity()) pdfCompareOverlay?.setOldDocumentFillOpacity(config.oldFillOpacity()) pdfCompareOverlay?.setNoFill(config.isNOFill()) pdfCompareOverlay?.setBlendMod(config.blendMod()) if ((pdfCompareOverlay?.compare()) != nil) { let document: CPDFDocument = (pdfCompareOverlay?.comparisonDocument()!)! if document == nil { DispatchQueue.main.async { self.coveringComplete?(self, document) } debugPrint("合并成功") } else { DispatchQueue.main.async { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Failure", comment: "") alert.runModal() } } } } else { var results = [CPDFCompareResults]() var pdfCompareContent: CPDFCompareContent? = nil // if let _pdfCompareContent = self._pdfCompareContent { // pdfCompareContent = _pdfCompareContent // } // // if self._compareCancel { // return // } pdfCompareContent = CPDFCompareContent(oldDocument: oldDoc, newDocument: doc) pdfCompareContent?.setDelete(config.deleteColor()) pdfCompareContent?.setReplace(config.replaceColor()) pdfCompareContent?.setInsert(config.insertColor()) pdfCompareContent?.setDeleteOpacity(config.deleteOpacity()) pdfCompareContent?.setReplaceOpacity(config.replaceOpacity()) pdfCompareContent?.setInsertOpacity(config.insertOpacity()) let maxIndex = max(config.fileOldAttribute.fetchSelectPages().count, config.fileNewAttribute.fetchSelectPages().count) var compareType: CPDFCompareType = .all if config.isCompareText() && !config.isCompareImage() { compareType = .text } else if !config.isCompareText() && config.isCompareImage() { compareType = .image } // if self._compareCancel { // return // } for i in 0..= config.fileOldAttribute.fetchSelectPages().count { oldPageIndex = Int(oldDoc!.pageCount) + i } else { oldPageIndex = Int(truncating: config.fileOldAttribute.fetchSelectPages()[i]) - 1 } let newPageIndex: Int if i >= config.fileNewAttribute.fetchSelectPages().count { newPageIndex = Int(doc!.pageCount) + i } else { newPageIndex = Int(truncating: config.fileNewAttribute.fetchSelectPages()[i]) - 1 } if let compareResults = pdfCompareContent?.compareOldPageIndex(oldPageIndex, newPageIndex: newPageIndex, type: compareType, isDrawHighlight: true) { results.append(compareResults) } // DispatchQueue.main.async { // if let compareLoadingWVC = self.compareLoadingWVC { // compareLoadingWVC.progress = CGFloat(i) / CGFloat(maxIndex) // } // } } DispatchQueue.main.async { self.contentComplete?(self,results, oldDoc!, doc!) if results.count > 0 { // Handle success case } else { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("There is no difference between the two documents.", comment: "") alert.runModal() } } } } } }