/* -*- 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 class Test : public SwModelTestBase { public: Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {} protected: /** * Validation handling */ bool mustValidate(const char* filename) const override { const char* aAllowlist[] = { "paragraph-mark-nonempty.odt" }; std::vector vAllowlist(aAllowlist, aAllowlist + SAL_N_ELEMENTS(aAllowlist)); return std::find(vAllowlist.begin(), vAllowlist.end(), filename) != vAllowlist.end(); } }; CPPUNIT_TEST_FIXTURE(Test, testfdo81381) { loadAndSave("fdo81381.docx"); xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[1]/w:object[1]/o:OLEObject[1]", "DrawAspect", "Icon"); } CPPUNIT_TEST_FIXTURE(Test, testSdtAlias) { loadAndSave("sdt-alias.docx"); xmlDocUniquePtr pXmlDoc = parseExport(); // was completely missing. assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:alias", "val", "Subtitle"); } CPPUNIT_TEST_FIXTURE(Test, testFooterBodyDistance) { loadAndSave("footer-body-distance.docx"); xmlDocUniquePtr pXmlDoc = parseExport(); // Page break was exported as section break, this was 0 assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:br", 1); } // Check for correct header/footer with special first page with TOC inside: // - DECLARE_ODFEXPORT_TEST(testTdf118393, "tdf118393.odt") // - DECLARE_OOXMLEXPORT_TEST(testTdf118393, "tdf118393.odt") CPPUNIT_TEST_FIXTURE(Test, testTdf118393) { loadAndReload("tdf118393.odt"); CPPUNIT_ASSERT_EQUAL( 7, getPages() ); // First page has no header/footer { xmlDocUniquePtr pXmlDoc = parseLayoutDump(); // check first page xmlXPathObjectPtr pXmlPage1Header = getXPathNode(pXmlDoc, "/root/page[1]/header"); CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlPage1Header->nodesetval)); xmlXPathObjectPtr pXmlPage1Footer = getXPathNode(pXmlDoc, "/root/page[1]/footer"); CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlPage1Footer->nodesetval)); // check second page in the same way xmlXPathObjectPtr pXmlPage2Header = getXPathNode(pXmlDoc, "/root/page[2]/header"); CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlPage2Header->nodesetval)); xmlXPathObjectPtr pXmlPage2Footer = getXPathNode(pXmlDoc, "/root/page[2]/footer"); CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlPage2Footer->nodesetval)); } // All other pages should have header/footer CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[2]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[2]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[3]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[3]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[4]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[4]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[5]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[5]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[6]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[6]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[7]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[7]/footer/txt/text()")); } DECLARE_OOXMLEXPORT_TEST(testfdo81031, "fdo81031.docx") { // vml image was not rendered // As there are also numPicBullets in the file, // the fragmentPath was not changed hence relationships were not resolved. uno::Reference image = getShape(1); uno::Reference xImage(image, uno::UNO_QUERY); uno::Reference xGraphic = getProperty >(xImage, "Graphic"); uno::Reference xBitmap(xGraphic, uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL( static_cast(381), xBitmap->getSize().Width ); CPPUNIT_ASSERT_EQUAL( static_cast(148), xBitmap->getSize().Height ); } CPPUNIT_TEST_FIXTURE(Test, testPlausableBorder) { loadAndSave("plausable-border.docx"); // sw::util::IsPlausableSingleWordSection() did not merge two page styles due to borders. xmlDocUniquePtr pXmlDoc = parseExport(); // Page break was exported as section break, this was 0 assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:br", 1); CPPUNIT_ASSERT_EQUAL( 2, getPages() ); } CPPUNIT_TEST_FIXTURE(Test, testUnwantedSectionBreak) { loadAndSave("unwanted-section-break.docx"); xmlDocUniquePtr pXmlDoc = parseExport(); // This was 2: an additional sectPr was added to the document. assertXPath(pXmlDoc, "//w:sectPr", 1); } CPPUNIT_TEST_FIXTURE(Test, testfdo80897 ) { loadAndSave("fdo80897.docx"); xmlDocUniquePtr pXmlDoc = parseExport(); assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:bodyPr/a:prstTxWarp", "prst", "textTriangle"); } DECLARE_OOXMLEXPORT_TEST(testFdo80997, "fdo80997.docx") { // The problem was that the DOCX exporter not able to export text behind textbox, if textbox has a wrap property. uno::Reference< text::XTextRange > xParagraph = getParagraph( 1 ); getRun( xParagraph, 1, " text"); } CPPUNIT_TEST_FIXTURE(Test, testFdo80902) { loadAndSave("fdo80902.docx"); // The problem was that the docGrid type was set as default so fix it for other grid type xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:docGrid", "type", "lines"); } CPPUNIT_TEST_FIXTURE(Test, testParaShading) { loadAndSave("para-shading.docx"); // Make sure the themeColor attribute is not written when it would be empty. xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:shd", "themeColor"); } DECLARE_OOXMLEXPORT_TEST(testFirstHeaderFooter, "first-header-footer.docx") { // Test import and export of a section's headerf/footerf properties. // (copied from a ww8export test, with doc converted to docx using Word) CPPUNIT_ASSERT_EQUAL( 6, getPages() ); // The document has 6 pages. Note that we don't test if 4 or just 2 page // styles are created, the point is that layout should be correct. CPPUNIT_ASSERT_EQUAL(OUString("First page header"), parseDump("/root/page[1]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("First page footer"), parseDump("/root/page[1]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Even page header"), parseDump("/root/page[2]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Even page footer"), parseDump("/root/page[2]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Odd page header"), parseDump("/root/page[3]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer"), parseDump("/root/page[3]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("First page header2"), parseDump("/root/page[4]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("First page footer 2"), parseDump("/root/page[4]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Odd page header 2"), parseDump("/root/page[5]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer 2"), parseDump("/root/page[5]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Even page header 2"), parseDump("/root/page[6]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Even page footer 2"), parseDump("/root/page[6]/footer/txt/text()")); } CPPUNIT_TEST_FIXTURE(Test, testFirstHeaderFooterB) { loadAndReload("first-header-footerB.odt"); CPPUNIT_ASSERT_EQUAL( 6, getPages() ); CPPUNIT_ASSERT_EQUAL(OUString("First page header"), parseDump("/root/page[1]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("First page footer"), parseDump("/root/page[1]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Even page header"), parseDump("/root/page[2]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Even page footer"), parseDump("/root/page[2]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Odd page header"), parseDump("/root/page[3]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer"), parseDump("/root/page[3]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("First page header2"), parseDump("/root/page[4]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("First page footer 2"), parseDump("/root/page[4]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Odd page header 2"), parseDump("/root/page[5]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer 2"), parseDump("/root/page[5]/footer/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Even page header 2"), parseDump("/root/page[6]/header/txt/text()")); CPPUNIT_ASSERT_EQUAL(OUString("Even page footer 2"), parseDump("/root/page[6]/footer/txt/text()")); } CPPUNIT_TEST_FIXTURE(Test, testFDO83044) { loadAndSave("fdo83044.docx"); xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:text", 1); } DECLARE_OOXMLEXPORT_TEST(testfdo83428, "fdo83428.docx") { uno::Reference xDocumentPropertiesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xProps(xDocumentPropertiesSupplier->getDocumentProperties()); uno::Reference xUDProps(xProps->getUserDefinedProperties(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("Document"), getProperty(xUDProps, "Testing")); } CPPUNIT_TEST_FIXTURE(Test, testShapeInFloattable) { loadAndSave("shape-in-floattable.docx"); xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); // No nested drawingML w:txbxContent. assertXPath(pXmlDoc, "//mc:Choice//w:txbxContent//w:txbxContent", 0); // Instead, make sure we have a separate shape and a table assertXPath(pXmlDoc, "//mc:AlternateContent//mc:Choice[@Requires='wpg']", 1); assertXPath(pXmlDoc, "/w:document/w:body/w:tbl", 1); } CPPUNIT_TEST_FIXTURE(Test, testEmptyAnnotationMark) { loadAndReload("empty-annotation-mark.docx"); // Delete the word that is commented, and save again. uno::Reference xRun = getRun(getParagraph(1), 3); CPPUNIT_ASSERT_EQUAL(OUString("with"), xRun->getString()); xRun->setString(""); uno::Reference xStorable(mxComponent, uno::UNO_QUERY); xStorable->store(); // Then inspect the OOXML markup of the modified document model. xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); // There were two commentReference nodes. assertXPath(pXmlDoc, "//w:commentReference", "id", "0"); // Empty comment range was not ignored on export, this was 1. assertXPath(pXmlDoc, "//w:commentRangeStart", 0); // Ditto. assertXPath(pXmlDoc, "//w:commentRangeEnd", 0); } DECLARE_OOXMLEXPORT_TEST(testDropdownInCell, "dropdown-in-cell.docx") { // First problem: table was missing from the document, this was 0. uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); // Second problem: dropdown shape wasn't anchored inside the B1 cell. if (getShapes() > 0) { uno::Reference xShape(getShape(1), uno::UNO_QUERY); uno::Reference xAnchor = xShape->getAnchor(); uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); uno::Reference xCell(xTable->getCellByName("B1"), uno::UNO_QUERY); uno::Reference xTextRangeCompare(xCell, uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int16(0), xTextRangeCompare->compareRegionStarts(xAnchor, xCell)); } else if (!mbExported) { // ComboBox was imported as DropDown text field uno::Reference xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xFieldsAccess(xTextFieldsSupplier->getTextFields()); uno::Reference xFields(xFieldsAccess->createEnumeration()); CPPUNIT_ASSERT(xFields->hasMoreElements()); uno::Any aField = xFields->nextElement(); uno::Reference xServiceInfo(aField, uno::UNO_QUERY); CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.textfield.DropDown")); } else { // DropDown text field is exported as inline SDT, we import that back here. 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); uno::Sequence aListItems; xContentControlProps->getPropertyValue("ListItems") >>= aListItems; CPPUNIT_ASSERT(aListItems.hasElements()); } } DECLARE_OOXMLEXPORT_TEST(testTableAlignment, "table-alignment.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); // This was LEFT_AND_WIDTH, i.e. table alignment wasn't imported correctly. CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::RIGHT, getProperty(xTable, "HoriOrient")); } CPPUNIT_TEST_FIXTURE(Test, testSdtIgnoredFooter) { loadAndSave("sdt-ignored-footer.docx"); xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); // This was 1, make sure no w:sdt sneaks into the main document from the footer. assertXPath(pXmlDoc, "//w:sdt", 0); } CPPUNIT_TEST_FIXTURE(Test, testSdtRunPicture) { loadAndSave("sdt-run-picture.docx"); // SDT around run was exported as SDT around paragraph xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); // This was 1: there was an SDT around w:p. assertXPath(pXmlDoc, "//w:body/w:sdt", 0); // This was 0: there were no SDT around w:r. assertXPath(pXmlDoc, "//w:body/w:p/w:sdt", 1); } DECLARE_OOXMLEXPORT_TEST(testChartDupe, "chart-dupe.docx") { // Single chart was exported back as two charts. uno::Reference xTextEmbeddedObjectsSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xEmbeddedObjects(xTextEmbeddedObjectsSupplier->getEmbeddedObjects(), uno::UNO_QUERY); // This was 2, on second import we got a duplicated chart copy. CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xEmbeddedObjects->getCount()); xmlDocUniquePtr pXmlDocCT = parseExport("[Content_Types].xml"); if (!pXmlDocCT) return; // initial import assertXPath(pXmlDocCT, "/ContentType:Types/ContentType:Override[@PartName='/word/charts/chart1.xml']", "ContentType", "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"); assertXPath(pXmlDocCT, "/ContentType:Types/ContentType:Override[@PartName='/word/embeddings/Microsoft_Excel_Worksheet1.xlsx']", "ContentType", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // check the rels too xmlDocUniquePtr pXmlDocRels = parseExport("word/charts/_rels/chart1.xml.rels"); assertXPath(pXmlDocRels, "/rels:Relationships/rels:Relationship[@Target='../embeddings/Microsoft_Excel_Worksheet1.xlsx']", "Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"); // check the content too xmlDocUniquePtr pXmlDocChart1 = parseExport("word/charts/chart1.xml"); assertXPath(pXmlDocChart1, "/c:chartSpace/c:externalData", "id", "rId1"); } DECLARE_OOXMLEXPORT_TEST(testPositionAndRotation, "position-and-rotation.docx") { // The document should look like: "This line is tricky, because only 'This line is tricky,' is on the left." // But the image was pushed down, so it did not break the line into two text portions. uno::Reference xShape = getShape(1); // Should be 1559, was -5639 CPPUNIT_ASSERT(xShape->getPosition().X > 1500); // Should be 88, was 473 CPPUNIT_ASSERT(xShape->getPosition().Y < 100); } DECLARE_OOXMLEXPORT_TEST(testNumberingFont, "numbering-font.docx") { // check that the original numrule font name is still Calibri uno::Reference xStyle(getStyles("CharacterStyles")->getByName("ListLabel 1"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("Calibri"), getProperty(xStyle, "CharFontName")); uno::Reference xPara = getParagraph(2); uno::Reference properties(xPara, uno::UNO_QUERY); uno::Any aValue = properties->getPropertyValue("ListAutoFormat"); CPPUNIT_ASSERT(aValue.hasValue()); uno::Sequence aListAutoFormat; CPPUNIT_ASSERT(aValue >>= aListAutoFormat); auto it = std::find_if(std::cbegin(aListAutoFormat), std::cend(aListAutoFormat), [](const css::beans::NamedValue& val) { return val.Name == "CharFontName"; }); CPPUNIT_ASSERT(it != std::cend(aListAutoFormat)); OUString sOverrideFontName; CPPUNIT_ASSERT(it->Value >>= sOverrideFontName); // but the overridden font name is Verdana CPPUNIT_ASSERT_EQUAL(OUString("Verdana"), sOverrideFontName); } CPPUNIT_TEST_FIXTURE(Test, testTdf106541_noinheritChapterNumbering) { loadAndReload("tdf106541_noinheritChapterNumbering.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); // in LO, it appears that styles based on the Chapter Numbering style explicitly set the // numbering style/outline level to 0 by default, and that LO prevents inheriting directly from "Outline" style. // Adding this preventative unit test to ensure that any fix for tdf106541 doesn't make incorrect assumptions. //reverting tdf#76817 hard-codes the numbering style on the paragraph, preventing RT of "Outline" style // CPPUNIT_ASSERT_EQUAL(OUString("Outline"), getProperty(getParagraph(1), "NumberingStyleName")); OUString sPara3NumberingStyle = getProperty(getParagraph(3), "NumberingStyleName"); CPPUNIT_ASSERT_EQUAL(sPara3NumberingStyle, getProperty(getParagraph(4), "NumberingStyleName")); xmlDocUniquePtr pXmlDoc = parseLayoutDump(); assertXPath(pXmlDoc, "//body/txt/Special", 3); //three of the four paragraphs have numbering assertXPath(pXmlDoc, "//body/txt[1]/Special", "rText", "1"); assertXPath(pXmlDoc, "//body/txt[2]/Special", 0); //second paragraph style disables numbering assertXPath(pXmlDoc, "//body/txt[3]/Special", "rText", "I."); assertXPath(pXmlDoc, "//body/txt[4]/Special", "rText", "II."); } DECLARE_OOXMLEXPORT_TEST(testTdf53856_conflictingStyle, "tdf53856_conflictingStyle.docx") { // The "Text" style conflicted with builtin paragraph style Caption -> Text uno::Reference xStyle(getStyles("ParagraphStyles")->getByName("Text"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("Times New Roman"), getProperty(xStyle, "CharFontName")); CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, getProperty(xStyle, "CharPosture")); } DECLARE_OOXMLEXPORT_TEST(testTdf104713_undefinedStyles, "tdf104713_undefinedStyles.docx") { // Normal paragraph style was not defined, so don't replace conflicting styles uno::Reference xStyle(getStyles("ParagraphStyles")->getByName("Heading 1"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(212), getProperty(xStyle, "ParaBottomMargin")); // tdf108765: once importing is finished, use default values for any styles not yet defined. xStyle.set( getStyles("ParagraphStyles")->getByName("Footnote"), uno::UNO_QUERY ); CPPUNIT_ASSERT_EQUAL_MESSAGE("Font size", 10.f, getProperty(xStyle, "CharHeight")); } CPPUNIT_TEST_FIXTURE(Test, testDrawingmlFlipv) { loadAndSave("drawingml-flipv.docx"); // The problem was that the shape had vertical flip only, but then we added rotation as well on export. xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); assertXPathNoAttribute(pXmlDoc, "//a:xfrm", "rot"); } CPPUNIT_TEST_FIXTURE(Test, testRot90Fliph) { loadAndSave("rot90-fliph.docx"); // The problem was that a shape rotation of 90° got turned into 270° after roundtrip. xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); assertXPath(pXmlDoc, "//a:xfrm", "flipH", "1"); // This was 16200000 (270 * 60000). assertXPath(pXmlDoc, "//a:xfrm", "rot", "5400000"); } CPPUNIT_TEST_FIXTURE(Test, testRot180Flipv) { loadAndSave("rot180-flipv.docx"); // 180° rotation got lost after roundtrip. xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); assertXPath(pXmlDoc, "//a:xfrm", "flipV", "1"); // This attribute was completely missing. assertXPath(pXmlDoc, "//a:xfrm", "rot", "10800000"); } CPPUNIT_TEST_FIXTURE(Test, testRot270Flipv) { loadAndSave("rot270-flipv.docx"); // 270° rotation got turned into 90° after roundtrip. xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); assertXPath(pXmlDoc, "//a:xfrm", "flipV", "1"); // This was 5400000. assertXPath(pXmlDoc, "//a:xfrm", "rot", "16200000"); } CPPUNIT_TEST_FIXTURE(Test, testMsoPosition) { loadAndSave("bnc884615-mso-position.docx"); { xmlDocUniquePtr doc = parseExport("word/footer1.xml"); // We write the frames out in different order than they were read, so check it's the correct // textbox first by checking width. These tests may need reordering if that gets fixed. OUString style1 = getXPath(doc, "/w:ftr/w:p/w:r[3]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style"); CPPUNIT_ASSERT( style1.indexOf( ";width:531pt;" ) >= 0 ); CPPUNIT_ASSERT( style1.indexOf( ";mso-position-vertical-relative:page" ) >= 0 ); CPPUNIT_ASSERT( style1.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 ); OUString style2 = getXPath(doc, "/w:ftr/w:p/w:r[4]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style"); CPPUNIT_ASSERT( style2.indexOf( ";width:549pt;" ) >= 0 ); CPPUNIT_ASSERT( style2.indexOf( ";mso-position-vertical-relative:text" ) >= 0 ); CPPUNIT_ASSERT( style2.indexOf( ";mso-position-horizontal:center" ) >= 0 ); CPPUNIT_ASSERT( style2.indexOf( ";mso-position-horizontal-relative:text" ) >= 0 ); OUString style3 = getXPath(doc, "/w:ftr/w:p/w:r[5]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style"); CPPUNIT_ASSERT( style3.indexOf( ";width:36pt;" ) >= 0 ); CPPUNIT_ASSERT( style3.indexOf( ";mso-position-horizontal-relative:text" ) >= 0 ); CPPUNIT_ASSERT( style3.indexOf( ";mso-position-vertical-relative:text" ) >= 0 ); } xmlDocUniquePtr doc = parseExport("word/header1.xml"); OUString style1 = getXPath(doc, "/w:hdr/w:p/w:r[2]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style"); CPPUNIT_ASSERT( style1.indexOf( ";width:335.75pt;" ) >= 0 ); CPPUNIT_ASSERT( style1.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 ); CPPUNIT_ASSERT( style1.indexOf( ";mso-position-vertical-relative:page" ) >= 0 ); OUString style2 = getXPath(doc, "/w:hdr/w:p/w:r[3]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style"); CPPUNIT_ASSERT( style2.indexOf( ";width:138.15pt;" ) >= 0 ); CPPUNIT_ASSERT( style2.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 ); CPPUNIT_ASSERT( style2.indexOf( ";mso-position-vertical-relative:page" ) >= 0 ); OUString style3 = getXPath(doc, "/w:hdr/w:p/w:r[4]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style"); CPPUNIT_ASSERT( style3.indexOf( ";width:163.8pt;" ) >= 0 ); CPPUNIT_ASSERT( style3.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 ); CPPUNIT_ASSERT( style3.indexOf( ";mso-position-vertical-relative:page" ) >= 0 ); } DECLARE_OOXMLEXPORT_TEST(testWpsCharColor, "wps-char-color.docx") { uno::Reference xShape(getShape(1), uno::UNO_QUERY); // This was -1, i.e. the character color was default (-1), not white. CPPUNIT_ASSERT_EQUAL(COL_WHITE, getProperty(xShape->getStart(), "CharColor")); } DECLARE_OOXMLEXPORT_TEST(testTableStyleCellBackColor, "table-style-cell-back-color.docx") { // The problem was that cell background was white, not green. 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 xCell = xTable->getCellByName("A1"); // This was 0xffffff. CPPUNIT_ASSERT_EQUAL(Color(0x00ff00), getProperty(xCell, "BackColor")); } DECLARE_OOXMLEXPORT_TEST(testTableStyleBorder, "table-style-border.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); // This was 0, the second cell was missing its right border. uno::Reference xCell = xTable->getCellByName("A2"); CPPUNIT_ASSERT(getProperty(xCell, "RightBorder").LineWidth > 0); // This was also 0 (even after fixing the previous problem), the first cell was missing its right border, too. xCell = xTable->getCellByName("A1"); CPPUNIT_ASSERT(getProperty(xCell, "RightBorder").LineWidth > 0); } DECLARE_OOXMLEXPORT_TEST(testTableStyleBorderExport, "table-style-border-export.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 xCell = xTable->getCellByName("A3"); // Bottom border was white, so this was 0xffffff. CPPUNIT_ASSERT_EQUAL(Color(0x8064A2), Color(ColorTransparency, getProperty(xCell, "BottomBorder").Color)); } DECLARE_OOXMLEXPORT_TEST(testAnchorPosition, "anchor-position.docx") { // The problem was that the at-char anchored picture was at the end of the // paragraph, so there were only two positions: a Text, then a Frame one. CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty(getRun(getParagraph(1), 1), "TextPortionType")); CPPUNIT_ASSERT_EQUAL(OUString("Frame"), getProperty(getRun(getParagraph(1), 2), "TextPortionType")); CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty(getRun(getParagraph(1), 3), "TextPortionType")); } DECLARE_OOXMLEXPORT_TEST(testMultiPageToc, "multi-page-toc.docx") { // Import of this document triggered an STL assertion. // Document has a ToC from its second paragraph. uno::Reference xTextSection = getProperty< uno::Reference >(getParagraph(2), "TextSection"); CPPUNIT_ASSERT_EQUAL(OUString("Table of Contents1"), xTextSection->getName()); // There should be a field in the header as well. uno::Reference xHeaderText = getProperty< uno::Reference >(getStyles("PageStyles")->getByName("Standard"), "HeaderText"); CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), getProperty(getRun(getParagraphOfText(1, xHeaderText), 1), "TextPortionType")); } DECLARE_OOXMLEXPORT_TEST(testTextboxTable, "textbox-table.docx") { // We wrote not-well-formed XML during export for this one: // Shape with textbox, having a table and also anchored inside a table. // Just make sure that we have both tables. uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount()); } CPPUNIT_TEST_FIXTURE(Test, testCropPixel) { loadAndSave("crop-pixel.docx"); // If map mode of the graphic is in pixels, then we used to handle original // size of the graphic as mm100, but it was in pixels. xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); // This is 17667 in the original document, was 504666 (so the image // become invisible), now is around 19072. CPPUNIT_ASSERT(getXPath(pXmlDoc, "//a:srcRect", "l").toInt32() <= 22452); } /* FixMe: tdf#142805 Test disabled, because the picture is not load at all. CPPUNIT_TEST_FIXTURE(Test, testEffectExtent) { loadAndSave("effect-extent.docx"); // The problem was that in case there were no shadows on the picture, we // wrote a full or zeros. xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); // E.g. this was 0. assertXPath(pXmlDoc, "//wp:effectExtent", "l", "114300"); } */ CPPUNIT_TEST_FIXTURE(Test, testEffectExtentInline) { loadAndSave("effect-extent-inline.docx"); // The problem was that in case there was inline rotated picture, we // wrote a full or zeros. xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); // E.g. this was 0. assertXPath(pXmlDoc, "//wp:effectExtent", "l", "609600"); assertXPath(pXmlDoc, "//wp:effectExtent", "r", "590550"); assertXPath(pXmlDoc, "//wp:effectExtent", "t", "590550"); assertXPath(pXmlDoc, "//wp:effectExtent", "b", "571500"); } DECLARE_OOXMLEXPORT_TEST(testEm, "em.docx") { // Test all possible arguments. CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::NONE, getProperty(getRun(getParagraph(1), 1), "CharEmphasis")); // This was ACCENT_ABOVE. CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::DOT_ABOVE, getProperty(getRun(getParagraph(1), 2), "CharEmphasis")); // This was DOT_ABOVE. CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::ACCENT_ABOVE, getProperty(getRun(getParagraph(1), 3), "CharEmphasis")); CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::CIRCLE_ABOVE, getProperty(getRun(getParagraph(1), 4), "CharEmphasis")); CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::DOT_BELOW, getProperty(getRun(getParagraph(1), 5), "CharEmphasis")); } DECLARE_OOXMLEXPORT_TEST(testFdo77716, "fdo77716.docx") { // The problem was that there should be 200 twips spacing between the two paragraphs, but there wasn't any. uno::Reference xStyle(getStyles("ParagraphStyles")->getByName("Standard"), uno::UNO_QUERY); // This was 0. CPPUNIT_ASSERT_EQUAL(static_cast(convertTwipToMm100(200)), getProperty(xStyle, "ParaBottomMargin")); } DECLARE_OOXMLEXPORT_TEST(testAfterlines, "afterlines.docx") { // This was 353, i.e. the value of from , instead of from . CPPUNIT_ASSERT_EQUAL(static_cast(423), getProperty(getParagraph(1), "ParaBottomMargin")); } DECLARE_OOXMLEXPORT_TEST(testParagraphMark, "paragraph-mark.docx") { // The problem was that we didn't handle the situation when an empty paragraph's marker had both a char style and some direct formatting. // This was 11. CPPUNIT_ASSERT_EQUAL(12.f, getProperty(getParagraph(1), "CharHeight")); // This was empty. CPPUNIT_ASSERT_EQUAL(OUString("Emphasis"), getProperty(getRun(getParagraph(1), 1), "CharStyleName")); } DECLARE_OOXMLEXPORT_TEST(testParagraphMark2, "paragraph-mark2.docx") { // The problem was that we didn't handle the situation when an empty paragraph's marker had both a char style and some direct formatting. // This was Segoe UI, set by Char Style FontStyle11 presumably. CPPUNIT_ASSERT_EQUAL(OUString("Arial"), getProperty(getRun(getParagraph(1), 1), "CharFontName")); // This was 11, set by Char Style FontStyle11 presumably. CPPUNIT_ASSERT_EQUAL(10.f, getProperty(getRun(getParagraph(1), 1), "CharHeight")); } CPPUNIT_TEST_FIXTURE(Test, testParagraphMarkNonempty) { loadAndSave("paragraph-mark-nonempty.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); xmlDocUniquePtr pXmlDoc = parseExport(); // There were two elements, make sure the 40 one is dropped and the 20 one is kept. assertXPath(pXmlDoc, "//w:p/w:pPr/w:rPr/w:sz", "val", "20"); } DECLARE_OOXMLEXPORT_TEST(testPageBreakBefore, "page-break-before.docx") { // This was style::BreakType_PAGE_BEFORE, i.e. page break wasn't ignored, as it should have been. CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, getProperty(getParagraph(2), "BreakType")); } DECLARE_OOXMLEXPORT_TEST(testTableRtl, "table-rtl.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); // This was text::WritingMode2::LR_TB, i.e. direction of the table was ignored. CPPUNIT_ASSERT_EQUAL(text::WritingMode2::RL_TB, getProperty(xTable, "WritingMode")); } DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist30, "cjklist30.docx") { sal_Int16 numFormat = getNumberingTypeOfParagraph(1); CPPUNIT_ASSERT_EQUAL(style::NumberingType::TIAN_GAN_ZH, numFormat); } DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist31, "cjklist31.docx") { sal_Int16 numFormat = getNumberingTypeOfParagraph(1); CPPUNIT_ASSERT_EQUAL(style::NumberingType::DI_ZI_ZH, numFormat); } DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist34, "cjklist34.docx") { sal_Int16 numFormat = getNumberingTypeOfParagraph(1); CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_UPPER_ZH_TW, numFormat); } DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist35, "cjklist35.docx") { sal_Int16 numFormat = getNumberingTypeOfParagraph(1); CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_LOWER_ZH, numFormat); } DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist44, "cjklist44.docx") { sal_Int16 numFormat = getNumberingTypeOfParagraph(1); CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_DIGITAL2_KO, numFormat); } DECLARE_OOXMLEXPORT_TEST(testOoxmlTextNumberList, "text_number_list.docx") { sal_Int16 numFormat = getNumberingTypeOfParagraph(1); CPPUNIT_ASSERT_EQUAL(style::NumberingType::TEXT_NUMBER, numFormat); } DECLARE_OOXMLEXPORT_TEST(testOoxmlTextCardinalList, "text_cardinal_list.docx") { sal_Int16 numFormat = getNumberingTypeOfParagraph(1); CPPUNIT_ASSERT_EQUAL(style::NumberingType::TEXT_CARDINAL, numFormat); } DECLARE_OOXMLEXPORT_TEST(testOoxmlTextOrdinalList, "text_ordinal_list.docx") { sal_Int16 numFormat = getNumberingTypeOfParagraph(1); CPPUNIT_ASSERT_EQUAL(style::NumberingType::TEXT_ORDINAL, numFormat); } DECLARE_OOXMLEXPORT_TEST(testOoxmlSymbolChicagoList, "symbol_chicago_list.docx") { sal_Int16 numFormat = getNumberingTypeOfParagraph(1); CPPUNIT_ASSERT_EQUAL(style::NumberingType::SYMBOL_CHICAGO, numFormat); } CPPUNIT_TEST_FIXTURE(Test, testOoxmlNumListZHTW) { loadAndSave("numlist-zhtw.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); xmlDocUniquePtr pXmlDoc = parseExport("word/numbering.xml"); assertXPath ( pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:numFmt","val","taiwaneseCountingThousand" ); } CPPUNIT_TEST_FIXTURE(Test, testOoxmlNumListZHCN) { loadAndSave("numlist-zhcn.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); xmlDocUniquePtr pXmlDoc = parseExport("word/numbering.xml"); assertXPath ( pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:numFmt","val","chineseCountingThousand" ); } CPPUNIT_TEST_FIXTURE(Test, testOOxmlOutlineNumberTypes) { loadAndSave("outline-number-types.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); xmlDocUniquePtr pXmlDoc = parseExport("word/numbering.xml"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:pStyle", "val", "Heading1"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:numFmt", "val", "none"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[2]/w:numFmt", "val", "decimalEnclosedCircle"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[3]/w:numFmt", "val", "decimal"); // CHARS_GREEK_UPPER_LETTER fallback to decimal assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[4]/w:numFmt", "val", "decimal"); // CHARS_GREEK_LOWER_LETTER fallback to decimal assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[5]/w:numFmt", "val", "arabicAlpha"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[6]/w:numFmt", "val", "hindiVowels"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[7]/w:numFmt", "val", "thaiLetters"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[1]/w:numFmt", "val", "decimal"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[2]/w:numFmt", "val", "decimal"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[3]/w:numFmt", "val", "decimal"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[4]/w:numFmt", "val", "decimal"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[5]/w:numFmt", "val", "russianUpper"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[6]/w:numFmt", "val", "russianLower"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[7]/w:numFmt", "val", "russianUpper"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[8]/w:numFmt", "val", "russianLower"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[1]/w:numFmt", "val", "decimal"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[2]/w:numFmt", "val", "decimal"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[3]/w:numFmt", "val", "decimal"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[4]/w:numFmt", "val", "decimal"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[5]/w:numFmt", "val", "decimal"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[6]/w:numFmt", "val", "decimal"); assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[7]/w:numFmt", "val", "decimal"); } DECLARE_OOXMLEXPORT_TEST(testNumParentStyle, "num-parent-style.docx") { CPPUNIT_ASSERT_EQUAL(static_cast(1), getProperty(getParagraph(1), "OutlineLevel")); CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty(getParagraph(1), "ListLabelString")); CPPUNIT_ASSERT_EQUAL(static_cast(2), getProperty(getParagraph(2), "OutlineLevel")); CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty(getParagraph(2), "ListLabelString")); CPPUNIT_ASSERT_EQUAL(static_cast(1), getProperty(getParagraph(3), "OutlineLevel")); CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty(getParagraph(3), "ListLabelString")); CPPUNIT_ASSERT_EQUAL(static_cast(2), getProperty(getParagraph(4), "OutlineLevel")); CPPUNIT_ASSERT_EQUAL(OUString("2.1"), getProperty(getParagraph(4), "ListLabelString")); } DECLARE_OOXMLEXPORT_TEST(testNumOverrideLvltext, "num-override-lvltext.docx") { uno::Reference xRules = getProperty< uno::Reference >(getStyles("NumberingStyles")->getByName("WWNum1"), "NumberingRules"); // This was 1, i.e. the numbering on the second level was "1", not "1.1". // Check the paragraph properties, not the list ones, since they can differ due to overrides uno::Reference xPara(getParagraph(1), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(1), getProperty(xPara, "NumberingLevel")); CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty(xPara, "ListLabelString")); // The paragraph marker's red font color was inherited by the number portion, this was ff0000. CPPUNIT_ASSERT_EQUAL(OUString("ffffffff"), parseDump("//Special[@nType='PortionType::Number']/SwFont", "color")); } DECLARE_OOXMLEXPORT_TEST(testNumOverrideStart, "num-override-start.docx") { uno::Reference xRules = getProperty< uno::Reference >(getStyles("NumberingStyles")->getByName("WWNum1"), "NumberingRules"); // List starts with "1.1" CPPUNIT_ASSERT_EQUAL(sal_Int16(1), comphelper::SequenceAsHashMap(xRules->getByIndex(1))["StartWith"].get()); // But paragraph starts with "1.3" uno::Reference xPara(getParagraph(1), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(1), getProperty(xPara, "NumberingLevel")); OUString listId; CPPUNIT_ASSERT(xPara->getPropertyValue("ListId") >>= listId); CPPUNIT_ASSERT_EQUAL(OUString("1.3"), getProperty(xPara, "ListLabelString")); } DECLARE_OOXMLEXPORT_TEST(testTextboxRightEdge, "textbox-right-edge.docx") { // I'm fairly sure this is not specific to DOCX, but the doc model created // by the ODF import doesn't trigger this bug, so let's test this here // instead of uiwriter. int nShapeLeft = parseDump("//anchored/SwAnchoredDrawObject/bounds", "left").toInt32(); int nShapeWidth = parseDump("//anchored/SwAnchoredDrawObject/bounds", "width").toInt32(); int nTextboxLeft = parseDump("//anchored/fly/infos/bounds", "left").toInt32(); int nTextboxWidth = parseDump("//anchored/fly/infos/bounds", "width").toInt32(); // This is a rectangle, make sure the right edge of the textbox is still // inside the draw shape. CPPUNIT_ASSERT(nShapeLeft + nShapeWidth >= nTextboxLeft + nTextboxWidth); } DECLARE_OOXMLEXPORT_TEST(testEffectExtentMargin, "effectextent-margin.docx") { // This was 318, i.e. oox::drawingml::convertEmuToHmm(114300), effectExtent // wasn't part of the margin, leading to the fly not taking enough space // around itself. CPPUNIT_ASSERT_EQUAL(oox::drawingml::convertEmuToHmm(114300+95250), getProperty(getShape(1), "LeftMargin")); } CPPUNIT_TEST_FIXTURE(Test, testTdf88583) { loadAndReload("tdf88583.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty(getParagraph(1), "FillStyle")); CPPUNIT_ASSERT_EQUAL(static_cast(0x00cc00), getProperty(getParagraph(1), "FillColor")); } DECLARE_OOXMLEXPORT_TEST(testTdf97090, "tdf97090.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); CPPUNIT_ASSERT_EQUAL(Color(0x95B3D7), getProperty(xTable->getCellByName("A1"), "BackColor")); uno::Reference paraEnumAccess(xTable->getCellByName("A1"), uno::UNO_QUERY); assert( paraEnumAccess.is() ); uno::Reference paraEnum = paraEnumAccess->createEnumeration(); assert( paraEnum.is() ); uno::Reference paragraphProperties(paraEnum->nextElement(), uno::UNO_QUERY); assert( paragraphProperties.is() ); CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty(paragraphProperties, "FillStyle")); CPPUNIT_ASSERT_EQUAL(Color(0xffffff), getProperty(paragraphProperties, "FillColor")); } DECLARE_OOXMLEXPORT_TEST(testTdf89791, "tdf89791.docx") { if (mbExported) { uno::Reference xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL()); CPPUNIT_ASSERT_EQUAL(false, bool(xNameAccess->hasByName("docProps/custom.xml"))); } //tdf#102619 - setting FollowStyle with a not-yet-created style was failing. (Titre is created before Corps de texte). uno::Reference< beans::XPropertySet > properties(getStyles("ParagraphStyles")->getByName("Titre"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("Corps de texte"), getProperty(properties, "FollowStyle")); } DECLARE_OOXMLEXPORT_TEST(testTdf91261, "tdf91261.docx") { bool snapToGrid = true; uno::Reference< text::XTextRange > xPara = getParagraph( 2 ); uno::Reference< beans::XPropertySet > properties( xPara, uno::UNO_QUERY); properties->getPropertyValue("SnapToGrid") >>= snapToGrid ; CPPUNIT_ASSERT_EQUAL(false, snapToGrid); uno::Reference< beans::XPropertySet> xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); sal_Int16 nGridMode; xStyle->getPropertyValue("GridMode") >>= nGridMode; CPPUNIT_ASSERT_EQUAL( sal_Int16(2), nGridMode); bool bGridSnapToChars; xStyle->getPropertyValue("GridSnapToChars") >>= bGridSnapToChars; CPPUNIT_ASSERT_EQUAL(true, bGridSnapToChars); } DECLARE_OOXMLEXPORT_TEST(testTdf79639, "tdf79639.docx") { // This was 0, floating table in header wasn't converted to a TextFrame. CPPUNIT_ASSERT_EQUAL(1, getShapes()); } DECLARE_OOXMLEXPORT_TEST(testTdf89890, "tdf89890.docx") { // Numbering picture bullet was too large. uno::Reference xPropertySet(getStyles("NumberingStyles")->getByName("WWNum1"), uno::UNO_QUERY); uno::Reference xLevels(xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY); uno::Sequence aProps; xLevels->getByIndex(0) >>= aProps; // 1st level bool bFound = false; for (beans::PropertyValue const & rProp : std::as_const(aProps)) { if (rProp.Name == "GraphicSize") { // Height of the graphic was too large: 4382 after import, then 2485 after roundtrip. CPPUNIT_ASSERT_EQUAL(static_cast(279), rProp.Value.get().Height); bFound = true; } } CPPUNIT_ASSERT(bFound); } DECLARE_OOXMLEXPORT_TEST(testTdf91594, "tdf91594.docx") { uno::Reference xPara1(getParagraph(1)); CPPUNIT_ASSERT_EQUAL(u'\xf0fb', xPara1->getString()[0] ); uno::Reference xPara2(getParagraph(2)); CPPUNIT_ASSERT_EQUAL(u'\xf0fc', xPara2->getString()[0] ); uno::Reference xPara3(getParagraph(3)); CPPUNIT_ASSERT_EQUAL(u'\xf0fd', xPara3->getString()[0] ); uno::Reference xPara4(getParagraph(4)); CPPUNIT_ASSERT_EQUAL(u'\xf0fe', xPara4->getString()[0] ); uno::Reference xRun(getRun(xPara1,1), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), getProperty(xRun, "CharFontName")); CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), getProperty(xRun, "CharFontNameAsian")); CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), getProperty(xRun, "CharFontNameComplex")); } DECLARE_OOXMLEXPORT_TEST(testTDF99434, "protectedform.docx") { css::uno::Reference m_xTextFactory(mxComponent, uno::UNO_QUERY); uno::Reference< beans::XPropertySet > xSettings(m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY); uno::Any aProtect = xSettings->getPropertyValue("ProtectForm"); bool bProt = false; aProtect >>= bProt; CPPUNIT_ASSERT(bProt); } DECLARE_OOXMLEXPORT_TEST(testTdf44986, "tdf44986.docx") { // Check that the table at the second paragraph. uno::Reference xTable(getParagraphOrTable(2), uno::UNO_QUERY); uno::Reference xTableRows = xTable->getRows(); // Check the first row of the table, it should have two cells (one separator). // This was 0: the first row had no separators, so it had only one cell, which was too wide. CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty< uno::Sequence >(xTableRows->getByIndex(0), "TableColumnSeparators").getLength()); // Check content of cells, including the newly added gridAfter cell CPPUNIT_ASSERT_EQUAL(OUString("A1"), uno::Reference(xTable->getCellByName("A1"), uno::UNO_QUERY_THROW)->getString()); CPPUNIT_ASSERT_EQUAL(OUString("A2"), uno::Reference(xTable->getCellByName("A2"), uno::UNO_QUERY_THROW)->getString()); CPPUNIT_ASSERT_EQUAL(OUString(""), uno::Reference(xTable->getCellByName("B1"), uno::UNO_QUERY_THROW)->getString()); } CPPUNIT_TEST_FIXTURE(Test, testTdf118682) { loadAndSave("tdf118682.fodt"); // Support cell references in table formulas xmlDocUniquePtr pXmlDoc = parseExport(); // Formula fields were completely missing. assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r/w:fldChar", 3); assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r/w:fldChar", 3); // Cell references were parenthesized: + and SUM() assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:instrText", " =A1+A2"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:instrText", " =SUM(A1:A3)"); } CPPUNIT_TEST_FIXTURE(Test, testTdf133163) { loadAndSave("tdf133163.fodt"); xmlDocUniquePtr pXmlDoc = parseExport(); // Formula cells were completely missing. assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r/w:fldChar", 3); assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r/w:fldChar", 3); // Cell references were parenthesized: + and SUM() assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:instrText", " =A1+A2"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:instrText", " =SUM(A1:A3)"); } CPPUNIT_TEST_FIXTURE(Test, testTdf133647) { loadAndSave("tdf133647.docx"); xmlDocUniquePtr pXmlDoc = parseExport(); // Keep original formula during round-trip assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[4]/w:p/w:r[2]/w:instrText", " =SUM(A1,B1)"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc[4]/w:p/w:r[2]/w:instrText", " =SUM(C1:D1)"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc[4]/w:p/w:r[2]/w:instrText", " =SUM(A1,5,B1:C1,6)"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[7]/w:tc[4]/w:p/w:r[2]/w:instrText", " =(1+2)*SUM(C1,D1)"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[8]/w:tc[4]/w:p/w:r[2]/w:instrText", " =3*(2+SUM(A1:C1)+7)"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[9]/w:tc[4]/w:p/w:r[2]/w:instrText", " =1+(SUM(1,2))"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[10]/w:tc[4]/w:p/w:r[2]/w:instrText", " =(SUM(C1,5)*(2+7))*(3+SUM(1,B1))"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[11]/w:tc[4]/w:p/w:r[2]/w:instrText", " =sum(a1,b1)"); } CPPUNIT_TEST_FIXTURE(Test, testTdf123386) { loadAndSave("tdf123386.docx"); xmlDocUniquePtr pXmlDoc = parseExport(); // Keep original formula during round-trip assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc[4]/w:p/w:r[2]/w:instrText", " =A1 < 2"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[4]/w:p/w:r[2]/w:instrText", " =B1 > 1"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc[4]/w:p/w:r[2]/w:instrText", " =C1=3"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc[4]/w:p/w:r[2]/w:instrText", " =D1 <> 3"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[7]/w:tc[4]/w:p/w:r[2]/w:instrText", " =AND(A1=1,B1=2)"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[8]/w:tc[4]/w:p/w:r[2]/w:instrText", " =AND((A1<1),(B1<>2))"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[9]/w:tc[4]/w:p/w:r[2]/w:instrText", " =OR(A1=1,B1=2)"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[10]/w:tc[4]/w:p/w:r[2]/w:instrText", " =OR(TRUE,FALSE)"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[11]/w:tc[4]/w:p/w:r[2]/w:instrText", " =NOT(TRUE)"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[12]/w:tc[4]/w:p/w:r[2]/w:instrText", " =AND(1,DEFINED(ABC1))"); } CPPUNIT_TEST_FIXTURE(Test, testTdf123389) { loadAndSave("tdf123389.docx"); xmlDocUniquePtr pXmlDoc = parseExport(); // Keep original formula during round-trip assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc[4]/w:p/w:r[2]/w:instrText", " =ROUND(2.345,1)"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[4]/w:p/w:r[2]/w:instrText", " =ROUND(A1,2)"); } DECLARE_OOXMLEXPORT_TEST(testTdf106953, "tdf106953.docx") { uno::Reference xRules = getProperty< uno::Reference >(getStyles("NumberingStyles")->getByName("WWNum1"), "NumberingRules"); // This was -635, so the tab of the numbering expanded to a small value instead of matching Word's larger value. CPPUNIT_ASSERT_EQUAL(static_cast(0), comphelper::SequenceAsHashMap(xRules->getByIndex(0))["FirstLineIndent"].get()); } CPPUNIT_TEST_FIXTURE(Test, testTdf115094v3) { loadAndSave("tdf115094v3.docx"); // floating table is now exported directly without surrounding frame xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblpPr", "tblpX", "1996"); assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblpPr", "tblpY", "1064"); } CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */