diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 0e63148238..14d2c51c58 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -1251,12 +1251,12 @@ constexpr auto fcAttrDepObjName {"Name"}; constexpr auto fcAttrDepAllowPartial {"AllowPartial"}; constexpr auto fcElementObjectDep {"Dep"}; -void Document::writeObjects(const std::vector& obj, +void Document::writeObjects(const std::vector& objs, Base::Writer& writer) const { // writing the features types writer.incInd(); // indentation for 'Objects count' - writer.Stream() << writer.ind() << "& obj, writer.incInd(); // indentation for 'Object type' if (isExporting(nullptr) == 0U) { - for (const auto o : obj) { + for (const auto o : objs) { const auto& outList = o->getOutList(DocumentObject::OutListNoHidden | DocumentObject::OutListNoXLinked); writer.Stream() << writer.ind() @@ -1294,7 +1294,7 @@ void Document::writeObjects(const std::vector& obj, } std::vector::const_iterator it; - for (it = obj.begin(); it != obj.end(); ++it) { + for (it = objs.begin(); it != objs.end(); ++it) { writer.Stream() << writer.ind() << "getTypeId().getName() << "\" " << "name=\"" << (*it)->getExportName() << "\" " @@ -1324,10 +1324,10 @@ void Document::writeObjects(const std::vector& obj, writer.Stream() << writer.ind() << "" << '\n'; // writing the features itself - writer.Stream() << writer.ind() << "" << '\n'; + writer.Stream() << writer.ind() << "" << '\n'; writer.incInd(); // indentation for 'Object name' - for (it = obj.begin(); it != obj.end(); ++it) { + for (it = objs.begin(); it != objs.end(); ++it) { writer.Stream() << writer.ind() << "getExportName() << "\""; if ((*it)->hasExtensions()) { writer.Stream() << " Extensions=\"True\""; @@ -2036,11 +2036,11 @@ bool Document::afterRestore(const std::vector& objArray, bool c return false; } - // some link type property cannot restore link information until other - // objects has been restored. For example, PropertyExpressionEngine and - // PropertySheet with expression containing label reference. So we add the - // Property::afterRestore() interface to let them sort it out. Note, this - // API is not called in object dedpenency order, because the order + // Some link type properties cannot restore link information until other + // objects have been restored. For example, PropertyExpressionEngine and + // PropertySheet with expressions containing a label reference. So we add + // the Property::afterRestore() interface to let them sort it out. Note, + // this API is not called in object dependency order, because the order // information is not ready yet. std::map> propMap; for (auto obj : objArray) { @@ -2228,7 +2228,7 @@ vector Document::getTouched() const return result; } -void Document::setClosable(const bool c) // NOLINT +void Document::setClosable(bool c) // NOLINT { setStatus(Document::Closable, c); } @@ -2508,7 +2508,7 @@ std::vector Document::getDependentDocuments(const bool sort) } std::vector Document::getDependentDocuments(std::vector docs, - const bool sort) + const bool sort) { DependencyList depList; std::map docMap; @@ -2572,11 +2572,6 @@ std::vector Document::getDependentDocuments(std::vector do return ret; } -void Document::_rebuildDependencyList(const std::vector& objs) -{ - (void)objs; -} - /** * @brief Signal that object identifiers, typically a property or document object has been renamed. * @@ -3144,15 +3139,15 @@ Document::addObjects(const char* sType, const std::vector& objectNa return objects; } -void Document::addObject(DocumentObject* pcObject, const char* pObjectName) +void Document::addObject(DocumentObject* obj, const char* name) { - if (pcObject->getDocument()) { + if (obj->getDocument()) { throw Base::RuntimeError("Document object is already added to a document"); } - pcObject->setDocument(this); + obj->setDocument(this); - _addObject(pcObject, pObjectName, AddObjectOption::SetNewStatus | AddObjectOption::ActivateObject); + _addObject(obj, name, AddObjectOption::SetNewStatus | AddObjectOption::ActivateObject); } void Document::_addObject(DocumentObject* pcObject, const char* pObjectName, AddObjectOptions options, const char* viewType) diff --git a/src/App/Document.h b/src/App/Document.h index 536f3d8a46..7a647d2b50 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -48,7 +48,7 @@ namespace Base class Writer; } -namespace App +namespace App { enum class AddObjectOption { @@ -64,9 +64,9 @@ using AddObjectOptions = Base::Flags; enum class RemoveObjectOption { None = 0, - MayRemoveWhileRecomputing = 1, + MayRemoveWhileRecomputing = 1, MayDestroyOutOfTransaction = 2, - DestroyOnRollback = 4, + DestroyOnRollback = 4, PreserveChildrenVisibility = 8 }; using RemoveObjectOptions = Base::Flags; @@ -88,7 +88,12 @@ class StringHasher; using StringHasherRef = Base::Reference; /** - * @brief The document class + * @brief A class that represents a FreeCAD document. + * + * A document is a container for all objects that are part of a FreeCAD + * project. Besides managing the objects, it also maintains properties itself. + * As such, it is also a PropertyContainer. + * * @ingroup DocumentGroup * @details For a more high-level discussion see the topic @ref DocumentGroup "Document". */ @@ -98,165 +103,300 @@ class AppExport Document: public PropertyContainer public: // clang-format off + /// Defines the position of the status bits for documents. enum Status { + /// Avoid recomputing the document. SkipRecompute = 0, + /// Keep trailing digits in the object names when reading objects. KeepTrailingDigits = 1, + /// Whether the document can be closed. Closable = 2, + /// Whether the document is currently being restored. Restoring = 3, + /// Whether the document is currently recomputing. Recomputing = 4, + /** Whether the document is being partially restored, + * typically meaning that there was an error. + */ PartialRestore = 5, + /// Whether the document is currently importing objects. Importing = 6, + /** Whether the document is a partial document, + * meaning that it is not fully loaded. + */ PartialDoc = 7, - AllowPartialRecompute = 8, // allow recomputing editing object if SkipRecompute is set - TempDoc = 9, // Mark as temporary document without prompt for save + /// Whether only the editing or active object is recomputed if SkipRecompute is set. + AllowPartialRecompute = 8, + /// Whether the document is a temporary document, meaning that it is not saved to a file. + TempDoc = 9, + /// Whether the document has an error during restore. RestoreError = 10, - LinkStampChanged = 11, // Indicates during restore time if any linked document's time stamp has changed - IgnoreErrorOnRecompute = 12, // Don't report errors if the recompute failed - RecomputeOnRestore = 13, // Mark pending recompute on restore for migration purposes - MigrateLCS = 14 // Migrate local coordinate system of older versions + /// Whether any linked document's time stamp has changed during restore time. + LinkStampChanged = 11, + /// Whether errors are reported if the recompute failed. + IgnoreErrorOnRecompute = 12, + /// Whether a recompute is necessary on restore for migration purposes. + RecomputeOnRestore = 13, + /// Whether the local coordinate system of older versions should be migrated. + MigrateLCS = 14 }; // clang-format on // NOLINTBEGIN - /** @name Properties */ - //@{ - /// holds the long name of the document (utf-8 coded) + /** @name Properties + * @{ + */ + + /// The long name of the document (utf-8 coded). PropertyString Label; - /// full qualified (with path) file name (utf-8 coded) + + /// The fully qualified (with path) file name (utf-8 coded). PropertyString FileName; - /// creators name (utf-8) + + /// The creator's name (utf-8). PropertyString CreatedBy; + /// The date when the document was created. PropertyString CreationDate; - /// user last modified the document + /// The user that last modified the document. PropertyString LastModifiedBy; + /// The date when the document was last modified. PropertyString LastModifiedDate; - /// company name UTF8(optional) + /// The company name (utf-8, optional). PropertyString Company; - /// Unit System + /// The Unit System for this document. PropertyEnumeration UnitSystem; - /// long comment or description (UTF8 with line breaks) + /// A long comment or description (utf-8 with line breaks). PropertyString Comment; - /// Id e.g. Part number + /// The Id, e.g. a Part number. PropertyString Id; - /// unique identifier of the document + /// A unique identifier of the document. PropertyUUID Uid; - /// Full name of the licence e.g. "Creative Commons Attribution". See https://spdx.org/licenses/ + /// The full name of the licence e.g. "Creative Commons Attribution". See https://spdx.org/licenses/. PropertyString License; - /// License description/contract URL + /// The URL to the license description or contract. PropertyString LicenseURL; - /// Meta descriptions + /// Meta descriptions. PropertyMap Meta; /// Material descriptions, used and defined in the Material module. PropertyMap Material; - /// read-only name of the temp dir created when the document is opened + /// Read-only name of the temp dir created when the document is opened. PropertyString TransientDir; - /// Tip object of the document (if any) + /// Tip object of the document (if any). PropertyLink Tip; - /// Tip object of the document (if any) + /// Tip object name of the document (if any). PropertyString TipName; - /// Whether to show hidden items in TreeView + /// Whether to show hidden items in TreeView. PropertyBool ShowHidden; - /// Whether to use hasher on topological naming + /// Whether to use hasher on topological naming. PropertyBool UseHasher; - //@} + /// @} - /** @name Signals of the document */ - //@{ + /** @name Signals of the document + * @{ + */ // clang-format off - /// signal before changing an doc property + + /// Signal before changing a document property. fastsignals::signal signalBeforeChange; - /// signal on changed doc property + /// Signal on a changed document property. fastsignals::signal signalChanged; - /// signal on new Object + /// Signal on new object. fastsignals::signal signalNewObject; - /// signal on deleted Object + /// Signal on a deleted object. fastsignals::signal signalDeletedObject; - /// signal before changing an Object + /// Signal before changing an object. fastsignals::signal signalBeforeChangeObject; - /// signal on changed Object + /// Signal on a changed object. fastsignals::signal signalChangedObject; - /// signal on manually called DocumentObject::touch() + /// Signal on a manually called DocumentObject::touch(). fastsignals::signal signalTouchedObject; - /// signal on relabeled Object + /// Signal on relabeled object. fastsignals::signal signalRelabelObject; - /// signal on activated Object + /// Signal on an activated object. fastsignals::signal signalActivatedObject; - /// signal on created object + /// Signal on a created object. fastsignals::signal signalTransactionAppend; - /// signal on removed object + /// Signal on a removed object. fastsignals::signal signalTransactionRemove; - /// signal on undo + /// Signal on undo. fastsignals::signal signalUndo; - /// signal on redo + /// Signal on redo. fastsignals::signal signalRedo; - /** signal on load/save document - * this signal is given when the document gets streamed. - * you can use this hook to write additional information in - * the file (like the Gui::Document does). + + /** + * @brief Signal on load/save document. + * + * This signal is given when the document gets streamed. You can use this + * hook to write additional information in the file (like Gui::Document + * does). */ fastsignals::signal signalSaveDocument; + /// Signal on restoring a document. fastsignals::signal signalRestoreDocument; + /// Signal on exporting objects. fastsignals::signal&, Base::Writer&)> signalExportObjects; + /// Signal on exporting view objects. fastsignals::signal&, Base::Writer&)> signalExportViewObjects; + /// Signal on importing objects. fastsignals::signal&, Base::XMLReader&)> signalImportObjects; + /// Signal on importing view objects. fastsignals::signal&, Base::Reader&, const std::map&)> signalImportViewObjects; + /// Signal after finishing importing objects. fastsignals::signal&)> signalFinishImportObjects; - // signal starting a save action to a file + /// Signal starting a save action to a file. fastsignals::signal signalStartSave; - // signal finishing a save action to a file + /// Signal finishing a save action to a file. fastsignals::signal signalFinishSave; + /// Signal before recomputing the document. fastsignals::signal signalBeforeRecompute; + /// Signal after recomputing the document. fastsignals::signal&)> signalRecomputed; + /// Signal after recomputing an object. fastsignals::signal signalRecomputedObject; - // signal a new opened transaction + /// Signal on a new opened transaction. fastsignals::signal signalOpenTransaction; - // signal a committed transaction + /// Signal on a committed transaction. fastsignals::signal signalCommitTransaction; - // signal an aborted transaction + /// Signal on an aborted transaction. fastsignals::signal signalAbortTransaction; + /// Signal on a skipping a recompute. fastsignals::signal&)> signalSkipRecompute; + /// Signal on finishing restoring an object. fastsignals::signal signalFinishRestoreObject; + /// Signal on a changed property in the property editor. fastsignals::signal signalChangePropertyEditor; + /// Signal on setting a value in an external link. fastsignals::signal signalLinkXsetValue; + // clang-format on - //@} + /// @} // NOLINTEND using PreRecomputeHook = std::function; + + /** @brief Set a hook for before a recompute. + * + * @param[in] hook: The function to be called before a recompute. + */ void setPreRecomputeHook(const PreRecomputeHook& hook); + /// Clear the document of all its administration. void clearDocument(); - /** @name File handling of the document */ - //@{ - /// Save the Document under a new Name - // void saveAs (const char* Name); + /** @name File handling of the document + * @{ + */ + /// Save the document to the file in Property Path bool save(); + + /** + * @brief Save the document to a specified file. + * + * @param[in] file: The file name to save the document to. + */ bool saveAs(const char* file); + + /** + * @brief Save a copy of the document to a specified file. + * + * @param[in] file: The file name to save the copy to. + */ bool saveCopy(const char* file) const; - /// Restore the document from the file in Property Path + + /** + * @brief Restore the document from the file in Property Path. + * + * @param[in] filename: The file name to restore the document from. If nullptr, then + * use the file name in property 'FileName'. + * @param[in] delaySignal: if true, the signals for restored objects are delayed until + * all objects are restored. + * @param[in] objNames: if not empty, only restore the objects with these + * names. This is useful to partially restore a document. If empty, + * restore all objects in the document. + */ void restore(const char* filename = nullptr, bool delaySignal = false, const std::vector& objNames = {}); + + /** + * @brief Called after a document is restored. + * + * This function can be delayed in restore() if `delaySignal` is true. + * + * @param[in] checkPartial: Check if the document is partially loaded. + * + * @returns True if the document is restored. Returning false means that + * the document must have a full reload. + */ bool afterRestore(bool checkPartial = false); - bool afterRestore(const std::vector&, bool checkPartial = false); + + /** + * @brief Called after a document is restored to check a list of objects. + * + * @param[in] checkPartial: Check if the document is partially loaded. + * @param[in] objs: The list of objects to check. + * + * @returns True if the document is restored. Returning false means that + * the document must have a full reload. + */ + bool afterRestore(const std::vector& objs, bool checkPartial = false); + + /// The status of export. enum ExportStatus { NotExporting, Exporting, }; + + /** + * @brief Check if an object is being exported. + * @param[in] obj: The object to check. + * @return The export status. + */ ExportStatus isExporting(const DocumentObject* obj) const; + + /// Get the export info. ExportInfo exportInfo() const; - void setExportInfo(const ExportInfo& info); - void exportObjects(const std::vector&, std::ostream&); - void exportGraphviz(std::ostream&) const; - std::vector importObjects(Base::XMLReader& reader); - /** Import any externally linked objects + + /** + * @brief Set the export info in this document. * - * @param objs: input list of objects. Only objects belonging to this document will + * @param[in] info: The export info to set. + */ + void setExportInfo(const ExportInfo& info); + + /** + *@brief Export a list of objects to a stream. + * + * @param[in] objs: The list of objects to export. + * @param[in, out] out: The output stream to write to. + */ + void exportObjects(const std::vector& objs, std::ostream& out); + + /** + * @brief Write the dependency graph of this document. + * + * The output is in the DOT format of Graphviz. + * + * @param[in, out] out: The output stream to write to. + */ + void exportGraphviz(std::ostream& out) const; + + /** + * @brief Import objects from a stream. + * + * @param[in, out] reader: The XML reader to read from. + * @return The list of imported objects. + */ + std::vector importObjects(Base::XMLReader& reader); + + /** + * @brief Import any externally linked objects + * + * @param[in] objs: input list of objects. Only objects belonging to this document will * be checked for external links. And all found external linked object will be imported * to this document. Link type properties of those input objects will be automatically * reassigned to the imported objects. Note that the link properties of other objects @@ -266,96 +406,144 @@ public: * * @return the list of imported objects */ - std::vector - importLinks(const std::vector& objs = {}); - /// Opens the document from its file name + std::vector importLinks(const std::vector& objs = {}); + + // Opens the document from its file name // void open (void); - /// Is the document already saved to a file? + + /// Check if the document has been saved. bool isSaved() const; - /// Get the document name + + /// Get the document name. const char* getName() const; - /// Get program version the project file was created with + + /// Get program version the project file was created with. const char* getProgramVersion() const; - /** Returned filename + + /** + * @brief Get the filename of the document. * - * For saved document, this will be the content stored in property - * 'Filename'. For unsaved temporary file, this will be the content of - * property 'TransientDir'. + * @return For a saved document, this will be the content stored in + * property 'Filename'. For an unsaved temporary file, this will be the + * content of property 'TransientDir'. */ const char* getFileName() const; - //@} + /// @} void Save(Base::Writer& writer) const override; void Restore(Base::XMLReader& reader) override; - /// returns the complete document memory consumption, including all managed DocObjects and Undo - /// Redo. unsigned int getMemSize() const override; - /** @name Object handling */ - //@{ - /** Add a feature of sType with sName (ASCII) to this document and set it active. - * Unicode names are set through the Label property. - * @param sType the type of created object - * @param pObjectName if nonNULL use that name otherwise generate a new unique name based on the - * \a sType - * @param isNew if false don't call the \c DocumentObject::setupObject() callback (default - * is true) - * @param viewType override object's view provider name - * @param isPartial indicate if this object is meant to be partially loaded + /** @name Object handling + * @{ + */ + + /** + * @brief Add an object of given type to the document. + * + * Add an object of given type with @p pObjectName that should be ASCII to + * this document and set it active. Unicode names are set through the + * Label property. + * + * @param[in] sType the type of created object + * @param[in] pObjectName if `nullptr` generate a new unique name based on @p + * sType, otherwise use this name. + * @param[in] isNew if false don't call the DocumentObject::setupObject() + * callback (default is true) + * @param[in] viewType override the object's view provider name + * @param[in] isPartial indicate if this object is meant to be partially loaded + * + * @return The newly added object. */ DocumentObject* addObject(const char* sType, const char* pObjectName = nullptr, bool isNew = true, const char* viewType = nullptr, bool isPartial = false); - //@{ - /** Add a feature of T type with sName (ASCII) to this document and set it active. - * Unicode names are set through the Label property. - * @param pObjectName if nonNULL use that name otherwise generate a new unique name based on the - * \a sType - * @param isNew if false don't call the \c DocumentObject::setupObject() callback (default - * is true) - * @param viewType override object's view provider name - * @param isPartial indicate if this object is meant to be partially loaded + + /** + * @brief Add an object of a given type to the document. + * + * Add an object of of a given type with @p pObjectName that should be + * ASCII to this document and set it active. Unicode names are set through + * the Label property. + * + * @tparam T The type of created object. + * @param[in] pObjectName if `nullptr` generate a new unique name based on @p + * T, otherwise use this name. + * @param[in] isNew if `false don't call the DocumentObject::setupObject() + * callback (default * is true) + * @param[in] viewType override object's view provider name + * @param[in] isPartial indicate if this object is meant to be partially loaded + * + * @return The newly added object. */ template T* addObject(const char* pObjectName = nullptr, bool isNew = true, const char* viewType = nullptr, bool isPartial = false); - /** Add an array of features of the given types and names. - * Unicode names are set through the Label property. - * @param sType The type of created object - * @param objectNames A list of object names - * @param isNew If false don't call the \c DocumentObject::setupObject() callback (default - * is true) + + /** + * @brief Add multiple objects of a given type to the document. + * + * Add multiple objects of a given type with @p objectNames that should be + * ASCII to this document. Unicode names are set through the Label + * property. + * + * @param[in] sType The type of created object + * @param[in] objectNames A list of object names + * @param[in] isNew If false don't call the DocumentObject::setupObject() + * callback (default is true) */ std::vector addObjects(const char* sType, const std::vector& objectNames, bool isNew = true); - /// Remove a feature out of the document - void removeObject(const char* sName); - /** Add an existing feature with sName (ASCII) to this document and set it active. - * Unicode names are set through the Label property. - * This is an overloaded function of the function above and can be used to create - * a feature outside and add it to the document afterwards. - * \note The passed feature must not yet be added to a document, otherwise an exception - * is raised. + + /** + * @brief Remove an object from the document. + * + * @param[in] sName The name of the object to remove. */ - void addObject(DocumentObject*, const char* pObjectName = nullptr); + void removeObject(const char* sName); - /// returns whether this is actually contains the DocumentObject. - /// Testing the DocumentObject's pDoc pointer is not sufficient because the object - /// removeObject and _removeObject leave _pDoc unchanged - bool containsObject(const DocumentObject*) const; + /** + * @brief Add an existing object to the document. + * + * Add an existing feature with @p pObjectName (ASCII) to this document and set it active. + * Unicode names are set through the Label property. + * + * This is an overloaded function of the function above and can be used to + * create a feature outside and add it to the document afterwards. + * + * @param[in] obj The object to add. + * @param[in] name if `nullptr` generate a new unique name based on @p + * this name. + * + * @throws Base::RuntimeError If the object is already in the document. + */ + void addObject(DocumentObject* obj, const char* name = nullptr); - /** Copy objects from another document to this document + /** + * @brief Check whether the document contains a document object. * - * @param objs - * @param recursive: if true, then all objects this object depends on are - * copied as well. By default \a recursive is false. + * @note Testing the @c DocumentObject's @c pDoc pointer is not sufficient + * because removeObject() leaves @c _pDoc unchanged. * - * @param returnAll: if true, return all copied objects including those + * @param[in] pcObject The object to check. + * + * @return Returns true if the object is in this document, false otherwise. + */ + bool containsObject(const DocumentObject* pcObject) const; + + /** + * @brief Copy objects from another document to this document. + * + * @param[in] objs The objects to copy. + * @param[in] recursive if true, then all objects this object depends on are + * copied as well. By default @a recursive is false. + * + * @param[in] returnAll: if true, return all copied objects including those * auto included by recursive searching. If false, then only return the * copied object corresponding to the input objects. * @@ -364,250 +552,639 @@ public: std::vector copyObject(const std::vector& objs, bool recursive = false, bool returnAll = false); - /** Move an object from another document to this document - * If \a recursive is true then all objects this object depends on - * are moved as well. By default \a recursive is false. - * Returns the moved object itself or 0 if the object is already part of this - * document.. + + /** + * @brief Move an object from another document to this document. + * + * @param[in] obj The object to move. + * @param[in] recursive If true then all objects this object depends on + * are moved as well. By default @a recursive is false. + * + * @returns The moved object itself or `nullptr` if the object is already part of this + * document. */ DocumentObject* moveObject(DocumentObject* obj, bool recursive = false); - /// Returns the active Object of this document + + /// Get the active Object of this document. DocumentObject* getActiveObject() const; - /// Returns a Object of this document + + /** + * @brief Get the object with the given name. + * + * @param[in] Name The name of the object to get. + * + * @return The document object with the given name or `nullptr` if no such + * object exists. + */ DocumentObject* getObject(const char* Name) const; - /// Returns a Object of this document by its id + + /** + * @brief Get the object with the given id. + * + * @param[in] id The id of the object to get. + * @return The document object with the given id or `nullptr` if no such + * object exists. + */ DocumentObject* getObjectByID(long id) const; - /// Returns true if the DocumentObject is contained in this document + + /** + * @brief Check whether the object is in this document. + * + * @param[in] pFeat The object to check. + * @return Returns true if the object is in this document, false otherwise. + */ bool isIn(const DocumentObject* pFeat) const; - /// Returns a Name of an Object or 0 - const char *getObjectName(const DocumentObject* pFeat) const; - /// Returns a Name for a new Object or empty if proposedName is null or empty. + + /** + * @brief Get the name of an object. + * + * @param[in] pFeat The object to get the name of. + * + * @return The name of the object or `nullptr` if the object is not in this document. + */ + const char* getObjectName(const DocumentObject* pFeat) const; + + /** + * @brief Get a unique name for an object given a proposed name. + * + * @param[in] proposedName The proposed name for the object. + * + * @return A unique name for the object or an empty string if the proposed + * name is empty. + */ std::string getUniqueObjectName(const char* proposedName) const; - /// Returns a name different from any of the Labels of any objects in this document, based on the given modelName. - std::string getStandardObjectLabel(const char* modelName, int d) const; - /// Determine if a given DocumentObject Name and a proposed Label are based on the same base name + + /** + * @brief Get a unique label for an object. + * + * The name is different from any of the labels of any object in this + * document, based on the given modelname. + * + * @param[in] modelName The base name to use for generating the label. + * @param[in] digitCount The number of digits to use for the numeric suffix. + * + * @return A unique label for the object. + */ + std::string getStandardObjectLabel(const char* modelName, int digitCount) const; + + /** + * @brief Check if an object name and a label have the same base. + * + * Determine if a given DocumentObject Name and a proposed Label are based + * on the same base name. + * + * @param[in] name The object name. + * @param[in] label The proposed label. + * + * @return Returns true if the base names are the same, false otherwise. + */ bool haveSameBaseName(const std::string& name, const std::string& label); - /// Returns a list of document's objects including the dependencies + + /// Get a list of the document's objects including the dependencies. std::vector getDependingObjects() const; - /// Returns a list of all Objects + + /// Get a list of all document objects. const std::vector& getObjects() const; + + /** + * @brief Get all objects of a given type. + * + * @param[in] typeId The type to search for. + * @return A vector of objects of the given type. + */ std::vector getObjectsOfType(const Base::Type& typeId) const; + + /** + * @brief Get all objects of any of the given types. + * + * @param[in] types The types to search for. + * @return A vector of objects of any of the given types. + */ std::vector getObjectsOfType(const std::vector& types) const; - /// Returns all object with given extensions. If derived=true also all objects with extensions - /// derived from the given one + + /** + * @brief Get all objects with a given extension. + * + * @param[in] typeId The extension type to search for. + * @param[in] derived If true, also include objects with extensions + * derived from the given one. + * + * @return A vector of objects with the given extension. + */ std::vector getObjectsWithExtension(const Base::Type& typeId, bool derived = true) const; + + /** + * @brief Find objects by type, name, and label. + * + * Find the objects that match all criteria. It is possible to ignore the + * name or label. + * + * @param[in] typeId The type to search for. + * @param[in] objname The name of the object to search for, or `nullptr` to + * ignore searching for the name. + * @param[in] label The label of the object to search for, or `nullptr` to + * ignore searching for the label. + * + *@return A vector of objects matching the given criteria. + */ std::vector findObjects(const Base::Type& typeId, const char* objname, const char* label) const; - /// Returns an array with the correct types already. + + /** + * @brief Get all objects of a given type. + * + * @tparam T The type to search for. + * @return A vector of objects of the given type. + */ template inline std::vector getObjectsOfType() const; + + /** + * @brief Count the number of objects of a given type. + * + * @tparam T The type to search for. + * @return The number of objects of the given type. + */ template inline int countObjectsOfType() const; - int countObjectsOfType(const char* typeName) const; - /// get the number of objects in the document - int countObjects() const; - //@} - /** @name methods for modification and state handling - */ - //@{ - /// Remove all modifications. After this call The document becomes Valid again. - void purgeTouched(); - /// check if there is any touched object in this document - bool isTouched() const; - /// check if there is any object must execute in this document - bool mustExecute() const; - /// returns all touched objects - std::vector getTouched() const; - /// set the document to be closable, this is on by default. - void setClosable(bool); - /// check whether the document can be closed - bool isClosable() const; - /// set the document to autoCreated, this is off by default. - void setAutoCreated(bool); - /// check whether the document is autoCreated. - bool isAutoCreated() const; - /** Recompute touched features and return the number of recalculated features + /** + * @brief Count the number of objects of a given type. * - * @param objs: specify a sub set of objects to recompute. If empty, then - * all object in this document is checked for recompute - * @param force - * @param hasError - * @param options + * @param[in] typeName The name of the type to search for. + * @return The number of objects of the given type. + */ + int countObjectsOfType(const char* typeName) const; + + /// Get the number of objects in the document + int countObjects() const; + /// @} + + /** @name Methods for modification and state handling. + * @{ + */ + + /** + * @brief Remove all modifications. + * + * After this call The document becomes Valid again. + */ + void purgeTouched(); + + /// Check if there is any touched object in this document. + bool isTouched() const; + + /// Check if there is any object must execute in this document. + bool mustExecute() const; + + /// Get all touched objects. + std::vector getTouched() const; + + /** + * @brief Set the document to be closable. + * + * This is on by default. + */ + void setClosable(bool c); + + /// Check whether the document can be closed. + bool isClosable() const; + + /// Set the document to autoCreated, this is off by default. + void setAutoCreated(bool); + + /// Check whether the document is autoCreated. + bool isAutoCreated() const; + + /** + * @brief Recompute touched features. + * + * @param[in] objs The subset of objects to recompute. If empty, then all + * object in this document are checked to be recomputed. + * + * @param[in] force If true, force a recompute even if the document is + * marked to skip recomputes. + * @param[out] hasError If not `nullptr`, set to true if there was any error. + * @param[in] options A bitmask of DependencyOption. + * + * @returns The number of objects recomputed. */ int recompute(const std::vector& objs = {}, bool force = false, bool* hasError = nullptr, int options = 0); - /// Recompute only one feature - bool recomputeFeature(DocumentObject* Feat, bool recursive = false); - /// get the text of the error of a specified object - const char* getErrorDescription(const DocumentObject*) const; - /// return the status bits - bool testStatus(Status pos) const; - /// set the status bits - void setStatus(Status pos, bool on); - //@} - - /** @name methods for the UNDO REDO and Transaction handling + /** + * @brief Recompute a single object. * - * Introduce a new concept of transaction ID. Each transaction must be - * unique inside the document. Multiple transactions from different - * documents can be grouped together with the same transaction ID. + * @param[in] Feat The object to recompute. + * @param[in] recursive If true, then all objects depending on this object + * are recomputed as well. * - * When undo, Gui component can query getAvailableUndo(id) to see if it is - * possible to undo with a given ID. If there more than one undo - * transactions, meaning that there are other transactions before the given - * ID. The Gui component shall ask user if they want to undo multiple steps. - * And if the user agrees, call undo(id) to unroll all transaction before - * and including the one with the given ID. Same applies for redo. - * - * The new transaction ID describe here is fully backward compatible. - * Calling the APIs with a default id=0 gives the original behavior. + * @return True if the object was recomputed, false if there was an error. + */ + bool recomputeFeature(DocumentObject* Feat, bool recursive = false); + + /** + * @brief Get the text of the error for a specified object. + * @param[in] Obj The object to get the error text for. + * + * @return The error text, or `nullptr` if there is no error. + */ + const char* getErrorDescription(const DocumentObject* Obj) const; + + /** + * @brief Get the status of this document for a given status bit. + * + * @param[in] pos The status bit to check. + * @return The status of the given bit. + */ + bool testStatus(Status pos) const; + + /** + * @brief Set or unset a status bit of this document. + * + * @param[in] pos The status bit to set or unset. + * @param[in] on If true, set the bit, if false, unset the bit. + */ + void setStatus(Status pos, bool on); + /// @} + + + /** @name Methods for the Undo, Redo, and Transaction handling. + * + * The concept of a transaction ID ensures that each transaction is unique + * inside the document. Multiple transactions from different documents can + * be grouped together with the same transaction ID. + * + * When undoing, a Gui component can query getAvailableUndo(id) to see if + * it is possible to undo with a given ID. If there are more than one undo + * transactions, this means that there are other transactions before the + * given ID. The Gui component shall ask the user if they want to undo + * multiple steps. And if the user agrees, calling undo(id) unrolls all + * transactions before and including the one with the given ID. The same + * applies for redo. + * + * The transaction ID described here is fully backward compatible. Calling + * the APIs with a default id=0 gives the original behavior. + * + * @{ + */ + + /** + * @brief Set the level of Undo/Redo. + * + * A mode of 0 disables Undo/Redo completely, while a nonzero value turns + * it on. + * + * @param[in] iMode The Undo/Redo mode. */ - //@{ - /// switch the level of Undo/Redo void setUndoMode(int iMode); - /// switch the level of Undo/Redo + + /// Get the Undo/Redo mode. int getUndoMode() const; - /// switch the transaction mode + + /// Set the transaction mode. void setTransactionMode(int iMode); - /** Open a new command Undo/Redo, an UTF-8 name can be specified + + /** + * @brief Open a new command Undo/Redo. * - * @param name: transaction name + * A UTF-8 name can be specified. * - * This function calls Application::setActiveTransaction(name) instead - * to setup a potential transaction which will only be created if there is + * @param[in] name The transaction name. + * + * This function calls Application::setActiveTransaction(name) instead of + * setup a potential transaction that will only be created if there are * actual changes. */ void openTransaction(const char* name = nullptr); - /// Rename the current transaction if the id matches - void renameTransaction(const char* name, int id) const; - /// Commit the Command transaction. Do nothing If there is no Command transaction open. - void commitTransaction(); - /// Abort the actually running transaction. - void abortTransaction() const; - /// Check if a transaction is open - bool hasPendingTransaction() const; - /// Return the undo/redo transaction ID starting from the back - int getTransactionID(bool undo, unsigned pos = 0) const; - /// Check if a transaction is open and its list is empty. - /// If no transaction is open true is returned. - bool isTransactionEmpty() const; - /// Set the Undo limit in Byte! - void setUndoLimit(unsigned int UndoMemSize = 0); - /// Returns the actual memory consumption of the Undo redo stuff. - unsigned int getUndoMemSize() const; - /// Set the Undo limit as stack size - void setMaxUndoStackSize(unsigned int UndoMaxStackSize = 20); // NOLINT - /// Set the Undo limit as stack size - unsigned int getMaxUndoStackSize() const; - /// Remove all stored Undos and Redos - void clearUndos(); - /// Returns the number of stored Undos. If greater than 0 Undo will be effective. - int getAvailableUndos(int id = 0) const; - /// Returns a list of the Undo names - std::vector getAvailableUndoNames() const; - /// Will UNDO one step, returns False if no undo was done (Undos == 0). - bool undo(int id = 0); - /// Returns the number of stored Redos. If greater than 0 Redo will be effective. - int getAvailableRedos(int id = 0) const; - /// Returns a list of the Redo names. - std::vector getAvailableRedoNames() const; - /// Will REDO one step, returns False if no redo was done (Redos == 0). - bool redo(int id = 0); - /// returns true if the document is in an Transaction phase, e.g. currently performing a - /// redo/undo or rollback - bool isPerformingTransaction() const; - /// \internal add or remove property from a transactional object - void addOrRemovePropertyOfObject(TransactionalObject*, const Property* prop, bool add); - void renamePropertyOfObject(TransactionalObject*, const Property* prop, const char* newName); - //@} - /** @name dependency stuff */ - //@{ - /// write GraphViz file + /** + * @brief Rename the current transaction. + * + * Rename the current transaction if it matches the given ID. + * + * @param[in] name The new name of the transaction. + * @param[in] id The transaction ID to match. + */ + void renameTransaction(const char* name, int id) const; + + /** + * @brief Commit the Command transaction. + * + * Do nothing If there is no Command transaction open. + */ + void commitTransaction(); + + /// Abort the currently running transaction. + void abortTransaction() const; + + /// Check whether a transaction is open. + bool hasPendingTransaction() const; + + /** + * @brief Get the undo or redo transaction ID. + * + * Get the transaction ID starting from the back. + * + * @param[in] undo If true, get the undo transaction ID, if false get the + * redo transaction ID. + * @param[in] pos The position from the back, 0 is the last transaction, + * 1 is the one before last, and so on. + * + * @return The transaction ID, or 0 if @p pos is out of range. + */ + int getTransactionID(bool undo, unsigned pos = 0) const; + + /** + * @brief Check if a transaction is open and its list is empty. + * + * @return True if there is a transaction open and its list is empty, true + * if there is no open transaction, false if a transaction is open but its + * list is not empty. + */ + bool isTransactionEmpty() const; + + /** + * @brief Set the undo limit. + * @param[in] UndoMemSize The maximum memory in bytes. + */ + void setUndoLimit(unsigned int UndoMemSize = 0); + + /** + * @brief Get the undo memory size. + * @return The memory used by the undo stack in bytes. + */ + unsigned int getUndoMemSize() const; + + /** + * @brief Set the Undo limit as stack size. + * + * @param[in] UndoMaxStackSize The maximum number of undos to store. + */ + void setMaxUndoStackSize(unsigned int UndoMaxStackSize = 20); // NOLINT + // + /// Get the maximum number of undos that can be stored. + unsigned int getMaxUndoStackSize() const; + + /// Remove all stored undos and redos. + void clearUndos(); + + /** + * @brief Get the number of undos stored. + * + * Get the number of stored for a given transaction ID. If @p id is 0, then + * return the total number of undos stored. If the number returned is greater + * than 0, then this means that an undo will be effective. + * + * @param[in] id The transaction ID to match or 0 to get the total number of undos. + * + * @return The number of undos stored. + */ + int getAvailableUndos(int id = 0) const; + + /// Get a list of the undo names. + std::vector getAvailableUndoNames() const; + + /** + * @brief Undo one or multiple steps. + * + * If @p id is 0, then undo one step. If @p id is not 0, then undo + * multiple steps until the transaction with the given ID is undone. + * + * @param[in] id The transaction ID to match or 0 to undo one step. + * + * @return Returns true if an undo was done, false if no undo was done. + */ + bool undo(int id = 0); + + /** + * @brief Get the number of redos stored. + * + * Get the number of stored redos for a given transaction ID. If @p id is 0, + * then return the total number of redos stored. If the number returned is + * greater than 0, then this means that a redo will be effective. + * + * @param[in] id The transaction ID to match or 0 to get the total number of redos. + * + * @return The number of redos stored. + */ + int getAvailableRedos(int id = 0) const; + + /// Get a list of the redo names. + std::vector getAvailableRedoNames() const; + + /** + * @brief Redo one or multiple steps. + * + * If @p id is 0, then redo one step. If @p id is not 0, then redo + * multiple steps until the transaction with the given ID is redone. + * + * @param[in] id The transaction ID to match or 0 to redo one step. + * + * @return Returns true if a redo was done, false if no redo was done. + */ + bool redo(int id = 0); + + /** + * @brief Check if the document is performing a transaction. + * + * This function returns true if the document is in a transaction phase, + * i.e. currently performing a redo/undo or rollback. + * + * @return True if the document is performing a transaction, false otherwise. + */ + bool isPerformingTransaction() const; + + /** + * @brief Register that a property of an object has changed in a transaction. + * + * @param[in] obj The object whose property has changed. + * @param[in] prop The property that has changed. + * @param[in] add If true, the property was added, if false it was removed. + * + * @warning This function is only for internal use. + */ + + void addOrRemovePropertyOfObject(TransactionalObject* obj, const Property* prop, bool add); + /** + * @brief Register that a property of an object has been renamed in a transaction. + * + * @param[in] obj The object whose property has changed. + * @param[in] prop The property that has changed. + * @param[in] newName The new name of the property. + * + * @warning This function is only for internal use. + */ + void renamePropertyOfObject(TransactionalObject* obj, const Property* prop, const char* newName); + /// @} + + /** @name Dependency items. + * @{ + */ + + /** + * @brief Write the dependency graph of this document. + * + * The dependency graph is in Graphviz DOT format. + * + * @param[in, out] out The output stream to write to. + */ void writeDependencyGraphViz(std::ostream& out); - /// checks if the graph is directed and has no cycles + + /// Checks if the dependency graph is directed and has no cycles. static bool checkOnCycle(); - /// get a list of all objects linking to the given object + + /** + * @brief Get the Inlist of an object. + * + * The Inlist represents the list of objects that have an edge pointing to + * @p me. This means that these objects depend on @p me and that on a + * recompute, @p me should be computed first. + * + * @param[in] me The object to get the Inlist for. + * + * @return The Inlist of the object. + */ std::vector getInList(const DocumentObject* me) const; - /// Option bit flags used by getDepenencyList() + /// The position of option flags used by getDependencyList() enum DependencyOption { - /// Return topological sorted list - DepSort = 1, - /// Do no include object linked by PropertyXLink, as it can handle external link - DepNoXLinked = 2, - /// Raise exception on cycles - DepNoCycle = 4, + DepSort = 1, ///< For a topologically sorted list + DepNoXLinked = 2, ///< Ignore external links + DepNoCycle = 4, ///< Ignore cyclic links }; - /** Get a complete list of all objects the given objects depend on. + + /** + * @brief Get a list of all objects that the given objects depend on. * * This function is defined as static because it accepts objects from * different documents, and the returned list will contain dependent - * objects from all relevant documents + * objects from all relevant documents. * - * @param objs: input objects to query for dependency. - * @param options: See DependencyOption + * @param[in] objs Objects for which we want to find the dependencies. + * @param[in] options A bitmask of DependencyOption. + * + * @return A list of all objects that the given objects depend on. */ static std::vector getDependencyList(const std::vector& objs, int options = 0); + /** + * @brief Get a list of documents that depend on this document. + * + * @param[in] sort If true, the returned list is topologically sorted. + * + * @return A list of documents that depend on this document. + */ std::vector getDependentDocuments(bool sort = true); + + /** + * @brief Get a list of documents that depend on the given documents. + * + * @param[in] docs The documents for which we want to find the dependencies. + * @param[in] sort If true, the returned list is topologically sorted. + * + * @return A list of documents that depend on the given documents. + */ static std::vector getDependentDocuments(std::vector docs, - bool sort); + bool sort); // set Changed // void setChanged(DocumentObject* change); - /// get a list of topological sorted objects (https://en.wikipedia.org/wiki/Topological_sorting) + + /** + * @brief Get a list of topologically sorted objects. + * + * For more information on topological sorting see + * https://en.wikipedia.org/wiki/Topological_sorting. + * + * @return A list of the topologically sorted objects of this document. + */ std::vector topologicalSort() const; - /// get all root objects (objects no other one reference too) + + /** + * @brief Get all root objects in the document. + * + * Root objects are objects that no other objects references. + * + * @return A list of all root objects. + */ std::vector getRootObjects() const; - /// get all tree root objects (objects that are at the root of the object tree) + + /** + * @brief Get all tree root objects in the document. + * + * These are objects that are at the root of the object tree. + * + * @return A list of all tree root objects. + */ std::vector getRootObjectsIgnoreLinks() const; - /// get all possible paths from one object to another following the OutList + + /** + * @brief Get all possible paths from one object to another. + * + * This functions follows the outlist to find all paths from @p from to @p to. + * + * @param[in] from The object to start from. + * @param[in] to The object to end at. + * + * @return A vector of object lists, each list is one path from @p from to + * @p to. + */ std::vector> getPathsByOutList(const DocumentObject* from, const DocumentObject* to) const; - //@} + /// @} - /** Called by a property during save to store its StringHasher + /** + * @brief Add a string hasher to the document. + * + * This function is called by a property during save to store its + * StringHasher. The StringHasher object is designed to be shared among + * multiple objects. We must not save duplicate copies of the same hasher, + * and must be able to restore with the same sharing relationship. This + * function returns whether the hasher has been added before by other + * objects, and the index of the hasher. If the hasher has not been added + * before, the object must save the hasher by calling StringHasher::Save + * + * @param[in] hasher The input hasher. * - * @param hasher: the input hasher * @return Returns a pair. The boolean indicates if the * StringHasher has been added before. The integer is the hasher index. - * - * The StringHasher object is designed to be shared among multiple objects. - * We must not save duplicate copies of the same hasher, and must be - * able to restore with the same sharing relationship. This function returns - * whether the hasher has been added before by other objects, and the index - * of the hasher. If the hasher has not been added before, the object must - * save the hasher by calling StringHasher::Save */ std::pair addStringHasher(const StringHasherRef& hasher) const; - /** Called by property to restore its StringHasher + /** + * @brief Get a string hasher from the document given an index. * - * @param index: the index previously returned by calling addStringHasher() - * during save. Or if is negative, then return document's own string hasher. + * This function is called by a property to restore its StringHasher. The + * caller is responsible for restoring the hasher if the caller is the + * first owner of the hasher, i.e. if addStringHasher() returns true during + * save. * - * @return Return the resulting string hasher. + * @param[in] index The index previously returned by calling + * addStringHasher() during save. Or if the index is negative, return the + * document's own string hasher. * - * The caller is responsible for restoring the hasher if the caller is the first - * owner of the hasher, i.e. if addStringHasher() returns true during save. + * @return Return the resulting string hasher or a new one if the index is + * not found. */ StringHasherRef getStringHasher(int index = -1) const; - /** Return the links to a given object + /** + * @brief Get the links to a given object. * - * @param links: holds the links found - * @param obj: the linked object. If NULL, then all links are returned. - * @param options: @sa GetLinkOption - * @param maxCount: limit the number of links returned, 0 means no limit - * @param objs: optional objects to search for, if empty, then all objects + * Get the links to an object that is contained in this document. If the + * object is `nullptr`, then all links in this document are returned. + * + * @param[in, out] links Holds the links found + * @param[in] obj The linked object. If `nullptr`, then all links are returned. + * @param[in] options: A bitmask of type GetLinkOption + * @param[in] maxCount: limit the number of links returned, 0 means no limit + * @param[in] objs: optional objects to search for, if empty, then all objects * of this document are searched. */ void getLinksTo(std::set& links, @@ -616,18 +1193,38 @@ public: int maxCount = 0, const std::vector& objs = {}) const; - /// Check if there is any link to the given object + /** + * @brief Check if there is any link to the given object. + * + * @param[in] obj The linked object. + * + * @return True if there is at least one link to the given object, false otherwise. + */ bool hasLinksTo(const DocumentObject* obj) const; - /// Called by objects during restore to ask for recompute + /** + * @brief Mark an object for recompute during restore. + * + * Called by objects during restore to ask for recompute. + * + * @param[in] obj The object to mark for recompute. + */ void addRecomputeObject(DocumentObject* obj); + /// Get the old label of an object before it was changed. const std::string& getOldLabel() const { return oldLabel; } - /// Function called to signal that an object identifier has been renamed + /** + * @brief Rename object identifiers. + * + * @param[in] paths A map of old to new object identifiers. + * @param[in] selector A function that returns true for objects that should + * be renamed, and false for objects that should be skipped. By default + * all objects are renamed. + */ void renameObjectIdentifiers( const std::map& paths, const std::function& selector = @@ -639,57 +1236,160 @@ public: std::string getFullName() const override; - /// Indicate if there is any document restoring/importing + /// Check if there is any document restoring/importing. static bool isAnyRestoring(); + /// Register a new label. void registerLabel(const std ::string& newLabel); + /// Unregister a label. void unregisterLabel(const std::string& oldLabel); + /// Check if a label exists. bool containsLabel(const std::string& label); + /// Create a unique label based on the given modelLabel. std::string makeUniqueLabel(const std::string& modelLabel); friend class Application; - /// because of transaction handling + // because of transaction handling friend class TransactionalObject; friend class DocumentObject; friend class Transaction; friend class TransactionDocumentObject; - /// Destruction ~Document() override; protected: - /// Construction + /** + * @brief Construct a new Document object. + * + * @param[in] documentName The name of the document. The default value is + * the empty string. + */ explicit Document(const char* documentName = ""); - void _removeObject(DocumentObject* pcObject, RemoveObjectOptions options = RemoveObjectOption::DestroyOnRollback | RemoveObjectOption::PreserveChildrenVisibility); + /** + *@brief Remove an object from the document. + * + * @param[in] pcObject The object to remove. + * @param[in] options A bitmask of RemoveObjectOptions. + */ + void _removeObject(DocumentObject* pcObject, + RemoveObjectOptions options = RemoveObjectOption::DestroyOnRollback + | RemoveObjectOption::PreserveChildrenVisibility); + + /** + * @brief Add an object to the document. + * + * @param[in] pcObject The object to add. + * @param[in] pObjectName if `nullptr` generate a new unique name based on @p + * pcObject type, otherwise use this name. + * @param[in] options A bitmask of AddObjectOptions. + * @param[in] viewType Override object's view provider name. + */ void _addObject(DocumentObject* pcObject, const char* pObjectName, AddObjectOptions options = AddObjectOption::ActivateObject, const char* viewType = nullptr); - /// checks if a valid transaction is open + + /** + * @brief Check if a valid transaction is open. + * + * Check if a valid transaction is open, and if not, open a new + * transaction. With the arguments we can check what kind of transaction + * we expect to be open. + * + * @param[in] pcDelObj The object being deleted, or `nullptr` if no + * object is being deleted. + * @param[in] What The property being changed, or `nullptr` if no property + * is being changed. + * @param[in] line The line number where this function is called. + */ void _checkTransaction(DocumentObject* pcDelObj, const Property* What, int line); + + /** + * @brief Break dependencies of an object. + * + * Break all dependencies of an object, i.e. remove all links to and from + * the object. + * + * @param[in] pcObject The object to break dependencies for. + * @param[in] clear If true, then also clear all link properties of @p pcObject. + */ void breakDependency(DocumentObject* pcObject, bool clear); + + /** + * @brief Read objects from an XML reader. + * + * @param[in, out] reader The XML reader to read from. + * @return A vector of objects read. + */ std::vector readObjects(Base::XMLReader& reader); - void writeObjects(const std::vector&, Base::Writer& writer) const; + + /** + * @brief Write objects to an XML writer. + * + * @param[in] objs The objects to write. + * @param[in, out] writer The XML writer to write to. + */ + void writeObjects(const std::vector& objs, Base::Writer& writer) const; + + /** + * @brief Save the document to a file. + * + * @param[in] filename The name of the file to save to. + * @return True if the document was saved successfully. + * @throw Base::FileException if the file could not be written. + */ bool saveToFile(const char* filename) const; + + /** + * @brief Count the object of a given type. + * + * @param[in] typeId The type to count. + * @return The number of objects of the given type. + */ int countObjectsOfType(const Base::Type& typeId) const; void onBeforeChange(const Property* prop) override; void onChanged(const Property* prop) override; - /// callback from the Document objects before property will be changed + + /** + * @brief Notify the document that a property is about to be changed. + * + * @param[in] Who The object whose property is about to be changed. + * @param[in] What The property that is about to be changed. + */ void onBeforeChangeProperty(const TransactionalObject* Who, const Property* What); - /// callback from the Document objects after property was changed + + /** + * @brief Notify the document that a property has changed. + * + * @param[in] Who The object whose property has changed. + * @param[in] What The property that has changed. + */ void onChangedProperty(const DocumentObject* Who, const Property* What); - /// helper which Recompute only this feature - /// @return 0 if succeeded, 1 if failed, -1 if aborted by user. + + /** + * @brief Recompute a single object. + * @param[in] Feat The object to recompute. + * @return 0 if succeeded, 1 if failed, -1 if aborted by user. + */ int _recomputeFeature(DocumentObject* Feat); + + /// Clear the redos. void _clearRedos(); - /// refresh the internal dependency graph - void _rebuildDependencyList( - const std::vector& objs = std::vector()); - + /** + * @brief Get the name of the transient directory for a given UUID and filename. + * + * @param[in] uuid The UUID of the document. + * @param[in] filename The name of the file. + * + * @return The name of the transient directory. + */ std::string getTransientDirectoryName(const std::string& uuid, const std::string& filename) const; - /** Open a new command Undo/Redo, an UTF-8 name can be specified + /** + * @brief Open a new command Undo/Redo. + * + * A UTF-8 name can be specified * * @param name: transaction name * @param id: transaction ID, if 0 then the ID is auto generated. @@ -700,9 +1400,23 @@ protected: * AutoTransaction setting. */ int _openTransaction(const char* name = nullptr, int id = 0); - /// Internally called by Application to commit the Command transaction. + + /** + * @brief Commit the Command transaction. + * + * This method is internally called by Application to commit the Command + * transaction. + * + * @param notify If true, notify the application to close the transaction. + */ void _commitTransaction(bool notify = false); - /// Internally called by Application to abort the running transaction. + + /** + * @brief Abort the running transaction. + * + * This method is internally called by Application to abort the running + * transaction. + */ void _abortTransaction(); private: diff --git a/src/App/Graphviz.cpp b/src/App/Graphviz.cpp index af1a0c73fb..6bb66128e0 100644 --- a/src/App/Graphviz.cpp +++ b/src/App/Graphviz.cpp @@ -97,7 +97,6 @@ void Document::exportGraphviz(std::ostream& out) const * This class creates the dependency graph for a document. * */ - class GraphCreator { public: @@ -132,7 +131,6 @@ void Document::exportGraphviz(std::ostream& out) const * @param docObj Document object to get an ID from * @return A string */ - std::string getId(const DocumentObject* docObj) { std::string id; @@ -150,7 +148,6 @@ void Document::exportGraphviz(std::ostream& out) const * @param path * @return A string */ - std::string getId(const ObjectIdentifier& path) { DocumentObject* docObj = path.getDocumentObject(); @@ -183,7 +180,6 @@ void Document::exportGraphviz(std::ostream& out) const * @brief setGraphAttributes Set graph attributes on a subgraph for a DocumentObject node. * @param obj DocumentObject */ - void setGraphAttributes(const DocumentObject* obj) { assert(GraphList.find(obj) != GraphList.end()); @@ -201,7 +197,6 @@ void Document::exportGraphviz(std::ostream& out) const * @param vertex Property node * @param name Name of node */ - void setPropertyVertexAttributes(Graph& g, Vertex vertex, const std::string& name) { get(vertex_attribute, g)[vertex]["label"] = name; @@ -217,7 +212,6 @@ void Document::exportGraphviz(std::ostream& out) const * @param obj DocumentObject to assess. * @param CSSubgraphs Boolean if the GeoFeatureGroups are created as subgraphs */ - void addExpressionSubgraphIfNeeded(DocumentObject* obj, bool CSsubgraphs) { @@ -283,7 +277,6 @@ void Document::exportGraphviz(std::ostream& out) const * @param docObj The document object to add. * @param name Name of node. */ - void add(DocumentObject* docObj, const std::string& name, const std::string& label,