/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { class Test : public SwModelTestBase { public: Test() : SwModelTestBase(u"/sw/qa/extras/rtfimport/data/"_ustr, u"Rich Text Format"_ustr) { } }; CPPUNIT_TEST_FIXTURE(Test, testN695479) { createSwDoc("n695479.rtf"); uno::Reference xTextFramesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY); uno::Reference xPropertySet(xIndexAccess->getByIndex(0), uno::UNO_QUERY); // Negative ABSH should mean fixed size. CPPUNIT_ASSERT_EQUAL(text::SizeType::FIX, getProperty(xPropertySet, u"SizeType"_ustr)); CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(300)), getProperty(xPropertySet, u"Height"_ustr)); int nShapes = getShapes(); CPPUNIT_ASSERT_EQUAL(3, nShapes); bool bFrameFound = false, bDrawFound = false; for (int i = 0; i < nShapes; ++i) { uno::Reference xServiceInfo(getShape(i + 1), uno::UNO_QUERY); if (xServiceInfo->supportsService(u"com.sun.star.text.TextFrame"_ustr)) { // Both frames should be anchored to the first paragraph. bFrameFound = true; uno::Reference xTextContent(xServiceInfo, uno::UNO_QUERY); uno::Reference xRange = xTextContent->getAnchor(); uno::Reference xText = xRange->getText(); CPPUNIT_ASSERT_EQUAL(u"plain"_ustr, xText->getString()); if (i == 0) // Additionally, the first frame should have double border at the bottom. CPPUNIT_ASSERT_EQUAL( table::BorderLineStyle::DOUBLE, getProperty(xPropertySet, u"BottomBorder"_ustr).LineStyle); } else if (xServiceInfo->supportsService(u"com.sun.star.drawing.LineShape"_ustr)) { // The older "drawing objects" syntax should be recognized. bDrawFound = true; xPropertySet.set(xServiceInfo, uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_PRINT_AREA, getProperty(xPropertySet, u"HoriOrientRelation"_ustr)); CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty(xPropertySet, u"VertOrientRelation"_ustr)); } } CPPUNIT_ASSERT(bFrameFound); CPPUNIT_ASSERT(bDrawFound); } CPPUNIT_TEST_FIXTURE(Test, testTdf117246) { createSwDoc("tdf117246.rtf"); // This was 2, all but the last \page was lost. CPPUNIT_ASSERT_EQUAL(3, getPages()); } CPPUNIT_TEST_FIXTURE(Test, testTdf108943) { createSwDoc("tdf108943.rtf"); uno::Reference xPropertySet( getStyles(u"NumberingStyles"_ustr)->getByName(u"WWNum1"_ustr), uno::UNO_QUERY); uno::Reference xLevels( xPropertySet->getPropertyValue(u"NumberingRules"_ustr), uno::UNO_QUERY); uno::Sequence aProps; xLevels->getByIndex(0) >>= aProps; // 1st level sal_Int32 nListtabStopPosition = 0; for (int i = 0; i < aProps.getLength(); ++i) { const beans::PropertyValue& rProp = aProps[i]; if (rProp.Name == "ListtabStopPosition") nListtabStopPosition = rProp.Value.get(); } // This was 0, \tx was handled in paragraphs only (and not in list definitions). CPPUNIT_ASSERT_EQUAL(static_cast(1270), nListtabStopPosition); } CPPUNIT_TEST_FIXTURE(Test, testFdo46662) { createSwDoc("fdo46662.rtf"); OUString listStyle; { uno::Reference xPara(getParagraph(1), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(0), getProperty(xPara, u"NumberingLevel"_ustr)); CPPUNIT_ASSERT(xPara->getPropertyValue(u"NumberingStyleName"_ustr) >>= listStyle); CPPUNIT_ASSERT(listStyle.startsWith("WWNum")); CPPUNIT_ASSERT_EQUAL(u"1"_ustr, getProperty(xPara, u"ListLabelString"_ustr)); } { uno::Reference xPara(getParagraph(2), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(1), getProperty(xPara, u"NumberingLevel"_ustr)); CPPUNIT_ASSERT(xPara->getPropertyValue(u"NumberingStyleName"_ustr) >>= listStyle); CPPUNIT_ASSERT(listStyle.startsWith("WWNum")); CPPUNIT_ASSERT_EQUAL(u"1.1"_ustr, getProperty(xPara, u"ListLabelString"_ustr)); } { uno::Reference xPara(getParagraph(3), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(2), getProperty(xPara, u"NumberingLevel"_ustr)); CPPUNIT_ASSERT(xPara->getPropertyValue(u"NumberingStyleName"_ustr) >>= listStyle); CPPUNIT_ASSERT(listStyle.startsWith("WWNum")); CPPUNIT_ASSERT_EQUAL(u"1.1.1"_ustr, getProperty(xPara, u"ListLabelString"_ustr)); } { uno::Reference xPara(getParagraph(4), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(3), getProperty(xPara, u"NumberingLevel"_ustr)); CPPUNIT_ASSERT(xPara->getPropertyValue(u"NumberingStyleName"_ustr) >>= listStyle); CPPUNIT_ASSERT(listStyle.startsWith("WWNum")); CPPUNIT_ASSERT_EQUAL(u"1.1.1.1"_ustr, getProperty(xPara, u"ListLabelString"_ustr)); } { uno::Reference xPara(getParagraph(5), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(0), getProperty(xPara, u"NumberingLevel"_ustr)); CPPUNIT_ASSERT(xPara->getPropertyValue(u"NumberingStyleName"_ustr) >>= listStyle); CPPUNIT_ASSERT(listStyle.startsWith("WWNum")); CPPUNIT_ASSERT_EQUAL(u"2"_ustr, getProperty(xPara, u"ListLabelString"_ustr)); } } CPPUNIT_TEST_FIXTURE(Test, testTdf115715) { createSwDoc("tdf115715.rtf"); // This was 0, second paragraph was shifted to the right, it had the same // horizontal position as the 3rd paragraph. CPPUNIT_ASSERT_EQUAL(static_cast(-1270), getProperty(getParagraph(2), u"ParaFirstLineIndent"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testTdf81943) { createSwDoc("tdf81943.rtf"); // The shape wasn't in background. CPPUNIT_ASSERT_EQUAL(false, getProperty(getShape(1), u"Opaque"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testTdf115155) { createSwDoc("tdf115155.rtf"); auto xLevels = getProperty>(getParagraph(2), u"NumberingRules"_ustr); // 1st level comphelper::SequenceAsHashMap aMap(xLevels->getByIndex(0)); // This was 1270: the left margin in the numbering rule was too small. CPPUNIT_ASSERT_EQUAL(static_cast(2540), aMap[u"IndentAt"_ustr].get()); } CPPUNIT_TEST_FIXTURE(Test, testTdf108951) { createSwDoc("tdf108951.rtf"); // This test is import-only, as we assert the list ID, which is OK to // re-order on export, but then this test would not pass anymore. // \ls2 was imported as WWNum1. CPPUNIT_ASSERT_EQUAL(u"WWNum2"_ustr, getProperty(getParagraph(1), u"NumberingStyleName"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testFdo47036) { createSwDoc("fdo47036.rtf"); int nShapes = getShapes(); CPPUNIT_ASSERT_EQUAL(3, nShapes); int nAtCharacter = 0; for (int i = 0; i < nShapes; ++i) { if (getProperty(getShape(i + 1), u"AnchorType"_ustr) == text::TextContentAnchorType_AT_CHARACTER) nAtCharacter++; } // The image at the document start was ignored. CPPUNIT_ASSERT_EQUAL(1, nAtCharacter); // There should be 2 textboxes, not 4 uno::Reference xTextFramesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount()); } CPPUNIT_TEST_FIXTURE(Test, testFdo45182) { createSwDoc("fdo45182.rtf"); uno::Reference xFootnotesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xFootnotes = xFootnotesSupplier->getFootnotes(); uno::Reference xTextRange(xFootnotes->getByIndex(0), uno::UNO_QUERY); // Encoding in the footnote was wrong. CPPUNIT_ASSERT_EQUAL(u"\u017Eivnost\u00ED" SAL_NEWLINE_STRING ""_ustr, xTextRange->getString()); } CPPUNIT_TEST_FIXTURE(Test, testFdo85812) { createSwDoc("fdo85812.rtf"); lang::Locale locale( getProperty(getRun(getParagraph(1), 1, u"This "_ustr), u"CharLocale"_ustr)); // the \lang inside the group was applied to CJK not Western CPPUNIT_ASSERT_EQUAL(u"en"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"US"_ustr, locale.Country); // further testing indicates that Word is doing really weird stuff // \loch \hich \dbch is reset by opening a group locale = getProperty(getRun(getParagraph(2), 1, u"CharGroup"_ustr), u"CharLocale"_ustr); CPPUNIT_ASSERT_EQUAL(u"ru"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"RU"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(2), 2, u"AfterChar"_ustr), u"CharLocale"_ustr); CPPUNIT_ASSERT_EQUAL(u"en"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"US"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(3), 2, u"AfterBookmark"_ustr), u"CharLocale"_ustr); CPPUNIT_ASSERT_EQUAL(u"en"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"US"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(4), 1, u"CharGroup"_ustr), u"CharLocale"_ustr); CPPUNIT_ASSERT_EQUAL(u"ru"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"RU"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(4), 1, u"CharGroup"_ustr), u"CharLocaleComplex"_ustr); CPPUNIT_ASSERT_EQUAL(u"ar"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"DZ"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(4), 2, u"AfterChar"_ustr), u"CharLocale"_ustr); CPPUNIT_ASSERT_EQUAL(u"en"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"US"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(4), 2, u"AfterChar"_ustr), u"CharLocaleComplex"_ustr); CPPUNIT_ASSERT_EQUAL(u"ar"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"DZ"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(5), 2, u"AfterBookmark"_ustr), u"CharLocale"_ustr); CPPUNIT_ASSERT_EQUAL(u"en"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"US"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(5), 2, u"AfterBookmark"_ustr), u"CharLocaleComplex"_ustr); CPPUNIT_ASSERT_EQUAL(u"ar"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"DZ"_ustr, locale.Country); // \ltrch \rtlch works differently - it is sticky across groups locale = getProperty(getRun(getParagraph(6), 1, u"CharGroup"_ustr), u"CharLocale"_ustr); CPPUNIT_ASSERT_EQUAL(u"en"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"US"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(6), 1, u"CharGroup"_ustr), u"CharLocaleComplex"_ustr); CPPUNIT_ASSERT_EQUAL(u"ar"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"DZ"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(6), 2, u"AfterChar"_ustr), u"CharLocale"_ustr); CPPUNIT_ASSERT_EQUAL(u"en"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"US"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(6), 2, u"AfterChar"_ustr), u"CharLocaleComplex"_ustr); CPPUNIT_ASSERT_EQUAL(u"ar"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"EG"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(7), 2, u"AfterBookmark"_ustr), u"CharLocale"_ustr); CPPUNIT_ASSERT_EQUAL(u"en"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"US"_ustr, locale.Country); locale = getProperty(getRun(getParagraph(7), 2, u"AfterBookmark"_ustr), u"CharLocaleComplex"_ustr); CPPUNIT_ASSERT_EQUAL(u"ar"_ustr, locale.Language); CPPUNIT_ASSERT_EQUAL(u"EG"_ustr, locale.Country); } CPPUNIT_TEST_FIXTURE(Test, testFdo49692) { createSwDoc("fdo49692.rtf"); uno::Reference xPropertySet( getStyles(u"NumberingStyles"_ustr)->getByName(u"WWNum1"_ustr), uno::UNO_QUERY); uno::Reference xLevels( xPropertySet->getPropertyValue(u"NumberingRules"_ustr), uno::UNO_QUERY); uno::Sequence aProps; xLevels->getByIndex(0) >>= aProps; // 1st level for (int i = 0; i < aProps.getLength(); ++i) { const beans::PropertyValue& rProp = aProps[i]; if (rProp.Name == "Suffix") { CPPUNIT_ASSERT(rProp.Value.get().isEmpty()); } } } CPPUNIT_TEST_FIXTURE(Test, testFdo45190) { createSwDoc("fdo45190.rtf"); // inherited \fi should be reset CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty(getParagraph(1), u"ParaFirstLineIndent"_ustr)); // but direct one not CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(-100)), getProperty(getParagraph(2), u"ParaFirstLineIndent"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testTdf59699) { createSwDoc("tdf59699.rtf"); // This resulted in a lang.IndexOutOfBoundsException: the referenced graphic data wasn't imported. uno::Reference xImage(getShape(1), uno::UNO_QUERY); auto xGraphic = getProperty>(xImage, u"Graphic"_ustr); CPPUNIT_ASSERT(xGraphic.is()); } CPPUNIT_TEST_FIXTURE(Test, testFdo52066) { createSwDoc("fdo52066.rtf"); /* * The problem was that the height of the shape was too big. * * xray ThisComponent.DrawPage(0).Size.Height */ uno::Reference xShape = getShape(1); CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(19)), xShape->getSize().Height); } CPPUNIT_TEST_FIXTURE(Test, testTdf112211_2) { createSwDoc("tdf112211-2.rtf"); // Spacing between the bullet and the actual text was too large. // This is now around 269, large old value was 629. xmlDocUniquePtr pXmlDoc = parseLayoutDump(); int nWidth = getXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout/" "child::*[@type='PortionType::TabLeft']", "width") .toInt32(); CPPUNIT_ASSERT_LESS(300, nWidth); } CPPUNIT_TEST_FIXTURE(Test, testTdf122430) { createSwDoc("tdf122430.rtf"); // Without the accompanying fix in place, this test would have failed with // 'Expected: 18, Actual : 12', i.e. the font was smaller than expected. CPPUNIT_ASSERT_EQUAL(18.0f, getProperty(getRun(getParagraph(1), 2), u"CharHeight"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testFdo49892) { createSwDoc("fdo49892.rtf"); int nShapes = getShapes(); CPPUNIT_ASSERT_EQUAL(5, nShapes); for (int i = 0; i < nShapes; ++i) { OUString aDescription = getProperty(getShape(i + 1), u"Description"_ustr); if (aDescription == "red") CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty(getShape(i + 1), u"ZOrder"_ustr)); else if (aDescription == "green") CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty(getShape(i + 1), u"ZOrder"_ustr)); else if (aDescription == "blue") CPPUNIT_ASSERT_EQUAL(sal_Int32(2), getProperty(getShape(i + 1), u"ZOrder"_ustr)); else if (aDescription == "rect") { CPPUNIT_ASSERT_EQUAL( text::RelOrientation::PAGE_FRAME, getProperty(getShape(i + 1), u"HoriOrientRelation"_ustr)); CPPUNIT_ASSERT_EQUAL( text::RelOrientation::PAGE_FRAME, getProperty(getShape(i + 1), u"VertOrientRelation"_ustr)); } } } CPPUNIT_TEST_FIXTURE(Test, testFdo52052) { createSwDoc("fdo52052.rtf"); // Make sure the textframe containing the text "third" appears on the 3rd page. xmlDocUniquePtr pXmlDoc = parseLayoutDump(); assertXPathContent(pXmlDoc, "/root/page[3]/body/txt/anchored/fly/txt/text()", u"third"); } CPPUNIT_TEST_FIXTURE(Test, testInk) { createSwDoc("ink.rtf"); /* * The problem was that the second segment had wrong command count and wrap type. * * oShape = ThisComponent.DrawPage(0) * oPathPropVec = oShape.CustomShapeGeometry(1).Value * oSegments = oPathPropVec(1).Value * msgbox oSegments(1).Count ' was 0x2000 | 10, should be 10 * msgbox oShape.Surround ' was 2, should be 1 */ uno::Sequence aProps = getProperty>( getShape(1), u"CustomShapeGeometry"_ustr); uno::Sequence aPathProps; for (int i = 0; i < aProps.getLength(); ++i) { const beans::PropertyValue& rProp = aProps[i]; if (rProp.Name == "Path") rProp.Value >>= aPathProps; } uno::Sequence aSegments; for (int i = 0; i < aPathProps.getLength(); ++i) { const beans::PropertyValue& rProp = aPathProps[i]; if (rProp.Name == "Segments") rProp.Value >>= aSegments; } CPPUNIT_ASSERT_EQUAL(sal_Int16(10), aSegments[1].Count); CPPUNIT_ASSERT_EQUAL(text::WrapTextMode_THROUGH, getProperty(getShape(1), u"Surround"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testFdo79319) { createSwDoc("fdo79319.rtf"); // the thin horizontal rule was imported as a big fat rectangle uno::Reference xShape = getShape(1); CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty(xShape, u"RelativeWidth"_ustr)); CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(16508), xShape->getSize().Width, 10); CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(53), xShape->getSize().Height, 10); #if 0 CPPUNIT_ASSERT_EQUAL(text::VertOrientation::CENTER, getProperty(xShape, "VertOrient")); CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, getProperty(xShape, "HoriOrient")); #endif } CPPUNIT_TEST_FIXTURE(Test, testFdo48442) { createSwDoc("fdo48442.rtf"); // The problem was that \pvmrg is the default in RTF, but not in Writer. uno::Reference xShape = getShape(1); CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_PRINT_AREA, getProperty(xShape, u"VertOrientRelation"_ustr)); // was FRAME } CPPUNIT_TEST_FIXTURE(Test, testFdo55525) { createSwDoc("fdo55525.rtf"); uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); // Negative left margin was ~missing, -191 CPPUNIT_ASSERT_EQUAL(sal_Int32(-1877), getProperty(xTable, u"LeftMargin"_ustr)); // Cell width of A1 was 3332 (e.g. not set, 30% percent of total width) uno::Reference xTableRows = xTable->getRows(); CPPUNIT_ASSERT_EQUAL(sal_Int16(896), getProperty>( xTableRows->getByIndex(0), u"TableColumnSeparators"_ustr)[0] .Position); } CPPUNIT_TEST_FIXTURE(Test, testFdo57708) { createSwDoc("fdo57708.rtf"); // There were two issues: the doc was of 2 pages and the picture was missing. CPPUNIT_ASSERT_EQUAL(1, getPages()); // Two objects: a picture and a textframe. CPPUNIT_ASSERT_EQUAL(2, getShapes()); } CPPUNIT_TEST_FIXTURE(Test, testFdo45183) { createSwDoc("fdo45183.rtf"); // Was text::WrapTextMode_PARALLEL, i.e. shpfblwtxt didn't send the shape below text. CPPUNIT_ASSERT_EQUAL(text::WrapTextMode_THROUGH, getProperty(getShape(1), u"Surround"_ustr)); uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); // Was 247, resulting in a table having width almost zero and height of 10+ pages. CPPUNIT_ASSERT_EQUAL(sal_Int32(16237), getProperty(xTables->getByIndex(0), u"Width"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testFdo59953) { createSwDoc("fdo59953.rtf"); 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 width of A1 was 4998 (e.g. not set / not wide enough, ~50% of total width) uno::Reference xTableRows = xTable->getRows(); CPPUNIT_ASSERT_EQUAL(sal_Int16(7649), getProperty>( xTableRows->getByIndex(0), u"TableColumnSeparators"_ustr)[0] .Position); } CPPUNIT_TEST_FIXTURE(Test, testTdf84684) { createSwDoc("tdf84684.rtf"); // The ZOrder of the two children of the group shape were swapped. uno::Reference xGroup(getShape(1), uno::UNO_QUERY); uno::Reference xChild1(xGroup->getByIndex(0), uno::UNO_QUERY); // This was Pie 2. CPPUNIT_ASSERT_EQUAL(u"Rectangle 1"_ustr, xChild1->getName()); uno::Reference xChild2(xGroup->getByIndex(1), uno::UNO_QUERY); // This was Rectangle 1. CPPUNIT_ASSERT_EQUAL(u"Pie 2"_ustr, xChild2->getName()); } CPPUNIT_TEST_FIXTURE(Test, testFdo81944) { createSwDoc("fdo81944.rtf"); // font properties in style were not imported uno::Reference xPropertySet( getStyles(u"ParagraphStyles"_ustr)->getByName(u"Standard"_ustr), uno::UNO_QUERY); uno::Reference xStyle(xPropertySet, uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(u"Segoe UI"_ustr, getProperty(xStyle, u"CharFontName"_ustr)); CPPUNIT_ASSERT_EQUAL(9.0f, getProperty(xStyle, u"CharHeight"_ustr)); // not sure if this should be set on Asian or Complex or both? CPPUNIT_ASSERT_EQUAL(u"Times New Roman"_ustr, getProperty(xStyle, u"CharFontNameComplex"_ustr)); CPPUNIT_ASSERT_EQUAL(11.0f, getProperty(xStyle, u"CharHeightComplex"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testSbkodd) { createSwDoc("sbkodd.rtf"); uno::Reference xModel(mxComponent, uno::UNO_QUERY); uno::Reference xTextViewCursorSupplier( xModel->getCurrentController(), uno::UNO_QUERY); uno::Reference xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(1), xCursor->getPage()); xCursor->jumpToNextPage(); CPPUNIT_ASSERT_EQUAL(static_cast(3), xCursor->getPage()); } CPPUNIT_TEST_FIXTURE(Test, testSbkeven) { createSwDoc("sbkeven.rtf"); uno::Reference xModel(mxComponent, uno::UNO_QUERY); uno::Reference xTextViewCursorSupplier( xModel->getCurrentController(), uno::UNO_QUERY); uno::Reference xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast(1), xCursor->getPage()); xCursor->jumpToNextPage(); CPPUNIT_ASSERT_EQUAL(static_cast(2), xCursor->getPage()); xCursor->jumpToNextPage(); CPPUNIT_ASSERT_EQUAL(static_cast(4), xCursor->getPage()); } CPPUNIT_TEST_FIXTURE(Test, testPoshPosv) { createSwDoc("posh-posv.rtf"); CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, getProperty(getShape(1), u"HoriOrient"_ustr)); CPPUNIT_ASSERT_EQUAL(text::VertOrientation::CENTER, getProperty(getShape(1), u"VertOrient"_ustr)); CPPUNIT_ASSERT_EQUAL(true, getProperty(getShape(1), u"FrameIsAutomaticHeight"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testPoshLeftRight) { createSwDoc("posh-leftright.rtf"); CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::RIGHT, getProperty(getShape(1), u"HoriOrient"_ustr)); CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::LEFT, getProperty(getShape(2), u"HoriOrient"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testTdf96326) { createSwDoc("tdf96326.rtf"); // Make sure this is not checked. auto xFormField = getProperty>(getRun(getParagraph(1), 2), u"Bookmark"_ustr); uno::Reference xParameters = xFormField->getParameters(); // This was true, ffres=25 was interpreted as checked. CPPUNIT_ASSERT_EQUAL(false, bool(xParameters->hasElements())); // And this is checked. xFormField = getProperty>(getRun(getParagraph(2), 2), u"Bookmark"_ustr); xParameters = xFormField->getParameters(); CPPUNIT_ASSERT_EQUAL(true, xParameters->getByName(u"Checkbox_Checked"_ustr).get()); } CPPUNIT_TEST_FIXTURE(Test, testN823655) { createSwDoc("n823655.rtf"); uno::Sequence aProps = getProperty>( getShape(1), u"CustomShapeGeometry"_ustr); uno::Sequence aPathProps; for (int i = 0; i < aProps.getLength(); ++i) { const beans::PropertyValue& rProp = aProps[i]; if (rProp.Name == "Path") aPathProps = rProp.Value.get>(); } uno::Sequence aCoordinates; for (int i = 0; i < aPathProps.getLength(); ++i) { const beans::PropertyValue& rProp = aPathProps[i]; if (rProp.Name == "Coordinates") aCoordinates = rProp.Value.get>(); } // The first coordinate pair of this freeform shape was 286,0 instead of 0,286. CPPUNIT_ASSERT_EQUAL(sal_Int32(286), aCoordinates[0].Second.Value.get()); } CPPUNIT_TEST_FIXTURE(Test, testN823675) { createSwDoc("n823675.rtf"); uno::Reference xPropertySet( getStyles(u"NumberingStyles"_ustr)->getByName(u"WWNum1"_ustr), uno::UNO_QUERY); uno::Reference xLevels( xPropertySet->getPropertyValue(u"NumberingRules"_ustr), uno::UNO_QUERY); uno::Sequence aProps; xLevels->getByIndex(0) >>= aProps; // 1st level awt::FontDescriptor aFont; for (int i = 0; i < aProps.getLength(); ++i) { const beans::PropertyValue& rProp = aProps[i]; if (rProp.Name == "BulletFont") aFont = rProp.Value.get(); } // This was empty, i.e. no font name was set for the bullet numbering. CPPUNIT_ASSERT_EQUAL(u"Symbol"_ustr, aFont.Name); } CPPUNIT_TEST_FIXTURE(Test, testGroupshape) { createSwDoc("groupshape.rtf"); // There should be a single groupshape with 2 children. CPPUNIT_ASSERT_EQUAL(1, getShapes()); uno::Reference xGroupshape(getShape(1), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xGroupshape->getCount()); } CPPUNIT_TEST_FIXTURE(Test, testGroupshape_notext) { createSwDoc("groupshape-notext.rtf"); // There should be a single groupshape with 2 children. CPPUNIT_ASSERT_EQUAL(1, getShapes()); uno::Reference xGroupshape(getShape(1), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xGroupshape->getCount()); } CPPUNIT_TEST_FIXTURE(Test, testFdo81033) { createSwDoc("fdo81033.rtf"); // Number of tabstops in the paragraph should be 2, was 3. uno::Sequence tabs( getProperty>(getParagraph(1), u"ParaTabStops"_ustr)); CPPUNIT_ASSERT_EQUAL(sal_Int32(2), tabs.getLength()); CPPUNIT_ASSERT_EQUAL(sal_Int32(5808), tabs[0].Position); CPPUNIT_ASSERT_EQUAL(style::TabAlign_LEFT, tabs[0].Alignment); CPPUNIT_ASSERT_EQUAL(u' ', tabs[0].FillChar); CPPUNIT_ASSERT_EQUAL(sal_Int32(16002), tabs[1].Position); CPPUNIT_ASSERT_EQUAL(style::TabAlign_LEFT, tabs[1].Alignment); CPPUNIT_ASSERT_EQUAL(u'_', tabs[1].FillChar); } CPPUNIT_TEST_FIXTURE(Test, testTdf116269) { createSwDoc("tdf116269.rtf"); // This was 2540, implicit 0 left margin was ignored on import (inherited // value from list definition is repeated if it's not 0). CPPUNIT_ASSERT_EQUAL(static_cast(0), getProperty(getParagraph(1), u"ParaLeftMargin"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testTdf116265) { createSwDoc("tdf116265.rtf"); // This was -635, \fi as direct formatting has to be ignored due to // matching \fi in list definition (and with invalid level numbers). CPPUNIT_ASSERT_EQUAL(static_cast(0), getProperty(getParagraph(2), u"ParaFirstLineIndent"_ustr)); xmlDocUniquePtr pLayout = parseLayoutDump(); // Ensure that there is a tabstop in the pseudo-numbering (numbering::NONE followed by tabstop) assertXPath(pLayout, "//SwFixPortion", 1); } CPPUNIT_TEST_FIXTURE(Test, testFdo66565) { createSwDoc("fdo66565.rtf"); 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 width of A2 was 554, should be 453/14846*10000 uno::Reference xTableRows = xTable->getRows(); CPPUNIT_ASSERT_EQUAL(sal_Int16(304), getProperty>( xTableRows->getByIndex(1), u"TableColumnSeparators"_ustr)[0] .Position); } CPPUNIT_TEST_FIXTURE(Test, testFdo67365) { createSwDoc("fdo67365.rtf"); 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 xRows = xTable->getRows(); // The table only had 3 rows. CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xRows->getCount()); // This was 4999, i.e. the two cells of the row had equal widths instead of a larger and a smaller cell. CPPUNIT_ASSERT_EQUAL(sal_Int16(5290), getProperty>( xRows->getByIndex(2), u"TableColumnSeparators"_ustr)[0] .Position); uno::Reference xCell(xTable->getCellByName(u"A2"_ustr), uno::UNO_QUERY); // Paragraph was aligned to center, should be left. CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_LEFT, static_cast(getProperty( getParagraphOfText(1, xCell->getText()), u"ParaAdjust"_ustr))); } CPPUNIT_TEST_FIXTURE(Test, testFdo47440) { createSwDoc("fdo47440.rtf"); // Vertical and horizontal orientation of the picture wasn't imported (was text::RelOrientation::FRAME). CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty(getShape(1), u"HoriOrientRelation"_ustr)); CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty(getShape(1), u"VertOrientRelation"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testFdo53556) { createSwDoc("fdo53556.rtf"); // This was drawing::FillStyle_SOLID, which resulted in being non-transparent, hiding text which would be visible. CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty(getShape(3), u"FillStyle"_ustr)); // This was a com.sun.star.drawing.CustomShape, which resulted in lack of word wrapping in the bugdoc. uno::Reference xShapeProperties(getShape(1), uno::UNO_QUERY); uno::Reference xShapeDescriptor(xShapeProperties, uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(u"FrameShape"_ustr, xShapeDescriptor->getShapeType()); } CPPUNIT_TEST_FIXTURE(Test, testGroupshapeRotation) { createSwDoc("groupshape-rotation.rtf"); // Rotation on groupshapes wasn't handled correctly, RotateAngle was 4500. CPPUNIT_ASSERT_EQUAL(sal_Int32(315 * 100), getProperty(getShape(1), u"RotateAngle"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testTdf115153) { createSwDoc("tdf115153.rtf"); auto const xShape(getShape(1)); CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::NONE, getProperty(xShape, u"HoriOrient"_ustr)); CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty(xShape, u"HoriOrientRelation"_ustr)); CPPUNIT_ASSERT_EQUAL(sal_Int32(2533), getProperty(xShape, u"HoriOrientPosition"_ustr)); // VertOrient was wrong CPPUNIT_ASSERT_EQUAL(text::VertOrientation::NONE, getProperty(xShape, u"VertOrient"_ustr)); CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty(xShape, u"VertOrientRelation"_ustr)); CPPUNIT_ASSERT_EQUAL(sal_Int32(2131), getProperty(xShape, u"VertOrientPosition"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, test165717Tdf) { createSwDoc("165717.rtf"); uno::Reference const xPara3PS(getParagraphOrTable(3), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(u"Converted1"_ustr, getProperty(xPara3PS, u"PageDescName"_ustr)); CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty(xPara3PS, u"PageNumberOffset"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testFdo68291) { createSwDoc("fdo68291.odt"); uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference xText = xTextDocument->getText(); uno::Reference xEnd = xText->getEnd(); paste(u"rtfimport/data/fdo68291-paste.rtf", u"com.sun.star.comp.Writer.RtfFilter"_ustr, xEnd); // This was "Standard", causing an unwanted page break on next paste. CPPUNIT_ASSERT_EQUAL(uno::Any(), uno::Reference(getParagraph(1), uno::UNO_QUERY_THROW) ->getPropertyValue(u"PageDescName"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testTdf105511) { struct DefaultLocale : public comphelper::ConfigurationProperty { static OUString path() { return u"/org.openoffice.Office.Linguistic/General/DefaultLocale"_ustr; } ~DefaultLocale() = delete; }; auto batch = comphelper::ConfigurationChanges::create(); DefaultLocale::set(u"ru-RU"_ustr, batch); batch->commit(); createSwDoc("tdf105511.rtf"); getParagraph(1, u"\u0418\u043C\u044F"_ustr); } CPPUNIT_TEST_FIXTURE(Test, testContSectionPageBreak) { createSwDoc("cont-section-pagebreak.rtf"); uno::Reference xParaSecond = getParagraph(2); CPPUNIT_ASSERT_EQUAL(u"SECOND"_ustr, xParaSecond->getString()); CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, getProperty(xParaSecond, u"BreakType"_ustr)); CPPUNIT_ASSERT_EQUAL(uno::Any(), uno::Reference(xParaSecond, uno::UNO_QUERY_THROW) ->getPropertyValue(u"PageDescName"_ustr)); // actually not sure how many paragraph there should be between // SECOND and THIRD - important is that the page break is on there // (could be either 1 or 2; in Word it's a 2-line paragraph with the 1st // line containing only the page break being ~0 height) uno::Reference xParaNext = getParagraph(3); CPPUNIT_ASSERT_EQUAL(OUString(), xParaNext->getString()); //If PageDescName is not empty, a page break / switch to page style is defined CPPUNIT_ASSERT(uno::Any() != getProperty(xParaNext, u"PageDescName"_ustr)); uno::Reference xParaThird = getParagraph(4); CPPUNIT_ASSERT_EQUAL(u"THIRD"_ustr, xParaThird->getString()); CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, getProperty(xParaThird, u"BreakType"_ustr)); CPPUNIT_ASSERT_EQUAL(uno::Any(), uno::Reference(xParaThird, uno::UNO_QUERY_THROW) ->getPropertyValue(u"PageDescName"_ustr)); // there is an empty paragraph after THIRD uno::Reference xParaLast = getParagraph(5); CPPUNIT_ASSERT_EQUAL(OUString(), xParaLast->getString()); try { getParagraph(6); } catch (container::NoSuchElementException const&) { // does not exist - expected } CPPUNIT_ASSERT_EQUAL(2, getPages()); } CPPUNIT_TEST_FIXTURE(Test, testSectionPageBreak) { createSwDoc("section-pagebreak.rtf"); uno::Reference xParaSecond = getParagraph(2); CPPUNIT_ASSERT_EQUAL(u"SECOND"_ustr, xParaSecond->getString()); CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, getProperty(xParaSecond, u"BreakType"_ustr)); CPPUNIT_ASSERT(uno::Any() != getProperty(xParaSecond, u"PageDescName"_ustr)); // actually not sure how many paragraph there should be between // SECOND and THIRD - important is that the page break is on there // (could be either 1 or 2; in Word it's a 2-line paragraph with the 1st // line containing only the page break being ~0 height) uno::Reference xParaNext = getParagraph(3); CPPUNIT_ASSERT_EQUAL(OUString(), xParaNext->getString()); //If PageDescName is not empty, a page break / switch to page style is defined CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, getProperty(xParaNext, u"BreakType"_ustr)); uno::Reference xParaThird = getParagraph(4); CPPUNIT_ASSERT_EQUAL(u"THIRD"_ustr, xParaThird->getString()); CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, getProperty(xParaThird, u"BreakType"_ustr)); CPPUNIT_ASSERT(uno::Any() != getProperty(xParaThird, u"PageDescName"_ustr)); // there is an empty paragraph after THIRD uno::Reference xParaLast = getParagraph(5); CPPUNIT_ASSERT_EQUAL(OUString(), xParaLast->getString()); try { getParagraph(6); } catch (container::NoSuchElementException const&) { // does not exist - expected } CPPUNIT_ASSERT_EQUAL(4, getPages()); } CPPUNIT_TEST_FIXTURE(Test, testBackground) { createSwDoc("background.rtf"); // The first shape wasn't in the foreground. CPPUNIT_ASSERT_EQUAL(true, getProperty(getShape(1), u"Opaque"_ustr)); CPPUNIT_ASSERT_EQUAL(false, getProperty(getShape(2), u"Opaque"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testFdo74823) { createSwDoc("fdo74823.rtf"); 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 width of C2 was too large / column separator being 3749 too small (e.g. not set, around 3/7 of total width) uno::Reference xTableRows = xTable->getRows(); CPPUNIT_ASSERT_EQUAL(sal_Int16(5391), getProperty>( xTableRows->getByIndex(1), u"TableColumnSeparators"_ustr)[2] .Position); } CPPUNIT_TEST_FIXTURE(Test, testFdo74599) { createSwDoc("fdo74599.rtf"); uno::Reference xPropertySet( getStyles(u"ParagraphStyles"_ustr)->getByName(u"Heading 3"_ustr), uno::UNO_QUERY); // Writer default styles weren't disabled, so the color was gray, not default (black). CPPUNIT_ASSERT_EQUAL(static_cast(-1), getProperty(xPropertySet, u"CharColor"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testColumnBreak) { createSwDoc("column-break.rtf"); // Column break at the very start of the document was ignored. CPPUNIT_ASSERT_EQUAL(style::BreakType_COLUMN_BEFORE, getProperty(getParagraph(2), u"BreakType"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testTdf166191) { createSwDoc("tdf166191.rtf"); //text of second paragraph should be in 12pt and not bold uno::Reference textRun = getRun(getParagraph(2), 1); CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty(textRun, u"CharWeight"_ustr)); CPPUNIT_ASSERT_EQUAL(12.0f, getProperty(textRun, u"CharHeight"_ustr)); } // tests should only be added to rtfIMPORT *if* they fail round-tripping in rtfEXPORT } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */