summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-06-12 08:12:44 +0200
committerMiklos Vajna <vmiklos@collabora.com>2023-06-12 10:29:17 +0200
commitb71a9bcc2e1b4541c14e8197b5b888ee92297a6e (patch)
treeab3060c7c9ad66baa1dd3c0470ac1079c61f5d57 /writerfilter
parent1b0420e9980324f04bfd4b1316b572331f1e83bc (diff)
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 <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx20
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/floattable-outer-nonsplit-inner.docxbin0 -> 16566 bytes
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableHandler.cxx27
3 files changed, 32 insertions, 15 deletions
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 <com/sun/star/table/BorderLine2.hpp>
#include <com/sun/star/text/XTextTable.hpp>
#include <com/sun/star/text/XTextTablesSupplier.hpp>
+#include <com/sun/star/text/XTextFramesSupplier.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <com/sun/star/text/XTextDocument.hpp>
#include <com/sun/star/style/BreakType.hpp>
@@ -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<text::XTextFramesSupplier> xFramesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> 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<sal_Int32>(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
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/floattable-outer-nonsplit-inner.docx
Binary files 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<text::XTextTable> & 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<text::XTextAppendAndConvert> 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<beans::XPropertySet> xFrameAnchor;
- if (xTextAppendAndConvert.is() && nestedTableLevel <= 1)
+ if (xTextAppendAndConvert.is() && !(nestedTableLevel >= 2 && bTableStartsAtCellStart))
{
std::deque<css::uno::Any> aFramedRedlines = m_rDMapper_Impl.m_aStoredRedlines[StoredRedlines::FRAME];
std::vector<sal_Int32> redPos, redLen;