diff options
Diffstat (limited to 'sw/qa/writerfilter/cppunittests/dmapper')
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 Binary files differnew file mode 100644 index 000000000000..d0bc40e23ba1 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/1cell-insidev-rightborder.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/alt-chunk.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/alt-chunk.docx Binary files differnew file mode 100644 index 000000000000..40d071ff40a6 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/alt-chunk.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/chart-zorder.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/chart-zorder.docx Binary files differnew file mode 100644 index 000000000000..e022a3bde266 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/chart-zorder.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/clearing-break.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/clearing-break.docx Binary files differnew file mode 100644 index 000000000000..453a4c2b83d1 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/clearing-break.docx 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 Binary files differnew file mode 100644 index 000000000000..0aae9439209b --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/content-control-data-binding-color.docx 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 Binary files differnew file mode 100644 index 000000000000..9ad644ef642c --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/content-control-date-data-binding.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/create-date-preserve.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/create-date-preserve.docx Binary files differnew file mode 100644 index 000000000000..4a587ce0d2ef --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/create-date-preserve.docx 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 Binary files differnew file mode 100644 index 000000000000..088c056f3511 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/do-not-break-wrapped-tables.docx 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 Binary files differnew file mode 100644 index 000000000000..3eb5b0e2f448 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/draw-shape-inline-effect.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/fdo78333-1-minimized.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/fdo78333-1-minimized.docx Binary files differnew file mode 100644 index 000000000000..0c4a5bc67288 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/fdo78333-1-minimized.docx 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 Binary files differnew file mode 100644 index 000000000000..65e238869b1b --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/field-if-inside-if.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-header.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-header.docx Binary files differnew file mode 100644 index 000000000000..3840b2550d5b --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-header.docx 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 Binary files differnew file mode 100644 index 000000000000..e5c0cb19b342 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floating-table-section-break.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-break-before.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-break-before.docx Binary files differnew file mode 100644 index 000000000000..7fcfed4a637d --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-break-before.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-footnote-redline.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-footnote-redline.docx Binary files differnew file mode 100644 index 000000000000..10904ce43eb5 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-footnote-redline.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header-overlap.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header-overlap.docx Binary files differnew file mode 100644 index 000000000000..1230b9f4e07c --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header-overlap.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header.docx Binary files differnew file mode 100644 index 000000000000..1042dfc0616d --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-header.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-hidden-anchor.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-hidden-anchor.docx Binary files differnew file mode 100644 index 000000000000..08816aacc47e --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-hidden-anchor.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-3tables.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-3tables.docx Binary files differnew file mode 100644 index 000000000000..f171a1150695 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-3tables.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-cellstart.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-cellstart.docx Binary files differnew file mode 100644 index 000000000000..837d539bb984 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested-cellstart.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested.docx Binary files differnew file mode 100644 index 000000000000..655e6c0e0bad --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-nested.docx 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 Binary files differnew file mode 100644 index 000000000000..dc213b1b0d26 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-outer-nonsplit-inner.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-sectend.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-sectend.docx Binary files differnew file mode 100644 index 000000000000..50a121412d10 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-sectend.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-tbl-overlap.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-tbl-overlap.docx Binary files differnew file mode 100644 index 000000000000..b5b23931a240 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-tbl-overlap.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-then-table.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-then-table.docx Binary files differnew file mode 100644 index 000000000000..134473c46012 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-then-table.docx 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 Binary files differnew file mode 100644 index 000000000000..91d6686a365e --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/floattable-wrap-on-all-pages.docx 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 Binary files differnew file mode 100644 index 000000000000..ceae0b784e18 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/follow-page-top-margin.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/frame-direction.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/frame-direction.docx Binary files differnew file mode 100644 index 000000000000..33f191e80350 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/frame-direction.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/group-shape-rotation.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/group-shape-rotation.docx Binary files differnew file mode 100644 index 000000000000..c9fee726bb89 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/group-shape-rotation.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/inline-anchored-zorder.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/inline-anchored-zorder.docx Binary files differnew file mode 100644 index 000000000000..93932c4703b7 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/inline-anchored-zorder.docx 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 Binary files differnew file mode 100644 index 000000000000..3792285f4849 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/inline-inshape-anchored-zorder.docx 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 Binary files differnew file mode 100644 index 000000000000..34f24a3e2a12 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/large-para-top-margin.docx 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 Binary files differnew file mode 100644 index 000000000000..5b6926460c80 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/layout-in-cell-2.docx 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 Binary files differnew file mode 100644 index 000000000000..d88761421154 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/layout-in-cell-wrapnone-column.docx 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 Binary files differnew file mode 100644 index 000000000000..8bd464a9ea6c --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border-no-margin.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border.docx Binary files differnew file mode 100644 index 000000000000..878ba1e7899b --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/negative-page-border.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/nested-floating-table.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/nested-floating-table.docx Binary files differnew file mode 100644 index 000000000000..73fd922fccd5 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/nested-floating-table.docx 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 Binary files differnew file mode 100644 index 000000000000..f908d94b56fe --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/num-restart-style-parent.docx 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 Binary files differnew file mode 100644 index 000000000000..376a1fb1e483 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/page-break-footer-table.docx 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 Binary files differnew file mode 100644 index 000000000000..d1ae18a27a55 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/ptab.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/redlined-shape-sdt.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/redlined-shape-sdt.docx Binary files differnew file mode 100644 index 000000000000..ea7f4a5bd664 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/redlined-shape-sdt.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/relfromh-insidemargin.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/relfromh-insidemargin.docx Binary files differnew file mode 100644 index 000000000000..1f7a281e8b63 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/relfromh-insidemargin.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-block-text.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-block-text.docx Binary files differnew file mode 100644 index 000000000000..2dfbc4a3284a --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-block-text.docx 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 Binary files differnew file mode 100644 index 000000000000..ed6d7ac54052 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-dropdown-no-display-text.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-checkbox.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-checkbox.docx Binary files differnew file mode 100644 index 000000000000..c6718b97c2a0 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-checkbox.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-combobox.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-combobox.docx Binary files differnew file mode 100644 index 000000000000..2ae80047cc1b --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-combobox.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-dropdown.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-dropdown.docx Binary files differnew file mode 100644 index 000000000000..7718c0b04daa --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-dropdown.docx 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 Binary files differnew file mode 100644 index 000000000000..863bc9213b5b --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-in-para.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-picture.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-picture.docx Binary files differnew file mode 100644 index 000000000000..25fcc7f6f8f9 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-picture.docx 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 Binary files differnew file mode 100644 index 000000000000..127d81fd966b --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-plain-text.docx 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 Binary files differnew file mode 100644 index 000000000000..0d1004ef8a6e --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/sdt-run-rich-text.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/semi-transparent-text.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/semi-transparent-text.docx Binary files differnew file mode 100644 index 000000000000..6c0f8a79cbb4 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/semi-transparent-text.docx 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 Binary files differnew file mode 100644 index 000000000000..2031f4769877 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/table-negative-vertical-pos.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf129205.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf129205.docx Binary files differnew file mode 100644 index 000000000000..4289254d0a97 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf129205.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540ChildRotation.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540ChildRotation.docx Binary files differnew file mode 100644 index 000000000000..902bb6192afe --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540ChildRotation.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupLinePosSize.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupLinePosSize.docx Binary files differnew file mode 100644 index 000000000000..d0ceff118eab --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupLinePosSize.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupRotation.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupRotation.docx Binary files differnew file mode 100644 index 000000000000..13e65c1d122a --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf141540GroupRotation.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142304GroupPosition.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142304GroupPosition.docx Binary files differnew file mode 100644 index 000000000000..681a6e3b7943 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142304GroupPosition.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305SquareWrapMargin.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305SquareWrapMargin.docx Binary files differnew file mode 100644 index 000000000000..9a0fc8a2b5c1 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305SquareWrapMargin.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305StrokeGlowMargin.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305StrokeGlowMargin.docx Binary files differnew file mode 100644 index 000000000000..3adc2d91b6f1 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf142305StrokeGlowMargin.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143208_wrapTight.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143208_wrapTight.docx Binary files differnew file mode 100644 index 000000000000..fab911ad902e --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143208_wrapTight.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143455_SmartArtPosition.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143455_SmartArtPosition.docx Binary files differnew file mode 100644 index 000000000000..1b1881b1e9ef --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf143455_SmartArtPosition.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf149840_SmartArtBackground.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf149840_SmartArtBackground.docx Binary files differnew file mode 100644 index 000000000000..318cef8f3c4b --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf149840_SmartArtBackground.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf152884_Char_Transparency.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf152884_Char_Transparency.docx Binary files differnew file mode 100644 index 000000000000..e1603956948f --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf152884_Char_Transparency.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/tdf158360.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf158360.docx Binary files differnew file mode 100644 index 000000000000..a46ee67c007e --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/tdf158360.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline-top.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline-top.docx Binary files differnew file mode 100644 index 000000000000..dbd750092811 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline-top.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline.docx Binary files differnew file mode 100644 index 000000000000..493604d778e9 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/textbox-textline.docx diff --git a/sw/qa/writerfilter/cppunittests/dmapper/data/wrap-poly-crop.docx b/sw/qa/writerfilter/cppunittests/dmapper/data/wrap-poly-crop.docx Binary files differnew file mode 100644 index 000000000000..1835a130d740 --- /dev/null +++ b/sw/qa/writerfilter/cppunittests/dmapper/data/wrap-poly-crop.docx |