diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx index 0c70295e9370..e5c114474425 100644 --- a/sw/inc/fesh.hxx +++ b/sw/inc/fesh.hxx @@ -672,7 +672,7 @@ public: void SetRowSplit( const SwFormatRowSplit &rSz ); std::unique_ptr GetRowSplit() const; - void SetBoxAlign( sal_uInt16 nOrient ); + SW_DLLPUBLIC void SetBoxAlign(sal_uInt16 nOrient); sal_uInt16 GetBoxAlign() const; ///< USHRT_MAX if ambiguous. bool BalanceRowHeight( bool bTstOnly, const bool bOptimize = false ); diff --git a/sw/qa/extras/layout/data/2024-01-19_merged-cells-on-separate-pages-vertical-alignement.odt b/sw/qa/extras/layout/data/2024-01-19_merged-cells-on-separate-pages-vertical-alignement.odt new file mode 100644 index 000000000000..e316e93fe087 Binary files /dev/null and b/sw/qa/extras/layout/data/2024-01-19_merged-cells-on-separate-pages-vertical-alignement.odt differ diff --git a/sw/qa/extras/layout/layout5.cxx b/sw/qa/extras/layout/layout5.cxx index 64d7e33a8b23..eaefdcf69bbf 100644 --- a/sw/qa/extras/layout/layout5.cxx +++ b/sw/qa/extras/layout/layout5.cxx @@ -742,6 +742,67 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter5, testTdf117245) assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout", 1); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter5, testTdf159029) +{ + createSwDoc("2024-01-19_merged-cells-on-separate-pages-vertical-alignement.odt"); + + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[2]/infos/bounds", "top", + u"1970"); + assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[2]/txt[1]/infos/bounds", "top", + u"1970"); + } + + // set vert orient + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + pWrtShell->GotoTable("Table1"); + pWrtShell->Right(SwCursorSkipMode::Cells, /*bSelect=*/false, 1, /*bBasicCall=*/false); + pWrtShell->SetBoxAlign(css::text::VertOrientation::BOTTOM); + + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[2]/infos/bounds", "top", + u"1970"); + assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[2]/txt[1]/infos/bounds", "top", + u"15494"); + } + + // delete + pWrtShell->SttEndDoc(true); + pWrtShell->DelRight(); + + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[2]/infos/bounds", "top", + u"1694"); + // the problem was that this moved to the top of the cell + assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[2]/txt[1]/infos/bounds", "top", + u"15494"); + } + + pWrtShell->Undo(); + + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[2]/infos/bounds", "top", + u"1970"); + // the problem was that this moved to the top of the cell + assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[2]/txt[1]/infos/bounds", "top", + u"15494"); + } + + pWrtShell->Redo(); + + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[2]/infos/bounds", "top", + u"1694"); + assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[2]/txt[1]/infos/bounds", "top", + u"15494"); + } +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter5, testTdf118672) { createSwDoc("tdf118672.odt"); diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index e61ccacaaafb..f69b94df8a09 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -185,6 +185,22 @@ void SwTabFrame::RegistFlys() } } +static void InvalidateVertOrientCells(SwRowFrame & rRow) +{ + for (SwFrame * pLower{rRow.Lower()}; pLower != nullptr; pLower = pLower->GetNext()) + { + SwCellFrame * pCell{static_cast(pLower)}; + if (pCell->GetLayoutRowSpan() != 1) + { + pCell = const_cast(&pCell->FindStartEndOfRowSpanCell(true)); + } + if (pCell->GetFormat()->GetVertOrient().GetVertOrient() != text::VertOrientation::NONE) + { // tdf#159029 force repositioning of content in cell because it + pCell->InvalidatePrt(); // was disabled by SetRebuildLastLine() + } + } +} + static void SwInvalidateAll( SwFrame *pFrame, tools::Long nBottom ); static void lcl_RecalcRow( SwRowFrame& rRow, tools::Long nBottom ); static bool lcl_ArrangeLowers( SwLayoutFrame *pLay, tools::Long lYStart, bool bInva ); @@ -865,6 +881,7 @@ static bool lcl_RecalcSplitLine( SwRowFrame& rLastLine, SwRowFrame& rFollowLine, // Everything looks fine. Splitting seems to be successful. We invalidate // rFollowLine to force a new formatting. ::SwInvalidateAll( &rFollowLine, LONG_MAX ); + InvalidateVertOrientCells(rLastLine); } else { @@ -2680,6 +2697,7 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) ::SwInvalidateAll( pLastLine, LONG_MAX ); SetRebuildLastLine( true ); lcl_RecalcRow(*static_cast(pLastLine), LONG_MAX); + InvalidateVertOrientCells(*static_cast(pLastLine)); SetRebuildLastLine( false ); }