From 660fe22de8b0bee7347299925f7c44bcc7a83f5c Mon Sep 17 00:00:00 2001 From: Losminek <301412321+Losminek@users.noreply.github.com> Date: Sun, 11 Oct 2026 17:35:52 +0200 Subject: [PATCH 1/3] i18n (cs): Effect > Pathfinder > Add reads "Sjednotit", keyed by the effect id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The key "Add" is shared by Effect > Pathfinder > Add (PathfinderOp::Unite), the File Info button and a label in the raster effects dialog. One plain row cannot fit all three: "Přidat" is right for the button, but the Pathfinder effect unites shapes, so it reads "Sjednotit". - cs.tsv: `@id pathfinder.add` = "Sjednotit"; the plain "Add" row stays "Přidat". - menus.rs: Effect menu items all run effect.apply / effect.dialog, so the command id cannot tell them apart. effect_item_label() looks the effect's own id up first (an @id row), and "Last Effect: {name}" does the same. - appearance.rs: the Appearance panel's effect labels use the same lookup. - i18n/tests.rs: an @id row may now name an effect id as well as a command id; czech_reads_as_czech pins Add and pathfinder.add. No other catalog has an @id row, so their behaviour is unchanged. Co-Authored-By: Claude Opus 5.5 --- crates/ui-egui/src/i18n/cs.tsv | 1 + crates/ui-egui/src/i18n/tests.rs | 11 +++++++++-- crates/ui-egui/src/menus.rs | 17 +++++++++++++++-- crates/ui-egui/src/panels/appearance.rs | 5 +++-- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index 2bb30fde..cb76481b 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -370,6 +370,7 @@ Zig Zag… Cikcak… Pathfinder Operace s cestami Add Přidat +@id pathfinder.add Sjednotit Intersect Protnout Exclude Vyloučit Subtract Odečíst diff --git a/crates/ui-egui/src/i18n/tests.rs b/crates/ui-egui/src/i18n/tests.rs index fe849bc5..657f0acc 100644 --- a/crates/ui-egui/src/i18n/tests.rs +++ b/crates/ui-egui/src/i18n/tests.rs @@ -161,8 +161,11 @@ fn bundled_catalogs_are_consistent() { assert_eq!(src.ends_with('…'), tr.ends_with('…'), "{}: ellipsis mismatch: {src:?}", l.code); } if ctx == "@id" { - let known = - crate::menus::UI_COMMANDS.iter().any(|c| c.0 == src) || vectorcraft_engine::cmd::command_specs().iter().any(|c| c.id == src); + // A command id, or an effect id: Effect menu items share `effect.apply` / + // `effect.dialog`, so the effect's own id is what tells them apart. + let known = crate::menus::UI_COMMANDS.iter().any(|c| c.0 == src) + || vectorcraft_engine::cmd::command_specs().iter().any(|c| c.id == src) + || vectorcraft_effects::effect_catalog().iter().any(|e| e.id == src); assert!(known, "{}: unknown command id {src:?}", l.code); } } @@ -839,6 +842,10 @@ fn czech_reads_as_czech() { assert_eq!(trn(cs(), n, "{n} Layer", "{n} Layers"), format!("{n} {word}")); } assert_eq!(tr_ctx(cs(), "axis", "Both"), "Obě"); + // "Add" is Unite in Effect › Pathfinder (an `@id` row for the effect id); "Přidat" elsewhere. + assert_eq!(tr(cs(), "Add"), "Přidat"); + assert_eq!(tr_id(cs(), "pathfinder.add", "Add"), "Sjednotit"); + assert_eq!(tr_id(cs(), "pathfinder.intersect", "Intersect"), "Protnout"); let nested = "command `object.group` is not available right now: nothing selected"; assert_eq!(message(cs(), nested), "příkaz `object.group` nyní není k dispozici: nic není vybráno"); } diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index 95d815c9..25d3737f 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -1650,7 +1650,7 @@ pub fn display_label(app: &VectorcraftApp, id: &str, label: &str) -> String { "effect.last" => match &app.last_effect { Some((e, _)) => { let name = vectorcraft_effects::effect_info(e).map(|i| i.label).unwrap_or(e.as_str()); - fmt(tl!("Last Effect: {name}"), &[("name", tl!(name))]) + fmt(tl!("Last Effect: {name}"), &[("name", crate::i18n::tr_id(lang, e, name))]) } None => crate::i18n::tr_id(lang, id, label).to_string(), }, @@ -1661,6 +1661,19 @@ pub fn display_label(app: &VectorcraftApp, id: &str, label: &str) -> String { } } +/// The label of an Effect menu item in the UI language, by the effect's own id. Every effect item +/// runs `effect.apply` or `effect.dialog`, so the command id can't tell them apart; an `@id` row +/// for the effect id (for example `pathfinder.add`) wins over the plain row of the English label. +/// `None` when the catalog has no such row, and the plain translation applies. +fn effect_item_label(id: &str, p: &Value) -> Option { + if !matches!(id, "effect.apply" | "effect.dialog") { + return None; + } + let effect = p.get("effect")?.as_str()?; + let shown = crate::i18n::tr_id(crate::i18n::current(), effect, ""); + (!shown.is_empty()).then(|| shown.to_string()) +} + /// Menu slots that are left out while they have nothing to show (unused saved views, recent files, /// User Defined swatch and graphic style libraries). fn hidden_when_disabled(id: &str) -> bool { @@ -1793,7 +1806,7 @@ pub fn entry<'a>(app: &VectorcraftApp, it: &'a Item) -> Option> { Entry::Item(Row { command: Some((id, p)), source: label, - label: display_label(app, id, label).into(), + label: effect_item_label(id, p).unwrap_or_else(|| display_label(app, id, label)).into(), shortcut: item_shortcut(id, p), enabled, checked, diff --git a/crates/ui-egui/src/panels/appearance.rs b/crates/ui-egui/src/panels/appearance.rs index e8db7719..27b3be5e 100644 --- a/crates/ui-egui/src/panels/appearance.rs +++ b/crates/ui-egui/src/panels/appearance.rs @@ -160,10 +160,11 @@ fn built_in_effect(id: &str) -> bool { catalog().iter().any(|c| c.0 == id) } -/// [`effect_label`] as shown: a built-in effect's in the UI language, a plug-in's as it is. +/// [`effect_label`] as shown: a built-in effect's in the UI language (an `@id` row for the +/// effect's id wins over the plain row of its English label), a plug-in's as it is. fn shown_effect_label(id: &str) -> String { match catalog().iter().find(|c| c.0 == id) { - Some(c) => tl!(&c.1).to_string(), + Some(c) => crate::i18n::t_id(id, &c.1).to_string(), None => effect_label(id), } } From 6371211f3b81bd40ff0b6eb5437fde2c3f835442 Mon Sep 17 00:00:00 2001 From: Losminek <301412321+Losminek@users.noreply.github.com> Date: Sun, 11 Oct 2026 18:50:31 +0200 Subject: [PATCH 2/3] i18n (cs): translate the remaining new-document preset names Co-Authored-By: Claude Opus 5.5 --- crates/ui-egui/src/i18n/cs.tsv | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index cb76481b..3a991f3f 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -4178,3 +4178,52 @@ effect Regular Pravidelný @msg missing panel layout chybí rozložení panelů @msg unsupported native docking operation nepodporovaná nativní operace ukotvení @msg this kind of brush has no options dialog yet tento druh štětce zatím nemá dialogové okno možností + Phone 393×852 Telefon 393×852 + Phone 430×932 Telefon 430×932 + Phone 360×800 Telefon 360×800 + Phone 412×915 Telefon 412×915 + Phone 375×667 Telefon 375×667 + Tablet 768×1024 Tablet 768×1024 + Tablet 820×1180 Tablet 820×1180 + Tablet 834×1194 Tablet 834×1194 + Tablet 1024×1366 Tablet 1024×1366 + Tablet 800×1280 Tablet 800×1280 + Watch 184×224 Hodinky 184×224 + Watch 198×242 Hodinky 198×242 + Web 1600×900 Web 1600×900 + Web 1440×900 Web 1440×900 + Web 1366×768 Web 1366×768 + Web 1280×800 Web 1280×800 + Web 1024×768 Web 1024×768 + Legal Legal + Tabloid Tabloid + A3 A3 + A4 A4 + A5 A5 + B4 B4 + B5 B5 + HDTV 1080p HDTV 1080p + HDTV 720p HDTV 720p + 4K UHD 4K UHD + 8K UHD 8K UHD + 2K Cinema Kino 2K + 4K Cinema Kino 4K + Greeting Card Blahopřání + Square 8 × 8 in Čtverec 8 × 8 in + Poster 18 × 24 in Plakát 18 × 24 in + Poster 24 × 36 in Plakát 24 × 36 in + Logo 1000×1000 Logo 1000×1000 + Business Card 3.5 × 2 in Vizitka 3,5 × 2 in + Business Card 85 × 55 mm Vizitka 85 × 55 mm + Letterhead Letter Hlavičkový papír Letter + Letterhead A4 Hlavičkový papír A4 + Envelope DL Obálka DL + Envelope #10 Obálka #10 + Social Portrait Post 1080×1350 Portrétní příspěvek pro sociální sítě 1080×1350 + Social Landscape Post 1200×630 Příspěvek na šířku pro sociální sítě 1200×630 + Social Story 1080×1920 Příběh pro sociální sítě 1080×1920 + Social Tall Post 1000×1500 Vysoký příspěvek pro sociální sítě 1000×1500 + Profile Cover 1500×500 Úvodní obrázek profilu 1500×500 + Page Cover 1640×624 Úvodní obrázek stránky 1640×624 + Video Banner 2560×1440 Banner videa 2560×1440 + Video Thumbnail 1280×720 Miniatura videa 1280×720 From e61ed740c3b691177a850e21075ffcbead4466ff Mon Sep 17 00:00:00 2001 From: Losminek <301412321+Losminek@users.noreply.github.com> Date: Sun, 11 Oct 2026 19:13:01 +0200 Subject: [PATCH 3/3] =?UTF-8?q?i18n=20(cs):=20translate=20the=20remaining?= =?UTF-8?q?=20looked-up=20strings=20(shortcut=20editor,=20arrowheads,=20co?= =?UTF-8?q?lour=20harmony,=20presets=20categories,=20=E2=80=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These strings reach tl!/tr at render time but had no Czech entry; several are passed through variables or helpers, so the literal-based coverage test does not see them. Co-Authored-By: Claude Opus 5.5 --- crates/ui-egui/src/i18n/cs.tsv | 223 ++++++++++++++++++++++++++++++++- 1 file changed, 220 insertions(+), 3 deletions(-) diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index 3a991f3f..b488bbfa 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -1037,8 +1037,8 @@ lighting Light Světlo Expand: Rozložit: Gradient (.) Přechod (.) H: V: - Modify Upravit - Navigate Navigace + Modify Úpravy + Navigate Pohled None (/) Žádná (/) Select All Pins Vybrat všechny špendlíky Show Mesh Zobrazit síť @@ -3303,7 +3303,7 @@ effect Regular Pravidelný Join the ArtCraft community on Discord (discord.gg/artcraft) Připojte se ke komunitě ArtCraft na Discordu (discord.gg/artcraft) Source code on GitHub Zdrojový kód na GitHubu All Tools Všechny nástroje - Draw Kreslení + Draw Kresba Reset Obnovit — missing — chybí (closest) (nejbližší) @@ -4227,3 +4227,220 @@ effect Regular Pravidelný Page Cover 1640×624 Úvodní obrázek stránky 1640×624 Video Banner 2560×1440 Banner videa 2560×1440 Video Thumbnail 1280×720 Miniatura videa 1280×720 +# Keyboard Shortcuts dialog (shortcut_editor.rs) + Keyboard Shortcuts Klávesové zkratky + Set: Sada: + Reset to Defaults Obnovit výchozí hodnoty + Tool Nástroj + Command Příkaz + Shortcut Zkratka + Menu Commands Příkazy nabídky + Press keys… Stiskněte klávesy… + Use Default Použít výchozí + Go to Conflict Přejít ke konfliktu + Remove the shortcut Odebrat zkratku + Click, then press the new shortcut (Esc cancels) Klikněte a stiskněte novou zkratku (Esc zruší) + All shortcuts reset to defaults. Všechny zkratky byly obnoveny na výchozí hodnoty. + Imported. Press OK to keep the imported set. Importováno. Importovanou sadu zachováte stisknutím OK. + ⚠ {chord} was already used by {names} — it has been removed there. Pozor: zkratka {chord} už byla použita pro {names} — tam byla odebrána. + VectorCraft Defaults Výchozí VectorCraft +@plural {n} shortcut is assigned more than once|{n} shortcuts are assigned more than once {n} zkratka je přiřazena více než jednou|{n} zkratky jsou přiřazeny více než jednou|{n} zkratek je přiřazeno více než jednou +# Print dialog: overprints note and choice labels + Simulate prints overprints as Overprint Preview shows them; separations always keep them. A preset flattens transparency before printing (PostScript files always flatten it). Možnost Simulovat vytiskne přetisky tak, jak je ukazuje Náhled přetisků; separace je vždy zachovávají. Přednastavení před tiskem sloučí průhlednost (soubory PostScript ji sloučí vždy). + Preserve Zachovat + Simulate Simulovat + Portrait (flipped) Na výšku (převrácené) + Landscape (flipped) Na šířku (převrácené) + Visible & Printable Layers Viditelné a tisknutelné vrstvy + Visible Layers Viditelné vrstvy + All Layers Všechny vrstvy + Do Not Scale Neměnit měřítko + Fit to Page Přizpůsobit stránce + Custom Scale Vlastní měřítko + Tile Imageable Areas Dlaždice z potisknutelných oblastí + Composite Kompozitní + Separations Separace + Up (right reading) Nahoru (čitelné) + Down (right reading) Dolů (čitelné) + Positive Pozitiv + Negative Negativ + Subset Podmnožina + Complete Úplná + [Custom] [Vlastní] + [Default] [Výchozí] +# PDF options: choice labels + No downsampling Bez převzorkování + Subsample Podvzorkování + Bicubic Bikubické + Minimum Minimální + Run Length Délka běhu + Roman Římské + No conversion Bez převodu + Convert to destination Převést do cíle + Convert to destination (preserve numbers) Převést do cíle (zachovat hodnoty) + Don't include profiles Nezahrnovat profily + Include all profiles Zahrnout všechny profily + Include destination profile Zahrnout cílový profil + Include tagged source profiles Zahrnout označené zdrojové profily + Low resolution (150 ppi) Nízké rozlišení (150 ppi) + High resolution Vysoké rozlišení + Inserting, deleting and rotating pages Vkládání, mazání a otáčení stránek + Filling in form fields and signing Vyplňování formulářových polí a podepisování + Commenting, filling in form fields and signing Komentování, vyplňování formulářových polí a podepisování + Any except extracting pages Vše kromě extrahování stránek + Bounding Box Ohraničovací rámeček +# New Document preset categories + Mobile Mobil + Film & Video Film a video + Art & Illustration Umění a ilustrace + Branding Branding + Social Sociální sítě +# Arrowheads (Stroke panel) + Triangle Trojúhelník + Triangle (open) Trojúhelník (otevřený) + Circle (open) Kruh (otevřený) + Square (open) Čtverec (otevřený) + Bar Příčka + Arrow Šipka + Arrow (open) Šipka (otevřená) + Barbed S protihroty + Half Arrow (left) Poloviční šipka (vlevo) + Half Arrow (right) Poloviční šipka (vpravo) + Concave Vkleslá + Double Bar Dvojitá příčka + Feather Pírko + Dot on Bar Tečka na příčce + Chevron Véčko + Double Arrow Dvojitá šipka + Cross Kříž + Plus Plus + Hexagon Šestiúhelník + Hexagon (open) Šestiúhelník (otevřený) + Tag Štítek + Tag (open) Štítek (otevřený) + Half Circle Půlkruh + Drop Kapka + Slash Lomítko + Double Slash Dvojité lomítko + Diamond (open) Kosočtverec (otevřený) + Reverse Triangle Obrácený trojúhelník + Swallowtail Vlaštovčí ocas + Bracket Závorka + Fork Vidlice + Leaf List + Kite Deltoid + Triangle to Bar Trojúhelník k příčce + Oval Ovál +# Colour harmony rules (Color Guide, Recolor Artwork, Color Themes) + Complementary Komplementární + Complementary 2 Komplementární 2 + Split Complementary Rozdělená komplementární + Left Complement Levý doplněk + Right Complement Pravý doplněk + Analogous Analogická + Analogous 2 Analogická 2 + Monochromatic Monochromatická + Shades Tmavé tóny + Triad Triáda + Triad 2 Triáda 2 + Triad 3 Triáda 3 + Tetrad Tetráda + Tetrad 2 Tetráda 2 + Tetrad 3 Tetráda 3 + Compound Složená + Compound 2 Složená 2 + High Contrast Vysoký kontrast + High Contrast 2 Vysoký kontrast 2 + High Contrast 3 Vysoký kontrast 3 + Pentagram Pentagram +# Rendering intents, recolor methods, gradient kinds + Perceptual Percepční + Relative Colorimetric Relativní kolorimetrický + Absolute Colorimetric Absolutní kolorimetrický + Exact Přesná + Preserve Tints Zachovat světlé tóny + Scale Tints Změnit měřítko světlých tónů + Linear Lineární + Freeform Volný +# DXF options + 8 Colors 8 barev + 16 Colors 16 barev + 256 Colors 256 barev + True Colors Plné barvy + Preserve Appearance Zachovat vzhled + Maximize Editability Maximalizovat upravitelnost +# Layers panel: generated names + Clip Group Ořezová skupina + Guide Vodítko + Symbol Symbol + Envelope Obálka + Mesh Síť + Placed Document Umístěný dokument + Radial Repeat Kruhové opakování + Grid Repeat Mřížkové opakování + Mirror Repeat Zrcadlové opakování +# Generic parameter dialog (command.rs): Area Type Options + Auto Size Automatická velikost + Shrink Text to Fit Zmenšit text, aby se vešel + Ascent Výška nad účařím + Cap Height Výška verzálek + x Height Výška x + Justify Do bloku + First Baseline První účaří + Vertical Align Svislé zarovnání + Save Selection Uložit výběr +# Liquify tools + Twirl Zatočení + Pucker Smrštění + Bloat Vyboulení + Scallop Vroubkování + Wrinkle Zvrásnění +# File Info, Flattener Preview, Flattener presets + Unknown Neznámý + Copyrighted Chráněno autorským právem + Public Domain Volné dílo + None (Color Preview) Žádné (náhled barev) + Rasterized Complex Regions Rastrované složité oblasti + Transparent Objects Průhledné objekty + All Affected Objects Všechny dotčené objekty + Expanded Patterns Rozložené vzorky + Outlined Strokes Tahy převedené na křivky + Outlined Text Text převedený na křivky + All Rasterized Regions Všechny rastrované oblasti + High Resolution Vysoké rozlišení + Medium Resolution Střední rozlišení + Low Resolution Nízké rozlišení +# Save for Web, EPS, raster export options + Copyright and Contact Info Autorská práva a kontaktní údaje + All Slices Všechny řezy + Selected Slices Vybrané řezy + No Slices Žádné řezy + Images Only Jen obrazy + HTML and Images HTML a obrazy + Selective Selektivní + Adaptive Adaptivní + Black & White Černobílá + No Dither Bez rozptylu + Diffusion Difuze + Unsorted Neseřazeno + Sort by Hue Řadit podle odstínu + Sort by Luminance Řadit podle jasu + Sort by Popularity Řadit podle četnosti + Baseline (Standard) Základní (standardní) + Baseline Optimized Základní optimalizovaná + Art Optimized Optimalizováno pro kresbu + Type Optimized Optimalizováno pro text + Language Level 2 Jazyková úroveň 2 + Language Level 3 Jazyková úroveň 3 + TIFF (Black & White) TIFF (černobílý) + TIFF (8-bit Color) TIFF (8bitová barva) + 1 bit 1 bit + 4 bit 4 bity + 8 bit 8 bitů + 16 bit 16 bitů + 24 bit 24 bitů + 32 bit 32 bitů + 16 bits/pixel 16 bitů na pixel + 24 bits/pixel 24 bitů na pixel + 32 bits/pixel 32 bitů na pixel + DWG (use DXF) DWG (použijte DXF)