// // KMMergeWindowController.swift // PDF Reader Pro // // Created by lizhe on 2023/11/8. // import Cocoa typealias KMMergeWindowControllerCancelAction = (_ controller: KMMergeWindowController) -> Void typealias KMMergeWindowControllerAddFilesAction = (_ controller: KMMergeWindowController) -> Void typealias KMMergeWindowControllerMergeAction = (_ controller: KMMergeWindowController, _ filePath: String) -> Void typealias KMMergeWindowControllerClearAction = (_ controller: KMMergeWindowController) -> Void class KMMergeWindowController: KMBaseWindowController { @IBOutlet weak var mergeView: KMMergeView! // var cancelAction: KMMergeWindowControllerCancelAction? var oldPDFDocument: CPDFDocument = CPDFDocument() var password: String = "" var oriDucumentUrl: URL? { didSet { guard let document = CPDFDocument(url: oriDucumentUrl!) else { return } oldPDFDocument = document oldPDFDocument.unlock(withPassword: self.password) } } var type: KMMergeViewType = .add var pageIndex: Int? var mergeAction: KMMergeWindowControllerMergeAction? // - (id)initWithPDFDocument:(PDFDocument *)document password:(NSString *)password // { // if (self = [super initWithWindowNibName:@"KMPDFEditAppendWindow"]) { // // // self.PDFDocument = document; // self.PDFDocument = [[PDFDocument alloc] init]; // self.editType = KMPDFPageEditAppend; // _lockFilePathArr = [[NSMutableArray alloc] init]; // _files = [[NSMutableArray alloc] init]; // // KMFileAttribute *file = [[KMFileAttribute alloc] init]; // file.myPDFDocument = document; // file.filePath = document.documentURL.path; // file.oriFilePath = self.oriDucumentUrl.path; // if (password && password.length > 0) { // file.password = password; // file.isLocked = YES; // } // [self.files addObject:file]; // } // return self; // } convenience init(document: PDFDocument, password: String) { self.init(windowNibName: "KMMergeWindowController") self.password = password } override func windowDidLoad() { super.windowDidLoad() self.window!.title = NSLocalizedString("Merge PDF Files", comment: ""); // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. self.mergeView.type = self.type mergeView.addFilesAction = { [unowned self] view in self.addFile() } mergeView.clearAction = { [unowned self] view in } mergeView.mergeAction = { [unowned self] view, files, size in mergeFiles(files: files, size: size) } mergeView.cancelAction = { [unowned self] view in cancelAction?(self) } } } extension KMMergeWindowController { func addFile() { var size = 0.0 let files = self.mergeView.files for file in files { size = size + file.fileSize } if !IAPProductsManager.default().isAvailableAllFunction() && (files.count >= 2 || size > 20 * 1024 * 1024) { KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf"] if KMPurchaseManager.manager.state == .subscription { openPanel.allowsMultipleSelection = true openPanel.message = NSLocalizedString("Select files to merge. To select multiple files press cmd ⌘ button on keyboard and click on the target files one by one.", comment: "") } else { openPanel.allowsMultipleSelection = false openPanel.message = NSLocalizedString("Select files to merge, only one file can be selected at a time.", comment: "") } openPanel.beginSheetModal(for: self.window!) { (result) in if result == NSApplication.ModalResponse.OK { var array: [URL] = [] for fileURL in openPanel.urls { array.append(fileURL) } let attribe = try?FileManager.default.attributesOfItem(atPath: openPanel.urls.first!.path) let fileSize = attribe?[FileAttributeKey.size] as? CGFloat ?? 0 size = fileSize + size if !IAPProductsManager.default().isAvailableAllFunction() && (files.count >= 2 || size > 20 * 1024 * 1024) { KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } self.mergeView.addFilePaths(urls: array) } } } func mergeFiles(files: [KMFileAttribute], size: CGSize = CGSizeZero) { var size = 0.0 for file in files { size = size + file.fileSize } if !IAPProductsManager.default().isAvailableAllFunction() && (files.count >= 2 || size > 20 * 1024 * 1024) { KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } var filesCount = 1 if self.oriDucumentUrl != nil { filesCount = 0 } if files.count <= filesCount { let alert = NSAlert.init() alert.alertStyle = .critical alert.messageText = NSLocalizedString("To start merging, please select at least 2 files.", comment: "") alert.runModal() return } // _isSuccessfully = NO; // [self.nCancelVC setEnabled:NO]; // self.canMerge = NO; // var rootPDFOutlineArray: [CPDFOutline] = [] var allPage = true //只有是全部才支持大纲的合并 for file in files { if file.fetchSelectPages().count == 0 { let alert = NSAlert.init() alert.alertStyle = .critical alert.messageText = "\(file.filePath.lastPathComponent) + \(NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: ""))" alert.runModal() return } allPage = file.bAllPage /*防止文件被地址变换后crash*/ guard let tDocument = CPDFDocument(url: NSURL(fileURLWithPath: file.filePath) as URL) else { print("文件不存在") let alert = NSAlert.init() alert.alertStyle = .critical alert.messageText = "\(file.filePath.lastPathComponent) + \(NSLocalizedString("Failed to merge!", comment: ""))" alert.runModal() return } var outlineArray: [CPDFOutline] = [] // if file.isLocked { tDocument.unlock(withPassword: file.password) // } if tDocument.outlineRoot() != nil { rootPDFOutlineArray.append(tDocument.outlineRoot()) self.fetchAllOfChildren(tDocument.outlineRoot(), containerArray: &outlineArray) outlineArray.removeObject(tDocument.outlineRoot()) } else { let rootOutline = tDocument.setNewOutlineRoot() if rootOutline != nil { rootPDFOutlineArray.append(rootOutline!) } } for number in file.fetchSelectPages() { let page = tDocument.page(at: UInt(number - 1)) // if pageIndex != nil { // self.oldPDFDocument.insert(page!, at: pageIndex!) // pageIndex = pageIndex! + 1 // } else { self.oldPDFDocument.insertPageObject(page, at: self.oldPDFDocument.pageCount) // } // self.insertIndexSet.addIndex:(self.pdfDocument.pageCount - 1) } } let fileName = (files.first?.filePath.deletingPathExtension.lastPathComponent ?? "") + "_Merged" // DispatchQueue.main.async { if self.oldPDFDocument.outlineRoot() == nil { self.oldPDFDocument.setNewOutlineRoot() } if allPage { var insertIndex = 0 for i in 0..