diff options
author | Noel Grandin <noelgrandin@gmail.com> | 2022-07-30 09:02:31 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-07-31 09:27:23 +0200 |
commit | 80cdfe4512a66ab58e0ae27c9fafad601c2f84b2 (patch) | |
tree | 5b0b1b392c3a53b53515b46a9d0e8b23cfd12528 /sc/source/ui/undo | |
parent | 93bea3531cff7f1e35a4c982836afbabfa587a6f (diff) |
sc, out of order undo: allow a subset of a non-empty redo list
This is the calc analogue of
commit 60665dc4a2af238939b1a5056ae4a4ce2c083159
sw, out of order undo: allow a subset of a non-empty redo list
Specifically, we used to not allow out of order undo at all if the redo
list was non-empty. This relaxes that condition a bit. Out of order undo
is OK with a non-empty redo list, in case all undo actions in the redo
list are either
1) owned by the current view or
2) independent from the undo action to be executed
I.e. if view1 has lots of type undo actions and an view2 adds a
single type undo action on top of it, then allow view 1 to execute
multiple of its typing undo actions, not just a single one.
Change-Id: Ib7ab88e9ebbefce267d3c7d567debd1cd98d7d6d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137628
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'sc/source/ui/undo')
-rw-r--r-- | sc/source/ui/undo/undobase.cxx | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/sc/source/ui/undo/undobase.cxx b/sc/source/ui/undo/undobase.cxx index b591b38aabc7..250c78619ef8 100644 --- a/sc/source/ui/undo/undobase.cxx +++ b/sc/source/ui/undo/undobase.cxx @@ -623,10 +623,9 @@ ScUndoManager::~ScUndoManager() {} */ bool ScUndoManager::IsViewUndoActionIndependent(const SfxViewShell* pView) const { - if (GetUndoActionCount() <= 1 || SdrUndoManager::GetRedoActionCount() > 0) + if (GetUndoActionCount() <= 1) { - // Single or less undo, owned by another view; or redo actions that might depend on the - // current undo order. + // Single or less undo, owned by another view. return false; } @@ -662,21 +661,46 @@ bool ScUndoManager::IsViewUndoActionIndependent(const SfxViewShell* pView) const if (!viewRange) return false; - return !topRange->Intersects(*viewRange); + if (topRange->Intersects(*viewRange)) + return false; + + for (size_t i = 0; i < GetRedoActionCount(); ++i) + { + auto pRedoAction = getScUndoEnterData(GetRedoAction(i)); + if (!pRedoAction) + { + return false; + } + std::optional<ScRange> redoRange = getAffectedRangeFromUndo(pRedoAction); + if (!redoRange || (redoRange->Intersects(*viewRange) && pRedoAction->GetViewShellId() != nViewId)) + { + // Dependent redo action and owned by another view. + return false; + } + } + + return true; } std::optional<ScRange> ScUndoManager::getAffectedRangeFromUndo(const SfxUndoAction* pAction) { - auto pListAction = dynamic_cast<const SfxListUndoAction*>(pAction); - if (!pListAction) - return std::nullopt; - if (pListAction->maUndoActions.size() > 1) - return std::nullopt; - auto pTopScUndoEnterData = dynamic_cast<ScUndoEnterData*>(pListAction->maUndoActions[0].pAction.get()); + auto pTopScUndoEnterData = getScUndoEnterData(pAction); if (!pTopScUndoEnterData) return std::nullopt; return pTopScUndoEnterData->GetPositionAddress(); } +const ScUndoEnterData* ScUndoManager::getScUndoEnterData(const SfxUndoAction* pAction) +{ + const ScUndoEnterData* pUndoEnterData = dynamic_cast<const ScUndoEnterData*>(pAction); + if (pUndoEnterData) + return pUndoEnterData; + auto pListAction = dynamic_cast<const SfxListUndoAction*>(pAction); + if (!pListAction) + return nullptr; + if (pListAction->maUndoActions.size() > 1) + return nullptr; + return dynamic_cast<ScUndoEnterData*>(pListAction->maUndoActions[0].pAction.get()); +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |