diff --git a/src/App/DocumentObject.cpp b/src/App/DocumentObject.cpp
index 4198c42426..6a6156e0f2 100644
--- a/src/App/DocumentObject.cpp
+++ b/src/App/DocumentObject.cpp
@@ -422,10 +422,12 @@ void DocumentObject::onChanged(const Property* prop)
if (prop == &Label && _pDoc && oldLabel != Label.getStrValue())
_pDoc->signalRelabelObject(*this);
- if (prop->getType() & Prop_Output)
- return;
- // set object touched
- StatusBits.set(ObjectStatus::Touch);
+ // set object touched if it is a input ptoperty
+ if (!(prop->getType() & Prop_Output))
+ StatusBits.set(0);
+
+ //call the parent for appropriate handling
+ TransactionalObject::onChanged(prop);
}
PyObject *DocumentObject::getPyObject(void)
diff --git a/src/App/GroupExtension.cpp b/src/App/GroupExtension.cpp
index bd092dd8c1..b34da464b5 100644
--- a/src/App/GroupExtension.cpp
+++ b/src/App/GroupExtension.cpp
@@ -32,6 +32,7 @@
#include "Document.h"
#include "FeaturePythonPyImp.h"
#include "GeoFeatureGroupExtension.h"
+#include
using namespace App;
@@ -75,8 +76,14 @@ std::vector GroupExtension::addObject(DocumentObject* obj)
//if we are on a geofeaturegroup we need to ensure the object is too
auto geogrp = GeoFeatureGroupExtension::getGroupOfObject(getExtendedObject());
- if( geogrp && (geogrp != GeoFeatureGroupExtension::getGroupOfObject(obj)) )
- geogrp->getExtensionByType()->addObject(obj);
+ auto objgrp = GeoFeatureGroupExtension::getGroupOfObject(obj);
+ if( geogrp != objgrp ) {
+ //what to doo depends on if we are in geofeature group or not
+ if(geogrp)
+ geogrp->getExtensionByType()->addObject(obj);
+ else
+ objgrp->getExtensionByType()->removeObject(obj);
+ }
std::vector grp = Group.getValues();
grp.push_back(obj);
@@ -245,19 +252,29 @@ PyObject* GroupExtension::getExtensionPyObject(void) {
void GroupExtension::extensionOnChanged(const Property* p) {
- //we need to remove all object that have other parent geofeature groups
- if(strcmp(p->getName(), "Group")==0) {
+ //objects are only allowed in a single group. Note that this check must only be done for normal
+ //groups, not any derived classes
+ if((this->getExtensionTypeId() == GroupExtension::getExtensionClassTypeId()) &&
+ (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());
+ //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::GroupExtension::getExtensionClassTypeId(), false) &&
+ in != getExtendedObject()) {
+ error = true;
+ corrected.erase(std::remove(corrected.begin(), corrected.end(), obj), corrected.end());
+ break;
+ }
}
- }
+ }
+
+ //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 Group");
diff --git a/src/Mod/Test/Document.py b/src/Mod/Test/Document.py
index c1a9d051e9..039a9c581c 100644
--- a/src/Mod/Test/Document.py
+++ b/src/Mod/Test/Document.py
@@ -862,14 +862,28 @@ 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
+ except:
+ pass
+ else:
+ self.fail("No exception at cross geofeaturegroup links")
- #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 = []
-
- #test set links over geofeaturegroup borders
-
+ prt2.addObject(grp1)
+ grp = grp1.Group
+ grp.append(obj1)
+ try:
+ grp1.Group = grp
+ except:
+ pass
+ else:
+ self.fail("No exception thrown when object is in multiple Groups")
+
+
def tearDown(self):
# closing doc