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.
This commit is contained in:
Alexander Golubev 2015-08-31 23:55:57 +03:00 committed by Stefan Tröger
parent c6797b6c29
commit 26bb702ff6
4 changed files with 57 additions and 18 deletions

View File

@ -135,12 +135,13 @@ struct DocumentP
std::map<std::string,DocumentObject*> objectMap;
DocumentObject* activeObject;
Transaction *activeUndoTransaction;
Transaction *activeTransaction;
Transaction *activeTransaction; ///< FIXME: has no effect (2015-09-01, Fat-Zer)
int iTransactionMode;
int iTransactionCount;
std::map<int,Transaction*> mTransactions;
std::map<Vertex,DocumentObject*> 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<DocumentObject*>::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::BaseClass*>(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<Vertex,DocumentObject*>::iterator it = d->vertexMap.begin(); it != d->vertexMap.end(); ++it) {
@ -2124,10 +2144,18 @@ void Document::_remObject(DocumentObject* pcObject)
std::map<std::string,DocumentObject*>::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) {

View File

@ -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.

View File

@ -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.

View File

@ -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