tdf#159029 sw: layout: fix cell vertical orientation after split
The vertical alignment of cells is implemented in SwCellFrame::Format(), but it is disabled if IsRebuildLastLine() is true (apparently since the time when splitting table rows was first implemented in commit90b73c7b66"INTEGRATION: CWS cellbreak") which is in 2 different cases: 1. when another line fits on the page, around a call to lcl_RecalcRow(pLastLine) after RemoveFollowFlowLine() - this is the relevant case when the paragraph is deleted This case used to work by accident before commit068c133ac4, when after RemoveFollowFlowLine() of row 406 the text frame moved to the top, then a Split of the row after the one containing the last part of the merged cell with the problem was attempted and failed, and in lcl_RecalcRow() after the Split the alignment was fixed; this commit changed it so that the first row frame 6 had an invalid position, which caused an earlier correction of the position of all the cells and text frames during the lcl_RecalcRow() after joining the follow, where m_bIsRebuildLastLine was set. 2. after a successful Split() with bTryToSplit=true, i.e., a row was split - this is the relevant case on Undo of the paragraph delete This actually was a problem already before the above mentioned commit, but then it could be "fixed" by clicking on the cell, which stopped to work. Here there is no RemoveFollowFlowLine() at the start, but then again a failed attempt to Split a row followed by a successful Split between rows; before the 2nd Split the text frame is correctly positioned and valid, but then lcl_RecalcSplitLine() calling lcl_ShrinkCellsAndAllContent() moves the text frame up. In both cases, explicitly invalidate the PrtArea of cells in the last row where a vertical orientation is set. (regression from commit068c133ac4) Change-Id: I7d2e85bb76a4b77c7871d759abbebd6abeb31282 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181113 Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> Tested-by: Jenkins
This commit is contained in:
+1
-1
@@ -672,7 +672,7 @@ public:
|
||||
void SetRowSplit( const SwFormatRowSplit &rSz );
|
||||
std::unique_ptr<SwFormatRowSplit> 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 );
|
||||
|
||||
BIN
Binary file not shown.
@@ -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");
|
||||
|
||||
@@ -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<SwCellFrame *>(pLower)};
|
||||
if (pCell->GetLayoutRowSpan() != 1)
|
||||
{
|
||||
pCell = const_cast<SwCellFrame *>(&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<SwRowFrame*>(pLastLine), LONG_MAX);
|
||||
InvalidateVertOrientCells(*static_cast<SwRowFrame *>(pLastLine));
|
||||
SetRebuildLastLine( false );
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user