tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sw / qa / extras / ww8export / ww8export4.cxx
blob2a8f5d939b361e9c660d2fbd3a43b09f4137c3ed
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/document/XDocumentPropertiesSupplier.hpp>
15 #include <com/sun/star/graphic/XGraphic.hpp>
16 #include <com/sun/star/style/ParagraphAdjust.hpp>
17 #include <com/sun/star/text/TextContentAnchorType.hpp>
18 #include <com/sun/star/text/XTextDocument.hpp>
19 #include <com/sun/star/text/XTextFrame.hpp>
20 #include <com/sun/star/text/XTextTable.hpp>
21 #include <com/sun/star/text/WrapTextMode.hpp>
22 #include <com/sun/star/text/XTextField.hpp>
24 #include <comphelper/sequenceashashmap.hxx>
25 #include <o3tl/string_view.hxx>
26 #include <svx/svdpage.hxx>
28 #include <docsh.hxx>
29 #include <drawdoc.hxx>
30 #include <IDocumentDrawModelAccess.hxx>
31 #include <IDocumentMarkAccess.hxx>
32 #include <IDocumentSettingAccess.hxx>
33 #include <unotxdoc.hxx>
34 #include <ndtxt.hxx>
35 #include <editeng/lrspitem.hxx>
36 #include <wrtsh.hxx>
37 #include <itabenum.hxx>
38 #include <frmmgr.hxx>
39 #include <formatflysplit.hxx>
40 #include <fmtwrapinfluenceonobjpos.hxx>
41 #include <fmtftntx.hxx>
43 namespace
45 class Test : public SwModelTestBase
47 public:
48 Test()
49 : SwModelTestBase(u"/sw/qa/extras/ww8export/data/"_ustr, u"MS Word 97"_ustr)
54 CPPUNIT_TEST_FIXTURE(Test, testTdf77964)
56 loadAndReload("tdf77964.doc");
57 // both images were loading as AT_PARA instead of AS_CHAR. Image2 visually had text wrapping.
58 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER, getProperty<text::TextContentAnchorType>(getShapeByName(u"Image2"), u"AnchorType"_ustr));
61 DECLARE_WW8EXPORT_TEST(testTdf72511_editengLRSpace, "tdf72511_editengLRSpace.doc")
63 // given a default paragraph style with a left indent of 2 inches,
64 // the comment should ignore the indent, but the textbox must not.
65 uno::Reference<beans::XPropertySet> xRun(
66 getProperty<uno::Reference<beans::XPropertySet>>(getRun(getParagraph(1), 3), u"TextField"_ustr));
67 uno::Reference<text::XText> xComment(getProperty<uno::Reference<text::XText>>(xRun, u"TextRange"_ustr));
68 uno::Reference<beans::XPropertySet> xParagraph(getParagraphOfText(1, xComment), uno::UNO_QUERY);
69 // The comment was indented by 4001 (2 inches) instead of nothing
70 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xParagraph, u"ParaLeftMargin"_ustr));
72 uno::Reference<drawing::XShapes> xGroupShape(getShape(1), uno::UNO_QUERY_THROW);
73 uno::Reference<drawing::XShape> xShape2(xGroupShape->getByIndex(1), uno::UNO_QUERY_THROW);
74 CPPUNIT_ASSERT_EQUAL(u"com.sun.star.drawing.TextShape"_ustr, xShape2->getShapeType());
75 uno::Reference<text::XTextRange> xTextbox(xShape2, uno::UNO_QUERY_THROW);
76 uno::Reference<beans::XPropertySet> xTBPara(xTextbox, uno::UNO_QUERY);
77 // Textbox paragraphs had no indent instead of 5080 (2 inches - the same as normal paragraphs).
78 CPPUNIT_ASSERT_EQUAL(sal_Int32(5080), getProperty<sal_Int32>(xTBPara, u"ParaLeftMargin"_ustr));
79 CPPUNIT_ASSERT_EQUAL_MESSAGE("sanity check: normal paragraph's indent", sal_Int32(5080),
80 getProperty<sal_Int32>(getParagraph(1), u"ParaLeftMargin"_ustr));
83 DECLARE_WW8EXPORT_TEST(testTdf160049_anchorMargin, "tdf160049_anchorMargin.doc")
85 // given a document with a LEFT "column/text" anchored image
87 // The image takes into account the margin, so it looks like it is in the middle of the doc,
88 // which is "Paragraph text area"/PRINT_AREA/1, not "Entire paragraph area"/FRAME/0
89 CPPUNIT_ASSERT_EQUAL(css::text::RelOrientation::PRINT_AREA,
90 getProperty<sal_Int16>(getShape(1), u"HoriOrientRelation"_ustr));
93 DECLARE_WW8EXPORT_TEST(testTdf150197_anlv2ListFormat, "tdf150197_anlv2ListFormat.doc")
95 CPPUNIT_ASSERT_EQUAL(u"1."_ustr, getProperty<OUString>(getParagraph(2), u"ListLabelString"_ustr));
96 CPPUNIT_ASSERT_EQUAL(u"2."_ustr, getProperty<OUString>(getParagraph(3), u"ListLabelString"_ustr));
97 CPPUNIT_ASSERT_EQUAL_MESSAGE("Did you fix me? I should be 2.1", u"4.1"_ustr,
98 getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
101 DECLARE_WW8EXPORT_TEST(testTdf117994_CRnumformatting, "tdf117994_CRnumformatting.doc")
103 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
104 assertXPath(pXmlDoc, "//body/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']", "expand", u"1.");
105 //Without this fix in place, it would become 200 (and non-bold).
106 assertXPath(pXmlDoc, "//body/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']/SwFont", "height", u"160");
109 DECLARE_WW8EXPORT_TEST(testTdf151548_formFieldMacros, "tdf151548_formFieldMacros.doc")
111 SwDoc* pDoc = getSwDoc();
112 IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
113 for(auto aIter = pMarkAccess->getFieldmarksBegin(); aIter != pMarkAccess->getFieldmarksEnd(); ++aIter)
115 const OUString sName = (*aIter)->GetName();
116 CPPUNIT_ASSERT(sName == "Check1" || sName == "Check2" || sName == "Text1" || sName == "Dropdown1");
120 DECLARE_WW8EXPORT_TEST(testTdf141649_conditionalText, "tdf141649_conditionalText.doc")
122 // In MS Word, the IF field is editable and requires manual update, so the most correct
123 // result is "manual refresh with F9" inside a text field,
124 // but for our purposes, a single instance of "trueResult" is appropriate.
125 getParagraph(1, u"trueResult"_ustr);
128 DECLARE_WW8EXPORT_TEST(testTdf91632_layoutInCellD, "tdf91632_layoutInCellD.doc")
130 // given a table with two layoutInCell images, and cell A1 has 1/2 inch border padding (margin)
131 // - A1 contains an image, vertically aligned to the outside of the page (aka cell)
132 // - B1 contains an image, vertically aligned from top of the page (aka cell)
134 // In Microsoft's layoutInCell implementation, vertical "page" is identical to "margin",
135 // and everything (including center/bottom) actually is oriented to the top of the margin.
137 xmlDocUniquePtr pDump = parseLayoutDump();
138 // Cell A1
139 sal_Int32 nShapeTop
140 = getXPath(pDump, "//tab/row[1]/cell[1]/txt[1]/anchored/fly/SwAnchoredObject/bounds",
141 "top")
142 .toInt32();
143 sal_Int32 nShapeBottom
144 = getXPath(pDump, "//tab/row[1]/cell[1]/txt[1]/anchored/fly/SwAnchoredObject/bounds",
145 "bottom")
146 .toInt32();
147 // use paragraph 1 to indicate where the cell spacing/padding ends, and the text starts.
148 sal_Int32 nPara1Top
149 = getXPath(pDump, "//tab/row[1]/cell[1]/txt[1]/infos/bounds", "top").toInt32();
150 // use paragraph 5 to prove the image is not at the bottom.
151 assertXPathContent(pDump, "//tab/row[1]/cell[1]/txt[5]", u"Below logo");
152 sal_Int32 nPara5Top
153 = getXPath(pDump, "//tab/row[1]/cell[1]/txt[5]/infos/bounds", "top").toInt32();
154 CPPUNIT_ASSERT_EQUAL(nShapeTop, nPara1Top);
155 CPPUNIT_ASSERT(nPara5Top > nShapeBottom); // ShapeBottom is higher than Para5Top
157 // In the file it is specified as "page" (PAGE_FRAME), but implemented as if it were "margin"
158 // so on import we intentionally changed it to match the closest setting to the implementation.
159 const auto xShape = getShape(1);
160 CPPUNIT_ASSERT_EQUAL(css::text::RelOrientation::PAGE_PRINT_AREA,
161 getProperty<sal_Int16>(xShape, u"VertOrientRelation"_ustr));
163 CPPUNIT_ASSERT(getProperty<bool>(xShape, u"IsFollowingTextFlow"_ustr));
165 // Cell B1
166 nShapeTop
167 = getXPath(pDump, "//tab/row[1]/cell[2]/txt[1]/anchored/fly/SwAnchoredObject/bounds",
168 "top")
169 .toInt32();
170 nShapeBottom
171 = getXPath(pDump, "//tab/row[1]/cell[2]/txt[1]/anchored/fly/SwAnchoredObject/bounds",
172 "bottom")
173 .toInt32();
174 // use paragraph 1 to indicate where the cell spacing/padding ends, and the text starts.
175 nPara1Top
176 = getXPath(pDump, "//tab/row[1]/cell[2]/txt[1]/infos/bounds", "top").toInt32();
177 // use paragraph 5 to prove the image is not at the bottom.
178 assertXPathContent(pDump, "//tab/row[1]/cell[2]/txt[5]", u"Below image");
179 nPara5Top
180 = getXPath(pDump, "//tab[1]/row/cell[2]/txt[5]/infos/bounds", "top").toInt32();
181 CPPUNIT_ASSERT_EQUAL(nShapeTop, nPara1Top);
182 CPPUNIT_ASSERT(nPara5Top > nShapeBottom); // ShapeBottom is higher than Para5Top
184 const auto xShape2 = getShape(2);
185 CPPUNIT_ASSERT_EQUAL(css::text::RelOrientation::PAGE_PRINT_AREA,
186 getProperty<sal_Int16>(xShape2, u"VertOrientRelation"_ustr));
188 CPPUNIT_ASSERT(getProperty<bool>(xShape2, u"IsFollowingTextFlow"_ustr));
191 DECLARE_WW8EXPORT_TEST(testTdf162541, "tdf162541_notLayoutInCell_paraLeft.doc")
193 // Note: this file looks very strange in MS Word. The image splits the table into two...
195 // given cell B2 with a para-left para-fromTop image that is NOT layoutInCell
196 xmlDocUniquePtr pDump = parseLayoutDump();
197 sal_Int32 nShapeLeft
198 = getXPath(pDump, "//tab/row[2]/cell[2]/txt/anchored/fly/SwAnchoredObject/bounds",
199 "left")
200 .toInt32();
201 sal_Int32 nParaLeft
202 = getXPath(pDump, "//tab/row[2]/cell[2]/txt/infos/bounds", "left").toInt32();
203 sal_Int32 nTableLeft
204 = getXPath(pDump, "//tab/infos/bounds", "left").toInt32();
205 // The image uses the table-paragraph to orient to the left (bizarre MSO layout anomaly)
206 CPPUNIT_ASSERT(nShapeLeft < nParaLeft); // shape is located in column A, not column B
207 CPPUNIT_ASSERT_EQUAL(nTableLeft, nShapeLeft);
208 CPPUNIT_ASSERT(!getProperty<bool>(getShape(1), u"IsFollowingTextFlow"_ustr));
211 DECLARE_WW8EXPORT_TEST(testTdf162542, "tdf162542_notLayoutInCell_charLeft_wrapThrough.doc")
213 // given cell B2 with a char-oriented-left wrapThrough image that is NOT layoutInCell
214 xmlDocUniquePtr pDump = parseLayoutDump();
215 sal_Int32 nShapeLeft
216 = getXPath(pDump, "//tab/row[2]/cell[2]/txt[6]/anchored/fly/SwAnchoredObject/bounds",
217 "left")
218 .toInt32();
219 sal_Int32 nPara6Left
220 = getXPath(pDump, "//tab/row[2]/cell[2]/txt[6]/infos/bounds", "left").toInt32();
221 CPPUNIT_ASSERT(nShapeLeft > nPara6Left); // nShapeLeft starts after the word "anchor"
223 // tdf#162551: The top is oriented to the top of the page - but MSO treats it as layoutInCell
224 sal_Int32 nShapeTop
225 = getXPath(pDump, "//tab/row[2]/cell[2]/txt[6]/anchored/fly/SwAnchoredObject/bounds",
226 "top")
227 .toInt32();
228 sal_Int32 nPara1Top
229 = getXPath(pDump, "//tab/row[2]/cell[2]/txt[1]/infos/bounds", "top").toInt32();
230 // layoutInCell uses the cell margin as the top-most point, not the cell edge
231 CPPUNIT_ASSERT_EQUAL(nPara1Top, nShapeTop); // nShapeTop starts at the cell margin"
233 // since in fact layoutInCell is supposed to be applied, we mark (and export) as layoutInCell
234 CPPUNIT_ASSERT(getProperty<bool>(getShape(1), u"IsFollowingTextFlow"_ustr)); // tdf#162551
237 CPPUNIT_TEST_FIXTURE(Test, testEndnotesAtSectEndDOC)
239 // Given a document, endnotes at collected at section end:
240 createSwDoc();
242 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
243 pWrtShell->SplitNode();
244 pWrtShell->Up(/*bSelect=*/false);
245 pWrtShell->Insert(u"x"_ustr);
246 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
247 SwSectionData aSection(SectionType::Content, pWrtShell->GetUniqueSectionName());
248 pWrtShell->StartAction();
249 SfxItemSetFixed<RES_FTN_AT_TXTEND, RES_FRAMEDIR> aSet(pWrtShell->GetAttrPool());
250 aSet.Put(SwFormatEndAtTextEnd(FTNEND_ATTXTEND));
251 pWrtShell->InsertSection(aSection, &aSet);
252 pWrtShell->EndAction();
253 pWrtShell->InsertFootnote(OUString(), /*bEndNote=*/true);
256 // When saving to DOC:
257 saveAndReload(u"MS Word 97"_ustr);
259 // Then make sure the endnote position is section end:
260 SwDoc* pDoc = getSwDoc();
261 SwSectionFormats& rSections = pDoc->GetSections();
262 SwSectionFormat* pFormat = rSections[0];
263 // Without the accompanying fix in place, this test would have failed, endnotes were at doc end.
264 CPPUNIT_ASSERT(pFormat->GetEndAtTextEnd().IsAtEnd());
267 DECLARE_WW8EXPORT_TEST(testTdf90408, "tdf90408.doc")
269 uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1), 1), uno::UNO_QUERY_THROW);
270 CPPUNIT_ASSERT_EQUAL_MESSAGE("checkbox is 16pt", 16.f, getProperty<float>(xRun, u"CharHeight"_ustr));
271 xRun.set(getRun(getParagraph(1), 2, u"unchecked"_ustr), uno::UNO_QUERY_THROW);
272 CPPUNIT_ASSERT_EQUAL_MESSAGE("text is 12pt", 12.f, getProperty<float>(xRun, u"CharHeight"_ustr));
275 DECLARE_WW8EXPORT_TEST(testTdf90408B, "tdf90408B.doc")
277 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
278 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
279 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
280 uno::Reference<text::XTextRange> xCell(xTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY);
282 uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY);
283 uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
284 uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
286 uno::Reference<beans::XPropertySet> xRun(getRun(xPara, 1), uno::UNO_QUERY_THROW);
287 CPPUNIT_ASSERT_EQUAL_MESSAGE("checkbox is 28pt", 28.f, getProperty<float>(xRun, u"CharHeight"_ustr));
288 xRun.set(getRun(xPara, 2, u" Κατάψυξη, "_ustr), uno::UNO_QUERY_THROW);
289 CPPUNIT_ASSERT_EQUAL_MESSAGE("text is 10pt", 10.f, getProperty<float>(xRun, u"CharHeight"_ustr));
292 DECLARE_WW8EXPORT_TEST(testTdf155465_paraAdjustDistribute, "tdf155465_paraAdjustDistribute.doc")
294 // Without the accompanying fix in place, this test would have failed with
295 // 'Expected: 2; Actual : 0', i.e. the first paragraph's ParaAdjust was left, not block.
296 const style::ParagraphAdjust eBlock = style::ParagraphAdjust_BLOCK;
297 auto nAdjust = getProperty<sal_Int16>(getParagraph(1), u"ParaAdjust"_ustr);
298 CPPUNIT_ASSERT_EQUAL(eBlock, static_cast<style::ParagraphAdjust>(nAdjust));
300 nAdjust = getProperty<sal_Int16>(getParagraph(1), u"ParaLastLineAdjust"_ustr);
301 CPPUNIT_ASSERT_EQUAL(eBlock, static_cast<style::ParagraphAdjust>(nAdjust));
303 nAdjust = getProperty<sal_Int16>(getParagraph(2), u"ParaAdjust"_ustr);
304 CPPUNIT_ASSERT_EQUAL(eBlock, static_cast<style::ParagraphAdjust>(nAdjust));
306 nAdjust = getProperty<sal_Int16>(getParagraph(2), u"ParaLastLineAdjust"_ustr);
307 CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_LEFT, static_cast<style::ParagraphAdjust>(nAdjust));
310 CPPUNIT_TEST_FIXTURE(Test, testDontBreakWrappedTables)
312 // Given a document with the DO_NOT_BREAK_WRAPPED_TABLES compat mode enabled:
313 createSwDoc();
315 SwDoc* pDoc = getSwDoc();
316 IDocumentSettingAccess& rIDSA = pDoc->getIDocumentSettingAccess();
317 rIDSA.set(DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES, true);
320 // When saving to doc:
321 saveAndReload(u"MS Word 97"_ustr);
323 // Then make sure the compat flag is serialized:
324 SwDoc* pDoc = getSwDoc();
325 IDocumentSettingAccess& rIDSA = pDoc->getIDocumentSettingAccess();
326 bool bDontBreakWrappedTables = rIDSA.get(DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES);
327 // Without the accompanying fix in place, this test would have failed, the compat flag was not
328 // set.
329 CPPUNIT_ASSERT(bDontBreakWrappedTables);
332 CPPUNIT_TEST_FIXTURE(Test, testFloattableOverlapNeverDOCExport)
334 // Given a document with a floating table, overlap is not allowed:
336 createSwDoc();
337 SwDoc* pDoc = getSwDoc();
338 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
339 pWrtShell->Insert2(u"before table"_ustr);
340 // Insert a table:
341 SwInsertTableOptions aTableOptions(SwInsertTableFlags::DefaultBorder, 0);
342 pWrtShell->InsertTable(aTableOptions, /*nRows=*/1, /*nCols=*/1);
343 pWrtShell->MoveTable(GotoPrevTable, fnTableStart);
344 // Select table:
345 pWrtShell->SelAll();
346 // Wrap the table in a text frame:
347 SwFlyFrameAttrMgr aMgr(true, pWrtShell, Frmmgr_Type::TEXT, nullptr);
348 pWrtShell->StartAllAction();
349 aMgr.InsertFlyFrame(RndStdIds::FLY_AT_PARA, aMgr.GetPos(), aMgr.GetSize());
350 pWrtShell->EndAllAction();
351 // Allow the text frame to split:
352 pWrtShell->StartAllAction();
353 sw::FrameFormats<sw::SpzFrameFormat*>* pFlys = pDoc->GetSpzFrameFormats();
354 sw::SpzFrameFormat* pFly = (*pFlys)[0];
355 SwAttrSet aSet(pFly->GetAttrSet());
356 aSet.Put(SwFormatFlySplit(true));
357 // Don't allow overlap:
358 SwFormatWrapInfluenceOnObjPos aInfluence;
359 aInfluence.SetAllowOverlap(false);
360 aSet.Put(aInfluence);
361 pDoc->SetAttr(aSet, *pFly);
362 pWrtShell->EndAllAction();
365 // When saving to DOC:
366 saveAndReload(u"MS Word 97"_ustr);
368 // Then make sure that the overlap=never markup is written:
369 SwDoc* pDoc = getSwDoc();
370 sw::FrameFormats<sw::SpzFrameFormat*>* pFlys = pDoc->GetSpzFrameFormats();
371 sw::SpzFrameFormat* pFly = (*pFlys)[0];
372 // Without the accompanying fix in place, this test would have failed, i.e. TFNoAllowOverlap was
373 // not written.
374 CPPUNIT_ASSERT(!pFly->GetAttrSet().GetWrapInfluenceOnObjPos().GetAllowOverlap());
377 bool IsFirstLine(const SwTextNode* pTextNode)
379 const SfxPoolItem* pItem = pTextNode->GetNoCondAttr(RES_MARGIN_FIRSTLINE, false);
380 return !!pItem;
383 DECLARE_WW8EXPORT_TEST(testInlinePageBreakFirstLine, "inlinePageBreakFirstLine.doc")
385 SwDoc* pDoc = getSwDoc();
386 const SwNodes& rNodes = pDoc->GetNodes();
388 std::vector<SwTextNode*> aTextNodes;
390 for (SwNodeOffset nNode(0); nNode < rNodes.Count(); ++nNode)
392 SwNode* pNode = pDoc->GetNodes()[nNode];
393 SwTextNode* pTextNode = pNode->GetTextNode();
394 if (!pTextNode)
395 continue;
396 aTextNodes.push_back(pTextNode);
399 CPPUNIT_ASSERT_EQUAL(size_t(3), aTextNodes.size());
400 CPPUNIT_ASSERT_EQUAL(u"First line"_ustr, aTextNodes[0]->GetText());
401 CPPUNIT_ASSERT(IsFirstLine(aTextNodes[0]));
402 // Here exists an inline pagebreak (a pagebreak without a paragraph before it)
403 // This text node is not indented because it is not the first line of the paragraph
404 CPPUNIT_ASSERT_EQUAL(u"Should not be indented"_ustr, aTextNodes[1]->GetText());
405 CPPUNIT_ASSERT(!IsFirstLine(aTextNodes[1]));
406 // Here is the actual second paragraph
407 CPPUNIT_ASSERT_EQUAL(u"Should be indented"_ustr, aTextNodes[2]->GetText());
408 CPPUNIT_ASSERT(IsFirstLine(aTextNodes[2]));
411 CPPUNIT_TEST_FIXTURE(Test, testLegalNumbering)
413 auto verify = [this]() {
414 // Second level's numbering should use Arabic numbers for first level reference
415 auto xPara = getParagraph(1);
416 CPPUNIT_ASSERT_EQUAL(u"CH I"_ustr, getProperty<OUString>(xPara, u"ListLabelString"_ustr));
417 xPara = getParagraph(2);
418 // Without the accompanying fix in place, this test would have failed with:
419 // - Expected: Sect 1.01
420 // - Actual : Sect I.01
421 // i.e. fLegal was ignored on import/export.
422 CPPUNIT_ASSERT_EQUAL(u"Sect 1.01"_ustr, getProperty<OUString>(xPara, u"ListLabelString"_ustr));
423 xPara = getParagraph(3);
424 CPPUNIT_ASSERT_EQUAL(u"CH II"_ustr, getProperty<OUString>(xPara, u"ListLabelString"_ustr));
425 xPara = getParagraph(4);
426 CPPUNIT_ASSERT_EQUAL(u"Sect 2.01"_ustr, getProperty<OUString>(xPara, u"ListLabelString"_ustr));
429 createSwDoc("listWithLgl.doc");
430 verify();
431 saveAndReload(mpFilter);
432 verify();
435 CPPUNIT_TEST_FIXTURE(Test, testDOCExportDoNotMirrorRtlDrawObjs)
437 // Given a document with a shape, anchored in an RTL paragraph, loaded from DOCX:
438 createSwDoc("draw-obj-rtl-no-mirror-vml.docx");
440 // When saving that to DOC:
441 saveAndReload(mpFilter);
443 // Then make sure the shape is on the right margin:
444 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
445 sal_Int32 nPageRight = getXPath(pXmlDoc, "//page/infos/bounds", "right").toInt32();
446 sal_Int32 nBodyRight = getXPath(pXmlDoc, "//body/infos/bounds", "right").toInt32();
447 sal_Int32 nShapeLeft
448 = getXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds", "left").toInt32();
449 CPPUNIT_ASSERT_GREATER(nBodyRight, nShapeLeft);
450 sal_Int32 nShapeRight
451 = getXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds", "right").toInt32();
452 // Without the accompanying fix in place, this test would have failed with:
453 // - Expected less than: 12523
454 // - Actual : 12536
455 // i.e. the shape was outside of the page right margin area, due to an unwanted mapping.
456 CPPUNIT_ASSERT_LESS(nPageRight, nShapeRight);
459 DECLARE_WW8EXPORT_TEST(testNonInlinePageBreakFirstLine, "nonInlinePageBreakFirstLine.doc")
461 SwDoc* pDoc = getSwDoc();
462 const SwNodes& rNodes = pDoc->GetNodes();
464 std::vector<SwTextNode*> aTextNodes;
466 for (SwNodeOffset nNode(0); nNode < rNodes.Count(); ++nNode)
468 SwNode* pNode = pDoc->GetNodes()[nNode];
469 SwTextNode* pTextNode = pNode->GetTextNode();
470 if (!pTextNode)
471 continue;
472 aTextNodes.push_back(pTextNode);
475 CPPUNIT_ASSERT_EQUAL(size_t(2), aTextNodes.size());
476 CPPUNIT_ASSERT_EQUAL(u"First line"_ustr, aTextNodes[0]->GetText());
477 CPPUNIT_ASSERT(IsFirstLine(aTextNodes[0]));
478 // Here exists a pagebreak after a paragraph
479 // This text node is indented because it is the first line of a paragraph
480 CPPUNIT_ASSERT_EQUAL(u"Should be indented"_ustr, aTextNodes[1]->GetText());
481 CPPUNIT_ASSERT(IsFirstLine(aTextNodes[1]));
484 DECLARE_WW8EXPORT_TEST(testTdf104704_mangledFooter, "tdf104704_mangledFooter.odt")
486 CPPUNIT_ASSERT_EQUAL(2, getPages());
489 CPPUNIT_TEST_FIXTURE(Test, testEmptyGroup)
491 // Given a document with an empty group
492 createSwDoc("empty_group.docx");
494 CPPUNIT_ASSERT_EQUAL(1, getPages());
495 CPPUNIT_ASSERT_EQUAL(1, getShapes());
496 SwDoc* pDoc = getSwDoc();
497 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
498 SdrObject* pObject = pPage->GetObj(0);
500 CPPUNIT_ASSERT_EQUAL(u"Empty group"_ustr, pObject->GetName());
501 CPPUNIT_ASSERT(pObject->IsGroupObject());
502 CPPUNIT_ASSERT_EQUAL(size_t(0), pObject->GetSubList()->GetObjCount());
504 // it must not assert/crash on save
505 saveAndReload(mpFilter);
508 CPPUNIT_TEST_FIXTURE(Test, testTdf135709)
510 createSwDoc("tdf135709.odt");
511 saveAndReload("MS Word 97");
513 uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
514 uno::Reference<beans::XPropertySet> xPropertySet(xTextFramesSupplier->getTextFrames()->getByName("Frame1") , uno::UNO_QUERY);
516 xPropertySet->setPropertyValue("AnchorType",
517 uno::Any(text::TextContentAnchorType_AT_CHARACTER));
519 text::WrapTextMode eValue;
520 xPropertySet->getPropertyValue("Surround") >>= eValue;
521 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrap should be PARALLEL", text::WrapTextMode_PARALLEL, eValue);
524 CPPUNIT_TEST_FIXTURE(Test, testTdf135710)
526 // Uses same test doc as testTdf135709
527 createSwDoc("tdf135709.odt");
528 saveAndReload("MS Word 97");
530 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
532 sal_Int32 nFlyLeft = getXPath(pXmlDoc, "(//anchored)[1]/fly/infos/bounds", "left").toInt32();
534 // Set the anchor of the image to AT PARAGRAPH, without the fix in place this
535 // results in the picture moving to the first column
536 uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
537 uno::Reference<beans::XPropertySet> xPropertySet(xTextFramesSupplier->getTextFrames()->getByName("Frame1") , uno::UNO_QUERY);
538 xPropertySet->setPropertyValue("AnchorType",
539 uno::Any(text::TextContentAnchorType_AT_PARAGRAPH));
540 pXmlDoc = parseLayoutDump();
542 sal_Int32 nFlyLeftAfter = getXPath(pXmlDoc, "(//anchored)[1]/fly/infos/bounds", "left").toInt32();
544 // Without the fix in place this fails with
545 // Expected: 4771
546 // Actual: 1418
547 // i.e. the picture has moved from the second column to the first column
548 CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<double>(nFlyLeft), static_cast<double>(nFlyLeftAfter), 2.0);
551 CPPUNIT_TEST_FIXTURE(Test, testTdf56738)
553 auto verify = [this]() {
554 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
555 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
556 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
558 // make sure we get to the correct field to test
559 CPPUNIT_ASSERT(xFields->hasMoreElements());
560 uno::Reference<text::XTextField> xField;
561 xField.set(xFields->nextElement(), uno::UNO_QUERY);
562 CPPUNIT_ASSERT_EQUAL(u"2"_ustr, xField->getPresentation(false));
564 CPPUNIT_ASSERT(xFields->hasMoreElements());
565 xField.set(xFields->nextElement(), uno::UNO_QUERY_THROW);
566 CPPUNIT_ASSERT_EQUAL(u"3"_ustr, xField->getPresentation(false));
568 CPPUNIT_ASSERT(xFields->hasMoreElements());
569 xField.set(xFields->nextElement(), uno::UNO_QUERY_THROW);
570 OUString sExpComment1(u"Como eu vou saber se é a USG é anterior a 20s????"_ustr);
571 CPPUNIT_ASSERT_EQUAL(sExpComment1, getProperty<OUString>(xField, u"Content"_ustr));
573 CPPUNIT_ASSERT(xFields->hasMoreElements());
574 xField.set(xFields->nextElement(), uno::UNO_QUERY_THROW);
576 OUString sExpComment(u"Não sei se é relevante esta pergunta. O que eu queria saber é se o médico ate\
577 nde muito parto na água. Tb posso fazer porcentagem de atendimento..."_ustr);
579 // Without the fix in place this fails with
580 // Expected: Não sei se é relevante esta pergunta. O que eu queria saber é
581 // se o médico atende muito parto na água. Tb posso fazer porcentagem de atendimento...
582 // Actual: N縊 sei se �relevante esta pergunta. O que eu queria saber �
583 // se o m馘ico atende muito parto na 疊ua. Tb posso fazer porcentagem de atendimento...
584 // i.e. the display characters of the second comment were getting re-interpreted from Latin-1 to Shift-Js
585 CPPUNIT_ASSERT_EQUAL(sExpComment, getProperty<OUString>(xField, u"Content"_ustr));
588 // make sure everything survives roundtrip
589 createSwDoc("tdf56738.doc");
590 verify();
591 saveAndReload(mpFilter);
592 verify();
595 CPPUNIT_TEST_FIXTURE(Test, testTdf120629)
597 createSwDoc("tdf120629.odt");
599 sal_Int16 numFormat = getNumberingTypeOfParagraph(1);
600 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(56), numFormat);
602 saveAndReload("MS Word 97");
603 sal_Int16 numFormat_after = getNumberingTypeOfParagraph(1);
604 // Without the fix in place this fails with
605 // Expected: 56
606 // Actual: 4
607 // i.e. numbering type gets changed to ARABIC, should stay the same
608 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(56), numFormat_after);
611 CPPUNIT_TEST_FIXTURE(Test, testTdf54862)
613 createSwDoc("tdf54862.doc");
614 auto verify = [this]() {
615 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
616 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
617 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
619 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
621 sal_Int32 nCellA2Height = getXPath(pXmlDoc, "//tab/row[1]/cell[2]/infos/bounds", "height").toInt32();
622 sal_Int32 nCellB4Height = getXPath(pXmlDoc, "//tab/row[4]/cell[2]/infos/bounds", "height").toInt32();
624 // Without the fix in place this is this fails with:
625 // Expected: 1269, 9021
626 // Actual: 562, 623
627 // i.e. Cells A2 and B4 are not vertically merged, making them the wrong height
628 CPPUNIT_ASSERT_EQUAL(sal_Int32(1269), nCellA2Height);
629 CPPUNIT_ASSERT_EQUAL(sal_Int32(9021), nCellB4Height);
632 verify();
633 saveAndReload(mpFilter);
634 verify();
637 DECLARE_WW8EXPORT_TEST(testTdf85435, "tdf85435.doc")
639 // Without the fix, this document only has one page.
640 CPPUNIT_ASSERT_EQUAL(2, getPages());
643 } // end of anonymous namespace
644 CPPUNIT_PLUGIN_IMPLEMENT();
646 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */