sw/qa/core/txtnode/txtnode.cxx | 14 +++++++++++++- sw/source/core/layout/flylay.cxx | 11 +++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-)
New commits: commit a74d8487c9bb2f586067f2139e8c136628da2da4 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 16:13:44 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 (cherry picked from commit 5fec60b4732bdbdb681be08e43a9be47c3bfb320) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160704 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.