/**************************************************************************** * Copyright (c) 2017 Zheng Lei (realthunder) * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ****************************************************************************/ #ifndef APP_LINK_H #define APP_LINK_H #include #include #include #include "DocumentObject.h" #include "DocumentObjectExtension.h" #include "FeaturePython.h" #include "GroupExtension.h" #include "PropertyLinks.h" //FIXME: ISO C++11 requires at least one argument for the "..." in a variadic macro #if defined(__clang__) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" #endif #define LINK_THROW(_type,_msg) do{\ if(FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))\ FC_ERR(_msg);\ throw _type(_msg);\ }while(0) namespace App { class AppExport LinkBaseExtension : public App::DocumentObjectExtension { EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(App::LinkExtension); using inherited = App::DocumentObjectExtension; public: LinkBaseExtension(); ~LinkBaseExtension() override = default; PropertyBool _LinkTouched; PropertyInteger _LinkOwner; PropertyLinkList _ChildCache; // cache for plain group expansion enum { LinkModeNone, LinkModeAutoDelete, LinkModeAutoLink, LinkModeAutoUnlink, }; /** \name Parameter definition * * Parameter definition (Name, Type, Property Type, Default, Document). * The variadic is here so that the parameter can be extended by adding * extra fields. See LINK_PARAM_EXT() for an example */ //@{ #define LINK_PARAM_LINK_PLACEMENT(...) \ (LinkPlacement, Base::Placement, App::PropertyPlacement, Base::Placement(), "Link placement", ##__VA_ARGS__) #define LINK_PARAM_PLACEMENT(...) \ (Placement, Base::Placement, App::PropertyPlacement, Base::Placement(), \ "Alias to LinkPlacement to make the link object compatibale with other objects", ##__VA_ARGS__) #define LINK_PARAM_OBJECT(...) \ (LinkedObject, App::DocumentObject*, App::PropertyLink, 0, "Linked object", ##__VA_ARGS__) #define LINK_PARAM_TRANSFORM(...) \ (LinkTransform, bool, App::PropertyBool, false, \ "Set to false to override linked object's placement", ##__VA_ARGS__) #define LINK_PARAM_CLAIM_CHILD(...) \ (LinkClaimChild, bool, App::PropertyBool, false, \ "Claim the linked object as a child", ##__VA_ARGS__) #define LINK_PARAM_COPY_ON_CHANGE(...) \ (LinkCopyOnChange, long, App::PropertyEnumeration, ((long)0), \ "Disabled: disable copy on change\n"\ "Enabled: enable copy linked object on change of any of its properties marked as CopyOnChange\n"\ "Owned: indicate the linked object has been copied and is own owned by the link. And the\n"\ " the link will try to sync any change of the original linked object back to the copy.",\ ##__VA_ARGS__) #define LINK_PARAM_COPY_ON_CHANGE_SOURCE(...) \ (LinkCopyOnChangeSource, App::DocumentObject*, App::PropertyLink, 0, "The copy on change source object", ##__VA_ARGS__) #define LINK_PARAM_COPY_ON_CHANGE_GROUP(...) \ (LinkCopyOnChangeGroup, App::DocumentObject*, App::PropertyLink, 0, \ "Linked to a internal group object for holding on change copies", ##__VA_ARGS__) #define LINK_PARAM_COPY_ON_CHANGE_TOUCHED(...) \ (LinkCopyOnChangeTouched, bool, App::PropertyBool, 0, "Indicating the copy on change source object has been changed", ##__VA_ARGS__) #define LINK_PARAM_SCALE(...) \ (Scale, double, App::PropertyFloat, 1.0, "Scale factor", ##__VA_ARGS__) #define LINK_PARAM_SCALE_VECTOR(...) \ (ScaleVector, Base::Vector3d, App::PropertyVector, Base::Vector3d(1,1,1), "Scale factors", ##__VA_ARGS__) #define LINK_PARAM_PLACEMENTS(...) \ (PlacementList, std::vector, App::PropertyPlacementList, std::vector(),\ "The placement for each link element", ##__VA_ARGS__) #define LINK_PARAM_SCALES(...) \ (ScaleList, std::vector, App::PropertyVectorList, std::vector(),\ "The scale factors for each link element", ##__VA_ARGS__) #define LINK_PARAM_VISIBILITIES(...) \ (VisibilityList, boost::dynamic_bitset<>, App::PropertyBoolList, boost::dynamic_bitset<>(),\ "The visibility state of each link element", ##__VA_ARGS__) #define LINK_PARAM_COUNT(...) \ (ElementCount, int, App::PropertyInteger, 0, "Link element count", ##__VA_ARGS__) #define LINK_PARAM_ELEMENTS(...) \ (ElementList, std::vector, App::PropertyLinkList, std::vector(),\ "The link element object list", ##__VA_ARGS__) #define LINK_PARAM_SHOW_ELEMENT(...) \ (ShowElement, bool, App::PropertyBool, true, "Enable link element list", ##__VA_ARGS__) #define LINK_PARAM_MODE(...) \ (LinkMode, long, App::PropertyEnumeration, ((long)0), "Link group mode", ##__VA_ARGS__) #define LINK_PARAM_LINK_EXECUTE(...) \ (LinkExecute, const char*, App::PropertyString, (""),\ "Link execute function. Default to 'appLinkExecute'. 'None' to disable.", ##__VA_ARGS__) #define LINK_PARAM_COLORED_ELEMENTS(...) \ (ColoredElements, App::DocumentObject*, App::PropertyLinkSubHidden, \ 0, "Link colored elements", ##__VA_ARGS__) #define LINK_PARAM(_param) (LINK_PARAM_##_param()) #define LINK_PNAME(_param) BOOST_PP_TUPLE_ELEM(0,_param) #define LINK_PTYPE(_param) BOOST_PP_TUPLE_ELEM(1,_param) #define LINK_PPTYPE(_param) BOOST_PP_TUPLE_ELEM(2,_param) #define LINK_PDEF(_param) BOOST_PP_TUPLE_ELEM(3,_param) #define LINK_PDOC(_param) BOOST_PP_TUPLE_ELEM(4,_param) #define LINK_PINDEX(_param) BOOST_PP_CAT(Prop,LINK_PNAME(_param)) //@} #define LINK_PARAMS \ LINK_PARAM(PLACEMENT)\ LINK_PARAM(LINK_PLACEMENT)\ LINK_PARAM(OBJECT)\ LINK_PARAM(CLAIM_CHILD)\ LINK_PARAM(TRANSFORM)\ LINK_PARAM(SCALE)\ LINK_PARAM(SCALE_VECTOR)\ LINK_PARAM(PLACEMENTS)\ LINK_PARAM(SCALES)\ LINK_PARAM(VISIBILITIES)\ LINK_PARAM(COUNT)\ LINK_PARAM(ELEMENTS)\ LINK_PARAM(SHOW_ELEMENT)\ LINK_PARAM(MODE)\ LINK_PARAM(LINK_EXECUTE)\ LINK_PARAM(COLORED_ELEMENTS)\ LINK_PARAM(COPY_ON_CHANGE)\ LINK_PARAM(COPY_ON_CHANGE_SOURCE)\ LINK_PARAM(COPY_ON_CHANGE_GROUP)\ LINK_PARAM(COPY_ON_CHANGE_TOUCHED)\ enum PropIndex { #define LINK_PINDEX_DEFINE(_1,_2,_param) LINK_PINDEX(_param), // defines Prop##Name enumeration value BOOST_PP_SEQ_FOR_EACH(LINK_PINDEX_DEFINE,_,LINK_PARAMS) PropMax }; virtual void setProperty(int idx, Property *prop); Property *getProperty(int idx); Property *getProperty(const char *); struct PropInfo { int index; const char *name; Base::Type type; const char *doc; PropInfo(int index, const char *name,Base::Type type,const char *doc) : index(index), name(name), type(type), doc(doc) {} PropInfo() : index(0), name(nullptr), doc(nullptr) {} }; #define LINK_PROP_INFO(_1,_var,_param) \ _var.push_back(PropInfo(BOOST_PP_CAT(Prop,LINK_PNAME(_param)),\ BOOST_PP_STRINGIZE(LINK_PNAME(_param)),\ LINK_PPTYPE(_param)::getClassTypeId(), \ LINK_PDOC(_param))); virtual const std::vector &getPropertyInfo() const; using PropInfoMap = std::map; virtual const PropInfoMap &getPropertyInfoMap() const; enum LinkCopyOnChangeType { CopyOnChangeDisabled = 0, CopyOnChangeEnabled = 1, CopyOnChangeOwned = 2, CopyOnChangeTracking = 3 }; #define LINK_PROP_GET(_1,_2,_param) \ LINK_PTYPE(_param) BOOST_PP_SEQ_CAT((get)(LINK_PNAME(_param))(Value)) () const {\ auto prop = props[LINK_PINDEX(_param)];\ if(!prop) return LINK_PDEF(_param);\ return static_cast(prop)->getValue();\ }\ const LINK_PPTYPE(_param) *BOOST_PP_SEQ_CAT((get)(LINK_PNAME(_param))(Property)) () const {\ auto prop = props[LINK_PINDEX(_param)];\ return static_cast(prop);\ }\ LINK_PPTYPE(_param) *BOOST_PP_SEQ_CAT((get)(LINK_PNAME(_param))(Property)) () {\ auto prop = props[LINK_PINDEX(_param)];\ return static_cast(prop);\ }\ // defines get##Name##Property() and get##Name##Value() accessor BOOST_PP_SEQ_FOR_EACH(LINK_PROP_GET,_,LINK_PARAMS) PropertyLinkList *_getElementListProperty() const; const std::vector &_getElementListValue() const; PropertyBool *_getShowElementProperty() const; bool _getShowElementValue() const; PropertyInteger *_getElementCountProperty() const; int _getElementCountValue() const; std::vector getLinkedChildren(bool filter=true) const; const char *flattenSubname(const char *subname) const; void expandSubname(std::string &subname) const; DocumentObject *getLink(int depth=0) const; Base::Matrix4D getTransform(bool transform) const; Base::Vector3d getScaleVector() const; App::GroupExtension *linkedPlainGroup() const; bool linkTransform() const; const char *getSubName() const { parseSubName(); return !mySubName.empty()?mySubName.c_str():nullptr; } const std::vector &getSubElements() const { parseSubName(); return mySubElements; } bool extensionGetSubObject(DocumentObject *&ret, const char *subname, PyObject **pyObj=nullptr, Base::Matrix4D *mat=nullptr, bool transform=false, int depth=0) const override; bool extensionGetSubObjects(std::vector&ret, int reason) const override; bool extensionGetLinkedObject(DocumentObject *&ret, bool recurse, Base::Matrix4D *mat, bool transform, int depth) const override; App::DocumentObjectExecReturn *extensionExecute() override; short extensionMustExecute() override; void extensionOnChanged(const Property* p) override; void onExtendedUnsetupObject () override; void onExtendedDocumentRestored() override; int extensionSetElementVisible(const char *, bool) override; int extensionIsElementVisible(const char *) override; bool extensionHasChildElement() const override; PyObject* getExtensionPyObject() override; Property *extensionGetPropertyByName(const char* name) const override; static int getArrayIndex(const char *subname, const char **psubname=nullptr); int getElementIndex(const char *subname, const char **psubname=nullptr) const; void elementNameFromIndex(int idx, std::ostream &ss) const; DocumentObject *getContainer(); const DocumentObject *getContainer() const; void setLink(int index, DocumentObject *obj, const char *subname=nullptr, const std::vector &subs = std::vector()); DocumentObject *getTrueLinkedObject(bool recurse, Base::Matrix4D *mat=nullptr,int depth=0, bool noElement=false) const; using LinkPropMap = std::map >; bool hasPlacement() const { return getLinkPlacementProperty() || getPlacementProperty(); } void cacheChildLabel(int enable=-1) const; static bool setupCopyOnChange(App::DocumentObject *obj, App::DocumentObject *linked, std::vector *copyOnChangeConns, bool checkExisting); static bool isCopyOnChangeProperty(App::DocumentObject *obj, const Property &prop); void syncCopyOnChange(); /** Options used in setOnChangeCopyObject() * Multiple options can be combined by bitwise or operator */ enum class OnChangeCopyOptions { /// No options set None = 0, /// If set, then exclude the input from object list to copy on change, or else, include the input object. Exclude = 1, /// If set , then apply the setting to all links to the input object, or else, apply only to this link. ApplyAll = 2, }; /** Include or exclude object from list of objects to copy on change * @param obj: input object * @param options: control options. @sa OnChangeCopyOptions. */ void setOnChangeCopyObject(App::DocumentObject *obj, OnChangeCopyOptions options); std::vector getOnChangeCopyObjects( std::vector *excludes = nullptr, App::DocumentObject *src = nullptr); bool isLinkedToConfigurableObject() const; void monitorOnChangeCopyObjects(const std::vector &objs); /// Check if the linked object is a copy on change bool isLinkMutated() const; protected: void _handleChangedPropertyName(Base::XMLReader &reader, const char * TypeName, const char *PropName); void parseSubName() const; void update(App::DocumentObject *parent, const Property *prop); void checkCopyOnChange(App::DocumentObject *parent, const App::Property &prop); void setupCopyOnChange(App::DocumentObject *parent, bool checkSource = false); App::DocumentObject *makeCopyOnChange(); void syncElementList(); void detachElement(App::DocumentObject *obj); void detachElements(); void checkGeoElementMap(const App::DocumentObject *obj, const App::DocumentObject *linked, PyObject **pyObj, const char *postfix) const; void updateGroup(); void slotChangedPlainGroup(const App::DocumentObject &, const App::Property &); protected: std::vector props; std::unordered_set myHiddenElements; mutable std::vector mySubElements; mutable std::string mySubName; std::unordered_map plainGroupConns; long prevLinkedObjectID = 0; mutable std::unordered_map myLabelCache; // for label based subname lookup mutable bool enableLabelCache{false}; bool hasOldSubElement{false}; std::vector copyOnChangeConns; std::vector copyOnChangeSrcConns; bool hasCopyOnChange{true}; mutable bool checkingProperty = false; bool pauseCopyOnChange = false; boost::signals2::scoped_connection connCopyOnChangeSource; }; /////////////////////////////////////////////////////////////////////////// using LinkBaseExtensionPython = ExtensionPythonT; /////////////////////////////////////////////////////////////////////////// class AppExport LinkExtension : public LinkBaseExtension { EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(App::LinkExtension); using inherited = LinkBaseExtension; public: LinkExtension(); ~LinkExtension() override = default; /** \name Helpers for defining extended parameter * * extended parameter definition * (Name, Type, Property_Type, Default, Document, Property_Name, * Derived_Property_Type, App_Property_Type, Group) * * This helper simply reuses Name as Property_Name, Property_Type as * Derived_Property_type, Prop_None as App_Propert_Type * * Note: Because PropertyView will merge linked object's properties into * ours, we set the default group name as ' Link' with a leading space to * try to make our group before others */ //@{ #define LINK_ENAME(_param) BOOST_PP_TUPLE_ELEM(5,_param) #define LINK_ETYPE(_param) BOOST_PP_TUPLE_ELEM(6,_param) #define LINK_EPTYPE(_param) BOOST_PP_TUPLE_ELEM(7,_param) #define LINK_EGROUP(_param) BOOST_PP_TUPLE_ELEM(8,_param) #define _LINK_PROP_ADD(_add_property, _param) \ _add_property(BOOST_PP_STRINGIZE(LINK_ENAME(_param)),LINK_ENAME(_param),\ (LINK_PDEF(_param)),LINK_EGROUP(_param),LINK_EPTYPE(_param),LINK_PDOC(_param));\ setProperty(LINK_PINDEX(_param),&LINK_ENAME(_param)); #define LINK_PROP_ADD(_1,_2,_param) \ _LINK_PROP_ADD(_ADD_PROPERTY_TYPE,_param); #define LINK_PROP_ADD_EXTENSION(_1,_2,_param) \ _LINK_PROP_ADD(_EXTENSION_ADD_PROPERTY_TYPE,_param); #define LINK_PROPS_ADD(_seq) \ BOOST_PP_SEQ_FOR_EACH(LINK_PROP_ADD,_,_seq) #define LINK_PROPS_ADD_EXTENSION(_seq) \ BOOST_PP_SEQ_FOR_EACH(LINK_PROP_ADD_EXTENSION,_,_seq) #define _LINK_PROP_SET(_1,_2,_param) \ setProperty(LINK_PINDEX(_param),&LINK_ENAME(_param)); #define LINK_PROPS_SET(_seq) BOOST_PP_SEQ_FOR_EACH(_LINK_PROP_SET,_,_seq) /// Helper for defining default extended parameter #define _LINK_PARAM_EXT(_name,_type,_ptype,_def,_doc,...) \ ((_name,_type,_ptype,_def,_doc,_name,_ptype,App::Prop_None," Link")) /** Define default extended parameter * It simply reuses Name as Property_Name, Property_Type as * Derived_Property_Type, and App::Prop_None as App::PropertyType */ #define LINK_PARAM_EXT(_param) BOOST_PP_EXPAND(_LINK_PARAM_EXT LINK_PARAM_##_param()) /// Helper for extended parameter with app property type #define _LINK_PARAM_EXT_ATYPE(_name,_type,_ptype,_def,_doc,_atype) \ ((_name,_type,_ptype,_def,_doc,_name,_ptype,_atype," Link")) /// Define extended parameter with app property type #define LINK_PARAM_EXT_ATYPE(_param,_atype) \ BOOST_PP_EXPAND(_LINK_PARAM_EXT_ATYPE LINK_PARAM_##_param(_atype)) /// Helper for extended parameter with derived property type #define _LINK_PARAM_EXT_TYPE(_name,_type,_ptype,_def,_doc,_dtype) \ ((_name,_type,_ptype,_def,_doc,_name,_dtype,App::Prop_None," Link")) /// Define extended parameter with derived property type #define LINK_PARAM_EXT_TYPE(_param,_dtype) \ BOOST_PP_EXPAND(_LINK_PARAM_EXT_TYPE LINK_PARAM_##_param(_dtype)) /// Helper for extended parameter with a different property name #define _LINK_PARAM_EXT_NAME(_name,_type,_ptype,_def,_doc,_pname) \ ((_name,_type,_ptype,_def,_doc,_pname,_ptype,App::Prop_None," Link")) /// Define extended parameter with a different property name #define LINK_PARAM_EXT_NAME(_param,_pname) BOOST_PP_EXPAND(_LINK_PARAM_EXT_NAME LINK_PARAM_##_param(_pname)) //@} #define LINK_PARAMS_EXT \ LINK_PARAM_EXT(SCALE)\ LINK_PARAM_EXT_ATYPE(SCALE_VECTOR,App::Prop_Hidden)\ LINK_PARAM_EXT(SCALES)\ LINK_PARAM_EXT(VISIBILITIES)\ LINK_PARAM_EXT(PLACEMENTS)\ LINK_PARAM_EXT(ELEMENTS) #define LINK_PROP_DEFINE(_1,_2,_param) LINK_ETYPE(_param) LINK_ENAME(_param); #define LINK_PROPS_DEFINE(_seq) BOOST_PP_SEQ_FOR_EACH(LINK_PROP_DEFINE,_,_seq) // defines the actual properties LINK_PROPS_DEFINE(LINK_PARAMS_EXT) void onExtendedDocumentRestored() override { LINK_PROPS_SET(LINK_PARAMS_EXT); inherited::onExtendedDocumentRestored(); } }; /////////////////////////////////////////////////////////////////////////// using LinkExtensionPython = ExtensionPythonT; /////////////////////////////////////////////////////////////////////////// class AppExport Link : public App::DocumentObject, public App::LinkExtension { PROPERTY_HEADER_WITH_EXTENSIONS(App::Link); using inherited = App::DocumentObject; public: #define LINK_PARAMS_LINK \ LINK_PARAM_EXT_TYPE(OBJECT, App::PropertyXLink)\ LINK_PARAM_EXT(CLAIM_CHILD)\ LINK_PARAM_EXT(TRANSFORM)\ LINK_PARAM_EXT(LINK_PLACEMENT)\ LINK_PARAM_EXT(PLACEMENT)\ LINK_PARAM_EXT(SHOW_ELEMENT)\ LINK_PARAM_EXT_TYPE(COUNT,App::PropertyIntegerConstraint)\ LINK_PARAM_EXT(LINK_EXECUTE)\ LINK_PARAM_EXT_ATYPE(COLORED_ELEMENTS,App::Prop_Hidden)\ LINK_PARAM_EXT(COPY_ON_CHANGE)\ LINK_PARAM_EXT_TYPE(COPY_ON_CHANGE_SOURCE, App::PropertyXLink)\ LINK_PARAM_EXT(COPY_ON_CHANGE_GROUP)\ LINK_PARAM_EXT(COPY_ON_CHANGE_TOUCHED)\ LINK_PROPS_DEFINE(LINK_PARAMS_LINK) Link(); const char* getViewProviderName() const override{ return "Gui::ViewProviderLink"; } void onDocumentRestored() override { LINK_PROPS_SET(LINK_PARAMS_LINK); inherited::onDocumentRestored(); } void handleChangedPropertyName(Base::XMLReader &reader, const char * TypeName, const char *PropName) override { _handleChangedPropertyName(reader,TypeName,PropName); } bool canLinkProperties() const override; }; using LinkPython = App::FeaturePythonT; /////////////////////////////////////////////////////////////////////////// class AppExport LinkElement : public App::DocumentObject, public App::LinkBaseExtension { PROPERTY_HEADER_WITH_EXTENSIONS(App::LinkElement); using inherited = App::DocumentObject; public: #define LINK_PARAMS_ELEMENT \ LINK_PARAM_EXT(SCALE)\ LINK_PARAM_EXT_ATYPE(SCALE_VECTOR,App::Prop_Hidden)\ LINK_PARAM_EXT_TYPE(OBJECT, App::PropertyXLink)\ LINK_PARAM_EXT(TRANSFORM) \ LINK_PARAM_EXT(LINK_PLACEMENT)\ LINK_PARAM_EXT(PLACEMENT)\ LINK_PARAM_EXT(COPY_ON_CHANGE)\ LINK_PARAM_EXT_TYPE(COPY_ON_CHANGE_SOURCE, App::PropertyXLink)\ LINK_PARAM_EXT(COPY_ON_CHANGE_GROUP)\ LINK_PARAM_EXT(COPY_ON_CHANGE_TOUCHED)\ // defines the actual properties LINK_PROPS_DEFINE(LINK_PARAMS_ELEMENT) LinkElement(); const char* getViewProviderName() const override{ return "Gui::ViewProviderLink"; } void onDocumentRestored() override { LINK_PROPS_SET(LINK_PARAMS_ELEMENT); inherited::onDocumentRestored(); } bool canDelete() const; void handleChangedPropertyName(Base::XMLReader &reader, const char * TypeName, const char *PropName) override { _handleChangedPropertyName(reader,TypeName,PropName); } }; using LinkElementPython = App::FeaturePythonT; /////////////////////////////////////////////////////////////////////////// class AppExport LinkGroup : public App::DocumentObject, public App::LinkBaseExtension { PROPERTY_HEADER_WITH_EXTENSIONS(App::LinkGroup); using inherited = App::DocumentObject; public: #define LINK_PARAMS_GROUP \ LINK_PARAM_EXT(ELEMENTS)\ LINK_PARAM_EXT(PLACEMENT)\ LINK_PARAM_EXT(VISIBILITIES)\ LINK_PARAM_EXT(MODE)\ LINK_PARAM_EXT_ATYPE(COLORED_ELEMENTS,App::Prop_Hidden) // defines the actual properties LINK_PROPS_DEFINE(LINK_PARAMS_GROUP) LinkGroup(); const char* getViewProviderName() const override{ return "Gui::ViewProviderLink"; } void onDocumentRestored() override { LINK_PROPS_SET(LINK_PARAMS_GROUP); inherited::onDocumentRestored(); } }; using LinkGroupPython = App::FeaturePythonT; } //namespace App ENABLE_BITMASK_OPERATORS(App::Link::OnChangeCopyOptions) /*[[[cog import LinkParams LinkParams.declare() ]]]*/ namespace App { /** Convenient class to obtain App::Link related parameters * The parameters are under group "User parameter:BaseApp/Preferences/Link" * * This class is auto generated by LinkParams.py. Modify that file * instead of this one, if you want to add any parameter. You need * to install Cog Python package for code generation: * @code * pip install cogapp * @endcode * * Once modified, you can regenerate the header and the source file, * @code * python3 -m cogapp -r Link.h Link.cpp * @endcode * * You can add a new parameter by adding lines in LinkParams.py. Available * parameter types are 'Int, UInt, String, Bool, Float'. For example, to add * a new Int type parameter, * @code * ParamInt(parameter_name, default_value, documentation, on_change=False) * @endcode * * If there is special handling on parameter change, pass in on_change=True. * And you need to provide a function implementation in Link.cpp with * the following signature. * @code * void LinkParams:onChanged() * @endcode */ class AppExport LinkParams { public: static ParameterGrp::handle getHandle(); //@{ /// Accessor for parameter CopyOnChangeApplyToAll /// /// Stores the last user choice of whether to apply CopyOnChange setup to all link /// that links to the same configurable object static const bool & getCopyOnChangeApplyToAll(); static const bool & defaultCopyOnChangeApplyToAll(); static void removeCopyOnChangeApplyToAll(); static void setCopyOnChangeApplyToAll(const bool &v); static const char *docCopyOnChangeApplyToAll(); //@} // Auto generated code. See class document of LinkParams. }; } // namespace App //[[[end]]] #if defined(__clang__) # pragma clang diagnostic pop #endif #endif // APP_LINK_H