Merge pull request #25197 from pieterhijma/doc-link
Doc: Improve the documentation of Link
This commit is contained in:
@@ -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]]]
|
||||
|
||||
480
src/App/Link.h
480
src/App/Link.h
@@ -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]]]
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"""
|
||||
//@}}
|
||||
/// @}}
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user