forked from 1b-agent/opencadstudio-upstream
fix(print): complete Windows printer discovery, honor the true default, surface failures; make CTB loading usable (#1261)
Printer enumeration used EnumPrinters level 4 only, which is served from the local registry cache and misses Win11 per-user network printers; an empty result now retries with level 2 (spooler RPC) and merges the resolved default. The dialog's 'System default printer' used to delegate to the shell print verb — the default PDF handler's own printer choice, not the system default; it now resolves GetDefaultPrinterW and dispatches printto naming that printer explicitly. Every dispatch probes OpenPrinterW first, so a printer that vanished between listing and printing produces a clear error instead of ShellExecute's silent nothing, and all SE_ERR_* codes carry readable reasons. Legacy CTB: picking an unparseable table used to swallow the failure (.ok()) — the user saw nothing at all. Load errors now reach the command line, the picker accepts .stb alongside .ctb (the container gains the STBVER1 header; .stb application errors state the actual reason), and a table loaded from anywhere is copied into the user's plot-styles folder so it persists in the dialog, matching AutoCAD. Buffer parsing for both EnumPrinters layouts is unit-tested; the missing-printer path was exercised against the real spooler (existence probe only, no job).
This commit is contained in:
1 parent
02d9273a19
commit
5ea4294d3d
6 files changed
+390
-44
No files matched your search
+33
-5
@@ -1523,19 +1523,47 @@ mod save_failure_tests {
|
||||
// ── Plot Style Table ──────────────────────────────────────────────────────
|
||||
|
||||
/// Show a file-open dialog and load the selected CTB or STB file.
|
||||
pub async fn pick_plot_style() -> Option<plot_style::PlotStyleTable> {
|
||||
/// `Ok(None)` means the user cancelled the dialog; `Err` carries a parse
|
||||
/// failure so it reaches the command line instead of dying silently (the
|
||||
/// legacy-CTB complaint in #1261d was partly that a file which failed to
|
||||
/// parse produced no feedback at all).
|
||||
pub async fn pick_plot_style() -> Result<Option<plot_style::PlotStyleTable>, String> {
|
||||
let dialog = crate::sys::file_dialog()
|
||||
.set_title(crate::t!("Load Plot Style Table").as_ref())
|
||||
.add_filter(crate::t!("Plot Style Tables").as_ref(), &["ctb", "CTB"])
|
||||
.add_filter(crate::t!("CTB Files").as_ref(), &["ctb", "CTB"])
|
||||
.add_filter(
|
||||
crate::t!("Plot Style Tables").as_ref(),
|
||||
&["ctb", "stb", "CTB", "STB"],
|
||||
)
|
||||
.add_filter(crate::t!("All Files").as_ref(), &["*"]);
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let dialog = match plot_style::ensure_plot_styles_dir() {
|
||||
Ok(dir) => dialog.set_directory(dir),
|
||||
Err(_) => dialog,
|
||||
};
|
||||
let handle = dialog.pick_file().await?;
|
||||
plot_style::PlotStyleTable::load(&crate::sys::handle_path(&handle)).ok()
|
||||
let Some(handle) = dialog.pick_file().await else {
|
||||
return Ok(None);
|
||||
};
|
||||
let path = crate::sys::handle_path(&handle);
|
||||
let table = plot_style::PlotStyleTable::load(&path).map_err(|error| {
|
||||
crate::tf!(
|
||||
"Could not load plot style table '{}': {error}",
|
||||
path.display()
|
||||
)
|
||||
.into_owned()
|
||||
})?;
|
||||
// Loading a table registers it, the way AutoCAD does: copy it next to the
|
||||
// built-ins so it stays in the Plot dialog's table list after restart.
|
||||
// Failures are non-fatal — the table is already applied to this plot.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
if !table.is_stb {
|
||||
if let (Ok(dir), Some(file_name)) = (plot_style::plot_styles_dir(), path.file_name()) {
|
||||
let registered = dir.join(file_name);
|
||||
if !registered.exists() {
|
||||
let _ = std::fs::copy(&path, ®istered);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Some(table))
|
||||
}
|
||||
|
||||
// ── Image file picker ─────────────────────────────────────────────────────
|
||||
|
||||
Reference in new issue
Block a user