feat(locale): localize full interface
This commit is contained in:
parent
b90b3e3ecf
commit
3e6693b93f
205 changed files with 32367 additions and 3808 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -172,7 +172,7 @@ impl OpenCADStudio {
|
|||
tasks.push(self.apply_cmd_result(CmdResult::CancelForSpaceChange));
|
||||
} else if message_pending {
|
||||
self.command_line
|
||||
.push_info("Command cancelled because the active drawing space changed.");
|
||||
.push_info(crate::t!("Command cancelled because the active drawing space changed.").as_ref());
|
||||
}
|
||||
cancellation_reported = true;
|
||||
}
|
||||
|
|
@ -186,7 +186,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
if !cancellation_reported && (grip_cancelled || suspended_cancelled || editor_cancelled) {
|
||||
self.command_line
|
||||
.push_info("Command cancelled because the active drawing space changed.");
|
||||
.push_info(crate::t!("Command cancelled because the active drawing space changed.").as_ref());
|
||||
}
|
||||
|
||||
self.command_line.input.clear();
|
||||
|
|
@ -210,7 +210,7 @@ impl OpenCADStudio {
|
|||
.is_some_and(|command| command.name() != "LIMITS")
|
||||
&& self.tabs[i].scene.drawing_limit_check_enabled();
|
||||
if checks_limits && !self.tabs[i].scene.point_inside_drawing_limits(point) {
|
||||
self.command_line.push_error("Outside limits.");
|
||||
self.command_line.push_error(crate::t!("Outside limits.").as_ref());
|
||||
return false;
|
||||
}
|
||||
true
|
||||
|
|
@ -389,7 +389,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.select_entity(h, false);
|
||||
}
|
||||
self.command_line
|
||||
.push_info(&format!("{count} object(s) added to selection."));
|
||||
.push_info(crate::tf!("{count} object(s) added to selection.").as_ref());
|
||||
self.refresh_properties();
|
||||
let handles: Vec<Handle> = self.tabs[i]
|
||||
.scene
|
||||
|
|
@ -754,7 +754,7 @@ impl OpenCADStudio {
|
|||
});
|
||||
let Some((min_x, min_y, max_x, max_y)) = bounds else {
|
||||
self.command_line
|
||||
.push_error("MVIEW: the clipping boundary has no usable area.");
|
||||
.push_error(crate::t!("MVIEW: the clipping boundary has no usable area.").as_ref());
|
||||
self.tabs[i].active_cmd = None;
|
||||
if let Some(pending) = pending {
|
||||
self.commit_undo_delta(i, pending);
|
||||
|
|
@ -763,7 +763,7 @@ impl OpenCADStudio {
|
|||
};
|
||||
if max_x - min_x < 1e-6 || max_y - min_y < 1e-6 {
|
||||
self.command_line
|
||||
.push_error("MVIEW: the clipping boundary has no usable area.");
|
||||
.push_error(crate::t!("MVIEW: the clipping boundary has no usable area.").as_ref());
|
||||
self.tabs[i].active_cmd = None;
|
||||
if let Some(pending) = pending {
|
||||
self.commit_undo_delta(i, pending);
|
||||
|
|
@ -1051,7 +1051,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
self.command_line
|
||||
.push_output(&format!("Block \"{name}\" created."));
|
||||
.push_output(crate::tf!("Block \"{name}\" created.").as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
Err(err) => {
|
||||
|
|
@ -1098,7 +1098,7 @@ impl OpenCADStudio {
|
|||
self.restore_pre_cmd_tangent();
|
||||
let noun = if count == 1 { "copy" } else { "copies" };
|
||||
self.command_line
|
||||
.push_output(&format!("{label}: {count} {noun} created."));
|
||||
.push_output(crate::tf!("{label}: {count} {noun} created.").as_ref());
|
||||
self.refresh_properties();
|
||||
if let Some(pd) = pending {
|
||||
self.commit_undo_delta(i, pd);
|
||||
|
|
@ -1133,7 +1133,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].snap_result = None;
|
||||
if was_catchment {
|
||||
self.command_line
|
||||
.push_info("Catchment tagged successfully.");
|
||||
.push_info(crate::t!("Catchment tagged successfully.").as_ref());
|
||||
}
|
||||
self.refresh_properties();
|
||||
}
|
||||
|
|
@ -1171,7 +1171,7 @@ impl OpenCADStudio {
|
|||
// Report honestly rather than claiming success while
|
||||
// changing nothing. (#181 / DIM-020)
|
||||
self.command_line
|
||||
.push_info("DIMBREAK: not yet implemented — nothing changed.");
|
||||
.push_info(crate::t!("DIMBREAK: not yet implemented — nothing changed.").as_ref());
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
return Task::none();
|
||||
|
|
@ -1181,7 +1181,7 @@ impl OpenCADStudio {
|
|||
apply_dimspace(&mut self.tabs[i].scene, encoded);
|
||||
}
|
||||
self.push_undo_snapshot(i, "DIMSPACE");
|
||||
self.command_line.push_output("DIMSPACE Spacing adjusted.");
|
||||
self.command_line.push_output(crate::t!("DIMSPACE Spacing adjusted.").as_ref());
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
|
@ -1192,7 +1192,7 @@ impl OpenCADStudio {
|
|||
// model (not yet present) to store and render the jog.
|
||||
// Report honestly rather than faking success. (DIM-019)
|
||||
self.command_line
|
||||
.push_info("DIMJOGLINE: not yet implemented — nothing changed.");
|
||||
.push_info(crate::t!("DIMJOGLINE: not yet implemented — nothing changed.").as_ref());
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
return Task::none();
|
||||
|
|
@ -1203,7 +1203,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.push_undo_snapshot(i, "MLEADERALIGN");
|
||||
self.command_line
|
||||
.push_output("MLEADERALIGN Leaders aligned.");
|
||||
.push_output(crate::t!("MLEADERALIGN Leaders aligned.").as_ref());
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
|
@ -1215,7 +1215,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.push_undo_snapshot(i, "MLEADERCOLLECT");
|
||||
self.command_line
|
||||
.push_output("MLEADERCOLLECT Leaders collected.");
|
||||
.push_output(crate::t!("MLEADERCOLLECT Leaders collected.").as_ref());
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
|
@ -1461,10 +1461,10 @@ impl OpenCADStudio {
|
|||
self.invalidate_property_targets(i, &dest);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_info(&format!("Layer matched to \"{layer}\"."));
|
||||
.push_info(crate::tf!("Layer matched to \"{layer}\".").as_ref());
|
||||
self.sync_ribbon_layers();
|
||||
} else {
|
||||
self.command_line.push_error("Source object not found.");
|
||||
self.command_line.push_error(crate::t!("Source object not found.").as_ref());
|
||||
}
|
||||
}
|
||||
CmdResult::MatchProperties { dest, src } => {
|
||||
|
|
@ -1605,14 +1605,14 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_info(&format!("Properties matched to {} object(s).", dest.len()));
|
||||
.push_info(crate::tf!("Properties matched to {} object(s).", dest.len()).as_ref());
|
||||
// Clear the consumed target selection and keep prompting.
|
||||
self.tabs[i].scene.deselect_all();
|
||||
if let Some(cmd) = &self.tabs[i].active_cmd {
|
||||
self.command_line.push_info(&cmd.prompt());
|
||||
}
|
||||
} else {
|
||||
self.command_line.push_error("Source object not found.");
|
||||
self.command_line.push_error(crate::t!("Source object not found.").as_ref());
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
self.tabs[i].scene.clear_preview_wire();
|
||||
|
|
@ -1623,7 +1623,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].snap_result = None;
|
||||
self.tabs[i].scene.clear_preview_wire();
|
||||
if self.clipboard.is_empty() {
|
||||
self.command_line.push_error("Clipboard is empty.");
|
||||
self.command_line.push_error(crate::t!("Clipboard is empty.").as_ref());
|
||||
} else {
|
||||
let delta = base_pt - self.clipboard_base;
|
||||
let translate = crate::command::EntityTransform::Translate(delta);
|
||||
|
|
@ -1640,7 +1640,7 @@ impl OpenCADStudio {
|
|||
self.refresh_layer_panel();
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_info(&format!("{count} object(s) pasted."));
|
||||
.push_info(crate::tf!("{count} object(s) pasted.").as_ref());
|
||||
}
|
||||
}
|
||||
CmdResult::CreateGroup { handles, name } => {
|
||||
|
|
@ -1652,7 +1652,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.commit_group_undo(i, undo);
|
||||
self.command_line
|
||||
.push_info(&format!("Group \"{}\" created.", name));
|
||||
.push_info(crate::tf!("Group \"{}\" created.", name).as_ref());
|
||||
}
|
||||
CmdResult::DeleteGroups { handles } => {
|
||||
self.tabs[i].active_cmd = None;
|
||||
|
|
@ -1664,10 +1664,10 @@ impl OpenCADStudio {
|
|||
self.commit_group_undo(i, undo);
|
||||
if count > 0 {
|
||||
self.command_line
|
||||
.push_info(&format!("{} group(s) dissolved.", count));
|
||||
.push_info(crate::tf!("{} group(s) dissolved.", count).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_info("No groups found for selected objects.");
|
||||
.push_info(crate::t!("No groups found for selected objects.").as_ref());
|
||||
}
|
||||
}
|
||||
CmdResult::VpLayerUpdate {
|
||||
|
|
@ -1747,14 +1747,14 @@ impl OpenCADStudio {
|
|||
self.push_undo_snapshot(i, "VPLAYER");
|
||||
self.tabs[i].dirty = true;
|
||||
if frozen_count > 0 {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"VPLAYER: {frozen_count} layer(s) frozen in viewport."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
if thawed_count > 0 {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"VPLAYER: {thawed_count} layer(s) thawed in viewport."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
// Sync layer panel so VP freeze columns update immediately.
|
||||
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
||||
|
|
@ -1778,7 +1778,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i]
|
||||
.scene
|
||||
.zoom_to_window(p1.as_vec3(), p2.as_vec3());
|
||||
self.command_line.push_output("Zoom Window");
|
||||
self.command_line.push_output(crate::t!("Zoom Window").as_ref());
|
||||
}
|
||||
CmdResult::Measurement(msg) => {
|
||||
self.tabs[i].active_cmd = None;
|
||||
|
|
@ -1844,7 +1844,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
self.restore_pre_cmd_tangent();
|
||||
self.command_line.push_output("ALIGN: applied.");
|
||||
self.command_line.push_output(crate::t!("ALIGN: applied.").as_ref());
|
||||
self.refresh_properties();
|
||||
if let Some(pd) = pending {
|
||||
self.commit_undo_delta(i, pd);
|
||||
|
|
@ -1869,12 +1869,12 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.erase_entities(&[handle]);
|
||||
self.tabs[i].scene.add_entity(new_entity);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("LENGTHEN: applied.");
|
||||
self.command_line.push_output(crate::t!("LENGTHEN: applied.").as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
None => {
|
||||
self.command_line
|
||||
.push_error("LENGTHEN: entity type not supported.");
|
||||
.push_error(crate::t!("LENGTHEN: entity type not supported.").as_ref());
|
||||
}
|
||||
}
|
||||
self.tabs[i].active_cmd = None;
|
||||
|
|
@ -1898,10 +1898,10 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("DIVIDE: {count} point(s) placed."));
|
||||
.push_output(crate::tf!("DIVIDE: {count} point(s) placed.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("DIVIDE: entity type not supported or N < 2.");
|
||||
.push_error(crate::t!("DIVIDE: entity type not supported or N < 2.").as_ref());
|
||||
}
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
|
@ -1927,10 +1927,10 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("MEASURE: {count} point(s) placed."));
|
||||
.push_output(crate::tf!("MEASURE: {count} point(s) placed.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("MEASURE: entity type not supported or distance too large.");
|
||||
.push_error(crate::t!("MEASURE: entity type not supported or distance too large.").as_ref());
|
||||
}
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
|
@ -1956,7 +1956,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
None => self
|
||||
.command_line
|
||||
.push_error("PEDIT: cannot convert this entity."),
|
||||
.push_error(crate::t!("PEDIT: cannot convert this entity.").as_ref()),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
|
@ -1976,12 +1976,12 @@ impl OpenCADStudio {
|
|||
self.tabs[i]
|
||||
.scene
|
||||
.bump_entities(&[(handle, crate::scene::ChangeKind::Modified)]);
|
||||
self.command_line.push_output("PEDIT: applied.");
|
||||
self.command_line.push_output(crate::t!("PEDIT: applied.").as_ref());
|
||||
self.refresh_properties();
|
||||
} else {
|
||||
self.discard_last_undo_entry(i);
|
||||
self.command_line
|
||||
.push_error("PEDIT: operation not applicable to this entity.");
|
||||
.push_error(crate::t!("PEDIT: operation not applicable to this entity.").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2011,9 +2011,9 @@ impl OpenCADStudio {
|
|||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
self.restore_pre_cmd_tangent();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"JOIN: {count_in} object(s) joined into {count_out}."
|
||||
));
|
||||
).as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
None => {
|
||||
|
|
@ -2049,7 +2049,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].snap_result = None;
|
||||
self.restore_pre_cmd_tangent();
|
||||
self.command_line
|
||||
.push_output(&format!("BREAK: {} fragment(s).", count));
|
||||
.push_output(crate::tf!("BREAK: {} fragment(s).", count).as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
None => {
|
||||
|
|
@ -2058,7 +2058,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.clear_preview_wire();
|
||||
self.restore_pre_cmd_tangent();
|
||||
self.command_line
|
||||
.push_error("BREAK: entity type not supported.");
|
||||
.push_error(crate::t!("BREAK: entity type not supported.").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2072,7 +2072,7 @@ impl OpenCADStudio {
|
|||
let y1 = p1.y.max(p2.y);
|
||||
self.plot_window = Some((x0, y0, x1, y1));
|
||||
self.command_line
|
||||
.push_output(&format!("Plot window: {x0:.2},{y0:.2} to {x1:.2},{y1:.2}"));
|
||||
.push_output(crate::tf!("Plot window: {x0:.2},{y0:.2} to {x1:.2},{y1:.2}").as_ref());
|
||||
// Pick window closed the plot dialog so the viewport could
|
||||
// receive the two clicks — bring the dialog back with the
|
||||
// window now active.
|
||||
|
|
@ -2089,9 +2089,9 @@ impl OpenCADStudio {
|
|||
let x2 = p1.x.max(p2.x);
|
||||
let y2 = p1.y.max(p2.y);
|
||||
self.plot_window = Some((x1, y1, x2, y2));
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Plot window: {x1:.2},{y1:.2} to {x2:.2},{y2:.2}"
|
||||
));
|
||||
).as_ref());
|
||||
self.plot_dialog.area = "Window".to_string();
|
||||
self.active_modal = Some(super::ModalKind::Plot);
|
||||
}
|
||||
|
|
@ -2127,7 +2127,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_output("STRETCH: nothing crosses the window.");
|
||||
.push_output(crate::t!("STRETCH: nothing crosses the window.").as_ref());
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
self.tabs[i].scene.clear_preview_wire();
|
||||
|
|
@ -2395,7 +2395,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.clear_preview_wire();
|
||||
self.restore_pre_cmd_tangent();
|
||||
self.command_line
|
||||
.push_output(&format!("STRETCH: {count} entity(ies) stretched."));
|
||||
.push_output(crate::tf!("STRETCH: {count} entity(ies) stretched.").as_ref());
|
||||
self.refresh_properties();
|
||||
if let Some(pending) = pending {
|
||||
self.commit_undo_delta(i, pending);
|
||||
|
|
@ -2418,7 +2418,7 @@ impl OpenCADStudio {
|
|||
.insert(handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("Solid created.");
|
||||
self.command_line.push_output(crate::t!("Solid created.").as_ref());
|
||||
}
|
||||
if let Some(pd) = pending {
|
||||
self.commit_undo_delta(i, pd);
|
||||
|
|
@ -2492,15 +2492,15 @@ impl OpenCADStudio {
|
|||
// ACIS geometry (else the solid is dropped by other CAD apps).
|
||||
self.tabs[i].scene.solid_models.insert(new_handle, solid);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("EXTRUDE: solid created.");
|
||||
self.command_line.push_output(crate::t!("EXTRUDE: solid created.").as_ref());
|
||||
if let Some(pd) = pending {
|
||||
self.commit_undo_delta(i, pd);
|
||||
}
|
||||
} else {
|
||||
self.command_line.push_error("EXTRUDE: could not build profile. Select a closed 2D entity (Circle, LwPolyline, etc.).");
|
||||
self.command_line.push_error(crate::t!("EXTRUDE: could not build profile. Select a closed 2D entity (Circle, LwPolyline, etc.).").as_ref());
|
||||
}
|
||||
} else {
|
||||
self.command_line.push_error("EXTRUDE: entity not found.");
|
||||
self.command_line.push_error(crate::t!("EXTRUDE: entity not found.").as_ref());
|
||||
}
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
|
@ -2577,16 +2577,16 @@ impl OpenCADStudio {
|
|||
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("REVOLVE: solid created ({:.0}°).", angle_deg));
|
||||
.push_output(crate::tf!("REVOLVE: solid created ({:.0}°).", angle_deg).as_ref());
|
||||
if let Some(pd) = pending {
|
||||
self.commit_undo_delta(i, pd);
|
||||
}
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("REVOLVE: could not revolve profile.");
|
||||
.push_error(crate::t!("REVOLVE: could not revolve profile.").as_ref());
|
||||
}
|
||||
} else {
|
||||
self.command_line.push_error("REVOLVE: entity not found.");
|
||||
self.command_line.push_error(crate::t!("REVOLVE: entity not found.").as_ref());
|
||||
}
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
|
@ -2755,12 +2755,12 @@ impl OpenCADStudio {
|
|||
.meshes
|
||||
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("SWEEP: solid created.");
|
||||
self.command_line.push_output(crate::t!("SWEEP: solid created.").as_ref());
|
||||
if let Some(pd) = pending {
|
||||
self.commit_undo_delta(i, pd);
|
||||
}
|
||||
} else {
|
||||
self.command_line.push_error("SWEEP: could not sweep profile along path. Use a closed 2D profile and a Line or Polyline path.");
|
||||
self.command_line.push_error(crate::t!("SWEEP: could not sweep profile along path. Use a closed 2D profile and a Line or Polyline path.").as_ref());
|
||||
}
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
|
@ -2849,15 +2849,15 @@ impl OpenCADStudio {
|
|||
.meshes
|
||||
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"LOFT: solid created from {} profiles.",
|
||||
handles.len()
|
||||
));
|
||||
).as_ref());
|
||||
if let Some(pd) = pending {
|
||||
self.commit_undo_delta(i, pd);
|
||||
}
|
||||
} else {
|
||||
self.command_line.push_error("LOFT: could not loft profiles. Ensure sections have the same edge count and are compatible.");
|
||||
self.command_line.push_error(crate::t!("LOFT: could not loft profiles. Ensure sections have the same edge count and are compatible.").as_ref());
|
||||
}
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
|
@ -2893,10 +2893,10 @@ impl OpenCADStudio {
|
|||
// Re-add with updated model
|
||||
self.tabs[i].scene.add_hatch(model);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("HATCHEDIT: hatch updated.");
|
||||
self.command_line.push_output(crate::t!("HATCHEDIT: hatch updated.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("HATCHEDIT: hatch entity not found.");
|
||||
.push_error(crate::t!("HATCHEDIT: hatch entity not found.").as_ref());
|
||||
}
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
|
@ -2942,7 +2942,7 @@ impl OpenCADStudio {
|
|||
crate::app::text_inline::can_edit_text(handle, &self.tabs[i].scene.document);
|
||||
if !is_editable {
|
||||
self.command_line
|
||||
.push_error("TEXTEDIT: selected entity is not text.");
|
||||
.push_error(crate::t!("TEXTEDIT: selected entity is not text.").as_ref());
|
||||
let prompt = self.tabs[i].active_cmd.as_ref().map(|c| c.prompt());
|
||||
if let Some(p) = prompt {
|
||||
self.command_line.push_info(&p);
|
||||
|
|
@ -2970,7 +2970,7 @@ impl OpenCADStudio {
|
|||
self.texteditmode = val;
|
||||
let display_val = if val { 1 } else { 0 };
|
||||
self.command_line
|
||||
.push_output(&format!("TEXTEDITMODE set to {display_val}"));
|
||||
.push_output(crate::tf!("TEXTEDITMODE set to {display_val}").as_ref());
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
self.tabs[i].scene.clear_preview_wire();
|
||||
|
|
@ -3014,11 +3014,11 @@ impl OpenCADStudio {
|
|||
}
|
||||
if updated {
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("DDEDIT: text updated.");
|
||||
self.command_line.push_output(crate::t!("DDEDIT: text updated.").as_ref());
|
||||
} else {
|
||||
self.discard_last_undo_entry(i);
|
||||
self.command_line
|
||||
.push_error("DDEDIT: entity type not supported.");
|
||||
.push_error(crate::t!("DDEDIT: entity type not supported.").as_ref());
|
||||
}
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
|
|
|||
|
|
@ -43,12 +43,12 @@ impl OpenCADStudio {
|
|||
} else {
|
||||
"model space"
|
||||
};
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Base point ({}, {}, {}) set for {space}.",
|
||||
nums[0], nums[1], z
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error("Usage: BASE <x> <y> [z]");
|
||||
self.command_line.push_error(crate::t!("Usage: BASE <x> <y> [z]").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -60,7 +60,7 @@ impl OpenCADStudio {
|
|||
return match self.mtext_selected_text() {
|
||||
Some(text) => {
|
||||
self.command_line
|
||||
.push_info("Copied selected text to clipboard.");
|
||||
.push_info(crate::t!("Copied selected text to clipboard.").as_ref());
|
||||
Some(iced::clipboard::write(text).discard())
|
||||
}
|
||||
None => Some(Task::none()),
|
||||
|
|
@ -91,10 +91,10 @@ impl OpenCADStudio {
|
|||
&self.tabs[i].scene.document,
|
||||
&self.clipboard,
|
||||
);
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{} object(s) copied to clipboard.",
|
||||
self.clipboard.len()
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,12 +145,12 @@ impl OpenCADStudio {
|
|||
&self.tabs[i].scene.document,
|
||||
&self.clipboard,
|
||||
);
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{} object(s) copied to clipboard (base {:.3},{:.3}).",
|
||||
self.clipboard.len(),
|
||||
base.x,
|
||||
base.y
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -187,13 +187,13 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_info(&format!("{} object(s) cut to clipboard.", count));
|
||||
.push_info(crate::tf!("{} object(s) cut to clipboard.", count).as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
"PASTECLIP" => {
|
||||
if self.clipboard.is_empty() {
|
||||
self.command_line.push_error("Clipboard is empty.");
|
||||
self.command_line.push_error(crate::t!("Clipboard is empty.").as_ref());
|
||||
} else {
|
||||
let wires = self.tabs[i].scene.wires_for_entities(&self.clipboard);
|
||||
let base = self.clipboard_base;
|
||||
|
|
@ -210,7 +210,7 @@ impl OpenCADStudio {
|
|||
"PASTEORIG" => {
|
||||
if self.clipboard.is_empty() {
|
||||
self.command_line
|
||||
.push_error("PASTEORIG: clipboard is empty.");
|
||||
.push_error(crate::t!("PASTEORIG: clipboard is empty.").as_ref());
|
||||
} else {
|
||||
let count = self.clipboard.len();
|
||||
self.push_undo_snapshot(i, "PASTEORIG");
|
||||
|
|
@ -219,10 +219,10 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_layer_panel();
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"PASTEORIG: {} object(s) pasted at original coordinates.",
|
||||
count
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -231,7 +231,7 @@ impl OpenCADStudio {
|
|||
"PASTEBLOCK" => {
|
||||
if self.clipboard.is_empty() {
|
||||
self.command_line
|
||||
.push_error("PASTEBLOCK: clipboard is empty.");
|
||||
.push_error(crate::t!("PASTEBLOCK: clipboard is empty.").as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "PASTEBLOCK");
|
||||
self.merge_clipboard_deps(i);
|
||||
|
|
@ -294,7 +294,7 @@ impl OpenCADStudio {
|
|||
self.command_line.push_info(&cmd.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
}
|
||||
Err(e) => self.command_line.push_error(&format!("PASTEBLOCK: {e}")),
|
||||
Err(e) => self.command_line.push_error(crate::tf!("PASTEBLOCK: {e}").as_ref()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -323,7 +323,7 @@ impl OpenCADStudio {
|
|||
let blocks = self.tabs[i].scene.custom_block_names();
|
||||
if blocks.is_empty() {
|
||||
self.command_line
|
||||
.push_error("No user-defined blocks found in this drawing.");
|
||||
.push_error(crate::t!("No user-defined blocks found in this drawing.").as_ref());
|
||||
} else {
|
||||
use crate::modules::insert::insert_block::InsertBlockCommand;
|
||||
let cmd = InsertBlockCommand::new(blocks);
|
||||
|
|
@ -336,7 +336,7 @@ impl OpenCADStudio {
|
|||
let blocks = self.tabs[i].scene.custom_block_names();
|
||||
if blocks.is_empty() {
|
||||
self.command_line
|
||||
.push_error("No user-defined blocks found in this drawing.");
|
||||
.push_error(crate::t!("No user-defined blocks found in this drawing.").as_ref());
|
||||
} else {
|
||||
use crate::modules::insert::minsert::MinsertCommand;
|
||||
let cmd = MinsertCommand::new(blocks);
|
||||
|
|
@ -359,20 +359,20 @@ impl OpenCADStudio {
|
|||
let arg = cmd.trim_start_matches("ATTSYNC").trim();
|
||||
let blocks = self.tabs[i].scene.custom_block_names();
|
||||
if arg.is_empty() {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"Usage: ATTSYNC <block name>. Blocks: {}",
|
||||
if blocks.is_empty() {
|
||||
"(none)".to_string()
|
||||
} else {
|
||||
blocks.join(", ")
|
||||
}
|
||||
));
|
||||
).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
let Some(block) = blocks.iter().find(|b| b.eq_ignore_ascii_case(arg)).cloned()
|
||||
else {
|
||||
self.command_line
|
||||
.push_error(&format!("ATTSYNC: no block named \"{arg}\"."));
|
||||
.push_error(crate::tf!("ATTSYNC: no block named \"{arg}\".").as_ref());
|
||||
return Some(Task::none());
|
||||
};
|
||||
// Gather the block's attribute definitions (tag, default value).
|
||||
|
|
@ -422,10 +422,10 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"ATTSYNC: synchronised {synced} insert(s) of \"{block}\" against {} attribute definition(s).",
|
||||
attdefs.len()
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
// ADCENTER / CONTENTBROWSER — report the drawing's named content
|
||||
|
|
@ -440,7 +440,7 @@ impl OpenCADStudio {
|
|||
.names()
|
||||
.map(|s| s.to_string())
|
||||
.collect();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Blocks ({}): {}",
|
||||
blocks.len(),
|
||||
if blocks.is_empty() {
|
||||
|
|
@ -448,12 +448,12 @@ impl OpenCADStudio {
|
|||
} else {
|
||||
blocks.join(", ")
|
||||
}
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Layers ({}): {}",
|
||||
layers.len(),
|
||||
layers.join(", ")
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
// BLOCKPALETTE — list the blocks available to insert.
|
||||
|
|
@ -464,11 +464,11 @@ impl OpenCADStudio {
|
|||
"No user-defined blocks. Define one with BLOCK, then INSERT it.",
|
||||
);
|
||||
} else {
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Blocks ({}) — insert with INSERT <name>: {}",
|
||||
blocks.len(),
|
||||
blocks.join(", ")
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -527,9 +527,9 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if xrefs.is_empty() {
|
||||
self.command_line
|
||||
.push_output("XREF No external references in this drawing.");
|
||||
.push_output(crate::t!("XREF No external references in this drawing.").as_ref());
|
||||
} else {
|
||||
self.command_line.push_output("XREF External references:");
|
||||
self.command_line.push_output(crate::t!("XREF External references:").as_ref());
|
||||
for line in xrefs {
|
||||
self.command_line.push_output(&line);
|
||||
}
|
||||
|
|
@ -548,19 +548,19 @@ impl OpenCADStudio {
|
|||
match info.status {
|
||||
crate::io::xref::XrefStatus::Loaded => {
|
||||
self.command_line
|
||||
.push_output(&format!("XREF Reloaded \"{}\"", info.name));
|
||||
.push_output(crate::tf!("XREF Reloaded \"{}\"", info.name).as_ref());
|
||||
}
|
||||
crate::io::xref::XrefStatus::NotFound => {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"XREF Not found: \"{}\" ({})",
|
||||
info.name, info.path
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
crate::io::xref::XrefStatus::Unloaded => {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"XREF Unloaded (skipped): \"{}\"",
|
||||
info.name
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -574,7 +574,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("XREF Save the drawing first to resolve relative XREF paths.");
|
||||
.push_error(crate::t!("XREF Save the drawing first to resolve relative XREF paths.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -604,7 +604,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
None => self
|
||||
.command_line
|
||||
.push_error("XOPEN: select an external reference (xref) to open."),
|
||||
.push_error(crate::t!("XOPEN: select an external reference (xref) to open.").as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -622,7 +622,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if inserts.is_empty() {
|
||||
self.command_line
|
||||
.push_error("NCOPY: select a block reference first.");
|
||||
.push_error(crate::t!("NCOPY: select a block reference first.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
self.push_undo_snapshot(i, "NCOPY");
|
||||
|
|
@ -638,9 +638,9 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"NCOPY: copied {n} nested object(s) into model space (blocks kept)."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
_ => return None,
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("JUSTIFYTEXT: select text objects first.");
|
||||
.push_error(crate::t!("JUSTIFYTEXT: select text objects first.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
if opt.is_empty() {
|
||||
|
|
@ -130,7 +130,7 @@ impl OpenCADStudio {
|
|||
};
|
||||
if text_align.is_none() && mtext_ap.is_none() {
|
||||
self.command_line
|
||||
.push_error("JUSTIFYTEXT: unknown justification option.");
|
||||
.push_error(crate::t!("JUSTIFYTEXT: unknown justification option.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
self.push_undo_snapshot(i, "JUSTIFYTEXT");
|
||||
|
|
@ -175,7 +175,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line
|
||||
.push_output(&format!("JUSTIFYTEXT: updated {n} text object(s)."));
|
||||
.push_output(crate::tf!("JUSTIFYTEXT: updated {n} text object(s).").as_ref());
|
||||
}
|
||||
|
||||
// TCASE <Upper|Lower|Sentence|Title> — change the case of the text in
|
||||
|
|
@ -207,7 +207,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("TCASE: select text objects first.");
|
||||
.push_error(crate::t!("TCASE: select text objects first.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
if !matches!(
|
||||
|
|
@ -223,7 +223,7 @@ impl OpenCADStudio {
|
|||
| "TITLE"
|
||||
) {
|
||||
self.command_line
|
||||
.push_info("Usage: TCASE <Upper|Lower|Sentence|Title>");
|
||||
.push_info(crate::t!("Usage: TCASE <Upper|Lower|Sentence|Title>").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
let conv = move |s: &str| -> String {
|
||||
|
|
@ -263,7 +263,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line
|
||||
.push_output(&format!("TCASE: updated {n} text object(s)."));
|
||||
.push_output(crate::tf!("TCASE: updated {n} text object(s).").as_ref());
|
||||
}
|
||||
|
||||
// TEXTMASK — place a wipeout mask sized to each selected text object's
|
||||
|
|
@ -296,7 +296,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("TEXTMASK: select text objects first.");
|
||||
.push_error(crate::t!("TEXTMASK: select text objects first.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
self.push_undo_snapshot(i, "TEXTMASK");
|
||||
|
|
@ -339,7 +339,7 @@ impl OpenCADStudio {
|
|||
.replace_selection(handles.iter().cloned().collect());
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("TEXTMASK: masked {n} text object(s)."));
|
||||
.push_output(crate::tf!("TEXTMASK: masked {n} text object(s).").as_ref());
|
||||
return self.dispatch_view("DRAWORDER FRONT", i);
|
||||
}
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("TEXTFIT: select single-line text first.");
|
||||
.push_error(crate::t!("TEXTFIT: select single-line text first.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
self.push_undo_snapshot(i, "TEXTFIT");
|
||||
|
|
@ -412,9 +412,9 @@ impl OpenCADStudio {
|
|||
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
||||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"TEXTFIT: fitted {n} text object(s) to width {target}."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
// (text sequential numbering)
|
||||
|
|
@ -450,7 +450,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if texts.is_empty() {
|
||||
self.command_line
|
||||
.push_error("TCOUNT: select single-line text first.");
|
||||
.push_error(crate::t!("TCOUNT: select single-line text first.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
// Reading order: higher Y first, then smaller X.
|
||||
|
|
@ -478,10 +478,10 @@ impl OpenCADStudio {
|
|||
.map(|(handle, _, _)| (*handle, crate::scene::ChangeKind::Modified))
|
||||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"TCOUNT: numbered {} text object(s) from {start}.",
|
||||
texts.len()
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
"MLEADER" => {
|
||||
|
|
@ -575,7 +575,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
if pts.len() < 2 {
|
||||
self.command_line
|
||||
.push_error("QDIM: no dimensionable endpoints in the selection.");
|
||||
.push_error(crate::t!("QDIM: no dimensionable endpoints in the selection.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
// Choose the dimension axis from the points' spread: a wider X
|
||||
|
|
@ -596,7 +596,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
if pts.len() < 2 {
|
||||
self.command_line
|
||||
.push_error("QDIM: endpoints collapse to a single position.");
|
||||
.push_error(crate::t!("QDIM: endpoints collapse to a single position.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
self.push_undo_snapshot(i, "QDIM");
|
||||
|
|
@ -628,7 +628,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("QDIM {made} dimensions created."));
|
||||
.push_output(crate::tf!("QDIM {made} dimensions created.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
|
||||
|
|
@ -697,28 +697,28 @@ impl OpenCADStudio {
|
|||
|
||||
"ZOOM EXTENTS ALL" | "ZOOM EXTENTS ALL VIEWPORTS" | "ZEA" => {
|
||||
self.tabs[i].scene.fit_all_model_viewports();
|
||||
self.command_line.push_output("Zoom Extents — All Viewports");
|
||||
self.command_line.push_output(crate::t!("Zoom Extents — All Viewports").as_ref());
|
||||
}
|
||||
|
||||
"ZOOM EXTENTS" | "ZOOMEXTENTS" | "ZE" => {
|
||||
self.tabs[i].scene.fit_all();
|
||||
self.command_line.push_output("Zoom Extents");
|
||||
self.command_line.push_output(crate::t!("Zoom Extents").as_ref());
|
||||
}
|
||||
|
||||
"ZOOM IN" | "ZI" => {
|
||||
self.tabs[i].scene.zoom_camera(1.0 / 1.5);
|
||||
self.command_line.push_output("Zoom In");
|
||||
self.command_line.push_output(crate::t!("Zoom In").as_ref());
|
||||
}
|
||||
|
||||
"ZOOM OUT" | "ZO" => {
|
||||
self.tabs[i].scene.zoom_camera(1.5);
|
||||
self.command_line.push_output("Zoom Out");
|
||||
self.command_line.push_output(crate::t!("Zoom Out").as_ref());
|
||||
}
|
||||
|
||||
// ZOOM ALL — fit the configured drawing limits.
|
||||
"ZOOM ALL" | "ZOOM A" | "ZA" => {
|
||||
self.tabs[i].scene.fit_all_with_limits();
|
||||
self.command_line.push_output("Zoom All");
|
||||
self.command_line.push_output(crate::t!("Zoom All").as_ref());
|
||||
}
|
||||
|
||||
// ZOOM SCALE — set zoom factor (e.g. "ZOOM SCALE 2" or "ZS 0.5")
|
||||
|
|
@ -731,7 +731,7 @@ impl OpenCADStudio {
|
|||
if factor > 0.0 {
|
||||
self.tabs[i].scene.zoom_camera(1.0 / factor);
|
||||
self.command_line
|
||||
.push_output(&format!("Zoom Scale ×{factor:.3}"));
|
||||
.push_output(crate::tf!("Zoom Scale ×{factor:.3}").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -992,10 +992,10 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_output(&format!("{exploded} object(s) exploded."));
|
||||
.push_output(crate::tf!("{exploded} object(s) exploded.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_info("EXPLODE: no explodable objects selected.");
|
||||
.push_info(crate::t!("EXPLODE: no explodable objects selected.").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1108,11 +1108,11 @@ impl OpenCADStudio {
|
|||
});
|
||||
let Some((center, radius)) = found else {
|
||||
self.command_line
|
||||
.push_error("DIMJOGGED: select an arc or circle first.");
|
||||
.push_error(crate::t!("DIMJOGGED: select an arc or circle first.").as_ref());
|
||||
return None;
|
||||
};
|
||||
if radius <= 0.0 {
|
||||
self.command_line.push_error("DIMJOGGED: invalid radius.");
|
||||
self.command_line.push_error(crate::t!("DIMJOGGED: invalid radius.").as_ref());
|
||||
return None;
|
||||
}
|
||||
let k = std::f64::consts::FRAC_1_SQRT_2;
|
||||
|
|
@ -1129,7 +1129,7 @@ impl OpenCADStudio {
|
|||
.add_entity(acadrust::EntityType::Dimension(Dimension::Radius(dim)));
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output("DIMJOGGED: created a jogged radius dimension.");
|
||||
.push_output(crate::t!("DIMJOGGED: created a jogged radius dimension.").as_ref());
|
||||
}
|
||||
|
||||
// ARCTEXT <text> — lay the text out as one Text entity per character
|
||||
|
|
@ -1166,12 +1166,12 @@ impl OpenCADStudio {
|
|||
});
|
||||
let Some(arc) = arc else {
|
||||
self.command_line
|
||||
.push_error("ARCTEXT: select an arc first.");
|
||||
.push_error(crate::t!("ARCTEXT: select an arc first.").as_ref());
|
||||
return None;
|
||||
};
|
||||
let chars: Vec<char> = text.chars().filter(|c| !c.is_control()).collect();
|
||||
if chars.is_empty() {
|
||||
self.command_line.push_error("ARCTEXT: no printable text.");
|
||||
self.command_line.push_error(crate::t!("ARCTEXT: no printable text.").as_ref());
|
||||
return None;
|
||||
}
|
||||
let n = chars.len();
|
||||
|
|
@ -1195,7 +1195,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("ARCTEXT: placed {n} character(s) along the arc."));
|
||||
.push_output(crate::tf!("ARCTEXT: placed {n} character(s) along the arc.").as_ref());
|
||||
}
|
||||
|
||||
_ => return None,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ impl OpenCADStudio {
|
|||
"PAN" => {
|
||||
self.tabs[i].pan_mode = true;
|
||||
self.command_line
|
||||
.push_output("PAN: drag with the left mouse button. Press Esc to exit.");
|
||||
.push_output(crate::t!("PAN: drag with the left mouse button. Press Esc to exit.").as_ref());
|
||||
}
|
||||
|
||||
// ── TABLE cell editing ─────────────────────────────────────────────
|
||||
|
|
@ -46,18 +46,18 @@ impl OpenCADStudio {
|
|||
if found {
|
||||
self.push_undo_snapshot(i, "TABLE CELL");
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"TABLE CELL: set [{row},{col}] = \"{text}\"."
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(
|
||||
"TABLE CELL: select a Table entity first, or row/col out of range."
|
||||
crate::t!("TABLE CELL: select a Table entity first, or row/col out of range.").as_ref()
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_info("Usage: TABLE CELL <row> <col> <text>");
|
||||
.push_info(crate::t!("Usage: TABLE CELL <row> <col> <text>").as_ref());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -111,9 +111,9 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"UCSICON {sub}: updated {count} viewport(s) + model space."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
"" => {
|
||||
// Bare UCSICON toggles visibility.
|
||||
|
|
@ -128,11 +128,11 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
let state = if visible { "ON" } else { "OFF" };
|
||||
self.command_line.push_output(&format!("UCSICON {state}"));
|
||||
self.command_line.push_output(crate::tf!("UCSICON {state}").as_ref());
|
||||
}
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_info("Usage: UCSICON ON | OFF | NOORIGIN | ORIGIN");
|
||||
.push_info(crate::t!("Usage: UCSICON ON | OFF | NOORIGIN | ORIGIN").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -172,12 +172,12 @@ impl OpenCADStudio {
|
|||
tokens.iter().map(|value| value.parse()).collect();
|
||||
let Ok(values) = values else {
|
||||
self.command_line
|
||||
.push_error("LIMITS: four numeric coordinates required.");
|
||||
.push_error(crate::t!("LIMITS: four numeric coordinates required.").as_ref());
|
||||
return Some(Task::none());
|
||||
};
|
||||
if tokens.len() != 4 || !values.iter().all(|value| value.is_finite()) {
|
||||
self.command_line
|
||||
.push_error("LIMITS: four finite numeric coordinates required.");
|
||||
.push_error(crate::t!("LIMITS: four finite numeric coordinates required.").as_ref());
|
||||
} else {
|
||||
let first = glam::DVec2::new(values[0], values[1]);
|
||||
let opposite = glam::DVec2::new(values[2], values[3]);
|
||||
|
|
@ -185,15 +185,15 @@ impl OpenCADStudio {
|
|||
let max = first.max(opposite);
|
||||
if min.x == max.x || min.y == max.y {
|
||||
self.command_line
|
||||
.push_error("LIMITS: corners must define a non-zero area.");
|
||||
.push_error(crate::t!("LIMITS: corners must define a non-zero area.").as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "LIMITS");
|
||||
self.tabs[i].scene.set_current_drawing_limits(min, max);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Drawing limits: {:.4},{:.4} to {:.4},{:.4}.",
|
||||
min.x, min.y, max.x, max.y
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -249,13 +249,13 @@ impl OpenCADStudio {
|
|||
// ── TOOLPALETTES — not yet implemented ───────────────────────────────
|
||||
"TOOLPALETTES" => {
|
||||
self.command_line
|
||||
.push_info("TOOLPALETTES: Tool Palettes not yet implemented.");
|
||||
.push_info(crate::t!("TOOLPALETTES: Tool Palettes not yet implemented.").as_ref());
|
||||
}
|
||||
|
||||
// ── SHEETSET — not yet implemented ───────────────────────────────────
|
||||
"SHEETSET" => {
|
||||
self.command_line
|
||||
.push_info("SHEETSET: Sheet Set Manager not yet implemented.");
|
||||
.push_info(crate::t!("SHEETSET: Sheet Set Manager not yet implemented.").as_ref());
|
||||
}
|
||||
|
||||
// ── XDATA — read/write extended entity data ──────────────────────────
|
||||
|
|
@ -288,7 +288,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if selected_handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("XDATA: select entities first.");
|
||||
.push_error(crate::t!("XDATA: select entities first.").as_ref());
|
||||
} else {
|
||||
match sub.as_str() {
|
||||
"LIST" | "" => {
|
||||
|
|
@ -297,18 +297,18 @@ impl OpenCADStudio {
|
|||
let xd = &entity.common().extended_data;
|
||||
if xd.is_empty() {
|
||||
self.command_line
|
||||
.push_output(&format!(" {:x}: no xdata.", sh.value()));
|
||||
.push_output(crate::tf!(" {:x}: no xdata.", sh.value()).as_ref());
|
||||
} else {
|
||||
for rec in xd.records() {
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" {:x} [{}]: {} value(s)",
|
||||
sh.value(),
|
||||
rec.application_name,
|
||||
rec.values.len()
|
||||
));
|
||||
).as_ref());
|
||||
for v in &rec.values {
|
||||
self.command_line
|
||||
.push_output(&format!(" {:?}", v));
|
||||
.push_output(crate::tf!(" {:?}", v).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -329,10 +329,10 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"XDATA: set [{app}] = \"{val}\" on {} entity/entities.",
|
||||
selected_handles.len()
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
"CLEAR" => {
|
||||
let app_filter = parts.get(1).copied();
|
||||
|
|
@ -360,11 +360,11 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("XDATA: cleared.");
|
||||
self.command_line.push_output(crate::t!("XDATA: cleared.").as_ref());
|
||||
}
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_info("Usage: XDATA LIST | SET <app> <value> | CLEAR [app]");
|
||||
.push_info(crate::t!("Usage: XDATA LIST | SET <app> <value> | CLEAR [app]").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -486,7 +486,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_error("Usage: PLOTSTYLE [LOAD | CLEAR | STATUS]");
|
||||
.push_error(crate::t!("Usage: PLOTSTYLE [LOAD | CLEAR | STATUS]").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -529,7 +529,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("UNDERLAY: select underlay entities first.");
|
||||
.push_error(crate::t!("UNDERLAY: select underlay entities first.").as_ref());
|
||||
} else {
|
||||
let parts: Vec<&str> = sub.splitn(2, char::is_whitespace).collect();
|
||||
let action = parts.first().copied().unwrap_or("");
|
||||
|
|
@ -589,7 +589,7 @@ impl OpenCADStudio {
|
|||
},
|
||||
_ => {
|
||||
// No sub-command: print status.
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Underlay {:x}: fade={}, contrast={}, on={}, clip={}, mono={}",
|
||||
h.value(),
|
||||
ul.fade,
|
||||
|
|
@ -597,7 +597,7 @@ impl OpenCADStudio {
|
|||
ul.is_on(),
|
||||
ul.is_clipping(),
|
||||
ul.is_monochrome(),
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -605,10 +605,10 @@ impl OpenCADStudio {
|
|||
if changed > 0 {
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_info(&format!("Updated {changed} underlay(s)."));
|
||||
.push_info(crate::tf!("Updated {changed} underlay(s).").as_ref());
|
||||
} else if !action.is_empty() {
|
||||
self.command_line.push_error(
|
||||
"Usage: UNDERLAY [FADE <n>|CONTRAST <n>|ON|OFF|CLIP ON|OFF|MONO ON|OFF]"
|
||||
crate::t!("Usage: UNDERLAY [FADE <n>|CONTRAST <n>|ON|OFF|CLIP ON|OFF|MONO ON|OFF]").as_ref()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -635,13 +635,13 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("OBJECTSCALE: select objects first.");
|
||||
.push_error(crate::t!("OBJECTSCALE: select objects first.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
self.push_undo_snapshot(i, "OBJECTSCALE");
|
||||
let Some(scale) = self.tabs[i].scene.creation_annotation_scale_handle() else {
|
||||
self.command_line
|
||||
.push_error("OBJECTSCALE: the active annotation scale is unavailable.");
|
||||
.push_error(crate::t!("OBJECTSCALE: the active annotation scale is unavailable.").as_ref());
|
||||
return Some(Task::none());
|
||||
};
|
||||
let mut n = 0usize;
|
||||
|
|
@ -665,9 +665,9 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"OBJECTSCALE: added the active scale to {n} object(s)."
|
||||
));
|
||||
).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
|
||||
|
|
@ -688,13 +688,13 @@ impl OpenCADStudio {
|
|||
use acadrust::xdata::{ExtendedDataRecord, XDataValue};
|
||||
let url = cmd.strip_prefix("HYPERLINK").unwrap_or("").trim().to_string();
|
||||
if url.is_empty() {
|
||||
self.command_line.push_info("Usage: HYPERLINK <url> (select objects first)");
|
||||
self.command_line.push_info(crate::t!("Usage: HYPERLINK <url> (select objects first)").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
let handles: Vec<acadrust::Handle> =
|
||||
self.tabs[i].scene.selected_entities().iter().map(|(h, _)| *h).collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line.push_error("HYPERLINK: select objects first.");
|
||||
self.command_line.push_error(crate::t!("HYPERLINK: select objects first.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
self.push_undo_snapshot(i, "HYPERLINK");
|
||||
|
|
@ -710,7 +710,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("HYPERLINK: attached to {n} object(s)."));
|
||||
.push_output(crate::tf!("HYPERLINK: attached to {n} object(s).").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
|
||||
|
|
@ -745,10 +745,10 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("ADJUST: select raster image(s) first.");
|
||||
.push_error(crate::t!("ADJUST: select raster image(s) first.").as_ref());
|
||||
} else if action.is_empty() {
|
||||
self.command_line
|
||||
.push_info("Usage: ADJUST BRIGHTNESS|CONTRAST|FADE <0-100>");
|
||||
.push_info(crate::t!("Usage: ADJUST BRIGHTNESS|CONTRAST|FADE <0-100>").as_ref());
|
||||
} else if let Ok(v) = arg.parse::<u8>() {
|
||||
let v = v.min(100);
|
||||
self.push_undo_snapshot(i, "ADJUST");
|
||||
|
|
@ -792,14 +792,14 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line
|
||||
.push_output(&format!("ADJUST: {action} = {v} on {changed} image(s)."));
|
||||
.push_output(crate::tf!("ADJUST: {action} = {v} on {changed} image(s).").as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(
|
||||
"ADJUST: no raster images selected, or unknown property (use BRIGHTNESS|CONTRAST|FADE).",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
self.command_line.push_error("ADJUST: value must be 0-100.");
|
||||
self.command_line.push_error(crate::t!("ADJUST: value must be 0-100.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -837,7 +837,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
_ => self
|
||||
.command_line
|
||||
.push_error("ANNOALLVISIBLE: enter 0 or 1."),
|
||||
.push_error(crate::t!("ANNOALLVISIBLE: enter 0 or 1.").as_ref()),
|
||||
}
|
||||
}
|
||||
"ANNOAUTOSCALE" => {
|
||||
|
|
@ -867,7 +867,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("ANNOUPDATE: select annotation objects first.");
|
||||
.push_error(crate::t!("ANNOUPDATE: select annotation objects first.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
self.push_undo_snapshot(i, "ANNOUPDATE");
|
||||
|
|
@ -891,7 +891,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
}
|
||||
self.command_line
|
||||
.push_output(&format!("ANNOUPDATE: updated {updated} object(s)."));
|
||||
.push_output(crate::tf!("ANNOUPDATE: updated {updated} object(s).").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
cmd if cmd.starts_with("ANNOSCALE ") || cmd.starts_with("CANNOSCALE ") => {
|
||||
|
|
@ -909,7 +909,7 @@ impl OpenCADStudio {
|
|||
.current_annotation_scale
|
||||
.clone();
|
||||
self.command_line
|
||||
.push_output(&format!("Current annotation scale: {name}"));
|
||||
.push_output(crate::tf!("Current annotation scale: {name}").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
let previous = self.tabs[i].scene.displayed_annotation_scale_handle();
|
||||
|
|
@ -924,11 +924,11 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("Annotation scale: {arg}"));
|
||||
.push_output(crate::tf!("Annotation scale: {arg}").as_ref());
|
||||
}
|
||||
None => self
|
||||
.command_line
|
||||
.push_error("Usage: ANNOSCALE <ratio> e.g. 1:50, 2:1, or a factor"),
|
||||
.push_error(crate::t!("Usage: ANNOSCALE <ratio> e.g. 1:50, 2:1, or a factor").as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -962,19 +962,19 @@ impl OpenCADStudio {
|
|||
if self.tabs[i].scene.add_scale(arg, paper, drawing) {
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("Added annotation scale {arg}."));
|
||||
.push_output(crate::tf!("Added annotation scale {arg}.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_info(&format!("Scale {arg} already exists."));
|
||||
.push_info(crate::tf!("Scale {arg} already exists.").as_ref());
|
||||
}
|
||||
}
|
||||
_ => self
|
||||
.command_line
|
||||
.push_error("SCALELISTEDIT ADD: use a ratio like 1:50."),
|
||||
.push_error(crate::t!("SCALELISTEDIT ADD: use a ratio like 1:50.").as_ref()),
|
||||
},
|
||||
None => self
|
||||
.command_line
|
||||
.push_error("SCALELISTEDIT ADD: use a ratio like 1:50."),
|
||||
.push_error(crate::t!("SCALELISTEDIT ADD: use a ratio like 1:50.").as_ref()),
|
||||
},
|
||||
"DELETE" | "REMOVE" => {
|
||||
let current = self.tabs[i]
|
||||
|
|
@ -984,20 +984,20 @@ impl OpenCADStudio {
|
|||
.current_annotation_scale
|
||||
.clone();
|
||||
if arg.is_empty() {
|
||||
self.command_line.push_info("Usage: SCALELISTEDIT DELETE <name>");
|
||||
self.command_line.push_info(crate::t!("Usage: SCALELISTEDIT DELETE <name>").as_ref());
|
||||
} else if arg.eq_ignore_ascii_case(¤t) {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"Cannot delete the current annotation scale ({arg})."
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "SCALELISTEDIT");
|
||||
if self.tabs[i].scene.remove_scale(arg) {
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("Removed annotation scale {arg}."));
|
||||
.push_output(crate::tf!("Removed annotation scale {arg}.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_info(&format!("No annotation scale named {arg}."));
|
||||
.push_info(crate::tf!("No annotation scale named {arg}.").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1009,15 +1009,15 @@ impl OpenCADStudio {
|
|||
.map(|(n, _, _)| n)
|
||||
.collect();
|
||||
if names.is_empty() {
|
||||
self.command_line.push_info("No annotation scales defined.");
|
||||
self.command_line.push_info(crate::t!("No annotation scales defined.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_output(&format!("Annotation scales: {}", names.join(", ")));
|
||||
.push_output(crate::tf!("Annotation scales: {}", names.join(", ")).as_ref());
|
||||
}
|
||||
}
|
||||
_ => self
|
||||
.command_line
|
||||
.push_info("Usage: SCALELISTEDIT [ADD 1:50 | DELETE 1:50]"),
|
||||
.push_info(crate::t!("Usage: SCALELISTEDIT [ADD 1:50 | DELETE 1:50]").as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1056,7 +1056,7 @@ impl OpenCADStudio {
|
|||
let ncols = rows_data.iter().map(|r| r.len()).max().unwrap_or(0);
|
||||
if nrows == 0 || ncols == 0 {
|
||||
self.command_line
|
||||
.push_error("DATALINK: the CSV file is empty.");
|
||||
.push_error(crate::t!("DATALINK: the CSV file is empty.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
use acadrust::entities::TableBuilder;
|
||||
|
|
@ -1076,13 +1076,13 @@ impl OpenCADStudio {
|
|||
.scene
|
||||
.add_entity_clone(acadrust::EntityType::Table(table));
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"DATALINK: imported {nrows}×{ncols} cells into a table at the origin."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
Err(e) => {
|
||||
self.command_line
|
||||
.push_error(&format!("DATALINK: cannot read \"{path}\": {e}"));
|
||||
.push_error(crate::tf!("DATALINK: cannot read \"{path}\": {e}").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1110,7 +1110,7 @@ impl OpenCADStudio {
|
|||
let pts = parse_landxml_cgpoints(&xml);
|
||||
if pts.is_empty() {
|
||||
self.command_line
|
||||
.push_info("LANDXMLIMPORT: no <CgPoint> survey points found.");
|
||||
.push_info(crate::t!("LANDXMLIMPORT: no <CgPoint> survey points found.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
self.push_undo_snapshot(i, "LANDXMLIMPORT");
|
||||
|
|
@ -1122,21 +1122,21 @@ impl OpenCADStudio {
|
|||
.add_entity_clone(acadrust::EntityType::Point(p));
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"LANDXMLIMPORT: imported {} survey point(s). Use ZOOM EXTENTS to view.",
|
||||
pts.len()
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
Err(e) => self
|
||||
.command_line
|
||||
.push_error(&format!("LANDXMLIMPORT: cannot read \"{path}\": {e}")),
|
||||
.push_error(crate::tf!("LANDXMLIMPORT: cannot read \"{path}\": {e}").as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
"POINTCLOUDATTACH" | "RECAP" | "SYNCPVIEWPORTS" | "UNDERLAYLAYERS"
|
||||
| "UOSNAP" => {
|
||||
self.command_line
|
||||
.push_info(&format!("{cmd}: not yet implemented."));
|
||||
.push_info(crate::tf!("{cmd}: not yet implemented.").as_ref());
|
||||
}
|
||||
|
||||
_ => return None,
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if selected_handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("ATTEDIT: select an Insert entity first.");
|
||||
.push_error(crate::t!("ATTEDIT: select an Insert entity first.").as_ref());
|
||||
} else {
|
||||
let mut found_any = false;
|
||||
for sh in &selected_handles {
|
||||
|
|
@ -90,17 +90,17 @@ impl OpenCADStudio {
|
|||
if rest.is_empty() {
|
||||
// List attributes.
|
||||
if ins.attributes.is_empty() {
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" Insert {:x}: no attributes.",
|
||||
sh.value()
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
for attr in &ins.attributes {
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" [{tag}] = {val}",
|
||||
tag = attr.tag,
|
||||
val = attr.get_value()
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
if !found_any {
|
||||
self.command_line
|
||||
.push_error("ATTEDIT: no Insert entities in selection.");
|
||||
.push_error(crate::t!("ATTEDIT: no Insert entities in selection.").as_ref());
|
||||
}
|
||||
// If tag + value supplied, mutate attributes.
|
||||
if parts.len() == 2 && !parts[0].is_empty() {
|
||||
|
|
@ -133,13 +133,13 @@ impl OpenCADStudio {
|
|||
}
|
||||
if changed > 0 {
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"ATTEDIT: updated {changed} attribute(s) [{tag_up}] = {new_val}."
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"ATTEDIT: tag '{tag_up}' not found in selection."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -187,13 +187,13 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"ATTDISP {sub}: {count} attribute definition(s) updated."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_info("Usage: ATTDISP ON | OFF | NORMAL");
|
||||
.push_info(crate::t!("Usage: ATTDISP ON | OFF | NORMAL").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -327,7 +327,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
None => {
|
||||
self.command_line
|
||||
.push_info("ARC Continue No previous line or arc to continue.");
|
||||
.push_info(crate::t!("ARC Continue No previous line or arc to continue.").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -599,7 +599,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("HATCHEDIT: selected entity is not a hatch.");
|
||||
.push_error(crate::t!("HATCHEDIT: selected entity is not a hatch.").as_ref());
|
||||
}
|
||||
} else {
|
||||
let cmd = HatcheditCommand::new();
|
||||
|
|
@ -721,7 +721,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_output(&format!("{n} object(s) erased."));
|
||||
.push_output(crate::tf!("{n} object(s) erased.").as_ref());
|
||||
if let Some(pd) = pending {
|
||||
self.commit_undo_delta(i, pd);
|
||||
}
|
||||
|
|
@ -783,7 +783,7 @@ impl OpenCADStudio {
|
|||
return Some(self.solid_polysolid(nums[0], nums[1]));
|
||||
}
|
||||
self.command_line
|
||||
.push_info("Usage: POLYSOLID <width> <height> (select a polyline first)");
|
||||
.push_info(crate::t!("Usage: POLYSOLID <width> <height> (select a polyline first)").as_ref());
|
||||
}
|
||||
|
||||
// SPLINEFIT — fit a smooth spline through the selected polyline's points.
|
||||
|
|
@ -829,7 +829,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
if loops.is_empty() {
|
||||
self.command_line
|
||||
.push_error("REGION: select closed polylines or circles.");
|
||||
.push_error(crate::t!("REGION: select closed polylines or circles.").as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "REGION");
|
||||
let count = loops.len();
|
||||
|
|
@ -845,7 +845,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("REGION: created {count} region(s)."));
|
||||
.push_output(crate::tf!("REGION: created {count} region(s).").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -871,7 +871,7 @@ impl OpenCADStudio {
|
|||
return Some(self.solid_pyramid(nums[0], nums[1], sides));
|
||||
}
|
||||
self.command_line
|
||||
.push_info("Usage: PYRAMID <radius> <height> [sides] (default 4 sides)");
|
||||
.push_info(crate::t!("Usage: PYRAMID <radius> <height> [sides] (default 4 sides)").as_ref());
|
||||
}
|
||||
|
||||
// SECTION [X|Y|Z] <value> — draw the cross-section outline of the solid.
|
||||
|
|
@ -1070,7 +1070,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
if sel.len() == 1 {
|
||||
self.command_line
|
||||
.push_error("DDEDIT: selected entity is not text.");
|
||||
.push_error(crate::t!("DDEDIT: selected entity is not text.").as_ref());
|
||||
} else {
|
||||
let cmd = DdeditCommand::new();
|
||||
self.command_line.push_info(&cmd.prompt());
|
||||
|
|
@ -1093,7 +1093,7 @@ impl OpenCADStudio {
|
|||
"Multiple"
|
||||
};
|
||||
self.command_line
|
||||
.push_output(&format!("Current settings: Edit mode = {}", mode_str));
|
||||
.push_output(crate::tf!("Current settings: Edit mode = {}", mode_str).as_ref());
|
||||
let new_cmd = TexteditCommand::new(self.texteditmode);
|
||||
self.command_line.push_info(&new_cmd.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ impl OpenCADStudio {
|
|||
"SAVEALL" => {
|
||||
if self.read_only {
|
||||
self.command_line
|
||||
.push_error("Read-only session (--read-only): saving is disabled.");
|
||||
.push_error(crate::t!("Read-only session (--read-only): saving is disabled.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
|
@ -27,10 +27,10 @@ impl OpenCADStudio {
|
|||
.active_save_jobs
|
||||
.contains_key(&self.tabs[t].id)
|
||||
{
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"SAVEALL: {} already has a save running",
|
||||
path.display()
|
||||
));
|
||||
).as_ref());
|
||||
skipped += 1;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -42,28 +42,28 @@ impl OpenCADStudio {
|
|||
Ok(()) => {
|
||||
saved += 1;
|
||||
}
|
||||
Err(e) => self.command_line.push_error(&format!(
|
||||
Err(e) => self.command_line.push_error(crate::tf!(
|
||||
"SAVEALL: {} failed: {e}",
|
||||
path.display()
|
||||
)),
|
||||
).as_ref()),
|
||||
}
|
||||
} else {
|
||||
skipped += 1;
|
||||
}
|
||||
}
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"SAVEALL: saved {saved} drawing(s){}.",
|
||||
if skipped > 0 {
|
||||
format!("; {skipped} need SAVEAS (no file path yet)")
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
self.command_line
|
||||
.push_info("SAVEALL: save each tab individually in the web build.");
|
||||
.push_info(crate::t!("SAVEALL: save each tab individually in the web build.").as_ref());
|
||||
}
|
||||
return Some(Task::none());
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ impl OpenCADStudio {
|
|||
Ok(n) => return Some(Task::done(Message::UndoMany(n))),
|
||||
Err(_) => {
|
||||
self.command_line
|
||||
.push_error("Usage: UNDO [number of steps]");
|
||||
.push_error(crate::t!("Usage: UNDO [number of steps]").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
}
|
||||
|
|
@ -87,7 +87,7 @@ impl OpenCADStudio {
|
|||
// without undoing any work done since.
|
||||
"OOPS" => {
|
||||
if self.oops_cache.is_empty() {
|
||||
self.command_line.push_info("OOPS: nothing to restore.");
|
||||
self.command_line.push_info(crate::t!("OOPS: nothing to restore.").as_ref());
|
||||
} else {
|
||||
let restored = std::mem::take(&mut self.oops_cache);
|
||||
let pending = self.begin_undo(i, "OOPS", restored.len(), true);
|
||||
|
|
@ -99,7 +99,7 @@ impl OpenCADStudio {
|
|||
self.commit_undo_delta(i, pending);
|
||||
}
|
||||
self.command_line
|
||||
.push_output(&format!("OOPS: restored {n} object(s)."));
|
||||
.push_output(crate::tf!("OOPS: restored {n} object(s).").as_ref());
|
||||
}
|
||||
}
|
||||
"CLEAR" | "CLR" => return Some(Task::done(Message::ClearScene)),
|
||||
|
|
@ -161,7 +161,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
};
|
||||
self.command_line
|
||||
.push_output(&format!("Visual style: {label}."));
|
||||
.push_output(crate::tf!("Visual style: {label}.").as_ref());
|
||||
return Some(Task::done(Message::SetWireframe(wireframe)));
|
||||
}
|
||||
// CLOSE — close the active drawing tab (with the unsaved-changes
|
||||
|
|
@ -216,18 +216,18 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
}
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{cmd}: packaged {copied} file(s) into {}",
|
||||
folder.display()
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
Err(e) => self
|
||||
.command_line
|
||||
.push_error(&format!("{cmd}: cannot create folder ({e}).")),
|
||||
.push_error(crate::tf!("{cmd}: cannot create folder ({e}).").as_ref()),
|
||||
}
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("ARCHIVE: save the drawing first (it has no file path yet).");
|
||||
.push_error(crate::t!("ARCHIVE: save the drawing first (it has no file path yet).").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -302,7 +302,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.recolor_meshes();
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.command_line
|
||||
.push_output("Background reset to default.");
|
||||
.push_output(crate::t!("Background reset to default.").as_ref());
|
||||
} else if let Some(rgba) = parse_background_color(&args) {
|
||||
if is_paper {
|
||||
self.tabs[i].paper_bg_color = Some(rgba);
|
||||
|
|
@ -316,12 +316,12 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.recolor_meshes();
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
let [r, g, b, _] = rgba;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Background: rgb({}, {}, {})",
|
||||
(r * 255.0).round() as u8,
|
||||
(g * 255.0).round() as u8,
|
||||
(b * 255.0).round() as u8
|
||||
));
|
||||
).as_ref());
|
||||
// Persisted centrally after this message via
|
||||
// `persist_settings_if_changed()`.
|
||||
} else {
|
||||
|
|
@ -361,20 +361,20 @@ impl OpenCADStudio {
|
|||
})
|
||||
.map(|l| Task::done(Message::Command(l.to_string())))
|
||||
.collect();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"SCRIPT: running {} command(s) from {p}.",
|
||||
cmds.len()
|
||||
));
|
||||
).as_ref());
|
||||
return Some(Task::batch(cmds));
|
||||
}
|
||||
Err(e) => {
|
||||
self.command_line
|
||||
.push_error(&format!("SCRIPT: cannot read {p}: {e}"));
|
||||
.push_error(crate::tf!("SCRIPT: cannot read {p}: {e}").as_ref());
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_info("Usage: SCRIPT <path to .scr file>");
|
||||
.push_info(crate::t!("Usage: SCRIPT <path to .scr file>").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ impl OpenCADStudio {
|
|||
match cmd {
|
||||
"3DORBIT" => {
|
||||
self.command_line
|
||||
.push_info("3D Orbit: drag with right mouse button.");
|
||||
.push_info(crate::t!("3D Orbit: drag with right mouse button.").as_ref());
|
||||
}
|
||||
|
||||
// ── Selection utilities ───────────────────────────────────────
|
||||
|
|
@ -24,20 +24,20 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.select_entity(h, false);
|
||||
}
|
||||
self.command_line
|
||||
.push_output(&format!("SELECTALL: {} object(s) selected.", count));
|
||||
.push_output(crate::tf!("SELECTALL: {} object(s) selected.", count).as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
|
||||
"DESELECT" | "DESELALL" => {
|
||||
self.tabs[i].scene.deselect_all();
|
||||
self.command_line.push_output("Deselected.");
|
||||
self.command_line.push_output(crate::t!("Deselected.").as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
|
||||
"SELECTSIMILAR" | "SELSIM" => {
|
||||
let added = self.tabs[i].scene.select_similar();
|
||||
self.command_line
|
||||
.push_output(&format!("Select Similar: {} added.", added));
|
||||
.push_output(crate::tf!("Select Similar: {} added.", added).as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
|
||||
|
|
@ -68,11 +68,11 @@ impl OpenCADStudio {
|
|||
let expr = cmd.splitn(2, char::is_whitespace).nth(1).unwrap_or("").trim();
|
||||
if expr.is_empty() {
|
||||
self.command_line
|
||||
.push_info("Usage: CAL <expression> e.g. CAL (2+3)*4");
|
||||
.push_info(crate::t!("Usage: CAL <expression> e.g. CAL (2+3)*4").as_ref());
|
||||
} else {
|
||||
match arith_eval(expr) {
|
||||
Ok(v) => self.command_line.push_output(&format!("= {v}")),
|
||||
Err(e) => self.command_line.push_error(&format!("CAL: {e}")),
|
||||
Ok(v) => self.command_line.push_output(crate::tf!("= {v}").as_ref()),
|
||||
Err(e) => self.command_line.push_error(crate::tf!("CAL: {e}").as_ref()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -82,7 +82,7 @@ impl OpenCADStudio {
|
|||
let selected: Vec<_> = self.tabs[i].scene.selected_entities();
|
||||
if selected.is_empty() {
|
||||
self.command_line
|
||||
.push_error("LIST: no entities selected. Select entities first.");
|
||||
.push_error(crate::t!("LIST: no entities selected. Select entities first.").as_ref());
|
||||
} else {
|
||||
for (handle, _) in &selected {
|
||||
if let Some(entity) = self.tabs[i].scene.document.get_entity(*handle) {
|
||||
|
|
@ -101,7 +101,7 @@ impl OpenCADStudio {
|
|||
};
|
||||
// Entity-specific details
|
||||
let details = entity_list_details(entity);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{type_name} Handle:{:X} Layer:{} Color:{} LT:{}{}",
|
||||
handle.value(),
|
||||
common.layer,
|
||||
|
|
@ -112,7 +112,7 @@ impl OpenCADStudio {
|
|||
} else {
|
||||
format!("\n {details}")
|
||||
}
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -127,7 +127,7 @@ impl OpenCADStudio {
|
|||
let selected = scene.selected_entities();
|
||||
if selected.is_empty() {
|
||||
self.command_line
|
||||
.push_error("SELHANDLES: no entities selected. Select entities first.");
|
||||
.push_error(crate::t!("SELHANDLES: no entities selected. Select entities first.").as_ref());
|
||||
} else {
|
||||
use std::collections::BTreeMap;
|
||||
let space = if scene.current_layout == "Model" {
|
||||
|
|
@ -207,16 +207,14 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if lines.is_empty() {
|
||||
self.command_line
|
||||
.push_info("DBLIST: drawing has no entities.");
|
||||
.push_info(crate::t!("DBLIST: drawing has no entities.").as_ref());
|
||||
} else {
|
||||
let count = lines.len();
|
||||
for l in lines {
|
||||
self.command_line.push_output(&l);
|
||||
}
|
||||
self.command_line.push_output(&format!(
|
||||
"DBLIST: {count} entit{}.",
|
||||
if count == 1 { "y" } else { "ies" }
|
||||
));
|
||||
self.command_line
|
||||
.push_output(crate::tf!("DBLIST: {count} objects.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -311,7 +309,7 @@ impl OpenCADStudio {
|
|||
// If a session is already active, tell the user.
|
||||
if self.tabs[i].refedit_session.is_some() {
|
||||
self.command_line
|
||||
.push_error("REFEDIT: a session is already active. Use REFCLOSE first.");
|
||||
.push_error(crate::t!("REFEDIT: a session is already active. Use REFCLOSE first.").as_ref());
|
||||
} else {
|
||||
// Check if a single INSERT is already selected.
|
||||
let selected: Vec<_> =
|
||||
|
|
@ -337,7 +335,7 @@ impl OpenCADStudio {
|
|||
use crate::modules::draw::modify::block_edit::BlockEditPickCommand;
|
||||
if self.tabs[i].refedit_session.is_some() {
|
||||
self.command_line
|
||||
.push_error("BEDIT: finish the active REFEDIT (REFCLOSE) first.");
|
||||
.push_error(crate::t!("BEDIT: finish the active REFEDIT (REFCLOSE) first.").as_ref());
|
||||
} else {
|
||||
// Jump straight to begin when a single INSERT is preselected.
|
||||
let selected: Vec<_> =
|
||||
|
|
@ -369,7 +367,7 @@ impl OpenCADStudio {
|
|||
Some(acadrust::EntityType::Insert(ins)) => ins.clone(),
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_error("BEDIT: selected object is not a block reference.");
|
||||
.push_error(crate::t!("BEDIT: selected object is not a block reference.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
};
|
||||
|
|
@ -383,16 +381,16 @@ impl OpenCADStudio {
|
|||
{
|
||||
Some(br) => (br.handle, br.flags.is_xref),
|
||||
None => {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"BEDIT: block \"{}\" not found.",
|
||||
insert.block_name
|
||||
));
|
||||
).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
};
|
||||
if is_xref {
|
||||
self.command_line
|
||||
.push_error("BEDIT: cannot edit an external reference (xref).");
|
||||
.push_error(crate::t!("BEDIT: cannot edit an external reference (xref).").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
if self.tabs[i]
|
||||
|
|
@ -519,10 +517,10 @@ impl OpenCADStudio {
|
|||
self.refresh_properties();
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"BEDIT: Editing block \"{}\". Use Save Block or Discard to finish.",
|
||||
insert.block_name
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
"BEDIT_SAVE" => {
|
||||
|
|
@ -532,12 +530,12 @@ impl OpenCADStudio {
|
|||
}
|
||||
None => {
|
||||
self.command_line
|
||||
.push_error("BEDIT_SAVE: no block editor is open.");
|
||||
.push_error(crate::t!("BEDIT_SAVE: no block editor is open.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
Some(_) => {
|
||||
self.command_line
|
||||
.push_error("BEDIT_SAVE: invalid block editor state.");
|
||||
.push_error(crate::t!("BEDIT_SAVE: invalid block editor state.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
};
|
||||
|
|
@ -549,10 +547,10 @@ impl OpenCADStudio {
|
|||
&session.return_camera,
|
||||
);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"BEDIT: Block \"{}\" saved. All references updated.",
|
||||
session.block_name
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
"BEDIT_DISCARD" => {
|
||||
|
|
@ -562,12 +560,12 @@ impl OpenCADStudio {
|
|||
}
|
||||
None => {
|
||||
self.command_line
|
||||
.push_error("BEDIT_DISCARD: no block editor is open.");
|
||||
.push_error(crate::t!("BEDIT_DISCARD: no block editor is open.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
Some(_) => {
|
||||
self.command_line
|
||||
.push_error("BEDIT_DISCARD: invalid block editor state.");
|
||||
.push_error(crate::t!("BEDIT_DISCARD: invalid block editor state.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
};
|
||||
|
|
@ -625,10 +623,10 @@ impl OpenCADStudio {
|
|||
&return_camera,
|
||||
);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"BEDIT: Block \"{}\" edit discarded.",
|
||||
block_name
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
cmd if cmd.starts_with("REFEDIT_BEGIN:") => {
|
||||
|
|
@ -645,7 +643,7 @@ impl OpenCADStudio {
|
|||
Some(acadrust::EntityType::Insert(ins)) => ins.clone(),
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_error("REFEDIT: selected object is not an INSERT.");
|
||||
.push_error(crate::t!("REFEDIT: selected object is not an INSERT.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
};
|
||||
|
|
@ -681,10 +679,10 @@ impl OpenCADStudio {
|
|||
{
|
||||
Some(br) => br.handle,
|
||||
None => {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"REFEDIT: block \"{}\" not found.",
|
||||
insert.block_name
|
||||
));
|
||||
).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
};
|
||||
|
|
@ -712,7 +710,7 @@ impl OpenCADStudio {
|
|||
};
|
||||
|
||||
if block_entities.is_empty() {
|
||||
self.command_line.push_error("REFEDIT: block is empty.");
|
||||
self.command_line.push_error(crate::t!("REFEDIT: block is empty.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
|
||||
|
|
@ -762,10 +760,10 @@ impl OpenCADStudio {
|
|||
// No active command — the user edits the block's geometry freely
|
||||
// (move, grips, draw, erase…) and runs REFCLOSE when done. (#136)
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"REFEDIT: Editing block \"{}\". Run REFCLOSE to save, REFCLOSE_DISCARD to cancel.",
|
||||
insert.block_name
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
"REFCLOSE" => {
|
||||
|
|
@ -776,7 +774,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].active_cmd = Some(Box::new(cmd_obj));
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("REFCLOSE: no REFEDIT session active.");
|
||||
.push_error(crate::t!("REFCLOSE: no REFEDIT session active.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -788,7 +786,7 @@ impl OpenCADStudio {
|
|||
Some(s) => s,
|
||||
None => {
|
||||
self.command_line
|
||||
.push_error("REFCLOSE: no REFEDIT session active.");
|
||||
.push_error(crate::t!("REFCLOSE: no REFEDIT session active.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
};
|
||||
|
|
@ -866,10 +864,10 @@ impl OpenCADStudio {
|
|||
}
|
||||
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"REFCLOSE: Block \"{}\" saved. All references updated.",
|
||||
session.block_name
|
||||
));
|
||||
).as_ref());
|
||||
// End the edit fade before rebuilding, so the restored geometry
|
||||
// recolours bright. (#136)
|
||||
self.tabs[i].scene.set_refedit_keep(None);
|
||||
|
|
@ -882,7 +880,7 @@ impl OpenCADStudio {
|
|||
Some(s) => s,
|
||||
None => {
|
||||
self.command_line
|
||||
.push_error("REFCLOSE: no REFEDIT session active.");
|
||||
.push_error(crate::t!("REFCLOSE: no REFEDIT session active.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
};
|
||||
|
|
@ -908,7 +906,7 @@ impl OpenCADStudio {
|
|||
// End the edit fade — restore the drawing to full brightness.
|
||||
self.tabs[i].scene.set_refedit_keep(None);
|
||||
self.command_line
|
||||
.push_output("REFCLOSE: Changes discarded.");
|
||||
.push_output(crate::t!("REFCLOSE: Changes discarded.").as_ref());
|
||||
}
|
||||
|
||||
"ALIGN" => {
|
||||
|
|
@ -966,20 +964,20 @@ impl OpenCADStudio {
|
|||
let selected = self.tabs[i].scene.selected_entities();
|
||||
if selected.is_empty() {
|
||||
self.command_line
|
||||
.push_error("MASSPROP: no entities selected. Select entities first.");
|
||||
.push_error(crate::t!("MASSPROP: no entities selected. Select entities first.").as_ref());
|
||||
} else {
|
||||
for (handle, _) in &selected {
|
||||
if let Some(entity) = self.tabs[i].scene.document.get_entity(*handle) {
|
||||
use crate::entities::traits::EntityTypeOps;
|
||||
if let Some(props) = entity.mass_props() {
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{} Area={:.4} Perimeter={:.4} Centroid=({:.4},{:.4})",
|
||||
crate::entities::names::dxf_name(entity),
|
||||
props.area,
|
||||
props.perimeter,
|
||||
props.cx,
|
||||
props.cy,
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1003,7 +1001,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
};
|
||||
if handles.is_empty() {
|
||||
self.command_line.push_error("FLATTEN: no entities.");
|
||||
self.command_line.push_error(crate::t!("FLATTEN: no entities.").as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "FLATTEN");
|
||||
for h in &handles {
|
||||
|
|
@ -1012,10 +1010,10 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"FLATTEN: {} entity(ies) moved to Z=0.",
|
||||
handles.len()
|
||||
));
|
||||
).as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
}
|
||||
|
|
@ -1054,17 +1052,17 @@ impl OpenCADStudio {
|
|||
|
||||
if prop.is_empty() {
|
||||
self.command_line
|
||||
.push_info("Usage: QSELECT TYPE|LAYER|COLOR|LINETYPE <value>");
|
||||
.push_info(crate::t!("Usage: QSELECT TYPE|LAYER|COLOR|LINETYPE <value>").as_ref());
|
||||
} else if matched.is_empty() {
|
||||
self.command_line
|
||||
.push_output("QSELECT: no matching entities.");
|
||||
.push_output(crate::t!("QSELECT: no matching entities.").as_ref());
|
||||
} 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()));
|
||||
.push_output(crate::tf!("QSELECT: {} entity(ies) selected.", matched.len()).as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
}
|
||||
|
|
@ -1102,10 +1100,10 @@ impl OpenCADStudio {
|
|||
}
|
||||
let total: usize = counts.values().sum();
|
||||
for (k, n) in &counts {
|
||||
self.command_line.push_output(&format!(" {k}: {n}"));
|
||||
self.command_line.push_output(crate::tf!(" {k}: {n}").as_ref());
|
||||
}
|
||||
self.command_line
|
||||
.push_output(&format!("COUNT: {total} entity(ies) total."));
|
||||
.push_output(crate::tf!("COUNT: {total} entity(ies) total.").as_ref());
|
||||
}
|
||||
|
||||
"DATAEXTRACTION" | "EATTEXT" | "ATTEXT" => {
|
||||
|
|
@ -1142,7 +1140,7 @@ impl OpenCADStudio {
|
|||
};
|
||||
|
||||
if search.is_empty() {
|
||||
self.command_line.push_error("FIND: specify search text.");
|
||||
self.command_line.push_error(crate::t!("FIND: specify search text.").as_ref());
|
||||
} else {
|
||||
let search_lc = search.to_lowercase();
|
||||
let mut count = 0usize;
|
||||
|
|
@ -1170,7 +1168,7 @@ impl OpenCADStudio {
|
|||
};
|
||||
if targets.is_empty() {
|
||||
self.command_line
|
||||
.push_output(&format!("FIND: \"{}\" not found.", search));
|
||||
.push_output(crate::tf!("FIND: \"{}\" not found.", search).as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "FIND/REPLACE");
|
||||
for h in &targets {
|
||||
|
|
@ -1182,34 +1180,34 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"FIND/REPLACE: replaced {} occurrence(s) of \"{}\" → \"{}\".",
|
||||
count, search, rep
|
||||
));
|
||||
).as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
} else {
|
||||
// List mode
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_output(&format!("FIND: \"{}\" not found.", search));
|
||||
.push_output(crate::tf!("FIND: \"{}\" not found.", search).as_ref());
|
||||
} else {
|
||||
for h in &handles {
|
||||
if let Some(e) = self.tabs[i].scene.document.get_entity(*h) {
|
||||
use crate::entities::traits::EntityTypeOps;
|
||||
let txt = e.text_content().unwrap_or_default();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" Handle {:X}: \"{}\"",
|
||||
h.value(),
|
||||
txt
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"FIND: {} match(es) for \"{}\".",
|
||||
handles.len(),
|
||||
search
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1309,12 +1307,12 @@ impl OpenCADStudio {
|
|||
let Some((verb, kind, layer, color, linetype, lt_scale, lw, template_dimstyle)) = info
|
||||
else {
|
||||
self.command_line
|
||||
.push_error("ADDSELECTED: selected object not found.");
|
||||
.push_error(crate::t!("ADDSELECTED: selected object not found.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let Some(verb) = verb else {
|
||||
self.command_line
|
||||
.push_error(&format!("ADDSELECTED: creating a new {kind} is not supported."));
|
||||
.push_error(crate::tf!("ADDSELECTED: creating a new {kind} is not supported.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
|
||||
|
|
@ -1399,9 +1397,9 @@ impl OpenCADStudio {
|
|||
self.ribbon.active_lineweight = lw;
|
||||
self.refresh_properties();
|
||||
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Add Selected: drawing a new {kind} on layer \"{layer}\"."
|
||||
));
|
||||
).as_ref());
|
||||
// Launch the matching draw command (installs its interactive step).
|
||||
self.dispatch_command(verb)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,15 +36,15 @@ impl OpenCADStudio {
|
|||
})
|
||||
.collect();
|
||||
self.command_line
|
||||
.push_output(&format!("Layers: {}", info.join(", ")));
|
||||
.push_output(crate::tf!("Layers: {}", info.join(", ")).as_ref());
|
||||
}
|
||||
"NEW" | "N" => {
|
||||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_error("Usage: LAYER NEW <name>");
|
||||
self.command_line.push_error(crate::t!("Usage: LAYER NEW <name>").as_ref());
|
||||
} else if self.tabs[i].scene.document.layers.contains(&name) {
|
||||
self.command_line
|
||||
.push_error(&format!("LAYER: '{}' already exists.", name));
|
||||
.push_error(crate::tf!("LAYER: '{}' already exists.", name).as_ref());
|
||||
} else {
|
||||
let mut layer = Layer::new(&name);
|
||||
// Allocate a unique handle so the layer survives a
|
||||
|
|
@ -54,7 +54,7 @@ impl OpenCADStudio {
|
|||
self.push_undo_snapshot(i, "LAYER NEW");
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("LAYER: '{}' created.", name));
|
||||
.push_output(crate::tf!("LAYER: '{}' created.", name).as_ref());
|
||||
}
|
||||
}
|
||||
"ON" => {
|
||||
|
|
@ -66,7 +66,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.push_undo_snapshot(i, "LAYER ON");
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("LAYER: layers turned on.");
|
||||
self.command_line.push_output(crate::t!("LAYER: layers turned on.").as_ref());
|
||||
}
|
||||
"OFF" => {
|
||||
for name in &parts[1..] {
|
||||
|
|
@ -76,7 +76,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.push_undo_snapshot(i, "LAYER OFF");
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("LAYER: layers turned off.");
|
||||
self.command_line.push_output(crate::t!("LAYER: layers turned off.").as_ref());
|
||||
}
|
||||
"FREEZE" | "FR" => {
|
||||
for name in &parts[1..] {
|
||||
|
|
@ -86,7 +86,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.push_undo_snapshot(i, "LAYER FREEZE");
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("LAYER: layers frozen.");
|
||||
self.command_line.push_output(crate::t!("LAYER: layers frozen.").as_ref());
|
||||
}
|
||||
"THAW" | "TH" => {
|
||||
for name in &parts[1..] {
|
||||
|
|
@ -96,7 +96,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.push_undo_snapshot(i, "LAYER THAW");
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("LAYER: layers thawed.");
|
||||
self.command_line.push_output(crate::t!("LAYER: layers thawed.").as_ref());
|
||||
}
|
||||
"LOCK" | "LO" => {
|
||||
for name in &parts[1..] {
|
||||
|
|
@ -106,7 +106,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.push_undo_snapshot(i, "LAYER LOCK");
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("LAYER: layers locked.");
|
||||
self.command_line.push_output(crate::t!("LAYER: layers locked.").as_ref());
|
||||
}
|
||||
"UNLOCK" | "UL" => {
|
||||
for name in &parts[1..] {
|
||||
|
|
@ -116,7 +116,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.push_undo_snapshot(i, "LAYER UNLOCK");
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("LAYER: layers unlocked.");
|
||||
self.command_line.push_output(crate::t!("LAYER: layers unlocked.").as_ref());
|
||||
}
|
||||
"COLOR" | "C" => {
|
||||
// LAYER COLOR <name> <aci_index>
|
||||
|
|
@ -137,17 +137,17 @@ impl OpenCADStudio {
|
|||
.invalidate_layer_dependencies(std::slice::from_ref(
|
||||
&layer_name,
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"LAYER: '{}' color set to ACI {}.",
|
||||
layer_name, idx
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("LAYER: '{}' not found.", layer_name));
|
||||
.push_error(crate::tf!("LAYER: '{}' not found.", layer_name).as_ref());
|
||||
}
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("Usage: LAYER COLOR <name> <aci_index>");
|
||||
.push_error(crate::t!("Usage: LAYER COLOR <name> <aci_index>").as_ref());
|
||||
}
|
||||
}
|
||||
"SET" | "S" | "CURRENT" => {
|
||||
|
|
@ -155,15 +155,15 @@ impl OpenCADStudio {
|
|||
if self.tabs[i].scene.document.layers.contains(&name) {
|
||||
self.tabs[i].layers.current_layer = name.clone();
|
||||
self.command_line
|
||||
.push_output(&format!("LAYER: current layer set to '{}'.", name));
|
||||
.push_output(crate::tf!("LAYER: current layer set to '{}'.", name).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("LAYER: '{}' not found.", name));
|
||||
.push_error(crate::tf!("LAYER: '{}' not found.", name).as_ref());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.command_line.push_info(
|
||||
"Usage: LAYER LIST | NEW <name> | ON/OFF/FREEZE/THAW/LOCK/UNLOCK <name> | COLOR <name> <aci> | SET <name>"
|
||||
crate::t!("Usage: LAYER LIST | NEW <name> | ON/OFF/FREEZE/THAW/LOCK/UNLOCK <name> | COLOR <name> <aci> | SET <name>").as_ref()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -202,22 +202,22 @@ impl OpenCADStudio {
|
|||
.map(|u| u.name.clone())
|
||||
.collect();
|
||||
if names.is_empty() {
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Active UCS: {} | No named UCSs defined.",
|
||||
active_name
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Active UCS: {} | Named: {}",
|
||||
active_name,
|
||||
names.join(", ")
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
"SAVE" | "S" => {
|
||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_error("Usage: UCS SAVE <name>");
|
||||
self.command_line.push_error(crate::t!("Usage: UCS SAVE <name>").as_ref());
|
||||
} else {
|
||||
// Save the current active UCS under this name.
|
||||
let ucs = match &self.tabs[i].active_ucs {
|
||||
|
|
@ -231,27 +231,27 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.document.ucss.add_or_replace(ucs);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("UCS '{}' saved.", name));
|
||||
.push_output(crate::tf!("UCS '{}' saved.", name).as_ref());
|
||||
}
|
||||
}
|
||||
"DELETE" | "DEL" | "D" => {
|
||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_error("Usage: UCS DELETE <name>");
|
||||
self.command_line.push_error(crate::t!("Usage: UCS DELETE <name>").as_ref());
|
||||
} else if self.tabs[i].scene.document.ucss.remove(&name).is_some() {
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("UCS '{}' deleted.", name));
|
||||
.push_output(crate::tf!("UCS '{}' deleted.", name).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("UCS '{}' not found.", name));
|
||||
.push_error(crate::tf!("UCS '{}' not found.", name).as_ref());
|
||||
}
|
||||
}
|
||||
"W" | "WORLD" => {
|
||||
self.tabs[i].active_ucs = None;
|
||||
active_changed = true;
|
||||
self.command_line
|
||||
.push_output("UCS reset to World Coordinate System.");
|
||||
.push_output(crate::t!("UCS reset to World Coordinate System.").as_ref());
|
||||
}
|
||||
// UCS ORIGIN x,y,z — shift the active UCS origin, keep axes
|
||||
"ORIGIN" | "O" => {
|
||||
|
|
@ -274,12 +274,12 @@ impl OpenCADStudio {
|
|||
wcs_origin.z as f64,
|
||||
);
|
||||
active_changed = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"UCS origin set to ({:.4}, {:.4}, {:.4}).",
|
||||
wcs_origin.x, wcs_origin.y, wcs_origin.z
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error("Usage: UCS ORIGIN x,y,z");
|
||||
self.command_line.push_error(crate::t!("Usage: UCS ORIGIN x,y,z").as_ref());
|
||||
}
|
||||
}
|
||||
// UCS Z angle — rotate active UCS around its Z axis by degrees
|
||||
|
|
@ -318,9 +318,9 @@ impl OpenCADStudio {
|
|||
self.tabs[i].active_ucs = Some(new_ucs);
|
||||
active_changed = true;
|
||||
self.command_line
|
||||
.push_output(&format!("UCS rotated {:.2}° around Z.", angle_deg));
|
||||
.push_output(crate::tf!("UCS rotated {:.2}° around Z.", angle_deg).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error("Usage: UCS Z <angle_degrees>");
|
||||
self.command_line.push_error(crate::t!("Usage: UCS Z <angle_degrees>").as_ref());
|
||||
}
|
||||
}
|
||||
// UCS X angle — rotate around current UCS X axis
|
||||
|
|
@ -346,9 +346,9 @@ impl OpenCADStudio {
|
|||
ucs.y_axis = Vector3::new(ny.x as f64, ny.y as f64, ny.z as f64);
|
||||
active_changed = true;
|
||||
self.command_line
|
||||
.push_output(&format!("UCS rotated {:.2}° around X.", angle_deg));
|
||||
.push_output(crate::tf!("UCS rotated {:.2}° around X.", angle_deg).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error("Usage: UCS X <angle_degrees>");
|
||||
self.command_line.push_error(crate::t!("Usage: UCS X <angle_degrees>").as_ref());
|
||||
}
|
||||
}
|
||||
// UCS Y angle — rotate around current UCS Y axis
|
||||
|
|
@ -374,9 +374,9 @@ impl OpenCADStudio {
|
|||
ucs.x_axis = Vector3::new(nx.x as f64, nx.y as f64, nx.z as f64);
|
||||
active_changed = true;
|
||||
self.command_line
|
||||
.push_output(&format!("UCS rotated {:.2}° around Y.", angle_deg));
|
||||
.push_output(crate::tf!("UCS rotated {:.2}° around Y.", angle_deg).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error("Usage: UCS Y <angle_degrees>");
|
||||
self.command_line.push_error(crate::t!("Usage: UCS Y <angle_degrees>").as_ref());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
|
@ -386,12 +386,12 @@ impl OpenCADStudio {
|
|||
self.tabs[i].active_ucs = Some(named);
|
||||
active_changed = true;
|
||||
self.command_line
|
||||
.push_output(&format!("UCS '{}' activated.", name));
|
||||
.push_output(crate::tf!("UCS '{}' activated.", name).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"UCS '{}' not found. Usage: UCS LIST | SAVE <name> | DELETE <name> | W | ORIGIN x,y,z | X/Y/Z <angle>",
|
||||
name
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -429,16 +429,16 @@ impl OpenCADStudio {
|
|||
"" | "CURRENT" | "C" => {
|
||||
let r = self.tabs[i].scene.viewcube_ucs_mat();
|
||||
self.plan_snap(i, r);
|
||||
self.command_line.push_output("PLAN: current UCS plan view.");
|
||||
self.command_line.push_output(crate::t!("PLAN: current UCS plan view.").as_ref());
|
||||
}
|
||||
"WORLD" | "W" => {
|
||||
self.plan_snap(i, glam::Mat4::IDENTITY);
|
||||
self.command_line.push_output("PLAN: world plan view.");
|
||||
self.command_line.push_output(crate::t!("PLAN: world plan view.").as_ref());
|
||||
}
|
||||
"UCS" | "U" => {
|
||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("");
|
||||
if name.is_empty() {
|
||||
self.command_line.push_info("Usage: PLAN UCS <name>");
|
||||
self.command_line.push_info(crate::t!("Usage: PLAN UCS <name>").as_ref());
|
||||
} else {
|
||||
let ucs = self.tabs[i]
|
||||
.scene
|
||||
|
|
@ -452,20 +452,20 @@ impl OpenCADStudio {
|
|||
let r = crate::app::helpers::UcsXform::from_ucs(&u)
|
||||
.rotation_mat();
|
||||
self.plan_snap(i, r);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"PLAN: plan view of UCS '{}'.",
|
||||
u.name
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
None => self
|
||||
.command_line
|
||||
.push_error(&format!("UCS '{name}' not found.")),
|
||||
.push_error(crate::tf!("UCS '{name}' not found.").as_ref()),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => self
|
||||
.command_line
|
||||
.push_info("Usage: PLAN [CURRENT / UCS <name> / WORLD]"),
|
||||
.push_info(crate::t!("Usage: PLAN [CURRENT / UCS <name> / WORLD]").as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -497,50 +497,50 @@ impl OpenCADStudio {
|
|||
.map(|v| v.name.clone())
|
||||
.collect();
|
||||
if views.is_empty() {
|
||||
self.command_line.push_output("No named views saved.");
|
||||
self.command_line.push_output(crate::t!("No named views saved.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_output(&format!("Named views: {}", views.join(", ")));
|
||||
.push_output(crate::tf!("Named views: {}", views.join(", ")).as_ref());
|
||||
}
|
||||
}
|
||||
"SAVE" | "S" => {
|
||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_error("Usage: VIEW SAVE <name>");
|
||||
self.command_line.push_error(crate::t!("Usage: VIEW SAVE <name>").as_ref());
|
||||
} else {
|
||||
let new_view = self.tabs[i].scene.current_as_named_view(&name);
|
||||
self.tabs[i].scene.document.views.add_or_replace(new_view);
|
||||
self.command_line
|
||||
.push_output(&format!("View '{}' saved.", name));
|
||||
.push_output(crate::tf!("View '{}' saved.", name).as_ref());
|
||||
}
|
||||
}
|
||||
"DELETE" | "DEL" | "D" => {
|
||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_error("Usage: VIEW DELETE <name>");
|
||||
self.command_line.push_error(crate::t!("Usage: VIEW DELETE <name>").as_ref());
|
||||
} else {
|
||||
if self.tabs[i].scene.document.views.remove(&name).is_some() {
|
||||
self.command_line
|
||||
.push_output(&format!("View '{}' deleted.", name));
|
||||
.push_output(crate::tf!("View '{}' deleted.", name).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("View '{}' not found.", name));
|
||||
.push_error(crate::tf!("View '{}' not found.", name).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
"RESTORE" | "R" => {
|
||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_error("Usage: VIEW RESTORE <name>");
|
||||
self.command_line.push_error(crate::t!("Usage: VIEW RESTORE <name>").as_ref());
|
||||
} else {
|
||||
let found = self.tabs[i].scene.document.views.get(&name).cloned();
|
||||
if let Some(v) = found {
|
||||
self.tabs[i].scene.restore_named_view(&v);
|
||||
self.command_line
|
||||
.push_output(&format!("View '{}' restored.", v.name));
|
||||
.push_output(crate::tf!("View '{}' restored.", v.name).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("View '{}' not found.", name));
|
||||
.push_error(crate::tf!("View '{}' not found.", name).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -573,10 +573,10 @@ impl OpenCADStudio {
|
|||
if let Some(v) = found {
|
||||
self.tabs[i].scene.restore_named_view(&v);
|
||||
self.command_line
|
||||
.push_output(&format!("View '{}' restored.", v.name));
|
||||
.push_output(crate::tf!("View '{}' restored.", v.name).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(
|
||||
"Usage: VIEW LIST | VIEW SAVE <name> | VIEW RESTORE <name> | VIEW DELETE <name>"
|
||||
crate::t!("Usage: VIEW LIST | VIEW SAVE <name> | VIEW RESTORE <name> | VIEW DELETE <name>").as_ref()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -614,16 +614,16 @@ impl OpenCADStudio {
|
|||
})
|
||||
.collect();
|
||||
if styles.is_empty() {
|
||||
self.command_line.push_output("No table styles.");
|
||||
self.command_line.push_output(crate::t!("No table styles.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_output(&format!("TableStyles:\n {}", styles.join("\n ")));
|
||||
.push_output(crate::tf!("TableStyles:\n {}", styles.join("\n ")).as_ref());
|
||||
}
|
||||
}
|
||||
"NEW" | "N" => {
|
||||
let name = parts.get(1).copied().unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_error("Usage: TABLESTYLE NEW <name>");
|
||||
self.command_line.push_error(crate::t!("Usage: TABLESTYLE NEW <name>").as_ref());
|
||||
} else {
|
||||
let doc = &self.tabs[i].scene.document;
|
||||
let exists = doc.objects.values().any(|o| {
|
||||
|
|
@ -631,7 +631,7 @@ impl OpenCADStudio {
|
|||
});
|
||||
if exists {
|
||||
self.command_line
|
||||
.push_error(&format!("TABLESTYLE: '{}' already exists.", name));
|
||||
.push_error(crate::tf!("TABLESTYLE: '{}' already exists.", name).as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "TABLESTYLE NEW");
|
||||
let mut style = TableStyle::standard();
|
||||
|
|
@ -647,13 +647,13 @@ impl OpenCADStudio {
|
|||
.insert(nh, ObjectType::TableStyle(style));
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("TABLESTYLE: '{}' created.", name));
|
||||
.push_output(crate::tf!("TABLESTYLE: '{}' created.", name).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_error("Usage: TABLESTYLE [LIST|NEW <name>]");
|
||||
.push_error(crate::t!("Usage: TABLESTYLE [LIST|NEW <name>]").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -693,16 +693,16 @@ impl OpenCADStudio {
|
|||
})
|
||||
.collect();
|
||||
if styles.is_empty() {
|
||||
self.command_line.push_output("No multiline styles.");
|
||||
self.command_line.push_output(crate::t!("No multiline styles.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_output(&format!("MLineStyles:\n {}", styles.join("\n ")));
|
||||
.push_output(crate::tf!("MLineStyles:\n {}", styles.join("\n ")).as_ref());
|
||||
}
|
||||
}
|
||||
"NEW" | "N" => {
|
||||
let name = parts.get(1).copied().unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_error("Usage: MLSTYLE NEW <name>");
|
||||
self.command_line.push_error(crate::t!("Usage: MLSTYLE NEW <name>").as_ref());
|
||||
} else {
|
||||
let doc = &self.tabs[i].scene.document;
|
||||
let exists = doc.objects.values().any(|o| {
|
||||
|
|
@ -710,7 +710,7 @@ impl OpenCADStudio {
|
|||
});
|
||||
if exists {
|
||||
self.command_line
|
||||
.push_error(&format!("MLSTYLE: '{}' already exists.", name));
|
||||
.push_error(crate::tf!("MLSTYLE: '{}' already exists.", name).as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "MLSTYLE NEW");
|
||||
let mut style = MLineStyle::standard();
|
||||
|
|
@ -726,14 +726,14 @@ impl OpenCADStudio {
|
|||
.insert(nh, ObjectType::MLineStyle(style));
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("MLSTYLE: '{}' created.", name));
|
||||
.push_output(crate::tf!("MLSTYLE: '{}' created.", name).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
"SET" | "S" => {
|
||||
let name = parts.get(1).copied().unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_error("Usage: MLSTYLE SET <name>");
|
||||
self.command_line.push_error(crate::t!("Usage: MLSTYLE SET <name>").as_ref());
|
||||
} else {
|
||||
let doc = &self.tabs[i].scene.document;
|
||||
let exists = doc.objects.values().any(|o| {
|
||||
|
|
@ -743,13 +743,13 @@ impl OpenCADStudio {
|
|||
self.push_undo_snapshot(i, "MLSTYLE SET");
|
||||
self.tabs[i].scene.document.header.multiline_style = name.clone();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"MLSTYLE: current style set to '{}'.",
|
||||
name
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("MLSTYLE: '{}' not found.", name));
|
||||
.push_error(crate::tf!("MLSTYLE: '{}' not found.", name).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -757,7 +757,7 @@ impl OpenCADStudio {
|
|||
let name = parts.get(1).copied().unwrap_or("").to_string();
|
||||
if name.is_empty() || name.eq_ignore_ascii_case("Standard") {
|
||||
self.command_line
|
||||
.push_error("Cannot delete the Standard style.");
|
||||
.push_error(crate::t!("Cannot delete the Standard style.").as_ref());
|
||||
} else {
|
||||
let doc = &self.tabs[i].scene.document;
|
||||
let handle = doc.objects.iter().find_map(|(&h, o)| {
|
||||
|
|
@ -776,16 +776,16 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.document.objects.remove(&h);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("MLSTYLE: '{}' deleted.", name));
|
||||
.push_output(crate::tf!("MLSTYLE: '{}' deleted.", name).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("MLSTYLE: '{}' not found.", name));
|
||||
.push_error(crate::tf!("MLSTYLE: '{}' not found.", name).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_error("Usage: MLSTYLE [LIST|NEW <name>|SET <name>|DEL <name>]");
|
||||
.push_error(crate::t!("Usage: MLSTYLE [LIST|NEW <name>|SET <name>|DEL <name>]").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -813,19 +813,19 @@ impl OpenCADStudio {
|
|||
.map(|s| format!("{}(txt:{:.2} asz:{:.2})", s.name, s.dimtxt, s.dimasz))
|
||||
.collect();
|
||||
if styles.is_empty() {
|
||||
self.command_line.push_output("No dim styles defined.");
|
||||
self.command_line.push_output(crate::t!("No dim styles defined.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_output(&format!("DimStyles: {}", styles.join(", ")));
|
||||
.push_output(crate::tf!("DimStyles: {}", styles.join(", ")).as_ref());
|
||||
}
|
||||
}
|
||||
"NEW" | "N" => {
|
||||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_error("Usage: DIMSTYLE NEW <name>");
|
||||
self.command_line.push_error(crate::t!("Usage: DIMSTYLE NEW <name>").as_ref());
|
||||
} else if self.tabs[i].scene.document.dim_styles.contains(&name) {
|
||||
self.command_line
|
||||
.push_error(&format!("DIMSTYLE: '{}' already exists.", name));
|
||||
.push_error(crate::tf!("DIMSTYLE: '{}' already exists.", name).as_ref());
|
||||
} else {
|
||||
let undo = self.begin_dim_style_undo(
|
||||
i,
|
||||
|
|
@ -837,7 +837,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.commit_dim_style_undo(i, undo);
|
||||
self.command_line
|
||||
.push_output(&format!("DIMSTYLE: '{}' created.", name));
|
||||
.push_output(crate::tf!("DIMSTYLE: '{}' created.", name).as_ref());
|
||||
}
|
||||
}
|
||||
"SET" | "S" => {
|
||||
|
|
@ -896,9 +896,9 @@ impl OpenCADStudio {
|
|||
ds.dimfxl = val;
|
||||
}
|
||||
_ => {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"DIMSTYLE: unknown property '{}'. Try: dimtxt dimasz dimdli dimexo dimexe dimgap dimscale dimlfac dimdle dimcen dimtsz", prop
|
||||
));
|
||||
).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
}
|
||||
|
|
@ -906,16 +906,16 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene
|
||||
.invalidate_dim_style_dependencies(&style_name);
|
||||
self.commit_dim_style_undo(i, undo);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"DIMSTYLE: '{style_name}'.{prop} = {val:.3}"
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("DIMSTYLE: '{}' not found.", style_name));
|
||||
.push_error(crate::tf!("DIMSTYLE: '{}' not found.", style_name).as_ref());
|
||||
}
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("Usage: DIMSTYLE SET <name> <property> <value>");
|
||||
.push_error(crate::t!("Usage: DIMSTYLE SET <name> <property> <value>").as_ref());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
|
@ -956,28 +956,28 @@ impl OpenCADStudio {
|
|||
let current = &self.tabs[i].active_mleader_style;
|
||||
if styles.is_empty() {
|
||||
self.command_line
|
||||
.push_output(&format!("MLeader styles: (none) active: {current}"));
|
||||
.push_output(crate::tf!("MLeader styles: (none) active: {current}").as_ref());
|
||||
} else {
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"MLeader styles: {} active: {current}",
|
||||
styles.join(", ")
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
"NEW" | "N" => {
|
||||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line
|
||||
.push_error("Usage: MLEADERSTYLE NEW <name>");
|
||||
.push_error(crate::t!("Usage: MLEADERSTYLE NEW <name>").as_ref());
|
||||
} else {
|
||||
let already_exists = self.tabs[i].scene.document.objects.values().any(
|
||||
|o| matches!(o, ObjectType::MultiLeaderStyle(s) if s.name == name),
|
||||
);
|
||||
if already_exists {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"MLEADERSTYLE: '{}' already exists.",
|
||||
name
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
let handle = self.tabs[i].scene.document.allocate_handle();
|
||||
let mut style = MultiLeaderStyle::new(&name);
|
||||
|
|
@ -990,7 +990,7 @@ impl OpenCADStudio {
|
|||
self.push_undo_snapshot(i, "MLEADERSTYLE NEW");
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("MLEADERSTYLE: '{}' created.", name));
|
||||
.push_output(crate::tf!("MLEADERSTYLE: '{}' created.", name).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1032,52 +1032,52 @@ impl OpenCADStudio {
|
|||
s.landing_gap = val;
|
||||
}
|
||||
_ => {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"MLEADERSTYLE: unknown property '{}'. Try: text_height arrowhead_size landing_distance landing_gap", prop
|
||||
));
|
||||
).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
}
|
||||
self.push_undo_snapshot(i, "MLEADERSTYLE SET");
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"MLEADERSTYLE: '{style_name}'.{prop} = {val:.3}"
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"MLEADERSTYLE: '{}' not found.",
|
||||
style_name
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("Usage: MLEADERSTYLE SET <name> <property> <value>");
|
||||
.push_error(crate::t!("Usage: MLEADERSTYLE SET <name> <property> <value>").as_ref());
|
||||
}
|
||||
}
|
||||
"CURRENT" | "C" | "ACTIVE" => {
|
||||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Current MLeader style: {}",
|
||||
self.tabs[i].active_mleader_style
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
let exists = name == "Standard" || self.tabs[i].scene.document.objects.values()
|
||||
.any(|o| matches!(o, ObjectType::MultiLeaderStyle(s) if s.name == name));
|
||||
if exists {
|
||||
self.tabs[i].active_mleader_style = name.clone();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"MLEADERSTYLE: current style set to '{name}'."
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("MLEADERSTYLE: '{}' not found.", name));
|
||||
.push_error(crate::tf!("MLEADERSTYLE: '{}' not found.", name).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.command_line.push_info(
|
||||
"Usage: MLEADERSTYLE LIST | NEW <name> | SET <name> <prop> <val> | CURRENT [<name>]"
|
||||
crate::t!("Usage: MLEADERSTYLE LIST | NEW <name> | SET <name> <prop> <val> | CURRENT [<name>]").as_ref()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1117,10 +1117,10 @@ impl OpenCADStudio {
|
|||
})
|
||||
.collect();
|
||||
if styles.is_empty() {
|
||||
self.command_line.push_output("No text styles defined.");
|
||||
self.command_line.push_output(crate::t!("No text styles defined.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_output(&format!("Text styles: {}", styles.join(" | ")));
|
||||
.push_output(crate::tf!("Text styles: {}", styles.join(" | ")).as_ref());
|
||||
}
|
||||
}
|
||||
"SET" | "S" => {
|
||||
|
|
@ -1128,20 +1128,20 @@ impl OpenCADStudio {
|
|||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("");
|
||||
if self.tabs[i].scene.document.text_styles.get(name).is_some() {
|
||||
self.command_line
|
||||
.push_output(&format!("{prefix}: active style set to '{name}'."));
|
||||
.push_output(crate::tf!("{prefix}: active style set to '{name}'.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("{prefix}: style '{name}' not found."));
|
||||
.push_error(crate::tf!("{prefix}: style '{name}' not found.").as_ref());
|
||||
}
|
||||
}
|
||||
"NEW" | "N" => {
|
||||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line
|
||||
.push_error(&format!("Usage: {prefix} NEW <name>"));
|
||||
.push_error(crate::tf!("Usage: {prefix} NEW <name>").as_ref());
|
||||
} else if self.tabs[i].scene.document.text_styles.contains(&name) {
|
||||
self.command_line
|
||||
.push_error(&format!("{prefix}: style '{name}' already exists."));
|
||||
.push_error(crate::tf!("{prefix}: style '{name}' already exists.").as_ref());
|
||||
} else {
|
||||
let undo = self.begin_text_style_undo(
|
||||
i,
|
||||
|
|
@ -1153,7 +1153,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.commit_text_style_undo(i, undo);
|
||||
self.command_line
|
||||
.push_output(&format!("{prefix}: style '{name}' created."));
|
||||
.push_output(crate::tf!("{prefix}: style '{name}' created.").as_ref());
|
||||
}
|
||||
}
|
||||
"FONT" | "F" => {
|
||||
|
|
@ -1162,7 +1162,7 @@ impl OpenCADStudio {
|
|||
let font = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||
if style_name.is_empty() || font.is_empty() {
|
||||
self.command_line
|
||||
.push_error(&format!("Usage: {prefix} FONT <style> <font_file>"));
|
||||
.push_error(crate::tf!("Usage: {prefix} FONT <style> <font_file>").as_ref());
|
||||
} else {
|
||||
let undo = self.begin_text_style_undo(
|
||||
i,
|
||||
|
|
@ -1178,12 +1178,12 @@ impl OpenCADStudio {
|
|||
.scene
|
||||
.invalidate_text_style_dependencies(&style_name);
|
||||
self.commit_text_style_undo(i, undo);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{prefix}: '{style_name}' font set to '{font}'."
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("{prefix}: style '{style_name}' not found."));
|
||||
.push_error(crate::tf!("{prefix}: style '{style_name}' not found.").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1206,17 +1206,17 @@ impl OpenCADStudio {
|
|||
.scene
|
||||
.invalidate_text_style_dependencies(&style_name);
|
||||
self.commit_text_style_undo(i, undo);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{prefix}: '{style_name}' width factor set to {factor:.3}."
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"{prefix}: style '{style_name}' not found."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("Usage: {prefix} WIDTH <style> <factor>"));
|
||||
.push_error(crate::tf!("Usage: {prefix} WIDTH <style> <factor>").as_ref());
|
||||
}
|
||||
}
|
||||
"OBLIQUE" => {
|
||||
|
|
@ -1238,24 +1238,24 @@ impl OpenCADStudio {
|
|||
.scene
|
||||
.invalidate_text_style_dependencies(&style_name);
|
||||
self.commit_text_style_undo(i, undo);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{prefix}: '{style_name}' oblique angle set to {deg:.1}°."
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"{prefix}: style '{style_name}' not found."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
} else {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"Usage: {prefix} OBLIQUE <style> <angle_degrees>"
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"Usage: {prefix} LIST | NEW <name> | FONT <style> <file> | WIDTH <style> <factor> | OBLIQUE <style> <angle>"
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.commit_layer_undo(i, undo);
|
||||
self.refresh_layer_panel();
|
||||
self.command_line.push_info("Layer(s) turned off.");
|
||||
self.command_line.push_info(crate::t!("Layer(s) turned off.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.commit_layer_undo(i, undo);
|
||||
self.refresh_layer_panel();
|
||||
self.command_line.push_info("Layer(s) frozen.");
|
||||
self.command_line.push_info(crate::t!("Layer(s) frozen.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ impl OpenCADStudio {
|
|||
cmd if cmd.starts_with("LAYDEL ") => {
|
||||
let name = cmd.trim_start_matches("LAYDEL").trim();
|
||||
if name.is_empty() {
|
||||
self.command_line.push_info("Usage: LAYDEL <layer name>");
|
||||
self.command_line.push_info(crate::t!("Usage: LAYDEL <layer name>").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
let resolved = self.tabs[i]
|
||||
|
|
@ -100,12 +100,12 @@ impl OpenCADStudio {
|
|||
.map(|s| s.to_string());
|
||||
let Some(layer) = resolved else {
|
||||
self.command_line
|
||||
.push_error(&format!("LAYDEL: no layer named \"{name}\"."));
|
||||
.push_error(crate::tf!("LAYDEL: no layer named \"{name}\".").as_ref());
|
||||
return Some(Task::none());
|
||||
};
|
||||
if layer == "0" {
|
||||
self.command_line
|
||||
.push_error("LAYDEL: layer \"0\" cannot be deleted.");
|
||||
.push_error(crate::t!("LAYDEL: layer \"0\" cannot be deleted.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
if layer.eq_ignore_ascii_case(&self.tabs[i].active_layer) {
|
||||
|
|
@ -130,9 +130,9 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.bump_geometry();
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_layer_panel();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"LAYDEL: deleted layer \"{layer}\" and {n} object(s)."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
// LAYMRG <source> <target> — move every object from <source> onto
|
||||
|
|
@ -152,7 +152,7 @@ impl OpenCADStudio {
|
|||
let parts: Vec<&str> = rest.split_whitespace().collect();
|
||||
if parts.len() != 2 {
|
||||
self.command_line
|
||||
.push_info("Usage: LAYMRG <source layer> <target layer>");
|
||||
.push_info(crate::t!("Usage: LAYMRG <source layer> <target layer>").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
let keys: Vec<String> = self.tabs[i]
|
||||
|
|
@ -172,17 +172,17 @@ impl OpenCADStudio {
|
|||
.cloned();
|
||||
let (Some(src), Some(dst)) = (src, dst) else {
|
||||
self.command_line
|
||||
.push_error("LAYMRG: source and target layers must both exist.");
|
||||
.push_error(crate::t!("LAYMRG: source and target layers must both exist.").as_ref());
|
||||
return Some(Task::none());
|
||||
};
|
||||
if src == dst {
|
||||
self.command_line
|
||||
.push_error("LAYMRG: source and target are the same layer.");
|
||||
.push_error(crate::t!("LAYMRG: source and target are the same layer.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
if src == "0" {
|
||||
self.command_line
|
||||
.push_error("LAYMRG: layer \"0\" cannot be merged away.");
|
||||
.push_error(crate::t!("LAYMRG: layer \"0\" cannot be merged away.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
if src.eq_ignore_ascii_case(&self.tabs[i].active_layer) {
|
||||
|
|
@ -206,9 +206,9 @@ impl OpenCADStudio {
|
|||
.invalidate_layer_dependencies(std::slice::from_ref(&dst));
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_layer_panel();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"LAYMRG: merged \"{src}\" into \"{dst}\" ({moved} object(s))."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
// LAYERSTATE — save / restore named snapshots of all layer states
|
||||
|
|
@ -241,12 +241,12 @@ impl OpenCADStudio {
|
|||
states.iter().map(|state| state.name.as_str()).collect();
|
||||
names.sort_unstable();
|
||||
self.command_line
|
||||
.push_output(&format!("Saved layer states: {}", names.join(", ")));
|
||||
.push_output(crate::tf!("Saved layer states: {}", names.join(", ")).as_ref());
|
||||
}
|
||||
}
|
||||
"SAVE" | "S" => {
|
||||
if arg.is_empty() {
|
||||
self.command_line.push_info("Usage: LAYERSTATE SAVE <name>");
|
||||
self.command_line.push_info(crate::t!("Usage: LAYERSTATE SAVE <name>").as_ref());
|
||||
} else {
|
||||
let description = self.tabs[i]
|
||||
.scene
|
||||
|
|
@ -261,17 +261,17 @@ impl OpenCADStudio {
|
|||
.capture_layer_state(arg, description);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("LAYERSTATE: saved \"{arg}\"."));
|
||||
.push_output(crate::tf!("LAYERSTATE: saved \"{arg}\".").as_ref());
|
||||
}
|
||||
}
|
||||
"RESTORE" | "R" => {
|
||||
if arg.is_empty() {
|
||||
self.command_line
|
||||
.push_info("Usage: LAYERSTATE RESTORE <name>");
|
||||
.push_info(crate::t!("Usage: LAYERSTATE RESTORE <name>").as_ref());
|
||||
} else if self.tabs[i].scene.document.layer_state(arg).is_none() {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"LAYERSTATE: no saved state named \"{arg}\"."
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
let names: Vec<String> = self.tabs[i]
|
||||
.scene
|
||||
|
|
@ -295,30 +295,30 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.invalidate_layer_dependencies(&names);
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_layer_panel();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"LAYERSTATE: restored \"{arg}\" ({n} layer(s))."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
"DELETE" | "D" => {
|
||||
if arg.is_empty() {
|
||||
self.command_line
|
||||
.push_info("Usage: LAYERSTATE DELETE <name>");
|
||||
.push_info(crate::t!("Usage: LAYERSTATE DELETE <name>").as_ref());
|
||||
} else if self.tabs[i].scene.document.layer_state(arg).is_none() {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"LAYERSTATE: no saved state named \"{arg}\"."
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "LAYERSTATE DELETE");
|
||||
self.tabs[i].scene.document.delete_layer_state(arg);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("LAYERSTATE: deleted \"{arg}\"."));
|
||||
.push_output(crate::tf!("LAYERSTATE: deleted \"{arg}\".").as_ref());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_info("Usage: LAYERSTATE SAVE|RESTORE|DELETE <name> | ? (list)");
|
||||
.push_info(crate::t!("Usage: LAYERSTATE SAVE|RESTORE|DELETE <name> | ? (list)").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -353,7 +353,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.commit_layer_undo(i, undo);
|
||||
self.refresh_layer_panel();
|
||||
self.command_line.push_info("Layer(s) locked.");
|
||||
self.command_line.push_info(crate::t!("Layer(s) locked.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -385,7 +385,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].layers.current_layer = layer.clone();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_info(&format!("Current layer set to \"{layer}\"."));
|
||||
.push_info(crate::tf!("Current layer set to \"{layer}\".").as_ref());
|
||||
self.refresh_layer_panel();
|
||||
}
|
||||
}
|
||||
|
|
@ -408,7 +408,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.commit_layer_undo(i, undo);
|
||||
self.refresh_layer_panel();
|
||||
self.command_line.push_info("All layers turned on.");
|
||||
self.command_line.push_info(crate::t!("All layers turned on.").as_ref());
|
||||
}
|
||||
|
||||
"LAYTHW" => {
|
||||
|
|
@ -429,7 +429,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.commit_layer_undo(i, undo);
|
||||
self.refresh_layer_panel();
|
||||
self.command_line.push_info("All layers thawed.");
|
||||
self.command_line.push_info(crate::t!("All layers thawed.").as_ref());
|
||||
}
|
||||
|
||||
"LAYULK" => {
|
||||
|
|
@ -462,7 +462,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.commit_layer_undo(i, undo);
|
||||
self.refresh_layer_panel();
|
||||
self.command_line.push_info("Layer(s) unlocked.");
|
||||
self.command_line.push_info(crate::t!("Layer(s) unlocked.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -476,7 +476,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if sel_layers.is_empty() {
|
||||
self.command_line
|
||||
.push_error("LAYISO: select entities on the layers to isolate first.");
|
||||
.push_error(crate::t!("LAYISO: select entities on the layers to isolate first.").as_ref());
|
||||
} else {
|
||||
let names: Vec<String> = self.tabs[i]
|
||||
.scene
|
||||
|
|
@ -498,7 +498,7 @@ impl OpenCADStudio {
|
|||
self.commit_layer_undo(i, undo);
|
||||
self.refresh_layer_panel();
|
||||
self.command_line
|
||||
.push_info(&format!("LAYISO: isolated {} layer(s).", sel_layers.len()));
|
||||
.push_info(crate::tf!("LAYISO: isolated {} layer(s).", sel_layers.len()).as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -506,7 +506,7 @@ impl OpenCADStudio {
|
|||
"ISOLATEOBJECTS" => {
|
||||
if self.tabs[i].scene.selected.is_empty() {
|
||||
self.command_line
|
||||
.push_error("ISOLATEOBJECTS: select the objects to isolate first.");
|
||||
.push_error(crate::t!("ISOLATEOBJECTS: select the objects to isolate first.").as_ref());
|
||||
} else {
|
||||
let n = self.tabs[i].scene.selected.len();
|
||||
let before = self.tabs[i].scene.object_isolation.clone();
|
||||
|
|
@ -519,9 +519,9 @@ impl OpenCADStudio {
|
|||
before,
|
||||
selected_before,
|
||||
);
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"Isolated {n} object(s). UNISOLATEOBJECTS to restore."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -529,7 +529,7 @@ impl OpenCADStudio {
|
|||
"HIDEOBJECTS" => {
|
||||
if self.tabs[i].scene.selected.is_empty() {
|
||||
self.command_line
|
||||
.push_error("HIDEOBJECTS: select the objects to hide first.");
|
||||
.push_error(crate::t!("HIDEOBJECTS: select the objects to hide first.").as_ref());
|
||||
} else {
|
||||
let n = self.tabs[i].scene.selected.len();
|
||||
let before = self.tabs[i].scene.object_isolation.clone();
|
||||
|
|
@ -544,7 +544,7 @@ impl OpenCADStudio {
|
|||
);
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_info(&format!("Hid {n} object(s). UNISOLATEOBJECTS to restore."));
|
||||
.push_info(crate::tf!("Hid {n} object(s). UNISOLATEOBJECTS to restore.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -562,9 +562,9 @@ impl OpenCADStudio {
|
|||
selected_before,
|
||||
);
|
||||
self.command_line
|
||||
.push_info("Isolation ended — all objects shown.");
|
||||
.push_info(crate::t!("Isolation ended — all objects shown.").as_ref());
|
||||
} else {
|
||||
self.command_line.push_info("No hidden objects.");
|
||||
self.command_line.push_info(crate::t!("No hidden objects.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -588,7 +588,7 @@ impl OpenCADStudio {
|
|||
self.commit_layer_undo(i, undo);
|
||||
self.refresh_layer_panel();
|
||||
self.command_line
|
||||
.push_info("LAYUNISO: all layers restored.");
|
||||
.push_info(crate::t!("LAYUNISO: all layers restored.").as_ref());
|
||||
}
|
||||
|
||||
"LAYMATCH" | "LAYMCH" => {
|
||||
|
|
@ -653,10 +653,10 @@ impl OpenCADStudio {
|
|||
self.commit_group_undo(i, undo);
|
||||
if count > 0 {
|
||||
self.command_line
|
||||
.push_info(&format!("{} group(s) dissolved.", count));
|
||||
.push_info(crate::tf!("{} group(s) dissolved.", count).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_info("No groups found for selected objects.");
|
||||
.push_info(crate::t!("No groups found for selected objects.").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ impl OpenCADStudio {
|
|||
// rather than keeping a second, blunter copy (#388, #389).
|
||||
if self.tabs[i].is_start && !start_allowed(cmd) {
|
||||
self.command_line
|
||||
.push_info("No drawing open. Use NEW or OPEN to start a drawing.");
|
||||
.push_info(crate::t!("No drawing open. Use NEW or OPEN to start a drawing.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.command_line
|
||||
.push_error(&format!("Unknown command: {cmd}"));
|
||||
.push_error(crate::tf!("Unknown command: {cmd}").as_ref());
|
||||
self.finish_dispatch(cmd)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ impl OpenCADStudio {
|
|||
"" => {
|
||||
let c = self.tabs[i].scene.document.header.current_entity_color;
|
||||
self.command_line
|
||||
.push_output(&format!("Current object colour: {}", describe(&c)));
|
||||
.push_output(crate::tf!("Current object colour: {}", describe(&c)).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
"BYLAYER" => Some(Color::ByLayer),
|
||||
|
|
@ -58,7 +58,7 @@ impl OpenCADStudio {
|
|||
self.ribbon.active_color = c;
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("Object colour set to {}.", describe(&c)));
|
||||
.push_output(crate::tf!("Object colour set to {}.", describe(&c)).as_ref());
|
||||
}
|
||||
None => {
|
||||
self.command_line.push_error(
|
||||
|
|
@ -96,10 +96,10 @@ impl OpenCADStudio {
|
|||
.map(|lt| format!("{} ({})", lt.name, lt.description))
|
||||
.collect();
|
||||
if ltypes.is_empty() {
|
||||
self.command_line.push_output("No linetypes defined.");
|
||||
self.command_line.push_output(crate::t!("No linetypes defined.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_output(&format!("Linetypes: {}", ltypes.join(", ")));
|
||||
.push_output(crate::tf!("Linetypes: {}", ltypes.join(", ")).as_ref());
|
||||
}
|
||||
}
|
||||
// Set the current linetype applied to newly drawn entities.
|
||||
|
|
@ -107,7 +107,7 @@ impl OpenCADStudio {
|
|||
let name = parts.get(1).copied().unwrap_or("");
|
||||
if name.is_empty() {
|
||||
self.command_line
|
||||
.push_info("Usage: LINETYPE SET <name | ByLayer | ByBlock>");
|
||||
.push_info(crate::t!("Usage: LINETYPE SET <name | ByLayer | ByBlock>").as_ref());
|
||||
} else {
|
||||
let canon = if name.eq_ignore_ascii_case("BYLAYER") {
|
||||
Some(("ByLayer".to_string(), acadrust::types::Handle::NULL))
|
||||
|
|
@ -129,19 +129,19 @@ impl OpenCADStudio {
|
|||
h.current_linetype_handle = handle;
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("Current linetype set to {nm}."));
|
||||
.push_output(crate::tf!("Current linetype set to {nm}.").as_ref());
|
||||
}
|
||||
None => {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"LINETYPE: \"{name}\" is not loaded. Use LINETYPE LIST to see available linetypes."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_info("Usage: LINETYPE LIST | SET <name>");
|
||||
.push_info(crate::t!("Usage: LINETYPE LIST | SET <name>").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -177,9 +177,9 @@ impl OpenCADStudio {
|
|||
let do_lts = all || matches!(sub.as_str(), "LINETYPES" | "LT");
|
||||
let do_blocks = all || matches!(sub.as_str(), "BLOCKS" | "BLOCK" | "B");
|
||||
if !(do_layers || do_styles || do_lts || do_blocks) {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"PURGE: unknown option \"{sub}\" — use ALL, Blocks, LAyers, LineTypes or STyles."
|
||||
));
|
||||
).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
|
||||
|
|
@ -560,13 +560,13 @@ impl OpenCADStudio {
|
|||
if n_sortents > 0 {
|
||||
parts.push(format!("{n_sortents} stale draw-order table(s)"));
|
||||
}
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"PURGE: {} item(s) removed — {}.",
|
||||
purged + n_sortents,
|
||||
parts.join(", ")
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line.push_output("PURGE: nothing to purge.");
|
||||
self.command_line.push_output(crate::t!("PURGE: nothing to purge.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -610,7 +610,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("CHPROP: no entities selected.");
|
||||
.push_error(crate::t!("CHPROP: no entities selected.").as_ref());
|
||||
} else {
|
||||
// Validate value early to give clear errors
|
||||
let color_val: Option<acadrust::types::Color> = if prop == "COLOR" {
|
||||
|
|
@ -640,10 +640,10 @@ impl OpenCADStudio {
|
|||
|| (prop == "LTSCALE" && ltscale_val.is_none())
|
||||
|| (prop == "TRANSPARENCY" && transparency_val.is_none())
|
||||
{
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"CHPROP: invalid value '{}' for {}.",
|
||||
value, prop
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
let mut changed = 0usize;
|
||||
for handle in &handles {
|
||||
|
|
@ -673,9 +673,9 @@ impl OpenCADStudio {
|
|||
changed += 1;
|
||||
}
|
||||
_ => {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"CHPROP: unknown property '{}'. Use: LAYER COLOR LINETYPE LTSCALE TRANSPARENCY", prop
|
||||
));
|
||||
).as_ref());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -689,10 +689,10 @@ impl OpenCADStudio {
|
|||
// re-tessellate the changed entities so they
|
||||
// repaint immediately (issue #231 class).
|
||||
self.invalidate_property_targets(i, &handles);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"CHPROP: {} entity/entities updated.",
|
||||
changed
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -711,7 +711,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("SETBYLAYER: select entities first.");
|
||||
.push_error(crate::t!("SETBYLAYER: select entities first.").as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "SETBYLAYER");
|
||||
let mut changed = 0usize;
|
||||
|
|
@ -730,9 +730,9 @@ impl OpenCADStudio {
|
|||
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
||||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"SETBYLAYER: reset {changed} entity/entities to ByLayer."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -778,7 +778,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
if dups.is_empty() {
|
||||
self.command_line
|
||||
.push_output("OVERKILL: no duplicate objects found.");
|
||||
.push_output(crate::t!("OVERKILL: no duplicate objects found.").as_ref());
|
||||
} else {
|
||||
let n = dups.len();
|
||||
self.push_undo_snapshot(i, "OVERKILL");
|
||||
|
|
@ -786,7 +786,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_output(&format!("OVERKILL: deleted {n} duplicate object(s)."));
|
||||
.push_output(crate::tf!("OVERKILL: deleted {n} duplicate object(s).").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -813,17 +813,17 @@ impl OpenCADStudio {
|
|||
} else {
|
||||
u8::from(self.pick_drag_rect)
|
||||
};
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{} = {v}",
|
||||
if is_add { "PICKADD" } else { "PICKDRAG" }
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
match arg {
|
||||
"0" | "1" => {
|
||||
let on = arg == "1";
|
||||
if is_add {
|
||||
self.pick_add = on;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"PICKADD = {} ({})",
|
||||
arg,
|
||||
if on {
|
||||
|
|
@ -831,10 +831,10 @@ impl OpenCADStudio {
|
|||
} else {
|
||||
"click replaces selection, Shift toggles"
|
||||
}
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.pick_drag_rect = on;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"PICKDRAG = {} ({})",
|
||||
arg,
|
||||
if on {
|
||||
|
|
@ -842,14 +842,14 @@ impl OpenCADStudio {
|
|||
} else {
|
||||
"press-drag lassoes"
|
||||
}
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
self.persist_settings_if_changed();
|
||||
}
|
||||
_ => self.command_line.push_error(&format!(
|
||||
_ => self.command_line.push_error(crate::tf!(
|
||||
"{}: expected 0 or 1.",
|
||||
if is_add { "PICKADD" } else { "PICKDRAG" }
|
||||
)),
|
||||
).as_ref()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1586,9 +1586,9 @@ impl OpenCADStudio {
|
|||
// prompt for a new value on the next line instead
|
||||
// of only echoing the current one. Enter keeps it.
|
||||
let current = msg.split('=').nth(1).map(str::trim).unwrap_or("");
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Enter new value for {name} <{current}>:"
|
||||
));
|
||||
).as_ref());
|
||||
self.pending_setvar = Some(name.clone());
|
||||
}
|
||||
}
|
||||
|
|
@ -1667,15 +1667,15 @@ impl OpenCADStudio {
|
|||
}
|
||||
};
|
||||
self.command_line
|
||||
.push_output("FINDNONPURGEABLE: named objects in use (not purgeable):");
|
||||
.push_output(crate::t!("FINDNONPURGEABLE: named objects in use (not purgeable):").as_ref());
|
||||
self.command_line
|
||||
.push_output(&format!(" Layers: {}", fmt(layers)));
|
||||
.push_output(crate::tf!(" Layers: {}", fmt(layers)).as_ref());
|
||||
self.command_line
|
||||
.push_output(&format!(" Linetypes: {}", fmt(linetypes)));
|
||||
.push_output(crate::tf!(" Linetypes: {}", fmt(linetypes)).as_ref());
|
||||
self.command_line
|
||||
.push_output(&format!(" Text styles: {}", fmt(styles)));
|
||||
.push_output(crate::tf!(" Text styles: {}", fmt(styles)).as_ref());
|
||||
self.command_line
|
||||
.push_output(&format!(" Blocks: {}", fmt(blocks)));
|
||||
.push_output(crate::tf!(" Blocks: {}", fmt(blocks)).as_ref());
|
||||
}
|
||||
|
||||
// ── AUDIT — report drawing-database integrity issues ─────────
|
||||
|
|
@ -1703,24 +1703,24 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.command_line
|
||||
.push_output(&format!("AUDIT: scanned {total} object(s)."));
|
||||
.push_output(crate::tf!("AUDIT: scanned {total} object(s).").as_ref());
|
||||
if undefined_layers.is_empty() && undefined_blocks.is_empty() {
|
||||
self.command_line.push_output("AUDIT: no issues found.");
|
||||
self.command_line.push_output(crate::t!("AUDIT: no issues found.").as_ref());
|
||||
} else {
|
||||
if !undefined_layers.is_empty() {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"AUDIT: reference(s) to undefined layer(s): {}",
|
||||
undefined_layers.into_iter().collect::<Vec<_>>().join(", ")
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
if !undefined_blocks.is_empty() {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"AUDIT: reference(s) to undefined block(s): {}",
|
||||
undefined_blocks.into_iter().collect::<Vec<_>>().join(", ")
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
self.command_line
|
||||
.push_info("AUDIT: report only — no automatic repair performed.");
|
||||
.push_info(crate::t!("AUDIT: report only — no automatic repair performed.").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1744,7 +1744,7 @@ impl OpenCADStudio {
|
|||
|
||||
if type_str.is_empty() || old_name.is_empty() || new_name.is_empty() {
|
||||
self.command_line.push_info(
|
||||
"Usage: RENAME <type> <old> <new> (types: LAYER BLOCK STYLE DIMSTYLE LINETYPE UCS VIEW)"
|
||||
crate::t!("Usage: RENAME <type> <old> <new> (types: LAYER BLOCK STYLE DIMSTYLE LINETYPE UCS VIEW)").as_ref()
|
||||
);
|
||||
} else {
|
||||
// Snapshot BEFORE mutating (undo must restore the old
|
||||
|
|
@ -1789,21 +1789,21 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("RENAME: '{}' → '{}'.", old_name, new_name));
|
||||
.push_output(crate::tf!("RENAME: '{}' → '{}'.", old_name, new_name).as_ref());
|
||||
} else {
|
||||
self.discard_last_undo_entry(i);
|
||||
if !known {
|
||||
self.command_line.push_error(&format!("RENAME: unknown type '{}'. Use LAYER BLOCK STYLE DIMSTYLE LINETYPE UCS VIEW", type_str));
|
||||
self.command_line.push_error(crate::tf!("RENAME: unknown type '{}'. Use LAYER BLOCK STYLE DIMSTYLE LINETYPE UCS VIEW", type_str).as_ref());
|
||||
} else if type_str == "BLOCK" {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"RENAME: could not rename block '{}' — missing/anonymous/xref, or '{}' is invalid or taken.",
|
||||
old_name, new_name
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"RENAME: could not rename '{}' in {} — not found or protected, or '{}' is invalid or taken.",
|
||||
old_name, type_str, new_name
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1825,17 +1825,17 @@ impl OpenCADStudio {
|
|||
if name_arg.is_empty() {
|
||||
let cur = &self.tabs[i].scene.document.header.current_layer_name;
|
||||
self.command_line
|
||||
.push_output(&format!("CLAYER = \"{cur}\""));
|
||||
.push_output(crate::tf!("CLAYER = \"{cur}\"").as_ref());
|
||||
} else {
|
||||
if self.tabs[i].scene.document.layers.contains(name_arg) {
|
||||
self.tabs[i].scene.document.header.current_layer_name =
|
||||
name_arg.to_string();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("CLAYER set to \"{name_arg}\""));
|
||||
.push_output(crate::tf!("CLAYER set to \"{name_arg}\"").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("CLAYER: layer '{}' not found.", name_arg));
|
||||
.push_error(crate::tf!("CLAYER: layer '{}' not found.", name_arg).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1851,16 +1851,16 @@ impl OpenCADStudio {
|
|||
if name_arg.is_empty() {
|
||||
let cur = &self.tabs[i].scene.document.header.current_dimstyle_name;
|
||||
self.command_line
|
||||
.push_output(&format!("CDIMSTY = \"{cur}\""));
|
||||
.push_output(crate::tf!("CDIMSTY = \"{cur}\"").as_ref());
|
||||
} else {
|
||||
if self.tabs[i].scene.document.dim_styles.contains(&name_arg) {
|
||||
self.tabs[i].scene.document.header.current_dimstyle_name = name_arg.clone();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("Active dim style set to \"{name_arg}\""));
|
||||
.push_output(crate::tf!("Active dim style set to \"{name_arg}\"").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("CDIMSTY: dim style '{}' not found.", name_arg));
|
||||
.push_error(crate::tf!("CDIMSTY: dim style '{}' not found.", name_arg).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1874,20 +1874,20 @@ impl OpenCADStudio {
|
|||
let val_str = cmd.trim_start_matches("LTSCALE").trim();
|
||||
if val_str.is_empty() {
|
||||
let v = self.tabs[i].scene.document.header.linetype_scale;
|
||||
self.command_line.push_output(&format!("LTSCALE = {v:.4}"));
|
||||
self.command_line.push_output(crate::tf!("LTSCALE = {v:.4}").as_ref());
|
||||
} else if let Ok(v) = val_str.parse::<f64>() {
|
||||
if v > 0.0 {
|
||||
self.push_undo_snapshot(i, "LTSCALE");
|
||||
self.tabs[i].scene.document.header.linetype_scale = v;
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("LTSCALE set to {v:.4}"));
|
||||
.push_output(crate::tf!("LTSCALE set to {v:.4}").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("LTSCALE: value must be positive.");
|
||||
.push_error(crate::t!("LTSCALE: value must be positive.").as_ref());
|
||||
}
|
||||
} else {
|
||||
self.command_line.push_error("Usage: LTSCALE [value]");
|
||||
self.command_line.push_error(crate::t!("Usage: LTSCALE [value]").as_ref());
|
||||
}
|
||||
}
|
||||
"PDMODE" => {
|
||||
|
|
@ -1903,14 +1903,14 @@ impl OpenCADStudio {
|
|||
let val_str = cmd.trim_start_matches("PDMODE").trim();
|
||||
if val_str.is_empty() {
|
||||
let v = self.tabs[i].scene.document.header.point_display_mode;
|
||||
self.command_line.push_output(&format!("PDMODE = {v}"));
|
||||
self.command_line.push_output(crate::tf!("PDMODE = {v}").as_ref());
|
||||
} else if let Ok(v) = val_str.parse::<i16>() {
|
||||
self.push_undo_snapshot(i, "PDMODE");
|
||||
self.tabs[i].scene.document.header.point_display_mode = v;
|
||||
// Point glyphs are built at tessellation time — rebuild them.
|
||||
self.tabs[i].scene.invalidate_point_dependencies();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!("PDMODE set to {v}"));
|
||||
self.command_line.push_output(crate::tf!("PDMODE set to {v}").as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(
|
||||
"Usage: PDMODE [value] (0=dot 1=none 2=+ 3=x 4=tick; +32 circle, +64 square)",
|
||||
|
|
@ -1922,17 +1922,17 @@ impl OpenCADStudio {
|
|||
if val_str.is_empty() {
|
||||
let v = if self.texteditmode { 1 } else { 0 };
|
||||
self.command_line
|
||||
.push_output(&format!("TEXTEDITMODE = {v}"));
|
||||
.push_output(crate::tf!("TEXTEDITMODE = {v}").as_ref());
|
||||
} else if let Some(v) =
|
||||
crate::modules::annotate::textedit::parse_texteditmode(&val_str)
|
||||
{
|
||||
self.texteditmode = v;
|
||||
let n = if v { 1 } else { 0 };
|
||||
self.command_line
|
||||
.push_output(&format!("TEXTEDITMODE set to {n}"));
|
||||
.push_output(crate::tf!("TEXTEDITMODE set to {n}").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("Requires 0 OR 1 OR MULTIPLE OR SINGLE");
|
||||
.push_error(crate::t!("Requires 0 OR 1 OR MULTIPLE OR SINGLE").as_ref());
|
||||
}
|
||||
}
|
||||
"ISAVEBAK" => {
|
||||
|
|
@ -1946,19 +1946,19 @@ impl OpenCADStudio {
|
|||
match cmd.trim_start_matches("ISAVEBAK").trim() {
|
||||
"" => {
|
||||
let v = if self.backup_on_save { 1 } else { 0 };
|
||||
self.command_line.push_output(&format!("ISAVEBAK = {v}"));
|
||||
self.command_line.push_output(crate::tf!("ISAVEBAK = {v}").as_ref());
|
||||
}
|
||||
"0" => {
|
||||
self.backup_on_save = false;
|
||||
self.persist_settings_if_changed();
|
||||
self.command_line.push_output("ISAVEBAK set to 0");
|
||||
self.command_line.push_output(crate::t!("ISAVEBAK set to 0").as_ref());
|
||||
}
|
||||
"1" => {
|
||||
self.backup_on_save = true;
|
||||
self.persist_settings_if_changed();
|
||||
self.command_line.push_output("ISAVEBAK set to 1");
|
||||
self.command_line.push_output(crate::t!("ISAVEBAK set to 1").as_ref());
|
||||
}
|
||||
_ => self.command_line.push_error("Requires 0 or 1"),
|
||||
_ => self.command_line.push_error(crate::t!("Requires 0 or 1").as_ref()),
|
||||
}
|
||||
}
|
||||
"FILEASSOC" => {
|
||||
|
|
@ -1974,7 +1974,7 @@ impl OpenCADStudio {
|
|||
match cmd.trim_start_matches("FILEASSOC").trim() {
|
||||
"" => {
|
||||
let v = if self.file_assoc_enabled { 1 } else { 0 };
|
||||
self.command_line.push_output(&format!("FILEASSOC = {v}"));
|
||||
self.command_line.push_output(crate::tf!("FILEASSOC = {v}").as_ref());
|
||||
}
|
||||
"1" => {
|
||||
self.file_assoc_enabled = true;
|
||||
|
|
@ -1985,7 +1985,7 @@ impl OpenCADStudio {
|
|||
),
|
||||
Err(e) => self
|
||||
.command_line
|
||||
.push_error(&format!("FILEASSOC: registration failed: {e}")),
|
||||
.push_error(crate::tf!("FILEASSOC: registration failed: {e}").as_ref()),
|
||||
}
|
||||
}
|
||||
"0" => {
|
||||
|
|
@ -1994,13 +1994,13 @@ impl OpenCADStudio {
|
|||
match crate::io::file_association::unregister_handler() {
|
||||
Ok(()) => self
|
||||
.command_line
|
||||
.push_output("FILEASSOC set to 0 — unregistered as a file handler"),
|
||||
.push_output(crate::t!("FILEASSOC set to 0 — unregistered as a file handler").as_ref()),
|
||||
Err(e) => self
|
||||
.command_line
|
||||
.push_error(&format!("FILEASSOC: unregister failed: {e}")),
|
||||
.push_error(crate::tf!("FILEASSOC: unregister failed: {e}").as_ref()),
|
||||
}
|
||||
}
|
||||
_ => self.command_line.push_error("Requires 0 or 1"),
|
||||
_ => self.command_line.push_error(crate::t!("Requires 0 or 1").as_ref()),
|
||||
}
|
||||
}
|
||||
"SAVETIME" => {
|
||||
|
|
@ -2016,7 +2016,7 @@ impl OpenCADStudio {
|
|||
let arg = cmd.trim_start_matches("SAVETIME").trim();
|
||||
if arg.is_empty() {
|
||||
self.command_line
|
||||
.push_output(&format!("SAVETIME = {}", self.savetime_min));
|
||||
.push_output(crate::tf!("SAVETIME = {}", self.savetime_min).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
match arg.parse::<i32>() {
|
||||
|
|
@ -2032,7 +2032,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
_ => self
|
||||
.command_line
|
||||
.push_error("Requires a non-negative number of minutes (0 = off)"),
|
||||
.push_error(crate::t!("Requires a non-negative number of minutes (0 = off)").as_ref()),
|
||||
}
|
||||
}
|
||||
"PDSIZE" => {
|
||||
|
|
@ -2048,14 +2048,14 @@ impl OpenCADStudio {
|
|||
let val_str = cmd.trim_start_matches("PDSIZE").trim();
|
||||
if val_str.is_empty() {
|
||||
let v = self.tabs[i].scene.document.header.point_display_size;
|
||||
self.command_line.push_output(&format!("PDSIZE = {v:.4}"));
|
||||
self.command_line.push_output(crate::tf!("PDSIZE = {v:.4}").as_ref());
|
||||
} else if let Ok(v) = val_str.parse::<f64>() {
|
||||
self.push_undo_snapshot(i, "PDSIZE");
|
||||
self.tabs[i].scene.document.header.point_display_size = v;
|
||||
self.tabs[i].scene.invalidate_point_dependencies();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("PDSIZE set to {v:.4}"));
|
||||
.push_output(crate::tf!("PDSIZE set to {v:.4}").as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(
|
||||
"Usage: PDSIZE [value] (>0 absolute size, <0 percent of viewport, 0 default)",
|
||||
|
|
@ -2087,19 +2087,19 @@ impl OpenCADStudio {
|
|||
_ => Err(()),
|
||||
};
|
||||
match parsed {
|
||||
Err(_) => self.command_line.push_error("Usage: LWDISPLAY [ON|OFF]"),
|
||||
Err(_) => self.command_line.push_error(crate::t!("Usage: LWDISPLAY [ON|OFF]").as_ref()),
|
||||
Ok(Some(v)) => {
|
||||
self.push_undo_snapshot(i, "LWDISPLAY");
|
||||
self.tabs[i].scene.document.header.lineweight_display = v;
|
||||
// No retessellate — the wire shader honours the flag via uniforms.
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("LWDISPLAY {}", if v { "ON" } else { "OFF" }));
|
||||
.push_output(crate::tf!("LWDISPLAY {}", if v { "ON" } else { "OFF" }).as_ref());
|
||||
}
|
||||
Ok(None) => {
|
||||
let v = self.tabs[i].scene.document.header.lineweight_display;
|
||||
self.command_line
|
||||
.push_output(&format!("LWDISPLAY = {}", if v { "ON" } else { "OFF" }));
|
||||
.push_output(crate::tf!("LWDISPLAY = {}", if v { "ON" } else { "OFF" }).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2121,7 +2121,7 @@ impl OpenCADStudio {
|
|||
.header
|
||||
.current_entity_linetype_scale;
|
||||
self.command_line
|
||||
.push_output(&format!("CELTSCALE = {v:.4}"));
|
||||
.push_output(crate::tf!("CELTSCALE = {v:.4}").as_ref());
|
||||
} else if let Ok(v) = val_str.parse::<f64>() {
|
||||
if v > 0.0 {
|
||||
self.tabs[i]
|
||||
|
|
@ -2131,13 +2131,13 @@ impl OpenCADStudio {
|
|||
.current_entity_linetype_scale = v;
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("CELTSCALE set to {v:.4}"));
|
||||
.push_output(crate::tf!("CELTSCALE set to {v:.4}").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("CELTSCALE: value must be positive.");
|
||||
.push_error(crate::t!("CELTSCALE: value must be positive.").as_ref());
|
||||
}
|
||||
} else {
|
||||
self.command_line.push_error("Usage: CELTSCALE [value]");
|
||||
self.command_line.push_error(crate::t!("Usage: CELTSCALE [value]").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2166,7 +2166,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if selected_handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("SCALETEXT: select Text/MText entities first.");
|
||||
.push_error(crate::t!("SCALETEXT: select Text/MText entities first.").as_ref());
|
||||
} else {
|
||||
let (use_absolute, value) = match (
|
||||
parts.first().map(|s| s.to_uppercase()).as_deref(),
|
||||
|
|
@ -2179,7 +2179,7 @@ impl OpenCADStudio {
|
|||
if let Some(val) = value {
|
||||
if val <= 0.0 {
|
||||
self.command_line
|
||||
.push_error("SCALETEXT: value must be positive.");
|
||||
.push_error(crate::t!("SCALETEXT: value must be positive.").as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "SCALETEXT");
|
||||
let mut count = 0usize;
|
||||
|
|
@ -2206,17 +2206,17 @@ impl OpenCADStudio {
|
|||
}
|
||||
if count > 0 {
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"SCALETEXT: scaled {count} text entity(ies)."
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("SCALETEXT: no Text/MText in selection.");
|
||||
.push_error(crate::t!("SCALETEXT: no Text/MText in selection.").as_ref());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.command_line
|
||||
.push_info("Usage: SCALETEXT <factor> or SCALETEXT H <height>");
|
||||
.push_info(crate::t!("Usage: SCALETEXT <factor> or SCALETEXT H <height>").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ impl OpenCADStudio {
|
|||
pub(super) fn dispatch_view(&mut self, cmd: &str, i: usize) -> Option<Task<Message>> {
|
||||
match cmd {
|
||||
"DONATE" => {
|
||||
self.command_line.push_info("Opening Patreon page...");
|
||||
self.command_line.push_info(crate::t!("Opening Patreon page...").as_ref());
|
||||
return Some(crate::sys::open_url(
|
||||
"https://patreon.com/HakanSeven12",
|
||||
self.main_window,
|
||||
|
|
@ -12,7 +12,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
|
||||
"WEBVERSION" => {
|
||||
self.command_line.push_info("Opening OCS Web...");
|
||||
self.command_line.push_info(crate::t!("Opening OCS Web...").as_ref());
|
||||
return Some(crate::sys::open_url(
|
||||
"https://hakanseven12.github.io/OpenCADStudio/",
|
||||
self.main_window,
|
||||
|
|
@ -21,7 +21,7 @@ impl OpenCADStudio {
|
|||
|
||||
"HELP" => {
|
||||
self.command_line
|
||||
.push_info("Opening OCS Discussions for help and questions...");
|
||||
.push_info(crate::t!("Opening OCS Discussions for help and questions...").as_ref());
|
||||
return Some(crate::sys::open_url(
|
||||
"https://github.com/HakanSeven12/OpenCADStudio/discussions",
|
||||
self.main_window,
|
||||
|
|
@ -41,78 +41,78 @@ impl OpenCADStudio {
|
|||
.map(|p| p.display().to_string())
|
||||
.unwrap_or_else(|| "(unsaved)".to_string());
|
||||
self.command_line
|
||||
.push_output(&format!("Drawing: {}", path_label));
|
||||
.push_output(crate::tf!("Drawing: {}", path_label).as_ref());
|
||||
self.command_line
|
||||
.push_output(&format!(" Created (Julian): {:.6}", h.create_date_julian));
|
||||
.push_output(crate::tf!(" Created (Julian): {:.6}", h.create_date_julian).as_ref());
|
||||
self.command_line
|
||||
.push_output(&format!(" Updated (Julian): {:.6}", h.update_date_julian));
|
||||
.push_output(crate::tf!(" Updated (Julian): {:.6}", h.update_date_julian).as_ref());
|
||||
self.command_line
|
||||
.push_output(&format!(" Total edit time: {:.4}", h.total_editing_time));
|
||||
.push_output(crate::tf!(" Total edit time: {:.4}", h.total_editing_time).as_ref());
|
||||
self.command_line
|
||||
.push_output(&format!(" User elapsed: {:.4}", h.user_elapsed_time));
|
||||
self.command_line.push_output(&format!(
|
||||
.push_output(crate::tf!(" User elapsed: {:.4}", h.user_elapsed_time).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" Last saved by: {}",
|
||||
if h.last_saved_by.is_empty() {
|
||||
"(unknown)"
|
||||
} else {
|
||||
&h.last_saved_by
|
||||
}
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" Fingerprint GUID: {}",
|
||||
if h.fingerprint_guid.is_empty() {
|
||||
"(none)"
|
||||
} else {
|
||||
&h.fingerprint_guid
|
||||
}
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" Version GUID: {}",
|
||||
if h.version_guid.is_empty() {
|
||||
"(none)"
|
||||
} else {
|
||||
&h.version_guid
|
||||
}
|
||||
));
|
||||
).as_ref());
|
||||
self.command_line
|
||||
.push_output(&format!(" Code page: {}", h.code_page));
|
||||
self.command_line.push_output(&format!(
|
||||
.push_output(crate::tf!(" Code page: {}", h.code_page).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" Menu name: {}",
|
||||
if h.menu_name.is_empty() {
|
||||
"(none)"
|
||||
} else {
|
||||
&h.menu_name
|
||||
}
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" Hyperlink base: {}",
|
||||
if h.hyperlink_base.is_empty() {
|
||||
"(none)"
|
||||
} else {
|
||||
&h.hyperlink_base
|
||||
}
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" Project name: {}",
|
||||
if h.project_name.is_empty() {
|
||||
"(none)"
|
||||
} else {
|
||||
&h.project_name
|
||||
}
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" Stylesheet: {}",
|
||||
if h.stylesheet.is_empty() {
|
||||
"(none)"
|
||||
} else {
|
||||
&h.stylesheet
|
||||
}
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" Required versions: {:#018x}",
|
||||
h.required_versions
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" Measurement: {} ({})",
|
||||
h.measurement,
|
||||
if h.measurement == 1 {
|
||||
|
|
@ -120,23 +120,23 @@ impl OpenCADStudio {
|
|||
} else {
|
||||
"Imperial"
|
||||
}
|
||||
));
|
||||
).as_ref());
|
||||
self.command_line
|
||||
.push_output(&format!(" Proxy graphics: {}", h.proxy_graphics));
|
||||
.push_output(crate::tf!(" Proxy graphics: {}", h.proxy_graphics).as_ref());
|
||||
self.command_line
|
||||
.push_output(&format!(" Tree depth: {}", h.tree_depth));
|
||||
self.command_line.push_output(&format!(
|
||||
.push_output(crate::tf!(" Tree depth: {}", h.tree_depth).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" User vars (int): {} {} {} {} {}",
|
||||
h.user_int1, h.user_int2, h.user_int3, h.user_int4, h.user_int5
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" User vars (real): {:.6} {:.6} {:.6} {:.6} {:.6}",
|
||||
h.user_real1, h.user_real2, h.user_real3, h.user_real4, h.user_real5
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" User timer: {}",
|
||||
if h.user_timer { "On" } else { "Off" }
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
// Edit a USERI1..USERI5 / USERR1..USERR5 slot. Lets the user
|
||||
|
|
@ -174,9 +174,9 @@ impl OpenCADStudio {
|
|||
_ => h.user_real5 = val,
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!("USERR{n} = {val}"));
|
||||
self.command_line.push_output(crate::tf!("USERR{n} = {val}").as_ref());
|
||||
} else {
|
||||
self.command_line.push_info("Usage: USERR <1-5> <real>");
|
||||
self.command_line.push_info(crate::t!("Usage: USERR <1-5> <real>").as_ref());
|
||||
}
|
||||
}
|
||||
(Some(n @ 1..=5), v, false) => {
|
||||
|
|
@ -189,14 +189,14 @@ impl OpenCADStudio {
|
|||
_ => h.user_int5 = val,
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!("USERI{n} = {val}"));
|
||||
self.command_line.push_output(crate::tf!("USERI{n} = {val}").as_ref());
|
||||
} else {
|
||||
self.command_line.push_info("Usage: USERI <1-5> <integer>");
|
||||
self.command_line.push_info(crate::t!("Usage: USERI <1-5> <integer>").as_ref());
|
||||
}
|
||||
}
|
||||
_ => self
|
||||
.command_line
|
||||
.push_info("Usage: USERI <1-5> <int> | USERR <1-5> <real>"),
|
||||
.push_info(crate::t!("Usage: USERI <1-5> <int> | USERR <1-5> <real>").as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +213,7 @@ impl OpenCADStudio {
|
|||
"https://github.com/HakanSeven12/OpenCADStudio/issues/new?body={}",
|
||||
crate::sys::percent_encode(&body)
|
||||
);
|
||||
self.command_line.push_info("Opening feedback page...");
|
||||
self.command_line.push_info(crate::t!("Opening feedback page...").as_ref());
|
||||
return Some(crate::sys::open_url(&url, self.main_window));
|
||||
}
|
||||
|
||||
|
|
@ -226,7 +226,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
|
||||
"CHANGELOG" => {
|
||||
self.command_line.push_info("Opening release notes...");
|
||||
self.command_line.push_info(crate::t!("Opening release notes...").as_ref());
|
||||
return Some(crate::sys::open_url(
|
||||
"https://github.com/HakanSeven12/OpenCADStudio/releases",
|
||||
self.main_window,
|
||||
|
|
@ -266,12 +266,12 @@ impl OpenCADStudio {
|
|||
let text: String = keys.iter().map(|(k, v)| format!("{k} {v}\n")).collect();
|
||||
let count = self.shortcut_overrides.len();
|
||||
match std::fs::write(path, text) {
|
||||
Ok(()) => self.command_line.push_output(&format!(
|
||||
Ok(()) => self.command_line.push_output(crate::tf!(
|
||||
"CUIEXPORT: wrote {count} shortcut(s) to \"{path}\"."
|
||||
)),
|
||||
).as_ref()),
|
||||
Err(e) => self
|
||||
.command_line
|
||||
.push_error(&format!("CUIEXPORT: cannot write \"{path}\": {e}")),
|
||||
.push_error(crate::tf!("CUIEXPORT: cannot write \"{path}\": {e}").as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -308,13 +308,13 @@ impl OpenCADStudio {
|
|||
n += 1;
|
||||
}
|
||||
}
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"CUIIMPORT: loaded {n} shortcut(s) from \"{path}\"."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
Err(e) => self
|
||||
.command_line
|
||||
.push_error(&format!("CUIIMPORT: cannot read \"{path}\": {e}")),
|
||||
.push_error(crate::tf!("CUIIMPORT: cannot read \"{path}\": {e}").as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -333,28 +333,28 @@ impl OpenCADStudio {
|
|||
let key = parts.get(1).map(|s| s.to_uppercase()).unwrap_or_default();
|
||||
let cmd_str = parts.get(2).map(|s| s.to_uppercase()).unwrap_or_default();
|
||||
if key.is_empty() || cmd_str.is_empty() {
|
||||
self.command_line.push_error("Usage: SHORTCUTS SET <key> <command> e.g. SHORTCUTS SET CTRL+D DIST");
|
||||
self.command_line.push_error(crate::t!("Usage: SHORTCUTS SET <key> <command> e.g. SHORTCUTS SET CTRL+D DIST").as_ref());
|
||||
} else {
|
||||
self.shortcut_overrides.insert(key.clone(), cmd_str.clone());
|
||||
self.command_line
|
||||
.push_output(&format!("Shortcut set: {key} → {cmd_str}"));
|
||||
.push_output(crate::tf!("Shortcut set: {key} → {cmd_str}").as_ref());
|
||||
}
|
||||
}
|
||||
"CLEAR" | "DELETE" | "REMOVE" => {
|
||||
let key = parts.get(1).map(|s| s.to_uppercase()).unwrap_or_default();
|
||||
if key.is_empty() {
|
||||
self.command_line.push_error("Usage: SHORTCUTS CLEAR <key>");
|
||||
self.command_line.push_error(crate::t!("Usage: SHORTCUTS CLEAR <key>").as_ref());
|
||||
} else if self.shortcut_overrides.remove(&key).is_some() {
|
||||
self.command_line
|
||||
.push_output(&format!("Shortcut '{key}' removed."));
|
||||
.push_output(crate::tf!("Shortcut '{key}' removed.").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("Shortcut '{key}' not found."));
|
||||
.push_error(crate::tf!("Shortcut '{key}' not found.").as_ref());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_info("Usage: SHORTCUTS LIST | SET <key> <cmd> | CLEAR <key>");
|
||||
.push_info(crate::t!("Usage: SHORTCUTS LIST | SET <key> <cmd> | CLEAR <key>").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -396,17 +396,17 @@ impl OpenCADStudio {
|
|||
return Some(Task::none());
|
||||
}
|
||||
_ => {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"COLORSCHEME: unknown theme '{}'. Type COLORSCHEME LIST for options.",
|
||||
sub
|
||||
));
|
||||
).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
};
|
||||
if let Some(t) = theme {
|
||||
let name = format!("{:?}", t);
|
||||
self.command_line
|
||||
.push_output(&format!("Color scheme set to '{name}'."));
|
||||
.push_output(crate::tf!("Color scheme set to '{name}'.").as_ref());
|
||||
return Some(Task::done(Message::SetTheme(t)));
|
||||
}
|
||||
return Some(Task::none());
|
||||
|
|
@ -421,7 +421,7 @@ impl OpenCADStudio {
|
|||
"MVIEW" => {
|
||||
if self.tabs[i].scene.current_layout == "Model" {
|
||||
self.command_line
|
||||
.push_error("MVIEW: switch to a paper space layout first.");
|
||||
.push_error(crate::t!("MVIEW: switch to a paper space layout first.").as_ref());
|
||||
} else {
|
||||
use crate::modules::layout::mview::MviewCommand;
|
||||
let scene = &self.tabs[i].scene;
|
||||
|
|
@ -464,7 +464,7 @@ impl OpenCADStudio {
|
|||
if sub.is_empty() {
|
||||
self.awaiting_vports = true;
|
||||
self.command_line
|
||||
.push_info("VPORTS Configuration [SIngle/2H/2V/4]:");
|
||||
.push_info(crate::t!("VPORTS Configuration [SIngle/2H/2V/4]:").as_ref());
|
||||
return Some(self.focus_cmd_input());
|
||||
}
|
||||
// Model space: split the tiled viewport layout via pane_grid.
|
||||
|
|
@ -494,11 +494,11 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.set_model_panes(config);
|
||||
self.tabs[i].scene.camera_generation += 1;
|
||||
self.command_line
|
||||
.push_output(&format!("VPORTS: {n} viewport(s)."));
|
||||
.push_output(crate::tf!("VPORTS: {n} viewport(s).").as_ref());
|
||||
}
|
||||
None => {
|
||||
self.command_line
|
||||
.push_error("VPORTS: use SINGLE | 2H | 2V | 4.");
|
||||
.push_error(crate::t!("VPORTS: use SINGLE | 2H | 2V | 4.").as_ref());
|
||||
}
|
||||
}
|
||||
} else if sub.is_empty() {
|
||||
|
|
@ -532,23 +532,23 @@ impl OpenCADStudio {
|
|||
})
|
||||
.collect();
|
||||
if viewports.is_empty() {
|
||||
self.command_line.push_info("No viewports. Use MVIEW to create one, or VPORTS 2H / 2V / 4 / SINGLE.");
|
||||
self.command_line.push_info(crate::t!("No viewports. Use MVIEW to create one, or VPORTS 2H / 2V / 4 / SINGLE.").as_ref());
|
||||
} else {
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{} viewport(s) in layout \"{}\":",
|
||||
viewports.len(),
|
||||
scene.current_layout
|
||||
));
|
||||
).as_ref());
|
||||
for (id, center, w, h, scale, is_on, locked) in &viewports {
|
||||
let state = match (is_on, locked) {
|
||||
(true, true) => "On, Locked",
|
||||
(true, false) => "On",
|
||||
(false, _) => "Off",
|
||||
};
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
" VP #{id}: {w:.1}×{h:.1} @ ({:.1},{:.1}) scale={scale:.4} [{state}]",
|
||||
center.x, center.y
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -654,7 +654,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.auto_fit_viewport(handle);
|
||||
}
|
||||
Err(e) => {
|
||||
self.command_line.push_error(&format!("VPORTS: {e}"));
|
||||
self.command_line.push_error(crate::tf!("VPORTS: {e}").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -686,11 +686,11 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"VPORTS: created {} viewport(s) [{}].",
|
||||
rects.len(),
|
||||
sub
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -700,10 +700,10 @@ impl OpenCADStudio {
|
|||
let scene = &self.tabs[i].scene;
|
||||
if scene.current_layout == "Model" {
|
||||
self.command_line
|
||||
.push_error("VPLAYER: switch to a paper space layout first.");
|
||||
.push_error(crate::t!("VPLAYER: switch to a paper space layout first.").as_ref());
|
||||
} else if scene.active_viewport.is_none() {
|
||||
self.command_line
|
||||
.push_error("VPLAYER: enter a viewport first (double-click or MS).");
|
||||
.push_error(crate::t!("VPLAYER: enter a viewport first (double-click or MS).").as_ref());
|
||||
} else {
|
||||
use crate::modules::layout::vplayer::VplayerCommand;
|
||||
let vp_handle = scene.active_viewport.unwrap();
|
||||
|
|
@ -729,12 +729,12 @@ impl OpenCADStudio {
|
|||
};
|
||||
if frozen_names.is_empty() {
|
||||
self.command_line
|
||||
.push_info("VPLAYER: no frozen layers in active viewport.");
|
||||
.push_info(crate::t!("VPLAYER: no frozen layers in active viewport.").as_ref());
|
||||
} else {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"VPLAYER: frozen layers: {}",
|
||||
frozen_names.join(", ")
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
let new_cmd = VplayerCommand::new(vp_handle);
|
||||
self.command_line.push_info(&new_cmd.prompt());
|
||||
|
|
@ -763,7 +763,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_info(&format!("{cmd}: no text or dimension objects."));
|
||||
.push_info(crate::tf!("{cmd}: no text or dimension objects.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
self.tabs[i].scene.replace_selection(handles);
|
||||
|
|
@ -802,7 +802,7 @@ impl OpenCADStudio {
|
|||
.collect();
|
||||
if selected.is_empty() {
|
||||
self.command_line
|
||||
.push_error("DRAWORDER: select entities first.");
|
||||
.push_error(crate::t!("DRAWORDER: select entities first.").as_ref());
|
||||
} else {
|
||||
// Parse relative target handle for ABOVE/UNDER.
|
||||
let relative_target: Option<(bool, acadrust::Handle)> = match option.as_str() {
|
||||
|
|
@ -940,12 +940,12 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
let rel = if above { "above" } else { "below" };
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"DRAWORDER: moved {} entities {} {:x}.",
|
||||
selected.len(),
|
||||
rel,
|
||||
target.value()
|
||||
));
|
||||
).as_ref());
|
||||
} else if let Some(to_front) = to_front_opt {
|
||||
let (min_eff, max_eff) = fb_baseline.unwrap_or((1, 0));
|
||||
for (k, h) in selected.iter().enumerate() {
|
||||
|
|
@ -957,11 +957,11 @@ impl OpenCADStudio {
|
|||
table.add_entry(*h, acadrust::Handle::new(sort));
|
||||
}
|
||||
let dir = if to_front { "front" } else { "back" };
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"DRAWORDER: moved {} entities to {}.",
|
||||
selected.len(),
|
||||
dir
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
// Sort order lives in SortEntitiesTable, which the
|
||||
|
|
@ -974,7 +974,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
} else {
|
||||
self.command_line.push_info(
|
||||
"Usage: DRAWORDER F|FRONT | B|BACK | A|ABOVE <handle> | U|UNDER <handle>"
|
||||
crate::t!("Usage: DRAWORDER F|FRONT | B|BACK | A|ABOVE <handle> | U|UNDER <handle>").as_ref()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1000,7 +1000,7 @@ impl OpenCADStudio {
|
|||
Some(acadrust::EntityType::Viewport(vp)) => vp.clone(),
|
||||
_ => {
|
||||
self.command_line
|
||||
.push_error("SYNCPVIEWPORTS: master is not a viewport.");
|
||||
.push_error(crate::t!("SYNCPVIEWPORTS: master is not a viewport.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
};
|
||||
|
|
@ -1023,9 +1023,9 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"SYNCPVIEWPORTS: synced {n} viewport(s) to the master."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
|
||||
// HIDE — hidden-line view of the active viewport.
|
||||
|
|
@ -1088,9 +1088,9 @@ impl CadCommand for DrawOrderRefCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.above {
|
||||
"DRAWORDER Select reference object (move selection above):".into()
|
||||
crate::t!("DRAWORDER Select reference object (move selection above):").into_owned()
|
||||
} else {
|
||||
"DRAWORDER Select reference object (move selection under):".into()
|
||||
crate::t!("DRAWORDER Select reference object (move selection under):").into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use crate::ui::{LayerPanel, PropertiesPanel};
|
|||
use acadrust::tables::Ucs;
|
||||
use acadrust::{CadDocument, EntityType, Handle};
|
||||
use iced;
|
||||
use crate::t;
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
|
@ -496,7 +497,13 @@ impl DocumentTab {
|
|||
.unwrap_or_default()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
None => self.tab_title.clone(),
|
||||
None => {
|
||||
if self.is_start {
|
||||
t!("Start").into_owned()
|
||||
} else {
|
||||
self.tab_title.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,9 +131,9 @@ impl OpenCADStudio {
|
|||
"Replaced 1 occurrence in {}; {remaining} matching object(s) remain.",
|
||||
match_label(target)
|
||||
);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"FIND/REPLACE: replaced 1 occurrence of \"{search}\"."
|
||||
));
|
||||
).as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
|
||||
|
|
@ -188,9 +188,9 @@ impl OpenCADStudio {
|
|||
"Replaced {replaced} occurrence(s) in {} object(s).",
|
||||
changed.len()
|
||||
);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"FIND/REPLACE: replaced {replaced} occurrence(s) of \"{search}\"."
|
||||
));
|
||||
).as_ref());
|
||||
self.refresh_properties();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ pub(super) fn next_group_auto_name(scene: &crate::scene::Scene) -> String {
|
|||
// ── Entity type labels ─────────────────────────────────────────────────────
|
||||
|
||||
pub(super) fn entity_type_label(entity: &acadrust::EntityType) -> String {
|
||||
crate::entities::names::ui_name_or_class(entity)
|
||||
crate::t!(crate::entities::names::ui_name_or_class(entity)).into_owned()
|
||||
}
|
||||
|
||||
pub(super) fn entity_type_key(entity: &acadrust::EntityType) -> String {
|
||||
|
|
|
|||
|
|
@ -1020,7 +1020,7 @@ impl OpenCADStudio {
|
|||
let available = self.tabs[i].history.undo_stack.len();
|
||||
let steps = steps.min(available);
|
||||
if steps == 0 {
|
||||
self.command_line.push_info("Nothing to undo.");
|
||||
self.command_line.push_info(crate::t!("Nothing to undo.").as_ref());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1069,7 +1069,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.finish_history_apply(i, had_full, layer_panel_changed, &changes);
|
||||
self.command_line
|
||||
.push_output(&format!("Undo: {last_label}"));
|
||||
.push_output(crate::tf!("Undo: {last_label}").as_ref());
|
||||
}
|
||||
|
||||
pub(super) fn redo_steps(&mut self, steps: usize) {
|
||||
|
|
@ -1078,7 +1078,7 @@ impl OpenCADStudio {
|
|||
let available = self.tabs[i].history.redo_stack.len();
|
||||
let steps = steps.min(available);
|
||||
if steps == 0 {
|
||||
self.command_line.push_info("Nothing to redo.");
|
||||
self.command_line.push_info(crate::t!("Nothing to redo.").as_ref());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1124,7 +1124,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.finish_history_apply(i, had_full, layer_panel_changed, &changes);
|
||||
self.command_line
|
||||
.push_output(&format!("Redo: {last_label}"));
|
||||
.push_output(crate::tf!("Redo: {last_label}").as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3019,7 +3019,7 @@ impl OpenCADStudio {
|
|||
for (id, res) in crate::plugin::external::load_at_startup(&mut app) {
|
||||
if let Err(e) = res {
|
||||
app.command_line
|
||||
.push_error(&format!("Plugin '{id}' failed to load: {e}"));
|
||||
.push_error(crate::tf!("Plugin '{id}' failed to load: {e}").as_ref());
|
||||
app.plugin_load_errors.insert(id, e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ impl super::OpenCADStudio {
|
|||
.collect();
|
||||
if handles.len() != 2 {
|
||||
self.command_line
|
||||
.push_error("Boolean: select exactly two solids created this session.");
|
||||
.push_error(crate::t!("Boolean: select exactly two solids created this session.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let a = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||
|
|
@ -50,7 +50,7 @@ impl super::OpenCADStudio {
|
|||
};
|
||||
let Some(result) = solid_model::boolean(kind, &a, &b) else {
|
||||
self.command_line
|
||||
.push_error("Boolean failed — the solids may not overlap.");
|
||||
.push_error(crate::t!("Boolean failed — the solids may not overlap.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ impl super::OpenCADStudio {
|
|||
.collect();
|
||||
if handles.len() != 1 {
|
||||
self.command_line
|
||||
.push_error("SLICE: select exactly one solid created this session.");
|
||||
.push_error(crate::t!("SLICE: select exactly one solid created this session.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||
|
|
@ -105,7 +105,7 @@ impl super::OpenCADStudio {
|
|||
}
|
||||
if min[0] > max[0] {
|
||||
self.command_line
|
||||
.push_error("SLICE: could not determine the solid's extent.");
|
||||
.push_error(crate::t!("SLICE: could not determine the solid's extent.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
// Generous margin so the box fully spans the solid in the free axes.
|
||||
|
|
@ -123,7 +123,7 @@ impl super::OpenCADStudio {
|
|||
}
|
||||
if hi[axis] <= lo[axis] {
|
||||
self.command_line
|
||||
.push_error("SLICE: the plane does not cross the solid on the kept side.");
|
||||
.push_error(crate::t!("SLICE: the plane does not cross the solid on the kept side.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let center = [
|
||||
|
|
@ -134,7 +134,7 @@ impl super::OpenCADStudio {
|
|||
let halfspace = solid_model::box_solid(center, hi[0] - lo[0], hi[1] - lo[1], hi[2] - lo[2]);
|
||||
let Some(result) = solid_model::boolean(Bool::Intersect, &solid, &halfspace) else {
|
||||
self.command_line
|
||||
.push_error("SLICE failed — the plane may not cross the solid.");
|
||||
.push_error(crate::t!("SLICE failed — the plane may not cross the solid.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
self.push_undo_snapshot(i, "SLICE");
|
||||
|
|
@ -149,10 +149,10 @@ impl super::OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
let ax = ["X", "Y", "Z"][axis];
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"SLICE: cut at {ax}={value}, kept the {} half.",
|
||||
if keep_low { "lower" } else { "upper" }
|
||||
));
|
||||
).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ impl super::OpenCADStudio {
|
|||
.collect();
|
||||
if handles.len() != 2 {
|
||||
self.command_line
|
||||
.push_error("INTERFERE: select exactly two solids created this session.");
|
||||
.push_error(crate::t!("INTERFERE: select exactly two solids created this session.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let a = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||
|
|
@ -184,11 +184,11 @@ impl super::OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_output("INTERFERE: created an interference solid from the overlap.");
|
||||
.push_output(crate::t!("INTERFERE: created an interference solid from the overlap.").as_ref());
|
||||
}
|
||||
None => self
|
||||
.command_line
|
||||
.push_output("INTERFERE: the selected solids do not overlap."),
|
||||
.push_output(crate::t!("INTERFERE: the selected solids do not overlap.").as_ref()),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -208,7 +208,7 @@ impl super::OpenCADStudio {
|
|||
.collect();
|
||||
if handles.len() != 1 {
|
||||
self.command_line
|
||||
.push_error("3DROTATE: select exactly one solid created this session.");
|
||||
.push_error(crate::t!("3DROTATE: select exactly one solid created this session.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||
|
|
@ -225,7 +225,7 @@ impl super::OpenCADStudio {
|
|||
}
|
||||
if min[0] > max[0] {
|
||||
self.command_line
|
||||
.push_error("3DROTATE: could not determine the solid's extent.");
|
||||
.push_error(crate::t!("3DROTATE: could not determine the solid's extent.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let origin = Point3::new(
|
||||
|
|
@ -250,10 +250,10 @@ impl super::OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"3DROTATE: rotated {angle_deg}° about the {} axis.",
|
||||
["X", "Y", "Z"][axis]
|
||||
));
|
||||
).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -280,7 +280,7 @@ impl super::OpenCADStudio {
|
|||
});
|
||||
let Some((handle, pts, closed)) = found else {
|
||||
self.command_line
|
||||
.push_error("POLYSOLID: select a polyline first.");
|
||||
.push_error(crate::t!("POLYSOLID: select a polyline first.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let mut segs: Vec<([f64; 2], [f64; 2])> = pts.windows(2).map(|w| (w[0], w[1])).collect();
|
||||
|
|
@ -308,7 +308,7 @@ impl super::OpenCADStudio {
|
|||
}
|
||||
let Some(result) = acc else {
|
||||
self.command_line
|
||||
.push_error("POLYSOLID: the polyline has no usable segments.");
|
||||
.push_error(crate::t!("POLYSOLID: the polyline has no usable segments.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
self.push_undo_snapshot(i, "POLYSOLID");
|
||||
|
|
@ -322,9 +322,9 @@ impl super::OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"POLYSOLID: built a wall solid from {used} segment(s) (width {width}, height {height})."
|
||||
));
|
||||
).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -344,7 +344,7 @@ impl super::OpenCADStudio {
|
|||
.collect();
|
||||
if handles.len() != 1 {
|
||||
self.command_line
|
||||
.push_error("3DMIRROR: select exactly one solid created this session.");
|
||||
.push_error(crate::t!("3DMIRROR: select exactly one solid created this session.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||
|
|
@ -361,7 +361,7 @@ impl super::OpenCADStudio {
|
|||
}
|
||||
if min[0] > max[0] {
|
||||
self.command_line
|
||||
.push_error("3DMIRROR: could not determine the solid's extent.");
|
||||
.push_error(crate::t!("3DMIRROR: could not determine the solid's extent.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let c = TVec3::new(
|
||||
|
|
@ -390,10 +390,10 @@ impl super::OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"3DMIRROR: added a mirror across the {} plane.",
|
||||
["X", "Y", "Z"][axis]
|
||||
));
|
||||
).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -417,7 +417,7 @@ impl super::OpenCADStudio {
|
|||
.collect();
|
||||
if handles.len() != 1 {
|
||||
self.command_line
|
||||
.push_error("3DALIGN: select exactly one solid created this session.");
|
||||
.push_error(crate::t!("3DALIGN: select exactly one solid created this session.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
// Build a right-handed frame (origin + orthonormal axes) from 3 points.
|
||||
|
|
@ -440,7 +440,7 @@ impl super::OpenCADStudio {
|
|||
};
|
||||
let (Some(s), Some(d)) = (frame(src), frame(dst)) else {
|
||||
self.command_line
|
||||
.push_error("3DALIGN: each point triple must be non-coincident and non-collinear.");
|
||||
.push_error(crate::t!("3DALIGN: each point triple must be non-coincident and non-collinear.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let a = (d * s.inverse()).to_cols_array(); // column-major [f64; 16]
|
||||
|
|
@ -462,7 +462,7 @@ impl super::OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_output("3DALIGN: aligned the solid to the destination points.");
|
||||
.push_output(crate::t!("3DALIGN: aligned the solid to the destination points.").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -487,7 +487,7 @@ impl super::OpenCADStudio {
|
|||
.collect();
|
||||
if handles.len() != 1 {
|
||||
self.command_line
|
||||
.push_error("SECTION: select exactly one solid created this session.");
|
||||
.push_error(crate::t!("SECTION: select exactly one solid created this session.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||
|
|
@ -504,7 +504,7 @@ impl super::OpenCADStudio {
|
|||
}
|
||||
if min[0] > max[0] {
|
||||
self.command_line
|
||||
.push_error("SECTION: could not determine the solid's extent.");
|
||||
.push_error(crate::t!("SECTION: could not determine the solid's extent.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
// Margin so the cutting plane fully spans the solid in the free axes.
|
||||
|
|
@ -546,7 +546,7 @@ impl super::OpenCADStudio {
|
|||
.collect();
|
||||
let Ok(face) = builder::try_attach_plane(&[wire]) else {
|
||||
self.command_line
|
||||
.push_error("SECTION: could not build the cutting plane.");
|
||||
.push_error(crate::t!("SECTION: could not build the cutting plane.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let shell: Shell = std::iter::once(face).collect();
|
||||
|
|
@ -556,7 +556,7 @@ impl super::OpenCADStudio {
|
|||
let segs = solid_mesh.extract_interference(&plane_mesh);
|
||||
if segs.is_empty() {
|
||||
self.command_line
|
||||
.push_output("SECTION: the plane does not cross the solid.");
|
||||
.push_output(crate::t!("SECTION: the plane does not cross the solid.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
self.push_undo_snapshot(i, "SECTION");
|
||||
|
|
@ -569,11 +569,11 @@ impl super::OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"SECTION: created {} section line(s) at {}={value}.",
|
||||
segs.len(),
|
||||
["X", "Y", "Z"][axis]
|
||||
));
|
||||
).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -581,7 +581,7 @@ impl super::OpenCADStudio {
|
|||
#[cfg(not(feature = "solid3d"))]
|
||||
pub(super) fn solid_section(&mut self, _axis: usize, _value: f64) -> Task<Message> {
|
||||
self.command_line
|
||||
.push_error("SECTION: solid modelling is unavailable in this build.");
|
||||
.push_error(crate::t!("SECTION: solid modelling is unavailable in this build.").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -604,7 +604,7 @@ impl super::OpenCADStudio {
|
|||
let n = sides.max(3);
|
||||
if radius <= 0.0 || height <= 0.0 {
|
||||
self.command_line
|
||||
.push_error("PYRAMID: radius and height must be positive.");
|
||||
.push_error(crate::t!("PYRAMID: radius and height must be positive.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let corners: Vec<Point3> = (0..n)
|
||||
|
|
@ -642,7 +642,7 @@ impl super::OpenCADStudio {
|
|||
}
|
||||
if faces.len() < n + 1 {
|
||||
self.command_line
|
||||
.push_error("PYRAMID: could not build all faces.");
|
||||
.push_error(crate::t!("PYRAMID: could not build all faces.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let shell = Shell::from(faces);
|
||||
|
|
@ -655,12 +655,12 @@ impl super::OpenCADStudio {
|
|||
} = truck_tess::tessellate_shell(&shell)
|
||||
else {
|
||||
self.command_line
|
||||
.push_error("PYRAMID: tessellation failed.");
|
||||
.push_error(crate::t!("PYRAMID: tessellation failed.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
if verts.is_empty() {
|
||||
self.command_line
|
||||
.push_error("PYRAMID: tessellation produced no geometry.");
|
||||
.push_error(crate::t!("PYRAMID: tessellation produced no geometry.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
self.push_undo_snapshot(i, "PYRAMID");
|
||||
|
|
@ -682,9 +682,9 @@ impl super::OpenCADStudio {
|
|||
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"PYRAMID: created a {n}-sided pyramid (radius {radius}, height {height})."
|
||||
));
|
||||
).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -713,12 +713,12 @@ impl super::OpenCADStudio {
|
|||
});
|
||||
let Some((handle, fit)) = found else {
|
||||
self.command_line
|
||||
.push_error("SPLINEFIT: select a polyline to fit a spline through.");
|
||||
.push_error(crate::t!("SPLINEFIT: select a polyline to fit a spline through.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
if fit.len() < 3 {
|
||||
self.command_line
|
||||
.push_error("SPLINEFIT: need at least 3 points.");
|
||||
.push_error(crate::t!("SPLINEFIT: need at least 3 points.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let n = fit.len();
|
||||
|
|
@ -756,7 +756,7 @@ impl super::OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_output(&format!("SPLINEFIT: fit a spline through {n} points."));
|
||||
.push_output(crate::tf!("SPLINEFIT: fit a spline through {n} points.").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -776,7 +776,7 @@ impl super::OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("FLATSHOT: select a solid created this session.");
|
||||
.push_error(crate::t!("FLATSHOT: select a solid created this session.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
self.push_undo_snapshot(i, "FLATSHOT");
|
||||
|
|
@ -797,7 +797,7 @@ impl super::OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_output(&format!("FLATSHOT: created {n} projected edge(s) at Z=0."));
|
||||
.push_output(crate::tf!("FLATSHOT: created {n} projected edge(s) at Z=0.").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -816,7 +816,7 @@ impl super::OpenCADStudio {
|
|||
.collect();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error("CONVTOSURFACE: select a solid created this session.");
|
||||
.push_error(crate::t!("CONVTOSURFACE: select a solid created this session.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let mut surfaces: Vec<Surface> = Vec::new();
|
||||
|
|
@ -848,7 +848,7 @@ impl super::OpenCADStudio {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_output(&format!("CONVTOSURFACE: converted {n} solid(s) to surface(s)."));
|
||||
.push_output(crate::tf!("CONVTOSURFACE: converted {n} solid(s) to surface(s).").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -595,7 +595,7 @@ mod tests {
|
|||
}
|
||||
impl ocs_plugin_api::host::InteractiveCommand for PlacePoint {
|
||||
fn prompt(&self) -> String {
|
||||
"Pick a point".into()
|
||||
crate::t!("Pick a point").into_owned()
|
||||
}
|
||||
fn on_point(&mut self, pt: [f64; 3]) -> ocs_plugin_api::host::CommandStep {
|
||||
use ocs_plugin_api::host::CommandStep;
|
||||
|
|
@ -632,7 +632,7 @@ mod tests {
|
|||
struct PickThenMark;
|
||||
impl ocs_plugin_api::host::InteractiveCommand for PickThenMark {
|
||||
fn prompt(&self) -> String {
|
||||
"Pick an object".into()
|
||||
crate::t!("Pick an object").into_owned()
|
||||
}
|
||||
fn on_point(&mut self, _pt: [f64; 3]) -> ocs_plugin_api::host::CommandStep {
|
||||
ocs_plugin_api::host::CommandStep::Cancel
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use crate::io::linetypes;
|
|||
use crate::scene::view::dispatch;
|
||||
use crate::ui;
|
||||
use acadrust::{EntityType, Handle};
|
||||
use crate::t;
|
||||
|
||||
/// Above this many selected objects the Properties panel skips per-entity
|
||||
/// property aggregation (which is O(n) per row, plus an O(n²) group filter) and
|
||||
|
|
@ -259,30 +260,30 @@ impl OpenCADStudio {
|
|||
};
|
||||
let sections = vec![
|
||||
PropSection {
|
||||
title: "General".to_string(),
|
||||
title: t!("General").into_owned(),
|
||||
props: vec![
|
||||
read_only("AC Version", doc.version.as_str().to_string()),
|
||||
read_only(t!("AC Version").as_ref(), doc.version.as_str().to_string()),
|
||||
Property {
|
||||
label: "Color".to_string(),
|
||||
label: t!("Color").into_owned(),
|
||||
field: "color",
|
||||
value: PropValue::ColorChoice(header.current_entity_color),
|
||||
},
|
||||
Property {
|
||||
label: "Layer".to_string(),
|
||||
label: t!("Layer").into_owned(),
|
||||
field: "layer",
|
||||
value: PropValue::LayerChoice(current_layer),
|
||||
},
|
||||
Property {
|
||||
label: "Linetype".to_string(),
|
||||
label: t!("Linetype").into_owned(),
|
||||
field: "linetype",
|
||||
value: PropValue::LinetypeChoice(current_linetype),
|
||||
},
|
||||
read_only(
|
||||
"Linetype scale",
|
||||
t!("Linetype scale").as_ref(),
|
||||
format_length(header.current_entity_linetype_scale),
|
||||
),
|
||||
Property {
|
||||
label: "Lineweight".to_string(),
|
||||
label: t!("Lineweight").into_owned(),
|
||||
field: "line_weight",
|
||||
value: PropValue::LwChoice(
|
||||
acadrust::types::LineWeight::from_value(
|
||||
|
|
@ -290,21 +291,21 @@ impl OpenCADStudio {
|
|||
),
|
||||
),
|
||||
},
|
||||
read_only("Transparency", "ByLayer".to_string()),
|
||||
read_only("Thickness", format_length(header.thickness)),
|
||||
read_only(t!("Transparency").as_ref(), "ByLayer".to_string()),
|
||||
read_only(t!("Thickness").as_ref(), format_length(header.thickness)),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "3D Visualization".to_string(),
|
||||
props: vec![read_only("Material", material)],
|
||||
title: t!("3D Visualization").into_owned(),
|
||||
props: vec![read_only(t!("Material").as_ref(), material)],
|
||||
},
|
||||
PropSection {
|
||||
title: "Plot style".to_string(),
|
||||
title: t!("Plot style").into_owned(),
|
||||
props: vec![
|
||||
read_only("Plot style", plot_style.to_string()),
|
||||
read_only("Plot style table", plot_table.clone()),
|
||||
read_only(t!("Plot style").as_ref(), plot_style.to_string()),
|
||||
read_only(t!("Plot style table").as_ref(), plot_table.clone()),
|
||||
read_only(
|
||||
"Plot table attached to",
|
||||
t!("Plot table attached to").as_ref(),
|
||||
if plot_table == "None" {
|
||||
"None".to_string()
|
||||
} else {
|
||||
|
|
@ -312,7 +313,7 @@ impl OpenCADStudio {
|
|||
},
|
||||
),
|
||||
read_only(
|
||||
"Plot table type",
|
||||
t!("Plot table type").as_ref(),
|
||||
if header.plotstyle_mode {
|
||||
"Named plot styles".to_string()
|
||||
} else {
|
||||
|
|
@ -322,39 +323,39 @@ impl OpenCADStudio {
|
|||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "View".to_string(),
|
||||
title: t!("View").into_owned(),
|
||||
props: vec![
|
||||
read_only("Center X", format_length(camera.target.x)),
|
||||
read_only("Center Y", format_length(camera.target.y)),
|
||||
read_only("Center Z", format_length(camera.target.z)),
|
||||
read_only("Height", format_length(view_height)),
|
||||
read_only("Width", format_length(view_width)),
|
||||
read_only(t!("Center X").as_ref(), format_length(camera.target.x)),
|
||||
read_only(t!("Center Y").as_ref(), format_length(camera.target.y)),
|
||||
read_only(t!("Center Z").as_ref(), format_length(camera.target.z)),
|
||||
read_only(t!("Height").as_ref(), format_length(view_height)),
|
||||
read_only(t!("Width").as_ref(), format_length(view_width)),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".to_string(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
read_only("Annotation scale", annotation_scale),
|
||||
read_only(t!("Annotation scale").as_ref(), annotation_scale),
|
||||
read_only(
|
||||
"UCS icon On",
|
||||
t!("UCS icon On").as_ref(),
|
||||
if self.show_ucs_icon { "Yes" } else { "No" }.to_string(),
|
||||
),
|
||||
read_only(
|
||||
"UCS icon at origin",
|
||||
t!("UCS icon at origin").as_ref(),
|
||||
if self.ucs_icon_at_origin { "Yes" } else { "No" }
|
||||
.to_string(),
|
||||
),
|
||||
read_only(
|
||||
"UCS per viewport",
|
||||
t!("UCS per viewport").as_ref(),
|
||||
if ucs_per_viewport { "Yes" } else { "No" }.to_string(),
|
||||
),
|
||||
read_only("UCS Name", ucs_name),
|
||||
read_only("Visual Style", tab.visual_style.clone()),
|
||||
read_only(t!("UCS Name").as_ref(), ucs_name),
|
||||
read_only(t!("Visual Style").as_ref(), tab.visual_style.clone()),
|
||||
],
|
||||
},
|
||||
];
|
||||
ui::PropertiesPanel {
|
||||
title: "No selection".to_string(),
|
||||
title: t!("No selection").into_owned(),
|
||||
sections,
|
||||
layer_combo: iced::widget::combo_box::State::new(layer_names.clone()),
|
||||
linetype_combo: iced::widget::combo_box::State::new(
|
||||
|
|
@ -435,61 +436,61 @@ impl OpenCADStudio {
|
|||
{
|
||||
use crate::entities::common::ro_prop;
|
||||
sections.push(crate::scene::model::object::PropSection {
|
||||
title: "Material Details".to_string(),
|
||||
title: t!("Material Details").into_owned(),
|
||||
props: vec![
|
||||
ro_prop("Name", "mat_name", material.name.clone()),
|
||||
ro_prop(t!("Name").as_ref(), "mat_name", material.name.clone()),
|
||||
ro_prop(
|
||||
"Description",
|
||||
t!("Description").as_ref(),
|
||||
"mat_description",
|
||||
material.description.clone(),
|
||||
),
|
||||
ro_prop(
|
||||
"Ambient",
|
||||
t!("Ambient").as_ref(),
|
||||
"mat_ambient",
|
||||
material_color_text(&material.ambient_color),
|
||||
),
|
||||
ro_prop(
|
||||
"Diffuse",
|
||||
t!("Diffuse").as_ref(),
|
||||
"mat_diffuse",
|
||||
material_color_text(&material.diffuse_color),
|
||||
),
|
||||
ro_prop(
|
||||
"Specular",
|
||||
t!("Specular").as_ref(),
|
||||
"mat_specular",
|
||||
material_color_text(&material.specular_color),
|
||||
),
|
||||
ro_prop(
|
||||
"Gloss",
|
||||
t!("Gloss").as_ref(),
|
||||
"mat_gloss",
|
||||
format!("{:.3}", material.specular_gloss_factor),
|
||||
),
|
||||
ro_prop(
|
||||
"Opacity",
|
||||
t!("Opacity").as_ref(),
|
||||
"mat_opacity",
|
||||
format!("{:.3}", material.opacity_percent),
|
||||
),
|
||||
ro_prop(
|
||||
"Reflectivity",
|
||||
t!("Reflectivity").as_ref(),
|
||||
"mat_reflectivity",
|
||||
format!("{:.3}", material.reflectivity),
|
||||
),
|
||||
ro_prop(
|
||||
"Translucence",
|
||||
t!("Translucence").as_ref(),
|
||||
"mat_translucence",
|
||||
format!("{:.3}", material.translucence),
|
||||
),
|
||||
ro_prop(
|
||||
"Refraction",
|
||||
t!("Refraction").as_ref(),
|
||||
"mat_refraction",
|
||||
format!("{:.3}", material.refraction_index),
|
||||
),
|
||||
ro_prop(
|
||||
"Self Illumination",
|
||||
t!("Self Illumination").as_ref(),
|
||||
"mat_self_illumination",
|
||||
format!("{:.3}", material.self_illumination),
|
||||
),
|
||||
ro_prop(
|
||||
"Luminance",
|
||||
t!("Luminance").as_ref(),
|
||||
"mat_luminance",
|
||||
format!(
|
||||
"{:.3} (mode {})",
|
||||
|
|
@ -497,42 +498,42 @@ impl OpenCADStudio {
|
|||
),
|
||||
),
|
||||
ro_prop(
|
||||
"Diffuse Map",
|
||||
t!("Diffuse Map").as_ref(),
|
||||
"mat_diffuse_map",
|
||||
material_map_text(&material.diffuse_map),
|
||||
),
|
||||
ro_prop(
|
||||
"Specular Map",
|
||||
t!("Specular Map").as_ref(),
|
||||
"mat_specular_map",
|
||||
material_map_text(&material.specular_map),
|
||||
),
|
||||
ro_prop(
|
||||
"Reflection Map",
|
||||
t!("Reflection Map").as_ref(),
|
||||
"mat_reflection_map",
|
||||
material_map_text(&material.reflection_map),
|
||||
),
|
||||
ro_prop(
|
||||
"Opacity Map",
|
||||
t!("Opacity Map").as_ref(),
|
||||
"mat_opacity_map",
|
||||
material_map_text(&material.opacity_map),
|
||||
),
|
||||
ro_prop(
|
||||
"Bump Map",
|
||||
t!("Bump Map").as_ref(),
|
||||
"mat_bump_map",
|
||||
material_map_text(&material.bump_map),
|
||||
),
|
||||
ro_prop(
|
||||
"Refraction Map",
|
||||
t!("Refraction Map").as_ref(),
|
||||
"mat_refraction_map",
|
||||
material_map_text(&material.refraction_map),
|
||||
),
|
||||
ro_prop(
|
||||
"Normal Map",
|
||||
t!("Normal Map").as_ref(),
|
||||
"mat_normal_map",
|
||||
material_map_text(&material.normal_map),
|
||||
),
|
||||
ro_prop(
|
||||
"Render Flags",
|
||||
t!("Render Flags").as_ref(),
|
||||
"mat_render_flags",
|
||||
format!(
|
||||
"illumination {}; channels {}; mode {}; two-sided {}",
|
||||
|
|
@ -543,7 +544,7 @@ impl OpenCADStudio {
|
|||
),
|
||||
),
|
||||
ro_prop(
|
||||
"Advanced",
|
||||
t!("Advanced").as_ref(),
|
||||
"mat_advanced",
|
||||
format!(
|
||||
"normal {:.3}; bump {:.3}; reflect {:.3}; transmit {:.3}",
|
||||
|
|
@ -578,16 +579,16 @@ impl OpenCADStudio {
|
|||
}
|
||||
use crate::entities::common::ro_prop;
|
||||
sections.push(crate::scene::model::object::PropSection {
|
||||
title: "Color Book".to_string(),
|
||||
title: t!("Color Book").into_owned(),
|
||||
props: vec![
|
||||
ro_prop("Book", "book_color_book", book.book_name.clone()),
|
||||
ro_prop(t!("Book").as_ref(), "book_color_book", book.book_name.clone()),
|
||||
ro_prop(
|
||||
"Color Name",
|
||||
t!("Color Name").as_ref(),
|
||||
"book_color_name",
|
||||
book.color_name.clone(),
|
||||
),
|
||||
ro_prop(
|
||||
"Color",
|
||||
t!("Color").as_ref(),
|
||||
"book_color_value",
|
||||
format!("{:?}", book.color),
|
||||
),
|
||||
|
|
@ -616,25 +617,25 @@ impl OpenCADStudio {
|
|||
};
|
||||
use crate::entities::common::ro_prop;
|
||||
sections.push(crate::scene::model::object::PropSection {
|
||||
title: format!("{scope} Visual Style"),
|
||||
title: t!("%{scope} Visual Style", scope = scope).into_owned(),
|
||||
props: vec![
|
||||
ro_prop(
|
||||
"Handle",
|
||||
t!("Handle").as_ref(),
|
||||
"vs_handle",
|
||||
format!("{:X}", handle.value()),
|
||||
),
|
||||
ro_prop(
|
||||
"Description",
|
||||
t!("Description").as_ref(),
|
||||
"vs_description",
|
||||
style.description.clone(),
|
||||
),
|
||||
ro_prop(
|
||||
"Type",
|
||||
t!("Type").as_ref(),
|
||||
"vs_type",
|
||||
style.style_type.to_string(),
|
||||
),
|
||||
ro_prop(
|
||||
"Face",
|
||||
t!("Face").as_ref(),
|
||||
"vs_face",
|
||||
format!(
|
||||
"lighting {}; quality {}; color {}; modifiers {}",
|
||||
|
|
@ -645,7 +646,7 @@ impl OpenCADStudio {
|
|||
),
|
||||
),
|
||||
ro_prop(
|
||||
"Edges",
|
||||
t!("Edges").as_ref(),
|
||||
"vs_edges",
|
||||
format!(
|
||||
"model {}; style {}",
|
||||
|
|
@ -653,17 +654,17 @@ impl OpenCADStudio {
|
|||
),
|
||||
),
|
||||
ro_prop(
|
||||
"Extended Lighting",
|
||||
t!("Extended Lighting").as_ref(),
|
||||
"vs_extended_lighting",
|
||||
style.extended_lighting_model.to_string(),
|
||||
),
|
||||
ro_prop(
|
||||
"Internal",
|
||||
t!("Internal").as_ref(),
|
||||
"vs_internal",
|
||||
style.internal_use_only.to_string(),
|
||||
),
|
||||
ro_prop(
|
||||
"Property Bag",
|
||||
t!("Property Bag").as_ref(),
|
||||
"vs_properties",
|
||||
visual_style_properties_text(style),
|
||||
),
|
||||
|
|
@ -692,22 +693,22 @@ impl OpenCADStudio {
|
|||
let metrics = mesh.metrics;
|
||||
let mut props = vec![
|
||||
ro_prop(
|
||||
"Vertices",
|
||||
t!("Vertices").as_ref(),
|
||||
"mesh_vertices",
|
||||
metrics.vertices.to_string(),
|
||||
),
|
||||
ro_prop(
|
||||
"Triangles",
|
||||
t!("Triangles").as_ref(),
|
||||
"mesh_triangles",
|
||||
metrics.triangles.to_string(),
|
||||
),
|
||||
ro_prop(
|
||||
"Surface Area",
|
||||
t!("Surface Area").as_ref(),
|
||||
"mesh_surface_area",
|
||||
format!("{:.6}", metrics.surface_area),
|
||||
),
|
||||
ro_prop(
|
||||
"Centroid",
|
||||
t!("Centroid").as_ref(),
|
||||
"mesh_centroid",
|
||||
format!(
|
||||
"{:.6}, {:.6}, {:.6}",
|
||||
|
|
@ -717,7 +718,7 @@ impl OpenCADStudio {
|
|||
),
|
||||
),
|
||||
ro_prop(
|
||||
"Tessellation",
|
||||
t!("Tessellation").as_ref(),
|
||||
"mesh_complete",
|
||||
if mesh.complete { "Complete" } else { "Partial" },
|
||||
),
|
||||
|
|
@ -733,14 +734,14 @@ impl OpenCADStudio {
|
|||
props.insert(
|
||||
3,
|
||||
ro_prop(
|
||||
"Volume",
|
||||
t!("Volume").as_ref(),
|
||||
"mesh_volume",
|
||||
format!("{:.6}", metrics.volume),
|
||||
),
|
||||
);
|
||||
}
|
||||
sections.push(crate::scene::model::object::PropSection {
|
||||
title: "Mass Properties".to_string(),
|
||||
title: t!("Mass Properties").into_owned(),
|
||||
props,
|
||||
});
|
||||
}
|
||||
|
|
@ -770,7 +771,7 @@ impl OpenCADStudio {
|
|||
continue;
|
||||
};
|
||||
let toggle = crate::scene::model::object::Property {
|
||||
label: "Uniform scale".into(),
|
||||
label: t!("Uniform scale").into_owned(),
|
||||
field: "ins_uniform",
|
||||
value: crate::scene::model::object::PropValue::BoolToggle {
|
||||
field: "ins_uniform",
|
||||
|
|
@ -787,7 +788,7 @@ impl OpenCADStudio {
|
|||
.position(|p| p.field == "x_scale")
|
||||
.unwrap_or(xi.min(section.props.len()));
|
||||
section.props[xi] = crate::entities::common::edit_prop(
|
||||
"Scale",
|
||||
t!("Scale").as_ref(),
|
||||
"u_scale",
|
||||
ins.x_scale(),
|
||||
);
|
||||
|
|
@ -975,7 +976,7 @@ impl OpenCADStudio {
|
|||
|
||||
if let Some(geom) = sections.last_mut() {
|
||||
geom.props.push(crate::scene::model::object::Property {
|
||||
label: "Frozen Layers".to_string(),
|
||||
label: t!("Frozen Layers").into_owned(),
|
||||
field: "frozen_layers",
|
||||
value: crate::scene::model::object::PropValue::EditText(
|
||||
frozen_names.join(", "),
|
||||
|
|
@ -983,7 +984,7 @@ impl OpenCADStudio {
|
|||
});
|
||||
if !ucs_names.is_empty() {
|
||||
geom.props.push(crate::scene::model::object::Property {
|
||||
label: "UCS Name".to_string(),
|
||||
label: t!("UCS Name").into_owned(),
|
||||
field: "vp_ucs_name",
|
||||
value: crate::scene::model::object::PropValue::Choice {
|
||||
selected: current_ucs,
|
||||
|
|
@ -993,7 +994,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
if !view_names.is_empty() {
|
||||
geom.props.push(crate::scene::model::object::Property {
|
||||
label: "Named View".to_string(),
|
||||
label: t!("Named View").into_owned(),
|
||||
field: "vp_named_view",
|
||||
value: crate::scene::model::object::PropValue::Choice {
|
||||
selected: String::new(),
|
||||
|
|
@ -1385,7 +1386,7 @@ impl OpenCADStudio {
|
|||
&mut sections,
|
||||
anchor,
|
||||
crate::entities::common::ro_prop(
|
||||
"Annotative",
|
||||
t!("Annotative").as_ref(),
|
||||
"annotative",
|
||||
"No",
|
||||
),
|
||||
|
|
@ -1430,7 +1431,7 @@ impl OpenCADStudio {
|
|||
&mut sections,
|
||||
anno_field,
|
||||
crate::entities::common::ro_prop(
|
||||
"Annotative scale",
|
||||
t!("Annotative scale").as_ref(),
|
||||
"annotative_scale",
|
||||
doc.header.current_annotation_scale.clone(),
|
||||
),
|
||||
|
|
@ -1443,7 +1444,7 @@ impl OpenCADStudio {
|
|||
let label = group_names.join(", ");
|
||||
if let Some(general) = sections.first_mut() {
|
||||
general.props.push(crate::scene::model::object::Property {
|
||||
label: "Group".to_string(),
|
||||
label: t!("Group").into_owned(),
|
||||
field: "group",
|
||||
value: crate::scene::model::object::PropValue::ReadOnly(label),
|
||||
});
|
||||
|
|
@ -1460,7 +1461,7 @@ impl OpenCADStudio {
|
|||
.map(|br| br.flags.is_xref || br.flags.is_xref_overlay)
|
||||
.unwrap_or(false);
|
||||
if is_xref {
|
||||
"External Reference".to_string()
|
||||
t!("External Reference").into_owned()
|
||||
} else {
|
||||
entity_type_label(entity)
|
||||
}
|
||||
|
|
@ -1474,7 +1475,13 @@ impl OpenCADStudio {
|
|||
.filter_map(|prop| match &prop.value {
|
||||
crate::scene::model::object::PropValue::Choice { options, .. } => Some((
|
||||
prop.field.to_string(),
|
||||
iced::widget::combo_box::State::new(options.clone()),
|
||||
iced::widget::combo_box::State::new(
|
||||
options
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(ui::properties::LocalizedChoice::new)
|
||||
.collect(),
|
||||
),
|
||||
)),
|
||||
_ => None,
|
||||
})
|
||||
|
|
@ -1495,7 +1502,7 @@ impl OpenCADStudio {
|
|||
// for seconds at tens of thousands of objects. Above the cap show a
|
||||
// count-only panel; bulk edits still go through the ribbon.
|
||||
n if n > MAX_PROP_AGGREGATE => ui::PropertiesPanel {
|
||||
title: format!("{} objects selected", n),
|
||||
title: t!("%{count} objects selected", count = n).into_owned(),
|
||||
layer_combo: iced::widget::combo_box::State::new(layer_names.clone()),
|
||||
linetype_combo: iced::widget::combo_box::State::new(linetype_items.clone()),
|
||||
lineweight_combo: iced::widget::combo_box::State::new(
|
||||
|
|
@ -1529,13 +1536,19 @@ impl OpenCADStudio {
|
|||
.filter_map(|prop| match &prop.value {
|
||||
crate::scene::model::object::PropValue::Choice { options, .. } => Some((
|
||||
prop.field.to_string(),
|
||||
iced::widget::combo_box::State::new(options.clone()),
|
||||
iced::widget::combo_box::State::new(
|
||||
options
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(ui::properties::LocalizedChoice::new)
|
||||
.collect(),
|
||||
),
|
||||
)),
|
||||
_ => None,
|
||||
})
|
||||
.collect(),
|
||||
sections,
|
||||
title: format!("{} objects selected", selected.len()),
|
||||
title: t!("%{count} objects selected", count = selected.len()).into_owned(),
|
||||
selection_group_combo: iced::widget::combo_box::State::new(groups.clone()),
|
||||
selection_groups: groups,
|
||||
selected_group: active_group,
|
||||
|
|
@ -1998,7 +2011,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
Err(e) => {
|
||||
self.command_line
|
||||
.push_error(&format!("Viewport could not be added: {e}"));
|
||||
.push_error(crate::tf!("Viewport could not be added: {e}").as_ref());
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -2037,7 +2050,7 @@ pub(super) fn build_selection_groups(
|
|||
selected: &[(Handle, &EntityType)],
|
||||
) -> Vec<ui::properties::SelectionGroup> {
|
||||
let mut groups = vec![ui::properties::SelectionGroup {
|
||||
label: format!("All({})", selected.len()),
|
||||
label: format!("{} ({})", t!("All").into_owned(), selected.len()),
|
||||
handles: selected.iter().map(|(handle, _)| *handle).collect(),
|
||||
}];
|
||||
|
||||
|
|
@ -2052,7 +2065,7 @@ pub(super) fn build_selection_groups(
|
|||
|
||||
for (kind, handles) in by_type {
|
||||
groups.push(ui::properties::SelectionGroup {
|
||||
label: format!("{}({})", title_case_word(&kind), handles.len()),
|
||||
label: format!("{}({})", t!(title_case_word(&kind)), handles.len()),
|
||||
handles,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -593,7 +593,7 @@ impl OpenCADStudio {
|
|||
self.load_style_bufs(kind);
|
||||
self.after_style_change(kind);
|
||||
self.command_line
|
||||
.push_output(&format!("Style '{name}' created."));
|
||||
.push_output(crate::tf!("Style '{name}' created.").as_ref());
|
||||
}
|
||||
|
||||
pub(super) fn style_copy(&mut self, kind: StyleKind) {
|
||||
|
|
@ -608,19 +608,19 @@ impl OpenCADStudio {
|
|||
self.load_style_bufs(kind);
|
||||
self.after_style_change(kind);
|
||||
self.command_line
|
||||
.push_output(&format!("Style '{name}' created."));
|
||||
.push_output(crate::tf!("Style '{name}' created.").as_ref());
|
||||
}
|
||||
|
||||
pub(super) fn style_delete(&mut self, kind: StyleKind) {
|
||||
let name = self.style_selected(kind);
|
||||
if name.eq_ignore_ascii_case("Standard") {
|
||||
self.command_line
|
||||
.push_error("Cannot delete the Standard style.");
|
||||
.push_error(crate::t!("Cannot delete the Standard style.").as_ref());
|
||||
return;
|
||||
}
|
||||
if self.style_in_use(kind, &name) {
|
||||
self.command_line
|
||||
.push_error("Cannot delete a style that is current or in use.");
|
||||
.push_error(crate::t!("Cannot delete a style that is current or in use.").as_ref());
|
||||
return;
|
||||
}
|
||||
if !self.remove_style_storage(kind, &name) {
|
||||
|
|
@ -635,7 +635,7 @@ impl OpenCADStudio {
|
|||
self.load_style_bufs(kind);
|
||||
self.after_style_change(kind);
|
||||
self.command_line
|
||||
.push_output(&format!("Style '{name}' deleted."));
|
||||
.push_output(crate::tf!("Style '{name}' deleted.").as_ref());
|
||||
}
|
||||
|
||||
/// Begin inline rename of the double-clicked style.
|
||||
|
|
@ -659,12 +659,12 @@ impl OpenCADStudio {
|
|||
}
|
||||
if old.eq_ignore_ascii_case("Standard") {
|
||||
self.command_line
|
||||
.push_error("Cannot rename the Standard style.");
|
||||
.push_error(crate::t!("Cannot rename the Standard style.").as_ref());
|
||||
return;
|
||||
}
|
||||
if self.style_exists(kind, &new) {
|
||||
self.command_line
|
||||
.push_error(&format!("Style '{new}' already exists."));
|
||||
.push_error(crate::tf!("Style '{new}' already exists.").as_ref());
|
||||
return;
|
||||
}
|
||||
self.rename_style_storage(kind, &old, &new);
|
||||
|
|
@ -674,7 +674,7 @@ impl OpenCADStudio {
|
|||
self.load_style_bufs(kind);
|
||||
self.after_style_change(kind);
|
||||
self.command_line
|
||||
.push_output(&format!("Renamed '{old}' → '{new}'."));
|
||||
.push_output(crate::tf!("Renamed '{old}' → '{new}'.").as_ref());
|
||||
}
|
||||
|
||||
pub(super) fn style_rename_cancel(&mut self) {
|
||||
|
|
|
|||
|
|
@ -224,10 +224,10 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
let raw = crate::app::expr_eval::eval_to_string(self.command_line.input.trim());
|
||||
self.command_line.input.clear();
|
||||
let Ok(v) = raw.parse::<f64>() else {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"{}: expected a number, got \"{raw}\"",
|
||||
pending.label
|
||||
));
|
||||
).as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let i = self.active_tab;
|
||||
|
|
@ -443,9 +443,9 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
return self.apply_cmd_result(result);
|
||||
}
|
||||
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"Expected coordinates (x,y) or a number, got: \"{text}\""
|
||||
));
|
||||
).as_ref());
|
||||
return self.focus_cmd_input();
|
||||
}
|
||||
if let Some(cmd) = self.command_line.submit() {
|
||||
|
|
@ -519,7 +519,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
}
|
||||
// Esc cancels a pending system-variable value prompt.
|
||||
if self.pending_setvar.take().is_some() {
|
||||
self.command_line.push_info("*Cancel*");
|
||||
self.command_line.push_info(crate::t!("*Cancel*").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
// UCS icon: Esc ends any grip drag and clears the selection
|
||||
|
|
@ -548,7 +548,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
sel.middle_down = false;
|
||||
sel.middle_last_pos = None;
|
||||
}
|
||||
self.command_line.push_output("PAN ended.");
|
||||
self.command_line.push_output(crate::t!("PAN ended.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
// Grip popup intercepts Escape — dismisses the menu
|
||||
|
|
@ -738,7 +738,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
names.retain(|n| n != "0" && *n != current);
|
||||
if names.len() < before {
|
||||
self.command_line
|
||||
.push_info("Layer \"0\" and the current layer can't be deleted — skipped.");
|
||||
.push_info(crate::t!("Layer \"0\" and the current layer can't be deleted — skipped.").as_ref());
|
||||
}
|
||||
if names.is_empty() {
|
||||
return Task::none();
|
||||
|
|
@ -971,7 +971,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
action: item.action,
|
||||
label,
|
||||
});
|
||||
self.command_line.push_info(&format!("{label}:"));
|
||||
self.command_line.push_info(crate::tf!("{label}:").as_ref());
|
||||
return self.focus_cmd_input();
|
||||
}
|
||||
// Break at vertex replaces the entity with the split pieces —
|
||||
|
|
@ -993,11 +993,11 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
self.tabs[i].dirty = true;
|
||||
self.refresh_selected_grips();
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output("Polyline broken at vertex.");
|
||||
self.command_line.push_output(crate::t!("Polyline broken at vertex.").as_ref());
|
||||
}
|
||||
None => self
|
||||
.command_line
|
||||
.push_error("Cannot break at this vertex."),
|
||||
.push_error(crate::t!("Cannot break at this vertex.").as_ref()),
|
||||
}
|
||||
return Task::none();
|
||||
}
|
||||
|
|
@ -1042,7 +1042,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
self.tabs[i].dirty = dirty_before;
|
||||
self.refresh_selected_grips();
|
||||
self.refresh_properties();
|
||||
self.command_line.push_error("Cannot add a vertex here.");
|
||||
self.command_line.push_error(crate::t!("Cannot add a vertex here.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
self.tabs[i]
|
||||
|
|
@ -1069,7 +1069,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
grip_world,
|
||||
));
|
||||
self.command_line
|
||||
.push_info("Specify new vertex location:");
|
||||
.push_info(crate::t!("Specify new vertex location:").as_ref());
|
||||
} else {
|
||||
if let Some(entity) =
|
||||
self.tabs[i].scene.document.get_entity_mut(popup.handle)
|
||||
|
|
@ -1083,7 +1083,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
self.refresh_selected_grips();
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_error("Cannot place the new vertex.");
|
||||
.push_error(crate::t!("Cannot place the new vertex.").as_ref());
|
||||
}
|
||||
return Task::none();
|
||||
}
|
||||
|
|
@ -2084,9 +2084,9 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
// The block's layer may have been locked while the editor was open —
|
||||
// refuse to write attributes to a locked-layer block.
|
||||
if let Some(layer) = self.tabs[i].scene.locked_layer_name(handle) {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"Object is on locked layer \"{layer}\" — unlock the layer to edit its attributes."
|
||||
));
|
||||
).as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
// Snapshot the working copy so the document can be mutated while the
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
|
|||
if self.tabs[self.active_tab].is_start && !matches!(event, ModuleEvent::Command(_)) {
|
||||
self.ribbon.close_dropdown();
|
||||
self.command_line
|
||||
.push_info("No drawing open — use New or Open first.");
|
||||
.push_info(crate::t!("No drawing open — use New or Open first.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
// Dismiss any open dropdown / collapsed-panel flyout on tool use,
|
||||
|
|
@ -141,13 +141,13 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
|
|||
}
|
||||
ModuleEvent::OpenFileDialog => {
|
||||
self.command_line
|
||||
.push_info("Open DWG/DXF: not yet implemented.");
|
||||
.push_info(crate::t!("Open DWG/DXF: not yet implemented.").as_ref());
|
||||
}
|
||||
ModuleEvent::ClearModels => {
|
||||
let i = self.active_tab;
|
||||
self.tabs[i].scene.clear();
|
||||
self.tabs[i].properties = PropertiesPanel::empty();
|
||||
self.command_line.push_output("Scene cleared.");
|
||||
self.command_line.push_output(crate::t!("Scene cleared.").as_ref());
|
||||
}
|
||||
ModuleEvent::SetWireframe(w) => {
|
||||
let i = self.active_tab;
|
||||
|
|
@ -265,7 +265,7 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
|
|||
|
||||
if self.active_save_jobs.contains_key(&self.tabs[idx].id) {
|
||||
self.command_line
|
||||
.push_info("Save already running for this drawing.");
|
||||
.push_info(crate::t!("Save already running for this drawing.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -659,7 +659,10 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
.is_some_and(|(loaded, current)| loaded != current)
|
||||
{
|
||||
self.command_line.push_error_once(
|
||||
"Drawing changed on disk while it was opening; Save will require conflict resolution.",
|
||||
crate::t!(
|
||||
"Drawing changed on disk while it was opening; Save will require conflict resolution."
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
}
|
||||
self.tabs[i].disk_fingerprint =
|
||||
|
|
@ -667,9 +670,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
match crate::io::edit_lock::EditLease::acquire(path) {
|
||||
Ok(lease) => {
|
||||
if let Some(warning) = lease.platform_warning() {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"Edit lease active; {warning}. External-change checks remain active."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
self.tabs[i].edit_lease = Some(lease);
|
||||
self.tabs[i].edit_lock_conflict = false;
|
||||
|
|
@ -677,16 +680,16 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
Err(crate::io::edit_lock::EditLeaseError::Locked(error)) => {
|
||||
self.tabs[i].edit_lease = None;
|
||||
self.tabs[i].edit_lock_conflict = true;
|
||||
self.command_line.push_error_once(&format!(
|
||||
self.command_line.push_error_once(crate::tf!(
|
||||
"Opened read-only against other editors: {error}"
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
Err(crate::io::edit_lock::EditLeaseError::Unavailable(error)) => {
|
||||
self.tabs[i].edit_lease = None;
|
||||
self.tabs[i].edit_lock_conflict = false;
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{error}. External-change checks remain active."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -718,22 +721,22 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
Some(Ok(warning)) => {
|
||||
self.tabs[i].edit_lock_conflict = false;
|
||||
if let Some(warning) = warning {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{warning}. External-change checks remain active."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
Some(Err(crate::io::edit_lock::EditLeaseError::Locked(error))) => {
|
||||
self.tabs[i].edit_lock_conflict = true;
|
||||
self.command_line.push_error_once(&format!(
|
||||
self.command_line.push_error_once(crate::tf!(
|
||||
"Saved, but the refreshed drawing is locked by another editor: {error}"
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
Some(Err(crate::io::edit_lock::EditLeaseError::Unavailable(error))) => {
|
||||
self.tabs[i].edit_lock_conflict = false;
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{error}. External-change checks remain active."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
None => self.install_native_edit_guard(i, path, None),
|
||||
}
|
||||
|
|
@ -765,9 +768,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
return Err(crate::io::SaveFailure::file_in_use(error));
|
||||
}
|
||||
Err(crate::io::edit_lock::EditLeaseError::Unavailable(error)) => {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{error}. External-change checks remain active."
|
||||
));
|
||||
).as_ref());
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -829,9 +832,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
let warning = lease.platform_warning().map(str::to_owned);
|
||||
self.tabs[i].edit_lock_conflict = false;
|
||||
if let Some(warning) = warning {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{warning}. External-change checks remain active."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
|
@ -840,9 +843,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
}
|
||||
Err(crate::io::edit_lock::EditLeaseError::Unavailable(error)) => {
|
||||
self.tabs[i].edit_lock_conflict = false;
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{error}. External-change checks remain active."
|
||||
));
|
||||
).as_ref());
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
|
@ -854,18 +857,18 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
self.tabs[i].edit_lease = Some(lease);
|
||||
self.tabs[i].edit_lock_conflict = false;
|
||||
if let Some(warning) = warning {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{warning}. External-change checks remain active."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Err(crate::io::edit_lock::EditLeaseError::Locked(error)) => Err(error),
|
||||
Err(crate::io::edit_lock::EditLeaseError::Unavailable(error)) => {
|
||||
self.tabs[i].edit_lock_conflict = false;
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{error}. External-change checks remain active."
|
||||
));
|
||||
).as_ref());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -883,34 +886,34 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
let timings = caches.timings;
|
||||
let entity_count = doc.entities().count();
|
||||
self.command_line
|
||||
.push_output(&format!("Opened \"{name}\" — {entity_count} entities"));
|
||||
.push_output(crate::tf!("Opened \"{name}\" — {entity_count} entities").as_ref());
|
||||
if caches.corrupt_dropped > 0 {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"Warning: {} corrupt entities dropped (parser junk — bad normals / counts)",
|
||||
caches.corrupt_dropped
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
if caches.xref_dropped > 0 {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"Warning: {} corrupt xref entities dropped",
|
||||
caches.xref_dropped
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
for info in &caches.xrefs {
|
||||
match info.status {
|
||||
crate::io::xref::XrefStatus::Loaded => {
|
||||
self.command_line
|
||||
.push_output(&format!("XREF Loaded \"{}\"", info.name));
|
||||
.push_output(crate::tf!("XREF Loaded \"{}\"", info.name).as_ref());
|
||||
}
|
||||
crate::io::xref::XrefStatus::NotFound => {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"XREF Not found: \"{}\" ({})",
|
||||
info.name, info.path
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
crate::io::xref::XrefStatus::Unloaded => {
|
||||
self.command_line
|
||||
.push_info(&format!("XREF Unloaded (skipped): \"{}\"", info.name));
|
||||
.push_info(crate::tf!("XREF Unloaded (skipped): \"{}\"", info.name).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -982,10 +985,10 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
let total_ms = open_started
|
||||
.map(|s| s.elapsed().as_millis() as u32)
|
||||
.unwrap_or(0);
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
" parse {}ms · purge {}ms · caches {}ms · xref {}ms · total {}ms",
|
||||
timings.parse_ms, timings.purge_ms, timings.caches_ms, timings.xref_ms, total_ms
|
||||
));
|
||||
).as_ref());
|
||||
|
||||
// Caches were built on the background thread inside open_path().
|
||||
self.tabs[i].scene.local_extent_max = caches.local_extent_max;
|
||||
|
|
@ -1209,7 +1212,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
if self.active_save_jobs.contains_key(&tab_id) {
|
||||
if purpose != crate::app::SavePurpose::Autosave {
|
||||
self.command_line
|
||||
.push_info("Save already running for this drawing.");
|
||||
.push_info(crate::t!("Save already running for this drawing.").as_ref());
|
||||
}
|
||||
return Task::none();
|
||||
}
|
||||
|
|
@ -1218,12 +1221,12 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
&& self.tabs[i].edit_lock_conflict
|
||||
{
|
||||
let error = "Drawing edit lock is held by another editor.".to_string();
|
||||
self.command_line.push_error_once(&format!(
|
||||
self.command_line.push_error_once(crate::tf!(
|
||||
"Unable to save \"{}\": {error}",
|
||||
path.file_name()
|
||||
.map(|name| name.to_string_lossy().into_owned())
|
||||
.unwrap_or_else(|| path.display().to_string())
|
||||
));
|
||||
).as_ref());
|
||||
self.pending_save_failure = Some(crate::app::PendingSaveFailure {
|
||||
tab_id,
|
||||
path,
|
||||
|
|
@ -1248,12 +1251,12 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
self.pending_save_leases.insert(tab_id, lease);
|
||||
}
|
||||
Err(crate::io::edit_lock::EditLeaseError::Locked(error)) => {
|
||||
self.command_line.push_error_once(&format!(
|
||||
self.command_line.push_error_once(crate::tf!(
|
||||
"Unable to save \"{}\": {error}",
|
||||
path.file_name()
|
||||
.map(|name| name.to_string_lossy().into_owned())
|
||||
.unwrap_or_else(|| path.display().to_string())
|
||||
));
|
||||
).as_ref());
|
||||
self.pending_save_failure = Some(crate::app::PendingSaveFailure {
|
||||
tab_id,
|
||||
path,
|
||||
|
|
@ -1268,9 +1271,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
return Task::none();
|
||||
}
|
||||
Err(crate::io::edit_lock::EditLeaseError::Unavailable(error)) => {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{error}. External-change checks remain active."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1424,9 +1427,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
.file_name()
|
||||
.map(|name| name.to_string_lossy().into_owned())
|
||||
.unwrap_or_else(|| outcome.path.display().to_string());
|
||||
self.command_line.push_error_once(&format!(
|
||||
self.command_line.push_error_once(crate::tf!(
|
||||
"Save stopped: \"{file_name}\" changed outside Open CAD Studio."
|
||||
));
|
||||
).as_ref());
|
||||
self.pending_external_change = Some(crate::app::PendingExternalChange {
|
||||
tab_id: outcome.tab_id,
|
||||
path: outcome.path.clone(),
|
||||
|
|
@ -1445,9 +1448,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
.file_name()
|
||||
.map(|name| name.to_string_lossy().into_owned())
|
||||
.unwrap_or_else(|| outcome.path.display().to_string());
|
||||
self.command_line.push_error_once(&format!(
|
||||
self.command_line.push_error_once(crate::tf!(
|
||||
"Unable to save \"{file_name}\": file is in use by another application."
|
||||
));
|
||||
).as_ref());
|
||||
self.pending_save_failure = Some(crate::app::PendingSaveFailure {
|
||||
tab_id: outcome.tab_id,
|
||||
path: outcome.path.clone(),
|
||||
|
|
@ -1470,7 +1473,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
return Task::none();
|
||||
}
|
||||
self.command_line
|
||||
.push_error(&format!("Save failed: {error}"));
|
||||
.push_error(crate::tf!("Save failed: {error}").as_ref());
|
||||
return match outcome.continuation {
|
||||
crate::app::SaveContinuation::CloseTab => {
|
||||
self.pending_close = Some(crate::app::PendingClose::Tab(i));
|
||||
|
|
@ -1496,7 +1499,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
let mut tasks = Vec::new();
|
||||
match outcome.purpose {
|
||||
crate::app::SavePurpose::Autosave => {
|
||||
self.command_line.push_output("Autosaved 1 drawing");
|
||||
self.command_line.push_output(crate::t!("Autosaved 1 drawing").as_ref());
|
||||
}
|
||||
crate::app::SavePurpose::Manual | crate::app::SavePurpose::SaveAs => {
|
||||
let path_changed = outcome.set_current_path
|
||||
|
|
@ -1507,7 +1510,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
!native_paths_match(current, &outcome.path)
|
||||
});
|
||||
self.command_line
|
||||
.push_output(&format!("Saved: {}", outcome.path.display()));
|
||||
.push_output(crate::tf!("Saved: {}", outcome.path.display()).as_ref());
|
||||
self.recent_thumbs.remove(&outcome.path);
|
||||
if let Some(previous) = outcome.previous_autosave {
|
||||
if previous != outcome.path {
|
||||
|
|
@ -1594,7 +1597,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
self.pending_save_failure = Some(failure);
|
||||
self.restore_failed_save_continuation(continuation, i);
|
||||
self.command_line
|
||||
.push_error_once(&format!("Unable to acquire edit lock: {error}"));
|
||||
.push_error_once(crate::tf!("Unable to acquire edit lock: {error}").as_ref());
|
||||
self.active_modal = Some(crate::app::ModalKind::FileInUse);
|
||||
return Task::none();
|
||||
}
|
||||
|
|
@ -1690,7 +1693,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
Err(error) => {
|
||||
self.close_active_modal();
|
||||
self.command_line
|
||||
.push_error(&format!("Reload failed: {error}"));
|
||||
.push_error(crate::tf!("Reload failed: {error}").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
};
|
||||
|
|
@ -1709,7 +1712,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
pub(super) fn on_save_file(&mut self) -> Task<Message> {
|
||||
if self.read_only {
|
||||
self.command_line
|
||||
.push_error("Read-only session (--read-only): saving is disabled.");
|
||||
.push_error(crate::t!("Read-only session (--read-only): saving is disabled.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let i = self.active_tab;
|
||||
|
|
@ -1859,11 +1862,11 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
},
|
||||
Message::WebRecentStored,
|
||||
);
|
||||
self.command_line.push_output(&format!("Saved: {filename}"));
|
||||
self.command_line.push_output(crate::tf!("Saved: {filename}").as_ref());
|
||||
true
|
||||
}
|
||||
Err(e) => {
|
||||
self.command_line.push_error(&format!("Save failed: {e}"));
|
||||
self.command_line.push_error(crate::tf!("Save failed: {e}").as_ref());
|
||||
false
|
||||
}
|
||||
};
|
||||
|
|
@ -2163,10 +2166,10 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_geometry_no_blocks();
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"Page setup: {w:.1}×{h:.1} mm area={plot_area} \
|
||||
center={center} rot={rotation}°"
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2178,7 +2181,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
self.direct_plot_params()
|
||||
else {
|
||||
self.command_line
|
||||
.push_error("Nothing to plot: model space contains no printable geometry.");
|
||||
.push_error(crate::t!("Nothing to plot: model space contains no printable geometry.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let plot_style = self.dialog_plot_style(&self.plot_dialog);
|
||||
|
|
@ -2221,7 +2224,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
job
|
||||
else {
|
||||
self.command_line
|
||||
.push_error("Plot area is empty. Pick a larger window.");
|
||||
.push_error(crate::t!("Plot area is empty. Pick a larger window.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let plot_style = self.dialog_plot_style(&self.plot_dialog);
|
||||
|
|
@ -2533,12 +2536,12 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
self.direct_plot_params()
|
||||
else {
|
||||
self.command_line
|
||||
.push_error("Nothing to plot: model space contains no printable geometry.");
|
||||
.push_error(crate::t!("Nothing to plot: model space contains no printable geometry.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let plot_style = self.dialog_plot_style(&self.plot_dialog);
|
||||
let options = self.plot_print_options(&self.plot_dialog, group_splits);
|
||||
self.command_line.push_info("Sending to system printer…");
|
||||
self.command_line.push_info(crate::t!("Sending to system printer…").as_ref());
|
||||
background_task(
|
||||
move || {
|
||||
iced::futures::executor::block_on(
|
||||
|
|
@ -2561,7 +2564,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
let i = self.active_tab;
|
||||
if self.tabs[i].scene.current_layout != "Model" {
|
||||
self.command_line
|
||||
.push_error("Quick print works in model space.");
|
||||
.push_error(crate::t!("Quick print works in model space.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let set: std::collections::HashSet<acadrust::Handle> = handles.into_iter().collect();
|
||||
|
|
@ -2593,12 +2596,12 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
};
|
||||
if !any {
|
||||
self.command_line
|
||||
.push_error("Selection has no printable geometry.");
|
||||
.push_error(crate::t!("Selection has no printable geometry.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
if !(x1 > x0 && y1 > y0) {
|
||||
self.command_line
|
||||
.push_error("Selection has no printable area.");
|
||||
.push_error(crate::t!("Selection has no printable area.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
// Small margin so the outermost strokes aren't clipped flush to the edge.
|
||||
|
|
@ -2786,7 +2789,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
match crate::io::print_to_printer::open_printer_properties(
|
||||
self.plot_dialog.printer.as_deref(),
|
||||
) {
|
||||
Ok(()) => self.command_line.push_info("Opened printer properties."),
|
||||
Ok(()) => self.command_line.push_info(crate::t!("Opened printer properties.").as_ref()),
|
||||
Err(error) => self.command_line.push_error(&error),
|
||||
}
|
||||
Task::none()
|
||||
|
|
@ -2924,7 +2927,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
}
|
||||
M::SetCurrent => {
|
||||
self.apply_dialog_to_layout();
|
||||
self.command_line.push_info("Page setup applied to the layout.");
|
||||
self.command_line.push_info(crate::t!("Page setup applied to the layout.").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
M::NewSetup => {
|
||||
|
|
@ -3327,10 +3330,10 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
fn on_plot_dlg_commit(&mut self, preview: bool) -> Task<Message> {
|
||||
let d = self.plot_dialog.clone();
|
||||
if d.style_missing {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"Plot style table '{}' is not loaded.",
|
||||
d.style_name
|
||||
));
|
||||
).as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
// Remember the user's print preferences across sessions.
|
||||
|
|
@ -3365,7 +3368,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
)) = job
|
||||
else {
|
||||
self.command_line
|
||||
.push_error("Plot area is empty. Pick a larger window.");
|
||||
.push_error(crate::t!("Plot area is empty. Pick a larger window.").as_ref());
|
||||
self.active_modal = Some(crate::app::ModalKind::Plot);
|
||||
return Task::none();
|
||||
};
|
||||
|
|
@ -3436,7 +3439,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
}
|
||||
|
||||
let opts = self.plot_print_options(&d, group_splits);
|
||||
self.command_line.push_info("Sending to system printer…");
|
||||
self.command_line.push_info(crate::t!("Sending to system printer…").as_ref());
|
||||
let work = move || {
|
||||
iced::futures::executor::block_on(
|
||||
crate::io::print_to_printer::print_wires_with(
|
||||
|
|
@ -3692,7 +3695,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
entry.screening = sc.min(100);
|
||||
}
|
||||
self.command_line
|
||||
.push_output(&format!("Plot style ACI {aci} updated."));
|
||||
.push_output(crate::tf!("Plot style ACI {aci} updated.").as_ref());
|
||||
}
|
||||
} else {
|
||||
// No table loaded: create an identity table and apply.
|
||||
|
|
@ -3714,7 +3717,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
}
|
||||
self.active_plot_style = Some(table);
|
||||
self.command_line
|
||||
.push_output(&format!("Created new CTB table, ACI {aci} updated."));
|
||||
.push_output(crate::tf!("Created new CTB table, ACI {aci} updated.").as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -3722,7 +3725,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
pub(super) fn on_plot_style_panel_save(&mut self) -> Task<Message> {
|
||||
if self.active_plot_style.is_none() {
|
||||
self.command_line
|
||||
.push_error("No plot style table loaded. Load or create one first.");
|
||||
.push_error(crate::t!("No plot style table loaded. Load or create one first.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let default_name = self
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ impl OpenCADStudio {
|
|||
Err(e) => {
|
||||
crate::scene::text::web_font::insert(script, None);
|
||||
self.command_line
|
||||
.push_error(&format!("Font load failed ({script:?}): {e}"));
|
||||
.push_error(crate::tf!("Font load failed ({script:?}): {e}").as_ref());
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
|
|
@ -323,10 +323,10 @@ impl OpenCADStudio {
|
|||
return match std::fs::metadata(&path) {
|
||||
Ok(m) => self.update(Message::OpenPathPicked(Some((path, m.len())))),
|
||||
Err(_) => {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"Recent file no longer exists: {}",
|
||||
path.display()
|
||||
));
|
||||
).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
};
|
||||
|
|
@ -489,7 +489,7 @@ impl OpenCADStudio {
|
|||
.map(|(_, _, l)| *l)
|
||||
.unwrap_or("Snap");
|
||||
self.command_line
|
||||
.push_info(&format!("Snap override: {label} (next pick only)."));
|
||||
.push_info(crate::tf!("Snap override: {label} (next pick only).").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -507,10 +507,10 @@ impl OpenCADStudio {
|
|||
.map(|e| e.to_string_lossy().to_lowercase())
|
||||
.unwrap_or_default();
|
||||
if !matches!(ext.as_str(), "dwg" | "dxf" | "bak" | "sv$") {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"Unsupported file type: {}",
|
||||
path.display()
|
||||
));
|
||||
).as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
// Already open → switch to its tab; a load in progress →
|
||||
|
|
@ -563,7 +563,7 @@ impl OpenCADStudio {
|
|||
});
|
||||
let size_label = format_size(size_bytes);
|
||||
self.command_line
|
||||
.push_info(&format!("Opening \"{name}\" ({size_label})…"));
|
||||
.push_info(crate::tf!("Opening \"{name}\" ({size_label})…").as_ref());
|
||||
let model_bg = self.default_bg_color.unwrap_or([
|
||||
33.0 / 255.0,
|
||||
40.0 / 255.0,
|
||||
|
|
@ -579,7 +579,7 @@ impl OpenCADStudio {
|
|||
Message::OpenCancel => {
|
||||
if let Some(p) = self.opening.take() {
|
||||
self.command_line
|
||||
.push_info(&format!("Open cancelled: \"{}\"", p.name));
|
||||
.push_info(crate::tf!("Open cancelled: \"{}\"", p.name).as_ref());
|
||||
}
|
||||
self.drain_pending_open()
|
||||
}
|
||||
|
|
@ -593,7 +593,7 @@ impl OpenCADStudio {
|
|||
// we suppress the noise.
|
||||
let was_open = self.opening.take().is_some();
|
||||
if was_open && e != "Cancelled" {
|
||||
self.command_line.push_error(&format!("Open failed: {e}"));
|
||||
self.command_line.push_error(crate::tf!("Open failed: {e}").as_ref());
|
||||
}
|
||||
// A drawing that fails to parse must not strand the ones queued
|
||||
// behind it.
|
||||
|
|
@ -604,9 +604,9 @@ impl OpenCADStudio {
|
|||
Message::WebRecentStored(result) => match result {
|
||||
Ok(path) => self.push_recent(path),
|
||||
Err(error) => {
|
||||
self.command_line.push_error(&format!(
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"Saved download, but recent copy could not be stored: {error}"
|
||||
));
|
||||
).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
},
|
||||
|
|
@ -625,7 +625,7 @@ impl OpenCADStudio {
|
|||
.unwrap_or(&path_str)
|
||||
.to_string();
|
||||
self.command_line
|
||||
.push_output(&format!("IMAGE \"{short}\": {pw}×{ph} px"));
|
||||
.push_output(crate::tf!("IMAGE \"{short}\": {pw}×{ph} px").as_ref());
|
||||
let cmd = ImageCommand::new(path_str, pw, ph);
|
||||
let i = self.active_tab;
|
||||
self.command_line.push_info(&cmd.prompt());
|
||||
|
|
@ -635,7 +635,7 @@ impl OpenCADStudio {
|
|||
|
||||
Message::ImagePickResult(Err(e)) => {
|
||||
if e != "Cancelled" {
|
||||
self.command_line.push_error(&format!("IMAGE: {e}"));
|
||||
self.command_line.push_error(crate::tf!("IMAGE: {e}").as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -671,7 +671,7 @@ impl OpenCADStudio {
|
|||
|
||||
Message::XAttachPickResult(Err(e)) => {
|
||||
if e != "Cancelled" {
|
||||
self.command_line.push_error(&format!("XATTACH: {e}"));
|
||||
self.command_line.push_error(crate::tf!("XATTACH: {e}").as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -701,13 +701,13 @@ impl OpenCADStudio {
|
|||
|
||||
Message::WblockWriteFinished(block_name, path, result) => {
|
||||
match result {
|
||||
Ok(()) => self.command_line.push_output(&format!(
|
||||
Ok(()) => self.command_line.push_output(crate::tf!(
|
||||
"WBLOCK Saved \"{block_name}\" → \"{}\"",
|
||||
path.display()
|
||||
)),
|
||||
).as_ref()),
|
||||
Err(error) => self
|
||||
.command_line
|
||||
.push_error(&format!("WBLOCK save failed: {error}")),
|
||||
.push_error(crate::tf!("WBLOCK save failed: {error}").as_ref()),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -739,11 +739,11 @@ impl OpenCADStudio {
|
|||
.map(|n| n.to_string_lossy().into_owned())
|
||||
.unwrap_or_else(|| path.to_string_lossy().into_owned());
|
||||
self.command_line
|
||||
.push_output(&format!("DATAEXTRACTION {rows} rows → \"{fname}\""));
|
||||
.push_output(crate::tf!("DATAEXTRACTION {rows} rows → \"{fname}\"").as_ref());
|
||||
}
|
||||
Err(e) => self
|
||||
.command_line
|
||||
.push_error(&format!("DATAEXTRACTION: write failed: {e}")),
|
||||
.push_error(crate::tf!("DATAEXTRACTION: write failed: {e}").as_ref()),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -754,7 +754,7 @@ impl OpenCADStudio {
|
|||
let i = self.active_tab;
|
||||
if self.tabs[i].scene.meshes.is_empty() {
|
||||
self.command_line
|
||||
.push_error("STLOUT: no 3D mesh data in this drawing.");
|
||||
.push_error(crate::t!("STLOUT: no 3D mesh data in this drawing.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
Task::perform(
|
||||
|
|
@ -780,8 +780,8 @@ impl OpenCADStudio {
|
|||
match result {
|
||||
Ok(()) => self
|
||||
.command_line
|
||||
.push_output(&format!("STLOUT: exported to \"{}\"", path.display())),
|
||||
Err(error) => self.command_line.push_error(&format!("STLOUT: {error}")),
|
||||
.push_output(crate::tf!("STLOUT: exported to \"{}\"", path.display()).as_ref()),
|
||||
Err(error) => self.command_line.push_error(crate::tf!("STLOUT: {error}").as_ref()),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -791,7 +791,7 @@ impl OpenCADStudio {
|
|||
let i = self.active_tab;
|
||||
if self.tabs[i].scene.meshes.is_empty() {
|
||||
self.command_line
|
||||
.push_error("STEPOUT: no 3D mesh data in this drawing.");
|
||||
.push_error(crate::t!("STEPOUT: no 3D mesh data in this drawing.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
Task::perform(
|
||||
|
|
@ -817,8 +817,8 @@ impl OpenCADStudio {
|
|||
match result {
|
||||
Ok(()) => self
|
||||
.command_line
|
||||
.push_output(&format!("STEPOUT: exported to \"{}\"", path.display())),
|
||||
Err(error) => self.command_line.push_error(&format!("STEPOUT: {error}")),
|
||||
.push_output(crate::tf!("STEPOUT: exported to \"{}\"", path.display()).as_ref()),
|
||||
Err(error) => self.command_line.push_error(crate::tf!("STEPOUT: {error}").as_ref()),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -843,11 +843,11 @@ impl OpenCADStudio {
|
|||
|
||||
Message::ObjImportFinished(tab_id, path, result) => {
|
||||
match result {
|
||||
Err(error) => self.command_line.push_error(&format!("IMPORTOBJ: {error}")),
|
||||
Err(error) => self.command_line.push_error(crate::tf!("IMPORTOBJ: {error}").as_ref()),
|
||||
Ok(mut mesh) => {
|
||||
let Some(i) = self.tabs.iter().position(|tab| tab.id == tab_id) else {
|
||||
self.command_line
|
||||
.push_info("IMPORTOBJ: target drawing was closed.");
|
||||
.push_info(crate::t!("IMPORTOBJ: target drawing was closed.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let file_stem = path
|
||||
|
|
@ -864,9 +864,9 @@ impl OpenCADStudio {
|
|||
.meshes
|
||||
.insert(handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"IMPORTOBJ: imported \"{file_stem}\" as mesh."
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -878,7 +878,7 @@ impl OpenCADStudio {
|
|||
Message::SaveAs => {
|
||||
if self.read_only {
|
||||
self.command_line
|
||||
.push_error("Read-only session (--read-only): saving is disabled.");
|
||||
.push_error(crate::t!("Read-only session (--read-only): saving is disabled.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let i = self.active_tab;
|
||||
|
|
@ -924,7 +924,7 @@ impl OpenCADStudio {
|
|||
.layers
|
||||
.sync_with_viewports(&doc_layers, vp_info);
|
||||
self.command_line
|
||||
.push_output("Scene cleared. Standard linetypes loaded.");
|
||||
.push_output(crate::t!("Scene cleared. Standard linetypes loaded.").as_ref());
|
||||
self.tabs[i].current_path = None;
|
||||
self.tabs[i].dirty = true;
|
||||
self.sync_ribbon_layers();
|
||||
|
|
@ -988,7 +988,7 @@ impl OpenCADStudio {
|
|||
let i = self.active_tab;
|
||||
if !crate::plugin::try_dispatch(self, i, &line) {
|
||||
self.command_line
|
||||
.push_error(&format!("No plugin handled: {command}"));
|
||||
.push_error(crate::tf!("No plugin handled: {command}").as_ref());
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
|
|
@ -1138,7 +1138,7 @@ impl OpenCADStudio {
|
|||
let Some(path) = self.tabs.get(idx).and_then(|tab| tab.current_path.clone())
|
||||
else {
|
||||
self.command_line
|
||||
.push_error("Save the drawing before copying its file path.");
|
||||
.push_error(crate::t!("Save the drawing before copying its file path.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let full_path = path.canonicalize().unwrap_or_else(|_| {
|
||||
|
|
@ -1151,7 +1151,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
});
|
||||
self.command_line
|
||||
.push_output(&format!("Copied path: {}", full_path.display()));
|
||||
.push_output(crate::tf!("Copied path: {}", full_path.display()).as_ref());
|
||||
return iced::clipboard::write(full_path.to_string_lossy().into_owned())
|
||||
.discard();
|
||||
}
|
||||
|
|
@ -1159,7 +1159,7 @@ impl OpenCADStudio {
|
|||
{
|
||||
let _ = idx;
|
||||
self.command_line
|
||||
.push_error("Full file paths are unavailable in the web application.");
|
||||
.push_error(crate::t!("Full file paths are unavailable in the web application.").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
|
@ -1170,16 +1170,16 @@ impl OpenCADStudio {
|
|||
let Some(path) = self.tabs.get(idx).and_then(|tab| tab.current_path.clone())
|
||||
else {
|
||||
self.command_line
|
||||
.push_error("Save the drawing before opening its file location.");
|
||||
.push_error(crate::t!("Save the drawing before opening its file location.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
match crate::sys::reveal_in_file_manager(&path) {
|
||||
Ok(()) => self
|
||||
.command_line
|
||||
.push_output(&format!("Opened file location: {}", path.display())),
|
||||
.push_output(crate::tf!("Opened file location: {}", path.display()).as_ref()),
|
||||
Err(error) => self
|
||||
.command_line
|
||||
.push_error(&format!("Could not open file location: {error}")),
|
||||
.push_error(crate::tf!("Could not open file location: {error}").as_ref()),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -1187,7 +1187,7 @@ impl OpenCADStudio {
|
|||
{
|
||||
let _ = idx;
|
||||
self.command_line
|
||||
.push_error("File locations are unavailable in the web application.");
|
||||
.push_error(crate::t!("File locations are unavailable in the web application.").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
|
@ -1442,7 +1442,7 @@ impl OpenCADStudio {
|
|||
self.ribbon.close_dropdown();
|
||||
if self.tabs[i].is_start {
|
||||
self.command_line
|
||||
.push_info("Open or create a drawing to manage layer states.");
|
||||
.push_info(crate::t!("Open or create a drawing to manage layer states.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let mut names: Vec<String> = self.tabs[i]
|
||||
|
|
@ -1482,7 +1482,7 @@ impl OpenCADStudio {
|
|||
let name = self.layer_state_name_buf.trim().to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line
|
||||
.push_error("Layer state name cannot be empty.");
|
||||
.push_error(crate::t!("Layer state name cannot be empty.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let old_name = self.layer_state_selected.clone();
|
||||
|
|
@ -1499,7 +1499,7 @@ impl OpenCADStudio {
|
|||
});
|
||||
if duplicate {
|
||||
self.command_line
|
||||
.push_error(&format!("Layer state \"{name}\" already exists."));
|
||||
.push_error(crate::tf!("Layer state \"{name}\" already exists.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
|
||||
|
|
@ -1520,7 +1520,7 @@ impl OpenCADStudio {
|
|||
self.layer_state_selected = Some(name.clone());
|
||||
self.layer_state_name_buf = name.clone();
|
||||
self.command_line
|
||||
.push_output(&format!("LAYERSTATE: saved \"{name}\" in the drawing."));
|
||||
.push_output(crate::tf!("LAYERSTATE: saved \"{name}\" in the drawing.").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
Message::LayerStateManagerRestore => {
|
||||
|
|
@ -1553,9 +1553,9 @@ impl OpenCADStudio {
|
|||
.invalidate_layer_dependencies(&layer_names);
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_layer_panel();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"LAYERSTATE: restored \"{name}\" ({restored} layer(s))."
|
||||
));
|
||||
).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
Message::LayerStateManagerDelete => {
|
||||
|
|
@ -1576,7 +1576,7 @@ impl OpenCADStudio {
|
|||
names.sort_by_key(|name| name.to_lowercase());
|
||||
self.load_layer_state_editor(names.into_iter().next());
|
||||
self.command_line
|
||||
.push_output(&format!("LAYERSTATE: deleted \"{name}\"."));
|
||||
.push_output(crate::tf!("LAYERSTATE: deleted \"{name}\".").as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -1587,7 +1587,7 @@ impl OpenCADStudio {
|
|||
};
|
||||
let Some(state) = self.tabs[i].scene.document.layer_state(&name) else {
|
||||
self.command_line
|
||||
.push_error(&format!("Layer state \"{name}\" was not found."));
|
||||
.push_error(crate::tf!("Layer state \"{name}\" was not found.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
self.layer_state_edit_draft = Some(state);
|
||||
|
|
@ -1730,7 +1730,7 @@ impl OpenCADStudio {
|
|||
let name = draft.name.trim().to_string();
|
||||
if name.is_empty() {
|
||||
self.command_line
|
||||
.push_error("Layer state name cannot be empty.");
|
||||
.push_error(crate::t!("Layer state name cannot be empty.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let old_name = self.layer_state_selected.clone();
|
||||
|
|
@ -1747,7 +1747,7 @@ impl OpenCADStudio {
|
|||
});
|
||||
if duplicate {
|
||||
self.command_line
|
||||
.push_error(&format!("Layer state \"{name}\" already exists."));
|
||||
.push_error(crate::tf!("Layer state \"{name}\" already exists.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let Some(state) = self.layer_state_edit_draft.take() else {
|
||||
|
|
@ -1775,7 +1775,7 @@ impl OpenCADStudio {
|
|||
self.layer_state_edit_color_open = None;
|
||||
self.active_modal = Some(super::ModalKind::LayerStateManager);
|
||||
self.command_line
|
||||
.push_output(&format!("LAYERSTATE: updated \"{name}\"."));
|
||||
.push_output(crate::tf!("LAYERSTATE: updated \"{name}\".").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
Message::LayerStateEditorCancel => {
|
||||
|
|
@ -1829,11 +1829,11 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.invalidate_layer_dependencies(&targets);
|
||||
self.tabs[i].dirty = true;
|
||||
self.commit_layer_undo(i, undo);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{} layer(s) turned {}",
|
||||
targets.len(),
|
||||
if on { "on" } else { "off" }
|
||||
));
|
||||
).as_ref());
|
||||
self.sync_ribbon_layers();
|
||||
}
|
||||
}
|
||||
|
|
@ -1869,11 +1869,11 @@ impl OpenCADStudio {
|
|||
// Lock state affects editability, not rendered geometry.
|
||||
self.tabs[i].dirty = true;
|
||||
self.commit_layer_undo(i, undo);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{} layer(s) {}",
|
||||
targets.len(),
|
||||
if locked { "locked" } else { "unlocked" }
|
||||
));
|
||||
).as_ref());
|
||||
self.sync_ribbon_layers();
|
||||
}
|
||||
}
|
||||
|
|
@ -1904,11 +1904,11 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.invalidate_layer_dependencies(&targets);
|
||||
self.tabs[i].dirty = true;
|
||||
self.commit_layer_undo(i, undo);
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{} layer(s) {}",
|
||||
targets.len(),
|
||||
if frozen { "frozen" } else { "thawed" }
|
||||
));
|
||||
).as_ref());
|
||||
self.sync_ribbon_layers();
|
||||
}
|
||||
}
|
||||
|
|
@ -2300,7 +2300,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.camera.borrow_mut().home_view(r_ucs);
|
||||
}
|
||||
self.tabs[i].scene.camera_generation += 1;
|
||||
self.command_line.push_output("View: Home");
|
||||
self.command_line.push_output(crate::t!("View: Home").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -2351,11 +2351,11 @@ impl OpenCADStudio {
|
|||
let mut changed = false;
|
||||
if name.is_empty() || name == "WCS" {
|
||||
self.tabs[i].active_ucs = None;
|
||||
self.command_line.push_output("UCS: World");
|
||||
self.command_line.push_output(crate::t!("UCS: World").as_ref());
|
||||
changed = true;
|
||||
} else if let Some(named) = self.tabs[i].scene.document.ucss.get(&name).cloned() {
|
||||
self.tabs[i].active_ucs = Some(named);
|
||||
self.command_line.push_output(&format!("UCS: {}", name));
|
||||
self.command_line.push_output(crate::tf!("UCS: {}", name).as_ref());
|
||||
changed = true;
|
||||
}
|
||||
if changed {
|
||||
|
|
@ -2511,7 +2511,7 @@ impl OpenCADStudio {
|
|||
_ => "live",
|
||||
};
|
||||
self.command_line
|
||||
.push_output(&format!("COORDS = {mode} ({label})"));
|
||||
.push_output(crate::tf!("COORDS = {mode} ({label})").as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -2700,11 +2700,11 @@ impl OpenCADStudio {
|
|||
self.active_modal = Some(crate::app::ModalKind::AnnoObjectScale);
|
||||
} else {
|
||||
self.command_line
|
||||
.push_info("The selected object does not support annotation scales.");
|
||||
.push_info(crate::t!("The selected object does not support annotation scales.").as_ref());
|
||||
}
|
||||
} else {
|
||||
self.command_line
|
||||
.push_info("Select one object first, then run OBJECTSCALE.");
|
||||
.push_info(crate::t!("Select one object first, then run OBJECTSCALE.").as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -3341,7 +3341,7 @@ impl OpenCADStudio {
|
|||
let to_move: Vec<_> = self.tabs[i].scene.selected.iter().cloned().collect();
|
||||
if to_move.is_empty() {
|
||||
self.command_line
|
||||
.push_error("DRAWORDER: select entities first.");
|
||||
.push_error(crate::t!("DRAWORDER: select entities first.").as_ref());
|
||||
} else {
|
||||
use crate::command::CadCommand;
|
||||
let cmd = super::commands::DrawOrderRefCommand::new(to_move, above);
|
||||
|
|
@ -3356,7 +3356,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.selection.borrow_mut().context_menu = None;
|
||||
let added = self.tabs[i].scene.select_similar();
|
||||
self.command_line
|
||||
.push_output(&format!("Select Similar: {} added.", added));
|
||||
.push_output(crate::tf!("Select Similar: {} added.", added).as_ref());
|
||||
self.refresh_properties();
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -3366,7 +3366,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.selection.borrow_mut().context_menu = None;
|
||||
let count = self.tabs[i].scene.invert_selection();
|
||||
self.command_line
|
||||
.push_output(&format!("Invert Selection: {} object(s) selected.", count));
|
||||
.push_output(crate::tf!("Invert Selection: {} object(s) selected.", count).as_ref());
|
||||
self.refresh_properties();
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -3441,7 +3441,7 @@ impl OpenCADStudio {
|
|||
state.append,
|
||||
);
|
||||
self.command_line
|
||||
.push_output(&format!("QSELECT: {} object(s) selected.", matched));
|
||||
.push_output(crate::tf!("QSELECT: {} object(s) selected.", matched).as_ref());
|
||||
self.refresh_properties();
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -4023,7 +4023,7 @@ impl OpenCADStudio {
|
|||
if self.tabs[i].scene.delete_layout(&name) {
|
||||
self.layout_rename_state = None;
|
||||
self.command_line
|
||||
.push_output(&format!("Layout \"{name}\" silindi"));
|
||||
.push_output(crate::tf!("Layout \"{name}\" silindi").as_ref());
|
||||
self.tabs[i].dirty = true;
|
||||
}
|
||||
Task::batch([cancel_task, switch_task])
|
||||
|
|
@ -4061,7 +4061,7 @@ impl OpenCADStudio {
|
|||
let i = self.active_tab;
|
||||
if self.tabs[i].is_start {
|
||||
self.command_line
|
||||
.push_info("Open or create a drawing to manage layouts.");
|
||||
.push_info(crate::t!("Open or create a drawing to manage layouts.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let current = self.tabs[i].scene.current_layout.clone();
|
||||
|
|
@ -4097,9 +4097,9 @@ impl OpenCADStudio {
|
|||
let new_name = self.layout_manager_rename_buf.trim().to_string();
|
||||
if old_name == "Model" {
|
||||
self.command_line
|
||||
.push_error("Cannot rename the Model layout.");
|
||||
.push_error(crate::t!("Cannot rename the Model layout.").as_ref());
|
||||
} else if new_name.is_empty() {
|
||||
self.command_line.push_error("Layout name cannot be empty.");
|
||||
self.command_line.push_error(crate::t!("Layout name cannot be empty.").as_ref());
|
||||
} else if new_name == old_name {
|
||||
// no-op
|
||||
} else {
|
||||
|
|
@ -4111,7 +4111,7 @@ impl OpenCADStudio {
|
|||
self.layout_manager_selected = new_name.clone();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("Layout renamed: '{old_name}' → '{new_name}'"));
|
||||
.push_output(crate::tf!("Layout renamed: '{old_name}' → '{new_name}'").as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -4119,7 +4119,7 @@ impl OpenCADStudio {
|
|||
let i = self.active_tab;
|
||||
if self.tabs[i].is_start {
|
||||
self.command_line
|
||||
.push_info("Open or create a drawing to add a layout.");
|
||||
.push_info(crate::t!("Open or create a drawing to add a layout.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let existing = self.tabs[i].scene.layout_names();
|
||||
|
|
@ -4134,9 +4134,9 @@ impl OpenCADStudio {
|
|||
self.layout_manager_selected = name.clone();
|
||||
self.layout_manager_rename_buf = name.clone();
|
||||
self.command_line
|
||||
.push_output(&format!("Layout '{name}' created."));
|
||||
.push_output(crate::tf!("Layout '{name}' created.").as_ref());
|
||||
}
|
||||
Err(e) => self.command_line.push_error(&format!("LAYOUT: {e}")),
|
||||
Err(e) => self.command_line.push_error(crate::tf!("LAYOUT: {e}").as_ref()),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -4145,7 +4145,7 @@ impl OpenCADStudio {
|
|||
let name = self.layout_manager_selected.clone();
|
||||
if name == "Model" {
|
||||
self.command_line
|
||||
.push_error("Cannot delete the Model layout.");
|
||||
.push_error(crate::t!("Cannot delete the Model layout.").as_ref());
|
||||
Task::none()
|
||||
} else {
|
||||
let deleting_current = self.tabs[i].scene.current_layout == name;
|
||||
|
|
@ -4165,7 +4165,7 @@ impl OpenCADStudio {
|
|||
self.layout_manager_selected = "Model".to_string();
|
||||
self.layout_manager_rename_buf = String::new();
|
||||
self.command_line
|
||||
.push_output(&format!("Layout '{name}' deleted."));
|
||||
.push_output(crate::tf!("Layout '{name}' deleted.").as_ref());
|
||||
Task::batch([cancel_task, switch_task])
|
||||
}
|
||||
}
|
||||
|
|
@ -4209,7 +4209,7 @@ impl OpenCADStudio {
|
|||
let task = self.on_layout_switch(name.clone());
|
||||
if self.tabs[self.active_tab].scene.current_layout == name {
|
||||
self.command_line
|
||||
.push_output(&format!("Switched to layout '{name}'."));
|
||||
.push_output(crate::tf!("Switched to layout '{name}'.").as_ref());
|
||||
}
|
||||
task
|
||||
}
|
||||
|
|
@ -4273,10 +4273,10 @@ impl OpenCADStudio {
|
|||
}
|
||||
Message::AliasEditorApply => {
|
||||
self.apply_alias_editor_rows();
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"{} alias(es) applied.",
|
||||
self.command_aliases.len()
|
||||
));
|
||||
).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -4334,7 +4334,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
Err(error) => self
|
||||
.command_line
|
||||
.push_error(&format!("Unable to change UI language: {error}")),
|
||||
.push_error(crate::tf!("Unable to change UI language: {error}").as_ref()),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -4959,7 +4959,7 @@ impl OpenCADStudio {
|
|||
let phase = Instant::now();
|
||||
self.refresh_properties();
|
||||
let properties_ms = phase.elapsed().as_secs_f64() * 1000.0;
|
||||
self.command_line.push_output("MSPACE");
|
||||
self.command_line.push_output(crate::t!("MSPACE").as_ref());
|
||||
if perf {
|
||||
crate::perf_record!(
|
||||
"[perf] viewport-enter total={:.2}ms normalize={:.2}ms display={:.2}ms ucs={:.2}ms properties={:.2}ms handle={}",
|
||||
|
|
@ -4996,7 +4996,7 @@ impl OpenCADStudio {
|
|||
// Paper space has no UCS — drop the viewport's UCS.
|
||||
self.tabs[i].refresh_active_ucs();
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output("PSPACE");
|
||||
self.command_line.push_output(crate::t!("PSPACE").as_ref());
|
||||
if context_changed {
|
||||
self.sync_dyn_fields();
|
||||
}
|
||||
|
|
@ -5007,7 +5007,7 @@ impl OpenCADStudio {
|
|||
let i = self.active_tab;
|
||||
if self.tabs[i].scene.current_layout == "Model" {
|
||||
self.command_line
|
||||
.push_error("MS is only available in paper space layouts.");
|
||||
.push_error(crate::t!("MS is only available in paper space layouts.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
if self.tabs[i].scene.active_viewport.is_some() {
|
||||
|
|
@ -5018,7 +5018,7 @@ impl OpenCADStudio {
|
|||
Some(handle) => Task::done(Message::EnterViewport(handle)),
|
||||
None => {
|
||||
self.command_line
|
||||
.push_error("No viewport found in this layout.");
|
||||
.push_error(crate::t!("No viewport found in this layout.").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
|
@ -5163,7 +5163,7 @@ impl OpenCADStudio {
|
|||
Ok(msg) => self.command_line.push_info(&msg),
|
||||
Err(err) => self
|
||||
.command_line
|
||||
.push_error(&format!("Could not set default app: {err}")),
|
||||
.push_error(crate::tf!("Could not set default app: {err}").as_ref()),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -5252,11 +5252,11 @@ impl OpenCADStudio {
|
|||
Message::PrintToPrinter => self.on_print_to_printer(),
|
||||
Message::PrintResult(Ok(printer)) => {
|
||||
self.command_line
|
||||
.push_info(&format!("Sent to printer: {printer}"));
|
||||
.push_info(crate::tf!("Sent to printer: {printer}").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
Message::PrintResult(Err(e)) => {
|
||||
self.command_line.push_error(&format!("Print failed: {e}"));
|
||||
self.command_line.push_error(crate::tf!("Print failed: {e}").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -5273,7 +5273,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.plot_dialog.style_name = table.name.clone();
|
||||
self.plot_dialog.style_missing = false;
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Plot style '{}' loaded ({} color entries).",
|
||||
table.name,
|
||||
table
|
||||
|
|
@ -5281,7 +5281,7 @@ impl OpenCADStudio {
|
|||
.iter()
|
||||
.filter(|e| e.color.is_some())
|
||||
.count()
|
||||
));
|
||||
).as_ref());
|
||||
self.active_plot_style = Some(table);
|
||||
self.plot_dialog.plot_styles = crate::io::plot_style::available_ctb_names();
|
||||
Task::none()
|
||||
|
|
@ -5291,7 +5291,7 @@ impl OpenCADStudio {
|
|||
self.active_plot_style = None;
|
||||
self.plot_dialog.style_name.clear();
|
||||
self.plot_dialog.style_missing = false;
|
||||
self.command_line.push_output("Plot style table cleared.");
|
||||
self.command_line.push_output(crate::t!("Plot style table cleared.").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -5383,12 +5383,12 @@ impl OpenCADStudio {
|
|||
self.plot_dialog.style_missing = false;
|
||||
self.plot_dialog.plot_styles =
|
||||
crate::io::plot_style::available_ctb_names();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Plot style table saved to \"{}\".",
|
||||
path.display()
|
||||
));
|
||||
).as_ref());
|
||||
}
|
||||
Err(e) => self.command_line.push_error(&format!("Save error: {e}")),
|
||||
Err(e) => self.command_line.push_error(crate::tf!("Save error: {e}").as_ref()),
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
|
|
@ -5416,7 +5416,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.document.header.current_text_style_name = name.clone();
|
||||
self.sync_ribbon_styles();
|
||||
self.command_line
|
||||
.push_output(&format!("Current text style: {}", name));
|
||||
.push_output(crate::tf!("Current text style: {}", name).as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -5716,7 +5716,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.document.header.current_table_style_name = name.clone();
|
||||
self.ribbon.active_table_style = name.clone();
|
||||
self.command_line
|
||||
.push_output(&format!("Current table style: {name}"));
|
||||
.push_output(crate::tf!("Current table style: {name}").as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -5745,7 +5745,7 @@ impl OpenCADStudio {
|
|||
// Staged: persists on Apply.
|
||||
self.tabs[i].scene.document.header.multiline_style = name.clone();
|
||||
self.command_line
|
||||
.push_output(&format!("Current multiline style: {}", name));
|
||||
.push_output(crate::tf!("Current multiline style: {}", name).as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -5878,10 +5878,10 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.document.header.current_dimstyle_name =
|
||||
self.dimstyle_selected.clone();
|
||||
self.sync_ribbon_styles();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Current dim style set to '{}'.",
|
||||
self.dimstyle_selected
|
||||
));
|
||||
).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
Message::DimStyleDialogDelete => {
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ impl OpenCADStudio {
|
|||
ds.dimalt = self.ds_dimalt;
|
||||
ds.dimapost = self.ds_dimapost.clone();
|
||||
self.command_line
|
||||
.push_output(&format!("DimStyle '{}' updated.", self.dimstyle_selected));
|
||||
.push_output(crate::tf!("DimStyle '{}' updated.", self.dimstyle_selected).as_ref());
|
||||
}
|
||||
|
||||
/// Update a single string buffer field.
|
||||
|
|
@ -687,7 +687,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
|||
self.tabs[i].active_mleader_style = name.clone();
|
||||
self.ribbon.active_mleader_style = name.clone();
|
||||
self.command_line
|
||||
.push_output(&format!("Current multileader style: {}", name));
|
||||
.push_output(crate::tf!("Current multileader style: {}", name).as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -515,7 +515,7 @@ impl OpenCADStudio {
|
|||
if self.tabs[i].scene.set_active_viewport_render_mode(mode) {
|
||||
self.tabs[i].scene.bump_geometry_no_blocks();
|
||||
self.command_line
|
||||
.push_output(&format!("Viewport visual style: {label}"));
|
||||
.push_output(crate::tf!("Viewport visual style: {label}").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
self.tabs[i].render_mode = mode;
|
||||
|
|
@ -533,7 +533,7 @@ impl OpenCADStudio {
|
|||
// pipeline keys its upload cache off `geometry_epoch`.
|
||||
self.tabs[i].scene.bump_geometry_no_blocks();
|
||||
self.command_line
|
||||
.push_output(&format!("Visual style: {label}"));
|
||||
.push_output(crate::tf!("Visual style: {label}").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -2616,7 +2616,7 @@ impl OpenCADStudio {
|
|||
.as_mut()
|
||||
.map(|c| c.on_structure_pick(pick.handle, center));
|
||||
self.command_line
|
||||
.push_info(&format!("{} acquired.", pick.label));
|
||||
.push_info(crate::tf!("{} acquired.", pick.label).as_ref());
|
||||
result
|
||||
} else {
|
||||
let msg = self.tabs[i]
|
||||
|
|
@ -2745,7 +2745,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i].active_cmd = Some(cmd);
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error("HATCHEDIT: not a hatch entity.");
|
||||
.push_error(crate::t!("HATCHEDIT: not a hatch entity.").as_ref());
|
||||
self.tabs[i].active_cmd = None;
|
||||
}
|
||||
}
|
||||
|
|
@ -2772,7 +2772,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
result
|
||||
} else {
|
||||
self.command_line.push_info("Nothing found at that point.");
|
||||
self.command_line.push_info(crate::t!("Nothing found at that point.").as_ref());
|
||||
None
|
||||
}
|
||||
} else if self.tabs[i]
|
||||
|
|
@ -2787,7 +2787,7 @@ impl OpenCADStudio {
|
|||
.as_mut()
|
||||
.map(|c| c.on_tangent_point(obj, pick_wcs))
|
||||
} else {
|
||||
self.command_line.push_info("Select a tangent object.");
|
||||
self.command_line.push_info(crate::t!("Select a tangent object.").as_ref());
|
||||
None
|
||||
}
|
||||
} else if !self.command_point_allowed(i, world_pt) {
|
||||
|
|
@ -3250,9 +3250,9 @@ impl OpenCADStudio {
|
|||
// `selection_just_completed`, or a
|
||||
// gather command (MOVE's "select
|
||||
// objects") would wrongly finish.
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"Object is on locked layer \"{layer}\" — unlock the layer to select or edit it."
|
||||
));
|
||||
).as_ref());
|
||||
} else {
|
||||
// Individual picks accumulate (issue #47):
|
||||
// each plain click adds to the selection,
|
||||
|
|
@ -3513,9 +3513,9 @@ impl OpenCADStudio {
|
|||
// Locked layer: double-click must not open any editor
|
||||
// (text / attribute / in-place block edit).
|
||||
if let Some(layer) = self.tabs[i].scene.locked_layer_name(handle) {
|
||||
self.command_line.push_info(&format!(
|
||||
self.command_line.push_info(crate::tf!(
|
||||
"Object is on locked layer \"{layer}\" — unlock the layer to edit it."
|
||||
));
|
||||
).as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
// Any text-bearing entity opens its in-place editor
|
||||
|
|
@ -3693,7 +3693,7 @@ impl OpenCADStudio {
|
|||
self.tabs[i]
|
||||
.scene
|
||||
.record_nav_perf(crate::scene::NavPerfOp::Zoom, now);
|
||||
self.command_line.push_output("Zoom Extents");
|
||||
self.command_line.push_output(crate::t!("Zoom Extents").as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -3891,7 +3891,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].scene.camera_generation += 1;
|
||||
self.command_line
|
||||
.push_output(&format!("View: {}", region.label()));
|
||||
.push_output(crate::tf!("View: {}", region.label()).as_ref());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -4094,7 +4094,7 @@ impl OpenCADStudio {
|
|||
.position(|session| session.block_name == name)
|
||||
else {
|
||||
self.command_line
|
||||
.push_error(&format!("BEDIT: block tab \"{name}\" is not open."));
|
||||
.push_error(crate::tf!("BEDIT: block tab \"{name}\" is not open.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
if self.tabs[i].active_block_edit == Some(target_index) {
|
||||
|
|
@ -4156,7 +4156,7 @@ impl OpenCADStudio {
|
|||
let i = self.active_tab;
|
||||
if self.tabs[i].is_start {
|
||||
self.command_line
|
||||
.push_info("Open or create a drawing to switch layouts.");
|
||||
.push_info(crate::t!("Open or create a drawing to switch layouts.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let perf = crate::perf::enabled();
|
||||
|
|
@ -4270,7 +4270,7 @@ impl OpenCADStudio {
|
|||
let i = self.active_tab;
|
||||
if self.tabs[i].is_start {
|
||||
self.command_line
|
||||
.push_info("Open or create a drawing to add a layout.");
|
||||
.push_info(crate::t!("Open or create a drawing to add a layout.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
let cancel_task = self.cancel_active_command_for_space_change();
|
||||
|
|
@ -4310,15 +4310,15 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.ensure_sheet_viewport(&new_name);
|
||||
let switch_task = self.on_layout_switch(new_name.clone());
|
||||
self.tabs[i].scene.fit_all();
|
||||
self.command_line.push_output(&format!(
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Layout \"{new_name}\" created — use MVIEW to add a viewport"
|
||||
));
|
||||
).as_ref());
|
||||
self.tabs[i].dirty = true;
|
||||
return Task::batch([cancel_task, switch_task]);
|
||||
}
|
||||
Err(e) => self
|
||||
.command_line
|
||||
.push_error(&format!("Failed to create layout: {e}")),
|
||||
.push_error(crate::tf!("Failed to create layout: {e}").as_ref()),
|
||||
}
|
||||
cancel_task
|
||||
}
|
||||
|
|
@ -4342,7 +4342,7 @@ impl OpenCADStudio {
|
|||
.is_some()
|
||||
{
|
||||
self.command_line
|
||||
.push_error(&format!("\"{}\" name already in use", new_name));
|
||||
.push_error(crate::tf!("\"{}\" name already in use", new_name).as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "BLOCK RENAME");
|
||||
if self.tabs[i].scene.rename_block(&orig, &new_name) {
|
||||
|
|
@ -4358,10 +4358,10 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("Block \"{orig}\" → \"{new_name}\""));
|
||||
.push_output(crate::tf!("Block \"{orig}\" → \"{new_name}\"").as_ref());
|
||||
} else {
|
||||
self.command_line
|
||||
.push_error(&format!("Could not rename block \"{orig}\""));
|
||||
.push_error(crate::tf!("Could not rename block \"{orig}\"").as_ref());
|
||||
}
|
||||
}
|
||||
return Task::none();
|
||||
|
|
@ -4373,7 +4373,7 @@ impl OpenCADStudio {
|
|||
.any(|n| *n == new_name);
|
||||
if exists {
|
||||
self.command_line
|
||||
.push_error(&format!("\"{}\" name already in use", new_name));
|
||||
.push_error(crate::tf!("\"{}\" name already in use", new_name).as_ref());
|
||||
} else {
|
||||
self.push_undo_snapshot(i, "LAYOUT RENAME");
|
||||
self.tabs[i].scene.rename_layout(&orig, &new_name);
|
||||
|
|
@ -4382,7 +4382,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("Layout \"{orig}\" → \"{new_name}\""));
|
||||
.push_output(crate::tf!("Layout \"{orig}\" → \"{new_name}\"").as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use iced::widget::{
|
|||
use iced::window;
|
||||
use iced::{keyboard, Background, Border, Color, Element, Fill, Subscription, Task, Theme};
|
||||
use iced_aw::ContextMenu;
|
||||
use crate::t;
|
||||
|
||||
mod controls;
|
||||
mod modal;
|
||||
|
|
@ -1210,7 +1211,7 @@ impl OpenCADStudio {
|
|||
let copy_btn = button(
|
||||
row![
|
||||
crate::ui::icons::themed_primary(crate::ui::icons::COPY, 11.0),
|
||||
text("Copy").size(11),
|
||||
text(t!("Copy")).size(11),
|
||||
]
|
||||
.spacing(4)
|
||||
.align_y(iced::Center),
|
||||
|
|
@ -1221,7 +1222,7 @@ impl OpenCADStudio {
|
|||
let clear_btn = button(
|
||||
row![
|
||||
crate::ui::icons::themed_danger(crate::ui::icons::TRASH, 11.0),
|
||||
text("Clear").size(11),
|
||||
text(t!("Clear")).size(11),
|
||||
]
|
||||
.spacing(4)
|
||||
.align_y(iced::Center),
|
||||
|
|
@ -1230,7 +1231,7 @@ impl OpenCADStudio {
|
|||
.style(perf_button_style)
|
||||
.padding([2, 6]);
|
||||
let header = row![
|
||||
text("PERF").size(12).style(|theme: &Theme| iced::widget::text::Style {
|
||||
text(t!("PERF")).size(12).style(|theme: &Theme| iced::widget::text::Style {
|
||||
color: Some(theme.palette().success.base.color),
|
||||
}),
|
||||
Space::new().width(iced::Length::Fill),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
use super::super::{Message, OpenCADStudio};
|
||||
use crate::t;
|
||||
use iced::widget::{button, column, container, row, text, Space};
|
||||
use iced::{Background, Element, Fill, Fit, Theme};
|
||||
use std::borrow::Cow;
|
||||
|
||||
impl OpenCADStudio {
|
||||
/// Title shown in the active modal's title bar. Keep in sync with the
|
||||
|
|
@ -221,7 +223,7 @@ impl OpenCADStudio {
|
|||
)
|
||||
} else {
|
||||
automatic_flow(ex, |flow| {
|
||||
container(text("The selected layer state is no longer available."))
|
||||
container(text(t!("The selected layer state is no longer available.")))
|
||||
.padding(16)
|
||||
.width(flow.width)
|
||||
.height(flow.height)
|
||||
|
|
@ -941,12 +943,12 @@ fn automatic_flow<'a>(
|
|||
)
|
||||
}
|
||||
|
||||
fn dialog_button(
|
||||
label: &'static str,
|
||||
fn dialog_button<'a>(
|
||||
label: impl Into<Cow<'a, str>>,
|
||||
message: Message,
|
||||
style: fn(&Theme, button::Status) -> button::Style,
|
||||
) -> Element<'static, Message> {
|
||||
button(text(label).size(13))
|
||||
) -> Element<'a, Message> {
|
||||
button(text(label.into()).size(13))
|
||||
.on_press(message)
|
||||
.style(style)
|
||||
.padding([6, 18])
|
||||
|
|
@ -980,7 +982,7 @@ fn save_as_dialog_window<'a>(
|
|||
.iter()
|
||||
.copied()
|
||||
.find(|&s| s == format);
|
||||
let label = |s: &'static str| text(s).size(11).style(dialog_muted_text_style);
|
||||
let label = |s: Cow<'static, str>| text(s).size(11).style(dialog_muted_text_style);
|
||||
let field_width = if matches!(sizing.width, iced::Length::Fill) {
|
||||
Fill
|
||||
} else {
|
||||
|
|
@ -988,7 +990,7 @@ fn save_as_dialog_window<'a>(
|
|||
};
|
||||
|
||||
let mut items: Vec<Element<'a, Message>> = Vec::new();
|
||||
items.push(text("Save Drawing As").size(14).into());
|
||||
items.push(text(t!("Save Drawing As")).size(14).into());
|
||||
items.push(Space::new().height(12).into());
|
||||
|
||||
// Web has no native file dialog, so the file name is typed here. On native
|
||||
|
|
@ -997,7 +999,7 @@ fn save_as_dialog_window<'a>(
|
|||
{
|
||||
items.push(
|
||||
row![
|
||||
label("File name:").width(70),
|
||||
label(t!("File name:")).width(70),
|
||||
iced::widget::text_input("drawing.dwg", filename)
|
||||
.on_input(Message::SaveDialogFilenameChanged)
|
||||
.size(13)
|
||||
|
|
@ -1016,7 +1018,7 @@ fn save_as_dialog_window<'a>(
|
|||
|
||||
items.push(
|
||||
row![
|
||||
label("Format:").width(70),
|
||||
label(t!("Format:")).width(70),
|
||||
iced::widget::pick_list(
|
||||
sel_fmt,
|
||||
crate::io::SAVE_FORMAT_OPTIONS,
|
||||
|
|
@ -1034,9 +1036,9 @@ fn save_as_dialog_window<'a>(
|
|||
items.push(
|
||||
row![
|
||||
Space::new().width(Fit),
|
||||
dialog_button("Save as...", Message::SaveDialogConfirm, button::primary),
|
||||
dialog_button(t!("Save as..."), Message::SaveDialogConfirm, button::primary),
|
||||
Space::new().width(8),
|
||||
dialog_button("Cancel", Message::SaveDialogCancel, button::secondary),
|
||||
dialog_button(t!("Cancel"), Message::SaveDialogCancel, button::secondary),
|
||||
]
|
||||
.into(),
|
||||
);
|
||||
|
|
@ -1058,18 +1060,21 @@ fn unsaved_changes_dialog_window(
|
|||
name: &str,
|
||||
sizing: crate::ui::modal::ModalSizing,
|
||||
) -> Element<'static, Message> {
|
||||
let body_text = format!("Do you want to save changes to \"{}\"?", name);
|
||||
let body_text = t!(
|
||||
"Do you want to save changes to \"%{name}\"?",
|
||||
name = name
|
||||
);
|
||||
|
||||
container(
|
||||
column![
|
||||
text(body_text).size(13),
|
||||
iced::widget::Space::new().height(20),
|
||||
row![
|
||||
dialog_button("Save", Message::UnsavedDialogSave, button::primary),
|
||||
dialog_button(t!("Save"), Message::UnsavedDialogSave, button::primary),
|
||||
iced::widget::Space::new().width(8),
|
||||
dialog_button("Discard", Message::UnsavedDialogDiscard, button::danger),
|
||||
dialog_button(t!("Discard"), Message::UnsavedDialogDiscard, button::danger),
|
||||
iced::widget::Space::new().width(8),
|
||||
dialog_button("Cancel", Message::UnsavedDialogCancel, button::secondary),
|
||||
dialog_button(t!("Cancel"), Message::UnsavedDialogCancel, button::secondary),
|
||||
],
|
||||
]
|
||||
.spacing(0),
|
||||
|
|
@ -1090,19 +1095,18 @@ fn file_in_use_dialog_window(
|
|||
let file_name = std::path::Path::new(path)
|
||||
.file_name()
|
||||
.map(|name| name.to_string_lossy().into_owned())
|
||||
.unwrap_or_else(|| "Drawing".to_string());
|
||||
let heading = format!("\"{file_name}\" could not be saved.");
|
||||
let path_line = format!("Path: {path}");
|
||||
let details = format!("Details: {error}");
|
||||
.unwrap_or_else(|| t!("Drawing").into_owned());
|
||||
let heading = t!("\"%{file_name}\" could not be saved.", file_name = file_name);
|
||||
let path_line = t!("Path: %{path}", path = path);
|
||||
let details = t!("Details: %{error}", error = error);
|
||||
|
||||
container(
|
||||
column![
|
||||
text(heading).size(14),
|
||||
Space::new().height(8),
|
||||
text(
|
||||
"The file is open or being used by another application. \
|
||||
Close it there and retry, or save this drawing under a different name."
|
||||
)
|
||||
text(t!(
|
||||
"The file is open or being used by another application. Close it there and retry, or save this drawing under a different name."
|
||||
))
|
||||
.size(13)
|
||||
.width(Fit),
|
||||
Space::new().height(12),
|
||||
|
|
@ -1112,19 +1116,19 @@ fn file_in_use_dialog_window(
|
|||
Space::new().height(18),
|
||||
row![
|
||||
dialog_button(
|
||||
"Retry",
|
||||
t!("Retry"),
|
||||
Message::SaveFileInUseRetry,
|
||||
button::primary
|
||||
),
|
||||
Space::new().width(8),
|
||||
dialog_button(
|
||||
"Save As",
|
||||
t!("Save As"),
|
||||
Message::SaveFileInUseSaveAs,
|
||||
button::secondary
|
||||
),
|
||||
Space::new().width(8),
|
||||
dialog_button(
|
||||
"Cancel",
|
||||
t!("Cancel"),
|
||||
Message::SaveFileInUseCancel,
|
||||
button::secondary
|
||||
),
|
||||
|
|
@ -1147,18 +1151,17 @@ fn external_change_dialog_window(
|
|||
let file_name = std::path::Path::new(path)
|
||||
.file_name()
|
||||
.map(|name| name.to_string_lossy().into_owned())
|
||||
.unwrap_or_else(|| "Drawing".to_string());
|
||||
let heading = format!("\"{file_name}\" was changed by another application.");
|
||||
let path_line = format!("Path: {path}");
|
||||
.unwrap_or_else(|| t!("Drawing").into_owned());
|
||||
let heading = t!("\"%{file_name}\" was changed by another application.", file_name = file_name);
|
||||
let path_line = t!("Path: %{path}", path = path);
|
||||
|
||||
container(
|
||||
column![
|
||||
text(heading).size(14),
|
||||
Space::new().height(8),
|
||||
text(
|
||||
"Saving now could destroy those external changes. Reload the disk copy, \
|
||||
save your local work elsewhere, or explicitly overwrite it."
|
||||
)
|
||||
text(t!(
|
||||
"Saving now could destroy those external changes. Reload the disk copy, save your local work elsewhere, or explicitly overwrite it."
|
||||
))
|
||||
.size(13)
|
||||
.width(Fit),
|
||||
Space::new().height(12),
|
||||
|
|
@ -1166,25 +1169,25 @@ fn external_change_dialog_window(
|
|||
Space::new().height(18),
|
||||
row![
|
||||
dialog_button(
|
||||
"Reload from Disk",
|
||||
t!("Reload from Disk"),
|
||||
Message::ExternalChangeReload,
|
||||
button::primary
|
||||
),
|
||||
Space::new().width(8),
|
||||
dialog_button(
|
||||
"Save As",
|
||||
t!("Save As"),
|
||||
Message::ExternalChangeSaveAs,
|
||||
button::secondary
|
||||
),
|
||||
Space::new().width(8),
|
||||
dialog_button(
|
||||
"Overwrite",
|
||||
t!("Overwrite"),
|
||||
Message::ExternalChangeOverwrite,
|
||||
button::danger
|
||||
),
|
||||
Space::new().width(8),
|
||||
dialog_button(
|
||||
"Cancel",
|
||||
t!("Cancel"),
|
||||
Message::ExternalChangeCancel,
|
||||
button::secondary
|
||||
),
|
||||
|
|
@ -1209,10 +1212,11 @@ fn aec_drop_dialog_window(
|
|||
src_version: &str,
|
||||
sizing: crate::ui::modal::ModalSizing,
|
||||
) -> Element<'static, Message> {
|
||||
let body_text = format!(
|
||||
"This drawing contains {count} AEC/Civil objects that \"{target}\" \
|
||||
cannot store, so they will not be saved.\n\n\
|
||||
To keep them, save in the source version ({src_version})."
|
||||
let body_text = t!(
|
||||
"This drawing contains %{count} AEC/Civil objects that \"%{target}\" cannot store, so they will not be saved.\n\nTo keep them, save in the source version (%{src_version}).",
|
||||
count = count,
|
||||
target = target,
|
||||
src_version = src_version,
|
||||
);
|
||||
|
||||
container(
|
||||
|
|
@ -1221,14 +1225,14 @@ fn aec_drop_dialog_window(
|
|||
iced::widget::Space::new().height(20),
|
||||
row![
|
||||
dialog_button(
|
||||
"Save in source version",
|
||||
t!("Save in source version"),
|
||||
Message::AecDropSameVersion,
|
||||
button::primary
|
||||
),
|
||||
iced::widget::Space::new().width(8),
|
||||
dialog_button("Save anyway", Message::AecDropProceed, button::warning),
|
||||
dialog_button(t!("Save anyway"), Message::AecDropProceed, button::warning),
|
||||
iced::widget::Space::new().width(8),
|
||||
dialog_button("Back", Message::AecDropBack, button::secondary),
|
||||
dialog_button(t!("Back"), Message::AecDropBack, button::secondary),
|
||||
],
|
||||
]
|
||||
.spacing(0),
|
||||
|
|
@ -1249,16 +1253,25 @@ fn layer_delete_warning_window(
|
|||
count: usize,
|
||||
sizing: crate::ui::modal::ModalSizing,
|
||||
) -> Element<'static, Message> {
|
||||
let obj = if count == 1 { "object" } else { "objects" };
|
||||
let subject = if names.len() == 1 {
|
||||
format!("Layer \"{}\"", names[0])
|
||||
let obj = if count == 1 { t!("object") } else { t!("objects") };
|
||||
let has = if names.len() == 1 { t!("has") } else { t!("hold") };
|
||||
let those = if count == 1 {
|
||||
t!("that object")
|
||||
} else {
|
||||
format!("{} selected layers", names.len())
|
||||
t!("those objects")
|
||||
};
|
||||
let body_text = format!(
|
||||
"{subject} still {} {count} {obj}.\n\nDeleting will also remove {} from the drawing. Continue?",
|
||||
if names.len() == 1 { "has" } else { "hold" },
|
||||
if count == 1 { "that object" } else { "those objects" }
|
||||
let subject = if names.len() == 1 {
|
||||
t!("Layer \"%{name}\"", name = names[0]).into_owned()
|
||||
} else {
|
||||
t!("%{count} selected layers", count = names.len()).into_owned()
|
||||
};
|
||||
let body_text = t!(
|
||||
"%{subject} still %{has} %{count} %{obj}.\n\nDeleting will also remove %{those} from the drawing. Continue?",
|
||||
subject = subject,
|
||||
has = has,
|
||||
count = count,
|
||||
obj = obj,
|
||||
those = those,
|
||||
);
|
||||
|
||||
container(
|
||||
|
|
@ -1267,12 +1280,12 @@ fn layer_delete_warning_window(
|
|||
iced::widget::Space::new().height(20),
|
||||
row![
|
||||
dialog_button(
|
||||
"Delete Objects",
|
||||
t!("Delete Objects"),
|
||||
Message::LayerDeleteConfirm,
|
||||
button::danger
|
||||
),
|
||||
iced::widget::Space::new().width(8),
|
||||
dialog_button("Cancel", Message::CloseModal, button::secondary),
|
||||
dialog_button(t!("Cancel"), Message::CloseModal, button::secondary),
|
||||
],
|
||||
]
|
||||
.spacing(0),
|
||||
|
|
@ -1293,19 +1306,19 @@ fn default_assoc_dialog_window(
|
|||
) -> Element<'static, Message> {
|
||||
container(
|
||||
column![
|
||||
text("Make Open CAD Studio your default CAD app?")
|
||||
text(t!("Make Open CAD Studio your default CAD app?"))
|
||||
.size(15),
|
||||
iced::widget::Space::new().height(10),
|
||||
text("Open .dwg and .dxf drawings in Open CAD Studio by default. You can change this later in your system settings.")
|
||||
text(t!("Open .dwg and .dxf drawings in Open CAD Studio by default. You can change this later in your system settings."))
|
||||
.size(12)
|
||||
.style(dialog_muted_text_style),
|
||||
iced::widget::Space::new().height(22),
|
||||
row![
|
||||
iced::widget::Space::new().width(Fit),
|
||||
dialog_button("Not now", Message::AssocPromptNo, button::secondary),
|
||||
dialog_button(t!("Not now"), Message::AssocPromptNo, button::secondary),
|
||||
iced::widget::Space::new().width(8),
|
||||
dialog_button(
|
||||
"Yes, set as default",
|
||||
t!("Yes, set as default"),
|
||||
Message::AssocPromptYes,
|
||||
button::primary
|
||||
),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use iced::widget::{
|
|||
Space,
|
||||
};
|
||||
use iced::{Background, Border, Color, Element, Fill, Theme};
|
||||
use crate::t;
|
||||
|
||||
pub(super) fn position_canvas_overlay<'a>(
|
||||
anchor: iced::Point,
|
||||
|
|
@ -28,7 +29,7 @@ pub(super) fn text_inline_overlay(
|
|||
ed: &super::super::text_inline::TextInlineState,
|
||||
canvas: (f32, f32),
|
||||
) -> Element<'_, Message> {
|
||||
let field = text_input("Text", &ed.value)
|
||||
let field = text_input(t!("Text").as_ref(), &ed.value)
|
||||
.id(iced::widget::Id::new(TEXT_INLINE_ID))
|
||||
.on_input(Message::TextInlineInput)
|
||||
.on_submit(Message::TextInlineOk)
|
||||
|
|
@ -366,7 +367,7 @@ pub(super) fn mtext_editor_overlay<'a>(
|
|||
|
||||
crate::ui::modal::modal(
|
||||
iced::widget::Space::new().width(Fill).height(Fill),
|
||||
"Text Editor",
|
||||
t!("Text Editor"),
|
||||
content,
|
||||
Message::MTextCancel,
|
||||
modal_offset,
|
||||
|
|
@ -577,7 +578,7 @@ fn mtext_editor_content<'a>(
|
|||
f64::from(writing_area_px / preview_scale).max(slider_min * 2.0);
|
||||
let width_slider = column![
|
||||
row![
|
||||
text(format!("Width: {:.3}", ed.rect_width)).size(11),
|
||||
text(t!("Width: %{value}", value = format!("{:.3}", ed.rect_width))).size(11),
|
||||
Space::new().width(width),
|
||||
text(format!("{:.0}%", ed.rect_width / slider_max * 100.0)).size(11),
|
||||
]
|
||||
|
|
@ -709,7 +710,7 @@ fn mtext_editor_content<'a>(
|
|||
let action_bar = container(
|
||||
row![
|
||||
iced::widget::Space::new().width(width),
|
||||
crate::ui::style::style_manager::tb_button("Apply", Message::MTextApply, true),
|
||||
crate::ui::style::style_manager::tb_button(t!("Apply"), Message::MTextApply, true),
|
||||
]
|
||||
.align_y(iced::Alignment::Center),
|
||||
)
|
||||
|
|
@ -784,13 +785,13 @@ pub(super) fn viewport_context_menu_overlay(
|
|||
let mut items: Vec<Element<'static, Message>> = Vec::new();
|
||||
|
||||
if has_cmd {
|
||||
items.push(item("Cancel".to_string(), Message::CommandEscape));
|
||||
items.push(item("Enter".to_string(), Message::CommandFinalize));
|
||||
items.push(item(t!("Cancel").into_owned(), Message::CommandEscape));
|
||||
items.push(item(t!("Enter").into_owned(), Message::CommandFinalize));
|
||||
} else {
|
||||
if !last_cmds.is_empty() {
|
||||
let last = last_cmds[0].clone();
|
||||
items.push(item(
|
||||
format!("Repeat {last}"),
|
||||
t!("Repeat %{last}", last = last).into_owned(),
|
||||
Message::Command(last.to_uppercase()),
|
||||
));
|
||||
if last_cmds.len() > 1 {
|
||||
|
|
@ -802,13 +803,13 @@ pub(super) fn viewport_context_menu_overlay(
|
|||
items.push(sep());
|
||||
}
|
||||
if has_selection {
|
||||
items.push(item("Delete".to_string(), Message::DeleteSelected));
|
||||
items.push(item(t!("Delete").into_owned(), Message::DeleteSelected));
|
||||
items.push(item(
|
||||
"Move".to_string(),
|
||||
t!("Move").into_owned(),
|
||||
Message::Command("MOVE".to_string()),
|
||||
));
|
||||
items.push(item(
|
||||
"Copy".to_string(),
|
||||
t!("Copy").into_owned(),
|
||||
Message::Command("COPY".to_string()),
|
||||
));
|
||||
items.push(sep());
|
||||
|
|
@ -820,7 +821,7 @@ pub(super) fn viewport_context_menu_overlay(
|
|||
items.push(
|
||||
button(
|
||||
row![
|
||||
text("Draw Order").size(12),
|
||||
text(t!("Draw Order").into_owned()).size(12),
|
||||
iced::widget::Space::new().width(Fill),
|
||||
do_caret,
|
||||
]
|
||||
|
|
@ -834,51 +835,51 @@ pub(super) fn viewport_context_menu_overlay(
|
|||
);
|
||||
if draworder_open {
|
||||
items.push(subitem(
|
||||
"Bring to Front".to_string(),
|
||||
t!("Bring to Front").into_owned(),
|
||||
Message::Command("DRAWORDER F".to_string()),
|
||||
));
|
||||
items.push(subitem(
|
||||
"Send to Back".to_string(),
|
||||
t!("Send to Back").into_owned(),
|
||||
Message::Command("DRAWORDER B".to_string()),
|
||||
));
|
||||
items.push(subitem(
|
||||
"Bring Above Object".to_string(),
|
||||
t!("Bring Above Object").into_owned(),
|
||||
Message::DrawOrderPickRef(true),
|
||||
));
|
||||
items.push(subitem(
|
||||
"Send Under Object".to_string(),
|
||||
t!("Send Under Object").into_owned(),
|
||||
Message::DrawOrderPickRef(false),
|
||||
));
|
||||
}
|
||||
items.push(sep());
|
||||
items.push(item(
|
||||
"Isolate Objects".to_string(),
|
||||
t!("Isolate Objects").into_owned(),
|
||||
Message::Command("ISOLATEOBJECTS".to_string()),
|
||||
));
|
||||
items.push(item(
|
||||
"Hide Objects".to_string(),
|
||||
t!("Hide Objects").into_owned(),
|
||||
Message::Command("HIDEOBJECTS".to_string()),
|
||||
));
|
||||
items.push(sep());
|
||||
items.push(item("Select Similar".to_string(), Message::SelectSimilar));
|
||||
items.push(item(t!("Select Similar").into_owned(), Message::SelectSimilar));
|
||||
items.push(item(
|
||||
"Invert Selection".to_string(),
|
||||
t!("Invert Selection").into_owned(),
|
||||
Message::InvertSelection,
|
||||
));
|
||||
}
|
||||
if isolation_active {
|
||||
items.push(item(
|
||||
"End Object Isolation".to_string(),
|
||||
t!("End Object Isolation").into_owned(),
|
||||
Message::Command("UNISOLATEOBJECTS".to_string()),
|
||||
));
|
||||
}
|
||||
items.push(item(
|
||||
"Select All".to_string(),
|
||||
t!("Select All").into_owned(),
|
||||
Message::Command("SELECTALL".to_string()),
|
||||
));
|
||||
items.push(item("Quick Select...".to_string(), Message::QSelectOpen));
|
||||
items.push(item(t!("Quick Select...").into_owned(), Message::QSelectOpen));
|
||||
items.push(item(
|
||||
"Zoom Extents".to_string(),
|
||||
t!("Zoom Extents").into_owned(),
|
||||
Message::Command("ZOOM EXTENTS".to_string()),
|
||||
));
|
||||
}
|
||||
|
|
@ -1020,7 +1021,7 @@ pub(super) fn qselect_overlay<'a>(
|
|||
|
||||
crate::ui::modal::modal(
|
||||
Space::new().width(Fill).height(Fill),
|
||||
"Quick Select",
|
||||
t!("Quick Select"),
|
||||
content,
|
||||
Message::QSelectClose,
|
||||
modal_offset,
|
||||
|
|
@ -1081,13 +1082,13 @@ fn qselect_content<'a>(
|
|||
iced::Length::Shrink
|
||||
};
|
||||
|
||||
let label = |s: &'static str| {
|
||||
let label = |s: std::borrow::Cow<'static, str>| {
|
||||
text(s)
|
||||
.size(12)
|
||||
.width(iced::Length::Fixed(90.0))
|
||||
};
|
||||
|
||||
let btn = |lbl: &'static str, msg: Message, primary: bool| {
|
||||
let btn = |lbl: std::borrow::Cow<'static, str>, msg: Message, primary: bool| {
|
||||
button(text(lbl).size(12))
|
||||
.on_press(msg)
|
||||
.style(move |theme: &Theme, st| {
|
||||
|
|
@ -1124,7 +1125,7 @@ fn qselect_content<'a>(
|
|||
|
||||
let panel_body = column![
|
||||
row![
|
||||
label("Object type:"),
|
||||
label(t!("Object type:")),
|
||||
iced::widget::pick_list(
|
||||
Some(type_sel),
|
||||
type_options,
|
||||
|
|
@ -1144,7 +1145,7 @@ fn qselect_content<'a>(
|
|||
.width(sizing.width),
|
||||
Space::new().height(6),
|
||||
row![
|
||||
label("Property:"),
|
||||
label(t!("Property:")),
|
||||
iced::widget::pick_list(
|
||||
Some(prop_sel),
|
||||
prop_options,
|
||||
|
|
@ -1164,7 +1165,7 @@ fn qselect_content<'a>(
|
|||
.width(sizing.width),
|
||||
Space::new().height(6),
|
||||
row![
|
||||
label("Operator:"),
|
||||
label(t!("Operator:")),
|
||||
iced::widget::pick_list(
|
||||
Some(state.operator),
|
||||
op_options,
|
||||
|
|
@ -1177,7 +1178,7 @@ fn qselect_content<'a>(
|
|||
.spacing(8)
|
||||
.width(sizing.width),
|
||||
Space::new().height(6),
|
||||
row![label("Value:"), value_input,]
|
||||
row![label(t!("Value:")), value_input,]
|
||||
.align_y(iced::Alignment::Center)
|
||||
.spacing(8)
|
||||
.width(sizing.width),
|
||||
|
|
@ -1187,15 +1188,15 @@ fn qselect_content<'a>(
|
|||
.on_toggle(Message::QSelectSetAppend)
|
||||
.size(14),
|
||||
Space::new().width(6),
|
||||
text("Append to current selection").size(12),
|
||||
text(t!("Append to current selection")).size(12),
|
||||
]
|
||||
.align_y(iced::Alignment::Center),
|
||||
Space::new().height(14),
|
||||
row![
|
||||
Space::new().width(field_width),
|
||||
btn("Cancel", Message::QSelectClose, false),
|
||||
btn(t!("Cancel"), Message::QSelectClose, false),
|
||||
Space::new().width(8),
|
||||
btn("Apply", Message::QSelectApply, true),
|
||||
btn(t!("Apply"), Message::QSelectApply, true),
|
||||
]
|
||||
.align_y(iced::Alignment::Center),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ impl CadCommand for ValuePromptCommand {
|
|||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
self.prompt.to_string()
|
||||
crate::t!(self.prompt).into_owned()
|
||||
}
|
||||
|
||||
fn wants_text_input(&self) -> bool {
|
||||
|
|
@ -177,9 +177,18 @@ impl CadCommand for RenameCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
RenameStep::Type => "RENAME Select the object type to rename:".to_string(),
|
||||
RenameStep::Old { ty } => format!("RENAME {ty} Enter the current name:"),
|
||||
RenameStep::New { ty, old } => format!("RENAME {ty} Rename \"{old}\" to:"),
|
||||
RenameStep::Type => crate::t!("RENAME Select the object type to rename:").into_owned(),
|
||||
RenameStep::Old { ty } => crate::t!(
|
||||
"RENAME %{type} Enter the current name:",
|
||||
type = ty
|
||||
)
|
||||
.into_owned(),
|
||||
RenameStep::New { ty, old } => crate::t!(
|
||||
"RENAME %{type} Rename \"%{old}\" to:",
|
||||
type = ty,
|
||||
old = old
|
||||
)
|
||||
.into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -274,8 +283,10 @@ impl CadCommand for UserRegCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match self.slot {
|
||||
None => format!("{} which register? [1-5]:", self.name),
|
||||
Some(n) => format!("{}{n} new value:", self.name),
|
||||
None => crate::t!("%{name} which register? [1-5]:", name = self.name)
|
||||
.into_owned(),
|
||||
Some(n) => crate::t!("%{name}%{slot} new value:", name = self.name, slot = n)
|
||||
.into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -369,8 +380,8 @@ impl CadCommand for KeywordCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match self.pending {
|
||||
Some((_, value_prompt)) => value_prompt.to_string(),
|
||||
None => self.prompt.to_string(),
|
||||
Some((_, value_prompt)) => crate::t!(value_prompt).into_owned(),
|
||||
None => crate::t!(self.prompt).into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -464,8 +475,8 @@ impl CadCommand for TwoValuePromptCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.first {
|
||||
None => self.prompt1.to_string(),
|
||||
Some(_) => self.prompt2.to_string(),
|
||||
None => crate::t!(self.prompt1).into_owned(),
|
||||
Some(_) => crate::t!(self.prompt2).into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -548,11 +559,15 @@ impl CadCommand for SelectThenKeywordCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.gathering {
|
||||
return format!("{} select objects, then press Enter:", self.name);
|
||||
return crate::t!(
|
||||
"%{name} select objects, then press Enter:",
|
||||
name = self.name
|
||||
)
|
||||
.into_owned();
|
||||
}
|
||||
match self.pending {
|
||||
Some((_, value_prompt)) => value_prompt.to_string(),
|
||||
None => self.prompt.to_string(),
|
||||
Some((_, value_prompt)) => crate::t!(value_prompt).into_owned(),
|
||||
None => crate::t!(self.prompt).into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -655,9 +670,13 @@ impl CadCommand for SelectThenValueCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.gathering {
|
||||
format!("{} select objects, then press Enter:", self.name)
|
||||
crate::t!(
|
||||
"%{name} select objects, then press Enter:",
|
||||
name = self.name
|
||||
)
|
||||
.into_owned()
|
||||
} else {
|
||||
self.value_prompt.to_string()
|
||||
crate::t!(self.value_prompt).into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -740,11 +759,15 @@ impl CadCommand for SelectThenTwoValueCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.gathering {
|
||||
format!("{} select objects, then press Enter:", self.name)
|
||||
crate::t!(
|
||||
"%{name} select objects, then press Enter:",
|
||||
name = self.name
|
||||
)
|
||||
.into_owned()
|
||||
} else if self.first.is_none() {
|
||||
self.prompt1.to_string()
|
||||
crate::t!(self.prompt1).into_owned()
|
||||
} else {
|
||||
self.prompt2.to_string()
|
||||
crate::t!(self.prompt2).into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1220,14 +1243,14 @@ impl CmdOption {
|
|||
/// Button whose keyword is typed on click, e.g. `("Ttr", "TTR")`.
|
||||
pub fn new(label: &str, keyword: &str) -> Self {
|
||||
Self {
|
||||
label: label.to_string(),
|
||||
label: crate::t!(label).into_owned(),
|
||||
keyword: keyword.to_string(),
|
||||
}
|
||||
}
|
||||
/// A "finish" button that submits the step like Enter.
|
||||
pub fn enter(label: &str) -> Self {
|
||||
Self {
|
||||
label: label.to_string(),
|
||||
label: crate::t!(label).into_owned(),
|
||||
keyword: String::new(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use acadrust::entities::Arc;
|
||||
use crate::t;
|
||||
use truck_modeling::{builder, Point3};
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
|
|
@ -152,26 +153,26 @@ fn properties(arc: &Arc) -> Vec<PropSection> {
|
|||
let (ex, ey, ez) = arc_pt(ea);
|
||||
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
ro("Start X", "start_x", format!("{sx:.4}")),
|
||||
ro("Start Y", "start_y", format!("{sy:.4}")),
|
||||
ro("Start Z", "start_z", format!("{sz:.4}")),
|
||||
edit("Center X", "center_x", arc.center.x),
|
||||
edit("Center Y", "center_y", arc.center.y),
|
||||
edit("Center Z", "center_z", arc.center.z),
|
||||
ro("End X", "end_x", format!("{ex:.4}")),
|
||||
ro("End Y", "end_y", format!("{ey:.4}")),
|
||||
ro("End Z", "end_z", format!("{ez:.4}")),
|
||||
edit("Radius", "radius", arc.radius),
|
||||
edit_angle("Start angle", "start_angle", sa.to_degrees()),
|
||||
edit_angle("End angle", "end_angle", ea.to_degrees()),
|
||||
ro("Total angle", "total_angle", format!("{total_angle:.2}")),
|
||||
ro("Arc length", "arc_length", format!("{arc_length:.4}")),
|
||||
ro("Area", "area", format!("{area:.4}")),
|
||||
ro("Normal X", "normal_x", format!("{:.4}", arc.normal.x)),
|
||||
ro("Normal Y", "normal_y", format!("{:.4}", arc.normal.y)),
|
||||
ro("Normal Z", "normal_z", format!("{:.4}", arc.normal.z)),
|
||||
ro(t!("Start X").as_ref(), "start_x", format!("{sx:.4}")),
|
||||
ro(t!("Start Y").as_ref(), "start_y", format!("{sy:.4}")),
|
||||
ro(t!("Start Z").as_ref(), "start_z", format!("{sz:.4}")),
|
||||
edit(t!("Center X").as_ref(), "center_x", arc.center.x),
|
||||
edit(t!("Center Y").as_ref(), "center_y", arc.center.y),
|
||||
edit(t!("Center Z").as_ref(), "center_z", arc.center.z),
|
||||
ro(t!("End X").as_ref(), "end_x", format!("{ex:.4}")),
|
||||
ro(t!("End Y").as_ref(), "end_y", format!("{ey:.4}")),
|
||||
ro(t!("End Z").as_ref(), "end_z", format!("{ez:.4}")),
|
||||
edit(t!("Radius").as_ref(), "radius", arc.radius),
|
||||
edit_angle(t!("Start angle").as_ref(), "start_angle", sa.to_degrees()),
|
||||
edit_angle(t!("End angle").as_ref(), "end_angle", ea.to_degrees()),
|
||||
ro(t!("Total angle").as_ref(), "total_angle", format!("{total_angle:.2}")),
|
||||
ro(t!("Arc length").as_ref(), "arc_length", format!("{arc_length:.4}")),
|
||||
ro(t!("Area").as_ref(), "area", format!("{area:.4}")),
|
||||
ro(t!("Normal X").as_ref(), "normal_x", format!("{:.4}", arc.normal.x)),
|
||||
ro(t!("Normal Y").as_ref(), "normal_y", format!("{:.4}", arc.normal.y)),
|
||||
ro(t!("Normal Z").as_ref(), "normal_z", format!("{:.4}", arc.normal.z)),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Pr
|
|||
use crate::scene::model::wire_model::SnapHint;
|
||||
use crate::scene::text::lff;
|
||||
use crate::scene::view::transform;
|
||||
use crate::t;
|
||||
|
||||
// ── Shared helpers ────────────────────────────────────────────────────────────
|
||||
|
||||
|
|
@ -414,22 +415,22 @@ impl PropertyEditable for AttributeDefinition {
|
|||
fn geometry_properties(&self, text_style_names: &[String]) -> Vec<PropSection> {
|
||||
let mut text_props = vec![
|
||||
Property {
|
||||
label: "Tag".into(),
|
||||
label: t!("Tag").into_owned(),
|
||||
field: "att_tag",
|
||||
value: PropValue::EditText(self.tag.clone()),
|
||||
},
|
||||
Property {
|
||||
label: "Prompt".into(),
|
||||
label: t!("Prompt").into_owned(),
|
||||
field: "att_prompt",
|
||||
value: PropValue::EditText(self.prompt.clone()),
|
||||
},
|
||||
Property {
|
||||
label: "Value".into(),
|
||||
label: t!("Value").into_owned(),
|
||||
field: "att_default",
|
||||
value: PropValue::EditText(self.default_value.clone()),
|
||||
},
|
||||
Property {
|
||||
label: "Style".into(),
|
||||
label: t!("Style").into_owned(),
|
||||
field: "att_style",
|
||||
value: PropValue::Choice {
|
||||
selected: if self.text_style.trim().is_empty() {
|
||||
|
|
@ -441,12 +442,12 @@ impl PropertyEditable for AttributeDefinition {
|
|||
},
|
||||
},
|
||||
ro(
|
||||
"Annotative",
|
||||
t!("Annotative").as_ref(),
|
||||
"att_annotative",
|
||||
bool_yn(self.flags.annotative),
|
||||
),
|
||||
Property {
|
||||
label: "Justify".into(),
|
||||
label: t!("Justify").into_owned(),
|
||||
field: "att_halign",
|
||||
value: PropValue::Choice {
|
||||
selected: halign_str(self.horizontal_alignment).to_string(),
|
||||
|
|
@ -457,7 +458,7 @@ impl PropertyEditable for AttributeDefinition {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "V-Align".into(),
|
||||
label: t!("V-Align").into_owned(),
|
||||
field: "att_valign",
|
||||
value: PropValue::Choice {
|
||||
selected: valign_str(self.vertical_alignment).to_string(),
|
||||
|
|
@ -467,25 +468,25 @@ impl PropertyEditable for AttributeDefinition {
|
|||
.collect(),
|
||||
},
|
||||
},
|
||||
edit("Height", "att_h", self.height),
|
||||
edit_angle("Rotation", "att_rot", self.rotation.to_degrees()),
|
||||
edit("Width factor", "att_wf", self.width_factor),
|
||||
edit_angle("Obliquing", "att_ob", self.oblique_angle.to_degrees()),
|
||||
edit("Text alignment X", "att_ax", self.alignment_point.x),
|
||||
edit("Text alignment Y", "att_ay", self.alignment_point.y),
|
||||
edit("Text alignment Z", "att_az", self.alignment_point.z),
|
||||
edit(t!("Height").as_ref(), "att_h", self.height),
|
||||
edit_angle(t!("Rotation").as_ref(), "att_rot", self.rotation.to_degrees()),
|
||||
edit(t!("Width factor").as_ref(), "att_wf", self.width_factor),
|
||||
edit_angle(t!("Obliquing").as_ref(), "att_ob", self.oblique_angle.to_degrees()),
|
||||
edit(t!("Text alignment X").as_ref(), "att_ax", self.alignment_point.x),
|
||||
edit(t!("Text alignment Y").as_ref(), "att_ay", self.alignment_point.y),
|
||||
edit(t!("Text alignment Z").as_ref(), "att_az", self.alignment_point.z),
|
||||
ro(
|
||||
"Boundary width",
|
||||
t!("Boundary width").as_ref(),
|
||||
"att_field_len",
|
||||
self.field_length.to_string(),
|
||||
),
|
||||
ro(
|
||||
"Upside down",
|
||||
t!("Upside down").as_ref(),
|
||||
"att_upside_down",
|
||||
bool_yn(self.text_generation_flags & 0x4 != 0),
|
||||
),
|
||||
ro(
|
||||
"Backward",
|
||||
t!("Backward").as_ref(),
|
||||
"att_backward",
|
||||
bool_yn(self.text_generation_flags & 0x2 != 0),
|
||||
),
|
||||
|
|
@ -499,27 +500,27 @@ impl PropertyEditable for AttributeDefinition {
|
|||
}
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Text".into(),
|
||||
title: t!("Text").into_owned(),
|
||||
props: text_props,
|
||||
},
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Position X", "att_ix", self.insertion_point.x),
|
||||
edit("Position Y", "att_iy", self.insertion_point.y),
|
||||
edit("Position Z", "att_iz", self.insertion_point.z),
|
||||
edit(t!("Position X").as_ref(), "att_ix", self.insertion_point.x),
|
||||
edit(t!("Position Y").as_ref(), "att_iy", self.insertion_point.y),
|
||||
edit(t!("Position Z").as_ref(), "att_iz", self.insertion_point.z),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
ro("Invisible", "att_invisible", bool_yn(self.flags.invisible)),
|
||||
ro("Constant", "att_constant", bool_yn(self.flags.constant)),
|
||||
ro("Verify", "att_verify", bool_yn(self.flags.verify)),
|
||||
ro("Preset", "att_preset", bool_yn(self.flags.preset)),
|
||||
ro("Lock position", "att_lock_pos", bool_yn(self.lock_position)),
|
||||
ro(t!("Invisible").as_ref(), "att_invisible", bool_yn(self.flags.invisible)),
|
||||
ro(t!("Constant").as_ref(), "att_constant", bool_yn(self.flags.constant)),
|
||||
ro(t!("Verify").as_ref(), "att_verify", bool_yn(self.flags.verify)),
|
||||
ro(t!("Preset").as_ref(), "att_preset", bool_yn(self.flags.preset)),
|
||||
ro(t!("Lock position").as_ref(), "att_lock_pos", bool_yn(self.lock_position)),
|
||||
Property {
|
||||
label: "Multiple lines".into(),
|
||||
label: t!("Multiple lines").into_owned(),
|
||||
field: "att_mtext_flag",
|
||||
value: PropValue::Choice {
|
||||
selected: mtext_flag_str(self.mtext_flag).to_string(),
|
||||
|
|
@ -686,21 +687,21 @@ impl PropertyEditable for AttributeEntity {
|
|||
fn geometry_properties(&self, text_style_names: &[String]) -> Vec<PropSection> {
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Text".into(),
|
||||
title: t!("Text").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Tag".into(),
|
||||
label: t!("Tag").into_owned(),
|
||||
field: "atte_tag",
|
||||
value: PropValue::EditText(self.tag.clone()),
|
||||
},
|
||||
ro("Prompt", "atte_prompt", String::new()),
|
||||
ro(t!("Prompt").as_ref(), "atte_prompt", String::new()),
|
||||
Property {
|
||||
label: "Value".into(),
|
||||
label: t!("Value").into_owned(),
|
||||
field: "atte_val",
|
||||
value: PropValue::EditText(self.value.clone()),
|
||||
},
|
||||
Property {
|
||||
label: "Style".into(),
|
||||
label: t!("Style").into_owned(),
|
||||
field: "atte_style",
|
||||
value: PropValue::Choice {
|
||||
selected: if self.text_style.trim().is_empty() {
|
||||
|
|
@ -712,7 +713,7 @@ impl PropertyEditable for AttributeEntity {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Justify".into(),
|
||||
label: t!("Justify").into_owned(),
|
||||
field: "atte_halign",
|
||||
value: PropValue::Choice {
|
||||
selected: halign_str(self.horizontal_alignment).to_string(),
|
||||
|
|
@ -723,7 +724,7 @@ impl PropertyEditable for AttributeEntity {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "V-Align".into(),
|
||||
label: t!("V-Align").into_owned(),
|
||||
field: "atte_valign",
|
||||
value: PropValue::Choice {
|
||||
selected: valign_str(self.vertical_alignment).to_string(),
|
||||
|
|
@ -734,56 +735,56 @@ impl PropertyEditable for AttributeEntity {
|
|||
},
|
||||
},
|
||||
ro(
|
||||
"Annotative",
|
||||
t!("Annotative").as_ref(),
|
||||
"atte_annotative",
|
||||
bool_yn(self.flags.annotative),
|
||||
),
|
||||
edit("Height", "atte_h", self.height),
|
||||
edit_angle("Rotation", "atte_rot", self.rotation.to_degrees()),
|
||||
edit("Width factor", "atte_wf", self.width_factor),
|
||||
edit_angle("Obliquing", "atte_ob", self.oblique_angle.to_degrees()),
|
||||
edit("Text alignment X", "atte_ax", self.alignment_point.x),
|
||||
edit("Text alignment Y", "atte_ay", self.alignment_point.y),
|
||||
edit("Text alignment Z", "atte_az", self.alignment_point.z),
|
||||
edit(t!("Height").as_ref(), "atte_h", self.height),
|
||||
edit_angle(t!("Rotation").as_ref(), "atte_rot", self.rotation.to_degrees()),
|
||||
edit(t!("Width factor").as_ref(), "atte_wf", self.width_factor),
|
||||
edit_angle(t!("Obliquing").as_ref(), "atte_ob", self.oblique_angle.to_degrees()),
|
||||
edit(t!("Text alignment X").as_ref(), "atte_ax", self.alignment_point.x),
|
||||
edit(t!("Text alignment Y").as_ref(), "atte_ay", self.alignment_point.y),
|
||||
edit(t!("Text alignment Z").as_ref(), "atte_az", self.alignment_point.z),
|
||||
ro(
|
||||
"Boundary width",
|
||||
t!("Boundary width").as_ref(),
|
||||
"atte_field_len",
|
||||
self.field_length.to_string(),
|
||||
),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Position X", "atte_ix", self.insertion_point.x),
|
||||
edit("Position Y", "atte_iy", self.insertion_point.y),
|
||||
edit("Position Z", "atte_iz", self.insertion_point.z),
|
||||
edit(t!("Position X").as_ref(), "atte_ix", self.insertion_point.x),
|
||||
edit(t!("Position Y").as_ref(), "atte_iy", self.insertion_point.y),
|
||||
edit(t!("Position Z").as_ref(), "atte_iz", self.insertion_point.z),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
ro(
|
||||
"Upside down",
|
||||
t!("Upside down").as_ref(),
|
||||
"atte_upside_down",
|
||||
bool_yn(self.text_generation_flags & 0x4 != 0),
|
||||
),
|
||||
ro(
|
||||
"Backward",
|
||||
t!("Backward").as_ref(),
|
||||
"atte_backward",
|
||||
bool_yn(self.text_generation_flags & 0x2 != 0),
|
||||
),
|
||||
ro("Invisible", "atte_invisible", bool_yn(self.flags.invisible)),
|
||||
ro(t!("Invisible").as_ref(), "atte_invisible", bool_yn(self.flags.invisible)),
|
||||
ro(
|
||||
"Multiple lines",
|
||||
t!("Multiple lines").as_ref(),
|
||||
"atte_mtext_flag",
|
||||
mtext_flag_str(self.mtext_flag),
|
||||
),
|
||||
ro("Constant", "atte_constant", bool_yn(self.flags.constant)),
|
||||
ro("Verify", "atte_verify", bool_yn(self.flags.verify)),
|
||||
ro("Preset", "atte_preset", bool_yn(self.flags.preset)),
|
||||
ro(t!("Constant").as_ref(), "atte_constant", bool_yn(self.flags.constant)),
|
||||
ro(t!("Verify").as_ref(), "atte_verify", bool_yn(self.flags.verify)),
|
||||
ro(t!("Preset").as_ref(), "atte_preset", bool_yn(self.flags.preset)),
|
||||
ro(
|
||||
"Lock position",
|
||||
t!("Lock position").as_ref(),
|
||||
"atte_lock_pos",
|
||||
bool_yn(self.lock_position),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use acadrust::entities::Circle;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{
|
||||
|
|
@ -134,18 +135,18 @@ fn properties(circle: &Circle) -> Vec<PropSection> {
|
|||
use std::f64::consts::PI;
|
||||
let r = circle.radius;
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Center X", "center_x", circle.center.x),
|
||||
edit("Center Y", "center_y", circle.center.y),
|
||||
edit("Center Z", "center_z", circle.center.z),
|
||||
edit("Radius", "radius", r),
|
||||
edit("Diameter", "diameter", r * 2.0),
|
||||
edit("Circumference", "circumference", 2.0 * PI * r),
|
||||
edit("Area", "area", PI * r * r),
|
||||
ro("Normal X", "normal_x", format!("{:.4}", circle.normal.x)),
|
||||
ro("Normal Y", "normal_y", format!("{:.4}", circle.normal.y)),
|
||||
ro("Normal Z", "normal_z", format!("{:.4}", circle.normal.z)),
|
||||
edit(t!("Center X").as_ref(), "center_x", circle.center.x),
|
||||
edit(t!("Center Y").as_ref(), "center_y", circle.center.y),
|
||||
edit(t!("Center Z").as_ref(), "center_z", circle.center.z),
|
||||
edit(t!("Radius").as_ref(), "radius", r),
|
||||
edit(t!("Diameter").as_ref(), "diameter", r * 2.0),
|
||||
edit(t!("Circumference").as_ref(), "circumference", 2.0 * PI * r),
|
||||
edit(t!("Area").as_ref(), "area", PI * r * r),
|
||||
ro(t!("Normal X").as_ref(), "normal_x", format!("{:.4}", circle.normal.x)),
|
||||
ro(t!("Normal Y").as_ref(), "normal_y", format!("{:.4}", circle.normal.y)),
|
||||
ro(t!("Normal Z").as_ref(), "normal_z", format!("{:.4}", circle.normal.z)),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ pub fn triangle_grip(id: usize, world: glam::DVec3) -> GripDef {
|
|||
/// LINEAR formatter, so LUNITS=Architectural showed a block rotation as
|
||||
/// feet-and-inches and the string wouldn't parse back (#297). Value in
|
||||
/// DEGREES, matching every angle call site.
|
||||
pub fn edit_angle_prop(label: &'static str, field: &'static str, value_deg: f64) -> Property {
|
||||
pub fn edit_angle_prop(label: &str, field: &'static str, value_deg: f64) -> Property {
|
||||
Property {
|
||||
label: label.into(),
|
||||
field,
|
||||
|
|
@ -195,7 +195,7 @@ pub fn edit_angle_prop(label: &'static str, field: &'static str, value_deg: f64)
|
|||
}
|
||||
}
|
||||
|
||||
pub fn edit_prop(label: &'static str, field: &'static str, value: f64) -> Property {
|
||||
pub fn edit_prop(label: &str, field: &'static str, value: f64) -> Property {
|
||||
Property {
|
||||
label: label.into(),
|
||||
field,
|
||||
|
|
@ -203,7 +203,7 @@ pub fn edit_prop(label: &'static str, field: &'static str, value: f64) -> Proper
|
|||
}
|
||||
}
|
||||
|
||||
pub fn ro_prop(label: &'static str, field: &'static str, value: impl Into<String>) -> Property {
|
||||
pub fn ro_prop(label: &str, field: &'static str, value: impl Into<String>) -> Property {
|
||||
Property {
|
||||
label: label.into(),
|
||||
field,
|
||||
|
|
@ -215,7 +215,7 @@ pub fn ro_prop(label: &'static str, field: &'static str, value: impl Into<String
|
|||
/// read-only value using the same length formatting. Used where a field's
|
||||
/// editability depends on entity state (e.g. a text point that is only live for
|
||||
/// certain justifications, or an MText column dimension).
|
||||
pub fn num_prop(label: &'static str, field: &'static str, value: f64, editable: bool) -> Property {
|
||||
pub fn num_prop(label: &str, field: &'static str, value: f64, editable: bool) -> Property {
|
||||
if editable {
|
||||
edit_prop(label, field, value)
|
||||
} else {
|
||||
|
|
@ -226,7 +226,7 @@ pub fn num_prop(label: &'static str, field: &'static str, value: f64, editable:
|
|||
/// A ◀ / ▶ index navigator row (e.g. a polyline's Current Vertex). `display` is
|
||||
/// the label shown between the arrows (e.g. "2 / 7").
|
||||
pub fn stepper_prop(
|
||||
label: &'static str,
|
||||
label: &str,
|
||||
field: &'static str,
|
||||
display: impl Into<String>,
|
||||
) -> Property {
|
||||
|
|
|
|||
|
|
@ -12,46 +12,47 @@ use crate::entities::common::{
|
|||
};
|
||||
use crate::entities::traits::{Grippable, PropertyEditable, Transformable};
|
||||
use crate::scene::model::object::{GripApply, GripDef, PropSection};
|
||||
use crate::t;
|
||||
|
||||
fn base_props(base: &DimensionBase) -> Vec<crate::scene::model::object::Property> {
|
||||
vec![
|
||||
crate::scene::model::object::Property {
|
||||
label: "Text".into(),
|
||||
label: t!("Text").into_owned(),
|
||||
field: "text",
|
||||
value: crate::scene::model::object::PropValue::EditText(base.text.clone()),
|
||||
},
|
||||
crate::scene::model::object::Property {
|
||||
label: "User Text".into(),
|
||||
label: t!("User Text").into_owned(),
|
||||
field: "user_text",
|
||||
value: crate::scene::model::object::PropValue::EditText(
|
||||
base.user_text.clone().unwrap_or_default(),
|
||||
),
|
||||
},
|
||||
crate::scene::model::object::Property {
|
||||
label: "Style".into(),
|
||||
label: t!("Style").into_owned(),
|
||||
field: "style_name",
|
||||
value: crate::scene::model::object::PropValue::EditText(base.style_name.clone()),
|
||||
},
|
||||
edit("Text X", "text_x", base.text_middle_point.x),
|
||||
edit("Text Y", "text_y", base.text_middle_point.y),
|
||||
edit("Text Z", "text_z", base.text_middle_point.z),
|
||||
edit(t!("Text X").as_ref(), "text_x", base.text_middle_point.x),
|
||||
edit(t!("Text Y").as_ref(), "text_y", base.text_middle_point.y),
|
||||
edit(t!("Text Z").as_ref(), "text_z", base.text_middle_point.z),
|
||||
edit(
|
||||
"Text Rotation (deg)",
|
||||
t!("Text Rotation (deg)").as_ref(),
|
||||
"text_rotation",
|
||||
base.text_rotation.to_degrees(),
|
||||
),
|
||||
edit(
|
||||
"Horizontal Dir (deg)",
|
||||
t!("Horizontal Dir (deg)").as_ref(),
|
||||
"horizontal_direction",
|
||||
base.horizontal_direction.to_degrees(),
|
||||
),
|
||||
edit(
|
||||
"Line Spacing",
|
||||
t!("Line Spacing").as_ref(),
|
||||
"line_spacing_factor",
|
||||
base.line_spacing_factor,
|
||||
),
|
||||
ro(
|
||||
"Measurement",
|
||||
t!("Measurement").as_ref(),
|
||||
"measurement",
|
||||
format!("{:.4}", base.actual_measurement),
|
||||
),
|
||||
|
|
@ -68,7 +69,7 @@ fn properties(dim: &Dimension) -> Vec<PropSection> {
|
|||
d.definition_point,
|
||||
));
|
||||
props.push(edit(
|
||||
"Ext Rotation (deg)",
|
||||
t!("Ext Rotation (deg)").as_ref(),
|
||||
"ext_line_rotation",
|
||||
d.ext_line_rotation.to_degrees(),
|
||||
));
|
||||
|
|
@ -79,20 +80,20 @@ fn properties(dim: &Dimension) -> Vec<PropSection> {
|
|||
d.second_point,
|
||||
d.definition_point,
|
||||
));
|
||||
props.push(edit_angle("Rotation", "rotation", d.rotation.to_degrees()));
|
||||
props.push(edit_angle(t!("Rotation").as_ref(), "rotation", d.rotation.to_degrees()));
|
||||
props.push(edit(
|
||||
"Ext Rotation (deg)",
|
||||
t!("Ext Rotation (deg)").as_ref(),
|
||||
"ext_line_rotation",
|
||||
d.ext_line_rotation.to_degrees(),
|
||||
));
|
||||
}
|
||||
Dimension::Radius(d) => {
|
||||
props.extend(radius_like_props(d.angle_vertex, d.definition_point));
|
||||
props.push(edit("Leader Length", "leader_length", d.leader_length));
|
||||
props.push(edit(t!("Leader Length").as_ref(), "leader_length", d.leader_length));
|
||||
}
|
||||
Dimension::Diameter(d) => {
|
||||
props.extend(radius_like_props(d.angle_vertex, d.definition_point));
|
||||
props.push(edit("Leader Length", "leader_length", d.leader_length));
|
||||
props.push(edit(t!("Leader Length").as_ref(), "leader_length", d.leader_length));
|
||||
}
|
||||
Dimension::Angular2Ln(d) => {
|
||||
props.extend(angular_props(
|
||||
|
|
@ -101,9 +102,9 @@ fn properties(dim: &Dimension) -> Vec<PropSection> {
|
|||
d.second_point,
|
||||
d.definition_point,
|
||||
));
|
||||
props.push(edit("Arc X", "dimension_arc_x", d.dimension_arc.x));
|
||||
props.push(edit("Arc Y", "dimension_arc_y", d.dimension_arc.y));
|
||||
props.push(edit("Arc Z", "dimension_arc_z", d.dimension_arc.z));
|
||||
props.push(edit(t!("Arc X").as_ref(), "dimension_arc_x", d.dimension_arc.x));
|
||||
props.push(edit(t!("Arc Y").as_ref(), "dimension_arc_y", d.dimension_arc.y));
|
||||
props.push(edit(t!("Arc Z").as_ref(), "dimension_arc_z", d.dimension_arc.z));
|
||||
}
|
||||
Dimension::Angular3Pt(d) => {
|
||||
props.extend(angular_props(
|
||||
|
|
@ -114,17 +115,17 @@ fn properties(dim: &Dimension) -> Vec<PropSection> {
|
|||
));
|
||||
}
|
||||
Dimension::Ordinate(d) => {
|
||||
props.push(edit("Origin X", "definition_x", d.definition_point.x));
|
||||
props.push(edit("Origin Y", "definition_y", d.definition_point.y));
|
||||
props.push(edit("Origin Z", "definition_z", d.definition_point.z));
|
||||
props.push(edit("Feature X", "feature_x", d.feature_location.x));
|
||||
props.push(edit("Feature Y", "feature_y", d.feature_location.y));
|
||||
props.push(edit("Feature Z", "feature_z", d.feature_location.z));
|
||||
props.push(edit("Leader X", "leader_x", d.leader_endpoint.x));
|
||||
props.push(edit("Leader Y", "leader_y", d.leader_endpoint.y));
|
||||
props.push(edit("Leader Z", "leader_z", d.leader_endpoint.z));
|
||||
props.push(edit(t!("Origin X").as_ref(), "definition_x", d.definition_point.x));
|
||||
props.push(edit(t!("Origin Y").as_ref(), "definition_y", d.definition_point.y));
|
||||
props.push(edit(t!("Origin Z").as_ref(), "definition_z", d.definition_point.z));
|
||||
props.push(edit(t!("Feature X").as_ref(), "feature_x", d.feature_location.x));
|
||||
props.push(edit(t!("Feature Y").as_ref(), "feature_y", d.feature_location.y));
|
||||
props.push(edit(t!("Feature Z").as_ref(), "feature_z", d.feature_location.z));
|
||||
props.push(edit(t!("Leader X").as_ref(), "leader_x", d.leader_endpoint.x));
|
||||
props.push(edit(t!("Leader Y").as_ref(), "leader_y", d.leader_endpoint.y));
|
||||
props.push(edit(t!("Leader Z").as_ref(), "leader_z", d.leader_endpoint.z));
|
||||
props.push(ro(
|
||||
"Ordinate Type",
|
||||
t!("Ordinate Type").as_ref(),
|
||||
"ordinate_type",
|
||||
if d.is_ordinate_type_x { "X" } else { "Y" },
|
||||
));
|
||||
|
|
@ -137,42 +138,42 @@ fn properties(dim: &Dimension) -> Vec<PropSection> {
|
|||
d.definition_point,
|
||||
));
|
||||
props.push(edit(
|
||||
"Arc Start (deg)",
|
||||
t!("Arc Start (deg)").as_ref(),
|
||||
"arc_start_parameter",
|
||||
d.arc_start_parameter.to_degrees(),
|
||||
));
|
||||
props.push(edit(
|
||||
"Arc End (deg)",
|
||||
t!("Arc End (deg)").as_ref(),
|
||||
"arc_end_parameter",
|
||||
d.arc_end_parameter.to_degrees(),
|
||||
));
|
||||
props.push(ro("Partial", "is_partial", d.is_partial.to_string()));
|
||||
props.push(ro("Has Leader", "has_leader", d.has_leader.to_string()));
|
||||
props.push(edit("Leader 1 X", "leader1_x", d.first_leader_point.x));
|
||||
props.push(edit("Leader 1 Y", "leader1_y", d.first_leader_point.y));
|
||||
props.push(edit("Leader 1 Z", "leader1_z", d.first_leader_point.z));
|
||||
props.push(edit("Leader 2 X", "leader2_x", d.second_leader_point.x));
|
||||
props.push(edit("Leader 2 Y", "leader2_y", d.second_leader_point.y));
|
||||
props.push(edit("Leader 2 Z", "leader2_z", d.second_leader_point.z));
|
||||
props.push(ro(t!("Partial").as_ref(), "is_partial", d.is_partial.to_string()));
|
||||
props.push(ro(t!("Has Leader").as_ref(), "has_leader", d.has_leader.to_string()));
|
||||
props.push(edit(t!("Leader 1 X").as_ref(), "leader1_x", d.first_leader_point.x));
|
||||
props.push(edit(t!("Leader 1 Y").as_ref(), "leader1_y", d.first_leader_point.y));
|
||||
props.push(edit(t!("Leader 1 Z").as_ref(), "leader1_z", d.first_leader_point.z));
|
||||
props.push(edit(t!("Leader 2 X").as_ref(), "leader2_x", d.second_leader_point.x));
|
||||
props.push(edit(t!("Leader 2 Y").as_ref(), "leader2_y", d.second_leader_point.y));
|
||||
props.push(edit(t!("Leader 2 Z").as_ref(), "leader2_z", d.second_leader_point.z));
|
||||
}
|
||||
Dimension::LargeRadial(d) => {
|
||||
props.push(edit("Center X", "definition_x", d.definition_point.x));
|
||||
props.push(edit("Center Y", "definition_y", d.definition_point.y));
|
||||
props.push(edit("Center Z", "definition_z", d.definition_point.z));
|
||||
props.push(edit("Chord X", "chord_x", d.chord_point.x));
|
||||
props.push(edit("Chord Y", "chord_y", d.chord_point.y));
|
||||
props.push(edit("Chord Z", "chord_z", d.chord_point.z));
|
||||
props.push(edit("Override Center X", "override_x", d.override_center.x));
|
||||
props.push(edit("Override Center Y", "override_y", d.override_center.y));
|
||||
props.push(edit("Override Center Z", "override_z", d.override_center.z));
|
||||
props.push(edit("Jog X", "jog_x", d.jog_point.x));
|
||||
props.push(edit("Jog Y", "jog_y", d.jog_point.y));
|
||||
props.push(edit("Jog Z", "jog_z", d.jog_point.z));
|
||||
props.push(edit_angle("Jog Angle", "jog_angle", d.jog_angle.to_degrees()));
|
||||
props.push(edit(t!("Center X").as_ref(), "definition_x", d.definition_point.x));
|
||||
props.push(edit(t!("Center Y").as_ref(), "definition_y", d.definition_point.y));
|
||||
props.push(edit(t!("Center Z").as_ref(), "definition_z", d.definition_point.z));
|
||||
props.push(edit(t!("Chord X").as_ref(), "chord_x", d.chord_point.x));
|
||||
props.push(edit(t!("Chord Y").as_ref(), "chord_y", d.chord_point.y));
|
||||
props.push(edit(t!("Chord Z").as_ref(), "chord_z", d.chord_point.z));
|
||||
props.push(edit(t!("Override Center X").as_ref(), "override_x", d.override_center.x));
|
||||
props.push(edit(t!("Override Center Y").as_ref(), "override_y", d.override_center.y));
|
||||
props.push(edit(t!("Override Center Z").as_ref(), "override_z", d.override_center.z));
|
||||
props.push(edit(t!("Jog X").as_ref(), "jog_x", d.jog_point.x));
|
||||
props.push(edit(t!("Jog Y").as_ref(), "jog_y", d.jog_point.y));
|
||||
props.push(edit(t!("Jog Z").as_ref(), "jog_z", d.jog_point.z));
|
||||
props.push(edit_angle(t!("Jog Angle").as_ref(), "jog_angle", d.jog_angle.to_degrees()));
|
||||
}
|
||||
}
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props,
|
||||
}]
|
||||
}
|
||||
|
|
@ -183,15 +184,15 @@ fn linear_like_props(
|
|||
definition: acadrust::types::Vector3,
|
||||
) -> Vec<crate::scene::model::object::Property> {
|
||||
vec![
|
||||
edit("First X", "first_x", first.x),
|
||||
edit("First Y", "first_y", first.y),
|
||||
edit("First Z", "first_z", first.z),
|
||||
edit("Second X", "second_x", second.x),
|
||||
edit("Second Y", "second_y", second.y),
|
||||
edit("Second Z", "second_z", second.z),
|
||||
edit("Definition X", "definition_x", definition.x),
|
||||
edit("Definition Y", "definition_y", definition.y),
|
||||
edit("Definition Z", "definition_z", definition.z),
|
||||
edit(t!("First X").as_ref(), "first_x", first.x),
|
||||
edit(t!("First Y").as_ref(), "first_y", first.y),
|
||||
edit(t!("First Z").as_ref(), "first_z", first.z),
|
||||
edit(t!("Second X").as_ref(), "second_x", second.x),
|
||||
edit(t!("Second Y").as_ref(), "second_y", second.y),
|
||||
edit(t!("Second Z").as_ref(), "second_z", second.z),
|
||||
edit(t!("Definition X").as_ref(), "definition_x", definition.x),
|
||||
edit(t!("Definition Y").as_ref(), "definition_y", definition.y),
|
||||
edit(t!("Definition Z").as_ref(), "definition_z", definition.z),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -200,12 +201,12 @@ fn radius_like_props(
|
|||
point: acadrust::types::Vector3,
|
||||
) -> Vec<crate::scene::model::object::Property> {
|
||||
vec![
|
||||
edit("Center X", "center_x", center.x),
|
||||
edit("Center Y", "center_y", center.y),
|
||||
edit("Center Z", "center_z", center.z),
|
||||
edit("Point X", "point_x", point.x),
|
||||
edit("Point Y", "point_y", point.y),
|
||||
edit("Point Z", "point_z", point.z),
|
||||
edit(t!("Center X").as_ref(), "center_x", center.x),
|
||||
edit(t!("Center Y").as_ref(), "center_y", center.y),
|
||||
edit(t!("Center Z").as_ref(), "center_z", center.z),
|
||||
edit(t!("Point X").as_ref(), "point_x", point.x),
|
||||
edit(t!("Point Y").as_ref(), "point_y", point.y),
|
||||
edit(t!("Point Z").as_ref(), "point_z", point.z),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -216,18 +217,18 @@ fn angular_props(
|
|||
definition: acadrust::types::Vector3,
|
||||
) -> Vec<crate::scene::model::object::Property> {
|
||||
vec![
|
||||
edit("Vertex X", "vertex_x", vertex.x),
|
||||
edit("Vertex Y", "vertex_y", vertex.y),
|
||||
edit("Vertex Z", "vertex_z", vertex.z),
|
||||
edit("First X", "first_x", first.x),
|
||||
edit("First Y", "first_y", first.y),
|
||||
edit("First Z", "first_z", first.z),
|
||||
edit("Second X", "second_x", second.x),
|
||||
edit("Second Y", "second_y", second.y),
|
||||
edit("Second Z", "second_z", second.z),
|
||||
edit("Definition X", "definition_x", definition.x),
|
||||
edit("Definition Y", "definition_y", definition.y),
|
||||
edit("Definition Z", "definition_z", definition.z),
|
||||
edit(t!("Vertex X").as_ref(), "vertex_x", vertex.x),
|
||||
edit(t!("Vertex Y").as_ref(), "vertex_y", vertex.y),
|
||||
edit(t!("Vertex Z").as_ref(), "vertex_z", vertex.z),
|
||||
edit(t!("First X").as_ref(), "first_x", first.x),
|
||||
edit(t!("First Y").as_ref(), "first_y", first.y),
|
||||
edit(t!("First Z").as_ref(), "first_z", first.z),
|
||||
edit(t!("Second X").as_ref(), "second_x", second.x),
|
||||
edit(t!("Second Y").as_ref(), "second_y", second.y),
|
||||
edit(t!("Second Z").as_ref(), "second_z", second.z),
|
||||
edit(t!("Definition X").as_ref(), "definition_x", definition.x),
|
||||
edit(t!("Definition Y").as_ref(), "definition_y", definition.y),
|
||||
edit(t!("Definition Z").as_ref(), "definition_z", definition.z),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -1150,133 +1151,133 @@ pub fn style_sections(style: &DimStyle) -> Vec<crate::scene::model::object::Prop
|
|||
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Lines & Arrows".into(),
|
||||
title: t!("Lines & Arrows").into_owned(),
|
||||
props: vec![
|
||||
ro("Arrow size", "dim_arrow_size", f(s.dimasz)),
|
||||
ro("Dim line color", "dim_line_color", s.dimclrd.to_string()),
|
||||
ro(t!("Arrow size").as_ref(), "dim_arrow_size", f(s.dimasz)),
|
||||
ro(t!("Dim line color").as_ref(), "dim_line_color", s.dimclrd.to_string()),
|
||||
ro(
|
||||
"Dim line lineweight",
|
||||
t!("Dim line lineweight").as_ref(),
|
||||
"dim_line_lineweight",
|
||||
s.dimlwd.to_string(),
|
||||
),
|
||||
ro("Ext line color", "dim_ext_line_color", s.dimclre.to_string()),
|
||||
ro(t!("Ext line color").as_ref(), "dim_ext_line_color", s.dimclre.to_string()),
|
||||
ro(
|
||||
"Ext line lineweight",
|
||||
t!("Ext line lineweight").as_ref(),
|
||||
"dim_ext_line_lineweight",
|
||||
s.dimlwe.to_string(),
|
||||
),
|
||||
ro("Dim line 1", "dim_line_1", onoff(!s.dimsd1)),
|
||||
ro("Dim line 2", "dim_line_2", onoff(!s.dimsd2)),
|
||||
ro("Ext line 1", "dim_ext_line_1", onoff(!s.dimse1)),
|
||||
ro("Ext line 2", "dim_ext_line_2", onoff(!s.dimse2)),
|
||||
ro("Dim line ext", "dim_line_ext", f(s.dimdle)),
|
||||
ro("Ext line ext", "dim_ext_line_ext", f(s.dimexe)),
|
||||
ro("Ext line offset", "dim_ext_line_offset", f(s.dimexo)),
|
||||
ro("Ext line fixed", "dim_ext_line_fixed", yn(s.dimfxlon)),
|
||||
ro(t!("Dim line 1").as_ref(), "dim_line_1", onoff(!s.dimsd1)),
|
||||
ro(t!("Dim line 2").as_ref(), "dim_line_2", onoff(!s.dimsd2)),
|
||||
ro(t!("Ext line 1").as_ref(), "dim_ext_line_1", onoff(!s.dimse1)),
|
||||
ro(t!("Ext line 2").as_ref(), "dim_ext_line_2", onoff(!s.dimse2)),
|
||||
ro(t!("Dim line ext").as_ref(), "dim_line_ext", f(s.dimdle)),
|
||||
ro(t!("Ext line ext").as_ref(), "dim_ext_line_ext", f(s.dimexe)),
|
||||
ro(t!("Ext line offset").as_ref(), "dim_ext_line_offset", f(s.dimexo)),
|
||||
ro(t!("Ext line fixed").as_ref(), "dim_ext_line_fixed", yn(s.dimfxlon)),
|
||||
ro(
|
||||
"Ext line fixed length",
|
||||
t!("Ext line fixed length").as_ref(),
|
||||
"dim_ext_line_fixed_length",
|
||||
f(s.dimfxl),
|
||||
),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Text".into(),
|
||||
title: t!("Text").into_owned(),
|
||||
props: vec![
|
||||
ro("Fill color", "dim_text_fill_color", s.dimtfillclr.to_string()),
|
||||
ro("Text color", "dim_text_color", s.dimclrt.to_string()),
|
||||
ro("Text height", "dim_text_height", f(s.dimtxt)),
|
||||
ro("Text offset", "dim_text_offset", f(s.dimgap)),
|
||||
ro("Text pos vert", "dim_text_pos_vert", s.dimtad.to_string()),
|
||||
ro("Text pos hor", "dim_text_pos_hor", s.dimjust.to_string()),
|
||||
ro("Text outside align", "dim_text_outside_align", yn(s.dimtoh)),
|
||||
ro("Text inside align", "dim_text_inside_align", yn(s.dimtih)),
|
||||
ro("Text style", "dim_text_style", s.dimtxsty.clone()),
|
||||
ro(t!("Fill color").as_ref(), "dim_text_fill_color", s.dimtfillclr.to_string()),
|
||||
ro(t!("Text color").as_ref(), "dim_text_color", s.dimclrt.to_string()),
|
||||
ro(t!("Text height").as_ref(), "dim_text_height", f(s.dimtxt)),
|
||||
ro(t!("Text offset").as_ref(), "dim_text_offset", f(s.dimgap)),
|
||||
ro(t!("Text pos vert").as_ref(), "dim_text_pos_vert", s.dimtad.to_string()),
|
||||
ro(t!("Text pos hor").as_ref(), "dim_text_pos_hor", s.dimjust.to_string()),
|
||||
ro(t!("Text outside align").as_ref(), "dim_text_outside_align", yn(s.dimtoh)),
|
||||
ro(t!("Text inside align").as_ref(), "dim_text_inside_align", yn(s.dimtih)),
|
||||
ro(t!("Text style").as_ref(), "dim_text_style", s.dimtxsty.clone()),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Fit".into(),
|
||||
title: t!("Fit").into_owned(),
|
||||
props: vec![
|
||||
ro("Fit", "dim_fit", s.dimatfit.to_string()),
|
||||
ro("Text inside", "dim_text_inside", yn(s.dimtix)),
|
||||
ro("Text movement", "dim_text_movement", s.dimtmove.to_string()),
|
||||
ro("Dim scale overall", "dim_scale_overall", f(s.dimscale)),
|
||||
ro("Dim line forced", "dim_line_forced", yn(s.dimtofl)),
|
||||
ro("Dim line inside", "dim_line_inside", yn(s.dimsoxd)),
|
||||
ro(t!("Fit").as_ref(), "dim_fit", s.dimatfit.to_string()),
|
||||
ro(t!("Text inside").as_ref(), "dim_text_inside", yn(s.dimtix)),
|
||||
ro(t!("Text movement").as_ref(), "dim_text_movement", s.dimtmove.to_string()),
|
||||
ro(t!("Dim scale overall").as_ref(), "dim_scale_overall", f(s.dimscale)),
|
||||
ro(t!("Dim line forced").as_ref(), "dim_line_forced", yn(s.dimtofl)),
|
||||
ro(t!("Dim line inside").as_ref(), "dim_line_inside", yn(s.dimsoxd)),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Primary Units".into(),
|
||||
title: t!("Primary Units").into_owned(),
|
||||
props: vec![
|
||||
ro("Dim units", "dim_units", s.dimlunit.to_string()),
|
||||
ro("Precision", "dim_precision", s.dimdec.to_string()),
|
||||
ro("Decimal separator", "dim_decimal_separator", dsep),
|
||||
ro("Dim prefix/suffix", "dim_prefix_suffix", s.dimpost.clone()),
|
||||
ro("Dim roundoff", "dim_roundoff", f(s.dimrnd)),
|
||||
ro(t!("Dim units").as_ref(), "dim_units", s.dimlunit.to_string()),
|
||||
ro(t!("Precision").as_ref(), "dim_precision", s.dimdec.to_string()),
|
||||
ro(t!("Decimal separator").as_ref(), "dim_decimal_separator", dsep),
|
||||
ro(t!("Dim prefix/suffix").as_ref(), "dim_prefix_suffix", s.dimpost.clone()),
|
||||
ro(t!("Dim roundoff").as_ref(), "dim_roundoff", f(s.dimrnd)),
|
||||
ro(
|
||||
"Suppress leading zeros",
|
||||
t!("Suppress leading zeros").as_ref(),
|
||||
"dim_suppress_leading_zeros",
|
||||
yn(s.dimzin & 4 != 0),
|
||||
),
|
||||
ro(
|
||||
"Suppress trailing zeros",
|
||||
t!("Suppress trailing zeros").as_ref(),
|
||||
"dim_suppress_trailing_zeros",
|
||||
yn(s.dimzin & 8 != 0),
|
||||
),
|
||||
ro("Dim scale linear", "dim_scale_linear", f(s.dimlfac)),
|
||||
ro("Angle format", "dim_angle_format", s.dimaunit.to_string()),
|
||||
ro("Angle precision", "dim_angle_precision", s.dimadec.to_string()),
|
||||
ro(t!("Dim scale linear").as_ref(), "dim_scale_linear", f(s.dimlfac)),
|
||||
ro(t!("Angle format").as_ref(), "dim_angle_format", s.dimaunit.to_string()),
|
||||
ro(t!("Angle precision").as_ref(), "dim_angle_precision", s.dimadec.to_string()),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Alternate Units".into(),
|
||||
title: t!("Alternate Units").into_owned(),
|
||||
props: vec![
|
||||
ro("Alt enabled", "dim_alt_enabled", yn(s.dimalt)),
|
||||
ro("Alt format", "dim_alt_format", s.dimaltu.to_string()),
|
||||
ro("Alt precision", "dim_alt_precision", s.dimaltd.to_string()),
|
||||
ro("Alt scale factor", "dim_alt_scale_factor", f(s.dimaltf)),
|
||||
ro("Alt roundoff", "dim_alt_roundoff", f(s.dimaltrnd)),
|
||||
ro("Alt prefix/suffix", "dim_alt_prefix_suffix", s.dimapost.clone()),
|
||||
ro(t!("Alt enabled").as_ref(), "dim_alt_enabled", yn(s.dimalt)),
|
||||
ro(t!("Alt format").as_ref(), "dim_alt_format", s.dimaltu.to_string()),
|
||||
ro(t!("Alt precision").as_ref(), "dim_alt_precision", s.dimaltd.to_string()),
|
||||
ro(t!("Alt scale factor").as_ref(), "dim_alt_scale_factor", f(s.dimaltf)),
|
||||
ro(t!("Alt roundoff").as_ref(), "dim_alt_roundoff", f(s.dimaltrnd)),
|
||||
ro(t!("Alt prefix/suffix").as_ref(), "dim_alt_prefix_suffix", s.dimapost.clone()),
|
||||
ro(
|
||||
"Alt suppress leading zeros",
|
||||
t!("Alt suppress leading zeros").as_ref(),
|
||||
"dim_alt_suppress_leading_zeros",
|
||||
yn(s.dimaltz & 4 != 0),
|
||||
),
|
||||
ro(
|
||||
"Alt suppress trailing zeros",
|
||||
t!("Alt suppress trailing zeros").as_ref(),
|
||||
"dim_alt_suppress_trailing_zeros",
|
||||
yn(s.dimaltz & 8 != 0),
|
||||
),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Tolerances".into(),
|
||||
title: t!("Tolerances").into_owned(),
|
||||
props: vec![
|
||||
ro("Tolerance display", "dim_tolerance_display", tol_display),
|
||||
ro("Tolerance limit lower", "dim_tolerance_limit_lower", f(s.dimtm)),
|
||||
ro("Tolerance limit upper", "dim_tolerance_limit_upper", f(s.dimtp)),
|
||||
ro(t!("Tolerance display").as_ref(), "dim_tolerance_display", tol_display),
|
||||
ro(t!("Tolerance limit lower").as_ref(), "dim_tolerance_limit_lower", f(s.dimtm)),
|
||||
ro(t!("Tolerance limit upper").as_ref(), "dim_tolerance_limit_upper", f(s.dimtp)),
|
||||
ro(
|
||||
"Tolerance precision",
|
||||
t!("Tolerance precision").as_ref(),
|
||||
"dim_tolerance_precision",
|
||||
s.dimtdec.to_string(),
|
||||
),
|
||||
ro(
|
||||
"Tolerance text height",
|
||||
t!("Tolerance text height").as_ref(),
|
||||
"dim_tolerance_text_height",
|
||||
f(s.dimtfac),
|
||||
),
|
||||
ro(
|
||||
"Tolerance pos vert",
|
||||
t!("Tolerance pos vert").as_ref(),
|
||||
"dim_tolerance_pos_vert",
|
||||
s.dimtolj.to_string(),
|
||||
),
|
||||
ro(
|
||||
"Tolerance suppress leading zeros",
|
||||
t!("Tolerance suppress leading zeros").as_ref(),
|
||||
"dim_tolerance_suppress_leading_zeros",
|
||||
yn(s.dimtzin & 4 != 0),
|
||||
),
|
||||
ro(
|
||||
"Tolerance suppress trailing zeros",
|
||||
t!("Tolerance suppress trailing zeros").as_ref(),
|
||||
"dim_tolerance_suppress_trailing_zeros",
|
||||
yn(s.dimtzin & 8 != 0),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use acadrust::entities::Ellipse;
|
||||
use crate::t;
|
||||
use truck_modeling::{builder, BSplineCurve, Curve, Edge, KnotVec, Point3, Wire};
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
|
|
@ -194,35 +195,35 @@ fn properties(ell: &Ellipse) -> Vec<PropSection> {
|
|||
let props = ell.mass_props();
|
||||
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
ro("Start X", "start_x", format!("{:.4}", start.x)),
|
||||
ro("Start Y", "start_y", format!("{:.4}", start.y)),
|
||||
ro("Start Z", "start_z", format!("{:.4}", start.z)),
|
||||
edit("Center X", "center_x", ell.center.x),
|
||||
edit("Center Y", "center_y", ell.center.y),
|
||||
edit("Center Z", "center_z", ell.center.z),
|
||||
ro("End X", "end_x", format!("{:.4}", end.x)),
|
||||
ro("End Y", "end_y", format!("{:.4}", end.y)),
|
||||
ro("End Z", "end_z", format!("{:.4}", end.z)),
|
||||
edit("Major radius", "major_r", r_major),
|
||||
edit("Minor radius", "minor_r", r_minor),
|
||||
edit("Radius ratio", "ratio", ell.minor_axis_ratio),
|
||||
edit("Start angle", "start_angle", start_angle),
|
||||
edit("End angle", "end_angle", end_angle),
|
||||
ro("Major axis vector X", "major_x", format!("{:.4}", major_vec.x)),
|
||||
ro("Major axis vector Y", "major_y", format!("{:.4}", major_vec.y)),
|
||||
ro("Major axis vector Z", "major_z", format!("{:.4}", major_vec.z)),
|
||||
ro("Minor axis vector X", "minor_x", format!("{:.4}", minor_vec.x)),
|
||||
ro("Minor axis vector Y", "minor_y", format!("{:.4}", minor_vec.y)),
|
||||
ro("Minor axis vector Z", "minor_z", format!("{:.4}", minor_vec.z)),
|
||||
ro("Area", "area", format!("{:.4}", props.area)),
|
||||
ro("Start parameter", "start_param", format!("{:.4}", ell.start_parameter)),
|
||||
ro("End parameter", "end_param", format!("{:.4}", ell.end_parameter)),
|
||||
ro("Length", "length", format!("{:.4}", props.perimeter)),
|
||||
ro("Normal X", "normal_x", format!("{:.4}", ell.normal.x)),
|
||||
ro("Normal Y", "normal_y", format!("{:.4}", ell.normal.y)),
|
||||
ro("Normal Z", "normal_z", format!("{:.4}", ell.normal.z)),
|
||||
ro(t!("Start X").as_ref(), "start_x", format!("{:.4}", start.x)),
|
||||
ro(t!("Start Y").as_ref(), "start_y", format!("{:.4}", start.y)),
|
||||
ro(t!("Start Z").as_ref(), "start_z", format!("{:.4}", start.z)),
|
||||
edit(t!("Center X").as_ref(), "center_x", ell.center.x),
|
||||
edit(t!("Center Y").as_ref(), "center_y", ell.center.y),
|
||||
edit(t!("Center Z").as_ref(), "center_z", ell.center.z),
|
||||
ro(t!("End X").as_ref(), "end_x", format!("{:.4}", end.x)),
|
||||
ro(t!("End Y").as_ref(), "end_y", format!("{:.4}", end.y)),
|
||||
ro(t!("End Z").as_ref(), "end_z", format!("{:.4}", end.z)),
|
||||
edit(t!("Major radius").as_ref(), "major_r", r_major),
|
||||
edit(t!("Minor radius").as_ref(), "minor_r", r_minor),
|
||||
edit(t!("Radius ratio").as_ref(), "ratio", ell.minor_axis_ratio),
|
||||
edit(t!("Start angle").as_ref(), "start_angle", start_angle),
|
||||
edit(t!("End angle").as_ref(), "end_angle", end_angle),
|
||||
ro(t!("Major axis vector X").as_ref(), "major_x", format!("{:.4}", major_vec.x)),
|
||||
ro(t!("Major axis vector Y").as_ref(), "major_y", format!("{:.4}", major_vec.y)),
|
||||
ro(t!("Major axis vector Z").as_ref(), "major_z", format!("{:.4}", major_vec.z)),
|
||||
ro(t!("Minor axis vector X").as_ref(), "minor_x", format!("{:.4}", minor_vec.x)),
|
||||
ro(t!("Minor axis vector Y").as_ref(), "minor_y", format!("{:.4}", minor_vec.y)),
|
||||
ro(t!("Minor axis vector Z").as_ref(), "minor_z", format!("{:.4}", minor_vec.z)),
|
||||
ro(t!("Area").as_ref(), "area", format!("{:.4}", props.area)),
|
||||
ro(t!("Start parameter").as_ref(), "start_param", format!("{:.4}", ell.start_parameter)),
|
||||
ro(t!("End parameter").as_ref(), "end_param", format!("{:.4}", ell.end_parameter)),
|
||||
ro(t!("Length").as_ref(), "length", format!("{:.4}", props.perimeter)),
|
||||
ro(t!("Normal X").as_ref(), "normal_x", format!("{:.4}", ell.normal.x)),
|
||||
ro(t!("Normal Y").as_ref(), "normal_y", format!("{:.4}", ell.normal.y)),
|
||||
ro(t!("Normal Z").as_ref(), "normal_z", format!("{:.4}", ell.normal.z)),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use acadrust::entities::{
|
|||
PointCloudData, PointCloudExData, RemoteTextData, SectionObjectData,
|
||||
};
|
||||
use acadrust::types::{Handle, Transform, Vector3};
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{
|
||||
|
|
@ -29,7 +30,7 @@ fn handle_text(handle: Handle) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
fn text_prop(label: &'static str, field: &'static str, value: &str) -> Property {
|
||||
fn text_prop(label: &str, field: &'static str, value: &str) -> Property {
|
||||
Property {
|
||||
label: label.into(),
|
||||
field,
|
||||
|
|
@ -37,7 +38,7 @@ fn text_prop(label: &'static str, field: &'static str, value: &str) -> Property
|
|||
}
|
||||
}
|
||||
|
||||
fn bool_prop(label: &'static str, field: &'static str, value: bool) -> Property {
|
||||
fn bool_prop(label: &str, field: &'static str, value: bool) -> Property {
|
||||
Property {
|
||||
label: label.into(),
|
||||
field,
|
||||
|
|
@ -481,40 +482,36 @@ fn section_properties(data: &SectionObjectData) -> Vec<PropSection> {
|
|||
.join("\n");
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Section Object".into(),
|
||||
title: t!("Section Object").into_owned(),
|
||||
props: vec![
|
||||
text_prop("Name", "ext_section_name", &data.name),
|
||||
ro_prop("State", "ext_section_state", data.state.to_string()),
|
||||
ro_prop("Flags", "ext_section_flags", data.flags.to_string()),
|
||||
ro_prop(
|
||||
"Vertical Direction",
|
||||
text_prop(t!("Name").as_ref(), "ext_section_name", &data.name),
|
||||
ro_prop(t!("State").as_ref(), "ext_section_state", data.state.to_string()),
|
||||
ro_prop(t!("Flags").as_ref(), "ext_section_flags", data.flags.to_string()),
|
||||
ro_prop(t!("Vertical Direction").as_ref(),
|
||||
"ext_section_vertical",
|
||||
vector_text(data.vertical_direction),
|
||||
),
|
||||
edit_prop("Top Height", "ext_section_top", data.top_height),
|
||||
edit_prop("Bottom Height", "ext_section_bottom", data.bottom_height),
|
||||
ro_prop(
|
||||
"Indicator Alpha",
|
||||
edit_prop(t!("Top Height").as_ref(), "ext_section_top", data.top_height),
|
||||
edit_prop(t!("Bottom Height").as_ref(), "ext_section_bottom", data.bottom_height),
|
||||
ro_prop(t!("Indicator Alpha").as_ref(),
|
||||
"ext_section_alpha",
|
||||
data.indicator_alpha.to_string(),
|
||||
),
|
||||
ro_prop(
|
||||
"Indicator Color",
|
||||
ro_prop(t!("Indicator Color").as_ref(),
|
||||
"ext_section_color",
|
||||
format!("{:?}", data.indicator_color),
|
||||
),
|
||||
ro_prop(
|
||||
"Settings",
|
||||
ro_prop(t!("Settings").as_ref(),
|
||||
"ext_section_settings",
|
||||
handle_text(data.settings_handle),
|
||||
),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Section Vertices".into(),
|
||||
title: t!("Section Vertices").into_owned(),
|
||||
props: vec![
|
||||
ro_prop("Cutting Line", "ext_section_vertices", vertices),
|
||||
ro_prop("Back Line", "ext_section_back_vertices", back_vertices),
|
||||
ro_prop(t!("Cutting Line").as_ref(), "ext_section_vertices", vertices),
|
||||
ro_prop(t!("Back Line").as_ref(), "ext_section_back_vertices", back_vertices),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
@ -522,114 +519,102 @@ fn section_properties(data: &SectionObjectData) -> Vec<PropSection> {
|
|||
|
||||
fn arc_text_properties(data: &ArcAlignedTextData) -> Vec<PropSection> {
|
||||
vec![PropSection {
|
||||
title: "Arc-Aligned Text".into(),
|
||||
title: t!("Arc-Aligned Text").into_owned(),
|
||||
props: vec![
|
||||
text_prop("Text", "ext_arc_text", &data.text),
|
||||
text_prop("Font", "ext_arc_font", &data.font_name),
|
||||
text_prop("Big Font", "ext_arc_big_font", &data.big_font_name),
|
||||
text_prop("Style", "ext_arc_style", &data.style_name),
|
||||
ro_prop("Center", "ext_arc_center", vector_text(data.center)),
|
||||
edit_prop("Radius", "ext_arc_radius", data.radius),
|
||||
edit_prop("X Scale", "ext_arc_xscale", data.x_scale),
|
||||
edit_prop("Text Size", "ext_arc_size", data.text_size),
|
||||
edit_prop(
|
||||
"Character Spacing",
|
||||
text_prop(t!("Text").as_ref(), "ext_arc_text", &data.text),
|
||||
text_prop(t!("Font").as_ref(), "ext_arc_font", &data.font_name),
|
||||
text_prop(t!("Big Font").as_ref(), "ext_arc_big_font", &data.big_font_name),
|
||||
text_prop(t!("Style").as_ref(), "ext_arc_style", &data.style_name),
|
||||
ro_prop(t!("Center").as_ref(), "ext_arc_center", vector_text(data.center)),
|
||||
edit_prop(t!("Radius").as_ref(), "ext_arc_radius", data.radius),
|
||||
edit_prop(t!("X Scale").as_ref(), "ext_arc_xscale", data.x_scale),
|
||||
edit_prop(t!("Text Size").as_ref(), "ext_arc_size", data.text_size),
|
||||
edit_prop(t!("Character Spacing").as_ref(),
|
||||
"ext_arc_spacing",
|
||||
data.character_spacing,
|
||||
),
|
||||
edit_prop(
|
||||
"Offset From Arc",
|
||||
edit_prop(t!("Offset From Arc").as_ref(),
|
||||
"ext_arc_offset",
|
||||
data.offset_from_arc,
|
||||
),
|
||||
edit_prop("Right Offset", "ext_arc_right", data.right_offset),
|
||||
edit_prop("Left Offset", "ext_arc_left", data.left_offset),
|
||||
edit_angle_prop(
|
||||
"Start Angle",
|
||||
edit_prop(t!("Right Offset").as_ref(), "ext_arc_right", data.right_offset),
|
||||
edit_prop(t!("Left Offset").as_ref(), "ext_arc_left", data.left_offset),
|
||||
edit_angle_prop(t!("Start Angle").as_ref(),
|
||||
"ext_arc_start",
|
||||
data.start_angle.to_degrees(),
|
||||
),
|
||||
edit_angle_prop("End Angle", "ext_arc_end", data.end_angle.to_degrees()),
|
||||
bool_prop("Reverse", "ext_arc_reverse", data.reverse),
|
||||
ro_prop(
|
||||
"Text Direction",
|
||||
edit_angle_prop(t!("End Angle").as_ref(), "ext_arc_end", data.end_angle.to_degrees()),
|
||||
bool_prop(t!("Reverse").as_ref(), "ext_arc_reverse", data.reverse),
|
||||
ro_prop(t!("Text Direction").as_ref(),
|
||||
"ext_arc_direction",
|
||||
data.text_direction.to_string(),
|
||||
),
|
||||
ro_prop("Alignment", "ext_arc_alignment", data.alignment.to_string()),
|
||||
ro_prop(
|
||||
"Text Position",
|
||||
ro_prop(t!("Alignment").as_ref(), "ext_arc_alignment", data.alignment.to_string()),
|
||||
ro_prop(t!("Text Position").as_ref(),
|
||||
"ext_arc_position",
|
||||
data.text_position.to_string(),
|
||||
),
|
||||
bool_prop("Bold", "ext_arc_bold", data.bold),
|
||||
bool_prop("Italic", "ext_arc_italic", data.italic),
|
||||
bool_prop("Underlined", "ext_arc_underlined", data.underlined),
|
||||
ro_prop(
|
||||
"Character Set",
|
||||
bool_prop(t!("Bold").as_ref(), "ext_arc_bold", data.bold),
|
||||
bool_prop(t!("Italic").as_ref(), "ext_arc_italic", data.italic),
|
||||
bool_prop(t!("Underlined").as_ref(), "ext_arc_underlined", data.underlined),
|
||||
ro_prop(t!("Character Set").as_ref(),
|
||||
"ext_arc_charset",
|
||||
data.character_set.to_string(),
|
||||
),
|
||||
ro_prop(
|
||||
"Pitch And Family",
|
||||
ro_prop(t!("Pitch And Family").as_ref(),
|
||||
"ext_arc_pitch",
|
||||
data.pitch_and_family.to_string(),
|
||||
),
|
||||
bool_prop("SHX", "ext_arc_shx", data.is_shx),
|
||||
ro_prop("Text Color", "ext_arc_color", data.text_color.to_string()),
|
||||
ro_prop("Normal", "ext_arc_normal", vector_text(data.normal)),
|
||||
bool_prop("Wizard Flag", "ext_arc_wizard", data.wizard_flag),
|
||||
ro_prop("Arc", "ext_arc_handle", handle_text(data.arc_handle)),
|
||||
bool_prop(t!("SHX").as_ref(), "ext_arc_shx", data.is_shx),
|
||||
ro_prop(t!("Text Color").as_ref(), "ext_arc_color", data.text_color.to_string()),
|
||||
ro_prop(t!("Normal").as_ref(), "ext_arc_normal", vector_text(data.normal)),
|
||||
bool_prop(t!("Wizard Flag").as_ref(), "ext_arc_wizard", data.wizard_flag),
|
||||
ro_prop(t!("Arc").as_ref(), "ext_arc_handle", handle_text(data.arc_handle)),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
||||
fn remote_text_properties(data: &RemoteTextData) -> Vec<PropSection> {
|
||||
vec![PropSection {
|
||||
title: "Remote Text".into(),
|
||||
title: t!("Remote Text").into_owned(),
|
||||
props: vec![
|
||||
text_prop("Text", "ext_rtext_text", &data.text),
|
||||
ro_prop("Position", "ext_rtext_position", vector_text(data.position)),
|
||||
ro_prop("Normal", "ext_rtext_normal", vector_text(data.normal)),
|
||||
edit_angle_prop(
|
||||
"Rotation",
|
||||
text_prop(t!("Text").as_ref(), "ext_rtext_text", &data.text),
|
||||
ro_prop(t!("Position").as_ref(), "ext_rtext_position", vector_text(data.position)),
|
||||
ro_prop(t!("Normal").as_ref(), "ext_rtext_normal", vector_text(data.normal)),
|
||||
edit_angle_prop(t!("Rotation").as_ref(),
|
||||
"ext_rtext_rotation",
|
||||
data.rotation.to_degrees(),
|
||||
),
|
||||
edit_prop("Height", "ext_rtext_height", data.height),
|
||||
text_prop("Style Name", "ext_rtext_style", &data.style_name),
|
||||
ro_prop(
|
||||
"Style Handle",
|
||||
edit_prop(t!("Height").as_ref(), "ext_rtext_height", data.height),
|
||||
text_prop(t!("Style Name").as_ref(), "ext_rtext_style", &data.style_name),
|
||||
ro_prop(t!("Style Handle").as_ref(),
|
||||
"ext_rtext_style_handle",
|
||||
handle_text(data.style_handle),
|
||||
),
|
||||
ro_prop("Flags", "ext_rtext_flags", data.flags.to_string()),
|
||||
ro_prop(t!("Flags").as_ref(), "ext_rtext_flags", data.flags.to_string()),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
||||
fn geo_marker_properties(data: &GeoPositionMarkerData) -> Vec<PropSection> {
|
||||
vec![PropSection {
|
||||
title: "Geographic Position Marker".into(),
|
||||
title: t!("Geographic Position Marker").into_owned(),
|
||||
props: vec![
|
||||
ro_prop(
|
||||
"Class Version",
|
||||
ro_prop(t!("Class Version").as_ref(),
|
||||
"ext_geo_version",
|
||||
data.class_version.to_string(),
|
||||
),
|
||||
ro_prop("Position", "ext_geo_position", vector_text(data.position)),
|
||||
edit_prop("Radius", "ext_geo_radius", data.radius),
|
||||
text_prop("Notes", "ext_geo_notes", &data.notes),
|
||||
edit_prop("Landing Gap", "ext_geo_gap", data.landing_gap),
|
||||
bool_prop("Text Visible", "ext_geo_visible", data.mtext_visible),
|
||||
ro_prop(
|
||||
"Text Alignment",
|
||||
ro_prop(t!("Position").as_ref(), "ext_geo_position", vector_text(data.position)),
|
||||
edit_prop(t!("Radius").as_ref(), "ext_geo_radius", data.radius),
|
||||
text_prop(t!("Notes").as_ref(), "ext_geo_notes", &data.notes),
|
||||
edit_prop(t!("Landing Gap").as_ref(), "ext_geo_gap", data.landing_gap),
|
||||
bool_prop(t!("Text Visible").as_ref(), "ext_geo_visible", data.mtext_visible),
|
||||
ro_prop(t!("Text Alignment").as_ref(),
|
||||
"ext_geo_alignment",
|
||||
data.text_alignment.to_string(),
|
||||
),
|
||||
bool_prop("Frame Text", "ext_geo_frame", data.enable_frame_text),
|
||||
ro_prop(
|
||||
"Embedded MText",
|
||||
bool_prop(t!("Frame Text").as_ref(), "ext_geo_frame", data.enable_frame_text),
|
||||
ro_prop(t!("Embedded MText").as_ref(),
|
||||
"ext_geo_mtext",
|
||||
data.embedded_mtext
|
||||
.as_ref()
|
||||
|
|
@ -660,91 +645,77 @@ fn point_cloud_properties(data: &PointCloudData) -> Vec<PropSection> {
|
|||
.join("\n");
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Point Cloud".into(),
|
||||
title: t!("Point Cloud").into_owned(),
|
||||
props: vec![
|
||||
ro_prop(
|
||||
"Class Version",
|
||||
ro_prop(t!("Class Version").as_ref(),
|
||||
"ext_pc_version",
|
||||
data.class_version.to_string(),
|
||||
),
|
||||
ro_prop("Origin", "ext_pc_origin", vector_text(data.origin)),
|
||||
text_prop("Saved File", "ext_pc_file", &data.saved_filename),
|
||||
ro_prop(
|
||||
"Source Files",
|
||||
ro_prop(t!("Origin").as_ref(), "ext_pc_origin", vector_text(data.origin)),
|
||||
text_prop(t!("Saved File").as_ref(), "ext_pc_file", &data.saved_filename),
|
||||
ro_prop(t!("Source Files").as_ref(),
|
||||
"ext_pc_sources",
|
||||
data.source_files.join("\n"),
|
||||
),
|
||||
ro_prop("Extents Min", "ext_pc_min", vector_text(data.extents_min)),
|
||||
ro_prop("Extents Max", "ext_pc_max", vector_text(data.extents_max)),
|
||||
ro_prop(
|
||||
"Point Count",
|
||||
ro_prop(t!("Extents Min").as_ref(), "ext_pc_min", vector_text(data.extents_min)),
|
||||
ro_prop(t!("Extents Max").as_ref(), "ext_pc_max", vector_text(data.extents_max)),
|
||||
ro_prop(t!("Point Count").as_ref(),
|
||||
"ext_pc_count",
|
||||
data.point_count.to_string(),
|
||||
),
|
||||
text_prop("UCS Name", "ext_pc_ucs", &data.ucs_name),
|
||||
ro_prop(
|
||||
"UCS Origin",
|
||||
text_prop(t!("UCS Name").as_ref(), "ext_pc_ucs", &data.ucs_name),
|
||||
ro_prop(t!("UCS Origin").as_ref(),
|
||||
"ext_pc_ucs_origin",
|
||||
vector_text(data.ucs_origin),
|
||||
),
|
||||
ro_prop(
|
||||
"UCS X",
|
||||
ro_prop(t!("UCS X").as_ref(),
|
||||
"ext_pc_ucs_x",
|
||||
vector_text(data.ucs_x_direction),
|
||||
),
|
||||
ro_prop(
|
||||
"UCS Y",
|
||||
ro_prop(t!("UCS Y").as_ref(),
|
||||
"ext_pc_ucs_y",
|
||||
vector_text(data.ucs_y_direction),
|
||||
),
|
||||
ro_prop(
|
||||
"UCS Z",
|
||||
ro_prop(t!("UCS Z").as_ref(),
|
||||
"ext_pc_ucs_z",
|
||||
vector_text(data.ucs_z_direction),
|
||||
),
|
||||
ro_prop(
|
||||
"Definition",
|
||||
ro_prop(t!("Definition").as_ref(),
|
||||
"ext_pc_definition",
|
||||
handle_text(data.definition_handle),
|
||||
),
|
||||
ro_prop(
|
||||
"Reactor",
|
||||
ro_prop(t!("Reactor").as_ref(),
|
||||
"ext_pc_reactor",
|
||||
handle_text(data.reactor_handle),
|
||||
),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Point Cloud Display".into(),
|
||||
title: t!("Point Cloud Display").into_owned(),
|
||||
props: vec![
|
||||
bool_prop("Show Intensity", "ext_pc_show_intensity", data.show_intensity),
|
||||
ro_prop(
|
||||
"Intensity Scheme",
|
||||
bool_prop(t!("Show Intensity").as_ref(), "ext_pc_show_intensity", data.show_intensity),
|
||||
ro_prop(t!("Intensity Scheme").as_ref(),
|
||||
"ext_pc_intensity_scheme",
|
||||
data.intensity_scheme.to_string(),
|
||||
),
|
||||
edit_prop(
|
||||
"Minimum Intensity",
|
||||
edit_prop(t!("Minimum Intensity").as_ref(),
|
||||
"ext_pc_intensity_min",
|
||||
data.minimum_intensity,
|
||||
),
|
||||
edit_prop(
|
||||
"Maximum Intensity",
|
||||
edit_prop(t!("Maximum Intensity").as_ref(),
|
||||
"ext_pc_intensity_max",
|
||||
data.maximum_intensity,
|
||||
),
|
||||
edit_prop(
|
||||
"Low Threshold",
|
||||
edit_prop(t!("Low Threshold").as_ref(),
|
||||
"ext_pc_low_threshold",
|
||||
data.low_intensity_threshold,
|
||||
),
|
||||
edit_prop(
|
||||
"High Threshold",
|
||||
edit_prop(t!("High Threshold").as_ref(),
|
||||
"ext_pc_high_threshold",
|
||||
data.high_intensity_threshold,
|
||||
),
|
||||
bool_prop("Show Clipping", "ext_pc_show_clipping", data.show_clipping),
|
||||
ro_prop("Clippings", "ext_pc_clippings", clips),
|
||||
bool_prop(t!("Show Clipping").as_ref(), "ext_pc_show_clipping", data.show_clipping),
|
||||
ro_prop(t!("Clippings").as_ref(), "ext_pc_clippings", clips),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
@ -770,92 +741,77 @@ fn point_cloud_ex_properties(data: &PointCloudExData) -> Vec<PropSection> {
|
|||
.join("\n");
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Point Cloud Ex".into(),
|
||||
title: t!("Point Cloud Ex").into_owned(),
|
||||
props: vec![
|
||||
ro_prop(
|
||||
"Class Version",
|
||||
ro_prop(t!("Class Version").as_ref(),
|
||||
"ext_pcx_version",
|
||||
data.class_version.to_string(),
|
||||
),
|
||||
text_prop("Name", "ext_pcx_name", &data.name),
|
||||
ro_prop("Extents Min", "ext_pcx_min", vector_text(data.extents_min)),
|
||||
ro_prop("Extents Max", "ext_pcx_max", vector_text(data.extents_max)),
|
||||
ro_prop(
|
||||
"UCS Origin",
|
||||
text_prop(t!("Name").as_ref(), "ext_pcx_name", &data.name),
|
||||
ro_prop(t!("Extents Min").as_ref(), "ext_pcx_min", vector_text(data.extents_min)),
|
||||
ro_prop(t!("Extents Max").as_ref(), "ext_pcx_max", vector_text(data.extents_max)),
|
||||
ro_prop(t!("UCS Origin").as_ref(),
|
||||
"ext_pcx_ucs_origin",
|
||||
vector_text(data.ucs_origin),
|
||||
),
|
||||
ro_prop(
|
||||
"UCS X",
|
||||
ro_prop(t!("UCS X").as_ref(),
|
||||
"ext_pcx_ucs_x",
|
||||
vector_text(data.ucs_x_direction),
|
||||
),
|
||||
ro_prop(
|
||||
"UCS Y",
|
||||
ro_prop(t!("UCS Y").as_ref(),
|
||||
"ext_pcx_ucs_y",
|
||||
vector_text(data.ucs_y_direction),
|
||||
),
|
||||
ro_prop(
|
||||
"UCS Z",
|
||||
ro_prop(t!("UCS Z").as_ref(),
|
||||
"ext_pcx_ucs_z",
|
||||
vector_text(data.ucs_z_direction),
|
||||
),
|
||||
bool_prop("Locked", "ext_pcx_locked", data.locked),
|
||||
ro_prop(
|
||||
"Definition",
|
||||
bool_prop(t!("Locked").as_ref(), "ext_pcx_locked", data.locked),
|
||||
ro_prop(t!("Definition").as_ref(),
|
||||
"ext_pcx_definition",
|
||||
handle_text(data.definition_handle),
|
||||
),
|
||||
ro_prop(
|
||||
"Reactor",
|
||||
ro_prop(t!("Reactor").as_ref(),
|
||||
"ext_pcx_reactor",
|
||||
handle_text(data.reactor_handle),
|
||||
),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Point Cloud Ex Display".into(),
|
||||
title: t!("Point Cloud Ex Display").into_owned(),
|
||||
props: vec![
|
||||
bool_prop(
|
||||
"Show Intensity",
|
||||
bool_prop(t!("Show Intensity").as_ref(),
|
||||
"ext_pcx_show_intensity",
|
||||
data.show_intensity,
|
||||
),
|
||||
bool_prop("Show Cropping", "ext_pcx_show_cropping", data.show_cropping),
|
||||
ro_prop(
|
||||
"Unknown Flags",
|
||||
bool_prop(t!("Show Cropping").as_ref(), "ext_pcx_show_cropping", data.show_cropping),
|
||||
ro_prop(t!("Unknown Flags").as_ref(),
|
||||
"ext_pcx_unknown",
|
||||
format!("{}, {}", data.unknown_bl0, data.unknown_bl1),
|
||||
),
|
||||
ro_prop(
|
||||
"Stylization Type",
|
||||
ro_prop(t!("Stylization Type").as_ref(),
|
||||
"ext_pcx_stylization",
|
||||
data.stylization_type.to_string(),
|
||||
),
|
||||
text_prop(
|
||||
"Intensity Color Scheme",
|
||||
text_prop(t!("Intensity Color Scheme").as_ref(),
|
||||
"ext_pcx_intensity_scheme",
|
||||
&data.intensity_color_scheme,
|
||||
),
|
||||
text_prop(
|
||||
"Current Color Scheme",
|
||||
text_prop(t!("Current Color Scheme").as_ref(),
|
||||
"ext_pcx_current_scheme",
|
||||
&data.current_color_scheme,
|
||||
),
|
||||
text_prop(
|
||||
"Classification Scheme",
|
||||
text_prop(t!("Classification Scheme").as_ref(),
|
||||
"ext_pcx_class_scheme",
|
||||
&data.classification_color_scheme,
|
||||
),
|
||||
edit_prop("Elevation Min", "ext_pcx_elevation_min", data.elevation_min),
|
||||
edit_prop("Elevation Max", "ext_pcx_elevation_max", data.elevation_max),
|
||||
ro_prop(
|
||||
"Intensity Range",
|
||||
edit_prop(t!("Elevation Min").as_ref(), "ext_pcx_elevation_min", data.elevation_min),
|
||||
edit_prop(t!("Elevation Max").as_ref(), "ext_pcx_elevation_max", data.elevation_max),
|
||||
ro_prop(t!("Intensity Range").as_ref(),
|
||||
"ext_pcx_intensity_range",
|
||||
format!("{}..{}", data.intensity_min, data.intensity_max),
|
||||
),
|
||||
ro_prop(
|
||||
"Out Of Range Behavior",
|
||||
ro_prop(t!("Out Of Range Behavior").as_ref(),
|
||||
"ext_pcx_out_of_range",
|
||||
format!(
|
||||
"intensity {}; elevation {}",
|
||||
|
|
@ -863,22 +819,19 @@ fn point_cloud_ex_properties(data: &PointCloudExData) -> Vec<PropSection> {
|
|||
data.elevation_out_of_range_behavior
|
||||
),
|
||||
),
|
||||
bool_prop(
|
||||
"Fixed Elevation Range",
|
||||
bool_prop(t!("Fixed Elevation Range").as_ref(),
|
||||
"ext_pcx_fixed_range",
|
||||
data.elevation_apply_to_fixed_range,
|
||||
),
|
||||
bool_prop(
|
||||
"Intensity Gradient",
|
||||
bool_prop(t!("Intensity Gradient").as_ref(),
|
||||
"ext_pcx_intensity_gradient",
|
||||
data.intensity_as_gradient,
|
||||
),
|
||||
bool_prop(
|
||||
"Elevation Gradient",
|
||||
bool_prop(t!("Elevation Gradient").as_ref(),
|
||||
"ext_pcx_elevation_gradient",
|
||||
data.elevation_as_gradient,
|
||||
),
|
||||
ro_prop("Croppings", "ext_pcx_croppings", crops),
|
||||
ro_prop(t!("Croppings").as_ref(), "ext_pcx_croppings", crops),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
@ -918,25 +871,23 @@ fn reference_properties(
|
|||
fn properties(entity: &ExtendedEntity) -> Vec<PropSection> {
|
||||
match &entity.data {
|
||||
ExtendedEntityData::Camera { view_handle } => vec![PropSection {
|
||||
title: "Camera".into(),
|
||||
props: vec![ro_prop("View", "ext_camera_view", handle_text(*view_handle))],
|
||||
title: t!("Camera").into_owned(),
|
||||
props: vec![ro_prop(t!("View").as_ref(), "ext_camera_view", handle_text(*view_handle))],
|
||||
}],
|
||||
ExtendedEntityData::SectionObject(data) => section_properties(data),
|
||||
ExtendedEntityData::ArcAlignedText(data) => arc_text_properties(data),
|
||||
ExtendedEntityData::RemoteText(data) => remote_text_properties(data),
|
||||
ExtendedEntityData::GeoPositionMarker(data) => geo_marker_properties(data),
|
||||
ExtendedEntityData::CoordinationModel(data) => vec![PropSection {
|
||||
title: "Coordination Model".into(),
|
||||
title: t!("Coordination Model").into_owned(),
|
||||
props: vec![
|
||||
ro_prop("Flags", "ext_coord_flags", data.flags.to_string()),
|
||||
ro_prop(
|
||||
"Definition",
|
||||
ro_prop(t!("Flags").as_ref(), "ext_coord_flags", data.flags.to_string()),
|
||||
ro_prop(t!("Definition").as_ref(),
|
||||
"ext_coord_definition",
|
||||
handle_text(data.definition_handle),
|
||||
),
|
||||
edit_prop("Unit Factor", "ext_coord_unit", data.unit_factor),
|
||||
ro_prop(
|
||||
"Transform",
|
||||
edit_prop(t!("Unit Factor").as_ref(), "ext_coord_unit", data.unit_factor),
|
||||
ro_prop(t!("Transform").as_ref(),
|
||||
"ext_coord_transform",
|
||||
data.transform
|
||||
.chunks_exact(4)
|
||||
|
|
@ -954,68 +905,60 @@ fn properties(entity: &ExtendedEntity) -> Vec<PropSection> {
|
|||
ExtendedEntityData::PointCloud(data) => point_cloud_properties(data),
|
||||
ExtendedEntityData::PointCloudEx(data) => point_cloud_ex_properties(data),
|
||||
ExtendedEntityData::Proxy(data) => vec![PropSection {
|
||||
title: "Proxy Entity".into(),
|
||||
title: t!("Proxy Entity").into_owned(),
|
||||
props: vec![
|
||||
ro_prop("Proxy ID", "ext_proxy_id", data.proxy_id.to_string()),
|
||||
ro_prop("Class ID", "ext_proxy_class", data.class_id.to_string()),
|
||||
ro_prop("DXF Subclass", "ext_proxy_subclass", data.dxf_subclass.clone()),
|
||||
ro_prop("Version", "ext_proxy_version", data.version.to_string()),
|
||||
ro_prop(
|
||||
"DWG Version",
|
||||
ro_prop(t!("Proxy ID").as_ref(), "ext_proxy_id", data.proxy_id.to_string()),
|
||||
ro_prop(t!("Class ID").as_ref(), "ext_proxy_class", data.class_id.to_string()),
|
||||
ro_prop(t!("DXF Subclass").as_ref(), "ext_proxy_subclass", data.dxf_subclass.clone()),
|
||||
ro_prop(t!("Version").as_ref(), "ext_proxy_version", data.version.to_string()),
|
||||
ro_prop(t!("DWG Version").as_ref(),
|
||||
"ext_proxy_dwg_version",
|
||||
format!("{}.{}", data.dwg_version, data.maintenance_version),
|
||||
),
|
||||
ro_prop("From DXF", "ext_proxy_from_dxf", data.from_dxf.to_string()),
|
||||
ro_prop(
|
||||
"Graphics",
|
||||
ro_prop(t!("From DXF").as_ref(), "ext_proxy_from_dxf", data.from_dxf.to_string()),
|
||||
ro_prop(t!("Graphics").as_ref(),
|
||||
"ext_proxy_graphics",
|
||||
format!("{} bits", data.graphics.bit_count),
|
||||
),
|
||||
ro_prop(
|
||||
"Payload",
|
||||
ro_prop(t!("Payload").as_ref(),
|
||||
"ext_proxy_payload",
|
||||
format!("{} bits", data.payload.bit_count),
|
||||
),
|
||||
ro_prop(
|
||||
"Text Payload",
|
||||
ro_prop(t!("Text Payload").as_ref(),
|
||||
"ext_proxy_text_payload",
|
||||
format!("{} bits", data.text_payload.bit_count),
|
||||
),
|
||||
ro_prop(
|
||||
"Object References",
|
||||
ro_prop(t!("Object References").as_ref(),
|
||||
"ext_proxy_references",
|
||||
reference_properties(&data.object_ids),
|
||||
),
|
||||
],
|
||||
}],
|
||||
ExtendedEntityData::OleFrame(data) => vec![PropSection {
|
||||
title: "OLE Frame".into(),
|
||||
title: t!("OLE Frame").into_owned(),
|
||||
props: vec![
|
||||
ro_prop("Flag", "ext_ole_flag", data.flag.to_string()),
|
||||
ro_prop("Mode", "ext_ole_mode", data.mode.to_string()),
|
||||
ro_prop(
|
||||
"Storage Size",
|
||||
ro_prop(t!("Flag").as_ref(), "ext_ole_flag", data.flag.to_string()),
|
||||
ro_prop(t!("Mode").as_ref(), "ext_ole_mode", data.mode.to_string()),
|
||||
ro_prop(t!("Storage Size").as_ref(),
|
||||
"ext_ole_size",
|
||||
format!("{} bytes", data.storage.encoded_len()),
|
||||
),
|
||||
],
|
||||
}],
|
||||
ExtendedEntityData::LayoutPrintConfig(data) => vec![PropSection {
|
||||
title: "Layout Print Configuration".into(),
|
||||
title: t!("Layout Print Configuration").into_owned(),
|
||||
props: vec![
|
||||
ro_prop(
|
||||
"Class Version",
|
||||
ro_prop(t!("Class Version").as_ref(),
|
||||
"ext_print_version",
|
||||
data.class_version.to_string(),
|
||||
),
|
||||
ro_prop("Flag", "ext_print_flag", data.flag.to_string()),
|
||||
ro_prop(t!("Flag").as_ref(), "ext_print_flag", data.flag.to_string()),
|
||||
],
|
||||
}],
|
||||
ExtendedEntityData::Format(data) => vec![PropSection {
|
||||
title: "Format".into(),
|
||||
title: t!("Format").into_owned(),
|
||||
props: vec![
|
||||
ro_prop(
|
||||
"DWG Payload",
|
||||
ro_prop(t!("DWG Payload").as_ref(),
|
||||
"ext_format_dwg",
|
||||
format!(
|
||||
"{} bytes / {} handle bits",
|
||||
|
|
@ -1023,54 +966,47 @@ fn properties(entity: &ExtendedEntity) -> Vec<PropSection> {
|
|||
data.raw_dwg_handle_bits
|
||||
),
|
||||
),
|
||||
ro_prop(
|
||||
"DWG Version",
|
||||
ro_prop(t!("DWG Version").as_ref(),
|
||||
"ext_format_version",
|
||||
format!("{:?}", data.raw_dwg_version),
|
||||
),
|
||||
ro_prop(
|
||||
"DXF Codes",
|
||||
ro_prop(t!("DXF Codes").as_ref(),
|
||||
"ext_format_dxf",
|
||||
data.raw_dxf_codes.as_ref().map_or(0, Vec::len).to_string(),
|
||||
),
|
||||
],
|
||||
}],
|
||||
ExtendedEntityData::Legacy(data) => vec![PropSection {
|
||||
title: "Legacy Entity".into(),
|
||||
props: vec![ro_prop("Data", "ext_legacy_data", format!("{data:#?}"))],
|
||||
title: t!("Legacy Entity").into_owned(),
|
||||
props: vec![ro_prop(t!("Data").as_ref(), "ext_legacy_data", format!("{data:#?}"))],
|
||||
}],
|
||||
ExtendedEntityData::DynamicBlock(data) => vec![PropSection {
|
||||
title: "Dynamic Block Entity".into(),
|
||||
title: t!("Dynamic Block Entity").into_owned(),
|
||||
props: vec![
|
||||
ro_prop(
|
||||
"Class",
|
||||
ro_prop(t!("Class").as_ref(),
|
||||
"ext_dynamic_class",
|
||||
data.entity_dxf_name().unwrap_or("Helper"),
|
||||
),
|
||||
ro_prop("Decoded Data", "ext_dynamic_data", format!("{data:#?}")),
|
||||
ro_prop(t!("Decoded Data").as_ref(), "ext_dynamic_data", format!("{data:#?}")),
|
||||
],
|
||||
}],
|
||||
ExtendedEntityData::RegisteredClass(data) => vec![PropSection {
|
||||
title: "Registered Class Entity".into(),
|
||||
title: t!("Registered Class Entity").into_owned(),
|
||||
props: vec![
|
||||
ro_prop("DXF Name", "ext_registered_dxf", data.dxf_name.clone()),
|
||||
ro_prop(
|
||||
"C++ Class",
|
||||
ro_prop(t!("DXF Name").as_ref(), "ext_registered_dxf", data.dxf_name.clone()),
|
||||
ro_prop(t!("C++ Class").as_ref(),
|
||||
"ext_registered_cpp",
|
||||
data.cpp_class_name.clone(),
|
||||
),
|
||||
ro_prop(
|
||||
"Properties",
|
||||
ro_prop(t!("Properties").as_ref(),
|
||||
"ext_registered_properties",
|
||||
semantic_properties(&data.properties),
|
||||
),
|
||||
ro_prop(
|
||||
"Payload",
|
||||
ro_prop(t!("Payload").as_ref(),
|
||||
"ext_registered_payload",
|
||||
format!("{} bits", data.payload.bit_count),
|
||||
),
|
||||
ro_prop(
|
||||
"Object References",
|
||||
ro_prop(t!("Object References").as_ref(),
|
||||
"ext_registered_references",
|
||||
reference_properties(&data.object_ids),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use acadrust::entities::{BoundaryEdge, Hatch};
|
||||
use glam::Vec3;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{center_grip, circle_grip, edit_angle_prop as edit_angle, edit_prop as edit, parse_f64, ro_prop as ro};
|
||||
|
|
@ -264,10 +265,10 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
let centered = if g.shift.abs() < 1e-9 { "Yes" } else { "No" };
|
||||
let mut sections = vec![
|
||||
PropSection {
|
||||
title: "Pattern".into(),
|
||||
title: t!("Pattern").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Type".into(),
|
||||
label: t!("Type").into_owned(),
|
||||
field: "fill_type",
|
||||
value: PropValue::Choice {
|
||||
selected: grad_type.to_string(),
|
||||
|
|
@ -279,7 +280,7 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
crate::scene::model::hatch_model::GradientKind::from_name(&g.name);
|
||||
let _ = invert;
|
||||
Property {
|
||||
label: "Gradient type".into(),
|
||||
label: t!("Gradient type").into_owned(),
|
||||
field: "gradient_type",
|
||||
value: PropValue::Choice {
|
||||
selected: kind.label().to_string(),
|
||||
|
|
@ -291,7 +292,7 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
}
|
||||
},
|
||||
Property {
|
||||
label: "Invert".into(),
|
||||
label: t!("Invert").into_owned(),
|
||||
field: "gradient_invert",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "gradient_invert",
|
||||
|
|
@ -302,39 +303,38 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Color 1".into(),
|
||||
label: t!("Color 1").into_owned(),
|
||||
field: "gradient_color_1",
|
||||
value: PropValue::ColorChoice(grad_c1),
|
||||
},
|
||||
Property {
|
||||
label: "Color 2".into(),
|
||||
label: t!("Color 2").into_owned(),
|
||||
field: "gradient_color_2",
|
||||
value: PropValue::ColorChoice(grad_c2),
|
||||
},
|
||||
edit_angle("Angle", "pattern_angle", g.angle.to_degrees()),
|
||||
ro("Centered", "gradient_centered", centered),
|
||||
edit_angle(t!("Angle").as_ref(), "pattern_angle", g.angle.to_degrees()),
|
||||
ro(t!("Centered").as_ref(), "gradient_centered", centered),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Elevation", "elevation", h.elevation),
|
||||
ro("Area", "area", format!("{:.4}", area)),
|
||||
ro("Cumulative area", "cumulative_area", format!("{:.4}", area)),
|
||||
edit(t!("Elevation").as_ref(), "elevation", h.elevation),
|
||||
ro(t!("Area").as_ref(), "area", format!("{:.4}", area)),
|
||||
ro(t!("Cumulative area").as_ref(), "cumulative_area", format!("{:.4}", area)),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
ro(
|
||||
"Associative",
|
||||
ro(t!("Associative").as_ref(),
|
||||
"associative",
|
||||
if h.is_associative { "Yes" } else { "No" },
|
||||
),
|
||||
ro("Annotative", "annotative", String::new()),
|
||||
ro("Island detection style", "style", style),
|
||||
ro(t!("Annotative").as_ref(), "annotative", String::new()),
|
||||
ro(t!("Island detection style").as_ref(), "style", style),
|
||||
Property {
|
||||
label: "Background".into(),
|
||||
label: t!("Background").into_owned(),
|
||||
field: "bg_enabled",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "bg_enabled",
|
||||
|
|
@ -347,7 +347,7 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
if bg_on {
|
||||
if let Some(sec) = sections.last_mut() {
|
||||
sec.props.push(Property {
|
||||
label: "Background color".into(),
|
||||
label: t!("Background color").into_owned(),
|
||||
field: "background_color",
|
||||
value: PropValue::ColorChoice(bg_col),
|
||||
});
|
||||
|
|
@ -360,7 +360,7 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
// ── Hatch (pattern / solid) ────────────────────────────────────────────
|
||||
// "Type" = pattern definition source (Predefined / User Defined / Custom).
|
||||
let type_row = Property {
|
||||
label: "Type".into(),
|
||||
label: t!("Type").into_owned(),
|
||||
field: "pattern_type_label",
|
||||
value: PropValue::Choice {
|
||||
selected: pattern_type.to_string(),
|
||||
|
|
@ -368,12 +368,12 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
},
|
||||
};
|
||||
let pattern_name_row = Property {
|
||||
label: "Pattern name".into(),
|
||||
label: t!("Pattern name").into_owned(),
|
||||
field: "pattern_name",
|
||||
value: PropValue::HatchPatternChoice(h.pattern.name.clone()),
|
||||
};
|
||||
let associative_row = Property {
|
||||
label: "Associative".into(),
|
||||
label: t!("Associative").into_owned(),
|
||||
field: "associative",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "associative",
|
||||
|
|
@ -381,7 +381,7 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
},
|
||||
};
|
||||
let double_row = Property {
|
||||
label: "Double".into(),
|
||||
label: t!("Double").into_owned(),
|
||||
field: "double",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "double",
|
||||
|
|
@ -389,15 +389,14 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
},
|
||||
};
|
||||
let island_row = Property {
|
||||
label: "Island detection style".into(),
|
||||
label: t!("Island detection style").into_owned(),
|
||||
field: "style",
|
||||
value: PropValue::Choice {
|
||||
selected: style.to_string(),
|
||||
options: vec!["Normal".into(), "Outer".into(), "Ignore".into()],
|
||||
},
|
||||
};
|
||||
let spacing_row = edit(
|
||||
"Spacing",
|
||||
let spacing_row = edit(t!("Spacing").as_ref(),
|
||||
"spacing",
|
||||
h.pattern
|
||||
.lines
|
||||
|
|
@ -415,22 +414,22 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
|
||||
let mut sections = vec![
|
||||
PropSection {
|
||||
title: "Pattern".into(),
|
||||
title: t!("Pattern").into_owned(),
|
||||
props: vec![
|
||||
type_row,
|
||||
pattern_name_row,
|
||||
ro("Annotative", "annotative", String::new()),
|
||||
edit_angle("Angle", "pattern_angle", h.pattern_angle.to_degrees()),
|
||||
edit("Scale", "pattern_scale", h.pattern_scale),
|
||||
edit("Origin X", "origin_x", origin_x),
|
||||
edit("Origin Y", "origin_y", origin_y),
|
||||
ro(t!("Annotative").as_ref(), "annotative", String::new()),
|
||||
edit_angle(t!("Angle").as_ref(), "pattern_angle", h.pattern_angle.to_degrees()),
|
||||
edit(t!("Scale").as_ref(), "pattern_scale", h.pattern_scale),
|
||||
edit(t!("Origin X").as_ref(), "origin_x", origin_x),
|
||||
edit(t!("Origin Y").as_ref(), "origin_y", origin_y),
|
||||
spacing_row,
|
||||
ro("ISO pen width", "iso_pen_width", String::new()),
|
||||
ro(t!("ISO pen width").as_ref(), "iso_pen_width", String::new()),
|
||||
double_row,
|
||||
associative_row,
|
||||
island_row,
|
||||
Property {
|
||||
label: "Background".into(),
|
||||
label: t!("Background").into_owned(),
|
||||
field: "bg_enabled",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "bg_enabled",
|
||||
|
|
@ -440,18 +439,18 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Elevation", "elevation", h.elevation),
|
||||
ro("Area", "area", format!("{:.4}", area)),
|
||||
ro("Cumulative area", "cumulative_area", format!("{:.4}", area)),
|
||||
edit(t!("Elevation").as_ref(), "elevation", h.elevation),
|
||||
ro(t!("Area").as_ref(), "area", format!("{:.4}", area)),
|
||||
ro(t!("Cumulative area").as_ref(), "cumulative_area", format!("{:.4}", area)),
|
||||
],
|
||||
},
|
||||
];
|
||||
if bg_on {
|
||||
if let Some(sec) = sections.first_mut() {
|
||||
sec.props.push(Property {
|
||||
label: "Background color".into(),
|
||||
label: t!("Background color").into_owned(),
|
||||
field: "background_color",
|
||||
value: PropValue::ColorChoice(bg_col),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
// as the Geometry property group.
|
||||
|
||||
use acadrust::entities::{Helix, HelixConstraint};
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::ro_prop as ro;
|
||||
|
|
@ -70,20 +71,20 @@ fn properties(helix: &Helix) -> Vec<PropSection> {
|
|||
};
|
||||
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
ro("Base point X", "base_x", format!("{:.4}", bp.x)),
|
||||
ro("Base point Y", "base_y", format!("{:.4}", bp.y)),
|
||||
ro("Base point Z", "base_z", format!("{:.4}", bp.z)),
|
||||
ro("Number of turns", "num_turns", format!("{turns:.4}")),
|
||||
ro("Turn height", "turn_height", format!("{turn_height:.4}")),
|
||||
ro("Turns", "turns", format!("{turns:.4}")),
|
||||
ro("Height", "height", format!("{height:.4}")),
|
||||
ro("Base radius", "base_radius", format!("{base_radius:.4}")),
|
||||
ro("Top radius", "top_radius", format!("{top_radius:.4}")),
|
||||
ro("Turn slope", "turn_slope", format!("{turn_slope:.4}")),
|
||||
ro("Twist", "twist", twist),
|
||||
ro("Constrain", "constrain", constrain),
|
||||
ro(t!("Base point X").as_ref(), "base_x", format!("{:.4}", bp.x)),
|
||||
ro(t!("Base point Y").as_ref(), "base_y", format!("{:.4}", bp.y)),
|
||||
ro(t!("Base point Z").as_ref(), "base_z", format!("{:.4}", bp.z)),
|
||||
ro(t!("Number of turns").as_ref(), "num_turns", format!("{turns:.4}")),
|
||||
ro(t!("Turn height").as_ref(), "turn_height", format!("{turn_height:.4}")),
|
||||
ro(t!("Turns").as_ref(), "turns", format!("{turns:.4}")),
|
||||
ro(t!("Height").as_ref(), "height", format!("{height:.4}")),
|
||||
ro(t!("Base radius").as_ref(), "base_radius", format!("{base_radius:.4}")),
|
||||
ro(t!("Top radius").as_ref(), "top_radius", format!("{top_radius:.4}")),
|
||||
ro(t!("Turn slope").as_ref(), "turn_slope", format!("{turn_slope:.4}")),
|
||||
ro(t!("Twist").as_ref(), "twist", twist),
|
||||
ro(t!("Constrain").as_ref(), "constrain", constrain),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use crate::entities::traits::TruckConvertible;
|
|||
use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject};
|
||||
use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property};
|
||||
use crate::scene::model::wire_model::TangentGeom;
|
||||
use crate::t;
|
||||
|
||||
// ── TruckConvertible (used for snap/grip key-vertices) ─────────────────────
|
||||
|
||||
|
|
@ -219,27 +220,27 @@ fn properties(leader: &Leader) -> Vec<PropSection> {
|
|||
|
||||
// Geometry sits right after General — a leader owns editable path vertices,
|
||||
// navigated one at a time by the Current Vertex spinner.
|
||||
let mut geometry = vec![stepper("Current Vertex", "current_vertex", vertex_label)];
|
||||
let mut geometry = vec![stepper(t!("Current Vertex").as_ref(), "current_vertex", vertex_label)];
|
||||
if let Some(v) = leader.vertices.get(vi) {
|
||||
geometry.push(edit("Vertex X", "vertex_x", v.x));
|
||||
geometry.push(edit("Vertex Y", "vertex_y", v.y));
|
||||
geometry.push(edit("Vertex Z", "vertex_z", v.z));
|
||||
geometry.push(edit(t!("Vertex X").as_ref(), "vertex_x", v.x));
|
||||
geometry.push(edit(t!("Vertex Y").as_ref(), "vertex_y", v.y));
|
||||
geometry.push(edit(t!("Vertex Z").as_ref(), "vertex_z", v.z));
|
||||
} else {
|
||||
geometry.push(ro("Vertex X", "vertex_x", String::new()));
|
||||
geometry.push(ro("Vertex Y", "vertex_y", String::new()));
|
||||
geometry.push(ro("Vertex Z", "vertex_z", String::new()));
|
||||
geometry.push(ro(t!("Vertex X").as_ref(), "vertex_x", String::new()));
|
||||
geometry.push(ro(t!("Vertex Y").as_ref(), "vertex_y", String::new()));
|
||||
geometry.push(ro(t!("Vertex Z").as_ref(), "vertex_z", String::new()));
|
||||
}
|
||||
|
||||
// Misc: Dim style (upgraded to a dropdown by the panel builder), the
|
||||
// combined path/arrow Type, and annotative state (from the dim style).
|
||||
let misc = vec![
|
||||
Property {
|
||||
label: "Dim style".into(),
|
||||
label: t!("Dim style").into_owned(),
|
||||
field: "dimension_style",
|
||||
value: PropValue::EditText(leader.dimension_style.clone()),
|
||||
},
|
||||
choice_prop(
|
||||
"Type",
|
||||
t!("Type").as_ref(),
|
||||
"leader_type",
|
||||
leader_type_str(&leader.path_type, leader.arrow_enabled),
|
||||
&[
|
||||
|
|
@ -249,42 +250,42 @@ fn properties(leader: &Leader) -> Vec<PropSection> {
|
|||
"Spline without arrow",
|
||||
],
|
||||
),
|
||||
ro("Annotative", "annotative", "No"),
|
||||
ro(t!("Annotative").as_ref(), "annotative", "No"),
|
||||
];
|
||||
|
||||
// Lines & Arrows / Text / Fit are dimension-style-derived; the panel builder
|
||||
// resolves leader.dimension_style and fills these values from the DimStyle.
|
||||
let lines_arrows = vec![
|
||||
ro("Arrow", "arrow_block", "Closed filled"),
|
||||
ro("Arrow size", "arrow_size", String::new()),
|
||||
ro("Dim line lineweight", "dim_line_lw", "ByLayer"),
|
||||
ro("Dim line color", "dim_line_color", "ByLayer"),
|
||||
ro(t!("Arrow").as_ref(), "arrow_block", "Closed filled"),
|
||||
ro(t!("Arrow size").as_ref(), "arrow_size", String::new()),
|
||||
ro(t!("Dim line lineweight").as_ref(), "dim_line_lw", "ByLayer"),
|
||||
ro(t!("Dim line color").as_ref(), "dim_line_color", "ByLayer"),
|
||||
];
|
||||
let text = vec![
|
||||
ro("Text offset", "text_offset", String::new()),
|
||||
ro("Text pos vert", "text_pos_vert", String::new()),
|
||||
ro(t!("Text offset").as_ref(), "text_offset", String::new()),
|
||||
ro(t!("Text pos vert").as_ref(), "text_pos_vert", String::new()),
|
||||
];
|
||||
let fit = vec![ro("Dim scale overall", "dim_scale_overall", String::new())];
|
||||
let fit = vec![ro(t!("Dim scale overall").as_ref(), "dim_scale_overall", String::new())];
|
||||
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: geometry,
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: misc,
|
||||
},
|
||||
PropSection {
|
||||
title: "Lines & Arrows".into(),
|
||||
title: t!("Lines & Arrows").into_owned(),
|
||||
props: lines_arrows,
|
||||
},
|
||||
PropSection {
|
||||
title: "Text".into(),
|
||||
title: t!("Text").into_owned(),
|
||||
props: text,
|
||||
},
|
||||
PropSection {
|
||||
title: "Fit".into(),
|
||||
title: t!("Fit").into_owned(),
|
||||
props: fit,
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
use acadrust::entities::Light;
|
||||
use acadrust::EntityType;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{
|
||||
|
|
@ -262,27 +263,27 @@ impl PropertyEditable for Light {
|
|||
_ => "Point",
|
||||
};
|
||||
let mut props = vec![
|
||||
ro_prop("Name", "li_name", self.name.clone()),
|
||||
ro_prop("Type", "li_type", kind),
|
||||
edit("Position X", "li_px", self.position.x),
|
||||
edit("Position Y", "li_py", self.position.y),
|
||||
edit("Position Z", "li_pz", self.position.z),
|
||||
ro_prop(t!("Name").as_ref(), "li_name", self.name.clone()),
|
||||
ro_prop(t!("Type").as_ref(), "li_type", kind),
|
||||
edit(t!("Position X").as_ref(), "li_px", self.position.x),
|
||||
edit(t!("Position Y").as_ref(), "li_py", self.position.y),
|
||||
edit(t!("Position Z").as_ref(), "li_pz", self.position.z),
|
||||
];
|
||||
if self.light_type != 2 {
|
||||
props.push(edit("Target X", "li_tx", self.target.x));
|
||||
props.push(edit("Target Y", "li_ty", self.target.y));
|
||||
props.push(edit("Target Z", "li_tz", self.target.z));
|
||||
props.push(edit(t!("Target X").as_ref(), "li_tx", self.target.x));
|
||||
props.push(edit(t!("Target Y").as_ref(), "li_ty", self.target.y));
|
||||
props.push(edit(t!("Target Z").as_ref(), "li_tz", self.target.z));
|
||||
}
|
||||
let mut sections = vec![
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props,
|
||||
},
|
||||
PropSection {
|
||||
title: "Light".into(),
|
||||
title: t!("Light").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "On".into(),
|
||||
label: t!("On").into_owned(),
|
||||
field: "li_status",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "li_status",
|
||||
|
|
@ -290,17 +291,17 @@ impl PropertyEditable for Light {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Plot Glyph".into(),
|
||||
label: t!("Plot Glyph").into_owned(),
|
||||
field: "li_plot_glyph",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "li_plot_glyph",
|
||||
value: self.plot_glyph,
|
||||
},
|
||||
},
|
||||
ro_prop("Color", "li_color", format!("{:?}", self.light_color)),
|
||||
edit("Intensity", "li_intensity", self.intensity),
|
||||
ro_prop(t!("Color").as_ref(), "li_color", format!("{:?}", self.light_color)),
|
||||
edit(t!("Intensity").as_ref(), "li_intensity", self.intensity),
|
||||
Property {
|
||||
label: "Attenuation".into(),
|
||||
label: t!("Attenuation").into_owned(),
|
||||
field: "li_attenuation",
|
||||
value: PropValue::Choice {
|
||||
selected: match self.attenuation_type {
|
||||
|
|
@ -317,42 +318,39 @@ impl PropertyEditable for Light {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Use Limits".into(),
|
||||
label: t!("Use Limits").into_owned(),
|
||||
field: "li_use_limits",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "li_use_limits",
|
||||
value: self.use_attenuation_limits,
|
||||
},
|
||||
},
|
||||
edit("Start Limit", "li_start", self.attenuation_start_limit),
|
||||
edit("End Limit", "li_end", self.attenuation_end_limit),
|
||||
edit_angle_prop(
|
||||
"Hotspot Angle",
|
||||
edit(t!("Start Limit").as_ref(), "li_start", self.attenuation_start_limit),
|
||||
edit(t!("End Limit").as_ref(), "li_end", self.attenuation_end_limit),
|
||||
edit_angle_prop(t!("Hotspot Angle").as_ref(),
|
||||
"li_hotspot",
|
||||
self.hotspot_angle.to_degrees(),
|
||||
),
|
||||
edit_angle_prop(
|
||||
"Falloff Angle",
|
||||
edit_angle_prop(t!("Falloff Angle").as_ref(),
|
||||
"li_falloff",
|
||||
self.falloff_angle.to_degrees(),
|
||||
),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Shadows".into(),
|
||||
title: t!("Shadows").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Cast Shadows".into(),
|
||||
label: t!("Cast Shadows").into_owned(),
|
||||
field: "li_shadows",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "li_shadows",
|
||||
value: self.cast_shadows,
|
||||
},
|
||||
},
|
||||
ro_prop("Type", "li_shadow_type", self.shadow_type.to_string()),
|
||||
ro_prop("Map Size", "li_shadow_size", self.shadow_map_size.to_string()),
|
||||
ro_prop(
|
||||
"Softness",
|
||||
ro_prop(t!("Type").as_ref(), "li_shadow_type", self.shadow_type.to_string()),
|
||||
ro_prop(t!("Map Size").as_ref(), "li_shadow_size", self.shadow_map_size.to_string()),
|
||||
ro_prop(t!("Softness").as_ref(),
|
||||
"li_shadow_softness",
|
||||
self.shadow_map_softness.to_string(),
|
||||
),
|
||||
|
|
@ -361,36 +359,30 @@ impl PropertyEditable for Light {
|
|||
];
|
||||
if let Some(photo) = &self.photometric_data {
|
||||
sections.push(PropSection {
|
||||
title: "Photometric".into(),
|
||||
title: t!("Photometric").into_owned(),
|
||||
props: vec![
|
||||
ro_prop("Web File", "li_web_file", photo.web_file.clone()),
|
||||
ro_prop(
|
||||
"Physical Method",
|
||||
ro_prop(t!("Web File").as_ref(), "li_web_file", photo.web_file.clone()),
|
||||
ro_prop(t!("Physical Method").as_ref(),
|
||||
"li_physical_method",
|
||||
photo.physical_intensity_method.to_string(),
|
||||
),
|
||||
edit(
|
||||
"Physical Intensity",
|
||||
edit(t!("Physical Intensity").as_ref(),
|
||||
"li_physical_intensity",
|
||||
photo.physical_intensity,
|
||||
),
|
||||
edit(
|
||||
"Illuminance Distance",
|
||||
edit(t!("Illuminance Distance").as_ref(),
|
||||
"li_illuminance_distance",
|
||||
photo.illuminance_distance,
|
||||
),
|
||||
edit(
|
||||
"Color Temperature",
|
||||
edit(t!("Color Temperature").as_ref(),
|
||||
"li_color_temperature",
|
||||
photo.lamp_color_temperature,
|
||||
),
|
||||
ro_prop(
|
||||
"Lamp Preset",
|
||||
ro_prop(t!("Lamp Preset").as_ref(),
|
||||
"li_lamp_preset",
|
||||
photo.lamp_color_preset.to_string(),
|
||||
),
|
||||
ro_prop(
|
||||
"Shape",
|
||||
ro_prop(t!("Shape").as_ref(),
|
||||
"li_shape",
|
||||
format!(
|
||||
"{} · {:.6} × {:.6} · radius {:.6}",
|
||||
|
|
@ -400,8 +392,7 @@ impl PropertyEditable for Light {
|
|||
photo.extended_light_radius
|
||||
),
|
||||
),
|
||||
ro_prop(
|
||||
"Web",
|
||||
ro_prop(t!("Web").as_ref(),
|
||||
"li_web",
|
||||
format!(
|
||||
"type {}; symmetry {}; flux {:.6}; angles {:?}; rotation {:.6},{:.6},{:.6}",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use acadrust::{entities::Line, Entity};
|
||||
use crate::t;
|
||||
use truck_modeling::{builder, Point3};
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
|
|
@ -81,19 +82,19 @@ fn properties(line: &Line) -> Vec<PropSection> {
|
|||
let dz = line.end.z - line.start.z;
|
||||
let angle = dy.atan2(dx).to_degrees().rem_euclid(360.0);
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Start X", "start_x", line.start.x),
|
||||
edit("Start Y", "start_y", line.start.y),
|
||||
edit("Start Z", "start_z", line.start.z),
|
||||
edit("End X", "end_x", line.end.x),
|
||||
edit("End Y", "end_y", line.end.y),
|
||||
edit("End Z", "end_z", line.end.z),
|
||||
ro("Delta X", "delta_x", format!("{dx:.4}")),
|
||||
ro("Delta Y", "delta_y", format!("{dy:.4}")),
|
||||
ro("Delta Z", "delta_z", format!("{dz:.4}")),
|
||||
ro("Length", "length", format!("{:.4}", line.length())),
|
||||
ro("Angle", "angle", format!("{angle:.2}")),
|
||||
edit(t!("Start X").as_ref(), "start_x", line.start.x),
|
||||
edit(t!("Start Y").as_ref(), "start_y", line.start.y),
|
||||
edit(t!("Start Z").as_ref(), "start_z", line.start.z),
|
||||
edit(t!("End X").as_ref(), "end_x", line.end.x),
|
||||
edit(t!("End Y").as_ref(), "end_y", line.end.y),
|
||||
edit(t!("End Z").as_ref(), "end_z", line.end.z),
|
||||
ro(t!("Delta X").as_ref(), "delta_x", format!("{dx:.4}")),
|
||||
ro(t!("Delta Y").as_ref(), "delta_y", format!("{dy:.4}")),
|
||||
ro(t!("Delta Z").as_ref(), "delta_z", format!("{dz:.4}")),
|
||||
ro(t!("Length").as_ref(), "length", format!("{:.4}", line.length())),
|
||||
ro(t!("Angle").as_ref(), "angle", format!("{angle:.2}")),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use acadrust::entities::{LwPolyline, LwVertex};
|
||||
use crate::t;
|
||||
use truck_modeling::{builder, Edge, Point3, Wire};
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
|
|
@ -616,24 +617,24 @@ fn properties(pline: &LwPolyline) -> Vec<PropSection> {
|
|||
};
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
stepper("Current Vertex", "current_vertex", vertex_label),
|
||||
edit("Vertex X", "vertex_x", vx),
|
||||
edit("Vertex Y", "vertex_y", vy),
|
||||
edit("Start segment width", "start_width", start_w),
|
||||
edit("End segment width", "end_width", end_w),
|
||||
edit("Global width", "global_width", pline.constant_width),
|
||||
edit("Elevation", "elevation", pline.elevation),
|
||||
ro("Area", "area", format!("{:.4}", mp.area)),
|
||||
ro("Length", "length", format!("{:.4}", mp.perimeter)),
|
||||
stepper(t!("Current Vertex").as_ref(), "current_vertex", vertex_label),
|
||||
edit(t!("Vertex X").as_ref(), "vertex_x", vx),
|
||||
edit(t!("Vertex Y").as_ref(), "vertex_y", vy),
|
||||
edit(t!("Start segment width").as_ref(), "start_width", start_w),
|
||||
edit(t!("End segment width").as_ref(), "end_width", end_w),
|
||||
edit(t!("Global width").as_ref(), "global_width", pline.constant_width),
|
||||
edit(t!("Elevation").as_ref(), "elevation", pline.elevation),
|
||||
ro(t!("Area").as_ref(), "area", format!("{:.4}", mp.area)),
|
||||
ro(t!("Length").as_ref(), "length", format!("{:.4}", mp.perimeter)),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Closed".into(),
|
||||
label: t!("Closed").into_owned(),
|
||||
field: "closed",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "closed",
|
||||
|
|
@ -641,7 +642,7 @@ fn properties(pline: &LwPolyline) -> Vec<PropSection> {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Linetype generation".into(),
|
||||
label: t!("Linetype generation").into_owned(),
|
||||
field: "plinegen",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "plinegen",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use acadrust::entities::{mesh::Mesh, polygon_mesh::PolygonMesh, Face3D, PolyfaceMesh};
|
||||
use glam::Vec3;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{parse_f64, ro_prop as ro, square_grip};
|
||||
|
|
@ -249,25 +250,25 @@ impl PropertyEditable for Face3D {
|
|||
let inv = self.invisible_edges;
|
||||
let edge = |hidden: bool| if hidden { "Invisible" } else { "Visible" };
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
ro("Current vertex", "f3_current", String::new()),
|
||||
edit("Vertex 1 X", "f3_p1x", self.first_corner.x),
|
||||
edit("Vertex 1 Y", "f3_p1y", self.first_corner.y),
|
||||
edit("Vertex 1 Z", "f3_p1z", self.first_corner.z),
|
||||
edit("Vertex 2 X", "f3_p2x", self.second_corner.x),
|
||||
edit("Vertex 2 Y", "f3_p2y", self.second_corner.y),
|
||||
edit("Vertex 2 Z", "f3_p2z", self.second_corner.z),
|
||||
edit("Vertex 3 X", "f3_p3x", self.third_corner.x),
|
||||
edit("Vertex 3 Y", "f3_p3y", self.third_corner.y),
|
||||
edit("Vertex 3 Z", "f3_p3z", self.third_corner.z),
|
||||
edit("Vertex 4 X", "f3_p4x", self.fourth_corner.x),
|
||||
edit("Vertex 4 Y", "f3_p4y", self.fourth_corner.y),
|
||||
edit("Vertex 4 Z", "f3_p4z", self.fourth_corner.z),
|
||||
ro("Edge 1", "f3_edge1", edge(inv.is_first_invisible())),
|
||||
ro("Edge 2", "f3_edge2", edge(inv.is_second_invisible())),
|
||||
ro("Edge 3", "f3_edge3", edge(inv.is_third_invisible())),
|
||||
ro("Edge 4", "f3_edge4", edge(inv.is_fourth_invisible())),
|
||||
ro(t!("Current vertex").as_ref(), "f3_current", String::new()),
|
||||
edit(t!("Vertex 1 X").as_ref(), "f3_p1x", self.first_corner.x),
|
||||
edit(t!("Vertex 1 Y").as_ref(), "f3_p1y", self.first_corner.y),
|
||||
edit(t!("Vertex 1 Z").as_ref(), "f3_p1z", self.first_corner.z),
|
||||
edit(t!("Vertex 2 X").as_ref(), "f3_p2x", self.second_corner.x),
|
||||
edit(t!("Vertex 2 Y").as_ref(), "f3_p2y", self.second_corner.y),
|
||||
edit(t!("Vertex 2 Z").as_ref(), "f3_p2z", self.second_corner.z),
|
||||
edit(t!("Vertex 3 X").as_ref(), "f3_p3x", self.third_corner.x),
|
||||
edit(t!("Vertex 3 Y").as_ref(), "f3_p3y", self.third_corner.y),
|
||||
edit(t!("Vertex 3 Z").as_ref(), "f3_p3z", self.third_corner.z),
|
||||
edit(t!("Vertex 4 X").as_ref(), "f3_p4x", self.fourth_corner.x),
|
||||
edit(t!("Vertex 4 Y").as_ref(), "f3_p4y", self.fourth_corner.y),
|
||||
edit(t!("Vertex 4 Z").as_ref(), "f3_p4z", self.fourth_corner.z),
|
||||
ro(t!("Edge 1").as_ref(), "f3_edge1", edge(inv.is_first_invisible())),
|
||||
ro(t!("Edge 2").as_ref(), "f3_edge2", edge(inv.is_second_invisible())),
|
||||
ro(t!("Edge 3").as_ref(), "f3_edge3", edge(inv.is_third_invisible())),
|
||||
ro(t!("Edge 4").as_ref(), "f3_edge4", edge(inv.is_fourth_invisible())),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
|
@ -380,37 +381,34 @@ impl PropertyEditable for PolygonMesh {
|
|||
let face_count = cells_m * cells_n;
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
ro("Vertex", "pm_vertex", String::new()),
|
||||
ro(
|
||||
"Vertex X",
|
||||
ro(t!("Vertex").as_ref(), "pm_vertex", String::new()),
|
||||
ro(t!("Vertex X").as_ref(),
|
||||
"pm_vx",
|
||||
first.map(|v| format!("{:.4}", v.location.x)).unwrap_or_default(),
|
||||
),
|
||||
ro(
|
||||
"Vertex Y",
|
||||
ro(t!("Vertex Y").as_ref(),
|
||||
"pm_vy",
|
||||
first.map(|v| format!("{:.4}", v.location.y)).unwrap_or_default(),
|
||||
),
|
||||
ro(
|
||||
"Vertex Z",
|
||||
ro(t!("Vertex Z").as_ref(),
|
||||
"pm_vz",
|
||||
first.map(|v| format!("{:.4}", v.location.z)).unwrap_or_default(),
|
||||
),
|
||||
ro("M vertex count", "pm_m", self.m_vertex_count.to_string()),
|
||||
ro("N vertex count", "pm_n", self.n_vertex_count.to_string()),
|
||||
ro("M closed", "pm_closed_m", yesno(self.is_closed_m())),
|
||||
ro("N closed", "pm_closed_n", yesno(self.is_closed_n())),
|
||||
ro("M density", "pm_smooth_m", self.m_smooth_density.to_string()),
|
||||
ro("N density", "pm_smooth_n", self.n_smooth_density.to_string()),
|
||||
ro("Vertex count", "pm_v", self.vertices.len().to_string()),
|
||||
ro("Face count", "pm_faces", face_count.to_string()),
|
||||
ro(t!("M vertex count").as_ref(), "pm_m", self.m_vertex_count.to_string()),
|
||||
ro(t!("N vertex count").as_ref(), "pm_n", self.n_vertex_count.to_string()),
|
||||
ro(t!("M closed").as_ref(), "pm_closed_m", yesno(self.is_closed_m())),
|
||||
ro(t!("N closed").as_ref(), "pm_closed_n", yesno(self.is_closed_n())),
|
||||
ro(t!("M density").as_ref(), "pm_smooth_m", self.m_smooth_density.to_string()),
|
||||
ro(t!("N density").as_ref(), "pm_smooth_n", self.n_smooth_density.to_string()),
|
||||
ro(t!("Vertex count").as_ref(), "pm_v", self.vertices.len().to_string()),
|
||||
ro(t!("Face count").as_ref(), "pm_faces", face_count.to_string()),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
props: vec![ro("Fit/smooth", "pm_smooth", smooth)],
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![ro(t!("Fit/smooth").as_ref(), "pm_smooth", smooth)],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
@ -495,39 +493,36 @@ impl PropertyEditable for PolyfaceMesh {
|
|||
let first = self.vertices.first();
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
ro("Vertex", "pfm_vertex", String::new()),
|
||||
ro(
|
||||
"Vertex X",
|
||||
ro(t!("Vertex").as_ref(), "pfm_vertex", String::new()),
|
||||
ro(t!("Vertex X").as_ref(),
|
||||
"pfm_vx",
|
||||
first.map(|v| format!("{:.4}", v.location.x)).unwrap_or_default(),
|
||||
),
|
||||
ro(
|
||||
"Vertex Y",
|
||||
ro(t!("Vertex Y").as_ref(),
|
||||
"pfm_vy",
|
||||
first.map(|v| format!("{:.4}", v.location.y)).unwrap_or_default(),
|
||||
),
|
||||
ro(
|
||||
"Vertex Z",
|
||||
ro(t!("Vertex Z").as_ref(),
|
||||
"pfm_vz",
|
||||
first.map(|v| format!("{:.4}", v.location.z)).unwrap_or_default(),
|
||||
),
|
||||
// Polyface meshes store an explicit vertex/face list rather
|
||||
// than an M×N grid, so the grid-only rows are not applicable.
|
||||
ro("M vertex count", "pfm_m", String::new()),
|
||||
ro("N vertex count", "pfm_n", String::new()),
|
||||
ro("M closed", "pfm_closed_m", String::new()),
|
||||
ro("N closed", "pfm_closed_n", String::new()),
|
||||
ro("M density", "pfm_density_m", String::new()),
|
||||
ro("N density", "pfm_density_n", String::new()),
|
||||
ro("Vertex count", "pfm_v", self.vertices.len().to_string()),
|
||||
ro("Face count", "pfm_f", self.faces.len().to_string()),
|
||||
ro(t!("M vertex count").as_ref(), "pfm_m", String::new()),
|
||||
ro(t!("N vertex count").as_ref(), "pfm_n", String::new()),
|
||||
ro(t!("M closed").as_ref(), "pfm_closed_m", String::new()),
|
||||
ro(t!("N closed").as_ref(), "pfm_closed_n", String::new()),
|
||||
ro(t!("M density").as_ref(), "pfm_density_m", String::new()),
|
||||
ro(t!("N density").as_ref(), "pfm_density_n", String::new()),
|
||||
ro(t!("Vertex count").as_ref(), "pfm_v", self.vertices.len().to_string()),
|
||||
ro(t!("Face count").as_ref(), "pfm_f", self.faces.len().to_string()),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
props: vec![ro("Fit/smooth", "pfm_smooth", smooth)],
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![ro(t!("Fit/smooth").as_ref(), "pfm_smooth", smooth)],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
@ -1149,26 +1144,25 @@ impl PropertyEditable for Mesh {
|
|||
let watertight =
|
||||
!self.faces.is_empty() && edge_use.values().all(|&c| c == 2);
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Level of Smoothness".into(),
|
||||
label: t!("Level of Smoothness").into_owned(),
|
||||
field: "msh_subdiv_edit",
|
||||
value: PropValue::EditText(self.subdivision_level.to_string()),
|
||||
},
|
||||
Property {
|
||||
label: "Blend Creases".into(),
|
||||
label: t!("Blend Creases").into_owned(),
|
||||
field: "msh_blend_crease",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "msh_blend_crease",
|
||||
value: self.blend_crease,
|
||||
},
|
||||
},
|
||||
ro("Number of Faces", "msh_f", self.faces.len().to_string()),
|
||||
ro("Number of Vertices", "msh_v", self.vertices.len().to_string()),
|
||||
ro("Number of Edges", "msh_e", self.edges.len().to_string()),
|
||||
ro(
|
||||
"Creased Edges",
|
||||
ro(t!("Number of Faces").as_ref(), "msh_f", self.faces.len().to_string()),
|
||||
ro(t!("Number of Vertices").as_ref(), "msh_v", self.vertices.len().to_string()),
|
||||
ro(t!("Number of Edges").as_ref(), "msh_e", self.edges.len().to_string()),
|
||||
ro(t!("Creased Edges").as_ref(),
|
||||
"msh_creased",
|
||||
self.edges
|
||||
.iter()
|
||||
|
|
@ -1176,14 +1170,12 @@ impl PropertyEditable for Mesh {
|
|||
.count()
|
||||
.to_string(),
|
||||
),
|
||||
ro(
|
||||
"Override Option",
|
||||
ro(t!("Override Option").as_ref(),
|
||||
"msh_override",
|
||||
self.override_option.to_string(),
|
||||
),
|
||||
ro("Number of Grips", "msh_grips", self.vertices.len().to_string()),
|
||||
ro(
|
||||
"Watertight",
|
||||
ro(t!("Number of Grips").as_ref(), "msh_grips", self.vertices.len().to_string()),
|
||||
ro(t!("Watertight").as_ref(),
|
||||
"msh_watertight",
|
||||
if watertight { "Yes" } else { "No" },
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use acadrust::entities::MLine;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip};
|
||||
|
|
@ -336,24 +337,24 @@ impl PropertyEditable for MLine {
|
|||
let cur_z = cur.map(|v| v.position.z).unwrap_or(0.0);
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
ro("Vertex", "ml_vertex", if self.vertices.is_empty() { String::new() } else { "1".to_string() }),
|
||||
edit("Vertex X", "ml_vertex_x", cur_x),
|
||||
edit("Vertex Y", "ml_vertex_y", cur_y),
|
||||
edit("Vertex Z", "ml_vertex_z", cur_z),
|
||||
ro(t!("Vertex").as_ref(), "ml_vertex", if self.vertices.is_empty() { String::new() } else { "1".to_string() }),
|
||||
edit(t!("Vertex X").as_ref(), "ml_vertex_x", cur_x),
|
||||
edit(t!("Vertex Y").as_ref(), "ml_vertex_y", cur_y),
|
||||
edit(t!("Vertex Z").as_ref(), "ml_vertex_z", cur_z),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Style".into(),
|
||||
label: t!("Style").into_owned(),
|
||||
field: "ml_style",
|
||||
value: PropValue::EditText(self.style_name.clone()),
|
||||
},
|
||||
Property {
|
||||
label: "Style justification".into(),
|
||||
label: t!("Style justification").into_owned(),
|
||||
field: "ml_justification",
|
||||
value: PropValue::Choice {
|
||||
selected: just_str.to_string(),
|
||||
|
|
@ -363,7 +364,7 @@ impl PropertyEditable for MLine {
|
|||
.collect(),
|
||||
},
|
||||
},
|
||||
edit("Style scale", "ml_scale", self.scale_factor),
|
||||
edit(t!("Style scale").as_ref(), "ml_scale", self.scale_factor),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckC
|
|||
use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject};
|
||||
use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property};
|
||||
use crate::scene::model::wire_model::SnapHint;
|
||||
use crate::t;
|
||||
|
||||
/// The entity's `column_data` as the layout's column description.
|
||||
///
|
||||
|
|
@ -254,15 +255,15 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
let height_editable = col_type == 1 || (col_type == 2 && !t.column_data.auto_height);
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Text".into(),
|
||||
title: t!("Text").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Contents".into(),
|
||||
label: t!("Contents").into_owned(),
|
||||
field: "content",
|
||||
value: PropValue::EditText(t.value.clone()),
|
||||
},
|
||||
Property {
|
||||
label: "Style".into(),
|
||||
label: t!("Style").into_owned(),
|
||||
field: "style",
|
||||
value: PropValue::Choice {
|
||||
selected: if t.style.trim().is_empty() {
|
||||
|
|
@ -274,12 +275,12 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
},
|
||||
},
|
||||
ro(
|
||||
"Annotative",
|
||||
t!("Annotative").as_ref(),
|
||||
"annotative",
|
||||
if t.is_annotative { "Yes" } else { "No" },
|
||||
),
|
||||
Property {
|
||||
label: "Justify".into(),
|
||||
label: t!("Justify").into_owned(),
|
||||
field: "justify",
|
||||
value: PropValue::Choice {
|
||||
selected: attachment_str(&t.attachment_point).to_string(),
|
||||
|
|
@ -300,7 +301,7 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Direction".into(),
|
||||
label: t!("Direction").into_owned(),
|
||||
field: "direction",
|
||||
value: PropValue::Choice {
|
||||
selected: drawing_dir_str(&t.drawing_direction).to_string(),
|
||||
|
|
@ -310,12 +311,12 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
.collect(),
|
||||
},
|
||||
},
|
||||
edit("Text height", "height", t.height),
|
||||
edit_angle("Rotation", "rotation", t.rotation.to_degrees()),
|
||||
edit("Line space factor", "line_spacing", t.line_spacing_factor),
|
||||
edit("Line space distance", "line_space_distance", line_space_distance),
|
||||
edit(t!("Text height").as_ref(), "height", t.height),
|
||||
edit_angle(t!("Rotation").as_ref(), "rotation", t.rotation.to_degrees()),
|
||||
edit(t!("Line space factor").as_ref(), "line_spacing", t.line_spacing_factor),
|
||||
edit(t!("Line space distance").as_ref(), "line_space_distance", line_space_distance),
|
||||
Property {
|
||||
label: "Line space style".into(),
|
||||
label: t!("Line space style").into_owned(),
|
||||
field: "line_space_style",
|
||||
value: PropValue::Choice {
|
||||
selected: match t.line_spacing_style {
|
||||
|
|
@ -330,7 +331,7 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Background mask".into(),
|
||||
label: t!("Background mask").into_owned(),
|
||||
field: "background_mask",
|
||||
value: PropValue::Choice {
|
||||
selected: if t.background_fill_flags & 0x01 != 0 {
|
||||
|
|
@ -346,15 +347,15 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
.collect(),
|
||||
},
|
||||
},
|
||||
num_row("Defined width", "rect_w", t.rectangle_width, width_editable),
|
||||
num_row(t!("Defined width").as_ref(), "rect_w", t.rectangle_width, width_editable),
|
||||
num_row(
|
||||
"Defined height",
|
||||
t!("Defined height").as_ref(),
|
||||
"rect_h",
|
||||
t.rectangle_height.unwrap_or(0.0),
|
||||
height_editable,
|
||||
),
|
||||
Property {
|
||||
label: "Columns".into(),
|
||||
label: t!("Columns").into_owned(),
|
||||
field: "columns",
|
||||
value: PropValue::Choice {
|
||||
selected: columns_str(&t.column_data).to_string(),
|
||||
|
|
@ -366,20 +367,20 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
},
|
||||
// Count / width / gutter are live only when columns are on.
|
||||
num_row(
|
||||
"Column count",
|
||||
t!("Column count").as_ref(),
|
||||
"col_count",
|
||||
t.column_data.column_count as f64,
|
||||
col_type != 0,
|
||||
),
|
||||
num_row("Column width", "col_width", t.column_data.width, col_type != 0),
|
||||
num_row(t!("Column width").as_ref(), "col_width", t.column_data.width, col_type != 0),
|
||||
num_row(
|
||||
"Column gutter",
|
||||
t!("Column gutter").as_ref(),
|
||||
"col_gutter",
|
||||
t.column_data.gutter,
|
||||
col_type != 0,
|
||||
),
|
||||
Property {
|
||||
label: "Text frame".into(),
|
||||
label: t!("Text frame").into_owned(),
|
||||
field: "text_frame",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "text_frame",
|
||||
|
|
@ -389,11 +390,11 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Position X", "ins_x", t.insertion_point.x),
|
||||
edit("Position Y", "ins_y", t.insertion_point.y),
|
||||
edit("Position Z", "ins_z", t.insertion_point.z),
|
||||
edit(t!("Position X").as_ref(), "ins_x", t.insertion_point.x),
|
||||
edit(t!("Position Y").as_ref(), "ins_y", t.insertion_point.y),
|
||||
edit(t!("Position Z").as_ref(), "ins_z", t.insertion_point.z),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use acadrust::entities::{
|
|||
use crate::entities::text_support::{
|
||||
layout_mtext, resolve_text_style, MTextRenderOpts, MTextVAnchor, ResolvedTextStyle,
|
||||
};
|
||||
use crate::t;
|
||||
|
||||
/// Map MLEADER's vertical attachment enum onto the shared `MTextVAnchor`
|
||||
/// used by `layout_mtext`. Replaces the old `v_offset_for_attachment`
|
||||
|
|
@ -650,19 +651,19 @@ fn properties(ml: &MultiLeader) -> Vec<PropSection> {
|
|||
|
||||
// ── Misc ─────────────────────────────────────────────────────────────
|
||||
let misc = PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
// Overall scale is grayed when annotative (annotation scale drives sizing).
|
||||
num_row(
|
||||
"Overall scale",
|
||||
t!("Overall scale").as_ref(),
|
||||
"scale_factor",
|
||||
ml.scale_factor,
|
||||
!ml.enable_annotation_scale,
|
||||
),
|
||||
// Style name is resolved from style_handle by the panel builder (needs doc).
|
||||
ro("Multileader style", "mleader_style", "Standard"),
|
||||
ro(t!("Multileader style").as_ref(), "mleader_style", "Standard"),
|
||||
bool_toggle(
|
||||
"Annotative",
|
||||
t!("Annotative").as_ref(),
|
||||
"enable_annotation_scale",
|
||||
ml.enable_annotation_scale,
|
||||
),
|
||||
|
|
@ -673,127 +674,127 @@ fn properties(ml: &MultiLeader) -> Vec<PropSection> {
|
|||
// Landing rows are folded in here: the standalone "Leader Structure" group
|
||||
// is a style-dialog tab, not a palette group.
|
||||
let leaders = PropSection {
|
||||
title: "Leaders".into(),
|
||||
title: t!("Leaders").into_owned(),
|
||||
props: vec![
|
||||
choice(
|
||||
"Leader type",
|
||||
t!("Leader type").as_ref(),
|
||||
"path_type",
|
||||
leader_type_str(&ml.path_type),
|
||||
&["Straight", "Spline", "None"],
|
||||
),
|
||||
Property {
|
||||
label: "Leader color".into(),
|
||||
label: t!("Leader color").into_owned(),
|
||||
field: "line_color",
|
||||
value: PropValue::ColorChoice(ml.line_color),
|
||||
},
|
||||
// Linetype name resolved from line_type_handle by the panel builder.
|
||||
ro("Leader linetype", "line_type_handle", "ByBlock"),
|
||||
ro(t!("Leader linetype").as_ref(), "line_type_handle", "ByBlock"),
|
||||
Property {
|
||||
label: "Leader lineweight".into(),
|
||||
label: t!("Leader lineweight").into_owned(),
|
||||
field: "line_weight",
|
||||
value: PropValue::LwChoice(ml.line_weight),
|
||||
},
|
||||
// Arrowhead block name resolved by the panel builder (default "Closed filled").
|
||||
ro("Arrowhead", "arrowhead_handle", "Closed filled"),
|
||||
edit("Arrowhead size", "arrowhead_size", ml.arrowhead_size),
|
||||
bool_toggle("Horizontal Landing", "enable_dogleg", ml.enable_dogleg),
|
||||
ro(t!("Arrowhead").as_ref(), "arrowhead_handle", "Closed filled"),
|
||||
edit(t!("Arrowhead size").as_ref(), "arrowhead_size", ml.arrowhead_size),
|
||||
bool_toggle(t!("Horizontal Landing").as_ref(), "enable_dogleg", ml.enable_dogleg),
|
||||
num_row(
|
||||
"Landing distance",
|
||||
t!("Landing distance").as_ref(),
|
||||
"landing_distance",
|
||||
ml.dogleg_length,
|
||||
ml.enable_dogleg,
|
||||
),
|
||||
bool_toggle("Leader extension", "enable_landing", ml.enable_landing),
|
||||
bool_toggle(t!("Leader extension").as_ref(), "enable_landing", ml.enable_landing),
|
||||
],
|
||||
};
|
||||
|
||||
// ── Text (shown only for MText content) ──────────────────────────────
|
||||
let text = PropSection {
|
||||
title: "Text".into(),
|
||||
title: t!("Text").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Contents".into(),
|
||||
label: t!("Contents").into_owned(),
|
||||
field: "text_string",
|
||||
value: PropValue::EditText(ctx.text_string.clone()),
|
||||
},
|
||||
// Text-style name resolved from text_style_handle by the panel builder.
|
||||
ro("Text style", "text_style_handle", "Standard"),
|
||||
ro(t!("Text style").as_ref(), "text_style_handle", "Standard"),
|
||||
choice(
|
||||
"Justify",
|
||||
t!("Justify").as_ref(),
|
||||
"text_alignment",
|
||||
text_align_str(&ml.text_alignment),
|
||||
&["Left", "Center", "Right"],
|
||||
),
|
||||
choice(
|
||||
"Direction",
|
||||
t!("Direction").as_ref(),
|
||||
"text_flow_direction",
|
||||
flow_dir_str(&ctx.text_flow_direction),
|
||||
&["By style", "Left to right", "Top to bottom"],
|
||||
),
|
||||
edit("Width", "text_width", ctx.text_width),
|
||||
edit("Height", "text_height", ml.text_height),
|
||||
edit_angle("Rotation", "text_rotation", ctx.text_rotation.to_degrees()),
|
||||
edit("Line space factor", "line_spacing", ctx.line_spacing_factor),
|
||||
edit(t!("Width").as_ref(), "text_width", ctx.text_width),
|
||||
edit(t!("Height").as_ref(), "text_height", ml.text_height),
|
||||
edit_angle(t!("Rotation").as_ref(), "text_rotation", ctx.text_rotation.to_degrees()),
|
||||
edit(t!("Line space factor").as_ref(), "line_spacing", ctx.line_spacing_factor),
|
||||
edit(
|
||||
"Line space distance",
|
||||
t!("Line space distance").as_ref(),
|
||||
"line_space_distance",
|
||||
ml.text_height * 1.666_666_666_666_667 * ctx.line_spacing_factor,
|
||||
),
|
||||
choice(
|
||||
"Line space style",
|
||||
t!("Line space style").as_ref(),
|
||||
"line_space_style",
|
||||
line_style_str(&ctx.line_spacing_style),
|
||||
&["At least", "Exactly"],
|
||||
),
|
||||
bool_toggle(
|
||||
"Background mask",
|
||||
t!("Background mask").as_ref(),
|
||||
"background_fill_enabled",
|
||||
ctx.background_fill_enabled,
|
||||
),
|
||||
choice(
|
||||
"Attachment type",
|
||||
t!("Attachment type").as_ref(),
|
||||
"text_attachment_direction",
|
||||
attach_dir_str(&ml.text_attachment_direction),
|
||||
&["Horizontal", "Vertical"],
|
||||
),
|
||||
choice(
|
||||
"Left Attachment",
|
||||
t!("Left Attachment").as_ref(),
|
||||
"text_left_attachment",
|
||||
attachment_str(&ml.text_left_attachment),
|
||||
&ATTACH_LABELS,
|
||||
),
|
||||
choice(
|
||||
"Right Attachment",
|
||||
t!("Right Attachment").as_ref(),
|
||||
"text_right_attachment",
|
||||
attachment_str(&ml.text_right_attachment),
|
||||
&ATTACH_LABELS,
|
||||
),
|
||||
edit("Landing gap", "landing_gap", ctx.landing_gap),
|
||||
bool_toggle("Text frame", "text_frame", ml.text_frame),
|
||||
edit(t!("Landing gap").as_ref(), "landing_gap", ctx.landing_gap),
|
||||
bool_toggle(t!("Text frame").as_ref(), "text_frame", ml.text_frame),
|
||||
],
|
||||
};
|
||||
|
||||
// ── Block ────────────────────────────────────────────────────────────
|
||||
let block = PropSection {
|
||||
title: "Block".into(),
|
||||
title: t!("Block").into_owned(),
|
||||
props: vec![
|
||||
ro(
|
||||
"Source block",
|
||||
t!("Source block").as_ref(),
|
||||
"block_content_handle",
|
||||
hexh(ml.block_content_handle),
|
||||
),
|
||||
ro(
|
||||
"Block connection",
|
||||
t!("Block connection").as_ref(),
|
||||
"block_connection_type",
|
||||
format!("{:?}", ml.block_connection_type),
|
||||
),
|
||||
ro(
|
||||
"Block color",
|
||||
t!("Block color").as_ref(),
|
||||
"block_content_color",
|
||||
format!("{:?}", ml.block_content_color),
|
||||
),
|
||||
ro(
|
||||
"Block scale",
|
||||
t!("Block scale").as_ref(),
|
||||
"block_scale",
|
||||
format!(
|
||||
"{:.3} × {:.3} × {:.3}",
|
||||
|
|
@ -801,7 +802,7 @@ fn properties(ml: &MultiLeader) -> Vec<PropSection> {
|
|||
),
|
||||
),
|
||||
edit(
|
||||
"Block rotation",
|
||||
t!("Block rotation").as_ref(),
|
||||
"block_rotation",
|
||||
ml.block_rotation.to_degrees(),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use acadrust::entities::Point;
|
||||
use acadrust::EntityType;
|
||||
use crate::t;
|
||||
use truck_modeling::{builder, Point3};
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
|
|
@ -187,11 +188,11 @@ fn grips(pt: &Point) -> Vec<GripDef> {
|
|||
|
||||
fn properties(pt: &Point) -> Vec<PropSection> {
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Position X", "loc_x", pt.location.x),
|
||||
edit("Position Y", "loc_y", pt.location.y),
|
||||
edit("Position Z", "loc_z", pt.location.z),
|
||||
edit(t!("Position X").as_ref(), "loc_x", pt.location.x),
|
||||
edit(t!("Position Y").as_ref(), "loc_y", pt.location.y),
|
||||
edit(t!("Position Z").as_ref(), "loc_z", pt.location.z),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use acadrust::entities::{Polyline, Polyline2D, Polyline3D};
|
||||
use crate::t;
|
||||
use truck_modeling::{builder, Edge, Point3, Wire};
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
|
|
@ -123,11 +124,11 @@ impl Grippable for Polyline {
|
|||
impl PropertyEditable for Polyline {
|
||||
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
ro("Vertices", "vertices", self.vertices.len().to_string()),
|
||||
ro(t!("Vertices").as_ref(), "vertices", self.vertices.len().to_string()),
|
||||
Property {
|
||||
label: "Closed".into(),
|
||||
label: t!("Closed").into_owned(),
|
||||
field: "pl_closed",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "pl_closed",
|
||||
|
|
@ -565,24 +566,24 @@ impl PropertyEditable for Polyline2D {
|
|||
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
stepper("Current Vertex", "pl2_current_vertex", vertex_label),
|
||||
edit("Vertex X", "pl2_vertex_x", vertex_x),
|
||||
edit("Vertex Y", "pl2_vertex_y", vertex_y),
|
||||
edit("Start segment width", "pl2_seg_start_w", seg_start_w),
|
||||
edit("End segment width", "pl2_seg_end_w", seg_end_w),
|
||||
edit("Global width", "pl2_start_w", self.start_width),
|
||||
edit("Elevation", "pl2_elevation", self.elevation),
|
||||
ro("Area", "pl2_area", format!("{area:.4}")),
|
||||
ro("Length", "pl2_length", format!("{length:.4}")),
|
||||
stepper(t!("Current Vertex").as_ref(), "pl2_current_vertex", vertex_label),
|
||||
edit(t!("Vertex X").as_ref(), "pl2_vertex_x", vertex_x),
|
||||
edit(t!("Vertex Y").as_ref(), "pl2_vertex_y", vertex_y),
|
||||
edit(t!("Start segment width").as_ref(), "pl2_seg_start_w", seg_start_w),
|
||||
edit(t!("End segment width").as_ref(), "pl2_seg_end_w", seg_end_w),
|
||||
edit(t!("Global width").as_ref(), "pl2_start_w", self.start_width),
|
||||
edit(t!("Elevation").as_ref(), "pl2_elevation", self.elevation),
|
||||
ro(t!("Area").as_ref(), "pl2_area", format!("{area:.4}")),
|
||||
ro(t!("Length").as_ref(), "pl2_length", format!("{length:.4}")),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Closed".into(),
|
||||
label: t!("Closed").into_owned(),
|
||||
field: "pl2_closed",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "pl2_closed",
|
||||
|
|
@ -590,7 +591,7 @@ impl PropertyEditable for Polyline2D {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Linetype generation".into(),
|
||||
label: t!("Linetype generation").into_owned(),
|
||||
field: "pl2_ltype_gen",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "pl2_ltype_gen",
|
||||
|
|
@ -838,26 +839,26 @@ impl PropertyEditable for Polyline3D {
|
|||
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
ro("Vertex", "pl3_vertex", if n > 0 { "1" } else { "" }),
|
||||
edit("Vertex X", "pl3_vertex_x", vertex_x),
|
||||
edit("Vertex Y", "pl3_vertex_y", vertex_y),
|
||||
edit("Vertex Z", "pl3_vertex_z", vertex_z),
|
||||
ro(t!("Vertex").as_ref(), "pl3_vertex", if n > 0 { "1" } else { "" }),
|
||||
edit(t!("Vertex X").as_ref(), "pl3_vertex_x", vertex_x),
|
||||
edit(t!("Vertex Y").as_ref(), "pl3_vertex_y", vertex_y),
|
||||
edit(t!("Vertex Z").as_ref(), "pl3_vertex_z", vertex_z),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Closed".into(),
|
||||
label: t!("Closed").into_owned(),
|
||||
field: "pl3_closed",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "pl3_closed",
|
||||
value: self.is_closed(),
|
||||
},
|
||||
},
|
||||
ro("Fit/Smooth", "pl3_smooth", fit_smooth),
|
||||
ro(t!("Fit/Smooth").as_ref(), "pl3_smooth", fit_smooth),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use acadrust::entities::{RasterImage, Wipeout};
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{center_grip, edit_prop as edit, ro_prop as ro, square_grip};
|
||||
|
|
@ -289,27 +290,27 @@ impl PropertyEditable for RasterImage {
|
|||
let transparency = format!("{:.0}%", self.common.transparency.as_percent() * 100.0);
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Position X", "ri_ox", self.insertion_point.x),
|
||||
edit("Position Y", "ri_oy", self.insertion_point.y),
|
||||
edit("Position Z", "ri_oz", self.insertion_point.z),
|
||||
ro("Rotation", "ri_rotation", format!("{:.4}", rotation_deg)),
|
||||
ro("Width", "ri_width", format!("{:.4}", self.width())),
|
||||
ro("Height", "ri_height", format!("{:.4}", self.height())),
|
||||
ro("Scale", "ri_scale", format!("{:.4}", scale)),
|
||||
edit(t!("Position X").as_ref(), "ri_ox", self.insertion_point.x),
|
||||
edit(t!("Position Y").as_ref(), "ri_oy", self.insertion_point.y),
|
||||
edit(t!("Position Z").as_ref(), "ri_oz", self.insertion_point.z),
|
||||
ro(t!("Rotation").as_ref(), "ri_rotation", format!("{:.4}", rotation_deg)),
|
||||
ro(t!("Width").as_ref(), "ri_width", format!("{:.4}", self.width())),
|
||||
ro(t!("Height").as_ref(), "ri_height", format!("{:.4}", self.height())),
|
||||
ro(t!("Scale").as_ref(), "ri_scale", format!("{:.4}", scale)),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
ro("Name", "ri_name", self.file_name().to_string()),
|
||||
edit("Brightness", "ri_bright", self.brightness as f64),
|
||||
edit("Contrast", "ri_contrast", self.contrast as f64),
|
||||
edit("Fade", "ri_fade", self.fade as f64),
|
||||
ro("Transparency", "ri_transparency", transparency),
|
||||
ro(t!("Name").as_ref(), "ri_name", self.file_name().to_string()),
|
||||
edit(t!("Brightness").as_ref(), "ri_bright", self.brightness as f64),
|
||||
edit(t!("Contrast").as_ref(), "ri_contrast", self.contrast as f64),
|
||||
edit(t!("Fade").as_ref(), "ri_fade", self.fade as f64),
|
||||
ro(t!("Transparency").as_ref(), "ri_transparency", transparency),
|
||||
Property {
|
||||
label: "Show image".into(),
|
||||
label: t!("Show image").into_owned(),
|
||||
field: "ri_show_image",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "ri_show_image",
|
||||
|
|
@ -317,7 +318,7 @@ impl PropertyEditable for RasterImage {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Show clipped".into(),
|
||||
label: t!("Show clipped").into_owned(),
|
||||
field: "ri_show_clipped",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "ri_show_clipped",
|
||||
|
|
@ -325,7 +326,7 @@ impl PropertyEditable for RasterImage {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Clip inverted".into(),
|
||||
label: t!("Clip inverted").into_owned(),
|
||||
field: "ri_clip_inverted",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "ri_clip_inverted",
|
||||
|
|
@ -596,18 +597,18 @@ impl PropertyEditable for Wipeout {
|
|||
.contains(acadrust::entities::WipeoutDisplayFlags::TRANSPARENCY_ON);
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Position X", "wo_ox", self.insertion_point.x),
|
||||
edit("Position Y", "wo_oy", self.insertion_point.y),
|
||||
edit("Position Z", "wo_oz", self.insertion_point.z),
|
||||
edit(t!("Position X").as_ref(), "wo_ox", self.insertion_point.x),
|
||||
edit(t!("Position Y").as_ref(), "wo_oy", self.insertion_point.y),
|
||||
edit(t!("Position Z").as_ref(), "wo_oz", self.insertion_point.z),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Show image".into(),
|
||||
label: t!("Show image").into_owned(),
|
||||
field: "wo_show_image",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "wo_show_image",
|
||||
|
|
@ -615,7 +616,7 @@ impl PropertyEditable for Wipeout {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Show clipped".into(),
|
||||
label: t!("Show clipped").into_owned(),
|
||||
field: "wo_show_clipped",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "wo_show_clipped",
|
||||
|
|
@ -623,7 +624,7 @@ impl PropertyEditable for Wipeout {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Background transparency".into(),
|
||||
label: t!("Background transparency").into_owned(),
|
||||
field: "wo_bg_transparency",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "wo_bg_transparency",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use acadrust::entities::{Ray, XLine};
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{center_grip, edit_prop as edit, square_grip};
|
||||
|
|
@ -91,14 +92,14 @@ impl Grippable for Ray {
|
|||
impl PropertyEditable for Ray {
|
||||
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Start X", "ray_bx", self.base_point.x),
|
||||
edit("Start Y", "ray_by", self.base_point.y),
|
||||
edit("Start Z", "ray_bz", self.base_point.z),
|
||||
edit("Direction vector X", "ray_dx", self.direction.x),
|
||||
edit("Direction vector Y", "ray_dy", self.direction.y),
|
||||
edit("Direction vector Z", "ray_dz", self.direction.z),
|
||||
edit(t!("Start X").as_ref(), "ray_bx", self.base_point.x),
|
||||
edit(t!("Start Y").as_ref(), "ray_by", self.base_point.y),
|
||||
edit(t!("Start Z").as_ref(), "ray_bz", self.base_point.z),
|
||||
edit(t!("Direction vector X").as_ref(), "ray_dx", self.direction.x),
|
||||
edit(t!("Direction vector Y").as_ref(), "ray_dy", self.direction.y),
|
||||
edit(t!("Direction vector Z").as_ref(), "ray_dz", self.direction.z),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
|
@ -229,14 +230,14 @@ impl Grippable for XLine {
|
|||
impl PropertyEditable for XLine {
|
||||
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Base X", "xl_bx", self.base_point.x),
|
||||
edit("Base Y", "xl_by", self.base_point.y),
|
||||
edit("Base Z", "xl_bz", self.base_point.z),
|
||||
edit("Direction vector X", "xl_dx", self.direction.x),
|
||||
edit("Direction vector Y", "xl_dy", self.direction.y),
|
||||
edit("Direction vector Z", "xl_dz", self.direction.z),
|
||||
edit(t!("Base X").as_ref(), "xl_bx", self.base_point.x),
|
||||
edit(t!("Base Y").as_ref(), "xl_by", self.base_point.y),
|
||||
edit(t!("Base Z").as_ref(), "xl_bz", self.base_point.z),
|
||||
edit(t!("Direction vector X").as_ref(), "xl_dx", self.direction.x),
|
||||
edit(t!("Direction vector Y").as_ref(), "xl_dy", self.direction.y),
|
||||
edit(t!("Direction vector Z").as_ref(), "xl_dz", self.direction.z),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
// gives a rough indication of the glyph orientation.
|
||||
|
||||
use acadrust::entities::Shape;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{edit_angle_prop as edit_angle, edit_prop as edit, ro_prop as ro, square_grip};
|
||||
|
|
@ -254,29 +255,29 @@ impl PropertyEditable for Shape {
|
|||
_ => "(none)".to_string(),
|
||||
};
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
ro("Name", "shp_name", self.shape_name.clone()),
|
||||
ro("Number", "shp_number", self.shape_number.to_string()),
|
||||
ro(t!("Name").as_ref(), "shp_name", self.shape_name.clone()),
|
||||
ro(t!("Number").as_ref(), "shp_number", self.shape_number.to_string()),
|
||||
Property {
|
||||
label: "Style".into(),
|
||||
label: t!("Style").into_owned(),
|
||||
field: "shp_style",
|
||||
value: PropValue::Choice {
|
||||
selected: self.style_name.clone(),
|
||||
options: text_style_names.to_vec(),
|
||||
},
|
||||
},
|
||||
ro("Style Handle", "shp_style_handle", style_handle_display),
|
||||
edit("Insert X", "shp_ix", self.insertion_point.x),
|
||||
edit("Insert Y", "shp_iy", self.insertion_point.y),
|
||||
edit("Insert Z", "shp_iz", self.insertion_point.z),
|
||||
edit("Size", "shp_sz", self.size),
|
||||
edit_angle("Rotation", "shp_rot", self.rotation.to_degrees()),
|
||||
edit("Width Factor", "shp_xs", self.relative_x_scale),
|
||||
edit_angle("Oblique Angle", "shp_ob", self.oblique_angle.to_degrees()),
|
||||
edit("Normal X", "shp_nx", self.normal.x),
|
||||
edit("Normal Y", "shp_ny", self.normal.y),
|
||||
edit("Normal Z", "shp_nz", self.normal.z),
|
||||
ro(t!("Style Handle").as_ref(), "shp_style_handle", style_handle_display),
|
||||
edit(t!("Insert X").as_ref(), "shp_ix", self.insertion_point.x),
|
||||
edit(t!("Insert Y").as_ref(), "shp_iy", self.insertion_point.y),
|
||||
edit(t!("Insert Z").as_ref(), "shp_iz", self.insertion_point.z),
|
||||
edit(t!("Size").as_ref(), "shp_sz", self.size),
|
||||
edit_angle(t!("Rotation").as_ref(), "shp_rot", self.rotation.to_degrees()),
|
||||
edit(t!("Width Factor").as_ref(), "shp_xs", self.relative_x_scale),
|
||||
edit_angle(t!("Oblique Angle").as_ref(), "shp_ob", self.oblique_angle.to_degrees()),
|
||||
edit(t!("Normal X").as_ref(), "shp_nx", self.normal.x),
|
||||
edit(t!("Normal Y").as_ref(), "shp_ny", self.normal.y),
|
||||
edit(t!("Normal Z").as_ref(), "shp_nz", self.normal.z),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
// Grips: 4 corner grip points.
|
||||
|
||||
use acadrust::entities::Solid;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip};
|
||||
|
|
@ -153,21 +154,21 @@ impl PropertyEditable for Solid {
|
|||
// field on the entity); reported from the first corner's Z.
|
||||
let elevation = self.first_corner.z;
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Point 1 X", "sl_p1x", self.first_corner.x),
|
||||
edit("Point 1 Y", "sl_p1y", self.first_corner.y),
|
||||
edit("Point 1 Z", "sl_p1z", self.first_corner.z),
|
||||
edit("Point 2 X", "sl_p2x", self.second_corner.x),
|
||||
edit("Point 2 Y", "sl_p2y", self.second_corner.y),
|
||||
edit("Point 2 Z", "sl_p2z", self.second_corner.z),
|
||||
edit("Point 3 X", "sl_p3x", self.third_corner.x),
|
||||
edit("Point 3 Y", "sl_p3y", self.third_corner.y),
|
||||
edit("Point 3 Z", "sl_p3z", self.third_corner.z),
|
||||
edit("Point 4 X", "sl_p4x", self.fourth_corner.x),
|
||||
edit("Point 4 Y", "sl_p4y", self.fourth_corner.y),
|
||||
edit("Point 4 Z", "sl_p4z", self.fourth_corner.z),
|
||||
ro("Elevation", "sl_elev", format!("{:.4}", elevation)),
|
||||
edit(t!("Point 1 X").as_ref(), "sl_p1x", self.first_corner.x),
|
||||
edit(t!("Point 1 Y").as_ref(), "sl_p1y", self.first_corner.y),
|
||||
edit(t!("Point 1 Z").as_ref(), "sl_p1z", self.first_corner.z),
|
||||
edit(t!("Point 2 X").as_ref(), "sl_p2x", self.second_corner.x),
|
||||
edit(t!("Point 2 Y").as_ref(), "sl_p2y", self.second_corner.y),
|
||||
edit(t!("Point 2 Z").as_ref(), "sl_p2z", self.second_corner.z),
|
||||
edit(t!("Point 3 X").as_ref(), "sl_p3x", self.third_corner.x),
|
||||
edit(t!("Point 3 Y").as_ref(), "sl_p3y", self.third_corner.y),
|
||||
edit(t!("Point 3 Z").as_ref(), "sl_p3z", self.third_corner.z),
|
||||
edit(t!("Point 4 X").as_ref(), "sl_p4x", self.fourth_corner.x),
|
||||
edit(t!("Point 4 Y").as_ref(), "sl_p4y", self.fourth_corner.y),
|
||||
edit(t!("Point 4 Z").as_ref(), "sl_p4z", self.fourth_corner.z),
|
||||
ro(t!("Elevation").as_ref(), "sl_elev", format!("{:.4}", elevation)),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
// the MeshModel vertices to match.
|
||||
|
||||
use acadrust::entities::{Body, Region, Solid3D, Surface};
|
||||
use crate::t;
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{center_grip, edit_prop as edit, parse_f64, ro_prop as ro};
|
||||
use crate::entities::traits::{Grippable, PropertyEditable, Transformable};
|
||||
|
|
@ -119,46 +120,40 @@ fn acis_sections(
|
|||
);
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Modeler Geometry".into(),
|
||||
title: t!("Modeler Geometry").into_owned(),
|
||||
props: vec![
|
||||
ro(
|
||||
"Format",
|
||||
ro(t!("Format").as_ref(),
|
||||
"acis_format",
|
||||
if acis.is_binary { "SAB" } else { "SAT" },
|
||||
),
|
||||
ro("Version", "acis_version", format!("{:?}", acis.version)),
|
||||
ro("Data Size", "acis_size", format!("{} bytes", acis.size())),
|
||||
ro("Revision", "acis_revision", revision),
|
||||
ro("Material Bindings", "acis_materials", bindings),
|
||||
ro("Extra Modeler Data", "acis_extra", extra),
|
||||
ro("History", "acis_history", handle_text(history)),
|
||||
ro(t!("Version").as_ref(), "acis_version", format!("{:?}", acis.version)),
|
||||
ro(t!("Data Size").as_ref(), "acis_size", format!("{} bytes", acis.size())),
|
||||
ro(t!("Revision").as_ref(), "acis_revision", revision),
|
||||
ro(t!("Material Bindings").as_ref(), "acis_materials", bindings),
|
||||
ro(t!("Extra Modeler Data").as_ref(), "acis_extra", extra),
|
||||
ro(t!("History").as_ref(), "acis_history", handle_text(history)),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Modeler Display Data".into(),
|
||||
title: t!("Modeler Display Data").into_owned(),
|
||||
props: vec![
|
||||
ro(
|
||||
"Wireframe Cache",
|
||||
ro(t!("Wireframe Cache").as_ref(),
|
||||
"acis_wireframe",
|
||||
yes_no(acis.wireframe_data_present),
|
||||
),
|
||||
ro(
|
||||
"Reference Point",
|
||||
ro(t!("Reference Point").as_ref(),
|
||||
"acis_wireframe_point",
|
||||
yes_no(acis.wireframe_point_present),
|
||||
),
|
||||
ro(
|
||||
"Isoline List",
|
||||
ro(t!("Isoline List").as_ref(),
|
||||
"acis_wireframe_isolines",
|
||||
yes_no(acis.wireframe_isoline_present),
|
||||
),
|
||||
ro(
|
||||
"Isolines",
|
||||
ro(t!("Isolines").as_ref(),
|
||||
"acis_isolines",
|
||||
acis.wireframe_isolines.to_string(),
|
||||
),
|
||||
ro(
|
||||
"Wires",
|
||||
ro(t!("Wires").as_ref(),
|
||||
"acis_wires",
|
||||
format!(
|
||||
"{} (unknown {}, silhouette {}, visible {}, hidden {}, isoline {}; {} points; {} transformed)",
|
||||
|
|
@ -172,8 +167,7 @@ fn acis_sections(
|
|||
transformed
|
||||
),
|
||||
),
|
||||
ro(
|
||||
"View Silhouettes",
|
||||
ro(t!("View Silhouettes").as_ref(),
|
||||
"acis_silhouettes",
|
||||
format!(
|
||||
"{} views; {} wires",
|
||||
|
|
@ -194,11 +188,11 @@ fn position_section(prefix: &str, p: &acadrust::types::Vector3) -> PropSection {
|
|||
_ => ["s3d_px", "s3d_py", "s3d_pz"],
|
||||
};
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Position X", fields[0], p.x),
|
||||
edit("Position Y", fields[1], p.y),
|
||||
edit("Position Z", fields[2], p.z),
|
||||
edit(t!("Position X").as_ref(), fields[0], p.x),
|
||||
edit(t!("Position Y").as_ref(), fields[1], p.y),
|
||||
edit(t!("Position Z").as_ref(), fields[2], p.z),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
|
@ -259,7 +253,7 @@ impl PropertyEditable for Solid3D {
|
|||
acis_sections(&self.acis_data, &self.wires, &self.silhouettes, self.history_handle);
|
||||
sections[0]
|
||||
.props
|
||||
.insert(0, ro("UID", "s3d_uid", self.uid.clone()));
|
||||
.insert(0, ro(t!("UID").as_ref(), "s3d_uid", self.uid.clone()));
|
||||
sections.push(position_section("s3d", &self.point_of_reference));
|
||||
sections
|
||||
}
|
||||
|
|
@ -304,14 +298,14 @@ impl PropertyEditable for Region {
|
|||
acis_sections(&self.acis_data, &self.wires, &self.silhouettes, self.history_handle);
|
||||
sections[0]
|
||||
.props
|
||||
.insert(0, ro("UID", "rgn_uid", self.uid.clone()));
|
||||
.insert(0, ro(t!("UID").as_ref(), "rgn_uid", self.uid.clone()));
|
||||
let mut geometry = position_section("rgn", &self.point_of_reference);
|
||||
geometry
|
||||
.props
|
||||
.push(ro("Area", "rgn_area", format!("{area:.4}")));
|
||||
.push(ro(t!("Area").as_ref(), "rgn_area", format!("{area:.4}")));
|
||||
geometry
|
||||
.props
|
||||
.push(ro("Perimeter", "rgn_perimeter", format!("{perimeter:.4}")));
|
||||
.push(ro(t!("Perimeter").as_ref(), "rgn_perimeter", format!("{perimeter:.4}")));
|
||||
sections.push(geometry);
|
||||
sections
|
||||
}
|
||||
|
|
@ -355,7 +349,7 @@ impl PropertyEditable for Body {
|
|||
acis_sections(&self.acis_data, &self.wires, &self.silhouettes, self.history_handle);
|
||||
sections[0]
|
||||
.props
|
||||
.insert(0, ro("UID", "bdy_uid", self.uid.clone()));
|
||||
.insert(0, ro(t!("UID").as_ref(), "bdy_uid", self.uid.clone()));
|
||||
sections.push(position_section("bdy", &self.point_of_reference));
|
||||
sections
|
||||
}
|
||||
|
|
@ -433,19 +427,16 @@ fn sweep_options_text(options: &acadrust::entities::SurfaceSweepOptions) -> Stri
|
|||
fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||
use acadrust::entities::SurfaceData;
|
||||
let mut props = vec![
|
||||
ro("Kind", "srf_kind", format!("{:?}", surface.kind)),
|
||||
ro(
|
||||
"Modeler Format",
|
||||
ro(t!("Kind").as_ref(), "srf_kind", format!("{:?}", surface.kind)),
|
||||
ro(t!("Modeler Format").as_ref(),
|
||||
"srf_modeler_version",
|
||||
surface.modeler_format_version.to_string(),
|
||||
),
|
||||
edit(
|
||||
"U Isolines",
|
||||
edit(t!("U Isolines").as_ref(),
|
||||
"srf_u_isolines",
|
||||
surface.u_isolines as f64,
|
||||
),
|
||||
edit(
|
||||
"V Isolines",
|
||||
edit(t!("V Isolines").as_ref(),
|
||||
"srf_v_isolines",
|
||||
surface.v_isolines as f64,
|
||||
),
|
||||
|
|
@ -453,8 +444,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
match &surface.surface_data {
|
||||
SurfaceData::Generic => {}
|
||||
SurfaceData::Plane { class_version } => {
|
||||
props.push(ro(
|
||||
"Class Version",
|
||||
props.push(ro(t!("Class Version").as_ref(),
|
||||
"srf_class_version",
|
||||
class_version.to_string(),
|
||||
));
|
||||
|
|
@ -466,25 +456,21 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
sweep_transform,
|
||||
} => {
|
||||
props.extend([
|
||||
ro(
|
||||
"Sweep Entity",
|
||||
ro(t!("Sweep Entity").as_ref(),
|
||||
"srf_sweep_entity",
|
||||
embedded_name(sweep_entity.as_ref()),
|
||||
),
|
||||
ro("Sweep Vector", "srf_sweep_vector", vector_text(sweep_vector)),
|
||||
ro("Sweep Options", "srf_sweep_options", sweep_options_text(options)),
|
||||
ro(
|
||||
"Sweep Transform",
|
||||
ro(t!("Sweep Vector").as_ref(), "srf_sweep_vector", vector_text(sweep_vector)),
|
||||
ro(t!("Sweep Options").as_ref(), "srf_sweep_options", sweep_options_text(options)),
|
||||
ro(t!("Sweep Transform").as_ref(),
|
||||
"srf_sweep_transform",
|
||||
matrix_text(sweep_transform),
|
||||
),
|
||||
ro(
|
||||
"Sweep Entity Transform",
|
||||
ro(t!("Sweep Entity Transform").as_ref(),
|
||||
"srf_sweep_entity_transform",
|
||||
matrix_text(&options.sweep_entity_transform),
|
||||
),
|
||||
ro(
|
||||
"Path Entity Transform",
|
||||
ro(t!("Path Entity Transform").as_ref(),
|
||||
"srf_path_entity_transform",
|
||||
matrix_text(&options.path_entity_transform),
|
||||
),
|
||||
|
|
@ -513,8 +499,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
path_curve,
|
||||
} => {
|
||||
props.extend([
|
||||
ro(
|
||||
"Embedded Curves",
|
||||
ro(t!("Embedded Curves").as_ref(),
|
||||
"srf_loft_embedded",
|
||||
format!(
|
||||
"{} cross sections; {} guides; path {}",
|
||||
|
|
@ -523,8 +508,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
embedded_name(path_entity.as_ref())
|
||||
),
|
||||
),
|
||||
ro(
|
||||
"Database Curves",
|
||||
ro(t!("Database Curves").as_ref(),
|
||||
"srf_loft_handles",
|
||||
format!(
|
||||
"{} cross sections; {} guides; path {}",
|
||||
|
|
@ -533,8 +517,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
handle_text(*path_curve)
|
||||
),
|
||||
),
|
||||
ro(
|
||||
"Draft",
|
||||
ro(t!("Draft").as_ref(),
|
||||
"srf_loft_draft",
|
||||
format!(
|
||||
"type {}; angle {:.6}→{:.6}; magnitude {:.6}→{:.6}",
|
||||
|
|
@ -545,8 +528,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
end_draft_magnitude
|
||||
),
|
||||
),
|
||||
ro(
|
||||
"Loft Flags",
|
||||
ro(t!("Loft Flags").as_ref(),
|
||||
"srf_loft_flags",
|
||||
format!(
|
||||
"arc-length {}; no-twist {}; align {}; simple {}; closed {}; solid {}; ruled {}; virtual-guide {}",
|
||||
|
|
@ -560,8 +542,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
yes_no(*virtual_guide)
|
||||
),
|
||||
),
|
||||
ro(
|
||||
"Loft Transform",
|
||||
ro(t!("Loft Transform").as_ref(),
|
||||
"srf_loft_transform",
|
||||
matrix_text(loft_transform),
|
||||
),
|
||||
|
|
@ -584,33 +565,28 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
close_to_axis,
|
||||
} => {
|
||||
props.extend([
|
||||
ro(
|
||||
"Revolve Entity",
|
||||
ro(t!("Revolve Entity").as_ref(),
|
||||
"srf_revolve_entity",
|
||||
embedded_name(revolve_entity.as_ref()),
|
||||
),
|
||||
ro(
|
||||
"Class / Entity",
|
||||
ro(t!("Class / Entity").as_ref(),
|
||||
"srf_revolve_ids",
|
||||
format!("{class_version} / {entity_id}"),
|
||||
),
|
||||
ro("Axis Point", "srf_axis_point", vector_text(axis_point)),
|
||||
ro("Axis Vector", "srf_axis_vector", vector_text(axis_vector)),
|
||||
ro(
|
||||
"Angles",
|
||||
ro(t!("Axis Point").as_ref(), "srf_axis_point", vector_text(axis_point)),
|
||||
ro(t!("Axis Vector").as_ref(), "srf_axis_vector", vector_text(axis_vector)),
|
||||
ro(t!("Angles").as_ref(),
|
||||
"srf_revolve_angles",
|
||||
format!(
|
||||
"start {:.6}; revolve {:.6}; draft {:.6}; twist {:.6}",
|
||||
start_angle, revolve_angle, draft_angle, twist_angle
|
||||
),
|
||||
),
|
||||
ro(
|
||||
"Draft Distances",
|
||||
ro(t!("Draft Distances").as_ref(),
|
||||
"srf_revolve_draft_distances",
|
||||
format!("{draft_start_distance:.6}→{draft_end_distance:.6}"),
|
||||
),
|
||||
ro(
|
||||
"Revolve Flags",
|
||||
ro(t!("Revolve Flags").as_ref(),
|
||||
"srf_revolve_flags",
|
||||
format!(
|
||||
"solid {}; close-to-axis {}",
|
||||
|
|
@ -618,8 +594,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
yes_no(*close_to_axis)
|
||||
),
|
||||
),
|
||||
ro(
|
||||
"Entity Transform",
|
||||
ro(t!("Entity Transform").as_ref(),
|
||||
"srf_revolve_transform",
|
||||
matrix_text(entity_transform),
|
||||
),
|
||||
|
|
@ -634,13 +609,11 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
options,
|
||||
} => {
|
||||
props.extend([
|
||||
ro(
|
||||
"Class Version",
|
||||
ro(t!("Class Version").as_ref(),
|
||||
"srf_class_version",
|
||||
class_version.to_string(),
|
||||
),
|
||||
ro(
|
||||
"Sweep / Path",
|
||||
ro(t!("Sweep / Path").as_ref(),
|
||||
"srf_swept_entities",
|
||||
format!(
|
||||
"{} / {}",
|
||||
|
|
@ -648,24 +621,20 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
embedded_name(path_entity.as_ref())
|
||||
),
|
||||
),
|
||||
ro("Sweep Options", "srf_sweep_options", sweep_options_text(options)),
|
||||
ro(
|
||||
"Sweep Transform",
|
||||
ro(t!("Sweep Options").as_ref(), "srf_sweep_options", sweep_options_text(options)),
|
||||
ro(t!("Sweep Transform").as_ref(),
|
||||
"srf_sweep_transform",
|
||||
matrix_text(sweep_transform),
|
||||
),
|
||||
ro(
|
||||
"Path Transform",
|
||||
ro(t!("Path Transform").as_ref(),
|
||||
"srf_path_transform",
|
||||
matrix_text(path_transform),
|
||||
),
|
||||
ro(
|
||||
"Sweep Entity Transform",
|
||||
ro(t!("Sweep Entity Transform").as_ref(),
|
||||
"srf_sweep_entity_transform",
|
||||
matrix_text(&options.sweep_entity_transform),
|
||||
),
|
||||
ro(
|
||||
"Path Entity Transform",
|
||||
ro(t!("Path Entity Transform").as_ref(),
|
||||
"srf_path_entity_transform",
|
||||
matrix_text(&options.path_entity_transform),
|
||||
),
|
||||
|
|
@ -680,25 +649,23 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
|||
v_vector2,
|
||||
} => {
|
||||
props.extend([
|
||||
ro(
|
||||
"NURB Version",
|
||||
ro(t!("NURB Version").as_ref(),
|
||||
"srf_nurb_version",
|
||||
short_170.to_string(),
|
||||
),
|
||||
ro(
|
||||
"CV Hull",
|
||||
ro(t!("CV Hull").as_ref(),
|
||||
"srf_nurb_cv_hull",
|
||||
yes_no(*cv_hull_display),
|
||||
),
|
||||
ro("U Vector 1", "srf_nurb_u1", vector_text(u_vector1)),
|
||||
ro("V Vector 1", "srf_nurb_v1", vector_text(v_vector1)),
|
||||
ro("U Vector 2", "srf_nurb_u2", vector_text(u_vector2)),
|
||||
ro("V Vector 2", "srf_nurb_v2", vector_text(v_vector2)),
|
||||
ro(t!("U Vector 1").as_ref(), "srf_nurb_u1", vector_text(u_vector1)),
|
||||
ro(t!("V Vector 1").as_ref(), "srf_nurb_v1", vector_text(v_vector1)),
|
||||
ro(t!("U Vector 2").as_ref(), "srf_nurb_u2", vector_text(u_vector2)),
|
||||
ro(t!("V Vector 2").as_ref(), "srf_nurb_v2", vector_text(v_vector2)),
|
||||
]);
|
||||
}
|
||||
}
|
||||
PropSection {
|
||||
title: "Surface Construction".into(),
|
||||
title: t!("Surface Construction").into_owned(),
|
||||
props,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use acadrust::entities::Spline;
|
||||
use crate::t;
|
||||
use truck_modeling::{
|
||||
base::{BoundedCurve, ParametricCurve, Vector4},
|
||||
builder, BSplineCurve, Curve, Edge, KnotVec, NurbsCurve, Point3, Wire,
|
||||
|
|
@ -383,58 +384,58 @@ fn properties(spline: &Spline) -> Vec<PropSection> {
|
|||
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Data Points".into(),
|
||||
title: t!("Data Points").into_owned(),
|
||||
props: vec![
|
||||
ro("Show", "show", show),
|
||||
ro("Degree", "degree", spline.degree.to_string()),
|
||||
ro(t!("Show").as_ref(), "show", show),
|
||||
ro(t!("Degree").as_ref(), "degree", spline.degree.to_string()),
|
||||
ro(
|
||||
"Control Point Count",
|
||||
t!("Control Point Count").as_ref(),
|
||||
"ctrl_pt_count",
|
||||
spline.control_points.len().to_string(),
|
||||
),
|
||||
ro("Control Point", "ctrl_pt_index", "0"),
|
||||
ro(t!("Control Point").as_ref(), "ctrl_pt_index", "0"),
|
||||
edit(
|
||||
"Control Point X",
|
||||
t!("Control Point X").as_ref(),
|
||||
"ctrl_pt_x",
|
||||
cp0.map(|p| p.x).unwrap_or(0.0),
|
||||
),
|
||||
edit(
|
||||
"Control Point Y",
|
||||
t!("Control Point Y").as_ref(),
|
||||
"ctrl_pt_y",
|
||||
cp0.map(|p| p.y).unwrap_or(0.0),
|
||||
),
|
||||
edit(
|
||||
"Control Point Z",
|
||||
t!("Control Point Z").as_ref(),
|
||||
"ctrl_pt_z",
|
||||
cp0.map(|p| p.z).unwrap_or(0.0),
|
||||
),
|
||||
edit("Weight", "weight", w0.unwrap_or(1.0)),
|
||||
ro("Knot Parameterization", "knot_param", knot_param),
|
||||
edit(t!("Weight").as_ref(), "weight", w0.unwrap_or(1.0)),
|
||||
ro(t!("Knot Parameterization").as_ref(), "knot_param", knot_param),
|
||||
ro(
|
||||
"Fit Point Count",
|
||||
t!("Fit Point Count").as_ref(),
|
||||
"fit_pt_count",
|
||||
spline.fit_points.len().to_string(),
|
||||
),
|
||||
ro("Fit Point", "fit_pt_index", "0"),
|
||||
edit("Fit Point X", "fit_pt_x", fp0.map(|p| p.x).unwrap_or(0.0)),
|
||||
edit("Fit Point Y", "fit_pt_y", fp0.map(|p| p.y).unwrap_or(0.0)),
|
||||
edit("Fit Point Z", "fit_pt_z", fp0.map(|p| p.z).unwrap_or(0.0)),
|
||||
edit("Fit Tolerance", "fit_tolerance", spline.fit_tolerance),
|
||||
edit("Start Tangent X", "start_tan_x", spline.begin_tangent.x),
|
||||
edit("Start Tangent Y", "start_tan_y", spline.begin_tangent.y),
|
||||
edit("Start Tangent Z", "start_tan_z", spline.begin_tangent.z),
|
||||
edit("End Tangent X", "end_tan_x", spline.end_tangent.x),
|
||||
edit("End Tangent Y", "end_tan_y", spline.end_tangent.y),
|
||||
edit("End Tangent Z", "end_tan_z", spline.end_tangent.z),
|
||||
ro(t!("Fit Point").as_ref(), "fit_pt_index", "0"),
|
||||
edit(t!("Fit Point X").as_ref(), "fit_pt_x", fp0.map(|p| p.x).unwrap_or(0.0)),
|
||||
edit(t!("Fit Point Y").as_ref(), "fit_pt_y", fp0.map(|p| p.y).unwrap_or(0.0)),
|
||||
edit(t!("Fit Point Z").as_ref(), "fit_pt_z", fp0.map(|p| p.z).unwrap_or(0.0)),
|
||||
edit(t!("Fit Tolerance").as_ref(), "fit_tolerance", spline.fit_tolerance),
|
||||
edit(t!("Start Tangent X").as_ref(), "start_tan_x", spline.begin_tangent.x),
|
||||
edit(t!("Start Tangent Y").as_ref(), "start_tan_y", spline.begin_tangent.y),
|
||||
edit(t!("Start Tangent Z").as_ref(), "start_tan_z", spline.begin_tangent.z),
|
||||
edit(t!("End Tangent X").as_ref(), "end_tan_x", spline.end_tangent.x),
|
||||
edit(t!("End Tangent Y").as_ref(), "end_tan_y", spline.end_tangent.y),
|
||||
edit(t!("End Tangent Z").as_ref(), "end_tan_z", spline.end_tangent.z),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
ro("Closed", "closed", yes_no(closed)),
|
||||
ro("Planar", "planar", yes_no(spline.flags.planar)),
|
||||
ro("Length", "length", format!("{length:.4}")),
|
||||
ro("Area", "area", area),
|
||||
ro(t!("Closed").as_ref(), "closed", yes_no(closed)),
|
||||
ro(t!("Planar").as_ref(), "planar", yes_no(spline.flags.planar)),
|
||||
ro(t!("Length").as_ref(), "length", format!("{length:.4}")),
|
||||
ro(t!("Area").as_ref(), "area", area),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject};
|
|||
use crate::scene::model::object::{GripApply, GripDef, PropSection, Property, PropValue};
|
||||
use crate::scene::view::transform;
|
||||
use crate::scene::model::wire_model::SnapHint;
|
||||
use crate::t;
|
||||
|
||||
fn v3(v: &acadrust::types::Vector3) -> Vec3 {
|
||||
Vec3::new(v.x as f32, v.y as f32, v.z as f32)
|
||||
|
|
@ -1773,7 +1774,7 @@ impl PropertyEditable for Table {
|
|||
_ => "(none)".to_string(),
|
||||
}
|
||||
};
|
||||
let toggle = |label: &'static str, field: &'static str, b: bool| -> Property {
|
||||
let toggle = |label: &str, field: &'static str, b: bool| -> Property {
|
||||
Property {
|
||||
label: label.into(),
|
||||
field,
|
||||
|
|
@ -1806,93 +1807,93 @@ impl PropertyEditable for Table {
|
|||
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Table".into(),
|
||||
title: t!("Table").into_owned(),
|
||||
props: vec![
|
||||
ro(
|
||||
"Table style",
|
||||
t!("Table style").as_ref(),
|
||||
"tbl_style_handle",
|
||||
fmt_h(&self.table_style_handle),
|
||||
),
|
||||
ro("Rows", "tbl_rows", self.rows.len().to_string()),
|
||||
ro("Columns", "tbl_cols", self.columns.len().to_string()),
|
||||
ro("Contents", "tbl_contents", content_count.to_string()),
|
||||
ro(t!("Rows").as_ref(), "tbl_rows", self.rows.len().to_string()),
|
||||
ro(t!("Columns").as_ref(), "tbl_cols", self.columns.len().to_string()),
|
||||
ro(t!("Contents").as_ref(), "tbl_contents", content_count.to_string()),
|
||||
ro(
|
||||
"Block contents",
|
||||
t!("Block contents").as_ref(),
|
||||
"tbl_block_contents",
|
||||
block_content_count.to_string(),
|
||||
),
|
||||
ro(
|
||||
"Field contents",
|
||||
t!("Field contents").as_ref(),
|
||||
"tbl_field_contents",
|
||||
field_content_count.to_string(),
|
||||
),
|
||||
ro(
|
||||
"Merged ranges",
|
||||
t!("Merged ranges").as_ref(),
|
||||
"tbl_merged_ranges",
|
||||
self.merged_ranges.len().to_string(),
|
||||
),
|
||||
ro(
|
||||
"Linked cells",
|
||||
t!("Linked cells").as_ref(),
|
||||
"tbl_linked_cells",
|
||||
linked_cell_count.to_string(),
|
||||
),
|
||||
ro("Direction", "tbl_direction", format!("{:.4}", direction_deg)),
|
||||
ro(t!("Direction").as_ref(), "tbl_direction", format!("{:.4}", direction_deg)),
|
||||
ro(
|
||||
"Table width",
|
||||
t!("Table width").as_ref(),
|
||||
"tbl_width",
|
||||
format!("{:.4}", self.total_width()),
|
||||
),
|
||||
ro(
|
||||
"Table height",
|
||||
t!("Table height").as_ref(),
|
||||
"tbl_height",
|
||||
format!("{:.4}", self.total_height()),
|
||||
),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Table Breaks".into(),
|
||||
title: t!("Table Breaks").into_owned(),
|
||||
props: vec![
|
||||
toggle(
|
||||
"Enabled",
|
||||
t!("Enabled").as_ref(),
|
||||
"tbl_break_enabled",
|
||||
self.break_options.contains(BreakOptionFlags::ENABLE_BREAKS),
|
||||
),
|
||||
ro(
|
||||
"Direction",
|
||||
t!("Direction").as_ref(),
|
||||
"tbl_break_direction",
|
||||
format!("{:?}", self.break_flow_direction),
|
||||
),
|
||||
toggle(
|
||||
"Repeat top labels",
|
||||
t!("Repeat top labels").as_ref(),
|
||||
"tbl_break_repeat_top",
|
||||
self.break_options
|
||||
.contains(BreakOptionFlags::REPEAT_TOP_LABELS),
|
||||
),
|
||||
toggle(
|
||||
"Repeat bottom labels",
|
||||
t!("Repeat bottom labels").as_ref(),
|
||||
"tbl_break_repeat_bottom",
|
||||
self.break_options
|
||||
.contains(BreakOptionFlags::REPEAT_BOTTOM_LABELS),
|
||||
),
|
||||
toggle(
|
||||
"Manual positions",
|
||||
t!("Manual positions").as_ref(),
|
||||
"tbl_break_manual_positions",
|
||||
self.break_options
|
||||
.contains(BreakOptionFlags::ALLOW_MANUAL_POSITIONS),
|
||||
),
|
||||
toggle(
|
||||
"Manual heights",
|
||||
t!("Manual heights").as_ref(),
|
||||
"tbl_break_manual_heights",
|
||||
self.break_options
|
||||
.contains(BreakOptionFlags::ALLOW_MANUAL_HEIGHTS),
|
||||
),
|
||||
ro(
|
||||
"Segments",
|
||||
t!("Segments").as_ref(),
|
||||
"tbl_break_segments",
|
||||
self.break_ranges.len().max(self.break_data.len()).to_string(),
|
||||
),
|
||||
ro("Break heights", "tbl_break_height", break_heights),
|
||||
edit("Spacing", "tbl_break_spacing", self.break_spacing),
|
||||
ro(t!("Break heights").as_ref(), "tbl_break_height", break_heights),
|
||||
edit(t!("Spacing").as_ref(), "tbl_break_spacing", self.break_spacing),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use crate::scene::convert::acad_to_truck::{GlyphRun, TextStroke, TruckEntity, Tr
|
|||
use crate::scene::text::lff;
|
||||
use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property};
|
||||
use crate::scene::model::wire_model::SnapHint;
|
||||
use crate::t;
|
||||
|
||||
/// Combined single-line-text justification (horizontal × vertical) shown as one
|
||||
/// dropdown value. Horizontal-only modes (Aligned/Middle/Fit) ignore the
|
||||
|
|
@ -273,15 +274,15 @@ fn properties(t: &Text, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
};
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Text".into(),
|
||||
title: t!("Text").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Contents".into(),
|
||||
label: t!("Contents").into_owned(),
|
||||
field: "content",
|
||||
value: PropValue::EditText(t.value.clone()),
|
||||
},
|
||||
Property {
|
||||
label: "Style".into(),
|
||||
label: t!("Style").into_owned(),
|
||||
field: "style",
|
||||
value: PropValue::Choice {
|
||||
selected: if t.style.trim().is_empty() {
|
||||
|
|
@ -292,9 +293,9 @@ fn properties(t: &Text, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
options: text_style_names.to_vec(),
|
||||
},
|
||||
},
|
||||
ro("Annotative", "annotative", "No"),
|
||||
ro(t!("Annotative").as_ref(), "annotative", "No"),
|
||||
Property {
|
||||
label: "Justify".into(),
|
||||
label: t!("Justify").into_owned(),
|
||||
field: "justify",
|
||||
value: PropValue::Choice {
|
||||
selected: text_justify_str(
|
||||
|
|
@ -324,28 +325,28 @@ fn properties(t: &Text, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
.collect(),
|
||||
},
|
||||
},
|
||||
edit("Height", "height", t.height),
|
||||
edit_angle("Rotation", "rotation", t.rotation.to_degrees()),
|
||||
edit("Width factor", "width_factor", t.width_factor),
|
||||
edit_angle("Obliquing", "oblique_angle", t.oblique_angle.to_degrees()),
|
||||
num_row("Text alignment X", "align_x", ax, align_editable),
|
||||
num_row("Text alignment Y", "align_y", ay, align_editable),
|
||||
num_row("Text alignment Z", "align_z", az, align_editable),
|
||||
edit(t!("Height").as_ref(), "height", t.height),
|
||||
edit_angle(t!("Rotation").as_ref(), "rotation", t.rotation.to_degrees()),
|
||||
edit(t!("Width factor").as_ref(), "width_factor", t.width_factor),
|
||||
edit_angle(t!("Obliquing").as_ref(), "oblique_angle", t.oblique_angle.to_degrees()),
|
||||
num_row(t!("Text alignment X").as_ref(), "align_x", ax, align_editable),
|
||||
num_row(t!("Text alignment Y").as_ref(), "align_y", ay, align_editable),
|
||||
num_row(t!("Text alignment Z").as_ref(), "align_z", az, align_editable),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
num_row("Position X", "ins_x", t.insertion_point.x, pos_editable),
|
||||
num_row("Position Y", "ins_y", t.insertion_point.y, pos_editable),
|
||||
num_row("Position Z", "ins_z", t.insertion_point.z, pos_editable),
|
||||
num_row(t!("Position X").as_ref(), "ins_x", t.insertion_point.x, pos_editable),
|
||||
num_row(t!("Position Y").as_ref(), "ins_y", t.insertion_point.y, pos_editable),
|
||||
num_row(t!("Position Z").as_ref(), "ins_z", t.insertion_point.z, pos_editable),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
Property {
|
||||
label: "Upside down".into(),
|
||||
label: t!("Upside down").into_owned(),
|
||||
field: "upside_down",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "upside_down",
|
||||
|
|
@ -353,7 +354,7 @@ fn properties(t: &Text, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Backward".into(),
|
||||
label: t!("Backward").into_owned(),
|
||||
field: "backward",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "backward",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use crate::scene::model::object::{GripApply, GripDef, PropSection};
|
|||
use crate::scene::model::wire_model::SnapHint;
|
||||
use crate::scene::text::lff;
|
||||
use crate::scene::view::transform;
|
||||
use crate::t;
|
||||
|
||||
// ── GDT text parser ───────────────────────────────────────────────────────────
|
||||
|
||||
|
|
@ -541,25 +542,25 @@ impl PropertyEditable for Tolerance {
|
|||
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Text".into(),
|
||||
title: t!("Text").into_owned(),
|
||||
props: vec![
|
||||
ro("Text style", "tol_text_style", String::new()),
|
||||
edit("Text height", "tol_text_height", self.text_height),
|
||||
ro(t!("Text style").as_ref(), "tol_text_style", String::new()),
|
||||
edit(t!("Text height").as_ref(), "tol_text_height", self.text_height),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Position X", "tol_ix", self.insertion_point.x),
|
||||
edit("Position Y", "tol_iy", self.insertion_point.y),
|
||||
edit("Position Z", "tol_iz", self.insertion_point.z),
|
||||
edit(t!("Position X").as_ref(), "tol_ix", self.insertion_point.x),
|
||||
edit(t!("Position Y").as_ref(), "tol_iy", self.insertion_point.y),
|
||||
edit(t!("Position Z").as_ref(), "tol_iz", self.insertion_point.z),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
ro(
|
||||
"Dimension style",
|
||||
t!("Dimension style").as_ref(),
|
||||
"tol_dim_style",
|
||||
if self.dimension_style_name.is_empty() {
|
||||
"(default)".to_string()
|
||||
|
|
@ -567,9 +568,9 @@ impl PropertyEditable for Tolerance {
|
|||
self.dimension_style_name.clone()
|
||||
},
|
||||
),
|
||||
edit("Direction X", "tol_dir_x", self.direction.x),
|
||||
edit("Direction Y", "tol_dir_y", self.direction.y),
|
||||
edit("Direction Z", "tol_dir_z", self.direction.z),
|
||||
edit(t!("Direction X").as_ref(), "tol_dir_x", self.direction.x),
|
||||
edit(t!("Direction Y").as_ref(), "tol_dir_y", self.direction.y),
|
||||
edit(t!("Direction Z").as_ref(), "tol_dir_z", self.direction.z),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
// Props: position, scales, rotation, contrast, fade, flags.
|
||||
|
||||
use acadrust::entities::{Underlay, UnderlayDisplayFlags};
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{center_grip, edit_angle_prop as edit_angle, edit_prop as edit, ro_prop as ro, square_grip};
|
||||
|
|
@ -224,26 +225,26 @@ impl PropertyEditable for Underlay {
|
|||
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
title: t!("Geometry").into_owned(),
|
||||
props: vec![
|
||||
edit("Position X", "ul_ix", self.insertion_point.x),
|
||||
edit("Position Y", "ul_iy", self.insertion_point.y),
|
||||
edit("Position Z", "ul_iz", self.insertion_point.z),
|
||||
edit("Scale X", "ul_sx", self.x_scale),
|
||||
edit("Scale Y", "ul_sy", self.y_scale),
|
||||
edit("Scale Z", "ul_sz", self.z_scale),
|
||||
ro("Width", "ul_width", format!("{:.4}", width)),
|
||||
ro("Height", "ul_height", format!("{:.4}", height)),
|
||||
edit_angle("Rotation", "ul_rot", self.rotation.to_degrees()),
|
||||
edit(t!("Position X").as_ref(), "ul_ix", self.insertion_point.x),
|
||||
edit(t!("Position Y").as_ref(), "ul_iy", self.insertion_point.y),
|
||||
edit(t!("Position Z").as_ref(), "ul_iz", self.insertion_point.z),
|
||||
edit(t!("Scale X").as_ref(), "ul_sx", self.x_scale),
|
||||
edit(t!("Scale Y").as_ref(), "ul_sy", self.y_scale),
|
||||
edit(t!("Scale Z").as_ref(), "ul_sz", self.z_scale),
|
||||
ro(t!("Width").as_ref(), "ul_width", format!("{:.4}", width)),
|
||||
ro(t!("Height").as_ref(), "ul_height", format!("{:.4}", height)),
|
||||
edit_angle(t!("Rotation").as_ref(), "ul_rot", self.rotation.to_degrees()),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Underlay Adjust".into(),
|
||||
title: t!("Underlay Adjust").into_owned(),
|
||||
props: vec![
|
||||
edit("Contrast", "ul_contrast", self.contrast as f64),
|
||||
edit("Fade", "ul_fade", self.fade as f64),
|
||||
edit(t!("Contrast").as_ref(), "ul_contrast", self.contrast as f64),
|
||||
edit(t!("Fade").as_ref(), "ul_fade", self.fade as f64),
|
||||
Property {
|
||||
label: "Monochrome".into(),
|
||||
label: t!("Monochrome").into_owned(),
|
||||
field: "ul_mono",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "ul_mono",
|
||||
|
|
@ -251,7 +252,7 @@ impl PropertyEditable for Underlay {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Adjust Colors for Background".into(),
|
||||
label: t!("Adjust Colors for Background").into_owned(),
|
||||
field: "ul_adjust_bg",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "ul_adjust_bg",
|
||||
|
|
@ -261,14 +262,14 @@ impl PropertyEditable for Underlay {
|
|||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![
|
||||
// Underlay name/path/layers live on the separate
|
||||
// UnderlayDefinition object, not reachable from the entity.
|
||||
ro("Underlay name", "ul_name", String::new()),
|
||||
ro("Underlay path", "ul_path", String::new()),
|
||||
ro(t!("Underlay name").as_ref(), "ul_name", String::new()),
|
||||
ro(t!("Underlay path").as_ref(), "ul_path", String::new()),
|
||||
Property {
|
||||
label: "Show underlay".into(),
|
||||
label: t!("Show underlay").into_owned(),
|
||||
field: "ul_on",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "ul_on",
|
||||
|
|
@ -276,7 +277,7 @@ impl PropertyEditable for Underlay {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Clipping".into(),
|
||||
label: t!("Clipping").into_owned(),
|
||||
field: "ul_clip",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "ul_clip",
|
||||
|
|
@ -284,14 +285,14 @@ impl PropertyEditable for Underlay {
|
|||
},
|
||||
},
|
||||
Property {
|
||||
label: "Show clipped".into(),
|
||||
label: t!("Show clipped").into_owned(),
|
||||
field: "ul_clip_inverted",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "ul_clip_inverted",
|
||||
value: self.clip_inverted,
|
||||
},
|
||||
},
|
||||
ro("Underlay layers", "ul_layers", String::new()),
|
||||
ro(t!("Underlay layers").as_ref(), "ul_layers", String::new()),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use acadrust::entities::{SectionSymbol, ViewBorder};
|
||||
use crate::t;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{edit_angle_prop, edit_prop, parse_f64, ro_prop, square_grip};
|
||||
|
|
@ -83,37 +84,31 @@ impl PropertyEditable for SectionSymbol {
|
|||
.join("\n");
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Section Symbol".into(),
|
||||
title: t!("Section Symbol").into_owned(),
|
||||
props: vec![
|
||||
edit_prop("Symbol Scale", "section_scale", self.symbol_scale),
|
||||
ro_prop(
|
||||
"View Symbol Version",
|
||||
edit_prop(t!("Symbol Scale").as_ref(), "section_scale", self.symbol_scale),
|
||||
ro_prop(t!("View Symbol Version").as_ref(),
|
||||
"section_view_version",
|
||||
self.view_symbol_version.to_string(),
|
||||
),
|
||||
ro_prop("Version", "section_version", self.version.to_string()),
|
||||
ro_prop(
|
||||
"Style",
|
||||
ro_prop(t!("Version").as_ref(), "section_version", self.version.to_string()),
|
||||
ro_prop(t!("Style").as_ref(),
|
||||
"section_style",
|
||||
handle_text(self.style_handle),
|
||||
),
|
||||
ro_prop(
|
||||
"View Representation",
|
||||
ro_prop(t!("View Representation").as_ref(),
|
||||
"section_view_rep",
|
||||
handle_text(self.view_rep_handle),
|
||||
),
|
||||
ro_prop(
|
||||
"View Symbol Flags",
|
||||
ro_prop(t!("View Symbol Flags").as_ref(),
|
||||
"section_view_flags",
|
||||
self.raw_view_symbol_70.to_string(),
|
||||
),
|
||||
ro_prop(
|
||||
"Point Count",
|
||||
ro_prop(t!("Point Count").as_ref(),
|
||||
"section_point_count",
|
||||
self.points.len().to_string(),
|
||||
),
|
||||
ro_prop(
|
||||
"Stored Point Counts",
|
||||
ro_prop(t!("Stored Point Counts").as_ref(),
|
||||
"section_raw_counts",
|
||||
format!(
|
||||
"{}, {}, flags {}",
|
||||
|
|
@ -122,12 +117,12 @@ impl PropertyEditable for SectionSymbol {
|
|||
self.raw_flags_90
|
||||
),
|
||||
),
|
||||
ro_prop("Identifier", "section_label", self.label.clone()),
|
||||
ro_prop(t!("Identifier").as_ref(), "section_label", self.label.clone()),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Section Points".into(),
|
||||
props: vec![ro_prop("Records", "section_points", point_data)],
|
||||
title: t!("Section Points").into_owned(),
|
||||
props: vec![ro_prop(t!("Records").as_ref(), "section_points", point_data)],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
@ -197,34 +192,29 @@ impl Grippable for ViewBorder {
|
|||
impl PropertyEditable for ViewBorder {
|
||||
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
||||
vec![PropSection {
|
||||
title: "Drawing View".into(),
|
||||
title: t!("Drawing View").into_owned(),
|
||||
props: vec![
|
||||
edit_prop("Center X", "view_border_x", self.center[0]),
|
||||
edit_prop("Center Y", "view_border_y", self.center[1]),
|
||||
ro_prop(
|
||||
"Width",
|
||||
edit_prop(t!("Center X").as_ref(), "view_border_x", self.center[0]),
|
||||
edit_prop(t!("Center Y").as_ref(), "view_border_y", self.center[1]),
|
||||
ro_prop(t!("Width").as_ref(),
|
||||
"view_border_width",
|
||||
format!("{:.6}", self.max[0] - self.min[0]),
|
||||
),
|
||||
ro_prop(
|
||||
"Height",
|
||||
ro_prop(t!("Height").as_ref(),
|
||||
"view_border_height",
|
||||
format!("{:.6}", self.max[1] - self.min[1]),
|
||||
),
|
||||
edit_prop("Scale", "view_border_scale", self.scale),
|
||||
edit_angle_prop(
|
||||
"Rotation",
|
||||
edit_prop(t!("Scale").as_ref(), "view_border_scale", self.scale),
|
||||
edit_angle_prop(t!("Rotation").as_ref(),
|
||||
"view_border_rotation",
|
||||
self.rotation_angle.to_degrees(),
|
||||
),
|
||||
ro_prop("Version", "view_border_version", self.version.to_string()),
|
||||
ro_prop(
|
||||
"Active Viewport",
|
||||
ro_prop(t!("Version").as_ref(), "view_border_version", self.version.to_string()),
|
||||
ro_prop(t!("Active Viewport").as_ref(),
|
||||
"view_border_viewport",
|
||||
handle_text(self.active_viewport),
|
||||
),
|
||||
ro_prop(
|
||||
"Scale Object",
|
||||
ro_prop(t!("Scale Object").as_ref(),
|
||||
"view_border_scale_handle",
|
||||
handle_text(self.scale_handle),
|
||||
),
|
||||
|
|
|
|||
130
src/i18n.rs
130
src/i18n.rs
|
|
@ -7,9 +7,13 @@ use i18n_embed::DesktopLanguageRequester;
|
|||
#[cfg(target_arch = "wasm32")]
|
||||
use i18n_embed::WebLanguageRequester;
|
||||
use rust_embed::RustEmbed;
|
||||
use std::borrow::Cow;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::OnceLock;
|
||||
|
||||
#[path = "locale_catalog.rs"]
|
||||
mod locale_catalog;
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "locales/"]
|
||||
struct Localizations;
|
||||
|
|
@ -123,6 +127,107 @@ pub fn set_language(language: Language) -> Result<(), i18n_embed::I18nEmbedError
|
|||
load_language(loader(), language)
|
||||
}
|
||||
|
||||
/// Translate an application-facing source label from the complete UI catalog.
|
||||
///
|
||||
/// Stable semantic ids remain preferable for new code. This compatibility
|
||||
/// layer lets existing UI surfaces move to Fluent without turning command
|
||||
/// tokens, property ids, file-format values, or plug-in supplied text into
|
||||
/// translatable data.
|
||||
pub fn translate(source: impl AsRef<str>) -> Cow<'static, str> {
|
||||
let source = source.as_ref();
|
||||
locale_catalog::message_id(source)
|
||||
.map(|message_id| Cow::Owned(loader().get(message_id)))
|
||||
.unwrap_or_else(|| Cow::Owned(source.to_string()))
|
||||
}
|
||||
|
||||
/// Translate a catalog message and replace the named values used by legacy
|
||||
/// command prompts. Catalog generation protects these markers from machine
|
||||
/// translation and Fluent parsing.
|
||||
pub fn translate_args(
|
||||
source: impl AsRef<str>,
|
||||
args: &[(&str, String)],
|
||||
) -> Cow<'static, str> {
|
||||
let source = source.as_ref();
|
||||
let mut translated = locale_catalog::message_id(source)
|
||||
.map(|message_id| loader().get(message_id))
|
||||
.unwrap_or_else(|| source.to_string());
|
||||
for (name, value) in args {
|
||||
translated = translated.replace(&format!("__ocs_arg_{name}__"), value);
|
||||
translated = translated.replace(&format!("%{{{name}}}"), value);
|
||||
}
|
||||
Cow::Owned(translated)
|
||||
}
|
||||
|
||||
/// Translate a Rust formatting template after its values have been rendered.
|
||||
/// The catalog stores positional markers, while this function recovers each
|
||||
/// rendered value from the English template and places it in the localized
|
||||
/// sentence. File names, handles, counts, and command values therefore remain
|
||||
/// data instead of being sent through translation.
|
||||
pub fn translate_format(template: &str, rendered: String) -> Cow<'static, str> {
|
||||
let Some(message_id) = locale_catalog::message_id(template) else {
|
||||
return Cow::Owned(rendered);
|
||||
};
|
||||
let Some(values) = format_values(template, &rendered) else {
|
||||
return Cow::Owned(rendered);
|
||||
};
|
||||
let mut translated = loader().get(message_id);
|
||||
for (index, value) in values.iter().enumerate() {
|
||||
translated = translated.replace(&format!("__ocs_fmt_{index}__"), value);
|
||||
}
|
||||
Cow::Owned(translated)
|
||||
}
|
||||
|
||||
fn format_values(template: &str, rendered: &str) -> Option<Vec<String>> {
|
||||
let mut literals = vec![String::new()];
|
||||
let mut chars = template.chars().peekable();
|
||||
while let Some(ch) = chars.next() {
|
||||
match (ch, chars.peek().copied()) {
|
||||
('{', Some('{')) => {
|
||||
chars.next();
|
||||
literals.last_mut()?.push('{');
|
||||
}
|
||||
('}', Some('}')) => {
|
||||
chars.next();
|
||||
literals.last_mut()?.push('}');
|
||||
}
|
||||
('{', _) => {
|
||||
let mut closed = false;
|
||||
for inner in chars.by_ref() {
|
||||
if inner == '}' {
|
||||
closed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !closed {
|
||||
return None;
|
||||
}
|
||||
literals.push(String::new());
|
||||
}
|
||||
('}', _) => return None,
|
||||
_ => literals.last_mut()?.push(ch),
|
||||
}
|
||||
}
|
||||
|
||||
let mut cursor = 0;
|
||||
if !rendered.starts_with(&literals[0]) {
|
||||
return None;
|
||||
}
|
||||
cursor += literals[0].len();
|
||||
let mut values = Vec::with_capacity(literals.len().saturating_sub(1));
|
||||
for index in 1..literals.len() {
|
||||
let separator = &literals[index];
|
||||
if index + 1 == literals.len() && separator.is_empty() {
|
||||
values.push(rendered[cursor..].to_string());
|
||||
cursor = rendered.len();
|
||||
} else {
|
||||
let offset = rendered[cursor..].find(separator)?;
|
||||
values.push(rendered[cursor..cursor + offset].to_string());
|
||||
cursor += offset + separator.len();
|
||||
}
|
||||
}
|
||||
(cursor == rendered.len()).then_some(values)
|
||||
}
|
||||
|
||||
/// Built-in ribbon modules have stable ids; plug-ins keep their supplied title
|
||||
/// until they provide their own localization bundle.
|
||||
pub fn ribbon_module_title(id: &str, fallback: &str) -> String {
|
||||
|
|
@ -151,3 +256,28 @@ macro_rules! tr {
|
|||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// Source-catalog compatibility macro used while the existing interface is
|
||||
/// migrated to semantic Fluent ids. Named arguments mirror the command prompt
|
||||
/// placeholders already present in the source catalog.
|
||||
#[macro_export]
|
||||
macro_rules! t {
|
||||
($source:expr $(,)?) => {
|
||||
$crate::i18n::translate($source)
|
||||
};
|
||||
($source:expr, $($name:ident = $value:expr),+ $(,)?) => {
|
||||
$crate::i18n::translate_args(
|
||||
$source,
|
||||
&[$((stringify!($name), ($value).to_string())),+],
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// Localized counterpart of `format!` for application-facing messages.
|
||||
#[macro_export]
|
||||
macro_rules! tf {
|
||||
($template:literal $($args:tt)*) => {{
|
||||
let rendered = format!($template $($args)*);
|
||||
$crate::i18n::translate_format($template, rendered)
|
||||
}};
|
||||
}
|
||||
|
|
|
|||
2987
src/locale_catalog.rs
Normal file
2987
src/locale_catalog.rs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -8,6 +8,7 @@ use glam::DVec3;
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_aligned.svg"));
|
||||
|
||||
|
|
@ -57,18 +58,18 @@ impl CadCommand for AlignedDimensionCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.awaiting_text {
|
||||
return "DIMALIGNED Enter dimension text (blank = measured value):".into();
|
||||
return t!("DIMALIGNED Enter dimension text (blank = measured value):").into_owned();
|
||||
}
|
||||
if self.awaiting_angle {
|
||||
return "DIMALIGNED Specify text angle (degrees):".into();
|
||||
return t!("DIMALIGNED Specify text angle (degrees):").into_owned();
|
||||
}
|
||||
match self.step {
|
||||
Step::First => "DIMALIGNED Specify first extension line origin:".into(),
|
||||
Step::First => t!("DIMALIGNED Specify first extension line origin:").into_owned(),
|
||||
Step::Second(_) => {
|
||||
"DIMALIGNED Specify second extension line origin [Text/Angle]:".into()
|
||||
t!("DIMALIGNED Specify second extension line origin [Text/Angle]:").into_owned()
|
||||
}
|
||||
Step::DimLine { .. } => {
|
||||
"DIMALIGNED Specify dimension line location [Text/Angle]:".into()
|
||||
t!("DIMALIGNED Specify dimension line location [Text/Angle]:").into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use crate::command::{CadCommand, CmdResult};
|
|||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use glam::{DVec3, Vec3};
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_angular.svg"));
|
||||
|
||||
|
|
@ -49,10 +50,14 @@ impl CadCommand for AngularDimensionCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
Step::Vertex => "DIMANGULAR Specify angle vertex:".into(),
|
||||
Step::FirstRay(_) => "DIMANGULAR Specify first extension line point:".into(),
|
||||
Step::SecondRay { .. } => "DIMANGULAR Specify second extension line point:".into(),
|
||||
Step::ArcPoint { .. } => "DIMANGULAR Specify dimension arc location:".into(),
|
||||
Step::Vertex => t!("DIMANGULAR Specify angle vertex:").into_owned(),
|
||||
Step::FirstRay(_) => {
|
||||
t!("DIMANGULAR Specify first extension line point:").into_owned()
|
||||
}
|
||||
Step::SecondRay { .. } => {
|
||||
t!("DIMANGULAR Specify second extension line point:").into_owned()
|
||||
}
|
||||
Step::ArcPoint { .. } => t!("DIMANGULAR Specify dimension arc location:").into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use glam::DVec3;
|
|||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/ddedit.svg"));
|
||||
|
||||
|
|
@ -38,7 +39,7 @@ impl CadCommand for DdeditCommand {
|
|||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
"DDEDIT Select text entity:".into()
|
||||
t!("DDEDIT Select text entity:").into_owned()
|
||||
}
|
||||
|
||||
fn needs_entity_pick(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use glam::{DVec3, Vec3};
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_diameter.svg"));
|
||||
|
||||
|
|
@ -57,16 +58,16 @@ impl CadCommand for DiameterDimensionCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.awaiting_text {
|
||||
return "DIMDIAMETER Enter dimension text (blank = measured value):".into();
|
||||
return t!("DIMDIAMETER Enter dimension text (blank = measured value):").into_owned();
|
||||
}
|
||||
if self.awaiting_angle {
|
||||
return "DIMDIAMETER Specify text angle (degrees):".into();
|
||||
return t!("DIMDIAMETER Specify text angle (degrees):").into_owned();
|
||||
}
|
||||
match self.step {
|
||||
Step::CenterPoint => "DIMDIAMETER Specify center point:".into(),
|
||||
Step::ArcPoint(_) => "DIMDIAMETER Specify point on circle:".into(),
|
||||
Step::CenterPoint => t!("DIMDIAMETER Specify center point:").into_owned(),
|
||||
Step::ArcPoint(_) => t!("DIMDIAMETER Specify point on circle:").into_owned(),
|
||||
Step::TextPoint { .. } => {
|
||||
"DIMDIAMETER Specify dimension line location [Text/Angle]:".into()
|
||||
t!("DIMDIAMETER Specify dimension line location [Text/Angle]:").into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use glam::{DVec3, Vec3};
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_baseline.svg"));
|
||||
|
||||
|
|
@ -130,9 +131,9 @@ impl CadCommand for DimBaselineCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if !self.ready {
|
||||
"DIMBASELINE No base dimension found. Place a dimension first.".into()
|
||||
t!("DIMBASELINE No base dimension found. Place a dimension first.").into_owned()
|
||||
} else {
|
||||
"DIMBASELINE Specify a second extension line origin (Enter to exit):".into()
|
||||
t!("DIMBASELINE Specify a second extension line origin (Enter to exit):").into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use glam::{DVec3, Vec3};
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_continue.svg"));
|
||||
|
||||
|
|
@ -104,9 +105,9 @@ impl CadCommand for DimContinueCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if !self.ready {
|
||||
"DIMCONTINUE No base dimension found. Place a dimension first.".into()
|
||||
t!("DIMCONTINUE No base dimension found. Place a dimension first.").into_owned()
|
||||
} else {
|
||||
"DIMCONTINUE Specify a second extension line origin (Enter to exit):".into()
|
||||
t!("DIMCONTINUE Specify a second extension line origin (Enter to exit):").into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use glam::DVec3;
|
|||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_break.svg"));
|
||||
|
||||
|
|
@ -50,9 +51,9 @@ impl CadCommand for DimBreakCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::PickDim => "DIMBREAK Select dimension to break:".into(),
|
||||
Step::PickDim => t!("DIMBREAK Select dimension to break:").into_owned(),
|
||||
Step::PickCrossing { .. } => {
|
||||
"DIMBREAK Select object to break at, or Enter for Auto:".into()
|
||||
t!("DIMBREAK Select object to break at, or Enter for Auto:").into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use glam::DVec3;
|
|||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_edit.svg"));
|
||||
|
||||
|
|
@ -45,9 +46,9 @@ impl CadCommand for DimEditCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::PickDim => "DIMEDIT Select dimension:".into(),
|
||||
Step::PickDim => t!("DIMEDIT Select dimension:").into_owned(),
|
||||
Step::EnterText { .. } => {
|
||||
"DIMEDIT Enter text override (blank = reset to measured):".into()
|
||||
t!("DIMEDIT Enter text override (blank = reset to measured):").into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use glam::DVec3;
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_jog.svg"));
|
||||
|
||||
|
|
@ -46,8 +47,8 @@ impl CadCommand for DimJogLineCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::PickDim => "DIMJOGLINE Select linear or aligned dimension:".into(),
|
||||
Step::PickJogPos { .. } => "DIMJOGLINE Specify jog location:".into(),
|
||||
Step::PickDim => t!("DIMJOGLINE Select linear or aligned dimension:").into_owned(),
|
||||
Step::PickJogPos { .. } => t!("DIMJOGLINE Specify jog location:").into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use glam::DVec3;
|
|||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_space.svg"));
|
||||
|
||||
|
|
@ -47,12 +48,13 @@ impl CadCommand for DimSpaceCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::PickBase => "DIMSPACE Select base dimension:".into(),
|
||||
Step::PickOthers { others, .. } => format!(
|
||||
"DIMSPACE Select dimension to space ({} selected, Enter when done):",
|
||||
others.len()
|
||||
),
|
||||
Step::EnterSpacing { .. } => "DIMSPACE Enter value (0 = auto):".into(),
|
||||
Step::PickBase => t!("DIMSPACE Select base dimension:").into_owned(),
|
||||
Step::PickOthers { others, .. } => t!(
|
||||
"DIMSPACE Select dimension to space (%{count} selected, Enter when done):",
|
||||
count = others.len()
|
||||
)
|
||||
.into_owned(),
|
||||
Step::EnterSpacing { .. } => t!("DIMSPACE Enter value (0 = auto):").into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use glam::DVec3;
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_tedit.svg"));
|
||||
|
||||
|
|
@ -49,8 +50,10 @@ impl CadCommand for DimTeditCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::PickDim => "DIMTEDIT Select dimension:".into(),
|
||||
Step::PickTextPos { .. } => "DIMTEDIT Specify new location for dimension text:".into(),
|
||||
Step::PickDim => t!("DIMTEDIT Select dimension:").into_owned(),
|
||||
Step::PickTextPos { .. } => {
|
||||
t!("DIMTEDIT Specify new location for dimension text:").into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ use glam::{DVec3, Mat4, Vec3};
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/leader.svg"));
|
||||
|
||||
|
|
@ -52,12 +53,13 @@ impl CadCommand for LeaderCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.verts.is_empty() {
|
||||
"LEADER Specify arrowhead point:".into()
|
||||
t!("LEADER Specify arrowhead point:").into_owned()
|
||||
} else {
|
||||
format!(
|
||||
"LEADER Specify next point [{} pts — Enter to place text]:",
|
||||
self.verts.len()
|
||||
t!(
|
||||
"LEADER Specify next point [%{count} pts — Enter to place text]:",
|
||||
count = self.verts.len()
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use crate::command::{CadCommand, CmdResult};
|
|||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use glam::{DVec3, Mat4, Vec3};
|
||||
use crate::t;
|
||||
|
||||
/// World-space measurement axis for a linear dimension between `first` and
|
||||
/// `second`, chosen as the UCS X or Y axis (whichever the span is closer to).
|
||||
|
|
@ -75,18 +76,18 @@ impl CadCommand for LinearDimensionCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.awaiting_text {
|
||||
return "DIMLINEAR Enter dimension text (blank = measured value):".into();
|
||||
return t!("DIMLINEAR Enter dimension text (blank = measured value):").into_owned();
|
||||
}
|
||||
if self.awaiting_angle {
|
||||
return "DIMLINEAR Specify text angle (degrees):".into();
|
||||
return t!("DIMLINEAR Specify text angle (degrees):").into_owned();
|
||||
}
|
||||
match self.step {
|
||||
Step::FirstPoint => "DIMLINEAR Specify first extension line origin:".into(),
|
||||
Step::FirstPoint => t!("DIMLINEAR Specify first extension line origin:").into_owned(),
|
||||
Step::SecondPoint(_) => {
|
||||
"DIMLINEAR Specify second extension line origin [Text/Angle]:".into()
|
||||
t!("DIMLINEAR Specify second extension line origin [Text/Angle]:").into_owned()
|
||||
}
|
||||
Step::DimensionLine { .. } => {
|
||||
"DIMLINEAR Specify dimension line location [Text/Angle]:".into()
|
||||
t!("DIMLINEAR Specify dimension line location [Text/Angle]:").into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use glam::{DVec3, Mat4, Vec3};
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mleader.svg"));
|
||||
|
||||
|
|
@ -47,12 +48,13 @@ impl CadCommand for MLeaderCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.verts.is_empty() {
|
||||
"MLEADER Specify arrowhead point:".into()
|
||||
t!("MLEADER Specify arrowhead point:").into_owned()
|
||||
} else {
|
||||
format!(
|
||||
"MLEADER Specify next point [{} pts — Enter to place text]:",
|
||||
self.verts.len()
|
||||
t!(
|
||||
"MLEADER Specify next point [%{count} pts — Enter to place text]:",
|
||||
count = self.verts.len()
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use glam::{DVec3, Vec3};
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
// ── MLEADERADD ────────────────────────────────────────────────────────────────
|
||||
|
||||
|
|
@ -60,12 +61,15 @@ impl CadCommand for MLeaderAddCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
AddStep::PickMLeader => "MLEADERADD Select a multileader:".into(),
|
||||
AddStep::PickArrowhead { .. } => "MLEADERADD Specify arrowhead location:".into(),
|
||||
AddStep::CollectPoints { pts, .. } => format!(
|
||||
"MLEADERADD Specify next leader point ({} pts, Enter to finish):",
|
||||
pts.len()
|
||||
),
|
||||
AddStep::PickMLeader => t!("MLEADERADD Select a multileader:").into_owned(),
|
||||
AddStep::PickArrowhead { .. } => {
|
||||
t!("MLEADERADD Specify arrowhead location:").into_owned()
|
||||
}
|
||||
AddStep::CollectPoints { pts, .. } => t!(
|
||||
"MLEADERADD Specify next leader point (%{count} pts, Enter to finish):",
|
||||
count = pts.len()
|
||||
)
|
||||
.into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -192,9 +196,9 @@ impl CadCommand for MLeaderRemoveCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
RemoveStep::PickMLeader => "MLEADERREMOVE Select a multileader:".into(),
|
||||
RemoveStep::PickMLeader => t!("MLEADERREMOVE Select a multileader:").into_owned(),
|
||||
RemoveStep::PickLeaderToRemove { .. } => {
|
||||
"MLEADERREMOVE Click near the leader line to remove:".into()
|
||||
t!("MLEADERREMOVE Click near the leader line to remove:").into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -300,13 +304,13 @@ impl CadCommand for MLeaderAlignCommand {
|
|||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
AlignStep::Gathering => {
|
||||
"MLEADERALIGN Select multileaders to align (Enter when done):".into()
|
||||
t!("MLEADERALIGN Select multileaders to align (Enter when done):").into_owned()
|
||||
}
|
||||
AlignStep::PickDirection { .. } => {
|
||||
"MLEADERALIGN Specify direction — pick start point:".into()
|
||||
t!("MLEADERALIGN Specify direction — pick start point:").into_owned()
|
||||
}
|
||||
AlignStep::PickEndDir { .. } => {
|
||||
"MLEADERALIGN Specify end point of alignment direction:".into()
|
||||
t!("MLEADERALIGN Specify end point of alignment direction:").into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -405,10 +409,10 @@ impl CadCommand for MLeaderCollectCommand {
|
|||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
CollectStep::Gathering => {
|
||||
"MLEADERCOLLECT Select multileaders to collect (Enter when done):".into()
|
||||
t!("MLEADERCOLLECT Select multileaders to collect (Enter when done):").into_owned()
|
||||
}
|
||||
CollectStep::PickLocation { .. } => {
|
||||
"MLEADERCOLLECT Specify collected multileader location:".into()
|
||||
t!("MLEADERCOLLECT Specify collected multileader location:").into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use crate::command::{CadCommand, CmdResult};
|
|||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use glam::DVec3;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mtext.svg"));
|
||||
|
||||
|
|
@ -37,7 +38,7 @@ impl CadCommand for MTextCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::InsertPoint => "MTEXT Specify insertion point:".into(),
|
||||
Step::InsertPoint => t!("MTEXT Specify insertion point:").into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ use glam::{DVec3, Vec3};
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
|
|
@ -50,8 +51,8 @@ impl CadCommand for OrdinateDimCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
Step::FeaturePoint => "DIMORDINATE Specify feature location:".into(),
|
||||
Step::LeaderEndpoint { .. } => "DIMORDINATE Specify leader endpoint:".into(),
|
||||
Step::FeaturePoint => t!("DIMORDINATE Specify feature location:").into_owned(),
|
||||
Step::LeaderEndpoint { .. } => t!("DIMORDINATE Specify leader endpoint:").into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use glam::DVec3;
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/qdim.svg"));
|
||||
|
||||
|
|
@ -50,8 +51,10 @@ impl CadCommand for QdimCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::Gathering => "QDIM Select geometry to dimension (Enter when done):".into(),
|
||||
Step::PlaceLine { .. } => "QDIM Specify dimension line position:".into(),
|
||||
Step::Gathering => {
|
||||
t!("QDIM Select geometry to dimension (Enter when done):").into_owned()
|
||||
}
|
||||
Step::PlaceLine { .. } => t!("QDIM Specify dimension line position:").into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use crate::command::{CadCommand, CmdResult};
|
|||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use glam::{DVec3, Vec3};
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_radius.svg"));
|
||||
|
||||
|
|
@ -55,16 +56,16 @@ impl CadCommand for RadiusDimensionCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.awaiting_text {
|
||||
return "DIMRADIUS Enter dimension text (blank = measured value):".into();
|
||||
return t!("DIMRADIUS Enter dimension text (blank = measured value):").into_owned();
|
||||
}
|
||||
if self.awaiting_angle {
|
||||
return "DIMRADIUS Specify text angle (degrees):".into();
|
||||
return t!("DIMRADIUS Specify text angle (degrees):").into_owned();
|
||||
}
|
||||
match self.step {
|
||||
Step::CenterPoint => "DIMRADIUS Specify center point:".into(),
|
||||
Step::RadiusPoint(_) => "DIMRADIUS Specify radius point:".into(),
|
||||
Step::CenterPoint => t!("DIMRADIUS Specify center point:").into_owned(),
|
||||
Step::RadiusPoint(_) => t!("DIMRADIUS Specify radius point:").into_owned(),
|
||||
Step::TextPoint { .. } => {
|
||||
"DIMRADIUS Specify dimension line location [Text/Angle]:".into()
|
||||
t!("DIMRADIUS Specify dimension line location [Text/Angle]:").into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use glam::DVec3;
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/table.svg"));
|
||||
|
||||
|
|
@ -57,13 +58,23 @@ impl CadCommand for TableCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::Columns => format!("TABLE Enter number of columns [{DEFAULT_COLS}]:"),
|
||||
Step::Rows { cols } => format!(
|
||||
"TABLE Enter number of rows (incl. header) [{DEFAULT_ROWS}] ({cols} cols):"
|
||||
),
|
||||
Step::Insertion { cols, rows } => {
|
||||
format!("TABLE Specify insertion point [{cols}×{rows}]:")
|
||||
}
|
||||
Step::Columns => t!(
|
||||
"TABLE Enter number of columns [%{cols}]:",
|
||||
cols = DEFAULT_COLS
|
||||
)
|
||||
.into_owned(),
|
||||
Step::Rows { cols } => t!(
|
||||
"TABLE Enter number of rows (incl. header) [%{rows}] (%{cols} cols):",
|
||||
rows = DEFAULT_ROWS,
|
||||
cols = cols
|
||||
)
|
||||
.into_owned(),
|
||||
Step::Insertion { cols, rows } => t!(
|
||||
"TABLE Specify insertion point [%{cols}×%{rows}]:",
|
||||
cols = cols,
|
||||
rows = rows
|
||||
)
|
||||
.into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use crate::command::{CadCommand, CmdResult};
|
|||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use glam::DVec3;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/text.svg"));
|
||||
|
||||
|
|
@ -37,7 +38,7 @@ impl CadCommand for TextCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::InsertPoint => "TEXT Specify insertion point:".into(),
|
||||
Step::InsertPoint => t!("TEXT Specify insertion point:").into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use acadrust::Handle;
|
|||
use glam::DVec3;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::t;
|
||||
|
||||
/// Parse a TEXTEDITMODE value. Accepts `0`/`m`/`multiple`/`false` (Multiple → false)
|
||||
/// and `1`/`s`/`single`/`true` (Single → true), case-insensitive. Returns `None`
|
||||
|
|
@ -69,24 +70,27 @@ impl CadCommand for TexteditCommand {
|
|||
match self.step {
|
||||
Step::PickObject => {
|
||||
if self.edit_count == 0 {
|
||||
"TEXTEDIT Select an annotation object or [Undo Mode]:".to_string()
|
||||
t!("TEXTEDIT Select an annotation object or [Undo Mode]:").into_owned()
|
||||
} else {
|
||||
"TEXTEDIT Select an annotation object or [Undo Mode] <exit>:".to_string()
|
||||
t!("TEXTEDIT Select an annotation object or [Undo Mode] <exit>:").into_owned()
|
||||
}
|
||||
}
|
||||
Step::EnterMode => {
|
||||
let prefix = if self.invalid_mode {
|
||||
"Requires Single or Multiple. "
|
||||
format!("{} ", t!("Requires Single or Multiple."))
|
||||
} else {
|
||||
""
|
||||
String::new()
|
||||
};
|
||||
format!(
|
||||
"{prefix}TEXTEDIT Enter text edit mode [Single/Multiple] <{}>:",
|
||||
match self.mode {
|
||||
TextEditMode::Single => "Single",
|
||||
TextEditMode::Multiple => "Multiple",
|
||||
}
|
||||
let mode = match self.mode {
|
||||
TextEditMode::Single => t!("Single"),
|
||||
TextEditMode::Multiple => t!("Multiple"),
|
||||
};
|
||||
t!(
|
||||
"%{prefix}TEXTEDIT Enter text edit mode [Single/Multiple] <%{mode}>:",
|
||||
prefix = prefix,
|
||||
mode = mode
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -220,11 +224,16 @@ impl CadCommand for TexteditmodeCommand {
|
|||
fn prompt(&self) -> String {
|
||||
let v = if self.current { 1 } else { 0 };
|
||||
let prefix = if self.invalid {
|
||||
"Requires 0 OR 1 OR MULTIPLE OR SINGLE. "
|
||||
format!("{} ", t!("Requires 0 OR 1 OR MULTIPLE OR SINGLE."))
|
||||
} else {
|
||||
""
|
||||
String::new()
|
||||
};
|
||||
format!("{prefix}TEXTEDITMODE Enter new value for TEXTEDITMODE <{v}>:")
|
||||
t!(
|
||||
"%{prefix}TEXTEDITMODE Enter new value for TEXTEDITMODE <%{v}>:",
|
||||
prefix = prefix,
|
||||
v = v
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
|
||||
fn wants_text_input(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use glam::DVec3;
|
|||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/tolerance.svg"));
|
||||
|
||||
|
|
@ -46,8 +47,10 @@ impl CadCommand for ToleranceCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::Text => "TOLERANCE Enter tolerance text:".into(),
|
||||
Step::Insertion { text } => format!("TOLERANCE Specify insertion point [{text}]:"),
|
||||
Step::Text => t!("TOLERANCE Enter tolerance text:").into_owned(),
|
||||
Step::Insertion { text } => {
|
||||
t!("TOLERANCE Specify insertion point [%{text}]:", text = text).into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
// receives the dispatched `COPYBASE_AT <x> <y> <z>` token.
|
||||
|
||||
use glam::DVec3;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ impl CadCommand for CopyBaseCommand {
|
|||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
"COPYBASE Specify base point:".to_string()
|
||||
t!("COPYBASE Specify base point:").into_owned()
|
||||
}
|
||||
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ pub const MENU_ITEMS: &[(&str, &str, IconKind)] = &[
|
|||
|
||||
use acadrust::Handle;
|
||||
use glam::{DVec3, Vec3};
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
|
|
@ -103,7 +104,7 @@ impl CadCommand for PasteCommand {
|
|||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
"PASTECLIP Pick insertion point:".into()
|
||||
t!("PASTECLIP Pick insertion point:").into_owned()
|
||||
}
|
||||
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
use acadrust::types::Vector3;
|
||||
use acadrust::{Arc as CadArc, EntityType};
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::IconKind;
|
||||
|
|
@ -312,12 +313,20 @@ impl CadCommand for ArcCommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
0 => "ARC Specify center:".into(),
|
||||
1 => "ARC Specify start point:".into(),
|
||||
_ => format!(
|
||||
"ARC Specify end point [c=({:.2},{:.2}) r={:.3}]:",
|
||||
self.c.x, self.c.y, self.r
|
||||
),
|
||||
0 => t!("ARC Specify center:").into_owned(),
|
||||
1 => t!("ARC Specify start point:").into_owned(),
|
||||
_ => {
|
||||
let cx = format!("{:.2}", self.c.x);
|
||||
let cy = format!("{:.2}", self.c.y);
|
||||
let r = format!("{:.3}", self.r);
|
||||
t!(
|
||||
"ARC Specify end point [c=(%{cx},%{cy}) r=%{r}]:",
|
||||
cx = cx,
|
||||
cy = cy,
|
||||
r = r
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -437,9 +446,9 @@ impl CadCommand for Arc3PCommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match self.pts.len() {
|
||||
0 => "ARC 3P Specify start point:".into(),
|
||||
1 => "ARC 3P Specify second point on arc:".into(),
|
||||
_ => "ARC 3P Specify end point:".into(),
|
||||
0 => t!("ARC 3P Specify start point:").into_owned(),
|
||||
1 => t!("ARC 3P Specify second point on arc:").into_owned(),
|
||||
_ => t!("ARC 3P Specify end point:").into_owned(),
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -537,9 +546,12 @@ impl CadCommand for ArcSCECommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
0 => "ARC SCE Specify start point:".into(),
|
||||
1 => "ARC SCE Specify center:".into(),
|
||||
_ => format!("ARC SCE Specify end point [r={:.3}]:", self.r),
|
||||
0 => t!("ARC SCE Specify start point:").into_owned(),
|
||||
1 => t!("ARC SCE Specify center:").into_owned(),
|
||||
_ => {
|
||||
let r = format!("{:.3}", self.r);
|
||||
t!("ARC SCE Specify end point [r=%{r}]:", r = r).into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -637,12 +649,16 @@ impl CadCommand for ArcSCACommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
0 => "ARC SCA Specify start point:".into(),
|
||||
1 => "ARC SCA Specify center:".into(),
|
||||
_ => format!(
|
||||
"ARC SCA Click end direction or type arc span in degrees [start={:.1}°]:",
|
||||
self.sa.to_degrees()
|
||||
),
|
||||
0 => t!("ARC SCA Specify start point:").into_owned(),
|
||||
1 => t!("ARC SCA Specify center:").into_owned(),
|
||||
_ => {
|
||||
let sa = format!("{:.1}°", self.sa.to_degrees());
|
||||
t!(
|
||||
"ARC SCA Click end direction or type arc span in degrees [start=%{sa}]:",
|
||||
sa = sa
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -767,12 +783,16 @@ impl CadCommand for ArcSCLCommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
0 => "ARC SCL Specify start point:".into(),
|
||||
1 => "ARC SCL Specify center:".into(),
|
||||
_ => format!(
|
||||
"ARC SCL Click chord end or type chord length [r={:.3}]:",
|
||||
self.r
|
||||
),
|
||||
0 => t!("ARC SCL Specify start point:").into_owned(),
|
||||
1 => t!("ARC SCL Specify center:").into_owned(),
|
||||
_ => {
|
||||
let r = format!("{:.3}", self.r);
|
||||
t!(
|
||||
"ARC SCL Click chord end or type chord length [r=%{r}]:",
|
||||
r = r
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -871,9 +891,9 @@ impl CadCommand for ArcSEACommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
0 => "ARC SEA Specify start point:".into(),
|
||||
1 => "ARC SEA Specify end point:".into(),
|
||||
_ => "ARC SEA Specify angle (move cursor perpendicular to chord):".into(),
|
||||
0 => t!("ARC SEA Specify start point:").into_owned(),
|
||||
1 => t!("ARC SEA Specify end point:").into_owned(),
|
||||
_ => t!("ARC SEA Specify angle (move cursor perpendicular to chord):").into_owned(),
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -949,9 +969,9 @@ impl CadCommand for ArcSERCommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
0 => "ARC SER Specify start point:".into(),
|
||||
1 => "ARC SER Specify end point:".into(),
|
||||
_ => "ARC SER Click radius point or type radius value:".into(),
|
||||
0 => t!("ARC SER Specify start point:").into_owned(),
|
||||
1 => t!("ARC SER Specify end point:").into_owned(),
|
||||
_ => t!("ARC SER Click radius point or type radius value:").into_owned(),
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -1065,9 +1085,9 @@ impl CadCommand for ArcSEDCommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
0 => "ARC SED Specify start point:".into(),
|
||||
1 => "ARC SED Specify end point:".into(),
|
||||
_ => "ARC SED Specify tangent direction at start:".into(),
|
||||
0 => t!("ARC SED Specify start point:").into_owned(),
|
||||
1 => t!("ARC SED Specify end point:").into_owned(),
|
||||
_ => t!("ARC SED Specify tangent direction at start:").into_owned(),
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -1149,12 +1169,16 @@ impl CadCommand for ArcCSACommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
0 => "ARC CSA Specify center:".into(),
|
||||
1 => "ARC CSA Specify start point:".into(),
|
||||
_ => format!(
|
||||
"ARC CSA Click end direction or type arc span in degrees [start={:.1}°]:",
|
||||
self.sa.to_degrees()
|
||||
),
|
||||
0 => t!("ARC CSA Specify center:").into_owned(),
|
||||
1 => t!("ARC CSA Specify start point:").into_owned(),
|
||||
_ => {
|
||||
let sa = format!("{:.1}°", self.sa.to_degrees());
|
||||
t!(
|
||||
"ARC CSA Click end direction or type arc span in degrees [start=%{sa}]:",
|
||||
sa = sa
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -1274,12 +1298,16 @@ impl CadCommand for ArcCSLCommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
0 => "ARC CSL Specify center:".into(),
|
||||
1 => "ARC CSL Specify start point:".into(),
|
||||
_ => format!(
|
||||
"ARC CSL Click chord end or type chord length [r={:.3}]:",
|
||||
self.r
|
||||
),
|
||||
0 => t!("ARC CSL Specify center:").into_owned(),
|
||||
1 => t!("ARC CSL Specify start point:").into_owned(),
|
||||
_ => {
|
||||
let r = format!("{:.3}", self.r);
|
||||
t!(
|
||||
"ARC CSL Click chord end or type chord length [r=%{r}]:",
|
||||
r = r
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -1386,7 +1414,7 @@ impl CadCommand for ArcContCommand {
|
|||
"ARC_CONT"
|
||||
}
|
||||
fn prompt(&self) -> String {
|
||||
"ARC Continue Specify end point [Ctrl = flip direction]:".into()
|
||||
t!("ARC Continue Specify end point [Ctrl = flip direction]:").into_owned()
|
||||
}
|
||||
fn set_ctrl(&mut self, ctrl: bool) {
|
||||
self.ctrl = ctrl;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use acadrust::entities::AttributeDefinition;
|
|||
use acadrust::types::Vector3;
|
||||
use acadrust::EntityType;
|
||||
use glam::DVec3;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
|
|
@ -52,12 +53,22 @@ impl CadCommand for AttdefCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::Tag => "ATTDEF Enter attribute tag (no spaces):".into(),
|
||||
Step::Prompt { tag } => format!("ATTDEF Enter prompt for '{tag}' (Enter=use tag):"),
|
||||
Step::Default { tag, .. } => {
|
||||
format!("ATTDEF Enter default value for '{tag}' (Enter=blank):")
|
||||
}
|
||||
Step::Insertion { tag, .. } => format!("ATTDEF Specify insertion point for '{tag}':"),
|
||||
Step::Tag => t!("ATTDEF Enter attribute tag (no spaces):").into_owned(),
|
||||
Step::Prompt { tag } => t!(
|
||||
"ATTDEF Enter prompt for '%{tag}' (Enter=use tag):",
|
||||
tag = tag
|
||||
)
|
||||
.into_owned(),
|
||||
Step::Default { tag, .. } => t!(
|
||||
"ATTDEF Enter default value for '%{tag}' (Enter=blank):",
|
||||
tag = tag
|
||||
)
|
||||
.into_owned(),
|
||||
Step::Insertion { tag, .. } => t!(
|
||||
"ATTDEF Specify insertion point for '%{tag}':",
|
||||
tag = tag
|
||||
)
|
||||
.into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
use acadrust::types::Vector3;
|
||||
use acadrust::{EntityType, Handle, Line};
|
||||
use glam::DVec3;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
|
|
@ -216,9 +217,9 @@ impl CadCommand for CenterLineCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.first.is_none() {
|
||||
"CENTERLINE Select first line:".to_string()
|
||||
t!("CENTERLINE Select first line:").into_owned()
|
||||
} else {
|
||||
"CENTERLINE Select second line:".to_string()
|
||||
t!("CENTERLINE Select second line:").into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
use acadrust::types::Vector3;
|
||||
use acadrust::{Circle, EntityType};
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult, DynField, TangentObject};
|
||||
use crate::modules::draw::defaults;
|
||||
|
|
@ -135,11 +136,19 @@ impl CadCommand for CircleCommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
StepCR::Center => "CIRCLE Specify center point:".into(),
|
||||
StepCR::Radius(c) => format!(
|
||||
"CIRCLE Specify radius or type value <{:.4}> [center ({:.3},{:.3})]:",
|
||||
self.default_r, c.x, c.y
|
||||
),
|
||||
StepCR::Center => t!("CIRCLE Specify center point:").into_owned(),
|
||||
StepCR::Radius(c) => {
|
||||
let r = format!("{:.4}", self.default_r);
|
||||
let cx = format!("{:.3}", c.x);
|
||||
let cy = format!("{:.3}", c.y);
|
||||
t!(
|
||||
"CIRCLE Specify radius or type value <%{r}> [center (%{cx},%{cy})]:",
|
||||
r = r,
|
||||
cx = cx,
|
||||
cy = cy
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +160,7 @@ impl CadCommand for CircleCommand {
|
|||
CmdOption::new("2P", "2P"),
|
||||
CmdOption::new("Ttr", "TTR"),
|
||||
CmdOption::new("Ttt", "TTT"),
|
||||
CmdOption::new("Diameter", "D"),
|
||||
CmdOption::new(t!("Diameter").as_ref(), "D"),
|
||||
],
|
||||
StepCR::Radius(_) => vec![],
|
||||
}
|
||||
|
|
@ -259,11 +268,12 @@ impl CadCommand for CircleCDCommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
StepCR::Center => "CIRCLE CD Specify center point:".into(),
|
||||
StepCR::Radius(c) => format!(
|
||||
StepCR::Center => t!("CIRCLE CD Specify center point:").into_owned(),
|
||||
StepCR::Radius(c) => crate::tf!(
|
||||
"CIRCLE CD Specify diameter or type value <{:.4}> [center ({:.3},{:.3})]:",
|
||||
self.default_d, c.x, c.y
|
||||
),
|
||||
)
|
||||
.into_owned(),
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -343,9 +353,9 @@ impl CadCommand for Circle2PCommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
if self.p1.is_none() {
|
||||
"CIRCLE 2P Specify first end of diameter:".into()
|
||||
crate::t!("CIRCLE 2P Specify first end of diameter:").into_owned()
|
||||
} else {
|
||||
"CIRCLE 2P Specify second end of diameter:".into()
|
||||
crate::t!("CIRCLE 2P Specify second end of diameter:").into_owned()
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -393,9 +403,9 @@ impl CadCommand for Circle3PCommand {
|
|||
}
|
||||
fn prompt(&self) -> String {
|
||||
match self.pts.len() {
|
||||
0 => "CIRCLE 3P Specify first point:".into(),
|
||||
1 => "CIRCLE 3P Specify second point:".into(),
|
||||
_ => "CIRCLE 3P Specify third point:".into(),
|
||||
0 => crate::t!("CIRCLE 3P Specify first point:").into_owned(),
|
||||
1 => crate::t!("CIRCLE 3P Specify second point:").into_owned(),
|
||||
_ => crate::t!("CIRCLE 3P Specify third point:").into_owned(),
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
@ -897,9 +907,9 @@ impl CadCommand for CircleTTRCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
StepTTR::First => "CIRCLE TTR Select first tangent object:".into(),
|
||||
StepTTR::Second { .. } => "CIRCLE TTR Select second tangent object:".into(),
|
||||
StepTTR::Radius { .. } => "CIRCLE TTR Specify radius:".into(),
|
||||
StepTTR::First => crate::t!("CIRCLE TTR Select first tangent object:").into_owned(),
|
||||
StepTTR::Second { .. } => crate::t!("CIRCLE TTR Select second tangent object:").into_owned(),
|
||||
StepTTR::Radius { .. } => crate::t!("CIRCLE TTR Specify radius:").into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -992,9 +1002,9 @@ impl CadCommand for CircleTTTCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match self.objs.len() {
|
||||
0 => "CIRCLE TTT Select first tangent object:".into(),
|
||||
1 => "CIRCLE TTT Select second tangent object:".into(),
|
||||
_ => "CIRCLE TTT Select third tangent object:".into(),
|
||||
0 => crate::t!("CIRCLE TTT Select first tangent object:").into_owned(),
|
||||
1 => crate::t!("CIRCLE TTT Select second tangent object:").into_owned(),
|
||||
_ => crate::t!("CIRCLE TTT Select third tangent object:").into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue