Save keeps the open text box or paragraph the document refused, and still applies the other (#3496)

This commit is contained in:
MarekSpodBiedry
2026-10-22 19:18:09 +02:00
parent 7956c6c182
commit db0689e381
2 changed files with 47 additions and 1 deletions
+33
View File
@@ -1513,6 +1513,39 @@ mod tests {
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn a_refused_text_box_does_not_lose_the_open_paragraph() {
let (mut app, mut ed) = preview_app();
ed.text = "Text preview".into();
app.views[0].line_editor = Some(ed);
let draft = crate::content_ui::TextDraft {
page: 9,
index: None,
rect: [20.0, 20.0, 120.0, 40.0],
text: "Typed text".into(),
style: crate::content_ui::default_style(),
focus: true,
};
app.views[0].content.draft = Some(draft.clone());
assert!(!app.commit_typing_in(app.views[0].id));
assert_eq!(app.views[0].content.draft, Some(draft), "the refused text box stays open");
assert!(app.views[0].line_editor.is_none(), "the paragraph was applied");
let doc = app.session.get(app.views[0].id).unwrap();
assert_eq!(doc.text_lines(0).iter().map(|l| l.text.as_str()).collect::<String>(), "Text preview");
}
#[test]
fn a_refused_paragraph_stays_open_with_its_text() {
let (mut app, mut ed) = preview_app();
ed.text = "Text preview".into();
ed.page = 9;
app.views[0].line_editor = Some(ed.clone());
assert!(!app.commit_typing_in(app.views[0].id));
assert_eq!(app.views[0].line_editor, Some(ed), "the paragraph keeps its unsaved text");
}
#[test]
fn text_background_is_cached_without_editing_and_released_on_cancel() {
let (app, ed) = preview_app();
+14 -1
View File
@@ -545,9 +545,22 @@ impl PdfCraftApp {
fn commit_open_text_edits(&mut self, id: pdfcraft_engine::DocId) -> bool {
let Some(doc) = self.session.get(id) else { return true };
let Some(view) = self.views.iter_mut().find(|v| v.id == id) else { return true };
// Both are taken out of the view before either edit runs, so keep what is needed to put
// back whichever one the document refuses: typed text must not be lost.
let (draft, select_added, editor) = (view.content.draft.clone(), view.content.select_added, view.line_editor.clone());
let added = view.content.finish_draft(doc.added());
let paragraph = view.line_editor.take_if(|ed| ed.has_changes()).and_then(crate::edit_text_ui::finished_edit);
added.into_iter().chain(paragraph).all(|edit| self.apply_edit(edit))
let added_ok = added.is_none_or(|edit| self.apply_edit(edit));
let paragraph_ok = paragraph.is_none_or(|edit| self.apply_edit(edit));
if let Some(view) = self.views.iter_mut().find(|v| v.id == id) {
if !added_ok {
(view.content.draft, view.content.select_added) = (draft, select_added);
}
if !paragraph_ok {
view.line_editor = editor;
}
}
added_ok && paragraph_ok
}
/// The Fill & Sign type box commits on click-away. Save does that first, so the text is in