sw/qa/core/txtnode/txtnode.cxx   |   14 +++++++++++++-
 sw/source/core/layout/flylay.cxx |   11 +++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)

New commits:
commit 5fec60b4732bdbdb681be08e43a9be47c3bfb320
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Dec 14 08:39:50 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Dec 14 10:21:54 2023 +0100

    sw floattable: fix outdated text frame portions after split
    
    The document has a floating table of 2 pages, with some anchor text on
    page 2. Split of the anchor text resulted in 2 paragraphs: the first
    still hosts the floating table and now lacks a fly portion (overlap of
    text and floating table) and the second still wraps around the floating
    table but has the correct position.
    
    What happens is that we format the first text frame, then its flys
    (which moves the follow fly from page 1 to page 2) and then we format
    the second text frame. This means that the first text frame should have
    a fly portion to wrap around the floating table, but it does not have,
    because SwTextFrame::Format() is called for the first text frame, then
    SwPageFrame::MoveFly() is called, then SwTextFrame::Format() for the
    second text frame, i.e. no reformat of the first text frame after moving
    the fly.
    
    Fix the problem somewhat similar to what commit
    cf2c070de2bafeec3b476c6bff7bb4ac87ba46db (sw layout: invalidate margins
    of body content when moving a fly from page, 2022-12-09) did, but here
    what's outdated is the portions of the text frame, and only for the
    anchor text frame.
    
    This fixes the problem in practice, but note that in theory this could
    affect non-split flys and also other, non-anchor text frames as well.
    Limit the update of the portion list to the anchor of the split fly, but
    we may want to do the same for all lowers of the body frame if there is
    a practical need for it.
    
    Change-Id: I3067e78d30e16ed3d2f02a80cff4cd84d9bdcf3b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160748
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx
index 5b4023a41dc6..c2df8a407e69 100644
--- a/sw/qa/core/txtnode/txtnode.cxx
+++ b/sw/qa/core/txtnode/txtnode.cxx
@@ -517,7 +517,7 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, 
testSplitFlyAnchorSplit)
     CPPUNIT_ASSERT(pPage1->GetSortedObjs());
     auto pPage2 = pPage1->GetNext()->DynCastPageFrame();
     CPPUNIT_ASSERT(pPage2);
-    // Page 1 has the follow fly:
+    // Page 2 has the follow fly:
     CPPUNIT_ASSERT(pPage2->GetSortedObjs());
     // Anchor text is now just "A":
     auto pText1 = pPage2->FindFirstBodyContent()->DynCastTextFrame();
@@ -525,6 +525,18 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, 
testSplitFlyAnchorSplit)
     // New text frame is just "B":
     auto pText2 = pText1->GetNext()->DynCastTextFrame();
     CPPUNIT_ASSERT_EQUAL(OUString("B"), pText2->GetText());
+
+    // Also test that the new follow anchor text frame still has a fly 
portion, otherwise the anchor
+    // text and the floating table would overlap:
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    OUString aPortionType
+        = getXPath(pXmlDoc, 
"//page[2]/body/txt[1]/SwParaPortion/SwLineLayout[1]/child::*[1]"_ostr,
+                   "type"_ostr);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: PortionType::Fly
+    // - Actual  : PortionType::Para
+    // i.e. the fly portion was missing, text overlapped.
+    CPPUNIT_ASSERT_EQUAL(OUString("PortionType::Fly"), aPortionType);
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index e507e92e6dcd..457a0d41bbf3 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -1039,6 +1039,17 @@ void SwPageFrame::MoveFly( SwFlyFrame *pToMove, 
SwPageFrame *pDest )
     // #i28701#
     pToMove->UnlockPosition();
 
+    if (pToMove->IsFlySplitAllowed())
+    {
+        // Inserting a fly to the page affects the fly portions of the 
intersecting paragraphs, so
+        // update the portions of the anchor of the fly frame.
+        SwTextFrame* pAnchor = pToMove->FindAnchorCharFrame();
+        if (pAnchor)
+        {
+            pAnchor->ClearPara();
+        }
+    }
+
     // Notify accessible layout. That's required at this place for
     // frames only where the anchor is moved. Creation of new frames
     // is additionally handled by the SwFrameNotify class.

Reply via email to