// // KMMergeWindowController.swift // PDF Master // // Created by lizhe on 2023/11/8. // import Cocoa typealias KMMergeWindowControllerCancelAction = (_ controller: KMMergeWindowController) -> Void typealias KMMergeWindowControllerAddFilesAction = (_ controller: KMMergeWindowController) -> Void typealias KMMergeWindowControllerMergeAction = (_ controller: KMMergeWindowController) -> Void typealias KMMergeWindowControllerClearAction = (_ controller: KMMergeWindowController) -> Void class KMMergeWindowController: NSWindowController { @IBOutlet weak var mergeView: KMMergeView! var cancelAction: KMMergeWindowControllerCancelAction? var pdfDocument: PDFDocument = PDFDocument() var password: String = "" var oriDucumentUrl: URL? // - (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") } 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. mergeView.addFilesAction = { [unowned self] view in self.addFile() } mergeView.clearAction = { [unowned self] view in } mergeView.mergeAction = { [unowned self] view, files, size in self.mergeFiles(files: files, size: size) } mergeView.cancelAction = { [unowned self] view in cancelAction?(self) } } } extension KMMergeWindowController { func addFile() { // if (![IAPProductsManager defaultManager].isAvailableAllFunction) { // //免費版只支援2個檔案做合併小于20M的文件合并 // if (_files.count >= 2 || self.allFileSize > (20 * 1024 * 1024)) { // #if VERSION_DMG // [[KMPurchaseCompareWindowController sharedInstance] showWindow:nil]; // #else // KMToolCompareWindowController * vc = [KMToolCompareWindowController toolCompareWithType:KMCompareWithToolType_PageEdit setSelectIndex:1]; // [vc showWindow:nil]; // #endif // 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 the 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) // if let filePath = fileURL.path { // if !FileManager.default.isExecutableFile(atPath: filePath) { // continue // } // // do { // let attrib = try FileManager.default.attributesOfItem(atPath: filePath) //// if let fileSize = attrib[FileAttributeKey.size] as? NSNumber { //// self.allFileSize += fileSize.floatValue //// } //// //// if !IAPProductsManager.defaultManager.isAvailableAllFunction { //// if self.allFileSize > (20 * 1024 * 1024) || self.files.count >= 2 { //// let vc = KMToolCompareWindowController.toolCompare(withType: .pageEdit, setSelectIndex: 1) //// vc?.showWindow(nil) //// self.allFileSize -= fileSize.floatValue //// self.addFiles(array) //// return //// } //// } // array.append(fileURL) // } catch { // print("Error getting file attributes: \(error)") // } // } } self.mergeView.addFilePaths(urls: array) } } } func mergeFiles(files: [KMFileAttribute], size: CGSize = CGSizeZero) { if files.count <= 1 { 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: [PDFOutline] = [] 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 let tDocument = PDFDocument(url: NSURL(fileURLWithPath: file.filePath) as URL)! var outlineArray: [PDFOutline] = [] 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 = PDFOutline.init() tDocument.outlineRoot = rootOutline if tDocument.outlineRoot != nil { rootPDFOutlineArray.append(tDocument.outlineRoot!) } } for number in file.fetchSelectPages() { let page = tDocument.page(at: number.intValue - 1) self.pdfDocument.insert(page!, at: self.pdfDocument.pageCount) // self.insertIndexSet.addIndex:(self.pdfDocument.pageCount - 1) } } let fileName = (files.first?.filePath.lastPathComponent)! + "_Merged" DispatchQueue.main.async { self.pdfDocument.outlineRoot = PDFOutline.init() if allPage { var insertIndex = 0 for i in 0..