M4.63: Links panel with status, Relink, Go To, Update, Edit Original, Embed/Unembed, Link Info and Placement Options

The Links panel lists every image (thumbnail, name, page, missing/modified/embedded
badge) with Show filters, sorting and thumbnail sizes; its buttons and flyout relink
(to a file or a folder), go to, update, edit the original, embed and unembed, show in
folder and open Placement Options. Link Info shows format, colour space, location, ppi
and effective ppi, dimensions, scale, rotation, size and dates. Edit > Edit Original
and the Properties panel's image section reach the same commands.

Engine: links.list, links.goTo, links.embed, links.unembed, links.info and
links.placementOptions; links.relink and links.update now place the new file as the
image's Placement Options say (transforms, bounds, file dimensions, fit, fill, the
alignment point, clip to the old bounds). Model: ImageObject.placement.
UI: links.editOriginal, links.reveal, ui.placementOptionsDialog; Services.open_file
and pick_folder on the desktop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bflatastic
2026-10-05 12:40:05 +07:00
co-authored by Claude Opus 5.5
parent 171de62fde
commit 2925e7f9b5
50 changed files with 1901 additions and 86 deletions
+21
View File
@@ -173,10 +173,31 @@ fn services() -> Services {
let _ = webbrowser::open(url);
})),
reveal: Some(Box::new(reveal)),
// Links panel: Edit Original; Package: Show Package. Relink to Folder and Package pick folders.
open_file: Some(Box::new(open_file)),
pick_folder: Some(Box::new(|| rfd::FileDialog::new().pick_folder().map(|p| p.to_string_lossy().to_string()))),
..Default::default()
}
}
/// Edit Original, Show Package: open `path` (a file or a folder) in the system's default app for it.
fn open_file(path: &str) -> Result<(), String> {
#[cfg(windows)]
let mut c = {
use std::os::windows::process::CommandExt as _;
let mut c = std::process::Command::new("explorer");
c.raw_arg(format!("\"{}\"", path.replace('/', "\\")));
c
};
#[cfg(target_os = "macos")]
let mut c = std::process::Command::new("open");
#[cfg(not(any(target_os = "macos", windows)))]
let mut c = std::process::Command::new("xdg-open");
#[cfg(not(windows))]
c.arg(path);
c.spawn().map(|_| ()).map_err(|e| format!("can't open {path}: {e}"))
}
/// The window, Dock, taskbar and app-switcher icon (`assets/app-icon/`, see its README). macOS gets
/// the version with Apple's transparent margin; elsewhere the full-bleed tile. The app ID matches
/// `packaging/linux/ai.storyteller.vectorcraft.desktop` so Wayland docks find the launcher icon.