/* -*- 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/.
*/
CPPUNIT_TEST_FIXTURE(Test, testTdf131540)
{
loadAndReload("tdf131540.odt");
CPPUNIT_ASSERT_EQUAL(2, getShapes());
CPPUNIT_ASSERT_EQUAL(1, getPages()); // There are 2 OLEs test if one of them moved on save:
CPPUNIT_ASSERT_EQUAL_MESSAGE("The shape1 moved on saving!", text::RelOrientation::PAGE_FRAME,
getProperty<sal_Int16>(getShape(1), u"HoriOrientRelation"_ustr));
CPPUNIT_ASSERT_EQUAL_MESSAGE("The shape2 moved on saving!", text::RelOrientation::PAGE_FRAME,
getProperty<sal_Int16>(getShape(2), u"HoriOrientRelation"_ustr));
}
CPPUNIT_TEST_FIXTURE(Test, testTdf131801)
{ auto verify = [this]() {
CPPUNIT_ASSERT_EQUAL(1, getPages());
xmlDocUniquePtr pDump = parseLayoutDump(); // "1." is red
assertXPath(pDump, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u"1.");
assertXPath(pDump, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont", "color", u"00ff0000"); // "2." is red
assertXPath(pDump, "//page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u"2.");
assertXPath(pDump, "//page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont", "color", u"00ff0000"); // "3." is black
assertXPath(pDump, "//page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u"3.");
assertXPath(pDump, "//page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont", "color", u"ffffffff"); // "4." is black
assertXPath(pDump, "//page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u"4.");
assertXPath(pDump, "//page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont", "color", u"ffffffff"); // "5." is red
assertXPath(pDump, "//page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u"5.");
assertXPath(pDump, "//page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont", "color", u"00ff0000"); // "6." is red
assertXPath(pDump, "//page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u"6.");
assertXPath(pDump, "//page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont", "color", u"00ff0000"); // "7." is black
assertXPath(pDump, "//page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u"7.");
assertXPath(pDump, "//page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont", "color", u"ffffffff"); // "8." is black
assertXPath(pDump, "//page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwFieldPortion[1]", "expand", u"8.");
assertXPath(pDump, "//page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwFieldPortion[1]/SwFont", "color", u"ffffffff");
};
DECLARE_OOXMLEXPORT_TEST(testTdf137850_compat14ZOrder, "tdf137850_compat14ZOrder.docx")
{ // The file contains 2 shapes which have a different value of behindDoc. // Test that the textbox is hidden behind the arrow (for Word <= 2010/compatibilityMode==14)
uno::Reference<text::XText> xShape(getShape(1), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"2015"_ustr, xShape->getString());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Textbox is in the background", false, getProperty<bool>(xShape, u"Opaque"_ustr));
}
DECLARE_OOXMLEXPORT_TEST(testTdf137850_compat15ZOrder, "tdf137850_compat15ZOrder.docx")
{ // The file contains 2 shapes which have a different value of behindDoc. // Test that the textbox is not hidden behind the arrow (for Word >= 2013/compatibilityMode==15)
uno::Reference<text::XText> xShape(getShape(2), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"2015"_ustr, xShape->getString());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Textbox is in the foreground", true, getProperty<bool>(xShape, u"Opaque"_ustr));
}
CPPUNIT_TEST_FIXTURE(Test, testTdf118701)
{
loadAndSave("tdf118701.docx"); // This was 6, related to moving inline images after the page breaks
CPPUNIT_ASSERT_EQUAL(4, getPages());
// Keep numbering of the paragraph of the inline image
assertXPath(pXmlDoc, "/w:document/w:body/w:p[8]/w:pPr[1]/w:numPr", 0);
assertXPath(pXmlDoc, "/w:document/w:body/w:p[9]/w:pPr[1]/w:numPr", 1); // This was 0
assertXPath(pXmlDoc, "/w:document/w:body/w:p[10]/w:pPr[1]/w:numPr", 1);
}
// Tests new cell formula AVERAGE
uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"AVERAGE()"_ustr, xEnumerationAccess1->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(u"3"_ustr, xEnumerationAccess1->getPresentation(false).trim());
// MEAN converted to AVERAGE
assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:instrText", u" =AVERAGE(A1:A2)");
assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:instrText", u" =AVERAGE(A1:A3)");
}
// Without the fix in place, this test would have failed with // - Expected: ab=cd.. // - Actual : abcd..
CPPUNIT_ASSERT_EQUAL(u"ab=cd.."_ustr, xEnumerationAccess->getPresentation(true).trim());
};
// Ignore empty cells or cells with text content with new interoperability functions COUNT, AVERAGE and PRODUCT
uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"COUNT()"_ustr, xEnumerationAccess1->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(u"2"_ustr, xEnumerationAccess1->getPresentation(false).trim());
uno::Reference<text::XTextField> xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"AVERAGE()"_ustr, xEnumerationAccess2->getPresentation(true).trim()); // This was 0
CPPUNIT_ASSERT_EQUAL(u"** Expression is faulty **"_ustr, xEnumerationAccess2->getPresentation(false).trim());
uno::Reference<text::XTextField> xEnumerationAccess3(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"AVERAGE()"_ustr, xEnumerationAccess3->getPresentation(true).trim()); // This was 0
CPPUNIT_ASSERT_EQUAL(u"** Expression is faulty **"_ustr, xEnumerationAccess3->getPresentation(false).trim());
uno::Reference<text::XTextField> xEnumerationAccess4(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"COUNT()"_ustr, xEnumerationAccess4->getPresentation(true).trim()); // This was 2
CPPUNIT_ASSERT_EQUAL(u"0"_ustr, xEnumerationAccess4->getPresentation(false).trim());
uno::Reference<text::XTextField> xEnumerationAccess5(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"COUNT()"_ustr, xEnumerationAccess5->getPresentation(true).trim()); // This was 1
CPPUNIT_ASSERT_EQUAL(u"0"_ustr, xEnumerationAccess5->getPresentation(false).trim());
uno::Reference<text::XTextField> xEnumerationAccess6(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"PRODUCT()"_ustr, xEnumerationAccess6->getPresentation(true).trim()); // This was 0
CPPUNIT_ASSERT_EQUAL(u"60"_ustr, xEnumerationAccess6->getPresentation(false).trim());
uno::Reference<text::XTextField> xEnumerationAccess7(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"AVERAGE()"_ustr, xEnumerationAccess7->getPresentation(true).trim()); // This was 2
CPPUNIT_ASSERT_EQUAL(u"8"_ustr, xEnumerationAccess7->getPresentation(false).trim());
}
DECLARE_OOXMLEXPORT_TEST(testTdf138739, "tdf138739.docx")
{
uno::Reference<beans::XPropertySet> xParaProps(getParagraph(1), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Font type name does not match!", u"Comic Sans MS"_ustr,
xParaProps->getPropertyValue(u"CharFontName"_ustr).get<OUString>());
// tdf#148565: text at anchor point should be bold, Comic Sans MS font
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(getRun(getParagraph(5), 3), u"CharWeight"_ustr));
}
CPPUNIT_TEST_FIXTURE(Test, testTdf166436)
{ // Without the fix in place, this test would have crashed at import time
loadAndReload("tdf166436.docx");
uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
CPPUNIT_ASSERT(xFieldsAccess->hasElements());
}
// Tests new cell formula MOD
uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"MOD(()|())"_ustr, xEnumerationAccess1->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(u"2"_ustr, xEnumerationAccess1->getPresentation(false).trim());
// Tests conversion of range IDs ABOVE, BELOW, LEFT and RIGHT
uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY); // Note: range ends at B4 here, which is a cell with text content
CPPUNIT_ASSERT_EQUAL(u"average( )"_ustr, xEnumerationAccess1->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(u"5,5"_ustr, xEnumerationAccess1->getPresentation(false).trim());
// range ends at the end of the empty cells
uno::Reference<text::XTextField> xEnumerationAccess6(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"SUM()"_ustr, xEnumerationAccess6->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(u"0"_ustr, xEnumerationAccess6->getPresentation(false).trim());
// range starts at the first cell above D5
uno::Reference<text::XTextField> xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"AVERAGE()"_ustr, xEnumerationAccess2->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(u"5,33"_ustr, xEnumerationAccess2->getPresentation(false).trim());
// Tests conversion of range IDs ABOVE, BELOW, LEFT and RIGHT
uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY); // Note: range ends at B4 here, which is a cell with text content
CPPUNIT_ASSERT_EQUAL(u"MAX()"_ustr, xEnumerationAccess1->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(u"12"_ustr, xEnumerationAccess1->getPresentation(false).trim());
// range ends at the end of the empty cells
uno::Reference<text::XTextField> xEnumerationAccess6(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"MAX()"_ustr, xEnumerationAccess6->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(u"9"_ustr, xEnumerationAccess6->getPresentation(false).trim());
// range starts at the first cell above D5
uno::Reference<text::XTextField> xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"SUM()"_ustr, xEnumerationAccess2->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(u"30"_ustr, xEnumerationAccess2->getPresentation(false).trim());
// table formula conversion worked only in the first table
uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u""_ustr, xEnumerationAccess1->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(u"1"_ustr, xEnumerationAccess1->getPresentation(false).trim());
// These were <?> and SUM(<?:?>) with zero values
uno::Reference<text::XTextField> xEnumerationAccess3(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u""_ustr, xEnumerationAccess3->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(u"1"_ustr, xEnumerationAccess3->getPresentation(false).trim());
// Sanity check - always good to test when dealing with page styles and breaks.
CPPUNIT_ASSERT_EQUAL(5, getPages());
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
// Page Style should be explicitly mentioned - otherwise it would be a "follow" style
uno::Reference<beans::XPropertySet> xPara(getParagraph(2, u"2"_ustr), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT(uno::Any() != xPara->getPropertyValue(u"PageDescName"_ustr)); // CPPUNIT_ASSERT_EQUAL(OUString("First Page header"), // getXPathContent(pXmlDoc, "/root/page[2]/header/txt"));
// Page Style is converted into a page break instead. Still shows "first" header.
xPara.set(getParagraph(3, u"3"_ustr), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_EQUAL(uno::Any(), xPara->getPropertyValue(u"PageDescName"_ustr)); // CPPUNIT_ASSERT_EQUAL(OUString("Default page style - first page style"), // getXPathContent(pXmlDoc, "/root/page[3]/header/txt"));
assertXPathContent(pXmlDoc, "/root/page[3]/footer/txt", u"");
// Page Style is converted into a page break instead. Shows the "normal" header.
xPara.set(getParagraph(5, u"4"_ustr), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_EQUAL(uno::Any(), xPara->getPropertyValue(u"PageDescName"_ustr));
assertXPathContent(pXmlDoc, "/root/page[4]/header/txt", u"Default page style");
// Page Style is retained (with wrong header) in order to preserve page re-numbering.
xPara.set(getParagraph(7, u"1"_ustr), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT(uno::Any() != xPara->getPropertyValue(u"PageDescName"_ustr));
assertXPathContent(pXmlDoc, "/root/page[5]/footer/txt", u"");
}
CPPUNIT_TEST_FIXTURE(Test, testTdf136929_framesOfParagraph)
{
loadAndReload("tdf136929_framesOfParagraph.odt"); // Before this fix, the image was placed in the footer instead of in the text body - messing everything up.
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Pages", 5, getPages() );
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
CPPUNIT_ASSERT_EQUAL_MESSAGE("Header2 text", u"* | *"_ustr, getXPathContent(pXmlDoc, "/root/page[4]/footer/txt"));
}
DECLARE_OOXMLEXPORT_TEST(testTdf136589_paraHadField, "tdf136589_paraHadField.docx")
{ // The section break should not add an additional CR - which equals an empty page two.
CPPUNIT_ASSERT_EQUAL(2, getPages());
//tdf#118711 - don't explicitly specify the default page style at the beginning of the document
uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_EQUAL(uno::Any(), xPara->getPropertyValue(u"PageDescName"_ustr));
}
CPPUNIT_TEST_FIXTURE(Test, testTdf133370_columnBreak)
{
loadAndReload("tdf133370_columnBreak.odt"); // Since non-DOCX formats ignores column breaks in non-column situations, don't export to docx.
CPPUNIT_ASSERT_EQUAL(1, getPages());
}
CPPUNIT_TEST_FIXTURE(Test, testTdf134649_pageBreak)
{
loadAndReload("tdf134649_pageBreak.fodt"); // This was 1 (missing page break between tables).
CPPUNIT_ASSERT_EQUAL(2, getPages());
}
DECLARE_OOXMLEXPORT_TEST(testTdf135343_columnSectionBreak_c14v2, "tdf135343_columnSectionBreak_c14v2.docx")
{ // In this Word 2010 v2, section three was changed to start with a nextColumn break instead of a continuous break. // The previous section has no columns, so this time start the columns on a new page.
uno::Reference<beans::XPropertySet> xTextSection = getProperty<uno::Reference<beans::XPropertySet>>(getParagraph(10, u""_ustr), u"TextSection"_ustr);
uno::Reference<text::XTextColumns> xTextColumns = getProperty<uno::Reference<text::XTextColumns>>(xTextSection, u"TextColumns"_ustr);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Section three's columns", sal_Int16(3), xTextColumns->getColumnCount()); //CPPUNIT_ASSERT_EQUAL(2, getPages());
}
DECLARE_OOXMLEXPORT_TEST(testTdf135343_columnSectionBreak_c12v3, "tdf135343_columnSectionBreak_c12v3.docx")
{ // In this Word 20-3 v3, section one and two have different number of columns. It acts like a page break.
uno::Reference<beans::XPropertySet> xTextSection = getProperty<uno::Reference<beans::XPropertySet>>(getParagraph(1, u"Four columns,"_ustr), u"TextSection"_ustr);
uno::Reference<text::XTextColumns> xTextColumns = getProperty<uno::Reference<text::XTextColumns>>(xTextSection, u"TextColumns"_ustr);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Section one's columns", sal_Int16(4), xTextColumns->getColumnCount());
DECLARE_OOXMLEXPORT_TEST(testTdf135343_columnSectionBreak_c15, "tdf135343_columnSectionBreak_c15.docx")
{ // Word 2013+ version - nextColumn breaks inside column sections are always handled like nextPage breaks.
uno::Reference<beans::XPropertySet> xTextSection = getProperty<uno::Reference<beans::XPropertySet>>(getParagraph(12, u"RTL 2"_ustr), u"TextSection"_ustr);
uno::Reference<text::XTextColumns> xTextColumns = getProperty<uno::Reference<text::XTextColumns>>(xTextSection, u"TextColumns"_ustr);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Section four's columns", sal_Int16(3), xTextColumns->getColumnCount());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Fits on two pages", 2, getPages());
}
DECLARE_OOXMLEXPORT_TEST(testTdf121669_equalColumns, "tdf121669_equalColumns.docx")
{
uno::Reference<beans::XPropertySet> xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(1), u"TextSection"_ustr);
CPPUNIT_ASSERT(xTextSection.is());
uno::Reference<text::XTextColumns> xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, u"TextColumns"_ustr); // The property was ignored when deciding at export whether the columns were equal or not. Layout isn't reliable.
CPPUNIT_ASSERT(getProperty<bool>(xTextColumns, u"IsAutomatic"_ustr));
}
CPPUNIT_TEST_FIXTURE(Test, testTdf132149_pgBreak)
{
loadAndReload("tdf132149_pgBreak.odt"); // This 5 page document is designed to visually exaggerate the problems // of emulating LO's followed-by-page-style into MSWord's sections. // While much has been improved, there are extra pages present, which still need fixing.
xmlDocUniquePtr pDump = parseLayoutDump();
// No header on pages 1,2,3.
assertXPath(pDump, "//page[2]/header", 0);
// Margins/page orientation between Right and Left page styles are different
assertXPath(pDump, "//page[1]/infos/prtBounds", "left", u"1134"); //Right page style
assertXPath(pDump, "//page[2]/infos/prtBounds", "left", u"2268"); //Left page style
assertXPath(pDump, "//page[1]/infos/bounds", "width", u"8391"); //landscape
assertXPath(pDump, "//page[2]/infos/bounds", "width", u"5940"); //portrait // This two-line 3rd page ought not to exist. DID YOU FIX ME? The real page 3 should be "8391" landscape.
assertXPath(pDump, "//page[3]/infos/bounds", "width", u"5940"); // This really ought to be on odd page 3, but now it is on odd page 5.
assertXPath(pDump, "//page[5]/infos/bounds", "width", u"8391");
assertXPath(pDump, "//page[5]/infos/prtBounds", "right", u"6122"); //Left page style
//Page style change here must not be lost. This SHOULD be on page 4, but sadly it is not.
assertXPathContent(pDump, "//page[6]/header/txt", u"First Page Style");
CPPUNIT_ASSERT(getXPathContent(pDump, "//page[6]/body/txt[1]").startsWith("Lorem ipsum"));
}
CPPUNIT_TEST_FIXTURE(Test, testTdf132149_pgBreakB)
{
loadAndReload("tdf132149_pgBreakB.odt"); // This 5 page document is designed to visually exaggerate the problems // of emulating LO's followed-by-page-style into MSWord's sections.
xmlDocUniquePtr pDump = parseLayoutDump();
//Sanity check to ensure the correct page is being tested. This SHOULD be on page 3, but sadly it is not.
CPPUNIT_ASSERT(getXPathContent(pDump, "//page[5]/body/txt[1]").startsWith("Lorem ipsum")); //Prior to this fix, the original alternation between portrait and landscape was completely lost.
assertXPath(pDump, "//page[5]/infos/bounds", "width", u"8391"); //landscape
}
CPPUNIT_TEST_FIXTURE(Test, testTdf132149_pgBreak2)
{
loadAndReload("tdf132149_pgBreak2.odt"); // This 3 page document is designed to visually exaggerate the problems // of emulating LO's followed-by-page-style into MSWord's sections.
// The only specified page style change should be between page 1 and 2. // When the first paragraph was split into 3, each paragraph specified a page break. The last was unnecessary.
uno::Reference<beans::XPropertySet> xParaThree(getParagraph(3), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_EQUAL(uno::Any(), xParaThree->getPropertyValue(u"PageDescName"_ustr)); // The ODT is only 2 paragraphs, but a hack to get the right page style breaks para1 into pieces. // This was 4 paragraphs - the unnecessary page break had hacked in another paragraph split.
CPPUNIT_ASSERT_LESSEQUAL( 3, getParagraphs() );
}
CPPUNIT_TEST_FIXTURE(Test, testTdf136952_pgBreak3B)
{
loadAndReload("tdf136952_pgBreak3B.odt"); // This 4 page document is designed to visually exaggerate the problems // of emulating LO's followed-by-page-style into MSWord's sections.
xmlDocUniquePtr pDump = parseLayoutDump();
//page::breakAfter must not be lost. //Prior to this bug fix, the Lorem ipsum paragraph was in the middle of a portrait page, with no switch to landscape occurring.
CPPUNIT_ASSERT(getXPathContent(pDump, "//page[3]/body/txt[1]").startsWith("Lorem ipsum"));
assertXPath(pDump, "//page[3]/infos/bounds", "width", u"8391"); //landscape
}
DECLARE_OOXMLEXPORT_TEST(testTdf135949_anchoredBeforeBreak, "tdf135949_anchoredBeforeBreak.docx")
{
xmlDocUniquePtr pDump = parseLayoutDump(); //The picture was shown on page 2, because the empty paragraph before the page break was removed
assertXPath(pDump, "//page[1]/body/txt/anchored/fly", 1);
}
// The outside border should not be applied on inside cells. The merge doesn't extend to the table bottom. // [Note: as humans, we would call this cell D3, but since row 4 hasn't been analyzed yet, it is considered column C.]
table::BorderLine2 aBorder = getProperty<table::BorderLine2>(xTable->getCellByName(u"C3"_ustr), u"BottomBorder"_ustr);
CPPUNIT_ASSERT_EQUAL_MESSAGE("No bottom border on merged cell", sal_uInt32(0), aBorder.LineWidth);
// [Note: as humans, we would call this cell C3, but since row 4 hasn't been analyzed yet, it is considered column B.]
aBorder = getProperty<table::BorderLine2>(xTable->getCellByName(u"B3"_ustr), u"BottomBorder"_ustr);
CPPUNIT_ASSERT_EQUAL_MESSAGE("No bottom border on merged cell", sal_uInt32(0), aBorder.LineWidth);
}
// The bottom border from the last merged cell was not showing
table::BorderLine2 aBorder = getProperty<table::BorderLine2>(xTable->getCellByName(u"A1"_ustr), u"BottomBorder"_ustr);
CPPUNIT_ASSERT_MESSAGE("Bottom border on merged cell", aBorder.LineWidth > 0);
}
// A border defined on an earlier merged cell was showing
table::BorderLine2 aBorder = getProperty<table::BorderLine2>(xTable->getCellByName(u"C1"_ustr), u"BottomBorder"_ustr);
CPPUNIT_ASSERT_EQUAL_MESSAGE("No bottom border on merged cell", sal_uInt32(0), aBorder.LineWidth); // MS Word is interesting here. 2/3 of the merged cell has the right border, so what to do?
aBorder = getProperty<table::BorderLine2>(xTable->getCellByName(u"C1"_ustr), u"RightBorder"_ustr);
CPPUNIT_ASSERT_EQUAL_MESSAGE("No right border on merged cell", sal_uInt32(0), aBorder.LineWidth);
}
// Hand-crafted pre-emptive test to make sure borders aren't lost. // MS Word is interesting here. 2/3 of the merged cell has the right border, so what to do?
table::BorderLine2 aBorderR = getProperty<table::BorderLine2>(xTable->getCellByName(u"A1"_ustr), u"RightBorder"_ustr);
table::BorderLine2 aBorderL = getProperty<table::BorderLine2>(xTable->getCellByName(u"B1"_ustr), u"LeftBorder"_ustr);
CPPUNIT_ASSERT_MESSAGE("Border between A1 and B1", (aBorderR.LineWidth + aBorderL.LineWidth) > 0);
aBorderR = getProperty<table::BorderLine2>(xTable->getCellByName(u"A3"_ustr), u"RightBorder"_ustr);
aBorderL = getProperty<table::BorderLine2>(xTable->getCellByName(u"B3"_ustr), u"LeftBorder"_ustr);
CPPUNIT_ASSERT_MESSAGE("Border between A3 and B3", (aBorderR.LineWidth + aBorderL.LineWidth) > 0);
}
// Table borders (width 159) apply to edge cells, even in uneven cases caused by gridBefore/gridAfter,
table::BorderLine2 aBorder = getProperty<table::BorderLine2>(xTable->getCellByName(u"A1"_ustr), u"RightBorder"_ustr);
CPPUNIT_ASSERT_MESSAGE("Right border before gridAfter cells", aBorder.LineWidth > 0);
aBorder = getProperty<table::BorderLine2>(xTable->getCellByName(u"E2"_ustr), u"LeftBorder"_ustr);
CPPUNIT_ASSERT_MESSAGE("Left edge border after gridBefore cells", aBorder.LineWidth > 100);
aBorder = getProperty<table::BorderLine2>(xTable->getCellByName(u"E2"_ustr), u"TopBorder"_ustr); // but only for left/right borders, not top and bottom. // So somewhat inconsistently, gridBefore/After affects outside edges of columns, but not of rows. // insideH borders are width 53. (no insideV borders defined to emphasize missing edge borders)
CPPUNIT_ASSERT_MESSAGE("Top border on 'inside' cell", aBorder.LineWidth > 0);
CPPUNIT_ASSERT_MESSAGE("Top border is not an edge border", aBorder.LineWidth < 100);
}
CPPUNIT_TEST_FIXTURE(Test, testTdf135329_lostImage)
{
loadAndReload("tdf135329_lostImage.odt"); // the character-anchored image was being skipped, since searchNext didn't notice it.
uno::Reference<beans::XPropertySet> xImageProps(getShape(2), uno::UNO_QUERY_THROW);
}
CPPUNIT_TEST_FIXTURE(Test, testTdf136441_commentInFootnote)
{
loadAndReload("tdf136441_commentInFootnote.odt"); // failed to load without error if footnote contained a comment. // (MS Word's UI doesn't allow adding comments to a footnote.)
}
CPPUNIT_TEST_FIXTURE(Test, testTdf137683_charHighlightTests)
{ auto verify = [this]() {
uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(10), 2, u"no highlight"_ustr), uno::UNO_QUERY_THROW); // This test was failing with a cyan charHighlight of 65535 (0x00FFFF), instead of COL_TRANSPARENT (0xFFFFFFFF)
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_AUTO), getProperty<sal_Int32>(xRun, u"CharHighlight"_ustr));
};
// Don't export unnecessary w:highlight="none" (Unnecessary one intentionally hand-added to original .docx)
createSwDoc("tdf137683_charHighlightTests.docx");
verify();
saveAndReload(mpFilter);
verify();
DECLARE_OOXMLEXPORT_TEST(testTdf138345_charStyleHighlight, "tdf138345_charStyleHighlight.docx")
{ // MS Word ignores the w:highlight setting in character styles. So shall we. // Without the fix, there would be an orange or yellow background on some words. const uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1), 2, u"orange background"_ustr), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_TRANSPARENT), getProperty<sal_Int32>(xRun,u"CharHighlight"_ustr));
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_TRANSPARENT), getProperty<sal_Int32>(xRun,u"CharBackColor"_ustr));
}
CPPUNIT_TEST_FIXTURE(Test, testTdf125268)
{
loadAndReload("tdf125268.odt");
CPPUNIT_ASSERT_EQUAL(1, getPages()); const uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1), 1, u"Hello"_ustr), uno::UNO_QUERY); // Without the fix in place, this test would have failed with // - Expected: -1 // - Actual : 0
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_TRANSPARENT), getProperty<sal_Int32>(xRun,u"CharHighlight"_ustr));
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_BLACK), getProperty<sal_Int32>(xRun,u"CharBackColor"_ustr));
}
CPPUNIT_TEST_FIXTURE(Test, testTdf138345_numberingHighlight)
{
loadAndSave("tdf138345_numberingHighlight.docx"); // Before the fix, the highlight was completely lost.
xmlDocUniquePtr pXmlStyles = parseExport(u"word/numbering.xml"_ustr); if (pXmlStyles)
assertXPath(pXmlStyles, "/w:numbering/w:abstractNum[@w:abstractNumId='1']/w:lvl[@w:ilvl='0']/w:rPr/w:highlight", "val", u"red");
}
CPPUNIT_ASSERT_EQUAL_MESSAGE("Fill style setting does not match!",
drawing::FillStyle::FillStyle_SOLID, nFillStyle);
Color aExpectedColor;
aExpectedColor.SetRed(255);
aExpectedColor.SetGreen(0);
aExpectedColor.SetBlue(0);
CPPUNIT_ASSERT_EQUAL_MESSAGE("OLE bg color does not match!", aExpectedColor, aFillColor);
}
CPPUNIT_TEST_FIXTURE(Test, testRelativeAnchorHeightFromBottomMarginHasFooter)
{
loadAndSave("tdf133070_testRelativeAnchorHeightFromBottomMarginHasFooter.docx"); // tdf#133070 The height was set relative to page print area bottom, // but this was handled relative to page height. // Note: page print area bottom = margin + footer height. // In this case the footer exists.
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
assertXPath(pXmlDoc, "//anchored/SwAnchoredDrawObject/bounds", "height", u"1147");
}
DECLARE_OOXMLEXPORT_TEST(TestTdf132483, "tdf132483.docx")
{
uno::Reference<beans::XPropertySet> xOLEProps(getShape(1), uno::UNO_QUERY_THROW);
sal_Int16 nVRelPos = -1;
sal_Int16 nHRelPos = -1;
xOLEProps->getPropertyValue(u"VertOrientRelation"_ustr) >>= nVRelPos;
xOLEProps->getPropertyValue(u"HoriOrientRelation"_ustr) >>= nHRelPos;
CPPUNIT_ASSERT_EQUAL_MESSAGE("The OLE is shifted vertically",
text::RelOrientation::PAGE_FRAME , nVRelPos);
CPPUNIT_ASSERT_EQUAL_MESSAGE("The OLE is shifted horizontally",
text::RelOrientation::PAGE_FRAME , nHRelPos);
}
CPPUNIT_TEST_FIXTURE(Test, testRelativeAnchorHeightFromBottomMarginNoFooter)
{
loadAndSave("tdf133070_testRelativeAnchorHeightFromBottomMarginNoFooter.docx"); // tdf#133070 The height was set relative to page print area bottom, // but this was handled relative to page height. // Note: page print area bottom = margin + footer height. // In this case the footer does not exist, so OpenDocument and OOXML margins are the same.
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
assertXPath(pXmlDoc, "//anchored/SwAnchoredDrawObject/bounds", "height", u"1147");
}
// Padding in this document is 0.10 cm which should translate to 3 pt (approx. 1.0583mm)
assertXPath(pXmlDocument, "/w:document/w:body/w:sectPr/w:pgBorders/w:top", "space", u"3");
assertXPath(pXmlDocument, "/w:document/w:body/w:sectPr/w:pgBorders/w:left", "space", u"3");
assertXPath(pXmlDocument, "/w:document/w:body/w:sectPr/w:pgBorders/w:bottom", "space", u"3");
assertXPath(pXmlDocument, "/w:document/w:body/w:sectPr/w:pgBorders/w:right", "space", u"3");
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.