App: fix property ordering problem when undo/redo (#3255)

* Part: fix Placement/Shape onChanged() handling

* App: fix property ordering problem when undo/redo
See https://tracker.freecadweb.org/view.php?id=4265#c14271

* Gui: fix undo/redo signaling
Make sure to signal after all properties has been restored
This commit is contained in:
Zheng Lei
2022-02-21 19:29:01 +08:00
committed by GitHub
parent b42462ba14
commit c3178343db
14 changed files with 250 additions and 68 deletions

View File

@@ -957,6 +957,7 @@ bool Document::undo(int id)
if(it == mUndoMap.end())
return false;
if(it->second != d->activeUndoTransaction) {
TransactionGuard guard(true);
while(mUndoTransactions.size() && mUndoTransactions.back()!=it->second)
undo(0);
}
@@ -966,11 +967,13 @@ bool Document::undo(int id)
_commitTransaction(true);
if (mUndoTransactions.empty())
return false;
TransactionGuard guard(true);
// redo
d->activeUndoTransaction = new Transaction(mUndoTransactions.back()->getID());
d->activeUndoTransaction->Name = mUndoTransactions.back()->Name;
{
Base::FlagToggler<bool> flag(d->undoing);
// applying the undo
mUndoTransactions.back()->apply(*this,false);
@@ -983,18 +986,6 @@ bool Document::undo(int id)
mUndoMap.erase(mUndoTransactions.back()->getID());
delete mUndoTransactions.back();
mUndoTransactions.pop_back();
}
for(auto & obj:d->objectArray) {
if(obj->testStatus(ObjectStatus::PendingTransactionUpdate)) {
obj->onUndoRedoFinished();
obj->setStatus(ObjectStatus::PendingTransactionUpdate,false);
}
}
signalUndo(*this); // now signal the undo
return true;
}
@@ -1008,8 +999,11 @@ bool Document::redo(int id)
auto it = mRedoMap.find(id);
if(it == mRedoMap.end())
return false;
while(mRedoTransactions.size() && mRedoTransactions.back()!=it->second)
redo(0);
{
TransactionGuard guard(false);
while(mRedoTransactions.size() && mRedoTransactions.back()!=it->second)
redo(0);
}
}
if (d->activeUndoTransaction)
@@ -1017,12 +1011,13 @@ bool Document::redo(int id)
assert(mRedoTransactions.size()!=0);
TransactionGuard guard(false);
// undo
d->activeUndoTransaction = new Transaction(mRedoTransactions.back()->getID());
d->activeUndoTransaction->Name = mRedoTransactions.back()->Name;
// do the redo
{
Base::FlagToggler<bool> flag(d->undoing);
mRedoTransactions.back()->apply(*this,true);
@@ -1033,16 +1028,6 @@ bool Document::redo(int id)
mRedoMap.erase(mRedoTransactions.back()->getID());
delete mRedoTransactions.back();
mRedoTransactions.pop_back();
}
for(auto & obj:d->objectArray) {
if(obj->testStatus(ObjectStatus::PendingTransactionUpdate)) {
obj->onUndoRedoFinished();
obj->setStatus(ObjectStatus::PendingTransactionUpdate,false);
}
}
signalRedo(*this);
return true;
}
@@ -1067,7 +1052,7 @@ void Document::addOrRemovePropertyOfObject(TransactionalObject* obj, Property *p
bool Document::isPerformingTransaction() const
{
return d->undoing || d->rollback;
return d->undoing || d->rollback || Transaction::isApplying();
}
std::vector<std::string> Document::getAvailableUndoNames() const
@@ -1222,17 +1207,12 @@ void Document::commitTransaction() {
void Document::_commitTransaction(bool notify)
{
if (isPerformingTransaction()) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
FC_WARN("Cannot commit transaction while transacting");
return;
}
else if (d->committing) {
// for a recursive call return without printing a warning
return;
}
if (d->activeUndoTransaction) {
if(d->undoing || d->rollback || d->committing) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
FC_WARN("Cannot commit transaction while transacting");
return;
}
Base::FlagToggler<> flag(d->committing);
Application::TransactionSignaller signaller(false,true);
int id = d->activeUndoTransaction->getID();
@@ -1264,12 +1244,13 @@ void Document::abortTransaction() {
void Document::_abortTransaction()
{
if(isPerformingTransaction() || d->committing) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
FC_WARN("Cannot abort transaction while transacting");
}
if (d->activeUndoTransaction) {
if(d->undoing || d->rollback || d->committing) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
FC_WARN("Cannot abort transaction while transacting");
return;
}
Base::FlagToggler<bool> flag(d->rollback);
Application::TransactionSignaller signaller(true,true);
@@ -2937,6 +2918,10 @@ std::string Document::getFullName() const {
return myName;
}
App::Document *Document::getOwnerDocument() const {
return const_cast<App::Document*>(this);
}
const char* Document::getProgramVersion() const
{
return d->programVersion.c_str();