mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-24 10:46:50 -06:00
Translate form-dialog field labels, choices and notes
Page Setup, Insert and the other form dialogs drew their field labels in English in every interface language, though their titles and OK/Cancel were translated and most catalogs already carry the labels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JadgGo4G2GHaAMNb3qyygk
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
37e41424ed
commit
29adb19872
@@ -1389,12 +1389,14 @@ fn form(ui: &mut egui::Ui, d: &mut Dialog, confirm: &mut bool, open: &mut bool)
|
||||
|
||||
/// Draws a dialog's `fields`, editing its values.
|
||||
fn form_fields(ui: &mut egui::Ui, d: &mut Dialog) {
|
||||
// Field labels, choices and notes are English source strings, translated as they are drawn.
|
||||
let lang = crate::i18n::current(ui.ctx());
|
||||
egui::Grid::new("form").num_columns(1).spacing(vec2(8.0, 6.0)).show(ui, |ui| {
|
||||
for f in d.fields.clone() {
|
||||
match f {
|
||||
Field::Text { key, label } => {
|
||||
ui.vertical(|ui| {
|
||||
ui.label(label);
|
||||
ui.label(lang.tr(label));
|
||||
let mut s = d
|
||||
.values
|
||||
.get(key)
|
||||
@@ -1414,17 +1416,17 @@ fn form_fields(ui: &mut egui::Ui, d: &mut Dialog) {
|
||||
Field::Password { key, label } => {
|
||||
// Masked as typed (Excel shows dots); "Show password" reveals it on purpose.
|
||||
ui.vertical(|ui| {
|
||||
ui.label(label);
|
||||
ui.label(lang.tr(label));
|
||||
let mut s = d.values.get(key).and_then(Json::as_str).unwrap_or_default().to_string();
|
||||
if ui.add(egui::TextEdit::singleline(&mut s).password(!d.show_password).desired_width(320.0)).changed() {
|
||||
d.values.insert(key.into(), json!(s));
|
||||
}
|
||||
ui.checkbox(&mut d.show_password, "Show password");
|
||||
ui.checkbox(&mut d.show_password, lang.tr("Show password"));
|
||||
});
|
||||
}
|
||||
Field::Number { key, label } => {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(label);
|
||||
ui.label(lang.tr(label));
|
||||
let mut n = d.values.get(key).and_then(Json::as_f64).unwrap_or(0.0);
|
||||
if ui.add(egui::DragValue::new(&mut n).speed(0.5)).changed() {
|
||||
d.values.insert(key.into(), json!(n));
|
||||
@@ -1433,20 +1435,20 @@ fn form_fields(ui: &mut egui::Ui, d: &mut Dialog) {
|
||||
}
|
||||
Field::Choice { key, label, options } => {
|
||||
ui.vertical(|ui| {
|
||||
ui.label(egui::RichText::new(label).strong());
|
||||
ui.label(egui::RichText::new(lang.tr(label)).strong());
|
||||
let cur = d.values.get(key).and_then(Json::as_str).unwrap_or("").to_string();
|
||||
if d.name == "dataValidation" {
|
||||
let selected = options.iter().find(|(val, _)| *val == cur).map(|(_, text)| *text).unwrap_or("");
|
||||
let selected = options.iter().find(|(val, _)| *val == cur).map(|(_, text)| lang.tr(text)).unwrap_or("");
|
||||
egui::ComboBox::from_id_salt(("dataValidation", key)).selected_text(selected).width(300.0).show_ui(ui, |ui| {
|
||||
for (val, text) in options {
|
||||
if ui.selectable_label(cur == val, text).clicked() {
|
||||
if ui.selectable_label(cur == val, lang.tr(text)).clicked() {
|
||||
d.set_value(key, json!(val));
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
for (val, text) in options {
|
||||
if ui.radio(cur == val, text).clicked() {
|
||||
if ui.radio(cur == val, lang.tr(text)).clicked() {
|
||||
d.set_value(key, json!(val));
|
||||
}
|
||||
}
|
||||
@@ -1455,12 +1457,12 @@ fn form_fields(ui: &mut egui::Ui, d: &mut Dialog) {
|
||||
}
|
||||
Field::Check { key, label } => {
|
||||
let mut b = d.values.get(key).and_then(Json::as_bool).unwrap_or(false);
|
||||
if ui.checkbox(&mut b, label).changed() {
|
||||
if ui.checkbox(&mut b, lang.tr(label)).changed() {
|
||||
d.values.insert(key.into(), json!(b));
|
||||
}
|
||||
}
|
||||
Field::Note(t) => {
|
||||
ui.label(egui::RichText::new(t).small());
|
||||
ui.label(egui::RichText::new(lang.tr(&t)).small());
|
||||
}
|
||||
}
|
||||
ui.end_row();
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
//! Form dialogs draw their field labels and choices in the interface language, as their titles
|
||||
//! and OK/Cancel buttons already were (Page Setup showed "Left margin (in):" in every language).
|
||||
|
||||
use egui_kittest::kittest::Queryable as _;
|
||||
use gridcraft_engine::Session;
|
||||
use gridcraft_ui_egui::SheetApp;
|
||||
use serde_json::json;
|
||||
|
||||
fn harness() -> egui_kittest::Harness<'static, SheetApp> {
|
||||
let mut session = Session::new();
|
||||
session.new_workbook();
|
||||
let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_ui_state(
|
||||
|ui, app: &mut SheetApp| {
|
||||
let ctx = ui.ctx().clone();
|
||||
app.logic(&ctx);
|
||||
app.ui(ui);
|
||||
},
|
||||
SheetApp::new(session, Default::default()),
|
||||
);
|
||||
h.run_steps(4);
|
||||
h
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn form_fields_are_translated() {
|
||||
for (dialog, translated, english) in [
|
||||
("pageSetup", ["Margem esquerda (pol.):", "Rodapé (pol.):"], ["Left margin (in):", "Footer (in):"]),
|
||||
("insertPaste", ["Deslocar células para a direita", "Deslocar células para baixo"], ["Shift cells right", "Shift cells down"]),
|
||||
] {
|
||||
let mut h = harness();
|
||||
h.state_mut().run("app.language.set", json!({"language": "pt"})).unwrap();
|
||||
h.state_mut().open_dialog(dialog, json!({}));
|
||||
h.run_steps(3);
|
||||
for label in translated {
|
||||
assert!(h.query_by_label_contains(label).is_some(), "{dialog}: no {label}");
|
||||
}
|
||||
for label in english {
|
||||
assert!(h.query_by_label_contains(label).is_none(), "{dialog}: {label} is untranslated");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user