// // KMPDFEditInsertPageWindow.swift // PDF Reader Pro // // Created by tangchao on 2023/11/13. // import Cocoa enum KMPDFEditInsertType: Int { case management = 1 case pageEdit } class KMPDFEditInsertPageWindow: NSWindowController { var currentPage: Int = 1 var insertLocation: Int = 0 @IBOutlet var progress: NSProgressIndicator! @IBOutlet var pageCountLabel: NSTextField! @IBOutlet var pageLabel: NSTextField! @IBOutlet var pagesText: NSTextField! @IBOutlet var outputFolderText: NSTextField! @IBOutlet var locationFirstButton: NSButton! @IBOutlet var locationLastButton: NSButton! @IBOutlet var rangeButton: NSButton! @IBOutlet var insertButton: NSButton! @IBOutlet var cancelButton: NSButton! @IBOutlet var selectedPathButton: NSButton! @IBOutlet var byPageStepper: NSStepper! @IBOutlet var whereInsertBox: NSBox! @IBOutlet var insertLabel: NSTextField! @IBOutlet var whereInsertLabel: NSTextField! @IBOutlet var locationRangePopUpButton: NSPopUpButton! @IBOutlet var allPageButton: NSButton! @IBOutlet var singlePageButton: NSButton! @IBOutlet var doublePageButton: NSButton! @IBOutlet var customPageButton: NSButton! @IBOutlet var customTextField: NSTextField! @IBOutlet var rangeTextField: NSTextField! weak var pdfDocument: CPDFDocument? var insertDocument: CPDFDocument? var type: KMPDFEditInsertType = .management var fromFilePath: URL? private var _insertPages: [CPDFPage] = [] private var _selectPagesIndex: Int = 0 private var _password: String = "" private var _fromFilePassword: String = "" private var _insertPageIndex: Int = 0 var callback: ((CPDFDocument?, NSString?, [CPDFPage]?, Int) -> Void)? var fileAttribute = KMFileAttribute() convenience init(document: CPDFDocument, path: URL, password: String? = nil) { self.init(windowNibName: "KMPDFEditInsertPageWindow") self.insertDocument = CPDFDocument(url: path) if let data = self.insertDocument?.isLocked, data { self.insertDocument?.unlock(withPassword: password ?? "") } self.fromFilePath = path self.type = .pageEdit self.pdfDocument = document } convenience init(documentPath: URL) { self.init(windowNibName: "KMPDFEditInsertPageWindow") self.type = .management self.currentPage = 1 self.pdfDocument = CPDFDocument(url: documentPath) } override func windowDidLoad() { super.windowDidLoad() self._insertPages = [] var viewColor = NSColor.white var viewborderColor = NSColor(red: 195.0/255.0, green: 195.0/255.0, blue: 195.0/255.0, alpha: 1) var textColor = NSColor(red: 51.0/255.0, green: 51.0/255.0, blue: 51.0/255.0, alpha: 1) if KMAppearance.isSupportNewColor() { if KMAppearance.isDarkMode() { viewColor = NSColor(red: 101.0/255.0, green: 101.0/255.0, blue: 101.0/255.0, alpha: 1) viewborderColor = NSColor.clear textColor = .white } } self.outputFolderText.textColor = textColor self.selectedPathButton.title = KMLocalizedString("Choose...", nil) self.whereInsertLabel.stringValue = KMLocalizedString("Where to insert?",nil) self.pageLabel.stringValue = KMLocalizedString("Page", nil) self.progress.isHidden = true self.outputFolderText.isEditable = false self.pagesText.isEditable = false self.byPageStepper.isEnabled = false self.locationFirstButton.title = KMLocalizedString("First", nil) self.locationLastButton.title = KMLocalizedString("Last", nil) self.cancelButton.title = KMLocalizedString("Cancel", nil) self.insertButton.title = KMLocalizedString("Insert", nil) self.pagesText.formatter = TextFieldFormatter() self.pagesText.delegate = self self.allPageButton.title = KMLocalizedString("All Pages", nil) self.singlePageButton.title = KMLocalizedString("Odd Pages Only", nil) self.doublePageButton.title = KMLocalizedString("Even Pages Only", nil) self.rangeTextField.placeholderString = KMLocalizedString("e.g. 1,3-5,10", nil) self.insertLabel.stringValue = KMLocalizedString("Page Range", nil) if(self.type == .pageEdit) { self.customTextField.stringValue = String(format: "/ %ld", self.insertDocument?.pageCount ?? 0) self.outputFolderText.stringValue = self.fromFilePath?.path ?? "" } self._selectPagesIndex = 0 self.rangeTextField.isEnabled = self.customPageButton.state == .on self.allPageButton.state = .on let menu = NSMenu() _ = menu.addItem(title: KMLocalizedString("After", nil), action: #selector(after_Action), target: self) _ = menu.addItem(title: KMLocalizedString("Before", nil), action: #selector(before_Action), target: self) self.locationRangePopUpButton.menu = menu self.outputFolderText.placeholderString = KMLocalizedString("Select a File", nil) self.locationRangePopUpButton.isEnabled = false if let data = self.pdfDocument?.isLocked, data { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { KMBaseWindowController.checkPassword(url: self.pdfDocument!.documentURL, type: .owner) { success, resultPassword in if (resultPassword.isEmpty == false) { self.pdfDocument?.unlock(withPassword: resultPassword) self._password = resultPassword self.pageCountLabel.stringValue = String(format: "/%ld", self.pdfDocument?.pageCount ?? 0) self.byPageStepper.minValue = 1.0 self.byPageStepper.maxValue = Double(self.pdfDocument?.pageCount ?? 0) } } } } else { self.byPageStepper.minValue = 1.0 self.byPageStepper.maxValue = Double(self.pdfDocument?.pageCount ?? 0) self.pageCountLabel.stringValue = String(format: "/%ld", self.pdfDocument?.pageCount ?? 0) } if (self.insertLocation == 2) { self.locationLastButton.state = .on } else if (self.insertLocation == 3) { self.rangeButton.state = .on self.locationRangePopUpButton.isEnabled = true self.pagesText.isEditable = true self.byPageStepper.isEnabled = true } else { self.locationFirstButton.state = .on } self.pagesText.stringValue = String(format: "%ld", self.currentPage) self.byPageStepper.integerValue = Int(self.pagesText.stringValue) ?? 0 } @IBAction func byPageStepperAction(_ sender: AnyObject) { self.pagesText.stringValue = "\(self.byPageStepper.integerValue)" } @IBAction func buttonItemClicked_Location(_ sender: NSButton) { if (sender == self.rangeButton) { self.pagesText.isEditable = true self.locationRangePopUpButton.isEnabled = true self.byPageStepper.isEnabled = true } else { self.pagesText.isEditable = false self.locationRangePopUpButton.isEnabled = false self.byPageStepper.isEnabled = false } } @IBAction func buttonItemClicked_Cancel(_ sender: AnyObject) { self.pdfDocument = nil guard let block = self.callback else { return } block(nil, nil, nil, 0) } @IBAction func buttonItemClicked_Insert(_ sender: AnyObject) { if (self.insertDocument == nil) { return } let fromDocument = CPDFDocument(url: self.fromFilePath) if let data = (fromDocument?.isLocked), data { fromDocument?.unlock(withPassword: self.insertDocument?.password ?? "") } self.progress.isHidden = false self.cancelButton.isEnabled = false self.insertButton.isEnabled = false self.progress.startAnimation(nil) var pages: [CPDFPage] = [] if self.outputFolderText.stringValue == "" || self.outputFolderText.stringValue.isEmpty { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = KMLocalizedString("Select a File", nil) alert.runModal() self.progress.isHidden = true self.cancelButton.isEnabled = true self.insertButton.isEnabled = true self.progress.stopAnimation(nil) return } let fileAttribute = KMFileAttribute() self.fileAttribute = fileAttribute fileAttribute.password = self.insertDocument?.password ?? "" fileAttribute.filePath = self.outputFolderText.stringValue if ((0 == self._selectPagesIndex)) { fileAttribute.bAllPage = true fileAttribute.pagesType = .all } else if(1 == self._selectPagesIndex){ fileAttribute.bAllPage = false fileAttribute.pagesType = .odd let tDocument = CPDFDocument(url: URL(fileURLWithPath: fileAttribute.filePath)) var tPagesString = "" for i in 0 ..< (tDocument?.pageCount ?? 0) { if (i%2 == 0) { if (tPagesString.isEmpty) { tPagesString.append("\(i+1)") }else{ tPagesString.append(",\(i+1)") } } } fileAttribute.pagesString = tPagesString } else if (2 == self._selectPagesIndex){ fileAttribute.bAllPage = false fileAttribute.pagesType = .even let tDocument = CPDFDocument(url: URL(fileURLWithPath: fileAttribute.filePath)) var tPagesString = "" for i in 0 ..< (tDocument?.pageCount ?? 0) { if (i%2 == 1) { if (tPagesString.isEmpty) { tPagesString.append("\(i+1)") }else{ tPagesString.append(",\(i+1)") } } } fileAttribute.pagesString = tPagesString } else { fileAttribute.bAllPage = false fileAttribute.pagesType = .custom fileAttribute.pagesString = self.rangeTextField.stringValue } if (fileAttribute.fetchSelectPages().isEmpty) { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = String(format: "%@ %@", fileAttribute.filePath.lastPathComponent, KMLocalizedString("Invalid page range or the page number is out of range. Please try again.", nil)) alert.runModal() self.progress.isHidden = true self.cancelButton.isEnabled = true self.insertButton.isEnabled = true self.progress.stopAnimation(nil) return } else { for number in fileAttribute.fetchSelectPages() { // let page = self.insertDocument?.page(at: UInt(number.intValue-1)).copy() // pages.append(page as! CPDFPage) } } var index = 0 if (self.locationFirstButton.state == .on) { index = 0 } else if (self.locationLastButton.state == .on) { index = Int(self.pdfDocument?.pageCount ?? 0) } else { index = Int(self.pagesText.stringValue) ?? 0 if ((1 == self.locationRangePopUpButton.indexOfSelectedItem)) { index = index - 1 } } for page in pages { self._insertPages.append(page) } self._insertPageIndex = index self.progress.isHidden = true self.cancelButton.isEnabled = true self.insertButton.isEnabled = true self.progress.stopAnimation(nil) guard let block = self.callback else { return } block(self.pdfDocument, self._password as NSString, self._insertPages, self._insertPageIndex) } @IBAction func buttonItemClicked_OutputFolder(_ sender: AnyObject) { let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf"] openPanel.beginSheetModal(for: self.window!) { result in if (result == .OK) { for fileURL in openPanel.urls { let pdfDoc = CPDFDocument(url: fileURL) if let data = pdfDoc?.isLocked, data { DispatchQueue.main.asyncAfter(deadline: .now()+0.5) { KMBaseWindowController.checkPassword(url: fileURL, type: .owner) { result, pwd in if (pwd.isEmpty == false) { self._password = pwd self.fromFilePath = fileURL self.insertDocument = CPDFDocument(url: fileURL) if let data = self.insertDocument?.isLocked, data { self.insertDocument?.unlock(withPassword: pwd) } self.customTextField.stringValue = String(format: "/ %ld", self.insertDocument?.pageCount ?? 0) self.outputFolderText.stringValue = self.fromFilePath?.path ?? "" self.window?.makeFirstResponder(self) self.pagesText.stringValue = "1" self.insertButton.isEnabled = true } } } } else { self.fromFilePath = fileURL self.outputFolderText.stringValue = self.fromFilePath?.path ?? "" self.insertDocument = CPDFDocument(url: fileURL) self.customTextField.stringValue = String(format: "/ %ld", self.insertDocument?.pageCount ?? 0) self.window?.makeFirstResponder(self) self.pagesText.stringValue = "1" self.insertButton.isEnabled = true } } } } } @IBAction func customPageButton_Action(_ sender: NSButton) { self.allPageButton.state = .off self.singlePageButton.state = .off self.doublePageButton.state = .off self.customPageButton.state = .off sender.state = .on self.rangeTextField.isEnabled = false self.customTextField.textColor = NSColor.disabledControlTextColor self._selectPagesIndex = sender.tag if (sender.tag == 3) { self.rangeTextField.isEnabled = true self.customTextField.textColor = NSColor.labelColor self.window?.makeFirstResponder(self.rangeTextField) if(self.rangeTextField.stringValue.isEmpty) { return } } } override func keyDown(with event: NSEvent) { super.keyDown(with: event) self.window?.makeFirstResponder(nil) } @IBAction func after_Action(_ sender: AnyObject?) { } @IBAction func before_Action(_ sender: AnyObject?) { } } extension KMPDFEditInsertPageWindow: NSTextFieldDelegate { func controlTextDidChange(_ obj: Notification) { let textField = obj.object as? NSTextField if (self.pagesText.isEqual(to: textField)) { if let data = Int(textField!.stringValue), data <= 0 { self.pagesText.stringValue = "1" self.byPageStepper.integerValue = 1 } else if let data = textField?.stringValue.stringToCGFloat(), data > self.byPageStepper.maxValue { self.pagesText.stringValue = String(format: "%.0f", self.byPageStepper.maxValue) self.byPageStepper.integerValue = Int(self.byPageStepper.maxValue) } else { self.byPageStepper.integerValue = Int(self.pagesText.stringValue) ?? 0 } } } } // MARK: - Private Methods extension KMPDFEditInsertPageWindow { /* #pragma mark Private methor - (void)viewFileAtFinder:(NSString *)filePath { NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; NSURL *url = [NSURL fileURLWithPath:filePath]; [workspace activateFileViewerSelectingURLs:[NSArray arrayWithObject:url]]; } */ }