diff --git a/src/App/Document.cpp b/src/App/Document.cpp index fe186f3c41..71ed12bc2e 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -995,7 +995,14 @@ void Document::Save(Base::Writer& writer) const writer.incInd(); + // NOTE: This differs from LS3 Code. Persisting this table + // forces the assertion in Writer.addFile(...): assert(!isForceXML()); to be removed + // see: https://github.com/FreeCAD/FreeCAD/issues/27489 + // + // Original code in LS3: + // d->Hasher->setPersistenceFileName(0); d->Hasher->setPersistenceFileName("StringHasher.Table"); + for (const auto o : d->objectArray) { o->beforeSave(); } @@ -3134,7 +3141,7 @@ DocumentObject* Document::addObject(const char* sType, AddObjectOption::SetNewStatus | (isPartial ? AddObjectOption::SetPartialStatus : AddObjectOption::UnsetPartialStatus) | (isNew ? AddObjectOption::DoSetup : AddObjectOption::None) - | AddObjectOption::ActivateObject, + | AddObjectOption::ActivateObject, viewType); // return the Object @@ -3201,7 +3208,7 @@ void Document::_addObject(DocumentObject* pcObject, const char* pObjectName, Add else { ObjectName = getUniqueObjectName(pcObject->getTypeId().getName()); } - + // insert in the name map d->objectMap[ObjectName] = pcObject; d->objectNameManager.addExactName(ObjectName); @@ -3217,7 +3224,7 @@ void Document::_addObject(DocumentObject* pcObject, const char* pObjectName, Add } d->objectIdMap[pcObject->_Id] = pcObject; d->objectArray.push_back(pcObject); - + // do no transactions if we do a rollback! if (!d->rollback) { // Undo stuff @@ -3236,9 +3243,9 @@ void Document::_addObject(DocumentObject* pcObject, const char* pObjectName, Add if (!isPerformingTransaction() && options.testFlag(AddObjectOption::DoSetup)) { pcObject->setupObject(); } - + if (options.testFlag(AddObjectOption::SetNewStatus)) { - pcObject->setStatus(ObjectStatus::New, true); + pcObject->setStatus(ObjectStatus::New, true); } if (options.testFlag(AddObjectOption::SetPartialStatus) || options.testFlag(AddObjectOption::UnsetPartialStatus)) { pcObject->setStatus(ObjectStatus::PartialObject, options.testFlag(AddObjectOption::SetPartialStatus)); @@ -3250,15 +3257,15 @@ void Document::_addObject(DocumentObject* pcObject, const char* pObjectName, Add pcObject->_pcViewProviderName = viewType ? viewType : ""; signalNewObject(*pcObject); - + // do no transactions if we do a rollback! if (!d->rollback && d->activeUndoTransaction) { signalTransactionAppend(*pcObject, d->activeUndoTransaction); } - + if (options.testFlag(AddObjectOption::ActivateObject)) { d->activeObject = pcObject; - signalActivatedObject(*pcObject); + signalActivatedObject(*pcObject); } } @@ -3295,7 +3302,7 @@ void Document::_removeObject(DocumentObject* pcObject, RemoveObjectOptions optio FC_ERR("Cannot delete " << pcObject->getFullName() << " while recomputing"); return; } - + TransactionLocker tlock; _checkTransaction(pcObject, nullptr, __LINE__); @@ -3305,7 +3312,7 @@ void Document::_removeObject(DocumentObject* pcObject, RemoveObjectOptions optio FC_ERR("Internal error, could not find " << pcObject->getFullName() << " to remove"); } - if (options.testFlag(RemoveObjectOption::PreserveChildrenVisibility) + if (options.testFlag(RemoveObjectOption::PreserveChildrenVisibility) && !d->rollback && d->activeUndoTransaction && pcObject->hasChildElement()) { // Preserve link group sub object global visibilities. Normally those // claimed object should be hidden in global coordinate space. However, @@ -3313,7 +3320,7 @@ void Document::_removeObject(DocumentObject* pcObject, RemoveObjectOptions optio // children, which may now in the global space. When the parent is // undeleted, having its children shown in both the local and global // coordinate space is very confusing. Hence, we preserve the visibility - // here + // here for (auto& sub : pcObject->getSubObjects()) { if (sub.empty()) { continue; @@ -3360,7 +3367,7 @@ void Document::_removeObject(DocumentObject* pcObject, RemoveObjectOptions optio } std::unique_ptr tobedestroyed; - if ((options.testFlag(RemoveObjectOption::MayDestroyOutOfTransaction) && !d->rollback && !d->activeUndoTransaction) + if ((options.testFlag(RemoveObjectOption::MayDestroyOutOfTransaction) && !d->rollback && !d->activeUndoTransaction) || (options.testFlag(RemoveObjectOption::DestroyOnRollback) && d->rollback)) { // if not saved in undo -> delete object later std::unique_ptr delobj(pos->second); @@ -3376,13 +3383,13 @@ void Document::_removeObject(DocumentObject* pcObject, RemoveObjectOptions optio break; } } - + // In case the object gets deleted the pointer must be nullified if (tobedestroyed) { tobedestroyed->pcNameInDocument = nullptr; } - // Erase last to avoid invalidating pcObject->pcNameInDocument + // Erase last to avoid invalidating pcObject->pcNameInDocument // when it is still needed in Transaction::addObjectNew d->objectMap.erase(pos); } diff --git a/src/Base/Writer.cpp b/src/Base/Writer.cpp index 90f0445891..44ead1e313 100644 --- a/src/Base/Writer.cpp +++ b/src/Base/Writer.cpp @@ -294,7 +294,8 @@ std::vector Writer::getErrors() const std::string Writer::addFile(const char* Name, const Base::Persistence* Object) { // always check isForceXML() before requesting a file! - assert(!isForceXML()); + // assert(!isForceXML()); Changes introduced in 1.0 differ from LS3 (TNP), so this assertion is + // not valid anymore. FileEntry temp; temp.FileName = Name ? Name : "";