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/awt/FontWeight.hpp>
13 #include <com/sun/star/text/VertOrientation.hpp>
14 #include <com/sun/star/text/XFootnote.hpp>
15 #include <com/sun/star/text/XTextColumns.hpp>
16 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
17 #include <com/sun/star/view/XSelectionSupplier.hpp>
18 #include <com/sun/star/style/ParagraphAdjust.hpp>
19 #include <com/sun/star/text/SizeType.hpp>
20 #include <com/sun/star/text/XTextContent.hpp>
21 #include <com/sun/star/text/XTextField.hpp>
22 #include <com/sun/star/text/XTextTable.hpp>
24 #include <tools/UnitConversion.hxx>
25 #include <comphelper/sequenceashashmap.hxx>
26 #include <svx/svdpage.hxx>
28 #include <drawdoc.hxx>
29 #include <IDocumentDrawModelAccess.hxx>
30 #include <unotxdoc.hxx>
32 #include <IDocumentLayoutAccess.hxx>
33 #include <rootfrm.hxx>
34 #include <pagefrm.hxx>
35 #include <flyfrms.hxx>
36 #include <sortedobjs.hxx>
38 #include <IDocumentMarkAccess.hxx>
39 #include <xmloff/odffields.hxx>
41 class Test
: public SwModelTestBase
45 : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text")
50 DECLARE_OOXMLEXPORT_TEST(testFdo78939
, "fdo78939.docx")
52 // fdo#78939 : LO hanged while opening issue document
54 // Whenever a para-style was applied to a Numbering format level,
55 // LO incorrectly also changed the para-style...
57 // check that file opens and does not hang while opening and also
58 // check that an incorrect numbering style is not applied ...
59 CPPUNIT_ASSERT_EQUAL(OUString(), getProperty
<OUString
>(getParagraph(1), "NumberingStyleName"));
62 DECLARE_OOXMLEXPORT_TEST(testFootnote
, "footnote.docx")
64 uno::Reference
<text::XFootnotesSupplier
> xFootnotesSupplier(mxComponent
, uno::UNO_QUERY
);
65 uno::Reference
<container::XIndexAccess
> xFootnotes
= xFootnotesSupplier
->getFootnotes();
66 uno::Reference
<text::XTextRange
> xFootnote(xFootnotes
->getByIndex(0), uno::UNO_QUERY
);
67 OUString aFootnote
= xFootnote
->getString();
68 // Ensure there are no additional newlines after "bar".
69 CPPUNIT_ASSERT(aFootnote
.endsWith("bar"));
72 DECLARE_OOXMLEXPORT_TEST(testTableBtlrCenter
, "table-btlr-center.docx")
74 // Note that this is btLr text, so layout and doc model horizontal/vertical is the opposite of
76 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
77 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
79 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
80 uno::Reference
<table::XCell
> xCell
= xTable
->getCellByName("A2");
81 // Cell vertical alignment was CENTER, should be NONE.
82 CPPUNIT_ASSERT_EQUAL(text::VertOrientation::NONE
, getProperty
<sal_Int16
>(xCell
, "VertOrient"));
84 // Cell horizontal alignment should be CENTER.
85 uno::Reference
<text::XText
> xCellText(xCell
, uno::UNO_QUERY
);
86 auto nActual
= getProperty
<sal_Int32
>(getParagraphOfText(1, xCellText
), "ParaAdjust");
87 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(style::ParagraphAdjust_CENTER
), nActual
);
90 DECLARE_OOXMLEXPORT_TEST(testFdo80555
, "fdo80555.docx")
92 uno::Reference
<drawing::XShape
> xShape
= getShape(1);
93 // Shape was wrongly placed at X=0, Y=0
94 CPPUNIT_ASSERT_EQUAL(sal_Int32(3318), xShape
->getPosition().X
);
95 CPPUNIT_ASSERT_EQUAL(sal_Int32(247), xShape
->getPosition().Y
);
98 CPPUNIT_TEST_FIXTURE(Test
, testTdf104418
)
100 loadAndReload("tdf104418.odt");
101 // Problem was that <w:hideMark> cell property was ignored.
102 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
103 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
105 uno::Reference
<text::XTextTable
> xTextTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
106 uno::Reference
<table::XTableRows
> xTableRows
= xTextTable
->getRows();
108 // Without the fix in place, this test would have failed with
111 CPPUNIT_ASSERT_EQUAL(sal_Int64(750),
112 getProperty
<sal_Int64
>(xTableRows
->getByIndex(0), "Height"));
115 DECLARE_OOXMLEXPORT_TEST(testHidemark
, "hidemark.docx")
117 // Problem was that <w:hideMark> cell property was ignored.
118 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
119 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
121 uno::Reference
<text::XTextTable
> xTextTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
122 uno::Reference
<table::XTableRows
> xTableRows
= xTextTable
->getRows();
123 // Height should be minimal
124 CPPUNIT_ASSERT_EQUAL(convertTwipToMm100(MINLAY
),
125 getProperty
<sal_Int64
>(xTableRows
->getByIndex(1), "Height"));
126 // Size type was MIN, should be FIX to avoid considering the end of paragraph marker.
127 CPPUNIT_ASSERT_EQUAL(text::SizeType::FIX
,
128 getProperty
<sal_Int16
>(xTableRows
->getByIndex(1), "SizeType"));
130 //tdf#104876: Width was not recognized during import when table size was 'auto'
131 CPPUNIT_ASSERT_MESSAGE("table size is less than 7000?",
132 sal_Int32(7000) > getProperty
<sal_Int32
>(xTextTable
, "Width"));
135 DECLARE_OOXMLEXPORT_TEST(testHidemarkb
, "tdf99616_hidemarkb.docx")
137 // Problem was that the smallest possible height was forced, not the min specified size.
138 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
139 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
141 uno::Reference
<text::XTextTable
> xTextTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
142 uno::Reference
<table::XTableRows
> xTableRows
= xTextTable
->getRows();
143 // Height should be .5cm
144 CPPUNIT_ASSERT_EQUAL(sal_Int64(501),
145 getProperty
<sal_Int64
>(xTableRows
->getByIndex(1), "Height"));
146 // Size type was MIN, should be FIX to avoid considering the end of paragraph marker.
147 CPPUNIT_ASSERT_EQUAL(text::SizeType::FIX
,
148 getProperty
<sal_Int16
>(xTableRows
->getByIndex(1), "SizeType"));
151 DECLARE_OOXMLEXPORT_TEST(testBnc891663
, "bnc891663.docx")
153 // The image should be inside a cell, so the text in the following cell should be below it.
155 = parseDump("/root/page/body/tab/row[1]/cell[2]/txt[1]/anchored/fly/infos/bounds", "top")
158 = parseDump("/root/page/body/tab/row[1]/cell[2]/txt[1]/anchored/fly/infos/bounds", "height")
161 = parseDump("/root/page/body/tab/row[2]/cell[1]/txt[1]/infos/bounds", "top").toInt32();
162 CPPUNIT_ASSERT(textNextRowTop
>= imageTop
+ imageHeight
);
165 DECLARE_OOXMLEXPORT_TEST(testTdf123104
, "tdf123104.docx")
167 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
168 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
170 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
171 uno::Reference
<table::XCell
> xCell
= xTable
->getCellByName("E1");
172 // See SwXCell::getPropertyValue(), we really put 'long' into an Any there.
173 // Without the accompanying fix in place, this test would have failed with 'Expected: 3;Actual :
174 // 2', i.e. the vertical merge covered one less cell, resulting in a cell with white background.
175 CPPUNIT_ASSERT_EQUAL(static_cast<tools::Long
>(3), getProperty
<tools::Long
>(xCell
, "RowSpan"));
178 DECLARE_OOXMLEXPORT_TEST(testFdo85542
, "fdo85542.docx")
180 uno::Reference
<text::XBookmarksSupplier
> xBookmarksSupplier(mxComponent
, uno::UNO_QUERY
);
181 uno::Reference
<container::XIndexAccess
> xBookmarksByIdx(xBookmarksSupplier
->getBookmarks(),
183 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(3), xBookmarksByIdx
->getCount());
184 uno::Reference
<container::XNameAccess
> xBookmarksByName
= xBookmarksSupplier
->getBookmarks();
185 CPPUNIT_ASSERT(xBookmarksByName
->hasByName("B1"));
186 CPPUNIT_ASSERT(xBookmarksByName
->hasByName("B2"));
187 CPPUNIT_ASSERT(xBookmarksByName
->hasByName("B3"));
189 uno::Reference
<text::XTextContent
> xContent1(xBookmarksByName
->getByName("B1"), uno::UNO_QUERY
);
190 uno::Reference
<text::XTextRange
> xRange1
= xContent1
->getAnchor();
191 CPPUNIT_ASSERT_EQUAL(OUString("ABB"), xRange1
->getString());
193 uno::Reference
<text::XTextContent
> xContent2(xBookmarksByName
->getByName("B2"), uno::UNO_QUERY
);
194 uno::Reference
<text::XTextRange
> xRange2
= xContent2
->getAnchor();
195 CPPUNIT_ASSERT_EQUAL(OUString("BBC"), xRange2
->getString());
196 // B3 -- testing a collapsed bookmark
197 uno::Reference
<text::XTextContent
> xContent3(xBookmarksByName
->getByName("B3"), uno::UNO_QUERY
);
198 uno::Reference
<text::XTextRange
> xRange3
= xContent3
->getAnchor();
199 CPPUNIT_ASSERT_EQUAL(xRange3
->getString(), OUString());
200 uno::Reference
<text::XText
> xText
= xRange3
->getText();
201 uno::Reference
<text::XTextCursor
> xNeighborhoodCursor
= xText
->createTextCursor();
202 xNeighborhoodCursor
->gotoRange(xRange3
, false);
203 xNeighborhoodCursor
->goLeft(1, false);
204 xNeighborhoodCursor
->goRight(2, true);
205 CPPUNIT_ASSERT_EQUAL(OUString("AB"), xNeighborhoodCursor
->getString());
208 CPPUNIT_TEST_FIXTURE(Test
, testTdf65955
)
210 loadAndReload("tdf65955.odt");
211 CPPUNIT_ASSERT_EQUAL(1, getPages());
212 uno::Reference
<text::XBookmarksSupplier
> xBookmarksSupplier(mxComponent
, uno::UNO_QUERY
);
213 uno::Reference
<container::XIndexAccess
> xBookmarksByIdx(xBookmarksSupplier
->getBookmarks(),
215 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(2), xBookmarksByIdx
->getCount());
216 uno::Reference
<container::XNameAccess
> xBookmarksByName
= xBookmarksSupplier
->getBookmarks();
217 CPPUNIT_ASSERT(xBookmarksByName
->hasByName("a"));
218 CPPUNIT_ASSERT(xBookmarksByName
->hasByName("b"));
220 uno::Reference
<text::XTextContent
> xContent3(xBookmarksByName
->getByName("a"), uno::UNO_QUERY
);
221 uno::Reference
<text::XTextRange
> xRange3
= xContent3
->getAnchor();
222 CPPUNIT_ASSERT_EQUAL(xRange3
->getString(), OUString());
224 uno::Reference
<text::XTextContent
> xContent2(xBookmarksByName
->getByName("b"), uno::UNO_QUERY
);
225 uno::Reference
<text::XTextRange
> xRange2
= xContent2
->getAnchor();
226 CPPUNIT_ASSERT_EQUAL(OUString("r"), xRange2
->getString());
229 CPPUNIT_TEST_FIXTURE(Test
, testTdf65955_2
)
231 loadAndReload("tdf65955_2.odt");
232 CPPUNIT_ASSERT_EQUAL(1, getPages());
233 uno::Reference
<text::XBookmarksSupplier
> xBookmarksSupplier(mxComponent
, uno::UNO_QUERY
);
234 uno::Reference
<container::XIndexAccess
> xBookmarksByIdx(xBookmarksSupplier
->getBookmarks(),
236 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), xBookmarksByIdx
->getCount());
237 uno::Reference
<container::XNameAccess
> xBookmarksByName
= xBookmarksSupplier
->getBookmarks();
238 CPPUNIT_ASSERT(xBookmarksByName
->hasByName("test"));
240 uno::Reference
<text::XTextContent
> xContent3(xBookmarksByName
->getByName("test"),
242 uno::Reference
<text::XTextRange
> xRange3
= xContent3
->getAnchor();
243 CPPUNIT_ASSERT_EQUAL(OUString("foo bar"), xRange3
->getString());
246 DECLARE_OOXMLEXPORT_TEST(testChtOutlineNumberingOoxml
, "chtoutline.docx")
248 static constexpr OUStringLiteral aExpectedNumbering
= u
"\u7b2c 1 \u7ae0";
250 uno::Reference
<beans::XPropertySet
> xPara(getParagraph(1), uno::UNO_QUERY
);
251 CPPUNIT_ASSERT_EQUAL(OUString(aExpectedNumbering
),
252 getProperty
<OUString
>(xPara
, "ListLabelString"));
255 DECLARE_OOXMLEXPORT_TEST(mathtype
, "mathtype.docx")
257 uno::Reference
<text::XTextEmbeddedObjectsSupplier
> xTextEmbeddedObjectsSupplier(mxComponent
,
259 uno::Reference
<container::XIndexAccess
> xEmbeddedObjects(
260 xTextEmbeddedObjectsSupplier
->getEmbeddedObjects(), uno::UNO_QUERY
);
261 // This failed as the Model property was empty.
263 = getProperty
<uno::Reference
<lang::XServiceInfo
>>(xEmbeddedObjects
->getByIndex(0), "Model");
264 CPPUNIT_ASSERT(xModel
->supportsService("com.sun.star.formula.FormulaProperties"));
267 CPPUNIT_TEST_FIXTURE(Test
, testTdf8255
)
269 auto verify
= [this]() {
270 // A full-page-wide multi-page floating table should be allowed to split:
271 uno::Reference
<text::XTextFramesSupplier
> xDocument(mxComponent
, uno::UNO_QUERY
);
272 uno::Reference
<beans::XPropertySet
> xFrame(xDocument
->getTextFrames()->getByName("Frame1"),
274 bool bIsSplitAllowed
{};
275 xFrame
->getPropertyValue("IsSplitAllowed") >>= bIsSplitAllowed
;
276 CPPUNIT_ASSERT(bIsSplitAllowed
);
278 createSwDoc("tdf8255.docx");
280 saveAndReload("Office Open XML Text");
284 DECLARE_OOXMLEXPORT_TEST(testTdf87460
, "tdf87460.docx")
286 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
287 uno::Reference
<text::XEndnotesSupplier
> xEndnotesSupplier(xTextDocument
, uno::UNO_QUERY
);
288 uno::Reference
<container::XIndexAccess
> xEndnotes
= xEndnotesSupplier
->getEndnotes();
289 // This was 0: endnote was lost on import.
290 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), xEndnotes
->getCount());
293 DECLARE_OOXMLEXPORT_TEST(testTdf90611
, "tdf90611.docx")
295 uno::Reference
<text::XFootnotesSupplier
> xFootnotesSupplier(mxComponent
, uno::UNO_QUERY
);
296 uno::Reference
<container::XIndexAccess
> xFootnotes
= xFootnotesSupplier
->getFootnotes();
297 uno::Reference
<text::XText
> xFootnoteText
;
298 xFootnotes
->getByIndex(0) >>= xFootnoteText
;
300 CPPUNIT_ASSERT_EQUAL(10.f
,
301 getProperty
<float>(getParagraphOfText(1, xFootnoteText
), "CharHeight"));
304 DECLARE_OOXMLEXPORT_TEST(testTdf89702
, "tdf89702.docx")
306 // Get the first paragraph's numbering style's 2nd level's character style name.
307 uno::Reference
<text::XTextRange
> xParagraph
= getParagraph(1);
309 = getProperty
<uno::Reference
<container::XIndexAccess
>>(xParagraph
, "NumberingRules");
310 uno::Sequence
<beans::PropertyValue
> aLevel
;
311 xLevels
->getByIndex(1) >>= aLevel
; // 2nd level
312 OUString aCharStyleName
= std::find_if(std::cbegin(aLevel
), std::cend(aLevel
),
313 [](const beans::PropertyValue
& rValue
) {
314 return rValue
.Name
== "CharStyleName";
316 ->Value
.get
<OUString
>();
318 // Make sure that the font name is Arial, this was Verdana.
319 uno::Reference
<beans::XPropertySet
> xStyle(
320 getStyles("CharacterStyles")->getByName(aCharStyleName
), uno::UNO_QUERY
);
321 CPPUNIT_ASSERT_EQUAL(OUString("Arial"), getProperty
<OUString
>(xStyle
, "CharFontName"));
324 DECLARE_OOXMLEXPORT_TEST(testTdf86374
, "tdf86374.docx")
326 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
327 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
329 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
330 uno::Reference
<table::XTableRows
> xTableRows
= xTable
->getRows();
331 // btLr text direction was imported as FIX, it should be MIN to have enough space for the additionally entered paragraphs.
332 CPPUNIT_ASSERT_EQUAL(text::SizeType::MIN
,
333 getProperty
<sal_Int16
>(xTableRows
->getByIndex(0), "SizeType"));
336 DECLARE_OOXMLEXPORT_TEST(testTdf87924
, "tdf87924.docx")
338 uno::Reference
<beans::XPropertySet
> xPropertySet(getShape(1), uno::UNO_QUERY
);
339 comphelper::SequenceAsHashMap
aGeometry(xPropertySet
->getPropertyValue("CustomShapeGeometry"));
340 // This was -270, the text rotation angle was set when it should not be rotated.
341 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0),
342 aGeometry
["TextPreRotateAngle"].get
<sal_Int32
>());
345 DECLARE_OOXMLEXPORT_TEST(testIndents
, "indents.docx")
347 //expected left margin and first line indent values
348 static const sal_Int32 indents
[] = { 0, 0, -2000, 0, -2000, 1000, -1000, -1000, 2000, -1000 };
349 uno::Reference
<text::XTextDocument
> textDocument(mxComponent
, uno::UNO_QUERY
);
350 uno::Reference
<container::XEnumerationAccess
> xParaEnumAccess(textDocument
->getText(),
352 // list of paragraphs
353 uno::Reference
<container::XEnumeration
> xParaEnum
= xParaEnumAccess
->createEnumeration();
354 size_t paraIndex
= 0;
357 uno::Reference
<lang::XServiceInfo
> xServiceInfo
;
358 if (xParaEnum
->nextElement() >>= xServiceInfo
)
360 uno::Reference
<beans::XPropertySet
> const xPropertySet(xServiceInfo
,
361 uno::UNO_QUERY_THROW
);
362 sal_Int32 nIndent
= 0;
363 sal_Int32 nFirstLine
= 0;
364 xPropertySet
->getPropertyValue("ParaLeftMargin") >>= nIndent
;
365 xPropertySet
->getPropertyValue("ParaFirstLineIndent") >>= nFirstLine
;
366 CPPUNIT_ASSERT_EQUAL(indents
[paraIndex
* 2], nIndent
);
367 CPPUNIT_ASSERT_EQUAL(indents
[paraIndex
* 2 + 1], nFirstLine
);
370 } while (xParaEnum
->hasMoreElements());
373 DECLARE_OOXMLEXPORT_TEST(testTdf92454
, "tdf92454.docx")
375 // The first paragraph had a large indentation / left margin as inheritance
376 // in Word and Writer works differently, and no direct value was set to be
378 uno::Reference
<beans::XPropertyState
> xParagraph(getParagraph(1), uno::UNO_QUERY
);
379 // This was beans::PropertyState_DEFAULT_VALUE.
380 CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE
,
381 xParagraph
->getPropertyState("ParaFirstLineIndent"));
384 DECLARE_OOXMLEXPORT_TEST(testTdf95377
, "tdf95377.docx")
386 uno::Reference
<beans::XPropertyState
> xParagraph(getParagraph(1), uno::UNO_QUERY
);
387 CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), getProperty
<sal_Int32
>(xParagraph
, "ParaRightMargin"));
389 xParagraph
.set(getParagraph(2), uno::UNO_QUERY
);
390 CPPUNIT_ASSERT_EQUAL(sal_Int32(-501),
391 getProperty
<sal_Int32
>(xParagraph
, "ParaFirstLineIndent"));
392 CPPUNIT_ASSERT_EQUAL(sal_Int32(2501), getProperty
<sal_Int32
>(xParagraph
, "ParaLeftMargin"));
393 CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE
,
394 xParagraph
->getPropertyState("ParaFirstLineIndent"));
396 xParagraph
.set(getParagraph(3), uno::UNO_QUERY
);
397 CPPUNIT_ASSERT_EQUAL(sal_Int32(-250),
398 getProperty
<sal_Int32
>(xParagraph
, "ParaFirstLineIndent"));
399 CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty
<sal_Int32
>(xParagraph
, "ParaLeftMargin"));
400 CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE
,
401 xParagraph
->getPropertyState("ParaFirstLineIndent"));
403 //default style has numbering enabled. Styles inherit numbering unless specifically disabled
404 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
406 "//body/txt/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']",
407 3); //first three paragraphs have numbering
409 "//body/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']",
412 "//body/txt[2]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']",
415 "//body/txt[3]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']",
419 "/root/page/body/txt[4]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']",
420 0); //last paragraph style disables numbering
423 DECLARE_OOXMLEXPORT_TEST(testTdf95376
, "tdf95376.docx")
425 uno::Reference
<beans::XPropertyState
> xParagraph(getParagraph(2), uno::UNO_QUERY
);
426 // This was beans::PropertyState_DIRECT_VALUE: indentation-from-numbering
427 // did not have priority over indentation-from-paragraph-style, due to a
428 // filter workaround that's not correct here.
429 CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DEFAULT_VALUE
,
430 xParagraph
->getPropertyState("ParaFirstLineIndent"));
432 //tdf#131321 - paragraph styles lost their numbering. Bullet+space inherits WWNum1 from Bullet
433 uno::Reference
<beans::XPropertySet
> xStyle(
434 getStyles("ParagraphStyles")->getByName("Bullet+space"), uno::UNO_QUERY
);
435 CPPUNIT_ASSERT(!(getProperty
<OUString
>(xStyle
, "NumberingStyleName")).isEmpty());
438 DECLARE_OOXMLEXPORT_TEST(testTdf92124
, "tdf92124.docx")
440 // Get the second paragraph's numbering style's 1st level's suffix.
441 uno::Reference
<text::XTextRange
> xParagraph
= getParagraph(2);
443 = getProperty
<uno::Reference
<container::XIndexAccess
>>(xParagraph
, "NumberingRules");
444 uno::Sequence
<beans::PropertyValue
> aLevel
;
445 xLevels
->getByIndex(0) >>= aLevel
; // 1st level
447 = std::find_if(std::cbegin(aLevel
), std::cend(aLevel
),
448 [](const beans::PropertyValue
& rValue
) { return rValue
.Name
== "Suffix"; })
449 ->Value
.get
<OUString
>();
450 // Make sure it's empty as the source document contains <w:suff w:val="nothing"/>.
451 CPPUNIT_ASSERT(aSuffix
.isEmpty());
454 DECLARE_OOXMLEXPORT_TEST(testTdf90153
, "tdf90153.docx")
456 // This was at-para, so the line-level VertOrientRelation was lost, resulting in an incorrect vertical position.
457 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER
,
458 getProperty
<text::TextContentAnchorType
>(getShape(1), "AnchorType"));
461 DECLARE_OOXMLEXPORT_TEST(testTdf93919
, "tdf93919.docx")
463 // This was 0, left margin was not inherited from the list style.
464 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1270),
465 getProperty
<sal_Int32
>(getParagraph(1), "ParaLeftMargin"));
468 DECLARE_OOXMLEXPORT_TEST(testTdf91417
, "tdf91417.docx")
470 // The first paragraph should contain a link to "http://www.google.com/"
471 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
472 uno::Reference
<text::XTextCursor
> xTextCursor
= xTextDocument
->getText()->createTextCursor();
473 uno::Reference
<beans::XPropertySet
> xCursorProps(xTextCursor
, uno::UNO_QUERY
);
475 xCursorProps
->getPropertyValue("HyperLinkURL") >>= aValue
;
476 CPPUNIT_ASSERT_EQUAL(OUString("http://www.google.com/"), aValue
);
479 DECLARE_OOXMLEXPORT_TEST(testTdf90810
, "tdf90810short.docx")
481 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
482 uno::Reference
<text::XFootnotesSupplier
> xFootnoteSupp(xTextDocument
, uno::UNO_QUERY
);
483 uno::Reference
<container::XIndexAccess
> xFootnoteIdxAcc
= xFootnoteSupp
->getFootnotes();
484 uno::Reference
<text::XFootnote
> xFootnote(xFootnoteIdxAcc
->getByIndex(0), uno::UNO_QUERY
);
485 uno::Reference
<text::XText
> xFootnoteText(xFootnote
, uno::UNO_QUERY
);
486 OUString sFootnoteText
= xFootnoteText
->getString();
487 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(89), sFootnoteText
.getLength());
490 DECLARE_OOXMLEXPORT_TEST(testTdf89165
, "tdf89165.docx")
492 // This must not hang in layout
495 DECLARE_OOXMLEXPORT_TEST(testTdf95777
, "tdf95777.docx")
497 // This must not fail on open
500 CPPUNIT_TEST_FIXTURE(Test
, testTdf94374
)
502 createSwDoc("hello.docx");
503 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
504 uno::Reference
<text::XTextRange
> xText
= xTextDocument
->getText();
505 uno::Reference
<text::XTextRange
> xEnd
= xText
->getEnd();
506 // This failed: it wasn't possible to insert a DOCX document into an existing Writer one.
507 paste(u
"ooxmlexport/data/tdf94374.docx", "com.sun.star.comp.Writer.WriterFilter", xEnd
);
510 DECLARE_OOXMLEXPORT_TEST(testTdf83300
, "tdf83300.docx")
512 // tdf#143722: This was 'TOC Heading', upon updating a TOC the heading replaced its Word-default blue + Calibri style
513 // with a Writer-default black + Liberation Sans one
514 CPPUNIT_ASSERT_EQUAL(OUString("Contents Heading"),
515 getProperty
<OUString
>(getParagraph(1), "ParaStyleName"));
518 DECLARE_OOXMLEXPORT_TEST(testTdf78902
, "tdf78902.docx")
520 // This hung in layout.
521 CPPUNIT_ASSERT_EQUAL(2, getPages());
524 DECLARE_OOXMLEXPORT_TEST(testTdf95775
, "tdf95775.docx")
526 // This must not fail in layout
529 DECLARE_OOXMLEXPORT_TEST(testTdf92157
, "tdf92157.docx")
531 // A graphic with dimensions 0,0 should not fail on load
533 // Additionally, the bookmark names should not change (they got a "1" appended when copied)
534 uno::Reference
<text::XBookmarksSupplier
> xBookmarksSupplier(mxComponent
, uno::UNO_QUERY
);
535 uno::Reference
<container::XNameAccess
> xBookmarksByName
= xBookmarksSupplier
->getBookmarks();
536 CPPUNIT_ASSERT(xBookmarksByName
->hasByName("referentiegegevens"));
537 CPPUNIT_ASSERT(xBookmarksByName
->hasByName("referentiegegevens_bk"));
540 DECLARE_OOXMLEXPORT_TEST(testTdf97417
, "section_break_numbering.docx")
542 uno::Reference
<beans::XPropertySet
> xProps(getParagraph(1), uno::UNO_QUERY_THROW
);
543 CPPUNIT_ASSERT_MESSAGE("1st page: first paragraph erroneous numbering",
544 !xProps
->getPropertyValue("NumberingRules").hasValue());
545 // paragraph with numbering and section break was removed by writerfilter
546 // but its numbering was copied to all following paragraphs
547 CPPUNIT_ASSERT_MESSAGE(
548 "2nd page: first paragraph missing numbering",
549 getProperty
<uno::Reference
<container::XIndexAccess
>>(getParagraph(2), "NumberingRules")
551 xProps
= uno::Reference
<beans::XPropertySet
>(getParagraph(3), uno::UNO_QUERY_THROW
);
552 CPPUNIT_ASSERT_MESSAGE("2nd page: second paragraph erroneous numbering",
553 !xProps
->getPropertyValue("NumberingRules").hasValue());
555 CPPUNIT_ASSERT_EQUAL(2, getPages());
558 DECLARE_OOXMLEXPORT_TEST(testTdf94043
, "tdf94043.docx")
561 = getProperty
<uno::Reference
<beans::XPropertySet
>>(getParagraph(2), "TextSection");
563 = getProperty
<uno::Reference
<text::XTextColumns
>>(xTextSection
, "TextColumns");
564 // This was 0, the separator line was not visible due to 0 width.
565 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(2),
566 getProperty
<sal_Int32
>(xTextColumns
, "SeparatorLineWidth"));
569 DECLARE_OOXMLEXPORT_TEST(testTdf95213
, "tdf95213.docx")
571 // Get the second paragraph's numbering style's 2nd level's character style name.
572 uno::Reference
<text::XTextRange
> xParagraph
= getParagraph(2);
574 = getProperty
<uno::Reference
<container::XIndexAccess
>>(xParagraph
, "NumberingRules");
575 uno::Sequence
<beans::PropertyValue
> aLevel
;
576 xLevels
->getByIndex(1) >>= aLevel
; // 2nd level
577 OUString aName
= std::find_if(std::cbegin(aLevel
), std::cend(aLevel
),
578 [](const beans::PropertyValue
& rValue
) {
579 return rValue
.Name
== "CharStyleName";
581 ->Value
.get
<OUString
>();
583 uno::Reference
<beans::XPropertySet
> xStyle(getStyles("CharacterStyles")->getByName(aName
),
585 // This was awt::FontWeight::BOLD.
586 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL
, getProperty
<float>(xStyle
, "CharWeight"));
589 DECLARE_OOXMLEXPORT_TEST(testTdf97371
, "tdf97371.docx")
591 SwXTextDocument
* pTextDoc
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
592 CPPUNIT_ASSERT(pTextDoc
);
593 SwDoc
* pDoc
= pTextDoc
->GetDocShell()->GetDoc();
594 SdrPage
* pPage
= pDoc
->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
595 SdrObject
* pShape
= pPage
->GetObj(0);
596 SdrObject
* pTextBox
= pPage
->GetObj(1);
597 tools::Long nDiff
= std::abs(pShape
->GetSnapRect().Top() - pTextBox
->GetSnapRect().Top());
598 // The top of the two shapes were 410 and 3951, now it should be 3950 and 3951.
599 CPPUNIT_ASSERT(nDiff
< 10);
602 CPPUNIT_TEST_FIXTURE(Test
, testTdf99140
)
604 auto verify
= [this]() {
605 // A multi-page floating table appeared only on the first page.
606 SwDoc
* pDoc
= getSwDoc();
607 SwRootFrame
* pLayout
= pDoc
->getIDocumentLayoutAccess().GetCurrentLayout();
608 auto pPage1
= dynamic_cast<SwPageFrame
*>(pLayout
->Lower());
609 CPPUNIT_ASSERT(pPage1
);
610 const SwSortedObjs
& rPage1Objs
= *pPage1
->GetSortedObjs();
611 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage1Objs
.size());
612 auto pPage1Fly
= dynamic_cast<SwFlyAtContentFrame
*>(rPage1Objs
[0]);
613 CPPUNIT_ASSERT(pPage1Fly
);
614 SwFrame
* pTab1
= pPage1Fly
->GetLower();
615 // This was text::HoriOrientation::NONE, the second table was too wide due to this.
616 CPPUNIT_ASSERT_EQUAL(static_cast<tools::Long
>(9622), pTab1
->getFrameArea().Width());
617 SwFrame
* pRow1
= pTab1
->GetLower();
618 SwFrame
* pCell1
= pRow1
->GetLower();
619 auto pText1
= dynamic_cast<SwTextFrame
*>(pCell1
->GetLower());
620 CPPUNIT_ASSERT(pText1
);
621 CPPUNIT_ASSERT_EQUAL(OUString("Table2:A1"), pText1
->GetText());
623 auto pPage2
= dynamic_cast<SwPageFrame
*>(pPage1
->GetNext());
624 CPPUNIT_ASSERT(pPage2
);
625 const SwSortedObjs
& rPage2Objs
= *pPage2
->GetSortedObjs();
626 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage2Objs
.size());
627 auto pPage2Fly
= dynamic_cast<SwFlyAtContentFrame
*>(rPage2Objs
[0]);
628 CPPUNIT_ASSERT(pPage2Fly
);
629 SwFrame
* pTab2
= pPage2Fly
->GetLower();
630 SwFrame
* pRow2
= pTab2
->GetLower();
631 SwFrame
* pCell2
= pRow2
->GetLower();
632 auto pText2
= dynamic_cast<SwTextFrame
*>(pCell2
->GetLower());
633 CPPUNIT_ASSERT(pText2
);
634 CPPUNIT_ASSERT_EQUAL(OUString("Table2:A2"), pText2
->GetText());
636 createSwDoc("tdf99140.docx");
638 saveAndReload("Office Open XML Text");
642 CPPUNIT_TEST_FIXTURE(Test
, testTableMarginAdjustment
)
644 loadAndReload("table.fodt");
645 // Writer, (new) Word: margin 0 means table border starts at 0
646 // (old) Word: margin 0 means paragraph in table starts at 0
648 auto const xTable(getParagraphOrTable(1));
649 // shifted very slightly to account for half of the thin border width, so 4, not 0.
650 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), getProperty
<sal_Int32
>(xTable
, "LeftMargin"));
652 // Now that compatibilityMode is set to 2013's 15 (new), expect the new values,
653 // since LO is exporting in the NEW way now instead of the OLD way.
654 // This was 55 when using 2007's compatibilityMode of 12 (old)
656 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
658 assertXPath(pXmlDoc
, "//w:tbl[1]/w:tblPr[1]/w:tblInd[1]", "type", "dxa");
659 assertXPath(pXmlDoc
, "//w:tbl[1]/w:tblPr[1]/w:tblInd[1]", "w", "0");
661 // tdf#143982: automatic tables should export as something better than just left-and-size
662 CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty
<sal_Int16
>(xTable
, "RelativeWidth"));
665 DECLARE_OOXMLEXPORT_TEST(testTdf119760_tableInTablePosition
, "tdf119760_tableInTablePosition.docx")
669 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
671 assertXPath(pXmlDoc
, "//w:tbl[1]/w:tr[1]/w:tc[1]/w:tbl[1]/w:tblPr[1]/w:tblInd[1]", "type",
673 assertXPath(pXmlDoc
, "//w:tbl[1]/w:tr[1]/w:tc[1]/w:tbl[1]//w:tblPr[1]/w:tblInd[1]", "w",
677 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
678 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
680 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
681 // For compatibilityMode 15: margin 0 means table border starts at 0,
682 // shifted to account for half of the thick border width, so 106, not 0.
683 CPPUNIT_ASSERT_EQUAL(sal_Int32(106), getProperty
<sal_Int32
>(xTable
, "LeftMargin"));
686 DECLARE_OOXMLEXPORT_TEST(testTableCellMargin
, "table-cell-margin.docx")
688 sal_Int32
const cellLeftMarginFromOffice
[] = { 250, 100, 0, 0 };
690 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
691 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
694 for (int i
= 0; i
< 4; i
++)
696 uno::Reference
<text::XTextTable
> xTable1(xTables
->getByIndex(i
), uno::UNO_QUERY
);
698 // Verify left margin of 1st cell :
699 // * Office left margins are measured relative to the right of the border
700 // * LO left spacing is measured from the center of the border
701 uno::Reference
<table::XCell
> xCell
= xTable1
->getCellByName("A1");
702 uno::Reference
<beans::XPropertySet
> xPropSet(xCell
, uno::UNO_QUERY_THROW
);
703 sal_Int32 aLeftMargin
= -1;
704 xPropSet
->getPropertyValue("LeftBorderDistance") >>= aLeftMargin
;
705 uno::Any aLeftBorder
= xPropSet
->getPropertyValue("LeftBorder");
706 table::BorderLine2 aLeftBorderLine
;
707 aLeftBorder
>>= aLeftBorderLine
;
708 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
709 "Incorrect left spacing computed from docx cell margin", cellLeftMarginFromOffice
[i
],
710 aLeftMargin
- 0.5 * aLeftBorderLine
.LineWidth
, 1);
711 // The 'a' in the fourth table should not be partly hidden by the border
714 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect cell left padding",
715 0.5 * aLeftBorderLine
.LineWidth
, aLeftMargin
, 1);
716 // tdf#119885: cell's edit area must touch right border
717 sal_Int32 aRightMargin
= -1;
718 xPropSet
->getPropertyValue("RightBorderDistance") >>= aRightMargin
;
719 uno::Any aRightBorder
= xPropSet
->getPropertyValue("RightBorder");
720 table::BorderLine2 aRightBorderLine
;
721 aRightBorder
>>= aRightBorderLine
;
722 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect cell right padding",
723 0.5 * aRightBorderLine
.LineWidth
, aRightMargin
, 1);
728 CPPUNIT_TEST_FIXTURE(Test
, TestPuzzleExport
)
730 loadAndReload("TestPuzzleExport.odt");
731 // See tdf#148342 for details
733 uno::Reference
<text::XTextDocument
> xTextDoc(mxComponent
, uno::UNO_QUERY_THROW
);
734 auto pSwDoc
= dynamic_cast<SwXTextDocument
*>(xTextDoc
.get());
735 CPPUNIT_ASSERT(pSwDoc
);
737 auto pMeta
= pSwDoc
->GetDocShell()->GetPreviewMetaFile();
738 CPPUNIT_ASSERT(pMeta
);
739 MetafileXmlDump aDumper
;
740 auto pMetaXml
= dumpAndParse(aDumper
, *pMeta
);
741 CPPUNIT_ASSERT(pMetaXml
);
742 // After parsing check that node...
744 = getXPathNode(pMetaXml
, "/metafile/push/push/push/push[4]/push/push/polypolygon/polygon");
745 CPPUNIT_ASSERT(pXNode
);
746 auto pNode
= pXNode
->nodesetval
->nodeTab
[0];
747 CPPUNIT_ASSERT(pNode
);
748 auto it
= pNode
->children
;
750 // .. and count the children
751 while (it
!= nullptr)
756 // In case of puzzle there will be so many... Without the fix there was a rectangle with 4 points.
757 CPPUNIT_ASSERT_GREATER(300, nCount
);
760 // tdf#106742 for DOCX with compatibility level <= 14 (MS Word up to and incl. ver.2010), we should use cell margins when calculating table left border position
761 DECLARE_OOXMLEXPORT_TEST(testTablePosition14
, "table-position-14.docx")
763 sal_Int32
const aXCoordsFromOffice
[] = { 2500, -1000, 0, 0 };
765 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
766 uno::Reference
<frame::XModel
> xModel(mxComponent
, uno::UNO_QUERY
);
767 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
770 for (int i
= 0; i
< 4; i
++)
772 uno::Reference
<text::XTextTable
> xTable1(xTables
->getByIndex(i
), uno::UNO_QUERY
);
775 uno::Reference
<view::XSelectionSupplier
> xCtrl(xModel
->getCurrentController(),
777 xCtrl
->select(uno::Any(xTable1
));
778 uno::Reference
<text::XTextViewCursorSupplier
> xTextViewCursorSupplier(xCtrl
,
780 uno::Reference
<text::XTextViewCursor
> xCursor
= xTextViewCursorSupplier
->getViewCursor();
781 awt::Point pos
= xCursor
->getPosition();
782 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect X coord computed from docx",
783 aXCoordsFromOffice
[i
], pos
.X
, 1);
787 // tdf#106742 for DOCX with compatibility level > 14 (MS Word since ver.2013),
788 // we should NOT use cell margins when calculating table left border position. But we do need to use border width.
789 DECLARE_OOXMLEXPORT_TEST(testTablePosition15
, "table-position-15.docx")
791 sal_Int32
const aXCoordsFromOffice
[] = { 2751, -899, 1, 212 };
793 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
794 uno::Reference
<frame::XModel
> xModel(mxComponent
, uno::UNO_QUERY
);
795 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
798 for (int i
= 0; i
< 4; i
++)
800 uno::Reference
<text::XTextTable
> xTable1(xTables
->getByIndex(i
), uno::UNO_QUERY
);
803 uno::Reference
<view::XSelectionSupplier
> xCtrl(xModel
->getCurrentController(),
805 xCtrl
->select(uno::Any(xTable1
));
806 uno::Reference
<text::XTextViewCursorSupplier
> xTextViewCursorSupplier(xCtrl
,
808 uno::Reference
<text::XTextViewCursor
> xCursor
= xTextViewCursorSupplier
->getViewCursor();
809 awt::Point pos
= xCursor
->getPosition();
810 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect X coord computed from docx",
811 aXCoordsFromOffice
[i
], pos
.X
, 1);
815 DECLARE_OOXMLEXPORT_TEST(testTdf107359
, "tdf107359-char-pitch.docx")
817 uno::Reference
<beans::XPropertySet
> xPropertySet(getStyles("PageStyles")->getByName("Standard"),
820 bool bGridSnapToChars
;
821 xPropertySet
->getPropertyValue("GridSnapToChars") >>= bGridSnapToChars
;
822 CPPUNIT_ASSERT_EQUAL(false, bGridSnapToChars
);
824 sal_Int32 nRubyHeight
;
825 xPropertySet
->getPropertyValue("GridRubyHeight") >>= nRubyHeight
;
826 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nRubyHeight
);
828 sal_Int32 nBaseHeight
;
829 xPropertySet
->getPropertyValue("GridBaseHeight") >>= nBaseHeight
;
830 CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(18 * 20)), nBaseHeight
);
832 sal_Int32 nBaseWidth
;
833 xPropertySet
->getPropertyValue("GridBaseWidth") >>= nBaseWidth
;
834 CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(24 * 20)), nBaseWidth
);
837 CPPUNIT_TEST_FIXTURE(Test
, testTdf77236_MissingSolidFill
)
839 loadAndSave("tdf77236_MissingSolidFill.docx");
840 // tdf#77236: solidFill of VML shape was not exported if the colors of line and style were the same
841 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
844 "//mc:Choice/w:drawing/wp:inline/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:solidFill",
848 DECLARE_OOXMLEXPORT_TEST(testTdf105875_VmlShapeRotationWithFlip
,
849 "tdf105875_VmlShapeRotationWithFlip.docx")
851 // tdf#105875: check whether the rotation of the VML bezier shape is ok (with flip too)
852 // TODO: fix export too
857 uno::Reference
<beans::XPropertySet
> xPropertySet(getShape(1), uno::UNO_QUERY_THROW
);
858 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
859 xPropertySet
->getPropertyValue("RotateAngle").get
<sal_Int32
>());
863 uno::Reference
<beans::XPropertySet
> xPropertySet(getShape(2), uno::UNO_QUERY_THROW
);
864 CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(220 * 100),
865 xPropertySet
->getPropertyValue("RotateAngle").get
<sal_Int32
>(),
870 uno::Reference
<beans::XPropertySet
> xPropertySet(getShape(3), uno::UNO_QUERY_THROW
);
871 CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(320 * 100),
872 xPropertySet
->getPropertyValue("RotateAngle").get
<sal_Int32
>(),
877 uno::Reference
<beans::XPropertySet
> xPropertySet(getShape(4), uno::UNO_QUERY_THROW
);
878 CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(140 * 100),
879 xPropertySet
->getPropertyValue("RotateAngle").get
<sal_Int32
>(),
884 uno::Reference
<beans::XPropertySet
> xPropertySet(getShape(5), uno::UNO_QUERY_THROW
);
885 CPPUNIT_ASSERT_DOUBLES_EQUAL(
886 sal_Int32(40 * 100), xPropertySet
->getPropertyValue("RotateAngle").get
<sal_Int32
>(), 1);
890 CPPUNIT_TEST_FIXTURE(Test
, testTdf133363
)
892 loadAndSave("tdf133363.docx");
893 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
894 // tdf#133363: remove extra auto space between first and second list elements
895 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p[2]/w:pPr/w:spacing", "before",
897 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p[3]/w:pPr/w:spacing", "after",
901 DECLARE_OOXMLEXPORT_TEST(testTdf138093
, "tdf138093.docx")
905 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
906 assertXPath(pXmlDoc
, "//w:sdt", 3);
907 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
908 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
910 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
911 uno::Reference
<table::XCell
> xCell
= xTable
->getCellByName("B1");
912 uno::Reference
<container::XEnumerationAccess
> xParagraphsAccess(xCell
, uno::UNO_QUERY
);
913 uno::Reference
<container::XEnumeration
> xParagraphs
914 = xParagraphsAccess
->createEnumeration();
915 uno::Reference
<container::XEnumerationAccess
> xParagraph(xParagraphs
->nextElement(),
917 uno::Reference
<container::XEnumeration
> xPortions
= xParagraph
->createEnumeration();
918 uno::Reference
<beans::XPropertySet
> xTextPortion(xPortions
->nextElement(), uno::UNO_QUERY
);
920 OUString aPortionType
;
921 xTextPortion
->getPropertyValue("TextPortionType") >>= aPortionType
;
922 CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType
);
924 uno::Reference
<text::XTextContent
> xContentControl
;
925 xTextPortion
->getPropertyValue("ContentControl") >>= xContentControl
;
926 uno::Reference
<beans::XPropertySet
> xContentControlProps(xContentControl
, uno::UNO_QUERY
);
928 xContentControlProps
->getPropertyValue("Date") >>= bDate
;
929 CPPUNIT_ASSERT(bDate
);
930 uno::Reference
<container::XEnumerationAccess
> xContentControlEnumAccess(xContentControl
,
932 uno::Reference
<container::XEnumeration
> xContentControlEnum
933 = xContentControlEnumAccess
->createEnumeration();
934 uno::Reference
<text::XTextRange
> xTextPortionRange(xContentControlEnum
->nextElement(),
936 CPPUNIT_ASSERT_EQUAL(OUString("2017"), xTextPortionRange
->getString());
940 SwXTextDocument
* pTextDoc
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
941 CPPUNIT_ASSERT(pTextDoc
);
942 SwDoc
* pDoc
= pTextDoc
->GetDocShell()->GetDoc();
943 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
944 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess
->getAllMarksCount());
946 ::sw::mark::IDateFieldmark
* pFieldmark
947 = dynamic_cast<::sw::mark::IDateFieldmark
*>(*pMarkAccess
->getAllMarksBegin());
948 CPPUNIT_ASSERT(pFieldmark
);
949 CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE
), pFieldmark
->GetFieldname());
950 CPPUNIT_ASSERT_EQUAL(OUString("2017"), pFieldmark
->GetContent());
954 DECLARE_OOXMLEXPORT_TEST(testTdf131722
, "tdf131722.docx")
958 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
959 assertXPath(pXmlDoc
, "//w:sdt", 4);
960 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
961 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
963 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
964 uno::Reference
<table::XCell
> xCell
= xTable
->getCellByName("A1");
965 uno::Reference
<container::XEnumerationAccess
> xParagraphsAccess(xCell
, uno::UNO_QUERY
);
966 uno::Reference
<container::XEnumeration
> xParagraphs
967 = xParagraphsAccess
->createEnumeration();
968 uno::Reference
<container::XEnumerationAccess
> xParagraph(xParagraphs
->nextElement(),
970 uno::Reference
<container::XEnumeration
> xPortions
= xParagraph
->createEnumeration();
971 uno::Reference
<beans::XPropertySet
> xTextPortion(xPortions
->nextElement(), uno::UNO_QUERY
);
973 OUString aPortionType
;
974 xTextPortion
->getPropertyValue("TextPortionType") >>= aPortionType
;
975 CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType
);
977 uno::Reference
<text::XTextContent
> xContentControl
;
978 xTextPortion
->getPropertyValue("ContentControl") >>= xContentControl
;
979 uno::Reference
<beans::XPropertySet
> xContentControlProps(xContentControl
, uno::UNO_QUERY
);
981 xContentControlProps
->getPropertyValue("Date") >>= bDate
;
982 CPPUNIT_ASSERT(bDate
);
983 uno::Reference
<container::XEnumerationAccess
> xContentControlEnumAccess(xContentControl
,
985 uno::Reference
<container::XEnumeration
> xContentControlEnum
986 = xContentControlEnumAccess
->createEnumeration();
987 uno::Reference
<text::XTextRange
> xTextPortionRange(xContentControlEnum
->nextElement(),
989 CPPUNIT_ASSERT_EQUAL(OUString("Enter a date here!"), xTextPortionRange
->getString());
993 SwXTextDocument
* pTextDoc
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
994 CPPUNIT_ASSERT(pTextDoc
);
995 SwDoc
* pDoc
= pTextDoc
->GetDocShell()->GetDoc();
996 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
997 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess
->getFieldmarksCount());
999 for (auto aIter
= pMarkAccess
->getFieldmarksBegin();
1000 aIter
!= pMarkAccess
->getFieldmarksEnd(); ++aIter
)
1002 ::sw::mark::IDateFieldmark
* pFieldmark
1003 = dynamic_cast<::sw::mark::IDateFieldmark
*>(*aIter
);
1004 CPPUNIT_ASSERT(pFieldmark
);
1005 CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE
), pFieldmark
->GetFieldname());
1006 CPPUNIT_ASSERT_EQUAL(OUString("Enter a date here!"), pFieldmark
->GetContent());
1011 CPPUNIT_TEST_FIXTURE(Test
, testTdf155945
)
1013 createSwDoc("tdf155945.docx");
1015 CPPUNIT_ASSERT_EQUAL(3, getParagraphs());
1016 // Without a fix in place, this would fail with
1019 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty
<sal_Int32
>(getParagraph(2), "ParaBottomMargin"));
1022 CPPUNIT_TEST_FIXTURE(Test
, testTdf133560
)
1024 createSwDoc("lastEmptyLineWithDirectFormatting.docx");
1026 CPPUNIT_ASSERT_EQUAL(4, getParagraphs());
1027 // Without a fix in place, this would fail with
1030 CPPUNIT_ASSERT_EQUAL(12.0f
, getProperty
<float>(getParagraph(4), "CharHeight"));
1033 DECLARE_OOXMLEXPORT_TEST(testTdf156372
, "tdf156372.doc")
1035 sal_Int32 nHeight
= parseDump("//page[1]/header/tab/row[1]/infos/bounds", "height").toInt32();
1036 // Without a fix in place, this would fail with
1039 CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(847), nHeight
, 5);
1041 CPPUNIT_ASSERT_EQUAL(1, getPages());
1044 CPPUNIT_TEST_FIXTURE(Test
, testTdf156548
)
1046 // Given a document using two bookmarks with similar names longer than 40 characters
1047 loadAndReload("longBookmarkName.fodt");
1049 // After the export, the names must be no longer than 40 characters; they must be unique;
1050 // and the hyperlinks must use the same names, to still point to the correct targets:
1053 // 1st paragraph - hyperlink to 4th paragraph
1054 auto sURL
= getProperty
<OUString
>(getRun(getParagraph(1), 1), "HyperLinkURL");
1055 CPPUNIT_ASSERT_EQUAL(OUString("#A_bookmark_name_longer_than_forty_charac"), sURL
);
1056 // 4th paragraph - a bookmark
1057 auto xBookmark
= getProperty
<uno::Reference
<container::XNamed
>>(getRun(getParagraph(4), 1),
1059 CPPUNIT_ASSERT_EQUAL(OUString("A_bookmark_name_longer_than_forty_charac"),
1060 xBookmark
->getName());
1064 // 2nd paragraph - hyperlink to 5th paragraph
1065 auto sURL
= getProperty
<OUString
>(getRun(getParagraph(2), 1), "HyperLinkURL");
1066 CPPUNIT_ASSERT_EQUAL(OUString("#A_bookmark_name_longer_than_forty_chara1"), sURL
);
1067 // 5th paragraph - a bookmark
1068 auto xBookmark
= getProperty
<uno::Reference
<container::XNamed
>>(getRun(getParagraph(5), 1),
1070 CPPUNIT_ASSERT_EQUAL(OUString("A_bookmark_name_longer_than_forty_chara1"),
1071 xBookmark
->getName());
1075 CPPUNIT_TEST_FIXTURE(Test
, testTdf157136
)
1077 // Given a document with two content controls - one block, one inline
1078 createSwDoc("tdf157136_TwoContentControls.docx");
1080 // Both of them must import with the correct character style
1083 // 1st paragraph - block content control
1084 auto xRun
= getRun(getParagraph(1), 1);
1085 CPPUNIT_ASSERT_EQUAL(OUString("Click or tap here to enter text.\r"), xRun
->getString());
1086 // Without the fix in place, this would fail with
1087 // - Expected: Placeholder Text
1089 CPPUNIT_ASSERT_EQUAL(OUString("Placeholder Text"),
1090 getProperty
<OUString
>(xRun
, "CharStyleName"));
1094 // 2nd paragraph - inline content control
1095 auto xRun
= getRun(getParagraph(2), 1);
1096 auto xContentControl
1097 = getProperty
<css::uno::Reference
<css::text::XTextRange
>>(xRun
, "ContentControl");
1098 CPPUNIT_ASSERT_EQUAL(OUString("Click or tap here to enter text."),
1099 xContentControl
->getString());
1100 CPPUNIT_ASSERT_EQUAL(OUString("Placeholder Text"),
1101 getProperty
<OUString
>(xRun
, "CharStyleName"));
1104 // Test the same after round-trip
1105 saveAndReload("Office Open XML Text");
1108 // 1st paragraph - becomes inline content control after roundtrip
1109 auto xRun
= getRun(getParagraph(1), 1);
1110 auto xContentControl
1111 = getProperty
<css::uno::Reference
<css::text::XTextRange
>>(xRun
, "ContentControl");
1112 CPPUNIT_ASSERT_EQUAL(OUString("Click or tap here to enter text."),
1113 xContentControl
->getString());
1114 CPPUNIT_ASSERT_EQUAL(OUString("Placeholder Text"),
1115 getProperty
<OUString
>(xRun
, "CharStyleName"));
1119 // 2nd paragraph - inline content control
1120 auto xRun
= getRun(getParagraph(2), 1);
1121 auto xContentControl
1122 = getProperty
<css::uno::Reference
<css::text::XTextRange
>>(xRun
, "ContentControl");
1123 CPPUNIT_ASSERT_EQUAL(OUString("Click or tap here to enter text."),
1124 xContentControl
->getString());
1125 CPPUNIT_ASSERT_EQUAL(OUString("Placeholder Text"),
1126 getProperty
<OUString
>(xRun
, "CharStyleName"));
1130 CPPUNIT_PLUGIN_IMPLEMENT();
1132 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */