diff options
author | Armin Le Grand (Allotropia) <Armin.Le.Grand@me.com> | 2022-05-12 18:21:05 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2022-05-13 11:43:33 +0200 |
commit | 99e10099b5d63c30b9a960fc94fc438ae7ab63dd (patch) | |
tree | f47760e1c3ac2d1650190055c37bfc91807bef45 /svx | |
parent | 27a273293618e6dbc2de5b299247b1d9f05864c6 (diff) |
Advanced Diagram support: Secure Redo, evtl. flush Redo-Stack
Change-Id: Iade4ea85289377774e51671f1e9848c19d757633
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134245
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'svx')
-rw-r--r-- | svx/source/svdraw/sdrundomanager.cxx | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/svx/source/svdraw/sdrundomanager.cxx b/svx/source/svdraw/sdrundomanager.cxx index 943a5fcb7326..2f286096c160 100644 --- a/svx/source/svdraw/sdrundomanager.cxx +++ b/svx/source/svdraw/sdrundomanager.cxx @@ -18,6 +18,7 @@ */ #include <svx/sdrundomanager.hxx> +#include <svx/svdundo.hxx> #include <sfx2/objsh.hxx> #include <svl/hint.hxx> @@ -64,6 +65,7 @@ bool SdrUndoManager::Undo() bool SdrUndoManager::Redo() { bool bRetval(false); + bool bClearRedoStack(false); if (isTextEditActive()) { @@ -73,8 +75,47 @@ bool SdrUndoManager::Redo() if (!bRetval) { + // Check if the current and thus to-be undone UndoAction is a SdrUndoDiagramModelData action + const bool bCurrentIsDiagramChange( + GetRedoActionCount() + && nullptr != dynamic_cast<SdrUndoDiagramModelData*>(GetRedoAction())); + // no redo triggered up to now, trigger local one bRetval = SfxUndoManager::Redo(); + + // it was a SdrUndoDiagramModelData action and we have more Redo actions + if (bCurrentIsDiagramChange && GetRedoActionCount()) + { + const bool bNextIsDiagramChange( + nullptr != dynamic_cast<SdrUndoDiagramModelData*>(GetRedoAction())); + + // We have more Redo-actions and the 'next' one to be executed is *not* a + // SdrUndoDiagramModelData-action. This means that the already executed + // one had done a re-Layout/Re-create of the Diagram XShape/SdrObject + // representation based on the restored Diagram ModelData. When the next + // Redo action is something else (and thus will not itself re-create + // XShapes/SdrShapes) it may be that it is an UnGroup/Delete where a former + // as-content-of-Diagram created XShape/SdrShape is referenced, an action + // that references a XShape/SdrShape by pointer/reference. That + // pointer/reference *cannot* be valid anymore (now). + + // The problem here is that Undo/Redo actions historically reference + // XShapes/SdrShapes by pointer/reference, e.g. deleting means: remove + // from an SdrObjList and add to an Undo action. I is *not* + // adddress/incarnation-invariant in the sense to remember e.g. to + // remove the Nth object in tha list (that would work). + + // It might be possible to solve/correct this better, but since it's + // a rare corner case just avoid the possible crash when continuing Redos + // by clearing the Redo-Stack here as a consequence + bClearRedoStack = !bNextIsDiagramChange; + } + } + + if (bClearRedoStack) + { + // clear Redo-Stack (explanation see above) + ClearRedo(); } return bRetval; |