Base class for all extension that can be added to a DocumentObject. More...
#include <Extension.h>
Public Member Functions | |
Extension () | |
App::ExtensionContainer * | getExtendedContainer () |
const App::ExtensionContainer * | getExtendedContainer () const |
virtual PyObject * | getExtensionPyObject () |
virtual void | initExtension (App::ExtensionContainer *obj) |
bool | isPythonExtension () |
std::string | name () const |
virtual | ~Extension () |
Access properties | |
virtual Property * | extensionGetPropertyByName (const char *name) const |
find a property by its name More... | |
virtual const char * | extensionGetPropertyName (const Property *prop) const |
get the name of a property More... | |
virtual void | extensionGetPropertyMap (std::map< std::string, Property * > &Map) const |
get all properties of the class (including properties of the parent) More... | |
virtual void | extensionGetPropertyList (std::vector< Property * > &List) const |
get all properties of the class (including properties of the parent) More... | |
virtual short | extensionGetPropertyType (const Property *prop) const |
get the Type of a Property More... | |
virtual short | extensionGetPropertyType (const char *name) const |
get the Type of a named Property More... | |
virtual const char * | extensionGetPropertyGroup (const Property *prop) const |
get the Group of a Property More... | |
virtual const char * | extensionGetPropertyGroup (const char *name) const |
get the Group of a named Property More... | |
virtual const char * | extensionGetPropertyDocumentation (const Property *prop) const |
get the Group of a Property More... | |
virtual const char * | extensionGetPropertyDocumentation (const char *name) const |
get the Group of a named Property More... | |
Persistence | |
virtual void | extensionSave (Base::Writer &) const |
virtual void | extensionRestore (Base::XMLReader &) |
TypeHandling | |
class | App::ExtensionContainer |
bool | m_isPythonExtension = false |
Py::SmartPtr | ExtensionPythonObject |
bool | extensionIsDerivedFrom (const Base::Type type) const |
static void | initExtensionSubclass (Base::Type &toInit, const char *ClassName, const char *ParentName, Base::Type::instantiationMethod method=nullptr) |
virtual void | extensionOnChanged (const Property *p) |
void | initExtensionType (Base::Type type) |
Base class for all extension that can be added to a DocumentObject.
For general documentation on why extension system exists and how to use it see the ExtensionContainer documentation. Following is a description howto create custom extensions.
Extensions are like every other FreeCAD object and based on properties. All information storage and persistence should be achieved by use of those. Additional any number of methods can be added to provide functionality around the properties. There are 3 small difference to normal objects:
The special python extension type created above is important, as only those python extensions can be added to an object from python. It does not work to add the c++ version directly there.
Note that every method of the extension becomes part of the extended object when added from c++. This means one should carefully design the API and make only necessary methods public or protected. Every internal method should be private.
The automatic availability of methods in the class does not hold for the python interface, only for c++ classes. This is like every where else in FreeCAD, there is no automatic creation of python API from c++ classes. Hence the extension creator must also create a custom python object of its extension, which works exactly like the normal FreeCAD python object workflow. There is nothing special at all for extension python objects, the normal xml + imp.cpp approach is used. It must only be taken care that the objects father is the correct extension base class. Of course also make sure your extension returns the correct python object in its "getPyObject" call. Every method you create in the extensions python will be later added to an extended object. This happens automatically for both, c++ and python extension, if "getPyObject" returns the correct python object. No extra work needs to be done.
A special case that needs to be handled for extensions is the possibility of overridden methods. Often it is desired to customise extension behaviour by allowing the user to override methods provided by the extension. On c++ side this is trivial, such methods are simply marked as "virtual" and can than be overridden in any derived class. This is more involved for the python interface and here special care needs to be taken.
As already seen above one needs to create a special ExtensionPythonT<> object for extension from python. This is done exactly for the purpose of allowing to have overridable methods. The ExtensionPythonT wrapper adds a proxy property which holds a PyObject which itself will contain the implementations for the overridden methods. This design is equal to the ObjectPythonT<> design of normal document objects. As this wrapper inherits the c++ extension class it can also override the virtual functions the user designed to be overridden. What it should do at a call of the virtual method is to check if this method is implemented in the proxy object and if so call it, and if not call the normal c++ version. It is the extensions creators responsibility to implement this check and call behaviour for every overridable method. This is done by creating a custom wrapper just like ExtensionPythonT<> and overriding all virtual methods.
@Note As seen in the code there are multiple helper macros to ease the repetitive work of querying and calling methods of the proxy object. See the macro documentation for how to use them.
To ensure that your wrapper is used when a extension is created from python the extension type must be exposed as follows:
This boilerplate is absolutely necessary to allow overridable methods in python and it is the extension creator's responsibility to ensure full implementation.
Extension::Extension | ( | ) |
|
virtual |
References ExtensionPythonObject.
|
virtual |
find a property by its name
Reimplemented in App::LinkBaseExtension.
Referenced by App::LinkBaseExtension::extensionGetPropertyByName().
|
virtual |
get the Group of a named Property
|
virtual |
get the Group of a Property
|
virtual |
get the Group of a named Property
|
virtual |
get the Group of a Property
|
virtual |
get all properties of the class (including properties of the parent)
|
virtual |
get all properties of the class (including properties of the parent)
|
virtual |
get the name of a property
Referenced by App::LinkBaseExtension::setProperty().
|
virtual |
get the Type of a named Property
get the Type of a Property
bool App::Extension::extensionIsDerivedFrom | ( | const Base::Type | type | ) | const |
Referenced by App::LinkBaseExtension::getTrueLinkedObject().
|
protectedvirtual |
Reimplemented in Part::AttachExtension, Part::PrismExtension, Gui::ViewProviderLinkObserver, PartGui::ViewProviderSplineExtension, App::GeoFeatureGroupExtension, App::GroupExtension, App::LinkBaseExtension, and App::OriginGroupExtension.
Referenced by Part::AttachExtension::extensionOnChanged(), Part::PrismExtension::extensionOnChanged(), PartGui::ViewProviderSplineExtension::extensionOnChanged(), App::GroupExtension::extensionOnChanged(), and App::LinkBaseExtension::extensionOnChanged().
|
virtual |
|
virtual |
App::ExtensionContainer * App::Extension::getExtendedContainer | ( | ) |
Referenced by App::GeoFeatureGroupExtension::extensionGetSubObject(), App::GroupExtension::extensionGetSubObject(), Gui::ViewProviderLinkObserver::extensionModeSwitchChange(), Gui::ViewProviderLinkObserver::extensionOnChanged(), Gui::ViewProviderLinkObserver::extensionReattach(), App::LinkBaseExtension::getContainer(), App::DocumentObjectExtension::getExtendedObject(), Gui::ViewProviderExtension::getExtendedViewProvider(), and App::GeoFeatureGroupExtension::placement().
const App::ExtensionContainer * App::Extension::getExtendedContainer | ( | ) | const |
|
virtual |
Reimplemented in Gui::ViewProviderExtension, App::DocumentObjectExtension, Part::AttachExtension, TechDraw::CosmeticExtension, App::GroupExtension, and App::LinkBaseExtension.
References ExtensionPythonObject.
|
virtual |
Reimplemented in App::GeoFeatureGroupExtension.
References Base::Type::isBad(), and App::ExtensionContainer::registerExtension().
Referenced by Part::Cylinder::Cylinder(), PartDesign::Cylinder::Cylinder(), PartDesign::FeaturePrimitive::FeaturePrimitive(), App::GeoFeatureGroupExtension::initExtension(), App::Link::Link(), App::LinkElement::LinkElement(), App::LinkGroup::LinkGroup(), Part::Prism::Prism(), PartDesign::Prism::Prism(), PartDesignGui::ViewProvider::ViewProvider(), PartDesignGui::ViewProviderBody::ViewProviderBody(), PartDesignGui::ViewProviderBoolean::ViewProviderBoolean(), PartDesignGui::ViewProviderDatum::ViewProviderDatum(), and SketcherGui::ViewProviderSketch::ViewProviderSketch().
|
staticprotected |
References Base::Type::badType(), Base::Type::createType(), and Base::Type::fromName().
|
protected |
References Base::Type::isBad().
Referenced by App::GroupExtension::GroupExtension().
bool App::Extension::isPythonExtension | ( | ) |
std::string Extension::name | ( | ) | const |
References Base::Type::getName(), and Base::Type::isBad().
Referenced by draftguitools.gui_groups.Ui_AddNamedGroup::accept(), prototype.Node::addtofreecad(), Addon.Addon::disable(), Addon.Addon::enable(), App::LinkBaseExtension::extensionGetSubObjects(), PartDesignGui::ViewProviderDressUp::featureName(), addonmanager_macro.Macro::filename(), gzip_utf8.GzipFile::filename(), addonmanager_macro.Macro::fill_details_from_code(), addonmanager_macro.Macro::fill_details_from_wiki(), Addon.Addon::get_cached_icon_filename(), App::LinkBaseExtension::getElementIndex(), ifc4.ifcapproval::hasidentifierorname(), addonmanager_macro.Macro::install(), Addon.Addon::is_disabled(), femsolver.elmer.sifio.Section::keys(), automotive_design.si_unit::named_unit_dimensions(), Mod.PartDesign.WizardShaft.SegmentFunction.SegmentFunction::output(), prototype.Node::pprint(), prototype.Node::pprint2(), PathScripts.PathSetupSheetGui.OpTaskPanel::propertyGroup(), PathScripts.PathSetupSheetGui.OpTaskPanel::propertyName(), PathScripts.PathJobGui.TaskPanel::reject(), addonmanager_macro.Macro::remove(), Sketcher::SketchObject::renameConstraint(), Addon.Addon::to_cache(), ifc2x3.ifcexternalreference::wr1(), ifc2x3.ifcdocumentreference::wr1(), ifc4.ifcexternalreference::wr1(), ifc4.ifcdocumentreference::wr1(), and automotive_design.general_property_association::wr2().
|
friend |
|
protected |
Referenced by getExtensionPyObject(), Gui::ViewProviderExtension::getExtensionPyObject(), App::DocumentObjectExtension::getExtensionPyObject(), Part::AttachExtension::getExtensionPyObject(), TechDraw::CosmeticExtension::getExtensionPyObject(), App::GroupExtension::getExtensionPyObject(), App::LinkBaseExtension::getExtensionPyObject(), and ~Extension().
|
protected |