123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- //
- // KMCompressWindowController.swift
- // PDF Master
- //
- // Created by tangchao on 2022/11/25.
- //
- import Cocoa
- protocol KMLoadingProtocol: NSObjectProtocol {
-
- func beginLoading()
- func endLoading()
- }
- extension NSView: KMLoadingProtocol {
- var markViewTag: Int {
- get {
- return 123456
- }
- }
-
- func beginLoading() {
- self.endLoading()
-
- if (Thread.isMainThread) {
- self.beginLoadingInMainThread()
- } else {
- DispatchQueue.main.async {
- self.beginLoadingInMainThread()
- }
- }
- }
-
- func endLoading() {
- if (Thread.isMainThread) {
- self.endLoadingInMainThread()
- } else {
- DispatchQueue.main.async {
- self.endLoadingInMainThread()
- }
- }
- }
-
-
- // MARK: exe in main thread
-
- private func beginLoadingInMainThread() {
- let maskView = self.createLoadingMaskView()
- self.addSubview(maskView)
- maskView.frame = self.bounds
- maskView.autoresizingMask = [.minXMargin, .maxXMargin, .minYMargin, .maxYMargin]
-
- let loadingIndicator = self.createLoadingIndicator()
- maskView.addSubview(loadingIndicator)
- let size = NSMakeSize(32, 32)
- let left: CGFloat = (NSWidth(self.bounds)-size.width) * 0.5
- let top: CGFloat = (NSHeight(self.bounds)-size.height) * 0.5
- loadingIndicator.frame = NSMakeRect(left, top, size.width, size.height)
- loadingIndicator.autoresizingMask = [.minXMargin, .maxXMargin, .minYMargin, .maxYMargin]
-
- loadingIndicator.startAnimation(nil)
- }
-
- private func endLoadingInMainThread() {
- let maskView = self.viewWithTag(self.markViewTag)
- if (maskView == nil) {
- return
- }
-
- let loadingIndicator = maskView?.subviews.first
- if (loadingIndicator is NSProgressIndicator == false) {
- return
- }
-
- (loadingIndicator as! NSProgressIndicator).stopAnimation(nil)
- loadingIndicator?.removeFromSuperview()
- maskView?.removeFromSuperview()
- }
-
- // MARK: Init View
-
- private func createLoadingMaskView() -> NSButton {
- let mask = NSButton()
- mask.tag = self.markViewTag
- mask.isBordered = false
- mask.title = ""
- mask.target = self
- mask.action = #selector(loadingMask_Click)
-
- return mask
- }
-
- private func createLoadingIndicator() -> NSProgressIndicator {
- let loading = NSProgressIndicator()
- loading.style = .spinning
- loading.controlSize = .regular
- loading.isIndeterminate = true
-
- return loading
- }
-
- @objc private func loadingMask_Click() {}
- }
- typealias KMCompressWindowControllerItemClick = (Int)->()
- typealias KMCompressWindowControllerResultCallback = (_ result: Bool,_ openDocuemt: Bool, _ fileURL: URL, _ error: String)->()
- class KMCompressWindowController: NSWindowController {
- @IBOutlet weak var titleLabel: NSTextField!
-
- @IBOutlet weak var largeBox: NSBox!
- @IBOutlet weak var standardBox: NSBox!
- @IBOutlet weak var smallBox: NSBox!
- @IBOutlet weak var minimumBox: NSBox!
-
- @IBOutlet weak var batchButton: NSButton!
- @IBOutlet weak var cancelBox: NSBox!
- @IBOutlet weak var compressBox: NSBox!
-
- var documentURL: URL!
- var password: String!
- private var datas: [String] = []
- var selectIndex = 2
-
- var itemClick : KMCompressWindowControllerItemClick!
- var resultCallback : KMCompressWindowControllerResultCallback!
- var largeVC : KMDesignButton!
- var standardVC : KMDesignButton!
- var smallVC : KMDesignButton!
- var minimumVC : KMDesignButton!
- var cancelVC : KMDesignButton!
- var compressVC : KMDesignButton!
- deinit {
- KMPrint("KMCompressWindowController 已释放")
- }
-
- override func windowDidLoad() {
- super.windowDidLoad()
- self.window?.appearance = NSAppearance(named: .aqua)
- largeVC = KMDesignButton.init(withType: .RadioButton)
- standardVC = KMDesignButton.init(withType: .RadioButton)
- smallVC = KMDesignButton.init(withType: .RadioButton)
- minimumVC = KMDesignButton.init(withType: .RadioButton)
- cancelVC = KMDesignButton.init(withType: .Text)
- compressVC = KMDesignButton.init(withType: .Text)
- largeBox.fillColor = .clear
- largeBox.contentView = largeVC.view
- standardBox.fillColor = .clear
- standardBox.contentView = standardVC.view
- smallBox.fillColor = .clear
- smallBox.contentView = smallVC.view
- minimumBox.fillColor = .clear
- minimumBox.contentView = minimumVC.view
- cancelBox.fillColor = .clear
- cancelBox.contentView = cancelVC.view
- compressBox.fillColor = .clear
- compressBox.contentView = compressVC.view
-
- titleLabel.stringValue = NSLocalizedString("Compress", comment: "")
-
- batchButton.isBordered = false
- batchButton.title = NSLocalizedString("Batch", comment: "")
- batchButton.wantsLayer = true
- batchButton.layer?.borderWidth = 1
- batchButton.layer?.borderColor = NSColor.black.cgColor
- batchButton.layer?.cornerRadius = 4
- batchButton.target = self
- batchButton.action = #selector(batchButtonAction)
- batchButton.isHidden = true
-
- cancelVC.target = self
- cancelVC.action = #selector(cancelButtonAction)
- cancelVC.stringValue = NSLocalizedString("Cancel", comment: "")
- cancelVC.button(type: .Sec, size: .m)
- cancelVC.button.keyEquivalent = KMKeyEquivalent.esc.string()
-
- compressVC.target = self
- compressVC.action = #selector(compressButtonAction)
- compressVC.stringValue = NSLocalizedString("Compress", comment: "")
- compressVC.button(type: .Cta, size: .m)
- compressVC.button.keyEquivalent = KMKeyEquivalent.enter
-
- largeVC.target = self
- largeVC.action = #selector(self.radioButtonAction(_:))
- largeVC.stringValue = NSLocalizedString("Large File Size", comment: "")
- largeVC.checkbox_radio()
-
- standardVC.target = self
- standardVC.action = #selector(self.radioButtonAction(_:))
- standardVC.stringValue = NSLocalizedString("Standard File Size", comment: "")
- standardVC.checkbox_radio()
- smallVC.target = self
- smallVC.action = #selector(self.radioButtonAction(_:))
- smallVC.stringValue = NSLocalizedString("Small File Size", comment: "")
- smallVC.checkbox_radio()
- minimumVC.target = self
- minimumVC.action = #selector(self.radioButtonAction(_:))
- minimumVC.stringValue = NSLocalizedString("Minimum File Size", comment: "")
- minimumVC.checkbox_radio()
-
- self.initUIProperty()
-
- smallVC.state = .Checked
- }
-
- private func initUIProperty() {
- self.titleLabel.textColor = NSColor.titleColor()
- self.titleLabel.font = .SFProTextSemibold(16)
-
- self.batchButton.setTitleColor(NSColor.buttonTitleColor())
- self.batchButton.layer?.borderColor = NSColor.buttonBorderColor().cgColor
- self.batchButton.font = .SFProTextRegular(14)
- }
-
- @objc func radioButtonAction(_ sender: NSButton) {
- largeVC.state = .Norm
- standardVC.state = .Norm
- smallVC.state = .Norm
- minimumVC.state = .Norm
- if (largeVC.button == sender) {
- largeVC.state = .Checked
- self.selectIndex = 0
- } else if (standardVC.button == sender) {
- standardVC.state = .Checked
- self.selectIndex = 1
- } else if (smallVC.button == sender) {
- smallVC.state = .Checked
- self.selectIndex = 2
- } else if (minimumVC.button == sender) {
- minimumVC.state = .Checked
- self.selectIndex = 3
- }
- }
-
- @objc func batchButtonAction() {
- guard let callback = itemClick else {
- return
- }
-
- callback(1)
- }
-
- @objc func cancelButtonAction() {
- guard let callback = itemClick else {
- return
- }
-
- callback(2)
- }
-
- @objc func compressButtonAction() {
- if documentURL == nil {
- return
- }
-
- NSPanel.savePanel(self.window!, true) { panel in
- panel.nameFieldStringValue = ""+self.documentURL.deletingPathExtension().lastPathComponent+"_Compressed"
- panel.allowedFileTypes = ["pdf"]
- } completion: { response, url, isOpen in
- if (response == .cancel) {
- return
- }
-
- self.beginLoading()
- DispatchQueue.main.async {
- let docuemt = CPDFDocument.init(url: self.documentURL)
- if (docuemt?.isLocked)! && self.password != nil {
- docuemt?.unlock(withPassword: self.password)
- }
-
- var option = 60
- if self.selectIndex == 0 {
- option = 120
- } else if self.selectIndex == 1 {
- option = 90
- } else if self.selectIndex == 2 {
- option = 60
- } else if self.selectIndex == 3 {
- option = 30
- }
-
- let result = docuemt?.writeOptimize(to: url, withOptions: [.imageQualityOption : option])
-
- self.endLoading()
- guard let callback = self.resultCallback else {
- if result! {
- if isOpen { /// 开启文档
- if !url!.path.isPDFValid() {
- let alert = NSAlert()
- alert.alertStyle = .critical
- alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
- alert.runModal()
- return
- }
- NSDocumentController.shared.openDocument(withContentsOf: url!, display: true) { document, alreadyOpen, error in
-
- }
- } else {
- NSWorkspace.shared.activateFileViewerSelecting([url!])
- }
- }
- return
- }
-
- callback(result!, isOpen, url!, "")
- }
- }
- }
-
- func getUniqueFilePath(filePath: String) -> String {
- var i: Int = 0
- var isDirectory: ObjCBool = false
- var uniqueFilePath = filePath
- let fileManager = FileManager.default
- fileManager.fileExists(atPath: uniqueFilePath, isDirectory: &isDirectory)
- if isDirectory.boolValue {
- var path: String = ""
- while fileManager.fileExists(atPath: uniqueFilePath) {
- i += 1
-
- path = filePath
- path.append("(\(i))")
- uniqueFilePath = path
- }
- } else {
- let fileURL = URL(fileURLWithPath: filePath)
- var path: String = ""
- while fileManager.fileExists(atPath: uniqueFilePath) {
- i += 1
-
- path = fileURL.deletingPathExtension().path
- path.append("(\(i))")
- path.append(".")
- path.append(fileURL.pathExtension)
- uniqueFilePath = path
- }
- }
- return uniqueFilePath
- }
-
- }
- extension KMCompressWindowController: NSTableViewDataSource {
- func numberOfRows(in tableView: NSTableView) -> Int {
- datas.count
- }
-
- }
- extension KMCompressWindowController: KMLoadingProtocol {
- func beginLoading() {
- self.window?.contentView?.beginLoading()
- }
-
- func endLoading() {
- self.window?.contentView?.endLoading()
- }
- }
|