remove properties from transactions when being deleted

This commit is contained in:
wmayer
2017-08-28 21:20:17 +02:00
parent 5219cb5b38
commit a5bc70cca0
13 changed files with 64 additions and 8 deletions

View File

@@ -869,6 +869,17 @@ bool Document::redo(void)
return false;
}
void Document::removePropertyOfObject(TransactionalObject* obj, const char* name)
{
Property* prop = obj->getDynamicPropertyByName(name);
if (prop) {
if (d->activeUndoTransaction)
d->activeUndoTransaction->removeProperty(obj, prop);
for (auto it : mUndoTransactions)
it->removeProperty(obj, prop);
}
}
bool Document::isPerformingTransaction() const
{
return d->undoing || d->rollback;

View File

@@ -309,6 +309,8 @@ public:
bool redo() ;
/// returns true if the document is in an Transaction phase, e.g. currently performing a redo/undo or rollback
bool isPerformingTransaction() const;
/// \internal remove property from a transactional object with name \a name
void removePropertyOfObject(TransactionalObject*, const char*);
//@}
/** @name dependency stuff */

View File

@@ -402,6 +402,12 @@ void DocumentObject::setDocument(App::Document* doc)
onSettingDocument();
}
void DocumentObject::onAboutToRemoveProperty(const char* prop)
{
if (_pDoc)
_pDoc->removePropertyOfObject(this, prop);
}
void DocumentObject::onBeforeChange(const Property* prop)
{
// Store current name in oldLabel, to be able to easily retrieve old name of document object later

View File

@@ -255,6 +255,8 @@ protected:
void resetError(void){StatusBits.reset(ObjectStatus::Error);}
void setDocument(App::Document* doc);
/// \internal get called when removing a property of name \a prop
void onAboutToRemoveProperty(const char* prop);
/// get called before the value is changed
virtual void onBeforeChange(const Property* prop);
/// get called by the container when a property was changed

View File

@@ -79,6 +79,7 @@ public:
return props->addDynamicProperty(type, name, group, doc, attr, ro, hidden);
}
virtual bool removeDynamicProperty(const char* name) {
FeatureT::onAboutToRemoveProperty(name);
return props->removeDynamicProperty(name);
}
std::vector<std::string> getDynamicPropertyNames() const {

View File

@@ -110,6 +110,7 @@ public:
return props->addDynamicProperty(type, name, group, doc, attr, ro, hidden);
}
virtual bool removeDynamicProperty(const char* name) {
FeatureT::onAboutToRemoveProperty(name);
return props->removeDynamicProperty(name);
}
std::vector<std::string> getDynamicPropertyNames() const {

View File

@@ -114,6 +114,15 @@ bool Transaction::hasObject(const TransactionalObject *Obj) const
return false;
}
void Transaction::removeProperty(TransactionalObject *Obj,
const Property* pcProp)
{
for (auto it : _Objects) {
if (it.first == Obj)
it.second->removeProperty(pcProp);
}
}
//**************************************************************************
// separator for other implemetation aspects
@@ -277,6 +286,15 @@ void TransactionObject::setProperty(const Property* pcProp)
_PropChangeMap[pcProp] = pcProp->Copy();
}
void TransactionObject::removeProperty(const Property* pcProp)
{
std::map<const Property*, Property*>::iterator pos = _PropChangeMap.find(pcProp);
if (pos != _PropChangeMap.end()) {
delete pos->second;
_PropChangeMap.erase(pos);
}
}
unsigned int TransactionObject::getMemSize (void) const
{
return 0;

View File

@@ -66,6 +66,7 @@ public:
int getPos(void) const;
/// check if this object is used in a transaction
bool hasObject(const TransactionalObject *Obj) const;
void removeProperty(TransactionalObject *Obj, const Property* pcProp);
void addObjectNew(TransactionalObject *Obj);
void addObjectDel(const TransactionalObject *Obj);
@@ -94,6 +95,7 @@ public:
virtual void applyChn(Document &Doc, TransactionalObject *pcObj, bool Forward);
void setProperty(const Property* pcProp);
void removeProperty(const Property* pcProp);
virtual unsigned int getMemSize (void) const;
virtual void Save (Base::Writer &writer) const;

View File

@@ -94,6 +94,15 @@ const char* ViewProviderDocumentObject::detachFromDocument()
return "";
}
void ViewProviderDocumentObject::onAboutToRemoveProperty(const char* prop)
{
// transactions of view providers are also managed in App::Document.
App::DocumentObject* docobject = getObject();
App::Document* document = docobject ? docobject->getDocument() : nullptr;
if (document)
document->removePropertyOfObject(this, prop);
}
void ViewProviderDocumentObject::onBeforeChange(const App::Property* prop)
{
if (isAttachedToDocument()) {

View File

@@ -126,6 +126,8 @@ protected:
/** @name Transaction handling
*/
//@{
/// \internal get called when removing a property of name \a prop
void onAboutToRemoveProperty(const char* prop);
virtual bool isAttachedToDocument() const;
virtual const char* detachFromDocument();
//@}

View File

@@ -301,6 +301,7 @@ public:
return props->addDynamicProperty(type, name, group, doc, attr, ro, hidden);
}
virtual bool removeDynamicProperty(const char* name) {
ViewProviderT::onAboutToRemoveProperty(name);
return props->removeDynamicProperty(name);
}
std::vector<std::string> getDynamicPropertyNames() const {

View File

@@ -113,7 +113,7 @@ void Sheet::clearAll()
std::vector<std::string> propNames = props.getDynamicPropertyNames();
for (std::vector<std::string>::const_iterator i = propNames.begin(); i != propNames.end(); ++i)
props.removeDynamicProperty((*i).c_str());
this->removeDynamicProperty((*i).c_str());
propAddress.clear();
cellErrors.clear();
@@ -460,7 +460,7 @@ void Sheet::removeAliases()
std::map<CellAddress, std::string>::iterator i = removedAliases.begin();
while (i != removedAliases.end()) {
props.removeDynamicProperty(i->second.c_str());
this->removeDynamicProperty(i->second.c_str());
++i;
}
removedAliases.clear();
@@ -491,7 +491,7 @@ Property * Sheet::setFloatProperty(CellAddress key, double value)
if (!prop || prop->getTypeId() != PropertyFloat::getClassTypeId()) {
if (prop) {
props.removeDynamicProperty(key.toString().c_str());
this->removeDynamicProperty(key.toString().c_str());
propAddress.erase(prop);
}
floatProp = freecad_dynamic_cast<PropertyFloat>(props.addDynamicProperty("App::PropertyFloat", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Hidden | Prop_Transient));
@@ -522,7 +522,7 @@ Property * Sheet::setQuantityProperty(CellAddress key, double value, const Base:
if (!prop || prop->getTypeId() != PropertySpreadsheetQuantity::getClassTypeId()) {
if (prop) {
props.removeDynamicProperty(key.toString().c_str());
this->removeDynamicProperty(key.toString().c_str());
propAddress.erase(prop);
}
Property * p = props.addDynamicProperty("Spreadsheet::PropertySpreadsheetQuantity", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Hidden | Prop_Transient);
@@ -556,7 +556,7 @@ Property * Sheet::setStringProperty(CellAddress key, const std::string & value)
if (!stringProp) {
if (prop) {
props.removeDynamicProperty(key.toString().c_str());
this->removeDynamicProperty(key.toString().c_str());
propAddress.erase(prop);
}
stringProp = freecad_dynamic_cast<PropertyString>(props.addDynamicProperty("App::PropertyString", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Hidden | Prop_Transient));
@@ -590,7 +590,7 @@ void Sheet::updateAlias(CellAddress key)
if (aliasProp) {
// Type of alias and property must always be the same
if (aliasProp->getTypeId() != prop->getTypeId()) {
props.removeDynamicProperty(alias.c_str());
this->removeDynamicProperty(alias.c_str());
aliasProp = 0;
}
}
@@ -882,7 +882,7 @@ void Sheet::clear(CellAddress address, bool /*all*/)
// Remove alias, if defined
std::string aliasStr;
if (cell && cell->getAlias(aliasStr))
props.removeDynamicProperty(aliasStr.c_str());
this->removeDynamicProperty(aliasStr.c_str());
cells.clear(address);
@@ -896,7 +896,7 @@ void Sheet::clear(CellAddress address, bool /*all*/)
docDeps.setValues(dv);
propAddress.erase(prop);
props.removeDynamicProperty(addr.c_str());
this->removeDynamicProperty(addr.c_str());
}
/**

View File

@@ -187,6 +187,7 @@ public:
return props.addDynamicProperty(type, name, group, doc, attr, ro, hidden);
}
virtual bool removeDynamicProperty(const char* name) {
App::DocumentObject::onAboutToRemoveProperty(name);
return props.removeDynamicProperty(name);
}
std::vector<std::string> getDynamicPropertyNames() const {