forked from 1b-agent/opencadstudio-upstream
feat: PRINT command — send layout to system printer via lp/lpr
The PRINT command renders the current layout to a temporary PDF (reusing the existing PDF export pipeline) and dispatches it to the OS default printer: - Linux/macOS: `lp` (CUPS) with `lpr` as fallback. - Windows: ShellExecute "print" verb (compiled-in, unused on Linux). PLOT and EXPORT still open the save-file dialog as before. Status messages are shown in the command line during the async job. Closes ROADMAP 1.8. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
1 parent
ff39759d02
commit
f515b556c7
5 files changed
+191
-1
No files matched your search
+5
-1
@@ -3794,9 +3794,13 @@ impl H7CAD {
|
||||
}
|
||||
|
||||
// ── Plot / Page Setup ──────────────────────────────────────────
|
||||
"PRINT"|"PLOT"|"EXPORT" => {
|
||||
"PLOT"|"EXPORT" => {
|
||||
return Task::done(Message::PlotExport);
|
||||
}
|
||||
// PRINT — send current layout to the system default printer.
|
||||
"PRINT" => {
|
||||
return Task::done(Message::PrintToPrinter);
|
||||
}
|
||||
// PLOTSTYLE — load or clear CTB/STB plot style table
|
||||
cmd if cmd == "PLOTSTYLE" || cmd.starts_with("PLOTSTYLE ") => {
|
||||
let sub = cmd.split_once(' ')
|
||||
|
||||
@@ -402,6 +402,10 @@ pub enum Message {
|
||||
PlotExport,
|
||||
/// Callback after the user picks (or cancels) the export path.
|
||||
PlotExportPath(Option<std::path::PathBuf>),
|
||||
/// Send current layout to the system printer (via lp / lpr).
|
||||
PrintToPrinter,
|
||||
/// Callback from the async printer job.
|
||||
PrintResult(Result<String, String>),
|
||||
// ── Plot Style Table ─────────────────────────────────────────────────
|
||||
/// Open file dialog to load a CTB/STB plot style table.
|
||||
PlotStyleLoad,
|
||||
|
||||
@@ -2722,6 +2722,70 @@ impl H7CAD {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
// ── Print to system printer ───────────────────────────────────────
|
||||
Message::PrintToPrinter => {
|
||||
let i = self.active_tab;
|
||||
let scene = &self.tabs[i].scene;
|
||||
let layout_name = scene.current_layout.clone();
|
||||
let wires = scene.entity_wires();
|
||||
use acadrust::objects::{ObjectType, PlotType};
|
||||
let ps_snap = scene.document.objects.values().find_map(|obj| {
|
||||
if let ObjectType::PlotSettings(ps) = obj {
|
||||
if ps.page_name == layout_name { Some(ps.clone()) } else { None }
|
||||
} else { None }
|
||||
});
|
||||
let (paper_w, paper_h, draw_ox, draw_oy, rotation_deg) =
|
||||
if let Some(((x0, y0), (x1, y1))) = scene.paper_limits() {
|
||||
let (pw, ph) = (x1 - x0, y1 - y0);
|
||||
let use_extents = ps_snap.as_ref()
|
||||
.map(|ps| matches!(ps.plot_type, PlotType::Extents))
|
||||
.unwrap_or(false);
|
||||
let (ox, oy) = if use_extents {
|
||||
if let Some((mn, _mx)) = scene.model_space_extents() {
|
||||
(-mn.x as f64, -mn.y as f64)
|
||||
} else { (-x0, -y0) }
|
||||
} else { (-x0, -y0) };
|
||||
let rot = ps_snap.as_ref()
|
||||
.map(|ps| ps.rotation.to_degrees() as i32)
|
||||
.unwrap_or(0);
|
||||
(pw, ph, ox, oy, rot)
|
||||
} else {
|
||||
if let Some((mn, mx)) = scene.model_space_extents() {
|
||||
let margin = 1.05_f64;
|
||||
let w = ((mx.x - mn.x) as f64 * margin).max(1.0);
|
||||
let h = ((mx.y - mn.y) as f64 * margin).max(1.0);
|
||||
let pad_x = (w - (mx.x - mn.x) as f64) * 0.5;
|
||||
let pad_y = (h - (mx.y - mn.y) as f64) * 0.5;
|
||||
(w, h, -(mn.x as f64) + pad_x, -(mn.y as f64) + pad_y, 0)
|
||||
} else { (297.0, 210.0, 0.0, 0.0, 0) }
|
||||
};
|
||||
let (eff_w, eff_h) = match rotation_deg {
|
||||
90 | 270 => (paper_h, paper_w),
|
||||
_ => (paper_w, paper_h),
|
||||
};
|
||||
let plot_style = self.active_plot_style.clone();
|
||||
self.command_line.push_info("Sending to system printer…");
|
||||
Task::perform(
|
||||
async move {
|
||||
crate::io::print_to_printer::print_wires(
|
||||
wires, eff_w, eff_h,
|
||||
draw_ox as f32, draw_oy as f32,
|
||||
rotation_deg, plot_style,
|
||||
)
|
||||
.await
|
||||
},
|
||||
Message::PrintResult,
|
||||
)
|
||||
}
|
||||
Message::PrintResult(Ok(printer)) => {
|
||||
self.command_line.push_info(&format!("Sent to printer: {printer}"));
|
||||
Task::none()
|
||||
}
|
||||
Message::PrintResult(Err(e)) => {
|
||||
self.command_line.push_error(&format!("Print failed: {e}"));
|
||||
Task::none()
|
||||
}
|
||||
|
||||
// ── Plot Style Table ──────────────────────────────────────────────
|
||||
Message::PlotStyleLoad => {
|
||||
Task::perform(
|
||||
|
||||
Reference in new issue
Block a user