M14.i18n: translate Czech labels at UI render sites

Localize native/web file filters, diagnostic labels, numbered presets
and contributor tooltips with English fallback and Czech plural forms.
Fix gradient adjective agreement and disambiguate Japanese printer marks
in PDF/Print choices and summaries. Keep file extensions and names intact.

Add Czech catalog rows and regression coverage; update localization evidence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Losminek
2026-10-12 08:18:13 +07:00
committed by bflatastic
co-authored by Claude Opus 5.5
parent 25c60fd0f5
commit e3dec2e87b
15 changed files with 155 additions and 32 deletions
+3 -1
View File
@@ -304,7 +304,9 @@ fn details(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog, b: &mut
let saving = !d.bool(SAVING);
d.fields.insert(SAVING.into(), json!(saving));
if saving && d.str("presetName").is_empty() {
d.fields.insert("presetName".into(), json!(format!("Preset {}", app.session.prefs.new_doc_presets.len() + 1)));
let template = "Preset {number}";
let name = crate::i18n::fmt(tl!(template), &[("number", &(app.session.prefs.new_doc_presets.len() + 1).to_string())]);
d.fields.insert("presetName".into(), json!(name));
}
}
});
+9 -2
View File
@@ -272,13 +272,19 @@ pub(super) fn choice<T: Choice>(d: &Dialog, path: &str) -> Option<T> {
/// A dropdown of the choices `T` (options for which `enabled` is false are greyed).
pub(super) fn pick<T: Choice>(ui: &mut egui::Ui, d: &mut Dialog, path: &str, width: f32, enabled: impl Fn(T) -> bool) -> bool {
let current = choice_index::<T>(d, path);
let label = current.and_then(|i| T::LABELS.get(i)).copied().unwrap_or_default();
let chosen = widgets::dropdown_with(ui, path, label, T::LABELS, width, |i| T::ALL.get(i).is_some_and(|c| enabled(*c)));
let labels: Vec<_> = T::LABELS.iter().map(|label| choice_label(crate::i18n::current(), path, label)).collect();
let label = current.and_then(|i| labels.get(i)).copied().unwrap_or_default();
let chosen = widgets::dropdown_with(ui, path, label, &labels, width, |i| T::ALL.get(i).is_some_and(|c| enabled(*c)));
let Some(id) = chosen.and_then(|i| T::IDS.get(i)) else { return false };
set(d, path, json!(id));
true
}
/// Printer mark styles use adjectives, separately from interface language names.
pub(super) fn choice_label<'a>(lang: crate::i18n::Lang, path: &str, label: &'a str) -> &'a str {
if path == "marks.kind" { crate::i18n::tr_ctx(lang, "mark-style", label) } else { crate::i18n::tr(lang, label) }
}
pub(super) fn number(ui: &mut egui::Ui, d: &mut Dialog, path: &str, suffix: &str, enabled: bool) {
let v = get(d, path).as_f64().unwrap_or(0.0);
ui.add_enabled_ui(enabled, |ui| {
@@ -785,6 +791,7 @@ pub(super) fn option_rows<'a>(ui: &mut egui::Ui, changed: impl IntoIterator<Item
for c in changed {
let value = match &c["value"] {
Value::Bool(b) => if *b { tl!("On") } else { tl!("Off") }.to_string(),
Value::String(s) if c["option"] == "marks.kind" => choice_label(crate::i18n::current(), "marks.kind", s).to_string(),
Value::String(s) => s.clone(),
other => other.to_string(),
};
@@ -296,3 +296,11 @@ fn simplify_dialog_ok_keeps_exactly_one_undo_with_or_without_preview() {
assert!(app.session.doc().unwrap().selection.anchors.is_empty());
}
}
#[test]
fn printer_mark_labels_are_distinct_from_language_names() {
let cs = crate::i18n::Lang::from_code("cs").unwrap();
assert_eq!(save_pdf::choice_label(cs, "marks.kind", "Japanese"), "Japonské");
assert_eq!(save_pdf::choice_label(cs, "language", "Japanese"), "Japonština");
assert_eq!(save_pdf::choice_label(crate::i18n::Lang::EN, "marks.kind", "Japanese"), "Japanese");
}