/* -*- 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/.
*/
namespace
{ class Test : public SwModelTestBase
{ public:
Test()
: SwModelTestBase(u"/sw/qa/extras/odfexport/data/"_ustr, u"writer8"_ustr)
{
}
};
CPPUNIT_TEST_FIXTURE(Test, tdf135942)
{
loadAndReload("nestedTableInFooter.odt"); // All table autostyles should be collected, including nested, and must not crash.
CPPUNIT_TEST_FIXTURE(Test, testPersonalMetaData)
{ // 1. Remove personal info, keep user info auto pBatch(comphelper::ConfigurationChanges::create());
officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::set(true, pBatch);
officecfg::Office::Common::Security::Scripting::KeepDocUserInfoOnSaving::set(true, pBatch);
pBatch->commit();
CPPUNIT_TEST_FIXTURE(Test, testRemoveOnlyEditTimeMetaData)
{ // 1. Check we have the original edit time info
loadAndSave("personalmetadata.odt");
xmlDocUniquePtr pXmlDoc = parseExport(u"meta.xml"_ustr);
assertXPathContent(pXmlDoc, "/office:document-meta/office:meta/meta:editing-duration",
u"PT21M22S");
// Set config RemoveEditingTimeOnSaving to true auto pBatch(comphelper::ConfigurationChanges::create());
officecfg::Office::Common::Security::Scripting::RemoveEditingTimeOnSaving::set(true, pBatch);
pBatch->commit();
// 2. Check edit time info is 0
loadAndSave("personalmetadata.odt");
pXmlDoc = parseExport(u"meta.xml"_ustr);
assertXPathContent(pXmlDoc, "/office:document-meta/office:meta/meta:editing-duration", u"P0D");
assertXPath(
pXmlDoc, "/office:document-styles/office:automatic-styles/style:style[@style:family='table']", 1);
}
DECLARE_ODFEXPORT_TEST(testGutterLeft, "gutter-left.odt")
{
CPPUNIT_ASSERT_EQUAL(1, getPages());
uno::Reference<beans::XPropertySet> xPageStyle;
getStyles(u"PageStyles"_ustr)->getByName(u"Standard"_ustr) >>= xPageStyle;
sal_Int32 nGutterMargin{};
xPageStyle->getPropertyValue(u"GutterMargin"_ustr) >>= 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<sal_Int32>(1270), nGutterMargin);
}
DECLARE_ODFEXPORT_TEST(testTdf52065_centerTabs, "testTdf52065_centerTabs.odt")
{
CPPUNIT_ASSERT_EQUAL(1, getPages());
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
sal_Int32 nTabStop
= getXPath(pXmlDoc, "//body/txt[4]/SwParaPortion/SwLineLayout/child::*[3]", "width")
.toInt32(); // Without the fix, the text was unseen, with a tabstop width of 64057. It should be 3057
CPPUNIT_ASSERT(nTabStop < 4000);
CPPUNIT_ASSERT(3000 < nTabStop);
assertXPath(pXmlDoc, "//body/txt[4]/SwParaPortion/SwLineLayout/child::*[4]", "portion",
u"Pečiatka zamestnávateľa");
// tdf#149547: __XXX___invalid CharacterStyles should not be imported/exported
CPPUNIT_ASSERT(!getStyles(u"CharacterStyles"_ustr)->hasByName(u"__XXX___invalid"_ustr));
}
sal_Int32 nParaHeight = getXPath(pXmlDoc, "//header/txt[1]/infos/bounds", "height").toInt32(); // The wrapping on header images is supposed to be ignored (since OOo for MS compat reasons), // thus making the text run underneath the image. Before, height was 1104. Now it is 552.
CPPUNIT_ASSERT_MESSAGE("Paragraph should fit on a single line", nParaHeight < 600);
}
DECLARE_ODFEXPORT_TEST(testTdf153090, "Custom-Style-TOC.docx")
{
uno::Reference<text::XDocumentIndexesSupplier> xIndexSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<container::XIndexAccess> xIndexes(xIndexSupplier->getDocumentIndexes());
uno::Reference<text::XDocumentIndex> xTOC(xIndexes->getByIndex(0), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"_CustomImageCaption"_ustr,
getProperty<OUString>(xTOC, u"CreateFromParagraphStyle"_ustr)); // tdf#153659 this was imported as "table of figures" instead of "Figure Index 1" // thus custom settings were not retained after ToF update
CPPUNIT_ASSERT_EQUAL(u"Figure Index 1"_ustr,
getProperty<OUString>(getParagraph(1), u"ParaStyleName"_ustr));
xTOC->update();
OUString const tocContent(xTOC->getAnchor()->getString());
CPPUNIT_ASSERT(tocContent.indexOf("1. Abb. Ein Haus") != -1);
CPPUNIT_ASSERT(tocContent.indexOf("2. Abb.Ein Schiff!") != -1);
CPPUNIT_ASSERT(tocContent.indexOf(u"1. ábra Small house with Hungarian description category")
!= -1);
}
DECLARE_ODFEXPORT_TEST(testTdf143793_noBodyWrapping, "tdf143793_noBodyWrapping.odt")
{
CPPUNIT_ASSERT_EQUAL(2, getShapes()); // Preserve old document wrapping. Compat "Use OOo 1.1 text wrapping around objects" // Originally, the body text did not wrap around spill-over header images
CPPUNIT_ASSERT_EQUAL_MESSAGE("Fits on one page", 1, getPages());
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
sal_Int32 nParaHeight
= getXPath(pXmlDoc, "//page[1]/header/txt[1]/infos/bounds", "height").toInt32(); // The header text should wrap around the header image in OOo 1.1 and prior, // thus taking up two lines instead of one. One line is 276. It should be 552.
CPPUNIT_ASSERT_MESSAGE("Header text should fill two lines", nParaHeight > 400);
}
DECLARE_ODFEXPORT_TEST(testTdf143605, "tdf143605.odt")
{
CPPUNIT_ASSERT_EQUAL(1, getPages()); // With numbering type "none" there should be just prefix & suffix
CPPUNIT_ASSERT_EQUAL(u"."_ustr,
getProperty<OUString>(getParagraph(1), u"ListLabelString"_ustr));
}
CPPUNIT_TEST_FIXTURE(Test, testTdf165115)
{ // Test saving a template file with password protection
createSwDoc();
saveAndReload("writer8_template", "test");
}
CPPUNIT_TEST_FIXTURE(Test, testTdf57317_autoListName)
{
createSwDoc("tdf57317_autoListName.odt"); // The list style (from styles.xml) overrides a duplicate named auto-style //uno::Any aNumStyle = getStyles("NumberingStyles")->getByName("L1"); //CPPUNIT_ASSERT(aNumStyle.hasValue());
uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u">1<"_ustr, getProperty<OUString>(xPara, u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u"L1"_ustr, getProperty<OUString>(xPara, u"NumberingStyleName"_ustr));
// This was failing with a duplicate auto numbering style name of L1 instead of a unique name, // thus it was showing the same info as before the bullet modification.
saveAndReload(u"writer8"_ustr);
xPara.set(getParagraph(1), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u""_ustr, getProperty<OUString>(xPara, u"ListLabelString"_ustr));
CPPUNIT_TEST_FIXTURE(Test, testListFormatDocx)
{
loadAndReload("listformat.docx"); // Ensure in resulting ODT we also have not just prefix/suffix, but custom delimiters
CPPUNIT_ASSERT_EQUAL(u">1<"_ustr,
getProperty<OUString>(getParagraph(1), u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u">>1/1<<"_ustr,
getProperty<OUString>(getParagraph(2), u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u">>1/1/1<<"_ustr,
getProperty<OUString>(getParagraph(3), u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u">>1/1/2<<"_ustr,
getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
// Check also that in numbering styles we have num-list-format defined
xmlDocUniquePtr pXmlDoc = parseExport(u"styles.xml"_ustr);
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/" "text:list-level-style-number[@text:level='1']", "num-list-format", u">%1%<");
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/" "text:list-level-style-number[@text:level='2']", "num-list-format", u">>%1%/%2%<<");
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/" "text:list-level-style-number[@text:level='3']", "num-list-format", u">>%1%/%2%/%3%<<");
// But for compatibility there are still prefix/suffix
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/" "text:list-level-style-number[@text:level='1']", "num-prefix", u">");
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/" "text:list-level-style-number[@text:level='1']", "num-suffix", u"<");
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/" "text:list-level-style-number[@text:level='2']", "num-prefix", u">>");
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/" "text:list-level-style-number[@text:level='2']", "num-suffix", u"<<");
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/" "text:list-level-style-number[@text:level='3']", "num-prefix", u">>");
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/" "text:list-level-style-number[@text:level='3']", "num-suffix", u"<<");
}
CPPUNIT_TEST_FIXTURE(Test, testShapeWithHyperlink)
{
loadAndSave("shape-with-hyperlink.odt");
CPPUNIT_ASSERT_EQUAL(1, getShapes());
CPPUNIT_ASSERT_EQUAL(1, getPages());
xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); // Check how conversion from prefix/suffix to list format did work
assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:p/draw:a", "href",
u"http://shape.com/");
}
CPPUNIT_TEST_FIXTURE(Test, testListFormatOdt)
{ auto verify = [this]() {
CPPUNIT_ASSERT_EQUAL(1, getPages()); // Ensure in resulting ODT we also have not just prefix/suffix, but custom delimiters
CPPUNIT_ASSERT_EQUAL(u">1<"_ustr,
getProperty<OUString>(getParagraph(1), u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u">>1.1<<"_ustr,
getProperty<OUString>(getParagraph(2), u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u">>1.1.1<<"_ustr,
getProperty<OUString>(getParagraph(3), u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u">>1.1.2<<"_ustr,
getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
};
xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); // Check how conversion from prefix/suffix to list format did work
assertXPath(
pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/" "text:list-level-style-number[@text:level='1']", "num-list-format", u">%1%<");
assertXPath(
pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/" "text:list-level-style-number[@text:level='2']", "num-list-format", u">>%1%.%2%<<");
assertXPath(
pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/" "text:list-level-style-number[@text:level='3']", "num-list-format", u">>%1%.%2%.%3%<<");
// But for compatibility there are still prefix/suffix as they were before
assertXPath(
pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/" "text:list-level-style-number[@text:level='1']", "num-prefix", u">");
assertXPath(
pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/" "text:list-level-style-number[@text:level='1']", "num-suffix", u"<");
assertXPath(
pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/" "text:list-level-style-number[@text:level='2']", "num-prefix", u">>");
assertXPath(
pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/" "text:list-level-style-number[@text:level='2']", "num-suffix", u"<<");
assertXPath(
pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/" "text:list-level-style-number[@text:level='3']", "num-prefix", u">>");
assertXPath(
pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/" "text:list-level-style-number[@text:level='3']", "num-suffix", u"<<");
}
CPPUNIT_TEST_FIXTURE(Test, testStyleLink)
{ // Given a document with a para and a char style that links each other, when loading that // document:
createSwDoc("style-link.fodt");
// Then make sure the char style links the para one:
uno::Any aCharStyle
= getStyles(u"CharacterStyles"_ustr)->getByName(u"List Paragraph Char"_ustr); // Without the accompanying fix in place, this test would have failed with: // - Expected: List Paragraph // - Actual : // i.e. the linked style was lost on import.
CPPUNIT_ASSERT_EQUAL(u"List Paragraph"_ustr,
getProperty<OUString>(aCharStyle, u"LinkStyle"_ustr));
uno::Any aParaStyle = getStyles(u"ParagraphStyles"_ustr)->getByName(u"List Paragraph"_ustr); // Without the accompanying fix in place, this test would have failed with: // - Expected: List Paragraph Char // - Actual : // i.e. the linked style was lost on import.
CPPUNIT_ASSERT_EQUAL(u"List Paragraph Char"_ustr,
getProperty<OUString>(aParaStyle, u"LinkStyle"_ustr));
}
// list is continued
uno::Reference<container::XNamed> const xNum2(
getProperty<uno::Reference<container::XNamed>>(getParagraph(9), u"NumberingRules"_ustr));
CPPUNIT_ASSERT_EQUAL(xNum1->getName(), xNum2->getName());
// 2: style applies list-style-name and margin-left, list applies list-style-name
CPPUNIT_ASSERT_EQUAL(sal_Int32(-1000),
getProperty<sal_Int32>(getParagraph(9), u"ParaFirstLineIndent"_ustr));
CPPUNIT_ASSERT_EQUAL(sal_Int32(5001),
getProperty<sal_Int32>(getParagraph(9), u"ParaLeftMargin"_ustr));
CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
getProperty<sal_Int32>(getParagraph(9), u"ParaRightMargin"_ustr));
// list is continued
uno::Reference<container::XNamed> const xNum3(
getProperty<uno::Reference<container::XNamed>>(getParagraph(16), u"NumberingRules"_ustr));
CPPUNIT_ASSERT_EQUAL(xNum1->getName(), xNum3->getName());
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/infos/prtBounds", "left", u"2268");
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/infos/prtBounds", "right", u"11339"); // the list style name of the list is the same as the list style name of the // paragraph, but in any case the margins of the paragraph take precedence
assertXPath(pXmlDoc, "/root/page[1]/body/txt[9]/infos/prtBounds", "left", u"2268");
assertXPath(pXmlDoc, "/root/page[1]/body/txt[9]/infos/prtBounds", "right", u"11339");
assertXPath(pXmlDoc, "/root/page[1]/body/txt[16]/infos/prtBounds", "left", u"357");
assertXPath(pXmlDoc, "/root/page[1]/body/txt[16]/infos/prtBounds", "right", u"11339");
}
DECLARE_ODFEXPORT_TEST(testSectionColumnSeparator, "section-columns-separator.fodt")
{ // tdf#150235: due to wrong types used in column export, 'style:height' and 'style:style' // attributes were exported incorrectly for 'style:column-sep' element auto xSection
= getProperty<uno::Reference<uno::XInterface>>(getParagraph(1), u"TextSection"_ustr); auto xColumns = getProperty<uno::Reference<text::XTextColumns>>(xSection, u"TextColumns"_ustr);
CPPUNIT_ASSERT(xColumns);
CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xColumns->getColumnCount());
// Without the accompanying fix in place, this test would have failed with: // - Expected: 50 // - Actual : 100
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(50),
getProperty<sal_Int32>(xColumns, u"SeparatorLineRelativeHeight"_ustr)); // Without the accompanying fix in place, this test would have failed with: // - Expected: 2 // - Actual : 0
CPPUNIT_ASSERT_EQUAL(css::text::ColumnSeparatorStyle::DOTTED,
getProperty<sal_Int16>(xColumns, u"SeparatorLineStyle"_ustr));
// Check the rest of the properties, too
CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xColumns, u"IsAutomatic"_ustr));
CPPUNIT_ASSERT_EQUAL(sal_Int32(600),
getProperty<sal_Int32>(xColumns, u"AutomaticDistance"_ustr));
CPPUNIT_ASSERT_EQUAL(sal_Int32(9),
getProperty<sal_Int32>(xColumns, u"SeparatorLineWidth"_ustr));
CPPUNIT_ASSERT_EQUAL(Color(0x99, 0xAA, 0xBB),
getProperty<Color>(xColumns, u"SeparatorLineColor"_ustr));
CPPUNIT_ASSERT_EQUAL(css::style::VerticalAlignment_BOTTOM,
getProperty<css::style::VerticalAlignment>(
xColumns, u"SeparatorLineVerticalAlignment"_ustr));
CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xColumns, u"SeparatorLineIsOn"_ustr));
}
// now check the positions where text is actually painted - // wonder how fragile this is... // FIXME some platform difference, 1st one is 2306 on Linux, 3087 on WNT ? // some Mac has 3110 #if !defined(_WIN32) && !defined(MACOSX)
{
std::shared_ptr<GDIMetaFile> pMetaFile = getSwDocShell()->GetPreviewMetaFile();
MetafileXmlDump aDumper;
xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *pMetaFile);
// 1: inherited from paragraph style and overridden by list // bullet char is extra
assertXPath(pXmlDoc, "//textarray[1]", "x", u"2306"); // text is after a tab from list - haven't checked if that is correct?
assertXPath(pXmlDoc, "//textarray[2]", "x", u"2873"); // second line
assertXPath(pXmlDoc, "//textarray[3]", "x", u"2873"); // 2: as 1 + paragraph sets firstline
assertXPath(pXmlDoc, "//textarray[4]", "x", u"3440");
assertXPath(pXmlDoc, "//textarray[5]", "x", u"3593");
assertXPath(pXmlDoc, "//textarray[6]", "x", u"2873"); // 3: as 1 + paragraph sets textleft
assertXPath(pXmlDoc, "//textarray[7]", "x", u"2873");
assertXPath(pXmlDoc, "//textarray[8]", "x", u"3440");
assertXPath(pXmlDoc, "//textarray[9]", "x", u"3440"); // 4: as 1 + paragraph sets firstline, textleft
assertXPath(pXmlDoc, "//textarray[10]", "x", u"2306");
assertXPath(pXmlDoc, "//textarray[11]", "x", u"3440");
assertXPath(pXmlDoc, "//textarray[12]", "x", u"3440"); // 5: as 1 + paragraph sets firstline
assertXPath(pXmlDoc, "//textarray[13]", "x", u"1739");
assertXPath(pXmlDoc, "//textarray[14]", "x", u"2873");
assertXPath(pXmlDoc, "//textarray[15]", "x", u"2873"); // 6: as 1
assertXPath(pXmlDoc, "//textarray[16]", "x", u"2306");
assertXPath(pXmlDoc, "//textarray[17]", "x", u"2873");
auto xFactory(mxComponent.queryThrow<lang::XMultiServiceFactory>()); auto xComment(xFactory->createInstance(u"com.sun.star.text.textfield.Annotation"_ustr)
.queryThrow<text::XTextContent>()); auto xCommentText(getProperty<uno::Reference<text::XTextRange>>(xComment, u"TextRange"_ustr));
xCommentText->setString(u"Hello World"_ustr);
xCommentText.queryThrow<beans::XPropertySet>()->setPropertyValue(u"ParaStyleName"_ustr,
uno::Any(u"Heading"_ustr));
xComment->attach(getParagraph(1)->getEnd());
saveAndReload(u"writer8"_ustr);
auto xFields(
mxComponent.queryThrow<text::XTextFieldsSupplier>()->getTextFields()->createEnumeration());
xComment.set(xFields->nextElement().queryThrow<text::XTextContent>());
CPPUNIT_ASSERT(xComment.queryThrow<lang::XServiceInfo>()->supportsService(
u"com.sun.star.text.textfield.Annotation"_ustr));
auto xStyleFamilies(
mxComponent.queryThrow<style::XStyleFamiliesSupplier>()->getStyleFamilies()); auto xParaStyles(xStyleFamilies->getByName(u"ParagraphStyles"_ustr)); auto xStyle(xParaStyles.queryThrow<container::XNameAccess>()->getByName(u"Heading"_ustr));
CPPUNIT_ASSERT_EQUAL(getProperty<float>(xStyle, u"CharHeight"_ustr),
getProperty<float>(xCommentText, u"CharHeight"_ustr));
CPPUNIT_ASSERT_EQUAL(
beans::PropertyState_DEFAULT_VALUE,
xCommentText.queryThrow<beans::XPropertyState>()->getPropertyState(u"CharHeight"_ustr));
}
// Second level's numbering should use Arabic numbers for first level reference auto xPara = getParagraph(1);
CPPUNIT_ASSERT_EQUAL(u"CH I"_ustr, getProperty<OUString>(xPara, u"ListLabelString"_ustr));
xPara = getParagraph(2);
CPPUNIT_ASSERT_EQUAL(u"Sect 1.01"_ustr, getProperty<OUString>(xPara, u"ListLabelString"_ustr));
xPara = getParagraph(3);
CPPUNIT_ASSERT_EQUAL(u"CH II"_ustr, getProperty<OUString>(xPara, u"ListLabelString"_ustr));
xPara = getParagraph(4);
CPPUNIT_ASSERT_EQUAL(u"Sect 2.01"_ustr, getProperty<OUString>(xPara, u"ListLabelString"_ustr));
// Test that the markup stays at save-and-reload
xmlDocUniquePtr pXmlDoc = parseExport(u"styles.xml"_ustr);
assertXPath(
pXmlDoc, "/office:document-styles/office:styles/text:outline-style/text:outline-level-style[2]", "is-legal", u"true");
}
createSwDoc("footnote_spacing_hanging_para.docx"); // 1. Make sure that DOCX import sets NoGapAfterNoteNumber option, and creates // correct layout
{
uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY_THROW);
uno::Reference<beans::XPropertySet> xSettings(
xFactory->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_EQUAL(uno::Any(true),
xSettings->getPropertyValue(u"NoGapAfterNoteNumber"_ustr));
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
sal_Int32 width
= getXPath(pXmlDoc, "/root/page/ftncont/ftn/txt/SwParaPortion/SwLineLayout/SwFieldPortion", "width")
.toInt32();
CPPUNIT_ASSERT(width);
CPPUNIT_ASSERT_LESS(sal_Int32(100), width); // It was 720, i.e. 0.5 inch
}
saveAndReload(mpFilter); // 2. Make sure that exported document has NoGapAfterNoteNumber option set, // and has correct layout
{
xmlDocUniquePtr pXmlDoc = parseExport(u"settings.xml"_ustr);
assertXPathContent(pXmlDoc, "//config:config-item[@config:name='NoGapAfterNoteNumber']",
u"true");
createSwDoc(); // 5. Make sure that a new Writer document has this setting set to false
{
uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY_THROW);
uno::Reference<beans::XPropertySet> xSettings(
xFactory->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_EQUAL(uno::Any(false),
xSettings->getPropertyValue(u"NoGapAfterNoteNumber"_ustr));
}
}
CPPUNIT_TEST_FIXTURE(Test, testTdf159438)
{ // Given a text with bookmarks, where an end of one bookmark is the position of another, // and the start of a third
loadAndReload("bookmark_order.fodt"); auto xPara = getParagraph(1);
// Check that the order of runs is correct (bookmarks don't overlap)
{ auto run = getRun(xPara, 1);
CPPUNIT_ASSERT_EQUAL(u"Bookmark"_ustr, getProperty<OUString>(run, u"TextPortionType"_ustr));
CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(run, u"IsStart"_ustr));
CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(run, u"IsCollapsed"_ustr)); auto named = getProperty<uno::Reference<container::XNamed>>(run, u"Bookmark"_ustr);
CPPUNIT_ASSERT_EQUAL(u"bookmark1"_ustr, named->getName());
}
{ auto run = getRun(xPara, 2);
CPPUNIT_ASSERT_EQUAL(u"Text"_ustr, getProperty<OUString>(run, u"TextPortionType"_ustr));
CPPUNIT_ASSERT_EQUAL(u"foo"_ustr, run->getString());
}
{ auto run = getRun(xPara, 3);
CPPUNIT_ASSERT_EQUAL(u"Bookmark"_ustr, getProperty<OUString>(run, u"TextPortionType"_ustr));
CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(run, u"IsStart"_ustr));
CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(run, u"IsCollapsed"_ustr)); auto named = getProperty<uno::Reference<container::XNamed>>(run, u"Bookmark"_ustr);
CPPUNIT_ASSERT_EQUAL(u"bookmark1"_ustr, named->getName());
}
{ auto run = getRun(xPara, 4);
CPPUNIT_ASSERT_EQUAL(u"Bookmark"_ustr, getProperty<OUString>(run, u"TextPortionType"_ustr));
CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(run, u"IsStart"_ustr));
CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(run, u"IsCollapsed"_ustr)); auto named = getProperty<uno::Reference<container::XNamed>>(run, u"Bookmark"_ustr);
CPPUNIT_ASSERT_EQUAL(u"bookmark2"_ustr, named->getName());
}
{ auto run = getRun(xPara, 5);
CPPUNIT_ASSERT_EQUAL(u"Bookmark"_ustr, getProperty<OUString>(run, u"TextPortionType"_ustr));
CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(run, u"IsStart"_ustr));
CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(run, u"IsCollapsed"_ustr)); auto named = getProperty<uno::Reference<container::XNamed>>(run, u"Bookmark"_ustr);
CPPUNIT_ASSERT_EQUAL(u"bookmark3"_ustr, named->getName());
}
{ auto run = getRun(xPara, 6);
CPPUNIT_ASSERT_EQUAL(u"Text"_ustr, getProperty<OUString>(run, u"TextPortionType"_ustr));
CPPUNIT_ASSERT_EQUAL(u"bar"_ustr, run->getString());
}
{ auto run = getRun(xPara, 7);
CPPUNIT_ASSERT_EQUAL(u"Bookmark"_ustr, getProperty<OUString>(run, u"TextPortionType"_ustr));
CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(run, u"IsStart"_ustr));
CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(run, u"IsCollapsed"_ustr)); auto named = getProperty<uno::Reference<container::XNamed>>(run, u"Bookmark"_ustr);
CPPUNIT_ASSERT_EQUAL(u"bookmark3"_ustr, named->getName());
}
// Test that the markup stays at save-and-reload
xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
// Without the fix in place, this would fail with // - Expected: bookmark-end // - Actual : bookmark-start // - In XPath '//office:body/office:text/text:p/*[2]' name of node is incorrect
assertXPathNodeName(pXmlDoc, "//office:body/office:text/text:p/*[2]", "bookmark-end");
assertXPath(pXmlDoc, "//office:body/office:text/text:p/*[2]", "name", u"bookmark1");
CPPUNIT_TEST_FIXTURE(Test, testTdf160700)
{ // Given a document with an empty numbered paragraph, and a cross-reference to it
loadAndReload("tdf160700.odt");
// Refresh fields and ensure cross-reference to numbered para is okay auto xTextFieldsSupplier(mxComponent.queryThrow<text::XTextFieldsSupplier>()); auto xFieldsAccess(xTextFieldsSupplier->getTextFields());
auto xFields(xFieldsAccess->createEnumeration());
CPPUNIT_ASSERT(xFields->hasMoreElements()); auto xTextField(xFields->nextElement().queryThrow<text::XTextField>()); // Save must not create markup with text:bookmark-end element before text:bookmark-start // Without the fix, this would fail with // - Expected: 1 // - Actual : Error: Reference source not found // i.e., the bookmark wasn't imported, and the field had no proper source
CPPUNIT_ASSERT_EQUAL(u"1"_ustr, xTextField->getPresentation(false));
xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); // Check that we export the bookmark in the empty paragraph as a single text:bookmark // element. Another valid markup is text:bookmark-start followed by text:bookmark-end // (in that order). The problem was, that text:bookmark-end was before text:bookmark-start.
assertXPathChildren(pXmlDoc, "//office:text/text:list/text:list-item/text:p", 1);
assertXPath(pXmlDoc, "//office:text/text:list/text:list-item/text:p/text:bookmark");
}
CPPUNIT_TEST_FIXTURE(Test, testTdf160253_ordinary_numbering)
{ // Given a document with a list, and an out-of-the-list paragraph in the middle, having an // endnote, which has a paragraph in another list. // Before the fix, this already failed with // Error: "list2916587379" is referenced by an IDREF, but not defined.
loadAndReload("tdf160253_ordinary_numbering.fodt");
// Make sure that the fourth paragraph has correct number - it was "1." before the fix
CPPUNIT_ASSERT_EQUAL(u"3."_ustr,
getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
// Make sure that we emit an identifier for the first list, and refer to it in the continuation
xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); // This failed before the fix, because 'xml:id' attribute wasn't emitted
OUString firstListId = getXPath(pXmlDoc, "//office:body/office:text/text:list[1]", "id");
CPPUNIT_ASSERT(!firstListId.isEmpty());
assertXPath(pXmlDoc, "//office:body/office:text/text:list[2]", "continue-list", firstListId);
}
CPPUNIT_TEST_FIXTURE(Test, testTdf160253_outline_numbering)
{ // Given a document with an outline (chapter) numbering, and a paragraph in the middle, having // an endnote, which has a paragraph in a list. // Before the fix, this already failed with // Error: "list2916587379" is referenced by an IDREF, but not defined.
loadAndReload("tdf160253_outline_numbering.fodt");
// Make sure that the third paragraph has correct number - it was "1" before the fix
CPPUNIT_ASSERT_EQUAL(u"2"_ustr,
getProperty<OUString>(getParagraph(3), u"ListLabelString"_ustr));
// The difference with the ordinary numbering is that for outline numbering, the list element // isn't really necessary. It is a TODO to fix the output, and not export the list. // xmlDocUniquePtr pXmlDoc = parseExport("content.xml"); // assertXPath(pXmlDoc, "//office:body/office:text/text:list", 0);
}
CPPUNIT_TEST_FIXTURE(Test, testTableInFrameAnchoredToPage)
{ // Given a table in a frame anchored to a page: // it must not assert on export because of missing format for an exported table
loadAndReload("table_in_frame_to_page.fodt");
// Check also, that autostyles defined inside that frame are stored correctly. If not, then // these paragraphs would refer to styles in <office::styles>, not in <office:automatic-styles>, // without the 'italic' and 'bold' attributes.
OString P = AutoStyleUsedIn(xPathTextBox + "/text:p", "style-name");
assertXPath(pXmlDoc, P + "/style:text-properties", "font-weight", u"bold");
P = AutoStyleUsedIn(xPathTextBox + "/table:table/table:table-row[1]/table:table-cell[1]/text:p", "style-name");
assertXPath(pXmlDoc, P + "/style:text-properties", "font-style", u"italic");
}
CPPUNIT_TEST_FIXTURE(Test, testDeletedTableAutostylesExport)
{ // Given a document with deleted table: // it must not assert on export because of missing format for an exported table
loadAndReload("deleted_table.fodt");
}
uno::Reference<text::XText> xHeaderTextPage1 = getProperty<uno::Reference<text::XText>>(
getStyles(u"PageStyles"_ustr)->getByName(u"Standard"_ustr), u"HeaderTextFirst"_ustr);
CPPUNIT_ASSERT_EQUAL(u"Classification: General Business"_ustr, xHeaderTextPage1->getString());
// Without the fix in place, this test would have failed with // - Expected: (Sign GB)Test // - Actual : Test
CPPUNIT_ASSERT_EQUAL(u"(Sign GB)Test"_ustr, getParagraph(1)->getString());
}
CPPUNIT_TEST_FIXTURE(Test, testMidnightRedlineDatetime)
{ // Given a document with a tracked change with a midnight datetime: // make sure that it succeeds export and import validation. Before the fix, this failed: // - Error: "2001-01-01" does not satisfy the "dateTime" type // because "2001-01-01T00:00:00" became "2001-01-01" on roundtrip.
loadAndReload("midnight_redline.fodt");
CPPUNIT_TEST_FIXTURE(Test, testTdf122452)
{ // FIXME: Error: element "text:insertion" was found where no element may occur
skipValidation();
loadAndReload("tdf122452.doc");
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
// Without the fix in place this fails with: // Expected: 1 // Actual: 0
CPPUNIT_ASSERT_EQUAL_MESSAGE("Redlines should be Hidden", true,
pWrtShell->GetLayout()->IsHideRedlines());
}
// This was 8 (duplicated images anchored at page)
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xIndexAccess->getCount());
}
CPPUNIT_TEST_FIXTURE(Test, testTdf163703)
{ // Given a document with italics autostyle in a comment
loadAndReload("italics-in-comment.fodt");
auto xFields(
mxComponent.queryThrow<text::XTextFieldsSupplier>()->getTextFields()->createEnumeration()); auto xComment(xFields->nextElement().queryThrow<text::XTextContent>());
CPPUNIT_ASSERT(xComment.queryThrow<lang::XServiceInfo>()->supportsService(
u"com.sun.star.text.textfield.Annotation"_ustr));
auto xCommentText(getProperty<uno::Reference<css::text::XText>>(xComment, u"TextRange"_ustr));
CPPUNIT_ASSERT(xCommentText);
CPPUNIT_ASSERT_EQUAL(1, getParagraphs(xCommentText)); auto xCommentPara(getParagraphOrTable(1, xCommentText).queryThrow<css::text::XTextRange>());
CPPUNIT_ASSERT_EQUAL(u"lorem"_ustr, xCommentPara->getString());
// Without the fix, this would fail with // - Expected: lo // - Actual : lorem // - run does not contain expected content // because direct formatting was dropped on export, and the comment was exported in one chunk auto x1stRun = getRun(xCommentPara, 1, "lo");
CPPUNIT_ASSERT_EQUAL(css::awt::FontSlant_NONE,
getProperty<css::awt::FontSlant>(x1stRun, u"CharPosture"_ustr));
auto x2ndRun = getRun(xCommentPara, 2, "r");
CPPUNIT_ASSERT_EQUAL(css::awt::FontSlant_ITALIC,
getProperty<css::awt::FontSlant>(x2ndRun, u"CharPosture"_ustr));
auto x3rdRun = getRun(xCommentPara, 3, "em");
CPPUNIT_ASSERT_EQUAL(css::awt::FontSlant_NONE,
getProperty<css::awt::FontSlant>(x3rdRun, u"CharPosture"_ustr));
xmlDocUniquePtr pXml = parseExport(u"content.xml"_ustr);
assertXPathContent(pXml, "//office:text/text:p/office:annotation/text:p", u"lorem"); // Without the fix, this would fail with // - Expected: 1
--> --------------------
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.