Merge pull request #1782 from ramox81/codex/refedit-nested-messages

REFEDIT: nested pick messages, window pick and session note

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 5.5 committed 2026-10-14 23:57:08 +03:00
commit 98f0c15e3f
25 files changed
+195 -11

No files matched your search

+3
View File
@@ -6485,6 +6485,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = إضافة إلى مجموعة العمل
.remove-from-working-set = إزالة من مجموعة العمل
.toolbar-objects = كائنات
+3
View File
@@ -6473,6 +6473,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Добави към работния набор
.remove-from-working-set = Премахни от работния набор
.toolbar-objects = обекта
+3
View File
@@ -6470,6 +6470,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Přidat do pracovní sady
.remove-from-working-set = Odebrat z pracovní sady
.toolbar-objects = objektů
+3
View File
@@ -6471,6 +6471,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Zum Arbeitssatz hinzufügen
.remove-from-working-set = Aus dem Arbeitssatz entfernen
.toolbar-objects = Objekte
+3
View File
@@ -6473,6 +6473,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Προσθήκη στο σύνολο εργασίας
.remove-from-working-set = Αφαίρεση από το σύνολο εργασίας
.toolbar-objects = αντικείμενα
+3
View File
@@ -6472,6 +6472,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Add to Working Set
.remove-from-working-set = Remove from Working Set
.toolbar-objects = objects
+3
View File
@@ -6473,6 +6473,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Añadir al conjunto de trabajo
.remove-from-working-set = Eliminar del conjunto de trabajo
.toolbar-objects = objetos
+3
View File
@@ -6470,6 +6470,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Lisää työjoukkoon
.remove-from-working-set = Poista työjoukosta
.toolbar-objects = objektia
+3
View File
@@ -6473,6 +6473,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Ajouter au jeu de travail
.remove-from-working-set = Supprimer du jeu de travail
.toolbar-objects = objets
+3
View File
@@ -6461,6 +6461,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = कार्य सेट में जोड़ें
.remove-from-working-set = कार्य सेट से हटाएँ
.toolbar-objects = ऑब्जेक्ट
+3
View File
@@ -6457,6 +6457,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Hozzáadás a munkakészlethez
.remove-from-working-set = Eltávolítás a munkakészletből
.toolbar-objects = objektum
+3
View File
@@ -6472,6 +6472,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Aggiungi al gruppo di lavoro
.remove-from-working-set = Rimuovi dal gruppo di lavoro
.toolbar-objects = oggetti
+3
View File
@@ -6461,6 +6461,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = 作業セットに追加
.remove-from-working-set = 作業セットから除去
.toolbar-objects = 個のオブジェクト
+3
View File
@@ -6472,6 +6472,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = 작업 세트에 추가
.remove-from-working-set = 작업 세트에서 제거
.toolbar-objects = 개 객체
+3
View File
@@ -6473,6 +6473,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = ເພີ່ມໃສ່ຊຸດເຮັດວຽກ
.remove-from-working-set = ລຶບອອກຈາກຊຸດເຮັດວຽກ
.toolbar-objects = ວັດຖຸ
+3
View File
@@ -6471,6 +6471,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Toevoegen aan werkset
.remove-from-working-set = Verwijderen uit werkset
.toolbar-objects = objecten
+3
View File
@@ -6472,6 +6472,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Dodaj do zbioru roboczego
.remove-from-working-set = Usuń ze zbioru roboczego
.toolbar-objects = obiekty
+3
View File
@@ -6473,6 +6473,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Adicionar ao conjunto de trabalho
.remove-from-working-set = Remover do conjunto de trabalho
.toolbar-objects = objetos
+3
View File
@@ -6474,6 +6474,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = Добавить в рабочий набор
.remove-from-working-set = Удалить из рабочего набора
.toolbar-objects = объектов
+3
View File
@@ -6394,6 +6394,9 @@ view-background =
.select-image = Arka Plan Görüntüsü Seç
ref-edit =
.entities-added = __ocs_fmt_0__ nesne eklendi
.use-refclose = Referans düzenleme oturumunu bitirmek için REFCLOSE komutunu veya referans düzenleme araç çubuğunu kullanın.
.opposite-corner = Karşı köşeyi belirtin:
.add-to-working-set = Çalışma Kümesine Ekle
.remove-from-working-set = Çalışma Kümesinden Çıkar
.toolbar-objects = nesne
+3
View File
@@ -6456,6 +6456,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = 添加到工作集
.remove-from-working-set = 从工作集删除
.toolbar-objects = 个对象
+3
View File
@@ -6468,6 +6468,9 @@ view-background =
.select-image = Select Background Image
ref-edit =
.entities-added = __ocs_fmt_0__ entities added
.use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session.
.opposite-corner = Specify opposite corner:
.add-to-working-set = 加入工作集
.remove-from-working-set = 從工作集移除
.toolbar-objects = 個物件
+16 -1
View File
@@ -256,7 +256,7 @@ impl OpenCADStudio {
.map(|l| l.insert.value().to_string())
.collect();
return self.dispatch_command(&format!(
"REFEDIT_BEGIN:{}:{}:{}::{}:{}",
"REFEDIT_BEGIN:{}:{}:{}::{}:{}:1",
state.top.value(),
path.join(","),
attributes as u8,
@@ -293,6 +293,8 @@ impl OpenCADStudio {
let unique = parts
.next()
.map_or(self.refedit_options.unique_names, |v| v == "1");
// Opened from the Reference Edit dialog (REFEDIT, not -REFEDIT).
let from_dialog = parts.next() == Some("1");
if self.tabs[i].refedit_session.is_some() || self.reject_locked_edit(i, top) {
return;
}
@@ -396,6 +398,19 @@ impl OpenCADStudio {
self.tabs[i].scene.refedit_lock = lock;
self.tabs[i].scene.deselect_all();
self.tabs[i].dirty = true;
if from_dialog {
match nested.len() {
0 => {}
1 => self.command_line.push_output(crate::t!("1 item selected").as_ref()),
n => self
.command_line
.push_output(crate::tf!("{} items selected", n).as_ref()),
}
self.command_line.push_output(
crate::t!("Use REFCLOSE or the Refedit toolbar to end reference editing session.")
.as_ref(),
);
}
// No active command — the definition's objects are edited freely
// (move, grips, draw, erase…) until REFCLOSE.
self.tabs[i].active_cmd = None;
+3
View File
@@ -3,6 +3,9 @@
pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static str)> {
match source {
"{} entities added" => Some(("ref-edit", "entities-added")),
"Use REFCLOSE or the Refedit toolbar to end reference editing session." => Some(("ref-edit", "use-refclose")),
"Specify opposite corner:" => Some(("ref-edit", "opposite-corner")),
"Add to Working Set" => Some(("ref-edit", "add-to-working-set")),
"Remove from Working Set" => Some(("ref-edit", "remove-from-working-set")),
"Select reference:" => Some(("ref-edit", "select-reference")),
+110 -10
View File
@@ -414,6 +414,8 @@ pub struct RefEditOptionsCommand {
/// Set when the Edit Reference dialog already chose the attribute
/// option: the nested pick then opens the session directly.
attributes: Option<bool>,
/// First corner of a window started by a pick on empty space.
corner: Option<DVec3>,
}
impl RefEditOptionsCommand {
@@ -435,6 +437,7 @@ impl RefEditOptionsCommand {
lock,
unique,
attributes: None,
corner: None,
}
}
@@ -464,34 +467,81 @@ impl RefEditOptionsCommand {
let nested: Vec<String> = self.nested.iter().map(|h| h.value().to_string()).collect();
CmdResult::Relaunch(
format!(
"REFEDIT_BEGIN:{}:{}:{}:{}:{}:{}",
"REFEDIT_BEGIN:{}:{}:{}:{}:{}:{}:{}",
self.top.value(),
path.join(","),
attributes as u8,
nested.join(","),
self.lock as u8,
self.unique as u8
self.unique as u8,
self.attributes.is_some() as u8
),
vec![],
)
}
fn pick_nested(&mut self, point: DVec3) -> CmdResult {
/// A pick at `point`: the nearest object of the level within `tolerance`
/// (any distance when None), else the first corner of a window.
fn pick_nested(&mut self, point: DVec3, tolerance: Option<f64>) -> CmdResult {
if let Some(first) = self.corner.take() {
return self.window_nested(first, point);
}
let nearest = self
.hits
.get(self.level)
.into_iter()
.flatten()
.filter_map(|(h, paths)| paths_distance(paths, point).map(|d| (*h, d)))
.filter(|(_, d)| tolerance.is_none_or(|t| *d <= t))
.min_by(|a, b| a.1.total_cmp(&b.1));
match nearest {
Some((h, _)) if !self.nested.contains(&h) => {
self.nested.push(h);
CmdResult::ReportMeasurement(t!("1 entity added").into_owned())
Some((h, _)) => {
let added = !self.nested.contains(&h);
if added {
self.nested.push(h);
}
CmdResult::ReportMeasurement(entities_added(added as usize))
}
None => {
self.corner = Some(point);
CmdResult::NeedPoint
}
_ => CmdResult::NeedPoint,
}
}
/// The level's objects in the window from `first` to `second`: wholly
/// inside when it was dragged to the right, touching it when to the left.
fn window_nested(&mut self, first: DVec3, second: DVec3) -> CmdResult {
let (lo, hi) = (first.min(second), first.max(second));
let crossing = second.x < first.x;
let inside = |p: &[f64; 3]| p[0] >= lo.x && p[0] <= hi.x && p[1] >= lo.y && p[1] <= hi.y;
let picked: Vec<Handle> = self
.hits
.get(self.level)
.into_iter()
.flatten()
.filter(|(_, paths)| {
let points = || paths.iter().flatten();
if crossing {
points().any(inside)
|| paths.iter().any(|path| {
path.windows(2).any(|s| segment_meets_box(s[0], s[1], lo, hi))
})
} else {
points().next().is_some() && points().all(inside)
}
})
.map(|(h, _)| *h)
.collect();
let mut added = 0;
for h in picked {
if !self.nested.contains(&h) {
self.nested.push(h);
added += 1;
}
}
CmdResult::ReportMeasurement(entities_added(added))
}
}
impl CadCommand for RefEditOptionsCommand {
@@ -504,6 +554,9 @@ impl CadCommand for RefEditOptionsCommand {
OptionStep::Method => {
t!("Enter object selection method [All/Nested] <All>:").into_owned()
}
OptionStep::Nested if self.corner.is_some() => {
t!("Specify opposite corner:").into_owned()
}
OptionStep::Nested => t!("Select nested objects:").into_owned(),
OptionStep::Attributes => {
t!("Display attribute definitions [Yes/No] <No>:").into_owned()
@@ -526,8 +579,13 @@ impl CadCommand for RefEditOptionsCommand {
fn needs_entity_pick(&self) -> bool {
matches!(self.step, OptionStep::Nested)
}
fn on_entity_pick(&mut self, _handle: Handle, pt: DVec3) -> CmdResult {
self.pick_nested(pt)
fn on_entity_pick(&mut self, handle: Handle, pt: DVec3) -> CmdResult {
// A click on empty space starts a window, as does one beside the
// reference's objects.
if handle.is_null() {
return self.pick_nested(pt, Some(0.0));
}
self.pick_nested(pt, None)
}
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
let word = text.trim().to_ascii_uppercase();
@@ -554,7 +612,8 @@ impl CadCommand for RefEditOptionsCommand {
}
fn on_point(&mut self, pt: DVec3) -> CmdResult {
match self.step {
OptionStep::Nested => self.pick_nested(pt),
// A typed point picks the object it lies on.
OptionStep::Nested => self.pick_nested(pt, Some(1e-6 * pt.length().max(1.0))),
_ => CmdResult::NeedPoint,
}
}
@@ -573,12 +632,14 @@ impl CadCommand for RefEditOptionsCommand {
self.step = OptionStep::Attributes;
CmdResult::NeedPoint
}
OptionStep::Nested if self.corner.take().is_some() => CmdResult::NeedPoint,
OptionStep::Nested => {
let n = self.nested.len();
if n == 0 {
return CmdResult::CancelWithMessage(t!("0 items selected").into_owned());
}
if let Some(attributes) = self.attributes {
// The count and the session's note follow as it opens.
return self.begin(attributes);
}
self.step = OptionStep::Attributes;
@@ -593,6 +654,45 @@ impl CadCommand for RefEditOptionsCommand {
}
}
/// `N entity added` / `N entities added`.
fn entities_added(n: usize) -> String {
if n == 1 {
t!("1 entity added").into_owned()
} else {
crate::tf!("{} entities added", n).into_owned()
}
}
/// Whether the segment from `a` to `b` crosses the box `lo`..`hi` (XY).
fn segment_meets_box(a: [f64; 3], b: [f64; 3], lo: DVec3, hi: DVec3) -> bool {
// Liang–Barsky clip of the segment against the box.
let (mut t0, mut t1) = (0.0f64, 1.0f64);
let d = [b[0] - a[0], b[1] - a[1]];
for (p, q) in [
(-d[0], a[0] - lo.x),
(d[0], hi.x - a[0]),
(-d[1], a[1] - lo.y),
(d[1], hi.y - a[1]),
] {
if p == 0.0 {
if q < 0.0 {
return false;
}
} else {
let r = q / p;
if p < 0.0 {
t0 = t0.max(r);
} else {
t1 = t1.min(r);
}
if t0 > t1 {
return false;
}
}
}
true
}
// ── REFSET ────────────────────────────────────────────────────────────────
/// `Enter an option [Add/Remove] <Add>:` then `Select objects:`.