// // 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 private var ocrLanguage_: COCRLanguage = .english 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 tables", 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("OCR Settings", nil) ocrBox.titleFont = .SFProTextBoldFont(14.0) formatLabel.font = .SFProTextBoldFont(14.0) headerView.convertHeaderClickedCallBack = { [weak self] in self?.moreConvertInfoAction() } self.ocrButton.title = NSLocalizedString("Recognize text", comment: "") self.ocrLabel.stringValue = NSLocalizedString("Language Option", comment: "") + ":" ocrLanguageBox.selectItem(at: 2) 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 KMMemberInfo.shared.isMemberAllFunction { 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 KMMemberInfo.shared.isMemberAllFunction { if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { isShowAdvanced = false } } #else // 免费版 isShowAdvanced = true if KMMemberInfo.shared.isMemberAllFunction { 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 KMMemberInfo.shared.isMemberAllFunction && IAPProductsManager.default().isAvailableAdvancedPDFToOffice() == false { let limitWC = KMPurchaseLimitWindowController.currentLimitWC() limitWC.continueBlock = { windowController in } limitWC.window?.center() limitWC.showWindow(nil) }else{ KMProductCompareWC.shared.orientation = false let winC = KMProductCompareWC.shared 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 KMMemberInfo.shared.isMemberAllFunction == true { self.convertActionVC() } else { KMMemberInfo.shared.advancedFunctionUsage() } #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?) { switch (ocrLanguageBox.indexOfSelectedItem) { case 0: //chinese self.ocrLanguage_ = .chinese break case 1: //chinese zht self.ocrLanguage_ = .chineseTraditional break case 2: //English self.ocrLanguage_ = .english break case 3: //Japanese self.ocrLanguage_ = .japanese break case 4: //Kroean self.ocrLanguage_ = .korean break case 5: //Serbian self.ocrLanguage_ = .serbian break case 6: //Occitan self.ocrLanguage_ = .occitan break case 7: //Danish self.ocrLanguage_ = .danish break case 8: //German self.ocrLanguage_ = .german break case 9: //French self.ocrLanguage_ = .french break case 10: //Italian self.ocrLanguage_ = .italian break case 11: //Spanish self.ocrLanguage_ = .spanish break case 12: //Portuguese self.ocrLanguage_ = .portuguese break case 13: //Maori self.ocrLanguage_ = .maori break case 14: //Malay self.ocrLanguage_ = .malay break case 15: //Malay self.ocrLanguage_ = .maltese break case 16: //Dutch self.ocrLanguage_ = .dutch break case 17: //Norwegian self.ocrLanguage_ = .norwegian break case 18: //Polish self.ocrLanguage_ = .polish break case 19: //Romanian self.ocrLanguage_ = .romanian break case 20: //Slovak self.ocrLanguage_ = .slovak break case 21: //Slovenian self.ocrLanguage_ = .slovenian break case 22: //Albanian self.ocrLanguage_ = .albanian break case 23: //Swedish self.ocrLanguage_ = .swedish break case 24: //Swahili self.ocrLanguage_ = .swahili break case 25: //Tagalog self.ocrLanguage_ = .tagalog break case 26: //Turish self.ocrLanguage_ = .turish break case 27: //Uzbek self.ocrLanguage_ = .uzbek break case 28: //Vietnamese self.ocrLanguage_ = .vietnamese break case 29: //Afrikaans self.ocrLanguage_ = .afrikaans break case 30: //Azerbaijani self.ocrLanguage_ = .azerbaijani break case 31: //Bosnian self.ocrLanguage_ = .bosnian break case 32: //Czech self.ocrLanguage_ = .czech break case 33: //Welsh self.ocrLanguage_ = .welsh break case 34: //Estonian self.ocrLanguage_ = .estonian break case 35: //Irish self.ocrLanguage_ = .irish break case 36: //Croatian self.ocrLanguage_ = .croatian break case 37: //Hungarian self.ocrLanguage_ = .hungarian break case 38: //Indonesian self.ocrLanguage_ = .indonesian break case 39: //Icelandic self.ocrLanguage_ = .icelandic break case 40: //Kurdish self.ocrLanguage_ = .kurdish break case 41: //Lithuanian self.ocrLanguage_ = .lithuanian break case 42: //Latvian self.ocrLanguage_ = .latvian break case 43: //Marathi self.ocrLanguage_ = .marathi break case 44: //Nepali self.ocrLanguage_ = .nepali break case 45: //Latvia self.ocrLanguage_ = .latvian break case 46: //Bihari self.ocrLanguage_ = .bihari break case 47: //Maithili self.ocrLanguage_ = .maithili break case 48: //Angika self.ocrLanguage_ = .angika break case 49: //Bhojpuri self.ocrLanguage_ = .bhojpuri break case 50: //Magahi self.ocrLanguage_ = .magahi break case 51: //Nagpur self.ocrLanguage_ = .nagpur break case 52: //Newari self.ocrLanguage_ = .newari break case 53: //GoanKonkani self.ocrLanguage_ = .goanKonkani break case 54: //SaudiArabia self.ocrLanguage_ = .saudiArabia break default: self.ocrLanguage_ = .english break } } @IBAction func comboxClicked_SupoortOCR(_ sender: AnyObject?) { if(ocrButton.state == .on) { ocrLabel.textColor = KMAppearance.titleColor() ocrLanguageBox.isEnabled = true } else { ocrLabel.textColor = KMAppearance.Layout.h2Color() ocrLanguageBox.isEnabled = false } } }