/* -*- 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 class Test : public SwModelTestBase { public: Test() : SwModelTestBase("/sw/qa/extras/ww8export/data/", "MS Word 97") { } }; DECLARE_WW8EXPORT_TEST(testTdf37778_readonlySection, "tdf37778_readonlySection.doc") { uno::Reference xStorable(mxComponent, uno::UNO_QUERY); CPPUNIT_ASSERT( xStorable->isReadonly() ); uno::Reference xTextSectionsSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY); // The problem was that section protection was being enabled in addition to being read-only. // This created an explicit section with protection. There should be just the default, non-explicit section. CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of Sections", sal_Int32(0), xSections->getCount()); // tdf#127862: page fill color (in this case white) was lost uno::Reference xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); CPPUNIT_ASSERT(drawing::FillStyle_NONE != getProperty(xStyle, "FillStyle")); // tdf#136983 uno::Reference xDPS(mxComponent, uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL_MESSAGE("Last printed date", sal_Int16(2009), xDPS->getDocumentProperties()->getPrintDate().Year); } DECLARE_WW8EXPORT_TEST(testTdf100961_fixedDateTime, "tdf100961_fixedDateTime.doc") { // This should be a fixed date/time field, not the current time. getParagraph(1, "05.01.19 04:06:08"); css::uno::Reference xSupplier(mxComponent, css::uno::UNO_QUERY_THROW); auto xFieldsAccess(xSupplier->getTextFields()); auto xFields(xFieldsAccess->createEnumeration()); css::uno::Reference xField(xFields->nextElement(), css::uno::UNO_QUERY); // Check fixed property was imported and date value was parsed correctly CPPUNIT_ASSERT_EQUAL(true, getProperty(xField, "IsFixed")); CPPUNIT_ASSERT_EQUAL(true, getProperty(xField, "IsDate")); auto datetime = getProperty(xField, "DateTimeValue"); CPPUNIT_ASSERT_EQUAL(sal_uInt16(5), datetime.Day); CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), datetime.Month); CPPUNIT_ASSERT_EQUAL(sal_Int16(2019), datetime.Year); xField.set(xFields->nextElement(), css::uno::UNO_QUERY); // Check fixed property was imported and time value was parsed correctly CPPUNIT_ASSERT_EQUAL(true, getProperty(xField, "IsFixed")); CPPUNIT_ASSERT_EQUAL(false, getProperty(xField, "IsDate")); datetime = getProperty(xField, "DateTimeValue"); CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), datetime.Hours); CPPUNIT_ASSERT_EQUAL(sal_uInt16(6), datetime.Minutes); CPPUNIT_ASSERT_EQUAL(sal_uInt16(8), datetime.Seconds); } DECLARE_WW8EXPORT_TEST(testTdf147861_customField, "tdf147861_customField.doc") { // These should each be specific values, not a shared DocProperty getParagraph(1, "CustomEditedTitle"); // edited // A couple of \x0\x0 at the end of the import variable thwart an equality comparison CPPUNIT_ASSERT(getParagraph(2)->getString().startsWith(" INSERT Custom Title here")); getParagraph(3, "My Title"); // edited // Verify that these are fields, and not just plain text uno::Reference xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); auto xFieldsAccess(xTextFieldsSupplier->getTextFields()); uno::Reference xFields(xFieldsAccess->createEnumeration()); uno::Reference xField(xFields->nextElement(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("CustomEditedTitle"), xField->getPresentation(false)); // The " (fixed)" part is unnecessary, but it must be consistent across a round-trip CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Title (fixed)"), xField->getPresentation(true)); } DECLARE_WW8EXPORT_TEST(testTdf148380_createField, "tdf148380_createField.doc") { // Verify that these are fields, and not just plain text uno::Reference xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); auto xFieldsAccess(xTextFieldsSupplier->getTextFields()); uno::Reference xFields(xFieldsAccess->createEnumeration()); uno::Reference xField(xFields->nextElement(), uno::UNO_QUERY); // This should NOT be "Lorenzo Chavez", or a real date since the user hand-modified the result. CPPUNIT_ASSERT_EQUAL(OUString("Myself - that's who"), xField->getPresentation(false)); xField.set(xFields->nextElement(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("yesterday at noon"), xField->getPresentation(false)); } DECLARE_WW8EXPORT_TEST(testTdf148380_fldLocked, "tdf148380_fldLocked.doc") { getParagraph(2, "4/5/2022 4:29:00 PM"); getParagraph(4, "1/23/4567 8:9:10 PM"); // Verify that these are fields, and not just plain text // (import only, since export thankfully just dumps these fixed fields as plain text if (isExported()) return; uno::Reference xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); auto xFieldsAccess(xTextFieldsSupplier->getTextFields()); uno::Reference xFields(xFieldsAccess->createEnumeration()); uno::Reference xField(xFields->nextElement(), uno::UNO_QUERY); // This should NOT be updated at FILEOPEN to match the last modified time - it is locked. CPPUNIT_ASSERT_EQUAL(OUString("4/5/2022 4:29:00 PM"), xField->getPresentation(false)); CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Modified (fixed)"), xField->getPresentation(true)); xField.set(xFields->nextElement(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("1/23/4567 8:9:10 PM"), xField->getPresentation(false)); CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Last printed (fixed)"), xField->getPresentation(true)); } DECLARE_WW8EXPORT_TEST(testTdf138345_paraCharHighlight, "tdf138345_paraCharHighlight.doc") { uno::Reference xRun(getRun(getParagraph(9), 1, "A side benefit is that "), uno::UNO_QUERY_THROW); // Paragraph style paraNoCharBackground cancel paraCharBackground using COL_TRANSPARENT. // Before this fix, the paragraph was by default covered with a yellow CharHighlight. CPPUNIT_ASSERT_EQUAL(static_cast(COL_AUTO), getProperty(xRun, "CharHighlight")); CPPUNIT_ASSERT_EQUAL(static_cast(COL_AUTO), getProperty(xRun, "CharBackColor")); xRun.set(getRun(getParagraph(9), 2), uno::UNO_QUERY_THROW); // Character style formatting must not contain a highlight setting at all. CPPUNIT_ASSERT_EQUAL(static_cast(COL_AUTO), getProperty(xRun, "CharHighlight")); CPPUNIT_ASSERT_EQUAL(static_cast(COL_AUTO), getProperty(xRun, "CharBackColor")); //tdf#118711 - don't explicitly specify the default page style at the beginning of the document uno::Reference xPara(getParagraph(1), uno::UNO_QUERY_THROW); CPPUNIT_ASSERT_EQUAL(uno::Any(), xPara->getPropertyValue("PageDescName")); } DECLARE_WW8EXPORT_TEST(testTdf104596_wrapInHeaderTable, "tdf104596_wrapInHeaderTable.doc") { xmlDocUniquePtr pXmlDoc = parseLayoutDump(); sal_Int32 nRowHeight = getXPath(pXmlDoc, "//header/tab/row[1]/infos/bounds"_ostr, "height"_ostr).toInt32(); // The fly is supposed to be no-wrap, so the text should come underneath it, not wrap-through, // thus making the row much higher. Before, height was 706. Now it is 1067. CPPUNIT_ASSERT_MESSAGE("Text must wrap under green box", nRowHeight > 1000); } DECLARE_WW8EXPORT_TEST(testGutterLeft, "gutter-left.doc") { uno::Reference xPageStyle; getStyles("PageStyles")->getByName("Standard") >>= xPageStyle; sal_Int32 nGutterMargin{}; xPageStyle->getPropertyValue("GutterMargin") >>= nGutterMargin; // Without the accompanying fix in place, this test would have failed with: // - Expected: 1270 // - Actual : 0 // i.e. gutter margin was lost. CPPUNIT_ASSERT_EQUAL(static_cast(1270), nGutterMargin); } CPPUNIT_TEST_FIXTURE(Test, testGutterTop) { createSwDoc("gutter-top.doc"); saveAndReload("MS Word 97"); uno::Reference xFactory(mxComponent, uno::UNO_QUERY); uno::Reference xSettings( xFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY); bool bGutterAtTop{}; xSettings->getPropertyValue("GutterAtTop") >>= bGutterAtTop; // Without the accompanying fix in place, this test would have failed, because the gutter was // at the left. CPPUNIT_ASSERT(bGutterAtTop); } DECLARE_WW8EXPORT_TEST(testArabicZeroNumbering, "arabic-zero-numbering.doc") { auto xNumberingRules = getProperty>(getParagraph(1), "NumberingRules"); comphelper::SequenceAsHashMap aMap(xNumberingRules->getByIndex(0)); // Without the accompanying fix in place, this test would have failed with: // - Expected: 64 // - Actual : 4 // i.e. numbering type was ARABIC, not ARABIC_ZERO. CPPUNIT_ASSERT_EQUAL(o3tl::narrowing(style::NumberingType::ARABIC_ZERO), aMap["NumberingType"].get()); } DECLARE_WW8EXPORT_TEST(testTdf128501, "tdf128501.doc") { if (!isExported()) { uno::Reference xShapeDescriptor = getShape(1); CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.CustomShape"), xShapeDescriptor->getShapeType()); } else { uno::Reference xShapeDescriptor = getShape(1); // Without the fix in place, this test would have failed with // - Expected: FrameShape // - Actual : com.sun.star.drawing.CustomShape CPPUNIT_ASSERT_EQUAL(OUString("FrameShape"), xShapeDescriptor->getShapeType()); } } CPPUNIT_TEST_FIXTURE(SwModelTestBase, testArabicZeroNumberingFootnote) { // Create a document, set footnote numbering type to ARABIC_ZERO. createSwDoc(); uno::Reference xFootnotesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xFootnoteSettings = xFootnotesSupplier->getFootnoteSettings(); sal_uInt16 nNumberingType = style::NumberingType::ARABIC_ZERO; xFootnoteSettings->setPropertyValue("NumberingType", uno::Any(nNumberingType)); // Insert a footnote. uno::Reference xFactory(mxComponent, uno::UNO_QUERY); uno::Reference xFootnote( xFactory->createInstance("com.sun.star.text.Footnote"), uno::UNO_QUERY); uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference xTextContentAppend(xTextDocument->getText(), uno::UNO_QUERY); xTextContentAppend->appendTextContent(xFootnote, {}); saveAndReload("MS Word 97"); xFootnotesSupplier.set(mxComponent, uno::UNO_QUERY); sal_uInt16 nExpected = style::NumberingType::ARABIC_ZERO; auto nActual = getProperty(xFootnotesSupplier->getFootnoteSettings(), "NumberingType"); // Without the accompanying fix in place, this test would have failed with: // - Expected: 64 // - Actual : 4 // i.e. the numbering type was ARABIC, not ARABIC_ZERO. CPPUNIT_ASSERT_EQUAL(nExpected, nActual); } CPPUNIT_TEST_FIXTURE(SwModelTestBase, testChicagoNumberingFootnote) { // Create a document, set footnote numbering type to SYMBOL_CHICAGO. createSwDoc(); uno::Reference xFootnotesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xFootnoteSettings = xFootnotesSupplier->getFootnoteSettings(); sal_uInt16 nNumberingType = style::NumberingType::SYMBOL_CHICAGO; xFootnoteSettings->setPropertyValue("NumberingType", uno::Any(nNumberingType)); // Insert a footnote. uno::Reference xFactory(mxComponent, uno::UNO_QUERY); uno::Reference xFootnote( xFactory->createInstance("com.sun.star.text.Footnote"), uno::UNO_QUERY); uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference xTextContentAppend(xTextDocument->getText(), uno::UNO_QUERY); xTextContentAppend->appendTextContent(xFootnote, {}); saveAndReload("MS Word 97"); xFootnotesSupplier.set(mxComponent, uno::UNO_QUERY); sal_uInt16 nExpected = style::NumberingType::SYMBOL_CHICAGO; auto nActual = getProperty(xFootnotesSupplier->getFootnoteSettings(), "NumberingType"); // Without the accompanying fix in place, this test would have failed with: // - Expected: 63 // - Actual : 4 // i.e. the numbering type was ARABIC, not SYMBOL_CHICAGO. CPPUNIT_ASSERT_EQUAL(nExpected, nActual); } DECLARE_WW8EXPORT_TEST(testHyperLinkURLSaving, "tdf120003.doc") { OUString URL = getProperty(getShape(1), "HyperLinkURL"); // Without the fix in place, this test would have failed with // - Expected: https://www.libreoffice.org/ // - Actual : tps://www.libreoffice.org/ CPPUNIT_ASSERT_EQUAL(OUString("https://www.libreoffice.org/"), URL); } DECLARE_WW8EXPORT_TEST(testdf79553_lineNumbers, "tdf79553_lineNumbers.doc") { bool bValue = false; sal_Int32 nValue = -1; uno::Reference< text::XTextDocument > xtextDocument(mxComponent, uno::UNO_QUERY); uno::Reference< text::XLineNumberingProperties > xLineProperties( xtextDocument, uno::UNO_QUERY_THROW ); uno::Reference< beans::XPropertySet > xPropertySet = xLineProperties->getLineNumberingProperties(); xPropertySet->getPropertyValue("IsOn") >>= bValue; CPPUNIT_ASSERT_EQUAL(true, bValue); xPropertySet->getPropertyValue("Distance") >>= nValue; CPPUNIT_ASSERT_MESSAGE("automatic distance", nValue > 0); } CPPUNIT_TEST_FIXTURE(Test, testTdf138302_restartNumbering) { loadAndReload("tdf138302_restartNumbering.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference xPara(getParagraph(8), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty(xPara, "ListLabelString")); // tdf#143982: automatic tables should export as something better than just left-and-size uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); CPPUNIT_ASSERT(getProperty(xTable, "IsWidthRelative")); CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty(xTable, "RelativeWidth")); } DECLARE_WW8EXPORT_TEST(testTdf122429_header, "tdf122429_header.doc") { uno::Reference pageStyles = getStyles("PageStyles"); uno::Reference pageStyle(pageStyles->getByName("Default Page Style"), uno::UNO_QUERY); bool headerIsOn = getProperty(pageStyle, "HeaderIsOn"); CPPUNIT_ASSERT(headerIsOn); } CPPUNIT_TEST_FIXTURE(Test, testTdf122460_header) { loadAndReload("tdf122460_header.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference pageStyles = getStyles("PageStyles"); uno::Reference pageStyle(pageStyles->getByName("Default Page Style"), uno::UNO_QUERY); bool headerIsOn = getProperty(pageStyle, "HeaderIsOn"); CPPUNIT_ASSERT(headerIsOn); } DECLARE_WW8EXPORT_TEST(testTdf139495_tinyHeader, "tdf139495_tinyHeader.doc") { // In Word 2003, this is one page, but definitely not six pages. CPPUNIT_ASSERT(getPages() < 3); } DECLARE_WW8EXPORT_TEST(testTdf124937, "tdf124937.doc") { // Check it doesn't crash at import time uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); CPPUNIT_ASSERT_EQUAL(1, getPages()); } DECLARE_WW8EXPORT_TEST(testFdo53985, "fdo53985.doc") { uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTables->getCount()); // Only 4 tables were imported. SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); CPPUNIT_ASSERT(pTextDoc); SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); CPPUNIT_ASSERT_EQUAL_MESSAGE("Compatibility: Protect form", true, pDoc->getIDocumentSettingAccess().get( DocumentSettingId::PROTECT_FORM ) ); uno::Reference xTextSectionsSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xSections->getCount()); // The first paragraph wasn't counted as a section. uno::Reference xSect(xSections->getByIndex(0), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL_MESSAGE("Section1 is protected", true, getProperty(xSect, "IsProtected")); xSect.set(xSections->getByIndex(3), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL_MESSAGE("Section4 is protected", false, getProperty(xSect, "IsProtected")); } DECLARE_WW8EXPORT_TEST(testTdf73056_cellMargins, "tdf73056_cellMargins.doc") { uno::Reference< text::XTextTablesSupplier > xTablesSupplier( mxComponent, uno::UNO_QUERY ); uno::Reference< container::XIndexAccess > xTables( xTablesSupplier->getTextTables(), uno::UNO_QUERY ); uno::Reference< text::XTextTable > xTable1( xTables->getByIndex( 0 ), uno::UNO_QUERY ); uno::Reference< table::XCell > xCell = xTable1->getCellByName( "B4" ); // only the first cell with specific margins was processed, leaving the rest at table defaults. Was 0. uno::Reference< beans::XPropertySet > xPropSet( xCell, uno::UNO_QUERY_THROW ); CPPUNIT_ASSERT_EQUAL_MESSAGE( "bottom cell spacing to contents", sal_Int32(101), getProperty(xPropSet, "BottomBorderDistance" ) ); } DECLARE_WW8EXPORT_TEST(testTdf135672_tableGrows, "tdf135672_tableGrows.doc") { auto const xTable(getParagraphOrTable(1)); // This would shift left every round-trip. First time was -259, next -418. CPPUNIT_ASSERT_EQUAL(sal_Int32(-101), getProperty(xTable, "LeftMargin")); // This would grow every round-trip. First time was 11118, next 11435 CPPUNIT_ASSERT_EQUAL(sal_Int32(10800), getProperty(xTable, "Width")); } CPPUNIT_TEST_FIXTURE(Test, testTdf79435_legacyInputFields) { loadAndReload("tdf79435_legacyInputFields.docx"); //using .docx input file to verify cross-format compatibility. uno::Reference xFormField = getProperty< uno::Reference >(getRun(getParagraph(5), 3), "Bookmark"); uno::Reference xParameters(xFormField->getParameters()); OUString sTmp; // Too often the string reader can fail during import - fix that first to prevent round-tripping garbage. // (for example BR-1010B.doc from tdf#48097) //xParameters->getByName("EntryMacro") >>= sTmp; //CPPUNIT_ASSERT_EQUAL(OUString("test"), sTmp); //xParameters->getByName("Help") >>= sTmp; //CPPUNIT_ASSERT_EQUAL(OUString("F1Help"), sTmp); //xParameters->getByName("ExitMacro") >>= sTmp; //CPPUNIT_ASSERT_EQUAL(OUString("test"), sTmp); xParameters->getByName("Description") >>= sTmp; CPPUNIT_ASSERT_EQUAL(OUString("StatusHelp"), sTmp); //xParameters->getByName("Content") >>= sTmp; //CPPUNIT_ASSERT_EQUAL(OUString("Camelcase"), sTmp); //xParameters->getByName("Format") >>= sTmp; //CPPUNIT_ASSERT_EQUAL(OUString("TITLE CASE"), sTmp); sal_uInt16 nMaxLength = 0; xParameters->getByName("MaxLength") >>= nMaxLength; CPPUNIT_ASSERT_EQUAL_MESSAGE("Max Length", sal_uInt16(10), nMaxLength); // too bad this is based on character runs - just found try trial and error. xFormField = getProperty< uno::Reference >(getRun(getParagraph(6), 2), "Bookmark"); xParameters.set(xFormField->getParameters()); xParameters->getByName("Type") >>= sTmp; CPPUNIT_ASSERT_EQUAL(OUString("calculated"), sTmp); xFormField = getProperty< uno::Reference >(getRun(getParagraph(7), 2), "Bookmark"); xParameters.set(xFormField->getParameters()); xParameters->getByName("Type") >>= sTmp; CPPUNIT_ASSERT_EQUAL(OUString("currentDate"), sTmp); xFormField = getProperty< uno::Reference >(getRun(getParagraph(7), 7), "Bookmark"); xParameters.set(xFormField->getParameters()); xParameters->getByName("Type") >>= sTmp; CPPUNIT_ASSERT_EQUAL(OUString("currentTime"), sTmp); xFormField = getProperty< uno::Reference >(getRun(getParagraph(8), 2), "Bookmark"); xParameters.set(xFormField->getParameters()); xParameters->getByName("Type") >>= sTmp; CPPUNIT_ASSERT_EQUAL(OUString("number"), sTmp); xFormField = getProperty< uno::Reference >(getRun(getParagraph(8), 7), "Bookmark"); xParameters.set(xFormField->getParameters()); xParameters->getByName("Type") >>= sTmp; CPPUNIT_ASSERT_EQUAL(OUString("date"), sTmp); } CPPUNIT_TEST_FIXTURE(Test, testTdf134264) { loadAndReload("tdf134264.docx"); // Without the fix in place, ADDRESSBLOCK fields would have been lost after RT CPPUNIT_ASSERT_EQUAL(OUString("MF"), getParagraph(1)->getString()); CPPUNIT_ASSERT_EQUAL(OUString("M19"), getParagraph(2)->getString()); CPPUNIT_ASSERT_EQUAL(OUString("1815"), getParagraph(3)->getString()); } DECLARE_WW8EXPORT_TEST(testTdf120225_textControlCrossRef, "tdf120225_textControlCrossRef.doc") { uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY); uno::Reference xParaEnum = xParaEnumAccess->createEnumeration(); uno::Reference xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY); uno::Reference xRunEnum = xRunEnumAccess->createEnumeration(); xRunEnum->nextElement(); uno::Reference xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), getProperty(xPropertySet, "TextPortionType")); uno::Reference xBookmark(getProperty< uno::Reference >(xPropertySet, "Bookmark"), uno::UNO_QUERY_THROW); // Critical test: does TextField's bookmark name match cross-reference? const OUString& sTextFieldName( xBookmark->getName() ); uno::Reference xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xFieldsAccess(xTextFieldsSupplier->getTextFields()); uno::Reference xFields(xFieldsAccess->createEnumeration()); CPPUNIT_ASSERT(xFields->hasMoreElements()); xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sTextFieldName, getProperty(xPropertySet, "SourceName")); uno::Reference xBookmarksSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY); uno::Reference xBookmarksByName = xBookmarksSupplier->getBookmarks(); // TextFields should not be turned into real bookmarks. CPPUNIT_ASSERT_EQUAL(static_cast(0), xBookmarksByIdx->getCount()); // The actual name isn't critical, but if it fails, it is worth asking why. CPPUNIT_ASSERT_EQUAL(OUString("Text1"), sTextFieldName); } CPPUNIT_TEST_FIXTURE(Test, testTdf134948) { loadAndReload("tdf134948.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Only 1 paragraph", 1, getParagraphs()); } CPPUNIT_TEST_FIXTURE(Test, testTdf132726) { loadAndReload("tdf132726.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference xRun = getRun(getParagraph(1), 1, "What sentence has a yellow background? "); CPPUNIT_ASSERT_EQUAL( COL_AUTO, getProperty(xRun, "CharBackColor")); xRun = getRun(getParagraph(1), 2, "Why, this sentence of course"); CPPUNIT_ASSERT_EQUAL( COL_YELLOW, getProperty(xRun, "CharBackColor")); } CPPUNIT_TEST_FIXTURE(Test, testTdf127316_autoEscapement) { loadAndReload("tdf127316_autoEscapement.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference xPara = getParagraph(2); CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty(getRun(xPara, 1, "Normal text "), "CharEscapement"), 0); // Negative escapements (subscripts) were decreasing by 1% every round-trip due to bad manual rounding. // This should be roughly .2*35% of the ORIGINAL (non-reduced) size. However, during export the // proportional height has to be changed into direct formatting, which then changes the relative percent. // In this case, a 24pt font, proportional at 65% becomes roughly a 16pt font. // Thus an escapement of 7% (1.68pt) becomes roughly 10.5% for the 16pt font. CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Subscript", -10.f, getProperty(getRun(xPara, 2), "CharEscapement"), 1); } CPPUNIT_TEST_FIXTURE(Test, testTdf127316_autoEscapement2) { loadAndReload("tdf127316_autoEscapement2.odt"); CPPUNIT_ASSERT_EQUAL(2, getPages()); uno::Reference xPara = getParagraph(1); CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty(getRun(xPara, 1, "Base1"), "CharEscapement"), 0); // Font is 80% of 40pt or 32pt, original escapement is 6.4pt, so round-trip escapement is 20%. CPPUNIT_ASSERT_DOUBLES_EQUAL(20.f, getProperty(getRun(xPara, 2,"AutoSuperscript"), "CharEscapement"), 1); xPara.set( getParagraph(3) ); CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty(getRun(xPara, 1, "Base3"), "CharEscapement"), 0); // font is 20% of 40pt or 8pt, original escapement is 25.6pt, so round-trip escapement is 320%. CPPUNIT_ASSERT_DOUBLES_EQUAL(320.f, getProperty(getRun(xPara, 2,"AutoSuperscript"), "CharEscapement"), 3); } CPPUNIT_TEST_FIXTURE(Test, testTdf120412_proportionalEscapement) { loadAndReload("tdf120412_proportionalEscapement.odt"); uno::Reference xPara = getParagraph(2); CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty(getRun(xPara, 2, "Base"), "CharEscapement"), 0); // Import was limiting to 100%. And export based the position on the original height, not the proportional height. CPPUNIT_ASSERT_DOUBLES_EQUAL( 150.f, getProperty(getRun(xPara, 3,"Super"), "CharEscapement"), 2); CPPUNIT_ASSERT_EQUAL(2, getPages()); } DECLARE_WW8EXPORT_TEST(testTdf133453_realFontSize, "tdf133453_realFontSize.doc") { CPPUNIT_ASSERT_EQUAL( -95.f, getProperty(getRun(getParagraph(1), 2, "2"), "CharEscapement") ); } DECLARE_WW8EXPORT_TEST(testTdf116194, "tdf116194.doc") { CPPUNIT_ASSERT_EQUAL( Color(0xc00000), getProperty(getRun(getParagraph(1), 1), "CharColor")); } CPPUNIT_TEST_FIXTURE(Test, testTdf121111_fillStyleNone) { loadAndReload("tdf121111_fillStyleNone.docx"); uno::Reference xStyle(getStyles("ParagraphStyles")->getByName("Numbering - First level"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(Color(0xb8cce4), getProperty(xStyle, "ParaBackColor"));//R:184 G:204 B:228 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty(xStyle, "FillStyle")); uno::Reference xText(getParagraph(12)); CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xText, "ParaBackColor")); CPPUNIT_ASSERT_EQUAL_MESSAGE("No fill", drawing::FillStyle_NONE, getProperty(xText, "FillStyle")); } CPPUNIT_TEST_FIXTURE(Test, testTdf128608_fillStyleNoneB) { loadAndReload("tdf128608_fillStyleNoneB.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference xText(getParagraph(1)); CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xText, "ParaBackColor")); CPPUNIT_ASSERT_EQUAL_MESSAGE("No fill", drawing::FillStyle_NONE, getProperty(xText, "FillStyle")); } DECLARE_WW8EXPORT_TEST(testTdf132094_transparentPageImage, "tdf132094_transparentPageImage.doc") { uno::Reference image (getShape(1), uno::UNO_QUERY); // Don't add fillstyle when none is set. // Well, ok, at least make it transparent if you do uselessly set a solid color... const bool bFillNone = drawing::FillStyle_NONE == getProperty(image, "FillStyle"); const bool bTransparent = sal_Int16(0) != getProperty(image, "FillTransparence"); CPPUNIT_ASSERT_MESSAGE("no background fill", bTransparent || bFillNone); } DECLARE_WW8EXPORT_TEST(testTdf112618_textbox_no_bg, "tdf112618_textbox_no_bg.doc") { Color nTransparence = getProperty(getShape(2), "FillTransparence"); CPPUNIT_ASSERT_EQUAL(Color(0x000064), nTransparence); CPPUNIT_ASSERT_EQUAL(nTransparence, getProperty(getShape(2), "BackColorTransparency")); } DECLARE_WW8EXPORT_TEST(testTdf101826_xattrTextBoxFill, "tdf101826_xattrTextBoxFill.doc") { //Basic 1 Color Fill: gradient from yellow(FFFF00) to brown(767600) currently saves as mid-color CPPUNIT_ASSERT_MESSAGE("background color", Color(0xFF, 0xFF, 0x00) != getProperty(getShape(1), "BackColor")); //Basic 2 Color Fill: gradient from yellow(FFFF00) to green(00B050) currently saves as mid-color CPPUNIT_ASSERT_MESSAGE("background color", Color(0xFF, 0xFF, 0x00) != getProperty(getShape(4), "BackColor")); //Basic Picture Fill: Tux image CPPUNIT_ASSERT_EQUAL_MESSAGE("background image", drawing::FillStyle_BITMAP, getProperty(getShape(5), "FillStyle")); } DECLARE_WW8EXPORT_TEST(testTdf123433_fillStyleStop, "tdf123433_fillStyleStop.doc") { uno::Reference xText(getParagraph(12)); CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty(xText, "FillStyle")); CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xText, "ParaBackColor")); } CPPUNIT_TEST_FIXTURE(Test, testTdf127862_pageFillStyle) { loadAndReload("tdf127862_pageFillStyle.odt"); CPPUNIT_ASSERT_EQUAL(6, getPages()); uno::Reference xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); CPPUNIT_ASSERT(drawing::FillStyle_NONE != getProperty(xStyle, "FillStyle")); } DECLARE_WW8EXPORT_TEST(testTdf128608_tableParaBackColor, "tdf128608_tableParaBackColor.doc") { 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("A4"), uno::UNO_QUERY); uno::Reference xParaEnumAccess(xCell->getText(), uno::UNO_QUERY); uno::Reference xParaEnum = xParaEnumAccess->createEnumeration(); uno::Reference xPara(xParaEnum->nextElement(), uno::UNO_QUERY); // ParaBackColor doesn't seem to be used in this case, but keep it here to make sure it stays as AUTO. CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xPara, "ParaBackColor")); // No paragraph background colour/fill. (The cell background colour should be used.) CPPUNIT_ASSERT_EQUAL_MESSAGE("No fillstyle", drawing::FillStyle_NONE, getProperty(xPara, "FillStyle")); } CPPUNIT_TEST_FIXTURE(Test, testTdf117217_largeTableBackgrounds) { loadAndReload("tdf117217_largeTableBackgrounds.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); // Cell 22: light-red == 16711680 uno::Reference xCell(xTable->getCellByName("V1"), uno::UNO_QUERY_THROW); CPPUNIT_ASSERT_EQUAL_MESSAGE("light red", Color(0xE0C2CD), getProperty(xCell, "BackColor")); xCell.set(xTable->getCellByName("Z1"), uno::UNO_QUERY_THROW); CPPUNIT_ASSERT_EQUAL_MESSAGE("light red", Color(0xE0C2CD), getProperty(xCell, "BackColor")); } CPPUNIT_TEST_FIXTURE(Test, testTdf94009_zeroPgMargin) { loadAndReload("tdf94009_zeroPgMargin.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference defaultStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty(defaultStyle, "TopMargin")); } DECLARE_WW8EXPORT_TEST(testTdf108518_CRnumformatting, "tdf108518_CRnumformatting.doc") { CPPUNIT_ASSERT_EQUAL(OUString("6.2.3."), parseDump("//body/txt[4]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']"_ostr, "expand"_ostr)); //Without this fix in place, it would become 200 (and non-bold). CPPUNIT_ASSERT_EQUAL(OUString("220"), parseDump("//body/txt[4]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']/SwFont"_ostr, "height"_ostr)); } DECLARE_WW8EXPORT_TEST(testTdf120711_joinedParagraphWithChangeTracking, "tdf120711.doc") { sal_Int16 numFormat = getNumberingTypeOfParagraph(5); // last paragraph is not a list item CPPUNIT_ASSERT(style::NumberingType::CHAR_SPECIAL != numFormat); } CPPUNIT_TEST_FIXTURE(Test, testTdf129522_removeShadowStyle) { loadAndReload("tdf129522_removeShadowStyle.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference< container::XNameAccess > paragraphStyles = getStyles("ParagraphStyles"); uno::Reference< beans::XPropertySet > xStyleProps(paragraphStyles->getByName("Shadow"), uno::UNO_QUERY_THROW); table::ShadowFormat aShadow = getProperty(xStyleProps, "ParaShadowFormat"); CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location); // Shadows were inherited regardless of whether the style disabled them. xStyleProps.set(paragraphStyles->getByName("Shadow-removed"), uno::UNO_QUERY_THROW); aShadow = getProperty(xStyleProps, "ParaShadowFormat"); CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE, aShadow.Location); uno::Reference< container::XNameAccess > characterStyles = getStyles("CharacterStyles"); xStyleProps.set(characterStyles->getByName("CharShadow"), uno::UNO_QUERY_THROW); aShadow = getProperty(xStyleProps, "CharShadowFormat"); CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location); xStyleProps.set(characterStyles->getByName("CharShadow-removed"), uno::UNO_QUERY_THROW); aShadow = getProperty(xStyleProps, "CharShadowFormat"); CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE, aShadow.Location); } DECLARE_WW8EXPORT_TEST(testTdf81705_outlineLevel, "tdf81705_outlineLevel.doc") { // direct formatting resets outline level to body text (0) CPPUNIT_ASSERT_EQUAL_MESSAGE("Paragraph C", sal_uInt16(0), getProperty(getParagraph(3), "OutlineLevel")); // myStyle sets outline level to 1. CPPUNIT_ASSERT_EQUAL_MESSAGE("Paragraph D", sal_uInt16(1), getProperty(getParagraph(4), "OutlineLevel")); } DECLARE_WW8EXPORT_TEST(testBtlrCell, "btlr-cell.doc") { // Without the accompanying fix in place, this test would have failed, as // the btlr text direction in the A1 cell was lost on DOC import and // export. uno::Reference xSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTables = xSupplier->getTextTables(); uno::Reference xTable(xTables->getByName("Table1"), uno::UNO_QUERY); uno::Reference xA1(xTable->getCellByName("A1"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR, getProperty(xA1, "WritingMode")); uno::Reference xB1(xTable->getCellByName("B1"), uno::UNO_QUERY); auto nActual = getProperty(xB1, "WritingMode"); CPPUNIT_ASSERT(nActual == text::WritingMode2::LR_TB || nActual == text::WritingMode2::CONTEXT); uno::Reference xC1(xTable->getCellByName("C1"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(text::WritingMode2::TB_RL, getProperty(xC1, "WritingMode")); } DECLARE_WW8EXPORT_TEST(testTdf118375export, "tdf118375_240degClockwise.doc") { // The input document has one custom shape, which is rotated 240deg. Check // that it has the same position as in Word. uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY_THROW); CPPUNIT_ASSERT_MESSAGE("Could not get XDrawPagesSupplier", xDrawPagesSupplier.is()); uno::Reference xDrawPages(xDrawPagesSupplier->getDrawPages()); uno::Reference xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY_THROW); CPPUNIT_ASSERT_MESSAGE("Could not get xDrawPage", xDrawPage.is()); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); CPPUNIT_ASSERT_MESSAGE("Could not get xShape", xShape.is()); uno::Reference xShapeProps(xShape, uno::UNO_QUERY); CPPUNIT_ASSERT_MESSAGE("Could not get the shape properties", xShapeProps.is()); sal_Int32 nPosX = {}, nPosY = {}; CPPUNIT_ASSERT(xShapeProps->getPropertyValue("HoriOrientPosition") >>= nPosX); CPPUNIT_ASSERT(xShapeProps->getPropertyValue("VertOrientPosition") >>= nPosY); // Allow some tolerance because rounding errors through integer arithmetic // in rotation. CPPUNIT_ASSERT_DOUBLES_EQUAL(5200.0, static_cast(nPosX), 1.0); CPPUNIT_ASSERT_DOUBLES_EQUAL(1152.0, static_cast(nPosY), 1.0); } DECLARE_WW8EXPORT_TEST(testImageCommentAtChar, "image-comment-at-char.doc") { uno::Reference xPara = getParagraph(1); CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty(getRun(xPara, 1), "TextPortionType")); // Without the accompanying fix in place, this test would have failed with 'Expected: // Annotation; Actual: Frame', i.e. the comment start before the image was lost. CPPUNIT_ASSERT_EQUAL(OUString("Annotation"), getProperty(getRun(xPara, 2), "TextPortionType")); CPPUNIT_ASSERT_EQUAL(OUString("Frame"), getProperty(getRun(xPara, 3), "TextPortionType")); CPPUNIT_ASSERT_EQUAL(OUString("AnnotationEnd"), getProperty(getRun(xPara, 4), "TextPortionType")); CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty(getRun(xPara, 5), "TextPortionType")); } CPPUNIT_TEST_FIXTURE(Test, testTdf126708emf) { loadAndReload("tdf126708_containsemf.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); auto xShape = getShape(1); // First check the size of the EMF graphic contained in the shape. auto xGraphic = getProperty< uno::Reference >( xShape, "Graphic"); auto xSize = getProperty(xGraphic, "Size100thMM"); CPPUNIT_ASSERT_EQUAL(sal_Int32(8501), xSize.Height); CPPUNIT_ASSERT_EQUAL(sal_Int32(18939), xSize.Width); // Now check that the shape itself has a decent size. // This size varies slightly when round tripping through doc format. xSize = getProperty(xShape, "Size"); CPPUNIT_ASSERT(abs(xSize.Height - 7629) <= 6); CPPUNIT_ASSERT(abs(xSize.Width - 17000) <= 6); } CPPUNIT_TEST_FIXTURE(Test, testBtlrFrame) { loadAndReload("btlr-frame.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); if (!isExported()) { return; } // Without the accompanying fix in place, this test would have failed with a // beans.UnknownPropertyException, as the writing direction was lost, so the default direction // resulted in a conversion to a Writer text frame. uno::Reference xFrame(getShape(1), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(9000), getProperty(xFrame, "RotateAngle")); } DECLARE_WW8EXPORT_TEST(testPresetDash, "tdf127166_prstDash_Word97.doc") { // Error was, that the 'sys' preset dash styles were neither imported not // exported, the mixed styles had wrong dash-dot order, they were imported // with absolute values. const drawing::LineDash dashParams[] = { {drawing::DashStyle_RECTRELATIVE, 1, 400, 0, 0, 300}, // dash {drawing::DashStyle_RECTRELATIVE, 1, 400, 1, 100, 300}, // dashDot {drawing::DashStyle_RECTRELATIVE, 1, 100, 0, 0, 300}, // dot {drawing::DashStyle_RECTRELATIVE, 1, 800, 0, 0, 300}, // lgDash {drawing::DashStyle_RECTRELATIVE, 1, 800, 1, 100, 300}, // lgDashDot {drawing::DashStyle_RECTRELATIVE, 1, 800, 2, 100, 300}, // lgDashDotDot {drawing::DashStyle_RECTRELATIVE, 1, 300, 0, 0, 100}, // sysDash {drawing::DashStyle_RECTRELATIVE, 1, 300, 1, 100, 100}, // sysDashDot {drawing::DashStyle_RECTRELATIVE, 1, 300, 2, 100, 100}, // sysDashDotDot {drawing::DashStyle_RECTRELATIVE, 1, 100, 0, 0, 100} // sysDot }; drawing::LineDash aPresetLineDash; drawing::LineDash aShapeLineDash; for (sal_uInt16 i = 0; i < 10; i++) { aPresetLineDash = dashParams[i]; uno::Reference xShape = getShape(i+1); aShapeLineDash = getProperty(xShape, "LineDash"); bool bIsEqual = aPresetLineDash.Style == aShapeLineDash.Style && aPresetLineDash.Dots == aShapeLineDash.Dots && aPresetLineDash.DotLen == aShapeLineDash.DotLen && aPresetLineDash.Dashes == aShapeLineDash.Dashes && aPresetLineDash.DashLen == aShapeLineDash.DashLen && aPresetLineDash.Distance == aShapeLineDash.Distance; CPPUNIT_ASSERT_MESSAGE("LineDash differ", bIsEqual); } const auto& pLayout = parseLayoutDump(); // Ensure that there is no tabstop in the first paragraph (despite chapter numbering's setting) // This is a pre-emptive test to ensure something visibly correct is not broken. assertXPath(pLayout, "//body/txt[1]//SwFixPortion"_ostr, 0); } CPPUNIT_TEST_FIXTURE(Test, testRtlGutter) { auto verify = [this]() { uno::Reference xStandard( getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); CPPUNIT_ASSERT(getProperty(xStandard, "RtlGutter")); }; // Given a document with RTL gutter, when loading it: createSwDoc("rtl-gutter.doc"); // Then make sure the section's gutter is still RTL: // Without the accompanying fix in place, this test would have failed as the SPRM was missing. verify(); saveAndReload("MS Word 97"); verify(); } DECLARE_WW8EXPORT_TEST(testTdf94326_notOutlineNumbering, "tdf94326_notOutlineNumbering.doc") { // The directly applied numbering list must not be lost. uno::Reference xPara(getParagraph(2, u"ОБЩИЕ ПОЛОЖЕНИЯ"_ustr), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf106541_cancelOutline, "tdf106541_cancelOutline.doc") { // The ability to cancel numbering must not be lost. uno::Reference xPara(getParagraph(1, "Cancelled by style"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(2, "Cancelled by inherited style"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(4, "Cancelled by direct paragraph formatting"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf104239_chapterNumbering, "tdf104239_chapterNumbering.doc") { uno::Reference xNumberingSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xNumberingRules = xNumberingSupplier->getChapterNumberingRules(); comphelper::SequenceAsHashMap hashMap(xNumberingRules->getByIndex(0)); CPPUNIT_ASSERT(hashMap["HeadingStyleName"].get().match("Heading 1")); sal_uInt16 nNumberingType = style::NumberingType::CHARS_UPPER_LETTER_N; CPPUNIT_ASSERT_EQUAL(nNumberingType, hashMap["NumberingType"].get()); hashMap = xNumberingRules->getByIndex(5); CPPUNIT_ASSERT(hashMap["HeadingStyleName"].get().match("Heading 6")); nNumberingType = style::NumberingType::ARABIC; CPPUNIT_ASSERT_EQUAL(nNumberingType, hashMap["NumberingType"].get()); } DECLARE_WW8EXPORT_TEST(testTdf106541_inheritChapterNumbering, "tdf106541_inheritChapterNumbering.doc") { // The level and numbering are inherited from Heading 1. uno::Reference xPara(getParagraph(3, "Letter A"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("a."), getProperty(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf106541_inheritChapterNumberingB, "tdf106541_inheritChapterNumberingB.doc") { // The level and numbering are inherited from Heading 1. uno::Reference xPara(getParagraph(1, "Chapter 1, level 1"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(2, "Chapter 1, level 2"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf75748_inheritChapterNumberingC, "tdf75748_inheritChapterNumberingC.doc") { uno::Reference xPara(getParagraph(5, "Inherited from Heading 3"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("II.B.1."), getProperty(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf104239_numbering, "tdf104239_numbering.doc") { // The paragraph starts with "paraksta Pieņemšanas". [Roundtrip by Word 2016 avoids the problem.] uno::Reference xPara(getParagraph(51), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("3.3.1."), getProperty(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf104239_chapterNumberingLevels, "tdf104239_chapterNumberingLevels.doc") { uno::Reference xPara(getParagraph(1, "Heading 1"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("Article I."), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(2, "Heading 2"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(3, "Heading 3"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("First"), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(4, "Heading 4"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(8, "Heading 9"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("1.1.1.1.1.1.1.1.1."), getProperty(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf104239_chapterNumberTortureTest, "tdf104239_chapterNumberTortureTest.doc") { // There is no point in identifying what the wrong values where in this test, //because EVERYTHING was wrong, and MANY different fixes are required to solve the problems. uno::Reference xPara(getParagraph(1, "No numId in style or paragraph"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(2, "Paragraph cancels numbering(0)"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(3, "First numbered line"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("1st.i.a.1.I"), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(7, "inheritOnly: inherit outlineLvl and listLvl."), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("2nd.ii"), getProperty(xPara, "ListLabelString")); CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty(xPara, "NumberingLevel")); // Level 2 xPara.set(getParagraph(9, "outline with Body listLvl(9)."), uno::UNO_QUERY); if (!isExported()) CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(10, "outline with Body listLvl(9) #2."), uno::UNO_QUERY); if (!isExported()) CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(11, "direct formatting - Body listLvl(9)."), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara, "ListLabelString")); xPara.set(getParagraph(12, "direct numId, inherit listLvl."), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("2nd.ii.a.1.I"), getProperty(xPara, "ListLabelString")); CPPUNIT_ASSERT_EQUAL(sal_Int16(4), getProperty(xPara, "NumberingLevel")); // Level 5 xPara.set(getParagraph(13, "Style numId0 cancels inherited numbering."), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf106541_inheritOutlineNumbering, "tdf106541_inheritOutlineNumbering.doc") { // The level and numbering are inherited from Level2. uno::Reference xPara(getParagraph(2, "This should be a sub-point."), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf104239_sharedOutlineNumId, "tdf104239_sharedOutlineNumId.doc") { uno::Reference xPara(getParagraph(5, "Principes"), uno::UNO_QUERY); // This was ".1." previously. CPPUNIT_ASSERT_EQUAL(OUString("2.1."), getProperty(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf120394, "tdf120394.doc") { CPPUNIT_ASSERT_EQUAL(1, getPages()); { uno::Reference xPara(getParagraph(1), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(2), getProperty(xPara, "NumberingLevel")); CPPUNIT_ASSERT_EQUAL(OUString("1.1.1"), getProperty(xPara, "ListLabelString")); } { uno::Reference xPara(getParagraph(5), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(0), getProperty(xPara, "NumberingLevel")); CPPUNIT_ASSERT_EQUAL(OUString(), getProperty(xPara, "ListLabelString")); } { uno::Reference xPara(getParagraph(8), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(2), getProperty(xPara, "NumberingLevel")); CPPUNIT_ASSERT_EQUAL(OUString(), getProperty(xPara, "ListLabelString")); } { uno::Reference xPara(getParagraph(9), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(2), getProperty(xPara, "NumberingLevel")); CPPUNIT_ASSERT_EQUAL(OUString("1.1.2"), getProperty(xPara, "ListLabelString")); } { uno::Reference xPara(getParagraph(10), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(2), getProperty(xPara, "NumberingLevel")); CPPUNIT_ASSERT_EQUAL(OUString(), getProperty(xPara, "ListLabelString")); } } DECLARE_WW8EXPORT_TEST(testTdf142760, "tdf142760.doc") { // Without the fix in place, this test would have failed with // - Expected: 2 // - Actual : 6 CPPUNIT_ASSERT_EQUAL(2, getPages()); CPPUNIT_ASSERT_EQUAL(1, getShapes()); uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); } DECLARE_WW8EXPORT_TEST(testTdf134570, "tdf134570.doc") { CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference xPara(getParagraph(1), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(1), getProperty(xPara, "NumberingLevel")); CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty(xPara, "ListLabelString")); } CPPUNIT_TEST_FIXTURE(Test, testTdf136814) { loadAndReload("tdf136814.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); sal_Int32 nBorderDistance = static_cast(106); CPPUNIT_ASSERT_EQUAL(nBorderDistance, getProperty(xStyle, "TopBorderDistance")); CPPUNIT_ASSERT_EQUAL(nBorderDistance, getProperty(xStyle, "RightBorderDistance")); CPPUNIT_ASSERT_EQUAL(nBorderDistance, getProperty(xStyle, "BottomBorderDistance")); CPPUNIT_ASSERT_EQUAL(nBorderDistance, getProperty(xStyle, "LeftBorderDistance")); } CPPUNIT_TEST_FIXTURE(Test, testTdf79186_noLayoutInCell) { loadAndReload("tdf79186_noLayoutInCell.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); CPPUNIT_ASSERT(!getProperty(getShape(1), "IsFollowingTextFlow")); CPPUNIT_ASSERT(getProperty(getShape(1), "SurroundContour")); // tdf#140508 } CPPUNIT_TEST_FIXTURE(Test, testClearingBreak) { auto verify = [this]() { uno::Reference xParagraph(getParagraph(1), uno::UNO_QUERY); uno::Reference xPortions = xParagraph->createEnumeration(); xPortions->nextElement(); xPortions->nextElement(); // Without the accompanying fix in place, this test would have failed with: // An uncaught exception of type com.sun.star.container.NoSuchElementException // i.e. the first para was just a fly + text portion, the clearing break was lost. uno::Reference xPortion(xPortions->nextElement(), uno::UNO_QUERY); OUString aPortionType; xPortion->getPropertyValue("TextPortionType") >>= aPortionType; CPPUNIT_ASSERT_EQUAL(OUString("LineBreak"), aPortionType); uno::Reference xLineBreak; xPortion->getPropertyValue("LineBreak") >>= xLineBreak; sal_Int16 eClear{}; uno::Reference xLineBreakProps(xLineBreak, uno::UNO_QUERY); xLineBreakProps->getPropertyValue("Clear") >>= eClear; CPPUNIT_ASSERT_EQUAL(static_cast(SwLineBreakClear::ALL), eClear); }; // Given a document with a clearing break: // When loading that file: createSwDoc("clearing-break.doc"); // Then make sure that the clear property of the break is not ignored: verify(); saveAndReload("MS Word 97"); // Make sure that the clear property of the break is not ignored during export: verify(); } CPPUNIT_TEST_FIXTURE(Test, testTdf142840) { loadAndReload("tdf142840.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference xBookmarksSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY); uno::Reference xBookmarksByName = xBookmarksSupplier->getBookmarks(); // Ensure space are replaced by underscore in bookmark name (it was working before, but ensure this) CPPUNIT_ASSERT_EQUAL(static_cast(1), xBookmarksByIdx->getCount()); CPPUNIT_ASSERT(xBookmarksByName->hasByName("Chapter_1")); CPPUNIT_ASSERT(!xBookmarksByName->hasByName("Chapter 1")); // And hyperlink is referring bookmark with underscore also (this was broken) CPPUNIT_ASSERT_EQUAL(OUString("#Chapter_1"), getProperty(getRun(getParagraph(1), 1), "HyperLinkURL")); } CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */