fix(clipboard): share COPY across drawings

This commit is contained in:
Hakan Seven committed 2026-08-29 23:12:26 +03:00
1 parent 217f20d8bc
commit 7a523a0f44
5 files changed
+67 -36

No files matched your search

+30
View File
@@ -1216,6 +1216,36 @@ impl OpenCADStudio {
self.commit_undo_delta(i, pd);
}
}
CmdResult::CopyToClipboard { handles, base } => {
let count = self.copy_entities_to_clipboard(i, &handles, base);
self.command_line.push_info(crate::tf!(
"{} object(s) copied to clipboard.",
count
).as_ref());
let prompt = self.tabs[i]
.active_cmd
.as_ref()
.map(|command| command.prompt());
if let Some(prompt) = prompt {
self.command_line.push_info(&prompt);
}
self.command_line.set_step_options(
self.tabs[i]
.active_cmd
.as_ref()
.map(|command| command.options())
.unwrap_or_default(),
);
if !self.tabs[i]
.active_cmd
.as_ref()
.is_some_and(|command| command.entity_pick_highlights_hover())
{
self.tabs[i].scene.set_hover_highlight(None);
}
self.sync_dyn_fields();
self.refresh_area_preview(i);
}
CmdResult::CommitAndExit(entity) => {
// For XATTACH: ensure the xref block definition exists before
// committing the INSERT entity that references it.
+30 -34
View File
@@ -1,6 +1,28 @@
use super::*;
impl OpenCADStudio {
pub(in crate::app) fn copy_entities_to_clipboard(
&mut self,
i: usize,
handles: &[acadrust::Handle],
base: glam::DVec3,
) -> usize {
let (entities, deps) = {
let document = &self.tabs[i].scene.document;
let entities: Vec<_> = handles
.iter()
.filter_map(|&handle| document.get_entity(handle).cloned())
.collect();
let deps = super::super::ClipboardDeps::capture(document, &entities);
(entities, deps)
};
let count = entities.len();
self.clipboard_base = base;
self.clipboard = entities;
self.clipboard_deps = deps;
count
}
pub(super) fn dispatch_blocks(&mut self, cmd: &str, i: usize) -> Option<Task<Message>> {
match cmd {
// ── BASE — drawing insertion base point ───────────────────────
@@ -79,22 +101,14 @@ impl OpenCADStudio {
self.command_line.push_info(&cmd.prompt());
self.tabs[i].active_cmd = Some(Box::new(cmd));
} else {
let entities: Vec<_> = handles
.iter()
.filter_map(|&h| self.tabs[i].scene.document.get_entity(h).cloned())
.collect();
self.clipboard_base = super::super::helpers::entities_lower_left_by_bbox(
let base = super::super::helpers::entities_lower_left_by_bbox(
&self.tabs[i].scene.document,
&handles,
);
self.clipboard = entities;
self.clipboard_deps = super::super::ClipboardDeps::capture(
&self.tabs[i].scene.document,
&self.clipboard,
);
let count = self.copy_entities_to_clipboard(i, &handles, base);
self.command_line.push_info(crate::tf!(
"{} object(s) copied to clipboard.",
self.clipboard.len()
count
).as_ref());
}
}
@@ -136,19 +150,10 @@ impl OpenCADStudio {
.collect();
if coords.len() == 3 && !handles.is_empty() {
let base = glam::DVec3::new(coords[0], coords[1], coords[2]);
let entities: Vec<_> = handles
.iter()
.filter_map(|&h| self.tabs[i].scene.document.get_entity(h).cloned())
.collect();
self.clipboard_base = base;
self.clipboard = entities;
self.clipboard_deps = super::super::ClipboardDeps::capture(
&self.tabs[i].scene.document,
&self.clipboard,
);
let count = self.copy_entities_to_clipboard(i, &handles, base);
self.command_line.push_info(crate::tf!(
"{} object(s) copied to clipboard (base {:.3},{:.3}).",
self.clipboard.len(),
count,
base.x,
base.y
).as_ref());
@@ -169,20 +174,11 @@ impl OpenCADStudio {
self.command_line.push_info(&cmd.prompt());
self.tabs[i].active_cmd = Some(Box::new(cmd));
} else {
let entities: Vec<_> = handles
.iter()
.filter_map(|&h| self.tabs[i].scene.document.get_entity(h).cloned())
.collect();
self.clipboard_base = super::super::helpers::entities_lower_left_by_bbox(
let base = super::super::helpers::entities_lower_left_by_bbox(
&self.tabs[i].scene.document,
&handles,
);
let count = entities.len();
self.clipboard = entities;
self.clipboard_deps = super::super::ClipboardDeps::capture(
&self.tabs[i].scene.document,
&self.clipboard,
);
let count = self.copy_entities_to_clipboard(i, &handles, base);
self.push_undo_snapshot(i, "CUTCLIP");
self.tabs[i].scene.erase_entities(&handles);
self.tabs[i].scene.deselect_all();
@@ -193,7 +189,7 @@ impl OpenCADStudio {
}
}
"PASTECLIP" => {
"PASTE" | "PASTECLIP" => {
if self.clipboard.is_empty() {
return Some(self.read_system_clipboard_for_paste());
} else {
+2
View File
@@ -1299,6 +1299,8 @@ pub enum CmdResult {
TransformSelected(Vec<Handle>, EntityTransform),
/// Copy selected entities with a transform; command stays active for more copies.
CopySelected(Vec<Handle>, EntityTransform),
/// Store selected entities in the shared clipboard; command stays active.
CopyToClipboard { handles: Vec<Handle>, base: DVec3 },
/// Commit a hatch fill (stored in Scene::hatches, not the DXF document).
CommitHatch(HatchModel),
/// Commit a hatch with the selected hatch's entity colour and transparency.
+1 -1
View File
@@ -132,6 +132,6 @@ impl CadCommand for PasteCommand {
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["PASTECLIP"] }); // PasteCommand
inventory::submit!(crate::command::CommandRegistration { names: &["PASTE", "PASTECLIP"] }); // PasteCommand
inventory::submit!(crate::command::CommandRegistration { names: &["PASTEORIG"] });
inventory::submit!(crate::command::CommandRegistration { names: &["PASTEBLOCK"] });
+4 -1
View File
@@ -92,7 +92,10 @@ impl CadCommand for CopyCommand {
match &self.step {
Step::Base => {
self.step = Step::Placing(pt);
CmdResult::NeedPoint
CmdResult::CopyToClipboard {
handles: self.handles.clone(),
base: pt,
}
}
Step::Placing(base) => {
let delta = pt - *base;