diff --git a/sw/CppunitTest_sw_ooxmlexport19.mk b/sw/CppunitTest_sw_ooxmlexport19.mk new file mode 100644 index 000000000000..14e1f8815b26 --- /dev/null +++ b/sw/CppunitTest_sw_ooxmlexport19.mk @@ -0,0 +1,18 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# 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/. +# +#************************************************************************* + +$(eval $(call sw_ooxmlexport_test,19)) + +$(eval $(call gb_CppunitTest_use_custom_headers,sw_ooxmlexport19,\ + officecfg/registry \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk index cd1c3dbc31b4..5e62f4c1b1b7 100644 --- a/sw/Module_sw.mk +++ b/sw/Module_sw.mk @@ -92,6 +92,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\ CppunitTest_sw_ooxmlexport16 \ CppunitTest_sw_ooxmlexport17 \ CppunitTest_sw_ooxmlexport18 \ + CppunitTest_sw_ooxmlexport19 \ CppunitTest_sw_ooxmlexport_template \ CppunitTest_sw_ooxmlfieldexport \ CppunitTest_sw_ooxmllinks \ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx index 3065083f9254..4ed28d57f88d 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx @@ -13,37 +13,26 @@ #include #include #include +#include #include #include -#include #include #include -#include #include #include -#include -#include -#include #include #include +#include +#include +#include +#include #include +#include #include #include #include #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include class Test : public SwModelTestBase { @@ -729,761 +718,6 @@ DECLARE_OOXMLEXPORT_TEST(testGroupshapeTrackedchanges, "groupshape-trackedchange CPPUNIT_ASSERT_EQUAL(OUString(" Inserted"), getRun(xParagraph, 5)->getString()); } -DECLARE_OOXMLEXPORT_TEST(testFdo78939, "fdo78939.docx") -{ - // fdo#78939 : LO hanged while opening issue document - - // Whenever a para-style was applied to a Numbering format level, - // LO incorrectly also changed the para-style... - - // check that file opens and does not hang while opening and also - // check that an incorrect numbering style is not applied ... - CPPUNIT_ASSERT_EQUAL(OUString(), getProperty(getParagraph(1), "NumberingStyleName")); -} - -DECLARE_OOXMLEXPORT_TEST(testFootnote, "footnote.docx") -{ - uno::Reference xFootnotesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xFootnotes = xFootnotesSupplier->getFootnotes(); - uno::Reference xFootnote(xFootnotes->getByIndex(0), uno::UNO_QUERY); - OUString aFootnote = xFootnote->getString(); - // Ensure there are no additional newlines after "bar". - CPPUNIT_ASSERT(aFootnote.endsWith("bar")); -} - -DECLARE_OOXMLEXPORT_TEST(testTableBtlrCenter, "table-btlr-center.docx") -{ - // Note that this is btLr text, so layout and doc model horizontal/vertical is the opposite of - // each other. - uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); - uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); - uno::Reference xCell = xTable->getCellByName("A2"); - // Cell vertical alignment was CENTER, should be NONE. - CPPUNIT_ASSERT_EQUAL(text::VertOrientation::NONE, getProperty(xCell, "VertOrient")); - - // Cell horizontal alignment should be CENTER. - uno::Reference xCellText(xCell, uno::UNO_QUERY); - auto nActual = getProperty(getParagraphOfText(1, xCellText), "ParaAdjust"); - CPPUNIT_ASSERT_EQUAL(static_cast(style::ParagraphAdjust_CENTER), nActual); -} - -DECLARE_OOXMLEXPORT_TEST(testFdo80555, "fdo80555.docx") -{ - uno::Reference xShape = getShape(1); - // Shape was wrongly placed at X=0, Y=0 - CPPUNIT_ASSERT_EQUAL(sal_Int32(3318), xShape->getPosition().X); - CPPUNIT_ASSERT_EQUAL(sal_Int32(247), xShape->getPosition().Y); -} - -CPPUNIT_TEST_FIXTURE(Test, testTdf104418) -{ - loadAndReload("tdf104418.odt"); - // Problem was that cell property was ignored. - uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY); - uno::Reference xTextTable(xTables->getByIndex(0), uno::UNO_QUERY); - uno::Reference xTableRows = xTextTable->getRows(); - - // Without the fix in place, this test would have failed with - // - Expected: 750 - // - Actual : 1499 - CPPUNIT_ASSERT_EQUAL(sal_Int64(750) , getProperty(xTableRows->getByIndex(0), "Height")); -} - -DECLARE_OOXMLEXPORT_TEST(testHidemark, "hidemark.docx") -{ - // Problem was that cell property was ignored. - uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY); - uno::Reference xTextTable(xTables->getByIndex(0), uno::UNO_QUERY); - uno::Reference xTableRows = xTextTable->getRows(); - // Height should be minimal - CPPUNIT_ASSERT_EQUAL(convertTwipToMm100(MINLAY), getProperty(xTableRows->getByIndex(1), "Height")); - // Size type was MIN, should be FIX to avoid considering the end of paragraph marker. - CPPUNIT_ASSERT_EQUAL(text::SizeType::FIX, getProperty(xTableRows->getByIndex(1), "SizeType")); - - //tdf#104876: Width was not recognized during import when table size was 'auto' - CPPUNIT_ASSERT_MESSAGE("table size is less than 7000?",sal_Int32(7000) > getProperty(xTextTable, "Width")); -} - -DECLARE_OOXMLEXPORT_TEST(testHidemarkb, "tdf99616_hidemarkb.docx") -{ - // Problem was that the smallest possible height was forced, not the min specified size. - uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY); - uno::Reference xTextTable(xTables->getByIndex(0), uno::UNO_QUERY); - uno::Reference xTableRows = xTextTable->getRows(); - // Height should be .5cm - CPPUNIT_ASSERT_EQUAL(sal_Int64(501), getProperty(xTableRows->getByIndex(1), "Height")); - // Size type was MIN, should be FIX to avoid considering the end of paragraph marker. - CPPUNIT_ASSERT_EQUAL(text::SizeType::FIX, getProperty(xTableRows->getByIndex(1), "SizeType")); -} - -DECLARE_OOXMLEXPORT_TEST(testBnc891663, "bnc891663.docx") -{ - // The image should be inside a cell, so the text in the following cell should be below it. - int imageTop = parseDump("/root/page/body/tab/row[1]/cell[2]/txt[1]/anchored/fly/infos/bounds", "top").toInt32(); - int imageHeight = parseDump("/root/page/body/tab/row[1]/cell[2]/txt[1]/anchored/fly/infos/bounds", "height").toInt32(); - int textNextRowTop = parseDump("/root/page/body/tab/row[2]/cell[1]/txt[1]/infos/bounds", "top").toInt32(); - CPPUNIT_ASSERT( textNextRowTop >= imageTop + imageHeight ); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf123104, "tdf123104.docx") -{ - uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); - uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); - uno::Reference xCell = xTable->getCellByName("E1"); - // See SwXCell::getPropertyValue(), we really put 'long' into an Any there. - // Without the accompanying fix in place, this test would have failed with 'Expected: 3;Actual : - // 2', i.e. the vertical merge covered one less cell, resulting in a cell with white background. - CPPUNIT_ASSERT_EQUAL(static_cast(3), getProperty(xCell, "RowSpan")); -} - -DECLARE_OOXMLEXPORT_TEST(testFdo85542, "fdo85542.docx") -{ - uno::Reference xBookmarksSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(static_cast(3), xBookmarksByIdx->getCount()); - uno::Reference xBookmarksByName = xBookmarksSupplier->getBookmarks(); - CPPUNIT_ASSERT(xBookmarksByName->hasByName("B1")); - CPPUNIT_ASSERT(xBookmarksByName->hasByName("B2")); - CPPUNIT_ASSERT(xBookmarksByName->hasByName("B3")); - // B1 - uno::Reference xContent1(xBookmarksByName->getByName("B1"), uno::UNO_QUERY); - uno::Reference xRange1 = xContent1->getAnchor(); - CPPUNIT_ASSERT_EQUAL(OUString("ABB"), xRange1->getString()); - // B2 - uno::Reference xContent2(xBookmarksByName->getByName("B2"), uno::UNO_QUERY); - uno::Reference xRange2 = xContent2->getAnchor(); - CPPUNIT_ASSERT_EQUAL(OUString("BBC"), xRange2->getString()); - // B3 -- testing a collapsed bookmark - uno::Reference xContent3(xBookmarksByName->getByName("B3"), uno::UNO_QUERY); - uno::Reference xRange3 = xContent3->getAnchor(); - CPPUNIT_ASSERT_EQUAL(xRange3->getString(), OUString()); - uno::Reference xText = xRange3->getText( ); - uno::Reference xNeighborhoodCursor = xText->createTextCursor( ); - xNeighborhoodCursor->gotoRange(xRange3, false); - xNeighborhoodCursor->goLeft(1, false); - xNeighborhoodCursor->goRight(2, true); - CPPUNIT_ASSERT_EQUAL(OUString("AB"), xNeighborhoodCursor->getString()); -} - -CPPUNIT_TEST_FIXTURE(Test, testTdf65955) -{ - loadAndReload("tdf65955.odt"); - CPPUNIT_ASSERT_EQUAL(1, getPages()); - uno::Reference xBookmarksSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(static_cast(2), xBookmarksByIdx->getCount()); - uno::Reference xBookmarksByName = xBookmarksSupplier->getBookmarks(); - CPPUNIT_ASSERT(xBookmarksByName->hasByName("a")); - CPPUNIT_ASSERT(xBookmarksByName->hasByName("b")); - // a - uno::Reference xContent3(xBookmarksByName->getByName("a"), uno::UNO_QUERY); - uno::Reference xRange3 = xContent3->getAnchor(); - CPPUNIT_ASSERT_EQUAL(xRange3->getString(), OUString()); - // b - uno::Reference xContent2(xBookmarksByName->getByName("b"), uno::UNO_QUERY); - uno::Reference xRange2 = xContent2->getAnchor(); - CPPUNIT_ASSERT_EQUAL(OUString("r"), xRange2->getString()); -} - -CPPUNIT_TEST_FIXTURE(Test, testTdf65955_2) -{ - loadAndReload("tdf65955_2.odt"); - CPPUNIT_ASSERT_EQUAL(1, getPages()); - uno::Reference xBookmarksSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(static_cast(1), xBookmarksByIdx->getCount()); - uno::Reference xBookmarksByName = xBookmarksSupplier->getBookmarks(); - CPPUNIT_ASSERT(xBookmarksByName->hasByName("test")); - - uno::Reference xContent3(xBookmarksByName->getByName("test"), uno::UNO_QUERY); - uno::Reference xRange3 = xContent3->getAnchor(); - CPPUNIT_ASSERT_EQUAL(OUString("foo bar"), xRange3->getString()); -} - -DECLARE_OOXMLEXPORT_TEST(testChtOutlineNumberingOoxml, "chtoutline.docx") -{ - static constexpr OUStringLiteral aExpectedNumbering = u"\u7b2c 1 \u7ae0"; - - uno::Reference xPara(getParagraph(1), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(OUString(aExpectedNumbering), - getProperty(xPara, "ListLabelString")); -} - -DECLARE_OOXMLEXPORT_TEST(mathtype, "mathtype.docx") -{ - uno::Reference xTextEmbeddedObjectsSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xEmbeddedObjects(xTextEmbeddedObjectsSupplier->getEmbeddedObjects(), uno::UNO_QUERY); - // This failed as the Model property was empty. - auto xModel = getProperty< uno::Reference >(xEmbeddedObjects->getByIndex(0), "Model"); - CPPUNIT_ASSERT(xModel->supportsService("com.sun.star.formula.FormulaProperties")); -} - -CPPUNIT_TEST_FIXTURE(Test, testTdf8255) -{ - SwModelTestBase::FlySplitGuard aGuard; - auto verify = [this]() { - // A full-page-wide multi-page floating table should be allowed to split: - uno::Reference xDocument(mxComponent, uno::UNO_QUERY); - uno::Reference xFrame(xDocument->getTextFrames()->getByName("Frame1"), - uno::UNO_QUERY); - bool bIsSplitAllowed{}; - xFrame->getPropertyValue("IsSplitAllowed") >>= bIsSplitAllowed; - CPPUNIT_ASSERT(bIsSplitAllowed); - }; - createSwDoc("tdf8255.docx"); - verify(); - reload(mpFilter, "tdf8255.docx"); - verify(); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf87460, "tdf87460.docx") -{ - uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); - uno::Reference xEndnotesSupplier(xTextDocument, uno::UNO_QUERY); - uno::Reference xEndnotes = xEndnotesSupplier->getEndnotes(); - // This was 0: endnote was lost on import. - CPPUNIT_ASSERT_EQUAL(static_cast(1), xEndnotes->getCount()); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf90611, "tdf90611.docx") -{ - uno::Reference xFootnotesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xFootnotes = xFootnotesSupplier->getFootnotes(); - uno::Reference xFootnoteText; - xFootnotes->getByIndex(0) >>= xFootnoteText; - // This was 11. - CPPUNIT_ASSERT_EQUAL(10.f, getProperty(getParagraphOfText(1, xFootnoteText), "CharHeight")); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf89702, "tdf89702.docx") -{ - // Get the first paragraph's numbering style's 2nd level's character style name. - uno::Reference xParagraph = getParagraph(1); - auto xLevels = getProperty< uno::Reference >(xParagraph, "NumberingRules"); - uno::Sequence aLevel; - xLevels->getByIndex(1) >>= aLevel; // 2nd level - OUString aCharStyleName = std::find_if(std::cbegin(aLevel), std::cend(aLevel), [](const beans::PropertyValue& rValue) { return rValue.Name == "CharStyleName"; })->Value.get(); - - // Make sure that the font name is Arial, this was Verdana. - uno::Reference xStyle(getStyles("CharacterStyles")->getByName(aCharStyleName), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(OUString("Arial"), getProperty(xStyle, "CharFontName")); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf86374, "tdf86374.docx") -{ - uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); - uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); - uno::Reference xTableRows = xTable->getRows(); - // btLr text direction was imported as FIX, it should be MIN to have enough space for the additionally entered paragraphs. - CPPUNIT_ASSERT_EQUAL(text::SizeType::MIN, getProperty(xTableRows->getByIndex(0), "SizeType")); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf87924, "tdf87924.docx") -{ - uno::Reference xPropertySet(getShape(1), uno::UNO_QUERY); - comphelper::SequenceAsHashMap aGeometry(xPropertySet->getPropertyValue("CustomShapeGeometry")); - // This was -270, the text rotation angle was set when it should not be rotated. - CPPUNIT_ASSERT_EQUAL(static_cast(0), aGeometry["TextPreRotateAngle"].get()); -} - -DECLARE_OOXMLEXPORT_TEST(testIndents, "indents.docx") -{ - //expected left margin and first line indent values - static const sal_Int32 indents[] = - { - 0, 0, - -2000, 0, - -2000, 1000, - -1000, -1000, - 2000, -1000 - }; - uno::Reference textDocument(mxComponent, uno::UNO_QUERY); - uno::Reference xParaEnumAccess(textDocument->getText(), uno::UNO_QUERY); - // list of paragraphs - uno::Reference xParaEnum = xParaEnumAccess->createEnumeration(); - size_t paraIndex = 0; - do - { - uno::Reference xServiceInfo; - if (xParaEnum->nextElement() >>= xServiceInfo) - { - uno::Reference const xPropertySet(xServiceInfo, uno::UNO_QUERY_THROW); - sal_Int32 nIndent = 0; - sal_Int32 nFirstLine = 0; - xPropertySet->getPropertyValue("ParaLeftMargin") >>= nIndent; - xPropertySet->getPropertyValue("ParaFirstLineIndent") >>= nFirstLine; - CPPUNIT_ASSERT_EQUAL(indents[paraIndex * 2], nIndent); - CPPUNIT_ASSERT_EQUAL(indents[paraIndex * 2 + 1], nFirstLine); - ++paraIndex; - } - } while (xParaEnum->hasMoreElements()); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf92454, "tdf92454.docx") -{ - // The first paragraph had a large indentation / left margin as inheritance - // in Word and Writer works differently, and no direct value was set to be - // explicit. - uno::Reference xParagraph(getParagraph(1), uno::UNO_QUERY); - // This was beans::PropertyState_DEFAULT_VALUE. - CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, xParagraph->getPropertyState("ParaFirstLineIndent")); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf95377, "tdf95377.docx") -{ - uno::Reference xParagraph(getParagraph(1), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), getProperty(xParagraph, "ParaRightMargin")); - - xParagraph.set(getParagraph(2), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(sal_Int32(-501), getProperty(xParagraph, "ParaFirstLineIndent")); - CPPUNIT_ASSERT_EQUAL(sal_Int32(2501), getProperty(xParagraph, "ParaLeftMargin")); - CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, xParagraph->getPropertyState("ParaFirstLineIndent")); - - xParagraph.set(getParagraph(3), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(sal_Int32(-250), getProperty(xParagraph, "ParaFirstLineIndent")); - CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty(xParagraph, "ParaLeftMargin")); - CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, xParagraph->getPropertyState("ParaFirstLineIndent")); - - //default style has numbering enabled. Styles inherit numbering unless specifically disabled - xmlDocUniquePtr pXmlDoc = parseLayoutDump(); - assertXPath(pXmlDoc, "//body/txt/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", 3); //first three paragraphs have numbering - assertXPath(pXmlDoc, "//body/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", "expand", "a."); - assertXPath(pXmlDoc, "//body/txt[2]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", "expand", "b."); - assertXPath(pXmlDoc, "//body/txt[3]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", "expand", "c."); - assertXPath(pXmlDoc, "/root/page/body/txt[4]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", 0); //last paragraph style disables numbering -} - -DECLARE_OOXMLEXPORT_TEST(testTdf95376, "tdf95376.docx") -{ - uno::Reference xParagraph(getParagraph(2), uno::UNO_QUERY); - // This was beans::PropertyState_DIRECT_VALUE: indentation-from-numbering - // did not have priority over indentation-from-paragraph-style, due to a - // filter workaround that's not correct here. - CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DEFAULT_VALUE, xParagraph->getPropertyState("ParaFirstLineIndent")); - - //tdf#131321 - paragraph styles lost their numbering. Bullet+space inherits WWNum1 from Bullet - uno::Reference xStyle(getStyles("ParagraphStyles")->getByName("Bullet+space"), uno::UNO_QUERY); - CPPUNIT_ASSERT(!(getProperty(xStyle, "NumberingStyleName")).isEmpty()); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf92124, "tdf92124.docx") -{ - // Get the second paragraph's numbering style's 1st level's suffix. - uno::Reference xParagraph = getParagraph(2); - auto xLevels = getProperty< uno::Reference >(xParagraph, "NumberingRules"); - uno::Sequence aLevel; - xLevels->getByIndex(0) >>= aLevel; // 1st level - OUString aSuffix = std::find_if(std::cbegin(aLevel), std::cend(aLevel), [](const beans::PropertyValue& rValue) { return rValue.Name == "Suffix"; })->Value.get(); - // Make sure it's empty as the source document contains . - CPPUNIT_ASSERT(aSuffix.isEmpty()); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf90153, "tdf90153.docx") -{ - // This was at-para, so the line-level VertOrientRelation was lost, resulting in an incorrect vertical position. - CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, getProperty(getShape(1), "AnchorType")); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf93919, "tdf93919.docx") -{ - // This was 0, left margin was not inherited from the list style. - CPPUNIT_ASSERT_EQUAL(static_cast(1270), getProperty(getParagraph(1), "ParaLeftMargin")); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf91417, "tdf91417.docx") -{ - // The first paragraph should contain a link to "http://www.google.com/" - uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); - uno::Reference xTextCursor = xTextDocument->getText()->createTextCursor( ); - uno::Reference xCursorProps(xTextCursor, uno::UNO_QUERY); - OUString aValue; - xCursorProps->getPropertyValue("HyperLinkURL") >>= aValue; - CPPUNIT_ASSERT_EQUAL(OUString("http://www.google.com/"), aValue); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf90810, "tdf90810short.docx") -{ - uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); - uno::Reference xFootnoteSupp(xTextDocument, uno::UNO_QUERY); - uno::Reference xFootnoteIdxAcc = xFootnoteSupp->getFootnotes(); - uno::Reference xFootnote(xFootnoteIdxAcc->getByIndex(0), uno::UNO_QUERY); - uno::Reference xFootnoteText(xFootnote, uno::UNO_QUERY); - OUString sFootnoteText = xFootnoteText->getString(); - CPPUNIT_ASSERT_EQUAL(static_cast(89), sFootnoteText.getLength()); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf89165, "tdf89165.docx") -{ - // This must not hang in layout -} - -DECLARE_OOXMLEXPORT_TEST(testTdf95777, "tdf95777.docx") -{ - // This must not fail on open -} - -CPPUNIT_TEST_FIXTURE(Test, testTdf94374) -{ - createSwDoc("hello.docx"); - uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); - uno::Reference xText = xTextDocument->getText(); - uno::Reference xEnd = xText->getEnd(); - // This failed: it wasn't possible to insert a DOCX document into an existing Writer one. - paste(u"ooxmlexport/data/tdf94374.docx", "com.sun.star.comp.Writer.WriterFilter", xEnd); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf83300, "tdf83300.docx") -{ - // tdf#143722: This was 'TOC Heading', upon updating a TOC the heading replaced its Word-default blue + Calibri style - // with a Writer-default black + Liberation Sans one - CPPUNIT_ASSERT_EQUAL(OUString("Contents Heading"), getProperty(getParagraph(1), "ParaStyleName")); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf78902, "tdf78902.docx") -{ - // This hung in layout. - CPPUNIT_ASSERT_EQUAL(2, getPages()); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf95775, "tdf95775.docx") -{ - // This must not fail in layout -} - -DECLARE_OOXMLEXPORT_TEST(testTdf92157, "tdf92157.docx") -{ - // A graphic with dimensions 0,0 should not fail on load - - // Additionally, the bookmark names should not change (they got a "1" appended when copied) - uno::Reference xBookmarksSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xBookmarksByName = xBookmarksSupplier->getBookmarks(); - CPPUNIT_ASSERT(xBookmarksByName->hasByName("referentiegegevens")); - CPPUNIT_ASSERT(xBookmarksByName->hasByName("referentiegegevens_bk")); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf97417, "section_break_numbering.docx") -{ - uno::Reference xProps(getParagraph(1), uno::UNO_QUERY_THROW); - CPPUNIT_ASSERT_MESSAGE("1st page: first paragraph erroneous numbering", - !xProps->getPropertyValue("NumberingRules").hasValue()); - // paragraph with numbering and section break was removed by writerfilter - // but its numbering was copied to all following paragraphs - CPPUNIT_ASSERT_MESSAGE("2nd page: first paragraph missing numbering", - getProperty>(getParagraph(2), "NumberingRules").is()); - xProps = uno::Reference(getParagraph(3), uno::UNO_QUERY_THROW); - CPPUNIT_ASSERT_MESSAGE("2nd page: second paragraph erroneous numbering", - !xProps->getPropertyValue("NumberingRules").hasValue()); - - CPPUNIT_ASSERT_EQUAL(2, getPages()); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf94043, "tdf94043.docx") -{ - auto xTextSection = getProperty< uno::Reference >(getParagraph(2), "TextSection"); - auto xTextColumns = getProperty< uno::Reference >(xTextSection, "TextColumns"); - // This was 0, the separator line was not visible due to 0 width. - CPPUNIT_ASSERT_EQUAL(static_cast(2), getProperty(xTextColumns, "SeparatorLineWidth")); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf95213, "tdf95213.docx") -{ - // Get the second paragraph's numbering style's 2nd level's character style name. - uno::Reference xParagraph = getParagraph(2); - auto xLevels = getProperty< uno::Reference >(xParagraph, "NumberingRules"); - uno::Sequence aLevel; - xLevels->getByIndex(1) >>= aLevel; // 2nd level - OUString aName = std::find_if(std::cbegin(aLevel), std::cend(aLevel), [](const beans::PropertyValue& rValue) { return rValue.Name == "CharStyleName"; })->Value.get(); - - uno::Reference xStyle(getStyles("CharacterStyles")->getByName(aName), uno::UNO_QUERY); - // This was awt::FontWeight::BOLD. - CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty(xStyle, "CharWeight")); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf97371, "tdf97371.docx") -{ - SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); - CPPUNIT_ASSERT(pTextDoc); - SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); - SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); - SdrObject* pShape = pPage->GetObj(0); - SdrObject* pTextBox = pPage->GetObj(1); - tools::Long nDiff = std::abs(pShape->GetSnapRect().Top() - pTextBox->GetSnapRect().Top()); - // The top of the two shapes were 410 and 3951, now it should be 3950 and 3951. - CPPUNIT_ASSERT(nDiff < 10); -} - -CPPUNIT_TEST_FIXTURE(Test, testTdf99140) -{ - SwModelTestBase::FlySplitGuard aGuard; - auto verify = [this]() { - // A multi-page floating table appeared only on the first page. - SwDoc* pDoc = getSwDoc(); - SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); - auto pPage1 = dynamic_cast(pLayout->Lower()); - CPPUNIT_ASSERT(pPage1); - const SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs(); - CPPUNIT_ASSERT_EQUAL(static_cast(1), rPage1Objs.size()); - auto pPage1Fly = dynamic_cast(rPage1Objs[0]); - CPPUNIT_ASSERT(pPage1Fly); - SwFrame* pTab1 = pPage1Fly->GetLower(); - // This was text::HoriOrientation::NONE, the second table was too wide due to this. - CPPUNIT_ASSERT_EQUAL(static_cast(9622), pTab1->getFrameArea().Width()); - SwFrame* pRow1 = pTab1->GetLower(); - SwFrame* pCell1 = pRow1->GetLower(); - auto pText1 = dynamic_cast(pCell1->GetLower()); - CPPUNIT_ASSERT(pText1); - CPPUNIT_ASSERT_EQUAL(OUString("Table2:A1"), pText1->GetText()); - - auto pPage2 = dynamic_cast(pPage1->GetNext()); - CPPUNIT_ASSERT(pPage2); - const SwSortedObjs& rPage2Objs = *pPage2->GetSortedObjs(); - CPPUNIT_ASSERT_EQUAL(static_cast(1), rPage2Objs.size()); - auto pPage2Fly = dynamic_cast(rPage2Objs[0]); - CPPUNIT_ASSERT(pPage2Fly); - SwFrame* pTab2 = pPage2Fly->GetLower(); - SwFrame* pRow2 = pTab2->GetLower(); - SwFrame* pCell2 = pRow2->GetLower(); - auto pText2 = dynamic_cast(pCell2->GetLower()); - CPPUNIT_ASSERT(pText2); - CPPUNIT_ASSERT_EQUAL(OUString("Table2:A2"), pText2->GetText()); - }; - createSwDoc("tdf99140.docx"); - verify(); - reload(mpFilter, "tdf99140.docx"); - verify(); -} - -CPPUNIT_TEST_FIXTURE(Test, testTableMarginAdjustment) -{ - loadAndReload("table.fodt"); - // Writer, (new) Word: margin 0 means table border starts at 0 - // (old) Word: margin 0 means paragraph in table starts at 0 - - auto const xTable(getParagraphOrTable(1)); - // shifted very slightly to account for half of the thin border width, so 4, not 0. - CPPUNIT_ASSERT_EQUAL(sal_Int32(4), getProperty(xTable, "LeftMargin")); - - // Now that compatibilityMode is set to 2013's 15 (new), expect the new values, - // since LO is exporting in the NEW way now instead of the OLD way. - // This was 55 when using 2007's compatibilityMode of 12 (old) - - xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); - - assertXPath(pXmlDoc, "//w:tbl[1]/w:tblPr[1]/w:tblInd[1]", "type", "dxa"); - assertXPath(pXmlDoc, "//w:tbl[1]/w:tblPr[1]/w:tblInd[1]", "w", "0"); - - - // tdf#143982: automatic tables should export as something better than just left-and-size - CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty(xTable, "RelativeWidth")); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf119760_tableInTablePosition, "tdf119760_tableInTablePosition.docx") -{ - if ( isExported() ) - { - xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); - - assertXPath(pXmlDoc, "//w:tbl[1]/w:tr[1]/w:tc[1]/w:tbl[1]/w:tblPr[1]/w:tblInd[1]", "type", "dxa"); - assertXPath(pXmlDoc, "//w:tbl[1]/w:tr[1]/w:tc[1]/w:tbl[1]//w:tblPr[1]/w:tblInd[1]", "w", "0"); - } - - uno::Reference< text::XTextTablesSupplier > xTablesSupplier( mxComponent, uno::UNO_QUERY ); - uno::Reference< container::XIndexAccess > xTables( xTablesSupplier->getTextTables(), uno::UNO_QUERY ); - uno::Reference< text::XTextTable > xTable( xTables->getByIndex(0), uno::UNO_QUERY ); - // For compatibilityMode 15: margin 0 means table border starts at 0, - // shifted to account for half of the thick border width, so 106, not 0. - CPPUNIT_ASSERT_EQUAL(sal_Int32(106), getProperty(xTable, "LeftMargin")); -} - -DECLARE_OOXMLEXPORT_TEST( testTableCellMargin, "table-cell-margin.docx" ) -{ - sal_Int32 const cellLeftMarginFromOffice[] = { 250, 100, 0, 0 }; - - uno::Reference< text::XTextTablesSupplier > xTablesSupplier( mxComponent, uno::UNO_QUERY ); - uno::Reference< container::XIndexAccess > xTables( xTablesSupplier->getTextTables(), uno::UNO_QUERY ); - - for ( int i = 0; i < 4; i++ ) - { - uno::Reference< text::XTextTable > xTable1( xTables->getByIndex( i ), uno::UNO_QUERY ); - - // Verify left margin of 1st cell : - // * Office left margins are measured relative to the right of the border - // * LO left spacing is measured from the center of the border - uno::Reference< table::XCell > xCell = xTable1->getCellByName( "A1" ); - uno::Reference< beans::XPropertySet > xPropSet( xCell, uno::UNO_QUERY_THROW ); - sal_Int32 aLeftMargin = -1; - xPropSet->getPropertyValue( "LeftBorderDistance" ) >>= aLeftMargin; - uno::Any aLeftBorder = xPropSet->getPropertyValue( "LeftBorder" ); - table::BorderLine2 aLeftBorderLine; - aLeftBorder >>= aLeftBorderLine; - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Incorrect left spacing computed from docx cell margin", - cellLeftMarginFromOffice[i], aLeftMargin - 0.5 * aLeftBorderLine.LineWidth, 1 ); - // The 'a' in the fourth table should not be partly hidden by the border - if ( i == 3 ) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect cell left padding", - 0.5 * aLeftBorderLine.LineWidth, aLeftMargin, 1); - // tdf#119885: cell's edit area must touch right border - sal_Int32 aRightMargin = -1; - xPropSet->getPropertyValue("RightBorderDistance") >>= aRightMargin; - uno::Any aRightBorder = xPropSet->getPropertyValue("RightBorder"); - table::BorderLine2 aRightBorderLine; - aRightBorder >>= aRightBorderLine; - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect cell right padding", - 0.5 * aRightBorderLine.LineWidth, aRightMargin, 1); - } - } -} - -CPPUNIT_TEST_FIXTURE(Test, TestPuzzleExport) -{ - loadAndReload("TestPuzzleExport.odt"); - // See tdf#148342 for details - // Get the doc - uno::Reference< text::XTextDocument > xTextDoc(mxComponent, uno::UNO_QUERY_THROW); - auto pSwDoc = dynamic_cast(xTextDoc.get()); - CPPUNIT_ASSERT(pSwDoc); - // Create a metafile - auto pMeta = pSwDoc->GetDocShell()->GetPreviewMetaFile(); - CPPUNIT_ASSERT(pMeta); - MetafileXmlDump aDumper; - auto pMetaXml = dumpAndParse(aDumper, *pMeta); - CPPUNIT_ASSERT(pMetaXml); - // After parsing check that node... - auto pXNode = getXPathNode(pMetaXml, "/metafile/push/push/push/push[4]/push/push/polypolygon/polygon"); - CPPUNIT_ASSERT(pXNode); - auto pNode = pXNode->nodesetval->nodeTab[0]; - CPPUNIT_ASSERT(pNode); - auto it = pNode->children; - int nCount = 0; - // .. and count the children - while (it != nullptr) - { - nCount++; - it = it->next; - } - // In case of puzzle there will be so many... Without the fix there was a rectangle with 4 points. - CPPUNIT_ASSERT_GREATER(300, nCount); -} - -// tdf#106742 for DOCX with compatibility level <= 14 (MS Word up to and incl. ver.2010), we should use cell margins when calculating table left border position -DECLARE_OOXMLEXPORT_TEST( testTablePosition14, "table-position-14.docx") -{ - sal_Int32 const aXCoordsFromOffice[] = { 2500, -1000, 0, 0 }; - - uno::Reference< text::XTextTablesSupplier > xTablesSupplier( mxComponent, uno::UNO_QUERY ); - uno::Reference< frame::XModel > xModel( mxComponent, uno::UNO_QUERY ); - uno::Reference< container::XIndexAccess > xTables( xTablesSupplier->getTextTables(), uno::UNO_QUERY ); - - for ( int i = 0; i < 4; i++ ) - { - uno::Reference< text::XTextTable > xTable1( xTables->getByIndex( i ), uno::UNO_QUERY ); - - // Verify X coord - uno::Reference< view::XSelectionSupplier > xCtrl( xModel->getCurrentController(), uno::UNO_QUERY ); - xCtrl->select( uno::Any( xTable1 ) ); - uno::Reference< text::XTextViewCursorSupplier > xTextViewCursorSupplier( xCtrl, uno::UNO_QUERY ); - uno::Reference< text::XTextViewCursor > xCursor = xTextViewCursorSupplier->getViewCursor(); - awt::Point pos = xCursor->getPosition(); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Incorrect X coord computed from docx", - aXCoordsFromOffice[i], pos.X, 1 ); - } -} - -// tdf#106742 for DOCX with compatibility level > 14 (MS Word since ver.2013), -// we should NOT use cell margins when calculating table left border position. But we do need to use border width. -DECLARE_OOXMLEXPORT_TEST( testTablePosition15, "table-position-15.docx" ) -{ - sal_Int32 const aXCoordsFromOffice[] = { 2751, -899, 1, 212 }; - - uno::Reference< text::XTextTablesSupplier > xTablesSupplier( mxComponent, uno::UNO_QUERY ); - uno::Reference< frame::XModel > xModel( mxComponent, uno::UNO_QUERY ); - uno::Reference< container::XIndexAccess > xTables( xTablesSupplier->getTextTables(), uno::UNO_QUERY ); - - for ( int i = 0; i < 4; i++ ) - { - uno::Reference< text::XTextTable > xTable1( xTables->getByIndex( i ), uno::UNO_QUERY ); - - // Verify X coord - uno::Reference< view::XSelectionSupplier > xCtrl( xModel->getCurrentController(), uno::UNO_QUERY ); - xCtrl->select( uno::Any( xTable1 ) ); - uno::Reference< text::XTextViewCursorSupplier > xTextViewCursorSupplier( xCtrl, uno::UNO_QUERY ); - uno::Reference< text::XTextViewCursor > xCursor = xTextViewCursorSupplier->getViewCursor(); - awt::Point pos = xCursor->getPosition(); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Incorrect X coord computed from docx", - aXCoordsFromOffice[i], pos.X, 1 ); - } -} - -DECLARE_OOXMLEXPORT_TEST( testTdf107359, "tdf107359-char-pitch.docx" ) -{ - uno::Reference xPropertySet(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); - - bool bGridSnapToChars; - xPropertySet->getPropertyValue("GridSnapToChars") >>= bGridSnapToChars; - CPPUNIT_ASSERT_EQUAL( false, bGridSnapToChars ); - - sal_Int32 nRubyHeight; - xPropertySet->getPropertyValue("GridRubyHeight") >>= nRubyHeight; - CPPUNIT_ASSERT_EQUAL( sal_Int32(0), nRubyHeight ); - - sal_Int32 nBaseHeight; - xPropertySet->getPropertyValue("GridBaseHeight") >>= nBaseHeight; - CPPUNIT_ASSERT_EQUAL( sal_Int32(convertTwipToMm100(18 * 20)), nBaseHeight ); - - sal_Int32 nBaseWidth; - xPropertySet->getPropertyValue("GridBaseWidth") >>= nBaseWidth; - CPPUNIT_ASSERT_EQUAL( sal_Int32(convertTwipToMm100(24 * 20)), nBaseWidth ); -} - -CPPUNIT_TEST_FIXTURE(Test, testTdf77236_MissingSolidFill) -{ - loadAndSave("tdf77236_MissingSolidFill.docx"); - // tdf#77236: solidFill of VML shape was not exported if the colors of line and style were the same - xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); - assertXPath(pXmlDoc, "//mc:Choice/w:drawing/wp:inline/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:solidFill", 1); -} - -DECLARE_OOXMLEXPORT_TEST(testTdf105875_VmlShapeRotationWithFlip, "tdf105875_VmlShapeRotationWithFlip.docx") -{ - // tdf#105875: check whether the rotation of the VML bezier shape is ok (with flip too) - // TODO: fix export too - if (isExported()) - return; - - { - uno::Reference xPropertySet(getShape(1), uno::UNO_QUERY_THROW); - CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xPropertySet->getPropertyValue("RotateAngle").get()); - } - - { - uno::Reference xPropertySet(getShape(2), uno::UNO_QUERY_THROW); - CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(220 * 100), xPropertySet->getPropertyValue("RotateAngle").get(), 1); - } - - { - uno::Reference xPropertySet(getShape(3), uno::UNO_QUERY_THROW); - CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(320 * 100), xPropertySet->getPropertyValue("RotateAngle").get(), 1); - } - - { - uno::Reference xPropertySet(getShape(4), uno::UNO_QUERY_THROW); - CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(140 * 100), xPropertySet->getPropertyValue("RotateAngle").get(), 1); - } - - { - uno::Reference xPropertySet(getShape(5), uno::UNO_QUERY_THROW); - CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(40 * 100), xPropertySet->getPropertyValue("RotateAngle").get(), 1); - } - -} - CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx new file mode 100644 index 000000000000..984d67c46b89 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx @@ -0,0 +1,890 @@ +/* -*- 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Test : public SwModelTestBase +{ +public: + Test() + : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") + { + } +}; + +DECLARE_OOXMLEXPORT_TEST(testFdo78939, "fdo78939.docx") +{ + // fdo#78939 : LO hanged while opening issue document + + // Whenever a para-style was applied to a Numbering format level, + // LO incorrectly also changed the para-style... + + // check that file opens and does not hang while opening and also + // check that an incorrect numbering style is not applied ... + CPPUNIT_ASSERT_EQUAL(OUString(), getProperty(getParagraph(1), "NumberingStyleName")); +} + +DECLARE_OOXMLEXPORT_TEST(testFootnote, "footnote.docx") +{ + uno::Reference xFootnotesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xFootnotes = xFootnotesSupplier->getFootnotes(); + uno::Reference xFootnote(xFootnotes->getByIndex(0), uno::UNO_QUERY); + OUString aFootnote = xFootnote->getString(); + // Ensure there are no additional newlines after "bar". + CPPUNIT_ASSERT(aFootnote.endsWith("bar")); +} + +DECLARE_OOXMLEXPORT_TEST(testTableBtlrCenter, "table-btlr-center.docx") +{ + // Note that this is btLr text, so layout and doc model horizontal/vertical is the opposite of + // each other. + uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference xCell = xTable->getCellByName("A2"); + // Cell vertical alignment was CENTER, should be NONE. + CPPUNIT_ASSERT_EQUAL(text::VertOrientation::NONE, getProperty(xCell, "VertOrient")); + + // Cell horizontal alignment should be CENTER. + uno::Reference xCellText(xCell, uno::UNO_QUERY); + auto nActual = getProperty(getParagraphOfText(1, xCellText), "ParaAdjust"); + CPPUNIT_ASSERT_EQUAL(static_cast(style::ParagraphAdjust_CENTER), nActual); +} + +DECLARE_OOXMLEXPORT_TEST(testFdo80555, "fdo80555.docx") +{ + uno::Reference xShape = getShape(1); + // Shape was wrongly placed at X=0, Y=0 + CPPUNIT_ASSERT_EQUAL(sal_Int32(3318), xShape->getPosition().X); + CPPUNIT_ASSERT_EQUAL(sal_Int32(247), xShape->getPosition().Y); +} + +CPPUNIT_TEST_FIXTURE(Test, testTdf104418) +{ + loadAndReload("tdf104418.odt"); + // Problem was that cell property was ignored. + uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference xTextTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference xTableRows = xTextTable->getRows(); + + // Without the fix in place, this test would have failed with + // - Expected: 750 + // - Actual : 1499 + CPPUNIT_ASSERT_EQUAL(sal_Int64(750), + getProperty(xTableRows->getByIndex(0), "Height")); +} + +DECLARE_OOXMLEXPORT_TEST(testHidemark, "hidemark.docx") +{ + // Problem was that cell property was ignored. + uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference xTextTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference xTableRows = xTextTable->getRows(); + // Height should be minimal + CPPUNIT_ASSERT_EQUAL(convertTwipToMm100(MINLAY), + getProperty(xTableRows->getByIndex(1), "Height")); + // Size type was MIN, should be FIX to avoid considering the end of paragraph marker. + CPPUNIT_ASSERT_EQUAL(text::SizeType::FIX, + getProperty(xTableRows->getByIndex(1), "SizeType")); + + //tdf#104876: Width was not recognized during import when table size was 'auto' + CPPUNIT_ASSERT_MESSAGE("table size is less than 7000?", + sal_Int32(7000) > getProperty(xTextTable, "Width")); +} + +DECLARE_OOXMLEXPORT_TEST(testHidemarkb, "tdf99616_hidemarkb.docx") +{ + // Problem was that the smallest possible height was forced, not the min specified size. + uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference xTextTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference xTableRows = xTextTable->getRows(); + // Height should be .5cm + CPPUNIT_ASSERT_EQUAL(sal_Int64(501), + getProperty(xTableRows->getByIndex(1), "Height")); + // Size type was MIN, should be FIX to avoid considering the end of paragraph marker. + CPPUNIT_ASSERT_EQUAL(text::SizeType::FIX, + getProperty(xTableRows->getByIndex(1), "SizeType")); +} + +DECLARE_OOXMLEXPORT_TEST(testBnc891663, "bnc891663.docx") +{ + // The image should be inside a cell, so the text in the following cell should be below it. + int imageTop + = parseDump("/root/page/body/tab/row[1]/cell[2]/txt[1]/anchored/fly/infos/bounds", "top") + .toInt32(); + int imageHeight + = parseDump("/root/page/body/tab/row[1]/cell[2]/txt[1]/anchored/fly/infos/bounds", "height") + .toInt32(); + int textNextRowTop + = parseDump("/root/page/body/tab/row[2]/cell[1]/txt[1]/infos/bounds", "top").toInt32(); + CPPUNIT_ASSERT(textNextRowTop >= imageTop + imageHeight); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf123104, "tdf123104.docx") +{ + uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference xCell = xTable->getCellByName("E1"); + // See SwXCell::getPropertyValue(), we really put 'long' into an Any there. + // Without the accompanying fix in place, this test would have failed with 'Expected: 3;Actual : + // 2', i.e. the vertical merge covered one less cell, resulting in a cell with white background. + CPPUNIT_ASSERT_EQUAL(static_cast(3), getProperty(xCell, "RowSpan")); +} + +DECLARE_OOXMLEXPORT_TEST(testFdo85542, "fdo85542.docx") +{ + uno::Reference xBookmarksSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast(3), xBookmarksByIdx->getCount()); + uno::Reference xBookmarksByName = xBookmarksSupplier->getBookmarks(); + CPPUNIT_ASSERT(xBookmarksByName->hasByName("B1")); + CPPUNIT_ASSERT(xBookmarksByName->hasByName("B2")); + CPPUNIT_ASSERT(xBookmarksByName->hasByName("B3")); + // B1 + uno::Reference xContent1(xBookmarksByName->getByName("B1"), uno::UNO_QUERY); + uno::Reference xRange1 = xContent1->getAnchor(); + CPPUNIT_ASSERT_EQUAL(OUString("ABB"), xRange1->getString()); + // B2 + uno::Reference xContent2(xBookmarksByName->getByName("B2"), uno::UNO_QUERY); + uno::Reference xRange2 = xContent2->getAnchor(); + CPPUNIT_ASSERT_EQUAL(OUString("BBC"), xRange2->getString()); + // B3 -- testing a collapsed bookmark + uno::Reference xContent3(xBookmarksByName->getByName("B3"), uno::UNO_QUERY); + uno::Reference xRange3 = xContent3->getAnchor(); + CPPUNIT_ASSERT_EQUAL(xRange3->getString(), OUString()); + uno::Reference xText = xRange3->getText(); + uno::Reference xNeighborhoodCursor = xText->createTextCursor(); + xNeighborhoodCursor->gotoRange(xRange3, false); + xNeighborhoodCursor->goLeft(1, false); + xNeighborhoodCursor->goRight(2, true); + CPPUNIT_ASSERT_EQUAL(OUString("AB"), xNeighborhoodCursor->getString()); +} + +CPPUNIT_TEST_FIXTURE(Test, testTdf65955) +{ + loadAndReload("tdf65955.odt"); + CPPUNIT_ASSERT_EQUAL(1, getPages()); + uno::Reference xBookmarksSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast(2), xBookmarksByIdx->getCount()); + uno::Reference xBookmarksByName = xBookmarksSupplier->getBookmarks(); + CPPUNIT_ASSERT(xBookmarksByName->hasByName("a")); + CPPUNIT_ASSERT(xBookmarksByName->hasByName("b")); + // a + uno::Reference xContent3(xBookmarksByName->getByName("a"), uno::UNO_QUERY); + uno::Reference xRange3 = xContent3->getAnchor(); + CPPUNIT_ASSERT_EQUAL(xRange3->getString(), OUString()); + // b + uno::Reference xContent2(xBookmarksByName->getByName("b"), uno::UNO_QUERY); + uno::Reference xRange2 = xContent2->getAnchor(); + CPPUNIT_ASSERT_EQUAL(OUString("r"), xRange2->getString()); +} + +CPPUNIT_TEST_FIXTURE(Test, testTdf65955_2) +{ + loadAndReload("tdf65955_2.odt"); + CPPUNIT_ASSERT_EQUAL(1, getPages()); + uno::Reference xBookmarksSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast(1), xBookmarksByIdx->getCount()); + uno::Reference xBookmarksByName = xBookmarksSupplier->getBookmarks(); + CPPUNIT_ASSERT(xBookmarksByName->hasByName("test")); + + uno::Reference xContent3(xBookmarksByName->getByName("test"), + uno::UNO_QUERY); + uno::Reference xRange3 = xContent3->getAnchor(); + CPPUNIT_ASSERT_EQUAL(OUString("foo bar"), xRange3->getString()); +} + +DECLARE_OOXMLEXPORT_TEST(testChtOutlineNumberingOoxml, "chtoutline.docx") +{ + static constexpr OUStringLiteral aExpectedNumbering = u"\u7b2c 1 \u7ae0"; + + uno::Reference xPara(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(aExpectedNumbering), + getProperty(xPara, "ListLabelString")); +} + +DECLARE_OOXMLEXPORT_TEST(mathtype, "mathtype.docx") +{ + uno::Reference xTextEmbeddedObjectsSupplier(mxComponent, + uno::UNO_QUERY); + uno::Reference xEmbeddedObjects( + xTextEmbeddedObjectsSupplier->getEmbeddedObjects(), uno::UNO_QUERY); + // This failed as the Model property was empty. + auto xModel + = getProperty>(xEmbeddedObjects->getByIndex(0), "Model"); + CPPUNIT_ASSERT(xModel->supportsService("com.sun.star.formula.FormulaProperties")); +} + +CPPUNIT_TEST_FIXTURE(Test, testTdf8255) +{ + SwModelTestBase::FlySplitGuard aGuard; + auto verify = [this]() { + // A full-page-wide multi-page floating table should be allowed to split: + uno::Reference xDocument(mxComponent, uno::UNO_QUERY); + uno::Reference xFrame(xDocument->getTextFrames()->getByName("Frame1"), + uno::UNO_QUERY); + bool bIsSplitAllowed{}; + xFrame->getPropertyValue("IsSplitAllowed") >>= bIsSplitAllowed; + CPPUNIT_ASSERT(bIsSplitAllowed); + }; + createSwDoc("tdf8255.docx"); + verify(); + reload(mpFilter, "tdf8255.docx"); + verify(); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf87460, "tdf87460.docx") +{ + uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference xEndnotesSupplier(xTextDocument, uno::UNO_QUERY); + uno::Reference xEndnotes = xEndnotesSupplier->getEndnotes(); + // This was 0: endnote was lost on import. + CPPUNIT_ASSERT_EQUAL(static_cast(1), xEndnotes->getCount()); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf90611, "tdf90611.docx") +{ + uno::Reference xFootnotesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xFootnotes = xFootnotesSupplier->getFootnotes(); + uno::Reference xFootnoteText; + xFootnotes->getByIndex(0) >>= xFootnoteText; + // This was 11. + CPPUNIT_ASSERT_EQUAL(10.f, + getProperty(getParagraphOfText(1, xFootnoteText), "CharHeight")); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf89702, "tdf89702.docx") +{ + // Get the first paragraph's numbering style's 2nd level's character style name. + uno::Reference xParagraph = getParagraph(1); + auto xLevels + = getProperty>(xParagraph, "NumberingRules"); + uno::Sequence aLevel; + xLevels->getByIndex(1) >>= aLevel; // 2nd level + OUString aCharStyleName = std::find_if(std::cbegin(aLevel), std::cend(aLevel), + [](const beans::PropertyValue& rValue) { + return rValue.Name == "CharStyleName"; + }) + ->Value.get(); + + // Make sure that the font name is Arial, this was Verdana. + uno::Reference xStyle( + getStyles("CharacterStyles")->getByName(aCharStyleName), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Arial"), getProperty(xStyle, "CharFontName")); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf86374, "tdf86374.docx") +{ + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference xTableRows = xTable->getRows(); + // btLr text direction was imported as FIX, it should be MIN to have enough space for the additionally entered paragraphs. + CPPUNIT_ASSERT_EQUAL(text::SizeType::MIN, + getProperty(xTableRows->getByIndex(0), "SizeType")); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf87924, "tdf87924.docx") +{ + uno::Reference xPropertySet(getShape(1), uno::UNO_QUERY); + comphelper::SequenceAsHashMap aGeometry(xPropertySet->getPropertyValue("CustomShapeGeometry")); + // This was -270, the text rotation angle was set when it should not be rotated. + CPPUNIT_ASSERT_EQUAL(static_cast(0), + aGeometry["TextPreRotateAngle"].get()); +} + +DECLARE_OOXMLEXPORT_TEST(testIndents, "indents.docx") +{ + //expected left margin and first line indent values + static const sal_Int32 indents[] = { 0, 0, -2000, 0, -2000, 1000, -1000, -1000, 2000, -1000 }; + uno::Reference textDocument(mxComponent, uno::UNO_QUERY); + uno::Reference xParaEnumAccess(textDocument->getText(), + uno::UNO_QUERY); + // list of paragraphs + uno::Reference xParaEnum = xParaEnumAccess->createEnumeration(); + size_t paraIndex = 0; + do + { + uno::Reference xServiceInfo; + if (xParaEnum->nextElement() >>= xServiceInfo) + { + uno::Reference const xPropertySet(xServiceInfo, + uno::UNO_QUERY_THROW); + sal_Int32 nIndent = 0; + sal_Int32 nFirstLine = 0; + xPropertySet->getPropertyValue("ParaLeftMargin") >>= nIndent; + xPropertySet->getPropertyValue("ParaFirstLineIndent") >>= nFirstLine; + CPPUNIT_ASSERT_EQUAL(indents[paraIndex * 2], nIndent); + CPPUNIT_ASSERT_EQUAL(indents[paraIndex * 2 + 1], nFirstLine); + ++paraIndex; + } + } while (xParaEnum->hasMoreElements()); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf92454, "tdf92454.docx") +{ + // The first paragraph had a large indentation / left margin as inheritance + // in Word and Writer works differently, and no direct value was set to be + // explicit. + uno::Reference xParagraph(getParagraph(1), uno::UNO_QUERY); + // This was beans::PropertyState_DEFAULT_VALUE. + CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, + xParagraph->getPropertyState("ParaFirstLineIndent")); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf95377, "tdf95377.docx") +{ + uno::Reference xParagraph(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), getProperty(xParagraph, "ParaRightMargin")); + + xParagraph.set(getParagraph(2), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-501), + getProperty(xParagraph, "ParaFirstLineIndent")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2501), getProperty(xParagraph, "ParaLeftMargin")); + CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, + xParagraph->getPropertyState("ParaFirstLineIndent")); + + xParagraph.set(getParagraph(3), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-250), + getProperty(xParagraph, "ParaFirstLineIndent")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty(xParagraph, "ParaLeftMargin")); + CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, + xParagraph->getPropertyState("ParaFirstLineIndent")); + + //default style has numbering enabled. Styles inherit numbering unless specifically disabled + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, + "//body/txt/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", + 3); //first three paragraphs have numbering + assertXPath(pXmlDoc, + "//body/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", + "expand", "a."); + assertXPath(pXmlDoc, + "//body/txt[2]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", + "expand", "b."); + assertXPath(pXmlDoc, + "//body/txt[3]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", + "expand", "c."); + assertXPath( + pXmlDoc, + "/root/page/body/txt[4]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", + 0); //last paragraph style disables numbering +} + +DECLARE_OOXMLEXPORT_TEST(testTdf95376, "tdf95376.docx") +{ + uno::Reference xParagraph(getParagraph(2), uno::UNO_QUERY); + // This was beans::PropertyState_DIRECT_VALUE: indentation-from-numbering + // did not have priority over indentation-from-paragraph-style, due to a + // filter workaround that's not correct here. + CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DEFAULT_VALUE, + xParagraph->getPropertyState("ParaFirstLineIndent")); + + //tdf#131321 - paragraph styles lost their numbering. Bullet+space inherits WWNum1 from Bullet + uno::Reference xStyle( + getStyles("ParagraphStyles")->getByName("Bullet+space"), uno::UNO_QUERY); + CPPUNIT_ASSERT(!(getProperty(xStyle, "NumberingStyleName")).isEmpty()); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf92124, "tdf92124.docx") +{ + // Get the second paragraph's numbering style's 1st level's suffix. + uno::Reference xParagraph = getParagraph(2); + auto xLevels + = getProperty>(xParagraph, "NumberingRules"); + uno::Sequence aLevel; + xLevels->getByIndex(0) >>= aLevel; // 1st level + OUString aSuffix + = std::find_if(std::cbegin(aLevel), std::cend(aLevel), + [](const beans::PropertyValue& rValue) { return rValue.Name == "Suffix"; }) + ->Value.get(); + // Make sure it's empty as the source document contains . + CPPUNIT_ASSERT(aSuffix.isEmpty()); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf90153, "tdf90153.docx") +{ + // This was at-para, so the line-level VertOrientRelation was lost, resulting in an incorrect vertical position. + CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, + getProperty(getShape(1), "AnchorType")); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf93919, "tdf93919.docx") +{ + // This was 0, left margin was not inherited from the list style. + CPPUNIT_ASSERT_EQUAL(static_cast(1270), + getProperty(getParagraph(1), "ParaLeftMargin")); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf91417, "tdf91417.docx") +{ + // The first paragraph should contain a link to "http://www.google.com/" + uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference xTextCursor = xTextDocument->getText()->createTextCursor(); + uno::Reference xCursorProps(xTextCursor, uno::UNO_QUERY); + OUString aValue; + xCursorProps->getPropertyValue("HyperLinkURL") >>= aValue; + CPPUNIT_ASSERT_EQUAL(OUString("http://www.google.com/"), aValue); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf90810, "tdf90810short.docx") +{ + uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference xFootnoteSupp(xTextDocument, uno::UNO_QUERY); + uno::Reference xFootnoteIdxAcc = xFootnoteSupp->getFootnotes(); + uno::Reference xFootnote(xFootnoteIdxAcc->getByIndex(0), uno::UNO_QUERY); + uno::Reference xFootnoteText(xFootnote, uno::UNO_QUERY); + OUString sFootnoteText = xFootnoteText->getString(); + CPPUNIT_ASSERT_EQUAL(static_cast(89), sFootnoteText.getLength()); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf89165, "tdf89165.docx") +{ + // This must not hang in layout +} + +DECLARE_OOXMLEXPORT_TEST(testTdf95777, "tdf95777.docx") +{ + // This must not fail on open +} + +CPPUNIT_TEST_FIXTURE(Test, testTdf94374) +{ + createSwDoc("hello.docx"); + uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference xText = xTextDocument->getText(); + uno::Reference xEnd = xText->getEnd(); + // This failed: it wasn't possible to insert a DOCX document into an existing Writer one. + paste(u"ooxmlexport/data/tdf94374.docx", "com.sun.star.comp.Writer.WriterFilter", xEnd); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf83300, "tdf83300.docx") +{ + // tdf#143722: This was 'TOC Heading', upon updating a TOC the heading replaced its Word-default blue + Calibri style + // with a Writer-default black + Liberation Sans one + CPPUNIT_ASSERT_EQUAL(OUString("Contents Heading"), + getProperty(getParagraph(1), "ParaStyleName")); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf78902, "tdf78902.docx") +{ + // This hung in layout. + CPPUNIT_ASSERT_EQUAL(2, getPages()); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf95775, "tdf95775.docx") +{ + // This must not fail in layout +} + +DECLARE_OOXMLEXPORT_TEST(testTdf92157, "tdf92157.docx") +{ + // A graphic with dimensions 0,0 should not fail on load + + // Additionally, the bookmark names should not change (they got a "1" appended when copied) + uno::Reference xBookmarksSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xBookmarksByName = xBookmarksSupplier->getBookmarks(); + CPPUNIT_ASSERT(xBookmarksByName->hasByName("referentiegegevens")); + CPPUNIT_ASSERT(xBookmarksByName->hasByName("referentiegegevens_bk")); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf97417, "section_break_numbering.docx") +{ + uno::Reference xProps(getParagraph(1), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_MESSAGE("1st page: first paragraph erroneous numbering", + !xProps->getPropertyValue("NumberingRules").hasValue()); + // paragraph with numbering and section break was removed by writerfilter + // but its numbering was copied to all following paragraphs + CPPUNIT_ASSERT_MESSAGE( + "2nd page: first paragraph missing numbering", + getProperty>(getParagraph(2), "NumberingRules") + .is()); + xProps = uno::Reference(getParagraph(3), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_MESSAGE("2nd page: second paragraph erroneous numbering", + !xProps->getPropertyValue("NumberingRules").hasValue()); + + CPPUNIT_ASSERT_EQUAL(2, getPages()); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf94043, "tdf94043.docx") +{ + auto xTextSection + = getProperty>(getParagraph(2), "TextSection"); + auto xTextColumns + = getProperty>(xTextSection, "TextColumns"); + // This was 0, the separator line was not visible due to 0 width. + CPPUNIT_ASSERT_EQUAL(static_cast(2), + getProperty(xTextColumns, "SeparatorLineWidth")); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf95213, "tdf95213.docx") +{ + // Get the second paragraph's numbering style's 2nd level's character style name. + uno::Reference xParagraph = getParagraph(2); + auto xLevels + = getProperty>(xParagraph, "NumberingRules"); + uno::Sequence aLevel; + xLevels->getByIndex(1) >>= aLevel; // 2nd level + OUString aName = std::find_if(std::cbegin(aLevel), std::cend(aLevel), + [](const beans::PropertyValue& rValue) { + return rValue.Name == "CharStyleName"; + }) + ->Value.get(); + + uno::Reference xStyle(getStyles("CharacterStyles")->getByName(aName), + uno::UNO_QUERY); + // This was awt::FontWeight::BOLD. + CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty(xStyle, "CharWeight")); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf97371, "tdf97371.docx") +{ + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); + SdrObject* pShape = pPage->GetObj(0); + SdrObject* pTextBox = pPage->GetObj(1); + tools::Long nDiff = std::abs(pShape->GetSnapRect().Top() - pTextBox->GetSnapRect().Top()); + // The top of the two shapes were 410 and 3951, now it should be 3950 and 3951. + CPPUNIT_ASSERT(nDiff < 10); +} + +CPPUNIT_TEST_FIXTURE(Test, testTdf99140) +{ + SwModelTestBase::FlySplitGuard aGuard; + auto verify = [this]() { + // A multi-page floating table appeared only on the first page. + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPage1 = dynamic_cast(pLayout->Lower()); + CPPUNIT_ASSERT(pPage1); + const SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast(1), rPage1Objs.size()); + auto pPage1Fly = dynamic_cast(rPage1Objs[0]); + CPPUNIT_ASSERT(pPage1Fly); + SwFrame* pTab1 = pPage1Fly->GetLower(); + // This was text::HoriOrientation::NONE, the second table was too wide due to this. + CPPUNIT_ASSERT_EQUAL(static_cast(9622), pTab1->getFrameArea().Width()); + SwFrame* pRow1 = pTab1->GetLower(); + SwFrame* pCell1 = pRow1->GetLower(); + auto pText1 = dynamic_cast(pCell1->GetLower()); + CPPUNIT_ASSERT(pText1); + CPPUNIT_ASSERT_EQUAL(OUString("Table2:A1"), pText1->GetText()); + + auto pPage2 = dynamic_cast(pPage1->GetNext()); + CPPUNIT_ASSERT(pPage2); + const SwSortedObjs& rPage2Objs = *pPage2->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast(1), rPage2Objs.size()); + auto pPage2Fly = dynamic_cast(rPage2Objs[0]); + CPPUNIT_ASSERT(pPage2Fly); + SwFrame* pTab2 = pPage2Fly->GetLower(); + SwFrame* pRow2 = pTab2->GetLower(); + SwFrame* pCell2 = pRow2->GetLower(); + auto pText2 = dynamic_cast(pCell2->GetLower()); + CPPUNIT_ASSERT(pText2); + CPPUNIT_ASSERT_EQUAL(OUString("Table2:A2"), pText2->GetText()); + }; + createSwDoc("tdf99140.docx"); + verify(); + reload(mpFilter, "tdf99140.docx"); + verify(); +} + +CPPUNIT_TEST_FIXTURE(Test, testTableMarginAdjustment) +{ + loadAndReload("table.fodt"); + // Writer, (new) Word: margin 0 means table border starts at 0 + // (old) Word: margin 0 means paragraph in table starts at 0 + + auto const xTable(getParagraphOrTable(1)); + // shifted very slightly to account for half of the thin border width, so 4, not 0. + CPPUNIT_ASSERT_EQUAL(sal_Int32(4), getProperty(xTable, "LeftMargin")); + + // Now that compatibilityMode is set to 2013's 15 (new), expect the new values, + // since LO is exporting in the NEW way now instead of the OLD way. + // This was 55 when using 2007's compatibilityMode of 12 (old) + + xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); + + assertXPath(pXmlDoc, "//w:tbl[1]/w:tblPr[1]/w:tblInd[1]", "type", "dxa"); + assertXPath(pXmlDoc, "//w:tbl[1]/w:tblPr[1]/w:tblInd[1]", "w", "0"); + + // tdf#143982: automatic tables should export as something better than just left-and-size + CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty(xTable, "RelativeWidth")); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf119760_tableInTablePosition, "tdf119760_tableInTablePosition.docx") +{ + if (isExported()) + { + xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); + + assertXPath(pXmlDoc, "//w:tbl[1]/w:tr[1]/w:tc[1]/w:tbl[1]/w:tblPr[1]/w:tblInd[1]", "type", + "dxa"); + assertXPath(pXmlDoc, "//w:tbl[1]/w:tr[1]/w:tc[1]/w:tbl[1]//w:tblPr[1]/w:tblInd[1]", "w", + "0"); + } + + uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); + // For compatibilityMode 15: margin 0 means table border starts at 0, + // shifted to account for half of the thick border width, so 106, not 0. + CPPUNIT_ASSERT_EQUAL(sal_Int32(106), getProperty(xTable, "LeftMargin")); +} + +DECLARE_OOXMLEXPORT_TEST(testTableCellMargin, "table-cell-margin.docx") +{ + sal_Int32 const cellLeftMarginFromOffice[] = { 250, 100, 0, 0 }; + + uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + + for (int i = 0; i < 4; i++) + { + uno::Reference xTable1(xTables->getByIndex(i), uno::UNO_QUERY); + + // Verify left margin of 1st cell : + // * Office left margins are measured relative to the right of the border + // * LO left spacing is measured from the center of the border + uno::Reference xCell = xTable1->getCellByName("A1"); + uno::Reference xPropSet(xCell, uno::UNO_QUERY_THROW); + sal_Int32 aLeftMargin = -1; + xPropSet->getPropertyValue("LeftBorderDistance") >>= aLeftMargin; + uno::Any aLeftBorder = xPropSet->getPropertyValue("LeftBorder"); + table::BorderLine2 aLeftBorderLine; + aLeftBorder >>= aLeftBorderLine; + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "Incorrect left spacing computed from docx cell margin", cellLeftMarginFromOffice[i], + aLeftMargin - 0.5 * aLeftBorderLine.LineWidth, 1); + // The 'a' in the fourth table should not be partly hidden by the border + if (i == 3) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect cell left padding", + 0.5 * aLeftBorderLine.LineWidth, aLeftMargin, 1); + // tdf#119885: cell's edit area must touch right border + sal_Int32 aRightMargin = -1; + xPropSet->getPropertyValue("RightBorderDistance") >>= aRightMargin; + uno::Any aRightBorder = xPropSet->getPropertyValue("RightBorder"); + table::BorderLine2 aRightBorderLine; + aRightBorder >>= aRightBorderLine; + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect cell right padding", + 0.5 * aRightBorderLine.LineWidth, aRightMargin, 1); + } + } +} + +CPPUNIT_TEST_FIXTURE(Test, TestPuzzleExport) +{ + loadAndReload("TestPuzzleExport.odt"); + // See tdf#148342 for details + // Get the doc + uno::Reference xTextDoc(mxComponent, uno::UNO_QUERY_THROW); + auto pSwDoc = dynamic_cast(xTextDoc.get()); + CPPUNIT_ASSERT(pSwDoc); + // Create a metafile + auto pMeta = pSwDoc->GetDocShell()->GetPreviewMetaFile(); + CPPUNIT_ASSERT(pMeta); + MetafileXmlDump aDumper; + auto pMetaXml = dumpAndParse(aDumper, *pMeta); + CPPUNIT_ASSERT(pMetaXml); + // After parsing check that node... + auto pXNode + = getXPathNode(pMetaXml, "/metafile/push/push/push/push[4]/push/push/polypolygon/polygon"); + CPPUNIT_ASSERT(pXNode); + auto pNode = pXNode->nodesetval->nodeTab[0]; + CPPUNIT_ASSERT(pNode); + auto it = pNode->children; + int nCount = 0; + // .. and count the children + while (it != nullptr) + { + nCount++; + it = it->next; + } + // In case of puzzle there will be so many... Without the fix there was a rectangle with 4 points. + CPPUNIT_ASSERT_GREATER(300, nCount); +} + +// tdf#106742 for DOCX with compatibility level <= 14 (MS Word up to and incl. ver.2010), we should use cell margins when calculating table left border position +DECLARE_OOXMLEXPORT_TEST(testTablePosition14, "table-position-14.docx") +{ + sal_Int32 const aXCoordsFromOffice[] = { 2500, -1000, 0, 0 }; + + uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xModel(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + + for (int i = 0; i < 4; i++) + { + uno::Reference xTable1(xTables->getByIndex(i), uno::UNO_QUERY); + + // Verify X coord + uno::Reference xCtrl(xModel->getCurrentController(), + uno::UNO_QUERY); + xCtrl->select(uno::Any(xTable1)); + uno::Reference xTextViewCursorSupplier(xCtrl, + uno::UNO_QUERY); + uno::Reference xCursor = xTextViewCursorSupplier->getViewCursor(); + awt::Point pos = xCursor->getPosition(); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect X coord computed from docx", + aXCoordsFromOffice[i], pos.X, 1); + } +} + +// tdf#106742 for DOCX with compatibility level > 14 (MS Word since ver.2013), +// we should NOT use cell margins when calculating table left border position. But we do need to use border width. +DECLARE_OOXMLEXPORT_TEST(testTablePosition15, "table-position-15.docx") +{ + sal_Int32 const aXCoordsFromOffice[] = { 2751, -899, 1, 212 }; + + uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xModel(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + + for (int i = 0; i < 4; i++) + { + uno::Reference xTable1(xTables->getByIndex(i), uno::UNO_QUERY); + + // Verify X coord + uno::Reference xCtrl(xModel->getCurrentController(), + uno::UNO_QUERY); + xCtrl->select(uno::Any(xTable1)); + uno::Reference xTextViewCursorSupplier(xCtrl, + uno::UNO_QUERY); + uno::Reference xCursor = xTextViewCursorSupplier->getViewCursor(); + awt::Point pos = xCursor->getPosition(); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect X coord computed from docx", + aXCoordsFromOffice[i], pos.X, 1); + } +} + +DECLARE_OOXMLEXPORT_TEST(testTdf107359, "tdf107359-char-pitch.docx") +{ + uno::Reference xPropertySet(getStyles("PageStyles")->getByName("Standard"), + uno::UNO_QUERY); + + bool bGridSnapToChars; + xPropertySet->getPropertyValue("GridSnapToChars") >>= bGridSnapToChars; + CPPUNIT_ASSERT_EQUAL(false, bGridSnapToChars); + + sal_Int32 nRubyHeight; + xPropertySet->getPropertyValue("GridRubyHeight") >>= nRubyHeight; + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nRubyHeight); + + sal_Int32 nBaseHeight; + xPropertySet->getPropertyValue("GridBaseHeight") >>= nBaseHeight; + CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(18 * 20)), nBaseHeight); + + sal_Int32 nBaseWidth; + xPropertySet->getPropertyValue("GridBaseWidth") >>= nBaseWidth; + CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(24 * 20)), nBaseWidth); +} + +CPPUNIT_TEST_FIXTURE(Test, testTdf77236_MissingSolidFill) +{ + loadAndSave("tdf77236_MissingSolidFill.docx"); + // tdf#77236: solidFill of VML shape was not exported if the colors of line and style were the same + xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); + assertXPath( + pXmlDoc, + "//mc:Choice/w:drawing/wp:inline/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:solidFill", + 1); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf105875_VmlShapeRotationWithFlip, + "tdf105875_VmlShapeRotationWithFlip.docx") +{ + // tdf#105875: check whether the rotation of the VML bezier shape is ok (with flip too) + // TODO: fix export too + if (isExported()) + return; + + { + uno::Reference xPropertySet(getShape(1), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), + xPropertySet->getPropertyValue("RotateAngle").get()); + } + + { + uno::Reference xPropertySet(getShape(2), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(220 * 100), + xPropertySet->getPropertyValue("RotateAngle").get(), + 1); + } + + { + uno::Reference xPropertySet(getShape(3), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(320 * 100), + xPropertySet->getPropertyValue("RotateAngle").get(), + 1); + } + + { + uno::Reference xPropertySet(getShape(4), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(140 * 100), + xPropertySet->getPropertyValue("RotateAngle").get(), + 1); + } + + { + uno::Reference xPropertySet(getShape(5), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_DOUBLES_EQUAL( + sal_Int32(40 * 100), xPropertySet->getPropertyValue("RotateAngle").get(), 1); + } +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */