|
@@ -1,477 +0,0 @@
|
|
|
-//
|
|
|
-// KMBaseViewController.swift
|
|
|
-// PDF Reader Pro
|
|
|
-//
|
|
|
-// Created by tangchao on 2023/5/5.
|
|
|
-//
|
|
|
-
|
|
|
-import Cocoa
|
|
|
-
|
|
|
-// 基类 [抽象类]
|
|
|
-class KMBaseViewController: NSViewController {
|
|
|
- // 是否需要菜单
|
|
|
- var needMenu = false {
|
|
|
- didSet {
|
|
|
- if (self.needMenu) {
|
|
|
- self.addMenu(to: self.view)
|
|
|
- } else {
|
|
|
- self.removeMenu(to: self.view)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- deinit {
|
|
|
- Swift.debugPrint(self.className + " 已释放")
|
|
|
-
|
|
|
- self.removeNotifations()
|
|
|
- }
|
|
|
-
|
|
|
- override func viewDidLoad() {
|
|
|
- super.viewDidLoad()
|
|
|
-
|
|
|
- if (self.needMenu) {
|
|
|
- self.addMenu(to: self.view)
|
|
|
- } else {
|
|
|
- self.removeMenu(to: self.view)
|
|
|
- }
|
|
|
-
|
|
|
- self.addNotifations()
|
|
|
- }
|
|
|
-
|
|
|
- // Noti
|
|
|
-
|
|
|
- func addNotifations() { }
|
|
|
-
|
|
|
- func removeNotifations() {
|
|
|
- NotificationCenter.default.removeObserver(self)
|
|
|
- }
|
|
|
-
|
|
|
- func km_add_office_multi(fileUrls: [URL], completionBlock:@escaping ([String])->Void) -> Void {
|
|
|
- var fileUrlStrings: [String] = []
|
|
|
-
|
|
|
- let dispatchGroup = Dispatch.DispatchGroup()
|
|
|
- for (index, fileUrl) in fileUrls.enumerated() {
|
|
|
- let filePath = fileUrl.path
|
|
|
- let folderPath = "convertToPDF_\(index).pdf"
|
|
|
- let savePath: String? = folderPath.kUrlToPDFFolderPath() as String
|
|
|
- if (savePath == nil) {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- dispatchGroup.enter()
|
|
|
- KMConvertPDFManager.convertFile(filePath, savePath: savePath!) { success, errorDic in
|
|
|
- if errorDic != nil || !success || !FileManager.default.fileExists(atPath: savePath!) {
|
|
|
- dispatchGroup.leave()
|
|
|
-
|
|
|
- if FileManager.default.fileExists(atPath: savePath!) {
|
|
|
- try?FileManager.default.removeItem(atPath: savePath!)
|
|
|
- }
|
|
|
- let alert = NSAlert.init()
|
|
|
- alert.alertStyle = .critical
|
|
|
- var infoString = ""
|
|
|
- if errorDic != nil {
|
|
|
- for key in (errorDic! as Dictionary).keys {
|
|
|
- infoString = infoString.appendingFormat("%@\n", errorDic![key] as! CVarArg)
|
|
|
- }
|
|
|
- }
|
|
|
- alert.informativeText = NSLocalizedString("Please install Microsoft Office to create PDFs from Office files", comment: "")
|
|
|
- alert.messageText = NSLocalizedString("Failed to Create PDF", comment: "")
|
|
|
- alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
|
|
|
- alert.runModal()
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- if !savePath!.isPDFValid() {
|
|
|
- dispatchGroup.leave()
|
|
|
-
|
|
|
- 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
|
|
|
- }
|
|
|
-
|
|
|
- fileUrlStrings.append(savePath!)
|
|
|
- dispatchGroup.leave()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- dispatchGroup.notify(queue: DispatchQueue.main) {
|
|
|
- completionBlock(fileUrlStrings)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // MARK: - Open Password Files
|
|
|
-
|
|
|
- private var lockedFiles: [URL] = []
|
|
|
- func km_open_pdf_multi(type: KMPasswordInputWindowType = .open, progressBlock: ((_ index: Int, _ params: Any...)->Void)? = nil, completionBlock:@escaping ([CPDFDocument])->Void) {
|
|
|
- NSPanel.km_open_pdf_multi_success(self.view.window!, panel: nil) { urls in
|
|
|
- self.km_add_pdf_multi(fileUrls: urls, type: type, progressBlock: progressBlock, completionBlock: completionBlock)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- func km_open_file_multi(type: KMPasswordInputWindowType = .open, progressBlock: ((_ index: Int, _ params: Any...)->Void)? = nil, completionBlock:@escaping ([CPDFDocument])->Void) {
|
|
|
- NSPanel.km_open_multi_success(self.view.window!) { panel in
|
|
|
- var array: [String] = []
|
|
|
- for fileType in KMConvertPDFManager.supportFileType() {
|
|
|
- array.append(fileType)
|
|
|
- }
|
|
|
- panel.allowedFileTypes = KMTools.pdfExtensions + array
|
|
|
- } completion: { urls in
|
|
|
- self.km_add_file_multi(fileUrls: urls, type: type, progressBlock: progressBlock, completionBlock: completionBlock)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- func km_add_pdf_multi(fileUrlStrings: [String] ,type: KMPasswordInputWindowType = .open, progressBlock: ((_ index: Int, _ params: Any...)->Void)? = nil, completionBlock:@escaping ([CPDFDocument])->Void) {
|
|
|
- var urls: [URL] = []
|
|
|
- for string in fileUrlStrings {
|
|
|
- urls.append(URL(fileURLWithPath: string))
|
|
|
- }
|
|
|
- self.km_add_pdf_multi(fileUrls: urls, type: type, progressBlock: progressBlock, completionBlock: completionBlock)
|
|
|
- }
|
|
|
-
|
|
|
- func km_add_pdf_multi(fileUrls: [URL] ,type: KMPasswordInputWindowType = .open, progressBlock: ((_ index: Int, _ params: Any...)->Void)? = nil, completionBlock:@escaping ([CPDFDocument])->Void) {
|
|
|
- var results: [CPDFDocument] = []
|
|
|
-
|
|
|
- self.lockedFiles.removeAll()
|
|
|
- var index = 0
|
|
|
- for url in fileUrls {
|
|
|
- let document = CPDFDocument(url: url)
|
|
|
- if (document!.isLocked) {
|
|
|
- self.lockedFiles.append(url)
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- if let _document = document {
|
|
|
- results.append(_document)
|
|
|
- }
|
|
|
-
|
|
|
- index += 1
|
|
|
- if let _callback = progressBlock {
|
|
|
- _callback(index, ((document != nil) ? document : CPDFDocument()) as Any, url)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (self.lockedFiles.count == 0) {
|
|
|
- completionBlock(results)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
-// if let _callback = progressBlock {
|
|
|
-// _callback(0, results)
|
|
|
-// }
|
|
|
-
|
|
|
- self._openPasswordWindow_loop(fileUrl: self.lockedFiles.first!, type: type) { params in
|
|
|
- index += 1
|
|
|
- if (params.count <= 2) { // 参数错误
|
|
|
- if let _callback = progressBlock { // 回调进度
|
|
|
- _callback(index)
|
|
|
- }
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- let fileUrl = params[0] as! URL
|
|
|
- let result = params[1] as! KMPasswordInputWindowResult
|
|
|
- let password = params[2] as? String
|
|
|
- if (result == .cancel) {
|
|
|
- if let _callback = progressBlock { // 回调进度
|
|
|
- _callback(index, CPDFDocument() as Any, fileUrl, result)
|
|
|
- }
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- let document = CPDFDocument(url: fileUrl)
|
|
|
- if let _password = password { // 将文档进行解密
|
|
|
- document?.unlock(withPassword: _password)
|
|
|
- }
|
|
|
- if let _callback = progressBlock { // 回调进度
|
|
|
- _callback(index, document as Any, fileUrl, result, password as Any)
|
|
|
- }
|
|
|
- // 将文档加入返回数据
|
|
|
- if let _document = document {
|
|
|
- results.append(_document)
|
|
|
- }
|
|
|
- } completionBlock: {
|
|
|
- completionBlock(results)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- func km_add_file_multi(fileUrls: [URL] ,type: KMPasswordInputWindowType = .open, progressBlock: ((_ index: Int, _ params: Any...)->Void)? = nil, completionBlock:@escaping ([CPDFDocument])->Void) {
|
|
|
- var pdfUrls: [URL] = []
|
|
|
- var imageUrls: [URL] = []
|
|
|
- var officeUrls: [URL] = []
|
|
|
- for url in fileUrls {
|
|
|
- let type = url.pathExtension.lowercased()
|
|
|
- if (KMTools.isPDFType(type)) {
|
|
|
- pdfUrls.append(url)
|
|
|
- }
|
|
|
- if (KMTools.isImageType(type)) {
|
|
|
- imageUrls.append(url)
|
|
|
- }
|
|
|
- if (KMTools.isOfficeType(type)) {
|
|
|
- officeUrls.append(url)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (officeUrls.count == 0) {
|
|
|
- self.km_add_pdf_multi(fileUrls: pdfUrls, type: type, progressBlock: progressBlock) { documents in
|
|
|
- var index = documents.count
|
|
|
- var _documents: [CPDFDocument] = []
|
|
|
- for imageUrl in imageUrls {
|
|
|
- index += 1
|
|
|
- let document = CPDFDocument()
|
|
|
- let image = NSImage(contentsOfFile: imageUrl.path)
|
|
|
-// document?.insertPage(image!.size, withImage: imageUrl.path, at: 0)
|
|
|
- document?.km_insertPage(image?.size ?? .zero, withImage: imageUrl.path, at: 0)
|
|
|
- _documents.append(document!)
|
|
|
-
|
|
|
- if let _callback = progressBlock { // 回调进度
|
|
|
- _callback(index, document as Any, imageUrl)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- completionBlock(documents + _documents)
|
|
|
- }
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- self.km_add_office_multi(fileUrls: officeUrls) { [unowned self] fileUrlStrings in
|
|
|
- var officeDocuments: [CPDFDocument] = []
|
|
|
- var index = 0
|
|
|
- for fileUrlString in fileUrlStrings {
|
|
|
- index += 1
|
|
|
- let document = CPDFDocument(url: URL(fileURLWithPath: fileUrlString))
|
|
|
- officeDocuments.append(document!)
|
|
|
-
|
|
|
- if let _callback = progressBlock { // 回调进度
|
|
|
- _callback(index, document as Any, URL(fileURLWithPath: fileUrlString))
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- self.km_add_pdf_multi(fileUrls: pdfUrls) { documents in
|
|
|
- var index = documents.count + officeDocuments.count
|
|
|
- var _documents: [CPDFDocument] = []
|
|
|
- for imageUrl in imageUrls {
|
|
|
- index += 1
|
|
|
- let document = CPDFDocument()
|
|
|
- let image = NSImage(contentsOfFile: imageUrl.path)
|
|
|
-// document?.insertPage(image!.size, withImage: imageUrl.path, at: 0)
|
|
|
- document?.km_insertPage(image!.size, withImage: imageUrl.path, at: 0)
|
|
|
- _documents.append(document!)
|
|
|
-
|
|
|
- if let _callback = progressBlock { // 回调进度
|
|
|
- _callback(index, document as Any, imageUrl)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- completionBlock(officeDocuments + documents + _documents)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // MARK: - ProgressBlock Params Fetch
|
|
|
-
|
|
|
- func fetchProgressBlockParamsForDocument(params: Any...) -> CPDFDocument? {
|
|
|
- return params.first as? CPDFDocument
|
|
|
- }
|
|
|
- func fetchProgressBlockParamsForFileUrl(params: Any...) -> URL? {
|
|
|
- if (params.count < 2) {
|
|
|
- return nil
|
|
|
- }
|
|
|
- return params[1] as? URL
|
|
|
- }
|
|
|
-
|
|
|
- func fetchProgressBlockParamsForResult(params: Any...) -> KMPasswordInputWindowResult? {
|
|
|
- if (params.count <= 2) {
|
|
|
- return nil
|
|
|
- }
|
|
|
- return params[2] as? KMPasswordInputWindowResult
|
|
|
- }
|
|
|
- func fetchProgressBlockParamsForPassword(params: Any...) -> String? {
|
|
|
- if (params.count <= 2) {
|
|
|
- return nil
|
|
|
- }
|
|
|
- return params.last as? String
|
|
|
- }
|
|
|
- func fetchProgressBlockParamsIsPasswordFile(params: Any...) -> Bool {
|
|
|
- if (params.count <= 2) {
|
|
|
- return false
|
|
|
- }
|
|
|
- return true
|
|
|
- }
|
|
|
-
|
|
|
- // MARK: - Open Password Window
|
|
|
- // 留意:
|
|
|
- // -会直接弹密码弹窗,不会判断文档是否加密
|
|
|
- // -在使用前最好判断下文件是否已加密
|
|
|
-
|
|
|
- func openPasswordWindow(fileUrlString: String, type: KMPasswordInputWindowType = .open, completionBlock:@escaping (KMPasswordInputWindowResult, String?)->Void) {
|
|
|
- self.openPasswordWindow(fileUrl: URL(fileURLWithPath: fileUrlString), type: type, completionBlock: completionBlock)
|
|
|
- }
|
|
|
-
|
|
|
- func openPasswordWindow(fileUrl: URL, type: KMPasswordInputWindowType = .open, completionBlock:@escaping (KMPasswordInputWindowResult, String?)->Void) {
|
|
|
- KMPasswordInputWindow.openWindow(window: self.view.window!, type: type, url: fileUrl, callback: completionBlock)
|
|
|
- }
|
|
|
-
|
|
|
- func openPasswordWindow_success(fileUrlString: String, type: KMPasswordInputWindowType = .open, completionBlock:@escaping (String)->Void) {
|
|
|
- self.openPasswordWindow_success(fileUrl: URL(fileURLWithPath: fileUrlString), type: type, completionBlock: completionBlock)
|
|
|
- }
|
|
|
-
|
|
|
- func openPasswordWindow_success(fileUrl: URL, type: KMPasswordInputWindowType = .open, completionBlock:@escaping (String)->Void) {
|
|
|
- KMPasswordInputWindow.success_openWindow(window: self.view.window!, url: fileUrl, callback: completionBlock)
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- fileprivate func _openPasswordWindow_loop(fileUrl: URL, type: KMPasswordInputWindowType, progressBlock: ((_ params: Any...)->Void)?, completionBlock:@escaping ()->Void) {
|
|
|
- KMPasswordInputWindow.openWindow(window: self.view.window!, type: type, url: fileUrl) { [weak self] result, password in
|
|
|
- // 将结果返回
|
|
|
- if let _callback = progressBlock {
|
|
|
- _callback(fileUrl, result, password as Any)
|
|
|
- }
|
|
|
-
|
|
|
- // 进行下一个
|
|
|
- self?.lockedFiles.removeFirst()
|
|
|
- if let _fileUrl = self?.lockedFiles.first {
|
|
|
- self?._openPasswordWindow_loop(fileUrl: _fileUrl, type: type, progressBlock: progressBlock, completionBlock: completionBlock)
|
|
|
- } else {
|
|
|
- completionBlock()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // MARK: - Progress Window
|
|
|
-
|
|
|
- var progressC: SKProgressController?
|
|
|
- func showProgressWindow(message: String = "") {
|
|
|
- if (self.progressC != nil) {
|
|
|
- self.hiddenProgressWindow()
|
|
|
- }
|
|
|
-
|
|
|
- let progressC = SKProgressController()
|
|
|
- progressC.window?.backgroundColor = NSColor.km_init(hex: "#36383B")
|
|
|
- progressC.window?.contentView?.wantsLayer = true
|
|
|
- progressC.window?.contentView?.layer?.backgroundColor = NSColor.km_init(hex: "#36383B").cgColor
|
|
|
- progressC.progressField.textColor = NSColor.white
|
|
|
- progressC.showClose = false
|
|
|
- progressC.message = message
|
|
|
-
|
|
|
- self.progressC = progressC
|
|
|
- self.view.window?.beginSheet(progressC.window!)
|
|
|
- }
|
|
|
-
|
|
|
- func hiddenProgressWindow() {
|
|
|
- if let _progressC = self.progressC {
|
|
|
- if let _window = _progressC.window {
|
|
|
- self.view.window?.endSheet(_window)
|
|
|
- }
|
|
|
- self.progressC = nil
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // MARK: - Menu Add & Remove
|
|
|
-
|
|
|
- public func addMenu(to view: NSView?) {
|
|
|
- if let menuView = view {
|
|
|
- self.addMenu(to: menuView)
|
|
|
- return
|
|
|
- }
|
|
|
- self.addMenu(to: self.view)
|
|
|
- }
|
|
|
-
|
|
|
- public func removeMenu(to view: NSView?) {
|
|
|
- if let menuView = view {
|
|
|
- self.removeMenu(to: menuView)
|
|
|
- return
|
|
|
- }
|
|
|
- self.removeMenu(to: self.view)
|
|
|
- }
|
|
|
-
|
|
|
- private func addMenu(to view: NSView) {
|
|
|
- // 先移除
|
|
|
- self.removeMenu(to: view)
|
|
|
-
|
|
|
- let menu = NSMenu()
|
|
|
- menu.delegate = self
|
|
|
- view.menu = menu
|
|
|
- }
|
|
|
- private func removeMenu(to view: NSView) {
|
|
|
- view.menu?.delegate = nil
|
|
|
- view.menu = nil
|
|
|
- }
|
|
|
-
|
|
|
- // MARK: - Document isDocumentEdited
|
|
|
-
|
|
|
- public func setDocumentEditedState(window: NSWindow? = nil) {
|
|
|
- var _win = window
|
|
|
- if (_win == nil) {
|
|
|
- _win = self.view.window
|
|
|
- }
|
|
|
- guard let _window = _win else {
|
|
|
- return
|
|
|
- }
|
|
|
- guard let _document = NSDocumentController.shared.document(for: _window) else {
|
|
|
- return
|
|
|
- }
|
|
|
- self.setDocumentEditedState(document: _document)
|
|
|
- }
|
|
|
-
|
|
|
- public func setDocumentEditedState(url: URL? = nil) {
|
|
|
- if let _url = url {
|
|
|
- KMTools.setDocumentEditedState(url: _url)
|
|
|
- } else {
|
|
|
- self.setDocumentEditedState(window: self.view.window)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public func setDocumentEditedState(document: NSDocument) {
|
|
|
- km_synchronized(document) {
|
|
|
- if let _document = document as? KMMainDocument {
|
|
|
- _document.km_updateChangeCount(.changeDone)
|
|
|
- } else {
|
|
|
- document.updateChangeCount(.changeDone)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public func clearDocumentEditedState(window: NSWindow? = nil) {
|
|
|
- var _win = window
|
|
|
- if (_win == nil) {
|
|
|
- _win = self.view.window
|
|
|
- }
|
|
|
- guard let _window = _win else {
|
|
|
- return
|
|
|
- }
|
|
|
- guard let _document = NSDocumentController.shared.document(for: _window) else {
|
|
|
- return
|
|
|
- }
|
|
|
- self.clearDocumentEditedState(document: _document)
|
|
|
- }
|
|
|
-
|
|
|
- public func clearDocumentEditedState(url: URL? = nil) {
|
|
|
- if let _url = url {
|
|
|
- KMTools.clearDocumentEditedState(url: _url)
|
|
|
- } else {
|
|
|
- self.clearDocumentEditedState(window: self.view.window)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public func clearDocumentEditedState(document: NSDocument) {
|
|
|
- km_synchronized(document) {
|
|
|
- if let _document = document as? KMMainDocument {
|
|
|
- _document.km_updateChangeCount(.changeCleared)
|
|
|
- } else {
|
|
|
- document.updateChangeCount(.changeCleared)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-extension KMBaseViewController: NSMenuDelegate, NSMenuItemValidation {
|
|
|
- func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
|
|
|
- return true
|
|
|
- }
|
|
|
-
|
|
|
- func menuNeedsUpdate(_ menu: NSMenu) {
|
|
|
- menu.removeAllItems()
|
|
|
- }
|
|
|
-}
|