/**************************************************************************** * 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; bool isLink() const override; bool isLinkGroup() 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); } bool isLink() const override; App::Link* getLinkGroup() const; }; 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