Extensions: Handle new dynamic_cast's

This commit is contained in:
Stefan Tröger 2016-09-04 17:42:26 +02:00 committed by wmayer
parent ab692a4c08
commit 258be36aad
13 changed files with 83 additions and 52 deletions

View File

@ -1894,14 +1894,15 @@ DocumentObject * Document::addObject(const char* sType, const char* pObjectName,
string ObjectName;
if (!base)
return 0;
if (!base->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId())) {
App::DocumentObject* pcObject = dynamic_cast<App::DocumentObject*>(base);
if (!pcObject) {
delete base;
std::stringstream str;
str << "'" << sType << "' is not a document object type";
throw Base::TypeError(str.str());
}
App::DocumentObject* pcObject = dynamic_cast<App::DocumentObject*>(base);
pcObject->setDocument(this);
// do no transactions if we do a rollback!

View File

@ -259,5 +259,26 @@ protected: // attributes
} //namespace App
/**
* Overload of freecads base class cast for all cases without any virtual inheritance
*/
template<typename T> T * freecad_dynamic_cast(App::DocumentObject * t)
{
if (t && t->isDerivedFrom(T::getClassTypeId()))
return static_cast<T*>(t);
else
return nullptr;
}
/**
* See explaination above
*/
template<typename T> const T * freecad_dynamic_cast(const App::DocumentObject * t)
{
if (t && t->isDerivedFrom(T::getClassTypeId()))
return static_cast<const T*>(t);
else
return nullptr;
}
#endif // APP_DOCUMENTOBJECT_H

View File

@ -149,7 +149,7 @@ PyObject* ExtensionContainerPy::addExtension(PyObject *args) {
throw Py::Exception(Base::BaseExceptionFreeCADError,str.str());
}
ext->initExtension(dynamic_cast<App::DocumentObject*>(getExtensionContainerPtr()));
ext->initExtension(getExtensionContainerPtr());
//set the proxy to allow python overrides
App::Property* pp = ext->getPropertyByName("Proxy");

View File

@ -70,13 +70,15 @@ App::DocumentObject *OriginGroupExtension::getGroupOfObject (const DocumentObjec
std::vector<DocumentObject*> grps = doc->getObjectsWithExtension ( OriginGroupExtension::getClassTypeId() );
for (auto grpObj: grps) {
OriginGroupExtension* grp = dynamic_cast <OriginGroupExtension* >(grpObj->getExtension(OriginGroupExtension::getClassTypeId()));
if(!grp) throw Base::TypeError("Wrong type in origin group extenion");
if ( indirect ) {
if ( grp->geoHasObject (obj) ) {
return dynamic_cast<App::DocumentObject*>(grp);
return grp->getExtendedObject();
}
} else {
if ( grp->hasObject (obj) ) {
return dynamic_cast<App::DocumentObject*>(grp);
return grp->getExtendedObject();
}
}
}

View File

@ -131,6 +131,7 @@ void PropertyLink::Restore(Base::XMLReader &reader)
if (name != "") {
DocumentObject* parent = dynamic_cast<DocumentObject*>(getContainer());
if(!parent) throw Base::TypeError("Property container is not document object");
App::Document* document = parent->getDocument();
DocumentObject* object = document ? document->getObject(name.c_str()) : 0;
if (!object) {
@ -289,6 +290,7 @@ void PropertyLinkList::Restore(Base::XMLReader &reader)
// document. Thus, we should silently ingore this.
// Property not in an object!
DocumentObject* father = dynamic_cast<DocumentObject*>(getContainer());
if(!father) throw Base::TypeError("Property container is not document object");
App::Document* document = father->getDocument();
DocumentObject* child = document ? document->getObject(name.c_str()) : 0;
if (child)
@ -479,7 +481,10 @@ void PropertyLinkSub::Restore(Base::XMLReader &reader)
DocumentObject *pcObject;
if (!name.empty()) {
App::Document* document = dynamic_cast<DocumentObject*>(getContainer())->getDocument();
auto* parent = dynamic_cast<DocumentObject*>(getContainer());
if(!parent) throw Base::TypeError("Property container is not document object");
App::Document* document = parent->getDocument();
pcObject = document ? document->getObject(name.c_str()) : 0;
if (!pcObject) {
if (reader.isVerbose()) {
@ -807,7 +812,6 @@ void PropertyLinkSubList::Restore(Base::XMLReader &reader)
reader.readElement("LinkSubList");
// get the value of my attribute
int count = reader.getAttributeAsInteger("count");
assert(getContainer()->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId()) );
std::vector<DocumentObject*> values;
values.reserve(count);
@ -821,6 +825,7 @@ void PropertyLinkSubList::Restore(Base::XMLReader &reader)
// document. Thus, we should silently ignore this.
// Property not in an object!
DocumentObject* father = dynamic_cast<DocumentObject*>(getContainer());
if(!father) throw Base::TypeError("Property container is not document object");
App::Document* document = father->getDocument();
DocumentObject* child = document ? document->getObject(name.c_str()) : 0;
if (child)

View File

@ -105,30 +105,24 @@ public:
/**
* Template that works just like dynamic_cast, but expects the argument to
* inherit from Base::BaseClass.
* inherit from Base::BaseClass. Note thst for base class this is exactly the same as a dynamic_cast.
* The reason for that is that it is not possible to static_cast base to anything in the inheritance
* chain after PropertyContainer. The reason for this is the used virtual inheritance.
* However, the function can be overload for different cast between objects in the inheritnce
* chain after PropertyContainer, for example from DocumentObject to all its derived types-
*
*/
template<typename T> T * freecad_dynamic_cast(Base::BaseClass * t)
{
if (t && t->isDerivedFrom(T::getClassTypeId()))
return dynamic_cast<T*>(t);
else
return 0;
return dynamic_cast<T*>(t);
}
/**
* Template that works just like dynamic_cast, but expects the argument to
* inherit from a const Base::BaseClass.
*
* See explaination above
*/
template<typename T> const T * freecad_dynamic_cast(const Base::BaseClass * t)
{
if (t && t->isDerivedFrom(T::getClassTypeId()))
return dynamic_cast<const T*>(t);
else
return 0;
return dynamic_cast<const T*>(t);
}

View File

@ -53,7 +53,7 @@ ViewProviderGeoFeatureGroupExtension::~ViewProviderGeoFeatureGroupExtension()
std::vector<App::DocumentObject*> ViewProviderGeoFeatureGroupExtension::extensionClaimChildren3D(void) const {
auto* ext = getExtendedViewProvider()->getObject()->getExtensionByType<App::GeoFeatureGroupExtension>();
return ext->getGeoSubObjects();
return ext ? ext->getGeoSubObjects() : std::vector<App::DocumentObject*>();
}
void ViewProviderGeoFeatureGroupExtension::extensionAttach(App::DocumentObject* pcObject)
@ -84,7 +84,7 @@ std::vector<std::string> ViewProviderGeoFeatureGroupExtension::extensionGetDispl
void ViewProviderGeoFeatureGroupExtension::extensionUpdateData(const App::Property* prop)
{
auto obj = getExtendedViewProvider()->getObject()->getExtensionByType<App::GeoFeatureGroupExtension>();
if (prop == &obj->Placement) {
if (obj && prop == &obj->Placement) {
getExtendedViewProvider()->setTransformation ( obj->Placement.getValue().toMatrix() );
} else {
ViewProviderGroupExtension::extensionUpdateData ( prop );

View File

@ -61,6 +61,9 @@ std::vector<App::DocumentObject*> ViewProviderOriginGroupExtension::constructChi
const std::vector<App::DocumentObject*> &children ) const
{
auto* group = getExtendedViewProvider()->getObject()->getExtensionByType<App::OriginGroupExtension>();
if(!group)
return children;
App::DocumentObject *originObj = group->Origin.getValue();
// Origin must be first
@ -102,7 +105,7 @@ void ViewProviderOriginGroupExtension::extensionAttach(App::DocumentObject *pcOb
void ViewProviderOriginGroupExtension::extensionUpdateData( const App::Property* prop ) {
auto* group = getExtendedViewProvider()->getObject()->getExtensionByType<App::OriginGroupExtension>();
if ( prop == &group->Group ) {
if ( group && prop == &group->Group ) {
updateOriginSize();
}
@ -111,7 +114,7 @@ void ViewProviderOriginGroupExtension::extensionUpdateData( const App::Property*
void ViewProviderOriginGroupExtension::slotChangedObjectApp ( const App::DocumentObject& obj) {
auto* group = getExtendedViewProvider()->getObject()->getExtensionByType<App::OriginGroupExtension>();
if ( group->hasObject (&obj, /*recusive=*/ true ) ) {
if ( group && group->hasObject (&obj, /*recusive=*/ true ) ) {
updateOriginSize ();
}
}
@ -132,6 +135,8 @@ void ViewProviderOriginGroupExtension::slotChangedObjectGui ( const Gui::ViewPro
void ViewProviderOriginGroupExtension::updateOriginSize () {
auto* group = getExtendedViewProvider()->getObject()->getExtensionByType<App::OriginGroupExtension>();
if(!group)
return;
// obtain an Origin and it's ViewProvider
App::Origin* origin = 0;

View File

@ -288,8 +288,8 @@ QString PropertyItem::pythonIdentifier(const App::Property* prop) const
QString propName = QString::fromLatin1(parent->getPropertyName(prop));
return QString::fromLatin1("FreeCAD.getDocument(\"%1\").%2").arg(docName).arg(propName);
}
if (parent->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId())) {
App::DocumentObject* obj = dynamic_cast<App::DocumentObject*>(parent);
App::DocumentObject* obj = dynamic_cast<App::DocumentObject*>(parent);
if (obj) {
App::Document* doc = obj->getDocument();
QString docName = QString::fromLatin1(App::GetApplication().getDocumentName(doc));
QString objName = QString::fromLatin1(obj->getNameInDocument());
@ -3375,13 +3375,12 @@ QVariant PropertyLinkItem::value(const App::Property* prop) const
else {
// no object assigned
// the document name
if (c->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId())) {
App::DocumentObject* obj = dynamic_cast<App::DocumentObject*>(c);
App::DocumentObject* obj = dynamic_cast<App::DocumentObject*>(c);
if (obj)
list << QString::fromLatin1(obj->getDocument()->getName());
}
else {
else
list << QString::fromLatin1("");
}
// the internal object name
list << QString::fromLatin1("Null");
// the object label
@ -3389,13 +3388,11 @@ QVariant PropertyLinkItem::value(const App::Property* prop) const
}
// the name of this object
if (c->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId())) {
App::DocumentObject* obj = dynamic_cast<App::DocumentObject*>(c);
list << QString::fromLatin1(obj->getNameInDocument());
}
else {
App::DocumentObject* cobj = dynamic_cast<App::DocumentObject*>(c);
if (cobj)
list << QString::fromLatin1(cobj->getNameInDocument());
else
list << QString::fromLatin1("Null");
}
return QVariant(list);
}

View File

@ -263,10 +263,11 @@ void PropertyPostDataObject::SaveDocFile (Base::Writer &writer) const
// We only print an error message but continue writing the next files to the
// stream...
App::PropertyContainer* father = this->getContainer();
if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
if (father) {
App::DocumentObject* obj = dynamic_cast<App::DocumentObject*>(father);
Base::Console().Error("Dataset of '%s' cannot be written to vtk file '%s'\n",
obj->Label.getValue(),fi.filePath().c_str());
if(obj)
Base::Console().Error("Dataset of '%s' cannot be written to vtk file '%s'\n",
obj->Label.getValue(),fi.filePath().c_str());
}
else {
Base::Console().Error("Cannot save vtk file '%s'\n", fi.filePath().c_str());
@ -331,10 +332,11 @@ void PropertyPostDataObject::RestoreDocFile(Base::Reader &reader)
// We only print an error message but continue reading the next files from the
// stream...
App::PropertyContainer* father = this->getContainer();
if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
if (father) {
App::DocumentObject* obj = dynamic_cast<App::DocumentObject*>(father);
Base::Console().Error("Dataset file '%s' with data of '%s' seems to be empty\n",
fi.filePath().c_str(),obj->Label.getValue());
if(obj)
Base::Console().Error("Dataset file '%s' with data of '%s' seems to be empty\n",
fi.filePath().c_str(),obj->Label.getValue());
}
else {
Base::Console().Warning("Loaded Dataset file '%s' seems to be empty\n", fi.filePath().c_str());

View File

@ -296,10 +296,11 @@ void PropertyPartShape::SaveDocFile (Base::Writer &writer) const
// We only print an error message but continue writing the next files to the
// stream...
App::PropertyContainer* father = this->getContainer();
if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
if (father) {
App::DocumentObject* obj = dynamic_cast<App::DocumentObject*>(father);
Base::Console().Error("Shape of '%s' cannot be written to BRep file '%s'\n",
obj->Label.getValue(),fi.filePath().c_str());
if(obj)
Base::Console().Error("Shape of '%s' cannot be written to BRep file '%s'\n",
obj->Label.getValue(),fi.filePath().c_str());
}
else {
Base::Console().Error("Cannot save BRep file '%s'\n", fi.filePath().c_str());
@ -375,10 +376,11 @@ void PropertyPartShape::RestoreDocFile(Base::Reader &reader)
// We only print an error message but continue reading the next files from the
// stream...
App::PropertyContainer* father = this->getContainer();
if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
if (father) {
App::DocumentObject* obj = dynamic_cast<App::DocumentObject*>(father);
Base::Console().Error("BRep file '%s' with shape of '%s' seems to be empty\n",
fi.filePath().c_str(),obj->Label.getValue());
if(obj)
Base::Console().Error("BRep file '%s' with shape of '%s' seems to be empty\n",
fi.filePath().c_str(),obj->Label.getValue());
}
else {
Base::Console().Warning("Loaded BRep file '%s' seems to be empty\n", fi.filePath().c_str());

View File

@ -442,7 +442,7 @@ void CmdPartDesignNewSketch::activated(int iMsg)
auto group = App::GeoFeatureGroupExtension::getGroupOfObject ( pcActiveBody );
App::GeoFeatureGroupExtension* geoGroup = nullptr;
if(group)
geoGroup = dynamic_cast<App::GeoFeatureGroupExtension*>(group->getExtension(App::GeoFeatureGroupExtension::getClassTypeId()));
geoGroup = group->getExtensionByType<App::GeoFeatureGroupExtension>();
std::vector<App::DocumentObject*> planes;
std::vector<PartDesignGui::TaskFeaturePick::featureStatus> status;

View File

@ -330,7 +330,9 @@ SbBox3f ViewProviderDatum::getRelevantBoundBox () const {
App::DocumentObject* group = App::DocumentObjectGroup::getGroupOfObject ( this->getObject () );
if(group) {
objs = dynamic_cast<App::GroupExtension*>(group->getExtension(App::GroupExtension::getClassTypeId()))->getObjects ();
auto* ext = group->getExtensionByType<App::GroupExtension>();
if(ext)
objs = ext->getObjects ();
} else {
// Fallback to whole document
objs = this->getObject ()->getDocument ()->getObjects ();