From c0a270a76ef9a10a7a903977834f51a802a69b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Mon, 5 Jun 2017 08:54:21 +0200 Subject: [PATCH] Ensure objects to be in a single GeoFeatureGroup only --- src/App/GeoFeatureGroupExtension.cpp | 32 ++++++++++++++++++++++++++++ src/App/GeoFeatureGroupExtension.h | 2 ++ src/App/GroupExtension.cpp | 1 - src/Mod/Test/Document.py | 30 ++++++++++++++++---------- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/App/GeoFeatureGroupExtension.cpp b/src/App/GeoFeatureGroupExtension.cpp index 42d2dead2c..e57aecf21e 100644 --- a/src/App/GeoFeatureGroupExtension.cpp +++ b/src/App/GeoFeatureGroupExtension.cpp @@ -178,6 +178,38 @@ std::vector GeoFeatureGroupExtension::removeObjects(std::vector return removed; } +void GeoFeatureGroupExtension::extensionOnChanged(const Property* p) { + + //objects are only allowed in a single GeoFeatureGroup + if((strcmp(p->getName(), "Group")==0)) { + + bool error = false; + auto corrected = Group.getValues(); + for(auto obj : Group.getValues()) { + + //we have already set the obj into the group, so in a case of multiple groups getGroupOfObject + //would return anyone of it and hence it is possible that we miss an error. We need a custom check + auto list = obj->getInList(); + for (auto in : list) { + if(in->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId()) && + in != getExtendedObject()) { + error = true; + corrected.erase(std::remove(corrected.begin(), corrected.end(), obj), corrected.end()); + } + } + } + + //if an error was found we need to correct the values and inform the user + if(error) { + Group.setValues(corrected); + throw Base::Exception("Object can only be in a single GeoFeatureGroup"); + } + } + + App::GroupExtension::extensionOnChanged(p); +} + + std::vector< DocumentObject* > GeoFeatureGroupExtension::getObjectsFromLinks(DocumentObject* obj) { //we get all linked objects. We can't use outList() as this includes the links from expressions diff --git a/src/App/GeoFeatureGroupExtension.h b/src/App/GeoFeatureGroupExtension.h index 47bc42200a..ae3246f4c9 100644 --- a/src/App/GeoFeatureGroupExtension.h +++ b/src/App/GeoFeatureGroupExtension.h @@ -68,6 +68,8 @@ public: /// Constructor GeoFeatureGroupExtension(void); virtual ~GeoFeatureGroupExtension(); + + virtual void extensionOnChanged(const Property* p); /** Returns the geo feature group which contains this object. * In case this object is not part of any geoFeatureGroup 0 is returned. diff --git a/src/App/GroupExtension.cpp b/src/App/GroupExtension.cpp index de219972a7..3437683638 100644 --- a/src/App/GroupExtension.cpp +++ b/src/App/GroupExtension.cpp @@ -272,7 +272,6 @@ void GroupExtension::extensionOnChanged(const Property* p) { in != getExtendedObject()) { error = true; corrected.erase(std::remove(corrected.begin(), corrected.end(), obj), corrected.end()); - break; } } } diff --git a/src/Mod/Test/Document.py b/src/Mod/Test/Document.py index a09558d65d..f9ce372af4 100644 --- a/src/Mod/Test/Document.py +++ b/src/Mod/Test/Document.py @@ -873,19 +873,17 @@ class UndoRedoCases(unittest.TestCase): self.failUnless(prt1.hasObject(obj1)==False) self.failUnless(prt2.hasObject(grp2)) self.failUnless(prt2.hasObject(obj1)) - - #to test: try add obj to second group by .Group = [] - grp = prt1.Group - grp.append(grp2) - try: - prt1.Group=grp - self.Doc.recompute() + grp = prt1.Group + grp.append(obj1) + prt1.Group = grp except: - pass + grp.remove(obj1) + self.failUnless(prt1.Group == grp) else: - self.fail("No exception at cross geofeaturegroup links") - + self.fail("No exception thrown when object is in multiple Groups") + + #it is not allowed to be in 2 Groups prt2.addObject(grp1) grp = grp1.Group grp.append(obj1) @@ -896,7 +894,17 @@ class UndoRedoCases(unittest.TestCase): else: self.fail("No exception thrown when object is in multiple Groups") - + #to test: try add obj to second group by .Group = [] + grp = prt1.Group + grp.append(grp2) + + try: + prt1.Group=grp + self.Doc.recompute() + except: + pass + else: + self.fail("No exception at cross geofeaturegroup links") def tearDown(self): # closing doc