diff --git a/crates/ui-egui/src/app/prefs.rs b/crates/ui-egui/src/app/prefs.rs index 489c216162..0d7ccf6801 100644 --- a/crates/ui-egui/src/app/prefs.rs +++ b/crates/ui-egui/src/app/prefs.rs @@ -161,6 +161,7 @@ impl PdfCraftApp { ); let size = self.print_draft.paper_size(); v["print_paper_size"] = serde_json::json!([size.0, size.1]); + v["print_paper_overridden"] = serde_json::json!(self.print_draft.paper_overridden); v.to_string() } @@ -287,6 +288,7 @@ impl PdfCraftApp { 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); } 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 262c84077a..af71bfac1c 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 && self.print_draft.paper == 0 { + if !picked && !self.print_draft.paper_overridden { self.print_draft.auto_select_default_paper(); } self.dialog = Some(crate::Dialog::Print); @@ -318,7 +318,7 @@ impl PdfCraftApp { d.printer_picked = false; d.printer = default_printer(&printers); d.update_printer_papers(); - if !d.paper_overridden && d.paper == 0 { + if !d.paper_overridden { d.auto_select_default_paper(); } } diff --git a/crates/ui-egui/src/workflows/print_ui/body.rs b/crates/ui-egui/src/workflows/print_ui/body.rs index edff10b9b6..3d093cbd54 100644 --- a/crates/ui-egui/src/workflows/print_ui/body.rs +++ b/crates/ui-egui/src/workflows/print_ui/body.rs @@ -214,10 +214,13 @@ pub(crate) fn body( let paper_label = ui.label(tl!("Paper:")); let paper_name = d.paper_name().to_string(); let before = d.paper; + let mut paper_clicked = false; ui.horizontal(|ui| { craft_ui::ComboBox::from_id_salt("paper").selected_text(tl!(&paper_name)).width(180.0).show_ui(ui, |ui| { for (i, (name, _)) in d.papers.iter().enumerate() { - ui.selectable_value(&mut d.paper, i, tl!(name)); + if ui.selectable_value(&mut d.paper, i, tl!(name)).clicked() { + paper_clicked = true; + } } }) .response @@ -246,7 +249,7 @@ pub(crate) fn body( d.paper_overridden = true; } // Label stock gets the label layout (cut, turned upright, fitted). - if d.paper != before && d.paper == print::LABEL_PAPER { + if paper_clicked && d.paper != before && d.paper == print::LABEL_PAPER { d.paper_before_label = Some(before); d.handling = Handling::Label; d.sheet = 0; @@ -281,6 +284,7 @@ pub(crate) fn body( && let Some(paper) = matched { d.paper = paper; + d.paper_overridden = true; // A paper picked outright: nothing for leaving Label to give back. d.paper_before_label = None; d.handling = Handling::Size; diff --git a/crates/ui-egui/src/workflows/print_ui/draft.rs b/crates/ui-egui/src/workflows/print_ui/draft.rs index 47d388122c..72082626cb 100644 --- a/crates/ui-egui/src/workflows/print_ui/draft.rs +++ b/crates/ui-egui/src/workflows/print_ui/draft.rs @@ -168,10 +168,14 @@ 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 mut papers = default_papers(); if let Some(ref printer) = self.printer { let detected = spool::printer_papers(printer); for (name, size) in detected { + if !(size.0 >= 72.0 && size.1 >= 72.0 && size.0.is_finite() && size.1.is_finite()) { + continue; + } let norm = (size.0.min(size.1), size.0.max(size.1)); if !papers.iter().any(|(_, s)| { let s_norm = (s.0.min(s.1), s.0.max(s.1)); @@ -192,6 +196,7 @@ 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)); } /// Auto-select the printer's configured default paper (from DEVMODE / driver settings). @@ -199,7 +204,9 @@ impl PrintDraft { if let Some(ref printer) = self.printer && let Some((name, size)) = spool::printer_default_paper(printer) { + let overridden = self.paper_overridden; self.apply_driver_paper(name, size); + self.paper_overridden = overridden; } } diff --git a/crates/ui-egui/tests/it/print.rs b/crates/ui-egui/tests/it/print.rs index ef3821e234..9aa3779e29 100644 --- a/crates/ui-egui/tests/it/print.rs +++ b/crates/ui-egui/tests/it/print.rs @@ -791,9 +791,10 @@ fn paper_choice_survives_cancel_and_settings_restore() { let saved = h.state().persist(); let json: serde_json::Value = serde_json::from_str(&saved).unwrap(); assert_eq!(json["print_paper"], "A4", "store the canonical name, not its position"); + assert_eq!(json["print_paper_overridden"], true, "explicitly chosen paper records override flag"); let mut app = PdfCraftApp::new(); app.restore(&saved); - let expected = pdfcraft_ui_egui::PrintDraft { paper: a4, ..Default::default() }; + 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"); let mut restarted = harness_with_settings(Some(saved)); assert!(restarted.state_mut().execute("print.dialog"));