From 788fe423e8b3e257ca59d5b2f75cc7e97ef859f8 Mon Sep 17 00:00:00 2001 From: Pieter Hijma Date: Sun, 8 Jun 2025 13:53:55 +0200 Subject: [PATCH] Doc: Improve App::DocumentObject documentation It also improves documentation from other files for relevant dependent functions. --- src/App/Application.h | 10 +- src/App/DocumentObject.cpp | 2 +- src/App/DocumentObject.h | 1105 ++++++++++++++++++++-------- src/App/DocumentObjectExtension.h | 27 +- src/App/Link.h | 38 + src/App/PropertyExpressionEngine.h | 1 - src/App/PropertyLinks.h | 32 +- 7 files changed, 883 insertions(+), 332 deletions(-) diff --git a/src/App/Application.h b/src/App/Application.h index 511badca96..fb593fe69e 100644 --- a/src/App/Application.h +++ b/src/App/Application.h @@ -461,16 +461,18 @@ public: /** @name Link handling */ //@{ - /** Check for link recursion depth + /** + * @brief Check for link recursion depth. + * + * The function uses an internal count of all objects in all documents as + * the limit of recursion depth. If the depth exceeds this limit, it means + * that there is likely a cyclic reference in the links. * * @param depth: current depth * @param option: whether to throw exception, print an error message or quieten any output. * In the latter case the caller must check the returned value. * * @return Return the maximum remaining depth. - * - * The function uses an internal count of all objects in all documents as - * the limit of recursion depth. */ int checkLinkDepth(int depth, MessageOption option = MessageOption::Error); diff --git a/src/App/DocumentObject.cpp b/src/App/DocumentObject.cpp index 403e367373..fcecdf15f0 100644 --- a/src/App/DocumentObject.cpp +++ b/src/App/DocumentObject.cpp @@ -616,7 +616,7 @@ bool DocumentObject::isInOutListRecursive(DocumentObject* linkTo) const } std::vector> -DocumentObject::getPathsByOutList(App::DocumentObject* to) const +DocumentObject::getPathsByOutList(const App::DocumentObject* to) const { return _pDoc->getPathsByOutList(this, to); } diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h index 30f05c2486..6b0ac2bc9c 100644 --- a/src/App/DocumentObject.h +++ b/src/App/DocumentObject.h @@ -56,42 +56,65 @@ class DocumentObjectPy; class Expression; // clang-format off +/// Defines the position of the status bits for document objects. enum ObjectStatus { - Touch = 0, - Error = 1, - New = 2, - Recompute = 3, // set when the object is currently being recomputed - Restore = 4, - Remove = 5, - PythonCall = 6, - Destroy = 7, - Enforce = 8, - Recompute2 = 9, // set when the object is being recomputed in the second pass - PartialObject = 10, - PendingRecompute = 11, // set by Document, indicating the object is in recomputation queue - ObjImporting = 13, // Mark the object as importing - NoTouch = 14, // no touch on any property change - GeoExcluded = 15, // mark as a member but not claimed by GeoFeatureGroup - Expand = 16, // indicate the object's tree item expansion status - NoAutoExpand = 17, // disable tree item auto expand on selection for this object - PendingTransactionUpdate = 18, // mark that the object expects a call to onUndoRedoFinished() after transaction is finished. - RecomputeExtension = 19, // mark the object to recompute its extensions - TouchOnColorChange = 20, // inform view provider touch object on color change - Freeze = 21, // do not recompute ever + Touch = 0, ///< Whether the object is marked as 'touched'. + Error = 1, ///< Whether the object is in an error state. + New = 2, ///< Whether the object is newly created. + Recompute = 3, ///< Whether the object is currently recomputing. + Restore = 4, ///< Whether the object is currently restoring from a file. + Remove = 5, ///< Whether the object is about to be removed from the document. + PythonCall = 6, ///< Unused flag. + Destroy = 7, ///< Whether the object is about to be destroyed. + Enforce = 8, ///< Whether the object is forced to be recomputed. + Recompute2 = 9, ///< Whether the object is going to be recomputed in the second pass. + PartialObject = 10, ///< Whether this is a partially loaded object. + PendingRecompute = 11, ///< Whether the object is in the recomputation queue, set by Document. + ObjImporting = 13, ///< Whether the object is being imported. + NoTouch = 14, ///< Whether the object should be touched on a property change. + GeoExcluded = 15, ///< Whether the object is a member but not claimed by a GeoFeatureGroup. + Expand = 16, ///< Whether the object is expanded in the tree view. + NoAutoExpand = 17, ///< Whether the object should have auto expansion disabled on selection. + /// Whether the object expects a call to onUndoRedoFinished() after transaction is finished. + PendingTransactionUpdate = 18, + RecomputeExtension = 19, ///< Whether the extensions of this object should be recomputed. + TouchOnColorChange = 20, ///< Whether the object should be touched on color change. + Freeze = 21, ///< Whether the object is frozen and is excluded from recomputation. }; // clang-format on -/** Return object for feature execution +/** + * @brief A return object for feature execution. + * + * This class is used to return the result of a feature execution and is + * returned by the recompute(), execute() and executeExtension() methods. + * + * Note that these functions return a pointer to an instance and that + * DocumentObject::StdReturn is a static instance of this class that has as + * value `nullptr`. Returning @ref DocumentObject::StdReturn "StdReturn" + * indicates that the execution was successful and that no further action is + * needed. */ class AppExport DocumentObjectExecReturn { public: + /** + * @brief Construct a DocumentObjectExecReturn object. + * + * Constructing an object of this type means that the execution was + * unsuccessful and the reason is given in the `Why` member. + * + * @param[in] sWhy The reason for the failed execution. + * @param[in] WhichObject The object that caused the failed execution. + */ explicit DocumentObjectExecReturn(const std::string& sWhy, DocumentObject* WhichObject = nullptr) : Why(sWhy) , Which(WhichObject) {} + + /// @copydoc DocumentObjectExecReturn::DocumentObjectExecReturn(const std::string&, DocumentObject*) explicit DocumentObjectExecReturn(const char* sWhy, DocumentObject* WhichObject = nullptr) : Which(WhichObject) { @@ -100,15 +123,19 @@ public: } } + /// The reason for the failed execution. std::string Why; + + /// The object that caused the failed execution. DocumentObject* Which; }; /** * @brief %Base class of all objects handled in the @ref App::Document "Document". - * @ingroup DocObject - * @details For a more high-level overview see topic @ref DocObject "Document Object". + * @ingroup DocumentObjectGroup + * + * For a more high-level overview see topic @ref DocumentObjectGroup "Document Object". */ class AppExport DocumentObject: public App::TransactionalObject { @@ -120,76 +147,159 @@ private: std::vector readOnlyProperties; public: + /** + * @name Static properties + * @{ + */ + + /// A property for the label of the document object. PropertyString Label; + + /// A property for the description of the document object. PropertyString Label2; + + /// A property that manages the expressions in the document object. PropertyExpressionEngine ExpressionEngine; - /// Allow control visibility status in App name space + /// A property that controls the visibility status in App name space. PropertyBool Visibility; + /// @} + /** + * @name Signals for property change + * @{ + */ // clang-format off - /// signal before changing a property of this object + /** + * @brief Signal that the property of this object is about to change. + * + * Subscribers will get the current object and the property about to be modified. + * + * @param[in] obj The document object whose property is changing. + * @param[in] prop The property that is about to change. + */ fastsignals::signal signalBeforeChange; - /// signal on changed property of this object + + /** + * @brief Signal that the property of this object has changed. + * + * Subscribers will get the current object and the property that has changed. + * + * @param[in] obj The document object whose property just changed. + * @param[in] prop The property that was changed. + */ fastsignals::signal signalChanged; - /// signal on changed property of this object before document scoped signalChangedObject + + /** + * @brief Emitted immediately after any property of this object has changed. + * + * This is fired before the outer "document-scoped" change notification. + * + * @param[in] obj The document object whose property just changed. + * @param[in] prop The property that was changed. + */ fastsignals::signal signalEarlyChanged; + /// @} // clang-format on - /// returns the type name of the ViewProvider + /** + * @brief Get the name of the type of the ViewProvider. + * + * By overriding this function, document objects can indicate what the type + * of the belonging view provider is. Note that this function is + * essentially the boundary between the App and Gui namespaces. + * + * @return The name of the type of the ViewProvider. + */ virtual const char* getViewProviderName() const { return ""; } + /** - * This function is introduced to allow Python feature override its view provider. - * The default implementation just returns \ref getViewProviderName(). + * @brief Get the name of the type of the ViewProvider for Python. + * + * This function is introduced to allow Python feature override its view + * provider. The default implementation just returns \ref + * getViewProviderName(). * * The core will only accept the overridden view provider if it returns * true when calling Gui::ViewProviderDocumentObject::allowOverride(obj). * If not, the view provider will be reverted to the one returned from \ref * getViewProviderName(). + * + * @return The name of the type of the ViewProvider for Python. */ virtual const char* getViewProviderNameOverride() const { return getViewProviderName(); } - /// Constructor DocumentObject(); + ~DocumentObject() override; - /// returns a value that uniquely identifies this DocumentObject. + /// Get a value that uniquely identifies this document object. const char* getDagKey() const; - /// returns the name which is set in the document for this object (not the name property!) + + /// Get the name of the object in the document. const char* getNameInDocument() const; - /// Return the object ID that is unique within its owner document + + /// Get the object ID that is unique within its owner document. long getID() const { return _Id; } - /// returns the name that is safe to be exported to other document + + /** + * @brief Get the export name of the object. + * + * This name is safe to be exported to another document. + * + * @param[in] forced If true, the name is forced to be unique. + * + * @return The export name of the object. + */ std::string getExportName(bool forced = false) const; - /// Return the object full name of the form DocName#ObjName + + /** + * @brief Get the full name of the object. + * + * The name is of the form `DocName#ObjName`. + * + * @return The full name of the object. + */ std::string getFullName() const override; - /// Return the object full label in the form DocName#ObjName + + /** + * @brief Get the full label of the object. + * + * The label is of the form `DocName#Label`. + * + * @return The full label of the object. + */ std::string getFullLabel() const; + bool isAttachedToDocument() const override; const char* detachFromDocument() override; - /// gets the document in which this Object is handled + + /// Get the document of which this object is part. App::Document* getDocument() const; - /** Set the property touched -> changed, cause recomputation in Update() + /** + * @name Status handling + * @{ */ - //@{ /** * @brief Set this document object touched. * - * Touching a document object does not mean to recompute it, it only means - * that other document objects that link to it (i.e. its InList) will be - * recomputed. If it should be forced to recompute a document object then - * use \ref enforceRecompute() instead. + * With @p noRecompute it is possible to make sure that only other document + * objects that link to it (i.e. its InList) will be recomputed. By + * default the document object itself will be recomputed as well. + * + * @param[in] noRecompute If true, the object will not be recomputed when + * touched. */ void touch(bool noRecompute = false); @@ -198,8 +308,8 @@ public: * * @return true if document object is touched, false if not. */ - bool isTouched() const; + /** * @brief Enforce this document object to be recomputed. * @@ -217,38 +327,46 @@ public: * @return true if document object must be recomputed, false if not. */ bool mustRecompute() const; - /// reset this document object touched + + /// Reset the touch flags of the document object. void purgeTouched() { StatusBits.reset(ObjectStatus::Touch); StatusBits.reset(ObjectStatus::Enforce); setPropertyStatus(0, false); } - /// set this feature to error + + /// Check whether this document object is in an error state. bool isError() const { return StatusBits.test(ObjectStatus::Error); } + + /// Check whether this document object is in a valid state. bool isValid() const { return !StatusBits.test(ObjectStatus::Error); } - /// remove the error from the object + + /// Remove the error from the object. void purgeError() { StatusBits.reset(ObjectStatus::Error); } - /// returns true if this objects is currently recomputing + + /// Check whether this document object is being recomputed. bool isRecomputing() const { return StatusBits.test(ObjectStatus::Recompute); } - /// returns true if this objects is currently restoring from file + + /// Check whether the document is restoring from file. bool isRestoring() const { return StatusBits.test(ObjectStatus::Restore); } - /// returns true if this objects is currently removed from the document + + /// Check whether this document object is being removed. bool isRemoving() const { return StatusBits.test(ObjectStatus::Remove); @@ -273,207 +391,403 @@ public: * @see touch() */ void unfreeze(bool noRecompute = false); - /// returns true if this objects is currently freezed + + /// Check whether this document object is being freezed. bool isFreezed() const { return StatusBits.test(ObjectStatus::Freeze); } - /// return the status bits + + /// Get the status bits. unsigned long getStatus() const { return StatusBits.to_ulong(); } + + /** + * @brief Test the status of the document object. + * + * @param[in] pos The status bit to test. + * + * @return true if the status bit is set, false otherwise. + */ bool testStatus(ObjectStatus pos) const { return StatusBits.test(size_t(pos)); } + + /** + * @brief Set the status of the document object for a particular bit. + * + * @param[in] pos The status bit to set. + * @param[in] on The value to set the status bit to. + */ void setStatus(ObjectStatus pos, bool on) { StatusBits.set(size_t(pos), on); } - //@} + /// Check whether the document object is exporting. int isExporting() const; + /// @} - /** Child element handling + /** + * @name Child element handling + * @{ */ - //@{ - /** Set sub-element visibility + + /** @brief Set the visibility of a sub-element. * - * For performance reason, \c element must not contain any further - * sub-elements, i.e. there should be no '.' inside \c element. + * For performance reason, @p element must not contain any further + * sub-elements, i.e. there should be no '.' inside @p element. * * @return -1 if element visibility is not supported, 0 if element is not * found, 1 if success */ virtual int setElementVisible(const char* element, bool visible); - /** Get sub-element visibility + /** @brief Get the visibility of a sub-element. * - * @return -1 if element visibility is not supported or element not found, 0 - * if element is invisible, or else 1 + * @return -1 if element visibility is not supported or if the element is not found, 0 + * if element is invisible, or else 1. */ virtual int isElementVisible(const char* element) const; - /// return true to activate tree view group object handling and element visibility + /// Check whether the object has child elements. virtual bool hasChildElement() const; - //@} + ///@} - /** DAG handling - This part of the interface deals with viewing the document as - a DAG (directed acyclic graph). - */ - //@{ - /// OutList options + /** + * @name DAG handling + * + * This part of the interface deals with viewing the document as a DAG + * (directed acyclic graph). + * + * @{ + */ + + /// Options for computing the OutList enum OutListOption { - /// Do not include link from expression engine - OutListNoExpression = 1, - /// Do not hide any link (i.e. include links with LinkScopeHidden) - OutListNoHidden = 2, - /// Do not include link from PropertyXLink - OutListNoXLinked = 4, + OutListNoExpression = 1, ///< Do not include links from the expression engine. + OutListNoHidden = 2, ///< Do not hide any link (i.e. include links with LinkScopeHidden). + OutListNoXLinked = 4, ///< Do not include links from PropertyXLink properties. }; - /// returns a list of objects this object is pointing to by Links + + /// Get a list of objects this object links to. const std::vector& getOutList() const; + + /** + * @brief Get a list of objects this object links to. + * + * @param[in] option Options for computing the OutList. + * + * @return A vector of objects this object links to. + * + * @see OutListOption for available options. + */ std::vector getOutList(int option) const; + + /** + * @brief Get a list of objects this object links to. + * + * @param[in] option Options for computing the OutList. + * + * @param[in,out] res The vector to fill with the objects this object depends on. + * + * @see OutListOption for available options. + */ void getOutList(int option, std::vector& res) const; - /// returns a list of objects linked by the property - std::vector getOutListOfProperty(App::Property*) const; - /// returns a list of objects this object is pointing to by Links and all further descended - std::vector getOutListRecursive() const; - /// clear internal out list cache - void clearOutListCache() const; - /// get all possible paths from this to another object following the OutList - std::vector> getPathsByOutList(App::DocumentObject* to) const; - /// get all objects link to this object - const std::vector& getInList() const; - /// get all objects link directly or indirectly to this object - std::vector getInListRecursive() const; - /** Get a set of all objects linking to this object, including possible external parent objects + /** + * @brief Get a list of objects that a property links to. * - * @param inSet [out]: a set containing all objects linking to this object. - * @param recursive [in]: whether to obtain recursive in list - * @param inList [in, out]: optional pointer to a vector holding the output + * @param[in] prop The property to query for linked objects. + * @return A vector of objects that the property links to. + */ + std::vector getOutListOfProperty(App::Property* prop) const; + + /** + * @brief Get a list of objects this object links to, recursively. + * + * This function returns all objects that this object links to and all + * further descendants. + * + * @return A vector of objects this object links to, recursively. + */ + std::vector getOutListRecursive() const; + + /// Clear the internal OutList cache. + void clearOutListCache() const; + + /** + * @brief Get all possible paths from this object to another object. + * + * This function returns all paths from this object to the specified object + * by following the OutList. The paths are returned as a vector of lists, + * where each list represents a path from this object to the target object. + * + * @param[in] to The target object to which paths are sought. + * + * @return A vector of lists, where each list contains the objects in a + * path from this object to the target object. + */ + std::vector> getPathsByOutList(const App::DocumentObject* to) const; + + /** @brief Get a list of objects that link to this object. + * + * This function returns a list of objects that directly link to this + * object, i.e. the InList. + * + * @return A reference to the list of objects that depend on this object. + */ + const std::vector& getInList() const; + + /** + * @brief Get a list of objects that link to this object, recursively. + * + * This function returns all objects that link to this object directly and + * indirectly. + * + * @return A vector of objects that link to this object, recursively. + */ + std::vector getInListRecursive() const; + + /** @brief Get a set of all objects linking to this object. + * + * This function returns a set of all objects that link to this object, + * including possible external parent objects. + * + * @param[in,out] inSet A set containing all objects linking to this object. + * @param[in] recursive Whether to obtain the InList recursively. + * @param[in,out] inList An optional pointer to a vector holding the output. * objects, with the furthest linking object ordered last. */ void getInListEx(std::set& inSet, bool recursive, std::vector* inList = nullptr) const; - /** Return a set of all objects linking to this object, including possible external parent - * objects - * @param recursive [in]: whether to obtain recursive in list + + /** + * @brief Get a set of all objects linking to this object. + * + * This function returns a set of all objects that link to this object, + * including possible external parent objects. + * + * @param[in] recursive Whether to obtain the InList recursively. + * + * @return A set containing all objects linking to this object. */ std::set getInListEx(bool recursive) const; - /// get group if object is part of a group, otherwise 0 is returned + /** + * @brief Get the group this object belongs to. + * + * This function returns the group that this object is part of, if any. + * + * @return A pointer to the group this object belongs to, or nullptr if it + * is not part of any group. + */ DocumentObjectGroup* getGroup() const; - /// test if this object is in the InList and recursive further down + /** + * @brief Check if an object is (in)directly in the InList of this object. + * + * This function checks if the specified object is in the InList of this + * object, either directly or recursively. + * + * @param[in] objToTest The object to test for presence in the InList. + * + * @return true if the object is in the InList, false otherwise. + */ bool isInInListRecursive(DocumentObject* objToTest) const; - /// test if this object is directly (non recursive) in the InList - bool isInInList(DocumentObject* objToTest) const; - /// test if the given object is in the OutList and recursive further down - bool isInOutListRecursive(DocumentObject* objToTest) const; - /// test if this object is directly (non recursive) in the OutList - bool isInOutList(DocumentObject* objToTest) const; - /// internal, used by PropertyLink to maintain DAG back links - void _removeBackLink(DocumentObject*); - /// internal, used by PropertyLink to maintain DAG back links - void _addBackLink(DocumentObject*); - //@} /** - * @brief testIfLinkIsDAG tests a link that is about to be created for - * circular references. - * @param objToLinkIn (input). The object this object is to depend on after - * the link is going to be created. - * @return true if link can be created (no cycles will be made). False if - * the link will cause a circular dependency and break recomputes. Throws an - * error if the document already has a circular dependency. - * That is, if the return is true, the link is allowed. + * @brief Check if an object is directly in the InList of this object. + * + * This function checks if the specified object is directly in the InList + * of this object, without checking recursively. + * + * @param[in] objToTest The object to test for presence in the InList. + * + * @return true if the object is directly in the InList, false otherwise. + */ + bool isInInList(DocumentObject* objToTest) const; + + /** + * @brief Check if an object is (in)directly in the OutList of this object. + * + * This function checks if the specified object is in the OutList of this + * object, either directly or recursively. + * + * @param[in] objToTest The object to test for presence in the OutList. + * + * @return true if the object is in the OutList, false otherwise. + */ + bool isInOutListRecursive(DocumentObject* objToTest) const; + + /** + * @brief Check if an object is directly in the OutList of this object. + * + * This function checks if the specified object is directly in the OutList + * of this object, without checking recursively. + * + * @param[in] objToTest The object to test for presence in the OutList. + * + * @return true if the object is directly in the OutList, false otherwise. + */ + bool isInOutList(DocumentObject* objToTest) const; + + /** + * @brief Remove a back link from the InList of this object. + * + * This is an internal method, used by @ref App::PropertyLink + * "PropertyLink" (and variants) to maintain DAG back links when a link + * property's value is set. + * + * @param[in] obj The object to remove from the InList. + */ + void _removeBackLink(DocumentObject* obj); + + /** + * @brief Add a back link to the InList of this object. + * + * This is an internal method, used by @ref App::PropertyLink + * "PropertyLink" (and variants) to maintain DAG back links when a link + * property's value is set. + * + * @param[in] obj The object to remove from the InList. + */ + void _addBackLink(DocumentObject*); + + /** + * @brief Test an about to created link for circular references. + * + * This function checks if the link to the specified parameter is DAG + * compatible, which means that no circular references will be created. + * + * @param[in] linkTo The object that this object is about to link to. + * + * @return true if the link can be created without a circular dependency, + * false if it will cause a circular dependency. */ bool testIfLinkDAGCompatible(DocumentObject* linkTo) const; - bool testIfLinkDAGCompatible(const std::vector& linksTo) const; - bool testIfLinkDAGCompatible(App::PropertyLinkSubList& linksTo) const; - bool testIfLinkDAGCompatible(App::PropertyLinkSub& linkTo) const; - /** Return the element map version of the geometry data stored in the given property + /** + * @copybrief testIfLinkDAGCompatible(DocumentObject*) const * - * @param prop: the geometry property to query for element map version - * @param restored: whether to query for the restored element map version. - * In case of version upgrade, the restored version may - * be different from the current version. + * @param[in] linksTo A list of objects that this object is about to link to. + * + * @return true if the links can be created without a circular dependency, + * false if they will cause a circular dependency. + */ + bool testIfLinkDAGCompatible(const std::vector& linksTo) const; + + /// @copydoc testIfLinkDAGCompatible(const std::vector&) const + bool testIfLinkDAGCompatible(App::PropertyLinkSubList& linksTo) const; + + /// @copydoc testIfLinkDAGCompatible(DocumentObject*) const + bool testIfLinkDAGCompatible(App::PropertyLinkSub& linkTo) const; + ///@} + + /** + * @brief Get the element map version of the geometry data stored in the given property. + * + * @param[in] prop: the geometry property to query for element map version + * @param[in] restored: whether to query for the restored element map version. + * In case of version upgrade, the restored version may + * be different from the current version. * * @return Return the element map version string. */ virtual std::string getElementMapVersion(const App::Property* prop, bool restored = false) const; - /// Return true to signal re-generation of geometry element names + /** @brief Check the element map versionn of the property. + * + * This function checks whether the element map version of the given + * property matches the given version string. If the function returns + * true, the geometry element names need to be recomputed. + * + * @param[in] prop: the geometry property to query for element map version + * @param[in] ver: the version string to compare with + * + * @return true if the element map version differs and the geometry element + * namess need to be recomputed. + */ virtual bool checkElementMapVersion(const App::Property* prop, const char* ver) const; public: - /** mustExecute - * We call this method to check if the object was modified to - * be invoked. If the object label or an argument is modified. - * If we must recompute the object - to call the method execute(). - * 0: no recomputation is needed - * 1: recomputation needed + + /** + * @brief Whether the object must be executed. * - * @remark If an object is marked as 'touched' then this does not + * This method checks if the object was modified to be invoked. + * + * @return 0 if no execute is needed, 1 if the object must be executed. + * + * @remark If an object is marked as 'touched', then this does not * necessarily mean that it will be recomputed. It only means that all - * objects that link it (i.e. its InList) will be recomputed. + * objects that link to it (i.e. its InList) will be recomputed. */ virtual short mustExecute() const; - /** Recompute only this feature + /** + * @brief Recompute only this feature. * - * @param recursive: set to true to recompute any dependent objects as well + * @param recursive: set to true to recompute any dependent objects as well. + * + * @return true if the feature was recomputed, false if it was not. */ bool recomputeFeature(bool recursive = false); - /// get the status Message + /// Get the status message. const char* getStatusString() const; - /** Called in case of losing a link - * Get called by the document when a object got deleted a link property of this - * object ist pointing to. The standard behaviour of the DocumentObject implementation - * is to reset the links to nothing. You may override this method to implement - * additional or different behavior. + /** + * @brief Called when a link to a DocumentObject is lost. + * + * This method is called by the document when a link property of this + * object is pointing to a DocumentObject that has been deleted. The + * standard behavior of the DocumentObject implementation is to reset the + * links to nothing. You may override this method to implement additional + * or different behavior. + * + * @param[in] obj The DocumentObject that has been lost. */ - virtual void onLostLinkToObject(DocumentObject*); + virtual void onLostLinkToObject(DocumentObject* obj); + PyObject* getPyObject() override; - /** Get the sub element/object by name + /** + * @brief Get the sub element/object by name. * - * @param subname: a string which is dot separated name to refer to a sub - * element or object. An empty string can be used to refer to the object - * itself + * @param[in] subname A string that is a dot separated name to refer to a + * sub element or object. An empty string can be used to refer to the + * object itself. * - * @param pyObj: if non zero, returns the python object corresponding to + * @param[out] pyObj If not null, returns the python object corresponding to * this sub object. The actual type of this python object is implementation - * dependent. For example, The current implementation of Part::Feature will - * return the TopoShapePy, event if there is no sub-element reference, in - * which case it returns the whole shape. + * dependent. For example, The current implementation of @c Part::Feature + * will return the TopoShapePy, even if there is no sub-element reference, + * in which case it returns the whole shape. * - * @param mat: If non zero, it is used as the current transformation matrix - * on input. And output as the accumulated transformation up until and - * include the transformation applied by the final object reference in \c - * subname. For Part::Feature, the transformation is applied to the - * TopoShape inside \c pyObj before returning. + * @param[in,out] mat If not null, it is used as the current + * transformation matrix on input. On output it is used as the accumulated + * transformation up until and include the transformation applied by the + * final object reference in @c subname. For @c Part::Feature, the + * transformation is applied to the @c TopoShape inside @c pyObj before + * returning. * - * @param transform: if false, then it will not apply the object's own - * transformation to \c mat, which lets you override the object's placement + * @param[in] transform: If false, then it will not apply the object's own + * transformation to @p mat, which lets you override the object's placement * (and possibly scale). * - * @param depth: depth limitation as hint for cyclic link detection + * @param[in] depth: Depth limitation as hint for cyclic link detection. * - * @return The last document object referred in subname. If subname is empty, - * then it shall return itself. If subname is invalid, then it shall return - * zero. + * @return The last document object referred in subname. If @p subname is + * empty, then it returns itself. If @p subname is invalid, then it returns @c + * nullptr. */ virtual DocumentObject* getSubObject(const char* subname, PyObject** pyObj = nullptr, @@ -481,107 +795,175 @@ public: bool transform = true, int depth = 0) const; - /** Return a list of objects referenced by a given subname including this object - * @param subname: the sub name path - * @param subsizes: optional sub name sizes for each returned object, that is, - * ret[i] = getSubObject(std::string(subname, subsizes[i]).c_str()); - * @param flatten: whether to flatten the object hierarchies that belong to - * the same geo feature group, e.g. (Part.Fusion.Box -> Part.Box) + /** + * @brief Get a list of objects referenced by a given subname. * - * @return Return a list of objects along the path. + * This method returns a list of objects along the path that is represented + * by the subname. It includes this object. With the optional argument @p + * subsizes, it is possible to infer which part of the subname relates to + * which document object, with the following relation: + * @code + * ret[i] = getSubObject(std::string(subname, subsizes[i]).c_str()); + * @endcode + * + * @param[in] subname: The subname path. + * @param[in,out] subsizes: The optional subname sizes for each returned object. + * @param[in] flatten: Whether to flatten the object hierarchies that belong to + * the same geo feature group, e.g. (Part.Fusion.Box -> Part.Box) + * + * @return Return a list of objects along the path of the subname. */ std::vector getSubObjectList(const char* subname, std::vector* subsizes = nullptr, bool flatten = false) const; - /// reason of calling getSubObjects() + /// Reason of calling getSubObjects() enum GSReason { - /// default, mostly for exporting shape objects + /// Default, mostly for exporting shape objects GS_DEFAULT, - /// for element selection + /// For element selection GS_SELECT, }; - /** Return name reference of all sub-objects + /** + * @brief Get name references of all sub-objects. * - * @param reason: indicate reason of obtaining the sub objects + * This function returns a list of sub-object names for this object. The + * default implementation returns all object references in PropertyLink, + * and PropertyLinkList, if any. * - * The default implementation returns all object references in - * PropertyLink, and PropertyLinkList, if any - * - * @return Return a vector of subname references for all sub-objects. In - * most cases, the name returned will be the object name plus an ending - * '.', which can be passed directly to getSubObject() to retrieve the + * In most cases, the names returned will be the object name plus an ending + * '.' that can be passed directly to getSubObject() to retrieve the * name. The reason to return the name reference instead of the sub object - * itself is because there may be no real sub object, or the sub object - * need special transformation. For example, sub objects of an array type - * of object. + * itself is because there may be no real sub object or the sub object is a + * special case, for example sub objects of an array type of object. + * + * @param[in] reason The reason for obtaining the sub objects. + * + * @return A vector of subname references for all sub-objects. */ virtual std::vector getSubObjects(int reason = 0) const; - /// Obtain top parents and subnames of this object using its InList + /** + * @brief Get the parent objects and the subnames of this object. + * + * This function returns a vector of pairs, where each pair contains a + * pointer to a parent DocumentObject and its subname using thee object's + * InList. The @p depth parameter ensures that there is no endless loop in + * case there is a cyclic dependency. + * + * @param[in] depth Optional depth that specifies on which level in parents + * the search is. + * + * @return A vector of pairs containing parent DocumentObjects and their subnames. + * @throws Base::RuntimeError If the search triggers a cycle in the dependencies in the InList. + */ std::vector> getParents(int depth = 0) const; - /// Obtain the first parent group of this object - App::DocumentObject* getFirstParent() const; + /** + * @brief Get the first parent object of this object that is a group. + * + * This function returns the first parent object that is a group, i.e. that + * has the extension GroupExtension. + * + * @return A pointer to the first parent group object, or @c nullptr if no such + * parent exists. + */ + App::DocumentObject* getFirstParent() const; - /** Return the linked object with optional transformation + /** + * @brief Get the linked object with an optional transformation. + * + * This method returns the linked object of this document object. The @p + * depth parameter indicates the current depth of recursion, which is used + * to prevent infinite recursion in case of cyclic dependencies. * * @param recurse: If false, return the immediate linked object, or else * recursively call this function to return the final linked object. * - * @param mat: If non zero, it is used as the current transformation matrix - * on input. And output as the accumulated transformation till the final + * @param mat: If non-null, it is used as the current transformation matrix + * on input. And output as the accumulated transformation until the final * linked object. * * @param transform: if false, then it will not accumulate the object's own * placement into \c mat, which lets you override the object's placement. * - * @return Return the linked object. This function must return itself if the - * it is not a link or the link is invalid. + * @param depth: Indicates the current depth of recursion. + * + * @return Return the linked object. This function returns itself if it is + * not a link or the link is invalid. */ virtual DocumentObject* getLinkedObject(bool recurse = true, Base::Matrix4D* mat = nullptr, bool transform = false, int depth = 0) const; - /* Return true to cause PropertyView to show linked object's property */ + /** + * @brief Check whether this object can adopt properties from linked objects. + * + * This function is used to determine if the object can adopt properties + * from linked objects. It is typically used in the context of the + * property view to decide whether to show properties from linked objects. + * + * @return true if the object can adopt properties from links, false otherwise. + */ virtual bool canLinkProperties() const { return true; } - /* Return whether this object is a link */ + /// Check whether this object is a link. virtual bool isLink() const { return false; } - /* Return whether this object is a link group */ + /// Check whether this object is a link group. virtual bool isLinkGroup() const { return false; } - /* Return true to bypass duplicate label checking */ + /** + * @brief Check whether this object allows duplicate labels. + * + * This function is used to determine if the object allows duplicate + * labels. Overriding this function and returning true allows to bypass + * duplicate labell checking. + * + * @return true if duplicate labels are allowed, false otherwise. + */ virtual bool allowDuplicateLabel() const { return false; } - /// Handle Label changes, including forcing unique label values, - /// signalling OnBeforeLabelChange, and arranging to update linked references, - /// on the assumption that after returning the label will indeed be changed to - /// the (altered) value of newLabel. - /// Returns a vector of referenging (linking) properties as produced by - /// PropertyLinkBase::updateLabelReferences which is needed for undo/redo purposes. + + /** + * @brief Called when a new label for the document object is proposed. + * + * This method is called when a new label is proposed for the document + * object and it handles label changes,including ensuring unique label values, + * signaling onBeforeChangeLabel(), and updating linked references. + * + * It assumes that after returning, the label will indeed be changed to the + * (possibly altered) value of @p newLabel. + * + * @param[in,out] newLabel The proposed new label for the document object. + * + * @return A vector of referencing (linking) properties as produced by + * PropertyLinkBase::updateLabelReferences(), which is needed for undo/redo + * purposes. + */ std::vector>> onProposedLabelChange(std::string& newLabel); - /*** Called to let object itself control relabeling + + /** + * @brief Called to ensure that the object can control its relabeling. * - * @param newLabel: input as the new label, which can be modified by object itself + * @param[in,out] newLabel The new label proposed for the object. * - * This function is called before onBeforeChange() + * @note This function is called before onBeforeChange(). */ virtual void onBeforeChangeLabel(std::string& newLabel) { @@ -592,6 +974,13 @@ public: friend class Transaction; friend class ObjectExecution; + /** + * @brief The standard return object for document object execution. + * + * Its value is set to `nullptr` which means that the execution + * was successful. If the execution fails, it is set to a pointer to an + * instance of this class that contains the error message. + */ static DocumentObjectExecReturn* StdReturn; void Save(Base::Writer& writer) const override; @@ -599,40 +988,59 @@ public: /* Expression support */ /** - * @brief Associate the expression \expr with the object identifier \a path in this document object. - * @param path Target object identifier for the result of the expression - * @param expr Expression tree + * @brief Set an expression for a given object identifier. + * + * Associate the expression @p expr with object identifier @p path in this document object. + * + * @param[in] path The target object identifier for the result of the expression. + * @param[in,out] expr The Expression tree. */ virtual void setExpression(const ObjectIdentifier& path, std::shared_ptr expr); /** - * @brief Clear the expression of the object identifier \a path in this document object. - * @param path Target object identifier + * @brief Clear the expression of an object identifier in this document object. + * + * @param[in] path The target object identifier. */ void clearExpression(const ObjectIdentifier& path); /** - * @brief Get expression information associated with \a path. - * @param path Object identifier - * @return Expression info, containing expression and optional comment. + * @brief Get expression information associated with an object identifier. + * + * @param[in] path The object identifier. + * + * @return Expression info that contains the expression and whether the + * expression is busy. */ virtual const PropertyExpressionEngine::ExpressionInfo getExpression(const ObjectIdentifier& path) const; /** - * @brief Invoke ExpressionEngine's renameObjectIdentifier, to possibly rewrite expressions using - * the \a paths map with current and new identifiers. + * @brief Rename object identifiers in expressions. * - * @param paths + * Invoke ExpressionEngine's renameObjectIdentifier, to possibly rewrite + * expressions using the @p paths map with current and new identifiers. + * + * @param[in] paths A map of old to new object identifiers. */ virtual void renameObjectIdentifiers(const std::map& paths); + /// Get the old label of the object. const std::string& getOldLabel() const { return oldLabel; } + /** + * @brief Get the name of the view provider that was stored for this object. + * + * This function returns the name of the view provider that was stored for + * this object. This is the case when the object has a custom view + * provider. + * + * @return The name of the view provider that was stored for this object. + */ const char* getViewProviderNameStored() const { return _pcViewProviderName.c_str(); @@ -650,17 +1058,30 @@ public: bool ro = false, bool hidden = false) override; - /** Resolve the last document object referenced in the subname + /** + * @brief Resolve the last document object referenced in the subname. * - * @param subname: dot separated subname - * @param parent: return the direct parent of the object - * @param childName: return child name to be passed to is/setElementVisible() - * @param subElement: return non-object sub-element name if found. The - * pointer is guaranteed to be within the buffer pointed to by 'subname' + * If @p childName is not null, the method will return the name of the + * child that can be passed to isElementVisible() or setElementVisible(). + * + * @param[in] subname A dot separated subname. + * @param[in,out] parent If not null, return the direct parent of the object. + * @param[in,out] childName If not null, return the child name. + * @param[in,out] subElement If not null, return the non-object sub-element + * name if found. The pointer is guaranteed to be within the buffer pointed + * to by @p subname. + * @param[in,out] pyObj If not null, return the python object corresponding + * to this sub object. + * @param[in,out] mat If not null, it is used for (accumulated) + * transformation of the sub object. + * @param[in] transform Whether to apply the object's own transformation. + * @param[in] depth Maintains the current depth of recursion for cyclic + * link detection. * * @sa getSubObject() - * @return Returns the last referenced document object in the subname. If no - * such object in subname, return pObject. + * + * @return The last referenced document object in the subname or if no such + * object in subname, itself. */ App::DocumentObject* resolve(const char* subname, App::DocumentObject** parent = nullptr, @@ -671,26 +1092,16 @@ public: bool transform = true, int depth = 0) const; - /** Resolve a link reference that is relative to this object reference + /** + * @brief Resolve a link reference that is relative to this object reference. * - * @param subname: on input, this is the subname reference to the object - * that is to be assigned a link. On output, the reference may be offset - * to be rid of any common parent. - * @param link: on input, this is the top parent of the link reference. On - * output, it may be altered to one of its child to be rid off any common - * parent. - * @param linkSub: on input, this the subname of the link reference. On - * output, it may be offset to be rid off any common parent. - * - * @return The corrected top parent of the object that is to be assigned the - * link. If the output 'subname' is empty, then return the object itself. - * - * To avoid any cyclic reference, an object must not be assign a link to any - * of the object in its parent. This function can be used to resolve any + * To avoid cyclic references, an object must not be assigned a link to any + * of the objects in its parent. This function can be used to resolve any * common parents of an object and its link target. * - * For example, with the following object hierarchy + * For example, with the following object hierarchy: * + * ``` * Group * |--Group001 * | |--Box @@ -698,169 +1109,239 @@ public: * |--Group002 * |--Box001 * |--Cylinder001 + * ``` * - * If you want add a link of Group.Group002.Box001 to Group.Group001, you - * can call with the following parameter (which are usually obtained from - * Selection.getSelectionEx(), check usage in TreeWidget::onDropEvent()): + * If you want to add a link of `Group.Group002.Box001` to + * `Group.Group001`, you can call the method with the following parameters: + * + * ```cpp * std::string subname("Group002."); * auto link = Group; * std::string linkSub("Group001.Box001."); * parent = Group.resolveRelativeLink(subname,link,linkSub); + * ``` * * The resolving result is as follow: + * + * ``` * return -> Group001 * subname -> "" * link -> Group002 * linkSub -> "Box001." + * ``` * - * The common parent 'Group' is removed. + * The common parent `Group` is removed. + * + * @param[in,out] subname The subname reference to the object that is to be + * assigned a link on input. On output, the reference may be offset to get + * rid of any common parent. + * + * @param[in,out] link The top parent of the link reference on input. On + * output, it may be altered to one of its children to get rid of any + * common parent. + * + * @param[in,out] linkSub The subname of the link reference on input. On + * output, it may be offset to get rid of any common parent. + * + * @return The corrected top parent of the object that is to be assigned + * the link. If the output @p subname is empty, then the object + * itself is returned. */ App::DocumentObject* resolveRelativeLink(std::string& subname, App::DocumentObject*& link, std::string& linkSub) const; - /** Called to adjust link properties to avoid cyclic links - * - * @param inList: the recursive in-list of the future parent object, - * including the parent itself. - * @param visited: optional set holding the visited objects. If null then - * only this object is adjusted, or else all object inside the out-list of - * this object will be checked. - * - * @return Return whether the object has been modified + /** + * @brief Adjust relative link properties to avoid cyclic links. * * This function tries to adjust any relative link properties (i.e. link - * properties that can hold subnames) to avoid cyclic when added to the - * future parent. + * properties that can hold subnames) to avoid cycles between links when + * added to the future parent. + * + * @param[in] inList The recursive in-list of the future parent object, + * including the parent itself. + * + * @param[in,out] visited An optional set holding the visited objects. If + * null then only this object is adjusted, or else all objects inside the + * out-list of this object will be checked. + * + * @return True if the object has been modified, false otherwise. */ virtual bool adjustRelativeLinks(const std::set& inList, std::set* visited = nullptr); - /** allow partial loading of dependent objects + /** + * @brief Check whether the object allows partial loading of dependent objects. * - * @return Returns 0 means do not support partial loading. 1 means allow - * dependent objects to be partially loaded, i.e. only create, but not - * restored. 2 means this object itself can be partially loaded. + * The possible return values are: + * - 0: Do not support partial loading. + * - 1: Allow dependent objects to be partially loaded, i.e. only create them, but do not + * restore them. + * - 2: This object itself can be partially loaded. + * + * @return Whether the object supports partial loading. */ virtual int canLoadPartial() const { return 0; } - virtual void onUpdateElementReference(const Property*) + /** + * @brief Called when an element reference is updated. + * + * @param[in] prop The property that was updated. + */ + virtual void onUpdateElementReference([[maybe_unused]] const Property* prop) {} - /** Allow object to redirect a subname path - * - * @param ss: input as the current subname path from \a topParent leading - * just before this object, i.e. ends at the parent of this object. This - * function should append its own name to this path, or redirect the - * subname to other place. - * @param topParent: top parent of this subname path - * @param child: the immediate child object in the path + /** + * @brief Allow an object to redirect a subname path. * * This function is called by tree view to generate a subname path when an - * item is selected in the tree. Document object can use this function to - * redirect the selection to some other objects. + * item is selected in the tree. A document object can use this function + * to redirect the selection to some other object. + * + * @param[in,out] ss The current subname path from @p topParent leading to + * just before this object as input, i.e. ends at the parent of this + * object. As output, this method should append its own name to this path, or + * redirect the subname to another place. + * + * @param[in] topParent The top parent of this subname path. + * @param[in] child The immediate child object in the path. + * + * @return true if the subname was redirected, false otherwise. */ virtual bool redirectSubName(std::ostringstream& ss, DocumentObject* topParent, DocumentObject* child) const; - /** Special marker to mark the object as hidden + /** + * @brief A special marker to mark the object as hidden. * * It is used by Gui::ViewProvider::getElementColors(), but exposed here - * for convenience + * for convenience. + * + * @return A string that is used to mark the object as hidden. */ static const std::string& hiddenMarker(); - /// Check if the subname reference ends with hidden marker. + + /** + * @brief Check if the subname reference ends with hidden marker. + * + * @param[in] subname The subname to check. + * + * @return A pointer to the hidden marker if it is found, or nullptr if not. + */ static const char* hasHiddenMarker(const char* subname); - /* Find the placement of a target object as seen from this. - If no targetObj given, the last object found in the subname is used as target. - */ + /** + * @brief Find the placement of a target object as seen from this. + * + * If no targetObj given, the last object found in the subname is used as + * target. + * + * @param[in] sub The subname that is targeted. + * @param[in] targetObj The object that is targeted. + * + * @return The placement of the target object from the perspective of this + * object. + */ virtual Base::Placement getPlacementOf(const std::string& sub, DocumentObject* targetObj = nullptr); - /* Returns the Placement property value if any.*/ + /// Returns the Placement property value if any. virtual Base::Placement getPlacement() const; - /* Returns the Placement property to use if any*/ + /// Returns the Placement property to use if any. virtual App::PropertyPlacement* getPlacementProperty() const; protected: - /// recompute only this object + /// Recompute only this object. virtual App::DocumentObjectExecReturn* recompute(); - /** get called by the document to recompute this feature - * Normally this method get called in the processing of - * Document::recompute(). - * In execute() the output properties get recomputed - * with the data from linked objects and objects own - * properties. + + /** + * @brief Execute the document object. + * + * In some contexts this is called "invoking" the object. It is called by + * the document to recompute this feature, normally in the processing of + * Document::recompute(). In this method, the output properties get + * recomputed with the data from linked objects and the properties from the + * object itself. + * + * @return On success, A pointer to StdReturn is returned which is set to + * `nullptr`. On failure, it returns a pointer to a newly created + * App::DocumentObjectExecReturn that containss the error message. */ virtual App::DocumentObjectExecReturn* execute(); /** - * Executes the extensions of a document object. + * @brief Executes the extensions of a document object. + * + * @sa recompute() */ App::DocumentObjectExecReturn* executeExtensions(); - /** Status bits of the document object - * The first 8 bits are used for the base system the rest can be used in - * descendent classes to mark special statuses on the objects. - * The bits and their meaning are listed below: - * 0 - object is marked as 'touched' - * 1 - object is marked as 'erroneous' - * 2 - object is marked as 'new' - * 3 - object is marked as 'recompute', i.e. the object gets recomputed now - * 4 - object is marked as 'restoring', i.e. the object gets loaded at the moment - * 5 - object is marked as 'deleting', i.e. the object gets deleted at the moment - * 6 - reserved - * 7 - reserved - * 16 - object is marked as 'expanded' in the tree view + /** + * @brief Status bits of the document object. + * + * For the status bits, see ObjectStatus. */ std::bitset<32> StatusBits; + /// Set this object in the error state. void setError() { StatusBits.set(ObjectStatus::Error); } + + /// Reset the error state of this object. void resetError() { StatusBits.reset(ObjectStatus::Error); } + + /// Set the document this object belongs to. void setDocument(App::Document* doc); - /// get called before the value is changed void onBeforeChange(const Property* prop) override; - /// get called by the container when a property was changed void onChanged(const Property* prop) override; - /// get called by the container when a property was changed void onEarlyChange(const Property* prop) override; - /// get called after a document has been fully restored + + /// Called after a document has been fully restored. virtual void onDocumentRestored(); - /// get called after an object finishes restoreContent. + void restoreFinished() override; - /// get called after an undo/redo transaction is finished + + /// Called after an undo/redo transaction has finished. virtual void onUndoRedoFinished(); - /// get called after setting the document + + /// Called after setting the document. virtual void onSettingDocument(); - /// get called after a brand new object was created + + /// Called after a brand new object was created. virtual void setupObject(); - /// get called when object is going to be removed from the document + + /// Called when object is going to be removed from the document. virtual void unsetupObject(); - /// get called when a property status has changed + /** + * @brief Called when a property status has changed. + * + * @param[in] prop The property of which the status has changed. + * @param[in] oldStatus The old status of the property. + */ void onPropertyStatusChanged(const Property& prop, unsigned long oldStatus) override; private: void printInvalidLinks() const; - /// python object of this class and all descendent protected: // attributes + + /// Python object of this class and all descendent classes. Py::SmartPtr PythonObject; - /// pointer to the document this object belongs to + + /// A pointer to the document this object belongs to. App::Document* _pDoc {nullptr}; - /// Old label; used for renaming expressions + /// The old label that is used for renaming expressions. std::string oldLabel; private: diff --git a/src/App/DocumentObjectExtension.h b/src/App/DocumentObjectExtension.h index 32f1500816..f8030db4d8 100644 --- a/src/App/DocumentObjectExtension.h +++ b/src/App/DocumentObjectExtension.h @@ -97,10 +97,31 @@ public: */ virtual bool extensionGetSubObjects(std::vector& ret, int reason) const; - /** Get the linked object - * @sa DocumentObject::getLinkedObject() + /** + * @brief Get the linked object of this extension. * - * @return Return turn if handled, the linked object is returned in \c ret + * This method returns the linked object of this document object. If there + * is no linked object, it will return the container object of the + * extension. + * + * @param[out] ret The linked object is returned in this parameter. + * + * @param[in] recurse If true, it will recursively resolve the link until it + * reaches the final linked object. + * + * @param mat[in,out] 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[in] transform If false, then it will not accumulate the object's own + * placement into @p mat, which lets you override the object's placement. + * + * @param[in] depth This parameter indicates the level on which we are + * resolving the link. + * + * @return Returns true if the linked object is successfully retrieved and + * returned in @p ret. If the linked object is not found or is invalid, it + * returns false. */ virtual bool extensionGetLinkedObject(DocumentObject*& ret, bool recursive, diff --git a/src/App/Link.h b/src/App/Link.h index 11c02633e3..b1cae01ddb 100644 --- a/src/App/Link.h +++ b/src/App/Link.h @@ -341,6 +341,17 @@ public: const char* flattenSubname(const char* subname) const; void expandSubname(std::string& subname) const; + /** + * @brief Get the object the link points to. + * + * This method returns the linked object of this link. The @p depth + * parameter is used as an indication of how deep the recursion is as a + * safeguard against infinite recursion caused by cyclic dependencies. + * + * @param[in] depth The level on which we are resolving the link. + * + * @return Returns the linked object or @c nullptr if there is no linked value. + */ DocumentObject* getLink(int depth = 0) const; Base::Matrix4D getTransform(bool transform) const; @@ -403,6 +414,33 @@ public: const char* subname = nullptr, const std::vector& subs = std::vector()); + /** + * @brief Get the true linked object. + * + * This method returns the true linked object, which is the object that the + * link points to. The @p depth parameter is used as an indication of the + * current level of recursion is as a safeguard against infinite recursion + * caused by cyclic dependencies. + * + * @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. + * + * @sa DocumentObject::getLinkedObject() which may return itself if it is not a link. + * + */ DocumentObject* getTrueLinkedObject(bool recurse, Base::Matrix4D* mat = nullptr, int depth = 0, diff --git a/src/App/PropertyExpressionEngine.h b/src/App/PropertyExpressionEngine.h index 3edb835c12..b1d83e0a56 100644 --- a/src/App/PropertyExpressionEngine.h +++ b/src/App/PropertyExpressionEngine.h @@ -100,7 +100,6 @@ public: /** * @brief The ExpressionInfo struct encapsulates an expression. */ - struct ExpressionInfo { std::shared_ptr expression; /**< The actual expression tree */ diff --git a/src/App/PropertyLinks.h b/src/App/PropertyLinks.h index 973cfdd0e3..a0af06530d 100644 --- a/src/App/PropertyLinks.h +++ b/src/App/PropertyLinks.h @@ -262,14 +262,20 @@ public: return nullptr; } - /** Update object label reference in this property + /** + * @brief Update the object label reference of this property. * - * @param obj: the object owner of the changing label - * @param ref: subname reference to old label - * @param newLabel: the future new label + * This method does not update the property itself, but returns a copy of + * the property with the updated label reference if the property is + * affected. The copy will later be assigned to this property by calling its + * Paste() method. * - * @return Returns a copy of the property if its link reference is affected. - * The copy will later be assgiend to this property by calling its Paste(). + * @param[in] obj The object owner of the changing label. + * @param[in] ref The subname reference to old label. + * @param[in] newLabel The future new label. + * + * @return A copy of the property if its link reference is affected, + * otherwise `nullptr`. */ virtual Property* CopyOnLabelChange(App::DocumentObject* obj, const std::string& ref, const char* newLabel) const @@ -556,13 +562,17 @@ public: */ static void getLabelReferences(std::vector& labels, const char* subname); - /** Helper function to collect changed property when an object re-label + /** + * @brief Update label references on label change of a document object. * - * @param obj: the object that owns the label - * @param newLabel: the new label + * This helper function collects changed properties when an object re-label + * takes place. It returns a map from affected properties to copies of + * those affectedd propertiess with updated subname references. * - * @return return a map from the affected property to a copy of it with - * updated subname references + * @param[in] obj The object that owns the label that is changed. + * @param[in] newLabel The new label of the object. + * + * @return The map from affected property to a copy of it. */ static std::vector>> updateLabelReferences(App::DocumentObject* obj, const char* newLabel);