[Libreoffice-commits] core.git: sw/qa sw/source

Daniel Arato (NISZ) (via logerrit) logerrit at kemper.freedesktop.org
Tue May 4 13:39:01 UTC 2021


 sw/qa/uitest/writer_tests7/tdf46561.py |   13 +++++
 sw/source/core/doc/docdesc.cxx         |   84 +++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+)

New commits:
commit 65e52cb61d74b0c71b45b63b2da131bc6b621104
Author:     Daniel Arato (NISZ) <arato.daniel at nisz.hu>
AuthorDate: Mon Apr 26 15:04:17 2021 +0200
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Tue May 4 15:38:21 2021 +0200

    tdf#141613 sw: fix crash at header/footer undo
    
    Undoing the creation of a header/footer used to leave their
    corresponding document nodes intact, causing the node index
    of a previous undo entry to point to the wrong node.
    
    We now force the destruction of the header/footer nodes manually.
    We also cut the redo chain which loses the redo history, but solves
    another crash for now (when redoing the creation of the header).
    
    The proper solution would be to create a new SwUndo* derived class
    from scratch to represent the creation of a new header/footer section
    in the document.
    
    Regression from commit 8d8486f43c1a8a51157bfc3e0b87090b05a9229e
    (tdf#46561 sw: fix lost undo stack setting header/footer)
    
    Change-Id: I97188aa8ded802bc6b6fa88ddd83a95c40de8bc3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114667
    Tested-by: László Németh <nemeth at numbertext.org>
    Reviewed-by: László Németh <nemeth at numbertext.org>

diff --git a/sw/qa/uitest/writer_tests7/tdf46561.py b/sw/qa/uitest/writer_tests7/tdf46561.py
index 1c90dc3c404a..7d43ed8505eb 100644
--- a/sw/qa/uitest/writer_tests7/tdf46561.py
+++ b/sw/qa/uitest/writer_tests7/tdf46561.py
@@ -97,4 +97,17 @@ class tdf46561(UITestCase):
 
         self.ui_test.close_doc()
 
+    # Check that former crash has been fixed
+    def test_tdf141613(self):
+        self.ui_test.create_doc_in_start_center("writer")
+
+        xWriterDoc = self.xUITest.getTopFocusWindow()
+        xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+        xArgs = mkPropertyValues({"Text": "something"})
+        self.xUITest.executeCommandWithParameters(".uno:InsertText", xArgs)
+        self.xUITest.executeCommand(".uno:InsertPageHeader")
+        self.xUITest.executeCommand(".uno:Undo")
+        self.xUITest.executeCommand(".uno:Undo")
+
 # vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/core/doc/docdesc.cxx b/sw/source/core/doc/docdesc.cxx
index ee08206bd7ef..4f38197f7ce9 100644
--- a/sw/source/core/doc/docdesc.cxx
+++ b/sw/source/core/doc/docdesc.cxx
@@ -424,6 +424,90 @@ void SwDoc::ChgPageDesc( size_t i, const SwPageDesc &rChged )
 
         GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoPageDesc>(rDesc, rChged, this));
     }
