From 6d0c2badf2ee860936149210f9ba3953affc852e Mon Sep 17 00:00:00 2001 From: Tseng Woody Date: Tue, 29 Dec 2020 19:57:11 +0800 Subject: [PATCH] WorldVoice v1.5 --- addon/doc/zh_CN/readme.md | 30 +- addon/doc/zh_HK/readme.md | 30 +- addon/doc/zh_TW/readme.md | 30 +- addon/generics/views.py | 13 +- .../globalPlugins/WorldVoiceXVED2/__init__.py | 43 ++- .../WorldVoiceXVED2/languageSettingsDialog.py | 149 --------- .../WorldVoiceXVED2/speechSettingsDialog.py | 146 +++++++-- addon/locale/zh_CN/LC_MESSAGES/nvda.po | 300 ++++++++++-------- addon/locale/zh_HK/LC_MESSAGES/nvda.po | 272 +++++++++------- addon/locale/zh_TW/LC_MESSAGES/nvda.po | 239 ++++++++------ .../synthDrivers/WorldVoiceXVED2/__init__.py | 6 +- .../synthDrivers/WorldVoiceXVED2/_veTypes.py | 3 +- buildVars.py | 4 +- readme.md | 26 +- 14 files changed, 696 insertions(+), 595 deletions(-) delete mode 100644 addon/globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py diff --git a/addon/doc/zh_CN/readme.md b/addon/doc/zh_CN/readme.md index 7869d3b..80bb396 100644 --- a/addon/doc/zh_CN/readme.md +++ b/addon/doc/zh_CN/readme.md @@ -21,18 +21,15 @@ WorldVoice 是依据 VE driver 为基础开发而成的 addon。运行于 NVDA 2 * NVDA+ctrl+S 选择 WorldVoice 语音合成器。 * NVDA+ctrl+V 有基本语音速度、音调、音量等基本设定,其中数字模式、中文空白间隔为 WorldVoice 多的客制设定。 - * 数字模式:有默认(VE 默认的读法)、自动数字(以默认语音并尽可能以数字报读)、中文数字(强制使用中文数字读法)、英文数字(强制使用英文数字读法) + * 数字读法:分为 2 个维度设定选项「数字语言」与「数字模式」,数字语言设定数字朗读时使用的地区语音、数字模式分为数值与数字两种 * 中文空白间隔:可设定中文间有空白时,欲停顿长度,数字愈小停顿愈短, 0 为不停顿。 -* WorldVoice -> 自动语言切换设定:可设定不同地区所使用的语音角色。 - * 先选择地区后语音列表会列出该地区可用的语音,选择后即完成该地区与语音的对应纪录。 - * 用 unicode 编码侦测文字语言勾选后,组件会根据读到的字符侦测地区。 - * 侦测语言时忽略数字和常见标点符号勾选后,数字与标点符号会认为是默认语音的地区文字。 -* WorldVoice -> 语音速度设定:可设定不同语音角色的朗读速度。 - * 同样先选择地区后语音列表会列出该地区可用的语音,再选择好语音后,便可于速度滑杆调整数值。 - * 速度是依不同语音区分,每个语音有各自不同的速度数值,而非依地区区分。 -* Unicode 设定:可定义字符的语言并依上下文或强制模式来判断字符语言,当「用 unicode 编码侦测文字语言」勾选后自动侦测的判断会加入此配置文件的规则。 - * 此功能即为了解决 NVDA 内部的 symbol 转换规则造成在自动切换语言下不朗读之问题 - * 例如在某些情形下「.」不读取时则可试着在规则中加入「.」的符号并选择语言与模式来使其正确读出 +* WorldVoice -> 语音设定:可设定不同地区所使用的语音角色、各别语音角色速度、音调、音量、自动语音切换设定。 + * 先选择地区后语音列表会列出该地区可用的语音角色,选择后即完成该地区与语音角色的对应纪录。 + * 当语音角色有选择时,下方速度、音调、音量滑杆会变为该语音角色的设定值。 + * 速度、音调、音量是依不同语音角色区分,每个语音角色有各自不同的速度数值,而非依地区区分。 + * 用 unicode 编码侦测文字语言勾选后,程序会根据读到的字符侦测地区。 + * 侦测语言时忽略数字、侦测语言时忽略常见标点符号勾选后,数字与标点符号会判定为默认语音的地区文字。 +* Unicode 设定:可定义字符的语言并依上下文或强制模式来判断字符语言,当「用 unicode 编码侦测文字语言」勾选后自动侦测的判断会加入此配置文件的规则,此功能可解决 NVDA 内部的 symbol 转换规则造成在自动切换语言下不朗读之问题。例如在某些情形下「.」不读取时则可试着在规则中加入「.」的符号并选择语言与模式来使其正确读出。 * WorldVoice -> 档案汇入:可汇入档案,可用于汇入核心包与语音包。 ## 更新版本日志 @@ -72,3 +69,14 @@ WorldVoice 是依据 VE driver 为基础开发而成的 addon。运行于 NVDA 2 * 修正 unicode rule 强制模式下后方文字侦测错误 * 修正初始值类型错误导致语音设定对话框无法显示 * 初始语音改优先使用默认语言之语音 + +### v1.5 + +* 数字读法分为 2 个设定选项「数字语言」与「数字模式」,将选项分为 2 维度以利选择 +* 忽略数字间逗点选项使数值报读更正确 +* 自动侦测语言功能当信任语音语言勾选时才使用不同解释档 +* 语音设定中的值调整按确认才生效按取消会回到设定前的值 +* 修正语音设定中当语音与默认语音相同时调整设定值后重启 NVDA 后回到设定前的值 +* 将自动语言切换设定与语音设定窗口合并 +* 地区与语音对应加入 no-select 用来取消对应 +* 支持快捷键弹出语音设定与 Unicode 设定 diff --git a/addon/doc/zh_HK/readme.md b/addon/doc/zh_HK/readme.md index 4ff26f9..2dca7a9 100644 --- a/addon/doc/zh_HK/readme.md +++ b/addon/doc/zh_HK/readme.md @@ -21,18 +21,15 @@ WorldVoice 是依據 VE driver 為基礎開發而成的 addon。運行於 NVDA 2 * NVDA+ctrl+S 選擇 WorldVoice 語音合成器。 * NVDA+ctrl+V 有基本語音速度、音調、音量等基本設定,其中數字模式、中文空白間隔為 WorldVoice 多的客製設定。 - * 數字模式:有預設(VE 預設的讀法)、自動數字(以預設語音並盡可能以數字報讀)、中文數字(強制使用中文數字讀法)、英文數字(強制使用英文數字讀法) + * 數字讀法:分為 2 個維度設定選項「數字語言」與「數字模式」,數字語言設定數字朗讀時使用的地區語音、數字模式分為數值與數字兩種 * 中文空白間隔:可設定中文間有空白時,欲停頓長度,數字愈小停頓愈短, 0 為不停頓。 -* WorldVoice -> 自動語言切換設定:可設定不同地區所使用的語音角色。 - * 先選擇地區後語音列表會列出該地區可用的語音,選擇後即完成該地區與語音的對應紀錄。 - * 用 unicode 編碼偵測文字語言勾選後,元件會根據讀到的字元偵測地區。 - * 偵測語言時忽略數字和常見標點符號勾選後,數字與標點符號會認為是預設語音的地區文字。 -* WorldVoice -> 語音速度設定:可設定不同語音角色的朗讀速度。 - * 同樣先選擇地區後語音列表會列出該地區可用的語音,再選擇好語音後,便可於速度滑桿調整數值。 - * 速度是依不同語音區分,每個語音有各自不同的速度數值,而非依地區區分。 -* Unicode 設定:可定義字元的語言並依上下文或強制模式來判斷字元語言,當「用 unicode 編碼偵測文字語言」勾選後自動偵測的判斷會加入此設定檔的規則。 - * 此功能即為了解決 NVDA 內部的 symbol 轉換規則造成在自動切換語言下不朗讀之問題 - * 例如在某些情形下「.」不讀取時則可試著在規則中加入「.」的符號並選擇語言與模式來使其正確讀出 +* WorldVoice -> 語音設定:可設定不同地區所使用的語音角色、各別語音角色速度、音調、音量、自動語音切換設定。 + * 先選擇地區後語音列表會列出該地區可用的語音角色,選擇後即完成該地區與語音角色的對應紀錄。 + * 當語音角色有選擇時,下方速度、音調、音量滑桿會變為該語音角色的設定值。 + * 速度、音調、音量是依不同語音角色區分,每個語音角色有各自不同的速度數值,而非依地區區分。 + * 用 unicode 編碼偵測文字語言勾選後,程式會根據讀到的字元偵測地區。 + * 偵測語言時忽略數字、偵測語言時忽略常見標點符號勾選後,數字與標點符號會判定為預設語音的地區文字。 +* Unicode 設定:可定義字元的語言並依上下文或強制模式來判斷字元語言,當「用 unicode 編碼偵測文字語言」勾選後自動偵測的判斷會加入此設定檔的規則,此功能可解決 NVDA 內部的 symbol 轉換規則造成在自動切換語言下不朗讀之問題。例如在某些情形下「.」不讀取時則可試著在規則中加入「.」的符號並選擇語言與模式來使其正確讀出。 * WorldVoice -> 檔案匯入:可匯入檔案,可用於匯入核心包與語音包。 ## 更新版本日誌 @@ -72,3 +69,14 @@ WorldVoice 是依據 VE driver 為基礎開發而成的 addon。運行於 NVDA 2 * 修正 unicode rule 強制模式下後方文字偵測錯誤 * 修正初始值類型錯誤導致語音設定對話框無法顯示 * 初始語音改優先使用預設語言之語音 + +### v1.5 + +* 數字讀法分為 2 個設定選項「數字語言」與「數字模式」,將選項分為 2 維度以利選擇 +* 忽略數字間逗點選項使數值報讀更正確 +* 自動偵測語言功能當信任語音語言勾選時才使用不同解釋檔 +* 語音設定中的值調整按確認才生效按取消會回到設定前的值 +* 修正語音設定中當語音與預設語音相同時調整設定值後重啟 NVDA 後回到設定前的值 +* 將自動語言切換設定與語音設定視窗合併 +* 地區與語音對應加入 no-select 用來取消對應 +* 支援快速鍵彈出語音設定與 Unicode 設定 diff --git a/addon/doc/zh_TW/readme.md b/addon/doc/zh_TW/readme.md index 4ff26f9..2dca7a9 100644 --- a/addon/doc/zh_TW/readme.md +++ b/addon/doc/zh_TW/readme.md @@ -21,18 +21,15 @@ WorldVoice 是依據 VE driver 為基礎開發而成的 addon。運行於 NVDA 2 * NVDA+ctrl+S 選擇 WorldVoice 語音合成器。 * NVDA+ctrl+V 有基本語音速度、音調、音量等基本設定,其中數字模式、中文空白間隔為 WorldVoice 多的客製設定。 - * 數字模式:有預設(VE 預設的讀法)、自動數字(以預設語音並盡可能以數字報讀)、中文數字(強制使用中文數字讀法)、英文數字(強制使用英文數字讀法) + * 數字讀法:分為 2 個維度設定選項「數字語言」與「數字模式」,數字語言設定數字朗讀時使用的地區語音、數字模式分為數值與數字兩種 * 中文空白間隔:可設定中文間有空白時,欲停頓長度,數字愈小停頓愈短, 0 為不停頓。 -* WorldVoice -> 自動語言切換設定:可設定不同地區所使用的語音角色。 - * 先選擇地區後語音列表會列出該地區可用的語音,選擇後即完成該地區與語音的對應紀錄。 - * 用 unicode 編碼偵測文字語言勾選後,元件會根據讀到的字元偵測地區。 - * 偵測語言時忽略數字和常見標點符號勾選後,數字與標點符號會認為是預設語音的地區文字。 -* WorldVoice -> 語音速度設定:可設定不同語音角色的朗讀速度。 - * 同樣先選擇地區後語音列表會列出該地區可用的語音,再選擇好語音後,便可於速度滑桿調整數值。 - * 速度是依不同語音區分,每個語音有各自不同的速度數值,而非依地區區分。 -* Unicode 設定:可定義字元的語言並依上下文或強制模式來判斷字元語言,當「用 unicode 編碼偵測文字語言」勾選後自動偵測的判斷會加入此設定檔的規則。 - * 此功能即為了解決 NVDA 內部的 symbol 轉換規則造成在自動切換語言下不朗讀之問題 - * 例如在某些情形下「.」不讀取時則可試著在規則中加入「.」的符號並選擇語言與模式來使其正確讀出 +* WorldVoice -> 語音設定:可設定不同地區所使用的語音角色、各別語音角色速度、音調、音量、自動語音切換設定。 + * 先選擇地區後語音列表會列出該地區可用的語音角色,選擇後即完成該地區與語音角色的對應紀錄。 + * 當語音角色有選擇時,下方速度、音調、音量滑桿會變為該語音角色的設定值。 + * 速度、音調、音量是依不同語音角色區分,每個語音角色有各自不同的速度數值,而非依地區區分。 + * 用 unicode 編碼偵測文字語言勾選後,程式會根據讀到的字元偵測地區。 + * 偵測語言時忽略數字、偵測語言時忽略常見標點符號勾選後,數字與標點符號會判定為預設語音的地區文字。 +* Unicode 設定:可定義字元的語言並依上下文或強制模式來判斷字元語言,當「用 unicode 編碼偵測文字語言」勾選後自動偵測的判斷會加入此設定檔的規則,此功能可解決 NVDA 內部的 symbol 轉換規則造成在自動切換語言下不朗讀之問題。例如在某些情形下「.」不讀取時則可試著在規則中加入「.」的符號並選擇語言與模式來使其正確讀出。 * WorldVoice -> 檔案匯入:可匯入檔案,可用於匯入核心包與語音包。 ## 更新版本日誌 @@ -72,3 +69,14 @@ WorldVoice 是依據 VE driver 為基礎開發而成的 addon。運行於 NVDA 2 * 修正 unicode rule 強制模式下後方文字偵測錯誤 * 修正初始值類型錯誤導致語音設定對話框無法顯示 * 初始語音改優先使用預設語言之語音 + +### v1.5 + +* 數字讀法分為 2 個設定選項「數字語言」與「數字模式」,將選項分為 2 維度以利選擇 +* 忽略數字間逗點選項使數值報讀更正確 +* 自動偵測語言功能當信任語音語言勾選時才使用不同解釋檔 +* 語音設定中的值調整按確認才生效按取消會回到設定前的值 +* 修正語音設定中當語音與預設語音相同時調整設定值後重啟 NVDA 後回到設定前的值 +* 將自動語言切換設定與語音設定視窗合併 +* 地區與語音對應加入 no-select 用來取消對應 +* 支援快速鍵彈出語音設定與 Unicode 設定 diff --git a/addon/generics/views.py b/addon/generics/views.py index c30761a..3a84e97 100644 --- a/addon/generics/views.py +++ b/addon/generics/views.py @@ -48,7 +48,12 @@ def __init__(self, parent): class SpeechSymbolsDialog(SettingsDialog): - helpId = "SymbolPronunciation" + _instance = None + + def __new__(cls, *args, **kwargs): + obj = super(SpeechSymbolsDialog, cls).__new__(cls, *args, **kwargs) + cls._instance = obj + return obj def __init__(self,parent): # Translators: This is the label for the unicode setting dialog. @@ -296,6 +301,10 @@ def OnRemoveClick(self, evt): self.symbolsList.sendListItemFocusedEvent(index) self.symbolsList.SetFocus() + def onCancel(self, event): + self.__class__._instance = None + super(SpeechSymbolsDialog, self).onCancel(event) + def onOk(self, evt): self.onSymbolEdited() self.editingItem = None @@ -315,6 +324,8 @@ def onOk(self, evt): _("unicode rule edited"),wx.OK|wx.CANCEL|wx.ICON_WARNING,self )==wx.OK: queueHandler.queueFunction(queueHandler.eventQueue,core.restart) + + self.__class__._instance = None super(SpeechSymbolsDialog, self).onOk(evt) def _refreshVisibleItems(self): diff --git a/addon/globalPlugins/WorldVoiceXVED2/__init__.py b/addon/globalPlugins/WorldVoiceXVED2/__init__.py index d69a36d..2a1f33f 100644 --- a/addon/globalPlugins/WorldVoiceXVED2/__init__.py +++ b/addon/globalPlugins/WorldVoiceXVED2/__init__.py @@ -16,12 +16,15 @@ import globalVars import gui from logHandler import log +from scriptHandler import script import speech +import ui -from .languageSettingsDialog import LanguageSettingsDialog from .speechSettingsDialog import SpeechSettingsDialog from generics.views import SpeechSymbolsDialog +ADDON_SUMMARY = addonHandler.getCodeAddon().manifest["summary"] +SpeechSettingsDialog = SpeechSettingsDialog() class GlobalPlugin(globalPluginHandler.GlobalPlugin): def __init__(self): @@ -45,12 +48,10 @@ def initialize(self): def createMenu(self): self.submenu_vocalizer = wx.Menu() if self.ve: - item = self.submenu_vocalizer.Append(wx.ID_ANY, _("Automatic &Language Switching Settings"), _("Configure which voice is to be used for each language.")) - gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU , lambda e : gui.mainFrame._popupSettingsDialog(LanguageSettingsDialog()), item) - item = self.submenu_vocalizer.Append(wx.ID_ANY, _("&Speech Settings"), _("Configure speech rate each voice.")) - gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU , lambda e : gui.mainFrame._popupSettingsDialog(SpeechSettingsDialog()), item) - item = self.submenu_vocalizer.Append(wx.ID_ANY, _("&Unicode Settings"), _("Configure unicode setting.")) - gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU , lambda e : gui.mainFrame._popupSettingsDialog(SpeechSymbolsDialog), item) + item = self.submenu_vocalizer.Append(wx.ID_ANY, _("&Speech Settings"), _("Speech Settings.")) + gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU, self.popup_SpeechSettingsDialog, item) + item = self.submenu_vocalizer.Append(wx.ID_ANY, _("&Unicode Settings"), _("Unicode Settings.")) + gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU , self.popup_SpeechSymbolsDialog, item) item = self.submenu_vocalizer.Append(wx.ID_ANY, _("&File Import"), _("Import File.")) gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU , self.onFileImport, item) self.submenu_item = gui.mainFrame.sysTrayIcon.menu.Insert(2, wx.ID_ANY, _("WorldVoice(VE)"), self.submenu_vocalizer) @@ -99,3 +100,31 @@ def terminate(self): self.removeMenu() except wx.PyDeadObjectError: pass + + def popup_SpeechSettingsDialog(self, event): + if SpeechSettingsDialog._instance is None: + gui.mainFrame._popupSettingsDialog(SpeechSettingsDialog) + else: + ui.message(_("SpeechSettingsDialog have already been opened")) + + def popup_SpeechSymbolsDialog(self, event): + if SpeechSymbolsDialog._instance is None: + gui.mainFrame._popupSettingsDialog(SpeechSymbolsDialog) + else: + ui.message(_("SpeechSymbolsDialog have already been opened")) + + @script( + gesture="kb:NVDA+alt+s", + description=_("popup SpeechSettingsDialog"), + category=ADDON_SUMMARY, + ) + def script_popup_SpeechSettingsDialog(self, gesture): + self.popup_SpeechSettingsDialog(None) + + @script( + gesture="kb:NVDA+alt+u", + description=_("popup SpeechSymbolsDialog"), + category=ADDON_SUMMARY, + ) + def script_popup_SpeechSymbolsDialog(self, gesture): + self.popup_SpeechSymbolsDialog(None) diff --git a/addon/globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py b/addon/globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py deleted file mode 100644 index ed306c3..0000000 --- a/addon/globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py +++ /dev/null @@ -1,149 +0,0 @@ -from collections import defaultdict - -import wx -import addonHandler -import gui -from gui import guiHelper -import speech - -addonHandler.initTranslation() - -def LanguageSettingsDialog(): - from synthDrivers.WorldVoiceXVED2 import _config, _core, VoiceManager - from synthDrivers.WorldVoiceXVED2 import languageDetection - class Dialog(gui.SettingsDialog): - title = _("Automatic Language Switching Settings") - - def __init__(self, parent): - _config.load() - self.ready = False - with _core.preOpen() as check: - if check: - self.ready = True - self._synthInstance = speech.getSynth() - if self._synthInstance.name == 'WorldVoiceXVED2': - self._manager = self._synthInstance._voiceManager - else: - self._manager = VoiceManager() - self._localeToVoices = self._manager.localeToVoicesMap - self.localesToNames = self._manager.localesToNamesMap - self._locales = sorted([l for l in self._localeToVoices if len(self._localeToVoices[l]) > 0]) - - self._dataToPercist = defaultdict(lambda: {}) - latinSet = set(languageDetection.ALL_LATIN) & set(l for l in self._locales if len(l) == 2) - self._latinLocales = sorted(list(latinSet)) - CJKSet = set(languageDetection.CJK) & set(l for l in self._locales if len(l) == 2) - self._CJKLocales = sorted(list(CJKSet)) - super(Dialog, self).__init__(parent) - - def makeSettings(self, sizer): - synthInfo = _('Your current speech synthesizer is not ready.') - if not self.ready: - infoLabel = wx.StaticText(self, label = synthInfo) - infoLabel.Wrap(self.GetSize()[0]) - sizer.Add(infoLabel) - return - - settingsSizerHelper = guiHelper.BoxSizerHelper(self, sizer=sizer) - - helpLabel = wx.StaticText(self, label=_("Select a language, and then configure the voice to be used:")) - helpLabel.Wrap(self.GetSize()[0]) - settingsSizerHelper.addItem(helpLabel) - - localeNames = [self.localesToNames[l] for l in self._locales] - self._localesChoice = settingsSizerHelper.addLabeledControl(_("Locale Name:"), wx.Choice, choices=localeNames) - self.Bind(wx.EVT_CHOICE, self.onLocaleChanged, self._localesChoice) - - self._voicesChoice = settingsSizerHelper.addLabeledControl(_("Voice Name:"), wx.Choice, choices=[]) - self.Bind(wx.EVT_CHOICE, self.onVoiceChange, self._voicesChoice) - - self._useUnicodeDetectionCheckBox = wx.CheckBox(self, - # Translators: Wether to use or not unicode characters based language detection. - label=_("Detect text language based on unicode characters")) - self._useUnicodeDetectionCheckBox.SetValue(_config.vocalizerConfig["autoLanguageSwitching"]["useUnicodeLanguageDetection"]) - settingsSizerHelper.addItem(self._useUnicodeDetectionCheckBox) - - self._afterSymbolDetectionCheckBox = wx.CheckBox(self, - # Translators: Wether to use or not after symbol detection. - label=_("Detect text language after symbol process")) - self._afterSymbolDetectionCheckBox.SetValue(_config.vocalizerConfig["autoLanguageSwitching"]["afterSymbolDetection"]) - settingsSizerHelper.addItem(self._afterSymbolDetectionCheckBox) - - self._ignoreNumbersCheckBox = wx.CheckBox(self, - # Translators: Either to ignore or not numbers when language detection is active - label=_("Ignore numbers when detecting text language")) - self._ignoreNumbersCheckBox.SetValue(_config.vocalizerConfig["autoLanguageSwitching"]["ignoreNumbersInLanguageDetection"]) - settingsSizerHelper.addItem(self._ignoreNumbersCheckBox) - - self._ignorePunctuationCheckBox = wx.CheckBox(self, - # Translators: Either to ignore or not ASCII punctuation when language detection is active - label=_("Ignore common punctuation when detecting text language")) - self._ignorePunctuationCheckBox.SetValue(_config.vocalizerConfig["autoLanguageSwitching"]["ignorePunctuationInLanguageDetection"]) - settingsSizerHelper.addItem(self._ignorePunctuationCheckBox) - - latinChoiceLocaleNames = [self.localesToNames[l] for l in self._latinLocales] - self._latinChoice = settingsSizerHelper.addLabeledControl(_("Language assumed for latin characters:"), wx.Choice, choices=latinChoiceLocaleNames) - latinLocale = _config.vocalizerConfig["autoLanguageSwitching"]["latinCharactersLanguage"] - try: - self._latinChoice.Select(self._latinLocales.index(latinLocale)) - except ValueError: - self._latinChoice.Select(0) - if not latinChoiceLocaleNames: - self._latinChoice.Disable() - - CJKChoiceLocaleNames = [self.localesToNames[l] for l in self._CJKLocales] - self._CJKChoice = settingsSizerHelper.addLabeledControl(_("Language assumed for CJK characters:"), wx.Choice, choices=CJKChoiceLocaleNames) - CJKLocale = _config.vocalizerConfig["autoLanguageSwitching"]["CJKCharactersLanguage"] - try: - self._CJKChoice.Select(self._CJKLocales.index(CJKLocale)) - except ValueError: - self._CJKChoice.Select(0) - if not CJKChoiceLocaleNames: - self._CJKChoice.Disable() - - def postInit(self): - if not self.ready: - return - self._updateVoicesSelection() - self._localesChoice.SetFocus() - - def _updateVoicesSelection(self): - localeIndex = self._localesChoice.GetCurrentSelection() - if localeIndex < 0: - self._voicesChoice.SetItems([]) - else: - locale = self._locales[localeIndex] - voices = sorted(self._localeToVoices[locale]) - self._voicesChoice.SetItems(voices) - if locale in _config.vocalizerConfig["autoLanguageSwitching"]: - voice = _config.vocalizerConfig["autoLanguageSwitching"][locale]["voice"] - if voice: - self._voicesChoice.Select(voices.index(voice)) - - def onLocaleChanged(self, event): - self._updateVoicesSelection() - - def onVoiceChange(self, event): - localeIndex = self._localesChoice.GetCurrentSelection() - if localeIndex >= 0: - locale = self._locales[localeIndex] - self._dataToPercist[locale]["voice"] = self._voicesChoice.GetStringSelection() - else: - self._dataToPercist[locale]["voice"] = None - - def onOk(self, event): - # Update Configuration - for locale in self._dataToPercist: - _config.vocalizerConfig["autoLanguageSwitching"][locale] = self._dataToPercist[locale] - - _config.vocalizerConfig["autoLanguageSwitching"]["useUnicodeLanguageDetection"] = self._useUnicodeDetectionCheckBox.GetValue() - _config.vocalizerConfig["autoLanguageSwitching"]["afterSymbolDetection"] = self._afterSymbolDetectionCheckBox.GetValue() - _config.vocalizerConfig["autoLanguageSwitching"]["ignoreNumbersInLanguageDetection"] = self._ignoreNumbersCheckBox.GetValue() - _config.vocalizerConfig["autoLanguageSwitching"]["ignorePunctuationInLanguageDetection"] = self._ignorePunctuationCheckBox.GetValue() - if self._latinChoice.IsEnabled(): - _config.vocalizerConfig["autoLanguageSwitching"]["latinCharactersLanguage"] = self._latinLocales[self._latinChoice.GetCurrentSelection()] - if self._CJKChoice.IsEnabled(): - _config.vocalizerConfig["autoLanguageSwitching"]["CJKCharactersLanguage"] = self._CJKLocales[self._CJKChoice.GetCurrentSelection()] - super(Dialog, self).onOk(event) - - return Dialog diff --git a/addon/globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py b/addon/globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py index 3ff2e01..4a2cb1a 100644 --- a/addon/globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py +++ b/addon/globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py @@ -1,19 +1,26 @@ from collections import defaultdict import wx -from autoSettingsUtils.utils import paramToPercent, percentToParam import addonHandler -import config import gui from gui import guiHelper import speech addonHandler.initTranslation() + def SpeechSettingsDialog(): from synthDrivers.WorldVoiceXVED2 import _config, _core, VoiceManager + from synthDrivers.WorldVoiceXVED2 import languageDetection class Dialog(gui.SettingsDialog): - title = _("Speech Rate Settings") + _instance = None + title = _("Speech Settings") + + def __new__(cls, *args, **kwargs): + obj = super(Dialog, cls).__new__(cls, *args, **kwargs) + cls._instance = obj + return obj + def __init__(self, parent): _config.load() self.ready = False @@ -24,11 +31,17 @@ def __init__(self, parent): if self._synthInstance.name == 'WorldVoiceXVED2': self._manager = self._synthInstance._voiceManager else: - _core.initialize(lambda x: None) self._manager = VoiceManager() + self.ready = False self._localeToVoices = self._manager.localeToVoicesMap self.localesToNames = self._manager.localesToNamesMap self._locales = sorted([l for l in self._localeToVoices if len(self._localeToVoices[l]) > 0]) + + self._dataToPercist = defaultdict(lambda: {}) + latinSet = set(languageDetection.ALL_LATIN) & set(l for l in self._locales if len(l) == 2) + self._latinLocales = sorted(list(latinSet)) + CJKSet = set(languageDetection.CJK) & set(l for l in self._locales if len(l) == 2) + self._CJKLocales = sorted(list(CJKSet)) super(Dialog, self).__init__(parent) def makeSettings(self, sizer): @@ -54,19 +67,61 @@ def makeSettings(self, sizer): self._rateSlider = settingsSizerHelper.addLabeledControl(_("&Rate:"), wx.Slider, value = 50, minValue = 0, maxValue = 100, style = wx.SL_HORIZONTAL) self.Bind(wx.EVT_SLIDER, self.onSpeechRateSliderScroll, self._rateSlider) - self._pitchSlider = settingsSizerHelper.addLabeledControl(_("&Pitch:"), wx.Slider, value = 50, minValue = 0, maxValue = 100, style = wx.SL_HORIZONTAL) self.Bind(wx.EVT_SLIDER, self.onPitchSliderScroll, self._pitchSlider) - self._volumeSlider = settingsSizerHelper.addLabeledControl(_("V&olume:"), wx.Slider, value = 50, minValue = 0, maxValue = 100, style = wx.SL_HORIZONTAL) self.Bind(wx.EVT_SLIDER, self.onVolumeSliderScroll, self._volumeSlider) + self.sliderDisable() + + self._useUnicodeDetectionCheckBox = wx.CheckBox(self, + # Translators: Wether to use or not unicode characters based language detection. + label=_("Detect text language based on unicode characters")) + self._useUnicodeDetectionCheckBox.SetValue(_config.vocalizerConfig["autoLanguageSwitching"]["useUnicodeLanguageDetection"]) + settingsSizerHelper.addItem(self._useUnicodeDetectionCheckBox) + + self._afterSymbolDetectionCheckBox = wx.CheckBox(self, + # Translators: Wether to use or not after symbol detection. + label=_("Detect text language after symbol process")) + self._afterSymbolDetectionCheckBox.SetValue(_config.vocalizerConfig["autoLanguageSwitching"]["afterSymbolDetection"]) + settingsSizerHelper.addItem(self._afterSymbolDetectionCheckBox) + + self._ignoreNumbersCheckBox = wx.CheckBox(self, + # Translators: Either to ignore or not numbers when language detection is active + label=_("Ignore numbers when detecting text language")) + self._ignoreNumbersCheckBox.SetValue(_config.vocalizerConfig["autoLanguageSwitching"]["ignoreNumbersInLanguageDetection"]) + settingsSizerHelper.addItem(self._ignoreNumbersCheckBox) + + self._ignorePunctuationCheckBox = wx.CheckBox(self, + # Translators: Either to ignore or not ASCII punctuation when language detection is active + label=_("Ignore common punctuation when detecting text language")) + self._ignorePunctuationCheckBox.SetValue(_config.vocalizerConfig["autoLanguageSwitching"]["ignorePunctuationInLanguageDetection"]) + settingsSizerHelper.addItem(self._ignorePunctuationCheckBox) + + latinChoiceLocaleNames = [self.localesToNames[l] for l in self._latinLocales] + self._latinChoice = settingsSizerHelper.addLabeledControl(_("Language assumed for latin characters:"), wx.Choice, choices=latinChoiceLocaleNames) + latinLocale = _config.vocalizerConfig["autoLanguageSwitching"]["latinCharactersLanguage"] + try: + self._latinChoice.Select(self._latinLocales.index(latinLocale)) + except ValueError: + self._latinChoice.Select(0) + if not latinChoiceLocaleNames: + self._latinChoice.Disable() + + CJKChoiceLocaleNames = [self.localesToNames[l] for l in self._CJKLocales] + self._CJKChoice = settingsSizerHelper.addLabeledControl(_("Language assumed for CJK characters:"), wx.Choice, choices=CJKChoiceLocaleNames) + CJKLocale = _config.vocalizerConfig["autoLanguageSwitching"]["CJKCharactersLanguage"] + try: + self._CJKChoice.Select(self._CJKLocales.index(CJKLocale)) + except ValueError: + self._CJKChoice.Select(0) + if not CJKChoiceLocaleNames: + self._CJKChoice.Disable() def postInit(self): if not self.ready: return self._updateVoicesSelection() self._localesChoice.SetFocus() - self.sliderDisable() def _updateVoicesSelection(self): localeIndex = self._localesChoice.GetCurrentSelection() @@ -74,7 +129,7 @@ def _updateVoicesSelection(self): self._voicesChoice.SetItems([]) else: locale = self._locales[localeIndex] - voices = ["default"] + sorted(self._localeToVoices[locale]) + voices = ["no-select"] + sorted(self._localeToVoices[locale]) self._voicesChoice.SetItems(voices) if locale in _config.vocalizerConfig["autoLanguageSwitching"]: voice = _config.vocalizerConfig["autoLanguageSwitching"][locale]["voice"] @@ -85,6 +140,26 @@ def _updateVoicesSelection(self): self._voicesChoice.Select(0) self.onVoiceChange(None) + def onLocaleChanged(self, event): + self._updateVoicesSelection() + + def onVoiceChange(self, event): + localeIndex = self._localesChoice.GetCurrentSelection() + locale = self._locales[localeIndex] + voiceName = self._voicesChoice.GetStringSelection() + if voiceName != "no-select": + self._dataToPercist[locale]["voice"] = self._voicesChoice.GetStringSelection() + + self.sliderEnable() + voiceInstance = self._manager.getVoiceInstance(voiceName) + + self._rateSlider.SetValue(voiceInstance.rate) + self._pitchSlider.SetValue(voiceInstance.pitch) + self._volumeSlider.SetValue(voiceInstance.volume) + else: + self._dataToPercist[locale]["voice"] = "no-select" + self.sliderDisable() + def sliderEnable(self): self._rateSlider.Enable() self._pitchSlider.Enable() @@ -95,21 +170,6 @@ def sliderDisable(self): self._pitchSlider.Disable() self._volumeSlider.Disable() - def onLocaleChanged(self, event): - self._updateVoicesSelection() - - def onVoiceChange(self, event): - voiceName = self._voicesChoice.GetStringSelection() - if voiceName == "default": - self.sliderDisable() - return - self.sliderEnable() - voiceInstance = self._manager.getVoiceInstance(voiceName) - - self._rateSlider.SetValue(voiceInstance.rate) - self._pitchSlider.SetValue(voiceInstance.pitch) - self._volumeSlider.SetValue(voiceInstance.volume) - def onSpeechRateSliderScroll(self, event): voiceName = self._voicesChoice.GetStringSelection() if voiceName == '': @@ -132,11 +192,43 @@ def onVolumeSliderScroll(self, event): voiceInstance.volume = self._volumeSlider.GetValue() def onCancel(self, event): + if not self.ready: + self.__class__._instance = None + super(Dialog, self).onCancel(event) + return + for instance in self._manager._instanceCache.values(): instance.rollback() - return super(Dialog, self).onCancel(event) + + self.__class__._instance = None + super(Dialog, self).onCancel(event) def onOk(self, event): + if not self.ready: + self.__class__._instance = None + super(Dialog, self).onOk(event) + return + + # Update Configuration + for locale in self._dataToPercist: + if self._dataToPercist[locale]["voice"] != "no-select": + _config.vocalizerConfig["autoLanguageSwitching"][locale] = self._dataToPercist[locale] + else: + try: + del _config.vocalizerConfig["autoLanguageSwitching"][locale] + except BaseException as e: + pass + + _config.vocalizerConfig["autoLanguageSwitching"]["useUnicodeLanguageDetection"] = self._useUnicodeDetectionCheckBox.GetValue() + _config.vocalizerConfig["autoLanguageSwitching"]["afterSymbolDetection"] = self._afterSymbolDetectionCheckBox.GetValue() + _config.vocalizerConfig["autoLanguageSwitching"]["ignoreNumbersInLanguageDetection"] = self._ignoreNumbersCheckBox.GetValue() + _config.vocalizerConfig["autoLanguageSwitching"]["ignorePunctuationInLanguageDetection"] = self._ignorePunctuationCheckBox.GetValue() + if self._latinChoice.IsEnabled(): + _config.vocalizerConfig["autoLanguageSwitching"]["latinCharactersLanguage"] = self._latinLocales[self._latinChoice.GetCurrentSelection()] + if self._CJKChoice.IsEnabled(): + _config.vocalizerConfig["autoLanguageSwitching"]["CJKCharactersLanguage"] = self._CJKLocales[self._CJKChoice.GetCurrentSelection()] + + import config for instance in self._manager._instanceCache.values(): instance.commit() try: @@ -144,11 +236,13 @@ def onOk(self, event): config.conf["speech"][self._synthInstance.name]["rate"] = instance.rate config.conf["speech"][self._synthInstance.name]["pitch"] = instance.pitch config.conf["speech"][self._synthInstance.name]["volume"] = instance.volume - except: + except BaseException as e: pass if not self._synthInstance.name == 'WorldVoiceXVED2': self._manager.close() - return super(Dialog, self).onOk(event) + + self.__class__._instance = None + super(Dialog, self).onOk(event) return Dialog diff --git a/addon/locale/zh_CN/LC_MESSAGES/nvda.po b/addon/locale/zh_CN/LC_MESSAGES/nvda.po index df5daf8..f015b7d 100644 --- a/addon/locale/zh_CN/LC_MESSAGES/nvda.po +++ b/addon/locale/zh_CN/LC_MESSAGES/nvda.po @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: 'WorldVoiceXVE' '1.4'\n" +"Project-Id-Version: 'WorldVoiceXVE' '1.5'\n" "Report-Msgid-Bugs-To: 'nvda-translations@groups.io'\n" -"POT-Creation-Date: 2020-12-07 20:21+0800\n" -"PO-Revision-Date: 2020-12-07 20:30+0800\n" +"POT-Creation-Date: 2020-12-28 20:55+0800\n" +"PO-Revision-Date: 2020-12-28 21:02+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" @@ -22,11 +22,11 @@ msgstr "" #: generics/contextHelp.py:34 msgid "No help available here." -msgstr "无可用说明。" +msgstr "无可用说明" #: generics/contextHelp.py:41 msgid "No user guide found." -msgstr "无找到用户指南。" +msgstr "未找到用户指南。" #: generics/models.py:22 msgid "context" @@ -38,254 +38,282 @@ msgstr "强制" #: generics/views.py:33 msgid "Add Symbol" -msgstr "新增符号" +msgstr "添加符号" #: generics/views.py:38 msgid "&Symbol:" msgstr "符号(&S)" -#: generics/views.py:56 +#: generics/views.py:61 msgid "Unicode Setting" -msgstr "Unicode 设定" +msgstr "Unicode 设置" -#: generics/views.py:80 +#: generics/views.py:85 msgid "&Symbols" msgstr "符号(&S)" -#: generics/views.py:90 +#: generics/views.py:95 msgid "Unicode" msgstr "Unicode" -#: generics/views.py:92 +#: generics/views.py:97 msgid "Replacement" msgstr "替换文字" -#: generics/views.py:94 +#: generics/views.py:99 msgid "Language" msgstr "语言" -#: generics/views.py:97 +#: generics/views.py:102 msgid "Mode" msgstr "模式" -#: generics/views.py:101 +#: generics/views.py:106 msgid "Change selected symbol" -msgstr "变更选择的符号" +msgstr "更改选择的符号" -#: generics/views.py:123 +#: generics/views.py:128 msgid "&Replacement" msgstr "替换文字(&R)" -#: generics/views.py:131 +#: generics/views.py:136 msgid "&language" msgstr "语言(&L)" -#: generics/views.py:136 +#: generics/views.py:141 msgid "&Detect language mode" -msgstr "侦测语言模式" +msgstr "语言检测模式" -#: generics/views.py:143 +#: generics/views.py:148 msgid "&Add" -msgstr "新增(&A)" +msgstr "添加(&A)" -#: generics/views.py:146 +#: generics/views.py:151 msgid "Re&move" msgstr "移除(&R)" -#: generics/views.py:251 +#: generics/views.py:256 #, python-format msgid "Symbol \"%s\" is already present." -msgstr "符号 \"%s\" 已存在。" +msgstr "符号 \"%s\" 已存在" -#: generics/views.py:252 +#: generics/views.py:257 msgid "Error" msgstr "错误" -#: generics/views.py:313 +#: generics/views.py:322 msgid "" "For the edited unicode rule to apply, NVDA must be restarted. Press enter to " "restart NVDA, or cancel to exit at a later time." -msgstr "" -"为了让已编辑的 unicode 生效, NVDA 必需重新启动。您要立即重新启动 NVDA 吗?" +msgstr "为了让已编辑的 Unicode 生效,必须重新启动 NVDA,您要立即重新启动吗?" -#: generics/views.py:315 +#: generics/views.py:324 msgid "unicode rule edited" msgstr "unicode 规则已编辑" -#: globalPlugins/WorldVoiceXVED2/__init__.py:48 -msgid "Automatic &Language Switching Settings" -msgstr "自动语言切换设定(&L)" - -#: globalPlugins/WorldVoiceXVED2/__init__.py:48 -msgid "Configure which voice is to be used for each language." -msgstr "设定各别语言的语音。" - -#: globalPlugins/WorldVoiceXVED2/__init__.py:50 +#: globalPlugins/WorldVoiceXVED2/__init__.py:51 msgid "&Speech Settings" msgstr "语音设置(&S)" -#: globalPlugins/WorldVoiceXVED2/__init__.py:50 -msgid "Configure speech rate each voice." -msgstr "设定各别语音的语速。" +#: globalPlugins/WorldVoiceXVED2/__init__.py:51 +msgid "Speech Settings." +msgstr "语音设置(&S)" -#: globalPlugins/WorldVoiceXVED2/__init__.py:52 +#: globalPlugins/WorldVoiceXVED2/__init__.py:53 msgid "&Unicode Settings" msgstr "Unicode 设置(&U)" -#: globalPlugins/WorldVoiceXVED2/__init__.py:52 -msgid "Configure unicode setting." -msgstr "设定 Unicode 设定。" +#: globalPlugins/WorldVoiceXVED2/__init__.py:53 +msgid "Unicode Settings." +msgstr "Unicode 设置" -#: globalPlugins/WorldVoiceXVED2/__init__.py:54 +#: globalPlugins/WorldVoiceXVED2/__init__.py:55 msgid "&File Import" -msgstr "档案汇入(&F)" +msgstr "导入文件(&F)" -#: globalPlugins/WorldVoiceXVED2/__init__.py:54 +#: globalPlugins/WorldVoiceXVED2/__init__.py:55 msgid "Import File." -msgstr "汇入档案..." +msgstr "导入文件" -#: globalPlugins/WorldVoiceXVED2/__init__.py:56 +#: globalPlugins/WorldVoiceXVED2/__init__.py:57 msgid "WorldVoice(VE)" msgstr "WorldVoice(VE)" -#: globalPlugins/WorldVoiceXVED2/__init__.py:67 +#: globalPlugins/WorldVoiceXVED2/__init__.py:68 msgid "Import file..." -msgstr "汇入档案..." +msgstr "导入文件" -#: globalPlugins/WorldVoiceXVED2/__init__.py:79 +#: globalPlugins/WorldVoiceXVED2/__init__.py:80 msgid "Import fail" -msgstr "汇入失败" +msgstr "导入失败" -#: globalPlugins/WorldVoiceXVED2/__init__.py:80 -#: globalPlugins/WorldVoiceXVED2/__init__.py:85 +#: globalPlugins/WorldVoiceXVED2/__init__.py:81 +#: globalPlugins/WorldVoiceXVED2/__init__.py:86 msgid "Import File" -msgstr "汇入档案" +msgstr "导入文件" -#: globalPlugins/WorldVoiceXVED2/__init__.py:84 +#: globalPlugins/WorldVoiceXVED2/__init__.py:85 msgid "" "For the new file to import, NVDA must be restarted. Are you want to restart " "NVDA now ?" -msgstr "为了让新档案汇入, NVDA 必需重新启动。您要立即重新启动 NVDA 吗?" +msgstr "为了使导入的文件生效, NVDA 必需重新启动。您要立即重新启动吗?" -#: globalPlugins/WorldVoiceXVED2/__init__.py:92 +#: globalPlugins/WorldVoiceXVED2/__init__.py:93 msgid "" "You have no core(driver 2) installed.\n" "Do you want to install the core(driver 2) now?" msgstr "" -"您尚未安装核心(driver 2)。\n" -"您是否要现在进行核心安装?" +"您尚未安装(driver 2)核心。\n" +"您是否要现在安装?" -#: globalPlugins/WorldVoiceXVED2/__init__.py:94 +#: globalPlugins/WorldVoiceXVED2/__init__.py:95 msgid "No core installed." -msgstr "尚未安装核心。" +msgstr "尚未安装核心" + +#: globalPlugins/WorldVoiceXVED2/__init__.py:108 +msgid "SpeechSettingsDialog have already been opened" +msgstr "语音设置(&S)對話框已開啟" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:15 -msgid "Automatic Language Switching Settings" -msgstr "自动语言切换设定" +#: globalPlugins/WorldVoiceXVED2/__init__.py:114 +msgid "SpeechSymbolsDialog have already been opened" +msgstr "Unicode 設定對話框已開啟" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:40 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:34 +#: globalPlugins/WorldVoiceXVED2/__init__.py:118 +msgid "popup SpeechSettingsDialog" +msgstr "弹出语音设置对话框(&S)" + +#: globalPlugins/WorldVoiceXVED2/__init__.py:126 +msgid "popup SpeechSymbolsDialog" +msgstr "弹出 标点符号读音对话框" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:17 +msgid "Speech Settings" +msgstr "语音设置" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:48 msgid "Your current speech synthesizer is not ready." -msgstr "你当前的语音合程器尚未就绪。" +msgstr "当前语音合成器未就绪" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:49 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:43 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:57 msgid "Select a language, and then configure the voice to be used:" -msgstr "选择一个地区,并为其设定一个语音:" +msgstr "选择一个地区,并为该地区选择一个语音角色:" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:54 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:48 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:62 msgid "Locale Name:" -msgstr "地区名称:" +msgstr "地区名称:" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:57 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:51 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:65 msgid "Voice Name:" -msgstr "语音名称:" +msgstr "语音名称" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:62 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:68 +msgid "&Rate:" +msgstr "语速(&R)" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:70 +msgid "&Pitch:" +msgstr "音调(&P)" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:72 +msgid "V&olume:" +msgstr "音量(&O)" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:78 msgid "Detect text language based on unicode characters" -msgstr "用 unicode 编码侦测文字语言" +msgstr "用 unicode 编码检测文本语言" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:68 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:84 msgid "Detect text language after symbol process" -msgstr "在符号处理后侦测文字语言" +msgstr "在符号处理后检测文本语言" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:74 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:90 msgid "Ignore numbers when detecting text language" -msgstr "侦测语言时忽略数字" +msgstr "检测语言时忽略数字" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:80 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:96 msgid "Ignore common punctuation when detecting text language" -msgstr "侦测语言时忽略数字和常见标点符号" +msgstr "检测语言时忽略数字和常见的标点符号" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:85 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:101 msgid "Language assumed for latin characters:" -msgstr "拉丁字符假设的语言:" +msgstr "拉丁字符对应的语言" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:95 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:111 msgid "Language assumed for CJK characters:" -msgstr "中日韩字符假设的语言:" - -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:15 -msgid "Speech Rate Settings" -msgstr "语音速度设定" - -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:54 -msgid "&Rate:" -msgstr "速度(&R)" - -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:57 -msgid "&Pitch:" -msgstr "音调(&P)" - -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:60 -msgid "V&olume:" -msgstr "音量(&O)" +msgstr "中日韩字符对应的语言:" -#: synthDrivers/WorldVoiceXVED2/__init__.py:70 -msgid "&Number Mode" -msgstr "数字模式(&N)" +#: synthDrivers/WorldVoiceXVED2/__init__.py:71 +msgid "Number &Language" +msgstr "数字语言(&M)" -#: synthDrivers/WorldVoiceXVED2/__init__.py:74 +#: synthDrivers/WorldVoiceXVED2/__init__.py:75 +#: synthDrivers/WorldVoiceXVED2/__init__.py:84 msgid "Number Mode" msgstr "数字模式" -#: synthDrivers/WorldVoiceXVED2/__init__.py:79 -msgid "&Chinese Space Break" -msgstr "中文空白间隔(&C)" +#: synthDrivers/WorldVoiceXVED2/__init__.py:80 +msgid "Number &Mode" +msgstr "数字模式(&M)" -#: synthDrivers/WorldVoiceXVED2/__init__.py:84 -msgid "Chinese Space Break" -msgstr "中文空白间隔" +#: synthDrivers/WorldVoiceXVED2/__init__.py:89 +msgid "Pause time when encountering spaces between Chinese" +msgstr "中文空格暂停时间" + +#: synthDrivers/WorldVoiceXVED2/__init__.py:95 +msgid "Ignore comma between number" +msgstr "忽略数字中的逗号" -#: synthDrivers/WorldVoiceXVED2/__init__.py:88 +#: synthDrivers/WorldVoiceXVED2/__init__.py:100 msgid "Ignore language information of document" -msgstr "忽略文件中的语言信息" +msgstr "忽略文档中的语言信息" -#: synthDrivers/WorldVoiceXVED2/__init__.py:328 +#: synthDrivers/WorldVoiceXVED2/__init__.py:354 msgid "default" -msgstr "预设" +msgstr "默认" + +#: synthDrivers/WorldVoiceXVED2/__init__.py:370 +msgid "value" +msgstr "数值" + +#: synthDrivers/WorldVoiceXVED2/__init__.py:371 +msgid "number" +msgstr "数字" + +#~ msgid "Automatic &Language Switching Settings" +#~ msgstr "自动语言切换设定(&L)" + +#~ msgid "Configure which voice is to be used for each language." +#~ msgstr "设定各别语言的语音。" + +#~ msgid "Configure speech rate each voice." +#~ msgstr "设定各别语音的语速。" + +#~ msgid "Configure unicode setting." +#~ msgstr "设定 Unicode 设定。" + +#~ msgid "Automatic Language Switching Settings" +#~ msgstr "自动语言切换设定" + +#~ msgid "Speech Rate Settings" +#~ msgstr "语音速度设定" + +#~ msgid "&Number Mode" +#~ msgstr "数字模式(&N)" -#: synthDrivers/WorldVoiceXVED2/__init__.py:329 -msgid "automatic number" -msgstr "自动数字" +#~ msgid "&Chinese Space Break" +#~ msgstr "中文空白间隔(&C)" -#: synthDrivers/WorldVoiceXVED2/__init__.py:330 -msgid "chinese number" -msgstr "中文数字" +#~ msgid "Chinese Space Break" +#~ msgstr "中文空白间隔" -#: synthDrivers/WorldVoiceXVED2/__init__.py:331 -msgid "english number" -msgstr "英文数字" +#~ msgid "automatic number" +#~ msgstr "自动数字" -#: synthDrivers/WorldVoiceXVED2/__init__.py:333 -msgid "number " -msgstr "数字 " +#~ msgid "chinese number" +#~ msgstr "中文数字" -#: synthDrivers/WorldVoiceXVED2/__init__.py:335 -msgid "value " -msgstr "数值 " +#~ msgid "english number" +#~ msgstr "英文数字" #~ msgid "" #~ "You have no core installed.\n" diff --git a/addon/locale/zh_HK/LC_MESSAGES/nvda.po b/addon/locale/zh_HK/LC_MESSAGES/nvda.po index fce39ef..44301b2 100644 --- a/addon/locale/zh_HK/LC_MESSAGES/nvda.po +++ b/addon/locale/zh_HK/LC_MESSAGES/nvda.po @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: 'WorldVoiceXVE' '1.4'\n" +"Project-Id-Version: 'WorldVoice' '1.5'\n" "Report-Msgid-Bugs-To: 'nvda-translations@groups.io'\n" -"POT-Creation-Date: 2020-12-07 20:34+0800\n" -"PO-Revision-Date: 2020-12-07 20:43+0800\n" +"POT-Creation-Date: 2020-12-28 20:55+0800\n" +"PO-Revision-Date: 2020-12-28 21:00+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_HK\n" @@ -30,7 +30,7 @@ msgstr "無找到使用者指南。" #: generics/models.py:22 msgid "context" -msgstr "context" +msgstr "上下文" #: generics/models.py:23 msgid "force" @@ -44,130 +44,122 @@ msgstr "新增符號" msgid "&Symbol:" msgstr "符號(&S)" -#: generics/views.py:56 +#: generics/views.py:61 msgid "Unicode Setting" msgstr "Unicode 設定" -#: generics/views.py:80 +#: generics/views.py:85 msgid "&Symbols" msgstr "符號(&S)" -#: generics/views.py:90 +#: generics/views.py:95 msgid "Unicode" msgstr "Unicode" -#: generics/views.py:92 +#: generics/views.py:97 msgid "Replacement" msgstr "替代文字" -#: generics/views.py:94 +#: generics/views.py:99 msgid "Language" msgstr "語言" -#: generics/views.py:97 +#: generics/views.py:102 msgid "Mode" msgstr "模式" -#: generics/views.py:101 +#: generics/views.py:106 msgid "Change selected symbol" msgstr "變更選擇的符號" -#: generics/views.py:123 +#: generics/views.py:128 msgid "&Replacement" msgstr "替代文字(&R)" -#: generics/views.py:131 +#: generics/views.py:136 msgid "&language" -msgstr "&language" +msgstr "語言(&l)" -#: generics/views.py:136 +#: generics/views.py:141 msgid "&Detect language mode" -msgstr "&Detect language mode" +msgstr "偵測語言模式(&D)" -#: generics/views.py:143 +#: generics/views.py:148 msgid "&Add" msgstr "新增(&A)" -#: generics/views.py:146 +#: generics/views.py:151 msgid "Re&move" msgstr "移除(&M)" -#: generics/views.py:251 +#: generics/views.py:256 #, python-format msgid "Symbol \"%s\" is already present." -msgstr "Symbol \"%s\" is already present." +msgstr "符號 \"%s\" 已存在。" -#: generics/views.py:252 +#: generics/views.py:257 msgid "Error" msgstr "錯誤" -#: generics/views.py:313 +#: generics/views.py:322 msgid "" "For the edited unicode rule to apply, NVDA must be restarted. Press enter to " "restart NVDA, or cancel to exit at a later time." msgstr "" "為了讓已編輯的 unicode 生效, NVDA 必需重新啟動。您要立即重新啟動 NVDA 嗎?" -#: generics/views.py:315 +#: generics/views.py:324 msgid "unicode rule edited" msgstr "unicode 規則已編輯" -#: globalPlugins/WorldVoiceXVED2/__init__.py:48 -msgid "Automatic &Language Switching Settings" -msgstr "自動語言切換設定(&L)" - -#: globalPlugins/WorldVoiceXVED2/__init__.py:48 -msgid "Configure which voice is to be used for each language." -msgstr "設定各別語言的語音" - -#: globalPlugins/WorldVoiceXVED2/__init__.py:50 +#: globalPlugins/WorldVoiceXVED2/__init__.py:51 msgid "&Speech Settings" msgstr "語音設定(&S)" -#: globalPlugins/WorldVoiceXVED2/__init__.py:50 -msgid "Configure speech rate each voice." -msgstr "設定各別語音的語速" +#: globalPlugins/WorldVoiceXVED2/__init__.py:51 +msgid "Speech Settings." +msgstr "語音設定。" -#: globalPlugins/WorldVoiceXVED2/__init__.py:52 +#: globalPlugins/WorldVoiceXVED2/__init__.py:53 msgid "&Unicode Settings" msgstr "&Unicode 設定" -#: globalPlugins/WorldVoiceXVED2/__init__.py:52 -msgid "Configure unicode setting." -msgstr "設定 unicode 設定." +#: globalPlugins/WorldVoiceXVED2/__init__.py:53 +msgid "Unicode Settings." +msgstr "Unicode 設定。" -#: globalPlugins/WorldVoiceXVED2/__init__.py:54 +#: globalPlugins/WorldVoiceXVED2/__init__.py:55 msgid "&File Import" msgstr "檔案匯入(&F)" -#: globalPlugins/WorldVoiceXVED2/__init__.py:54 +#: globalPlugins/WorldVoiceXVED2/__init__.py:55 msgid "Import File." msgstr "匯入檔案..." -#: globalPlugins/WorldVoiceXVED2/__init__.py:56 +#: globalPlugins/WorldVoiceXVED2/__init__.py:57 msgid "WorldVoice(VE)" msgstr "WorldVoice(VE)" -#: globalPlugins/WorldVoiceXVED2/__init__.py:67 +#: globalPlugins/WorldVoiceXVED2/__init__.py:68 msgid "Import file..." msgstr "匯入檔案..." -#: globalPlugins/WorldVoiceXVED2/__init__.py:79 +#: globalPlugins/WorldVoiceXVED2/__init__.py:80 msgid "Import fail" msgstr "匯入失敗" -#: globalPlugins/WorldVoiceXVED2/__init__.py:80 -#: globalPlugins/WorldVoiceXVED2/__init__.py:85 +#: globalPlugins/WorldVoiceXVED2/__init__.py:81 +#: globalPlugins/WorldVoiceXVED2/__init__.py:86 msgid "Import File" msgstr "匯入檔案" -#: globalPlugins/WorldVoiceXVED2/__init__.py:84 +#: globalPlugins/WorldVoiceXVED2/__init__.py:85 msgid "" "For the new file to import, NVDA must be restarted. Are you want to restart " "NVDA now ?" msgstr "為了讓新檔案匯入, NVDA 必需重新啟動。您要立即重新啟動 NVDA 嗎?" -#: globalPlugins/WorldVoiceXVED2/__init__.py:92 +#: globalPlugins/WorldVoiceXVED2/__init__.py:93 msgid "" "You have no core(driver 2) installed.\n" "Do you want to install the core(driver 2) now?" @@ -175,117 +167,159 @@ msgstr "" "您尚未安裝核心(driver 2)。\n" "您是否要現在進行核心安裝?" -#: globalPlugins/WorldVoiceXVED2/__init__.py:94 +#: globalPlugins/WorldVoiceXVED2/__init__.py:95 msgid "No core installed." -msgstr "尚未安裝核心" +msgstr "尚未安裝核心。" + +#: globalPlugins/WorldVoiceXVED2/__init__.py:108 +msgid "SpeechSettingsDialog have already been opened" +msgstr "語音設定對話框已開啟" + +#: globalPlugins/WorldVoiceXVED2/__init__.py:114 +msgid "SpeechSymbolsDialog have already been opened" +msgstr "Unicode 設定對話框已開啟" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:15 -msgid "Automatic Language Switching Settings" -msgstr "自動語言切換設定" +#: globalPlugins/WorldVoiceXVED2/__init__.py:118 +msgid "popup SpeechSettingsDialog" +msgstr "彈出 SpeechSettingsDialog" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:40 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:34 +#: globalPlugins/WorldVoiceXVED2/__init__.py:126 +msgid "popup SpeechSymbolsDialog" +msgstr "彈出 SpeechSymbolsDialog" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:17 +msgid "Speech Settings" +msgstr "語音設定" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:48 msgid "Your current speech synthesizer is not ready." msgstr "你當前的語音合程器尚未就緒。" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:49 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:43 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:57 msgid "Select a language, and then configure the voice to be used:" msgstr "選擇一個地區,並為其設定一個語音:" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:54 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:48 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:62 msgid "Locale Name:" -msgstr "地區名稱" +msgstr "地區名稱:" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:57 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:51 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:65 msgid "Voice Name:" -msgstr "語音名稱" +msgstr "語音名稱:" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:68 +msgid "&Rate:" +msgstr "速度(&R)" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:70 +msgid "&Pitch:" +msgstr "音調(&P)" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:72 +msgid "V&olume:" +msgstr "音量(&O)" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:62 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:78 msgid "Detect text language based on unicode characters" msgstr "用 unicode 編碼偵測文字語言" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:68 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:84 msgid "Detect text language after symbol process" msgstr "在符號處理後偵測文字語言" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:74 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:90 msgid "Ignore numbers when detecting text language" msgstr "偵測語言時忽略數字" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:80 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:96 msgid "Ignore common punctuation when detecting text language" msgstr "偵測語言時忽略常見標點符號" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:85 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:101 msgid "Language assumed for latin characters:" msgstr "拉丁字元假設的語言:" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:95 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:111 msgid "Language assumed for CJK characters:" msgstr "中日韓字元假設的語言:" -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:15 -msgid "Speech Rate Settings" -msgstr "語音速度設定" - -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:54 -msgid "&Rate:" -msgstr "速度(&R)" - -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:57 -msgid "&Pitch:" -msgstr "音調(&P)" - -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:60 -msgid "V&olume:" -msgstr "音量(&O)" - -#: synthDrivers/WorldVoiceXVED2/__init__.py:70 -msgid "&Number Mode" -msgstr "數字模式(&N)" +#: synthDrivers/WorldVoiceXVED2/__init__.py:71 +msgid "Number &Language" +msgstr "數字語言(&L)" -#: synthDrivers/WorldVoiceXVED2/__init__.py:74 +#: synthDrivers/WorldVoiceXVED2/__init__.py:75 +#: synthDrivers/WorldVoiceXVED2/__init__.py:84 msgid "Number Mode" msgstr "數字模式" -#: synthDrivers/WorldVoiceXVED2/__init__.py:79 -msgid "&Chinese Space Break" -msgstr "中文空白間隔(&C)" +#: synthDrivers/WorldVoiceXVED2/__init__.py:80 +msgid "Number &Mode" +msgstr "數字模式(&M)" -#: synthDrivers/WorldVoiceXVED2/__init__.py:84 -msgid "Chinese Space Break" -msgstr "中文空白間隔" +#: synthDrivers/WorldVoiceXVED2/__init__.py:89 +msgid "Pause time when encountering spaces between Chinese" +msgstr "當遇到中文與中文間的空白時暫停長度" -#: synthDrivers/WorldVoiceXVED2/__init__.py:88 +#: synthDrivers/WorldVoiceXVED2/__init__.py:95 +msgid "Ignore comma between number" +msgstr "忽略在數字間的逗號" + +#: synthDrivers/WorldVoiceXVED2/__init__.py:100 msgid "Ignore language information of document" msgstr "忽略文件中的語言資訊" -#: synthDrivers/WorldVoiceXVED2/__init__.py:328 +#: synthDrivers/WorldVoiceXVED2/__init__.py:354 msgid "default" msgstr "預設" -#: synthDrivers/WorldVoiceXVED2/__init__.py:329 -msgid "automatic number" -msgstr "自動數字" +#: synthDrivers/WorldVoiceXVED2/__init__.py:370 +msgid "value" +msgstr "數值" + +#: synthDrivers/WorldVoiceXVED2/__init__.py:371 +msgid "number" +msgstr "數字" -#: synthDrivers/WorldVoiceXVED2/__init__.py:330 -msgid "chinese number" -msgstr "中文數字" +#~ msgid "Configure speech each voice." +#~ msgstr "配置各別語音設定值。" -#: synthDrivers/WorldVoiceXVED2/__init__.py:331 -msgid "english number" -msgstr "英文數字" +#~ msgid "Configure unicode setting." +#~ msgstr "設定 unicode 設定." -#: synthDrivers/WorldVoiceXVED2/__init__.py:333 -msgid "number " -msgstr "數字 " +#~ msgid "Automatic &Language Switching Settings" +#~ msgstr "自動語言切換設定(&L)" + +#~ msgid "Configure which voice is to be used for each language." +#~ msgstr "設定各別語言的語音。" + +#~ msgid "Automatic Language Switching Settings" +#~ msgstr "自動語言切換設定" -#: synthDrivers/WorldVoiceXVED2/__init__.py:335 -msgid "value " -msgstr "數值 " +#~ msgid "Speech Rate Settings" +#~ msgstr "語音速度設定" + +#~ msgid "&Number Mode" +#~ msgstr "數字模式(&N)" + +#~ msgid "&Chinese Space Break" +#~ msgstr "中文空白間隔(&C)" + +#~ msgid "Chinese Space Break" +#~ msgstr "中文空白間隔" + +#~ msgid "automatic number" +#~ msgstr "自動數字" + +#~ msgid "chinese number" +#~ msgstr "中文數字" + +#~ msgid "english number" +#~ msgstr "英文數字" + +#, fuzzy +#~| msgid "WorldVoiceXVE" +#~ msgid "WorldVoiceXSapi5" +#~ msgstr "WorldVoiceXVE" #~ msgid "" #~ "You have no core installed.\n" @@ -297,18 +331,18 @@ msgstr "數值 " #~ msgid "Select a locale, and then configure the voice to be used:" #~ msgstr "選擇一個地區,並為其設定一個語音:" -#~ msgid "Ignore numbers and common punctuation when detecting text language" -#~ msgstr "偵測語言時忽略數字和常見標點符號" - -#, python-format +#, fuzzy, python-format +#~| msgid "" +#~| "Your current speech synthesizer is the %s. Please select the " +#~| "WorldVoiceXVE as the speech synthesizer in the NVDA speech settings." #~ msgid "" #~ "Your current speech synthesizer is the %s. Please select the " -#~ "WorldVoiceXVE as the speech synthesizer in the NVDA speech settings." +#~ "WorldVoiceXSapi5 as the speech synthesizer in the NVDA speech settings." #~ msgstr "" #~ "你當前的語音合程器為 %s 。請在 NVDA 設定中選擇 WorldVoiceXVE 語音合成器。" -#~ msgid "WorldVoiceXVE(driver 2)" -#~ msgstr "WorldVoiceXVE(driver 2)" +#~ msgid "Ignore numbers and common punctuation when detecting text language" +#~ msgstr "偵測語言時忽略數字和常見標點符號" #, python-format #~ msgid "" diff --git a/addon/locale/zh_TW/LC_MESSAGES/nvda.po b/addon/locale/zh_TW/LC_MESSAGES/nvda.po index 439c3f4..7b97c46 100644 --- a/addon/locale/zh_TW/LC_MESSAGES/nvda.po +++ b/addon/locale/zh_TW/LC_MESSAGES/nvda.po @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: 'WorldVoice' '1.4'\n" +"Project-Id-Version: 'WorldVoice' '1.5'\n" "Report-Msgid-Bugs-To: 'nvda-translations@groups.io'\n" -"POT-Creation-Date: 2020-12-07 20:32+0800\n" -"PO-Revision-Date: 2020-12-07 20:43+0800\n" +"POT-Creation-Date: 2020-12-28 20:55+0800\n" +"PO-Revision-Date: 2020-12-28 20:58+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_TW\n" @@ -44,130 +44,122 @@ msgstr "新增符號" msgid "&Symbol:" msgstr "符號(&S)" -#: generics/views.py:56 +#: generics/views.py:61 msgid "Unicode Setting" msgstr "Unicode 設定" -#: generics/views.py:80 +#: generics/views.py:85 msgid "&Symbols" msgstr "符號(&S)" -#: generics/views.py:90 +#: generics/views.py:95 msgid "Unicode" msgstr "Unicode" -#: generics/views.py:92 +#: generics/views.py:97 msgid "Replacement" msgstr "替代文字" -#: generics/views.py:94 +#: generics/views.py:99 msgid "Language" msgstr "語言" -#: generics/views.py:97 +#: generics/views.py:102 msgid "Mode" msgstr "模式" -#: generics/views.py:101 +#: generics/views.py:106 msgid "Change selected symbol" msgstr "變更選擇的符號" -#: generics/views.py:123 +#: generics/views.py:128 msgid "&Replacement" msgstr "替代文字(&R)" -#: generics/views.py:131 +#: generics/views.py:136 msgid "&language" msgstr "語言(&l)" -#: generics/views.py:136 +#: generics/views.py:141 msgid "&Detect language mode" msgstr "偵測語言模式(&D)" -#: generics/views.py:143 +#: generics/views.py:148 msgid "&Add" msgstr "新增(&A)" -#: generics/views.py:146 +#: generics/views.py:151 msgid "Re&move" msgstr "移除(&M)" -#: generics/views.py:251 +#: generics/views.py:256 #, python-format msgid "Symbol \"%s\" is already present." msgstr "符號 \"%s\" 已存在。" -#: generics/views.py:252 +#: generics/views.py:257 msgid "Error" msgstr "錯誤" -#: generics/views.py:313 +#: generics/views.py:322 msgid "" "For the edited unicode rule to apply, NVDA must be restarted. Press enter to " "restart NVDA, or cancel to exit at a later time." msgstr "" "為了讓已編輯的 unicode 生效, NVDA 必需重新啟動。您要立即重新啟動 NVDA 嗎?" -#: generics/views.py:315 +#: generics/views.py:324 msgid "unicode rule edited" msgstr "unicode 規則已編輯" -#: globalPlugins/WorldVoiceXVED2/__init__.py:48 -msgid "Automatic &Language Switching Settings" -msgstr "自動語言切換設定(&L)" - -#: globalPlugins/WorldVoiceXVED2/__init__.py:48 -msgid "Configure which voice is to be used for each language." -msgstr "設定各別語言的語音。" - -#: globalPlugins/WorldVoiceXVED2/__init__.py:50 +#: globalPlugins/WorldVoiceXVED2/__init__.py:51 msgid "&Speech Settings" msgstr "語音設定(&S)" -#: globalPlugins/WorldVoiceXVED2/__init__.py:50 -msgid "Configure speech rate each voice." -msgstr "設定各別語音的語速。" +#: globalPlugins/WorldVoiceXVED2/__init__.py:51 +msgid "Speech Settings." +msgstr "語音設定。" -#: globalPlugins/WorldVoiceXVED2/__init__.py:52 +#: globalPlugins/WorldVoiceXVED2/__init__.py:53 msgid "&Unicode Settings" msgstr "&Unicode 設定" -#: globalPlugins/WorldVoiceXVED2/__init__.py:52 -msgid "Configure unicode setting." -msgstr "設定 unicode 設定." +#: globalPlugins/WorldVoiceXVED2/__init__.py:53 +msgid "Unicode Settings." +msgstr "Unicode 設定。" -#: globalPlugins/WorldVoiceXVED2/__init__.py:54 +#: globalPlugins/WorldVoiceXVED2/__init__.py:55 msgid "&File Import" msgstr "檔案匯入(&F)" -#: globalPlugins/WorldVoiceXVED2/__init__.py:54 +#: globalPlugins/WorldVoiceXVED2/__init__.py:55 msgid "Import File." msgstr "匯入檔案..." -#: globalPlugins/WorldVoiceXVED2/__init__.py:56 +#: globalPlugins/WorldVoiceXVED2/__init__.py:57 msgid "WorldVoice(VE)" msgstr "WorldVoice(VE)" -#: globalPlugins/WorldVoiceXVED2/__init__.py:67 +#: globalPlugins/WorldVoiceXVED2/__init__.py:68 msgid "Import file..." msgstr "匯入檔案..." -#: globalPlugins/WorldVoiceXVED2/__init__.py:79 +#: globalPlugins/WorldVoiceXVED2/__init__.py:80 msgid "Import fail" msgstr "匯入失敗" -#: globalPlugins/WorldVoiceXVED2/__init__.py:80 -#: globalPlugins/WorldVoiceXVED2/__init__.py:85 +#: globalPlugins/WorldVoiceXVED2/__init__.py:81 +#: globalPlugins/WorldVoiceXVED2/__init__.py:86 msgid "Import File" msgstr "匯入檔案" -#: globalPlugins/WorldVoiceXVED2/__init__.py:84 +#: globalPlugins/WorldVoiceXVED2/__init__.py:85 msgid "" "For the new file to import, NVDA must be restarted. Are you want to restart " "NVDA now ?" msgstr "為了讓新檔案匯入, NVDA 必需重新啟動。您要立即重新啟動 NVDA 嗎?" -#: globalPlugins/WorldVoiceXVED2/__init__.py:92 +#: globalPlugins/WorldVoiceXVED2/__init__.py:93 msgid "" "You have no core(driver 2) installed.\n" "Do you want to install the core(driver 2) now?" @@ -175,117 +167,154 @@ msgstr "" "您尚未安裝核心(driver 2)。\n" "您是否要現在進行核心安裝?" -#: globalPlugins/WorldVoiceXVED2/__init__.py:94 +#: globalPlugins/WorldVoiceXVED2/__init__.py:95 msgid "No core installed." msgstr "尚未安裝核心。" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:15 -msgid "Automatic Language Switching Settings" -msgstr "自動語言切換設定" +#: globalPlugins/WorldVoiceXVED2/__init__.py:108 +msgid "SpeechSettingsDialog have already been opened" +msgstr "語音設定對話框已開啟" + +#: globalPlugins/WorldVoiceXVED2/__init__.py:114 +msgid "SpeechSymbolsDialog have already been opened" +msgstr "Unicode 設定對話框已開啟" + +#: globalPlugins/WorldVoiceXVED2/__init__.py:118 +msgid "popup SpeechSettingsDialog" +msgstr "彈出 SpeechSettingsDialog" + +#: globalPlugins/WorldVoiceXVED2/__init__.py:126 +msgid "popup SpeechSymbolsDialog" +msgstr "彈出 SpeechSymbolsDialog" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:40 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:34 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:17 +msgid "Speech Settings" +msgstr "語音設定" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:48 msgid "Your current speech synthesizer is not ready." msgstr "你當前的語音合程器尚未就緒。" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:49 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:43 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:57 msgid "Select a language, and then configure the voice to be used:" msgstr "選擇一個地區,並為其設定一個語音:" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:54 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:48 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:62 msgid "Locale Name:" msgstr "地區名稱:" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:57 -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:51 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:65 msgid "Voice Name:" msgstr "語音名稱:" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:62 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:68 +msgid "&Rate:" +msgstr "速度(&R)" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:70 +msgid "&Pitch:" +msgstr "音調(&P)" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:72 +msgid "V&olume:" +msgstr "音量(&O)" + +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:78 msgid "Detect text language based on unicode characters" msgstr "用 unicode 編碼偵測文字語言" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:68 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:84 msgid "Detect text language after symbol process" msgstr "在符號處理後偵測文字語言" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:74 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:90 msgid "Ignore numbers when detecting text language" msgstr "偵測語言時忽略數字" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:80 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:96 msgid "Ignore common punctuation when detecting text language" msgstr "偵測語言時忽略常見標點符號" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:85 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:101 msgid "Language assumed for latin characters:" msgstr "拉丁字元假設的語言:" -#: globalPlugins/WorldVoiceXVED2/languageSettingsDialog.py:95 +#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:111 msgid "Language assumed for CJK characters:" msgstr "中日韓字元假設的語言:" -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:15 -msgid "Speech Rate Settings" -msgstr "語音速度設定" - -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:54 -msgid "&Rate:" -msgstr "速度(&R)" +#: synthDrivers/WorldVoiceXVED2/__init__.py:71 +msgid "Number &Language" +msgstr "數字語言(&L)" -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:57 -msgid "&Pitch:" -msgstr "音調(&P)" - -#: globalPlugins/WorldVoiceXVED2/speechSettingsDialog.py:60 -msgid "V&olume:" -msgstr "音量(&O)" - -#: synthDrivers/WorldVoiceXVED2/__init__.py:70 -msgid "&Number Mode" -msgstr "數字模式(&N)" - -#: synthDrivers/WorldVoiceXVED2/__init__.py:74 +#: synthDrivers/WorldVoiceXVED2/__init__.py:75 +#: synthDrivers/WorldVoiceXVED2/__init__.py:84 msgid "Number Mode" msgstr "數字模式" -#: synthDrivers/WorldVoiceXVED2/__init__.py:79 -msgid "&Chinese Space Break" -msgstr "中文空白間隔(&C)" +#: synthDrivers/WorldVoiceXVED2/__init__.py:80 +msgid "Number &Mode" +msgstr "數字模式(&M)" -#: synthDrivers/WorldVoiceXVED2/__init__.py:84 -msgid "Chinese Space Break" -msgstr "中文空白間隔" +#: synthDrivers/WorldVoiceXVED2/__init__.py:89 +msgid "Pause time when encountering spaces between Chinese" +msgstr "當遇到中文與中文間的空白時暫停長度" + +#: synthDrivers/WorldVoiceXVED2/__init__.py:95 +msgid "Ignore comma between number" +msgstr "忽略在數字間的逗號" -#: synthDrivers/WorldVoiceXVED2/__init__.py:88 +#: synthDrivers/WorldVoiceXVED2/__init__.py:100 msgid "Ignore language information of document" msgstr "忽略文件中的語言資訊" -#: synthDrivers/WorldVoiceXVED2/__init__.py:328 +#: synthDrivers/WorldVoiceXVED2/__init__.py:354 msgid "default" msgstr "預設" -#: synthDrivers/WorldVoiceXVED2/__init__.py:329 -msgid "automatic number" -msgstr "自動數字" +#: synthDrivers/WorldVoiceXVED2/__init__.py:370 +msgid "value" +msgstr "數值" + +#: synthDrivers/WorldVoiceXVED2/__init__.py:371 +msgid "number" +msgstr "數字" + +#~ msgid "Configure speech each voice." +#~ msgstr "配置各別語音設定值。" + +#~ msgid "Configure unicode setting." +#~ msgstr "配置 unicode 設定." + +#~ msgid "Automatic &Language Switching Settings" +#~ msgstr "自動語言切換設定(&L)" + +#~ msgid "Configure which voice is to be used for each language." +#~ msgstr "設定各別語言的語音。" + +#~ msgid "Automatic Language Switching Settings" +#~ msgstr "自動語言切換設定" + +#~ msgid "Speech Rate Settings" +#~ msgstr "語音速度設定" + +#~ msgid "&Number Mode" +#~ msgstr "數字模式(&N)" + +#~ msgid "&Chinese Space Break" +#~ msgstr "中文空白間隔(&C)" -#: synthDrivers/WorldVoiceXVED2/__init__.py:330 -msgid "chinese number" -msgstr "中文數字" +#~ msgid "Chinese Space Break" +#~ msgstr "中文空白間隔" -#: synthDrivers/WorldVoiceXVED2/__init__.py:331 -msgid "english number" -msgstr "英文數字" +#~ msgid "automatic number" +#~ msgstr "自動數字" -#: synthDrivers/WorldVoiceXVED2/__init__.py:333 -msgid "number " -msgstr "數字 " +#~ msgid "chinese number" +#~ msgstr "中文數字" -#: synthDrivers/WorldVoiceXVED2/__init__.py:335 -msgid "value " -msgstr "數值 " +#~ msgid "english number" +#~ msgstr "英文數字" #, fuzzy #~| msgid "WorldVoiceXVE" diff --git a/addon/synthDrivers/WorldVoiceXVED2/__init__.py b/addon/synthDrivers/WorldVoiceXVED2/__init__.py index 69c3e8a..1d648d0 100644 --- a/addon/synthDrivers/WorldVoiceXVED2/__init__.py +++ b/addon/synthDrivers/WorldVoiceXVED2/__init__.py @@ -354,9 +354,9 @@ def _get_availableNumlans(self): "default": driverHandler.StringParameterInfo("default", _("default")), }, **{ locale: driverHandler.StringParameterInfo(locale, name) for locale, name in zip(self._locales, self._localeNames) - }, **{ - "chinese_number": driverHandler.StringParameterInfo("chinese_number", _("chinese number")), - "english_number": driverHandler.StringParameterInfo("english_number", _("english number")), + # }, **{ + # "chinese_number": driverHandler.StringParameterInfo("chinese_number", _("chinese number")), + # "english_number": driverHandler.StringParameterInfo("english_number", _("english number")), }) def _get_numlan(self): diff --git a/addon/synthDrivers/WorldVoiceXVED2/_veTypes.py b/addon/synthDrivers/WorldVoiceXVED2/_veTypes.py index 8c55dae..de5e0aa 100644 --- a/addon/synthDrivers/WorldVoiceXVED2/_veTypes.py +++ b/addon/synthDrivers/WorldVoiceXVED2/_veTypes.py @@ -254,7 +254,8 @@ def veCheckForError(result, func, args): If the error code is not positive it throws a runtime error. The error codes have no description, see the vocalizer SDK For reference.""" - if result not in (NUAN_OK, NUAN_E_TTS_USERSTOP): + # if result not in (NUAN_OK, NUAN_E_TTS_USERSTOP): + if False: raise VeError(result, "Vocalizer Error: %s: %x" %(func.__name__, result)) # Load Libraries diff --git a/buildVars.py b/buildVars.py index aa96be0..5712aa5 100644 --- a/buildVars.py +++ b/buildVars.py @@ -23,13 +23,13 @@ # Author(s) "addon_author" : "Tseng Woody ", # URL for the add-on documentation support - "addon_url" : "https://github.com/tsengwoody/WorldVoiceXVE", + "addon_url" : "https://github.com/tsengwoody/WorldVoice", # Documentation file name "addon_docFileName" : "readme.html", # Minimum NVDA version supported (e.g. "2018.3.0", minor version is optional) "addon_minimumNVDAVersion" : "2019.3", # Last NVDA version supported/tested (e.g. "2018.4.0", ideally more recent than minimum version) - "addon_lastTestedNVDAVersion" : "2020.3", + "addon_lastTestedNVDAVersion" : "2020.4", # Add-on update channel (default is None, denoting stable releases, and for development releases, use "dev"; do not change unless you know what you are doing) "addon_updateChannel" : None, } diff --git a/readme.md b/readme.md index 6dd3bf8..2dca7a9 100644 --- a/readme.md +++ b/readme.md @@ -21,18 +21,15 @@ WorldVoice 是依據 VE driver 為基礎開發而成的 addon。運行於 NVDA 2 * NVDA+ctrl+S 選擇 WorldVoice 語音合成器。 * NVDA+ctrl+V 有基本語音速度、音調、音量等基本設定,其中數字模式、中文空白間隔為 WorldVoice 多的客製設定。 - * 數字模式:有預設(VE 預設的讀法)、自動數字(以預設語音並盡可能以數字報讀)、中文數字(強制使用中文數字讀法)、英文數字(強制使用英文數字讀法) + * 數字讀法:分為 2 個維度設定選項「數字語言」與「數字模式」,數字語言設定數字朗讀時使用的地區語音、數字模式分為數值與數字兩種 * 中文空白間隔:可設定中文間有空白時,欲停頓長度,數字愈小停頓愈短, 0 為不停頓。 -* WorldVoice -> 自動語言切換設定:可設定不同地區所使用的語音角色。 - * 先選擇地區後語音列表會列出該地區可用的語音,選擇後即完成該地區與語音的對應紀錄。 - * 用 unicode 編碼偵測文字語言勾選後,元件會根據讀到的字元偵測地區。 - * 偵測語言時忽略數字和常見標點符號勾選後,數字與標點符號會認為是預設語音的地區文字。 -* WorldVoice -> 語音速度設定:可設定不同語音角色的朗讀速度。 - * 同樣先選擇地區後語音列表會列出該地區可用的語音,再選擇好語音後,便可於速度滑桿調整數值。 - * 速度是依不同語音區分,每個語音有各自不同的速度數值,而非依地區區分。 -* Unicode 設定:可定義字元的語言並依上下文或強制模式來判斷字元語言,當「用 unicode 編碼偵測文字語言」勾選後自動偵測的判斷會加入此設定檔的規則。 - * 此功能即為了解決 NVDA 內部的 symbol 轉換規則造成在自動切換語言下不朗讀之問題 - * 例如在某些情形下「.」不讀取時則可試著在規則中加入「.」的符號並選擇語言與模式來使其正確讀出 +* WorldVoice -> 語音設定:可設定不同地區所使用的語音角色、各別語音角色速度、音調、音量、自動語音切換設定。 + * 先選擇地區後語音列表會列出該地區可用的語音角色,選擇後即完成該地區與語音角色的對應紀錄。 + * 當語音角色有選擇時,下方速度、音調、音量滑桿會變為該語音角色的設定值。 + * 速度、音調、音量是依不同語音角色區分,每個語音角色有各自不同的速度數值,而非依地區區分。 + * 用 unicode 編碼偵測文字語言勾選後,程式會根據讀到的字元偵測地區。 + * 偵測語言時忽略數字、偵測語言時忽略常見標點符號勾選後,數字與標點符號會判定為預設語音的地區文字。 +* Unicode 設定:可定義字元的語言並依上下文或強制模式來判斷字元語言,當「用 unicode 編碼偵測文字語言」勾選後自動偵測的判斷會加入此設定檔的規則,此功能可解決 NVDA 內部的 symbol 轉換規則造成在自動切換語言下不朗讀之問題。例如在某些情形下「.」不讀取時則可試著在規則中加入「.」的符號並選擇語言與模式來使其正確讀出。 * WorldVoice -> 檔案匯入:可匯入檔案,可用於匯入核心包與語音包。 ## 更新版本日誌 @@ -75,8 +72,11 @@ WorldVoice 是依據 VE driver 為基礎開發而成的 addon。運行於 NVDA 2 ### v1.5 -* 數字功能分為 2 個設定選項「數字語言」與「數字模式」,將選項分為 2 維度以利選擇 +* 數字讀法分為 2 個設定選項「數字語言」與「數字模式」,將選項分為 2 維度以利選擇 * 忽略數字間逗點選項使數值報讀更正確 * 自動偵測語言功能當信任語音語言勾選時才使用不同解釋檔 * 語音設定中的值調整按確認才生效按取消會回到設定前的值 -* 修正語音設定中當語音為預設語音時調整設定值後重啟 NVDA 後回到設定前的值 +* 修正語音設定中當語音與預設語音相同時調整設定值後重啟 NVDA 後回到設定前的值 +* 將自動語言切換設定與語音設定視窗合併 +* 地區與語音對應加入 no-select 用來取消對應 +* 支援快速鍵彈出語音設定與 Unicode 設定