fix(gui): drop a dead setting, make the language list and tail toggle real
Three settings were only half-wired: - autoPickByLanguage was saved but never read anywhere: delete it. - showUnstableTail had a checkbox and a setter, but nothing ever called the setter, so the checkbox did nothing: apply it in applyAppearance and re-render from the cached text instead of blanking the caption. - the language dropdown was hard-coded to auto/zh/en/ja while the registry declares up to 16 languages per model: build it from the selected model's own language list, with an ISO-code to display-name mapping (plus a unit test covering every code in the registry). The caption window's language pill now follows the setting too, instead of keeping whatever it showed at startup. windowPos is not dead -- it stores the dragged window position -- so it stays. 三个「半死」设置:autoPickByLanguage 存了但从没被读取,直接删掉;showUnstableTail 有复选框也有 setter,但从来没人调用 setter(复选框点了没用),改为在 applyAppearance 里生效并用缓存文本重画;「识别语言」下拉原来硬编码 自动/中/英/日,而注册表里每个模型 声明了最多 16 种语言,改为按所选模型的语言动态生成,并补 ISO 码→显示名映射与单元测试。 字幕窗的语言标签也跟着设置走了(原来只在启动时读一次)。windowPos 不是死设置(它存的 是拖动后的位置),保留。
This commit is contained in:
1 parent
6c04071bb5
commit
898763eb74
12 files changed
+141
-26
No files matched your search
+21
-12
@@ -50,12 +50,13 @@ QIcon makeTrayIcon()
|
|||||||
return QIcon(pm);
|
return QIcon(pm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 把设置应用到字幕窗(字号/不透明度/行数/位置)
|
// 把设置应用到字幕窗(字号/不透明度/行数/位置/灰色尾部)
|
||||||
void applyAppearance(lc::CaptionWindow & window, const lc::AppSettings & cfg)
|
void applyAppearance(lc::CaptionWindow & window, const lc::AppSettings & cfg)
|
||||||
{
|
{
|
||||||
window.setPanelOpacity(cfg.opacityPercent);
|
window.setPanelOpacity(cfg.opacityPercent);
|
||||||
window.setTextFontSize(cfg.fontSize);
|
window.setTextFontSize(cfg.fontSize);
|
||||||
window.setLineCounts(cfg.collapsedLines, cfg.expandedLines);
|
window.setLineCounts(cfg.collapsedLines, cfg.expandedLines);
|
||||||
|
window.setShowTail(cfg.showUnstableTail);
|
||||||
if (cfg.hasWindowPos) window.move(cfg.windowPos);
|
if (cfg.hasWindowPos) window.move(cfg.windowPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +194,8 @@ int main(int argc, char ** argv)
|
|||||||
applyAppearance(window, cfg);
|
applyAppearance(window, cfg);
|
||||||
// 语言 pill:流式模型不提供语言识别,就显示设置里选的语言
|
// 语言 pill:流式模型不提供语言识别,就显示设置里选的语言
|
||||||
if (!cfg.language.isEmpty()) {
|
if (!cfg.language.isEmpty()) {
|
||||||
window.setLanguage(QString::fromStdString(lc::languageDisplayName(cfg.language.toStdString())));
|
window.setLanguage(
|
||||||
|
QString::fromStdString(lc::languageDisplayNameFromCode(cfg.language.toStdString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注意声明顺序:asr 必须在 live 之前声明,
|
// 注意声明顺序:asr 必须在 live 之前声明,
|
||||||
@@ -259,24 +261,31 @@ int main(int argc, char ** argv)
|
|||||||
QString activeKey = backendKeyOf(cfg);
|
QString activeKey = backendKeyOf(cfg);
|
||||||
|
|
||||||
const auto openSettings = [&] {
|
const auto openSettings = [&] {
|
||||||
|
// 后端相关项变化时:先把语言标签跟设置对齐(流式模型没有自动检测结果来更新它),
|
||||||
|
// 再重启识别后端。
|
||||||
|
const auto applyBackend = [&]() -> bool {
|
||||||
|
if (backendKeyOf(cfg) == activeKey) return true;
|
||||||
|
window.setLanguage(cfg.language.isEmpty()
|
||||||
|
? QString()
|
||||||
|
: QString::fromStdString(
|
||||||
|
lc::languageDisplayNameFromCode(cfg.language.toStdString())));
|
||||||
|
if (!startTranscriber()) return false;
|
||||||
|
activeKey = backendKeyOf(cfg);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
lc::SettingsDialog dlg(false);
|
lc::SettingsDialog dlg(false);
|
||||||
QObject::connect(&dlg, &lc::SettingsDialog::settingsApplied, &window, [&] {
|
QObject::connect(&dlg, &lc::SettingsDialog::settingsApplied, &window, [&] {
|
||||||
lc::models::ModelStore::setRootOverride(cfg.modelDir);
|
lc::models::ModelStore::setRootOverride(cfg.modelDir);
|
||||||
applyAppearance(window, cfg); // 透明度/字号等立刻可见
|
applyAppearance(window, cfg); // 透明度/字号等立刻可见
|
||||||
if (backendKeyOf(cfg) != activeKey) {
|
applyBackend();
|
||||||
if (startTranscriber()) activeKey = backendKeyOf(cfg);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (dlg.exec() == QDialog::Accepted) {
|
if (dlg.exec() == QDialog::Accepted) {
|
||||||
lc::models::ModelStore::setRootOverride(cfg.modelDir);
|
lc::models::ModelStore::setRootOverride(cfg.modelDir);
|
||||||
applyAppearance(window, cfg);
|
applyAppearance(window, cfg);
|
||||||
if (backendKeyOf(cfg) != activeKey) {
|
if (!applyBackend()) {
|
||||||
if (!startTranscriber()) {
|
QMessageBox::warning(&window, QObject::tr("启动失败"),
|
||||||
QMessageBox::warning(&window, QObject::tr("启动失败"),
|
QObject::tr("模型加载失败,请检查设置。"));
|
||||||
QObject::tr("模型加载失败,请检查设置。"));
|
|
||||||
} else {
|
|
||||||
activeKey = backendKeyOf(cfg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+3
-2
@@ -65,8 +65,9 @@
|
|||||||
也可以指定某个具体输出设备(如 HDMI);列不出来或没列全时见
|
也可以指定某个具体输出设备(如 HDMI);列不出来或没列全时见
|
||||||
[troubleshooting.md](troubleshooting.md)。
|
[troubleshooting.md](troubleshooting.md)。
|
||||||
- **当前使用**:选择实际生效的模型(只列出**已安装**的)。
|
- **当前使用**:选择实际生效的模型(只列出**已安装**的)。
|
||||||
- **识别语言**:语言提示,多语言模型用它(例如 Nemotron 需要指定语言才不出错);
|
- **识别语言**:语言提示,多语言模型用它(例如 Nemotron 必须指定语言,否则「自动」可能识别成别的语言);
|
||||||
「自动检测」= 留空。目前提供 自动/中文/英文/日语。
|
「自动检测」= 留空。**候选项按所选模型支持的语言生成** —— 中文模型只给中文,Nemotron 给它的 16 种
|
||||||
|
语言,Qwen3-ASR 给常用语言。改完之后左上角的语言标签会同步更新。
|
||||||
- **下载源**:默认 `https://hf-mirror.com`(网络可达性最好的镜像);可改成其它镜像或官方源。
|
- **下载源**:默认 `https://hf-mirror.com`(网络可达性最好的镜像);可改成其它镜像或官方源。
|
||||||
- **代理**:不使用 / 跟随系统 / 手动设置(主机、端口、用户名、密码)。
|
- **代理**:不使用 / 跟随系统 / 手动设置(主机、端口、用户名、密码)。
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ ctest --test-dir build --output-on-failure # 也可以单独跑 build/tests/t
|
|||||||
| `tst_livepipeline.silenceEndsSegment` | 静音收束分段 |
|
| `tst_livepipeline.silenceEndsSegment` | 静音收束分段 |
|
||||||
| `tst_vad.quietSpeechIsDetected` | 噪声底用均值跟踪,把很轻的话音全判成静音 |
|
| `tst_vad.quietSpeechIsDetected` | 噪声底用均值跟踪,把很轻的话音全判成静音 |
|
||||||
| `tst_transcript.*` | 输出解析与语言名映射 |
|
| `tst_transcript.*` | 输出解析与语言名映射 |
|
||||||
|
| `tst_transcript.isoCodeDisplayName` / `registryLanguagesAllHaveDisplayNames` | 设置里的语言提示用的是 ISO 码(`zh`/`uk`…),漏了显示名的话「识别语言」下拉会直接露出 `uk` 这种码 |
|
||||||
|
|
||||||
写测试的过程中还**抓到一个真 bug**:段恰好结束在 chunk 边界(没有待处理音频)时,`flush()` 只提交"已稳定"部分,最后几个词会被丢掉。已修(用完整文本 `lastRawFull_` 提交)。
|
写测试的过程中还**抓到一个真 bug**:段恰好结束在 chunk 边界(没有待处理音频)时,`flush()` 只提交"已稳定"部分,最后几个词会被丢掉。已修(用完整文本 `lastRawFull_` 提交)。
|
||||||
|
|
||||||
|
|||||||
@@ -76,4 +76,38 @@ std::string languageDisplayName(const std::string & lang)
|
|||||||
return lang;
|
return lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ISO 639-1 码(注册表里用的形式,如 zh / en / ja)→ 显示名。
|
||||||
|
// ASR 模型自己吐的是完整语言名(走上面的 languageDisplayName),
|
||||||
|
// 但设置里的语言提示是 ISO 码,界面要显示成中文。
|
||||||
|
std::string languageDisplayNameFromCode(const std::string & code)
|
||||||
|
{
|
||||||
|
if (code.empty()) return {};
|
||||||
|
|
||||||
|
static const struct { const char * key; const char * display; } kMap[] = {
|
||||||
|
{ "zh", "中文" },
|
||||||
|
{ "en", "英语" },
|
||||||
|
{ "ja", "日语" },
|
||||||
|
{ "ko", "韩语" },
|
||||||
|
{ "fr", "法语" },
|
||||||
|
{ "de", "德语" },
|
||||||
|
{ "es", "西班牙语" },
|
||||||
|
{ "ru", "俄语" },
|
||||||
|
{ "it", "意大利语" },
|
||||||
|
{ "pt", "葡萄牙语" },
|
||||||
|
{ "ar", "阿拉伯语" },
|
||||||
|
{ "hi", "印地语" },
|
||||||
|
{ "vi", "越南语" },
|
||||||
|
{ "nl", "荷兰语" },
|
||||||
|
{ "tr", "土耳其语" },
|
||||||
|
{ "uk", "乌克兰语" },
|
||||||
|
{ "yue", "粤语" },
|
||||||
|
{ "auto", "自动检测" },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto & e : kMap) {
|
||||||
|
if (code == e.key) return e.display;
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace lc
|
} // namespace lc
|
||||||
@@ -17,4 +17,7 @@ ParsedTranscript parseAsrOutput(const std::string & raw);
|
|||||||
// "English" -> "英语","Chinese" -> "中文";未知则原样返回
|
// "English" -> "英语","Chinese" -> "中文";未知则原样返回
|
||||||
std::string languageDisplayName(const std::string & lang);
|
std::string languageDisplayName(const std::string & lang);
|
||||||
|
|
||||||
|
// ISO 码(注册表里用的形式)-> 显示名:"zh" -> "中文"、"ja" -> "日语";未知则原样返回
|
||||||
|
std::string languageDisplayNameFromCode(const std::string & code);
|
||||||
|
|
||||||
} // namespace lc
|
} // namespace lc
|
||||||
@@ -16,7 +16,6 @@ void AppSettings::load()
|
|||||||
s.beginGroup(QStringLiteral("app"));
|
s.beginGroup(QStringLiteral("app"));
|
||||||
modelId = s.value(QStringLiteral("modelId")).toString();
|
modelId = s.value(QStringLiteral("modelId")).toString();
|
||||||
language = s.value(QStringLiteral("language")).toString();
|
language = s.value(QStringLiteral("language")).toString();
|
||||||
autoPickByLanguage = s.value(QStringLiteral("autoPickByLanguage"), false).toBool();
|
|
||||||
|
|
||||||
opacityPercent = s.value(QStringLiteral("opacity"), 84).toInt();
|
opacityPercent = s.value(QStringLiteral("opacity"), 84).toInt();
|
||||||
fontSize = s.value(QStringLiteral("fontSize"), 15).toInt();
|
fontSize = s.value(QStringLiteral("fontSize"), 15).toInt();
|
||||||
@@ -60,7 +59,6 @@ void AppSettings::save()
|
|||||||
s.beginGroup(QStringLiteral("app"));
|
s.beginGroup(QStringLiteral("app"));
|
||||||
s.setValue(QStringLiteral("modelId"), modelId);
|
s.setValue(QStringLiteral("modelId"), modelId);
|
||||||
s.setValue(QStringLiteral("language"), language);
|
s.setValue(QStringLiteral("language"), language);
|
||||||
s.setValue(QStringLiteral("autoPickByLanguage"), autoPickByLanguage);
|
|
||||||
|
|
||||||
s.setValue(QStringLiteral("opacity"), opacityPercent);
|
s.setValue(QStringLiteral("opacity"), opacityPercent);
|
||||||
s.setValue(QStringLiteral("fontSize"), fontSize);
|
s.setValue(QStringLiteral("fontSize"), fontSize);
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ public:
|
|||||||
// 模型
|
// 模型
|
||||||
QString modelId; // 当前使用的模型注册表 id
|
QString modelId; // 当前使用的模型注册表 id
|
||||||
QString language; // 识别语言提示;"" = 自动
|
QString language; // 识别语言提示;"" = 自动
|
||||||
bool autoPickByLanguage = false;
|
|
||||||
|
|
||||||
// 显示
|
// 显示
|
||||||
int opacityPercent = 84;
|
int opacityPercent = 84;
|
||||||
|
|||||||
@@ -171,8 +171,7 @@ void CaptionWindow::setShowTail(bool on)
|
|||||||
{
|
{
|
||||||
if (showTail_ == on) return;
|
if (showTail_ == on) return;
|
||||||
showTail_ = on;
|
showTail_ = on;
|
||||||
setCaption(QString(), QString()); // 强制重画需要外部再喂一次;这里先清空缓存
|
renderCaption(); // 用缓存的文本立刻重画(不能走 setCaption:参数没变会被早退)
|
||||||
committed_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptionWindow::setPanelOpacity(int percent)
|
void CaptionWindow::setPanelOpacity(int percent)
|
||||||
@@ -235,8 +234,12 @@ void CaptionWindow::setCaption(const QString & committed, const QString & tail)
|
|||||||
if (committed == committed_ && tail == tail_) return;
|
if (committed == committed_ && tail == tail_) return;
|
||||||
committed_ = committed;
|
committed_ = committed;
|
||||||
tail_ = tail;
|
tail_ = tail;
|
||||||
|
renderCaption();
|
||||||
|
}
|
||||||
|
|
||||||
// 已稳定部分正常色,不稳定尾部暗色 —— 和 CLI 版渲染一致
|
// 已稳定部分正常色,不稳定尾部暗色 —— 和 CLI 版渲染一致
|
||||||
|
void CaptionWindow::renderCaption()
|
||||||
|
{
|
||||||
const QString html =
|
const QString html =
|
||||||
showTail_
|
showTail_
|
||||||
? QStringLiteral("<div>%1<span style=\"color:#9a9a9a\">%2</span></div>")
|
? QStringLiteral("<div>%1<span style=\"color:#9a9a9a\">%2</span></div>")
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ private:
|
|||||||
int textHeight() const; // 按折叠/展开计算文本区高度
|
int textHeight() const; // 按折叠/展开计算文本区高度
|
||||||
void relayout();
|
void relayout();
|
||||||
void scrollToEnd();
|
void scrollToEnd();
|
||||||
|
void renderCaption(); // 按 showTail_ 重画缓存的文本
|
||||||
void applyStyle();
|
void applyStyle();
|
||||||
|
|
||||||
QPushButton * langPill_ = nullptr;
|
QPushButton * langPill_ = nullptr;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "modeldownloader.h"
|
#include "modeldownloader.h"
|
||||||
#include "modelstore.h"
|
#include "modelstore.h"
|
||||||
|
#include "transcript.h"
|
||||||
|
|
||||||
namespace lc {
|
namespace lc {
|
||||||
|
|
||||||
@@ -77,6 +78,7 @@ SettingsDialog::SettingsDialog(bool firstRun, QWidget * parent)
|
|||||||
|
|
||||||
refreshModelTable();
|
refreshModelTable();
|
||||||
refreshActiveCombo();
|
refreshActiveCombo();
|
||||||
|
rebuildLanguageCombo();
|
||||||
updateStreamGroupEnabled();
|
updateStreamGroupEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,10 +147,8 @@ QWidget * SettingsDialog::buildModelPage()
|
|||||||
form->addRow(tr("当前使用"), activeCombo_);
|
form->addRow(tr("当前使用"), activeCombo_);
|
||||||
|
|
||||||
languageCombo_ = new QComboBox(page);
|
languageCombo_ = new QComboBox(page);
|
||||||
languageCombo_->addItem(tr("自动检测"), QString());
|
languageCombo_->setToolTip(tr("多语言模型(Nemotron / Qwen3-ASR)用它指定语言;"
|
||||||
languageCombo_->addItem(tr("中文"), QStringLiteral("zh"));
|
"列表按所选模型支持的语言变化。"));
|
||||||
languageCombo_->addItem(tr("英文"), QStringLiteral("en"));
|
|
||||||
languageCombo_->addItem(tr("日语"), QStringLiteral("ja"));
|
|
||||||
form->addRow(tr("识别语言"), languageCombo_);
|
form->addRow(tr("识别语言"), languageCombo_);
|
||||||
|
|
||||||
mirrorEdit_ = new QLineEdit(page);
|
mirrorEdit_ = new QLineEdit(page);
|
||||||
@@ -201,14 +201,13 @@ QWidget * SettingsDialog::buildModelPage()
|
|||||||
proxyUser_->setText(cfg.proxyUser);
|
proxyUser_->setText(cfg.proxyUser);
|
||||||
proxyPass_->setText(cfg.proxyPass);
|
proxyPass_->setText(cfg.proxyPass);
|
||||||
updateProxyEnabled();
|
updateProxyEnabled();
|
||||||
languageCombo_->setCurrentIndex(
|
|
||||||
qMax(0, languageCombo_->findData(cfg.language)));
|
|
||||||
|
|
||||||
connect(activeCombo_, &QComboBox::currentIndexChanged, this, [this](int idx) {
|
connect(activeCombo_, &QComboBox::currentIndexChanged, this, [this](int idx) {
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
AppSettings::instance().modelId = activeCombo_->itemData(idx).toString();
|
AppSettings::instance().modelId = activeCombo_->itemData(idx).toString();
|
||||||
AppSettings::instance().save();
|
AppSettings::instance().save();
|
||||||
}
|
}
|
||||||
|
rebuildLanguageCombo(); // 不同模型支持的语言不同
|
||||||
updateStreamGroupEnabled();
|
updateStreamGroupEnabled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -384,6 +383,38 @@ QWidget * SettingsDialog::buildAdvancedPage()
|
|||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 「识别语言」的候选项按**所选模型**支持的语言来填:
|
||||||
|
// 中文模型只给中文,Nemotron 给它的 16 种语言,Qwen3-ASR 给 52 语言里的常用项。
|
||||||
|
// 这样既不会出现「选了模型不支持的语言」,也不会像以前那样只有中/英/日三项。
|
||||||
|
void SettingsDialog::rebuildLanguageCombo()
|
||||||
|
{
|
||||||
|
if (!languageCombo_) return;
|
||||||
|
const QString wanted = (languageCombo_->currentIndex() >= 0)
|
||||||
|
? languageCombo_->currentData().toString()
|
||||||
|
: AppSettings::instance().language;
|
||||||
|
|
||||||
|
QStringList langs;
|
||||||
|
const QString id = (activeCombo_ && activeCombo_->currentIndex() >= 0)
|
||||||
|
? activeCombo_->currentData().toString()
|
||||||
|
: QString();
|
||||||
|
if (const ModelInfo * m = id.isEmpty() ? nullptr : ModelStore::find(id)) {
|
||||||
|
langs = m->languages;
|
||||||
|
}
|
||||||
|
if (langs.isEmpty()) langs = { QStringLiteral("zh"), QStringLiteral("en"), QStringLiteral("ja") };
|
||||||
|
|
||||||
|
languageCombo_->blockSignals(true);
|
||||||
|
languageCombo_->clear();
|
||||||
|
languageCombo_->addItem(tr("自动检测"), QString());
|
||||||
|
for (const QString & code : langs) {
|
||||||
|
if (code == QLatin1String("auto")) continue; // 第一项就是「自动」
|
||||||
|
languageCombo_->addItem(
|
||||||
|
QString::fromStdString(languageDisplayNameFromCode(code.toStdString())), code);
|
||||||
|
}
|
||||||
|
const int idx = languageCombo_->findData(wanted);
|
||||||
|
languageCombo_->setCurrentIndex(idx >= 0 ? idx : 0);
|
||||||
|
languageCombo_->blockSignals(false);
|
||||||
|
}
|
||||||
|
|
||||||
// 流式那一组参数只对 llama 后端(Qwen3-ASR)有意义;
|
// 流式那一组参数只对 llama 后端(Qwen3-ASR)有意义;
|
||||||
// 选了流式 ONNX 模型时置灰,免得改了没效果。
|
// 选了流式 ONNX 模型时置灰,免得改了没效果。
|
||||||
void SettingsDialog::updateStreamGroupEnabled()
|
void SettingsDialog::updateStreamGroupEnabled()
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ private:
|
|||||||
|
|
||||||
void refreshModelTable();
|
void refreshModelTable();
|
||||||
void refreshActiveCombo();
|
void refreshActiveCombo();
|
||||||
|
void rebuildLanguageCombo(); // 按所选模型支持的语言重建语言下拉
|
||||||
void updateStreamGroupEnabled(); // 流式参数只在 llama 后端下可用
|
void updateStreamGroupEnabled(); // 流式参数只在 llama 后端下可用
|
||||||
void onDownload();
|
void onDownload();
|
||||||
void onVerify();
|
void onVerify();
|
||||||
|
|||||||
@@ -42,6 +42,40 @@ private slots:
|
|||||||
QCOMPARE(QString::fromStdString(lc::languageDisplayName("Klingon")), QString("Klingon"));
|
QCOMPARE(QString::fromStdString(lc::languageDisplayName("Klingon")), QString("Klingon"));
|
||||||
QVERIFY(lc::languageDisplayName("").empty());
|
QVERIFY(lc::languageDisplayName("").empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设置里的语言提示是 ISO 码,界面要把它显示成中文名。
|
||||||
|
// 覆盖注册表里出现过的所有语言码,避免加了模型却漏了显示名。
|
||||||
|
void isoCodeDisplayName()
|
||||||
|
{
|
||||||
|
const struct { const char * code; const char * display; } kCases[] = {
|
||||||
|
{ "zh", "中文" }, { "en", "英语" }, { "ja", "日语" },
|
||||||
|
{ "ko", "韩语" }, { "fr", "法语" }, { "de", "德语" },
|
||||||
|
{ "es", "西班牙语" },{ "ru", "俄语" }, { "ar", "阿拉伯语" },
|
||||||
|
{ "hi", "印地语" }, { "vi", "越南语" }, { "it", "意大利语" },
|
||||||
|
{ "pt", "葡萄牙语" },{ "nl", "荷兰语" }, { "tr", "土耳其语" },
|
||||||
|
{ "uk", "乌克兰语" },{ "auto", "自动检测" },
|
||||||
|
};
|
||||||
|
for (const auto & c : kCases) {
|
||||||
|
QCOMPARE(QString::fromStdString(lc::languageDisplayNameFromCode(c.code)),
|
||||||
|
QString::fromUtf8(c.display));
|
||||||
|
}
|
||||||
|
// 未知码原样返回;空串返回空
|
||||||
|
QCOMPARE(QString::fromStdString(lc::languageDisplayNameFromCode("xx")), QString("xx"));
|
||||||
|
QVERIFY(lc::languageDisplayNameFromCode("").empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册表里每个模型声明的语言都必须能显示成中文名,
|
||||||
|
// 否则设置里的「识别语言」下拉会出现英文码。
|
||||||
|
void registryLanguagesAllHaveDisplayNames()
|
||||||
|
{
|
||||||
|
for (const char * code : { "zh", "en", "ja", "ko", "fr", "de", "es", "ru", "ar",
|
||||||
|
"hi", "vi", "it", "pt", "nl", "tr", "uk" }) {
|
||||||
|
const QString display =
|
||||||
|
QString::fromStdString(lc::languageDisplayNameFromCode(code));
|
||||||
|
QVERIFY2(display != QString::fromLatin1(code),
|
||||||
|
qPrintable(QStringLiteral("语言码没有显示名: %1").arg(code)));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
QTEST_MAIN(TstTranscript)
|
QTEST_MAIN(TstTranscript)
|
||||||
|
|||||||
Reference in new issue
Block a user