1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 */ 9 10 #include <swmodeltestbase.hxx> 11 12 #include <com/sun/star/beans/XPropertySet.hpp> 13 #include <com/sun/star/style/BreakType.hpp> 14 #include <com/sun/star/style/ParagraphAdjust.hpp> 15 #include <com/sun/star/table/BorderLine.hpp> 16 #include <com/sun/star/text/WritingMode2.hpp> 17 #include <com/sun/star/text/XDependentTextField.hpp> 18 #include <com/sun/star/text/XFootnotesSupplier.hpp> 19 #include <com/sun/star/text/RubyAdjust.hpp> 20 #include <com/sun/star/text/RubyPosition.hpp> 21 #include <com/sun/star/text/XDocumentIndex.hpp> 22 #include <com/sun/star/drawing/FillStyle.hpp> 23 24 class Test : public SwModelTestBase 25 { 26 public: Test()27 Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {} 28 29 protected: 30 /** 31 * Blacklist handling 32 */ mustTestImportOf(const char * filename) const33 bool mustTestImportOf(const char* filename) const override { 34 // If the testcase is stored in some other format, it's pointless to test. 35 return OString(filename).endsWith(".docx"); 36 } 37 }; 38 39 DECLARE_OOXMLEXPORT_TEST(testTdf57589_hashColor, "tdf57589_hashColor.docx") 40 { 41 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(getParagraph(1), "FillStyle")); 42 CPPUNIT_ASSERT_EQUAL(COL_LIGHTMAGENTA, Color(getProperty<sal_uInt32>(getParagraph(1), "ParaBackColor"))); 43 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(getParagraph(2), "FillStyle")); 44 CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(getProperty<sal_uInt32>(getParagraph(2), "ParaBackColor"))); 45 } 46 47 DECLARE_OOXMLEXPORT_TEST(testTdf90906_colAuto, "tdf90906_colAuto.docx") 48 { 49 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); 50 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); 51 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); 52 uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY); 53 uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY); 54 uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); 55 uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY); 56 CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(getProperty<sal_uInt32>(getRun(xPara, 1, "Nazwa"), "CharBackColor"))); 57 } 58 59 DECLARE_OOXMLEXPORT_TEST(testTdf90906_colAutoB, "tdf90906_colAutoB.docx") 60 { 61 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); 62 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); 63 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); 64 65 uno::Reference<table::XCell> xCell = xTable->getCellByName("A1"); 66 CPPUNIT_ASSERT_EQUAL(COL_LIGHTGREEN, Color(getProperty<sal_uInt32>(xCell, "BackColor"))); 67 xCell.set(xTable->getCellByName("A2")); 68 CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(getProperty<sal_uInt32>(xCell, "BackColor"))); 69 xCell.set(xTable->getCellByName("B1")); 70 CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(getProperty<sal_uInt32>(xCell, "BackColor"))); 71 xCell.set(xTable->getCellByName("B2")); 72 CPPUNIT_ASSERT_EQUAL(COL_LIGHTBLUE, Color(getProperty<sal_uInt32>(xCell, "BackColor"))); 73 74 uno::Reference<text::XTextRange> xText(getParagraph(2, "Paragraphs too")); 75 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xText, "FillStyle")); 76 CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(getProperty<sal_uInt32>(xText, "ParaBackColor"))); 77 } 78 79 DECLARE_OOXMLEXPORT_TEST(testTdf92524_autoColor, "tdf92524_autoColor.doc") 80 { 81 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(getParagraph(1), "FillStyle")); 82 CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(getProperty<sal_uInt32>(getParagraph(1), "ParaBackColor"))); 83 } 84 85 DECLARE_OOXMLEXPORT_TEST(testTdf116436_rowFill, "tdf116436_rowFill.odt") 86 { 87 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); 88 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); 89 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); 90 uno::Reference<table::XCell> xCell = xTable->getCellByName("A1"); 91 CPPUNIT_ASSERT_EQUAL(sal_Int32(0xF8DF7C), getProperty<sal_Int32>(xCell, "BackColor")); 92 } 93 94 DECLARE_OOXMLEXPORT_TEST(testTdf121665_back2backColumnBreaks, "tdf121665_back2backColumnBreaks.docx") 95 { 96 CPPUNIT_ASSERT_EQUAL_MESSAGE("Column break type", 97 style::BreakType_COLUMN_BEFORE, getProperty<style::BreakType>(getParagraph(2), "BreakType")); 98 } 99 100 DECLARE_OOXMLEXPORT_TEST(testTdf46938_clearTabStop, "tdf46938_clearTabStop.docx") 101 { 102 // Number of tabstops should be zero, overriding the one in the style 103 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty< uno::Sequence<style::TabStop> >(getParagraph(1), "ParaTabStops").getLength()); 104 } 105 106 DECLARE_OOXMLEXPORT_TEST(testTdf63561_clearTabs, "tdf63561_clearTabs.docx") 107 { 108 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), getProperty< uno::Sequence<style::TabStop> >(getParagraph(1), "ParaTabStops").getLength()); 109 CPPUNIT_ASSERT_EQUAL(sal_Int32(7), getProperty< uno::Sequence<style::TabStop> >(getParagraph(3), "ParaTabStops").getLength()); 110 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), getProperty< uno::Sequence<style::TabStop> >(getParagraph(4), "ParaTabStops").getLength()); 111 } 112 113 DECLARE_OOXMLEXPORT_TEST(testTdf63561_clearTabs2, "tdf63561_clearTabs2.docx") 114 { 115 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty< uno::Sequence<style::TabStop> >(getParagraph(1), "ParaTabStops").getLength()); 116 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), getProperty< uno::Sequence<style::TabStop> >(getParagraph(3), "ParaTabStops").getLength()); 117 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), getProperty< uno::Sequence<style::TabStop> >(getParagraph(4), "ParaTabStops").getLength()); 118 } 119 120 DECLARE_OOXMLEXPORT_TEST(testTdf124384, "tdf124384.docx") 121 { 122 // There should be no crash during loading of the document 123 // so, let's check just how much pages we have 124 CPPUNIT_ASSERT_EQUAL(1, getPages()); 125 } 126 127 DECLARE_OOXMLEXPORT_TEST(testTdf121456_tabsOffset, "tdf121456_tabsOffset.odt") 128 { 129 for (int i=2; i<8; i++) 130 { 131 uno::Sequence< style::TabStop > stops = getProperty< uno::Sequence<style::TabStop> >(getParagraph( i ), "ParaTabStops"); 132 CPPUNIT_ASSERT_EQUAL( sal_Int32(1), stops.getLength()); 133 CPPUNIT_ASSERT_EQUAL( css::style::TabAlign_RIGHT, stops[ 0 ].Alignment ); 134 CPPUNIT_ASSERT_EQUAL( sal_Int32(17000), stops[ 0 ].Position ); 135 } 136 } 137 138 // tdf#121561: make sure w:sdt/w:sdtContent around TOC is written during ODT->DOCX conversion 139 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf121561_tocTitle, "tdf121456_tabsOffset.odt") 140 { 141 xmlDocPtr pXmlDoc = parseExport(); 142 assertXPathContent(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtContent/w:p/w:r/w:t", "Inhaltsverzeichnis"); 143 assertXPathContent(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtContent/w:p/w:r/w:instrText", " TOC \\f \\o \"1-9\" \\h"); 144 assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:docPartObj/w:docPartGallery", "val", "Table of Contents"); 145 assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:docPartObj/w:docPartUnique", 1); 146 } 147 148 // Related issue tdf#121561: w:sdt/w:sdtContent around TOC 149 DECLARE_OOXMLEXPORT_TEST(testTdf124106, "tdf121456.docx") 150 { 151 uno::Reference<text::XTextDocument> textDocument(mxComponent, uno::UNO_QUERY); 152 uno::Reference<text::XText> text = textDocument->getText(); 153 // -1 if the 'Y' character does not occur 154 CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), text->getString().indexOf('Y')); 155 CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), text->getString().indexOf('y')); 156 } 157 158 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf121561_tocTitleDocx, "tdf121456_tabsOffset.odt") 159 { 160 xmlDocPtr pXmlDoc = parseExport(); 161 162 // get TOC node 163 uno::Reference<text::XDocumentIndexesSupplier> xIndexSupplier(mxComponent, uno::UNO_QUERY); 164 uno::Reference<container::XIndexAccess> xIndexes = xIndexSupplier->getDocumentIndexes( ); 165 uno::Reference<text::XDocumentIndex> xTOCIndex(xIndexes->getByIndex(0), uno::UNO_QUERY); 166 167 // ensure TOC title was set in TOC properties 168 CPPUNIT_ASSERT_EQUAL(OUString("Inhaltsverzeichnis"), getProperty<OUString>(xTOCIndex, "Title")); 169 170 // ensure TOC end-field mark is placed inside TOC section 171 assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtContent/w:p[16]/w:r/w:fldChar", "fldCharType", "end"); 172 } 173 174 DECLARE_OOXMLEXPORT_TEST(testTdf106174_rtlParaAlign, "tdf106174_rtlParaAlign.docx") 175 { 176 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_CENTER), getProperty<sal_Int16>(getParagraph(1), "ParaAdjust")); 177 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_CENTER), getProperty<sal_Int16>(getParagraph(2), "ParaAdjust")); 178 uno::Reference<beans::XPropertySet> xPropertySet(getStyles("ParagraphStyles")->getByName("Another paragraph aligned to right"), uno::UNO_QUERY); 179 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(xPropertySet, "ParaAdjust")); 180 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(3), "ParaAdjust")); 181 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(4), "ParaAdjust")); 182 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(5), "ParaAdjust")); 183 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getParagraph(6), "ParaAdjust")); 184 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(7), "ParaAdjust")); 185 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(8), "ParaAdjust")); 186 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getParagraph(9), "ParaAdjust")); 187 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getParagraph(10), "ParaAdjust")); 188 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(11), "ParaAdjust")); 189 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getParagraph(12), "ParaAdjust")); 190 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getParagraph(13), "ParaAdjust")); 191 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(14), "ParaAdjust")); 192 } 193 194 DECLARE_OOXMLEXPORT_TEST(testTdf82065_Ind_start_strict, "tdf82065_Ind_start_strict.docx") 195 { 196 uno::Reference<beans::XPropertySet> xPropertySet(getStyles("NumberingStyles")->getByName("WWNum1"), uno::UNO_QUERY); 197 uno::Reference<container::XIndexAccess> xLevels(xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY); 198 uno::Sequence<beans::PropertyValue> aProps; 199 xLevels->getByIndex(0) >>= aProps; // 1st level 200 bool bFoundIndentAt = false; 201 for (int i = 0; i < aProps.getLength(); ++i) 202 { 203 const beans::PropertyValue& rProp = aProps[i]; 204 205 if (rProp.Name == "IndentAt") 206 { 207 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("IndentAt", double(6001), rProp.Value.get<double>(), 10 ); 208 bFoundIndentAt = true; 209 } 210 } 211 CPPUNIT_ASSERT_EQUAL_MESSAGE("IndentAt defined", true, bFoundIndentAt); 212 } 213 214 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf76683_negativeTwipsMeasure, "tdf76683_negativeTwipsMeasure.docx") 215 { 216 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 217 assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:cols/w:col", 2); 218 sal_uInt32 nColumn1 = getXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:cols/w:col[1]", "w").toUInt32(); 219 sal_uInt32 nColumn2 = getXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:cols/w:col[2]", "w").toUInt32(); 220 CPPUNIT_ASSERT( nColumn1 > nColumn2 ); 221 } 222 223 DECLARE_OOXMLEXPORT_TEST(testTdf112694, "tdf112694.docx") 224 { 225 uno::Any aPageStyle = getStyles("PageStyles")->getByName("Standard"); 226 // Header was on when header for file was for explicit first pages only 227 // (marked via <w:titlePg>). 228 CPPUNIT_ASSERT(!getProperty<bool>(aPageStyle, "HeaderIsOn")); 229 } 230 231 DECLARE_OOXMLEXPORT_TEST(testTdf113849_evenAndOddHeaders, "tdf113849_evenAndOddHeaders.odt") 232 { 233 CPPUNIT_ASSERT_EQUAL_MESSAGE("Header2 text", OUString("L. J. Kendall"), parseDump("/root/page[2]/header/txt")); 234 CPPUNIT_ASSERT_EQUAL_MESSAGE("Footer2 text", OUString("*"), parseDump("/root/page[2]/footer/txt")); 235 236 CPPUNIT_ASSERT_EQUAL_MESSAGE("Header3 text", OUString("Shadow Hunt"), parseDump("/root/page[3]/header/txt")); 237 CPPUNIT_ASSERT_EQUAL_MESSAGE("Footer3 text", OUString("*"), parseDump("/root/page[3]/footer/txt")); 238 239 CPPUNIT_ASSERT_EQUAL_MESSAGE("Header4 text", OUString("L. J. Kendall"), parseDump("/root/page[4]/header/txt")); 240 CPPUNIT_ASSERT_EQUAL_MESSAGE("Footer4 text", OUString("*"), parseDump("/root/page[4]/footer/txt")); 241 242 CPPUNIT_ASSERT_EQUAL_MESSAGE("Footer5 text", OUString(""), parseDump("/root/page[5]/footer/txt")); 243 CPPUNIT_ASSERT_EQUAL_MESSAGE("Footer6 text", OUString(""), parseDump("/root/page[6]/footer/txt")); 244 245 CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of pages", 6, getPages() ); 246 } 247 248 DECLARE_OOXMLEXPORT_TEST(testTdf118361_RTLfootnoteSeparator, "tdf118361_RTLfootnoteSeparator.docx") 249 { 250 uno::Any aPageStyle = getStyles("PageStyles")->getByName("Standard"); 251 CPPUNIT_ASSERT_EQUAL_MESSAGE("Footnote separator RTL", sal_Int16(2), getProperty<sal_Int16>(aPageStyle, "FootnoteLineAdjust")); 252 } 253 254 DECLARE_OOXMLEXPORT_TEST(testTdf115861, "tdf115861.docx") 255 { 256 // Second item in the paragraph enumeration was a table, 2nd paragraph was 257 // lost. 258 CPPUNIT_ASSERT_EQUAL(OUString("(k)"), getParagraph(2)->getString()); 259 } 260 261 DECLARE_OOXMLEXPORT_TEST(testTdf67207_MERGEFIELD, "mailmerge.docx") 262 { 263 uno::Reference<beans::XPropertySet> xTextField = getProperty< uno::Reference<beans::XPropertySet> >(getRun(getParagraph(1), 2), "TextField"); 264 CPPUNIT_ASSERT(xTextField.is()); 265 uno::Reference<lang::XServiceInfo> xServiceInfo(xTextField, uno::UNO_QUERY_THROW); 266 uno::Reference<text::XDependentTextField> xDependent(xTextField, uno::UNO_QUERY_THROW); 267 268 CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.Database")); 269 OUString sValue; 270 xTextField->getPropertyValue("Content") >>= sValue; 271 CPPUNIT_ASSERT_EQUAL(OUString::fromUtf8(u8"«Name»"), sValue); 272 273 uno::Reference<beans::XPropertySet> xFiledMaster = xDependent->getTextFieldMaster(); 274 uno::Reference<lang::XServiceInfo> xFiledMasterServiceInfo(xFiledMaster, uno::UNO_QUERY_THROW); 275 276 CPPUNIT_ASSERT(xFiledMasterServiceInfo->supportsService("com.sun.star.text.fieldmaster.Database")); 277 278 // Defined properties: DataBaseName, Name, DataTableName, DataColumnName, DependentTextFields, DataCommandType, InstanceName, DataBaseURL 279 CPPUNIT_ASSERT(xFiledMaster->getPropertyValue("Name") >>= sValue); 280 CPPUNIT_ASSERT_EQUAL(OUString("Name"), sValue); 281 CPPUNIT_ASSERT(xFiledMaster->getPropertyValue("DataColumnName") >>= sValue); 282 CPPUNIT_ASSERT_EQUAL(OUString("Name"), sValue); 283 CPPUNIT_ASSERT(xFiledMaster->getPropertyValue("InstanceName") >>= sValue); 284 CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.text.fieldmaster.DataBase.Name"), sValue); 285 } 286 287 DECLARE_OOXMLEXPORT_TEST(testTdf115719, "tdf115719.docx") 288 { 289 // This was a single page, instead of pushing the textboxes to the second 290 // page. 291 CPPUNIT_ASSERT_EQUAL(2, getPages()); 292 } 293 294 DECLARE_OOXMLIMPORT_TEST(testTdf115719b, "tdf115719b.docx") 295 { 296 // This is similar to testTdf115719, but here the left textbox is not aligned "from left, by 297 // 0cm" but simply aligned to left, which is a different codepath. 298 299 // Without the accompanying fix in place, this test would have failed with: 300 // - Expected: 2 301 // - Actual : 1 302 // i.e. the the textboxes did not appear on the 2nd page, but everything was on a single page. 303 CPPUNIT_ASSERT_EQUAL(2, getPages()); 304 } 305 306 DECLARE_OOXMLEXPORT_TEST(testTdf123243, "tdf123243.docx") 307 { 308 // Without the accompanying fix in place, this test would have failed with 'Expected: 1; Actual: 309 // 2'; i.e. unexpected paragraph margin created 2 pages. 310 CPPUNIT_ASSERT_EQUAL(1, getPages()); 311 } 312 313 DECLARE_OOXMLEXPORT_TEST(testTdf116410, "tdf116410.docx") 314 { 315 // Opposite of the above, was 2 pages, should be 1 page. 316 CPPUNIT_ASSERT_EQUAL(1, getPages()); 317 } 318 319 DECLARE_OOXMLEXPORT_TEST(testDefaultStyle, "defaultStyle.docx") 320 { 321 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Default Style", OUString("Title"), getProperty<OUString>(getParagraph(1), "ParaStyleName") ); 322 CPPUNIT_ASSERT_EQUAL(2, getPages()); 323 } 324 325 DECLARE_OOXMLEXPORT_TEST(testTdf117988, "tdf117988.docx") 326 { 327 CPPUNIT_ASSERT_EQUAL(1, getPages()); 328 } 329 330 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testParagraphSplitOnSectionBorder, "parasplit-on-section-border.odt") 331 { 332 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 333 334 // Test document has only two paragraphs. After splitting, it should contain 335 // three of them. 336 assertXPath(pXmlDoc, "//w:sectPr", 2); 337 assertXPath(pXmlDoc, "//w:p", 3); 338 } 339 340 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf44832_testSectionWithDifferentHeader, "tdf44832_section_new_header.odt") 341 { 342 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 343 assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:headerReference", 1); 344 } 345 346 DECLARE_OOXMLEXPORT_TEST(testSignatureLineShape, "signature-line-all-props-set.docx") 347 { 348 uno::Reference<drawing::XShape> xSignatureLineShape = getShape(1); 349 uno::Reference<beans::XPropertySet> xPropSet(xSignatureLineShape, uno::UNO_QUERY); 350 351 bool bIsSignatureLine; 352 xPropSet->getPropertyValue("IsSignatureLine") >>= bIsSignatureLine; 353 CPPUNIT_ASSERT_EQUAL(true, bIsSignatureLine); 354 355 bool bShowSignDate; 356 xPropSet->getPropertyValue("SignatureLineShowSignDate") >>= bShowSignDate; 357 CPPUNIT_ASSERT_EQUAL(true, bShowSignDate); 358 359 bool bCanAddComment; 360 xPropSet->getPropertyValue("SignatureLineCanAddComment") >>= bCanAddComment; 361 CPPUNIT_ASSERT_EQUAL(true, bCanAddComment); 362 363 OUString aSignatureLineId; 364 xPropSet->getPropertyValue("SignatureLineId") >>= aSignatureLineId; 365 CPPUNIT_ASSERT_EQUAL(OUString("{0EBE47D5-A1BD-4C9E-A52E-6256E5C345E9}"), aSignatureLineId); 366 367 OUString aSuggestedSignerName; 368 xPropSet->getPropertyValue("SignatureLineSuggestedSignerName") >>= aSuggestedSignerName; 369 CPPUNIT_ASSERT_EQUAL(OUString("John Doe"), aSuggestedSignerName); 370 371 OUString aSuggestedSignerTitle; 372 xPropSet->getPropertyValue("SignatureLineSuggestedSignerTitle") >>= aSuggestedSignerTitle; 373 CPPUNIT_ASSERT_EQUAL(OUString("Farmer"), aSuggestedSignerTitle); 374 375 OUString aSuggestedSignerEmail; 376 xPropSet->getPropertyValue("SignatureLineSuggestedSignerEmail") >>= aSuggestedSignerEmail; 377 CPPUNIT_ASSERT_EQUAL(OUString("john@thefarmers.com"), aSuggestedSignerEmail); 378 379 OUString aSigningInstructions; 380 xPropSet->getPropertyValue("SignatureLineSigningInstructions") >>= aSigningInstructions; 381 CPPUNIT_ASSERT_EQUAL(OUString("Check the machines!"), aSigningInstructions); 382 } 383 384 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf117805, "tdf117805.odt") 385 { 386 uno::Reference<packages::zip::XZipFileAccess2> xNameAccess 387 = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), 388 maTempFile.GetURL()); 389 // This failed, the header was lost. It's still referenced at an incorrect 390 // location in document.xml, though. 391 CPPUNIT_ASSERT(xNameAccess->hasByName("word/header1.xml")); 392 393 uno::Reference<text::XText> textbox(getShape(1), uno::UNO_QUERY); 394 CPPUNIT_ASSERT_EQUAL(8, getParagraphs(textbox)); 395 } 396 397 DECLARE_OOXMLEXPORT_TEST(testTdf113183, "tdf113183.docx") 398 { 399 // The horizontal positioning of the star shape affected the positioning of 400 // the triangle one, so the triangle was outside the page frame. 401 xmlDocPtr pXmlDoc = parseLayoutDump(); 402 sal_Int32 nPageLeft = getXPath(pXmlDoc, "/root/page[1]/infos/bounds", "left").toInt32(); 403 sal_Int32 nPageWidth = getXPath(pXmlDoc, "/root/page[1]/infos/bounds", "width").toInt32(); 404 sal_Int32 nShapeLeft 405 = getXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject[2]/bounds", "left") 406 .toInt32(); 407 sal_Int32 nShapeWidth 408 = getXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject[2]/bounds", "width") 409 .toInt32(); 410 // Make sure the second triangle shape is within the page bounds (with ~1px tolerance). 411 CPPUNIT_ASSERT_GREATEREQUAL(nShapeLeft + nShapeWidth, nPageLeft + nPageWidth + 21); 412 } 413 414 DECLARE_OOXMLEXPORT_TEST(testGraphicObjectFliph, "graphic-object-fliph.docx") 415 { 416 CPPUNIT_ASSERT(getProperty<bool>(getShape(1), "HoriMirroredOnEvenPages")); 417 CPPUNIT_ASSERT(getProperty<bool>(getShape(1), "HoriMirroredOnOddPages")); 418 } 419 420 DECLARE_OOXMLEXPORT_TEST(testTdf113547, "tdf113547.docx") 421 { 422 uno::Reference<beans::XPropertySet> xPropertySet( 423 getStyles("NumberingStyles")->getByName("WWNum1"), uno::UNO_QUERY); 424 uno::Reference<container::XIndexAccess> xLevels( 425 xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY); 426 comphelper::SequenceAsHashMap aProps(xLevels->getByIndex(0)); // 1st level 427 // This was 0, first-line left margin of the numbering was lost. 428 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-635), aProps["FirstLineIndent"].get<sal_Int32>()); 429 } 430 431 DECLARE_OOXMLEXPORT_TEST(testTdf113399, "tdf113399.doc") 432 { 433 // 0 padding was not preserved 434 // In LO 0 is the default, but in OOXML format the default is 254 / 127 435 uno::Reference<beans::XPropertySet> xPropSet(getShape(1), uno::UNO_QUERY); 436 sal_Int32 nPaddingValue; 437 xPropSet->getPropertyValue("TextLeftDistance") >>= nPaddingValue; 438 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nPaddingValue); 439 xPropSet->getPropertyValue("TextRightDistance") >>= nPaddingValue; 440 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nPaddingValue); 441 xPropSet->getPropertyValue("TextUpperDistance") >>= nPaddingValue; 442 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nPaddingValue); 443 xPropSet->getPropertyValue("TextLowerDistance") >>= nPaddingValue; 444 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nPaddingValue); 445 } 446 447 DECLARE_OOXMLEXPORT_TEST(testTdf114882, "tdf114882.docx") 448 { 449 // fastserializer must not fail assertion because of mismatching elements 450 } 451 452 DECLARE_OOXMLEXPORT_TEST(testTdf49073, "tdf49073.docx") 453 { 454 // test case for Asian phontic guide (ruby text.) 455 sal_Unicode aRuby[3] = {0x304D,0x3082,0x3093}; 456 OUString sRuby(aRuby, SAL_N_ELEMENTS(aRuby)); 457 CPPUNIT_ASSERT_EQUAL(sRuby,getProperty<OUString>(getParagraph(1)->getStart(), "RubyText")); 458 OUString sStyle = getProperty<OUString>( getParagraph(1)->getStart(), "RubyCharStyleName"); 459 uno::Reference<beans::XPropertySet> xPropertySet(getStyles("CharacterStyles")->getByName(sStyle), uno::UNO_QUERY ); 460 CPPUNIT_ASSERT_EQUAL(5.f, getProperty<float>(xPropertySet, "CharHeight")); 461 CPPUNIT_ASSERT_EQUAL(sal_Int16(text::RubyAdjust_CENTER) ,getProperty<sal_Int16>(getParagraph(2)->getStart(),"RubyAdjust")); 462 CPPUNIT_ASSERT_EQUAL(sal_Int16(text::RubyAdjust_BLOCK) ,getProperty<sal_Int16>(getParagraph(3)->getStart(),"RubyAdjust")); 463 CPPUNIT_ASSERT_EQUAL(sal_Int16(text::RubyAdjust_INDENT_BLOCK),getProperty<sal_Int16>(getParagraph(4)->getStart(),"RubyAdjust")); 464 CPPUNIT_ASSERT_EQUAL(sal_Int16(text::RubyAdjust_LEFT) ,getProperty<sal_Int16>(getParagraph(5)->getStart(),"RubyAdjust")); 465 CPPUNIT_ASSERT_EQUAL(sal_Int16(text::RubyAdjust_RIGHT) ,getProperty<sal_Int16>(getParagraph(6)->getStart(),"RubyAdjust")); 466 CPPUNIT_ASSERT_EQUAL(sal_Int16(text::RubyPosition::INTER_CHARACTER) ,getProperty<sal_Int16>(getParagraph(7)->getStart(),"RubyPosition")); 467 } 468 469 DECLARE_OOXMLEXPORT_TEST(testTdf114703, "tdf114703.docx") 470 { 471 uno::Reference<container::XIndexAccess> xRules 472 = getProperty<uno::Reference<container::XIndexAccess>>( 473 getStyles("NumberingStyles")->getByName("WWNum1"), "NumberingRules"); 474 // This was 0, level override "default" replaced the non-default value from 475 // the abstract level. 476 CPPUNIT_ASSERT_EQUAL( 477 static_cast<sal_Int32>(-1000), 478 comphelper::SequenceAsHashMap(xRules->getByIndex(0))["FirstLineIndent"].get<sal_Int32>()); 479 } 480 481 DECLARE_OOXMLEXPORT_TEST(testTdf113258, "tdf113258.docx") 482 { 483 uno::Reference<text::XTextRange> xShape(getShape(1), uno::UNO_QUERY); 484 // This was 494, i.e. automatic spacing resulted in non-zero paragraph top 485 // margin for the first paragraph in a shape. 486 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 487 getProperty<sal_Int32>(xShape->getStart(), "ParaTopMargin")); 488 } 489 490 DECLARE_OOXMLEXPORT_TEST(testTdf113258_noBeforeAutospacing, "tdf113258_noBeforeAutospacing.docx") 491 { 492 uno::Reference<text::XTextRange> xShape(getShape(1), uno::UNO_QUERY); 493 // This was 0, i.e. disabled automatic spacing still resulted in zero paragraph 494 // top margin for the first paragraph in a shape. 495 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1764), 496 getProperty<sal_Int32>(xShape->getStart(), "ParaTopMargin")); 497 } 498 499 DECLARE_OOXMLEXPORT_TEST(testTdf120511_eatenSection, "tdf120511_eatenSection.docx") 500 { 501 xmlDocPtr pXmlDoc = parseLayoutDump(); 502 sal_Int32 nHeight = getXPath(pXmlDoc, "/root/page[1]/infos/prtBounds", "height").toInt32(); 503 sal_Int32 nWidth = getXPath(pXmlDoc, "/root/page[1]/infos/prtBounds", "width").toInt32(); 504 CPPUNIT_ASSERT_MESSAGE( "Page1 is portrait", nWidth < nHeight ); 505 nHeight = getXPath(pXmlDoc, "/root/page[2]/infos/prtBounds", "height").toInt32(); 506 nWidth = getXPath(pXmlDoc, "/root/page[2]/infos/prtBounds", "width").toInt32(); 507 CPPUNIT_ASSERT_MESSAGE( "Page2 is landscape", nWidth > nHeight ); 508 } 509 510 DECLARE_OOXMLEXPORT_TEST(testTdf104354, "tdf104354.docx") 511 { 512 uno::Reference<text::XTextRange> xShape(getShape(1), uno::UNO_QUERY); 513 // This was 494, i.e. automatic spacing resulted in non-zero paragraph top 514 // margin for the first paragraph in a text frame. 515 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 516 getProperty<sal_Int32>(xShape->getStart(), "ParaTopMargin")); 517 // still 494 in the second paragraph 518 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), 519 getProperty<sal_Int32>(xShape->getEnd(), "ParaTopMargin")); 520 } 521 522 DECLARE_OOXMLEXPORT_TEST(testTdf104354_firstParaInSection, "tdf104354_firstParaInSection.docx") 523 { 524 uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY); 525 uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes(); 526 uno::Reference<text::XText> xText(xFootnotes->getByIndex(0), uno::UNO_QUERY); 527 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), 528 getProperty<sal_Int32>(getParagraphOfText(1, xText), "ParaTopMargin")); 529 CPPUNIT_ASSERT_EQUAL(1, getPages()); 530 } 531 532 DECLARE_OOXMLEXPORT_TEST(testPageBreak_after, "pageBreak_after.odt") 533 { 534 // The problem was that the page breakAfter put the empty page BEFORE the table 535 xmlDocPtr pDump = parseLayoutDump(); 536 assertXPath(pDump, "/root/page[1]/body/tab", 1); 537 // There should be two pages actually - a blank page after a page break. 538 CPPUNIT_ASSERT_EQUAL_MESSAGE("Did you fix?? Table should be on page one of two", 1, getPages()); 539 } 540 541 DECLARE_OOXMLEXPORT_TEST(testTdf107035, "tdf107035.docx") 542 { 543 // Select the second run containing the page number field 544 auto xPgNumRun = getRun(getParagraph(1), 2, "1"); 545 546 // Check that the page number field colour is set to "automatic". 547 sal_Int32 nPgNumColour = getProperty<sal_Int32>(xPgNumRun, "CharColor"); 548 CPPUNIT_ASSERT_EQUAL(sal_Int32(COL_AUTO), nPgNumColour); 549 } 550 551 DECLARE_OOXMLEXPORT_TEST(testTdf112118_DOCX, "tdf112118.docx") 552 { 553 // The resulting left margin width (2081) differs from its DOC counterpart from ww8export2.cxx, 554 // because DOCX import does two conversions between mm/100 and twips on the route, losing one 555 // twip on the road and arriving with a value that is 2 mm/100 less. I don't see an obvious way 556 // to avoid that. 557 static const struct { 558 const char* styleName; 559 struct { 560 const char* sideName; 561 sal_Int32 nMargin; 562 sal_Int32 nBorderDistance; 563 sal_Int32 nBorderWidth; 564 } sideParams[4]; 565 } styleParams[] = { // Margin (MS-style), border distance, border width 566 { 567 "Standard", 568 { 569 { "Top", 496, 847, 159 }, // 851 twip, 24 pt (from text), 4.5 pt 570 { "Left", 2081, 706, 212 }, // 1701 twip, 20 pt (from text), 6.0 pt 571 { "Bottom", 1401, 564, 35 }, // 1134 twip, 16 pt (from text), 1.0 pt 572 { "Right", 3471, 423, 106 } // 2268 twip, 12 pt (from text), 3.0 pt 573 } 574 }, 575 { 576 "Converted1", 577 { 578 { "Top", 847, 496, 159 }, // 851 twip, 24 pt (from edge), 4.5 pt 579 { "Left", 706, 2081, 212 }, // 1701 twip, 20 pt (from edge), 6.0 pt 580 { "Bottom", 564, 1401, 35 }, // 1134 twip, 16 pt (from edge), 1.0 pt 581 { "Right", 423, 3471, 106 } // 2268 twip, 12 pt (from edge), 3.0 pt 582 } 583 } 584 }; 585 auto xStyles = getStyles("PageStyles"); 586 587 for (const auto& style : styleParams) 588 { 589 const OUString sName = OUString::createFromAscii(style.styleName); 590 uno::Reference<beans::XPropertySet> xStyle(xStyles->getByName(sName), uno::UNO_QUERY_THROW); 591 for (const auto& side : style.sideParams) 592 { 593 const OUString sSide = OUString::createFromAscii(side.sideName); 594 const OString sStage = style.styleName + OStringLiteral(" ") + side.sideName; 595 596 sal_Int32 nMargin = getProperty<sal_Int32>(xStyle, sSide + "Margin"); 597 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(sStage + " margin width").getStr(), 598 side.nMargin, nMargin); 599 600 sal_Int32 nBorderDistance = getProperty<sal_Int32>(xStyle, sSide + "BorderDistance"); 601 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(sStage + " border distance").getStr(), 602 side.nBorderDistance, nBorderDistance); 603 604 table::BorderLine aBorder = getProperty<table::BorderLine>(xStyle, sSide + "Border"); 605 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(sStage + " border width").getStr(), 606 side.nBorderWidth, 607 sal_Int32(aBorder.OuterLineWidth + aBorder.InnerLineWidth + aBorder.LineDistance)); 608 609 // tdf#116472: check that AUTO border color is imported as black 610 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(sStage + " border color").getStr(), 611 sal_Int32(COL_BLACK), aBorder.Color); 612 } 613 } 614 } 615 616 DECLARE_OOXMLEXPORT_TEST(testTdf82177_outsideCellBorders, "tdf82177_outsideCellBorders.docx") 617 { 618 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); 619 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); 620 uno::Reference< text::XTextTable > xTable( xTables->getByIndex(0), uno::UNO_QUERY ); 621 uno::Reference< table::XCell > xCell = xTable->getCellByName( "E4" ); 622 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), getProperty<table::BorderLine2>(xCell, "TopBorder").LineWidth); 623 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), getProperty<table::BorderLine2>(xCell, "LeftBorder").LineWidth); 624 } 625 626 DECLARE_OOXMLEXPORT_TEST(testTdf82177_insideCellBorders, "tdf82177_insideCellBorders.docx") 627 { 628 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); 629 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); 630 uno::Reference< text::XTextTable > xTable( xTables->getByIndex(0), uno::UNO_QUERY ); 631 uno::Reference< table::XCell > xCell = xTable->getCellByName( "E4" ); 632 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), getProperty<table::BorderLine2>(xCell, "TopBorder").LineWidth); 633 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), getProperty<table::BorderLine2>(xCell, "LeftBorder").LineWidth); 634 } 635 636 DECLARE_OOXMLEXPORT_TEST(testTdf82177_tblBorders, "tdf82177_tblBorders.docx") 637 { 638 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); 639 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); 640 uno::Reference< text::XTextTable > xTable( xTables->getByIndex(0), uno::UNO_QUERY ); 641 uno::Reference< table::XCell > xCell = xTable->getCellByName( "A5" ); 642 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), getProperty<table::BorderLine2>(xCell, "BottomBorder").LineWidth); 643 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), getProperty<table::BorderLine2>(xCell, "LeftBorder").LineWidth); 644 xCell.set(xTable->getCellByName( "E5" )); 645 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), getProperty<table::BorderLine2>(xCell, "TopBorder").LineWidth); 646 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), getProperty<table::BorderLine2>(xCell, "LeftBorder").LineWidth); 647 } 648 649 DECLARE_OOXMLEXPORT_TEST(testTdf119760_positionCellBorder, "tdf119760_positionCellBorder.docx") 650 { 651 //inconsistent in Word even. 2016 positions on last row, 2003 positions on first cell. 652 sal_Int32 nRowLeft = parseDump("/root/page/body/tab[4]/row[1]/infos/bounds", "left").toInt32(); 653 sal_Int32 nTextLeft = parseDump("/root/page/body/tab[4]/row[1]/cell[1]/txt/infos/bounds", "left").toInt32(); 654 CPPUNIT_ASSERT( nRowLeft < nTextLeft ); 655 } 656 657 DECLARE_OOXMLEXPORT_TEST(testTdf98620_environmentBiDi, "tdf98620_environmentBiDi.odt") 658 { 659 CPPUNIT_ASSERT_EQUAL(text::WritingMode2::RL_TB, getProperty<sal_Int16>( getParagraph(1), "WritingMode" )); 660 CPPUNIT_ASSERT_EQUAL(sal_Int32(style::ParagraphAdjust_RIGHT), getProperty<sal_Int32>( getParagraph(1), "ParaAdjust" )); 661 662 CPPUNIT_ASSERT_EQUAL(text::WritingMode2::LR_TB, getProperty<sal_Int16>( getParagraph(2), "WritingMode" )); 663 CPPUNIT_ASSERT_EQUAL(sal_Int32(style::ParagraphAdjust_RIGHT), getProperty<sal_Int32>( getParagraph(2), "ParaAdjust" )); 664 } 665 666 DECLARE_OOXMLEXPORT_TEST(testTdf116976, "tdf116976.docx") 667 { 668 // This was 0, relative size of shape after bitmap was ignored. 669 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(40), 670 getProperty<sal_Int16>(getShape(1), "RelativeWidth")); 671 } 672 673 DECLARE_OOXMLEXPORT_TEST(testTdf116985, "tdf116985.docx") 674 { 675 // Body frame width is 10800, 40% is the requested relative width, with 144 676 // spacing to text on the left/right side. So ideal width would be 4032, 677 // was 3431. Allow one pixel tolerance, though. 678 sal_Int32 nWidth 679 = parseDump("/root/page[1]/body/txt[1]/anchored/fly/infos/bounds", "width").toInt32(); 680 CPPUNIT_ASSERT(nWidth > 4000); 681 } 682 683 DECLARE_OOXMLEXPORT_TEST(testTdf116801, "tdf116801.docx") 684 { 685 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); 686 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), 687 uno::UNO_QUERY); 688 // This raised a lang::IndexOutOfBoundsException, table was missing from 689 // the import result. 690 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); 691 uno::Reference<text::XTextRange> xCell(xTable->getCellByName("D1"), uno::UNO_QUERY); 692 CPPUNIT_ASSERT_EQUAL(OUString("D1"), xCell->getString()); 693 } 694 695 DECLARE_OOXMLEXPORT_TEST(testTdf107969, "tdf107969.docx") 696 { 697 // A VML object in a footnote's tracked changes caused write past end of document.xml at export to docx. 698 // After that, importing after export failed with 699 // SAXParseException: '[word/document.xml line 2]: Extra content at the end of the document', Stream 'word/document.xml'. 700 } 701 702 DECLARE_OOXMLEXPORT_TEST(testOpenDocumentAsReadOnly, "open-as-read-only.docx") 703 { 704 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); 705 CPPUNIT_ASSERT(pTextDoc); 706 CPPUNIT_ASSERT(pTextDoc->GetDocShell()->IsSecurityOptOpenReadOnly()); 707 } 708 709 DECLARE_OOXMLEXPORT_TEST(testNoDefault, "noDefault.docx") 710 { 711 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); 712 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); 713 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); 714 uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY); 715 uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY); 716 uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); 717 uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY); 718 719 // Row 1: color directly applied to the paragraph, overrides table and style colors 720 CPPUNIT_ASSERT_EQUAL(sal_Int32(0x2E74B5), getProperty<sal_Int32>(getRun(xPara,1), "CharColor")); 721 722 // Row2: (still part of firstRow table-style) ought to use the Normal style color, not the table-style color(5B9BD5) 723 //xCell.set(xTable->getCellByName("A2"), uno::UNO_QUERY); 724 //xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY); 725 //xParaEnum = xParaEnumAccess->createEnumeration(); 726 //xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); 727 //CPPUNIT_ASSERT_EQUAL(sal_Int32(COL_LIGHTMAGENTA), getProperty<sal_Int32>(getRun(xPara,1), "CharColor")); 728 729 // Row 3+: Normal style still applied, even if nothing is specified with w:default="1" 730 xCell.set(xTable->getCellByName("A3"), uno::UNO_QUERY); 731 xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY); 732 xParaEnum = xParaEnumAccess->createEnumeration(); 733 xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); 734 CPPUNIT_ASSERT_EQUAL(sal_Int32(COL_LIGHTMAGENTA), getProperty<sal_Int32>(getRun(xPara,1), "CharColor")); 735 } 736 737 DECLARE_OOXMLEXPORT_TEST(testMarginsFromStyle, "margins_from_style.docx") 738 { 739 // tdf#118521 paragraphs with direct formatting of top or bottom margins have 740 // lost the other margin comes from paragraph style, getting a bad 741 // margin from the default style 742 743 // from direct formatting 744 CPPUNIT_ASSERT_EQUAL(sal_Int32(35), getProperty<sal_Int32>(getParagraph(1), "ParaTopMargin")); 745 // from paragraph style 746 CPPUNIT_ASSERT_EQUAL(sal_Int32(106), getProperty<sal_Int32>(getParagraph(1), "ParaBottomMargin")); 747 748 // from paragraph style 749 CPPUNIT_ASSERT_EQUAL(sal_Int32(388), getProperty<sal_Int32>(getParagraph(3), "ParaTopMargin")); 750 // from direct formatting 751 CPPUNIT_ASSERT_EQUAL(sal_Int32(600), getProperty<sal_Int32>(getParagraph(3), "ParaBottomMargin")); 752 } 753 754 DECLARE_OOXMLEXPORT_TEST(testTdf104348_contextMargin, "tdf104348_contextMargin.docx") 755 { 756 // tdf#104348 shows that ContextMargin belongs with Top/Bottom handling 757 758 uno::Reference<beans::XPropertySet> xMyStyle(getStyles("ParagraphStyles")->getByName("MyStyle"), uno::UNO_QUERY); 759 // from paragraph style - this is what direct formatting should equal 760 sal_Int32 nMargin = getProperty<sal_Int32>(xMyStyle, "ParaBottomMargin"); 761 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nMargin); 762 // from direct formatting 763 CPPUNIT_ASSERT_EQUAL(nMargin, getProperty<sal_Int32>(getParagraph(2), "ParaBottomMargin")); 764 } 765 766 DECLARE_OOXMLEXPORT_TEST(testTdf118521_marginsLR, "tdf118521_marginsLR.docx") 767 { 768 // tdf#118521 paragraphs with direct formatting of only some of left, right, or first margins have 769 // lost the other unset margins coming from paragraph style, getting a bad margin from the default style instead 770 771 uno::Reference<beans::XPropertySet> xMyStyle(getStyles("ParagraphStyles")->getByName("MyStyle"), uno::UNO_QUERY); 772 // from paragraph style - this is what direct formatting should equal 773 sal_Int32 nMargin = getProperty<sal_Int32>(xMyStyle, "ParaLeftMargin"); 774 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nMargin); 775 // from direct formatting 776 CPPUNIT_ASSERT_EQUAL(nMargin, getProperty<sal_Int32>(getParagraph(1), "ParaLeftMargin")); 777 778 nMargin = getProperty<sal_Int32>(xMyStyle, "ParaRightMargin"); 779 CPPUNIT_ASSERT_EQUAL(sal_Int32(1900), nMargin); 780 CPPUNIT_ASSERT_EQUAL(nMargin, getProperty<sal_Int32>(getParagraph(2), "ParaRightMargin")); 781 CPPUNIT_ASSERT_EQUAL(sal_Int32(882), getProperty<sal_Int32>(getParagraph(2), "ParaFirstLineIndent")); 782 } 783 784 DECLARE_OOXMLIMPORT_TEST(testTdf104797, "tdf104797.docx") 785 { 786 // check moveFrom and moveTo 787 CPPUNIT_ASSERT_EQUAL( OUString( "Will this sentence be duplicated?" ), getParagraph( 1 )->getString()); 788 CPPUNIT_ASSERT_EQUAL( OUString( "" ), getRun( getParagraph( 1 ), 1 )->getString()); 789 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(1), 2), "RedlineType")); 790 CPPUNIT_ASSERT_EQUAL(OUString("Delete"),getProperty<OUString>(getRun(getParagraph(1), 2), "RedlineType")); 791 CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(1), 2), "IsStart")); 792 CPPUNIT_ASSERT_EQUAL( OUString( "This is a filler sentence. Will this sentence be duplicated ADDED STUFF?" ), 793 getParagraph( 2 )->getString()); 794 CPPUNIT_ASSERT_EQUAL( OUString( "" ), getRun( getParagraph( 2 ), 1 )->getString()); 795 CPPUNIT_ASSERT_EQUAL( OUString( "This is a filler sentence." ), getRun( getParagraph( 2 ), 2 )->getString()); 796 CPPUNIT_ASSERT_EQUAL( OUString( "" ), getRun( getParagraph( 2 ), 3 )->getString()); 797 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(2), 3), "RedlineType")); 798 CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(2), 3), "RedlineType")); 799 CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(2), 3), "IsStart")); 800 CPPUNIT_ASSERT_EQUAL( OUString( " Will this sentence be duplicated ADDED STUFF?" ), getRun( getParagraph( 2 ), 4 )->getString()); 801 } 802 803 DECLARE_OOXMLEXPORT_TEST(testTdf113608_runAwayNumbering, "tdf113608_runAwayNumbering.docx") 804 { 805 // check that an incorrect numbering style is not applied 806 // after removing a w:r-less paragraph 807 CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(getParagraph(2), "NumberingStyleName")); 808 } 809 810 DECLARE_OOXMLEXPORT_TEST(testTdf119188_list_margin_in_cell, "tdf119188_list_margin_in_cell.docx") 811 { 812 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); 813 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); 814 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); 815 uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY); 816 817 // lists with auto margins in cells: top margin of the first paragraph is zero, 818 // but not the bottom margin of the last paragraph, also other list items have got 819 // zero margins. 820 821 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaTopMargin")); 822 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin")); 823 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), "ParaTopMargin")); 824 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), "ParaBottomMargin")); 825 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(3, xCell->getText()), "ParaTopMargin")); 826 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraphOfText(3, xCell->getText()), "ParaBottomMargin")); 827 } 828 829 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testChart_BorderLine_Style, "Chart_BorderLine_Style.docx") 830 { 831 /* DOCX containing Chart with BorderLine Style as Dash Type should get preserved 832 * inside an XML tag <a:prstDash> with value "dash", "sysDot, "lgDot", etc. 833 */ 834 xmlDocPtr pXmlDoc = parseExport("word/charts/chart1.xml"); 835 assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:spPr/a:ln/a:prstDash", "val", "sysDot"); 836 assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[2]/c:spPr/a:ln/a:prstDash", "val", "sysDash"); 837 assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[3]/c:spPr/a:ln/a:prstDash", "val", "dash"); 838 } 839 840 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testChart_Plot_BorderLine_Style, "Chart_Plot_BorderLine_Style.docx") 841 { 842 /* DOCX containing Chart wall (plot area) and Chart Page with BorderLine Style as Dash Type 843 * should get preserved inside an XML tag <a:prstDash> with value "dash", "sysDot, "lgDot", etc. 844 */ 845 xmlDocPtr pXmlDoc = parseExport("word/charts/chart1.xml"); 846 assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:spPr/a:ln/a:prstDash", "val", "lgDashDot"); 847 assertXPath(pXmlDoc, "/c:chartSpace/c:spPr/a:ln/a:prstDash", "val", "sysDash"); 848 849 } 850 851 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTrackChangesDeletedEmptyParagraph, "testTrackChangesDeletedEmptyParagraph.docx") 852 { 853 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 854 assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:pPr/w:rPr/w:del"); 855 } 856 857 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTrackChangesEmptyParagraphsInADeletion, "testTrackChangesEmptyParagraphsInADeletion.docx") 858 { 859 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 860 for (int i = 1; i < 12; ++i) 861 assertXPath(pXmlDoc, "/w:document/w:body/w:p[" + OString::number(i) + "]/w:pPr/w:rPr/w:del"); 862 } 863 864 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf70234, "tdf70234.docx") 865 { 866 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 867 // import field with tracked deletion 868 assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:del/w:r[1]/w:fldChar"); 869 870 // export multiple runs of a field with tracked deletion 871 assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:del/w:r", 6); 872 873 // export w:delInstrText 874 assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:del/w:r/w:delInstrText"); 875 } 876 877 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf115212, "tdf115212.docx") 878 { 879 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 880 // export field with tracked deletion 881 assertXPath(pXmlDoc, "//w:p[2]/w:del[1]/w:r[1]/w:fldChar"); 882 } 883 884 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf126243, "tdf120338.docx") 885 { 886 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 887 // export change tracking rejection data for tracked paragraph style change 888 assertXPath(pXmlDoc, "/w:document/w:body/w:p[11]/w:pPr/w:pPrChange/w:pPr/w:pStyle", "val", "Heading3"); 889 } 890 891 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf126245, "tdf126245.docx") 892 { 893 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 894 // export change tracking rejection data for tracked numbering change 895 assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:pPrChange/w:pPr/w:numPr/w:numId", "val", "1"); 896 } 897 898 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf124491, "tdf124491.docx") 899 { 900 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 901 // import format change of empty lines, FIXME: change w:r with w:pPr in export 902 assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/*/w:rPr/w:rPrChange"); 903 // empty line without format change 904 assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/*/w:rPrChange", 0); 905 assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/*/*/w:rPrChange", 0); 906 } 907 908 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf105485, "tdf105485.docx") 909 { 910 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 911 // import change tracking of deleted comments 912 assertXPath(pXmlDoc, "//w:del/w:r/w:commentReference"); 913 } 914 915 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf125894, "tdf125894.docx") 916 { 917 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 918 // import change tracking in frames 919 assertXPath(pXmlDoc, "//w:del", 2); 920 assertXPath(pXmlDoc, "//w:ins"); 921 } 922 923 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf128156, "tdf128156.docx") 924 { 925 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 926 // import change tracking in frames 927 assertXPath(pXmlDoc, "//w:ins"); 928 } 929 930 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf125546, "tdf125546.docx") 931 { 932 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 933 // compress redlines (it was 15) 934 assertXPath(pXmlDoc, "//w:rPrChange", 2); 935 } 936 937 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testLabelWidthAndPosition_Left_FirstLineIndent, "Hau_min_list2.fodt") 938 { 939 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 940 // list is LABEL_WIDTH_AND_POSITION with SvxAdjust::Left 941 // I) LTR 942 // a) all LTR cases with no number text look good in Word 943 // 1) negative first line indent on paragraph: 944 // no list width/indent: this one was 0 previously; this looks good 945 assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:ind", "start", "0"); 946 assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:ind", "hanging", "399"); 947 assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:ind", "end", "0"); 948 // list width: 949 assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:ind", "start", "567"); 950 assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:ind", "hanging", "966"); 951 assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:ind", "end", "0"); 952 // list indent: 953 assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:pPr/w:ind", "start", "567"); 954 assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:pPr/w:ind", "hanging", "399"); 955 assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:pPr/w:ind", "end", "0"); 956 // list width + list indent: 957 assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:pPr/w:ind", "start", "1134"); 958 assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:pPr/w:ind", "hanging", "966"); 959 assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:pPr/w:ind", "end", "0"); 960 // 2) positive first line indent on paragraph: 961 // no list width/indent: 962 assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:pPr/w:ind", "start", "0"); 963 assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:pPr/w:ind", "firstLine", "420"); 964 assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:pPr/w:ind", "end", "0"); 965 // list width: 966 assertXPath(pXmlDoc, "/w:document/w:body/w:p[6]/w:pPr/w:ind", "start", "567"); 967 assertXPath(pXmlDoc, "/w:document/w:body/w:p[6]/w:pPr/w:ind", "hanging", "147"); 968 assertXPath(pXmlDoc, "/w:document/w:body/w:p[6]/w:pPr/w:ind", "end", "0"); 969 // list indent: 970 assertXPath(pXmlDoc, "/w:document/w:body/w:p[7]/w:pPr/w:ind", "start", "567"); 971 assertXPath(pXmlDoc, "/w:document/w:body/w:p[7]/w:pPr/w:ind", "firstLine", "420"); 972 assertXPath(pXmlDoc, "/w:document/w:body/w:p[7]/w:pPr/w:ind", "end", "0"); 973 // list width + list indent: 974 assertXPath(pXmlDoc, "/w:document/w:body/w:p[8]/w:pPr/w:ind", "start", "1134"); 975 assertXPath(pXmlDoc, "/w:document/w:body/w:p[8]/w:pPr/w:ind", "hanging", "147"); 976 assertXPath(pXmlDoc, "/w:document/w:body/w:p[8]/w:pPr/w:ind", "end", "0"); 977 // b) all LTR cases with number text: the indent looks good but some tabs are wrong 978 // 1) negative first line indent on paragraph: 979 // no list width/indent: this one was 0 previously; this looks good 980 assertXPath(pXmlDoc, "/w:document/w:body/w:p[9]/w:pPr/w:ind", "start", "0"); 981 assertXPath(pXmlDoc, "/w:document/w:body/w:p[9]/w:pPr/w:ind", "hanging", "399"); 982 assertXPath(pXmlDoc, "/w:document/w:body/w:p[9]/w:pPr/w:ind", "end", "0"); 983 // list width: 984 assertXPath(pXmlDoc, "/w:document/w:body/w:p[10]/w:pPr/w:ind", "start", "567"); 985 assertXPath(pXmlDoc, "/w:document/w:body/w:p[10]/w:pPr/w:ind", "hanging", "966"); 986 assertXPath(pXmlDoc, "/w:document/w:body/w:p[10]/w:pPr/w:ind", "end", "0"); 987 // list indent: 988 assertXPath(pXmlDoc, "/w:document/w:body/w:p[11]/w:pPr/w:ind", "start", "567"); 989 assertXPath(pXmlDoc, "/w:document/w:body/w:p[11]/w:pPr/w:ind", "hanging", "399"); 990 assertXPath(pXmlDoc, "/w:document/w:body/w:p[11]/w:pPr/w:ind", "end", "0"); 991 // list width + list indent: 992 assertXPath(pXmlDoc, "/w:document/w:body/w:p[12]/w:pPr/w:ind", "start", "1134"); 993 assertXPath(pXmlDoc, "/w:document/w:body/w:p[12]/w:pPr/w:ind", "hanging", "966"); 994 assertXPath(pXmlDoc, "/w:document/w:body/w:p[12]/w:pPr/w:ind", "end", "0"); 995 // 2) positive first line indent on paragraph: 996 // no list width/indent: 997 assertXPath(pXmlDoc, "/w:document/w:body/w:p[13]/w:pPr/w:ind", "start", "0"); 998 assertXPath(pXmlDoc, "/w:document/w:body/w:p[13]/w:pPr/w:ind", "firstLine", "420"); 999 assertXPath(pXmlDoc, "/w:document/w:body/w:p[13]/w:pPr/w:ind", "end", "0"); 1000 // list width: 1001 assertXPath(pXmlDoc, "/w:document/w:body/w:p[14]/w:pPr/w:ind", "start", "567"); 1002 assertXPath(pXmlDoc, "/w:document/w:body/w:p[14]/w:pPr/w:ind", "hanging", "147"); 1003 assertXPath(pXmlDoc, "/w:document/w:body/w:p[14]/w:pPr/w:ind", "end", "0"); 1004 // list indent: 1005 assertXPath(pXmlDoc, "/w:document/w:body/w:p[15]/w:pPr/w:ind", "start", "567"); 1006 assertXPath(pXmlDoc, "/w:document/w:body/w:p[15]/w:pPr/w:ind", "firstLine", "420"); 1007 assertXPath(pXmlDoc, "/w:document/w:body/w:p[15]/w:pPr/w:ind", "end", "0"); 1008 // list width + list indent: 1009 assertXPath(pXmlDoc, "/w:document/w:body/w:p[16]/w:pPr/w:ind", "start", "1134"); 1010 assertXPath(pXmlDoc, "/w:document/w:body/w:p[16]/w:pPr/w:ind", "hanging", "147"); 1011 assertXPath(pXmlDoc, "/w:document/w:body/w:p[16]/w:pPr/w:ind", "end", "0"); 1012 // (w:p[17] is empty) 1013 // I) RTL 1014 // a) only RTL cases with no number text and no width/indent look good in Word 1015 // 1) negative first line indent on paragraph: 1016 // no list width/indent 1017 assertXPath(pXmlDoc, "/w:document/w:body/w:p[18]/w:pPr/w:ind", "start", "0"); 1018 assertXPath(pXmlDoc, "/w:document/w:body/w:p[18]/w:pPr/w:ind", "hanging", "399"); 1019 assertXPath(pXmlDoc, "/w:document/w:body/w:p[18]/w:pPr/w:ind", "end", "0"); 1020 // 2) positive first line indent on paragraph: 1021 // no list width/indent: 1022 assertXPath(pXmlDoc, "/w:document/w:body/w:p[22]/w:pPr/w:ind", "start", "0"); 1023 assertXPath(pXmlDoc, "/w:document/w:body/w:p[22]/w:pPr/w:ind", "firstLine", "420"); 1024 assertXPath(pXmlDoc, "/w:document/w:body/w:p[22]/w:pPr/w:ind", "end", "0"); 1025 // b) RTL cases with number text: the indent looks good but some tabs are wrong 1026 // 1) negative first line indent on paragraph: 1027 // no list width/indent 1028 assertXPath(pXmlDoc, "/w:document/w:body/w:p[26]/w:pPr/w:ind", "start", "0"); 1029 assertXPath(pXmlDoc, "/w:document/w:body/w:p[26]/w:pPr/w:ind", "hanging", "399"); 1030 assertXPath(pXmlDoc, "/w:document/w:body/w:p[26]/w:pPr/w:ind", "end", "0"); 1031 // 2) positive first line indent on paragraph: 1032 // no list width/indent: 1033 assertXPath(pXmlDoc, "/w:document/w:body/w:p[30]/w:pPr/w:ind", "start", "0"); 1034 assertXPath(pXmlDoc, "/w:document/w:body/w:p[30]/w:pPr/w:ind", "firstLine", "420"); 1035 assertXPath(pXmlDoc, "/w:document/w:body/w:p[30]/w:pPr/w:ind", "end", "0"); 1036 // TODO: other cases 1037 } 1038 1039 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf124604, "tdf124604.docx") 1040 { 1041 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 1042 // If the numbering comes from a base style, indentation of the base style has also priority. 1043 assertXPath(pXmlDoc, "/w:document/w:body/w:p[7]/w:pPr/w:ind", "start", "0"); 1044 } 1045 1046 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf95374, "tdf95374.docx") 1047 { 1048 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 1049 // Numbering disabled by non-existent numId=0, disabling also inheritance of indentation of parent styles 1050 assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:ind", "hanging", "0"); 1051 assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:ind", "start", "1136"); 1052 } 1053 1054 DECLARE_OOXMLEXPORT_TEST(testTdf118691, "tdf118691.docx") 1055 { 1056 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); 1057 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), 1058 uno::UNO_QUERY); 1059 // Text "Before" stays in the first cell, not removed before the table because of 1060 // bad handling of <w:cr> 1061 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); 1062 uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY); 1063 CPPUNIT_ASSERT_EQUAL(OUString("Before\nAfter"), xCell->getString()); 1064 } 1065 1066 DECLARE_OOXMLEXPORT_TEST(testTdf64264, "tdf64264.docx") 1067 { 1068 // DOCX table rows with tblHeader setting mustn't modify the count of the 1069 // repeated table header rows, when there is rows before them without tblHeader settings. 1070 xmlDocPtr pDump = parseLayoutDump(); 1071 CPPUNIT_ASSERT_EQUAL(2, getPages()); 1072 1073 // table starts on page 1 and finished on page 2 1074 // and it has got only a single repeating header line 1075 assertXPath(pDump, "/root/page[2]/body/tab", 1); 1076 assertXPath(pDump, "/root/page[2]/body/tab/row", 47); 1077 CPPUNIT_ASSERT_EQUAL(OUString("Repeating Table Header"), 1078 parseDump("/root/page[2]/body/tab/row[1]/cell[1]/txt/text()")); 1079 CPPUNIT_ASSERT_EQUAL(OUString("Text"), 1080 parseDump("/root/page[2]/body/tab/row[2]/cell[1]/txt/text()")); 1081 } 1082 1083 DECLARE_OOXMLEXPORT_TEST(testTdf58944RepeatingTableHeader, "tdf58944-repeating-table-header.docx") 1084 { 1085 // DOCX tables with more than 10 repeating header lines imported without repeating header lines 1086 // as a workaround for MSO's limitation of header line repetition 1087 xmlDocPtr pDump = parseLayoutDump(); 1088 CPPUNIT_ASSERT_EQUAL(2, getPages()); 1089 1090 // table starts on page 1 and finished on page 2 1091 // instead of showing only a part of it on page 2 1092 assertXPath(pDump, "/root/page[1]/body/tab", 1); 1093 assertXPath(pDump, "/root/page[1]/body/tab/row", 11); 1094 CPPUNIT_ASSERT_EQUAL(OUString("Test1"), 1095 parseDump("/root/page[2]/body/tab/row[1]/cell[1]/txt/text()")); 1096 CPPUNIT_ASSERT_EQUAL(OUString("Test2"), 1097 parseDump("/root/page[2]/body/tab/row[2]/cell[1]/txt/text()")); 1098 } 1099 1100 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf81100, "tdf81100.docx") 1101 { 1102 xmlDocPtr pXmlDoc = parseExport("word/styles.xml"); 1103 CPPUNIT_ASSERT(pXmlDoc); 1104 // keep "repeat table header" setting of table styles 1105 assertXPath(pXmlDoc, "/w:styles/w:style/w:tblStylePr/w:trPr/w:tblHeader", 4); 1106 1107 xmlDocPtr pDump = parseLayoutDump(); 1108 CPPUNIT_ASSERT_EQUAL(3, getPages()); 1109 1110 // table starts on page 1 and finished on page 2 1111 // and it has got only a single repeating header line 1112 assertXPath(pDump, "/root/page[2]/body/tab[1]", 1); 1113 assertXPath(pDump, "/root/page[2]/body/tab[1]/row", 2); 1114 assertXPath(pDump, "/root/page[3]/body/tab", 1); 1115 if (!mbExported) // TODO export tblHeader=false 1116 assertXPath(pDump, "/root/page[3]/body/tab/row", 1); 1117 } 1118 1119 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf121597TrackedDeletionOfMultipleParagraphs, "tdf121597.odt") 1120 { 1121 xmlDocPtr pXmlDoc = parseExport("word/document.xml"); 1122 1123 // check paragraphs with removed paragraph mark 1124 assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:rPr/w:del"); 1125 assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:rPr/w:del"); 1126 assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:pPr/w:rPr/w:del"); 1127 assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:pPr/w:rPr/w:del"); 1128 assertXPath(pXmlDoc, "/w:document/w:body/w:p[7]/w:pPr/w:rPr/w:del"); 1129 assertXPath(pXmlDoc, "/w:document/w:body/w:p[10]/w:pPr/w:rPr/w:del"); 1130 } 1131 1132 DECLARE_OOXMLEXPORT_TEST(testTdf123189_tableBackground, "table-black_fill.docx") 1133 { 1134 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); 1135 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); 1136 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); 1137 1138 uno::Reference<table::XCell> xCell = xTable->getCellByName("A1"); 1139 CPPUNIT_ASSERT_EQUAL(COL_TRANSPARENT, Color(getProperty<sal_uInt32>(xCell, "BackColor"))); 1140 } 1141 1142 DECLARE_OOXMLIMPORT_TEST(testTdf116084, "tdf116084.docx") 1143 { 1144 // tracked line is not a single text portion: w:del is recognized within w:ins 1145 CPPUNIT_ASSERT_EQUAL( OUString( "" ), getRun( getParagraph( 1 ), 1 )->getString()); 1146 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(1), 1), "RedlineType")); 1147 CPPUNIT_ASSERT_EQUAL( OUString( "There should be a better start to this. " ), getRun( getParagraph( 1 ), 2 )->getString()); 1148 } 1149 1150 DECLARE_OOXMLIMPORT_TEST(testTdf121176, "tdf121176.docx") 1151 { 1152 // w:del is imported correctly when it is in a same size w:ins 1153 CPPUNIT_ASSERT_EQUAL( OUString( "" ), getRun( getParagraph( 1 ), 1 )->getString()); 1154 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(1), 1), "RedlineType")); 1155 CPPUNIT_ASSERT_EQUAL( OUString( "must" ), getRun( getParagraph( 1 ), 2 )->getString()); 1156 } 1157 1158 DECLARE_OOXMLIMPORT_TEST(testTdf123054, "tdf123054.docx") 1159 { 1160 CPPUNIT_ASSERT_EQUAL(OUString("No Spacing"), 1161 getProperty<OUString>(getParagraph(20), "ParaStyleName")); 1162 } 1163 1164 DECLARE_OOXMLEXPORT_TEST(testTdf67207_MERGEFIELD_DATABASE, "tdf67207.docx") 1165 { 1166 // database fields use the database "database" and its table "Sheet1" 1167 uno::Reference<beans::XPropertySet> xTextField = getProperty< uno::Reference<beans::XPropertySet> >(getRun(getParagraph(2), 2), "TextField"); 1168 CPPUNIT_ASSERT(xTextField.is()); 1169 uno::Reference<lang::XServiceInfo> xServiceInfo(xTextField, uno::UNO_QUERY_THROW); 1170 uno::Reference<text::XDependentTextField> xDependent(xTextField, uno::UNO_QUERY_THROW); 1171 1172 CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.Database")); 1173 OUString sValue; 1174 xTextField->getPropertyValue("Content") >>= sValue; 1175 CPPUNIT_ASSERT_EQUAL(OUString::fromUtf8("<c1>"), sValue); 1176 1177 uno::Reference<beans::XPropertySet> xFiledMaster = xDependent->getTextFieldMaster(); 1178 uno::Reference<lang::XServiceInfo> xFiledMasterServiceInfo(xFiledMaster, uno::UNO_QUERY_THROW); 1179 1180 CPPUNIT_ASSERT(xFiledMasterServiceInfo->supportsService("com.sun.star.text.fieldmaster.Database")); 1181 1182 // Defined properties: DataBaseName, Name, DataTableName, DataColumnName, DependentTextFields, DataCommandType, InstanceName, DataBaseURL 1183 CPPUNIT_ASSERT(xFiledMaster->getPropertyValue("DataBaseName") >>= sValue); 1184 CPPUNIT_ASSERT_EQUAL(OUString("database"), sValue); 1185 sal_Int32 nCommandType; 1186 CPPUNIT_ASSERT(xFiledMaster->getPropertyValue("DataCommandType") >>= nCommandType); 1187 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nCommandType); // css::sdb::CommandType::TABLE 1188 CPPUNIT_ASSERT(xFiledMaster->getPropertyValue("DataTableName") >>= sValue); 1189 CPPUNIT_ASSERT_EQUAL(OUString("Sheet1"), sValue); 1190 CPPUNIT_ASSERT(xFiledMaster->getPropertyValue("DataColumnName") >>= sValue); 1191 CPPUNIT_ASSERT_EQUAL(OUString("c1"), sValue); 1192 CPPUNIT_ASSERT(xFiledMaster->getPropertyValue("InstanceName") >>= sValue); 1193 CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.text.fieldmaster.DataBase.database.Sheet1.c1"), sValue); 1194 } 1195 1196 CPPUNIT_PLUGIN_IMPLEMENT(); 1197 1198 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1199