Merge PR #2102: Romanian (ro) interface language

Conflicts:
- crates/ui-egui/src/i18n.rs: language registration lines kept from both sides (Language::ALL has 18 entries).
- crates/ui-egui/tests/file_menu.rs: both language rows kept.
- docs/localization-parity.md: one Last updated line naming all changes; both revision rows kept, newest first.
This commit is contained in:
aiongg
2026-10-22 02:38:43 +00:00
4 changed files with 1043 additions and 3 deletions
+19 -2
View File
@@ -20,6 +20,7 @@ mod ko;
mod pl;
mod nl;
mod pt;
mod ro;
mod ru;
mod sr;
mod vi;
@@ -48,11 +49,12 @@ pub enum Language {
Uk,
Vi,
Nl,
Ro,
}
impl Language {
pub const ALL: [Self; 17] = [
Self::En, Self::Es, Self::El, Self::Zh, Self::Ja, Self::Ko, Self::Ru, Self::PtBr, Self::De, Self::Cs, Self::Fr, Self::Sr, Self::Pl, Self::It, Self::Uk, Self::Vi, Self::Nl,
pub const ALL: [Self; 18] = [
Self::En, Self::Es, Self::El, Self::Zh, Self::Ja, Self::Ko, Self::Ru, Self::PtBr, Self::De, Self::Cs, Self::Fr, Self::Sr, Self::Pl, Self::It, Self::Uk, Self::Vi, Self::Nl, Self::Ro,
];
/// The language's own name, shown in the switcher.
@@ -75,6 +77,7 @@ impl Language {
Self::Uk => "Українська",
Self::Vi => "Tiếng Việt",
Self::Nl => "Nederlands",
Self::Ro => "Română",
}
}
@@ -98,6 +101,7 @@ impl Language {
Self::Uk => "uk",
Self::Vi => "vi",
Self::Nl => "nl",
Self::Ro => "ro",
}
}
@@ -124,6 +128,7 @@ impl Language {
"uk" => Some(Self::Uk),
"vi" => Some(Self::Vi),
"nl" => Some(Self::Nl),
"ro" => Some(Self::Ro),
_ => None,
}
}
@@ -168,6 +173,7 @@ impl Language {
Self::Uk => uk::translate(text),
Self::Vi => vi::translate(text),
Self::Nl => nl::translate(text),
Self::Ro => ro::translate(text),
};
translated.unwrap_or_else(|| text.rsplit_once('|').map_or(text, |(_, label)| label))
}
@@ -239,6 +245,7 @@ mod tests {
assert!(uk::translate(english).is_some_and(|text| !text.is_empty()), "missing Ukrainian: {english}");
assert!(vi::translate(english).is_some_and(|text| !text.is_empty()), "missing Vietnamese: {english}");
assert!(nl::translate(english).is_some_and(|text| !text.is_empty()), "missing Dutch: {english}");
assert!(ro::translate(english).is_some_and(|text| !text.is_empty()), "missing Romanian: {english}");
}
assert_eq!(Language::Ja.tr("Data"), "データ");
assert_eq!(Language::Zh.tr("Data"), "数据");
@@ -294,6 +301,10 @@ mod tests {
assert_eq!(Language::Nl.tr("Sheet1!A1"), "Sheet1!A1");
assert_eq!(Language::Nl.tr("Page Layout|Orientation"), "Paginastand");
assert_eq!(Language::Nl.tr("Orientation"), "Richting");
assert_eq!(Language::Ro.tr("Data"), "Date");
assert_eq!(Language::Ro.tr("Sheet1!A1"), "Sheet1!A1");
assert_eq!(Language::Ro.tr("Page Layout|Orientation"), "Orientare");
assert_eq!(Language::Ro.tr("Orientation"), "Orientare text");
assert_eq!(Language::parse("xx"), None);
}
@@ -383,6 +394,9 @@ mod tests {
assert_eq!(Language::Nl.tr("Options|General"), "Algemeen");
assert_eq!(Language::Nl.tr("Options|Save"), "Opslaan");
assert_eq!(Language::Nl.tr("Sheet Options|View"), "Weergeven");
assert_eq!(Language::Ro.tr("Options|General"), "General");
assert_eq!(Language::Ro.tr("Options|Save"), "Salvare");
assert_eq!(Language::Ro.tr("Sheet Options|View"), "Vizualizare");
}
#[test]
@@ -439,6 +453,9 @@ mod tests {
assert_eq!(Language::from_tag("nl-NL"), Some(Language::Nl));
assert_eq!(Language::from_tag("nl_BE"), Some(Language::Nl));
assert_eq!(Language::parse("nl"), Some(Language::Nl));
assert_eq!(Language::from_tag("ro-RO"), Some(Language::Ro));
assert_eq!(Language::from_tag("ro_MD.UTF-8"), Some(Language::Ro));
assert_eq!(Language::parse("ro"), Some(Language::Ro));
}
#[test]
File diff suppressed because it is too large Load Diff
+1
View File
@@ -138,6 +138,7 @@ fn translated_options_headings_show_no_context_prefix() {
("fr", ["Général", "Enregistrer"], ["Options|Général", "Options|Enregistrer"], ("Affichage", "Options de la feuille|Affichage")),
("sr", ["Opšte", "Sačuvaj"], ["Opcije|Opšte", "Opcije|Sačuvaj"], ("Prikaz", "Opcije lista|Prikaz")),
("nl", ["Algemeen", "Opslaan"], ["Opties|Algemeen", "Opties|Opslaan"], ("Weergeven", "Bladopties|Weergeven")),
("ro", ["General", "Salvare"], ["Opțiuni|General", "Opțiuni|Salvare"], ("Vizualizare", "Opțiuni foaie|Vizualizare")),
] {
let mut h = harness(Services::default());
h.state_mut().run("app.language.set", serde_json::json!({"language": code})).unwrap();
+2 -1
View File
@@ -1,6 +1,6 @@
# Localization parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-20 · **Change:** minor (the Japanese catalog covers the dialogs, messages and menus; Dutch interface language) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-21 · **Change:** minor (the Japanese catalog covers the dialogs, messages and menus; Dutch interface language; Romanian interface catalog) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
Per-language status against Excel, which ships its UI in dozens of languages (Windows language
packs cover 100+), with localized function names, argument separators, number and date formats,
@@ -85,6 +85,7 @@ language (none so far) and of localized function names.
| Date | Change | Summary |
|---|---|---|
| 2026-10-21 | minor | Romanian interface (`ro`, Română): 970 labels covering every key of the other catalogs (`crates/ui-egui/src/i18n/ro.rs`), `ro-*` system locales, the View-tab switcher and `app.language.set`; context keys show no prefix (File › Options test). English formulas and formats; AI-assisted draft pending native-speaker review |
| 2026-10-20 | minor | Japanese catalog (`i18n/ja.rs`) covers every key the Brazilian Portuguese catalog translates: the 398-label shared core moved verbatim plus 545 dialog, message, Backstage and menu strings — 943 keys, ~12% → ~43%. A test parses `pt.rs`'s source, so the two catalogs can't drift apart again. Portuguese re-measured at 943 (was 923) |
| 2026-10-15 | minor | Italian catalog (`i18n/it.rs`, 971 entries, ~44%): every key the Brazilian Portuguese catalog translates plus the PivotTable Fields pane strings; `it` locale tags (it-IT, it-CH…) resolve to Italian. Labels follow Excel's Italian terminology; native-speaker review still pending |
| 2026-10-20 | minor | Dutch (nl) interface catalog (`i18n/nl.rs`, 518 labels, ~24%): the shared key set every language must cover (ribbon, context menus, File view, dialog titles, Options page), matching the German, French and Czech catalogs; `nl-NL`, `nl-BE` locale tags resolve to Dutch |