diff --git a/ROADMAP.md b/ROADMAP.md index 010b49d31..9076d5400 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,7 +2,7 @@ **Stage: pre-alpha** · next: alpha, ~0% and ~15–25 h away; beta ~28 points and ~420–750 h beyond that (the core-workflow gate, not the percentage: ready for real work is already ~47%) -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (Live corners (#186); Optical kerning from outlines (#181); macOS lists fonts that font services and managers activate) · **Target:** Adobe InDesign 2026 +> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** minor (Japanese print, import and table controls localized; Live corners (#186); Optical kerning from outlines (#181); macOS lists fonts that font services and managers activate) · **Target:** Adobe InDesign 2026 DesignCraft aims at full Adobe InDesign parity, and to be better: faster, open (documented JSON format + IDML), scriptable by agents (MCP), and available on the web. @@ -129,6 +129,9 @@ list) · [roadmap.md](docs/roadmap.md) (milestones, plan) · [parity-checklist.m Newest first. +- **2026-10-11** · Japanese captions now cover print ranges, imported style handling and table + row/column movement, including row-height distribution. Existing translation and RTL helpers + handle the display; command IDs, stored option values and user-defined style names are unchanged. - **2026-10-11** · Moving a sheared and rotated text frame no longer leaves trails of text behind: canvas repaints cover the frame's whole text box, not just its outline. No readiness percentage change. - **2026-10-11** · Live corners: the yellow widget on a selected rectangle frame shows corner diamonds; dragging one rounds the corners, Alt-click steps the corner shape (#186). @@ -178,6 +181,7 @@ Newest first. | Date | Change | Summary | |---|---|---| +| 2026-10-11 | minor | Localized Japanese print, import and table controls; readiness estimates unchanged | | 2026-10-10 | minor | Full number 42% → 47% (method aligned with the standard: plain weighted sum, no new evidence); readiness table with hours per audience | | 2026-10-10 | minor | Headline adds mainstream practitioner (~42%) and essentials user (~54%); method in docs/target-app-parity.md | | 2026-10-10 | minor | Stage alpha → pre-alpha under the new core-workflow gate: manual text threading is missing; alpha gate table added to docs/roadmap.md | diff --git a/crates/ui-egui/src/dialogs.rs b/crates/ui-egui/src/dialogs.rs index d02470009..dee7f2a5c 100644 --- a/crates/ui-egui/src/dialogs.rs +++ b/crates/ui-egui/src/dialogs.rs @@ -299,11 +299,11 @@ fn print_dialog(app: &crate::DesignApp, ui: &mut egui::Ui, d: &mut Dialog) { crate::rtl::label(ui, crate::i18n::tr(&app.ui.language, "Pages:")); ui.vertical(|ui| { let range = d.s("range"); - if ui.radio(range == "all", "All").clicked() { + if ui.radio(range == "all", crate::rtl::widget(ui, crate::i18n::tr(&app.ui.language, "All"))).clicked() { d.fields.insert("range".into(), json!("all")); } ui.horizontal(|ui| { - if ui.radio(range == "range", "Range:").clicked() { + if ui.radio(range == "range", crate::rtl::widget(ui, crate::i18n::tr(&app.ui.language, "Range:"))).clicked() { d.fields.insert("range".into(), json!("range")); } text_field(ui, d, "pages", 120.0); @@ -1512,7 +1512,7 @@ pub fn show(app: &mut DesignApp, ctx: &egui::Context) { let cur = d.s("styleConflicts"); ui.horizontal(|ui| { for (v, l) in [("useExisting", "Use Document Style Definition"), ("redefine", "Redefine Document Style"), ("autoRename", "Auto Rename")] { - if ui.radio(cur == v, l).clicked() { + if ui.radio(cur == v, crate::rtl::widget(ui, crate::i18n::tr(&app.ui.language, l))).clicked() { d.fields.insert("styleConflicts".into(), json!(v)); } } @@ -1525,7 +1525,7 @@ pub fn show(app: &mut DesignApp, ctx: &egui::Context) { for w in &imported { ui.label(w); let mapped = d.fields.get("map").and_then(|m| m.get(w)).and_then(Value::as_str).unwrap_or("").to_string(); - let shown = if mapped.is_empty() { "(import)".to_string() } else { mapped.clone() }; + let shown = if mapped.is_empty() { crate::i18n::tr(&app.ui.language, "(import)").to_string() } else { mapped.clone() }; egui::ComboBox::from_id_salt(("imp_map", w)).selected_text(crate::rtl::widget(ui, &shown)).width(170.0).show_ui(ui, |ui| { if ui.selectable_label(mapped.is_empty(),crate::rtl::widget(ui, crate::i18n::tr(&app.ui.language, "(import)"))).clicked() && let Some(m) = d.fields.get_mut("map").and_then(Value::as_object_mut) diff --git a/crates/ui-egui/src/i18n/ja.rs b/crates/ui-egui/src/i18n/ja.rs index 887b4bcdd..1753b1377 100644 --- a/crates/ui-egui/src/i18n/ja.rs +++ b/crates/ui-egui/src/i18n/ja.rs @@ -926,6 +926,9 @@ pub(super) const TABLE: &[(&str, &str)] = &[ (" Open sample magazine ", " サンプルマガジンを開く "), ("(Top Level)", "(最上位)"), ("(import)", "(読み込み)"), + ("Use Document Style Definition", "ドキュメントのスタイル定義を使用"), + ("Redefine Document Style", "ドキュメントのスタイルを再定義"), + ("Auto Rename", "自動で名前を変更"), ("Anchored Object", "アンカー付きオブジェクト"), ("Apply Attributes (Eyedropper", "属性を適用 (スポイト"), ("Baseline Grid", "ベースライングリッド"), @@ -1391,6 +1394,7 @@ pub(super) const TABLE: &[(&str, &str)] = &[ ("Col ←", "列 ←"), ("Col →", "列 →"), ("Row ↑", "行 ↑"), + ("Distribute Rows Evenly", "行の高さを揃える"), ("Row ↓", "行 ↓"), ("Hide Others", "他のレイヤーを隠す"), ("Lock Others", "他のレイヤーをロック"), @@ -1525,6 +1529,7 @@ pub(super) const TABLE: &[(&str, &str)] = &[ ("All records", "すべてのレコード"), ("One record", "1件のレコード"), ("Range", "範囲"), + ("Range:", "範囲:"), ("Records per page", "ページあたりのレコード"), ("Single record", "単一レコード"), ("Multiple records", "複数レコード"), diff --git a/crates/ui-egui/src/panels/table.rs b/crates/ui-egui/src/panels/table.rs index 0238d2960..79b434a76 100644 --- a/crates/ui-egui/src/panels/table.rs +++ b/crates/ui-egui/src/panels/table.rs @@ -52,7 +52,7 @@ pub fn show(app: &mut DesignApp, ui: &mut egui::Ui) { ("Col ←", "table.moveColumn", c0, c0.saturating_sub(1), c0 > 0), ("Col →", "table.moveColumn", c0, c0 + 1, c0 + 1 < nc), ] { - if ui.add_enabled(ok, egui::Button::new(crate::rtl::widget(ui, label)).small()).clicked() + if ui.add_enabled(ok, egui::Button::new(crate::rtl::widget(ui, crate::i18n::tr(&app.ui.language, label))).small()).clicked() && let Err(e) = app.run(id, json!({"from": from, "to": to})) { app.status(format!("Table: {e}")); diff --git a/docs/localization-parity.md b/docs/localization-parity.md index d36053202..21ce0904b 100644 --- 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-10 · **Change:** major (first version; catalogs measured) · **Target:** Adobe InDesign 2026 (21.6) +> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** minor (Japanese print, import and table controls localized; catalog counts remain the 2026-10-10 measurement) · **Target:** Adobe InDesign 2026 (21.6) Per-language status of the DesignCraft interface and of document typesetting in each script. Script-specific typesetting detail: [cjk.md](cjk.md), [cjk-typography.md](cjk-typography.md), @@ -43,6 +43,11 @@ come as Middle East editions with an English or French interface and right-to-le Percentages are of the 1,724 measured strings. A language is `full` only when every user-visible string is translated and its script renders and edits correctly; none but English is. +Japanese follow-up (2026-10-11): print ranges, imported style handling, the built-in `(import)` +caption, table row/column movement and row-height distribution now use the existing translation +catalog. Print, import options and an active table were rendered in Japanese and English with +craft-fonts. The language totals above retain their dated measurement; this is a targeted fix. + ## Other shipped languages | Language | Code | UI strings translated | Status | @@ -77,4 +82,5 @@ locale shaping. See [typography-parity.md](typography-parity.md). | Date | Change | Summary | |---|---|---| +| 2026-10-11 | minor | Localized Japanese print, import and table controls; checked Japanese and English renders | | 2026-10-10 | major | Created: catalogs measured (1,724 strings), the twelve key languages plus Italian and Ukrainian |