+    else
+    {
+        SwUndoId nBeingUndone;
+        GetIDocumentUndoRedo().GetFirstRedoInfo(nullptr, &nBeingUndone);
+        if (SwUndoId::HEADER_FOOTER == nBeingUndone)
+        {
+            // The last format change is currently being undone. Remove header/footer and corresponding nodes.
+            auto rDescMasterHeaderFormat = rDesc.GetMaster().GetFormatAttr(RES_HEADER);
+            auto rDescLeftHeaderFormat = rDesc.GetLeft().GetFormatAttr(RES_HEADER);
+            auto rDescFirstLeftHeaderFormat = rDesc.GetFirstLeft().GetFormatAttr(RES_HEADER);
+            auto rDescMasterFooterFormat = rDesc.GetMaster().GetFormatAttr(RES_FOOTER);
+            auto rDescLeftFooterFormat = rDesc.GetLeft().GetFormatAttr(RES_FOOTER);
+            auto rDescFirstLeftFooterFormat = rDesc.GetFirstLeft().GetFormatAttr(RES_FOOTER);
+
+            auto rChgedMasterHeaderFormat = rChged.GetMaster().GetFormatAttr(RES_HEADER);
+            auto rChgedLeftHeaderFormat = rChged.GetLeft().GetFormatAttr(RES_HEADER);
+            auto rChgedFirstLeftHeaderFormat = rChged.GetFirstLeft().GetFormatAttr(RES_HEADER);
+            auto rChgedMasterFooterFormat = rChged.GetMaster().GetFormatAttr(RES_FOOTER);
+            auto rChgedLeftFooterFormat = rChged.GetLeft().GetFormatAttr(RES_FOOTER);
+            auto rChgedFirstLeftFooterFormat = rChged.GetFirstLeft().GetFormatAttr(RES_FOOTER);
+
+            rDesc.GetMaster().ResetFormatAttr(RES_HEADER);
+            rDesc.GetLeft().ResetFormatAttr(RES_HEADER);
+            rDesc.GetFirstLeft().ResetFormatAttr(RES_HEADER);
+            rDesc.GetMaster().ResetFormatAttr(RES_FOOTER);
+            rDesc.GetLeft().ResetFormatAttr(RES_FOOTER);
+            rDesc.GetFirstLeft().ResetFormatAttr(RES_FOOTER);
+
+            auto lDelHFFormat = [this](SwClient* pToRemove, SwFrameFormat* pFormat)
+            {
+                // Code taken from lcl_DelHFFormat
+                pFormat->Remove(pToRemove);
+                SwFormatContent& rCnt = const_cast<SwFormatContent&>(pFormat->GetContent());
+                if (rCnt.GetContentIdx())
+                {
+                    SwNode* pNode = nullptr;
+                    {
+                        SwNodeIndex aIdx(*rCnt.GetContentIdx(), 0);
+                        pNode = &aIdx.GetNode();
+                        sal_uInt32 nEnd = pNode->EndOfSectionIndex();
+                        while (aIdx < nEnd)
+                        {
+                            if (pNode->IsContentNode() &&
+                                static_cast<SwContentNode*>(pNode)->HasWriterListeners())
+                            {
+                                SwCursorShell* pShell = SwIterator<SwCursorShell, SwContentNode>(*static_cast<SwContentNode*>(pNode)).First();
+                                if (pShell)
+                                {
+                                    pShell->ParkCursor(aIdx);
+                                    aIdx = nEnd - 1;
+                                }
+                            }
+                            ++aIdx;
+                            pNode = &aIdx.GetNode();
+                        }
+                    }
+                    rCnt.SetNewContentIdx(nullptr);
+
+                    ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
+
+                    assert(pNode);
+                    getIDocumentContentOperations().DeleteSection(pNode);
+                }
+                delete pFormat;
+            };
+
+            if (rDescMasterHeaderFormat.GetHeaderFormat() && rDescMasterHeaderFormat != rChgedMasterHeaderFormat)
+                lDelHFFormat(&rDescMasterHeaderFormat, rDescMasterHeaderFormat.GetHeaderFormat());
+            else if (rDescLeftHeaderFormat.GetHeaderFormat() && rDescLeftHeaderFormat != rChgedLeftHeaderFormat)
+                lDelHFFormat(&rDescLeftHeaderFormat, rDescLeftHeaderFormat.GetHeaderFormat());
+            else if (rDescFirstLeftHeaderFormat.GetHeaderFormat() && rDescFirstLeftHeaderFormat != rChgedFirstLeftHeaderFormat)
+                lDelHFFormat(&rDescFirstLeftHeaderFormat, rDescFirstLeftHeaderFormat.GetHeaderFormat());
+
+            else if (rDescMasterFooterFormat.GetFooterFormat() && rDescMasterFooterFormat != rChgedMasterFooterFormat)
+                lDelHFFormat(&rDescMasterFooterFormat, rDescMasterFooterFormat.GetFooterFormat());
+            else if (rDescLeftFooterFormat.GetFooterFormat() && rDescLeftFooterFormat != rChgedLeftFooterFormat)
+                lDelHFFormat(&rDescLeftFooterFormat, rDescLeftFooterFormat.GetFooterFormat());
+            else if (rDescFirstLeftFooterFormat.GetFooterFormat() && rDescFirstLeftFooterFormat != rChgedFirstLeftFooterFormat)
+                lDelHFFormat(&rDescFirstLeftFooterFormat, rDescFirstLeftFooterFormat.GetFooterFormat());
+
+            // FIXME: Disable redoing this change until we figure out how
+            GetIDocumentUndoRedo().ClearRedo();
+        }
+    }
     ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
 
     // Mirror at first if needed.


More information about the Libreoffice-commits mailing list