// // KMConvertBaseWindowController.swift // PDF Reader Pro // // Created by tangchao on 2022/12/5. // import PDFKit typealias KMConvertBaseWindowControllerItemClick = (Int) -> () class KMConvertBaseWindowController: KMBaseWindowController { @IBOutlet weak var titleLabel: NSTextField! @IBOutlet weak var leftBox: NSBox! @IBOutlet weak var prePDFView: KMCustomPDFView? @IBOutlet weak var numberBox: NSView! @IBOutlet weak var numberTextField: NSTextField! @IBOutlet weak var perLabel: NSTextField! @IBOutlet weak var totalNumberLabel: NSTextField! @IBOutlet weak var backBox: NSBox! @IBOutlet weak var nextBox: NSBox! @IBOutlet weak var rightScrollView: NSScrollView! @IBOutlet weak var batchButton: NSButton! @IBOutlet weak var canelBox: NSBox! @IBOutlet weak var convertBox: NSBox! @IBOutlet weak var rightBoxHeightConst: NSLayoutConstraint! var canelButtonVC: KMDesignButton? var convertButtonVC: KMDesignButton? var backButtonVC: KMDesignButton? var nextButtonVC: KMDesignButton? var itemClick: KMConvertBaseWindowControllerItemClick? var documentModel: KMDocumentModel? var currentPageIndex: Int = 1 var pageRange = KMPageRange.all var pageRangeString: String = "" var settingView: KMConvertSettingView? var subType: Int = 0 var fileExtension: String { get { return "" } } var progressController: SKProgressController? private var convert: KMPDFConvert? var limit = true // 是否限制次数 var limitCount = true var oriDocumentUrl: URL? var subscribeWaterMarkType: KMSubscribeWaterMarkType? deinit { KMPrint("KMConvertBaseWindowController 已释放") self.prePDFView?.removeFromSuperview() self.prePDFView = nil #if VERSION_DMG NotificationCenter.default.removeObserver(self) #endif } convenience init() { self.init(windowNibName: "KMConvertBaseWindowController") } override func awakeFromNib() { super.awakeFromNib() DispatchQueue.main.async { self.window?.makeFirstResponder(nil) } } override func windowDidLoad() { super.windowDidLoad() // if (self.convertCountIsReach()) { // Swift.debugPrint("转档次数已达到限制. count: \(self.getConvertCount())") // } // #if VERSION_DMG NotificationCenter.default.addObserver(self, selector: #selector(km_windowWillCloseNotifation), name: NSWindow.willCloseNotification, object: nil) // #endif if (self.documentModel != nil) { let document = CPDFDocument(url: self.documentModel!.documentURL) if (document!.isLocked) { document?.unlock(withPassword: self.documentModel!.password) } self.prePDFView?.document = document! let number: Int = Int((self.prePDFView?.document.pageCount)!) let string = "\(number)" totalNumberLabel.stringValue = string self.prePDFView?.go(toPageIndex: self.documentModel!.currentIndex, animated: false) } if (self.prePDFView?.documentView() != nil) { self.prePDFView?.documentView().enclosingScrollView?.hasVerticalScroller = false self.prePDFView?.documentView().enclosingScrollView?.hasHorizontalScroller = false } if let pageCount = self.prePDFView?.document.pageCount { self.settingView?.pageCount = Int(pageCount) } batchButton.title = NSLocalizedString("Batch", comment: "") batchButton.isBordered = false batchButton.wantsLayer = true batchButton.layer?.borderWidth = 1 batchButton.layer?.cornerRadius = 4 batchButton.target = self batchButton.action = #selector(batchButtonAction) batchButton.isHidden = true self.updateBackAndNextButtonState() } override func initSubViews() { super.initSubViews() let view = self.initSettingView() // view?.frame = self.rightScrollView.bounds // view?.autoresizingMask = [.width, .height] self.settingView = view self.rightScrollView.documentView = view self.rightScrollView.verticalScrollElasticity = .none self.rightScrollView.horizontalScrollElasticity = .none view?.km_add_inset_constraint() view?.currentLanguage = self.getCurrentLanguage() view?.lanugageDidSelected = { [weak self] value, _ in guard let index = value as? Int else { return } self?.saveLanugageSelectedIndex(index: index) } view?.pageRangeDidChange = { [weak self] pageRange in self?.pageRange = pageRange if (pageRange != .custom) { self?.updatePreView(pageRange: pageRange) } } view?.pageRangeDidInputFinishCallback = { [unowned self] string in self.pageRangeString = string let array = self.findSelectPage(pageRangeString: string) if array.count == 0 { let alert = NSAlert() alert.alertStyle = .warning alert.messageText = NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "") alert.runModal() self.settingView?.pageRangeItemView?.pageSizeVC?.stringValue = "" } else { self.updatePreView(pageRange: .custom, pageString: string) } } view?.tipView?.itemClick = { [unowned self] _, _ in #if VERSION_DMG KMTools.openPurchaseProductWebsite() #else Task { @MainActor in if await (KMLightMemberManager.manager.canPayFunction() == false) { let _ = KMSubscribeWaterMarkWindowController.show(window: self.window!) { isSubscribeSuccess, isWaterMarkExport, isClose in if (isSubscribeSuccess) { self.refreshUI() } } } } #endif } self.settingView?.tipView?.isHidden = true Task { @MainActor in if await (KMLightMemberManager.manager.canUseAdvanced() == false) { self.limitCount = true } else { self.limitCount = false } if await (KMLightMemberManager.manager.canPayFunction() == false) { #if VERSION_DMG if (self.limitCount) { // 未登录 self.settingView?.tipView?.isHidden = true } else { self.settingView?.tipView?.isHidden = false } #else self.settingView?.tipView?.isHidden = false #endif } else { self.limit = false } } self.backButtonVC = KMDesignButton.init(withType: .Image) self.backBox.contentView = self.backButtonVC!.view self.nextButtonVC = KMDesignButton.init(withType: .Image) self.nextBox.contentView = self.nextButtonVC!.view self.canelButtonVC = KMDesignButton.init(withType: .Text) self.canelBox.contentView = self.canelButtonVC!.view self.convertButtonVC = KMDesignButton.init(withType: .Text) self.convertBox.contentView = self.convertButtonVC!.view } override func initDefaultValue() { super.initDefaultValue() self.totalNumberLabel.lineBreakMode = .byTruncatingTail self.prePDFView?.setDisplay(.singlePage) self.prePDFView?.layoutDocumentView() self.prePDFView?.autoScales = true self.prePDFView?.delegate = self self.backBox.fillColor = .clear self.backButtonVC?.target = self self.backButtonVC?.action = #selector(backButtonAction) self.backButtonVC?.image = NSImage(named: "KMImageNamePreviousPageImage")! self.backButtonVC?.image_disabled = NSImage(named: "KMImageNamePreviousPageImageDisable")! self.backButtonVC?.pagination() self.numberBox.wantsLayer = true self.numberBox.layer?.backgroundColor = NSColor.white.cgColor self.numberBox.layer?.borderWidth = 1 self.numberBox.layer?.cornerRadius = 4 self.numberTextField.focusRingType = .none self.numberTextField.delegate = self self.numberTextField.isBordered = false self.nextBox.fillColor = .clear self.nextButtonVC?.target = self self.nextButtonVC?.action = #selector(nextButtonAction) self.nextButtonVC?.image = NSImage(named: "KMImageNameNextPageImage")! self.nextButtonVC?.image_disabled = NSImage(named: "KMImageNameNextPageImageDisable")! self.nextButtonVC?.pagination() self.canelBox.fillColor = .clear self.canelButtonVC?.target = self self.canelButtonVC?.action = #selector(cancelButtonAction) self.canelButtonVC?.stringValue = NSLocalizedString("Cancel", comment: "") self.canelButtonVC?.button(type: .Sec, size: .m) self.canelButtonVC?.button.keyEquivalent = KMKeyEquivalent.esc.string() self.convertBox.fillColor = .clear self.convertButtonVC?.target = self self.convertButtonVC?.action = #selector(convertButtonAction) self.convertButtonVC?.stringValue = NSLocalizedString("Convert", comment: "") self.convertButtonVC?.button(type: .Cta, size: .m) // convertButtonVC.button.keyEquivalent = KMKeyEquivalent.enter self.rightScrollView.hasVerticalScroller = false self.rightScrollView.hasHorizontalScroller = false self.initUIProperty() } private func initUIProperty() { self.titleLabel.textColor = NSColor.titleColor() self.titleLabel.font = .SFProTextSemiboldFont(16) self.leftBox.fillColor = NSColor.km_init(hex: "#F7F8FA") self.prePDFView?.backgroundColor = NSColor.km_init(hex: "#F7F8FA") self.numberBox.layer?.borderColor = NSColor.km_init(hex: "#DFE1E5").cgColor self.perLabel.textColor = NSColor.titleColor() self.perLabel.font = .SFProTextRegularFont(12) self.totalNumberLabel.textColor = NSColor.titleColor() self.totalNumberLabel.font = .SFProTextRegularFont(12) self.batchButton.setTitleColor(NSColor.buttonTitleColor()) self.batchButton.layer?.borderColor = NSColor.buttonBorderColor().cgColor self.batchButton.font = .SFProTextRegularFont(14) } func initSettingView() -> KMConvertSettingView? { let settingView = KMConvertSettingView.createFromNib() return settingView } public func initConvert() -> KMPDFConvert { return KMPDFConvert() } func setupContentHeight(height: CGFloat, animated: Bool = false) { if (animated) { self.rightBoxHeightConst.animator().constant = height } else { self.rightBoxHeightConst.constant = height } } func refreshUI() { } @objc func backButtonAction() { if let _ = self.prePDFView?.canGoToPreviousPage() { self.currentPageIndex -= 1 self.prePDFView?.goToPreviousPage(nil) self.numberTextField.stringValue = "\(self.prePDFView!.currentPageIndex+1)" self.updateBackAndNextButtonState() } } @objc func nextButtonAction() { if let _ = self.prePDFView?.canGoToNextPage() { self.currentPageIndex += 1 self.prePDFView?.goToNextPage(nil) self.numberTextField.stringValue = "\(self.prePDFView!.currentPageIndex+1)" self.updateBackAndNextButtonState() } } @objc func batchButtonAction() { guard let callback = itemClick else { return } callback(1) } @objc func cancelButtonAction() { self._clearData() guard let callback = itemClick else { return } callback(2) } @objc func convertButtonAction() { self.window?.makeFirstResponder(nil) if (self.pageRange == .custom) { let array = self.findSelectPage(pageRangeString: self.pageRangeString) if (array.count <= 0) { self.window?.makeFirstResponder(self.settingView?.pageRangeItemView?.pageSizeVC?.textField) return } } var pages: [Int] = [] let filePath = self.getConvertFileSavePath() if (FileManager.default.fileExists(atPath: filePath)) { try?FileManager.default.removeItem(atPath: filePath) } if ((self.prePDFView?.document?.writeDecrypt(to: URL(fileURLWithPath: filePath)))!) { for i in 0 ..< self.prePDFView!.document.pageCount { pages.append(Int(i)+1) } } if (pages.count <= 0) { let alert = NSAlert() alert.alertStyle = .warning alert.messageText = NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "") alert.runModal() return } Task { @MainActor in #if VERSION_DMG if (await (KMLightMemberManager.manager.canUseAdvanced() == false)) { let _ = KMComparativeTableViewController.show(window: self.window!, .convert) return } #endif if await (KMLightMemberManager.manager.canPayFunction() == false) { var isContinue = false if pages.count <= 10 { isContinue = true } var limit = self.convertCountIsReach() if (!self.limitCount) { // 登录 limit = false } if (limit) { isContinue = false } let _ = KMSubscribeWaterMarkWindowController.show(window: self.window!, isContinue: isContinue, limit: limit, type: self.subscribeWaterMarkType!) { isSubscribeSuccess, isWaterMarkExport, isClose in if (isClose) { return } if (isSubscribeSuccess) { self._convertButtonAction() return } if (isWaterMarkExport && !limit) { self._convertButtonAction(limit: true) return } } return } self._convertButtonAction() } } func convertModelAppendParams(convert: KMPDFConvert) -> () { if let isAllowOCR = self.settingView?.ocrEnabled { convert.isAllowOCR = isAllowOCR if let idx = self.settingView?.ocrItemView?.languageIndex { // convert.ocrLanguage = KMPDFConvertManager.defaultManager.languages_asc[idx] } } else { convert.isAllowOCR = false } } func getConvertFileSavePath() -> String { var path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last path?.append("/") path?.append(Bundle.main.bundleIdentifier!) if (FileManager.default.fileExists(atPath: path!) == false) { try?FileManager.default.createDirectory(atPath: path!, withIntermediateDirectories: false) } path?.append("/") path?.append("convert.pdf") return path! } func isValidPagesString(pagesString: String)-> Bool { var valid = false for ch in pagesString { if ch != "0" && ch != "1" && ch != "2" && ch != "3" && ch != "4" && ch != "5" && ch != "6" && ch != "7" && ch != "8" && ch != "9" && ch != "," && ch != "-" { valid = false break } else { valid = true } } return valid } func findSelectPage(pageRangeString: String) -> ([Int]) { if !isValidPagesString(pagesString: pageRangeString) { return [] } var result: [Int] = [] let array = pageRangeString.components(separatedBy: ",") for string in array { if string.isEmpty { return [] } else { let pages = string .components(separatedBy: "-") if pages.count > 2 { return [] } else if pages.count == 1 { let page = pages[0] if page.isEmpty || Int(page)! > self.documentModel!.pageCount || Int(page)! == 0 { return [] } else { var hasSame: Bool = false for i in result { if i == Int(page)! { hasSame = true return [] } } if !hasSame { result.append(Int(page)!) } } } else if pages.count == 2 { let page1 = pages[0] let page2 = pages[1] if page1.isEmpty || page2.isEmpty || Int(page1)! >= Int(page2)! || Int(page2)! > self.documentModel!.pageCount || Int(page1)! == 0 { return [] } else { var hasSame: Bool = false for i in Int(page1)! ... Int(page2)! { for j in result { if j == i { hasSame = true return [] } } } if !hasSame { for i in Int(page1)! ... Int(page2)! { result.append(i) } } } } } } return result } // MARK: - // MARK: Private Methods private func updateBackAndNextButtonState() { var nextEnabled = false if let result = self.prePDFView?.canGoToNextPage() { nextEnabled = result } var backEnabled = false if let result = self.prePDFView?.canGoToPreviousPage() { backEnabled = result } if (Thread.isMainThread) { self.backButtonVC?.state = backEnabled ? .Norm : .Disabled self.nextButtonVC?.state = nextEnabled ? .Norm : .Disabled } else { DispatchQueue.main.async { self.backButtonVC?.state = backEnabled ? .Norm : .Disabled self.nextButtonVC?.state = nextEnabled ? .Norm : .Disabled } } } internal func updatePreView(pageRange: KMPageRange, pageString: String = "") { let pages = self.getPages(pageRange, pageString: pageString) if (pages == nil || pages!.isEmpty) { let alert = NSAlert() alert.alertStyle = .warning alert.messageText = NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "") alert.runModal() return } var indexs = IndexSet() for i in 0 ..< self.prePDFView!.document.pageCount { indexs.insert(IndexSet.Element(i)) } self.prePDFView?.document.removePage(at: indexs) #if DEBUG let pageIndexs = self.getPageIndexs(pageRange, pageString: pageString) if (pageIndexs != nil) { for i in pageIndexs! { KMPrint(i) } } #endif // self.prePDFView.document?.importPages(pageIndexs!, from: self.documentModel.document, at: 0) for page in pages! { self.prePDFView?.document.insertPageObject(page, at: self.prePDFView!.document.pageCount) } DispatchQueue.main.async { self.prePDFView?.layoutDocumentView() self.prePDFView?.setNeedsDisplayForVisiblePages() self.prePDFView?.goToFirstPage(nil) let number: Int = Int(self.prePDFView!.document!.pageCount) self.totalNumberLabel.stringValue = "\(number)" self.currentPageIndex = 1 self.numberTextField.stringValue = "1" self.updateBackAndNextButtonState() } } private func getPageIndexs(_ pageRange: KMPageRange, pageString: String = "") -> IndexSet? { guard let pageCount = self.documentModel?.pageCount, pageCount > 0 else { return nil } var indexs = IndexSet() if (pageRange == .all) { for i in 0 ..< pageCount { indexs.insert(i) } } else if (pageRange == .odd) { for i in 0 ..< pageCount { if ((i % 2) == 1) { continue } indexs.insert(i) } } else if (pageRange == .even) { for i in 0 ..< pageCount { if ((i % 2) == 0) { continue } indexs.insert(i) } } else if (pageRange == .current) { if (self.currentPageIndex >= 1 && self.currentPageIndex <= pageCount) { indexs.insert(self.currentPageIndex-1) } } else if (pageRange == .custom) { let array = self.findSelectPage(pageRangeString: pageString) if array.count == 0 { } else { for i in 0 ..< array.count { let index = array[i] if (index > pageCount || index < 1) { continue } indexs.insert(index-1) } } } return indexs } private func getPages(_ pageRange: KMPageRange, pageString: String = "") -> [CPDFPage]? { guard let pageCount = self.documentModel?.pageCount, pageCount > 0 else { return nil } var pages: [CPDFPage] = [] if (pageRange == .all) { for i in 0 ..< pageCount { let page = self.documentModel!.document?.page(at: UInt(i)) if (page == nil) { continue } pages.append(page!) } } else if (pageRange == .odd) { for i in 0 ..< pageCount { if ((i % 2) == 1) { continue } let page = self.documentModel!.document?.page(at: UInt(i)) if (page == nil) { continue } pages.append(page!) } } else if (pageRange == .even) { for i in 0 ..< pageCount { if ((i % 2) == 0) { continue } let page = self.documentModel!.document?.page(at: UInt(i)) if (page == nil) { continue } pages.append(page!) } } else if (pageRange == .current) { let page = self.prePDFView?.currentPage() if (page != nil) { pages.append(page!) } } else if (pageRange == .custom) { let array = self.findSelectPage(pageRangeString: pageString) if array.count == 0 { } else { for i in 0 ..< array.count { let index = array[i] if (index > pageCount || index < 1) { continue } let page = self.documentModel?.document?.page(at: UInt(index-1)) if (page == nil) { continue } pages.append(page!) } } } return pages } private func _convertButtonAction(limit: Bool = false) { var pages: [Int] = [] let filePath = self.getConvertFileSavePath() if (FileManager.default.fileExists(atPath: filePath)) { try?FileManager.default.removeItem(atPath: filePath) } if (limit) { if let _ = KMTools.saveWatermarkDocument(document: self.prePDFView!.document, to: URL(fileURLWithPath: filePath), removePWD: true) { for i in 0 ..< self.prePDFView!.document.pageCount { if (i >= 10) { break } pages.append(Int(i)+1) } } } else { if ((self.prePDFView?.document?.writeDecrypt(to: URL(fileURLWithPath: filePath)))!) { for i in 0 ..< self.prePDFView!.document.pageCount { pages.append(Int(i)+1) } } } if (pages.count <= 0) { let alert = NSAlert() alert.alertStyle = .warning alert.messageText = NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "") alert.runModal() return } DispatchQueue.main.async { NSPanel.savePanel(self.window!) { panel in var url: URL = self.prePDFView!.document.documentURL if (self.oriDocumentUrl != nil) { url = self.oriDocumentUrl! } let name = url.deletingPathExtension().lastPathComponent panel.nameFieldStringValue = name panel.allowedFileTypes = [self.fileExtension] } completion: { response, url in if (response == .cancel) { return } let outputFolderPath = url!.deletingLastPathComponent().path let convert = self.initConvert() self.convert = convert convert.password = self.documentModel!.password convert.outputFolderPath = outputFolderPath convert.filePath = filePath convert.pages = pages var fileName = url!.deletingPathExtension().lastPathComponent if (self.fileExtension.isEmpty) { fileName = url!.lastPathComponent } // if (fileName.isEmpty) { // fileName = NSLocalizedString("Untitled", comment: "") // } convert.outputFileName = fileName self.convertModelAppendParams(convert: convert) DispatchQueue.main.async { self.showProgressWindow() self.progressController?.maxValue = Double(convert.pages.count) } #if VERSION_DMG if self.settingView?.ocrItemView?.checkVC?.state == .Checked { let bundlePath = kResourcePath?.stringByAppendingPathComponent("DocumentAI.bundle") CPDFConvertKit.setOCRModelPath(bundlePath) } #else let bundlePath = Bundle.main.path(forResource: "DocumentAI", ofType: "bundle") CPDFConvertKit.setOCRModelPath(bundlePath) #endif DispatchQueue.global().async { KMPDFConvertManager.defaultManager.convert(convert: convert, progress: { index in DispatchQueue.main.async { self.progressController?.increment(by: 1.0) } }) { [unowned self] finished, error in self.hiddenProgressWindow() // 清除临时文件 if (FileManager.default.fileExists(atPath: filePath)) { try?FileManager.default.removeItem(atPath: filePath) } if finished { self._clearData() self.recordConvertCount() cancelButtonAction() if FileManager.default.fileExists(atPath: convert.outputFilePath) { NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: convert.outputFilePath)]) } } else { var errorString = "" let myError: NSError? = error as? NSError if myError?.code == 1 { errorString = NSLocalizedString("Password required or incorrect password. Please re-enter your password and try again", comment: "") } else if myError?.code == 2 { errorString = NSLocalizedString("The license doesn't allow the permission", comment: "") } else if myError?.code == 3 { errorString = NSLocalizedString("Malloc failure", comment: "") } else if myError?.code == 4 { errorString = NSLocalizedString("Unknown error in processing conversion. Please try again later", comment: "") } else if myError?.code == 5 { errorString = NSLocalizedString("Unknown error in processing PDF. Please try again later", comment: "") } else if myError?.code == 6 { errorString = NSLocalizedString("File not found or could not be opened. Check if your file exists or choose another file to convert", comment: "") } else if myError?.code == 7 { errorString = NSLocalizedString("File not in PDF format or corruptead. Change a PDF file and try again", comment: "") } else if myError?.code == 8 { errorString = NSLocalizedString("Unsupported security scheme", comment: "") } else if myError?.code == 9 { errorString = NSLocalizedString("Page not found or content error", comment: "") } else { errorString = NSLocalizedString("Table not found", comment: "") } let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Conversion Failed", comment: "") alert.informativeText = errorString alert.addButton(withTitle: NSLocalizedString("OK", comment: "")) alert.runModal() } } } } } } // MARK: - Notifation Methods @objc private func km_windowWillCloseNotifation() { Task { @MainActor in if await (KMLightMemberManager.manager.canUseAdvanced() == false) { self.limitCount = true } else { self.limitCount = false } if await (KMLightMemberManager.manager.canPayFunction() == false) { #if VERSION_DMG if (self.limitCount) { // 未登录 self.settingView?.tipView?.isHidden = true } else { self.settingView?.tipView?.isHidden = false } #else self.settingView?.tipView?.isHidden = false #endif } else { self.limit = false } } } // MARK: Progress func showProgressWindow() { self.hiddenProgressWindow() let progress = SKProgressController() progress.window?.backgroundColor = NSColor.km_init(hex: "#36383B") progress.window?.contentView?.wantsLayer = true progress.window?.contentView?.layer?.backgroundColor = NSColor.km_init(hex: "#36383B").cgColor progress.progressField.textColor = NSColor.white progress.message = NSLocalizedString("Converting...", comment: "") progress.closeBlock = { [weak self] in if let convert = self?.convert { KMPDFConvertManager.defaultManager.cancel(convert: convert) } } self.progressController = progress self.window?.beginSheet(progress.window!) } func hiddenProgressWindow() { if (self.progressController != nil) { self.window?.endSheet((self.progressController?.window)!) self.progressController = nil } } func getCurrentLanguage() -> String { // return Bundle.main.preferredLocalizations.first! let array: [String] = UserDefaults.standard.object(forKey: "AppleLanguages") as! [String] return array.first! } /// 存储用户的选择的语言 func saveLanugageSelectedIndex(index: Int) { UserDefaults.standard.setValue("\(index)", forKey: kKMConvertLanugageSelectedIndex) UserDefaults.standard.synchronize() } private func _clearData() { if let _ = self.oriDocumentUrl { if let data = self.prePDFView?.document.documentURL.path, FileManager.default.fileExists(atPath: data) { try?FileManager.default.removeItem(atPath: data) } } } } extension KMConvertBaseWindowController: NSTextFieldDelegate { func controlTextDidChange(_ obj: Notification) { if numberTextField.isEqual(to: obj.object) { let textField: NSTextField = obj.object as! NSTextField var value: String = "" for ch in textField.stringValue { if ch != "0" && ch != "1" && ch != "2" && ch != "3" && ch != "4" && ch != "5" && ch != "6" && ch != "7" && ch != "8" && ch != "9" { } else { if value.isEmpty && ch == "0" { } else { value.append(ch) } } } if value.isEmpty { value.append("1") } else { if Int(value)! <= 0 { value = "1" } else if Int(value)! > self.prePDFView!.document!.pageCount { let number: Int = Int(self.prePDFView!.document!.pageCount) value = "\(number)" } } numberTextField.stringValue = value } } func controlTextDidEndEditing(_ obj: Notification) { if numberTextField.isEqual(to: obj.object) { if (numberTextField.stringValue.isEmpty) { numberTextField.stringValue = "1" self.prePDFView?.go(toPageIndex: 0, animated: false) self.currentPageIndex = 1 self.updateBackAndNextButtonState() return } let number: Int = Int(numberTextField.stringValue)! if number > 0 && number <= self.prePDFView!.document!.pageCount { guard let page = self.prePDFView?.document?.page(at: UInt(number-1)) else { return } self.prePDFView?.go(to: page) currentPageIndex = number self.updateBackAndNextButtonState() } } } } extension KMConvertBaseWindowController: CPDFViewDelegate { func pdfViewCurrentPageDidChanged(_ pdfView: CPDFView!) { let currentIndex = pdfView.currentPageIndex currentPageIndex = currentIndex + 1 numberTextField.stringValue = "\(currentIndex+1)" self.updateBackAndNextButtonState() } } let kKMConvertCountKey = "KMConvertCountKey" let kKMConvertCountMax = 2 extension KMConvertBaseWindowController { func convertCountIsReach() -> Bool { #if VERSION_DMG return false #else let cnt = self.getConvertCount() if (cnt >= kKMConvertCountMax) { return true } return false #endif } func recordConvertCount() { let cnt = self.getConvertCount() UserDefaults.standard.setValue(cnt+1, forKey: kKMConvertCountKey) UserDefaults.standard.synchronize() } func clearConvertRecordCount() { UserDefaults.standard.setValue(0, forKey: kKMConvertCountKey) UserDefaults.standard.synchronize() } private func getConvertCount() -> Int { return UserDefaults.standard.integer(forKey: kKMConvertCountKey) } }