1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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  */
9 
10 #include <swmodeltestbase.hxx>
11 
12 #include <IDocumentSettingAccess.hxx>
13 #include <com/sun/star/beans/XPropertySet.hpp>
14 #include <com/sun/star/container/XIndexAccess.hpp>
15 #include <com/sun/star/drawing/FillStyle.hpp>
16 #include <com/sun/star/drawing/LineDash.hpp>
17 #include <com/sun/star/graphic/XGraphic.hpp>
18 #include <com/sun/star/text/XFormField.hpp>
19 #include <com/sun/star/text/XTextTable.hpp>
20 #include <com/sun/star/text/XTextTablesSupplier.hpp>
21 #include <com/sun/star/text/WritingMode2.hpp>
22 
23 class Test : public SwModelTestBase
24 {
25 public:
Test()26     Test()
27         : SwModelTestBase("/sw/qa/extras/ww8export/data/", "MS Word 97")
28     {
29     }
30 
mustTestImportOf(const char * filename) const31     bool mustTestImportOf(const char* filename) const override
32     {
33         // If the testcase is stored in some other format, it's pointless to test.
34         return OString(filename).endsWith(".doc");
35     }
36 };
37 
38 DECLARE_WW8EXPORT_TEST(testTdf37778_readonlySection, "tdf37778_readonlySection.doc")
39 {
40     uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
41     CPPUNIT_ASSERT( xStorable->isReadonly() );
42 
43     uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
44     uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
45     // The problem was that section protection was being enabled in addition to being read-only.
46     // This created an explicit section with protection. There should be just the default, non-explicit section.
47     CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of Sections", sal_Int32(0), xSections->getCount());
48 
49     // tdf#127862: page fill color (in this case white) was lost
50     uno::Reference<beans::XPropertySet> xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
51     CPPUNIT_ASSERT(drawing::FillStyle_NONE != getProperty<drawing::FillStyle>(xStyle, "FillStyle"));
52 }
53 
54 DECLARE_WW8EXPORT_TEST(testTdf122429_header, "tdf122429_header.doc")
55 {
56     uno::Reference<container::XNameAccess> pageStyles = getStyles("PageStyles");
57     uno::Reference<style::XStyle> pageStyle(pageStyles->getByName("Default Style"), uno::UNO_QUERY);
58     bool headerIsOn = getProperty<bool>(pageStyle, "HeaderIsOn");
59     CPPUNIT_ASSERT(headerIsOn);
60 }
61 
62 DECLARE_WW8EXPORT_TEST(testTdf122460_header, "tdf122460_header.odt")
63 {
64     uno::Reference<container::XNameAccess> pageStyles = getStyles("PageStyles");
65     uno::Reference<style::XStyle> pageStyle(pageStyles->getByName("Default Style"), uno::UNO_QUERY);
66     bool headerIsOn = getProperty<bool>(pageStyle, "HeaderIsOn");
67     CPPUNIT_ASSERT(headerIsOn);
68 }
69 
70 DECLARE_WW8EXPORT_TEST(testFdo53985, "fdo53985.doc")
71 {
72     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
73     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY);
74     CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTables->getCount()); // Only 4 tables were imported.
75 
76     SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
77     CPPUNIT_ASSERT(pTextDoc);
78     SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
79     CPPUNIT_ASSERT_EQUAL_MESSAGE("Compatibility: Protect form", true, pDoc->getIDocumentSettingAccess().get( DocumentSettingId::PROTECT_FORM ) );
80 
81     uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
82     uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
83     CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xSections->getCount()); // The first paragraph wasn't counted as a section.
84 
85     uno::Reference<beans::XPropertySet> xSect(xSections->getByIndex(0), uno::UNO_QUERY);
86     CPPUNIT_ASSERT_EQUAL_MESSAGE("Section1 is protected", true, getProperty<bool>(xSect, "IsProtected"));
87     xSect.set(xSections->getByIndex(3), uno::UNO_QUERY);
88     CPPUNIT_ASSERT_EQUAL_MESSAGE("Section4 is protected", false, getProperty<bool>(xSect, "IsProtected"));
89 }
90 
91 DECLARE_WW8EXPORT_TEST(testTdf79435_legacyInputFields, "tdf79435_legacyInputFields.docx")
92 {
93     //using .docx input file to verify cross-format compatibility.
94     uno::Reference<text::XFormField> xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(5), 3), "Bookmark");
95     uno::Reference<container::XNameContainer> xParameters(xFormField->getParameters());
96 
97     OUString sTmp;
98     // Too often the string reader can fail during import - fix that first to prevent round-tripping garbage.
99     // (for example BR-1010B.doc from tdf#48097)
100     //xParameters->getByName("EntryMacro") >>= sTmp;
101     //CPPUNIT_ASSERT_EQUAL(OUString("test"), sTmp);
102     //xParameters->getByName("Help") >>= sTmp;
103     //CPPUNIT_ASSERT_EQUAL(OUString("F1Help"), sTmp);
104     //xParameters->getByName("ExitMacro") >>= sTmp;
105     //CPPUNIT_ASSERT_EQUAL(OUString("test"), sTmp);
106     xParameters->getByName("Description") >>= sTmp;
107     CPPUNIT_ASSERT_EQUAL(OUString("StatusHelp"), sTmp);
108     //xParameters->getByName("Content") >>= sTmp;
109     //CPPUNIT_ASSERT_EQUAL(OUString("Camelcase"), sTmp);
110     //xParameters->getByName("Format") >>= sTmp;
111     //CPPUNIT_ASSERT_EQUAL(OUString("TITLE CASE"), sTmp);
112 
113     sal_uInt16 nMaxLength = 0;
114     xParameters->getByName("MaxLength") >>= nMaxLength;
115     CPPUNIT_ASSERT_EQUAL_MESSAGE("Max Length", sal_uInt16(10), nMaxLength);
116 
117     // too bad this is based on character runs - just found try trial and error.
118     xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(6), 2), "Bookmark");
119     xParameters.set(xFormField->getParameters());
120     xParameters->getByName("Type") >>= sTmp;
121     CPPUNIT_ASSERT_EQUAL(OUString("calculated"), sTmp);
122 
123     xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(7), 2), "Bookmark");
124     xParameters.set(xFormField->getParameters());
125     xParameters->getByName("Type") >>= sTmp;
126     CPPUNIT_ASSERT_EQUAL(OUString("currentDate"), sTmp);
127 
128     xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(7), 7), "Bookmark");
129     xParameters.set(xFormField->getParameters());
130     xParameters->getByName("Type") >>= sTmp;
131     CPPUNIT_ASSERT_EQUAL(OUString("currentTime"), sTmp);
132 
133     xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(8), 2), "Bookmark");
134     xParameters.set(xFormField->getParameters());
135     xParameters->getByName("Type") >>= sTmp;
136     CPPUNIT_ASSERT_EQUAL(OUString("number"), sTmp);
137 
138     xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(8), 7), "Bookmark");
139     xParameters.set(xFormField->getParameters());
140     xParameters->getByName("Type") >>= sTmp;
141     CPPUNIT_ASSERT_EQUAL(OUString("date"), sTmp);
142 }
143 
144 DECLARE_WW8EXPORT_TEST(testTdf120225_textControlCrossRef, "tdf120225_textControlCrossRef.doc")
145 {
146     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
147     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
148     uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
149     uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
150     uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
151     xRunEnum->nextElement();
152     uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
153 
154     CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), getProperty<OUString>(xPropertySet, "TextPortionType"));
155     uno::Reference<container::XNamed> xBookmark(getProperty< uno::Reference<beans::XPropertySet> >(xPropertySet, "Bookmark"), uno::UNO_QUERY_THROW);
156 
157     // Critical test: does TextField's bookmark name match cross-reference?
158     const OUString& sTextFieldName( xBookmark->getName() );
159     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
160     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
161     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
162     CPPUNIT_ASSERT(xFields->hasMoreElements());
163     xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY);
164     CPPUNIT_ASSERT_EQUAL(sTextFieldName, getProperty<OUString>(xPropertySet, "SourceName"));
165 
166     uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
167     uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
168     uno::Reference<container::XNameAccess> xBookmarksByName = xBookmarksSupplier->getBookmarks();
169     // TextFields should not be turned into real bookmarks.
170     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), xBookmarksByIdx->getCount());
171 
172     // The actual name isn't critical, but if it fails, it is worth asking why.
173     CPPUNIT_ASSERT_EQUAL(OUString("Text1"), sTextFieldName);
174 }
175 
176 DECLARE_WW8EXPORT_TEST(testTdf127316_autoEscapement, "tdf127316_autoEscapement.odt")
177 {
178     uno::Reference<text::XTextRange> xPara = getParagraph(2);
179     CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1, "Normal text "), "CharEscapement"), 0);
180     // Negative escapements (subscripts) were decreasing by 1% every round-trip due to bad manual rounding.
181     // This should be roughly .2*35% of the ORIGINAL (non-reduced) size. However, during export the
182     // proportional height has to be changed into direct formatting, which then changes the relative percent.
183     // In this case, a 24pt font, proportional at 65% becomes roughly a 16pt font.
184     // Thus an escapement of 7% (1.68pt) becomes roughly 10.5% for the 16pt font.
185     CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Subscript", -10.f, getProperty<float>(getRun(xPara, 2), "CharEscapement"), 1);
186 }
187 
188 DECLARE_WW8EXPORT_TEST(testTdf127316_autoEscapement2, "tdf127316_autoEscapement2.odt")
189 {
190     uno::Reference<text::XTextRange> xPara = getParagraph(1);
191     CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1, "Base1"), "CharEscapement"), 0);
192     // Font is 80% of 40pt or 32pt, original escapement is 6.4pt, so round-trip escapement is 20%.
193     CPPUNIT_ASSERT_DOUBLES_EQUAL(20.f, getProperty<float>(getRun(xPara, 2,"AutoSuperscript"), "CharEscapement"), 1);
194     xPara.set( getParagraph(3) );
195     CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1, "Base3"), "CharEscapement"), 0);
196     // font is 20% of 40pt or 8pt, original escapement is 25.6pt, so round-trip escapement is 320%.
197     CPPUNIT_ASSERT_DOUBLES_EQUAL(320.f, getProperty<float>(getRun(xPara, 2,"AutoSuperscript"), "CharEscapement"), 3);
198 }
199 
200 DECLARE_WW8EXPORT_TEST(testTdf120412_proportionalEscapement, "tdf120412_proportionalEscapement.odt")
201 {
202     uno::Reference<text::XTextRange> xPara = getParagraph(2);
203     CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 2, "Base"), "CharEscapement"), 0);
204     // Import was limiting to 100%. And export based the position on the original height, not the proportional height.
205     CPPUNIT_ASSERT_DOUBLES_EQUAL( 150.f, getProperty<float>(getRun(xPara, 3,"Super"), "CharEscapement"), 2);
206     CPPUNIT_ASSERT_EQUAL(2, getPages());
207 }
208 
209 DECLARE_WW8EXPORT_TEST(testTdf121111_fillStyleNone, "tdf121111_fillStyleNone.docx")
210 {
211     uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Numbering - First level"),
212                                                      uno::UNO_QUERY);
213     CPPUNIT_ASSERT_EQUAL(Color(184,204,228), Color(getProperty<sal_uInt32>(xStyle, "ParaBackColor")));//R:184 G:204 B:228
214     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xStyle, "FillStyle"));
215 
216     uno::Reference<text::XTextRange> xText(getParagraph(12));
217     CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(getProperty<sal_uInt32>(xText, "ParaBackColor")));
218     CPPUNIT_ASSERT_EQUAL_MESSAGE("No fill", drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xText, "FillStyle"));
219 }
220 
221 DECLARE_WW8EXPORT_TEST(testTdf128608_fillStyleNoneB, "tdf128608_fillStyleNoneB.odt")
222 {
223     uno::Reference<text::XTextRange> xText(getParagraph(1));
224     CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(getProperty<sal_uInt32>(xText, "ParaBackColor")));
225     CPPUNIT_ASSERT_EQUAL_MESSAGE("No fill", drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xText, "FillStyle"));
226 }
227 
228 DECLARE_WW8EXPORT_TEST(testTdf112618_textbox_no_bg, "tdf112618_textbox_no_bg.doc")
229 {
230     sal_uInt16 nTransparence = getProperty<sal_Int16>(getShape(2), "FillTransparence");
231     CPPUNIT_ASSERT_EQUAL(sal_uInt16(100), nTransparence);
232     CPPUNIT_ASSERT_EQUAL(nTransparence, getProperty<sal_uInt16>(getShape(2), "BackColorTransparency"));
233 }
234 
235 DECLARE_WW8EXPORT_TEST(testTdf101826_xattrTextBoxFill, "tdf101826_xattrTextBoxFill.doc")
236 {
237     //Basic 1 Color Fill: gradient from yellow(FFFF00) to brown(767600) currently saves as mid-color
238     CPPUNIT_ASSERT_MESSAGE("background color", Color(0xFF, 0xFF, 0x00) != getProperty<Color>(getShape(1), "BackColor"));
239     //Basic 2 Color Fill: gradient from yellow(FFFF00) to green(00B050) currently saves as mid-color
240     CPPUNIT_ASSERT_MESSAGE("background color", Color(0xFF, 0xFF, 0x00) != getProperty<Color>(getShape(4), "BackColor"));
241     //Basic Picture Fill: Tux image
242     CPPUNIT_ASSERT_EQUAL_MESSAGE("background image", drawing::FillStyle_BITMAP, getProperty<drawing::FillStyle>(getShape(5), "FillStyle"));
243 }
244 
245 DECLARE_WW8EXPORT_TEST(testTdf123433_fillStyleStop, "tdf123433_fillStyleStop.doc")
246 {
247     uno::Reference<text::XTextRange> xText(getParagraph(12));
248     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xText, "FillStyle"));
249     CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(getProperty<sal_uInt32>(xText, "ParaBackColor")));
250 }
251 
252 DECLARE_WW8EXPORT_TEST(testTdf127862_pageFillStyle, "tdf127862_pageFillStyle.odt")
253 {
254     uno::Reference<beans::XPropertySet> xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
255     CPPUNIT_ASSERT(drawing::FillStyle_NONE != getProperty<drawing::FillStyle>(xStyle, "FillStyle"));
256 }
257 
258 DECLARE_WW8EXPORT_TEST(testTdf128608_tableParaBackColor, "tdf128608_tableParaBackColor.doc")
259 {
260     uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
261     uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
262     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
263     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A4"), uno::UNO_QUERY);
264 
265     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY);
266     uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
267     uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
268     // ParaBackColor doesn't seem to be used in this case, but keep it here to make sure it stays as AUTO.
269     CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(getProperty<sal_uInt32>(xPara, "ParaBackColor")));
270     // No paragraph background colour/fill. (The cell background colour should be used.)
271     CPPUNIT_ASSERT_EQUAL_MESSAGE("No fillstyle", drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xPara, "FillStyle"));
272 }
273 
274 DECLARE_WW8EXPORT_TEST(testTdf94009_zeroPgMargin, "tdf94009_zeroPgMargin.odt")
275 {
276     uno::Reference<beans::XPropertySet> defaultStyle(getStyles("PageStyles")->getByName("Standard"),
277                                                      uno::UNO_QUERY);
278     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(defaultStyle, "TopMargin"));
279 }
280 
281 DECLARE_WW8EXPORT_TEST(testTdf120711_joinedParagraphWithChangeTracking, "tdf120711.doc")
282 {
283     sal_Int16   numFormat = getNumberingTypeOfParagraph(5);
284     // last paragraph is not a list item
285     CPPUNIT_ASSERT(style::NumberingType::CHAR_SPECIAL != numFormat);
286 }
287 
288 DECLARE_WW8EXPORT_TEST(testBtlrCell, "btlr-cell.doc")
289 {
290     // Without the accompanying fix in place, this test would have failed, as
291     // the btlr text direction in the A1 cell was lost on DOC import and
292     // export.
293     uno::Reference<text::XTextTablesSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
294     uno::Reference<container::XNameAccess> xTables = xSupplier->getTextTables();
295     uno::Reference<text::XTextTable> xTable(xTables->getByName("Table1"), uno::UNO_QUERY);
296     uno::Reference<beans::XPropertySet> xA1(xTable->getCellByName("A1"), uno::UNO_QUERY);
297     CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR, getProperty<sal_Int16>(xA1, "WritingMode"));
298 
299     uno::Reference<beans::XPropertySet> xB1(xTable->getCellByName("B1"), uno::UNO_QUERY);
300     auto nActual = getProperty<sal_Int16>(xB1, "WritingMode");
301     CPPUNIT_ASSERT(nActual == text::WritingMode2::LR_TB || nActual == text::WritingMode2::CONTEXT);
302 
303     uno::Reference<beans::XPropertySet> xC1(xTable->getCellByName("C1"), uno::UNO_QUERY);
304     CPPUNIT_ASSERT_EQUAL(text::WritingMode2::TB_RL, getProperty<sal_Int16>(xC1, "WritingMode"));
305 }
306 
307 DECLARE_WW8EXPORT_TEST(testTdf118375export, "tdf118375_240degClockwise.doc")
308 {
309     // The input document has one custom shape, which is rotated 240deg. Check
310     // that it has the same position as in Word.
311     uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent,
312                                                                    uno::UNO_QUERY_THROW);
313     CPPUNIT_ASSERT_MESSAGE("Could not get XDrawPagesSupplier", xDrawPagesSupplier.is());
314     uno::Reference<drawing::XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages());
315     uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY_THROW);
316     CPPUNIT_ASSERT_MESSAGE("Could not get xDrawPage", xDrawPage.is());
317     uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
318     CPPUNIT_ASSERT_MESSAGE("Could not get xShape", xShape.is());
319     uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
320     CPPUNIT_ASSERT_MESSAGE("Could not get the shape properties", xShapeProps.is());
321     sal_Int32 nPosX, nPosY;
322     xShapeProps->getPropertyValue("HoriOrientPosition") >>= nPosX;
323     xShapeProps->getPropertyValue("VertOrientPosition") >>= nPosY;
324     // Allow some tolerance because rounding errors through integer arithmetic
325     // in rotation.
326     CPPUNIT_ASSERT_DOUBLES_EQUAL(5200.0, static_cast<double>(nPosX), 1.0);
327     CPPUNIT_ASSERT_DOUBLES_EQUAL(1152.0, static_cast<double>(nPosY), 1.0);
328 }
329 
330 DECLARE_WW8EXPORT_TEST(testImageCommentAtChar, "image-comment-at-char.doc")
331 {
332     uno::Reference<text::XTextRange> xPara = getParagraph(1);
333     CPPUNIT_ASSERT_EQUAL(OUString("Text"),
334                          getProperty<OUString>(getRun(xPara, 1), "TextPortionType"));
335     // Without the accompanying fix in place, this test would have failed with 'Expected:
336     // Annotation; Actual: Frame', i.e. the comment start before the image was lost.
337     CPPUNIT_ASSERT_EQUAL(OUString("Annotation"),
338                          getProperty<OUString>(getRun(xPara, 2), "TextPortionType"));
339     CPPUNIT_ASSERT_EQUAL(OUString("Frame"),
340                          getProperty<OUString>(getRun(xPara, 3), "TextPortionType"));
341     CPPUNIT_ASSERT_EQUAL(OUString("AnnotationEnd"),
342                          getProperty<OUString>(getRun(xPara, 4), "TextPortionType"));
343     CPPUNIT_ASSERT_EQUAL(OUString("Text"),
344                          getProperty<OUString>(getRun(xPara, 5), "TextPortionType"));
345 }
346 
347 DECLARE_WW8EXPORT_TEST(testTdf126708emf, "tdf126708_containsemf.odt")
348 {
349     auto xShape = getShape(1);
350     // First check the size of the EMF graphic contained in the shape.
351     auto xGraphic = getProperty< uno::Reference<graphic::XGraphic> >(
352         xShape, "Graphic");
353     auto xSize = getProperty<awt::Size>(xGraphic, "Size100thMM");
354     CPPUNIT_ASSERT_EQUAL(sal_Int32(8501), xSize.Height);
355     CPPUNIT_ASSERT_EQUAL(sal_Int32(18939), xSize.Width);
356 
357     // Now check that the shape itself has a decent size.
358     // This size varies slightly when round tripping through doc format.
359     xSize = getProperty<awt::Size>(xShape, "Size");
360     CPPUNIT_ASSERT(abs(xSize.Height - 7629) <= 6);
361     CPPUNIT_ASSERT(abs(xSize.Width - 17000) <= 6);
362 }
363 
364 DECLARE_WW8EXPORT_TEST(testBtlrFrame, "btlr-frame.odt")
365 {
366     if (!mbExported)
367     {
368         return;
369     }
370 
371     // Without the accompanying fix in place, this test would have failed with a
372     // beans.UnknownPropertyException, as the writing direction was lost, so the default direction
373     // resulted in a conversion to a Writer text frame.
374     uno::Reference<beans::XPropertySet> xFrame(getShape(1), uno::UNO_QUERY);
375     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(9000), getProperty<sal_Int32>(xFrame, "RotateAngle"));
376 }
377 
378 DECLARE_WW8EXPORT_TEST(testPresetDash, "tdf127166_prstDash_Word97.doc")
379 {
380     // Error was, that the 'sys' preset dash styles were neither imported not
381     // exported, the mixed styles had wrong dash-dot order, they were imported
382     // with absolute values.
383     const drawing::LineDash dashParams[] =
384     {
385         {drawing::DashStyle_RECTRELATIVE, 1, 400, 0, 0, 300}, // dash
386         {drawing::DashStyle_RECTRELATIVE, 1, 400, 1, 100, 300}, // dashDot
387         {drawing::DashStyle_RECTRELATIVE, 1, 100, 0, 0, 300}, // dot
388         {drawing::DashStyle_RECTRELATIVE, 1, 800, 0, 0, 300}, // lgDash
389         {drawing::DashStyle_RECTRELATIVE, 1, 800, 1, 100, 300}, // lgDashDot
390         {drawing::DashStyle_RECTRELATIVE, 1, 800, 2, 100, 300}, // lgDashDotDot
391         {drawing::DashStyle_RECTRELATIVE, 1, 300, 0, 0, 100}, // sysDash
392         {drawing::DashStyle_RECTRELATIVE, 1, 300, 1, 100, 100}, // sysDashDot
393         {drawing::DashStyle_RECTRELATIVE, 1, 300, 2, 100, 100}, // sysDashDotDot
394         {drawing::DashStyle_RECTRELATIVE, 1, 100, 0, 0, 100} // sysDot
395     };
396     drawing::LineDash aPresetLineDash;
397     drawing::LineDash aShapeLineDash;
398     for (sal_uInt16 i = 0; i < 10; i++)
399     {
400         aPresetLineDash = dashParams[i];
401         uno::Reference<drawing::XShape> xShape = getShape(i+1);
402         aShapeLineDash = getProperty<drawing::LineDash>(xShape, "LineDash");
403         bool bIsEqual = aPresetLineDash.Style == aShapeLineDash.Style
404                         && aPresetLineDash.Dots == aShapeLineDash.Dots
405                         && aPresetLineDash.DotLen == aShapeLineDash.DotLen
406                         && aPresetLineDash.Dashes == aShapeLineDash.Dashes
407                         && aPresetLineDash.DashLen == aShapeLineDash.DashLen
408                         && aPresetLineDash.Distance == aShapeLineDash.Distance;
409         CPPUNIT_ASSERT_MESSAGE("LineDash differ", bIsEqual);
410     }
411 }
412 
413 CPPUNIT_PLUGIN_IMPLEMENT();
414 
415 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
416