feat(attedit): attribute editor dialog for blocks
Double-clicking a block reference that has attributes, or running ATTEDIT on one, now opens an editor dialog listing every attribute (tag + editable value) with OK / Cancel. OK writes the values back to the block, with undo and a repaint; Cancel discards. A block with no attributes still enters in-place block edit (REFEDIT) on double-click as before. (#192) ATTEDIT opens the dialog directly when a suitable block is already selected; otherwise it runs the pick command and the dialog opens once a block is chosen. This replaces the earlier command-line, per-attribute prompt flow, which is removed along with its __ATTEDIT__ sentinel path and the now-unused attedit_set_attrs trait hook; the ATTEDIT command is reduced to a plain block picker. The dialog is a tab-scoped in-canvas modal (Plan B): its working copy holds a document-local handle, so closing that tab or switching away dismisses the editor rather than risk applying edits to another tab's document. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
5f2e920b75
commit
86a59d6c7e
12 changed files with 346 additions and 192 deletions
|
|
@ -172,35 +172,17 @@ impl OpenCADStudio {
|
|||
let i = self.active_tab;
|
||||
match result {
|
||||
CmdResult::NeedPoint => {
|
||||
// If ATTEDIT just completed entity pick, inject attribute data.
|
||||
// ATTEDIT finished its entity pick: hand the chosen block off to
|
||||
// the attribute editor dialog and end the command (open_attribute
|
||||
// _editor reports "no attributes" / "select a block" as needed).
|
||||
let attedit_handle = self.tabs[i]
|
||||
.active_cmd
|
||||
.as_ref()
|
||||
.and_then(|c| c.attedit_pending_handle());
|
||||
if let Some(ins_handle) = attedit_handle {
|
||||
if let Some(acadrust::EntityType::Insert(ins)) =
|
||||
self.tabs[i].scene.document.get_entity(ins_handle)
|
||||
{
|
||||
let attrs: Vec<(String, String)> = ins
|
||||
.attributes
|
||||
.iter()
|
||||
.map(|a| (a.tag.clone(), a.get_value().to_string()))
|
||||
.collect();
|
||||
if attrs.is_empty() {
|
||||
self.command_line
|
||||
.push_error("ATTEDIT This INSERT has no attributes.");
|
||||
self.tabs[i].active_cmd = None;
|
||||
return Task::none();
|
||||
}
|
||||
if let Some(cmd) = &mut self.tabs[i].active_cmd {
|
||||
cmd.attedit_set_attrs(attrs);
|
||||
}
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("ATTEDIT Please select an INSERT entity with attributes.");
|
||||
self.tabs[i].active_cmd = None;
|
||||
return Task::none();
|
||||
}
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.open_attribute_editor(ins_handle);
|
||||
return Task::none();
|
||||
}
|
||||
let prompt = self.tabs[i].active_cmd.as_ref().map(|c| c.prompt());
|
||||
if let Some(p) = prompt {
|
||||
|
|
@ -458,28 +440,6 @@ impl OpenCADStudio {
|
|||
self.refresh_properties();
|
||||
}
|
||||
CmdResult::ReplaceEntity(handle, new_entities) => {
|
||||
// Detect ATTEDIT sentinel.
|
||||
if new_entities.len() == 1 {
|
||||
if let acadrust::EntityType::XLine(ref xl) = new_entities[0] {
|
||||
let layer = xl.common.layer.clone();
|
||||
if let Some(encoded) = layer.strip_prefix("__ATTEDIT__") {
|
||||
let label = self.history_label_from_active_cmd(i, "ATTEDIT");
|
||||
self.push_undo_snapshot(i, label);
|
||||
crate::modules::draw::modify::attedit::apply_attedit(
|
||||
&mut self.tabs[i].scene.document,
|
||||
handle,
|
||||
encoded,
|
||||
);
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
self.command_line
|
||||
.push_output("ATTEDIT Attribute values updated.");
|
||||
return Task::none();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Detect SPLINEDIT sentinel: a single XLine with a magic layer name.
|
||||
if new_entities.len() == 1 {
|
||||
if let acadrust::EntityType::XLine(ref xl) = new_entities[0] {
|
||||
|
|
|
|||
Loading…
Reference in a new issue