mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-11 21:32:39 +00:00
M7: offer to lock a signature right after it's placed, and keep the switch in the panel (#2149)
benandez's review suggestion on #2348. Right after Fill & Sign places a signature or initials, a notice says "Signature added. Others can move it until it's locked." with Lock now, which flattens the marks into the page (undoable) without saving; the save that follows then has nothing to ask about. The placed-signature mark is kept, so undoing the lock brings back the notice and the save-time question, which stays as the fallback. Dismiss hides the notice until the next signature. No notice on a digitally signed document or when saves lock anyway. The "Lock into the page when saving" switch is now once, in the panel's Sign yourself section, no longer in the Sign menu over the page. The three new strings are in all 22 catalogues (AI-assisted, not reviewed by native speakers). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
58e28e1950
commit
b92d937c91
30 files changed
+249
-21
No files matched your search
@@ -642,6 +642,9 @@ pub struct DocView {
|
||||
pub fill_text: Option<crate::fill_sign::TypeBox>,
|
||||
/// A queued Fill & Sign signature: select it after its edit succeeds, then leave placement.
|
||||
pub(crate) fill_signature_page: Option<usize>,
|
||||
/// The "Signature added … Lock now" notice was dismissed; placing another signature shows it
|
||||
/// again (#2149).
|
||||
pub(crate) lock_offer_dismissed: bool,
|
||||
pub(crate) signature_drag: crate::signature_drag::SignatureDrag,
|
||||
/// What the page modules claim for the cursor this frame; `document_area` sets it once.
|
||||
pub(crate) cursor: crate::page_cursor::PageCursor,
|
||||
@@ -736,6 +739,8 @@ pub enum ViewAction {
|
||||
CameraLevel,
|
||||
/// After Enhance page: leave the tool for this command (Crop pages, Organize pages).
|
||||
CameraNext(&'static str),
|
||||
/// Lock now, on the notice shown after a signature is placed (#2149).
|
||||
LockSignatures,
|
||||
}
|
||||
|
||||
/// Default page right-click menu actions.
|
||||
@@ -1001,6 +1006,7 @@ impl DocView {
|
||||
marquee_done: None,
|
||||
fill_text: None,
|
||||
fill_signature_page: None,
|
||||
lock_offer_dismissed: false,
|
||||
signature_drag: Default::default(),
|
||||
cursor: Default::default(),
|
||||
router: Default::default(),
|
||||
@@ -3030,6 +3036,12 @@ fn apply_notice(app: &mut PdfCraftApp, index: usize, notice: Option<Notice>) {
|
||||
Some(Notice::Console) => app.dialog = Some(crate::Dialog::JsConsole),
|
||||
// Back on in Preferences ▸ General.
|
||||
Some(Notice::HideSecured) => app.show_secured_notice = false,
|
||||
// Handled by the app with the other view actions (`ViewAction`).
|
||||
Some(Notice::LockSignatures) => {
|
||||
if let Some(view) = app.views.get_mut(index) {
|
||||
view.pending_action = Some(ViewAction::LockSignatures);
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
@@ -3499,13 +3511,19 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) {
|
||||
(app.left_open && app.left == crate::LeftPanel::Tool("edit")) || matches!(app.quick_tool, QuickTool::AddText | QuickTool::EditText);
|
||||
let text_style = app.text_style.clone();
|
||||
let show_secured_notice = app.show_secured_notice;
|
||||
// Offer to lock a just-placed signature (#2149) on the same terms the save-time question
|
||||
// asks: one is still there, saving doesn't lock it anyway, and the document isn't signed.
|
||||
let lock_offer = !app.flatten_fill_sign_on_save
|
||||
&& app.placed_signatures.contains(&app.views[index].id)
|
||||
&& doc.info.annotations.iter().any(|a| a.fill_sign)
|
||||
&& !doc.is_signed();
|
||||
let view = &mut app.views[index];
|
||||
// Opened without the owner password and something is restricted. The notice says so unless
|
||||
// the user turned it off (#4035): the restrictions themselves, and Document Properties ▸
|
||||
// Security, stay as they are.
|
||||
let secured = show_secured_notice && doc.security_summary().is_some_and(|s| !(s.owner || (s.permissions.modify() && s.permissions.assemble())));
|
||||
let repaired = !doc.repair_log().is_empty();
|
||||
let notice = notices(view, doc, secured, repaired, crate::sign_ui::banner(&doc.signatures), ui, &t);
|
||||
let notice = notices(view, doc, secured, repaired, lock_offer, crate::sign_ui::banner(&doc.signatures), ui, &t);
|
||||
apply_notice(app, index, notice);
|
||||
let Some(doc) = app.session.get(app.views[index].id) else { return };
|
||||
let info = &doc.info;
|
||||
|
||||
@@ -59,16 +59,20 @@ pub(super) enum Notice {
|
||||
Close,
|
||||
/// Stop showing the secured-document notice, in every document (#4035).
|
||||
HideSecured,
|
||||
/// Lock the placed signatures into the page (#2149).
|
||||
LockSignatures,
|
||||
}
|
||||
|
||||
/// The notice bar above the pages: a file changed on disk first, then what a historical
|
||||
/// snapshot is, then the signature status bar, a form's scripts having been turned
|
||||
/// off, security, forms and warnings.
|
||||
/// snapshot is, then the offer to lock a signature just placed, then the signature status bar,
|
||||
/// a form's scripts having been turned off, security, forms and warnings.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(super) fn notices(
|
||||
view: &mut DocView,
|
||||
doc: &pdfcraft_engine::Document,
|
||||
secured: bool,
|
||||
repaired: bool,
|
||||
lock_offer: bool,
|
||||
signed: Option<(&str, Color32, &str, String)>,
|
||||
ui: &mut egui::Ui,
|
||||
t: &Tokens,
|
||||
@@ -122,6 +126,22 @@ pub(super) fn notices(
|
||||
return Some(Notice::Close);
|
||||
}
|
||||
}
|
||||
// A signature just placed with Fill & Sign is a comment others can move (#2149): offer to
|
||||
// lock it into the page now. `lock_offer` is false for a digitally signed document.
|
||||
if lock_offer && !view.lock_offer_dismissed {
|
||||
let mut lock = false;
|
||||
notice_bar(ui, t, "lock", t.accent_text, tl!("Signature added. Others can move it until it's locked.").to_string(), |ui| {
|
||||
if icons::button(ui, "x", 22.0, false, tl!("Dismiss")).clicked() {
|
||||
view.lock_offer_dismissed = true;
|
||||
}
|
||||
if crate::widgets::pill_button(ui, tl!("Lock now"), true).clicked() {
|
||||
lock = true;
|
||||
}
|
||||
});
|
||||
if lock {
|
||||
return Some(Notice::LockSignatures);
|
||||
}
|
||||
}
|
||||
if let Some((icon, color, template, arg)) = signed {
|
||||
let mut open = false;
|
||||
notice_bar(ui, t, icon, color, crate::i18n::fmt(tl!(template), &[("by", &arg)]), |ui| {
|
||||
|
||||
@@ -478,6 +478,11 @@ impl PdfCraftApp {
|
||||
}
|
||||
}
|
||||
Some(crate::canvas::ViewAction::CameraLevel) => self.camera_level(i),
|
||||
Some(crate::canvas::ViewAction::LockSignatures) => {
|
||||
if let Some(id) = self.views.get(i).map(|v| v.id) {
|
||||
self.lock_signatures_now(id);
|
||||
}
|
||||
}
|
||||
Some(crate::canvas::ViewAction::CameraNext(command)) => {
|
||||
self.leave_camera(i);
|
||||
self.execute(command);
|
||||
@@ -681,6 +686,10 @@ impl PdfCraftApp {
|
||||
&& let Some(id) = doc_id
|
||||
{
|
||||
self.placed_signatures.insert(id);
|
||||
// A new signature shows the Lock now notice again, even if the last was dismissed.
|
||||
if let Some(view) = self.views.get_mut(i) {
|
||||
view.lock_offer_dismissed = false;
|
||||
}
|
||||
}
|
||||
// Tab can wrap to the same field (including another widget of that field).
|
||||
// Its new editor was opened before this edit ran, so it still holds the old
|
||||
|
||||
@@ -183,18 +183,8 @@ impl PdfCraftApp {
|
||||
/// again, and the answer isn't remembered.
|
||||
pub(crate) fn answer_lock_signatures(&mut self, lock: bool, remember: bool) {
|
||||
let Some(p) = self.pending_lock.take() else { return };
|
||||
if lock && !self.flatten_fill_sign_on_save {
|
||||
let before = self.session.get(p.id).map(|d| d.edit_generation());
|
||||
if let Err(e) = self.session.apply(p.id, pdfcraft_engine::Edit::FlattenFillSign) {
|
||||
self.notify_error(e);
|
||||
return;
|
||||
}
|
||||
if before != self.session.get(p.id).map(|d| d.edit_generation())
|
||||
&& let Some(doc) = self.session.get(p.id)
|
||||
&& let Some(view) = self.views.iter_mut().find(|v| v.id == p.id)
|
||||
{
|
||||
view.document_changed(&doc.info);
|
||||
}
|
||||
if lock && !self.flatten_fill_sign_on_save && !self.flatten_fill_sign_in(p.id) {
|
||||
return;
|
||||
}
|
||||
self.placed_signatures.remove(&p.id);
|
||||
if remember {
|
||||
@@ -209,6 +199,37 @@ impl PdfCraftApp {
|
||||
}
|
||||
}
|
||||
|
||||
/// Lock now, on the notice shown after a signature is placed (#2149): lock document `id`'s
|
||||
/// Fill & Sign marks into its pages, as the save-time question's Lock does but without
|
||||
/// saving. Undoable. The next save doesn't ask, as no Fill & Sign mark is left to lock; the
|
||||
/// placed-signature mark itself stays, so undoing the lock brings back both the notice and the
|
||||
/// save-time question. Never on a digitally signed document.
|
||||
pub(crate) fn lock_signatures_now(&mut self, id: pdfcraft_engine::DocId) {
|
||||
if self.session.get(id).is_none_or(|d| d.is_signed()) {
|
||||
return;
|
||||
}
|
||||
if self.flatten_fill_sign_in(id) {
|
||||
self.notify_tr("Signature locked into the page.");
|
||||
}
|
||||
}
|
||||
|
||||
/// Lock document `id`'s Fill & Sign marks into its pages (an undoable edit). Returns false,
|
||||
/// having told the user why, when that fails.
|
||||
fn flatten_fill_sign_in(&mut self, id: pdfcraft_engine::DocId) -> bool {
|
||||
let before = self.session.get(id).map(|d| d.edit_generation());
|
||||
if let Err(e) = self.session.apply(id, pdfcraft_engine::Edit::FlattenFillSign) {
|
||||
self.notify_error(e);
|
||||
return false;
|
||||
}
|
||||
if before != self.session.get(id).map(|d| d.edit_generation())
|
||||
&& let Some(doc) = self.session.get(id)
|
||||
&& let Some(view) = self.views.iter_mut().find(|v| v.id == id)
|
||||
{
|
||||
view.document_changed(&doc.info);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Write document `id` to `dest` and make it the document's file. Returns `true` if written.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn save_doc_to(&mut self, id: pdfcraft_engine::DocId, dest: &str, target: SaveTarget) -> bool {
|
||||
|
||||
@@ -2286,6 +2286,9 @@ calendar date December ديسمبر
|
||||
Keep editable إبقاؤه قابلًا للتحرير
|
||||
Lock into the page when saving التثبيت في الصفحة عند الحفظ
|
||||
Otherwise, ask on the first save after a signature is placed وإلا فاسأل عند أول حفظ بعد وضع توقيع
|
||||
Signature added. Others can move it until it's locked. تمت إضافة التوقيع. يمكن للآخرين نقله إلى أن يتم تثبيته.
|
||||
Lock now التثبيت الآن
|
||||
Signature locked into the page. تم تثبيت التوقيع في الصفحة.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. النص والعلامات والتوقيعات تصبح جزءًا من الصفحة. التعليقات الأخرى تبقى قابلة للتحرير.
|
||||
Date format تنسيق التاريخ
|
||||
Fill & Sign dates تواريخ التعبئة والتوقيع
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -146,6 +146,9 @@
|
||||
Keep editable Да остане редактируем
|
||||
Lock into the page when saving Заключване в страницата при запис
|
||||
Otherwise, ask on the first save after a signature is placed Иначе питай при първия запис след поставяне на подпис
|
||||
Signature added. Others can move it until it's locked. Подписът е добавен. Други могат да го преместват, докато не бъде заключен.
|
||||
Lock now Заключи сега
|
||||
Signature locked into the page. Подписът е заключен в страницата.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. Текстът, маркировките и подписите стават част от страницата. Другите коментари остават редактируеми.
|
||||
OK OK
|
||||
Cancel Отказ
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 8 and column 16.
|
@@ -2307,6 +2307,9 @@ calendar date December prosince
|
||||
Keep editable Ponechat upravitelné
|
||||
Lock into the page when saving Při ukládání zamknout do stránky
|
||||
Otherwise, ask on the first save after a signature is placed Jinak se zeptat při prvním uložení po umístění podpisu
|
||||
Signature added. Others can move it until it's locked. Podpis byl přidán. Ostatní ho mohou přesouvat, dokud nebude zamčen.
|
||||
Lock now Zamknout nyní
|
||||
Signature locked into the page. Podpis byl zamčen do stránky.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. Text, značky a podpisy se stanou součástí stránky. Ostatní komentáře zůstanou upravitelné.
|
||||
Date format Formát data
|
||||
Fill & Sign dates Datum pro Vyplnit a podepsat
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -79,6 +79,9 @@
|
||||
Keep editable Bearbeitbar lassen
|
||||
Lock into the page when saving Beim Speichern fest in die Seite übernehmen
|
||||
Otherwise, ask on the first save after a signature is placed Andernfalls beim ersten Speichern nach dem Platzieren einer Unterschrift fragen
|
||||
Signature added. Others can move it until it's locked. Unterschrift hinzugefügt. Andere können sie verschieben, bis sie fest übernommen ist.
|
||||
Lock now Jetzt übernehmen
|
||||
Signature locked into the page. Unterschrift fest in die Seite übernommen.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. Text, Markierungen und Unterschriften werden Teil der Seite. Andere Kommentare bleiben bearbeitbar.
|
||||
OK OK
|
||||
Join our Discord Unserem Discord beitreten
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 51.
|
@@ -294,6 +294,9 @@
|
||||
Keep editable Να παραμείνει επεξεργάσιμη
|
||||
Lock into the page when saving Κλείδωμα στη σελίδα κατά την αποθήκευση
|
||||
Otherwise, ask on the first save after a signature is placed Διαφορετικά, ερώτηση στην πρώτη αποθήκευση μετά την τοποθέτηση υπογραφής
|
||||
Signature added. Others can move it until it's locked. Η υπογραφή προστέθηκε. Άλλοι μπορούν να τη μετακινήσουν μέχρι να κλειδωθεί.
|
||||
Lock now Κλείδωμα τώρα
|
||||
Signature locked into the page. Η υπογραφή κλειδώθηκε στη σελίδα.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. Το κείμενο, τα σημάδια και οι υπογραφές γίνονται μέρος της σελίδας. Τα υπόλοιπα σχόλια παραμένουν επεξεργάσιμα.
|
||||
Current page — type a page number or label (such as iv) and press Enter Τρέχουσα σελίδα — πληκτρολογήστε αριθμό ή ετικέτα σελίδας (π.χ. iv) και πατήστε Enter
|
||||
Zoom — type a percentage and press Enter Ζουμ — πληκτρολογήστε ένα ποσοστό και πατήστε Enter
|
||||
|
||||
|
@@ -102,6 +102,9 @@
|
||||
Keep editable Mantener editable
|
||||
Lock into the page when saving Fijar en la página al guardar
|
||||
Otherwise, ask on the first save after a signature is placed Si no, preguntar al guardar por primera vez tras colocar una firma
|
||||
Signature added. Others can move it until it's locked. Firma añadida. Otros pueden moverla hasta que se fije.
|
||||
Lock now Fijar ahora
|
||||
Signature locked into the page. Firma fijada en la página.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. El texto, las marcas y las firmas pasan a formar parte de la página. Los demás comentarios siguen siendo editables.
|
||||
OK Aceptar
|
||||
Join our Discord Únete a nuestro Discord
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 60.
|
@@ -79,6 +79,9 @@
|
||||
Keep editable Garder modifiable
|
||||
Lock into the page when saving Intégrer à la page à l’enregistrement
|
||||
Otherwise, ask on the first save after a signature is placed Sinon, demander au premier enregistrement après avoir placé une signature
|
||||
Signature added. Others can move it until it's locked. Signature ajoutée. D’autres peuvent la déplacer tant qu’elle n’est pas intégrée.
|
||||
Lock now Intégrer maintenant
|
||||
Signature locked into the page. Signature intégrée à la page.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. Le texte, les marques et les signatures deviennent partie de la page. Les autres commentaires restent modifiables.
|
||||
OK OK
|
||||
Join our Discord Rejoindre notre Discord
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 39.
|
@@ -2263,6 +2263,9 @@ action wizard Start Indítás
|
||||
Keep editable Szerkeszthető marad
|
||||
Lock into the page when saving Mentéskor rögzítés az oldalba
|
||||
Otherwise, ask on the first save after a signature is placed Különben kérdezzen rá az aláírás elhelyezése utáni első mentéskor
|
||||
Signature added. Others can move it until it's locked. Aláírás hozzáadva. Mások áthelyezhetik, amíg nincs rögzítve.
|
||||
Lock now Rögzítés most
|
||||
Signature locked into the page. Az aláírás rögzítve az oldalba.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. A szöveg, a jelek és az aláírások az oldal részévé válnak. A többi megjegyzés szerkeszthető marad.
|
||||
Date format Dátumformátum
|
||||
Fill & Sign dates Kitöltés és aláírás dátumai
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 7 and column 44.
|
@@ -2223,6 +2223,9 @@
|
||||
Keep editable Mantieni modificabile
|
||||
Lock into the page when saving Blocca nella pagina al salvataggio
|
||||
Otherwise, ask on the first save after a signature is placed Altrimenti, chiedi al primo salvataggio dopo aver inserito una firma
|
||||
Signature added. Others can move it until it's locked. Firma aggiunta. Altri possono spostarla finché non viene bloccata.
|
||||
Lock now Blocca ora
|
||||
Signature locked into the page. Firma bloccata nella pagina.
|
||||
H / Space (hold) H / Spazio (tieni premuto)
|
||||
Home / End Home / Fine
|
||||
Inserted text Testo inserito
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2278,6 +2278,9 @@ signature pad Type 入力
|
||||
Keep editable 編集可能のままにする
|
||||
Lock into the page when saving 保存時にページに固定
|
||||
Otherwise, ask on the first save after a signature is placed それ以外は、署名を配置した後の最初の保存時に確認する
|
||||
Signature added. Others can move it until it's locked. 署名を追加しました。固定するまでは他の人が移動できます。
|
||||
Lock now 今すぐ固定
|
||||
Signature locked into the page. 署名をページに固定しました。
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. テキスト、マーク、署名がページの一部になります。その他のコメントは引き続き編集できます。
|
||||
Scroll tabs left タブを左にスクロール
|
||||
Scroll tabs right タブを右にスクロール
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2195,6 +2195,9 @@ calendar date December Желтоқсан
|
||||
Keep editable Өңделетін күйде қалдыру
|
||||
Lock into the page when saving Сақтағанда бетке бекіту
|
||||
Otherwise, ask on the first save after a signature is placed Әйтпесе, қолтаңба қойылғаннан кейінгі алғашқы сақтауда сұрау
|
||||
Signature added. Others can move it until it's locked. Қолтаңба қосылды. Ол бекітілгенше басқалар оны жылжыта алады.
|
||||
Lock now Қазір бекіту
|
||||
Signature locked into the page. Қолтаңба бетке бекітілді.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. Мәтін, белгілер мен қолтаңбалар беттің бөлігіне айналады. Басқа түсініктемелер өңделетін күйде қалады.
|
||||
Date format Күн пішімі
|
||||
Fill & Sign dates «Толтыру және қол қою» күндері
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 885 and column 9.
|
@@ -598,6 +598,9 @@
|
||||
Keep editable Palikti redaguojamą
|
||||
Lock into the page when saving Įrašant įtvirtinti puslapyje
|
||||
Otherwise, ask on the first save after a signature is placed Kitaip klausti pirmą kartą įrašant po parašo padėjimo
|
||||
Signature added. Others can move it until it's locked. Parašas pridėtas. Kiti gali jį perkelti, kol jis neįtvirtintas.
|
||||
Lock now Įtvirtinti dabar
|
||||
Signature locked into the page. Parašas įtvirtintas puslapyje.
|
||||
Flip Horizontal Apversti horizontaliai
|
||||
Flip Vertical Apversti vertikaliai
|
||||
Flip horizontal Apversti horizontaliai
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 408 and column 9.
|
@@ -2257,6 +2257,9 @@ signature pad Type Wpisz
|
||||
Keep editable Zachowaj edytowalny
|
||||
Lock into the page when saving Utrwalaj na stronie przy zapisie
|
||||
Otherwise, ask on the first save after a signature is placed W przeciwnym razie pytaj przy pierwszym zapisie po umieszczeniu podpisu
|
||||
Signature added. Others can move it until it's locked. Dodano podpis. Inni mogą go przesunąć, dopóki nie zostanie utrwalony.
|
||||
Lock now Utrwal teraz
|
||||
Signature locked into the page. Podpis utrwalono na stronie.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. Tekst, oznaczenia i podpisy stają się częścią strony. Pozostałe komentarze pozostają edytowalne.
|
||||
Scroll tabs left Przewiń karty w lewo
|
||||
Scroll tabs right Przewiń karty w prawo
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2216,6 +2216,9 @@ action wizard Start Iniciar
|
||||
Keep editable Manter editável
|
||||
Lock into the page when saving Fixar na página ao salvar
|
||||
Otherwise, ask on the first save after a signature is placed Caso contrário, perguntar ao salvar pela primeira vez após colocar uma assinatura
|
||||
Signature added. Others can move it until it's locked. Assinatura adicionada. Outras pessoas podem movê-la até que seja fixada.
|
||||
Lock now Fixar agora
|
||||
Signature locked into the page. Assinatura fixada na página.
|
||||
H / Space (hold) H / Espaço (manter pressionado)
|
||||
Home / End Home / End
|
||||
Inserted text Texto inserido
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -99,6 +99,9 @@
|
||||
Keep editable Оставить редактируемой
|
||||
Lock into the page when saving Закреплять на странице при сохранении
|
||||
Otherwise, ask on the first save after a signature is placed Иначе спрашивать при первом сохранении после размещения подписи
|
||||
Signature added. Others can move it until it's locked. Подпись добавлена. Другие могут перемещать её, пока она не закреплена.
|
||||
Lock now Закрепить сейчас
|
||||
Signature locked into the page. Подпись закреплена на странице.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. Текст, пометки и подписи становятся частью страницы. Остальные комментарии можно по-прежнему править.
|
||||
OK OK
|
||||
Join our Discord Присоединяйтесь к нашему Discord
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -2211,6 +2211,9 @@ signature pad Type Vtipkaj
|
||||
Keep editable Ohrani urejljivo
|
||||
Lock into the page when saving Ob shranjevanju zakleni v stran
|
||||
Otherwise, ask on the first save after a signature is placed Sicer vprašaj ob prvem shranjevanju po postavitvi podpisa
|
||||
Signature added. Others can move it until it's locked. Podpis je dodan. Drugi ga lahko premaknejo, dokler ni zaklenjen.
|
||||
Lock now Zakleni zdaj
|
||||
Signature locked into the page. Podpis je zaklenjen v stran.
|
||||
Font size 0 uses automatic sizing. Velikost pisave 0 pomeni samodejno velikost.
|
||||
Import list… Uvozi seznam…
|
||||
Larger pages Večje strani
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -2511,6 +2511,9 @@ animation effects Off ఆఫ్
|
||||
Keep editable సవరించగలిగేలా ఉంచు
|
||||
Lock into the page when saving సేవ్ చేసేటప్పుడు పేజీలో లాక్ చేయి
|
||||
Otherwise, ask on the first save after a signature is placed లేకపోతే, సంతకం ఉంచిన తర్వాత మొదటి సేవ్లో అడుగు
|
||||
Signature added. Others can move it until it's locked. సంతకం జోడించబడింది. లాక్ చేసే వరకు ఇతరులు దానిని తరలించగలరు.
|
||||
Lock now ఇప్పుడే లాక్ చేయి
|
||||
Signature locked into the page. సంతకం పేజీలో లాక్ చేయబడింది.
|
||||
|
||||
# Date picker: Today button (#4274) (AI-assisted, not separately native-reviewed)
|
||||
Today ఈరోజు
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 13 and column 16.
|
@@ -70,6 +70,9 @@
|
||||
Keep editable Düzenlenebilir bırak
|
||||
Lock into the page when saving Kaydederken sayfaya sabitle
|
||||
Otherwise, ask on the first save after a signature is placed Aksi halde, imza yerleştirildikten sonraki ilk kayıtta sor
|
||||
Signature added. Others can move it until it's locked. İmza eklendi. Sabitlenene kadar başkaları onu taşıyabilir.
|
||||
Lock now Şimdi sabitle
|
||||
Signature locked into the page. İmza sayfaya sabitlendi.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. Metin, işaretler ve imzalar sayfanın bir parçası olur. Diğer yorumlar düzenlenebilir kalır.
|
||||
OK Tamam
|
||||
Join our Discord Discord'umuza katılın
|
||||
|
||||
|
@@ -2286,6 +2286,9 @@ calendar date December грудня
|
||||
Keep editable Залишити редагованим
|
||||
Lock into the page when saving Закріплювати на сторінці під час збереження
|
||||
Otherwise, ask on the first save after a signature is placed Інакше питати під час першого збереження після розміщення підпису
|
||||
Signature added. Others can move it until it's locked. Підпис додано. Інші можуть переміщувати його, доки його не закріплено.
|
||||
Lock now Закріпити зараз
|
||||
Signature locked into the page. Підпис закріплено на сторінці.
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. Текст, позначки й підписи стають частиною сторінки. Інші коментарі залишаються редагованими.
|
||||
Date format Формат дати
|
||||
Fill & Sign dates Дати заповнення й підпису
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2894,3 +2894,6 @@ key Space Space
|
||||
Lock into the page when saving Khóa vào trang khi lưu
|
||||
Lock your signature into the page? Khóa chữ ký của bạn vào trang?
|
||||
Otherwise, ask on the first save after a signature is placed Nếu không, hỏi ở lần lưu đầu tiên sau khi đặt chữ ký
|
||||
Signature added. Others can move it until it's locked. Đã thêm chữ ký. Người khác có thể di chuyển nó cho đến khi được khóa.
|
||||
Lock now Khóa ngay
|
||||
Signature locked into the page. Đã khóa chữ ký vào trang.
|
||||
|
Can't render this file because it contains an unexpected character in line 495 and column 12.
|
@@ -152,6 +152,9 @@
|
||||
Keep editable 保持可编辑
|
||||
Lock into the page when saving 保存时锁定到页面
|
||||
Otherwise, ask on the first save after a signature is placed 否则,在放置签名后首次保存时询问
|
||||
Signature added. Others can move it until it's locked. 已添加签名。锁定之前,其他人可以移动它。
|
||||
Lock now 立即锁定
|
||||
Signature locked into the page. 签名已锁定到页面。
|
||||
Text, marks and signatures become part of the page. Other comments stay editable. 文字、标记和签名会成为页面内容。其他注释仍可编辑。
|
||||
OK 确定
|
||||
Cancel 取消
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -2552,6 +2552,9 @@ animation effects Off 關
|
||||
Keep editable 保持可編輯
|
||||
Lock into the page when saving 儲存時鎖定到頁面
|
||||
Otherwise, ask on the first save after a signature is placed 否則,在放置簽名後第一次儲存時詢問
|
||||
Signature added. Others can move it until it's locked. 已加入簽名。鎖定之前,其他人可以移動它。
|
||||
Lock now 立即鎖定
|
||||
Signature locked into the page. 簽名已鎖定到頁面。
|
||||
|
||||
# Date picker: Today button (#4274) (AI-assisted, not separately native-reviewed)
|
||||
Today 今天
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -291,6 +291,9 @@ fn tool_detail(app: &mut PdfCraftApp, ui: &mut egui::Ui, t: &Tokens, g: &'static
|
||||
if let Some(cmd) = crate::fill_sign::signature_entries(ui, app, t) {
|
||||
run = Some(cmd);
|
||||
}
|
||||
// Where the signing happens, not only in Preferences, and once: not also in the Sign
|
||||
// menu over the page, where it was easy to miss (#2149).
|
||||
ui.add(widgets::checkbox(&mut app.flatten_fill_sign_on_save, tl!("Lock into the page when saving")));
|
||||
}
|
||||
});
|
||||
if footer {
|
||||
|
||||
@@ -398,8 +398,6 @@ pub(crate) fn signature_entries(ui: &mut egui::Ui, app: &mut crate::PdfCraftApp,
|
||||
});
|
||||
ui.add_space(4.0);
|
||||
}
|
||||
// Where the signing happens, not only in Preferences (#2149).
|
||||
ui.add(crate::widgets::checkbox(&mut app.flatten_fill_sign_on_save, tl!("Lock into the page when saving")));
|
||||
command
|
||||
}
|
||||
|
||||
|
||||
@@ -1754,7 +1754,8 @@ fn photos_and_images_dropped_on_the_signature_pad_are_imported_not_opened() {
|
||||
|
||||
/// #2149: the first save after Fill & Sign places a signature asks whether to lock it into the
|
||||
/// page. Lock and save flattens it; Keep editable keeps it a comment; Don't ask again becomes
|
||||
/// the preference; the Sign menu has the switch too.
|
||||
/// the preference; the Fill & Sign panel has the switch too, once, and the Sign menu no longer
|
||||
/// does (review on #2348).
|
||||
#[test]
|
||||
fn the_first_save_after_placing_a_signature_asks_to_lock_it() {
|
||||
let out = std::env::temp_dir().join(format!("pdfcraft-lock-signature-{}.pdf", std::process::id()));
|
||||
@@ -1790,18 +1791,110 @@ fn the_first_save_after_placing_a_signature_asks_to_lock_it() {
|
||||
assert_eq!(signed(&h), 0, "locked into the page");
|
||||
assert!(!h.state().session.get(h.state().views[0].id).unwrap().dirty);
|
||||
assert!(h.state().flatten_fill_sign_on_save, "remembered as the preference");
|
||||
// The Sign menu shows the same switch.
|
||||
// The switch is in the panel's Sign yourself section, once; the Sign menu over the page,
|
||||
// where it was easy to miss, no longer has it.
|
||||
h.state_mut().flatten_fill_sign_on_save = false;
|
||||
h.get_by_label("Fill & Sign").click();
|
||||
h.run_steps(2);
|
||||
h.get_by_label("Fill & Sign").click();
|
||||
h.run_steps(2);
|
||||
h.get_by_label("Use signature");
|
||||
assert!(h.query_by_label("Lock into the page when saving").is_none(), "not in the Sign menu");
|
||||
h.key_press(egui::Key::Escape);
|
||||
h.run_steps(2);
|
||||
assert!(h.query_by_label("Lock into the page when saving").is_none(), "the panel is closed");
|
||||
h.state_mut().left = pdfcraft_ui_egui::LeftPanel::Tool("fill_sign");
|
||||
h.state_mut().left_open = true;
|
||||
h.run_steps(3);
|
||||
h.get_by_label("Use signature");
|
||||
assert_eq!(h.query_all_by_label("Lock into the page when saving").count(), 1, "once, in the panel");
|
||||
h.get_by_label("Lock into the page when saving").click();
|
||||
h.run_steps(2);
|
||||
assert!(h.state().flatten_fill_sign_on_save);
|
||||
let _ = std::fs::remove_file(&out);
|
||||
}
|
||||
|
||||
/// #2348 review (benandez): right after a signature is placed, a notice offers to lock it into
|
||||
/// the page now. Lock now flattens it (undoable) without saving, so the save that follows doesn't
|
||||
/// ask; undoing the lock brings back both the notice and the question. Dismiss hides the notice
|
||||
/// until the next signature. A digitally signed document, or one whose saves lock anyway, gets no
|
||||
/// notice.
|
||||
#[test]
|
||||
fn placing_a_signature_offers_to_lock_it_now() {
|
||||
const NOTICE: &str = "Signature added. Others can move it until it's locked.";
|
||||
let out = std::env::temp_dir().join(format!("pdfcraft-lock-now-{}.pdf", std::process::id()));
|
||||
let place = |h: &mut Harness<'static, PdfCraftApp>, y: f32| {
|
||||
h.state_mut().signature = Some(SavedSig::Typed("Ada Lovelace".into()));
|
||||
h.state_mut().execute("sign.fill.signature");
|
||||
h.run_steps(2);
|
||||
click(h, 40.0, y);
|
||||
h.run_steps(2);
|
||||
};
|
||||
let marks = |h: &Harness<'static, PdfCraftApp>| {
|
||||
h.state().session.get(h.state().views[0].id).unwrap().info.annotations.iter().filter(|a| a.fill_sign).count()
|
||||
};
|
||||
let mut h = harness();
|
||||
h.state_mut().save_override = Some(out.to_string_lossy().into_owned());
|
||||
assert!(h.query_by_label(NOTICE).is_none(), "nothing placed yet");
|
||||
place(&mut h, 300.0);
|
||||
h.get_by_label(NOTICE);
|
||||
h.get_by_label("Lock now").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(marks(&h), 0, "locked into the page");
|
||||
assert!(h.query_by_label(NOTICE).is_none(), "nothing left to lock");
|
||||
assert!(h.state().session.get(h.state().views[0].id).unwrap().dirty, "locked, not saved");
|
||||
// Undo brings the movable signature back, with the notice and the save-time question.
|
||||
assert!(h.state_mut().execute("edit.undo"));
|
||||
h.run_steps(3);
|
||||
assert_eq!(marks(&h), 1);
|
||||
h.get_by_label(NOTICE);
|
||||
assert!(!h.state_mut().save_active(SaveTarget::InPlace), "asks again after undoing the lock");
|
||||
h.run_steps(2);
|
||||
h.get_by_label("Cancel").click();
|
||||
h.run_steps(2);
|
||||
// Locked again, the save doesn't ask.
|
||||
h.get_by_label("Lock now").click();
|
||||
h.run_steps(3);
|
||||
assert!(h.state_mut().save_active(SaveTarget::InPlace), "already locked: no question");
|
||||
// Dismiss hides it until the next signature.
|
||||
place(&mut h, 200.0);
|
||||
h.get_by_label(NOTICE);
|
||||
h.get_by_label("Dismiss").click();
|
||||
h.run_steps(2);
|
||||
assert!(h.query_by_label(NOTICE).is_none(), "dismissed");
|
||||
place(&mut h, 100.0);
|
||||
h.get_by_label(NOTICE);
|
||||
// Once saved, a signature kept as a comment is no longer just placed: no notice.
|
||||
assert!(!h.state_mut().save_active(SaveTarget::InPlace), "asks first");
|
||||
h.run_steps(2);
|
||||
h.get_by_label("Keep editable").click();
|
||||
h.run_steps(3);
|
||||
assert!(marks(&h) > 0, "still a comment");
|
||||
assert!(h.query_by_label(NOTICE).is_none(), "saved: nothing just placed");
|
||||
place(&mut h, 50.0);
|
||||
h.get_by_label(NOTICE);
|
||||
// Saves that lock anyway need no offer.
|
||||
h.state_mut().flatten_fill_sign_on_save = true;
|
||||
h.run_steps(2);
|
||||
assert!(h.query_by_label(NOTICE).is_none(), "saving locks it anyway");
|
||||
let _ = std::fs::remove_file(&out);
|
||||
|
||||
// Digitally signed: no notice, as locking would change the document after signing.
|
||||
let mut doc = {
|
||||
let mut h = harness();
|
||||
let app = h.state_mut();
|
||||
let id = app.views[0].id;
|
||||
let p12 = std::fs::read(concat!(env!("CARGO_MANIFEST_DIR"), "/../sign/tests/data/ec-p256.p12")).unwrap();
|
||||
let digital_id = pdfcraft_engine::sign::pkcs12::open(&p12, "test").unwrap();
|
||||
let opts = pdfcraft_engine::SignOptions { page: 0, rect: Some([20.0, 20.0, 160.0, 50.0]), ..Default::default() };
|
||||
app.session.sign(id, &digital_id, opts).expect("signs")
|
||||
};
|
||||
let mut h = harness_bytes(&std::mem::take(&mut doc));
|
||||
place(&mut h, 300.0);
|
||||
assert_eq!(marks(&h), 1);
|
||||
assert!(h.query_by_label(NOTICE).is_none(), "a signed document isn't offered the lock");
|
||||
}
|
||||
|
||||
/// #2348 review: when locking the signature fails (here the document's security allows comments
|
||||
/// but not changes), nothing is lost: the next save asks again, and "Don't ask again" isn't
|
||||
/// remembered.
|
||||
|
||||
@@ -5441,8 +5441,8 @@ milestone = "M5"
|
||||
status = "shipped"
|
||||
commands = ["comment.flatten"]
|
||||
tools = ["doc_save", "doc_flatten"]
|
||||
evidence = ["crates/edit/src/tests.rs::fill_sign_flatten_bakes_marks_keeps_other_comments_and_does_not_reuse_pcfl0", "crates/engine/src/tests.rs::flattening_fill_and_sign_keeps_other_comments_fields_and_undoes", "crates/engine/src/tests.rs::flattening_fill_and_sign_is_refused_without_permission_to_change", "crates/automation/tests/it/automation.rs::saving_with_flatten_fill_sign_bakes_marks_and_leaves_other_comments", "crates/ui-egui/tests/it/fill_sign.rs::saving_flattens_fill_and_sign_only_when_the_preference_is_on", "crates/ui-egui/tests/it/fill_sign.rs::the_first_save_after_placing_a_signature_asks_to_lock_it", "crates/ui-egui/tests/it/fill_sign.rs::cancelling_the_lock_question_saves_nothing", "crates/ui-egui/tests/it/fill_sign.rs::a_lock_that_fails_keeps_the_question", "crates/ui-egui/tests/it/fill_sign.rs::the_lock_question_is_skipped_or_kept_where_it_must_be"]
|
||||
notes = "Preferences ▸ Fill & Sign, and doc_save flatten_fill_sign, bake text, marks and signatures into the page. The option defaults off, so a normal save leaves them editable; the first save after a signature or initials is placed asks whether to lock it into the page (Lock and save / Keep editable, with Don't ask again), and the Sign menu carries the same switch (#2149). Other comments and form fields stay. Flatten comments still flattens every comment."
|
||||
evidence = ["crates/edit/src/tests.rs::fill_sign_flatten_bakes_marks_keeps_other_comments_and_does_not_reuse_pcfl0", "crates/engine/src/tests.rs::flattening_fill_and_sign_keeps_other_comments_fields_and_undoes", "crates/engine/src/tests.rs::flattening_fill_and_sign_is_refused_without_permission_to_change", "crates/automation/tests/it/automation.rs::saving_with_flatten_fill_sign_bakes_marks_and_leaves_other_comments", "crates/ui-egui/tests/it/fill_sign.rs::saving_flattens_fill_and_sign_only_when_the_preference_is_on", "crates/ui-egui/tests/it/fill_sign.rs::placing_a_signature_offers_to_lock_it_now", "crates/ui-egui/tests/it/fill_sign.rs::the_first_save_after_placing_a_signature_asks_to_lock_it", "crates/ui-egui/tests/it/fill_sign.rs::cancelling_the_lock_question_saves_nothing", "crates/ui-egui/tests/it/fill_sign.rs::a_lock_that_fails_keeps_the_question", "crates/ui-egui/tests/it/fill_sign.rs::the_lock_question_is_skipped_or_kept_where_it_must_be"]
|
||||
notes = "Preferences ▸ Fill & Sign, and doc_save flatten_fill_sign, bake text, marks and signatures into the page. The option defaults off, so a normal save leaves them editable; right after a signature or initials is placed, a notice offers Lock now (undoable, no save), and the first save after one is placed asks whether to lock it into the page (Lock and save / Keep editable, with Don't ask again); the Fill & Sign panel's Sign yourself section carries the same switch (#2149). Not on a digitally signed document. Other comments and form fields stay. Flatten comments still flattens every comment."
|
||||
|
||||
[[feature]]
|
||||
id = "form.autofill-profile"
|
||||
|
||||
Reference in new issue
Block a user