sw/qa/extras/uiwriter/data2/tdf128603.odt |binary
 sw/qa/extras/uiwriter/uiwriter2.cxx       |   45 ++++++++++++++++++++++++++++++
 sw/source/core/layout/atrfrm.cxx          |   19 ++++++++++++
 3 files changed, 64 insertions(+)

New commits:
commit dbe744f1deef144e205b72e5927d61a6ea47af25
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Nov 7 10:10:43 2019 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Nov 7 12:27:34 2019 +0100

    tdf#128603 sw textbox: restore shape+frame pair on undo
    
    Undo of cut + paste restored both the shape and the frame, but the
    shape's content pointed to an invalid node index.
    
    Later this resulted in a crash.
    
    Make sure that in case the content of shape+frame don't match by the
    time the frame format pointer is set, we sync the draw format to the fly
    format.
    
    Change-Id: I233a504ca52698d1c514769d16c256408c29ae30
    Reviewed-on: https://gerrit.libreoffice.org/82192
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/uiwriter/data2/tdf128603.odt 
b/sw/qa/extras/uiwriter/data2/tdf128603.odt
new file mode 100644
index 000000000000..6fb758af9168
Binary files /dev/null and b/sw/qa/extras/uiwriter/data2/tdf128603.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx 
b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 14f7e0a5ac6b..912695cc03d4 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -47,6 +47,7 @@
 #include <AnnotationWin.hxx>
 #include <PostItMgr.hxx>
 #include <postithelper.hxx>
+#include <fmtcntnt.hxx>
 
 namespace
 {
@@ -2365,4 +2366,48 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf128335)
     pView->GetViewFrame()->GetDispatcher()->Execute(SID_CUT, 
SfxCallMode::SYNCHRON);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf128603)
+{
+    // Load the bugdoc, which has 3 textboxes.
+    SwDoc* pDoc = createDoc("tdf128603.odt");
+
+    // Select the 3rd textbox.
+    SwView* pView = pDoc->GetDocShell()->GetView();
+    pView->GetViewFrame()->GetDispatcher()->Execute(FN_CNTNT_TO_NEXT_FRAME, 
SfxCallMode::SYNCHRON);
+    // Make sure SwTextShell is replaced with SwDrawShell right now, not after 
120 ms, as set in the
+    // SwView ctor.
+    pView->StopShellTimer();
+    SwXTextDocument* pXTextDocument = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_TAB);
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_TAB);
+    Scheduler::ProcessEventsToIdle();
+
+    // Cut it.
+    pView->GetViewFrame()->GetDispatcher()->Execute(SID_CUT, 
SfxCallMode::SYNCHRON);
+
+    // Paste it: this makes the 3rd textbox anchored in the 2nd one.
+    pView->GetViewFrame()->GetDispatcher()->Execute(SID_PASTE, 
SfxCallMode::SYNCHRON);
+
+    // Undo all of this.
+    sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
+    rUndoManager.Undo();
+    rUndoManager.Undo();
+
+    // Make sure the content indexes still match.
+    const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(6), rSpzFrameFormats.size());
+    const SwNodeIndex* pIndex4 = 
rSpzFrameFormats[4]->GetContent().GetContentIdx();
+    CPPUNIT_ASSERT(pIndex4);
+    const SwNodeIndex* pIndex5 = 
rSpzFrameFormats[5]->GetContent().GetContentIdx();
+    CPPUNIT_ASSERT(pIndex5);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 11
+    // - Actual  : 14
+    // i.e. the shape content index and the frame content index did not match 
after undo, even if
+    // their "other text box format" pointers pointed to each other.
+    CPPUNIT_ASSERT_EQUAL(pIndex4->GetIndex(), pIndex5->GetIndex());
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index 0014d84249b0..79235781896d 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -2489,6 +2489,7 @@ void SwFrameFormat::SetOtherTextBoxFormat( SwFrameFormat 
*pFormat )
     {
         assert( nullptr != m_pOtherTextBoxFormat );
     }
+    bool bChanged = m_pOtherTextBoxFormat != pFormat;
     m_pOtherTextBoxFormat = pFormat;
 
     SdrObject* pObj = FindSdrObject();
@@ -2500,6 +2501,19 @@ void SwFrameFormat::SetOtherTextBoxFormat( SwFrameFormat 
*pFormat )
         if (pSwFlyDraw)
             pSwFlyDraw->SetTextBox(true);
     }
+
+    if (m_pOtherTextBoxFormat && bChanged && Which() == RES_DRAWFRMFMT)
+    {
+        // This is a shape of a shape+frame pair and my frame has changed. 
Make sure my content is
+        // in sync with the frame's content.
+        if (GetAttrSet().GetContent() != 
m_pOtherTextBoxFormat->GetAttrSet().GetContent())
+        {
+            SwAttrSet aSet(GetAttrSet());
+            SwFormatContent 
aContent(m_pOtherTextBoxFormat->GetAttrSet().GetContent());
+            aSet.Put(aContent);
+            SetFormatAttr(aSet);
+        }
+    }
 }
 
 bool SwFrameFormat::supportsFullDrawingLayerFillAttributeSet() const
@@ -2799,6 +2813,11 @@ void SwFrameFormat::dumpAsXml(xmlTextWriterPtr pWriter) 
const
     if (pWhich)
         xmlTextWriterWriteAttribute(pWriter, BAD_CAST("which"), 
BAD_CAST(pWhich));
 
+    if (m_pOtherTextBoxFormat)
+    {
+        xmlTextWriterWriteFormatAttribute(pWriter, 
BAD_CAST("OtherTextBoxFormat"), "%p", m_pOtherTextBoxFormat);
+    }
+
     GetAttrSet().dumpAsXml(pWriter);
 
     if (const SdrObject* pSdrObject = FindSdrObject())
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to