From 94082a2f73e4006eba5c872844d9660a281f9da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Thu, 9 Feb 2017 22:37:41 +0100 Subject: [PATCH] Group: ensure single group only --- src/App/GeoFeatureGroupExtension.cpp | 2 -- src/App/GeoFeatureGroupExtension.h | 1 + src/App/GroupExtension.cpp | 24 ++++++++++++++++++++++++ src/App/GroupExtension.h | 2 ++ src/Mod/Test/Document.py | 3 +++ 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/App/GeoFeatureGroupExtension.cpp b/src/App/GeoFeatureGroupExtension.cpp index 10425f6b13..0b7382f905 100644 --- a/src/App/GeoFeatureGroupExtension.cpp +++ b/src/App/GeoFeatureGroupExtension.cpp @@ -281,8 +281,6 @@ std::vector< DocumentObject* > GeoFeatureGroupExtension::getCSRelevantLinks(Docu return result; } - - // Python feature --------------------------------------------------------- namespace App { diff --git a/src/App/GeoFeatureGroupExtension.h b/src/App/GeoFeatureGroupExtension.h index a9b5d0ad4d..d4ec727b67 100644 --- a/src/App/GeoFeatureGroupExtension.h +++ b/src/App/GeoFeatureGroupExtension.h @@ -111,6 +111,7 @@ public: /// obj and from obj excluding expressions and stopping the recursion at other geofeaturegroups. /// The result is the combination of CSOutList and CSInList. static std::vector getCSRelevantLinks(App::DocumentObject* obj); + private: Base::Placement recursiveGroupPlacement(GeoFeatureGroupExtension* group); static std::vector getObjectsFromLinks(App::DocumentObject*); diff --git a/src/App/GroupExtension.cpp b/src/App/GroupExtension.cpp index 1645f82975..bd092dd8c1 100644 --- a/src/App/GroupExtension.cpp +++ b/src/App/GroupExtension.cpp @@ -243,6 +243,30 @@ PyObject* GroupExtension::getExtensionPyObject(void) { return Py::new_reference_to(ExtensionPythonObject); } +void GroupExtension::extensionOnChanged(const Property* p) { + + //we need to remove all object that have other parent geofeature groups + if(strcmp(p->getName(), "Group")==0) { + + bool error = false; + auto corrected = Group.getValues(); + for(auto obj : Group.getValues()) { + + auto grp = GroupExtension::getGroupOfObject(obj); + if(grp && (grp != getExtendedObject())) { + error = true; + corrected.erase(std::remove(corrected.begin(), corrected.end(), obj), corrected.end()); + } + } + if(error) { + Group.setValues(corrected); + throw Base::Exception("Object can only be in a single Group"); + } + } + + App::Extension::extensionOnChanged(p); +} + namespace App { EXTENSION_PROPERTY_SOURCE_TEMPLATE(App::GroupExtensionPython, App::GroupExtension) diff --git a/src/App/GroupExtension.h b/src/App/GroupExtension.h index 02b24f05c0..0dd0e91413 100644 --- a/src/App/GroupExtension.h +++ b/src/App/GroupExtension.h @@ -100,6 +100,8 @@ public: virtual PyObject* getExtensionPyObject(void); + virtual void extensionOnChanged(const Property* p) override; + /// Properties PropertyLinkList Group; diff --git a/src/Mod/Test/Document.py b/src/Mod/Test/Document.py index f8fa39d39b..5f07cebb5d 100644 --- a/src/Mod/Test/Document.py +++ b/src/Mod/Test/Document.py @@ -869,6 +869,9 @@ class UndoRedoCases(unittest.TestCase): #adding the object to a geofeaturegroup, but not its group, should handle it automatically when used #addObject + #to test: try add obj to second group, once by addObject, once by .Group = [] + + def tearDown(self): # closing doc