From 290f775316a61dc105f52b99ada8133885f67f84 Mon Sep 17 00:00:00 2001 From: Combiler01 Date: Wed, 4 Nov 2026 12:43:28 +0530 Subject: [PATCH] fix(print): refine paper matching, override tracking, and settings restore --- crates/ui-egui/src/app/prefs.rs | 24 +++++++++++++------ crates/ui-egui/src/workflows/print_ui.rs | 2 +- crates/ui-egui/src/workflows/print_ui/body.rs | 2 +- .../ui-egui/src/workflows/print_ui/draft.rs | 17 ++++++++++--- crates/ui-egui/tests/it/print.rs | 9 +++++++ 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/crates/ui-egui/src/app/prefs.rs b/crates/ui-egui/src/app/prefs.rs index 0d7ccf6801..6d26b665b5 100644 --- a/crates/ui-egui/src/app/prefs.rs +++ b/crates/ui-egui/src/app/prefs.rs @@ -276,19 +276,29 @@ impl PdfCraftApp { self.always_default_view = on; } if let Some(name) = v.get("print_paper").and_then(serde_json::Value::as_str) { - if let Some(paper) = self.print_draft.papers.iter().position(|(n, _)| n == name) { - self.print_draft.paper = paper; - } else if let Some(paper) = pdfcraft_engine::print::PAPERS.iter().position(|(canonical, _)| *canonical == name) { - self.print_draft.paper = paper; - } else if let Some(size) = v.get("print_paper_size").and_then(|s| { + let saved_size = v.get("print_paper_size").and_then(|s| { let w = s.get(0)?.as_f64()?; let h = s.get(1)?.as_f64()?; if w >= 72.0 && h >= 72.0 && w.is_finite() && h.is_finite() { Some((w, h)) } else { None } - }) { + }); + let matched_pos = self + .print_draft + .papers + .iter() + .position(|(n, s)| n == name && saved_size.is_none_or(|sz| (s.0 - sz.0).abs() <= 1.0 && (s.1 - sz.1).abs() <= 1.0)) + .or_else(|| { + pdfcraft_engine::print::PAPERS.iter().position(|(canonical, s)| { + *canonical == name && saved_size.is_none_or(|sz| (s.0 - sz.0).abs() <= 1.0 && (s.1 - sz.1).abs() <= 1.0) + }) + }); + if let Some(paper) = matched_pos { + self.print_draft.paper = paper; + self.print_draft.paper_overridden = v.get("print_paper_overridden").and_then(serde_json::Value::as_bool).unwrap_or(true); + } else if let Some(size) = saved_size { self.print_draft.papers.push((name.to_string(), size)); self.print_draft.paper = self.print_draft.papers.len() - 1; + self.print_draft.paper_overridden = v.get("print_paper_overridden").and_then(serde_json::Value::as_bool).unwrap_or(true); } - self.print_draft.paper_overridden = v.get("print_paper_overridden").and_then(serde_json::Value::as_bool).unwrap_or(true); } if let Some(on) = v["highlight_fields"].as_bool() { self.view_defaults.highlight_fields = on; diff --git a/crates/ui-egui/src/workflows/print_ui.rs b/crates/ui-egui/src/workflows/print_ui.rs index af71bfac1c..c9952428be 100644 --- a/crates/ui-egui/src/workflows/print_ui.rs +++ b/crates/ui-egui/src/workflows/print_ui.rs @@ -172,7 +172,7 @@ impl PdfCraftApp { ..keep }; self.print_draft.update_printer_papers(); - if !picked && !self.print_draft.paper_overridden { + if !self.print_draft.paper_overridden { self.print_draft.auto_select_default_paper(); } self.dialog = Some(crate::Dialog::Print); diff --git a/crates/ui-egui/src/workflows/print_ui/body.rs b/crates/ui-egui/src/workflows/print_ui/body.rs index 3d093cbd54..dcf90a1fb5 100644 --- a/crates/ui-egui/src/workflows/print_ui/body.rs +++ b/crates/ui-egui/src/workflows/print_ui/body.rs @@ -245,7 +245,7 @@ pub(crate) fn body( } } }); - if d.paper != before { + if paper_clicked || d.paper != before { d.paper_overridden = true; } // Label stock gets the label layout (cut, turned upright, fitted). diff --git a/crates/ui-egui/src/workflows/print_ui/draft.rs b/crates/ui-egui/src/workflows/print_ui/draft.rs index 72082626cb..bafe5dc3a6 100644 --- a/crates/ui-egui/src/workflows/print_ui/draft.rs +++ b/crates/ui-egui/src/workflows/print_ui/draft.rs @@ -168,7 +168,7 @@ impl PrintDraft { /// Refresh `self.papers` with driver-reported media sizes, preserving the current selection. pub fn update_printer_papers(&mut self) { - let before_label_name = self.paper_before_label.and_then(|idx| self.papers.get(idx).map(|p| p.0.clone())); + let before_label = self.paper_before_label.and_then(|idx| self.papers.get(idx).cloned()); let mut papers = default_papers(); if let Some(ref printer) = self.printer { let detected = spool::printer_papers(printer); @@ -188,7 +188,9 @@ impl PrintDraft { let current_name = self.paper_name().to_string(); let current_size = self.paper_size(); self.papers = papers; - if let Some(pos) = self.papers.iter().position(|(n, _)| n == ¤t_name) { + if let Some(pos) = + self.papers.iter().position(|(n, s)| n == ¤t_name && (s.0 - current_size.0).abs() <= 0.5 && (s.1 - current_size.1).abs() <= 0.5) + { self.paper = pos; } else if let Some(pos) = self.papers.iter().position(|(_, s)| (s.0 - current_size.0).abs() <= 0.5 && (s.1 - current_size.1).abs() <= 0.5) { self.paper = pos; @@ -196,7 +198,16 @@ impl PrintDraft { self.papers.push((current_name, current_size)); self.paper = self.papers.len() - 1; } - self.paper_before_label = before_label_name.and_then(|name| self.papers.iter().position(|(n, _)| n == &name)); + self.paper_before_label = before_label.map(|(name, size)| { + if let Some(pos) = self.papers.iter().position(|(n, s)| n == &name && (s.0 - size.0).abs() <= 0.5 && (s.1 - size.1).abs() <= 0.5) { + pos + } else if let Some(pos) = self.papers.iter().position(|(_, s)| (s.0 - size.0).abs() <= 0.5 && (s.1 - size.1).abs() <= 0.5) { + pos + } else { + self.papers.push((name, size)); + self.papers.len() - 1 + } + }); } /// Auto-select the printer's configured default paper (from DEVMODE / driver settings). diff --git a/crates/ui-egui/tests/it/print.rs b/crates/ui-egui/tests/it/print.rs index 9aa3779e29..04a7d67b52 100644 --- a/crates/ui-egui/tests/it/print.rs +++ b/crates/ui-egui/tests/it/print.rs @@ -796,6 +796,15 @@ fn paper_choice_survives_cancel_and_settings_restore() { app.restore(&saved); let expected = pdfcraft_ui_egui::PrintDraft { paper: a4, paper_overridden: true, ..Default::default() }; assert_eq!(app.print_draft, expected, "no other print preference becomes persistent"); + + // Default draft without override round-trips with paper_overridden remaining false. + let default_app = PdfCraftApp::new(); + let default_saved = default_app.persist(); + let default_json: serde_json::Value = serde_json::from_str(&default_saved).unwrap(); + assert_eq!(default_json["print_paper_overridden"], false); + let mut restored_default = PdfCraftApp::new(); + restored_default.restore(&default_saved); + assert!(!restored_default.print_draft.paper_overridden); let mut restarted = harness_with_settings(Some(saved)); assert!(restarted.state_mut().execute("print.dialog")); restarted.run_steps(3);