i18n: add Brazilian Portuguese (pt-br) UI translation
Add pt-br as a fifth interface language beside English, Simplified
Chinese, Traditional Chinese (Taiwan) and Japanese.
`crates/ui-egui/locales/pt-br.json` and `pt-br-formats.json` carry the
messages and the format strings; the language table gains the entry
(`PtBr, "pt-br", "Português (Brasil)", "Latn", ...`), and Edit > Language
plus `app.language.portuguese` select it. Locale tags pt-BR, pt_BR.UTF-8
and pt all normalize to the same language.
Translation follows pt-BR UI conventions (Adobe terms: revelação,
balanço de branco, máscara, cópia virtual…); proper nouns and file
formats stay as written (LightCraft, ArtCraft, GitHub, DNG, TIFF, XMP).
Placeholders, format specs and punctuation match the English source; the
English plural suffix is consumed with `{:.0}` where Portuguese does not
need it.
Tests: every_language_has_a_catalog_covering_the_source,
catalogs_agree_on_placeholders_and_report_gaps, locale_tags_normalize
and the painted-window test now cover pt-br. Docs: localization.md, a
new localization-pt-br.md and the parity rows.
Co-Authored-By: DeepSeek V4 Flash (opencode) <noreply@opencode.ai>
This commit is contained in:
1 parent
b35487add2
commit
fb01966a00
8 files changed
+1439
-6
No files matched your search
@@ -0,0 +1,122 @@
|
||||
{
|
||||
" ({} in Recently Deleted)": " ({} em Excluídos recentemente)",
|
||||
" · {skipped} skipped (file exists)": " · {skipped} ignorada(s) (arquivo existente)",
|
||||
" · {} duplicate{} skipped": " · {} duplicada{:.0} ignorada",
|
||||
" · {} failed: {}": " · {} falhou: {}",
|
||||
" · {} moved": " · {} movida(s)",
|
||||
" · {} not readable": " · {} não legível",
|
||||
", {failed} file{} not readable": ", {failed} arquivo{:.0} não legível",
|
||||
"Add {local_n} to My Photos": "Adicionar {local_n} a Minhas fotos",
|
||||
"Add {} Photo{}": "Adicionar {} foto{:.0}",
|
||||
"Add “{}” to Favorites": "Adicionar “{}” aos favoritos",
|
||||
"Added {n} photo{} to My Photos": "Adicionada {n} foto{:.0} a Minhas fotos",
|
||||
"Added {n} photo{} to “{}”": "Adicionada {n} foto{:.0} a “{}”",
|
||||
"Adding photos… {} of {}": "Adicionando fotos… {} de {}",
|
||||
"All {n} selected photos move by the same amount.": "Todas as {n} fotos selecionadas se movem pela mesma quantidade.",
|
||||
"Already in the library, in Recently Deleted: {} photo{} selected · right-click ▸ Restore, or Delete Permanently to import afresh": "Já na biblioteca, em Excluídos recentemente: {} foto{:.0} selecionada · clique com o botão direito ▸ Restaurar, ou Excluir permanentemente para importar de novo",
|
||||
"Already in the library: {} photo{} selected in All Photos": "Já na biblioteca: {} foto{:.0} selecionada em Todas as fotos",
|
||||
"Auto ({})": "Automático ({})",
|
||||
"Auto Sync: edits apply to {n} photos": "Sincronização automática: edições aplicadas a {n} fotos",
|
||||
"Automatic ({} MB)": "Automático ({} MB)",
|
||||
"Build 1:1 Previews ({scope})": "Gerar pré-visualizações 1:1 ({scope})",
|
||||
"Build Smart Previews ({scope})": "Gerar pré-visualizações inteligentes ({scope})",
|
||||
"Build Standard-Sized Previews ({scope})": "Gerar pré-visualizações em tamanho padrão ({scope})",
|
||||
"Click {}:1": "Clique em {}:1",
|
||||
"Create {n} Virtual Copies": "Criar {n} cópias virtuais",
|
||||
"Decoder: {reason}": "Decodificador: {reason}",
|
||||
"Delete \"{label}\"": "Excluir \"{label}\"",
|
||||
"Delete \"{label}\" (and the mask)": "Excluir \"{label}\" (e a máscara)",
|
||||
"Delete {n} Photos": "Excluir {n} fotos",
|
||||
"Delete “{current}”": "Excluir “{current}”",
|
||||
"Discard Smart Previews ({scope})": "Descartar pré-visualizações inteligentes ({scope})",
|
||||
"Duplicate \"{label}\"": "Duplicar \"{label}\"",
|
||||
"Example: {example}": "Exemplo: {example}",
|
||||
"Exported {n} photo{}": "Exportada {n} foto{:.0}",
|
||||
"Exported {ok} of {total} photo{}": "Exportadas {ok} de {total} foto{:.0}",
|
||||
"Exported {} point curve preset{}": "Exportadas {} predefinição{:.0} de curva de pontos",
|
||||
"Exported {} preset{}": "Exportadas {} predefinição{:.0}",
|
||||
"Exporting {} of {total}": "Exportando {} de {total}",
|
||||
"Filter bar — {active} active filter{}": "Barra de filtros — {active} filtro{:.0} ativo",
|
||||
"Healed {n} dust spot{}": "Recuperadas {n} mancha{:.0} de poeira",
|
||||
"Import cancelled · {} photo{} added": "Importação cancelada · {} foto{:.0} adicionada",
|
||||
"Imported {n} point curve preset{}": "Importadas {n} predefinição{:.0} de curva de pontos",
|
||||
"Imported {n} preset{}": "Importadas {n} predefinição{:.0}",
|
||||
"Imported {n} preset{}, {f} file{} not readable": "Importadas {n} predefinição{:.0}, {f} arquivo{:.0} não legível",
|
||||
"Imported {} photo{}": "Importadas {} foto{:.0}",
|
||||
"Label Set: {name}": "Conjunto de rótulos: {name}",
|
||||
"Matches: {}": "Correspondências: {}",
|
||||
"Merging… {stage} {:.0}%": "Mesclando… {stage} {:.0}%",
|
||||
"Move {what} to Recently Deleted?": "Mover {what} para Excluídos recentemente?",
|
||||
"Named ({named_n})": "Nomeadas ({named_n})",
|
||||
"Paste into {n} photo{} — only settings that were copied are pasted": "Colar em {n} foto{:.0} — somente os ajustes copiados são colados",
|
||||
"Preset: {name}": "Predefinição: {name}",
|
||||
"Preview only — editing the camera's embedded JPEG ({})": "Somente pré-visualização — editando o JPEG incorporado da câmera ({})",
|
||||
"Preview only — {}": "Somente pré-visualização — {}",
|
||||
"Profile: {}": "Perfil: {}",
|
||||
"Proof Copy ({})": "Cópia de prova ({})",
|
||||
"Proof Preview · {}": "Pré-visualização de prova · {}",
|
||||
"Quick Develop · {n} photos": "Revelação rápida · {n} fotos",
|
||||
"Quick Develop: {name}": "Revelação rápida: {name}",
|
||||
"Rated {}": "Avaliada {}",
|
||||
"Reading photos… {done} of {total}": "Lendo fotos… {done} de {total}",
|
||||
"Reading photos… {} of {}": "Lendo fotos… {} de {}",
|
||||
"Redo {}": "Refazer {}",
|
||||
"Remove “{}” from Favorites": "Remover “{}” dos favoritos",
|
||||
"Rename {n} Photos…": "Renomear {n} fotos…",
|
||||
"Rename “{name}”": "Renomear “{name}”",
|
||||
"Rendering on the CPU: {why}": "Renderizando na CPU: {why}",
|
||||
"Reset {name}": "Redefinir {name}",
|
||||
"Reset {} Channel": "Redefinir canal {}",
|
||||
"Saved export preset “{}”": "Predefinição de exportação “{}” salva",
|
||||
"Show {hidden} hidden location{}": "Mostrar {hidden} local{:.0} oculto",
|
||||
"Showing {n} of {}": "Mostrando {n} de {}",
|
||||
"Smart album: {}": "Álbum inteligente: {}",
|
||||
"Undo {}": "Desfazer {}",
|
||||
"Updated “{name}”": "“{name}” atualizado",
|
||||
"Version {} — a clean-room, pure-Rust photo library and raw developer.": "Versão {} — uma biblioteca de fotos e revelador RAW em Rust puro, desenvolvida de forma independente.",
|
||||
"Version: {}": "Versão: {}",
|
||||
"none (CPU rendering): {why}": "nenhum (renderização na CPU): {why}",
|
||||
"the {n} selected photos": "as {n} fotos selecionadas",
|
||||
"the {} photos in view": "as {} fotos em exibição",
|
||||
"these {count} photos": "estas {count} fotos",
|
||||
"{count} smart preview{} · {:.1} MB": "{count} pré-visualizações{:.0} · {:.1} MB",
|
||||
"{f} folders (and their subfolders)": "{f} pastas (e suas subpastas)",
|
||||
"{label} Grading": "Graduação de {label}",
|
||||
"{label} {d:+} on every selected photo": "{label} {d:+} em cada foto selecionada",
|
||||
"{label}, {n} photos": "{label}, {n} fotos",
|
||||
"{matching} of {t} photos": "{matching} de {t} fotos",
|
||||
"{matching} photos": "{matching} fotos",
|
||||
"{mode} spot {} of {}": "{mode}: ponto {} de {}",
|
||||
"{month}": "{month}",
|
||||
"{month} {year}": "{month}/{year}",
|
||||
"{msg} ({failed} failed)": "{msg} ({failed} com falha)",
|
||||
"{name} Label": "Rótulo {name}",
|
||||
"{name} Off": "{name} desativado",
|
||||
"{name} On": "{name} ativado",
|
||||
"{name} — double-click to reset it": "{name} — clique duas vezes para redefinir",
|
||||
"{n} change{} saved in memory but not written to disk: {e}\nLightCraft retries automatically; quitting now would lose {}.": "{n} alteração{:.0} salva na memória mas não gravada no disco: {e}\nO LightCraft tenta novamente automaticamente; encerrar agora perderia {}.",
|
||||
"{n} found · {sel} selected": "{n} encontradas · {sel} selecionadas",
|
||||
"{n} photos": "{n} fotos",
|
||||
"{n} photos in {} are hidden by the filters above": "{n} fotos em {} estão ocultas pelos filtros acima",
|
||||
"{n} photo{}": "{n} foto{:.0}",
|
||||
"{n} photo{} match · updates automatically as photos change": "{n} foto{:.0} correspondente(s) · atualiza automaticamente conforme as fotos mudam",
|
||||
"{n} photo{} now · updates automatically as photos change": "{n} foto{:.0} agora · atualiza automaticamente conforme as fotos mudam",
|
||||
"{sel_n} selected · {counted}": "{sel_n} selecionadas · {counted}",
|
||||
"{stage}… {:.0}%": "{stage}… {:.0}%",
|
||||
"{verb} {n} Photo{}": "{verb} {n} foto{:.0}",
|
||||
"{weekday}, {day}": "{weekday}, {day}",
|
||||
"{weekday}, {day} {month} {year}": "{weekday}, {day}/{month}/{year}",
|
||||
"{what} merge added": "{what} mesclagem adicionada",
|
||||
"{what} merge failed: {e}": "{what} falha na mesclagem: {e}",
|
||||
"{year}": "{year}",
|
||||
"{} and higher": "{} ou superior",
|
||||
"{} files": "{} arquivos",
|
||||
"{} files and {f} folder{}": "{} arquivos e {f} pasta{:.0}",
|
||||
"{} of 4 guides — drag along lines that should be vertical or horizontal.": "{} de 4 guias — arraste ao longo das linhas que devem ficar verticais ou horizontais.",
|
||||
"{} photos": "{} fotos",
|
||||
"{} photo{} not readable": "{} foto{:.0} não legível",
|
||||
"{} spot(s) on this photo": "{} ponto(s) nesta foto",
|
||||
"· {dups} already in the library": "· {dups} já na biblioteca",
|
||||
"· {n} photo{}": "· {n} foto{:.0}",
|
||||
"… and {more} more": "… e mais {more}"
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -120,6 +120,7 @@ language_table! {
|
||||
ZhHans, "zh-hans", "简体中文", "Hans", include_str!("../locales/zh-hans.json");
|
||||
ZhHant, "zh-hant", "繁體中文(台灣)", "Hant", include_str!("../locales/zh-hant.json");
|
||||
Ja, "ja", "日本語", "Jpan", include_str!("../locales/ja.json");
|
||||
PtBr, "pt-br", "Português (Brasil)", "Latn", include_str!("../locales/pt-br.json");
|
||||
}
|
||||
|
||||
// The settings file stores the BCP-47 code (`"zh-hans"`), never the Rust variant name, so a
|
||||
@@ -339,6 +340,10 @@ mod tests {
|
||||
assert_eq!(Locale::parse_tag("zh-Hant-TW"), Some(Locale::ZhHant));
|
||||
assert_eq!(Locale::parse_tag("zh-CN"), Some(Locale::ZhHans));
|
||||
assert_eq!(Locale::parse_tag("ja_JP.UTF-8"), Some(Locale::Ja));
|
||||
assert_eq!(Locale::parse_tag("pt-br"), Some(Locale::PtBr));
|
||||
assert_eq!(Locale::parse_tag("pt-BR"), Some(Locale::PtBr));
|
||||
assert_eq!(Locale::parse_tag("pt_BR.UTF-8"), Some(Locale::PtBr));
|
||||
assert_eq!(Locale::parse_tag("pt"), Some(Locale::PtBr));
|
||||
assert_eq!(Locale::parse_tag("de"), None);
|
||||
}
|
||||
|
||||
@@ -353,6 +358,9 @@ mod tests {
|
||||
assert_eq!(tr("A string no catalog has"), "A string no catalog has");
|
||||
set_language(Locale::Ja);
|
||||
assert_eq!(tr("Exposure"), "露出");
|
||||
set_language(Locale::PtBr);
|
||||
assert_eq!(tr("Exposure"), "Exposição");
|
||||
assert_eq!(tr("Settings"), "Configurações");
|
||||
set_language(Locale::En);
|
||||
assert_eq!(tr("Exposure"), "Exposure");
|
||||
}
|
||||
@@ -457,6 +465,7 @@ mod tests {
|
||||
("app.language.english", Locale::En),
|
||||
("app.language.simplifiedChinese", Locale::ZhHans),
|
||||
("app.language.japanese", Locale::Ja),
|
||||
("app.language.portuguese", Locale::PtBr),
|
||||
];
|
||||
// One command per language, and every command reachable from the menu table.
|
||||
assert_eq!(commands.len(), Locale::ALL.len());
|
||||
@@ -559,6 +568,8 @@ mod tests {
|
||||
assert!(text.contains("マイフォト") && text.contains("すべての写真"), "{text}");
|
||||
let text = painted_text(&ctx, &mut app, Locale::ZhHans);
|
||||
assert!(text.contains("我的照片") && text.contains("所有照片"), "{text}");
|
||||
let text = painted_text(&ctx, &mut app, Locale::PtBr);
|
||||
assert!(text.contains("Minhas fotos") && text.contains("Todas as fotos"), "{text}");
|
||||
set_language(Locale::En);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ pub const LANGUAGE_COMMANDS: &[UiCommand] = &[
|
||||
("app.language.simplifiedChinese", crate::i18n::Locale::ZhHans.name(), None, "Edit>Language"),
|
||||
("app.language.traditionalChinese", crate::i18n::Locale::ZhHant.name(), None, "Edit>Language"),
|
||||
("app.language.japanese", crate::i18n::Locale::Ja.name(), None, "Edit>Language"),
|
||||
("app.language.portuguese", crate::i18n::Locale::PtBr.name(), None, "Edit>Language"),
|
||||
];
|
||||
|
||||
/// Every UI command: the languages, then everything else. `xtask parity` reads both tables from
|
||||
@@ -33,6 +34,7 @@ pub fn language_from_command(id: &str) -> Option<crate::i18n::Locale> {
|
||||
"app.language.simplifiedChinese" => Some(crate::i18n::Locale::ZhHans),
|
||||
"app.language.traditionalChinese" => Some(crate::i18n::Locale::ZhHant),
|
||||
"app.language.japanese" => Some(crate::i18n::Locale::Ja),
|
||||
"app.language.portuguese" => Some(crate::i18n::Locale::PtBr),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# LightCraft em português do Brasil
|
||||
|
||||
O LightCraft pode ser exibido em inglês, chinês simplificado, chinês tradicional (Taiwan), japonês e
|
||||
português do Brasil. A preferência de idioma é gravada em `language` no `ui.json`.
|
||||
|
||||
- Troque em **Editar → Idioma** ou em **Configurações → Geral → Idioma**. A escolha é mantida nas
|
||||
próximas inicializações.
|
||||
- Traduzimos menus, edição de fotos, máscaras, recorte, configurações, importação, exportação e as
|
||||
principais mensagens de progresso.
|
||||
- Menus, telas e o texto com valores variáveis usam as fontes Inter (regular e semibold). Texto em
|
||||
chinês e japonês exibido nos nomes de idioma (por exemplo, 日本語) continua dependendo do repositório
|
||||
de fontes [storytold/craft-fonts](https://github.com/storytold/craft-fonts).
|
||||
- A tradução fica na camada de apresentação. IDs de comandos, nomes de arquivos de fotos e metadados
|
||||
digitados pelo usuário nunca são alterados.
|
||||
- Erros técnicos, informações complementares e notas de versão não traduzidos aparecem em inglês.
|
||||
- A tradução para chinês está em [`localization-zh-hans.md`](localization-zh-hans.md); para japonês,
|
||||
em [`localization-ja.md`](localization-ja.md). Como adicionar outro idioma está em
|
||||
[`localization.md`](localization.md).
|
||||
|
||||
## Manutenção da tradução
|
||||
|
||||
Os textos fixos ficam em `crates/ui-egui/locales/pt-br.json` e os textos com valores variáveis em
|
||||
`crates/ui-egui/locales/pt-br-formats.json`. O inglês é usado como chave.
|
||||
|
||||
Toda tradução de formato é verificada por `format!` do Rust no build. Referencie os valores por nome
|
||||
(`{n}`) ou por posição (`{0}`, `{1}`) e use as mesmas especificações de formato do inglês
|
||||
(`{:.1}`, `{d:+}`, `{:.0}%`). Quando o plural inglês (`"s"` / `""`) não for necessário em português,
|
||||
consuma o argumento correspondente com `{:.0}` — um texto com precisão 0 não imprime nada.
|
||||
|
||||
Aparência, fontes, troca de idioma, persistência da preferência e estabilidade dos IDs de comando são
|
||||
verificadas por `cargo test -p lightcraft-ui-egui i18n::tests` (a checagem de glifos só roda com
|
||||
`CRAFT_FONTS_DIR`). Para visualizar o idioma, renderize sem interface gráfica:
|
||||
|
||||
```sh
|
||||
LIGHTCRAFT_LANGUAGE=pt-br lightcraft-cli snapshot --demo --script tour.jsonl -o out.png --size 1600x1000
|
||||
```
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
The interface ships in the language it is written in (English) plus every language in the table in
|
||||
`crates/ui-egui/src/i18n.rs`. Today that is English, Simplified Chinese (`zh-hans`), Traditional
|
||||
Chinese (`zh-hant`, Taiwan) and Japanese (`ja`). This file is the reference for **adding or maintaining a language**; the per-language notes
|
||||
are in [`localization-zh-hans.md`](localization-zh-hans.md), [`localization-zh-hant.md`](localization-zh-hant.md) and
|
||||
[`localization-ja.md`](localization-ja.md).
|
||||
Chinese (`zh-hant`, Taiwan), Japanese (`ja`) and Brazilian Portuguese (`pt-br`). This file is the reference for **adding or maintaining a language**; the per-language notes
|
||||
are in [`localization-zh-hans.md`](localization-zh-hans.md), [`localization-zh-hant.md`](localization-zh-hant.md),
|
||||
[`localization-ja.md`](localization-ja.md) and [`localization-pt-br.md`](localization-pt-br.md).
|
||||
|
||||
## Adding a language
|
||||
|
||||
@@ -24,6 +24,7 @@ are in [`localization-zh-hans.md`](localization-zh-hans.md), [`localization-zh-h
|
||||
ZhHans, "zh-hans", "简体中文", "Hans", include_str!("../locales/zh-hans.json");
|
||||
ZhHant, "zh-hant", "繁體中文(台灣)", "Hant", include_str!("../locales/zh-hant.json");
|
||||
Ja, "ja", "日本語", "Jpan", include_str!("../locales/ja.json");
|
||||
PtBr, "pt-br", "Português (Brasil)", "Latn", include_str!("../locales/pt-br.json");
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+2
-2
@@ -505,8 +505,8 @@ under the UI command that wraps it (a no-op error); the UI command now wins.
|
||||
| LR-BEHAV-EMPTY-STATES | Empty states | P1 | ✅ | `crates/ui-egui/src/panels/mod.rs` (`empty_message`) | |
|
||||
| LR-BEHAV-TOOLTIPS | Tooltips with shortcuts | P0 | ✅ | `crates/ui-egui/src/panels/bottombar.rs` | |
|
||||
| LR-BEHAV-ACCESS | Accessibility | P2 | 🟡 | `crates/ui-egui/src/widgets.rs`, `crates/ui-egui/src/panels/grid.rs` | AccessKit (VoiceOver / Narrator / AT-SPI): sliders announce control and value, buttons / icon buttons / dropdowns / section headers / sources their labels and state, grid thumbnails file name, rating, flag and label; the canvas tools (crop, masks) are pointer-only; not audited with a screen reader |
|
||||
| LR-BEHAV-LOCALE | Language options | P2 | ✅ | `cmd:app.language.english`, `cmd:app.language.simplifiedChinese`, `cmd:app.language.traditionalChinese`, `cmd:app.language.japanese` | Edit > Language lists every language in the table and the active one is checked; shared with Settings > General (docs/localization.md) |
|
||||
| LR-BEHAV-LOCALIZE | Localisation | P2 | 🟡 | `crates/ui-egui/src/i18n.rs`, `crates/ui-egui/locales/`, `docs/localization.md`, `docs/localization-zh-hans.md`, `docs/localization-zh-hant.md`, `docs/localization-ja.md` | One table entry per language (code, endonym, ISO 15924 script, catalog): English, Simplified Chinese, Traditional Chinese (Taiwan) and Japanese UI with a persisted language preference and craft-fonts regular/bold faces per script; menus, edit, crop/masks, settings, import/export and primary progress messages. Adding a language is a table entry plus two catalogs. Stock presets/profiles, history steps, library headings, date headings and capture times are localised (user-named items stay verbatim); the Traditional Chinese catalog is the most complete, the others fall back to English for messages they lack. Technical errors/release notes remain English; Traditional Chinese borrows the Simplified Chinese face (no TC face in craft-fonts yet), and the web build embeds only the Japanese face. |
|
||||
| LR-BEHAV-LOCALE | Language options | P2 | ✅ | `cmd:app.language.english`, `cmd:app.language.simplifiedChinese`, `cmd:app.language.traditionalChinese`, `cmd:app.language.japanese`, `cmd:app.language.portuguese` | Edit > Language lists every language in the table and the active one is checked; shared with Settings > General (docs/localization.md) |
|
||||
| LR-BEHAV-LOCALIZE | Localisation | P2 | 🟡 | `crates/ui-egui/src/i18n.rs`, `crates/ui-egui/locales/`, `docs/localization.md`, `docs/localization-zh-hans.md`, `docs/localization-zh-hant.md`, `docs/localization-ja.md`, `docs/localization-pt-br.md` | One table entry per language (code, endonym, ISO 15924 script, catalog): English, Simplified Chinese, Traditional Chinese (Taiwan), Japanese and Brazilian Portuguese UI with a persisted language preference and craft-fonts regular/bold faces per script; menus, edit, crop/masks, settings, import/export and primary progress messages. Adding a language is a table entry plus two catalogs. Stock presets/profiles, history steps, library headings, date headings and capture times are localised (user-named items stay verbatim); the Traditional Chinese catalog is the most complete, the others fall back to English for messages they lack. Technical errors/release notes remain English; Traditional Chinese borrows the Simplified Chinese face (no TC face in craft-fonts yet), and the web build embeds only the Japanese face. |
|
||||
| LR-BEHAV-LEARN | Tutorials | OOS | 🚫 | | |
|
||||
| LR-BEHAV-WHATSNEW | What's new | P2 | ✅ | `cmd:app.whatsNew`, `docs/whats-new.md` | Help ▸ What's New: release highlights |
|
||||
| LR-BEHAV-AI-EA | Early-access badges | P2 | ⬜ | | |
|
||||
|
||||
+1
-1
@@ -452,7 +452,7 @@ old
|
||||
fn reads_the_language_commands_from_menus_rs() {
|
||||
let menus = include_str!("../../crates/ui-egui/src/menus.rs");
|
||||
let ids = ui_command_ids(menus);
|
||||
for id in ["view.detail", "app.language.english", "app.language.japanese", "app.language.simplifiedChinese"] {
|
||||
for id in ["view.detail", "app.language.english", "app.language.japanese", "app.language.simplifiedChinese", "app.language.portuguese"] {
|
||||
assert!(ids.iter().any(|known| known == id), "{id} not found");
|
||||
}
|
||||
assert_eq!(ids.iter().filter(|id| id.as_str() == "app.language.english").count(), 1, "one Language menu entry per language");
|
||||
|
||||
Reference in new issue
Block a user