1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include <swmodeltestbase.hxx>
12 #include <com/sun/star/style/BreakType.hpp>
13 #include <com/sun/star/style/LineSpacing.hpp>
14 #include <com/sun/star/text/WritingMode.hpp>
15 #include <com/sun/star/text/XTextFrame.hpp>
16 #include <com/sun/star/drawing/XControlShape.hpp>
17 #include <com/sun/star/style/ParagraphAdjust.hpp>
18 #include <com/sun/star/text/XTextTable.hpp>
20 #include <editeng/escapementitem.hxx>
21 #include <IDocumentSettingAccess.hxx>
22 #include <xmloff/odffields.hxx>
23 #include <comphelper/sequenceashashmap.hxx>
27 #include <frameformats.hxx>
28 #include <unotxdoc.hxx>
30 #include <o3tl/string_view.hxx>
32 class Test
: public SwModelTestBase
35 Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {}
38 // TODO: the re-import doesn't work just yet, but that isn't a regression...
39 DECLARE_SW_EXPORT_TEST(testFlyInFly
, "ooo39250-1-min.rtf", nullptr, Test
)
41 // check that anchor of text frame is in other text frame
42 uno::Reference
<text::XTextContent
> const xAnchored(getShape(3), uno::UNO_QUERY
);
43 CPPUNIT_ASSERT(xAnchored
.is());
44 CPPUNIT_ASSERT_EQUAL(OUString("Frame1")/*generated name*/, uno::Reference
<container::XNamed
>(xAnchored
, uno::UNO_QUERY_THROW
)->getName());
45 uno::Reference
<text::XText
> const xAnchorText(xAnchored
->getAnchor()->getText());
46 uno::Reference
<text::XTextFrame
> const xAnchorFrame(xAnchorText
, uno::UNO_QUERY
);
47 CPPUNIT_ASSERT(xAnchorFrame
.is());
48 CPPUNIT_ASSERT_EQUAL(OUString("Frame3"), uno::Reference
<container::XNamed
>(xAnchorFrame
, uno::UNO_QUERY_THROW
)->getName());
51 DECLARE_OOXMLEXPORT_TEST(testTdf125778_lostPageBreakTOX
, "tdf125778_lostPageBreakTOX.docx")
53 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Pages", 3, getPages() );
56 DECLARE_OOXMLEXPORT_TEST(testTdf126994_lostPageBreak
, "tdf126994_lostPageBreak.docx")
58 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Pages", 3, getPages() );
61 DECLARE_OOXMLEXPORT_TEST(testTdf155690
, "tdf155690.docx")
63 uno::Reference
<text::XBookmarksSupplier
> xBookmarksSupplier(mxComponent
, uno::UNO_QUERY
);
64 uno::Reference
<container::XNameAccess
> xBookmarks
= xBookmarksSupplier
->getBookmarks();
66 uno::Reference
<text::XTextContent
> xMark(xBookmarks
->getByName("row1_1"), uno::UNO_QUERY
);
67 CPPUNIT_ASSERT(xMark
.is());
68 // the problem was that the start was after the H
69 CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark
->getAnchor()->getString());
72 uno::Reference
<text::XTextContent
> xMark(xBookmarks
->getByName("row1_2"), uno::UNO_QUERY
);
73 CPPUNIT_ASSERT(xMark
.is());
74 CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark
->getAnchor()->getString());
77 uno::Reference
<text::XTextContent
> xMark(xBookmarks
->getByName("row1_3"), uno::UNO_QUERY
);
78 CPPUNIT_ASSERT(xMark
.is());
79 CPPUNIT_ASSERT_EQUAL(OUString("ello world"), xMark
->getAnchor()->getString());
82 uno::Reference
<text::XTextContent
> xMark(xBookmarks
->getByName("row1_4"), uno::UNO_QUERY
);
83 CPPUNIT_ASSERT(xMark
.is());
84 CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark
->getAnchor()->getString());
87 uno::Reference
<text::XTextContent
> xMark(xBookmarks
->getByName("row2_1"), uno::UNO_QUERY
);
88 CPPUNIT_ASSERT(xMark
.is());
89 CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark
->getAnchor()->getString());
92 uno::Reference
<text::XTextContent
> xMark(xBookmarks
->getByName("row2_1"), uno::UNO_QUERY
);
93 CPPUNIT_ASSERT(xMark
.is());
94 CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark
->getAnchor()->getString());
97 uno::Reference
<text::XTextContent
> xMark(xBookmarks
->getByName("row2_3"), uno::UNO_QUERY
);
98 CPPUNIT_ASSERT(xMark
.is());
99 CPPUNIT_ASSERT_EQUAL(OUString("ello world"), xMark
->getAnchor()->getString());
102 uno::Reference
<text::XTextContent
> xMark(xBookmarks
->getByName("row2_4"), uno::UNO_QUERY
);
103 CPPUNIT_ASSERT(xMark
.is());
104 CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark
->getAnchor()->getString());
108 CPPUNIT_TEST_FIXTURE(Test
, testTdf121374_sectionHF
)
110 loadAndReload("tdf121374_sectionHF.odt");
111 uno::Reference
<beans::XPropertySet
> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY
);
112 uno::Reference
<text::XTextRange
> xFooterText
= getProperty
< uno::Reference
<text::XTextRange
> >(xPageStyle
, "FooterText");
113 CPPUNIT_ASSERT_EQUAL( OUString("footer"), xFooterText
->getString() );
115 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Paragraphs", 6, getParagraphs() );
116 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Pages", 6, getPages() );
119 CPPUNIT_TEST_FIXTURE(Test
, testTdf121374_sectionHF2
)
121 loadAndReload("tdf121374_sectionHF2.doc");
122 uno::Reference
<beans::XPropertySet
> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY
);
123 uno::Reference
<text::XTextRange
> xHeaderText
= getProperty
< uno::Reference
<text::XTextRange
> >(xPageStyle
, "HeaderText");
124 CPPUNIT_ASSERT( xHeaderText
->getString().startsWith("virkamatka-anomus") );
127 CPPUNIT_TEST_FIXTURE(Test
, testTdf121666_lostPage
)
129 loadAndSave("tdf121666_lostPage.docx");
130 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
131 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:r[2]/w:br", "type", "page");
132 // The second page break is exported too.
133 // Before this fix, if a node had both section break and page break, then only the section break was exported.
134 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[2]/w:r[2]/w:br", "type", "page");
135 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[2]/w:pPr/w:sectPr/w:type", "val", "nextPage");
138 DECLARE_OOXMLEXPORT_TEST(testTdf140182_extraPagebreak
, "tdf140182_extraPagebreak.docx")
140 // Table, page break, section break should be only 2 pages
141 // 2 breaks would normally results in 3 pages, but page break + section break is a special case
142 // that is handled so to break only 1 page that result only 2 pages.
143 // Because of the table, a hack (m_bDummyParaAddedForTableInSection) is set for the entire section,
144 // that canceled the page break + section break special case handling, resulting 3 pages.
145 // The accompanying fix eliminates this cancellation.
146 CPPUNIT_ASSERT_EQUAL(2, getPages());
149 CPPUNIT_TEST_FIXTURE(Test
, testTdf121659_loseColumnBrNextToShape
)
151 loadAndSave("tdf121659_loseColumnBrNextToShape.docx");
152 // The third paragraph contains a manual column break and a shape.
153 // The column break was moved into the shape during the first import
154 // (messing also the shape position), and eliminated during the second import,
155 // losing the 2-column text layout. As a workaround, split the paragraph
156 // moving the column break into the fourth paragraph instead of losing it.
157 saveAndReload("Office Open XML Text");
158 bool bBreakOnPara3
= getProperty
<style::BreakType
>(getParagraph(3), "BreakType") == style::BreakType_COLUMN_BEFORE
;
159 bool bBreakOnPara4
= getProperty
<style::BreakType
>(getParagraph(4), "BreakType") == style::BreakType_COLUMN_BEFORE
;
160 CPPUNIT_ASSERT(bBreakOnPara3
|| bBreakOnPara4
);
163 DECLARE_OOXMLEXPORT_TEST(testTdf95848
, "tdf95848.docx")
168 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(1), uno::UNO_QUERY
);
169 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16
>(2), getProperty
<sal_Int16
>(xPara
, "NumberingLevel"));
170 CPPUNIT_ASSERT(xPara
->getPropertyValue("NumberingStyleName") >>= listStyle
);
171 CPPUNIT_ASSERT(listStyle
.startsWith("WWNum"));
172 CPPUNIT_ASSERT(xPara
->getPropertyValue("ListId") >>= listId
);
173 CPPUNIT_ASSERT_EQUAL(OUString("1.1.1"), getProperty
<OUString
>(xPara
, "ListLabelString"));
176 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(2), uno::UNO_QUERY
);
177 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16
>(2), getProperty
<sal_Int16
>(xPara
, "NumberingLevel"));
178 CPPUNIT_ASSERT_EQUAL(listStyle
, getProperty
<OUString
>(xPara
, "NumberingStyleName"));
179 CPPUNIT_ASSERT_EQUAL(listId
, getProperty
<OUString
>(xPara
, "ListId"));
180 CPPUNIT_ASSERT_EQUAL(OUString("1.1.2"), getProperty
<OUString
>(xPara
, "ListLabelString"));
183 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(3), uno::UNO_QUERY
);
184 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16
>(2), getProperty
<sal_Int16
>(xPara
, "NumberingLevel"));
185 // different numbering style
187 CPPUNIT_ASSERT(xPara
->getPropertyValue("NumberingStyleName") >>= listStyle3
);
188 CPPUNIT_ASSERT(listStyle3
.startsWith("WWNum"));
189 CPPUNIT_ASSERT(listStyle3
!= listStyle
);
191 CPPUNIT_ASSERT_EQUAL(OUString("1.1.3"), getProperty
<OUString
>(xPara
, "ListLabelString"));
192 CPPUNIT_ASSERT_EQUAL(listId
, getProperty
<OUString
>(xPara
, "ListId"));
196 DECLARE_OOXMLEXPORT_TEST(testTdf95848_2
, "tdf95848_2.docx")
201 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(1), uno::UNO_QUERY
);
202 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16
>(0), getProperty
<sal_Int16
>(xPara
, "NumberingLevel"));
203 CPPUNIT_ASSERT(xPara
->getPropertyValue("NumberingStyleName") >>= listStyle
);
204 CPPUNIT_ASSERT(listStyle
.startsWith("WWNum"));
205 CPPUNIT_ASSERT(xPara
->getPropertyValue("ListId") >>= listId
);
206 CPPUNIT_ASSERT_EQUAL(OUString("1)"), getProperty
<OUString
>(xPara
, "ListLabelString"));
207 // check indent of list style
208 auto xLevels
= getProperty
<uno::Reference
<container::XIndexAccess
>>(xPara
, "NumberingRules");
209 uno::Sequence
<beans::PropertyValue
> aLevel
;
210 xLevels
->getByIndex(0) >>= aLevel
; // top level
211 sal_Int32 nIndent
= std::find_if(std::cbegin(aLevel
), std::cend(aLevel
), [](const beans::PropertyValue
& rValue
) { return rValue
.Name
== "FirstLineIndent"; })->Value
.get
<sal_Int32
>();
212 CPPUNIT_ASSERT_EQUAL(sal_Int32(-635), nIndent
);
215 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(2), uno::UNO_QUERY
);
216 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16
>(0), getProperty
<sal_Int16
>(xPara
, "NumberingLevel"));
217 // different numbering style
219 CPPUNIT_ASSERT(xPara
->getPropertyValue("NumberingStyleName") >>= listStyle2
);
220 CPPUNIT_ASSERT(listStyle2
.startsWith("WWNum"));
221 CPPUNIT_ASSERT(listStyle2
!= listStyle
);
223 CPPUNIT_ASSERT_EQUAL(OUString("2)"), getProperty
<OUString
>(xPara
, "ListLabelString"));
224 CPPUNIT_ASSERT_EQUAL(listId
, getProperty
<OUString
>(xPara
, "ListId"));
225 // check indent of list style - override
226 auto xLevels
= getProperty
<uno::Reference
<container::XIndexAccess
>>(xPara
, "NumberingRules");
227 uno::Sequence
<beans::PropertyValue
> aLevel
;
228 xLevels
->getByIndex(0) >>= aLevel
; // top level
229 sal_Int32 nIndent
= std::find_if(std::cbegin(aLevel
), std::cend(aLevel
), [](const beans::PropertyValue
& rValue
) { return rValue
.Name
== "FirstLineIndent"; })->Value
.get
<sal_Int32
>();
230 CPPUNIT_ASSERT_EQUAL(sal_Int32(9366), nIndent
);
233 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(3), uno::UNO_QUERY
);
234 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16
>(0), getProperty
<sal_Int16
>(xPara
, "NumberingLevel"));
235 // different numbering style
237 CPPUNIT_ASSERT(xPara
->getPropertyValue("NumberingStyleName") >>= listStyle3
);
238 CPPUNIT_ASSERT(listStyle3
.startsWith("WWNum"));
239 CPPUNIT_ASSERT(listStyle3
!= listStyle
);
240 // and different list
241 CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty
<OUString
>(xPara
, "ListLabelString"));
242 CPPUNIT_ASSERT(listId
!= getProperty
<OUString
>(xPara
, "ListId"));
245 // continue the first list
246 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(4), uno::UNO_QUERY
);
247 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16
>(0), getProperty
<sal_Int16
>(xPara
, "NumberingLevel"));
248 CPPUNIT_ASSERT_EQUAL(listStyle
, getProperty
<OUString
>(xPara
, "NumberingStyleName"));
249 CPPUNIT_ASSERT_EQUAL(listId
, getProperty
<OUString
>(xPara
, "ListId"));
250 CPPUNIT_ASSERT_EQUAL(OUString("3)"), getProperty
<OUString
>(xPara
, "ListLabelString"));
253 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(5), uno::UNO_QUERY
);
254 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16
>(0), getProperty
<sal_Int16
>(xPara
, "NumberingLevel"));
255 CPPUNIT_ASSERT_EQUAL(listStyle
, getProperty
<OUString
>(xPara
, "NumberingStyleName"));
256 CPPUNIT_ASSERT_EQUAL(listId
, getProperty
<OUString
>(xPara
, "ListId"));
257 CPPUNIT_ASSERT_EQUAL(OUString("4)"), getProperty
<OUString
>(xPara
, "ListLabelString"));
261 DECLARE_OOXMLEXPORT_TEST(testTdf108496
, "tdf108496.docx")
265 // Lists with override
267 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(2), uno::UNO_QUERY
);
268 CPPUNIT_ASSERT(xPara
->getPropertyValue("NumberingStyleName") >>= listStyle
);
269 CPPUNIT_ASSERT(listStyle
.startsWith("WWNum"));
270 CPPUNIT_ASSERT(xPara
->getPropertyValue("ListId") >>= listId
);
271 CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty
<OUString
>(xPara
, "ListLabelString"));
274 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(3), uno::UNO_QUERY
);
275 CPPUNIT_ASSERT_EQUAL(listStyle
, getProperty
<OUString
>(xPara
, "NumberingStyleName"));
276 CPPUNIT_ASSERT_EQUAL(listId
, getProperty
<OUString
>(xPara
, "ListId"));
277 CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty
<OUString
>(xPara
, "ListLabelString"));
280 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(5), uno::UNO_QUERY
);
281 // different numbering style
283 CPPUNIT_ASSERT(xPara
->getPropertyValue("NumberingStyleName") >>= listStyle2
);
284 CPPUNIT_ASSERT(listStyle2
.startsWith("WWNum"));
285 CPPUNIT_ASSERT(listStyle2
!= listStyle
);
286 // restarted numeration due to override
287 CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty
<OUString
>(xPara
, "ListLabelString"));
288 CPPUNIT_ASSERT_EQUAL(listId
, getProperty
<OUString
>(xPara
, "ListId"));
291 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(6), uno::UNO_QUERY
);
292 // different numbering style
294 CPPUNIT_ASSERT(xPara
->getPropertyValue("NumberingStyleName") >>= listStyle2
);
295 CPPUNIT_ASSERT(listStyle2
.startsWith("WWNum"));
296 // restarted numeration due to override
297 CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty
<OUString
>(xPara
, "ListLabelString"));
298 CPPUNIT_ASSERT_EQUAL(listId
, getProperty
<OUString
>(xPara
, "ListId"));
301 // Lists without override
303 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(8), uno::UNO_QUERY
);
304 CPPUNIT_ASSERT(xPara
->getPropertyValue("NumberingStyleName") >>= listStyle
);
305 CPPUNIT_ASSERT(listStyle
.startsWith("WWNum"));
306 CPPUNIT_ASSERT(xPara
->getPropertyValue("ListId") >>= listId
);
307 CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty
<OUString
>(xPara
, "ListLabelString"));
310 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(9), uno::UNO_QUERY
);
311 CPPUNIT_ASSERT_EQUAL(listStyle
, getProperty
<OUString
>(xPara
, "NumberingStyleName"));
312 CPPUNIT_ASSERT_EQUAL(listId
, getProperty
<OUString
>(xPara
, "ListId"));
313 CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty
<OUString
>(xPara
, "ListLabelString"));
316 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(11), uno::UNO_QUERY
);
317 // different numbering style
319 CPPUNIT_ASSERT(xPara
->getPropertyValue("NumberingStyleName") >>= listStyle2
);
320 CPPUNIT_ASSERT(listStyle2
.startsWith("WWNum"));
321 CPPUNIT_ASSERT(listStyle2
!= listStyle
);
322 // numeration is continued
323 CPPUNIT_ASSERT_EQUAL(OUString("3"), getProperty
<OUString
>(xPara
, "ListLabelString"));
324 CPPUNIT_ASSERT_EQUAL(listId
, getProperty
<OUString
>(xPara
, "ListId"));
327 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(12), uno::UNO_QUERY
);
328 // different numbering style
330 CPPUNIT_ASSERT(xPara
->getPropertyValue("NumberingStyleName") >>= listStyle2
);
331 CPPUNIT_ASSERT(listStyle2
.startsWith("WWNum"));
332 // numeration is continued
333 CPPUNIT_ASSERT_EQUAL(OUString("4"), getProperty
<OUString
>(xPara
, "ListLabelString"));
334 CPPUNIT_ASSERT_EQUAL(listId
, getProperty
<OUString
>(xPara
, "ListId"));
338 DECLARE_OOXMLEXPORT_TEST(testTdf126723
, "tdf126723.docx")
340 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0), getProperty
<sal_Int32
>(getParagraph(2), "ParaLeftMargin"));
343 DECLARE_OOXMLEXPORT_TEST(testendingSectionProps
, "endingSectionProps.docx")
345 uno::Reference
<beans::XPropertySet
> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY
);
346 uno::Reference
<text::XTextRange
> xHeaderText
= getProperty
< uno::Reference
<text::XTextRange
> >(xPageStyle
, "HeaderText");
347 CPPUNIT_ASSERT_EQUAL( OUString("General header"), xHeaderText
->getString());
349 uno::Reference
<text::XTextSectionsSupplier
> xTextSectionsSupplier(mxComponent
, uno::UNO_QUERY
);
350 uno::Reference
<container::XIndexAccess
> xSections(xTextSectionsSupplier
->getTextSections(), uno::UNO_QUERY
);
351 uno::Reference
<beans::XPropertySet
> xSect(xSections
->getByIndex(0), uno::UNO_QUERY
);
353 CPPUNIT_ASSERT_EQUAL_MESSAGE("# of paragraphs", 2, getParagraphs());
354 CPPUNIT_ASSERT_EQUAL_MESSAGE("Section is RightToLeft", text::WritingMode2::RL_TB
, getProperty
<sal_Int16
>(xSect
, "WritingMode"));
355 //regression: tdf124637
356 //CPPUNIT_ASSERT_EQUAL_MESSAGE("Section Left Margin", sal_Int32(2540), getProperty<sal_Int32>(xSect, "SectionLeftMargin"));
359 DECLARE_OOXMLEXPORT_TEST(testTbrlTextbox
, "tbrl-textbox.docx")
361 uno::Reference
<beans::XPropertySet
> xPropertySet(getShape(1), uno::UNO_QUERY
);
362 // Without the accompanying fix in place, this test would have failed with 'Expected: -90;
363 // Actual: 0', i.e. tbRl writing direction was imported as lrTb.
364 // Note: Implementation was changed to use WritingMode property instead of TextPreRotateAngle.
365 CPPUNIT_ASSERT_EQUAL(text::WritingMode2::TB_RL90
,
366 getProperty
<sal_Int16
>(xPropertySet
, "WritingMode"));
369 DECLARE_OOXMLEXPORT_TEST(testBtlrShape
, "btlr-textbox.docx")
371 SwXTextDocument
* pTextDoc
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
372 CPPUNIT_ASSERT(pTextDoc
);
373 SwDoc
* pDoc
= pTextDoc
->GetDocShell()->GetDoc();
374 const auto& rFormats
= *pDoc
->GetSpzFrameFormats();
375 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rFormats
.size());
376 CPPUNIT_ASSERT_EQUAL(o3tl::narrowing
<sal_uInt16
>(RES_DRAWFRMFMT
), rFormats
[0]->Which());
377 CPPUNIT_ASSERT_EQUAL(o3tl::narrowing
<sal_uInt16
>(RES_FLYFRMFMT
), rFormats
[1]->Which());
378 // Without the accompanying fix in place, this test would have failed with 'Expected: 5, Actual:
379 // 4', i.e. the textbox inherited its writing direction instead of having an explicit btlr
381 CPPUNIT_ASSERT_EQUAL(SvxFrameDirection::Vertical_LR_BT
,
382 rFormats
[1]->GetAttrSet().GetFrameDir().GetValue());
385 CPPUNIT_TEST_FIXTURE(Test
, testTdf127316_autoEscapement
)
387 loadAndReload("tdf127316_autoEscapement.odt");
388 CPPUNIT_ASSERT_EQUAL(1, getPages());
389 // This should be roughly .8*35% of the ORIGINAL(non-reduced) size. However, during export the
390 // proportional height has to be changed into direct formatting, which then changes the relative percent.
391 // In this case, a 24pt font, proportional at 65% becomes roughly a 16pt font.
392 // Thus an escapement of 28% (6.72pt) becomes roughly 42% for the 16pt font.
393 uno::Reference
<text::XTextRange
> xPara
= getParagraph(1);
394 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f
, getProperty
<float>(getRun(xPara
, 1), "CharEscapement"), 0);
395 CPPUNIT_ASSERT_DOUBLES_EQUAL(42.f
, getProperty
<float>(getRun(xPara
, 2), "CharEscapement"), 1);
397 // Subscripts are different. Automatic escapement SHOULD BE limited by the font bottom line(?)
398 // and so the calculations ought to be different. There is room for a lot of export improvement here.
399 xPara
.set(getParagraph(2));
400 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f
, getProperty
<float>(getRun(xPara
, 1, "Normal text "), "CharEscapement"), 0);
401 // Negative escapements (subscripts) were decreasing by 1% every round-trip due to bad manual rounding.
402 // This should be roughly .2*35% of the ORIGINAL (non-reduced) size. However, during export the
403 // proportional height has to be changed into direct formatting, which then changes the relative percent.
404 // In this case, a 24pt font, proportional at 65% becomes roughly a 16pt font.
405 // Thus an escapement of 7% (1.68pt) becomes roughly 10.5% for the 16pt font.
406 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Subscript", -10.f
, getProperty
<float>(getRun(xPara
, 2), "CharEscapement"), 1);
409 DECLARE_OOXMLEXPORT_TEST(testTdf99602_subscript_charStyleSize
, "tdf99602_subscript_charStyleSize.docx")
411 uno::Reference
<text::XTextRange
> xPara
= getParagraph(1);
412 // The word "Base" should not be subscripted.
413 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f
, getProperty
<float>(getRun(xPara
, 1, "Base"), "CharEscapement"), 0);
414 // The word "Subscript" should be 48pt, subscripted by 25% (12pt).
415 CPPUNIT_ASSERT_DOUBLES_EQUAL( -25.f
, getProperty
<float>(getRun(xPara
, 2, "Subscript"), "CharEscapement"), 0);
418 DECLARE_OOXMLEXPORT_TEST(testTdf99602_charStyleSubscript
, "tdf99602_charStyleSubscript.docx")
420 uno::Reference
<text::XTextRange
> xPara
= getParagraph(1);
421 // The word "Base" should not be subscripted.
422 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f
, getProperty
<float>(getRun(xPara
, 1, "Base"), "CharEscapement"), 0);
423 // The word "Subscript" should be 48pt, automatically subscripted, and automatic proportioned.
424 CPPUNIT_ASSERT_EQUAL( sal_Int16(DFLT_ESC_AUTO_SUB
), getProperty
<sal_Int16
>(getRun(xPara
, 2, "Subscript"), "CharEscapement") );
425 CPPUNIT_ASSERT_EQUAL( sal_Int16(DFLT_ESC_PROP
), getProperty
<sal_Int16
>(getRun(xPara
, 2), "CharEscapementHeight") );
428 CPPUNIT_TEST_FIXTURE(Test
, testTdf99602_charStyleSubscript2
)
430 loadAndReload("tdf99602_charStyleSubscript2.odt");
431 CPPUNIT_ASSERT_EQUAL(1, getPages());
432 // *_In styles_*, don't let the proportionality/escapement affect the fontsize - otherwise it starts doubling up,
433 // so instead just throw away the values and use the default settings instead - meaning fontsize is unaffected.
434 // subscript custom: Proportional size is 80%, lower by 25%.
435 uno::Reference
<beans::XPropertySet
> xStyle(getStyles("CharacterStyles")->getByName("subscript custom"), uno::UNO_QUERY
);
436 CPPUNIT_ASSERT_EQUAL_MESSAGE("CharStyle has 12pt font size", 12.f
, getProperty
<float>(xStyle
, "CharHeight"));
437 // subscript larger font: Proportional size is 80%, lowered by DFLT_ESC_AUTO_SUB
438 xStyle
.set(getStyles("CharacterStyles")->getByName("subscript larger font"), uno::UNO_QUERY
);
439 CPPUNIT_ASSERT_EQUAL_MESSAGE("Auto CharStyle has 12pt font size", 12.f
, getProperty
<float>(xStyle
, "CharHeight"));
442 DECLARE_OOXMLEXPORT_TEST(testTdf124637_sectionMargin
, "tdf124637_sectionMargin.docx")
444 uno::Reference
<text::XTextSectionsSupplier
> xTextSectionsSupplier(mxComponent
, uno::UNO_QUERY
);
445 uno::Reference
<container::XIndexAccess
> xSections(xTextSectionsSupplier
->getTextSections(), uno::UNO_QUERY
);
446 // sections 0 and 1 must be related to footnotes...
447 uno::Reference
<beans::XPropertySet
> xSect(xSections
->getByIndex(2), uno::UNO_QUERY
);
449 CPPUNIT_ASSERT_EQUAL_MESSAGE("Section Left Margin", sal_Int32(0), getProperty
<sal_Int32
>(xSect
, "SectionLeftMargin"));
452 DECLARE_OOXMLEXPORT_TEST(testTdf123636_newlinePageBreak
, "tdf123636_newlinePageBreak.docx")
454 //MS Compatibility flag: SplitPgBreakAndParaMark
455 //special case: split first empty paragraph in a section.
456 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Paragraphs", 2, getParagraphs() );
457 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Pages", 2, getPages() );
460 DECLARE_OOXMLEXPORT_TEST(testTdf123636_newlinePageBreak2
, "tdf123636_newlinePageBreak2.docx")
462 //WITHOUT SplitPgBreakAndParaMark: a following anchored shape should force a page break
463 //CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Paragraphs", 2, getParagraphs() );
464 CPPUNIT_ASSERT_EQUAL(OUString(), getProperty
<OUString
>(getParagraph(2, ""), "NumberingStyleName"));
465 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Pages", 2, getPages() );
468 DECLARE_OOXMLEXPORT_TEST(testTdf123636_newlinePageBreak3
, "tdf123636_newlinePageBreak3.docx")
470 //MS Compatibility flag: SplitPgBreakAndParaMark
471 //proof case: split any non-empty paragraphs, not just the first paragraph of a section.
472 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Paragraphs", 5, getParagraphs() );
473 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Pages", 2, getPages() );
475 xmlDocUniquePtr pDump
= parseLayoutDump();
476 assertXPath(pDump
, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwParaPortion[1]", "portion", "Last line on page 1");
479 DECLARE_OOXMLEXPORT_TEST(testTdf123636_newlinePageBreak4
, "tdf123636_newlinePageBreak4.docx")
481 //MS Compatibility flag: SplitPgBreakAndParaMark
482 //special case: an empty paragraph doesn't split (except if first paragraph).
483 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Paragraphs", 3, getParagraphs() );
484 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Pages", 2, getPages() );
486 xmlDocUniquePtr pDump
= parseLayoutDump();
487 assertXPath(pDump
, "/root/page[2]/body/txt[1]/SwParaPortion", 0);
490 DECLARE_OOXMLEXPORT_TEST(testTdf118947_tableStyle
, "tdf118947_tableStyle.docx")
492 uno::Reference
<text::XTextTable
> xTable(getParagraphOrTable(1), uno::UNO_QUERY
);
493 uno::Reference
<text::XTextRange
> xCell(xTable
->getCellByName("A1"), uno::UNO_QUERY
);
494 uno::Reference
<container::XEnumerationAccess
> xParaEnumAccess(xCell
->getText(), uno::UNO_QUERY
);
495 uno::Reference
<container::XEnumeration
> xParaEnum
= xParaEnumAccess
->createEnumeration();
496 uno::Reference
<text::XTextRange
> xPara(xParaEnum
->nextElement(), uno::UNO_QUERY
);
497 CPPUNIT_ASSERT_EQUAL(OUString("Table grid settings set line-spacing to 250% instead of single-spacing, which is set as a document default."), xPara
->getString());
498 CPPUNIT_ASSERT_EQUAL_MESSAGE("TextBody has 10pt font size", 11.f
, getProperty
<float>(xPara
, "CharHeight"));
499 CPPUNIT_ASSERT_EQUAL_MESSAGE("TextBody has 1pt space below paragraph", sal_Int32(35), getProperty
<sal_Int32
>(xPara
, "ParaBottomMargin"));
500 CPPUNIT_ASSERT_EQUAL_MESSAGE("Table has 10pt space above paragraph", sal_Int32(353), getProperty
<sal_Int32
>(xPara
, "ParaTopMargin"));
501 CPPUNIT_ASSERT_EQUAL_MESSAGE("Table style sets 0 right margin", sal_Int32(0), getProperty
<sal_Int32
>(xPara
, "ParaRightMargin"));
502 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("TextBody has 1.07 line-spacing", sal_Int16(107), getProperty
<style::LineSpacing
>(xPara
, "ParaLineSpacing").Height
, 1);
503 // table-style based paragraph background color
504 CPPUNIT_ASSERT_EQUAL_MESSAGE("Missing paragraph background color in cell A1", Color(0xCCFFCC), getProperty
<Color
>(xPara
, "ParaBackColor"));
506 // This cell is affected by compatSetting overrideTableStyleFontSizeAndJustification=0 (the default value)
507 xCell
.set(xTable
->getCellByName("A2"), uno::UNO_QUERY
);
508 xParaEnumAccess
.set(xCell
->getText(), uno::UNO_QUERY
);
509 xParaEnum
= xParaEnumAccess
->createEnumeration();
510 xPara
.set(xParaEnum
->nextElement(), uno::UNO_QUERY
);
511 CPPUNIT_ASSERT_EQUAL(OUString("Notice that this is 8pt font, right aligned in compatibility mode."), xPara
->getString());
512 // Even though not specified, Table-Style distributes the properties in DocDefault. DocDefault fontsize is 8pt.
513 CPPUNIT_ASSERT_EQUAL_MESSAGE("Compat mode has 8pt font size", 8.f
, getProperty
<float>(getRun(xPara
,1), "CharHeight"));
514 CPPUNIT_ASSERT_EQUAL_MESSAGE("Normal has 0pt space below paragraph", sal_Int32(0), getProperty
<sal_Int32
>(xPara
, "ParaBottomMargin"));
515 CPPUNIT_ASSERT_EQUAL_MESSAGE("Table sets 10pt space above paragraph", sal_Int32(353), getProperty
<sal_Int32
>(xPara
, "ParaTopMargin"));
516 CPPUNIT_ASSERT_EQUAL_MESSAGE("Table style sets 0 right margin", sal_Int32(0), getProperty
<sal_Int32
>(xPara
, "ParaRightMargin"));
517 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table sets 2.5 line-spacing", sal_Int16(250), getProperty
<style::LineSpacing
>(xPara
, "ParaLineSpacing").Height
, 1);
518 CPPUNIT_ASSERT_EQUAL_MESSAGE("Paragraph background color in cell A2", sal_Int32(-1), getProperty
<sal_Int32
>(xPara
, "ParaBackColor"));
519 CPPUNIT_ASSERT_EQUAL_MESSAGE("Compat mode overrides left adjust", style::ParagraphAdjust_RIGHT
,
520 static_cast<style::ParagraphAdjust
>(getProperty
<sal_Int16
>(xPara
, "ParaAdjust")));
523 DECLARE_OOXMLEXPORT_TEST(testTdf118947_tableStyle2
, "tdf118947_tableStyle2.docx")
525 uno::Reference
<text::XTextTable
> xTable(getParagraphOrTable(1), uno::UNO_QUERY
);
526 // This cell is affected by compatSetting overrideTableStyleFontSizeAndJustification=1 (no goofy exception)
527 uno::Reference
<text::XTextRange
> xCell(xTable
->getCellByName("A2"), uno::UNO_QUERY
);
528 uno::Reference
<container::XEnumerationAccess
> xParaEnumAccess(xCell
->getText(), uno::UNO_QUERY
);
529 uno::Reference
<container::XEnumeration
> xParaEnum
= xParaEnumAccess
->createEnumeration();
530 uno::Reference
<text::XTextRange
> xPara(xParaEnum
->nextElement(), uno::UNO_QUERY
);
532 CPPUNIT_ASSERT_EQUAL(OUString("Notice that this is 12pt font, left aligned in non-compatibility mode."), xPara
->getString());
533 // Even though not specified, Table-Style tries to distribute the properties in DocDefault. DocDefault fontsize is 8pt.
534 // However, this is overridden by the default style's specified fontsize of 12 and left justify.
535 CPPUNIT_ASSERT_EQUAL_MESSAGE("Non-Compat mode has 12pt font size", 12.f
, getProperty
<float>(getRun(xPara
,1), "CharHeight"));
536 CPPUNIT_ASSERT_EQUAL_MESSAGE("Non-Compat mode keeps the style's left adjust", style::ParagraphAdjust_LEFT
,
537 static_cast<style::ParagraphAdjust
>(getProperty
<sal_Int16
>(xPara
, "ParaAdjust")));
540 CPPUNIT_TEST_FIXTURE(Test
, tdf123912_protectedForm
)
542 loadAndReload("tdf123912_protectedForm.odt");
543 CPPUNIT_ASSERT_EQUAL(1, getPages());
544 SwXTextDocument
* pTextDoc
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
545 CPPUNIT_ASSERT(pTextDoc
);
546 SwDoc
* pDoc
= pTextDoc
->GetDocShell()->GetDoc();
547 CPPUNIT_ASSERT_EQUAL_MESSAGE("Compatibility: Protect form", true,
548 pDoc
->getIDocumentSettingAccess().get( DocumentSettingId::PROTECT_FORM
) );
550 uno::Reference
<text::XTextSectionsSupplier
> xTextSectionsSupplier(mxComponent
, uno::UNO_QUERY
);
551 uno::Reference
<container::XIndexAccess
> xSections(xTextSectionsSupplier
->getTextSections(), uno::UNO_QUERY
);
552 uno::Reference
<beans::XPropertySet
> xSect(xSections
->getByIndex(0), uno::UNO_QUERY
);
554 CPPUNIT_ASSERT_EQUAL_MESSAGE("Section1 is protected", false, getProperty
<bool>(xSect
, "IsProtected"));
557 DECLARE_OOXMLEXPORT_TEST(tdf124600b
, "tdf124600b.docx")
559 // <wp:anchor allowOverlap="0"> was lost on roundtrip, we always wrote "1" on export.
560 bool bAllowOverlap1
= getProperty
<bool>(getShape(1), "AllowOverlap");
561 CPPUNIT_ASSERT(!bAllowOverlap1
);
562 bool bAllowOverlap2
= getProperty
<bool>(getShape(2), "AllowOverlap");
563 CPPUNIT_ASSERT(!bAllowOverlap2
);
566 CPPUNIT_TEST_FIXTURE(Test
, testDateControl
)
568 loadAndReload("empty-date-control.odt");
569 CPPUNIT_ASSERT_EQUAL(1, getPages());
570 // Check that we exported the empty date control correctly
571 // Date form field is converted to date content control.
573 uno::Reference
<beans::XPropertySet
> xTextPortion(getRun(getParagraph(1), 1), uno::UNO_QUERY
);
574 OUString aPortionType
;
575 xTextPortion
->getPropertyValue("TextPortionType") >>= aPortionType
;
576 CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType
);
577 uno::Reference
<text::XTextContent
> xContentControl
;
578 xTextPortion
->getPropertyValue("ContentControl") >>= xContentControl
;
579 uno::Reference
<beans::XPropertySet
> xContentControlProps(xContentControl
, uno::UNO_QUERY
);
581 xContentControlProps
->getPropertyValue("Date") >>= bDate
;
582 CPPUNIT_ASSERT(bDate
);
584 OUString sDateFormat
;
585 xContentControlProps
->getPropertyValue("DateFormat") >>= sDateFormat
;
588 xContentControlProps
->getPropertyValue("DateLanguage") >>= sLang
;
590 OUString sCurrentDate
;
591 xContentControlProps
->getPropertyValue("CurrentDate") >>= sCurrentDate
;
593 CPPUNIT_ASSERT_EQUAL(OUString("dd/MM/yyyy"), sDateFormat
);
594 CPPUNIT_ASSERT_EQUAL(OUString("en-US"), sLang
);
595 CPPUNIT_ASSERT_EQUAL(OUString(""), sCurrentDate
);
598 CPPUNIT_TEST_FIXTURE(Test
, testTdf121867
)
600 loadAndReload("tdf121867.odt");
601 CPPUNIT_ASSERT_EQUAL(1, getPages());
602 SwXTextDocument
* pTextDoc
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
603 SwEditShell
* pEditShell
= pTextDoc
->GetDocShell()->GetEditShell();
604 // Without the accompanying fix in place, this test would have failed with
605 // 'Expected: 3; Actual : 0', i.e. page width zoom was lost on export.
606 CPPUNIT_ASSERT_EQUAL(SvxZoomType::PAGEWIDTH
, pEditShell
->GetViewOptions()->GetZoomType());
609 DECLARE_OOXMLEXPORT_TEST(testParaAdjustDistribute
, "para-adjust-distribute.docx")
611 // Without the accompanying fix in place, this test would have failed with
612 // 'Expected: 2; Actual : 0', i.e. the first paragraph's ParaAdjust was
614 CPPUNIT_ASSERT_EQUAL(
615 style::ParagraphAdjust_BLOCK
,
616 static_cast<style::ParagraphAdjust
>(getProperty
<sal_Int16
>(getParagraph(1), "ParaAdjust")));
617 CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_BLOCK
,
618 static_cast<style::ParagraphAdjust
>(
619 getProperty
<sal_Int16
>(getParagraph(1), "ParaLastLineAdjust")));
621 CPPUNIT_ASSERT_EQUAL(
622 style::ParagraphAdjust_BLOCK
,
623 static_cast<style::ParagraphAdjust
>(getProperty
<sal_Int16
>(getParagraph(2), "ParaAdjust")));
624 CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_LEFT
,
625 static_cast<style::ParagraphAdjust
>(
626 getProperty
<sal_Int16
>(getParagraph(2), "ParaLastLineAdjust")));
629 CPPUNIT_TEST_FIXTURE(Test
, testInputListExport
)
631 loadAndReload("tdf122186_input_list.odt");
632 if (!isExported()) // importing the ODT, an input field
634 uno::Reference
<text::XTextFieldsSupplier
> xTextFieldsSupplier(mxComponent
, uno::UNO_QUERY
);
635 uno::Reference
<container::XEnumerationAccess
> xFieldsAccess(xTextFieldsSupplier
->getTextFields());
636 uno::Reference
<container::XEnumeration
> xFields(xFieldsAccess
->createEnumeration());
637 CPPUNIT_ASSERT(xFields
->hasMoreElements());
638 uno::Any aField
= xFields
->nextElement();
639 uno::Reference
<lang::XServiceInfo
> xServiceInfo(aField
, uno::UNO_QUERY
);
640 CPPUNIT_ASSERT(xServiceInfo
->supportsService("com.sun.star.text.textfield.DropDown"));
642 else // importing the DOCX, a content control
644 uno::Reference
<beans::XPropertySet
> xTextPortion(getRun(getParagraph(1), 1), uno::UNO_QUERY
);
645 OUString aPortionType
;
646 xTextPortion
->getPropertyValue("TextPortionType") >>= aPortionType
;
647 CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType
);
648 uno::Reference
<text::XTextContent
> xContentControl
;
649 xTextPortion
->getPropertyValue("ContentControl") >>= xContentControl
;
650 uno::Reference
<beans::XPropertySet
> xContentControlProps(xContentControl
, uno::UNO_QUERY
);
651 uno::Sequence
<beans::PropertyValues
> aListItems
;
652 xContentControlProps
->getPropertyValue("ListItems") >>= aListItems
;
653 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(3), aListItems
.getLength());
654 comphelper::SequenceAsHashMap
aMap0(aListItems
[0]);
655 CPPUNIT_ASSERT_EQUAL(OUString("1"), aMap0
["Value"].get
<OUString
>());
656 comphelper::SequenceAsHashMap
aMap1(aListItems
[1]);
657 CPPUNIT_ASSERT_EQUAL(OUString("2"), aMap1
["Value"].get
<OUString
>());
658 comphelper::SequenceAsHashMap
aMap2(aListItems
[2]);
659 CPPUNIT_ASSERT_EQUAL(OUString("3"), aMap2
["Value"].get
<OUString
>());
660 uno::Reference
<container::XEnumerationAccess
> xContentEnumAccess(xContentControl
, uno::UNO_QUERY
);
661 uno::Reference
<container::XEnumeration
> xContentEnum
= xContentEnumAccess
->createEnumeration();
662 uno::Reference
<text::XTextRange
> xContent(xContentEnum
->nextElement(), uno::UNO_QUERY
);
663 CPPUNIT_ASSERT_EQUAL(OUString("1"), xContent
->getString());
667 DECLARE_OOXMLEXPORT_TEST(testTdf123435
, "tdf123435.docx")
669 CPPUNIT_ASSERT_EQUAL(1, getPages());
671 // Without the fix in place, it would have failed with
674 CPPUNIT_ASSERT_EQUAL(2, getShapes());
677 CPPUNIT_TEST_FIXTURE(Test
, testTdf116371
)
679 loadAndReload("tdf116371.odt");
680 CPPUNIT_ASSERT_EQUAL(1, getShapes());
681 CPPUNIT_ASSERT_EQUAL(1, getPages());
682 // Make sure the rotation is exported correctly, and size not distorted
683 auto xShape(getShape(1));
684 CPPUNIT_ASSERT_DOUBLES_EQUAL(4700.0, getProperty
<double>(xShape
, "RotateAngle"), 10);
685 auto frameRect
= getProperty
<awt::Rectangle
>(xShape
, "FrameRect");
686 CPPUNIT_ASSERT_EQUAL(sal_Int32(24063), frameRect
.Height
);
687 CPPUNIT_ASSERT_EQUAL(sal_Int32(24179), frameRect
.Width
);
690 CPPUNIT_TEST_FIXTURE(Test
, testFrameSizeExport
)
692 loadAndSave("floating-tables-anchor.docx");
693 // Make sure the table width is 4000
694 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
695 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl[1]/w:tblPr/w:tblW", "w", "4000");
698 DECLARE_OOXMLEXPORT_TEST(testTdf119201
, "tdf119201.docx")
700 // Visibility of shapes wasn't imported/exported, for now base printable property on that, too
701 auto xShape(getShape(1));
702 CPPUNIT_ASSERT_MESSAGE("First shape should be visible.", getProperty
<bool>(xShape
, "Visible"));
703 CPPUNIT_ASSERT_MESSAGE("First shape should be printable.", getProperty
<bool>(xShape
, "Printable"));
704 xShape
= getShapeByName(u
"Rectangle 1");
705 CPPUNIT_ASSERT_MESSAGE("Second shape should not be visible.", !getProperty
<bool>(xShape
, "Visible"));
706 CPPUNIT_ASSERT_MESSAGE("Second shape should not be printable.", !getProperty
<bool>(xShape
, "Printable"));
707 xShape
= getShapeByName(u
"Oval 2");
708 CPPUNIT_ASSERT_MESSAGE("Third shape should be visible.", getProperty
<bool>(xShape
, "Visible"));
709 CPPUNIT_ASSERT_MESSAGE("Third shape should be printable.", getProperty
<bool>(xShape
, "Printable"));
712 DECLARE_OOXMLEXPORT_TEST(testTdf124594
, "tdf124594.docx")
714 xmlDocUniquePtr pDump
= parseLayoutDump();
715 // Without the accompanying fix in place, this test would have failed, as the portion text was
716 // only "Er horte leise Schritte hinter", which means the 1st line of the 2nd paragraph was
717 // split into two by a Special portion, i.e. the top margin of the shape was too large.
718 assertXPath(pDump
, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout[1]/SwLinePortion[1]", "portion",
719 "Er horte leise Schritte hinter sich. Das bedeutete nichts Gutes. Wer wu"); // ... until the bookmark.
722 CPPUNIT_TEST_FIXTURE(Test
, testTextInput
)
724 loadAndSave("textinput.odt");
725 CPPUNIT_ASSERT_EQUAL(1, getPages());
726 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
729 // test the exported DOCX
732 assertXPathContent(pXmlDoc
, "/w:document/w:body/w:p[1]/w:r[3]/w:instrText", " FILLIN \"\"");
733 assertXPathChildren(pXmlDoc
, "/w:document/w:body/w:p[1]/w:r[5]", 1);
734 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:r[5]/w:rPr", 1);
735 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:r[6]/w:fldChar", "fldCharType", "end");
738 assertXPathContent(pXmlDoc
, "/w:document/w:body/w:p[2]/w:r[3]/w:instrText", " FILLIN \"\"");
739 assertXPathContent(pXmlDoc
, "/w:document/w:body/w:p[2]/w:r[5]/w:t", "content without hint");
740 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[2]/w:r[6]/w:fldChar", "fldCharType", "end");
743 assertXPathContent(pXmlDoc
, "/w:document/w:body/w:p[3]/w:r[3]/w:instrText", " FILLIN \"hint empty\"");
744 assertXPathChildren(pXmlDoc
, "/w:document/w:body/w:p[3]/w:r[5]", 1);
745 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[3]/w:r[5]/w:rPr", 1);
746 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[3]/w:r[6]/w:fldChar", "fldCharType", "end");
749 assertXPathContent(pXmlDoc
, "/w:document/w:body/w:p[4]/w:r[3]/w:instrText", " FILLIN \"hint content\"");
750 assertXPathContent(pXmlDoc
, "/w:document/w:body/w:p[4]/w:r[5]/w:t", "content with hint");
751 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[4]/w:r[6]/w:fldChar", "fldCharType", "end");
753 // test the imported DOCX
754 uno::Reference
<text::XTextFieldsSupplier
> xTextFieldsSupplier(mxComponent
, uno::UNO_QUERY
);
755 uno::Reference
<container::XEnumerationAccess
> xFieldsAccess(xTextFieldsSupplier
->getTextFields());
756 uno::Reference
<container::XEnumeration
> xFields(xFieldsAccess
->createEnumeration());
757 CPPUNIT_ASSERT(xFields
->hasMoreElements());
762 uno::Any aField
= xFields
->nextElement();
763 uno::Reference
<lang::XServiceInfo
> xServiceInfo(aField
, uno::UNO_QUERY
);
764 CPPUNIT_ASSERT(xServiceInfo
->supportsService("com.sun.star.text.textfield.Input"));
765 uno::Reference
<beans::XPropertySet
> xPropertySet(aField
, uno::UNO_QUERY
);
766 uno::Reference
<text::XTextContent
> xText(aField
, uno::UNO_QUERY
);
768 // why is the enumeration not in the same order then the fields in the document?
769 // it seems to be stable and the navigation in the GUI is actually correct.
770 OUString sContent
, sHint
;
774 sContent
= "content with hint";
775 sHint
= "hint content";
778 sHint
= "hint empty";
781 sContent
= "content without hint";
784 CPPUNIT_ASSERT_EQUAL(uno::Any(sContent
), xPropertySet
->getPropertyValue("Content"));
785 CPPUNIT_ASSERT_EQUAL(sContent
, xText
->getAnchor()->getString());
786 CPPUNIT_ASSERT_EQUAL(uno::Any(sHint
), xPropertySet
->getPropertyValue("Hint"));
789 while (xFields
->hasMoreElements());
790 CPPUNIT_ASSERT_EQUAL(4, nElements
);
793 DECLARE_OOXMLEXPORT_TEST(testTdf123460
, "tdf123460.docx")
795 // check paragraph mark deletion at terminating moveFrom
796 CPPUNIT_ASSERT(getParagraph( 2 )->getString().startsWith("Nunc"));
797 uno::Reference
<container::XEnumerationAccess
> xRunEnumAccess(getParagraph( 2 ), uno::UNO_QUERY
);
798 uno::Reference
<container::XEnumeration
> xRunEnum
= xRunEnumAccess
->createEnumeration();
799 uno::Reference
<text::XTextRange
> xRun(xRunEnum
->nextElement(), uno::UNO_QUERY
);
800 CPPUNIT_ASSERT_EQUAL( OUString( "" ), xRun
->getString());
801 xRun
.set(xRunEnum
->nextElement(), uno::UNO_QUERY
);
802 CPPUNIT_ASSERT(hasProperty(xRun
, "RedlineType"));
803 CPPUNIT_ASSERT_EQUAL(OUString("Delete"),getProperty
<OUString
>(xRun
, "RedlineType"));
804 xRun
.set(xRunEnum
->nextElement(), uno::UNO_QUERY
);
805 CPPUNIT_ASSERT(xRun
->getString().endsWith("tellus."));
806 xRun
.set(xRunEnum
->nextElement(), uno::UNO_QUERY
);
807 CPPUNIT_ASSERT(hasProperty(xRun
, "Bookmark"));
809 // The paragraph marker's formatting.
810 xRun
.set(xRunEnum
->nextElement(), uno::UNO_QUERY
);
811 CPPUNIT_ASSERT_EQUAL(OUString("Text"),getProperty
<OUString
>(xRun
, "TextPortionType"));
812 CPPUNIT_ASSERT(xRun
->getString().isEmpty());
814 // deleted paragraph mark at the end of the second paragraph
817 // there is no run after the MoveBookmark
818 CPPUNIT_ASSERT(!xRunEnum
->hasMoreElements());
822 CPPUNIT_TEST_FIXTURE(Test
, testTdf146140
)
824 loadAndSave("tdf123460.docx");
825 CPPUNIT_ASSERT_EQUAL(1, getPages());
826 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
827 CPPUNIT_ASSERT(pXmlDoc
);
829 // This was 1 (put end of paragraph of the previous moveFrom into a w:del,
830 // resulting double deletions at the same position, which is an
831 // ODT back-compatibility issue described in tdf#107292)
832 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[2]/w:pPr/w:rPr/w:del", 0);
834 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[2]/w:pPr/w:rPr/w:moveFrom", 1);
837 //tdf#125298: fix charlimit restrictions in bookmarknames and field references if they contain non-ascii characters
838 CPPUNIT_TEST_FIXTURE(Test
, testTdf125298
)
840 loadAndSave("tdf125298_crossreflink_nonascii_charlimit.docx");
841 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
842 // check whether test file keeps non-ascii values or not
843 OUString bookmarkName1
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:bookmarkStart[1]", "name");
844 CPPUNIT_ASSERT_EQUAL(OUString::fromUtf8("\u00e1rv\u00edzt\u0171r\u0151_t\u00fck\u00f6rf\u00far\u00f3g\u00e9p"), bookmarkName1
);
846 OUString bookmarkName2
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[3]/w:bookmarkStart[1]", "name");
847 CPPUNIT_ASSERT_EQUAL(OUString::fromUtf8("\u00e91\u00e12\u01713\u01514\u00fa5\u00f66\u00fc7\u00f38\u00ed9"), bookmarkName2
);
848 OUString fieldName1
= getXPathContent(pXmlDoc
, "/w:document/w:body/w:p[5]/w:r[2]/w:instrText[1]");
849 OUString expectedFieldName1
= " REF " + bookmarkName1
+ " \\h ";
850 CPPUNIT_ASSERT_EQUAL(expectedFieldName1
, fieldName1
);
851 OUString fieldName2
= getXPathContent(pXmlDoc
, "/w:document/w:body/w:p[7]/w:r[2]/w:instrText[1]");
852 OUString expectedFieldName2
= " REF " + bookmarkName2
+ " \\h ";
853 CPPUNIT_ASSERT_EQUAL(expectedFieldName2
, fieldName2
);
856 DECLARE_OOXMLEXPORT_TEST(testTdf121784
, "tdf121784.docx")
858 // check tracked insertion of footnotes
859 CPPUNIT_ASSERT_EQUAL( OUString( "Text1" ), getParagraph( 1 )->getString());
860 CPPUNIT_ASSERT_EQUAL( OUString( "" ), getRun( getParagraph( 1 ), 2 )->getString());
861 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(1), 2), "RedlineType"));
862 CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty
<OUString
>(getRun(getParagraph(1), 2), "RedlineType"));
863 CPPUNIT_ASSERT_EQUAL( OUString( "1" ), getRun( getParagraph( 1 ), 3 )->getString());
865 // check tracked insertion of endnotes
866 CPPUNIT_ASSERT_EQUAL( OUString( "texti" ), getParagraph( 2 )->getString());
867 CPPUNIT_ASSERT_EQUAL( OUString( "" ), getRun( getParagraph( 2 ), 2 )->getString());
868 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(2), 2), "RedlineType"));
869 CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty
<OUString
>(getRun(getParagraph(2), 2), "RedlineType"));
870 CPPUNIT_ASSERT_EQUAL( OUString( "i" ), getRun( getParagraph( 2 ), 3 )->getString());
873 DECLARE_OOXMLEXPORT_TEST(testTbrlFrameVml
, "tbrl-frame-vml.docx")
875 uno::Reference
<beans::XPropertySet
> xTextFrame(getShape(1), uno::UNO_QUERY
);
876 CPPUNIT_ASSERT(xTextFrame
.is());
880 // DML import: creates a TextBox, eaVert read back as TB_RL in TextWritingMode
882 auto eMode
= getProperty
<text::WritingMode
>(xTextFrame
, "TextWritingMode");
883 CPPUNIT_ASSERT_EQUAL(text::WritingMode::WritingMode_TB_RL
, eMode
);
887 // VML import: creates a TextFrame.
889 auto nActual
= getProperty
<sal_Int16
>(xTextFrame
, "WritingMode");
890 // Without the accompanying fix in place, this test would have failed with 'Expected: 2; Actual:
891 // 4', i.e. writing direction was inherited from page, instead of explicit tbrl.
892 CPPUNIT_ASSERT_EQUAL(text::WritingMode2::TB_RL
, nActual
);
896 CPPUNIT_TEST_FIXTURE(Test
, testTdf119037
)
898 loadAndSave("tdf119037.odt");
899 CPPUNIT_ASSERT_EQUAL(1, getPages());
900 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
901 CPPUNIT_ASSERT(pXmlDoc
);
903 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:pPr/w:pBdr/w:top", "val", "single");
904 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:pPr/w:pBdr/w:left", "val", "single");
905 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:pPr/w:pBdr/w:right", "val", "single");
906 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:pPr/w:pBdr/w:bottom", "val", "single");
908 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[3]/w:pPr/w:pBdr/w:top", "val", "dotted");
909 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[3]/w:pPr/w:pBdr/w:left", "val", "dotted");
910 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[3]/w:pPr/w:pBdr/w:right", "val", "dotted");
911 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[3]/w:pPr/w:pBdr/w:bottom", "val", "dotted");
913 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[5]/w:pPr/w:pBdr/w:top", "val", "dashed");
914 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[5]/w:pPr/w:pBdr/w:left", "val", "dashed");
915 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[5]/w:pPr/w:pBdr/w:right", "val", "dashed");
916 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[5]/w:pPr/w:pBdr/w:bottom", "val", "dashed");
918 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[7]/w:pPr/w:pBdr/w:top", "val", "dashSmallGap");
919 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[7]/w:pPr/w:pBdr/w:left", "val", "dashSmallGap");
920 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[7]/w:pPr/w:pBdr/w:right", "val", "dashSmallGap");
921 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[7]/w:pPr/w:pBdr/w:bottom", "val", "dashSmallGap");
923 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[9]/w:pPr/w:pBdr/w:top", "val", "dotDash");
924 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[9]/w:pPr/w:pBdr/w:left", "val", "dotDash");
925 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[9]/w:pPr/w:pBdr/w:right", "val", "dotDash");
926 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[9]/w:pPr/w:pBdr/w:bottom", "val", "dotDash");
928 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[11]/w:pPr/w:pBdr/w:top", "val", "dotDotDash");
929 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[11]/w:pPr/w:pBdr/w:left", "val", "dotDotDash");
930 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[11]/w:pPr/w:pBdr/w:right", "val", "dotDotDash");
931 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[11]/w:pPr/w:pBdr/w:bottom", "val", "dotDotDash");
933 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[13]/w:pPr/w:pBdr/w:top", "val", "double");
934 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[13]/w:pPr/w:pBdr/w:left", "val", "double");
935 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[13]/w:pPr/w:pBdr/w:right", "val", "double");
936 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[13]/w:pPr/w:pBdr/w:bottom", "val", "double");
938 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[15]/w:pPr/w:pBdr/w:top", "val", "double");
939 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[15]/w:pPr/w:pBdr/w:left", "val", "double");
940 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[15]/w:pPr/w:pBdr/w:right", "val", "double");
941 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[15]/w:pPr/w:pBdr/w:bottom", "val", "double");
943 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[17]/w:pPr/w:pBdr/w:top", "val", "thinThickSmallGap");
944 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[17]/w:pPr/w:pBdr/w:left", "val", "thinThickSmallGap");
945 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[17]/w:pPr/w:pBdr/w:right", "val", "thinThickSmallGap");
946 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[17]/w:pPr/w:pBdr/w:bottom", "val", "thinThickSmallGap");
948 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[19]/w:pPr/w:pBdr/w:top", "val", "double");
949 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[19]/w:pPr/w:pBdr/w:left", "val", "double");
950 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[19]/w:pPr/w:pBdr/w:right", "val", "double");
951 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[19]/w:pPr/w:pBdr/w:bottom", "val", "double");
954 CPPUNIT_TEST_FIXTURE(Test
, testTdf125657
)
956 loadAndSave("tdf125657.docx");
957 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
958 CPPUNIT_ASSERT(pXmlDoc
);
959 auto checkAttrIsInt
= [&](const OString
& sAttrName
) {
960 OUString sAttr
= getXPath(pXmlDoc
,
961 "/w:document/w:body/w:p[1]/w:r[1]/w:drawing/wp:inline/a:graphic/"
962 "a:graphicData/pic:pic/pic:blipFill/a:srcRect",
964 OString
sAssertMsg("Attribute " + sAttrName
+ " value " + sAttr
.toUtf8()
965 + " is not a valid integer");
966 CPPUNIT_ASSERT_MESSAGE(sAssertMsg
.getStr(), !sAttr
.isEmpty());
967 // Only decimal characters allowed, optionally prepended with '-'; no '.'
968 CPPUNIT_ASSERT_MESSAGE(sAssertMsg
.getStr(),
969 sAttr
[0] == '-' || (sAttr
[0] >= '0' && sAttr
[0] <= '9'));
970 for (sal_Int32 i
= 1; i
< sAttr
.getLength(); ++i
) {
971 CPPUNIT_ASSERT_MESSAGE(sAssertMsg
.getStr(), sAttr
[i
] >= '0');
972 CPPUNIT_ASSERT_MESSAGE(sAssertMsg
.getStr(), sAttr
[i
] <= '9');
975 // check that we export all coordinates of srcRect as integers
982 DECLARE_OOXMLEXPORT_TEST(testTdf125324
, "tdf125324.docx")
984 discardDumpedLayout();
985 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
986 assertXPath(pXmlDoc
, "/root/page/body/txt[2]/anchored/fly/tab/infos/bounds", "top", "4193");
989 CPPUNIT_TEST_FIXTURE(Test
, testTdf78657
)
991 loadAndSave("tdf78657_picture_hyperlink.docx");
992 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
993 xmlDocUniquePtr pXmlRels
= parseExport("word/_rels/document.xml.rels");
994 assertXPath(pXmlDoc
, "/w:document/w:body/w:p/w:r/w:drawing/wp:inline/wp:docPr/a:hlinkClick", 1);
995 assertXPath(pXmlDoc
, "/w:document/w:body/w:p/w:r/w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:nvPicPr/pic:cNvPr/a:hlinkClick", 1);
996 assertXPath(pXmlRels
, "/rels:Relationships/rels:Relationship[@Target='http://www.google.com']", "TargetMode", "External");
999 CPPUNIT_TEST_FIXTURE(Test
, testBtlrFrame
)
1001 loadAndReload("btlr-frame.odt");
1002 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1003 CPPUNIT_ASSERT_EQUAL(1, getPages());
1004 uno::Reference
<beans::XPropertySet
> xPropertySet(getShape(1), uno::UNO_QUERY
);
1005 // Without the accompanying fix in place, this test would have failed with 'Expected:
1006 // -270; Actual: 0', i.e. the writing direction of the frame was lost.
1007 // Note: Implementation was changed to use WritingMode property instead of TextPreRotateAngle.
1008 CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR
,
1009 getProperty
<sal_Int16
>(xPropertySet
, "WritingMode"));
1012 CPPUNIT_TEST_FIXTURE(Test
, testTdf125518
)
1014 loadAndSave("tdf125518.odt");
1015 CPPUNIT_ASSERT_EQUAL(4, getShapes());
1016 CPPUNIT_ASSERT_EQUAL(2, getPages());
1017 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1020 // First diagram is anchored
1021 OUString anchorName
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:r[2]/w:drawing/wp:anchor/wp:docPr", "name");
1022 CPPUNIT_ASSERT_EQUAL(OUString("Object1"), anchorName
);
1024 // Second diagram has anchor
1025 anchorName
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[3]/w:r[1]/w:drawing/wp:anchor/wp:docPr", "name");
1026 CPPUNIT_ASSERT_EQUAL(OUString("Objekt1"), anchorName
);
1028 // Third diagram has no anchor
1029 anchorName
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[12]/w:r[2]/w:drawing/wp:inline/wp:docPr", "name");
1030 CPPUNIT_ASSERT_EQUAL(OUString("Object2"), anchorName
);
1032 // 4th diagram has anchor too
1033 anchorName
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[14]/w:r[3]/w:drawing/wp:anchor/wp:docPr", "name");
1034 CPPUNIT_ASSERT_EQUAL(OUString("Object3"), anchorName
);
1037 DECLARE_OOXMLEXPORT_TEST(testImageCommentAtChar
, "image-comment-at-char.docx")
1039 uno::Reference
<text::XTextRange
> xPara
= getParagraph(1);
1040 CPPUNIT_ASSERT_EQUAL(OUString("Text"),
1041 getProperty
<OUString
>(getRun(xPara
, 1), "TextPortionType"));
1042 // Without the accompanying fix in place, this test would have failed with 'Expected:
1043 // Annotation; Actual: Frame', i.e. the comment start before the image was lost.
1044 CPPUNIT_ASSERT_EQUAL(OUString("Annotation"),
1045 getProperty
<OUString
>(getRun(xPara
, 2), "TextPortionType"));
1046 CPPUNIT_ASSERT_EQUAL(OUString("Frame"),
1047 getProperty
<OUString
>(getRun(xPara
, 3), "TextPortionType"));
1048 CPPUNIT_ASSERT_EQUAL(OUString("AnnotationEnd"),
1049 getProperty
<OUString
>(getRun(xPara
, 4), "TextPortionType"));
1050 CPPUNIT_ASSERT_EQUAL(OUString("Text"),
1051 getProperty
<OUString
>(getRun(xPara
, 5), "TextPortionType"));
1054 CPPUNIT_TEST_FIXTURE(Test
, testTdf131594
)
1056 loadAndSave("tdf131594.docx");
1057 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1058 // lnNumType should not be exported if w:countBy="0"
1059 assertXPath(pXmlDoc
, "/w:document/w:body/w:sectPr/w:lnNumType", 0);
1062 CPPUNIT_TEST_FIXTURE(Test
, testTdf121663
)
1064 loadAndSave("tdf121663.docx");
1065 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1066 // auto distance of line numbering is 0.5 cm
1067 assertXPath(pXmlDoc
, "//w:lnNumType", "distance", "283");
1070 DECLARE_OOXMLEXPORT_TEST(testInvalidDateFormField
, "invalid_date_form_field.docx")
1073 uno::Reference
<container::XEnumerationAccess
> xParagraph(getParagraph(1), uno::UNO_QUERY
);
1074 uno::Reference
<container::XEnumeration
> xPortions
= xParagraph
->createEnumeration();
1077 while (xPortions
->hasMoreElements())
1079 uno::Reference
<beans::XPropertySet
> xTextPortion(xPortions
->nextElement(), uno::UNO_QUERY
);
1080 OUString aPortionType
;
1081 xTextPortion
->getPropertyValue("TextPortionType") >>= aPortionType
;
1082 if (aPortionType
!= "ContentControl")
1087 uno::Reference
<text::XTextContent
> xContentControl
;
1088 xTextPortion
->getPropertyValue("ContentControl") >>= xContentControl
;
1089 uno::Reference
<beans::XPropertySet
> xContentControlProps(xContentControl
, uno::UNO_QUERY
);
1091 xContentControlProps
->getPropertyValue("Date") >>= bDate
;
1092 CPPUNIT_ASSERT(bDate
);
1094 // Check date content control's parameters.
1095 OUString sDateFormat
;
1096 xContentControlProps
->getPropertyValue("DateFormat") >>= sDateFormat
;
1099 xContentControlProps
->getPropertyValue("DateLanguage") >>= sLang
;
1101 OUString sCurrentDate
;
1102 xContentControlProps
->getPropertyValue("CurrentDate") >>= sCurrentDate
;
1104 // The first one has invalid date format (invalid = LO can't parse it)
1108 CPPUNIT_ASSERT_EQUAL(OUString("YYYY.MM.DDT00:00:00Z"), sDateFormat
);
1109 CPPUNIT_ASSERT_EQUAL(OUString("en-US"), sLang
);
1110 CPPUNIT_ASSERT_EQUAL(OUString(""), sCurrentDate
);
1113 else if (nIndex
== 1) // The second has wrong date
1115 CPPUNIT_ASSERT_EQUAL(OUString("MM/DD/YY"), sDateFormat
);
1116 CPPUNIT_ASSERT_EQUAL(OUString("en-US"), sLang
);
1117 CPPUNIT_ASSERT_EQUAL(OUString("2019.06.34T00:00:00Z"), sCurrentDate
);
1120 else // The third one has wrong local
1122 CPPUNIT_ASSERT_EQUAL(OUString("[NatNum12 MMMM=abbreviation]YYYY\". \"MMMM D."), sDateFormat
);
1123 CPPUNIT_ASSERT_EQUAL(OUString("xxxx"), sLang
);
1124 CPPUNIT_ASSERT_EQUAL(OUString("2019.06.11T00:00:00Z"), sCurrentDate
);
1129 CPPUNIT_ASSERT_EQUAL(int(3), nIndex
);
1132 DECLARE_OOXMLEXPORT_TEST(tdf127085
, "tdf127085.docx")
1134 // Fill transparency was lost during export
1135 uno::Reference
<beans::XPropertySet
> xShape(getShape(1), uno::UNO_QUERY
);
1136 CPPUNIT_ASSERT_EQUAL(sal_Int16(50), getProperty
<sal_Int16
>(xShape
, "FillTransparence"));
1139 DECLARE_OOXMLEXPORT_TEST(tdf119809
, "tdf119809.docx")
1141 // Combobox without an item list lost during import
1142 if (getShapes() > 0)
1144 uno::Reference
<drawing::XControlShape
> xControlShape(getShape(1), uno::UNO_QUERY
);
1145 uno::Reference
<beans::XPropertySet
> xPropertySet(xControlShape
->getControl(), uno::UNO_QUERY
);
1146 uno::Reference
<lang::XServiceInfo
> xServiceInfo(xPropertySet
, uno::UNO_QUERY
);
1147 CPPUNIT_ASSERT_EQUAL(true, bool(xServiceInfo
->supportsService("com.sun.star.form.component.ComboBox")));
1148 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty
< uno::Sequence
<OUString
> >(xPropertySet
, "StringItemList").getLength());
1152 // DropDown was imported as content control
1153 // First run: bookmark
1154 uno::Reference
<beans::XPropertySet
> xTextPortion(getRun(getParagraph(1), 2), uno::UNO_QUERY
);
1155 OUString aPortionType
;
1156 xTextPortion
->getPropertyValue("TextPortionType") >>= aPortionType
;
1157 CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType
);
1158 uno::Reference
<text::XTextContent
> xContentControl
;
1159 xTextPortion
->getPropertyValue("ContentControl") >>= xContentControl
;
1160 uno::Reference
<beans::XPropertySet
> xContentControlProps(xContentControl
, uno::UNO_QUERY
);
1161 uno::Sequence
<beans::PropertyValues
> aListItems
;
1162 xContentControlProps
->getPropertyValue("ListItems") >>= aListItems
;
1163 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0), aListItems
.getLength());
1167 DECLARE_OOXMLEXPORT_TEST(tdf118169
, "tdf118169.docx")
1169 // Unicode characters were converted to question marks.
1170 uno::Reference
<drawing::XControlShape
> xControlShape(getShape(1), uno::UNO_QUERY
);
1171 uno::Reference
<beans::XPropertySet
> xPropertySet(xControlShape
->getControl(), uno::UNO_QUERY
);
1172 uno::Reference
<lang::XServiceInfo
> xServiceInfo(xPropertySet
, uno::UNO_QUERY
);
1173 CPPUNIT_ASSERT_EQUAL(true, bool(xServiceInfo
->supportsService("com.sun.star.form.component.CheckBox")));
1174 CPPUNIT_ASSERT_EQUAL(OUString(u
"őőőőőőőőőőőűűűű"), getProperty
<OUString
>(xPropertySet
, "Label"));
1177 CPPUNIT_TEST_FIXTURE(Test
, testTdf127116
)
1179 loadAndSave("tdf127116.odt");
1180 CPPUNIT_ASSERT_EQUAL(2, getPages());
1181 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1184 OUString bookmarkName
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:bookmarkStart", "name");
1185 OUString anchor
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[2]/w:hyperlink", "anchor");
1186 CPPUNIT_ASSERT_EQUAL(anchor
, bookmarkName
);
1189 CPPUNIT_TEST_FIXTURE(Test
, testTdf127339
)
1191 loadAndSave("tdf127339.docx");
1192 xmlDocUniquePtr pXmlRels
= parseExport("word/_rels/document.xml.rels");
1194 assertXPathNoAttribute(pXmlRels
, "/rels:Relationships/rels:Relationship[@Target='#bookmark']", "TargetMode");
1197 CPPUNIT_TEST_FIXTURE(Test
, testTdf127362
)
1199 loadAndSave("tdf127362.odt");
1200 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1201 CPPUNIT_ASSERT_EQUAL(2, getPages());
1202 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1204 xmlDocUniquePtr pXmlRels
= parseExport("word/_rels/document.xml.rels");
1206 OUString bookmarkName
= "#" + getXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:bookmarkStart", "name");
1207 OUString anchor
= getXPath(pXmlRels
, "/rels:Relationships/rels:Relationship[@Id='rId3']", "Target");
1208 CPPUNIT_ASSERT_EQUAL(anchor
, bookmarkName
);
1211 CPPUNIT_TEST_FIXTURE(Test
, testTdf127605
)
1213 loadAndSave("tdf127605.odt");
1214 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1215 CPPUNIT_ASSERT_EQUAL(2, getPages());
1216 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1218 OUString bookmarkName
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[2]/w:bookmarkStart", "name");
1219 OUString anchor
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:hyperlink", "anchor");
1220 CPPUNIT_ASSERT_EQUAL(anchor
, bookmarkName
);
1223 CPPUNIT_TEST_FIXTURE(Test
, testTdf127732
)
1225 loadAndSave("internal_hyperlink_frame.odt");
1226 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1227 CPPUNIT_ASSERT_EQUAL(2, getPages());
1228 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1230 OUString bookmarkName
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[2]/w:r[2]/mc:AlternateContent/mc:Fallback/w:pict/v:rect/v:textbox/w:txbxContent/w:p/w:bookmarkStart", "name");
1231 OUString anchor
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:hyperlink", "anchor");
1232 CPPUNIT_ASSERT_EQUAL(anchor
, bookmarkName
);
1235 CPPUNIT_TEST_FIXTURE(Test
, testTdf127733
)
1237 loadAndSave("internal_hyperlink_ole.odt");
1238 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1239 CPPUNIT_ASSERT_EQUAL(2, getPages());
1240 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1243 OUString bookmarkName
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[3]/w:bookmarkStart", "name");
1244 OUString anchor
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:hyperlink", "anchor");
1245 CPPUNIT_ASSERT_EQUAL(anchor
, bookmarkName
);
1248 CPPUNIT_TEST_FIXTURE(Test
, testTdf127734
)
1250 loadAndSave("internal_hyperlink_region.odt");
1251 CPPUNIT_ASSERT_EQUAL(2, getPages());
1252 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1254 OUString bookmarkName
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[2]/w:bookmarkStart", "name");
1255 OUString anchor
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:hyperlink", "anchor");
1256 CPPUNIT_ASSERT_EQUAL(anchor
, bookmarkName
);
1259 CPPUNIT_TEST_FIXTURE(Test
, testTdf127735
)
1261 loadAndSave("internal_hyperlink_table.odt");
1262 CPPUNIT_ASSERT_EQUAL(2, getPages());
1263 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1265 OUString bookmarkName
= getXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p/w:bookmarkStart", "name");
1266 OUString anchor
= getXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:hyperlink", "anchor");
1267 CPPUNIT_ASSERT_EQUAL(anchor
, bookmarkName
);
1270 CPPUNIT_TEST_FIXTURE(Test
, testTdf123628
)
1272 loadAndSave("tdf123628.odt");
1273 CPPUNIT_ASSERT_EQUAL(1, getPages());
1274 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1276 xmlDocUniquePtr pXmlStyles
= parseExport("word/styles.xml");
1278 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:hyperlink/w:r/w:rPr/w:rStyle", "val", "Hyperlink");
1279 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Hyperlink']/w:name", "val", "Hyperlink");
1282 DECLARE_OOXMLEXPORT_TEST(testTdf127741
, "tdf127741.docx")
1284 uno::Reference
<text::XTextRange
> xPara
= getParagraph(1);
1285 uno::Reference
<beans::XPropertySet
> xRun(getRun(xPara
,1), uno::UNO_QUERY
);
1286 OUString unVisitedStyleName
= getProperty
<OUString
>(xRun
, "UnvisitedCharStyleName");
1287 CPPUNIT_ASSERT(unVisitedStyleName
.equalsIgnoreAsciiCase("Internet Link"));
1288 OUString visitedStyleName
= getProperty
<OUString
>(xRun
, "VisitedCharStyleName");
1289 CPPUNIT_ASSERT(visitedStyleName
.equalsIgnoreAsciiCase("Visited Internet Link"));
1292 CPPUNIT_TEST_FIXTURE(Test
, testTdf142693_hugePaperSizeImport
)
1294 loadAndSave("tdf142693_hugePaperSizeImport.docx");
1295 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1296 assertXPath(pXmlDoc
, "/w:document/w:body/w:sectPr/w:pgSz", "w", "90369");
1297 assertXPath(pXmlDoc
, "/w:document/w:body/w:sectPr/w:pgSz", "h", "104372");
1300 CPPUNIT_TEST_FIXTURE(Test
, testTdf127925
)
1302 loadAndSave("tdf127925.odt");
1303 CPPUNIT_ASSERT_EQUAL(1, getPages());
1304 xmlDocUniquePtr pXmlStyles
= parseExport("word/styles.xml");
1305 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='FollowedHyperlink']/w:name", "val", "FollowedHyperlink");
1308 CPPUNIT_TEST_FIXTURE(Test
, testTdf127579
)
1310 loadAndSave("tdf127579.odt");
1311 CPPUNIT_ASSERT_EQUAL(1, getPages());
1312 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1313 assertXPath(pXmlDoc
, "/w:document/w:body/w:p/w:hyperlink/w:r/w:rPr/w:rStyle", "val", "Hyperlink");
1316 CPPUNIT_TEST_FIXTURE(Test
, testTdf128304
)
1318 loadAndReload("tdf128304.odt");
1319 CPPUNIT_ASSERT_EQUAL(4, getShapes());
1320 CPPUNIT_ASSERT_EQUAL(1, getPages());
1321 css::text::WritingMode eMode
;
1322 uno::Reference
<beans::XPropertySet
> xProps1(getShape(1), uno::UNO_QUERY
);
1323 CPPUNIT_ASSERT(xProps1
->getPropertyValue("TextWritingMode") >>= eMode
);
1324 CPPUNIT_ASSERT_EQUAL(css::text::WritingMode::WritingMode_TB_RL
, eMode
);
1326 uno::Reference
<beans::XPropertySet
> xProps2(getShape(2), uno::UNO_QUERY
);
1327 CPPUNIT_ASSERT(xProps2
->getPropertyValue("TextWritingMode") >>= eMode
);
1328 CPPUNIT_ASSERT_EQUAL(css::text::WritingMode::WritingMode_TB_RL
, eMode
);
1330 uno::Reference
<beans::XPropertySet
> xProps3(getShape(3), uno::UNO_QUERY
);
1331 CPPUNIT_ASSERT(xProps3
->getPropertyValue("TextWritingMode") >>= eMode
);
1332 CPPUNIT_ASSERT_EQUAL(css::text::WritingMode::WritingMode_TB_RL
, eMode
);
1334 uno::Reference
<beans::XPropertySet
> xProps4(getShape(4), uno::UNO_QUERY
);
1335 CPPUNIT_ASSERT(xProps4
->getPropertyValue("TextWritingMode") >>= eMode
);
1336 CPPUNIT_ASSERT_EQUAL(css::text::WritingMode::WritingMode_TB_RL
, eMode
);
1339 CPPUNIT_PLUGIN_IMPLEMENT();
1341 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */