tdf#167229 sw floattable: fix missing cell background with redlines

Open the DOCX file, the 3rd table should have a gray background in its
B2 cell, but its background is white.

It seems this happens because there are 2 floating tables before the
table and the first floating table has a redline. Commit
288db6eb47 (tdf#132271 DOCX: import change
tracking in floating tables, 2020-09-07) added special handling of
redlines inside floating tables, and I moved that code around for
SwFormatFlySplit in c50bf5a5da (sw
floattable: remove no longer needed DOCX import heuristics, 2023-04-12).
The trouble is that once these pending redlines are processed, nobody
clears rFramedRedlines, so it gets processed also for a next floating
table, which pollutes the state of the importer, which leads to missing
cell properties for later tables.

Fix the problem by clearing the redline list in
DomainMapperTableHandler::endTable(), which restores the invariant that
once the redline list is processed, it's cleared -- that was there in
the old SectionPropertyMap::CloseSectionGroup() code before the
SwFormatFlySplit work.

An alternative I've considered is to just catch exceptions in
BeforeConvertToTextFrame() when getting the TextTable and Cell
properties, but that would still result in this unwanted behavior that a
floattable-with-redlines has an influance on the next floattable.

Change-Id: I9998a46d72a72172dffcf85bf96b3478d63c9269
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187535
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Miklos Vajna
2025-07-08 09:50:08 +02:00
parent 53496854ab
commit f124b25380
4 changed files with 44 additions and 4 deletions

View File

@ -37,6 +37,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_writerfilter_dmapper, \
comphelper \
cppu \
cppuhelper \
editeng \
oox \
sal \
subsequenttest \
@ -45,6 +46,17 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_writerfilter_dmapper, \
utl \
tl \
vcl \
svl \
sw \
swqahelper \
))
$(eval $(call gb_CppunitTest_set_include,sw_writerfilter_dmapper,\
-I$(SRCDIR)/sw/inc \
-I$(SRCDIR)/sw/source/core/inc \
-I$(SRCDIR)/sw/source/uibase/inc \
-I$(SRCDIR)/sw/qa/inc \
$$(INCLUDE) \
))
$(eval $(call gb_CppunitTest_use_sdk_api,sw_writerfilter_dmapper))

View File

@ -7,7 +7,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <test/unoapixml_test.hxx>
#include <swmodeltestbase.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/table/BorderLine2.hpp>
@ -21,16 +21,19 @@
#include <com/sun/star/text/XPageCursor.hpp>
#include <com/sun/star/qa/XDumper.hpp>
#include <frmatr.hxx>
#include <swtable.hxx>
using namespace ::com::sun::star;
namespace
{
/// Tests for sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx.
class Test : public UnoApiXmlTest
class Test : public SwModelTestBase
{
public:
Test()
: UnoApiXmlTest(u"/sw/qa/writerfilter/dmapper/data/"_ustr)
: SwModelTestBase(u"/sw/qa/writerfilter/dmapper/data/"_ustr)
{
}
};
@ -277,6 +280,28 @@ CPPUNIT_TEST_FIXTURE(Test, testDOCXFloatingTableNestedLayout)
CPPUNIT_ASSERT_GREATER(nTableTop, nFlyTop);
CPPUNIT_ASSERT_LESS(nTableBottom, nFlyBottom);
}
CPPUNIT_TEST_FIXTURE(Test, testDOCXFloatingTableRedline)
{
// Given a document with 3 floating tables, the last table has a last cell with a custom cell
// background:
// When importing that document from DOCX:
createSwDoc("floattable-redline.docx");
// Then make sure that the cell background is not lost:
SwDoc* pDoc = getSwDoc();
sw::TableFrameFormats& rTableFormats = *pDoc->GetTableFrameFormats();
SwTableFormat* pTableFormat = rTableFormats[2];
SwTable* pTable = SwTable::FindTable(pTableFormat);
const SwTableBox* pCell = pTable->GetTableBox(u"B2"_ustr);
const SwAttrSet& rCellSet = pCell->GetFrameFormat()->GetAttrSet();
const SvxBrushItem& rCellBackground = rCellSet.GetBackground();
// Without the accompanying fix in place, this test would have failed with:
// - Expected: rgba[d0d8e8ff]
// - Actual : rgba[ffffff00]
// i.e. the cell background was white, should be gray.
CPPUNIT_ASSERT_EQUAL(Color(0xD0D8E8), rCellBackground.GetColor());
}
}
CPPUNIT_PLUGIN_IMPLEMENT();

View File

@ -1668,7 +1668,7 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
bool bRecordChanges = m_rDMapper_Impl.GetSettingsTable()->GetRecordChanges();
if (xTextAppendAndConvert.is() && !(bInFootnote && bRecordChanges))
{
const std::deque<StoredRedline>& rFramedRedlines = m_rDMapper_Impl.m_aStoredRedlines[StoredRedlines::FRAME];
std::deque<StoredRedline>& rFramedRedlines = m_rDMapper_Impl.m_aStoredRedlines[StoredRedlines::FRAME];
std::vector<sal_Int32> redPos, redLen;
std::vector<OUString> redCell;
std::vector<OUString> redTable;
@ -1722,6 +1722,9 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
}
AfterConvertToTextFrame(m_rDMapper_Impl, rFramedRedlines, redPos, redLen, redCell, redTable);
// These redlines are not relevant for the next floating table, clear them.
rFramedRedlines.clear();
}
if (xFrameAnchor.is() && eBreakType != style::BreakType_NONE)