// // KMHomeViewController+Action.swift // PDF Reader Pro // // Created by wanjun on 2022/10/13. // import Foundation extension KMHomeViewController: NSMenuItemValidation { func validateMenuItem(_ menuItem: NSMenuItem) -> Bool { if (menuItem.action == #selector(menuItemAction_currentWindowName)) { menuItem.title = NSLocalizedString("Home", comment: "") return true } if (menuItem.action == #selector(menuItemAction_showForwardTagPage) || menuItem.action == #selector(menuItemAction_showNextTagPage)) { if (self.myDocument != nil && (self.myDocument is KMMainDocument)) { let browser = (self.myDocument as! KMMainDocument).browser if (menuItem.action == #selector(menuItemAction_showForwardTagPage)) { return (browser as! KMBrowser).canSelectPreviousTab() } if (menuItem.action == #selector(menuItemAction_showNextTagPage)) { return (browser as! KMBrowser).canSelectNextTab() } } } if (menuItem.action == #selector(menuItemAction_mergeAllWindow)) { if let _browserWindowC = ((self.myDocument as? KMMainDocument)?.browser.windowController as? KMBrowserWindowController) { return _browserWindowC.canMergeAllWindow() } } if (menuItem.action == #selector(menuItemAction_ConvertToWord) || menuItem.action == #selector(menuItemAction_ConvertToExcel) || menuItem.action == #selector(menuItemAction_ConvertToPPT) || menuItem.action == #selector(menuItemAction_ConvertToRTF) || menuItem.action == #selector(menuItemAction_ConvertToHTML) || menuItem.action == #selector(menuItemAction_ConvertToText) || menuItem.action == #selector(menuItemAction_ConvertToCSV) || menuItem.action == #selector(menuItemAction_ConvertToImage)) { return false } if menuItem.action == #selector(menuItemClick_SettingPassword) || menuItem.action == #selector(menuItemClick_Compress) { guard let _windowC = NSApp.mainWindow?.windowController as? KMBrowserWindowController else { return false } let isHome = _windowC.browser?.activeTabContents()?.isHome ?? false return !isHome } return true } } extension KMHomeViewController { // MARK: Action @objc func homeToolAction(_ sender: NSButton) -> Void { if sender == homeButtonVC?.button { homeToolAction(homeToolState: KMHomeToolState.Home) } else if sender == pdfToolsButtonVC?.button { homeToolAction(homeToolState: KMHomeToolState.PDFTools) } else if sender == cloudDocumentsButtonVC?.button { homeToolAction(homeToolState: KMHomeToolState.CloudDocuments) } else if sender == openPDFButtonVC?.button { homeToolAction(homeToolState: KMHomeToolState.OpenPDF) } else if sender == createPDFButtonVC?.button { openSupportPDFButtonAction() } else if sender == createPDFImage?.button { homeToolAction(homeToolState: KMHomeToolState.CreatePDF) } } func homeToolAction(homeToolState: KMHomeToolState) { switch homeToolState { case .OpenPDF: openPDFButtonAction() break case .CreatePDF: break case .Home: homeButtonAction() break case .PDFTools: pdfToolsButtonAction() break case .FavoriteDocuments: favoriteDocumentsButtonAction() break case .CloudDocuments: cloudDocumentsButtonAction() break default: KMPrint("error: 错误的传入枚举") break } } func fastToolItemAction(_ type: DataNavigationViewButtonActionType) { print("fastToolItemAction + \(type.rawValue)") switch type { case .Batch: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Batch"]) fastTool_Batch() break case .OCR: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "OCR"]) fastTool_OCR() break case .ConvertPDF: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Convert PDF"]) fastTool_ConvertPDF() break case .ImageToPDF: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Image to PDF"]) fastTool_ImageToPDF() break case .MergePDF: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Merge"]) fastTool_MergePDF() break case .Compression: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Compress"]) fastTool_Compression() break case .Security: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Security"]) fastTool_Security() break case .FileCompare: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Compare"]) fastTool_FileCompare() break case .PDFToPPT: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "PDF to PPT"]) fastTool_PDFToPPT() break case .PDFToExcel: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "PDF to Excel"]) fastTool_PDFToExcel() break case .PDFToWord: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "PDF to Word"]) fastTool_PDFToWord() break case .PDFToImage: fastTool_PDFToImage() break case .Watermark: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Watermark"]) fastTool_Watermark() break case .Background: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Background"]) fastTool_Background() break case .HeaderAndFooter: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Header&Footer"]) fastTool_HeaderAndFooter() break case .BatesCode: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Bates Numbers"]) fastTool_BatesCode() break case .Print: fastTool_Print() break case .BatchRemove: fastTool_BatchRemove() break case .Insert: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Insert"]) fastTool_Insert() break case .BreakUp: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Split"]) fastTool_BreakUp() break case .Extract: fastTool_Extract() break case .MarkCipher: fastTool_MarkCipher() break case .AutomaticFormRecognition: fastTool_AutomaticFormRecognition() break case .PageEdit: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Page Edit"]) fastTool_PageEdit() break case .ComparativeTable: fastTool_FileCompare() break case .equity: break case .PrintMultipage: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Multiple"]) self.fastTool_printMultple() break case .PrintPoster: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Poster"]) self.fastTool_printPoster() break case .PrintBooklet: FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Booklet"]) self.fastTool_printBooklet() break case .AITools: // FMTrackEventManager.defaultManager.trackEvent(event: "Onbrd", withProperties: ["HP_Tools": "Booklet"]) // self.fastTool_printBooklet() self.showAITypeChooseView() break } } func openPDFButtonAction() { NSPanel.km_open_pdf_multi_success(self.view.window!, panel: nil) { urls in for url in urls { NSDocumentController.shared.km_safe_openDocument(withContentsOf: url, display: true) { _, _, _ in } } } } func openSupportPDFButtonAction() { var window = self.view.window if (window == nil) { window = NSApp.mainWindow } NSOpenPanel.km_open_multi(window!) { panel in // if let data = KMConvertPDFManager.supportFileType() as? [String], !data.isEmpty { panel.allowedFileTypes = KMTools.pdfExtensions + KMConvertPDFManager.supportFileType() // } else { // panel.allowedFileTypes = KMTools.pdfExtensions + KMTools.imageExtensions // } } completion: { [weak self] result , urls in if result == .OK { var imageUrl: [URL] = [] for url in urls! { let type = url.pathExtension.lowercased() if (type == "pdf" || type == "PDF") { NSDocumentController.shared.km_safe_openDocument(withContentsOf: url, display: true) { _, _, _ in } } else if (type == "jpg") || (type == "cur") || (type == "bmp") || (type == "jpeg") || (type == "gif") || (type == "png") || (type == "tiff") || (type == "tif") || (type == "ico") || (type == "icns") || (type == "tga") || (type == "psd") || (type == "eps") || (type == "hdr") || (type == "jp2") || (type == "jpc") || (type == "pict") || (type == "sgi") || (type == "heic") { self?.openImageFile(url: url) } else if (type == "doc") || (type == "docx") || (type == "xls") || (type == "xlsx") || (type == "ppt") || (type == "pptx") || (type == "pptx") { self?.openOfficeFile(url: url) } } } } } func homeButtonAction() { refreshRightBoxUI(.Home) } func pdfToolsButtonAction() { refreshRightBoxUI(.PDFTools) } func favoriteDocumentsButtonAction() { KMPrint("Favorite Documents") } func cloudDocumentsButtonAction() { refreshRightBoxUI(.CloudDocuments) } func productPromotionClickAction(_ name: NSString) { var httpString: NSString = "" if name.isEqual(to: "Windows") { httpString = "https://www.pdfreaderpro.com/windows?utm_source=MacApp&utm_campaign=PDFProMac&utm_medium=pdfmac_promo" } else if name.isEqual(to: "iPhone / iPad") { #if VERSION_FREE #if VERSION_DMG httpString = "https://www.pdfreaderpro.com/product?utm_source=MacAppDmg&utm_campaign=ProductLinkLeftNav&utm_medium=PdfProduct" #else httpString = "https://www.pdfreaderpro.com/product?utm_source=MacAppLite&utm_campaign=ProductLinkLeftNav&utm_medium=PdfProduct" #endif #else httpString = "https://www.pdfreaderpro.com/product?utm_source=MacApp&utm_campaign=ProductLinkLeftNav&utm_medium=PdfProduct" #endif } else if name.isEqual(to: "Android") { httpString = "https://www.pdfreaderpro.com/pdfreaderpro-android?utm_source=MacAppDmg&utm_campaign=AndroidLink&utm_medium=PdfAndroid" } else if name.isEqual(to: "ComPDFKit") { httpString = "https://www.compdf.com?utm_source=macapp&utm_medium=pdfmac&utm_campaign=compdfkit-promp" } else if name.isEqual(to: "ComVideoKit") { httpString = "https://www.filmagepro.com/video-sdk?utm_source=macapp&utm_medium=pdfmac&utm_campaign=comvideosdk-promo" } else if name.isEqual(to: "SignFlow") { httpString = "https://apps.apple.com/app/apple-store/id1584624017?pt=118745145&ct=pdfmac-promo&mt=8" } else if name.isEqual(to: "FiImage Editor") { httpString = "https://apps.apple.com/app/apple-store/id1475051178?pt=118745145&ct=pdfmac-promo&mt=8" } else if name.isEqual(to: "FiImage Screen") { httpString = "https://apps.apple.com/app/apple-store/id1475049179?pt=118745145&ct=pdfmac-promo&mt=8" } else if name.isEqual(to: "Free PDF Templates") { httpString = "https://www.pdfreaderpro.com/templates?utm_source=MacApp&utm_campaign=PDFProMac&utm_medium=pdfmac_promo" } self.workSpaceOpenUrl(httpString) } func historyFile(deleteDocuments indexPaths: [URL]) { // if UserDefaults.standard.bool(forKey: "kHistoryDeleteNOReminderKey") { // historyFileDeleteAction(indexPaths) // } else { // let historyFileDeleteVC: KMHistoryFileDeleteWindowController = KMHistoryFileDeleteWindowController.init(windowNibName: NSNib.Name("KMHistoryFileDeleteWindowController")) // historyFileDeleteVC.indexPaths = indexPaths // self.currentWindowController = historyFileDeleteVC // historyFileDeleteVC.deleteCallback = { [weak self](indexPaths: [URL], windowController: KMHistoryFileDeleteWindowController) -> Void in // if self != nil { // self?.currentWindowController = nil self.historyFileDeleteAction(indexPaths) // } // } // self.view.window?.beginSheet(historyFileDeleteVC.window!) // } } func historyFileDeleteAction(_ indexPaths: [URL]) -> Void { let urls: Array = NSDocumentController.shared.recentDocumentURLs NSDocumentController.shared.clearRecentDocuments(nil) DispatchQueue.main.asyncAfter(deadline: .now()) { [self] in for (_, url) in urls.enumerated() { if !indexPaths.contains(url) { NSDocumentController.shared.noteNewRecentDocumentURL(url) } } self.homeContentView.reloadData() } } func openNewWindowAlertV(){ let preferenceNoteShow = UserDefaults.standard.bool(forKey: KMTabbingHintShowFlag) if preferenceNoteShow { menuItemAction_newTagPageToNewWindow("") } else { self.showLimitWindowAlert(url: nil) } } func reopenDocument(forPaths path: URL?) -> Void { if path == nil { let browser = KMBrowser.init() as KMBrowser browser.windowController = KMBrowserWindowController.init(browser: browser) browser.addHomeTabContents() browser.windowController.showWindow(self) }else { let browser = KMBrowser.init() as KMBrowser browser.windowController = KMBrowserWindowController.init(browser: browser) browser.addHomeTabContents() browser.windowController.showWindow(self) NSDocumentController.shared.km_safe_openDocument(withContentsOf: path!, display: true) { doc, open, err in } } } func showLimitWindowAlert(url: URL?) { if !KMDataManager.default.isTabbingWin{ KMDataManager.default.isTabbingWin = true let tabbingWin: KMTabbingHintWindowController = KMTabbingHintWindowController() tabbingWin.selectCallBack = {[weak self] continueOrNot in KMDataManager.default.isTabbingWin = false if continueOrNot { self?.reopenDocument(forPaths: url) } else { } } self.km_beginSheet(windowC: tabbingWin) } } func openHistoryFilePath(url: URL) -> Void { 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.beginSheetModal(for: view.window!) { [unowned self] result in self.homeContentView.historyListView.reloadData() // self.historyFileViewController.reloadData() } return } if url.pathExtension.lowercased() == "pdf" { let pdfDoc = CPDFDocument.init(url: url) if pdfDoc != nil { let document = NSDocumentController.shared.document(for: url) var alreadyOpen = false for openDocument in NSDocumentController.shared.documents { if document == openDocument { alreadyOpen = true } } if !alreadyOpen { let controll: KMBrowserWindowController? = self.view.window?.windowController as? KMBrowserWindowController if controll?.browser?.tabCount() ?? 0 > 1{ if !IAPProductsManager.default().isAvailableAllFunction() { showLimitWindowAlert(url: url) return }else { if KMPreference.shared.openDocumentType == .newWindow { self.reopenDocument(forPaths: url) } } } } KMMainDocument().tryToUnlockDocument(pdfDoc!) var selectDocument: KMMainDocument? = nil if ((document?.isKind(of: KMMainDocument.self)) != nil) { selectDocument = (document as! KMMainDocument) } if selectDocument != nil { if selectDocument?.browser != nil { let currentIndex = selectDocument?.browser.tabStripModel.index(of: selectDocument) ?? 0 selectDocument?.browser.tabStripModel.selectTabContents(at: Int32(currentIndex), userGesture: true) let isVisible: Bool = selectDocument?.browser.window.isVisible ?? false let isMiniaturized: Bool = selectDocument?.browser.window.isMiniaturized ?? false if isVisible { selectDocument?.browser.window.orderFront(nil) } else if isMiniaturized { selectDocument?.browser.window.orderFront(nil) } } } else { NSDocumentController.shared.km_safe_openDocument(withContentsOf: url, display: true) { _, _, _ in } } } else { 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.beginSheetModal(for: view.window!) { [unowned self] result in self.homeContentView.historyListView.reloadData() // self.historyFileViewController.reloadData() } } } else { NSWorkspace.shared.open(url) } } func openFile(withFilePath path: URL) -> Void { let type = path.pathExtension.lowercased() if (type == "pdf") { // if !path.path.isPDFValid() { // let alert = NSAlert() // alert.alertStyle = .critical // alert.messageText = NSLocalizedString("This file format is not supported, please drag in PDF, picture, Office format files", comment: "") // alert.runModal() // return // } // if needShowTabbingHintWindow() { // showTabbingHintWindow() // return // } // NSDocumentController.shared.openDocument(withContentsOf: path, display: true) { document, documentWasAlreadyOpen, error in // if error != nil { // NSApp.presentError(error!) // return // } // } self.openHistoryFilePath(url: path) } else if (type == "jpg") || (type == "cur") || (type == "bmp") || (type == "jpeg") || (type == "gif") || (type == "png") || (type == "tiff") || (type == "tif") || (type == "ico") || (type == "icns") || (type == "tga") || (type == "psd") || (type == "eps") || (type == "hdr") || (type == "jp2") || (type == "jpc") || (type == "pict") || (type == "sgi") || (type == "heic") { openImageFile(url: path) } else if (type == "doc") || (type == "docx") || (type == "xls") || (type == "xlsx") || (type == "ppt") || (type == "pptx") || (type == "pptx") { let fileName: NSString = String(format: "%@.pdf", NSLocalizedString("Untitled", comment: "")) as NSString let savePath = fetchUniquePath(fileName.kUrlToPDFFolderPath() as String) openOfficeFile(url: path) } DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { self.homeContentView.historyListView.reloadData() } } func openImageFile(url: URL) -> Void { var filePath = url.path let fileName: NSString = url.lastPathComponent as NSString let savePath = fetchUniquePath(fileName.kUrlToPDFFolderPath() as String).deletingLastPathComponent let imageName = NSString(string: NSString(string: filePath).lastPathComponent).deletingPathExtension let path = self.fetchDifferentFilePath(filePath: savePath + "/" + imageName + ".pdf") if (!FileManager.default.fileExists(atPath: path.deletingLastPathComponent as String)) { try?FileManager.default.createDirectory(atPath: path.deletingLastPathComponent as String, withIntermediateDirectories: true, attributes: nil) } if (!FileManager.default.fileExists(atPath: path as String)) { FileManager.default.createFile(atPath: path as String, contents: nil) } let document = CPDFDocument.init() var success = false if NSString(string: NSString(string: filePath).lastPathComponent).pathExtension == "png" || NSString(string: NSString(string: filePath).lastPathComponent).pathExtension == "PNG" { let jpgPath = self.fetchDifferentFilePath(filePath: savePath + "/" + imageName + ".jpg") if (!FileManager.default.fileExists(atPath: jpgPath as String)) { FileManager.default.createFile(atPath: jpgPath as String, contents: nil) } // 加载 PNG 图像 guard let pngImage = NSImage(contentsOfFile: filePath) else { KMPrint("Failed to load PNG image") return } // 创建 NSBitmapImageRep 对象,并将 PNG 图像绘制到其中 let bitmap = NSBitmapImageRep(data: pngImage.tiffRepresentation!) guard let bitmap = bitmap else { return } let rect = NSRect(origin: .zero, size: bitmap.size) bitmap.draw(in: rect) // 将 PNG 图像数据转换为 JPG 图像数据 guard let jpgData = bitmap.representation(using: .jpeg, properties: [:]) else { KMPrint("Failed to convert PNG to JPG") return } // 保存 JPG 图像数据到文件 let fileURL = URL(fileURLWithPath: jpgPath) do { try jpgData.write(to: fileURL) filePath = fileURL.path KMPrint("JPG image saved successfully") } catch { KMPrint("Failed to save JPG image: \(error.localizedDescription)") } } //FIXME: 无法插入图片 let image = NSImage(contentsOfFile: filePath) let insertPageSuccess = document?.insertPage(image!.size, withImage: filePath, at: document!.pageCount) if insertPageSuccess != nil { //信号量控制异步 let semaphore = DispatchSemaphore(value: 0) DispatchQueue.global().async { success = ((document?.write(toFile: path)) != nil) semaphore.signal() } semaphore.wait() } else { } if success { NSDocumentController.shared.km_safe_openDocument(withContentsOf: URL(fileURLWithPath: path), display: true) { document, isOpened, error in if error != nil { NSApp.presentError(error!) } else { if FileManager.default.fileExists(atPath: filePath) { try? FileManager.default.removeItem(atPath: filePath) } if document is KMMainDocument { let newDocument = document (newDocument as! KMMainDocument).isNewCreated = true } } } } } func openOfficeFile(url: URL) -> Void { let filePath = url.path let folderPath = "convertToPDF.pdf" let savePath: String? = folderPath.kUrlToPDFFolderPath() as String if (!FileManager.default.fileExists(atPath: savePath!.deletingLastPathComponent as String)) { try?FileManager.default.createDirectory(atPath: savePath!.deletingLastPathComponent as String, withIntermediateDirectories: true, attributes: nil) } // if (!FileManager.default.fileExists(atPath: savePath! as String)) { // FileManager.default.createFile(atPath: savePath! as String, contents: nil) // } if savePath == nil { return } KMConvertPDFManager.convertFile(filePath, savePath: savePath!) { success, errorDic in if errorDic != nil || !success || !FileManager.default.fileExists(atPath: savePath!) { 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 } NSDocumentController.shared.km_safe_openDocument(withContentsOf: URL(fileURLWithPath: savePath!), display: true) { _, _, _ in } } } func aiTranslation(withFilePath path: String) -> Void { if !KMLightMemberManager.manager.isLogin() { KMLoginWindowController.show(window: NSApp.mainWindow!) return } let isExceedsLimit = self.isPDFPageCountExceedsLimit(filePath: path) if self.isFileGreaterThan10MB(atPath: path) { self.aiTranslationViewController.errorView.isHidden = false self.aiTranslationViewController.errorLabel.stringValue = NSLocalizedString("The uploaded file size cannot exceed 10MB", comment: "") } else if isExceedsLimit { self.aiTranslationViewController.errorView.isHidden = false self.aiTranslationViewController.errorLabel.stringValue = NSLocalizedString("Documents cannot exceed 30 pages", comment: "") } else { let url = URL(fileURLWithPath: path) if (url.pathExtension == "pdf") || url.pathExtension == "PDF" { if !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 } } let infoDictionary = Bundle .main.infoDictionary! let majorVersion = infoDictionary["CFBundleShortVersionString"] DispatchQueue.main.async { self.showProgressWindow() self.progressController?.maxValue = Double(100) } timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerTick), userInfo: nil, repeats: true) KMRequestServerManager.manager.aiTranslationFileUpload(file: path, version: majorVersion as! String) { [unowned self] success, result in if success { let result: NSDictionary = result!.result let fileKey = result["fileKey"] let fileName = result["fileName"] let pageCount = result["pageCount"] if fileKey != nil { self.fileTranslateHandle(fileKey as! String) } } else { let result: String = result!.message DispatchQueue.main.async { self.hiddenProgressWindow() self.aiTranslationViewController.errorView.isHidden = false self.aiTranslationViewController.errorLabel.stringValue = result } } } } } func fileTranslateHandle(_ fileKey: String) -> Void { let infoDictionary = Bundle .main.infoDictionary! let majorVersion = infoDictionary["CFBundleShortVersionString"] let languageArr = UserDefaults.standard.array(forKey: "KMAITranslationLanguageArrayKey1") as? [String] ?? [NSLocalizedString("Automatic", comment: ""), NSLocalizedString("English", comment: "")] let language1 = self.aiTranslationViewController.languageAbbreviation(languageArr[0]) let language2 = self.aiTranslationViewController.languageAbbreviation(languageArr[1]) KMRequestServerManager.manager.aiTranslationFileTranslateHandle(fileKey: fileKey, from: language1, to: language2, version: majorVersion as! String) { success, result in if success { let result: NSDictionary = result!.result let fileUrl: String = result["fileUrl"] as! String let downFileUrl: String = result["downFileUrl"] as! String let ossDownUrl: String = result["ossDownUrl"] as! String let fileName: String = result["fileName"] as! String let downFileName: String = result["downFileName"] as! String let from: String = result["from"] as! String let to: String = result["to"] as! String self.downloadFile(filePath: ossDownUrl, downFileName: downFileName) } else { let result: String = result!.message DispatchQueue.main.async { self.hiddenProgressWindow() self.aiTranslationViewController.errorView.isHidden = false self.aiTranslationViewController.errorLabel.stringValue = result } } } } func downloadFile(filePath: String, downFileName: String) -> Void { guard let fileURL = URL(string: filePath) else { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Invalid file link", comment: "") alert.runModal() return } let destinationURL = FileManager.default.temporaryDirectory.appendingPathComponent(downFileName) if FileManager.default.fileExists(atPath: destinationURL.path) { do { try FileManager.default.removeItem(at: destinationURL) KMPrint("删除旧文件成功") } catch { KMPrint("删除旧文件失败:\(error)") } } let sessionConfiguration = URLSessionConfiguration.default let session = URLSession(configuration: sessionConfiguration) let downloadTask = session.downloadTask(with: fileURL) { (tempLocalURL, response, error) in if let error = error { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = String(format: "%@:\(error)", NSLocalizedString("Download failed", comment: "")) alert.runModal() return } guard let tempLocalURL = tempLocalURL else { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Invalid temporary directory", comment: "") alert.runModal() return } DispatchQueue.main.async { self.hiddenProgressWindow() } do { try FileManager.default.moveItem(at: tempLocalURL, to: destinationURL) NSDocumentController.shared.openDocument(withContentsOf: destinationURL, display: true) { document, documentWasAlreadyOpen, error in if error != nil { NSApp.presentError(error!) } else { } } } catch { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = String(format: "%@:\(error)", NSLocalizedString("Failed to save file", comment: "")) alert.runModal() } } downloadTask.resume() } override func otherMouseDown(with event: NSEvent) { if historyFileViewController.selectFiles.count > 0 { let eventPoint = event.locationInWindow as NSPoint let x = eventPoint.x - 270.0 if x >= 0 { let point = NSPoint(x: x, y: eventPoint.y) let historyPoint = historyFileViewController.historyFileCollectionView.convert(eventPoint, from: nil) var indexPath: IndexPath? = nil if historyFileViewController.showMode == .List { let rowIndex = historyFileViewController.historyFileTableView.row(at: historyPoint) // 查找列索引 let columnIndex = historyFileViewController.historyFileTableView.column(at: point) // 使用行和列索引创建 indexPath if rowIndex != -1 { indexPath = IndexPath(item: columnIndex, section: rowIndex) } } else { indexPath = historyFileViewController.historyFileCollectionView.indexPathForItem(at: historyPoint) } if (historyFileViewController.historyFileCollectionView.frame.contains(point) || historyFileViewController.historyFileTableView.frame.contains(point) || historyFileViewController.deleteBox.frame.contains(point) || historyFileViewController.listBox.frame.contains(point) || historyFileViewController.thumbnailBox.frame.contains(point)) && indexPath != nil { } else { self.historyFileViewController.selectFiles.removeAll() self.historyFileViewController.selectFiles_shift.removeAll() if self.historyFileViewController.showMode == .Thumbnail { self.historyFileViewController.historyFileCollectionView.reloadData() } else { self.historyFileViewController.historyFileTableView.reloadData() } } } else { self.historyFileViewController.selectFiles.removeAll() self.historyFileViewController.selectFiles_shift.removeAll() if self.historyFileViewController.showMode == .Thumbnail { self.historyFileViewController.historyFileCollectionView.reloadData() } else { self.historyFileViewController.historyFileTableView.reloadData() } } } } // MARK: PDF Tools // 插入 func insertPageAction(_ pdfDocument: CPDFDocument, _ password: String, _ pages: [CPDFPage], _ indexPage: Int) -> Void { if indexPage >= 0 { let insertPages: [CPDFPage] = pages for i in 0...insertPages.count-1 { let page = pages[i] // FIXME: 待底层库修改,使用 insertPageObject 插入,插入位置变为文档最后,暂用 insertPage 代替 pdfDocument.insertPageObject(page, at: UInt(indexPage + i)) } self.savePDFDocument(pdfDocument, password: password) } } func extractPageAction(_ pdfDocument: CPDFDocument, _ pages: [CPDFPage], _ oneDocumentPerPage: Bool, _ isDeletePage: Bool) -> Void { if pages.count < 1 { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Please select two or more pages first to organize.", comment: "") alert.runModal() return } if !oneDocumentPerPage { let fileName = pdfDocument.getFileNameAccordingSelctPages(pages) let outputSavePanel = NSSavePanel() outputSavePanel.allowedFileTypes = ["pdf"] outputSavePanel.nameFieldStringValue = fileName outputSavePanel.beginSheetModal(for: self.view.window!) { result in if result == .OK { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { let saveFilePath = outputSavePanel.url?.path DispatchQueue.global().async { var pdf = CPDFDocument.init() let success = (pdf!.extractAsOneDocument(withPages: pages, savePath: saveFilePath)) as Bool DispatchQueue.main.async { if success { let workspace = NSWorkspace.shared let url = URL(fileURLWithPath: saveFilePath!) workspace.activateFileViewerSelecting([url]) if isDeletePage { for page in pages { let indexPage = pdfDocument.index(for: page) pdfDocument.removePage(at: indexPage) } } } } } } } } } else { let panel = NSOpenPanel() panel.canChooseFiles = false panel.canChooseDirectories = true panel.canCreateDirectories = true panel.allowsMultipleSelection = false panel.beginSheetModal(for: self.view.window!) { result in if result == .OK { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { let outputURL = panel.url DispatchQueue.global().async { let folderName = String(pdfDocument.documentURL!.lastPathComponent.split(separator: ".")[0]) + "_extract" var filePath = URL(fileURLWithPath: outputURL!.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) let successArray = pdfDocument.extractPerPageDocument(withPages: pages, folerPath: filePath) DispatchQueue.main.async { if successArray!.count > 0 { NSWorkspace.shared.activateFileViewerSelecting(successArray!) if !isDeletePage { for page in pages { let indexPage = pdfDocument.index(for: page) pdfDocument.removePage(at: indexPage) } } } } } } } } } } // MARK: 快捷工具 Action func fastToolDidSelectAllTools() { // 首页 快捷工具 Tools按钮 refreshRightBoxUI(.PDFTools) } func fastTool_Batch() { // Batch // KMBatchWindowController.openFile(nil, .Batch) if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let batchWindowController = KMBatchOperateWindowController.sharedWindowController batchWindowController.window?.makeKeyAndOrderFront("") } func fastTool_OCR() { // OCR // KMOCRWindowController.openFiles(window: self.view.window!) if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() var arr = KMImageToPDFMethod.supportedImageTypes() arr.append("pdf") openPanel.allowedFileTypes = arr //MARK: 允许多选还是单选,如果是付费用户允许多选 openPanel.allowsMultipleSelection = false openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in if result == NSApplication.ModalResponse.OK { quickOcr(urls: openPanel.urls) } } } func quickOcr(urls: Array) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { var document: CPDFDocument? for fileURL in urls { if fileURL.lastPathComponent.pathExtension == "pdf"{ document = CPDFDocument(url: fileURL) }else{ document = CPDFDocument() let image = NSImage(contentsOfFile: fileURL.path) _ = document?.km_insertPage(image!.size, withImage: fileURL.path, at: 0) } break } if document == nil{ let alert = NSAlert() alert.alertStyle = .critical alert.messageText = KMLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", nil) alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in if response == .alertFirstButtonReturn { // Handle cancel action } } return } let com = KMOCRPDFWindowController(cpdfDocument: document!, pwd: document!.password) self.km_beginSheet(windowC: com) } } func fastTool_ConvertPDF() { // 转换PDF // KMBatchWindowController.openFile(nil, .ConvertPDF) let openPanel = NSOpenPanel() var arr = KMImageToPDFMethod.supportedImageTypes() arr.append("pdf") openPanel.allowedFileTypes = ["pdf","PDF"] //MARK: 允许多选还是单选,如果是付费用户允许多选 openPanel.allowsMultipleSelection = false openPanel.beginSheetModal(for: self.view.window!) { [self] (result) in if result == NSApplication.ModalResponse.OK { quickConvertPdf(urls: openPanel.urls, type: .WordAdvance) } } } func quickConvertPdf(urls: Array, type: KMConvertWithPDFType) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { var arr: Array = Array() for fileURL in urls { let img = NSImage(contentsOfFile: fileURL.path) if self.isDamageImage(image: img, path: fileURL.path) { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = String(format: KMLocalizedString("The file \"%@\" could not be opened.", nil), fileURL.path.lastPathComponent) alert.informativeText = NSLocalizedString("It may be damaged or use a file format that PDF Reader Pro doesn’t recognize.", comment: "") alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "")) alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in if response == .alertFirstButtonReturn { // Handle cancel action } } continue } let file = KMBatchOperateFile(filePath: fileURL.path, type: .Convert) arr.append(file) } let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController") if #available(macOS 10.13, *) { baseWindowController.window?.makeKeyAndOrderFront(nil) } else { baseWindowController.showWindow(nil) } if arr.count > 0 { baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: .Convert, files: arr) } baseWindowController.switchToConvertType(convertType: type) } } func fastTool_ImageToPDF() { // 图片转PDF // KMImageToPDFWindowController.openFiles(window: NSApp.mainWindow!) let openPanel = NSOpenPanel() openPanel.allowedFileTypes = KMImageToPDFMethod.supportedImageTypes() //MARK: 允许多选还是单选,如果是付费用户允许多选 openPanel.allowsMultipleSelection = true openPanel.message = KMLocalizedString("Select images to create a new document. To select multiple files press cmd ⌘ button on keyboard and click on the target files one by one.", nil) // openPanel.canChooseFiles = false // openPanel.canChooseDirectories = true // openPanel.canCreateDirectories = true if IAPProductsManager.default().isAvailableAllFunction(){ openPanel.allowsMultipleSelection = true }else{ openPanel.allowsMultipleSelection = false } openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in if result == NSApplication.ModalResponse.OK { openImageToPdfWindow(urls: openPanel.urls) } } } func openImageToPdfWindow(urls: Array) { var arr: Array = Array() for fileURL in urls { let img = NSImage(contentsOfFile: fileURL.path) if self.isDamageImage(image: img, path: fileURL.path) { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = String(format: KMLocalizedString("The file \"%@\" could not be opened.", nil), fileURL.path.lastPathComponent) alert.informativeText = NSLocalizedString("It may be damaged or use a file format that PDF Reader Pro doesn’t recognize.", comment: "") alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "")) alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in if response == .alertFirstButtonReturn { // Handle cancel action } } continue } let file = KMBatchOperateFile(filePath: fileURL.path, type: .CreatePDF) arr.append(file) } let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController") if #available(macOS 10.13, *) { baseWindowController.window?.makeKeyAndOrderFront(nil) } else { baseWindowController.showWindow(nil) } if arr.count > 0 { baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: .CreatePDF, files: arr) } } func isDamageImage(image: NSImage?, path: String) -> Bool { if (image == nil) { return true } let addImageAnnotation = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).last!.appendingPathComponent(Bundle.main.bundleIdentifier!).appendingPathComponent("addImageAnnotation") // let addImageAnnotation = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("addImageAnnotation") if !FileManager.default.fileExists(atPath: addImageAnnotation.path) { try? FileManager.default.createDirectory(atPath: addImageAnnotation.path, withIntermediateDirectories: false, attributes: nil) } guard let data = image!.tiffRepresentation else { return false } guard let imageRep = NSBitmapImageRep(data: data) else { return false } imageRep.size = image!.size var imageData: Data? if path.lowercased() == "png" { imageData = imageRep.representation(using: .png, properties: [:]) } else { imageData = imageRep.representation(using: .jpeg, properties: [:]) } let rPath: URL = addImageAnnotation.appendingPathComponent(tagString()).appendingPathExtension("png") if let data = imageData { try?data.write(to: rPath) return false } else { return true } } func tagString() -> String { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyMMddHHmmss" let currentDate = Date() let formattedDate = dateFormatter.string(from: currentDate) let randomNum = Int(arc4random_uniform(10000)) let str = String(format: "%@%04d", dateFormatter.string(from: Date()),randomNum) return str//"(formattedDate)(String(format: "%04d", randomNum))" } func fastTool_MergePDF() { // MergePDF Task { @MainActor in self.km_open_pdf_merge() } } func km_open_pdf_merge() { DispatchQueue.main.async { self.mergeWindowController = KMMergeWindowController(windowNibName: "KMMergeWindowController") self.mergeWindowController!.type = .merge self.mergeWindowController!.cancelAction = { [unowned self] controller in self.view.window?.endSheet((self.mergeWindowController!.window)!) } self.view.window?.beginSheet(self.mergeWindowController!.window!) } } func fastTool_Compression() { // 压缩 let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf","PDF"] //MARK: 允许多选还是单选,如果是付费用户允许多选 openPanel.allowsMultipleSelection = false openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in if result == NSApplication.ModalResponse.OK { quickCompressPdf(urls: openPanel.urls) } } } func quickCompressPdf(urls: Array) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { var arr: Array = Array() for fileURL in urls { let file = KMBatchOperateFile(filePath: fileURL.path, type: .Compress) arr.append(file) } let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController") if #available(macOS 10.13, *) { baseWindowController.window?.makeKeyAndOrderFront(nil) } else { baseWindowController.showWindow(nil) } if arr.count > 0 { baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: .Compress, files: arr) } } } func km_secure_openPanel_compress() { DispatchQueue.main.async { NSOpenPanel.km_secure_openPanel(window: self.view.window!) { url, result, passowrd in if (url == nil) { return } if (result != nil && result! == .cancel) { return } self.showCompressWindow(url!, passowrd) } } } func showCompressWindow(_ url: URL, _ password: String?) { // Task { @MainActor in // let windowController = KMCompressWindowController(windowNibName: "KMCompressWindowController") // windowController.documentURL = url // windowController.password = password // // windowController.itemClick = { [weak self] _ in // self?.km_endSheet() // } // // windowController.resultCallback = { [weak self] result, openDocument, fileURL, _ in // if result { // self?.km_endSheet() // if openDocument { // NSDocumentController.shared.km_safe_openDocument(withContentsOf: fileURL, display: true) { _, _, _ in // // } // } else { // NSWorkspace.shared.activateFileViewerSelecting([fileURL]) // } // } else { // let alert = NSAlert() // alert.messageText = NSLocalizedString("Compress Faild", comment: "") // alert.runModal() // } // } // self.km_beginSheet(windowC: windowController) // } } func fastTool_Security() { // 安全 let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf","PDF"] //MARK: 允许多选还是单选,如果是付费用户允许多选 openPanel.allowsMultipleSelection = true openPanel.message = KMLocalizedString("To select multiple files press cmd ⌘ button on keyboard and click on the target files one by one.", nil) openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in if result == NSApplication.ModalResponse.OK { quickPassword(urls: openPanel.urls) } } } func quickPassword(urls: Array) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { var arr: Array = Array() for fileURL in urls { let file = KMBatchOperateFile(filePath: fileURL.path, type: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddPassword : .RemovePassword) arr.append(file) } let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController") if #available(macOS 10.13, *) { baseWindowController.window?.makeKeyAndOrderFront(nil) } else { baseWindowController.showWindow(nil) } if arr.count > 0 { baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddPassword : .RemovePassword, files: arr) } } } func fastTool_FileCompare() { // 文件对比 if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.allowsMultipleSelection = false openPanel.allowedFileTypes = ["pdf"] openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in if result == .cancel { return } if !openPanel.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 } KMBaseWindowController.checkPassword(url: URL(fileURLWithPath: openPanel.url!.path), type: .owner) { [unowned self] success, resultPassword in if success { DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { let controller = KMCompareWindowController(windowNibName: "KMCompareWindowController") self.currentWindowController = controller controller.password = resultPassword controller.filePath = openPanel.url!.path controller.cancelAction = { [unowned self] contr in self.view.window?.endSheet((controller.window)!) // self.currentWindowController = nil } controller.contentComplete = { [unowned self] controller, pdfCompareContent, result, oldDocument, document in DispatchQueue.main.async { self.view.window?.endSheet((controller.window)!) // self.currentWindowController = nil self.openContentCompareVC(with: pdfCompareContent, results: result, oldDocument: oldDocument, document: document) } } controller.coveringComplete = { [unowned self] controller, document in self.view.window?.endSheet((controller.window)!) // self.currentWindowController = nil self.openCoveringCompareVC(with: document) } // if index == 1 { controller.fileType = .content // } else { // controller.fileType = .coverting // } NSWindow.currentWindow().beginSheet(controller.window!) } } else { } } } } func fastTool_PDFToPPT() { // self.showConvertWindow(type: .ppt) let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf","PDF"] //MARK: 允许多选还是单选,如果是付费用户允许多选 openPanel.allowsMultipleSelection = false openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in if result == NSApplication.ModalResponse.OK { quickConvertPdf(urls: openPanel.urls, type: .PowerPoint) } } } func fastTool_PDFToExcel() { // self.showConvertWindow(type: .excel) let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf","PDF"] //MARK: 允许多选还是单选,如果是付费用户允许多选 openPanel.allowsMultipleSelection = false openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in if result == NSApplication.ModalResponse.OK { quickConvertPdf(urls: openPanel.urls, type: .Excel) } } } func fastTool_PDFToWord() { // PDF转Word // self.showConvertWindow(type: .word) fastTool_ConvertPDF() } func fastTool_PDFToImage() { // PDF转图片 self.showConvertWindow(type: .image) } func fastTool_Watermark() { // 水印 // KMBatchWindowController.openFile(nil, .Watermark) if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf","PDF"] //MARK: 允许多选还是单选,如果是付费用户允许多选 openPanel.allowsMultipleSelection = false openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in if result == NSApplication.ModalResponse.OK { quickWaterMark(urls: openPanel.urls) } } } func quickWaterMark(urls: Array) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { var arr: Array = Array() for fileURL in urls { let pdf = CPDFDocument(url: fileURL) if !pdf!.allowsPrinting || !pdf!.allowsCopying { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "") alert.runModal() return } let file = KMBatchOperateFile(filePath: fileURL.path, type: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddWatermark : .RemoveWatermark) arr.append(file) } let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController") if #available(macOS 10.13, *) { baseWindowController.window?.makeKeyAndOrderFront(nil) } else { baseWindowController.showWindow(nil) } if arr.count > 0 { baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddWatermark : .RemoveWatermark, files: arr) } } } func fastTool_Background() { // 背景 // KMBatchWindowController.openFile(nil, .Background) if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf","PDF"] //MARK: 允许多选还是单选,如果是付费用户允许多选 openPanel.allowsMultipleSelection = false openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in if result == NSApplication.ModalResponse.OK { quickBackgroudMark(urls: openPanel.urls) } } } func quickBackgroudMark(urls: Array) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { var arr: Array = Array() for fileURL in urls { let pdf = CPDFDocument(url: fileURL) if !pdf!.allowsPrinting || !pdf!.allowsCopying { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "") alert.runModal() return } let file = KMBatchOperateFile(filePath: fileURL.path, type: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddBackground : .RemoveBackground) arr.append(file) } let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController") if #available(macOS 10.13, *) { baseWindowController.window?.makeKeyAndOrderFront(nil) } else { baseWindowController.showWindow(nil) } if arr.count > 0 { baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddBackground : .RemoveBackground, files: arr) } } } func fastTool_HeaderAndFooter() { // 页眉页脚 // KMBatchWindowController.openFile(nil, .HeaderAndFooter) if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf","PDF"] //MARK: 允许多选还是单选,如果是付费用户允许多选 openPanel.allowsMultipleSelection = false openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in if result == NSApplication.ModalResponse.OK { quickHeaderAndFooterMark(urls: openPanel.urls) } } } func quickHeaderAndFooterMark(urls: Array) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { var arr: Array = Array() for fileURL in urls { let pdf = CPDFDocument(url: fileURL) if !pdf!.allowsPrinting || !pdf!.allowsCopying { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "") alert.runModal() return } let file = KMBatchOperateFile(filePath: fileURL.path, type: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddHeaderFooter : .RemoveHeaderFooter) arr.append(file) } let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController") if #available(macOS 10.13, *) { baseWindowController.window?.makeKeyAndOrderFront(nil) } else { baseWindowController.showWindow(nil) } if arr.count > 0 { baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddHeaderFooter : .RemoveHeaderFooter, files: arr) } } } func fastTool_BatesCode() { // 贝茨码 // KMBatchWindowController.openFile(nil, .BatesCode) if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf","PDF"] //MARK: 允许多选还是单选,如果是付费用户允许多选 openPanel.allowsMultipleSelection = false openPanel.beginSheetModal(for: NSWindow.currentWindow()) { [self] (result) in if result == NSApplication.ModalResponse.OK { quickBatesNumberMark(urls: openPanel.urls) } } } func quickBatesNumberMark(urls: Array) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { var arr: Array = Array() for fileURL in urls { let pdf = CPDFDocument(url: fileURL) if !pdf!.allowsPrinting || !pdf!.allowsCopying { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "") alert.runModal() return } let file = KMBatchOperateFile(filePath: fileURL.path, type: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddBates : .RemoveBates) arr.append(file) } let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController") if #available(macOS 10.13, *) { baseWindowController.window?.makeKeyAndOrderFront(nil) } else { baseWindowController.showWindow(nil) } if arr.count > 0 { baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: KMBatchQuickActionManager.defaultManager.actionType == .add ? .AddBates : .RemoveBates, files: arr) } } } func fastTool_Print() { // 打印 KMPrintWindowController.openFiles(window: self.view.window!) } func fastTool_BatchRemove() { // 批量移除 // KMBatchWindowController.openFile(nil, .BatchRemove) } func fastTool_Insert() { // 插入 if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.prompt = NSLocalizedString("Insert", comment: "") openPanel.allowsMultipleSelection = false openPanel.allowedFileTypes = ["pdf"] openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in if result == .OK { // DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { // let insertWindowController: KMPDFInsertPageWindow = KMPDFInsertPageWindow.init(documentPath: openPanel.url!, toolType: .Insert) // insertWindowController.beginSheetModal(for: self.view.window!) { pdfDocument, password, pages, indexPage in // self.insertPageAction(pdfDocument, password, pages, indexPage) // } // } // } let windowC = KMPDFInsertWindowController(fileURL: openPanel.url!) // [com beginSheetModalForWindow:[NSApp mainWindow] completionHandler:^(PDFDocument *pdfDocument, NSString *password, NSMutableArray *pages, NSInteger indexPage) { // if (pdfDocument && indexPage >= 0) { // [pdfDocument insertWithInsertPages:pages insertPageIndex:indexPage]; // [self savePDFDocument:pdfDocument password:password]; // } // }]; windowC.callback = { [unowned self] idx, params in if params.count >= 4 { if let doc = params.first as? CPDFDocument { // doc.insertWithInsertPages((params[2] as? [CPDFPage]) ?? [], insertPageIndex: params[3] as! Int) self.savePDFDocument(doc, password: params[1] as? String ?? "") } } self.km_endSheet() } self.km_beginSheet(windowC: windowC) } } } // func savePDFDocument(_ pdf: CPDFDocument, password: String?) { //// KMProgressWindowController * vc = [[KMProgressWindowController alloc] init]; //// [NSApp beginSheet:[vc window] modalForWindow:[NSApp mainWindow] modalDelegate:nil didEndSelector:nil contextInfo:NULL]; // // DispatchQueue.global().async { // var isSuccessfully = false // if (pdf.isEncrypted) { // isSuccessfully = pdf.write(to: pdf.documentURL, withOptions: [.userPasswordOption : password ?? "", .ownerPasswordOption : password ?? ""]) // } else { // isSuccessfully = pdf.write(to: pdf.documentURL) // } // if (!isSuccessfully) { //// isSuccessfully = [pdf.dataRepresentation writeToURL:pdf.documentURL atomically:YES]; // try?pdf.dataRepresentation().write(to: pdf.documentURL) // } // // Task { @MainActor in //// [NSApp endSheet:vc.window]; //// [vc close]; // // if (isSuccessfully) { //// BOOL autoOpen = [[NSUserDefaults standardUserDefaults] boolForKey:KMAutoOpenDocumentKey]; //// if (autoOpen) { //// [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:pdf.documentURL display:YES completionHandler:^(NSDocument * _Nullable document, BOOL documentWasAlreadyOpen, NSError * _Nullable error) { //// //// }]; //// } else { // let workspace = NSWorkspace.shared // let url = URL(fileURLWithPath: pdf.documentURL.path) // workspace.activateFileViewerSelecting([url]) //// } // } else { // _ = await KMAlertTool.runModel(message: KMLocalizedString("Failed to insert page(s)!", nil)) // } // } // } // } func fastTool_BreakUp() { // 拆分 // [[FMTrackEventManager manager] trackEvent:@"Onbrd" withProperties:@{@"HP_Tools":@"Split"}]; // // if (![IAPProductsManager defaultManager].isAvailableAllFunction) { // [[KMPurchaseCompareWindowController sharedInstance] showWindow:nil]; // return; // } // self.isDragEntered = YES; if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf"] openPanel.allowsMultipleSelection = false openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in // self.isDragEntered = NO; if result == .OK { DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { let com = SplitWindowController(fileURL: openPanel.url!) self.km_beginSheet(windowC: com) } } } } func fastTool_Extract() { // 提取 let openPanel = NSOpenPanel() openPanel.prompt = "提取" openPanel.allowsMultipleSelection = false openPanel.allowedFileTypes = ["pdf"] openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in if result == .OK { DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { let insertWindowController: KMPDFInsertPageWindow = KMPDFInsertPageWindow.init(documentPath: openPanel.url!, toolType: .Extract) insertWindowController.beginSheetExtractModal(for: self.view.window!) { pdfDocument, pages, oneDocumentPerPage, isDeletePage in self.extractPageAction(pdfDocument, pages, oneDocumentPerPage, isDeletePage) } } } } } func fastTool_MarkCipher() { // 标记密文 if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.allowsMultipleSelection = false openPanel.allowedFileTypes = ["pdf"] openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in if result == .cancel { return } if !openPanel.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 } DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { NSDocumentController.shared.openDocument(withContentsOf: openPanel.url!, display: true) { document, result, error in if (error != nil) { NSApp.presentError(error!) return } let toolbar = (document as! KMMainDocument).mainViewController?.toolbarController toolbar?.enterRedact() } } } } func fastTool_AutomaticFormRecognition() { // 表单自动识别 let openPanel = NSOpenPanel() openPanel.prompt = "表单自动识别" openPanel.allowsMultipleSelection = false openPanel.allowedFileTypes = ["pdf"] openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in if result == .OK { } } } func fastTool_PageEdit() { // 页面编辑 let openPanel = NSOpenPanel() openPanel.allowsMultipleSelection = false openPanel.allowedFileTypes = ["pdf"] openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in if result == .OK { if !openPanel.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 } if let pdf = CPDFDocument(url: openPanel.url!) { if pdf.allowsCopying == false || pdf.allowsPrinting == false { Task { _ = await KMAlertTool.runModel(message: KMLocalizedString("This is a secured document. Editing is not permitted.", nil)) } return } } let windowC = KMPDFEditWindowController(filepath: openPanel.url!.path, password: nil) // windowC.startModal(nil) windowC.showWindow(nil) } } } func fastTool_printBooklet() { if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.allowsMultipleSelection = false openPanel.allowedFileTypes = ["pdf"] openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in if result == .cancel { return } if !openPanel.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 } if let pdf = CPDFDocument(url: openPanel.url!) { if pdf.allowsCopying == false || pdf.allowsPrinting == false { Task { _ = await KMAlertTool.runModel(message: KMLocalizedString("This is a secured document. Editing is not permitted.", nil)) } return } } DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { let pdfDocument = CPDFDocument(url: openPanel.url!) KMPrintWindowController.showNewPrintWindowControll(inputDocument: pdfDocument, inputPageRange: KMPrintPageRange(), printType: .pamphlet) } } } func fastTool_printPoster() { if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.allowsMultipleSelection = false openPanel.allowedFileTypes = ["pdf"] openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in if result == .cancel { return } if !openPanel.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 } if let pdf = CPDFDocument(url: openPanel.url!) { if pdf.allowsCopying == false || pdf.allowsPrinting == false { Task { _ = await KMAlertTool.runModel(message: KMLocalizedString("This is a secured document. Editing is not permitted.", nil)) } return } } DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { let pdfDocument = CPDFDocument(url: openPanel.url!) KMPrintWindowController.showNewPrintWindowControll(inputDocument: pdfDocument, inputPageRange: KMPrintPageRange(), printType: .poster) } } } func fastTool_printMultple() { if !IAPProductsManager.default().isAvailableAllFunction(){ KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } let openPanel = NSOpenPanel() openPanel.allowsMultipleSelection = false openPanel.allowedFileTypes = ["pdf"] openPanel.beginSheetModal(for: NSApp.mainWindow!) { result in if result == .cancel { return } if !openPanel.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 } if let pdf = CPDFDocument(url: openPanel.url!) { if pdf.allowsCopying == false || pdf.allowsPrinting == false { Task { _ = await KMAlertTool.runModel(message: KMLocalizedString("This is a secured document. Editing is not permitted.", nil)) } return } } DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { let pdfDocument = CPDFDocument(url: openPanel.url!) KMPrintWindowController.showNewPrintWindowControll(inputDocument: pdfDocument, inputPageRange: KMPrintPageRange(), printType: .multipage) } } } @IBAction func escButtonAction(_ sender: Any) { // self.historyFileViewController.selectFiles.removeAll() // if self.historyFileViewController.showMode == .Thumbnail { // self.historyFileViewController.historyFileCollectionView.reloadData() // } else { // self.historyFileViewController.historyFileTableView.reloadData() // } } @IBAction func importFromFile(_ sender: Any) { self.openSupportPDFButtonAction() } @IBAction func menuItemClick_mergePDF(_ sender: Any) { fastTool_MergePDF() } @IBAction func menuItemClick_Compress(_ sender: Any) { fastTool_Compression() } @IBAction func menuItemClick_Convert(_ sender: Any) { fastTool_ConvertPDF() } @IBAction func menuItemClick_SettingPassword(_ sender: Any) { KMBatchQuickActionManager.defaultManager.actionType = .add fastTool_Security() } @IBAction func menuItemClick_RemovePassword(_ sender: Any) { KMBatchQuickActionManager.defaultManager.actionType = .add fastTool_Security() } 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 originalFileName = path.lastPathComponent.deletingPathExtension.lastPathComponent 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 kNewDocumentTempSavePath(_ fileName: String) -> String { // let searchPath = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).last //// let append1 = searchPath?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!) // let append2 = searchPath!.stringByAppendingPathComponent(String(format: "%@", fileName)) // return append2 // } // MARK: Notification @objc func homeFileRectChange(_ notification: Notification) -> Void { let window = notification.object self.historyFileViewController.reloadData() } } // MARK: window Menu extension KMHomeViewController { @IBAction func menuItemAction_showForwardTagPage(_ sender: Any) { (self.myDocument as? KMMainDocument)?.browser.selectPreviousTab() } @IBAction func menuItemAction_showNextTagPage(_ sender: Any) { (self.myDocument as? KMMainDocument)?.browser.selectNextTab() } @IBAction func menuItemAction_newTagPageToNewWindow(_ sender: Any) { if let browser = (self.myDocument as? KMMainDocument)?.browser { ((browser as! KMBrowser).windowController as? KMBrowserWindowController)?.openNewWindow(sender) } } @IBAction func menuItemAction_mergeAllWindow(_ sender: Any) { ((self.myDocument as? KMMainDocument)?.browser.windowController as? KMBrowserWindowController)?.mergeAllWindow(sender) } @IBAction func menuItemAction_currentWindowName(_ sender: Any) { } } // MARK: file Menu extension KMHomeViewController { @IBAction func menuItemAction_closeWindow(_ sender: Any) { self.view.window?.close() } @IBAction func menuItemAction_closeAllWindows(_ sender: Any) { for window in NSApp.windows { window.close() } } @IBAction func menuItemAction_ConvertToWord(_ sender: Any) { self.fastTool_PDFToWord() } @IBAction func menuItemAction_ConvertToExcel(_ sender: Any) { self.fastTool_PDFToExcel() } @IBAction func menuItemAction_ConvertToPPT(_ sender: Any) { self.fastTool_PDFToPPT() } @IBAction func menuItemAction_ConvertToRTF(_ sender: Any) { self.showConvertWindow(type: .rtf) } @IBAction func menuItemAction_ConvertToHTML(_ sender: Any) { self.showConvertWindow(type: .html) } @IBAction func menuItemAction_ConvertToText(_ sender: Any) { self.showConvertWindow(type: .text) } @IBAction func menuItemAction_ConvertToCSV(_ sender: Any) { self.showConvertWindow(type: .csv) } @IBAction func menuItemAction_ConvertToImage(_ sender: Any) { self.fastTool_PDFToImage() } } // MARK: help Menu extension KMHomeViewController { // @IBAction func menuItemAction_search(_ sender: Any) { // // } } // MARK: - Analytics (埋点) extension KMHomeViewController { func trackEvent_ai(eventName: String) -> Void { KMAnalytics.trackEvent(eventName: eventName, parameters: [ KMAnalytics.Parameter.categoryKey : KMAnalytics.Category.home, KMAnalytics.Parameter.labelKey : KMAnalytics.Label.ai_Btn], platform: .AppCenter, appTarget: .all) } func trackEvent_create(eventName: String) -> Void { KMAnalytics.trackEvent(eventName: eventName, parameters: [ KMAnalytics.Parameter.categoryKey : KMAnalytics.Category.home, KMAnalytics.Parameter.labelKey : KMAnalytics.Label.create_Btn], platform: .AppCenter, appTarget: .all) } } extension KMHomeViewController { //文件对比 func openContentCompareVC(with pdfCompareContent: CPDFCompareContent?, results: [CPDFCompareResults], oldDocument: CPDFDocument, document: CPDFDocument) { let compareContentController = KMCompareContentWindowController(document: document, oldDocument: oldDocument, results: results) self.currentController = compareContentController // let compareContentView = KMCompareContentView() // compareContentView.oldDocument = oldDocument // compareContentView.document = document // compareContentView.compareResults = results compareContentController.saveHandle = { [unowned self] view in DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.25) { [unowned self] in let saveController = KMCompareSaveWindow(windowNibName: "KMCompareSaveWindow") self.currentWindowController = saveController saveController.cancelHandle = { [unowned self] controller in NSWindow.currentWindow().endSheet(controller.window!) self.currentWindowController = nil } saveController.saveHandle = { [unowned self] controller, saveType in let folderPath = controller.fileSaveFolderPath if folderPath != nil { if !FileManager.default.fileExists(atPath: folderPath) { try? FileManager.default.createDirectory(atPath: folderPath, withIntermediateDirectories: true, attributes: nil) } var savePath: String #if VERSION_DMG #else let url = URL(fileURLWithPath: folderPath) let fileAccess = AppSandboxFileAccess() fileAccess?.persistPermissionURL(url) if let bookmarkData = try?url.bookmarkData(options: [.withSecurityScope]) { fileAccess?.bookmarkPersistanceDelegate.setBookmarkData(bookmarkData, for: url) let urlString = url.path let _url = URL(fileURLWithPath: urlString) fileAccess?.bookmarkPersistanceDelegate.setBookmarkData(bookmarkData, for: _url) } #endif switch saveType { case 0: let filePath = oldDocument.documentURL.path let fileName = filePath.deletingPathExtension.lastPathComponent savePath = "\(folderPath)/\(fileName)_compare\(filePath.extension)" savePath = self.getValidFilePath(savePath) oldDocument.write(to: URL(fileURLWithPath: savePath)) NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: savePath)]) case 1: let filePath = document.documentURL.path let fileName = filePath.deletingPathExtension.lastPathComponent savePath = "\(folderPath)/\(fileName)_compare\(filePath.extension)" savePath = self.getValidFilePath(savePath) document.write(to: URL(fileURLWithPath: savePath)) NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: savePath)]) case 2: let filePath = oldDocument.documentURL.path let fileName = filePath.deletingPathExtension.lastPathComponent savePath = "\(folderPath)/MergedCompareFile\(filePath.extension)" savePath = self.getValidFilePath(savePath) pdfCompareContent!.saveAsComparisonDocument(withFilePath: savePath) NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: savePath)]) default: break } } NSWindow.currentWindow().endSheet(controller.window!) self.currentWindowController = nil } NSWindow.currentWindow().beginSheet(saveController.window!) } } compareContentController.closeHandle = { [unowned self] controller in self.view.window!.endSheet(controller.window!) self.currentController = nil // view.removeFromSuperview() } NSWindow.currentWindow().beginSheet(compareContentController.window!) // self.PDFContendView.addSubview(compareContentView) // compareContentView.frame = self.PDFContendView.bounds // compareContentView.autoresizingMask = [.width,.height] } func getValidFilePath(_ oldPath: String) -> String { let fileManager = FileManager.default do { let fileAttributes = try fileManager.attributesOfItem(atPath: oldPath) guard let fileType = fileAttributes[FileAttributeKey.type] as? String else { return oldPath } var i = 1 var newPath = oldPath while fileManager.fileExists(atPath: newPath) { if fileType == FileAttributeType.typeDirectory.rawValue { newPath = oldPath + "(\(i))" } else { let fileExtension = (oldPath as NSString).pathExtension newPath = ((oldPath as NSString).deletingPathExtension as NSString).appendingFormat("(\(i)).\(fileExtension)" as NSString) as String } i += 1 } return newPath } catch { print("Error getting file attributes: \(error)") return oldPath } } func openCoveringCompareVC(with pdfDocument: CPDFDocument) { let controller = KMCompareCoveringWindowController(document: pdfDocument) self.currentWindowController = controller // let coveringView = KMCompareCoveringView() // coveringView.pdfDocument = pdfDocument controller.closeHandle = { [unowned self] controller in // view.removeFromSuperview() self.view.window!.endSheet(controller.window!) self.currentController = nil } controller.saveHandle = { [unowned self] controller in let savePanel = NSSavePanel() savePanel.nameFieldStringValue = "untitled" savePanel.allowedFileTypes = ["pdf"] savePanel.beginSheetModal(for: NSWindow.currentWindow()) { result in if result == .OK { pdfDocument.write(to: savePanel.url!) NSWorkspace.shared.activateFileViewerSelecting([savePanel.url!]) } } } // self.view.window!.endSheet(controller.window!) NSWindow.currentWindow().beginSheet(controller.window!) // self.PDFContendView.addSubview(coveringView) // coveringView.frame = self.PDFContendView.bounds // coveringView.autoresizingMask = [.width,.height] } }