| 3531 | _removeObject(pos->second, RemoveObjectOption::MayRemoveWhileRecomputing | RemoveObjectOption::MayDestroyOutOfTransaction); |
| 3532 | } |
| 3533 | void Document::_removeObject(DocumentObject* pcObject, RemoveObjectOptions options) |
| 3534 | { |
| 3535 | if (!options.testFlag(RemoveObjectOption::MayRemoveWhileRecomputing) && testStatus(Document::Recomputing)) { |
| 3536 | FC_ERR("Cannot delete " << pcObject->getFullName() << " while recomputing"); |
| 3537 | return; |
| 3538 | } |
| 3539 | |
| 3540 | TransactionLocker tlock(this); |
| 3541 | |
| 3542 | _checkTransaction(pcObject, nullptr, __LINE__); |
| 3543 | |
| 3544 | auto pos = d->objectMap.find(pcObject->getNameInDocument()); |
| 3545 | if (pos == d->objectMap.end()) { |
| 3546 | FC_ERR("Internal error, could not find " << pcObject->getFullName() << " to remove"); |
| 3547 | return; |
| 3548 | } |
| 3549 | |
| 3550 | if (options.testFlag(RemoveObjectOption::PreserveChildrenVisibility) |
| 3551 | && !d->rollback && d->activeUndoTransaction && pcObject->hasChildElement()) { |
| 3552 | // Preserve link group sub object global visibilities. Normally those |
| 3553 | // claimed object should be hidden in global coordinate space. However, |
| 3554 | // when the group is deleted, the user will naturally try to show the |
| 3555 | // children, which may now in the global space. When the parent is |
| 3556 | // undeleted, having its children shown in both the local and global |
| 3557 | // coordinate space is very confusing. Hence, we preserve the visibility |
| 3558 | // here |
| 3559 | for (auto& sub : pcObject->getSubObjects()) { |
| 3560 | if (sub.empty()) { |
| 3561 | continue; |
| 3562 | } |
| 3563 | if (sub[sub.size() - 1] != '.') { |
| 3564 | sub += '.'; |
| 3565 | } |
| 3566 | auto sobj = pcObject->getSubObject(sub.c_str()); |
| 3567 | if (sobj && sobj->getDocument() == this && !sobj->Visibility.getValue()) { |
| 3568 | d->activeUndoTransaction->addObjectChange(sobj, &sobj->Visibility); |
| 3569 | } |
| 3570 | } |
| 3571 | } |
| 3572 | |
| 3573 | if (d->activeObject == pcObject) { |
| 3574 | d->activeObject = nullptr; |
| 3575 | } |
| 3576 | |
| 3577 | // Mark the object as about to be removed |
| 3578 | pcObject->setStatus(ObjectStatus::Remove, true); |
| 3579 | if (!d->undoing && !d->rollback) { |
| 3580 | pcObject->unsetupObject(); |
| 3581 | } |
| 3582 | signalDeletedObject(*pcObject); |
| 3583 | signalTransactionRemove(*pcObject, d->rollback ? nullptr : d->activeUndoTransaction); |
| 3584 | breakDependency(pcObject, true); |
| 3585 | |
| 3586 | // TODO Check me if it's needed (2015-09-01, Fat-Zer) |
| 3587 | // remove the tip if needed |
| 3588 | if (Tip.getValue() == pcObject) { |
| 3589 | Tip.setValue(nullptr); |
| 3590 | TipName.setValue(""); |
no test coverage detected