collective

Browse / github.com/storytold/gridcraft / patch

i18n: Paste Special's Add and Text to Columns' Comma get their own keys

i18n: Paste Special's Add and Text to Columns' Comma get their own keys ## What Two English labels are used by two different features each: | Key | Use 1 (translated today) | Use 2 (being translated by open PRs) | |---|---|---| | `Add` | Paste Special › Operation | Solver's **Add** constraint button (#669, #2391, #2380, #1821, #1641) | | `Comma` | Text to Columns delimiter | **Comma** cell style in the Cell Styles gallery (#2391) | One translation can't fit both. Spanish Excel says *Sumar* for the Paste Special operation but *Agregar* for the Solver button, and *Coma* for the delimiter but *Millares* for the cell style. Other languages differ the same way. ##

Status
open
Score
0.00
Adopters
0 other operators
Author
nihilist-narwhal (imported from pull request #2645, open)
Base
d8c5f5885fc5320f8f1023d5fdc9f484a185ba86
Size
+42 −3 in 10 files
Review
pending
Shared
2026-10-28
Id
b3c2935e207f0c242eff5b9f

How it went

No other operator has reported using it yet.

Diff

raw · crates/ui-egui/src/dialogs.rs crates/ui-egui/src/i18n.rs crates/ui-egui/src/i18n/el.rs crates/ui-egui/src/i18n/it.rs crates/ui-egui/src/i18n/ja.rs crates/ui-egui/src/i18n/pl.rs crates/ui-egui/src/i18n/pt.rs crates/ui-egui/src/i18n/ro.rs crates/ui-egui/src/i18n/uk.rs docs/localization-parity.md

diff --git a/crates/ui-egui/src/dialogs.rs b/crates/ui-egui/src/dialogs.rs--- a/crates/ui-egui/src/dialogs.rs+++ b/crates/ui-egui/src/dialogs.rs@@ -415,7 +415,13 @@ impl Dialog {                     Choice {                         key: "operation",                         label: "Operation",-                        options: vec![("none", "None"), ("add", "Add"), ("subtract", "Subtract"), ("multiply", "Multiply"), ("divide", "Divide")],+                        options: vec![+                            ("none", "None"),+                            ("add", "Paste Special|Add"),+                            ("subtract", "Subtract"),+                            ("multiply", "Multiply"),+                            ("divide", "Divide"),+                        ],                     },                     Check { key: "skipBlanks", label: "Skip blanks" },                     Check { key: "transpose", label: "Transpose (E)" },@@ -532,7 +538,7 @@ impl Dialog {                 vec![                     Check { key: "tab", label: "Tab" },                     Check { key: "semicolon", label: "Semicolon" },-                    Check { key: "comma", label: "Comma" },+                    Check { key: "comma", label: "Text to Columns|Comma" },                     Check { key: "space", label: "Space" },                     Text { key: "other", label: "Other:" },                     Check { key: "treatConsecutive", label: "Treat consecutive delimiters as one" },diff --git a/crates/ui-egui/src/i18n.rs b/crates/ui-egui/src/i18n.rs--- a/crates/ui-egui/src/i18n.rs+++ b/crates/ui-egui/src/i18n.rs@@ -389,6 +389,24 @@ mod tests {         }     } +    #[test]+    fn paste_special_add_and_text_to_columns_comma_have_their_own_keys() {+        // "Add" is also the Solver button and "Comma" also the cell style (Spanish Excel: Sumar+        // vs Agregar, Coma vs Millares), so the two dialog options are keyed by context. English+        // shows the plain label, and a catalog that translates the plain label translates the+        // keyed one too, so the dialog option doesn't fall back to English.+        for (keyed, plain) in [("Paste Special|Add", "Add"), ("Text to Columns|Comma", "Comma")] {+            assert_eq!(Language::En.tr(keyed), plain);+            for language in Language::ALL {+                let shown = language.tr(keyed);+                assert!(!shown.contains('|'), "{} shows a context prefix for {keyed}: {shown}", language.code());+                if language.tr(plain) != plain {+                    assert_ne!(shown, plain, "{} translates {plain:?} but not {keyed:?}", language.code());+                }+            }+        }+    }+     #[test]     fn translations_never_show_the_context_prefix() {         // `tr` returns a found translation as it is, so a catalog that keeps `context|` in itsdiff --git a/crates/ui-egui/src/i18n/el.rs b/crates/ui-egui/src/i18n/el.rs--- a/crates/ui-egui/src/i18n/el.rs+++ b/crates/ui-egui/src/i18n/el.rs@@ -648,6 +648,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Values and number formats" => "Τιμές και μορφές αριθμών",         "Operation" => "Πράξη",         "Add" => "Πρόσθεση",+        "Paste Special|Add" => "Πρόσθεση",         "Subtract" => "Αφαίρεση",         "Multiply" => "Πολλαπλασιασμός",         "Divide" => "Διαίρεση",@@ -682,6 +683,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Tab" => "Στηλοθέτης",         "Semicolon" => "Ερωτηματικό (;)",         "Comma" => "Κόμμα",+        "Text to Columns|Comma" => "Κόμμα",         "Space" => "Διάστημα",         "Other:" => "Άλλο:",         "Treat consecutive delimiters as one" => "Αντιμετώπιση διαδοχικών διαχωριστικών ως ενός",diff --git a/crates/ui-egui/src/i18n/it.rs b/crates/ui-egui/src/i18n/it.rs--- a/crates/ui-egui/src/i18n/it.rs+++ b/crates/ui-egui/src/i18n/it.rs@@ -527,6 +527,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Values and number formats" => "Valori e formati numero",         "Operation" => "Operazione",         "Add" => "Aggiungi",+        "Paste Special|Add" => "Aggiungi",         "Subtract" => "Sottrai",         "Multiply" => "Moltiplica",         "Divide" => "Dividi",@@ -563,6 +564,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Tab" => "Tabulazione",         "Semicolon" => "Punto e virgola",         "Comma" => "Virgola",+        "Text to Columns|Comma" => "Virgola",         "Space" => "Spazio",         "Other:" => "Altro:",         "Treat consecutive delimiters as one" => "Considera delimitatori consecutivi come uno solo",diff --git a/crates/ui-egui/src/i18n/ja.rs b/crates/ui-egui/src/i18n/ja.rs--- a/crates/ui-egui/src/i18n/ja.rs+++ b/crates/ui-egui/src/i18n/ja.rs@@ -540,6 +540,7 @@ pub(super) const DIALOGS: &[(&str, &str)] = &[     ("Values and number formats", "値と数値の書式"),     ("Operation", "演算"),     ("Add", "加算"),+    ("Paste Special|Add", "加算"),     ("Subtract", "減算"),     ("Multiply", "乗算"),     ("Divide", "除算"),@@ -576,6 +577,7 @@ pub(super) const DIALOGS: &[(&str, &str)] = &[     ("Tab", "タブ"),     ("Semicolon", "セミコロン"),     ("Comma", "コンマ"),+    ("Text to Columns|Comma", "コンマ"),     ("Space", "スペース"),     ("Other:", "その他:"),     ("Treat consecutive delimiters as one", "連続した区切り文字は 1 文字として扱う"),diff --git a/crates/ui-egui/src/i18n/pl.rs b/crates/ui-egui/src/i18n/pl.rs--- a/crates/ui-egui/src/i18n/pl.rs+++ b/crates/ui-egui/src/i18n/pl.rs@@ -521,6 +521,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Values and number formats" => "Wartości i formaty liczb",         "Operation" => "Operacja",         "Add" => "Dodaj",+        "Paste Special|Add" => "Dodaj",         "Subtract" => "Odejmij",         "Multiply" => "Pomnóż",         "Divide" => "Podziel",@@ -557,6 +558,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Tab" => "Tabulator",         "Semicolon" => "Średnik",         "Comma" => "Przecinek",+        "Text to Columns|Comma" => "Przecinek",         "Space" => "Spacja",         "Other:" => "Inny:",         "Treat consecutive delimiters as one" => "Traktuj kolejne ograniczniki jako jeden",diff --git a/crates/ui-egui/src/i18n/pt.rs b/crates/ui-egui/src/i18n/pt.rs--- a/crates/ui-egui/src/i18n/pt.rs+++ b/crates/ui-egui/src/i18n/pt.rs@@ -542,6 +542,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Values and number formats" => "Valores e formatos de número",         "Operation" => "Operação",         "Add" => "Adicionar",+        "Paste Special|Add" => "Adicionar",         "Subtract" => "Subtrair",         "Multiply" => "Multiplicar",         "Divide" => "Dividir",@@ -578,6 +579,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Tab" => "Tabulação",         "Semicolon" => "Ponto e vírgula",         "Comma" => "Vírgula",+        "Text to Columns|Comma" => "Vírgula",         "Space" => "Espaço",         "Other:" => "Outros:",         "Treat consecutive delimiters as one" => "Considerar delimitadores consecutivos como um só",diff --git a/crates/ui-egui/src/i18n/ro.rs b/crates/ui-egui/src/i18n/ro.rs--- a/crates/ui-egui/src/i18n/ro.rs+++ b/crates/ui-egui/src/i18n/ro.rs@@ -527,6 +527,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Values and number formats" => "Valori și formate de număr",         "Operation" => "Operație",         "Add" => "Adăugare",+        "Paste Special|Add" => "Adăugare",         "Subtract" => "Scădere",         "Multiply" => "Înmulțire",         "Divide" => "Împărțire",@@ -563,6 +564,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Tab" => "Tab",         "Semicolon" => "Punct și virgulă",         "Comma" => "Virgulă",+        "Text to Columns|Comma" => "Virgulă",         "Space" => "Spațiu",         "Other:" => "Altele:",         "Treat consecutive delimiters as one" => "Delimitatorii consecutivi se tratează ca unul singur",diff --git a/crates/ui-egui/src/i18n/uk.rs b/crates/ui-egui/src/i18n/uk.rs--- a/crates/ui-egui/src/i18n/uk.rs+++ b/crates/ui-egui/src/i18n/uk.rs@@ -525,6 +525,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Values and number formats" => "Values and number formats",         "Operation" => "Operation",         "Add" => "Add",+        "Paste Special|Add" => "Add",         "Subtract" => "Subtract",         "Multiply" => "Multiply",         "Divide" => "Divide",@@ -561,6 +562,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {         "Tab" => "Tab",         "Semicolon" => "Semicolon",         "Comma" => "Comma",+        "Text to Columns|Comma" => "Comma",         "Space" => "Space",         "Other:" => "Other:",         "Treat consecutive delimiters as one" => "Treat consecutive delimiters as one",diff --git a/docs/localization-parity.md b/docs/localization-parity.md--- a/docs/localization-parity.md+++ b/docs/localization-parity.md@@ -1,6 +1,6 @@ # Localization parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-23 · **Change:** minor (missing translations are listed by `cargo xtask i18n-report` and never fail a check) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4+> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-26 · **Change:** minor (Paste Special's Add and Text to Columns' Comma get their own keys) · **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,@@ -110,6 +110,7 @@ language (none so far) and of localized function names.  | Date | Change | Summary | |---|---|---|+| 2026-10-26 | minor | Paste Special's Add operation and Text to Columns' Comma delimiter are keyed `Paste Special|Add` and `Text to Columns|Comma`, so they can be translated apart from the Solver's Add button and the Comma cell style (Spanish: Sumar vs Agregar, Coma vs Millares); every catalog keeps the text it showed | | 2026-10-23 | minor | Missing translations are reported, never a failure: `cargo xtask i18n-report` prints, per language, the strings other catalogs translate and it lacks (plus Spanish function help rows keyed by English the function catalog no longer has) and always passes; `cargo xtask ci` runs it first. Coverage and per-language parity tests and tests of one language's exact wording are gone; UI tests take the expected text from the catalog. Duplicate-key, placeholder, context-prefix and line-shape checks stay | | 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: furigana (`rPh` phonetic runs and `<phoneticPr>` in `xl/sharedStrings.xml`) is no longer deleted by an open + save; it is kept on the workbook and written back (a `<phoneticPr>` without runs is kept too, while duplicate texts with different readings keep only the first, reported on open). Display of the readings is still missing (`crates/xlsx/src/tests/phonetic_tests.rs`) |