123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- //
- // KMExtractImageWindowController.swift
- // PDF Reader Pro
- //
- // Created by liujiajie on 2023/11/17.
- //
- import Cocoa
- class KMExtractImageWindowController: NSWindowController,PDFConvertObjectDelegate,NSTextFieldDelegate{
- var docPath: String = ""
- var password: String = ""
- var currentPage: Int = 0
- var maskView: KMBookletMaskView?
-
- @IBOutlet var rangeTipLabel: NSTextField!
- @IBOutlet var rangeTextField: NSTextField!
- @IBOutlet var allPageButton: NSButton!
- @IBOutlet var currentPageButton: NSButton!
- @IBOutlet var singlePageButton: NSButton!
- @IBOutlet var doublePageButton: NSButton!
- @IBOutlet var customPageButton: NSButton!
- @IBOutlet var extractImageButton: NSButton!
- @IBOutlet var cancelButton: NSButton!
- @IBOutlet var customTextField: NSTextField!
- @IBOutlet var totalImagesTextField: NSTextField!
- lazy var pdfDocument: CPDFDocument? = {
- var pdfDoc = CPDFDocument(url: URL(fileURLWithPath: self.docPath))
- if (self.password.count > 0){
- pdfDoc?.unlock(withPassword: self.password)
- }
- return pdfDoc
- }()
- var selectPagesIndex: Int = 0
- // var pdfConverter: PDFConvertObject?
- lazy var pdfConverter: PDFConvertObject? = {
- let conerter = PDFConvertObject()
- return conerter
- }()
- @IBOutlet var currentPageTextField: NSTextField!
- @IBOutlet var pageCountTextField: NSTextField!
- @IBOutlet var pdfViewBG: NSView!
- var preViewPDFView: CPDFView!
-
- private var fileAttri_: KMFileAttribute?
-
- deinit {
- NotificationCenter.default.removeObserver(self)
-
- }
- override func windowDidLoad() {
- super.windowDidLoad()
- let preView: CPDFView = CPDFView(frame: self.pdfViewBG.bounds)
- self.pdfViewBG.addSubview(preView)
- self.preViewPDFView = preView
- configUI()
- }
- func configUI() {
- if !self.docPath.isEmpty && self.docPath.count > 0 {
- let url = URL(fileURLWithPath: docPath)
- let document = CPDFDocument(url: url)
- if self.password.count > 0 {
- document?.unlock(withPassword: password)
- }
- self.preViewPDFView.document = document
- self.preViewPDFView.autoScales = true
- self.preViewPDFView.layoutDocumentView()
- self.preViewPDFView.go(toPageIndex: self.currentPage, animated: true)
-
- self.fileAttri_ = KMFileAttribute()
- self.fileAttri_?.filePath = url.path
- }
- self.allPageButton.title = NSLocalizedString("All Pages", comment: "")
- self.singlePageButton.title = NSLocalizedString("Odd Pages Only", comment: "")
- self.doublePageButton.title = NSLocalizedString("Even Pages Only", comment: "")
- self.currentPageButton.title = NSLocalizedString("Current Page", comment: "")
- self.extractImageButton.title = NSLocalizedString("Extract", comment: "")
- self.cancelButton.title = NSLocalizedString("Cancel", comment: "")
- self.rangeTextField.placeholderString = NSLocalizedString("e.g. 1,3-5,10", comment: "")
- self.rangeTipLabel.stringValue = NSLocalizedString("Page Range", comment: "")
-
- self.currentPageTextField.stringValue = "\(self.currentPage + 1)"
- self.pageCountTextField.stringValue = "/ \(self.pdfDocument?.pageCount ?? 0)"
- self.customTextField.stringValue = self.pageCountTextField.stringValue
- self.selectPagesIndex = 0
-
- self.rangeTextField.isEnabled = false
- self.customTextField.isEnabled = false
- self.allPageButton.state = NSControl.StateValue.on
- if self.pdfDocument?.pageCount ?? 0 < 2 {
- self.doublePageButton.isEnabled = false
- } else {
- self.doublePageButton.isEnabled = true
- }
- self.preViewPDFView.setDisplay(.singlePage)
- self.preViewPDFView.layoutDocumentView()
- NotificationCenter.default.addObserver(self, selector: #selector(pageChangeNotification(notification:)), name: NSNotification.Name.PDFViewPageChanged, object: self.preViewPDFView)
- }
- func selectCurrentPageBtn() {
- self.customPageButton_Action(self.currentPageButton)
- }
-
- @IBAction func customPageButton_Action(_ sender: NSButton) {
- self.allPageButton.state = NSControl.StateValue.off
- self.currentPageButton.state = NSControl.StateValue.off
- self.singlePageButton.state = NSControl.StateValue.off
- self.doublePageButton.state = NSControl.StateValue.off
- self.customPageButton.state = NSControl.StateValue.off
- sender.state = NSControl.StateValue.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
- }
- }
- }
- @IBAction func extractImageButton_Action(_ sender: Any) {
- startExtracting()
- }
- @IBAction func cancleButton_Action(_ sender: Any) {
- self.window?.sheetParent?.endSheet(self.window!)
- }
- @IBAction func nextPage_Action(_ sender: Any) {
- if self.preViewPDFView.canGoToNextPage() {
- self.preViewPDFView.goToNextPage(sender)
- }
- let index = self.preViewPDFView.document.index(for: self.preViewPDFView.currentPage())
- self.currentPageTextField.stringValue = "\(index + 1)"
- }
- @IBAction func previousPage_Action(_ sender: Any) {
- if self.preViewPDFView.canGoToPreviousPage() {
- self.preViewPDFView.goToPreviousPage(sender)
- }
- let index = self.preViewPDFView.document.index(for: self.preViewPDFView.currentPage())
- self.currentPageTextField.stringValue = "\(index + 1)"
- }
-
- override func close() {
- if ((self.window?.isSheet) != nil) {
- self.window?.sheetParent?.endSheet(self.window!)
- } else {
- super.close()
- }
- }
-
- func startExtracting() {
- let indeSet = self.selectIndexSet()
- if indeSet.count == 0 { return }
- let lastPathName = self.pdfDocument?.documentURL.deletingPathExtension().lastPathComponent ?? ""
- var tFileName = (String(format: "%@_Extract Images", lastPathName))
- let outputSavePanel = NSSavePanel()
- if let data = outputSavePanel.directoryURL?.appendingPathComponent(tFileName) {
- let fileUrl = self.fetchUniquePath(data.path)
- tFileName = fileUrl.lastPathComponent
- }
-
- outputSavePanel.title = NSLocalizedString("Save as PDF", comment: "")
- outputSavePanel.allowsOtherFileTypes = true
- outputSavePanel.isExtensionHidden = true
- outputSavePanel.canCreateDirectories = true
- outputSavePanel.nameFieldStringValue = tFileName
- outputSavePanel.beginSheetModal(for: self.window!) {(result) in
- if result == NSApplication.ModalResponse.OK {
- self.showWaitting()
- DispatchQueue.main.async {
- let tDestFile = outputSavePanel.url?.path ?? ""
- let uniquePath = KMExtractImageWindowController.createDestFolder(path: tDestFile, isUnique: false)
- self.pdfConverter?.extractResourcesFromPDF(at: self.docPath, pdfPassword: self.password, selectIndexSet: indeSet as IndexSet, destDocPath: uniquePath, moreOptions: nil)
- self.extractOK(tDestFile)
- }
- }
- }
- }
-
- func fetchUniquePath(_ originalPath: String) -> String {
- var path = originalPath
- let dManager = FileManager.default
- if !dManager.fileExists(atPath: path) {
- if path.extension.count < 1 {
- path = path.stringByAppendingPathExtension("pdf")
- }
- return path
- } else {
- let originalFullFileName = path.lastPathComponent
- let url = URL(fileURLWithPath: path)
- // let originalFileName = path.lastPathComponent.deletingPathExtension.lastPathComponent
- // let originalFileName = url.deletingPathExtension().lastPathComponent
- let originalFileName = originalFullFileName
- // let originalExtension = path.extension
-
- let startIndex: Int = 0
- let endIndex: Int = startIndex + originalPath.count - originalFullFileName.count - 1
- let fileLocatePath = originalPath.substring(to: endIndex)
- var i = 1
- while (1 != 0) {
- var newName = String(format: "%@(%ld)", originalFileName, i)
- // newName = String(format: "%@%@", newName, originalExtension)
- let newPath = fileLocatePath.stringByAppendingPathComponent(newName)
- if !dManager.fileExists(atPath: newPath) {
- return newPath
- } else {
- i+=1
- continue
- }
- }
- }
- }
-
- func extractOK(_ folder: String) {
- self.hideWaitting()
- self.close()
- if FileManager.default.fileExists(atPath: folder) {
- let workspace = NSWorkspace.shared
- let url = URL(fileURLWithPath: folder)
- workspace.activateFileViewerSelecting([url])
- }
- }
- func selectIndexSet() -> NSMutableIndexSet {
- let pageCount = self.pdfDocument?.pageCount
- let indeSet = NSMutableIndexSet()
- if self.selectPagesIndex == 0 {
- for i in 0..<(pageCount ?? 0) {
- indeSet.add(IndexSet(integer: IndexSet.Element(i)))
- }
- } else if self.selectPagesIndex == 1 {
- for i in 0..<(pageCount ?? 0) {
- if i % 2 == 0 {
- indeSet.add(IndexSet(integer: IndexSet.Element(i)))
- }
- }
- } else if self.selectPagesIndex == 2 {
- for i in 0..<(pageCount ?? 0) {
- if i % 2 != 0 {
- indeSet.add(IndexSet(integer: IndexSet.Element(i)))
- }
- }
- } else if self.selectPagesIndex == 4 {
- if let index = self.preViewPDFView.document?.index(for: self.preViewPDFView.currentPage()!) {
- indeSet.add(IndexSet(integer: IndexSet.Element(index)))
- }
- } else {
- var fileAttribute = self.fileAttri_
- if fileAttribute == nil {
- self.fileAttri_ = KMFileAttribute()
- self.fileAttri_?.filePath = self.preViewPDFView.document?.documentURL?.path ?? ""
- fileAttribute = self.fileAttri_
- }
- fileAttribute?.bAllPage = false
- if (self.customPageButton.state == .on){
- fileAttribute?.pagesType = .custom
- }
- fileAttribute?.pagesString = self.rangeTextField.stringValue
- if let data = fileAttribute?.fetchSelectPages().isEmpty, data {
- let alert = NSAlert()
- alert.alertStyle = .critical
- alert.messageText = "\(fileAttribute?.filePath.lastPathComponent ?? "") \(NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: ""))"
- alert.runModal()
- return indeSet
- }
-
- for num in fileAttribute?.fetchSelectPages() ?? [] {
- indeSet.add(num-1)
- }
- }
- return indeSet
- }
- class func createDestFolder(path: String, isUnique: Bool) -> String {
- var ret = true
- var tUniqueName: String? = nil
- let tFileManager = FileManager.default
- if isUnique {
- tUniqueName = getUniqueFilePath(filePath: path)
- } else {
- tUniqueName = path
- }
-
- if !tFileManager.fileExists(atPath: tUniqueName!) {
- do {
- try tFileManager.createDirectory(atPath: tUniqueName!, withIntermediateDirectories: true, attributes: nil)
- } catch {
- ret = false
- }
- }
-
- return tUniqueName!
- }
- class func getUniqueFilePath(filePath: String) -> String {
- var i = 0
- var isDirectory = ObjCBool(false)
- var uniqueFilePath = filePath
- let filemanager = FileManager.default
- filemanager.fileExists(atPath: uniqueFilePath, isDirectory: &isDirectory)
-
- if isDirectory.boolValue {
- while filemanager.fileExists(atPath: uniqueFilePath) {
- i += 1
- uniqueFilePath = "\(filePath)(\(i))"
- }
- } else {
- while filemanager.fileExists(atPath: uniqueFilePath) {
- i += 1
- let path = "\(filePath.deletingPathExtension)(\(i))"
- uniqueFilePath = path.stringByAppendingPathExtension(filePath.customPathExtension)
- }
- }
-
- return uniqueFilePath
- }
-
- @objc func pageChangeNotification(notification: Notification) {
- self.currentPageTextField.stringValue = self.preViewPDFView.currentPage().label ?? ""
- }
- func controlTextDidEndEditing(_ obj: Notification) {
- if obj.object as? NSTextField == self.currentPageTextField {
- if let intValue = Int(self.currentPageTextField.stringValue), intValue > (self.preViewPDFView.document?.pageCount ?? 0) {
- let alert = NSAlert()
- alert.alertStyle = .critical
- alert.messageText = String(format: "%@%@", self.preViewPDFView.document.documentURL.lastPathComponent.lastPathComponent,KMLocalizedString("Invalid page range or the page number is out of range. Please try again."))
- alert.beginSheetModal(for: NSApp.mainWindow!, completionHandler: nil)
- return
- }
- self.preViewPDFView.go(to: self.preViewPDFView.document?.page(at: UInt((Int(self.currentPageTextField.stringValue) ?? 0) - 1)))
- } else if obj.object as? NSTextField == self.rangeTextField {
- if !checkPageRangeValidate(self.rangeTextField.stringValue) {
- let alert = NSAlert()
- alert.alertStyle = .critical
- alert.messageText = String(format: "%@%@", self.preViewPDFView.document.documentURL.lastPathComponent.lastPathComponent,KMLocalizedString("Invalid page range or the page number is out of range. Please try again."))
- alert.beginSheetModal(for: NSApp.mainWindow!, completionHandler: nil)
- return
- }
- }
- }
- func checkPageRangeValidate(_ pageRangeString: String) -> Bool {
- var fileAttribute = self.fileAttri_
- if fileAttribute == nil {
- self.fileAttri_ = KMFileAttribute()
- self.fileAttri_?.filePath = self.preViewPDFView.document?.documentURL?.path ?? ""
- fileAttribute = self.fileAttri_
- }
- fileAttribute?.bAllPage = false
- fileAttribute?.pagesString = self.rangeTextField.stringValue
- let isEmpty = fileAttribute?.fetchSelectPages().isEmpty ?? true
- let cnt = fileAttribute?.fetchSelectPages().count ?? 0
- if isEmpty || cnt < 1{
- return false
- }
- return true
- }
- override func mouseDown(with event: NSEvent) {
- super.mouseDown(with: event)
- self.window?.makeFirstResponder(nil)
- }
- @objc func pageChangeNotification(_ notification: Notification) {
- self.currentPageTextField.stringValue = self.preViewPDFView.currentPage().label ?? ""
- }
- func PDFConvertObject2(_ converter: PDFConvertObject, didEndConversion error: Error?) {
- self.hideWaitting()
- self.window?.sheetParent?.endSheet(self.window!)
- }
- func showWaitting() {
- if self.maskView == nil {
- self.maskView = KMBookletMaskView(frame: CGRect(x: 0, y: 0, width: self.window?.frame.size.width ?? 0, height: self.window?.frame.size.height ?? 0))
- }
- self.window?.contentView?.addSubview(self.maskView!)
- }
- func hideWaitting() {
- self.maskView?.removeFromSuperview()
- }
- func beginSheetModal(for window: NSWindow, completionHandler handler: ((NSInteger) -> Void)?) {
- self.window?.beginSheet(window, completionHandler: { returnCode in
- NSApp.endSheet(self.window!, returnCode: NSApplication.ModalResponse.abort.rawValue)
- if let handler = handler {
- handler(returnCode.rawValue)
- }
- })
- }
-
- }
|