FieldDefinition.h header
#include <ew/core/taxonomy/FieldDefinition.h>
Namespace ew::core::taxonomy
FieldDefinition class
class ew::core::taxonomy::FieldDefinition
The definition of one user-defined codex field on a taxonomy category: its stable key, display label, data type, and constraints. The key is fixed at construction and used for serialization and value lookup; everything else is editable. A Category forms its schema from a list of these, and they inherit to descendant categories.
A field is either SELECTABLE – the ordinary kind, a slot each entity fills in for itself – or FIXED, where the category supplies one value that every entity beneath reads and none can change. See isFixed.
Members
ew::core::taxonomy::FieldDefinition::FieldDefinition(QString key, QString label, FieldType type)
Creates a field with stable key, display label, and data type.
const QString & ew::core::taxonomy::FieldDefinition::key() const
The stable identifier used to store and look up this field's values. Immutable.
const QString & ew::core::taxonomy::FieldDefinition::label() const
The human-readable label shown in the UI.
void ew::core::taxonomy::FieldDefinition::setLabel(QString label)
Sets the field's display label.
FieldType ew::core::taxonomy::FieldDefinition::type() const
The field's data type.
void ew::core::taxonomy::FieldDefinition::setType(FieldType type)
Sets the field's data type.
bool ew::core::taxonomy::FieldDefinition::isRequired() const
Whether an entity must supply a value for this field.
void ew::core::taxonomy::FieldDefinition::setRequired(bool isRequired)
Sets whether a value is mandatory. Turning this on clears isFixed – see setFixed.
bool ew::core::taxonomy::FieldDefinition::isFixed() const
Whether the category supplies this field's value itself, and entities below it cannot.
A fixed field is DATA rather than a slot: its value is held once, here on the category, and every entity beneath shows that same value read-only. It is what lets a "Cities" category nested under the kingdom Vaertis state kingdom = Vaertis once, instead of every city storing its own copy of a fact none of them can vary.
void ew::core::taxonomy::FieldDefinition::setFixed(bool isFixed)
Sets whether the category supplies the value. Turning this on clears isRequired.
The two are mutually exclusive, and the exclusion is enforced HERE rather than left to each caller: "the entity must supply a value" and "the entity cannot supply a value" is a contradiction, and a field holding both would make a form that can never be completed.
const QString & ew::core::taxonomy::FieldDefinition::fixedValue() const
The value every entity below this category reads for a fixed field; empty otherwise.
void ew::core::taxonomy::FieldDefinition::setFixedValue(QString fixedValue)
Sets the value a fixed field supplies. Meaningful only while isFixed.
const QStringList & ew::core::taxonomy::FieldDefinition::options() const
The allowed values, used when type() is FieldType::Choice; empty otherwise.
void ew::core::taxonomy::FieldDefinition::setOptions(QStringList options)
Sets the allowed values (for FieldType::Choice).
ew::core::foundation::CategoryId ew::core::taxonomy::FieldDefinition::referenceCategoryId() const
The only category a FieldType::Reference value may point into, with its descendants; null for any object in the project.
An "Affiliation" that offers every document, map and timeline event in the project is not a choice, it is a haystack – the field says what KIND of thing it points at, and the picker should say the same. Null stays the default so a field written before this, or one that genuinely points anywhere, is unaffected.
A restriction constrains what can be PICKED, not what is stored: a value already pointing outside the target category keeps working and keeps showing its name, because a schema change is not a licence to silently drop the writer's data.
void ew::core::taxonomy::FieldDefinition::setReferenceCategoryId(ew::core::foundation::CategoryId referenceCategoryId)
Sets the category a reference value may point into. Meaningful only for FieldType::Reference; a null id lifts the restriction.
FieldType ew::core::taxonomy::FieldDefinition::elementType() const
What a List field's elements are, or what a Map field's VALUES are.
A composite field says what it holds, exactly as a Reference says what it points at. Without it a list would be a bag of anything, which is a paragraph with commas in it – and the point of making lists data is that a validator, a rollup and an exporter can all rely on every element being the same shape.
Meaningless for a scalar field. A List of Lists is deliberately not expressible: the case that wants it wants a property block (Gap Work Order 1.5), which is a named thing rather than a nest of anonymous ones.
void ew::core::taxonomy::FieldDefinition::setElementType(FieldType elementType)
Sets what a List holds, or what a Map's values are.
FieldType ew::core::taxonomy::FieldDefinition::keyType() const
What a Map field's KEYS are, declared independently of its values so "damage type to resistance number" and "region to price" are both expressible.
void ew::core::taxonomy::FieldDefinition::setKeyType(FieldType keyType)
Sets what a Map's keys are.
int ew::core::taxonomy::FieldDefinition::minimumCount() const
The fewest elements a List may hold, or 0 for no floor.
void ew::core::taxonomy::FieldDefinition::setMinimumCount(int minimumCount)
Sets the fewest elements a List may hold.
int ew::core::taxonomy::FieldDefinition::maximumCount() const
The most elements a List may hold, or 0 for no ceiling.
Zero rather than a sentinel maximum, because "no ceiling" is what almost every list wants and a default that has to be spelled out is a default nobody sets.
void ew::core::taxonomy::FieldDefinition::setMaximumCount(int maximumCount)
Sets the most elements a List may hold.
bool ew::core::taxonomy::FieldDefinition::requiresUniqueElements() const
Whether a List's elements must all differ.
Off by default: a list of the same word twice is legitimate in plenty of worlds, and a constraint nobody asked for is a finding nobody wanted.
void ew::core::taxonomy::FieldDefinition::setRequiresUniqueElements(bool requiresUniqueElements)
Sets whether a List's elements must all differ.
ew::core::foundation::BlockId ew::core::taxonomy::FieldDefinition::blockId() const
The block a Block field holds – or, for a List or Map whose elements are Blocks, the block each element holds. Null when neither applies.
By ID rather than by name, so renaming "Stats" to "Attributes" does not orphan every property that uses it. A field naming a block the project no longer has is reported rather than guessed at: silently dropping to Text would discard every value stored under it.
void ew::core::taxonomy::FieldDefinition::setBlockId(ew::core::foundation::BlockId blockId)
Sets the block this field (or each of its elements) holds.
const QString & ew::core::taxonomy::FieldDefinition::description() const
Optional help text explaining the field's purpose.
void ew::core::taxonomy::FieldDefinition::setDescription(QString description)
Sets the field's help text.
Functions
FieldDefinition ew::core::taxonomy::withKey(const FieldDefinition &definition, QString key)
definition with its key replaced by key and EVERYTHING ELSE carried across.
For the one thing that needs it: a property is described in a dialog before its key is known, because the key is derived from the label the writer types. Both desktop create paths therefore had to move a described property onto its real key, and both did it by constructing a fresh FieldDefinition and copying the fields they remembered – so a list's element type, a map's key type, the count limits, the uniqueness rule, the block and the reference restriction were all dropped on the way. "A list of Characters, at most five" was created as a bare list of text, while EDITING that same property kept everything, because the edit path passes the definition whole.
A copy-and-replace-one-field function exists so there is one place that knows the whole struct, rather than two call sites that each have to remember it. That is the same failure SetTimelineEventCommand's fieldsOf exists to prevent, and this is its equivalent here: a field added to FieldDefinition is carried by every caller automatically.