From 0b3fa7afb5a9770b80024e3db9764adcb3aab887 Mon Sep 17 00:00:00 2001 From: Philip Date: Mon, 19 Oct 2026 21:26:26 +0100 Subject: [PATCH] M10: review of #1609: no automatic recognition in Read mode or beneath a dialog CodeRabbit: Read mode leaves the Edit tool picked, so the recognition Edit starts could run in Read mode and change a scanned document; and it could run while a dialog or prompt was open, which PdfCraftApp::modal_open says nothing may act beneath. It now waits for Edit to be on outside Read mode with no modal open, and is tried again once they are gone. Co-Authored-By: Claude Sonnet 5.5 --- crates/ui-egui/src/ocr_ui.rs | 5 ++++- crates/ui-egui/tests/ocr.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/ocr_ui.rs b/crates/ui-egui/src/ocr_ui.rs index 34f023d6dd..dcd3553756 100644 --- a/crates/ui-egui/src/ocr_ui.rs +++ b/crates/ui-egui/src/ocr_ui.rs @@ -184,7 +184,10 @@ impl PdfCraftApp { // the same test the page view uses for editing content. let editing = (self.left_open && self.left == crate::LeftPanel::Tool("edit")) || matches!(self.quick_tool, crate::QuickTool::EditText | crate::QuickTool::AddText); - if !editing || self.ocr_run.is_some() || self.ocr_batch.is_some() { + // Not in Read mode (which leaves the Edit tool picked but is not editing) and not beneath a + // dialog or prompt: nothing may change the document under those. It is tried again once + // they are gone. + if !editing || self.mode == crate::Mode::Read || self.modal_open() || self.ocr_run.is_some() || self.ocr_batch.is_some() { return; } let Some((vi, id)) = self.active_ids() else { return }; diff --git a/crates/ui-egui/tests/ocr.rs b/crates/ui-egui/tests/ocr.rs index 86740c4517..872768c549 100644 --- a/crates/ui-egui/tests/ocr.rs +++ b/crates/ui-egui/tests/ocr.rs @@ -309,6 +309,33 @@ fn a_page_that_becomes_a_scan_while_edit_is_on_is_recognized() { assert_eq!(h.state().session.get(id).unwrap().can_undo(), Some("Recognize text")); } +/// Edit changes the document only while the user is editing: not in Read mode (which leaves the Edit +/// tool picked), and not beneath a dialog. The page is recognized once those are gone. +#[test] +fn edit_recognizes_a_scan_only_outside_read_mode_and_beneath_no_dialog() { + if !pdfcraft_engine::ocr::available() { + eprintln!("skipped: OCR models not installed"); + return; + } + let mut h = edit_harness(scan()); + let id = h.state().active_ids().unwrap().1; + let undo = |h: &Harness<'static, PdfCraftApp>| -> Option { h.state().session.get(id).unwrap().can_undo().map(String::from) }; + // Read mode with the Edit tool still picked. + assert!(h.state_mut().execute("edit.edit_text")); + h.state_mut().set_option("mode", "read").unwrap(); + h.run_steps(5); + assert_eq!(undo(&h), None, "not in Read mode"); + // A dialog over the window. + h.state_mut().set_option("mode", "edit").unwrap(); + h.state_mut().dialog = Some(pdfcraft_ui_egui::Dialog::JsConsole); + h.run_steps(5); + assert_eq!(undo(&h), None, "not beneath a dialog"); + // Both gone: it is read now. + h.state_mut().dialog = None; + h.run_steps(5); + assert_eq!(undo(&h).as_deref(), Some("Recognize text")); +} + #[test] fn editing_a_page_that_has_text_does_not_recognize_anything() { let mut h = edit_harness(text_page());