From bbc99126dbb0bfc1a018ca7f5e87e3667d8fad15 Mon Sep 17 00:00:00 2001 From: CindyGest <111882715+txiki739@users.noreply.github.com> Date: Thu, 15 Oct 2026 08:41:10 +0200 Subject: [PATCH] =?UTF-8?q?i18n(es):=20translate=20the=20new=20print=20and?= =?UTF-8?q?=20Add=20text=20strings,=20Type=20on=20the=20signature=20pad,?= =?UTF-8?q?=20t=C3=BA=20register=20(#2049)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * i18n(es): translate the new print and Add text strings, Type on the signature pad, tú register Seven tl! literals reached the Spanish UI in English: the PDF page size, Match page at 100%, PDF scale and the two scale hints in the print dialog, and the Done / Discard buttons of Add text. The signature pad's Type button read "Tipo" (the noun) because Spanish had no `signature pad` entry; it now reads "Escribir", beside Dibujar, Imagen and Escanear. Four rows used the formal usted register the catalog header rules out (Elija, Cámbielo, the signature-photo hint, the no-signature notice); they now use tú like the rest. Spanish gains `spanish_covers_ui_literals`, the check Japanese, Italian, French, German and others already have, and its command test checks menu names too, so a new string can't ship in English by accident. `contextual_labels_fall_back_to_the_plain_translation` used Spanish's missing `signature pad` entry as its example; it now uses a context no catalog defines, so it keeps testing the fallback as catalogs fill in. Co-Authored-By: Claude Opus 5.5 * Refresh catalog hashes after merging main --------- Co-authored-by: Claude Opus 5.5 Co-authored-by: Brandon Thomas --- ATTRIBUTION.toml | 2 +- crates/ui-egui/src/i18n/es.tsv | 18 ++++++++++++++---- crates/ui-egui/src/i18n/mod.rs | 18 +++++++++++++++++- parity/acrobat-features.toml | 2 +- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/ATTRIBUTION.toml b/ATTRIBUTION.toml index fcf3570cc..ddeeb86b6 100644 --- a/ATTRIBUTION.toml +++ b/ATTRIBUTION.toml @@ -74,7 +74,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Spanish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "df205fdfc750a3f9de5a667710506f09fbf5604d632576b0085f8f0560cf1bfd" +sha256 = "f4a3c6f7c33b31f489c3e7e3f23084ccbd0c31567e7d665d9c583ff4f9b56af7" [[asset]] path = "crates/ui-egui/src/i18n/fr.tsv" diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index 1176902b3..5fada5d9a 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -1646,6 +1646,7 @@ comment menu Edit Editar Undo {action} Deshacer {action} Redo {action} Rehacer {action} +signature pad Type Escribir certificate Subject Titular action wizard Start Iniciar Click to sort, drag to move the column. Drag its edge to resize it. Haz clic para ordenar; arrastra para mover la columna. Arrastra su borde para cambiar el ancho. @@ -2164,7 +2165,7 @@ action wizard Start Iniciar Only continue if you trust this document. An address can carry information from the document, such as what you typed into its form. Continúa solo si confías en este documento. Una dirección puede llevar información del documento, como lo que escribiste en su formulario. Print single-sided. Keep the sheets in order, cut at the marks, then stack the piles left to right, top to bottom. Imprime a una cara. Mantén las hojas en orden, corta por las marcas y apila los montones de izquierda a derecha y de arriba abajo. For page sizes and margins. Para tamaños de página y márgenes. - The PDF text fonts can't draw “{c}” ({code}). Choose supported text. Las fuentes de texto PDF no pueden mostrar «{c}» ({code}). Elija texto compatible. + The PDF text fonts can't draw “{c}” ({code}). Choose supported text. Las fuentes de texto PDF no pueden mostrar «{c}» ({code}). Elige texto compatible. The standard fonts can't draw “{c}” ({code}). Only Western European characters can be added as text for now. Las fuentes estándar no pueden mostrar «{c}» ({code}). Por ahora solo se pueden añadir como texto caracteres de Europa occidental. This field's font can't draw “{c}” ({code}), so PdfCraft shows ? in its place. The value is saved, and other PDF viewers redraw the field from it. La fuente de este campo no puede mostrar «{c}» ({code}), así que PdfCraft muestra ? en su lugar. El valor se guarda y los demás visores de PDF vuelven a dibujar el campo a partir de él. The fonts PdfCraft writes with can't draw “{c}” ({code}), so it shows as ? in every PDF viewer. The text is saved. Las fuentes con las que escribe PdfCraft no pueden mostrar «{c}» ({code}), así que aparece como ? en todos los visores de PDF. El texto se guarda. @@ -2399,6 +2400,13 @@ key Space Espacio Resize panel window Cambiar tamaño de la ventana del panel Tools Herramientas Inspector Inspector + +# Architectural print controls (follow-up to #599). + PDF page: {size} Página PDF: {size} + Match page at 100% Ajustar el papel a la página al 100 % + PDF scale: {scale}% Escala del PDF: {scale} % + Printer paper and scaling may differ. Check driver settings. El papel y la escala de la impresora pueden variar. Revisa los ajustes del controlador. + Drawing scale changes. Use Actual size for full-scale plans. La escala del dibujo cambia. Usa Tamaño real para los planos a escala. Select page {label} Seleccionar la página {label} Rotate page {label} counterclockwise Girar la página {label} a la izquierda Rotate page {label} clockwise Girar la página {label} a la derecha @@ -2413,13 +2421,15 @@ animation effects Off Desactivados Enhance camera image Mejorar foto de cámara Drag the corners onto the document's edges, then choose Enhance page. Arrastra las esquinas hasta los bordes del documento y elige Mejorar página. Enhance page Mejorar página + Done adding text Terminar de añadir texto + Discard this text (Esc) Descartar este texto (Esc) Certificate authority Autoridad de certificación End entity Entidad final Clean-up Limpieza Original Original Greyscale Escala de grises Black and white Blanco y negro - This printer's driver doesn't take two-sided settings from other programs, so its own setting applies. Change it in Properties… El controlador de esta impresora no acepta los ajustes de doble cara de otros programas, así que se aplica su propio ajuste. Cámbielo en Propiedades… + This printer's driver doesn't take two-sided settings from other programs, so its own setting applies. Change it in Properties… El controlador de esta impresora no acepta los ajustes de doble cara de otros programas, así que se aplica su propio ajuste. Cámbialo en Propiedades… Browser's print dialog Diálogo de impresión del navegador Copies, two-sided printing and colour are chosen in the browser's print dialog. Las copias, la impresión a doble cara y el color se eligen en el diálogo de impresión del navegador. Preparing {n} sheets for printing… Preparando {n} hojas para imprimir… @@ -2448,12 +2458,12 @@ animation effects Off Desactivados no output folder was chosen no se eligió ninguna carpeta de salida @plural Downloaded {n} PDF|Downloaded {n} PDFs Se descargó {n} PDF|Se descargaron {n} PDF Scan Escanear - Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Firme en una hoja de papel blanco y hágale una foto con luz intensa y uniforme (use el flash). Elija la foto o suéltela aquí: PdfCraft encuentra la firma y elimina el papel. + Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Firma en una hoja de papel blanco y hazle una foto con luz intensa y uniforme (usa el flash). Elige la foto o suéltala aquí: PdfCraft encuentra la firma y elimina el papel. Choose photo… Elegir foto… No photo chosen No se ha elegido ninguna foto Photo Foto Ink sensitivity Sensibilidad de la tinta - No signature was found in the frame. Move the frame over the signature or raise the ink sensitivity. No se encontró ninguna firma en el marco. Mueva el marco sobre la firma o aumente la sensibilidad de la tinta. + No signature was found in the frame. Move the frame over the signature or raise the ink sensitivity. No se encontró ninguna firma en el marco. Mueve el marco sobre la firma o aumenta la sensibilidad de la tinta. Couldn't use the photo: {e} No se puede usar la foto: {e} # PDF tab context menu (#1233) diff --git a/crates/ui-egui/src/i18n/mod.rs b/crates/ui-egui/src/i18n/mod.rs index 9257018a7..5bb2889c9 100644 --- a/crates/ui-egui/src/i18n/mod.rs +++ b/crates/ui-egui/src/i18n/mod.rs @@ -1186,6 +1186,8 @@ mod tests { assert_eq!(tr(es, "Informe del usuario.pdf"), "Informe del usuario.pdf"); assert_eq!(trn(es, 1, "{n} page", "{n} pages"), "1 página"); assert_eq!(trn(es, 3, "{n} page", "{n} pages"), "3 páginas"); + // The signature pad's Type is the verb (type your name), not the noun "Tipo". + assert_eq!(tr_ctx(es, "signature pad", "Type"), "Escribir"); let mut app = crate::PdfCraftApp::default(); app.set_option("language", "es").unwrap(); assert_eq!(app.language, "es"); @@ -1200,6 +1202,9 @@ mod tests { let es = Lang::from_code("es").expect("es registered"); for command in pdfcraft_engine::commands::COMMANDS { assert!(has(es, command.label), "missing command: {}", command.label); + if let Some(menu) = command.menu { + assert!(has(es, menu), "missing menu: {menu}"); + } } for group in pdfcraft_engine::catalog::TOOL_GROUPS { assert!(has(es, group.label), "missing group: {}", group.label); @@ -1212,6 +1217,16 @@ mod tests { } } + /// New tl!("literal") labels must not silently fall back to English in Spanish. + #[test] + fn spanish_covers_ui_literals() { + let es = Lang::from_code("es").expect("es registered"); + let literals = ui_literals(); + assert!(literals.len() > 900, "source scan found only {} literals", literals.len()); + let missing: Vec<_> = literals.iter().filter(|label| !has(es, label)).collect(); + assert!(missing.is_empty(), "untranslated Spanish UI literals: {missing:#?}"); + } + /// Spanish says everything the layers below word for themselves: what the accessibility /// checker finds and what its saved report calls things, what the PDF/A verifier reports, what /// a signature's details say and the changes they name, what can be wrong with the pages to @@ -1306,8 +1321,9 @@ mod tests { let te = Lang::from_code("te").expect("te registered"); assert_eq!(tr_ctx(te, "signature pad", "Type"), "టైప్ చేయి"); assert_eq!(tr(te, "Type"), "రకం"); + // A context no catalog defines, so the fallback stays tested as catalogs fill their gaps. let es = Lang::from_code("es").expect("es registered"); - assert_eq!(tr_ctx(es, "signature pad", "Type"), tr(es, "Type")); + assert_eq!(tr_ctx(es, "no such context", "Type"), tr(es, "Type")); } /// Telugu translates every registered command and every All tools group, section and item. diff --git a/parity/acrobat-features.toml b/parity/acrobat-features.toml index 5f292944b..bf70bfe5d 100644 --- a/parity/acrobat-features.toml +++ b/parity/acrobat-features.toml @@ -9940,7 +9940,7 @@ milestone = "M14" status = "partial" commands = ["app.preferences"] tools = [] -evidence = ["crates/ui-egui/src/commands.rs::localized_shortcut_labels_follow_language_and_platform", "crates/ui-egui/src/i18n/mod.rs::keyboard_key_names_have_a_separate_context_and_english_fallback", "crates/ui-egui/tests/commands.rs::localized_shortcuts_update_immediately_and_keep_command_ids_and_key_bindings", "crates/ui-egui/src/i18n/mod.rs::windows_display_language_resolves_chinese_scripts", "crates/ui-egui/src/i18n/mod.rs::neutral_locale_does_not_override_display_language", "crates/ui-egui/src/i18n/mod.rs::windows_display_language_query_returns_a_locale_tag", "crates/ui-egui/src/i18n/mod.rs::language_persists_and_invalid_input_keeps_current_language", "crates/ui-egui/src/i18n/mod.rs::bundled_catalogs_are_consistent", "crates/ui-egui/src/i18n/mod.rs::arabic_is_registered_and_persists", "crates/ui-egui/src/i18n/mod.rs::arabic_lookups_are_in_display_order", "crates/ui-egui/src/i18n/mod.rs::arabic_plurals_follow_the_six_cldr_forms", "crates/ui-egui/src/i18n/mod.rs::arabic_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::arabic_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::arabic_labels_have_glyphs", "crates/ui-egui/src/bidi.rs::rtl_labels_keep_placeholders_whole", "crates/ui-egui/src/i18n/mod.rs::japanese_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_history_and_diagnostics_preserve_user_values", "crates/ui-egui/tests/control.rs::simplified_chinese_signature_prompts_and_errors_keep_document_state", "crates/ui-egui/tests/control.rs::language_switch_preserves_document_and_command_ids", "crates/ui-egui/tests/control.rs::japanese_controls_and_search_keep_command_ids", "crates/ui-egui/tests/control.rs::japanese_dialogs_errors_and_custom_action_names", "crates/ui-egui/src/i18n/mod.rs::french_is_registered", "crates/ui-egui/src/i18n/mod.rs::french_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::french_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::french_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::german_certificate_subject_has_a_distinct_context", "crates/ui-egui/src/widgets.rs::search_placeholder_never_overlaps_the_shortcut", "crates/ui-egui/src/home.rs::translated_card_description_leaves_room_for_the_action", "crates/ui-egui/tests/control.rs::german_preferences_and_search_keep_command_ids", "crates/ui-egui/src/i18n/mod.rs::telugu_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::telugu_labels_have_glyphs", "crates/ui-egui/src/i18n/mod.rs::hungarian_is_registered", "crates/ui-egui/src/i18n/mod.rs::hungarian_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::hungarian_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::hungarian_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::ukrainian_is_registered_and_persists", "crates/ui-egui/src/i18n/mod.rs::ukrainian_integer_plurals_cover_teens_and_large_counts", "crates/ui-egui/src/i18n/mod.rs::ukrainian_calendar_uses_month_case_for_dates", "crates/ui-egui/src/i18n/mod.rs::ukrainian_catalog_does_not_leave_english_ui_text", "crates/ui-egui/src/i18n/mod.rs::ukrainian_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::ukrainian_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::ukrainian_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::spanish_covers_what_the_engine_says", "crates/ui-egui/src/i18n/mod.rs::spanish_keeps_the_holes_in_what_the_engine_says", "crates/print/src/tests.rs::wordings_are_said"] +evidence = ["crates/ui-egui/src/commands.rs::localized_shortcut_labels_follow_language_and_platform", "crates/ui-egui/src/i18n/mod.rs::keyboard_key_names_have_a_separate_context_and_english_fallback", "crates/ui-egui/tests/commands.rs::localized_shortcuts_update_immediately_and_keep_command_ids_and_key_bindings", "crates/ui-egui/src/i18n/mod.rs::windows_display_language_resolves_chinese_scripts", "crates/ui-egui/src/i18n/mod.rs::neutral_locale_does_not_override_display_language", "crates/ui-egui/src/i18n/mod.rs::windows_display_language_query_returns_a_locale_tag", "crates/ui-egui/src/i18n/mod.rs::language_persists_and_invalid_input_keeps_current_language", "crates/ui-egui/src/i18n/mod.rs::bundled_catalogs_are_consistent", "crates/ui-egui/src/i18n/mod.rs::arabic_is_registered_and_persists", "crates/ui-egui/src/i18n/mod.rs::arabic_lookups_are_in_display_order", "crates/ui-egui/src/i18n/mod.rs::arabic_plurals_follow_the_six_cldr_forms", "crates/ui-egui/src/i18n/mod.rs::arabic_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::arabic_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::arabic_labels_have_glyphs", "crates/ui-egui/src/bidi.rs::rtl_labels_keep_placeholders_whole", "crates/ui-egui/src/i18n/mod.rs::japanese_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_history_and_diagnostics_preserve_user_values", "crates/ui-egui/tests/control.rs::simplified_chinese_signature_prompts_and_errors_keep_document_state", "crates/ui-egui/tests/control.rs::language_switch_preserves_document_and_command_ids", "crates/ui-egui/tests/control.rs::japanese_controls_and_search_keep_command_ids", "crates/ui-egui/tests/control.rs::japanese_dialogs_errors_and_custom_action_names", "crates/ui-egui/src/i18n/mod.rs::french_is_registered", "crates/ui-egui/src/i18n/mod.rs::french_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::french_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::french_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::german_certificate_subject_has_a_distinct_context", "crates/ui-egui/src/widgets.rs::search_placeholder_never_overlaps_the_shortcut", "crates/ui-egui/src/home.rs::translated_card_description_leaves_room_for_the_action", "crates/ui-egui/tests/control.rs::german_preferences_and_search_keep_command_ids", "crates/ui-egui/src/i18n/mod.rs::telugu_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::telugu_labels_have_glyphs", "crates/ui-egui/src/i18n/mod.rs::hungarian_is_registered", "crates/ui-egui/src/i18n/mod.rs::hungarian_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::hungarian_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::hungarian_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::ukrainian_is_registered_and_persists", "crates/ui-egui/src/i18n/mod.rs::ukrainian_integer_plurals_cover_teens_and_large_counts", "crates/ui-egui/src/i18n/mod.rs::ukrainian_calendar_uses_month_case_for_dates", "crates/ui-egui/src/i18n/mod.rs::ukrainian_catalog_does_not_leave_english_ui_text", "crates/ui-egui/src/i18n/mod.rs::ukrainian_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::ukrainian_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::ukrainian_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::spanish_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::spanish_covers_what_the_engine_says", "crates/ui-egui/src/i18n/mod.rs::spanish_keeps_the_holes_in_what_the_engine_says", "crates/print/src/tests.rs::wordings_are_said"] notes = "Shortcut modifiers and key names use a dedicated catalog context across toolbar, menus, palette, Help and tooltips, with English fallback and macOS symbols preserved. Preferences switches Auto (system language)/English/Japanese/Simplified Chinese/Traditional Chinese/Czech/Brazilian Portuguese/German/Spanish/French/Telugu/Hungarian/Ukrainian/Italian/Arabic and persists; ui.set language auto|en|ja|zh-hans|zh-hant|cs|pt-br|de|es|fr|te|hu|uk|it|ar and ui.state expose it. TSV catalogs per language (same system as PhotoCraft); every dialog, panel and notice goes through tl!. Japanese, Traditional Chinese, Simplified Chinese, German, Spanish, French and Hungarian cover commands, dialogs, panels, shortcuts and history labels; Czech and Brazilian Portuguese the menus. French locales (fr, fr_FR, fr_CA, fr_BE) select the French catalog, German locales (de, de_DE, de_AT, de_CH) the German one, Hungarian locales (hu, hu_HU) the Hungarian one. German search hints reserve shortcut space, Home cards bound translated text, certificate Subject has its own context, and inserted tool names keep their capitalization. The sentences the layers below word for themselves (accessibility findings and the saved report, PDF/A problems, signature details, page-range mistakes, edit labels) are handed over apart from the document's own values and go through the catalog too, through said(&i18n::words); Spanish translates them and the other catalogs fall back to English. OS error details, and faults rather than mistakes, stay as they are. Auto detects the Windows display language after explicitly named supported locale overrides; neutral C/POSIX launcher locales are skipped on Windows, with Chinese script/region mapping and English fallback. Arabic (ar and every ar-* locale) covers commands, dialogs and panels with the six CLDR plural forms; its labels are put into display order when the catalog loads, because egui joins Arabic letters but lays words out left to right. Missing: a right-to-left layout (Arabic labels sit in the left-to-right layout, a wrapped Arabic paragraph breaks at the wrong end, and text typed into a field is not reordered), Czech and Brazilian Portuguese dialogs, Chinese and Telugu font delivery in releases (the pinned craft-fonts revision has an Arabic face; its Noto Sans CJK SC is never embedded, AGENTS.md §1.1), the engine's sentences in the other catalogs, a full localization audit." [[feature]]