android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / qa / extras / rtfexport / rtfexport3.cxx
blob6ce4b179ccfade4272630c50f347330ec34bd008
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/text/XFootnote.hpp>
13 #include <com/sun/star/text/XFootnotesSupplier.hpp>
14 #include <com/sun/star/awt/FontWeight.hpp>
15 #include <com/sun/star/text/XEndnotesSupplier.hpp>
16 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
17 #include <com/sun/star/text/XTextTablesSupplier.hpp>
18 #include <com/sun/star/text/XTextTable.hpp>
19 #include <com/sun/star/text/XTextDocument.hpp>
20 #include <com/sun/star/style/TabStop.hpp>
22 #include <comphelper/sequenceashashmap.hxx>
23 #include <tools/UnitConversion.hxx>
24 #include <comphelper/propertyvalue.hxx>
26 #include <unotxdoc.hxx>
27 #include <docsh.hxx>
28 #include <wrtsh.hxx>
29 #include <fmtpdsc.hxx>
30 #include <IDocumentContentOperations.hxx>
31 #include <IDocumentSettingAccess.hxx>
32 #include <itabenum.hxx>
33 #include <frmmgr.hxx>
34 #include <formatflysplit.hxx>
35 #include <fmtwrapinfluenceonobjpos.hxx>
37 using namespace css;
39 class Test : public SwModelTestBase
41 public:
42 Test()
43 : SwModelTestBase("/sw/qa/extras/rtfexport/data/", "Rich Text Format")
48 DECLARE_RTFEXPORT_TEST(testTdf100961_fixedDateTime, "tdf100961_fixedDateTime.rtf")
50 // This should be a fixed date/time field, not the current time.
51 getParagraph(1, "05.01.19 04:06:08");
53 uno::Reference<text::XTextFieldsSupplier> xTFS(mxComponent, uno::UNO_QUERY);
54 uno::Reference<container::XEnumeration> xFields(xTFS->getTextFields()->createEnumeration());
55 CPPUNIT_ASSERT_MESSAGE("constant time", getProperty<bool>(xFields->nextElement(), "IsFixed"));
58 DECLARE_RTFEXPORT_TEST(testTdf108949, "tdf108949_footnoteCharFormat.odt")
60 CPPUNIT_ASSERT_EQUAL(1, getPages());
61 CPPUNIT_ASSERT_EQUAL_MESSAGE("Paragraph Numbering style", OUString(),
62 getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
64 uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
65 uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
67 uno::Reference<text::XText> xFootnoteText;
68 xFootnotes->getByIndex(0) >>= xFootnoteText;
69 // This was green (0x00A800), the character property of the footnote character, not the footnote text
70 CPPUNIT_ASSERT_EQUAL_MESSAGE(
71 "Footnote Text color", COL_AUTO,
72 getProperty<Color>(getRun(getParagraphOfText(1, xFootnoteText), 1), "CharColor"));
75 DECLARE_RTFEXPORT_TEST(testTdf141964_numId0, "tdf141964_numId0.rtf")
77 // Unit test added where numId is zero - which is only possible in RTF.
78 uno::Reference<beans::XPropertySet> xPara(getParagraph(3, "Geschichte"), uno::UNO_QUERY);
79 // Pre-emptive test: ensure that paragraph 3 remains numbered and numId0 doesn't mean no numbering.
80 CPPUNIT_ASSERT(!getProperty<OUString>(xPara, "NumberingStyleName").isEmpty());
83 DECLARE_RTFEXPORT_TEST(testTdf108949_footnote, "tdf108949_footnote.rtf")
85 CPPUNIT_ASSERT_EQUAL_MESSAGE("Paragraph Numbering style", OUString(),
86 getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
88 uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
89 uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
91 uno::Reference<text::XFootnote> xFootnote;
92 xFootnotes->getByIndex(0) >>= xFootnote;
93 // The color of the footnote anchor was black (0x000000)
94 CPPUNIT_ASSERT_EQUAL_MESSAGE("Footnote Character color", Color(0xFF0000),
95 getProperty<Color>(xFootnote->getAnchor(), "CharColor"));
98 DECLARE_RTFEXPORT_TEST(testTdf130817, "tdf130817.rtf")
100 uno::Reference<text::XEndnotesSupplier> xEndnotesSupplier(mxComponent, uno::UNO_QUERY);
101 uno::Reference<container::XIndexAccess> xEndnotes = xEndnotesSupplier->getEndnotes();
103 uno::Reference<text::XFootnote> xEndnote1;
104 xEndnotes->getByIndex(0) >>= xEndnote1;
105 uno::Reference<text::XText> xEndnoteText1;
106 xEndnotes->getByIndex(0) >>= xEndnoteText1;
107 CPPUNIT_ASSERT_EQUAL(OUString("Titolo 1"), xEndnoteText1->getString().trim());
108 CPPUNIT_ASSERT_EQUAL(OUString("$"), xEndnote1->getAnchor()->getString());
110 uno::Reference<text::XFootnote> xEndnote2;
111 xEndnotes->getByIndex(1) >>= xEndnote2;
112 uno::Reference<text::XText> xEndnoteText2;
113 xEndnotes->getByIndex(1) >>= xEndnoteText2;
114 CPPUNIT_ASSERT_EQUAL(OUString("Titolo 2"), xEndnoteText2->getString().trim());
115 CPPUNIT_ASSERT_EQUAL(OUString("$"), xEndnote1->getAnchor()->getString());
118 DECLARE_RTFEXPORT_TEST(testTdf154129_transparentFrame, "tdf154129_transparentFrame.rtf")
120 // Without the fix, this was zero, and the text frame with "Visible" just looks white.
121 CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty<sal_Int16>(getShape(1), "FillTransparence"));
124 DECLARE_RTFEXPORT_TEST(testTdf137683_charHighlightNone, "tdf137683_charHighlightNone.rtf")
126 uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1), 1), uno::UNO_QUERY_THROW);
127 // This test was failing with a brown charHighlight of 8421376 (0x808000), instead of COL_TRANSPARENT (0xFFFFFFFF)
128 CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xRun, "CharHighlight"));
131 DECLARE_RTFEXPORT_TEST(testTdf116436_tableBackground, "tdf116436_tableBackground.odt")
133 CPPUNIT_ASSERT_EQUAL(1, getPages());
134 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
135 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
136 uno::UNO_QUERY);
137 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
138 uno::Reference<table::XCell> xCell = xTable->getCellByName("A1");
139 if (isExported())
140 CPPUNIT_ASSERT_EQUAL(Color(0xF8DF7C), getProperty<Color>(xCell, "BackColor"));
141 xCell.set(xTable->getCellByName("A6"));
142 CPPUNIT_ASSERT_EQUAL(Color(0x81D41A), getProperty<Color>(xCell, "BackColor"));
143 xCell.set(xTable->getCellByName("B6"));
144 if (isExported())
145 CPPUNIT_ASSERT_EQUAL(Color(0xFFFBCC), getProperty<Color>(xCell, "BackColor"));
148 DECLARE_RTFEXPORT_TEST(testTdf122589_firstSection, "tdf122589_firstSection.odt")
150 CPPUNIT_ASSERT_EQUAL(1, getPages());
151 uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"),
152 uno::UNO_QUERY);
153 uno::Reference<text::XTextRange> xHeaderText
154 = getProperty<uno::Reference<text::XTextRange>>(xPageStyle, "HeaderText");
155 CPPUNIT_ASSERT_EQUAL(OUString("My header"), xHeaderText->getString());
157 CPPUNIT_ASSERT_EQUAL_MESSAGE("# of paragraphs", 2, getParagraphs());
160 DECLARE_RTFEXPORT_TEST(testTdf104035, "tdf104035.rtf")
162 auto aTabStops = getProperty<uno::Sequence<style::TabStop>>(getParagraph(1), "ParaTabStops");
163 CPPUNIT_ASSERT(aTabStops.hasElements());
164 // This was 3330 twips instead, as tabs were assumed to be relative.
165 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(convertTwipToMm100(450)), aTabStops[0].Position);
168 DECLARE_RTFEXPORT_TEST(testGraphicObjectFliph, "graphic-object-fliph.rtf")
170 CPPUNIT_ASSERT(getProperty<bool>(getShape(1), "HoriMirroredOnEvenPages"));
171 CPPUNIT_ASSERT(getProperty<bool>(getShape(1), "HoriMirroredOnOddPages"));
174 DECLARE_RTFEXPORT_TEST(testTdf114333, "tdf114333.rtf")
176 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
177 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
178 uno::UNO_QUERY);
179 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
180 // Check the distance from left
181 CPPUNIT_ASSERT_EQUAL(sal_Int32(8502), getProperty<sal_Int32>(xTable, "LeftMargin"));
182 // This was 17000 = 8502 + 8498 on import, 15240 on export and following import
183 CPPUNIT_ASSERT_EQUAL(sal_Int32(8498), getProperty<sal_Int32>(xTable, "Width"));
186 DECLARE_RTFEXPORT_TEST(testTdf115180, "tdf115180.docx")
188 // On export to RTF, column separator positions were written without taking base width
189 // into account and then arrived huge, ~64000, which resulted in wrong table and cell widths
191 sal_Int32 rowWidth = parseDump("/root/page/body/tab/row/infos/bounds", "width").toInt32();
192 CPPUNIT_ASSERT_EQUAL_MESSAGE("Row width", sal_Int32(9360), rowWidth);
193 sal_Int32 cell1Width
194 = parseDump("/root/page/body/tab/row/cell[1]/infos/bounds", "width").toInt32();
195 CPPUNIT_ASSERT_MESSAGE("First cell width", cell1Width >= 9140);
196 CPPUNIT_ASSERT_MESSAGE("First cell width", cell1Width <= 9142);
197 sal_Int32 cell2Width
198 = parseDump("/root/page/body/tab/row/cell[2]/infos/bounds", "width").toInt32();
199 CPPUNIT_ASSERT_MESSAGE("Second cell width", cell2Width >= 218);
200 CPPUNIT_ASSERT_MESSAGE("Second cell width", cell2Width <= 220);
203 DECLARE_ODFEXPORT_TEST(testArabicZeroNumbering, "arabic-zero-numbering.rtf")
205 auto xNumberingRules
206 = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1), "NumberingRules");
207 comphelper::SequenceAsHashMap aMap(xNumberingRules->getByIndex(0));
208 // Without the accompanying fix in place, this test would have failed with:
209 // - Expected: 64
210 // - Actual : 4
211 // i.e. numbering type was ARABIC, not ARABIC_ZERO.
212 CPPUNIT_ASSERT_EQUAL(o3tl::narrowing<sal_uInt16>(style::NumberingType::ARABIC_ZERO),
213 aMap["NumberingType"].get<sal_uInt16>());
216 DECLARE_RTFEXPORT_TEST(testTdf116841, "tdf116841.rtf")
218 // This was 0, left margin was ignored as we assumed the default is already
219 // fine for us.
220 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1270),
221 getProperty<sal_Int32>(getParagraph(1), "ParaLeftMargin"));
224 DECLARE_RTFEXPORT_TEST(testTdf117268, "tdf117268.rtf")
226 // Here we check that we correctly mimic Word's treatment of erroneous \itap0 inside tables.
227 // Previously, the first table was import as text, and second top-level one only imported
228 // last row with nested table (first row was also imported as text).
229 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY_THROW);
230 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
231 uno::UNO_QUERY_THROW);
233 // First (simple) table
234 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY_THROW);
235 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getRows()->getCount());
236 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getColumns()->getCount());
237 uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY_THROW);
238 CPPUNIT_ASSERT_EQUAL(OUString("Text 1"), xCell->getString());
240 // Nested table
241 xTable.set(xTables->getByIndex(1), uno::UNO_QUERY_THROW);
242 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getRows()->getCount());
243 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getColumns()->getCount());
244 xCell.set(xTable->getCellByName("A1"), uno::UNO_QUERY_THROW);
245 CPPUNIT_ASSERT_EQUAL(OUString("Text 3"), xCell->getString());
246 uno::Reference<beans::XPropertySet> xNestedAnchor(xTable->getAnchor(), uno::UNO_QUERY_THROW);
247 uno::Reference<text::XTextRange> xAnchorCell(xNestedAnchor->getPropertyValue("Cell"),
248 uno::UNO_QUERY_THROW);
250 // Outer table
251 xTable.set(xTables->getByIndex(2), uno::UNO_QUERY_THROW);
252 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable->getRows()->getCount());
253 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getColumns()->getCount());
254 xCell.set(xTable->getCellByName("A1"), uno::UNO_QUERY_THROW);
255 CPPUNIT_ASSERT_EQUAL(OUString("Text 2"), xCell->getString());
256 xCell.set(xTable->getCellByName("A2"), uno::UNO_QUERY_THROW);
257 CPPUNIT_ASSERT_EQUAL(xCell, xAnchorCell);
260 DECLARE_RTFEXPORT_TEST(testTdf117505, "tdf117505.odt")
262 CPPUNIT_ASSERT_EQUAL(1, getShapes());
263 CPPUNIT_ASSERT_EQUAL(1, getPages());
264 uno::Reference<container::XNameAccess> xPageStyles(getStyles("PageStyles"));
265 uno::Reference<beans::XPropertySet> xFirstPage(xPageStyles->getByName("First Page"),
266 uno::UNO_QUERY);
267 // This was 499, small header height resulted in visible whitespace from
268 // remaining top margin -> header content moved down.
269 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1499),
270 getProperty<sal_Int32>(xFirstPage, "HeaderHeight"));
273 DECLARE_RTFEXPORT_TEST(testTdf112520, "tdf112520.docx")
275 if (!isExported())
276 return;
278 // Assert that the white shape is on top of the yellow one.
279 CPPUNIT_ASSERT_EQUAL(Color(0xffff00), getProperty<Color>(getShape(2), "FillColor"));
280 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,
281 getProperty<text::TextContentAnchorType>(getShape(2), "AnchorType"));
282 CPPUNIT_ASSERT_EQUAL(COL_WHITE, getProperty<Color>(getShape(3), "FillColor"));
283 // Without the accompanying fix in place, this test would have failed with
284 // 'expected: 4, actual: 2'.
285 // This means the draw page was 0/at-char/white, 1/at-char/yellow, 2/at-page/white,
286 // instead of the good 0/at-page/white, 1/at-char/yellow, 2/at-char/white.
287 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,
288 getProperty<text::TextContentAnchorType>(getShape(3), "AnchorType"));
291 CPPUNIT_TEST_FIXTURE(Test, testNestedHyperlink)
293 // Given a hyperlink contains a footnote which contains a hyperlink:
295 createSwDoc();
296 uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
297 uno::Reference<text::XTextContent> xFootnote(
298 xFactory->createInstance("com.sun.star.text.Footnote"), uno::UNO_QUERY);
299 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
300 uno::Reference<text::XText> xText = xTextDocument->getText();
301 uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
302 xText->insertString(xCursor, "a", /*bAbsorb=*/false);
303 xText->insertTextContent(xCursor, xFootnote, /*bAbsorb=*/false);
304 xText->insertString(xCursor, "b", /*bAbsorb=*/false);
305 xCursor->gotoStart(/*bExpand=*/false);
306 xCursor->gotoEnd(/*bExpand=*/true);
307 uno::Reference<beans::XPropertySet> xCursorProps(xCursor, uno::UNO_QUERY);
308 xCursorProps->setPropertyValue("HyperLinkURL", uno::Any(OUString("http://body.com/")));
309 uno::Reference<text::XText> xFootnoteText(xFootnote, uno::UNO_QUERY);
310 xCursor = xFootnoteText->createTextCursor();
311 xFootnoteText->insertString(xCursor, "x", /*bAbsorb=*/false);
312 xCursor->gotoStart(/*bExpand=*/false);
313 xCursor->gotoEnd(/*bExpand=*/true);
314 xCursorProps.set(xCursor, uno::UNO_QUERY);
315 xCursorProps->setPropertyValue("HyperLinkURL", uno::Any(OUString("http://footnote.com/")));
318 // When exporting to RTF:
319 // Without the accompanying fix in place, this test would have failed with:
320 // assertion failed
321 // - Expression: xComponent.is()
322 // i.e. the RTF output was not well-formed, loading failed.
323 saveAndReload("Rich Text Format");
325 // Then make sure both hyperlinks are have the correct URLs.
326 uno::Reference<text::XTextRange> xParagraph = getParagraph(1);
327 uno::Reference<text::XTextRange> xPortion = getRun(xParagraph, 1);
328 CPPUNIT_ASSERT_EQUAL(OUString("http://body.com/"),
329 getProperty<OUString>(xPortion, "HyperLinkURL"));
330 auto xFootnote = getProperty<uno::Reference<text::XText>>(getRun(xParagraph, 2), "Footnote");
331 uno::Reference<text::XTextRange> xFootnotePortion = getRun(getParagraphOfText(1, xFootnote), 1);
332 CPPUNIT_ASSERT_EQUAL(OUString("http://footnote.com/"),
333 getProperty<OUString>(xFootnotePortion, "HyperLinkURL"));
336 DECLARE_RTFEXPORT_TEST(testTdf121623, "tdf121623.rtf")
338 // This was 2, multicolumn section was ignored at the table.
339 CPPUNIT_ASSERT_EQUAL(1, getPages());
342 DECLARE_RTFEXPORT_TEST(testTdf66543, "tdf66543.rtf")
344 // Without the accompanying fix in place, this test would have failed with
345 // 'Expected: 2; Actual : 3' after import (off-by-one), then with
346 // 'Expected: 2; Actual : 0' (export not implemented).
347 CPPUNIT_ASSERT_EQUAL(sal_Int32(2),
348 getProperty<sal_Int32>(getParagraph(1), "ParaLineNumberStartValue"));
351 DECLARE_RTFEXPORT_TEST(testUlw, "ulw.rtf")
353 // Test underlying in individual words mode.
354 CPPUNIT_ASSERT(getProperty<bool>(getRun(getParagraph(1), 1), "CharWordMode"));
357 DECLARE_RTFEXPORT_TEST(testTdf122455, "tdf122455.rtf")
359 // Without the accompanying fix in place, this test would have failed with
360 // 'Expected: 16; Actual : 32', the font size from a list definition
361 // leaked into the first run's character properties.
362 CPPUNIT_ASSERT_EQUAL(16.0, getProperty<double>(getRun(getParagraph(1), 1), "CharHeight"));
365 DECLARE_RTFEXPORT_TEST(testTdf125719_case_1, "tdf125719_case_1.rtf")
367 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL,
368 getProperty<float>(getRun(getParagraph(1), 1), "CharWeight"));
369 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL,
370 getProperty<float>(getRun(getParagraph(3), 1), "CharWeight"));
373 DECLARE_RTFEXPORT_TEST(testTdf125719_case_2, "tdf125719_case_2.rtf")
375 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD,
376 getProperty<float>(getRun(getParagraph(1), 1), "CharWeight"));
377 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD,
378 getProperty<float>(getRun(getParagraph(3), 1), "CharWeight"));
379 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL,
380 getProperty<float>(getRun(getParagraph(5), 1), "CharWeight"));
383 DECLARE_RTFEXPORT_TEST(testTabs, "tabs.rtf")
385 // Test tab alignment in decimal mode.
386 auto aTabStops = getProperty<uno::Sequence<style::TabStop>>(getParagraph(1), "ParaTabStops");
387 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aTabStops.getLength());
388 const style::TabStop& rTabStop = aTabStops[0];
389 CPPUNIT_ASSERT_EQUAL(style::TabAlign_DECIMAL, rTabStop.Alignment);
392 DECLARE_RTFEXPORT_TEST(testTdf123703, "tdf123703.rtf")
394 #if !defined(MACOSX)
395 // This was 1, because of normal space character width in consecutive spaces
396 CPPUNIT_ASSERT_EQUAL(2, getPages());
397 #else
398 // still 1 here
399 CPPUNIT_ASSERT_EQUAL(1, getPages());
400 #endif
403 DECLARE_RTFEXPORT_TEST(testTdf123703_stshfdbch, "tdf123703_stshfdbch.rtf")
405 // still 1 here
406 CPPUNIT_ASSERT_EQUAL(1, getPages());
409 DECLARE_RTFEXPORT_TEST(testTdf123703_compatible, "tdf123703_compatible.rtf")
411 #if !defined(MACOSX)
412 // in the case of compatibility font id 31505
413 CPPUNIT_ASSERT_EQUAL(2, getPages());
414 #else
415 // still 1 here
416 CPPUNIT_ASSERT_EQUAL(1, getPages());
417 #endif
420 DECLARE_RTFEXPORT_TEST(testTdf128428_monospaced, "tdf128428_monospaced.rtf")
422 // still 1 here
423 CPPUNIT_ASSERT_EQUAL(1, getPages());
426 DECLARE_RTFEXPORT_TEST(testTdf128428_compatible_monospaced, "tdf128428_compatible_monospaced.rtf")
428 // still 1 here
429 CPPUNIT_ASSERT_EQUAL(1, getPages());
432 DECLARE_RTFEXPORT_TEST(testTdf128428_dntblnsbdb, "tdf128428_dntblnsbdb.rtf")
434 // still 1 here
435 CPPUNIT_ASSERT_EQUAL(1, getPages());
438 CPPUNIT_TEST_FIXTURE(Test, testDontBreakWrappedTables)
440 // Given a document with no DO_NOT_BREAK_WRAPPED_TABLES compat mode enabled:
441 createSwDoc();
443 SwDoc* pDoc = getSwDoc();
444 IDocumentSettingAccess& rIDSA = pDoc->getIDocumentSettingAccess();
445 rIDSA.set(DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES, true);
448 // When saving to rtf:
449 saveAndReload("Rich Text Format");
451 // Then make sure \nobrkwrptbl is not written:
452 SwDoc* pDoc = getSwDoc();
453 IDocumentSettingAccess& rIDSA = pDoc->getIDocumentSettingAccess();
454 bool bDontBreakWrappedTables = rIDSA.get(DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES);
455 // Without the accompanying fix in place, this test would have failed, the compat flag was not
456 // set.
457 CPPUNIT_ASSERT(bDontBreakWrappedTables);
460 CPPUNIT_TEST_FIXTURE(Test, testRtlGutter)
462 auto verify = [this]() {
463 uno::Reference<beans::XPropertySet> xStandard(
464 getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
465 CPPUNIT_ASSERT(getProperty<bool>(xStandard, "RtlGutter"));
468 // Given a document with RTL gutter, when loading it:
469 createSwDoc("rtl-gutter.rtf");
470 // Then make sure the section's gutter is still RTL:
471 // Without the accompanying fix in place, this test would have failed as \rtlgutter was missing.
472 verify();
473 saveAndReload("Rich Text Format");
474 verify();
477 CPPUNIT_TEST_FIXTURE(Test, testNegativePageBorder)
480 // Given a document with a top margin and a border which has more spacing than the margin on
481 // its 2nd page:
482 createSwDoc();
483 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
484 SwDocShell* pDocShell = pTextDoc->GetDocShell();
485 SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
486 pWrtShell->Insert("first");
487 pWrtShell->SplitNode();
488 pWrtShell->Insert("second");
489 SwPageDesc* pDesc = pWrtShell->FindPageDescByName("Left Page", true);
490 SwPaM aPaM(*pWrtShell->GetCursor()->GetPoint());
491 SwFormatPageDesc aFormatPageDesc(pDesc);
492 pDocShell->GetDoc()->getIDocumentContentOperations().InsertPoolItem(aPaM, aFormatPageDesc);
493 uno::Reference<beans::XPropertySet> xPageStyle(
494 getStyles("PageStyles")->getByName("Left Page"), uno::UNO_QUERY);
495 xPageStyle->setPropertyValue("TopMargin", uno::Any(static_cast<sal_Int32>(501)));
496 table::BorderLine2 aBorder;
497 aBorder.LineWidth = 159;
498 aBorder.OuterLineWidth = 159;
499 xPageStyle->setPropertyValue("TopBorder", uno::Any(aBorder));
500 sal_Int32 nTopBorderDistance = -646;
501 xPageStyle->setPropertyValue("TopBorderDistance", uno::Any(nTopBorderDistance));
504 // When saving that document to RTF:
505 saveAndReload("Rich Text Format");
507 // Then make sure that the border distance is negative, so the first line of body text appears
508 // on top of the page border:
509 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
510 SwDocShell* pDocShell = pTextDoc->GetDocShell();
511 SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
512 pWrtShell->Down(/*bSelect=*/false);
513 OUString aPageStyle = pWrtShell->GetCurPageStyle();
514 uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName(aPageStyle),
515 uno::UNO_QUERY);
516 auto nTopMargin = xPageStyle->getPropertyValue("TopMargin").get<sal_Int32>();
517 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(501), nTopMargin);
518 auto aTopBorder = xPageStyle->getPropertyValue("TopBorder").get<table::BorderLine2>();
519 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(159), aTopBorder.LineWidth);
520 auto nTopBorderDistance = xPageStyle->getPropertyValue("TopBorderDistance").get<sal_Int32>();
521 // Without the accompanying fix in place, this test would have failed with:
522 // - Expected: -646
523 // - Actual : 0
524 // i.e. the border negative distance was lost.
525 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-646), nTopBorderDistance);
528 CPPUNIT_TEST_FIXTURE(Test, testTdf127806)
530 createSwDoc("tdf127806.rtf");
531 CPPUNIT_ASSERT_EQUAL(2, getShapes());
533 CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.GroupShape"), getShape(1)->getShapeType());
534 auto xImage = getShape(2);
535 CPPUNIT_ASSERT_EQUAL(OUString("FrameShape"), xImage->getShapeType());
536 awt::Size aSize(xImage->getSize());
537 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(600), aSize.Height);
538 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(635), aSize.Width);
540 saveAndReload("Rich Text Format");
541 CPPUNIT_ASSERT_EQUAL(1, getShapes()); // FIXME: We lost one shape on export, that's sucks
543 xImage = getShape(1);
544 CPPUNIT_ASSERT_EQUAL(OUString("FrameShape"), xImage->getShapeType());
546 aSize = xImage->getSize();
547 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(600), aSize.Height);
548 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(635), aSize.Width);
551 DECLARE_RTFEXPORT_TEST(testTdf148578, "tdf148578.rtf")
553 // \trgaph567 should affect only table cell margins (~1cm),
554 // but do not shift table, since \trleft is not provided
555 uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
557 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(xTable, "LeftMargin"));
559 uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
560 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1000),
561 getProperty<sal_Int32>(xCell, "LeftBorderDistance"));
562 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1000),
563 getProperty<sal_Int32>(xCell, "RightBorderDistance"));
565 xCell.set(xTable->getCellByName("B1"), uno::UNO_QUERY);
566 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1000),
567 getProperty<sal_Int32>(xCell, "LeftBorderDistance"));
568 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1000),
569 getProperty<sal_Int32>(xCell, "RightBorderDistance"));
572 DECLARE_RTFEXPORT_TEST(testInvalidParagraphStyle, "invalidParagraphStyle.rtf")
574 // Given test has character style #30, but referred as paragraph style #30
575 // This was causing exception in finishParagraph(), so numbering and other
576 // properties were not applied. Ensure numbering is still here
577 sal_Int16 numFormat = getNumberingTypeOfParagraph(1);
578 CPPUNIT_ASSERT_EQUAL(style::NumberingType::ARABIC, numFormat);
581 DECLARE_RTFEXPORT_TEST(testTdf152784_1, "tdf152784_1.rtf")
583 // Ensure that paragraph having style with numbering does not have numbering
584 // since it is not explicitly defined in paragraph properties
585 uno::Reference<beans::XPropertySet> xPara(getParagraph(1, "Here should be no numbering!"),
586 uno::UNO_QUERY);
587 CPPUNIT_ASSERT(getProperty<OUString>(xPara, "NumberingStyleName").isEmpty());
590 CPPUNIT_TEST_FIXTURE(Test, testFloatingTableExport)
592 // Given a document with a floating table:
593 mxComponent = loadFromDesktop("private:factory/swriter");
594 // Insert a table:
595 uno::Sequence<beans::PropertyValue> aArgs = {
596 comphelper::makePropertyValue("Rows", static_cast<sal_Int32>(1)),
597 comphelper::makePropertyValue("Columns", static_cast<sal_Int32>(1)),
599 dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
600 // Select it:
601 dispatchCommand(mxComponent, ".uno:SelectAll", {});
602 // Wrap in a fly:
603 aArgs = {
604 comphelper::makePropertyValue("AnchorType", static_cast<sal_uInt16>(0)),
606 dispatchCommand(mxComponent, ".uno:InsertFrame", aArgs);
607 // Mark it as a floating table:
608 uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
609 uno::Reference<beans::XPropertySet> xFrame(
610 xTextFramesSupplier->getTextFrames()->getByName("Frame1"), uno::UNO_QUERY);
611 xFrame->setPropertyValue("IsSplitAllowed", uno::Any(true));
612 // Originally 10, 30 & 40 twips.
613 xFrame->setPropertyValue("VertOrientPosition", uno::Any(static_cast<sal_Int32>(18)));
614 xFrame->setPropertyValue("LeftMargin", uno::Any(static_cast<sal_Int32>(53)));
615 xFrame->setPropertyValue("RightMargin", uno::Any(static_cast<sal_Int32>(71)));
617 // When saving to RTF:
618 saveAndReload("Rich Text Format");
620 // Then make sure the floating table is there & has the expected properties:
621 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
622 uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
623 xFrame.set(xDrawPage->getByIndex(0), uno::UNO_QUERY);
624 bool bIsSplitAllowed{};
625 xFrame->getPropertyValue("IsSplitAllowed") >>= bIsSplitAllowed;
626 // Without the accompanying fix in place, this test would have failed, the table was not
627 // multi-page.
628 CPPUNIT_ASSERT(bIsSplitAllowed);
629 sal_Int16 nVertOrientRelation{};
630 xFrame->getPropertyValue("VertOrientRelation") >>= nVertOrientRelation;
631 CPPUNIT_ASSERT_EQUAL(text::RelOrientation::FRAME, nVertOrientRelation);
632 sal_Int16 nHoriOrientRelation{};
633 xFrame->getPropertyValue("HoriOrientRelation") >>= nHoriOrientRelation;
634 CPPUNIT_ASSERT_EQUAL(text::RelOrientation::FRAME, nHoriOrientRelation);
635 sal_Int32 nVertOrientPosition{};
636 xFrame->getPropertyValue("VertOrientPosition") >>= nVertOrientPosition;
637 sal_Int32 nExpected = 18;
638 CPPUNIT_ASSERT_EQUAL(nExpected, nVertOrientPosition);
639 sal_Int32 nLeftMargin{};
640 xFrame->getPropertyValue("LeftMargin") >>= nLeftMargin;
641 nExpected = 53;
642 CPPUNIT_ASSERT_EQUAL(nExpected, nLeftMargin);
643 sal_Int32 nRightMargin{};
644 xFrame->getPropertyValue("RightMargin") >>= nRightMargin;
645 nExpected = 71;
646 CPPUNIT_ASSERT_EQUAL(nExpected, nRightMargin);
649 CPPUNIT_TEST_FIXTURE(Test, testFloattableOverlapNeverRTFExport)
651 // Given a document with a floating table, overlap is not allowed:
653 createSwDoc();
654 SwDoc* pDoc = getSwDoc();
655 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
656 pWrtShell->Insert2("before table");
657 // Insert a table:
658 SwInsertTableOptions aTableOptions(SwInsertTableFlags::DefaultBorder, 0);
659 pWrtShell->InsertTable(aTableOptions, /*nRows=*/1, /*nCols=*/1);
660 pWrtShell->MoveTable(GotoPrevTable, fnTableStart);
661 // Select table:
662 pWrtShell->SelAll();
663 // Wrap the table in a text frame:
664 SwFlyFrameAttrMgr aMgr(true, pWrtShell, Frmmgr_Type::TEXT, nullptr);
665 pWrtShell->StartAllAction();
666 aMgr.InsertFlyFrame(RndStdIds::FLY_AT_PARA, aMgr.GetPos(), aMgr.GetSize());
667 pWrtShell->EndAllAction();
668 // Allow the text frame to split:
669 pWrtShell->StartAllAction();
670 sw::FrameFormats<sw::SpzFrameFormat*>* pFlys = pDoc->GetSpzFrameFormats();
671 sw::SpzFrameFormat* pFly = (*pFlys)[0];
672 SwAttrSet aSet(pFly->GetAttrSet());
673 aSet.Put(SwFormatFlySplit(true));
674 // Don't allow overlap:
675 SwFormatWrapInfluenceOnObjPos aInfluence;
676 aInfluence.SetAllowOverlap(false);
677 aSet.Put(aInfluence);
678 pDoc->SetAttr(aSet, *pFly);
679 pWrtShell->EndAllAction();
682 // When saving to RTF:
683 saveAndReload("Rich Text Format");
685 // Then make sure that the overlap=never markup is written:
686 SwDoc* pDoc = getSwDoc();
687 sw::FrameFormats<sw::SpzFrameFormat*>* pFlys = pDoc->GetSpzFrameFormats();
688 sw::SpzFrameFormat* pFly = (*pFlys)[0];
689 // Without the accompanying fix in place, this test would have failed, i.e. \tabsnoovrlp was not
690 // written.
691 CPPUNIT_ASSERT(!pFly->GetAttrSet().GetWrapInfluenceOnObjPos().GetAllowOverlap());
694 CPPUNIT_PLUGIN_IMPLEMENT();
696 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */