diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 961340bdb6..3ca4a38a72 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -1851,8 +1851,12 @@ void Document::writeObjects(const std::vector& obj, writer.Stream() << writer.ind() << "getTypeId().getName() << "\" " << "name=\"" << (*it)->getExportName() << "\" " - << "id=\"" << (*it)->getID() << "\" " - << "ViewType=\"" << (*it)->getViewProviderNameStored() << "\" "; + << "id=\"" << (*it)->getID() << "\" "; + + // Only write out custom view provider types + std::string viewType = (*it)->getViewProviderNameStored(); + if (viewType != (*it)->getViewProviderName()) + writer.Stream() << "ViewType=\"" << viewType << "\" "; // See DocumentObjectPy::getState if ((*it)->testStatus(ObjectStatus::Touch)) @@ -3476,7 +3480,7 @@ bool Document::recomputeFeature(DocumentObject* Feat, bool recursive) } DocumentObject * Document::addObject(const char* sType, const char* pObjectName, - bool isNew, const char *viewType, bool isPartial) + bool isNew, const char* viewType, bool isPartial) { Base::BaseClass* base = static_cast(Base::Type::createInstanceByName(sType,true)); @@ -3537,8 +3541,17 @@ DocumentObject * Document::addObject(const char* sType, const char* pObjectName, pcObject->setStatus(ObjectStatus::PartialObject, isPartial); - if (!viewType || viewType[0] == '\0') - viewType = pcObject->getViewProviderNameOverride(); + // If an object does not allow to override its view provider then ignore any + // input of the Document.xml or from Python as this information could be wrong. + // In this case the default type from getViewProviderName() is used. + if (pcObject->allowOverrideViewProviderName()) { + if (!viewType || viewType[0] == '\0') { + viewType = pcObject->getViewProviderNameOverride(); + } + } + else { + viewType = pcObject->getViewProviderName(); + } if (viewType && viewType[0] != '\0') pcObject->_pcViewProviderName = viewType; @@ -3632,8 +3645,16 @@ std::vector Document::addObjects(const char* sType, const std: // mark the object as new (i.e. set status bit 2) and send the signal pcObject->setStatus(ObjectStatus::New, true); - const char *viewType = pcObject->getViewProviderNameOverride(); - pcObject->_pcViewProviderName = viewType?viewType:""; + // If an object does not allow to override its view provider then use + // getViewProviderName() instead. + if (pcObject->allowOverrideViewProviderName()) { + const char *viewType = pcObject->getViewProviderNameOverride(); + pcObject->_pcViewProviderName = viewType ? viewType : ""; + } + else { + const char *viewType = pcObject->getViewProviderName(); + pcObject->_pcViewProviderName = viewType ? viewType : ""; + } signalNewObject(*pcObject); @@ -3691,8 +3712,16 @@ void Document::addObject(DocumentObject* pcObject, const char* pObjectName) // mark the object as new (i.e. set status bit 2) and send the signal pcObject->setStatus(ObjectStatus::New, true); - const char *viewType = pcObject->getViewProviderNameOverride(); - pcObject->_pcViewProviderName = viewType?viewType:""; + // If an object does not allow to override its view provider then use + // getViewProviderName() instead. + if (pcObject->allowOverrideViewProviderName()) { + const char *viewType = pcObject->getViewProviderNameOverride(); + pcObject->_pcViewProviderName = viewType ? viewType : ""; + } + else { + const char *viewType = pcObject->getViewProviderName(); + pcObject->_pcViewProviderName = viewType ? viewType : ""; + } signalNewObject(*pcObject); @@ -3723,8 +3752,16 @@ void Document::_addObject(DocumentObject* pcObject, const char* pObjectName) d->activeUndoTransaction->addObjectDel(pcObject); } - const char *viewType = pcObject->getViewProviderNameOverride(); - pcObject->_pcViewProviderName = viewType?viewType:""; + // If an object does not allow to override its view provider then use + // getViewProviderName() instead. + if (pcObject->allowOverrideViewProviderName()) { + const char *viewType = pcObject->getViewProviderNameOverride(); + pcObject->_pcViewProviderName = viewType ? viewType : ""; + } + else { + const char *viewType = pcObject->getViewProviderName(); + pcObject->_pcViewProviderName = viewType ? viewType : ""; + } // send the signal signalNewObject(*pcObject); diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h index f2599bb300..879ff4f260 100644 --- a/src/App/DocumentObject.h +++ b/src/App/DocumentObject.h @@ -110,10 +110,26 @@ public: virtual const char* getViewProviderName(void) const { return ""; } - /// This function is introduced to allow Python feature override its view provider + /** + * This function is introduced to allow Python feature override its view provider. + * The default implementation just returns \ref getViewProviderName(). + * + * If this method is reimplemented in sub-classes then also reimplement \ref + * allowOverrideViewProviderName() accordingly. + */ virtual const char *getViewProviderNameOverride() const { return getViewProviderName(); } + /** + * The function indicates whether the object type allows to define a view provider type + * different than the standard type. The default implementation returns false. + * The function can be overriden by Python feature to return true where the type can be + * retrieved from its proxy object. + * \sa getViewProviderNameOverride() + */ + virtual bool allowOverrideViewProviderName() const { + return false; + } /// Constructor DocumentObject(void); virtual ~DocumentObject(); diff --git a/src/App/FeaturePython.cpp b/src/App/FeaturePython.cpp index 9c61f3db01..f85c955a16 100644 --- a/src/App/FeaturePython.cpp +++ b/src/App/FeaturePython.cpp @@ -410,6 +410,11 @@ int FeaturePythonImp::setElementVisible(const char *element, bool visible) { return -2; } +bool FeaturePythonImp::allowOverrideViewProviderName() const +{ + return true; +} + std::string FeaturePythonImp::getViewProviderName() { _FC_PY_CALL_CHECK(getViewProviderName,return(std::string())); diff --git a/src/App/FeaturePython.h b/src/App/FeaturePython.h index 8183fb3886..0ef810b949 100644 --- a/src/App/FeaturePython.h +++ b/src/App/FeaturePython.h @@ -51,6 +51,7 @@ public: bool onBeforeChangeLabel(std::string &newLabel); void onChanged(const Property* prop); void onDocumentRestored(); + bool allowOverrideViewProviderName() const; std::string getViewProviderName(); PyObject *getPyObject(void); @@ -192,7 +193,10 @@ public: } return DocumentObject::StdReturn; } - virtual const char* getViewProviderNameOverride(void) const override{ + virtual bool allowOverrideViewProviderName() const { + return imp->allowOverrideViewProviderName(); + } + virtual const char* getViewProviderNameOverride(void) const override { viewProviderName = imp->getViewProviderName(); if(viewProviderName.size()) return viewProviderName.c_str();