/* -*- 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 #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"_ostr, "top"_ostr) .toInt32(); int imageHeight = parseDump("/root/page/body/tab/row[1]/cell[2]/txt[1]/anchored/fly/infos/bounds"_ostr, "height"_ostr) .toInt32(); int textNextRowTop = parseDump("/root/page/body/tab/row[2]/cell[1]/txt[1]/infos/bounds"_ostr, "top"_ostr) .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) { 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(); saveAndReload("Office Open XML Text"); 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()); // Also make sure that is mapped to a text frame (hosting the table): uno::Reference xTextFramesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTextFrames = xTextFramesSupplier->getTextFrames(); // Without the fix in place, this test would have failed, the table was inline. CPPUNIT_ASSERT(xTextFrames->hasByName("Frame1")); } 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']"_ostr, 3); //first three paragraphs have numbering assertXPath( pXmlDoc, "//body/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']"_ostr, "expand"_ostr, "a."); assertXPath( pXmlDoc, "//body/txt[2]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']"_ostr, "expand"_ostr, "b."); assertXPath( pXmlDoc, "//body/txt[3]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']"_ostr, "expand"_ostr, "c."); assertXPath( pXmlDoc, "/root/page/body/txt[4]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']"_ostr, 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_ASSERT_DOUBLES_EQUAL(tools::Long(3900), pShape->GetSnapRect().Top(), 100); } CPPUNIT_TEST_FIXTURE(Test, testTdf99140) { 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(); saveAndReload("Office Open XML Text"); 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]"_ostr, "type"_ostr, "dxa"); assertXPath(pXmlDoc, "//w:tbl[1]/w:tblPr[1]/w:tblInd[1]"_ostr, "w"_ostr, "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]"_ostr, "type"_ostr, "dxa"); assertXPath(pXmlDoc, "//w:tbl[1]/w:tr[1]/w:tc[1]/w:tbl[1]//w:tblPr[1]/w:tblInd[1]"_ostr, "w"_ostr, "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"_ostr); 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"_ostr, 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_TEST_FIXTURE(Test, testTdf133363) { loadAndSave("tdf133363.docx"); xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); // tdf#133363: remove extra auto space between first and second list elements assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p[2]/w:pPr/w:spacing"_ostr, "before"_ostr, "0"); assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p[3]/w:pPr/w:spacing"_ostr, "after"_ostr, "0"); } DECLARE_OOXMLEXPORT_TEST(testTdf138093, "tdf138093.docx") { if (isExported()) { xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); assertXPath(pXmlDoc, "//w:sdt"_ostr, 3); 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("B1"); uno::Reference xParagraphsAccess(xCell, uno::UNO_QUERY); uno::Reference xParagraphs = xParagraphsAccess->createEnumeration(); uno::Reference xParagraph(xParagraphs->nextElement(), uno::UNO_QUERY); uno::Reference xPortions = xParagraph->createEnumeration(); uno::Reference xTextPortion(xPortions->nextElement(), uno::UNO_QUERY); OUString aPortionType; xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType; CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType); uno::Reference xContentControl; xTextPortion->getPropertyValue("ContentControl") >>= xContentControl; uno::Reference xContentControlProps(xContentControl, uno::UNO_QUERY); bool bDate{}; xContentControlProps->getPropertyValue("Date") >>= bDate; CPPUNIT_ASSERT(bDate); uno::Reference xContentControlEnumAccess(xContentControl, uno::UNO_QUERY); uno::Reference xContentControlEnum = xContentControlEnumAccess->createEnumeration(); uno::Reference xTextPortionRange(xContentControlEnum->nextElement(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("2017"), xTextPortionRange->getString()); } else { SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); CPPUNIT_ASSERT(pTextDoc); SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess->getAllMarksCount()); ::sw::mark::IDateFieldmark* pFieldmark = dynamic_cast<::sw::mark::IDateFieldmark*>(*pMarkAccess->getAllMarksBegin()); CPPUNIT_ASSERT(pFieldmark); CPPUNIT_ASSERT_EQUAL(ODF_FORMDATE, pFieldmark->GetFieldname()); CPPUNIT_ASSERT_EQUAL(OUString("2017"), pFieldmark->GetContent()); } } DECLARE_OOXMLEXPORT_TEST(testTdf131722, "tdf131722.docx") { if (isExported()) { xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); assertXPath(pXmlDoc, "//w:sdt"_ostr, 4); 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("A1"); uno::Reference xParagraphsAccess(xCell, uno::UNO_QUERY); uno::Reference xParagraphs = xParagraphsAccess->createEnumeration(); uno::Reference xParagraph(xParagraphs->nextElement(), uno::UNO_QUERY); uno::Reference xPortions = xParagraph->createEnumeration(); uno::Reference xTextPortion(xPortions->nextElement(), uno::UNO_QUERY); OUString aPortionType; xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType; CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType); uno::Reference xContentControl; xTextPortion->getPropertyValue("ContentControl") >>= xContentControl; uno::Reference xContentControlProps(xContentControl, uno::UNO_QUERY); bool bDate{}; xContentControlProps->getPropertyValue("Date") >>= bDate; CPPUNIT_ASSERT(bDate); uno::Reference xContentControlEnumAccess(xContentControl, uno::UNO_QUERY); uno::Reference xContentControlEnum = xContentControlEnumAccess->createEnumeration(); uno::Reference xTextPortionRange(xContentControlEnum->nextElement(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("Enter a date here!"), xTextPortionRange->getString()); } else { SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); CPPUNIT_ASSERT(pTextDoc); SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess->getFieldmarksCount()); for (auto aIter = pMarkAccess->getFieldmarksBegin(); aIter != pMarkAccess->getFieldmarksEnd(); ++aIter) { ::sw::mark::IDateFieldmark* pFieldmark = dynamic_cast<::sw::mark::IDateFieldmark*>(*aIter); CPPUNIT_ASSERT(pFieldmark); CPPUNIT_ASSERT_EQUAL(ODF_FORMDATE, pFieldmark->GetFieldname()); CPPUNIT_ASSERT_EQUAL(OUString("Enter a date here!"), pFieldmark->GetContent()); } } } CPPUNIT_TEST_FIXTURE(Test, testTdf155945) { createSwDoc("tdf155945.docx"); CPPUNIT_ASSERT_EQUAL(3, getParagraphs()); // Without a fix in place, this would fail with // - Expected: 0 // - Actual : 423 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty(getParagraph(2), "ParaBottomMargin")); } CPPUNIT_TEST_FIXTURE(Test, testTdf133560) { createSwDoc("lastEmptyLineWithDirectFormatting.docx"); CPPUNIT_ASSERT_EQUAL(4, getParagraphs()); // Without a fix in place, this would fail with // - Expected: 12 // - Actual : 48 CPPUNIT_ASSERT_EQUAL(12.0f, getProperty(getParagraph(4), "CharHeight")); } CPPUNIT_TEST_FIXTURE(Test, testTdf150408_isLvl_RoundTrip) { loadAndSave("listWithLgl.docx"); // Second level's numbering should use Arabic numbers for first level reference auto xPara = getParagraph(1); CPPUNIT_ASSERT_EQUAL(OUString("CH I"), getProperty(xPara, "ListLabelString")); xPara = getParagraph(2); CPPUNIT_ASSERT_EQUAL(OUString("Sect 1.01"), getProperty(xPara, "ListLabelString")); xPara = getParagraph(3); CPPUNIT_ASSERT_EQUAL(OUString("CH II"), getProperty(xPara, "ListLabelString")); xPara = getParagraph(4); CPPUNIT_ASSERT_EQUAL(OUString("Sect 2.01"), getProperty(xPara, "ListLabelString")); xmlDocUniquePtr pXml = parseExport("word/numbering.xml"); assertXPath(pXml, "/w:numbering/w:abstractNum"_ostr); // Only one list // The second list level must keep the isLgl element assertXPath(pXml, "/w:numbering/w:abstractNum/w:lvl[2]/w:isLgl"_ostr); } DECLARE_OOXMLEXPORT_TEST(testTdf156372, "tdf156372.doc") { sal_Int32 nHeight = parseDump("//page[1]/header/tab/row[1]/infos/bounds"_ostr, "height"_ostr).toInt32(); // Without a fix in place, this would fail with // - Expected: 847 // - Actual : 1327 CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(847), nHeight, 5); CPPUNIT_ASSERT_EQUAL(1, getPages()); } CPPUNIT_TEST_FIXTURE(Test, testTdf156548) { // Given a document using two bookmarks with similar names longer than 40 characters loadAndReload("longBookmarkName.fodt"); // After the export, the names must be no longer than 40 characters; they must be unique; // and the hyperlinks must use the same names, to still point to the correct targets: { // 1st paragraph - hyperlink to 4th paragraph auto sURL = getProperty(getRun(getParagraph(1), 1), "HyperLinkURL"); CPPUNIT_ASSERT_EQUAL(OUString("#A_bookmark_name_longer_than_forty_charac"), sURL); // 4th paragraph - a bookmark auto xBookmark = getProperty>(getRun(getParagraph(4), 1), "Bookmark"); CPPUNIT_ASSERT_EQUAL(OUString("A_bookmark_name_longer_than_forty_charac"), xBookmark->getName()); } { // 2nd paragraph - hyperlink to 5th paragraph auto sURL = getProperty(getRun(getParagraph(2), 1), "HyperLinkURL"); CPPUNIT_ASSERT_EQUAL(OUString("#A_bookmark_name_longer_than_forty_chara1"), sURL); // 5th paragraph - a bookmark auto xBookmark = getProperty>(getRun(getParagraph(5), 1), "Bookmark"); CPPUNIT_ASSERT_EQUAL(OUString("A_bookmark_name_longer_than_forty_chara1"), xBookmark->getName()); } } CPPUNIT_TEST_FIXTURE(Test, testTdf157136) { // Given a document with two content controls - one block, one inline createSwDoc("tdf157136_TwoContentControls.docx"); // Both of them must import with the correct character style { // 1st paragraph - block content control auto xRun = getRun(getParagraph(1), 1); auto xContentControl = getProperty>(xRun, "ContentControl"); CPPUNIT_ASSERT_EQUAL(OUString("Click or tap here to enter text."), xContentControl->getString()); // Without the fix in place, this would fail with // - Expected: Placeholder Text // - Actual : CPPUNIT_ASSERT_EQUAL(OUString("Placeholder Text"), getProperty(xRun, "CharStyleName")); } { // 2nd paragraph - inline content control auto xRun = getRun(getParagraph(2), 1); auto xContentControl = getProperty>(xRun, "ContentControl"); CPPUNIT_ASSERT_EQUAL(OUString("Click or tap here to enter text."), xContentControl->getString()); CPPUNIT_ASSERT_EQUAL(OUString("Placeholder Text"), getProperty(xRun, "CharStyleName")); } // Test the same after round-trip saveAndReload("Office Open XML Text"); { // 1st paragraph - becomes inline content control after roundtrip auto xRun = getRun(getParagraph(1), 1); auto xContentControl = getProperty>(xRun, "ContentControl"); CPPUNIT_ASSERT_EQUAL(OUString("Click or tap here to enter text."), xContentControl->getString()); CPPUNIT_ASSERT_EQUAL(OUString("Placeholder Text"), getProperty(xRun, "CharStyleName")); } { // 2nd paragraph - inline content control auto xRun = getRun(getParagraph(2), 1); auto xContentControl = getProperty>(xRun, "ContentControl"); CPPUNIT_ASSERT_EQUAL(OUString("Click or tap here to enter text."), xContentControl->getString()); CPPUNIT_ASSERT_EQUAL(OUString("Placeholder Text"), getProperty(xRun, "CharStyleName")); } } //Tests for support of fallback for ECMA-376 1st ed to merge the title value with descr attribute CPPUNIT_TEST_FIXTURE(Test, testTdf148952_2007) { //Given a document with 1 image (with name, alt title and description field populated) in odt format createSwDoc("tdf148952.odt"); OUString rFilterName = "MS Word 2007 XML"; //Export it to MS word 2007(.docx) format saveAndReload(rFilterName); // Checks the number of images in the docx file const OString sFailedMessage = OString::Concat("Failed on filter: ") + rFilterName.toUtf8(); CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), 1, getShapes()); uno::Reference xImage(getShape(1), uno::UNO_QUERY); // Check if alt title value is appended to description OUString descr; xImage->getPropertyValue("Description") >>= descr; CPPUNIT_ASSERT_EQUAL(OUString("Black\nShapes"), descr); // Check if alt title field is empty OUString title; xImage->getPropertyValue("Title") >>= title; CPPUNIT_ASSERT_EQUAL(OUString(""), title); } //Tests for support of title attribute for ECMA-376 2nd ed and above CPPUNIT_TEST_FIXTURE(Test, testTdf148952_2010) { //Given a document with 1 image (with name, alt title and description field populated) in odt format createSwDoc("tdf148952.odt"); OUString rFilterName = "Office Open XML Text"; //Export it to MS word 2010-365 (.docx) format saveAndReload(rFilterName); // Checks the number of images in the docx file const OString sFailedMessage = OString::Concat("Failed on filter: ") + rFilterName.toUtf8(); CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), 1, getShapes()); uno::Reference xImage(getShape(1), uno::UNO_QUERY); // Check if description field contains same value after export OUString descr; xImage->getPropertyValue("Description") >>= descr; CPPUNIT_ASSERT_EQUAL(OUString("Shapes"), descr); // Check if alt title field contains same value after export OUString title; xImage->getPropertyValue("Title") >>= title; CPPUNIT_ASSERT_EQUAL(OUString("Black"), title); } CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */