diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-04-04 08:28:08 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-04-04 11:49:08 +0200 |
commit | 96df0ad0da6e8972a828721dac6b4ba7c69eba85 (patch) | |
tree | dda12d2373003d046fbb3ca6e4f514f4501bb1ee /sw | |
parent | 309469a3863c1ce7a2d463f3a62f5101c39ac89c (diff) |
sw floattable: fix removal of last follow fly with a start/middle one
The bugdoc has 3 pages: each page has 1 row of a floating table.
Deleting the last row deleted the last fly frame, but the text in the
body didn't move from page 3 to page 2.
It seems what happened was that the condition in
SwTextFrame::HasNonLastSplitFlyDrawObj() was wrong, it always filtered
for the master anchor, not for the relevant anchor. Once that's fixed,
the other problem was that by the time SwRootFrame::DeleteEmptyFlys_()
would invalidate the anchor, the follow/precede relationship is already
unlinked for the to-be-deleted fly, so we can't find the correct anchor
of the to-be-deleted fly.
Fix the second problem by invalidating the anchor earlier, in
SwFlyAtContentFrame::DelEmpty(), where the to-be-deleted fly is still
part of the flow frame chain.
With this, deleting the last row in the document results in deleting the
entire page 3 and moving up the body text, as expected.
Change-Id: I3303408cafabcc61abfffe6c355ec3874fff30a2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150008
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/core/layout/flycnt.cxx | 26 | ||||
-rw-r--r-- | sw/source/core/layout/flycnt.cxx | 13 | ||||
-rw-r--r-- | sw/source/core/text/itratr.cxx | 2 |
3 files changed, 37 insertions, 4 deletions
diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx index 34e31371d346..85dae0e7cfab 100644 --- a/sw/qa/core/layout/flycnt.cxx +++ b/sw/qa/core/layout/flycnt.cxx @@ -629,6 +629,32 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFly1stRowDelete) // on page 2. CPPUNIT_ASSERT(!pPage1->GetNext()); } + +CPPUNIT_TEST_FIXTURE(Test, testSplitFly3rdRowDelete) +{ + // Given a document with a floattable, split on 3 pages: + SwModelTestBase::FlySplitGuard aGuard; + createSwDoc("floattable-3pages.docx"); + + // When deleting the row of A3: + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + pWrtShell->GotoTable("Table1"); + pWrtShell->Down(/*bSelect=*/false); + pWrtShell->Down(/*bSelect=*/false); + SwTextNode* pTextNode = pWrtShell->GetCursor()->GetPointNode().GetTextNode(); + // We delete the right row: + CPPUNIT_ASSERT_EQUAL(OUString("A3"), pTextNode->GetText()); + pWrtShell->DeleteRow(); + + // Then make sure we only have 2 pages: + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPage1 = dynamic_cast<SwPageFrame*>(pLayout->Lower()); + CPPUNIT_ASSERT(pPage1); + auto pPage2 = dynamic_cast<SwPageFrame*>(pPage1->GetNext()); + // Without the accompanying fix in place, this test would have failed, page 3 was not deleted. + CPPUNIT_ASSERT(!pPage2->GetNext()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/flycnt.cxx b/sw/source/core/layout/flycnt.cxx index 042d684ff735..3b2b9e257e7e 100644 --- a/sw/source/core/layout/flycnt.cxx +++ b/sw/source/core/layout/flycnt.cxx @@ -1635,10 +1635,7 @@ void SwRootFrame::DeleteEmptyFlys_() if (!pFly->getFrameArea().HasArea() && !pFly->ContainsContent() && !pFly->IsDeleteForbidden()) { - SwTextFrame* pFlyAnchor = pFly->FindAnchorCharFrame(); SwFrame::DestroyFrame(pFly); - // So that JoinFrame() is called on the precede of the anchor if it has any. - pFlyAnchor->InvalidateSize(); } } } @@ -1655,6 +1652,16 @@ SwFlyAtContentFrame* SwFlyAtContentFrame::GetPrecede() void SwFlyAtContentFrame::DelEmpty() { + SwTextFrame* pAnchor = FindAnchorCharFrame(); + if (pAnchor) + { + if (SwFlowFrame* pAnchorPrecede = pAnchor->GetPrecede()) + { + // The anchor has a precede: invalidate it so that JoinFrame() is called on it. + pAnchorPrecede->GetFrame().InvalidateSize(); + } + } + SwFlyAtContentFrame* pMaster = IsFollow() ? GetPrecede() : nullptr; if (pMaster) { diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx index bc46758eb590..f055f735a94f 100644 --- a/sw/source/core/text/itratr.cxx +++ b/sw/source/core/text/itratr.cxx @@ -1507,7 +1507,7 @@ bool SwTextFrame::HasNonLastSplitFlyDrawObj() const // Nominally all flys are anchored in the master; see if this fly is effectively anchored in // us. SwTextFrame* pFlyAnchor = pFly->FindAnchorCharFrame(); - if (pFlyAnchor != pAnchor) + if (pFlyAnchor != this) { continue; } |