// // KMBatchOperateConvertViewController.swift // PDF Reader Pro // // Created by kdanmobile on 2023/11/1. // import Cocoa typealias detailInfoViewMouseDownCallback = (_ mouseDown: Bool) -> () class KMDetailInfoView: NSView{ var mouseDownCallback: detailInfoViewMouseDownCallback? override func mouseDown(with event: NSEvent) { super.mouseDown(with: event) guard let callBack = mouseDownCallback else { return } callBack(true) } } class KMBatchOperateConvertViewController: KMBatchOperateBaseViewController{ var dataSourcesArray: [KMConvertWithPDFType]? @IBOutlet var bottomView: NSView! @IBOutlet var convertButton: NSButton! @IBOutlet var buttonBottemOffset: NSLayoutConstraint! @IBOutlet var detailInfoLabel: NSTextField! @IBOutlet var detailInfoBox: NSBox! @IBOutlet var separateStypeTopOffset: NSLayoutConstraint! @IBOutlet var separateStypeBox: NSBox! @IBOutlet var wordButtonOne: NSButton! @IBOutlet var wordButtonTwo: NSButton! @IBOutlet var excelStyleBox: NSBox! @IBOutlet var allContentMenu: NSPopUpButton! @IBOutlet var allContentMenu2: NSMenuItem! @IBOutlet var allContentMenu3: NSMenuItem! @IBOutlet var onlyTextBtn: NSButton! @IBOutlet var onlyTableBtn: NSButton! @IBOutlet var allContentBtn: NSButton! @IBOutlet var tableMenu1: NSMenuItem! @IBOutlet var tableMenu2: NSMenuItem! @IBOutlet var tableMenu3: NSMenuItem! @IBOutlet var tableMenu: NSPopUpButton! @IBOutlet var csvExtractButton: NSButton! @IBOutlet var ocrBox: NSBox! @IBOutlet var ocrLabel: NSTextField! @IBOutlet var ocrButton: NSButton! @IBOutlet var ocrLanguageBox: NSPopUpButton! @IBOutlet var ocrTopOffset: NSLayoutConstraint! @IBOutlet var headerView: KMConvertCollectionViewHeader! @IBOutlet var headerTopOffset: NSLayoutConstraint! @IBOutlet var formatLabel: NSTextField! @IBOutlet var formatSelectButton: NSPopUpButton! var excelContentOption: CPDFConvertExcelContentOptions? var excelWorksheetOption: CPDFConvertExcelWorksheetOptions? var haveFiles: Bool = false deinit { NotificationCenter.default.removeObserver(self) } override var interfaceStatus: KMBatchOperateInterfaceStatus?{ set{ super.interfaceStatus = newValue self.convertButton.isEnabled = true if newValue == .Processing { formatSelectButton.isEnabled = false self.convertButton.title = NSLocalizedString("Cancel", comment: "") self.convertButton.tag = 2 self.convertButton.setTitleColor(KMAppearance.Layout.w0Color()) self.convertButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor if self.convertType == .WordStandard { self.convertButton.title = NSLocalizedString("Convert", comment: "") self.convertButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor self.convertButton.isEnabled = false } } else { DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) { var files: [URL] = [] for url in self.successFilePathURLArray! { if FileManager.default.fileExists(atPath: url.path) { files.append(url) } } if files.count > 0 { let workspace = NSWorkspace.shared workspace.activateFileViewerSelecting(files) } } formatSelectButton.isEnabled = true self.convertButton.title = NSLocalizedString("Convert", comment: "") self.convertButton.tag = 1 self.convertButton.setTitleColor(KMAppearance.Layout.w0Color()) self.convertButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor } } get{ return super.interfaceStatus } } override var convertType: KMConvertWithPDFType?{ set{ super.convertType = newValue changeAllFilesToConvertType(convertType!) fetchFileListViewController()?.reloadConvertInterface(withType: convertType!) } get{ return super.convertType } } func changeAllFilesToConvertType(_ type: KMConvertWithPDFType) { for i in 0.. 0 { detailInfoBox.isHidden = false buttonBottemOffset.constant = 45 } else { detailInfoBox.isHidden = true buttonBottemOffset.constant = 10 } if self.convertType == .WordAdvance { separateStypeBox.isHidden = false excelStyleBox.isHidden = true csvExtractButton.isHidden = true ocrBox.isHidden = false wordButtonOne.title = NSLocalizedString("Retain Flowing Text", comment: "") wordButtonTwo.title = NSLocalizedString("Retain Page Layout", comment: "") ocrTopOffset.constant = 15 + separateStypeBox.frame.height } else if self.convertType == .Excel { separateStypeBox.isHidden = true excelStyleBox.isHidden = false csvExtractButton.isHidden = true ocrBox.isHidden = false ocrTopOffset.constant = 15 + excelStyleBox.frame.height } else if .Json == convertType { wordButtonOne.title = NSLocalizedString("Extract text content", comment: "") wordButtonTwo.title = NSLocalizedString("Extract Table", comment: "") separateStypeBox.isHidden = false excelStyleBox.isHidden = true csvExtractButton.isHidden = true ocrBox.isHidden = false ocrTopOffset.constant = 15 + separateStypeBox.frame.height } else if (.PowerPoint == convertType || .RTF == convertType || .HTML == convertType || .Text == convertType) { separateStypeBox.isHidden = true excelStyleBox.isHidden = true csvExtractButton.isHidden = true ocrBox.isHidden = false ocrTopOffset.constant = 15 } else if self.convertType == .CSV { separateStypeBox.isHidden = true excelStyleBox.isHidden = true csvExtractButton.isHidden = false ocrBox.isHidden = true self.csvExtractButton.title = NSLocalizedString("Extract Tables Only", comment: "") } else { separateStypeBox.isHidden = true excelStyleBox.isHidden = true csvExtractButton.isHidden = true ocrBox.isHidden = true } } override func viewDidLoad() { super.viewDidLoad() self.prepareData() updateFormatView() self.view.wantsLayer = true convertButton.wantsLayer = true convertButton.font = NSFont.systemFont(ofSize: 13) convertButton.layer?.cornerRadius = 1.0 interfaceStatus = .PrepareProcess allContentBtn.state = .on allContentMenu.isEnabled = true tableMenu.isEnabled = false excelContentOption = .allContent excelWorksheetOption = .forEachPage onlyTextBtn.title = NSLocalizedString("Only Text", comment: "") onlyTableBtn.title = NSLocalizedString("Only Table", comment: "") allContentBtn.title = NSLocalizedString("All Content", comment: "") onlyTextBtn.toolTip = NSLocalizedString("Only Text", comment: "") onlyTableBtn.toolTip = NSLocalizedString("Only Table", comment: "") allContentBtn.toolTip = NSLocalizedString("All Content", comment: "") tableMenu1.title = NSLocalizedString("Create Sheet for each Table", comment: "") tableMenu2.title = NSLocalizedString("Create Sheet for each Page", comment: "") allContentMenu2.title = NSLocalizedString("Create Sheet for each Page", comment: "") tableMenu3.title = NSLocalizedString("Create single Sheet for File", comment: "") allContentMenu3.title = NSLocalizedString("Create single Sheet for File", comment: "") formatLabel.stringValue = KMLocalizedString("Format:", nil) ocrBox.title = KMLocalizedString("Text Recognition Settings", nil) ocrBox.titleFont = .SFProTextBoldFont(14.0) formatLabel.font = .SFProTextBoldFont(14.0) headerView.convertHeaderClickedCallBack = { [weak self] in self?.moreConvertInfoAction() } ocrLanguageBox.selectItem(at: 0) ocrLabel.textColor = KMAppearance.Layout.h2Color() ocrLanguageBox.isEnabled = false ocrButton.state = .off self.updateViewColor() NotificationCenter.default.addObserver(self, selector: #selector(batchFilesCountNotification(notification:)), name: Notification.Name(rawValue: "KMBatchFilesCountNotification"), object: nil) NotificationCenter.default.addObserver(self, selector: #selector(IAPProductPurchasedNotification(notification:)), name: NSNotification.Name("KMIAPProductPurchasedNotification"), object: nil) NotificationCenter.default.addObserver(self, selector: #selector(IAPProductRestoreFinishedNotification(notification:)), name: NSNotification.Name("KMIAPProductRestoreFinishedNotification"), object: nil) // NotificationCenter.default.addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil) DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil) NotificationCenter.default.addObserver(self, selector: #selector(deviceActivateStatusChanged(notification:)), name: NSNotification.Name("kDeviceActivateNotification"), object: nil) } @objc func batchFilesCountNotification(notification: NSNotification) { let arr: Array? = notification.object as? [KMBatchOperateFile] self.files? = arr ?? [] if files!.count > 0 { self.convertButton.setTitleColor(NSColor.white) self.convertButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor self.haveFiles = true } else { self.convertButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.6)) self.convertButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor self.haveFiles = false } } @objc func themeChanged(notification: NSNotification) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.updateViewColor() } } @objc func IAPProductRestoreFinishedNotification(notification: NSNotification) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.updateBottomView() self.prepareData() self.updateFormatView() } } @objc func IAPProductPurchasedNotification(notification: NSNotification) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.updateBottomView() self.prepareData() self.updateFormatView() } } @objc func deviceActivateStatusChanged(notification: NSNotification) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.updateBottomView() self.prepareData() self.updateFormatView() } } func updateViewColor() { self.view.wantsLayer = true if KMAppearance.isDarkMode() { self.view.layer?.backgroundColor = NSColor(red: 0.055, green: 0.067, blue: 0.078, alpha: 1).cgColor } else { self.view.layer?.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1).cgColor } } func convertActionVC() { var vc: KMToolCompareWindowController? = nil if(.WordStandard == self.convertType || .WordAdvance == self.convertType) { vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 1) } else if (.Excel == self.convertType) { vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 2) } else if (.PowerPoint == self.convertType) { vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 3) } else if (self.convertType == .JPG || self.convertType == .PNG || self.convertType == .GIF || self.convertType == .TIFF || self.convertType == .TGA || self.convertType == .BMP){ vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 4) } else { vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 0) } vc?.showWindow(nil) } func prepareData() { let arr: [KMConvertWithPDFType] = [.Excel, .PowerPoint, .RTF, .CSV, .HTML, .Text, .JPEG, .JPG, .PNG, .GIF, .TIFF, .TGA, .BMP, .JPEG2000, .Json] self.dataSourcesArray = arr var needShowAdvance = true var needShowDefault = true #if VERSION_FREE // 桌机版 if IAPProductsManager.default().isAvailableAllFunction() { if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { needShowAdvance = true needShowDefault = false } } #else if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { needShowAdvance = true needShowDefault = false } #endif if needShowDefault { var wordType: KMConvertWithPDFType = .WordStandard self.dataSourcesArray?.insert(wordType, at: 0) } if needShowAdvance { var wordType: KMConvertWithPDFType = .WordAdvance self.dataSourcesArray?.insert(wordType, at: 0) } } func updateFormatView() { var isShowAdvanced = false #if VERSION_FREE #if VERSION_DMG // 桌机版 isShowAdvanced = true if IAPProductsManager.default().isAvailableAllFunction() { if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { isShowAdvanced = false } } #else // 免费版 isShowAdvanced = true if IAPProductsManager.default().isAvailableAllFunction() { if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { isShowAdvanced = false } } #endif #else isShowAdvanced = true if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { isShowAdvanced = false } #endif self.formatSelectButton.removeAllItems() for i in 0.. KMConvertWithPDFType { var type: KMConvertWithPDFType? switch num { case 0: type = .WordAdvance case 1: type = .WordStandard case 2: type = .Excel case 3: type = .PowerPoint case 4: type = .RTF case 5: type = .CSV case 6: type = .HTML case 7: type = .Text case 8: type = .JPEG case 9: type = .JPG case 10: type = .PNG case 11: type = .GIF case 12: type = .TIFF case 13: type = .TGA case 14: type = .BMP case 15: type = .JPEG2000 case 16: type = .Json default: type = .WordAdvance } return type! } func moreConvertInfoAction() { if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() == false { #if VERSION_DMG if IAPProductsManager.default().isAvailableAllFunction() && IAPProductsManager.default().isAvailableAdvancedPDFToOffice() == false { let limitWC = KMPurchaseLimitWindowController.currentLimitWC() limitWC.continueBlock = { windowController in } limitWC.window?.center() limitWC.showWindow(nil) }else{ let winC = KMPurchaseCompareWindowController.sharedInstance() if let viewC = self.view.window?.contentViewController, viewC.kEventTag == 1 { winC?.kEventName = "Onbrd_ConvertPDF_BuyNow" } else { if convertType == .WordStandard || convertType == .WordAdvance { winC?.kEventName = "Onbrd_PDFtoWord_BuyNow" } else if convertType == .Excel { winC?.kEventName = "Onbrd_PDFtoExcel_BuyNow" } else if convertType == .PowerPoint { winC?.kEventName = "Onbrd_PDFtoPPT_BuyNow" } } winC?.showWindow(nil) } #else if IAPProductsManager.default().isAvailableAllFunction() { self.convertActionVC() } else { KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) } #endif } } @IBAction func buttonClicked_FormatSelect(_ sender: NSButton) { guard let item = self.formatSelectButton.selectedItem else { return } convertType = KMConvertWithPDFType(rawValue: item.tag) ?? .WordAdvance updateBottomView() } @IBAction func comboxClicked_OcrLanguage(_ sender: AnyObject?) { KMPrint("语言 ...") switch (ocrLanguageBox.indexOfSelectedItem) { case 0: //chinese // COCRLanguageChinese; break; case 1: //chinese zht // COCRLanguageChineseTraditional; break; case 2: //English // COCRLanguageEnglish; break; case 3: //Japanese // COCRLanguageJapanese; break; case 4: //Kroean // COCRLanguageKorean; break; case 5: //Serbian // COCRLanguageSerbian; break; case 6: //Occitan // COCRLanguageOccitan; break; case 7: //Danish // COCRLanguageDanish; break; case 8: //German // COCRLanguageGerman; break; case 9: //French // COCRLanguageFrench; break; case 10: //Italian // COCRLanguageItalian; break; case 11: //Spanish // COCRLanguageSpanish; break; case 12: //Portuguese // COCRLanguagePortuguese; break; case 13: //Maori // COCRLanguageMaori; break; case 14: //Malay // COCRLanguageMalay; break; case 15: //Malay // COCRLanguageMaltese; break; case 16: //Dutch // COCRLanguageDutch; break; case 17: //Norwegian // COCRLanguageNorwegian; break; case 18: //Polish // COCRLanguagePolish; break; case 19: //Romanian // COCRLanguageRomanian; break; case 20: //Slovak // COCRLanguageSlovak; break; case 21: //Slovenian // COCRLanguageSlovenian; break; case 22: //Albanian // COCRLanguageAlbanian; break; case 23: //Swedish // COCRLanguageSwedish; break; case 24: //Swahili // COCRLanguageSwahili; break; case 25: //Tagalog // COCRLanguageTagalog; break; case 26: //Turish // COCRLanguageTurish; break; case 27: //Uzbek // COCRLanguageUzbek; break; case 28: //Vietnamese // COCRLanguageVietnamese; break; case 29: //Afrikaans // COCRLanguageAfrikaans; break; case 30: //Azerbaijani // COCRLanguageAzerbaijani; break; case 31: //Bosnian // COCRLanguageBosnian; break; case 32: //Czech // COCRLanguageCzech; break; case 33: //Welsh // COCRLanguageWelsh; break; case 34: //Estonian // COCRLanguageEstonian; break; case 35: //Irish // COCRLanguageIrish; break; case 36: //Croatian // COCRLanguageCroatian; break; case 37: //Hungarian // COCRLanguageHungarian; break; case 38: //Indonesian // COCRLanguageIndonesian; break; case 39: //Icelandic // COCRLanguageIcelandic; break; case 40: //Kurdish // COCRLanguageKurdish; break; case 41: //Lithuanian // COCRLanguageLithuanian; break; case 42: //Latvian // COCRLanguageLatvian; break; case 43: //Marathi // COCRLanguageMarathi; break; case 44: //Nepali // COCRLanguageNepali; break; case 45: //Latvia // COCRLanguageHindi; break; case 46: //Bihari // COCRLanguageBihari; break; case 47: //Maithili // COCRLanguageMaithili; break; case 48: //Angika // COCRLanguageAngika; break; case 49: //Bhojpuri // COCRLanguageBhojpuri; break; case 50: //Magahi // COCRLanguageMagahi; break; case 51: //Nagpur // COCRLanguageNagpur; break; case 52: //Newari // COCRLanguageNewari; break; case 53: //GoanKonkani // COCRLanguageGoanKonkani; break; case 54: //SaudiArabia // COCRLanguageSaudiArabia; break; default: //Other Language such as Lagtin or Hindu break; } } @IBAction func comboxClicked_SupoortOCR(_ sender: AnyObject?) { KMPrint("是否支持OCR ...") if(ocrButton.state == .on) { ocrLabel.textColor = KMAppearance.titleColor() ocrLanguageBox.isEnabled = true } else { ocrLabel.textColor = KMAppearance.Layout.h2Color() ocrLanguageBox.isEnabled = false } } }