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

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue Nov 5 07:37:00 UTC 2019


 sw/qa/extras/uiwriter/data2/tdf128335.odt |binary
 sw/qa/extras/uiwriter/uiwriter2.cxx       |   36 ++++++++++++++++++++++++++++++
 sw/source/core/draw/dview.cxx             |    6 ++++-
 3 files changed, 41 insertions(+), 1 deletion(-)

New commits:
commit f6e7683847e5c959948b55c35bc916c69beb615e
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Nov 4 21:00:51 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Nov 5 08:36:05 2019 +0100

    tdf#128335 sw textbox: fix crash on deleting multiple shapes with textboxes
    
    This was introduced in commit 33141f999b22ce10cdbfbd76081fff211c4b5067
    (SwDrawView::DeleteMarked: delete textbox of shape as well, 2014-06-23),
    the problem is that in case one shape+textframe pair is anchored in an
    other textframe, which is also part of a shape+textframe pair, it
    matters what order we use for deleting these objects.
    
    What happened is that the anchor position of a 2nd textbox was updated
    on the deletion (cut) of the 1st textbox, and this was not properly
    restored on paste.
    
    Fix the problem by deleting in reverse order, assuming that the
    container is ordered by anchor positions.
    
    Change-Id: I62bc12a5064ce397234999e8fd7b108f79de3c24
    Reviewed-on: https://gerrit.libreoffice.org/82042
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/qa/extras/uiwriter/data2/tdf128335.odt b/sw/qa/extras/uiwriter/data2/tdf128335.odt
new file mode 100644
index 000000000000..6fb758af9168
Binary files /dev/null and b/sw/qa/extras/uiwriter/data2/tdf128335.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index de1ff27bfc96..14f7e0a5ac6b 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -17,6 +17,7 @@
 #include <com/sun/star/frame/DispatchHelper.hpp>
 #include <com/sun/star/style/LineSpacing.hpp>
 #include <com/sun/star/text/TableColumnSeparator.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
 #include <comphelper/propertysequence.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <i18nlangtag/languagetag.hxx>
@@ -2329,4 +2330,39 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf118311)
     assertXPath(pXmlDoc, "//page[1]//body/tab", 0);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf128335)
+{
+    // Load the bugdoc, which has 3 textboxes.
+    SwDoc* pDoc = createDoc("tdf128335.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);
+
+    // Select all shapes.
+    uno::Reference<view::XSelectionSupplier> xSelectionSupplier(
+        pXTextDocument->getCurrentController(), uno::UNO_QUERY);
+    xSelectionSupplier->select(pXTextDocument->getDrawPages()->getByIndex(0));
+
+    // Cut them.
+    // Without the accompanying fix in place, this test would have crashed as the textboxes were
+    // deleted in an incorrect order.
+    pView->GetViewFrame()->GetDispatcher()->Execute(SID_CUT, SfxCallMode::SYNCHRON);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx
index e617a6da8dec..54f86e8abb27 100644
--- a/sw/source/core/draw/dview.cxx
+++ b/sw/source/core/draw/dview.cxx
@@ -975,8 +975,12 @@ void SwDrawView::DeleteMarked()
         ::FrameNotify( Imp().GetShell(), FLY_DRAG_END );
 
         // Only delete these now: earlier deletion would clear the mark list as well.
-        for (auto& rpTextBox : aTextBoxesToDelete)
+        // Delete in reverse order, assuming that the container is sorted by anchor positions.
+        for (int i = aTextBoxesToDelete.size() - 1; i >= 0; --i)
+        {
+            SwFrameFormat*& rpTextBox = aTextBoxesToDelete[i];
             pDoc->getIDocumentLayoutAccess().DelLayoutFormat(rpTextBox);
+        }
     }
     pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY, nullptr);
     if( pTmpRoot )


More information about the Libreoffice-commits mailing list