123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- //
- // KMExtractWindowController.swift
- // PDF Reader Pro
- //
- // Created by kdanmobile on 2025/2/28.
- //
- import Cocoa
- import KMComponentLibrary
- import ComPDFKit
- class KMExtractWindowController: KMNBaseWindowController {
-
- @IBOutlet var contendBox: NSBox!
- @IBOutlet var titleLabel: NSTextField!
-
- @IBOutlet var previewBGView: NSView!
- @IBOutlet var pdfBGView: NSView!
-
- @IBOutlet var paginationView: ComponentPagination!
-
- @IBOutlet var pageRangeView: NSView!
- @IBOutlet var pageRangeLabel: NSTextField!
- @IBOutlet var allPageRadio: ComponentRadio!
- @IBOutlet var currentPageRadio: ComponentRadio!
- @IBOutlet var oddPageRadio: ComponentRadio!
- @IBOutlet var evenPageRadio: ComponentRadio!
- @IBOutlet var customPageRadio: ComponentRadio!
- @IBOutlet var customPageInput: ComponentInput!
-
- @IBOutlet var allPageBoxWidthConst: NSLayoutConstraint!
- @IBOutlet var curPageBoxWidthConst: NSLayoutConstraint!
- @IBOutlet var oddPageBoxWidthConst: NSLayoutConstraint!
- @IBOutlet var evenPageBoxWidthConst: NSLayoutConstraint!
- @IBOutlet var customPageBoxWidthConst: NSLayoutConstraint!
-
- @IBOutlet var settingView: NSView!
- @IBOutlet var settingLabel: NSTextField!
- @IBOutlet var eachPageCheckbox: ComponentCheckBox!
- @IBOutlet var eachPageBoxWidthConst: NSLayoutConstraint!
-
- @IBOutlet var cancelButton: ComponentButton!
- @IBOutlet var confirmButton: ComponentButton!
- @IBOutlet var cancelBtnWidthConst: NSLayoutConstraint!
- @IBOutlet var confirmBtnWidthConst: NSLayoutConstraint!
-
- var fileURL: URL?
- var pdfDocument: CPDFDocument?
- var pdfView: CPDFListView = CPDFListView.init()
-
- var typeIndex: Int = 1
-
- var resultIndexs: [Int] = []
-
- 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.
-
- pdfView.frame = pdfBGView.bounds
- pdfView.autoresizingMask = [.width, .height]
- pdfView.setDisplay(.singlePage)
- pdfView.toolMode = .CNoteToolMode
- pdfView.autoScales = true
- pdfView.delegate = self
- pdfView.pdfListViewDelegate = self
- pdfBGView.addSubview(pdfView)
-
- reloadData()
- }
-
- override func initContentView() {
- super.initContentView()
-
- guard let _ = self.contendBox else {
- return
- }
-
- paginationView.properties = ComponentPaginationProperty(doubleArrow_show: false)
-
- for box in [allPageRadio, currentPageRadio, oddPageRadio, evenPageRadio, customPageRadio] {
- box?.setTarget(self, action: #selector(checkBoxClicked(_:)))
- }
-
- cancelButton.setTarget(self, action: #selector(cancelButtonClicked(_ :)))
- cancelButton.keyEquivalent = KMKeyEquivalent.esc.string()
-
- confirmButton.setTarget(self, action: #selector(openButtonClicked(_ :)))
- confirmButton.keyEquivalent = KMKeyEquivalent.enter // Enter key
-
- }
-
- override func updateUIThemeColor() {
- super.updateUIThemeColor()
-
- self.reloadUI()
- }
-
- override func updateUILanguage() {
- super.updateUILanguage()
-
- self.reloadUI()
- }
-
- override func beginSheetFinish() {
- super.beginSheetFinish()
-
- typeIndex = 1
-
- self.initContentView()
-
- reloadData()
-
- loadPDFPreview()
-
- self.window?.makeFirstResponder(nil)
-
- }
-
- //
- func reloadUI() {
- guard let _ = self.contendBox else {
- return
- }
-
- previewBGView.wantsLayer = true
- previewBGView.layer?.cornerRadius = 8
- previewBGView.layer?.borderWidth = 1
- previewBGView.layer?.backgroundColor = ComponentLibrary.shared.getComponentColorFromKey("colorFill/4").cgColor
- previewBGView.layer?.borderColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/4").cgColor
-
- titleLabel.stringValue = KMLocalizedString("Extract")
- titleLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/1")
- titleLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-m-medium")
-
- pageRangeLabel.stringValue = KMLocalizedString("Page Range")
- pageRangeLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/2")
- pageRangeLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-medium")
-
- settingLabel.stringValue = KMLocalizedString("Settings")
- settingLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/2")
- settingLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-medium")
-
- allPageRadio.properties = ComponentCheckBoxProperty(size: .s,
- state: .normal,
- isDisabled: false,
- showhelp: false,
- text: KMLocalizedString("All Pages"),
- checkboxType: .normal)
-
- currentPageRadio.properties = ComponentCheckBoxProperty(size: .s,
- state: .normal,
- isDisabled: false,
- showhelp: false,
- text: KMLocalizedString("Current Page"),
- checkboxType: .normal)
-
- oddPageRadio.properties = ComponentCheckBoxProperty(size: .s,
- state: .normal,
- isDisabled: false,
- showhelp: false,
- text: KMLocalizedString("Odd Pages Only"),
- checkboxType: .normal)
-
- evenPageRadio.properties = ComponentCheckBoxProperty(size: .s,
- state: .normal,
- isDisabled: false,
- showhelp: false,
- text: KMLocalizedString("Even Pages Only"),
- checkboxType: .normal)
-
- customPageRadio.properties = ComponentCheckBoxProperty(size: .s,
- state: .normal,
- isDisabled: false,
- showhelp: false,
- text: KMLocalizedString("Custom"),
- checkboxType: .normal)
-
- customPageInput.properties = ComponentInputProperty(size: .s,
- state:.normal,
- isDisabled: true,
- placeholder: KMLocalizedString("e.g. 1,3-5,10"),
- text: "",
- creatable: true,
- regexString: "0123456789,-")
-
- eachPageCheckbox.properties = ComponentCheckBoxProperty(size: .s,
- state: .normal,
- isDisabled: false,
- showhelp: false,
- text: KMLocalizedString("Each page in a separate file"),
- checkboxType: .normal)
-
- cancelButton.properties = ComponentButtonProperty(type: .default_tertiary,
- size: .s,
- state: .normal,
- buttonText: KMLocalizedString("Cancel"),
- keepPressState: false)
-
-
- confirmButton.properties = ComponentButtonProperty(type: .primary,
- size: .s,
- state: .normal,
- buttonText: KMLocalizedString("Extract"),
- keepPressState: false)
-
- allPageBoxWidthConst.constant = allPageRadio.properties.propertyInfo.viewWidth
- curPageBoxWidthConst.constant = currentPageRadio.properties.propertyInfo.viewWidth
- oddPageBoxWidthConst.constant = oddPageRadio.properties.propertyInfo.viewWidth
- evenPageBoxWidthConst.constant = evenPageRadio.properties.propertyInfo.viewWidth
- customPageBoxWidthConst.constant = customPageRadio.properties.propertyInfo.viewWidth
-
- eachPageBoxWidthConst.constant = eachPageCheckbox.properties.propertyInfo.viewWidth
- cancelBtnWidthConst.constant = cancelButton.properties.propertyInfo.viewWidth
- confirmBtnWidthConst.constant = confirmButton.properties.propertyInfo.viewWidth
-
- }
-
- func loadPDFPreview() {
- guard let filePath = fileURL else {
- return
- }
-
- NSWindowController.checkPassword(url: filePath, type: .owner, password: "") { [unowned self] success, resultPassword in
- if success {
- DispatchQueue.main.async {
- self.pdfDocument = CPDFDocument.init(url: filePath)
- if resultPassword.isEmpty == false {
- self.pdfDocument?.unlock(withPassword: resultPassword)
- }
-
- self.pdfView.document = self.pdfDocument
-
- self.paginationView.properties.currentIndex = 1
- self.paginationView.properties.totalCount = Int(self.pdfDocument?.pageCount ?? 1 )
- self.paginationView.reloadData()
- }
- }
- }
- }
-
- func reloadData() {
- allPageRadio.properties.checkboxType = .normal
- currentPageRadio.properties.checkboxType = .normal
- oddPageRadio.properties.checkboxType = .normal
- evenPageRadio.properties.checkboxType = .normal
- customPageRadio.properties.checkboxType = .normal
- customPageInput.properties.isDisabled = true
-
- if typeIndex == 0 {
- allPageRadio.properties.checkboxType = .selected
- } else if typeIndex == 1 {
- currentPageRadio.properties.checkboxType = .selected
- } else if typeIndex == 2 {
- oddPageRadio.properties.checkboxType = .selected
- } else if typeIndex == 3 {
- evenPageRadio.properties.checkboxType = .selected
- } else if typeIndex == 4 {
- customPageRadio.properties.checkboxType = .selected
- customPageInput.properties.isDisabled = false
- }
- allPageRadio.reloadData()
- currentPageRadio.reloadData()
- oddPageRadio.reloadData()
- evenPageRadio.reloadData()
- customPageRadio.reloadData()
-
- customPageInput.reloadData()
-
-
- }
-
- //MARK: - Action
- @objc func checkBoxClicked(_ sender: ComponentCheckBox) {
- if sender == self.allPageRadio {
- self.typeIndex = 0
- } else if sender == self.currentPageRadio {
- self.typeIndex = 1
- } else if sender == self.oddPageRadio {
- self.typeIndex = 2
- } else if sender == self.evenPageRadio {
- self.typeIndex = 3
- } else if sender == self.customPageRadio {
- self.typeIndex = 4
- }
-
- reloadData()
- }
-
- @objc func cancelButtonClicked(_ sender: NSView) {
- self.own_closeEndSheet()
-
- }
-
- @objc func openButtonClicked(_ sender: NSView) {
- guard let pdfDocument = self.pdfDocument else {
- return
- }
-
- var pageIndexs: [Int] = []
-
- if typeIndex == 0 {
- pageIndexs = KMPageRangeSelectView.getSelectedPageIndex(pdfDocument, isAllPages: true)
- } else if typeIndex == 1 {
- pageIndexs = [self.pdfView.currentPageIndex + 1]
- } else if typeIndex == 2 {
- pageIndexs = KMPageRangeSelectView.getSelectedPageIndex(pdfDocument, isOddPage: true)
- } else if typeIndex == 3 {
- pageIndexs = KMPageRangeSelectView.getSelectedPageIndex(pdfDocument, isEvenPage: true)
- } else if typeIndex == 4 {
- if customPageInput.properties.text.isEmpty == true {
- let alert = NSAlert()
- alert.alertStyle = .warning
- alert.messageText = KMLocalizedString("Invalid page range .", comment: "")
- alert.runModal()
-
- return
- }
- pageIndexs = KMPageRangeSelectView.getSelectedPageIndex(pdfDocument, isCustom: customPageInput.properties.text)
- }
-
- if pageIndexs.count < 1 {
- let alert = NSAlert()
- alert.alertStyle = .warning
- alert.messageText = KMLocalizedString("Invalid page range .", comment: "")
- alert.runModal()
-
- return
- }
-
- self.resultIndexs.removeAll()
- for i in pageIndexs {
- resultIndexs.append(i - 1)
- }
-
- var fileName = pdfDocument.documentURL.deletingPathExtension().lastPathComponent
- if self.eachPageCheckbox.properties.checkboxType == .normal {
- fileName.append(" pages ")
- fileName.append(KMPageRangeTools.newParseSelectedIndexs(selectedIndex: resultIndexs.sorted()))
- fileName.append(".pdf")
-
- let panel = NSSavePanel()
- panel.nameFieldStringValue = fileName
- panel.canCreateDirectories = true
- panel.beginSheetModal(for: self.window!) { response in
- if response == .OK {
- if let pdf = CPDFDocument.init() {
- var extractPages: Array<CPDFPage> = []
- for i in self.resultIndexs {
- extractPages.append(pdfDocument.page(at: UInt(i)))
- }
- let _ = pdf.extractAsOneDocument(withPages: extractPages, savePath: panel.url!.path)
- self.own_closeEndSheet()
- NSWorkspace.shared.activateFileViewerSelecting([panel.url!])
- }
- }
- }
- } else {
- let panel = NSOpenPanel()
- panel.canChooseFiles = false
- panel.canChooseDirectories = true
- panel.canCreateDirectories = true
- panel.beginSheetModal(for: self.window!) { response in
- if response == .OK {
- let folderName = String((pdfDocument.documentURL!.lastPathComponent.split(separator: ".")[0])) + "_extract"
-
- var filePath = URL(fileURLWithPath: panel.url!.path).appendingPathComponent(folderName).path
- var i = 1
- let testFilePath = filePath
- while FileManager.default.fileExists(atPath: filePath) {
- filePath = testFilePath + "\(i)"
- i += 1
- }
-
- try? FileManager.default.createDirectory(atPath: filePath, withIntermediateDirectories: false, attributes: nil)
-
- /// 提取的页面
- var extractPages: Array<CPDFPage> = []
- for i in self.resultIndexs {
- extractPages.append(pdfDocument.page(at: UInt(i)))
- }
-
- var successArray: [URL]?
- successArray = pdfDocument.extractPerPageDocument(withPages: extractPages, folerPath: filePath)
-
- self.own_closeEndSheet()
- NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: filePath)])
- }
- }
- }
- }
- }
- extension KMExtractWindowController: CPDFListViewDelegate, CPDFViewDelegate {
- func pdfViewCurrentPageDidChanged(_ pdfView: CPDFView!) {
- let index = pdfView.currentPageIndex
-
- paginationView.properties.currentIndex = index + 1
- paginationView.reloadData()
- }
- }
|