Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / qa / extras / ww8export / ww8export2.cxx
blob51544b956abefa08aa59320c0a52b5acbe3dc8e9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <swmodeltestbase.hxx>
12 #include <com/sun/star/beans/XPropertySet.hpp>
13 #include <com/sun/star/container/XIndexAccess.hpp>
14 #include <com/sun/star/style/ParagraphAdjust.hpp>
15 #include <com/sun/star/text/HoriOrientation.hpp>
16 #include <com/sun/star/text/WritingMode2.hpp>
17 #include <com/sun/star/text/XDependentTextField.hpp>
18 #include <com/sun/star/text/XTextTable.hpp>
19 #include <com/sun/star/text/XTextTablesSupplier.hpp>
20 #include <com/sun/star/text/XFootnote.hpp>
21 #include <com/sun/star/drawing/XControlShape.hpp>
22 #include <com/sun/star/text/VertOrientation.hpp>
23 #include <com/sun/star/text/WrapTextMode.hpp>
24 #include <com/sun/star/text/TextContentAnchorType.hpp>
25 #include <com/sun/star/text/XFootnotesSupplier.hpp>
26 #include <com/sun/star/text/XEndnotesSupplier.hpp>
28 #include <svx/svdpage.hxx>
29 #include <o3tl/string_view.hxx>
31 #include <ftninfo.hxx>
32 #include <drawdoc.hxx>
33 #include <IDocumentDrawModelAccess.hxx>
34 #include <docsh.hxx>
35 #include <unotxdoc.hxx>
36 #include <IDocumentLayoutAccess.hxx>
37 #include <rootfrm.hxx>
38 #include <pagefrm.hxx>
39 #include <sortedobjs.hxx>
40 #include <cntfrm.hxx>
41 #include <anchoredobject.hxx>
42 #include <tabfrm.hxx>
43 #include <flyfrms.hxx>
45 class Test : public SwModelTestBase
47 public:
48 Test() : SwModelTestBase("/sw/qa/extras/ww8export/data/", "MS Word 97") {}
51 DECLARE_WW8EXPORT_TEST(testTdf99120, "tdf99120.doc")
53 CPPUNIT_ASSERT_EQUAL(OUString("Section 1, odd."), parseDump("/root/page[1]/header/txt/text()"));
54 CPPUNIT_ASSERT_EQUAL(OUString("Section 1, even."), parseDump("/root/page[2]/header/txt/text()"));
55 // This failed: the header was empty on the 3rd page, as the first page header was shown.
56 CPPUNIT_ASSERT_EQUAL(OUString("Section 2, odd."), parseDump("/root/page[3]/header/txt/text()"));
57 CPPUNIT_ASSERT_EQUAL(OUString("Section 2, even."), parseDump("/root/page[4]/header/txt/text()"));
60 CPPUNIT_TEST_FIXTURE(Test, testTdf41542_borderlessPadding)
62 loadAndReload("tdf41542_borderlessPadding.odt");
63 // the page style's borderless padding should force this to 3 pages, not 1
64 CPPUNIT_ASSERT_EQUAL( 3, getPages() );
67 DECLARE_WW8EXPORT_TEST(testTdf60378_mergedBorders, "tdf60378_mergedBorders.doc")
69 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
70 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
71 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
73 // The border width was zero
74 table::BorderLine2 aBorder = getProperty<table::BorderLine2>(xTable->getCellByName("B2"), "RightBorder");
75 CPPUNIT_ASSERT(aBorder.LineWidth > 0);
78 DECLARE_WW8EXPORT_TEST(testTdf55528_relativeTableWidth, "tdf55528_relativeTableWidth.doc")
81 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
82 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
83 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
85 CPPUNIT_ASSERT_EQUAL_MESSAGE("Table relative width percent", sal_Int16(98), getProperty<sal_Int16>(xTable, "RelativeWidth"));
88 CPPUNIT_TEST_FIXTURE(Test, testTdf128700_relativeTableWidth)
90 auto verify = [this]() {
91 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
92 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
93 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
95 // Since the table has been converted into a floating frame, the relative width either needed to be transferred
96 // onto the frame, or else just thrown out. Otherwise it becomes relative to the size of the frame.
97 CPPUNIT_ASSERT_EQUAL_MESSAGE("Floated table can't use relative width", sal_Int16(0), getProperty<sal_Int16>(xTable, "RelativeWidth"));
99 // This also resulted in a layout loop when flys were allowed to split in footers.
100 createSwDoc("tdf128700_relativeTableWidth.doc");
101 verify();
102 saveAndReload("MS Word 97");
103 verify();
106 CPPUNIT_TEST_FIXTURE(Test, testTdf116436_tableBackground)
108 loadAndReload("tdf116436_tableBackground.odt");
109 CPPUNIT_ASSERT_EQUAL(1, getPages());
110 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
111 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
112 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
113 uno::Reference<table::XCell> xCell = xTable->getCellByName("A1");
114 CPPUNIT_ASSERT_EQUAL(Color(0xF8DF7C), getProperty<Color>(xCell, "BackColor"));
115 xCell.set(xTable->getCellByName("A6"));
116 CPPUNIT_ASSERT_EQUAL(Color(0x81D41A), getProperty<Color>(xCell, "BackColor"));
117 xCell.set(xTable->getCellByName("B6"));
118 CPPUNIT_ASSERT_EQUAL(Color(0xFFFBCC), getProperty<Color>(xCell, "BackColor"));
121 DECLARE_WW8EXPORT_TEST(testTdf37153, "tdf37153_considerWrapOnObjPos.doc")
123 CPPUNIT_ASSERT_EQUAL(text::WrapTextMode_THROUGH, getProperty<text::WrapTextMode>(getShape(1), "Surround"));
125 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
126 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
127 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
128 CPPUNIT_ASSERT_EQUAL(text::VertOrientation::BOTTOM, getProperty<sal_Int16>(xTable->getCellByName("A1"), "VertOrient"));
130 //For MSO compatibility, the image should be at the top of the cell, not at the bottom - despite VertOrientation::BOTTOM
131 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
132 sal_Int32 nFlyTop = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/txt/anchored/fly/infos/bounds", "top").toInt32();
133 CPPUNIT_ASSERT_MESSAGE("FlyTop should be 3820, not 6623", nFlyTop < 4000);
134 sal_Int32 nTextTop = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[2]/txt[1]/infos/bounds", "top").toInt32();
135 CPPUNIT_ASSERT_MESSAGE("TextTop should be 5388", nTextTop > 4000);
138 DECLARE_WW8EXPORT_TEST(testTdf49102_mergedCellNumbering, "tdf49102_mergedCellNumbering.doc")
140 CPPUNIT_ASSERT_EQUAL( OUString("2."), parseDump("/root/page/body/tab/row[4]/cell/txt/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", "expand") );
143 CPPUNIT_TEST_FIXTURE(Test, testTdf55427_footnote2endnote)
145 loadAndReload("tdf55427_footnote2endnote.odt");
146 uno::Reference<beans::XPropertySet> xPageStyle(getStyles("ParagraphStyles")->getByName("Footnote"), uno::UNO_QUERY);
147 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Footnote style is rose color", Color(0xFF007F), getProperty< Color >(xPageStyle, "CharColor"));
148 xPageStyle.set(getStyles("ParagraphStyles")->getByName("Endnote"), uno::UNO_QUERY);
149 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Endnote style is cyan3 color", Color(0x2BD0D2), getProperty< Color >(xPageStyle, "CharColor"));
151 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
152 CPPUNIT_ASSERT(pTextDoc);
153 SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
154 // The footnote numbering type of ARABIC will not transfer over when those footnotes are converted to endnotes.
155 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Footnote numbering type", SVX_NUM_ARABIC, pDoc->GetFootnoteInfo().m_aFormat.GetNumberingType() );
156 // The original document has a real endnote using ROMAN_LOWER numbering, so that setting MUST remain unchanged.
157 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Endnote numbering type", SVX_NUM_ROMAN_LOWER, pDoc->GetEndNoteInfo().m_aFormat.GetNumberingType() );
159 uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
160 uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
162 uno::Reference<text::XEndnotesSupplier> xEndnotesSupplier(mxComponent, uno::UNO_QUERY);
163 uno::Reference<container::XIndexAccess> xEndnotes = xEndnotesSupplier->getEndnotes();
164 uno::Reference<text::XFootnote> xEndnote;
165 xEndnotes->getByIndex(0) >>= xEndnote;
166 uno::Reference<text::XText> xEndnoteText;
167 xEndnotes->getByIndex(0) >>= xEndnoteText;
169 // ODT footnote-at-document-end's closest DOC match is an endnote, so the two imports will not exactly match by design.
170 if (!isExported())
172 CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote count", sal_Int32(5), xFootnotes->getCount() );
173 CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote count", sal_Int32(1), xEndnotes->getCount() );
175 uno::Reference<text::XFootnote> xFootnote;
176 xFootnotes->getByIndex(0) >>= xFootnote;
177 CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote's number", OUString("1"), xFootnote->getAnchor()->getString() );
178 CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote's number", OUString("i"), xEndnote->getAnchor()->getString() );
180 uno::Reference<text::XText> xFootnoteText;
181 xFootnotes->getByIndex(0) >>= xFootnoteText;
182 CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote style", OUString("Footnote"), getProperty<OUString>(getParagraphOfText(1, xFootnoteText), "ParaStyleName") );
183 CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote style", OUString("Endnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
185 else
187 // These asserted items are major differences in the conversion from footnote to endnote, NOT necessary conditions for a proper functioning document.
188 CPPUNIT_ASSERT_EQUAL_MESSAGE( "At-Document-End footnotes were converted into endnotes", sal_Int32(0), xFootnotes->getCount() );
189 CPPUNIT_ASSERT_EQUAL_MESSAGE( "At-Document-End footnotes became endnotes", sal_Int32(6), xEndnotes->getCount() );
191 CPPUNIT_ASSERT_EQUAL_MESSAGE( "converted footnote's number", OUString("i"), xEndnote->getAnchor()->getString() );
192 xEndnotes->getByIndex(4) >>= xEndnote;
193 CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote's new number", OUString("v"), xEndnote->getAnchor()->getString() );
195 CPPUNIT_ASSERT_EQUAL_MESSAGE( "retained footnote style", OUString("Footnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
196 xEndnotes->getByIndex(4) >>= xEndnoteText;
197 CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote style", OUString("Endnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
201 DECLARE_WW8EXPORT_TEST(testTdf107931_KERN_DocEnabled_disabledDefStyle, "testTdf107931_KERN_DocEnabled_disabledDefStyle.doc")
203 // Paragraph 3: the default style has kerning disabled
204 CPPUNIT_ASSERT(!getProperty<bool>(getRun(getParagraph(3), 1), "CharAutoKerning"));
205 // Paragraph 4: style with kerning disabled
206 CPPUNIT_ASSERT(!getProperty<bool>(getRun(getParagraph(4), 1), "CharAutoKerning"));
207 // Paragraph 5: style with kerning enabled
208 CPPUNIT_ASSERT(getProperty<bool>(getRun(getParagraph(5), 1), "CharAutoKerning"));
209 // Paragraph 6: directly applied character properties: kerning disabled
210 CPPUNIT_ASSERT(!getProperty<bool>(getRun(getParagraph(6), 1), "CharAutoKerning"));
211 // Paragraph 7: directly applied character properties: kerning enabled
212 CPPUNIT_ASSERT(getProperty<bool>(getRun(getParagraph(7), 1), "CharAutoKerning"));
215 DECLARE_WW8EXPORT_TEST(testTdf107931_KERN_enabledDefStyle, "testTdf107931_KERN_enabledDefStyle.doc")
217 // Paragraph 3: the default style has kerning enabled
218 CPPUNIT_ASSERT(getProperty<bool>(getRun(getParagraph(3), 1), "CharAutoKerning"));
219 // Paragraph 4: style with kerning disabled
220 CPPUNIT_ASSERT(!getProperty<bool>(getRun(getParagraph(4), 1), "CharAutoKerning"));
221 // Paragraph 5: style with kerning enabled
222 CPPUNIT_ASSERT(getProperty<bool>(getRun(getParagraph(5), 1), "CharAutoKerning"));
223 // Paragraph 6: directly applied character properties: kerning disabled
224 CPPUNIT_ASSERT(!getProperty<bool>(getRun(getParagraph(6), 1), "CharAutoKerning"));
225 // Paragraph 7: directly applied character properties: kerning enabled
226 CPPUNIT_ASSERT(getProperty<bool>(getRun(getParagraph(7), 1), "CharAutoKerning"));
229 DECLARE_WW8EXPORT_TEST(testTdf89377, "tdf89377_tableWithBreakBeforeParaStyle.doc")
231 // the paragraph style should set table's text-flow break-before-page
232 CPPUNIT_ASSERT_EQUAL( 2, getPages() );
235 DECLARE_WW8EXPORT_TEST(testTdf96277, "tdf96277.doc")
237 // mismatch between anchoring at paragraph and ULSpacing to Page
238 CPPUNIT_ASSERT_EQUAL( 1, getPages() );
241 DECLARE_WW8EXPORT_TEST(testBnc863018b, "bnc863018b.doc")
243 // The whitespace above the table should allow text to flow between the table anchor and the table.
244 // Since it doesn't, don't add the whitespace.
245 CPPUNIT_ASSERT_EQUAL( 1, getPages() );
248 DECLARE_WW8EXPORT_TEST(testTdf112517_maxSprms, "tdf112517_maxSprms.doc")
250 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
251 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
252 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
253 CPPUNIT_ASSERT_EQUAL( sal_Int32(28), xTable->getRows()->getCount() );
256 CPPUNIT_TEST_FIXTURE(Test, testTdf108448_endNote)
258 loadAndReload("tdf108448_endNote.odt");
259 CPPUNIT_ASSERT_EQUAL(1, getPages());
260 uno::Reference<text::XEndnotesSupplier> xEndnotesSupplier(mxComponent, uno::UNO_QUERY);
261 uno::Reference<container::XIndexAccess> xEndnotes = xEndnotesSupplier->getEndnotes();
262 uno::Reference<text::XText> xEndnote;
263 xEndnotes->getByIndex(0) >>= xEndnote;
265 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of paragraphs in Endnote i", 1, getParagraphs(xEndnote) );
268 CPPUNIT_TEST_FIXTURE(Test, testTdf106062_nonHangingFootnote)
270 loadAndReload("tdf106062_nonHangingFootnote.odt");
271 CPPUNIT_ASSERT_EQUAL(1, getPages());
272 uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
273 uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
274 uno::Reference<text::XTextRange> xTextRange(xFootnotes->getByIndex(0), uno::UNO_QUERY);
275 // This failed, tab between the footnote number and the footnote content was lost on import.
276 CPPUNIT_ASSERT_MESSAGE( "Footnote starts with a tab", xTextRange->getString().startsWith("\t") );
279 CPPUNIT_TEST_FIXTURE(Test, testTdf116570_exportFootnote)
281 loadAndReload("tdf116570_exportFootnote.odt");
282 CPPUNIT_ASSERT_EQUAL(1, getPages());
283 uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
284 uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
285 uno::Reference<text::XText> xFootnoteText;
286 xFootnotes->getByIndex(0) >>= xFootnoteText;
288 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of paragraphs in first footnote", 2, getParagraphs(xFootnoteText) );
291 CPPUNIT_TEST_FIXTURE(Test, testTdf80635_pageRightRTL)
293 auto verify = [this]() {
294 // tdf#80635 - assert horizontal position of the table.
295 uno::Reference<drawing::XShape> xFly = getShape(1);
296 CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(xFly, "HoriOrientRelation"));
297 CPPUNIT_ASSERT_EQUAL_MESSAGE("Horizontal Orientation", text::HoriOrientation::RIGHT, getProperty<sal_Int16>(xFly, "HoriOrient"));
298 CPPUNIT_ASSERT_EQUAL_MESSAGE("text probably does not wrap here", 1, getPages());
300 createSwDoc("tdf80635_pageRightRTL.doc");
301 verify();
302 saveAndReload("MS Word 97");
303 verify();
306 CPPUNIT_TEST_FIXTURE(Test, testTdf80635_marginRTL)
308 auto verify = [this]() {
309 // tdf#80635 - assert the horizontal orientation of the table.
310 uno::Reference<drawing::XShape> xFly = getShape(1);
311 CPPUNIT_ASSERT_EQUAL_MESSAGE("Horizontal Orientation", text::HoriOrientation::RIGHT, getProperty<sal_Int16>(xFly, "HoriOrient"));
313 createSwDoc("tdf80635_marginRightRTL.doc");
314 verify();
315 saveAndReload("MS Word 97");
316 verify();
319 CPPUNIT_TEST_FIXTURE(Test, testTdf80635_marginLeft)
321 auto verify = [this]() {
322 // tdf#80635 - assert horizontal position of the table.
323 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
324 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
325 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
326 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table Indent", tools::Long(0), getProperty<tools::Long>(xTable, "LeftMargin"), 100);
327 uno::Reference<drawing::XShape> xFly = getShape(1);
328 CPPUNIT_ASSERT_EQUAL(sal_Int32(-2958), getProperty<sal_Int32>(xFly, "HoriOrientPosition"));
330 createSwDoc("tdf80635_marginLeft.doc");
331 verify();
332 saveAndReload("MS Word 97");
333 verify();
336 CPPUNIT_TEST_FIXTURE(Test, testTdf80635_pageLeft)
338 auto verify = [this]() {
339 // tdf#80635 - assert horizontal orient relation of the table.
340 uno::Reference<drawing::XShape> xFly = getShape(1);
341 CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(xFly, "HoriOrientRelation"));
342 CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::NONE, getProperty<sal_Int16>(xFly, "HoriOrient"));
343 CPPUNIT_ASSERT_EQUAL(sal_Int32(-189), getProperty<sal_Int32>(xFly, "HoriOrientPosition"));
345 createSwDoc("tdf80635_pageLeft.doc");
346 verify();
347 saveAndReload("MS Word 97");
348 verify();
351 DECLARE_WW8EXPORT_TEST(testTdf99197_defaultLTR, "tdf99197_defaultLTR.doc")
353 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Default Paragraph style, LTR",
354 text::WritingMode2::LR_TB, getProperty<sal_Int16>(getParagraph(1), "WritingMode") );
356 CPPUNIT_ASSERT_EQUAL_MESSAGE( "myDefaultStyle - no base style, LTR",
357 text::WritingMode2::LR_TB, getProperty<sal_Int16>(getParagraph(2), "WritingMode") );
360 CPPUNIT_TEST_FIXTURE(Test, testTdf107773)
362 auto verify = [this]() {
363 // This failed, multi-page table was imported as a non-split frame.
364 SwDoc* pDoc = getSwDoc();
365 SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
366 auto pPage1 = dynamic_cast<SwPageFrame*>(pLayout->Lower());
367 CPPUNIT_ASSERT(pPage1);
368 // pPage1 has no sorted (floating) objections.
369 CPPUNIT_ASSERT(pPage1->GetSortedObjs());
370 const SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs();
371 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage1Objs.size());
372 auto pPage1Fly = dynamic_cast<SwFlyAtContentFrame*>(rPage1Objs[0]);
373 CPPUNIT_ASSERT(pPage1Fly);
374 auto pTab1 = dynamic_cast<SwTabFrame*>(pPage1Fly->GetLower());
375 CPPUNIT_ASSERT(pTab1);
376 // This failed, the split fly containing a table was exported back to DOC as shape+table,
377 // which can't split.
378 CPPUNIT_ASSERT(pTab1->HasFollow());
380 // tdf#80635 - assert the horizontal orientation.
381 const SwFormatHoriOrient& rFormatHoriOrient = pPage1Fly->GetFormat()->GetHoriOrient();
382 CPPUNIT_ASSERT_EQUAL(css::text::HoriOrientation::CENTER, rFormatHoriOrient.GetHoriOrient());
384 createSwDoc("tdf107773.doc");
385 verify();
386 saveAndReload("MS Word 97");
387 verify();
390 DECLARE_WW8EXPORT_TEST(testTdf112074_RTLtableJustification, "tdf112074_RTLtableJustification.doc")
392 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
393 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
394 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
396 CPPUNIT_ASSERT_EQUAL_MESSAGE("Right To Left writing mode", text::WritingMode2::RL_TB, getProperty<sal_Int16>(xTable, "WritingMode"));
397 CPPUNIT_ASSERT_EQUAL_MESSAGE("Horizontal Orientation", text::HoriOrientation::LEFT_AND_WIDTH, getProperty<sal_Int16>(xTable, "HoriOrient"));
398 CPPUNIT_ASSERT_MESSAGE("Table Indent", getProperty<tools::Long>(xTable, "LeftMargin") > 3000);
399 CPPUNIT_ASSERT_MESSAGE("Table Indent is 3750", getProperty<tools::Long>(xTable, "LeftMargin") < 4000 );
400 CPPUNIT_ASSERT_EQUAL( style::ParagraphAdjust_RIGHT, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraphOrTable(2), "ParaAdjust")) );
403 DECLARE_WW8EXPORT_TEST(testTdf98620_rtlJustify, "tdf98620_rtlJustify.doc")
405 CPPUNIT_ASSERT_EQUAL( style::ParagraphAdjust_RIGHT, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraph(1), "ParaAdjust")) );
406 CPPUNIT_ASSERT_EQUAL_MESSAGE("Right To Left style", text::WritingMode2::RL_TB, getProperty<sal_Int16>(getParagraph(1), "WritingMode"));
409 DECLARE_WW8EXPORT_TEST(testTdf121110_absJustify, "tdf121110_absJustify.doc")
411 CPPUNIT_ASSERT_EQUAL( style::ParagraphAdjust_RIGHT, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraph(1), "ParaAdjust")) );
412 CPPUNIT_ASSERT_EQUAL( style::ParagraphAdjust_LEFT, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraph(3), "ParaAdjust")) );
415 CPPUNIT_TEST_FIXTURE(Test, testTdf106174_rtlParaAlign)
417 loadAndReload("tdf106174_rtlParaAlign.docx");
418 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_CENTER), getProperty<sal_Int16>(getParagraph(1), "ParaAdjust"));
419 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_CENTER), getProperty<sal_Int16>(getParagraph(2), "ParaAdjust"));
420 uno::Reference<beans::XPropertySet> xPropertySet(getStyles("ParagraphStyles")->getByName("Another paragraph aligned to right"), uno::UNO_QUERY);
421 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(xPropertySet, "ParaAdjust"));
422 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(3), "ParaAdjust"));
423 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(4), "ParaAdjust"));
424 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(5), "ParaAdjust"));
425 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getParagraph(6), "ParaAdjust"));
426 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(7), "ParaAdjust"));
427 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(8), "ParaAdjust"));
428 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getParagraph(9), "ParaAdjust"));
429 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getParagraph(10), "ParaAdjust"));
430 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(11), "ParaAdjust"));
431 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getParagraph(12), "ParaAdjust"));
432 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getParagraph(13), "ParaAdjust"));
433 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getParagraph(14), "ParaAdjust"));
436 DECLARE_WW8EXPORT_TEST(testTdf119232_startEvenPage, "tdf119232_startEvenPage.doc")
438 CPPUNIT_ASSERT_EQUAL(sal_Int16(2), getProperty<sal_Int16>(getParagraph(1), "PageNumberOffset"));
441 DECLARE_WW8EXPORT_TEST(testTdf104805, "tdf104805.doc")
443 // Prefix was "." instead of empty, so the second paragraph was
444 // rendered as ".1" instead of "1.".
445 // Unittest modified due to Prefix/Suffix support obsolete
446 uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY);
447 CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty<OUString>(xPara, "ListLabelString"));
450 DECLARE_WW8EXPORT_TEST(testTdf104334, "tdf104334.doc")
452 // This failed with a container::NoSuchElementException: STYLEREF was
453 // mapped to SwChapterField, and the field result was "This is a Heading 1"
454 // instead of just "1".
455 CPPUNIT_ASSERT_EQUAL(OUString("1"), getRun(getParagraph(2), 4)->getString());
458 DECLARE_WW8EXPORT_TEST(testTdf108072, "tdf108072.doc")
460 // The property IsSplitAllowed was imported from an obsolete property, sprmTFCantSplit90
461 // instead of sprmTFCantSplit. sprmTFCantSplit90 is set to true for merged rows, so
462 // for merged rows incorrect settings were imported, which prevented them from breaking over pages.
463 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
464 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
465 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
466 uno::Reference<container::XIndexAccess> xTableRows = xTable->getRows();
467 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTableRows->getByIndex(0), "IsSplitAllowed"));
470 DECLARE_WW8EXPORT_TEST(testTdf123321, "shapes-line-ellipse.doc")
472 // These are the 3 lines in which 1st and 3rd one were disappearing before
473 uno::Reference<drawing::XShape> l1 = getShape(7);
474 uno::Reference<drawing::XShape> l2 = getShape(8);
475 uno::Reference<drawing::XShape> l3 = getShape(9);
477 // first line (smallest)
478 // Fails without the fix: Expected: 423, Actual: 2
479 CPPUNIT_ASSERT_EQUAL(sal_Int32(423), l1->getSize().Height);
480 // Fails without the fix: Expected: 0, Actual: 2
481 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), l1->getSize().Width);
482 CPPUNIT_ASSERT_EQUAL(sal_Int32(7908), l1->getPosition().X);
483 CPPUNIT_ASSERT_EQUAL(sal_Int32(37), l1->getPosition().Y);
485 // second line (larger)
486 CPPUNIT_ASSERT_EQUAL(sal_Int32(2542), l2->getSize().Height);
487 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), l2->getSize().Width);
488 CPPUNIT_ASSERT_EQUAL(sal_Int32(7916), l2->getPosition().X);
489 CPPUNIT_ASSERT_EQUAL(sal_Int32(289), l2->getPosition().Y);
491 // third line (largest)
492 // Fails without the fix: Expected: 7027, Actual: 2
493 CPPUNIT_ASSERT_EQUAL(sal_Int32(7027), l3->getSize().Height);
494 // Fails without the fix: Expected: 0, Actual: 2
495 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), l3->getSize().Width);
496 CPPUNIT_ASSERT_EQUAL(sal_Int32(7911), l3->getPosition().X);
497 CPPUNIT_ASSERT_EQUAL(sal_Int32(231), l3->getPosition().Y);
500 DECLARE_WW8EXPORT_TEST(testTdf91687, "tdf91687.doc")
502 // Exported Watermarks were resized
503 uno::Reference<drawing::XShape> xWatermark = getShape(1);
505 CPPUNIT_ASSERT_EQUAL(sal_Int32(5172), xWatermark->getSize().Height);
506 CPPUNIT_ASSERT_EQUAL(sal_Int32(18105), xWatermark->getSize().Width);
509 DECLARE_WW8EXPORT_TEST(testTdf114308, "tdf114308.doc")
511 // Watermark with no additional padding
512 uno::Reference<drawing::XShape> xWatermark = getShape(1);
514 CPPUNIT_ASSERT_EQUAL(sal_Int32(8729), xWatermark->getSize().Height);
517 DECLARE_WW8EXPORT_TEST(testTdf111480, "tdf111480.doc")
519 // Circular text was imported horizontally
520 uno::Reference<drawing::XShape> xText = getShape(1);
522 CPPUNIT_ASSERT(xText->getSize().Height > 11000);
523 CPPUNIT_ASSERT(xText->getSize().Width > 11000);
526 CPPUNIT_TEST_FIXTURE(Test, testTdf70838)
528 loadAndReload("tdf70838.odt");
529 CPPUNIT_ASSERT_EQUAL(1, getShapes());
530 CPPUNIT_ASSERT_EQUAL(1, getPages());
531 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
532 CPPUNIT_ASSERT(pTextDoc);
533 SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
534 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
535 tools::Rectangle aRect = pPage->GetObj(0)->GetSnapRect();
536 CPPUNIT_ASSERT(aRect.GetHeight() > aRect.GetWidth());
539 CPPUNIT_TEST_FIXTURE(Test, testTdf70838b_verticalRotation)
541 loadAndReload("tdf70838b_verticalRotation.odt");
542 CPPUNIT_ASSERT_EQUAL(3, getShapes());
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 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
548 tools::Rectangle aGroupShape = pPage->GetObj(0)->GetSnapRect();
549 tools::Rectangle aLine = pPage->GetObj(2)->GetSnapRect();
551 CPPUNIT_ASSERT_MESSAGE("Smiley faces are round", aGroupShape.GetHeight() > aGroupShape.GetWidth());
552 CPPUNIT_ASSERT_MESSAGE("Line is taller, not wider", aLine.GetHeight() > aLine.GetWidth());
555 CPPUNIT_TEST_FIXTURE(Test, testTdf129247)
557 loadAndReload("tdf129247.docx");
558 CPPUNIT_ASSERT_EQUAL(1, getPages());
559 // Without the fix in place, the checkbox wouldn't be exported
560 CPPUNIT_ASSERT_EQUAL(1, getShapes());
563 CPPUNIT_TEST_FIXTURE(Test, testActiveXCheckbox)
565 loadAndReload("checkbox_control.odt");
566 CPPUNIT_ASSERT_EQUAL(2, getShapes());
567 CPPUNIT_ASSERT_EQUAL(1, getPages());
568 // First check box anchored as a floating object
569 uno::Reference<drawing::XControlShape> xControlShape;
570 if(!isExported())
571 xControlShape.set(getShape(1), uno::UNO_QUERY);
572 else
573 xControlShape.set(getShape(2), uno::UNO_QUERY);
574 CPPUNIT_ASSERT(xControlShape.is());
576 // Check whether we have the right control
577 uno::Reference<beans::XPropertySet> xPropertySet(xControlShape->getControl(), uno::UNO_QUERY);
578 uno::Reference<lang::XServiceInfo> xServiceInfo(xPropertySet, uno::UNO_QUERY);
579 CPPUNIT_ASSERT_EQUAL(true, bool(xServiceInfo->supportsService( "com.sun.star.form.component.CheckBox")));
580 CPPUNIT_ASSERT_EQUAL(OUString("Floating Checkbox"), getProperty<OUString>(xPropertySet, "Label"));
582 // Check anchor type
583 uno::Reference<beans::XPropertySet> xPropertySet2(xControlShape, uno::UNO_QUERY);
584 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet2,"AnchorType"));
586 // Second check box anchored inline / as character
587 if(!isExported())
588 xControlShape.set(getShape(2), uno::UNO_QUERY);
589 else
590 xControlShape.set(getShape(1), uno::UNO_QUERY);
592 // Check whether we have the right control
593 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY);
594 xServiceInfo.set(xPropertySet, uno::UNO_QUERY);
595 CPPUNIT_ASSERT_EQUAL(true, bool(xServiceInfo->supportsService("com.sun.star.form.component.CheckBox")));
596 CPPUNIT_ASSERT_EQUAL(OUString("Inline Checkbox"), getProperty<OUString>(xPropertySet, "Label"));
598 // Check anchor type
599 xPropertySet2.set(xControlShape, uno::UNO_QUERY);
600 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet2,"AnchorType"));
603 DECLARE_WW8EXPORT_TEST( testTdf115896_layoutInCell, "tdf115896_layoutInCell.doc" )
605 // Check anchor type - was anchored to page because of unknown version of Word
606 uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY_THROW);
607 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet,"AnchorType"));
610 DECLARE_WW8EXPORT_TEST(testTdf67207_MERGEFIELD, "mailmerge.doc")
612 uno::Reference<beans::XPropertySet> xTextField = getProperty< uno::Reference<beans::XPropertySet> >(getRun(getParagraph(1), 2), "TextField");
613 CPPUNIT_ASSERT(xTextField.is());
614 uno::Reference<lang::XServiceInfo> xServiceInfo(xTextField, uno::UNO_QUERY_THROW);
615 uno::Reference<text::XDependentTextField> xDependent(xTextField, uno::UNO_QUERY_THROW);
617 CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.Database"));
618 OUString sValue;
619 xTextField->getPropertyValue("Content") >>= sValue;
620 CPPUNIT_ASSERT_EQUAL(OUString(u"«Name»"), sValue);
622 uno::Reference<beans::XPropertySet> xFiledMaster = xDependent->getTextFieldMaster();
623 uno::Reference<lang::XServiceInfo> xFiledMasterServiceInfo(xFiledMaster, uno::UNO_QUERY_THROW);
625 CPPUNIT_ASSERT(xFiledMasterServiceInfo->supportsService("com.sun.star.text.fieldmaster.Database"));
627 // Defined properties: DataBaseName, Name, DataTableName, DataColumnName, DependentTextFields, DataCommandType, InstanceName, DataBaseURL
628 CPPUNIT_ASSERT(xFiledMaster->getPropertyValue("Name") >>= sValue);
629 CPPUNIT_ASSERT_EQUAL(OUString("Name"), sValue);
630 CPPUNIT_ASSERT(xFiledMaster->getPropertyValue("DataColumnName") >>= sValue);
631 CPPUNIT_ASSERT_EQUAL(OUString("Name"), sValue);
632 CPPUNIT_ASSERT(xFiledMaster->getPropertyValue("InstanceName") >>= sValue);
633 CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.text.fieldmaster.DataBase.Name"), sValue);
636 DECLARE_OOXMLEXPORT_TEST( testTableCrossReference, "table_cross_reference.odt" )
638 CPPUNIT_ASSERT_EQUAL(1, getPages());
639 // tdf#42346: Cross references to tables were not saved
640 // MSO uses simple bookmarks for referencing table caption, so we do the same by export
641 if (!isExported())
642 return;
644 // Check whether we have all the necessary bookmarks exported and imported back
645 uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
646 uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
647 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xBookmarksByIdx->getCount());
648 uno::Reference<container::XNameAccess> xBookmarksByName = xBookmarksSupplier->getBookmarks();
649 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_full"));
650 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_label_and_number"));
651 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_caption_only"));
652 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_number_only"));
654 // Check bookmark text ranges
656 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_full"), uno::UNO_QUERY);
657 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
658 CPPUNIT_ASSERT_EQUAL(OUString("Table 1: Table caption"), xRange->getString());
661 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_label_and_number"), uno::UNO_QUERY);
662 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
663 CPPUNIT_ASSERT_EQUAL(OUString("Table 1"), xRange->getString());
666 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_caption_only"), uno::UNO_QUERY);
667 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
668 CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), xRange->getString());
671 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_number_only"), uno::UNO_QUERY);
672 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
673 CPPUNIT_ASSERT_EQUAL(OUString("1"), xRange->getString());
676 // Check reference fields
677 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
678 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
679 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
680 CPPUNIT_ASSERT(xFields->hasMoreElements());
682 sal_uInt16 nIndex = 0;
683 while (xFields->hasMoreElements())
685 uno::Reference<lang::XServiceInfo> xServiceInfo(xFields->nextElement(), uno::UNO_QUERY);
686 uno::Reference<beans::XPropertySet> xPropertySet(xServiceInfo, uno::UNO_QUERY);
687 switch (nIndex)
689 // Full reference to table caption
690 case 0:
692 CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
693 OUString sValue;
694 sal_Int16 nValue;
695 xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
696 CPPUNIT_ASSERT_EQUAL(OUString("Table 1: Table caption"), sValue);
697 xPropertySet->getPropertyValue("SourceName") >>= sValue;
698 CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_full"), sValue);
699 xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
700 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
701 break;
703 // Reference to table number
704 case 1:
706 CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
707 OUString sValue;
708 sal_Int16 nValue;
709 xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
710 CPPUNIT_ASSERT_EQUAL(OUString("1"), sValue);
711 xPropertySet->getPropertyValue("SourceName") >>= sValue;
712 CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_number_only"), sValue);
713 xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
714 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
715 break;
717 // Reference to caption only
718 case 2:
720 CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
721 OUString sValue;
722 sal_Int16 nValue;
723 xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
724 CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), sValue);
725 xPropertySet->getPropertyValue("SourceName") >>= sValue;
726 CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_caption_only"), sValue);
727 xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
728 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
729 break;
731 // Reference to category and number
732 case 3:
734 CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
735 OUString sValue;
736 sal_Int16 nValue;
737 xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
738 CPPUNIT_ASSERT_EQUAL(OUString("Table 1"), sValue);
739 xPropertySet->getPropertyValue("SourceName") >>= sValue;
740 CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_label_and_number"), sValue);
741 xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
742 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
743 break;
745 // Reference to page of the table
746 case 4:
748 CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
749 OUString sValue;
750 sal_Int16 nValue;
751 xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
752 CPPUNIT_ASSERT_EQUAL(OUString("1"), sValue);
753 xPropertySet->getPropertyValue("SourceName") >>= sValue;
754 CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_full"), sValue);
755 xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
756 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
757 break;
759 // Page style reference / exported as simple page reference
760 case 5:
762 CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
763 OUString sValue;
764 sal_Int16 nValue;
765 xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
766 CPPUNIT_ASSERT_EQUAL(OUString("1"), sValue);
767 xPropertySet->getPropertyValue("SourceName") >>= sValue;
768 CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_full"), sValue);
769 xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
770 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
771 break;
773 // Above / below reference
774 case 6:
776 CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
777 OUString sValue;
778 sal_Int16 nValue;
779 xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
780 CPPUNIT_ASSERT_EQUAL(OUString("above"), sValue);
781 xPropertySet->getPropertyValue("SourceName") >>= sValue;
782 CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_full"), sValue);
783 xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
784 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
785 break;
787 default:
788 break;
790 ++nIndex;
792 CPPUNIT_ASSERT_EQUAL(sal_uInt16(8), nIndex);
795 CPPUNIT_TEST_FIXTURE(Test, testTableCrossReferenceCustomFormat)
797 loadAndReload("table_cross_reference_custom_format.odt");
798 CPPUNIT_ASSERT_EQUAL(1, getPages());
799 // tdf#42346: Cross references to tables were not saved
800 // Check also captions with custom formatting
801 if (!isExported())
802 return;
804 // Check whether we have all the necessary bookmarks exported and imported back
805 uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
806 uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
807 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(16), xBookmarksByIdx->getCount());
808 uno::Reference<container::XNameAccess> xBookmarksByName = xBookmarksSupplier->getBookmarks();
809 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_full"));
810 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_label_and_number"));
811 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_caption_only"));
812 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_number_only"));
813 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table1_full"));
814 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table1_label_and_number"));
815 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table1_caption_only"));
816 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table1_number_only"));
817 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table2_full"));
818 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table2_label_and_number"));
819 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table2_caption_only"));
820 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table2_number_only"));
821 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table3_full"));
822 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table3_label_and_number"));
823 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table3_caption_only"));
824 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table3_number_only"));
826 // Check bookmark text ranges
827 // First table's caption
829 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_full"), uno::UNO_QUERY);
830 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
831 CPPUNIT_ASSERT_EQUAL(OUString("1. Table: Table caption"), xRange->getString());
834 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_label_and_number"), uno::UNO_QUERY);
835 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
836 CPPUNIT_ASSERT_EQUAL(OUString("1. Table"), xRange->getString());
839 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_caption_only"), uno::UNO_QUERY);
840 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
841 CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), xRange->getString());
844 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_number_only"), uno::UNO_QUERY);
845 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
846 CPPUNIT_ASSERT_EQUAL(OUString("1"), xRange->getString());
848 // Second table's caption
850 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table1_full"), uno::UNO_QUERY);
851 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
852 CPPUNIT_ASSERT_EQUAL(OUString("2. TableTable caption"), xRange->getString());
855 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table1_label_and_number"), uno::UNO_QUERY);
856 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
857 CPPUNIT_ASSERT_EQUAL(OUString("2. Table"), xRange->getString());
860 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table1_caption_only"), uno::UNO_QUERY);
861 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
862 CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), xRange->getString());
865 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table1_number_only"), uno::UNO_QUERY);
866 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
867 CPPUNIT_ASSERT_EQUAL(OUString("2"), xRange->getString());
869 // Third table's caption
871 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table2_full"), uno::UNO_QUERY);
872 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
873 CPPUNIT_ASSERT_EQUAL(OUString("3) Table Table caption"), xRange->getString());
876 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table2_label_and_number"), uno::UNO_QUERY);
877 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
878 CPPUNIT_ASSERT_EQUAL(OUString("3) Table"), xRange->getString());
881 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table2_caption_only"), uno::UNO_QUERY);
882 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
883 CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), xRange->getString());
886 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table2_number_only"), uno::UNO_QUERY);
887 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
888 CPPUNIT_ASSERT_EQUAL(OUString("3"), xRange->getString());
890 // Fourth table's caption
892 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table3_full"), uno::UNO_QUERY);
893 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
894 CPPUNIT_ASSERT_EQUAL(OUString("Table 4- Table caption"), xRange->getString());
897 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table3_label_and_number"), uno::UNO_QUERY);
898 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
899 CPPUNIT_ASSERT_EQUAL(OUString("Table 4"), xRange->getString());
902 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table3_caption_only"), uno::UNO_QUERY);
903 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
904 CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), xRange->getString());
907 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table3_number_only"), uno::UNO_QUERY);
908 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
909 CPPUNIT_ASSERT_EQUAL(OUString("4"), xRange->getString());
913 DECLARE_OOXMLEXPORT_TEST( testObjectCrossReference, "object_cross_reference.odt" )
915 CPPUNIT_ASSERT_EQUAL(2, getPages());
916 // tdf#42346: Cross references to objects were not saved
917 // MSO uses simple bookmarks for referencing table caption, so we do the same by export
918 if (!isExported())
919 return;
921 // Check whether we have all the necessary bookmarks exported and imported back
922 uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
923 uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
924 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(15), xBookmarksByIdx->getCount());
925 uno::Reference<container::XNameAccess> xBookmarksByName = xBookmarksSupplier->getBookmarks();
926 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Drawing0_full"));
927 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Drawing0_label_and_number"));
928 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Drawing0_caption_only"));
929 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Drawing0_number_only"));
930 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Drawing1_full"));
932 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Illustration0_full"));
933 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Illustration0_label_and_number"));
934 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Illustration0_caption_only"));
935 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Illustration0_number_only"));
936 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Illustration1_caption_only"));
938 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Text0_full"));
939 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Text0_label_and_number"));
940 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Text0_caption_only"));
941 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Text0_number_only"));
942 CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Text1_label_and_number"));
944 // Check bookmark text ranges
945 // Cross references to shapes
947 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Drawing0_full"), uno::UNO_QUERY);
948 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
949 CPPUNIT_ASSERT_EQUAL(OUString("Drawing 1: A rectangle"), xRange->getString());
952 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Drawing0_label_and_number"), uno::UNO_QUERY);
953 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
954 CPPUNIT_ASSERT_EQUAL(OUString("Drawing 1"), xRange->getString());
957 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Drawing0_caption_only"), uno::UNO_QUERY);
958 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
959 CPPUNIT_ASSERT_EQUAL(OUString("A rectangle"), xRange->getString());
962 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Drawing0_number_only"), uno::UNO_QUERY);
963 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
964 CPPUNIT_ASSERT_EQUAL(OUString("1"), xRange->getString());
967 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Drawing1_full"), uno::UNO_QUERY);
968 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
969 CPPUNIT_ASSERT_EQUAL(OUString("Drawing 2: a circle"), xRange->getString());
972 // Cross references to pictures
974 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Illustration0_full"), uno::UNO_QUERY);
975 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
976 CPPUNIT_ASSERT_EQUAL(OUString("Illustration 1: A picture"), xRange->getString());
979 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Illustration0_label_and_number"), uno::UNO_QUERY);
980 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
981 CPPUNIT_ASSERT_EQUAL(OUString("Illustration 1"), xRange->getString());
984 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Illustration0_caption_only"), uno::UNO_QUERY);
985 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
986 CPPUNIT_ASSERT_EQUAL(OUString("A picture"), xRange->getString());
989 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Illustration0_number_only"), uno::UNO_QUERY);
990 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
991 CPPUNIT_ASSERT_EQUAL(OUString("1"), xRange->getString());
994 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Illustration1_caption_only"), uno::UNO_QUERY);
995 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
996 CPPUNIT_ASSERT_EQUAL(OUString("another image"), xRange->getString());
999 // Cross references to text frames
1001 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Text0_full"), uno::UNO_QUERY);
1002 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
1003 CPPUNIT_ASSERT_EQUAL(OUString("Text 1: A frame"), xRange->getString());
1006 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Text0_label_and_number"), uno::UNO_QUERY);
1007 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
1008 CPPUNIT_ASSERT_EQUAL(OUString("Text 1"), xRange->getString());
1011 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Text0_caption_only"), uno::UNO_QUERY);
1012 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
1013 CPPUNIT_ASSERT_EQUAL(OUString("A frame"), xRange->getString());
1016 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Text0_number_only"), uno::UNO_QUERY);
1017 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
1018 CPPUNIT_ASSERT_EQUAL(OUString("1"), xRange->getString());
1021 uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Text1_label_and_number"), uno::UNO_QUERY);
1022 uno::Reference<text::XTextRange> xRange = xContent->getAnchor();
1023 CPPUNIT_ASSERT_EQUAL(OUString("Text 2"), xRange->getString());
1027 DECLARE_WW8EXPORT_TEST(testTdf112118_DOC, "tdf112118.doc")
1029 static const struct {
1030 const char* styleName;
1031 struct {
1032 const char* sideName;
1033 sal_Int32 nMargin;
1034 sal_Int32 nBorderDistance;
1035 sal_Int32 nBorderWidth;
1036 } sideParams[4];
1037 } styleParams[] = { // Margin (MS-style), border distance, border width
1039 "Standard",
1041 { "Top", 496, 847, 159 }, // 851 twip, 24 pt (from text), 4.5 pt
1042 { "Left", 2083, 706, 212 }, // 1701 twip, 20 pt (from text), 6.0 pt
1043 { "Bottom", 1401, 564, 35 }, // 1134 twip, 16 pt (from text), 1.0 pt
1044 { "Right", 3471, 423, 106 } // 2268 twip, 12 pt (from text), 3.0 pt
1048 "Convert 1",
1050 { "Top", 847, 496, 159 }, // 851 twip, 24 pt (from edge), 4.5 pt
1051 { "Left", 706, 2083, 212 }, // 1701 twip, 20 pt (from edge), 6.0 pt
1052 { "Bottom", 564, 1401, 35 }, // 1134 twip, 16 pt (from edge), 1.0 pt
1053 { "Right", 423, 3471, 106 } // 2268 twip, 12 pt (from edge), 3.0 pt
1057 auto xStyles = getStyles("PageStyles");
1059 for (const auto& style : styleParams)
1061 const OUString sName = OUString::createFromAscii(style.styleName);
1062 uno::Reference<beans::XPropertySet> xStyle(xStyles->getByName(sName), uno::UNO_QUERY_THROW);
1063 for (const auto& side : style.sideParams)
1065 const OUString sSide = OUString::createFromAscii(side.sideName);
1066 const OString sStage = style.styleName + OString::Concat(" ") + side.sideName;
1068 sal_Int32 nMargin = getProperty<sal_Int32>(xStyle, sSide + "Margin");
1069 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(sStage + " margin width").getStr(),
1070 side.nMargin, nMargin);
1072 sal_Int32 nBorderDistance = getProperty<sal_Int32>(xStyle, sSide + "BorderDistance");
1073 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(sStage + " border distance").getStr(),
1074 side.nBorderDistance, nBorderDistance);
1076 table::BorderLine aBorder = getProperty<table::BorderLine>(xStyle, sSide + "Border");
1077 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(sStage + " border width").getStr(),
1078 side.nBorderWidth,
1079 sal_Int32(aBorder.OuterLineWidth + aBorder.InnerLineWidth + aBorder.LineDistance));
1081 // Check that AUTO border color is imported as black
1082 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(sStage + " border color").getStr(),
1083 sal_Int32(COL_BLACK), aBorder.Color);
1088 CPPUNIT_TEST_FIXTURE(Test, testTdf117503)
1090 loadAndReload("tdf117503.docx");
1091 // This was 3, first page + standard page styles were not merged together
1092 // on export.
1093 CPPUNIT_ASSERT_EQUAL(2, getPages());
1096 DECLARE_WW8EXPORT_TEST(testTdf117885, "tdf117885.doc")
1098 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1100 /* Get the vertical position of the paragraph containing the text "Start" */
1101 sal_Int32 nParaA_Top = getXPath(pXmlDoc,
1102 "/root/page/body/column[1]/body/txt[text()='Start']/infos/bounds", "top"
1103 ).toInt32();
1105 /* Get the vertical position of the paragraph containing the text "Top B" */
1106 sal_Int32 nParaB_Top = getXPath(pXmlDoc,
1107 "/root/page/body/column[2]/body/txt[text()='Top B']/infos/bounds", "top"
1108 ).toInt32();
1110 /* These two paragraphs are supposed to be at the top of the left
1111 * and right columns respectively. Check that they actually line up: */
1112 CPPUNIT_ASSERT_EQUAL(nParaA_Top, nParaB_Top);
1115 CPPUNIT_TEST_FIXTURE(Test, testTdf118133)
1117 loadAndReload("tdf118133.docx");
1118 // This was 0, doc import + doc export resulted in lost image due to broken
1119 // lazy-loading of tiff images.
1120 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(15240), getShape(1)->getSize().Width);
1123 DECLARE_WW8EXPORT_TEST(testTdf118412, "tdf118412.doc")
1125 /* Check that the first page's bottom margin is 1.251cm (not 2.540cm) */
1126 OUString sPageStyleName = getProperty<OUString>(getParagraph(1), "PageStyleName");
1127 uno::Reference<style::XStyle> xPageStyle(
1128 getStyles("PageStyles")->getByName(sPageStyleName), uno::UNO_QUERY);
1129 sal_Int32 nBottomMargin = getProperty<sal_Int32>(xPageStyle, "BottomMargin");
1130 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1251), nBottomMargin);
1133 CPPUNIT_TEST_FIXTURE(Test, testContentControlExport)
1135 // Given a document with a (rich text) content control:
1136 createSwDoc();
1137 uno::Reference<lang::XMultiServiceFactory> xMSF(mxComponent, uno::UNO_QUERY);
1138 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
1139 uno::Reference<text::XText> xText = xTextDocument->getText();
1140 uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
1141 xText->insertString(xCursor, "test", /*bAbsorb=*/false);
1142 xCursor->gotoStart(/*bExpand=*/false);
1143 xCursor->gotoEnd(/*bExpand=*/true);
1144 uno::Reference<text::XTextContent> xContentControl(
1145 xMSF->createInstance("com.sun.star.text.ContentControl"), uno::UNO_QUERY);
1146 xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true);
1148 // When saving that document to DOC and loading it back:
1149 saveAndReload("MS Word 97");
1151 // Then make sure the dummy character at the end is filtered out:
1152 OUString aBodyText = getBodyText();
1153 // Without the accompanying fix in place, this test would have failed:
1154 // - Expected: test
1155 // - Actual : test<space>
1156 // i.e. the CH_TXTATR_BREAKWORD at the end was written, then the import replaced that with a
1157 // space.
1158 CPPUNIT_ASSERT_EQUAL(OUString("test"), aBodyText);
1161 CPPUNIT_PLUGIN_IMPLEMENT();
1163 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */