KMTTSWindowController.swift 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. //
  2. // KMTTSWindowController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by liujiajie on 2023/12/12.
  6. //
  7. import Cocoa
  8. import KMComponentLibrary
  9. typealias TTSCloseWindowCallback = (_ isCloseWindow: Bool) -> Void
  10. let minSpeed: Float = 0.6
  11. let maxSpeed: Float = 5.0
  12. let standardSpeed: Float = 175.0
  13. class KMTTSWindowController: NSWindowController, NSWindowDelegate{
  14. @IBOutlet var titleLabel: NSTextField!
  15. @IBOutlet var previousButton: ComponentButton!
  16. @IBOutlet var playButton: ComponentButton!
  17. @IBOutlet var nextButton: ComponentButton!
  18. @IBOutlet var divider: ComponentDivider!
  19. @IBOutlet var languageLabel: NSTextField!
  20. @IBOutlet var languageSelect: ComponentSelect!
  21. @IBOutlet var speedLabel: NSTextField!
  22. @IBOutlet var speedSlider: ComponentSlider!
  23. @IBOutlet var speedInput: ComponentInputNumber!
  24. @IBOutlet var continueCheckbox: ComponentCheckBox!
  25. // @IBOutlet var sontinuouButton: NSButton!
  26. // @IBOutlet var speedLabel: NSTextField!
  27. // @IBOutlet var languageLabel: NSTextField!
  28. //
  29. // @IBOutlet var languageComboBox: NSPopUpButton!
  30. // @IBOutlet var speedTextField: NSTextField!
  31. // @IBOutlet var speedSlider: NSSlider!
  32. //
  33. // @IBOutlet var speedStepper: NSStepper!
  34. // @IBOutlet var nextButton: KMToolbarItem!
  35. // @IBOutlet var forwardButton: KMToolbarItem!
  36. //
  37. // @IBOutlet var playButton: KMToolbarItem!
  38. //
  39. // @IBOutlet var speedBox: NSBox!
  40. //
  41. // @IBOutlet var sppendCountLabel: NSTextField!
  42. var pdfView: CPDFView!
  43. var closeWindowCallback: TTSCloseWindowCallback?
  44. var pdfSelection: CPDFSelection?
  45. var currentPageIndex: Int = 0
  46. var isChangePage = false
  47. var voiceArrays = NSMutableArray()
  48. static let share = KMTTSWindowController()
  49. convenience init() {
  50. self.init(windowNibName: "KMTTSWindowController")
  51. }
  52. deinit {
  53. DistributedNotificationCenter.default().removeObserver(self)
  54. NotificationCenter.default.removeObserver(self)
  55. }
  56. override func windowDidLoad() {
  57. super.windowDidLoad()
  58. setUpproperty()
  59. }
  60. func setUpproperty() {
  61. titleLabel.stringValue = KMLocalizedString("TTS")
  62. titleLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/1")
  63. titleLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-medium")
  64. previousButton.properties = ComponentButtonProperty(type: .text_gray, size: .s, onlyIcon: true, icon: NSImage(named: "previous_fill"))
  65. playButton.properties = ComponentButtonProperty(type: .text_gray, size: .s, onlyIcon: true, icon: NSImage(named: "pause_fill"))
  66. nextButton.properties = ComponentButtonProperty(type: .text_gray, size: .s, onlyIcon: true, icon: NSImage(named: "next_fill"))
  67. previousButton.setTarget(self, action: #selector(buttonItemClick_Forward(_:)))
  68. playButton.setTarget(self, action: #selector(buttonItemClick_Play(_:)))
  69. nextButton.setTarget(self, action: #selector(buttonItemClick_Next(_:)))
  70. languageLabel.stringValue = KMLocalizedString("Language:")
  71. languageLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("comp-form/colorText-label")
  72. languageLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-regular")
  73. languageSelect.properties = ComponentSelectProperties(size: .s,
  74. state: .normal,
  75. creatable: false,
  76. text: "English (Albert)",
  77. textUnit: "")
  78. languageSelect.delegate = self
  79. speedLabel.stringValue = KMLocalizedString("Speed:")
  80. speedLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("comp-form/colorText-label")
  81. speedLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-regular")
  82. speedSlider.properties = ComponentSliderProperty(size: .m, percent: 1)
  83. speedSlider.delegate = self
  84. speedInput.properties = ComponentInputNumberProperty(alignment: .left,
  85. size: .s,
  86. state: .normal,
  87. isError: false,
  88. showErrorInfo: false,
  89. isDisabled: false,
  90. showPrefix: false,
  91. showSuffix: false,
  92. minSize: 1,
  93. maxSize: 11,
  94. text:"1",
  95. valueType: .floatType)
  96. speedInput.delegate = self
  97. continueCheckbox.properties = ComponentCheckBoxProperty(size: .s,
  98. state: .normal,
  99. isDisabled: false,
  100. showhelp: false,
  101. text: KMLocalizedString("Continuous Reading"),
  102. checkboxType: .normal)
  103. let array = KMTTSManager.defalutManager.availableVoices()
  104. let currentVoicName = KMTTSManager.defalutManager.voice()
  105. var currentIndex = 0
  106. let menu = NSMenu()
  107. for voiceType: NSSpeechSynthesizer.VoiceName in array {
  108. let voiceDic = NSMutableDictionary()
  109. let voiceLocaleIdentifier = ( NSSpeechSynthesizer.attributes( forVoice: voiceType )[ NSSpeechSynthesizer.VoiceAttributeKey.localeIdentifier ] as! String )
  110. let name = self.switchLanguage(withCode: voiceLocaleIdentifier)
  111. voiceDic["voiceType"] = voiceType
  112. voiceDic["voiceName"] = name
  113. voiceArrays.add(voiceDic)
  114. }
  115. var opacityItems: [ComponentMenuitemProperty] = []
  116. voiceArrays = self.sortArray(voiceArrays)
  117. for i in 0..<voiceArrays.count {
  118. let voiceDic = voiceArrays[i] as! NSDictionary
  119. let voiceType = voiceDic.object(forKey: "voiceType") as! NSSpeechSynthesizer.VoiceName
  120. if currentVoicName == voiceType {
  121. currentIndex = i
  122. }
  123. let dic = KMTTSManager.defalutManager.attributesForVoice(voiceType) as NSDictionary
  124. let code = ( NSSpeechSynthesizer.attributes( forVoice: voiceType )[ NSSpeechSynthesizer.VoiceAttributeKey.localeIdentifier ] as! String )
  125. var languageStaring: String? = nil
  126. let voiceName = ( NSSpeechSynthesizer.attributes( forVoice: voiceType )[ NSSpeechSynthesizer.VoiceAttributeKey.name ] as! String )
  127. let name = self.switchLanguage(withCode: code)
  128. if voiceName.count > 0 {
  129. languageStaring = "\(name)(\(voiceName))"
  130. }
  131. if let value = languageStaring, value.count > 0 {
  132. let item = ComponentMenuitemProperty(type: .normal, text: value)
  133. opacityItems.append(item)
  134. }
  135. languageSelect.updateMenuItemsArr(opacityItems)
  136. }
  137. languageSelect.selectItemAtIndex(currentIndex)
  138. KMTTSManager.defalutManager.delegate = self
  139. self.updateViewColor()
  140. if KMTTSManager.defalutManager.isContinue {
  141. continueCheckbox.properties.checkboxType = .selected
  142. } else {
  143. continueCheckbox.properties.checkboxType = .normal
  144. }
  145. continueCheckbox.setTarget(self, action: #selector(buttonItemClick_Continue(_:)))
  146. continueCheckbox.reloadData()
  147. DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil)
  148. NotificationCenter.default.addObserver(self, selector: #selector(handlePageChangedNotification), name: NSNotification.Name.CPDFViewPageChanged, object: self.pdfView)
  149. }
  150. func updateViewColor() {
  151. }
  152. func sortArray(_ array: NSArray) -> NSMutableArray {
  153. let sortDesc = [NSSortDescriptor(key: "voiceName", ascending: true)]
  154. let sortedArr = array.sortedArray(using: sortDesc) as NSArray
  155. let tArray = NSMutableArray(array: sortedArr)
  156. return tArray
  157. }
  158. func windowShouldClose(_ sender: NSWindow) -> Bool {
  159. self.stopSpeaking()
  160. if let callBlack = closeWindowCallback {
  161. callBlack(true)
  162. }
  163. return true
  164. }
  165. override func showWindow(_ sender: Any?) {
  166. super.showWindow(sender)
  167. self.isChangePage = false
  168. if self.pdfView.canGoToNextPage() {
  169. nextButton.properties.isDisabled = false
  170. } else{
  171. nextButton.properties.isDisabled = true
  172. }
  173. nextButton.reloadData()
  174. if self.pdfView.canGoToPreviousPage() {
  175. previousButton.properties.isDisabled = false
  176. } else {
  177. previousButton.properties.isDisabled = true
  178. }
  179. previousButton.reloadData()
  180. speedSlider.reloadData()
  181. }
  182. func stopSpeaking() {
  183. if KMTTSManager.defalutManager.isSpeaking() || KMTTSManager.defalutManager.isPaused {
  184. self.isChangePage = true
  185. KMTTSManager.defalutManager.stopSpeaking()
  186. speedSlider.properties.isDisabled = false
  187. speedSlider.reloadData()
  188. speedInput.properties.isDisabled = false
  189. speedInput.reloadData()
  190. playButton.properties.icon = NSImage(named: "pause_fill")
  191. playButton.reloadData()
  192. self.pdfView.setHighlightedSelections([])
  193. }
  194. self.pdfSelection = nil
  195. self.pdfView = nil
  196. }
  197. func quikeStartSpeakingPDFPage(_ page: CPDFPage) {
  198. if KMTTSManager.defalutManager.isSpeaking() || KMTTSManager.defalutManager.isPaused {
  199. KMTTSManager.defalutManager.stopSpeaking()
  200. self.isChangePage = true
  201. }
  202. self.currentPageIndex = Int(self.pdfView.document?.index(for: page) ?? 0)
  203. self.startSpeakingPDFPage(page)
  204. }
  205. func startSpeakingPDFPage(_ page: CPDFPage) {
  206. let dex = self.languageSelect.indexOfSelect()
  207. if dex >= 0 && dex < self.voiceArrays.count {
  208. let dic: NSMutableDictionary = self.voiceArrays[dex] as! NSMutableDictionary
  209. if let voiceName = dic["voiceType"] {
  210. KMTTSManager.defalutManager.setVoice(voice: voiceName as! NSSpeechSynthesizer.VoiceName)
  211. }
  212. }
  213. KMTTSManager.defalutManager.rate = Float(self.speedSlider.properties.percent) * Float(standardSpeed)
  214. let isSuccess = KMTTSManager.defalutManager.startSpeakingPDFPage(page)
  215. if isSuccess {
  216. playButton.properties.icon = NSImage(named: "play_fill")
  217. playButton.toolTip = NSLocalizedString("Pause", comment: "")
  218. speedSlider.properties.isDisabled = true
  219. speedInput.properties.isDisabled = true
  220. } else {
  221. playButton.properties.icon = NSImage(named: "pause_fill")
  222. playButton.toolTip = NSLocalizedString("Play", comment: "")
  223. speedSlider.properties.isDisabled = false
  224. speedInput.properties.isDisabled = false
  225. }
  226. playButton.reloadData()
  227. speedSlider.reloadData()
  228. speedInput.reloadData()
  229. }
  230. func startSpeakingPDFSelection(_ selection: CPDFSelection) {
  231. if KMTTSManager.defalutManager.isSpeaking() || KMTTSManager.defalutManager.isPaused {
  232. KMTTSManager.defalutManager.stopSpeaking()
  233. self.isChangePage = true
  234. }
  235. self.pdfSelection = selection
  236. self.pdfView?.setCurrentSelection(nil, animate: false)
  237. let dex = self.languageSelect.indexOfSelect()
  238. if dex >= 0 && dex < self.voiceArrays.count {
  239. let dic: NSMutableDictionary = self.voiceArrays[dex] as! NSMutableDictionary
  240. if let voiceName = dic["voiceType"] as? NSSpeechSynthesizer.VoiceName {
  241. KMTTSManager.defalutManager.setVoice(voice: voiceName)
  242. }
  243. }
  244. KMTTSManager.defalutManager.rate = Float(self.speedSlider.properties.percent) * Float(standardSpeed)
  245. let isSuccess = KMTTSManager.defalutManager.startSpeakingPDFSelection(selection)
  246. if isSuccess {
  247. playButton.properties.icon = NSImage(named: "play_fill")
  248. playButton.toolTip = NSLocalizedString("Pause", comment: "")
  249. speedSlider.properties.isDisabled = true
  250. speedInput.properties.isDisabled = true
  251. } else {
  252. playButton.properties.icon = NSImage(named: "pause_fill")
  253. playButton.toolTip = NSLocalizedString("Play", comment: "")
  254. speedSlider.properties.isDisabled = false
  255. speedInput.properties.isDisabled = false
  256. }
  257. }
  258. //MARK: - Noti
  259. @objc func themeChanged(notification: NSNotification) {
  260. DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
  261. self.updateViewColor()
  262. }
  263. }
  264. @objc func handlePageChangedNotification(notification: NSNotification) {
  265. guard let PDFView = notification.object as? CPDFView else { return }
  266. if PDFView == self.pdfView {
  267. if self.pdfView.canGoToNextPage() {
  268. nextButton.properties.isDisabled = false
  269. } else{
  270. nextButton.properties.isDisabled = true
  271. }
  272. nextButton.reloadData()
  273. if self.pdfView.canGoToPreviousPage() {
  274. previousButton.properties.isDisabled = false
  275. } else {
  276. previousButton.properties.isDisabled = true
  277. }
  278. previousButton.reloadData()
  279. }
  280. }
  281. //MARK: - IBAction
  282. @objc func buttonItemClick_Next(_ sender: NSView) {
  283. if (KMTTSManager.defalutManager.isSpeaking()) {
  284. var currentPageNum = self.currentPageIndex;
  285. var page: CPDFPage?
  286. if (currentPageNum + 1 < self.pdfView.document.pageCount) {
  287. page = self.pdfView.document.page(at: UInt(currentPageNum+1))
  288. self.currentPageIndex = currentPageNum + 1;
  289. } else {
  290. page = self.pdfView.document.page(at: self.pdfView.document.pageCount - 1)
  291. self.currentPageIndex = Int(self.pdfView.document.pageCount - 1)
  292. }
  293. self.pdfView.go(to: page)
  294. self.isChangePage = true
  295. self.startSpeakingPDFPage(page!)
  296. }
  297. }
  298. @objc func buttonItemClick_Forward(_ sender: NSView) {
  299. if (KMTTSManager.defalutManager.isSpeaking()) {
  300. var currentPageNum = self.currentPageIndex;
  301. var page: CPDFPage?
  302. if (currentPageNum - 1 < 0) {
  303. page = self.pdfView.document.page(at: 0)
  304. self.currentPageIndex = 0;
  305. } else {
  306. page = self.pdfView.document.page(at: UInt(currentPageNum - 1))
  307. self.currentPageIndex = currentPageNum - 1
  308. }
  309. self.pdfView.go(to: page)
  310. self.isChangePage = true
  311. self.startSpeakingPDFPage(page!)
  312. }
  313. }
  314. @objc func buttonItemClick_Play(_ sender: NSView) {
  315. if (KMTTSManager.defalutManager.isPaused) {
  316. self.playButton.properties.icon = NSImage(named: "play_fill")
  317. self.playButton.toolTip = KMLocalizedString("Pause")
  318. self.speedSlider.properties.isDisabled = true
  319. self.speedInput.properties.isDisabled = true
  320. KMTTSManager.defalutManager.continueSpeaking()
  321. } else if (KMTTSManager.defalutManager.isSpeaking()) {
  322. self.isChangePage = true
  323. self.playButton.properties.icon = NSImage(named: "pause_fill")
  324. self.playButton.toolTip = KMLocalizedString("Play")
  325. self.speedSlider.properties.isDisabled = false
  326. self.speedInput.properties.isDisabled = false
  327. self.pdfView.setHighlightedSelection(nil, animated: false)
  328. KMTTSManager.defalutManager.pauseSpeaking()
  329. } else {
  330. if ((self.pdfSelection) != nil) {
  331. self.startSpeakingPDFSelection(self.pdfSelection!)
  332. } else {
  333. let page = self.pdfView.currentPage()
  334. self.currentPageIndex = self.pdfView.currentPageIndex
  335. if page != nil {
  336. self.startSpeakingPDFPage(page!)
  337. }
  338. }
  339. }
  340. }
  341. @objc func buttonItemClick_Continue(_ sender: NSView) {
  342. KMTTSManager.defalutManager.isContinue = !(KMTTSManager.defalutManager.isContinue)
  343. }
  344. func stepperItemClick_Speed(_ sender: NSButton) {
  345. // var rate = self.speedStepper.floatValue
  346. // let str = String(format: "%.1f", rate)
  347. // self.speedStepper.stringValue = str
  348. // self.speedTextField.stringValue = str
  349. // self.speedSlider.stringValue = str
  350. // rate = Float(standardSpeed) * rate
  351. // KMTTSManager.defalutManager.rate = rate
  352. }
  353. func sliderItemClick_Speed(_ sender: NSButton) {
  354. // var rate: CGFloat = CGFloat(self.speedSlider.floatValue)
  355. // let str = String(format: "%.1f", rate)
  356. // self.speedStepper.stringValue = str
  357. // self.speedTextField.stringValue = str
  358. // self.speedSlider.stringValue = str
  359. // rate = CGFloat(standardSpeed) * rate
  360. // KMTTSManager.defalutManager.rate = Float(rate)
  361. }
  362. func buttonItemClick_Language() {
  363. if KMTTSManager.defalutManager.isSpeaking() {
  364. self.isChangePage = true
  365. if let pdfSelection = self.pdfSelection {
  366. self.startSpeakingPDFSelection(pdfSelection)
  367. } else {
  368. let currentPageInd = self.currentPageIndex
  369. if currentPageInd < (self.pdfView.document.pageCount - 1) {
  370. let page = self.pdfView.document.page(at: UInt(currentPageInd))
  371. self.startSpeakingPDFPage(page!)
  372. }
  373. }
  374. }
  375. }
  376. //MARK: - MouseEvent
  377. override func mouseDown(with event: NSEvent) {
  378. super.mouseDown(with: event)
  379. self.window?.makeFirstResponder(self)
  380. }
  381. func switchLanguage(withCode code: String) -> String {
  382. var language = code
  383. if code == "ar_SA" {
  384. language = "Arabic (Saudi Arabia)"
  385. } else if code == "cs_CZ" {
  386. language = "Czech (Czech republic)"
  387. } else if code == "da_DK" {
  388. language = "Danish (Denmark)"
  389. } else if code == "de_DE" {
  390. language = "German (Germany)"
  391. } else if code == "el_GR" {
  392. language = "Greek (Greece)"
  393. } else if code == "en_AU" {
  394. language = "English (Australia)"
  395. } else if code == "en_GB" {
  396. language = "English (UK)"
  397. } else if code == "en_IE" {
  398. language = "English (Ireland)"
  399. } else if code == "en_US" {
  400. language = "English"
  401. } else if code == "en_ZA" {
  402. language = "English (South Africa)"
  403. } else if code == "es_ES" {
  404. language = "Spanish (Spain)"
  405. } else if code == "es_MX" {
  406. language = "Spanish (Mexico)"
  407. } else if code == "fi_FI" {
  408. language = "Finnish (Finland)"
  409. } else if code == "fr_CA" {
  410. language = "French (Canada)"
  411. } else if code == "fr_FR" {
  412. language = "French (France)"
  413. } else if code == "he_IL" {
  414. language = "Hebrew"
  415. } else if code == "hi_IN" {
  416. language = "Hindi (India)"
  417. } else if code == "hu_HU" {
  418. language = "Hungarian (Hungary)"
  419. } else if code == "id_ID" {
  420. language = "Indonesian (Indonesia)"
  421. } else if code == "it_IT" {
  422. language = "Italian (Italy)"
  423. } else if code == "ja_JP" {
  424. language = "日本語"
  425. } else if code == "ko_KR" {
  426. language = "Korean (South Korea)"
  427. } else if code == "nl_BE" {
  428. language = "Dutch (Belgium)"
  429. } else if code == "nl_NL" {
  430. language = "Dutch (Holland)"
  431. } else if code == "nb_NO" {
  432. language = "Norwegian (Norway)"
  433. } else if code == "pl_PL" {
  434. language = "Polish (Poland)"
  435. } else if code == "pt_BR" {
  436. language = "Portuguese (Brazil)"
  437. } else if code == "pt_PT" {
  438. language = "Portuguese (Portugal)"
  439. } else if code == "ro_RO" {
  440. language = "Romanian (Romania)"
  441. } else if code == "ru_RU" {
  442. language = "Russian (Russia)"
  443. } else if code == "sk_SK" {
  444. language = "Slovakia (Slovakia)"
  445. } else if code == "sv_SE" {
  446. language = "Swe (Sweden)"
  447. } else if code == "th_TH" {
  448. language = "Thai (Thailand)"
  449. } else if code == "tr_TR" {
  450. language = "Turkish (Turkey)"
  451. } else if code == "zh_CN" {
  452. language = "简体中文"
  453. } else if code == "zh_HK" {
  454. language = "繁體中文 (香港)"
  455. } else if code == "zh_TW" {
  456. language = "繁體中文 (台灣)"
  457. } else if code == "en_IN" {
  458. language = "English"
  459. }
  460. return language
  461. }
  462. }
  463. //MARK: KMTTSManagerDelegate
  464. extension KMTTSWindowController: KMTTSManagerDelegate {
  465. func ttsMananger(_ tts: KMTTSManager, willSpeak selection: CPDFSelection) {
  466. self.pdfView?.setHighlightedSelection(selection, animated: false)
  467. }
  468. func ttsManangerDidFinishSpeech(_ tts: KMTTSManager) -> Bool {
  469. var isFinish = true
  470. if self.pdfSelection != nil {
  471. self.pdfSelection = nil
  472. self.pdfView.setHighlightedSelections(nil)
  473. self.playButton.properties.icon = NSImage(named: "pause_fill")
  474. self.speedSlider.properties.isDisabled = false
  475. self.speedInput.properties.isDisabled = false
  476. self.playButton.toolTip = KMLocalizedString("Play")
  477. } else {
  478. if KMTTSManager.defalutManager.isContinue {
  479. if !isChangePage {
  480. if let pdfSelection = self.pdfSelection {
  481. self.pdfView.setHighlightedSelections(nil)
  482. self.playButton.properties.icon = NSImage(named: "pause_fill")
  483. self.speedSlider.properties.isDisabled = false
  484. self.speedInput.properties.isDisabled = false
  485. self.playButton.toolTip = KMLocalizedString("Play")
  486. } else {
  487. let currentPageIndex = self.currentPageIndex
  488. if currentPageIndex + 1 < self.pdfView.document.pageCount {
  489. let page = self.pdfView.document.page(at: UInt(currentPageIndex+1))
  490. self.currentPageIndex = currentPageIndex+1
  491. self.pdfView.go(to: page)
  492. self.startSpeakingPDFPage(page!)
  493. isFinish = false
  494. } else {
  495. self.pdfView.setHighlightedSelections(nil)
  496. self.playButton.properties.icon = NSImage(named: "pause_fill")
  497. self.speedSlider.properties.isDisabled = false
  498. self.speedInput.properties.isDisabled = false
  499. self.playButton.toolTip = KMLocalizedString("Play")
  500. }
  501. }
  502. }
  503. } else {
  504. if !isChangePage {
  505. self.speedSlider.properties.isDisabled = false
  506. self.speedInput.properties.isDisabled = false
  507. self.pdfView.setHighlightedSelections(nil)
  508. self.playButton.properties.icon = NSImage(named: "pause_fill")
  509. self.playButton.toolTip = KMLocalizedString("Play")
  510. }
  511. }
  512. if isChangePage {
  513. isChangePage = false
  514. }
  515. }
  516. return isFinish
  517. }
  518. func ttsManangerdidErrorSpeech(_ tts: KMTTSManager, message: String) {
  519. }
  520. }
  521. //MARK: NSTextFieldDelegate
  522. extension KMTTSWindowController: NSTextFieldDelegate {
  523. func controlTextDidEndEditing(_ obj: Notification) {
  524. // if let textField = obj.object as? NSTextField {
  525. // if textField == self.speedTextField {
  526. // var rate: Float = Float(textField.stringValue) ?? 0
  527. // if maxSpeed - rate < 0 {
  528. // rate = maxSpeed
  529. // } else if rate - minSpeed < 0 {
  530. // rate = minSpeed
  531. // }
  532. // self.speedStepper.stringValue = String(format: "%.1f", rate)
  533. // self.speedTextField.stringValue = String(format: "%.1f", rate)
  534. // self.speedSlider.stringValue = String(format: "%.1f", rate)
  535. // rate = standardSpeed * rate
  536. // KMTTSManager.defalutManager.rate = rate
  537. // }
  538. // }
  539. }
  540. }
  541. //MARK: ComponentSelectDelegate
  542. extension KMTTSWindowController: ComponentSelectDelegate {
  543. func componentSelectDidSelect(view: ComponentSelect?, menuItemProperty: ComponentMenuitemProperty?) {
  544. buttonItemClick_Language()
  545. }
  546. }
  547. //MARK: ComponentSliderDelegate
  548. extension KMTTSWindowController: ComponentSliderDelegate {
  549. func componentSliderDidUpdate(_ view: ComponentSlider) {
  550. let percent = view.properties.percent
  551. }
  552. }
  553. //MARK: ComponentInputNumberDelegate
  554. extension KMTTSWindowController: ComponentInputNumberDelegate {
  555. func componentInputNumberDidValueChanged(inputNumber: ComponentInputNumber?) {
  556. }
  557. }