diff --git a/toonz/sources/common/tcore/tundo.cpp b/toonz/sources/common/tcore/tundo.cpp index 4eb219a..bca63db 100644 --- a/toonz/sources/common/tcore/tundo.cpp +++ b/toonz/sources/common/tcore/tundo.cpp @@ -37,9 +37,10 @@ public: } int getUndoCount() const { return (int)m_undos.size(); } void setLast() { - for (UINT i = 1; i < m_undos.size(); i++) - m_undos[i]->m_isLastInBlock = false; - m_undos[0]->m_isLastInBlock = true; + for (UINT i = 0; i < m_undos.size(); i++) { + m_undos[i]->m_isLastInBlock = (i == 0); + m_undos[i]->m_isLastInRedoBlock = (i == m_undos.size() - 1); + } } void undo() const override { @@ -65,7 +66,8 @@ public: //} void onAdd() override {} void add(TUndo *undo) { - undo->m_isLastInBlock = true; + undo->m_isLastInBlock = true; + undo->m_isLastInRedoBlock = true; m_undos.push_back(undo); } @@ -97,7 +99,7 @@ public: return m_undos.back()->getHistoryType(); } }; -} +} // namespace typedef std::deque UndoList; typedef UndoList::iterator UndoListIterator; @@ -186,9 +188,8 @@ void TUndoManager::TUndoManagerImp::doAdd(TUndo *undo) { int i, memorySize = 0, count = m_undoList.size(); for (i = 0; i < count; i++) memorySize += m_undoList[i]->getSize(); - while ( - count > 100 || - (count != 0 && memorySize + undo->getSize() > m_undoMemorySize)) // 20MB + while (count > 100 || (count != 0 && memorySize + undo->getSize() > + m_undoMemorySize)) // 20MB { --count; TUndo *undo = m_undoList.front(); @@ -197,7 +198,8 @@ void TUndoManager::TUndoManagerImp::doAdd(TUndo *undo) { delete undo; } - undo->m_isLastInBlock = true; + undo->m_isLastInBlock = true; + undo->m_isLastInRedoBlock = true; m_undoList.push_back(undo); m_current = m_undoList.end(); } diff --git a/toonz/sources/include/tundo.h b/toonz/sources/include/tundo.h index 64a9800..25e34a9 100644 --- a/toonz/sources/include/tundo.h +++ b/toonz/sources/include/tundo.h @@ -28,7 +28,10 @@ class DVAPI TUndo { public: + // To be called in the last of the block when undo bool m_isLastInBlock; + // To be called in the last of the block when redo + bool m_isLastInRedoBlock; public: TUndo() {} diff --git a/toonz/sources/toonzlib/fxcommand.cpp b/toonz/sources/toonzlib/fxcommand.cpp index f467e0f..2825851 100644 --- a/toonz/sources/toonzlib/fxcommand.cpp +++ b/toonz/sources/toonzlib/fxcommand.cpp @@ -1947,7 +1947,7 @@ void DeleteLinksUndo::redo() const { outputFx->getInputPort(index)->setFx(0); } - m_xshHandle->notifyXsheetChanged(); + if (m_isLastInRedoBlock) m_xshHandle->notifyXsheetChanged(); } //------------------------------------------------------ @@ -2012,7 +2012,7 @@ void DeleteLinksUndo::undo() const { } } - m_xshHandle->notifyXsheetChanged(); + if (m_isLastInBlock) m_xshHandle->notifyXsheetChanged(); } //------------------------------------------------------ @@ -2245,7 +2245,8 @@ void DeleteFxOrColumnUndo::redo() const { // Perform operation FxCommandUndo::removeFxOrColumn(xsh, m_fx.getPointer(), m_colIdx); - m_xshHandle->notifyXsheetChanged(); // Add the rest... + if (m_isLastInRedoBlock) + m_xshHandle->notifyXsheetChanged(); // Add the rest... } //------------------------------------------------------------- @@ -2296,7 +2297,7 @@ void DeleteFxOrColumnUndo::undo() const { // Re-establish fx links DeleteLinksUndo::undo(); - } else // Already covered by DeleteLinksUndo::undo() + } else if (m_isLastInBlock) // Already covered by DeleteLinksUndo::undo() m_xshHandle->notifyXsheetChanged(); // in the other branch } @@ -2327,12 +2328,18 @@ static void deleteFxs(const std::list &fxs, TXsheetHandle *xshHandle, std::unique_ptr undo( new DeleteFxOrColumnUndo(*ft, xshHandle, fxHandle)); if (undo->isConsistent()) { + // prevent emiting xsheetChanged signal for every undos which will cause + // multiple triggers of preview rendering + undo->m_isLastInRedoBlock = false; undo->redo(); TUndoManager::manager()->add(undo.release()); } } undoManager->endBlock(); + + // emit xsheetChanged once here + xshHandle->notifyXsheetChanged(); } //********************************************************************** @@ -2377,12 +2384,18 @@ static void deleteColumns(const std::list &columns, std::unique_ptr undo( new DeleteFxOrColumnUndo(cols[c]->getIndex(), xshHandle, fxHandle)); if (undo->isConsistent()) { + // prevent emiting xsheetChanged signal for every undos which will cause + // multiple triggers of preview rendering + undo->m_isLastInRedoBlock = false; undo->redo(); undoManager->add(undo.release()); } } undoManager->endBlock(); + + // emit xsheetChanged once here + xshHandle->notifyXsheetChanged(); } //********************************************************************** @@ -2407,9 +2420,9 @@ void TFxCommand::deleteSelection(const std::list &fxs, // Perform deletions TUndoManager::manager()->beginBlock(); - deleteColumns(columns, xshHandle, fxHandle); - deleteFxs(filteredFxs, xshHandle, fxHandle); - deleteLinks(links, xshHandle); + if (!columns.empty()) deleteColumns(columns, xshHandle, fxHandle); + if (!filteredFxs.empty()) deleteFxs(filteredFxs, xshHandle, fxHandle); + if (!links.empty()) deleteLinks(links, xshHandle); TUndoManager::manager()->endBlock(); }