Update Translations + String improvements (#16142)

Co-authored-by: Alexandre Folle de Menezes <afmenez@gmail.com>
This commit is contained in:
Ian Bassi
2026-10-05 14:43:19 -03:00
committed by GitHub
co-authored by Alexandre Folle de Menezes
parent c1e6de7e4e
commit eb5b9a77b9
101 changed files with 202689 additions and 37732 deletions
+1
View File
@@ -90,6 +90,7 @@ See the [Localization guide](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/
- Plural entries: read `nplurals` from the catalog's `Plural-Forms` header (it is **not** always 2 — ja/ko/zh/th/vi use 1, ru/cs/pl/lt use 3, uk uses 4). Each form must be genuinely inflected for its quantity; repeating one sentence across all forms is a bug in Slavic/Baltic languages, though it is correct for Turkish and Hungarian.
- An entry whose `msgstr` equals its `msgid` is untranslated even though it is not empty; a plural entry with any empty form is likewise incomplete.
- Mark machine-produced translations with an `# AI Translated` translator comment. Don't add it to a human translation you didn't actually rewrite.
- When you can't be sure of a machine translation's meaning or UI wording, also add `# Needs human review: <what to check>`. Never use `fuzzy` for this — fuzzy entries are hidden from users.
- Don't reflow or re-wrap unrelated entries — keep the diff limited to the strings you changed.
### Verifying
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
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
+61 -2
View File
@@ -52,8 +52,6 @@ src/slic3r/GUI/DeviceTab/uiDeviceUpdateVersion.h
src/slic3r/GUI/DeviceTab/uiDeviceUpdateVersion.cpp
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.h
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.cpp
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.h
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.cpp
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.cpp
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.h
@@ -301,3 +299,64 @@ src/slic3r/GUI/Gizmos/GLGizmoPrimitive.cpp
src/slic3r/GUI/Gizmos/GLGizmoSketch.cpp
src/slic3r/GUI/KeyChord.cpp
src/slic3r/GUI/Shortcuts.cpp
src/libslic3r/CAD/CadDocument.cpp
src/libslic3r/Support/TreeSupport3D.cpp
src/slic3r/Config/Snapshot.cpp
src/slic3r/GUI/AmsMappingPopupUpdate.cpp
src/slic3r/GUI/AuxiliaryDataViewModel.cpp
src/slic3r/GUI/AuxiliaryDialog.cpp
src/slic3r/GUI/BBLStatusBarPrint.cpp
src/slic3r/GUI/BBLStatusBarSend.cpp
src/slic3r/GUI/BaseTransparentDPIFrame.cpp
src/slic3r/GUI/CloneDialog.cpp
src/slic3r/GUI/ColorDecomposeDialog.cpp
src/slic3r/GUI/ColorDecomposeSupport.cpp
src/slic3r/GUI/ConfigWizard.cpp
src/slic3r/GUI/DeviceCore/DevCalib.cpp
src/slic3r/GUI/DeviceCore/DevUpgrade.cpp
src/slic3r/GUI/DeviceTab/uiAMSBestPositionPopup.cpp
src/slic3r/GUI/DeviceTab/wgtMsgPanel.cpp
src/slic3r/GUI/DragDropPanel.cpp
src/slic3r/GUI/GLCanvas3D.hpp
src/slic3r/GUI/GUI_Utils.cpp
src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp
src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.cpp
src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp
src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp
src/slic3r/GUI/Jobs/SLAImportDialog.hpp
src/slic3r/GUI/Jobs/TextureDisplacementBakeJob.cpp
src/slic3r/GUI/Jobs/TextureDisplacementDebugJob.cpp
src/slic3r/GUI/Jobs/TextureDisplacementPrepareJob.cpp
src/slic3r/GUI/MixedFilamentDialog.cpp
src/slic3r/GUI/ModelMall.cpp
src/slic3r/GUI/OAuthDialog.cpp
src/slic3r/GUI/PluginPickerDialog.cpp
src/slic3r/GUI/PluginsConfigDialog.cpp
src/slic3r/GUI/PluginsDialog.cpp
src/slic3r/GUI/PublishSettingsDialog.hpp
src/slic3r/GUI/PurgeModeDialog.cpp
src/slic3r/GUI/TerminalDialog.cpp
src/slic3r/GUI/TextureImportDialog.cpp
src/slic3r/GUI/TextureLibrary.cpp
src/slic3r/GUI/TextureProjectorFrame.cpp
src/slic3r/GUI/UVEditorCanvas.cpp
src/slic3r/GUI/UserManager.cpp
src/slic3r/GUI/WebDownPluginDlg.cpp
src/slic3r/GUI/WebViewDialog.cpp
src/slic3r/GUI/Widgets/AMSItem.cpp
src/slic3r/GUI/Widgets/DialogButtons.cpp
src/slic3r/Utils/NetworkAgentFactory.cpp
src/slic3r/plugin/PluginAuditManager.cpp
src/slic3r/plugin/PluginConfig.cpp
src/slic3r/plugin/PluginResolver.cpp
src/libslic3r/CAD/SketchEngine.cpp
src/libslic3r/CAD/GeometryEngine.cpp
src/slic3r/GUI/CAD/DesignOffer.hpp
src/slic3r/GUI/CAD/DesignSketchTool.cpp
src/slic3r/GUI/EncodedFilament.cpp
src/slic3r/GUI/HttpServer.cpp
src/slic3r/GUI/Plater.hpp
src/slic3r/GUI/PostProcessor.cpp
src/slic3r/GUI/TaskManager.cpp
src/slic3r/GUI/Widgets/ProgressDialog.hpp
src/slic3r/GUI/Widgets/StepCtrl.cpp
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
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
+9 -9
View File
@@ -416,8 +416,8 @@ function favDigitFromEvent(e) {
function resultCountText(total, shown, query) {
return (query || "").trim() ?
T("sd_result_count", "Showing %s actions", shown) :
T("sd_result_count_all", "%s actions", total);
T("sd_result_count", "Matching actions: %s", shown) :
T("sd_result_count_all", "Actions: %s", total);
}
// Display label for a notebook tab. Trim any stray whitespace; pages added with an empty title
@@ -758,7 +758,7 @@ window.HandleStudio = function (payload) {
var fid = payload.id;
if (fid && FAVS.indexOf(fid) !== -1) FAVS.splice(FAVS.indexOf(fid), 1);
render({ resize: true, keepScroll: true });
flashHint(T("sd_favs_full", "Favourites are full (%s max)", (payload.limit || K_FAV_LIMIT)));
flashHint(T("sd_favs_full", "Favorites are full (%s max)", (payload.limit || K_FAV_LIMIT)));
}
};
@@ -821,8 +821,8 @@ function pinSvg(on) {
function setPinState(pin, on) {
pin.classList.toggle("on", on);
pin.innerHTML = pinSvg(on);
pin.title = on ? T("sd_unpin_fav", "Unpin from favourites (%s)", shortcutCtrl() + "B") :
T("sd_pin_fav", "Pin to favourites (%s)", shortcutCtrl() + "B");
pin.title = on ? T("sd_unpin_fav", "Unpin from favorites (%s)", shortcutCtrl() + "B") :
T("sd_pin_fav", "Pin to favorites (%s)", shortcutCtrl() + "B");
}
// ---- render ------------------------------------------------------------------
@@ -858,15 +858,15 @@ function renderFav() {
badge.textContent = slot;
// Slot "0" is the 10th favourite (Alt/Option+0).
var slot_num = slot === "0" ? "10" : slot;
badge.title = T("sd_fav_slot", "Favourite %s (%s)", slot_num, shortcutAlt() + slot);
badge.title = T("sd_fav_slot", "Favorite %s (%s)", slot_num, shortcutAlt() + slot);
tile.appendChild(badge);
}
// Direct removal: a hover-revealed ✕ in the tile's corner. click() stops propagation so it
// unpins without activating the action.
var unpin = document.createElement("button");
unpin.className = "fav-unpin";
unpin.title = T("sd_remove_fav", "Remove from favourites");
unpin.setAttribute("aria-label", T("sd_remove_fav", "Remove from favourites"));
unpin.title = T("sd_remove_fav", "Remove from favorites");
unpin.setAttribute("aria-label", T("sd_remove_fav", "Remove from favorites"));
unpin.innerHTML = '<svg width="9" height="9" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><line x1="4" y1="4" x2="12" y2="12"/><line x1="12" y1="4" x2="4" y2="12"/></svg>';
unpin.onclick = function (ev) { ev.stopPropagation(); toggleFav(id); };
tile.appendChild(unpin);
@@ -1170,7 +1170,7 @@ function renderTabList() {
listEl.className = "dial-list";
if (countEl) {
countEl.hidden = false;
countEl.textContent = q ? T("sd_tab_match_count", "%s matches", list.length) : T("sd_tab_count", "%s tabs", list.length);
countEl.textContent = q ? T("sd_tab_match_count", "Matching tabs: %s", list.length) : T("sd_tab_count", "Tabs: %s", list.length);
}
list.forEach(function (t, i) { listEl.appendChild(renderTabRow(t, i)); });
}
+9 -6
View File
@@ -78,8 +78,9 @@ def load_table():
if not line.startswith('{"'):
continue
# id, name, row, key, action, refusal, accepts, need_bodies, need_sketches, need_sheet,
# sketch_mode, family, ... — split on top-level commas, respecting quotes.
f, cur, q, esc = [], "", False, False
# sketch_mode, family, ... — split on top-level commas, respecting quotes and the
# L(...) / L_CONTEXT(...) translation markers.
f, cur, q, esc, depth = [], "", False, False, 0
for ch in line[1:]:
if esc:
cur += ch; esc = False; continue
@@ -87,16 +88,18 @@ def load_table():
cur += ch; esc = True; continue
if ch == '"':
q = not q
if ch == "," and not q:
if not q:
depth += (ch == "(") - (ch == ")")
if ch == "," and not q and depth == 0:
f.append(cur.strip()); cur = ""; continue
if ch == "}" and not q:
if ch == "}" and not q and depth == 0:
break
cur += ch
f.append(cur.strip())
if len(f) < 12:
continue
# User-facing fields are wrapped in the L("...") gettext marker; strip it.
lit = lambda s: None if s == "nullptr" else re.sub(r'^L\((.*)\)$', r'\1', s).strip('"')
# User-facing fields are wrapped in L("...") or L_CONTEXT("...", ...); take the literal.
lit = lambda s: None if s == "nullptr" else re.search(r'"((?:[^"\\]|\\.)*)"', s).group(1)
out.append({"id": lit(f[0]), "name": lit(f[1]), "row": int(f[2]), "key": lit(f[3]),
"action": lit(f[4]), "accepts": int(f[6].rstrip("u"), 0),
"need_bodies": int(f[7]), "need_sketches": int(f[8]),
+10 -2
View File
@@ -43,6 +43,11 @@ def tstr(s):
return "nullptr" if s is None else "L(" + cstr(s) + ")"
def tstr_design(s):
# Verb name: same msgctxt as the Design panel's own tool labels.
return "L_CONTEXT(" + cstr(s) + ', "Design")'
def validate(A):
"""Refuse an atlas the header cannot represent, naming every fault at once.
@@ -90,6 +95,9 @@ def main():
"#ifndef L",
"#define L(s) s // gettext marker, as in slic3r/GUI/I18N.hpp",
"#endif",
"#ifndef L_CONTEXT",
"#define L_CONTEXT(s, context) s",
"#endif",
"",
"namespace Slic3r { namespace GUI {",
"",
@@ -113,7 +121,7 @@ def main():
"// nullptr -> kernel support exists, no GUI path yet (row shows disabled)",
"struct OfferVerb {",
" const char* id;",
" const char* name; // drawing-office word (L10); marked L(); translated at use",
" const char* name; // drawing-office word (L10); msgctxt \"Design\", translated at use",
" int row; // index into kOfferRowNames, the ratified address — NEVER reorder",
" const char* key; // shortcut shown in the row, or nullptr",
" const char* action;",
@@ -170,7 +178,7 @@ def main():
n = v.get("needs") or {}
lines.append(
" {%s, %s, %d, %s, %s, %s, 0x%08xu, %d, %d, %s, %s, %s, %s, %s}," % (
cstr(v["id"]), tstr(v["name"]), slots.index(v["slot"]),
cstr(v["id"]), tstr_design(v["name"]), slots.index(v["slot"]),
cstr(v.get("key")), cstr(v.get("action")), tstr(v.get("refusal")),
mask, n.get("bodies", 0), n.get("sketches", 0),
"true" if n.get("sheet") else "false",
File diff suppressed because it is too large Load Diff
+18 -16
View File
@@ -1,6 +1,7 @@
#include "libslic3r/CAD/GeometryEngine.hpp"
#include "libslic3r/Point.hpp"
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/I18N.hpp"
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRep_Tool.hxx>
@@ -73,19 +74,19 @@ std::vector<TopoDS_Shape> GeometryEngine::read_step_solids(const std::string& pa
try {
STEPControl_Reader reader;
if (reader.ReadFile(path.c_str()) != IFSelect_RetDone) {
err = "cannot read STEP file";
err = _u8L("cannot read STEP file");
return out;
}
reader.TransferRoots();
const TopoDS_Shape shape = reader.OneShape();
if (shape.IsNull()) { err = "STEP file has no geometry"; return out; }
if (shape.IsNull()) { err = _u8L("STEP file has no geometry"); return out; }
// One body per top-level solid; fall back to the whole shape (shells/faces) if none.
for (TopExp_Explorer ex(shape, TopAbs_SOLID); ex.More(); ex.Next())
out.push_back(ex.Current());
if (out.empty())
out.push_back(shape);
} catch (const Standard_Failure& e) {
err = *e.what() ? e.what() : "OCCT failed to read STEP";
err = *e.what() ? e.what() : _u8L("OCCT failed to read STEP");
out.clear();
}
return out;
@@ -115,7 +116,7 @@ TopoDS_Shape GeometryEngine::mesh_to_brep(const indexed_triangle_set& its,
if (tolerance <= 0.0)
throw std::runtime_error("mesh_to_brep: tolerance must be > 0");
if (its.indices.empty())
throw std::runtime_error("mesh_to_brep: mesh has no triangles");
throw std::runtime_error(_u8L("mesh_to_brep: mesh has no triangles"));
// 1. Tolerance-quantized vertex dedup. A merged vertex keeps the exact coordinates of the
// first input occurrence — vertices are grouped by a cell, never snapped onto its grid.
@@ -150,8 +151,8 @@ TopoDS_Shape GeometryEngine::mesh_to_brep(const indexed_triangle_set& its,
}
stats.kept_tris = int(tris.size());
if (tris.empty())
throw std::runtime_error("mesh_to_brep: every triangle was rejected as degenerate "
"(try a smaller tolerance)");
throw std::runtime_error(_u8L("mesh_to_brep: every triangle was rejected as degenerate "
"(try a smaller tolerance)"));
// 3. One face per triangle, sharing vertices and edges through the caches.
std::vector<TopoDS_Vertex> vertex_cache(verts.size());
@@ -361,7 +362,7 @@ TopoDS_Shape GeometryEngine::apply_fillet(const TopoDS_Shape& solid, double radi
// A too-large radius (e.g. >= half the smallest spanned dimension) makes the
// operation degenerate; OCCT leaves IsDone() false. Report it instead of
// silently returning the unfilleted solid (which reads as a false success).
if (!fillet.IsDone()) throw std::runtime_error("fillet radius too large for this geometry");
if (!fillet.IsDone()) throw std::runtime_error(_u8L("fillet radius too large for this geometry"));
return fillet.Shape();
}
@@ -377,7 +378,7 @@ TopoDS_Shape GeometryEngine::apply_chamfer(const TopoDS_Shape& solid, double dis
chamfer.Add(distance, edge); // symmetric chamfer
chamfer.Build();
if (!chamfer.IsDone()) throw std::runtime_error("chamfer distance too large for this geometry");
if (!chamfer.IsDone()) throw std::runtime_error(_u8L("chamfer distance too large for this geometry"));
return chamfer.Shape();
}
@@ -404,7 +405,7 @@ TopoDS_Shape GeometryEngine::apply_fillet(const TopoDS_Shape& solid, double radi
}
mk.Build();
if (!mk.IsDone()) throw std::runtime_error("apply_fillet: OCCT fillet failed");
if (!mk.IsDone()) throw std::runtime_error(_u8L("apply_fillet: OCCT fillet failed"));
return mk.Shape();
}
@@ -421,7 +422,7 @@ TopoDS_Shape GeometryEngine::apply_chamfer(const TopoDS_Shape& solid, double dis
}
mk.Build();
if (!mk.IsDone()) throw std::runtime_error("apply_chamfer: OCCT chamfer failed");
if (!mk.IsDone()) throw std::runtime_error(_u8L("apply_chamfer: OCCT chamfer failed"));
return mk.Shape();
}
@@ -547,12 +548,13 @@ GeometryEngine::MassProps GeometryEngine::mass_properties(const TopoDS_Shape& sh
std::string GeometryEngine::primitive_name(PrimitiveType type)
{
switch (type) {
case PrimitiveType::Box: return "Box";
case PrimitiveType::Cylinder: return "Cylinder";
case PrimitiveType::Sphere: return "Sphere";
case PrimitiveType::Cone: return "Cone";
case PrimitiveType::Torus: return "Torus";
default: return "Unknown";
// TRN Default name of an object created from the box primitive shape.
case PrimitiveType::Box: return _u8L("Box");
case PrimitiveType::Cylinder: return _u8L("Cylinder");
case PrimitiveType::Sphere: return _u8L("Sphere");
case PrimitiveType::Cone: return _u8L("Cone");
case PrimitiveType::Torus: return _u8L("Torus");
default: return _u8L("Unknown");
}
}
+30 -29
View File
@@ -1,6 +1,7 @@
#include "libslic3r/CAD/SketchEngine.hpp"
#include "libslic3r/Point.hpp"
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/I18N.hpp"
#include <Standard_Handle.hxx>
#include <GeomAbs_SurfaceType.hxx>
@@ -138,7 +139,7 @@ Vec3d SketchPlane::to_world(const Vec2d& pt) const
TopoDS_Wire SketchProfile::to_occt_wire(const SketchPlane& plane) const
{
if (points.size() < 2)
throw std::runtime_error("Profile has fewer than 2 points");
throw std::runtime_error(_u8L("Profile has fewer than 2 points"));
BRepBuilderAPI_MakeWire builder;
for (size_t i = 0; i < points.size(); ++i) {
@@ -150,7 +151,7 @@ TopoDS_Wire SketchProfile::to_occt_wire(const SketchPlane& plane) const
}
builder.Build();
if (!builder.IsDone())
throw std::runtime_error("Failed to build wire from profile");
throw std::runtime_error(_u8L("Failed to build wire from profile"));
return builder.Wire();
}
@@ -158,9 +159,9 @@ TopoDS_Wire SketchProfile::to_occt_wire(const SketchPlane& plane) const
TopoDS_Shape SketchEngine::make_prism(const TopoDS_Shape& base, const gp_Vec& vec)
{
if (vec.Magnitude() < 1e-9) throw std::runtime_error("extrude depth is zero");
if (vec.Magnitude() < 1e-9) throw std::runtime_error(_u8L("extrude depth is zero"));
BRepPrimAPI_MakePrism prism(base, vec);
if (!prism.IsDone()) throw std::runtime_error("extrude failed");
if (!prism.IsDone()) throw std::runtime_error(_u8L("extrude failed"));
return prism.Shape();
}
@@ -169,7 +170,7 @@ static TopoDS_Shape extrude_face_internal(const TopoDS_Face& face, const gp_Dir&
if (symmetric) {
gp_Vec halfVec = gp_Vec(dir) * (length / 2.0);
BRepAlgoAPI_Fuse fuse(SketchEngine::make_prism(face, halfVec), SketchEngine::make_prism(face, -halfVec));
if (!fuse.IsDone()) throw std::runtime_error("Fuse failed");
if (!fuse.IsDone()) throw std::runtime_error(_u8L("Fuse failed"));
return fuse.Shape();
}
return SketchEngine::make_prism(face, gp_Vec(dir) * length);
@@ -179,7 +180,7 @@ TopoDS_Shape SketchEngine::make_extrude(const TopoDS_Wire& wire, const SketchPla
double length, bool symmetric, double taper_deg)
{
BRepBuilderAPI_MakeFace fm(wire);
if (!fm.IsDone()) throw std::runtime_error("Failed to make face from wire");
if (!fm.IsDone()) throw std::runtime_error(_u8L("Failed to make face from wire"));
return make_extrude(fm.Face(), plane, length, symmetric, taper_deg);
}
@@ -194,7 +195,7 @@ TopoDS_Shape SketchEngine::make_extrude_two_sided(const TopoDS_Wire& wire, const
double up, double down)
{
BRepBuilderAPI_MakeFace fm(wire);
if (!fm.IsDone()) throw std::runtime_error("Failed to make face from wire");
if (!fm.IsDone()) throw std::runtime_error(_u8L("Failed to make face from wire"));
return make_extrude_two_sided(fm.Face(), plane, up, down);
}
@@ -206,7 +207,7 @@ TopoDS_Shape SketchEngine::make_extrude_two_sided(const TopoDS_Face& face, const
if (d < 1e-9) return make_prism(face, gp_Vec(dir) * u);
if (u < 1e-9) return make_prism(face, gp_Vec(dir) * -d);
BRepAlgoAPI_Fuse fuse(make_prism(face, gp_Vec(dir) * u), make_prism(face, gp_Vec(dir) * -d));
if (!fuse.IsDone()) throw std::runtime_error("two-sided extrude fuse failed");
if (!fuse.IsDone()) throw std::runtime_error(_u8L("two-sided extrude fuse failed"));
return fuse.Shape();
}
@@ -216,7 +217,7 @@ TopoDS_Shape SketchEngine::make_extrude_taper(const TopoDS_Wire& wire, const Ske
gp_Dir dir(plane.normal.x(), plane.normal.y(), plane.normal.z());
auto straight = [&]() -> TopoDS_Shape {
BRepBuilderAPI_MakeFace fm(wire);
if (!fm.IsDone()) throw std::runtime_error("Failed to make face from wire");
if (!fm.IsDone()) throw std::runtime_error(_u8L("Failed to make face from wire"));
return make_prism(fm.Face(), gp_Vec(dir) * length);
};
if (std::abs(taper_deg) >= 89.0 || std::abs(length) < 1e-9) return straight();
@@ -262,7 +263,7 @@ TopoDS_Shape SketchEngine::make_extrude_regions(
const SketchPlane& plane, double length, bool symmetric)
{
// The loop below skips regions that fail, so a zero depth is rejected before it.
if (std::abs(length) < 1e-9) throw std::runtime_error("extrude depth is zero");
if (std::abs(length) < 1e-9) throw std::runtime_error(_u8L("extrude depth is zero"));
// Drop consecutive coincident points and the closing duplicate. FreeType /
// SVG flattening routinely emits repeated points which would build a
@@ -348,7 +349,7 @@ TopoDS_Shape SketchEngine::make_extrude_regions(
}
}
if (count == 0) throw std::runtime_error("imported regions produced no extrudable geometry");
if (count == 0) throw std::runtime_error(_u8L("imported regions produced no extrudable geometry"));
return count == 1 ? last : TopoDS_Shape(comp); // avoid a compound-of-one
}
@@ -356,7 +357,7 @@ TopoDS_Shape SketchEngine::make_revolve(const TopoDS_Wire& wire, const gp_Ax1& a
{
BRepBuilderAPI_MakeFace faceMaker(wire);
if (!faceMaker.IsDone())
throw std::runtime_error("Failed to make face from wire");
throw std::runtime_error(_u8L("Failed to make face from wire"));
TopoDS_Face face = faceMaker.Face();
// A profile on both sides of the axis sweeps through itself; MakeRevol then fails with no
@@ -387,7 +388,7 @@ TopoDS_Shape SketchEngine::make_revolve(const TopoDS_Wire& wire, const gp_Ax1& a
if (angle_rad < 0) { axis.Reverse(); angle_rad = -angle_rad; }
BRepPrimAPI_MakeRevol rev(face, axis, angle_rad);
if (!rev.IsDone())
throw std::runtime_error("Failed to revolve");
throw std::runtime_error(_u8L("Failed to revolve"));
if (!BRepCheck_Analyzer(rev.Shape()).IsValid())
throw std::runtime_error("the profile crosses the revolve axis — it must lie on one side of it");
return rev.Shape();
@@ -397,29 +398,29 @@ TopoDS_Shape SketchEngine::make_sweep(const TopoDS_Wire& profile, const TopoDS_W
{
BRepBuilderAPI_MakeFace faceMaker(profile);
if (!faceMaker.IsDone())
throw std::runtime_error("Failed to make face from sweep profile");
throw std::runtime_error(_u8L("Failed to make face from sweep profile"));
TopoDS_Face face = faceMaker.Face();
BRepOffsetAPI_MakePipe pipe(path, face);
pipe.Build();
if (!pipe.IsDone())
throw std::runtime_error("Failed to sweep profile along path");
throw std::runtime_error(_u8L("Failed to sweep profile along path"));
return pipe.Shape();
}
TopoDS_Shape SketchEngine::make_loft(const std::vector<TopoDS_Wire>& profiles, bool ruled)
{
if (profiles.size() < 2)
throw std::runtime_error("loft needs at least 2 profiles");
throw std::runtime_error(_u8L("loft needs at least 2 profiles"));
BRepOffsetAPI_ThruSections loft(true /*solid*/, ruled);
for (const TopoDS_Wire& w : profiles) {
if (w.IsNull()) throw std::runtime_error("loft: null profile wire");
loft.AddWire(w);
}
loft.Build();
if (!loft.IsDone()) throw std::runtime_error("loft failed");
if (!loft.IsDone()) throw std::runtime_error(_u8L("loft failed"));
TopoDS_Shape s = loft.Shape();
if (s.IsNull()) throw std::runtime_error("loft produced no solid");
if (s.IsNull()) throw std::runtime_error(_u8L("loft produced no solid"));
return s;
}
@@ -427,16 +428,16 @@ TopoDS_Shape SketchEngine::make_loft(const std::vector<TopoDS_Wire>& profiles, b
TopoDS_Shape SketchEngine::make_loft_surface(const std::vector<TopoDS_Wire>& profiles, bool ruled)
{
if (profiles.size() < 2)
throw std::runtime_error("loft needs at least 2 profiles");
throw std::runtime_error(_u8L("loft needs at least 2 profiles"));
BRepOffsetAPI_ThruSections loft(false /*shell, no end caps*/, ruled);
for (const TopoDS_Wire& w : profiles) {
if (w.IsNull()) throw std::runtime_error("loft: null profile wire");
loft.AddWire(w);
}
loft.Build();
if (!loft.IsDone()) throw std::runtime_error("loft failed");
if (!loft.IsDone()) throw std::runtime_error(_u8L("loft failed"));
TopoDS_Shape s = loft.Shape();
if (s.IsNull()) throw std::runtime_error("loft produced no shape");
if (s.IsNull()) throw std::runtime_error(_u8L("loft produced no shape"));
return s;
}
@@ -444,11 +445,11 @@ TopoDS_Shape SketchEngine::make_pocket(const TopoDS_Wire& wire, const SketchPlan
const TopoDS_Shape& target, double depth)
{
BRepBuilderAPI_MakeFace fm(wire);
if (!fm.IsDone()) throw std::runtime_error("Pocket face failed");
if (!fm.IsDone()) throw std::runtime_error(_u8L("Pocket face failed"));
TopoDS_Shape tool = extrude_face_internal(fm.Face(),
gp_Dir(plane.normal.x(), plane.normal.y(), plane.normal.z()), depth + 1.0, false);
BRepAlgoAPI_Cut cut(target, tool);
if (!cut.IsDone()) throw std::runtime_error("Pocket cut failed");
if (!cut.IsDone()) throw std::runtime_error(_u8L("Pocket cut failed"));
return cut.Shape();
}
@@ -929,7 +930,7 @@ static TopoDS_Face checked_profile_face(const TopoDS_Face& f)
TopoDS_Face SketchEngine::wires_to_face(const std::vector<TopoDS_Wire>& wires,
const SketchPlane& plane)
{
if (wires.empty()) throw std::runtime_error("sketch has no closed loop");
if (wires.empty()) throw std::runtime_error(_u8L("sketch has no closed loop"));
// The ASSEMBLED face below is built on the SKETCH's own plane rather than on a surface OCCT
// infers from the outer wire. The inferred plane has no reason to share the sketch's normal,
@@ -944,7 +945,7 @@ TopoDS_Face SketchEngine::wires_to_face(const std::vector<TopoDS_Wire>& wires,
if (wires.size() == 1) {
BRepBuilderAPI_MakeFace fm(wires[0]);
if (!fm.IsDone()) throw std::runtime_error("sketch loop does not bound a face");
if (!fm.IsDone()) throw std::runtime_error(_u8L("sketch loop does not bound a face"));
return checked_profile_face(fm.Face());
}
@@ -956,7 +957,7 @@ TopoDS_Face SketchEngine::wires_to_face(const std::vector<TopoDS_Wire>& wires,
areas.reserve(wires.size());
for (const TopoDS_Wire& w : wires) {
BRepBuilderAPI_MakeFace fm(w);
if (!fm.IsDone()) throw std::runtime_error("sketch loop does not bound a face");
if (!fm.IsDone()) throw std::runtime_error(_u8L("sketch loop does not bound a face"));
faces.push_back(fm.Face());
GProp_GProps props;
BRepGProp::SurfaceProperties(faces.back(), props);
@@ -982,10 +983,10 @@ TopoDS_Face SketchEngine::wires_to_face(const std::vector<TopoDS_Wire>& wires,
got = true;
break;
}
if (!got) throw std::runtime_error("sketch loop does not bound a face");
if (!got) throw std::runtime_error(_u8L("sketch loop does not bound a face"));
BRepClass_FaceClassifier fc(faces[outer], p, 1e-7);
if (fc.State() != TopAbs_IN)
throw std::runtime_error("sketch has two disjoint regions; put each in its own sketch");
throw std::runtime_error(_u8L("sketch has two disjoint regions; put each in its own sketch"));
// Add the hole loop AS-IS and let ShapeFix_Face sort the orientations out below.
// Reversing it here only works when the sketch happened to wind both loops the same
// way: a circle drawn clockwise inside a counter-clockwise rectangle comes out matching
@@ -995,7 +996,7 @@ TopoDS_Face SketchEngine::wires_to_face(const std::vector<TopoDS_Wire>& wires,
// 147520 — a body larger than its own bounding box, which is the signature of it.
fm.Add(wires[i]);
}
if (!fm.IsDone()) throw std::runtime_error("sketch loop does not bound a face");
if (!fm.IsDone()) throw std::runtime_error(_u8L("sketch loop does not bound a face"));
// Winding-independent classification of outer vs holes — the same idiom make_extrude_regions
// already uses for imported glyphs, which is why holed TEXT extruded correctly all along
// while a holed SKETCH did not.
+3 -2
View File
@@ -264,7 +264,8 @@ AboutDialog::AboutDialog()
vesizer->Add(0, 0, 1, wxEXPAND, FromDIP(5));
auto version_string = std::string(SoftFever_VERSION); // _L("Orca Slicer ") + " " + std::string(SoftFever_VERSION);
wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize);
wxStaticText* credits_string = new wxStaticText(this, wxID_ANY, wxString::Format("Build %s", build_commit_label), wxDefaultPosition, wxDefaultSize);
// TRN %s is the commit the application was built from
wxStaticText* credits_string = new wxStaticText(this, wxID_ANY, wxString::Format(_L("Build %s"), build_commit_label), wxDefaultPosition, wxDefaultSize);
credits_string->SetFont(_build_string_font);
wxFont version_font = GetFont();
version_font = version_font.Scaled(1.85f); // SetPointSize(20) not works on macOS because it uses a 72 PPI reference
@@ -330,7 +331,7 @@ AboutDialog::AboutDialog()
copyright_hor_sizer->Add(copyright_ver_sizer, 0, wxLEFT, FromDIP(20));
wxStaticText *html_text = new wxStaticText(this, wxID_ANY, "Copyright(C) 2026 OrcaSlicer Pte Ltd All Rights Reserved", wxDefaultPosition, wxDefaultSize);
wxStaticText *html_text = new wxStaticText(this, wxID_ANY, _L("Copyright(C) 2026 OrcaSlicer Pte Ltd All Rights Reserved"), wxDefaultPosition, wxDefaultSize);
html_text->SetForegroundColour(wxColour(107, 107, 107));
copyright_ver_sizer->Add(html_text, 0, wxALL , 0);
+7 -6
View File
@@ -329,7 +329,8 @@ void AmsMapingPopup::update_mapping_items(MachineObject* obj, const std::vector<
if (m_show_type == ShowType::LEFT_AND_RIGHT_DYNAMIC) {
auto sizer_mapping_list = new wxBoxSizer(wxHORIZONTAL);
const auto& shown_name = td_opt->ams_id == VIRTUAL_TRAY_MAIN_ID ? "Ext-R" : "Ext-L";
// TRN Short labels of the external spool of the right and left nozzle
const auto& shown_name = td_opt->ams_id == VIRTUAL_TRAY_MAIN_ID ? _L("Ext-R") : _L("Ext-L");
auto ams_mapping_item_container = new MappingContainer(m_right_marea_panel, shown_name, 1);
ams_mapping_item_container->SetName(m_right_marea_panel->GetName());
ams_mapping_item_container->SetSizer(sizer_mapping_list);
@@ -506,7 +507,7 @@ void AmsMapingPopup::update_ams_tips(MachineObject* obj)
}
if (obj && obj->GetFilaSwitch()->IsInstalled()) {
const auto& msg = _L("External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it.");
const auto& msg = _L("External spools are not supported since Filament Track Switch has been installed. If you want to use an external spool, please uninstall it.");
m_ams_tips_msg_panel->AddMessage(msg, "#FF6F00", "");
}
@@ -588,7 +589,7 @@ void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data,
// slots Ext-R / Ext-L inline in the two-nozzle left+right views (matches that overload's result).
if ((m_show_type == ShowType::LEFT_AND_RIGHT || m_show_type == ShowType::LEFT_AND_RIGHT_DYNAMIC)
&& (tray_data[i].id == VIRTUAL_TRAY_MAIN_ID || tray_data[i].id == VIRTUAL_TRAY_DEPUTY_ID)) {
m_mapping_item->set_tray_index(tray_data[i].id == VIRTUAL_TRAY_MAIN_ID ? wxString("Ext-R") : wxString("Ext-L"));
m_mapping_item->set_tray_index(tray_data[i].id == VIRTUAL_TRAY_MAIN_ID ? _L("Ext-R") : _L("Ext-L"));
} else {
m_mapping_item->set_tray_index(wxGetApp().transition_tridid(tray_data[i].id));
}
@@ -607,7 +608,7 @@ void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data,
can_pick_the_item = !devPrinterUtil::IsVirtualSlot(m_mapping_item->m_ams_id);
if (!can_pick_the_item) {
item_tooltip_msg = _L(
"External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it.");
"External spools are not supported since Filament Track Switch has been installed. If you want to use an external spool, please uninstall it.");
}
}
}
@@ -624,7 +625,7 @@ void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data,
can_pick_the_item = !devPrinterUtil::IsVirtualSlot(m_mapping_item->m_ams_id);
if (!can_pick_the_item) {
item_tooltip_msg = _L(
"External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it.");
"External spools are not supported since Filament Track Switch has been installed. If you want to use an external spool, please uninstall it.");
}
} else if (m_show_type != ShowType::RIGHT && m_show_type != ShowType::LEFT_AND_RIGHT) {
can_pick_the_item = false;
@@ -718,7 +719,7 @@ void AmsMapingPopup::add_ext_ams_mapping(TrayData tray_data, MappingItem* item)
});
}
item->set_tray_index("Ext");
item->set_tray_index(_L("Ext"));
}
} // namespace Slic3r::GUI
+1 -1
View File
@@ -20,7 +20,7 @@ namespace GUI {
AuxiliaryDialog::AuxiliaryDialog(wxWindow * parent)
: DPIDialog(parent, wxID_ANY, _L("Auxiliaryies"), wxDefaultPosition,
: DPIDialog(parent, wxID_ANY, _L("Auxiliaries"), wxDefaultPosition,
wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
m_aux_list = new AuxiliaryList(this);
+96 -93
View File
@@ -13,6 +13,9 @@
#ifndef L
#define L(s) s // gettext marker, as in slic3r/GUI/I18N.hpp
#endif
#ifndef L_CONTEXT
#define L_CONTEXT(s, context) s
#endif
namespace Slic3r { namespace GUI {
@@ -52,7 +55,7 @@ inline uint32_t offer_bit(OfferSel s) { return 1u << int(s); }
// nullptr -> kernel support exists, no GUI path yet (row shows disabled)
struct OfferVerb {
const char* id;
const char* name; // drawing-office word (L10); marked L(); translated at use
const char* name; // drawing-office word (L10); msgctxt "Design", translated at use
int row; // index into kOfferRowNames, the ratified address — NEVER reorder
const char* key; // shortcut shown in the row, or nullptr
const char* action;
@@ -99,107 +102,107 @@ static const bool kOfferRowFlat[] = {
};
static const OfferVerb kOfferVerbs[] = {
{"sketch", L("Sketch"), 0, "Shift+S", "key:S+S", L("Click a face or a reference plane in the viewport, then a sketch tool"), 0x00000403u, 0, 0, false, false, nullptr, "design_sketch", L("Click a face or a reference plane, then pick a drawing tool")},
{"extrude", L("Extrude"), 1, "Shift+E", "key:S+E", L("Create a sketch, or pick a solid face, first"), 0x00004002u, 0, 0, false, false, nullptr, "design_extrude", L("Extrude a sketch profile, or push/pull a picked face")},
{"revolve", L("Revolve"), 1, "Shift+R", "key:S+R", L("Create a sketch profile to revolve first"), 0x00004000u, 0, 0, false, false, nullptr, "design_revolve", L("Revolve a profile about an axis")},
{"sweep", L("Sweep"), 1, "Shift+W", "key:S+W", L("Create a profile sketch to sweep first"), 0x00004000u, 0, 2, false, false, nullptr, "design_sweep", L("Sweep a profile along a path")},
{"loft", L("Loft"), 1, "Shift+L", "key:S+L", L("Create at least two profile sketches to loft"), 0x00004000u, 0, 2, false, false, nullptr, "design_loft", L("Loft (skin) between two or more profiles")},
{"thicken", L("Thicken"), 1, nullptr, "fly:material#4", L("Thicken needs a solid body — add or import one first"), 0x0000000au, 1, 0, false, false, nullptr, "design_thicken", L("Offset a solid face into a thin plate (new body)")},
{"rib", L("Rib"), 1, "R", "fly:material#5", L("Rib needs a solid body — add or import one first"), 0x00010000u, 1, 0, false, false, nullptr, "design_rib", L("Grow a thin wall from an open sketch line, fused to a body")},
{"boolean", L("Join"), 1, "Shift+B", "btn:bool#0", L("Boolean needs two bodies — add or import a second one"), 0x00000200u, 2, 0, false, false, nullptr, "design_boolean", L("Fuse the tool body into the target — one solid, no seam")},
{"bool_subtract", L("Subtract"), 1, nullptr, "btn:bool#1", L("Boolean needs two bodies — add or import a second one"), 0x00000200u, 2, 0, false, false, nullptr, "design_boolean", L("Cut the tool body out of the target")},
{"bool_intersect", L("Intersect"), 1, nullptr, "btn:bool#2", L("Boolean needs two bodies — add or import a second one"), 0x00000200u, 2, 0, false, false, nullptr, "design_boolean", L("Keep only where the two bodies overlap")},
{"surf_extrude", L("Surface Extrude"), 1, "Shift+G", "key:S+G", L("Create a sketch first"), 0x00004000u, 0, 0, false, false, nullptr, "design_extrude", L("Extrude a sketch into a sheet body (no end caps)")},
{"surf_revolve", L("Surface Revolve"), 1, nullptr, "fly:surface#1", L("Create a sketch profile to revolve first"), 0x00004000u, 0, 0, false, false, nullptr, "design_revolve", L("Revolve a sketch profile into a sheet body")},
{"surf_loft", L("Surface Loft"), 1, nullptr, "fly:surface#2", L("Create at least two profile sketches to loft"), 0x00004000u, 0, 2, false, false, nullptr, "design_loft", L("Loft (skin) between 2+ profiles, open (no end caps)")},
{"surf_fill", L("Surface Fill"), 1, nullptr, "fly:surface#3", L("Create a closed sketch first"), 0x00004000u, 0, 0, false, false, nullptr, "design_surface", L("Fill a sketch boundary with a smooth face")},
{"thicken_surf", L("Thicken Surface"), 1, nullptr, "fly:surface#5", L("Thicken Surface needs a surface body — make one with a Surface tool first"), 0x00000100u, 0, 0, true, false, nullptr, "design_thicken", L("Thicken a sheet body into a solid")},
{"hole", L("Hole"), 2, "Shift+H", "key:S+H", L("Pick a face or a plane to drill into"), 0x00000402u, 1, 0, false, false, nullptr, "design_hole", L("Drill a hole, centerd on a picked face or placed on a plane")},
{"thread", L("Thread"), 2, "Shift+T", "key:S+T", L("Pick a cylindrical surface (bore / outer) or a circular edge for a thread"), 0x00000024u, 1, 0, false, false, nullptr, "design_thread", L("Thread a cylindrical surface (inner bore / outer) or a circular edge")},
{"shell", L("Shell"), 2, "Shift+K", "key:S+K", L("Shell needs a solid body — add or import one first"), 0x00000082u, 1, 0, false, false, nullptr, "design_shell", L("Hollow the body to a wall thickness, opening a picked face")},
{"cut", L("Cut"), 2, "Shift+X", "key:S+X", L("Cut needs a solid body — add or import one first"), 0x000004feu, 1, 0, false, false, nullptr, "design_cut", L("Trim the body with a plane — drag the offset arrow; keep one half or both")},
{"split", L("Split"), 2, nullptr, nullptr, L("Split needs a solid body — add or import one first"), 0x000000feu, 1, 0, false, false, nullptr, nullptr, L("Split the body along a picked face into two solids")},
{"fillet", L("Fillet"), 3, "Shift+F", "btn:dress#0", L("Pick an edge to round"), 0x000000b2u, 1, 0, false, false, nullptr, "design_filletedge", L("Pick an edge, then drag the radius arrow or type it")},
{"chamfer", L("Chamfer"), 3, nullptr, "btn:dress#1", L("Pick an edge to bevel"), 0x000000b2u, 1, 0, false, false, nullptr, "design_chamfer", L("Pick an edge, then drag the distance arrow or type it")},
{"draft", L("Draft"), 3, "Shift+D", "key:S+D", L("Pick a face to taper"), 0x0000000au, 1, 0, false, false, nullptr, "design_draft", L("Tilt a picked face by a draft angle")},
{"surf_offset", L("Surface Offset"), 3, nullptr, "fly:surface#4", L("Surface Offset needs a surface body — make one with a Surface tool first"), 0x00000100u, 0, 0, true, false, nullptr, "design_offset", L("Offset a sheet body's shell by a signed distance")},
{"pattern", L("Linear pattern"), 4, "Shift+N", "btn:pat#0", L("Pattern needs a solid body — add or import one first"), 0x00006082u, 1, 0, false, false, nullptr, "design_array", L("Repeat the body along a direction — drag the spacing, set the count")},
{"pattern_circular", L("Circular pattern"), 4, nullptr, "btn:pat#1", L("Pattern needs a solid body — add or import one first"), 0x00006082u, 1, 0, false, false, nullptr, "design_polararray", L("Repeat the body around an axis — set the count and sweep")},
{"mirror", L("Mirror"), 4, "Shift+Z", "key:S+Z", L("Mirror needs a body — add or import one first"), 0x000004feu, 1, 0, false, false, nullptr, "design_mirror", L("Reflect a body about a plane")},
{"pat_curve", L("Pattern on Curve"), 4, nullptr, nullptr, L("Pattern on Curve needs a body and a curve"), 0x00000090u, 1, 0, false, false, nullptr, nullptr, L("Repeat the body along a picked curve")},
{"transform", L("Move"), 5, "Shift+Y", "key:S+Y", L("Transform needs a body — add or import one first"), 0x000021feu, 1, 0, false, false, nullptr, "design_move", L("Move and/or rotate an existing body")},
{"mate", L("Mate"), 5, nullptr, "fly:placement#2", L("Mate needs two coordinate systems — create them first"), 0x00001202u, 2, 0, false, false, nullptr, "design_c_coincident", L("Assembly: align two coordinate systems (fastened, planar, revolute, slider, cylindrical)")},
{"align", L("Align to"), 5, nullptr, nullptr, L("Align needs a body — add or import one first"), 0x00000002u, 1, 0, false, false, nullptr, nullptr, L("Align the body to a picked face or plane")},
{"plane", L("Plane"), 6, "Shift+P", "key:S+P", nullptr, 0x00000453u, 0, 0, false, false, nullptr, "design_plane", L("Reference plane (offset / tilt / midplane / tangent / two edges / coincident)")},
{"axis", L("Axis"), 6, "Shift+A", "key:S+A", nullptr, 0x00000057u, 0, 0, false, false, nullptr, "design_line", L("Datum axis (two points, face normal, cylinder centerline, two planes, along edge)")},
{"coordsys_v", L("Coordinate system"), 6, "Shift+C", "key:S+C", nullptr, 0x00000043u, 0, 0, false, false, nullptr, "design_point", L("Datum coordinate system (world point, or face + direction edge)")},
{"helix", L("Helix"), 6, nullptr, "fly:plane#3", nullptr, 0x00000405u, 0, 0, false, false, nullptr, "design_thread", L("Helical curve (spring path) — use as a sweep path for coils / springs / augers")},
{"project", L("Project"), 6, nullptr, "fly:plane#4", L("Project needs a body — add or import one first"), 0x00000482u, 1, 0, false, false, nullptr, "design_sketch", L("Project body edges onto a plane as sketch entities")},
{"measure", L("Measure"), 6, nullptr, nullptr, nullptr, 0x000b03feu, 0, 0, false, false, nullptr, nullptr, L("Measure between the picked points, edges or faces")},
{"mass_props", L("Volume and area"), 6, nullptr, "btn:mass", nullptr, 0x000000feu, 1, 0, false, false, nullptr, "info", L("Report the volume and surface area of the selected body")},
{"interference", L("Interference"), 6, nullptr, "btn:interference", L("Interference needs at least two bodies"), 0x00000280u, 2, 0, false, false, nullptr, nullptr, L("Check whether two bodies overlap — reports, changes nothing")},
{"edit_feature", L("Edit"), 7, nullptr, "btn:edit", nullptr, 0x00007d8eu, 0, 0, false, false, nullptr, "design_edit", L("Reopen the selected feature to change what it was made from")},
{"rename", L("Rename…"), 8, "F2", "btn:rename", L("Select a feature, or a body, to rename it"), 0x00004080u, 0, 0, false, false, nullptr, nullptr, L("Give this feature a name you will recognise in the tree (a body takes its name from the feature that makes it)")},
{"delete_face", L("Delete Face"), 7, nullptr, "fly:dressup#3", L("Delete Face needs a body — add or import one first"), 0x0000000eu, 1, 0, false, false, nullptr, "design_delete", L("Remove faces from a body and heal the solid")},
{"colour", L("Color"), 8, nullptr, "btn:colour", nullptr, 0x000001feu, 1, 0, false, false, nullptr, "color_palette", L("Set the selected body's display color")},
{"delete", L("Delete"), 7, "Del", "btn:delete", nullptr, 0x000f7c00u, 0, 0, false, false, nullptr, "design_delete", L("Delete what is selected")},
{"delete_body", L("Delete Body"), 7, nullptr, "btn:delete_body", nullptr, 0x000001feu, 1, 0, false, false, nullptr, "design_delete", L("Delete this whole body — removes the feature it was made from")},
{"sk_line_t", L("Line"), 0, "L", "key:L", nullptr, 0x000f8000u, 0, 0, false, true, L("Line"), "design_line", L("Line — click start, then end")},
{"sk_polyline", L("Polyline"), 0, nullptr, "fly:design_line#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Line"), "design_polyline", L("Click points; click the first point to close the loop, right-click to end it open")},
{"sk_rect", L("Corner rectangle"), 0, "R", "key:R", nullptr, 0x000f8000u, 0, 0, false, true, L("Rectangle"), "design_rect", L("Rectangle — click two opposite corners")},
{"sk_rect_center", L("Center rectangle"), 0, nullptr, "fly:design_rect#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Rectangle"), "design_crect", L("Click center, then a corner")},
{"sk_rect_oblique", L("Oblique rectangle"), 0, nullptr, "fly:design_rect#2", nullptr, 0x000f8000u, 0, 0, false, true, L("Rectangle"), "design_rect_oblique", L("Click two corners of one edge, then a point for the width")},
{"sk_rect_rounded", L("Rounded rectangle"), 0, nullptr, "fly:design_rect#3", nullptr, 0x000f8000u, 0, 0, false, true, L("Rectangle"), "design_rect_rounded", L("Click two opposite corners, then a point for the corner radius")},
{"sk_circle", L("Center circle"), 0, "C", "key:C", nullptr, 0x000f8000u, 0, 0, false, true, L("Circle"), "design_circle", L("Circle — click center, then radius")},
{"sk_circle_2pt", L("2-point circle"), 0, nullptr, "fly:design_circle#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Circle"), "design_circle2pt", L("Click two ends of the diameter")},
{"sk_circle_3pt", L("3-point circle"), 0, nullptr, "fly:design_circle#2", nullptr, 0x000f8000u, 0, 0, false, true, L("Circle"), "design_circle3pt", L("Click three points on the circle")},
{"sk_arc_t", L("3-point arc"), 0, "A", "key:A", nullptr, 0x000f8000u, 0, 0, false, true, L("Arc"), "design_arc3pt", L("Arc — click start, end, then a point")},
{"sk_arc_tangent", L("Tangent arc"), 0, nullptr, "fly:design_arc3pt#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Arc"), "design_tangentarc", L("Click start (on the last entity) then end")},
{"sk_arc_center", L("Center-point arc"), 0, nullptr, "fly:design_arc3pt#2", nullptr, 0x000f8000u, 0, 0, false, true, L("Arc"), "design_arc_center", L("Click center, then start, then a point for the end angle")},
{"sk_slot", L("Slot"), 0, "S", "key:S", nullptr, 0x000f8000u, 0, 0, false, true, L("Slot"), "design_slot", L("Slot — two centerline ends, then the width")},
{"sk_slot_arc", L("Arc slot"), 0, nullptr, "fly:design_slot#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Slot"), "design_slot_arc", L("Click center, start, end, then a point for the width")},
{"sk_ellipse", L("Ellipse"), 0, "E", "key:E", nullptr, 0x000f8000u, 0, 0, false, true, L("Ellipse"), "design_ellipse", L("Ellipse — center, major end, minor point")},
{"sk_ellipse_arc", L("Elliptical arc"), 0, nullptr, "fly:design_ellipse#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Ellipse"), "design_ellipse_arc", L("Click center, major-axis end, minor point, then arc start and end")},
{"sk_spline", L("Spline"), 0, "B", "key:B", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_bspline", L("Spline — click control points")},
{"sk_poly_3", L("Triangle"), 0, nullptr, "btn:poly#3", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Triangle — click center, then a vertex")},
{"sk_poly_4", L("Square"), 0, nullptr, "btn:poly#4", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Square — click center, then a vertex")},
{"sk_poly_5", L("Pentagon"), 0, nullptr, "btn:poly#5", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Pentagon — click center, then a vertex")},
{"sk_polygon", L("Hexagon"), 0, "G", "btn:poly#6", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Hexagon — click center, then a vertex")},
{"sk_poly_8", L("Octagon"), 0, nullptr, "btn:poly#8", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Octagon — click center, then a vertex")},
{"sk_poly_12", L("Dodecagon"), 0, nullptr, "btn:poly#12", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Dodecagon — click center, then a vertex")},
{"sk_poly_inscribed", L("Inscribed"), 0, nullptr, "btn:polyfit#0", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Measure the polygon to its corners (inscribed)")},
{"sk_poly_circumscribed", L("Circumscribed"), 0, nullptr, "btn:polyfit#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Measure the polygon to its flats (circumscribed)")},
{"sk_point_t", L("Point"), 0, "P", "key:P", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_point", L("Point — click to place")},
{"sk_text", L("Text"), 0, nullptr, "btn:text", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_text", L("Type text; it becomes a Text feature on this sketch's plane, editable later")},
{"sk_svg", L("SVG"), 0, nullptr, "btn:svg", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_svg", L("Import an SVG outline into this sketch as editable lines")},
{"sk_offset", L("Offset"), 1, "O", "key:O", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_offset", L("Offset — pick an entity, drag the distance")},
{"sk_trim", L("Trim"), 2, "T", "key:T", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_trim", L("Trim — click a segment to trim it")},
{"sk_fillet", L("Fillet"), 3, "F", "key:F", nullptr, 0x00090000u, 0, 0, false, true, nullptr, "design_filletedge", L("Fillet — pick two lines, set the radius")},
{"sk_chamfer", L("Chamfer"), 3, "H", "key:H", nullptr, 0x00090000u, 0, 0, false, true, nullptr, "design_chamfer", L("Chamfer — pick two lines, set the distance")},
{"sk_array", L("Linear array"), 4, nullptr, "fly:design_array#0", nullptr, 0x000b0000u, 0, 0, false, true, L("Array"), "design_array", L("Pick entities, drag the spacing handle, click the count; click empty to apply")},
{"sk_array_polar", L("Polar array"), 4, nullptr, "fly:design_array#1", nullptr, 0x000b0000u, 0, 0, false, true, L("Array"), "design_polararray", L("Pick entities, drag the sweep handle, click the count; click empty to apply")},
{"sk_mirror", L("Mirror"), 4, "M", "key:M", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_mirror", L("Mirror — pick axis, then entities")},
{"sk_move", L("Move"), 5, nullptr, "fly:design_move#0", nullptr, 0x000f0000u, 0, 0, false, true, L("Move"), "design_move", L("Pick entities, then drag the handle or click the distance; click empty to apply")},
{"sk_rotate", L("Rotate"), 5, nullptr, "fly:design_move#1", nullptr, 0x000f0000u, 0, 0, false, true, L("Move"), "design_rotate", L("Pick entities, then drag around the pivot or click the angle; click empty to apply")},
{"sk_scale", L("Scale"), 5, nullptr, "fly:design_move#2", nullptr, 0x000f0000u, 0, 0, false, true, L("Move"), "design_scale", L("Pick entities, then drag the handle or click the factor; click empty to apply")},
{"sk_dimension", L("Dimension"), 6, "D", "key:D", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_dimension", L("Dimension — click 2 points or an entity")},
{"sk_constrain", L("Constrain"), 6, "K", "key:K", nullptr, 0x000f0000u, 0, 0, false, true, nullptr, "design_constrain", L("Constrain the selected sketch entities to each other")},
{"sketch", L_CONTEXT("Sketch", "Design"), 0, "Shift+S", "key:S+S", L("Click a face or a reference plane in the viewport, then a sketch tool"), 0x00000403u, 0, 0, false, false, nullptr, "design_sketch", L("Click a face or a reference plane, then pick a drawing tool")},
{"extrude", L_CONTEXT("Extrude", "Design"), 1, "Shift+E", "key:S+E", L("Create a sketch, or pick a solid face, first"), 0x00004002u, 0, 0, false, false, nullptr, "design_extrude", L("Extrude a sketch profile, or push/pull a picked face")},
{"revolve", L_CONTEXT("Revolve", "Design"), 1, "Shift+R", "key:S+R", L("Create a sketch profile to revolve first"), 0x00004000u, 0, 0, false, false, nullptr, "design_revolve", L("Revolve a profile about an axis")},
{"sweep", L_CONTEXT("Sweep", "Design"), 1, "Shift+W", "key:S+W", L("Create a profile sketch to sweep first"), 0x00004000u, 0, 2, false, false, nullptr, "design_sweep", L("Sweep a profile along a path")},
{"loft", L_CONTEXT("Loft", "Design"), 1, "Shift+L", "key:S+L", L("Create at least two profile sketches to loft"), 0x00004000u, 0, 2, false, false, nullptr, "design_loft", L("Loft (skin) between two or more profiles")},
{"thicken", L_CONTEXT("Thicken", "Design"), 1, nullptr, "fly:material#4", L("Thicken needs a solid body — add or import one first"), 0x0000000au, 1, 0, false, false, nullptr, "design_thicken", L("Offset a solid face into a thin plate (new body)")},
{"rib", L_CONTEXT("Rib", "Design"), 1, "R", "fly:material#5", L("Rib needs a solid body — add or import one first"), 0x00010000u, 1, 0, false, false, nullptr, "design_rib", L("Grow a thin wall from an open sketch line, fused to a body")},
{"boolean", L_CONTEXT("Join", "Design"), 1, "Shift+B", "btn:bool#0", L("Boolean needs two bodies — add or import a second one"), 0x00000200u, 2, 0, false, false, nullptr, "design_boolean", L("Fuse the tool body into the target — one solid, no seam")},
{"bool_subtract", L_CONTEXT("Subtract", "Design"), 1, nullptr, "btn:bool#1", L("Boolean needs two bodies — add or import a second one"), 0x00000200u, 2, 0, false, false, nullptr, "design_boolean", L("Cut the tool body out of the target")},
{"bool_intersect", L_CONTEXT("Intersect", "Design"), 1, nullptr, "btn:bool#2", L("Boolean needs two bodies — add or import a second one"), 0x00000200u, 2, 0, false, false, nullptr, "design_boolean", L("Keep only where the two bodies overlap")},
{"surf_extrude", L_CONTEXT("Surface Extrude", "Design"), 1, "Shift+G", "key:S+G", L("Create a sketch first"), 0x00004000u, 0, 0, false, false, nullptr, "design_extrude", L("Extrude a sketch into a sheet body (no end caps)")},
{"surf_revolve", L_CONTEXT("Surface Revolve", "Design"), 1, nullptr, "fly:surface#1", L("Create a sketch profile to revolve first"), 0x00004000u, 0, 0, false, false, nullptr, "design_revolve", L("Revolve a sketch profile into a sheet body")},
{"surf_loft", L_CONTEXT("Surface Loft", "Design"), 1, nullptr, "fly:surface#2", L("Create at least two profile sketches to loft"), 0x00004000u, 0, 2, false, false, nullptr, "design_loft", L("Loft (skin) between 2+ profiles, open (no end caps)")},
{"surf_fill", L_CONTEXT("Surface Fill", "Design"), 1, nullptr, "fly:surface#3", L("Create a closed sketch first"), 0x00004000u, 0, 0, false, false, nullptr, "design_surface", L("Fill a sketch boundary with a smooth face")},
{"thicken_surf", L_CONTEXT("Thicken Surface", "Design"), 1, nullptr, "fly:surface#5", L("Thicken Surface needs a surface body — make one with a Surface tool first"), 0x00000100u, 0, 0, true, false, nullptr, "design_thicken", L("Thicken a sheet body into a solid")},
{"hole", L_CONTEXT("Hole", "Design"), 2, "Shift+H", "key:S+H", L("Pick a face or a plane to drill into"), 0x00000402u, 1, 0, false, false, nullptr, "design_hole", L("Drill a hole, centerd on a picked face or placed on a plane")},
{"thread", L_CONTEXT("Thread", "Design"), 2, "Shift+T", "key:S+T", L("Pick a cylindrical surface (bore / outer) or a circular edge for a thread"), 0x00000024u, 1, 0, false, false, nullptr, "design_thread", L("Thread a cylindrical surface (inner bore / outer) or a circular edge")},
{"shell", L_CONTEXT("Shell", "Design"), 2, "Shift+K", "key:S+K", L("Shell needs a solid body — add or import one first"), 0x00000082u, 1, 0, false, false, nullptr, "design_shell", L("Hollow the body to a wall thickness, opening a picked face")},
{"cut", L_CONTEXT("Cut", "Design"), 2, "Shift+X", "key:S+X", L("Cut needs a solid body — add or import one first"), 0x000004feu, 1, 0, false, false, nullptr, "design_cut", L("Trim the body with a plane — drag the offset arrow; keep one half or both")},
{"split", L_CONTEXT("Split", "Design"), 2, nullptr, nullptr, L("Split needs a solid body — add or import one first"), 0x000000feu, 1, 0, false, false, nullptr, nullptr, L("Split the body along a picked face into two solids")},
{"fillet", L_CONTEXT("Fillet", "Design"), 3, "Shift+F", "btn:dress#0", L("Pick an edge to round"), 0x000000b2u, 1, 0, false, false, nullptr, "design_filletedge", L("Pick an edge, then drag the radius arrow or type it")},
{"chamfer", L_CONTEXT("Chamfer", "Design"), 3, nullptr, "btn:dress#1", L("Pick an edge to bevel"), 0x000000b2u, 1, 0, false, false, nullptr, "design_chamfer", L("Pick an edge, then drag the distance arrow or type it")},
{"draft", L_CONTEXT("Draft", "Design"), 3, "Shift+D", "key:S+D", L("Pick a face to taper"), 0x0000000au, 1, 0, false, false, nullptr, "design_draft", L("Tilt a picked face by a draft angle")},
{"surf_offset", L_CONTEXT("Surface Offset", "Design"), 3, nullptr, "fly:surface#4", L("Surface Offset needs a surface body — make one with a Surface tool first"), 0x00000100u, 0, 0, true, false, nullptr, "design_offset", L("Offset a sheet body's shell by a signed distance")},
{"pattern", L_CONTEXT("Linear pattern", "Design"), 4, "Shift+N", "btn:pat#0", L("Pattern needs a solid body — add or import one first"), 0x00006082u, 1, 0, false, false, nullptr, "design_array", L("Repeat the body along a direction — drag the spacing, set the count")},
{"pattern_circular", L_CONTEXT("Circular pattern", "Design"), 4, nullptr, "btn:pat#1", L("Pattern needs a solid body — add or import one first"), 0x00006082u, 1, 0, false, false, nullptr, "design_polararray", L("Repeat the body around an axis — set the count and sweep")},
{"mirror", L_CONTEXT("Mirror", "Design"), 4, "Shift+Z", "key:S+Z", L("Mirror needs a body — add or import one first"), 0x000004feu, 1, 0, false, false, nullptr, "design_mirror", L("Reflect a body about a plane")},
{"pat_curve", L_CONTEXT("Pattern on Curve", "Design"), 4, nullptr, nullptr, L("Pattern on Curve needs a body and a curve"), 0x00000090u, 1, 0, false, false, nullptr, nullptr, L("Repeat the body along a picked curve")},
{"transform", L_CONTEXT("Move", "Design"), 5, "Shift+Y", "key:S+Y", L("Transform needs a body — add or import one first"), 0x000021feu, 1, 0, false, false, nullptr, "design_move", L("Move and/or rotate an existing body")},
{"mate", L_CONTEXT("Mate", "Design"), 5, nullptr, "fly:placement#2", L("Mate needs two coordinate systems — create them first"), 0x00001202u, 2, 0, false, false, nullptr, "design_c_coincident", L("Assembly: align two coordinate systems (fastened, planar, revolute, slider, cylindrical)")},
{"align", L_CONTEXT("Align to", "Design"), 5, nullptr, nullptr, L("Align needs a body — add or import one first"), 0x00000002u, 1, 0, false, false, nullptr, nullptr, L("Align the body to a picked face or plane")},
{"plane", L_CONTEXT("Plane", "Design"), 6, "Shift+P", "key:S+P", nullptr, 0x00000453u, 0, 0, false, false, nullptr, "design_plane", L("Reference plane (offset / tilt / midplane / tangent / two edges / coincident)")},
{"axis", L_CONTEXT("Axis", "Design"), 6, "Shift+A", "key:S+A", nullptr, 0x00000057u, 0, 0, false, false, nullptr, "design_line", L("Datum axis (two points, face normal, cylinder centerline, two planes, along edge)")},
{"coordsys_v", L_CONTEXT("Coordinate system", "Design"), 6, "Shift+C", "key:S+C", nullptr, 0x00000043u, 0, 0, false, false, nullptr, "design_point", L("Datum coordinate system (world point, or face + direction edge)")},
{"helix", L_CONTEXT("Helix", "Design"), 6, nullptr, "fly:plane#3", nullptr, 0x00000405u, 0, 0, false, false, nullptr, "design_thread", L("Helical curve (spring path) — use as a sweep path for coils / springs / augers")},
{"project", L_CONTEXT("Project", "Design"), 6, nullptr, "fly:plane#4", L("Project needs a body — add or import one first"), 0x00000482u, 1, 0, false, false, nullptr, "design_sketch", L("Project body edges onto a plane as sketch entities")},
{"measure", L_CONTEXT("Measure", "Design"), 6, nullptr, nullptr, nullptr, 0x000b03feu, 0, 0, false, false, nullptr, nullptr, L("Measure between the picked points, edges or faces")},
{"mass_props", L_CONTEXT("Volume and area", "Design"), 6, nullptr, "btn:mass", nullptr, 0x000000feu, 1, 0, false, false, nullptr, "info", L("Report the volume and surface area of the selected body")},
{"interference", L_CONTEXT("Interference", "Design"), 6, nullptr, "btn:interference", L("Interference needs at least two bodies"), 0x00000280u, 2, 0, false, false, nullptr, nullptr, L("Check whether two bodies overlap — reports, changes nothing")},
{"edit_feature", L_CONTEXT("Edit", "Design"), 7, nullptr, "btn:edit", nullptr, 0x00007d8eu, 0, 0, false, false, nullptr, "design_edit", L("Reopen the selected feature to change what it was made from")},
{"rename", L_CONTEXT("Rename…", "Design"), 8, "F2", "btn:rename", L("Select a feature, or a body, to rename it"), 0x00004080u, 0, 0, false, false, nullptr, nullptr, L("Give this feature a name you will recognise in the tree (a body takes its name from the feature that makes it)")},
{"delete_face", L_CONTEXT("Delete Face", "Design"), 7, nullptr, "fly:dressup#3", L("Delete Face needs a body — add or import one first"), 0x0000000eu, 1, 0, false, false, nullptr, "design_delete", L("Remove faces from a body and heal the solid")},
{"colour", L_CONTEXT("Color", "Design"), 8, nullptr, "btn:colour", nullptr, 0x000001feu, 1, 0, false, false, nullptr, "color_palette", L("Set the selected body's display color")},
{"delete", L_CONTEXT("Delete", "Design"), 7, "Del", "btn:delete", nullptr, 0x000f7c00u, 0, 0, false, false, nullptr, "design_delete", L("Delete what is selected")},
{"delete_body", L_CONTEXT("Delete Body", "Design"), 7, nullptr, "btn:delete_body", nullptr, 0x000001feu, 1, 0, false, false, nullptr, "design_delete", L("Delete this whole body — removes the feature it was made from")},
{"sk_line_t", L_CONTEXT("Line", "Design"), 0, "L", "key:L", nullptr, 0x000f8000u, 0, 0, false, true, L("Line"), "design_line", L("Line — click start, then end")},
{"sk_polyline", L_CONTEXT("Polyline", "Design"), 0, nullptr, "fly:design_line#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Line"), "design_polyline", L("Click points; click the first point to close the loop, right-click to end it open")},
{"sk_rect", L_CONTEXT("Corner rectangle", "Design"), 0, "R", "key:R", nullptr, 0x000f8000u, 0, 0, false, true, L("Rectangle"), "design_rect", L("Rectangle — click two opposite corners")},
{"sk_rect_center", L_CONTEXT("Center rectangle", "Design"), 0, nullptr, "fly:design_rect#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Rectangle"), "design_crect", L("Click center, then a corner")},
{"sk_rect_oblique", L_CONTEXT("Oblique rectangle", "Design"), 0, nullptr, "fly:design_rect#2", nullptr, 0x000f8000u, 0, 0, false, true, L("Rectangle"), "design_rect_oblique", L("Click two corners of one edge, then a point for the width")},
{"sk_rect_rounded", L_CONTEXT("Rounded rectangle", "Design"), 0, nullptr, "fly:design_rect#3", nullptr, 0x000f8000u, 0, 0, false, true, L("Rectangle"), "design_rect_rounded", L("Click two opposite corners, then a point for the corner radius")},
{"sk_circle", L_CONTEXT("Center circle", "Design"), 0, "C", "key:C", nullptr, 0x000f8000u, 0, 0, false, true, L("Circle"), "design_circle", L("Circle — click center, then radius")},
{"sk_circle_2pt", L_CONTEXT("2-point circle", "Design"), 0, nullptr, "fly:design_circle#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Circle"), "design_circle2pt", L("Click two ends of the diameter")},
{"sk_circle_3pt", L_CONTEXT("3-point circle", "Design"), 0, nullptr, "fly:design_circle#2", nullptr, 0x000f8000u, 0, 0, false, true, L("Circle"), "design_circle3pt", L("Click three points on the circle")},
{"sk_arc_t", L_CONTEXT("3-point arc", "Design"), 0, "A", "key:A", nullptr, 0x000f8000u, 0, 0, false, true, L("Arc"), "design_arc3pt", L("Arc — click start, end, then a point")},
{"sk_arc_tangent", L_CONTEXT("Tangent arc", "Design"), 0, nullptr, "fly:design_arc3pt#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Arc"), "design_tangentarc", L("Click start (on the last entity) then end")},
{"sk_arc_center", L_CONTEXT("Center-point arc", "Design"), 0, nullptr, "fly:design_arc3pt#2", nullptr, 0x000f8000u, 0, 0, false, true, L("Arc"), "design_arc_center", L("Click center, then start, then a point for the end angle")},
{"sk_slot", L_CONTEXT("Slot", "Design"), 0, "S", "key:S", nullptr, 0x000f8000u, 0, 0, false, true, L("Slot"), "design_slot", L("Slot — two centerline ends, then the width")},
{"sk_slot_arc", L_CONTEXT("Arc slot", "Design"), 0, nullptr, "fly:design_slot#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Slot"), "design_slot_arc", L("Click center, start, end, then a point for the width")},
{"sk_ellipse", L_CONTEXT("Ellipse", "Design"), 0, "E", "key:E", nullptr, 0x000f8000u, 0, 0, false, true, L("Ellipse"), "design_ellipse", L("Ellipse — center, major end, minor point")},
{"sk_ellipse_arc", L_CONTEXT("Elliptical arc", "Design"), 0, nullptr, "fly:design_ellipse#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Ellipse"), "design_ellipse_arc", L("Click center, major-axis end, minor point, then arc start and end")},
{"sk_spline", L_CONTEXT("Spline", "Design"), 0, "B", "key:B", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_bspline", L("Spline — click control points")},
{"sk_poly_3", L_CONTEXT("Triangle", "Design"), 0, nullptr, "btn:poly#3", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Triangle — click center, then a vertex")},
{"sk_poly_4", L_CONTEXT("Square", "Design"), 0, nullptr, "btn:poly#4", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Square — click center, then a vertex")},
{"sk_poly_5", L_CONTEXT("Pentagon", "Design"), 0, nullptr, "btn:poly#5", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Pentagon — click center, then a vertex")},
{"sk_polygon", L_CONTEXT("Hexagon", "Design"), 0, "G", "btn:poly#6", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Hexagon — click center, then a vertex")},
{"sk_poly_8", L_CONTEXT("Octagon", "Design"), 0, nullptr, "btn:poly#8", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Octagon — click center, then a vertex")},
{"sk_poly_12", L_CONTEXT("Dodecagon", "Design"), 0, nullptr, "btn:poly#12", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Dodecagon — click center, then a vertex")},
{"sk_poly_inscribed", L_CONTEXT("Inscribed", "Design"), 0, nullptr, "btn:polyfit#0", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Measure the polygon to its corners (inscribed)")},
{"sk_poly_circumscribed", L_CONTEXT("Circumscribed", "Design"), 0, nullptr, "btn:polyfit#1", nullptr, 0x000f8000u, 0, 0, false, true, L("Polygon"), "design_polygon", L("Measure the polygon to its flats (circumscribed)")},
{"sk_point_t", L_CONTEXT("Point", "Design"), 0, "P", "key:P", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_point", L("Point — click to place")},
{"sk_text", L_CONTEXT("Text", "Design"), 0, nullptr, "btn:text", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_text", L("Type text; it becomes a Text feature on this sketch's plane, editable later")},
{"sk_svg", L_CONTEXT("SVG", "Design"), 0, nullptr, "btn:svg", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_svg", L("Import an SVG outline into this sketch as editable lines")},
{"sk_offset", L_CONTEXT("Offset", "Design"), 1, "O", "key:O", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_offset", L("Offset — pick an entity, drag the distance")},
{"sk_trim", L_CONTEXT("Trim", "Design"), 2, "T", "key:T", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_trim", L("Trim — click a segment to trim it")},
{"sk_fillet", L_CONTEXT("Fillet", "Design"), 3, "F", "key:F", nullptr, 0x00090000u, 0, 0, false, true, nullptr, "design_filletedge", L("Fillet — pick two lines, set the radius")},
{"sk_chamfer", L_CONTEXT("Chamfer", "Design"), 3, "H", "key:H", nullptr, 0x00090000u, 0, 0, false, true, nullptr, "design_chamfer", L("Chamfer — pick two lines, set the distance")},
{"sk_array", L_CONTEXT("Linear array", "Design"), 4, nullptr, "fly:design_array#0", nullptr, 0x000b0000u, 0, 0, false, true, L("Array"), "design_array", L("Pick entities, drag the spacing handle, click the count; click empty to apply")},
{"sk_array_polar", L_CONTEXT("Polar array", "Design"), 4, nullptr, "fly:design_array#1", nullptr, 0x000b0000u, 0, 0, false, true, L("Array"), "design_polararray", L("Pick entities, drag the sweep handle, click the count; click empty to apply")},
{"sk_mirror", L_CONTEXT("Mirror", "Design"), 4, "M", "key:M", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_mirror", L("Mirror — pick axis, then entities")},
{"sk_move", L_CONTEXT("Move", "Design"), 5, nullptr, "fly:design_move#0", nullptr, 0x000f0000u, 0, 0, false, true, L("Move"), "design_move", L("Pick entities, then drag the handle or click the distance; click empty to apply")},
{"sk_rotate", L_CONTEXT("Rotate", "Design"), 5, nullptr, "fly:design_move#1", nullptr, 0x000f0000u, 0, 0, false, true, L("Move"), "design_rotate", L("Pick entities, then drag around the pivot or click the angle; click empty to apply")},
{"sk_scale", L_CONTEXT("Scale", "Design"), 5, nullptr, "fly:design_move#2", nullptr, 0x000f0000u, 0, 0, false, true, L("Move"), "design_scale", L("Pick entities, then drag the handle or click the factor; click empty to apply")},
{"sk_dimension", L_CONTEXT("Dimension", "Design"), 6, "D", "key:D", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_dimension", L("Dimension — click 2 points or an entity")},
{"sk_constrain", L_CONTEXT("Constrain", "Design"), 6, "K", "key:K", nullptr, 0x000f0000u, 0, 0, false, true, nullptr, "design_constrain", L("Constrain the selected sketch entities to each other")},
// Same verb, model-mode vocabulary: offered when a SKETCH is selected (bit 14, SkLoop), the
// state a user is in right after finishing one. Without this row the only way in was the
// toolbar icon, and constraints read as absent — see the Onshape-comparison report.
// It sits in the Reference row, the address the sketch-mode Constrain has: one verb, one row.
{"constrain", L("Constrain sketch"), 6, nullptr, "btn:constrain", L("Select a sketch to constrain it"), 0x00004000u, 0, 1, false, false, nullptr, "design_constrain", L("Add dimensions and relations (coincident, tangent, parallel...) to the selected sketch")},
{"sk_construct", L("Construction"), 6, "Q", "key:Q", nullptr, 0x000b8000u, 0, 0, false, true, nullptr, nullptr, L("Toggle construction: geometry that guides but is never built")},
{"sk_extend", L("Extend"), 7, "X", "key:X", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_extend", L("Extend — click a line/arc to extend it")},
{"sk_delete", L("Delete"), 7, "Del", "btn:sk_delete", nullptr, 0x000f0000u, 0, 0, false, true, nullptr, "design_delete", L("Delete the selected sketch entities")},
{"constrain", L_CONTEXT("Constrain sketch", "Design"), 6, nullptr, "btn:constrain", L("Select a sketch to constrain it"), 0x00004000u, 0, 1, false, false, nullptr, "design_constrain", L("Add dimensions and relations (coincident, tangent, parallel...) to the selected sketch")},
{"sk_construct", L_CONTEXT("Construction", "Design"), 6, "Q", "key:Q", nullptr, 0x000b8000u, 0, 0, false, true, nullptr, nullptr, L("Toggle construction: geometry that guides but is never built")},
{"sk_extend", L_CONTEXT("Extend", "Design"), 7, "X", "key:X", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_extend", L("Extend — click a line/arc to extend it")},
{"sk_delete", L_CONTEXT("Delete", "Design"), 7, "Del", "btn:sk_delete", nullptr, 0x000f0000u, 0, 0, false, true, nullptr, "design_delete", L("Delete the selected sketch entities")},
// Typing the defining number of the element you pointed at. Three rows rather than one so
// each names the quantity in the drawing-office word for THAT element; all three land on
// the same handler, because dimension_kind() already resolves the quantity from the
// selection. Without these, an element's own numbers were reachable only by arming the
// Dimension tool and re-picking geometry that was already selected.
{"sk_length", L("Length…"), 7, "V", "key:V", nullptr, 0x00010000u, 0, 0, false, true, nullptr, "design_dimension", L("Type the length of this line")},
{"sk_radius", L("Radius / diameter…"), 7, "V", "key:V", nullptr, 0x00020000u, 0, 0, false, true, nullptr, "design_dimension", L("Type the radius of this arc, or the diameter of this circle")},
{"sk_angdist", L("Angle / distance…"), 7, "V", "key:V", nullptr, 0x00080000u, 0, 0, false, true, nullptr, "design_dimension", L("Type the angle between two lines, or the distance between the two picks")},
{"sk_length", L_CONTEXT("Length…", "Design"), 7, "V", "key:V", nullptr, 0x00010000u, 0, 0, false, true, nullptr, "design_dimension", L("Type the length of this line")},
{"sk_radius", L_CONTEXT("Radius / diameter…", "Design"), 7, "V", "key:V", nullptr, 0x00020000u, 0, 0, false, true, nullptr, "design_dimension", L("Type the radius of this arc, or the diameter of this circle")},
{"sk_angdist", L_CONTEXT("Angle / distance…", "Design"), 7, "V", "key:V", nullptr, 0x00080000u, 0, 0, false, true, nullptr, "design_dimension", L("Type the angle between two lines, or the distance between the two picks")},
};
static const int kOfferVerbCount = 92;
+142 -128
View File
@@ -110,15 +110,6 @@
#include "slic3r/GUI/Shortcuts.hpp"
#include "slic3r/GUI/I18N.hpp"
// English-only pin for the Design tab (see design-ux-contract): one lever
// de-translates this whole TU so our strings never half-translate against the host's
// localized chrome. Host UI still follows the app locale; only this tab is pinned EN.
// GOTCHA: every _L(...) in this file must take a STRING LITERAL (FromUTF8 wants const char*).
#ifdef _L
#undef _L
#endif
#define _L(s) wxString::FromUTF8(s)
namespace Slic3r { namespace GUI {
// Mesh -> B-rep import defaults (see GeometryEngine::mesh_to_brep).
@@ -498,7 +489,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
}
m_viewport->set_sketch_construction(m_construction->GetValue());
set_status(StatusKind::Info, m_sketch_on.IsEmpty() ? hint
: wxString::Format(_L("%s · on %s"), hint, m_sketch_on));
: wxString::Format(_L("%s · plane: %s"), hint, m_sketch_on));
};
// Sketch-tool shortcuts (single letters, active only while a sketch is open). Family tools
@@ -731,11 +722,11 @@ DesignPanel::DesignPanel(wxWindow* parent)
wxString where;
const bool have_plane = sketch_plane_target(where);
set_status(StatusKind::Info, have_plane
? wxString::Format(_L("Sketching on %s — pick a tool"), where)
? wxString::Format(_L("Sketch plane: %s — pick a tool"), where)
: _L("Click a face or a reference plane in the viewport, then a sketch tool"));
if (m_sketch_hint) { // the card must agree with the status line, not argue with it
m_sketch_hint->SetLabel(have_plane
? wxString::Format(_L("Drawing on %s.\nPick a tool, or press Menu for the list."), where)
? wxString::Format(_L("Sketch plane: %s.\nPick a tool, or press Menu for the list."), where)
: _L("Click a face or a reference plane, then a sketch tool."));
m_sketch_hint->Refresh();
m_cards->Layout();
@@ -752,7 +743,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
// Add material: every feature that grows new solid material — from a profile
// (extrude/revolve/sweep/loft), from a face (thicken) or from a line (rib).
feat_dropdown("material", "design_extrude", _L("Add material (extrude / revolve / sweep / loft / thicken / rib)"), {
{"design_extrude", _L("Extrude"), _L("Extrude a sketch profile, or push/pull a picked face"),
{"design_extrude", _L_CONTEXT("Extrude", "Design"), _L("Extrude a sketch profile, or push/pull a picked face"),
[this] {
// Onshape push/pull: an explicitly picked solid face (Face-level cycle, no loop
// selected) is extruded as the profile — this takes priority over re-extruding an
@@ -833,7 +824,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
m_sel_solid_face = -1;
open_tool(Tool::Thicken); // syncs m_thicken_face_label from m_sel_solid_face
}, 0},
{"design_rib", _L("Rib"), _L("Grow a thin wall from an open sketch line, fused to a body"),
{"design_rib", _L_CONTEXT("Rib", "Design"), _L("Grow a thin wall from an open sketch line, fused to a body"),
[this] {
if (m_doc.bodies.empty()) {
set_status(StatusKind::Error, _L("Rib needs a solid body — add or import one first"));
@@ -873,7 +864,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
// shortcut at all, which also made its card unreachable to the rig.
});
auto* b_pattern = icon_btn("design_pattern", _L("Pattern"));
auto* b_pattern = icon_btn("design_pattern", _L_CONTEXT("Pattern", "Design"));
std::function<void()> act_pattern = [this] {
// Pattern replicates an existing body — needs at least one solid.
if (m_doc.bodies.empty()) {
@@ -979,7 +970,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
}, 0},
// Project belongs here, not in Dress-up: it consumes a body but PRODUCES sketch
// geometry, so it is reference/curve creation like the four above, not a finishing op.
{"design_sketch", _L("Project"), _L("Project body edges onto a plane as sketch entities"),
{"design_sketch", _L_CONTEXT("Project", "Design"), _L("Project body edges onto a plane as sketch entities"),
[this] {
if (m_doc.bodies.empty()) {
set_status(StatusKind::Error, _L("Project needs a body — add or import one first"));
@@ -1139,7 +1130,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
[this] { open_tool(Tool::Dressup); }, SHIFT('F')},
{"design_draft", _L("Draft (taper a face)"), _L("Tilt a picked face by a draft angle"),
[this] { open_tool(Tool::Draft); }, SHIFT('D')},
{"design_shell", _L("Shell"), _L("Hollow the body to a wall thickness, opening a picked face"),
{"design_shell", _L_CONTEXT("Shell", "Design"), _L("Hollow the body to a wall thickness, opening a picked face"),
[this] { open_tool(Tool::Shell); }, SHIFT('K')},
{"design_delete", _L("Delete Face"), _L("Remove faces from a body and heal the solid"),
[this] {
@@ -1165,7 +1156,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
// Hole / Thread — drilling into a solid (both face-aware)
feat_dropdown("hole", "design_hole", _L("Hole / thread"), {
{"design_hole", _L("Hole"), _L("Drill a hole, centerd on a picked face or placed on a plane"),
{"design_hole", _L("Hole"), _L("Drill a hole, centered on a picked face or placed on a plane"),
[this] {
// #2: drill on the picked solid face, centred on it (origin = face centroid,
// normal = inward). Otherwise fall back to the plane dropdown. m_hole_x/y then
@@ -1542,8 +1533,9 @@ DesignPanel::DesignPanel(wxWindow* parent)
if (n > 0) {
m_construction->SetValue(!m_construction->GetValue()); // the mode did not move
set_status(StatusKind::Info, wxString::Format(
_L("Converted %d entit%s between construction and real geometry"),
n, n == 1 ? "y" : "ies"));
_L_PLURAL("Converted %d entity between construction and real geometry",
"Converted %d entities between construction and real geometry", n),
n));
return;
}
m_viewport->set_sketch_construction(m_construction->GetValue()); });
@@ -1574,26 +1566,26 @@ DesignPanel::DesignPanel(wxWindow* parent)
b->Bind(wxEVT_BUTTON, [this, type](wxCommandEvent&) { apply_constraint(type); });
cadd(b);
};
cbtn("design_c_horizontal", _L("Horizontal"), SketchConstraintType::Horizontal);
cbtn("design_c_vertical", _L("Vertical"), SketchConstraintType::Vertical);
cbtn("design_c_parallel", _L("Parallel"), SketchConstraintType::Parallel);
cbtn("design_c_perpendicular", _L("Perpendicular"), SketchConstraintType::Perpendicular);
cbtn("design_c_coincident", _L("Coincident"), SketchConstraintType::Coincident);
cbtn("design_c_equal", _L("Equal length"), SketchConstraintType::EqualLength);
cbtn("design_c_equal_radius", _L("Equal radius"), SketchConstraintType::EqualRadius);
cbtn("design_c_collinear", _L("Collinear"), SketchConstraintType::Collinear);
cbtn("design_c_concentric", _L("Concentric"), SketchConstraintType::Concentric);
cbtn("design_c_tangent", _L("Tangent"), SketchConstraintType::Tangent);
cbtn("design_c_midpoint", _L("Midpoint"), SketchConstraintType::Midpoint);
cbtn("design_c_symmetric", _L("Symmetric"), SketchConstraintType::Symmetric);
cbtn("design_c_sym_v", _L("Symmetric about the vertical axis"), SketchConstraintType::SymmetricAboutY);
cbtn("design_c_sym_h", _L("Symmetric about the horizontal axis"), SketchConstraintType::SymmetricAboutX);
cbtn("design_c_angle", _L("Angle"), SketchConstraintType::Angle);
cbtn("design_c_radius", _L("Radius"), SketchConstraintType::Radius);
cbtn("design_c_diameter", _L("Diameter"), SketchConstraintType::Diameter);
cbtn("design_c_fix", _L("Fix point (anchor in place)"), SketchConstraintType::Fix);
cbtn("design_c_dist_x", _L("Horizontal distance"), SketchConstraintType::DistanceX);
cbtn("design_c_dist_y", _L("Vertical distance"), SketchConstraintType::DistanceY);
cbtn("design_c_horizontal", _L_CONTEXT("Horizontal", "Sketch Constraint"), SketchConstraintType::Horizontal);
cbtn("design_c_vertical", _L_CONTEXT("Vertical", "Sketch Constraint"), SketchConstraintType::Vertical);
cbtn("design_c_parallel", _L_CONTEXT("Parallel", "Sketch Constraint"), SketchConstraintType::Parallel);
cbtn("design_c_perpendicular", _L_CONTEXT("Perpendicular", "Sketch Constraint"), SketchConstraintType::Perpendicular);
cbtn("design_c_coincident", _L_CONTEXT("Coincident", "Sketch Constraint"), SketchConstraintType::Coincident);
cbtn("design_c_equal", _L_CONTEXT("Equal length", "Sketch Constraint"), SketchConstraintType::EqualLength);
cbtn("design_c_equal_radius", _L_CONTEXT("Equal radius", "Sketch Constraint"), SketchConstraintType::EqualRadius);
cbtn("design_c_collinear", _L_CONTEXT("Collinear", "Sketch Constraint"), SketchConstraintType::Collinear);
cbtn("design_c_concentric", _L_CONTEXT("Concentric", "Sketch Constraint"), SketchConstraintType::Concentric);
cbtn("design_c_tangent", _L_CONTEXT("Tangent", "Sketch Constraint"), SketchConstraintType::Tangent);
cbtn("design_c_midpoint", _L_CONTEXT("Midpoint", "Sketch Constraint"), SketchConstraintType::Midpoint);
cbtn("design_c_symmetric", _L_CONTEXT("Symmetric", "Sketch Constraint"), SketchConstraintType::Symmetric);
cbtn("design_c_sym_v", _L_CONTEXT("Symmetric about the vertical axis", "Sketch Constraint"), SketchConstraintType::SymmetricAboutY);
cbtn("design_c_sym_h", _L_CONTEXT("Symmetric about the horizontal axis", "Sketch Constraint"), SketchConstraintType::SymmetricAboutX);
cbtn("design_c_angle", _L_CONTEXT("Angle", "Sketch Constraint"), SketchConstraintType::Angle);
cbtn("design_c_radius", _L_CONTEXT("Radius", "Sketch Constraint"), SketchConstraintType::Radius);
cbtn("design_c_diameter", _L_CONTEXT("Diameter", "Sketch Constraint"), SketchConstraintType::Diameter);
cbtn("design_c_fix", _L_CONTEXT("Fix point (anchor in place)", "Sketch Constraint"), SketchConstraintType::Fix);
cbtn("design_c_dist_x", _L_CONTEXT("Horizontal distance", "Sketch Constraint"), SketchConstraintType::DistanceX);
cbtn("design_c_dist_y", _L_CONTEXT("Vertical distance", "Sketch Constraint"), SketchConstraintType::DistanceY);
// Trim/Extend are now standalone SKETCH scissors (Mode::Trim/Extend) in the sketch
// toolbar, NOT Constrain buttons. The other edit ops (Mirror/Offset/Fillet/Chamfer/
// Move/…) are first-class sketch tools too. Done constraining = the action-bar ✓.
@@ -1894,7 +1886,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
// --- Extrude dialog (consumes the selected sketch) ---
m_box_extrude = new wxBoxSizer(wxVERTICAL);
m_box_extrude->Add(card_header(m_cards, "design_extrude", _L("Extrude"), m_hdr_extrude), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_extrude->Add(card_header(m_cards, "design_extrude", _L_CONTEXT("Extrude", "Design"), m_hdr_extrude), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_extrude->Add(new wxStaticLine(m_cards), 0, wxEXPAND | wxALL, 8);
m_extrude_sketch_label = new wxStaticText(m_cards, wxID_ANY, _L("Sketch: —"));
m_box_extrude->Add(m_extrude_sketch_label, 0, wxLEFT | wxRIGHT | wxTOP, 12);
@@ -1912,9 +1904,9 @@ DesignPanel::DesignPanel(wxWindow* parent)
// End condition (order MUST match ExtrudeEnd: Blind/Symmetric/TwoSided/ThroughAll/
// UpToFace/UpToVertex). Up-to-face uses the currently click-selected solid face.
m_extrude_end = make_combo(m_cards);
for (const char* s : { "Blind", "Symmetric", "Two-sided", "Through all",
"Up to face", "Up to vertex" })
m_extrude_end->Append(s);
for (const char* s : { L("Blind"), L("Symmetric"), L("Two-sided"), L("Through all"),
L("Up to face"), L("Up to vertex") })
m_extrude_end->Append(_L(s));
m_extrude_end->SetSelection(0);
eform->Add(new wxStaticText(m_cards, wxID_ANY, _L("End")), 0, wxALIGN_CENTER_VERTICAL);
eform->Add(m_extrude_end, 0, wxEXPAND);
@@ -1931,8 +1923,8 @@ DesignPanel::DesignPanel(wxWindow* parent)
// Order is load-bearing: index maps to BooleanMode (New=0, Add=1, Cut=2, Intersect=3).
// Labels use Onshape wording so the choice reads as the user thinks of it.
m_mode->Append(_L("New body")); // separate coexisting solid
m_mode->Append(_L("Join")); // fuse into the target body (was "Add")
m_mode->Append(_L("Cut")); // subtract from the target body
m_mode->Append(_L_CONTEXT("Join", "Boolean Mode")); // fuse into the target body (was "Add")
m_mode->Append(_L_CONTEXT("Cut", "Boolean Mode")); // subtract from the target body
m_mode->Append(_L("Intersect")); // keep only the overlap
m_mode->SetSelection(0);
eform->Add(new wxStaticText(m_cards, wxID_ANY, _L("Result")), 0, wxALIGN_CENTER_VERTICAL);
@@ -1968,6 +1960,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
m_face_group = make_combo(m_cards);
m_face_group->Append(_L("Top")); // index 0 -> FaceGroup::Top
m_face_group->Append(_L("Bottom")); // 1 -> Bottom
// TRN Fillet/Chamfer edge group used when no edge is picked: the side edges, as opposed to the top and bottom ones.
m_face_group->Append(_L("Lateral")); // 2 -> Lateral
m_face_group->Append(_L("All")); // 3 -> All
m_face_group->SetSelection(3);
@@ -2129,8 +2122,8 @@ DesignPanel::DesignPanel(wxWindow* parent)
m_revolve_mode = make_combo(m_cards);
m_revolve_mode->Append(_L("New body")); // same four words as Extrude
m_revolve_mode->Append(_L("Join"));
m_revolve_mode->Append(_L("Cut"));
m_revolve_mode->Append(_L_CONTEXT("Join", "Boolean Mode"));
m_revolve_mode->Append(_L_CONTEXT("Cut", "Boolean Mode"));
m_revolve_mode->Append(_L("Intersect"));
m_revolve_mode->SetSelection(0);
rform->Add(new wxStaticText(m_cards, wxID_ANY, _L("Result")), 0, wxALIGN_CENTER_VERTICAL);
@@ -2159,8 +2152,8 @@ DesignPanel::DesignPanel(wxWindow* parent)
m_sweep_mode = make_combo(m_cards);
m_sweep_mode->Append(_L("New body")); // same four words as Extrude
m_sweep_mode->Append(_L("Join"));
m_sweep_mode->Append(_L("Cut"));
m_sweep_mode->Append(_L_CONTEXT("Join", "Boolean Mode"));
m_sweep_mode->Append(_L_CONTEXT("Cut", "Boolean Mode"));
m_sweep_mode->Append(_L("Intersect"));
m_sweep_mode->SetSelection(0);
sform->Add(new wxStaticText(m_cards, wxID_ANY, _L("Result")), 0, wxALIGN_CENTER_VERTICAL);
@@ -2172,14 +2165,14 @@ DesignPanel::DesignPanel(wxWindow* parent)
// --- Pattern (replicate the target body: linear or circular) ---
m_box_pattern = new wxBoxSizer(wxVERTICAL);
m_box_pattern->Add(card_header(m_cards, "design_pattern", _L("Pattern"), m_hdr_pattern), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_pattern->Add(card_header(m_cards, "design_pattern", _L_CONTEXT("Pattern", "Design"), m_hdr_pattern), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_pattern->Add(new wxStaticLine(m_cards), 0, wxEXPAND | wxALL, 8);
{
auto* pform = two_col_form();
m_pattern_type = make_combo(m_cards);
m_pattern_type->Append(_L("Linear"));
m_pattern_type->Append(_L("Circular"));
m_pattern_type->Append(_L_CONTEXT("Linear", "Design"));
m_pattern_type->Append(_L_CONTEXT("Circular", "Design"));
m_pattern_type->SetSelection(0);
pform->Add(new wxStaticText(m_cards, wxID_ANY, _L("Type")), 0, wxALIGN_CENTER_VERTICAL);
pform->Add(m_pattern_type, 0, wxEXPAND);
@@ -2215,7 +2208,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
auto* bform = two_col_form();
m_bool_op = make_combo(m_cards);
m_bool_op->Append(_L("Join")); // the Extrude result word; the offer row says the same
m_bool_op->Append(_L_CONTEXT("Join", "Boolean Mode")); // the Extrude result word; the offer row says the same
m_bool_op->Append(_L("Subtract"));
m_bool_op->Append(_L("Intersect"));
m_bool_op->SetSelection(0);
@@ -2255,7 +2248,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
// --- Cut (split a body with a plane): parameters only; ✓/✗ live on the ribbon ---
m_box_cut = new wxBoxSizer(wxVERTICAL);
m_box_cut->Add(card_header(m_cards, "design_cut", _L("Cut"), m_hdr_cut), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_cut->Add(card_header(m_cards, "design_cut", _L_CONTEXT("Cut", "Design"), m_hdr_cut), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_cut->Add(new wxStaticLine(m_cards), 0, wxEXPAND | wxALL, 8);
{
auto* cform = two_col_form();
@@ -2314,6 +2307,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
m_plane_base = make_combo(m_cards);
populate_plane_choices(m_plane_base); // XY/XZ/YZ + any existing datum planes
// TRN Plane tool: the reference plane (XY, XZ, YZ or a datum) the new plane is built from.
plform->Add(new wxStaticText(m_cards, wxID_ANY, _L("Base")), 0, wxALIGN_CENTER_VERTICAL);
plform->Add(m_plane_base, 0, wxEXPAND);
@@ -2371,8 +2365,8 @@ DesignPanel::DesignPanel(wxWindow* parent)
m_loft_mode = make_combo(m_cards);
m_loft_mode->Append(_L("New body")); // same four words as Extrude
m_loft_mode->Append(_L("Join"));
m_loft_mode->Append(_L("Cut"));
m_loft_mode->Append(_L_CONTEXT("Join", "Boolean Mode"));
m_loft_mode->Append(_L_CONTEXT("Cut", "Boolean Mode"));
m_loft_mode->Append(_L("Intersect"));
m_loft_mode->SetSelection(0);
lform->Add(new wxStaticText(m_cards, wxID_ANY, _L("Result")), 0, wxALIGN_CENTER_VERTICAL);
@@ -2515,7 +2509,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
sform->Add(m_shell_face_label, 0, wxALIGN_CENTER_VERTICAL);
m_box_shell = new wxBoxSizer(wxVERTICAL);
m_box_shell->Add(card_header(m_cards, "design_shell", _L("Shell"), m_hdr_shell), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_shell->Add(card_header(m_cards, "design_shell", _L_CONTEXT("Shell", "Design"), m_hdr_shell), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_shell->Add(new wxStaticLine(m_cards), 0, wxEXPAND | wxALL, 8);
m_box_shell->Add(new wxStaticText(m_cards, wxID_ANY,
_L("Pick a solid face to open it, then set the wall thickness.")),
@@ -2663,7 +2657,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
// --- Rib (thin wall from an open sketch line, fused to a body) ---
m_box_rib = new wxBoxSizer(wxVERTICAL);
m_box_rib->Add(card_header(m_cards, "design_rib", _L("Rib"), m_hdr_rib), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_rib->Add(card_header(m_cards, "design_rib", _L_CONTEXT("Rib", "Design"), m_hdr_rib), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_rib->Add(new wxStaticLine(m_cards), 0, wxEXPAND | wxALL, 8);
{
auto* rform = two_col_form();
@@ -2699,7 +2693,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
// --- Project (project body edges onto a plane as sketch entities) ---
m_box_project = new wxBoxSizer(wxVERTICAL);
m_box_project->Add(card_header(m_cards, "design_sketch", _L("Project"), m_hdr_project), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_project->Add(card_header(m_cards, "design_sketch", _L_CONTEXT("Project", "Design"), m_hdr_project), 0, wxLEFT | wxRIGHT | wxTOP, 12);
m_box_project->Add(new wxStaticLine(m_cards), 0, wxEXPAND | wxALL, 8);
{
auto* pform = two_col_form();
@@ -2937,11 +2931,11 @@ DesignPanel::DesignPanel(wxWindow* parent)
m_cs_hx = make_spin(m_cards, 1.0, -100000.0, 100000.0);
m_cs_hy = make_spin(m_cards, 0.0, -100000.0, 100000.0);
m_cs_hz = make_spin(m_cards, 0.0, -100000.0, 100000.0);
csform->Add(new wxStaticText(m_cards, wxID_ANY, _L("X hint X")), 0, wxALIGN_CENTER_VERTICAL);
csform->Add(new wxStaticText(m_cards, wxID_ANY, _L("X direction X")), 0, wxALIGN_CENTER_VERTICAL);
csform->Add(spin_frame(m_cs_hx), 0, wxEXPAND);
csform->Add(new wxStaticText(m_cards, wxID_ANY, _L("X hint Y")), 0, wxALIGN_CENTER_VERTICAL);
csform->Add(new wxStaticText(m_cards, wxID_ANY, _L("X direction Y")), 0, wxALIGN_CENTER_VERTICAL);
csform->Add(spin_frame(m_cs_hy), 0, wxEXPAND);
csform->Add(new wxStaticText(m_cards, wxID_ANY, _L("X hint Z")), 0, wxALIGN_CENTER_VERTICAL);
csform->Add(new wxStaticText(m_cards, wxID_ANY, _L("X direction Z")), 0, wxALIGN_CENTER_VERTICAL);
csform->Add(spin_frame(m_cs_hz), 0, wxEXPAND);
m_box_coordsys->Add(csform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
@@ -3190,7 +3184,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
// one click away on a row the user has just selected — the message points at it instead
// of describing a problem with no way out.
if (const std::string* why = (sel >= 0) ? mate_conflict_reason(sel) : nullptr) {
set_status(StatusKind::Error, wxString::FromUTF8(*why) + _L(" — the eye suppresses this mate"));
set_status(StatusKind::Error, wxString::Format(_L("%s. Click the eye icon to suppress this mate."), wxString::FromUTF8(*why)));
} else if (sel >= 0 && sel < int(m_doc.features.size())) {
// Name the two gestures the row supports, because neither is visible on it.
set_status(StatusKind::Info, wxString::Format(
@@ -3882,7 +3876,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
if (got && m_viewport) m_viewport->set_escalate_on_repick(true);
}
const int nb = int(m_doc.bodies.size());
const wxString bodytag = (nb > 1) ? wxString::Format(_L("Body %d "), body + 1) : wxString();
const bool bodytag = nb > 1;
// Each sub-element line ends by naming the NEXT click (gem). Escalation to the
// whole body is a gesture nothing on screen would otherwise reveal, and the status line
// is the only surface that can teach it at the moment it applies. It REPLACES the old
@@ -3894,13 +3888,22 @@ DesignPanel::DesignPanel(wxWindow* parent)
// into the panel. Say "what applies to it", never "verbs" — that is this codebase's
// word for a tool-offer entry, not a word the drawing office uses, and the plane and
// bodies-list lines already say it the right way.
set_status(level == 4 ? bodytag + _L("vertex selected — click again for the whole body")
: level == 1 ? bodytag + _L("selected (whole body) — right-click for what applies to it")
: level == 2 ? bodytag + wxString::Format(_L("face %d selected — right-click to push/pull it, or click again for the whole body"), face)
: level == 3 && m_sel_solid_edges.size() > 1
? bodytag + wxString::Format(_L_PLURAL("%zu edge selected — Shift+click adds or removes one, Fillet/Chamfer dresses them all", "%zu edges selected — Shift+click adds or removes one, Fillet/Chamfer dresses them all", m_sel_solid_edges.size()), m_sel_solid_edges.size())
: level == 3 ? bodytag + wxString::Format(_L("edge %d selected — Shift+click to add edges, or click again for the whole body"), edge)
: _L("Nothing selected"));
set_status(level == 4 ? (bodytag ? wxString::Format(_L("Body %d: vertex selected — click again for the whole body"), body + 1)
: _L("Vertex selected — click again for the whole body"))
: level == 1 ? (bodytag ? wxString::Format(_L("Body %d selected (whole body) — right-click for what applies to it"), body + 1)
: _L("Whole body selected — right-click for what applies to it"))
: level == 2 ? (bodytag ? wxString::Format(_L("Body %d: face %d selected — right-click to push/pull it, or click again for the whole body"), body + 1, face)
: wxString::Format(_L("Face %d selected — right-click to push/pull it, or click again for the whole body"), face))
: level == 3 && m_sel_solid_edges.size() > 1
? (bodytag ? wxString::Format(_L_PLURAL("Body %d: %zu edge selected — Shift+click adds or removes one, Fillet/Chamfer dresses them all",
"Body %d: %zu edges selected — Shift+click adds or removes one, Fillet/Chamfer dresses them all",
unsigned(m_sel_solid_edges.size())), body + 1, m_sel_solid_edges.size())
: wxString::Format(_L_PLURAL("%zu edge selected — Shift+click adds or removes one, Fillet/Chamfer dresses them all",
"%zu edges selected — Shift+click adds or removes one, Fillet/Chamfer dresses them all",
unsigned(m_sel_solid_edges.size())), m_sel_solid_edges.size()))
: level == 3 ? (bodytag ? wxString::Format(_L("Body %d: edge %d selected — Shift+click to add edges, or click again for the whole body"), body + 1, edge)
: wxString::Format(_L("Edge %d selected — Shift+click to add edges, or click again for the whole body"), edge))
: _L("Nothing selected"));
m_status->Refresh();
});
// A click on nothing drops a list row as it drops a pick. Not while a card is open: the
@@ -3995,7 +3998,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
if (m_viewport && m_viewport->is_sketching())
m_viewport->set_sketch_plane(plane_from_choice(m_ref_plane));
}
const char* nm = (base == 0) ? "XY" : (base == 1) ? "XZ" : (base == 2) ? "YZ" : "datum";
const wxString nm = ref_plane_name(base);
// Both halves named the TOOLBAR, which no longer carries either button: the tools
// moved to the offer. Name the gesture that actually works in each mode, and say
// what a plain click does, since the two are easy to confuse on a plane.
@@ -4036,10 +4039,12 @@ DesignPanel::DesignPanel(wxWindow* parent)
if (m_xf_angle) m_xf_angle->SetValue(sign * aa.angle() * 180.0 / M_PI);
}
const int nb = int(m_doc.bodies.size());
const wxString tag = (nb > 1) ? wxString::Format(_L("Body %d "), body + 1) : wxString();
const Vec3d t = xform.translation();
set_status(StatusKind::Info, tag + wxString::Format(_L("placed (%.1f, %.1f, %.1f) mm — drag arrows to move, rings to rotate"),
t.x(), t.y(), t.z()));
set_status(StatusKind::Info, nb > 1
? wxString::Format(_L("Body %d placed at (%.1f, %.1f, %.1f) mm — drag arrows to move, rings to rotate"),
body + 1, t.x(), t.y(), t.z())
: wxString::Format(_L("Placed at (%.1f, %.1f, %.1f) mm — drag arrows to move, rings to rotate"),
t.x(), t.y(), t.z()));
});
// Fillet/Chamfer radius gizmo: dragging (or editing) the edge-anchored arrow writes the
@@ -4126,7 +4131,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
set_status(error ? StatusKind::Error : StatusKind::Info, wxString::FromUTF8(msg));
});
m_viewport->set_on_sketch_exit_refused([this]() {
set_status(StatusKind::Info, _L("Sketch kept — Finish to commit it, Cancel to discard"));
set_status(StatusKind::Info, _L("Sketch kept — Confirm to commit it, Cancel to discard"));
});
// Ctrl+Z / Ctrl+Shift+Z (Ctrl+Y) from the viewport → feature-history undo/redo.
@@ -4444,7 +4449,7 @@ void DesignPanel::apply_dof_status(int dof, bool ok, bool has_constraints)
m_dof_status->SetLabel(_L("✓ Fully constrained"));
} else if (dof > 0) {
m_dof_status->SetForegroundColour(dp_ctl_text());
m_dof_status->SetLabel(wxString::Format(_L("%d degrees of freedom"), dof));
m_dof_status->SetLabel(wxString::Format(_L_PLURAL("%d degree of freedom", "%d degrees of freedom", dof), dof));
} else {
m_dof_status->SetLabel(wxString());
}
@@ -4521,7 +4526,7 @@ void DesignPanel::set_ui_mode(UiMode m)
if (sketching && m_sketch_banner_txt != nullptr)
m_sketch_banner_txt->SetLabel(
wxString::Format(_L("Editing: Sketch %d · N = look normal to the plane · "
"Finish or Cancel in the toolbar"),
"Confirm or Cancel in the toolbar"),
m_feature_counter + 1));
m_sketch_banner->Show(sketching);
m_sketch_banner->GetParent()->Layout();
@@ -4778,7 +4783,7 @@ void DesignPanel::text_dialog_done(bool accepted)
void DesignPanel::on_import_svg()
{
wxFileDialog dlg(this, _L("Import SVG"), wxEmptyString, wxEmptyString,
"SVG files (*.svg)|*.svg|All files|*.*",
_L("SVG files (*.svg)|*.svg|All files|*.*"),
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (dlg.ShowModal() != wxID_OK)
return;
@@ -4890,7 +4895,7 @@ bool DesignPanel::recompute_guarded(const wxString& message)
void DesignPanel::on_import_step()
{
wxFileDialog dlg(this, _L("Import STEP"), wxEmptyString, wxEmptyString,
"STEP files (*.step;*.stp)|*.step;*.stp|All files|*.*",
_L("STEP files (*.step;*.stp)|*.step;*.stp|All files|*.*"),
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (dlg.ShowModal() != wxID_OK)
return;
@@ -4938,7 +4943,9 @@ void DesignPanel::on_import_step()
set_tree_selection(int(m_doc.features.size()) - 1);
set_status_ok(); // canonical post-recompute viewport/pick/parts refresh
set_status(StatusKind::Info, wxString::Format(
_L("Imported %d solid(s) — pick a face or edge, then Fillet / Cut / Shell to modify"),
_L_PLURAL("Imported %d solid — pick a face or edge, then Fillet / Cut / Shell to modify",
"Imported %d solids — pick a face or edge, then Fillet / Cut / Shell to modify",
unsigned(solids.size())),
int(solids.size())));
}
@@ -4949,7 +4956,7 @@ void DesignPanel::on_import_step()
void DesignPanel::on_import_mesh()
{
wxFileDialog dlg(this, _L("Import mesh"), wxEmptyString, wxEmptyString,
"Mesh files (*.stl;*.obj)|*.stl;*.obj|All files|*.*",
_L("Mesh files (*.stl;*.obj)|*.stl;*.obj|All files|*.*"),
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (dlg.ShowModal() != wxID_OK)
return;
@@ -5032,8 +5039,8 @@ void DesignPanel::on_import_mesh()
stats.kept_tris, stats.faces_final, stats.volume));
} else {
set_status(StatusKind::Warning, wxString::Format(
_L("Imported as an open shell (not watertight): %d boundary edge(s), %d non-manifold "
"edge(s) — %d triangles → %d faces. The source mesh has holes or duplicated "
_L("Imported as an open shell (not watertight). Boundary edges: %d, non-manifold "
"edges: %d, triangles: %d → faces: %d. The source mesh has holes or duplicated "
"geometry; boolean features may fail on it"),
stats.boundary_edges, stats.nonmanifold_edges, stats.kept_tris, stats.faces_final));
}
@@ -5144,7 +5151,7 @@ void DesignPanel::cancel_insert()
set_ui_mode(UiMode::Feature);
sync_sketch_display();
refresh_tree();
set_status(StatusKind::Info, _L("Insert cancelled"));
set_status(StatusKind::Info, _L("Insert canceled"));
}
void DesignPanel::on_transform_imported(int feat_idx)
@@ -5171,7 +5178,7 @@ void DesignPanel::on_add_sketch()
m_doc.add_sketch(shape, plane, m_width->GetValue(), m_height->GetValue(),
m_radius->GetValue(), feature_name(_L("Sketch")));
m_doc.recompute(); // a lone sketch yields an empty body; that is expected
set_status(StatusKind::Info, wxString::Format(_L("Sketch added on %s — select it, then right-click to Extrude"), where));
set_status(StatusKind::Info, wxString::Format(_L("Sketch added (plane: %s) — select it, then right-click to Extrude"), where));
refresh_tree();
}
@@ -5882,7 +5889,8 @@ void DesignPanel::on_check_interference()
body_name(sorted[k].body_b), sorted[k].volume);
if (sorted.size() > shown)
list += wxString::FromUTF8(", …");
set_status(StatusKind::Warning, wxString::Format(_L("%zu overlapping pairs: %s"), sorted.size(), list));
set_status(StatusKind::Warning, wxString::Format(_L_PLURAL("%zu overlapping pair: %s", "%zu overlapping pairs: %s",
unsigned(sorted.size())), sorted.size(), list));
}
// Volume and surface area of the selected body. A report, not a feature: it never checkpoints,
@@ -6131,8 +6139,8 @@ SketchPlane DesignPanel::sketch_plane_from_selection(wxString& what) const
const int fi = (m_sel_solid_face >= 0 && m_sel_solid_body >= 0) ? m_sel_solid_face : m_pick_face;
if (fb >= 0 && fi >= 0 && m_doc.plane_of_face(fb, fi, p)) {
what = (m_doc.bodies.size() > 1)
? wxString::Format(_L("the picked face of Body %d"), fb + 1)
: _L("the picked face");
? wxString::Format(_L("Picked face (Body %d)"), fb + 1)
: _L("Picked face");
return p;
}
what = ref_plane_name(m_ref_plane);
@@ -6150,8 +6158,8 @@ bool DesignPanel::sketch_plane_target(wxString& what) const
SketchPlane p;
if (fb >= 0 && fi >= 0 && m_doc.plane_of_face(fb, fi, p)) {
what = (m_doc.bodies.size() > 1)
? wxString::Format(_L("the picked face of Body %d"), fb + 1)
: _L("the picked face");
? wxString::Format(_L("Picked face (Body %d)"), fb + 1)
: _L("Picked face");
return true;
}
if (m_plane_picked) { what = ref_plane_name(m_ref_plane); return true; }
@@ -6377,8 +6385,10 @@ static wxString sketch_step_prompt(DesignSketchTool::Mode m, int step, int picks
switch (m) {
case Mode::Select:
return picks > 0
? wxString::Format(_L("%d selected · Del removes them · Shift-click adds · "
"double-click takes the whole loop"), picks)
? wxString::Format(_L_PLURAL("%d selected · Del removes it · Shift-click adds · "
"double-click takes the whole loop",
"%d selected · Del removes them · Shift-click adds · "
"double-click takes the whole loop", picks), picks)
: _L("Select — click an entity to pick it · drag an endpoint or center to move it · "
"Shift-click adds · Del removes");
case Mode::Constrain:
@@ -6627,8 +6637,7 @@ void DesignPanel::show_offer_menu(const wxPoint& screen_pos)
return (v.accepts & bit) && v.need_bodies <= bodies && v.need_sketches <= sketches
&& (!v.need_sheet || sheet);
};
// Names and reasons live in the generated table as plain literals; they are the same strings
// the toolbar already ships, so the catalogue already carries their translations.
// Row names, verb names, refusals, families and hints are L()-marked in the generated table.
// Scope the lookup to the APPLICATION catalog. A bare wxGetTranslation() searches every
// loaded catalog, wxWidgets' own wxstd included — so on a non-English system the two row
// names that happen to be wx standard strings came back translated while the other six,
@@ -6642,7 +6651,7 @@ void DesignPanel::show_offer_menu(const wxPoint& screen_pos)
return wxGetTranslation(wxString::FromUTF8(s), SLIC3R_APP_KEY);
};
auto label = [&](const OfferVerb& v) {
wxString s = tr(v.name);
wxString s = I18N::translate(v.name, "Design");
if (v.key && *v.key) s += "\t" + wxString::FromUTF8(v.key);
return s;
};
@@ -7630,8 +7639,8 @@ void DesignPanel::flip_section_view()
if (!m_viewport || !m_section_on) return;
m_section_upper = !m_section_upper;
m_viewport->set_section_plane(true, m_section_cut_z, m_section_upper);
set_status(StatusKind::Info, wxString::Format(_L("Section view — showing the %s half"),
m_section_upper ? _L("upper") : _L("lower")));
set_status(StatusKind::Info, m_section_upper ? _L("Section view — showing the upper half")
: _L("Section view — showing the lower half"));
}
void DesignPanel::sync_body_visible()
@@ -8295,8 +8304,10 @@ void DesignPanel::apply_live_constraint(SketchConstraintType type)
// tool auto-selects only the entity it just drew — so after drawing two lines exactly
// one is selected and the button correctly refuses. Say how many are picked, or the
// refusal is indistinguishable from a dead button.
fail(wxString::Format(_L("%s — %d selected. Press Esc for the Select tool, click one "
"line, then Shift- or Ctrl-click the other."),
fail(wxString::Format(_L_PLURAL("%s — %d selected. Press Esc for the Select tool, click one "
"line, then Shift- or Ctrl-click the other.",
"%s — %d selected. Press Esc for the Select tool, click one "
"line, then Shift- or Ctrl-click the other.", unsigned(sel.size())),
constraint_reject_text(plan.reason, type), int(sel.size())));
return;
case ConstraintPlan::Kind::AskValue:
@@ -8364,7 +8375,7 @@ void DesignPanel::refresh_constrain_dof()
m_dof_status->SetLabel(_L("✓ Fully constrained")); m_dof_status->Show(!m_dof_status->GetLabel().IsEmpty());
} else if (r.dof > 0) {
m_dof_status->SetForegroundColour(dp_ctl_text());
m_dof_status->SetLabel(wxString::Format(_L("%d degrees of freedom"), r.dof)); m_dof_status->Show(!m_dof_status->GetLabel().IsEmpty());
m_dof_status->SetLabel(wxString::Format(_L_PLURAL("%d degree of freedom", "%d degrees of freedom", r.dof), r.dof)); m_dof_status->Show(!m_dof_status->GetLabel().IsEmpty());
} else {
m_dof_status->SetLabel(wxString()); m_dof_status->Show(!m_dof_status->GetLabel().IsEmpty());
}
@@ -8398,7 +8409,8 @@ wxString DesignPanel::constraint_label(const SketchEntityConstraintDef& d) const
// an empty string, or a NULL format string that crashes wxString::Format.
wxString s; s << wxUniChar(c) << ei; // avoid %c assert in Unicode build
if (r == SketchPointRole::P1) s += wxString::FromUTF8("·P1");
else if (r == SketchPointRole::Center) s += wxString::FromUTF8("·Ctr");
// TRN Design sketch: abbreviation of "center", appended to a point tag such as "L3·Ctr"
else if (r == SketchPointRole::Center) s += _L("·Ctr");
else if (r == SketchPointRole::P0) s += wxString::FromUTF8("·P0");
return s;
};
@@ -8408,27 +8420,27 @@ wxString DesignPanel::constraint_label(const SketchEntityConstraintDef& d) const
};
switch (d.type) {
case T::Fix: return wxString::Format(_L("Fix %s"), tag(d.ea, d.ra));
case T::Coincident: return two(_L("Coincident"));
case T::Horizontal: return two(_L("Horizontal"));
case T::Vertical: return two(_L("Vertical"));
case T::Coincident: return two(_L_CONTEXT("Coincident", "Sketch Constraint"));
case T::Horizontal: return two(_L_CONTEXT("Horizontal", "Sketch Constraint"));
case T::Vertical: return two(_L_CONTEXT("Vertical", "Sketch Constraint"));
case T::Distance: return wxString::Format("%s = %s", two(_L("Distance")), en_format(d.value));
case T::LockX: return wxString::Format(_L("Lock X %s"), tag(d.ea, d.ra));
case T::LockY: return wxString::Format(_L("Lock Y %s"), tag(d.ea, d.ra));
case T::EqualLength: return two(_L("Equal"));
case T::Parallel: return two(_L("Parallel"));
case T::Perpendicular: return two(_L("Perpendicular"));
case T::Concentric: return two(_L("Concentric"));
case T::Tangent: return two(_L("Tangent"));
case T::Midpoint: return two(_L("Midpoint"));
case T::EqualLength: return two(_L_CONTEXT("Equal", "Sketch Constraint"));
case T::Parallel: return two(_L_CONTEXT("Parallel", "Sketch Constraint"));
case T::Perpendicular: return two(_L_CONTEXT("Perpendicular", "Sketch Constraint"));
case T::Concentric: return two(_L_CONTEXT("Concentric", "Sketch Constraint"));
case T::Tangent: return two(_L_CONTEXT("Tangent", "Sketch Constraint"));
case T::Midpoint: return two(_L_CONTEXT("Midpoint", "Sketch Constraint"));
case T::Symmetric: return wxString::Format(_L("Symmetric %s — %s / %s"),
tag(d.ea, d.ra), tag(d.eb, d.rb), tag(d.ec, d.rc));
case T::SymmetricAboutY: return wxString::Format(_L("Symmetric about Y axis %s — %s"),
tag(d.ea, d.ra), tag(d.eb, d.rb));
case T::SymmetricAboutX: return wxString::Format(_L("Symmetric about X axis %s — %s"),
tag(d.ea, d.ra), tag(d.eb, d.rb));
case T::Angle: return wxString::Format(wxString::FromUTF8("%s = %s°"), two(_L("Angle")), en_format(d.value * 180.0 / M_PI, 1));
case T::Radius: return wxString::Format("%s %s = %s", _L("Radius"), tag(d.ea, d.ra), en_format(d.value));
case T::Diameter: return wxString::Format("%s %s = %s", _L("Diameter"), tag(d.ea, d.ra), en_format(d.value));
case T::Angle: return wxString::Format(wxString::FromUTF8("%s = %s°"), two(_L_CONTEXT("Angle", "Sketch Constraint")), en_format(d.value * 180.0 / M_PI, 1));
case T::Radius: return wxString::Format("%s %s = %s", _L_CONTEXT("Radius", "Sketch Constraint"), tag(d.ea, d.ra), en_format(d.value));
case T::Diameter: return wxString::Format("%s %s = %s", _L_CONTEXT("Diameter", "Sketch Constraint"), tag(d.ea, d.ra), en_format(d.value));
case T::PointOnLine: return two(_L("On line"));
case T::PointOnObject: return two(_L("On edge"));
}
@@ -9702,7 +9714,7 @@ void DesignPanel::load_feature_into_dialog(const CadFeature& f)
wxString s;
for (size_t i = 0; i < m_del_faces.size(); ++i) {
if (i > 0) s += ", ";
s += wxString::Format("Face %d", m_del_faces[i]);
s += wxString::Format(_L("Face %d"), m_del_faces[i]);
}
m_del_face_list->SetLabel(s.empty() ? _L("(none)") : s);
}
@@ -9768,7 +9780,7 @@ void DesignPanel::on_edit_feature()
m_viewport->set_display_sketches({});
m_viewport->edit_sketch(f.entities, f.entity_constraints, f.plane);
}
set_status(StatusKind::Info, _L("Editing sketch — drag a handle or click a quote to edit"));
set_status(StatusKind::Info, _L("Editing sketch — drag a handle or double-click a dimension to edit it"));
} else {
load_feature_into_dialog(f);
open_tool(Tool::Sketch);
@@ -9963,7 +9975,7 @@ void DesignPanel::on_export_step()
return;
}
wxFileDialog dlg(this, _L("Export STEP"), wxEmptyString, "model.step",
"STEP files (*.step;*.stp)|*.step;*.stp",
_L("STEP files (*.step;*.stp)|*.step;*.stp"),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if (dlg.ShowModal() != wxID_OK)
return;
@@ -11480,20 +11492,20 @@ void DesignPanel::open_tool(Tool t)
};
switch (t) {
case Tool::Sketch: m_hdr_sketch->SetLabel(title(_L("Sketch"))); break;
case Tool::Extrude: m_hdr_extrude->SetLabel(title(_L("Extrude"))); break;
case Tool::Extrude: m_hdr_extrude->SetLabel(title(_L_CONTEXT("Extrude", "Design"))); break;
case Tool::Dressup: m_hdr_dressup->SetLabel(title(
m_dressup_type->GetSelection() == 0 ? _L("Fillet") : _L("Chamfer"))); break;
case Tool::Hole: m_hdr_hole->SetLabel(title(_L("Hole"))); break;
case Tool::Thread: m_hdr_thread->SetLabel(title(_L("Thread"))); break;
case Tool::Shell: m_hdr_shell->SetLabel(title(_L("Shell"))); break;
case Tool::Shell: m_hdr_shell->SetLabel(title(_L_CONTEXT("Shell", "Design"))); break;
case Tool::Revolve: m_hdr_revolve->SetLabel(title(_L("Revolve"))); break;
case Tool::Sweep: m_hdr_sweep->SetLabel(title(_L("Sweep"))); break;
case Tool::Pattern: m_hdr_pattern->SetLabel(title(_L("Pattern"))); break;
case Tool::Pattern: m_hdr_pattern->SetLabel(title(_L_CONTEXT("Pattern", "Design"))); break;
case Tool::Plane: m_hdr_plane->SetLabel(title(_L("Plane"))); break;
case Tool::Loft: m_hdr_loft->SetLabel(title(_L("Loft"))); break;
case Tool::Draft: m_hdr_draft->SetLabel(title(_L("Draft"))); break;
case Tool::Boolean: m_hdr_boolean->SetLabel(title(_L("Boolean"))); break;
case Tool::Cut: m_hdr_cut->SetLabel(title(_L("Cut"))); break;
case Tool::Cut: m_hdr_cut->SetLabel(title(_L_CONTEXT("Cut", "Design"))); break;
case Tool::Axis: m_hdr_axis->SetLabel(title(_L("Axis"))); break;
case Tool::CoordSys: m_hdr_coordsys->SetLabel(title(_L("Coordinate system"))); break;
case Tool::SurfaceExtrude: m_hdr_surf_extrude->SetLabel(title(_L("Surface Extrude"))); break;
@@ -11505,8 +11517,8 @@ void DesignPanel::open_tool(Tool t)
case Tool::Transform: m_hdr_transform->SetLabel(title(_L("Transform"))); break;
case Tool::Mirror: m_hdr_mirror->SetLabel(title(_L("Mirror"))); break;
case Tool::Thicken: m_hdr_thicken->SetLabel(title(_L("Thicken"))); break;
case Tool::Rib: m_hdr_rib->SetLabel(title(_L("Rib"))); break;
case Tool::Project: m_hdr_project->SetLabel(title(_L("Project"))); break;
case Tool::Rib: m_hdr_rib->SetLabel(title(_L_CONTEXT("Rib", "Design"))); break;
case Tool::Project: m_hdr_project->SetLabel(title(_L_CONTEXT("Project", "Design"))); break;
case Tool::DeleteFace: m_hdr_delete_face->SetLabel(title(_L("Delete Face"))); break;
case Tool::Helix: m_hdr_helix->SetLabel(title(_L("Helix"))); break;
case Tool::Mate: m_hdr_mate->SetLabel(title(_L("Mate"))); break;
@@ -11743,7 +11755,7 @@ void DesignPanel::tool_cancel()
show_move_card(false);
feed_bodies(); // re-render the reverted placement
update_action_bar();
set_status(StatusKind::Info, _L("Move cancelled"));
set_status(StatusKind::Info, _L("Move canceled"));
return;
}
if (m_active == Tool::Insert) { cancel_insert(); return; }
@@ -11873,7 +11885,7 @@ void DesignPanel::escape()
return;
}
if (m_ui_mode == UiMode::Sketch) {
set_status(StatusKind::Info, _L("Sketch kept — Finish to commit it, Cancel to discard"));
set_status(StatusKind::Info, _L("Sketch kept — Confirm to commit it, Cancel to discard"));
}
return;
}
@@ -11956,8 +11968,10 @@ void DesignPanel::do_undo_redo(bool redo)
drop_selection();
reset_edit_state();
after_tree_edit(true); // refresh tree + viewport meshes + status from the restored doc
set_status(StatusKind::Info, wxString::Format(redo ? _L("Redo (%zu more)") : _L("Undo (%zu more)"),
redo ? m_doc.redo_depth() : m_doc.undo_depth()));
const size_t depth = redo ? m_doc.redo_depth() : m_doc.undo_depth();
set_status(StatusKind::Info, wxString::Format(redo ? _L_PLURAL("Redo (%zu more step)", "Redo (%zu more steps)", unsigned(depth))
: _L_PLURAL("Undo (%zu more step)", "Undo (%zu more steps)", unsigned(depth)),
depth));
}
// --- Document variables panel ---------------------------------------------------------
+2 -1
View File
@@ -1725,6 +1725,7 @@ void DesignSketchTool::open_polygon_side_editor(int fi)
if (f.begin < 0 || f.begin >= int(m_entities.size())) return;
const double side = (m_entities[f.begin].p1 - m_entities[f.begin].p0).norm();
const wxPoint px(m_last_mouse_x, m_last_mouse_y);
// TRN Design sketch: length of one side of a regular polygon (inline value editor title)
on_inline_edit(px, side, _u8L("Side"),
[this, fi](double v) { set_polygon_side(fi, v); },
[]() {});
@@ -9844,7 +9845,7 @@ std::string DesignSketchTool::build_readout() const
std::string out = b;
// Tell the user how to end a polyline chain — there's no other affordance for it.
if (m_mode == Mode::Polyline && m_points.size() >= 2)
out += " right-click or double-click to finish, click start to close";
out += " " + _u8L("right-click or double-click to finish, click start to close");
return out;
}
if (!m_active) return std::string();
+5 -4
View File
@@ -2,6 +2,7 @@
#include "CalibUtils.hpp"
#include "GUI.hpp"
#include "I18N.hpp"
#include "format.hpp"
#include "Widgets/Label.hpp"
#include "MsgDialog.hpp"
#include "DeviceCore/DevConfigUtil.h"
@@ -67,13 +68,13 @@ static wxString get_default_name(wxString filament_name, CalibMode mode){
case Slic3r::CalibMode::Calib_PA_Tower:
break;
case Slic3r::CalibMode::Calib_Flow_Rate:
filament_name += " Flow Rate Calibrated";
filament_name = format_wxstr(_L("%1% Flow Rate Calibrated"), filament_name);
break;
case Slic3r::CalibMode::Calib_Temp_Tower:
filament_name += " Temperature Calibrated";
filament_name = format_wxstr(_L("%1% Temperature Calibrated"), filament_name);
break;
case Slic3r::CalibMode::Calib_Vol_speed_Tower:
filament_name += " Max Vol Speed Calibrated";
filament_name = format_wxstr(_L("%1% Max Vol Speed Calibrated"), filament_name);
break;
case Slic3r::CalibMode::Calib_VFA_Tower:
break;
@@ -95,7 +96,7 @@ static wxString get_tray_name_by_tray_id(int tray_id)
{
wxString tray_name;
if (tray_id == VIRTUAL_TRAY_MAIN_ID || tray_id == VIRTUAL_TRAY_DEPUTY_ID) {
tray_name = "Ext";
tray_name = _L("Ext");
}
else {
int ams_id = tray_id / 4;
+9 -9
View File
@@ -1130,7 +1130,7 @@ void PageMaterials::sort_list_data(StringList* list, bool add_All_item, bool mat
for (const auto& item : prusa_profiles)
list->append(item, &const_cast<std::string&>(item.get()));
for (const auto& item : other_profiles)
list->append(item, &const_cast<std::string&>(item.get()));
list->append(item.get() == Materials::UNKNOWN ? _L(item.get()) : from_u8(item.get()), &const_cast<std::string&>(item.get()));
}
void PageMaterials::sort_list_data(PresetList* list, const std::vector<ProfilePrintData>& data)
@@ -1210,13 +1210,13 @@ void PageMaterials::on_activate()
}
const char *PageCustom::default_profile_name = "My Settings";
const char *PageCustom::default_profile_name = L("My Settings");
PageCustom::PageCustom(ConfigWizard *parent)
: ConfigWizardPage(parent, _L("Custom Printer Setup"), _L("Custom Printer"))
{
cb_custom = new wxCheckBox(this, wxID_ANY, _L("Define a custom printer profile"));
tc_profile_name = new wxTextCtrl(this, wxID_ANY, default_profile_name);
tc_profile_name = new wxTextCtrl(this, wxID_ANY, _L(default_profile_name));
auto *label = new wxStaticText(this, wxID_ANY, _L("Custom profile name:"));
wxGetApp().UpdateDarkUI(tc_profile_name);
@@ -1224,7 +1224,7 @@ PageCustom::PageCustom(ConfigWizard *parent)
tc_profile_name->Enable(false);
tc_profile_name->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &evt) {
if (tc_profile_name->GetValue().IsEmpty()) {
if (profile_name_prev.IsEmpty()) { tc_profile_name->SetValue(default_profile_name); }
if (profile_name_prev.IsEmpty()) { tc_profile_name->SetValue(_L(default_profile_name)); }
else { tc_profile_name->SetValue(profile_name_prev); }
} else {
profile_name_prev = tc_profile_name->GetValue();
@@ -1463,7 +1463,7 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent)
auto *default_bed = def_bed.get_default_value<ConfigOptionInts>();
spin_bed->SetValue(default_bed != nullptr && default_bed->size() > 0 ? default_bed->get_at(0) : 0);
append_text(_L("Enter the nozzle_temperature needed for extruding your filament."));
append_text(_L("Enter the nozzle temperature needed for extruding your filament."));
append_text(_L("A rule of thumb is 160 to 230℃ for PLA, and 215 to 250℃ for ABS."));
#endif
@@ -1720,7 +1720,7 @@ void ConfigWizardIndex::msw_rescale()
// Materials
const std::string Materials::UNKNOWN = "(Unknown)";
const std::string Materials::UNKNOWN = L("(Unknown)");
void Materials::push(const Preset *preset)
{
@@ -2188,8 +2188,8 @@ void ConfigWizard::priv::select_default_materials_for_printer_models(Technology
}
printer_names += "\n\n";
std::string message = (technology & T_FFF ?
GUI::format(_L("Following printer profiles has no default filament: %1%Please select one manually."), printer_names) :
GUI::format(_L("Following printer profiles has no default material: %1%Please select one manually."), printer_names));
GUI::format(_L("The following printer profiles have no default filament: %1%Please select one manually."), printer_names) :
GUI::format(_L("The following printer profiles have no default material: %1%Please select one manually."), printer_names));
MessageDialog msg(q, message, _L("Notice"), wxOK);
msg.ShowModal();
}
@@ -2449,7 +2449,7 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
}
if (!check_unsaved_preset_changes)
if ((check_unsaved_preset_changes = install_bundles.size() > 0))
header = _L_PLURAL("A new vendor was installed and one of its printers will be activated", "New vendors were installed and one of theirs printers will be activated", install_bundles.size());
header = _L_PLURAL("A new vendor was installed and one of its printers will be activated", "New vendors were installed and one of their printers will be activated", install_bundles.size());
// Decide whether to create snapshot based on run_reason and the reset profile checkbox
bool snapshot = true;
+2 -2
View File
@@ -39,7 +39,7 @@ CrealityDiscoveryDialog::CrealityDiscoveryDialog(wxWindow* parent)
m_list->AppendColumn(_L("Hostname"), wxLIST_FORMAT_LEFT, 14 * em);
m_list->AppendColumn(_L("IP"), wxLIST_FORMAT_LEFT, 14 * em);
auto* dlg_btns = new DialogButtons(this, {"Scan", "OK", "Cancel"}, "", 1 /*left_aligned*/);
auto* dlg_btns = new DialogButtons(this, {L("Scan"), "OK", "Cancel"}, "", 1 /*left_aligned*/);
auto* ok_btn = dlg_btns->GetOK();
ok_btn->SetLabel(_L("Use Selected"));
ok_btn->Disable();
@@ -91,7 +91,7 @@ void CrealityDiscoveryDialog::run_discovery()
if (!h.model_name.empty())
row.model = h.model_name;
else if (h.cfs_capable)
row.model = "(unknown K-series)";
row.model = _u8L("(unknown K-series)");
else
row.model = "Creality";
m_rows.push_back(std::move(row));
+1 -1
View File
@@ -652,7 +652,7 @@ DesktopIntegrationDialog::DesktopIntegrationDialog(wxWindow *parent)
wxString text = _L("Desktop Integration sets this binary to be searchable by the system.\n\nPress \"Perform\" to proceed.");
if (can_undo)
text += "\nPress \"Undo\" to remove previous integration.";
text += "\n" + _L("Press \"Undo\" to remove previous integration.");
vbox->Add(
new wxStaticText( this, wxID_ANY, text),
+1 -1
View File
@@ -154,7 +154,7 @@ void calib_fail_message(MachineObject* obj, std::string cali_mode, std::string r
} else if (reason == "nozzle_diameter is not matched") {
info = _L("Selected diameter and machine diameter do not match");
} else if (reason == "generate auto filament cali gcode failure") {
info = _L("Failed to generate cali gcode");
info = _L("Failed to generate calibration G-code");
} else {
info = wxString(reason);
}
+1 -1
View File
@@ -4313,7 +4313,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
info = _L("Selected diameter and machine diameter do not match");
}
else if (reason == "generate auto filament cali gcode failure") {
info = _L("Failed to generate cali G-code");
info = _L("Failed to generate calibration G-code");
}
else {
info = reason;
@@ -981,7 +981,7 @@ int ReselectMachineDialog::CaculateSwitcherDistribution(MachineObject* obj, cons
}
if (can.material_state == AMSCanType::AMS_CAN_TYPE_EMPTY)
{
material = "Empty";
material = L("Empty");
}
auto itOK = std::find_if(posOK.begin(), posOK.end(), [&](const trayHelper& tray){
+1 -1
View File
@@ -60,7 +60,7 @@ void wgtMsgPanelItem::CreateGui()
text_sizer->Add(m_text_label, 0, wxALIGN_CENTER_VERTICAL);
if (!m_wiki_url.IsEmpty()) {
m_wiki_link = new wxHyperlinkCtrl(this, wxID_ANY, "Wiki->", m_wiki_url);
m_wiki_link = new wxHyperlinkCtrl(this, wxID_ANY, _L("Wiki->"), m_wiki_url);
m_wiki_link->SetNormalColour(m_colour);
m_wiki_link->SetHoverColour(wxColour(0, 0, 200));
m_wiki_link->SetVisitedColour(*wxBLUE);
+2 -1
View File
@@ -19,6 +19,7 @@
#include "libslic3r/Utils.hpp"
#include <functional>
#include "slic3r/GUI/GUI.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "slic3r/GUI/Gizmos/GLGizmoBase.hpp"
#include <wx/arrstr.h>
@@ -165,7 +166,7 @@ void Downloader::start_download(const std::string& full_url)
// Orca: show error
NotificationManager* ntf_mngr = wxGetApp().notification_manager();
ntf_mngr->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel,
"Could not start download due to malformed URL");
_u8L("Could not start download due to malformed URL"));
return;
}
size_t id = get_next_id();
+2 -2
View File
@@ -161,7 +161,7 @@ void FileGet::priv::get_perform()
}
if (!found) {
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR);
evt->SetString(GUI::format_wxstr(L"Failed to find suitable filename. Last name: %1%." , (m_dest_folder / final_filename).string()));
evt->SetString(GUI::format_wxstr(_L("Failed to find suitable filename. Last name: %1%."), (m_dest_folder / final_filename).string()));
evt->SetInt(m_id);
m_evt_handler->QueueEvent(evt);
return;
@@ -367,7 +367,7 @@ void FileGet::priv::get_perform()
//TODO: report?
//error_message = GUI::format("Failed to write and move %1% to %2%", tmp_path, dest_path);
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR);
evt->SetString("Failed to write and move.");
evt->SetString(_L("Failed to write and move."));
evt->SetInt(m_id);
m_evt_handler->QueueEvent(evt);
return;
+2 -1
View File
@@ -11,6 +11,7 @@
#include <utility>
#include "GUI_App.hpp"
#include "I18N.hpp"
using json = nlohmann::json;
@@ -165,7 +166,7 @@ wxString FilamentColorCode::GetFilaColorName() const
if (it != m_fila_color_names.end() && !it->second.empty()) { return it->second; }
it = m_fila_color_names.find("en");// retry with English as fallback
return (it != m_fila_color_names.end()) ? it->second : "Unknown";
return (it != m_fila_color_names.end()) ? it->second : _L("Unknown");
}
FilamentColorCode::FilamentColorCode(const wxString& color_code, FilamentColorCodes* owner, FilamentColor&& color, std::unordered_map<wxString, wxString>&& name_map)
+1 -1
View File
@@ -75,7 +75,7 @@ void ExportPresetBundleDialog::on_script_message(const nlohmann::json& j)
OnRequestPresets();
} else if (strCmd == "export_local") {
wxFileDialog dlg(this, _L("Save preset bundle"), "", "export.orca_bundle",
"Orca Preset Bundle (*.orca_bundle)|*.orca_bundle", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
_L("Orca Preset Bundle (*.orca_bundle)|*.orca_bundle"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
wxString path;
wxString name;
if (dlg.ShowModal() == wxID_OK) {
+2 -1
View File
@@ -2179,7 +2179,8 @@ void PrinterAgentChoice::set_value(const std::string& value, bool change_event)
if (match == wxNOT_FOUND)
{
field->SetSelection(wxNOT_FOUND); // nothing shows as selected in the dropdown
field->SetValue(from_u8(value + " (missing)")); // set a value not in the selection (upper display field)
// TRN %1% is the ID of a printer agent that is no longer available
field->SetValue(format_wxstr(_L("%1% (missing)"), value)); // set a value not in the selection (upper display field)
}
else
{
+2 -1
View File
@@ -454,7 +454,8 @@ void FilamentMapManualPanel::UpdateNozzleCountDisplay()
if (m_right_panel->IsUseSeparation()) {
int standard_count = getExtruderNozzleCount(preset_bundle, 1, NozzleVolumeType::nvtStandard);
int highflow_count = getExtruderNozzleCount(preset_bundle, 1, NozzleVolumeType::nvtHighFlow);
wxString right_title = _L("Right Nozzle") + wxString::Format("(Std: %d, HF: %d)", standard_count, highflow_count);
// TRN Nozzle counts: Std = standard flow, HF = high flow
wxString right_title = _L("Right Nozzle") + wxString::Format(_L("(Std: %d, HF: %d)"), standard_count, highflow_count);
m_right_panel->UpdateLabel(right_title);
} else {
int right_count = getExtruderNozzleCountTotal(preset_bundle, 1);
+1 -1
View File
@@ -209,7 +209,7 @@ FileArchiveDialog::FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* ar
m_avc = new ArchiveViewCtrl(this, wxSize(45 * em, 30 * em));
wxDataViewColumn* toggle_column = m_avc->AppendToggleColumn(L"\u2714", 0, wxDATAVIEW_CELL_ACTIVATABLE, 6 * em);
m_avc->AppendTextColumn("filename", 1);
m_avc->AppendTextColumn(_L("filename"), 1);
std::vector<std::shared_ptr<ArchiveViewNode>> stack;
+1
View File
@@ -10190,6 +10190,7 @@ void GLCanvas3D::_render_canvas_toolbar()
[this, p]{p->toggle_show_wireframe(); m_dirty = true;}
);
// TRN View toggle that draws models see-through, so hidden parts show.
create_menu_item( _utf8(L("X-Ray")),
m_canvas_type != ECanvasType::CanvasPreview, // not work on preview
p->is_show_xray(),
+1 -1
View File
@@ -8242,7 +8242,7 @@ bool GUI_App::load_language(wxString language, bool initial)
message += _L("\nYou may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n");
#endif
if (initial)
message + "\n\nApplication will close.";
message += "\n\n" + _L("Application will close.");
wxMessageBox(message, _L("Orca Slicer - Switching language failed"), wxOK | wxICON_ERROR);
if (initial)
std::exit(EXIT_FAILURE);
@@ -102,6 +102,7 @@ void GLGizmoPrimitive::on_render_input_window(float x, float y, float bottom_lim
m_params.type = (PrimitiveType)cur;
m_preview_dirty = true;
}
// TRN Primitive gizmo: label in front of the preset cube size buttons
ImGui::TextUnformatted(_u8L("Quick:").c_str());
ImGui::SameLine();
if (ImGui::SmallButton("10mm")) apply_preset("10mm cube", 10, 10, 10);
@@ -133,11 +134,13 @@ void GLGizmoPrimitive::on_render_input_window(float x, float y, float bottom_lim
dim(_u8L("Radius").c_str(), m_params.sph_radius);
break;
case PrimitiveType::Cone:
// TRN Primitive gizmo: bottom radius of a cone ("Top R" is the top radius)
dim(_u8L("Bottom R").c_str(), m_params.cone_r1);
dim(_u8L("Top R").c_str(), m_params.cone_r2);
dim(_u8L("Height").c_str(), m_params.cone_height);
break;
case PrimitiveType::Torus:
// TRN Primitive gizmo: major radius of a torus ("Minor R" is the tube radius)
dim(_u8L("Major R").c_str(), m_params.torus_r1);
dim(_u8L("Minor R").c_str(), m_params.torus_r2, 0.1, 1.0);
break;
+5 -5
View File
@@ -1351,25 +1351,25 @@ void GLGizmoSVG::draw_window()
assert(m_volume_id.valid());
if (m_volume == nullptr ||
m_volume_id.invalid()) {
ImGui::Text("Not valid state please report reproduction steps on github");
ImGui::Text("%s", _u8L("Not valid state please report reproduction steps on github").c_str());
return;
}
assert(m_volume->emboss_shape.has_value());
if (!m_volume->emboss_shape.has_value()) {
ImGui::Text("No embossed file");
ImGui::Text("%s", _u8L("No embossed file").c_str());
return;
}
assert(m_volume->emboss_shape->svg_file.has_value());
if (!m_volume->emboss_shape->svg_file.has_value()){
ImGui::Text("Missing svg file in embossed shape");
ImGui::Text("%s", _u8L("Missing svg file in embossed shape").c_str());
return;
}
assert(m_volume->emboss_shape->svg_file->file_data != nullptr);
if (m_volume->emboss_shape->svg_file->file_data == nullptr){
ImGui::Text("Missing data of svg file");
ImGui::Text("%s", _u8L("Missing data of svg file").c_str());
return;
}
@@ -2143,7 +2143,7 @@ std::string volume_name(const EmbossShape &shape)
std::string file_name = get_file_name(shape.svg_file->path);
if (!file_name.empty())
return file_name;
return "SVG shape";
return _u8L("SVG shape");
}
CreateVolumeParams create_input(GLCanvas3D &canvas, RaycastManager& raycaster, ModelVolumeType volume_type)
+23 -20
View File
@@ -3,6 +3,7 @@
#include "slic3r/GUI/ImGuiWrapper.hpp"
#include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/NotificationManager.hpp"
#include "slic3r/GUI/format.hpp"
#include "libslic3r/Model.hpp"
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepPrimAPI_MakeRevol.hxx>
@@ -231,11 +232,11 @@ void GLGizmoSketch::draw_canvas()
TopoDS_Shape GLGizmoSketch::build_combined_shape()
{
if (m_profiles.empty() || !m_profiles[0].closed)
throw std::runtime_error("No outer profile");
throw std::runtime_error(_u8L("No outer profile"));
TopoDS_Wire outer_wire = m_profiles[0].to_occt_wire(m_plane);
BRepBuilderAPI_MakeFace face_maker(outer_wire);
if (!face_maker.IsDone()) throw std::runtime_error("Failed to make outer face");
if (!face_maker.IsDone()) throw std::runtime_error(_u8L("Failed to make outer face"));
for (size_t i = 1; i < m_profiles.size(); ++i) {
if (!m_profiles[i].closed) continue;
@@ -243,7 +244,7 @@ TopoDS_Shape GLGizmoSketch::build_combined_shape()
face_maker.Add(inner);
}
face_maker.Build();
if (!face_maker.IsDone()) throw std::runtime_error("Failed to build face with holes");
if (!face_maker.IsDone()) throw std::runtime_error(_u8L("Failed to build face with holes"));
TopoDS_Face face = face_maker.Face();
@@ -253,7 +254,7 @@ TopoDS_Shape GLGizmoSketch::build_combined_shape()
gp_Dir xd(m_plane.x_axis.x(), m_plane.x_axis.y(), m_plane.x_axis.z());
gp_Ax1 axis(o, xd);
BRepPrimAPI_MakeRevol rev(face, axis, m_sp.revolve_deg * M_PI / 180.0);
if (!rev.IsDone()) throw std::runtime_error("Revolve failed");
if (!rev.IsDone()) throw std::runtime_error(_u8L("Revolve failed"));
shape = rev.Shape();
} else {
shape = SketchEngine::make_extrude_face(face, m_plane, m_sp.extrude_len, m_sp.extrude_sym);
@@ -320,8 +321,9 @@ void GLGizmoSketch::on_render_input_window(float x, float y, float bottom_limit)
bool outer = (i == 0);
ImVec4 col = outer ? ImVec4(0,1,0,1) : ImVec4(1,0.3f,0.3f,1);
const std::string label = outer ? _u8L("Outer") : _u8L("Hole");
ImGui::TextColored(col, "%s %d: %zu %s %s", label.c_str(), i+1, p.points.size(),
_u8L("points").c_str(), p.closed ? _u8L("closed").c_str() : "");
const std::string state = p.closed ? _u8L("closed") : std::string();
// TRN Sketch gizmo profile list: "Outer" or "Hole", profile number, point count, "closed" or nothing
ImGui::TextColored(col, "%s", GUI::format(_u8L("%1% %2%: %3% points %4%"), label, i + 1, p.points.size(), state).c_str());
ImGui::SameLine();
if (ImGui::SmallButton("X")) delete_profile(i);
ImGui::PopID();
@@ -336,9 +338,9 @@ void GLGizmoSketch::on_render_input_window(float x, float y, float bottom_limit)
if (ImGui::CollapsingHeader(_u8L("Operation").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) {
static int pi = 0;
const std::string planes = "XY (" + _u8L("Top") + ")" + std::string(1, '\0') + "XZ (" + _u8L("Front") + ")"
+ std::string(1, '\0') + "YZ (" + _u8L("Side") + ")" + std::string(2, '\0');
if (ImGui::Combo(_u8L("Plane").c_str(), &pi, planes.c_str()))
const std::string plane_names[] = {_u8L("XY (Top)"), _u8L("XZ (Front)"), _u8L("YZ (Side)")};
const char* planes[] = {plane_names[0].c_str(), plane_names[1].c_str(), plane_names[2].c_str()};
if (ImGui::Combo(_u8L("Plane").c_str(), &pi, planes, 3))
m_plane = (pi==0) ? SketchPlane::XY() : (pi==1) ? SketchPlane::XZ() : SketchPlane::YZ();
is_revolve = (m_sp.revolve_deg > 0 && m_sp.revolve_deg < 360);
@@ -389,7 +391,8 @@ void GLGizmoSketch::on_render_input_window(float x, float y, float bottom_limit)
ImGui::Separator();
bool ok = has_closed_profile();
if (ok) ImGui::TextColored({0,1,0,1}, "%zu %s", m_profiles.size(), _u8L("closed profile(s)").c_str());
if (ok) ImGui::TextColored({0,1,0,1}, "%s", wxString::Format(_L_PLURAL("%zu closed profile", "%zu closed profiles",
unsigned(m_profiles.size())), m_profiles.size()).ToUTF8().data());
else ImGui::TextColored({0.6f,0.6f,0.6f,1}, "%s", _u8L("Draw a closed profile to enable").c_str());
auto btn = [&](const char* label, bool enabled) {
@@ -404,7 +407,7 @@ void GLGizmoSketch::on_render_input_window(float x, float y, float bottom_limit)
} else if (is_revolve) {
if (btn(_u8L("Revolve").c_str(), ok)) apply_revolve();
} else {
if (btn(_u8L("Extrude").c_str(), ok)) apply_extrude();
if (btn(_u8L_CONTEXT("Extrude", "Design").c_str(), ok)) apply_extrude();
}
if (ImGui::Button(_u8L("Clear all").c_str(), {-1,0})) clear_all();
@@ -419,7 +422,7 @@ void GLGizmoSketch::apply_extrude()
try {
TopoDS_Shape shape = build_combined_shape();
TriangleMesh mesh = SketchEngine::tessellate(shape, m_sp.linear_deflection);
if (mesh.its.indices.empty()) throw std::runtime_error("Empty result");
if (mesh.its.indices.empty()) throw std::runtime_error(_u8L("Empty result"));
wxGetApp().plater()->take_snapshot("Sketch Extrude");
ModelObject* mo = wxGetApp().model().add_object();
mo->name = "Extrusion";
@@ -428,7 +431,7 @@ void GLGizmoSketch::apply_extrude()
wxGetApp().plater()->update();
clear_all();
} catch (const std::exception& e) {
wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, std::string("Extrude: ")+e.what());
wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, GUI::format(_u8L("Extrude: %1%"), e.what()));
}
}
@@ -437,7 +440,7 @@ void GLGizmoSketch::apply_revolve()
try {
TopoDS_Shape shape = build_combined_shape();
TriangleMesh mesh = SketchEngine::tessellate(shape, m_sp.linear_deflection);
if (mesh.its.indices.empty()) throw std::runtime_error("Empty result");
if (mesh.its.indices.empty()) throw std::runtime_error(_u8L("Empty result"));
wxGetApp().plater()->take_snapshot("Sketch Revolve");
ModelObject* mo = wxGetApp().model().add_object();
mo->name = "Revolve";
@@ -446,7 +449,7 @@ void GLGizmoSketch::apply_revolve()
wxGetApp().plater()->update();
clear_all();
} catch (const std::exception& e) {
wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, std::string("Revolve: ")+e.what());
wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, GUI::format(_u8L("Revolve: %1%"), e.what()));
}
}
@@ -455,20 +458,20 @@ void GLGizmoSketch::apply_pocket()
try {
Selection& sel = m_parent.get_selection();
int obj_idx = sel.get_object_idx();
if (obj_idx < 0) throw std::runtime_error("No object selected");
if (obj_idx < 0) throw std::runtime_error(_u8L("No object selected"));
ModelObject* mo = wxGetApp().model().objects[obj_idx];
TopoDS_Wire outer = m_profiles[0].to_occt_wire(m_plane);
BRepBuilderAPI_MakeFace fm(outer);
if (!fm.IsDone()) throw std::runtime_error("Face failed");
if (!fm.IsDone()) throw std::runtime_error(_u8L("Face failed"));
for (size_t i = 1; i < m_profiles.size(); ++i)
if (m_profiles[i].closed) fm.Add(m_profiles[i].to_occt_wire(m_plane));
fm.Build();
if (!fm.IsDone()) throw std::runtime_error("Face with holes failed");
if (!fm.IsDone()) throw std::runtime_error(_u8L("Face with holes failed"));
TopoDS_Shape tool = SketchEngine::make_extrude_face(fm.Face(), m_plane, m_sp.extrude_len + 5.0, false);
TriangleMesh tool_mesh = SketchEngine::tessellate(tool, m_sp.linear_deflection);
if (tool_mesh.its.indices.empty()) throw std::runtime_error("Tool mesh empty");
if (tool_mesh.its.indices.empty()) throw std::runtime_error(_u8L("Tool mesh empty"));
wxGetApp().plater()->take_snapshot("Sketch Pocket");
mo->add_volume(std::move(tool_mesh), ModelVolumeType::NEGATIVE_VOLUME)->set_new_unique_id();
@@ -477,7 +480,7 @@ void GLGizmoSketch::apply_pocket()
clear_all();
wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::RegularNotificationLevel, _u8L("Pocket added (negative volume)").c_str());
} catch (const std::exception& e) {
wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, std::string("Pocket: ")+e.what());
wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, GUI::format(_u8L("Pocket: %1%"), e.what()));
}
}
@@ -411,7 +411,7 @@ bool GLGizmoTextureDisplacement::on_init()
m_desc["circle"] = _L("Circle");
m_desc["sphere"] = _L("Sphere");
m_desc["remove_layer"] = _L("Remove");
m_desc["bake"] = _L("Bake");
m_desc["bake"] = _L_CONTEXT("Bake", "Texture Displacement");
return true;
}
@@ -3509,7 +3509,7 @@ void GLGizmoTextureDisplacement::set_layer_texture(TextureDisplacementLayer &lay
void GLGizmoTextureDisplacement::import_custom_texture(TextureDisplacementLayer &layer)
{
const wxString wildcard = "Images (*.png;*.jpg;*.jpeg;*.bmp)|*.png;*.jpg;*.jpeg;*.bmp";
const wxString wildcard = _L("Images (*.png;*.jpg;*.jpeg;*.bmp)|*.png;*.jpg;*.jpeg;*.bmp");
wxFileDialog dialog(nullptr, _L("Choose a texture image (height map)"), wxEmptyString, wxEmptyString, wildcard,
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (dialog.ShowModal() != wxID_OK)
@@ -6001,8 +6001,8 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
// Midlevel: the height that means "don't move". At 0 the surface only ever bulges outwards;
// at 0.5 mid-grey is neutral and darker texels cut inwards.
m_preview_params_dirty |= float_row("##midlevel", _L("Midlevel"), &layer.midlevel, 0.f, 10.f, "%.2f", false, card_pad);
hover_tip(_u8L("Which grey stays where the surface already is. At 0 the texture only pushes "
"outwards; at 0.5 mid-grey stays put, so darker greys cut in and lighter ones "
hover_tip(_u8L("Which gray stays where the surface already is. At 0 the texture only pushes "
"outwards; at 0.5 mid-gray stays put, so darker grays cut in and lighter ones "
"still push out - one image both embosses and engraves.\n\n"
"What cuts in has to fit: inside a sharp corner or through a thin wall, a deep "
"cut can pass through the other side."));
@@ -6045,18 +6045,18 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
const bool has_color = decode_height_texture(layer).has_color();
bool color_enabled = layer.color_enabled && has_color;
m_imgui->disabled_begin(!has_color);
if (m_imgui->bbl_checkbox(_L("Colours"), color_enabled)) {
if (m_imgui->bbl_checkbox(_L("Colors"), color_enabled)) {
layer.color_enabled = color_enabled;
m_preview_params_dirty = true;
}
m_imgui->disabled_end();
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
m_imgui->tooltip(has_color ?
_u8L("Prints the painted area in the texture's colours as well as its "
"relief. Each colour is matched to the nearest of your loaded "
_u8L("Prints the painted area in the texture's colors as well as its "
"relief. Each color is matched to the nearest of your loaded "
"filaments; anything you did not paint keeps the object's own.") :
_u8L("This texture is a grayscale height map, so it has no colours to "
"apply. Import a colour image to use this."),
_u8L("This texture is a grayscale height map, so it has no colors to "
"apply. Import a color image to use this."),
wrap_w);
// The rest of colour belongs to the whole stack, not to this layer, so it only appears once -
@@ -6065,13 +6065,13 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
TextureDisplacementOptions &opts = mv->texture_displacement_options;
if (m_imgui->bbl_checkbox(_L("Mix filaments"), opts.color_mix_enabled))
m_preview_params_dirty = true;
hover_tip(_u8L("Interleaves two filaments to fake the colours in between, so a handful "
"of filaments can cover a photo or a gradient. An image of flat colours "
hover_tip(_u8L("Interleaves two filaments to fake the colors in between, so a handful "
"of filaments can cover a photo or a gradient. An image of flat colors "
"prints the same either way. Off uses one filament per area."));
if (opts.color_mix_enabled) {
slider_label(_L("Mix by"));
const std::string mix_z = _u8L("Layers");
const std::string mix_xy = _u8L("Surface");
const std::string mix_xy = _u8L_CONTEXT("Surface", "Texture Displacement");
const std::string mix_auto = _u8L("Automatic");
const char *mix_items[] = { mix_z.c_str(), mix_xy.c_str(), mix_auto.c_str() };
int mix_mode = int(opts.color_mix_mode);
@@ -6087,12 +6087,12 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
"any angle but can read as texture rather than as a blend.\n"
"Automatic: layers on upright faces; flat-facing faces take the nearer "
"single filament, since a checkerboard there shows as a pattern."));
ImGui::TextDisabled("%s", Slic3r::format(_u8L("%1% printable colours from %2% filaments"),
ImGui::TextDisabled("%s", Slic3r::format(_u8L("%1% printable colors from %2% filaments"),
int(cached_palette().size()), int(m_palette_filaments.size())).c_str());
}
if (int_row("##color_despeckle", _L("Denoise"), &opts.color_despeckle, 0, 6, "%d", card_pad))
m_preview_params_dirty = true;
hover_tip(_u8L("Cleans up single stray triangles of the wrong colour, which detail finer "
hover_tip(_u8L("Cleans up single stray triangles of the wrong color, which detail finer "
"than the mesh leaves behind. Raise it if the result looks speckled, "
"lower it if small features are being swallowed."));
}
@@ -6102,7 +6102,7 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
{
const float x0 = ImGui::GetCursorPosX();
ImGui::AlignTextToFramePadding();
ImGui::TextDisabled("%s", _u8L("Mapping").c_str());
ImGui::TextDisabled("%s", _u8L_CONTEXT("Mapping", "Texture Displacement").c_str());
ImGui::SameLine();
ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), x0 + label_w));
struct MappingIcon
@@ -6116,9 +6116,9 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
_L("Triplanar - projects the texture from all three axes at once and blends between them, so a "
"patch wrapping around a sharp edge has no seam.") },
{ "menu_obj_cylinder.svg", _L("Cylindrical"),
_L("Cylindrical - wraps the texture around the painted area's own centre, for round shapes.") },
_L("Cylindrical - wraps the texture around the painted area's own center, for round shapes.") },
{ "menu_obj_sphere.svg", _L("Spherical"),
_L("Spherical - wraps the texture around the painted area's own centre in both directions.") },
_L("Spherical - wraps the texture around the painted area's own center in both directions.") },
{ "texture_displacement_map_unwrap.svg", _L("Unwrap (LSCM)"),
_L("Unwrap - flattens the painted area and maps the texture onto it with as little stretching as "
"possible. The area is cut into pieces at its sharp edges first (see Seam angle), so each "
@@ -6261,9 +6261,9 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
ImGui::TextDisabled("%s", _u8L("Blend").c_str());
ImGui::SameLine();
ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), x0 + label_w));
const std::string blend_add = _u8L("Add");
const std::string blend_subtract = _u8L("Subtract");
const std::string blend_multiply = _u8L("Multiply");
const std::string blend_add = _u8L_CONTEXT("Add", "Texture Displacement");
const std::string blend_subtract = _u8L_CONTEXT("Subtract", "Texture Displacement");
const std::string blend_multiply = _u8L_CONTEXT("Multiply", "Texture Displacement");
const std::string blend_divide = _u8L("Divide");
const char *blend_items[] = { blend_add.c_str(), blend_subtract.c_str(), blend_multiply.c_str(), blend_divide.c_str() };
// The first layer has nothing before it to combine with - build_texture_displacement() makes it
@@ -6535,11 +6535,11 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
// Only worth showing when a layer is actually colouring: with no colour there is no boundary for it
// to refine and the control would do nothing whatever it is set to.
if (mv != nullptr && any_layer_colors(*mv)) {
if (float_row("##subdiv_color", _L("Colour detail"), &m_subdivide_color_mm, 0.f, 5.f, "%.3f mm", false, 0.f))
if (float_row("##subdiv_color", _L("Color detail"), &m_subdivide_color_mm, 0.f, 5.f, "%.3f mm", false, 0.f))
preview_live();
hover_tip(_u8L("Triangle size where two colours meet. Each triangle prints in one filament, so a "
"colour edge can only be as sharp as the triangles along it - and nothing else "
"refines there, since the surface is flat across a change of colour. 0 turns it off."));
hover_tip(_u8L("Triangle size where two colors meet. Each triangle prints in one filament, so a "
"color edge can only be as sharp as the triangles along it - and nothing else "
"refines there, since the surface is flat across a change of color. 0 turns it off."));
}
ImGui::TextDisabled("%s", _u8L("Triangle budget: set with Triangles, below.").c_str());
@@ -6657,7 +6657,7 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
"on a layer is a different thing: it blurs the image before it is used."));
if (opts.smooth_enabled) {
float percent = opts.smooth_strength * 100.f;
if (float_row("##dispsmooth", _L("Strength"), &percent, 1.f, 100.f, "%.0f %%", false, 0.f)) {
if (float_row("##dispsmooth", _L_CONTEXT("Strength", "Texture Displacement"), &percent, 1.f, 100.f, "%.0f %%", false, 0.f)) {
opts.smooth_strength = std::clamp(percent / 100.f, 0.01f, 1.f);
m_preview_params_dirty = true;
}
@@ -6699,16 +6699,17 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
}
hover_tip(_u8L("Bake by moving the vertices the mesh already has, after preparing it (remesh, "
"adaptive subdivision, and a cut along sharp steps in the texture). Keeps the "
"topology, which is what colours need. The default pipeline instead refines, "
"topology, which is what colors need. The default pipeline instead refines, "
"cleans up sliver triangles, displaces and simplifies in one run; nothing needs "
"preparing first, but it does not produce colours yet."));
"preparing first, but it does not produce colors yet."));
}
if (opts.pipeline_v2) {
// -1 is "auto": the row shows the recommendation, greyed; editing it makes it a fixed value.
const bool auto_budget = opts.v2_max_triangles_k < 0;
int shown_k = auto_budget ? v2_recommendation(*mv).budget_k : opts.v2_max_triangles_k;
m_imgui->disabled_begin(auto_budget);
if (int_row("##v2budget", _L("Budget"), &shown_k, 0, 4000, auto_budget ? "%d k (auto)" : "%d k", 0.f)) {
// TRN Slider value: %d is the triangle budget in thousands
if (int_row("##v2budget", _L("Budget"), &shown_k, 0, 4000, auto_budget ? _u8L("%d k (auto)").c_str() : "%d k", 0.f)) {
opts.v2_max_triangles_k = shown_k;
m_preview_params_dirty = true;
}
@@ -6827,7 +6828,7 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
ImGui::SetNextItemWidth(x0 + panel_w - ImGui::GetCursorPosX());
float shown = auto_res ? rec.edge_mm : opts.v2_refine_mm;
m_imgui->disabled_begin(busy || auto_res);
if (ImGui::SliderFloat("##v2edge", &shown, 0.02f, 2.f, auto_res ? "%.2f mm (auto)" : "%.2f mm",
if (ImGui::SliderFloat("##v2edge", &shown, 0.02f, 2.f, auto_res ? _u8L("%.2f mm (auto)").c_str() : "%.2f mm",
ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_Logarithmic)) {
opts.v2_refine_mm = shown;
m_preview_params_dirty = true;
+7 -6
View File
@@ -10,6 +10,7 @@
#include <boost/log/trivial.hpp>
#include "CloudProvider.hpp"
#include "GUI_App.hpp"
#include "I18N.hpp"
#include "slic3r/Utils/Http.hpp"
#include "slic3r/Utils/NetworkAgent.hpp"
#include "slic3r/Utils/BBLNetworkPlugin.hpp"
@@ -248,10 +249,10 @@ std::shared_ptr<HttpServer::Response> HttpServer::auth_handle_request(const std:
GUI::wxGetApp().CallAfter([] { wxGetApp().ShowUserLogin(false); });
}
const std::string title = login_ok ? "Authentication complete" : "Authentication failed";
const std::string title = login_ok ? _u8L("Authentication complete") : _u8L("Authentication failed");
const std::string message = login_ok
? "You can return to OrcaSlicer. This window will close automatically."
: "Something went wrong. Please return to OrcaSlicer and try again.";
? _u8L("You can return to OrcaSlicer. This window will close automatically.")
: _u8L("Something went wrong. Please return to OrcaSlicer and try again.");
const std::string html =
"<html><head><meta charset=\"utf-8\">"
"<style>body{font-family:Arial,sans-serif;background:#f7f7f7;color:#222;margin:32px;}"
@@ -434,9 +435,9 @@ void HttpServer::ResponseRedirect::write_response(std::stringstream& ssOut)
"<style>body{font-family:Arial,sans-serif;background:#f7f7f7;color:#222;margin:32px;}"
"a.button{display:inline-block;padding:10px 16px;margin-top:12px;background:#0f8bff;color:#fff;text-decoration:none;border-radius:6px;}"
"</style></head><body><div class=\"container\">"
"<h2>Authentication complete</h2>"
"<p>You can return to OrcaSlicer. If your browser does not redirect automatically, use the button below.</p>"
"<a class=\"button\" href=\"" + location_str + "\">Continue</a>"
"<h2>" + _u8L("Authentication complete") + "</h2>"
"<p>" + _u8L("You can return to OrcaSlicer. If your browser does not redirect automatically, use the button below.") + "</p>"
"<a class=\"button\" href=\"" + location_str + "\">" + _u8L("Continue") + "</a>"
"<script>setTimeout(function(){try{window.close();}catch(e){}},1500);</script>"
"</div></body></html>";
ssOut << "HTTP/1.1 302 Found" << std::endl;
+1 -1
View File
@@ -527,7 +527,7 @@ void ArrangeJob::check_unprintable()
#endif
if (it->poly.area() < 0.001) {
auto msg = (boost::format(
_utf8("Object %s has zero size and can't be arranged."))
_u8L("Object %s has zero size and can't be arranged."))
% _utf8(it->name)).str();
m_plater->get_notification_manager()->push_notification(NotificationType::BBLPlateInfo,
NotificationManager::NotificationLevel::WarningNotificationLevel, msg);
+6 -6
View File
@@ -318,7 +318,7 @@ void CreateVolumeJob::finalize(bool canceled, std::exception_ptr &eptr) {
if (!::finalize(canceled, eptr, *m_input.base))
return;
if (m_result.its.empty())
return create_message("Can't create empty volume.");
return create_message(_u8L("Can't create empty volume."));
create_volume(std::move(m_result), m_input.object_id, m_input.volume_type, m_input.trmat, *m_input.base, m_input.gizmo);
}
@@ -376,7 +376,7 @@ void CreateObjectJob::finalize(bool canceled, std::exception_ptr &eptr)
// only for sure
if (m_result.empty())
return create_message("Can't create empty object.");
return create_message(_u8L("Can't create empty object."));
GUI_App &app = wxGetApp();
Plater *plater = app.plater();
@@ -995,7 +995,7 @@ TriangleMesh create_mesh(DataBase &input, const Fnc& was_canceled, Job::Ctl& ctl
return {};
// only info
ctl.call_on_main_thread([]() {
create_message("It is used default volume for embossed text, try to change text or font to fix it.");
create_message(_u8L("It is used default volume for embossed text, try to change text or font to fix it."));
});
}
@@ -1056,7 +1056,7 @@ void update_volume(TriangleMesh &&mesh, const DataUpdate &data, const Transform3
{
// for sure that some object will be created
if (mesh.its.empty())
return create_message("Empty mesh can't be created.");
return create_message(_u8L("Empty mesh can't be created."));
Plater *plater = wxGetApp().plater();
// Check gizmo is still open otherwise job should be canceled
@@ -1115,10 +1115,10 @@ void create_volume(TriangleMesh &&mesh,
// Parent object for text volume was propably removed.
// Assumption: User know what he does, so text volume is no more needed.
if (obj == nullptr)
return create_message("Bad object to create volume.");
return create_message(_u8L("Bad object to create volume."));
if (mesh.its.empty())
return create_message("Can't create empty volume.");
return create_message(_u8L("Can't create empty volume."));
plater->take_snapshot(_u8L("Add Emboss text Volume"));
+1 -1
View File
@@ -487,7 +487,7 @@ ShortcutCaptureDialog::ShortcutCaptureDialog(wxWindow* parent, Shortcut shortcut
m_status_colour = m_status->GetForegroundColour();
sizer->Add(m_status, 0, wxLEFT | wxRIGHT | wxTOP, FromDIP(20));
auto dlg_btns = new DialogButtons(this, {"Unbind", "OK", "Cancel"}, "", 1 /*left_aligned*/);
auto dlg_btns = new DialogButtons(this, {L("Unbind"), "OK", "Cancel"}, "", 1 /*left_aligned*/);
dlg_btns->GetFIRST()->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
m_chord = KeyChord{};
m_conflicts.clear();
+2 -2
View File
@@ -1676,7 +1676,7 @@ void MixedFilamentDialog::update_ok_button_state()
wxString parts;
for (auto it = type_groups.begin(); it != type_groups.end(); ++it) {
if (!parts.empty())
parts += _L(" and ");
parts += "; ";
wxString slots;
for (size_t j = 0; j < it->second.size(); ++j) {
if (!slots.empty()) slots += ", ";
@@ -1684,7 +1684,7 @@ void MixedFilamentDialog::update_ok_button_state()
}
parts += wxString::Format(_L("Slot %s (%s)"), slots, wxString::FromUTF8(it->first));
}
m_type_mismatch_msg = parts + " " + _L("cannot be mixed. Please select the same filament type.");
m_type_mismatch_msg = wxString::Format(_L("Different filament types cannot be mixed: %s. Please select the same filament type."), parts);
} else {
m_type_mismatch_msg.clear();
}
+2 -1
View File
@@ -493,7 +493,8 @@ MultiMachineManagerPage::MultiMachineManagerPage(wxWindow* parent)
page_num_enter_evt();
});
m_page_num_enter = new Button(m_flipping_panel, _("Go"));
// TRN Button that jumps to the page number typed next to it
m_page_num_enter = new Button(m_flipping_panel, _L("Go"));
m_page_num_enter->SetMinSize(wxSize(FromDIP(25), FromDIP(25)));
m_page_num_enter->SetMaxSize(wxSize(FromDIP(25), FromDIP(25)));
m_page_num_enter->SetBackgroundColor(ctrl_bg);
+1 -1
View File
@@ -1166,7 +1166,7 @@ CloudTaskManagerPage::CloudTaskManagerPage(wxWindow* parent)
page_num_enter_evt();
});
m_page_num_enter = new Button(m_flipping_panel, _("Go"));
m_page_num_enter = new Button(m_flipping_panel, _L("Go"));
m_page_num_enter->SetMinSize(wxSize(FromDIP(25), FromDIP(25)));
m_page_num_enter->SetMaxSize(wxSize(FromDIP(25), FromDIP(25)));
m_page_num_enter->SetBackgroundColor(ctrl_bg);
+3 -3
View File
@@ -128,7 +128,7 @@ void NetworkPluginDownloadDialog::create_missing_plugin_ui()
main_sizer->AddSpacer(15);
auto dlg_btns = new DialogButtons(this,
{"Download and Install", "Skip for Now"},
{L("Download and Install"), L("Skip for Now")},
_L("Download and Install") // Primary button
);
@@ -190,7 +190,7 @@ void NetworkPluginDownloadDialog::create_update_available_ui(const std::string&
main_sizer->AddSpacer(10);
auto dlg_btns = new DialogButtons(this,
{"Update Now", "Remind Later", "Skip Version"},
{L("Update Now"), L("Remind Later"), L("Skip Version")},
_L("Update Now")
);
@@ -319,7 +319,7 @@ NetworkPluginRestartDialog::NetworkPluginRestartDialog(wxWindow* parent)
main_sizer->AddSpacer(15);
auto dlg_btns = new DialogButtons(this,
{"Restart Now", "Restart Later"},
{L("Restart Now"), L("Restart Later")},
_L("Restart Now") // Primary button
);
+5 -4
View File
@@ -273,7 +273,8 @@ void NetworkTestDialog::start_all_job_sequence()
void NetworkTestDialog::start_test_url(TestJob job, wxString name, wxString url)
{
m_in_testing[job] = true;
wxString info = wxString::Format("test %s start...", name);
// TRN %s is the name of the tested website
wxString info = wxString::Format(_L("test %s start..."), name);
update_status(job, info);
@@ -295,16 +296,16 @@ void NetworkTestDialog::start_test_url(TestJob job, wxString name, wxString url)
}
})
.on_ip_resolve([this,name,job](std::string ip) {
wxString ip_report = wxString::Format("test %s ip resolved = %s", name, ip);
wxString ip_report = wxString::Format(_L("test %s ip resolved = %s"), name, ip);
update_status(job, ip_report);
})
.on_error([this,name,job](std::string body, std::string error, unsigned int status) {
wxString info = wxString::Format("status=%u, body=%s, error=%s", status, body, error);
this->update_status(job, wxString::Format("test %s failed", name));
this->update_status(job, wxString::Format(_L("test %s failed"), name));
this->update_status(-1, info);
}).perform_sync();
if (result == 0) {
update_status(job, wxString::Format("test %s ok", name));
update_status(job, wxString::Format(_L("test %s ok"), name));
}
m_in_testing[job] = false;
}
+3 -5
View File
@@ -1272,7 +1272,7 @@ bool NotificationManager::ExportFinishedNotification::on_text_click()
}
void NotificationManager::ExportFinishedNotification::on_eject_click()
{
NotificationData data{ get_data().type, get_data().level , 0, _utf8("Ejecting.") };
NotificationData data{ get_data().type, get_data().level , 0, _u8L("Ejecting.") };
m_eject_pending = true;
m_multiline = false;
update(data);
@@ -1671,9 +1671,7 @@ void NotificationManager::PrintHostUploadNotification::render_bar(ImGuiWrapper&
{
ProgressBarNotification::render_bar(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
float uploaded = m_file_size * m_percentage;
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << (int)(m_percentage * 100) << "% - " << uploaded << " of " << m_file_size << "MB uploaded";
text = stream.str();
text = into_u8(wxString::Format(_L("%d%% - %.2f of %.2fMB uploaded"), (int)(m_percentage * 100), uploaded, m_file_size));
ImGui::SetCursorPosX(m_left_indentation);
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - (m_multiline ? 0 : m_line_height / 4));
break;
@@ -3595,7 +3593,7 @@ void NotificationManager::bbl_show_bed_filament_incompatible_notification(const
wxGetApp().open_browser_with_warning_dialog(bed_filament_compatibility_wiki);
return false;
};
push_notification_data({ NotificationType::BBLBedFilamentIncompatible,NotificationLevel::ErrorNotificationLevel,0,_u8L("Error:") + "\n" + text,"Click for more.",callback }, 0);
push_notification_data({ NotificationType::BBLBedFilamentIncompatible,NotificationLevel::ErrorNotificationLevel,0,_u8L("Error:") + "\n" + text,_u8L("Click for more."),callback }, 0);
}
void NotificationManager::bbl_close_bed_filament_incompatible_notification()
+5 -4
View File
@@ -134,13 +134,13 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent
m_name = "Settings to modified";
}
else if (type == itInstanceRoot) {
m_name = _(_devL("Instances"));
m_name = _L("Instances");
m_extruder = parent->m_extruder;
}
else if (type == itInstance)
{
m_idx = parent->GetChildCount();
m_name = wxString::Format(_(_devL("Instance %d")), m_idx + 1);
m_name = wxString::Format(_L("Instance %d"), m_idx + 1);
m_extruder = parent->GetParent()->m_extruder;
set_icons();
}
@@ -398,10 +398,11 @@ void ObjectDataViewModelNode::SetIdx(const int &idx)
// update name if this node is instance
if (m_type == itInstance) {
if (m_plate_idx > 0) {
m_name = wxString::Format(_(_devL("[P%d]Instance %d")), m_plate_idx, m_idx + 1);
// TRN Object list item: plate number, then instance number
m_name = wxString::Format(_L("[P%d]Instance %d"), m_plate_idx, m_idx + 1);
}
else {
m_name = wxString::Format(_(_devL("Instance %d")), m_idx + 1);
m_name = wxString::Format(_L("Instance %d"), m_idx + 1);
}
}
}
+2 -2
View File
@@ -83,7 +83,7 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent) :
m_presets = tab->get_presets();
const Preset &sel_preset = m_presets->get_selected_preset();
std::string suffix = _u8L_CONTEXT(L_CONTEXT("Copy", "PresetName"), "PresetName");
std::string preset_name = sel_preset.is_default ? "Untitled" : sel_preset.is_system ? (boost::format(("%1% - %2%")) % sel_preset.name % suffix).str() : sel_preset.name;
std::string preset_name = sel_preset.is_default ? _u8L("Untitled") : sel_preset.is_system ? (boost::format(("%1% - %2%")) % sel_preset.name % suffix).str() : sel_preset.name;
auto input_sizer = new wxBoxSizer(wxVERTICAL);
@@ -306,7 +306,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
result = host->test(msg); // using test with special input because I don't want to create the generate_auth_creds func for every printer
// Prompt user to approve access on the machine.
show_info(this, "API Key created. Go to the physical printer and hit \"authorize\" on the screen, then run \"Test\" again.\n"+msg, "API Key created.");
show_info(this, _L("API Key created. Go to the physical printer and hit \"authorize\" on the screen, then run \"Test\" again.") + "\n" + msg, _L("API Key created."));
}
+14 -15
View File
@@ -3000,6 +3000,7 @@ Sidebar::Sidebar(Plater *parent)
});
// "Variant", not "Nozzle": picking one switches the printer preset (see panel_nozzle_dia).
// TRN Sidebar label of the printer variant (nozzle) selector; picking one switches the printer preset.
p->label_nozzle_title = new Label(p->panel_nozzle_dia, _L("Variant"), LB_PROPAGATE_MOUSE_EVENT);
p->label_nozzle_title->SetFont(Label::Body_10);
@@ -3032,7 +3033,7 @@ Sidebar::Sidebar(Plater *parent)
p->combo_nozzle_dia->Bind(wxEVT_SET_FOCUS, [nozzle_focus_bg](auto& e) {nozzle_focus_bg(true ); e.Skip();});
p->combo_nozzle_dia->Bind(wxEVT_KILL_FOCUS, [nozzle_focus_bg](auto& e) {nozzle_focus_bg(false); e.Skip();});
p->label_nozzle_type = new Label(p->panel_nozzle_dia, "Brass", LB_PROPAGATE_MOUSE_EVENT | wxST_ELLIPSIZE_END | wxALIGN_CENTRE_HORIZONTAL);
p->label_nozzle_type = new Label(p->panel_nozzle_dia, _L("Brass"), LB_PROPAGATE_MOUSE_EVENT | wxST_ELLIPSIZE_END | wxALIGN_CENTRE_HORIZONTAL);
p->label_nozzle_type->SetFont(Label::Body_10);
p->label_nozzle_type->SetMinSize(FromDIP(wxSize(56, -1)));
p->label_nozzle_type->SetMaxSize(FromDIP(wxSize(56, -1)));
@@ -16322,7 +16323,7 @@ bool Plater::add_model(bool imperial_units, std::string fname)
void Plater::calib_pa(const Calib_Params& params)
{
const auto calib_pa_name = wxString::Format(L"Pressure Advance Test");
const auto calib_pa_name = _L("Pressure Advance Test");
new_project(false, false, calib_pa_name);
wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
@@ -16799,11 +16800,9 @@ void Plater::calib_flowrate(bool is_linear, int pass, InfillPattern pattern) {
return;
wxString calib_name;
if (is_linear) {
calib_name = L"Orca YOLO Flow Calibration";
if (pass == 2)
calib_name += L" - Perfectionist version";
calib_name = pass == 2 ? _L("Orca YOLO Flow Calibration - Perfectionist version") : _L("Orca YOLO Flow Calibration");
} else
calib_name = wxString::Format(L"Flowrate Test - Pass%d", pass);
calib_name = wxString::Format(_L("Flowrate Test - Pass%d"), pass);
if (new_project(false, false, calib_name) == wxID_CANCEL)
return;
@@ -16843,7 +16842,7 @@ void Plater::calib_temp(const Calib_Params& params) {
constexpr double base_temp_tower_block_height = 10.0;
constexpr int base_temp_tower_temp_step = 5;
const auto calib_temp_name = wxString::Format(L"Nozzle temperature test");
const auto calib_temp_name = _L("Nozzle temperature test");
new_project(false, false, calib_temp_name);
wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
if (params.mode != CalibMode::Calib_Temp_Tower) return;
@@ -16923,7 +16922,7 @@ void Plater::calib_temp(const Calib_Params& params) {
void Plater::calib_max_vol_speed(const Calib_Params& params)
{
const auto calib_vol_speed_name = wxString::Format(L"Max volumetric speed test");
const auto calib_vol_speed_name = _L("Max volumetric speed test");
new_project(false, false, calib_vol_speed_name);
wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
if (params.mode != CalibMode::Calib_Vol_speed_Tower)
@@ -17002,7 +17001,7 @@ void Plater::calib_max_vol_speed(const Calib_Params& params)
void Plater::calib_retraction(const Calib_Params& params)
{
const auto calib_retraction_name = wxString::Format(L"Retraction");
const auto calib_retraction_name = _L("Retraction");
new_project(false, false, calib_retraction_name);
wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
if (params.mode != CalibMode::Calib_Retraction_tower)
@@ -17064,7 +17063,7 @@ void Plater::calib_retraction(const Calib_Params& params)
void Plater::calib_VFA(const Calib_Params& params)
{
const auto calib_vfa_name = wxString::Format(L"VFA test");
const auto calib_vfa_name = _L("VFA test");
new_project(false, false, calib_vfa_name);
wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
if (params.mode != CalibMode::Calib_VFA_Tower)
@@ -17147,7 +17146,7 @@ void Plater::calib_VFA(const Calib_Params& params)
void Plater::calib_input_shaping_freq(const Calib_Params& params)
{
const auto calib_input_shaping_name = wxString::Format(L"Input shaping Frequency test");
const auto calib_input_shaping_name = _L("Input shaping Frequency test");
new_project(false, false, calib_input_shaping_name);
wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
if (params.mode != CalibMode::Calib_Input_shaping_freq)
@@ -17209,7 +17208,7 @@ void Plater::calib_input_shaping_freq(const Calib_Params& params)
void Plater::calib_input_shaping_damp(const Calib_Params& params)
{
const auto calib_input_shaping_name = wxString::Format(L"Input shaping Damping test");
const auto calib_input_shaping_name = _L("Input shaping Damping test");
new_project(false, false, calib_input_shaping_name);
wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
if (params.mode != CalibMode::Calib_Input_shaping_damp)
@@ -17270,7 +17269,7 @@ void Plater::calib_input_shaping_damp(const Calib_Params& params)
void Plater::Calib_Cornering(const Calib_Params& params)
{
const auto Calib_Cornering = wxString::Format(L"Cornering test");
const auto Calib_Cornering = _L("Cornering test");
new_project(false, false, Calib_Cornering);
wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
if (params.mode != CalibMode::Calib_Cornering)
@@ -17458,7 +17457,7 @@ void Plater::load_gcode(const wxString& filename)
if (p->preview->get_canvas3d()->get_gcode_layers_zs().empty()) {
MessageDialog(this, _L("The selected file") + ":\n" + filename + "\n" + _L("Does not contain valid G-code."),
wxString(GCODEVIEWER_APP_NAME) + " - " + _L("An Error has occurred while loading the G-code file."), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal();
set_project_filename(DEFAULT_PROJECT_NAME);
set_project_filename(_L(DEFAULT_PROJECT_NAME));
} else {
set_project_filename(filename);
}
@@ -17809,7 +17808,7 @@ ProjectDropDialog::ProjectDropDialog(const std::string &filename)
// Orca: hide the "Don't show again" checkbox, people keeps accidentally checked this then forgot
// wxBoxSizer *m_sizer_left = new wxBoxSizer(wxHORIZONTAL);
//
// auto dont_show_again = create_remember_checkbox(_L("Remember my choice."), this, _L("This option can be changed later in preferences, under 'Load Behaviour'."));
// auto dont_show_again = create_remember_checkbox(_L("Remember my choice."), this, _L("This option can be changed later in preferences, under 'Load Behavior'."));
// m_sizer_left->Add(dont_show_again, 0, wxALL, 5);
//
// m_sizer_bottom->Add(m_sizer_left, 0, wxEXPAND, 5);
+2 -1
View File
@@ -17,6 +17,7 @@
#include <atomic>
#include <memory>
#include "slic3r/GUI/Event.hpp"
#include "slic3r/GUI/I18N.hpp"
#include <string>
#include "slic3r/GUI/ObjectDataViewModel.hpp"
#include "slic3r/GUI/SettingsIndex.hpp"
@@ -140,7 +141,7 @@ wxDECLARE_EVENT(EVT_NOTICE_CHILDE_SIZE_CHANGED, SimpleEvent);
wxDECLARE_EVENT(EVT_NOTICE_FULL_SCREEN_CHANGED, IntEvent);
using ColorEvent = Event<wxColour>;
wxDECLARE_EVENT(EVT_ADD_CUSTOM_FILAMENT, ColorEvent);
const wxString DEFAULT_PROJECT_NAME = "Untitled";
const wxString DEFAULT_PROJECT_NAME = L("Untitled");
class SidebarProps
{
+18 -18
View File
@@ -265,25 +265,25 @@ PluginAvailableActions evaluate_action_policy(const PluginDialogItem& item)
available_actions.can_toggle = !is_loading && (has_local || available_actions.toggle_installs_cloud_plugin);
auto add_action = [&available_actions](const char* id, const char* label, bool enabled = true, bool danger = false) {
available_actions.context_actions.push_back(PluginContextAction{id, label, enabled, danger});
available_actions.context_actions.push_back(PluginContextAction{id, _u8L(label), enabled, danger});
};
// Owned cloud plugins fall through to the local delete: it removes the installed package only.
// Deleting a plugin from the cloud is a plugin hub operation and is never offered here.
if (is_cloud && !is_orphaned && !is_mine) {
add_action("unsubscribe_plugin", "Unsubscribe", true, true);
add_action("unsubscribe_plugin", L("Unsubscribe"), true, true);
} else if (has_local) {
add_action("delete_plugin", "Delete", true, true);
add_action("delete_plugin", L("Delete"), true, true);
}
add_action("open_folder", "Show in folder", has_local);
add_action("open_folder", L("Show in folder"), has_local);
if (!is_orphaned) {
if (is_cloud) {
add_action("reinstall_plugin", "Reinstall");
add_action("reinstall_plugin", L("Reinstall"));
} else {
add_action("reload_plugin", "Reload");
add_action("clear_cache_reload_plugin", "Delete cache and reload");
add_action("reload_plugin", L("Reload"));
add_action("clear_cache_reload_plugin", L("Delete cache and reload"));
}
}
@@ -811,7 +811,7 @@ void PluginsDialog::toggle_plugin(const std::string& plugin_key, bool enabled)
if (!available_actions.can_toggle) {
if (dialog_item.unauthorized && available_actions.toggle_installs_cloud_plugin == false && row_data.has_local_package() == false) {
const std::string install_error = "Unauthorized cloud plugins cannot be installed.";
const std::string install_error = _u8L("Unauthorized cloud plugins cannot be installed.");
manager.set_plugin_error(plugin_key, install_error);
show_status(from_u8(install_error), "warn");
}
@@ -1071,7 +1071,7 @@ void PluginsDialog::run_script_plugin_capability(const std::string& plugin_key,
ExecutionResult result;
auto complete_with_error = [this, &manager, &plugin_key](const std::string& plugin_error, const wxString& status_message) {
const std::string normalized_error = plugin_error.empty() ? "Script plugin failed." : plugin_error;
const std::string normalized_error = plugin_error.empty() ? _u8L("Script plugin failed.") : plugin_error;
if (!manager.set_plugin_error(plugin_key, normalized_error))
BOOST_LOG_TRIVIAL(warning) << "Failed to record plugin error. plugin_key=" << plugin_key;
@@ -1262,34 +1262,34 @@ void PluginsDialog::reload_local_plugin(const std::string& plugin_key, bool clea
if (clear_cache) {
PluginDescriptor descriptor;
if (!manager.try_get_plugin_descriptor(plugin_key, descriptor))
return {false, "Plugin not found."};
return {false, _u8L("Plugin not found.")};
boost::filesystem::path resolved_root;
std::string resolve_error;
if (!resolve_allowed_plugin_root(descriptor, {get_orca_plugins_dir()},
"Refusing to clear a plugin cache outside the local plugin directory.",
_u8L("Refusing to clear a plugin cache outside the local plugin directory."),
resolved_root, resolve_error))
return {false, resolve_error};
cache_dir = resolved_root / "__whl_extracted__";
}
if (!manager.unload_plugin(plugin_key))
return {false, "Failed to unload plugin."};
return {false, _u8L("Failed to unload plugin.")};
if (clear_cache) {
boost::system::error_code ec;
boost::filesystem::remove_all(cache_dir, ec);
if (ec)
return {false, "Failed to clear plugin cache: " + ec.message()};
return {false, GUI::format(_u8L("Failed to clear plugin cache: %1%"), ec.message())};
}
manager.load_plugin(plugin_key, false);
std::string error;
if (!manager.wait_for_plugin_load(plugin_key, std::chrono::minutes(5), error) || !manager.is_plugin_loaded(plugin_key))
return {false, error.empty() ? "Plugin failed to load." : error};
return {false, error.empty() ? _u8L("Plugin failed to load.") : error};
if (!was_loaded && !manager.unload_plugin(plugin_key))
return {false, "Plugin reloaded, but failed to restore the inactive state."};
return {false, _u8L("Plugin reloaded, but failed to restore the inactive state.")};
return {true, {}};
},
@@ -1297,7 +1297,7 @@ void PluginsDialog::reload_local_plugin(const std::string& plugin_key, bool clea
} catch (const std::exception& ex) {
reload_result = {false, ex.what()};
} catch (...) {
reload_result = {false, "Unknown plugin reload error."};
reload_result = {false, _u8L("Unknown plugin reload error.")};
}
if (!reload_result.first) {
@@ -1344,14 +1344,14 @@ void PluginsDialog::reinstall_cloud_plugin(const PluginDescriptor& plugin)
manager.load_plugin(plugin_key);
std::string error;
if (!manager.wait_for_plugin_load(plugin_key, std::chrono::minutes(5), error) || !manager.is_plugin_loaded(plugin_key))
return {false, error.empty() ? "Plugin failed to load." : error};
return {false, error.empty() ? _u8L("Plugin failed to load.") : error};
return {true, {}};
},
_L("Reloading plugin"), _L("Reloading plugin"));
} catch (const std::exception& ex) {
reload_result = {false, ex.what()};
} catch (...) {
reload_result = {false, "Unknown plugin reload error."};
reload_result = {false, _u8L("Unknown plugin reload error.")};
}
if (!reload_result.first) {
+18 -17
View File
@@ -120,9 +120,10 @@ static DWORD execute_process_winapi(const std::wstring& command_line)
if (!::CreateProcessW(nullptr /* lpApplicationName */, (LPWSTR) command_line.c_str(), nullptr /* lpProcessAttributes */,
nullptr /* lpThreadAttributes */, false /* bInheritHandles */,
CREATE_UNICODE_ENVIRONMENT /* | CREATE_NEW_CONSOLE */ /* dwCreationFlags */, (LPVOID) envstr.c_str(),
nullptr /* lpCurrentDirectory */, &startup_info, &process_info))
throw Slic3r::RuntimeError(std::string("Failed starting the script ") + boost::nowide::narrow(command_line) +
", Win32 error: " + std::to_string(int(::GetLastError())));
nullptr /* lpCurrentDirectory */, &startup_info, &process_info)) {
const int error = int(::GetLastError());
throw Slic3r::RuntimeError(Slic3r::format(_u8L("Failed starting the script %1%, Win32 error: %2%"), boost::nowide::narrow(command_line), error));
}
::WaitForSingleObject(process_info.hProcess, INFINITE);
ULONG rc = 0;
::GetExitCodeProcess(process_info.hProcess, &rc);
@@ -141,14 +142,14 @@ static int run_script(const std::string& script, const std::string& gcode, std::
LPWSTR* szArglist = CommandLineToArgvW(boost::nowide::widen(script).c_str(), &nArgs);
if (szArglist == nullptr || nArgs <= 0) {
// CommandLineToArgvW failed. Maybe the command line escapment is invalid?
throw Slic3r::RuntimeError(std::string("Post processing script ") + script + " on file " + gcode +
" failed. CommandLineToArgvW() refused to parse the command line path.");
throw Slic3r::RuntimeError(Slic3r::format(_u8L("Post processing script %1% on file %2% failed. CommandLineToArgvW() refused to parse the command line path."),
script, gcode));
}
std::wstring command_line;
std::wstring command = szArglist[0];
if (!boost::filesystem::exists(boost::filesystem::path(command)))
throw Slic3r::RuntimeError(std::string("The configured post-processing script does not exist: ") + boost::nowide::narrow(command));
throw Slic3r::RuntimeError(Slic3r::format(_u8L("The configured post-processing script does not exist: %1%"), boost::nowide::narrow(command)));
if (boost::iends_with(command, L".pl")) {
// This is a perl script. Run it through the perl interpreter.
// The current process may be slic3r.exe or slic3r-console.exe.
@@ -159,7 +160,7 @@ static int run_script(const std::string& script, const std::string& gcode, std::
boost::filesystem::path path_perl = path_exe.parent_path() / "perl" / "perl.exe";
if (!boost::filesystem::exists(path_perl)) {
LocalFree(szArglist);
throw Slic3r::RuntimeError(std::string("Perl interpreter ") + path_perl.string() + " does not exist.");
throw Slic3r::RuntimeError(Slic3r::format(_u8L("Perl interpreter %1% does not exist."), path_perl.string()));
}
// Replace it with the current perl interpreter.
quote_argv_winapi(boost::nowide::widen(path_perl.string()), command_line);
@@ -294,14 +295,14 @@ static void run_post_process_plugins(const ConfigOptionStrings& capabilities,
exec_result = cap->execute(ctx);
} catch (const std::exception& ex) {
const std::string msg =
(boost::format("Post-processing plugin %1% raised an exception.\nError: %2%") % ref.capability_name % ex.what()).str();
(boost::format(_u8L("Post-processing plugin %1% raised an exception.\nError: %2%")) % ref.capability_name % ex.what()).str();
BOOST_LOG_TRIVIAL(error) << msg;
throw Slic3r::RuntimeError(msg);
}
if (exec_result.status == PluginResult::RecoverableError || exec_result.status == PluginResult::FatalError) {
const std::string msg =
(boost::format("Post-processing plugin %1% failed.\nError: %2%") % ref.capability_name % exec_result.message).str();
(boost::format(_u8L("Post-processing plugin %1% failed.\nError: %2%")) % ref.capability_name % exec_result.message).str();
BOOST_LOG_TRIVIAL(error) << msg;
throw Slic3r::RuntimeError(msg);
}
@@ -370,7 +371,7 @@ bool run_post_process_scripts(
std::string error_message;
if (copy_file(src_path, path, error_message, false) != SUCCESS)
throw Slic3r::RuntimeError(
Slic3r::format("Failed making a temporary copy of G-code file %1% before running a post-processing script: %2%", src_path,
Slic3r::format(_u8L("Failed making a temporary copy of G-code file %1% before running a post-processing script: %2%"), src_path,
error_message));
} else {
// Don't make a copy of the G-code before running the post-processing script.
@@ -390,7 +391,7 @@ bool run_post_process_scripts(
auto gcode_file = boost::filesystem::path(path);
if (!boost::filesystem::exists(gcode_file))
throw Slic3r::RuntimeError(std::string("Post-processor can't find exported gcode file"));
throw Slic3r::RuntimeError(_u8L("Post-processor can't find exported gcode file"));
// Store print configuration into environment variables.
config.setenv_();
@@ -431,11 +432,11 @@ bool run_post_process_scripts(
const int result = run_script(script, gcode_file.string(), std_err);
if (result != 0) {
const std::string msg = std_err.empty() ?
(boost::format("Post-processing script %1% on file %2% failed.\nError code: %3%") %
(boost::format(_u8L("Post-processing script %1% on file %2% failed.\nError code: %3%")) %
script % path % result)
.str() :
(boost::format(
"Post-processing script %1% on file %2% failed.\nError code: %3%\nOutput:\n%4%") %
_u8L("Post-processing script %1% on file %2% failed.\nError code: %3%\nOutput:\n%4%")) %
script % path % result % std_err)
.str();
BOOST_LOG_TRIVIAL(error) << msg;
@@ -476,19 +477,19 @@ bool run_post_process_scripts(
new_output_name = outpath.string();
} else {
if (!op.is_absolute() || !op.has_filename())
throw Slic3r::RuntimeError("Unable to parse desired new path from output name file");
throw Slic3r::RuntimeError(_u8L("Unable to parse desired new path from output name file"));
}
if (!fs::exists(fs::path(new_output_name).parent_path()))
throw Slic3r::RuntimeError(
Slic3r::format("Output directory does not exist: %1%", fs::path(new_output_name).parent_path().string()));
Slic3r::format(_u8L("Output directory does not exist: %1%"), fs::path(new_output_name).parent_path().string()));
}
BOOST_LOG_TRIVIAL(trace) << "Post-processing script changed the file name from " << output_name << " to "
<< new_output_name;
output_name = new_output_name;
} catch (const std::exception& err) {
throw Slic3r::RuntimeError(Slic3r::format("run_post_process_scripts: Failed reading a file %1% "
"carrying the final name / path of a G-code file: %2%",
throw Slic3r::RuntimeError("run_post_process_scripts: " +
Slic3r::format(_u8L("Failed reading a file %1% carrying the final name / path of a G-code file: %2%"),
path_output_name, err.what()));
}
remove_output_name_file();
+9 -4
View File
@@ -1715,7 +1715,7 @@ void PreferencesDialog::create_items()
std::vector<wxString> projectLoadSettingsBehaviourOptions = {_L("Load All"), _L("Ask When Relevant"), _L("Always Ask"), _L("Load Geometry Only")};
std::vector<string> projectLoadSettingsConfigOptions = { OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_ALL, OPTION_PROJECT_LOAD_BEHAVIOUR_ASK_WHEN_RELEVANT, OPTION_PROJECT_LOAD_BEHAVIOUR_ALWAYS_ASK, OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_GEOMETRY };
auto item_project_load = create_item_combobox(_L("Load behaviour"), _L("Should printer/filament/process settings be loaded when opening a 3MF file?"), SETTING_PROJECT_LOAD_BEHAVIOUR, projectLoadSettingsBehaviourOptions, projectLoadSettingsConfigOptions);
auto item_project_load = create_item_combobox(_L("Load behavior"), _L("Should printer/filament/process settings be loaded when opening a 3MF file?"), SETTING_PROJECT_LOAD_BEHAVIOUR, projectLoadSettingsBehaviourOptions, projectLoadSettingsConfigOptions);
g_sizer->Add(item_project_load);
auto item_backup = create_item_backup(_L("Auto backup"), _L("Backup your project periodically to help with restoring from an occasional crash."));
@@ -1801,6 +1801,7 @@ void PreferencesDialog::create_items()
auto item_speed_dial_recents = create_item_spinctrl(
_L("Recent actions"),
"",
// TRN Unit shown after the number of recent actions, as in "5 actions".
_L("actions"),
_L("How many recently launched actions to show at the top of the Speed Dial. Set to 0 to hide recent actions."),
SETTING_SPEED_DIAL_RECENT_COUNT,
@@ -1851,7 +1852,7 @@ void PreferencesDialog::create_items()
g_sizer->AddGrowableCol(0, 1);
//// CONTROL > Behaviour
g_sizer->Add(create_item_title(_L("Behaviour")), 1, wxEXPAND);
g_sizer->Add(create_item_title(_L("Behavior")), 1, wxEXPAND);
std::vector<wxString> FlushOptionLabels = {_L("All"),_L("Color"),_L("None")};
std::vector<std::string> FlushOptionValues = { "all","color change","disabled" };
@@ -1900,7 +1901,7 @@ void PreferencesDialog::create_items()
if (wxGetApp().is_enable_cad_feature()) {
auto item_connector_face_glyph = create_item_checkbox(_L("Draw mate connectors as a face"),
_L("In the Design tab, draw a mate connector as a small face instead of the conventional "
"disc with a roll quadrant. A face's orientation is read without being learned. "
"disc with a roll quadrant. A face shows its orientation at a glance, without learning the disc convention. "
"Turn this off for the conventional CAD representation."), "design_connector_face_glyph");
g_sizer->Add(item_connector_face_glyph);
@@ -1999,7 +2000,11 @@ void PreferencesDialog::create_items()
);
g_sizer->Add(item_realistic_ssao);
std::vector<wxString> ShadowsLabels = { _L("Off"), _L("Static"), _L("Orbit") };
std::vector<wxString> ShadowsLabels = { _L("Off"),
// TRN Realistic-view shadow mode: the light stays fixed in the scene.
_L("Static"),
// TRN Realistic-view shadow mode: the light turns with the camera.
_L("Orbit") };
std::vector<std::string> ShadowsValues = { "off", "static", "orbit" };
auto item_realistic_shadows = create_item_combobox(
_L("Shadows"),
+2 -1
View File
@@ -2050,7 +2050,8 @@ void CrealityPrintHostSendDialog::init()
wxBitmap* bmp = get_extruder_color_icon(slot.color, "", icon_sz, icon_sz);
wxString label_str;
if (slot.box_id == 0)
label_str = wxString::Format("Ext - %s", slot.type.c_str());
// TRN External spool slot, followed by its filament type
label_str = wxString::Format(_L("Ext - %s"), slot.type.c_str());
else
label_str = wxString::Format("%s - %s", slot.tool_id.substr(1).c_str(), slot.type.c_str());
combo->Append(label_str, bmp ? *bmp : wxNullBitmap);
+1 -1
View File
@@ -276,7 +276,7 @@ private:
if (params.is_discarded())
params = json::object();
const std::string filter = json_string(params, "filter").empty() ? "All files (*.*)|*.*" : json_string(params, "filter");
const std::string filter = json_string(params, "filter").empty() ? _u8L("All files (*.*)|*.*") : json_string(params, "filter");
wxWindow* parent = owner().GetParent();
if (parent == nullptr)
+1 -1
View File
@@ -59,7 +59,7 @@ SavePresetDialog::Item::Item(Preset::Type type, const std::string &suffix, wxBox
m_presets = tab->get_presets();
const Preset &sel_preset = m_presets->get_selected_preset();
std::string preset_name = sel_preset.is_default ? "Untitled" : sel_preset.is_system ? (boost::format(("%1% - %2%")) % sel_preset.name % suffix).str() : sel_preset.is_from_bundle() && !sel_preset.alias.empty() ? sel_preset.alias : sel_preset.name;
std::string preset_name = sel_preset.is_default ? _u8L("Untitled") : sel_preset.is_system ? (boost::format(("%1% - %2%")) % sel_preset.name % suffix).str() : sel_preset.is_from_bundle() && !sel_preset.alias.empty() ? sel_preset.alias : sel_preset.name;
// if name contains extension
if (boost::iends_with(preset_name, ".ini")) {
+6 -6
View File
@@ -1131,7 +1131,7 @@ void SelectMachineDialog::sync_ams_mapping_result(std::vector<FilamentInfo> &res
if (result.empty()) {
BOOST_LOG_TRIVIAL(info) << "ams_mapping result is empty";
for (auto it = m_materialList.begin(); it != m_materialList.end(); it++) {
wxString ams_id = "Ext";//
wxString ams_id = _L("Ext");//
wxColour ams_col = wxColour(0xCE, 0xCE, 0xCE);
it->second->item->set_ams_info(ams_col, ams_id);
it->second->item->set_nozzle_info(get_mapped_nozzle_str(it->first));
@@ -1155,7 +1155,7 @@ void SelectMachineDialog::sync_ams_mapping_result(std::vector<FilamentInfo> &res
if (f->tray_id == VIRTUAL_TRAY_MAIN_ID || f->tray_id == VIRTUAL_TRAY_DEPUTY_ID)
{
ams_id = "Ext";
ams_id = _L("Ext");
}else if (f->tray_id >= 0) {
ams_id = wxGetApp().transition_tridid(f->tray_id);
} else {
@@ -3863,7 +3863,7 @@ void SelectMachineDialog::on_refresh(wxCommandEvent &event)
void SelectMachineDialog::on_set_finish_mapping(wxCommandEvent &evt)
{
auto selection_data = evt.GetString();
auto selection_data_arr = wxSplit(selection_data.ToStdString(), '|');
auto selection_data_arr = wxSplit(selection_data, '|');
BOOST_LOG_TRIVIAL(info) << "The ams mapping selection result: data is " << selection_data;
@@ -4376,9 +4376,9 @@ static wxString _check_kval_not_default(const MachineObject* obj, const std::vec
wxString ams_name;
if (info.tray_id == VIRTUAL_TRAY_MAIN_ID) {
ams_name = "Right-Ext";
ams_name = _L("Right-Ext");
} else if (info.tray_id == VIRTUAL_TRAY_DEPUTY_ID) {
ams_name = "Left-Ext";
ams_name = _L("Left-Ext");
} else {
ams_name = wxGetApp().transition_tridid(info.tray_id);
}
@@ -5509,7 +5509,7 @@ void SelectMachineDialog::change_materialitem_tip(bool no_ams_only_ext)
int id = iter->first;
Material *item = iter->second;
if (item) {
if (no_ams_only_ext && item->item->m_ams_name == "Ext") {
if (no_ams_only_ext && item->item->m_ams_name == _L("Ext")) {
item->item->SetToolTip(wxEmptyString);
}
else {
+3 -3
View File
@@ -1020,7 +1020,7 @@ void SendMultiMachinePage::OnSelectRadio(wxMouseEvent& event)
while (iter != m_material_list.end()) {
Material * item = iter->second;
MaterialItem *m = item->item;
if (item->id == m_current_filament_id) { m->set_ams_info(wxColour("#CECECE"), "Ext", 0, std::vector<wxColour>()); }
if (item->id == m_current_filament_id) { m->set_ams_info(wxColour("#CECECE"), _L("Ext"), 0, std::vector<wxColour>()); }
iter++;
}
} else if (rs->m_param_name == "use_ams") {
@@ -1072,7 +1072,7 @@ bool SendMultiMachinePage::get_value_radio(std::string param)
void SendMultiMachinePage::on_set_finish_mapping(wxCommandEvent& evt)
{
auto selection_data = evt.GetString();
auto selection_data_arr = wxSplit(selection_data.ToStdString(), '|');
auto selection_data_arr = wxSplit(selection_data, '|');
BOOST_LOG_TRIVIAL(info) << "The ams mapping selection result: data is " << selection_data;
@@ -1532,7 +1532,7 @@ void SendMultiMachinePage::sync_ams_list()
MaterialItem* item = new MaterialItem(m_main_page, colour_rgb, _L(display_materials[extruder]));
//item->set_ams_info(wxColour("#CECECE"), "A1", 0, std::vector<wxColour>());
item->set_ams_info(wxColour("#CECECE"), "Ext", 0, std::vector<wxColour>());
item->set_ams_info(wxColour("#CECECE"), _L("Ext"), 0, std::vector<wxColour>());
m_ams_list_sizer->Add(item, 0, wxALL, FromDIP(4));
item->Bind(wxEVT_LEFT_UP, [materials](wxMouseEvent& e) {});
+16 -16
View File
@@ -57,10 +57,10 @@ int json_int_or(const nlohmann::json& j, const char* key, int fallback)
wxString mode_label(ConfigOptionMode mode)
{
switch (mode) {
case comAdvanced: return _L("Advanced");
case comExpert: return _L("Expert");
case comDevelop: return _L("Developer");
default: return _L("Simple");
case comAdvanced: return _L_CONTEXT("Advanced", "Settings Mode");
case comExpert: return _L_CONTEXT("Expert", "Settings Mode");
case comDevelop: return _L_CONTEXT("Developer", "Settings Mode");
default: return _L_CONTEXT("Simple", "Settings Mode");
}
}
@@ -106,25 +106,25 @@ nlohmann::json speed_dial_ui_strings()
{"sd_no_actions", _u8L("No actions yet")},
{"sd_no_tabs_match", _u8L("No tabs match")},
{"sd_no_tabs", _u8L("No tabs")},
{"sd_result_count", _u8L("Showing %s actions")},
{"sd_result_count_all", _u8L("%s actions")},
{"sd_tab_count", _u8L("%s tabs")},
{"sd_tab_match_count", _u8L("%s matches")},
{"sd_favs_full", _u8L("Favourites are full (%s max)")},
{"sd_result_count", _u8L("Matching actions: %s")},
{"sd_result_count_all", _u8L("Actions: %s")},
{"sd_tab_count", _u8L("Tabs: %s")},
{"sd_tab_match_count", _u8L("Matching tabs: %s")},
{"sd_favs_full", _u8L("Favorites are full (%s max)")},
{"sd_go_to_pct", _u8L("Go to %s%% of the layer range")},
{"sd_enter_pct", _u8L("Enter a layer percentage (0-100)")},
{"sd_go_layer_ph", _u8L("Go to layer %% (0-100)")},
{"sd_go_tab_ph", _u8L("Go to tab")},
{"sd_fav_slot", _u8L("Favourite %s (%s)")},
{"sd_pin_fav", _u8L("Pin to favourites (%s)")},
{"sd_unpin_fav", _u8L("Unpin from favourites (%s)")},
{"sd_remove_fav", _u8L("Remove from favourites")},
{"sd_fav_slot", _u8L("Favorite %s (%s)")},
{"sd_pin_fav", _u8L("Pin to favorites (%s)")},
{"sd_unpin_fav", _u8L("Unpin from favorites (%s)")},
{"sd_remove_fav", _u8L("Remove from favorites")},
{"sd_move_left", _u8L("Move left")},
{"sd_move_right", _u8L("Move right")},
{"sd_unpin", _u8L("Unpin")},
{"sd_mode_advanced", _u8L("Advanced")},
{"sd_mode_expert", _u8L("Expert")},
{"sd_mode_develop", _u8L("Developer")},
{"sd_mode_advanced", _u8L_CONTEXT("Advanced", "Settings Mode")},
{"sd_mode_expert", _u8L_CONTEXT("Expert", "Settings Mode")},
{"sd_mode_develop", _u8L_CONTEXT("Developer", "Settings Mode")},
{"sd_wiki_f1", _u8L("Wiki (F1)")},
{"sd_no_wiki", _u8L("No wiki page for this action")},
{"sd_show_details", _u8L("Show details")},
+1 -1
View File
@@ -1216,7 +1216,7 @@ void PrintingTaskPanel::on_stage_clicked(wxMouseEvent &event)
if (obj && obj->stage_curr == 58) {
wxWindow *top = wxGetTopLevelParent(this);
ThermalPreconditioningDialog m_thermal_dialog(top ? top : this, obj->get_dev_id() , "Calculating...");
ThermalPreconditioningDialog m_thermal_dialog(top ? top : this, obj->get_dev_id() , _L("Calculating..."));
m_thermal_dialog.ShowModal();
}
+12 -12
View File
@@ -1228,7 +1228,7 @@ void SyncAmsInfoDialog::sync_ams_mapping_result(std::vector<FilamentInfo> &resul
if (result.empty()) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "ams_mapping result is empty";
for (auto it = m_materialList.begin(); it != m_materialList.end(); it++) {
wxString ams_id = "Ext";
wxString ams_id = _L("Ext");
wxColour ams_col = wxColour(0xCE, 0xCE, 0xCE);
it->second->item->set_ams_info(ams_col, ams_id, true); // sync_ams_mapping_result
}
@@ -1248,7 +1248,7 @@ void SyncAmsInfoDialog::sync_ams_mapping_result(std::vector<FilamentInfo> &resul
wxColour ams_col;
if (f->tray_id == VIRTUAL_TRAY_MAIN_ID || f->tray_id == VIRTUAL_TRAY_DEPUTY_ID) {
ams_id = "Ext";
ams_id = _L("Ext");
}
else if (f->tray_id >= 0) {
@@ -1567,13 +1567,13 @@ bool SyncAmsInfoDialog::is_nozzle_type_match(DevExtderSystem data, wxString &err
if (nozzle_volume_type_opt) {
NozzleVolumeType nozzle_volume_type = (NozzleVolumeType) (nozzle_volume_type_opt->get_at(used_extruders[i]));
if (nozzle_volume_type == NozzleVolumeType::nvtStandard) {
used_extruders_flow[used_extruders[i]] = "Standard";
used_extruders_flow[used_extruders[i]] = L("Standard");
} else if (nozzle_volume_type == NozzleVolumeType::nvtTPUHighFlow) {
used_extruders_flow[used_extruders[i]] = "TPU High Flow";
used_extruders_flow[used_extruders[i]] = L("TPU High Flow");
} else if (nozzle_volume_type == NozzleVolumeType::nvtE3DHighFlow) {
used_extruders_flow[used_extruders[i]] = "E3D High Flow";
used_extruders_flow[used_extruders[i]] = L("E3D High Flow");
} else {
used_extruders_flow[used_extruders[i]] = "High Flow";
used_extruders_flow[used_extruders[i]] = L("High Flow");
}
}
}
@@ -1584,13 +1584,13 @@ bool SyncAmsInfoDialog::is_nozzle_type_match(DevExtderSystem data, wxString &err
std::vector<std::string> flow_type_of_machine;
for (auto it = data.GetExtruders().begin(); it != data.GetExtruders().end(); it++) {
if (it->GetNozzleFlowType() == NozzleFlowType::H_FLOW) {
flow_type_of_machine.push_back("High Flow");
flow_type_of_machine.push_back(L("High Flow"));
} else if (it->GetNozzleFlowType() == NozzleFlowType::S_FLOW) {
flow_type_of_machine.push_back("Standard");
flow_type_of_machine.push_back(L("Standard"));
} else if (it->GetNozzleFlowType() == NozzleFlowType::U_FLOW) {
flow_type_of_machine.push_back("TPU High Flow");
flow_type_of_machine.push_back(L("TPU High Flow"));
} else if (it->GetNozzleFlowType() == NozzleFlowType::E_FLOW) {
flow_type_of_machine.push_back("E3D High Flow");
flow_type_of_machine.push_back(L("E3D High Flow"));
}
}
@@ -1612,7 +1612,7 @@ bool SyncAmsInfoDialog::is_nozzle_type_match(DevExtderSystem data, wxString &err
error_message = wxString::Format(_L("The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). "
"Please make sure the nozzle installed matches with settings in printer, "
"then set the corresponding printer preset while slicing."),
pos, flow_type_of_machine[target_machine_nozzle_id], used_extruders_flow[it->first]);
pos, _L(flow_type_of_machine[target_machine_nozzle_id]), _L(used_extruders_flow[it->first]));
return false;
}
}
@@ -2063,7 +2063,7 @@ void SyncAmsInfoDialog::on_refresh(wxCommandEvent &event)
void SyncAmsInfoDialog::on_set_finish_mapping(wxCommandEvent &evt)
{
auto selection_data = evt.GetString();
auto selection_data_arr = wxSplit(selection_data.ToStdString(), '|');
auto selection_data_arr = wxSplit(selection_data, '|');
BOOST_LOG_TRIVIAL(info) << "The ams mapping selection result: data is " << selection_data;
+2 -1
View File
@@ -2663,7 +2663,8 @@ void Tab::update_preset_description_line()
{
description_line += "\n\n" + _(L("Additional information:")) + "\n";
description_line += "\t" + _(L("vendor")) + ": " + (m_type == Slic3r::Preset::TYPE_PRINTER ? "\n\t\t" : "") + parent->vendor->name +
", ver: " + parent->vendor->config_version.to_string();
// TRN Short for "version"
", " + _L("ver") + ": " + parent->vendor->config_version.to_string();
if (m_type == Slic3r::Preset::TYPE_PRINTER) {
const std::string &printer_model = preset.config.opt_string("printer_model");
if (! printer_model.empty())
+2 -1
View File
@@ -6,6 +6,7 @@
#include "nlohmann/json.hpp"
#include "MainFrame.hpp"
#include "GUI_App.hpp"
#include "I18N.hpp"
#include <cassert>
#include <boost/log/trivial.hpp>
@@ -101,7 +102,7 @@ TaskStateInfo::TaskStateInfo(PrintParams param)
//wxCommandEvent event(EVT_MULTI_SEND_LIMIT);
//wxPostEvent(this, event);
GUI::wxGetApp().mainframe->CallAfter([]() {
GUI::wxGetApp().show_dialog("The printing task exceeds the limit, supporting a maximum of 6 printers.");
GUI::wxGetApp().show_dialog(_L("The printing task exceeds the limit, supporting a maximum of 6 printers."));
});
}
+5 -5
View File
@@ -98,7 +98,7 @@ void TerminalDialog::resolve_and_run(const std::string& cmd)
if (m_runner->is_running()) {
nlohmann::json err;
err["command"] = "process_error";
err["message"] = "A command is already running.";
err["message"] = _u8L("A command is already running.");
call_web_handler(err);
return;
}
@@ -117,7 +117,7 @@ void TerminalDialog::resolve_and_run(const std::string& cmd)
if (consume_command_prefix(cmd, "python", arg_string)) {
const std::string python_path = PythonInterpreter::bundled_python_executable();
if (python_path.empty()) {
send_process_error("Bundled Python executable not found.");
send_process_error(_u8L("Bundled Python executable not found."));
return;
}
executable = python_path;
@@ -125,13 +125,13 @@ void TerminalDialog::resolve_and_run(const std::string& cmd)
else if (consume_command_prefix(cmd, "uv", arg_string)) {
const std::string uv_path = PythonInterpreter::bundled_uv_path();
if (uv_path.empty()) {
send_process_error("uv executable not found.");
send_process_error(_u8L("uv executable not found."));
return;
}
executable = uv_path;
}
else {
send_process_error("Only 'python' and 'uv' commands are supported.");
send_process_error(_u8L("Only 'python' and 'uv' commands are supported."));
return;
}
@@ -166,7 +166,7 @@ void TerminalDialog::resolve_and_run(const std::string& cmd)
if (!started) {
nlohmann::json err;
err["command"] = "process_error";
err["message"] = "Failed to start process.";
err["message"] = _u8L("Failed to start process.");
call_web_handler(err);
}
}
+9 -8
View File
@@ -6,6 +6,7 @@
#include "TextureImportDialog.hpp"
#include "I18N.hpp"
#include "format.hpp"
#include "GUI_App.hpp"
#include "MsgDialog.hpp"
#include "ColorDecomposeDialog.hpp"
@@ -745,7 +746,7 @@ private:
: wxColour(128, 128, 128);
wxString name_str = (idx < m_names.size()) ? filament_name_to_wx_string(m_names[idx])
: wxString::Format("Filament %d", display_number((int)idx));
: wxString::Format(_L("Filament %d"), display_number((int)idx));
row->SetToolTip(name_str);
row->Bind(wxEVT_PAINT, [this, idx, sq, sq_r, sq_x, gap1, fil_clr, name_str, row_bg, hover_bg, name_fg](wxPaintEvent& e) {
@@ -828,7 +829,7 @@ private:
row->SetBackgroundColour(row_bg);
row->SetBackgroundStyle(wxBG_STYLE_PAINT);
row->SetCursor(wxCursor(wxCURSOR_HAND));
row->SetToolTip(entry.name.empty() ? wxString::Format("Filament %d", display_number(idx)) : filament_name_to_wx_string(entry.name));
row->SetToolTip(entry.name.empty() ? wxString::Format(_L("Filament %d"), display_number(idx)) : filament_name_to_wx_string(entry.name));
row->Bind(wxEVT_PAINT, [this, entry, idx, row_bg, hover_bg, name_fg](wxPaintEvent& e) {
auto* p = static_cast<wxPanel*>(e.GetEventObject());
@@ -1790,7 +1791,7 @@ TextureImportDialog::TextureImportDialog(
entry.dialog_index = (int)i;
entry.color_hex = texture_normalize_color_hex(entry.color_hex);
if (entry.name.empty())
entry.name = "Filament " + std::to_string(i + 1);
entry.name = GUI::format(_u8L("Filament %d"), i + 1);
m_filament_color_strs.push_back(entry.color_hex);
m_filament_names.push_back(entry.name);
m_filament_colors_rgba.push_back(parse_color_string(entry.color_hex));
@@ -2585,7 +2586,7 @@ void TextureImportDialog::on_computation_complete(wxCommandEvent&)
m_filament_entries[i].color_hex = i < m_filament_color_strs.size() ?
texture_normalize_color_hex(m_filament_color_strs[i]) : "#808080";
m_filament_entries[i].name = i < m_filament_names.size() ?
m_filament_names[i] : "Filament " + std::to_string(i + 1);
m_filament_names[i] : GUI::format(_u8L("Filament %d"), i + 1);
}
m_new_filament_colors.clear();
m_new_filament_preset_names.clear();
@@ -2988,7 +2989,7 @@ void TextureImportDialog::compact_used_virtual_filaments()
for (size_t i = 0; i < existing_count; ++i) {
compact_colors.push_back(old_colors[i]);
compact_color_strs.push_back(i < old_color_strs.size() ? old_color_strs[i] : "");
compact_names.push_back(i < old_names.size() ? old_names[i] : "Filament " + std::to_string(i + 1));
compact_names.push_back(i < old_names.size() ? old_names[i] : GUI::format(_u8L("Filament %d"), i + 1));
TextureFilamentEntry entry = i < old_entries.size() ? old_entries[i] : TextureFilamentEntry{};
entry.dialog_index = (int)i;
entry.color_hex = texture_normalize_color_hex(compact_color_strs.back());
@@ -3514,7 +3515,7 @@ void TextureImportDialog::show_filament_popup(size_t row_index)
if (m_mapping_rows[row_index].target_panel) {
wxString label = (idx >= 0 && idx < (int)m_filament_names.size())
? filament_name_to_wx_string(m_filament_names[idx])
: wxString::Format("Filament %d", display_number(idx));
: wxString::Format(_L("Filament %d"), display_number(idx));
m_mapping_rows[row_index].target_panel->SetToolTip(label);
m_mapping_rows[row_index].target_panel->Refresh();
}
@@ -3663,7 +3664,7 @@ void TextureImportDialog::do_auto_match()
// Match clusters to closest existing filaments
std::vector<std::string> names;
for (size_t i = 0; i < m_existing_filament_count; ++i)
names.push_back(m_filament_names.size() > i ? m_filament_names[i] : "Filament " + std::to_string(i + 1));
names.push_back(m_filament_names.size() > i ? m_filament_names[i] : GUI::format(_u8L("Filament %d"), i + 1));
std::vector<std::array<float, 4>> existing_filament_colors(
m_filament_colors_rgba.begin(),
@@ -3760,7 +3761,7 @@ void TextureImportDialog::rebuild_mapping_rows()
auto get_filament_label = [this, display_number](int idx) -> wxString {
if (idx >= 0 && idx < (int)m_filament_names.size())
return filament_name_to_wx_string(m_filament_names[idx]);
return wxString::Format("Filament %d", display_number(idx));
return wxString::Format(_L("Filament %d"), display_number(idx));
};
const wxColour dash_clr = StateColor::darkModeColorFor(wxColour("#ACACAC"));
+1 -1
View File
@@ -1249,7 +1249,7 @@ bool TroubleshootDialog::ExportAsJson(const wxString& json_data, const wxString&
wxFileDialog dialog(this, _L("Choose where to save the exported JSON file"), defaultPath,
export_name.IsEmpty() ? "export.json" : export_name + ".json",
"JSON files (*.json)|*.json",
_L("JSON files (*.json)|*.json"),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
);
+1 -1
View File
@@ -1928,7 +1928,7 @@ UVEditorPanel::UVEditorPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY)
"texture_displacement_distortion" };
const wxString bg_tips[3] = { _L("Height map - show the layer's texture under the islands"),
_L("Checker - a test grid; squares stay square where the unwrap does not stretch"),
_L("Distortion - colour each island by how much the unwrap stretches it") };
_L("Distortion - color each island by how much the unwrap stretches it") };
for (int i = 0; i < 3; ++i) {
m_background[i] = new UVToolButton(this, ID_UV_BG_HEIGHT + i, bg_icons[i], wxEmptyString, bg_tips[i], true, false, 22);
header->Add(m_background[i], 0, wxALIGN_CENTER_VERTICAL | wxLEFT, i == 0 ? gap : FromDIP(3));
+3 -3
View File
@@ -46,8 +46,8 @@ static const std::unordered_map<wxString, wxString> ACCESSORY_DISPLAY_STR = {
{"O2L_10B", L("Laser 10W")},
{"O2L_40B", L("Laser 40W")},
{"O2L_PCM", L("Cutting Module")},
{"O2L_ACM", "Active Cutting Module"},
{"O2L_UCM", "Ultrasonic Cutting Module"},
{"O2L_ACM", L("Active Cutting Module")},
{"O2L_UCM", L("Ultrasonic Cutting Module")},
{"O2L-AFP", L("Auto Fire Extinguishing System")},
{"O2L-FTS", L("Filament Track Switch")},
};
@@ -976,7 +976,7 @@ void MachineInfoPanel::update_ams_ext(MachineObject *obj)
wxString result = it->second.name.substr(0, pos);
result.MakeUpper();
if (auto str_it = ACCESSORY_DISPLAY_STR.find(result); str_it != ACCESSORY_DISPLAY_STR.end())
result = str_it->second;
result = _L(str_it->second);
ams_device_name = result + "-%s";
}
+2 -2
View File
@@ -617,7 +617,7 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
response["sequence_id"] = "";
if (!m_MainPtr->preset_updater) {
response["error"] = "Printer update service is unavailable.";
response["error"] = _u8L("Printer update service is unavailable.");
wxString strJS = wxString::Format("HandleStudio(%s)", response.dump(-1, ' ', true));
wxGetApp().CallAfter([this, strJS] { RunScript(strJS); });
} else {
@@ -671,7 +671,7 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
});
} catch (const std::exception &e) {
BOOST_LOG_TRIVIAL(warning) << "Failed to check for new printers: " << e.what();
response["error"] = "Failed to check for new printers.";
response["error"] = _u8L("Failed to check for new printers.");
wxString strJS = wxString::Format("HandleStudio(%s)", response.dump(-1, ' ', true));
wxGetApp().CallAfter([this, strJS] { RunScript(strJS); });
}
+1 -1
View File
@@ -974,7 +974,7 @@ void WebViewPanel::OnError(wxWebViewEvent& evt)
wxLogMessage("%s", "Error; url='" + evt.GetURL() + "', error='" + category + " (" + evt.GetString() + ")'");
// Show the info bar with an error
m_info->ShowMessage(_L("An error occurred loading ") + evt.GetURL() + "\n" + "'" + category + "'", wxICON_ERROR);
m_info->ShowMessage(wxString::Format(_L("An error occurred loading %s"), evt.GetURL()) + "\n" + "'" + category + "'", wxICON_ERROR);
}
UpdateState();
+6 -5
View File
@@ -1,6 +1,7 @@
#include "AMSItem.hpp"
#include "Label.hpp"
#include "../I18N.hpp"
#include "../format.hpp"
#include "../GUI_App.hpp"
#include "../FilamentBitmapUtils.hpp"
#include "../Utils/WxFontUtils.hpp"
@@ -1180,9 +1181,9 @@ void AMSLib::render_lite_text(wxDC& dc)
}
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_EMPTY) {
auto tsize = dc.GetMultiLineTextExtent(_L("/"));
auto tsize = dc.GetMultiLineTextExtent("/");
auto pot = wxPoint((libsize.x - tsize.x) / 2 + FromDIP(2), (libsize.y - tsize.y) / 2 + FromDIP(3));
dc.DrawText(_L("/"), pot);
dc.DrawText("/", pot);
}
}
@@ -4055,7 +4056,7 @@ void FeedDirectionDialog::OnRadioClicked(wxCommandEvent& evt)
m_extruderImage->setExtruderUsed("left");
m_load_extruder_id = 1;
{
SetTitle(wxString::Format(_L("Load %s to ") + _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase)), m_filament_id));
SetTitle(format_wxstr(_L("Load %1% to %2%"), m_filament_id, _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase))));
}
}
else if (clicked == m_rightRadio)
@@ -4064,7 +4065,7 @@ void FeedDirectionDialog::OnRadioClicked(wxCommandEvent& evt)
m_extruderImage->setExtruderUsed("right");
m_load_extruder_id = 0;
{
SetTitle(wxString::Format(_L("Load %s to ") + _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase)), m_filament_id));
SetTitle(format_wxstr(_L("Load %1% to %2%"), m_filament_id, _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase))));
}
}
}
@@ -4124,7 +4125,7 @@ void FeedDirectionDialog::SetExtruderMapping(MachineObject* obj,
return;
m_filament_id = filamentID;
SetTitle(wxString::Format(_L("Load %s to "), filamentID));
SetTitle(wxString::Format(_L("Load %s"), filamentID));
std::vector<wxString> extruderMapping(extruderSlots.size());
for (size_t i = 0; i < extruderSlots.size(); ++i) {
+2 -5
View File
@@ -147,11 +147,8 @@ void FilamentLoad::SetFilamentStep(FilamentStep item_idx, FilamentStepType f_typ
}
}
wxString slot_info = L"AMS-";
slot_info = slot_info + std::to_string(m_ams_id);
slot_info = slot_info + L'-';
slot_info = slot_info + std::to_string(m_slot_id);
slot_info = slot_info + L" Slot";
// TRN AMS unit number, then slot number
wxString slot_info = wxString::Format(_L("AMS-%d-%d Slot"), m_ams_id, m_slot_id);
step_control->SetSlotInformation(slot_info);
}
+1 -1
View File
@@ -526,7 +526,7 @@ void ProgressDialog::EnsureActiveEventLoopExists()
wxStaticText *ProgressDialog::CreateLabel(const wxString &text, wxSizer *sizer)
{
wxStaticText *label = new wxStaticText(this, wxID_ANY, text);
wxStaticText *value = new wxStaticText(this, wxID_ANY, wxGetTranslation("unknown"));
wxStaticText *value = new wxStaticText(this, wxID_ANY, _L("unknown"));
// Match the message label's look so the times theme with the rest of the
// dialog: PROGRESSDIALOG_GREY_700 is a key in the dark-mode colour map, so
+4 -3
View File
@@ -5,6 +5,7 @@
#include "wx/progdlg.h"
#include "wx/weakref.h"
#include "wx/simplebook.h"
#include "../I18N.hpp"
#include <wx/dlimpexp.h>
#include <wx/string.h>
#include <cstddef>
@@ -105,9 +106,9 @@ protected:
void SetMaximum(int maximum);
// Return the labels to use for showing the elapsed/estimated/remaining
// times respectively.
static wxString GetElapsedLabel() { return wxGetTranslation("Elapsed time:"); }
static wxString GetEstimatedLabel() { return wxGetTranslation("Estimated time:"); }
static wxString GetRemainingLabel() { return wxGetTranslation("Remaining time:"); }
static wxString GetElapsedLabel() { return _L("Elapsed time:"); }
static wxString GetEstimatedLabel() { return _L("Estimated time:"); }
static wxString GetRemainingLabel() { return _L("Remaining time:"); }
// Similar to wxWindow::HasFlag() but tests for a presence of a wxPD_XXX
// flag in our (separate) flags instead of using m_windowStyle.
+4 -2
View File
@@ -366,7 +366,8 @@ SideTools::SideTools(wxWindow *parent, wxWindowID id, const wxPoint &pos, const
sizer_error_code->Add(m_st_txt_error_code, 0, wxALL, 0);
auto st_title_error_desc = new wxStaticText(m_side_error_panel, wxID_ANY, wxT("desc"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
// TRN Short for "description" of a connection error
auto st_title_error_desc = new wxStaticText(m_side_error_panel, wxID_ANY, _L("desc"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
auto st_title_error_desc_doc = new wxStaticText(m_side_error_panel, wxID_ANY, ": ");
m_st_txt_error_desc = new Label(m_side_error_panel, wxEmptyString, LB_AUTO_WRAP);
st_title_error_desc->SetForegroundColour(0x909090);
@@ -383,7 +384,8 @@ SideTools::SideTools(wxWindow *parent, wxWindowID id, const wxPoint &pos, const
sizer_error_desc->Add(st_title_error_desc_doc, 0, wxALL, 0);
sizer_error_desc->Add(m_st_txt_error_desc, 0, wxALL, 0);
auto st_title_extra_info = new wxStaticText(m_side_error_panel, wxID_ANY, wxT("info"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
// TRN Short for "additional information" about a connection error
auto st_title_extra_info = new wxStaticText(m_side_error_panel, wxID_ANY, _L("info"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
auto st_title_extra_info_doc = new wxStaticText(m_side_error_panel, wxID_ANY, ": ");
m_st_txt_extra_info = new Label(m_side_error_panel, wxEmptyString, LB_AUTO_WRAP);
st_title_extra_info->SetForegroundColour(0x909090);
+4 -2
View File
@@ -1,5 +1,6 @@
#include "StepCtrl.hpp"
#include "Label.hpp"
#include "../I18N.hpp"
#include <wx/anybutton.h>
#include <wx/checklst.h>
@@ -423,8 +424,9 @@ void FilamentStepIndicator::doRender(wxDC& dc)
dc.SetTextForeground(wxColour(0, 150, 136));
int circleX = 20;
int circleY = 20;
wxSize sz = dc.GetTextExtent(L"Loading");
dc.DrawText(L"Loading", circleX, circleY);
const wxString loading = _L("Loading");
wxSize sz = dc.GetTextExtent(loading);
dc.DrawText(loading, circleX, circleY);
dc.SetFont(::Label::Body_13);
+2 -1
View File
@@ -480,7 +480,8 @@ Temp_Calibration_Dlg::Temp_Calibration_Dlg(wxWindow* parent, wxWindowID id, Plat
if(!ti->GetTextCtrl()->GetValue().ToULong(&t))
return;
if(t> 500 || t < 155){
MessageDialog msg_dlg(nullptr, wxString::Format(L"Supported range: 170%s - 500%s",
// TRN %s is the temperature unit
MessageDialog msg_dlg(nullptr, wxString::Format(_L("Supported range: 170%s - 500%s"),
_L("\u2103" /* °C */), _L("\u2103" /* °C */)),
wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();

Some files were not shown because too many files have changed in this diff Show More