feat(locale): localize full interface
This commit is contained in:
parent
b90b3e3ecf
commit
3e6693b93f
205 changed files with 32367 additions and 3808 deletions
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,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};
|
||||
|
|
@ -72,7 +73,7 @@ impl CadCommand for DimCenterCommand {
|
|||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
"DIMCENTER Select arc or circle:".to_string()
|
||||
t!("DIMCENTER Select arc or circle:").into_owned()
|
||||
}
|
||||
|
||||
fn needs_entity_pick(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
use acadrust::entities::{LwPolyline, LwVertex};
|
||||
use acadrust::EntityType;
|
||||
use glam::DVec3;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
|
||||
|
|
@ -45,9 +46,11 @@ impl CadCommand for DonutCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.state {
|
||||
DonutState::AskInner => "DONUT Specify inside diameter <0>:".into(),
|
||||
DonutState::AskOuter => "DONUT Specify outside diameter:".into(),
|
||||
DonutState::PlaceCenter => "DONUT Specify center of donut (Enter to exit):".into(),
|
||||
DonutState::AskInner => t!("DONUT Specify inside diameter <0>:").into_owned(),
|
||||
DonutState::AskOuter => t!("DONUT Specify outside diameter:").into_owned(),
|
||||
DonutState::PlaceCenter => {
|
||||
t!("DONUT Specify center of donut (Enter to exit):").into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
use acadrust::types::Vector3;
|
||||
use acadrust::{Ellipse, EntityType};
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::modules::IconKind;
|
||||
|
|
@ -126,12 +127,13 @@ impl CadCommand for EllipseCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
CtrStep::Center => "ELLIPSE Specify center:".into(),
|
||||
CtrStep::MajorAxis { .. } => "ELLIPSE Specify major axis endpoint:".into(),
|
||||
CtrStep::MinorRatio { major, .. } => format!(
|
||||
CtrStep::Center => t!("ELLIPSE Specify center:").into_owned(),
|
||||
CtrStep::MajorAxis { .. } => t!("ELLIPSE Specify major axis endpoint:").into_owned(),
|
||||
CtrStep::MinorRatio { major, .. } => crate::tf!(
|
||||
"ELLIPSE Specify minor axis point or type half-length [major r={:.3}]:",
|
||||
major.length()
|
||||
),
|
||||
)
|
||||
.into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,12 +267,17 @@ impl CadCommand for EllipseAxisCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
AxisStep::Pt1 => "ELLIPSE (Axis) Specify first endpoint of major axis:".into(),
|
||||
AxisStep::Pt2 { .. } => "ELLIPSE (Axis) Specify second endpoint of major axis:".into(),
|
||||
AxisStep::MinorRatio { major, .. } => format!(
|
||||
AxisStep::Pt1 => {
|
||||
t!("ELLIPSE (Axis) Specify first endpoint of major axis:").into_owned()
|
||||
}
|
||||
AxisStep::Pt2 { .. } => {
|
||||
t!("ELLIPSE (Axis) Specify second endpoint of major axis:").into_owned()
|
||||
}
|
||||
AxisStep::MinorRatio { major, .. } => crate::tf!(
|
||||
"ELLIPSE (Axis) Specify minor axis point or type half-length [major r={:.3}]:",
|
||||
major.length()
|
||||
),
|
||||
)
|
||||
.into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -397,19 +404,27 @@ impl CadCommand for EllipseArcCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
ArcStep::Center => "ELLIPSE ARC Specify center:".into(),
|
||||
ArcStep::MajorAxis { .. } => "ELLIPSE ARC Specify major axis endpoint:".into(),
|
||||
ArcStep::MinorRatio { major, .. } => format!(
|
||||
"ELLIPSE ARC Specify minor axis point or type half-length [major r={:.3}]:",
|
||||
major.length()
|
||||
),
|
||||
ArcStep::StartAngle { .. } => {
|
||||
"ELLIPSE ARC Specify start angle point or type degrees:".into()
|
||||
ArcStep::Center => t!("ELLIPSE ARC Specify center:").into_owned(),
|
||||
ArcStep::MajorAxis { .. } => t!("ELLIPSE ARC Specify major axis endpoint:").into_owned(),
|
||||
ArcStep::MinorRatio { major, .. } => {
|
||||
let r = format!("{:.3}", major.length());
|
||||
t!(
|
||||
"ELLIPSE ARC Specify minor axis point or type half-length [major r=%{r}]:",
|
||||
r = r
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
ArcStep::StartAngle { .. } => {
|
||||
t!("ELLIPSE ARC Specify start angle point or type degrees:").into_owned()
|
||||
}
|
||||
ArcStep::EndAngle { t_start, .. } => {
|
||||
let sa = format!("{:.1}°", t_start.to_degrees());
|
||||
t!(
|
||||
"ELLIPSE ARC Specify end angle point or type degrees [start=%{sa}]:",
|
||||
sa = sa
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
ArcStep::EndAngle { t_start, .. } => format!(
|
||||
"ELLIPSE ARC Specify end angle point or type degrees [start={:.1}°]:",
|
||||
t_start.to_degrees()
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use crate::modules::IconKind;
|
|||
use crate::scene::model::hatch_model::{HatchModel, HatchPattern, PatFamily};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use glam::DVec3;
|
||||
use crate::t;
|
||||
|
||||
// ── Icons ──────────────────────────────────────────────────────────────────
|
||||
|
||||
|
|
@ -258,17 +259,18 @@ impl CadCommand for HatchCommand {
|
|||
match &self.mode {
|
||||
Mode::PickInside => {
|
||||
let miss = if self.missed {
|
||||
" ⚠ No closed boundary found."
|
||||
t!(" ⚠ No closed boundary found.").into_owned()
|
||||
} else {
|
||||
""
|
||||
String::new()
|
||||
};
|
||||
format!("HATCH Pick internal point:{miss}")
|
||||
t!("HATCH Pick internal point:%{miss}", miss = miss).into_owned()
|
||||
}
|
||||
Mode::Manual => {
|
||||
if self.manual_pts.is_empty() {
|
||||
"HATCH Boundary point 1:".into()
|
||||
t!("HATCH Boundary point 1:").into_owned()
|
||||
} else {
|
||||
format!("HATCH Point {}:", self.manual_pts.len() + 1)
|
||||
let n = self.manual_pts.len() + 1;
|
||||
t!("HATCH Point %{n}:", n = n).into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -277,11 +279,11 @@ impl CadCommand for HatchCommand {
|
|||
fn options(&self) -> Vec<crate::command::CmdOption> {
|
||||
use crate::command::CmdOption;
|
||||
match &self.mode {
|
||||
Mode::PickInside => vec![CmdOption::new("Draw manually", "S")],
|
||||
Mode::PickInside => vec![CmdOption::new(t!("Draw manually").as_ref(), "S")],
|
||||
Mode::Manual => {
|
||||
// Enter accepts the boundary once at least 3 points are picked.
|
||||
if self.manual_pts.len() >= 3 {
|
||||
vec![CmdOption::enter("Accept")]
|
||||
vec![CmdOption::enter(t!("Accept").as_ref())]
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
|
|
@ -427,21 +429,28 @@ impl CadCommand for GradientCommand {
|
|||
match &self.mode {
|
||||
Mode::PickInside => {
|
||||
let miss = if self.missed {
|
||||
" ⚠ No closed boundary found."
|
||||
t!(" ⚠ No closed boundary found.")
|
||||
} else {
|
||||
""
|
||||
std::borrow::Cow::Borrowed("")
|
||||
};
|
||||
format!(
|
||||
"GRADIENT ({}{}) Pick internal point:{miss}",
|
||||
self.kind.label(),
|
||||
if self.invert { ", inverted" } else { "" }
|
||||
let invert = if self.invert {
|
||||
t!(", inverted")
|
||||
} else {
|
||||
std::borrow::Cow::Borrowed("")
|
||||
};
|
||||
t!(
|
||||
"GRADIENT (%{kind}%{invert}) Pick internal point:%{miss}",
|
||||
kind = t!(self.kind.label()),
|
||||
invert = invert,
|
||||
miss = miss
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
Mode::Manual => {
|
||||
if self.manual_pts.is_empty() {
|
||||
"GRADIENT Boundary point 1:".into()
|
||||
t!("GRADIENT Boundary point 1:").into_owned()
|
||||
} else {
|
||||
format!("GRADIENT Point {}:", self.manual_pts.len() + 1)
|
||||
t!("GRADIENT Point %{n}:", n = self.manual_pts.len() + 1).into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -592,11 +601,11 @@ impl CadCommand for BoundaryCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
let miss = if self.missed {
|
||||
" ⚠ No closed boundary found."
|
||||
t!(" ⚠ No closed boundary found.").into_owned()
|
||||
} else {
|
||||
""
|
||||
String::new()
|
||||
};
|
||||
format!("BOUNDARY Pick internal point:{miss}")
|
||||
t!("BOUNDARY Pick internal point:%{miss}", miss = miss).into_owned()
|
||||
}
|
||||
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
use acadrust::Handle;
|
||||
use glam::DVec3;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
|
||||
|
|
@ -53,13 +54,20 @@ impl CadCommand for HatcheditCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
HatcheditStep::PickHatch => "HATCHEDIT Select hatch:".into(),
|
||||
HatcheditStep::PickHatch => t!("HATCHEDIT Select hatch:").into_owned(),
|
||||
HatcheditStep::EditOptions {
|
||||
name, scale, angle, ..
|
||||
} => format!(
|
||||
"HATCHEDIT Pattern:{name} Scale:{scale:.4} Angle:{angle:.1} \
|
||||
[P <pat> / S <scale> / A <angle> | Enter to apply]:"
|
||||
),
|
||||
} => {
|
||||
let scale = format!("{scale:.4}");
|
||||
let angle = format!("{angle:.1}");
|
||||
t!(
|
||||
"HATCHEDIT Pattern:%{name} Scale:%{scale} Angle:%{angle} [P <pat> / S <scale> / A <angle> | Enter to apply]:",
|
||||
name = name,
|
||||
scale = scale,
|
||||
angle = angle
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
use acadrust::entities::Polyline3D;
|
||||
use acadrust::types::Vector3;
|
||||
use acadrust::EntityType;
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult, DynField};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
|
|
@ -115,11 +116,11 @@ impl CadCommand for HelixCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
Step::Center => "HELIX Specify centre point of base:".to_string(),
|
||||
Step::BaseRadius => "HELIX Specify base radius:".to_string(),
|
||||
Step::TopRadius => "HELIX Specify top radius <same as base>:".to_string(),
|
||||
Step::Height => "HELIX Specify helix height:".to_string(),
|
||||
Step::Turns => "HELIX Enter number of turns <3>:".to_string(),
|
||||
Step::Center => t!("HELIX Specify centre point of base:").into_owned(),
|
||||
Step::BaseRadius => t!("HELIX Specify base radius:").into_owned(),
|
||||
Step::TopRadius => t!("HELIX Specify top radius <same as base>:").into_owned(),
|
||||
Step::Height => t!("HELIX Specify helix height:").into_owned(),
|
||||
Step::Turns => t!("HELIX Enter number of turns <3>:").into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
use acadrust::types::Vector3;
|
||||
use acadrust::{EntityType, Line};
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult, TangentObject};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
|
|
@ -64,9 +65,9 @@ impl CadCommand for LineCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
match self.points.len() {
|
||||
0 => "LINE Specify first point:".to_string(),
|
||||
1 => "LINE Specify next point [Undo]:".to_string(),
|
||||
_ => "LINE Specify next point [Close/Undo]:".to_string(),
|
||||
0 => t!("LINE Specify first point:").into_owned(),
|
||||
1 => t!("LINE Specify next point [Undo]:").into_owned(),
|
||||
_ => t!("LINE Specify next point [Close/Undo]:").into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use acadrust::entities::MLine;
|
|||
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;
|
||||
|
|
@ -48,14 +49,19 @@ impl CadCommand for MlineCommand {
|
|||
|
||||
fn prompt(&self) -> String {
|
||||
if self.waiting_scale {
|
||||
"MLINE Enter scale factor:".into()
|
||||
t!("MLINE Enter scale factor:").into_owned()
|
||||
} else if self.points.is_empty() {
|
||||
format!("MLINE Specify start point (scale={:.2}):", self.scale)
|
||||
} else {
|
||||
format!(
|
||||
"MLINE Specify next point ({} pts, Enter to finish, C to close, S to set scale):",
|
||||
self.points.len()
|
||||
t!(
|
||||
"MLINE Specify start point (scale=%{scale}):",
|
||||
scale = format!("{:.2}", self.scale)
|
||||
)
|
||||
.into_owned()
|
||||
} else {
|
||||
t!(
|
||||
"MLINE Specify next point (%{count} pts, Enter to finish, C to close, S to set scale):",
|
||||
count = self.points.len()
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue