feat(thumbnails): embed DWG previews and wire cross-platform file thumbnails
Round-trip a raster preview through the DWG's embedded preview slot and
surface it to the OS file managers, so drawings show their contents in
Explorer / Finder / Nautilus instead of a generic document icon.
OCS:
* io::thumbnail — rasterize the scene to a BMP DIB on save (embedded via
acadrust's new Preview type) and read it back on open for the Start
page recent list; `--dwg-thumbnail IN OUT SIZE` CLI extracts a badged
PNG for external thumbnailers.
* io::file_association::install_thumbnailer — self-install the OS
integration on startup: Linux writes a .thumbnailer + hicolor mimetype
icons; Windows registers the IThumbnailProvider DLL under HKCU.
Shared core:
* crates/dwg-thumbnailer — lean (image-only) preview extractor + the
`badge_dwg` full-width "DWG" band, used by every platform so the
ribbon is single-sourced. Ships an rlib+staticlib.
* crates/dwg-thumbnailer-win — IThumbnailProvider COM in-proc server
(cfg(windows), CI-built as a workspace member).
* macos/ — QuickLook thumbnail extension (Swift + C-ABI bridge to the
core staticlib), assembled into a .appex.
Icons & packaging (single SVG source -> per-platform assets in CI):
* assets/mimetypes/image-vnd.{dwg,dxf}.svg — themed file icons.
* packaging: WiX ships dwg/dxf.ico + the thumbnail DLL and points the
ProgIds at them; Info.plist gets CFBundleTypeIconFile + the QuickLook
extension in Contents/PlugIns.
* release.yml — generate .ico (Windows) and .icns (macOS) from the SVGs,
build the QuickLook .appex, and bundle everything.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
5c4ba97c5f
commit
ba3b3202e8
20 changed files with 1085 additions and 76 deletions
20
src/main.rs
20
src/main.rs
|
|
@ -51,6 +51,19 @@ fn main() -> iced::Result {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
// Thumbnail mode: the OS file-manager thumbnailer invokes us as
|
||||
// `--dwg-thumbnail <in> <out> <size>`. Extract the DWG's embedded
|
||||
// preview to a PNG and exit — never touch the GUI.
|
||||
if let Some(a) = &args.dwg_thumbnail {
|
||||
let size = a.get(2).and_then(|s| s.parse().ok()).unwrap_or(256);
|
||||
let ok = io::thumbnail::extract_to_png(
|
||||
std::path::Path::new(&a[0]),
|
||||
std::path::Path::new(&a[1]),
|
||||
size,
|
||||
);
|
||||
std::process::exit(if ok { 0 } else { 1 });
|
||||
}
|
||||
|
||||
// Opt-in logging. `--log LEVEL` seeds RUST_LOG; the subscriber then
|
||||
// surfaces wgpu / iced / winit diagnostics that are otherwise silent.
|
||||
if let Some(level) = &args.log {
|
||||
|
|
@ -110,6 +123,13 @@ fn main() -> iced::Result {
|
|||
read_only: args.read_only,
|
||||
script_lines,
|
||||
});
|
||||
|
||||
// Register (or refresh) the freedesktop DWG thumbnailer so file managers
|
||||
// show OCS-embedded previews. Idempotent, best-effort, no consent step —
|
||||
// it only points a `.thumbnailer` at this same binary's `--dwg-thumbnail`
|
||||
// mode. Silently ignored on failure or non-Linux.
|
||||
io::file_association::install_thumbnailer();
|
||||
|
||||
app::run()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue