feat(locale): localize full interface
This commit is contained in:
parent
b90b3e3ecf
commit
3e6693b93f
205 changed files with 32367 additions and 3808 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -172,7 +172,7 @@ impl OpenCADStudio {
|
||||||
tasks.push(self.apply_cmd_result(CmdResult::CancelForSpaceChange));
|
tasks.push(self.apply_cmd_result(CmdResult::CancelForSpaceChange));
|
||||||
} else if message_pending {
|
} else if message_pending {
|
||||||
self.command_line
|
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;
|
cancellation_reported = true;
|
||||||
}
|
}
|
||||||
|
|
@ -186,7 +186,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if !cancellation_reported && (grip_cancelled || suspended_cancelled || editor_cancelled) {
|
if !cancellation_reported && (grip_cancelled || suspended_cancelled || editor_cancelled) {
|
||||||
self.command_line
|
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();
|
self.command_line.input.clear();
|
||||||
|
|
@ -210,7 +210,7 @@ impl OpenCADStudio {
|
||||||
.is_some_and(|command| command.name() != "LIMITS")
|
.is_some_and(|command| command.name() != "LIMITS")
|
||||||
&& self.tabs[i].scene.drawing_limit_check_enabled();
|
&& self.tabs[i].scene.drawing_limit_check_enabled();
|
||||||
if checks_limits && !self.tabs[i].scene.point_inside_drawing_limits(point) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
|
|
@ -389,7 +389,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.select_entity(h, false);
|
self.tabs[i].scene.select_entity(h, false);
|
||||||
}
|
}
|
||||||
self.command_line
|
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();
|
self.refresh_properties();
|
||||||
let handles: Vec<Handle> = self.tabs[i]
|
let handles: Vec<Handle> = self.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
|
|
@ -754,7 +754,7 @@ impl OpenCADStudio {
|
||||||
});
|
});
|
||||||
let Some((min_x, min_y, max_x, max_y)) = bounds else {
|
let Some((min_x, min_y, max_x, max_y)) = bounds else {
|
||||||
self.command_line
|
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;
|
self.tabs[i].active_cmd = None;
|
||||||
if let Some(pending) = pending {
|
if let Some(pending) = pending {
|
||||||
self.commit_undo_delta(i, 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 {
|
if max_x - min_x < 1e-6 || max_y - min_y < 1e-6 {
|
||||||
self.command_line
|
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;
|
self.tabs[i].active_cmd = None;
|
||||||
if let Some(pending) = pending {
|
if let Some(pending) = pending {
|
||||||
self.commit_undo_delta(i, pending);
|
self.commit_undo_delta(i, pending);
|
||||||
|
|
@ -1051,7 +1051,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].active_cmd = None;
|
self.tabs[i].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Block \"{name}\" created."));
|
.push_output(crate::tf!("Block \"{name}\" created.").as_ref());
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|
@ -1098,7 +1098,7 @@ impl OpenCADStudio {
|
||||||
self.restore_pre_cmd_tangent();
|
self.restore_pre_cmd_tangent();
|
||||||
let noun = if count == 1 { "copy" } else { "copies" };
|
let noun = if count == 1 { "copy" } else { "copies" };
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("{label}: {count} {noun} created."));
|
.push_output(crate::tf!("{label}: {count} {noun} created.").as_ref());
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
if let Some(pd) = pending {
|
if let Some(pd) = pending {
|
||||||
self.commit_undo_delta(i, pd);
|
self.commit_undo_delta(i, pd);
|
||||||
|
|
@ -1133,7 +1133,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
if was_catchment {
|
if was_catchment {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info("Catchment tagged successfully.");
|
.push_info(crate::t!("Catchment tagged successfully.").as_ref());
|
||||||
}
|
}
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
|
|
@ -1171,7 +1171,7 @@ impl OpenCADStudio {
|
||||||
// Report honestly rather than claiming success while
|
// Report honestly rather than claiming success while
|
||||||
// changing nothing. (#181 / DIM-020)
|
// changing nothing. (#181 / DIM-020)
|
||||||
self.command_line
|
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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
return Task::none();
|
return Task::none();
|
||||||
|
|
@ -1181,7 +1181,7 @@ impl OpenCADStudio {
|
||||||
apply_dimspace(&mut self.tabs[i].scene, encoded);
|
apply_dimspace(&mut self.tabs[i].scene, encoded);
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "DIMSPACE");
|
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].dirty = true;
|
||||||
self.tabs[i].active_cmd = None;
|
self.tabs[i].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
|
|
@ -1192,7 +1192,7 @@ impl OpenCADStudio {
|
||||||
// model (not yet present) to store and render the jog.
|
// model (not yet present) to store and render the jog.
|
||||||
// Report honestly rather than faking success. (DIM-019)
|
// Report honestly rather than faking success. (DIM-019)
|
||||||
self.command_line
|
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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
return Task::none();
|
return Task::none();
|
||||||
|
|
@ -1203,7 +1203,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "MLEADERALIGN");
|
self.push_undo_snapshot(i, "MLEADERALIGN");
|
||||||
self.command_line
|
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].dirty = true;
|
||||||
self.tabs[i].active_cmd = None;
|
self.tabs[i].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
|
|
@ -1215,7 +1215,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "MLEADERCOLLECT");
|
self.push_undo_snapshot(i, "MLEADERCOLLECT");
|
||||||
self.command_line
|
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].dirty = true;
|
||||||
self.tabs[i].active_cmd = None;
|
self.tabs[i].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
|
|
@ -1461,10 +1461,10 @@ impl OpenCADStudio {
|
||||||
self.invalidate_property_targets(i, &dest);
|
self.invalidate_property_targets(i, &dest);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info(&format!("Layer matched to \"{layer}\"."));
|
.push_info(crate::tf!("Layer matched to \"{layer}\".").as_ref());
|
||||||
self.sync_ribbon_layers();
|
self.sync_ribbon_layers();
|
||||||
} else {
|
} 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 } => {
|
CmdResult::MatchProperties { dest, src } => {
|
||||||
|
|
@ -1605,14 +1605,14 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.bump_entities(&changes);
|
self.tabs[i].scene.bump_entities(&changes);
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
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.
|
// Clear the consumed target selection and keep prompting.
|
||||||
self.tabs[i].scene.deselect_all();
|
self.tabs[i].scene.deselect_all();
|
||||||
if let Some(cmd) = &self.tabs[i].active_cmd {
|
if let Some(cmd) = &self.tabs[i].active_cmd {
|
||||||
self.command_line.push_info(&cmd.prompt());
|
self.command_line.push_info(&cmd.prompt());
|
||||||
}
|
}
|
||||||
} else {
|
} 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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
self.tabs[i].scene.clear_preview_wire();
|
self.tabs[i].scene.clear_preview_wire();
|
||||||
|
|
@ -1623,7 +1623,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
self.tabs[i].scene.clear_preview_wire();
|
self.tabs[i].scene.clear_preview_wire();
|
||||||
if self.clipboard.is_empty() {
|
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 {
|
} else {
|
||||||
let delta = base_pt - self.clipboard_base;
|
let delta = base_pt - self.clipboard_base;
|
||||||
let translate = crate::command::EntityTransform::Translate(delta);
|
let translate = crate::command::EntityTransform::Translate(delta);
|
||||||
|
|
@ -1640,7 +1640,7 @@ impl OpenCADStudio {
|
||||||
self.refresh_layer_panel();
|
self.refresh_layer_panel();
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info(&format!("{count} object(s) pasted."));
|
.push_info(crate::tf!("{count} object(s) pasted.").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CmdResult::CreateGroup { handles, name } => {
|
CmdResult::CreateGroup { handles, name } => {
|
||||||
|
|
@ -1652,7 +1652,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.commit_group_undo(i, undo);
|
self.commit_group_undo(i, undo);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info(&format!("Group \"{}\" created.", name));
|
.push_info(crate::tf!("Group \"{}\" created.", name).as_ref());
|
||||||
}
|
}
|
||||||
CmdResult::DeleteGroups { handles } => {
|
CmdResult::DeleteGroups { handles } => {
|
||||||
self.tabs[i].active_cmd = None;
|
self.tabs[i].active_cmd = None;
|
||||||
|
|
@ -1664,10 +1664,10 @@ impl OpenCADStudio {
|
||||||
self.commit_group_undo(i, undo);
|
self.commit_group_undo(i, undo);
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info(&format!("{} group(s) dissolved.", count));
|
.push_info(crate::tf!("{} group(s) dissolved.", count).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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 {
|
CmdResult::VpLayerUpdate {
|
||||||
|
|
@ -1747,14 +1747,14 @@ impl OpenCADStudio {
|
||||||
self.push_undo_snapshot(i, "VPLAYER");
|
self.push_undo_snapshot(i, "VPLAYER");
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
if frozen_count > 0 {
|
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."
|
"VPLAYER: {frozen_count} layer(s) frozen in viewport."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
if thawed_count > 0 {
|
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."
|
"VPLAYER: {thawed_count} layer(s) thawed in viewport."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
// Sync layer panel so VP freeze columns update immediately.
|
// Sync layer panel so VP freeze columns update immediately.
|
||||||
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
||||||
|
|
@ -1778,7 +1778,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i]
|
self.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.zoom_to_window(p1.as_vec3(), p2.as_vec3());
|
.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) => {
|
CmdResult::Measurement(msg) => {
|
||||||
self.tabs[i].active_cmd = None;
|
self.tabs[i].active_cmd = None;
|
||||||
|
|
@ -1844,7 +1844,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].active_cmd = None;
|
self.tabs[i].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
self.restore_pre_cmd_tangent();
|
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();
|
self.refresh_properties();
|
||||||
if let Some(pd) = pending {
|
if let Some(pd) = pending {
|
||||||
self.commit_undo_delta(i, pd);
|
self.commit_undo_delta(i, pd);
|
||||||
|
|
@ -1869,12 +1869,12 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.erase_entities(&[handle]);
|
self.tabs[i].scene.erase_entities(&[handle]);
|
||||||
self.tabs[i].scene.add_entity(new_entity);
|
self.tabs[i].scene.add_entity(new_entity);
|
||||||
self.tabs[i].dirty = true;
|
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();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.command_line
|
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;
|
self.tabs[i].active_cmd = None;
|
||||||
|
|
@ -1898,10 +1898,10 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("DIVIDE: {count} point(s) placed."));
|
.push_output(crate::tf!("DIVIDE: {count} point(s) placed.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
|
|
@ -1927,10 +1927,10 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("MEASURE: {count} point(s) placed."));
|
.push_output(crate::tf!("MEASURE: {count} point(s) placed.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
|
|
@ -1956,7 +1956,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
None => self
|
None => self
|
||||||
.command_line
|
.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]
|
self.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.bump_entities(&[(handle, crate::scene::ChangeKind::Modified)]);
|
.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();
|
self.refresh_properties();
|
||||||
} else {
|
} else {
|
||||||
self.discard_last_undo_entry(i);
|
self.discard_last_undo_entry(i);
|
||||||
self.command_line
|
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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
self.restore_pre_cmd_tangent();
|
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}."
|
"JOIN: {count_in} object(s) joined into {count_out}."
|
||||||
));
|
).as_ref());
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -2049,7 +2049,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
self.restore_pre_cmd_tangent();
|
self.restore_pre_cmd_tangent();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("BREAK: {} fragment(s).", count));
|
.push_output(crate::tf!("BREAK: {} fragment(s).", count).as_ref());
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -2058,7 +2058,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.clear_preview_wire();
|
self.tabs[i].scene.clear_preview_wire();
|
||||||
self.restore_pre_cmd_tangent();
|
self.restore_pre_cmd_tangent();
|
||||||
self.command_line
|
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);
|
let y1 = p1.y.max(p2.y);
|
||||||
self.plot_window = Some((x0, y0, x1, y1));
|
self.plot_window = Some((x0, y0, x1, y1));
|
||||||
self.command_line
|
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
|
// Pick window closed the plot dialog so the viewport could
|
||||||
// receive the two clicks — bring the dialog back with the
|
// receive the two clicks — bring the dialog back with the
|
||||||
// window now active.
|
// window now active.
|
||||||
|
|
@ -2089,9 +2089,9 @@ impl OpenCADStudio {
|
||||||
let x2 = p1.x.max(p2.x);
|
let x2 = p1.x.max(p2.x);
|
||||||
let y2 = p1.y.max(p2.y);
|
let y2 = p1.y.max(p2.y);
|
||||||
self.plot_window = Some((x1, y1, x2, y2));
|
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}"
|
"Plot window: {x1:.2},{y1:.2} to {x2:.2},{y2:.2}"
|
||||||
));
|
).as_ref());
|
||||||
self.plot_dialog.area = "Window".to_string();
|
self.plot_dialog.area = "Window".to_string();
|
||||||
self.active_modal = Some(super::ModalKind::Plot);
|
self.active_modal = Some(super::ModalKind::Plot);
|
||||||
}
|
}
|
||||||
|
|
@ -2127,7 +2127,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
self.tabs[i].scene.clear_preview_wire();
|
self.tabs[i].scene.clear_preview_wire();
|
||||||
|
|
@ -2395,7 +2395,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.clear_preview_wire();
|
self.tabs[i].scene.clear_preview_wire();
|
||||||
self.restore_pre_cmd_tangent();
|
self.restore_pre_cmd_tangent();
|
||||||
self.command_line
|
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();
|
self.refresh_properties();
|
||||||
if let Some(pending) = pending {
|
if let Some(pending) = pending {
|
||||||
self.commit_undo_delta(i, pending);
|
self.commit_undo_delta(i, pending);
|
||||||
|
|
@ -2418,7 +2418,7 @@ impl OpenCADStudio {
|
||||||
.insert(handle, crate::scene::MeshLodSet::from_single(mesh));
|
.insert(handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
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 {
|
if let Some(pd) = pending {
|
||||||
self.commit_undo_delta(i, pd);
|
self.commit_undo_delta(i, pd);
|
||||||
|
|
@ -2492,15 +2492,15 @@ impl OpenCADStudio {
|
||||||
// ACIS geometry (else the solid is dropped by other CAD apps).
|
// ACIS geometry (else the solid is dropped by other CAD apps).
|
||||||
self.tabs[i].scene.solid_models.insert(new_handle, solid);
|
self.tabs[i].scene.solid_models.insert(new_handle, solid);
|
||||||
self.tabs[i].dirty = true;
|
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 {
|
if let Some(pd) = pending {
|
||||||
self.commit_undo_delta(i, pd);
|
self.commit_undo_delta(i, pd);
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
} 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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
|
|
@ -2577,16 +2577,16 @@ impl OpenCADStudio {
|
||||||
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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 {
|
if let Some(pd) = pending {
|
||||||
self.commit_undo_delta(i, pd);
|
self.commit_undo_delta(i, pd);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("REVOLVE: could not revolve profile.");
|
.push_error(crate::t!("REVOLVE: could not revolve profile.").as_ref());
|
||||||
}
|
}
|
||||||
} else {
|
} 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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
|
|
@ -2755,12 +2755,12 @@ impl OpenCADStudio {
|
||||||
.meshes
|
.meshes
|
||||||
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||||
self.tabs[i].dirty = true;
|
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 {
|
if let Some(pd) = pending {
|
||||||
self.commit_undo_delta(i, pd);
|
self.commit_undo_delta(i, pd);
|
||||||
}
|
}
|
||||||
} else {
|
} 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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
|
|
@ -2849,15 +2849,15 @@ impl OpenCADStudio {
|
||||||
.meshes
|
.meshes
|
||||||
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"LOFT: solid created from {} profiles.",
|
"LOFT: solid created from {} profiles.",
|
||||||
handles.len()
|
handles.len()
|
||||||
));
|
).as_ref());
|
||||||
if let Some(pd) = pending {
|
if let Some(pd) = pending {
|
||||||
self.commit_undo_delta(i, pd);
|
self.commit_undo_delta(i, pd);
|
||||||
}
|
}
|
||||||
} else {
|
} 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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
|
|
@ -2893,10 +2893,10 @@ impl OpenCADStudio {
|
||||||
// Re-add with updated model
|
// Re-add with updated model
|
||||||
self.tabs[i].scene.add_hatch(model);
|
self.tabs[i].scene.add_hatch(model);
|
||||||
self.tabs[i].dirty = true;
|
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 {
|
} else {
|
||||||
self.command_line
|
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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = 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);
|
crate::app::text_inline::can_edit_text(handle, &self.tabs[i].scene.document);
|
||||||
if !is_editable {
|
if !is_editable {
|
||||||
self.command_line
|
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());
|
let prompt = self.tabs[i].active_cmd.as_ref().map(|c| c.prompt());
|
||||||
if let Some(p) = prompt {
|
if let Some(p) = prompt {
|
||||||
self.command_line.push_info(&p);
|
self.command_line.push_info(&p);
|
||||||
|
|
@ -2970,7 +2970,7 @@ impl OpenCADStudio {
|
||||||
self.texteditmode = val;
|
self.texteditmode = val;
|
||||||
let display_val = if val { 1 } else { 0 };
|
let display_val = if val { 1 } else { 0 };
|
||||||
self.command_line
|
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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
self.tabs[i].scene.clear_preview_wire();
|
self.tabs[i].scene.clear_preview_wire();
|
||||||
|
|
@ -3014,11 +3014,11 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if updated {
|
if updated {
|
||||||
self.tabs[i].dirty = true;
|
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 {
|
} else {
|
||||||
self.discard_last_undo_entry(i);
|
self.discard_last_undo_entry(i);
|
||||||
self.command_line
|
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].active_cmd = None;
|
||||||
self.tabs[i].snap_result = None;
|
self.tabs[i].snap_result = None;
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,12 @@ impl OpenCADStudio {
|
||||||
} else {
|
} else {
|
||||||
"model space"
|
"model space"
|
||||||
};
|
};
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"Base point ({}, {}, {}) set for {space}.",
|
"Base point ({}, {}, {}) set for {space}.",
|
||||||
nums[0], nums[1], z
|
nums[0], nums[1], z
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} 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() {
|
return match self.mtext_selected_text() {
|
||||||
Some(text) => {
|
Some(text) => {
|
||||||
self.command_line
|
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())
|
Some(iced::clipboard::write(text).discard())
|
||||||
}
|
}
|
||||||
None => Some(Task::none()),
|
None => Some(Task::none()),
|
||||||
|
|
@ -91,10 +91,10 @@ impl OpenCADStudio {
|
||||||
&self.tabs[i].scene.document,
|
&self.tabs[i].scene.document,
|
||||||
&self.clipboard,
|
&self.clipboard,
|
||||||
);
|
);
|
||||||
self.command_line.push_info(&format!(
|
self.command_line.push_info(crate::tf!(
|
||||||
"{} object(s) copied to clipboard.",
|
"{} object(s) copied to clipboard.",
|
||||||
self.clipboard.len()
|
self.clipboard.len()
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,12 +145,12 @@ impl OpenCADStudio {
|
||||||
&self.tabs[i].scene.document,
|
&self.tabs[i].scene.document,
|
||||||
&self.clipboard,
|
&self.clipboard,
|
||||||
);
|
);
|
||||||
self.command_line.push_info(&format!(
|
self.command_line.push_info(crate::tf!(
|
||||||
"{} object(s) copied to clipboard (base {:.3},{:.3}).",
|
"{} object(s) copied to clipboard (base {:.3},{:.3}).",
|
||||||
self.clipboard.len(),
|
self.clipboard.len(),
|
||||||
base.x,
|
base.x,
|
||||||
base.y
|
base.y
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,13 +187,13 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
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" => {
|
"PASTECLIP" => {
|
||||||
if self.clipboard.is_empty() {
|
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 {
|
} else {
|
||||||
let wires = self.tabs[i].scene.wires_for_entities(&self.clipboard);
|
let wires = self.tabs[i].scene.wires_for_entities(&self.clipboard);
|
||||||
let base = self.clipboard_base;
|
let base = self.clipboard_base;
|
||||||
|
|
@ -210,7 +210,7 @@ impl OpenCADStudio {
|
||||||
"PASTEORIG" => {
|
"PASTEORIG" => {
|
||||||
if self.clipboard.is_empty() {
|
if self.clipboard.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("PASTEORIG: clipboard is empty.");
|
.push_error(crate::t!("PASTEORIG: clipboard is empty.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let count = self.clipboard.len();
|
let count = self.clipboard.len();
|
||||||
self.push_undo_snapshot(i, "PASTEORIG");
|
self.push_undo_snapshot(i, "PASTEORIG");
|
||||||
|
|
@ -219,10 +219,10 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_layer_panel();
|
self.refresh_layer_panel();
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"PASTEORIG: {} object(s) pasted at original coordinates.",
|
"PASTEORIG: {} object(s) pasted at original coordinates.",
|
||||||
count
|
count
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,7 +231,7 @@ impl OpenCADStudio {
|
||||||
"PASTEBLOCK" => {
|
"PASTEBLOCK" => {
|
||||||
if self.clipboard.is_empty() {
|
if self.clipboard.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("PASTEBLOCK: clipboard is empty.");
|
.push_error(crate::t!("PASTEBLOCK: clipboard is empty.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.push_undo_snapshot(i, "PASTEBLOCK");
|
self.push_undo_snapshot(i, "PASTEBLOCK");
|
||||||
self.merge_clipboard_deps(i);
|
self.merge_clipboard_deps(i);
|
||||||
|
|
@ -294,7 +294,7 @@ impl OpenCADStudio {
|
||||||
self.command_line.push_info(&cmd.prompt());
|
self.command_line.push_info(&cmd.prompt());
|
||||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
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();
|
let blocks = self.tabs[i].scene.custom_block_names();
|
||||||
if blocks.is_empty() {
|
if blocks.is_empty() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
use crate::modules::insert::insert_block::InsertBlockCommand;
|
use crate::modules::insert::insert_block::InsertBlockCommand;
|
||||||
let cmd = InsertBlockCommand::new(blocks);
|
let cmd = InsertBlockCommand::new(blocks);
|
||||||
|
|
@ -336,7 +336,7 @@ impl OpenCADStudio {
|
||||||
let blocks = self.tabs[i].scene.custom_block_names();
|
let blocks = self.tabs[i].scene.custom_block_names();
|
||||||
if blocks.is_empty() {
|
if blocks.is_empty() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
use crate::modules::insert::minsert::MinsertCommand;
|
use crate::modules::insert::minsert::MinsertCommand;
|
||||||
let cmd = MinsertCommand::new(blocks);
|
let cmd = MinsertCommand::new(blocks);
|
||||||
|
|
@ -359,20 +359,20 @@ impl OpenCADStudio {
|
||||||
let arg = cmd.trim_start_matches("ATTSYNC").trim();
|
let arg = cmd.trim_start_matches("ATTSYNC").trim();
|
||||||
let blocks = self.tabs[i].scene.custom_block_names();
|
let blocks = self.tabs[i].scene.custom_block_names();
|
||||||
if arg.is_empty() {
|
if arg.is_empty() {
|
||||||
self.command_line.push_info(&format!(
|
self.command_line.push_info(crate::tf!(
|
||||||
"Usage: ATTSYNC <block name>. Blocks: {}",
|
"Usage: ATTSYNC <block name>. Blocks: {}",
|
||||||
if blocks.is_empty() {
|
if blocks.is_empty() {
|
||||||
"(none)".to_string()
|
"(none)".to_string()
|
||||||
} else {
|
} else {
|
||||||
blocks.join(", ")
|
blocks.join(", ")
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
let Some(block) = blocks.iter().find(|b| b.eq_ignore_ascii_case(arg)).cloned()
|
let Some(block) = blocks.iter().find(|b| b.eq_ignore_ascii_case(arg)).cloned()
|
||||||
else {
|
else {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
};
|
};
|
||||||
// Gather the block's attribute definitions (tag, default value).
|
// 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].scene.bump_entities(&changes);
|
||||||
self.tabs[i].dirty = true;
|
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).",
|
"ATTSYNC: synchronised {synced} insert(s) of \"{block}\" against {} attribute definition(s).",
|
||||||
attdefs.len()
|
attdefs.len()
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADCENTER / CONTENTBROWSER — report the drawing's named content
|
// ADCENTER / CONTENTBROWSER — report the drawing's named content
|
||||||
|
|
@ -440,7 +440,7 @@ impl OpenCADStudio {
|
||||||
.names()
|
.names()
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect();
|
.collect();
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"Blocks ({}): {}",
|
"Blocks ({}): {}",
|
||||||
blocks.len(),
|
blocks.len(),
|
||||||
if blocks.is_empty() {
|
if blocks.is_empty() {
|
||||||
|
|
@ -448,12 +448,12 @@ impl OpenCADStudio {
|
||||||
} else {
|
} else {
|
||||||
blocks.join(", ")
|
blocks.join(", ")
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"Layers ({}): {}",
|
"Layers ({}): {}",
|
||||||
layers.len(),
|
layers.len(),
|
||||||
layers.join(", ")
|
layers.join(", ")
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
// BLOCKPALETTE — list the blocks available to insert.
|
// BLOCKPALETTE — list the blocks available to insert.
|
||||||
|
|
@ -464,11 +464,11 @@ impl OpenCADStudio {
|
||||||
"No user-defined blocks. Define one with BLOCK, then INSERT it.",
|
"No user-defined blocks. Define one with BLOCK, then INSERT it.",
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"Blocks ({}) — insert with INSERT <name>: {}",
|
"Blocks ({}) — insert with INSERT <name>: {}",
|
||||||
blocks.len(),
|
blocks.len(),
|
||||||
blocks.join(", ")
|
blocks.join(", ")
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -527,9 +527,9 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if xrefs.is_empty() {
|
if xrefs.is_empty() {
|
||||||
self.command_line
|
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 {
|
} 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 {
|
for line in xrefs {
|
||||||
self.command_line.push_output(&line);
|
self.command_line.push_output(&line);
|
||||||
}
|
}
|
||||||
|
|
@ -548,19 +548,19 @@ impl OpenCADStudio {
|
||||||
match info.status {
|
match info.status {
|
||||||
crate::io::xref::XrefStatus::Loaded => {
|
crate::io::xref::XrefStatus::Loaded => {
|
||||||
self.command_line
|
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 => {
|
crate::io::xref::XrefStatus::NotFound => {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"XREF Not found: \"{}\" ({})",
|
"XREF Not found: \"{}\" ({})",
|
||||||
info.name, info.path
|
info.name, info.path
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
crate::io::xref::XrefStatus::Unloaded => {
|
crate::io::xref::XrefStatus::Unloaded => {
|
||||||
self.command_line.push_info(&format!(
|
self.command_line.push_info(crate::tf!(
|
||||||
"XREF Unloaded (skipped): \"{}\"",
|
"XREF Unloaded (skipped): \"{}\"",
|
||||||
info.name
|
info.name
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -574,7 +574,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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
|
None => self
|
||||||
.command_line
|
.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();
|
.collect();
|
||||||
if inserts.is_empty() {
|
if inserts.is_empty() {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "NCOPY");
|
self.push_undo_snapshot(i, "NCOPY");
|
||||||
|
|
@ -638,9 +638,9 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
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)."
|
"NCOPY: copied {n} nested object(s) into model space (blocks kept)."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => return None,
|
_ => return None,
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
if opt.is_empty() {
|
if opt.is_empty() {
|
||||||
|
|
@ -130,7 +130,7 @@ impl OpenCADStudio {
|
||||||
};
|
};
|
||||||
if text_align.is_none() && mtext_ap.is_none() {
|
if text_align.is_none() && mtext_ap.is_none() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("JUSTIFYTEXT: unknown justification option.");
|
.push_error(crate::t!("JUSTIFYTEXT: unknown justification option.").as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "JUSTIFYTEXT");
|
self.push_undo_snapshot(i, "JUSTIFYTEXT");
|
||||||
|
|
@ -175,7 +175,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
self.tabs[i].scene.bump_entities(&changes);
|
self.tabs[i].scene.bump_entities(&changes);
|
||||||
self.command_line
|
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
|
// TCASE <Upper|Lower|Sentence|Title> — change the case of the text in
|
||||||
|
|
@ -207,7 +207,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
if !matches!(
|
if !matches!(
|
||||||
|
|
@ -223,7 +223,7 @@ impl OpenCADStudio {
|
||||||
| "TITLE"
|
| "TITLE"
|
||||||
) {
|
) {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
let conv = move |s: &str| -> String {
|
let conv = move |s: &str| -> String {
|
||||||
|
|
@ -263,7 +263,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
self.tabs[i].scene.bump_entities(&changes);
|
self.tabs[i].scene.bump_entities(&changes);
|
||||||
self.command_line
|
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
|
// TEXTMASK — place a wipeout mask sized to each selected text object's
|
||||||
|
|
@ -296,7 +296,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "TEXTMASK");
|
self.push_undo_snapshot(i, "TEXTMASK");
|
||||||
|
|
@ -339,7 +339,7 @@ impl OpenCADStudio {
|
||||||
.replace_selection(handles.iter().cloned().collect());
|
.replace_selection(handles.iter().cloned().collect());
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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);
|
return self.dispatch_view("DRAWORDER FRONT", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -373,7 +373,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "TEXTFIT");
|
self.push_undo_snapshot(i, "TEXTFIT");
|
||||||
|
|
@ -412,9 +412,9 @@ impl OpenCADStudio {
|
||||||
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
||||||
.collect();
|
.collect();
|
||||||
self.tabs[i].scene.bump_entities(&changes);
|
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}."
|
"TEXTFIT: fitted {n} text object(s) to width {target}."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
// (text sequential numbering)
|
// (text sequential numbering)
|
||||||
|
|
@ -450,7 +450,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if texts.is_empty() {
|
if texts.is_empty() {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
// Reading order: higher Y first, then smaller X.
|
// Reading order: higher Y first, then smaller X.
|
||||||
|
|
@ -478,10 +478,10 @@ impl OpenCADStudio {
|
||||||
.map(|(handle, _, _)| (*handle, crate::scene::ChangeKind::Modified))
|
.map(|(handle, _, _)| (*handle, crate::scene::ChangeKind::Modified))
|
||||||
.collect();
|
.collect();
|
||||||
self.tabs[i].scene.bump_entities(&changes);
|
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}.",
|
"TCOUNT: numbered {} text object(s) from {start}.",
|
||||||
texts.len()
|
texts.len()
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
"MLEADER" => {
|
"MLEADER" => {
|
||||||
|
|
@ -575,7 +575,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if pts.len() < 2 {
|
if pts.len() < 2 {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
// Choose the dimension axis from the points' spread: a wider X
|
// Choose the dimension axis from the points' spread: a wider X
|
||||||
|
|
@ -596,7 +596,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if pts.len() < 2 {
|
if pts.len() < 2 {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "QDIM");
|
self.push_undo_snapshot(i, "QDIM");
|
||||||
|
|
@ -628,7 +628,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("QDIM {made} dimensions created."));
|
.push_output(crate::tf!("QDIM {made} dimensions created.").as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -697,28 +697,28 @@ impl OpenCADStudio {
|
||||||
|
|
||||||
"ZOOM EXTENTS ALL" | "ZOOM EXTENTS ALL VIEWPORTS" | "ZEA" => {
|
"ZOOM EXTENTS ALL" | "ZOOM EXTENTS ALL VIEWPORTS" | "ZEA" => {
|
||||||
self.tabs[i].scene.fit_all_model_viewports();
|
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" => {
|
"ZOOM EXTENTS" | "ZOOMEXTENTS" | "ZE" => {
|
||||||
self.tabs[i].scene.fit_all();
|
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" => {
|
"ZOOM IN" | "ZI" => {
|
||||||
self.tabs[i].scene.zoom_camera(1.0 / 1.5);
|
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" => {
|
"ZOOM OUT" | "ZO" => {
|
||||||
self.tabs[i].scene.zoom_camera(1.5);
|
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 — fit the configured drawing limits.
|
||||||
"ZOOM ALL" | "ZOOM A" | "ZA" => {
|
"ZOOM ALL" | "ZOOM A" | "ZA" => {
|
||||||
self.tabs[i].scene.fit_all_with_limits();
|
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")
|
// ZOOM SCALE — set zoom factor (e.g. "ZOOM SCALE 2" or "ZS 0.5")
|
||||||
|
|
@ -731,7 +731,7 @@ impl OpenCADStudio {
|
||||||
if factor > 0.0 {
|
if factor > 0.0 {
|
||||||
self.tabs[i].scene.zoom_camera(1.0 / factor);
|
self.tabs[i].scene.zoom_camera(1.0 / factor);
|
||||||
self.command_line
|
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.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("{exploded} object(s) exploded."));
|
.push_output(crate::tf!("{exploded} object(s) exploded.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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 {
|
let Some((center, radius)) = found else {
|
||||||
self.command_line
|
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;
|
return None;
|
||||||
};
|
};
|
||||||
if radius <= 0.0 {
|
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;
|
return None;
|
||||||
}
|
}
|
||||||
let k = std::f64::consts::FRAC_1_SQRT_2;
|
let k = std::f64::consts::FRAC_1_SQRT_2;
|
||||||
|
|
@ -1129,7 +1129,7 @@ impl OpenCADStudio {
|
||||||
.add_entity(acadrust::EntityType::Dimension(Dimension::Radius(dim)));
|
.add_entity(acadrust::EntityType::Dimension(Dimension::Radius(dim)));
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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
|
// ARCTEXT <text> — lay the text out as one Text entity per character
|
||||||
|
|
@ -1166,12 +1166,12 @@ impl OpenCADStudio {
|
||||||
});
|
});
|
||||||
let Some(arc) = arc else {
|
let Some(arc) = arc else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("ARCTEXT: select an arc first.");
|
.push_error(crate::t!("ARCTEXT: select an arc first.").as_ref());
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let chars: Vec<char> = text.chars().filter(|c| !c.is_control()).collect();
|
let chars: Vec<char> = text.chars().filter(|c| !c.is_control()).collect();
|
||||||
if chars.is_empty() {
|
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;
|
return None;
|
||||||
}
|
}
|
||||||
let n = chars.len();
|
let n = chars.len();
|
||||||
|
|
@ -1195,7 +1195,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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,
|
_ => return None,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ impl OpenCADStudio {
|
||||||
"PAN" => {
|
"PAN" => {
|
||||||
self.tabs[i].pan_mode = true;
|
self.tabs[i].pan_mode = true;
|
||||||
self.command_line
|
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 ─────────────────────────────────────────────
|
// ── TABLE cell editing ─────────────────────────────────────────────
|
||||||
|
|
@ -46,18 +46,18 @@ impl OpenCADStudio {
|
||||||
if found {
|
if found {
|
||||||
self.push_undo_snapshot(i, "TABLE CELL");
|
self.push_undo_snapshot(i, "TABLE CELL");
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"TABLE CELL: set [{row},{col}] = \"{text}\"."
|
"TABLE CELL: set [{row},{col}] = \"{text}\"."
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_error(
|
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
|
self.command_line
|
||||||
.push_info("Usage: TABLE CELL <row> <col> <text>");
|
.push_info(crate::t!("Usage: TABLE CELL <row> <col> <text>").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -111,9 +111,9 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
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."
|
"UCSICON {sub}: updated {count} viewport(s) + model space."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
"" => {
|
"" => {
|
||||||
// Bare UCSICON toggles visibility.
|
// Bare UCSICON toggles visibility.
|
||||||
|
|
@ -128,11 +128,11 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
let state = if visible { "ON" } else { "OFF" };
|
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
|
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();
|
tokens.iter().map(|value| value.parse()).collect();
|
||||||
let Ok(values) = values else {
|
let Ok(values) = values else {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
};
|
};
|
||||||
if tokens.len() != 4 || !values.iter().all(|value| value.is_finite()) {
|
if tokens.len() != 4 || !values.iter().all(|value| value.is_finite()) {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("LIMITS: four finite numeric coordinates required.");
|
.push_error(crate::t!("LIMITS: four finite numeric coordinates required.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let first = glam::DVec2::new(values[0], values[1]);
|
let first = glam::DVec2::new(values[0], values[1]);
|
||||||
let opposite = glam::DVec2::new(values[2], values[3]);
|
let opposite = glam::DVec2::new(values[2], values[3]);
|
||||||
|
|
@ -185,15 +185,15 @@ impl OpenCADStudio {
|
||||||
let max = first.max(opposite);
|
let max = first.max(opposite);
|
||||||
if min.x == max.x || min.y == max.y {
|
if min.x == max.x || min.y == max.y {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
self.push_undo_snapshot(i, "LIMITS");
|
self.push_undo_snapshot(i, "LIMITS");
|
||||||
self.tabs[i].scene.set_current_drawing_limits(min, max);
|
self.tabs[i].scene.set_current_drawing_limits(min, max);
|
||||||
self.tabs[i].dirty = true;
|
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}.",
|
"Drawing limits: {:.4},{:.4} to {:.4},{:.4}.",
|
||||||
min.x, min.y, max.x, max.y
|
min.x, min.y, max.x, max.y
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -249,13 +249,13 @@ impl OpenCADStudio {
|
||||||
// ── TOOLPALETTES — not yet implemented ───────────────────────────────
|
// ── TOOLPALETTES — not yet implemented ───────────────────────────────
|
||||||
"TOOLPALETTES" => {
|
"TOOLPALETTES" => {
|
||||||
self.command_line
|
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 — not yet implemented ───────────────────────────────────
|
||||||
"SHEETSET" => {
|
"SHEETSET" => {
|
||||||
self.command_line
|
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 ──────────────────────────
|
// ── XDATA — read/write extended entity data ──────────────────────────
|
||||||
|
|
@ -288,7 +288,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if selected_handles.is_empty() {
|
if selected_handles.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("XDATA: select entities first.");
|
.push_error(crate::t!("XDATA: select entities first.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
match sub.as_str() {
|
match sub.as_str() {
|
||||||
"LIST" | "" => {
|
"LIST" | "" => {
|
||||||
|
|
@ -297,18 +297,18 @@ impl OpenCADStudio {
|
||||||
let xd = &entity.common().extended_data;
|
let xd = &entity.common().extended_data;
|
||||||
if xd.is_empty() {
|
if xd.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!(" {:x}: no xdata.", sh.value()));
|
.push_output(crate::tf!(" {:x}: no xdata.", sh.value()).as_ref());
|
||||||
} else {
|
} else {
|
||||||
for rec in xd.records() {
|
for rec in xd.records() {
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" {:x} [{}]: {} value(s)",
|
" {:x} [{}]: {} value(s)",
|
||||||
sh.value(),
|
sh.value(),
|
||||||
rec.application_name,
|
rec.application_name,
|
||||||
rec.values.len()
|
rec.values.len()
|
||||||
));
|
).as_ref());
|
||||||
for v in &rec.values {
|
for v in &rec.values {
|
||||||
self.command_line
|
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.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"XDATA: set [{app}] = \"{val}\" on {} entity/entities.",
|
"XDATA: set [{app}] = \"{val}\" on {} entity/entities.",
|
||||||
selected_handles.len()
|
selected_handles.len()
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
"CLEAR" => {
|
"CLEAR" => {
|
||||||
let app_filter = parts.get(1).copied();
|
let app_filter = parts.get(1).copied();
|
||||||
|
|
@ -360,11 +360,11 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
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
|
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
|
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();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("UNDERLAY: select underlay entities first.");
|
.push_error(crate::t!("UNDERLAY: select underlay entities first.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let parts: Vec<&str> = sub.splitn(2, char::is_whitespace).collect();
|
let parts: Vec<&str> = sub.splitn(2, char::is_whitespace).collect();
|
||||||
let action = parts.first().copied().unwrap_or("");
|
let action = parts.first().copied().unwrap_or("");
|
||||||
|
|
@ -589,7 +589,7 @@ impl OpenCADStudio {
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
// No sub-command: print status.
|
// 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={}",
|
"Underlay {:x}: fade={}, contrast={}, on={}, clip={}, mono={}",
|
||||||
h.value(),
|
h.value(),
|
||||||
ul.fade,
|
ul.fade,
|
||||||
|
|
@ -597,7 +597,7 @@ impl OpenCADStudio {
|
||||||
ul.is_on(),
|
ul.is_on(),
|
||||||
ul.is_clipping(),
|
ul.is_clipping(),
|
||||||
ul.is_monochrome(),
|
ul.is_monochrome(),
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -605,10 +605,10 @@ impl OpenCADStudio {
|
||||||
if changed > 0 {
|
if changed > 0 {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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() {
|
} else if !action.is_empty() {
|
||||||
self.command_line.push_error(
|
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();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("OBJECTSCALE: select objects first.");
|
.push_error(crate::t!("OBJECTSCALE: select objects first.").as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "OBJECTSCALE");
|
self.push_undo_snapshot(i, "OBJECTSCALE");
|
||||||
let Some(scale) = self.tabs[i].scene.creation_annotation_scale_handle() else {
|
let Some(scale) = self.tabs[i].scene.creation_annotation_scale_handle() else {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
};
|
};
|
||||||
let mut n = 0usize;
|
let mut n = 0usize;
|
||||||
|
|
@ -665,9 +665,9 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
self.tabs[i].scene.bump_entities(&changes);
|
self.tabs[i].scene.bump_entities(&changes);
|
||||||
self.tabs[i].dirty = true;
|
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)."
|
"OBJECTSCALE: added the active scale to {n} object(s)."
|
||||||
));
|
).as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -688,13 +688,13 @@ impl OpenCADStudio {
|
||||||
use acadrust::xdata::{ExtendedDataRecord, XDataValue};
|
use acadrust::xdata::{ExtendedDataRecord, XDataValue};
|
||||||
let url = cmd.strip_prefix("HYPERLINK").unwrap_or("").trim().to_string();
|
let url = cmd.strip_prefix("HYPERLINK").unwrap_or("").trim().to_string();
|
||||||
if url.is_empty() {
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
let handles: Vec<acadrust::Handle> =
|
let handles: Vec<acadrust::Handle> =
|
||||||
self.tabs[i].scene.selected_entities().iter().map(|(h, _)| *h).collect();
|
self.tabs[i].scene.selected_entities().iter().map(|(h, _)| *h).collect();
|
||||||
if handles.is_empty() {
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "HYPERLINK");
|
self.push_undo_snapshot(i, "HYPERLINK");
|
||||||
|
|
@ -710,7 +710,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -745,10 +745,10 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
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() {
|
} else if action.is_empty() {
|
||||||
self.command_line
|
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>() {
|
} else if let Ok(v) = arg.parse::<u8>() {
|
||||||
let v = v.min(100);
|
let v = v.min(100);
|
||||||
self.push_undo_snapshot(i, "ADJUST");
|
self.push_undo_snapshot(i, "ADJUST");
|
||||||
|
|
@ -792,14 +792,14 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
self.tabs[i].scene.bump_entities(&changes);
|
self.tabs[i].scene.bump_entities(&changes);
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
self.command_line.push_error(
|
self.command_line.push_error(
|
||||||
"ADJUST: no raster images selected, or unknown property (use BRIGHTNESS|CONTRAST|FADE).",
|
"ADJUST: no raster images selected, or unknown property (use BRIGHTNESS|CONTRAST|FADE).",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
_ => self
|
||||||
.command_line
|
.command_line
|
||||||
.push_error("ANNOALLVISIBLE: enter 0 or 1."),
|
.push_error(crate::t!("ANNOALLVISIBLE: enter 0 or 1.").as_ref()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"ANNOAUTOSCALE" => {
|
"ANNOAUTOSCALE" => {
|
||||||
|
|
@ -867,7 +867,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "ANNOUPDATE");
|
self.push_undo_snapshot(i, "ANNOUPDATE");
|
||||||
|
|
@ -891,7 +891,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
}
|
}
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
cmd if cmd.starts_with("ANNOSCALE ") || cmd.starts_with("CANNOSCALE ") => {
|
cmd if cmd.starts_with("ANNOSCALE ") || cmd.starts_with("CANNOSCALE ") => {
|
||||||
|
|
@ -909,7 +909,7 @@ impl OpenCADStudio {
|
||||||
.current_annotation_scale
|
.current_annotation_scale
|
||||||
.clone();
|
.clone();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Current annotation scale: {name}"));
|
.push_output(crate::tf!("Current annotation scale: {name}").as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
let previous = self.tabs[i].scene.displayed_annotation_scale_handle();
|
let previous = self.tabs[i].scene.displayed_annotation_scale_handle();
|
||||||
|
|
@ -924,11 +924,11 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Annotation scale: {arg}"));
|
.push_output(crate::tf!("Annotation scale: {arg}").as_ref());
|
||||||
}
|
}
|
||||||
None => self
|
None => self
|
||||||
.command_line
|
.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) {
|
if self.tabs[i].scene.add_scale(arg, paper, drawing) {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Added annotation scale {arg}."));
|
.push_output(crate::tf!("Added annotation scale {arg}.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info(&format!("Scale {arg} already exists."));
|
.push_info(crate::tf!("Scale {arg} already exists.").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => self
|
_ => self
|
||||||
.command_line
|
.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
|
None => self
|
||||||
.command_line
|
.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" => {
|
"DELETE" | "REMOVE" => {
|
||||||
let current = self.tabs[i]
|
let current = self.tabs[i]
|
||||||
|
|
@ -984,20 +984,20 @@ impl OpenCADStudio {
|
||||||
.current_annotation_scale
|
.current_annotation_scale
|
||||||
.clone();
|
.clone();
|
||||||
if arg.is_empty() {
|
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) {
|
} 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})."
|
"Cannot delete the current annotation scale ({arg})."
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.push_undo_snapshot(i, "SCALELISTEDIT");
|
self.push_undo_snapshot(i, "SCALELISTEDIT");
|
||||||
if self.tabs[i].scene.remove_scale(arg) {
|
if self.tabs[i].scene.remove_scale(arg) {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Removed annotation scale {arg}."));
|
.push_output(crate::tf!("Removed annotation scale {arg}.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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)
|
.map(|(n, _, _)| n)
|
||||||
.collect();
|
.collect();
|
||||||
if names.is_empty() {
|
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 {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Annotation scales: {}", names.join(", ")));
|
.push_output(crate::tf!("Annotation scales: {}", names.join(", ")).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => self
|
_ => self
|
||||||
.command_line
|
.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);
|
let ncols = rows_data.iter().map(|r| r.len()).max().unwrap_or(0);
|
||||||
if nrows == 0 || ncols == 0 {
|
if nrows == 0 || ncols == 0 {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
use acadrust::entities::TableBuilder;
|
use acadrust::entities::TableBuilder;
|
||||||
|
|
@ -1076,13 +1076,13 @@ impl OpenCADStudio {
|
||||||
.scene
|
.scene
|
||||||
.add_entity_clone(acadrust::EntityType::Table(table));
|
.add_entity_clone(acadrust::EntityType::Table(table));
|
||||||
self.tabs[i].dirty = true;
|
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."
|
"DATALINK: imported {nrows}×{ncols} cells into a table at the origin."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.command_line
|
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);
|
let pts = parse_landxml_cgpoints(&xml);
|
||||||
if pts.is_empty() {
|
if pts.is_empty() {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "LANDXMLIMPORT");
|
self.push_undo_snapshot(i, "LANDXMLIMPORT");
|
||||||
|
|
@ -1122,21 +1122,21 @@ impl OpenCADStudio {
|
||||||
.add_entity_clone(acadrust::EntityType::Point(p));
|
.add_entity_clone(acadrust::EntityType::Point(p));
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
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.",
|
"LANDXMLIMPORT: imported {} survey point(s). Use ZOOM EXTENTS to view.",
|
||||||
pts.len()
|
pts.len()
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
Err(e) => self
|
Err(e) => self
|
||||||
.command_line
|
.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"
|
"POINTCLOUDATTACH" | "RECAP" | "SYNCPVIEWPORTS" | "UNDERLAYLAYERS"
|
||||||
| "UOSNAP" => {
|
| "UOSNAP" => {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info(&format!("{cmd}: not yet implemented."));
|
.push_info(crate::tf!("{cmd}: not yet implemented.").as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => return None,
|
_ => return None,
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if selected_handles.is_empty() {
|
if selected_handles.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("ATTEDIT: select an Insert entity first.");
|
.push_error(crate::t!("ATTEDIT: select an Insert entity first.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let mut found_any = false;
|
let mut found_any = false;
|
||||||
for sh in &selected_handles {
|
for sh in &selected_handles {
|
||||||
|
|
@ -90,17 +90,17 @@ impl OpenCADStudio {
|
||||||
if rest.is_empty() {
|
if rest.is_empty() {
|
||||||
// List attributes.
|
// List attributes.
|
||||||
if ins.attributes.is_empty() {
|
if ins.attributes.is_empty() {
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" Insert {:x}: no attributes.",
|
" Insert {:x}: no attributes.",
|
||||||
sh.value()
|
sh.value()
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
for attr in &ins.attributes {
|
for attr in &ins.attributes {
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" [{tag}] = {val}",
|
" [{tag}] = {val}",
|
||||||
tag = attr.tag,
|
tag = attr.tag,
|
||||||
val = attr.get_value()
|
val = attr.get_value()
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -108,7 +108,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if !found_any {
|
if !found_any {
|
||||||
self.command_line
|
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 tag + value supplied, mutate attributes.
|
||||||
if parts.len() == 2 && !parts[0].is_empty() {
|
if parts.len() == 2 && !parts[0].is_empty() {
|
||||||
|
|
@ -133,13 +133,13 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if changed > 0 {
|
if changed > 0 {
|
||||||
self.tabs[i].dirty = true;
|
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}."
|
"ATTEDIT: updated {changed} attribute(s) [{tag_up}] = {new_val}."
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"ATTEDIT: tag '{tag_up}' not found in selection."
|
"ATTEDIT: tag '{tag_up}' not found in selection."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -187,13 +187,13 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
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."
|
"ATTDISP {sub}: {count} attribute definition(s) updated."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.command_line
|
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 => {
|
None => {
|
||||||
self.command_line
|
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));
|
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
let cmd = HatcheditCommand::new();
|
let cmd = HatcheditCommand::new();
|
||||||
|
|
@ -721,7 +721,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
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 {
|
if let Some(pd) = pending {
|
||||||
self.commit_undo_delta(i, pd);
|
self.commit_undo_delta(i, pd);
|
||||||
}
|
}
|
||||||
|
|
@ -783,7 +783,7 @@ impl OpenCADStudio {
|
||||||
return Some(self.solid_polysolid(nums[0], nums[1]));
|
return Some(self.solid_polysolid(nums[0], nums[1]));
|
||||||
}
|
}
|
||||||
self.command_line
|
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.
|
// SPLINEFIT — fit a smooth spline through the selected polyline's points.
|
||||||
|
|
@ -829,7 +829,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if loops.is_empty() {
|
if loops.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("REGION: select closed polylines or circles.");
|
.push_error(crate::t!("REGION: select closed polylines or circles.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.push_undo_snapshot(i, "REGION");
|
self.push_undo_snapshot(i, "REGION");
|
||||||
let count = loops.len();
|
let count = loops.len();
|
||||||
|
|
@ -845,7 +845,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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));
|
return Some(self.solid_pyramid(nums[0], nums[1], sides));
|
||||||
}
|
}
|
||||||
self.command_line
|
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.
|
// SECTION [X|Y|Z] <value> — draw the cross-section outline of the solid.
|
||||||
|
|
@ -1070,7 +1070,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if sel.len() == 1 {
|
if sel.len() == 1 {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("DDEDIT: selected entity is not text.");
|
.push_error(crate::t!("DDEDIT: selected entity is not text.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let cmd = DdeditCommand::new();
|
let cmd = DdeditCommand::new();
|
||||||
self.command_line.push_info(&cmd.prompt());
|
self.command_line.push_info(&cmd.prompt());
|
||||||
|
|
@ -1093,7 +1093,7 @@ impl OpenCADStudio {
|
||||||
"Multiple"
|
"Multiple"
|
||||||
};
|
};
|
||||||
self.command_line
|
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);
|
let new_cmd = TexteditCommand::new(self.texteditmode);
|
||||||
self.command_line.push_info(&new_cmd.prompt());
|
self.command_line.push_info(&new_cmd.prompt());
|
||||||
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
|
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ impl OpenCADStudio {
|
||||||
"SAVEALL" => {
|
"SAVEALL" => {
|
||||||
if self.read_only {
|
if self.read_only {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
|
@ -27,10 +27,10 @@ impl OpenCADStudio {
|
||||||
.active_save_jobs
|
.active_save_jobs
|
||||||
.contains_key(&self.tabs[t].id)
|
.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",
|
"SAVEALL: {} already has a save running",
|
||||||
path.display()
|
path.display()
|
||||||
));
|
).as_ref());
|
||||||
skipped += 1;
|
skipped += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -42,28 +42,28 @@ impl OpenCADStudio {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
saved += 1;
|
saved += 1;
|
||||||
}
|
}
|
||||||
Err(e) => self.command_line.push_error(&format!(
|
Err(e) => self.command_line.push_error(crate::tf!(
|
||||||
"SAVEALL: {} failed: {e}",
|
"SAVEALL: {} failed: {e}",
|
||||||
path.display()
|
path.display()
|
||||||
)),
|
).as_ref()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
skipped += 1;
|
skipped += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"SAVEALL: saved {saved} drawing(s){}.",
|
"SAVEALL: saved {saved} drawing(s){}.",
|
||||||
if skipped > 0 {
|
if skipped > 0 {
|
||||||
format!("; {skipped} need SAVEAS (no file path yet)")
|
format!("; {skipped} need SAVEAS (no file path yet)")
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
|
|
@ -76,7 +76,7 @@ impl OpenCADStudio {
|
||||||
Ok(n) => return Some(Task::done(Message::UndoMany(n))),
|
Ok(n) => return Some(Task::done(Message::UndoMany(n))),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -87,7 +87,7 @@ impl OpenCADStudio {
|
||||||
// without undoing any work done since.
|
// without undoing any work done since.
|
||||||
"OOPS" => {
|
"OOPS" => {
|
||||||
if self.oops_cache.is_empty() {
|
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 {
|
} else {
|
||||||
let restored = std::mem::take(&mut self.oops_cache);
|
let restored = std::mem::take(&mut self.oops_cache);
|
||||||
let pending = self.begin_undo(i, "OOPS", restored.len(), true);
|
let pending = self.begin_undo(i, "OOPS", restored.len(), true);
|
||||||
|
|
@ -99,7 +99,7 @@ impl OpenCADStudio {
|
||||||
self.commit_undo_delta(i, pending);
|
self.commit_undo_delta(i, pending);
|
||||||
}
|
}
|
||||||
self.command_line
|
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)),
|
"CLEAR" | "CLR" => return Some(Task::done(Message::ClearScene)),
|
||||||
|
|
@ -161,7 +161,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.command_line
|
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)));
|
return Some(Task::done(Message::SetWireframe(wireframe)));
|
||||||
}
|
}
|
||||||
// CLOSE — close the active drawing tab (with the unsaved-changes
|
// 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 {}",
|
"{cmd}: packaged {copied} file(s) into {}",
|
||||||
folder.display()
|
folder.display()
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
Err(e) => self
|
Err(e) => self
|
||||||
.command_line
|
.command_line
|
||||||
.push_error(&format!("{cmd}: cannot create folder ({e}).")),
|
.push_error(crate::tf!("{cmd}: cannot create folder ({e}).").as_ref()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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.recolor_meshes();
|
||||||
self.tabs[i].scene.bump_geometry();
|
self.tabs[i].scene.bump_geometry();
|
||||||
self.command_line
|
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) {
|
} else if let Some(rgba) = parse_background_color(&args) {
|
||||||
if is_paper {
|
if is_paper {
|
||||||
self.tabs[i].paper_bg_color = Some(rgba);
|
self.tabs[i].paper_bg_color = Some(rgba);
|
||||||
|
|
@ -316,12 +316,12 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.recolor_meshes();
|
self.tabs[i].scene.recolor_meshes();
|
||||||
self.tabs[i].scene.bump_geometry();
|
self.tabs[i].scene.bump_geometry();
|
||||||
let [r, g, b, _] = rgba;
|
let [r, g, b, _] = rgba;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"Background: rgb({}, {}, {})",
|
"Background: rgb({}, {}, {})",
|
||||||
(r * 255.0).round() as u8,
|
(r * 255.0).round() as u8,
|
||||||
(g * 255.0).round() as u8,
|
(g * 255.0).round() as u8,
|
||||||
(b * 255.0).round() as u8
|
(b * 255.0).round() as u8
|
||||||
));
|
).as_ref());
|
||||||
// Persisted centrally after this message via
|
// Persisted centrally after this message via
|
||||||
// `persist_settings_if_changed()`.
|
// `persist_settings_if_changed()`.
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -361,20 +361,20 @@ impl OpenCADStudio {
|
||||||
})
|
})
|
||||||
.map(|l| Task::done(Message::Command(l.to_string())))
|
.map(|l| Task::done(Message::Command(l.to_string())))
|
||||||
.collect();
|
.collect();
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"SCRIPT: running {} command(s) from {p}.",
|
"SCRIPT: running {} command(s) from {p}.",
|
||||||
cmds.len()
|
cmds.len()
|
||||||
));
|
).as_ref());
|
||||||
return Some(Task::batch(cmds));
|
return Some(Task::batch(cmds));
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.command_line
|
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
|
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 {
|
match cmd {
|
||||||
"3DORBIT" => {
|
"3DORBIT" => {
|
||||||
self.command_line
|
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 ───────────────────────────────────────
|
// ── Selection utilities ───────────────────────────────────────
|
||||||
|
|
@ -24,20 +24,20 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.select_entity(h, false);
|
self.tabs[i].scene.select_entity(h, false);
|
||||||
}
|
}
|
||||||
self.command_line
|
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();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
|
|
||||||
"DESELECT" | "DESELALL" => {
|
"DESELECT" | "DESELALL" => {
|
||||||
self.tabs[i].scene.deselect_all();
|
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();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
|
|
||||||
"SELECTSIMILAR" | "SELSIM" => {
|
"SELECTSIMILAR" | "SELSIM" => {
|
||||||
let added = self.tabs[i].scene.select_similar();
|
let added = self.tabs[i].scene.select_similar();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Select Similar: {} added.", added));
|
.push_output(crate::tf!("Select Similar: {} added.", added).as_ref());
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,11 +68,11 @@ impl OpenCADStudio {
|
||||||
let expr = cmd.splitn(2, char::is_whitespace).nth(1).unwrap_or("").trim();
|
let expr = cmd.splitn(2, char::is_whitespace).nth(1).unwrap_or("").trim();
|
||||||
if expr.is_empty() {
|
if expr.is_empty() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
match arith_eval(expr) {
|
match arith_eval(expr) {
|
||||||
Ok(v) => self.command_line.push_output(&format!("= {v}")),
|
Ok(v) => self.command_line.push_output(crate::tf!("= {v}").as_ref()),
|
||||||
Err(e) => self.command_line.push_error(&format!("CAL: {e}")),
|
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();
|
let selected: Vec<_> = self.tabs[i].scene.selected_entities();
|
||||||
if selected.is_empty() {
|
if selected.is_empty() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
for (handle, _) in &selected {
|
for (handle, _) in &selected {
|
||||||
if let Some(entity) = self.tabs[i].scene.document.get_entity(*handle) {
|
if let Some(entity) = self.tabs[i].scene.document.get_entity(*handle) {
|
||||||
|
|
@ -101,7 +101,7 @@ impl OpenCADStudio {
|
||||||
};
|
};
|
||||||
// Entity-specific details
|
// Entity-specific details
|
||||||
let details = entity_list_details(entity);
|
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:{}{}",
|
"{type_name} Handle:{:X} Layer:{} Color:{} LT:{}{}",
|
||||||
handle.value(),
|
handle.value(),
|
||||||
common.layer,
|
common.layer,
|
||||||
|
|
@ -112,7 +112,7 @@ impl OpenCADStudio {
|
||||||
} else {
|
} else {
|
||||||
format!("\n {details}")
|
format!("\n {details}")
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +127,7 @@ impl OpenCADStudio {
|
||||||
let selected = scene.selected_entities();
|
let selected = scene.selected_entities();
|
||||||
if selected.is_empty() {
|
if selected.is_empty() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
let space = if scene.current_layout == "Model" {
|
let space = if scene.current_layout == "Model" {
|
||||||
|
|
@ -207,16 +207,14 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if lines.is_empty() {
|
if lines.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info("DBLIST: drawing has no entities.");
|
.push_info(crate::t!("DBLIST: drawing has no entities.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let count = lines.len();
|
let count = lines.len();
|
||||||
for l in lines {
|
for l in lines {
|
||||||
self.command_line.push_output(&l);
|
self.command_line.push_output(&l);
|
||||||
}
|
}
|
||||||
self.command_line.push_output(&format!(
|
self.command_line
|
||||||
"DBLIST: {count} entit{}.",
|
.push_output(crate::tf!("DBLIST: {count} objects.").as_ref());
|
||||||
if count == 1 { "y" } else { "ies" }
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -311,7 +309,7 @@ impl OpenCADStudio {
|
||||||
// If a session is already active, tell the user.
|
// If a session is already active, tell the user.
|
||||||
if self.tabs[i].refedit_session.is_some() {
|
if self.tabs[i].refedit_session.is_some() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
// Check if a single INSERT is already selected.
|
// Check if a single INSERT is already selected.
|
||||||
let selected: Vec<_> =
|
let selected: Vec<_> =
|
||||||
|
|
@ -337,7 +335,7 @@ impl OpenCADStudio {
|
||||||
use crate::modules::draw::modify::block_edit::BlockEditPickCommand;
|
use crate::modules::draw::modify::block_edit::BlockEditPickCommand;
|
||||||
if self.tabs[i].refedit_session.is_some() {
|
if self.tabs[i].refedit_session.is_some() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
// Jump straight to begin when a single INSERT is preselected.
|
// Jump straight to begin when a single INSERT is preselected.
|
||||||
let selected: Vec<_> =
|
let selected: Vec<_> =
|
||||||
|
|
@ -369,7 +367,7 @@ impl OpenCADStudio {
|
||||||
Some(acadrust::EntityType::Insert(ins)) => ins.clone(),
|
Some(acadrust::EntityType::Insert(ins)) => ins.clone(),
|
||||||
_ => {
|
_ => {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -383,16 +381,16 @@ impl OpenCADStudio {
|
||||||
{
|
{
|
||||||
Some(br) => (br.handle, br.flags.is_xref),
|
Some(br) => (br.handle, br.flags.is_xref),
|
||||||
None => {
|
None => {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"BEDIT: block \"{}\" not found.",
|
"BEDIT: block \"{}\" not found.",
|
||||||
insert.block_name
|
insert.block_name
|
||||||
));
|
).as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if is_xref {
|
if is_xref {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
if self.tabs[i]
|
if self.tabs[i]
|
||||||
|
|
@ -519,10 +517,10 @@ impl OpenCADStudio {
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.tabs[i].active_cmd = None;
|
self.tabs[i].active_cmd = None;
|
||||||
self.tabs[i].dirty = true;
|
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.",
|
"BEDIT: Editing block \"{}\". Use Save Block or Discard to finish.",
|
||||||
insert.block_name
|
insert.block_name
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
"BEDIT_SAVE" => {
|
"BEDIT_SAVE" => {
|
||||||
|
|
@ -532,12 +530,12 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -549,10 +547,10 @@ impl OpenCADStudio {
|
||||||
&session.return_camera,
|
&session.return_camera,
|
||||||
);
|
);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"BEDIT: Block \"{}\" saved. All references updated.",
|
"BEDIT: Block \"{}\" saved. All references updated.",
|
||||||
session.block_name
|
session.block_name
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
"BEDIT_DISCARD" => {
|
"BEDIT_DISCARD" => {
|
||||||
|
|
@ -562,12 +560,12 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -625,10 +623,10 @@ impl OpenCADStudio {
|
||||||
&return_camera,
|
&return_camera,
|
||||||
);
|
);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"BEDIT: Block \"{}\" edit discarded.",
|
"BEDIT: Block \"{}\" edit discarded.",
|
||||||
block_name
|
block_name
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd if cmd.starts_with("REFEDIT_BEGIN:") => {
|
cmd if cmd.starts_with("REFEDIT_BEGIN:") => {
|
||||||
|
|
@ -645,7 +643,7 @@ impl OpenCADStudio {
|
||||||
Some(acadrust::EntityType::Insert(ins)) => ins.clone(),
|
Some(acadrust::EntityType::Insert(ins)) => ins.clone(),
|
||||||
_ => {
|
_ => {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -681,10 +679,10 @@ impl OpenCADStudio {
|
||||||
{
|
{
|
||||||
Some(br) => br.handle,
|
Some(br) => br.handle,
|
||||||
None => {
|
None => {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"REFEDIT: block \"{}\" not found.",
|
"REFEDIT: block \"{}\" not found.",
|
||||||
insert.block_name
|
insert.block_name
|
||||||
));
|
).as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -712,7 +710,7 @@ impl OpenCADStudio {
|
||||||
};
|
};
|
||||||
|
|
||||||
if block_entities.is_empty() {
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -762,10 +760,10 @@ impl OpenCADStudio {
|
||||||
// No active command — the user edits the block's geometry freely
|
// No active command — the user edits the block's geometry freely
|
||||||
// (move, grips, draw, erase…) and runs REFCLOSE when done. (#136)
|
// (move, grips, draw, erase…) and runs REFCLOSE when done. (#136)
|
||||||
self.tabs[i].active_cmd = None;
|
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.",
|
"REFEDIT: Editing block \"{}\". Run REFCLOSE to save, REFCLOSE_DISCARD to cancel.",
|
||||||
insert.block_name
|
insert.block_name
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
"REFCLOSE" => {
|
"REFCLOSE" => {
|
||||||
|
|
@ -776,7 +774,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].active_cmd = Some(Box::new(cmd_obj));
|
self.tabs[i].active_cmd = Some(Box::new(cmd_obj));
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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,
|
Some(s) => s,
|
||||||
None => {
|
None => {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -866,10 +864,10 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"REFCLOSE: Block \"{}\" saved. All references updated.",
|
"REFCLOSE: Block \"{}\" saved. All references updated.",
|
||||||
session.block_name
|
session.block_name
|
||||||
));
|
).as_ref());
|
||||||
// End the edit fade before rebuilding, so the restored geometry
|
// End the edit fade before rebuilding, so the restored geometry
|
||||||
// recolours bright. (#136)
|
// recolours bright. (#136)
|
||||||
self.tabs[i].scene.set_refedit_keep(None);
|
self.tabs[i].scene.set_refedit_keep(None);
|
||||||
|
|
@ -882,7 +880,7 @@ impl OpenCADStudio {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
None => {
|
None => {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -908,7 +906,7 @@ impl OpenCADStudio {
|
||||||
// End the edit fade — restore the drawing to full brightness.
|
// End the edit fade — restore the drawing to full brightness.
|
||||||
self.tabs[i].scene.set_refedit_keep(None);
|
self.tabs[i].scene.set_refedit_keep(None);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output("REFCLOSE: Changes discarded.");
|
.push_output(crate::t!("REFCLOSE: Changes discarded.").as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
"ALIGN" => {
|
"ALIGN" => {
|
||||||
|
|
@ -966,20 +964,20 @@ impl OpenCADStudio {
|
||||||
let selected = self.tabs[i].scene.selected_entities();
|
let selected = self.tabs[i].scene.selected_entities();
|
||||||
if selected.is_empty() {
|
if selected.is_empty() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
for (handle, _) in &selected {
|
for (handle, _) in &selected {
|
||||||
if let Some(entity) = self.tabs[i].scene.document.get_entity(*handle) {
|
if let Some(entity) = self.tabs[i].scene.document.get_entity(*handle) {
|
||||||
use crate::entities::traits::EntityTypeOps;
|
use crate::entities::traits::EntityTypeOps;
|
||||||
if let Some(props) = entity.mass_props() {
|
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})",
|
"{} Area={:.4} Perimeter={:.4} Centroid=({:.4},{:.4})",
|
||||||
crate::entities::names::dxf_name(entity),
|
crate::entities::names::dxf_name(entity),
|
||||||
props.area,
|
props.area,
|
||||||
props.perimeter,
|
props.perimeter,
|
||||||
props.cx,
|
props.cx,
|
||||||
props.cy,
|
props.cy,
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1003,7 +1001,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if handles.is_empty() {
|
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 {
|
} else {
|
||||||
self.push_undo_snapshot(i, "FLATTEN");
|
self.push_undo_snapshot(i, "FLATTEN");
|
||||||
for h in &handles {
|
for h in &handles {
|
||||||
|
|
@ -1012,10 +1010,10 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
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.",
|
"FLATTEN: {} entity(ies) moved to Z=0.",
|
||||||
handles.len()
|
handles.len()
|
||||||
));
|
).as_ref());
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1054,17 +1052,17 @@ impl OpenCADStudio {
|
||||||
|
|
||||||
if prop.is_empty() {
|
if prop.is_empty() {
|
||||||
self.command_line
|
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() {
|
} else if matched.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output("QSELECT: no matching entities.");
|
.push_output(crate::t!("QSELECT: no matching entities.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.tabs[i].scene.deselect_all();
|
self.tabs[i].scene.deselect_all();
|
||||||
for h in &matched {
|
for h in &matched {
|
||||||
self.tabs[i].scene.select_entity(*h, false);
|
self.tabs[i].scene.select_entity(*h, false);
|
||||||
}
|
}
|
||||||
self.command_line
|
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();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1102,10 +1100,10 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
let total: usize = counts.values().sum();
|
let total: usize = counts.values().sum();
|
||||||
for (k, n) in &counts {
|
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
|
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" => {
|
"DATAEXTRACTION" | "EATTEXT" | "ATTEXT" => {
|
||||||
|
|
@ -1142,7 +1140,7 @@ impl OpenCADStudio {
|
||||||
};
|
};
|
||||||
|
|
||||||
if search.is_empty() {
|
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 {
|
} else {
|
||||||
let search_lc = search.to_lowercase();
|
let search_lc = search.to_lowercase();
|
||||||
let mut count = 0usize;
|
let mut count = 0usize;
|
||||||
|
|
@ -1170,7 +1168,7 @@ impl OpenCADStudio {
|
||||||
};
|
};
|
||||||
if targets.is_empty() {
|
if targets.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("FIND: \"{}\" not found.", search));
|
.push_output(crate::tf!("FIND: \"{}\" not found.", search).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.push_undo_snapshot(i, "FIND/REPLACE");
|
self.push_undo_snapshot(i, "FIND/REPLACE");
|
||||||
for h in &targets {
|
for h in &targets {
|
||||||
|
|
@ -1182,34 +1180,34 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"FIND/REPLACE: replaced {} occurrence(s) of \"{}\" → \"{}\".",
|
"FIND/REPLACE: replaced {} occurrence(s) of \"{}\" → \"{}\".",
|
||||||
count, search, rep
|
count, search, rep
|
||||||
));
|
).as_ref());
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// List mode
|
// List mode
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("FIND: \"{}\" not found.", search));
|
.push_output(crate::tf!("FIND: \"{}\" not found.", search).as_ref());
|
||||||
} else {
|
} else {
|
||||||
for h in &handles {
|
for h in &handles {
|
||||||
if let Some(e) = self.tabs[i].scene.document.get_entity(*h) {
|
if let Some(e) = self.tabs[i].scene.document.get_entity(*h) {
|
||||||
use crate::entities::traits::EntityTypeOps;
|
use crate::entities::traits::EntityTypeOps;
|
||||||
let txt = e.text_content().unwrap_or_default();
|
let txt = e.text_content().unwrap_or_default();
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" Handle {:X}: \"{}\"",
|
" Handle {:X}: \"{}\"",
|
||||||
h.value(),
|
h.value(),
|
||||||
txt
|
txt
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"FIND: {} match(es) for \"{}\".",
|
"FIND: {} match(es) for \"{}\".",
|
||||||
handles.len(),
|
handles.len(),
|
||||||
search
|
search
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1309,12 +1307,12 @@ impl OpenCADStudio {
|
||||||
let Some((verb, kind, layer, color, linetype, lt_scale, lw, template_dimstyle)) = info
|
let Some((verb, kind, layer, color, linetype, lt_scale, lw, template_dimstyle)) = info
|
||||||
else {
|
else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("ADDSELECTED: selected object not found.");
|
.push_error(crate::t!("ADDSELECTED: selected object not found.").as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let Some(verb) = verb else {
|
let Some(verb) = verb else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1399,9 +1397,9 @@ impl OpenCADStudio {
|
||||||
self.ribbon.active_lineweight = lw;
|
self.ribbon.active_lineweight = lw;
|
||||||
self.refresh_properties();
|
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}\"."
|
"Add Selected: drawing a new {kind} on layer \"{layer}\"."
|
||||||
));
|
).as_ref());
|
||||||
// Launch the matching draw command (installs its interactive step).
|
// Launch the matching draw command (installs its interactive step).
|
||||||
self.dispatch_command(verb)
|
self.dispatch_command(verb)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,15 +36,15 @@ impl OpenCADStudio {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Layers: {}", info.join(", ")));
|
.push_output(crate::tf!("Layers: {}", info.join(", ")).as_ref());
|
||||||
}
|
}
|
||||||
"NEW" | "N" => {
|
"NEW" | "N" => {
|
||||||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
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) {
|
} else if self.tabs[i].scene.document.layers.contains(&name) {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("LAYER: '{}' already exists.", name));
|
.push_error(crate::tf!("LAYER: '{}' already exists.", name).as_ref());
|
||||||
} else {
|
} else {
|
||||||
let mut layer = Layer::new(&name);
|
let mut layer = Layer::new(&name);
|
||||||
// Allocate a unique handle so the layer survives a
|
// Allocate a unique handle so the layer survives a
|
||||||
|
|
@ -54,7 +54,7 @@ impl OpenCADStudio {
|
||||||
self.push_undo_snapshot(i, "LAYER NEW");
|
self.push_undo_snapshot(i, "LAYER NEW");
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("LAYER: '{}' created.", name));
|
.push_output(crate::tf!("LAYER: '{}' created.", name).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"ON" => {
|
"ON" => {
|
||||||
|
|
@ -66,7 +66,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "LAYER ON");
|
self.push_undo_snapshot(i, "LAYER ON");
|
||||||
self.tabs[i].dirty = true;
|
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" => {
|
"OFF" => {
|
||||||
for name in &parts[1..] {
|
for name in &parts[1..] {
|
||||||
|
|
@ -76,7 +76,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "LAYER OFF");
|
self.push_undo_snapshot(i, "LAYER OFF");
|
||||||
self.tabs[i].dirty = true;
|
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" => {
|
"FREEZE" | "FR" => {
|
||||||
for name in &parts[1..] {
|
for name in &parts[1..] {
|
||||||
|
|
@ -86,7 +86,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "LAYER FREEZE");
|
self.push_undo_snapshot(i, "LAYER FREEZE");
|
||||||
self.tabs[i].dirty = true;
|
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" => {
|
"THAW" | "TH" => {
|
||||||
for name in &parts[1..] {
|
for name in &parts[1..] {
|
||||||
|
|
@ -96,7 +96,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "LAYER THAW");
|
self.push_undo_snapshot(i, "LAYER THAW");
|
||||||
self.tabs[i].dirty = true;
|
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" => {
|
"LOCK" | "LO" => {
|
||||||
for name in &parts[1..] {
|
for name in &parts[1..] {
|
||||||
|
|
@ -106,7 +106,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "LAYER LOCK");
|
self.push_undo_snapshot(i, "LAYER LOCK");
|
||||||
self.tabs[i].dirty = true;
|
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" => {
|
"UNLOCK" | "UL" => {
|
||||||
for name in &parts[1..] {
|
for name in &parts[1..] {
|
||||||
|
|
@ -116,7 +116,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "LAYER UNLOCK");
|
self.push_undo_snapshot(i, "LAYER UNLOCK");
|
||||||
self.tabs[i].dirty = true;
|
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" => {
|
"COLOR" | "C" => {
|
||||||
// LAYER COLOR <name> <aci_index>
|
// LAYER COLOR <name> <aci_index>
|
||||||
|
|
@ -137,17 +137,17 @@ impl OpenCADStudio {
|
||||||
.invalidate_layer_dependencies(std::slice::from_ref(
|
.invalidate_layer_dependencies(std::slice::from_ref(
|
||||||
&layer_name,
|
&layer_name,
|
||||||
));
|
));
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"LAYER: '{}' color set to ACI {}.",
|
"LAYER: '{}' color set to ACI {}.",
|
||||||
layer_name, idx
|
layer_name, idx
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("LAYER: '{}' not found.", layer_name));
|
.push_error(crate::tf!("LAYER: '{}' not found.", layer_name).as_ref());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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" => {
|
"SET" | "S" | "CURRENT" => {
|
||||||
|
|
@ -155,15 +155,15 @@ impl OpenCADStudio {
|
||||||
if self.tabs[i].scene.document.layers.contains(&name) {
|
if self.tabs[i].scene.document.layers.contains(&name) {
|
||||||
self.tabs[i].layers.current_layer = name.clone();
|
self.tabs[i].layers.current_layer = name.clone();
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
self.command_line
|
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(
|
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())
|
.map(|u| u.name.clone())
|
||||||
.collect();
|
.collect();
|
||||||
if names.is_empty() {
|
if names.is_empty() {
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"Active UCS: {} | No named UCSs defined.",
|
"Active UCS: {} | No named UCSs defined.",
|
||||||
active_name
|
active_name
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"Active UCS: {} | Named: {}",
|
"Active UCS: {} | Named: {}",
|
||||||
active_name,
|
active_name,
|
||||||
names.join(", ")
|
names.join(", ")
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"SAVE" | "S" => {
|
"SAVE" | "S" => {
|
||||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
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 {
|
} else {
|
||||||
// Save the current active UCS under this name.
|
// Save the current active UCS under this name.
|
||||||
let ucs = match &self.tabs[i].active_ucs {
|
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].scene.document.ucss.add_or_replace(ucs);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("UCS '{}' saved.", name));
|
.push_output(crate::tf!("UCS '{}' saved.", name).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"DELETE" | "DEL" | "D" => {
|
"DELETE" | "DEL" | "D" => {
|
||||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
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() {
|
} else if self.tabs[i].scene.document.ucss.remove(&name).is_some() {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("UCS '{}' deleted.", name));
|
.push_output(crate::tf!("UCS '{}' deleted.", name).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("UCS '{}' not found.", name));
|
.push_error(crate::tf!("UCS '{}' not found.", name).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"W" | "WORLD" => {
|
"W" | "WORLD" => {
|
||||||
self.tabs[i].active_ucs = None;
|
self.tabs[i].active_ucs = None;
|
||||||
active_changed = true;
|
active_changed = true;
|
||||||
self.command_line
|
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
|
// UCS ORIGIN x,y,z — shift the active UCS origin, keep axes
|
||||||
"ORIGIN" | "O" => {
|
"ORIGIN" | "O" => {
|
||||||
|
|
@ -274,12 +274,12 @@ impl OpenCADStudio {
|
||||||
wcs_origin.z as f64,
|
wcs_origin.z as f64,
|
||||||
);
|
);
|
||||||
active_changed = true;
|
active_changed = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"UCS origin set to ({:.4}, {:.4}, {:.4}).",
|
"UCS origin set to ({:.4}, {:.4}, {:.4}).",
|
||||||
wcs_origin.x, wcs_origin.y, wcs_origin.z
|
wcs_origin.x, wcs_origin.y, wcs_origin.z
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} 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
|
// 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);
|
self.tabs[i].active_ucs = Some(new_ucs);
|
||||||
active_changed = true;
|
active_changed = true;
|
||||||
self.command_line
|
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 {
|
} 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
|
// 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);
|
ucs.y_axis = Vector3::new(ny.x as f64, ny.y as f64, ny.z as f64);
|
||||||
active_changed = true;
|
active_changed = true;
|
||||||
self.command_line
|
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 {
|
} 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
|
// 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);
|
ucs.x_axis = Vector3::new(nx.x as f64, nx.y as f64, nx.z as f64);
|
||||||
active_changed = true;
|
active_changed = true;
|
||||||
self.command_line
|
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 {
|
} 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);
|
self.tabs[i].active_ucs = Some(named);
|
||||||
active_changed = true;
|
active_changed = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("UCS '{}' activated.", name));
|
.push_output(crate::tf!("UCS '{}' activated.", name).as_ref());
|
||||||
} else {
|
} 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>",
|
"UCS '{}' not found. Usage: UCS LIST | SAVE <name> | DELETE <name> | W | ORIGIN x,y,z | X/Y/Z <angle>",
|
||||||
name
|
name
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -429,16 +429,16 @@ impl OpenCADStudio {
|
||||||
"" | "CURRENT" | "C" => {
|
"" | "CURRENT" | "C" => {
|
||||||
let r = self.tabs[i].scene.viewcube_ucs_mat();
|
let r = self.tabs[i].scene.viewcube_ucs_mat();
|
||||||
self.plan_snap(i, r);
|
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" => {
|
"WORLD" | "W" => {
|
||||||
self.plan_snap(i, glam::Mat4::IDENTITY);
|
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" => {
|
"UCS" | "U" => {
|
||||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("");
|
let name = parts.get(2).map(|s| s.trim()).unwrap_or("");
|
||||||
if name.is_empty() {
|
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 {
|
} else {
|
||||||
let ucs = self.tabs[i]
|
let ucs = self.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
|
|
@ -452,20 +452,20 @@ impl OpenCADStudio {
|
||||||
let r = crate::app::helpers::UcsXform::from_ucs(&u)
|
let r = crate::app::helpers::UcsXform::from_ucs(&u)
|
||||||
.rotation_mat();
|
.rotation_mat();
|
||||||
self.plan_snap(i, r);
|
self.plan_snap(i, r);
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"PLAN: plan view of UCS '{}'.",
|
"PLAN: plan view of UCS '{}'.",
|
||||||
u.name
|
u.name
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
None => self
|
None => self
|
||||||
.command_line
|
.command_line
|
||||||
.push_error(&format!("UCS '{name}' not found.")),
|
.push_error(crate::tf!("UCS '{name}' not found.").as_ref()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => self
|
_ => self
|
||||||
.command_line
|
.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())
|
.map(|v| v.name.clone())
|
||||||
.collect();
|
.collect();
|
||||||
if views.is_empty() {
|
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 {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Named views: {}", views.join(", ")));
|
.push_output(crate::tf!("Named views: {}", views.join(", ")).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"SAVE" | "S" => {
|
"SAVE" | "S" => {
|
||||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
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 {
|
} else {
|
||||||
let new_view = self.tabs[i].scene.current_as_named_view(&name);
|
let new_view = self.tabs[i].scene.current_as_named_view(&name);
|
||||||
self.tabs[i].scene.document.views.add_or_replace(new_view);
|
self.tabs[i].scene.document.views.add_or_replace(new_view);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("View '{}' saved.", name));
|
.push_output(crate::tf!("View '{}' saved.", name).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"DELETE" | "DEL" | "D" => {
|
"DELETE" | "DEL" | "D" => {
|
||||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
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 {
|
} else {
|
||||||
if self.tabs[i].scene.document.views.remove(&name).is_some() {
|
if self.tabs[i].scene.document.views.remove(&name).is_some() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("View '{}' deleted.", name));
|
.push_output(crate::tf!("View '{}' deleted.", name).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("View '{}' not found.", name));
|
.push_error(crate::tf!("View '{}' not found.", name).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"RESTORE" | "R" => {
|
"RESTORE" | "R" => {
|
||||||
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
let name = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
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 {
|
} else {
|
||||||
let found = self.tabs[i].scene.document.views.get(&name).cloned();
|
let found = self.tabs[i].scene.document.views.get(&name).cloned();
|
||||||
if let Some(v) = found {
|
if let Some(v) = found {
|
||||||
self.tabs[i].scene.restore_named_view(&v);
|
self.tabs[i].scene.restore_named_view(&v);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("View '{}' restored.", v.name));
|
.push_output(crate::tf!("View '{}' restored.", v.name).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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 {
|
if let Some(v) = found {
|
||||||
self.tabs[i].scene.restore_named_view(&v);
|
self.tabs[i].scene.restore_named_view(&v);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("View '{}' restored.", v.name));
|
.push_output(crate::tf!("View '{}' restored.", v.name).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_error(
|
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();
|
.collect();
|
||||||
if styles.is_empty() {
|
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 {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("TableStyles:\n {}", styles.join("\n ")));
|
.push_output(crate::tf!("TableStyles:\n {}", styles.join("\n ")).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"NEW" | "N" => {
|
"NEW" | "N" => {
|
||||||
let name = parts.get(1).copied().unwrap_or("").to_string();
|
let name = parts.get(1).copied().unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
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 {
|
} else {
|
||||||
let doc = &self.tabs[i].scene.document;
|
let doc = &self.tabs[i].scene.document;
|
||||||
let exists = doc.objects.values().any(|o| {
|
let exists = doc.objects.values().any(|o| {
|
||||||
|
|
@ -631,7 +631,7 @@ impl OpenCADStudio {
|
||||||
});
|
});
|
||||||
if exists {
|
if exists {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("TABLESTYLE: '{}' already exists.", name));
|
.push_error(crate::tf!("TABLESTYLE: '{}' already exists.", name).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.push_undo_snapshot(i, "TABLESTYLE NEW");
|
self.push_undo_snapshot(i, "TABLESTYLE NEW");
|
||||||
let mut style = TableStyle::standard();
|
let mut style = TableStyle::standard();
|
||||||
|
|
@ -647,13 +647,13 @@ impl OpenCADStudio {
|
||||||
.insert(nh, ObjectType::TableStyle(style));
|
.insert(nh, ObjectType::TableStyle(style));
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("TABLESTYLE: '{}' created.", name));
|
.push_output(crate::tf!("TABLESTYLE: '{}' created.", name).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.command_line
|
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();
|
.collect();
|
||||||
if styles.is_empty() {
|
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 {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("MLineStyles:\n {}", styles.join("\n ")));
|
.push_output(crate::tf!("MLineStyles:\n {}", styles.join("\n ")).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"NEW" | "N" => {
|
"NEW" | "N" => {
|
||||||
let name = parts.get(1).copied().unwrap_or("").to_string();
|
let name = parts.get(1).copied().unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
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 {
|
} else {
|
||||||
let doc = &self.tabs[i].scene.document;
|
let doc = &self.tabs[i].scene.document;
|
||||||
let exists = doc.objects.values().any(|o| {
|
let exists = doc.objects.values().any(|o| {
|
||||||
|
|
@ -710,7 +710,7 @@ impl OpenCADStudio {
|
||||||
});
|
});
|
||||||
if exists {
|
if exists {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("MLSTYLE: '{}' already exists.", name));
|
.push_error(crate::tf!("MLSTYLE: '{}' already exists.", name).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.push_undo_snapshot(i, "MLSTYLE NEW");
|
self.push_undo_snapshot(i, "MLSTYLE NEW");
|
||||||
let mut style = MLineStyle::standard();
|
let mut style = MLineStyle::standard();
|
||||||
|
|
@ -726,14 +726,14 @@ impl OpenCADStudio {
|
||||||
.insert(nh, ObjectType::MLineStyle(style));
|
.insert(nh, ObjectType::MLineStyle(style));
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("MLSTYLE: '{}' created.", name));
|
.push_output(crate::tf!("MLSTYLE: '{}' created.", name).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"SET" | "S" => {
|
"SET" | "S" => {
|
||||||
let name = parts.get(1).copied().unwrap_or("").to_string();
|
let name = parts.get(1).copied().unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
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 {
|
} else {
|
||||||
let doc = &self.tabs[i].scene.document;
|
let doc = &self.tabs[i].scene.document;
|
||||||
let exists = doc.objects.values().any(|o| {
|
let exists = doc.objects.values().any(|o| {
|
||||||
|
|
@ -743,13 +743,13 @@ impl OpenCADStudio {
|
||||||
self.push_undo_snapshot(i, "MLSTYLE SET");
|
self.push_undo_snapshot(i, "MLSTYLE SET");
|
||||||
self.tabs[i].scene.document.header.multiline_style = name.clone();
|
self.tabs[i].scene.document.header.multiline_style = name.clone();
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"MLSTYLE: current style set to '{}'.",
|
"MLSTYLE: current style set to '{}'.",
|
||||||
name
|
name
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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();
|
let name = parts.get(1).copied().unwrap_or("").to_string();
|
||||||
if name.is_empty() || name.eq_ignore_ascii_case("Standard") {
|
if name.is_empty() || name.eq_ignore_ascii_case("Standard") {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("Cannot delete the Standard style.");
|
.push_error(crate::t!("Cannot delete the Standard style.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let doc = &self.tabs[i].scene.document;
|
let doc = &self.tabs[i].scene.document;
|
||||||
let handle = doc.objects.iter().find_map(|(&h, o)| {
|
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].scene.document.objects.remove(&h);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("MLSTYLE: '{}' deleted.", name));
|
.push_output(crate::tf!("MLSTYLE: '{}' deleted.", name).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("MLSTYLE: '{}' not found.", name));
|
.push_error(crate::tf!("MLSTYLE: '{}' not found.", name).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.command_line
|
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))
|
.map(|s| format!("{}(txt:{:.2} asz:{:.2})", s.name, s.dimtxt, s.dimasz))
|
||||||
.collect();
|
.collect();
|
||||||
if styles.is_empty() {
|
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 {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("DimStyles: {}", styles.join(", ")));
|
.push_output(crate::tf!("DimStyles: {}", styles.join(", ")).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"NEW" | "N" => {
|
"NEW" | "N" => {
|
||||||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
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) {
|
} else if self.tabs[i].scene.document.dim_styles.contains(&name) {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("DIMSTYLE: '{}' already exists.", name));
|
.push_error(crate::tf!("DIMSTYLE: '{}' already exists.", name).as_ref());
|
||||||
} else {
|
} else {
|
||||||
let undo = self.begin_dim_style_undo(
|
let undo = self.begin_dim_style_undo(
|
||||||
i,
|
i,
|
||||||
|
|
@ -837,7 +837,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.commit_dim_style_undo(i, undo);
|
self.commit_dim_style_undo(i, undo);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("DIMSTYLE: '{}' created.", name));
|
.push_output(crate::tf!("DIMSTYLE: '{}' created.", name).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"SET" | "S" => {
|
"SET" | "S" => {
|
||||||
|
|
@ -896,9 +896,9 @@ impl OpenCADStudio {
|
||||||
ds.dimfxl = val;
|
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
|
"DIMSTYLE: unknown property '{}'. Try: dimtxt dimasz dimdli dimexo dimexe dimgap dimscale dimlfac dimdle dimcen dimtsz", prop
|
||||||
));
|
).as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -906,16 +906,16 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene
|
self.tabs[i].scene
|
||||||
.invalidate_dim_style_dependencies(&style_name);
|
.invalidate_dim_style_dependencies(&style_name);
|
||||||
self.commit_dim_style_undo(i, undo);
|
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}"
|
"DIMSTYLE: '{style_name}'.{prop} = {val:.3}"
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("DIMSTYLE: '{}' not found.", style_name));
|
.push_error(crate::tf!("DIMSTYLE: '{}' not found.", style_name).as_ref());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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;
|
let current = &self.tabs[i].active_mleader_style;
|
||||||
if styles.is_empty() {
|
if styles.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("MLeader styles: (none) active: {current}"));
|
.push_output(crate::tf!("MLeader styles: (none) active: {current}").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"MLeader styles: {} active: {current}",
|
"MLeader styles: {} active: {current}",
|
||||||
styles.join(", ")
|
styles.join(", ")
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"NEW" | "N" => {
|
"NEW" | "N" => {
|
||||||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
if name.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("Usage: MLEADERSTYLE NEW <name>");
|
.push_error(crate::t!("Usage: MLEADERSTYLE NEW <name>").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let already_exists = self.tabs[i].scene.document.objects.values().any(
|
let already_exists = self.tabs[i].scene.document.objects.values().any(
|
||||||
|o| matches!(o, ObjectType::MultiLeaderStyle(s) if s.name == name),
|
|o| matches!(o, ObjectType::MultiLeaderStyle(s) if s.name == name),
|
||||||
);
|
);
|
||||||
if already_exists {
|
if already_exists {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"MLEADERSTYLE: '{}' already exists.",
|
"MLEADERSTYLE: '{}' already exists.",
|
||||||
name
|
name
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
let handle = self.tabs[i].scene.document.allocate_handle();
|
let handle = self.tabs[i].scene.document.allocate_handle();
|
||||||
let mut style = MultiLeaderStyle::new(&name);
|
let mut style = MultiLeaderStyle::new(&name);
|
||||||
|
|
@ -990,7 +990,7 @@ impl OpenCADStudio {
|
||||||
self.push_undo_snapshot(i, "MLEADERSTYLE NEW");
|
self.push_undo_snapshot(i, "MLEADERSTYLE NEW");
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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;
|
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
|
"MLEADERSTYLE: unknown property '{}'. Try: text_height arrowhead_size landing_distance landing_gap", prop
|
||||||
));
|
).as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "MLEADERSTYLE SET");
|
self.push_undo_snapshot(i, "MLEADERSTYLE SET");
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"MLEADERSTYLE: '{style_name}'.{prop} = {val:.3}"
|
"MLEADERSTYLE: '{style_name}'.{prop} = {val:.3}"
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"MLEADERSTYLE: '{}' not found.",
|
"MLEADERSTYLE: '{}' not found.",
|
||||||
style_name
|
style_name
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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" => {
|
"CURRENT" | "C" | "ACTIVE" => {
|
||||||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
if name.is_empty() {
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"Current MLeader style: {}",
|
"Current MLeader style: {}",
|
||||||
self.tabs[i].active_mleader_style
|
self.tabs[i].active_mleader_style
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
let exists = name == "Standard" || self.tabs[i].scene.document.objects.values()
|
let exists = name == "Standard" || self.tabs[i].scene.document.objects.values()
|
||||||
.any(|o| matches!(o, ObjectType::MultiLeaderStyle(s) if s.name == name));
|
.any(|o| matches!(o, ObjectType::MultiLeaderStyle(s) if s.name == name));
|
||||||
if exists {
|
if exists {
|
||||||
self.tabs[i].active_mleader_style = name.clone();
|
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}'."
|
"MLEADERSTYLE: current style set to '{name}'."
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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(
|
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();
|
.collect();
|
||||||
if styles.is_empty() {
|
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 {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Text styles: {}", styles.join(" | ")));
|
.push_output(crate::tf!("Text styles: {}", styles.join(" | ")).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"SET" | "S" => {
|
"SET" | "S" => {
|
||||||
|
|
@ -1128,20 +1128,20 @@ impl OpenCADStudio {
|
||||||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("");
|
let name = parts.get(1).map(|s| s.trim()).unwrap_or("");
|
||||||
if self.tabs[i].scene.document.text_styles.get(name).is_some() {
|
if self.tabs[i].scene.document.text_styles.get(name).is_some() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("{prefix}: style '{name}' not found."));
|
.push_error(crate::tf!("{prefix}: style '{name}' not found.").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"NEW" | "N" => {
|
"NEW" | "N" => {
|
||||||
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string();
|
||||||
if name.is_empty() {
|
if name.is_empty() {
|
||||||
self.command_line
|
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) {
|
} else if self.tabs[i].scene.document.text_styles.contains(&name) {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("{prefix}: style '{name}' already exists."));
|
.push_error(crate::tf!("{prefix}: style '{name}' already exists.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let undo = self.begin_text_style_undo(
|
let undo = self.begin_text_style_undo(
|
||||||
i,
|
i,
|
||||||
|
|
@ -1153,7 +1153,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.commit_text_style_undo(i, undo);
|
self.commit_text_style_undo(i, undo);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("{prefix}: style '{name}' created."));
|
.push_output(crate::tf!("{prefix}: style '{name}' created.").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"FONT" | "F" => {
|
"FONT" | "F" => {
|
||||||
|
|
@ -1162,7 +1162,7 @@ impl OpenCADStudio {
|
||||||
let font = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
let font = parts.get(2).map(|s| s.trim()).unwrap_or("").to_string();
|
||||||
if style_name.is_empty() || font.is_empty() {
|
if style_name.is_empty() || font.is_empty() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
let undo = self.begin_text_style_undo(
|
let undo = self.begin_text_style_undo(
|
||||||
i,
|
i,
|
||||||
|
|
@ -1178,12 +1178,12 @@ impl OpenCADStudio {
|
||||||
.scene
|
.scene
|
||||||
.invalidate_text_style_dependencies(&style_name);
|
.invalidate_text_style_dependencies(&style_name);
|
||||||
self.commit_text_style_undo(i, undo);
|
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}'."
|
"{prefix}: '{style_name}' font set to '{font}'."
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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
|
.scene
|
||||||
.invalidate_text_style_dependencies(&style_name);
|
.invalidate_text_style_dependencies(&style_name);
|
||||||
self.commit_text_style_undo(i, undo);
|
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}."
|
"{prefix}: '{style_name}' width factor set to {factor:.3}."
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"{prefix}: style '{style_name}' not found."
|
"{prefix}: style '{style_name}' not found."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("Usage: {prefix} WIDTH <style> <factor>"));
|
.push_error(crate::tf!("Usage: {prefix} WIDTH <style> <factor>").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"OBLIQUE" => {
|
"OBLIQUE" => {
|
||||||
|
|
@ -1238,24 +1238,24 @@ impl OpenCADStudio {
|
||||||
.scene
|
.scene
|
||||||
.invalidate_text_style_dependencies(&style_name);
|
.invalidate_text_style_dependencies(&style_name);
|
||||||
self.commit_text_style_undo(i, undo);
|
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}°."
|
"{prefix}: '{style_name}' oblique angle set to {deg:.1}°."
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"{prefix}: style '{style_name}' not found."
|
"{prefix}: style '{style_name}' not found."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"Usage: {prefix} OBLIQUE <style> <angle_degrees>"
|
"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>"
|
"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.tabs[i].dirty = true;
|
||||||
self.commit_layer_undo(i, undo);
|
self.commit_layer_undo(i, undo);
|
||||||
self.refresh_layer_panel();
|
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.tabs[i].dirty = true;
|
||||||
self.commit_layer_undo(i, undo);
|
self.commit_layer_undo(i, undo);
|
||||||
self.refresh_layer_panel();
|
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 ") => {
|
cmd if cmd.starts_with("LAYDEL ") => {
|
||||||
let name = cmd.trim_start_matches("LAYDEL").trim();
|
let name = cmd.trim_start_matches("LAYDEL").trim();
|
||||||
if name.is_empty() {
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
let resolved = self.tabs[i]
|
let resolved = self.tabs[i]
|
||||||
|
|
@ -100,12 +100,12 @@ impl OpenCADStudio {
|
||||||
.map(|s| s.to_string());
|
.map(|s| s.to_string());
|
||||||
let Some(layer) = resolved else {
|
let Some(layer) = resolved else {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
};
|
};
|
||||||
if layer == "0" {
|
if layer == "0" {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
if layer.eq_ignore_ascii_case(&self.tabs[i].active_layer) {
|
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].scene.bump_geometry();
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_layer_panel();
|
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)."
|
"LAYDEL: deleted layer \"{layer}\" and {n} object(s)."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
// LAYMRG <source> <target> — move every object from <source> onto
|
// LAYMRG <source> <target> — move every object from <source> onto
|
||||||
|
|
@ -152,7 +152,7 @@ impl OpenCADStudio {
|
||||||
let parts: Vec<&str> = rest.split_whitespace().collect();
|
let parts: Vec<&str> = rest.split_whitespace().collect();
|
||||||
if parts.len() != 2 {
|
if parts.len() != 2 {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
let keys: Vec<String> = self.tabs[i]
|
let keys: Vec<String> = self.tabs[i]
|
||||||
|
|
@ -172,17 +172,17 @@ impl OpenCADStudio {
|
||||||
.cloned();
|
.cloned();
|
||||||
let (Some(src), Some(dst)) = (src, dst) else {
|
let (Some(src), Some(dst)) = (src, dst) else {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
};
|
};
|
||||||
if src == dst {
|
if src == dst {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
if src == "0" {
|
if src == "0" {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
if src.eq_ignore_ascii_case(&self.tabs[i].active_layer) {
|
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));
|
.invalidate_layer_dependencies(std::slice::from_ref(&dst));
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_layer_panel();
|
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))."
|
"LAYMRG: merged \"{src}\" into \"{dst}\" ({moved} object(s))."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
// LAYERSTATE — save / restore named snapshots of all layer states
|
// LAYERSTATE — save / restore named snapshots of all layer states
|
||||||
|
|
@ -241,12 +241,12 @@ impl OpenCADStudio {
|
||||||
states.iter().map(|state| state.name.as_str()).collect();
|
states.iter().map(|state| state.name.as_str()).collect();
|
||||||
names.sort_unstable();
|
names.sort_unstable();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Saved layer states: {}", names.join(", ")));
|
.push_output(crate::tf!("Saved layer states: {}", names.join(", ")).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"SAVE" | "S" => {
|
"SAVE" | "S" => {
|
||||||
if arg.is_empty() {
|
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 {
|
} else {
|
||||||
let description = self.tabs[i]
|
let description = self.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
|
|
@ -261,17 +261,17 @@ impl OpenCADStudio {
|
||||||
.capture_layer_state(arg, description);
|
.capture_layer_state(arg, description);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("LAYERSTATE: saved \"{arg}\"."));
|
.push_output(crate::tf!("LAYERSTATE: saved \"{arg}\".").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"RESTORE" | "R" => {
|
"RESTORE" | "R" => {
|
||||||
if arg.is_empty() {
|
if arg.is_empty() {
|
||||||
self.command_line
|
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() {
|
} 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}\"."
|
"LAYERSTATE: no saved state named \"{arg}\"."
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
let names: Vec<String> = self.tabs[i]
|
let names: Vec<String> = self.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
|
|
@ -295,30 +295,30 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.invalidate_layer_dependencies(&names);
|
self.tabs[i].scene.invalidate_layer_dependencies(&names);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_layer_panel();
|
self.refresh_layer_panel();
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"LAYERSTATE: restored \"{arg}\" ({n} layer(s))."
|
"LAYERSTATE: restored \"{arg}\" ({n} layer(s))."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"DELETE" | "D" => {
|
"DELETE" | "D" => {
|
||||||
if arg.is_empty() {
|
if arg.is_empty() {
|
||||||
self.command_line
|
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() {
|
} 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}\"."
|
"LAYERSTATE: no saved state named \"{arg}\"."
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.push_undo_snapshot(i, "LAYERSTATE DELETE");
|
self.push_undo_snapshot(i, "LAYERSTATE DELETE");
|
||||||
self.tabs[i].scene.document.delete_layer_state(arg);
|
self.tabs[i].scene.document.delete_layer_state(arg);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("LAYERSTATE: deleted \"{arg}\"."));
|
.push_output(crate::tf!("LAYERSTATE: deleted \"{arg}\".").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.command_line
|
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.tabs[i].dirty = true;
|
||||||
self.commit_layer_undo(i, undo);
|
self.commit_layer_undo(i, undo);
|
||||||
self.refresh_layer_panel();
|
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].layers.current_layer = layer.clone();
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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();
|
self.refresh_layer_panel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -408,7 +408,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.commit_layer_undo(i, undo);
|
self.commit_layer_undo(i, undo);
|
||||||
self.refresh_layer_panel();
|
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" => {
|
"LAYTHW" => {
|
||||||
|
|
@ -429,7 +429,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.commit_layer_undo(i, undo);
|
self.commit_layer_undo(i, undo);
|
||||||
self.refresh_layer_panel();
|
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" => {
|
"LAYULK" => {
|
||||||
|
|
@ -462,7 +462,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.commit_layer_undo(i, undo);
|
self.commit_layer_undo(i, undo);
|
||||||
self.refresh_layer_panel();
|
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();
|
.collect();
|
||||||
if sel_layers.is_empty() {
|
if sel_layers.is_empty() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
let names: Vec<String> = self.tabs[i]
|
let names: Vec<String> = self.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
|
|
@ -498,7 +498,7 @@ impl OpenCADStudio {
|
||||||
self.commit_layer_undo(i, undo);
|
self.commit_layer_undo(i, undo);
|
||||||
self.refresh_layer_panel();
|
self.refresh_layer_panel();
|
||||||
self.command_line
|
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" => {
|
"ISOLATEOBJECTS" => {
|
||||||
if self.tabs[i].scene.selected.is_empty() {
|
if self.tabs[i].scene.selected.is_empty() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
let n = self.tabs[i].scene.selected.len();
|
let n = self.tabs[i].scene.selected.len();
|
||||||
let before = self.tabs[i].scene.object_isolation.clone();
|
let before = self.tabs[i].scene.object_isolation.clone();
|
||||||
|
|
@ -519,9 +519,9 @@ impl OpenCADStudio {
|
||||||
before,
|
before,
|
||||||
selected_before,
|
selected_before,
|
||||||
);
|
);
|
||||||
self.command_line.push_info(&format!(
|
self.command_line.push_info(crate::tf!(
|
||||||
"Isolated {n} object(s). UNISOLATEOBJECTS to restore."
|
"Isolated {n} object(s). UNISOLATEOBJECTS to restore."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -529,7 +529,7 @@ impl OpenCADStudio {
|
||||||
"HIDEOBJECTS" => {
|
"HIDEOBJECTS" => {
|
||||||
if self.tabs[i].scene.selected.is_empty() {
|
if self.tabs[i].scene.selected.is_empty() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
let n = self.tabs[i].scene.selected.len();
|
let n = self.tabs[i].scene.selected.len();
|
||||||
let before = self.tabs[i].scene.object_isolation.clone();
|
let before = self.tabs[i].scene.object_isolation.clone();
|
||||||
|
|
@ -544,7 +544,7 @@ impl OpenCADStudio {
|
||||||
);
|
);
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
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,
|
selected_before,
|
||||||
);
|
);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info("Isolation ended — all objects shown.");
|
.push_info(crate::t!("Isolation ended — all objects shown.").as_ref());
|
||||||
} else {
|
} 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.commit_layer_undo(i, undo);
|
||||||
self.refresh_layer_panel();
|
self.refresh_layer_panel();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info("LAYUNISO: all layers restored.");
|
.push_info(crate::t!("LAYUNISO: all layers restored.").as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
"LAYMATCH" | "LAYMCH" => {
|
"LAYMATCH" | "LAYMCH" => {
|
||||||
|
|
@ -653,10 +653,10 @@ impl OpenCADStudio {
|
||||||
self.commit_group_undo(i, undo);
|
self.commit_group_undo(i, undo);
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info(&format!("{} group(s) dissolved.", count));
|
.push_info(crate::tf!("{} group(s) dissolved.", count).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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).
|
// rather than keeping a second, blunter copy (#388, #389).
|
||||||
if self.tabs[i].is_start && !start_allowed(cmd) {
|
if self.tabs[i].is_start && !start_allowed(cmd) {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,7 +164,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("Unknown command: {cmd}"));
|
.push_error(crate::tf!("Unknown command: {cmd}").as_ref());
|
||||||
self.finish_dispatch(cmd)
|
self.finish_dispatch(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ impl OpenCADStudio {
|
||||||
"" => {
|
"" => {
|
||||||
let c = self.tabs[i].scene.document.header.current_entity_color;
|
let c = self.tabs[i].scene.document.header.current_entity_color;
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
"BYLAYER" => Some(Color::ByLayer),
|
"BYLAYER" => Some(Color::ByLayer),
|
||||||
|
|
@ -58,7 +58,7 @@ impl OpenCADStudio {
|
||||||
self.ribbon.active_color = c;
|
self.ribbon.active_color = c;
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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 => {
|
None => {
|
||||||
self.command_line.push_error(
|
self.command_line.push_error(
|
||||||
|
|
@ -96,10 +96,10 @@ impl OpenCADStudio {
|
||||||
.map(|lt| format!("{} ({})", lt.name, lt.description))
|
.map(|lt| format!("{} ({})", lt.name, lt.description))
|
||||||
.collect();
|
.collect();
|
||||||
if ltypes.is_empty() {
|
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 {
|
} else {
|
||||||
self.command_line
|
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.
|
// Set the current linetype applied to newly drawn entities.
|
||||||
|
|
@ -107,7 +107,7 @@ impl OpenCADStudio {
|
||||||
let name = parts.get(1).copied().unwrap_or("");
|
let name = parts.get(1).copied().unwrap_or("");
|
||||||
if name.is_empty() {
|
if name.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info("Usage: LINETYPE SET <name | ByLayer | ByBlock>");
|
.push_info(crate::t!("Usage: LINETYPE SET <name | ByLayer | ByBlock>").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let canon = if name.eq_ignore_ascii_case("BYLAYER") {
|
let canon = if name.eq_ignore_ascii_case("BYLAYER") {
|
||||||
Some(("ByLayer".to_string(), acadrust::types::Handle::NULL))
|
Some(("ByLayer".to_string(), acadrust::types::Handle::NULL))
|
||||||
|
|
@ -129,19 +129,19 @@ impl OpenCADStudio {
|
||||||
h.current_linetype_handle = handle;
|
h.current_linetype_handle = handle;
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Current linetype set to {nm}."));
|
.push_output(crate::tf!("Current linetype set to {nm}.").as_ref());
|
||||||
}
|
}
|
||||||
None => {
|
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."
|
"LINETYPE: \"{name}\" is not loaded. Use LINETYPE LIST to see available linetypes."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.command_line
|
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_lts = all || matches!(sub.as_str(), "LINETYPES" | "LT");
|
||||||
let do_blocks = all || matches!(sub.as_str(), "BLOCKS" | "BLOCK" | "B");
|
let do_blocks = all || matches!(sub.as_str(), "BLOCKS" | "BLOCK" | "B");
|
||||||
if !(do_layers || do_styles || do_lts || do_blocks) {
|
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."
|
"PURGE: unknown option \"{sub}\" — use ALL, Blocks, LAyers, LineTypes or STyles."
|
||||||
));
|
).as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -560,13 +560,13 @@ impl OpenCADStudio {
|
||||||
if n_sortents > 0 {
|
if n_sortents > 0 {
|
||||||
parts.push(format!("{n_sortents} stale draw-order table(s)"));
|
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 — {}.",
|
"PURGE: {} item(s) removed — {}.",
|
||||||
purged + n_sortents,
|
purged + n_sortents,
|
||||||
parts.join(", ")
|
parts.join(", ")
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} 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();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("CHPROP: no entities selected.");
|
.push_error(crate::t!("CHPROP: no entities selected.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
// Validate value early to give clear errors
|
// Validate value early to give clear errors
|
||||||
let color_val: Option<acadrust::types::Color> = if prop == "COLOR" {
|
let color_val: Option<acadrust::types::Color> = if prop == "COLOR" {
|
||||||
|
|
@ -640,10 +640,10 @@ impl OpenCADStudio {
|
||||||
|| (prop == "LTSCALE" && ltscale_val.is_none())
|
|| (prop == "LTSCALE" && ltscale_val.is_none())
|
||||||
|| (prop == "TRANSPARENCY" && transparency_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 {}.",
|
"CHPROP: invalid value '{}' for {}.",
|
||||||
value, prop
|
value, prop
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
let mut changed = 0usize;
|
let mut changed = 0usize;
|
||||||
for handle in &handles {
|
for handle in &handles {
|
||||||
|
|
@ -673,9 +673,9 @@ impl OpenCADStudio {
|
||||||
changed += 1;
|
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
|
"CHPROP: unknown property '{}'. Use: LAYER COLOR LINETYPE LTSCALE TRANSPARENCY", prop
|
||||||
));
|
).as_ref());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -689,10 +689,10 @@ impl OpenCADStudio {
|
||||||
// re-tessellate the changed entities so they
|
// re-tessellate the changed entities so they
|
||||||
// repaint immediately (issue #231 class).
|
// repaint immediately (issue #231 class).
|
||||||
self.invalidate_property_targets(i, &handles);
|
self.invalidate_property_targets(i, &handles);
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"CHPROP: {} entity/entities updated.",
|
"CHPROP: {} entity/entities updated.",
|
||||||
changed
|
changed
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -711,7 +711,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("SETBYLAYER: select entities first.");
|
.push_error(crate::t!("SETBYLAYER: select entities first.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.push_undo_snapshot(i, "SETBYLAYER");
|
self.push_undo_snapshot(i, "SETBYLAYER");
|
||||||
let mut changed = 0usize;
|
let mut changed = 0usize;
|
||||||
|
|
@ -730,9 +730,9 @@ impl OpenCADStudio {
|
||||||
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
||||||
.collect();
|
.collect();
|
||||||
self.tabs[i].scene.bump_entities(&changes);
|
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."
|
"SETBYLAYER: reset {changed} entity/entities to ByLayer."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -778,7 +778,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if dups.is_empty() {
|
if dups.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output("OVERKILL: no duplicate objects found.");
|
.push_output(crate::t!("OVERKILL: no duplicate objects found.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let n = dups.len();
|
let n = dups.len();
|
||||||
self.push_undo_snapshot(i, "OVERKILL");
|
self.push_undo_snapshot(i, "OVERKILL");
|
||||||
|
|
@ -786,7 +786,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
u8::from(self.pick_drag_rect)
|
u8::from(self.pick_drag_rect)
|
||||||
};
|
};
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"{} = {v}",
|
"{} = {v}",
|
||||||
if is_add { "PICKADD" } else { "PICKDRAG" }
|
if is_add { "PICKADD" } else { "PICKDRAG" }
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
match arg {
|
match arg {
|
||||||
"0" | "1" => {
|
"0" | "1" => {
|
||||||
let on = arg == "1";
|
let on = arg == "1";
|
||||||
if is_add {
|
if is_add {
|
||||||
self.pick_add = on;
|
self.pick_add = on;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"PICKADD = {} ({})",
|
"PICKADD = {} ({})",
|
||||||
arg,
|
arg,
|
||||||
if on {
|
if on {
|
||||||
|
|
@ -831,10 +831,10 @@ impl OpenCADStudio {
|
||||||
} else {
|
} else {
|
||||||
"click replaces selection, Shift toggles"
|
"click replaces selection, Shift toggles"
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.pick_drag_rect = on;
|
self.pick_drag_rect = on;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"PICKDRAG = {} ({})",
|
"PICKDRAG = {} ({})",
|
||||||
arg,
|
arg,
|
||||||
if on {
|
if on {
|
||||||
|
|
@ -842,14 +842,14 @@ impl OpenCADStudio {
|
||||||
} else {
|
} else {
|
||||||
"press-drag lassoes"
|
"press-drag lassoes"
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
self.persist_settings_if_changed();
|
self.persist_settings_if_changed();
|
||||||
}
|
}
|
||||||
_ => self.command_line.push_error(&format!(
|
_ => self.command_line.push_error(crate::tf!(
|
||||||
"{}: expected 0 or 1.",
|
"{}: expected 0 or 1.",
|
||||||
if is_add { "PICKADD" } else { "PICKDRAG" }
|
if is_add { "PICKADD" } else { "PICKDRAG" }
|
||||||
)),
|
).as_ref()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1586,9 +1586,9 @@ impl OpenCADStudio {
|
||||||
// prompt for a new value on the next line instead
|
// prompt for a new value on the next line instead
|
||||||
// of only echoing the current one. Enter keeps it.
|
// of only echoing the current one. Enter keeps it.
|
||||||
let current = msg.split('=').nth(1).map(str::trim).unwrap_or("");
|
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}>:"
|
"Enter new value for {name} <{current}>:"
|
||||||
));
|
).as_ref());
|
||||||
self.pending_setvar = Some(name.clone());
|
self.pending_setvar = Some(name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1667,15 +1667,15 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.command_line
|
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
|
self.command_line
|
||||||
.push_output(&format!(" Layers: {}", fmt(layers)));
|
.push_output(crate::tf!(" Layers: {}", fmt(layers)).as_ref());
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!(" Linetypes: {}", fmt(linetypes)));
|
.push_output(crate::tf!(" Linetypes: {}", fmt(linetypes)).as_ref());
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!(" Text styles: {}", fmt(styles)));
|
.push_output(crate::tf!(" Text styles: {}", fmt(styles)).as_ref());
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!(" Blocks: {}", fmt(blocks)));
|
.push_output(crate::tf!(" Blocks: {}", fmt(blocks)).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── AUDIT — report drawing-database integrity issues ─────────
|
// ── AUDIT — report drawing-database integrity issues ─────────
|
||||||
|
|
@ -1703,24 +1703,24 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.command_line
|
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() {
|
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 {
|
} else {
|
||||||
if !undefined_layers.is_empty() {
|
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): {}",
|
"AUDIT: reference(s) to undefined layer(s): {}",
|
||||||
undefined_layers.into_iter().collect::<Vec<_>>().join(", ")
|
undefined_layers.into_iter().collect::<Vec<_>>().join(", ")
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
if !undefined_blocks.is_empty() {
|
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): {}",
|
"AUDIT: reference(s) to undefined block(s): {}",
|
||||||
undefined_blocks.into_iter().collect::<Vec<_>>().join(", ")
|
undefined_blocks.into_iter().collect::<Vec<_>>().join(", ")
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
self.command_line
|
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() {
|
if type_str.is_empty() || old_name.is_empty() || new_name.is_empty() {
|
||||||
self.command_line.push_info(
|
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 {
|
} else {
|
||||||
// Snapshot BEFORE mutating (undo must restore the old
|
// Snapshot BEFORE mutating (undo must restore the old
|
||||||
|
|
@ -1789,21 +1789,21 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("RENAME: '{}' → '{}'.", old_name, new_name));
|
.push_output(crate::tf!("RENAME: '{}' → '{}'.", old_name, new_name).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.discard_last_undo_entry(i);
|
self.discard_last_undo_entry(i);
|
||||||
if !known {
|
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" {
|
} 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.",
|
"RENAME: could not rename block '{}' — missing/anonymous/xref, or '{}' is invalid or taken.",
|
||||||
old_name, new_name
|
old_name, new_name
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} 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.",
|
"RENAME: could not rename '{}' in {} — not found or protected, or '{}' is invalid or taken.",
|
||||||
old_name, type_str, new_name
|
old_name, type_str, new_name
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1825,17 +1825,17 @@ impl OpenCADStudio {
|
||||||
if name_arg.is_empty() {
|
if name_arg.is_empty() {
|
||||||
let cur = &self.tabs[i].scene.document.header.current_layer_name;
|
let cur = &self.tabs[i].scene.document.header.current_layer_name;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("CLAYER = \"{cur}\""));
|
.push_output(crate::tf!("CLAYER = \"{cur}\"").as_ref());
|
||||||
} else {
|
} else {
|
||||||
if self.tabs[i].scene.document.layers.contains(name_arg) {
|
if self.tabs[i].scene.document.layers.contains(name_arg) {
|
||||||
self.tabs[i].scene.document.header.current_layer_name =
|
self.tabs[i].scene.document.header.current_layer_name =
|
||||||
name_arg.to_string();
|
name_arg.to_string();
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("CLAYER set to \"{name_arg}\""));
|
.push_output(crate::tf!("CLAYER set to \"{name_arg}\"").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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() {
|
if name_arg.is_empty() {
|
||||||
let cur = &self.tabs[i].scene.document.header.current_dimstyle_name;
|
let cur = &self.tabs[i].scene.document.header.current_dimstyle_name;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("CDIMSTY = \"{cur}\""));
|
.push_output(crate::tf!("CDIMSTY = \"{cur}\"").as_ref());
|
||||||
} else {
|
} else {
|
||||||
if self.tabs[i].scene.document.dim_styles.contains(&name_arg) {
|
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].scene.document.header.current_dimstyle_name = name_arg.clone();
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
self.command_line
|
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();
|
let val_str = cmd.trim_start_matches("LTSCALE").trim();
|
||||||
if val_str.is_empty() {
|
if val_str.is_empty() {
|
||||||
let v = self.tabs[i].scene.document.header.linetype_scale;
|
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>() {
|
} else if let Ok(v) = val_str.parse::<f64>() {
|
||||||
if v > 0.0 {
|
if v > 0.0 {
|
||||||
self.push_undo_snapshot(i, "LTSCALE");
|
self.push_undo_snapshot(i, "LTSCALE");
|
||||||
self.tabs[i].scene.document.header.linetype_scale = v;
|
self.tabs[i].scene.document.header.linetype_scale = v;
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("LTSCALE set to {v:.4}"));
|
.push_output(crate::tf!("LTSCALE set to {v:.4}").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("LTSCALE: value must be positive.");
|
.push_error(crate::t!("LTSCALE: value must be positive.").as_ref());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_error("Usage: LTSCALE [value]");
|
self.command_line.push_error(crate::t!("Usage: LTSCALE [value]").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"PDMODE" => {
|
"PDMODE" => {
|
||||||
|
|
@ -1903,14 +1903,14 @@ impl OpenCADStudio {
|
||||||
let val_str = cmd.trim_start_matches("PDMODE").trim();
|
let val_str = cmd.trim_start_matches("PDMODE").trim();
|
||||||
if val_str.is_empty() {
|
if val_str.is_empty() {
|
||||||
let v = self.tabs[i].scene.document.header.point_display_mode;
|
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>() {
|
} else if let Ok(v) = val_str.parse::<i16>() {
|
||||||
self.push_undo_snapshot(i, "PDMODE");
|
self.push_undo_snapshot(i, "PDMODE");
|
||||||
self.tabs[i].scene.document.header.point_display_mode = v;
|
self.tabs[i].scene.document.header.point_display_mode = v;
|
||||||
// Point glyphs are built at tessellation time — rebuild them.
|
// Point glyphs are built at tessellation time — rebuild them.
|
||||||
self.tabs[i].scene.invalidate_point_dependencies();
|
self.tabs[i].scene.invalidate_point_dependencies();
|
||||||
self.tabs[i].dirty = true;
|
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 {
|
} else {
|
||||||
self.command_line.push_error(
|
self.command_line.push_error(
|
||||||
"Usage: PDMODE [value] (0=dot 1=none 2=+ 3=x 4=tick; +32 circle, +64 square)",
|
"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() {
|
if val_str.is_empty() {
|
||||||
let v = if self.texteditmode { 1 } else { 0 };
|
let v = if self.texteditmode { 1 } else { 0 };
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("TEXTEDITMODE = {v}"));
|
.push_output(crate::tf!("TEXTEDITMODE = {v}").as_ref());
|
||||||
} else if let Some(v) =
|
} else if let Some(v) =
|
||||||
crate::modules::annotate::textedit::parse_texteditmode(&val_str)
|
crate::modules::annotate::textedit::parse_texteditmode(&val_str)
|
||||||
{
|
{
|
||||||
self.texteditmode = v;
|
self.texteditmode = v;
|
||||||
let n = if v { 1 } else { 0 };
|
let n = if v { 1 } else { 0 };
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("TEXTEDITMODE set to {n}"));
|
.push_output(crate::tf!("TEXTEDITMODE set to {n}").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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" => {
|
"ISAVEBAK" => {
|
||||||
|
|
@ -1946,19 +1946,19 @@ impl OpenCADStudio {
|
||||||
match cmd.trim_start_matches("ISAVEBAK").trim() {
|
match cmd.trim_start_matches("ISAVEBAK").trim() {
|
||||||
"" => {
|
"" => {
|
||||||
let v = if self.backup_on_save { 1 } else { 0 };
|
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" => {
|
"0" => {
|
||||||
self.backup_on_save = false;
|
self.backup_on_save = false;
|
||||||
self.persist_settings_if_changed();
|
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" => {
|
"1" => {
|
||||||
self.backup_on_save = true;
|
self.backup_on_save = true;
|
||||||
self.persist_settings_if_changed();
|
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" => {
|
"FILEASSOC" => {
|
||||||
|
|
@ -1974,7 +1974,7 @@ impl OpenCADStudio {
|
||||||
match cmd.trim_start_matches("FILEASSOC").trim() {
|
match cmd.trim_start_matches("FILEASSOC").trim() {
|
||||||
"" => {
|
"" => {
|
||||||
let v = if self.file_assoc_enabled { 1 } else { 0 };
|
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" => {
|
"1" => {
|
||||||
self.file_assoc_enabled = true;
|
self.file_assoc_enabled = true;
|
||||||
|
|
@ -1985,7 +1985,7 @@ impl OpenCADStudio {
|
||||||
),
|
),
|
||||||
Err(e) => self
|
Err(e) => self
|
||||||
.command_line
|
.command_line
|
||||||
.push_error(&format!("FILEASSOC: registration failed: {e}")),
|
.push_error(crate::tf!("FILEASSOC: registration failed: {e}").as_ref()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"0" => {
|
"0" => {
|
||||||
|
|
@ -1994,13 +1994,13 @@ impl OpenCADStudio {
|
||||||
match crate::io::file_association::unregister_handler() {
|
match crate::io::file_association::unregister_handler() {
|
||||||
Ok(()) => self
|
Ok(()) => self
|
||||||
.command_line
|
.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
|
Err(e) => self
|
||||||
.command_line
|
.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" => {
|
"SAVETIME" => {
|
||||||
|
|
@ -2016,7 +2016,7 @@ impl OpenCADStudio {
|
||||||
let arg = cmd.trim_start_matches("SAVETIME").trim();
|
let arg = cmd.trim_start_matches("SAVETIME").trim();
|
||||||
if arg.is_empty() {
|
if arg.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("SAVETIME = {}", self.savetime_min));
|
.push_output(crate::tf!("SAVETIME = {}", self.savetime_min).as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
match arg.parse::<i32>() {
|
match arg.parse::<i32>() {
|
||||||
|
|
@ -2032,7 +2032,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
_ => self
|
_ => self
|
||||||
.command_line
|
.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" => {
|
"PDSIZE" => {
|
||||||
|
|
@ -2048,14 +2048,14 @@ impl OpenCADStudio {
|
||||||
let val_str = cmd.trim_start_matches("PDSIZE").trim();
|
let val_str = cmd.trim_start_matches("PDSIZE").trim();
|
||||||
if val_str.is_empty() {
|
if val_str.is_empty() {
|
||||||
let v = self.tabs[i].scene.document.header.point_display_size;
|
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>() {
|
} else if let Ok(v) = val_str.parse::<f64>() {
|
||||||
self.push_undo_snapshot(i, "PDSIZE");
|
self.push_undo_snapshot(i, "PDSIZE");
|
||||||
self.tabs[i].scene.document.header.point_display_size = v;
|
self.tabs[i].scene.document.header.point_display_size = v;
|
||||||
self.tabs[i].scene.invalidate_point_dependencies();
|
self.tabs[i].scene.invalidate_point_dependencies();
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("PDSIZE set to {v:.4}"));
|
.push_output(crate::tf!("PDSIZE set to {v:.4}").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_error(
|
self.command_line.push_error(
|
||||||
"Usage: PDSIZE [value] (>0 absolute size, <0 percent of viewport, 0 default)",
|
"Usage: PDSIZE [value] (>0 absolute size, <0 percent of viewport, 0 default)",
|
||||||
|
|
@ -2087,19 +2087,19 @@ impl OpenCADStudio {
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
};
|
};
|
||||||
match parsed {
|
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)) => {
|
Ok(Some(v)) => {
|
||||||
self.push_undo_snapshot(i, "LWDISPLAY");
|
self.push_undo_snapshot(i, "LWDISPLAY");
|
||||||
self.tabs[i].scene.document.header.lineweight_display = v;
|
self.tabs[i].scene.document.header.lineweight_display = v;
|
||||||
// No retessellate — the wire shader honours the flag via uniforms.
|
// No retessellate — the wire shader honours the flag via uniforms.
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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) => {
|
Ok(None) => {
|
||||||
let v = self.tabs[i].scene.document.header.lineweight_display;
|
let v = self.tabs[i].scene.document.header.lineweight_display;
|
||||||
self.command_line
|
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
|
.header
|
||||||
.current_entity_linetype_scale;
|
.current_entity_linetype_scale;
|
||||||
self.command_line
|
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>() {
|
} else if let Ok(v) = val_str.parse::<f64>() {
|
||||||
if v > 0.0 {
|
if v > 0.0 {
|
||||||
self.tabs[i]
|
self.tabs[i]
|
||||||
|
|
@ -2131,13 +2131,13 @@ impl OpenCADStudio {
|
||||||
.current_entity_linetype_scale = v;
|
.current_entity_linetype_scale = v;
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("CELTSCALE set to {v:.4}"));
|
.push_output(crate::tf!("CELTSCALE set to {v:.4}").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("CELTSCALE: value must be positive.");
|
.push_error(crate::t!("CELTSCALE: value must be positive.").as_ref());
|
||||||
}
|
}
|
||||||
} else {
|
} 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();
|
.collect();
|
||||||
if selected_handles.is_empty() {
|
if selected_handles.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("SCALETEXT: select Text/MText entities first.");
|
.push_error(crate::t!("SCALETEXT: select Text/MText entities first.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
let (use_absolute, value) = match (
|
let (use_absolute, value) = match (
|
||||||
parts.first().map(|s| s.to_uppercase()).as_deref(),
|
parts.first().map(|s| s.to_uppercase()).as_deref(),
|
||||||
|
|
@ -2179,7 +2179,7 @@ impl OpenCADStudio {
|
||||||
if let Some(val) = value {
|
if let Some(val) = value {
|
||||||
if val <= 0.0 {
|
if val <= 0.0 {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("SCALETEXT: value must be positive.");
|
.push_error(crate::t!("SCALETEXT: value must be positive.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.push_undo_snapshot(i, "SCALETEXT");
|
self.push_undo_snapshot(i, "SCALETEXT");
|
||||||
let mut count = 0usize;
|
let mut count = 0usize;
|
||||||
|
|
@ -2206,17 +2206,17 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"SCALETEXT: scaled {count} text entity(ies)."
|
"SCALETEXT: scaled {count} text entity(ies)."
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("SCALETEXT: no Text/MText in selection.");
|
.push_error(crate::t!("SCALETEXT: no Text/MText in selection.").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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>> {
|
pub(super) fn dispatch_view(&mut self, cmd: &str, i: usize) -> Option<Task<Message>> {
|
||||||
match cmd {
|
match cmd {
|
||||||
"DONATE" => {
|
"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(
|
return Some(crate::sys::open_url(
|
||||||
"https://patreon.com/HakanSeven12",
|
"https://patreon.com/HakanSeven12",
|
||||||
self.main_window,
|
self.main_window,
|
||||||
|
|
@ -12,7 +12,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
|
|
||||||
"WEBVERSION" => {
|
"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(
|
return Some(crate::sys::open_url(
|
||||||
"https://hakanseven12.github.io/OpenCADStudio/",
|
"https://hakanseven12.github.io/OpenCADStudio/",
|
||||||
self.main_window,
|
self.main_window,
|
||||||
|
|
@ -21,7 +21,7 @@ impl OpenCADStudio {
|
||||||
|
|
||||||
"HELP" => {
|
"HELP" => {
|
||||||
self.command_line
|
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(
|
return Some(crate::sys::open_url(
|
||||||
"https://github.com/HakanSeven12/OpenCADStudio/discussions",
|
"https://github.com/HakanSeven12/OpenCADStudio/discussions",
|
||||||
self.main_window,
|
self.main_window,
|
||||||
|
|
@ -41,78 +41,78 @@ impl OpenCADStudio {
|
||||||
.map(|p| p.display().to_string())
|
.map(|p| p.display().to_string())
|
||||||
.unwrap_or_else(|| "(unsaved)".to_string());
|
.unwrap_or_else(|| "(unsaved)".to_string());
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Drawing: {}", path_label));
|
.push_output(crate::tf!("Drawing: {}", path_label).as_ref());
|
||||||
self.command_line
|
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
|
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
|
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
|
self.command_line
|
||||||
.push_output(&format!(" User elapsed: {:.4}", h.user_elapsed_time));
|
.push_output(crate::tf!(" User elapsed: {:.4}", h.user_elapsed_time).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" Last saved by: {}",
|
" Last saved by: {}",
|
||||||
if h.last_saved_by.is_empty() {
|
if h.last_saved_by.is_empty() {
|
||||||
"(unknown)"
|
"(unknown)"
|
||||||
} else {
|
} else {
|
||||||
&h.last_saved_by
|
&h.last_saved_by
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" Fingerprint GUID: {}",
|
" Fingerprint GUID: {}",
|
||||||
if h.fingerprint_guid.is_empty() {
|
if h.fingerprint_guid.is_empty() {
|
||||||
"(none)"
|
"(none)"
|
||||||
} else {
|
} else {
|
||||||
&h.fingerprint_guid
|
&h.fingerprint_guid
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" Version GUID: {}",
|
" Version GUID: {}",
|
||||||
if h.version_guid.is_empty() {
|
if h.version_guid.is_empty() {
|
||||||
"(none)"
|
"(none)"
|
||||||
} else {
|
} else {
|
||||||
&h.version_guid
|
&h.version_guid
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!(" Code page: {}", h.code_page));
|
.push_output(crate::tf!(" Code page: {}", h.code_page).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" Menu name: {}",
|
" Menu name: {}",
|
||||||
if h.menu_name.is_empty() {
|
if h.menu_name.is_empty() {
|
||||||
"(none)"
|
"(none)"
|
||||||
} else {
|
} else {
|
||||||
&h.menu_name
|
&h.menu_name
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" Hyperlink base: {}",
|
" Hyperlink base: {}",
|
||||||
if h.hyperlink_base.is_empty() {
|
if h.hyperlink_base.is_empty() {
|
||||||
"(none)"
|
"(none)"
|
||||||
} else {
|
} else {
|
||||||
&h.hyperlink_base
|
&h.hyperlink_base
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" Project name: {}",
|
" Project name: {}",
|
||||||
if h.project_name.is_empty() {
|
if h.project_name.is_empty() {
|
||||||
"(none)"
|
"(none)"
|
||||||
} else {
|
} else {
|
||||||
&h.project_name
|
&h.project_name
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" Stylesheet: {}",
|
" Stylesheet: {}",
|
||||||
if h.stylesheet.is_empty() {
|
if h.stylesheet.is_empty() {
|
||||||
"(none)"
|
"(none)"
|
||||||
} else {
|
} else {
|
||||||
&h.stylesheet
|
&h.stylesheet
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" Required versions: {:#018x}",
|
" Required versions: {:#018x}",
|
||||||
h.required_versions
|
h.required_versions
|
||||||
));
|
).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" Measurement: {} ({})",
|
" Measurement: {} ({})",
|
||||||
h.measurement,
|
h.measurement,
|
||||||
if h.measurement == 1 {
|
if h.measurement == 1 {
|
||||||
|
|
@ -120,23 +120,23 @@ impl OpenCADStudio {
|
||||||
} else {
|
} else {
|
||||||
"Imperial"
|
"Imperial"
|
||||||
}
|
}
|
||||||
));
|
).as_ref());
|
||||||
self.command_line
|
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
|
self.command_line
|
||||||
.push_output(&format!(" Tree depth: {}", h.tree_depth));
|
.push_output(crate::tf!(" Tree depth: {}", h.tree_depth).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" User vars (int): {} {} {} {} {}",
|
" User vars (int): {} {} {} {} {}",
|
||||||
h.user_int1, h.user_int2, h.user_int3, h.user_int4, h.user_int5
|
h.user_int1, h.user_int2, h.user_int3, h.user_int4, h.user_int5
|
||||||
));
|
).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" User vars (real): {:.6} {:.6} {:.6} {:.6} {:.6}",
|
" User vars (real): {:.6} {:.6} {:.6} {:.6} {:.6}",
|
||||||
h.user_real1, h.user_real2, h.user_real3, h.user_real4, h.user_real5
|
h.user_real1, h.user_real2, h.user_real3, h.user_real4, h.user_real5
|
||||||
));
|
).as_ref());
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
" User timer: {}",
|
" User timer: {}",
|
||||||
if h.user_timer { "On" } else { "Off" }
|
if h.user_timer { "On" } else { "Off" }
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edit a USERI1..USERI5 / USERR1..USERR5 slot. Lets the user
|
// Edit a USERI1..USERI5 / USERR1..USERR5 slot. Lets the user
|
||||||
|
|
@ -174,9 +174,9 @@ impl OpenCADStudio {
|
||||||
_ => h.user_real5 = val,
|
_ => h.user_real5 = val,
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
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 {
|
} 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) => {
|
(Some(n @ 1..=5), v, false) => {
|
||||||
|
|
@ -189,14 +189,14 @@ impl OpenCADStudio {
|
||||||
_ => h.user_int5 = val,
|
_ => h.user_int5 = val,
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
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 {
|
} 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
|
_ => self
|
||||||
.command_line
|
.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={}",
|
"https://github.com/HakanSeven12/OpenCADStudio/issues/new?body={}",
|
||||||
crate::sys::percent_encode(&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));
|
return Some(crate::sys::open_url(&url, self.main_window));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -226,7 +226,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
|
|
||||||
"CHANGELOG" => {
|
"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(
|
return Some(crate::sys::open_url(
|
||||||
"https://github.com/HakanSeven12/OpenCADStudio/releases",
|
"https://github.com/HakanSeven12/OpenCADStudio/releases",
|
||||||
self.main_window,
|
self.main_window,
|
||||||
|
|
@ -266,12 +266,12 @@ impl OpenCADStudio {
|
||||||
let text: String = keys.iter().map(|(k, v)| format!("{k} {v}\n")).collect();
|
let text: String = keys.iter().map(|(k, v)| format!("{k} {v}\n")).collect();
|
||||||
let count = self.shortcut_overrides.len();
|
let count = self.shortcut_overrides.len();
|
||||||
match std::fs::write(path, text) {
|
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}\"."
|
"CUIEXPORT: wrote {count} shortcut(s) to \"{path}\"."
|
||||||
)),
|
).as_ref()),
|
||||||
Err(e) => self
|
Err(e) => self
|
||||||
.command_line
|
.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;
|
n += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"CUIIMPORT: loaded {n} shortcut(s) from \"{path}\"."
|
"CUIIMPORT: loaded {n} shortcut(s) from \"{path}\"."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
Err(e) => self
|
Err(e) => self
|
||||||
.command_line
|
.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 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();
|
let cmd_str = parts.get(2).map(|s| s.to_uppercase()).unwrap_or_default();
|
||||||
if key.is_empty() || cmd_str.is_empty() {
|
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 {
|
} else {
|
||||||
self.shortcut_overrides.insert(key.clone(), cmd_str.clone());
|
self.shortcut_overrides.insert(key.clone(), cmd_str.clone());
|
||||||
self.command_line
|
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" => {
|
"CLEAR" | "DELETE" | "REMOVE" => {
|
||||||
let key = parts.get(1).map(|s| s.to_uppercase()).unwrap_or_default();
|
let key = parts.get(1).map(|s| s.to_uppercase()).unwrap_or_default();
|
||||||
if key.is_empty() {
|
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() {
|
} else if self.shortcut_overrides.remove(&key).is_some() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Shortcut '{key}' removed."));
|
.push_output(crate::tf!("Shortcut '{key}' removed.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("Shortcut '{key}' not found."));
|
.push_error(crate::tf!("Shortcut '{key}' not found.").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.command_line
|
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());
|
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.",
|
"COLORSCHEME: unknown theme '{}'. Type COLORSCHEME LIST for options.",
|
||||||
sub
|
sub
|
||||||
));
|
).as_ref());
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(t) = theme {
|
if let Some(t) = theme {
|
||||||
let name = format!("{:?}", t);
|
let name = format!("{:?}", t);
|
||||||
self.command_line
|
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::done(Message::SetTheme(t)));
|
||||||
}
|
}
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
|
|
@ -421,7 +421,7 @@ impl OpenCADStudio {
|
||||||
"MVIEW" => {
|
"MVIEW" => {
|
||||||
if self.tabs[i].scene.current_layout == "Model" {
|
if self.tabs[i].scene.current_layout == "Model" {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
use crate::modules::layout::mview::MviewCommand;
|
use crate::modules::layout::mview::MviewCommand;
|
||||||
let scene = &self.tabs[i].scene;
|
let scene = &self.tabs[i].scene;
|
||||||
|
|
@ -464,7 +464,7 @@ impl OpenCADStudio {
|
||||||
if sub.is_empty() {
|
if sub.is_empty() {
|
||||||
self.awaiting_vports = true;
|
self.awaiting_vports = true;
|
||||||
self.command_line
|
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());
|
return Some(self.focus_cmd_input());
|
||||||
}
|
}
|
||||||
// Model space: split the tiled viewport layout via pane_grid.
|
// 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.set_model_panes(config);
|
||||||
self.tabs[i].scene.camera_generation += 1;
|
self.tabs[i].scene.camera_generation += 1;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("VPORTS: {n} viewport(s)."));
|
.push_output(crate::tf!("VPORTS: {n} viewport(s).").as_ref());
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.command_line
|
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() {
|
} else if sub.is_empty() {
|
||||||
|
|
@ -532,23 +532,23 @@ impl OpenCADStudio {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
if viewports.is_empty() {
|
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 {
|
} else {
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"{} viewport(s) in layout \"{}\":",
|
"{} viewport(s) in layout \"{}\":",
|
||||||
viewports.len(),
|
viewports.len(),
|
||||||
scene.current_layout
|
scene.current_layout
|
||||||
));
|
).as_ref());
|
||||||
for (id, center, w, h, scale, is_on, locked) in &viewports {
|
for (id, center, w, h, scale, is_on, locked) in &viewports {
|
||||||
let state = match (is_on, locked) {
|
let state = match (is_on, locked) {
|
||||||
(true, true) => "On, Locked",
|
(true, true) => "On, Locked",
|
||||||
(true, false) => "On",
|
(true, false) => "On",
|
||||||
(false, _) => "Off",
|
(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}]",
|
" VP #{id}: {w:.1}×{h:.1} @ ({:.1},{:.1}) scale={scale:.4} [{state}]",
|
||||||
center.x, center.y
|
center.x, center.y
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -654,7 +654,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.auto_fit_viewport(handle);
|
self.tabs[i].scene.auto_fit_viewport(handle);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
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.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"VPORTS: created {} viewport(s) [{}].",
|
"VPORTS: created {} viewport(s) [{}].",
|
||||||
rects.len(),
|
rects.len(),
|
||||||
sub
|
sub
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -700,10 +700,10 @@ impl OpenCADStudio {
|
||||||
let scene = &self.tabs[i].scene;
|
let scene = &self.tabs[i].scene;
|
||||||
if scene.current_layout == "Model" {
|
if scene.current_layout == "Model" {
|
||||||
self.command_line
|
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() {
|
} else if scene.active_viewport.is_none() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
use crate::modules::layout::vplayer::VplayerCommand;
|
use crate::modules::layout::vplayer::VplayerCommand;
|
||||||
let vp_handle = scene.active_viewport.unwrap();
|
let vp_handle = scene.active_viewport.unwrap();
|
||||||
|
|
@ -729,12 +729,12 @@ impl OpenCADStudio {
|
||||||
};
|
};
|
||||||
if frozen_names.is_empty() {
|
if frozen_names.is_empty() {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
self.command_line.push_info(&format!(
|
self.command_line.push_info(crate::tf!(
|
||||||
"VPLAYER: frozen layers: {}",
|
"VPLAYER: frozen layers: {}",
|
||||||
frozen_names.join(", ")
|
frozen_names.join(", ")
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
let new_cmd = VplayerCommand::new(vp_handle);
|
let new_cmd = VplayerCommand::new(vp_handle);
|
||||||
self.command_line.push_info(&new_cmd.prompt());
|
self.command_line.push_info(&new_cmd.prompt());
|
||||||
|
|
@ -763,7 +763,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
self.tabs[i].scene.replace_selection(handles);
|
self.tabs[i].scene.replace_selection(handles);
|
||||||
|
|
@ -802,7 +802,7 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if selected.is_empty() {
|
if selected.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("DRAWORDER: select entities first.");
|
.push_error(crate::t!("DRAWORDER: select entities first.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
// Parse relative target handle for ABOVE/UNDER.
|
// Parse relative target handle for ABOVE/UNDER.
|
||||||
let relative_target: Option<(bool, acadrust::Handle)> = match option.as_str() {
|
let relative_target: Option<(bool, acadrust::Handle)> = match option.as_str() {
|
||||||
|
|
@ -940,12 +940,12 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let rel = if above { "above" } else { "below" };
|
let rel = if above { "above" } else { "below" };
|
||||||
self.command_line.push_info(&format!(
|
self.command_line.push_info(crate::tf!(
|
||||||
"DRAWORDER: moved {} entities {} {:x}.",
|
"DRAWORDER: moved {} entities {} {:x}.",
|
||||||
selected.len(),
|
selected.len(),
|
||||||
rel,
|
rel,
|
||||||
target.value()
|
target.value()
|
||||||
));
|
).as_ref());
|
||||||
} else if let Some(to_front) = to_front_opt {
|
} else if let Some(to_front) = to_front_opt {
|
||||||
let (min_eff, max_eff) = fb_baseline.unwrap_or((1, 0));
|
let (min_eff, max_eff) = fb_baseline.unwrap_or((1, 0));
|
||||||
for (k, h) in selected.iter().enumerate() {
|
for (k, h) in selected.iter().enumerate() {
|
||||||
|
|
@ -957,11 +957,11 @@ impl OpenCADStudio {
|
||||||
table.add_entry(*h, acadrust::Handle::new(sort));
|
table.add_entry(*h, acadrust::Handle::new(sort));
|
||||||
}
|
}
|
||||||
let dir = if to_front { "front" } else { "back" };
|
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 {}.",
|
"DRAWORDER: moved {} entities to {}.",
|
||||||
selected.len(),
|
selected.len(),
|
||||||
dir
|
dir
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Sort order lives in SortEntitiesTable, which the
|
// Sort order lives in SortEntitiesTable, which the
|
||||||
|
|
@ -974,7 +974,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_info(
|
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(),
|
Some(acadrust::EntityType::Viewport(vp)) => vp.clone(),
|
||||||
_ => {
|
_ => {
|
||||||
self.command_line
|
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());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1023,9 +1023,9 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
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."
|
"SYNCPVIEWPORTS: synced {n} viewport(s) to the master."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
// HIDE — hidden-line view of the active viewport.
|
// HIDE — hidden-line view of the active viewport.
|
||||||
|
|
@ -1088,9 +1088,9 @@ impl CadCommand for DrawOrderRefCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
if self.above {
|
if self.above {
|
||||||
"DRAWORDER Select reference object (move selection above):".into()
|
crate::t!("DRAWORDER Select reference object (move selection above):").into_owned()
|
||||||
} else {
|
} 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::tables::Ucs;
|
||||||
use acadrust::{CadDocument, EntityType, Handle};
|
use acadrust::{CadDocument, EntityType, Handle};
|
||||||
use iced;
|
use iced;
|
||||||
|
use crate::t;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
@ -496,7 +497,13 @@ impl DocumentTab {
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_string(),
|
.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.",
|
"Replaced 1 occurrence in {}; {remaining} matching object(s) remain.",
|
||||||
match_label(target)
|
match_label(target)
|
||||||
);
|
);
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"FIND/REPLACE: replaced 1 occurrence of \"{search}\"."
|
"FIND/REPLACE: replaced 1 occurrence of \"{search}\"."
|
||||||
));
|
).as_ref());
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,9 +188,9 @@ impl OpenCADStudio {
|
||||||
"Replaced {replaced} occurrence(s) in {} object(s).",
|
"Replaced {replaced} occurrence(s) in {} object(s).",
|
||||||
changed.len()
|
changed.len()
|
||||||
);
|
);
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"FIND/REPLACE: replaced {replaced} occurrence(s) of \"{search}\"."
|
"FIND/REPLACE: replaced {replaced} occurrence(s) of \"{search}\"."
|
||||||
));
|
).as_ref());
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -360,7 +360,7 @@ pub(super) fn next_group_auto_name(scene: &crate::scene::Scene) -> String {
|
||||||
// ── Entity type labels ─────────────────────────────────────────────────────
|
// ── Entity type labels ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
pub(super) fn entity_type_label(entity: &acadrust::EntityType) -> String {
|
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 {
|
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 available = self.tabs[i].history.undo_stack.len();
|
||||||
let steps = steps.min(available);
|
let steps = steps.min(available);
|
||||||
if steps == 0 {
|
if steps == 0 {
|
||||||
self.command_line.push_info("Nothing to undo.");
|
self.command_line.push_info(crate::t!("Nothing to undo.").as_ref());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1069,7 +1069,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.finish_history_apply(i, had_full, layer_panel_changed, &changes);
|
self.finish_history_apply(i, had_full, layer_panel_changed, &changes);
|
||||||
self.command_line
|
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) {
|
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 available = self.tabs[i].history.redo_stack.len();
|
||||||
let steps = steps.min(available);
|
let steps = steps.min(available);
|
||||||
if steps == 0 {
|
if steps == 0 {
|
||||||
self.command_line.push_info("Nothing to redo.");
|
self.command_line.push_info(crate::t!("Nothing to redo.").as_ref());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1124,7 +1124,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.finish_history_apply(i, had_full, layer_panel_changed, &changes);
|
self.finish_history_apply(i, had_full, layer_panel_changed, &changes);
|
||||||
self.command_line
|
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) {
|
for (id, res) in crate::plugin::external::load_at_startup(&mut app) {
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
app.command_line
|
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);
|
app.plugin_load_errors.insert(id, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ impl super::OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.len() != 2 {
|
if handles.len() != 2 {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let a = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
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 {
|
let Some(result) = solid_model::boolean(kind, &a, &b) else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ impl super::OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.len() != 1 {
|
if handles.len() != 1 {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||||
|
|
@ -105,7 +105,7 @@ impl super::OpenCADStudio {
|
||||||
}
|
}
|
||||||
if min[0] > max[0] {
|
if min[0] > max[0] {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// Generous margin so the box fully spans the solid in the free axes.
|
// 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] {
|
if hi[axis] <= lo[axis] {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let center = [
|
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 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 {
|
let Some(result) = solid_model::boolean(Bool::Intersect, &solid, &halfspace) else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
self.push_undo_snapshot(i, "SLICE");
|
self.push_undo_snapshot(i, "SLICE");
|
||||||
|
|
@ -149,10 +149,10 @@ impl super::OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
let ax = ["X", "Y", "Z"][axis];
|
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.",
|
"SLICE: cut at {ax}={value}, kept the {} half.",
|
||||||
if keep_low { "lower" } else { "upper" }
|
if keep_low { "lower" } else { "upper" }
|
||||||
));
|
).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,7 +169,7 @@ impl super::OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.len() != 2 {
|
if handles.len() != 2 {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let a = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
let a = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||||
|
|
@ -184,11 +184,11 @@ impl super::OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
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
|
None => self
|
||||||
.command_line
|
.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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -208,7 +208,7 @@ impl super::OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.len() != 1 {
|
if handles.len() != 1 {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||||
|
|
@ -225,7 +225,7 @@ impl super::OpenCADStudio {
|
||||||
}
|
}
|
||||||
if min[0] > max[0] {
|
if min[0] > max[0] {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let origin = Point3::new(
|
let origin = Point3::new(
|
||||||
|
|
@ -250,10 +250,10 @@ impl super::OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"3DROTATE: rotated {angle_deg}° about the {} axis.",
|
"3DROTATE: rotated {angle_deg}° about the {} axis.",
|
||||||
["X", "Y", "Z"][axis]
|
["X", "Y", "Z"][axis]
|
||||||
));
|
).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,7 +280,7 @@ impl super::OpenCADStudio {
|
||||||
});
|
});
|
||||||
let Some((handle, pts, closed)) = found else {
|
let Some((handle, pts, closed)) = found else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("POLYSOLID: select a polyline first.");
|
.push_error(crate::t!("POLYSOLID: select a polyline first.").as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let mut segs: Vec<([f64; 2], [f64; 2])> = pts.windows(2).map(|w| (w[0], w[1])).collect();
|
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 {
|
let Some(result) = acc else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
self.push_undo_snapshot(i, "POLYSOLID");
|
self.push_undo_snapshot(i, "POLYSOLID");
|
||||||
|
|
@ -322,9 +322,9 @@ impl super::OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
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})."
|
"POLYSOLID: built a wall solid from {used} segment(s) (width {width}, height {height})."
|
||||||
));
|
).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -344,7 +344,7 @@ impl super::OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.len() != 1 {
|
if handles.len() != 1 {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||||
|
|
@ -361,7 +361,7 @@ impl super::OpenCADStudio {
|
||||||
}
|
}
|
||||||
if min[0] > max[0] {
|
if min[0] > max[0] {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let c = TVec3::new(
|
let c = TVec3::new(
|
||||||
|
|
@ -390,10 +390,10 @@ impl super::OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"3DMIRROR: added a mirror across the {} plane.",
|
"3DMIRROR: added a mirror across the {} plane.",
|
||||||
["X", "Y", "Z"][axis]
|
["X", "Y", "Z"][axis]
|
||||||
));
|
).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -417,7 +417,7 @@ impl super::OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.len() != 1 {
|
if handles.len() != 1 {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// Build a right-handed frame (origin + orthonormal axes) from 3 points.
|
// 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 {
|
let (Some(s), Some(d)) = (frame(src), frame(dst)) else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let a = (d * s.inverse()).to_cols_array(); // column-major [f64; 16]
|
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.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -487,7 +487,7 @@ impl super::OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.len() != 1 {
|
if handles.len() != 1 {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||||
|
|
@ -504,7 +504,7 @@ impl super::OpenCADStudio {
|
||||||
}
|
}
|
||||||
if min[0] > max[0] {
|
if min[0] > max[0] {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// Margin so the cutting plane fully spans the solid in the free axes.
|
// Margin so the cutting plane fully spans the solid in the free axes.
|
||||||
|
|
@ -546,7 +546,7 @@ impl super::OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
let Ok(face) = builder::try_attach_plane(&[wire]) else {
|
let Ok(face) = builder::try_attach_plane(&[wire]) else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let shell: Shell = std::iter::once(face).collect();
|
let shell: Shell = std::iter::once(face).collect();
|
||||||
|
|
@ -556,7 +556,7 @@ impl super::OpenCADStudio {
|
||||||
let segs = solid_mesh.extract_interference(&plane_mesh);
|
let segs = solid_mesh.extract_interference(&plane_mesh);
|
||||||
if segs.is_empty() {
|
if segs.is_empty() {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "SECTION");
|
self.push_undo_snapshot(i, "SECTION");
|
||||||
|
|
@ -569,11 +569,11 @@ impl super::OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"SECTION: created {} section line(s) at {}={value}.",
|
"SECTION: created {} section line(s) at {}={value}.",
|
||||||
segs.len(),
|
segs.len(),
|
||||||
["X", "Y", "Z"][axis]
|
["X", "Y", "Z"][axis]
|
||||||
));
|
).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -581,7 +581,7 @@ impl super::OpenCADStudio {
|
||||||
#[cfg(not(feature = "solid3d"))]
|
#[cfg(not(feature = "solid3d"))]
|
||||||
pub(super) fn solid_section(&mut self, _axis: usize, _value: f64) -> Task<Message> {
|
pub(super) fn solid_section(&mut self, _axis: usize, _value: f64) -> Task<Message> {
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -604,7 +604,7 @@ impl super::OpenCADStudio {
|
||||||
let n = sides.max(3);
|
let n = sides.max(3);
|
||||||
if radius <= 0.0 || height <= 0.0 {
|
if radius <= 0.0 || height <= 0.0 {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let corners: Vec<Point3> = (0..n)
|
let corners: Vec<Point3> = (0..n)
|
||||||
|
|
@ -642,7 +642,7 @@ impl super::OpenCADStudio {
|
||||||
}
|
}
|
||||||
if faces.len() < n + 1 {
|
if faces.len() < n + 1 {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let shell = Shell::from(faces);
|
let shell = Shell::from(faces);
|
||||||
|
|
@ -655,12 +655,12 @@ impl super::OpenCADStudio {
|
||||||
} = truck_tess::tessellate_shell(&shell)
|
} = truck_tess::tessellate_shell(&shell)
|
||||||
else {
|
else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("PYRAMID: tessellation failed.");
|
.push_error(crate::t!("PYRAMID: tessellation failed.").as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
};
|
};
|
||||||
if verts.is_empty() {
|
if verts.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("PYRAMID: tessellation produced no geometry.");
|
.push_error(crate::t!("PYRAMID: tessellation produced no geometry.").as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "PYRAMID");
|
self.push_undo_snapshot(i, "PYRAMID");
|
||||||
|
|
@ -682,9 +682,9 @@ impl super::OpenCADStudio {
|
||||||
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
.insert(new_handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
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})."
|
"PYRAMID: created a {n}-sided pyramid (radius {radius}, height {height})."
|
||||||
));
|
).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -713,12 +713,12 @@ impl super::OpenCADStudio {
|
||||||
});
|
});
|
||||||
let Some((handle, fit)) = found else {
|
let Some((handle, fit)) = found else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
if fit.len() < 3 {
|
if fit.len() < 3 {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let n = fit.len();
|
let n = fit.len();
|
||||||
|
|
@ -756,7 +756,7 @@ impl super::OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -776,7 +776,7 @@ impl super::OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
self.push_undo_snapshot(i, "FLATSHOT");
|
self.push_undo_snapshot(i, "FLATSHOT");
|
||||||
|
|
@ -797,7 +797,7 @@ impl super::OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -816,7 +816,7 @@ impl super::OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
if handles.is_empty() {
|
if handles.is_empty() {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let mut surfaces: Vec<Surface> = Vec::new();
|
let mut surfaces: Vec<Surface> = Vec::new();
|
||||||
|
|
@ -848,7 +848,7 @@ impl super::OpenCADStudio {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -595,7 +595,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
impl ocs_plugin_api::host::InteractiveCommand for PlacePoint {
|
impl ocs_plugin_api::host::InteractiveCommand for PlacePoint {
|
||||||
fn prompt(&self) -> String {
|
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 {
|
fn on_point(&mut self, pt: [f64; 3]) -> ocs_plugin_api::host::CommandStep {
|
||||||
use ocs_plugin_api::host::CommandStep;
|
use ocs_plugin_api::host::CommandStep;
|
||||||
|
|
@ -632,7 +632,7 @@ mod tests {
|
||||||
struct PickThenMark;
|
struct PickThenMark;
|
||||||
impl ocs_plugin_api::host::InteractiveCommand for PickThenMark {
|
impl ocs_plugin_api::host::InteractiveCommand for PickThenMark {
|
||||||
fn prompt(&self) -> String {
|
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 {
|
fn on_point(&mut self, _pt: [f64; 3]) -> ocs_plugin_api::host::CommandStep {
|
||||||
ocs_plugin_api::host::CommandStep::Cancel
|
ocs_plugin_api::host::CommandStep::Cancel
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use crate::io::linetypes;
|
||||||
use crate::scene::view::dispatch;
|
use crate::scene::view::dispatch;
|
||||||
use crate::ui;
|
use crate::ui;
|
||||||
use acadrust::{EntityType, Handle};
|
use acadrust::{EntityType, Handle};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
/// Above this many selected objects the Properties panel skips per-entity
|
/// 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
|
/// property aggregation (which is O(n) per row, plus an O(n²) group filter) and
|
||||||
|
|
@ -259,30 +260,30 @@ impl OpenCADStudio {
|
||||||
};
|
};
|
||||||
let sections = vec![
|
let sections = vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "General".to_string(),
|
title: t!("General").into_owned(),
|
||||||
props: vec![
|
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 {
|
Property {
|
||||||
label: "Color".to_string(),
|
label: t!("Color").into_owned(),
|
||||||
field: "color",
|
field: "color",
|
||||||
value: PropValue::ColorChoice(header.current_entity_color),
|
value: PropValue::ColorChoice(header.current_entity_color),
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Layer".to_string(),
|
label: t!("Layer").into_owned(),
|
||||||
field: "layer",
|
field: "layer",
|
||||||
value: PropValue::LayerChoice(current_layer),
|
value: PropValue::LayerChoice(current_layer),
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Linetype".to_string(),
|
label: t!("Linetype").into_owned(),
|
||||||
field: "linetype",
|
field: "linetype",
|
||||||
value: PropValue::LinetypeChoice(current_linetype),
|
value: PropValue::LinetypeChoice(current_linetype),
|
||||||
},
|
},
|
||||||
read_only(
|
read_only(
|
||||||
"Linetype scale",
|
t!("Linetype scale").as_ref(),
|
||||||
format_length(header.current_entity_linetype_scale),
|
format_length(header.current_entity_linetype_scale),
|
||||||
),
|
),
|
||||||
Property {
|
Property {
|
||||||
label: "Lineweight".to_string(),
|
label: t!("Lineweight").into_owned(),
|
||||||
field: "line_weight",
|
field: "line_weight",
|
||||||
value: PropValue::LwChoice(
|
value: PropValue::LwChoice(
|
||||||
acadrust::types::LineWeight::from_value(
|
acadrust::types::LineWeight::from_value(
|
||||||
|
|
@ -290,21 +291,21 @@ impl OpenCADStudio {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
read_only("Transparency", "ByLayer".to_string()),
|
read_only(t!("Transparency").as_ref(), "ByLayer".to_string()),
|
||||||
read_only("Thickness", format_length(header.thickness)),
|
read_only(t!("Thickness").as_ref(), format_length(header.thickness)),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "3D Visualization".to_string(),
|
title: t!("3D Visualization").into_owned(),
|
||||||
props: vec![read_only("Material", material)],
|
props: vec![read_only(t!("Material").as_ref(), material)],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Plot style".to_string(),
|
title: t!("Plot style").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
read_only("Plot style", plot_style.to_string()),
|
read_only(t!("Plot style").as_ref(), plot_style.to_string()),
|
||||||
read_only("Plot style table", plot_table.clone()),
|
read_only(t!("Plot style table").as_ref(), plot_table.clone()),
|
||||||
read_only(
|
read_only(
|
||||||
"Plot table attached to",
|
t!("Plot table attached to").as_ref(),
|
||||||
if plot_table == "None" {
|
if plot_table == "None" {
|
||||||
"None".to_string()
|
"None".to_string()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -312,7 +313,7 @@ impl OpenCADStudio {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
read_only(
|
read_only(
|
||||||
"Plot table type",
|
t!("Plot table type").as_ref(),
|
||||||
if header.plotstyle_mode {
|
if header.plotstyle_mode {
|
||||||
"Named plot styles".to_string()
|
"Named plot styles".to_string()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -322,39 +323,39 @@ impl OpenCADStudio {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "View".to_string(),
|
title: t!("View").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
read_only("Center X", format_length(camera.target.x)),
|
read_only(t!("Center X").as_ref(), format_length(camera.target.x)),
|
||||||
read_only("Center Y", format_length(camera.target.y)),
|
read_only(t!("Center Y").as_ref(), format_length(camera.target.y)),
|
||||||
read_only("Center Z", format_length(camera.target.z)),
|
read_only(t!("Center Z").as_ref(), format_length(camera.target.z)),
|
||||||
read_only("Height", format_length(view_height)),
|
read_only(t!("Height").as_ref(), format_length(view_height)),
|
||||||
read_only("Width", format_length(view_width)),
|
read_only(t!("Width").as_ref(), format_length(view_width)),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".to_string(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
read_only("Annotation scale", annotation_scale),
|
read_only(t!("Annotation scale").as_ref(), annotation_scale),
|
||||||
read_only(
|
read_only(
|
||||||
"UCS icon On",
|
t!("UCS icon On").as_ref(),
|
||||||
if self.show_ucs_icon { "Yes" } else { "No" }.to_string(),
|
if self.show_ucs_icon { "Yes" } else { "No" }.to_string(),
|
||||||
),
|
),
|
||||||
read_only(
|
read_only(
|
||||||
"UCS icon at origin",
|
t!("UCS icon at origin").as_ref(),
|
||||||
if self.ucs_icon_at_origin { "Yes" } else { "No" }
|
if self.ucs_icon_at_origin { "Yes" } else { "No" }
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
read_only(
|
read_only(
|
||||||
"UCS per viewport",
|
t!("UCS per viewport").as_ref(),
|
||||||
if ucs_per_viewport { "Yes" } else { "No" }.to_string(),
|
if ucs_per_viewport { "Yes" } else { "No" }.to_string(),
|
||||||
),
|
),
|
||||||
read_only("UCS Name", ucs_name),
|
read_only(t!("UCS Name").as_ref(), ucs_name),
|
||||||
read_only("Visual Style", tab.visual_style.clone()),
|
read_only(t!("Visual Style").as_ref(), tab.visual_style.clone()),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
ui::PropertiesPanel {
|
ui::PropertiesPanel {
|
||||||
title: "No selection".to_string(),
|
title: t!("No selection").into_owned(),
|
||||||
sections,
|
sections,
|
||||||
layer_combo: iced::widget::combo_box::State::new(layer_names.clone()),
|
layer_combo: iced::widget::combo_box::State::new(layer_names.clone()),
|
||||||
linetype_combo: iced::widget::combo_box::State::new(
|
linetype_combo: iced::widget::combo_box::State::new(
|
||||||
|
|
@ -435,61 +436,61 @@ impl OpenCADStudio {
|
||||||
{
|
{
|
||||||
use crate::entities::common::ro_prop;
|
use crate::entities::common::ro_prop;
|
||||||
sections.push(crate::scene::model::object::PropSection {
|
sections.push(crate::scene::model::object::PropSection {
|
||||||
title: "Material Details".to_string(),
|
title: t!("Material Details").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop("Name", "mat_name", material.name.clone()),
|
ro_prop(t!("Name").as_ref(), "mat_name", material.name.clone()),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Description",
|
t!("Description").as_ref(),
|
||||||
"mat_description",
|
"mat_description",
|
||||||
material.description.clone(),
|
material.description.clone(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Ambient",
|
t!("Ambient").as_ref(),
|
||||||
"mat_ambient",
|
"mat_ambient",
|
||||||
material_color_text(&material.ambient_color),
|
material_color_text(&material.ambient_color),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Diffuse",
|
t!("Diffuse").as_ref(),
|
||||||
"mat_diffuse",
|
"mat_diffuse",
|
||||||
material_color_text(&material.diffuse_color),
|
material_color_text(&material.diffuse_color),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Specular",
|
t!("Specular").as_ref(),
|
||||||
"mat_specular",
|
"mat_specular",
|
||||||
material_color_text(&material.specular_color),
|
material_color_text(&material.specular_color),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Gloss",
|
t!("Gloss").as_ref(),
|
||||||
"mat_gloss",
|
"mat_gloss",
|
||||||
format!("{:.3}", material.specular_gloss_factor),
|
format!("{:.3}", material.specular_gloss_factor),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Opacity",
|
t!("Opacity").as_ref(),
|
||||||
"mat_opacity",
|
"mat_opacity",
|
||||||
format!("{:.3}", material.opacity_percent),
|
format!("{:.3}", material.opacity_percent),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Reflectivity",
|
t!("Reflectivity").as_ref(),
|
||||||
"mat_reflectivity",
|
"mat_reflectivity",
|
||||||
format!("{:.3}", material.reflectivity),
|
format!("{:.3}", material.reflectivity),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Translucence",
|
t!("Translucence").as_ref(),
|
||||||
"mat_translucence",
|
"mat_translucence",
|
||||||
format!("{:.3}", material.translucence),
|
format!("{:.3}", material.translucence),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Refraction",
|
t!("Refraction").as_ref(),
|
||||||
"mat_refraction",
|
"mat_refraction",
|
||||||
format!("{:.3}", material.refraction_index),
|
format!("{:.3}", material.refraction_index),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Self Illumination",
|
t!("Self Illumination").as_ref(),
|
||||||
"mat_self_illumination",
|
"mat_self_illumination",
|
||||||
format!("{:.3}", material.self_illumination),
|
format!("{:.3}", material.self_illumination),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Luminance",
|
t!("Luminance").as_ref(),
|
||||||
"mat_luminance",
|
"mat_luminance",
|
||||||
format!(
|
format!(
|
||||||
"{:.3} (mode {})",
|
"{:.3} (mode {})",
|
||||||
|
|
@ -497,42 +498,42 @@ impl OpenCADStudio {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Diffuse Map",
|
t!("Diffuse Map").as_ref(),
|
||||||
"mat_diffuse_map",
|
"mat_diffuse_map",
|
||||||
material_map_text(&material.diffuse_map),
|
material_map_text(&material.diffuse_map),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Specular Map",
|
t!("Specular Map").as_ref(),
|
||||||
"mat_specular_map",
|
"mat_specular_map",
|
||||||
material_map_text(&material.specular_map),
|
material_map_text(&material.specular_map),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Reflection Map",
|
t!("Reflection Map").as_ref(),
|
||||||
"mat_reflection_map",
|
"mat_reflection_map",
|
||||||
material_map_text(&material.reflection_map),
|
material_map_text(&material.reflection_map),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Opacity Map",
|
t!("Opacity Map").as_ref(),
|
||||||
"mat_opacity_map",
|
"mat_opacity_map",
|
||||||
material_map_text(&material.opacity_map),
|
material_map_text(&material.opacity_map),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Bump Map",
|
t!("Bump Map").as_ref(),
|
||||||
"mat_bump_map",
|
"mat_bump_map",
|
||||||
material_map_text(&material.bump_map),
|
material_map_text(&material.bump_map),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Refraction Map",
|
t!("Refraction Map").as_ref(),
|
||||||
"mat_refraction_map",
|
"mat_refraction_map",
|
||||||
material_map_text(&material.refraction_map),
|
material_map_text(&material.refraction_map),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Normal Map",
|
t!("Normal Map").as_ref(),
|
||||||
"mat_normal_map",
|
"mat_normal_map",
|
||||||
material_map_text(&material.normal_map),
|
material_map_text(&material.normal_map),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Render Flags",
|
t!("Render Flags").as_ref(),
|
||||||
"mat_render_flags",
|
"mat_render_flags",
|
||||||
format!(
|
format!(
|
||||||
"illumination {}; channels {}; mode {}; two-sided {}",
|
"illumination {}; channels {}; mode {}; two-sided {}",
|
||||||
|
|
@ -543,7 +544,7 @@ impl OpenCADStudio {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Advanced",
|
t!("Advanced").as_ref(),
|
||||||
"mat_advanced",
|
"mat_advanced",
|
||||||
format!(
|
format!(
|
||||||
"normal {:.3}; bump {:.3}; reflect {:.3}; transmit {:.3}",
|
"normal {:.3}; bump {:.3}; reflect {:.3}; transmit {:.3}",
|
||||||
|
|
@ -578,16 +579,16 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
use crate::entities::common::ro_prop;
|
use crate::entities::common::ro_prop;
|
||||||
sections.push(crate::scene::model::object::PropSection {
|
sections.push(crate::scene::model::object::PropSection {
|
||||||
title: "Color Book".to_string(),
|
title: t!("Color Book").into_owned(),
|
||||||
props: vec![
|
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(
|
ro_prop(
|
||||||
"Color Name",
|
t!("Color Name").as_ref(),
|
||||||
"book_color_name",
|
"book_color_name",
|
||||||
book.color_name.clone(),
|
book.color_name.clone(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Color",
|
t!("Color").as_ref(),
|
||||||
"book_color_value",
|
"book_color_value",
|
||||||
format!("{:?}", book.color),
|
format!("{:?}", book.color),
|
||||||
),
|
),
|
||||||
|
|
@ -616,25 +617,25 @@ impl OpenCADStudio {
|
||||||
};
|
};
|
||||||
use crate::entities::common::ro_prop;
|
use crate::entities::common::ro_prop;
|
||||||
sections.push(crate::scene::model::object::PropSection {
|
sections.push(crate::scene::model::object::PropSection {
|
||||||
title: format!("{scope} Visual Style"),
|
title: t!("%{scope} Visual Style", scope = scope).into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Handle",
|
t!("Handle").as_ref(),
|
||||||
"vs_handle",
|
"vs_handle",
|
||||||
format!("{:X}", handle.value()),
|
format!("{:X}", handle.value()),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Description",
|
t!("Description").as_ref(),
|
||||||
"vs_description",
|
"vs_description",
|
||||||
style.description.clone(),
|
style.description.clone(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Type",
|
t!("Type").as_ref(),
|
||||||
"vs_type",
|
"vs_type",
|
||||||
style.style_type.to_string(),
|
style.style_type.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Face",
|
t!("Face").as_ref(),
|
||||||
"vs_face",
|
"vs_face",
|
||||||
format!(
|
format!(
|
||||||
"lighting {}; quality {}; color {}; modifiers {}",
|
"lighting {}; quality {}; color {}; modifiers {}",
|
||||||
|
|
@ -645,7 +646,7 @@ impl OpenCADStudio {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Edges",
|
t!("Edges").as_ref(),
|
||||||
"vs_edges",
|
"vs_edges",
|
||||||
format!(
|
format!(
|
||||||
"model {}; style {}",
|
"model {}; style {}",
|
||||||
|
|
@ -653,17 +654,17 @@ impl OpenCADStudio {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Extended Lighting",
|
t!("Extended Lighting").as_ref(),
|
||||||
"vs_extended_lighting",
|
"vs_extended_lighting",
|
||||||
style.extended_lighting_model.to_string(),
|
style.extended_lighting_model.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Internal",
|
t!("Internal").as_ref(),
|
||||||
"vs_internal",
|
"vs_internal",
|
||||||
style.internal_use_only.to_string(),
|
style.internal_use_only.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Property Bag",
|
t!("Property Bag").as_ref(),
|
||||||
"vs_properties",
|
"vs_properties",
|
||||||
visual_style_properties_text(style),
|
visual_style_properties_text(style),
|
||||||
),
|
),
|
||||||
|
|
@ -692,22 +693,22 @@ impl OpenCADStudio {
|
||||||
let metrics = mesh.metrics;
|
let metrics = mesh.metrics;
|
||||||
let mut props = vec![
|
let mut props = vec![
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Vertices",
|
t!("Vertices").as_ref(),
|
||||||
"mesh_vertices",
|
"mesh_vertices",
|
||||||
metrics.vertices.to_string(),
|
metrics.vertices.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Triangles",
|
t!("Triangles").as_ref(),
|
||||||
"mesh_triangles",
|
"mesh_triangles",
|
||||||
metrics.triangles.to_string(),
|
metrics.triangles.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Surface Area",
|
t!("Surface Area").as_ref(),
|
||||||
"mesh_surface_area",
|
"mesh_surface_area",
|
||||||
format!("{:.6}", metrics.surface_area),
|
format!("{:.6}", metrics.surface_area),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Centroid",
|
t!("Centroid").as_ref(),
|
||||||
"mesh_centroid",
|
"mesh_centroid",
|
||||||
format!(
|
format!(
|
||||||
"{:.6}, {:.6}, {:.6}",
|
"{:.6}, {:.6}, {:.6}",
|
||||||
|
|
@ -717,7 +718,7 @@ impl OpenCADStudio {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Tessellation",
|
t!("Tessellation").as_ref(),
|
||||||
"mesh_complete",
|
"mesh_complete",
|
||||||
if mesh.complete { "Complete" } else { "Partial" },
|
if mesh.complete { "Complete" } else { "Partial" },
|
||||||
),
|
),
|
||||||
|
|
@ -733,14 +734,14 @@ impl OpenCADStudio {
|
||||||
props.insert(
|
props.insert(
|
||||||
3,
|
3,
|
||||||
ro_prop(
|
ro_prop(
|
||||||
"Volume",
|
t!("Volume").as_ref(),
|
||||||
"mesh_volume",
|
"mesh_volume",
|
||||||
format!("{:.6}", metrics.volume),
|
format!("{:.6}", metrics.volume),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
sections.push(crate::scene::model::object::PropSection {
|
sections.push(crate::scene::model::object::PropSection {
|
||||||
title: "Mass Properties".to_string(),
|
title: t!("Mass Properties").into_owned(),
|
||||||
props,
|
props,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -770,7 +771,7 @@ impl OpenCADStudio {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let toggle = crate::scene::model::object::Property {
|
let toggle = crate::scene::model::object::Property {
|
||||||
label: "Uniform scale".into(),
|
label: t!("Uniform scale").into_owned(),
|
||||||
field: "ins_uniform",
|
field: "ins_uniform",
|
||||||
value: crate::scene::model::object::PropValue::BoolToggle {
|
value: crate::scene::model::object::PropValue::BoolToggle {
|
||||||
field: "ins_uniform",
|
field: "ins_uniform",
|
||||||
|
|
@ -787,7 +788,7 @@ impl OpenCADStudio {
|
||||||
.position(|p| p.field == "x_scale")
|
.position(|p| p.field == "x_scale")
|
||||||
.unwrap_or(xi.min(section.props.len()));
|
.unwrap_or(xi.min(section.props.len()));
|
||||||
section.props[xi] = crate::entities::common::edit_prop(
|
section.props[xi] = crate::entities::common::edit_prop(
|
||||||
"Scale",
|
t!("Scale").as_ref(),
|
||||||
"u_scale",
|
"u_scale",
|
||||||
ins.x_scale(),
|
ins.x_scale(),
|
||||||
);
|
);
|
||||||
|
|
@ -975,7 +976,7 @@ impl OpenCADStudio {
|
||||||
|
|
||||||
if let Some(geom) = sections.last_mut() {
|
if let Some(geom) = sections.last_mut() {
|
||||||
geom.props.push(crate::scene::model::object::Property {
|
geom.props.push(crate::scene::model::object::Property {
|
||||||
label: "Frozen Layers".to_string(),
|
label: t!("Frozen Layers").into_owned(),
|
||||||
field: "frozen_layers",
|
field: "frozen_layers",
|
||||||
value: crate::scene::model::object::PropValue::EditText(
|
value: crate::scene::model::object::PropValue::EditText(
|
||||||
frozen_names.join(", "),
|
frozen_names.join(", "),
|
||||||
|
|
@ -983,7 +984,7 @@ impl OpenCADStudio {
|
||||||
});
|
});
|
||||||
if !ucs_names.is_empty() {
|
if !ucs_names.is_empty() {
|
||||||
geom.props.push(crate::scene::model::object::Property {
|
geom.props.push(crate::scene::model::object::Property {
|
||||||
label: "UCS Name".to_string(),
|
label: t!("UCS Name").into_owned(),
|
||||||
field: "vp_ucs_name",
|
field: "vp_ucs_name",
|
||||||
value: crate::scene::model::object::PropValue::Choice {
|
value: crate::scene::model::object::PropValue::Choice {
|
||||||
selected: current_ucs,
|
selected: current_ucs,
|
||||||
|
|
@ -993,7 +994,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if !view_names.is_empty() {
|
if !view_names.is_empty() {
|
||||||
geom.props.push(crate::scene::model::object::Property {
|
geom.props.push(crate::scene::model::object::Property {
|
||||||
label: "Named View".to_string(),
|
label: t!("Named View").into_owned(),
|
||||||
field: "vp_named_view",
|
field: "vp_named_view",
|
||||||
value: crate::scene::model::object::PropValue::Choice {
|
value: crate::scene::model::object::PropValue::Choice {
|
||||||
selected: String::new(),
|
selected: String::new(),
|
||||||
|
|
@ -1385,7 +1386,7 @@ impl OpenCADStudio {
|
||||||
&mut sections,
|
&mut sections,
|
||||||
anchor,
|
anchor,
|
||||||
crate::entities::common::ro_prop(
|
crate::entities::common::ro_prop(
|
||||||
"Annotative",
|
t!("Annotative").as_ref(),
|
||||||
"annotative",
|
"annotative",
|
||||||
"No",
|
"No",
|
||||||
),
|
),
|
||||||
|
|
@ -1430,7 +1431,7 @@ impl OpenCADStudio {
|
||||||
&mut sections,
|
&mut sections,
|
||||||
anno_field,
|
anno_field,
|
||||||
crate::entities::common::ro_prop(
|
crate::entities::common::ro_prop(
|
||||||
"Annotative scale",
|
t!("Annotative scale").as_ref(),
|
||||||
"annotative_scale",
|
"annotative_scale",
|
||||||
doc.header.current_annotation_scale.clone(),
|
doc.header.current_annotation_scale.clone(),
|
||||||
),
|
),
|
||||||
|
|
@ -1443,7 +1444,7 @@ impl OpenCADStudio {
|
||||||
let label = group_names.join(", ");
|
let label = group_names.join(", ");
|
||||||
if let Some(general) = sections.first_mut() {
|
if let Some(general) = sections.first_mut() {
|
||||||
general.props.push(crate::scene::model::object::Property {
|
general.props.push(crate::scene::model::object::Property {
|
||||||
label: "Group".to_string(),
|
label: t!("Group").into_owned(),
|
||||||
field: "group",
|
field: "group",
|
||||||
value: crate::scene::model::object::PropValue::ReadOnly(label),
|
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)
|
.map(|br| br.flags.is_xref || br.flags.is_xref_overlay)
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if is_xref {
|
if is_xref {
|
||||||
"External Reference".to_string()
|
t!("External Reference").into_owned()
|
||||||
} else {
|
} else {
|
||||||
entity_type_label(entity)
|
entity_type_label(entity)
|
||||||
}
|
}
|
||||||
|
|
@ -1474,7 +1475,13 @@ impl OpenCADStudio {
|
||||||
.filter_map(|prop| match &prop.value {
|
.filter_map(|prop| match &prop.value {
|
||||||
crate::scene::model::object::PropValue::Choice { options, .. } => Some((
|
crate::scene::model::object::PropValue::Choice { options, .. } => Some((
|
||||||
prop.field.to_string(),
|
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,
|
_ => None,
|
||||||
})
|
})
|
||||||
|
|
@ -1495,7 +1502,7 @@ impl OpenCADStudio {
|
||||||
// for seconds at tens of thousands of objects. Above the cap show a
|
// for seconds at tens of thousands of objects. Above the cap show a
|
||||||
// count-only panel; bulk edits still go through the ribbon.
|
// count-only panel; bulk edits still go through the ribbon.
|
||||||
n if n > MAX_PROP_AGGREGATE => ui::PropertiesPanel {
|
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()),
|
layer_combo: iced::widget::combo_box::State::new(layer_names.clone()),
|
||||||
linetype_combo: iced::widget::combo_box::State::new(linetype_items.clone()),
|
linetype_combo: iced::widget::combo_box::State::new(linetype_items.clone()),
|
||||||
lineweight_combo: iced::widget::combo_box::State::new(
|
lineweight_combo: iced::widget::combo_box::State::new(
|
||||||
|
|
@ -1529,13 +1536,19 @@ impl OpenCADStudio {
|
||||||
.filter_map(|prop| match &prop.value {
|
.filter_map(|prop| match &prop.value {
|
||||||
crate::scene::model::object::PropValue::Choice { options, .. } => Some((
|
crate::scene::model::object::PropValue::Choice { options, .. } => Some((
|
||||||
prop.field.to_string(),
|
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,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
sections,
|
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_group_combo: iced::widget::combo_box::State::new(groups.clone()),
|
||||||
selection_groups: groups,
|
selection_groups: groups,
|
||||||
selected_group: active_group,
|
selected_group: active_group,
|
||||||
|
|
@ -1998,7 +2011,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.command_line
|
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
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2037,7 +2050,7 @@ pub(super) fn build_selection_groups(
|
||||||
selected: &[(Handle, &EntityType)],
|
selected: &[(Handle, &EntityType)],
|
||||||
) -> Vec<ui::properties::SelectionGroup> {
|
) -> Vec<ui::properties::SelectionGroup> {
|
||||||
let mut groups = 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(),
|
handles: selected.iter().map(|(handle, _)| *handle).collect(),
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
|
@ -2052,7 +2065,7 @@ pub(super) fn build_selection_groups(
|
||||||
|
|
||||||
for (kind, handles) in by_type {
|
for (kind, handles) in by_type {
|
||||||
groups.push(ui::properties::SelectionGroup {
|
groups.push(ui::properties::SelectionGroup {
|
||||||
label: format!("{}({})", title_case_word(&kind), handles.len()),
|
label: format!("{}({})", t!(title_case_word(&kind)), handles.len()),
|
||||||
handles,
|
handles,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -593,7 +593,7 @@ impl OpenCADStudio {
|
||||||
self.load_style_bufs(kind);
|
self.load_style_bufs(kind);
|
||||||
self.after_style_change(kind);
|
self.after_style_change(kind);
|
||||||
self.command_line
|
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) {
|
pub(super) fn style_copy(&mut self, kind: StyleKind) {
|
||||||
|
|
@ -608,19 +608,19 @@ impl OpenCADStudio {
|
||||||
self.load_style_bufs(kind);
|
self.load_style_bufs(kind);
|
||||||
self.after_style_change(kind);
|
self.after_style_change(kind);
|
||||||
self.command_line
|
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) {
|
pub(super) fn style_delete(&mut self, kind: StyleKind) {
|
||||||
let name = self.style_selected(kind);
|
let name = self.style_selected(kind);
|
||||||
if name.eq_ignore_ascii_case("Standard") {
|
if name.eq_ignore_ascii_case("Standard") {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("Cannot delete the Standard style.");
|
.push_error(crate::t!("Cannot delete the Standard style.").as_ref());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if self.style_in_use(kind, &name) {
|
if self.style_in_use(kind, &name) {
|
||||||
self.command_line
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if !self.remove_style_storage(kind, &name) {
|
if !self.remove_style_storage(kind, &name) {
|
||||||
|
|
@ -635,7 +635,7 @@ impl OpenCADStudio {
|
||||||
self.load_style_bufs(kind);
|
self.load_style_bufs(kind);
|
||||||
self.after_style_change(kind);
|
self.after_style_change(kind);
|
||||||
self.command_line
|
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.
|
/// Begin inline rename of the double-clicked style.
|
||||||
|
|
@ -659,12 +659,12 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
if old.eq_ignore_ascii_case("Standard") {
|
if old.eq_ignore_ascii_case("Standard") {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("Cannot rename the Standard style.");
|
.push_error(crate::t!("Cannot rename the Standard style.").as_ref());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if self.style_exists(kind, &new) {
|
if self.style_exists(kind, &new) {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("Style '{new}' already exists."));
|
.push_error(crate::tf!("Style '{new}' already exists.").as_ref());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.rename_style_storage(kind, &old, &new);
|
self.rename_style_storage(kind, &old, &new);
|
||||||
|
|
@ -674,7 +674,7 @@ impl OpenCADStudio {
|
||||||
self.load_style_bufs(kind);
|
self.load_style_bufs(kind);
|
||||||
self.after_style_change(kind);
|
self.after_style_change(kind);
|
||||||
self.command_line
|
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) {
|
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());
|
let raw = crate::app::expr_eval::eval_to_string(self.command_line.input.trim());
|
||||||
self.command_line.input.clear();
|
self.command_line.input.clear();
|
||||||
let Ok(v) = raw.parse::<f64>() else {
|
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}\"",
|
"{}: expected a number, got \"{raw}\"",
|
||||||
pending.label
|
pending.label
|
||||||
));
|
).as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let i = self.active_tab;
|
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);
|
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}\""
|
"Expected coordinates (x,y) or a number, got: \"{text}\""
|
||||||
));
|
).as_ref());
|
||||||
return self.focus_cmd_input();
|
return self.focus_cmd_input();
|
||||||
}
|
}
|
||||||
if let Some(cmd) = self.command_line.submit() {
|
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.
|
// Esc cancels a pending system-variable value prompt.
|
||||||
if self.pending_setvar.take().is_some() {
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// UCS icon: Esc ends any grip drag and clears the selection
|
// 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_down = false;
|
||||||
sel.middle_last_pos = None;
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// Grip popup intercepts Escape — dismisses the menu
|
// 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);
|
names.retain(|n| n != "0" && *n != current);
|
||||||
if names.len() < before {
|
if names.len() < before {
|
||||||
self.command_line
|
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() {
|
if names.is_empty() {
|
||||||
return Task::none();
|
return Task::none();
|
||||||
|
|
@ -971,7 +971,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||||
action: item.action,
|
action: item.action,
|
||||||
label,
|
label,
|
||||||
});
|
});
|
||||||
self.command_line.push_info(&format!("{label}:"));
|
self.command_line.push_info(crate::tf!("{label}:").as_ref());
|
||||||
return self.focus_cmd_input();
|
return self.focus_cmd_input();
|
||||||
}
|
}
|
||||||
// Break at vertex replaces the entity with the split pieces —
|
// 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.tabs[i].dirty = true;
|
||||||
self.refresh_selected_grips();
|
self.refresh_selected_grips();
|
||||||
self.refresh_properties();
|
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
|
None => self
|
||||||
.command_line
|
.command_line
|
||||||
.push_error("Cannot break at this vertex."),
|
.push_error(crate::t!("Cannot break at this vertex.").as_ref()),
|
||||||
}
|
}
|
||||||
return Task::none();
|
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.tabs[i].dirty = dirty_before;
|
||||||
self.refresh_selected_grips();
|
self.refresh_selected_grips();
|
||||||
self.refresh_properties();
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
self.tabs[i]
|
self.tabs[i]
|
||||||
|
|
@ -1069,7 +1069,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||||
grip_world,
|
grip_world,
|
||||||
));
|
));
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info("Specify new vertex location:");
|
.push_info(crate::t!("Specify new vertex location:").as_ref());
|
||||||
} else {
|
} else {
|
||||||
if let Some(entity) =
|
if let Some(entity) =
|
||||||
self.tabs[i].scene.document.get_entity_mut(popup.handle)
|
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_selected_grips();
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("Cannot place the new vertex.");
|
.push_error(crate::t!("Cannot place the new vertex.").as_ref());
|
||||||
}
|
}
|
||||||
return Task::none();
|
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 —
|
// The block's layer may have been locked while the editor was open —
|
||||||
// refuse to write attributes to a locked-layer block.
|
// refuse to write attributes to a locked-layer block.
|
||||||
if let Some(layer) = self.tabs[i].scene.locked_layer_name(handle) {
|
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."
|
"Object is on locked layer \"{layer}\" — unlock the layer to edit its attributes."
|
||||||
));
|
).as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// Snapshot the working copy so the document can be mutated while the
|
// 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(_)) {
|
if self.tabs[self.active_tab].is_start && !matches!(event, ModuleEvent::Command(_)) {
|
||||||
self.ribbon.close_dropdown();
|
self.ribbon.close_dropdown();
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// Dismiss any open dropdown / collapsed-panel flyout on tool use,
|
// 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 => {
|
ModuleEvent::OpenFileDialog => {
|
||||||
self.command_line
|
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 => {
|
ModuleEvent::ClearModels => {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
self.tabs[i].scene.clear();
|
self.tabs[i].scene.clear();
|
||||||
self.tabs[i].properties = PropertiesPanel::empty();
|
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) => {
|
ModuleEvent::SetWireframe(w) => {
|
||||||
let i = self.active_tab;
|
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) {
|
if self.active_save_jobs.contains_key(&self.tabs[idx].id) {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -659,7 +659,10 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
.is_some_and(|(loaded, current)| loaded != current)
|
.is_some_and(|(loaded, current)| loaded != current)
|
||||||
{
|
{
|
||||||
self.command_line.push_error_once(
|
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 =
|
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) {
|
match crate::io::edit_lock::EditLease::acquire(path) {
|
||||||
Ok(lease) => {
|
Ok(lease) => {
|
||||||
if let Some(warning) = lease.platform_warning() {
|
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."
|
"Edit lease active; {warning}. External-change checks remain active."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
self.tabs[i].edit_lease = Some(lease);
|
self.tabs[i].edit_lease = Some(lease);
|
||||||
self.tabs[i].edit_lock_conflict = false;
|
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)) => {
|
Err(crate::io::edit_lock::EditLeaseError::Locked(error)) => {
|
||||||
self.tabs[i].edit_lease = None;
|
self.tabs[i].edit_lease = None;
|
||||||
self.tabs[i].edit_lock_conflict = true;
|
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}"
|
"Opened read-only against other editors: {error}"
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
Err(crate::io::edit_lock::EditLeaseError::Unavailable(error)) => {
|
Err(crate::io::edit_lock::EditLeaseError::Unavailable(error)) => {
|
||||||
self.tabs[i].edit_lease = None;
|
self.tabs[i].edit_lease = None;
|
||||||
self.tabs[i].edit_lock_conflict = false;
|
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."
|
"{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)) => {
|
Some(Ok(warning)) => {
|
||||||
self.tabs[i].edit_lock_conflict = false;
|
self.tabs[i].edit_lock_conflict = false;
|
||||||
if let Some(warning) = warning {
|
if let Some(warning) = warning {
|
||||||
self.command_line.push_info(&format!(
|
self.command_line.push_info(crate::tf!(
|
||||||
"{warning}. External-change checks remain active."
|
"{warning}. External-change checks remain active."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(Err(crate::io::edit_lock::EditLeaseError::Locked(error))) => {
|
Some(Err(crate::io::edit_lock::EditLeaseError::Locked(error))) => {
|
||||||
self.tabs[i].edit_lock_conflict = true;
|
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}"
|
"Saved, but the refreshed drawing is locked by another editor: {error}"
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
Some(Err(crate::io::edit_lock::EditLeaseError::Unavailable(error))) => {
|
Some(Err(crate::io::edit_lock::EditLeaseError::Unavailable(error))) => {
|
||||||
self.tabs[i].edit_lock_conflict = false;
|
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."
|
"{error}. External-change checks remain active."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
None => self.install_native_edit_guard(i, path, None),
|
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));
|
return Err(crate::io::SaveFailure::file_in_use(error));
|
||||||
}
|
}
|
||||||
Err(crate::io::edit_lock::EditLeaseError::Unavailable(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."
|
"{error}. External-change checks remain active."
|
||||||
));
|
).as_ref());
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -829,9 +832,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
let warning = lease.platform_warning().map(str::to_owned);
|
let warning = lease.platform_warning().map(str::to_owned);
|
||||||
self.tabs[i].edit_lock_conflict = false;
|
self.tabs[i].edit_lock_conflict = false;
|
||||||
if let Some(warning) = warning {
|
if let Some(warning) = warning {
|
||||||
self.command_line.push_info(&format!(
|
self.command_line.push_info(crate::tf!(
|
||||||
"{warning}. External-change checks remain active."
|
"{warning}. External-change checks remain active."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
@ -840,9 +843,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
}
|
}
|
||||||
Err(crate::io::edit_lock::EditLeaseError::Unavailable(error)) => {
|
Err(crate::io::edit_lock::EditLeaseError::Unavailable(error)) => {
|
||||||
self.tabs[i].edit_lock_conflict = false;
|
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."
|
"{error}. External-change checks remain active."
|
||||||
));
|
).as_ref());
|
||||||
return Ok(());
|
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_lease = Some(lease);
|
||||||
self.tabs[i].edit_lock_conflict = false;
|
self.tabs[i].edit_lock_conflict = false;
|
||||||
if let Some(warning) = warning {
|
if let Some(warning) = warning {
|
||||||
self.command_line.push_info(&format!(
|
self.command_line.push_info(crate::tf!(
|
||||||
"{warning}. External-change checks remain active."
|
"{warning}. External-change checks remain active."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(crate::io::edit_lock::EditLeaseError::Locked(error)) => Err(error),
|
Err(crate::io::edit_lock::EditLeaseError::Locked(error)) => Err(error),
|
||||||
Err(crate::io::edit_lock::EditLeaseError::Unavailable(error)) => {
|
Err(crate::io::edit_lock::EditLeaseError::Unavailable(error)) => {
|
||||||
self.tabs[i].edit_lock_conflict = false;
|
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."
|
"{error}. External-change checks remain active."
|
||||||
));
|
).as_ref());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -883,34 +886,34 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
let timings = caches.timings;
|
let timings = caches.timings;
|
||||||
let entity_count = doc.entities().count();
|
let entity_count = doc.entities().count();
|
||||||
self.command_line
|
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 {
|
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)",
|
"Warning: {} corrupt entities dropped (parser junk — bad normals / counts)",
|
||||||
caches.corrupt_dropped
|
caches.corrupt_dropped
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
if caches.xref_dropped > 0 {
|
if caches.xref_dropped > 0 {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"Warning: {} corrupt xref entities dropped",
|
"Warning: {} corrupt xref entities dropped",
|
||||||
caches.xref_dropped
|
caches.xref_dropped
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
for info in &caches.xrefs {
|
for info in &caches.xrefs {
|
||||||
match info.status {
|
match info.status {
|
||||||
crate::io::xref::XrefStatus::Loaded => {
|
crate::io::xref::XrefStatus::Loaded => {
|
||||||
self.command_line
|
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 => {
|
crate::io::xref::XrefStatus::NotFound => {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"XREF Not found: \"{}\" ({})",
|
"XREF Not found: \"{}\" ({})",
|
||||||
info.name, info.path
|
info.name, info.path
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
crate::io::xref::XrefStatus::Unloaded => {
|
crate::io::xref::XrefStatus::Unloaded => {
|
||||||
self.command_line
|
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
|
let total_ms = open_started
|
||||||
.map(|s| s.elapsed().as_millis() as u32)
|
.map(|s| s.elapsed().as_millis() as u32)
|
||||||
.unwrap_or(0);
|
.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",
|
" parse {}ms · purge {}ms · caches {}ms · xref {}ms · total {}ms",
|
||||||
timings.parse_ms, timings.purge_ms, timings.caches_ms, timings.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().
|
// Caches were built on the background thread inside open_path().
|
||||||
self.tabs[i].scene.local_extent_max = caches.local_extent_max;
|
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 self.active_save_jobs.contains_key(&tab_id) {
|
||||||
if purpose != crate::app::SavePurpose::Autosave {
|
if purpose != crate::app::SavePurpose::Autosave {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
|
|
@ -1218,12 +1221,12 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
&& self.tabs[i].edit_lock_conflict
|
&& self.tabs[i].edit_lock_conflict
|
||||||
{
|
{
|
||||||
let error = "Drawing edit lock is held by another editor.".to_string();
|
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}",
|
"Unable to save \"{}\": {error}",
|
||||||
path.file_name()
|
path.file_name()
|
||||||
.map(|name| name.to_string_lossy().into_owned())
|
.map(|name| name.to_string_lossy().into_owned())
|
||||||
.unwrap_or_else(|| path.display().to_string())
|
.unwrap_or_else(|| path.display().to_string())
|
||||||
));
|
).as_ref());
|
||||||
self.pending_save_failure = Some(crate::app::PendingSaveFailure {
|
self.pending_save_failure = Some(crate::app::PendingSaveFailure {
|
||||||
tab_id,
|
tab_id,
|
||||||
path,
|
path,
|
||||||
|
|
@ -1248,12 +1251,12 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
self.pending_save_leases.insert(tab_id, lease);
|
self.pending_save_leases.insert(tab_id, lease);
|
||||||
}
|
}
|
||||||
Err(crate::io::edit_lock::EditLeaseError::Locked(error)) => {
|
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}",
|
"Unable to save \"{}\": {error}",
|
||||||
path.file_name()
|
path.file_name()
|
||||||
.map(|name| name.to_string_lossy().into_owned())
|
.map(|name| name.to_string_lossy().into_owned())
|
||||||
.unwrap_or_else(|| path.display().to_string())
|
.unwrap_or_else(|| path.display().to_string())
|
||||||
));
|
).as_ref());
|
||||||
self.pending_save_failure = Some(crate::app::PendingSaveFailure {
|
self.pending_save_failure = Some(crate::app::PendingSaveFailure {
|
||||||
tab_id,
|
tab_id,
|
||||||
path,
|
path,
|
||||||
|
|
@ -1268,9 +1271,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
Err(crate::io::edit_lock::EditLeaseError::Unavailable(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."
|
"{error}. External-change checks remain active."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1424,9 +1427,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
.file_name()
|
.file_name()
|
||||||
.map(|name| name.to_string_lossy().into_owned())
|
.map(|name| name.to_string_lossy().into_owned())
|
||||||
.unwrap_or_else(|| outcome.path.display().to_string());
|
.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."
|
"Save stopped: \"{file_name}\" changed outside Open CAD Studio."
|
||||||
));
|
).as_ref());
|
||||||
self.pending_external_change = Some(crate::app::PendingExternalChange {
|
self.pending_external_change = Some(crate::app::PendingExternalChange {
|
||||||
tab_id: outcome.tab_id,
|
tab_id: outcome.tab_id,
|
||||||
path: outcome.path.clone(),
|
path: outcome.path.clone(),
|
||||||
|
|
@ -1445,9 +1448,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
.file_name()
|
.file_name()
|
||||||
.map(|name| name.to_string_lossy().into_owned())
|
.map(|name| name.to_string_lossy().into_owned())
|
||||||
.unwrap_or_else(|| outcome.path.display().to_string());
|
.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."
|
"Unable to save \"{file_name}\": file is in use by another application."
|
||||||
));
|
).as_ref());
|
||||||
self.pending_save_failure = Some(crate::app::PendingSaveFailure {
|
self.pending_save_failure = Some(crate::app::PendingSaveFailure {
|
||||||
tab_id: outcome.tab_id,
|
tab_id: outcome.tab_id,
|
||||||
path: outcome.path.clone(),
|
path: outcome.path.clone(),
|
||||||
|
|
@ -1470,7 +1473,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("Save failed: {error}"));
|
.push_error(crate::tf!("Save failed: {error}").as_ref());
|
||||||
return match outcome.continuation {
|
return match outcome.continuation {
|
||||||
crate::app::SaveContinuation::CloseTab => {
|
crate::app::SaveContinuation::CloseTab => {
|
||||||
self.pending_close = Some(crate::app::PendingClose::Tab(i));
|
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();
|
let mut tasks = Vec::new();
|
||||||
match outcome.purpose {
|
match outcome.purpose {
|
||||||
crate::app::SavePurpose::Autosave => {
|
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 => {
|
crate::app::SavePurpose::Manual | crate::app::SavePurpose::SaveAs => {
|
||||||
let path_changed = outcome.set_current_path
|
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)
|
!native_paths_match(current, &outcome.path)
|
||||||
});
|
});
|
||||||
self.command_line
|
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);
|
self.recent_thumbs.remove(&outcome.path);
|
||||||
if let Some(previous) = outcome.previous_autosave {
|
if let Some(previous) = outcome.previous_autosave {
|
||||||
if previous != outcome.path {
|
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.pending_save_failure = Some(failure);
|
||||||
self.restore_failed_save_continuation(continuation, i);
|
self.restore_failed_save_continuation(continuation, i);
|
||||||
self.command_line
|
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);
|
self.active_modal = Some(crate::app::ModalKind::FileInUse);
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
|
|
@ -1690,7 +1693,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
self.close_active_modal();
|
self.close_active_modal();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("Reload failed: {error}"));
|
.push_error(crate::tf!("Reload failed: {error}").as_ref());
|
||||||
return Task::none();
|
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> {
|
pub(super) fn on_save_file(&mut self) -> Task<Message> {
|
||||||
if self.read_only {
|
if self.read_only {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
|
|
@ -1859,11 +1862,11 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
},
|
},
|
||||||
Message::WebRecentStored,
|
Message::WebRecentStored,
|
||||||
);
|
);
|
||||||
self.command_line.push_output(&format!("Saved: {filename}"));
|
self.command_line.push_output(crate::tf!("Saved: {filename}").as_ref());
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.command_line.push_error(&format!("Save failed: {e}"));
|
self.command_line.push_error(crate::tf!("Save failed: {e}").as_ref());
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -2163,10 +2166,10 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
|
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.tabs[i].scene.bump_geometry_no_blocks();
|
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} \
|
"Page setup: {w:.1}×{h:.1} mm area={plot_area} \
|
||||||
center={center} rot={rotation}°"
|
center={center} rot={rotation}°"
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2178,7 +2181,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
self.direct_plot_params()
|
self.direct_plot_params()
|
||||||
else {
|
else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let plot_style = self.dialog_plot_style(&self.plot_dialog);
|
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
|
job
|
||||||
else {
|
else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let plot_style = self.dialog_plot_style(&self.plot_dialog);
|
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()
|
self.direct_plot_params()
|
||||||
else {
|
else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let plot_style = self.dialog_plot_style(&self.plot_dialog);
|
let plot_style = self.dialog_plot_style(&self.plot_dialog);
|
||||||
let options = self.plot_print_options(&self.plot_dialog, group_splits);
|
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(
|
background_task(
|
||||||
move || {
|
move || {
|
||||||
iced::futures::executor::block_on(
|
iced::futures::executor::block_on(
|
||||||
|
|
@ -2561,7 +2564,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
if self.tabs[i].scene.current_layout != "Model" {
|
if self.tabs[i].scene.current_layout != "Model" {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let set: std::collections::HashSet<acadrust::Handle> = handles.into_iter().collect();
|
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 {
|
if !any {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("Selection has no printable geometry.");
|
.push_error(crate::t!("Selection has no printable geometry.").as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
if !(x1 > x0 && y1 > y0) {
|
if !(x1 > x0 && y1 > y0) {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("Selection has no printable area.");
|
.push_error(crate::t!("Selection has no printable area.").as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// Small margin so the outermost strokes aren't clipped flush to the edge.
|
// 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(
|
match crate::io::print_to_printer::open_printer_properties(
|
||||||
self.plot_dialog.printer.as_deref(),
|
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),
|
Err(error) => self.command_line.push_error(&error),
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
|
|
@ -2924,7 +2927,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
}
|
}
|
||||||
M::SetCurrent => {
|
M::SetCurrent => {
|
||||||
self.apply_dialog_to_layout();
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
M::NewSetup => {
|
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> {
|
fn on_plot_dlg_commit(&mut self, preview: bool) -> Task<Message> {
|
||||||
let d = self.plot_dialog.clone();
|
let d = self.plot_dialog.clone();
|
||||||
if d.style_missing {
|
if d.style_missing {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"Plot style table '{}' is not loaded.",
|
"Plot style table '{}' is not loaded.",
|
||||||
d.style_name
|
d.style_name
|
||||||
));
|
).as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// Remember the user's print preferences across sessions.
|
// Remember the user's print preferences across sessions.
|
||||||
|
|
@ -3365,7 +3368,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||||
)) = job
|
)) = job
|
||||||
else {
|
else {
|
||||||
self.command_line
|
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);
|
self.active_modal = Some(crate::app::ModalKind::Plot);
|
||||||
return Task::none();
|
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);
|
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 || {
|
let work = move || {
|
||||||
iced::futures::executor::block_on(
|
iced::futures::executor::block_on(
|
||||||
crate::io::print_to_printer::print_wires_with(
|
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);
|
entry.screening = sc.min(100);
|
||||||
}
|
}
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Plot style ACI {aci} updated."));
|
.push_output(crate::tf!("Plot style ACI {aci} updated.").as_ref());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No table loaded: create an identity table and apply.
|
// 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.active_plot_style = Some(table);
|
||||||
self.command_line
|
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()
|
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> {
|
pub(super) fn on_plot_style_panel_save(&mut self) -> Task<Message> {
|
||||||
if self.active_plot_style.is_none() {
|
if self.active_plot_style.is_none() {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let default_name = self
|
let default_name = self
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@ impl OpenCADStudio {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
crate::scene::text::web_font::insert(script, None);
|
crate::scene::text::web_font::insert(script, None);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("Font load failed ({script:?}): {e}"));
|
.push_error(crate::tf!("Font load failed ({script:?}): {e}").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
|
|
@ -323,10 +323,10 @@ impl OpenCADStudio {
|
||||||
return match std::fs::metadata(&path) {
|
return match std::fs::metadata(&path) {
|
||||||
Ok(m) => self.update(Message::OpenPathPicked(Some((path, m.len())))),
|
Ok(m) => self.update(Message::OpenPathPicked(Some((path, m.len())))),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
self.command_line.push_error(&format!(
|
self.command_line.push_error(crate::tf!(
|
||||||
"Recent file no longer exists: {}",
|
"Recent file no longer exists: {}",
|
||||||
path.display()
|
path.display()
|
||||||
));
|
).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -489,7 +489,7 @@ impl OpenCADStudio {
|
||||||
.map(|(_, _, l)| *l)
|
.map(|(_, _, l)| *l)
|
||||||
.unwrap_or("Snap");
|
.unwrap_or("Snap");
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -507,10 +507,10 @@ impl OpenCADStudio {
|
||||||
.map(|e| e.to_string_lossy().to_lowercase())
|
.map(|e| e.to_string_lossy().to_lowercase())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
if !matches!(ext.as_str(), "dwg" | "dxf" | "bak" | "sv$") {
|
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: {}",
|
"Unsupported file type: {}",
|
||||||
path.display()
|
path.display()
|
||||||
));
|
).as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// Already open → switch to its tab; a load in progress →
|
// Already open → switch to its tab; a load in progress →
|
||||||
|
|
@ -563,7 +563,7 @@ impl OpenCADStudio {
|
||||||
});
|
});
|
||||||
let size_label = format_size(size_bytes);
|
let size_label = format_size(size_bytes);
|
||||||
self.command_line
|
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([
|
let model_bg = self.default_bg_color.unwrap_or([
|
||||||
33.0 / 255.0,
|
33.0 / 255.0,
|
||||||
40.0 / 255.0,
|
40.0 / 255.0,
|
||||||
|
|
@ -579,7 +579,7 @@ impl OpenCADStudio {
|
||||||
Message::OpenCancel => {
|
Message::OpenCancel => {
|
||||||
if let Some(p) = self.opening.take() {
|
if let Some(p) = self.opening.take() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info(&format!("Open cancelled: \"{}\"", p.name));
|
.push_info(crate::tf!("Open cancelled: \"{}\"", p.name).as_ref());
|
||||||
}
|
}
|
||||||
self.drain_pending_open()
|
self.drain_pending_open()
|
||||||
}
|
}
|
||||||
|
|
@ -593,7 +593,7 @@ impl OpenCADStudio {
|
||||||
// we suppress the noise.
|
// we suppress the noise.
|
||||||
let was_open = self.opening.take().is_some();
|
let was_open = self.opening.take().is_some();
|
||||||
if was_open && e != "Cancelled" {
|
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
|
// A drawing that fails to parse must not strand the ones queued
|
||||||
// behind it.
|
// behind it.
|
||||||
|
|
@ -604,9 +604,9 @@ impl OpenCADStudio {
|
||||||
Message::WebRecentStored(result) => match result {
|
Message::WebRecentStored(result) => match result {
|
||||||
Ok(path) => self.push_recent(path),
|
Ok(path) => self.push_recent(path),
|
||||||
Err(error) => {
|
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}"
|
"Saved download, but recent copy could not be stored: {error}"
|
||||||
));
|
).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -625,7 +625,7 @@ impl OpenCADStudio {
|
||||||
.unwrap_or(&path_str)
|
.unwrap_or(&path_str)
|
||||||
.to_string();
|
.to_string();
|
||||||
self.command_line
|
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 cmd = ImageCommand::new(path_str, pw, ph);
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
self.command_line.push_info(&cmd.prompt());
|
self.command_line.push_info(&cmd.prompt());
|
||||||
|
|
@ -635,7 +635,7 @@ impl OpenCADStudio {
|
||||||
|
|
||||||
Message::ImagePickResult(Err(e)) => {
|
Message::ImagePickResult(Err(e)) => {
|
||||||
if e != "Cancelled" {
|
if e != "Cancelled" {
|
||||||
self.command_line.push_error(&format!("IMAGE: {e}"));
|
self.command_line.push_error(crate::tf!("IMAGE: {e}").as_ref());
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -671,7 +671,7 @@ impl OpenCADStudio {
|
||||||
|
|
||||||
Message::XAttachPickResult(Err(e)) => {
|
Message::XAttachPickResult(Err(e)) => {
|
||||||
if e != "Cancelled" {
|
if e != "Cancelled" {
|
||||||
self.command_line.push_error(&format!("XATTACH: {e}"));
|
self.command_line.push_error(crate::tf!("XATTACH: {e}").as_ref());
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -701,13 +701,13 @@ impl OpenCADStudio {
|
||||||
|
|
||||||
Message::WblockWriteFinished(block_name, path, result) => {
|
Message::WblockWriteFinished(block_name, path, result) => {
|
||||||
match result {
|
match result {
|
||||||
Ok(()) => self.command_line.push_output(&format!(
|
Ok(()) => self.command_line.push_output(crate::tf!(
|
||||||
"WBLOCK Saved \"{block_name}\" → \"{}\"",
|
"WBLOCK Saved \"{block_name}\" → \"{}\"",
|
||||||
path.display()
|
path.display()
|
||||||
)),
|
).as_ref()),
|
||||||
Err(error) => self
|
Err(error) => self
|
||||||
.command_line
|
.command_line
|
||||||
.push_error(&format!("WBLOCK save failed: {error}")),
|
.push_error(crate::tf!("WBLOCK save failed: {error}").as_ref()),
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -739,11 +739,11 @@ impl OpenCADStudio {
|
||||||
.map(|n| n.to_string_lossy().into_owned())
|
.map(|n| n.to_string_lossy().into_owned())
|
||||||
.unwrap_or_else(|| path.to_string_lossy().into_owned());
|
.unwrap_or_else(|| path.to_string_lossy().into_owned());
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("DATAEXTRACTION {rows} rows → \"{fname}\""));
|
.push_output(crate::tf!("DATAEXTRACTION {rows} rows → \"{fname}\"").as_ref());
|
||||||
}
|
}
|
||||||
Err(e) => self
|
Err(e) => self
|
||||||
.command_line
|
.command_line
|
||||||
.push_error(&format!("DATAEXTRACTION: write failed: {e}")),
|
.push_error(crate::tf!("DATAEXTRACTION: write failed: {e}").as_ref()),
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -754,7 +754,7 @@ impl OpenCADStudio {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
if self.tabs[i].scene.meshes.is_empty() {
|
if self.tabs[i].scene.meshes.is_empty() {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
Task::perform(
|
Task::perform(
|
||||||
|
|
@ -780,8 +780,8 @@ impl OpenCADStudio {
|
||||||
match result {
|
match result {
|
||||||
Ok(()) => self
|
Ok(()) => self
|
||||||
.command_line
|
.command_line
|
||||||
.push_output(&format!("STLOUT: exported to \"{}\"", path.display())),
|
.push_output(crate::tf!("STLOUT: exported to \"{}\"", path.display()).as_ref()),
|
||||||
Err(error) => self.command_line.push_error(&format!("STLOUT: {error}")),
|
Err(error) => self.command_line.push_error(crate::tf!("STLOUT: {error}").as_ref()),
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -791,7 +791,7 @@ impl OpenCADStudio {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
if self.tabs[i].scene.meshes.is_empty() {
|
if self.tabs[i].scene.meshes.is_empty() {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
Task::perform(
|
Task::perform(
|
||||||
|
|
@ -817,8 +817,8 @@ impl OpenCADStudio {
|
||||||
match result {
|
match result {
|
||||||
Ok(()) => self
|
Ok(()) => self
|
||||||
.command_line
|
.command_line
|
||||||
.push_output(&format!("STEPOUT: exported to \"{}\"", path.display())),
|
.push_output(crate::tf!("STEPOUT: exported to \"{}\"", path.display()).as_ref()),
|
||||||
Err(error) => self.command_line.push_error(&format!("STEPOUT: {error}")),
|
Err(error) => self.command_line.push_error(crate::tf!("STEPOUT: {error}").as_ref()),
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -843,11 +843,11 @@ impl OpenCADStudio {
|
||||||
|
|
||||||
Message::ObjImportFinished(tab_id, path, result) => {
|
Message::ObjImportFinished(tab_id, path, result) => {
|
||||||
match 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) => {
|
Ok(mut mesh) => {
|
||||||
let Some(i) = self.tabs.iter().position(|tab| tab.id == tab_id) else {
|
let Some(i) = self.tabs.iter().position(|tab| tab.id == tab_id) else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info("IMPORTOBJ: target drawing was closed.");
|
.push_info(crate::t!("IMPORTOBJ: target drawing was closed.").as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let file_stem = path
|
let file_stem = path
|
||||||
|
|
@ -864,9 +864,9 @@ impl OpenCADStudio {
|
||||||
.meshes
|
.meshes
|
||||||
.insert(handle, crate::scene::MeshLodSet::from_single(mesh));
|
.insert(handle, crate::scene::MeshLodSet::from_single(mesh));
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"IMPORTOBJ: imported \"{file_stem}\" as mesh."
|
"IMPORTOBJ: imported \"{file_stem}\" as mesh."
|
||||||
));
|
).as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -878,7 +878,7 @@ impl OpenCADStudio {
|
||||||
Message::SaveAs => {
|
Message::SaveAs => {
|
||||||
if self.read_only {
|
if self.read_only {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
|
|
@ -924,7 +924,7 @@ impl OpenCADStudio {
|
||||||
.layers
|
.layers
|
||||||
.sync_with_viewports(&doc_layers, vp_info);
|
.sync_with_viewports(&doc_layers, vp_info);
|
||||||
self.command_line
|
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].current_path = None;
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.sync_ribbon_layers();
|
self.sync_ribbon_layers();
|
||||||
|
|
@ -988,7 +988,7 @@ impl OpenCADStudio {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
if !crate::plugin::try_dispatch(self, i, &line) {
|
if !crate::plugin::try_dispatch(self, i, &line) {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(&format!("No plugin handled: {command}"));
|
.push_error(crate::tf!("No plugin handled: {command}").as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
|
|
@ -1138,7 +1138,7 @@ impl OpenCADStudio {
|
||||||
let Some(path) = self.tabs.get(idx).and_then(|tab| tab.current_path.clone())
|
let Some(path) = self.tabs.get(idx).and_then(|tab| tab.current_path.clone())
|
||||||
else {
|
else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let full_path = path.canonicalize().unwrap_or_else(|_| {
|
let full_path = path.canonicalize().unwrap_or_else(|_| {
|
||||||
|
|
@ -1151,7 +1151,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.command_line
|
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())
|
return iced::clipboard::write(full_path.to_string_lossy().into_owned())
|
||||||
.discard();
|
.discard();
|
||||||
}
|
}
|
||||||
|
|
@ -1159,7 +1159,7 @@ impl OpenCADStudio {
|
||||||
{
|
{
|
||||||
let _ = idx;
|
let _ = idx;
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1170,16 +1170,16 @@ impl OpenCADStudio {
|
||||||
let Some(path) = self.tabs.get(idx).and_then(|tab| tab.current_path.clone())
|
let Some(path) = self.tabs.get(idx).and_then(|tab| tab.current_path.clone())
|
||||||
else {
|
else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
match crate::sys::reveal_in_file_manager(&path) {
|
match crate::sys::reveal_in_file_manager(&path) {
|
||||||
Ok(()) => self
|
Ok(()) => self
|
||||||
.command_line
|
.command_line
|
||||||
.push_output(&format!("Opened file location: {}", path.display())),
|
.push_output(crate::tf!("Opened file location: {}", path.display()).as_ref()),
|
||||||
Err(error) => self
|
Err(error) => self
|
||||||
.command_line
|
.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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -1187,7 +1187,7 @@ impl OpenCADStudio {
|
||||||
{
|
{
|
||||||
let _ = idx;
|
let _ = idx;
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1442,7 +1442,7 @@ impl OpenCADStudio {
|
||||||
self.ribbon.close_dropdown();
|
self.ribbon.close_dropdown();
|
||||||
if self.tabs[i].is_start {
|
if self.tabs[i].is_start {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let mut names: Vec<String> = self.tabs[i]
|
let mut names: Vec<String> = self.tabs[i]
|
||||||
|
|
@ -1482,7 +1482,7 @@ impl OpenCADStudio {
|
||||||
let name = self.layer_state_name_buf.trim().to_string();
|
let name = self.layer_state_name_buf.trim().to_string();
|
||||||
if name.is_empty() {
|
if name.is_empty() {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let old_name = self.layer_state_selected.clone();
|
let old_name = self.layer_state_selected.clone();
|
||||||
|
|
@ -1499,7 +1499,7 @@ impl OpenCADStudio {
|
||||||
});
|
});
|
||||||
if duplicate {
|
if duplicate {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1520,7 +1520,7 @@ impl OpenCADStudio {
|
||||||
self.layer_state_selected = Some(name.clone());
|
self.layer_state_selected = Some(name.clone());
|
||||||
self.layer_state_name_buf = name.clone();
|
self.layer_state_name_buf = name.clone();
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::LayerStateManagerRestore => {
|
Message::LayerStateManagerRestore => {
|
||||||
|
|
@ -1553,9 +1553,9 @@ impl OpenCADStudio {
|
||||||
.invalidate_layer_dependencies(&layer_names);
|
.invalidate_layer_dependencies(&layer_names);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_layer_panel();
|
self.refresh_layer_panel();
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"LAYERSTATE: restored \"{name}\" ({restored} layer(s))."
|
"LAYERSTATE: restored \"{name}\" ({restored} layer(s))."
|
||||||
));
|
).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::LayerStateManagerDelete => {
|
Message::LayerStateManagerDelete => {
|
||||||
|
|
@ -1576,7 +1576,7 @@ impl OpenCADStudio {
|
||||||
names.sort_by_key(|name| name.to_lowercase());
|
names.sort_by_key(|name| name.to_lowercase());
|
||||||
self.load_layer_state_editor(names.into_iter().next());
|
self.load_layer_state_editor(names.into_iter().next());
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("LAYERSTATE: deleted \"{name}\"."));
|
.push_output(crate::tf!("LAYERSTATE: deleted \"{name}\".").as_ref());
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -1587,7 +1587,7 @@ impl OpenCADStudio {
|
||||||
};
|
};
|
||||||
let Some(state) = self.tabs[i].scene.document.layer_state(&name) else {
|
let Some(state) = self.tabs[i].scene.document.layer_state(&name) else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
self.layer_state_edit_draft = Some(state);
|
self.layer_state_edit_draft = Some(state);
|
||||||
|
|
@ -1730,7 +1730,7 @@ impl OpenCADStudio {
|
||||||
let name = draft.name.trim().to_string();
|
let name = draft.name.trim().to_string();
|
||||||
if name.is_empty() {
|
if name.is_empty() {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let old_name = self.layer_state_selected.clone();
|
let old_name = self.layer_state_selected.clone();
|
||||||
|
|
@ -1747,7 +1747,7 @@ impl OpenCADStudio {
|
||||||
});
|
});
|
||||||
if duplicate {
|
if duplicate {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let Some(state) = self.layer_state_edit_draft.take() else {
|
let Some(state) = self.layer_state_edit_draft.take() else {
|
||||||
|
|
@ -1775,7 +1775,7 @@ impl OpenCADStudio {
|
||||||
self.layer_state_edit_color_open = None;
|
self.layer_state_edit_color_open = None;
|
||||||
self.active_modal = Some(super::ModalKind::LayerStateManager);
|
self.active_modal = Some(super::ModalKind::LayerStateManager);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("LAYERSTATE: updated \"{name}\"."));
|
.push_output(crate::tf!("LAYERSTATE: updated \"{name}\".").as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::LayerStateEditorCancel => {
|
Message::LayerStateEditorCancel => {
|
||||||
|
|
@ -1829,11 +1829,11 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.invalidate_layer_dependencies(&targets);
|
self.tabs[i].scene.invalidate_layer_dependencies(&targets);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.commit_layer_undo(i, undo);
|
self.commit_layer_undo(i, undo);
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"{} layer(s) turned {}",
|
"{} layer(s) turned {}",
|
||||||
targets.len(),
|
targets.len(),
|
||||||
if on { "on" } else { "off" }
|
if on { "on" } else { "off" }
|
||||||
));
|
).as_ref());
|
||||||
self.sync_ribbon_layers();
|
self.sync_ribbon_layers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1869,11 +1869,11 @@ impl OpenCADStudio {
|
||||||
// Lock state affects editability, not rendered geometry.
|
// Lock state affects editability, not rendered geometry.
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.commit_layer_undo(i, undo);
|
self.commit_layer_undo(i, undo);
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"{} layer(s) {}",
|
"{} layer(s) {}",
|
||||||
targets.len(),
|
targets.len(),
|
||||||
if locked { "locked" } else { "unlocked" }
|
if locked { "locked" } else { "unlocked" }
|
||||||
));
|
).as_ref());
|
||||||
self.sync_ribbon_layers();
|
self.sync_ribbon_layers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1904,11 +1904,11 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.invalidate_layer_dependencies(&targets);
|
self.tabs[i].scene.invalidate_layer_dependencies(&targets);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.commit_layer_undo(i, undo);
|
self.commit_layer_undo(i, undo);
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"{} layer(s) {}",
|
"{} layer(s) {}",
|
||||||
targets.len(),
|
targets.len(),
|
||||||
if frozen { "frozen" } else { "thawed" }
|
if frozen { "frozen" } else { "thawed" }
|
||||||
));
|
).as_ref());
|
||||||
self.sync_ribbon_layers();
|
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.borrow_mut().home_view(r_ucs);
|
||||||
}
|
}
|
||||||
self.tabs[i].scene.camera_generation += 1;
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2351,11 +2351,11 @@ impl OpenCADStudio {
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
if name.is_empty() || name == "WCS" {
|
if name.is_empty() || name == "WCS" {
|
||||||
self.tabs[i].active_ucs = None;
|
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;
|
changed = true;
|
||||||
} else if let Some(named) = self.tabs[i].scene.document.ucss.get(&name).cloned() {
|
} else if let Some(named) = self.tabs[i].scene.document.ucss.get(&name).cloned() {
|
||||||
self.tabs[i].active_ucs = Some(named);
|
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;
|
changed = true;
|
||||||
}
|
}
|
||||||
if changed {
|
if changed {
|
||||||
|
|
@ -2511,7 +2511,7 @@ impl OpenCADStudio {
|
||||||
_ => "live",
|
_ => "live",
|
||||||
};
|
};
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("COORDS = {mode} ({label})"));
|
.push_output(crate::tf!("COORDS = {mode} ({label})").as_ref());
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -2700,11 +2700,11 @@ impl OpenCADStudio {
|
||||||
self.active_modal = Some(crate::app::ModalKind::AnnoObjectScale);
|
self.active_modal = Some(crate::app::ModalKind::AnnoObjectScale);
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -3341,7 +3341,7 @@ impl OpenCADStudio {
|
||||||
let to_move: Vec<_> = self.tabs[i].scene.selected.iter().cloned().collect();
|
let to_move: Vec<_> = self.tabs[i].scene.selected.iter().cloned().collect();
|
||||||
if to_move.is_empty() {
|
if to_move.is_empty() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("DRAWORDER: select entities first.");
|
.push_error(crate::t!("DRAWORDER: select entities first.").as_ref());
|
||||||
} else {
|
} else {
|
||||||
use crate::command::CadCommand;
|
use crate::command::CadCommand;
|
||||||
let cmd = super::commands::DrawOrderRefCommand::new(to_move, above);
|
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;
|
self.tabs[i].scene.selection.borrow_mut().context_menu = None;
|
||||||
let added = self.tabs[i].scene.select_similar();
|
let added = self.tabs[i].scene.select_similar();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Select Similar: {} added.", added));
|
.push_output(crate::tf!("Select Similar: {} added.", added).as_ref());
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -3366,7 +3366,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.selection.borrow_mut().context_menu = None;
|
self.tabs[i].scene.selection.borrow_mut().context_menu = None;
|
||||||
let count = self.tabs[i].scene.invert_selection();
|
let count = self.tabs[i].scene.invert_selection();
|
||||||
self.command_line
|
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();
|
self.refresh_properties();
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -3441,7 +3441,7 @@ impl OpenCADStudio {
|
||||||
state.append,
|
state.append,
|
||||||
);
|
);
|
||||||
self.command_line
|
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();
|
self.refresh_properties();
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -4023,7 +4023,7 @@ impl OpenCADStudio {
|
||||||
if self.tabs[i].scene.delete_layout(&name) {
|
if self.tabs[i].scene.delete_layout(&name) {
|
||||||
self.layout_rename_state = None;
|
self.layout_rename_state = None;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Layout \"{name}\" silindi"));
|
.push_output(crate::tf!("Layout \"{name}\" silindi").as_ref());
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
}
|
}
|
||||||
Task::batch([cancel_task, switch_task])
|
Task::batch([cancel_task, switch_task])
|
||||||
|
|
@ -4061,7 +4061,7 @@ impl OpenCADStudio {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
if self.tabs[i].is_start {
|
if self.tabs[i].is_start {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let current = self.tabs[i].scene.current_layout.clone();
|
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();
|
let new_name = self.layout_manager_rename_buf.trim().to_string();
|
||||||
if old_name == "Model" {
|
if old_name == "Model" {
|
||||||
self.command_line
|
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() {
|
} 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 {
|
} else if new_name == old_name {
|
||||||
// no-op
|
// no-op
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -4111,7 +4111,7 @@ impl OpenCADStudio {
|
||||||
self.layout_manager_selected = new_name.clone();
|
self.layout_manager_selected = new_name.clone();
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -4119,7 +4119,7 @@ impl OpenCADStudio {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
if self.tabs[i].is_start {
|
if self.tabs[i].is_start {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let existing = self.tabs[i].scene.layout_names();
|
let existing = self.tabs[i].scene.layout_names();
|
||||||
|
|
@ -4134,9 +4134,9 @@ impl OpenCADStudio {
|
||||||
self.layout_manager_selected = name.clone();
|
self.layout_manager_selected = name.clone();
|
||||||
self.layout_manager_rename_buf = name.clone();
|
self.layout_manager_rename_buf = name.clone();
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -4145,7 +4145,7 @@ impl OpenCADStudio {
|
||||||
let name = self.layout_manager_selected.clone();
|
let name = self.layout_manager_selected.clone();
|
||||||
if name == "Model" {
|
if name == "Model" {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error("Cannot delete the Model layout.");
|
.push_error(crate::t!("Cannot delete the Model layout.").as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
} else {
|
} else {
|
||||||
let deleting_current = self.tabs[i].scene.current_layout == name;
|
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_selected = "Model".to_string();
|
||||||
self.layout_manager_rename_buf = String::new();
|
self.layout_manager_rename_buf = String::new();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Layout '{name}' deleted."));
|
.push_output(crate::tf!("Layout '{name}' deleted.").as_ref());
|
||||||
Task::batch([cancel_task, switch_task])
|
Task::batch([cancel_task, switch_task])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4209,7 +4209,7 @@ impl OpenCADStudio {
|
||||||
let task = self.on_layout_switch(name.clone());
|
let task = self.on_layout_switch(name.clone());
|
||||||
if self.tabs[self.active_tab].scene.current_layout == name {
|
if self.tabs[self.active_tab].scene.current_layout == name {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Switched to layout '{name}'."));
|
.push_output(crate::tf!("Switched to layout '{name}'.").as_ref());
|
||||||
}
|
}
|
||||||
task
|
task
|
||||||
}
|
}
|
||||||
|
|
@ -4273,10 +4273,10 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
Message::AliasEditorApply => {
|
Message::AliasEditorApply => {
|
||||||
self.apply_alias_editor_rows();
|
self.apply_alias_editor_rows();
|
||||||
self.command_line.push_info(&format!(
|
self.command_line.push_info(crate::tf!(
|
||||||
"{} alias(es) applied.",
|
"{} alias(es) applied.",
|
||||||
self.command_aliases.len()
|
self.command_aliases.len()
|
||||||
));
|
).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4334,7 +4334,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
Err(error) => self
|
Err(error) => self
|
||||||
.command_line
|
.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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -4959,7 +4959,7 @@ impl OpenCADStudio {
|
||||||
let phase = Instant::now();
|
let phase = Instant::now();
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
let properties_ms = phase.elapsed().as_secs_f64() * 1000.0;
|
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 {
|
if perf {
|
||||||
crate::perf_record!(
|
crate::perf_record!(
|
||||||
"[perf] viewport-enter total={:.2}ms normalize={:.2}ms display={:.2}ms ucs={:.2}ms properties={:.2}ms handle={}",
|
"[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.
|
// Paper space has no UCS — drop the viewport's UCS.
|
||||||
self.tabs[i].refresh_active_ucs();
|
self.tabs[i].refresh_active_ucs();
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
self.command_line.push_output("PSPACE");
|
self.command_line.push_output(crate::t!("PSPACE").as_ref());
|
||||||
if context_changed {
|
if context_changed {
|
||||||
self.sync_dyn_fields();
|
self.sync_dyn_fields();
|
||||||
}
|
}
|
||||||
|
|
@ -5007,7 +5007,7 @@ impl OpenCADStudio {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
if self.tabs[i].scene.current_layout == "Model" {
|
if self.tabs[i].scene.current_layout == "Model" {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
if self.tabs[i].scene.active_viewport.is_some() {
|
if self.tabs[i].scene.active_viewport.is_some() {
|
||||||
|
|
@ -5018,7 +5018,7 @@ impl OpenCADStudio {
|
||||||
Some(handle) => Task::done(Message::EnterViewport(handle)),
|
Some(handle) => Task::done(Message::EnterViewport(handle)),
|
||||||
None => {
|
None => {
|
||||||
self.command_line
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5163,7 +5163,7 @@ impl OpenCADStudio {
|
||||||
Ok(msg) => self.command_line.push_info(&msg),
|
Ok(msg) => self.command_line.push_info(&msg),
|
||||||
Err(err) => self
|
Err(err) => self
|
||||||
.command_line
|
.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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -5252,11 +5252,11 @@ impl OpenCADStudio {
|
||||||
Message::PrintToPrinter => self.on_print_to_printer(),
|
Message::PrintToPrinter => self.on_print_to_printer(),
|
||||||
Message::PrintResult(Ok(printer)) => {
|
Message::PrintResult(Ok(printer)) => {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info(&format!("Sent to printer: {printer}"));
|
.push_info(crate::tf!("Sent to printer: {printer}").as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::PrintResult(Err(e)) => {
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5273,7 +5273,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.plot_dialog.style_name = table.name.clone();
|
self.plot_dialog.style_name = table.name.clone();
|
||||||
self.plot_dialog.style_missing = false;
|
self.plot_dialog.style_missing = false;
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"Plot style '{}' loaded ({} color entries).",
|
"Plot style '{}' loaded ({} color entries).",
|
||||||
table.name,
|
table.name,
|
||||||
table
|
table
|
||||||
|
|
@ -5281,7 +5281,7 @@ impl OpenCADStudio {
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|e| e.color.is_some())
|
.filter(|e| e.color.is_some())
|
||||||
.count()
|
.count()
|
||||||
));
|
).as_ref());
|
||||||
self.active_plot_style = Some(table);
|
self.active_plot_style = Some(table);
|
||||||
self.plot_dialog.plot_styles = crate::io::plot_style::available_ctb_names();
|
self.plot_dialog.plot_styles = crate::io::plot_style::available_ctb_names();
|
||||||
Task::none()
|
Task::none()
|
||||||
|
|
@ -5291,7 +5291,7 @@ impl OpenCADStudio {
|
||||||
self.active_plot_style = None;
|
self.active_plot_style = None;
|
||||||
self.plot_dialog.style_name.clear();
|
self.plot_dialog.style_name.clear();
|
||||||
self.plot_dialog.style_missing = false;
|
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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5383,12 +5383,12 @@ impl OpenCADStudio {
|
||||||
self.plot_dialog.style_missing = false;
|
self.plot_dialog.style_missing = false;
|
||||||
self.plot_dialog.plot_styles =
|
self.plot_dialog.plot_styles =
|
||||||
crate::io::plot_style::available_ctb_names();
|
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 \"{}\".",
|
"Plot style table saved to \"{}\".",
|
||||||
path.display()
|
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()
|
Task::none()
|
||||||
|
|
@ -5416,7 +5416,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.document.header.current_text_style_name = name.clone();
|
self.tabs[i].scene.document.header.current_text_style_name = name.clone();
|
||||||
self.sync_ribbon_styles();
|
self.sync_ribbon_styles();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Current text style: {}", name));
|
.push_output(crate::tf!("Current text style: {}", name).as_ref());
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -5716,7 +5716,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.document.header.current_table_style_name = name.clone();
|
self.tabs[i].scene.document.header.current_table_style_name = name.clone();
|
||||||
self.ribbon.active_table_style = name.clone();
|
self.ribbon.active_table_style = name.clone();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Current table style: {name}"));
|
.push_output(crate::tf!("Current table style: {name}").as_ref());
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -5745,7 +5745,7 @@ impl OpenCADStudio {
|
||||||
// Staged: persists on Apply.
|
// Staged: persists on Apply.
|
||||||
self.tabs[i].scene.document.header.multiline_style = name.clone();
|
self.tabs[i].scene.document.header.multiline_style = name.clone();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Current multiline style: {}", name));
|
.push_output(crate::tf!("Current multiline style: {}", name).as_ref());
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -5878,10 +5878,10 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].scene.document.header.current_dimstyle_name =
|
self.tabs[i].scene.document.header.current_dimstyle_name =
|
||||||
self.dimstyle_selected.clone();
|
self.dimstyle_selected.clone();
|
||||||
self.sync_ribbon_styles();
|
self.sync_ribbon_styles();
|
||||||
self.command_line.push_output(&format!(
|
self.command_line.push_output(crate::tf!(
|
||||||
"Current dim style set to '{}'.",
|
"Current dim style set to '{}'.",
|
||||||
self.dimstyle_selected
|
self.dimstyle_selected
|
||||||
));
|
).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::DimStyleDialogDelete => {
|
Message::DimStyleDialogDelete => {
|
||||||
|
|
|
||||||
|
|
@ -368,7 +368,7 @@ impl OpenCADStudio {
|
||||||
ds.dimalt = self.ds_dimalt;
|
ds.dimalt = self.ds_dimalt;
|
||||||
ds.dimapost = self.ds_dimapost.clone();
|
ds.dimapost = self.ds_dimapost.clone();
|
||||||
self.command_line
|
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.
|
/// 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.tabs[i].active_mleader_style = name.clone();
|
||||||
self.ribbon.active_mleader_style = name.clone();
|
self.ribbon.active_mleader_style = name.clone();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Current multileader style: {}", name));
|
.push_output(crate::tf!("Current multileader style: {}", name).as_ref());
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -515,7 +515,7 @@ impl OpenCADStudio {
|
||||||
if self.tabs[i].scene.set_active_viewport_render_mode(mode) {
|
if self.tabs[i].scene.set_active_viewport_render_mode(mode) {
|
||||||
self.tabs[i].scene.bump_geometry_no_blocks();
|
self.tabs[i].scene.bump_geometry_no_blocks();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Viewport visual style: {label}"));
|
.push_output(crate::tf!("Viewport visual style: {label}").as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
self.tabs[i].render_mode = mode;
|
self.tabs[i].render_mode = mode;
|
||||||
|
|
@ -533,7 +533,7 @@ impl OpenCADStudio {
|
||||||
// pipeline keys its upload cache off `geometry_epoch`.
|
// pipeline keys its upload cache off `geometry_epoch`.
|
||||||
self.tabs[i].scene.bump_geometry_no_blocks();
|
self.tabs[i].scene.bump_geometry_no_blocks();
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Visual style: {label}"));
|
.push_output(crate::tf!("Visual style: {label}").as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2616,7 +2616,7 @@ impl OpenCADStudio {
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.map(|c| c.on_structure_pick(pick.handle, center));
|
.map(|c| c.on_structure_pick(pick.handle, center));
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info(&format!("{} acquired.", pick.label));
|
.push_info(crate::tf!("{} acquired.", pick.label).as_ref());
|
||||||
result
|
result
|
||||||
} else {
|
} else {
|
||||||
let msg = self.tabs[i]
|
let msg = self.tabs[i]
|
||||||
|
|
@ -2745,7 +2745,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].active_cmd = Some(cmd);
|
self.tabs[i].active_cmd = Some(cmd);
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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;
|
self.tabs[i].active_cmd = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2772,7 +2772,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
} else {
|
} 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
|
None
|
||||||
}
|
}
|
||||||
} else if self.tabs[i]
|
} else if self.tabs[i]
|
||||||
|
|
@ -2787,7 +2787,7 @@ impl OpenCADStudio {
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.map(|c| c.on_tangent_point(obj, pick_wcs))
|
.map(|c| c.on_tangent_point(obj, pick_wcs))
|
||||||
} else {
|
} else {
|
||||||
self.command_line.push_info("Select a tangent object.");
|
self.command_line.push_info(crate::t!("Select a tangent object.").as_ref());
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
} else if !self.command_point_allowed(i, world_pt) {
|
} else if !self.command_point_allowed(i, world_pt) {
|
||||||
|
|
@ -3250,9 +3250,9 @@ impl OpenCADStudio {
|
||||||
// `selection_just_completed`, or a
|
// `selection_just_completed`, or a
|
||||||
// gather command (MOVE's "select
|
// gather command (MOVE's "select
|
||||||
// objects") would wrongly finish.
|
// 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."
|
"Object is on locked layer \"{layer}\" — unlock the layer to select or edit it."
|
||||||
));
|
).as_ref());
|
||||||
} else {
|
} else {
|
||||||
// Individual picks accumulate (issue #47):
|
// Individual picks accumulate (issue #47):
|
||||||
// each plain click adds to the selection,
|
// each plain click adds to the selection,
|
||||||
|
|
@ -3513,9 +3513,9 @@ impl OpenCADStudio {
|
||||||
// Locked layer: double-click must not open any editor
|
// Locked layer: double-click must not open any editor
|
||||||
// (text / attribute / in-place block edit).
|
// (text / attribute / in-place block edit).
|
||||||
if let Some(layer) = self.tabs[i].scene.locked_layer_name(handle) {
|
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."
|
"Object is on locked layer \"{layer}\" — unlock the layer to edit it."
|
||||||
));
|
).as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// Any text-bearing entity opens its in-place editor
|
// Any text-bearing entity opens its in-place editor
|
||||||
|
|
@ -3693,7 +3693,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i]
|
self.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.record_nav_perf(crate::scene::NavPerfOp::Zoom, now);
|
.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()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -3891,7 +3891,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].scene.camera_generation += 1;
|
self.tabs[i].scene.camera_generation += 1;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("View: {}", region.label()));
|
.push_output(crate::tf!("View: {}", region.label()).as_ref());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4094,7 +4094,7 @@ impl OpenCADStudio {
|
||||||
.position(|session| session.block_name == name)
|
.position(|session| session.block_name == name)
|
||||||
else {
|
else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
};
|
};
|
||||||
if self.tabs[i].active_block_edit == Some(target_index) {
|
if self.tabs[i].active_block_edit == Some(target_index) {
|
||||||
|
|
@ -4156,7 +4156,7 @@ impl OpenCADStudio {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
if self.tabs[i].is_start {
|
if self.tabs[i].is_start {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let perf = crate::perf::enabled();
|
let perf = crate::perf::enabled();
|
||||||
|
|
@ -4270,7 +4270,7 @@ impl OpenCADStudio {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
if self.tabs[i].is_start {
|
if self.tabs[i].is_start {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
}
|
}
|
||||||
let cancel_task = self.cancel_active_command_for_space_change();
|
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);
|
self.tabs[i].scene.ensure_sheet_viewport(&new_name);
|
||||||
let switch_task = self.on_layout_switch(new_name.clone());
|
let switch_task = self.on_layout_switch(new_name.clone());
|
||||||
self.tabs[i].scene.fit_all();
|
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"
|
"Layout \"{new_name}\" created — use MVIEW to add a viewport"
|
||||||
));
|
).as_ref());
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
return Task::batch([cancel_task, switch_task]);
|
return Task::batch([cancel_task, switch_task]);
|
||||||
}
|
}
|
||||||
Err(e) => self
|
Err(e) => self
|
||||||
.command_line
|
.command_line
|
||||||
.push_error(&format!("Failed to create layout: {e}")),
|
.push_error(crate::tf!("Failed to create layout: {e}").as_ref()),
|
||||||
}
|
}
|
||||||
cancel_task
|
cancel_task
|
||||||
}
|
}
|
||||||
|
|
@ -4342,7 +4342,7 @@ impl OpenCADStudio {
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
self.push_undo_snapshot(i, "BLOCK RENAME");
|
self.push_undo_snapshot(i, "BLOCK RENAME");
|
||||||
if self.tabs[i].scene.rename_block(&orig, &new_name) {
|
if self.tabs[i].scene.rename_block(&orig, &new_name) {
|
||||||
|
|
@ -4358,10 +4358,10 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Block \"{orig}\" → \"{new_name}\""));
|
.push_output(crate::tf!("Block \"{orig}\" → \"{new_name}\"").as_ref());
|
||||||
} else {
|
} else {
|
||||||
self.command_line
|
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();
|
return Task::none();
|
||||||
|
|
@ -4373,7 +4373,7 @@ impl OpenCADStudio {
|
||||||
.any(|n| *n == new_name);
|
.any(|n| *n == new_name);
|
||||||
if exists {
|
if exists {
|
||||||
self.command_line
|
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 {
|
} else {
|
||||||
self.push_undo_snapshot(i, "LAYOUT RENAME");
|
self.push_undo_snapshot(i, "LAYOUT RENAME");
|
||||||
self.tabs[i].scene.rename_layout(&orig, &new_name);
|
self.tabs[i].scene.rename_layout(&orig, &new_name);
|
||||||
|
|
@ -4382,7 +4382,7 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.command_line
|
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::window;
|
||||||
use iced::{keyboard, Background, Border, Color, Element, Fill, Subscription, Task, Theme};
|
use iced::{keyboard, Background, Border, Color, Element, Fill, Subscription, Task, Theme};
|
||||||
use iced_aw::ContextMenu;
|
use iced_aw::ContextMenu;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
mod controls;
|
mod controls;
|
||||||
mod modal;
|
mod modal;
|
||||||
|
|
@ -1210,7 +1211,7 @@ impl OpenCADStudio {
|
||||||
let copy_btn = button(
|
let copy_btn = button(
|
||||||
row![
|
row![
|
||||||
crate::ui::icons::themed_primary(crate::ui::icons::COPY, 11.0),
|
crate::ui::icons::themed_primary(crate::ui::icons::COPY, 11.0),
|
||||||
text("Copy").size(11),
|
text(t!("Copy")).size(11),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
|
|
@ -1221,7 +1222,7 @@ impl OpenCADStudio {
|
||||||
let clear_btn = button(
|
let clear_btn = button(
|
||||||
row![
|
row![
|
||||||
crate::ui::icons::themed_danger(crate::ui::icons::TRASH, 11.0),
|
crate::ui::icons::themed_danger(crate::ui::icons::TRASH, 11.0),
|
||||||
text("Clear").size(11),
|
text(t!("Clear")).size(11),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
|
|
@ -1230,7 +1231,7 @@ impl OpenCADStudio {
|
||||||
.style(perf_button_style)
|
.style(perf_button_style)
|
||||||
.padding([2, 6]);
|
.padding([2, 6]);
|
||||||
let header = row![
|
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),
|
color: Some(theme.palette().success.base.color),
|
||||||
}),
|
}),
|
||||||
Space::new().width(iced::Length::Fill),
|
Space::new().width(iced::Length::Fill),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
use super::super::{Message, OpenCADStudio};
|
use super::super::{Message, OpenCADStudio};
|
||||||
|
use crate::t;
|
||||||
use iced::widget::{button, column, container, row, text, Space};
|
use iced::widget::{button, column, container, row, text, Space};
|
||||||
use iced::{Background, Element, Fill, Fit, Theme};
|
use iced::{Background, Element, Fill, Fit, Theme};
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
impl OpenCADStudio {
|
impl OpenCADStudio {
|
||||||
/// Title shown in the active modal's title bar. Keep in sync with the
|
/// Title shown in the active modal's title bar. Keep in sync with the
|
||||||
|
|
@ -221,7 +223,7 @@ impl OpenCADStudio {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
automatic_flow(ex, |flow| {
|
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)
|
.padding(16)
|
||||||
.width(flow.width)
|
.width(flow.width)
|
||||||
.height(flow.height)
|
.height(flow.height)
|
||||||
|
|
@ -941,12 +943,12 @@ fn automatic_flow<'a>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dialog_button(
|
fn dialog_button<'a>(
|
||||||
label: &'static str,
|
label: impl Into<Cow<'a, str>>,
|
||||||
message: Message,
|
message: Message,
|
||||||
style: fn(&Theme, button::Status) -> button::Style,
|
style: fn(&Theme, button::Status) -> button::Style,
|
||||||
) -> Element<'static, Message> {
|
) -> Element<'a, Message> {
|
||||||
button(text(label).size(13))
|
button(text(label.into()).size(13))
|
||||||
.on_press(message)
|
.on_press(message)
|
||||||
.style(style)
|
.style(style)
|
||||||
.padding([6, 18])
|
.padding([6, 18])
|
||||||
|
|
@ -980,7 +982,7 @@ fn save_as_dialog_window<'a>(
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.find(|&s| s == format);
|
.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) {
|
let field_width = if matches!(sizing.width, iced::Length::Fill) {
|
||||||
Fill
|
Fill
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -988,7 +990,7 @@ fn save_as_dialog_window<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut items: Vec<Element<'a, Message>> = Vec::new();
|
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());
|
items.push(Space::new().height(12).into());
|
||||||
|
|
||||||
// Web has no native file dialog, so the file name is typed here. On native
|
// 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(
|
items.push(
|
||||||
row![
|
row![
|
||||||
label("File name:").width(70),
|
label(t!("File name:")).width(70),
|
||||||
iced::widget::text_input("drawing.dwg", filename)
|
iced::widget::text_input("drawing.dwg", filename)
|
||||||
.on_input(Message::SaveDialogFilenameChanged)
|
.on_input(Message::SaveDialogFilenameChanged)
|
||||||
.size(13)
|
.size(13)
|
||||||
|
|
@ -1016,7 +1018,7 @@ fn save_as_dialog_window<'a>(
|
||||||
|
|
||||||
items.push(
|
items.push(
|
||||||
row![
|
row![
|
||||||
label("Format:").width(70),
|
label(t!("Format:")).width(70),
|
||||||
iced::widget::pick_list(
|
iced::widget::pick_list(
|
||||||
sel_fmt,
|
sel_fmt,
|
||||||
crate::io::SAVE_FORMAT_OPTIONS,
|
crate::io::SAVE_FORMAT_OPTIONS,
|
||||||
|
|
@ -1034,9 +1036,9 @@ fn save_as_dialog_window<'a>(
|
||||||
items.push(
|
items.push(
|
||||||
row![
|
row![
|
||||||
Space::new().width(Fit),
|
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),
|
Space::new().width(8),
|
||||||
dialog_button("Cancel", Message::SaveDialogCancel, button::secondary),
|
dialog_button(t!("Cancel"), Message::SaveDialogCancel, button::secondary),
|
||||||
]
|
]
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -1058,18 +1060,21 @@ fn unsaved_changes_dialog_window(
|
||||||
name: &str,
|
name: &str,
|
||||||
sizing: crate::ui::modal::ModalSizing,
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'static, Message> {
|
) -> 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(
|
container(
|
||||||
column![
|
column![
|
||||||
text(body_text).size(13),
|
text(body_text).size(13),
|
||||||
iced::widget::Space::new().height(20),
|
iced::widget::Space::new().height(20),
|
||||||
row![
|
row![
|
||||||
dialog_button("Save", Message::UnsavedDialogSave, button::primary),
|
dialog_button(t!("Save"), Message::UnsavedDialogSave, button::primary),
|
||||||
iced::widget::Space::new().width(8),
|
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),
|
iced::widget::Space::new().width(8),
|
||||||
dialog_button("Cancel", Message::UnsavedDialogCancel, button::secondary),
|
dialog_button(t!("Cancel"), Message::UnsavedDialogCancel, button::secondary),
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
.spacing(0),
|
.spacing(0),
|
||||||
|
|
@ -1090,19 +1095,18 @@ fn file_in_use_dialog_window(
|
||||||
let file_name = std::path::Path::new(path)
|
let file_name = std::path::Path::new(path)
|
||||||
.file_name()
|
.file_name()
|
||||||
.map(|name| name.to_string_lossy().into_owned())
|
.map(|name| name.to_string_lossy().into_owned())
|
||||||
.unwrap_or_else(|| "Drawing".to_string());
|
.unwrap_or_else(|| t!("Drawing").into_owned());
|
||||||
let heading = format!("\"{file_name}\" could not be saved.");
|
let heading = t!("\"%{file_name}\" could not be saved.", file_name = file_name);
|
||||||
let path_line = format!("Path: {path}");
|
let path_line = t!("Path: %{path}", path = path);
|
||||||
let details = format!("Details: {error}");
|
let details = t!("Details: %{error}", error = error);
|
||||||
|
|
||||||
container(
|
container(
|
||||||
column![
|
column![
|
||||||
text(heading).size(14),
|
text(heading).size(14),
|
||||||
Space::new().height(8),
|
Space::new().height(8),
|
||||||
text(
|
text(t!(
|
||||||
"The file is open or being used by another application. \
|
"The file is open or being used by another application. Close it there and retry, or save this drawing under a different name."
|
||||||
Close it there and retry, or save this drawing under a different name."
|
))
|
||||||
)
|
|
||||||
.size(13)
|
.size(13)
|
||||||
.width(Fit),
|
.width(Fit),
|
||||||
Space::new().height(12),
|
Space::new().height(12),
|
||||||
|
|
@ -1112,19 +1116,19 @@ fn file_in_use_dialog_window(
|
||||||
Space::new().height(18),
|
Space::new().height(18),
|
||||||
row![
|
row![
|
||||||
dialog_button(
|
dialog_button(
|
||||||
"Retry",
|
t!("Retry"),
|
||||||
Message::SaveFileInUseRetry,
|
Message::SaveFileInUseRetry,
|
||||||
button::primary
|
button::primary
|
||||||
),
|
),
|
||||||
Space::new().width(8),
|
Space::new().width(8),
|
||||||
dialog_button(
|
dialog_button(
|
||||||
"Save As",
|
t!("Save As"),
|
||||||
Message::SaveFileInUseSaveAs,
|
Message::SaveFileInUseSaveAs,
|
||||||
button::secondary
|
button::secondary
|
||||||
),
|
),
|
||||||
Space::new().width(8),
|
Space::new().width(8),
|
||||||
dialog_button(
|
dialog_button(
|
||||||
"Cancel",
|
t!("Cancel"),
|
||||||
Message::SaveFileInUseCancel,
|
Message::SaveFileInUseCancel,
|
||||||
button::secondary
|
button::secondary
|
||||||
),
|
),
|
||||||
|
|
@ -1147,18 +1151,17 @@ fn external_change_dialog_window(
|
||||||
let file_name = std::path::Path::new(path)
|
let file_name = std::path::Path::new(path)
|
||||||
.file_name()
|
.file_name()
|
||||||
.map(|name| name.to_string_lossy().into_owned())
|
.map(|name| name.to_string_lossy().into_owned())
|
||||||
.unwrap_or_else(|| "Drawing".to_string());
|
.unwrap_or_else(|| t!("Drawing").into_owned());
|
||||||
let heading = format!("\"{file_name}\" was changed by another application.");
|
let heading = t!("\"%{file_name}\" was changed by another application.", file_name = file_name);
|
||||||
let path_line = format!("Path: {path}");
|
let path_line = t!("Path: %{path}", path = path);
|
||||||
|
|
||||||
container(
|
container(
|
||||||
column![
|
column![
|
||||||
text(heading).size(14),
|
text(heading).size(14),
|
||||||
Space::new().height(8),
|
Space::new().height(8),
|
||||||
text(
|
text(t!(
|
||||||
"Saving now could destroy those external changes. Reload the disk copy, \
|
"Saving now could destroy those external changes. Reload the disk copy, save your local work elsewhere, or explicitly overwrite it."
|
||||||
save your local work elsewhere, or explicitly overwrite it."
|
))
|
||||||
)
|
|
||||||
.size(13)
|
.size(13)
|
||||||
.width(Fit),
|
.width(Fit),
|
||||||
Space::new().height(12),
|
Space::new().height(12),
|
||||||
|
|
@ -1166,25 +1169,25 @@ fn external_change_dialog_window(
|
||||||
Space::new().height(18),
|
Space::new().height(18),
|
||||||
row![
|
row![
|
||||||
dialog_button(
|
dialog_button(
|
||||||
"Reload from Disk",
|
t!("Reload from Disk"),
|
||||||
Message::ExternalChangeReload,
|
Message::ExternalChangeReload,
|
||||||
button::primary
|
button::primary
|
||||||
),
|
),
|
||||||
Space::new().width(8),
|
Space::new().width(8),
|
||||||
dialog_button(
|
dialog_button(
|
||||||
"Save As",
|
t!("Save As"),
|
||||||
Message::ExternalChangeSaveAs,
|
Message::ExternalChangeSaveAs,
|
||||||
button::secondary
|
button::secondary
|
||||||
),
|
),
|
||||||
Space::new().width(8),
|
Space::new().width(8),
|
||||||
dialog_button(
|
dialog_button(
|
||||||
"Overwrite",
|
t!("Overwrite"),
|
||||||
Message::ExternalChangeOverwrite,
|
Message::ExternalChangeOverwrite,
|
||||||
button::danger
|
button::danger
|
||||||
),
|
),
|
||||||
Space::new().width(8),
|
Space::new().width(8),
|
||||||
dialog_button(
|
dialog_button(
|
||||||
"Cancel",
|
t!("Cancel"),
|
||||||
Message::ExternalChangeCancel,
|
Message::ExternalChangeCancel,
|
||||||
button::secondary
|
button::secondary
|
||||||
),
|
),
|
||||||
|
|
@ -1209,10 +1212,11 @@ fn aec_drop_dialog_window(
|
||||||
src_version: &str,
|
src_version: &str,
|
||||||
sizing: crate::ui::modal::ModalSizing,
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'static, Message> {
|
) -> Element<'static, Message> {
|
||||||
let body_text = format!(
|
let body_text = t!(
|
||||||
"This drawing contains {count} AEC/Civil objects that \"{target}\" \
|
"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}).",
|
||||||
cannot store, so they will not be saved.\n\n\
|
count = count,
|
||||||
To keep them, save in the source version ({src_version})."
|
target = target,
|
||||||
|
src_version = src_version,
|
||||||
);
|
);
|
||||||
|
|
||||||
container(
|
container(
|
||||||
|
|
@ -1221,14 +1225,14 @@ fn aec_drop_dialog_window(
|
||||||
iced::widget::Space::new().height(20),
|
iced::widget::Space::new().height(20),
|
||||||
row![
|
row![
|
||||||
dialog_button(
|
dialog_button(
|
||||||
"Save in source version",
|
t!("Save in source version"),
|
||||||
Message::AecDropSameVersion,
|
Message::AecDropSameVersion,
|
||||||
button::primary
|
button::primary
|
||||||
),
|
),
|
||||||
iced::widget::Space::new().width(8),
|
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),
|
iced::widget::Space::new().width(8),
|
||||||
dialog_button("Back", Message::AecDropBack, button::secondary),
|
dialog_button(t!("Back"), Message::AecDropBack, button::secondary),
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
.spacing(0),
|
.spacing(0),
|
||||||
|
|
@ -1249,16 +1253,25 @@ fn layer_delete_warning_window(
|
||||||
count: usize,
|
count: usize,
|
||||||
sizing: crate::ui::modal::ModalSizing,
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'static, Message> {
|
) -> Element<'static, Message> {
|
||||||
let obj = if count == 1 { "object" } else { "objects" };
|
let obj = if count == 1 { t!("object") } else { t!("objects") };
|
||||||
let subject = if names.len() == 1 {
|
let has = if names.len() == 1 { t!("has") } else { t!("hold") };
|
||||||
format!("Layer \"{}\"", names[0])
|
let those = if count == 1 {
|
||||||
|
t!("that object")
|
||||||
} else {
|
} else {
|
||||||
format!("{} selected layers", names.len())
|
t!("those objects")
|
||||||
};
|
};
|
||||||
let body_text = format!(
|
let subject = if names.len() == 1 {
|
||||||
"{subject} still {} {count} {obj}.\n\nDeleting will also remove {} from the drawing. Continue?",
|
t!("Layer \"%{name}\"", name = names[0]).into_owned()
|
||||||
if names.len() == 1 { "has" } else { "hold" },
|
} else {
|
||||||
if count == 1 { "that object" } else { "those objects" }
|
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(
|
container(
|
||||||
|
|
@ -1267,12 +1280,12 @@ fn layer_delete_warning_window(
|
||||||
iced::widget::Space::new().height(20),
|
iced::widget::Space::new().height(20),
|
||||||
row![
|
row![
|
||||||
dialog_button(
|
dialog_button(
|
||||||
"Delete Objects",
|
t!("Delete Objects"),
|
||||||
Message::LayerDeleteConfirm,
|
Message::LayerDeleteConfirm,
|
||||||
button::danger
|
button::danger
|
||||||
),
|
),
|
||||||
iced::widget::Space::new().width(8),
|
iced::widget::Space::new().width(8),
|
||||||
dialog_button("Cancel", Message::CloseModal, button::secondary),
|
dialog_button(t!("Cancel"), Message::CloseModal, button::secondary),
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
.spacing(0),
|
.spacing(0),
|
||||||
|
|
@ -1293,19 +1306,19 @@ fn default_assoc_dialog_window(
|
||||||
) -> Element<'static, Message> {
|
) -> Element<'static, Message> {
|
||||||
container(
|
container(
|
||||||
column![
|
column![
|
||||||
text("Make Open CAD Studio your default CAD app?")
|
text(t!("Make Open CAD Studio your default CAD app?"))
|
||||||
.size(15),
|
.size(15),
|
||||||
iced::widget::Space::new().height(10),
|
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)
|
.size(12)
|
||||||
.style(dialog_muted_text_style),
|
.style(dialog_muted_text_style),
|
||||||
iced::widget::Space::new().height(22),
|
iced::widget::Space::new().height(22),
|
||||||
row![
|
row![
|
||||||
iced::widget::Space::new().width(Fit),
|
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),
|
iced::widget::Space::new().width(8),
|
||||||
dialog_button(
|
dialog_button(
|
||||||
"Yes, set as default",
|
t!("Yes, set as default"),
|
||||||
Message::AssocPromptYes,
|
Message::AssocPromptYes,
|
||||||
button::primary
|
button::primary
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use iced::widget::{
|
||||||
Space,
|
Space,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Color, Element, Fill, Theme};
|
use iced::{Background, Border, Color, Element, Fill, Theme};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub(super) fn position_canvas_overlay<'a>(
|
pub(super) fn position_canvas_overlay<'a>(
|
||||||
anchor: iced::Point,
|
anchor: iced::Point,
|
||||||
|
|
@ -28,7 +29,7 @@ pub(super) fn text_inline_overlay(
|
||||||
ed: &super::super::text_inline::TextInlineState,
|
ed: &super::super::text_inline::TextInlineState,
|
||||||
canvas: (f32, f32),
|
canvas: (f32, f32),
|
||||||
) -> Element<'_, Message> {
|
) -> 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))
|
.id(iced::widget::Id::new(TEXT_INLINE_ID))
|
||||||
.on_input(Message::TextInlineInput)
|
.on_input(Message::TextInlineInput)
|
||||||
.on_submit(Message::TextInlineOk)
|
.on_submit(Message::TextInlineOk)
|
||||||
|
|
@ -366,7 +367,7 @@ pub(super) fn mtext_editor_overlay<'a>(
|
||||||
|
|
||||||
crate::ui::modal::modal(
|
crate::ui::modal::modal(
|
||||||
iced::widget::Space::new().width(Fill).height(Fill),
|
iced::widget::Space::new().width(Fill).height(Fill),
|
||||||
"Text Editor",
|
t!("Text Editor"),
|
||||||
content,
|
content,
|
||||||
Message::MTextCancel,
|
Message::MTextCancel,
|
||||||
modal_offset,
|
modal_offset,
|
||||||
|
|
@ -577,7 +578,7 @@ fn mtext_editor_content<'a>(
|
||||||
f64::from(writing_area_px / preview_scale).max(slider_min * 2.0);
|
f64::from(writing_area_px / preview_scale).max(slider_min * 2.0);
|
||||||
let width_slider = column![
|
let width_slider = column![
|
||||||
row![
|
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),
|
Space::new().width(width),
|
||||||
text(format!("{:.0}%", ed.rect_width / slider_max * 100.0)).size(11),
|
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(
|
let action_bar = container(
|
||||||
row![
|
row![
|
||||||
iced::widget::Space::new().width(width),
|
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),
|
.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();
|
let mut items: Vec<Element<'static, Message>> = Vec::new();
|
||||||
|
|
||||||
if has_cmd {
|
if has_cmd {
|
||||||
items.push(item("Cancel".to_string(), Message::CommandEscape));
|
items.push(item(t!("Cancel").into_owned(), Message::CommandEscape));
|
||||||
items.push(item("Enter".to_string(), Message::CommandFinalize));
|
items.push(item(t!("Enter").into_owned(), Message::CommandFinalize));
|
||||||
} else {
|
} else {
|
||||||
if !last_cmds.is_empty() {
|
if !last_cmds.is_empty() {
|
||||||
let last = last_cmds[0].clone();
|
let last = last_cmds[0].clone();
|
||||||
items.push(item(
|
items.push(item(
|
||||||
format!("Repeat {last}"),
|
t!("Repeat %{last}", last = last).into_owned(),
|
||||||
Message::Command(last.to_uppercase()),
|
Message::Command(last.to_uppercase()),
|
||||||
));
|
));
|
||||||
if last_cmds.len() > 1 {
|
if last_cmds.len() > 1 {
|
||||||
|
|
@ -802,13 +803,13 @@ pub(super) fn viewport_context_menu_overlay(
|
||||||
items.push(sep());
|
items.push(sep());
|
||||||
}
|
}
|
||||||
if has_selection {
|
if has_selection {
|
||||||
items.push(item("Delete".to_string(), Message::DeleteSelected));
|
items.push(item(t!("Delete").into_owned(), Message::DeleteSelected));
|
||||||
items.push(item(
|
items.push(item(
|
||||||
"Move".to_string(),
|
t!("Move").into_owned(),
|
||||||
Message::Command("MOVE".to_string()),
|
Message::Command("MOVE".to_string()),
|
||||||
));
|
));
|
||||||
items.push(item(
|
items.push(item(
|
||||||
"Copy".to_string(),
|
t!("Copy").into_owned(),
|
||||||
Message::Command("COPY".to_string()),
|
Message::Command("COPY".to_string()),
|
||||||
));
|
));
|
||||||
items.push(sep());
|
items.push(sep());
|
||||||
|
|
@ -820,7 +821,7 @@ pub(super) fn viewport_context_menu_overlay(
|
||||||
items.push(
|
items.push(
|
||||||
button(
|
button(
|
||||||
row![
|
row![
|
||||||
text("Draw Order").size(12),
|
text(t!("Draw Order").into_owned()).size(12),
|
||||||
iced::widget::Space::new().width(Fill),
|
iced::widget::Space::new().width(Fill),
|
||||||
do_caret,
|
do_caret,
|
||||||
]
|
]
|
||||||
|
|
@ -834,51 +835,51 @@ pub(super) fn viewport_context_menu_overlay(
|
||||||
);
|
);
|
||||||
if draworder_open {
|
if draworder_open {
|
||||||
items.push(subitem(
|
items.push(subitem(
|
||||||
"Bring to Front".to_string(),
|
t!("Bring to Front").into_owned(),
|
||||||
Message::Command("DRAWORDER F".to_string()),
|
Message::Command("DRAWORDER F".to_string()),
|
||||||
));
|
));
|
||||||
items.push(subitem(
|
items.push(subitem(
|
||||||
"Send to Back".to_string(),
|
t!("Send to Back").into_owned(),
|
||||||
Message::Command("DRAWORDER B".to_string()),
|
Message::Command("DRAWORDER B".to_string()),
|
||||||
));
|
));
|
||||||
items.push(subitem(
|
items.push(subitem(
|
||||||
"Bring Above Object".to_string(),
|
t!("Bring Above Object").into_owned(),
|
||||||
Message::DrawOrderPickRef(true),
|
Message::DrawOrderPickRef(true),
|
||||||
));
|
));
|
||||||
items.push(subitem(
|
items.push(subitem(
|
||||||
"Send Under Object".to_string(),
|
t!("Send Under Object").into_owned(),
|
||||||
Message::DrawOrderPickRef(false),
|
Message::DrawOrderPickRef(false),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
items.push(sep());
|
items.push(sep());
|
||||||
items.push(item(
|
items.push(item(
|
||||||
"Isolate Objects".to_string(),
|
t!("Isolate Objects").into_owned(),
|
||||||
Message::Command("ISOLATEOBJECTS".to_string()),
|
Message::Command("ISOLATEOBJECTS".to_string()),
|
||||||
));
|
));
|
||||||
items.push(item(
|
items.push(item(
|
||||||
"Hide Objects".to_string(),
|
t!("Hide Objects").into_owned(),
|
||||||
Message::Command("HIDEOBJECTS".to_string()),
|
Message::Command("HIDEOBJECTS".to_string()),
|
||||||
));
|
));
|
||||||
items.push(sep());
|
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(
|
items.push(item(
|
||||||
"Invert Selection".to_string(),
|
t!("Invert Selection").into_owned(),
|
||||||
Message::InvertSelection,
|
Message::InvertSelection,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if isolation_active {
|
if isolation_active {
|
||||||
items.push(item(
|
items.push(item(
|
||||||
"End Object Isolation".to_string(),
|
t!("End Object Isolation").into_owned(),
|
||||||
Message::Command("UNISOLATEOBJECTS".to_string()),
|
Message::Command("UNISOLATEOBJECTS".to_string()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
items.push(item(
|
items.push(item(
|
||||||
"Select All".to_string(),
|
t!("Select All").into_owned(),
|
||||||
Message::Command("SELECTALL".to_string()),
|
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(
|
items.push(item(
|
||||||
"Zoom Extents".to_string(),
|
t!("Zoom Extents").into_owned(),
|
||||||
Message::Command("ZOOM EXTENTS".to_string()),
|
Message::Command("ZOOM EXTENTS".to_string()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
@ -1020,7 +1021,7 @@ pub(super) fn qselect_overlay<'a>(
|
||||||
|
|
||||||
crate::ui::modal::modal(
|
crate::ui::modal::modal(
|
||||||
Space::new().width(Fill).height(Fill),
|
Space::new().width(Fill).height(Fill),
|
||||||
"Quick Select",
|
t!("Quick Select"),
|
||||||
content,
|
content,
|
||||||
Message::QSelectClose,
|
Message::QSelectClose,
|
||||||
modal_offset,
|
modal_offset,
|
||||||
|
|
@ -1081,13 +1082,13 @@ fn qselect_content<'a>(
|
||||||
iced::Length::Shrink
|
iced::Length::Shrink
|
||||||
};
|
};
|
||||||
|
|
||||||
let label = |s: &'static str| {
|
let label = |s: std::borrow::Cow<'static, str>| {
|
||||||
text(s)
|
text(s)
|
||||||
.size(12)
|
.size(12)
|
||||||
.width(iced::Length::Fixed(90.0))
|
.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))
|
button(text(lbl).size(12))
|
||||||
.on_press(msg)
|
.on_press(msg)
|
||||||
.style(move |theme: &Theme, st| {
|
.style(move |theme: &Theme, st| {
|
||||||
|
|
@ -1124,7 +1125,7 @@ fn qselect_content<'a>(
|
||||||
|
|
||||||
let panel_body = column![
|
let panel_body = column![
|
||||||
row![
|
row![
|
||||||
label("Object type:"),
|
label(t!("Object type:")),
|
||||||
iced::widget::pick_list(
|
iced::widget::pick_list(
|
||||||
Some(type_sel),
|
Some(type_sel),
|
||||||
type_options,
|
type_options,
|
||||||
|
|
@ -1144,7 +1145,7 @@ fn qselect_content<'a>(
|
||||||
.width(sizing.width),
|
.width(sizing.width),
|
||||||
Space::new().height(6),
|
Space::new().height(6),
|
||||||
row![
|
row![
|
||||||
label("Property:"),
|
label(t!("Property:")),
|
||||||
iced::widget::pick_list(
|
iced::widget::pick_list(
|
||||||
Some(prop_sel),
|
Some(prop_sel),
|
||||||
prop_options,
|
prop_options,
|
||||||
|
|
@ -1164,7 +1165,7 @@ fn qselect_content<'a>(
|
||||||
.width(sizing.width),
|
.width(sizing.width),
|
||||||
Space::new().height(6),
|
Space::new().height(6),
|
||||||
row![
|
row![
|
||||||
label("Operator:"),
|
label(t!("Operator:")),
|
||||||
iced::widget::pick_list(
|
iced::widget::pick_list(
|
||||||
Some(state.operator),
|
Some(state.operator),
|
||||||
op_options,
|
op_options,
|
||||||
|
|
@ -1177,7 +1178,7 @@ fn qselect_content<'a>(
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.width(sizing.width),
|
.width(sizing.width),
|
||||||
Space::new().height(6),
|
Space::new().height(6),
|
||||||
row![label("Value:"), value_input,]
|
row![label(t!("Value:")), value_input,]
|
||||||
.align_y(iced::Alignment::Center)
|
.align_y(iced::Alignment::Center)
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.width(sizing.width),
|
.width(sizing.width),
|
||||||
|
|
@ -1187,15 +1188,15 @@ fn qselect_content<'a>(
|
||||||
.on_toggle(Message::QSelectSetAppend)
|
.on_toggle(Message::QSelectSetAppend)
|
||||||
.size(14),
|
.size(14),
|
||||||
Space::new().width(6),
|
Space::new().width(6),
|
||||||
text("Append to current selection").size(12),
|
text(t!("Append to current selection")).size(12),
|
||||||
]
|
]
|
||||||
.align_y(iced::Alignment::Center),
|
.align_y(iced::Alignment::Center),
|
||||||
Space::new().height(14),
|
Space::new().height(14),
|
||||||
row![
|
row![
|
||||||
Space::new().width(field_width),
|
Space::new().width(field_width),
|
||||||
btn("Cancel", Message::QSelectClose, false),
|
btn(t!("Cancel"), Message::QSelectClose, false),
|
||||||
Space::new().width(8),
|
Space::new().width(8),
|
||||||
btn("Apply", Message::QSelectApply, true),
|
btn(t!("Apply"), Message::QSelectApply, true),
|
||||||
]
|
]
|
||||||
.align_y(iced::Alignment::Center),
|
.align_y(iced::Alignment::Center),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ impl CadCommand for ValuePromptCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
self.prompt.to_string()
|
crate::t!(self.prompt).into_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wants_text_input(&self) -> bool {
|
fn wants_text_input(&self) -> bool {
|
||||||
|
|
@ -177,9 +177,18 @@ impl CadCommand for RenameCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
RenameStep::Type => "RENAME Select the object type to rename:".to_string(),
|
RenameStep::Type => crate::t!("RENAME Select the object type to rename:").into_owned(),
|
||||||
RenameStep::Old { ty } => format!("RENAME {ty} Enter the current name:"),
|
RenameStep::Old { ty } => crate::t!(
|
||||||
RenameStep::New { ty, old } => format!("RENAME {ty} Rename \"{old}\" to:"),
|
"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 {
|
fn prompt(&self) -> String {
|
||||||
match self.slot {
|
match self.slot {
|
||||||
None => format!("{} which register? [1-5]:", self.name),
|
None => crate::t!("%{name} which register? [1-5]:", name = self.name)
|
||||||
Some(n) => format!("{}{n} new value:", 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 {
|
fn prompt(&self) -> String {
|
||||||
match self.pending {
|
match self.pending {
|
||||||
Some((_, value_prompt)) => value_prompt.to_string(),
|
Some((_, value_prompt)) => crate::t!(value_prompt).into_owned(),
|
||||||
None => self.prompt.to_string(),
|
None => crate::t!(self.prompt).into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -464,8 +475,8 @@ impl CadCommand for TwoValuePromptCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.first {
|
match &self.first {
|
||||||
None => self.prompt1.to_string(),
|
None => crate::t!(self.prompt1).into_owned(),
|
||||||
Some(_) => self.prompt2.to_string(),
|
Some(_) => crate::t!(self.prompt2).into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -548,11 +559,15 @@ impl CadCommand for SelectThenKeywordCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
if self.gathering {
|
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 {
|
match self.pending {
|
||||||
Some((_, value_prompt)) => value_prompt.to_string(),
|
Some((_, value_prompt)) => crate::t!(value_prompt).into_owned(),
|
||||||
None => self.prompt.to_string(),
|
None => crate::t!(self.prompt).into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -655,9 +670,13 @@ impl CadCommand for SelectThenValueCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
if self.gathering {
|
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 {
|
} 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 {
|
fn prompt(&self) -> String {
|
||||||
if self.gathering {
|
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() {
|
} else if self.first.is_none() {
|
||||||
self.prompt1.to_string()
|
crate::t!(self.prompt1).into_owned()
|
||||||
} else {
|
} 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")`.
|
/// Button whose keyword is typed on click, e.g. `("Ttr", "TTR")`.
|
||||||
pub fn new(label: &str, keyword: &str) -> Self {
|
pub fn new(label: &str, keyword: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
label: label.to_string(),
|
label: crate::t!(label).into_owned(),
|
||||||
keyword: keyword.to_string(),
|
keyword: keyword.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// A "finish" button that submits the step like Enter.
|
/// A "finish" button that submits the step like Enter.
|
||||||
pub fn enter(label: &str) -> Self {
|
pub fn enter(label: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
label: label.to_string(),
|
label: crate::t!(label).into_owned(),
|
||||||
keyword: String::new(),
|
keyword: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use acadrust::entities::Arc;
|
use acadrust::entities::Arc;
|
||||||
|
use crate::t;
|
||||||
use truck_modeling::{builder, Point3};
|
use truck_modeling::{builder, Point3};
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
|
|
@ -152,26 +153,26 @@ fn properties(arc: &Arc) -> Vec<PropSection> {
|
||||||
let (ex, ey, ez) = arc_pt(ea);
|
let (ex, ey, ez) = arc_pt(ea);
|
||||||
|
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Start X", "start_x", format!("{sx:.4}")),
|
ro(t!("Start X").as_ref(), "start_x", format!("{sx:.4}")),
|
||||||
ro("Start Y", "start_y", format!("{sy:.4}")),
|
ro(t!("Start Y").as_ref(), "start_y", format!("{sy:.4}")),
|
||||||
ro("Start Z", "start_z", format!("{sz:.4}")),
|
ro(t!("Start Z").as_ref(), "start_z", format!("{sz:.4}")),
|
||||||
edit("Center X", "center_x", arc.center.x),
|
edit(t!("Center X").as_ref(), "center_x", arc.center.x),
|
||||||
edit("Center Y", "center_y", arc.center.y),
|
edit(t!("Center Y").as_ref(), "center_y", arc.center.y),
|
||||||
edit("Center Z", "center_z", arc.center.z),
|
edit(t!("Center Z").as_ref(), "center_z", arc.center.z),
|
||||||
ro("End X", "end_x", format!("{ex:.4}")),
|
ro(t!("End X").as_ref(), "end_x", format!("{ex:.4}")),
|
||||||
ro("End Y", "end_y", format!("{ey:.4}")),
|
ro(t!("End Y").as_ref(), "end_y", format!("{ey:.4}")),
|
||||||
ro("End Z", "end_z", format!("{ez:.4}")),
|
ro(t!("End Z").as_ref(), "end_z", format!("{ez:.4}")),
|
||||||
edit("Radius", "radius", arc.radius),
|
edit(t!("Radius").as_ref(), "radius", arc.radius),
|
||||||
edit_angle("Start angle", "start_angle", sa.to_degrees()),
|
edit_angle(t!("Start angle").as_ref(), "start_angle", sa.to_degrees()),
|
||||||
edit_angle("End angle", "end_angle", ea.to_degrees()),
|
edit_angle(t!("End angle").as_ref(), "end_angle", ea.to_degrees()),
|
||||||
ro("Total angle", "total_angle", format!("{total_angle:.2}")),
|
ro(t!("Total angle").as_ref(), "total_angle", format!("{total_angle:.2}")),
|
||||||
ro("Arc length", "arc_length", format!("{arc_length:.4}")),
|
ro(t!("Arc length").as_ref(), "arc_length", format!("{arc_length:.4}")),
|
||||||
ro("Area", "area", format!("{area:.4}")),
|
ro(t!("Area").as_ref(), "area", format!("{area:.4}")),
|
||||||
ro("Normal X", "normal_x", format!("{:.4}", arc.normal.x)),
|
ro(t!("Normal X").as_ref(), "normal_x", format!("{:.4}", arc.normal.x)),
|
||||||
ro("Normal Y", "normal_y", format!("{:.4}", arc.normal.y)),
|
ro(t!("Normal Y").as_ref(), "normal_y", format!("{:.4}", arc.normal.y)),
|
||||||
ro("Normal Z", "normal_z", format!("{:.4}", arc.normal.z)),
|
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::model::wire_model::SnapHint;
|
||||||
use crate::scene::text::lff;
|
use crate::scene::text::lff;
|
||||||
use crate::scene::view::transform;
|
use crate::scene::view::transform;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
// ── Shared helpers ────────────────────────────────────────────────────────────
|
// ── Shared helpers ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -414,22 +415,22 @@ impl PropertyEditable for AttributeDefinition {
|
||||||
fn geometry_properties(&self, text_style_names: &[String]) -> Vec<PropSection> {
|
fn geometry_properties(&self, text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
let mut text_props = vec![
|
let mut text_props = vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Tag".into(),
|
label: t!("Tag").into_owned(),
|
||||||
field: "att_tag",
|
field: "att_tag",
|
||||||
value: PropValue::EditText(self.tag.clone()),
|
value: PropValue::EditText(self.tag.clone()),
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Prompt".into(),
|
label: t!("Prompt").into_owned(),
|
||||||
field: "att_prompt",
|
field: "att_prompt",
|
||||||
value: PropValue::EditText(self.prompt.clone()),
|
value: PropValue::EditText(self.prompt.clone()),
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Value".into(),
|
label: t!("Value").into_owned(),
|
||||||
field: "att_default",
|
field: "att_default",
|
||||||
value: PropValue::EditText(self.default_value.clone()),
|
value: PropValue::EditText(self.default_value.clone()),
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Style".into(),
|
label: t!("Style").into_owned(),
|
||||||
field: "att_style",
|
field: "att_style",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: if self.text_style.trim().is_empty() {
|
selected: if self.text_style.trim().is_empty() {
|
||||||
|
|
@ -441,12 +442,12 @@ impl PropertyEditable for AttributeDefinition {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ro(
|
ro(
|
||||||
"Annotative",
|
t!("Annotative").as_ref(),
|
||||||
"att_annotative",
|
"att_annotative",
|
||||||
bool_yn(self.flags.annotative),
|
bool_yn(self.flags.annotative),
|
||||||
),
|
),
|
||||||
Property {
|
Property {
|
||||||
label: "Justify".into(),
|
label: t!("Justify").into_owned(),
|
||||||
field: "att_halign",
|
field: "att_halign",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: halign_str(self.horizontal_alignment).to_string(),
|
selected: halign_str(self.horizontal_alignment).to_string(),
|
||||||
|
|
@ -457,7 +458,7 @@ impl PropertyEditable for AttributeDefinition {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "V-Align".into(),
|
label: t!("V-Align").into_owned(),
|
||||||
field: "att_valign",
|
field: "att_valign",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: valign_str(self.vertical_alignment).to_string(),
|
selected: valign_str(self.vertical_alignment).to_string(),
|
||||||
|
|
@ -467,25 +468,25 @@ impl PropertyEditable for AttributeDefinition {
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edit("Height", "att_h", self.height),
|
edit(t!("Height").as_ref(), "att_h", self.height),
|
||||||
edit_angle("Rotation", "att_rot", self.rotation.to_degrees()),
|
edit_angle(t!("Rotation").as_ref(), "att_rot", self.rotation.to_degrees()),
|
||||||
edit("Width factor", "att_wf", self.width_factor),
|
edit(t!("Width factor").as_ref(), "att_wf", self.width_factor),
|
||||||
edit_angle("Obliquing", "att_ob", self.oblique_angle.to_degrees()),
|
edit_angle(t!("Obliquing").as_ref(), "att_ob", self.oblique_angle.to_degrees()),
|
||||||
edit("Text alignment X", "att_ax", self.alignment_point.x),
|
edit(t!("Text alignment X").as_ref(), "att_ax", self.alignment_point.x),
|
||||||
edit("Text alignment Y", "att_ay", self.alignment_point.y),
|
edit(t!("Text alignment Y").as_ref(), "att_ay", self.alignment_point.y),
|
||||||
edit("Text alignment Z", "att_az", self.alignment_point.z),
|
edit(t!("Text alignment Z").as_ref(), "att_az", self.alignment_point.z),
|
||||||
ro(
|
ro(
|
||||||
"Boundary width",
|
t!("Boundary width").as_ref(),
|
||||||
"att_field_len",
|
"att_field_len",
|
||||||
self.field_length.to_string(),
|
self.field_length.to_string(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Upside down",
|
t!("Upside down").as_ref(),
|
||||||
"att_upside_down",
|
"att_upside_down",
|
||||||
bool_yn(self.text_generation_flags & 0x4 != 0),
|
bool_yn(self.text_generation_flags & 0x4 != 0),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Backward",
|
t!("Backward").as_ref(),
|
||||||
"att_backward",
|
"att_backward",
|
||||||
bool_yn(self.text_generation_flags & 0x2 != 0),
|
bool_yn(self.text_generation_flags & 0x2 != 0),
|
||||||
),
|
),
|
||||||
|
|
@ -499,27 +500,27 @@ impl PropertyEditable for AttributeDefinition {
|
||||||
}
|
}
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Text".into(),
|
title: t!("Text").into_owned(),
|
||||||
props: text_props,
|
props: text_props,
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Position X", "att_ix", self.insertion_point.x),
|
edit(t!("Position X").as_ref(), "att_ix", self.insertion_point.x),
|
||||||
edit("Position Y", "att_iy", self.insertion_point.y),
|
edit(t!("Position Y").as_ref(), "att_iy", self.insertion_point.y),
|
||||||
edit("Position Z", "att_iz", self.insertion_point.z),
|
edit(t!("Position Z").as_ref(), "att_iz", self.insertion_point.z),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Invisible", "att_invisible", bool_yn(self.flags.invisible)),
|
ro(t!("Invisible").as_ref(), "att_invisible", bool_yn(self.flags.invisible)),
|
||||||
ro("Constant", "att_constant", bool_yn(self.flags.constant)),
|
ro(t!("Constant").as_ref(), "att_constant", bool_yn(self.flags.constant)),
|
||||||
ro("Verify", "att_verify", bool_yn(self.flags.verify)),
|
ro(t!("Verify").as_ref(), "att_verify", bool_yn(self.flags.verify)),
|
||||||
ro("Preset", "att_preset", bool_yn(self.flags.preset)),
|
ro(t!("Preset").as_ref(), "att_preset", bool_yn(self.flags.preset)),
|
||||||
ro("Lock position", "att_lock_pos", bool_yn(self.lock_position)),
|
ro(t!("Lock position").as_ref(), "att_lock_pos", bool_yn(self.lock_position)),
|
||||||
Property {
|
Property {
|
||||||
label: "Multiple lines".into(),
|
label: t!("Multiple lines").into_owned(),
|
||||||
field: "att_mtext_flag",
|
field: "att_mtext_flag",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: mtext_flag_str(self.mtext_flag).to_string(),
|
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> {
|
fn geometry_properties(&self, text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Text".into(),
|
title: t!("Text").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Tag".into(),
|
label: t!("Tag").into_owned(),
|
||||||
field: "atte_tag",
|
field: "atte_tag",
|
||||||
value: PropValue::EditText(self.tag.clone()),
|
value: PropValue::EditText(self.tag.clone()),
|
||||||
},
|
},
|
||||||
ro("Prompt", "atte_prompt", String::new()),
|
ro(t!("Prompt").as_ref(), "atte_prompt", String::new()),
|
||||||
Property {
|
Property {
|
||||||
label: "Value".into(),
|
label: t!("Value").into_owned(),
|
||||||
field: "atte_val",
|
field: "atte_val",
|
||||||
value: PropValue::EditText(self.value.clone()),
|
value: PropValue::EditText(self.value.clone()),
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Style".into(),
|
label: t!("Style").into_owned(),
|
||||||
field: "atte_style",
|
field: "atte_style",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: if self.text_style.trim().is_empty() {
|
selected: if self.text_style.trim().is_empty() {
|
||||||
|
|
@ -712,7 +713,7 @@ impl PropertyEditable for AttributeEntity {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Justify".into(),
|
label: t!("Justify").into_owned(),
|
||||||
field: "atte_halign",
|
field: "atte_halign",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: halign_str(self.horizontal_alignment).to_string(),
|
selected: halign_str(self.horizontal_alignment).to_string(),
|
||||||
|
|
@ -723,7 +724,7 @@ impl PropertyEditable for AttributeEntity {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "V-Align".into(),
|
label: t!("V-Align").into_owned(),
|
||||||
field: "atte_valign",
|
field: "atte_valign",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: valign_str(self.vertical_alignment).to_string(),
|
selected: valign_str(self.vertical_alignment).to_string(),
|
||||||
|
|
@ -734,56 +735,56 @@ impl PropertyEditable for AttributeEntity {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ro(
|
ro(
|
||||||
"Annotative",
|
t!("Annotative").as_ref(),
|
||||||
"atte_annotative",
|
"atte_annotative",
|
||||||
bool_yn(self.flags.annotative),
|
bool_yn(self.flags.annotative),
|
||||||
),
|
),
|
||||||
edit("Height", "atte_h", self.height),
|
edit(t!("Height").as_ref(), "atte_h", self.height),
|
||||||
edit_angle("Rotation", "atte_rot", self.rotation.to_degrees()),
|
edit_angle(t!("Rotation").as_ref(), "atte_rot", self.rotation.to_degrees()),
|
||||||
edit("Width factor", "atte_wf", self.width_factor),
|
edit(t!("Width factor").as_ref(), "atte_wf", self.width_factor),
|
||||||
edit_angle("Obliquing", "atte_ob", self.oblique_angle.to_degrees()),
|
edit_angle(t!("Obliquing").as_ref(), "atte_ob", self.oblique_angle.to_degrees()),
|
||||||
edit("Text alignment X", "atte_ax", self.alignment_point.x),
|
edit(t!("Text alignment X").as_ref(), "atte_ax", self.alignment_point.x),
|
||||||
edit("Text alignment Y", "atte_ay", self.alignment_point.y),
|
edit(t!("Text alignment Y").as_ref(), "atte_ay", self.alignment_point.y),
|
||||||
edit("Text alignment Z", "atte_az", self.alignment_point.z),
|
edit(t!("Text alignment Z").as_ref(), "atte_az", self.alignment_point.z),
|
||||||
ro(
|
ro(
|
||||||
"Boundary width",
|
t!("Boundary width").as_ref(),
|
||||||
"atte_field_len",
|
"atte_field_len",
|
||||||
self.field_length.to_string(),
|
self.field_length.to_string(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Position X", "atte_ix", self.insertion_point.x),
|
edit(t!("Position X").as_ref(), "atte_ix", self.insertion_point.x),
|
||||||
edit("Position Y", "atte_iy", self.insertion_point.y),
|
edit(t!("Position Y").as_ref(), "atte_iy", self.insertion_point.y),
|
||||||
edit("Position Z", "atte_iz", self.insertion_point.z),
|
edit(t!("Position Z").as_ref(), "atte_iz", self.insertion_point.z),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro(
|
ro(
|
||||||
"Upside down",
|
t!("Upside down").as_ref(),
|
||||||
"atte_upside_down",
|
"atte_upside_down",
|
||||||
bool_yn(self.text_generation_flags & 0x4 != 0),
|
bool_yn(self.text_generation_flags & 0x4 != 0),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Backward",
|
t!("Backward").as_ref(),
|
||||||
"atte_backward",
|
"atte_backward",
|
||||||
bool_yn(self.text_generation_flags & 0x2 != 0),
|
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(
|
ro(
|
||||||
"Multiple lines",
|
t!("Multiple lines").as_ref(),
|
||||||
"atte_mtext_flag",
|
"atte_mtext_flag",
|
||||||
mtext_flag_str(self.mtext_flag),
|
mtext_flag_str(self.mtext_flag),
|
||||||
),
|
),
|
||||||
ro("Constant", "atte_constant", bool_yn(self.flags.constant)),
|
ro(t!("Constant").as_ref(), "atte_constant", bool_yn(self.flags.constant)),
|
||||||
ro("Verify", "atte_verify", bool_yn(self.flags.verify)),
|
ro(t!("Verify").as_ref(), "atte_verify", bool_yn(self.flags.verify)),
|
||||||
ro("Preset", "atte_preset", bool_yn(self.flags.preset)),
|
ro(t!("Preset").as_ref(), "atte_preset", bool_yn(self.flags.preset)),
|
||||||
ro(
|
ro(
|
||||||
"Lock position",
|
t!("Lock position").as_ref(),
|
||||||
"atte_lock_pos",
|
"atte_lock_pos",
|
||||||
bool_yn(self.lock_position),
|
bool_yn(self.lock_position),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use acadrust::entities::Circle;
|
use acadrust::entities::Circle;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::{
|
use crate::entities::common::{
|
||||||
|
|
@ -134,18 +135,18 @@ fn properties(circle: &Circle) -> Vec<PropSection> {
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
let r = circle.radius;
|
let r = circle.radius;
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Center X", "center_x", circle.center.x),
|
edit(t!("Center X").as_ref(), "center_x", circle.center.x),
|
||||||
edit("Center Y", "center_y", circle.center.y),
|
edit(t!("Center Y").as_ref(), "center_y", circle.center.y),
|
||||||
edit("Center Z", "center_z", circle.center.z),
|
edit(t!("Center Z").as_ref(), "center_z", circle.center.z),
|
||||||
edit("Radius", "radius", r),
|
edit(t!("Radius").as_ref(), "radius", r),
|
||||||
edit("Diameter", "diameter", r * 2.0),
|
edit(t!("Diameter").as_ref(), "diameter", r * 2.0),
|
||||||
edit("Circumference", "circumference", 2.0 * PI * r),
|
edit(t!("Circumference").as_ref(), "circumference", 2.0 * PI * r),
|
||||||
edit("Area", "area", PI * r * r),
|
edit(t!("Area").as_ref(), "area", PI * r * r),
|
||||||
ro("Normal X", "normal_x", format!("{:.4}", circle.normal.x)),
|
ro(t!("Normal X").as_ref(), "normal_x", format!("{:.4}", circle.normal.x)),
|
||||||
ro("Normal Y", "normal_y", format!("{:.4}", circle.normal.y)),
|
ro(t!("Normal Y").as_ref(), "normal_y", format!("{:.4}", circle.normal.y)),
|
||||||
ro("Normal Z", "normal_z", format!("{:.4}", circle.normal.z)),
|
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
|
/// LINEAR formatter, so LUNITS=Architectural showed a block rotation as
|
||||||
/// feet-and-inches and the string wouldn't parse back (#297). Value in
|
/// feet-and-inches and the string wouldn't parse back (#297). Value in
|
||||||
/// DEGREES, matching every angle call site.
|
/// 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 {
|
Property {
|
||||||
label: label.into(),
|
label: label.into(),
|
||||||
field,
|
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 {
|
Property {
|
||||||
label: label.into(),
|
label: label.into(),
|
||||||
field,
|
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 {
|
Property {
|
||||||
label: label.into(),
|
label: label.into(),
|
||||||
field,
|
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
|
/// 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
|
/// editability depends on entity state (e.g. a text point that is only live for
|
||||||
/// certain justifications, or an MText column dimension).
|
/// 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 {
|
if editable {
|
||||||
edit_prop(label, field, value)
|
edit_prop(label, field, value)
|
||||||
} else {
|
} 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
|
/// A ◀ / ▶ index navigator row (e.g. a polyline's Current Vertex). `display` is
|
||||||
/// the label shown between the arrows (e.g. "2 / 7").
|
/// the label shown between the arrows (e.g. "2 / 7").
|
||||||
pub fn stepper_prop(
|
pub fn stepper_prop(
|
||||||
label: &'static str,
|
label: &str,
|
||||||
field: &'static str,
|
field: &'static str,
|
||||||
display: impl Into<String>,
|
display: impl Into<String>,
|
||||||
) -> Property {
|
) -> Property {
|
||||||
|
|
|
||||||
|
|
@ -12,46 +12,47 @@ use crate::entities::common::{
|
||||||
};
|
};
|
||||||
use crate::entities::traits::{Grippable, PropertyEditable, Transformable};
|
use crate::entities::traits::{Grippable, PropertyEditable, Transformable};
|
||||||
use crate::scene::model::object::{GripApply, GripDef, PropSection};
|
use crate::scene::model::object::{GripApply, GripDef, PropSection};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
fn base_props(base: &DimensionBase) -> Vec<crate::scene::model::object::Property> {
|
fn base_props(base: &DimensionBase) -> Vec<crate::scene::model::object::Property> {
|
||||||
vec![
|
vec![
|
||||||
crate::scene::model::object::Property {
|
crate::scene::model::object::Property {
|
||||||
label: "Text".into(),
|
label: t!("Text").into_owned(),
|
||||||
field: "text",
|
field: "text",
|
||||||
value: crate::scene::model::object::PropValue::EditText(base.text.clone()),
|
value: crate::scene::model::object::PropValue::EditText(base.text.clone()),
|
||||||
},
|
},
|
||||||
crate::scene::model::object::Property {
|
crate::scene::model::object::Property {
|
||||||
label: "User Text".into(),
|
label: t!("User Text").into_owned(),
|
||||||
field: "user_text",
|
field: "user_text",
|
||||||
value: crate::scene::model::object::PropValue::EditText(
|
value: crate::scene::model::object::PropValue::EditText(
|
||||||
base.user_text.clone().unwrap_or_default(),
|
base.user_text.clone().unwrap_or_default(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
crate::scene::model::object::Property {
|
crate::scene::model::object::Property {
|
||||||
label: "Style".into(),
|
label: t!("Style").into_owned(),
|
||||||
field: "style_name",
|
field: "style_name",
|
||||||
value: crate::scene::model::object::PropValue::EditText(base.style_name.clone()),
|
value: crate::scene::model::object::PropValue::EditText(base.style_name.clone()),
|
||||||
},
|
},
|
||||||
edit("Text X", "text_x", base.text_middle_point.x),
|
edit(t!("Text X").as_ref(), "text_x", base.text_middle_point.x),
|
||||||
edit("Text Y", "text_y", base.text_middle_point.y),
|
edit(t!("Text Y").as_ref(), "text_y", base.text_middle_point.y),
|
||||||
edit("Text Z", "text_z", base.text_middle_point.z),
|
edit(t!("Text Z").as_ref(), "text_z", base.text_middle_point.z),
|
||||||
edit(
|
edit(
|
||||||
"Text Rotation (deg)",
|
t!("Text Rotation (deg)").as_ref(),
|
||||||
"text_rotation",
|
"text_rotation",
|
||||||
base.text_rotation.to_degrees(),
|
base.text_rotation.to_degrees(),
|
||||||
),
|
),
|
||||||
edit(
|
edit(
|
||||||
"Horizontal Dir (deg)",
|
t!("Horizontal Dir (deg)").as_ref(),
|
||||||
"horizontal_direction",
|
"horizontal_direction",
|
||||||
base.horizontal_direction.to_degrees(),
|
base.horizontal_direction.to_degrees(),
|
||||||
),
|
),
|
||||||
edit(
|
edit(
|
||||||
"Line Spacing",
|
t!("Line Spacing").as_ref(),
|
||||||
"line_spacing_factor",
|
"line_spacing_factor",
|
||||||
base.line_spacing_factor,
|
base.line_spacing_factor,
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Measurement",
|
t!("Measurement").as_ref(),
|
||||||
"measurement",
|
"measurement",
|
||||||
format!("{:.4}", base.actual_measurement),
|
format!("{:.4}", base.actual_measurement),
|
||||||
),
|
),
|
||||||
|
|
@ -68,7 +69,7 @@ fn properties(dim: &Dimension) -> Vec<PropSection> {
|
||||||
d.definition_point,
|
d.definition_point,
|
||||||
));
|
));
|
||||||
props.push(edit(
|
props.push(edit(
|
||||||
"Ext Rotation (deg)",
|
t!("Ext Rotation (deg)").as_ref(),
|
||||||
"ext_line_rotation",
|
"ext_line_rotation",
|
||||||
d.ext_line_rotation.to_degrees(),
|
d.ext_line_rotation.to_degrees(),
|
||||||
));
|
));
|
||||||
|
|
@ -79,20 +80,20 @@ fn properties(dim: &Dimension) -> Vec<PropSection> {
|
||||||
d.second_point,
|
d.second_point,
|
||||||
d.definition_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(
|
props.push(edit(
|
||||||
"Ext Rotation (deg)",
|
t!("Ext Rotation (deg)").as_ref(),
|
||||||
"ext_line_rotation",
|
"ext_line_rotation",
|
||||||
d.ext_line_rotation.to_degrees(),
|
d.ext_line_rotation.to_degrees(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Dimension::Radius(d) => {
|
Dimension::Radius(d) => {
|
||||||
props.extend(radius_like_props(d.angle_vertex, d.definition_point));
|
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) => {
|
Dimension::Diameter(d) => {
|
||||||
props.extend(radius_like_props(d.angle_vertex, d.definition_point));
|
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) => {
|
Dimension::Angular2Ln(d) => {
|
||||||
props.extend(angular_props(
|
props.extend(angular_props(
|
||||||
|
|
@ -101,9 +102,9 @@ fn properties(dim: &Dimension) -> Vec<PropSection> {
|
||||||
d.second_point,
|
d.second_point,
|
||||||
d.definition_point,
|
d.definition_point,
|
||||||
));
|
));
|
||||||
props.push(edit("Arc X", "dimension_arc_x", d.dimension_arc.x));
|
props.push(edit(t!("Arc X").as_ref(), "dimension_arc_x", d.dimension_arc.x));
|
||||||
props.push(edit("Arc Y", "dimension_arc_y", d.dimension_arc.y));
|
props.push(edit(t!("Arc Y").as_ref(), "dimension_arc_y", d.dimension_arc.y));
|
||||||
props.push(edit("Arc Z", "dimension_arc_z", d.dimension_arc.z));
|
props.push(edit(t!("Arc Z").as_ref(), "dimension_arc_z", d.dimension_arc.z));
|
||||||
}
|
}
|
||||||
Dimension::Angular3Pt(d) => {
|
Dimension::Angular3Pt(d) => {
|
||||||
props.extend(angular_props(
|
props.extend(angular_props(
|
||||||
|
|
@ -114,17 +115,17 @@ fn properties(dim: &Dimension) -> Vec<PropSection> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Dimension::Ordinate(d) => {
|
Dimension::Ordinate(d) => {
|
||||||
props.push(edit("Origin X", "definition_x", d.definition_point.x));
|
props.push(edit(t!("Origin X").as_ref(), "definition_x", d.definition_point.x));
|
||||||
props.push(edit("Origin Y", "definition_y", d.definition_point.y));
|
props.push(edit(t!("Origin Y").as_ref(), "definition_y", d.definition_point.y));
|
||||||
props.push(edit("Origin Z", "definition_z", d.definition_point.z));
|
props.push(edit(t!("Origin Z").as_ref(), "definition_z", d.definition_point.z));
|
||||||
props.push(edit("Feature X", "feature_x", d.feature_location.x));
|
props.push(edit(t!("Feature X").as_ref(), "feature_x", d.feature_location.x));
|
||||||
props.push(edit("Feature Y", "feature_y", d.feature_location.y));
|
props.push(edit(t!("Feature Y").as_ref(), "feature_y", d.feature_location.y));
|
||||||
props.push(edit("Feature Z", "feature_z", d.feature_location.z));
|
props.push(edit(t!("Feature Z").as_ref(), "feature_z", d.feature_location.z));
|
||||||
props.push(edit("Leader X", "leader_x", d.leader_endpoint.x));
|
props.push(edit(t!("Leader X").as_ref(), "leader_x", d.leader_endpoint.x));
|
||||||
props.push(edit("Leader Y", "leader_y", d.leader_endpoint.y));
|
props.push(edit(t!("Leader Y").as_ref(), "leader_y", d.leader_endpoint.y));
|
||||||
props.push(edit("Leader Z", "leader_z", d.leader_endpoint.z));
|
props.push(edit(t!("Leader Z").as_ref(), "leader_z", d.leader_endpoint.z));
|
||||||
props.push(ro(
|
props.push(ro(
|
||||||
"Ordinate Type",
|
t!("Ordinate Type").as_ref(),
|
||||||
"ordinate_type",
|
"ordinate_type",
|
||||||
if d.is_ordinate_type_x { "X" } else { "Y" },
|
if d.is_ordinate_type_x { "X" } else { "Y" },
|
||||||
));
|
));
|
||||||
|
|
@ -137,42 +138,42 @@ fn properties(dim: &Dimension) -> Vec<PropSection> {
|
||||||
d.definition_point,
|
d.definition_point,
|
||||||
));
|
));
|
||||||
props.push(edit(
|
props.push(edit(
|
||||||
"Arc Start (deg)",
|
t!("Arc Start (deg)").as_ref(),
|
||||||
"arc_start_parameter",
|
"arc_start_parameter",
|
||||||
d.arc_start_parameter.to_degrees(),
|
d.arc_start_parameter.to_degrees(),
|
||||||
));
|
));
|
||||||
props.push(edit(
|
props.push(edit(
|
||||||
"Arc End (deg)",
|
t!("Arc End (deg)").as_ref(),
|
||||||
"arc_end_parameter",
|
"arc_end_parameter",
|
||||||
d.arc_end_parameter.to_degrees(),
|
d.arc_end_parameter.to_degrees(),
|
||||||
));
|
));
|
||||||
props.push(ro("Partial", "is_partial", d.is_partial.to_string()));
|
props.push(ro(t!("Partial").as_ref(), "is_partial", d.is_partial.to_string()));
|
||||||
props.push(ro("Has Leader", "has_leader", d.has_leader.to_string()));
|
props.push(ro(t!("Has Leader").as_ref(), "has_leader", d.has_leader.to_string()));
|
||||||
props.push(edit("Leader 1 X", "leader1_x", d.first_leader_point.x));
|
props.push(edit(t!("Leader 1 X").as_ref(), "leader1_x", d.first_leader_point.x));
|
||||||
props.push(edit("Leader 1 Y", "leader1_y", d.first_leader_point.y));
|
props.push(edit(t!("Leader 1 Y").as_ref(), "leader1_y", d.first_leader_point.y));
|
||||||
props.push(edit("Leader 1 Z", "leader1_z", d.first_leader_point.z));
|
props.push(edit(t!("Leader 1 Z").as_ref(), "leader1_z", d.first_leader_point.z));
|
||||||
props.push(edit("Leader 2 X", "leader2_x", d.second_leader_point.x));
|
props.push(edit(t!("Leader 2 X").as_ref(), "leader2_x", d.second_leader_point.x));
|
||||||
props.push(edit("Leader 2 Y", "leader2_y", d.second_leader_point.y));
|
props.push(edit(t!("Leader 2 Y").as_ref(), "leader2_y", d.second_leader_point.y));
|
||||||
props.push(edit("Leader 2 Z", "leader2_z", d.second_leader_point.z));
|
props.push(edit(t!("Leader 2 Z").as_ref(), "leader2_z", d.second_leader_point.z));
|
||||||
}
|
}
|
||||||
Dimension::LargeRadial(d) => {
|
Dimension::LargeRadial(d) => {
|
||||||
props.push(edit("Center X", "definition_x", d.definition_point.x));
|
props.push(edit(t!("Center X").as_ref(), "definition_x", d.definition_point.x));
|
||||||
props.push(edit("Center Y", "definition_y", d.definition_point.y));
|
props.push(edit(t!("Center Y").as_ref(), "definition_y", d.definition_point.y));
|
||||||
props.push(edit("Center Z", "definition_z", d.definition_point.z));
|
props.push(edit(t!("Center Z").as_ref(), "definition_z", d.definition_point.z));
|
||||||
props.push(edit("Chord X", "chord_x", d.chord_point.x));
|
props.push(edit(t!("Chord X").as_ref(), "chord_x", d.chord_point.x));
|
||||||
props.push(edit("Chord Y", "chord_y", d.chord_point.y));
|
props.push(edit(t!("Chord Y").as_ref(), "chord_y", d.chord_point.y));
|
||||||
props.push(edit("Chord Z", "chord_z", d.chord_point.z));
|
props.push(edit(t!("Chord Z").as_ref(), "chord_z", d.chord_point.z));
|
||||||
props.push(edit("Override Center X", "override_x", d.override_center.x));
|
props.push(edit(t!("Override Center X").as_ref(), "override_x", d.override_center.x));
|
||||||
props.push(edit("Override Center Y", "override_y", d.override_center.y));
|
props.push(edit(t!("Override Center Y").as_ref(), "override_y", d.override_center.y));
|
||||||
props.push(edit("Override Center Z", "override_z", d.override_center.z));
|
props.push(edit(t!("Override Center Z").as_ref(), "override_z", d.override_center.z));
|
||||||
props.push(edit("Jog X", "jog_x", d.jog_point.x));
|
props.push(edit(t!("Jog X").as_ref(), "jog_x", d.jog_point.x));
|
||||||
props.push(edit("Jog Y", "jog_y", d.jog_point.y));
|
props.push(edit(t!("Jog Y").as_ref(), "jog_y", d.jog_point.y));
|
||||||
props.push(edit("Jog Z", "jog_z", d.jog_point.z));
|
props.push(edit(t!("Jog Z").as_ref(), "jog_z", d.jog_point.z));
|
||||||
props.push(edit_angle("Jog Angle", "jog_angle", d.jog_angle.to_degrees()));
|
props.push(edit_angle(t!("Jog Angle").as_ref(), "jog_angle", d.jog_angle.to_degrees()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props,
|
props,
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
@ -183,15 +184,15 @@ fn linear_like_props(
|
||||||
definition: acadrust::types::Vector3,
|
definition: acadrust::types::Vector3,
|
||||||
) -> Vec<crate::scene::model::object::Property> {
|
) -> Vec<crate::scene::model::object::Property> {
|
||||||
vec![
|
vec![
|
||||||
edit("First X", "first_x", first.x),
|
edit(t!("First X").as_ref(), "first_x", first.x),
|
||||||
edit("First Y", "first_y", first.y),
|
edit(t!("First Y").as_ref(), "first_y", first.y),
|
||||||
edit("First Z", "first_z", first.z),
|
edit(t!("First Z").as_ref(), "first_z", first.z),
|
||||||
edit("Second X", "second_x", second.x),
|
edit(t!("Second X").as_ref(), "second_x", second.x),
|
||||||
edit("Second Y", "second_y", second.y),
|
edit(t!("Second Y").as_ref(), "second_y", second.y),
|
||||||
edit("Second Z", "second_z", second.z),
|
edit(t!("Second Z").as_ref(), "second_z", second.z),
|
||||||
edit("Definition X", "definition_x", definition.x),
|
edit(t!("Definition X").as_ref(), "definition_x", definition.x),
|
||||||
edit("Definition Y", "definition_y", definition.y),
|
edit(t!("Definition Y").as_ref(), "definition_y", definition.y),
|
||||||
edit("Definition Z", "definition_z", definition.z),
|
edit(t!("Definition Z").as_ref(), "definition_z", definition.z),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,12 +201,12 @@ fn radius_like_props(
|
||||||
point: acadrust::types::Vector3,
|
point: acadrust::types::Vector3,
|
||||||
) -> Vec<crate::scene::model::object::Property> {
|
) -> Vec<crate::scene::model::object::Property> {
|
||||||
vec![
|
vec![
|
||||||
edit("Center X", "center_x", center.x),
|
edit(t!("Center X").as_ref(), "center_x", center.x),
|
||||||
edit("Center Y", "center_y", center.y),
|
edit(t!("Center Y").as_ref(), "center_y", center.y),
|
||||||
edit("Center Z", "center_z", center.z),
|
edit(t!("Center Z").as_ref(), "center_z", center.z),
|
||||||
edit("Point X", "point_x", point.x),
|
edit(t!("Point X").as_ref(), "point_x", point.x),
|
||||||
edit("Point Y", "point_y", point.y),
|
edit(t!("Point Y").as_ref(), "point_y", point.y),
|
||||||
edit("Point Z", "point_z", point.z),
|
edit(t!("Point Z").as_ref(), "point_z", point.z),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,18 +217,18 @@ fn angular_props(
|
||||||
definition: acadrust::types::Vector3,
|
definition: acadrust::types::Vector3,
|
||||||
) -> Vec<crate::scene::model::object::Property> {
|
) -> Vec<crate::scene::model::object::Property> {
|
||||||
vec![
|
vec![
|
||||||
edit("Vertex X", "vertex_x", vertex.x),
|
edit(t!("Vertex X").as_ref(), "vertex_x", vertex.x),
|
||||||
edit("Vertex Y", "vertex_y", vertex.y),
|
edit(t!("Vertex Y").as_ref(), "vertex_y", vertex.y),
|
||||||
edit("Vertex Z", "vertex_z", vertex.z),
|
edit(t!("Vertex Z").as_ref(), "vertex_z", vertex.z),
|
||||||
edit("First X", "first_x", first.x),
|
edit(t!("First X").as_ref(), "first_x", first.x),
|
||||||
edit("First Y", "first_y", first.y),
|
edit(t!("First Y").as_ref(), "first_y", first.y),
|
||||||
edit("First Z", "first_z", first.z),
|
edit(t!("First Z").as_ref(), "first_z", first.z),
|
||||||
edit("Second X", "second_x", second.x),
|
edit(t!("Second X").as_ref(), "second_x", second.x),
|
||||||
edit("Second Y", "second_y", second.y),
|
edit(t!("Second Y").as_ref(), "second_y", second.y),
|
||||||
edit("Second Z", "second_z", second.z),
|
edit(t!("Second Z").as_ref(), "second_z", second.z),
|
||||||
edit("Definition X", "definition_x", definition.x),
|
edit(t!("Definition X").as_ref(), "definition_x", definition.x),
|
||||||
edit("Definition Y", "definition_y", definition.y),
|
edit(t!("Definition Y").as_ref(), "definition_y", definition.y),
|
||||||
edit("Definition Z", "definition_z", definition.z),
|
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![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Lines & Arrows".into(),
|
title: t!("Lines & Arrows").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Arrow size", "dim_arrow_size", f(s.dimasz)),
|
ro(t!("Arrow size").as_ref(), "dim_arrow_size", f(s.dimasz)),
|
||||||
ro("Dim line color", "dim_line_color", s.dimclrd.to_string()),
|
ro(t!("Dim line color").as_ref(), "dim_line_color", s.dimclrd.to_string()),
|
||||||
ro(
|
ro(
|
||||||
"Dim line lineweight",
|
t!("Dim line lineweight").as_ref(),
|
||||||
"dim_line_lineweight",
|
"dim_line_lineweight",
|
||||||
s.dimlwd.to_string(),
|
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(
|
ro(
|
||||||
"Ext line lineweight",
|
t!("Ext line lineweight").as_ref(),
|
||||||
"dim_ext_line_lineweight",
|
"dim_ext_line_lineweight",
|
||||||
s.dimlwe.to_string(),
|
s.dimlwe.to_string(),
|
||||||
),
|
),
|
||||||
ro("Dim line 1", "dim_line_1", onoff(!s.dimsd1)),
|
ro(t!("Dim line 1").as_ref(), "dim_line_1", onoff(!s.dimsd1)),
|
||||||
ro("Dim line 2", "dim_line_2", onoff(!s.dimsd2)),
|
ro(t!("Dim line 2").as_ref(), "dim_line_2", onoff(!s.dimsd2)),
|
||||||
ro("Ext line 1", "dim_ext_line_1", onoff(!s.dimse1)),
|
ro(t!("Ext line 1").as_ref(), "dim_ext_line_1", onoff(!s.dimse1)),
|
||||||
ro("Ext line 2", "dim_ext_line_2", onoff(!s.dimse2)),
|
ro(t!("Ext line 2").as_ref(), "dim_ext_line_2", onoff(!s.dimse2)),
|
||||||
ro("Dim line ext", "dim_line_ext", f(s.dimdle)),
|
ro(t!("Dim line ext").as_ref(), "dim_line_ext", f(s.dimdle)),
|
||||||
ro("Ext line ext", "dim_ext_line_ext", f(s.dimexe)),
|
ro(t!("Ext line ext").as_ref(), "dim_ext_line_ext", f(s.dimexe)),
|
||||||
ro("Ext line offset", "dim_ext_line_offset", f(s.dimexo)),
|
ro(t!("Ext line offset").as_ref(), "dim_ext_line_offset", f(s.dimexo)),
|
||||||
ro("Ext line fixed", "dim_ext_line_fixed", yn(s.dimfxlon)),
|
ro(t!("Ext line fixed").as_ref(), "dim_ext_line_fixed", yn(s.dimfxlon)),
|
||||||
ro(
|
ro(
|
||||||
"Ext line fixed length",
|
t!("Ext line fixed length").as_ref(),
|
||||||
"dim_ext_line_fixed_length",
|
"dim_ext_line_fixed_length",
|
||||||
f(s.dimfxl),
|
f(s.dimfxl),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Text".into(),
|
title: t!("Text").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Fill color", "dim_text_fill_color", s.dimtfillclr.to_string()),
|
ro(t!("Fill color").as_ref(), "dim_text_fill_color", s.dimtfillclr.to_string()),
|
||||||
ro("Text color", "dim_text_color", s.dimclrt.to_string()),
|
ro(t!("Text color").as_ref(), "dim_text_color", s.dimclrt.to_string()),
|
||||||
ro("Text height", "dim_text_height", f(s.dimtxt)),
|
ro(t!("Text height").as_ref(), "dim_text_height", f(s.dimtxt)),
|
||||||
ro("Text offset", "dim_text_offset", f(s.dimgap)),
|
ro(t!("Text offset").as_ref(), "dim_text_offset", f(s.dimgap)),
|
||||||
ro("Text pos vert", "dim_text_pos_vert", s.dimtad.to_string()),
|
ro(t!("Text pos vert").as_ref(), "dim_text_pos_vert", s.dimtad.to_string()),
|
||||||
ro("Text pos hor", "dim_text_pos_hor", s.dimjust.to_string()),
|
ro(t!("Text pos hor").as_ref(), "dim_text_pos_hor", s.dimjust.to_string()),
|
||||||
ro("Text outside align", "dim_text_outside_align", yn(s.dimtoh)),
|
ro(t!("Text outside align").as_ref(), "dim_text_outside_align", yn(s.dimtoh)),
|
||||||
ro("Text inside align", "dim_text_inside_align", yn(s.dimtih)),
|
ro(t!("Text inside align").as_ref(), "dim_text_inside_align", yn(s.dimtih)),
|
||||||
ro("Text style", "dim_text_style", s.dimtxsty.clone()),
|
ro(t!("Text style").as_ref(), "dim_text_style", s.dimtxsty.clone()),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Fit".into(),
|
title: t!("Fit").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Fit", "dim_fit", s.dimatfit.to_string()),
|
ro(t!("Fit").as_ref(), "dim_fit", s.dimatfit.to_string()),
|
||||||
ro("Text inside", "dim_text_inside", yn(s.dimtix)),
|
ro(t!("Text inside").as_ref(), "dim_text_inside", yn(s.dimtix)),
|
||||||
ro("Text movement", "dim_text_movement", s.dimtmove.to_string()),
|
ro(t!("Text movement").as_ref(), "dim_text_movement", s.dimtmove.to_string()),
|
||||||
ro("Dim scale overall", "dim_scale_overall", f(s.dimscale)),
|
ro(t!("Dim scale overall").as_ref(), "dim_scale_overall", f(s.dimscale)),
|
||||||
ro("Dim line forced", "dim_line_forced", yn(s.dimtofl)),
|
ro(t!("Dim line forced").as_ref(), "dim_line_forced", yn(s.dimtofl)),
|
||||||
ro("Dim line inside", "dim_line_inside", yn(s.dimsoxd)),
|
ro(t!("Dim line inside").as_ref(), "dim_line_inside", yn(s.dimsoxd)),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Primary Units".into(),
|
title: t!("Primary Units").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Dim units", "dim_units", s.dimlunit.to_string()),
|
ro(t!("Dim units").as_ref(), "dim_units", s.dimlunit.to_string()),
|
||||||
ro("Precision", "dim_precision", s.dimdec.to_string()),
|
ro(t!("Precision").as_ref(), "dim_precision", s.dimdec.to_string()),
|
||||||
ro("Decimal separator", "dim_decimal_separator", dsep),
|
ro(t!("Decimal separator").as_ref(), "dim_decimal_separator", dsep),
|
||||||
ro("Dim prefix/suffix", "dim_prefix_suffix", s.dimpost.clone()),
|
ro(t!("Dim prefix/suffix").as_ref(), "dim_prefix_suffix", s.dimpost.clone()),
|
||||||
ro("Dim roundoff", "dim_roundoff", f(s.dimrnd)),
|
ro(t!("Dim roundoff").as_ref(), "dim_roundoff", f(s.dimrnd)),
|
||||||
ro(
|
ro(
|
||||||
"Suppress leading zeros",
|
t!("Suppress leading zeros").as_ref(),
|
||||||
"dim_suppress_leading_zeros",
|
"dim_suppress_leading_zeros",
|
||||||
yn(s.dimzin & 4 != 0),
|
yn(s.dimzin & 4 != 0),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Suppress trailing zeros",
|
t!("Suppress trailing zeros").as_ref(),
|
||||||
"dim_suppress_trailing_zeros",
|
"dim_suppress_trailing_zeros",
|
||||||
yn(s.dimzin & 8 != 0),
|
yn(s.dimzin & 8 != 0),
|
||||||
),
|
),
|
||||||
ro("Dim scale linear", "dim_scale_linear", f(s.dimlfac)),
|
ro(t!("Dim scale linear").as_ref(), "dim_scale_linear", f(s.dimlfac)),
|
||||||
ro("Angle format", "dim_angle_format", s.dimaunit.to_string()),
|
ro(t!("Angle format").as_ref(), "dim_angle_format", s.dimaunit.to_string()),
|
||||||
ro("Angle precision", "dim_angle_precision", s.dimadec.to_string()),
|
ro(t!("Angle precision").as_ref(), "dim_angle_precision", s.dimadec.to_string()),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Alternate Units".into(),
|
title: t!("Alternate Units").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Alt enabled", "dim_alt_enabled", yn(s.dimalt)),
|
ro(t!("Alt enabled").as_ref(), "dim_alt_enabled", yn(s.dimalt)),
|
||||||
ro("Alt format", "dim_alt_format", s.dimaltu.to_string()),
|
ro(t!("Alt format").as_ref(), "dim_alt_format", s.dimaltu.to_string()),
|
||||||
ro("Alt precision", "dim_alt_precision", s.dimaltd.to_string()),
|
ro(t!("Alt precision").as_ref(), "dim_alt_precision", s.dimaltd.to_string()),
|
||||||
ro("Alt scale factor", "dim_alt_scale_factor", f(s.dimaltf)),
|
ro(t!("Alt scale factor").as_ref(), "dim_alt_scale_factor", f(s.dimaltf)),
|
||||||
ro("Alt roundoff", "dim_alt_roundoff", f(s.dimaltrnd)),
|
ro(t!("Alt roundoff").as_ref(), "dim_alt_roundoff", f(s.dimaltrnd)),
|
||||||
ro("Alt prefix/suffix", "dim_alt_prefix_suffix", s.dimapost.clone()),
|
ro(t!("Alt prefix/suffix").as_ref(), "dim_alt_prefix_suffix", s.dimapost.clone()),
|
||||||
ro(
|
ro(
|
||||||
"Alt suppress leading zeros",
|
t!("Alt suppress leading zeros").as_ref(),
|
||||||
"dim_alt_suppress_leading_zeros",
|
"dim_alt_suppress_leading_zeros",
|
||||||
yn(s.dimaltz & 4 != 0),
|
yn(s.dimaltz & 4 != 0),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Alt suppress trailing zeros",
|
t!("Alt suppress trailing zeros").as_ref(),
|
||||||
"dim_alt_suppress_trailing_zeros",
|
"dim_alt_suppress_trailing_zeros",
|
||||||
yn(s.dimaltz & 8 != 0),
|
yn(s.dimaltz & 8 != 0),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Tolerances".into(),
|
title: t!("Tolerances").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Tolerance display", "dim_tolerance_display", tol_display),
|
ro(t!("Tolerance display").as_ref(), "dim_tolerance_display", tol_display),
|
||||||
ro("Tolerance limit lower", "dim_tolerance_limit_lower", f(s.dimtm)),
|
ro(t!("Tolerance limit lower").as_ref(), "dim_tolerance_limit_lower", f(s.dimtm)),
|
||||||
ro("Tolerance limit upper", "dim_tolerance_limit_upper", f(s.dimtp)),
|
ro(t!("Tolerance limit upper").as_ref(), "dim_tolerance_limit_upper", f(s.dimtp)),
|
||||||
ro(
|
ro(
|
||||||
"Tolerance precision",
|
t!("Tolerance precision").as_ref(),
|
||||||
"dim_tolerance_precision",
|
"dim_tolerance_precision",
|
||||||
s.dimtdec.to_string(),
|
s.dimtdec.to_string(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Tolerance text height",
|
t!("Tolerance text height").as_ref(),
|
||||||
"dim_tolerance_text_height",
|
"dim_tolerance_text_height",
|
||||||
f(s.dimtfac),
|
f(s.dimtfac),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Tolerance pos vert",
|
t!("Tolerance pos vert").as_ref(),
|
||||||
"dim_tolerance_pos_vert",
|
"dim_tolerance_pos_vert",
|
||||||
s.dimtolj.to_string(),
|
s.dimtolj.to_string(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Tolerance suppress leading zeros",
|
t!("Tolerance suppress leading zeros").as_ref(),
|
||||||
"dim_tolerance_suppress_leading_zeros",
|
"dim_tolerance_suppress_leading_zeros",
|
||||||
yn(s.dimtzin & 4 != 0),
|
yn(s.dimtzin & 4 != 0),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Tolerance suppress trailing zeros",
|
t!("Tolerance suppress trailing zeros").as_ref(),
|
||||||
"dim_tolerance_suppress_trailing_zeros",
|
"dim_tolerance_suppress_trailing_zeros",
|
||||||
yn(s.dimtzin & 8 != 0),
|
yn(s.dimtzin & 8 != 0),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use acadrust::entities::Ellipse;
|
use acadrust::entities::Ellipse;
|
||||||
|
use crate::t;
|
||||||
use truck_modeling::{builder, BSplineCurve, Curve, Edge, KnotVec, Point3, Wire};
|
use truck_modeling::{builder, BSplineCurve, Curve, Edge, KnotVec, Point3, Wire};
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
|
|
@ -194,35 +195,35 @@ fn properties(ell: &Ellipse) -> Vec<PropSection> {
|
||||||
let props = ell.mass_props();
|
let props = ell.mass_props();
|
||||||
|
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Start X", "start_x", format!("{:.4}", start.x)),
|
ro(t!("Start X").as_ref(), "start_x", format!("{:.4}", start.x)),
|
||||||
ro("Start Y", "start_y", format!("{:.4}", start.y)),
|
ro(t!("Start Y").as_ref(), "start_y", format!("{:.4}", start.y)),
|
||||||
ro("Start Z", "start_z", format!("{:.4}", start.z)),
|
ro(t!("Start Z").as_ref(), "start_z", format!("{:.4}", start.z)),
|
||||||
edit("Center X", "center_x", ell.center.x),
|
edit(t!("Center X").as_ref(), "center_x", ell.center.x),
|
||||||
edit("Center Y", "center_y", ell.center.y),
|
edit(t!("Center Y").as_ref(), "center_y", ell.center.y),
|
||||||
edit("Center Z", "center_z", ell.center.z),
|
edit(t!("Center Z").as_ref(), "center_z", ell.center.z),
|
||||||
ro("End X", "end_x", format!("{:.4}", end.x)),
|
ro(t!("End X").as_ref(), "end_x", format!("{:.4}", end.x)),
|
||||||
ro("End Y", "end_y", format!("{:.4}", end.y)),
|
ro(t!("End Y").as_ref(), "end_y", format!("{:.4}", end.y)),
|
||||||
ro("End Z", "end_z", format!("{:.4}", end.z)),
|
ro(t!("End Z").as_ref(), "end_z", format!("{:.4}", end.z)),
|
||||||
edit("Major radius", "major_r", r_major),
|
edit(t!("Major radius").as_ref(), "major_r", r_major),
|
||||||
edit("Minor radius", "minor_r", r_minor),
|
edit(t!("Minor radius").as_ref(), "minor_r", r_minor),
|
||||||
edit("Radius ratio", "ratio", ell.minor_axis_ratio),
|
edit(t!("Radius ratio").as_ref(), "ratio", ell.minor_axis_ratio),
|
||||||
edit("Start angle", "start_angle", start_angle),
|
edit(t!("Start angle").as_ref(), "start_angle", start_angle),
|
||||||
edit("End angle", "end_angle", end_angle),
|
edit(t!("End angle").as_ref(), "end_angle", end_angle),
|
||||||
ro("Major axis vector X", "major_x", format!("{:.4}", major_vec.x)),
|
ro(t!("Major axis vector X").as_ref(), "major_x", format!("{:.4}", major_vec.x)),
|
||||||
ro("Major axis vector Y", "major_y", format!("{:.4}", major_vec.y)),
|
ro(t!("Major axis vector Y").as_ref(), "major_y", format!("{:.4}", major_vec.y)),
|
||||||
ro("Major axis vector Z", "major_z", format!("{:.4}", major_vec.z)),
|
ro(t!("Major axis vector Z").as_ref(), "major_z", format!("{:.4}", major_vec.z)),
|
||||||
ro("Minor axis vector X", "minor_x", format!("{:.4}", minor_vec.x)),
|
ro(t!("Minor axis vector X").as_ref(), "minor_x", format!("{:.4}", minor_vec.x)),
|
||||||
ro("Minor axis vector Y", "minor_y", format!("{:.4}", minor_vec.y)),
|
ro(t!("Minor axis vector Y").as_ref(), "minor_y", format!("{:.4}", minor_vec.y)),
|
||||||
ro("Minor axis vector Z", "minor_z", format!("{:.4}", minor_vec.z)),
|
ro(t!("Minor axis vector Z").as_ref(), "minor_z", format!("{:.4}", minor_vec.z)),
|
||||||
ro("Area", "area", format!("{:.4}", props.area)),
|
ro(t!("Area").as_ref(), "area", format!("{:.4}", props.area)),
|
||||||
ro("Start parameter", "start_param", format!("{:.4}", ell.start_parameter)),
|
ro(t!("Start parameter").as_ref(), "start_param", format!("{:.4}", ell.start_parameter)),
|
||||||
ro("End parameter", "end_param", format!("{:.4}", ell.end_parameter)),
|
ro(t!("End parameter").as_ref(), "end_param", format!("{:.4}", ell.end_parameter)),
|
||||||
ro("Length", "length", format!("{:.4}", props.perimeter)),
|
ro(t!("Length").as_ref(), "length", format!("{:.4}", props.perimeter)),
|
||||||
ro("Normal X", "normal_x", format!("{:.4}", ell.normal.x)),
|
ro(t!("Normal X").as_ref(), "normal_x", format!("{:.4}", ell.normal.x)),
|
||||||
ro("Normal Y", "normal_y", format!("{:.4}", ell.normal.y)),
|
ro(t!("Normal Y").as_ref(), "normal_y", format!("{:.4}", ell.normal.y)),
|
||||||
ro("Normal Z", "normal_z", format!("{:.4}", ell.normal.z)),
|
ro(t!("Normal Z").as_ref(), "normal_z", format!("{:.4}", ell.normal.z)),
|
||||||
],
|
],
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use acadrust::entities::{
|
||||||
PointCloudData, PointCloudExData, RemoteTextData, SectionObjectData,
|
PointCloudData, PointCloudExData, RemoteTextData, SectionObjectData,
|
||||||
};
|
};
|
||||||
use acadrust::types::{Handle, Transform, Vector3};
|
use acadrust::types::{Handle, Transform, Vector3};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::{
|
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 {
|
Property {
|
||||||
label: label.into(),
|
label: label.into(),
|
||||||
field,
|
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 {
|
Property {
|
||||||
label: label.into(),
|
label: label.into(),
|
||||||
field,
|
field,
|
||||||
|
|
@ -481,40 +482,36 @@ fn section_properties(data: &SectionObjectData) -> Vec<PropSection> {
|
||||||
.join("\n");
|
.join("\n");
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Section Object".into(),
|
title: t!("Section Object").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
text_prop("Name", "ext_section_name", &data.name),
|
text_prop(t!("Name").as_ref(), "ext_section_name", &data.name),
|
||||||
ro_prop("State", "ext_section_state", data.state.to_string()),
|
ro_prop(t!("State").as_ref(), "ext_section_state", data.state.to_string()),
|
||||||
ro_prop("Flags", "ext_section_flags", data.flags.to_string()),
|
ro_prop(t!("Flags").as_ref(), "ext_section_flags", data.flags.to_string()),
|
||||||
ro_prop(
|
ro_prop(t!("Vertical Direction").as_ref(),
|
||||||
"Vertical Direction",
|
|
||||||
"ext_section_vertical",
|
"ext_section_vertical",
|
||||||
vector_text(data.vertical_direction),
|
vector_text(data.vertical_direction),
|
||||||
),
|
),
|
||||||
edit_prop("Top Height", "ext_section_top", data.top_height),
|
edit_prop(t!("Top Height").as_ref(), "ext_section_top", data.top_height),
|
||||||
edit_prop("Bottom Height", "ext_section_bottom", data.bottom_height),
|
edit_prop(t!("Bottom Height").as_ref(), "ext_section_bottom", data.bottom_height),
|
||||||
ro_prop(
|
ro_prop(t!("Indicator Alpha").as_ref(),
|
||||||
"Indicator Alpha",
|
|
||||||
"ext_section_alpha",
|
"ext_section_alpha",
|
||||||
data.indicator_alpha.to_string(),
|
data.indicator_alpha.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Indicator Color").as_ref(),
|
||||||
"Indicator Color",
|
|
||||||
"ext_section_color",
|
"ext_section_color",
|
||||||
format!("{:?}", data.indicator_color),
|
format!("{:?}", data.indicator_color),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Settings").as_ref(),
|
||||||
"Settings",
|
|
||||||
"ext_section_settings",
|
"ext_section_settings",
|
||||||
handle_text(data.settings_handle),
|
handle_text(data.settings_handle),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Section Vertices".into(),
|
title: t!("Section Vertices").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop("Cutting Line", "ext_section_vertices", vertices),
|
ro_prop(t!("Cutting Line").as_ref(), "ext_section_vertices", vertices),
|
||||||
ro_prop("Back Line", "ext_section_back_vertices", back_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> {
|
fn arc_text_properties(data: &ArcAlignedTextData) -> Vec<PropSection> {
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Arc-Aligned Text".into(),
|
title: t!("Arc-Aligned Text").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
text_prop("Text", "ext_arc_text", &data.text),
|
text_prop(t!("Text").as_ref(), "ext_arc_text", &data.text),
|
||||||
text_prop("Font", "ext_arc_font", &data.font_name),
|
text_prop(t!("Font").as_ref(), "ext_arc_font", &data.font_name),
|
||||||
text_prop("Big Font", "ext_arc_big_font", &data.big_font_name),
|
text_prop(t!("Big Font").as_ref(), "ext_arc_big_font", &data.big_font_name),
|
||||||
text_prop("Style", "ext_arc_style", &data.style_name),
|
text_prop(t!("Style").as_ref(), "ext_arc_style", &data.style_name),
|
||||||
ro_prop("Center", "ext_arc_center", vector_text(data.center)),
|
ro_prop(t!("Center").as_ref(), "ext_arc_center", vector_text(data.center)),
|
||||||
edit_prop("Radius", "ext_arc_radius", data.radius),
|
edit_prop(t!("Radius").as_ref(), "ext_arc_radius", data.radius),
|
||||||
edit_prop("X Scale", "ext_arc_xscale", data.x_scale),
|
edit_prop(t!("X Scale").as_ref(), "ext_arc_xscale", data.x_scale),
|
||||||
edit_prop("Text Size", "ext_arc_size", data.text_size),
|
edit_prop(t!("Text Size").as_ref(), "ext_arc_size", data.text_size),
|
||||||
edit_prop(
|
edit_prop(t!("Character Spacing").as_ref(),
|
||||||
"Character Spacing",
|
|
||||||
"ext_arc_spacing",
|
"ext_arc_spacing",
|
||||||
data.character_spacing,
|
data.character_spacing,
|
||||||
),
|
),
|
||||||
edit_prop(
|
edit_prop(t!("Offset From Arc").as_ref(),
|
||||||
"Offset From Arc",
|
|
||||||
"ext_arc_offset",
|
"ext_arc_offset",
|
||||||
data.offset_from_arc,
|
data.offset_from_arc,
|
||||||
),
|
),
|
||||||
edit_prop("Right Offset", "ext_arc_right", data.right_offset),
|
edit_prop(t!("Right Offset").as_ref(), "ext_arc_right", data.right_offset),
|
||||||
edit_prop("Left Offset", "ext_arc_left", data.left_offset),
|
edit_prop(t!("Left Offset").as_ref(), "ext_arc_left", data.left_offset),
|
||||||
edit_angle_prop(
|
edit_angle_prop(t!("Start Angle").as_ref(),
|
||||||
"Start Angle",
|
|
||||||
"ext_arc_start",
|
"ext_arc_start",
|
||||||
data.start_angle.to_degrees(),
|
data.start_angle.to_degrees(),
|
||||||
),
|
),
|
||||||
edit_angle_prop("End Angle", "ext_arc_end", data.end_angle.to_degrees()),
|
edit_angle_prop(t!("End Angle").as_ref(), "ext_arc_end", data.end_angle.to_degrees()),
|
||||||
bool_prop("Reverse", "ext_arc_reverse", data.reverse),
|
bool_prop(t!("Reverse").as_ref(), "ext_arc_reverse", data.reverse),
|
||||||
ro_prop(
|
ro_prop(t!("Text Direction").as_ref(),
|
||||||
"Text Direction",
|
|
||||||
"ext_arc_direction",
|
"ext_arc_direction",
|
||||||
data.text_direction.to_string(),
|
data.text_direction.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop("Alignment", "ext_arc_alignment", data.alignment.to_string()),
|
ro_prop(t!("Alignment").as_ref(), "ext_arc_alignment", data.alignment.to_string()),
|
||||||
ro_prop(
|
ro_prop(t!("Text Position").as_ref(),
|
||||||
"Text Position",
|
|
||||||
"ext_arc_position",
|
"ext_arc_position",
|
||||||
data.text_position.to_string(),
|
data.text_position.to_string(),
|
||||||
),
|
),
|
||||||
bool_prop("Bold", "ext_arc_bold", data.bold),
|
bool_prop(t!("Bold").as_ref(), "ext_arc_bold", data.bold),
|
||||||
bool_prop("Italic", "ext_arc_italic", data.italic),
|
bool_prop(t!("Italic").as_ref(), "ext_arc_italic", data.italic),
|
||||||
bool_prop("Underlined", "ext_arc_underlined", data.underlined),
|
bool_prop(t!("Underlined").as_ref(), "ext_arc_underlined", data.underlined),
|
||||||
ro_prop(
|
ro_prop(t!("Character Set").as_ref(),
|
||||||
"Character Set",
|
|
||||||
"ext_arc_charset",
|
"ext_arc_charset",
|
||||||
data.character_set.to_string(),
|
data.character_set.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Pitch And Family").as_ref(),
|
||||||
"Pitch And Family",
|
|
||||||
"ext_arc_pitch",
|
"ext_arc_pitch",
|
||||||
data.pitch_and_family.to_string(),
|
data.pitch_and_family.to_string(),
|
||||||
),
|
),
|
||||||
bool_prop("SHX", "ext_arc_shx", data.is_shx),
|
bool_prop(t!("SHX").as_ref(), "ext_arc_shx", data.is_shx),
|
||||||
ro_prop("Text Color", "ext_arc_color", data.text_color.to_string()),
|
ro_prop(t!("Text Color").as_ref(), "ext_arc_color", data.text_color.to_string()),
|
||||||
ro_prop("Normal", "ext_arc_normal", vector_text(data.normal)),
|
ro_prop(t!("Normal").as_ref(), "ext_arc_normal", vector_text(data.normal)),
|
||||||
bool_prop("Wizard Flag", "ext_arc_wizard", data.wizard_flag),
|
bool_prop(t!("Wizard Flag").as_ref(), "ext_arc_wizard", data.wizard_flag),
|
||||||
ro_prop("Arc", "ext_arc_handle", handle_text(data.arc_handle)),
|
ro_prop(t!("Arc").as_ref(), "ext_arc_handle", handle_text(data.arc_handle)),
|
||||||
],
|
],
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_text_properties(data: &RemoteTextData) -> Vec<PropSection> {
|
fn remote_text_properties(data: &RemoteTextData) -> Vec<PropSection> {
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Remote Text".into(),
|
title: t!("Remote Text").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
text_prop("Text", "ext_rtext_text", &data.text),
|
text_prop(t!("Text").as_ref(), "ext_rtext_text", &data.text),
|
||||||
ro_prop("Position", "ext_rtext_position", vector_text(data.position)),
|
ro_prop(t!("Position").as_ref(), "ext_rtext_position", vector_text(data.position)),
|
||||||
ro_prop("Normal", "ext_rtext_normal", vector_text(data.normal)),
|
ro_prop(t!("Normal").as_ref(), "ext_rtext_normal", vector_text(data.normal)),
|
||||||
edit_angle_prop(
|
edit_angle_prop(t!("Rotation").as_ref(),
|
||||||
"Rotation",
|
|
||||||
"ext_rtext_rotation",
|
"ext_rtext_rotation",
|
||||||
data.rotation.to_degrees(),
|
data.rotation.to_degrees(),
|
||||||
),
|
),
|
||||||
edit_prop("Height", "ext_rtext_height", data.height),
|
edit_prop(t!("Height").as_ref(), "ext_rtext_height", data.height),
|
||||||
text_prop("Style Name", "ext_rtext_style", &data.style_name),
|
text_prop(t!("Style Name").as_ref(), "ext_rtext_style", &data.style_name),
|
||||||
ro_prop(
|
ro_prop(t!("Style Handle").as_ref(),
|
||||||
"Style Handle",
|
|
||||||
"ext_rtext_style_handle",
|
"ext_rtext_style_handle",
|
||||||
handle_text(data.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> {
|
fn geo_marker_properties(data: &GeoPositionMarkerData) -> Vec<PropSection> {
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geographic Position Marker".into(),
|
title: t!("Geographic Position Marker").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop(
|
ro_prop(t!("Class Version").as_ref(),
|
||||||
"Class Version",
|
|
||||||
"ext_geo_version",
|
"ext_geo_version",
|
||||||
data.class_version.to_string(),
|
data.class_version.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop("Position", "ext_geo_position", vector_text(data.position)),
|
ro_prop(t!("Position").as_ref(), "ext_geo_position", vector_text(data.position)),
|
||||||
edit_prop("Radius", "ext_geo_radius", data.radius),
|
edit_prop(t!("Radius").as_ref(), "ext_geo_radius", data.radius),
|
||||||
text_prop("Notes", "ext_geo_notes", &data.notes),
|
text_prop(t!("Notes").as_ref(), "ext_geo_notes", &data.notes),
|
||||||
edit_prop("Landing Gap", "ext_geo_gap", data.landing_gap),
|
edit_prop(t!("Landing Gap").as_ref(), "ext_geo_gap", data.landing_gap),
|
||||||
bool_prop("Text Visible", "ext_geo_visible", data.mtext_visible),
|
bool_prop(t!("Text Visible").as_ref(), "ext_geo_visible", data.mtext_visible),
|
||||||
ro_prop(
|
ro_prop(t!("Text Alignment").as_ref(),
|
||||||
"Text Alignment",
|
|
||||||
"ext_geo_alignment",
|
"ext_geo_alignment",
|
||||||
data.text_alignment.to_string(),
|
data.text_alignment.to_string(),
|
||||||
),
|
),
|
||||||
bool_prop("Frame Text", "ext_geo_frame", data.enable_frame_text),
|
bool_prop(t!("Frame Text").as_ref(), "ext_geo_frame", data.enable_frame_text),
|
||||||
ro_prop(
|
ro_prop(t!("Embedded MText").as_ref(),
|
||||||
"Embedded MText",
|
|
||||||
"ext_geo_mtext",
|
"ext_geo_mtext",
|
||||||
data.embedded_mtext
|
data.embedded_mtext
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -660,91 +645,77 @@ fn point_cloud_properties(data: &PointCloudData) -> Vec<PropSection> {
|
||||||
.join("\n");
|
.join("\n");
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Point Cloud".into(),
|
title: t!("Point Cloud").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop(
|
ro_prop(t!("Class Version").as_ref(),
|
||||||
"Class Version",
|
|
||||||
"ext_pc_version",
|
"ext_pc_version",
|
||||||
data.class_version.to_string(),
|
data.class_version.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop("Origin", "ext_pc_origin", vector_text(data.origin)),
|
ro_prop(t!("Origin").as_ref(), "ext_pc_origin", vector_text(data.origin)),
|
||||||
text_prop("Saved File", "ext_pc_file", &data.saved_filename),
|
text_prop(t!("Saved File").as_ref(), "ext_pc_file", &data.saved_filename),
|
||||||
ro_prop(
|
ro_prop(t!("Source Files").as_ref(),
|
||||||
"Source Files",
|
|
||||||
"ext_pc_sources",
|
"ext_pc_sources",
|
||||||
data.source_files.join("\n"),
|
data.source_files.join("\n"),
|
||||||
),
|
),
|
||||||
ro_prop("Extents Min", "ext_pc_min", vector_text(data.extents_min)),
|
ro_prop(t!("Extents Min").as_ref(), "ext_pc_min", vector_text(data.extents_min)),
|
||||||
ro_prop("Extents Max", "ext_pc_max", vector_text(data.extents_max)),
|
ro_prop(t!("Extents Max").as_ref(), "ext_pc_max", vector_text(data.extents_max)),
|
||||||
ro_prop(
|
ro_prop(t!("Point Count").as_ref(),
|
||||||
"Point Count",
|
|
||||||
"ext_pc_count",
|
"ext_pc_count",
|
||||||
data.point_count.to_string(),
|
data.point_count.to_string(),
|
||||||
),
|
),
|
||||||
text_prop("UCS Name", "ext_pc_ucs", &data.ucs_name),
|
text_prop(t!("UCS Name").as_ref(), "ext_pc_ucs", &data.ucs_name),
|
||||||
ro_prop(
|
ro_prop(t!("UCS Origin").as_ref(),
|
||||||
"UCS Origin",
|
|
||||||
"ext_pc_ucs_origin",
|
"ext_pc_ucs_origin",
|
||||||
vector_text(data.ucs_origin),
|
vector_text(data.ucs_origin),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("UCS X").as_ref(),
|
||||||
"UCS X",
|
|
||||||
"ext_pc_ucs_x",
|
"ext_pc_ucs_x",
|
||||||
vector_text(data.ucs_x_direction),
|
vector_text(data.ucs_x_direction),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("UCS Y").as_ref(),
|
||||||
"UCS Y",
|
|
||||||
"ext_pc_ucs_y",
|
"ext_pc_ucs_y",
|
||||||
vector_text(data.ucs_y_direction),
|
vector_text(data.ucs_y_direction),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("UCS Z").as_ref(),
|
||||||
"UCS Z",
|
|
||||||
"ext_pc_ucs_z",
|
"ext_pc_ucs_z",
|
||||||
vector_text(data.ucs_z_direction),
|
vector_text(data.ucs_z_direction),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Definition").as_ref(),
|
||||||
"Definition",
|
|
||||||
"ext_pc_definition",
|
"ext_pc_definition",
|
||||||
handle_text(data.definition_handle),
|
handle_text(data.definition_handle),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Reactor").as_ref(),
|
||||||
"Reactor",
|
|
||||||
"ext_pc_reactor",
|
"ext_pc_reactor",
|
||||||
handle_text(data.reactor_handle),
|
handle_text(data.reactor_handle),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Point Cloud Display".into(),
|
title: t!("Point Cloud Display").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
bool_prop("Show Intensity", "ext_pc_show_intensity", data.show_intensity),
|
bool_prop(t!("Show Intensity").as_ref(), "ext_pc_show_intensity", data.show_intensity),
|
||||||
ro_prop(
|
ro_prop(t!("Intensity Scheme").as_ref(),
|
||||||
"Intensity Scheme",
|
|
||||||
"ext_pc_intensity_scheme",
|
"ext_pc_intensity_scheme",
|
||||||
data.intensity_scheme.to_string(),
|
data.intensity_scheme.to_string(),
|
||||||
),
|
),
|
||||||
edit_prop(
|
edit_prop(t!("Minimum Intensity").as_ref(),
|
||||||
"Minimum Intensity",
|
|
||||||
"ext_pc_intensity_min",
|
"ext_pc_intensity_min",
|
||||||
data.minimum_intensity,
|
data.minimum_intensity,
|
||||||
),
|
),
|
||||||
edit_prop(
|
edit_prop(t!("Maximum Intensity").as_ref(),
|
||||||
"Maximum Intensity",
|
|
||||||
"ext_pc_intensity_max",
|
"ext_pc_intensity_max",
|
||||||
data.maximum_intensity,
|
data.maximum_intensity,
|
||||||
),
|
),
|
||||||
edit_prop(
|
edit_prop(t!("Low Threshold").as_ref(),
|
||||||
"Low Threshold",
|
|
||||||
"ext_pc_low_threshold",
|
"ext_pc_low_threshold",
|
||||||
data.low_intensity_threshold,
|
data.low_intensity_threshold,
|
||||||
),
|
),
|
||||||
edit_prop(
|
edit_prop(t!("High Threshold").as_ref(),
|
||||||
"High Threshold",
|
|
||||||
"ext_pc_high_threshold",
|
"ext_pc_high_threshold",
|
||||||
data.high_intensity_threshold,
|
data.high_intensity_threshold,
|
||||||
),
|
),
|
||||||
bool_prop("Show Clipping", "ext_pc_show_clipping", data.show_clipping),
|
bool_prop(t!("Show Clipping").as_ref(), "ext_pc_show_clipping", data.show_clipping),
|
||||||
ro_prop("Clippings", "ext_pc_clippings", clips),
|
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");
|
.join("\n");
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Point Cloud Ex".into(),
|
title: t!("Point Cloud Ex").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop(
|
ro_prop(t!("Class Version").as_ref(),
|
||||||
"Class Version",
|
|
||||||
"ext_pcx_version",
|
"ext_pcx_version",
|
||||||
data.class_version.to_string(),
|
data.class_version.to_string(),
|
||||||
),
|
),
|
||||||
text_prop("Name", "ext_pcx_name", &data.name),
|
text_prop(t!("Name").as_ref(), "ext_pcx_name", &data.name),
|
||||||
ro_prop("Extents Min", "ext_pcx_min", vector_text(data.extents_min)),
|
ro_prop(t!("Extents Min").as_ref(), "ext_pcx_min", vector_text(data.extents_min)),
|
||||||
ro_prop("Extents Max", "ext_pcx_max", vector_text(data.extents_max)),
|
ro_prop(t!("Extents Max").as_ref(), "ext_pcx_max", vector_text(data.extents_max)),
|
||||||
ro_prop(
|
ro_prop(t!("UCS Origin").as_ref(),
|
||||||
"UCS Origin",
|
|
||||||
"ext_pcx_ucs_origin",
|
"ext_pcx_ucs_origin",
|
||||||
vector_text(data.ucs_origin),
|
vector_text(data.ucs_origin),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("UCS X").as_ref(),
|
||||||
"UCS X",
|
|
||||||
"ext_pcx_ucs_x",
|
"ext_pcx_ucs_x",
|
||||||
vector_text(data.ucs_x_direction),
|
vector_text(data.ucs_x_direction),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("UCS Y").as_ref(),
|
||||||
"UCS Y",
|
|
||||||
"ext_pcx_ucs_y",
|
"ext_pcx_ucs_y",
|
||||||
vector_text(data.ucs_y_direction),
|
vector_text(data.ucs_y_direction),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("UCS Z").as_ref(),
|
||||||
"UCS Z",
|
|
||||||
"ext_pcx_ucs_z",
|
"ext_pcx_ucs_z",
|
||||||
vector_text(data.ucs_z_direction),
|
vector_text(data.ucs_z_direction),
|
||||||
),
|
),
|
||||||
bool_prop("Locked", "ext_pcx_locked", data.locked),
|
bool_prop(t!("Locked").as_ref(), "ext_pcx_locked", data.locked),
|
||||||
ro_prop(
|
ro_prop(t!("Definition").as_ref(),
|
||||||
"Definition",
|
|
||||||
"ext_pcx_definition",
|
"ext_pcx_definition",
|
||||||
handle_text(data.definition_handle),
|
handle_text(data.definition_handle),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Reactor").as_ref(),
|
||||||
"Reactor",
|
|
||||||
"ext_pcx_reactor",
|
"ext_pcx_reactor",
|
||||||
handle_text(data.reactor_handle),
|
handle_text(data.reactor_handle),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Point Cloud Ex Display".into(),
|
title: t!("Point Cloud Ex Display").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
bool_prop(
|
bool_prop(t!("Show Intensity").as_ref(),
|
||||||
"Show Intensity",
|
|
||||||
"ext_pcx_show_intensity",
|
"ext_pcx_show_intensity",
|
||||||
data.show_intensity,
|
data.show_intensity,
|
||||||
),
|
),
|
||||||
bool_prop("Show Cropping", "ext_pcx_show_cropping", data.show_cropping),
|
bool_prop(t!("Show Cropping").as_ref(), "ext_pcx_show_cropping", data.show_cropping),
|
||||||
ro_prop(
|
ro_prop(t!("Unknown Flags").as_ref(),
|
||||||
"Unknown Flags",
|
|
||||||
"ext_pcx_unknown",
|
"ext_pcx_unknown",
|
||||||
format!("{}, {}", data.unknown_bl0, data.unknown_bl1),
|
format!("{}, {}", data.unknown_bl0, data.unknown_bl1),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Stylization Type").as_ref(),
|
||||||
"Stylization Type",
|
|
||||||
"ext_pcx_stylization",
|
"ext_pcx_stylization",
|
||||||
data.stylization_type.to_string(),
|
data.stylization_type.to_string(),
|
||||||
),
|
),
|
||||||
text_prop(
|
text_prop(t!("Intensity Color Scheme").as_ref(),
|
||||||
"Intensity Color Scheme",
|
|
||||||
"ext_pcx_intensity_scheme",
|
"ext_pcx_intensity_scheme",
|
||||||
&data.intensity_color_scheme,
|
&data.intensity_color_scheme,
|
||||||
),
|
),
|
||||||
text_prop(
|
text_prop(t!("Current Color Scheme").as_ref(),
|
||||||
"Current Color Scheme",
|
|
||||||
"ext_pcx_current_scheme",
|
"ext_pcx_current_scheme",
|
||||||
&data.current_color_scheme,
|
&data.current_color_scheme,
|
||||||
),
|
),
|
||||||
text_prop(
|
text_prop(t!("Classification Scheme").as_ref(),
|
||||||
"Classification Scheme",
|
|
||||||
"ext_pcx_class_scheme",
|
"ext_pcx_class_scheme",
|
||||||
&data.classification_color_scheme,
|
&data.classification_color_scheme,
|
||||||
),
|
),
|
||||||
edit_prop("Elevation Min", "ext_pcx_elevation_min", data.elevation_min),
|
edit_prop(t!("Elevation Min").as_ref(), "ext_pcx_elevation_min", data.elevation_min),
|
||||||
edit_prop("Elevation Max", "ext_pcx_elevation_max", data.elevation_max),
|
edit_prop(t!("Elevation Max").as_ref(), "ext_pcx_elevation_max", data.elevation_max),
|
||||||
ro_prop(
|
ro_prop(t!("Intensity Range").as_ref(),
|
||||||
"Intensity Range",
|
|
||||||
"ext_pcx_intensity_range",
|
"ext_pcx_intensity_range",
|
||||||
format!("{}..{}", data.intensity_min, data.intensity_max),
|
format!("{}..{}", data.intensity_min, data.intensity_max),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Out Of Range Behavior").as_ref(),
|
||||||
"Out Of Range Behavior",
|
|
||||||
"ext_pcx_out_of_range",
|
"ext_pcx_out_of_range",
|
||||||
format!(
|
format!(
|
||||||
"intensity {}; elevation {}",
|
"intensity {}; elevation {}",
|
||||||
|
|
@ -863,22 +819,19 @@ fn point_cloud_ex_properties(data: &PointCloudExData) -> Vec<PropSection> {
|
||||||
data.elevation_out_of_range_behavior
|
data.elevation_out_of_range_behavior
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
bool_prop(
|
bool_prop(t!("Fixed Elevation Range").as_ref(),
|
||||||
"Fixed Elevation Range",
|
|
||||||
"ext_pcx_fixed_range",
|
"ext_pcx_fixed_range",
|
||||||
data.elevation_apply_to_fixed_range,
|
data.elevation_apply_to_fixed_range,
|
||||||
),
|
),
|
||||||
bool_prop(
|
bool_prop(t!("Intensity Gradient").as_ref(),
|
||||||
"Intensity Gradient",
|
|
||||||
"ext_pcx_intensity_gradient",
|
"ext_pcx_intensity_gradient",
|
||||||
data.intensity_as_gradient,
|
data.intensity_as_gradient,
|
||||||
),
|
),
|
||||||
bool_prop(
|
bool_prop(t!("Elevation Gradient").as_ref(),
|
||||||
"Elevation Gradient",
|
|
||||||
"ext_pcx_elevation_gradient",
|
"ext_pcx_elevation_gradient",
|
||||||
data.elevation_as_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> {
|
fn properties(entity: &ExtendedEntity) -> Vec<PropSection> {
|
||||||
match &entity.data {
|
match &entity.data {
|
||||||
ExtendedEntityData::Camera { view_handle } => vec![PropSection {
|
ExtendedEntityData::Camera { view_handle } => vec![PropSection {
|
||||||
title: "Camera".into(),
|
title: t!("Camera").into_owned(),
|
||||||
props: vec![ro_prop("View", "ext_camera_view", handle_text(*view_handle))],
|
props: vec![ro_prop(t!("View").as_ref(), "ext_camera_view", handle_text(*view_handle))],
|
||||||
}],
|
}],
|
||||||
ExtendedEntityData::SectionObject(data) => section_properties(data),
|
ExtendedEntityData::SectionObject(data) => section_properties(data),
|
||||||
ExtendedEntityData::ArcAlignedText(data) => arc_text_properties(data),
|
ExtendedEntityData::ArcAlignedText(data) => arc_text_properties(data),
|
||||||
ExtendedEntityData::RemoteText(data) => remote_text_properties(data),
|
ExtendedEntityData::RemoteText(data) => remote_text_properties(data),
|
||||||
ExtendedEntityData::GeoPositionMarker(data) => geo_marker_properties(data),
|
ExtendedEntityData::GeoPositionMarker(data) => geo_marker_properties(data),
|
||||||
ExtendedEntityData::CoordinationModel(data) => vec![PropSection {
|
ExtendedEntityData::CoordinationModel(data) => vec![PropSection {
|
||||||
title: "Coordination Model".into(),
|
title: t!("Coordination Model").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop("Flags", "ext_coord_flags", data.flags.to_string()),
|
ro_prop(t!("Flags").as_ref(), "ext_coord_flags", data.flags.to_string()),
|
||||||
ro_prop(
|
ro_prop(t!("Definition").as_ref(),
|
||||||
"Definition",
|
|
||||||
"ext_coord_definition",
|
"ext_coord_definition",
|
||||||
handle_text(data.definition_handle),
|
handle_text(data.definition_handle),
|
||||||
),
|
),
|
||||||
edit_prop("Unit Factor", "ext_coord_unit", data.unit_factor),
|
edit_prop(t!("Unit Factor").as_ref(), "ext_coord_unit", data.unit_factor),
|
||||||
ro_prop(
|
ro_prop(t!("Transform").as_ref(),
|
||||||
"Transform",
|
|
||||||
"ext_coord_transform",
|
"ext_coord_transform",
|
||||||
data.transform
|
data.transform
|
||||||
.chunks_exact(4)
|
.chunks_exact(4)
|
||||||
|
|
@ -954,68 +905,60 @@ fn properties(entity: &ExtendedEntity) -> Vec<PropSection> {
|
||||||
ExtendedEntityData::PointCloud(data) => point_cloud_properties(data),
|
ExtendedEntityData::PointCloud(data) => point_cloud_properties(data),
|
||||||
ExtendedEntityData::PointCloudEx(data) => point_cloud_ex_properties(data),
|
ExtendedEntityData::PointCloudEx(data) => point_cloud_ex_properties(data),
|
||||||
ExtendedEntityData::Proxy(data) => vec![PropSection {
|
ExtendedEntityData::Proxy(data) => vec![PropSection {
|
||||||
title: "Proxy Entity".into(),
|
title: t!("Proxy Entity").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop("Proxy ID", "ext_proxy_id", data.proxy_id.to_string()),
|
ro_prop(t!("Proxy ID").as_ref(), "ext_proxy_id", data.proxy_id.to_string()),
|
||||||
ro_prop("Class ID", "ext_proxy_class", data.class_id.to_string()),
|
ro_prop(t!("Class ID").as_ref(), "ext_proxy_class", data.class_id.to_string()),
|
||||||
ro_prop("DXF Subclass", "ext_proxy_subclass", data.dxf_subclass.clone()),
|
ro_prop(t!("DXF Subclass").as_ref(), "ext_proxy_subclass", data.dxf_subclass.clone()),
|
||||||
ro_prop("Version", "ext_proxy_version", data.version.to_string()),
|
ro_prop(t!("Version").as_ref(), "ext_proxy_version", data.version.to_string()),
|
||||||
ro_prop(
|
ro_prop(t!("DWG Version").as_ref(),
|
||||||
"DWG Version",
|
|
||||||
"ext_proxy_dwg_version",
|
"ext_proxy_dwg_version",
|
||||||
format!("{}.{}", data.dwg_version, data.maintenance_version),
|
format!("{}.{}", data.dwg_version, data.maintenance_version),
|
||||||
),
|
),
|
||||||
ro_prop("From DXF", "ext_proxy_from_dxf", data.from_dxf.to_string()),
|
ro_prop(t!("From DXF").as_ref(), "ext_proxy_from_dxf", data.from_dxf.to_string()),
|
||||||
ro_prop(
|
ro_prop(t!("Graphics").as_ref(),
|
||||||
"Graphics",
|
|
||||||
"ext_proxy_graphics",
|
"ext_proxy_graphics",
|
||||||
format!("{} bits", data.graphics.bit_count),
|
format!("{} bits", data.graphics.bit_count),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Payload").as_ref(),
|
||||||
"Payload",
|
|
||||||
"ext_proxy_payload",
|
"ext_proxy_payload",
|
||||||
format!("{} bits", data.payload.bit_count),
|
format!("{} bits", data.payload.bit_count),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Text Payload").as_ref(),
|
||||||
"Text Payload",
|
|
||||||
"ext_proxy_text_payload",
|
"ext_proxy_text_payload",
|
||||||
format!("{} bits", data.text_payload.bit_count),
|
format!("{} bits", data.text_payload.bit_count),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Object References").as_ref(),
|
||||||
"Object References",
|
|
||||||
"ext_proxy_references",
|
"ext_proxy_references",
|
||||||
reference_properties(&data.object_ids),
|
reference_properties(&data.object_ids),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
ExtendedEntityData::OleFrame(data) => vec![PropSection {
|
ExtendedEntityData::OleFrame(data) => vec![PropSection {
|
||||||
title: "OLE Frame".into(),
|
title: t!("OLE Frame").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop("Flag", "ext_ole_flag", data.flag.to_string()),
|
ro_prop(t!("Flag").as_ref(), "ext_ole_flag", data.flag.to_string()),
|
||||||
ro_prop("Mode", "ext_ole_mode", data.mode.to_string()),
|
ro_prop(t!("Mode").as_ref(), "ext_ole_mode", data.mode.to_string()),
|
||||||
ro_prop(
|
ro_prop(t!("Storage Size").as_ref(),
|
||||||
"Storage Size",
|
|
||||||
"ext_ole_size",
|
"ext_ole_size",
|
||||||
format!("{} bytes", data.storage.encoded_len()),
|
format!("{} bytes", data.storage.encoded_len()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
ExtendedEntityData::LayoutPrintConfig(data) => vec![PropSection {
|
ExtendedEntityData::LayoutPrintConfig(data) => vec![PropSection {
|
||||||
title: "Layout Print Configuration".into(),
|
title: t!("Layout Print Configuration").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop(
|
ro_prop(t!("Class Version").as_ref(),
|
||||||
"Class Version",
|
|
||||||
"ext_print_version",
|
"ext_print_version",
|
||||||
data.class_version.to_string(),
|
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 {
|
ExtendedEntityData::Format(data) => vec![PropSection {
|
||||||
title: "Format".into(),
|
title: t!("Format").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop(
|
ro_prop(t!("DWG Payload").as_ref(),
|
||||||
"DWG Payload",
|
|
||||||
"ext_format_dwg",
|
"ext_format_dwg",
|
||||||
format!(
|
format!(
|
||||||
"{} bytes / {} handle bits",
|
"{} bytes / {} handle bits",
|
||||||
|
|
@ -1023,54 +966,47 @@ fn properties(entity: &ExtendedEntity) -> Vec<PropSection> {
|
||||||
data.raw_dwg_handle_bits
|
data.raw_dwg_handle_bits
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("DWG Version").as_ref(),
|
||||||
"DWG Version",
|
|
||||||
"ext_format_version",
|
"ext_format_version",
|
||||||
format!("{:?}", data.raw_dwg_version),
|
format!("{:?}", data.raw_dwg_version),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("DXF Codes").as_ref(),
|
||||||
"DXF Codes",
|
|
||||||
"ext_format_dxf",
|
"ext_format_dxf",
|
||||||
data.raw_dxf_codes.as_ref().map_or(0, Vec::len).to_string(),
|
data.raw_dxf_codes.as_ref().map_or(0, Vec::len).to_string(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
ExtendedEntityData::Legacy(data) => vec![PropSection {
|
ExtendedEntityData::Legacy(data) => vec![PropSection {
|
||||||
title: "Legacy Entity".into(),
|
title: t!("Legacy Entity").into_owned(),
|
||||||
props: vec![ro_prop("Data", "ext_legacy_data", format!("{data:#?}"))],
|
props: vec![ro_prop(t!("Data").as_ref(), "ext_legacy_data", format!("{data:#?}"))],
|
||||||
}],
|
}],
|
||||||
ExtendedEntityData::DynamicBlock(data) => vec![PropSection {
|
ExtendedEntityData::DynamicBlock(data) => vec![PropSection {
|
||||||
title: "Dynamic Block Entity".into(),
|
title: t!("Dynamic Block Entity").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop(
|
ro_prop(t!("Class").as_ref(),
|
||||||
"Class",
|
|
||||||
"ext_dynamic_class",
|
"ext_dynamic_class",
|
||||||
data.entity_dxf_name().unwrap_or("Helper"),
|
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 {
|
ExtendedEntityData::RegisteredClass(data) => vec![PropSection {
|
||||||
title: "Registered Class Entity".into(),
|
title: t!("Registered Class Entity").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop("DXF Name", "ext_registered_dxf", data.dxf_name.clone()),
|
ro_prop(t!("DXF Name").as_ref(), "ext_registered_dxf", data.dxf_name.clone()),
|
||||||
ro_prop(
|
ro_prop(t!("C++ Class").as_ref(),
|
||||||
"C++ Class",
|
|
||||||
"ext_registered_cpp",
|
"ext_registered_cpp",
|
||||||
data.cpp_class_name.clone(),
|
data.cpp_class_name.clone(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Properties").as_ref(),
|
||||||
"Properties",
|
|
||||||
"ext_registered_properties",
|
"ext_registered_properties",
|
||||||
semantic_properties(&data.properties),
|
semantic_properties(&data.properties),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Payload").as_ref(),
|
||||||
"Payload",
|
|
||||||
"ext_registered_payload",
|
"ext_registered_payload",
|
||||||
format!("{} bits", data.payload.bit_count),
|
format!("{} bits", data.payload.bit_count),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Object References").as_ref(),
|
||||||
"Object References",
|
|
||||||
"ext_registered_references",
|
"ext_registered_references",
|
||||||
reference_properties(&data.object_ids),
|
reference_properties(&data.object_ids),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use acadrust::entities::{BoundaryEdge, Hatch};
|
use acadrust::entities::{BoundaryEdge, Hatch};
|
||||||
use glam::Vec3;
|
use glam::Vec3;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
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};
|
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 centered = if g.shift.abs() < 1e-9 { "Yes" } else { "No" };
|
||||||
let mut sections = vec![
|
let mut sections = vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Pattern".into(),
|
title: t!("Pattern").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Type".into(),
|
label: t!("Type").into_owned(),
|
||||||
field: "fill_type",
|
field: "fill_type",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: grad_type.to_string(),
|
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);
|
crate::scene::model::hatch_model::GradientKind::from_name(&g.name);
|
||||||
let _ = invert;
|
let _ = invert;
|
||||||
Property {
|
Property {
|
||||||
label: "Gradient type".into(),
|
label: t!("Gradient type").into_owned(),
|
||||||
field: "gradient_type",
|
field: "gradient_type",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: kind.label().to_string(),
|
selected: kind.label().to_string(),
|
||||||
|
|
@ -291,7 +292,7 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Invert".into(),
|
label: t!("Invert").into_owned(),
|
||||||
field: "gradient_invert",
|
field: "gradient_invert",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "gradient_invert",
|
field: "gradient_invert",
|
||||||
|
|
@ -302,39 +303,38 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Color 1".into(),
|
label: t!("Color 1").into_owned(),
|
||||||
field: "gradient_color_1",
|
field: "gradient_color_1",
|
||||||
value: PropValue::ColorChoice(grad_c1),
|
value: PropValue::ColorChoice(grad_c1),
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Color 2".into(),
|
label: t!("Color 2").into_owned(),
|
||||||
field: "gradient_color_2",
|
field: "gradient_color_2",
|
||||||
value: PropValue::ColorChoice(grad_c2),
|
value: PropValue::ColorChoice(grad_c2),
|
||||||
},
|
},
|
||||||
edit_angle("Angle", "pattern_angle", g.angle.to_degrees()),
|
edit_angle(t!("Angle").as_ref(), "pattern_angle", g.angle.to_degrees()),
|
||||||
ro("Centered", "gradient_centered", centered),
|
ro(t!("Centered").as_ref(), "gradient_centered", centered),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Elevation", "elevation", h.elevation),
|
edit(t!("Elevation").as_ref(), "elevation", h.elevation),
|
||||||
ro("Area", "area", format!("{:.4}", area)),
|
ro(t!("Area").as_ref(), "area", format!("{:.4}", area)),
|
||||||
ro("Cumulative area", "cumulative_area", format!("{:.4}", area)),
|
ro(t!("Cumulative area").as_ref(), "cumulative_area", format!("{:.4}", area)),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro(
|
ro(t!("Associative").as_ref(),
|
||||||
"Associative",
|
|
||||||
"associative",
|
"associative",
|
||||||
if h.is_associative { "Yes" } else { "No" },
|
if h.is_associative { "Yes" } else { "No" },
|
||||||
),
|
),
|
||||||
ro("Annotative", "annotative", String::new()),
|
ro(t!("Annotative").as_ref(), "annotative", String::new()),
|
||||||
ro("Island detection style", "style", style),
|
ro(t!("Island detection style").as_ref(), "style", style),
|
||||||
Property {
|
Property {
|
||||||
label: "Background".into(),
|
label: t!("Background").into_owned(),
|
||||||
field: "bg_enabled",
|
field: "bg_enabled",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "bg_enabled",
|
field: "bg_enabled",
|
||||||
|
|
@ -347,7 +347,7 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
||||||
if bg_on {
|
if bg_on {
|
||||||
if let Some(sec) = sections.last_mut() {
|
if let Some(sec) = sections.last_mut() {
|
||||||
sec.props.push(Property {
|
sec.props.push(Property {
|
||||||
label: "Background color".into(),
|
label: t!("Background color").into_owned(),
|
||||||
field: "background_color",
|
field: "background_color",
|
||||||
value: PropValue::ColorChoice(bg_col),
|
value: PropValue::ColorChoice(bg_col),
|
||||||
});
|
});
|
||||||
|
|
@ -360,7 +360,7 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
||||||
// ── Hatch (pattern / solid) ────────────────────────────────────────────
|
// ── Hatch (pattern / solid) ────────────────────────────────────────────
|
||||||
// "Type" = pattern definition source (Predefined / User Defined / Custom).
|
// "Type" = pattern definition source (Predefined / User Defined / Custom).
|
||||||
let type_row = Property {
|
let type_row = Property {
|
||||||
label: "Type".into(),
|
label: t!("Type").into_owned(),
|
||||||
field: "pattern_type_label",
|
field: "pattern_type_label",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: pattern_type.to_string(),
|
selected: pattern_type.to_string(),
|
||||||
|
|
@ -368,12 +368,12 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let pattern_name_row = Property {
|
let pattern_name_row = Property {
|
||||||
label: "Pattern name".into(),
|
label: t!("Pattern name").into_owned(),
|
||||||
field: "pattern_name",
|
field: "pattern_name",
|
||||||
value: PropValue::HatchPatternChoice(h.pattern.name.clone()),
|
value: PropValue::HatchPatternChoice(h.pattern.name.clone()),
|
||||||
};
|
};
|
||||||
let associative_row = Property {
|
let associative_row = Property {
|
||||||
label: "Associative".into(),
|
label: t!("Associative").into_owned(),
|
||||||
field: "associative",
|
field: "associative",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "associative",
|
field: "associative",
|
||||||
|
|
@ -381,7 +381,7 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let double_row = Property {
|
let double_row = Property {
|
||||||
label: "Double".into(),
|
label: t!("Double").into_owned(),
|
||||||
field: "double",
|
field: "double",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "double",
|
field: "double",
|
||||||
|
|
@ -389,15 +389,14 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let island_row = Property {
|
let island_row = Property {
|
||||||
label: "Island detection style".into(),
|
label: t!("Island detection style").into_owned(),
|
||||||
field: "style",
|
field: "style",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: style.to_string(),
|
selected: style.to_string(),
|
||||||
options: vec!["Normal".into(), "Outer".into(), "Ignore".into()],
|
options: vec!["Normal".into(), "Outer".into(), "Ignore".into()],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let spacing_row = edit(
|
let spacing_row = edit(t!("Spacing").as_ref(),
|
||||||
"Spacing",
|
|
||||||
"spacing",
|
"spacing",
|
||||||
h.pattern
|
h.pattern
|
||||||
.lines
|
.lines
|
||||||
|
|
@ -415,22 +414,22 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
||||||
|
|
||||||
let mut sections = vec![
|
let mut sections = vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Pattern".into(),
|
title: t!("Pattern").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
type_row,
|
type_row,
|
||||||
pattern_name_row,
|
pattern_name_row,
|
||||||
ro("Annotative", "annotative", String::new()),
|
ro(t!("Annotative").as_ref(), "annotative", String::new()),
|
||||||
edit_angle("Angle", "pattern_angle", h.pattern_angle.to_degrees()),
|
edit_angle(t!("Angle").as_ref(), "pattern_angle", h.pattern_angle.to_degrees()),
|
||||||
edit("Scale", "pattern_scale", h.pattern_scale),
|
edit(t!("Scale").as_ref(), "pattern_scale", h.pattern_scale),
|
||||||
edit("Origin X", "origin_x", origin_x),
|
edit(t!("Origin X").as_ref(), "origin_x", origin_x),
|
||||||
edit("Origin Y", "origin_y", origin_y),
|
edit(t!("Origin Y").as_ref(), "origin_y", origin_y),
|
||||||
spacing_row,
|
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,
|
double_row,
|
||||||
associative_row,
|
associative_row,
|
||||||
island_row,
|
island_row,
|
||||||
Property {
|
Property {
|
||||||
label: "Background".into(),
|
label: t!("Background").into_owned(),
|
||||||
field: "bg_enabled",
|
field: "bg_enabled",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "bg_enabled",
|
field: "bg_enabled",
|
||||||
|
|
@ -440,18 +439,18 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Elevation", "elevation", h.elevation),
|
edit(t!("Elevation").as_ref(), "elevation", h.elevation),
|
||||||
ro("Area", "area", format!("{:.4}", area)),
|
ro(t!("Area").as_ref(), "area", format!("{:.4}", area)),
|
||||||
ro("Cumulative area", "cumulative_area", format!("{:.4}", area)),
|
ro(t!("Cumulative area").as_ref(), "cumulative_area", format!("{:.4}", area)),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
if bg_on {
|
if bg_on {
|
||||||
if let Some(sec) = sections.first_mut() {
|
if let Some(sec) = sections.first_mut() {
|
||||||
sec.props.push(Property {
|
sec.props.push(Property {
|
||||||
label: "Background color".into(),
|
label: t!("Background color").into_owned(),
|
||||||
field: "background_color",
|
field: "background_color",
|
||||||
value: PropValue::ColorChoice(bg_col),
|
value: PropValue::ColorChoice(bg_col),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
// as the Geometry property group.
|
// as the Geometry property group.
|
||||||
|
|
||||||
use acadrust::entities::{Helix, HelixConstraint};
|
use acadrust::entities::{Helix, HelixConstraint};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::ro_prop as ro;
|
use crate::entities::common::ro_prop as ro;
|
||||||
|
|
@ -70,20 +71,20 @@ fn properties(helix: &Helix) -> Vec<PropSection> {
|
||||||
};
|
};
|
||||||
|
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Base point X", "base_x", format!("{:.4}", bp.x)),
|
ro(t!("Base point X").as_ref(), "base_x", format!("{:.4}", bp.x)),
|
||||||
ro("Base point Y", "base_y", format!("{:.4}", bp.y)),
|
ro(t!("Base point Y").as_ref(), "base_y", format!("{:.4}", bp.y)),
|
||||||
ro("Base point Z", "base_z", format!("{:.4}", bp.z)),
|
ro(t!("Base point Z").as_ref(), "base_z", format!("{:.4}", bp.z)),
|
||||||
ro("Number of turns", "num_turns", format!("{turns:.4}")),
|
ro(t!("Number of turns").as_ref(), "num_turns", format!("{turns:.4}")),
|
||||||
ro("Turn height", "turn_height", format!("{turn_height:.4}")),
|
ro(t!("Turn height").as_ref(), "turn_height", format!("{turn_height:.4}")),
|
||||||
ro("Turns", "turns", format!("{turns:.4}")),
|
ro(t!("Turns").as_ref(), "turns", format!("{turns:.4}")),
|
||||||
ro("Height", "height", format!("{height:.4}")),
|
ro(t!("Height").as_ref(), "height", format!("{height:.4}")),
|
||||||
ro("Base radius", "base_radius", format!("{base_radius:.4}")),
|
ro(t!("Base radius").as_ref(), "base_radius", format!("{base_radius:.4}")),
|
||||||
ro("Top radius", "top_radius", format!("{top_radius:.4}")),
|
ro(t!("Top radius").as_ref(), "top_radius", format!("{top_radius:.4}")),
|
||||||
ro("Turn slope", "turn_slope", format!("{turn_slope:.4}")),
|
ro(t!("Turn slope").as_ref(), "turn_slope", format!("{turn_slope:.4}")),
|
||||||
ro("Twist", "twist", twist),
|
ro(t!("Twist").as_ref(), "twist", twist),
|
||||||
ro("Constrain", "constrain", constrain),
|
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::convert::acad_to_truck::{TruckEntity, TruckObject};
|
||||||
use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property};
|
use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property};
|
||||||
use crate::scene::model::wire_model::TangentGeom;
|
use crate::scene::model::wire_model::TangentGeom;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
// ── TruckConvertible (used for snap/grip key-vertices) ─────────────────────
|
// ── 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,
|
// Geometry sits right after General — a leader owns editable path vertices,
|
||||||
// navigated one at a time by the Current Vertex spinner.
|
// 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) {
|
if let Some(v) = leader.vertices.get(vi) {
|
||||||
geometry.push(edit("Vertex X", "vertex_x", v.x));
|
geometry.push(edit(t!("Vertex X").as_ref(), "vertex_x", v.x));
|
||||||
geometry.push(edit("Vertex Y", "vertex_y", v.y));
|
geometry.push(edit(t!("Vertex Y").as_ref(), "vertex_y", v.y));
|
||||||
geometry.push(edit("Vertex Z", "vertex_z", v.z));
|
geometry.push(edit(t!("Vertex Z").as_ref(), "vertex_z", v.z));
|
||||||
} else {
|
} else {
|
||||||
geometry.push(ro("Vertex X", "vertex_x", String::new()));
|
geometry.push(ro(t!("Vertex X").as_ref(), "vertex_x", String::new()));
|
||||||
geometry.push(ro("Vertex Y", "vertex_y", String::new()));
|
geometry.push(ro(t!("Vertex Y").as_ref(), "vertex_y", String::new()));
|
||||||
geometry.push(ro("Vertex Z", "vertex_z", 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
|
// Misc: Dim style (upgraded to a dropdown by the panel builder), the
|
||||||
// combined path/arrow Type, and annotative state (from the dim style).
|
// combined path/arrow Type, and annotative state (from the dim style).
|
||||||
let misc = vec![
|
let misc = vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Dim style".into(),
|
label: t!("Dim style").into_owned(),
|
||||||
field: "dimension_style",
|
field: "dimension_style",
|
||||||
value: PropValue::EditText(leader.dimension_style.clone()),
|
value: PropValue::EditText(leader.dimension_style.clone()),
|
||||||
},
|
},
|
||||||
choice_prop(
|
choice_prop(
|
||||||
"Type",
|
t!("Type").as_ref(),
|
||||||
"leader_type",
|
"leader_type",
|
||||||
leader_type_str(&leader.path_type, leader.arrow_enabled),
|
leader_type_str(&leader.path_type, leader.arrow_enabled),
|
||||||
&[
|
&[
|
||||||
|
|
@ -249,42 +250,42 @@ fn properties(leader: &Leader) -> Vec<PropSection> {
|
||||||
"Spline without arrow",
|
"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
|
// Lines & Arrows / Text / Fit are dimension-style-derived; the panel builder
|
||||||
// resolves leader.dimension_style and fills these values from the DimStyle.
|
// resolves leader.dimension_style and fills these values from the DimStyle.
|
||||||
let lines_arrows = vec![
|
let lines_arrows = vec![
|
||||||
ro("Arrow", "arrow_block", "Closed filled"),
|
ro(t!("Arrow").as_ref(), "arrow_block", "Closed filled"),
|
||||||
ro("Arrow size", "arrow_size", String::new()),
|
ro(t!("Arrow size").as_ref(), "arrow_size", String::new()),
|
||||||
ro("Dim line lineweight", "dim_line_lw", "ByLayer"),
|
ro(t!("Dim line lineweight").as_ref(), "dim_line_lw", "ByLayer"),
|
||||||
ro("Dim line color", "dim_line_color", "ByLayer"),
|
ro(t!("Dim line color").as_ref(), "dim_line_color", "ByLayer"),
|
||||||
];
|
];
|
||||||
let text = vec![
|
let text = vec![
|
||||||
ro("Text offset", "text_offset", String::new()),
|
ro(t!("Text offset").as_ref(), "text_offset", String::new()),
|
||||||
ro("Text pos vert", "text_pos_vert", 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![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: geometry,
|
props: geometry,
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: misc,
|
props: misc,
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Lines & Arrows".into(),
|
title: t!("Lines & Arrows").into_owned(),
|
||||||
props: lines_arrows,
|
props: lines_arrows,
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Text".into(),
|
title: t!("Text").into_owned(),
|
||||||
props: text,
|
props: text,
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Fit".into(),
|
title: t!("Fit").into_owned(),
|
||||||
props: fit,
|
props: fit,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
use acadrust::entities::Light;
|
use acadrust::entities::Light;
|
||||||
use acadrust::EntityType;
|
use acadrust::EntityType;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::{
|
use crate::entities::common::{
|
||||||
|
|
@ -262,27 +263,27 @@ impl PropertyEditable for Light {
|
||||||
_ => "Point",
|
_ => "Point",
|
||||||
};
|
};
|
||||||
let mut props = vec![
|
let mut props = vec![
|
||||||
ro_prop("Name", "li_name", self.name.clone()),
|
ro_prop(t!("Name").as_ref(), "li_name", self.name.clone()),
|
||||||
ro_prop("Type", "li_type", kind),
|
ro_prop(t!("Type").as_ref(), "li_type", kind),
|
||||||
edit("Position X", "li_px", self.position.x),
|
edit(t!("Position X").as_ref(), "li_px", self.position.x),
|
||||||
edit("Position Y", "li_py", self.position.y),
|
edit(t!("Position Y").as_ref(), "li_py", self.position.y),
|
||||||
edit("Position Z", "li_pz", self.position.z),
|
edit(t!("Position Z").as_ref(), "li_pz", self.position.z),
|
||||||
];
|
];
|
||||||
if self.light_type != 2 {
|
if self.light_type != 2 {
|
||||||
props.push(edit("Target X", "li_tx", self.target.x));
|
props.push(edit(t!("Target X").as_ref(), "li_tx", self.target.x));
|
||||||
props.push(edit("Target Y", "li_ty", self.target.y));
|
props.push(edit(t!("Target Y").as_ref(), "li_ty", self.target.y));
|
||||||
props.push(edit("Target Z", "li_tz", self.target.z));
|
props.push(edit(t!("Target Z").as_ref(), "li_tz", self.target.z));
|
||||||
}
|
}
|
||||||
let mut sections = vec![
|
let mut sections = vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props,
|
props,
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Light".into(),
|
title: t!("Light").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "On".into(),
|
label: t!("On").into_owned(),
|
||||||
field: "li_status",
|
field: "li_status",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "li_status",
|
field: "li_status",
|
||||||
|
|
@ -290,17 +291,17 @@ impl PropertyEditable for Light {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Plot Glyph".into(),
|
label: t!("Plot Glyph").into_owned(),
|
||||||
field: "li_plot_glyph",
|
field: "li_plot_glyph",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "li_plot_glyph",
|
field: "li_plot_glyph",
|
||||||
value: self.plot_glyph,
|
value: self.plot_glyph,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ro_prop("Color", "li_color", format!("{:?}", self.light_color)),
|
ro_prop(t!("Color").as_ref(), "li_color", format!("{:?}", self.light_color)),
|
||||||
edit("Intensity", "li_intensity", self.intensity),
|
edit(t!("Intensity").as_ref(), "li_intensity", self.intensity),
|
||||||
Property {
|
Property {
|
||||||
label: "Attenuation".into(),
|
label: t!("Attenuation").into_owned(),
|
||||||
field: "li_attenuation",
|
field: "li_attenuation",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: match self.attenuation_type {
|
selected: match self.attenuation_type {
|
||||||
|
|
@ -317,42 +318,39 @@ impl PropertyEditable for Light {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Use Limits".into(),
|
label: t!("Use Limits").into_owned(),
|
||||||
field: "li_use_limits",
|
field: "li_use_limits",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "li_use_limits",
|
field: "li_use_limits",
|
||||||
value: self.use_attenuation_limits,
|
value: self.use_attenuation_limits,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edit("Start Limit", "li_start", self.attenuation_start_limit),
|
edit(t!("Start Limit").as_ref(), "li_start", self.attenuation_start_limit),
|
||||||
edit("End Limit", "li_end", self.attenuation_end_limit),
|
edit(t!("End Limit").as_ref(), "li_end", self.attenuation_end_limit),
|
||||||
edit_angle_prop(
|
edit_angle_prop(t!("Hotspot Angle").as_ref(),
|
||||||
"Hotspot Angle",
|
|
||||||
"li_hotspot",
|
"li_hotspot",
|
||||||
self.hotspot_angle.to_degrees(),
|
self.hotspot_angle.to_degrees(),
|
||||||
),
|
),
|
||||||
edit_angle_prop(
|
edit_angle_prop(t!("Falloff Angle").as_ref(),
|
||||||
"Falloff Angle",
|
|
||||||
"li_falloff",
|
"li_falloff",
|
||||||
self.falloff_angle.to_degrees(),
|
self.falloff_angle.to_degrees(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Shadows".into(),
|
title: t!("Shadows").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Cast Shadows".into(),
|
label: t!("Cast Shadows").into_owned(),
|
||||||
field: "li_shadows",
|
field: "li_shadows",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "li_shadows",
|
field: "li_shadows",
|
||||||
value: self.cast_shadows,
|
value: self.cast_shadows,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ro_prop("Type", "li_shadow_type", self.shadow_type.to_string()),
|
ro_prop(t!("Type").as_ref(), "li_shadow_type", self.shadow_type.to_string()),
|
||||||
ro_prop("Map Size", "li_shadow_size", self.shadow_map_size.to_string()),
|
ro_prop(t!("Map Size").as_ref(), "li_shadow_size", self.shadow_map_size.to_string()),
|
||||||
ro_prop(
|
ro_prop(t!("Softness").as_ref(),
|
||||||
"Softness",
|
|
||||||
"li_shadow_softness",
|
"li_shadow_softness",
|
||||||
self.shadow_map_softness.to_string(),
|
self.shadow_map_softness.to_string(),
|
||||||
),
|
),
|
||||||
|
|
@ -361,36 +359,30 @@ impl PropertyEditable for Light {
|
||||||
];
|
];
|
||||||
if let Some(photo) = &self.photometric_data {
|
if let Some(photo) = &self.photometric_data {
|
||||||
sections.push(PropSection {
|
sections.push(PropSection {
|
||||||
title: "Photometric".into(),
|
title: t!("Photometric").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro_prop("Web File", "li_web_file", photo.web_file.clone()),
|
ro_prop(t!("Web File").as_ref(), "li_web_file", photo.web_file.clone()),
|
||||||
ro_prop(
|
ro_prop(t!("Physical Method").as_ref(),
|
||||||
"Physical Method",
|
|
||||||
"li_physical_method",
|
"li_physical_method",
|
||||||
photo.physical_intensity_method.to_string(),
|
photo.physical_intensity_method.to_string(),
|
||||||
),
|
),
|
||||||
edit(
|
edit(t!("Physical Intensity").as_ref(),
|
||||||
"Physical Intensity",
|
|
||||||
"li_physical_intensity",
|
"li_physical_intensity",
|
||||||
photo.physical_intensity,
|
photo.physical_intensity,
|
||||||
),
|
),
|
||||||
edit(
|
edit(t!("Illuminance Distance").as_ref(),
|
||||||
"Illuminance Distance",
|
|
||||||
"li_illuminance_distance",
|
"li_illuminance_distance",
|
||||||
photo.illuminance_distance,
|
photo.illuminance_distance,
|
||||||
),
|
),
|
||||||
edit(
|
edit(t!("Color Temperature").as_ref(),
|
||||||
"Color Temperature",
|
|
||||||
"li_color_temperature",
|
"li_color_temperature",
|
||||||
photo.lamp_color_temperature,
|
photo.lamp_color_temperature,
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Lamp Preset").as_ref(),
|
||||||
"Lamp Preset",
|
|
||||||
"li_lamp_preset",
|
"li_lamp_preset",
|
||||||
photo.lamp_color_preset.to_string(),
|
photo.lamp_color_preset.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Shape").as_ref(),
|
||||||
"Shape",
|
|
||||||
"li_shape",
|
"li_shape",
|
||||||
format!(
|
format!(
|
||||||
"{} · {:.6} × {:.6} · radius {:.6}",
|
"{} · {:.6} × {:.6} · radius {:.6}",
|
||||||
|
|
@ -400,8 +392,7 @@ impl PropertyEditable for Light {
|
||||||
photo.extended_light_radius
|
photo.extended_light_radius
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Web").as_ref(),
|
||||||
"Web",
|
|
||||||
"li_web",
|
"li_web",
|
||||||
format!(
|
format!(
|
||||||
"type {}; symmetry {}; flux {:.6}; angles {:?}; rotation {:.6},{:.6},{:.6}",
|
"type {}; symmetry {}; flux {:.6}; angles {:?}; rotation {:.6},{:.6},{:.6}",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use acadrust::{entities::Line, Entity};
|
use acadrust::{entities::Line, Entity};
|
||||||
|
use crate::t;
|
||||||
use truck_modeling::{builder, Point3};
|
use truck_modeling::{builder, Point3};
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
|
|
@ -81,19 +82,19 @@ fn properties(line: &Line) -> Vec<PropSection> {
|
||||||
let dz = line.end.z - line.start.z;
|
let dz = line.end.z - line.start.z;
|
||||||
let angle = dy.atan2(dx).to_degrees().rem_euclid(360.0);
|
let angle = dy.atan2(dx).to_degrees().rem_euclid(360.0);
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Start X", "start_x", line.start.x),
|
edit(t!("Start X").as_ref(), "start_x", line.start.x),
|
||||||
edit("Start Y", "start_y", line.start.y),
|
edit(t!("Start Y").as_ref(), "start_y", line.start.y),
|
||||||
edit("Start Z", "start_z", line.start.z),
|
edit(t!("Start Z").as_ref(), "start_z", line.start.z),
|
||||||
edit("End X", "end_x", line.end.x),
|
edit(t!("End X").as_ref(), "end_x", line.end.x),
|
||||||
edit("End Y", "end_y", line.end.y),
|
edit(t!("End Y").as_ref(), "end_y", line.end.y),
|
||||||
edit("End Z", "end_z", line.end.z),
|
edit(t!("End Z").as_ref(), "end_z", line.end.z),
|
||||||
ro("Delta X", "delta_x", format!("{dx:.4}")),
|
ro(t!("Delta X").as_ref(), "delta_x", format!("{dx:.4}")),
|
||||||
ro("Delta Y", "delta_y", format!("{dy:.4}")),
|
ro(t!("Delta Y").as_ref(), "delta_y", format!("{dy:.4}")),
|
||||||
ro("Delta Z", "delta_z", format!("{dz:.4}")),
|
ro(t!("Delta Z").as_ref(), "delta_z", format!("{dz:.4}")),
|
||||||
ro("Length", "length", format!("{:.4}", line.length())),
|
ro(t!("Length").as_ref(), "length", format!("{:.4}", line.length())),
|
||||||
ro("Angle", "angle", format!("{angle:.2}")),
|
ro(t!("Angle").as_ref(), "angle", format!("{angle:.2}")),
|
||||||
],
|
],
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use acadrust::entities::{LwPolyline, LwVertex};
|
use acadrust::entities::{LwPolyline, LwVertex};
|
||||||
|
use crate::t;
|
||||||
use truck_modeling::{builder, Edge, Point3, Wire};
|
use truck_modeling::{builder, Edge, Point3, Wire};
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
|
|
@ -616,24 +617,24 @@ fn properties(pline: &LwPolyline) -> Vec<PropSection> {
|
||||||
};
|
};
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
stepper("Current Vertex", "current_vertex", vertex_label),
|
stepper(t!("Current Vertex").as_ref(), "current_vertex", vertex_label),
|
||||||
edit("Vertex X", "vertex_x", vx),
|
edit(t!("Vertex X").as_ref(), "vertex_x", vx),
|
||||||
edit("Vertex Y", "vertex_y", vy),
|
edit(t!("Vertex Y").as_ref(), "vertex_y", vy),
|
||||||
edit("Start segment width", "start_width", start_w),
|
edit(t!("Start segment width").as_ref(), "start_width", start_w),
|
||||||
edit("End segment width", "end_width", end_w),
|
edit(t!("End segment width").as_ref(), "end_width", end_w),
|
||||||
edit("Global width", "global_width", pline.constant_width),
|
edit(t!("Global width").as_ref(), "global_width", pline.constant_width),
|
||||||
edit("Elevation", "elevation", pline.elevation),
|
edit(t!("Elevation").as_ref(), "elevation", pline.elevation),
|
||||||
ro("Area", "area", format!("{:.4}", mp.area)),
|
ro(t!("Area").as_ref(), "area", format!("{:.4}", mp.area)),
|
||||||
ro("Length", "length", format!("{:.4}", mp.perimeter)),
|
ro(t!("Length").as_ref(), "length", format!("{:.4}", mp.perimeter)),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Closed".into(),
|
label: t!("Closed").into_owned(),
|
||||||
field: "closed",
|
field: "closed",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "closed",
|
field: "closed",
|
||||||
|
|
@ -641,7 +642,7 @@ fn properties(pline: &LwPolyline) -> Vec<PropSection> {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Linetype generation".into(),
|
label: t!("Linetype generation").into_owned(),
|
||||||
field: "plinegen",
|
field: "plinegen",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "plinegen",
|
field: "plinegen",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use acadrust::entities::{mesh::Mesh, polygon_mesh::PolygonMesh, Face3D, PolyfaceMesh};
|
use acadrust::entities::{mesh::Mesh, polygon_mesh::PolygonMesh, Face3D, PolyfaceMesh};
|
||||||
use glam::Vec3;
|
use glam::Vec3;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::{parse_f64, ro_prop as ro, square_grip};
|
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 inv = self.invisible_edges;
|
||||||
let edge = |hidden: bool| if hidden { "Invisible" } else { "Visible" };
|
let edge = |hidden: bool| if hidden { "Invisible" } else { "Visible" };
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Current vertex", "f3_current", String::new()),
|
ro(t!("Current vertex").as_ref(), "f3_current", String::new()),
|
||||||
edit("Vertex 1 X", "f3_p1x", self.first_corner.x),
|
edit(t!("Vertex 1 X").as_ref(), "f3_p1x", self.first_corner.x),
|
||||||
edit("Vertex 1 Y", "f3_p1y", self.first_corner.y),
|
edit(t!("Vertex 1 Y").as_ref(), "f3_p1y", self.first_corner.y),
|
||||||
edit("Vertex 1 Z", "f3_p1z", self.first_corner.z),
|
edit(t!("Vertex 1 Z").as_ref(), "f3_p1z", self.first_corner.z),
|
||||||
edit("Vertex 2 X", "f3_p2x", self.second_corner.x),
|
edit(t!("Vertex 2 X").as_ref(), "f3_p2x", self.second_corner.x),
|
||||||
edit("Vertex 2 Y", "f3_p2y", self.second_corner.y),
|
edit(t!("Vertex 2 Y").as_ref(), "f3_p2y", self.second_corner.y),
|
||||||
edit("Vertex 2 Z", "f3_p2z", self.second_corner.z),
|
edit(t!("Vertex 2 Z").as_ref(), "f3_p2z", self.second_corner.z),
|
||||||
edit("Vertex 3 X", "f3_p3x", self.third_corner.x),
|
edit(t!("Vertex 3 X").as_ref(), "f3_p3x", self.third_corner.x),
|
||||||
edit("Vertex 3 Y", "f3_p3y", self.third_corner.y),
|
edit(t!("Vertex 3 Y").as_ref(), "f3_p3y", self.third_corner.y),
|
||||||
edit("Vertex 3 Z", "f3_p3z", self.third_corner.z),
|
edit(t!("Vertex 3 Z").as_ref(), "f3_p3z", self.third_corner.z),
|
||||||
edit("Vertex 4 X", "f3_p4x", self.fourth_corner.x),
|
edit(t!("Vertex 4 X").as_ref(), "f3_p4x", self.fourth_corner.x),
|
||||||
edit("Vertex 4 Y", "f3_p4y", self.fourth_corner.y),
|
edit(t!("Vertex 4 Y").as_ref(), "f3_p4y", self.fourth_corner.y),
|
||||||
edit("Vertex 4 Z", "f3_p4z", self.fourth_corner.z),
|
edit(t!("Vertex 4 Z").as_ref(), "f3_p4z", self.fourth_corner.z),
|
||||||
ro("Edge 1", "f3_edge1", edge(inv.is_first_invisible())),
|
ro(t!("Edge 1").as_ref(), "f3_edge1", edge(inv.is_first_invisible())),
|
||||||
ro("Edge 2", "f3_edge2", edge(inv.is_second_invisible())),
|
ro(t!("Edge 2").as_ref(), "f3_edge2", edge(inv.is_second_invisible())),
|
||||||
ro("Edge 3", "f3_edge3", edge(inv.is_third_invisible())),
|
ro(t!("Edge 3").as_ref(), "f3_edge3", edge(inv.is_third_invisible())),
|
||||||
ro("Edge 4", "f3_edge4", edge(inv.is_fourth_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;
|
let face_count = cells_m * cells_n;
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Vertex", "pm_vertex", String::new()),
|
ro(t!("Vertex").as_ref(), "pm_vertex", String::new()),
|
||||||
ro(
|
ro(t!("Vertex X").as_ref(),
|
||||||
"Vertex X",
|
|
||||||
"pm_vx",
|
"pm_vx",
|
||||||
first.map(|v| format!("{:.4}", v.location.x)).unwrap_or_default(),
|
first.map(|v| format!("{:.4}", v.location.x)).unwrap_or_default(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Vertex Y").as_ref(),
|
||||||
"Vertex Y",
|
|
||||||
"pm_vy",
|
"pm_vy",
|
||||||
first.map(|v| format!("{:.4}", v.location.y)).unwrap_or_default(),
|
first.map(|v| format!("{:.4}", v.location.y)).unwrap_or_default(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Vertex Z").as_ref(),
|
||||||
"Vertex Z",
|
|
||||||
"pm_vz",
|
"pm_vz",
|
||||||
first.map(|v| format!("{:.4}", v.location.z)).unwrap_or_default(),
|
first.map(|v| format!("{:.4}", v.location.z)).unwrap_or_default(),
|
||||||
),
|
),
|
||||||
ro("M vertex count", "pm_m", self.m_vertex_count.to_string()),
|
ro(t!("M vertex count").as_ref(), "pm_m", self.m_vertex_count.to_string()),
|
||||||
ro("N vertex count", "pm_n", self.n_vertex_count.to_string()),
|
ro(t!("N vertex count").as_ref(), "pm_n", self.n_vertex_count.to_string()),
|
||||||
ro("M closed", "pm_closed_m", yesno(self.is_closed_m())),
|
ro(t!("M closed").as_ref(), "pm_closed_m", yesno(self.is_closed_m())),
|
||||||
ro("N closed", "pm_closed_n", yesno(self.is_closed_n())),
|
ro(t!("N closed").as_ref(), "pm_closed_n", yesno(self.is_closed_n())),
|
||||||
ro("M density", "pm_smooth_m", self.m_smooth_density.to_string()),
|
ro(t!("M density").as_ref(), "pm_smooth_m", self.m_smooth_density.to_string()),
|
||||||
ro("N density", "pm_smooth_n", self.n_smooth_density.to_string()),
|
ro(t!("N density").as_ref(), "pm_smooth_n", self.n_smooth_density.to_string()),
|
||||||
ro("Vertex count", "pm_v", self.vertices.len().to_string()),
|
ro(t!("Vertex count").as_ref(), "pm_v", self.vertices.len().to_string()),
|
||||||
ro("Face count", "pm_faces", face_count.to_string()),
|
ro(t!("Face count").as_ref(), "pm_faces", face_count.to_string()),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![ro("Fit/smooth", "pm_smooth", smooth)],
|
props: vec![ro(t!("Fit/smooth").as_ref(), "pm_smooth", smooth)],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -495,39 +493,36 @@ impl PropertyEditable for PolyfaceMesh {
|
||||||
let first = self.vertices.first();
|
let first = self.vertices.first();
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Vertex", "pfm_vertex", String::new()),
|
ro(t!("Vertex").as_ref(), "pfm_vertex", String::new()),
|
||||||
ro(
|
ro(t!("Vertex X").as_ref(),
|
||||||
"Vertex X",
|
|
||||||
"pfm_vx",
|
"pfm_vx",
|
||||||
first.map(|v| format!("{:.4}", v.location.x)).unwrap_or_default(),
|
first.map(|v| format!("{:.4}", v.location.x)).unwrap_or_default(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Vertex Y").as_ref(),
|
||||||
"Vertex Y",
|
|
||||||
"pfm_vy",
|
"pfm_vy",
|
||||||
first.map(|v| format!("{:.4}", v.location.y)).unwrap_or_default(),
|
first.map(|v| format!("{:.4}", v.location.y)).unwrap_or_default(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Vertex Z").as_ref(),
|
||||||
"Vertex Z",
|
|
||||||
"pfm_vz",
|
"pfm_vz",
|
||||||
first.map(|v| format!("{:.4}", v.location.z)).unwrap_or_default(),
|
first.map(|v| format!("{:.4}", v.location.z)).unwrap_or_default(),
|
||||||
),
|
),
|
||||||
// Polyface meshes store an explicit vertex/face list rather
|
// Polyface meshes store an explicit vertex/face list rather
|
||||||
// than an M×N grid, so the grid-only rows are not applicable.
|
// than an M×N grid, so the grid-only rows are not applicable.
|
||||||
ro("M vertex count", "pfm_m", String::new()),
|
ro(t!("M vertex count").as_ref(), "pfm_m", String::new()),
|
||||||
ro("N vertex count", "pfm_n", String::new()),
|
ro(t!("N vertex count").as_ref(), "pfm_n", String::new()),
|
||||||
ro("M closed", "pfm_closed_m", String::new()),
|
ro(t!("M closed").as_ref(), "pfm_closed_m", String::new()),
|
||||||
ro("N closed", "pfm_closed_n", String::new()),
|
ro(t!("N closed").as_ref(), "pfm_closed_n", String::new()),
|
||||||
ro("M density", "pfm_density_m", String::new()),
|
ro(t!("M density").as_ref(), "pfm_density_m", String::new()),
|
||||||
ro("N density", "pfm_density_n", String::new()),
|
ro(t!("N density").as_ref(), "pfm_density_n", String::new()),
|
||||||
ro("Vertex count", "pfm_v", self.vertices.len().to_string()),
|
ro(t!("Vertex count").as_ref(), "pfm_v", self.vertices.len().to_string()),
|
||||||
ro("Face count", "pfm_f", self.faces.len().to_string()),
|
ro(t!("Face count").as_ref(), "pfm_f", self.faces.len().to_string()),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![ro("Fit/smooth", "pfm_smooth", smooth)],
|
props: vec![ro(t!("Fit/smooth").as_ref(), "pfm_smooth", smooth)],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -1149,26 +1144,25 @@ impl PropertyEditable for Mesh {
|
||||||
let watertight =
|
let watertight =
|
||||||
!self.faces.is_empty() && edge_use.values().all(|&c| c == 2);
|
!self.faces.is_empty() && edge_use.values().all(|&c| c == 2);
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Level of Smoothness".into(),
|
label: t!("Level of Smoothness").into_owned(),
|
||||||
field: "msh_subdiv_edit",
|
field: "msh_subdiv_edit",
|
||||||
value: PropValue::EditText(self.subdivision_level.to_string()),
|
value: PropValue::EditText(self.subdivision_level.to_string()),
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Blend Creases".into(),
|
label: t!("Blend Creases").into_owned(),
|
||||||
field: "msh_blend_crease",
|
field: "msh_blend_crease",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "msh_blend_crease",
|
field: "msh_blend_crease",
|
||||||
value: self.blend_crease,
|
value: self.blend_crease,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ro("Number of Faces", "msh_f", self.faces.len().to_string()),
|
ro(t!("Number of Faces").as_ref(), "msh_f", self.faces.len().to_string()),
|
||||||
ro("Number of Vertices", "msh_v", self.vertices.len().to_string()),
|
ro(t!("Number of Vertices").as_ref(), "msh_v", self.vertices.len().to_string()),
|
||||||
ro("Number of Edges", "msh_e", self.edges.len().to_string()),
|
ro(t!("Number of Edges").as_ref(), "msh_e", self.edges.len().to_string()),
|
||||||
ro(
|
ro(t!("Creased Edges").as_ref(),
|
||||||
"Creased Edges",
|
|
||||||
"msh_creased",
|
"msh_creased",
|
||||||
self.edges
|
self.edges
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -1176,14 +1170,12 @@ impl PropertyEditable for Mesh {
|
||||||
.count()
|
.count()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Override Option").as_ref(),
|
||||||
"Override Option",
|
|
||||||
"msh_override",
|
"msh_override",
|
||||||
self.override_option.to_string(),
|
self.override_option.to_string(),
|
||||||
),
|
),
|
||||||
ro("Number of Grips", "msh_grips", self.vertices.len().to_string()),
|
ro(t!("Number of Grips").as_ref(), "msh_grips", self.vertices.len().to_string()),
|
||||||
ro(
|
ro(t!("Watertight").as_ref(),
|
||||||
"Watertight",
|
|
||||||
"msh_watertight",
|
"msh_watertight",
|
||||||
if watertight { "Yes" } else { "No" },
|
if watertight { "Yes" } else { "No" },
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use acadrust::entities::MLine;
|
use acadrust::entities::MLine;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip};
|
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);
|
let cur_z = cur.map(|v| v.position.z).unwrap_or(0.0);
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Vertex", "ml_vertex", if self.vertices.is_empty() { String::new() } else { "1".to_string() }),
|
ro(t!("Vertex").as_ref(), "ml_vertex", if self.vertices.is_empty() { String::new() } else { "1".to_string() }),
|
||||||
edit("Vertex X", "ml_vertex_x", cur_x),
|
edit(t!("Vertex X").as_ref(), "ml_vertex_x", cur_x),
|
||||||
edit("Vertex Y", "ml_vertex_y", cur_y),
|
edit(t!("Vertex Y").as_ref(), "ml_vertex_y", cur_y),
|
||||||
edit("Vertex Z", "ml_vertex_z", cur_z),
|
edit(t!("Vertex Z").as_ref(), "ml_vertex_z", cur_z),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Style".into(),
|
label: t!("Style").into_owned(),
|
||||||
field: "ml_style",
|
field: "ml_style",
|
||||||
value: PropValue::EditText(self.style_name.clone()),
|
value: PropValue::EditText(self.style_name.clone()),
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Style justification".into(),
|
label: t!("Style justification").into_owned(),
|
||||||
field: "ml_justification",
|
field: "ml_justification",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: just_str.to_string(),
|
selected: just_str.to_string(),
|
||||||
|
|
@ -363,7 +364,7 @@ impl PropertyEditable for MLine {
|
||||||
.collect(),
|
.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::convert::acad_to_truck::{TruckEntity, TruckObject};
|
||||||
use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property};
|
use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property};
|
||||||
use crate::scene::model::wire_model::SnapHint;
|
use crate::scene::model::wire_model::SnapHint;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
/// The entity's `column_data` as the layout's column description.
|
/// 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);
|
let height_editable = col_type == 1 || (col_type == 2 && !t.column_data.auto_height);
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Text".into(),
|
title: t!("Text").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Contents".into(),
|
label: t!("Contents").into_owned(),
|
||||||
field: "content",
|
field: "content",
|
||||||
value: PropValue::EditText(t.value.clone()),
|
value: PropValue::EditText(t.value.clone()),
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Style".into(),
|
label: t!("Style").into_owned(),
|
||||||
field: "style",
|
field: "style",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: if t.style.trim().is_empty() {
|
selected: if t.style.trim().is_empty() {
|
||||||
|
|
@ -274,12 +275,12 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ro(
|
ro(
|
||||||
"Annotative",
|
t!("Annotative").as_ref(),
|
||||||
"annotative",
|
"annotative",
|
||||||
if t.is_annotative { "Yes" } else { "No" },
|
if t.is_annotative { "Yes" } else { "No" },
|
||||||
),
|
),
|
||||||
Property {
|
Property {
|
||||||
label: "Justify".into(),
|
label: t!("Justify").into_owned(),
|
||||||
field: "justify",
|
field: "justify",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: attachment_str(&t.attachment_point).to_string(),
|
selected: attachment_str(&t.attachment_point).to_string(),
|
||||||
|
|
@ -300,7 +301,7 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Direction".into(),
|
label: t!("Direction").into_owned(),
|
||||||
field: "direction",
|
field: "direction",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: drawing_dir_str(&t.drawing_direction).to_string(),
|
selected: drawing_dir_str(&t.drawing_direction).to_string(),
|
||||||
|
|
@ -310,12 +311,12 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edit("Text height", "height", t.height),
|
edit(t!("Text height").as_ref(), "height", t.height),
|
||||||
edit_angle("Rotation", "rotation", t.rotation.to_degrees()),
|
edit_angle(t!("Rotation").as_ref(), "rotation", t.rotation.to_degrees()),
|
||||||
edit("Line space factor", "line_spacing", t.line_spacing_factor),
|
edit(t!("Line space factor").as_ref(), "line_spacing", t.line_spacing_factor),
|
||||||
edit("Line space distance", "line_space_distance", line_space_distance),
|
edit(t!("Line space distance").as_ref(), "line_space_distance", line_space_distance),
|
||||||
Property {
|
Property {
|
||||||
label: "Line space style".into(),
|
label: t!("Line space style").into_owned(),
|
||||||
field: "line_space_style",
|
field: "line_space_style",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: match t.line_spacing_style {
|
selected: match t.line_spacing_style {
|
||||||
|
|
@ -330,7 +331,7 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Background mask".into(),
|
label: t!("Background mask").into_owned(),
|
||||||
field: "background_mask",
|
field: "background_mask",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: if t.background_fill_flags & 0x01 != 0 {
|
selected: if t.background_fill_flags & 0x01 != 0 {
|
||||||
|
|
@ -346,15 +347,15 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
.collect(),
|
.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(
|
num_row(
|
||||||
"Defined height",
|
t!("Defined height").as_ref(),
|
||||||
"rect_h",
|
"rect_h",
|
||||||
t.rectangle_height.unwrap_or(0.0),
|
t.rectangle_height.unwrap_or(0.0),
|
||||||
height_editable,
|
height_editable,
|
||||||
),
|
),
|
||||||
Property {
|
Property {
|
||||||
label: "Columns".into(),
|
label: t!("Columns").into_owned(),
|
||||||
field: "columns",
|
field: "columns",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: columns_str(&t.column_data).to_string(),
|
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.
|
// Count / width / gutter are live only when columns are on.
|
||||||
num_row(
|
num_row(
|
||||||
"Column count",
|
t!("Column count").as_ref(),
|
||||||
"col_count",
|
"col_count",
|
||||||
t.column_data.column_count as f64,
|
t.column_data.column_count as f64,
|
||||||
col_type != 0,
|
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(
|
num_row(
|
||||||
"Column gutter",
|
t!("Column gutter").as_ref(),
|
||||||
"col_gutter",
|
"col_gutter",
|
||||||
t.column_data.gutter,
|
t.column_data.gutter,
|
||||||
col_type != 0,
|
col_type != 0,
|
||||||
),
|
),
|
||||||
Property {
|
Property {
|
||||||
label: "Text frame".into(),
|
label: t!("Text frame").into_owned(),
|
||||||
field: "text_frame",
|
field: "text_frame",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "text_frame",
|
field: "text_frame",
|
||||||
|
|
@ -389,11 +390,11 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Position X", "ins_x", t.insertion_point.x),
|
edit(t!("Position X").as_ref(), "ins_x", t.insertion_point.x),
|
||||||
edit("Position Y", "ins_y", t.insertion_point.y),
|
edit(t!("Position Y").as_ref(), "ins_y", t.insertion_point.y),
|
||||||
edit("Position Z", "ins_z", t.insertion_point.z),
|
edit(t!("Position Z").as_ref(), "ins_z", t.insertion_point.z),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use acadrust::entities::{
|
||||||
use crate::entities::text_support::{
|
use crate::entities::text_support::{
|
||||||
layout_mtext, resolve_text_style, MTextRenderOpts, MTextVAnchor, ResolvedTextStyle,
|
layout_mtext, resolve_text_style, MTextRenderOpts, MTextVAnchor, ResolvedTextStyle,
|
||||||
};
|
};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
/// Map MLEADER's vertical attachment enum onto the shared `MTextVAnchor`
|
/// Map MLEADER's vertical attachment enum onto the shared `MTextVAnchor`
|
||||||
/// used by `layout_mtext`. Replaces the old `v_offset_for_attachment`
|
/// used by `layout_mtext`. Replaces the old `v_offset_for_attachment`
|
||||||
|
|
@ -650,19 +651,19 @@ fn properties(ml: &MultiLeader) -> Vec<PropSection> {
|
||||||
|
|
||||||
// ── Misc ─────────────────────────────────────────────────────────────
|
// ── Misc ─────────────────────────────────────────────────────────────
|
||||||
let misc = PropSection {
|
let misc = PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
// Overall scale is grayed when annotative (annotation scale drives sizing).
|
// Overall scale is grayed when annotative (annotation scale drives sizing).
|
||||||
num_row(
|
num_row(
|
||||||
"Overall scale",
|
t!("Overall scale").as_ref(),
|
||||||
"scale_factor",
|
"scale_factor",
|
||||||
ml.scale_factor,
|
ml.scale_factor,
|
||||||
!ml.enable_annotation_scale,
|
!ml.enable_annotation_scale,
|
||||||
),
|
),
|
||||||
// Style name is resolved from style_handle by the panel builder (needs doc).
|
// 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(
|
bool_toggle(
|
||||||
"Annotative",
|
t!("Annotative").as_ref(),
|
||||||
"enable_annotation_scale",
|
"enable_annotation_scale",
|
||||||
ml.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
|
// Landing rows are folded in here: the standalone "Leader Structure" group
|
||||||
// is a style-dialog tab, not a palette group.
|
// is a style-dialog tab, not a palette group.
|
||||||
let leaders = PropSection {
|
let leaders = PropSection {
|
||||||
title: "Leaders".into(),
|
title: t!("Leaders").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
choice(
|
choice(
|
||||||
"Leader type",
|
t!("Leader type").as_ref(),
|
||||||
"path_type",
|
"path_type",
|
||||||
leader_type_str(&ml.path_type),
|
leader_type_str(&ml.path_type),
|
||||||
&["Straight", "Spline", "None"],
|
&["Straight", "Spline", "None"],
|
||||||
),
|
),
|
||||||
Property {
|
Property {
|
||||||
label: "Leader color".into(),
|
label: t!("Leader color").into_owned(),
|
||||||
field: "line_color",
|
field: "line_color",
|
||||||
value: PropValue::ColorChoice(ml.line_color),
|
value: PropValue::ColorChoice(ml.line_color),
|
||||||
},
|
},
|
||||||
// Linetype name resolved from line_type_handle by the panel builder.
|
// 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 {
|
Property {
|
||||||
label: "Leader lineweight".into(),
|
label: t!("Leader lineweight").into_owned(),
|
||||||
field: "line_weight",
|
field: "line_weight",
|
||||||
value: PropValue::LwChoice(ml.line_weight),
|
value: PropValue::LwChoice(ml.line_weight),
|
||||||
},
|
},
|
||||||
// Arrowhead block name resolved by the panel builder (default "Closed filled").
|
// Arrowhead block name resolved by the panel builder (default "Closed filled").
|
||||||
ro("Arrowhead", "arrowhead_handle", "Closed filled"),
|
ro(t!("Arrowhead").as_ref(), "arrowhead_handle", "Closed filled"),
|
||||||
edit("Arrowhead size", "arrowhead_size", ml.arrowhead_size),
|
edit(t!("Arrowhead size").as_ref(), "arrowhead_size", ml.arrowhead_size),
|
||||||
bool_toggle("Horizontal Landing", "enable_dogleg", ml.enable_dogleg),
|
bool_toggle(t!("Horizontal Landing").as_ref(), "enable_dogleg", ml.enable_dogleg),
|
||||||
num_row(
|
num_row(
|
||||||
"Landing distance",
|
t!("Landing distance").as_ref(),
|
||||||
"landing_distance",
|
"landing_distance",
|
||||||
ml.dogleg_length,
|
ml.dogleg_length,
|
||||||
ml.enable_dogleg,
|
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) ──────────────────────────────
|
// ── Text (shown only for MText content) ──────────────────────────────
|
||||||
let text = PropSection {
|
let text = PropSection {
|
||||||
title: "Text".into(),
|
title: t!("Text").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Contents".into(),
|
label: t!("Contents").into_owned(),
|
||||||
field: "text_string",
|
field: "text_string",
|
||||||
value: PropValue::EditText(ctx.text_string.clone()),
|
value: PropValue::EditText(ctx.text_string.clone()),
|
||||||
},
|
},
|
||||||
// Text-style name resolved from text_style_handle by the panel builder.
|
// 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(
|
choice(
|
||||||
"Justify",
|
t!("Justify").as_ref(),
|
||||||
"text_alignment",
|
"text_alignment",
|
||||||
text_align_str(&ml.text_alignment),
|
text_align_str(&ml.text_alignment),
|
||||||
&["Left", "Center", "Right"],
|
&["Left", "Center", "Right"],
|
||||||
),
|
),
|
||||||
choice(
|
choice(
|
||||||
"Direction",
|
t!("Direction").as_ref(),
|
||||||
"text_flow_direction",
|
"text_flow_direction",
|
||||||
flow_dir_str(&ctx.text_flow_direction),
|
flow_dir_str(&ctx.text_flow_direction),
|
||||||
&["By style", "Left to right", "Top to bottom"],
|
&["By style", "Left to right", "Top to bottom"],
|
||||||
),
|
),
|
||||||
edit("Width", "text_width", ctx.text_width),
|
edit(t!("Width").as_ref(), "text_width", ctx.text_width),
|
||||||
edit("Height", "text_height", ml.text_height),
|
edit(t!("Height").as_ref(), "text_height", ml.text_height),
|
||||||
edit_angle("Rotation", "text_rotation", ctx.text_rotation.to_degrees()),
|
edit_angle(t!("Rotation").as_ref(), "text_rotation", ctx.text_rotation.to_degrees()),
|
||||||
edit("Line space factor", "line_spacing", ctx.line_spacing_factor),
|
edit(t!("Line space factor").as_ref(), "line_spacing", ctx.line_spacing_factor),
|
||||||
edit(
|
edit(
|
||||||
"Line space distance",
|
t!("Line space distance").as_ref(),
|
||||||
"line_space_distance",
|
"line_space_distance",
|
||||||
ml.text_height * 1.666_666_666_666_667 * ctx.line_spacing_factor,
|
ml.text_height * 1.666_666_666_666_667 * ctx.line_spacing_factor,
|
||||||
),
|
),
|
||||||
choice(
|
choice(
|
||||||
"Line space style",
|
t!("Line space style").as_ref(),
|
||||||
"line_space_style",
|
"line_space_style",
|
||||||
line_style_str(&ctx.line_spacing_style),
|
line_style_str(&ctx.line_spacing_style),
|
||||||
&["At least", "Exactly"],
|
&["At least", "Exactly"],
|
||||||
),
|
),
|
||||||
bool_toggle(
|
bool_toggle(
|
||||||
"Background mask",
|
t!("Background mask").as_ref(),
|
||||||
"background_fill_enabled",
|
"background_fill_enabled",
|
||||||
ctx.background_fill_enabled,
|
ctx.background_fill_enabled,
|
||||||
),
|
),
|
||||||
choice(
|
choice(
|
||||||
"Attachment type",
|
t!("Attachment type").as_ref(),
|
||||||
"text_attachment_direction",
|
"text_attachment_direction",
|
||||||
attach_dir_str(&ml.text_attachment_direction),
|
attach_dir_str(&ml.text_attachment_direction),
|
||||||
&["Horizontal", "Vertical"],
|
&["Horizontal", "Vertical"],
|
||||||
),
|
),
|
||||||
choice(
|
choice(
|
||||||
"Left Attachment",
|
t!("Left Attachment").as_ref(),
|
||||||
"text_left_attachment",
|
"text_left_attachment",
|
||||||
attachment_str(&ml.text_left_attachment),
|
attachment_str(&ml.text_left_attachment),
|
||||||
&ATTACH_LABELS,
|
&ATTACH_LABELS,
|
||||||
),
|
),
|
||||||
choice(
|
choice(
|
||||||
"Right Attachment",
|
t!("Right Attachment").as_ref(),
|
||||||
"text_right_attachment",
|
"text_right_attachment",
|
||||||
attachment_str(&ml.text_right_attachment),
|
attachment_str(&ml.text_right_attachment),
|
||||||
&ATTACH_LABELS,
|
&ATTACH_LABELS,
|
||||||
),
|
),
|
||||||
edit("Landing gap", "landing_gap", ctx.landing_gap),
|
edit(t!("Landing gap").as_ref(), "landing_gap", ctx.landing_gap),
|
||||||
bool_toggle("Text frame", "text_frame", ml.text_frame),
|
bool_toggle(t!("Text frame").as_ref(), "text_frame", ml.text_frame),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
// ── Block ────────────────────────────────────────────────────────────
|
// ── Block ────────────────────────────────────────────────────────────
|
||||||
let block = PropSection {
|
let block = PropSection {
|
||||||
title: "Block".into(),
|
title: t!("Block").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro(
|
ro(
|
||||||
"Source block",
|
t!("Source block").as_ref(),
|
||||||
"block_content_handle",
|
"block_content_handle",
|
||||||
hexh(ml.block_content_handle),
|
hexh(ml.block_content_handle),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Block connection",
|
t!("Block connection").as_ref(),
|
||||||
"block_connection_type",
|
"block_connection_type",
|
||||||
format!("{:?}", ml.block_connection_type),
|
format!("{:?}", ml.block_connection_type),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Block color",
|
t!("Block color").as_ref(),
|
||||||
"block_content_color",
|
"block_content_color",
|
||||||
format!("{:?}", ml.block_content_color),
|
format!("{:?}", ml.block_content_color),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Block scale",
|
t!("Block scale").as_ref(),
|
||||||
"block_scale",
|
"block_scale",
|
||||||
format!(
|
format!(
|
||||||
"{:.3} × {:.3} × {:.3}",
|
"{:.3} × {:.3} × {:.3}",
|
||||||
|
|
@ -801,7 +802,7 @@ fn properties(ml: &MultiLeader) -> Vec<PropSection> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
edit(
|
edit(
|
||||||
"Block rotation",
|
t!("Block rotation").as_ref(),
|
||||||
"block_rotation",
|
"block_rotation",
|
||||||
ml.block_rotation.to_degrees(),
|
ml.block_rotation.to_degrees(),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use acadrust::entities::Point;
|
use acadrust::entities::Point;
|
||||||
use acadrust::EntityType;
|
use acadrust::EntityType;
|
||||||
|
use crate::t;
|
||||||
use truck_modeling::{builder, Point3};
|
use truck_modeling::{builder, Point3};
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
|
|
@ -187,11 +188,11 @@ fn grips(pt: &Point) -> Vec<GripDef> {
|
||||||
|
|
||||||
fn properties(pt: &Point) -> Vec<PropSection> {
|
fn properties(pt: &Point) -> Vec<PropSection> {
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Position X", "loc_x", pt.location.x),
|
edit(t!("Position X").as_ref(), "loc_x", pt.location.x),
|
||||||
edit("Position Y", "loc_y", pt.location.y),
|
edit(t!("Position Y").as_ref(), "loc_y", pt.location.y),
|
||||||
edit("Position Z", "loc_z", pt.location.z),
|
edit(t!("Position Z").as_ref(), "loc_z", pt.location.z),
|
||||||
],
|
],
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use acadrust::entities::{Polyline, Polyline2D, Polyline3D};
|
use acadrust::entities::{Polyline, Polyline2D, Polyline3D};
|
||||||
|
use crate::t;
|
||||||
use truck_modeling::{builder, Edge, Point3, Wire};
|
use truck_modeling::{builder, Edge, Point3, Wire};
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
|
|
@ -123,11 +124,11 @@ impl Grippable for Polyline {
|
||||||
impl PropertyEditable for Polyline {
|
impl PropertyEditable for Polyline {
|
||||||
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Vertices", "vertices", self.vertices.len().to_string()),
|
ro(t!("Vertices").as_ref(), "vertices", self.vertices.len().to_string()),
|
||||||
Property {
|
Property {
|
||||||
label: "Closed".into(),
|
label: t!("Closed").into_owned(),
|
||||||
field: "pl_closed",
|
field: "pl_closed",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "pl_closed",
|
field: "pl_closed",
|
||||||
|
|
@ -565,24 +566,24 @@ impl PropertyEditable for Polyline2D {
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
stepper("Current Vertex", "pl2_current_vertex", vertex_label),
|
stepper(t!("Current Vertex").as_ref(), "pl2_current_vertex", vertex_label),
|
||||||
edit("Vertex X", "pl2_vertex_x", vertex_x),
|
edit(t!("Vertex X").as_ref(), "pl2_vertex_x", vertex_x),
|
||||||
edit("Vertex Y", "pl2_vertex_y", vertex_y),
|
edit(t!("Vertex Y").as_ref(), "pl2_vertex_y", vertex_y),
|
||||||
edit("Start segment width", "pl2_seg_start_w", seg_start_w),
|
edit(t!("Start segment width").as_ref(), "pl2_seg_start_w", seg_start_w),
|
||||||
edit("End segment width", "pl2_seg_end_w", seg_end_w),
|
edit(t!("End segment width").as_ref(), "pl2_seg_end_w", seg_end_w),
|
||||||
edit("Global width", "pl2_start_w", self.start_width),
|
edit(t!("Global width").as_ref(), "pl2_start_w", self.start_width),
|
||||||
edit("Elevation", "pl2_elevation", self.elevation),
|
edit(t!("Elevation").as_ref(), "pl2_elevation", self.elevation),
|
||||||
ro("Area", "pl2_area", format!("{area:.4}")),
|
ro(t!("Area").as_ref(), "pl2_area", format!("{area:.4}")),
|
||||||
ro("Length", "pl2_length", format!("{length:.4}")),
|
ro(t!("Length").as_ref(), "pl2_length", format!("{length:.4}")),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Closed".into(),
|
label: t!("Closed").into_owned(),
|
||||||
field: "pl2_closed",
|
field: "pl2_closed",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "pl2_closed",
|
field: "pl2_closed",
|
||||||
|
|
@ -590,7 +591,7 @@ impl PropertyEditable for Polyline2D {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Linetype generation".into(),
|
label: t!("Linetype generation").into_owned(),
|
||||||
field: "pl2_ltype_gen",
|
field: "pl2_ltype_gen",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "pl2_ltype_gen",
|
field: "pl2_ltype_gen",
|
||||||
|
|
@ -838,26 +839,26 @@ impl PropertyEditable for Polyline3D {
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Vertex", "pl3_vertex", if n > 0 { "1" } else { "" }),
|
ro(t!("Vertex").as_ref(), "pl3_vertex", if n > 0 { "1" } else { "" }),
|
||||||
edit("Vertex X", "pl3_vertex_x", vertex_x),
|
edit(t!("Vertex X").as_ref(), "pl3_vertex_x", vertex_x),
|
||||||
edit("Vertex Y", "pl3_vertex_y", vertex_y),
|
edit(t!("Vertex Y").as_ref(), "pl3_vertex_y", vertex_y),
|
||||||
edit("Vertex Z", "pl3_vertex_z", vertex_z),
|
edit(t!("Vertex Z").as_ref(), "pl3_vertex_z", vertex_z),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Closed".into(),
|
label: t!("Closed").into_owned(),
|
||||||
field: "pl3_closed",
|
field: "pl3_closed",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "pl3_closed",
|
field: "pl3_closed",
|
||||||
value: self.is_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 acadrust::entities::{RasterImage, Wipeout};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::{center_grip, edit_prop as edit, ro_prop as ro, square_grip};
|
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);
|
let transparency = format!("{:.0}%", self.common.transparency.as_percent() * 100.0);
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Position X", "ri_ox", self.insertion_point.x),
|
edit(t!("Position X").as_ref(), "ri_ox", self.insertion_point.x),
|
||||||
edit("Position Y", "ri_oy", self.insertion_point.y),
|
edit(t!("Position Y").as_ref(), "ri_oy", self.insertion_point.y),
|
||||||
edit("Position Z", "ri_oz", self.insertion_point.z),
|
edit(t!("Position Z").as_ref(), "ri_oz", self.insertion_point.z),
|
||||||
ro("Rotation", "ri_rotation", format!("{:.4}", rotation_deg)),
|
ro(t!("Rotation").as_ref(), "ri_rotation", format!("{:.4}", rotation_deg)),
|
||||||
ro("Width", "ri_width", format!("{:.4}", self.width())),
|
ro(t!("Width").as_ref(), "ri_width", format!("{:.4}", self.width())),
|
||||||
ro("Height", "ri_height", format!("{:.4}", self.height())),
|
ro(t!("Height").as_ref(), "ri_height", format!("{:.4}", self.height())),
|
||||||
ro("Scale", "ri_scale", format!("{:.4}", scale)),
|
ro(t!("Scale").as_ref(), "ri_scale", format!("{:.4}", scale)),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Name", "ri_name", self.file_name().to_string()),
|
ro(t!("Name").as_ref(), "ri_name", self.file_name().to_string()),
|
||||||
edit("Brightness", "ri_bright", self.brightness as f64),
|
edit(t!("Brightness").as_ref(), "ri_bright", self.brightness as f64),
|
||||||
edit("Contrast", "ri_contrast", self.contrast as f64),
|
edit(t!("Contrast").as_ref(), "ri_contrast", self.contrast as f64),
|
||||||
edit("Fade", "ri_fade", self.fade as f64),
|
edit(t!("Fade").as_ref(), "ri_fade", self.fade as f64),
|
||||||
ro("Transparency", "ri_transparency", transparency),
|
ro(t!("Transparency").as_ref(), "ri_transparency", transparency),
|
||||||
Property {
|
Property {
|
||||||
label: "Show image".into(),
|
label: t!("Show image").into_owned(),
|
||||||
field: "ri_show_image",
|
field: "ri_show_image",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "ri_show_image",
|
field: "ri_show_image",
|
||||||
|
|
@ -317,7 +318,7 @@ impl PropertyEditable for RasterImage {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Show clipped".into(),
|
label: t!("Show clipped").into_owned(),
|
||||||
field: "ri_show_clipped",
|
field: "ri_show_clipped",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "ri_show_clipped",
|
field: "ri_show_clipped",
|
||||||
|
|
@ -325,7 +326,7 @@ impl PropertyEditable for RasterImage {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Clip inverted".into(),
|
label: t!("Clip inverted").into_owned(),
|
||||||
field: "ri_clip_inverted",
|
field: "ri_clip_inverted",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "ri_clip_inverted",
|
field: "ri_clip_inverted",
|
||||||
|
|
@ -596,18 +597,18 @@ impl PropertyEditable for Wipeout {
|
||||||
.contains(acadrust::entities::WipeoutDisplayFlags::TRANSPARENCY_ON);
|
.contains(acadrust::entities::WipeoutDisplayFlags::TRANSPARENCY_ON);
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Position X", "wo_ox", self.insertion_point.x),
|
edit(t!("Position X").as_ref(), "wo_ox", self.insertion_point.x),
|
||||||
edit("Position Y", "wo_oy", self.insertion_point.y),
|
edit(t!("Position Y").as_ref(), "wo_oy", self.insertion_point.y),
|
||||||
edit("Position Z", "wo_oz", self.insertion_point.z),
|
edit(t!("Position Z").as_ref(), "wo_oz", self.insertion_point.z),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Show image".into(),
|
label: t!("Show image").into_owned(),
|
||||||
field: "wo_show_image",
|
field: "wo_show_image",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "wo_show_image",
|
field: "wo_show_image",
|
||||||
|
|
@ -615,7 +616,7 @@ impl PropertyEditable for Wipeout {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Show clipped".into(),
|
label: t!("Show clipped").into_owned(),
|
||||||
field: "wo_show_clipped",
|
field: "wo_show_clipped",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "wo_show_clipped",
|
field: "wo_show_clipped",
|
||||||
|
|
@ -623,7 +624,7 @@ impl PropertyEditable for Wipeout {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Background transparency".into(),
|
label: t!("Background transparency").into_owned(),
|
||||||
field: "wo_bg_transparency",
|
field: "wo_bg_transparency",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "wo_bg_transparency",
|
field: "wo_bg_transparency",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use acadrust::entities::{Ray, XLine};
|
use acadrust::entities::{Ray, XLine};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::{center_grip, edit_prop as edit, square_grip};
|
use crate::entities::common::{center_grip, edit_prop as edit, square_grip};
|
||||||
|
|
@ -91,14 +92,14 @@ impl Grippable for Ray {
|
||||||
impl PropertyEditable for Ray {
|
impl PropertyEditable for Ray {
|
||||||
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Start X", "ray_bx", self.base_point.x),
|
edit(t!("Start X").as_ref(), "ray_bx", self.base_point.x),
|
||||||
edit("Start Y", "ray_by", self.base_point.y),
|
edit(t!("Start Y").as_ref(), "ray_by", self.base_point.y),
|
||||||
edit("Start Z", "ray_bz", self.base_point.z),
|
edit(t!("Start Z").as_ref(), "ray_bz", self.base_point.z),
|
||||||
edit("Direction vector X", "ray_dx", self.direction.x),
|
edit(t!("Direction vector X").as_ref(), "ray_dx", self.direction.x),
|
||||||
edit("Direction vector Y", "ray_dy", self.direction.y),
|
edit(t!("Direction vector Y").as_ref(), "ray_dy", self.direction.y),
|
||||||
edit("Direction vector Z", "ray_dz", self.direction.z),
|
edit(t!("Direction vector Z").as_ref(), "ray_dz", self.direction.z),
|
||||||
],
|
],
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
@ -229,14 +230,14 @@ impl Grippable for XLine {
|
||||||
impl PropertyEditable for XLine {
|
impl PropertyEditable for XLine {
|
||||||
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Base X", "xl_bx", self.base_point.x),
|
edit(t!("Base X").as_ref(), "xl_bx", self.base_point.x),
|
||||||
edit("Base Y", "xl_by", self.base_point.y),
|
edit(t!("Base Y").as_ref(), "xl_by", self.base_point.y),
|
||||||
edit("Base Z", "xl_bz", self.base_point.z),
|
edit(t!("Base Z").as_ref(), "xl_bz", self.base_point.z),
|
||||||
edit("Direction vector X", "xl_dx", self.direction.x),
|
edit(t!("Direction vector X").as_ref(), "xl_dx", self.direction.x),
|
||||||
edit("Direction vector Y", "xl_dy", self.direction.y),
|
edit(t!("Direction vector Y").as_ref(), "xl_dy", self.direction.y),
|
||||||
edit("Direction vector Z", "xl_dz", self.direction.z),
|
edit(t!("Direction vector Z").as_ref(), "xl_dz", self.direction.z),
|
||||||
],
|
],
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
// gives a rough indication of the glyph orientation.
|
// gives a rough indication of the glyph orientation.
|
||||||
|
|
||||||
use acadrust::entities::Shape;
|
use acadrust::entities::Shape;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::{edit_angle_prop as edit_angle, edit_prop as edit, ro_prop as ro, square_grip};
|
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(),
|
_ => "(none)".to_string(),
|
||||||
};
|
};
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Name", "shp_name", self.shape_name.clone()),
|
ro(t!("Name").as_ref(), "shp_name", self.shape_name.clone()),
|
||||||
ro("Number", "shp_number", self.shape_number.to_string()),
|
ro(t!("Number").as_ref(), "shp_number", self.shape_number.to_string()),
|
||||||
Property {
|
Property {
|
||||||
label: "Style".into(),
|
label: t!("Style").into_owned(),
|
||||||
field: "shp_style",
|
field: "shp_style",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: self.style_name.clone(),
|
selected: self.style_name.clone(),
|
||||||
options: text_style_names.to_vec(),
|
options: text_style_names.to_vec(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ro("Style Handle", "shp_style_handle", style_handle_display),
|
ro(t!("Style Handle").as_ref(), "shp_style_handle", style_handle_display),
|
||||||
edit("Insert X", "shp_ix", self.insertion_point.x),
|
edit(t!("Insert X").as_ref(), "shp_ix", self.insertion_point.x),
|
||||||
edit("Insert Y", "shp_iy", self.insertion_point.y),
|
edit(t!("Insert Y").as_ref(), "shp_iy", self.insertion_point.y),
|
||||||
edit("Insert Z", "shp_iz", self.insertion_point.z),
|
edit(t!("Insert Z").as_ref(), "shp_iz", self.insertion_point.z),
|
||||||
edit("Size", "shp_sz", self.size),
|
edit(t!("Size").as_ref(), "shp_sz", self.size),
|
||||||
edit_angle("Rotation", "shp_rot", self.rotation.to_degrees()),
|
edit_angle(t!("Rotation").as_ref(), "shp_rot", self.rotation.to_degrees()),
|
||||||
edit("Width Factor", "shp_xs", self.relative_x_scale),
|
edit(t!("Width Factor").as_ref(), "shp_xs", self.relative_x_scale),
|
||||||
edit_angle("Oblique Angle", "shp_ob", self.oblique_angle.to_degrees()),
|
edit_angle(t!("Oblique Angle").as_ref(), "shp_ob", self.oblique_angle.to_degrees()),
|
||||||
edit("Normal X", "shp_nx", self.normal.x),
|
edit(t!("Normal X").as_ref(), "shp_nx", self.normal.x),
|
||||||
edit("Normal Y", "shp_ny", self.normal.y),
|
edit(t!("Normal Y").as_ref(), "shp_ny", self.normal.y),
|
||||||
edit("Normal Z", "shp_nz", self.normal.z),
|
edit(t!("Normal Z").as_ref(), "shp_nz", self.normal.z),
|
||||||
],
|
],
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
// Grips: 4 corner grip points.
|
// Grips: 4 corner grip points.
|
||||||
|
|
||||||
use acadrust::entities::Solid;
|
use acadrust::entities::Solid;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip};
|
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.
|
// field on the entity); reported from the first corner's Z.
|
||||||
let elevation = self.first_corner.z;
|
let elevation = self.first_corner.z;
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Point 1 X", "sl_p1x", self.first_corner.x),
|
edit(t!("Point 1 X").as_ref(), "sl_p1x", self.first_corner.x),
|
||||||
edit("Point 1 Y", "sl_p1y", self.first_corner.y),
|
edit(t!("Point 1 Y").as_ref(), "sl_p1y", self.first_corner.y),
|
||||||
edit("Point 1 Z", "sl_p1z", self.first_corner.z),
|
edit(t!("Point 1 Z").as_ref(), "sl_p1z", self.first_corner.z),
|
||||||
edit("Point 2 X", "sl_p2x", self.second_corner.x),
|
edit(t!("Point 2 X").as_ref(), "sl_p2x", self.second_corner.x),
|
||||||
edit("Point 2 Y", "sl_p2y", self.second_corner.y),
|
edit(t!("Point 2 Y").as_ref(), "sl_p2y", self.second_corner.y),
|
||||||
edit("Point 2 Z", "sl_p2z", self.second_corner.z),
|
edit(t!("Point 2 Z").as_ref(), "sl_p2z", self.second_corner.z),
|
||||||
edit("Point 3 X", "sl_p3x", self.third_corner.x),
|
edit(t!("Point 3 X").as_ref(), "sl_p3x", self.third_corner.x),
|
||||||
edit("Point 3 Y", "sl_p3y", self.third_corner.y),
|
edit(t!("Point 3 Y").as_ref(), "sl_p3y", self.third_corner.y),
|
||||||
edit("Point 3 Z", "sl_p3z", self.third_corner.z),
|
edit(t!("Point 3 Z").as_ref(), "sl_p3z", self.third_corner.z),
|
||||||
edit("Point 4 X", "sl_p4x", self.fourth_corner.x),
|
edit(t!("Point 4 X").as_ref(), "sl_p4x", self.fourth_corner.x),
|
||||||
edit("Point 4 Y", "sl_p4y", self.fourth_corner.y),
|
edit(t!("Point 4 Y").as_ref(), "sl_p4y", self.fourth_corner.y),
|
||||||
edit("Point 4 Z", "sl_p4z", self.fourth_corner.z),
|
edit(t!("Point 4 Z").as_ref(), "sl_p4z", self.fourth_corner.z),
|
||||||
ro("Elevation", "sl_elev", format!("{:.4}", elevation)),
|
ro(t!("Elevation").as_ref(), "sl_elev", format!("{:.4}", elevation)),
|
||||||
],
|
],
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
// the MeshModel vertices to match.
|
// the MeshModel vertices to match.
|
||||||
|
|
||||||
use acadrust::entities::{Body, Region, Solid3D, Surface};
|
use acadrust::entities::{Body, Region, Solid3D, Surface};
|
||||||
|
use crate::t;
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::{center_grip, edit_prop as edit, parse_f64, ro_prop as ro};
|
use crate::entities::common::{center_grip, edit_prop as edit, parse_f64, ro_prop as ro};
|
||||||
use crate::entities::traits::{Grippable, PropertyEditable, Transformable};
|
use crate::entities::traits::{Grippable, PropertyEditable, Transformable};
|
||||||
|
|
@ -119,46 +120,40 @@ fn acis_sections(
|
||||||
);
|
);
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Modeler Geometry".into(),
|
title: t!("Modeler Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro(
|
ro(t!("Format").as_ref(),
|
||||||
"Format",
|
|
||||||
"acis_format",
|
"acis_format",
|
||||||
if acis.is_binary { "SAB" } else { "SAT" },
|
if acis.is_binary { "SAB" } else { "SAT" },
|
||||||
),
|
),
|
||||||
ro("Version", "acis_version", format!("{:?}", acis.version)),
|
ro(t!("Version").as_ref(), "acis_version", format!("{:?}", acis.version)),
|
||||||
ro("Data Size", "acis_size", format!("{} bytes", acis.size())),
|
ro(t!("Data Size").as_ref(), "acis_size", format!("{} bytes", acis.size())),
|
||||||
ro("Revision", "acis_revision", revision),
|
ro(t!("Revision").as_ref(), "acis_revision", revision),
|
||||||
ro("Material Bindings", "acis_materials", bindings),
|
ro(t!("Material Bindings").as_ref(), "acis_materials", bindings),
|
||||||
ro("Extra Modeler Data", "acis_extra", extra),
|
ro(t!("Extra Modeler Data").as_ref(), "acis_extra", extra),
|
||||||
ro("History", "acis_history", handle_text(history)),
|
ro(t!("History").as_ref(), "acis_history", handle_text(history)),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Modeler Display Data".into(),
|
title: t!("Modeler Display Data").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro(
|
ro(t!("Wireframe Cache").as_ref(),
|
||||||
"Wireframe Cache",
|
|
||||||
"acis_wireframe",
|
"acis_wireframe",
|
||||||
yes_no(acis.wireframe_data_present),
|
yes_no(acis.wireframe_data_present),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Reference Point").as_ref(),
|
||||||
"Reference Point",
|
|
||||||
"acis_wireframe_point",
|
"acis_wireframe_point",
|
||||||
yes_no(acis.wireframe_point_present),
|
yes_no(acis.wireframe_point_present),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Isoline List").as_ref(),
|
||||||
"Isoline List",
|
|
||||||
"acis_wireframe_isolines",
|
"acis_wireframe_isolines",
|
||||||
yes_no(acis.wireframe_isoline_present),
|
yes_no(acis.wireframe_isoline_present),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Isolines").as_ref(),
|
||||||
"Isolines",
|
|
||||||
"acis_isolines",
|
"acis_isolines",
|
||||||
acis.wireframe_isolines.to_string(),
|
acis.wireframe_isolines.to_string(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Wires").as_ref(),
|
||||||
"Wires",
|
|
||||||
"acis_wires",
|
"acis_wires",
|
||||||
format!(
|
format!(
|
||||||
"{} (unknown {}, silhouette {}, visible {}, hidden {}, isoline {}; {} points; {} transformed)",
|
"{} (unknown {}, silhouette {}, visible {}, hidden {}, isoline {}; {} points; {} transformed)",
|
||||||
|
|
@ -172,8 +167,7 @@ fn acis_sections(
|
||||||
transformed
|
transformed
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("View Silhouettes").as_ref(),
|
||||||
"View Silhouettes",
|
|
||||||
"acis_silhouettes",
|
"acis_silhouettes",
|
||||||
format!(
|
format!(
|
||||||
"{} views; {} wires",
|
"{} views; {} wires",
|
||||||
|
|
@ -194,11 +188,11 @@ fn position_section(prefix: &str, p: &acadrust::types::Vector3) -> PropSection {
|
||||||
_ => ["s3d_px", "s3d_py", "s3d_pz"],
|
_ => ["s3d_px", "s3d_py", "s3d_pz"],
|
||||||
};
|
};
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Position X", fields[0], p.x),
|
edit(t!("Position X").as_ref(), fields[0], p.x),
|
||||||
edit("Position Y", fields[1], p.y),
|
edit(t!("Position Y").as_ref(), fields[1], p.y),
|
||||||
edit("Position Z", fields[2], p.z),
|
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);
|
acis_sections(&self.acis_data, &self.wires, &self.silhouettes, self.history_handle);
|
||||||
sections[0]
|
sections[0]
|
||||||
.props
|
.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.push(position_section("s3d", &self.point_of_reference));
|
||||||
sections
|
sections
|
||||||
}
|
}
|
||||||
|
|
@ -304,14 +298,14 @@ impl PropertyEditable for Region {
|
||||||
acis_sections(&self.acis_data, &self.wires, &self.silhouettes, self.history_handle);
|
acis_sections(&self.acis_data, &self.wires, &self.silhouettes, self.history_handle);
|
||||||
sections[0]
|
sections[0]
|
||||||
.props
|
.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);
|
let mut geometry = position_section("rgn", &self.point_of_reference);
|
||||||
geometry
|
geometry
|
||||||
.props
|
.props
|
||||||
.push(ro("Area", "rgn_area", format!("{area:.4}")));
|
.push(ro(t!("Area").as_ref(), "rgn_area", format!("{area:.4}")));
|
||||||
geometry
|
geometry
|
||||||
.props
|
.props
|
||||||
.push(ro("Perimeter", "rgn_perimeter", format!("{perimeter:.4}")));
|
.push(ro(t!("Perimeter").as_ref(), "rgn_perimeter", format!("{perimeter:.4}")));
|
||||||
sections.push(geometry);
|
sections.push(geometry);
|
||||||
sections
|
sections
|
||||||
}
|
}
|
||||||
|
|
@ -355,7 +349,7 @@ impl PropertyEditable for Body {
|
||||||
acis_sections(&self.acis_data, &self.wires, &self.silhouettes, self.history_handle);
|
acis_sections(&self.acis_data, &self.wires, &self.silhouettes, self.history_handle);
|
||||||
sections[0]
|
sections[0]
|
||||||
.props
|
.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.push(position_section("bdy", &self.point_of_reference));
|
||||||
sections
|
sections
|
||||||
}
|
}
|
||||||
|
|
@ -433,19 +427,16 @@ fn sweep_options_text(options: &acadrust::entities::SurfaceSweepOptions) -> Stri
|
||||||
fn surface_construction_section(surface: &Surface) -> PropSection {
|
fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
use acadrust::entities::SurfaceData;
|
use acadrust::entities::SurfaceData;
|
||||||
let mut props = vec![
|
let mut props = vec![
|
||||||
ro("Kind", "srf_kind", format!("{:?}", surface.kind)),
|
ro(t!("Kind").as_ref(), "srf_kind", format!("{:?}", surface.kind)),
|
||||||
ro(
|
ro(t!("Modeler Format").as_ref(),
|
||||||
"Modeler Format",
|
|
||||||
"srf_modeler_version",
|
"srf_modeler_version",
|
||||||
surface.modeler_format_version.to_string(),
|
surface.modeler_format_version.to_string(),
|
||||||
),
|
),
|
||||||
edit(
|
edit(t!("U Isolines").as_ref(),
|
||||||
"U Isolines",
|
|
||||||
"srf_u_isolines",
|
"srf_u_isolines",
|
||||||
surface.u_isolines as f64,
|
surface.u_isolines as f64,
|
||||||
),
|
),
|
||||||
edit(
|
edit(t!("V Isolines").as_ref(),
|
||||||
"V Isolines",
|
|
||||||
"srf_v_isolines",
|
"srf_v_isolines",
|
||||||
surface.v_isolines as f64,
|
surface.v_isolines as f64,
|
||||||
),
|
),
|
||||||
|
|
@ -453,8 +444,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
match &surface.surface_data {
|
match &surface.surface_data {
|
||||||
SurfaceData::Generic => {}
|
SurfaceData::Generic => {}
|
||||||
SurfaceData::Plane { class_version } => {
|
SurfaceData::Plane { class_version } => {
|
||||||
props.push(ro(
|
props.push(ro(t!("Class Version").as_ref(),
|
||||||
"Class Version",
|
|
||||||
"srf_class_version",
|
"srf_class_version",
|
||||||
class_version.to_string(),
|
class_version.to_string(),
|
||||||
));
|
));
|
||||||
|
|
@ -466,25 +456,21 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
sweep_transform,
|
sweep_transform,
|
||||||
} => {
|
} => {
|
||||||
props.extend([
|
props.extend([
|
||||||
ro(
|
ro(t!("Sweep Entity").as_ref(),
|
||||||
"Sweep Entity",
|
|
||||||
"srf_sweep_entity",
|
"srf_sweep_entity",
|
||||||
embedded_name(sweep_entity.as_ref()),
|
embedded_name(sweep_entity.as_ref()),
|
||||||
),
|
),
|
||||||
ro("Sweep Vector", "srf_sweep_vector", vector_text(sweep_vector)),
|
ro(t!("Sweep Vector").as_ref(), "srf_sweep_vector", vector_text(sweep_vector)),
|
||||||
ro("Sweep Options", "srf_sweep_options", sweep_options_text(options)),
|
ro(t!("Sweep Options").as_ref(), "srf_sweep_options", sweep_options_text(options)),
|
||||||
ro(
|
ro(t!("Sweep Transform").as_ref(),
|
||||||
"Sweep Transform",
|
|
||||||
"srf_sweep_transform",
|
"srf_sweep_transform",
|
||||||
matrix_text(sweep_transform),
|
matrix_text(sweep_transform),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Sweep Entity Transform").as_ref(),
|
||||||
"Sweep Entity Transform",
|
|
||||||
"srf_sweep_entity_transform",
|
"srf_sweep_entity_transform",
|
||||||
matrix_text(&options.sweep_entity_transform),
|
matrix_text(&options.sweep_entity_transform),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Path Entity Transform").as_ref(),
|
||||||
"Path Entity Transform",
|
|
||||||
"srf_path_entity_transform",
|
"srf_path_entity_transform",
|
||||||
matrix_text(&options.path_entity_transform),
|
matrix_text(&options.path_entity_transform),
|
||||||
),
|
),
|
||||||
|
|
@ -513,8 +499,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
path_curve,
|
path_curve,
|
||||||
} => {
|
} => {
|
||||||
props.extend([
|
props.extend([
|
||||||
ro(
|
ro(t!("Embedded Curves").as_ref(),
|
||||||
"Embedded Curves",
|
|
||||||
"srf_loft_embedded",
|
"srf_loft_embedded",
|
||||||
format!(
|
format!(
|
||||||
"{} cross sections; {} guides; path {}",
|
"{} cross sections; {} guides; path {}",
|
||||||
|
|
@ -523,8 +508,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
embedded_name(path_entity.as_ref())
|
embedded_name(path_entity.as_ref())
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Database Curves").as_ref(),
|
||||||
"Database Curves",
|
|
||||||
"srf_loft_handles",
|
"srf_loft_handles",
|
||||||
format!(
|
format!(
|
||||||
"{} cross sections; {} guides; path {}",
|
"{} cross sections; {} guides; path {}",
|
||||||
|
|
@ -533,8 +517,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
handle_text(*path_curve)
|
handle_text(*path_curve)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Draft").as_ref(),
|
||||||
"Draft",
|
|
||||||
"srf_loft_draft",
|
"srf_loft_draft",
|
||||||
format!(
|
format!(
|
||||||
"type {}; angle {:.6}→{:.6}; magnitude {:.6}→{:.6}",
|
"type {}; angle {:.6}→{:.6}; magnitude {:.6}→{:.6}",
|
||||||
|
|
@ -545,8 +528,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
end_draft_magnitude
|
end_draft_magnitude
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Loft Flags").as_ref(),
|
||||||
"Loft Flags",
|
|
||||||
"srf_loft_flags",
|
"srf_loft_flags",
|
||||||
format!(
|
format!(
|
||||||
"arc-length {}; no-twist {}; align {}; simple {}; closed {}; solid {}; ruled {}; virtual-guide {}",
|
"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)
|
yes_no(*virtual_guide)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Loft Transform").as_ref(),
|
||||||
"Loft Transform",
|
|
||||||
"srf_loft_transform",
|
"srf_loft_transform",
|
||||||
matrix_text(loft_transform),
|
matrix_text(loft_transform),
|
||||||
),
|
),
|
||||||
|
|
@ -584,33 +565,28 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
close_to_axis,
|
close_to_axis,
|
||||||
} => {
|
} => {
|
||||||
props.extend([
|
props.extend([
|
||||||
ro(
|
ro(t!("Revolve Entity").as_ref(),
|
||||||
"Revolve Entity",
|
|
||||||
"srf_revolve_entity",
|
"srf_revolve_entity",
|
||||||
embedded_name(revolve_entity.as_ref()),
|
embedded_name(revolve_entity.as_ref()),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Class / Entity").as_ref(),
|
||||||
"Class / Entity",
|
|
||||||
"srf_revolve_ids",
|
"srf_revolve_ids",
|
||||||
format!("{class_version} / {entity_id}"),
|
format!("{class_version} / {entity_id}"),
|
||||||
),
|
),
|
||||||
ro("Axis Point", "srf_axis_point", vector_text(axis_point)),
|
ro(t!("Axis Point").as_ref(), "srf_axis_point", vector_text(axis_point)),
|
||||||
ro("Axis Vector", "srf_axis_vector", vector_text(axis_vector)),
|
ro(t!("Axis Vector").as_ref(), "srf_axis_vector", vector_text(axis_vector)),
|
||||||
ro(
|
ro(t!("Angles").as_ref(),
|
||||||
"Angles",
|
|
||||||
"srf_revolve_angles",
|
"srf_revolve_angles",
|
||||||
format!(
|
format!(
|
||||||
"start {:.6}; revolve {:.6}; draft {:.6}; twist {:.6}",
|
"start {:.6}; revolve {:.6}; draft {:.6}; twist {:.6}",
|
||||||
start_angle, revolve_angle, draft_angle, twist_angle
|
start_angle, revolve_angle, draft_angle, twist_angle
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Draft Distances").as_ref(),
|
||||||
"Draft Distances",
|
|
||||||
"srf_revolve_draft_distances",
|
"srf_revolve_draft_distances",
|
||||||
format!("{draft_start_distance:.6}→{draft_end_distance:.6}"),
|
format!("{draft_start_distance:.6}→{draft_end_distance:.6}"),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Revolve Flags").as_ref(),
|
||||||
"Revolve Flags",
|
|
||||||
"srf_revolve_flags",
|
"srf_revolve_flags",
|
||||||
format!(
|
format!(
|
||||||
"solid {}; close-to-axis {}",
|
"solid {}; close-to-axis {}",
|
||||||
|
|
@ -618,8 +594,7 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
yes_no(*close_to_axis)
|
yes_no(*close_to_axis)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Entity Transform").as_ref(),
|
||||||
"Entity Transform",
|
|
||||||
"srf_revolve_transform",
|
"srf_revolve_transform",
|
||||||
matrix_text(entity_transform),
|
matrix_text(entity_transform),
|
||||||
),
|
),
|
||||||
|
|
@ -634,13 +609,11 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
options,
|
options,
|
||||||
} => {
|
} => {
|
||||||
props.extend([
|
props.extend([
|
||||||
ro(
|
ro(t!("Class Version").as_ref(),
|
||||||
"Class Version",
|
|
||||||
"srf_class_version",
|
"srf_class_version",
|
||||||
class_version.to_string(),
|
class_version.to_string(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Sweep / Path").as_ref(),
|
||||||
"Sweep / Path",
|
|
||||||
"srf_swept_entities",
|
"srf_swept_entities",
|
||||||
format!(
|
format!(
|
||||||
"{} / {}",
|
"{} / {}",
|
||||||
|
|
@ -648,24 +621,20 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
embedded_name(path_entity.as_ref())
|
embedded_name(path_entity.as_ref())
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro("Sweep Options", "srf_sweep_options", sweep_options_text(options)),
|
ro(t!("Sweep Options").as_ref(), "srf_sweep_options", sweep_options_text(options)),
|
||||||
ro(
|
ro(t!("Sweep Transform").as_ref(),
|
||||||
"Sweep Transform",
|
|
||||||
"srf_sweep_transform",
|
"srf_sweep_transform",
|
||||||
matrix_text(sweep_transform),
|
matrix_text(sweep_transform),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Path Transform").as_ref(),
|
||||||
"Path Transform",
|
|
||||||
"srf_path_transform",
|
"srf_path_transform",
|
||||||
matrix_text(path_transform),
|
matrix_text(path_transform),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Sweep Entity Transform").as_ref(),
|
||||||
"Sweep Entity Transform",
|
|
||||||
"srf_sweep_entity_transform",
|
"srf_sweep_entity_transform",
|
||||||
matrix_text(&options.sweep_entity_transform),
|
matrix_text(&options.sweep_entity_transform),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("Path Entity Transform").as_ref(),
|
||||||
"Path Entity Transform",
|
|
||||||
"srf_path_entity_transform",
|
"srf_path_entity_transform",
|
||||||
matrix_text(&options.path_entity_transform),
|
matrix_text(&options.path_entity_transform),
|
||||||
),
|
),
|
||||||
|
|
@ -680,25 +649,23 @@ fn surface_construction_section(surface: &Surface) -> PropSection {
|
||||||
v_vector2,
|
v_vector2,
|
||||||
} => {
|
} => {
|
||||||
props.extend([
|
props.extend([
|
||||||
ro(
|
ro(t!("NURB Version").as_ref(),
|
||||||
"NURB Version",
|
|
||||||
"srf_nurb_version",
|
"srf_nurb_version",
|
||||||
short_170.to_string(),
|
short_170.to_string(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(t!("CV Hull").as_ref(),
|
||||||
"CV Hull",
|
|
||||||
"srf_nurb_cv_hull",
|
"srf_nurb_cv_hull",
|
||||||
yes_no(*cv_hull_display),
|
yes_no(*cv_hull_display),
|
||||||
),
|
),
|
||||||
ro("U Vector 1", "srf_nurb_u1", vector_text(u_vector1)),
|
ro(t!("U Vector 1").as_ref(), "srf_nurb_u1", vector_text(u_vector1)),
|
||||||
ro("V Vector 1", "srf_nurb_v1", vector_text(v_vector1)),
|
ro(t!("V Vector 1").as_ref(), "srf_nurb_v1", vector_text(v_vector1)),
|
||||||
ro("U Vector 2", "srf_nurb_u2", vector_text(u_vector2)),
|
ro(t!("U Vector 2").as_ref(), "srf_nurb_u2", vector_text(u_vector2)),
|
||||||
ro("V Vector 2", "srf_nurb_v2", vector_text(v_vector2)),
|
ro(t!("V Vector 2").as_ref(), "srf_nurb_v2", vector_text(v_vector2)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Surface Construction".into(),
|
title: t!("Surface Construction").into_owned(),
|
||||||
props,
|
props,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use acadrust::entities::Spline;
|
use acadrust::entities::Spline;
|
||||||
|
use crate::t;
|
||||||
use truck_modeling::{
|
use truck_modeling::{
|
||||||
base::{BoundedCurve, ParametricCurve, Vector4},
|
base::{BoundedCurve, ParametricCurve, Vector4},
|
||||||
builder, BSplineCurve, Curve, Edge, KnotVec, NurbsCurve, Point3, Wire,
|
builder, BSplineCurve, Curve, Edge, KnotVec, NurbsCurve, Point3, Wire,
|
||||||
|
|
@ -383,58 +384,58 @@ fn properties(spline: &Spline) -> Vec<PropSection> {
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Data Points".into(),
|
title: t!("Data Points").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Show", "show", show),
|
ro(t!("Show").as_ref(), "show", show),
|
||||||
ro("Degree", "degree", spline.degree.to_string()),
|
ro(t!("Degree").as_ref(), "degree", spline.degree.to_string()),
|
||||||
ro(
|
ro(
|
||||||
"Control Point Count",
|
t!("Control Point Count").as_ref(),
|
||||||
"ctrl_pt_count",
|
"ctrl_pt_count",
|
||||||
spline.control_points.len().to_string(),
|
spline.control_points.len().to_string(),
|
||||||
),
|
),
|
||||||
ro("Control Point", "ctrl_pt_index", "0"),
|
ro(t!("Control Point").as_ref(), "ctrl_pt_index", "0"),
|
||||||
edit(
|
edit(
|
||||||
"Control Point X",
|
t!("Control Point X").as_ref(),
|
||||||
"ctrl_pt_x",
|
"ctrl_pt_x",
|
||||||
cp0.map(|p| p.x).unwrap_or(0.0),
|
cp0.map(|p| p.x).unwrap_or(0.0),
|
||||||
),
|
),
|
||||||
edit(
|
edit(
|
||||||
"Control Point Y",
|
t!("Control Point Y").as_ref(),
|
||||||
"ctrl_pt_y",
|
"ctrl_pt_y",
|
||||||
cp0.map(|p| p.y).unwrap_or(0.0),
|
cp0.map(|p| p.y).unwrap_or(0.0),
|
||||||
),
|
),
|
||||||
edit(
|
edit(
|
||||||
"Control Point Z",
|
t!("Control Point Z").as_ref(),
|
||||||
"ctrl_pt_z",
|
"ctrl_pt_z",
|
||||||
cp0.map(|p| p.z).unwrap_or(0.0),
|
cp0.map(|p| p.z).unwrap_or(0.0),
|
||||||
),
|
),
|
||||||
edit("Weight", "weight", w0.unwrap_or(1.0)),
|
edit(t!("Weight").as_ref(), "weight", w0.unwrap_or(1.0)),
|
||||||
ro("Knot Parameterization", "knot_param", knot_param),
|
ro(t!("Knot Parameterization").as_ref(), "knot_param", knot_param),
|
||||||
ro(
|
ro(
|
||||||
"Fit Point Count",
|
t!("Fit Point Count").as_ref(),
|
||||||
"fit_pt_count",
|
"fit_pt_count",
|
||||||
spline.fit_points.len().to_string(),
|
spline.fit_points.len().to_string(),
|
||||||
),
|
),
|
||||||
ro("Fit Point", "fit_pt_index", "0"),
|
ro(t!("Fit Point").as_ref(), "fit_pt_index", "0"),
|
||||||
edit("Fit Point X", "fit_pt_x", fp0.map(|p| p.x).unwrap_or(0.0)),
|
edit(t!("Fit Point X").as_ref(), "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(t!("Fit Point Y").as_ref(), "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(t!("Fit Point Z").as_ref(), "fit_pt_z", fp0.map(|p| p.z).unwrap_or(0.0)),
|
||||||
edit("Fit Tolerance", "fit_tolerance", spline.fit_tolerance),
|
edit(t!("Fit Tolerance").as_ref(), "fit_tolerance", spline.fit_tolerance),
|
||||||
edit("Start Tangent X", "start_tan_x", spline.begin_tangent.x),
|
edit(t!("Start Tangent X").as_ref(), "start_tan_x", spline.begin_tangent.x),
|
||||||
edit("Start Tangent Y", "start_tan_y", spline.begin_tangent.y),
|
edit(t!("Start Tangent Y").as_ref(), "start_tan_y", spline.begin_tangent.y),
|
||||||
edit("Start Tangent Z", "start_tan_z", spline.begin_tangent.z),
|
edit(t!("Start Tangent Z").as_ref(), "start_tan_z", spline.begin_tangent.z),
|
||||||
edit("End Tangent X", "end_tan_x", spline.end_tangent.x),
|
edit(t!("End Tangent X").as_ref(), "end_tan_x", spline.end_tangent.x),
|
||||||
edit("End Tangent Y", "end_tan_y", spline.end_tangent.y),
|
edit(t!("End Tangent Y").as_ref(), "end_tan_y", spline.end_tangent.y),
|
||||||
edit("End Tangent Z", "end_tan_z", spline.end_tangent.z),
|
edit(t!("End Tangent Z").as_ref(), "end_tan_z", spline.end_tangent.z),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Closed", "closed", yes_no(closed)),
|
ro(t!("Closed").as_ref(), "closed", yes_no(closed)),
|
||||||
ro("Planar", "planar", yes_no(spline.flags.planar)),
|
ro(t!("Planar").as_ref(), "planar", yes_no(spline.flags.planar)),
|
||||||
ro("Length", "length", format!("{length:.4}")),
|
ro(t!("Length").as_ref(), "length", format!("{length:.4}")),
|
||||||
ro("Area", "area", area),
|
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::model::object::{GripApply, GripDef, PropSection, Property, PropValue};
|
||||||
use crate::scene::view::transform;
|
use crate::scene::view::transform;
|
||||||
use crate::scene::model::wire_model::SnapHint;
|
use crate::scene::model::wire_model::SnapHint;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
fn v3(v: &acadrust::types::Vector3) -> Vec3 {
|
fn v3(v: &acadrust::types::Vector3) -> Vec3 {
|
||||||
Vec3::new(v.x as f32, v.y as f32, v.z as f32)
|
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(),
|
_ => "(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 {
|
Property {
|
||||||
label: label.into(),
|
label: label.into(),
|
||||||
field,
|
field,
|
||||||
|
|
@ -1806,93 +1807,93 @@ impl PropertyEditable for Table {
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Table".into(),
|
title: t!("Table").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro(
|
ro(
|
||||||
"Table style",
|
t!("Table style").as_ref(),
|
||||||
"tbl_style_handle",
|
"tbl_style_handle",
|
||||||
fmt_h(&self.table_style_handle),
|
fmt_h(&self.table_style_handle),
|
||||||
),
|
),
|
||||||
ro("Rows", "tbl_rows", self.rows.len().to_string()),
|
ro(t!("Rows").as_ref(), "tbl_rows", self.rows.len().to_string()),
|
||||||
ro("Columns", "tbl_cols", self.columns.len().to_string()),
|
ro(t!("Columns").as_ref(), "tbl_cols", self.columns.len().to_string()),
|
||||||
ro("Contents", "tbl_contents", content_count.to_string()),
|
ro(t!("Contents").as_ref(), "tbl_contents", content_count.to_string()),
|
||||||
ro(
|
ro(
|
||||||
"Block contents",
|
t!("Block contents").as_ref(),
|
||||||
"tbl_block_contents",
|
"tbl_block_contents",
|
||||||
block_content_count.to_string(),
|
block_content_count.to_string(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Field contents",
|
t!("Field contents").as_ref(),
|
||||||
"tbl_field_contents",
|
"tbl_field_contents",
|
||||||
field_content_count.to_string(),
|
field_content_count.to_string(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Merged ranges",
|
t!("Merged ranges").as_ref(),
|
||||||
"tbl_merged_ranges",
|
"tbl_merged_ranges",
|
||||||
self.merged_ranges.len().to_string(),
|
self.merged_ranges.len().to_string(),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Linked cells",
|
t!("Linked cells").as_ref(),
|
||||||
"tbl_linked_cells",
|
"tbl_linked_cells",
|
||||||
linked_cell_count.to_string(),
|
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(
|
ro(
|
||||||
"Table width",
|
t!("Table width").as_ref(),
|
||||||
"tbl_width",
|
"tbl_width",
|
||||||
format!("{:.4}", self.total_width()),
|
format!("{:.4}", self.total_width()),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Table height",
|
t!("Table height").as_ref(),
|
||||||
"tbl_height",
|
"tbl_height",
|
||||||
format!("{:.4}", self.total_height()),
|
format!("{:.4}", self.total_height()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Table Breaks".into(),
|
title: t!("Table Breaks").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
toggle(
|
toggle(
|
||||||
"Enabled",
|
t!("Enabled").as_ref(),
|
||||||
"tbl_break_enabled",
|
"tbl_break_enabled",
|
||||||
self.break_options.contains(BreakOptionFlags::ENABLE_BREAKS),
|
self.break_options.contains(BreakOptionFlags::ENABLE_BREAKS),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Direction",
|
t!("Direction").as_ref(),
|
||||||
"tbl_break_direction",
|
"tbl_break_direction",
|
||||||
format!("{:?}", self.break_flow_direction),
|
format!("{:?}", self.break_flow_direction),
|
||||||
),
|
),
|
||||||
toggle(
|
toggle(
|
||||||
"Repeat top labels",
|
t!("Repeat top labels").as_ref(),
|
||||||
"tbl_break_repeat_top",
|
"tbl_break_repeat_top",
|
||||||
self.break_options
|
self.break_options
|
||||||
.contains(BreakOptionFlags::REPEAT_TOP_LABELS),
|
.contains(BreakOptionFlags::REPEAT_TOP_LABELS),
|
||||||
),
|
),
|
||||||
toggle(
|
toggle(
|
||||||
"Repeat bottom labels",
|
t!("Repeat bottom labels").as_ref(),
|
||||||
"tbl_break_repeat_bottom",
|
"tbl_break_repeat_bottom",
|
||||||
self.break_options
|
self.break_options
|
||||||
.contains(BreakOptionFlags::REPEAT_BOTTOM_LABELS),
|
.contains(BreakOptionFlags::REPEAT_BOTTOM_LABELS),
|
||||||
),
|
),
|
||||||
toggle(
|
toggle(
|
||||||
"Manual positions",
|
t!("Manual positions").as_ref(),
|
||||||
"tbl_break_manual_positions",
|
"tbl_break_manual_positions",
|
||||||
self.break_options
|
self.break_options
|
||||||
.contains(BreakOptionFlags::ALLOW_MANUAL_POSITIONS),
|
.contains(BreakOptionFlags::ALLOW_MANUAL_POSITIONS),
|
||||||
),
|
),
|
||||||
toggle(
|
toggle(
|
||||||
"Manual heights",
|
t!("Manual heights").as_ref(),
|
||||||
"tbl_break_manual_heights",
|
"tbl_break_manual_heights",
|
||||||
self.break_options
|
self.break_options
|
||||||
.contains(BreakOptionFlags::ALLOW_MANUAL_HEIGHTS),
|
.contains(BreakOptionFlags::ALLOW_MANUAL_HEIGHTS),
|
||||||
),
|
),
|
||||||
ro(
|
ro(
|
||||||
"Segments",
|
t!("Segments").as_ref(),
|
||||||
"tbl_break_segments",
|
"tbl_break_segments",
|
||||||
self.break_ranges.len().max(self.break_data.len()).to_string(),
|
self.break_ranges.len().max(self.break_data.len()).to_string(),
|
||||||
),
|
),
|
||||||
ro("Break heights", "tbl_break_height", break_heights),
|
ro(t!("Break heights").as_ref(), "tbl_break_height", break_heights),
|
||||||
edit("Spacing", "tbl_break_spacing", self.break_spacing),
|
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::text::lff;
|
||||||
use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property};
|
use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property};
|
||||||
use crate::scene::model::wire_model::SnapHint;
|
use crate::scene::model::wire_model::SnapHint;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
/// Combined single-line-text justification (horizontal × vertical) shown as one
|
/// Combined single-line-text justification (horizontal × vertical) shown as one
|
||||||
/// dropdown value. Horizontal-only modes (Aligned/Middle/Fit) ignore the
|
/// 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![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Text".into(),
|
title: t!("Text").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Contents".into(),
|
label: t!("Contents").into_owned(),
|
||||||
field: "content",
|
field: "content",
|
||||||
value: PropValue::EditText(t.value.clone()),
|
value: PropValue::EditText(t.value.clone()),
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Style".into(),
|
label: t!("Style").into_owned(),
|
||||||
field: "style",
|
field: "style",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: if t.style.trim().is_empty() {
|
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(),
|
options: text_style_names.to_vec(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ro("Annotative", "annotative", "No"),
|
ro(t!("Annotative").as_ref(), "annotative", "No"),
|
||||||
Property {
|
Property {
|
||||||
label: "Justify".into(),
|
label: t!("Justify").into_owned(),
|
||||||
field: "justify",
|
field: "justify",
|
||||||
value: PropValue::Choice {
|
value: PropValue::Choice {
|
||||||
selected: text_justify_str(
|
selected: text_justify_str(
|
||||||
|
|
@ -324,28 +325,28 @@ fn properties(t: &Text, text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
edit("Height", "height", t.height),
|
edit(t!("Height").as_ref(), "height", t.height),
|
||||||
edit_angle("Rotation", "rotation", t.rotation.to_degrees()),
|
edit_angle(t!("Rotation").as_ref(), "rotation", t.rotation.to_degrees()),
|
||||||
edit("Width factor", "width_factor", t.width_factor),
|
edit(t!("Width factor").as_ref(), "width_factor", t.width_factor),
|
||||||
edit_angle("Obliquing", "oblique_angle", t.oblique_angle.to_degrees()),
|
edit_angle(t!("Obliquing").as_ref(), "oblique_angle", t.oblique_angle.to_degrees()),
|
||||||
num_row("Text alignment X", "align_x", ax, align_editable),
|
num_row(t!("Text alignment X").as_ref(), "align_x", ax, align_editable),
|
||||||
num_row("Text alignment Y", "align_y", ay, align_editable),
|
num_row(t!("Text alignment Y").as_ref(), "align_y", ay, align_editable),
|
||||||
num_row("Text alignment Z", "align_z", az, align_editable),
|
num_row(t!("Text alignment Z").as_ref(), "align_z", az, align_editable),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
num_row("Position X", "ins_x", t.insertion_point.x, pos_editable),
|
num_row(t!("Position X").as_ref(), "ins_x", t.insertion_point.x, pos_editable),
|
||||||
num_row("Position Y", "ins_y", t.insertion_point.y, pos_editable),
|
num_row(t!("Position Y").as_ref(), "ins_y", t.insertion_point.y, pos_editable),
|
||||||
num_row("Position Z", "ins_z", t.insertion_point.z, pos_editable),
|
num_row(t!("Position Z").as_ref(), "ins_z", t.insertion_point.z, pos_editable),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
Property {
|
Property {
|
||||||
label: "Upside down".into(),
|
label: t!("Upside down").into_owned(),
|
||||||
field: "upside_down",
|
field: "upside_down",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "upside_down",
|
field: "upside_down",
|
||||||
|
|
@ -353,7 +354,7 @@ fn properties(t: &Text, text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Backward".into(),
|
label: t!("Backward").into_owned(),
|
||||||
field: "backward",
|
field: "backward",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "backward",
|
field: "backward",
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ use crate::scene::model::object::{GripApply, GripDef, PropSection};
|
||||||
use crate::scene::model::wire_model::SnapHint;
|
use crate::scene::model::wire_model::SnapHint;
|
||||||
use crate::scene::text::lff;
|
use crate::scene::text::lff;
|
||||||
use crate::scene::view::transform;
|
use crate::scene::view::transform;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
// ── GDT text parser ───────────────────────────────────────────────────────────
|
// ── GDT text parser ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -541,25 +542,25 @@ impl PropertyEditable for Tolerance {
|
||||||
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Text".into(),
|
title: t!("Text").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro("Text style", "tol_text_style", String::new()),
|
ro(t!("Text style").as_ref(), "tol_text_style", String::new()),
|
||||||
edit("Text height", "tol_text_height", self.text_height),
|
edit(t!("Text height").as_ref(), "tol_text_height", self.text_height),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Position X", "tol_ix", self.insertion_point.x),
|
edit(t!("Position X").as_ref(), "tol_ix", self.insertion_point.x),
|
||||||
edit("Position Y", "tol_iy", self.insertion_point.y),
|
edit(t!("Position Y").as_ref(), "tol_iy", self.insertion_point.y),
|
||||||
edit("Position Z", "tol_iz", self.insertion_point.z),
|
edit(t!("Position Z").as_ref(), "tol_iz", self.insertion_point.z),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
ro(
|
ro(
|
||||||
"Dimension style",
|
t!("Dimension style").as_ref(),
|
||||||
"tol_dim_style",
|
"tol_dim_style",
|
||||||
if self.dimension_style_name.is_empty() {
|
if self.dimension_style_name.is_empty() {
|
||||||
"(default)".to_string()
|
"(default)".to_string()
|
||||||
|
|
@ -567,9 +568,9 @@ impl PropertyEditable for Tolerance {
|
||||||
self.dimension_style_name.clone()
|
self.dimension_style_name.clone()
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
edit("Direction X", "tol_dir_x", self.direction.x),
|
edit(t!("Direction X").as_ref(), "tol_dir_x", self.direction.x),
|
||||||
edit("Direction Y", "tol_dir_y", self.direction.y),
|
edit(t!("Direction Y").as_ref(), "tol_dir_y", self.direction.y),
|
||||||
edit("Direction Z", "tol_dir_z", self.direction.z),
|
edit(t!("Direction Z").as_ref(), "tol_dir_z", self.direction.z),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
// Props: position, scales, rotation, contrast, fade, flags.
|
// Props: position, scales, rotation, contrast, fade, flags.
|
||||||
|
|
||||||
use acadrust::entities::{Underlay, UnderlayDisplayFlags};
|
use acadrust::entities::{Underlay, UnderlayDisplayFlags};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
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};
|
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![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Geometry".into(),
|
title: t!("Geometry").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Position X", "ul_ix", self.insertion_point.x),
|
edit(t!("Position X").as_ref(), "ul_ix", self.insertion_point.x),
|
||||||
edit("Position Y", "ul_iy", self.insertion_point.y),
|
edit(t!("Position Y").as_ref(), "ul_iy", self.insertion_point.y),
|
||||||
edit("Position Z", "ul_iz", self.insertion_point.z),
|
edit(t!("Position Z").as_ref(), "ul_iz", self.insertion_point.z),
|
||||||
edit("Scale X", "ul_sx", self.x_scale),
|
edit(t!("Scale X").as_ref(), "ul_sx", self.x_scale),
|
||||||
edit("Scale Y", "ul_sy", self.y_scale),
|
edit(t!("Scale Y").as_ref(), "ul_sy", self.y_scale),
|
||||||
edit("Scale Z", "ul_sz", self.z_scale),
|
edit(t!("Scale Z").as_ref(), "ul_sz", self.z_scale),
|
||||||
ro("Width", "ul_width", format!("{:.4}", width)),
|
ro(t!("Width").as_ref(), "ul_width", format!("{:.4}", width)),
|
||||||
ro("Height", "ul_height", format!("{:.4}", height)),
|
ro(t!("Height").as_ref(), "ul_height", format!("{:.4}", height)),
|
||||||
edit_angle("Rotation", "ul_rot", self.rotation.to_degrees()),
|
edit_angle(t!("Rotation").as_ref(), "ul_rot", self.rotation.to_degrees()),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Underlay Adjust".into(),
|
title: t!("Underlay Adjust").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit("Contrast", "ul_contrast", self.contrast as f64),
|
edit(t!("Contrast").as_ref(), "ul_contrast", self.contrast as f64),
|
||||||
edit("Fade", "ul_fade", self.fade as f64),
|
edit(t!("Fade").as_ref(), "ul_fade", self.fade as f64),
|
||||||
Property {
|
Property {
|
||||||
label: "Monochrome".into(),
|
label: t!("Monochrome").into_owned(),
|
||||||
field: "ul_mono",
|
field: "ul_mono",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "ul_mono",
|
field: "ul_mono",
|
||||||
|
|
@ -251,7 +252,7 @@ impl PropertyEditable for Underlay {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Adjust Colors for Background".into(),
|
label: t!("Adjust Colors for Background").into_owned(),
|
||||||
field: "ul_adjust_bg",
|
field: "ul_adjust_bg",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "ul_adjust_bg",
|
field: "ul_adjust_bg",
|
||||||
|
|
@ -261,14 +262,14 @@ impl PropertyEditable for Underlay {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Misc".into(),
|
title: t!("Misc").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
// Underlay name/path/layers live on the separate
|
// Underlay name/path/layers live on the separate
|
||||||
// UnderlayDefinition object, not reachable from the entity.
|
// UnderlayDefinition object, not reachable from the entity.
|
||||||
ro("Underlay name", "ul_name", String::new()),
|
ro(t!("Underlay name").as_ref(), "ul_name", String::new()),
|
||||||
ro("Underlay path", "ul_path", String::new()),
|
ro(t!("Underlay path").as_ref(), "ul_path", String::new()),
|
||||||
Property {
|
Property {
|
||||||
label: "Show underlay".into(),
|
label: t!("Show underlay").into_owned(),
|
||||||
field: "ul_on",
|
field: "ul_on",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "ul_on",
|
field: "ul_on",
|
||||||
|
|
@ -276,7 +277,7 @@ impl PropertyEditable for Underlay {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Clipping".into(),
|
label: t!("Clipping").into_owned(),
|
||||||
field: "ul_clip",
|
field: "ul_clip",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "ul_clip",
|
field: "ul_clip",
|
||||||
|
|
@ -284,14 +285,14 @@ impl PropertyEditable for Underlay {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Property {
|
Property {
|
||||||
label: "Show clipped".into(),
|
label: t!("Show clipped").into_owned(),
|
||||||
field: "ul_clip_inverted",
|
field: "ul_clip_inverted",
|
||||||
value: PropValue::BoolToggle {
|
value: PropValue::BoolToggle {
|
||||||
field: "ul_clip_inverted",
|
field: "ul_clip_inverted",
|
||||||
value: self.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 acadrust::entities::{SectionSymbol, ViewBorder};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::EntityTransform;
|
use crate::command::EntityTransform;
|
||||||
use crate::entities::common::{edit_angle_prop, edit_prop, parse_f64, ro_prop, square_grip};
|
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");
|
.join("\n");
|
||||||
vec![
|
vec![
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Section Symbol".into(),
|
title: t!("Section Symbol").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit_prop("Symbol Scale", "section_scale", self.symbol_scale),
|
edit_prop(t!("Symbol Scale").as_ref(), "section_scale", self.symbol_scale),
|
||||||
ro_prop(
|
ro_prop(t!("View Symbol Version").as_ref(),
|
||||||
"View Symbol Version",
|
|
||||||
"section_view_version",
|
"section_view_version",
|
||||||
self.view_symbol_version.to_string(),
|
self.view_symbol_version.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop("Version", "section_version", self.version.to_string()),
|
ro_prop(t!("Version").as_ref(), "section_version", self.version.to_string()),
|
||||||
ro_prop(
|
ro_prop(t!("Style").as_ref(),
|
||||||
"Style",
|
|
||||||
"section_style",
|
"section_style",
|
||||||
handle_text(self.style_handle),
|
handle_text(self.style_handle),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("View Representation").as_ref(),
|
||||||
"View Representation",
|
|
||||||
"section_view_rep",
|
"section_view_rep",
|
||||||
handle_text(self.view_rep_handle),
|
handle_text(self.view_rep_handle),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("View Symbol Flags").as_ref(),
|
||||||
"View Symbol Flags",
|
|
||||||
"section_view_flags",
|
"section_view_flags",
|
||||||
self.raw_view_symbol_70.to_string(),
|
self.raw_view_symbol_70.to_string(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Point Count").as_ref(),
|
||||||
"Point Count",
|
|
||||||
"section_point_count",
|
"section_point_count",
|
||||||
self.points.len().to_string(),
|
self.points.len().to_string(),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Stored Point Counts").as_ref(),
|
||||||
"Stored Point Counts",
|
|
||||||
"section_raw_counts",
|
"section_raw_counts",
|
||||||
format!(
|
format!(
|
||||||
"{}, {}, flags {}",
|
"{}, {}, flags {}",
|
||||||
|
|
@ -122,12 +117,12 @@ impl PropertyEditable for SectionSymbol {
|
||||||
self.raw_flags_90
|
self.raw_flags_90
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ro_prop("Identifier", "section_label", self.label.clone()),
|
ro_prop(t!("Identifier").as_ref(), "section_label", self.label.clone()),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
PropSection {
|
PropSection {
|
||||||
title: "Section Points".into(),
|
title: t!("Section Points").into_owned(),
|
||||||
props: vec![ro_prop("Records", "section_points", point_data)],
|
props: vec![ro_prop(t!("Records").as_ref(), "section_points", point_data)],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -197,34 +192,29 @@ impl Grippable for ViewBorder {
|
||||||
impl PropertyEditable for ViewBorder {
|
impl PropertyEditable for ViewBorder {
|
||||||
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
||||||
vec![PropSection {
|
vec![PropSection {
|
||||||
title: "Drawing View".into(),
|
title: t!("Drawing View").into_owned(),
|
||||||
props: vec![
|
props: vec![
|
||||||
edit_prop("Center X", "view_border_x", self.center[0]),
|
edit_prop(t!("Center X").as_ref(), "view_border_x", self.center[0]),
|
||||||
edit_prop("Center Y", "view_border_y", self.center[1]),
|
edit_prop(t!("Center Y").as_ref(), "view_border_y", self.center[1]),
|
||||||
ro_prop(
|
ro_prop(t!("Width").as_ref(),
|
||||||
"Width",
|
|
||||||
"view_border_width",
|
"view_border_width",
|
||||||
format!("{:.6}", self.max[0] - self.min[0]),
|
format!("{:.6}", self.max[0] - self.min[0]),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Height").as_ref(),
|
||||||
"Height",
|
|
||||||
"view_border_height",
|
"view_border_height",
|
||||||
format!("{:.6}", self.max[1] - self.min[1]),
|
format!("{:.6}", self.max[1] - self.min[1]),
|
||||||
),
|
),
|
||||||
edit_prop("Scale", "view_border_scale", self.scale),
|
edit_prop(t!("Scale").as_ref(), "view_border_scale", self.scale),
|
||||||
edit_angle_prop(
|
edit_angle_prop(t!("Rotation").as_ref(),
|
||||||
"Rotation",
|
|
||||||
"view_border_rotation",
|
"view_border_rotation",
|
||||||
self.rotation_angle.to_degrees(),
|
self.rotation_angle.to_degrees(),
|
||||||
),
|
),
|
||||||
ro_prop("Version", "view_border_version", self.version.to_string()),
|
ro_prop(t!("Version").as_ref(), "view_border_version", self.version.to_string()),
|
||||||
ro_prop(
|
ro_prop(t!("Active Viewport").as_ref(),
|
||||||
"Active Viewport",
|
|
||||||
"view_border_viewport",
|
"view_border_viewport",
|
||||||
handle_text(self.active_viewport),
|
handle_text(self.active_viewport),
|
||||||
),
|
),
|
||||||
ro_prop(
|
ro_prop(t!("Scale Object").as_ref(),
|
||||||
"Scale Object",
|
|
||||||
"view_border_scale_handle",
|
"view_border_scale_handle",
|
||||||
handle_text(self.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")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use i18n_embed::WebLanguageRequester;
|
use i18n_embed::WebLanguageRequester;
|
||||||
use rust_embed::RustEmbed;
|
use rust_embed::RustEmbed;
|
||||||
|
use std::borrow::Cow;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
|
#[path = "locale_catalog.rs"]
|
||||||
|
mod locale_catalog;
|
||||||
|
|
||||||
#[derive(RustEmbed)]
|
#[derive(RustEmbed)]
|
||||||
#[folder = "locales/"]
|
#[folder = "locales/"]
|
||||||
struct Localizations;
|
struct Localizations;
|
||||||
|
|
@ -123,6 +127,107 @@ pub fn set_language(language: Language) -> Result<(), i18n_embed::I18nEmbedError
|
||||||
load_language(loader(), language)
|
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
|
/// Built-in ribbon modules have stable ids; plug-ins keep their supplied title
|
||||||
/// until they provide their own localization bundle.
|
/// until they provide their own localization bundle.
|
||||||
pub fn ribbon_module_title(id: &str, fallback: &str) -> String {
|
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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_aligned.svg"));
|
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 {
|
fn prompt(&self) -> String {
|
||||||
if self.awaiting_text {
|
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 {
|
if self.awaiting_angle {
|
||||||
return "DIMALIGNED Specify text angle (degrees):".into();
|
return t!("DIMALIGNED Specify text angle (degrees):").into_owned();
|
||||||
}
|
}
|
||||||
match self.step {
|
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(_) => {
|
Step::Second(_) => {
|
||||||
"DIMALIGNED Specify second extension line origin [Text/Angle]:".into()
|
t!("DIMALIGNED Specify second extension line origin [Text/Angle]:").into_owned()
|
||||||
}
|
}
|
||||||
Step::DimLine { .. } => {
|
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::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
use glam::{DVec3, Vec3};
|
use glam::{DVec3, Vec3};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_angular.svg"));
|
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 {
|
fn prompt(&self) -> String {
|
||||||
match self.step {
|
match self.step {
|
||||||
Step::Vertex => "DIMANGULAR Specify angle vertex:".into(),
|
Step::Vertex => t!("DIMANGULAR Specify angle vertex:").into_owned(),
|
||||||
Step::FirstRay(_) => "DIMANGULAR Specify first extension line point:".into(),
|
Step::FirstRay(_) => {
|
||||||
Step::SecondRay { .. } => "DIMANGULAR Specify second extension line point:".into(),
|
t!("DIMANGULAR Specify first extension line point:").into_owned()
|
||||||
Step::ArcPoint { .. } => "DIMANGULAR Specify dimension arc location:".into(),
|
}
|
||||||
|
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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/ddedit.svg"));
|
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/ddedit.svg"));
|
||||||
|
|
||||||
|
|
@ -38,7 +39,7 @@ impl CadCommand for DdeditCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
"DDEDIT Select text entity:".into()
|
t!("DDEDIT Select text entity:").into_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn needs_entity_pick(&self) -> bool {
|
fn needs_entity_pick(&self) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ use glam::{DVec3, Vec3};
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_diameter.svg"));
|
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 {
|
fn prompt(&self) -> String {
|
||||||
if self.awaiting_text {
|
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 {
|
if self.awaiting_angle {
|
||||||
return "DIMDIAMETER Specify text angle (degrees):".into();
|
return t!("DIMDIAMETER Specify text angle (degrees):").into_owned();
|
||||||
}
|
}
|
||||||
match self.step {
|
match self.step {
|
||||||
Step::CenterPoint => "DIMDIAMETER Specify center point:".into(),
|
Step::CenterPoint => t!("DIMDIAMETER Specify center point:").into_owned(),
|
||||||
Step::ArcPoint(_) => "DIMDIAMETER Specify point on circle:".into(),
|
Step::ArcPoint(_) => t!("DIMDIAMETER Specify point on circle:").into_owned(),
|
||||||
Step::TextPoint { .. } => {
|
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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_baseline.svg"));
|
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 {
|
fn prompt(&self) -> String {
|
||||||
if !self.ready {
|
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 {
|
} 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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_continue.svg"));
|
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 {
|
fn prompt(&self) -> String {
|
||||||
if !self.ready {
|
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 {
|
} 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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_break.svg"));
|
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 {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
Step::PickDim => "DIMBREAK Select dimension to break:".into(),
|
Step::PickDim => t!("DIMBREAK Select dimension to break:").into_owned(),
|
||||||
Step::PickCrossing { .. } => {
|
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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_edit.svg"));
|
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 {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
Step::PickDim => "DIMEDIT Select dimension:".into(),
|
Step::PickDim => t!("DIMEDIT Select dimension:").into_owned(),
|
||||||
Step::EnterText { .. } => {
|
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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_jog.svg"));
|
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 {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
Step::PickDim => "DIMJOGLINE Select linear or aligned dimension:".into(),
|
Step::PickDim => t!("DIMJOGLINE Select linear or aligned dimension:").into_owned(),
|
||||||
Step::PickJogPos { .. } => "DIMJOGLINE Specify jog location:".into(),
|
Step::PickJogPos { .. } => t!("DIMJOGLINE Specify jog location:").into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ use glam::DVec3;
|
||||||
|
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_space.svg"));
|
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 {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
Step::PickBase => "DIMSPACE Select base dimension:".into(),
|
Step::PickBase => t!("DIMSPACE Select base dimension:").into_owned(),
|
||||||
Step::PickOthers { others, .. } => format!(
|
Step::PickOthers { others, .. } => t!(
|
||||||
"DIMSPACE Select dimension to space ({} selected, Enter when done):",
|
"DIMSPACE Select dimension to space (%{count} selected, Enter when done):",
|
||||||
others.len()
|
count = others.len()
|
||||||
),
|
)
|
||||||
Step::EnterSpacing { .. } => "DIMSPACE Enter value (0 = auto):".into(),
|
.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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_tedit.svg"));
|
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 {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
Step::PickDim => "DIMTEDIT Select dimension:".into(),
|
Step::PickDim => t!("DIMTEDIT Select dimension:").into_owned(),
|
||||||
Step::PickTextPos { .. } => "DIMTEDIT Specify new location for dimension text:".into(),
|
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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/leader.svg"));
|
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/leader.svg"));
|
||||||
|
|
||||||
|
|
@ -52,12 +53,13 @@ impl CadCommand for LeaderCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
if self.verts.is_empty() {
|
if self.verts.is_empty() {
|
||||||
"LEADER Specify arrowhead point:".into()
|
t!("LEADER Specify arrowhead point:").into_owned()
|
||||||
} else {
|
} else {
|
||||||
format!(
|
t!(
|
||||||
"LEADER Specify next point [{} pts — Enter to place text]:",
|
"LEADER Specify next point [%{count} pts — Enter to place text]:",
|
||||||
self.verts.len()
|
count = self.verts.len()
|
||||||
)
|
)
|
||||||
|
.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use crate::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
use glam::{DVec3, Mat4, Vec3};
|
use glam::{DVec3, Mat4, Vec3};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
/// World-space measurement axis for a linear dimension between `first` and
|
/// 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).
|
/// `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 {
|
fn prompt(&self) -> String {
|
||||||
if self.awaiting_text {
|
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 {
|
if self.awaiting_angle {
|
||||||
return "DIMLINEAR Specify text angle (degrees):".into();
|
return t!("DIMLINEAR Specify text angle (degrees):").into_owned();
|
||||||
}
|
}
|
||||||
match self.step {
|
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(_) => {
|
Step::SecondPoint(_) => {
|
||||||
"DIMLINEAR Specify second extension line origin [Text/Angle]:".into()
|
t!("DIMLINEAR Specify second extension line origin [Text/Angle]:").into_owned()
|
||||||
}
|
}
|
||||||
Step::DimensionLine { .. } => {
|
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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mleader.svg"));
|
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mleader.svg"));
|
||||||
|
|
||||||
|
|
@ -47,12 +48,13 @@ impl CadCommand for MLeaderCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
if self.verts.is_empty() {
|
if self.verts.is_empty() {
|
||||||
"MLEADER Specify arrowhead point:".into()
|
t!("MLEADER Specify arrowhead point:").into_owned()
|
||||||
} else {
|
} else {
|
||||||
format!(
|
t!(
|
||||||
"MLEADER Specify next point [{} pts — Enter to place text]:",
|
"MLEADER Specify next point [%{count} pts — Enter to place text]:",
|
||||||
self.verts.len()
|
count = self.verts.len()
|
||||||
)
|
)
|
||||||
|
.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ use glam::{DVec3, Vec3};
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
// ── MLEADERADD ────────────────────────────────────────────────────────────────
|
// ── MLEADERADD ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -60,12 +61,15 @@ impl CadCommand for MLeaderAddCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
AddStep::PickMLeader => "MLEADERADD Select a multileader:".into(),
|
AddStep::PickMLeader => t!("MLEADERADD Select a multileader:").into_owned(),
|
||||||
AddStep::PickArrowhead { .. } => "MLEADERADD Specify arrowhead location:".into(),
|
AddStep::PickArrowhead { .. } => {
|
||||||
AddStep::CollectPoints { pts, .. } => format!(
|
t!("MLEADERADD Specify arrowhead location:").into_owned()
|
||||||
"MLEADERADD Specify next leader point ({} pts, Enter to finish):",
|
}
|
||||||
pts.len()
|
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 {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
RemoveStep::PickMLeader => "MLEADERREMOVE Select a multileader:".into(),
|
RemoveStep::PickMLeader => t!("MLEADERREMOVE Select a multileader:").into_owned(),
|
||||||
RemoveStep::PickLeaderToRemove { .. } => {
|
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 {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
AlignStep::Gathering => {
|
AlignStep::Gathering => {
|
||||||
"MLEADERALIGN Select multileaders to align (Enter when done):".into()
|
t!("MLEADERALIGN Select multileaders to align (Enter when done):").into_owned()
|
||||||
}
|
}
|
||||||
AlignStep::PickDirection { .. } => {
|
AlignStep::PickDirection { .. } => {
|
||||||
"MLEADERALIGN Specify direction — pick start point:".into()
|
t!("MLEADERALIGN Specify direction — pick start point:").into_owned()
|
||||||
}
|
}
|
||||||
AlignStep::PickEndDir { .. } => {
|
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 {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
CollectStep::Gathering => {
|
CollectStep::Gathering => {
|
||||||
"MLEADERCOLLECT Select multileaders to collect (Enter when done):".into()
|
t!("MLEADERCOLLECT Select multileaders to collect (Enter when done):").into_owned()
|
||||||
}
|
}
|
||||||
CollectStep::PickLocation { .. } => {
|
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::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
use glam::DVec3;
|
use glam::DVec3;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mtext.svg"));
|
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mtext.svg"));
|
||||||
|
|
||||||
|
|
@ -37,7 +38,7 @@ impl CadCommand for MTextCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub fn tool() -> ToolDef {
|
pub fn tool() -> ToolDef {
|
||||||
ToolDef {
|
ToolDef {
|
||||||
|
|
@ -50,8 +51,8 @@ impl CadCommand for OrdinateDimCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.step {
|
match self.step {
|
||||||
Step::FeaturePoint => "DIMORDINATE Specify feature location:".into(),
|
Step::FeaturePoint => t!("DIMORDINATE Specify feature location:").into_owned(),
|
||||||
Step::LeaderEndpoint { .. } => "DIMORDINATE Specify leader endpoint:".into(),
|
Step::LeaderEndpoint { .. } => t!("DIMORDINATE Specify leader endpoint:").into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ use glam::DVec3;
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/qdim.svg"));
|
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/qdim.svg"));
|
||||||
|
|
||||||
|
|
@ -50,8 +51,10 @@ impl CadCommand for QdimCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
Step::Gathering => "QDIM Select geometry to dimension (Enter when done):".into(),
|
Step::Gathering => {
|
||||||
Step::PlaceLine { .. } => "QDIM Specify dimension line position:".into(),
|
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::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
use glam::{DVec3, Vec3};
|
use glam::{DVec3, Vec3};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_radius.svg"));
|
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 {
|
fn prompt(&self) -> String {
|
||||||
if self.awaiting_text {
|
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 {
|
if self.awaiting_angle {
|
||||||
return "DIMRADIUS Specify text angle (degrees):".into();
|
return t!("DIMRADIUS Specify text angle (degrees):").into_owned();
|
||||||
}
|
}
|
||||||
match self.step {
|
match self.step {
|
||||||
Step::CenterPoint => "DIMRADIUS Specify center point:".into(),
|
Step::CenterPoint => t!("DIMRADIUS Specify center point:").into_owned(),
|
||||||
Step::RadiusPoint(_) => "DIMRADIUS Specify radius point:".into(),
|
Step::RadiusPoint(_) => t!("DIMRADIUS Specify radius point:").into_owned(),
|
||||||
Step::TextPoint { .. } => {
|
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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/table.svg"));
|
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/table.svg"));
|
||||||
|
|
||||||
|
|
@ -57,13 +58,23 @@ impl CadCommand for TableCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
Step::Columns => format!("TABLE Enter number of columns [{DEFAULT_COLS}]:"),
|
Step::Columns => t!(
|
||||||
Step::Rows { cols } => format!(
|
"TABLE Enter number of columns [%{cols}]:",
|
||||||
"TABLE Enter number of rows (incl. header) [{DEFAULT_ROWS}] ({cols} cols):"
|
cols = DEFAULT_COLS
|
||||||
),
|
)
|
||||||
Step::Insertion { cols, rows } => {
|
.into_owned(),
|
||||||
format!("TABLE Specify insertion point [{cols}×{rows}]:")
|
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::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
use glam::DVec3;
|
use glam::DVec3;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/text.svg"));
|
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/text.svg"));
|
||||||
|
|
||||||
|
|
@ -37,7 +38,7 @@ impl CadCommand for TextCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
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 glam::DVec3;
|
||||||
|
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
/// Parse a TEXTEDITMODE value. Accepts `0`/`m`/`multiple`/`false` (Multiple → false)
|
/// Parse a TEXTEDITMODE value. Accepts `0`/`m`/`multiple`/`false` (Multiple → false)
|
||||||
/// and `1`/`s`/`single`/`true` (Single → true), case-insensitive. Returns `None`
|
/// and `1`/`s`/`single`/`true` (Single → true), case-insensitive. Returns `None`
|
||||||
|
|
@ -69,24 +70,27 @@ impl CadCommand for TexteditCommand {
|
||||||
match self.step {
|
match self.step {
|
||||||
Step::PickObject => {
|
Step::PickObject => {
|
||||||
if self.edit_count == 0 {
|
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 {
|
} 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 => {
|
Step::EnterMode => {
|
||||||
let prefix = if self.invalid_mode {
|
let prefix = if self.invalid_mode {
|
||||||
"Requires Single or Multiple. "
|
format!("{} ", t!("Requires Single or Multiple."))
|
||||||
} else {
|
} else {
|
||||||
""
|
String::new()
|
||||||
};
|
};
|
||||||
format!(
|
let mode = match self.mode {
|
||||||
"{prefix}TEXTEDIT Enter text edit mode [Single/Multiple] <{}>:",
|
TextEditMode::Single => t!("Single"),
|
||||||
match self.mode {
|
TextEditMode::Multiple => t!("Multiple"),
|
||||||
TextEditMode::Single => "Single",
|
};
|
||||||
TextEditMode::Multiple => "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 {
|
fn prompt(&self) -> String {
|
||||||
let v = if self.current { 1 } else { 0 };
|
let v = if self.current { 1 } else { 0 };
|
||||||
let prefix = if self.invalid {
|
let prefix = if self.invalid {
|
||||||
"Requires 0 OR 1 OR MULTIPLE OR SINGLE. "
|
format!("{} ", t!("Requires 0 OR 1 OR MULTIPLE OR SINGLE."))
|
||||||
} else {
|
} 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 {
|
fn wants_text_input(&self) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ use glam::DVec3;
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/tolerance.svg"));
|
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/tolerance.svg"));
|
||||||
|
|
||||||
|
|
@ -46,8 +47,10 @@ impl CadCommand for ToleranceCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
Step::Text => "TOLERANCE Enter tolerance text:".into(),
|
Step::Text => t!("TOLERANCE Enter tolerance text:").into_owned(),
|
||||||
Step::Insertion { text } => format!("TOLERANCE Specify insertion point [{text}]:"),
|
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.
|
// receives the dispatched `COPYBASE_AT <x> <y> <z>` token.
|
||||||
|
|
||||||
use glam::DVec3;
|
use glam::DVec3;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
|
|
||||||
|
|
@ -21,7 +22,7 @@ impl CadCommand for CopyBaseCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
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 {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ pub const MENU_ITEMS: &[(&str, &str, IconKind)] = &[
|
||||||
|
|
||||||
use acadrust::Handle;
|
use acadrust::Handle;
|
||||||
use glam::{DVec3, Vec3};
|
use glam::{DVec3, Vec3};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
|
@ -103,7 +104,7 @@ impl CadCommand for PasteCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
"PASTECLIP Pick insertion point:".into()
|
t!("PASTECLIP Pick insertion point:").into_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
use acadrust::types::Vector3;
|
use acadrust::types::Vector3;
|
||||||
use acadrust::{Arc as CadArc, EntityType};
|
use acadrust::{Arc as CadArc, EntityType};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::IconKind;
|
use crate::modules::IconKind;
|
||||||
|
|
@ -312,12 +313,20 @@ impl CadCommand for ArcCommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.step {
|
match self.step {
|
||||||
0 => "ARC Specify center:".into(),
|
0 => t!("ARC Specify center:").into_owned(),
|
||||||
1 => "ARC Specify start point:".into(),
|
1 => t!("ARC Specify start point:").into_owned(),
|
||||||
_ => format!(
|
_ => {
|
||||||
"ARC Specify end point [c=({:.2},{:.2}) r={:.3}]:",
|
let cx = format!("{:.2}", self.c.x);
|
||||||
self.c.x, self.c.y, self.r
|
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 {
|
fn prompt(&self) -> String {
|
||||||
match self.pts.len() {
|
match self.pts.len() {
|
||||||
0 => "ARC 3P Specify start point:".into(),
|
0 => t!("ARC 3P Specify start point:").into_owned(),
|
||||||
1 => "ARC 3P Specify second point on arc:".into(),
|
1 => t!("ARC 3P Specify second point on arc:").into_owned(),
|
||||||
_ => "ARC 3P Specify end point:".into(),
|
_ => t!("ARC 3P Specify end point:").into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -537,9 +546,12 @@ impl CadCommand for ArcSCECommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.step {
|
match self.step {
|
||||||
0 => "ARC SCE Specify start point:".into(),
|
0 => t!("ARC SCE Specify start point:").into_owned(),
|
||||||
1 => "ARC SCE Specify center:".into(),
|
1 => t!("ARC SCE Specify center:").into_owned(),
|
||||||
_ => format!("ARC SCE Specify end point [r={:.3}]:", self.r),
|
_ => {
|
||||||
|
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 {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -637,12 +649,16 @@ impl CadCommand for ArcSCACommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.step {
|
match self.step {
|
||||||
0 => "ARC SCA Specify start point:".into(),
|
0 => t!("ARC SCA Specify start point:").into_owned(),
|
||||||
1 => "ARC SCA Specify center:".into(),
|
1 => t!("ARC SCA Specify center:").into_owned(),
|
||||||
_ => format!(
|
_ => {
|
||||||
"ARC SCA Click end direction or type arc span in degrees [start={:.1}°]:",
|
let sa = format!("{:.1}°", self.sa.to_degrees());
|
||||||
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 {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -767,12 +783,16 @@ impl CadCommand for ArcSCLCommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.step {
|
match self.step {
|
||||||
0 => "ARC SCL Specify start point:".into(),
|
0 => t!("ARC SCL Specify start point:").into_owned(),
|
||||||
1 => "ARC SCL Specify center:".into(),
|
1 => t!("ARC SCL Specify center:").into_owned(),
|
||||||
_ => format!(
|
_ => {
|
||||||
"ARC SCL Click chord end or type chord length [r={:.3}]:",
|
let r = format!("{:.3}", self.r);
|
||||||
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 {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -871,9 +891,9 @@ impl CadCommand for ArcSEACommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.step {
|
match self.step {
|
||||||
0 => "ARC SEA Specify start point:".into(),
|
0 => t!("ARC SEA Specify start point:").into_owned(),
|
||||||
1 => "ARC SEA Specify end point:".into(),
|
1 => t!("ARC SEA Specify end point:").into_owned(),
|
||||||
_ => "ARC SEA Specify angle (move cursor perpendicular to chord):".into(),
|
_ => t!("ARC SEA Specify angle (move cursor perpendicular to chord):").into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -949,9 +969,9 @@ impl CadCommand for ArcSERCommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.step {
|
match self.step {
|
||||||
0 => "ARC SER Specify start point:".into(),
|
0 => t!("ARC SER Specify start point:").into_owned(),
|
||||||
1 => "ARC SER Specify end point:".into(),
|
1 => t!("ARC SER Specify end point:").into_owned(),
|
||||||
_ => "ARC SER Click radius point or type radius value:".into(),
|
_ => t!("ARC SER Click radius point or type radius value:").into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -1065,9 +1085,9 @@ impl CadCommand for ArcSEDCommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.step {
|
match self.step {
|
||||||
0 => "ARC SED Specify start point:".into(),
|
0 => t!("ARC SED Specify start point:").into_owned(),
|
||||||
1 => "ARC SED Specify end point:".into(),
|
1 => t!("ARC SED Specify end point:").into_owned(),
|
||||||
_ => "ARC SED Specify tangent direction at start:".into(),
|
_ => t!("ARC SED Specify tangent direction at start:").into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -1149,12 +1169,16 @@ impl CadCommand for ArcCSACommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.step {
|
match self.step {
|
||||||
0 => "ARC CSA Specify center:".into(),
|
0 => t!("ARC CSA Specify center:").into_owned(),
|
||||||
1 => "ARC CSA Specify start point:".into(),
|
1 => t!("ARC CSA Specify start point:").into_owned(),
|
||||||
_ => format!(
|
_ => {
|
||||||
"ARC CSA Click end direction or type arc span in degrees [start={:.1}°]:",
|
let sa = format!("{:.1}°", self.sa.to_degrees());
|
||||||
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 {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -1274,12 +1298,16 @@ impl CadCommand for ArcCSLCommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.step {
|
match self.step {
|
||||||
0 => "ARC CSL Specify center:".into(),
|
0 => t!("ARC CSL Specify center:").into_owned(),
|
||||||
1 => "ARC CSL Specify start point:".into(),
|
1 => t!("ARC CSL Specify start point:").into_owned(),
|
||||||
_ => format!(
|
_ => {
|
||||||
"ARC CSL Click chord end or type chord length [r={:.3}]:",
|
let r = format!("{:.3}", self.r);
|
||||||
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 {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -1386,7 +1414,7 @@ impl CadCommand for ArcContCommand {
|
||||||
"ARC_CONT"
|
"ARC_CONT"
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
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) {
|
fn set_ctrl(&mut self, ctrl: bool) {
|
||||||
self.ctrl = ctrl;
|
self.ctrl = ctrl;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ use acadrust::entities::AttributeDefinition;
|
||||||
use acadrust::types::Vector3;
|
use acadrust::types::Vector3;
|
||||||
use acadrust::EntityType;
|
use acadrust::EntityType;
|
||||||
use glam::DVec3;
|
use glam::DVec3;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
|
@ -52,12 +53,22 @@ impl CadCommand for AttdefCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
Step::Tag => "ATTDEF Enter attribute tag (no spaces):".into(),
|
Step::Tag => t!("ATTDEF Enter attribute tag (no spaces):").into_owned(),
|
||||||
Step::Prompt { tag } => format!("ATTDEF Enter prompt for '{tag}' (Enter=use tag):"),
|
Step::Prompt { tag } => t!(
|
||||||
Step::Default { tag, .. } => {
|
"ATTDEF Enter prompt for '%{tag}' (Enter=use tag):",
|
||||||
format!("ATTDEF Enter default value for '{tag}' (Enter=blank):")
|
tag = tag
|
||||||
}
|
)
|
||||||
Step::Insertion { tag, .. } => format!("ATTDEF Specify insertion point for '{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::types::Vector3;
|
||||||
use acadrust::{EntityType, Handle, Line};
|
use acadrust::{EntityType, Handle, Line};
|
||||||
use glam::DVec3;
|
use glam::DVec3;
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
|
|
@ -216,9 +217,9 @@ impl CadCommand for CenterLineCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
if self.first.is_none() {
|
if self.first.is_none() {
|
||||||
"CENTERLINE Select first line:".to_string()
|
t!("CENTERLINE Select first line:").into_owned()
|
||||||
} else {
|
} else {
|
||||||
"CENTERLINE Select second line:".to_string()
|
t!("CENTERLINE Select second line:").into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
use acadrust::types::Vector3;
|
use acadrust::types::Vector3;
|
||||||
use acadrust::{Circle, EntityType};
|
use acadrust::{Circle, EntityType};
|
||||||
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::{CadCommand, CmdResult, DynField, TangentObject};
|
use crate::command::{CadCommand, CmdResult, DynField, TangentObject};
|
||||||
use crate::modules::draw::defaults;
|
use crate::modules::draw::defaults;
|
||||||
|
|
@ -135,11 +136,19 @@ impl CadCommand for CircleCommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
StepCR::Center => "CIRCLE Specify center point:".into(),
|
StepCR::Center => t!("CIRCLE Specify center point:").into_owned(),
|
||||||
StepCR::Radius(c) => format!(
|
StepCR::Radius(c) => {
|
||||||
"CIRCLE Specify radius or type value <{:.4}> [center ({:.3},{:.3})]:",
|
let r = format!("{:.4}", self.default_r);
|
||||||
self.default_r, c.x, c.y
|
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("2P", "2P"),
|
||||||
CmdOption::new("Ttr", "TTR"),
|
CmdOption::new("Ttr", "TTR"),
|
||||||
CmdOption::new("Ttt", "TTT"),
|
CmdOption::new("Ttt", "TTT"),
|
||||||
CmdOption::new("Diameter", "D"),
|
CmdOption::new(t!("Diameter").as_ref(), "D"),
|
||||||
],
|
],
|
||||||
StepCR::Radius(_) => vec![],
|
StepCR::Radius(_) => vec![],
|
||||||
}
|
}
|
||||||
|
|
@ -259,11 +268,12 @@ impl CadCommand for CircleCDCommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
StepCR::Center => "CIRCLE CD Specify center point:".into(),
|
StepCR::Center => t!("CIRCLE CD Specify center point:").into_owned(),
|
||||||
StepCR::Radius(c) => format!(
|
StepCR::Radius(c) => crate::tf!(
|
||||||
"CIRCLE CD Specify diameter or type value <{:.4}> [center ({:.3},{:.3})]:",
|
"CIRCLE CD Specify diameter or type value <{:.4}> [center ({:.3},{:.3})]:",
|
||||||
self.default_d, c.x, c.y
|
self.default_d, c.x, c.y
|
||||||
),
|
)
|
||||||
|
.into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -343,9 +353,9 @@ impl CadCommand for Circle2PCommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
if self.p1.is_none() {
|
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 {
|
} 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 {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -393,9 +403,9 @@ impl CadCommand for Circle3PCommand {
|
||||||
}
|
}
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.pts.len() {
|
match self.pts.len() {
|
||||||
0 => "CIRCLE 3P Specify first point:".into(),
|
0 => crate::t!("CIRCLE 3P Specify first point:").into_owned(),
|
||||||
1 => "CIRCLE 3P Specify second point:".into(),
|
1 => crate::t!("CIRCLE 3P Specify second point:").into_owned(),
|
||||||
_ => "CIRCLE 3P Specify third point:".into(),
|
_ => crate::t!("CIRCLE 3P Specify third point:").into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
|
@ -897,9 +907,9 @@ impl CadCommand for CircleTTRCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
StepTTR::First => "CIRCLE TTR Select first tangent object:".into(),
|
StepTTR::First => crate::t!("CIRCLE TTR Select first tangent object:").into_owned(),
|
||||||
StepTTR::Second { .. } => "CIRCLE TTR Select second tangent object:".into(),
|
StepTTR::Second { .. } => crate::t!("CIRCLE TTR Select second tangent object:").into_owned(),
|
||||||
StepTTR::Radius { .. } => "CIRCLE TTR Specify radius:".into(),
|
StepTTR::Radius { .. } => crate::t!("CIRCLE TTR Specify radius:").into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -992,9 +1002,9 @@ impl CadCommand for CircleTTTCommand {
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match self.objs.len() {
|
match self.objs.len() {
|
||||||
0 => "CIRCLE TTT Select first tangent object:".into(),
|
0 => crate::t!("CIRCLE TTT Select first tangent object:").into_owned(),
|
||||||
1 => "CIRCLE TTT Select second tangent object:".into(),
|
1 => crate::t!("CIRCLE TTT Select second tangent object:").into_owned(),
|
||||||
_ => "CIRCLE TTT Select third tangent object:".into(),
|
_ => crate::t!("CIRCLE TTT Select third tangent object:").into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue