From 3468c8543f8fb1dbb882ec145e4ab0eecdc1b7eb Mon Sep 17 00:00:00 2001 From: Marco Arnulfo Date: Fri, 16 Oct 2026 02:43:02 +0200 Subject: [PATCH] fix(print): disable Print on documents whose security forbids printing (part of #2669) --- ATTRIBUTION.toml | 44 ++++++++++++------------- crates/engine/src/commands.rs | 5 ++- crates/engine/src/tests.rs | 18 +++++++++++ crates/ui-egui/src/chrome.rs | 8 ++++- crates/ui-egui/src/commands.rs | 1 + crates/ui-egui/src/i18n/ar.tsv | 1 + crates/ui-egui/src/i18n/bg.tsv | 1 + crates/ui-egui/src/i18n/cs.tsv | 1 + crates/ui-egui/src/i18n/de.tsv | 1 + crates/ui-egui/src/i18n/el.tsv | 1 + crates/ui-egui/src/i18n/es.tsv | 1 + crates/ui-egui/src/i18n/fr.tsv | 1 + crates/ui-egui/src/i18n/hu.tsv | 1 + crates/ui-egui/src/i18n/it.tsv | 1 + crates/ui-egui/src/i18n/ja.tsv | 1 + crates/ui-egui/src/i18n/kk.tsv | 1 + crates/ui-egui/src/i18n/lt.tsv | 1 + crates/ui-egui/src/i18n/pl.tsv | 1 + crates/ui-egui/src/i18n/pt-br.tsv | 1 + crates/ui-egui/src/i18n/ru.tsv | 1 + crates/ui-egui/src/i18n/sl.tsv | 1 + crates/ui-egui/src/i18n/te.tsv | 1 + crates/ui-egui/src/i18n/tr.tsv | 1 + crates/ui-egui/src/i18n/uk.tsv | 1 + crates/ui-egui/src/i18n/vi.tsv | 1 + crates/ui-egui/src/i18n/zh-hans.tsv | 1 + crates/ui-egui/src/i18n/zh-hant.tsv | 1 + crates/ui-egui/src/lib.rs | 4 +++ crates/ui-egui/tests/print.rs | 50 +++++++++++++++++++++++++++++ parity/acrobat-features.toml | 2 +- 30 files changed, 129 insertions(+), 25 deletions(-) diff --git a/ATTRIBUTION.toml b/ATTRIBUTION.toml index db3dd6124..ce45c74d9 100644 --- a/ATTRIBUTION.toml +++ b/ATTRIBUTION.toml @@ -7,7 +7,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Greek UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "6eee0b34db6529f26235bfc07fa1fdb9030b8e7b0b10ede271ca9242cb491919" +sha256 = "66a6fefdf9a249e78a99a25ed5bcb7c242c48424e72a15dbf680783d93a5cbb2" # ATTRIBUTION.toml: one entry per asset (AGENTS.md §1). The source of truth for provenance and licences. # ATTRIBUTION.md is generated from this file: `cargo xtask assets --write`. Checked by `cargo xtask assets` (part of `xtask ci`). @@ -30,7 +30,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Simplified Chinese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "9870c0fb9f7198155be16adee7f45d36cb9a254af90b545a3ce5b04cbbbf24d4" +sha256 = "27b4f7bbecd334b9afec112ec4af1cf2a9e0d1a03d779eea6bd7b5ddd53ce65a" [[asset]] path = "crates/ui-egui/src/i18n/zh-hant.tsv" @@ -41,7 +41,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Traditional Chinese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "fc31e40877ce115cfb7033c57dd6acabcae3725b249364387e3fe23e04d94e5e" +sha256 = "f9f2726c2fde84838cb3847bba236c1c9071de0de727baf6792250d5d306dc89" [[asset]] path = "crates/ui-egui/src/i18n/cs.tsv" @@ -52,7 +52,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Czech UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "5de19834f293efaea68cb6b7f51a71d320391f53345f56cfebcd73dab828b665" +sha256 = "673927d13eccc8dc1842355423b02e3289c9531756a90038ca5a1129cac47b1c" [[asset]] path = "crates/ui-egui/src/i18n/pt-br.tsv" @@ -63,7 +63,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Brazilian Portuguese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "cef0d22341d0722f029c6543fc846fce164331b7ad8f693a6754b7567b9d9e95" +sha256 = "80965a09f5954b4d74bceb425a4ce99add4f14a12052c39f8a4264b4866d74cf" [[asset]] path = "crates/ui-egui/src/i18n/es.tsv" @@ -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 = "c0ca7761cbabd8096bc9af54cdf6b88b3ae0cd8210003db8b3356e2706e44fc8" +sha256 = "52dccd8c26e353b4fafc98c281b187efe6d73173b27e6ed004951c8c6e177865" [[asset]] path = "crates/ui-egui/src/i18n/fr.tsv" @@ -85,7 +85,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "French UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "a8afd51c3296f44b0446d6b06492b1348444b3e3c448a326ad213d18ce7af714" +sha256 = "1349c8c928a06979f78c01bc2cb6d01238b8740b644a442eb859a47efc83c39c" [[asset]] path = "crates/ui-egui/src/i18n/de.tsv" @@ -96,7 +96,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "German UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "7676a2dfaa7d66e2e9ef608d2d9de7f863557dcecbef6d94bafa981097405e6d" +sha256 = "912ce3994630b9567b8715dfbd4f9c94e93981405072fa1333004401fa7aa500" [[asset]] path = "crates/ui-egui/src/i18n/te.tsv" @@ -107,7 +107,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Telugu UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "9a22996c0308ea5b20ec5e328504cd83cbb560147763faaf0e6987f974844c29" +sha256 = "b11e184dcf3f3009355bd5a0c3a89f74444526d5b83a320e4ed38d3f4bdf0cb5" [[asset]] path = "crates/ui-egui/src/i18n/it.tsv" @@ -118,7 +118,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Italian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "eacc972d65a2d951e94e1a8cf944638e8328f73f6c05759de6059a425f159cd7" +sha256 = "ce9928ec2fb669bdbbda46b68c13b4a0a65e803bcafce81fc45e67b524f42cfa" [[asset]] path = "crates/ui-egui/src/i18n/pl.tsv" @@ -129,7 +129,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Polish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "dfa4aa540cc7d61fa22a27a949e6eec0f78dcc5b883d0e4e004d695e460b95aa" +sha256 = "94f201eb0db015ac83088114b1ac81821184d547d703b4f7c08d85fff5b5caa9" [[asset]] path = "crates/ui-egui/src/i18n/ru.tsv" @@ -140,7 +140,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Russian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "27e02e7bb3d378bceca76988a9dceaa68d974f57cbee962954deca6184cf62aa" +sha256 = "8ff506154703c629a548adcf5b38bb34b537f5f2eeec5854028d523388c6ce08" [[asset]] path = "crates/ui-egui/src/i18n/hu.tsv" @@ -151,7 +151,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Hungarian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "9675edd36c5ae54d9893fd10c4325aab664941bf714c08fbfeef9134fa42056c" +sha256 = "b8794ff615b0ff4e1a6e918c94fdffe30ca019c2d29830bf82e8f9fc342bd061" [[asset]] path = "crates/ui-egui/src/i18n/bg.tsv" @@ -162,7 +162,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Bulgarian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "ce18fc96f8516aa917e4a8bcfd290edec13a9800b3d1ee102e4b2a71b8467d2b" +sha256 = "1d50f941c6e337e219adba150264081baac7536267d69ab4f78677d62f5c05fa" [[asset]] path = "crates/ui-egui/src/i18n/kk.tsv" @@ -173,7 +173,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Kazakh UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "286a1e2e051748eb4bcee3906918dc78d0704f8a37bde22dc50d3376d5e75017" +sha256 = "18761eafa7e170447c2eee86a4a648a30b536eaea305fa5665561f759fc32f59" [[asset]] path = "crates/ui-egui/src/i18n/ja.tsv" @@ -184,7 +184,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Japanese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "77593b7497c67f4a79cc31fa43fdd6eae11601dd87c079a8e666b25cdd9117ba" +sha256 = "340c18d0cb6869d71ff94aad0d234aafc6fc061482517d86accf2ff46523b5f9" [[asset]] path = "crates/ui-egui/src/i18n/uk.tsv" @@ -195,7 +195,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 = "d7d93a03f22ab380696f69b20b12104bf30e78c4440b683df63594af716894e2" +sha256 = "25b31a55949e1c0a5ff387b2b7fb1a746f9b198d978129244f717cf23374ae8c" [[asset]] path = "crates/ui-egui/src/i18n/ar.tsv" @@ -206,7 +206,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Arabic UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "889a0d0a9ea53ca0a818c2ba672c053c232d2cca140f8d63127353e6f36505fe" +sha256 = "bad7be0d9c36d403b505e69d8235fcda157b5510124a9df94b663e7c0b42f45f" [[asset]] path = "crates/ui-egui/src/i18n/tr.tsv" @@ -217,7 +217,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Turkish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "bae8b21651ae2a69c71c91b69ba79727254dbfb078c1be312a13383332934927" +sha256 = "8a7a89926f235e2ff2ff5b95adf9229d4e1a1d0ff8c9b9b58e24c5ade7f74116" [[asset]] path = "crates/ui-egui/src/i18n/lt.tsv" @@ -228,7 +228,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Lithuanian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "7fa70f68a9fa24d0b1cac05fe3aaabaeaca9750c57416124bd317a4eda806d5a" +sha256 = "11cf9d15269bdc755c0a6127bd09931de3703ab195f302149a44f65bee916829" [[asset]] @@ -3352,7 +3352,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Vietnamese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "95b5fc6d10f7bc8371688772741870448de716fa2dd9af62fdfe4e009d269b45" +sha256 = "8ad0a39be936b14c3fb75e3f2c983ad6326a82fcfd1db7334aae9c15594ebbf7" [[asset]] path = "crates/ui-egui/src/i18n/sl.tsv" @@ -3363,7 +3363,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Slovene UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "3ac2b113045b7e399dd6d9ddb7773e5b0874c8b43c2ba4cca5854598a2a7ba92" +sha256 = "eabf2b951dfdfa424a42915da3d6c675ca5a27861e87836e0b0bcfd8aaaa66c0" [[asset]] diff --git a/crates/engine/src/commands.rs b/crates/engine/src/commands.rs index fcd56efee..4d8452afd 100644 --- a/crates/engine/src/commands.rs +++ b/crates/engine/src/commands.rs @@ -26,6 +26,8 @@ pub enum Needs { Annotate, /// The open document's security allows copying text and images out of it. Copying, + /// The open document's security allows printing (low resolution counts). + Printing, /// The document has form fields and its security allows filling them in. FillForms, /// The document has comments and allows changes. @@ -188,7 +190,7 @@ pub const COMMANDS: &[CommandSpec] = &[ c("file.close", "Close file", FILE, Some(Shortcut::cmd("W")), Document, "x"), c("file.close_all", "Close all", FILE, Some(Shortcut::cmd_shift("W")), Document, "x"), c("file.revert", "Revert", FILE, None, Undo, "rotate-ccw"), - c("print.dialog", "Print…", FILE, Some(Shortcut::cmd("P")), Document, "printer"), + c("print.dialog", "Print…", FILE, Some(Shortcut::cmd("P")), Printing, "printer"), c("file.properties", "Document properties…", FILE, Some(Shortcut::cmd("D")), Document, "info"), c("file.word_count", "Word count…", FILE, None, Copying, "hash"), ct("edit.undo", "Undo", EDIT, Some(Shortcut::cmd("Z")), Undo, "undo-2"), @@ -398,6 +400,7 @@ pub fn is_enabled(spec: &CommandSpec, session: &Session, active: Option) Modification => doc.is_some_and(|d| d.allows_modification()), Annotate => doc.is_some_and(|d| d.allows_annotation()), Copying => doc.is_some_and(|d| d.allows_copying()), + Printing => doc.is_some_and(|d| d.allows_printing()), FillForms => doc.is_some_and(|d| d.allows_form_filling() && !d.form.is_empty()), Marks(k) => doc.is_some_and(|d| d.allows_modification() && d.marks().contains(&k)), HasComments => doc.is_some_and(|d| d.allows_modification() && !d.info.annotations.is_empty()), diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index d5ffac500..32288ea6e 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -1210,6 +1210,24 @@ fn copy_restricted_documents_refuse_extraction_unless_opened_by_the_owner() { assert!(s.get(plain).unwrap().check_copying().is_ok() && extracting.iter().all(|c| enabled(&s, plain, c))); } +/// Table 22, bit 3 (#2669): a document that forbids printing disables Print up front instead +/// of refusing once the dialog is confirmed. Low-resolution printing (bit 3 on, bit 12 off) is +/// still printing, and the owner password lifts the restriction. +#[test] +fn print_restricted_documents_disable_print_unless_opened_by_the_owner() { + let enabled = |s: &Session, id, c| commands::is_enabled(commands::command(c).unwrap(), s, Some(id)); + let bytes = protected("", "owner", -1 ^ 0b100); + let mut s = Session::new(); + let id = s.open("r.pdf", None, bytes.clone(), None).unwrap(); + assert!(!s.get(id).unwrap().allows_printing()); + assert!(!enabled(&s, id, "print.dialog")); + assert!(enabled(&s, id, "export.text"), "only printing is withheld"); + let oid = s.open("r.pdf", None, bytes, Some("owner")).unwrap(); + assert!(enabled(&s, oid, "print.dialog"), "the owner may print"); + let low = s.open("low.pdf", None, protected("", "owner", -1 ^ (1 << 11)), None).unwrap(); + assert!(enabled(&s, low, "print.dialog"), "low-resolution printing is printing"); +} + #[test] fn the_permissions_password_unlocks_an_open_document() { // Only a permissions password (#995, #1077): opens without asking. Changes are allowed, diff --git a/crates/ui-egui/src/chrome.rs b/crates/ui-egui/src/chrome.rs index fb9e0a7c0..5a3efcebe 100644 --- a/crates/ui-egui/src/chrome.rs +++ b/crates/ui-egui/src/chrome.rs @@ -512,7 +512,13 @@ pub fn mode_bar(app: &mut PdfCraftApp, ui: &mut egui::Ui) { let has_doc = app.active.is_some(); ui.add_enabled_ui(has_doc, |ui| { let tip = crate::commands::command_tip(ui.ctx(), tl!("Print ({key})"), "print.dialog"); - if icons::button(ui, "printer", 32.0, false, &tip).clicked() { + // A document that forbids printing says so here, before the dialog (#2669). + let may_print = !has_doc || pdfcraft_engine::commands::command("print.dialog").is_some_and(|c| app.command_enabled(c)); + let mut print = ui.add_enabled_ui(may_print, |ui| icons::button(ui, "printer", 32.0, false, &tip)).inner; + if !may_print { + print = print.on_disabled_hover_text(crate::print_refused()); + } + if print.clicked() { app.run_command("print.dialog"); } let tip = crate::commands::command_tip(ui.ctx(), tl!("Save ({key})"), "file.save"); diff --git a/crates/ui-egui/src/commands.rs b/crates/ui-egui/src/commands.rs index 832ce7cfb..ae5bc2ff1 100644 --- a/crates/ui-egui/src/commands.rs +++ b/crates/ui-egui/src/commands.rs @@ -143,6 +143,7 @@ impl PdfCraftApp { tl!("The document's security settings don't allow this change").to_string() } commands::Needs::Copying if self.active.is_some() => crate::copy_refused().to_string(), + commands::Needs::Printing if self.active.is_some() => crate::print_refused().to_string(), commands::Needs::TwoPageView if self.active.is_some() => tl!("Switch to two-page view first to show the cover page").to_string(), _ => tl!("Open a document first").to_string(), }; diff --git a/crates/ui-egui/src/i18n/ar.tsv b/crates/ui-egui/src/i18n/ar.tsv index 8697887e1..a3041cf33 100644 --- a/crates/ui-egui/src/i18n/ar.tsv +++ b/crates/ui-egui/src/i18n/ar.tsv @@ -1764,6 +1764,7 @@ This document has no restrictions to lift لا توجد في هذا المستند قيود لرفعها The document's security settings don't allow this change إعدادات أمان المستند لا تسمح بهذا التغيير The document's security settings don't allow copying text and images إعدادات أمان المستند لا تسمح بنسخ النصوص والصور + The document's security settings don't allow printing إعدادات أمان المستند لا تسمح بالطباعة Open a document first افتح مستندًا أولًا Security will be removed when you save سيُزال الأمان عند الحفظ Click text or an image to edit it انقر على نص أو صورة لتحريرها diff --git a/crates/ui-egui/src/i18n/bg.tsv b/crates/ui-egui/src/i18n/bg.tsv index 813a2c7ae..6bf9ba53c 100644 --- a/crates/ui-egui/src/i18n/bg.tsv +++ b/crates/ui-egui/src/i18n/bg.tsv @@ -1727,6 +1727,7 @@ This document has no restrictions to lift Този документ няма ограничения за премахване The document's security settings don't allow this change Настройките за защита на документа не позволяват тази промяна The document's security settings don't allow copying text and images Настройките за защита на документа не позволяват копиране на текст и изображения + The document's security settings don't allow printing Настройките за защита на документа не позволяват печат Open a document first Първо отворете документ Security will be removed when you save Защитата ще бъде премахната при записване Click text or an image to edit it Щракнете върху текст или изображение, за да го редактирате diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index 993632552..1b97cf8a4 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -1811,6 +1811,7 @@ key Space Mezerník Only the document's owner can change its security (open it with the permissions password) Zabezpečení může změnit jen vlastník dokumentu (otevřete ho heslem oprávnění) The document's security settings don't allow this change Nastavení zabezpečení dokumentu tuto změnu nedovoluje The document's security settings don't allow copying text and images Nastavení zabezpečení dokumentu nedovoluje kopírovat text a obrázky + The document's security settings don't allow printing Nastavení zabezpečení dokumentu nedovoluje tisk Open a document first Nejdřív otevřete dokument Security will be removed when you save Zabezpečení se odebere při uložení Click text or an image to edit it Kliknutím na text nebo obrázek ho upravíte diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index 4d9207eb9..d95d5ac89 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -1700,6 +1700,7 @@ This document has no restrictions to lift Dieses Dokument hat keine Einschränkungen, die aufgehoben werden können The document's security settings don't allow this change Die Sicherheitseinstellungen des Dokuments erlauben diese Änderung nicht The document's security settings don't allow copying text and images Die Sicherheitseinstellungen des Dokuments erlauben kein Kopieren von Text und Bildern + The document's security settings don't allow printing Die Sicherheitseinstellungen des Dokuments erlauben kein Drucken Open a document first Öffne zuerst ein Dokument Security will be removed when you save Die Sicherheit wird beim Speichern entfernt Click text or an image to edit it Klicke auf Text oder ein Bild, um es zu bearbeiten diff --git a/crates/ui-egui/src/i18n/el.tsv b/crates/ui-egui/src/i18n/el.tsv index 06fe2b540..78a11e753 100644 --- a/crates/ui-egui/src/i18n/el.tsv +++ b/crates/ui-egui/src/i18n/el.tsv @@ -2263,6 +2263,7 @@ comment menu Edit Επεξεργασία Couldn't unlock {name}: {e} Δεν ήταν δυνατό το ξεκλείδωμα του {name}: {e} This document has no restrictions to lift Αυτό το έγγραφο δεν έχει περιορισμούς προς άρση The document's security settings don't allow copying text and images Οι ρυθμίσεις ασφαλείας του εγγράφου δεν επιτρέπουν την αντιγραφή κειμένου και εικόνων + The document's security settings don't allow printing Οι ρυθμίσεις ασφαλείας του εγγράφου δεν επιτρέπουν την εκτύπωση Add the files to combine Προσθέστε τα αρχεία προς συνδυασμό Leave out files that can't be read? Να παραλειφθούν τα αρχεία που δεν διαβάζονται; These files can't be read, so they won't be in the combined PDF: Αυτά τα αρχεία δεν διαβάζονται, οπότε δεν θα συμπεριληφθούν στο συνδυασμένο PDF: diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index 79c668992..d296b778a 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -1777,6 +1777,7 @@ action wizard Start Iniciar This document has no restrictions to lift Este documento no tiene restricciones que quitar The document's security settings don't allow this change La configuración de seguridad del documento no permite este cambio The document's security settings don't allow copying text and images La configuración de seguridad del documento no permite copiar texto ni imágenes + The document's security settings don't allow printing La configuración de seguridad del documento no permite imprimir Open a document first Abre primero un documento Security will be removed when you save La seguridad se quitará al guardar Click text or an image to edit it Haz clic en un texto o una imagen para editarlo diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index 9bdcf0bc8..b0ad6436d 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -1695,6 +1695,7 @@ This document has no restrictions to lift Ce document n'a aucune restriction à lever The document's security settings don't allow this change Les paramètres de protection du document n'autorisent pas cette modification The document's security settings don't allow copying text and images Les paramètres de protection du document n'autorisent pas la copie de texte et d'images + The document's security settings don't allow printing Les paramètres de protection du document n'autorisent pas l'impression Open a document first Ouvrez d'abord un document Security will be removed when you save La protection sera retirée à l'enregistrement Click text or an image to edit it Cliquez sur un texte ou une image pour le modifier diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv index d537677c7..79c54d008 100644 --- a/crates/ui-egui/src/i18n/hu.tsv +++ b/crates/ui-egui/src/i18n/hu.tsv @@ -1685,6 +1685,7 @@ This document has no restrictions to lift Ebben a dokumentumban nincs feloldható korlátozás The document's security settings don't allow this change A dokumentum biztonsági beállításai nem engedik ezt a módosítást The document's security settings don't allow copying text and images A dokumentum biztonsági beállításai nem engedik a szöveg és a képek másolását + The document's security settings don't allow printing A dokumentum biztonsági beállításai nem engedik a nyomtatást Open a document first Előbb nyiss meg egy dokumentumot Security will be removed when you save A védelem mentéskor megszűnik Click text or an image to edit it Kattints a szövegre vagy egy képre a szerkesztéshez diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index 35cba7a41..c1e9279f2 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -1771,6 +1771,7 @@ This document has no restrictions to lift Questo documento non ha restrizioni da rimuovere The document's security settings don't allow this change Le impostazioni di sicurezza del documento non consentono questa modifica The document's security settings don't allow copying text and images Le impostazioni di sicurezza del documento non consentono di copiare testo e immagini + The document's security settings don't allow printing Le impostazioni di sicurezza del documento non consentono la stampa Open a document first Apri prima un documento Security will be removed when you save La protezione verrà rimossa al salvataggio Click text or an image to edit it Fai clic su un testo o un'immagine per modificarlo diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index e845a736d..32cf201ae 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -1776,6 +1776,7 @@ This document has no restrictions to lift この文書には解除する制限がありません The document's security settings don't allow this change 文書のセキュリティ設定により、この変更は許可されていません The document's security settings don't allow copying text and images 文書のセキュリティ設定により、テキストと画像のコピーは許可されていません + The document's security settings don't allow printing 文書のセキュリティ設定により、印刷は許可されていません Open a document first 先に文書を開いてください Security will be removed when you save セキュリティは保存時に解除されます Click text or an image to edit it テキストまたは画像をクリックして編集 diff --git a/crates/ui-egui/src/i18n/kk.tsv b/crates/ui-egui/src/i18n/kk.tsv index 9acb4ec1b..444a2364e 100644 --- a/crates/ui-egui/src/i18n/kk.tsv +++ b/crates/ui-egui/src/i18n/kk.tsv @@ -2253,6 +2253,7 @@ key Space Бос орын Couldn't unlock {name}: {e} {name} құлпын ашу мүмкін болмады: {e} This document has no restrictions to lift Бұл құжатта алып тасталатын шектеулер жоқ The document's security settings don't allow copying text and images Құжаттың қауіпсіздік параметрлері мәтін мен суреттерді көшіруге рұқсат бермейді + The document's security settings don't allow printing Құжаттың қауіпсіздік параметрлері басып шығаруға рұқсат бермейді Add the files to combine Біріктірілетін файлдарды қосыңыз Leave out files that can't be read? Оқылмайтын файлдарды қалдырып кету керек пе? These files can't be read, so they won't be in the combined PDF: Бұл файлдар оқылмайды, сондықтан біріктірілген PDF-ке кірмейді: diff --git a/crates/ui-egui/src/i18n/lt.tsv b/crates/ui-egui/src/i18n/lt.tsv index d1dfc3304..e04a48e53 100644 --- a/crates/ui-egui/src/i18n/lt.tsv +++ b/crates/ui-egui/src/i18n/lt.tsv @@ -1145,6 +1145,7 @@ The document now conforms to {level}; save it to keep the changes Dokumentas dabar atitinka {level}; įrašykite jį, kad išsaugotumėte pakeitimus The document opens without a password; this password is needed to change the restrictions. It's applied when you save. Dokumentą galima atverti be slaptažodžio; šis slaptažodis reikalingas apribojimams keisti. Jis pritaikomas įrašant dokumentą. The document's security settings don't allow copying text and images Dokumento saugos nuostatos neleidžia kopijuoti teksto ir paveikslėlių + The document's security settings don't allow printing Dokumento saugos nuostatos neleidžia spausdinti The document's security settings don't allow this change Dokumento saugos nuostatos neleidžia atlikti šio pakeitimo The existing action will be preserved. Esamas veiksmas bus išsaugotas. The fonts PdfCraft writes with can't draw “{c}” ({code}), so it shows as ? in every PDF viewer. The text is saved. „PdfCraft“ naudojami šriftai negali atvaizduoti simbolio „{c}“ ({code}), todėl visose PDF žiūryklėse jis rodomas kaip ?. Tekstas įrašytas. diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index c432a6a92..94a5b8415 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -1758,6 +1758,7 @@ Couldn't unlock {name}: {e} Nie udało się odblokować pliku {name}: {e} This document has no restrictions to lift Ten dokument nie ma ograniczeń do zniesienia The document's security settings don't allow this change Ustawienia zabezpieczeń dokumentu nie zezwalają na tę zmianę + The document's security settings don't allow printing Ustawienia zabezpieczeń dokumentu nie zezwalają na drukowanie Open a document first Najpierw otwórz dokument Security will be removed when you save Zabezpieczenia zostaną usunięte przy zapisie Click text or an image to edit it Kliknij tekst lub obraz, aby go edytować diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index 89ff80f9d..4a2ab6dc9 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -1599,6 +1599,7 @@ This document has no restrictions to lift Este documento não tem restrições a remover The document's security settings don't allow this change As configurações de segurança do documento não permitem esta alteração The document's security settings don't allow copying text and images As configurações de segurança do documento não permitem copiar texto e imagens + The document's security settings don't allow printing As configurações de segurança do documento não permitem imprimir Open a document first Abra um documento primeiro Security will be removed when you save A segurança será removida ao salvar Click text or an image to edit it Clique no texto ou em uma imagem para editá-lo diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index 73f21aa0d..fa942ceb6 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -1765,6 +1765,7 @@ This document has no restrictions to lift У этого документа нет ограничений, которые можно снять The document's security settings don't allow this change Настройки безопасности документа не разрешают это изменение The document's security settings don't allow copying text and images Настройки безопасности документа не разрешают копировать текст и изображения + The document's security settings don't allow printing Настройки безопасности документа не разрешают печать Open a document first Сначала откройте документ Security will be removed when you save Безопасность будет удалена при сохранении Click text or an image to edit it Щёлкните текст или изображение, чтобы редактировать diff --git a/crates/ui-egui/src/i18n/sl.tsv b/crates/ui-egui/src/i18n/sl.tsv index dd169bc96..6b53dba02 100644 --- a/crates/ui-egui/src/i18n/sl.tsv +++ b/crates/ui-egui/src/i18n/sl.tsv @@ -2268,6 +2268,7 @@ key Space Preslednica Couldn't unlock {name}: {e} Dokumenta {name} ni bilo mogoče odkleniti: {e} This document has no restrictions to lift Ta dokument nima omejitev, ki bi jih bilo treba odpraviti The document's security settings don't allow copying text and images Varnostne nastavitve dokumenta ne dovolijo kopiranja besedila in slik + The document's security settings don't allow printing Varnostne nastavitve dokumenta ne dovolijo tiskanja Add the files to combine Dodajte datoteke za združevanje Leave out files that can't be read? Izpustim datoteke, ki jih ni mogoče prebrati? These files can't be read, so they won't be in the combined PDF: Teh datotek ni mogoče prebrati, zato ne bodo v združenem PDF-ju: diff --git a/crates/ui-egui/src/i18n/te.tsv b/crates/ui-egui/src/i18n/te.tsv index 47aee36f8..0407d76ee 100644 --- a/crates/ui-egui/src/i18n/te.tsv +++ b/crates/ui-egui/src/i18n/te.tsv @@ -1684,6 +1684,7 @@ action wizard Start ప్రారంభించు This document has no restrictions to lift ఈ పత్రంలో తొలగించాల్సిన పరిమితులు లేవు The document's security settings don't allow this change పత్రం భద్రతా సెట్టింగ్‌లు ఈ మార్పును అనుమతించవు The document's security settings don't allow copying text and images పత్రం భద్రతా సెట్టింగ్‌లు టెక్స్ట్, చిత్రాలను కాపీ చేయడాన్ని అనుమతించవు + The document's security settings don't allow printing పత్రం భద్రతా సెట్టింగ్‌లు ముద్రించడాన్ని అనుమతించవు Open a document first ముందుగా ఒక పత్రాన్ని తెరవండి Security will be removed when you save మీరు సేవ్ చేసినప్పుడు భద్రత తీసివేయబడుతుంది Click text or an image to edit it సవరించడానికి టెక్స్ట్ లేదా చిత్రంపై క్లిక్ చేయండి diff --git a/crates/ui-egui/src/i18n/tr.tsv b/crates/ui-egui/src/i18n/tr.tsv index 95ca0b608..f5e365bee 100644 --- a/crates/ui-egui/src/i18n/tr.tsv +++ b/crates/ui-egui/src/i18n/tr.tsv @@ -2259,6 +2259,7 @@ key Space Boşluk Couldn't unlock {name}: {e} {name} kilidi açılamadı: {e} This document has no restrictions to lift Bu belgede kaldırılacak kısıtlama yok The document's security settings don't allow copying text and images Belgenin güvenlik ayarları metin ve resimlerin kopyalanmasına izin vermiyor + The document's security settings don't allow printing Belgenin güvenlik ayarları yazdırmaya izin vermiyor Add the files to combine Birleştirilecek dosyaları ekleyin Leave out files that can't be read? Okunamayan dosyalar dışarıda bırakılsın mı? These files can't be read, so they won't be in the combined PDF: Bu dosyalar okunamıyor, bu yüzden birleştirilmiş PDF'de yer almayacak: diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index 7993a0618..4b8463be9 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -1762,6 +1762,7 @@ This document has no restrictions to lift Цей документ не має обмежень, які можна зняти The document's security settings don't allow this change Налаштування захисту документа не дозволяють цю зміну The document's security settings don't allow copying text and images Налаштування захисту документа не дозволяють копіювати текст і зображення + The document's security settings don't allow printing Налаштування захисту документа не дозволяють друк Open a document first Спочатку відкрийте документ Security will be removed when you save Захист буде знято під час збереження Click text or an image to edit it Клацніть текст або зображення для редагування diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index bae599bf6..4380a98f2 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -1136,6 +1136,7 @@ theme Appearance Giao diện The document now conforms to {level}; save it to keep the changes Tài liệu hiện tuân thủ {level}; hãy lưu để giữ các thay đổi The document opens without a password; this password is needed to change the restrictions. It's applied when you save. Tài liệu mở không cần mật khẩu; mật khẩu này cần để thay đổi các hạn chế. Mật khẩu được áp dụng khi bạn lưu. The document's security settings don't allow copying text and images Cài đặt bảo mật của tài liệu không cho phép sao chép văn bản và hình ảnh + The document's security settings don't allow printing Cài đặt bảo mật của tài liệu không cho phép in The document's security settings don't allow this change Cài đặt bảo mật của tài liệu không cho phép thay đổi này The existing action will be preserved. Hành động hiện có sẽ được giữ nguyên. The fonts PdfCraft writes with can't draw “{c}” ({code}), so it shows as ? in every PDF viewer. The text is saved. Phông chữ mà PdfCraft dùng để ghi không thể vẽ “{c}” ({code}), nên nó hiển thị là ? trong mọi trình xem PDF. Văn bản vẫn được lưu. diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index 1ddecc655..ef7e0279d 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -1734,6 +1734,7 @@ This document has no restrictions to lift 此文档没有可解除的限制 The document's security settings don't allow this change 文档安全设置不允许此更改 The document's security settings don't allow copying text and images 文档安全设置不允许复制文本和图像 + The document's security settings don't allow printing 文档安全设置不允许打印 Open a document first 请先打开文档 Security will be removed when you save 保存时将删除安全性设置 Click text or an image to edit it 单击文本或图像进行编辑 diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index bb5ec3649..ed104d1b6 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -1677,6 +1677,7 @@ This document has no restrictions to lift 此文件沒有可解除的限制 The document's security settings don't allow this change 文件安全設定不允許此更改 The document's security settings don't allow copying text and images 文件安全設定不允許複製文字和圖片 + The document's security settings don't allow printing 文件安全設定不允許列印 Open a document first 請先開啟文件 Security will be removed when you save 儲存時將刪除安全性設定 Click text or an image to edit it 按一下文字或圖片進行編輯 diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 268214b16..1fa95b2e2 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -2855,6 +2855,10 @@ pub(crate) fn copy_refused() -> &'static str { tl!("The document's security settings don't allow copying text and images") } +pub(crate) fn print_refused() -> &'static str { + tl!("The document's security settings don't allow printing") +} + impl PdfCraftApp { /// Whether text and images may be copied out of document `id`; says why not when they may /// not. Reading aloud and accessibility tools don't ask (assistive technology may read diff --git a/crates/ui-egui/tests/print.rs b/crates/ui-egui/tests/print.rs index f3d10238c..618480525 100644 --- a/crates/ui-egui/tests/print.rs +++ b/crates/ui-egui/tests/print.rs @@ -426,3 +426,53 @@ fn an_empty_printer_list_says_none_were_found() { h.get_by_label_contains("No printers were found"); assert!(!h.get_by_role_and_label(Role::Button, "Save as PDF").accesskit_node().is_disabled()); } + +/// A document whose security forbids printing (#2669) says so before the dialog opens, and the +/// top bar's Print button is disabled, instead of the dialog refusing on confirm. +#[test] +fn print_restricted_documents_say_so_before_the_dialog() { + let mut doc = pdfcraft_cos::Document::open(std::sync::Arc::new(include_bytes!("data/form.pdf").to_vec())).unwrap(); + doc.set_encryption(&pdfcraft_cos::NewEncryption { + algorithm: pdfcraft_cos::Algorithm::Aes256, + user_password: "", + owner_password: "owner", + permissions: -1 ^ 0b100, + encrypt_metadata: true, + seed: [3; 32], + }) + .unwrap(); + let bytes = pdfcraft_cos::write_full(&doc, &Default::default()).unwrap(); + let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_| { + let mut app = PdfCraftApp::new(); + app.set_option("language", "en").unwrap(); + app.open_bytes("restricted.pdf", None, bytes).unwrap(); + app + }); + h.ctx.set_os(egui::os::OperatingSystem::Windows); + h.run_steps(4); + assert!(h.get_by_label("Print (Ctrl+P)").accesskit_node().is_disabled()); + h.get_by_label("Print (Ctrl+P)").hover(); + h.run_steps(30); + h.get_by_label_contains("don't allow printing"); + assert!(!h.state_mut().execute("print.dialog")); + h.run_steps(2); + assert_eq!(h.state().dialog, None); + assert_eq!(h.state().toast.as_ref().map(|t| t.0.as_str()), Some("The document's security settings don't allow printing")); +} + +/// With no document open the top bar's Print button is disabled too, but not for security +/// reasons: its tooltip must not blame the document's settings (#2669). +#[test] +fn print_without_a_document_does_not_blame_security() { + let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_| { + let mut app = PdfCraftApp::new(); + app.set_option("language", "en").unwrap(); + app + }); + h.ctx.set_os(egui::os::OperatingSystem::Windows); + h.run_steps(4); + assert!(h.get_by_label("Print (Ctrl+P)").accesskit_node().is_disabled()); + h.get_by_label("Print (Ctrl+P)").hover(); + h.run_steps(30); + assert!(h.query_by_label_contains("don't allow printing").is_none()); +} diff --git a/parity/acrobat-features.toml b/parity/acrobat-features.toml index d8fbe77dd..ee11a597b 100644 --- a/parity/acrobat-features.toml +++ b/parity/acrobat-features.toml @@ -214,7 +214,7 @@ milestone = "M1" status = "shipped" commands = [] tools = [] -evidence = ["crates/ui-egui/tests/editing.rs::restricted_documents_show_a_notice_and_block_page_changes", "crates/crypt/src/tests.rs::permission_bits_follow_table_22", "crates/crypt/src/tests.rs::perms_limits_what_an_edited_p_grants", "crates/engine/src/tests.rs::combining_protected_files_is_refused_clearly"] +evidence = ["crates/ui-egui/tests/editing.rs::restricted_documents_show_a_notice_and_block_page_changes", "crates/crypt/src/tests.rs::permission_bits_follow_table_22", "crates/crypt/src/tests.rs::perms_limits_what_an_edited_p_grants", "crates/engine/src/tests.rs::combining_protected_files_is_refused_clearly", "crates/engine/src/tests.rs::print_restricted_documents_disable_print_unless_opened_by_the_owner", "crates/ui-egui/tests/print.rs::print_restricted_documents_say_so_before_the_dialog"] notes = "" [[feature]]