forked from 1b-agent/opencadstudio-upstream
ATTACH: FILEDIA, -ATTACH command line and reference file types
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
b1d4c9bd9b
commit
0678c579c0
33 files changed
+519
-47
No files matched your search
@@ -147,6 +147,9 @@ pub struct XAttachCommand {
|
||||
|
||||
const NONZERO: &str = "Value must be nonzero.";
|
||||
|
||||
/// Raster image files ATTACH places as images.
|
||||
pub const IMAGE_EXTENSIONS: &[&str] = &["bmp", "gif", "jpg", "jpeg", "png", "tif", "tiff", "webp"];
|
||||
|
||||
impl XAttachCommand {
|
||||
pub fn new(request: XrefAttachRequest, placement: XrefPlacement, label: &'static str) -> Self {
|
||||
let block_name = path_to_block_name(&request.path);
|
||||
|
||||
@@ -36,6 +36,14 @@ impl XrefCommand {
|
||||
}
|
||||
}
|
||||
|
||||
/// -XREF already at its Attach file prompt (XATTACH while FILEDIA is 0).
|
||||
pub fn attach(saved_paths: Vec<(String, String)>) -> Self {
|
||||
Self {
|
||||
step: Step::File { overlay: false },
|
||||
saved_paths,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether any reference name matches `pattern` (`*` / `?` wildcards).
|
||||
fn matches(&self, pattern: &str) -> bool {
|
||||
self.saved_paths
|
||||
@@ -197,6 +205,106 @@ impl CadCommand for XrefCommand {
|
||||
}
|
||||
}
|
||||
|
||||
/// -ATTACH (and ATTACH while FILEDIA is 0): the file on the command line,
|
||||
/// then the attach flow of its file type.
|
||||
pub struct AttachCommand {
|
||||
/// The drawing whose reference type is asked; `None` while asking for the file.
|
||||
drawing: Option<String>,
|
||||
}
|
||||
|
||||
impl AttachCommand {
|
||||
pub fn new() -> Self {
|
||||
Self { drawing: None }
|
||||
}
|
||||
|
||||
fn reference(path: &str, overlay: bool) -> CmdResult {
|
||||
let verb = if overlay {
|
||||
"XREFOVERLAYFILE"
|
||||
} else {
|
||||
"XREFATTACHFILE"
|
||||
};
|
||||
CmdResult::Dispatch(format!("{verb} {path}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl CadCommand for AttachCommand {
|
||||
fn name(&self) -> &'static str {
|
||||
"-ATTACH"
|
||||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
match self.drawing {
|
||||
None => "-ATTACH Path to file to attach:".to_string(),
|
||||
Some(_) => {
|
||||
"-ATTACH Specify reference type [Attachment/Overlay] <Attachment>:".to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn options(&self) -> Vec<CmdOption> {
|
||||
match self.drawing {
|
||||
None => Vec::new(),
|
||||
Some(_) => vec![
|
||||
CmdOption::new("Attachment", "A"),
|
||||
CmdOption::new("Overlay", "O"),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
fn input_kind(&self) -> InputKind {
|
||||
match self.drawing {
|
||||
None => InputKind::FreeText,
|
||||
Some(_) => InputKind::SingleToken,
|
||||
}
|
||||
}
|
||||
|
||||
fn on_point(&mut self, _pt: DVec3) -> CmdResult {
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
|
||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||
let value = text.trim().trim_matches('"');
|
||||
if let Some(path) = self.drawing.clone() {
|
||||
return Some(match value.to_uppercase().as_str() {
|
||||
"A" | "ATTACHMENT" => Self::reference(&path, false),
|
||||
"O" | "OVERLAY" => Self::reference(&path, true),
|
||||
_ => CmdResult::ReportError("Invalid option keyword.".to_string()),
|
||||
});
|
||||
}
|
||||
if value.is_empty() {
|
||||
return Some(self.on_enter());
|
||||
}
|
||||
if !std::path::Path::new(value).is_file() {
|
||||
return Some(CmdResult::ReportError(format!("{value} not found.")));
|
||||
}
|
||||
let ext = std::path::Path::new(value)
|
||||
.extension()
|
||||
.map(|e| e.to_string_lossy().to_ascii_lowercase())
|
||||
.unwrap_or_default();
|
||||
Some(match ext.as_str() {
|
||||
"pdf" => CmdResult::Dispatch(format!("-PDFATTACH {value}")),
|
||||
"dwf" | "dwfx" => CmdResult::Dispatch(format!("-DWFATTACH {value}")),
|
||||
"dgn" => CmdResult::Dispatch(format!("-DGNATTACH {value}")),
|
||||
"rcp" | "rcs" => CmdResult::Dispatch(format!("-POINTCLOUDATTACH {value}")),
|
||||
// Images have no dialog after the file: ATTACH places them.
|
||||
e if crate::modules::insert::xattach::IMAGE_EXTENSIONS.contains(&e) => {
|
||||
CmdResult::Dispatch(format!("ATTACH {value}"))
|
||||
}
|
||||
_ => {
|
||||
self.drawing = Some(value.to_string());
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn on_enter(&mut self) -> CmdResult {
|
||||
match self.drawing.clone() {
|
||||
None => CmdResult::ReportError("Filename cannot be blank".to_string()),
|
||||
Some(path) => Self::reference(&path, false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A stored path shown the way the platform writes it.
|
||||
pub fn display_path(path: &str) -> String {
|
||||
if cfg!(windows) {
|
||||
|
||||
Reference in new issue
Block a user