src/docs/flow-main-translation.md
STranslate/ViewModels/MainWindowViewModel.cs
OnInputTextChanged():自动翻译防抖入口。InputClear():输入翻译入口,清空输入并进入临时输入翻译模式。TranslateAsync():主翻译命令。SingleTranslateAsync() / SingleTransBackAsync():单服务执行。ExecuteTranslateAsync():缓存优先 + 实时翻译编排。ResolveTranslationLanguageContextAsync():解析实际参与翻译的源/目标语种。HandleCapturedText():统一处理取词入口文本的换行与分隔符。STranslate/Helpers/LanguageDetector.cs
GetLanguageAsync():源语种判定与目标语种推导。GetTargetLanguage():根据实际源语种推导目标语种。STranslate/Core/SqlService.cs
GetDataAsync() / InsertOrUpdateDataAsync():历史缓存读取与落盘。STranslate/Core/Utilities.cs
CapturedTextHandler():取词文本后处理。OnInputTextChanged(value):
Settings.AutoTranslate == false 直接返回。DebounceExecutor 按 Settings.AutoTranslateDelayMs 延迟执行 TranslateCommand。TranslateAsync() 执行前先取消防抖队列,重置已启用服务的结果对象。ExecuteTranslateAsync(checkCacheFirst):
ExecMode == Automatic 的服务。(InputText, SourceLang, TargetLang) 查询 SqlService。LanguageDetector.GetLanguageAsync() 获取最终 source/target。
Settings.LanguageDetector 并跳过缓存重新翻译;识别状态仍由本次翻译流程按实际检测结果刷新。source 执行一次。Tencent 不再作为可选检测器参与运行。SemaphoreSlim 并发执行服务:
ITranslatePlugin 走主翻译,按需执行自动回译。IDictionaryPlugin 走词典查询路径。EffectiveSourceLang / EffectiveTargetLang,用于历史页和 CSV 导出展示自动识别后的实际语种。HistoryData 记录 ServiceDisplayName,避免服务重命名后历史结果只剩服务 ID。Settings.HideInput 和 Settings.HideInputWithLangSelectControl 控制输入框和语言选择控件。InputClear() 后会启用临时输入翻译模式,让输入框和语言选择控件在当前会话内可见并获得焦点。ExecuteTranslate(text, ...) 用于已有文本直接翻译,会退出临时输入翻译模式并继续按用户隐藏设置展示结果。Ctrl+C+C、增量翻译、剪贴板监听等入口取得文本后,不直接进入翻译。MainWindowViewModel.HandleCapturedText(text, scope) 先按 Settings.LineBreakHandleType 处理换行。Settings.TextSeparatorHandleType != None 且当前 scope 包含在 Settings.TextSeparatorHandleScopes 中,再把英文/数字标识符内部的 _ 或 - 转为空格。ExecuteTranslate() 或追加到输入框;普通键盘输入不走该取词后处理。PopulateResultsFromCacheAsync() 遍历目标服务。TransResult / TransBackResult。DictionaryResult。TemporaryTranslate(service) / 输出区重试先走服务级 CanExecute:不同服务可并发,同一服务已有手动任务时继续提示等待。SingleTranslateAsync(service) / SingleTransBackAsync(service) 启动时快照当前输入文本与源/目标语种,并用 PluginID + ServiceID 登记本次任务的取消令牌。IDictionaryPlugin:用快照文本执行 ExecuteDictAsync(),失败即返回;词典手动执行仍保持现有历史语义,不额外落盘。ITranslatePlugin:用快照文本和语种配置识别实际语种后执行 ExecuteAsync(),按配置追加 ExecuteBackAsync()。HistoryData,避免多个手动服务并发完成时互相覆盖。Settings.CopyAfterTranslationNotAutomatic 为真时,手动执行完成立即复制结果;多个并发服务仍按完成顺序更新剪贴板。CancelAllOperations() 取消所有已登记的手动单服务任务。Settings.CopyAfterTranslation 支持第 N 个自动服务或最后一个自动服务。Settings.HistoryLimit > 0 时使用 SQLite;否则仅使用内存 _recentTexts 缓存最近输入。当替换翻译 / TTS / 生词本等核心服务未配置或全部禁用时,使用 Helper.PromptConfigureService 弹出 MessageBox(OK/Cancel)。弹窗底层统一走 AppMessageBox:优先挂到当前活动窗口,没有活动窗口时才通过主屏中心的临时透明 owner 显示:
具体映射:
| 功能 | 未配置服务 | 跳转页面 | 涉及 ViewModel 方法 |
|---|---|---|---|
| 替换翻译 | 替换翻译服务 | TranslatePage | ReplaceTranslateAsync |
| 朗读 | TTS | TtsPage | PlayAudioAsync / SilentTtsHandlerAsync |
| 保存生词本 | 生词本服务 | VocabularyPage | SaveToVocabularyAsync / SaveToVocabularyWithNoteAsync |
执行过程中抛出异常或识别失败时,使用当前窗口内的 Snackbar 提示:
_snackbar.ShowWarning("LanguageDetectionFailed")。_snackbar.ShowWarning("NoTextRecognizedMessage")。_snackbar.ShowError("TtsFailed") / _snackbar.ShowInfo("TtsCancelled")。_snackbar.ShowError("OperationFailed") 或显示服务端返回的错误信息。Service.Options
ExecMode:自动/手动执行。AutoBackTranslation:自动回译开关。HistoryModel / HistoryData
RawData 序列化所有服务结果(翻译、回译、词典)。EffectiveSourceLang / EffectiveTargetLang 保存实际参与翻译的语言。ServiceDisplayName 保存服务显示名快照。TranslateResult / DictionaryResult
None:当前不显示识别语种标签。Cache:当前翻译结果来自缓存命中;若缓存里记录了 EffectiveSourceLang,识别状态仍可显示该语言。Detected:显示最近一次主翻译实际使用的源语种,可能来自自动识别成功或识别失败后的回退语言。AutoTranslate、AutoTranslateDelayMsCopyAfterTranslation、CopyAfterTranslationNotAutomaticHistoryLimitTextSeparatorHandleType、TextSeparatorHandleScopesHideInput:用户持久隐藏输入框偏好。HideInputWithLangSelectControl:隐藏输入框时是否一并隐藏语言选择控件。IsInputActuallyHidden:叠加临时输入翻译模式后的实际隐藏状态。IsInputBoxVisible / IsLanguageSelectControlVisible:主窗口 XAML 直接绑定的实际可见状态。STranslate/ViewModels/MainWindowViewModel.csSTranslate/Helpers/LanguageDetector.csSTranslate/Core/SqlService.csSTranslate/Core/Utilities.csSTranslate/Services/TranslateService.csSTranslate.Plugin/ITranslatePlugin.csExecuteAsync 返回后、历史入库前处理。OnInputTextChanged 与 Settings.AutoTranslateDelayMs。InputClear()、输入区有效显隐属性和 MainWindow.xaml 绑定,避免直接改 Settings.HideInput 破坏用户偏好。HistoryModel.HasData() 与 PopulateResultsFromCacheAsync(),避免只改 UI 层。TranslateAsync() 内 CopyAfterTranslation 分支,并同步枚举定义与设置页。TextSeparatorHandleScope 并复用 HandleCapturedText(),避免各入口文本清洗行为不一致。