summaryrefslogtreecommitdiff
path: root/sw/qa/writerfilter/cppunittests/dmapper
diff options
context:
space:
mode:
Diffstat (limited to 'sw/qa/writerfilter/cppunittests/dmapper')
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/CellColorHandler.cxx48
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/DomainMapper.cxx166
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/DomainMapperTableHandler.cxx236
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/DomainMapperTableManager.cxx47
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/DomainMapper_Impl.cxx416
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/GraphicImport.cxx415
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/PropertyMap.cxx180
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/SdtHelper.cxx261
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/SettingsTable.cxx92
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/TableManager.cxx46
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/TextEffectsHandler.cxx70
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/1cell-insidev-rightborder.docxbin0 -> 13204 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/alt-chunk.docxbin0 -> 22007 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/chart-zorder.docxbin0 -> 21206 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/clearing-break.docxbin0 -> 15739 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/content-control-data-binding-color.docxbin0 -> 21621 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/content-control-date-data-binding.docxbin0 -> 33834 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/create-date-preserve.docxbin0 -> 13310 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/do-not-break-wrapped-tables.docxbin0 -> 13150 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/draw-shape-inline-effect.docxbin0 -> 16534 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/fdo78333-1-minimized.docxbin0 -> 27391 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/field-if-inside-if.docxbin0 -> 12874 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-header.docxbin0 -> 15046 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-section-break.docxbin0 -> 12496 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-break-before.docxbin0 -> 12423 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-footnote-redline.docxbin0 -> 9673 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header-overlap.docxbin0 -> 23584 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header.docxbin0 -> 34658 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-hidden-anchor.docxbin0 -> 21698 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-3tables.docxbin0 -> 131360 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-cellstart.docxbin0 -> 19261 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested.docxbin0 -> 12716 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-outer-nonsplit-inner.docxbin0 -> 16566 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-sectend.docxbin0 -> 16398 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-tbl-overlap.docxbin0 -> 12734 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-then-table.docxbin0 -> 98649 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-vertical-frame-offset.rtf43
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/floattable-wrap-on-all-pages.docxbin0 -> 13446 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/follow-page-top-margin.docxbin0 -> 23144 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/frame-direction.docxbin0 -> 28204 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/group-shape-rotation.docxbin0 -> 24177 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/inline-anchored-zorder.docxbin0 -> 16684 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/inline-inshape-anchored-zorder.docxbin0 -> 17243 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/large-para-top-margin.docxbin0 -> 23126 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/layout-in-cell-2.docxbin0 -> 66189 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/layout-in-cell-wrapnone-column.docxbin0 -> 12900 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border-no-margin.docxbin0 -> 12206 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border.docxbin0 -> 12124 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/nested-floating-table.docxbin0 -> 12915 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/num-restart-style-parent.docxbin0 -> 12336 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/page-break-footer-table.docxbin0 -> 15416 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/paste-ole.rtf30
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/ptab.docxbin0 -> 15861 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/redlined-shape-sdt.docxbin0 -> 13837 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/relfromh-insidemargin.docxbin0 -> 16119 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/sdt-block-text.docxbin0 -> 13467 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/sdt-dropdown-no-display-text.docxbin0 -> 11858 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-checkbox.docxbin0 -> 4244 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-combobox.docxbin0 -> 4274 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-dropdown.docxbin0 -> 4323 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-in-para.docxbin0 -> 11987 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-picture.docxbin0 -> 13686 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-plain-text.docxbin0 -> 4179 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-rich-text.docxbin0 -> 5406 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/semi-transparent-text.docxbin0 -> 12738 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/table-negative-vertical-pos.docxbin0 -> 12648 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf129205.docxbin0 -> 13237 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540ChildRotation.docxbin0 -> 15385 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupLinePosSize.docxbin0 -> 19457 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupRotation.docxbin0 -> 18803 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf142304GroupPosition.docxbin0 -> 20932 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305SquareWrapMargin.docxbin0 -> 23700 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305StrokeGlowMargin.docxbin0 -> 74805 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf143208_wrapTight.docxbin0 -> 20136 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf143455_SmartArtPosition.docxbin0 -> 24753 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf149840_SmartArtBackground.docxbin0 -> 23200 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf152884_Char_Transparency.docxbin0 -> 14109 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/tdf158360.docxbin0 -> 27389 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline-top.docxbin0 -> 12637 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline.docxbin0 -> 12934 bytes
-rw-r--r--sw/qa/writerfilter/cppunittests/dmapper/data/wrap-poly-crop.docxbin0 -> 15018 bytes
81 files changed, 2050 insertions, 0 deletions
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/CellColorHandler.cxx b/sw/qa/writerfilter/cppunittests/dmapper/CellColorHandler.cxx
new file mode 100644
index 000000000000..f7904c95fb9a
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/CellColorHandler.cxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapi_test.hxx>
+
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/dmapper/CellColorHandler.cxx.
+class Test : public UnoApiTest
+{
+public:
+ Test()
+ : UnoApiTest("/sw/qa/writerfilter/cppunittests/dmapper/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, test129205)
+{
+ loadFromFile(u"tdf129205.docx");
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ drawing::FillStyle eFillStyle = drawing::FillStyle::FillStyle_NONE;
+ xPara->getPropertyValue("FillStyle") >>= eFillStyle;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: drawing::FillStyle_NONE
+ // - Actual : FillStyle_SOLID
+ // i.e. the paragraph had a solid fill, making the header image invisible.
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, eFillStyle);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/DomainMapper.cxx b/sw/qa/writerfilter/cppunittests/dmapper/DomainMapper.cxx
new file mode 100644
index 000000000000..4a69c4520f07
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/DomainMapper.cxx
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapi_test.hxx>
+
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+
+#include <tools/UnitConversion.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/dmapper/DomainMapper.cxx.
+class Test : public UnoApiTest
+{
+public:
+ Test()
+ : UnoApiTest("/sw/qa/writerfilter/cppunittests/dmapper/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testLargeParaTopMargin)
+{
+ // Given a document with a paragraph with a large "before" spacing.
+ loadFromFile(u"large-para-top-margin.docx");
+
+ // When checking the first paragraph.
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+
+ // Then assert its top margin.
+ sal_Int32 nParaTopMargin{};
+ xPara->getPropertyValue("ParaTopMargin") >>= nParaTopMargin;
+ // <w:spacing w:before="37050"/> in the document.
+ sal_Int32 nExpected = convertTwipToMm100(37050);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 65352
+ // - Actual : 0
+ // i.e. the paragraph margin was lost, which shifted the paragraph to the right (no top margin
+ // -> wrap around a TextBox), which shifted the triangle shape out of the page frame.
+ CPPUNIT_ASSERT_EQUAL(nExpected, nParaTopMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunInPara)
+{
+ // Given a document with a block SDT, and inside that some content + a run SDT:
+ loadFromFile(u"sdt-run-in-para.docx");
+
+ // Then make sure the content inside the block SDT but outside the run SDT is not lost:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: first-second
+ // - Actual : second
+ // i.e. the block-SDT-only string was lost.
+ CPPUNIT_ASSERT_EQUAL(OUString("first-second"), xPara->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtDropdownNoDisplayText)
+{
+ // Given a document with <w:listItem w:value="..."/> (no display text):
+ loadFromFile(u"sdt-dropdown-no-display-text.docx");
+
+ // Then make sure we create a dropdown content control, not a rich text one:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xParagraphsAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration();
+ uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY);
+ OUString aPortionType;
+ xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+ uno::Reference<text::XTextContent> xContentControl;
+ xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValues> aListItems;
+ xContentControlProps->getPropertyValue("ListItems") >>= aListItems;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 0
+ // i.e. the list item was lost on import.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aListItems.getLength());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testFloattableThenTable)
+{
+ // Given a document with an in-section floating table, followed by a table:
+ // When laying out that document:
+ loadFromFile(u"floattable-then-table.docx");
+
+ // Then make sure that instead of crashing, the floating table is anchored inside the body text
+ // (and not a cell):
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XText> xBodyText = xTextDocument->getText();
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<text::XTextContent> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xAnchor = xShape->getAnchor();
+ // Make sure the anchor text is the body text, not some cell.
+ CPPUNIT_ASSERT_EQUAL(xBodyText, xAnchor->getText());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtBlockText)
+{
+ // Given a document with a block SDT that only contains text:
+ loadFromFile(u"sdt-block-text.docx");
+
+ // Then make sure that the text inside the SDT is imported as a content control:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPara->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ OUString aTextPortionType;
+ xPortion->getPropertyValue("TextPortionType") >>= aTextPortionType;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: ContentControl
+ // - Actual : TextField
+ // i.e. the SDT was imported as a text field, not as a content control.
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aTextPortionType);
+
+ // Make sure the properties are imported
+ uno::Reference<text::XTextContent> xContentControl;
+ xPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY);
+ OUString aAlias;
+ xContentControlProps->getPropertyValue("Alias") >>= aAlias;
+ CPPUNIT_ASSERT_EQUAL(OUString("myalias"), aAlias);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testFdo78333)
+{
+ // just care that it doesn't crash/assert
+ loadFromFile(u"fdo78333-1-minimized.docx");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf158360)
+{
+ // just test that doc with annotation in TOC doesn't crash/assert
+ loadFromFile(u"tdf158360.docx");
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/DomainMapperTableHandler.cxx b/sw/qa/writerfilter/cppunittests/dmapper/DomainMapperTableHandler.cxx
new file mode 100644
index 000000000000..0283f80e9ceb
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/DomainMapperTableHandler.cxx
@@ -0,0 +1,236 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapixml_test.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#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>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
+#include <com/sun/star/qa/XDumper.hpp>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx.
+class Test : public UnoApiXmlTest
+{
+public:
+ Test()
+ : UnoApiXmlTest("/sw/qa/writerfilter/cppunittests/dmapper/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, test1cellInsidevRightborder)
+{
+ loadFromFile(u"1cell-insidev-rightborder.docx");
+ uno::Reference<text::XTextTablesSupplier> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTextDocument->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
+ table::BorderLine2 aBorder;
+ xCell->getPropertyValue("RightBorder") >>= aBorder;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 0
+ // - Actual : 18
+ // i.e. the request to have no table-level right border was lost on import.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), aBorder.LineWidth);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testNestedFloatingTable)
+{
+ loadFromFile(u"nested-floating-table.docx");
+ // Normal outer table, floating inner tables.
+ uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xIndexAccess->getCount());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testFloatingTableBreakBefore)
+{
+ // Given a 3 pages document: page break, then a multi-page floating table on pages 2 and 3:
+ // When laying out that document:
+ loadFromFile(u"floattable-break-before.docx");
+
+ // Then make sure the page break property is on the anchor of the floating table, otherwise it
+ // has no effect:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xText(xTextDocument->getText(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xText->createEnumeration();
+ xParagraphs->nextElement();
+ xParagraphs->nextElement();
+ uno::Reference<beans::XPropertySet> xParagraph(xParagraphs->nextElement(), uno::UNO_QUERY);
+ style::BreakType eBreakType{};
+ xParagraph->getPropertyValue("BreakType") >>= eBreakType;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 4 (style::BreakType_PAGE_BEFORE)
+ // - Actual : 0 (style::BreakType_NONE)
+ // i.e. the page break was lost.
+ CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, eBreakType);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, test3NestedFloatingTables)
+{
+ // Given a document with nested tables: outer and inner one is normal, middle one is floating:
+ // When laying out that document:
+ loadFromFile(u"floattable-nested-3tables.docx");
+
+ // Then make sure we don't crash and create the 3 tables:
+ // Without the accompanying fix in place, this would have crashed, layout can't handle nested
+ // floating tables currently.
+ uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
+ 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:
+ loadFromFile(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_TEST_FIXTURE(Test, testDOCXFloatingTableHiddenAnchor)
+{
+ // Given a document with a floating table, anchored in a paragraph that is hidden:
+ loadFromFile(u"floattable-hidden-anchor.docx");
+
+ // When checking the visibility of the anchor paragraph:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xText(xTextDocument->getText(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xText->createEnumeration();
+ uno::Reference<beans::XPropertySet> xAnchor(xParagraphs->nextElement(), uno::UNO_QUERY);
+
+ // Then make sure the anchor (and thus the table) is visible:
+ bool bCharHidden{};
+ CPPUNIT_ASSERT(xAnchor->getPropertyValue("CharHidden") >>= bCharHidden);
+ // Without the accompanying fix in place, this test would have failed, the paragraph + table was
+ // hidden.
+ CPPUNIT_ASSERT(!bCharHidden);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testDOCXFloatingTableNested)
+{
+ // Given a document with nested, multi-page floating tables:
+ // When loading that document:
+ loadFromFile(u"floattable-nested.docx");
+
+ // Then make sure that both floating tables are allowed to split:
+ uno::Reference<text::XTextFramesSupplier> xFramesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xFrames(xFramesSupplier->getTextFrames(),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xFrames->getCount());
+ // Outer frame:
+ uno::Reference<beans::XPropertySet> xFrame1;
+ xFrames->getByIndex(0) >>= xFrame1;
+ bool bIsSplitAllowed = false;
+ xFrame1->getPropertyValue("IsSplitAllowed") >>= bIsSplitAllowed;
+ CPPUNIT_ASSERT(bIsSplitAllowed);
+ // Inner frame:
+ uno::Reference<beans::XPropertySet> xFrame2;
+ xFrames->getByIndex(1) >>= xFrame2;
+ bIsSplitAllowed = false;
+ xFrame2->getPropertyValue("IsSplitAllowed") >>= bIsSplitAllowed;
+ // Without the accompanying fix in place, this test would have failed, the inner frame could not
+ // split.
+ CPPUNIT_ASSERT(bIsSplitAllowed);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testDOCXFloatingTableHeader)
+{
+ // Given a document with a header that has a floating table and some large images in the body
+ // text:
+ loadFromFile(u"floattable-header.docx");
+
+ // When breaking that document into pages:
+ uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
+ xModel->getCurrentController(), uno::UNO_QUERY);
+ uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(),
+ uno::UNO_QUERY);
+ xCursor->jumpToLastPage();
+
+ // Then make sure we get 2 pages:
+ sal_Int32 nLastPage = xCursor->getPage();
+ // Without the accompanying fix in place, this test would have failed, the page count went to
+ // 2233 pages and then there was a layout loop.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), nLastPage);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testDOCXFloatingTableFootnoteRedline)
+{
+ // Given a document with a floating table in a footnote, with track changes recorded (but not
+ // visible):
+ // When importing that document:
+ loadFromFile(u"floattable-footnote-redline.docx");
+
+ // Then make sure the table is imported as inline, till Writer layout is ready to handle
+ // floating tables in footnotes:
+ uno::Reference<drawing::XDrawPageSupplier> xModel(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xModel->getDrawPage();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), xDrawPage->getCount());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testDOCXFloatingTableHeaderBodyOverlap)
+{
+ // Given a document with a floating table in a header, the floating table extends the header
+ // frame:
+ // When importing that document:
+ loadFromFile(u"floattable-header-overlap.docx");
+
+ // Then make sure the fly bottom is less than the top of the body text:
+ uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+ css::uno::Reference<qa::XDumper> xDumper(xModel->getCurrentController(), uno::UNO_QUERY);
+ OString aDump = xDumper->dump("layout").toUtf8();
+ auto pCharBuffer = reinterpret_cast<const xmlChar*>(aDump.getStr());
+ xmlDocUniquePtr pXmlDoc(xmlParseDoc(pCharBuffer));
+ sal_Int32 nFlyBottom = getXPath(pXmlDoc, "//fly/infos/bounds"_ostr, "bottom"_ostr).toInt32();
+ // Body text top is body top + height of the first line, that's just a fly portion (kind of a
+ // top margin).
+ sal_Int32 nBodyTop
+ = getXPath(pXmlDoc, "//page[1]/body/txt[1]/infos/bounds"_ostr, "top"_ostr).toInt32();
+ // Without the accompanying fix in place, this test would have failed, the first line was not a
+ // fly portion but it was actual text, above the floating table.
+ assertXPath(pXmlDoc, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]/child::*"_ostr,
+ "type"_ostr, "PortionType::Fly");
+ sal_Int32 nBodyFlyPortionHeight
+ = getXPath(pXmlDoc, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "height"_ostr)
+ .toInt32();
+ sal_Int32 nBodyTextTop = nBodyTop + nBodyFlyPortionHeight;
+ // Fly bottom was 3063, body text top was 7148.
+ CPPUNIT_ASSERT_LESS(nBodyTextTop, nFlyBottom);
+}
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/DomainMapperTableManager.cxx b/sw/qa/writerfilter/cppunittests/dmapper/DomainMapperTableManager.cxx
new file mode 100644
index 000000000000..420ae2a18330
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/DomainMapperTableManager.cxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapi_test.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/text/XTextFramesSupplier.hpp>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/dmapper/DomainMapperTableManager.cxx.
+class Test : public UnoApiTest
+{
+public:
+ Test()
+ : UnoApiTest("/sw/qa/writerfilter/cppunittests/dmapper/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testTblOverlap)
+{
+ // Given a document with 2 floating tables, the second is not allowed to overlap:
+ // When importing that document:
+ loadFromFile(u"floattable-tbl-overlap.docx");
+
+ // Then make sure the second table is marked as "can't overlap":
+ uno::Reference<text::XTextFramesSupplier> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xFrames(xTextDocument->getTextFrames(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xFrame(xFrames->getByIndex(1), uno::UNO_QUERY);
+ bool bAllowOverlap{};
+ CPPUNIT_ASSERT(xFrame->getPropertyValue("AllowOverlap") >>= bAllowOverlap);
+ // Without the accompanying fix in place, this test would have failed, the tables were marked as
+ // "can overlap".
+ CPPUNIT_ASSERT(!bAllowOverlap);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/DomainMapper_Impl.cxx b/sw/qa/writerfilter/cppunittests/dmapper/DomainMapper_Impl.cxx
new file mode 100644
index 000000000000..fcbc933b18a0
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/DomainMapper_Impl.cxx
@@ -0,0 +1,416 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapi_test.hxx>
+
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/style/BreakType.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/text/XTextTablesSupplier.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/document/XDocumentInsertable.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
+
+#include <vcl/scheduler.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx.
+class Test : public UnoApiTest
+{
+public:
+ Test()
+ : UnoApiTest("/sw/qa/writerfilter/cppunittests/dmapper/data/")
+ {
+ }
+};
+
+// TODO HEADER FOOTER TEST
+CPPUNIT_TEST_FIXTURE(Test, testPageBreakFooterTable)
+{
+ // Load a document which refers to a footer which ends with a table, and there is a page break
+ // in the body text right after the footer reference.
+ loadFromFile(u"page-break-footer-table.docx");
+
+ // Check the last paragraph.
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPara;
+ while (xParaEnum->hasMoreElements())
+ {
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ }
+ style::BreakType eType = style::BreakType_NONE;
+ xPara->getPropertyValue("BreakType") >>= eType;
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 4
+ // - Actual : 0
+ // i.e. there was no page break before the last paragraph.
+ CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, eType);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testNumberingRestartStyleParent)
+{
+ loadFromFile(u"num-restart-style-parent.docx");
+
+ // The paragraphs are A 1 2 B 1 2.
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPara;
+ static constexpr OUString aProp(u"ListLabelString"_ustr);
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("A."), xPara->getPropertyValue(aProp).get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("1."), xPara->getPropertyValue(aProp).get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("2."), xPara->getPropertyValue(aProp).get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("B."), xPara->getPropertyValue(aProp).get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1.
+ // - Actual : 3.
+ // i.e. the numbering was not restarted after B.
+ CPPUNIT_ASSERT_EQUAL(OUString("1."), xPara->getPropertyValue(aProp).get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("2."), xPara->getPropertyValue(aProp).get<OUString>());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testFrameDirection)
+{
+ loadFromFile(u"frame-direction.docx");
+
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xFrame0(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xFrame1(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xFrame2(xDrawPage->getByIndex(2), uno::UNO_QUERY);
+ // Without the accompanying fix in place, all of the following values would be text::WritingMode2::CONTEXT
+ CPPUNIT_ASSERT_EQUAL(text::WritingMode2::CONTEXT,
+ xFrame0->getPropertyValue("WritingMode").get<sal_Int16>());
+ CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR,
+ xFrame1->getPropertyValue("WritingMode").get<sal_Int16>());
+ CPPUNIT_ASSERT_EQUAL(text::WritingMode2::TB_RL,
+ xFrame2->getPropertyValue("WritingMode").get<sal_Int16>());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testAltChunk)
+{
+ loadFromFile(u"alt-chunk.docx");
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<text::XTextRange> xPara;
+ uno::Reference<beans::XPropertySet> xParaProps;
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ xParaProps.set(xPara, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("outer, before sect break"), xPara->getString());
+ CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
+ xParaProps->getPropertyValue("PageStyleName").get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ xParaProps.set(xPara, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("outer, after sect break"), xPara->getString());
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: Converted1
+ // - Actual : Standard
+ // i.e. the page break between the first and the second paragraph was missing.
+ CPPUNIT_ASSERT_EQUAL(OUString("Converted1"),
+ xParaProps->getPropertyValue("PageStyleName").get<OUString>());
+
+ // Without the accompanying fix in place, this test would have failed with a
+ // container.NoSuchElementException, as the document had only 2 paragraphs, all the "inner"
+ // content was lost.
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("inner doc, first para"), xPara->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testFieldIfInsideIf)
+{
+ // Load a document with a field in a table cell: it contains an IF field with various nested
+ // fields.
+ loadFromFile(u"field-if-inside-if.docx");
+ uno::Reference<text::XTextTablesSupplier> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTextDocument->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+
+ // Get the result of the topmost field.
+ uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2
+ // - Actual : 0** Expression is faulty **2
+ // i.e. some of the inner fields escaped outside the outer field.
+ CPPUNIT_ASSERT_EQUAL(OUString("2"), xCell->getString());
+
+ // Test the second cell: it contains "IF ", not the usual " IF ".
+ xCell.set(xTable->getCellByName("A2"), uno::UNO_QUERY);
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 25
+ // - Actual : 025
+ // i.e. some of the inner fields escaped outside the outer field.
+ CPPUNIT_ASSERT_EQUAL(OUString("25"), xCell->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testCreateDatePreserve)
+{
+ loadFromFile(u"create-date-preserve.docx");
+ // Trigger idle layout.
+ Scheduler::ProcessEventsToIdle();
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPortionEnumAccess(xParaEnum->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPortionEnumAccess->createEnumeration();
+ uno::Reference<text::XTextRange> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 7/7/2020 10:11:00 AM
+ // - Actual : 07/07/2020
+ // i.e. the formatting of the create date field was lost.
+ CPPUNIT_ASSERT_EQUAL(OUString("7/7/2020 10:11:00 AM"), xPortion->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testChartZOrder)
+{
+ // Given a document with a chart and a shape on it:
+ loadFromFile(u"chart-zorder.docx");
+
+ // Then make sure the shape is on top of the chart:
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<lang::XServiceInfo> xChart(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed, as the chart was on top
+ // of the shape.
+ CPPUNIT_ASSERT(xChart->supportsService("com.sun.star.text.TextEmbeddedObject"));
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testPTab)
+{
+ // Given a document that has a <w:ptab> to render a linebreak:
+ loadFromFile(u"ptab.docx");
+
+ // Then make sure that the Writer doc model contains that linebreak:
+ uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
+ uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xStyleFamilies
+ = xStyleFamiliesSupplier->getStyleFamilies();
+ uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
+ auto xFooter = xStyle->getPropertyValue("FooterText").get<uno::Reference<text::XTextRange>>();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: <space><newline>1\n
+ // - Actual: <space><tab>1\n
+ // i.e. the layout height of the footer text was incorrect, the page number field was not
+ // visually inside the background shape.
+ CPPUNIT_ASSERT_EQUAL(OUString(" \n1" SAL_NEWLINE_STRING), xFooter->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testPasteOle)
+{
+ // Given an empty document:
+ mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
+
+ // When pasting RTF into that document:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xTextDocument->getText();
+ uno::Reference<document::XDocumentInsertable> xCursor(
+ xText->createTextCursorByRange(xText->getStart()), uno::UNO_QUERY);
+ OUString aURL = createFileURL(u"paste-ole.rtf");
+ xCursor->insertDocumentFromURL(aURL, {});
+
+ // Then make sure that all the 3 paragraphs of the paste data (empty para, OLE obj, text) are
+ // inserted to the document:
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xText, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ xParaEnum->nextElement();
+ // Without the accompanying fix in place, this test would have failed, as the paste result was a
+ // single paragraph, containing the OLE object, and the content after the OLE object was lost.
+ CPPUNIT_ASSERT(xParaEnum->hasMoreElements());
+ xParaEnum->nextElement();
+ CPPUNIT_ASSERT(xParaEnum->hasMoreElements());
+ uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("hello"), xPara->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testClearingBreak)
+{
+ // Given a document with a clearing break:
+ loadFromFile(u"clearing-break.docx");
+
+ // Then make sure that the clear property of the break is not ignored:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xTextDocument->getText();
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xText, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration();
+ xPortions->nextElement();
+ xPortions->nextElement();
+ // Without the accompanying fix in place, this test would have failed with:
+ // An uncaught exception of type com.sun.star.container.NoSuchElementException
+ // i.e. the first para was just a fly + text portion, the clearing break was lost.
+ uno::Reference<beans::XPropertySet> xPortion(xPortions->nextElement(), uno::UNO_QUERY);
+ OUString aPortionType;
+ xPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+ CPPUNIT_ASSERT_EQUAL(OUString("LineBreak"), aPortionType);
+ uno::Reference<text::XTextContent> xLineBreak;
+ xPortion->getPropertyValue("LineBreak") >>= xLineBreak;
+ sal_Int16 eClear{};
+ uno::Reference<beans::XPropertySet> xLineBreakProps(xLineBreak, uno::UNO_QUERY);
+ xLineBreakProps->getPropertyValue("Clear") >>= eClear;
+ // SwLineBreakClear::ALL
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(3), eClear);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testContentControlDateDataBinding)
+{
+ // Given a document with date content control and data binding, data binding date is 2012,
+ // in-document date is 2022:
+ loadFromFile(u"content-control-date-data-binding.docx");
+
+ // Then make sure that the date is from the data binding, not from document.xml:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xTextDocument->getText();
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xText, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xParaEnumAccess->createEnumeration();
+ uno::Reference<text::XTextRange> xParagraph(xParagraphs->nextElement(), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 4/26/2012
+ // - Actual : 4/26/2022
+ // i.e. the date was from document.xml, which is considered outdated.
+ CPPUNIT_ASSERT_EQUAL(OUString("4/26/2012"), xParagraph->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testContentControlDataBindingColor)
+{
+ // Given a document with an inline content control with data binding, placeholder char color is
+ // set to red, when loading that document:
+ loadFromFile(u"content-control-data-binding-color.docx");
+
+ // Then make sure that the placeholder char color is not in the document, since data binding is
+ // active:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xTextDocument->getText();
+ uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+ xCursor->gotoEnd(/*bExpand=*/false);
+ xCursor->goLeft(/*nCount=*/1, /*bExpand=*/false);
+ uno::Reference<beans::XPropertySet> xCursorProps(xCursor, uno::UNO_QUERY);
+ Color nColor;
+ CPPUNIT_ASSERT(xCursorProps->getPropertyValue("CharColor") >>= nColor);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: rgba[ffffff00]
+ // - Actual : rgba[ff0000ff]
+ // i.e. the char color was red, not the default / automatic.
+ CPPUNIT_ASSERT_EQUAL(COL_AUTO, nColor);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testFloatingTableSectionBreak)
+{
+ // Given a document with 2 floating tables and 2 pages, section break (next page) between the
+ // two:
+ loadFromFile(u"floating-table-section-break.docx");
+
+ // When going to the last page:
+ uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
+ xModel->getCurrentController(), uno::UNO_QUERY);
+ uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(),
+ uno::UNO_QUERY);
+ xCursor->jumpToLastPage();
+
+ // Then make sure that we're on page 2:
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2
+ // - Actual : 1
+ // i.e. the document was of 1 page, the section break was lost.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2), xCursor->getPage());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testFloattableSectend)
+{
+ // Given a document with 2 tables, table 1 on page 1, table 2 on page 2:
+ loadFromFile(u"floattable-sectend.docx");
+
+ // When importing that document and listing the tables:
+ uno::Reference<text::XTextTablesSupplier> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTextDocument->getTextTables(), uno::UNO_QUERY);
+
+ // Then make sure that we have two tables:
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2
+ // - Actual : 1
+ // i.e. the first table was lost.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xTables->getCount());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testRedlinedShapeThenSdt)
+{
+ // Given a file with a second paragraph where text is followed by a redline, then an SDT:
+ // When importing that document:
+ loadFromFile(u"redlined-shape-sdt.docx");
+
+ // Then make sure the content control doesn't start at para start:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ xParaEnum->nextElement();
+ uno::Reference<container::XEnumerationAccess> xPortionEnumAccess(xParaEnum->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPortionEnumAccess->createEnumeration();
+
+ uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: Text
+ // - Actual : ContentControl
+ // i.e. the content control started at para start.
+ CPPUNIT_ASSERT_EQUAL(u"Text"_ustr,
+ xPortion->getPropertyValue("TextPortionType").get<OUString>());
+ xPortion.set(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ // Redline start+end pair, containing a pair of text portions with an anchored object in the
+ // middle.
+ CPPUNIT_ASSERT_EQUAL(u"Redline"_ustr,
+ xPortion->getPropertyValue("TextPortionType").get<OUString>());
+ xPortion.set(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(u"Text"_ustr,
+ xPortion->getPropertyValue("TextPortionType").get<OUString>());
+ xPortion.set(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(u"Frame"_ustr,
+ xPortion->getPropertyValue("TextPortionType").get<OUString>());
+ xPortion.set(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(u"Text"_ustr,
+ xPortion->getPropertyValue("TextPortionType").get<OUString>());
+ xPortion.set(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(u"Redline"_ustr,
+ xPortion->getPropertyValue("TextPortionType").get<OUString>());
+ xPortion.set(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(u"ContentControl"_ustr,
+ xPortion->getPropertyValue("TextPortionType").get<OUString>());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/GraphicImport.cxx b/sw/qa/writerfilter/cppunittests/dmapper/GraphicImport.cxx
new file mode 100644
index 000000000000..c48e15851747
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/GraphicImport.cxx
@@ -0,0 +1,415 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapi_test.hxx>
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/view/XViewCursor.hpp>
+#include <com/sun/star/drawing/PointSequenceSequence.hpp>
+
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <officecfg/Office/Common.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/dmapper/GraphicImport.cxx.
+class Test : public UnoApiTest
+{
+public:
+ Test()
+ : UnoApiTest("/sw/qa/writerfilter/cppunittests/dmapper/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf143455SmartArtPosition)
+{
+ loadFromFile(u"tdf143455_SmartArtPosition.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ // Without fix in place the group, which represents the SmartArt, was placed at the initializing
+ // position 0|0.
+ sal_Int32 nHoriPosition = 0;
+ xShape->getPropertyValue("HoriOrientPosition") >>= nHoriPosition;
+ // The test would have failed with Expected: 2858, Actual: 0
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2858), nHoriPosition);
+ sal_Int32 nVertPosition = 0;
+ xShape->getPropertyValue("VertOrientPosition") >>= nVertPosition;
+ // The test would have failed with Expected: 1588, Actual: 0
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1588), nVertPosition);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf143208wrapTight)
+{
+ loadFromFile(u"tdf143208_wrapTight.docx");
+ // The document has a shape with indentation and contour wrap "wrapTight". Error was, that
+ // the corresponding shape property 'ContourOutside=true' was not set.
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ bool bContourOutside = false;
+ xShape->getPropertyValue("ContourOutside") >>= bContourOutside;
+ CPPUNIT_ASSERT(bContourOutside);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf142305StrokeGlowMargin)
+{
+ loadFromFile(u"tdf142305StrokeGlowMargin.docx");
+ // The document has an arc with fat stroke and glow. Its bounding rectangle differs much
+ // from the snap rectangle. Error was, that the margins were not set in a way, that the shape
+ // would render similar to Word.
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int32 nTopMargin = 0;
+ xShape->getPropertyValue("TopMargin") >>= nTopMargin;
+ // Without fix in place top margin was 0, so that the text comes near to the shape.
+ // The test would have failed with Expected: 838, Actual: 0
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(838), nTopMargin);
+ sal_Int32 nBottomMargin = 0;
+ // Without fix in place bottom margin was >0, so that the text was far from to the shape.
+ // The test would have failed with Expected: 0, Actual: 637
+ xShape->getPropertyValue("BottomMargin") >>= nBottomMargin;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nBottomMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf142305SquareWrapMargin)
+{
+ loadFromFile(u"tdf142305SquareWrapMargin.docx");
+ uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
+ xModel->getCurrentController(), uno::UNO_QUERY_THROW);
+ uno::Reference<text::XTextViewCursor> xViewCursor(xTextViewCursorSupplier->getViewCursor());
+ xViewCursor->gotoStart(/*bExpand=*/false);
+ uno::Reference<view::XViewCursor> xCursor(xViewCursor, uno::UNO_QUERY);
+ xCursor->goDown(/*nCount=*/10, /*bExpand=*/false);
+ xViewCursor->goRight(/*nCount=*/1, /*bExpand=*/true);
+ OUString sText = xViewCursor->getString();
+ // Without fix in place, wrap was tight to the bounding box and not around the full shape as in
+ // Word. That results in different text at start of line, here "u" instead of expected "m".
+ CPPUNIT_ASSERT(sText.startsWith("m"));
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf142304GroupPosition)
+{
+ loadFromFile(u"tdf142304GroupPosition.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int32 nVertPosition = 0;
+ xShape->getPropertyValue("VertOrientPosition") >>= nVertPosition;
+ // Without fix in place the group was shifted left and down
+ // The test would have failed with Expected: 2178, Actual: 2521
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2178), nVertPosition);
+ sal_Int32 nHoriPosition = 0;
+ // The test would have failed with Expected: 4304, Actual: 3874
+ xShape->getPropertyValue("HoriOrientPosition") >>= nHoriPosition;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4304), nHoriPosition);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf141540ChildRotation)
+{
+ loadFromFile(u"tdf141540ChildRotation.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<container::XIndexAccess> xGroup(xDrawPage->getByIndex(0), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xRotatedShape(xGroup->getByIndex(1), uno::UNO_QUERY);
+ sal_Int32 nShearAngle = 9000; // initialize with invalid value
+ xRotatedShape->getPropertyValue("ShearAngle") >>= nShearAngle;
+ // Without fix in place, this test would have failed with:
+ // - Expected: 0
+ // - Actual : 2494
+ // i.e. the rotated rectangle in the group was sheared, although the group itself is not rotated
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nShearAngle);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf141540GroupRotation)
+{
+ loadFromFile(u"tdf141540GroupRotation.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int32 nShearAngle = 9000; // init with invalid value
+ xShape->getPropertyValue("ShearAngle") >>= nShearAngle;
+ // Without fix in place, this test would have failed with:
+ // - Expected: 0
+ // - Actual : -3190
+ // i.e. the group has got a shearing although MSO does not know shearing at all.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nShearAngle);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf141540GroupLinePosSize)
+{
+ loadFromFile(u"tdf141540GroupLinePosSize.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+
+ // Test line
+ uno::Reference<drawing::XShape> xLineShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ awt::Point aPosition = xLineShape->getPosition();
+ awt::Size aSize = xLineShape->getSize();
+ // Without fix in place, you had got Position = (19|6498), Size = 5001 x 2
+ // i.e. the line was nearly horizontal instead of vertical
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5022), aPosition.X);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2963), aPosition.Y);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aSize.Width);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(7073), aSize.Height);
+
+ // Test group
+ uno::Reference<drawing::XShape> xGroupShape(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ aPosition = xGroupShape->getPosition();
+ aSize = xGroupShape->getSize();
+ // Without fix in place, you had got Position = (11511|3480), Size = 4022 x 4022
+ // i.e. the group was erroneously downscaled to unrotated size
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(10679), aPosition.X);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2648), aPosition.Y);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5687), aSize.Width);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5687), aSize.Height);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testGroupShapeRotation)
+{
+ loadFromFile(u"group-shape-rotation.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int32 nVertPosition = 0;
+ xShape->getPropertyValue("VertOrientPosition") >>= nVertPosition;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1221
+ // - Actual : -2048
+ // i.e. the group shape had a so low vertical position that the line shape did not point into
+ // it.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1221), nVertPosition);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testDrawShapeInlineEffect)
+{
+ loadFromFile(u"draw-shape-inline-effect.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int32 nBottomMargin = 0;
+ xShape->getPropertyValue("BottomMargin") >>= nBottomMargin;
+ // 273 in mm100 is 98425 EMUs from the file.
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 273
+ // - Actual : 0
+ // i.e. the layout result had less pages than expected (compared to Word).
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(273), nBottomMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineAnchoredZOrder)
+{
+ // Load a document which has two shapes: an inline one and an anchored one. The inline has no
+ // explicit ZOrder, the anchored one has, and it's set to a value so it's visible.
+ loadFromFile(u"inline-anchored-zorder.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<container::XNamed> xOval(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: Oval 2
+ // - Actual :
+ // i.e. the rectangle (with no name) was on top of the oval one, not the other way around.
+ CPPUNIT_ASSERT_EQUAL(OUString("Oval 2"), xOval->getName());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineInShapeAnchoredZOrder)
+{
+ // This document has a textbox shape and then an inline shape inside that.
+ // The ZOrder of the inline shape is larger than the hosting textbox, so the image is visible.
+ loadFromFile(u"inline-inshape-anchored-zorder.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<container::XNamed> xOval(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: Picture 1
+ // - Actual : Text Box 2
+ // i.e. the image was behind the textbox that was hosting it.
+ CPPUNIT_ASSERT_EQUAL(OUString("Picture 1"), xOval->getName());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testRelfromhInsidemargin)
+{
+ loadFromFile(u"relfromh-insidemargin.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int16 nRelation = 0;
+ xShape->getPropertyValue("HoriOrientRelation") >>= nRelation;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 7 (PAGE_FRAME)
+ // - Actual : 0 (FRAME)
+ // i.e. the horizontal position was relative to the paragraph area, not to the entire page.
+ CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, nRelation);
+ bool bPageToggle = false;
+ xShape->getPropertyValue("PageToggle") >>= bPageToggle;
+ CPPUNIT_ASSERT(bPageToggle);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testWrapPolyCrop)
+{
+ loadFromFile(u"wrap-poly-crop.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ drawing::PointSequenceSequence aContour;
+ xShape->getPropertyValue("ContourPolyPolygon") >>= aContour;
+ auto aPolyPolygon = basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(aContour);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aPolyPolygon.count());
+ auto aPolygon = aPolyPolygon.getB2DPolygon(0);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(4), aPolygon.count());
+
+ // Ideally this would be 2352, because the graphic size in mm100, using the graphic's DPI is
+ // 10582, the lower 33% of the graphic is cropped, and the wrap polygon covers the middle third
+ // of the area vertically. Which means 10582*2/3 = 7054.67 is the cropped height, and the top of
+ // the middle third is 2351.55.
+ // Then there is a 15 twips shift from the origo, so it's 2351.55 + 26.46 = 2378.01 in mm100.
+ //
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2368
+ // - Actual : 3542
+ // i.e. the wrap polygon covered a larger-than-correct area, which end the end means 3 lines
+ // were wrapping around the image, not only 2 as Word does it.
+ CPPUNIT_ASSERT_EQUAL(2368., aPolygon.getB2DPoint(0).getY());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTextboxTextline)
+{
+ // Load a document with a shape with a textbox.
+ // The shape's vertical relation is <wp:positionV relativeFrom="line">.
+ loadFromFile(u"textbox-textline.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int16 nActualRelation{};
+ CPPUNIT_ASSERT(xShape->getPropertyValue("VertOrientRelation") >>= nActualRelation);
+ sal_Int32 nActualPosition{};
+ CPPUNIT_ASSERT(xShape->getPropertyValue("VertOrientPosition") >>= nActualPosition);
+
+ sal_Int16 nExpectedRelation = text::RelOrientation::TEXT_LINE;
+ CPPUNIT_ASSERT_EQUAL(nExpectedRelation, nActualRelation);
+ sal_Int32 nExpectedPosition = -2;
+ CPPUNIT_ASSERT_EQUAL(nExpectedPosition, nActualPosition);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTextboxTextlineTop)
+{
+ loadFromFile(u"textbox-textline-top.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int16 nActualRelation{};
+ CPPUNIT_ASSERT(xShape->getPropertyValue("VertOrientRelation") >>= nActualRelation);
+ sal_Int16 nExpectedRelation = text::RelOrientation::TEXT_LINE;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 9 (TEXT_LINE)
+ // - Actual : 0 (FRAME)
+ // i.e. the anchor point for the positioning was wrong, resulting in overlapping textboxes.
+ CPPUNIT_ASSERT_EQUAL(nExpectedRelation, nActualRelation);
+
+ sal_Int16 nActualOrient{};
+ CPPUNIT_ASSERT(xShape->getPropertyValue("VertOrient") >>= nActualOrient);
+ sal_Int16 nExpectedOrient = text::VertOrientation::BOTTOM;
+ CPPUNIT_ASSERT_EQUAL(nExpectedOrient, nActualOrient);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testLayoutInCellWrapnoneColumn)
+{
+ // Given a file with a table, then a shape anchored inside the cell:
+ loadFromFile(u"layout-in-cell-wrapnone-column.docx");
+
+ // Then make sure the shape can leave the cell:
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ uno::Reference<container::XNamed> xNamedShape(xShape, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Text Box 1"), xNamedShape->getName());
+ bool bFollowingTextFlow = true;
+ // Without the accompanying fix in place, this test would have failed, the shape was not allowed
+ // to leave the cell, leading to incorrect layout.
+ CPPUNIT_ASSERT(xShape->getPropertyValue("IsFollowingTextFlow") >>= bFollowingTextFlow);
+ CPPUNIT_ASSERT(!bFollowingTextFlow);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testLayoutInCellOfHraphics)
+{
+ // Given a file with a table, then a shape anchored inside the cell:
+ loadFromFile(u"layout-in-cell-2.docx");
+
+ // Then make sure the cell obeys the layoutInCell:
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ bool bFollowingTextFlow = false;
+ CPPUNIT_ASSERT(xShape->getPropertyValue("IsFollowingTextFlow") >>= bFollowingTextFlow);
+ CPPUNIT_ASSERT(bFollowingTextFlow);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf149840SmartArtBackground)
+{
+ // Make sure SmartArt is loaded as group shape
+ bool bUseGroup = officecfg::Office::Common::Filter::Microsoft::Import::SmartArtToShapes::get();
+ if (!bUseGroup)
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> pChange(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Filter::Microsoft::Import::SmartArtToShapes::set(true, pChange);
+ pChange->commit();
+ }
+
+ loadFromFile(u"tdf149840_SmartArtBackground.docx");
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<container::XIndexAccess> xGroup(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xGroup->getCount());
+
+ // The first shape in the group, which represents the SmartArt, corresponds to the background of
+ // the diagram. Without fix in place it has width and height zero, which does not only result in
+ // not visible background but in wrong sizes of the diagram shapes too.
+ uno::Reference<drawing::XShape> xBackgroundShape(xGroup->getByIndex(0), uno::UNO_QUERY);
+ awt::Size aBackgroundSize = xBackgroundShape->getSize();
+ // Tolerances are for rounding inaccuracies.
+ // The test would have failed with Expected: 9560x5036, Actual: 2x2
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(9560), aBackgroundSize.Width, 1);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(5036), aBackgroundSize.Height, 1);
+
+ uno::Reference<drawing::XShape> xShapeOne(xGroup->getByIndex(1), uno::UNO_QUERY);
+ awt::Size aShapeOneSize = xShapeOne->getSize();
+ // The test would have failed with Expected: 3282x3709, Actual: 3972x3709
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(3282), aShapeOneSize.Width, 1);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(3709), aShapeOneSize.Height, 1);
+
+ uno::Reference<drawing::XShape> xShapeTwo(xGroup->getByIndex(2), uno::UNO_QUERY);
+ awt::Size aShapeTwoSize = xShapeTwo->getSize();
+ // The test would have failed with Expected: 2404x5226, Actual: 2910x5226
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(2404), aShapeTwoSize.Width, 1);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(5226), aShapeTwoSize.Height, 1);
+
+ if (!bUseGroup)
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> pChange(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Filter::Microsoft::Import::SmartArtToShapes::set(false, pChange);
+ pChange->commit();
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/PropertyMap.cxx b/sw/qa/writerfilter/cppunittests/dmapper/PropertyMap.cxx
new file mode 100644
index 000000000000..78e231e483cd
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/PropertyMap.cxx
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapi_test.hxx>
+
+#include <com/sun/star/text/XPageCursor.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/table/BorderLine2.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+
+#include <unotools/streamwrap.hxx>
+#include <comphelper/propertyvalue.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/dmapper/PropertyMap.cxx.
+class Test : public UnoApiTest
+{
+public:
+ Test()
+ : UnoApiTest("/sw/qa/writerfilter/cppunittests/dmapper/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testFloatingTableHeader)
+{
+ loadFromFile(u"floating-table-header.docx");
+ uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
+ xModel->getCurrentController(), uno::UNO_QUERY);
+ uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(),
+ uno::UNO_QUERY);
+ xCursor->jumpToLastPage();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 3
+ // i.e. a document which is 1 page in Word was imported as a 3 page one.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), xCursor->getPage());
+}
+
+// TODO - First Page Headers Support
+CPPUNIT_TEST_FIXTURE(Test, testFollowPageTopMargin)
+{
+ // Load a document with 2 pages: first page has larger top margin, second page has smaller top
+ // margin.
+ loadFromFile(u"follow-page-top-margin.docx");
+ uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
+ uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xStyleFamilies
+ = xStyleFamiliesSupplier->getStyleFamilies();
+ uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
+ auto nTopMargin = xStyle->getPropertyValue("TopMargin").get<sal_Int32>();
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 250
+ // - Actual : 1249
+ // i.e. the top margin on page 2 was too large.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1249), nTopMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTableNegativeVerticalPos)
+{
+ // Given a document with a table which has a negative vertical position (moves up to overlap
+ // with the header):
+ loadFromFile(u"table-negative-vertical-pos.docx");
+
+ // Then make sure we don't import that as a plain table, which can't have a negative top margin:
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 0
+ // i.e. this was imported as a plain table, resulting in a 0 top margin (y pos too large).
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xDrawPage->getCount());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testNegativePageBorder)
+{
+ // Given a document with a top margin and a border which has more spacing than the margin:
+ loadFromFile(u"negative-page-border.docx");
+
+ // Then make sure that the border distance is negative, so it can appear at the correct
+ // position:
+ uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
+ uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xStyleFamilies
+ = xStyleFamiliesSupplier->getStyleFamilies();
+ uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
+ auto nTopMargin = xStyle->getPropertyValue("TopMargin").get<sal_Int32>();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(501), nTopMargin);
+ auto aTopBorder = xStyle->getPropertyValue("TopBorder").get<table::BorderLine2>();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(159), aTopBorder.LineWidth);
+ auto nTopBorderDistance = xStyle->getPropertyValue("TopBorderDistance").get<sal_Int32>();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: -646
+ // - Actual : 0
+ // i.e. the border negative distance was lost.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-646), nTopBorderDistance);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testNegativePageBorderNoMargin)
+{
+ // Given a document with no top margin and a border which has spacing:
+ loadFromFile(u"negative-page-border-no-margin.docx");
+
+ // Then make sure that the border distance is negative, so it can appear at the correct
+ // position:
+ uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
+ uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xStyleFamilies
+ = xStyleFamiliesSupplier->getStyleFamilies();
+ uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
+ auto nTopMargin = xStyle->getPropertyValue("TopMargin").get<sal_Int32>();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nTopMargin);
+ auto aTopBorder = xStyle->getPropertyValue("TopBorder").get<table::BorderLine2>();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(159), aTopBorder.LineWidth);
+ auto nTopBorderDistance = xStyle->getPropertyValue("TopBorderDistance").get<sal_Int32>();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: -1147
+ // - Actual : 0
+ // i.e. the border negative distance was lost.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-1147), nTopBorderDistance);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testPasteHeaderDisable)
+{
+ // Given an empty document with a turned on header:
+ mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
+ uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
+ uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xStyleFamilies
+ = xStyleFamiliesSupplier->getStyleFamilies();
+ uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
+ xStyle->setPropertyValue("HeaderIsOn", uno::Any(true));
+
+ // When pasting RTF content:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xText = xTextDocument->getText();
+ uno::Reference<text::XTextRange> xBodyEnd = xText->getEnd();
+ uno::Reference<document::XFilter> xFilter(
+ m_xSFactory->createInstance("com.sun.star.comp.Writer.RtfFilter"), uno::UNO_QUERY);
+ uno::Reference<document::XImporter> xImporter(xFilter, uno::UNO_QUERY);
+ xImporter->setTargetDocument(mxComponent);
+ std::unique_ptr<SvStream> pStream(new SvMemoryStream);
+ pStream->WriteOString("{\\rtf1 paste}");
+ pStream->Seek(0);
+ uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(std::move(pStream)));
+ uno::Sequence aDescriptor{ comphelper::makePropertyValue("InputStream", xStream),
+ comphelper::makePropertyValue("InsertMode", true),
+ comphelper::makePropertyValue("TextInsertModeRange", xBodyEnd) };
+ CPPUNIT_ASSERT(xFilter->filter(aDescriptor));
+
+ // Then make sure the header stays on:
+ CPPUNIT_ASSERT(xStyle->getPropertyValue("HeaderIsOn").get<bool>());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/SdtHelper.cxx b/sw/qa/writerfilter/cppunittests/dmapper/SdtHelper.cxx
new file mode 100644
index 000000000000..b5e60e1035dc
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/SdtHelper.cxx
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapi_test.hxx>
+
+#include <comphelper/sequenceashashmap.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+
+using namespace com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/dmapper/SdtHelper.cxx.
+class Test : public UnoApiTest
+{
+public:
+ Test()
+ : UnoApiTest("/sw/qa/writerfilter/cppunittests/dmapper/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunRichText)
+{
+ // Given a document with a rich text inline/run SDT:
+ loadFromFile(u"sdt-run-rich-text.docx");
+
+ // Then make sure that formatting of the text inside the SDT is not lost:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPara->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ OUString aTextPortionType;
+ xPortion->getPropertyValue("TextPortionType") >>= aTextPortionType;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: ContentControl
+ // - Actual : TextField
+ // i.e. the SDT was imported as a text field, and the whole SDT had 12pt font size.
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aTextPortionType);
+ uno::Reference<text::XTextContent> xContentControl;
+ xPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<text::XTextRange> xContentControlRange(xContentControl, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xContentControlRange->getText();
+ uno::Reference<container::XEnumerationAccess> xContentEnumAccess(xText, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xContentEnum = xContentEnumAccess->createEnumeration();
+ uno::Reference<beans::XPropertySet> xContent(xContentEnum->nextElement(), uno::UNO_QUERY);
+ float fCharheight{};
+ xContent->getPropertyValue("CharHeight") >>= fCharheight;
+ CPPUNIT_ASSERT_EQUAL(12.f, fCharheight);
+ xContent.set(xContentEnum->nextElement(), uno::UNO_QUERY);
+ xContent->getPropertyValue("CharHeight") >>= fCharheight;
+ CPPUNIT_ASSERT_EQUAL(24.f, fCharheight);
+ uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY);
+ OUString aAlias;
+ xContentControlProps->getPropertyValue("Alias") >>= aAlias;
+ // This was empty.
+ CPPUNIT_ASSERT_EQUAL(OUString("myalias"), aAlias);
+ OUString aTag;
+ xContentControlProps->getPropertyValue("Tag") >>= aTag;
+ // This was empty.
+ CPPUNIT_ASSERT_EQUAL(OUString("mytag"), aTag);
+ sal_Int32 nId = 0;
+ xContentControlProps->getPropertyValue("Id") >>= nId;
+ // This was 0.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2147483647), nId);
+ sal_uInt32 nTabIndex = 0;
+ xContentControlProps->getPropertyValue("TabIndex") >>= nTabIndex;
+ // This was 0
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(4294967295), nTabIndex);
+ OUString aLock;
+ xContentControlProps->getPropertyValue("Lock") >>= aLock;
+ // This was empty.
+ CPPUNIT_ASSERT_EQUAL(OUString("contentLocked"), aLock);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunPlainText)
+{
+ // Given a document with a plain text inline/run SDT:
+ loadFromFile(u"sdt-run-plain-text.docx");
+
+ // Then make sure that the text inside the SDT is not rich:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPara->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ OUString aTextPortionType;
+ xPortion->getPropertyValue("TextPortionType") >>= aTextPortionType;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: ContentControl
+ // - Actual : TextField
+ // i.e. the SDT was imported as a text field, not as a content control.
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aTextPortionType);
+ uno::Reference<beans::XPropertySet> xContentControl;
+ xPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ bool bPlainText{};
+ xContentControl->getPropertyValue("PlainText") >>= bPlainText;
+ CPPUNIT_ASSERT(bPlainText);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunCheckbox)
+{
+ // Given a document with a checkbox inline/run SDT:
+ loadFromFile(u"sdt-run-checkbox.docx");
+
+ // Then make sure that the doc model has a clickable checkbox content control:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPara->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ OUString aTextPortionType;
+ xPortion->getPropertyValue("TextPortionType") >>= aTextPortionType;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: ContentControl
+ // - Actual : Text
+ // i.e. the SDT was imported as plain text, making it hard to fill in checkboxes.
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aTextPortionType);
+ uno::Reference<text::XTextContent> xContentControl;
+ xPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY);
+ bool bCheckbox{};
+ xContentControlProps->getPropertyValue("Checkbox") >>= bCheckbox;
+ CPPUNIT_ASSERT(bCheckbox);
+ bool bChecked{};
+ xContentControlProps->getPropertyValue("Checked") >>= bChecked;
+ CPPUNIT_ASSERT(bChecked);
+ OUString aCheckedState;
+ xContentControlProps->getPropertyValue("CheckedState") >>= aCheckedState;
+ CPPUNIT_ASSERT_EQUAL(u"☒"_ustr, aCheckedState);
+ OUString aUncheckedState;
+ xContentControlProps->getPropertyValue("UncheckedState") >>= aUncheckedState;
+ CPPUNIT_ASSERT_EQUAL(u"☐"_ustr, aUncheckedState);
+ uno::Reference<text::XTextRange> xContentControlRange(xContentControl, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xContentControlRange->getText();
+ uno::Reference<container::XEnumerationAccess> xContentEnumAccess(xText, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xContentEnum = xContentEnumAccess->createEnumeration();
+ uno::Reference<text::XTextRange> xContent(xContentEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(u"☒"_ustr, xContent->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunDropdown)
+{
+ // Given a document with a dropdown inline/run SDT:
+ loadFromFile(u"sdt-run-dropdown.docx");
+
+ // Then make sure that the doc model has a clickable dropdown content control:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xParagraphsAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration();
+ uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY);
+ OUString aPortionType;
+ xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+ // Without the accompanying fix in place, this failed with:
+ // - Expected: ContentControl
+ // - Actual : TextField
+ // i.e. the SDT was imported as a dropdown field, which does not support display-text + value
+ // pairs.
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+ uno::Reference<text::XTextContent> xContentControl;
+ xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValues> aListItems;
+ xContentControlProps->getPropertyValue("ListItems") >>= aListItems;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), aListItems.getLength());
+ comphelper::SequenceAsHashMap aMap0(aListItems[0]);
+ CPPUNIT_ASSERT_EQUAL(OUString("red"), aMap0["DisplayText"].get<OUString>());
+ CPPUNIT_ASSERT_EQUAL(OUString("R"), aMap0["Value"].get<OUString>());
+ comphelper::SequenceAsHashMap aMap1(aListItems[1]);
+ CPPUNIT_ASSERT_EQUAL(OUString("green"), aMap1["DisplayText"].get<OUString>());
+ CPPUNIT_ASSERT_EQUAL(OUString("G"), aMap1["Value"].get<OUString>());
+ comphelper::SequenceAsHashMap aMap2(aListItems[2]);
+ CPPUNIT_ASSERT_EQUAL(OUString("blue"), aMap2["DisplayText"].get<OUString>());
+ CPPUNIT_ASSERT_EQUAL(OUString("B"), aMap2["Value"].get<OUString>());
+ uno::Reference<text::XTextRange> xContentControlRange(xContentControl, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xContentControlRange->getText();
+ uno::Reference<container::XEnumerationAccess> xContentEnumAccess(xText, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xContentEnum = xContentEnumAccess->createEnumeration();
+ uno::Reference<text::XTextRange> xContent(xContentEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("choose a color"), xContent->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunComboBox)
+{
+ // Given a document with a combo box inline/run SDT:
+ loadFromFile(u"sdt-run-combobox.docx");
+
+ // Then make sure that the doc model has a clickable combo box content control:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xParagraphsAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration();
+ uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY);
+ OUString aPortionType;
+ xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+ uno::Reference<text::XTextContent> xContentControl;
+ xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY);
+ bool bComboBox{};
+ xContentControlProps->getPropertyValue("ComboBox") >>= bComboBox;
+ // Without the accompanying fix in place, this failed as the content control was a drop-down,
+ // not a combo box.
+ CPPUNIT_ASSERT(bComboBox);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunPicture)
+{
+ // Given a document with a dropdown inline/run SDT:
+ loadFromFile(u"sdt-run-picture.docx");
+
+ // Then make sure that the doc model has a clickable picture content control:
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xParagraphsAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration();
+ uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY);
+ OUString aPortionType;
+ xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+ // Without the accompanying fix in place, this failed with:
+ // - Expected: ContentControl
+ // - Actual : Frame
+ // i.e. the SDT was imported as a plain image, not as a clickable placeholder in a content
+ // control.
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+ uno::Reference<text::XTextContent> xContentControl;
+ xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY);
+ bool bPicture{};
+ xContentControlProps->getPropertyValue("Picture") >>= bPicture;
+ CPPUNIT_ASSERT(bPicture);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/SettingsTable.cxx b/sw/qa/writerfilter/cppunittests/dmapper/SettingsTable.cxx
new file mode 100644
index 000000000000..f8305efb5315
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/SettingsTable.cxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapixml_test.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/qa/XDumper.hpp>
+
+#include <test/xmldocptr.hxx>
+
+using namespace com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/dmapper/SettingsTable.cxx.
+class Test : public UnoApiXmlTest
+{
+public:
+ Test()
+ : UnoApiXmlTest("/sw/qa/writerfilter/cppunittests/dmapper/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testDoNotBreakWrappedTables)
+{
+ // Given a document with <w:doNotBreakWrappedTables>:
+ // When importing that document:
+ loadFromFile(u"do-not-break-wrapped-tables.docx");
+
+ // Then make sure that the matching compat flag is set:
+ uno::Reference<lang::XMultiServiceFactory> xDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xSettings(
+ xDocument->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
+ bool bDoNotBreakWrappedTables{};
+ xSettings->getPropertyValue("DoNotBreakWrappedTables") >>= bDoNotBreakWrappedTables;
+ // Without the accompanying fix in place, this test would have failed, the compat flag was not
+ // set.
+ CPPUNIT_ASSERT(bDoNotBreakWrappedTables);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testAllowTextAfterFloatingTableBreak)
+{
+ // Given a document with <w:compatSetting w:name="allowTextAfterFloatingTableBreak">:
+ // When importing that document:
+ loadFromFile(u"floattable-wrap-on-all-pages.docx");
+
+ // Then make sure that the matching compat flag is set:
+ uno::Reference<lang::XMultiServiceFactory> xDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xSettings(
+ xDocument->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
+ bool bAllowTextAfterFloatingTableBreak{};
+ xSettings->getPropertyValue("AllowTextAfterFloatingTableBreak")
+ >>= bAllowTextAfterFloatingTableBreak;
+ // Without the accompanying fix in place, this test would have failed, the compat flag was not
+ // set.
+ CPPUNIT_ASSERT(bAllowTextAfterFloatingTableBreak);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testAddVerticalFrameOffsetsRTF)
+{
+ // Given a document with a floating table, immediately followed by an inline table:
+ // When importing that document:
+ loadFromFile(u"floattable-vertical-frame-offset.rtf");
+
+ // Then make sure the floating and the inline tables don't overlap:
+ uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+ css::uno::Reference<qa::XDumper> xDumper(xModel->getCurrentController(), uno::UNO_QUERY);
+ OString aDump = xDumper->dump("layout").toUtf8();
+ auto pCharBuffer = reinterpret_cast<const xmlChar*>(aDump.getStr());
+ xmlDocUniquePtr pXmlDoc(xmlParseDoc(pCharBuffer));
+ sal_Int32 nFlyBottom = getXPath(pXmlDoc, "//fly/infos/bounds"_ostr, "bottom"_ostr).toInt32();
+ sal_Int32 nTableFrameTop
+ = getXPath(pXmlDoc, "//body/tab/infos/bounds"_ostr, "top"_ostr).toInt32();
+ sal_Int32 nTableTopMargin
+ = getXPath(pXmlDoc, "//body/tab/infos/prtBounds"_ostr, "top"_ostr).toInt32();
+ sal_Int32 nTableTop = nTableFrameTop + nTableTopMargin;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected greater than: 2747
+ // - Actual : 1449
+ // i.e. table top should be ~2748, but was less, leading to an overlap.
+ CPPUNIT_ASSERT_GREATER(nFlyBottom, nTableTop);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/TableManager.cxx b/sw/qa/writerfilter/cppunittests/dmapper/TableManager.cxx
new file mode 100644
index 000000000000..45dc968c0f22
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/TableManager.cxx
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapi_test.hxx>
+
+#include <com/sun/star/text/XTextFramesSupplier.hpp>
+
+using namespace com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/dmapper/TableManager.cxx.
+class Test : public UnoApiTest
+{
+public:
+ Test()
+ : UnoApiTest("/sw/qa/writerfilter/cppunittests/dmapper/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testFloattableNestedCellStartDOCXImport)
+{
+ // Given a document with a nested floating table at cell start and an other inner floating table:
+ // When importing that document:
+ loadFromFile(u"floattable-nested-cellstart.docx");
+
+ // Then make sure that both inner tables are floating:
+ uno::Reference<text::XTextFramesSupplier> xFramesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xFrames(xFramesSupplier->getTextFrames(),
+ uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2
+ // - Actual : 1
+ // i.e. the first inner table was not floating.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xFrames->getCount());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/TextEffectsHandler.cxx b/sw/qa/writerfilter/cppunittests/dmapper/TextEffectsHandler.cxx
new file mode 100644
index 000000000000..c14496179dc6
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/TextEffectsHandler.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapi_test.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/dmapper/TextEffectsHandler.cxx.
+class Test : public UnoApiTest
+{
+public:
+ Test()
+ : UnoApiTest("/sw/qa/writerfilter/cppunittests/dmapper/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testSemiTransparentText)
+{
+ // Load a document with a single paragraph: second text portion has semi-transparent text.
+ loadFromFile(u"semi-transparent-text.docx");
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPara->createEnumeration();
+ xPortionEnum->nextElement();
+ uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ sal_Int16 nCharTransparence = 0;
+ xPortion->getPropertyValue("CharTransparence") >>= nCharTransparence;
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 74
+ // - Actual : 0
+ // i.e. text was imported as regular text with solid color only.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(74), nCharTransparence);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testThemeColorTransparency)
+{
+ // Load a document with a single paragraph. It has semi-transparent text and the color is
+ // determined by a w14:schemeClr element.
+ loadFromFile(u"tdf152884_Char_Transparency.docx");
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPara->createEnumeration();
+ sal_Int16 nCharTransparence = 0;
+ uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ xPortion->getPropertyValue("CharTransparence") >>= nCharTransparence;
+ // Without the fix this test would have failed with: Expected 74, Actual 0
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(74), nCharTransparence);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/1cell-insidev-rightborder.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/1cell-insidev-rightborder.docx
new file mode 100644
index 000000000000..d0bc40e23ba1
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/1cell-insidev-rightborder.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/alt-chunk.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/alt-chunk.docx
new file mode 100644
index 000000000000..40d071ff40a6
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/alt-chunk.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/chart-zorder.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/chart-zorder.docx
new file mode 100644
index 000000000000..e022a3bde266
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/chart-zorder.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/clearing-break.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/clearing-break.docx
new file mode 100644
index 000000000000..453a4c2b83d1
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/clearing-break.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/content-control-data-binding-color.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/content-control-data-binding-color.docx
new file mode 100644
index 000000000000..0aae9439209b
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/content-control-data-binding-color.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/content-control-date-data-binding.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/content-control-date-data-binding.docx
new file mode 100644
index 000000000000..9ad644ef642c
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/content-control-date-data-binding.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/create-date-preserve.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/create-date-preserve.docx
new file mode 100644
index 000000000000..4a587ce0d2ef
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/create-date-preserve.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/do-not-break-wrapped-tables.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/do-not-break-wrapped-tables.docx
new file mode 100644
index 000000000000..088c056f3511
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/do-not-break-wrapped-tables.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/draw-shape-inline-effect.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/draw-shape-inline-effect.docx
new file mode 100644
index 000000000000..3eb5b0e2f448
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/draw-shape-inline-effect.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/fdo78333-1-minimized.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/fdo78333-1-minimized.docx
new file mode 100644
index 000000000000..0c4a5bc67288
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/fdo78333-1-minimized.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/field-if-inside-if.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/field-if-inside-if.docx
new file mode 100644
index 000000000000..65e238869b1b
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/field-if-inside-if.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-header.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-header.docx
new file mode 100644
index 000000000000..3840b2550d5b
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-header.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-section-break.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-section-break.docx
new file mode 100644
index 000000000000..e5c0cb19b342
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-section-break.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-break-before.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-break-before.docx
new file mode 100644
index 000000000000..7fcfed4a637d
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-break-before.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-footnote-redline.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-footnote-redline.docx
new file mode 100644
index 000000000000..10904ce43eb5
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-footnote-redline.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header-overlap.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header-overlap.docx
new file mode 100644
index 000000000000..1230b9f4e07c
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header-overlap.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header.docx
new file mode 100644
index 000000000000..1042dfc0616d
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-hidden-anchor.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-hidden-anchor.docx
new file mode 100644
index 000000000000..08816aacc47e
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-hidden-anchor.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-3tables.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-3tables.docx
new file mode 100644
index 000000000000..f171a1150695
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-3tables.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-cellstart.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-cellstart.docx
new file mode 100644
index 000000000000..837d539bb984
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-cellstart.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested.docx
new file mode 100644
index 000000000000..655e6c0e0bad
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-outer-nonsplit-inner.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-outer-nonsplit-inner.docx
new file mode 100644
index 000000000000..dc213b1b0d26
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-outer-nonsplit-inner.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-sectend.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-sectend.docx
new file mode 100644
index 000000000000..50a121412d10
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-sectend.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-tbl-overlap.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-tbl-overlap.docx
new file mode 100644
index 000000000000..b5b23931a240
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-tbl-overlap.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-then-table.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-then-table.docx
new file mode 100644
index 000000000000..134473c46012
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-then-table.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-vertical-frame-offset.rtf b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-vertical-frame-offset.rtf
new file mode 100644
index 000000000000..a7f8c45e83c8
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-vertical-frame-offset.rtf
@@ -0,0 +1,43 @@
+{\rtf1
+\paperw11907\paperh16840\margl567\margr397\margt567\margb397
+\pard\plain\par
+\par
+\trowd
+\trgaph70\trrh1315\trleft-70\tpvpara\tphmrg\tposx211\tposnegy-16\trautofit1\tblind0\tblindtype3 \clvertalt\clbrdrt
+\brdrs\brdrw30 \clbrdrl\brdrs\brdrw30 \clbrdrb\brdrs\brdrw30 \clbrdrr\brdrtbl \cltxlrtb\clshdrawnil \cellx2694
+\cellx4678\pard \ltrpar\ql \li0\ri0\widctlpar\intbl\pvpara\phmrg\posx211\posnegy-16\dxfrtext141\dfrmtxtx141\dfrmtxty0\wraparound\faauto\adjustright\rin0\lin0\pararsid5002879
+{\rtlch\fcs1 \ab\af1 \ltrch\fcs0
+\b\fs14\lang1053\langfe1033\langnp1053\insrsid1249889 Table1:A1}
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \fs14\lang1053\langfe1033\langnp1053\insrsid1249889 \cell }
+\pard \ltrpar\ql \li0\ri0\widctlpar\intbl
+\tx2694\pvpara\phmrg\posx211\posnegy-16\dxfrtext141\dfrmtxtx141\dfrmtxty0\wraparound\faauto\adjustright\rin0\lin0\pararsid935586
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \fs14\insrsid1249889 Table1:B1}
+{\rtlch\fcs1 \af1\afs4 \ltrch\fcs0
+\fs14\lang1053\langfe1033\langnp1053\insrsid1249889 \cell }
+\pard \ltrpar\ql \li0\ri0\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1053\langfe1033\langnp1053\insrsid1249889\charrsid15953318
+\trowd \irow0\irowband0\lastrow \ltrrow\ts11\trgaph70\trrh1315\trleft-70\tpvpara\tphmrg\tposx211\tposnegy-16\trautofit1\trpaddl70\trpaddr70\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblrsid5002879
+\tblind0\tblindtype3\cltxlrtb\clshdrawnil \cellx2694\clvertalt\clbrdrt\brdrs\brdrw30 \clbrdrl\brdrtbl \clbrdrb\brdrs\brdrw30 \clbrdrr
+\brdrtbl \cltxlrtb\clshdrawnil \cellx4678\row }
+\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\adjustright\rin0\lin0\itap0
+{\rtlch\fcs1 \af1\afs4 \ltrch\fcs0 \fs4\lang1053\langfe1033\langnp1053\insrsid16530204
+\par \ltrrow}
+\trowd \irow0\irowband0\lastrow \ltrrow\trqc\trgaph108\trrh-609\trleft-57\trkeep\trbrdrt\brdrs\brdrw10
+\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblrsid1533051\tbllkhdrrows\tbllklastrow\tbllkhdrcols\tbllklastcol\tblind0\tblindtype3 \clvertalc\clbrdrt\brdrs\brdrw30 \clbrdrl\brdrs\brdrw30
+\clbrdrb\brdrs\brdrw30 \clbrdrr\brdrnone \cltxlrtb\clpadt57\clpadr57\clpadft3\clpadfr3\clshdrawnil \cellx1303\clvertalc\clbrdrt\brdrs\brdrw30 \clbrdrl\brdrnone \clbrdrb\brdrs\brdrw30 \clbrdrr\brdrs\brdrw30
+\cltxlrtb\clpadt57\clpadr57\clpadft3\clpadfr3\clshdrawnil \cellx7294\pard \ltrpar\ql \li0\ri0\widctlpar\intbl\wrapdefault\faauto\adjustright\rin0\lin0
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid1533051 Table2:A1}
+{\rtlch\fcs1 \af1
+\ltrch\fcs0 \fs18\insrsid1533051 \cell }
+{\rtlch\fcs1 \ab\af1 \ltrch\fcs0 \b\fs14\insrsid1533051 Table2:B1}
+{\rtlch\fcs1 \ab\af1\afs18 \ltrch\fcs0 \b\fs14\insrsid1533051 \cell }
+\pard \ltrpar
+\ql \li0\ri0\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+{\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid1533051 \trowd \irow0\irowband0\lastrow \ltrrow\ts11\trqc\trgaph108\trrh-609\trleft-57\trkeep\trbrdrt\brdrs\brdrw10 \trbrdrl
+\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10
+\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblrsid1533051\tbllkhdrrows\tbllklastrow\tbllkhdrcols\tbllklastcol\tblind0\tblindtype3 \clvertalc\clbrdrt\brdrs\brdrw30 \clbrdrl\brdrs\brdrw30
+\clbrdrb\brdrs\brdrw30 \clbrdrr\brdrnone \cltxlrtb\clpadt57\clpadr57\clpadft3\clpadfr3\clshdrawnil \cellx1303\clvertalc\clbrdrt\brdrs\brdrw30 \clbrdrl\brdrnone \clbrdrb\brdrs\brdrw30 \clbrdrr\brdrs\brdrw30
+\cltxlrtb\clpadt57\clpadr57\clpadft3\clpadfr3\clshdrawnil \cellx7294\row }
+\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\adjustright\rin0\lin0\itap0
+\par
+}
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-wrap-on-all-pages.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-wrap-on-all-pages.docx
new file mode 100644
index 000000000000..91d6686a365e
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-wrap-on-all-pages.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/follow-page-top-margin.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/follow-page-top-margin.docx
new file mode 100644
index 000000000000..ceae0b784e18
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/follow-page-top-margin.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/frame-direction.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/frame-direction.docx
new file mode 100644
index 000000000000..33f191e80350
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/frame-direction.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/group-shape-rotation.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/group-shape-rotation.docx
new file mode 100644
index 000000000000..c9fee726bb89
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/group-shape-rotation.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/inline-anchored-zorder.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/inline-anchored-zorder.docx
new file mode 100644
index 000000000000..93932c4703b7
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/inline-anchored-zorder.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/inline-inshape-anchored-zorder.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/inline-inshape-anchored-zorder.docx
new file mode 100644
index 000000000000..3792285f4849
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/inline-inshape-anchored-zorder.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/large-para-top-margin.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/large-para-top-margin.docx
new file mode 100644
index 000000000000..34f24a3e2a12
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/large-para-top-margin.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/layout-in-cell-2.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/layout-in-cell-2.docx
new file mode 100644
index 000000000000..5b6926460c80
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/layout-in-cell-2.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/layout-in-cell-wrapnone-column.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/layout-in-cell-wrapnone-column.docx
new file mode 100644
index 000000000000..d88761421154
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/layout-in-cell-wrapnone-column.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border-no-margin.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border-no-margin.docx
new file mode 100644
index 000000000000..8bd464a9ea6c
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border-no-margin.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border.docx
new file mode 100644
index 000000000000..878ba1e7899b
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/nested-floating-table.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/nested-floating-table.docx
new file mode 100644
index 000000000000..73fd922fccd5
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/nested-floating-table.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/num-restart-style-parent.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/num-restart-style-parent.docx
new file mode 100644
index 000000000000..f908d94b56fe
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/num-restart-style-parent.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/page-break-footer-table.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/page-break-footer-table.docx
new file mode 100644
index 000000000000..376a1fb1e483
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/page-break-footer-table.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/paste-ole.rtf b/sw/qa/writerfilter/cppunittests/dmapper/data/paste-ole.rtf
new file mode 100644
index 000000000000..27ce59baa50b
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/paste-ole.rtf
@@ -0,0 +1,30 @@
+{\rtf1
+\pard\plain\par
+\pard\plain
+{\object\objemb\objw1287\objh832\objscalex100\objscaley99
+{\*\objclass Package}
+{\*\objdata 0105000002000000080000005061636b616765000000000000000000eb010000
+020030322e73766700443a5c446e445c54657374646174656e5c416c6c654461746569547970656e5c30322e737667000000030036000000443a5c54454d505c7b42433241443335362d363732422d344345302d394136342d3033373544464134324334377d5c30322e73766700ab0000003c7376672076657273696f6e
+3d22312e31222076696577426f783d223020302034342032362220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667223e0a203c7265637420783d222e352220793d222e35222077696474683d22343322206865696768743d223235222072783d2232222072793d2232222066696c6c3d
+222366666622207374726f6b653d2223303037616666222f3e0a3c2f7376673e0a3500000044003a005c00540045004d0050005c007b00420043003200410044003300350036002d0036003700320042002d0034004300450030002d0039004100360034002d003000330037003500440046004100340032004300340037
+007d005c00300032002e0073007600670006000000300032002e007300760067002600000044003a005c0044006e0044005c00540065007300740064006100740065006e005c0041006c006c0065004400610074006500690054007900700065006e005c00300032002e007300760067000105000000000000}
+{\result
+{\*\shppict
+{\pict
+\picscalex100\picscaley99\picw2270\pich1468\picwgoal1287\pichgoal832\emfblip
+010000006c00000000000000000000009500000095000000000000000000
+0000670f0000630f000020454d4600000100280100000700000002000000
+00000000000000000000000038070000bd030000e9010000fd0000000000
+00000000000000000000f675070016dd0300210000000800000062000000
+0c0000000100000027000000180000000100000000000000ff0000000000
+000047000000700000000000000000000000950000009500000050000000
+010000002000000001000000030000003000000000000000000000009600
+000096000000320000000000000064000000320000000000000032000000
+960000006400000032000000640000006400000096000000220000000c00
+0000ffffffff0e00000014000000000000001000000014000000}
+}
+}
+}
+\pard\plain\par
+\pard\plain hello\par
+}
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/ptab.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/ptab.docx
new file mode 100644
index 000000000000..d1ae18a27a55
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/ptab.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/redlined-shape-sdt.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/redlined-shape-sdt.docx
new file mode 100644
index 000000000000..ea7f4a5bd664
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/redlined-shape-sdt.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/relfromh-insidemargin.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/relfromh-insidemargin.docx
new file mode 100644
index 000000000000..1f7a281e8b63
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/relfromh-insidemargin.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-block-text.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-block-text.docx
new file mode 100644
index 000000000000..2dfbc4a3284a
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-block-text.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-dropdown-no-display-text.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-dropdown-no-display-text.docx
new file mode 100644
index 000000000000..ed6d7ac54052
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-dropdown-no-display-text.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-checkbox.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-checkbox.docx
new file mode 100644
index 000000000000..c6718b97c2a0
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-checkbox.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-combobox.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-combobox.docx
new file mode 100644
index 000000000000..2ae80047cc1b
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-combobox.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-dropdown.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-dropdown.docx
new file mode 100644
index 000000000000..7718c0b04daa
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-dropdown.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-in-para.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-in-para.docx
new file mode 100644
index 000000000000..863bc9213b5b
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-in-para.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-picture.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-picture.docx
new file mode 100644
index 000000000000..25fcc7f6f8f9
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-picture.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-plain-text.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-plain-text.docx
new file mode 100644
index 000000000000..127d81fd966b
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-plain-text.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-rich-text.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-rich-text.docx
new file mode 100644
index 000000000000..0d1004ef8a6e
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-rich-text.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/semi-transparent-text.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/semi-transparent-text.docx
new file mode 100644
index 000000000000..6c0f8a79cbb4
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/semi-transparent-text.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/table-negative-vertical-pos.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/table-negative-vertical-pos.docx
new file mode 100644
index 000000000000..2031f4769877
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/table-negative-vertical-pos.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf129205.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf129205.docx
new file mode 100644
index 000000000000..4289254d0a97
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf129205.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540ChildRotation.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540ChildRotation.docx
new file mode 100644
index 000000000000..902bb6192afe
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540ChildRotation.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupLinePosSize.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupLinePosSize.docx
new file mode 100644
index 000000000000..d0ceff118eab
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupLinePosSize.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupRotation.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupRotation.docx
new file mode 100644
index 000000000000..13e65c1d122a
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupRotation.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142304GroupPosition.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142304GroupPosition.docx
new file mode 100644
index 000000000000..681a6e3b7943
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142304GroupPosition.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305SquareWrapMargin.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305SquareWrapMargin.docx
new file mode 100644
index 000000000000..9a0fc8a2b5c1
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305SquareWrapMargin.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305StrokeGlowMargin.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305StrokeGlowMargin.docx
new file mode 100644
index 000000000000..3adc2d91b6f1
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305StrokeGlowMargin.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143208_wrapTight.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143208_wrapTight.docx
new file mode 100644
index 000000000000..fab911ad902e
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143208_wrapTight.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143455_SmartArtPosition.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143455_SmartArtPosition.docx
new file mode 100644
index 000000000000..1b1881b1e9ef
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143455_SmartArtPosition.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf149840_SmartArtBackground.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf149840_SmartArtBackground.docx
new file mode 100644
index 000000000000..318cef8f3c4b
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf149840_SmartArtBackground.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf152884_Char_Transparency.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf152884_Char_Transparency.docx
new file mode 100644
index 000000000000..e1603956948f
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf152884_Char_Transparency.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf158360.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf158360.docx
new file mode 100644
index 000000000000..a46ee67c007e
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf158360.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline-top.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline-top.docx
new file mode 100644
index 000000000000..dbd750092811
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline-top.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline.docx
new file mode 100644
index 000000000000..493604d778e9
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline.docx
Binary files differ
diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/wrap-poly-crop.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/wrap-poly-crop.docx
new file mode 100644
index 000000000000..1835a130d740
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/dmapper/data/wrap-poly-crop.docx
Binary files differ