summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-04-04 08:28:08 +0200
committerMiklos Vajna <vmiklos@collabora.com>2023-04-04 11:49:08 +0200
commit96df0ad0da6e8972a828721dac6b4ba7c69eba85 (patch)
treedda12d2373003d046fbb3ca6e4f514f4501bb1ee /sw
parent309469a3863c1ce7a2d463f3a62f5101c39ac89c (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.cxx26
-rw-r--r--sw/source/core/layout/flycnt.cxx13
-rw-r--r--sw/source/core/text/itratr.cxx2
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;
}