From 96505d3a77c79e65ecdfe9635ecb8ae02f75072e Mon Sep 17 00:00:00 2001 From: ruchirguitar <113586074+ruchirguitar@users.noreply.github.com> Date: Thu, 5 Nov 2026 12:37:16 +0530 Subject: [PATCH] Fix #5526: document the functions the link-status selection touches Doc comments for the Select add-on commands, the Select by Link Status dialog body, the Links panel menu and the test helpers (review: docstring coverage). Co-Authored-By: Claude Opus 5.5 --- crates/engine/src/cmd/addons/select.rs | 6 ++++++ crates/engine/src/cmd/addons/select/tests.rs | 6 ++++++ crates/ui-egui/src/addons/select/link_status.rs | 3 +++ crates/ui-egui/src/addons/select/link_status/tests.rs | 2 ++ crates/ui-egui/src/panels/links.rs | 2 ++ 5 files changed, 19 insertions(+) diff --git a/crates/engine/src/cmd/addons/select.rs b/crates/engine/src/cmd/addons/select.rs index 4d71895c0..b2ab59d85 100644 --- a/crates/engine/src/cmd/addons/select.rs +++ b/crates/engine/src/cmd/addons/select.rs @@ -25,6 +25,7 @@ pub const RELATIONS: [&str; 3] = ["overlap", "inside", "outside"]; /// in the document, a file not found, a file changed since it was read. pub const LINK_STATUSES: [&str; 4] = ["linked", "embedded", "missing", "modified"]; +/// The add-on's commands: Select by Artboards and Select by Link Status. pub fn specs() -> Vec { vec![ cmd!( @@ -48,6 +49,8 @@ pub fn specs() -> Vec { ] } +/// `addon.select.byArtboards`: select the objects Select All takes that overlap, lie inside or lie +/// outside the chosen artboards. fn by_artboards(s: &mut Session, p: &Value) -> Result { const C: &str = "addon.select.byArtboards"; let relation = text_param(p, "relation", C)?.unwrap_or("overlap"); @@ -151,6 +154,9 @@ fn skip_reason(st: &DocState, locks: &LockedArtboards, id: NodeId) -> Option<&'s }) } +/// `addon.select.byLinkStatus`: select the images and placed documents whose link has one of the +/// statuses asked for (among `ids` when given), replacing the selection or adding to it, and list +/// those left out with the reason ([`skip_reason`]). fn by_link_status(s: &mut Session, p: &Value) -> Result { const C: &str = "addon.select.byLinkStatus"; let wanted = link_statuses(p, C)?; diff --git a/crates/engine/src/cmd/addons/select/tests.rs b/crates/engine/src/cmd/addons/select/tests.rs index ca5956526..c97b27825 100644 --- a/crates/engine/src/cmd/addons/select/tests.rs +++ b/crates/engine/src/cmd/addons/select/tests.rs @@ -150,6 +150,8 @@ mod by_link_status { _dir: Folder, } + /// [`Links`] in a fresh folder named after `name`: the files placed, then one changed and two + /// removed. fn links(name: &str) -> Links { let dir = Folder::new(name); let (a, b, c, e, d) = (dir.file("ok.png"), dir.file("changes.png"), dir.file("goes.png"), dir.file("kept.png"), dir.file("page.vectorcraft")); @@ -168,19 +170,23 @@ mod by_link_status { Links { s, ok, modified, missing, embedded, document, _dir: dir } } + /// Run the command with `p`, which must succeed. fn run(s: &mut Session, p: Value) -> Value { s.execute(C, &p).unwrap_or_else(|e| panic!("{p}: {e}")) } + /// `v` sorted. fn sorted(mut v: Vec) -> Vec { v.sort(); v } + /// The selected objects, sorted. fn selection(s: &Session) -> Vec { sorted(s.doc().unwrap().selection.objects.clone()) } + /// The ids of a JSON list, sorted. fn ids(v: &Value) -> Vec { sorted(v.as_array().unwrap().iter().map(|i| NodeId(i.as_u64().unwrap())).collect()) } diff --git a/crates/ui-egui/src/addons/select/link_status.rs b/crates/ui-egui/src/addons/select/link_status.rs index 7b7203276..0b367a7ba 100644 --- a/crates/ui-egui/src/addons/select/link_status.rs +++ b/crates/ui-egui/src/addons/select/link_status.rs @@ -138,6 +138,7 @@ pub(crate) fn message(statuses: &[&str], count: u64, reasons: &[&str]) -> String }; let Some(first) = reasons.first() else { return selected }; // Hidden and locked go together; a template layer, or the isolated group, alone. + /// The group reason `r` is told in: hidden and locked are one. fn kind(r: &str) -> &str { match r { "hidden" | "locked" => "locked", @@ -217,6 +218,8 @@ fn status_label(status: &str) -> &'static str { STATUSES.iter().find(|(s, ..)| *s == status).map_or("", |&(.., label)| tl!(label)) } +/// The dialog: the search, the Show filter, a checkbox row per image shown (name, status, format), +/// All / None with the count chosen, and Zoom to Selection. Returns false: nothing to preview. fn body(_app: &mut VectorcraftApp, ui: &mut Ui, d: &mut Dialog) -> bool { let t = Tokens::get(ui.ctx()); let rows: Vec = d.fields.get("__rows").and_then(Value::as_array).cloned().unwrap_or_default(); diff --git a/crates/ui-egui/src/addons/select/link_status/tests.rs b/crates/ui-egui/src/addons/select/link_status/tests.rs index 22b07ccac..8ad61f6e5 100644 --- a/crates/ui-egui/src/addons/select/link_status/tests.rs +++ b/crates/ui-egui/src/addons/select/link_status/tests.rs @@ -28,6 +28,7 @@ impl Drop for Folder { } } +/// A `w` × `h` red PNG. fn png(w: u32, h: u32) -> Vec { let mut out = vec![]; image::RgbaImage::from_pixel(w, h, image::Rgba([200, 40, 40, 255])) @@ -53,6 +54,7 @@ fn app(dir: &Folder) -> (VectorcraftApp, u64, u64, u64) { (app, river, harbour, stamp) } +/// The selected objects' ids, sorted. fn selected(app: &VectorcraftApp) -> Vec { let mut ids: Vec = app.session.active().unwrap().selection.objects.iter().map(|id| id.0).collect(); ids.sort_unstable(); diff --git a/crates/ui-egui/src/panels/links.rs b/crates/ui-egui/src/panels/links.rs index d27603424..a7fe30185 100644 --- a/crates/ui-egui/src/panels/links.rs +++ b/crates/ui-egui/src/panels/links.rs @@ -535,6 +535,8 @@ fn link_info(ui: &mut Ui, info: Option<&Value>, units: vectorcraft_doc::Unit) { row(ui, tl!("Status"), status.into()); } +/// The panel's flyout menu: the link commands for the selected rows, Select Linked / Embedded / +/// Missing / Modified for the whole document, and the Show, Sort and thumbnail options. pub fn menu(app: &mut VectorcraftApp, ui: &mut Ui) { let o = options(ui.ctx()); // The rows the panel shows (the menu opens from it).