|
| 1 | +# A part of NonVisual Desktop Access (NVDA) |
| 2 | +# Copyright (C) 2025 NV Access Limited, Noelia Ruiz Martínez |
| 3 | +# This file may be used under the terms of the GNU General Public License, version 2 or later, as modified by the NVDA license. |
| 4 | +# For full terms and any additional permissions, see the NVDA license file: https://github.com/nvaccess/nvda/blob/master/copying.txt |
| 5 | + |
| 6 | +import languageHandler |
| 7 | +import synthDriverHandler |
| 8 | +import config |
| 9 | +from config.configFlags import ReportNotSupportedLanguage |
| 10 | +from . import speech |
| 11 | +from .types import SpeechSequence |
| 12 | +from .commands import LangChangeCommand, BeepCommand |
| 13 | + |
| 14 | + |
| 15 | +def getSpeechSequenceWithLangs(speechSequence: SpeechSequence) -> SpeechSequence: |
| 16 | + """Get a speech sequence with the language description for each non default language of the read text. |
| 17 | +
|
| 18 | + :param speechSequence: The original speech sequence. |
| 19 | + :return: A speech sequence containing descriptions for each non default language, indicating if the language is not supported by the current synthesizer. |
| 20 | + """ |
| 21 | + if not shouldMakeLangChangeCommand(): |
| 22 | + return speechSequence |
| 23 | + curSynth = synthDriverHandler.getSynth() |
| 24 | + filteredSpeechSequence = list() |
| 25 | + for index, item in enumerate(speechSequence): |
| 26 | + if ( |
| 27 | + not isinstance(item, LangChangeCommand) |
| 28 | + or item.isDefault |
| 29 | + or getLangToReport(item.lang) == speech._speechState.lastReportedLanguage |
| 30 | + or index == len(speechSequence) - 1 |
| 31 | + ): |
| 32 | + filteredSpeechSequence.append(item) |
| 33 | + continue |
| 34 | + langDesc = languageHandler.getLanguageDescription(getLangToReport(item.lang)) |
| 35 | + if langDesc is None: |
| 36 | + langDesc = getLangToReport(item.lang) |
| 37 | + # Ensure that the language description is pronnounced in the default language. |
| 38 | + filteredSpeechSequence.append(LangChangeCommand(None)) |
| 39 | + if shouldReportNotSupported() and not curSynth.languageIsSupported(getLangToReport(item.lang)): |
| 40 | + if config.conf["speech"]["reportNotSupportedLanguage"] == ReportNotSupportedLanguage.SPEECH.value: |
| 41 | + filteredSpeechSequence.append( |
| 42 | + # Translators: Reported when the language of the text being read is not supported by the current synthesizer. |
| 43 | + pgettext("languageNotSupported", "{lang} (not supported)").format(lang=langDesc), |
| 44 | + ) |
| 45 | + else: # Beep |
| 46 | + filteredSpeechSequence.append(langDesc) |
| 47 | + filteredSpeechSequence.append(BeepCommand(500, 50)) |
| 48 | + elif config.conf["speech"]["reportLanguage"]: |
| 49 | + filteredSpeechSequence.append(langDesc) |
| 50 | + speech._speechState.lastReportedLanguage = getLangToReport(item.lang) |
| 51 | + filteredSpeechSequence.append(item) |
| 52 | + return filteredSpeechSequence |
| 53 | + |
| 54 | + |
| 55 | +def shouldSwitchVoice() -> bool: |
| 56 | + """Determines if the current synthesizer should switch to the voice corresponding to the language of the text been read.""" |
| 57 | + return config.conf["speech"]["autoLanguageSwitching"] |
| 58 | + |
| 59 | + |
| 60 | +def shouldMakeLangChangeCommand() -> bool: |
| 61 | + """Determines if NVDA should get the language of the text been read.""" |
| 62 | + return config.conf["speech"]["autoLanguageSwitching"] or config.conf["speech"]["reportLanguage"] |
| 63 | + |
| 64 | + |
| 65 | +def shouldReportNotSupported() -> bool: |
| 66 | + """Determines if NVDA should report if the language is not supported by the synthesizer.""" |
| 67 | + return ( |
| 68 | + config.conf["speech"]["autoLanguageSwitching"] |
| 69 | + and config.conf["speech"]["reportNotSupportedLanguage"] != ReportNotSupportedLanguage.OFF.value |
| 70 | + ) |
| 71 | + |
| 72 | + |
| 73 | +def getLangToReport(lang: str) -> str: |
| 74 | + """Gets the language to report by NVDA, according to speech settings. |
| 75 | +
|
| 76 | + :param lang: A language code corresponding to the text been read. |
| 77 | + :return: A language code corresponding to the language to be reported. |
| 78 | + """ |
| 79 | + if config.conf["speech"]["autoLanguageSwitching"] and not config.conf["speech"]["autoDialectSwitching"]: |
| 80 | + return lang.split("_")[0] |
| 81 | + return lang |
0 commit comments