123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- //
- // KMBatchOperateBaseViewController.swift
- // PDF Reader Pro
- //
- // Created by kdanmobile on 2023/10/30.
- //
- import Cocoa
- //var kBatchQueueOperationsChanged = "kBatchQueueOperationsChanged"
- private var kBatchQueueOperationsChanged = 0x000101
- class KMBatchOperateBaseViewController: NSViewController, KMBatchOperateProtocol{
- var operateType: KMBatchOperationType?
- var convertType: KMConvertWithPDFType?
- var files: [KMBatchOperateFile]?
- lazy var queue: KMOperationQueue? = {
- var queue: KMOperationQueue?
- if !((self.view.window as? KMBatchWindow)?.isBatch ?? false) {
- queue = KMOperationQueue()
- } else {
- if self.operateType == .Convert {
- queue = KMConvertOperationQueue.sharedQueue
- } else if self.operateType == .Compress {
- queue = KMCompressOperationQueue.sharedQueue
- } else if self.operateType == .AddPassword {
- queue = KMAddPasswordOperationQueue.sharedQueue
- } else if self.operateType == .RemovePassword {
- queue = KMRemovePasswordOperationQueue.sharedQueue
- } else if self.operateType == .AddWatermark {
- queue = KMAddWatermarkOprationQueue.sharedQueue
- } else if self.operateType == .RemoveWatermark {
- queue = KMRemoveWatermarkOperationQueue.sharedQueue
- } else if self.operateType == .AddBackground {
- queue = KMAddBackgroundOperationQueue.sharedQueue
- } else if self.operateType == .RemoveBackground {
- queue = KMRemoveBackgroundOperationQueue.sharedQueue
- } else if self.operateType == .AddHeaderFooter {
- queue = KMAddHeaderFooterOperationQueue.sharedQueue
- } else if self.operateType == .RemoveHeaderFooter {
- queue = KMRemoveHeaderFooterQueue.sharedQueue
- } else if self.operateType == .AddBates {
- queue = KMAddBatesOperationQueue.sharedQueue
- } else if self.operateType == .RemoveBates {
- queue = KMRemoveBatesOperationQueue.sharedQueue
- }
- }
- return queue
- }()
- lazy var successFilePathURLArray: [URL]? = {
- let arr = NSMutableArray()
- return (arr as! [URL])
- }()
- var name: String = ""
- var interfaceStatus: KMBatchOperateInterfaceStatus?
- var choosePath: String = ""
-
- init(files: [KMBatchOperateFile]) {
- super.init(nibName: String(describing: type(of: self)), bundle: nil)
- self.files = (files)
- }
-
- required init?(coder: NSCoder) {
- super.init(coder: coder)
- }
- deinit {
- // queue?.removeObserver(self, forKeyPath: "operations")
- }
- override func viewDidLoad() {
- super.viewDidLoad()
- self.queue?.addObserver(self, forKeyPath: "operations", options: .new, context: &kBatchQueueOperationsChanged)
- }
-
- func operateCompleted() {
- showWindowCloseButton()
- if successFilePathURLArray!.count > 0 {
- NSWorkspace.shared.activateFileViewerSelecting(successFilePathURLArray!)
- }
- self.interfaceStatus = .PrepareProcess
- }
- func showWindowCloseButton() {
- let btn = self.view.window?.standardWindowButton(NSWindow.ButtonType.closeButton)
- btn?.isHidden = false
- }
- func beginBatchOperation() {
- for i in 0..<self.files!.count {
- let file = self.files?[i]
- file?.currentOperateInfo?.resetState()
- }
- if self.files!.count < 1 {
- NSSound.beep()
- return
- }
-
- self.fetchFileListViewController()!.reloadData()
-
- let openPanel = NSOpenPanel()
- openPanel.canChooseFiles = false
- openPanel.canChooseDirectories = true
- openPanel.canCreateDirectories = true
- openPanel.beginSheetModal(for: self.view.window!) { (result) in
- if result == NSApplication.ModalResponse.OK {
- for fileURL in openPanel.urls {
- self.choosePath = fileURL.path
- self.beginQueueOperation()
- }
- }
- }
- }
- func fetchFileListViewController() -> KMBatchOperateLeftViewController? {
- guard let vc = self.view.window?.contentViewController as? KMBatchOperateSplitViewController,
- let viewController = vc.splitViewItems.first?.viewController as? KMBatchOperateLeftViewController
- else {
- return nil
- }
- return viewController
- }
- func beginQueueOperation() {//业务逻辑转移到数据处理层
- // hiddenWindowCloseButtonIfNeeded()
- self.successFilePathURLArray?.removeAll()
- for i in 0..<self.files!.count {
- let file = self.files![i]
- if file.fileType == .PDF {
- if self.operateType == .Convert {
- file.convertType = self.convertType ?? .WordAdvance
- }
- file.currentOperateInfo?.savePath = self.choosePath
- let operation = operationWithFile(file)
- operation.delegate = self
- self.queue?.addOperation(operation)
- }
- }
- if self.queue?.operations.count ?? 0 > 0 {
- self.interfaceStatus = .Processing
- }
- }
- func operationWithFile(_ file: KMBatchOperateFile) -> KMBatchOperation {
- var operation: KMBatchOperation?
- if self.operateType == .Convert {
- return KMBatchConvertOperation(file: file, convertType: self.convertType!)
- } else if self.operateType == .Compress {
- return KMCompressOperation(file: file, compressValue: 60)
- } else if self.operateType == .AddPassword {
- // handle AddPassword operation
- } else if self.operateType == .RemovePassword {
- return KMBatchRemovePasswordOperation(file: file)
- } else if self.operateType == .AddWatermark {
- // handle AddWatermark operation
- } else if self.operateType == .RemoveWatermark {
- return KMBatchRemoveWatermarkOperation(file: file)
- } else if self.operateType == .AddBackground {
- // handle AddBackground operation
- } else if self.operateType == .RemoveBackground {
- return KMBatchRemoveBackgroundOperation(file: file)
- } else if self.operateType == .AddHeaderFooter {
- // handle AddHeaderFooter operation
- } else if self.operateType == .RemoveHeaderFooter {
- return KMBatchRemoveHeaderFooterOperation(file: file)
- } else if self.operateType == .AddBates {
- // operation = KMBatchRemoveHeaderFooterOperation(file: file)
- } else if self.operateType == .RemoveBates {
- var op = KMBatchRemoveHeaderFooterOperation(file: file)
- op.isBates = true
- return op
- } else {
-
- }
- return operation ?? KMBatchOperation(file: file)
- }
- func cancelBatchOperation() {
- for i in 0..<(self.queue?.operations.count)! {
- let operation = self.queue?.operations[i]
- if !operation!.isExecuting {
- operation?.cancel()
- } else {
- // Do nothing
- }
- }
- self.interfaceStatus = .PrepareProcess
- }
- func hiddenWindowCloseButtonIfNeeded() {
- let btn = self.view.window?.standardWindowButton(NSWindow.ButtonType.closeButton)
- btn?.isHidden = true
- }
- func allPageNumbers(_ pageString: String) -> [NSNumber] {
- let array = pageString.components(separatedBy: ",")
- let pageNumbers = NSMutableArray()
- var isInvalid = false
- for s in array {
- if s == "" {
- isInvalid = true
- break
- } else {
- let pages = s.components(separatedBy: "-")
- if pages.count > 2 {
- isInvalid = true
- break
- } else if pages.count == 1 {
- let p = pages[0]
- if p == "" || Int(p) == 0 {
- isInvalid = true
- break
- } else {
- var isEqual = false
- for pageNumber in pageNumbers {
- if (pageNumber as AnyObject).intValue == Int(p) {
- isEqual = true
- isInvalid = true
- break
- }
- }
- if !isEqual {
- pageNumbers.add(NSNumber(value: Int(p)!))
- }
- }
- } else if pages.count == 2 {
- let p1 = pages[0]
- let p2 = pages[1]
- if p1 == "" || p2 == "" || Int(p1)! >= Int(p2)! || Int(p1) == 0 {
- isInvalid = true
- break
- } else {
- var isEqual = false
- for i in Int(p1)!...Int(p2)! {
- for pageNumber in pageNumbers {
- if (pageNumber as AnyObject).intValue == i {
- isEqual = true
- isInvalid = true
- break
- }
- }
- }
- if !isEqual {
- for i in Int(p1)!...Int(p2)! {
- pageNumbers.add(NSNumber(value: i))
- }
- }
- }
- }
- }
- }
- return pageNumbers as! [NSNumber]
- }
- override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
- if keyPath == "operations" && context == &kBatchQueueOperationsChanged {
- if self.queue?.operations.count == 0 {
- DispatchQueue.main.async {
- self.operateCompleted()
- }
- }
- } else {
- super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
- }
- }
- }
- extension KMBatchOperateBaseViewController{
- func fileBeginOperate(_ file: KMBatchOperateFile, info: KMBatchBaseParameter) {
- DispatchQueue.main.async {
- info.status = .processing
- self.fetchFileListViewController()?.reloadFile(file)
- }
- }
- func fileOperating(_ file: KMBatchOperateFile, progress: CGFloat, info: KMBatchBaseParameter) {
- DispatchQueue.main.async {
- info.progress = Float(progress)
- self.fetchFileListViewController()?.reloadFile(file)
- }
- }
- func fileOperateSuccessed(_ file: KMBatchOperateFile, info: KMBatchBaseParameter) {
- DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
- info.status = .Success
- if info.outPutPath?.count ?? 0 > 0{
- let url: URL = URL(fileURLWithPath: info.outPutPath!)
- self.successFilePathURLArray?.append(url)
- }
- self.fetchFileListViewController()?.reloadFile(file)
- }
- }
- func fileOperateFailed(_ file: KMBatchOperateFile, error: NSError, info: KMBatchBaseParameter) {
- DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
- info.status = .Failed
- info.error = error
- self.fetchFileListViewController()?.reloadData()
- }
- }
- func fileOperateCanceled(_ file: KMBatchOperateFile, info: KMBatchBaseParameter) {
- DispatchQueue.main.async {
- info.status = .Waiting
- info.error = nil
- self.fetchFileListViewController()?.reloadFile(file)
- }
- }
- }
|