Add German (de) interface language
New catalog crates/ui-egui/src/i18n/de.rs (266 entries) mirroring the ru.rs key set exactly; original translations written from the meaning of the English UI strings, MIT OR Apache-2.0. - Language::De registered (code de, name Deutsch); de/de-DE/de_AT/de-CH resolve via from_tag - Tests: German coverage in the i18n coverage loop, de/de-AT/de-CH locale tags, ribbon round-trip case, default CJK font-order assertion - Docs: localization-parity.md row, ROADMAP.md languages section cargo test -p gridcraft-ui-egui i18n: 5 passed; --lib: 21 passed; interaction + formula_locale: 13 + 8 passed.
This commit is contained in:
parent
9f896c1249
commit
a44cc8540d
16
ROADMAP.md
16
ROADMAP.md
|
|
@ -62,7 +62,7 @@ collaboration, mobile, AI).
|
|||
| File formats | ~50% | 80–120 | [file-format-parity.md](docs/file-format-parity.md) |
|
||||
| Performance | ~35% | 35–55 | [target-app-parity.md](docs/target-app-parity.md#performance) |
|
||||
| Stability | ~60% | 15–25 | [gaps.md](docs/gaps.md) |
|
||||
| Localization | ~10% (ribbon in 5 languages) | 100–165 | [localization-parity.md](docs/localization-parity.md) |
|
||||
| Localization | ~10% (ribbon in 6 languages) | 100–165 | [localization-parity.md](docs/localization-parity.md) |
|
||||
| Hardware (multi-core calc, GPU, pen, multi-window) | ~40% | 25–40 | [hardware-parity.md](docs/hardware-parity.md) |
|
||||
| Platforms | ~80% (no iOS/Android; ahead on Linux, BSD, RISC-V) | 30–60 | [target-app-parity.md](docs/target-app-parity.md#platforms) |
|
||||
| Ecosystem / add-ins | ~10% (VBA out of scope; own scripts, MCP, CLI) | 25–40 | [target-app-parity.md](docs/target-app-parity.md#ecosystem-and-ai) |
|
||||
|
|
@ -89,11 +89,12 @@ collaboration, mobile, AI).
|
|||
|
||||
## Languages
|
||||
|
||||
The ribbon is translated into Japanese, Simplified Chinese, Korean, Brazilian Portuguese and
|
||||
Russian (266–268 labels each, ~12% of ~2,200 strings; merged 10-10 in #31, #104, #82), the
|
||||
The ribbon is translated into Japanese, Simplified Chinese, Korean, Brazilian Portuguese, Russian
|
||||
and German (266–268 labels each, ~12% of ~2,200 strings; merged 10-10 in #31, #104, #82, German
|
||||
added 10-11), the
|
||||
interface follows the system language, and CJK, Thai and Hebrew text falls back to system fonts
|
||||
(#38). Dialogs, menus and messages are English; formulas and number formats are en-US only. German
|
||||
is in PR #163. Detail: [localization-parity.md](docs/localization-parity.md).
|
||||
(#38). Dialogs, menus and messages are English; formulas and number formats are en-US only.
|
||||
Localized German formulas and numbers are in PR #163. Detail: [localization-parity.md](docs/localization-parity.md).
|
||||
|
||||
| Language | Code | Status | UI strings |
|
||||
|---|---|---|---|
|
||||
|
|
@ -106,11 +107,11 @@ is in PR #163. Detail: [localization-parity.md](docs/localization-parity.md).
|
|||
| Portuguese | pt-BR | menus only | ~12% |
|
||||
| Indonesian | id | none | 0% |
|
||||
| Japanese | ja | menus only | ~12% |
|
||||
| German | de | none (PR #163 open) | 0% |
|
||||
| German | de | menus only | ~12% |
|
||||
| Korean | ko | menus only | ~12% |
|
||||
| Vietnamese | vi | none | 0% |
|
||||
|
||||
Other shipped languages: 1 (Russian, menus only, ~12%).
|
||||
Other shipped languages: 2 (Russian and German, menus only, ~12%).
|
||||
|
||||
## Upcoming
|
||||
|
||||
|
|
@ -131,6 +132,7 @@ Ranked; estimates in Opus 5.5 agent-hours. Detail and the full beta-gate list in
|
|||
|
||||
| Date | What landed |
|
||||
|---|---|
|
||||
| 2026-10-11 | Ribbon translated into German (266 labels; `de`, `de-DE`, `de-AT`, `de-CH` locale tags resolve to German) |
|
||||
| 2026-10-10 | Ribbon translated into Japanese, Chinese, Korean, Brazilian Portuguese and Russian with system-language default (#31, #104, #82); CJK/Thai/Hebrew font fallback (#38); clear messages for encrypted and `.xls` files (#17); smooth line charts (#62). Progress docs restructured to the craftrules standard; full re-measure (this page). Initial ribbon key tips (#43), in-place text box editing (#84), copy as HTML table (#36). ODS and XLSB data import (#100, #101); recalc linear in the number of range formulas (#66); RISC-V Linux build; Flatpak repository on Pages; web cell-commit trap fixed |
|
||||
| 2026-10-09 | Community fixes: spill range operator `A1#`, sheet-scoped names, protection refuses locked-cell edits, Insert/Delete Cells adjust references, `DATE(1900,2,29)`, SUMIF sizing, `ROUND` at 15 digits, `_xlpm.` LAMBDA parameters in XLSX, vertical scrollbar, system appearance, border previews; v0.4.0 |
|
||||
| 2026-10-08 | v0.2.0 and v0.3.0 releases; Flatpak, AppImage zsync, branded DMG; desktop log file; DirectX 12 default on Windows |
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ pub fn handle(app: &mut SheetApp, ctx: &egui::Context, method: &str, p: &Json) -
|
|||
("view.theme", "Display Theme", ""),
|
||||
("view.zoom100", "100%", ""),
|
||||
("ui.dialog", "Open Dialog", ""),
|
||||
("app.language.set", "Interface Language", "{language: \"en\"|\"zh\"|\"ja\"|\"ko\"|\"ru\"|\"pt\"} (alias: code)"),
|
||||
("app.language.set", "Interface Language", "{language: \"en\"|\"zh\"|\"ja\"|\"ko\"|\"ru\"|\"pt\"|\"de\"} (alias: code)"),
|
||||
("app.language.english", "Interface Language: English", ""),
|
||||
("app.language.japanese", "Interface Language: Japanese", ""),
|
||||
] {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
mod de;
|
||||
mod ko;
|
||||
mod pt;
|
||||
mod ru;
|
||||
|
|
@ -26,10 +27,11 @@ pub enum Language {
|
|||
Ru,
|
||||
#[serde(rename = "pt")]
|
||||
PtBr,
|
||||
De,
|
||||
}
|
||||
|
||||
impl Language {
|
||||
pub const ALL: [Self; 7] = [Self::En, Self::Es, Self::Zh, Self::Ja, Self::Ko, Self::Ru, Self::PtBr];
|
||||
pub const ALL: [Self; 8] = [Self::En, Self::Es, Self::Zh, Self::Ja, Self::Ko, Self::Ru, Self::PtBr, Self::De];
|
||||
|
||||
/// The language's own name, shown in the switcher.
|
||||
pub fn name(self) -> &'static str {
|
||||
|
|
@ -41,6 +43,7 @@ impl Language {
|
|||
Self::Ko => "한국어",
|
||||
Self::Ru => "Русский",
|
||||
Self::PtBr => "Português (Brasil)",
|
||||
Self::De => "Deutsch",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,6 +57,7 @@ impl Language {
|
|||
Self::Ko => "ko",
|
||||
Self::Ru => "ru",
|
||||
Self::PtBr => "pt",
|
||||
Self::De => "de",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,6 +74,7 @@ impl Language {
|
|||
"ko" => Some(Self::Ko),
|
||||
"ru" => Some(Self::Ru),
|
||||
"pt" => Some(Self::PtBr),
|
||||
"de" => Some(Self::De),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -103,6 +108,7 @@ impl Language {
|
|||
Self::Ko => ko::translate(text),
|
||||
Self::Ru => ru::translate(text),
|
||||
Self::PtBr => pt::translate(text),
|
||||
Self::De => de::translate(text),
|
||||
};
|
||||
translated.unwrap_or_else(|| text.rsplit_once('|').map_or(text, |(_, label)| label))
|
||||
}
|
||||
|
|
@ -434,12 +440,15 @@ mod tests {
|
|||
assert!(ko::translate(english).is_some_and(|text| !text.is_empty()), "missing Korean: {english}");
|
||||
assert!(ru::translate(english).is_some_and(|text| !text.is_empty()), "missing Russian: {english}");
|
||||
assert!(pt::translate(english).is_some_and(|text| !text.is_empty()), "missing Portuguese: {english}");
|
||||
assert!(de::translate(english).is_some_and(|text| !text.is_empty()), "missing German: {english}");
|
||||
}
|
||||
assert_eq!(Language::Ja.tr("Data"), "データ");
|
||||
assert_eq!(Language::Zh.tr("Data"), "数据");
|
||||
assert_eq!(Language::Ko.tr("Data"), "데이터");
|
||||
assert_eq!(Language::Ru.tr("Data"), "Данные");
|
||||
assert_eq!(Language::PtBr.tr("Data"), "Dados");
|
||||
assert_eq!(Language::De.tr("Data"), "Daten");
|
||||
assert_eq!(Language::De.tr("Sheet1!A1"), "Sheet1!A1");
|
||||
assert_eq!(Language::PtBr.tr("Date"), "Data");
|
||||
assert_eq!(Language::PtBr.tr("Sheet1!A1"), "Sheet1!A1");
|
||||
assert_eq!(Language::Ja.tr("Sheet1!A1"), "Sheet1!A1");
|
||||
|
|
@ -476,7 +485,9 @@ mod tests {
|
|||
assert_eq!(Language::from_tag("zh-Hans-CN"), Some(Language::Zh));
|
||||
assert_eq!(Language::from_tag("ko-KR"), Some(Language::Ko));
|
||||
assert_eq!(Language::from_tag("RU_ru"), Some(Language::Ru));
|
||||
assert_eq!(Language::from_tag("de-DE"), None);
|
||||
assert_eq!(Language::from_tag("de-DE"), Some(Language::De));
|
||||
assert_eq!(Language::from_tag("de_AT"), Some(Language::De));
|
||||
assert_eq!(Language::from_tag("de-CH"), Some(Language::De));
|
||||
assert_eq!(Language::from_tag("pt-BR"), Some(Language::PtBr));
|
||||
assert_eq!(Language::parse("pt"), Some(Language::PtBr));
|
||||
assert_eq!(Language::parse("pt-br"), Some(Language::PtBr));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,274 @@
|
|||
//! German translations for the interface strings in i18n.rs. Labels follow the wording German
|
||||
//! spreadsheet users know; anything absent falls back to English.
|
||||
|
||||
pub(super) fn translate(text: &str) -> Option<&'static str> {
|
||||
Some(match text {
|
||||
"Paste" => "Einfügen",
|
||||
"Paste Values" => "Werte einfügen",
|
||||
"Paste Formulas" => "Formeln einfügen",
|
||||
"Paste Formatting" => "Formatierung einfügen",
|
||||
"Transpose" => "Transponieren",
|
||||
"Paste Link" => "Verknüpfung einfügen",
|
||||
"Paste Special…" => "Inhalte einfügen…",
|
||||
"Cut (⌘X)" => "Ausschneiden (⌘X)",
|
||||
"Copy (⌘C)" => "Kopieren (⌘C)",
|
||||
"Format Painter (double-click to keep it on)" => "Format übertragen (Doppelklick zum Beibehalten)",
|
||||
"Bold (⌘B)" => "Fett (⌘B)",
|
||||
"Italic (⌘I)" => "Kursiv (⌘I)",
|
||||
"Underline (⌘U)" => "Unterstrichen (⌘U)",
|
||||
"Double Underline" => "Doppelt unterstrichen",
|
||||
"Strikethrough" => "Durchgestrichen",
|
||||
"Underline" => "Unterstrichen",
|
||||
"Increase Font Size" => "Schriftgrad vergrößern",
|
||||
"Decrease Font Size" => "Schriftgrad verkleinern",
|
||||
"Wrap Text" => "Zeilenumbruch",
|
||||
"Merge & Center" => "Verbinden und zentrieren",
|
||||
"Merge Cells" => "Zellen verbinden",
|
||||
"Merge Across" => "Zeilenweise verbinden",
|
||||
"Unmerge Cells" => "Zellverbindung aufheben",
|
||||
"Fill Color" => "Füllfarbe",
|
||||
"Font Color" => "Schriftfarbe",
|
||||
"Borders" => "Rahmen",
|
||||
"Top\nAlign" => "Oben\nausrichten",
|
||||
"Middle\nAlign" => "Vertikal\nzentrieren",
|
||||
"Bottom\nAlign" => "Unten\nausrichten",
|
||||
"Left" => "Links",
|
||||
"Right" => "Rechts",
|
||||
"Center" => "Zentriert",
|
||||
"Horizontal" => "Horizontal",
|
||||
"Vertical Text" => "Vertikaler Text",
|
||||
"Decrease Indent" => "Einzug verkleinern",
|
||||
"Increase Indent" => "Einzug vergrößern",
|
||||
"Orientation" => "Ausrichtung",
|
||||
"Angle Counterclockwise" => "Gegen den Uhrzeigersinn neigen",
|
||||
"Angle Clockwise" => "Im Uhrzeigersinn neigen",
|
||||
"Rotate Text Up" => "Text nach oben drehen",
|
||||
"Rotate Text Down" => "Text nach unten drehen",
|
||||
"Accounting Number Format" => "Buchhaltungszahlenformat",
|
||||
"Percent Style" => "Prozentformat",
|
||||
"Comma Style" => "Kommaformat",
|
||||
"Increase Decimal" => "Dezimalstelle hinzufügen",
|
||||
"Decrease Decimal" => "Dezimalstelle entfernen",
|
||||
"More Accounting Formats…" => "Weitere Buchhaltungsformate…",
|
||||
"Conditional\nFormatting" => "Bedingte\nFormatierung",
|
||||
"Conditional Formatting" => "Bedingte Formatierung",
|
||||
"Format\nas Table" => "Als Tabelle\nformatieren",
|
||||
"Cell\nStyles" => "Zell-\nformate",
|
||||
"Format Cells…" => "Zellen formatieren…",
|
||||
"Format Cell Alignment…" => "Zellausrichtung…",
|
||||
"Format\nPane" => "Format-\nbereich",
|
||||
"Format" => "Format",
|
||||
"Insert" => "Einfügen",
|
||||
"Insert Cells…" => "Zellen einfügen…",
|
||||
"Delete" => "Löschen",
|
||||
"Delete Cells…" => "Zellen löschen…",
|
||||
"Insert Sheet Rows" => "Blattzeilen einfügen",
|
||||
"Insert Sheet Columns" => "Blattspalten einfügen",
|
||||
"Delete Sheet Rows" => "Blattzeilen löschen",
|
||||
"Delete Sheet Columns" => "Blattspalten löschen",
|
||||
"Row Height…" => "Zeilenhöhe…",
|
||||
"AutoFit Row Height" => "Zeilenhöhe automatisch anpassen",
|
||||
"Column Width…" => "Spaltenbreite…",
|
||||
"AutoFit Column Width" => "Spaltenbreite automatisch anpassen",
|
||||
"Default Width…" => "Standardbreite…",
|
||||
"Hide Rows" => "Zeilen ausblenden",
|
||||
"Unhide Rows" => "Zeilen einblenden",
|
||||
"Hide Columns" => "Spalten ausblenden",
|
||||
"Unhide Columns" => "Spalten einblenden",
|
||||
"Lock Cell" => "Zelle sperren",
|
||||
"Clear" => "Löschen",
|
||||
"Clear All" => "Alles löschen",
|
||||
"Clear Formats" => "Formate löschen",
|
||||
"Clear Contents" => "Inhalte löschen",
|
||||
"Clear Comments and Notes" => "Kommentare und Notizen löschen",
|
||||
"Clear Hyperlinks" => "Hyperlinks löschen",
|
||||
"AutoSum" => "AutoSumme",
|
||||
"AutoSum (⌘⇧T)" => "AutoSumme (⌘⇧T)",
|
||||
"Flash\nFill" => "Blitz-\nvorschau",
|
||||
"Flash Fill" => "Blitzvorschau",
|
||||
"Fill" => "Ausfüllen",
|
||||
"Clear Print Area" => "Druckbereich aufheben",
|
||||
"Find &\nSelect" => "Suchen und\nAuswählen",
|
||||
"Find…" => "Suchen…",
|
||||
"Replace…" => "Ersetzen…",
|
||||
"Go To…" => "Gehe zu…",
|
||||
"Go To Special…" => "Inhalte auswählen…",
|
||||
"PivotTable" => "PivotTable",
|
||||
"Recommended\nCharts" => "Empfohlene\nDiagramme",
|
||||
"Table" => "Tabelle",
|
||||
"Pictures" => "Bilder",
|
||||
"Shapes" => "Formen",
|
||||
"Icons" => "Symbole",
|
||||
"Text\nBox" => "Text-\nfeld",
|
||||
"Comment" => "Kommentar",
|
||||
"New\nComment" => "Neuer\nKommentar",
|
||||
"New Note" => "Neue Notiz",
|
||||
"Show/Hide Note" => "Notiz anzeigen/ausblenden",
|
||||
"Header &\nFooter" => "Kopf- und\nFußzeile",
|
||||
"Text to\nColumns" => "Text in\nSpalten",
|
||||
"Link" => "Link",
|
||||
"Symbol" => "Symbol",
|
||||
"Sparklines" => "Sparklines",
|
||||
"Header & Footer" => "Kopf- und Fußzeile",
|
||||
"Draw with ink" => "Mit Freihand zeichnen",
|
||||
"Eraser" => "Radierer",
|
||||
"Ink to\nShape" => "Freihand in\nForm umwandeln",
|
||||
"Select\nObjects" => "Objekte\nauswählen",
|
||||
"Themes" => "Designs",
|
||||
"Margins" => "Seitenränder",
|
||||
"Size" => "Größe",
|
||||
"Print\nArea" => "Druck-\nbereich",
|
||||
"Set Print Area" => "Druckbereich festlegen",
|
||||
"Breaks" => "Umbrüche",
|
||||
"Insert Page Break" => "Seitenumbruch einfügen",
|
||||
"Remove Page Break" => "Seitenumbruch entfernen",
|
||||
"Reset All Page Breaks" => "Alle Seitenumbrüche zurücksetzen",
|
||||
"Print\nTitles" => "Druck-\ntitel",
|
||||
"Narrow" => "Schmal",
|
||||
"Wide" => "Breit",
|
||||
"Normal" => "Normal",
|
||||
"Portrait" => "Hochformat",
|
||||
"Landscape" => "Querformat",
|
||||
"Custom Margins…" => "Benutzerdefinierte Seitenränder…",
|
||||
"Insert\nFunction" => "Funktion\neinfügen",
|
||||
"Name\nManager" => "Namens-\nmanager",
|
||||
"Define Name" => "Namen definieren",
|
||||
"Use in Formula" => "In Formel verwenden",
|
||||
"Create from Selection" => "Aus Auswahl erstellen",
|
||||
"Trace Precedents" => "Spur zum Vorgänger",
|
||||
"Trace Dependents" => "Spur zum Nachfolger",
|
||||
"Remove Arrows" => "Pfeile entfernen",
|
||||
"Show Formulas" => "Formeln anzeigen",
|
||||
"Error Checking" => "Fehlerüberprüfung",
|
||||
"Evaluate Formula" => "Formel auswerten",
|
||||
"Watch Window" => "Überwachungsfenster",
|
||||
"Calculation\nOptions" => "Berechnungs-\noptionen",
|
||||
"Calculate Now" => "Jetzt berechnen",
|
||||
"Calculate Sheet" => "Blatt berechnen",
|
||||
"Automatic" => "Automatisch",
|
||||
"Automatic Except for Data Tables" => "Automatisch, außer für Datentabellen",
|
||||
"Manual" => "Manuell",
|
||||
"Sort &\nFilter" => "Sortieren und\nFiltern",
|
||||
"Sort" => "Sortieren",
|
||||
"Sort A to Z" => "Von A bis Z sortieren",
|
||||
"Sort Z to A" => "Von Z bis A sortieren",
|
||||
"Custom Sort…" => "Benutzerdefiniertes Sortieren…",
|
||||
"Filter" => "Filtern",
|
||||
"Reapply" => "Erneut anwenden",
|
||||
"Get Data\n(Text/CSV)" => "Daten abrufen\n(Text/CSV)",
|
||||
"Remove\nDuplicates" => "Duplikate\nentfernen",
|
||||
"Data\nValidation" => "Daten-\nüberprüfung",
|
||||
"Data Validation" => "Datenüberprüfung",
|
||||
"Data Validation…" => "Datenüberprüfung…",
|
||||
"Circle Invalid Data" => "Ungültige Daten einkreisen",
|
||||
"Clear Validation" => "Datenüberprüfung löschen",
|
||||
"Group" => "Gruppieren",
|
||||
"Ungroup" => "Gruppierung aufheben",
|
||||
"Subtotal" => "Teilergebnis",
|
||||
"What-If\nAnalysis" => "Was-wäre-wenn-\nAnalyse",
|
||||
"Data Table…" => "Datentabelle…",
|
||||
"Scenario Manager…" => "Szenario-Manager…",
|
||||
"Goal Seek…" => "Zielwertsuche…",
|
||||
"Spelling" => "Rechtschreibung",
|
||||
"Check\nAccessibility" => "Barrierefreiheit\nprüfen",
|
||||
"Threaded Comments" => "Threadkommentare",
|
||||
"Show\nComments" => "Kommentare\nanzeigen",
|
||||
"Protect\nWorkbook" => "Arbeitsmappe\nschützen",
|
||||
"Unprotect\nSheet" => "Blattschutz\naufheben",
|
||||
"Protect Sheet…" => "Blatt schützen…",
|
||||
"Comments" => "Kommentare",
|
||||
"Notes" => "Notizen",
|
||||
"Page Break\nPreview" => "Seitenumbruch-\nvorschau",
|
||||
"Page\nLayout" => "Seiten-\nlayout",
|
||||
"Formula Bar" => "Formelleiste",
|
||||
"Gridlines" => "Gitternetzlinien",
|
||||
"Headings" => "Überschriften",
|
||||
"Zoom" => "Zoom",
|
||||
"100%" => "100%",
|
||||
"Zoom to\nSelection" => "Zoom auf die\nAuswahl",
|
||||
"Freeze\nPanes" => "Fenster\nfixieren",
|
||||
"Freeze Panes" => "Fenster fixieren",
|
||||
"Freeze Top Row" => "Oberste Zeile fixieren",
|
||||
"Freeze First Column" => "Erste Spalte fixieren",
|
||||
"Unfreeze Panes" => "Fixierung aufheben",
|
||||
"Dark Mode" => "Dunkler Modus",
|
||||
"Interface language" => "Anzeigesprache",
|
||||
"Command\nPalette" => "Befehls-\npalette",
|
||||
"Agent\nControl" => "Agenten-\nsteuerung",
|
||||
"Action\nJournal" => "Aktions-\nprotokoll",
|
||||
"About\nGridCraft" => "Über\nGridCraft",
|
||||
"Share" => "Teilen",
|
||||
"Add Chart\nElement" => "Diagrammelement\nhinzufügen",
|
||||
"Change\nChart Type" => "Diagrammtyp\nändern",
|
||||
"Switch\nRow/Column" => "Zeile/Spalte\nwechseln",
|
||||
"Data Labels: None" => "Datenbeschriftungen: Keine",
|
||||
"Data Labels: Show" => "Datenbeschriftungen: Anzeigen",
|
||||
"Legend: None" => "Legende: Keine",
|
||||
"Legend: Bottom" => "Legende: Unten",
|
||||
"Legend: Top" => "Legende: Oben",
|
||||
"Legend: Right" => "Legende: Rechts",
|
||||
"Gridlines: None" => "Gitternetzlinien: Keine",
|
||||
"Gridlines: Show" => "Gitternetzlinien: Anzeigen",
|
||||
"Chart\nTitle" => "Diagramm-\ntitel",
|
||||
"Delete\nChart" => "Diagramm\nlöschen",
|
||||
"Convert\nto Range" => "In Bereich\nkonvertieren",
|
||||
"Table\nStyles" => "Tabellen-\nformate",
|
||||
"Top 10 Items" => "Obere 10 Elemente",
|
||||
"Top 10%" => "Obere 10 %",
|
||||
"Bottom 10 Items" => "Untere 10 Elemente",
|
||||
"Bottom 10%" => "Untere 10 %",
|
||||
"Above Average" => "Überdurchschnittlich",
|
||||
"Below Average" => "Unterdurchschnittlich",
|
||||
"Clear Rules from Entire Sheet" => "Regeln im gesamten Blatt löschen",
|
||||
"Clear Rules from Selected Cells" => "Regeln in den ausgewählten Zellen löschen",
|
||||
"Constants" => "Konstanten",
|
||||
"Data Bars" => "Datenbalken",
|
||||
"Color Scales" => "Farbskalen",
|
||||
"Icon Sets" => "Symbolsätze",
|
||||
"Home" => "Start",
|
||||
"Draw" => "Zeichnen",
|
||||
"Page Layout" => "Seitenlayout",
|
||||
"Formulas" => "Formeln",
|
||||
"Data" => "Daten",
|
||||
"Review" => "Überprüfen",
|
||||
"View" => "Ansicht",
|
||||
"Automate" => "Automatisieren",
|
||||
"Table Design" => "Tabellenentwurf",
|
||||
"Chart Design" => "Diagrammentwurf",
|
||||
"Ready" => "Bereit",
|
||||
"Enter" => "Eingeben",
|
||||
"Edit" => "Bearbeiten",
|
||||
"Point" => "Zeigen",
|
||||
"Calculate" => "Berechnen",
|
||||
"Select destination and press Enter or choose Paste" => "Ziel auswählen und die Eingabetaste drücken oder „Einfügen“ wählen",
|
||||
"General" => "Standard",
|
||||
"Number" => "Zahl",
|
||||
"Currency" => "Währung",
|
||||
"Accounting" => "Buchhaltung",
|
||||
"Date" => "Datum",
|
||||
"Time" => "Uhrzeit",
|
||||
"Percentage" => "Prozentsatz",
|
||||
"Fraction" => "Bruch",
|
||||
"Scientific" => "Wissenschaftlich",
|
||||
"Text" => "Text",
|
||||
"Special" => "Sonderformat",
|
||||
"Custom" => "Benutzerdefiniert",
|
||||
"Short Date" => "Kurzes Datum",
|
||||
"Long Date" => "Langes Datum",
|
||||
"More Number Formats…" => "Weitere Zahlenformate…",
|
||||
"Financial" => "Finanzmathematik",
|
||||
"Logical" => "Logisch",
|
||||
"Date &\nTime" => "Datum &\nUhrzeit",
|
||||
"Lookup &\nReference" => "Nachschlagen &\nVerweisen",
|
||||
"Math &\nTrig" => "Mathematik &\nTrigonometrie",
|
||||
"More\nFunctions" => "Weitere\nFunktionen",
|
||||
"Page Layout|Orientation" => "Seitenausrichtung",
|
||||
"Display theme" => "Anzeigedesign",
|
||||
"System" => "System",
|
||||
"Light" => "Hell",
|
||||
"Dark" => "Dunkel",
|
||||
"Sheet Options|View" => "Anzeige",
|
||||
"Print" => "Drucken",
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
|
@ -587,7 +587,7 @@ mod tests {
|
|||
assert_eq!(keys(HanOrder::Japanese), ["sys-cjk-han-ja", "sys-cjk-han-zh", "sys-cjk-hangul", "sys-thai", "sys-hebrew"]);
|
||||
assert_eq!(keys(HanOrder::Chinese), ["sys-cjk-han-zh", "sys-cjk-han-ja", "sys-cjk-hangul", "sys-thai", "sys-hebrew"]);
|
||||
assert_eq!(HanOrder::of(Language::Ja), HanOrder::Japanese);
|
||||
for l in [Language::En, Language::Zh, Language::Ko, Language::Ru, Language::PtBr] {
|
||||
for l in [Language::En, Language::Zh, Language::Ko, Language::Ru, Language::PtBr, Language::De] {
|
||||
assert_eq!(HanOrder::of(l), HanOrder::Chinese, "{l:?} shares the default order (no font rebuild)");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ fn language_switch_translates_the_ribbon_and_persists() {
|
|||
assert!(ids.contains(&id), "engine.commands lists {id}");
|
||||
}
|
||||
for (language, expected) in
|
||||
[(Language::Zh, "数据"), (Language::Ja, "データ"), (Language::Ko, "데이터"), (Language::Ru, "Данные"), (Language::PtBr, "Dados")]
|
||||
[(Language::Zh, "数据"), (Language::Ja, "データ"), (Language::Ko, "데이터"), (Language::Ru, "Данные"), (Language::PtBr, "Dados"), (Language::De, "Daten")]
|
||||
{
|
||||
h.state_mut().run("app.language.set", json!({"language": language.code()})).unwrap();
|
||||
h.run_steps(2); // every locale renders the ribbon without panicking
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Localization parity
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** minor (re-measured after the 10-10 language and font-fallback merges) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (German ribbon catalog added) · **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,
|
||||
|
|
@ -10,9 +10,10 @@ right-to-left sheets and full complex-script support. Part of
|
|||
## Where we are (measured from source on `main`, after the 2026-10-10 merges)
|
||||
|
||||
- **A first catalog exists, for the ribbon only.** `crates/ui-egui/src/i18n.rs` (merged 10-10 in
|
||||
#31, #104, #82) adds an interface-language preference that defaults to the system language
|
||||
(closes #20) and a View-tab switcher, with English-keyed lookup tables: Japanese 268 labels,
|
||||
Simplified Chinese, Korean, Russian and Brazilian Portuguese 266 each. The tables are used by
|
||||
#31, #104, #82; German added 10-11) adds an interface-language preference that defaults to the
|
||||
system language (closes #20) and a View-tab switcher, with English-keyed lookup tables:
|
||||
Japanese 268 labels, Simplified Chinese, Korean, Russian, Brazilian Portuguese and German 266
|
||||
each. The tables are used by
|
||||
the ribbon, sheet tabs and widgets (`ribbon.rs`, `tabs.rs`, `widgets.rs`); dialogs, menus,
|
||||
context menus, task panes, status messages, command labels and function descriptions are still
|
||||
English literals. Untranslated labels fall back to English.
|
||||
|
|
@ -47,11 +48,11 @@ separators, number/date formats, machine translation with agent review, and scri
|
|||
| Portuguese | pt-BR | 266 (~12%) | no | Latin: yes | no | menus only | 4–8 h |
|
||||
| Indonesian | id | 0 (0%) | no | Latin: yes | no | none | 5–8 h |
|
||||
| Japanese | ja | 268 (~12%) | no | CJK system-font fallback; IME unverified; no furigana display | no | menus only | 8–12 h |
|
||||
| German | de | 0 (0%; PR #163 open) | no | Latin: yes | no | none | 6–10 h |
|
||||
| German | de | 266 (~12%) | no | Latin: yes | no | menus only | 4–8 h |
|
||||
| Korean | ko | 266 (~12%) | no | Hangul via the CJK fallback; IME unverified | no | menus only | 6–10 h |
|
||||
| Vietnamese | vi | 0 (0%) | no | Latin with stacked diacritics: unverified | no | none | 6–10 h |
|
||||
|
||||
Other shipped languages: Russian (ru), 266 labels (~12%), menus only.
|
||||
Other shipped languages: Russian (ru) and German (de), 266 labels each (~12%), menus only.
|
||||
|
||||
**Total:** catalog work 10–20 h + languages 92–144 h ≈ **100–165 h**. Parallelizes almost fully
|
||||
once the catalog covers dialogs and commands. **Needs a human:** native-speaker review of every
|
||||
|
|
@ -73,5 +74,6 @@ language (none so far) and of localized function names.
|
|||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-11 | minor | German ribbon catalog (`i18n/de.rs`, 266 labels, ~12%); `de` locale tags (de-DE, de-AT, de-CH…) resolve to German. PR #163 (localized German formulas/numbers) still open |
|
||||
| 2026-10-10 | minor | Re-measured after #31, #104, #82, #38 merged: ribbon translated into ja, zh, ko, pt-BR and ru (266–268 labels, ~12%), system-language default, CJK/Thai/Hebrew font fallback; ~10% ready, 100–165 h |
|
||||
| 2026-10-10 | major | Created: English only, no catalog, ~2,200 strings, script-support gaps, open language PRs |
|
||||
|
|
|
|||
Loading…
Reference in New Issue