diff --git a/ATTRIBUTION.toml b/ATTRIBUTION.toml index 26abaaa8..7aa5e915 100644 --- a/ATTRIBUTION.toml +++ b/ATTRIBUTION.toml @@ -151,7 +151,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Ukrainian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "750c7229170e1ffd96b140ed13f0ce85a7c04a5223ed2648a75c96e2c0d65140" +sha256 = "55fb645e8983bd4396c3d70a7a53040bd260476b198d3cf2cf5d223f909e7436" [[asset]] path = "assets/icons/accessibility.svg" diff --git a/ROADMAP.md b/ROADMAP.md index b3b29ad1..1225b19f 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -106,7 +106,7 @@ Hours are for a single agent (low–high). "Done" is the estimated fraction of t | M11 | Optimize, preflight, PDF/A/X/UA, print production | 200–350 | 18% | 165–290 | Done: new `optimize` crate: Reduce File Size and the PDF Optimizer (images measured where drawn, bicubic downsampling, JPEG/ZIP recompression only when smaller, discard objects and user data, Flate clean-up, resource merging, object streams). Missing: fonts and transparency panels, space audit, preflight, PDF/A/X/UA | | M12 | Accessibility, compare, measure, search, XFA | 200–380 | 23% | 155–295 | Done: new `a11y` crate with the Accessibility Checker (all 32 rules, report, Fix/Skip/Explain, options dialog and results panel, agent tools). Done since: 2D distance, perimeter and area measurements with persistent viewport calibration, snapping, live information and CSV export. Missing: autotag, Tags/Order/Content panels, Reading Order tool, alt-text workflow, compare, geospatial/3D measurement, search index, XFA | | M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 33–66 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers | -| M14 | 1.0 polish: performance, localization, installers | 120–250 | 5% | 115–240 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`; Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Hungarian and Ukrainian catalogs have ≈1,800–2,000 entries each; Simplified Chinese, French, German, Hungarian and Ukrainian coverage is checked against the UI source; Czech and Brazilian Portuguese for menus. French locales (`fr`, `fr_FR`, `fr_CA`) follow the French catalog; Ukrainian locales (`uk`, `uk_UA`) follow the Ukrainian one. #307 (bounded large-PDF memory): share resource indexes and native parser metadata, inspect structure lazily, bound scan/full-save caches and raster storage, and reuse signature discovery safely. Three Linux trials retain full-save workflow RSS at 1.06 GiB (previously 3.69 GiB); rebased engine navigation uses 821 MiB (previously 997 MiB). With the RSS guard removed, the unmodified baseline was kernel OOM-killed in a 15 GiB container; rebased optimized inspection completed at 497.7 MiB in 1.78 s. Strict Clippy, 1,336 workspace tests and 30 WASM crate checks pass. The larger-host follow-up is closed. File-backed input, global memory budgets and Windows validation remain pending. Missing: more catalogs filled in, installers, performance budgets | +| M14 | 1.0 polish: performance, localization, installers | 120–250 | 5% | 115–240 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`; Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Hungarian and Ukrainian catalogs have ≈1,800–2,100 entries each; Simplified Chinese, French, German, Hungarian and Ukrainian coverage is checked against the UI source; Czech and Brazilian Portuguese for menus. French locales (`fr`, `fr_FR`, `fr_CA`) follow the French catalog; Ukrainian locales (`uk`, `uk_UA`) follow the Ukrainian one; its certificate and accessibility wording has a dictionary-checked follow-up. #307 (bounded large-PDF memory): share resource indexes and native parser metadata, inspect structure lazily, bound scan/full-save caches and raster storage, and reuse signature discovery safely. Three Linux trials retain full-save workflow RSS at 1.06 GiB (previously 3.69 GiB); rebased engine navigation uses 821 MiB (previously 997 MiB). With the RSS guard removed, the unmodified baseline was kernel OOM-killed in a 15 GiB container; rebased optimized inspection completed at 497.7 MiB in 1.78 s. Strict Clippy, 1,336 workspace tests and 30 WASM crate checks pass. The larger-host follow-up is closed. File-backed input, global memory budgets and Windows validation remain pending. Missing: more catalogs filled in, installers, performance budgets | | | **Total (original plan sizing)** | **2,085–3,840** | **≈ 35%** | **≈ 1,350–2,500 at the planned rate; ≈ 600–1,100 at the measured rate** | | **Overall progress: about 30–35% of the effort (51.0% of features shipped).** The viewer and the core are far ahead of the editing features, because the viewer was built first so progress could be seen; rendering itself is still borrowed from `hayro`. See [Honest assessment](#honest-assessment-2026-10-05). @@ -184,6 +184,8 @@ Newest first. One line per session: the date, what moved, and the new overall pe - **2026-10-09 (community, M5, #158):** Fill & Sign date format. Preferences ▸ Date format sets the pattern Fill & Sign dates use: 12 presets or any pattern in Acrobat date letters (with `\` escapes), checked and previewed as typed, remembered, and settable through `fill_sign_date_format`, `fill_sign_add` `format`/`language` and `ui set date-format`/`date-language`. Month and weekday names come in the interface languages (Czech in the genitive after a day), following the interface language unless one is picked. Fill & Sign text is still Helvetica/WinAnsi, so a date with other letters (Czech ř, Japanese, Chinese) is refused with a warning rather than saved as "?". This goes past Acrobat, whose Fill & Sign has no format setting. Overall estimate unchanged (about 30–35%). +- **2026-10-09 (M14, #503 follow-up):** Reviewed the complete Ukrainian catalog with VESUM 6.8.6 and manually checked the labels added when #509 landed. Certificate Subject now names the certificate holder separately from the document topic; certificate types and fingerprints, equal field sizes, keyboard/assistive-technology guidance and table sections use clearer contextual wording. Reviewed technical compounds and abbreviations remain unchanged. Overall effort estimate remains about 30–35%. + - **2026-10-09 (community, Home pinned folders):** Home gets a Folders section: File ▸ Pin folder to Home… (or "Pin a folder…" on Home) pins up to 8 folders, and each lists its newest PDFs (name, how long ago, size; 8 at first, up to 100 with Show more), one click to open, Unpin to remove. Folders are read on a worker thread and listed again every few seconds while Home shows, so new scans appear without reopening anything; a folder that can't be read (moved, offline synced drive) stays pinned and says so. Each folder is described by where it is ("iCloud Drive", "OneDrive · Contoso", "Documents › Work") rather than its full path, so two folders called "Scans" can be told apart. Cloud drives work through their local synced folder; nothing is read through a provider's API. Settings keep only absolute paths, without duplicates. Command label translated in every catalog; Home strings in French, Spanish, Japanese and both Chinese catalogs. Not yet: subfolders, search inside a pinned folder, the web build. Overall estimate unchanged (about 30–35%). - **2026-10-09 (community, M14, Telugu):** Telugu (తెలుగు, `te`) as a complete catalog of 1,984 entries covering every command, All tools entry, dialog, panel and notice; `te` and `te_IN` locales follow it. Telugu text is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, storytold/craft-fonts#10), kept in the web build too, after the CJK and Arabic faces; egui shapes its conjuncts. Commands use the plain imperative and sentences the polite form. The craft-fonts revision pinned for releases has no Telugu face yet, so release builds show Telugu as replacement boxes until the pin moves. Overall estimate unchanged (about 30–35%). diff --git a/crates/ui-egui/src/i18n/mod.rs b/crates/ui-egui/src/i18n/mod.rs index da944c6e..c17bab23 100644 --- a/crates/ui-egui/src/i18n/mod.rs +++ b/crates/ui-egui/src/i18n/mod.rs @@ -1640,6 +1640,8 @@ mod tests { assert_eq!(tr_ctx(uk, "comment menu", "Edit"), "Редагувати"); assert_eq!(tr_ctx(uk, "signature pad", "Type"), "Ввести"); assert_eq!(tr_ctx(uk, "action wizard", "Start"), "Почати"); + assert_eq!(tr(uk, "Subject"), "Тема"); + assert_eq!(tr_ctx(uk, "certificate", "Subject"), "Власник сертифіката"); let mut app = crate::PdfCraftApp::default(); app.set_option("language", "UK").unwrap(); assert_eq!(app.language, "uk"); diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index 1dc65fc0..080f8997 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -2090,17 +2090,19 @@ calendar date December грудня The Windows store's digital IDs couldn't be listed: {e} Не вдалося отримати список цифрових посвідчень зі сховища Windows: {e} Align fields Вирівняти поля Distribute fields Розподілити поля - Match field sizes Вирівняти розміри полів + Match field sizes Задати однакові розміри полів Mark for redaction Позначити для вилучення вмісту Mark pages for redaction Позначити сторінки для вилучення вмісту Change document properties Змінити властивості документа Mark differences Позначити відмінності Run form script Виконати сценарій форми - Scripted content must be usable with a keyboard and assistive technology. Check the document's scripts. Вміст зі сценаріями має бути доступним із клавіатури та допоміжних технологій. Перевірте сценарії документа. - Table rows belong directly in a table or its head, body or foot. Fix the table's tags. Рядки таблиці мають бути безпосередньо в таблиці або в її заголовку, тілі чи підсумку. Виправте теги таблиці. + Scripted content must be usable with a keyboard and assistive technology. Check the document's scripts. Вміст зі сценаріями має бути доступним для керування за допомогою клавіатури й допоміжних технологій. Перевірте сценарії документа. + Table rows belong directly in a table or its head, body or foot. Fix the table's tags. Рядки таблиці мають належати безпосередньо таблиці або її заголовній, основній чи нижній частині. Виправте теги таблиці. Basic constraints Основні обмеження - SHA-1 digest Дайджест SHA-1 - SHA-256 digest Дайджест SHA-256 + Certificate authority Центр сертифікації + End entity Кінцевий суб’єкт + SHA-1 digest Відбиток SHA-1 + SHA-256 digest Відбиток SHA-256 Squiggly Хвилясте Home / End Home / End H / Space (hold) H / Пробіл (утримувати) @@ -2125,3 +2127,4 @@ calendar date December грудня Printer properties Властивості принтера Reset to printer defaults Скинути до налаштувань принтера за замовчуванням This printer offers no settings of its own. Цей принтер не має власних налаштувань. +certificate Subject Власник сертифіката diff --git a/crates/ui-egui/src/sign_ui.rs b/crates/ui-egui/src/sign_ui.rs index bb453ff1..36b7fc87 100644 --- a/crates/ui-egui/src/sign_ui.rs +++ b/crates/ui-egui/src/sign_ui.rs @@ -1071,7 +1071,7 @@ pub(crate) fn cert_viewer(ui: &mut egui::Ui, v: &mut CertViewer, trusted: &[Cert ("Validity starts", c.not_before.to_string()), ("Validity ends", c.not_after.to_string()), ("Public key", c.public_key.describe()), - ("Basic constraints", if c.is_ca { "Certificate authority".into() } else { "End entity".into() }), + ("Basic constraints", tl!(if c.is_ca { "Certificate authority" } else { "End entity" }).to_string()), ("Key usage", c.key_usage.map(key_usage).unwrap_or_else(|| tl!("Not present").to_string())), ("Self-signed", if c.is_self_signed() { tl!("Yes").to_string() } else { tl!("No").to_string() }), ("SHA-1 digest", hex(&sign::keys::DigestAlg::Sha1.digest(&[&c.raw]))),