i18n: German context menus' Insert reads "Zellen einfügen", not a second "Einfügen" (#2874)

German showed "Einfügen" for Paste and again for Insert in the cell menu
("Einfügen…") and the row and column header menus ("Einfügen"). The cell
menu's Insert… now reads "Zellen einfügen…", as Excel's German menu does.
The header menus' Insert gets its own key, "Header Menu|Insert", German
"Zellen einfügen"; the plain "Insert" stays as the Insert dialog's title
and button use it, and every other catalog gets the new key with the text
it shows today.

A test reads the three menus' items from menus.rs and checks that no two
read alike in German.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Zinadin ZidanandClaude Opus 5.5 committed 2026-11-05 12:04:32 +06:00
1 parent 1fb191571b
commit cb05971659
20 files changed
+67 -3

No files matched your search

+2 -2
View File
@@ -496,7 +496,7 @@ pub(super) fn header_menu(app: &mut SheetApp, ui: &mut egui::Ui, was_open: bool)
("Copy", "edit.copy"),
("Paste", "edit.paste"),
("-", ""),
("Insert", "home.insertRows"),
("Header Menu|Insert", "home.insertRows"),
("Delete", "home.deleteRows"),
("Clear Contents", "edit.clearContents"),
("-", ""),
@@ -513,7 +513,7 @@ pub(super) fn header_menu(app: &mut SheetApp, ui: &mut egui::Ui, was_open: bool)
("Copy", "edit.copy"),
("Paste", "edit.paste"),
("-", ""),
("Insert", "home.insertColumns"),
("Header Menu|Insert", "home.insertColumns"),
("Delete", "home.deleteColumns"),
("Clear Contents", "edit.clearContents"),
("-", ""),
+46
View File
@@ -180,6 +180,52 @@ fn filter_menu_uses_the_table_whose_header_was_clicked() {
assert_eq!(filter_table_range(&sh, 1, 4), None);
}
/// The `("Label", "id")` keys written in `src`, without separators.
fn menu_labels(src: &str) -> Vec<&str> {
src.split("(\"").skip(1).filter_map(|rest| rest.split_once("\", \"").map(|(label, _)| label)).filter(|label| *label != "-").collect()
}
/// The source of `menus.rs` from `start` to the first `end` after it.
fn menu_source<'a>(src: &'a str, start: &str, end: &str) -> &'a str {
let from = src.find(start).unwrap_or_else(|| panic!("{start:?} not in menus.rs"));
let rest = &src[from..];
&rest[..rest.find(end).unwrap_or_else(|| panic!("{end:?} not after {start:?}"))]
}
/// German read "Einfügen" for Paste and "Einfügen…"/"Einfügen" for Insert in the same menu
/// (#2874): no two items of the cell, row header or column header menu may read alike, ignoring
/// case and a trailing ellipsis. The items are read from `menus.rs`, so new ones are checked too.
#[test]
fn german_context_menus_have_no_two_items_alike() {
use crate::i18n::Language;
let src = include_str!("menus.rs");
let cell = menu_labels(menu_source(src, "fn context_menu(", "let lang ="));
let (rows, columns) =
menu_source(src, "fn header_menu(", "let lang =").split_once("} else {").expect("header menu has a rows and a columns list");
let insert_copied = menu_labels(menu_source(src, "fn insert_copied_item(", "\n}"));
assert_eq!(insert_copied.len(), 3, "{insert_copied:?}");
for (menu, keys) in [("cell", cell), ("row header", menu_labels(rows)), ("column header", menu_labels(columns))] {
assert!(keys.contains(&"Paste") && keys.len() > 8, "{menu} menu not read from menus.rs: {keys:?}");
// A menu holds at most one Insert Copied/Cut Cells entry.
for extra in &insert_copied {
let mut seen: Vec<(String, &str)> = Vec::new();
for key in keys.iter().chain([extra]) {
let shown = Language::De.tr(key).trim_end_matches('…').trim().to_lowercase();
if let Some((_, other)) = seen.iter().find(|(text, _)| *text == shown) {
panic!("German {menu} menu shows {key:?} and {other:?} both as {shown:?}");
}
seen.push((shown, key));
}
}
}
assert_eq!(Language::De.tr("Insert…"), "Zellen einfügen…");
assert_eq!(Language::De.tr("Header Menu|Insert"), "Zellen einfügen");
// Only German changed: the header menu's Insert reads as the plain Insert everywhere else.
for language in Language::ALL.into_iter().filter(|l| *l != Language::De) {
assert_eq!(language.tr("Header Menu|Insert"), language.tr("Insert"), "{}", language.code());
}
}
#[test]
fn cell_text_y_moves_monotonically_in_standard_and_tall_rows() {
let rect_std = Rect::from_min_max(pos2(0.0, 0.0), pos2(100.0, 20.0));
+1
View File
@@ -57,6 +57,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Podokno\nformátu",
"Format" => "Formát",
"Insert" => "Vložit",
"Header Menu|Insert" => "Vložit",
"Insert Cells…" => "Vložit buňky…",
"Delete" => "Odstranit",
"Delete Cells…" => "Odstranit buňky…",
+2 -1
View File
@@ -57,6 +57,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Format-\nbereich",
"Format" => "Format",
"Insert" => "Einfügen",
"Header Menu|Insert" => "Zellen einfügen",
"Insert Cells…" => "Zellen einfügen…",
"Delete" => "Löschen",
"Select Data…" => "Daten auswählen…",
@@ -476,7 +477,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
// grid.rs cell and row/column header context menus.
"Cut" => "Ausschneiden",
"Copy" => "Kopieren",
"Insert…" => "Einfügen…",
"Insert…" => "Zellen einfügen…",
"Delete…" => "Löschen…",
"Filter by Selected Cell's Value" => "Nach Wert der gewählten Zelle filtern",
"New Comment" => "Neuer Kommentar",
+1
View File
@@ -56,6 +56,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Παράθυρο\nμορφοποίησης",
"Format" => "Μορφοποίηση",
"Insert" => "Εισαγωγή",
"Header Menu|Insert" => "Εισαγωγή",
"Insert Cells…" => "Εισαγωγή κελιών…",
"Delete" => "Διαγραφή",
"Delete Cells…" => "Διαγραφή κελιών…",
+1
View File
@@ -60,6 +60,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Panel\nde formato",
"Format" => "Formato",
"Insert" => "Insertar",
"Header Menu|Insert" => "Insertar",
"Insert Cells…" => "Insertar celdas…",
"Delete" => "Eliminar",
"Delete Cells…" => "Eliminar celdas…",
+1
View File
@@ -67,6 +67,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Volet\nFormat",
"Format" => "Format",
"Insert" => "Insertion",
"Header Menu|Insert" => "Insertion",
"Insert Cells…" => "Insérer des cellules…",
"Delete" => "Supprimer",
"Delete Cells…" => "Supprimer des cellules…",
+1
View File
@@ -60,6 +60,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Riquadro\nFormato",
"Format" => "Formato",
"Insert" => "Inserisci",
"Header Menu|Insert" => "Inserisci",
"Insert Cells…" => "Inserisci celle…",
"Delete" => "Elimina",
"Delete Cells…" => "Elimina celle…",
+1
View File
@@ -64,6 +64,7 @@ pub(super) const CORE: &[(&str, &str)] = &[
("Format\nPane", "書式ウィンドウ"),
("Format", "書式"),
("Insert", "挿入"),
("Header Menu|Insert", "挿入"),
("Insert Cells…", "セルの挿入…"),
("Delete", "削除"),
("Delete Cells…", "セルの削除…"),
+1
View File
@@ -62,6 +62,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "서식\n창",
"Format" => "서식",
"Insert" => "삽입",
"Header Menu|Insert" => "삽입",
"Insert Cells…" => "셀 삽입…",
"Delete" => "삭제",
"Delete Cells…" => "셀 삭제…",
+1
View File
@@ -61,6 +61,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Opmaak-\nvenster",
"Format" => "Opmaak",
"Insert" => "Invoegen",
"Header Menu|Insert" => "Invoegen",
"Insert Cells…" => "Cellen invoegen…",
"Delete" => "Verwijderen",
"Delete Cells…" => "Cellen verwijderen…",
+1
View File
@@ -56,6 +56,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Okienko\nformatowania",
"Format" => "Formatuj",
"Insert" => "Wstaw",
"Header Menu|Insert" => "Wstaw",
"Insert Cells…" => "Wstaw komórki…",
"Delete" => "Usuń",
"Delete Cells…" => "Usuń komórki…",
+1
View File
@@ -59,6 +59,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Painel de\nFormatação",
"Format" => "Formatar",
"Insert" => "Inserir",
"Header Menu|Insert" => "Inserir",
"Insert Cells…" => "Inserir Células…",
"Delete" => "Excluir",
"Delete Cells…" => "Excluir Células…",
+1
View File
@@ -63,6 +63,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Panou\nformatare",
"Format" => "Format",
"Insert" => "Inserare",
"Header Menu|Insert" => "Inserare",
"Insert Cells…" => "Inserare celule…",
"Delete" => "Ștergere",
"Delete Cells…" => "Ștergere celule…",
+1
View File
@@ -62,6 +62,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Область\nформатирования",
"Format" => "Формат",
"Insert" => "Вставить",
"Header Menu|Insert" => "Вставить",
"Insert Cells…" => "Вставить ячейки…",
"Delete" => "Удалить",
"Delete Cells…" => "Удалить ячейки…",
+1
View File
@@ -63,6 +63,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Okno za\noblikovanje",
"Format" => "Oblikovanje",
"Insert" => "Umetni",
"Header Menu|Insert" => "Umetni",
"Insert Cells…" => "Umetni ćelije…",
"Delete" => "Obriši",
"Delete Cells…" => "Obriši ćelije…",
+1
View File
@@ -59,6 +59,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Biçim\nBölmesi",
"Format" => "Biçim",
"Insert" => "Ekle",
"Header Menu|Insert" => "Ekle",
"Insert Cells…" => "Hücre Ekle…",
"Delete" => "Sil",
"Delete Cells…" => "Hücreleri Sil…",
+1
View File
@@ -58,6 +58,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Область\nформатування",
"Format" => "Формат",
"Insert" => "Вставити",
"Header Menu|Insert" => "Вставити",
"Insert Cells…" => "Вставити комірки…",
"Delete" => "Видалити",
"Delete Cells…" => "Видалити комірки…",
+1
View File
@@ -64,6 +64,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "Ngăn\nđịnh dạng",
"Format" => "Định dạng",
"Insert" => "Chèn",
"Header Menu|Insert" => "Chèn",
"Insert Cells…" => "Chèn ô…",
"Delete" => "Xóa",
"Delete Cells…" => "Xóa ô…",
+1
View File
@@ -62,6 +62,7 @@ pub(super) fn translate(text: &str) -> Option<&'static str> {
"Format\nPane" => "格式\n窗格",
"Format" => "格式",
"Insert" => "插入",
"Header Menu|Insert" => "插入",
"Insert Cells…" => "插入单元格…",
"Delete" => "删除",
"Delete Cells…" => "删除单元格…",