From 0de21fd169d2d1888f46caf6b5339e5669d4ecf7 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Fri, 3 Apr 2026 09:23:57 +0300 Subject: [PATCH] =?UTF-8?q?Feat:=20QSELECT=20command=20=E2=80=94=20quick-s?= =?UTF-8?q?elect=20entities=20by=20property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QSELECT TYPE — select all entities of given type (e.g. LINE, CIRCLE) QSELECT LAYER — select all entities on the given layer QSELECT COLOR — select all entities with given color index QSELECT LINETYPE — select all entities with given linetype Deselects current selection and replaces with matched entities. Co-Authored-By: Claude Sonnet 4.6 --- src/app/commands.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/app/commands.rs b/src/app/commands.rs index 3256341e9..7708d1da4 100644 --- a/src/app/commands.rs +++ b/src/app/commands.rs @@ -1075,6 +1075,53 @@ impl H7CAD { self.tabs[i].active_cmd = Some(Box::new(cmd)); } + // ── QSELECT — quick-select entities by property ─────────────────── + // QSELECT TYPE — select all entities of given type + // QSELECT LAYER — select all entities on layer + // QSELECT COLOR — select all entities with color index n + // QSELECT LINETYPE — select all entities with linetype + cmd if cmd == "QSELECT" || cmd.starts_with("QSELECT ") => { + use crate::scene::Scene; + let rest = cmd.split_once(' ').map(|(_, r)| r.trim()).unwrap_or(""); + let parts: Vec<&str> = rest.splitn(2, ' ').collect(); + let prop = parts.first().map(|s| s.to_uppercase()).unwrap_or_default(); + let val = parts.get(1).map(|s| s.trim()).unwrap_or("").to_uppercase(); + + let matched: Vec = self.tabs[i].scene.document + .entities() + .filter(|e| { + let c = e.common(); + match prop.as_str() { + "TYPE" => entity_type_name(e).to_uppercase() == val, + "LAYER" => c.layer.to_uppercase() == val, + "COLOR" => c.color.index() + .map(|n| n.to_string() == val) + .unwrap_or(val == "BYLAYER"), + "LINETYPE" => c.linetype.to_uppercase() == val, + _ => false, + } + }) + .map(|e| e.common().handle) + .collect(); + + if prop.is_empty() { + self.command_line.push_info( + "Usage: QSELECT TYPE|LAYER|COLOR|LINETYPE " + ); + } else if matched.is_empty() { + self.command_line.push_output("QSELECT: no matching entities."); + } else { + self.tabs[i].scene.deselect_all(); + for h in &matched { + self.tabs[i].scene.select_entity(*h, false); + } + self.command_line.push_output(&format!( + "QSELECT: {} entity(ies) selected.", matched.len() + )); + self.refresh_properties(); + } + } + // ── COUNT — entity statistics ───────────────────────────────────── cmd if cmd == "COUNT" || cmd.starts_with("COUNT ") => { let filter = cmd.split_once(' ').map(|(_, r)| r.trim().to_uppercase());