From 238c8a8567d48dc8fac0edc077230c66bc380294 Mon Sep 17 00:00:00 2001 From: ickby Date: Tue, 15 Aug 2017 06:26:26 +0200 Subject: [PATCH] Expose onBeforeChange to python document observer --- src/App/Application.cpp | 6 ++++++ src/App/Application.h | 3 +++ src/App/Document.cpp | 3 +++ src/App/Document.h | 2 ++ src/App/DocumentObserverPython.cpp | 26 ++++++++++++++++++++++++++ src/App/DocumentObserverPython.h | 2 ++ 6 files changed, 42 insertions(+) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index fb03814abb..624f11f296 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -418,6 +418,7 @@ Document* Application::newDocument(const char * Name, const char * UserName) // connect the signals to the application for the new document _pActiveDoc->signalNewObject.connect(boost::bind(&App::Application::slotNewObject, this, _1)); _pActiveDoc->signalDeletedObject.connect(boost::bind(&App::Application::slotDeletedObject, this, _1)); + _pActiveDoc->signalBeforeChangeObject.connect(boost::bind(&App::Application::slotBeforeChangeObject, this, _1, _2)); _pActiveDoc->signalChangedObject.connect(boost::bind(&App::Application::slotChangedObject, this, _1, _2)); _pActiveDoc->signalRelabelObject.connect(boost::bind(&App::Application::slotRelabelObject, this, _1)); _pActiveDoc->signalActivatedObject.connect(boost::bind(&App::Application::slotActivatedObject, this, _1)); @@ -987,6 +988,11 @@ void Application::slotDeletedObject(const App::DocumentObject&O) this->signalDeletedObject(O); } +void Application::slotBeforeChangeObject(const DocumentObject& O, const Property& Prop) +{ + this->signalBeforeChangeObject(O, Prop); +} + void Application::slotChangedObject(const App::DocumentObject&O, const App::Property& P) { this->signalChangedObject(O,P); diff --git a/src/App/Application.h b/src/App/Application.h index 5bc2599fbc..544e363c5c 100644 --- a/src/App/Application.h +++ b/src/App/Application.h @@ -134,6 +134,8 @@ public: /// signal on deleted Object boost::signal signalDeletedObject; /// signal on changed Object + boost::signal signalBeforeChangeObject; + /// signal on changed Object boost::signal signalChangedObject; /// signal on relabeled Object boost::signal signalRelabelObject; @@ -276,6 +278,7 @@ protected: //@{ void slotNewObject(const App::DocumentObject&); void slotDeletedObject(const App::DocumentObject&); + void slotBeforeChangeObject(const App::DocumentObject&, const App::Property& Prop); void slotChangedObject(const App::DocumentObject&, const App::Property& Prop); void slotRelabelObject(const App::DocumentObject&); void slotActivatedObject(const App::DocumentObject&); diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 90fdcc7bd0..66e4ee90b7 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -1140,6 +1140,9 @@ 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 (d->activeUndoTransaction && !d->rollback) d->activeUndoTransaction->addObjectChange(Who,What); } diff --git a/src/App/Document.h b/src/App/Document.h index 582a802e7c..18fd49941f 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -117,6 +117,8 @@ public: //boost::signal m_sig; /// signal on deleted Object boost::signal signalDeletedObject; + /// signal before changing an Object + boost::signal signalBeforeChangeObject; /// signal on changed Object boost::signal signalChangedObject; /// signal on relabeled Object diff --git a/src/App/DocumentObserverPython.cpp b/src/App/DocumentObserverPython.cpp index 621eb96760..7c2ad40724 100644 --- a/src/App/DocumentObserverPython.cpp +++ b/src/App/DocumentObserverPython.cpp @@ -76,6 +76,8 @@ 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 + (&DocumentObserverPython::slotBeforeChangeObject, this, _1, _2)); this->connectDocumentChangedObject = App::GetApplication().signalChangedObject.connect(boost::bind (&DocumentObserverPython::slotChangedObject, this, _1, _2)); @@ -247,6 +249,30 @@ void DocumentObserverPython::slotDeletedObject(const App::DocumentObject& Obj) } } +void DocumentObserverPython::slotBeforeChangeObject(const App::DocumentObject& Obj, + const App::Property& Prop) +{ + Base::PyGILStateLocker lock; + try { + if (this->inst.hasAttr(std::string("slotBeforeChangeObject"))) { + Py::Callable method(this->inst.getAttr(std::string("slotBeforeChangeObject"))); + Py::Tuple args(2); + args.setItem(0, Py::Object(const_cast(Obj).getPyObject(), true)); + // If a property is touched but not part of a document object then its name is null. + // In this case the slot function must not be called. + const char* prop_name = Obj.getPropertyName(&Prop); + if (prop_name) { + args.setItem(1, Py::String(prop_name)); + method.apply(args); + } + } + } + catch (Py::Exception&) { + Base::PyException e; // extract the Python error text + e.ReportException(); + } +} + void DocumentObserverPython::slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop) { diff --git a/src/App/DocumentObserverPython.h b/src/App/DocumentObserverPython.h index 7ddff06ee1..66375e4bc1 100644 --- a/src/App/DocumentObserverPython.h +++ b/src/App/DocumentObserverPython.h @@ -64,6 +64,8 @@ private: /** Checks if the given object is about to be removed. */ void slotDeletedObject(const App::DocumentObject& Obj); /** The property of an observed object has changed */ + void slotBeforeChangeObject(const App::DocumentObject& Obj, const App::Property& Prop); + /** The property of an observed object has changed */ void slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop); /** Undoes the last transaction of the document */ void slotUndoDocument(const App::Document& Doc);