merge main

This commit is contained in:
Lam Wei Lun
2026-10-06 13:08:46 +08:00
parent ccbb73baaf
commit ecbd03fed7
868 changed files with 203633 additions and 35823 deletions
+9 -5
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,15 +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
lit = lambda s: None if s == "nullptr" else 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]),
+33 -6
View File
@@ -37,6 +37,17 @@ def cstr(s):
return '"' + s.replace("\\", "\\\\").replace('"', '\\"') + '"'
def tstr(s):
# User-facing text: wrapped in the no-op L() marker so xgettext puts it in the catalogue.
# The DesignPanel translates it at use; without the marker it compiles and never translates.
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.
@@ -81,6 +92,13 @@ def main():
"",
"#include <cstdint>",
"",
"#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 {",
"",
"// What the viewport has selected. Ordered as in tool_atlas.json; the bitmask in",
@@ -103,8 +121,8 @@ 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); translated at use with wxGetTranslation",
" int row; // 0..7, the ratified index — NEVER reorder",
" 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;",
" const char* refusal; // why this row is greyed, in the product's own words",
@@ -125,11 +143,20 @@ def main():
"// Row labels, in ratified order.",
"static const char* const kOfferRowNames[] = {",
]
# A flat row's label is never shown, so it is not marked for translation.
for s in A["slots"]:
lines.append(f' "{s["label"]}",')
lines.append(f' {cstr(s["label"]) if s.get("flat") else tstr(s["label"])},')
lines += [
"};",
f"static const int kOfferRowCount = {len(slots)};",
"// A flat row is not a family: its verbs come first, at the top level of the offer, each",
"// an item of its own.",
"static const bool kOfferRowFlat[] = {",
]
for s in A["slots"]:
lines.append(f' {"true" if s.get("flat") else "false"},')
lines += [
"};",
"",
"static const OfferVerb kOfferVerbs[] = {",
]
@@ -151,12 +178,12 @@ 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"]), cstr(v["name"]), slots.index(v["slot"]),
cstr(v.get("key")), cstr(v.get("action")), cstr(v.get("refusal")),
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",
"true" if v.get("mode") == "sketch" else "false",
cstr(v.get("family")), cstr(v.get("icon")), cstr(v.get("hint"))))
tstr(v.get("family")), cstr(v.get("icon")), tstr(v.get("hint"))))
lines += [
"};",
f"static const int kOfferVerbCount = {len(A['verbs'])};",
+47 -39
View File
@@ -67,6 +67,12 @@
"angle": 225,
"label": "Modify",
"why": "edits or removes what is already there"
},
{
"id": "top",
"label": "Top",
"flat": true,
"why": "the verbs a selection is opened for most. A flat slot is not a family: its verbs sit first, at the top level of the offer, each an item of its own, and its label is never shown. Appended last, so no ratified index moved."
}
],
"selections": [
@@ -326,7 +332,7 @@
"id": "rib",
"name": "Rib",
"slot": "add",
"key": null,
"key": "R",
"feature": "Rib",
"mcp": "rib",
"accepts": [
@@ -343,7 +349,7 @@
},
{
"id": "boolean",
"name": "Union",
"name": "Join",
"slot": "add",
"key": "Shift+B",
"feature": "Boolean",
@@ -354,7 +360,7 @@
"needs": {
"bodies": 2
},
"refusal": "Boolean needs two bodies — create or import a second solid",
"refusal": "Boolean needs two bodies — add or import a second one",
"gui": true,
"action": "btn:bool#0",
"icon": "design_boolean",
@@ -373,7 +379,7 @@
"needs": {
"bodies": 2
},
"refusal": "Boolean needs two bodies — create or import a second solid",
"refusal": "Boolean needs two bodies — add or import a second one",
"gui": true,
"action": "btn:bool#1",
"mode": null,
@@ -393,7 +399,7 @@
"needs": {
"bodies": 2
},
"refusal": "Boolean needs two bodies — create or import a second solid",
"refusal": "Boolean needs two bodies — add or import a second one",
"gui": true,
"action": "btn:bool#2",
"mode": null,
@@ -483,7 +489,7 @@
"needs": {
"sheet": true
},
"refusal": "target is not a sheet body",
"refusal": "Thicken Surface needs a surface body — make one with a Surface tool first",
"gui": true,
"action": "fly:surface#5",
"icon": "design_thicken",
@@ -507,7 +513,7 @@
"gui": true,
"action": "key:S+H",
"icon": "design_hole",
"hint": "Drill a hole, centred on a picked face or placed on a plane"
"hint": "Drill a hole, centerd on a picked face or placed on a plane"
},
{
"id": "thread",
@@ -543,7 +549,7 @@
"needs": {
"bodies": 1
},
"refusal": "Shell needs a solid body",
"refusal": "Shell needs a solid body — add or import one first",
"gui": true,
"action": "key:S+K",
"icon": "design_shell",
@@ -569,7 +575,7 @@
"needs": {
"bodies": 1
},
"refusal": "Create a solid body to cut first",
"refusal": "Cut needs a solid body — add or import one first",
"gui": true,
"action": "key:S+X",
"icon": "design_cut",
@@ -594,7 +600,7 @@
"needs": {
"bodies": 1
},
"refusal": "Split needs a solid body",
"refusal": "Split needs a solid body — add or import one first",
"gui": false,
"action": null,
"icon": null,
@@ -677,7 +683,7 @@
"needs": {
"sheet": true
},
"refusal": "target is not a sheet body",
"refusal": "Surface Offset needs a surface body — make one with a Surface tool first",
"gui": true,
"action": "fly:surface#4",
"icon": "design_offset",
@@ -699,7 +705,7 @@
"needs": {
"bodies": 1
},
"refusal": "Create a solid body to pattern first",
"refusal": "Pattern needs a solid body — add or import one first",
"gui": true,
"action": "btn:pat#0",
"icon": "design_array",
@@ -721,7 +727,7 @@
"needs": {
"bodies": 1
},
"refusal": "Create a solid body to pattern first",
"refusal": "Pattern needs a solid body — add or import one first",
"gui": true,
"action": "btn:pat#1",
"mode": null,
@@ -768,7 +774,7 @@
"needs": {
"bodies": 1
},
"refusal": "Pattern on curve needs a body and a curve",
"refusal": "Pattern on Curve needs a body and a curve",
"gui": false,
"action": null,
"icon": null,
@@ -816,11 +822,11 @@
"needs": {
"bodies": 2
},
"refusal": "A mate needs two coordinate systems",
"refusal": "Mate needs two coordinate systems — create them first",
"gui": true,
"action": "fly:placement#2",
"icon": "design_c_coincident",
"hint": "Assembly: align two CoordSys features (fastened, planar, revolute, slider, cylindrical)"
"hint": "Assembly: align two coordinate systems (fastened, planar, revolute, slider, cylindrical)"
},
{
"id": "align",
@@ -835,7 +841,7 @@
"needs": {
"bodies": 1
},
"refusal": "Align needs a body",
"refusal": "Align needs a body — add or import one first",
"gui": false,
"action": null,
"icon": null,
@@ -885,7 +891,7 @@
},
{
"id": "coordsys_v",
"name": "Coord Sys",
"name": "Coordinate system",
"slot": "reference",
"key": "Shift+C",
"feature": "CoordSys",
@@ -972,7 +978,7 @@
},
{
"id": "mass_props",
"name": "Mass",
"name": "Volume and area",
"slot": "reference",
"key": null,
"feature": null,
@@ -1003,14 +1009,15 @@
"feature": null,
"mcp": "check_interference",
"accepts": [
"body_solid",
"bodies_2"
],
"needs": {
"bodies": 2
},
"refusal": null,
"gui": false,
"action": null,
"refusal": "Interference needs at least two bodies",
"gui": true,
"action": "btn:interference",
"icon": null,
"hint": "Check whether two bodies overlap — reports, changes nothing"
},
@@ -1043,7 +1050,7 @@
{
"id": "rename",
"name": "Rename…",
"slot": "modify",
"slot": "top",
"key": "F2",
"feature": "Tree",
"mcp": null,
@@ -1082,8 +1089,8 @@
},
{
"id": "colour",
"name": "Colour",
"slot": "modify",
"name": "Color",
"slot": "top",
"key": null,
"feature": null,
"mcp": null,
@@ -1104,7 +1111,7 @@
"gui": true,
"action": "btn:colour",
"icon": "color_palette",
"hint": "Set the selected body's display colour"
"hint": "Set the selected body's display color"
},
{
"id": "delete",
@@ -1227,7 +1234,7 @@
},
{
"id": "sk_rect_center",
"name": "Centre rectangle",
"name": "Center rectangle",
"slot": "create",
"key": null,
"feature": "Sketch",
@@ -1296,7 +1303,7 @@
},
{
"id": "sk_circle",
"name": "Centre circle",
"name": "Center circle",
"slot": "create",
"key": "C",
"feature": "Sketch",
@@ -1411,7 +1418,7 @@
},
{
"id": "sk_arc_center",
"name": "Centre-point arc",
"name": "Center-point arc",
"slot": "create",
"key": null,
"feature": "Sketch",
@@ -1453,7 +1460,7 @@
"action": "key:S",
"family": "Slot",
"icon": "design_slot",
"hint": "Slot — two centerline ends, then end radius"
"hint": "Slot — two centerline ends, then the width"
},
{
"id": "sk_slot_arc",
@@ -1567,7 +1574,7 @@
"mode": "sketch",
"family": "Polygon",
"icon": "design_polygon",
"hint": "Triangle — click centre, then a vertex"
"hint": "Triangle — click center, then a vertex"
},
{
"id": "sk_poly_4",
@@ -1590,7 +1597,7 @@
"mode": "sketch",
"family": "Polygon",
"icon": "design_polygon",
"hint": "Square — click centre, then a vertex"
"hint": "Square — click center, then a vertex"
},
{
"id": "sk_poly_5",
@@ -1613,7 +1620,7 @@
"mode": "sketch",
"family": "Polygon",
"icon": "design_polygon",
"hint": "Pentagon — click centre, then a vertex"
"hint": "Pentagon — click center, then a vertex"
},
{
"id": "sk_polygon",
@@ -1636,7 +1643,7 @@
"action": "btn:poly#6",
"family": "Polygon",
"icon": "design_polygon",
"hint": "Hexagon — click centre, then a vertex"
"hint": "Hexagon — click center, then a vertex"
},
{
"id": "sk_poly_8",
@@ -1659,7 +1666,7 @@
"mode": "sketch",
"family": "Polygon",
"icon": "design_polygon",
"hint": "Octagon — click centre, then a vertex"
"hint": "Octagon — click center, then a vertex"
},
{
"id": "sk_poly_12",
@@ -1682,7 +1689,7 @@
"mode": "sketch",
"family": "Polygon",
"icon": "design_polygon",
"hint": "Dodecagon — click centre, then a vertex"
"hint": "Dodecagon — click center, then a vertex"
},
{
"id": "sk_poly_inscribed",
@@ -1772,7 +1779,7 @@
"action": "btn:text",
"mode": "sketch",
"icon": "design_text",
"hint": "Type text; its outline is added to this sketch as editable lines"
"hint": "Type text; it becomes a Text feature on this sketch's plane, editable later"
},
{
"id": "sk_svg",
@@ -2048,7 +2055,7 @@
{
"id": "constrain",
"name": "Constrain sketch",
"slot": "modify",
"slot": "reference",
"key": null,
"feature": "Sketch",
"mcp": null,
@@ -2067,7 +2074,8 @@
"note": [
"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."
"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."
]
},
{