Merge pull request #25197 from pieterhijma/doc-link

Doc: Improve the documentation of Link
This commit is contained in:
Chris Hennes
2026-01-31 19:52:19 +01:00
committed by GitHub
4 changed files with 518 additions and 131 deletions

View File

@@ -61,104 +61,85 @@ import LinkParams
LinkParams.define()
]]]*/
namespace
{
// Auto generated code. See class document of LinkParams.
class LinkParamsP: public ParameterGrp::ObserverType
{
// Auto generated code (App/params_utils.py:209)
namespace {
class LinkParamsP: public ParameterGrp::ObserverType {
public:
// Auto generated code. See class document of LinkParams.
ParameterGrp::handle handle;
std::unordered_map<const char *,void(*)(LinkParamsP*),App::CStringHasher,App::CStringHasher> funcs;
// Auto generated code. See class document of LinkParams.
std::unordered_map<const char*, void (*)(LinkParamsP*), App::CStringHasher, App::CStringHasher>
funcs;
bool CopyOnChangeApplyToAll;
bool CopyOnChangeApplyToAll; // Auto generated code. See class document of LinkParams.
// Auto generated code. See class document of LinkParams.
LinkParamsP()
{
handle = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Link");
// Auto generated code (App/params_utils.py:247)
LinkParamsP() {
handle = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Link");
handle->Attach(this);
CopyOnChangeApplyToAll = handle->GetBool("CopyOnChangeApplyToAll", true);
funcs["CopyOnChangeApplyToAll"] = &LinkParamsP::updateCopyOnChangeApplyToAll;
}
// Auto generated code. See class document of LinkParams.
~LinkParamsP() override = default;
// Auto generated code (App/params_utils.py:265)
~LinkParamsP() {
}
// Auto generated code. See class document of LinkParams.
void OnChange(Base::Subject<const char*>&, const char* sReason) override
{
if (!sReason) {
// Auto generated code (App/params_utils.py:272)
void OnChange(Base::Subject<const char*> &, const char* sReason) {
if(!sReason)
return;
}
auto it = funcs.find(sReason);
if (it == funcs.end()) {
if(it == funcs.end())
return;
}
it->second(this);
}
// Auto generated code. See class document of LinkParams.
static void updateCopyOnChangeApplyToAll(LinkParamsP* self)
{
// Auto generated code (App/params_utils.py:290)
static void updateCopyOnChangeApplyToAll(LinkParamsP *self) {
self->CopyOnChangeApplyToAll = self->handle->GetBool("CopyOnChangeApplyToAll", true);
}
};
// Auto generated code. See class document of LinkParams.
LinkParamsP* instance()
{
static LinkParamsP* inst = new LinkParamsP;
// Auto generated code (App/params_utils.py:312)
LinkParamsP *instance() {
static LinkParamsP *inst = new LinkParamsP;
return inst;
}
} // Anonymous namespace
} // Anonymous namespace
// Auto generated code. See class document of LinkParams.
ParameterGrp::handle LinkParams::getHandle()
{
// Auto generated code (App/params_utils.py:323)
ParameterGrp::handle LinkParams::getHandle() {
return instance()->handle;
}
// Auto generated code. See class document of LinkParams.
const char* LinkParams::docCopyOnChangeApplyToAll()
{
return QT_TRANSLATE_NOOP(
"LinkParams",
"Stores the last user choice of whether to apply CopyOnChange setup to all links\n"
"that reference the same configurable object");
// Auto generated code (App/params_utils.py:352)
const char *LinkParams::docCopyOnChangeApplyToAll() {
return QT_TRANSLATE_NOOP("LinkParams",
"Stores the last user choice of whether to apply CopyOnChange setup to all link\n"
"that links to the same configurable object");
}
// Auto generated code. See class document of LinkParams.
const bool& LinkParams::getCopyOnChangeApplyToAll()
{
// Auto generated code (App/params_utils.py:360)
const bool & LinkParams::getCopyOnChangeApplyToAll() {
return instance()->CopyOnChangeApplyToAll;
}
// Auto generated code. See class document of LinkParams.
const bool& LinkParams::defaultCopyOnChangeApplyToAll()
{
static const bool def = true;
// Auto generated code (App/params_utils.py:368)
const bool & LinkParams::defaultCopyOnChangeApplyToAll() {
const static bool def = true;
return def;
}
// Auto generated code. See class document of LinkParams.
void LinkParams::setCopyOnChangeApplyToAll(const bool& v)
{
instance()->handle->SetBool("CopyOnChangeApplyToAll", v);
// Auto generated code (App/params_utils.py:377)
void LinkParams::setCopyOnChangeApplyToAll(const bool &v) {
instance()->handle->SetBool("CopyOnChangeApplyToAll",v);
instance()->CopyOnChangeApplyToAll = v;
}
// Auto generated code. See class document of LinkParams.
void LinkParams::removeCopyOnChangeApplyToAll()
{
// Auto generated code (App/params_utils.py:386)
void LinkParams::removeCopyOnChangeApplyToAll() {
instance()->handle->RemoveBool("CopyOnChangeApplyToAll");
}
//[[[end]]]

View File

@@ -51,6 +51,13 @@
namespace App
{
/**
* @brief The base class of the link extension.
* @ingroup LinksGroup
*
* The functionality in this class is reused in LinkExtension, LinkElement, and
* LinkGroup.
*/
class AppExport LinkBaseExtension: public App::DocumentObjectExtension
{
EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(App::LinkExtension);
@@ -60,25 +67,31 @@ public:
LinkBaseExtension();
~LinkBaseExtension() override = default;
/// Whether the link has been touched (i.e. its linked object changed)
PropertyBool _LinkTouched;
/// Contains the object ID of the object that owns the link.
PropertyInteger _LinkOwner;
/// Cache of children of the link group.
PropertyLinkList _ChildCache; // cache for plain group expansion
/// Options for the link mode.
enum
{
LinkModeNone,
LinkModeAutoDelete,
LinkModeAutoLink,
LinkModeAutoUnlink,
LinkModeNone, ///< No mode for the link.
LinkModeAutoDelete, ///< Delete the linked object when the link is deleted.
LinkModeAutoLink, ///< Create link elements of sub-element automatically (unused).
LinkModeAutoUnlink, ///< Unused option.
};
/** \name Parameter definition
/**
* @name Parameter definition.
* @brief Parameter definition (Name, Type, Property Type, Default, Document).
*
* Parameter definition (Name, Type, Property Type, Default, Document).
* The variadic is here so that the parameter can be extended by adding
* extra fields. See LINK_PARAM_EXT() for an example
* extra fields. See LINK_PARAM_EXT() for an example.
*
* @{
*/
//@{
#define LINK_PARAM_LINK_PLACEMENT(...) \
(LinkPlacement, \
@@ -229,7 +242,7 @@ public:
#define LINK_PDOC(_param) BOOST_PP_TUPLE_ELEM(4, _param)
#define LINK_PINDEX(_param) BOOST_PP_CAT(Prop, LINK_PNAME(_param))
//@}
/// @}
#define LINK_PARAMS \
LINK_PARAM(PLACEMENT) \
@@ -253,6 +266,7 @@ public:
LINK_PARAM(COPY_ON_CHANGE_GROUP) \
LINK_PARAM(COPY_ON_CHANGE_TOUCHED)
/// The property indices.
enum PropIndex
{
#define LINK_PINDEX_DEFINE(_1, _2, _param) LINK_PINDEX(_param),
@@ -261,17 +275,49 @@ public:
BOOST_PP_SEQ_FOR_EACH(LINK_PINDEX_DEFINE, _, LINK_PARAMS) PropMax
};
/**
* @brief Set a property to a given index..
*
* @param[in] idx The property index obtained from the PropIndex enum.
* @param[in] prop The property to set.
*/
virtual void setProperty(int idx, Property* prop);
/**
* @brief Get a property by its index.
*
* @param[in] idx The property index obtained from the PropIndex enum.
*
* @return The property at the given index, or nullptr if the index is out
* of range or the property is not set.
*/
Property* getProperty(int idx);
/**
*
* @brief Get a property by its name.
*
* @param[in] name The name of the property to get.
* @return The property with the given name, or nullptr if not found.
*/
Property* getProperty(const char*);
/// Information about a link property.
struct PropInfo
{
int index;
const char* name;
Base::Type type;
const char* doc;
int index; ///< The property index obtained from the PropIndex enum.
const char* name; ///< The name of the property.
Base::Type type; ///< The type of the property.
const char* doc; ///< The documentation string of the property.
/**
* @brief Construct a property info.
*
* @param[in] index The property index obtained from the PropIndex enum.
* @param[in] name The name of the property.
* @param[in] type The type of the property.
* @param[in] doc The documentation string of the property.
*/
PropInfo(int index, const char* name, Base::Type type, const char* doc)
: index(index)
, name(name)
@@ -292,17 +338,22 @@ public:
LINK_PPTYPE(_param)::getClassTypeId(), \
LINK_PDOC(_param)));
/// Get the property info of this link.
virtual const std::vector<PropInfo>& getPropertyInfo() const;
/// A mapping from property name to its info.
using PropInfoMap = std::map<std::string, PropInfo>;
/// Get the property info map of this link.
virtual const PropInfoMap& getPropertyInfoMap() const;
/// The types for copy on change links.
enum LinkCopyOnChangeType
{
CopyOnChangeDisabled = 0,
CopyOnChangeEnabled = 1,
CopyOnChangeOwned = 2,
CopyOnChangeTracking = 3
CopyOnChangeDisabled = 0, ///< No copy on change behavior.
CopyOnChangeEnabled = 1, ///< Copy on change is enabled but not necessarily in effect.
CopyOnChangeOwned = 2, ///< Copy on change is enabled and in effect.
CopyOnChangeTracking = 3 ///< Tracking copy-on-change behavior.
};
#define LINK_PROP_GET(_1, _2, _param) \
@@ -327,18 +378,52 @@ public:
// defines get##Name##Property() and get##Name##Value() accessor
BOOST_PP_SEQ_FOR_EACH(LINK_PROP_GET, _, LINK_PARAMS)
/// Get the element list of this link.
PropertyLinkList* _getElementListProperty() const;
/// Get the element value list of this link.
const std::vector<App::DocumentObject*>& _getElementListValue() const;
/// Get the show element property.
PropertyBool* _getShowElementProperty() const;
/// Get the show element value.
bool _getShowElementValue() const;
/// Get the element count property.
PropertyInteger* _getElementCountProperty() const;
/// Get the element count value.
int _getElementCountValue() const;
/**
* @brief Get the linked children of this link.
*
* @param[in] filter If true, it will filter out objects that are a group.
*
* @return A vector of linked children.
*/
std::vector<DocumentObject*> getLinkedChildren(bool filter = true) const;
/**
* @brief Get a flattened subname.
*
* Get a flattened subname in case it references an object inside a linked
* plain group.
*
* @param[in] subname The subname to flatten.
* @return Returns the flattened subname.
*/
const char* flattenSubname(const char* subname) const;
/**
* @brief Expand the subname.
*
* Expand the subname in case it references an object inside a linked plain
* group.
*
* @param[in,out] subname The subname to expand. It will be modified in place.
*/
void expandSubname(std::string& subname) const;
/**
@@ -354,19 +439,34 @@ public:
*/
DocumentObject* getLink(int depth = 0) const;
/**
* @brief Get the transformation matrix of the link.
*
* @param[in] transform If true, it will take into account the placement of
* the link or the original object, if false, it will only provide the
* scaling.
*
* @return The transformation matrix of the link.
*/
Base::Matrix4D getTransform(bool transform) const;
/// Get the scale vector of the link.
Base::Vector3d getScaleVector() const;
/// Get the linked plain group if the linked object is a plain group.
App::GroupExtension* linkedPlainGroup() const;
/// Whether to transform the link together with the linked object.
bool linkTransform() const;
/// Get the subname of the link.
const char* getSubName() const
{
parseSubName();
return !mySubName.empty() ? mySubName.c_str() : nullptr;
}
/// Get the sub-elements of the link.
const std::vector<std::string>& getSubElements() const
{
parseSubName();
@@ -402,13 +502,56 @@ public:
Property* extensionGetPropertyByName(const char* name) const override;
/**
* @brief Get the array index from a subname.
*
* @param[in] subname The subname to get the array index from.
* @param[in,out] psubname If not null, it will point to the position
* in the subname after the array index.
*
* @return The array index, or -1 if there is no array index.
*/
static int getArrayIndex(const char* subname, const char** psubname = nullptr);
/**
* @brief Get the element index from a subname.
*
* This method will acquire the element index from a subname using various
* strategies.
*
* @param[in] subname The subname to get the element index from.
* @param[in,out] psubname If not null, it will point to the position
* in the subname after the element index.
*
* @return The element index, or -1 if there is no element index.
*/
int getElementIndex(const char* subname, const char** psubname = nullptr) const;
/**
*
* @brief Get the element name from an index.
*
* This method will return the element name corresponding to the given
* index.
*
* @param[in] idx The index of the element.
* @param[out] ss The output stream to write the element name to.
*/
void elementNameFromIndex(int idx, std::ostream& ss) const;
/// Get the container object of this link.
DocumentObject* getContainer();
/// Get the container object of this link (const version).
const DocumentObject* getContainer() const;
/**
* @brief Set the linked object.
*
* @param[in] index The index of the link property to set.
* @param[in] obj The object to link to.
* @param[in] subname The subname to link to.
* @param[in] subs The sub-elements to link to.
*/
void setLink(int index,
DocumentObject* obj,
const char* subname = nullptr,
@@ -424,17 +567,13 @@ public:
*
* @param recurse If true, it will recursively resolve the link until it reaches
* the final linked object, or until it reaches the maximum recursion depth.
*
* @param mat If non-null, it is used as the current transformation matrix on
* input. On output it is used as the accumulated transformation up until
* the final linked object.
*
* @param depth This parameter indicates the level on which we are
* resolving the link.
*
* @param noElement If true, it will not return the linked object if it is
* a link to an element.
*
* @return Returns the true linked object. If the linked object is not found
* or is invalid, it returns @c nullptr.
*
@@ -446,52 +585,109 @@ public:
int depth = 0,
bool noElement = false) const;
using LinkPropMap = std::map<const Property*, std::pair<LinkBaseExtension*, int>>;
/// Check whether the link has a placement property.
bool hasPlacement() const
{
return getLinkPlacementProperty() || getPlacementProperty();
}
/**
* @brief Enable the cache for child labels.
*
* @param[in] enable If -1, it will enable the cache and only clear it. If
* 0, it will clear the cache and disableit. If 1, it will enable the cache and fill it
* with the current child elements.
*/
void cacheChildLabel(int enable = -1) const;
/**
* @brief Setup copy on change behavior.
*
* This static method sets up the copy on change behavior for a given object.
*
* @param[in] obj The object to set up copy on change for.
* @param[in] linked The linked object to copy from.
* @param[in,out] copyOnChangeConns The vector to store the connections for copy on change.
* @param[in] checkExisting If true, it will check the links properties
* against the properties of the linked object.
*
* @return True if the setup was successful, false otherwise.
*/
static bool
setupCopyOnChange(App::DocumentObject* obj,
App::DocumentObject* linked,
std::vector<fastsignals::scoped_connection>* copyOnChangeConns,
bool checkExisting);
/**
* @brief Check if a property is marked as copy on change.
*
* @param[in] obj The object to check the property on.
* @param[in] prop The property to check.
* @return True if the property is marked as copy on change, false otherwise.
*/
static bool isCopyOnChangeProperty(App::DocumentObject* obj, const Property& prop);
/**
* @brief Synchronize the copy on change object with the source object.
*
* This means updating the mutated copy in the copy-on-change group.
*/
void syncCopyOnChange();
/** Options used in setOnChangeCopyObject()
* Multiple options can be combined by bitwise or operator
/**
* @brief Options used in setOnChangeCopyObject()
*
* Multiple options can be combined by bitwise or operator.
*/
enum class OnChangeCopyOptions
{
/// No options set
None = 0,
/// If set, then exclude the input from object list to copy on change, or else, include the
/// input object.
Exclude = 1,
/// If set , then apply the setting to all links to the input object, or else, apply only to
/// this link.
ApplyAll = 2,
None = 0, ///< No options set
Exclude = 1, ///< Exclude an object to be copied when the configuration changes.
ApplyAll = 2, ///< Apply the configuration to all links.
};
/** Include or exclude object from list of objects to copy on change
* @param obj: input object
* @param options: control options. @sa OnChangeCopyOptions.
/**
* @brief Include or exclude an object from the list of objects to copy on change.
*
* @param[in] obj: The object to include or exclude.
* @param[in] options: control options of type OnChangeCopyOptions.
*/
void setOnChangeCopyObject(App::DocumentObject* obj, OnChangeCopyOptions options);
/**
* @brief Get the list of objects that are set to be copied on change.
*
* @param[out] excludes: If not null, it will contain the objects that are
* excluded from copy-on-change.
* @param[in] src: The source of the copy on change link. If `nullptr`, it
* will use the `LinkCopyOnChangeSource` property to determine the source
* or if not a copy-on-change link, the linked object.
*
* @return Objects that depend on the source of the copy-on-change link.
*/
std::vector<App::DocumentObject*>
getOnChangeCopyObjects(std::vector<App::DocumentObject*>* excludes = nullptr,
App::DocumentObject* src = nullptr);
/**
* @brief Check whether this link is configurable one.
*
* This essentially means that the linked object has copy-on-change properties.
*
* @return True if the link is configurable, false otherwise.
*/
bool isLinkedToConfigurableObject() const;
/**
* @brief Monitor changes on the list of copy-on-change objects.
*
* This function has as input the list of dependencies of original
* dependencies of the copy-on-change link. It sets up connections to
* monitor these original objects, to update the copy-on-change links.
*
* @param[in] objs The list of objects to monitor.
*/
void monitorOnChangeCopyObjects(const std::vector<App::DocumentObject*>& objs);
/// Check if the linked object is a copy on change
@@ -500,43 +696,140 @@ public:
protected:
void
_handleChangedPropertyName(Base::XMLReader& reader, const char* TypeName, const char* PropName);
/// Parse the subname into mySubName and mySubElements
void parseSubName() const;
/**
* @brief Update the link when a property changes.
*
* It fullfills a role similar to DocumentObject::onChanged().
*
* @param[in] parent The parent document object.
* @param[in] prop The property that changed.
*/
void update(App::DocumentObject* parent, const Property* prop);
/**
* @brief Check a property in case of copy-on-change.
*
* If a copy is a copy-on-change property in the parent, copy the property
* from the source to the link (in the copy-on-change group).
*
* @param[in] parent The parent document object.
* @param[in] prop The property to check.
*/
void checkCopyOnChange(App::DocumentObject* parent, const App::Property& prop);
/**
* @brief Setup copy-on-change behavior for this link.
*
* Transform a regular link into a copy-on-change link. This means that
* the linked object is copied in the copy-on-change group and that the
* linked object will point to this copy, while the copy-on-change source
* will point to the original.
*
* @param[in] parent The parent document object.
* @param[in] checkSource If true, it will check the and set the
* copy-on-change source property.
*/
void setupCopyOnChange(App::DocumentObject* parent, bool checkSource = false);
/**
* @brief Make a copy-of-change link from this link.
*
* This function retrieves the dependencies from the linked object and
* copies them. It will put these copies into the copy-on-change group and
* the linked object will be the root of these list of dependencies, making
* it equivalent to the original linked object.
*
* @return The new copy-on-change link object.
*/
App::DocumentObject* makeCopyOnChange();
/// Sync the link elements in this link.
void syncElementList();
/**
* @brief Detach a linked element.
*
* Depending on earlier set options, the object may be deleted.
*
* @param[in] obj The object to detach.
*/
void detachElement(App::DocumentObject* obj);
/// Detach all linked elements.
void detachElements();
/**
* @brief Check the geo element map for a linked object.
*
* This method checks if subnames are in accordance with the geo element
* map.
*
* @param[in] obj The document object containing the link.
* @param[in] linked The linked document object.
* @param[in] pyObj The Python object corresponding to the linked object.
* @param[in] postfix The postfix that should be taken into account regarding subelements.
*/
void checkGeoElementMap(const App::DocumentObject* obj,
const App::DocumentObject* linked,
PyObject** pyObj,
const char* postfix) const;
/// Update the connections for a group of link elements.
void updateGroup();
void slotChangedPlainGroup(const App::DocumentObject&, const App::Property&);
/**
* @brief Slot called when a plain group changes.
*
* @param[in] obj The document object that changed.
* @param[in] prop The property that changed.
*/
void slotChangedPlainGroup(const App::DocumentObject& obj, const App::Property& prop);
protected:
/// The properties for the link.
std::vector<Property*> props;
/// A set of elements to hide.
std::unordered_set<const App::DocumentObject*> myHiddenElements;
/// Cached subelements.
mutable std::vector<std::string> mySubElements;
/// Cached subname.
mutable std::string mySubName;
/// Connections to monitor plain group changes.
std::unordered_map<const App::DocumentObject*, fastsignals::scoped_connection>
plainGroupConns;
long prevLinkedObjectID = 0;
mutable std::unordered_map<std::string, int> myLabelCache; // for label based subname lookup
/// Cache for label based subname lookup.
mutable std::unordered_map<std::string, int> myLabelCache;
/// Whether the label cache is enabled.
mutable bool enableLabelCache {false};
/// Whether the link has old style subelement.
bool hasOldSubElement {false};
/// Connections for copy on change behavior.
std::vector<fastsignals::scoped_connection> copyOnChangeConns;
/// Connections for the source objects for copy on change.
std::vector<fastsignals::scoped_connection> copyOnChangeSrcConns;
/// Whether the link has copy on change behavior.
bool hasCopyOnChange {true};
/// Whether we are checking properties to avoid recursion.
mutable bool checkingProperty = false;
/// Whether to pause copy on change updates.
bool pauseCopyOnChange = false;
/// Connection for monitoring changes on the copy on change source.
fastsignals::scoped_connection connCopyOnChangeSource;
};
@@ -546,6 +839,14 @@ using LinkBaseExtensionPython = ExtensionPythonT<LinkBaseExtension>;
///////////////////////////////////////////////////////////////////////////
/**
* @brief The link extension class.
* @ingroup LinksGroup
*
* This class implements the link extension functionality and is the extension
* that makes @ref App::Link "Link" a link.
*/
class AppExport LinkExtension: public LinkBaseExtension
{
EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(App::LinkExtension);
@@ -555,20 +856,23 @@ public:
LinkExtension();
~LinkExtension() override = default;
/** \name Helpers for defining extended parameter
/**
* @name Helpers for defining extended properties.
* @brief Macros that help define properties that extend the properties of the linked object.
*
* extended parameter definition
* (Name, Type, Property_Type, Default, Document, Property_Name,
* Derived_Property_Type, App_Property_Type, Group)
* Extended property definition:
* `(Name, Type, Property_Type, Default, %Document, Property_Name,
* Derived_Property_Type, App_Property_Type, Group)`
*
* This helper simply reuses Name as Property_Name, Property_Type as
* Derived_Property_type, Prop_None as App_Propert_Type
* This helper simply reuses `Name` as `Property_Name`, `Property_Type` as
* `Derived_Property_type`, `Prop_None` as `App_Propert_Type`.
*
* Note: Because PropertyView will merge linked object's properties into
* @note
* Because PropertyView will merge linked object's properties into
* ours, we set the default group name as ' Link' with a leading space to
* try to make our group before others
* {@
*/
//@{
#define LINK_ENAME(_param) BOOST_PP_TUPLE_ELEM(5, _param)
#define LINK_ETYPE(_param) BOOST_PP_TUPLE_ELEM(6, _param)
@@ -659,6 +963,14 @@ using LinkExtensionPython = ExtensionPythonT<LinkExtension>;
///////////////////////////////////////////////////////////////////////////
/**
* @brief The %Link class.
* @ingroup LinksGroup
*
* Instances of this class represent links to other objects in the document or
* even to objects in other documents.
*/
class AppExport Link: public App::DocumentObject, public App::LinkExtension
{
PROPERTY_HEADER_WITH_EXTENSIONS(App::Link);
@@ -715,6 +1027,17 @@ using LinkPython = App::FeaturePythonT<Link>;
///////////////////////////////////////////////////////////////////////////
/**
* @brief A class that represents an element of a link.
* @ingroup LinksGroup
*
* A link with an element count greater than 0 will contain multiple links to
* the linked object, all with their own placement, scale, and visibility.
* These links are instances of this class. The link itself becomes a special
* link pointing to the same linked object, but its element list will contain
* references to the element links.
*/
class AppExport LinkElement: public App::DocumentObject, public App::LinkBaseExtension
{
PROPERTY_HEADER_WITH_EXTENSIONS(App::LinkElement);
@@ -733,10 +1056,12 @@ public:
LINK_PARAM_EXT(COPY_ON_CHANGE_GROUP) \
LINK_PARAM_EXT(COPY_ON_CHANGE_TOUCHED)
// defines the actual properties
/// Define the various properties for a link element.
LINK_PROPS_DEFINE(LINK_PARAMS_ELEMENT)
LinkElement();
const char* getViewProviderName() const override
{
return "Gui::ViewProviderLink";
@@ -748,6 +1073,7 @@ public:
inherited::onDocumentRestored();
}
/// Check whether this link element can be deleted.
bool canDelete() const;
void handleChangedPropertyName(Base::XMLReader& reader,
@@ -759,6 +1085,7 @@ public:
bool isLink() const override;
/// Get the parent link of this link element.
App::Link* getLinkGroup() const;
Base::Placement getPlacementOf(const std::string& sub, DocumentObject* targetObj = nullptr) override;
@@ -768,6 +1095,21 @@ using LinkElementPython = App::FeaturePythonT<LinkElement>;
///////////////////////////////////////////////////////////////////////////
/**
* @brief A class that represents a group of links.
* @ingroup LinksGroup
*
* Other than "upgrading" a normal Link to having multiple @ref
* App::LinkElement "LinkElements", a link group is a grouping for document
* objects where the group itself has a separate placement or visibility of the
* elements.
*
* A link group can contain the objects directly as children (called a simple
* group), or it can contain links to the objects. In the latter case, it is
* possible to create a group with transform links which means that the
* placement of the original objects affect the placement of the links as well.
*/
class AppExport LinkGroup: public App::DocumentObject, public App::LinkBaseExtension
{
PROPERTY_HEADER_WITH_EXTENSIONS(App::LinkGroup);
@@ -781,7 +1123,7 @@ public:
LINK_PARAM_EXT(MODE) \
LINK_PARAM_EXT_ATYPE(COLORED_ELEMENTS, App::Prop_Hidden)
// defines the actual properties
/// Define the various properties of the link group.
LINK_PROPS_DEFINE(LINK_PARAMS_GROUP)
LinkGroup();
@@ -809,13 +1151,14 @@ import LinkParams
LinkParams.declare()
]]]*/
namespace App
{
/** Convenient class to obtain App::Link related parameters
// Auto generated code (App/params_utils.py:90)
namespace App {
/**
* @brief Convenient class to obtain App::Link related parameters
*
* The parameters are under group "User parameter:BaseApp/Preferences/Link"
*
* This class is auto generated by LinkParams.py. Modify that file
* This class is auto generated by App/LinkParams.py. Modify that file
* instead of this one, if you want to add any parameter. You need
* to install Cog Python package for code generation:
* @code
@@ -827,7 +1170,7 @@ namespace App
* python3 -m cogapp -r Link.h Link.cpp
* @endcode
*
* You can add a new parameter by adding lines in LinkParams.py. Available
* You can add a new parameter by adding lines in App/LinkParams.py. Available
* parameter types are 'Int, UInt, String, Bool, Float'. For example, to add
* a new Int type parameter,
* @code
@@ -841,26 +1184,27 @@ namespace App
* void LinkParams:on<parameter_name>Changed()
* @endcode
*/
class AppExport LinkParams
{
class AppExport LinkParams {
public:
static ParameterGrp::handle getHandle();
//@{
/// Accessor for parameter CopyOnChangeApplyToAll
// Auto generated code (App/params_utils.py:139)
/// @name CopyOnChangeApplyToAll accessors
/// @brief Accessors for parameter CopyOnChangeApplyToAll
///
/// Stores the last user choice of whether to apply CopyOnChange setup to all link
/// that links to the same configurable object
static const bool& getCopyOnChangeApplyToAll();
static const bool& defaultCopyOnChangeApplyToAll();
/// @{
static const bool & getCopyOnChangeApplyToAll();
static const bool & defaultCopyOnChangeApplyToAll();
static void removeCopyOnChangeApplyToAll();
static void setCopyOnChangeApplyToAll(const bool& v);
static const char* docCopyOnChangeApplyToAll();
//@}
static void setCopyOnChangeApplyToAll(const bool &v);
static const char *docCopyOnChangeApplyToAll();
/// @}
// Auto generated code. See class document of LinkParams.
};
} // namespace App
// Auto generated code (App/params_utils.py:180)
}; // class LinkParams
} // namespace App
//[[[end]]]

View File

@@ -692,6 +692,66 @@
* handle multiple inheritance in the C-API for Python extensions.
*/
/**
* @defgroup LinksGroup Links
* @ingroup APP
* @brief Links determine relations between document objects and documents.
*
* App::Link document objects are special document objects that create links to
* other document objects, potentially in other documents. Links are special
* document objects that inherit most properties from the object they are
* linked to, but they can override some properties as well, such as the
* placement, color, or scale. More precisely, the properties that can be
* overridden typically apply simple transforms on the shape of the linked
* object.
*
* The most visible part of links to users is App::Link. It inherits from @ref
* App::DocumentObject "DocumentObject" and from @ref App::LinkExtension
* "LinkExtension" which gives it the functionality to link to other document
* objects. @ref App::LinkExtension "LinkExtension" inherits from @ref
* App::LinkBaseExtension "LinkBaseExtension" and gets most of its
* functionality from that class.
*
* There are two other classes that inherit from @ref App::LinkBaseExtension
* "LinkBaseExtension", namely @ref App::LinkGroup "LinkGroup" and @ref
* App::LinkElement "LinkElement". A %LinkGroup is a group of document objects
* or links with, for example, a common placement.
*
* A @ref App::LinkElement "LinkElement" is a container for link elements to
* form a special kind of group based on only one link. This can be achieved
* by creating an App::Link to an object and increase the element count to
* greater than 0. Each link is then represented by a @ref App::LinkElement
* "LinkElement".
*
* Links are very cheap in the sense that there is no copy of the object it
* links to, although it does have its own shape. The view provider of the
* link also simply makes use the document objects in the original linked
* object. Changing a property in the link (unless it is one of the overridden
* ones) will typically also affect the original linked object.
*
* @section SecCopyOnChange Copy-on-change links
*
* Links can be created as "copy-on-change" links. To create copy-on-change
* links, the source object needs to have a property that is marked as
* "copy-on-change". Creating an App::Link from this source objects creates a
* normal link where the property `LinkedObject` points to the source object.
*
* The user can then change the property `LinkCopyOnChange` to `Enabled` which
* provides the user with copy-on-link behavior although the link is still a
* regular link. What is special, is that the link adopts the copy-on-change
* property from the source object in order for users to change the value in
* the link. As soon as the adopted copy-on-change property is changed, a
* special hidden document object is created inside the link will contain a
* copy of the source object. The link's `LinkedObject` property is then
* changed to point to this hidden object, the changed property is applied on
* this hidden object and the link is now a variant of the original source
* object.
*
* Instead of changing the property `LinkCopyOnChange` to `Enabled`, the user
* can also set it to `Tracking` which means that changes in the original
* object are tracked and applied on the copy.
*/
/**
* @namespace App
* @ingroup APP

View File

@@ -90,8 +90,9 @@ def declare_begin(module, header=True):
f"""
{trace_comment()}
namespace {namespace} {{
/** {class_doc}
/**
* @brief {class_doc}
*
* The parameters are under group "{param_path}"
*
* This class is auto generated by {param_file}. Modify that file
@@ -137,8 +138,8 @@ public:
cog.out(
f"""
{trace_comment()}
//@{{
/// Accessor for parameter {param.name}"""
/// @name {param.name} accessors
/// @brief Accessors for parameter {param.name}"""
)
if param._doc:
cog.out(
@@ -152,6 +153,7 @@ public:
)
cog.out(
f"""
/// @{{
static const {param.C_Type} & get{param.name}();
static const {param.C_Type} & default{param.name}();
static void remove{param.name}();
@@ -165,7 +167,7 @@ public:
)
cog.out(
f"""
//@}}
/// @}}
"""
)