Gui: add new API ViewProviderDocumentObject::allowOverride()
This API is used to delcare if a view provider can be used as an override for a give object. Conflicts: src/App/DocumentObject.h
This commit is contained in:
@@ -3540,17 +3540,8 @@ DocumentObject * Document::addObject(const char* sType, const char* pObjectName,
|
||||
|
||||
pcObject->setStatus(ObjectStatus::PartialObject, isPartial);
|
||||
|
||||
// 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')
|
||||
viewType = pcObject->getViewProviderNameOverride();
|
||||
|
||||
if (viewType && viewType[0] != '\0')
|
||||
pcObject->_pcViewProviderName = viewType;
|
||||
@@ -3644,16 +3635,8 @@ std::vector<DocumentObject *> 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);
|
||||
|
||||
// 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 : "";
|
||||
}
|
||||
const char *viewType = pcObject->getViewProviderNameOverride();
|
||||
pcObject->_pcViewProviderName = viewType ? viewType : "";
|
||||
|
||||
signalNewObject(*pcObject);
|
||||
|
||||
@@ -3711,16 +3694,8 @@ 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);
|
||||
|
||||
// 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 : "";
|
||||
}
|
||||
const char *viewType = pcObject->getViewProviderNameOverride();
|
||||
pcObject->_pcViewProviderName = viewType ? viewType : "";
|
||||
|
||||
signalNewObject(*pcObject);
|
||||
|
||||
@@ -3751,16 +3726,8 @@ void Document::_addObject(DocumentObject* pcObject, const char* pObjectName)
|
||||
d->activeUndoTransaction->addObjectDel(pcObject);
|
||||
}
|
||||
|
||||
// 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 : "";
|
||||
}
|
||||
const char *viewType = pcObject->getViewProviderNameOverride();
|
||||
pcObject->_pcViewProviderName = viewType ? viewType : "";
|
||||
|
||||
// send the signal
|
||||
signalNewObject(*pcObject);
|
||||
|
||||
@@ -114,22 +114,15 @@ public:
|
||||
* 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.
|
||||
* The core will only accept the overridden view provider if it returns
|
||||
* true when calling Gui::ViewProviderDocumentObject::allowOverride(obj).
|
||||
* If not, the view provider will be reverted to the one returned from \ref
|
||||
* getViewProviderName().
|
||||
*/
|
||||
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 overridden 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();
|
||||
|
||||
@@ -435,11 +435,6 @@ int FeaturePythonImp::setElementVisible(const char *element, bool visible) {
|
||||
}
|
||||
}
|
||||
|
||||
bool FeaturePythonImp::allowOverrideViewProviderName() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string FeaturePythonImp::getViewProviderName()
|
||||
{
|
||||
_FC_PY_CALL_CHECK(getViewProviderName,return(std::string()));
|
||||
|
||||
@@ -57,7 +57,6 @@ public:
|
||||
bool onBeforeChangeLabel(std::string &newLabel);
|
||||
void onChanged(const Property* prop);
|
||||
void onDocumentRestored();
|
||||
bool allowOverrideViewProviderName() const;
|
||||
std::string getViewProviderName();
|
||||
PyObject *getPyObject(void);
|
||||
|
||||
@@ -200,9 +199,6 @@ public:
|
||||
}
|
||||
return DocumentObject::StdReturn;
|
||||
}
|
||||
virtual bool allowOverrideViewProviderName() const {
|
||||
return imp->allowOverrideViewProviderName();
|
||||
}
|
||||
virtual const char* getViewProviderNameOverride(void) const override {
|
||||
viewProviderName = imp->getViewProviderName();
|
||||
if(viewProviderName.size())
|
||||
|
||||
@@ -621,44 +621,52 @@ void Document::slotNewObject(const App::DocumentObject& Obj)
|
||||
if (!pcProvider) {
|
||||
//Base::Console().Log("Document::slotNewObject() called\n");
|
||||
std::string cName = Obj.getViewProviderNameStored();
|
||||
if (cName.empty()) {
|
||||
// handle document object with no view provider specified
|
||||
Base::Console().Log("%s has no view provider specified\n", Obj.getTypeId().getName());
|
||||
return;
|
||||
for(;;) {
|
||||
if (cName.empty()) {
|
||||
// handle document object with no view provider specified
|
||||
FC_LOG(Obj.getFullName() << " has no view provider specified");
|
||||
return;
|
||||
}
|
||||
Base::BaseClass* base = static_cast<Base::BaseClass*>(
|
||||
Base::Type::createInstanceByName(cName.c_str(),true));
|
||||
pcProvider = Base::freecad_dynamic_cast<ViewProviderDocumentObject>(base);
|
||||
if (!pcProvider) {
|
||||
// type not derived from ViewProviderDocumentObject!!!
|
||||
FC_ERR("Invalid view provider type '" << cName << "' for " << Obj.getFullName());
|
||||
delete base;
|
||||
return;
|
||||
} else if (cName!=Obj.getViewProviderName() && !pcProvider->allowOverride(Obj)) {
|
||||
FC_WARN("View provider type '" << cName << "' does not support " << Obj.getFullName());
|
||||
delete base;
|
||||
pcProvider = 0;
|
||||
cName = Obj.getViewProviderName();
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
setModified(true);
|
||||
Base::BaseClass* base = static_cast<Base::BaseClass*>(Base::Type::createInstanceByName(cName.c_str(),true));
|
||||
if (base) {
|
||||
// type not derived from ViewProviderDocumentObject!!!
|
||||
assert(base->getTypeId().isDerivedFrom(Gui::ViewProviderDocumentObject::getClassTypeId()));
|
||||
pcProvider = static_cast<ViewProviderDocumentObject*>(base);
|
||||
d->_ViewProviderMap[&Obj] = pcProvider;
|
||||
d->_CoinMap[pcProvider->getRoot()] = pcProvider;
|
||||
pcProvider->setStatus(Gui::ViewStatus::TouchDocument, d->_changeViewTouchDocument);
|
||||
d->_ViewProviderMap[&Obj] = pcProvider;
|
||||
d->_CoinMap[pcProvider->getRoot()] = pcProvider;
|
||||
pcProvider->setStatus(Gui::ViewStatus::TouchDocument, d->_changeViewTouchDocument);
|
||||
|
||||
try {
|
||||
// if successfully created set the right name and calculate the view
|
||||
//FIXME: Consider to change argument of attach() to const pointer
|
||||
pcProvider->attach(const_cast<App::DocumentObject*>(&Obj));
|
||||
pcProvider->updateView();
|
||||
pcProvider->setActiveMode();
|
||||
}
|
||||
catch(const Base::MemoryException& e){
|
||||
FC_ERR("Memory exception in " << Obj.getFullName() << " thrown: " << e.what());
|
||||
}
|
||||
catch(Base::Exception &e){
|
||||
e.ReportException();
|
||||
}
|
||||
try {
|
||||
// if successfully created set the right name and calculate the view
|
||||
//FIXME: Consider to change argument of attach() to const pointer
|
||||
pcProvider->attach(const_cast<App::DocumentObject*>(&Obj));
|
||||
pcProvider->updateView();
|
||||
pcProvider->setActiveMode();
|
||||
}
|
||||
catch(const Base::MemoryException& e){
|
||||
FC_ERR("Memory exception in " << Obj.getFullName() << " thrown: " << e.what());
|
||||
}
|
||||
catch(Base::Exception &e){
|
||||
e.ReportException();
|
||||
}
|
||||
#ifndef FC_DEBUG
|
||||
catch(...){
|
||||
FC_ERR("Unknown exception in Feature " << Obj.getFullName() << " thrown");
|
||||
}
|
||||
catch(...){
|
||||
FC_ERR("Unknown exception in Feature " << Obj.getFullName() << " thrown");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
FC_WARN("no view provider for the object " << cName << " found");
|
||||
}
|
||||
}else{
|
||||
try {
|
||||
pcProvider->reattach(const_cast<App::DocumentObject*>(&Obj));
|
||||
|
||||
@@ -139,6 +139,14 @@ public:
|
||||
|
||||
virtual std::string getFullName() const override;
|
||||
|
||||
/** Allow this class to be used as an override for the original view provider of the given object
|
||||
*
|
||||
* @sa App::DocumentObject::getViewProviderNameOverride()
|
||||
*/
|
||||
virtual bool allowOverride(const App::DocumentObject &) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
/*! Get the active mdi view of the document this view provider is part of.
|
||||
@note The returned mdi view doesn't need to be a 3d view but can be e.g.
|
||||
|
||||
@@ -1711,15 +1711,22 @@ QPixmap ViewProviderLink::getOverlayPixmap() const {
|
||||
void ViewProviderLink::onChanged(const App::Property* prop) {
|
||||
if(prop==&ChildViewProvider) {
|
||||
childVp = freecad_dynamic_cast<ViewProviderDocumentObject>(ChildViewProvider.getObject().get());
|
||||
if(childVp) {
|
||||
childVp->setPropertyPrefix("ChildViewProvider.");
|
||||
childVp->Visibility.setValue(getObject()->Visibility.getValue());
|
||||
childVp->attach(getObject());
|
||||
childVp->updateView();
|
||||
childVp->setActiveMode();
|
||||
if(pcModeSwitch->getNumChildren()>1){
|
||||
childVpLink = LinkInfo::get(childVp,0);
|
||||
pcModeSwitch->replaceChild(1,childVpLink->getSnapshot(LinkView::SnapshotTransform));
|
||||
if(childVp && getObject()) {
|
||||
if(strcmp(childVp->getTypeId().getName(),getObject()->getViewProviderName())!=0
|
||||
&& !childVp->allowOverride(*getObject()))
|
||||
{
|
||||
FC_ERR("Child view provider type '" << childVp->getTypeId().getName()
|
||||
<< "' does not support " << getObject()->getFullName());
|
||||
} else {
|
||||
childVp->setPropertyPrefix("ChildViewProvider.");
|
||||
childVp->Visibility.setValue(getObject()->Visibility.getValue());
|
||||
childVp->attach(getObject());
|
||||
childVp->updateView();
|
||||
childVp->setActiveMode();
|
||||
if(pcModeSwitch->getNumChildren()>1){
|
||||
childVpLink = LinkInfo::get(childVp,0);
|
||||
pcModeSwitch->replaceChild(1,childVpLink->getSnapshot(LinkView::SnapshotTransform));
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if(!isRestoring()) {
|
||||
|
||||
@@ -265,6 +265,10 @@ public:
|
||||
virtual ViewProviderDocumentObject *getLinkedViewProvider(
|
||||
std::string *subname=0, bool recursive=false) const override;
|
||||
|
||||
virtual bool allowOverride(const App::DocumentObject &) const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool setEdit(int ModNum) override;
|
||||
void setEditViewer(View3DInventorViewer*, int ModNum) override;
|
||||
|
||||
@@ -467,6 +467,12 @@ void ViewProviderPartExt::onChanged(const App::Property* prop)
|
||||
ViewProviderGeometryObject::onChanged(prop);
|
||||
}
|
||||
|
||||
bool ViewProviderPartExt::allowOverride(const App::DocumentObject &) const {
|
||||
// Many derived view providers still uses static_cast to get object
|
||||
// pointer, so check for exact type here.
|
||||
return getTypeId() == ViewProviderPartExt::getClassTypeId();
|
||||
}
|
||||
|
||||
void ViewProviderPartExt::attach(App::DocumentObject *pcFeat)
|
||||
{
|
||||
// call parent attach method
|
||||
|
||||
@@ -134,6 +134,8 @@ public:
|
||||
}
|
||||
virtual void forceUpdate(bool enable = true) override;
|
||||
|
||||
virtual bool allowOverride(const App::DocumentObject &) const override;
|
||||
|
||||
/** @name Edit methods */
|
||||
//@{
|
||||
void setupContextMenu(QMenu*, QObject*, const char*) override;
|
||||
|
||||
Reference in New Issue
Block a user