From 26bb702ff6d9babb62aa3827175e25644e15a88e Mon Sep 17 00:00:00 2001 From: Alexander Golubev Date: Mon, 31 Aug 2015 23:55:57 +0300 Subject: [PATCH] App: add two callback to DocumentObject to perform initialization/uninitialization inside an object Added two callbacks to App::DocumentObject - setupObject() - unsetupObject() All associated code was added to App::Document Also was added a specific flag ObjectFlag::Deleted wich is set when performing the deletion. --- src/App/Document.cpp | 38 +++++++++++++++++++++++++++++++++----- src/App/Document.h | 7 +++++-- src/App/Document.h.orig | 21 +++++++++++---------- src/App/DocumentObject.h | 9 ++++++++- 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 47054b8ea..b037f219e 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -135,12 +135,13 @@ struct DocumentP std::map objectMap; DocumentObject* activeObject; Transaction *activeUndoTransaction; - Transaction *activeTransaction; + Transaction *activeTransaction; ///< FIXME: has no effect (2015-09-01, Fat-Zer) int iTransactionMode; int iTransactionCount; std::map mTransactions; std::map vertexMap; bool rollback; + bool undoing; ///< document in the midle of undo or redo bool closable; bool keepTrailingDigits; int iUndoMode; @@ -156,6 +157,7 @@ struct DocumentP iTransactionMode = 0; iTransactionCount = 0; rollback = false; + undoing = false; closable = true; keepTrailingDigits = true; iUndoMode = 0; @@ -572,9 +574,10 @@ bool Document::undo(void) // redo d->activeUndoTransaction = new Transaction(); d->activeUndoTransaction->Name = mUndoTransactions.back()->Name; - + d->undoing = true; // applying the undo mUndoTransactions.back()->apply(*this,false); + d->undoing = false; // save the redo mRedoTransactions.push_back(d->activeUndoTransaction); @@ -603,7 +606,9 @@ bool Document::redo(void) d->activeUndoTransaction->Name = mRedoTransactions.back()->Name; // do the redo + d->undoing = true; mRedoTransactions.back()->apply(*this,true); + d->undoing = false; mUndoTransactions.push_back(d->activeUndoTransaction); d->activeUndoTransaction = 0; @@ -1110,7 +1115,7 @@ void Document::Restore(Base::XMLReader &reader) string name = reader.getAttribute("name"); try { - addObject(type.c_str(),name.c_str()); + addObject(type.c_str(), name.c_str(), /*isNew=*/ false); } catch ( Base::Exception& ) { Base::Console().Message("Cannot create object '%s'\n", name.c_str()); @@ -1226,7 +1231,7 @@ Document::readObjects(Base::XMLReader& reader) // otherwise we may cause a dependency to itself // Example: Object 'Cut001' references object 'Cut' and removing the // digits we make an object 'Cut' referencing itself. - App::DocumentObject* obj = addObject(type.c_str(),name.c_str()); + App::DocumentObject* obj = addObject(type.c_str(), name.c_str(), /*isNew=*/ false); if (obj) { objs.push_back(obj); // use this name for the later access because an object with @@ -1464,6 +1469,8 @@ void Document::restore (void) // !TODO mind exeptions while restoring! clearUndos(); for (std::vector::iterator obj = d->objectArray.begin(); obj != d->objectArray.end(); ++obj) { + // NOTE don't call unsetupObject () here due to it is intended to do some manipulations + // on other objects, but here we are wiping out document completely signalDeletedObject(*(*obj)); delete *obj; } @@ -1930,7 +1937,7 @@ void Document::recomputeFeature(DocumentObject* Feat) _recomputeFeature(Feat); } -DocumentObject * Document::addObject(const char* sType, const char* pObjectName) +DocumentObject * Document::addObject(const char* sType, const char* pObjectName, bool isNew) { Base::BaseClass* base = static_cast(Base::Type::createInstanceByName(sType,true)); @@ -1977,6 +1984,11 @@ DocumentObject * Document::addObject(const char* sType, const char* pObjectName) pcObject->Label.setValue( ObjectName ); + // Call the object-specific initialization + if (!d->undoing && !d->rollback && isNew) { + pcObject->setupObject (); + } + // mark the object as new (i.e. set status bit 2) and send the signal pcObject->StatusBits.set(2); signalNewObject(*pcObject); @@ -2066,7 +2078,15 @@ void Document::remObject(const char* sName) if (d->activeObject == pos->second) d->activeObject = 0; + // Mark the object as about to be deleted + pos->second->StatusBits.set (ObjectStatus::Delete); + if (!d->undoing && !d->rollback) { + pos->second->unsetupObject(); + } signalDeletedObject(*(pos->second)); + // TODO Check me if it's needed (2015-09-01, Fat-Zer) + pos->second->StatusBits.reset (ObjectStatus::Delete); // Unset the bit to be on the safe side + if (!d->vertexMap.empty()) { // recompute of document is running for (std::map::iterator it = d->vertexMap.begin(); it != d->vertexMap.end(); ++it) { @@ -2124,10 +2144,18 @@ void Document::_remObject(DocumentObject* pcObject) std::map::iterator pos = d->objectMap.find(pcObject->getNameInDocument()); + if (d->activeObject == pcObject) d->activeObject = 0; + // Mark the object as about to be deleted + pcObject->StatusBits.set (ObjectStatus::Delete); + if (!d->undoing && !d->rollback) { + pcObject->unsetupObject(); + } signalDeletedObject(*pcObject); + // TODO Check me if it's needed (2015-09-01, Fat-Zer) + pcObject->StatusBits.reset (ObjectStatus::Delete); // Unset the bit to be on the safe side //remove the tip if needed if(Tip.getValue() == pcObject) { diff --git a/src/App/Document.h b/src/App/Document.h index 297dec147..99dc1d6a3 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -167,9 +167,12 @@ public: /** @name Object handling */ //@{ /** Add a feature of sType with sName (ASCII) to this document and set it active. - * Unicode names are set through the Label property. + * Unicode names are set through the Label propery. + * @param sType the type of created object + * @param pObjectName if nonNULL use that name otherwise generate a new uniq name based on the \a sType + * @param isNew if false don't call the \c DocumentObject::setupObject() callback (default is true) */ - DocumentObject *addObject(const char* sType, const char* pObjectName=0); + DocumentObject *addObject(const char* sType, const char* pObjectName=0, bool isNew=true); /// Remove a feature out of the document void remObject(const char* sName); /** Add an existing feature with sName (ASCII) to this document and set it active. diff --git a/src/App/Document.h.orig b/src/App/Document.h.orig index 2e54b3586..24f469593 100644 --- a/src/App/Document.h.orig +++ b/src/App/Document.h.orig @@ -167,10 +167,20 @@ public: /** @name Object handling */ //@{ /** Add a feature of sType with sName (ASCII) to this document and set it active. +<<<<<<< aed54b532a8900cea389cf5b8a9e941402f9728f * Unicode names are set through the Label property. */ DocumentObject *addObject(const char* sType, const char* pObjectName=0); -<<<<<<< dd080ca693c9af42b6b87ee453f71fccb227b951 +======= + * Unicode names are set through the Label propery. + * @param sType the type of created object + * @param pObjectName if nonNULL use that name otherwise generate a new uniq name based on the \a sType + * @param isNew if false don't call the \c DocumentObject::setupObject() callback (default is true) + */ + DocumentObject *addObject(const char* sType, const char* pObjectName=0, bool isNew=true); +>>>>>>> App: add two callback to DocumentObject to perform initialization/uninitialization inside an object + /// Remove a feature out of the document + void remObject(const char* sName); /** Add an existing feature with sName (ASCII) to this document and set it active. * Unicode names are set through the Label property. * This is an overloaded function of the function above and can be used to create @@ -180,16 +190,7 @@ public: */ void addObject(DocumentObject*, const char* pObjectName=0); - /** Remove a feature out of the document. - * If i is marked as undeletable an exeption is thrown. If you want to delete in nonetheless set - * the function parameter \a forceIfUndeletable to true - */ - void remObject(const char* sName, bool forceIfUndeletable = false); -======= - /// Remove a feature out of the document - void remObject(const char* sName); ->>>>>>> Revert "part deletion handling" /** Copy an object from another document to this document * If \a recursive is true then all objects this object depends on * are copied as well. By default \a recursive is false. diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h index 8b32e7a5e..e4ef9ebf7 100644 --- a/src/App/DocumentObject.h +++ b/src/App/DocumentObject.h @@ -47,6 +47,7 @@ enum ObjectStatus { New = 2, Recompute = 3, Restore = 4, + Delete = 5, Expand = 16 }; @@ -114,6 +115,8 @@ public: bool isRecomputing() const {return StatusBits.test(3);} /// returns true if this objects is currently restoring from file bool isRestoring() const {return StatusBits.test(4);} + /// returns true if this objects is currently restoring from file + bool isDeleting() const {return StatusBits.test(5);} /// recompute only this object virtual App::DocumentObjectExecReturn *recompute(void); /// return the status bits @@ -194,7 +197,7 @@ protected: * 2 - object is marked as 'new' * 3 - object is marked as 'recompute', i.e. the object gets recomputed now * 4 - object is marked as 'restoring', i.e. the object gets loaded at the moment - * 5 - reserved + * 5 - object is marked as 'deleting', i.e. the object gets deleted at the moment * 6 - reserved * 7 - reserved * 16 - object is marked as 'expanded' in the tree view @@ -213,6 +216,10 @@ protected: virtual void onDocumentRestored() {} /// get called after setting the document virtual void onSettingDocument() {} + /// get called after a brand new object was created + virtual void setupObject() {} + /// get called when object is going to be removed from the document + virtual void unsetupObject() {} /// python object of this class and all descendend protected: // attributes