Files
solvecraft/crates/doc
CamWight 64ba396c05 Part properties: one table of keys (#4784) (#4786)
* claim: #4784

* Part properties: one table of keys, each with its scope, check and label (#4784)

SolidCraft's part-property keys (project, part number, revision, author,
organization, description, licence) were declared once but listed again
by hand in each command, error, dialog and window. They are now one
table, metadata::KEYS: each row has the key, where it may be set
(Scope: the design, a component or both), how its value is checked and
the message id of its label. A new key is one row.

Metadata::set is told whose metadata it changes (Owner::Design or
Owner::Component), and a key is taken where its scope covers that
owner. is_well_known, both set commands, document.metadata,
component.metadata, the refusals, the Design Properties dialog and the
Bill of Materials window read the table; the hand-written lists are
gone (WELL_KNOWN, the label match whose fallback named any unknown key
"License", the window's three labels). metadata::BOM_KEYS names, in
column order, the keys a bill of materials lists for each part:
component.metadata returns them, component.metadata.set takes each as a
parameter of its own and the window edits them; a test keeps each one a
row of the table that a component takes. Free properties use the keys'
text rule (metadata::check_text) instead of a copy of it. The params
docs point to document.metadata's properties instead of repeating the
keys.

Every key accepted before still is, on the design and on a component.
Two things change:
- a refused key or a full metadata on a component says "part property"
  ("`bogus` is not a part property: …", "part properties are limited
  to …"), not "design property";
- changing the design's own properties no longer evaluates the model.
  The fields that change no geometry are named once,
  Document::with_part_properties_of: the design's metadata, and each
  component's metadata and free properties. It compares them first and
  copies the design only when one differs, as before.

The shortcut is for a session's own edits only. A command that gives
the session another design (doc.open, file.new, doc.recover: through
Session::replace_design, which now counts them) is refreshed in full,
however little the new design differs from the one before, so its
joints are solved and its occurrence state pruned. Before, opening a
design that differed from the open one only in render settings or
component properties skipped that; with the design's properties in the
list it would have for two revisions of one part too.

Tests: the table (one row per key, the dialog's order); the bill of
materials' keys (rows a component takes, in column order); each scope
on each owner, and refusals that name the owner (the empty key, an
unknown key, a 256-byte key shown cut); the text check at 4096 bytes,
line breaks, tabs and control characters; hostile keys and values
refused without a change; only-part-property changes in each scope,
and changes beside them (units, a component's name, an added, removed
or swapped component); document.metadata.set, remove, undo and redo
evaluate nothing; opening a revision that differs only in its author
solves its joint; the component wording, the shortcuts and the limits;
the dialog's and the window's labels from the table.

What the tests can't reach: every row is Scope::Both, so a known key
refused for its owner (the wrong-owner branch of check) can't happen
yet. It becomes live with the first single-scope row, bom_type, a
component-only key.

Left for later (not this topic):
- Metadata::others() ignores scope, so a component-only key stored on
  the design would be neither a dialog field nor listed under other
  tools' data. It matters from the first single-scope key (bom_type).
- assembly.bom's rows, its CSV columns and the window's grid headers
  still name the three keys by hand; the bill of materials module's
  rewrite will read BOM_KEYS.
- The bill of materials types (P1, #5107, into drawings) still use
  WELL_KNOWN and the two-argument set: once this is on main, bom_type
  is rebuilt on it as one KEYS row with Scope::Component, set through
  Owner::Component.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 20:03:22 +00:00
..