From b71a9bcc2e1b4541c14e8197b5b888ee92297a6e Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Mon, 12 Jun 2023 08:12:44 +0200 Subject: sw floattable: import non-split inner floating tables from DOCX The last floating table from the bugdoc has an inner floating table. That inner floating table was imported as a normal table, which means that the content is on page 1 in Word, but it on 2 pages in Writer. Import of nested floating tables were disabled because the layout is not yet ready to handle nested split flys. But in case the inner table is not in a fly, then the table height is large enough that it doesn't fit into page 1, which leads to incorrect layout. Fix the problem by allowing inner floating tables in floating tables, but disable the ability to split for the inner one for now. In the long run we still need layout-level nested multi-page floating tables, but one step at a time. Change-Id: Ib90cf2873bf7d6c817450a263156764f6f09855e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152891 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- .../dmapper/DomainMapperTableHandler.cxx | 20 +++++++++++++++ .../data/floattable-outer-nonsplit-inner.docx | Bin 0 -> 16566 bytes .../source/dmapper/DomainMapperTableHandler.cxx | 27 +++++++++------------ 3 files changed, 32 insertions(+), 15 deletions(-) create mode 100644 writerfilter/qa/cppunittests/dmapper/data/floattable-outer-nonsplit-inner.docx (limited to 'writerfilter') diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx index 803f2cd938b6..1f044bc2f309 100644 --- a/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,25 @@ CPPUNIT_TEST_FIXTURE(Test, test3NestedFloatingTables) uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xIndexAccess->getCount()); } + +CPPUNIT_TEST_FIXTURE(Test, testFloatingTablesOuterNonsplitInner) +{ + // Given a document with a normal table, 3 outer floating tables and an inner floating table in + // the last floating table: + loadFromURL(u"floattable-outer-nonsplit-inner.docx"); + + // When counting the floating tables in the document: + uno::Reference xFramesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xFrames(xFramesSupplier->getTextFrames(), + uno::UNO_QUERY); + + // Then make sure no floating tables are missing: + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 4 + // - Actual : 3 + // i.e. the inner floating table was not floating. + CPPUNIT_ASSERT_EQUAL(static_cast(4), xFrames->getCount()); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/qa/cppunittests/dmapper/data/floattable-outer-nonsplit-inner.docx b/writerfilter/qa/cppunittests/dmapper/data/floattable-outer-nonsplit-inner.docx new file mode 100644 index 000000000000..dc213b1b0d26 Binary files /dev/null and b/writerfilter/qa/cppunittests/dmapper/data/floattable-outer-nonsplit-inner.docx differ diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index f2f09d8a22d4..438036a65ec3 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -1329,7 +1329,7 @@ static void lcl_convertFormulaRanges(const uno::Reference & xT } } -void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel, bool /*bTableStartsAtCellStart*/) +void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel, bool bTableStartsAtCellStart) { #ifdef DBG_UTIL TagLogger::getInstance().startElement("tablehandler.endTable"); @@ -1558,27 +1558,24 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel, bool /*bT comphelper::makePropertyValue("IsFollowingTextFlow", true)); } - // A text frame created for floating tables is always allowed to split. - aFrameProperties.push_back(comphelper::makePropertyValue("IsSplitAllowed", true)); - - // In case the document ends with a table, we're called after - // SectionPropertyMap::CloseSectionGroup(), so we'll have no idea - // about the text area width, nor can fix this by delaying the text - // frame conversion: just do it here. - // Also, when the anchor is within a table, then do it here as well, - // as xStart/xEnd would not point to the start/end at conversion - // time anyway. - // Next exception: it's pointless to delay the conversion if the - // table is not in the body text. + if (nestedTableLevel <= 1) + { + // A text frame created for floating tables is allowed to split if it's a toplevel + // table. + aFrameProperties.push_back(comphelper::makePropertyValue("IsSplitAllowed", true)); + } + sal_Int32 nTableWidth = 0; m_aTableProperties->getValue(TablePropertyMap::TABLE_WIDTH, nTableWidth); sal_Int32 nTableWidthType = text::SizeType::FIX; m_aTableProperties->getValue(TablePropertyMap::TABLE_WIDTH_TYPE, nTableWidthType); // m_xText points to the body text, get the current xText from m_rDMapper_Impl, in case e.g. we would be in a header. uno::Reference xTextAppendAndConvert(m_rDMapper_Impl.GetTopTextAppend(), uno::UNO_QUERY); - // Only execute the conversion for top-level tables. + // Don't execute the conversion for nested tables anchored at a cell start: that + // currently invalidates the cell start / end references and the outer table conversion + // would fail. uno::Reference xFrameAnchor; - if (xTextAppendAndConvert.is() && nestedTableLevel <= 1) + if (xTextAppendAndConvert.is() && !(nestedTableLevel >= 2 && bTableStartsAtCellStart)) { std::deque aFramedRedlines = m_rDMapper_Impl.m_aStoredRedlines[StoredRedlines::FRAME]; std::vector redPos, redLen; -- cgit