From e91de65df0af17eff22d7e3b050e36e31d682055 Mon Sep 17 00:00:00 2001 From: ickby Date: Sun, 9 Sep 2018 15:08:24 +0200 Subject: [PATCH] Fix and test the new signals --- src/App/Document.cpp | 12 +- src/App/DocumentObserverPython.cpp | 5 +- src/App/DocumentObserverPython.h | 1 + src/Mod/Test/Document.py | 201 +++++++++++++++++++++++++++++ 4 files changed, 212 insertions(+), 7 deletions(-) diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 66e4ee90b7..533ba01fdf 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -962,7 +962,7 @@ void Document::openTransaction(const char* name) else d->activeUndoTransaction->Name = ""; - signalOpenTransaction(*this, name); + signalOpenTransaction(*this, d->activeUndoTransaction->Name); } } @@ -1140,8 +1140,8 @@ void Document::onChanged(const Property* prop) void Document::onBeforeChangeProperty(const TransactionalObject *Who, const Property *What) { - if(Who->isDerivedFrom(App::DocumentObject::getClassTypeId()) - signalBeforeChangeObject(*static_cast(Who), *What); + if(Who->isDerivedFrom(App::DocumentObject::getClassTypeId())) + signalBeforeChangeObject(*static_cast(Who), *What); if (d->activeUndoTransaction && !d->rollback) d->activeUndoTransaction->addObjectChange(Who,What); @@ -2252,7 +2252,7 @@ int Document::recompute() if ((*objIt)->isTouched() || doRecompute) { (*objIt)->purgeTouched(); - signalObjectRecomputed(*(*objOt)); + signalRecomputedObject(*(*objIt)); // force recompute of all dependent objects for (auto inObjIt : (*objIt)->getInList()) inObjIt->enforceRecompute(); @@ -2522,8 +2522,10 @@ void Document::recomputeFeature(DocumentObject* Feat) _RecomputeLog.clear(); // verify that the feature is (active) part of the document - if (Feat->getNameInDocument()) + if (Feat->getNameInDocument()) { _recomputeFeature(Feat); + signalRecomputedObject(*Feat); + } } DocumentObject * Document::addObject(const char* sType, const char* pObjectName, bool isNew) diff --git a/src/App/DocumentObserverPython.cpp b/src/App/DocumentObserverPython.cpp index 7c2ad40724..9f127b5e0a 100644 --- a/src/App/DocumentObserverPython.cpp +++ b/src/App/DocumentObserverPython.cpp @@ -76,7 +76,7 @@ DocumentObserverPython::DocumentObserverPython(const Py::Object& obj) : inst(obj (&DocumentObserverPython::slotCreatedObject, this, _1)); this->connectDocumentDeletedObject = App::GetApplication().signalDeletedObject.connect(boost::bind (&DocumentObserverPython::slotDeletedObject, this, _1)); - this->connectDocumentChangedObject = App::GetApplication().signalBeforeChangeObject.connect(boost::bind + this->connectDocumentBeforeChangeObject = App::GetApplication().signalBeforeChangeObject.connect(boost::bind (&DocumentObserverPython::slotBeforeChangeObject, this, _1, _2)); this->connectDocumentChangedObject = App::GetApplication().signalChangedObject.connect(boost::bind (&DocumentObserverPython::slotChangedObject, this, _1, _2)); @@ -105,6 +105,7 @@ DocumentObserverPython::~DocumentObserverPython() this->connectDocumentCreatedObject.disconnect(); this->connectDocumentDeletedObject.disconnect(); + this->connectDocumentBeforeChangeObject.disconnect(); this->connectDocumentChangedObject.disconnect(); this->connectDocumentObjectRecomputed.disconnect(); this->connectDocumentRecomputed.disconnect(); @@ -381,4 +382,4 @@ void DocumentObserverPython::slotAbortTransaction(const App::Document& doc) Base::PyException e; // extract the Python error text e.ReportException(); } -} \ No newline at end of file +} diff --git a/src/App/DocumentObserverPython.h b/src/App/DocumentObserverPython.h index 66375e4bc1..e6a0a772e1 100644 --- a/src/App/DocumentObserverPython.h +++ b/src/App/DocumentObserverPython.h @@ -95,6 +95,7 @@ private: Connection connectApplicationRedoDocument; Connection connectDocumentCreatedObject; Connection connectDocumentDeletedObject; + Connection connectDocumentBeforeChangeObject; Connection connectDocumentChangedObject; Connection connectDocumentObjectRecomputed; Connection connectDocumentRecomputed; diff --git a/src/Mod/Test/Document.py b/src/Mod/Test/Document.py index ec242aa71d..8eaff2721a 100644 --- a/src/Mod/Test/Document.py +++ b/src/Mod/Test/Document.py @@ -1309,3 +1309,204 @@ class DocumentExpressionCases(unittest.TestCase): def tearDown(self): #closing doc FreeCAD.closeDocument(self.Doc.Name) + + +class DocumentObserverCases(unittest.TestCase): + + class Observer(): + + signal = [] + parameter = None + parameter2 = None + + def slotCreatedDocument(self, doc): + self.signal.append('DocCreated'); + self.parameter = doc; + + def slotDeletedDocument(self, doc): + self.signal.append('DocDeleted'); + self.parameter = doc; + + def slotRelabelDocument(self, doc): + self.signal.append('DocRelabled'); + self.parameter = doc; + + def slotActivateDocument(self, doc): + self.signal.append('DocActivated'); + self.parameter = doc; + + def slotRecomputedDocument(self, doc): + self.signal.append('DocRecomputed'); + self.parameter = doc; + + def slotUndoDocument(self, doc): + self.signal.append('DocUndo'); + self.parameter = doc; + + def slotRedoDocument(self, doc): + self.signal.append('DocRedo'); + self.parameter = doc; + + def slotOpenTransaction(self, doc, name): + self.signal.append('DocOpenTransaction'); + self.parameter = doc; + self.parameter2 = name; + + def slotCommitTransaction(self, doc): + self.signal.append('DocCommitTransaction'); + self.parameter = doc; + + def slotAbortTransaction(self, doc): + self.signal.append('DocAbortTransaction'); + self.parameter = doc; + + def slotCreatedObject(self, obj): + self.signal.append('ObjCreated'); + self.parameter = obj; + + def slotDeletedObject(self, obj): + self.signal.append('ObjDeleted'); + self.parameter = obj; + + def slotChangedObject(self, obj, prop): + self.signal.append('ObjChanged'); + self.parameter = obj; + self.parameter2 = prop; + + def slotBeforeChangeObject(self, obj, prop): + self.signal.append('ObjBeforeChange'); + self.parameter = obj; + self.parameter2 = prop; + + def slotRecomputedObject(self, obj): + self.signal.append('ObjRecomputed'); + self.parameter = obj; + + + def setUp(self): + self.Obs = self.Observer(); + FreeCAD.addDocumentObserver(self.Obs); + + def testDocument(self): + + # testing document level signals + self.Doc1 = FreeCAD.newDocument("Observer1"); + self.failUnless(self.Obs.signal.pop(0) == 'DocActivated') + self.failUnless(self.Obs.signal.pop(0) == 'DocCreated') + self.failUnless(self.Obs.signal.pop(0) == 'DocRelabled') + self.failUnless(self.Obs.parameter is self.Doc1) + self.failUnless(not self.Obs.signal) + + self.Doc2 = FreeCAD.newDocument("Observer2"); + self.failUnless(self.Obs.signal.pop(0) == 'DocActivated') + self.failUnless(self.Obs.signal.pop(0) == 'DocCreated') + self.failUnless(self.Obs.signal.pop(0) == 'DocRelabled') + self.failUnless(self.Obs.parameter is self.Doc2) + self.failUnless(not self.Obs.signal) + + FreeCAD.setActiveDocument('Observer1') + self.failUnless(self.Obs.signal.pop() == 'DocActivated') + self.failUnless(self.Obs.parameter is self.Doc1) + self.failUnless(not self.Obs.signal) + + self.Doc2.openTransaction('test') + self.failUnless(self.Obs.signal.pop() == 'DocOpenTransaction') + self.failUnless(self.Obs.parameter is self.Doc2) + self.failUnless(self.Obs.parameter2 == 'test') + self.failUnless(not self.Obs.signal) + + self.Doc2.commitTransaction() + self.failUnless(self.Obs.signal.pop() == 'DocCommitTransaction') + self.failUnless(self.Obs.parameter is self.Doc2) + self.failUnless(not self.Obs.signal) + + self.Doc2.openTransaction('test2') + self.failUnless(self.Obs.signal.pop() == 'DocOpenTransaction') + self.failUnless(self.Obs.parameter is self.Doc2) + self.failUnless(not self.Obs.signal) + + self.Doc2.abortTransaction() + self.failUnless(self.Obs.signal.pop() == 'DocAbortTransaction') + self.failUnless(self.Obs.parameter is self.Doc2) + self.failUnless(not self.Obs.signal) + + self.Doc2.undo() + self.failUnless(self.Obs.signal.pop() == 'DocUndo') + self.failUnless(self.Obs.parameter is self.Doc2) + self.failUnless(not self.Obs.signal) + + self.Doc2.redo() + self.failUnless(self.Obs.signal.pop() == 'DocRedo') + self.failUnless(self.Obs.parameter is self.Doc2) + self.failUnless(not self.Obs.signal) + + FreeCAD.closeDocument('Observer2') + self.failUnless(self.Obs.signal.pop() == 'DocDeleted') + self.failUnless(self.Obs.parameter is self.Doc2) + self.failUnless(not self.Obs.signal) + + FreeCAD.closeDocument('Observer1') + self.failUnless(self.Obs.signal.pop() == 'DocDeleted') + self.failUnless(self.Obs.parameter is self.Doc1) + self.failUnless(not self.Obs.signal) + + def testObject(self): + #testing signal on object changes + + self.Doc1 = FreeCAD.newDocument("Observer1") + self.Obs.signal = [] + + obj = self.Doc1.addObject("App::DocumentObject","obj") + self.failUnless(self.Obs.signal.pop() == 'ObjCreated') + self.failUnless(self.Obs.parameter is obj) + #there are multiple object change signals + self.Obs.signal = [] + + obj.Label = "myobj" + self.failUnless(self.Obs.signal.pop(0) == 'ObjBeforeChange') + self.failUnless(self.Obs.signal.pop(0) == 'ObjChanged') + self.failUnless(self.Obs.parameter is obj) + self.failUnless(self.Obs.parameter2 == "Label") + self.failUnless(not self.Obs.signal) + + obj.touch() + obj.recompute() + self.failUnless(self.Obs.signal.pop(0) == 'ObjRecomputed') + self.failUnless(self.Obs.parameter is obj) + self.failUnless(not self.Obs.signal) + + obj.touch() + self.Doc1.recompute() + self.failUnless(self.Obs.signal.pop(0) == 'ObjRecomputed') + self.failUnless(self.Obs.signal.pop(0) == 'DocRecomputed') + self.failUnless(self.Obs.parameter is self.Doc1) + self.failUnless(not self.Obs.signal) + + FreeCAD.ActiveDocument.removeObject(obj.Name) + self.failUnless(self.Obs.signal.pop(0) == 'ObjDeleted') + self.failUnless(self.Obs.parameter is obj) + self.failUnless(not self.Obs.signal) + + FreeCAD.closeDocument('Observer1') + self.Obs.signal = [] + + def testUndoDisabledDocument(self): + + # testing document level signals + self.Doc1 = FreeCAD.newDocument("Observer1"); + self.Doc1.UndoMode = 0 + self.Obs.signal = [] + + self.Doc1.openTransaction('test') + self.Doc1.commitTransaction() + self.Doc1.undo() + self.Doc1.redo() + self.failUnless(not self.Obs.signal) + + FreeCAD.closeDocument('Observer1') + self.Obs.signal = [] + + def tearDown(self): + #closing doc + FreeCAD.removeDocumentObserver(self.Obs) + self.Obs = None