[Doc] Improve documentation PropertyContainer
This commit is contained in:
committed by
Benjamin Nauck
parent
8956c56235
commit
519b78d775
@@ -334,6 +334,14 @@ public:
|
||||
return FeatureT::canLoadPartial();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called when a property is edited by the user.
|
||||
*
|
||||
* This override first attempts to handle the property edit in the
|
||||
* associated Python object.
|
||||
*
|
||||
* @param[in] propName The name of the property to be edited.
|
||||
*/
|
||||
void editProperty(const char* propName) override
|
||||
{
|
||||
if (!imp->editProperty(propName)) {
|
||||
|
||||
@@ -63,49 +63,83 @@ class AppExport Property: public Base::Persistence
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Defines the position in the status bitmask.
|
||||
*/
|
||||
enum Status
|
||||
{
|
||||
Touched = 0, // touched property
|
||||
Immutable = 1, // can't modify property
|
||||
ReadOnly = 2, // for property editor
|
||||
Hidden = 3, // for property editor
|
||||
Transient = 4, // for property container save
|
||||
MaterialEdit = 5, // to turn ON PropertyMaterial edit
|
||||
NoMaterialListEdit = 6, // to turn OFF PropertyMaterialList edit
|
||||
Output = 7, // same effect as Prop_Output
|
||||
LockDynamic = 8, // prevent being removed from dynamic property
|
||||
NoModify = 9, // prevent causing Gui::Document::setModified()
|
||||
PartialTrigger = 10, // allow change in partial doc
|
||||
NoRecompute = 11, // don't touch owner for recompute on property change
|
||||
Single = 12, // for save/load of floating point numbers
|
||||
Ordered = 13, // for PropertyLists whether the order of the elements is
|
||||
// relevant for the container using it
|
||||
EvalOnRestore = 14, // In case of expression binding, evaluate the
|
||||
// expression on restore and touch the object on value change.
|
||||
Busy = 15, // internal use to avoid recursive signaling
|
||||
CopyOnChange =
|
||||
16, // for Link to copy the linked object on change of the property with this flag
|
||||
UserEdit = 17, // cause property editor to create button for user defined editing
|
||||
/// @brief Whether a property is touched.
|
||||
Touched = 0,
|
||||
/// @brief Whether a property can be modified.
|
||||
Immutable = 1,
|
||||
/// @brief Whether a property is read-only for the property editor.
|
||||
ReadOnly = 2,
|
||||
/// @brief Whether the property is hidden in the property editor.
|
||||
Hidden = 3,
|
||||
/// @brief Whether a property is saved in the document.
|
||||
Transient = 4,
|
||||
/// @brief To turn ON PropertyMaterial edit.
|
||||
MaterialEdit = 5,
|
||||
/// @brief To turn OFF PropertyMaterialList edit.
|
||||
NoMaterialListEdit = 6,
|
||||
/// @brief Whether a property is an output property.
|
||||
Output = 7,
|
||||
/// @brief Whether a dynamic property can be removed.
|
||||
LockDynamic = 8,
|
||||
/// @brief Prevents causing `Gui::Document::setModified()`
|
||||
NoModify = 9,
|
||||
/// @brief Whether to allow change in a partial document.
|
||||
PartialTrigger = 10,
|
||||
/// @brief Whether to prevent to touch the owner for a recompute on property change.
|
||||
NoRecompute = 11,
|
||||
/// @brief Whether a floating point number should be saved as single precision.
|
||||
Single = 12,
|
||||
/// @brief For PropertyLists, whether the order of the elements is
|
||||
/// relevant for the container using it.
|
||||
Ordered = 13,
|
||||
/// @brief In case of expression binding, whether the expression on
|
||||
/// restore and touch the object on value change.
|
||||
EvalOnRestore = 14,
|
||||
/// @brief For internal use to avoid recursive signaling.
|
||||
Busy = 15,
|
||||
/// @brief Whether the linked object should be copied on change of the property.
|
||||
CopyOnChange = 16,
|
||||
/// @brief Whether the property editor should create a button for user defined editing.
|
||||
UserEdit = 17,
|
||||
|
||||
// The following bits are corresponding to PropertyType set when the
|
||||
// property added. These types are meant to be static, and cannot be
|
||||
// changed in runtime. It is mirrored here to save the linear search
|
||||
// required in PropertyContainer::getPropertyType()
|
||||
//
|
||||
|
||||
/// @brief Mark the beginning of enum PropertyType bits.
|
||||
PropStaticBegin = 21,
|
||||
PropDynamic = 21, // indicating the property is dynamically added
|
||||
PropNoPersist = 22, // corresponding to Prop_NoPersist
|
||||
PropNoRecompute = 23, // corresponding to Prop_NoRecompute
|
||||
PropReadOnly = 24, // corresponding to Prop_ReadOnly
|
||||
PropTransient = 25, // corresponding to Prop_Transient
|
||||
PropHidden = 26, // corresponding to Prop_Hidden
|
||||
PropOutput = 27, // corresponding to Prop_Output
|
||||
/// @brief Whether the property is dynamically added.
|
||||
PropDynamic = 21,
|
||||
/// @brief Corresponds to Prop_NoPersist
|
||||
PropNoPersist = 22,
|
||||
/// @brief Corresponds to Prop_NoRecompute
|
||||
PropNoRecompute = 23,
|
||||
/// @brief Corresponds to Prop_ReadOnly
|
||||
PropReadOnly = 24,
|
||||
/// @brief Corresponds to Prop_Transient
|
||||
PropTransient = 25,
|
||||
/// @brief Corresponds to Prop_Hidden
|
||||
PropHidden = 26,
|
||||
/// @brief Corresponds to Prop_Output
|
||||
PropOutput = 27,
|
||||
/// @brief Mark the end of enum PropertyType bits.
|
||||
PropStaticEnd = 28,
|
||||
|
||||
User1 = 28, // user-defined status
|
||||
User2 = 29, // user-defined status
|
||||
User3 = 30, // user-defined status
|
||||
User4 = 31 // user-defined status
|
||||
/// @brief User defined status bit.
|
||||
User1 = 28,
|
||||
/// @brief User defined status bit.
|
||||
User2 = 29,
|
||||
/// @brief User defined status bit.
|
||||
User3 = 30,
|
||||
/// @brief User defined status bit.
|
||||
User4 = 31
|
||||
};
|
||||
|
||||
Property();
|
||||
|
||||
@@ -46,10 +46,6 @@ using namespace std;
|
||||
TYPESYSTEM_SOURCE(App::PropertyContainer,Base::Persistence)
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// Construction/Destruction
|
||||
|
||||
// Here's the implementation! Description should take place in the header file!
|
||||
PropertyContainer::PropertyContainer()
|
||||
{
|
||||
propertyData.parentPropertyData = nullptr;
|
||||
@@ -68,7 +64,6 @@ unsigned int PropertyContainer::getMemSize () const
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
App::Property* PropertyContainer::addDynamicProperty(
|
||||
const char* type, const char* name, const char* group, const char* doc,
|
||||
short attr, bool ro, bool hidden)
|
||||
@@ -191,18 +186,6 @@ const PropertyData * PropertyContainer::getPropertyDataPtr(){return &propertyDat
|
||||
const PropertyData & PropertyContainer::getPropertyData() const{return propertyData;}
|
||||
|
||||
|
||||
/**
|
||||
* @brief PropertyContainer::handleChangedPropertyName is called during restore to possibly
|
||||
* fix reading of older versions of this property container. This method is typically called
|
||||
* if the property on file has changed its name in more recent versions.
|
||||
*
|
||||
* The default implementation does nothing.
|
||||
*
|
||||
* @param reader The XML stream to read from.
|
||||
* @param TypeName Name of property type on file.
|
||||
* @param PropName Name of property on file that does not exist in the container anymore.
|
||||
*/
|
||||
|
||||
void PropertyContainer::handleChangedPropertyName(Base::XMLReader &reader, const char * TypeName, const char *PropName)
|
||||
{
|
||||
(void)reader;
|
||||
@@ -210,18 +193,6 @@ void PropertyContainer::handleChangedPropertyName(Base::XMLReader &reader, const
|
||||
(void)PropName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PropertyContainer::handleChangedPropertyType is called during restore to possibly
|
||||
* fix reading of older versions of the property container. This method is typically called
|
||||
* if the property on file has changed its type in more recent versions.
|
||||
*
|
||||
* The default implementation does nothing.
|
||||
*
|
||||
* @param reader The XML stream to read from.
|
||||
* @param TypeName Name of property type on file.
|
||||
* @param prop Pointer to property to restore. Its type differs from TypeName.
|
||||
*/
|
||||
|
||||
void PropertyContainer::handleChangedPropertyType(XMLReader &reader, const char *TypeName, Property *prop)
|
||||
{
|
||||
(void)reader;
|
||||
|
||||
@@ -45,15 +45,29 @@ class DocumentObject;
|
||||
class Extension;
|
||||
|
||||
// clang-format off
|
||||
|
||||
/**
|
||||
* @brief Flags that define special behaviors for a property.
|
||||
*
|
||||
* These flags can be combined using bitwise OR to assign multiple attributes
|
||||
* to a property.
|
||||
*/
|
||||
enum PropertyType
|
||||
{
|
||||
Prop_None = 0, /*!< No special property type */
|
||||
Prop_ReadOnly = 1, /*!< Property is read-only in the editor */
|
||||
Prop_Transient = 2, /*!< Property content won't be saved to file, but still saves name, type and status */
|
||||
Prop_Hidden = 4, /*!< Property won't appear in the editor */
|
||||
Prop_Output = 8, /*!< Modified property doesn't touch its parent container */
|
||||
Prop_NoRecompute = 16,/*!< Modified property doesn't touch its container for recompute */
|
||||
Prop_NoPersist = 32,/*!< Property won't be saved to file at all */
|
||||
/// @brief No special property type.
|
||||
Prop_None = 0,
|
||||
/// @brief The property is read-only in the editor.
|
||||
Prop_ReadOnly = 1,
|
||||
/// @brief The property content won't be saved to file, but still saves name, type and status.
|
||||
Prop_Transient = 2,
|
||||
/// @brief The property is hidden in the editor.
|
||||
Prop_Hidden = 4,
|
||||
/// @brief A modified property doesn't touch its parent container.
|
||||
Prop_Output = 8,
|
||||
/// @brief A modified property doesn't touch its container for recompute.
|
||||
Prop_NoRecompute = 16,
|
||||
/// @brief property won't be saved to file at all.
|
||||
Prop_NoPersist = 32,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -148,7 +162,15 @@ struct AppExport PropertyData
|
||||
};
|
||||
|
||||
|
||||
/** Base class of all classes with properties
|
||||
/** @brief %Base class of all classes with properties.
|
||||
* @ingroup PropertyFramework
|
||||
*
|
||||
* @details This base class for all classes that hold properties has
|
||||
* essentially two important children: Document and DocumentObject. Both
|
||||
* classes can hold properties and the shared functionality to make that happen
|
||||
* is in this class.
|
||||
*
|
||||
* For a more high-level overview see topic @ref PropertyFramework "Property Framework".
|
||||
*/
|
||||
class AppExport PropertyContainer: public Base::Persistence
|
||||
{
|
||||
@@ -157,94 +179,304 @@ class AppExport PropertyContainer: public Base::Persistence
|
||||
|
||||
public:
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
* @brief Construct a property container.
|
||||
*/
|
||||
PropertyContainer();
|
||||
|
||||
/**
|
||||
* A destructor.
|
||||
* A more elaborate description of the destructor.
|
||||
* @brief Destruct a property container.
|
||||
*/
|
||||
~PropertyContainer() override;
|
||||
|
||||
unsigned int getMemSize () const override;
|
||||
|
||||
/**
|
||||
* @brief Get the full name of the property container.
|
||||
*
|
||||
* The full name typically also contains the name of the document.
|
||||
*
|
||||
* @return The full name of the property container.
|
||||
*/
|
||||
virtual std::string getFullName() const {return {};}
|
||||
|
||||
/// find a property by its name
|
||||
/**
|
||||
* @brief Find a property by its name.
|
||||
*
|
||||
* @param[in] name The name of the property to find.
|
||||
* @return The property if found or `nullptr` when not found.
|
||||
*/
|
||||
virtual Property *getPropertyByName(const char* name) const;
|
||||
/// get the name of a property
|
||||
|
||||
/**
|
||||
* @brief Get the name of a property.
|
||||
*
|
||||
* @param[in] prop The property to get the name for.
|
||||
* @return The name of the property.
|
||||
*/
|
||||
virtual const char* getPropertyName(const Property* prop) const;
|
||||
/// get all properties of the class (including properties of the parent)
|
||||
virtual void getPropertyMap(std::map<std::string,Property*> &Map) const;
|
||||
/// get all properties of the class (including properties of the parent)
|
||||
|
||||
/**
|
||||
* Get all properties of the property container.
|
||||
*
|
||||
* This includes the properties of the parent container.
|
||||
*
|
||||
* @param[out] map A map of property names to properties.
|
||||
*/
|
||||
virtual void getPropertyMap(std::map<std::string,Property*> &map) const;
|
||||
|
||||
/**
|
||||
* Get all properties of the property container.
|
||||
*
|
||||
* This includes the properties of the parent container.
|
||||
*
|
||||
* @param[out] List A vector of properties.
|
||||
*/
|
||||
virtual void getPropertyList(std::vector<Property*> &List) const;
|
||||
/// Call the given visitor for each property. The visiting order is undefined.
|
||||
/// This method is necessary because PropertyContainer has no begin and end methods
|
||||
/// and it is not practical to implement these.
|
||||
/// What gets visited is undefined if the collection of Properties is changed during this call.
|
||||
|
||||
/**
|
||||
* @brief Visit each property in the container.
|
||||
*
|
||||
* This method allows you to apply a function to each property in the
|
||||
* container. The visiting order is undefined. This mehod is necessary
|
||||
* because PropertyContainer has no begin and end methods and it is not
|
||||
* practical to implement these. What gets visited is undefined if the
|
||||
* collection of Properties is changed during this call.
|
||||
*
|
||||
* @param[in] visitor The function to apply to each property.
|
||||
*/
|
||||
virtual void visitProperties(const std::function<void(Property*)>& visitor) const;
|
||||
/// get all properties with their names, may contain duplicates and aliases
|
||||
virtual void getPropertyNamedList(std::vector<std::pair<const char*,Property*> > &List) const;
|
||||
/// set the Status bit of all properties at once
|
||||
|
||||
/**
|
||||
* @brief Get a list of properties with their names.
|
||||
*
|
||||
* The list may contain duplicates and aliases.
|
||||
*
|
||||
* @param[out] List A vector of pairs, where each pair contains the name and
|
||||
* the property.
|
||||
*/
|
||||
virtual void getPropertyNamedList(std::vector<std::pair<const char*,Property*> > &list) const;
|
||||
|
||||
/**
|
||||
* @brief Set a status bit for all properties.
|
||||
*
|
||||
* This method sets a status bit for all properties in the container at once.
|
||||
* The status bits are defined in enum Property::Status.
|
||||
*
|
||||
* @param[in] bit The status bit to set.
|
||||
* @param[in] value The value to set the status bit to.
|
||||
*/
|
||||
void setPropertyStatus(unsigned char bit,bool value);
|
||||
|
||||
/// get the Type of a Property
|
||||
/**
|
||||
* @brief Get the type of a property given a property.
|
||||
*
|
||||
* This method returns the type as a bitmask of the PropertyType enum.
|
||||
*
|
||||
* @param[in] prop The property to get the type for.
|
||||
* @return The type as a bitmask of the PropertyType enum.
|
||||
*/
|
||||
virtual short getPropertyType(const Property* prop) const;
|
||||
/// get the Type of a named Property
|
||||
|
||||
/**
|
||||
* @brief Get the type of a property given a property name.
|
||||
*
|
||||
* This method returns the type as a bitmask of the PropertyType enum.
|
||||
*
|
||||
* @param[in] name The name of the property to get the type for.
|
||||
* @return The type as a bitmask of the PropertyType enum.
|
||||
*/
|
||||
virtual short getPropertyType(const char *name) const;
|
||||
/// get the Group of a Property
|
||||
|
||||
/**
|
||||
* @brief Get the group of a property given a property.
|
||||
*
|
||||
* @param[in] prop The property to get the group for.
|
||||
* @return The group name of the property.
|
||||
*/
|
||||
virtual const char* getPropertyGroup(const Property* prop) const;
|
||||
/// get the Group of a named Property
|
||||
|
||||
/**
|
||||
* @brief Get the group of a property given a property name.
|
||||
*
|
||||
* @param[in] name The name of the property to get the group for.
|
||||
* @return The group name of the property.
|
||||
*/
|
||||
virtual const char* getPropertyGroup(const char *name) const;
|
||||
/// get the Group of a Property
|
||||
|
||||
/**
|
||||
* @brief Get the documentation of a property given a property.
|
||||
*
|
||||
* @param[in] prop The property to get the documentation for.
|
||||
* @return The documentation string of the property.
|
||||
*/
|
||||
virtual const char* getPropertyDocumentation(const Property* prop) const;
|
||||
/// get the Group of a named Property
|
||||
|
||||
/**
|
||||
* @brief Get the documentation of a property given a property name.
|
||||
*
|
||||
* @param[in] name The name of the property to get the documentation for.
|
||||
* @return The documentation string of the property.
|
||||
*/
|
||||
virtual const char* getPropertyDocumentation(const char *name) const;
|
||||
/// check if the property is read-only
|
||||
|
||||
/**
|
||||
* @brief Check if a property is read-only given a property.
|
||||
*
|
||||
* @param[in] prop The property to check.
|
||||
* @return `true` if the property is read-only; `false` otherwise.
|
||||
*/
|
||||
bool isReadOnly(const Property* prop) const;
|
||||
/// check if the named property is read-only
|
||||
|
||||
/**
|
||||
* @brief Check if a property is read-only given a property name.
|
||||
*
|
||||
* @param[in] name The name of the property to check.
|
||||
* @return `true` if the property is read-only; `false` otherwise.
|
||||
*/
|
||||
bool isReadOnly(const char *name) const;
|
||||
/// check if the property is hidden
|
||||
|
||||
/**
|
||||
* @brief Check if a property is hidden given a property.
|
||||
*
|
||||
* @param[in] prop The property to check.
|
||||
* @return `true` if the property is hidden; `false` otherwise.
|
||||
*/
|
||||
bool isHidden(const Property* prop) const;
|
||||
/// check if the named property is hidden
|
||||
|
||||
/**
|
||||
* @brief Check if a property is hidden given a property name.
|
||||
*
|
||||
* @param[in] name The name of the property to check.
|
||||
* @return `true` if the property is hidden; `false` otherwise.
|
||||
*/
|
||||
bool isHidden(const char *name) const;
|
||||
|
||||
/**
|
||||
* Add a property at runtime.
|
||||
*
|
||||
* Dynamic properties are properties that are not defined at compile-time
|
||||
* but can be added and removed during the lifetime of the object.
|
||||
*
|
||||
* @param[in] type The type name of the property (e.g., "App::PropertyFloat").
|
||||
* @param[in] name Optional name of the property. If null, a default name may be generated.
|
||||
* @param[in] group Optional group name to which the property belongs
|
||||
* (used for UI or logical grouping).
|
||||
* @param[in] doc Optional documentation string describing the purpose of the property.
|
||||
* @param[in] attr Bitmask of property attributes, composed of values from the
|
||||
* PropertyType enum.
|
||||
* @param[in] ro If true, the property is marked as read-only.
|
||||
* @param[in] hidden If true, the property is hidden from the user interface.
|
||||
* @return A pointer to the newly added Property.
|
||||
* @throws Exception A runtime exception is thrown if the property cannot be added, such
|
||||
* as when the name is invalid.
|
||||
*/
|
||||
virtual App::Property* addDynamicProperty(
|
||||
const char* type, const char* name=nullptr,
|
||||
const char* group=nullptr, const char* doc=nullptr,
|
||||
short attr=0, bool ro=false, bool hidden=false);
|
||||
|
||||
/**
|
||||
* @brief Get the data of a dynamic property.
|
||||
*
|
||||
* This function retrieves the data associated with a dynamic property.
|
||||
*
|
||||
* @param[in] prop The property to get the data for.
|
||||
* @returns The data of the dynamic property.
|
||||
*/
|
||||
DynamicProperty::PropData getDynamicPropertyData(const Property* prop) const {
|
||||
return dynamicProps.getDynamicPropertyData(prop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the group and documentation of a dynamic property.
|
||||
*
|
||||
* @param[in] prop The property to change.
|
||||
* @param[in] group The new group name for organizational purposes, (e.g., in UI panels).
|
||||
* @param[in] doc The new documentation string for this property.
|
||||
* @return `true` if the update was successful; `false` otherwise.
|
||||
*/
|
||||
bool changeDynamicProperty(const Property *prop, const char *group, const char *doc) {
|
||||
return dynamicProps.changeDynamicProperty(prop,group,doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a dynamic property.
|
||||
*
|
||||
* @param[in] name The name of the property to remove.
|
||||
* @return `true` if the property was removed; `false` otherwise.
|
||||
*/
|
||||
virtual bool removeDynamicProperty(const char* name) {
|
||||
return dynamicProps.removeDynamicProperty(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the names of all dynamic properties.
|
||||
*
|
||||
* @returns A vector of strings containing the names of all dynamic properties.
|
||||
*/
|
||||
virtual std::vector<std::string> getDynamicPropertyNames() const {
|
||||
return dynamicProps.getDynamicPropertyNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a dynamic property.
|
||||
*
|
||||
* @param[in] name The name of the property.
|
||||
* @returns The property if found or `nullptr` when not found.
|
||||
*/
|
||||
virtual App::Property *getDynamicPropertyByName(const char* name) const {
|
||||
return dynamicProps.getDynamicPropertyByName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called when the status of a property is changed.
|
||||
*
|
||||
* This method is called when the status of a property changes. It can be
|
||||
* overridden by subclasses to implement custom behavior when a property
|
||||
* status changes.
|
||||
*
|
||||
* @param[in] prop The property whose status has changed.
|
||||
* @param[in] oldStatus The old status of the property as a bitmask of enum
|
||||
* Property::Status.
|
||||
*/
|
||||
virtual void onPropertyStatusChanged(const Property &prop, unsigned long oldStatus);
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
|
||||
/**
|
||||
* @brief Prepare the properties for saving.
|
||||
*
|
||||
* All non-transient properties are prepared to be saved.
|
||||
*
|
||||
* @see Property::beforeSave()
|
||||
*/
|
||||
virtual void beforeSave() const;
|
||||
|
||||
virtual void editProperty(const char * /*propName*/) {}
|
||||
/**
|
||||
* @brief Called when a property is edited by the user.
|
||||
*
|
||||
* Subclasses can override this method to implement custom behavior for
|
||||
* editing specific properties.
|
||||
*
|
||||
* @param[in] propName The name of the property to be edited.
|
||||
*/
|
||||
virtual void editProperty([[maybe_unused]] const char* propName) {}
|
||||
|
||||
/**
|
||||
* @brief Get the prefix for property names.
|
||||
*
|
||||
* @return The prefix for property names.
|
||||
*/
|
||||
const char *getPropertyPrefix() const {
|
||||
return _propertyPrefix.c_str();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the prefix for property names.
|
||||
*
|
||||
* @param[in] prefix The new prefix for property names.
|
||||
*/
|
||||
void setPropertyPrefix(const char *prefix) {
|
||||
_propertyPrefix = prefix;
|
||||
}
|
||||
@@ -254,29 +486,113 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
/** get called by the container when a property has changed
|
||||
/**
|
||||
* @brief Called when a property is about to change.
|
||||
*
|
||||
* This function is called before onChanged()
|
||||
* This method can be overridden by subclasses to implement custom behavior
|
||||
* when a property is about to change. This method is called in
|
||||
* Property::touch() right before onChanged() is called, typically in the
|
||||
* DocumentObject::execute() phase.
|
||||
*
|
||||
* @note This can be considered a low-level callback and is not widely
|
||||
* overridden. For preparing for a property change, use onBeforeChange().
|
||||
*
|
||||
* @param[in] prop The property that is about to change.
|
||||
* @see Property::onBeforeChange()
|
||||
*/
|
||||
virtual void onEarlyChange(const Property* /*prop*/){}
|
||||
/// get called by the container when a property has changed
|
||||
virtual void onChanged(const Property* /*prop*/){}
|
||||
/// get called before the value is changed
|
||||
virtual void onBeforeChange(const Property* /*prop*/){}
|
||||
virtual void onEarlyChange([[maybe_unused]] const Property* prop){}
|
||||
|
||||
//void hasChanged(Property* prop);
|
||||
static const PropertyData * getPropertyDataPtr();
|
||||
/**
|
||||
* @brief Called when a property has changed.
|
||||
*
|
||||
* This method can be overridden by subclasses to implement custom behavior
|
||||
* when a property has changed.
|
||||
*
|
||||
* @param[in] prop The property that has changed.
|
||||
*/
|
||||
virtual void onChanged([[maybe_unused]] const Property* prop){}
|
||||
|
||||
/**
|
||||
* @brief Called before a property is changed.
|
||||
*
|
||||
* This method can be overridden by subclasses to implement custom behavior
|
||||
* before a property has changed. It allows property containers to prepare
|
||||
* for a property change.
|
||||
*
|
||||
* @param[in] prop The property that is about to change.
|
||||
*/
|
||||
virtual void onBeforeChange([[maybe_unused]] const Property* prop){}
|
||||
|
||||
/**
|
||||
* @brief Get a pointer to the class-wide static property data.
|
||||
*
|
||||
* This method gives access to the class-wide static PropertyData shared by
|
||||
* all instances of the class. The macros `PROPERTY_HEADER` and
|
||||
* `PROPERTY_SOURCE` variants ensure that each subclass of %PropertyContainer
|
||||
* has its own static PropertyData instance, and that this method returns the
|
||||
* instance for that subclass.
|
||||
*
|
||||
* @returns A pointer to the static `PropertyData`.
|
||||
*/
|
||||
static const PropertyData* getPropertyDataPtr();
|
||||
|
||||
/**
|
||||
* @brief Get a reference to the static property data for the dynamic type of this instance.
|
||||
*
|
||||
* This virtual method allows retrieval of the class-level static
|
||||
* PropertyData associated with the actual (dynamic) type of the object, even
|
||||
* when accessed via a base class pointer. The `PROPERTY_HEADER` and
|
||||
* `PROPERTY_SOURCE` macros ensure that each subclass defines its own static
|
||||
* PropertyData instance, and that this method correctly dispatches to return
|
||||
* it.
|
||||
*
|
||||
* @return A reference to the static `PropertyData` corresponding to the dynamic type.
|
||||
*/
|
||||
virtual const PropertyData& getPropertyData() const;
|
||||
|
||||
virtual void handleChangedPropertyName(Base::XMLReader &reader, const char * TypeName, const char *PropName);
|
||||
virtual void handleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, Property * prop);
|
||||
/**
|
||||
* @brief Handle a changed property name during restore.
|
||||
*
|
||||
* This method is called during restore to possibly fix reading of older
|
||||
* versions of this property container. This method is typically called if
|
||||
* the property on file has changed its name in more recent versions.
|
||||
*
|
||||
* The default implementation does nothing.
|
||||
*
|
||||
* @param[in,out] reader The XML stream to read from.
|
||||
* @param[in] typeName The name of the property type in the file.
|
||||
* @param[in] propName The name of the property in the file that does no
|
||||
* longer exist in the container.
|
||||
*/
|
||||
virtual void handleChangedPropertyName(Base::XMLReader& reader, const char* typeName, const char* propName);
|
||||
|
||||
/**
|
||||
* @brief Handle a changed property type during restore.
|
||||
*
|
||||
* This method is called during restore to possibly fix reading of older
|
||||
* versions of this property container. This method is typically called if
|
||||
* the property on file has changed its type in more recent versions.
|
||||
*
|
||||
* The default implementation does nothing.
|
||||
*
|
||||
* @param[in,out] reader The XML stream to read from.
|
||||
* @param[in] typeName The name of the property type in the file.
|
||||
* @param[in, out] prop The property that needs to be restored. Its type differs from `typeName`.
|
||||
*/
|
||||
virtual void handleChangedPropertyType(Base::XMLReader &reader, const char * typeName, Property * prop);
|
||||
|
||||
public:
|
||||
// forbidden
|
||||
|
||||
/// @brief The copy constructor is deleted to prevent copying.
|
||||
PropertyContainer(const PropertyContainer&) = delete;
|
||||
|
||||
/// @brief The assignment operator is deleted to prevent assignment.
|
||||
PropertyContainer& operator = (const PropertyContainer&) = delete;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief The container for dynamic properties.
|
||||
*/
|
||||
DynamicProperty dynamicProps;
|
||||
|
||||
private:
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
* @ref DocumentGroup "Document", @ref DocumentObjectGroup "Document Object",
|
||||
* the @ref ExpressionFramework "Expression Framework", and the @ref
|
||||
* PropertyFramework "Property Framework".
|
||||
*
|
||||
* The largest difference between the functionality in @ref BASE "Base"
|
||||
* compared to %App is that %App introduces the notion of properties, both used
|
||||
* in @ref App::Document "Document" and @ref App::DocumentObject
|
||||
* "DocumentObject". In addition, %App has a representation of the running
|
||||
* @ref App::Application "Application".
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -58,11 +64,46 @@
|
||||
*
|
||||
* The property framework introduces the ability to access attributes (member
|
||||
* variables) of a class by name without knowing the class type. It's like the
|
||||
* reflection mechanism of Java or C#. This ability is introduced by the
|
||||
* App::PropertyContainer class and can be used by all derived classes.
|
||||
* reflection mechanism of Java or C#. This ability is introduced by the @ref
|
||||
* App::PropertyContainer "PropertyContainer" class and can be used by all
|
||||
* derived classes. In particular, there are two classes that inherit from
|
||||
* @ref App::PropertyContainer "PropertyContainer" which are @ref App::Document
|
||||
* "Document" and @ref App::DocumentObject "DocumentObject". These two classes
|
||||
* serve different purposes but are both able to hold properties. @ref
|
||||
* App::PropertyContainer "PropertyContainer" contains the shared logic to do
|
||||
* so.
|
||||
*
|
||||
* This makes it possible in the first place to make an automatic mapping to python (e.g. in App::FeaturePy) and
|
||||
* abstract editing properties in Gui::PropertyEditor.
|
||||
* In C++, it is possible to define properties as part of the class. These can
|
||||
* be considered "static" properties but this term is typically not used within
|
||||
* FreeCAD. Properties created in a class cannot be removed from a @ref
|
||||
* App::PropertyContainer "PropertyContainer".
|
||||
*
|
||||
* However, it is also possible to add properties to a @ref
|
||||
* App::PropertyContainer "PropertyContainer" at runtime. These properties are
|
||||
* called "dynamic properties" and these properties can be freely added and
|
||||
* removed by users.
|
||||
*
|
||||
* In Python, all properties are dynamic properties. This makes it difficult
|
||||
* to understand whether properties are part of a Python class and are
|
||||
* necessary for the functioning of the class, or whether a user has added
|
||||
* these properties. Therefore, it is possible to indicate that a property is
|
||||
* "locked":
|
||||
*
|
||||
* @code
|
||||
* prop->setStatus(Property::LockDynamic, true);
|
||||
* @endcode
|
||||
*
|
||||
* In Python, this can be indicated in the `addProperty()` function:
|
||||
*
|
||||
* @code
|
||||
* addProperty(type: string, name: string, group="", doc="",
|
||||
* attr=0, read_only=False, hidden=False,
|
||||
* locked=False, enum_vals=[])
|
||||
* @endcode
|
||||
*
|
||||
* The Property Framework makes it possible in the first place to make an
|
||||
* automatic mapping to python (e.g. in App::FeaturePy) and abstract editing
|
||||
* properties in Gui::PropertyEditor.
|
||||
*
|
||||
* @section Examples
|
||||
*
|
||||
|
||||
@@ -39,11 +39,14 @@ class BaseExport Persistence: public BaseClass
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
/** This method is used to get the size of objects
|
||||
* It is not meant to have the exact size, it is more or less an estimation
|
||||
* which runs fast! Is it two bytes or a GB?
|
||||
/**
|
||||
* @brief Get the size of objects.
|
||||
*
|
||||
* It is not meant to have the exact size, it is more or less a fast
|
||||
* estimation to tell whether it is two bytes or a GB.
|
||||
*/
|
||||
virtual unsigned int getMemSize() const = 0;
|
||||
|
||||
/** This method is used to save properties to an XML document.
|
||||
* A good example you'll find in PropertyStandard.cpp, e.g. the vector:
|
||||
* \code
|
||||
|
||||
Reference in New Issue
Block a user