svx/source/svdraw/sdrundomanager.cxx |   41 +++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

New commits:
commit 99e10099b5d63c30b9a960fc94fc438ae7ab63dd
Author:     Armin Le Grand (Allotropia) <armin.le.gr...@me.com>
AuthorDate: Thu May 12 18:21:05 2022 +0200
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Fri May 13 11:43:33 2022 +0200

    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.gr...@me.com>

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;

Reply via email to