diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 7275adc431..d9f9bd23a2 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -863,6 +863,12 @@ bool Document::redo(void) return false; } +bool Document::performsTransactionOperation() { + + return d->undoing || d->rollback; +} + + std::vector Document::getAvailableUndoNames() const { std::vector vList; diff --git a/src/App/Document.h b/src/App/Document.h index 996d37abf2..64b20fa8f4 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -306,6 +306,8 @@ public: std::vector getAvailableRedoNames() const; /// Will REDO one step, returns False if no redo was done (Redos == 0). bool redo() ; + /// returns true if the document is in an Transaction phase, e.g. currently performing a redo/undo or rollback + bool performsTransactionOperation(); //@} /** @name dependency stuff */ diff --git a/src/App/GeoFeatureGroupExtension.cpp b/src/App/GeoFeatureGroupExtension.cpp index 12333c56f9..19d88828f7 100644 --- a/src/App/GeoFeatureGroupExtension.cpp +++ b/src/App/GeoFeatureGroupExtension.cpp @@ -32,6 +32,7 @@ #include "GeoFeatureGroupExtension.h" #include "OriginFeature.h" #include "Origin.h" +#include "OriginGroupExtension.h" //#include "GeoFeatureGroupPy.h" //#include "FeaturePythonPyImp.h" @@ -81,6 +82,13 @@ void GeoFeatureGroupExtension::transformPlacement(const Base::Placement &transfo DocumentObject* GeoFeatureGroupExtension::getGroupOfObject(const DocumentObject* obj) { + if(!obj) + return nullptr; + + //we will find origins, but not origin features + if(obj->isDerivedFrom(App::OriginFeature::getClassTypeId())) + return OriginGroupExtension::getGroupOfObject(obj); + //compared to GroupExtension we do return here all geofeaturegroups including all extensions erived from it //like origingroup. That is needed as we use this function to get all local coordinate systems. Also there //is no reason to distuinguish between geofeatuergroups, there is only between group/geofeaturegroup diff --git a/src/App/Origin.cpp b/src/App/Origin.cpp index f3e41287e3..b506619eec 100644 --- a/src/App/Origin.cpp +++ b/src/App/Origin.cpp @@ -99,7 +99,7 @@ App::Plane *Origin::getPlane( const char *role ) const { } } -bool Origin::hasObject (DocumentObject *obj) const { +bool Origin::hasObject (const DocumentObject *obj) const { const auto & features = OriginFeatures.getValues (); return std::find (features.begin(), features.end(), obj) != features.end (); } diff --git a/src/App/Origin.h b/src/App/Origin.h index 1a7d0c5ab4..a36a6626f8 100644 --- a/src/App/Origin.h +++ b/src/App/Origin.h @@ -106,7 +106,7 @@ public: ///@} /// Returns true if the given object is part of the origin - bool hasObject (DocumentObject *obj) const; + bool hasObject (const DocumentObject *obj) const; /// Returns the default bounding box of the origin (use this if you confused what should be s ) // TODO Delete me if not really needed (2015-09-01, Fat-Zer) diff --git a/src/App/OriginGroupExtension.cpp b/src/App/OriginGroupExtension.cpp index a7b9ca5502..55418ebce5 100644 --- a/src/App/OriginGroupExtension.cpp +++ b/src/App/OriginGroupExtension.cpp @@ -67,10 +67,20 @@ App::Origin *OriginGroupExtension::getOrigin () const { App::DocumentObject *OriginGroupExtension::getGroupOfObject (const DocumentObject* obj) { + if(!obj) + return nullptr; + + bool isOriginFeature = obj->isDerivedFrom(App::OriginFeature::getClassTypeId()); + auto list = obj->getInList(); - for (auto obj : list) { - if(obj->hasExtension(App::OriginGroupExtension::getExtensionClassTypeId())) - return obj; + for (auto o : list) { + if(o->hasExtension(App::OriginGroupExtension::getExtensionClassTypeId())) + return o; + else if (isOriginFeature && o->isDerivedFrom(App::Origin::getClassTypeId())) { + auto result = getGroupOfObject(o); + if(result) + return result; + } } return nullptr; diff --git a/src/App/PropertyLinks.cpp b/src/App/PropertyLinks.cpp index 62838f2d0e..af835ad33e 100644 --- a/src/App/PropertyLinks.cpp +++ b/src/App/PropertyLinks.cpp @@ -51,8 +51,14 @@ void ensureDAG(PropertyContainer* container, App::DocumentObject* object) { if(!container || !object) return; + //document containers and other non-object things don't need to be handled if(!container->isDerivedFrom(App::DocumentObject::getClassTypeId())) - throw Base::Exception("Only DocumentObjects are allowed to use PropertyLinks"); + return; + + //undo and redo do not need to be handled as they can only go to already checked stated (the link + //state during those actions can get messed up, we really don't want to check for that) + if(object->getDocument()->performsTransactionOperation()) + return; auto cont = static_cast(container); @@ -71,15 +77,21 @@ void ensureDAG(PropertyContainer* container, App::DocumentObject* object) { }; //helper functions to ensure correct geofeaturegroups. Each object is only allowed to be in a -//single group, and links are not allowed to cross GeoFeatureGroup borders +//single geofeatueregroup, and links are not allowed to cross GeoFeatureGroup borders void ensureCorrectGroups(PropertyContainer* container, App::DocumentObject* object) { //on object creation the container may be null, and linked objects may be null anyhow if(!container || !object) return; + //document containers and other non-object things don't need to be handled if(!container->isDerivedFrom(App::DocumentObject::getClassTypeId())) - throw Base::Exception("Only DocumentObjects are allowed to use PropertyLinks"); + return; + + //undo and redo do not need to be handled as they can only go to already checked stated (the link + //state during those actions can get messed up, we really don't want to check for that) + if(object->getDocument()->performsTransactionOperation()) + return; auto cont = static_cast(container);