xref: /core/sd/qa/unit/import-tests.cxx (revision 88a5f776)
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 <sal/config.h>
11 
12 #include <config_features.h>
13 #include <config_poppler.h>
14 #include <memory>
15 #include <ostream>
16 #include <sdpage.hxx>
17 
18 #include "sdmodeltestbase.hxx"
19 
20 #include <svl/stritem.hxx>
21 #include <editeng/eeitem.hxx>
22 #include <editeng/editobj.hxx>
23 #include <editeng/outlobj.hxx>
24 #include <editeng/ulspitem.hxx>
25 #include <editeng/fhgtitem.hxx>
26 #include <editeng/escapementitem.hxx>
27 #include <editeng/colritem.hxx>
28 #include <editeng/numitem.hxx>
29 #include <editeng/unoprnms.hxx>
30 #include <sfx2/app.hxx>
31 #include <sfx2/sfxsids.hrc>
32 #include <svl/style.hxx>
33 
34 #include <svx/svdotext.hxx>
35 #include <svx/svdoashp.hxx>
36 #include <svx/svdogrp.hxx>
37 #include <svx/svdoole2.hxx>
38 #include <svx/svdotable.hxx>
39 #include <svx/xfillit0.hxx>
40 #include <svx/xflclit.hxx>
41 #include <svx/xlineit0.hxx>
42 #include <svx/xlnclit.hxx>
43 #include <svx/xlnwtit.hxx>
44 #include <svx/sdasitm.hxx>
45 #include <svx/sdmetitm.hxx>
46 #include <svx/sdooitm.hxx>
47 #include <animations/animationnodehelper.hxx>
48 #include <sax/tools/converter.hxx>
49 
50 #include <com/sun/star/awt/Gradient.hpp>
51 #include <com/sun/star/awt/XBitmap.hpp>
52 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
53 #include <com/sun/star/document/XEventsSupplier.hpp>
54 #include <com/sun/star/presentation/ClickAction.hpp>
55 #include <com/sun/star/presentation/XPresentationPage.hpp>
56 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
57 #include <com/sun/star/drawing/BitmapMode.hpp>
58 #include <com/sun/star/drawing/ColorMode.hpp>
59 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
60 #include <com/sun/star/drawing/XDrawPage.hpp>
61 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
62 #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
63 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
64 #include <com/sun/star/drawing/GluePoint2.hpp>
65 #include <com/sun/star/container/XIdentifierAccess.hpp>
66 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
67 #include <com/sun/star/animations/XAnimationNode.hpp>
68 #include <com/sun/star/animations/XAnimate.hpp>
69 #include <com/sun/star/beans/XPropertySet.hpp>
70 #include <com/sun/star/chart/DataLabelPlacement.hpp>
71 #include <com/sun/star/chart/XChartDocument.hpp>
72 #include <com/sun/star/chart2/XChartDocument.hpp>
73 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
74 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
75 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
76 #include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
77 #include <com/sun/star/chart2/data/XDataSequence.hpp>
78 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
79 #include <com/sun/star/graphic/XGraphic.hpp>
80 #include <com/sun/star/table/BorderLineStyle.hpp>
81 #include <com/sun/star/table/BorderLine2.hpp>
82 #include <com/sun/star/style/ParagraphAdjust.hpp>
83 #include <com/sun/star/style/LineSpacing.hpp>
84 #include <com/sun/star/style/LineSpacingMode.hpp>
85 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
86 #include <com/sun/star/table/XTableRows.hpp>
87 #include <com/sun/star/style/NumberingType.hpp>
88 #include <com/sun/star/frame/Desktop.hpp>
89 #include <com/sun/star/text/GraphicCrop.hpp>
90 #include <com/sun/star/text/XTextCursor.hpp>
91 #include <com/sun/star/xml/dom/XDocument.hpp>
92 
93 #include <stlpool.hxx>
94 #include <comphelper/processfactory.hxx>
95 #include <comphelper/sequenceashashmap.hxx>
96 #include <comphelper/graphicmimetype.hxx>
97 #include <comphelper/lok.hxx>
98 #include <vcl/pngread.hxx>
99 #include <vcl/bitmapaccess.hxx>
100 #include <vcl/dibtools.hxx>
101 #include <svx/svdograf.hxx>
102 
103 using namespace ::com::sun::star;
104 
105 namespace com::sun::star::uno {
106 
107 template<class T>
108 static std::ostream& operator<<(std::ostream& rStrm, const uno::Reference<T>& xRef)
109 {
110     rStrm << xRef.get();
111     return rStrm;
112 }
113 
114 }
115 
116 
117 /// Impress import filters tests.
118 class SdImportTest : public SdModelTestBase
119 {
120 public:
121     virtual void setUp() override;
122 
123     void testDocumentLayout();
124     void testSmoketest();
125     void testN759180();
126     void testN778859();
127     void testMasterPageStyleParent();
128     void testGradientAngle();
129     void testTdf97808();
130     void testFillStyleNone();
131     void testFdo64512();
132     void testFdo71075();
133     void testN828390_2();
134     void testN828390_3();
135     void testFdo68594();
136     void testFdo72998();
137     void testFdo77027();
138     void testStrictOOXML();
139     void testN862510_1();
140     void testN862510_2();
141     void testN862510_4();
142     void testBnc870237();
143     void testBnc887225();
144     void testPredefinedTableStyle();
145     void testBnc591147();
146     void testCreationDate();
147     void testBnc584721_1();
148     void testBnc584721_2();
149     void testBnc584721_4();
150     void testBnc904423();
151     void testShapeLineStyle();
152     void testTableBorderLineStyle();
153     void testBnc862510_6();
154     void testBnc862510_7();
155 #if ENABLE_PDFIMPORT
156 #if HAVE_FEATURE_PDFIUM
157     void testPDFImportShared();
158 #endif
159 #if defined(IMPORT_PDF_ELEMENTS)
160     void testPDFImport();
161     void testPDFImportSkipImages();
162 #endif
163 #endif
164     void testBulletSuffix();
165     void testBnc910045();
166     void testRowHeight();
167     void testTdf93830();
168     void testTdf127129();
169     void testTdf93097();
170     void testTdf62255();
171     void testTdf93124();
172     void testTdf99729();
173     void testTdf89927();
174     void testTdf93868();
175     void testTdf95932();
176     void testTdf99030();
177     void testTdf49561();
178     void testTdf103473();
179     void testAoo124143();
180     void testTdf103567();
181     void testTdf103792();
182     void testTdf103876();
183     void testTdf79007();
184     void testTdf129686();
185     void testTdf104015();
186     void testTdf104201();
187     void testTdf103477();
188     void testTdf104445();
189     void testTdf105150();
190     void testTdf105150PPT();
191     void testTdf123684();
192     void testTdf100926();
193     void testTdf89064();
194     void testTdf108925();
195     void testTdf109067();
196     void testTdf109187();
197     void testTdf108926();
198     void testTdf100065();
199     void testTdf90626();
200     void testTdf114488();
201     void testTdf114913();
202     void testTdf114821();
203     void testTdf115394();
204     void testTdf115394PPT();
205     void testTdf51340();
206     void testTdf116899();
207     void testTdf77747();
208     void testTdf116266();
209     void testTdf128684();
210     void testTdf119187();
211     void testShapeGlowEffectPPTXImpoer();
212     void testShapeBlurPPTXImport();
213 
214     bool checkPattern(sd::DrawDocShellRef const & rDocRef, int nShapeNumber, std::vector<sal_uInt8>& rExpected);
215     void testPatternImport();
216     void testPptCrop();
217     void testTdf120028();
218     void testTdf120028b();
219     void testDescriptionImport();
220     void testTdf83247();
221     void testTdf47365();
222     void testTdf122899();
223     void testOOXTheme();
224     void testCropToShape();
225     void testTdf127964();
226     void testTdf106638();
227     void testTdf113198();
228 
229     CPPUNIT_TEST_SUITE(SdImportTest);
230 
231     CPPUNIT_TEST(testDocumentLayout);
232     CPPUNIT_TEST(testSmoketest);
233     CPPUNIT_TEST(testN759180);
234     CPPUNIT_TEST(testN778859);
235     CPPUNIT_TEST(testMasterPageStyleParent);
236     CPPUNIT_TEST(testGradientAngle);
237     CPPUNIT_TEST(testTdf97808);
238     CPPUNIT_TEST(testFillStyleNone);
239     CPPUNIT_TEST(testFdo64512);
240     CPPUNIT_TEST(testFdo71075);
241     CPPUNIT_TEST(testN828390_2);
242     CPPUNIT_TEST(testN828390_3);
243     CPPUNIT_TEST(testFdo68594);
244     CPPUNIT_TEST(testFdo72998);
245     CPPUNIT_TEST(testFdo77027);
246     CPPUNIT_TEST(testStrictOOXML);
247     CPPUNIT_TEST(testN862510_1);
248     CPPUNIT_TEST(testN862510_2);
249     CPPUNIT_TEST(testN862510_4);
250     CPPUNIT_TEST(testBnc870237);
251     CPPUNIT_TEST(testBnc887225);
252     CPPUNIT_TEST(testPredefinedTableStyle);
253     CPPUNIT_TEST(testBnc591147);
254     CPPUNIT_TEST(testCreationDate);
255     CPPUNIT_TEST(testBnc584721_1);
256     CPPUNIT_TEST(testBnc584721_2);
257     CPPUNIT_TEST(testBnc584721_4);
258     CPPUNIT_TEST(testBnc904423);
259     CPPUNIT_TEST(testShapeLineStyle);
260     CPPUNIT_TEST(testTableBorderLineStyle);
261     CPPUNIT_TEST(testBnc862510_6);
262     CPPUNIT_TEST(testBnc862510_7);
263 #if ENABLE_PDFIMPORT
264 #if HAVE_FEATURE_PDFIUM
265     CPPUNIT_TEST(testPDFImportShared);
266 #endif
267 #if defined(IMPORT_PDF_ELEMENTS)
268     CPPUNIT_TEST(testPDFImport);
269     CPPUNIT_TEST(testPDFImportSkipImages);
270 #endif
271 #endif
272     CPPUNIT_TEST(testBulletSuffix);
273     CPPUNIT_TEST(testBnc910045);
274     CPPUNIT_TEST(testRowHeight);
275     CPPUNIT_TEST(testTdf93830);
276     CPPUNIT_TEST(testTdf127129);
277     CPPUNIT_TEST(testTdf93097);
278     CPPUNIT_TEST(testTdf62255);
279     CPPUNIT_TEST(testTdf93124);
280     CPPUNIT_TEST(testTdf99729);
281     CPPUNIT_TEST(testTdf89927);
282     CPPUNIT_TEST(testTdf93868);
283     CPPUNIT_TEST(testTdf95932);
284     CPPUNIT_TEST(testTdf99030);
285     CPPUNIT_TEST(testTdf49561);
286     CPPUNIT_TEST(testTdf103473);
287     CPPUNIT_TEST(testAoo124143);
288     CPPUNIT_TEST(testTdf103567);
289     CPPUNIT_TEST(testTdf103792);
290     CPPUNIT_TEST(testTdf103876);
291     CPPUNIT_TEST(testTdf79007);
292     CPPUNIT_TEST(testTdf129686);
293     CPPUNIT_TEST(testTdf104015);
294     CPPUNIT_TEST(testTdf104201);
295     CPPUNIT_TEST(testTdf103477);
296     CPPUNIT_TEST(testTdf104445);
297     CPPUNIT_TEST(testTdf105150);
298     CPPUNIT_TEST(testTdf105150PPT);
299     CPPUNIT_TEST(testTdf123684);
300     CPPUNIT_TEST(testTdf100926);
301     CPPUNIT_TEST(testPatternImport);
302     CPPUNIT_TEST(testTdf89064);
303     CPPUNIT_TEST(testTdf108925);
304     CPPUNIT_TEST(testTdf109067);
305     CPPUNIT_TEST(testTdf109187);
306     CPPUNIT_TEST(testTdf108926);
307     CPPUNIT_TEST(testTdf100065);
308     CPPUNIT_TEST(testTdf90626);
309     CPPUNIT_TEST(testTdf114488);
310     CPPUNIT_TEST(testTdf114913);
311     CPPUNIT_TEST(testTdf114821);
312     CPPUNIT_TEST(testTdf115394);
313     CPPUNIT_TEST(testTdf115394PPT);
314     CPPUNIT_TEST(testTdf51340);
315     CPPUNIT_TEST(testTdf116899);
316     CPPUNIT_TEST(testTdf77747);
317     CPPUNIT_TEST(testTdf116266);
318     CPPUNIT_TEST(testPptCrop);
319     CPPUNIT_TEST(testTdf120028);
320     CPPUNIT_TEST(testTdf120028b);
321     CPPUNIT_TEST(testDescriptionImport);
322     CPPUNIT_TEST(testTdf83247);
323     CPPUNIT_TEST(testTdf47365);
324     CPPUNIT_TEST(testTdf122899);
325     CPPUNIT_TEST(testOOXTheme);
326     CPPUNIT_TEST(testCropToShape);
327     CPPUNIT_TEST(testTdf127964);
328     CPPUNIT_TEST(testTdf106638);
329     CPPUNIT_TEST(testTdf128684);
330     CPPUNIT_TEST(testTdf113198);
331     CPPUNIT_TEST(testTdf119187);
332     CPPUNIT_TEST(testShapeGlowEffectPPTXImpoer);
333     CPPUNIT_TEST(testShapeBlurPPTXImport);
334 
335     CPPUNIT_TEST_SUITE_END();
336 };
337 
338 void SdImportTest::setUp()
339 {
340     SdModelTestBase::setUp();
341     mxDesktop.set(frame::Desktop::create(getComponentContext()));
342 }
343 
344 /** Test document against a reference XML dump of shapes.
345 
346 If you want to update one of these tests, or add a new one, set the nUpdateMe
347 to the index of the test, and the dump XML's will be created (or rewritten)
348 instead of checking. Use with care - when the test is failing, first find out
349 why, instead of just updating .xml's blindly.
350 
351 Example: Let's say you are adding a test called fdoABCD.pptx.  You'll place it
352 to the data/ subdirectory, and will add an entry to aFilesToCompare below,
353 the 3rd parameter is for export test - can be -1 (don't export), ODP, PPT or PPTX
354 like:
355 
356         { "fdoABCD.pptx", "xml/fdoABCD_", PPTX },
357 
358 and will count the index in the aFilesToCompare structure (1st is 0, 2nd is 1,
359 etc.)  Temporarily you'll set nUpdateMe to this index (instead of -1), and run
360 
361 make sd
362 
363 This will generate the sd/qa/unit/data/xml/fdoABCD_*.xml for you.  Now you
364 will change nUpdateMe back to -1, and commit your fdoABCD.pptx test, the
365 xml/fdoABCD_*.xml dumps, and the aFilesToCompare addition in one commit.
366 
367 As the last step, you will revert your fix and do 'make sd' again, to check
368 that without your fix, the unit test breaks.  Then clean up, and push :-)
369 
370 NOTE: This approach is suitable only for tests of fixes that actually change
371 the layout - best to check by reverting your fix locally after having added
372 the test, and re-running; it should break.
373 */
374 void SdImportTest::testDocumentLayout()
375 {
376     static const struct { const char *pInput, *pDump; sal_Int32 nFormat; sal_Int32 nExportType; } aFilesToCompare[] =
377     {
378         { "odp/shapes-test.odp", "xml/shapes-test_page", ODP, -1 },
379         { "fdo47434.pptx", "xml/fdo47434_", PPTX, -1 },
380         { "n758621.ppt", "xml/n758621_", PPT, -1 },
381         { "fdo64586.ppt", "xml/fdo64586_", PPT, -1 },
382         { "n819614.pptx", "xml/n819614_", PPTX, -1 },
383         { "n820786.pptx", "xml/n820786_", PPTX, -1 },
384         { "n762695.pptx", "xml/n762695_", PPTX, -1 },
385         { "n593612.pptx", "xml/n593612_", PPTX, -1 },
386         { "fdo71434.pptx", "xml/fdo71434_", PPTX, -1 },
387         { "n902652.pptx", "xml/n902652_", PPTX, -1 },
388         { "tdf90403.pptx", "xml/tdf90403_", PPTX, -1 },
389         { "tdf90338.odp", "xml/tdf90338_", ODP, PPTX },
390         { "tdf92001.odp", "xml/tdf92001_", ODP, PPTX },
391 // GCC -mfpmath=387 rounding issues in lclPushMarkerProperties
392 // (oox/source/drawingml/lineproperties.cxx); see mail sub-thread starting at
393 // <https://lists.freedesktop.org/archives/libreoffice/2016-September/
394 // 075211.html> "Re: Test File: sc/qa/unit/data/functions/fods/chiinv.fods:
395 // fails with Assertion" for how "-mfpmath=sse -msse2" would fix that:
396 #if !(defined LINUX && defined X86)
397         { "tdf100491.pptx", "xml/tdf100491_", PPTX, -1 },
398 #endif
399         { "tdf109317.pptx", "xml/tdf109317_", PPTX, ODP},
400         // { "pptx/n828390.pptx", "pptx/xml/n828390_", PPTX, PPTX }, // Example
401     };
402 
403     for ( int i = 0; i < static_cast< int >( SAL_N_ELEMENTS( aFilesToCompare ) ); ++i )
404     {
405         int const nUpdateMe = -1; // index of test we want to update; supposedly only when the test is created
406 
407         sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc( "/sd/qa/unit/data/" ) + OUString::createFromAscii( aFilesToCompare[i].pInput ), aFilesToCompare[i].nFormat );
408         if( aFilesToCompare[i].nExportType >= 0 )
409             xDocShRef = saveAndReload( xDocShRef.get(), aFilesToCompare[i].nExportType );
410         compareWithShapesDump( xDocShRef,
411                 m_directories.getPathFromSrc( "/sd/qa/unit/data/" ) + OUString::createFromAscii( aFilesToCompare[i].pDump ),
412                 i == nUpdateMe );
413     }
414 }
415 
416 void SdImportTest::testSmoketest()
417 {
418     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/smoketest.pptx"), PPTX);
419 
420     SdDrawDocument *pDoc = xDocShRef->GetDoc();
421     CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
422 
423     // cf. SdrModel svx/svdmodel.hxx ...
424 
425     CPPUNIT_ASSERT_EQUAL_MESSAGE( "wrong page count", static_cast<sal_uInt16>(3), pDoc->GetPageCount());
426 
427     const SdrPage *pPage = pDoc->GetPage (1);
428     CPPUNIT_ASSERT_MESSAGE( "no page", pPage != nullptr );
429 
430     CPPUNIT_ASSERT_MESSAGE( "changed", !pDoc->IsChanged() );
431 
432     xDocShRef->DoClose();
433 }
434 
435 void SdImportTest::testN759180()
436 {
437     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/n759180.pptx"), PPTX);
438 
439     const SdrPage *pPage = GetPage( 1, xDocShRef );
440 
441     //sal_uIntPtr nObjs = pPage->GetObjCount();
442     //for (sal_uIntPtr i = 0; i < nObjs; i++)
443     {
444         // Get the object
445         SdrObject *pObj = pPage->GetObj(0);
446         SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
447         CPPUNIT_ASSERT(pTxtObj);
448         std::vector<EECharAttrib> rLst;
449         const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
450         const SvxULSpaceItem *pULSpace = aEdit.GetParaAttribs(0).GetItem(EE_PARA_ULSPACE);
451         CPPUNIT_ASSERT(pULSpace);
452         CPPUNIT_ASSERT_EQUAL_MESSAGE( "Para bottom spacing is wrong!", static_cast<sal_uInt16>(0), pULSpace->GetLower());
453         aEdit.GetCharAttribs(1, rLst);
454         auto it = std::find_if(rLst.rbegin(), rLst.rend(),
455             [](const EECharAttrib& rCharAttr) { return dynamic_cast<const SvxFontHeightItem *>(rCharAttr.pAttr) != nullptr; });
456         if (it != rLst.rend())
457         {
458             const SvxFontHeightItem * pFontHeight = dynamic_cast<const SvxFontHeightItem *>((*it).pAttr);
459             // nStart == 9
460             // font height = 5 => 5*2540/72
461             CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font height is wrong", static_cast<sal_uInt32>(176), pFontHeight->GetHeight() );
462         }
463     }
464 
465     xDocShRef->DoClose();
466 }
467 
468 void SdImportTest::testN862510_1()
469 {
470     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n862510_1.pptx"), PPTX );
471 
472     const SdrPage *pPage = GetPage( 1, xDocShRef );
473     {
474         std::vector<EECharAttrib> rLst;
475         SdrObject *pObj = pPage->GetObj( 0 );
476         SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
477         CPPUNIT_ASSERT( pTxtObj );
478         const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
479         aEdit.GetCharAttribs( 0, rLst );
480         for( std::vector<EECharAttrib>::reverse_iterator it = rLst.rbegin(); it!=rLst.rend(); ++it)
481         {
482             const SvxEscapementItem *pFontEscapement = dynamic_cast<const SvxEscapementItem *>( (*it).pAttr );
483             CPPUNIT_ASSERT_MESSAGE( "Baseline attribute not handled properly", !(pFontEscapement && pFontEscapement->GetProportionalHeight() != 100) );
484         }
485     }
486 
487     xDocShRef->DoClose();
488 }
489 
490 void SdImportTest::testN862510_2()
491 {
492     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n862510_2.pptx"), PPTX );
493 
494     const SdrPage *pPage = GetPage( 1, xDocShRef );
495     {
496         CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
497         SdrObjGroup *pGrpObj = dynamic_cast<SdrObjGroup *>( pPage->GetObj( 0 ) );
498         CPPUNIT_ASSERT( pGrpObj );
499         SdrObjCustomShape *pObj = dynamic_cast<SdrObjCustomShape *>( pGrpObj->GetSubList()->GetObj( 1 ) );
500         CPPUNIT_ASSERT( pObj );
501         CPPUNIT_ASSERT_EQUAL_MESSAGE( "Wrong Text Rotation!", 90.0, pObj->GetExtraTextRotation( true ) );
502     }
503 
504     xDocShRef->DoClose();
505 }
506 
507 void SdImportTest::testN862510_4()
508 {
509     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n862510_4.pptx"), PPTX );
510 
511     const SdrPage *pPage = GetPage( 1, xDocShRef );
512     {
513         std::vector<EECharAttrib> rLst;
514         SdrObject *pObj = pPage->GetObj( 0 );
515         SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
516         CPPUNIT_ASSERT( pTxtObj );
517         const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
518         aEdit.GetCharAttribs( 0, rLst );
519         for( std::vector<EECharAttrib>::reverse_iterator it = rLst.rbegin(); it != rLst.rend(); ++it )
520         {
521             const SvxColorItem *pC = dynamic_cast<const SvxColorItem *>( (*it).pAttr );
522             CPPUNIT_ASSERT_MESSAGE( "gradfill for text color not handled!", !( pC && pC->GetValue() == Color(0) ) );
523         }
524     }
525 
526     xDocShRef->DoClose();
527 }
528 
529 void SdImportTest::testN828390_2()
530 {
531     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n828390_2.pptx"), PPTX );
532     const SdrPage *pPage = GetPage( 1, xDocShRef );
533 
534     SdrObject *pObj = pPage->GetObj(0);
535     SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
536     CPPUNIT_ASSERT( pTxtObj );
537     const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
538     CPPUNIT_ASSERT_EQUAL(OUString("Linux  "), aEdit.GetText(0));
539     CPPUNIT_ASSERT_EQUAL(OUString("Standard Platform"), aEdit.GetText(1));
540 
541     xDocShRef->DoClose();
542 }
543 
544 void SdImportTest::testN828390_3()
545 {
546     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n828390_3.pptx"), PPTX );
547     const SdrPage *pPage = GetPage( 1, xDocShRef );
548 
549     SdrObject *pObj = pPage->GetObj(0);
550     SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
551     CPPUNIT_ASSERT( pTxtObj );
552     const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
553     std::vector<EECharAttrib> rLst;
554     aEdit.GetCharAttribs(1, rLst);
555     bool bPassed = std::none_of(rLst.rbegin(), rLst.rend(),
556         [](const EECharAttrib& rCharAttr) {
557             const SvxEscapementItem *pFontEscapement = dynamic_cast<const SvxEscapementItem *>(rCharAttr.pAttr);
558             return pFontEscapement && (pFontEscapement->GetEsc() != 0);
559         });
560     CPPUNIT_ASSERT_MESSAGE("CharEscapment not imported properly", bPassed);
561 
562     xDocShRef->DoClose();
563 }
564 
565 void SdImportTest::testMasterPageStyleParent()
566 {
567     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/odp/masterpage_style_parent.odp"), ODP );
568     SdDrawDocument *pDoc = xDocShRef->GetDoc();
569     CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
570 
571     SdStyleSheetPool *const pPool(pDoc->GetSdStyleSheetPool());
572 
573     int parents(0);
574     SfxStyleSheetIterator iter(pPool, SfxStyleFamily::Page);
575     for (SfxStyleSheetBase * pStyle = iter.First(); pStyle; pStyle = iter.Next())
576     {
577         OUString const name(pStyle->GetName());
578         OUString const parent(pStyle->GetParent());
579         if (!parent.isEmpty())
580         {
581             ++parents;
582             // check that parent exists
583             SfxStyleSheetBase *const pParentStyle(
584                     pPool->Find(parent, SfxStyleFamily::Page));
585             CPPUNIT_ASSERT(pParentStyle);
586             CPPUNIT_ASSERT_EQUAL(pParentStyle->GetName(), parent);
587             // check that parent has the same master page as pStyle
588             CPPUNIT_ASSERT(parent.indexOf(SD_LT_SEPARATOR) != -1);
589             CPPUNIT_ASSERT(name.indexOf(SD_LT_SEPARATOR) != -1);
590             CPPUNIT_ASSERT_EQUAL(
591                     parent.copy(0, parent.indexOf(SD_LT_SEPARATOR)),
592                     name.copy(0, name.indexOf(SD_LT_SEPARATOR)));
593         }
594     }
595     // check that there are actually parents...
596     CPPUNIT_ASSERT_EQUAL(16, parents);
597 
598     xDocShRef->DoClose();
599 }
600 
601 void SdImportTest::testGradientAngle()
602 {
603     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odg/gradient-angle.fodg"), FODG);
604 
605     uno::Reference<lang::XMultiServiceFactory> const xDoc(
606         xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY);
607 
608     awt::Gradient gradient;
609     uno::Reference<container::XNameAccess> const xGradients(
610         xDoc->createInstance("com.sun.star.drawing.GradientTable"),
611         uno::UNO_QUERY);
612 
613     CPPUNIT_ASSERT(xGradients->getByName("Gradient 38") >>= gradient);
614     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), gradient.Angle); // was: 3600
615 
616     CPPUNIT_ASSERT(xGradients->getByName("Gradient 10") >>= gradient);
617     CPPUNIT_ASSERT_EQUAL(sal_Int16(270), gradient.Angle); // 27deg
618 
619     CPPUNIT_ASSERT(xGradients->getByName("Gradient 11") >>= gradient);
620     CPPUNIT_ASSERT_EQUAL(sal_Int16(1145), gradient.Angle); // 2rad
621 
622     CPPUNIT_ASSERT(xGradients->getByName("Gradient 12") >>= gradient);
623     CPPUNIT_ASSERT_EQUAL(sal_Int16(900), gradient.Angle); // 100grad
624 
625     CPPUNIT_ASSERT(xGradients->getByName("Gradient 13") >>= gradient);
626     CPPUNIT_ASSERT_EQUAL(sal_Int16(3599), gradient.Angle); // -1
627 
628     CPPUNIT_ASSERT(xGradients->getByName("Gradient 14") >>= gradient);
629     CPPUNIT_ASSERT_EQUAL(sal_Int16(3028), gradient.Angle); // -1rad
630 
631     CPPUNIT_ASSERT(xGradients->getByName("Gradient 15") >>= gradient);
632     CPPUNIT_ASSERT_EQUAL(sal_Int16(300), gradient.Angle); // 3900
633 
634     CPPUNIT_ASSERT(xGradients->getByName("Gradient 16") >>= gradient);
635     CPPUNIT_ASSERT_EQUAL(sal_Int16(105), gradient.Angle); // 10.5deg
636 
637     CPPUNIT_ASSERT(xGradients->getByName("Gradient 17") >>= gradient);
638     CPPUNIT_ASSERT_EQUAL(sal_Int16(1800), gradient.Angle); // \pi rad
639 
640     uno::Reference<container::XNameAccess> const xTranspGradients(
641         xDoc->createInstance("com.sun.star.drawing.TransparencyGradientTable"),
642         uno::UNO_QUERY);
643 
644     CPPUNIT_ASSERT(xTranspGradients->getByName("Transparency 2") >>= gradient);
645     CPPUNIT_ASSERT_EQUAL(sal_Int16(10), gradient.Angle); // 1
646 
647     CPPUNIT_ASSERT(xTranspGradients->getByName("Transparency 1") >>= gradient);
648     CPPUNIT_ASSERT_EQUAL(sal_Int16(900), gradient.Angle); // 90deg
649 
650     CPPUNIT_ASSERT(xTranspGradients->getByName("Transparency 3") >>= gradient);
651     CPPUNIT_ASSERT_EQUAL(sal_Int16(572), gradient.Angle); // 1.0rad
652 
653     CPPUNIT_ASSERT(xTranspGradients->getByName("Transparency 4") >>= gradient);
654     CPPUNIT_ASSERT_EQUAL(sal_Int16(1800), gradient.Angle); // 1000grad
655 
656     xDocShRef->DoClose();
657 }
658 
659 void SdImportTest::testN778859()
660 {
661     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n778859.pptx"), PPTX);
662 
663     const SdrPage *pPage = GetPage( 1, xDocShRef );
664     {
665         // Get the object
666         SdrObject *pObj = pPage->GetObj(1);
667         SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
668         CPPUNIT_ASSERT_MESSAGE( "no text object", pTxtObj != nullptr);
669         CPPUNIT_ASSERT(!pTxtObj->IsAutoFit());
670     }
671 
672     xDocShRef->DoClose();
673 }
674 
675 void SdImportTest::testFdo68594()
676 {
677     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/fdo68594.ppt"), PPT);
678 
679     const SdrPage *pPage = &(GetPage( 1, xDocShRef )->TRG_GetMasterPage());
680     SdrObject *pObj = pPage->GetObj(1);
681     SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
682     CPPUNIT_ASSERT_MESSAGE( "no text object", pTxtObj != nullptr);
683     const SvxColorItem *pC = &pTxtObj->GetMergedItem(EE_CHAR_COLOR);
684     CPPUNIT_ASSERT_MESSAGE( "no color item", pC != nullptr);
685     // Color should be black
686     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Placeholder color mismatch", sal_uInt32(0), sal_uInt32(pC->GetValue()) );
687 
688     xDocShRef->DoClose();
689 }
690 
691 void SdImportTest::testPptCrop()
692 {
693     sd::DrawDocShellRef xDocShRef
694         = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/crop.ppt"), PPT);
695 
696     uno::Reference<beans::XPropertySet> xPropertySet(
697         getShapeFromPage(/*nShape=*/1, /*nPage=*/0, xDocShRef));
698     text::GraphicCrop aCrop;
699     xPropertySet->getPropertyValue("GraphicCrop") >>= aCrop;
700     // These were all 0, lazy-loading broke cropping.
701     CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(0), aCrop.Top);
702     CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(0), aCrop.Bottom);
703     CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(0), aCrop.Left);
704     CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(0), aCrop.Right);
705 
706     xDocShRef->DoClose();
707 }
708 
709 void SdImportTest::testFdo72998()
710 {
711     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/cshapes.pptx"), PPTX);
712 
713     const SdrPage *pPage = GetPage( 1, xDocShRef );
714     {
715         SdrObjCustomShape *pObj = dynamic_cast<SdrObjCustomShape *>(pPage->GetObj(2));
716         CPPUNIT_ASSERT( pObj );
717         const SdrCustomShapeGeometryItem& rGeometryItem = pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
718         const css::uno::Any* pViewBox = const_cast<SdrCustomShapeGeometryItem&>(rGeometryItem).GetPropertyValueByName( OUString( "ViewBox" ) );
719         CPPUNIT_ASSERT_MESSAGE( "Missing ViewBox", pViewBox );
720         css::awt::Rectangle aViewBox;
721         CPPUNIT_ASSERT( (*pViewBox >>= aViewBox ) );
722         CPPUNIT_ASSERT_MESSAGE( "Width should be zero - for forcing scale to 1", !aViewBox.Width );
723         CPPUNIT_ASSERT_MESSAGE( "Height should be zero - for forcing scale to 1", !aViewBox.Height );
724     }
725 
726     xDocShRef->DoClose();
727 }
728 
729 void SdImportTest::testFdo77027()
730 {
731     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odp/fdo77027.odp"), ODP);
732 
733     const SdrPage *pPage = GetPage( 1, xDocShRef );
734     {
735         SdrOle2Obj *const pObj = dynamic_cast<SdrOle2Obj*>(pPage->GetObj(0));
736         CPPUNIT_ASSERT(pObj);
737 
738         // check that the fill style/color was actually imported
739         const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
740                 pObj->GetMergedItem(XATTR_FILLSTYLE));
741         CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
742         const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
743                 pObj->GetMergedItem(XATTR_FILLCOLOR));
744         CPPUNIT_ASSERT_EQUAL(Color(0xff6600), rColorItem.GetColorValue());
745     }
746 
747     xDocShRef->DoClose();
748 }
749 
750 void SdImportTest::testTdf97808()
751 {
752     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/tdf97808.fodp"), FODP);
753 
754     uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(
755         xDocShRef->GetModel(), uno::UNO_QUERY);
756     uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
757     uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("graphics"), uno::UNO_QUERY);
758     uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("objectwithoutfill"), uno::UNO_QUERY);
759     OUString lineend;
760     CPPUNIT_ASSERT(xStyle->getPropertyValue("LineEndName") >>= lineend);
761     CPPUNIT_ASSERT_EQUAL(OUString("Arrow"), lineend);
762 
763     // the draw:marker-end="" did not override the style
764     uno::Reference<drawing::XDrawPagesSupplier> xDoc(
765         xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW);
766     uno::Reference<drawing::XDrawPage> xPage(
767         xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW);
768     uno::Reference<beans::XPropertySet> xLine(
769         xPage->getByIndex(0), uno::UNO_QUERY_THROW);
770     //uno::Reference<style::XStyle> xParent;
771     uno::Reference<beans::XPropertySet> xParent;
772     CPPUNIT_ASSERT(xLine->getPropertyValue("Style") >>= xParent);
773     CPPUNIT_ASSERT_EQUAL(xStyle, xParent);
774     CPPUNIT_ASSERT(xLine->getPropertyValue("LineEndName") >>= lineend);
775     CPPUNIT_ASSERT_EQUAL(OUString(), lineend);
776 
777     xDocShRef->DoClose();
778 }
779 void SdImportTest::testFillStyleNone()
780 {
781     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/tdf123841.odg"), ODG);
782 
783     const SdrPage* pPage = GetPage(1, xDocShRef);
784     const SdrObject* pObj = pPage->GetObj(0);
785     auto& rFillStyleItem
786         = dynamic_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE));
787     // Without the accompanying fix in place, this test would have failed with 'Expected: 0; Actual:
788     // 1', i.e. the shape's fill was FillStyle_SOLID, making the text of the shape unreadable.
789     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, rFillStyleItem.GetValue());
790     xDocShRef->DoClose();
791 }
792 
793 void SdImportTest::testFdo64512()
794 {
795     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/fdo64512.odp"), ODP);
796 
797     uno::Reference< drawing::XDrawPagesSupplier > xDoc(
798         xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
799     CPPUNIT_ASSERT_EQUAL_MESSAGE( "not exactly one page", static_cast<sal_Int32>(1), xDoc->getDrawPages()->getCount() );
800 
801     uno::Reference< drawing::XDrawPage > xPage(
802         xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW );
803     CPPUNIT_ASSERT_EQUAL_MESSAGE( "not exactly three shapes", static_cast<sal_Int32>(3), xPage->getCount() );
804 
805     uno::Reference< beans::XPropertySet > xConnectorShape(
806         xPage->getByIndex(2), uno::UNO_QUERY );
807     CPPUNIT_ASSERT_MESSAGE( "no connector shape", xConnectorShape.is() );
808 
809     uno::Reference< beans::XPropertySet > xSvgShape(
810         xConnectorShape->getPropertyValue("StartShape"), uno::UNO_QUERY );
811     CPPUNIT_ASSERT_MESSAGE( "no start shape", xSvgShape.is() );
812 
813     uno::Reference< beans::XPropertySet > xCustomShape(
814         xConnectorShape->getPropertyValue("EndShape"), uno::UNO_QUERY );
815     CPPUNIT_ASSERT_MESSAGE( "no end shape", xCustomShape.is() );
816 
817     uno::Reference< animations::XAnimationNodeSupplier > xAnimNodeSupplier(
818         xPage, uno::UNO_QUERY_THROW );
819     uno::Reference< animations::XAnimationNode > xRootNode(
820         xAnimNodeSupplier->getAnimationNode() );
821     std::vector< uno::Reference< animations::XAnimationNode > > aAnimVector;
822     anim::create_deep_vector(xRootNode, aAnimVector);
823     CPPUNIT_ASSERT_EQUAL_MESSAGE( "not 8 animation nodes", static_cast<std::size_t>(8), aAnimVector.size() );
824 
825     uno::Reference< animations::XAnimate > xNode(
826         aAnimVector[7], uno::UNO_QUERY_THROW );
827     uno::Reference< drawing::XShape > xTargetShape(
828         xNode->getTarget(), uno::UNO_QUERY_THROW );
829     CPPUNIT_ASSERT_MESSAGE( "inner node not referencing svg shape",
830                             xTargetShape != xSvgShape );
831 
832     xDocShRef->DoClose();
833 }
834 
835 // Unit test for importing charts
836 void SdImportTest::testFdo71075()
837 {
838     double values[] = { 12.0, 13.0, 14.0 };
839     css::uno::Any aAny;
840     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/fdo71075.odp"), ODP);
841 
842     uno::Reference< beans::XPropertySet > xPropSet( getShapeFromPage( 0, 0, xDocShRef ) );
843     aAny = xPropSet->getPropertyValue( "Model" );
844     CPPUNIT_ASSERT_MESSAGE( "The shape doesn't have the property", aAny.hasValue() );
845 
846     uno::Reference< chart::XChartDocument > xChartDoc;
847     aAny >>= xChartDoc;
848     CPPUNIT_ASSERT_MESSAGE( "failed to load chart", xChartDoc.is() );
849     uno::Reference< chart2::XChartDocument > xChart2Doc( xChartDoc, uno::UNO_QUERY );
850     CPPUNIT_ASSERT_MESSAGE( "failed to load chart", xChart2Doc.is() );
851 
852     uno::Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( xChart2Doc->getFirstDiagram(), uno::UNO_QUERY );
853     uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysSeq( xBCooSysCnt->getCoordinateSystems());
854     uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[0], uno::UNO_QUERY );
855 
856     uno::Reference< chart2::XDataSeriesContainer > xDSCnt( xCTCnt->getChartTypes()[0], uno::UNO_QUERY );
857     CPPUNIT_ASSERT_MESSAGE( "failed to load data series", xDSCnt.is() );
858     uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries());
859     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Invalid Series count", static_cast<sal_Int32>(1), aSeriesSeq.getLength() );
860     uno::Reference< chart2::data::XDataSource > xSource( aSeriesSeq[0], uno::UNO_QUERY );
861     uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(xSource->getDataSequences());
862     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Invalid Series count", static_cast<sal_Int32>(1), aSeqCnt.getLength());
863     uno::Reference< chart2::data::XDataSequence > xValueSeq( aSeqCnt[0]->getValues() );
864     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Invalid Data count", static_cast<sal_Int32>(SAL_N_ELEMENTS(values)), xValueSeq->getData().getLength());
865     uno::Reference< chart2::data::XNumericalDataSequence > xNumSeq( xValueSeq, uno::UNO_QUERY );
866     uno::Sequence< double > aValues( xNumSeq->getNumericalData());
867     for(sal_Int32 i=0;i<xValueSeq->getData().getLength();i++)
868         CPPUNIT_ASSERT_EQUAL_MESSAGE( "Invalid Series count", values[i], aValues.getConstArray()[i]);
869 
870     xDocShRef->DoClose();
871 }
872 
873 void SdImportTest::testStrictOOXML()
874 {
875     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/strict_ooxml.pptx"), PPTX);
876 
877     SdDrawDocument *pDoc = xDocShRef->GetDoc();
878     CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
879     getShapeFromPage( 0, 0, xDocShRef );
880 
881     xDocShRef->DoClose();
882 }
883 
884 void SdImportTest::testBnc870237()
885 {
886     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc870237.pptx"), PPTX);
887     const SdrPage *pPage = GetPage( 1, xDocShRef );
888 
889     // Simulate a:ext inside dsp:txXfrm with changing the lower distance
890     const SdrObjGroup* pGroupObj = dynamic_cast<SdrObjGroup*>( pPage->GetObj( 0 ) );
891     const SdrObject* pObj = pGroupObj->GetSubList()->GetObj( 1 );
892     CPPUNIT_ASSERT_MESSAGE( "no object", pObj != nullptr);
893     CPPUNIT_ASSERT_EQUAL( sal_Int32(0), pObj->GetMergedItem(SDRATTR_TEXT_UPPERDIST).GetValue());
894     CPPUNIT_ASSERT_EQUAL( sal_Int32(9919), pObj->GetMergedItem(SDRATTR_TEXT_LOWERDIST).GetValue());
895     CPPUNIT_ASSERT_EQUAL( sal_Int32(0), pObj->GetMergedItem(SDRATTR_TEXT_RIGHTDIST).GetValue());
896     CPPUNIT_ASSERT_EQUAL( sal_Int32(0), pObj->GetMergedItem(SDRATTR_TEXT_LEFTDIST).GetValue());
897 
898     xDocShRef->DoClose();
899 }
900 
901 void SdImportTest::testCreationDate()
902 {
903     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/fdo71434.pptx"), PPTX);
904     uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(xDocShRef->GetModel(), uno::UNO_QUERY);
905     uno::Reference<document::XDocumentProperties> xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties();
906     util::DateTime aDate = xDocumentProperties->getCreationDate();
907     OUStringBuffer aBuffer;
908     sax::Converter::convertDateTime(aBuffer, aDate, nullptr);
909     // Metadata wasn't imported, this was 0000-00-00.
910     CPPUNIT_ASSERT_EQUAL(OUString("2013-11-09T10:37:56"), aBuffer.makeStringAndClear());
911     xDocShRef->DoClose();
912 }
913 
914 void SdImportTest::testPredefinedTableStyle()
915 {
916     // 073A0DAA-6AF3-43AB-8588-CEC1D06C72B9 (Medium Style 2)
917     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/predefined-table-style.pptx"), PPTX );
918     const SdrPage *pPage = GetPage( 1, xDocShRef );
919 
920     sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
921     CPPUNIT_ASSERT( pTableObj );
922 
923     uno::Reference< table::XCellRange > xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
924     uno::Reference< beans::XPropertySet > xCell;
925     sal_Int32 nColor;
926 
927     xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
928     xCell->getPropertyValue("FillColor") >>= nColor;
929     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nColor);
930 
931     xCell.set(xTable->getCellByPosition(0, 1), uno::UNO_QUERY_THROW);
932     xCell->getPropertyValue("FillColor") >>= nColor;
933     CPPUNIT_ASSERT_EQUAL(sal_Int32(13421772), nColor);
934 
935     xCell.set(xTable->getCellByPosition(0, 2), uno::UNO_QUERY_THROW);
936     xCell->getPropertyValue("FillColor") >>= nColor;
937     CPPUNIT_ASSERT_EQUAL(sal_Int32(15198183), nColor);
938 
939     xDocShRef->DoClose();
940 }
941 
942 void SdImportTest::testBnc887225()
943 {
944     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc887225.pptx"), PPTX );
945     // In the document, lastRow and lastCol table properties are used.
946     // Make sure styles are set properly for individual cells.
947 
948     const SdrPage *pPage = GetPage( 1, xDocShRef );
949 
950     sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(2));
951     CPPUNIT_ASSERT( pTableObj );
952     uno::Reference< table::XCellRange > xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
953     uno::Reference< beans::XPropertySet > xCell;
954     sal_Int32 nColor;
955 
956     xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
957     xCell->getPropertyValue("FillColor") >>= nColor;
958     CPPUNIT_ASSERT_EQUAL(sal_Int32(6003669), nColor);
959 
960     xCell.set(xTable->getCellByPosition(0, 1), uno::UNO_QUERY_THROW);
961     xCell->getPropertyValue("FillColor") >>= nColor;
962     CPPUNIT_ASSERT_EQUAL(sal_Int32(6003669), nColor);
963 
964     xCell.set(xTable->getCellByPosition(1, 1), uno::UNO_QUERY_THROW);
965     xCell->getPropertyValue("FillColor") >>= nColor;
966     CPPUNIT_ASSERT_EQUAL(sal_Int32(13754095), nColor);
967 
968     xCell.set(xTable->getCellByPosition(1, 2), uno::UNO_QUERY_THROW);
969     xCell->getPropertyValue("FillColor") >>= nColor;
970     CPPUNIT_ASSERT_EQUAL(sal_Int32(15331319), nColor);
971 
972     xCell.set(xTable->getCellByPosition(1, 4), uno::UNO_QUERY_THROW);
973     xCell->getPropertyValue("FillColor") >>= nColor;
974     CPPUNIT_ASSERT_EQUAL(sal_Int32(6003669), nColor);
975 
976     xCell.set(xTable->getCellByPosition(3, 2), uno::UNO_QUERY_THROW);
977     xCell->getPropertyValue("FillColor") >>= nColor;
978     CPPUNIT_ASSERT_EQUAL(sal_Int32(6003669), nColor);
979 
980     xCell.set(xTable->getCellByPosition(3, 4), uno::UNO_QUERY_THROW);
981     xCell->getPropertyValue("FillColor") >>= nColor;
982     CPPUNIT_ASSERT_EQUAL(sal_Int32(6003669), nColor);
983 
984     xDocShRef->DoClose();
985 }
986 
987 void SdImportTest::testBnc584721_1()
988 {
989     // Title text shape on the master page contained wrong text.
990 
991     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc584721_1_2.pptx"), PPTX);
992 
993     const SdrPage *pPage = &(GetPage( 1, xDocShRef )->TRG_GetMasterPage());
994     SdrObject *pObj = pPage->GetObj(0);
995     SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
996     CPPUNIT_ASSERT_MESSAGE( "no text object", pTxtObj != nullptr);
997     const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
998     CPPUNIT_ASSERT_EQUAL(OUString("Click to edit Master title style"), aEdit.GetText(0));
999     xDocShRef->DoClose();
1000 }
1001 
1002 void SdImportTest::testBnc584721_2()
1003 {
1004     // Import created an extra/unneeded outliner shape on the master slide next to the imported title shape.
1005 
1006     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc584721_1_2.pptx"), PPTX);
1007 
1008     const SdrPage *pPage = &(GetPage( 1, xDocShRef )->TRG_GetMasterPage());
1009     CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
1010 
1011     xDocShRef->DoClose();
1012 }
1013 
1014 void SdImportTest::testBnc591147()
1015 {
1016     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc591147.pptx"), PPTX);
1017 
1018     // In the document, there are two slides with media files.
1019     uno::Reference< drawing::XDrawPagesSupplier > xDoc(
1020         xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
1021     CPPUNIT_ASSERT_EQUAL( sal_Int32(2), xDoc->getDrawPages()->getCount() );
1022 
1023     // First page has video file inserted
1024     uno::Reference< drawing::XDrawPage > xPage(
1025         xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW );
1026     CPPUNIT_ASSERT_EQUAL( sal_Int32(1), xPage->getCount() );
1027 
1028     //uno::Reference< drawing::XShape > xShape(xPage->getByIndex(0), uno::UNO_QUERY_THROW );
1029     uno::Reference< beans::XPropertySet > xPropSet( getShape( 0, xPage ) );
1030     OUString sVideoURL("emptyURL");
1031     bool bSuccess = xPropSet->getPropertyValue("MediaURL") >>= sVideoURL;
1032     CPPUNIT_ASSERT_MESSAGE( "MediaURL property is not set", bSuccess );
1033     CPPUNIT_ASSERT_MESSAGE("MediaURL is empty", !sVideoURL.isEmpty());
1034 
1035     // Second page has audio file inserted
1036     xPage.set( xDoc->getDrawPages()->getByIndex(1), uno::UNO_QUERY_THROW );
1037     CPPUNIT_ASSERT_EQUAL( sal_Int32(1), xPage->getCount() );
1038 
1039     xPropSet.set( getShape( 0, xPage ) );
1040     OUString sAudioURL("emptyURL");
1041     bSuccess = xPropSet->getPropertyValue("MediaURL") >>= sAudioURL;
1042     CPPUNIT_ASSERT_MESSAGE( "MediaURL property is not set", bSuccess );
1043     CPPUNIT_ASSERT_MESSAGE("MediaURL is empty", !sAudioURL.isEmpty());
1044 
1045     CPPUNIT_ASSERT_MESSAGE( "sAudioURL and sVideoURL should not be equal", sAudioURL != sVideoURL );
1046 
1047     xDocShRef->DoClose();
1048 }
1049 
1050 void SdImportTest::testBnc584721_4()
1051 {
1052     // Black text was imported as white because of wrong caching mechanism
1053 
1054     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc584721_4.pptx"), PPTX);
1055     uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 1, 1, xDocShRef ) );
1056 
1057     // Get first paragraph of the text
1058     uno::Reference<text::XTextRange> const xParagraph( getParagraphFromShape( 0, xShape ) );
1059 
1060     // Get first run of the paragraph
1061     uno::Reference<text::XTextRange> xRun( getRunFromParagraph (0, xParagraph ) );
1062     uno::Reference< beans::XPropertySet > xPropSet( xRun, uno::UNO_QUERY_THROW );
1063     Color nCharColor;
1064     xPropSet->getPropertyValue( "CharColor" ) >>= nCharColor;
1065 
1066     // Color should be black
1067     CPPUNIT_ASSERT_EQUAL( COL_BLACK, nCharColor );
1068 
1069     xDocShRef->DoClose();
1070 }
1071 
1072 void SdImportTest::testBnc904423()
1073 {
1074     // Here the problem was that different fill properties were applied in wrong order on the shape
1075     // Right order: 1) master slide fill style, 2) theme, 3) direct formatting
1076     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/bnc904423.pptx"), PPTX);
1077 
1078     const SdrPage *pPage = GetPage( 1, xDocShRef );
1079     // First shape's background color is defined on master slide
1080     {
1081         SdrObject *const pObj = pPage->GetObj(0);
1082         CPPUNIT_ASSERT(pObj);
1083 
1084         const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
1085                 pObj->GetMergedItem(XATTR_FILLSTYLE));
1086         CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
1087         const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
1088                 pObj->GetMergedItem(XATTR_FILLCOLOR));
1089         CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x00CC99), sal_uInt32(rColorItem.GetColorValue()));
1090     }
1091 
1092     // Second shape's background color is defined by theme
1093     {
1094         SdrObject *const pObj = pPage->GetObj(1);
1095         CPPUNIT_ASSERT(pObj);
1096 
1097         const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
1098                 pObj->GetMergedItem(XATTR_FILLSTYLE));
1099         CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
1100         const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
1101                 pObj->GetMergedItem(XATTR_FILLCOLOR));
1102         CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x3333CC), sal_uInt32(rColorItem.GetColorValue()));
1103     }
1104 
1105     // Third shape's background color is defined by direct formatting
1106     {
1107         SdrObject *const pObj = pPage->GetObj(2);
1108         CPPUNIT_ASSERT(pObj);
1109 
1110         const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
1111                 pObj->GetMergedItem(XATTR_FILLSTYLE));
1112         CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
1113         const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
1114                 pObj->GetMergedItem(XATTR_FILLCOLOR));
1115         CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xFF0000), sal_uInt32(rColorItem.GetColorValue()));
1116     }
1117 
1118     xDocShRef->DoClose();
1119 }
1120 
1121 void SdImportTest::testShapeLineStyle()
1122 {
1123     // Here the problem was that different line properties were applied in wrong order on the shape
1124     // Right order: 1) master slide line style, 2) theme, 3) direct formatting
1125     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/ShapeLineProperties.pptx"), PPTX);
1126 
1127     const SdrPage *pPage = GetPage( 1, xDocShRef );
1128     // First shape's line style is defined on master slide
1129     {
1130         SdrObject *const pObj = pPage->GetObj(0);
1131         CPPUNIT_ASSERT(pObj);
1132 
1133         const XLineStyleItem& rStyleItem = dynamic_cast<const XLineStyleItem&>(
1134                 pObj->GetMergedItem(XATTR_LINESTYLE));
1135         CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_DASH, rStyleItem.GetValue());
1136 
1137         const XLineColorItem& rColorItem = dynamic_cast<const XLineColorItem&>(
1138                 pObj->GetMergedItem(XATTR_LINECOLOR));
1139         CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xFF0000), sal_uInt32(rColorItem.GetColorValue()));
1140 
1141         const XLineWidthItem& rWidthItem = dynamic_cast<const XLineWidthItem&>(
1142                 pObj->GetMergedItem(XATTR_LINEWIDTH));
1143         CPPUNIT_ASSERT_EQUAL(sal_Int32(132), rWidthItem.GetValue());
1144     }
1145 
1146     // Second shape's line style is defined by theme
1147     {
1148         SdrObject *const pObj = pPage->GetObj(1);
1149         CPPUNIT_ASSERT(pObj);
1150 
1151         const XLineStyleItem& rStyleItem = dynamic_cast<const XLineStyleItem&>(
1152                 pObj->GetMergedItem(XATTR_LINESTYLE));
1153         CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_SOLID, rStyleItem.GetValue());
1154 
1155         const XLineColorItem& rColorItem = dynamic_cast<const XLineColorItem&>(
1156                 pObj->GetMergedItem(XATTR_LINECOLOR));
1157         CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x3333CC), sal_uInt32(rColorItem.GetColorValue()));
1158 
1159         const XLineWidthItem& rWidthItem = dynamic_cast<const XLineWidthItem&>(
1160                 pObj->GetMergedItem(XATTR_LINEWIDTH));
1161         CPPUNIT_ASSERT_EQUAL(sal_Int32(35), rWidthItem.GetValue());
1162     }
1163 
1164     // Third shape's line style is defined by direct formatting
1165     {
1166         SdrObject *const pObj = pPage->GetObj(2);
1167         CPPUNIT_ASSERT(pObj);
1168 
1169         const XLineStyleItem& rStyleItem = dynamic_cast<const XLineStyleItem&>(
1170                 pObj->GetMergedItem(XATTR_LINESTYLE));
1171         CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_SOLID, rStyleItem.GetValue());
1172 
1173         const XLineColorItem& rColorItem = dynamic_cast<const XLineColorItem&>(
1174                 pObj->GetMergedItem(XATTR_LINECOLOR));
1175         CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x7030A0), sal_uInt32(rColorItem.GetColorValue()));
1176 
1177         const XLineWidthItem& rWidthItem = dynamic_cast<const XLineWidthItem&>(
1178                 pObj->GetMergedItem(XATTR_LINEWIDTH));
1179         CPPUNIT_ASSERT_EQUAL(sal_Int32(176), rWidthItem.GetValue());
1180     }
1181 
1182     xDocShRef->DoClose();
1183 }
1184 
1185 void SdImportTest::testTableBorderLineStyle()
1186 {
1187     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tableBorderLineStyle.pptx"), PPTX );
1188 
1189     // TODO: If you are working on improvement of table border line style
1190     // support, then expect this unit test to fail.
1191 
1192     const sal_Int16 nObjBorderLineStyles[] =
1193         {
1194             ::table::BorderLineStyle::DASHED,
1195             ::table::BorderLineStyle::DASH_DOT_DOT,
1196             ::table::BorderLineStyle::DASH_DOT,
1197             ::table::BorderLineStyle::DOTTED,
1198             ::table::BorderLineStyle::DASHED,
1199             ::table::BorderLineStyle::DOTTED,
1200             ::table::BorderLineStyle::DASHED,
1201             ::table::BorderLineStyle::DASH_DOT,
1202             ::table::BorderLineStyle::DASH_DOT,
1203             ::table::BorderLineStyle::SOLID,
1204             ::table::BorderLineStyle::NONE
1205         };
1206 
1207     const SdrPage *pPage = GetPage( 1, xDocShRef );
1208     CPPUNIT_ASSERT_EQUAL(SAL_N_ELEMENTS(nObjBorderLineStyles), pPage->GetObjCount());
1209 
1210     sdr::table::SdrTableObj *pTableObj;
1211     uno::Reference< table::XCellRange > xTable;
1212     uno::Reference< beans::XPropertySet > xCell;
1213     table::BorderLine2 aBorderLine;
1214 
1215     for (size_t i = 0; i < SAL_N_ELEMENTS(nObjBorderLineStyles); i++)
1216     {
1217         pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(i));
1218         CPPUNIT_ASSERT( pTableObj );
1219         xTable.set(pTableObj->getTable(), uno::UNO_QUERY_THROW);
1220         xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
1221         xCell->getPropertyValue("TopBorder") >>= aBorderLine;
1222         if (aBorderLine.LineWidth > 0) {
1223             CPPUNIT_ASSERT_EQUAL(nObjBorderLineStyles[i], aBorderLine.LineStyle);
1224         }
1225     }
1226 
1227     xDocShRef->DoClose();
1228 }
1229 
1230 void SdImportTest::testBnc862510_6()
1231 {
1232     // Black text was imported instead of gray
1233     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc862510_6.pptx"), PPTX);
1234     uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
1235 
1236     // Get first paragraph of the text
1237     uno::Reference<text::XTextRange> const xParagraph( getParagraphFromShape( 0, xShape ) );
1238 
1239     // Get first run of the paragraph
1240     uno::Reference<text::XTextRange> xRun( getRunFromParagraph( 0, xParagraph ) );
1241     uno::Reference< beans::XPropertySet > xPropSet( xRun, uno::UNO_QUERY_THROW );
1242     sal_Int32 nCharColor;
1243     xPropSet->getPropertyValue( "CharColor" ) >>= nCharColor;
1244 
1245     // Color should be gray
1246     CPPUNIT_ASSERT_EQUAL( sal_Int32(0x8B8B8B), nCharColor );
1247 
1248     xDocShRef->DoClose();
1249 }
1250 
1251 void SdImportTest::testBnc862510_7()
1252 {
1253     // Title shape's text was aligned to left instead of center.
1254     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc862510_7.pptx"), PPTX);
1255     uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
1256 
1257     // Get first paragraph
1258     uno::Reference<text::XTextRange> const xParagraph( getParagraphFromShape( 0, xShape ) );
1259     uno::Reference< beans::XPropertySet > xPropSet( xParagraph, uno::UNO_QUERY_THROW );
1260 
1261     sal_Int16 nParaAdjust = 0;
1262     xPropSet->getPropertyValue( "ParaAdjust" ) >>= nParaAdjust;
1263     CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER, static_cast<style::ParagraphAdjust>(nParaAdjust));
1264 
1265     xDocShRef->DoClose();
1266 }
1267 
1268 #if ENABLE_PDFIMPORT
1269 // These tests use the old PDF-importing logic, which imports PDF elements as
1270 // SD elements. This suffered many issues, and therefore wasn't ideal.
1271 // The old PDF importer relied on an open-source project (xpdf) with an
1272 // incompatible license (gpl), which has to be interfaced via an out-of-process
1273 // library wrapper process. The resulting imported document was inaccurate
1274 // and often very slow and with large memory footprint.
1275 // Instead, PDFium offers state-of-the-art PDF importing logic,
1276 // which is well-maintained and renders PDFs into images with high accuracy.
1277 // So, the idea is to import PDFs as images using PDFium, which has a very
1278 // high quality (and is much faster) than importing individual editable elements.
1279 // So that's the "new" way of importing.
1280 // The user then breaks the image to editable elements (which is not perfect,
1281 // but very close to the old way), only if they need editing ability.
1282 // PDFium should overall be better, and where it isn't, we just need to improve it.
1283 // So these tests aren't really useful anymore. They should be modified to do
1284 // import+break and then check the results. But that isn't straight-forward and
1285 // currently await volunteering time to implement.
1286 
1287 #if HAVE_FEATURE_PDFIUM
1288 void SdImportTest::testPDFImportShared()
1289 {
1290     comphelper::LibreOfficeKit::setActive();
1291     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pdf/multipage.pdf"), PDF);
1292     SdDrawDocument *pDoc = xDocShRef->GetDoc();
1293     CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
1294 
1295     // This test is to verify that we share the PDF stream linked to each
1296     // Graphic instance in the imported document.
1297     // Since we import PDFs as images, we support attaching the original
1298     // PDF with each image to allow for advanced editing.
1299     // Here we iterate over all Graphic instances embedded in the pages
1300     // and verify that they all point to the same object in memory.
1301     std::vector<Graphic> aGraphics;
1302 
1303     for (int nPageIndex = 0; nPageIndex < pDoc->GetPageCount(); ++nPageIndex)
1304     {
1305         const SdrPage* pPage = GetPage(nPageIndex, xDocShRef);
1306         if (pPage == nullptr)
1307             break;
1308 
1309         for (size_t nObjIndex = 0; nObjIndex < pPage->GetObjCount(); ++nObjIndex)
1310         {
1311             SdrObject* pObject = pPage->GetObj(nObjIndex);
1312             if (pObject == nullptr)
1313                 continue;
1314 
1315             SdrGrafObj* pSdrGrafObj = dynamic_cast<SdrGrafObj*>(pObject);
1316             if (pSdrGrafObj == nullptr)
1317                 continue;
1318 
1319             const GraphicObject& rGraphicObject = pSdrGrafObj->GetGraphicObject().GetGraphic();
1320             const Graphic& rGraphic = rGraphicObject.GetGraphic();
1321             CPPUNIT_ASSERT_MESSAGE("After loading, the PDF shouldn't have the primitive sequence created yet",
1322                                    !rGraphic.getVectorGraphicData()->isPrimitiveSequenceCreated());
1323             aGraphics.push_back(rGraphic);
1324         }
1325     }
1326 
1327     CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected more than one page.", size_t(9), aGraphics.size());
1328 
1329     Graphic const & rFirstGraphic = aGraphics[0];
1330 
1331     for (size_t i = 0; i < aGraphics.size(); ++i)
1332     {
1333         Graphic const & rGraphic = aGraphics[i];
1334         CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected all PDF streams to be identical.",
1335                                      rFirstGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray(),
1336                                      rGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray());
1337 
1338         CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected all GfxLinks to be identical.",
1339                                      rFirstGraphic.GetSharedGfxLink().get(),
1340                                      rGraphic.GetSharedGfxLink().get());
1341 
1342         CPPUNIT_ASSERT_EQUAL_MESSAGE("Page number doesn't match expected", sal_Int32(i), rGraphic.getPageNumber());
1343     }
1344 
1345     xDocShRef->DoClose();
1346     comphelper::LibreOfficeKit::setActive(false);
1347 }
1348 #endif
1349 
1350 #if defined(IMPORT_PDF_ELEMENTS)
1351 
1352 void SdImportTest::testPDFImport()
1353 {
1354     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pdf/txtpic.pdf"), PDF);
1355     SdDrawDocument *pDoc = xDocShRef->GetDoc();
1356     CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
1357     uno::Reference< drawing::XDrawPagesSupplier > xDoc(xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
1358     uno::Reference< drawing::XDrawPage > xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW );
1359     CPPUNIT_ASSERT_EQUAL_MESSAGE( "no exactly two shapes", static_cast<sal_Int32>(2), xPage->getCount() );
1360 
1361     uno::Reference< beans::XPropertySet > xShape( getShape( 0, xPage ) );
1362     uno::Reference<text::XText> xText = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
1363     CPPUNIT_ASSERT_MESSAGE( "not a text shape", xText.is() );
1364 
1365     xDocShRef->DoClose();
1366 }
1367 
1368 void SdImportTest::testPDFImportSkipImages()
1369 {
1370     auto pParams = std::make_shared<SfxAllItemSet>( SfxGetpApp()->GetPool() );
1371     pParams->Put( SfxStringItem ( SID_FILE_FILTEROPTIONS, "SkipImages" ) );
1372 
1373     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pdf/txtpic.pdf"), PDF, pParams);
1374     SdDrawDocument *pDoc = xDocShRef->GetDoc();
1375     CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
1376     uno::Reference< drawing::XDrawPagesSupplier > xDoc(xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
1377     uno::Reference< drawing::XDrawPage > xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW );
1378     CPPUNIT_ASSERT_EQUAL_MESSAGE( "no exactly one shape", static_cast<sal_Int32>(1), xPage->getCount() );
1379 
1380     uno::Reference< drawing::XShape > xShape(xPage->getByIndex(0), uno::UNO_QUERY_THROW );
1381     uno::Reference<text::XText> xText = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
1382     CPPUNIT_ASSERT_MESSAGE( "not a text shape", xText.is() );
1383 
1384     xDocShRef->DoClose();
1385 }
1386 
1387 #endif
1388 #endif
1389 
1390 void SdImportTest::testBulletSuffix()
1391 {
1392     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n83889.pptx"), PPTX );
1393 
1394     // check suffix of the char bullet
1395     const SdrPage *pPage = GetPage( 1, xDocShRef );
1396     SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pPage->GetObj(0) );
1397     CPPUNIT_ASSERT_MESSAGE( "no text object", pTxtObj != nullptr);
1398     const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
1399     const SvxNumBulletItem *pNumFmt = aEdit.GetParaAttribs(1).GetItem(EE_PARA_NUMBULLET);
1400     CPPUNIT_ASSERT(pNumFmt);
1401     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bullet's suffix is wrong!", pNumFmt->GetNumRule()->GetLevel(0).GetSuffix(), OUString() );
1402     xDocShRef->DoClose();
1403 }
1404 
1405 void SdImportTest::testBnc910045()
1406 {
1407     // Problem with table style which defines cell color with fill style
1408     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc910045.pptx"), PPTX );
1409     const SdrPage *pPage = GetPage( 1, xDocShRef );
1410 
1411     sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
1412     CPPUNIT_ASSERT( pTableObj );
1413     uno::Reference< table::XCellRange > xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
1414     uno::Reference< beans::XPropertySet > xCell;
1415     sal_Int32 nColor;
1416 
1417     xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
1418     xCell->getPropertyValue("FillColor") >>= nColor;
1419     CPPUNIT_ASSERT_EQUAL(sal_Int32(5210557), nColor);
1420 
1421     xDocShRef->DoClose();
1422 }
1423 
1424 void SdImportTest::testRowHeight()
1425 {
1426     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n80340.pptx"), PPTX );
1427     const SdrPage *pPage = GetPage( 1, xDocShRef );
1428 
1429     sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
1430     CPPUNIT_ASSERT( pTableObj );
1431 
1432     sal_Int32 nHeight;
1433     uno::Reference< css::table::XTable > xTable(pTableObj->getTable(), uno::UNO_SET_THROW);
1434     uno::Reference< css::table::XTableRows > xRows( xTable->getRows(), uno::UNO_SET_THROW);
1435     uno::Reference< beans::XPropertySet > xRefRow( xRows->getByIndex(0), uno::UNO_QUERY_THROW );
1436     xRefRow->getPropertyValue( "Height" ) >>= nHeight;
1437     CPPUNIT_ASSERT_EQUAL( sal_Int32(507), nHeight);
1438 
1439     xDocShRef->DoClose();
1440 }
1441 
1442 void SdImportTest::testTdf93830()
1443 {
1444     // Text shape offset was ignored
1445     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf93830.pptx"), PPTX);
1446     uno::Reference< drawing::XDrawPage > xPage( getPage( 0, xDocShRef ) );
1447 
1448     // Get the first text box from group shape
1449     uno::Reference< container::XIndexAccess > xShape( xPage->getByIndex(0), uno::UNO_QUERY );
1450     uno::Reference< beans::XPropertySet > xPropSet( xShape->getByIndex(3), uno::UNO_QUERY );
1451     CPPUNIT_ASSERT_MESSAGE( "no textbox shape", xPropSet.is() );
1452 
1453     sal_Int32 nTextLeftDistance = 0;
1454     xPropSet->getPropertyValue( "TextLeftDistance" ) >>= nTextLeftDistance;
1455     CPPUNIT_ASSERT_EQUAL(sal_Int32(4152), nTextLeftDistance);
1456 
1457     xDocShRef->DoClose();
1458 }
1459 
1460 void SdImportTest::testTdf127129()
1461 {
1462     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf127129.pptx"), PPTX);
1463     uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
1464     uno::Reference< text::XTextRange > xParagraph( getParagraphFromShape( 0, xShape ) );
1465     uno::Reference< text::XTextRange > xRun( getRunFromParagraph( 0, xParagraph ) );
1466     uno::Reference< beans::XPropertySet > xPropSet( xRun, uno::UNO_QUERY_THROW );
1467 
1468     sal_Int32 nCharColor;
1469     xPropSet->getPropertyValue( "CharColor" ) >>= nCharColor;
1470     CPPUNIT_ASSERT_EQUAL( sal_Int32(0x000000), nCharColor );
1471 
1472     // Without the accompanying fix in place, the highlight would be -1
1473     sal_Int32 nCharBackColor;
1474     xPropSet->getPropertyValue( "CharBackColor" ) >>= nCharBackColor;
1475     CPPUNIT_ASSERT_EQUAL( sal_Int32(0xFF00), nCharBackColor );
1476 
1477     xDocShRef->DoClose();
1478 }
1479 void SdImportTest::testTdf93097()
1480 {
1481     // Throwing metadata import aborted the filter, check that metadata is now imported.
1482     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf93097.pptx"), PPTX);
1483     uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(xDocShRef->GetModel(), uno::UNO_QUERY);
1484     uno::Reference<document::XDocumentProperties> xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties();
1485     CPPUNIT_ASSERT_EQUAL(OUString("ss"), xDocumentProperties->getTitle());
1486     xDocShRef->DoClose();
1487 }
1488 
1489 void SdImportTest::testTdf62255()
1490 {
1491     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf62255.pptx"), PPTX);
1492     const SdrPage *pPage = GetPage( 1, xDocShRef );
1493 
1494     sdr::table::SdrTableObj *pTableObj;
1495     pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
1496     CPPUNIT_ASSERT( pTableObj );
1497 
1498     css::uno::Any aAny;
1499     uno::Reference< table::XCellRange > xTable;
1500     uno::Reference< beans::XPropertySet > xCell;
1501     xTable.set(pTableObj->getTable(), uno::UNO_QUERY_THROW);
1502     xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
1503     aAny = xCell->getPropertyValue("FillStyle");
1504 
1505     if (aAny.hasValue())
1506     {
1507         drawing::FillStyle aFillStyle;
1508         aAny >>= aFillStyle;
1509         CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, aFillStyle);
1510     }
1511 
1512     xDocShRef->DoClose();
1513 }
1514 
1515 void SdImportTest::testTdf93124()
1516 {
1517     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/tdf93124.ppt"), PPT);
1518     uno::Reference < uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1519     uno::Reference< drawing::XGraphicExportFilter > xGraphicExporter = drawing::GraphicExportFilter::create(xContext);
1520 
1521     uno::Sequence< beans::PropertyValue > aFilterData(2);
1522     aFilterData[0].Name = "PixelWidth";
1523     aFilterData[0].Value <<= sal_Int32(320);
1524     aFilterData[1].Name = "PixelHeight";
1525     aFilterData[1].Value <<= sal_Int32(180);
1526 
1527     utl::TempFile aTempFile;
1528     aTempFile.EnableKillingFile();
1529 
1530     uno::Sequence< beans::PropertyValue > aDescriptor(3);
1531     aDescriptor[0].Name = "URL";
1532     aDescriptor[0].Value <<= aTempFile.GetURL();
1533     aDescriptor[1].Name = "FilterName";
1534     aDescriptor[1].Value <<= OUString("PNG");
1535     aDescriptor[2].Name = "FilterData";
1536     aDescriptor[2].Value <<= aFilterData;
1537 
1538     uno::Reference< lang::XComponent > xPage(getPage(0, xDocShRef), uno::UNO_QUERY);
1539     xGraphicExporter->setSourceDocument(xPage);
1540     xGraphicExporter->filter(aDescriptor);
1541 
1542     SvFileStream aFileStream(aTempFile.GetURL(), StreamMode::READ);
1543     vcl::PNGReader aPNGReader(aFileStream);
1544     BitmapEx aBMPEx = aPNGReader.Read();
1545 
1546     // make sure the bitmap is not empty and correct size (PNG export->import was successful)
1547     CPPUNIT_ASSERT_EQUAL(Size(320, 180), aBMPEx.GetSizePixel());
1548     Bitmap aBMP = aBMPEx.GetBitmap();
1549     {
1550         Bitmap::ScopedReadAccess pReadAccess(aBMP);
1551         int nNonWhiteCount = 0;
1552         // The word "Top" should be in rectangle 34,4 - 76,30. If text alignment is wrong, the rectangle will be white.
1553         for (long nY = 4; nY < (4 + 26); ++nY)
1554         {
1555             for (long nX = 34; nX < (34 + 43); ++nX)
1556             {
1557                 const Color aColor = pReadAccess->GetColor(nY, nX);
1558                 if ((aColor.GetRed() != 0xff) || (aColor.GetGreen() != 0xff) || (aColor.GetBlue() != 0xff))
1559                     ++nNonWhiteCount;
1560             }
1561         }
1562         CPPUNIT_ASSERT_MESSAGE("Tdf93124: vertical alignment of text is incorrect!", nNonWhiteCount>50);
1563     }
1564     xDocShRef->DoClose();
1565 }
1566 
1567 void SdImportTest::testTdf99729()
1568 {
1569     const OUString filenames[] = { "/sd/qa/unit/data/odp/tdf99729-new.odp", "/sd/qa/unit/data/odp/tdf99729-legacy.odp" };
1570     int nonwhitecounts[] = { 0, 0 };
1571     for (size_t i = 0; i < SAL_N_ELEMENTS(filenames); ++i)
1572     {
1573         // 1st check for new behaviour - having AnchoredTextOverflowLegacy compatibility flag set to false in settings.xml
1574         uno::Reference<lang::XComponent> xComponent
1575             = loadFromDesktop(m_directories.getURLFromSrc(filenames[i]),
1576                               "com.sun.star.presentation.PresentationDocument");
1577 
1578         uno::Reference<uno::XComponentContext> xContext = getComponentContext();
1579         CPPUNIT_ASSERT(xContext.is());
1580         uno::Reference< drawing::XGraphicExportFilter > xGraphicExporter = drawing::GraphicExportFilter::create(xContext);
1581         CPPUNIT_ASSERT(xGraphicExporter.is());
1582 
1583         uno::Sequence< beans::PropertyValue > aFilterData(2);
1584         aFilterData[0].Name = "PixelWidth";
1585         aFilterData[0].Value <<= sal_Int32(320);
1586         aFilterData[1].Name = "PixelHeight";
1587         aFilterData[1].Value <<= sal_Int32(240);
1588 
1589         utl::TempFile aTempFile;
1590         aTempFile.EnableKillingFile();
1591 
1592         uno::Sequence< beans::PropertyValue > aDescriptor(3);
1593         aDescriptor[0].Name = "URL";
1594         aDescriptor[0].Value <<= aTempFile.GetURL();
1595         aDescriptor[1].Name = "FilterName";
1596         aDescriptor[1].Value <<= OUString("PNG");
1597         aDescriptor[2].Name = "FilterData";
1598         aDescriptor[2].Value <<= aFilterData;
1599 
1600         uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(xComponent, uno::UNO_QUERY);
1601         uno::Reference<lang::XComponent> xPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
1602                                                uno::UNO_QUERY);
1603         CPPUNIT_ASSERT(xPage.is());
1604         xGraphicExporter->setSourceDocument(xPage);
1605         xGraphicExporter->filter(aDescriptor);
1606 
1607         SvFileStream aFileStream(aTempFile.GetURL(), StreamMode::READ);
1608         vcl::PNGReader aPNGReader(aFileStream);
1609         BitmapEx aBMPEx = aPNGReader.Read();
1610         Bitmap aBMP = aBMPEx.GetBitmap();
1611         Bitmap::ScopedReadAccess pRead(aBMP);
1612         for (long nX = 154; nX < (154 + 12); ++nX)
1613         {
1614             for (long nY = 16; nY < (16 + 96); ++nY)
1615             {
1616                 const Color aColor = pRead->GetColor(nY, nX);
1617                 if ((aColor.GetRed() != 0xff) || (aColor.GetGreen() != 0xff) || (aColor.GetBlue() != 0xff))
1618                     ++nonwhitecounts[i];
1619             }
1620         }
1621         xComponent->dispose();
1622     }
1623     // The numbers 1-9 should be above the Text Box in rectangle 154,16 - 170,112.
1624     // If text alignment is wrong, the rectangle will be white.
1625     CPPUNIT_ASSERT_MESSAGE("Tdf99729: vertical alignment of text is incorrect!", nonwhitecounts[0]>100); // it is 134 with cleartype disabled
1626     // The numbers 1-9 should be below the Text Box -> rectangle 154,16 - 170,112 should be white.
1627     CPPUNIT_ASSERT_EQUAL_MESSAGE("Tdf99729: legacy vertical alignment of text is incorrect!", 0, nonwhitecounts[1]);
1628 }
1629 
1630 void SdImportTest::testTdf89927()
1631 {
1632     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf89927.pptx"), PPTX);
1633     uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
1634     uno::Reference< text::XTextRange > xParagraph( getParagraphFromShape( 0, xShape ) );
1635     uno::Reference< text::XTextRange > xRun( getRunFromParagraph( 0, xParagraph ) );
1636     uno::Reference< beans::XPropertySet > xPropSet( xRun, uno::UNO_QUERY_THROW );
1637 
1638     sal_Int32 nCharColor;
1639     xPropSet->getPropertyValue( "CharColor" ) >>= nCharColor;
1640     CPPUNIT_ASSERT_EQUAL( sal_Int32(0xFFFFFF), nCharColor );
1641 
1642     xDocShRef->DoClose();
1643 }
1644 
1645 void SdImportTest::testTdf93868()
1646 {
1647     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf93868.pptx"), PPTX);
1648 
1649     const SdrPage *pPage = &(GetPage( 1, xDocShRef )->TRG_GetMasterPage());
1650     CPPUNIT_ASSERT_EQUAL(size_t(5), pPage->GetObjCount());
1651     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, dynamic_cast<const XFillStyleItem&>(pPage->GetObj(0)->GetMergedItem(XATTR_FILLSTYLE)).GetValue());
1652     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, dynamic_cast<const XFillStyleItem&>(pPage->GetObj(1)->GetMergedItem(XATTR_FILLSTYLE)).GetValue());
1653 
1654     xDocShRef->DoClose();
1655 }
1656 
1657 void SdImportTest::testTdf95932()
1658 {
1659     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf95932.pptx"), PPTX);
1660 
1661     const SdrPage *pPage = GetPage( 1, xDocShRef );
1662     SdrObject *const pObj = pPage->GetObj(2);
1663     CPPUNIT_ASSERT(pObj);
1664 
1665     const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
1666         pObj->GetMergedItem(XATTR_FILLSTYLE));
1667     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
1668     const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
1669         pObj->GetMergedItem(XATTR_FILLCOLOR));
1670     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x76bf3d), sal_uInt32(rColorItem.GetColorValue()));
1671 
1672     xDocShRef->DoClose();
1673 }
1674 
1675 void SdImportTest::testTdf99030()
1676 {
1677     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf99030.pptx"), PPTX);
1678 
1679     uno::Reference< drawing::XMasterPagesSupplier > xDoc(
1680         xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
1681     uno::Reference< drawing::XDrawPage > xPage(
1682         xDoc->getMasterPages()->getByIndex( 0 ), uno::UNO_QUERY_THROW );
1683     uno::Reference< beans::XPropertySet > xPropSet( xPage, uno::UNO_QUERY );
1684 
1685     sal_Int32 nFillColor(0);
1686     uno::Any aAny = xPropSet->getPropertyValue( "Background" );
1687     if (aAny.hasValue())
1688     {
1689         uno::Reference< beans::XPropertySet > xBackgroundPropSet;
1690         aAny >>= xBackgroundPropSet;
1691         xBackgroundPropSet->getPropertyValue( "FillColor" ) >>= nFillColor;
1692     }
1693     CPPUNIT_ASSERT_EQUAL( sal_Int32(0x676A55), nFillColor );
1694 
1695     xDocShRef->DoClose();
1696 }
1697 
1698 void SdImportTest::testTdf49561()
1699 {
1700     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/tdf49561.ppt"), PPT);
1701 
1702     uno::Reference< drawing::XMasterPagesSupplier > xDoc(
1703         xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
1704     uno::Reference< drawing::XDrawPage > xPage(
1705         xDoc->getMasterPages()->getByIndex( 0 ), uno::UNO_QUERY_THROW );
1706     CPPUNIT_ASSERT_EQUAL( sal_Int32(5), xPage->getCount() );
1707 
1708     uno::Reference< beans::XPropertySet > xShape( getShape( 3, xPage ) );
1709     uno::Reference<text::XTextRange> xParagraph( getParagraphFromShape( 0, xShape ) );
1710     uno::Reference<text::XTextRange> xRun( getRunFromParagraph (0, xParagraph ) );
1711     uno::Reference< beans::XPropertySet > xPropSet(xRun , uno::UNO_QUERY_THROW );
1712 
1713     float fCharHeight = 0;
1714     CPPUNIT_ASSERT(xPropSet->getPropertyValue("CharHeight") >>= fCharHeight);
1715     CPPUNIT_ASSERT_EQUAL(12.f, fCharHeight);
1716 
1717     OUString aCharFontName;
1718     CPPUNIT_ASSERT(xPropSet->getPropertyValue("CharFontName") >>= aCharFontName);
1719     CPPUNIT_ASSERT_EQUAL(OUString("Stencil"), aCharFontName);
1720 
1721     xDocShRef->DoClose();
1722 }
1723 
1724 void SdImportTest::testTdf103473()
1725 {
1726     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf103473.pptx"), PPTX);
1727 
1728     const SdrPage *pPage = GetPage(1, xDocShRef);
1729     SdrTextObj *const pObj = dynamic_cast<SdrTextObj *const>(pPage->GetObj(0));
1730     CPPUNIT_ASSERT(pObj);
1731     ::tools::Rectangle aRect = pObj->GetGeoRect();
1732     CPPUNIT_ASSERT_EQUAL(3629L, aRect.Left());
1733     CPPUNIT_ASSERT_EQUAL(4431L, aRect.Top());
1734     CPPUNIT_ASSERT_EQUAL(8353L, aRect.Right());
1735     CPPUNIT_ASSERT_EQUAL(9155L, aRect.Bottom());
1736 
1737     xDocShRef->DoClose();
1738 }
1739 
1740 void SdImportTest::testAoo124143()
1741 {
1742     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odg/ooo124143-1.odg"), ODG);
1743 
1744     uno::Reference<beans::XPropertySet> const xImage(getShapeFromPage(0, 0, xDocShRef));
1745     uno::Reference<drawing::XGluePointsSupplier> const xGPS(xImage, uno::UNO_QUERY);
1746     uno::Reference<container::XIdentifierAccess> const xGluePoints(xGPS->getGluePoints(), uno::UNO_QUERY);
1747 
1748     uno::Sequence<sal_Int32> const ids(xGluePoints->getIdentifiers());
1749     CPPUNIT_ASSERT_EQUAL(sal_Int32(6), ids.getLength());
1750     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), ids[0]);
1751     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), ids[1]);
1752     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), ids[2]);
1753     CPPUNIT_ASSERT_EQUAL(sal_Int32(3), ids[3]);
1754     CPPUNIT_ASSERT_EQUAL(sal_Int32(4), ids[4]);
1755     CPPUNIT_ASSERT_EQUAL(sal_Int32(5), ids[5]);
1756 
1757     // interesting ones are custom 4, 5
1758     drawing::GluePoint2 glue4;
1759     xGluePoints->getByIdentifier(4) >>= glue4;
1760     CPPUNIT_ASSERT_EQUAL(sal_Int32( 2470), glue4.Position.X);
1761     CPPUNIT_ASSERT_EQUAL(sal_Int32(-1810), glue4.Position.Y);
1762 
1763     drawing::GluePoint2 glue5;
1764     xGluePoints->getByIdentifier(5) >>= glue5;
1765     CPPUNIT_ASSERT_EQUAL(sal_Int32(-2975), glue5.Position.X);
1766     CPPUNIT_ASSERT_EQUAL(sal_Int32(-2165), glue5.Position.Y);
1767 
1768     // now check connectors
1769     uno::Reference<beans::XPropertySet> const xEllipse(getShapeFromPage(1, 0, xDocShRef));
1770     uno::Reference<beans::XPropertySet> const xConn1(getShapeFromPage(2, 0, xDocShRef));
1771     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xConn1->getPropertyValue("StartGluePointIndex").get<sal_Int32>());
1772     CPPUNIT_ASSERT_EQUAL(xEllipse, xConn1->getPropertyValue("StartShape").get<uno::Reference<beans::XPropertySet>>());
1773     CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xConn1->getPropertyValue("EndGluePointIndex").get<sal_Int32>());
1774     CPPUNIT_ASSERT_EQUAL(xImage, xConn1->getPropertyValue("EndShape").get<uno::Reference<beans::XPropertySet>>());
1775     uno::Reference<beans::XPropertySet> const xConn2(getShapeFromPage(3, 0, xDocShRef));
1776     CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xConn2->getPropertyValue("StartGluePointIndex").get<sal_Int32>());
1777     CPPUNIT_ASSERT_EQUAL(xEllipse, xConn2->getPropertyValue("StartShape").get<uno::Reference<beans::XPropertySet>>());
1778     CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xConn2->getPropertyValue("EndGluePointIndex").get<sal_Int32>());
1779     CPPUNIT_ASSERT_EQUAL(xImage, xConn2->getPropertyValue("EndShape").get<uno::Reference<beans::XPropertySet>>());
1780 
1781     xDocShRef->DoClose();
1782 }
1783 
1784 void SdImportTest::testTdf103567()
1785 {
1786     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odp/tdf103567.odp"), ODP);
1787     for (int i = 0; i < 4; ++i)
1788     {
1789         uno::Reference<beans::XPropertySet> const xShape(getShapeFromPage(i, 0, xDocShRef));
1790         uno::Reference<document::XEventsSupplier> const xEventsSupplier(xShape, uno::UNO_QUERY);
1791         uno::Reference<container::XNameAccess> const xEvents(xEventsSupplier->getEvents());
1792         OString const msg("shape " + OString::number(i) + ": ");
1793 
1794         CPPUNIT_ASSERT(xEvents->hasByName("OnClick"));
1795         uno::Sequence<beans::PropertyValue> props;
1796         xEvents->getByName("OnClick") >>= props;
1797         comphelper::SequenceAsHashMap const map(props);
1798         {
1799             auto iter(map.find("EventType"));
1800             CPPUNIT_ASSERT_MESSAGE(OString(msg + "no EventType").getStr(), iter != map.end());
1801             CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.getStr(), OUString("Presentation"), iter->second.get<OUString>());
1802         }
1803         {
1804             auto iter(map.find("ClickAction"));
1805             CPPUNIT_ASSERT_MESSAGE(OString(msg + "no ClickAction").getStr(), iter != map.end());
1806             if (i % 2 == 0)
1807             {
1808                 CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.getStr(), css::presentation::ClickAction_DOCUMENT, iter->second.get<css::presentation::ClickAction>());
1809             }
1810             else
1811             {
1812                 CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.getStr(), css::presentation::ClickAction_NEXTPAGE, iter->second.get<css::presentation::ClickAction>());
1813             }
1814         }
1815         if (i % 2 == 0)
1816         {
1817             auto iter(map.find("Bookmark"));
1818             CPPUNIT_ASSERT_MESSAGE(OString(msg + "no Bookmark").getStr(), iter != map.end());
1819             CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.getStr(), OUString("http://example.com/"), iter->second.get<OUString>());
1820         }
1821     }
1822 
1823     xDocShRef->DoClose();
1824 }
1825 
1826 void SdImportTest::testTdf103792()
1827 {
1828     // Title text shape on the actual slide contained no text neither a placeholder text.
1829     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf103792.pptx"), PPTX);
1830 
1831     const SdrPage *pPage = GetPage(1, xDocShRef);
1832     CPPUNIT_ASSERT_MESSAGE("No page found", pPage != nullptr);
1833     SdrObject *pObj = pPage->GetObj(0);
1834     CPPUNIT_ASSERT_MESSAGE("Wrong object", pObj != nullptr);
1835     SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>(pObj);
1836     CPPUNIT_ASSERT_MESSAGE("Not a text object", pTxtObj != nullptr);
1837 
1838     const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
1839     CPPUNIT_ASSERT_EQUAL(OUString("Click to add Title"), aEdit.GetText(0));
1840 
1841     xDocShRef->DoClose();
1842 }
1843 
1844 void SdImportTest::testTdf103876()
1845 {
1846     // Title text shape's placeholder text did not inherit the corresponding text properties
1847     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf103876.pptx"), PPTX);
1848     uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
1849 
1850     // Check paragraph alignment
1851     sal_Int16 nParaAdjust = 0;
1852     xShape->getPropertyValue( "ParaAdjust" ) >>= nParaAdjust;
1853     CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER, static_cast<style::ParagraphAdjust>(nParaAdjust));
1854 
1855     // Check character color
1856     sal_Int32 nCharColor;
1857     xShape->getPropertyValue( "CharColor" ) >>= nCharColor;
1858     CPPUNIT_ASSERT_EQUAL( sal_Int32(0xFF0000), nCharColor );
1859 
1860     xDocShRef->DoClose();
1861 }
1862 
1863 void SdImportTest::testTdf79007()
1864 {
1865     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf79007.pptx"), PPTX);
1866 
1867     uno::Reference<beans::XPropertySet> xShape1(getShapeFromPage(0, 0, xDocShRef));
1868     CPPUNIT_ASSERT_MESSAGE("Not a shape", xShape1.is());
1869 
1870     // Check we map mso washout to our watermark
1871     drawing::ColorMode aColorMode1;
1872     xShape1->getPropertyValue("GraphicColorMode") >>= aColorMode1;
1873     CPPUNIT_ASSERT_EQUAL(drawing::ColorMode_WATERMARK, aColorMode1);
1874 
1875     sal_Int16 nContrast1;
1876     xShape1->getPropertyValue("AdjustContrast") >>= nContrast1;
1877     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nContrast1);
1878 
1879     sal_Int16 nLuminance1;
1880     xShape1->getPropertyValue("AdjustLuminance") >>= nLuminance1;
1881     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nLuminance1);
1882 
1883     uno::Reference<beans::XPropertySet> xShape2(getShapeFromPage(1, 0, xDocShRef));
1884     CPPUNIT_ASSERT_MESSAGE("Not a shape", xShape2.is());
1885 
1886     // Check we map mso grayscale to our grayscale
1887     drawing::ColorMode aColorMode2;
1888     xShape2->getPropertyValue("GraphicColorMode") >>= aColorMode2;
1889     CPPUNIT_ASSERT_EQUAL(drawing::ColorMode_GREYS, aColorMode2);
1890 
1891     sal_Int16 nContrast2;
1892     xShape2->getPropertyValue("AdjustContrast") >>= nContrast2;
1893     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nContrast2);
1894 
1895     sal_Int16 nLuminance2;
1896     xShape2->getPropertyValue("AdjustLuminance") >>= nLuminance2;
1897     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nLuminance2);
1898 
1899     uno::Reference<beans::XPropertySet> xShape3(getShapeFromPage(2, 0, xDocShRef));
1900     CPPUNIT_ASSERT_MESSAGE("Not a shape", xShape3.is());
1901 
1902     // Check we map mso black/white to our black/white
1903     drawing::ColorMode aColorMode3;
1904     xShape3->getPropertyValue("GraphicColorMode") >>= aColorMode3;
1905     CPPUNIT_ASSERT_EQUAL(drawing::ColorMode_MONO, aColorMode3);
1906 
1907     sal_Int16 nContrast3;
1908     xShape3->getPropertyValue("AdjustContrast") >>= nContrast3;
1909     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nContrast3);
1910 
1911     sal_Int16 nLuminance3;
1912     xShape3->getPropertyValue("AdjustLuminance") >>= nLuminance3;
1913     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nLuminance3);
1914 
1915     xDocShRef->DoClose();
1916 }
1917 
1918 void SdImportTest::testTdf129686()
1919 {
1920     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf129686.pptx"), PPTX);
1921     uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
1922 
1923     // Get first paragraph of the text
1924     uno::Reference<text::XTextRange> const xParagraph( getParagraphFromShape( 0, xShape ) );
1925 
1926     // Get first run of the paragraph
1927     uno::Reference<text::XTextRange> xRun( getRunFromParagraph (0, xParagraph ) );
1928     uno::Reference< beans::XPropertySet > xPropSet( xRun, uno::UNO_QUERY_THROW );
1929     sal_Int16 nTransparency = 0;
1930     xPropSet->getPropertyValue("CharTransparence") >>= nTransparency;
1931 
1932     // 100 = no transparency
1933     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(100), nTransparency);
1934 
1935     xDocShRef->DoClose();
1936 }
1937 
1938 void SdImportTest::testTdf104015()
1939 {
1940     // Shape fill, line and effect properties were not inherited from master slide shape
1941     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf104015.pptx"), PPTX);
1942 
1943     const SdrPage *pPage = GetPage( 1, xDocShRef );
1944     CPPUNIT_ASSERT_MESSAGE("No page found", pPage != nullptr);
1945     SdrObject *const pObj = pPage->GetObj(0);
1946     CPPUNIT_ASSERT_MESSAGE("Wrong object", pObj != nullptr);
1947     // Should have a red fill color
1948     {
1949         const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
1950                 pObj->GetMergedItem(XATTR_FILLSTYLE));
1951         CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
1952         const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
1953                 pObj->GetMergedItem(XATTR_FILLCOLOR));
1954         CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xFF0000), sal_uInt32(rColorItem.GetColorValue()));
1955     }
1956     // Should have a blue line
1957     {
1958         const XLineStyleItem& rStyleItem = dynamic_cast<const XLineStyleItem&>(
1959                 pObj->GetMergedItem(XATTR_LINESTYLE));
1960         CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_SOLID, rStyleItem.GetValue());
1961 
1962         const XLineColorItem& rColorItem = dynamic_cast<const XLineColorItem&>(
1963                 pObj->GetMergedItem(XATTR_LINECOLOR));
1964         CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x0000FF), sal_uInt32(rColorItem.GetColorValue()));
1965     }
1966     // Should have some shadow
1967     {
1968         const SdrOnOffItem& rShadowItem = dynamic_cast<const SdrOnOffItem&>(
1969                 pObj->GetMergedItem(SDRATTR_SHADOW));
1970         CPPUNIT_ASSERT(rShadowItem.GetValue());
1971     }
1972 
1973     xDocShRef->DoClose();
1974 }
1975 
1976 void SdImportTest::testTdf104201()
1977 {
1978     // Group shape properties did not overwrite the child shapes' fill
1979     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf104201.pptx"), PPTX);
1980 
1981     const SdrPage *pPage = GetPage(1, xDocShRef);
1982     CPPUNIT_ASSERT_MESSAGE("No page found", pPage != nullptr);
1983 
1984     // First shape has red fill, but this should be overwritten by green group fill
1985     {
1986         SdrObject *const pObj = pPage->GetObj(0);
1987         CPPUNIT_ASSERT_MESSAGE("Wrong object", pObj != nullptr);
1988         const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
1989             pObj->GetMergedItem(XATTR_FILLSTYLE));
1990         CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
1991         const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
1992             pObj->GetMergedItem(XATTR_FILLCOLOR));
1993         CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x00FF00), sal_uInt32(rColorItem.GetColorValue()));
1994     }
1995     // Second shape has blue fill, but this should be overwritten by green group fill
1996     {
1997         SdrObject *const pObj = pPage->GetObj(0);
1998         CPPUNIT_ASSERT_MESSAGE("Wrong object", pObj != nullptr);
1999         const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
2000             pObj->GetMergedItem(XATTR_FILLSTYLE));
2001         CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
2002         const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
2003             pObj->GetMergedItem(XATTR_FILLCOLOR));
2004         CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x00FF00), sal_uInt32(rColorItem.GetColorValue()));
2005     }
2006 
2007     xDocShRef->DoClose();
2008 }
2009 
2010 void SdImportTest::testTdf103477()
2011 {
2012     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf103477.pptx"), PPTX);
2013 
2014     const SdrPage *pPage = GetPage( 1, xDocShRef );
2015 
2016     SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pPage->GetObj(6) );
2017     CPPUNIT_ASSERT_MESSAGE( "no text object", pTxtObj != nullptr );
2018 
2019     const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
2020     const SvxNumBulletItem *pNumFmt = aEdit.GetParaAttribs(0).GetItem(EE_PARA_NUMBULLET);
2021     CPPUNIT_ASSERT(pNumFmt);
2022     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bullet's color is wrong!", Color(0x000000), pNumFmt->GetNumRule()->GetLevel(1).GetBulletColor());
2023 
2024     xDocShRef->DoClose();
2025 }
2026 
2027 void SdImportTest::testTdf105150()
2028 {
2029     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf105150.pptx"), PPTX);
2030     const SdrPage* pPage = GetPage(1, xDocShRef);
2031     const SdrObject* pObj = pPage->GetObj(1);
2032     auto& rFillStyleItem = dynamic_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE));
2033     // This was drawing::FillStyle_NONE, <p:sp useBgFill="1"> was ignored when
2034     // the slide didn't have an explicit background fill.
2035     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rFillStyleItem.GetValue());
2036     xDocShRef->DoClose();
2037 }
2038 
2039 void SdImportTest::testTdf123684()
2040 {
2041     sd::DrawDocShellRef xDocShRef
2042         = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf123684.pptx"), PPTX);
2043     const SdrPage* pPage = GetPage(1, xDocShRef);
2044     const SdrObject* pObj = pPage->GetObj(0);
2045     auto& rFillStyleItem
2046         = dynamic_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE));
2047     // Without the accompanying fix in place, this test would have failed with 'Expected: 0; Actual:
2048     // 1', i.e. the shape's fill was FillStyle_SOLID, making the text of the shape unreadable.
2049     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, rFillStyleItem.GetValue());
2050     xDocShRef->DoClose();
2051 }
2052 
2053 void SdImportTest::testTdf105150PPT()
2054 {
2055     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/ppt/tdf105150.ppt"), PPT);
2056     const SdrPage* pPage = GetPage(1, xDocShRef);
2057     const SdrObject* pObj = pPage->GetObj(1);
2058     // This was drawing::FillStyle_NONE, the shape's mso_fillBackground was
2059     // ignored when the slide didn't have an explicit background fill.
2060     auto& rFillStyleItem = dynamic_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE));
2061     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rFillStyleItem.GetValue());
2062     xDocShRef->DoClose();
2063 }
2064 
2065 void SdImportTest::testTdf104445()
2066 {
2067     // Extra bullets were added to the first shape
2068     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf104445.pptx"), PPTX);
2069 
2070     // First shape should not have bullet
2071     {
2072         uno::Reference< beans::XPropertySet > xShape(getShapeFromPage(0, 0, xDocShRef));
2073         uno::Reference< text::XText > xText = uno::Reference< text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
2074         CPPUNIT_ASSERT_MESSAGE("Not a text shape", xText.is());
2075         uno::Reference< beans::XPropertySet > xPropSet(xText, uno::UNO_QUERY_THROW);
2076 
2077         uno::Reference< container::XIndexAccess > xNumRule;
2078         xPropSet->getPropertyValue("NumberingRules") >>= xNumRule;
2079         uno::Sequence<beans::PropertyValue> aBulletProps;
2080         xNumRule->getByIndex(0) >>= aBulletProps;
2081 
2082         for (beans::PropertyValue const & rProp : std::as_const(aBulletProps))
2083         {
2084             if(rProp.Name == "NumberingType")
2085                 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::NumberingType::NUMBER_NONE), rProp.Value.get<sal_Int16>());
2086             if(rProp.Name == "LeftMargin")
2087                 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rProp.Value.get<sal_Int32>());
2088         }
2089     }
2090     // Second shape should have bullet set
2091     {
2092         uno::Reference< beans::XPropertySet > xShape(getShapeFromPage(1, 0, xDocShRef));
2093         uno::Reference< text::XText > xText = uno::Reference< text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
2094         CPPUNIT_ASSERT_MESSAGE("Not a text shape", xText.is());
2095         uno::Reference< beans::XPropertySet > xPropSet(xText, uno::UNO_QUERY_THROW);
2096 
2097         uno::Reference< container::XIndexAccess > xNumRule;
2098         xPropSet->getPropertyValue("NumberingRules") >>= xNumRule;
2099         uno::Sequence<beans::PropertyValue> aBulletProps;
2100         xNumRule->getByIndex(0) >>= aBulletProps;
2101 
2102         for(beans::PropertyValue const & rProp : std::as_const(aBulletProps))
2103         {
2104             if(rProp.Name == "NumberingType")
2105                 CPPUNIT_ASSERT_EQUAL(sal_Int16(style::NumberingType::CHAR_SPECIAL), rProp.Value.get<sal_Int16>());
2106             if(rProp.Name == "LeftMargin")
2107                 CPPUNIT_ASSERT_EQUAL(sal_Int32(635), rProp.Value.get<sal_Int32>());
2108         }
2109     }
2110     xDocShRef->DoClose();
2111 }
2112 
2113 namespace
2114 {
2115 
2116 bool checkPatternValues(std::vector<sal_uInt8>& rExpected, Bitmap& rBitmap)
2117 {
2118     bool bResult = true;
2119 
2120     const Color aFGColor(0xFF0000);
2121     const Color aBGColor(0xFFFFFF);
2122 
2123     Bitmap::ScopedReadAccess pAccess(rBitmap);
2124     for (long y = 0; y < pAccess->Height(); ++y)
2125     {
2126         Scanline pScanline = pAccess->GetScanline( y );
2127         for (long x = 0; x < pAccess->Width(); ++x)
2128         {
2129             Color aColor = pAccess->GetPixelFromData(pScanline, x);
2130             sal_uInt8 aValue = rExpected[y*8+x];
2131 
2132             if (aValue == 1 && aColor != aFGColor)
2133                 bResult = false;
2134             else if (aValue == 0 && aColor != aBGColor)
2135                 bResult = false;
2136         }
2137     }
2138 
2139     return bResult;
2140 }
2141 
2142 } // end anonymous namespace
2143 
2144 bool SdImportTest::checkPattern(sd::DrawDocShellRef const & rDocRef, int nShapeNumber, std::vector<sal_uInt8>& rExpected)
2145 {
2146     uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(nShapeNumber, 0, rDocRef));
2147     CPPUNIT_ASSERT_MESSAGE("Not a shape", xShape.is());
2148 
2149     Bitmap aBitmap;
2150     if (xShape.is())
2151     {
2152         uno::Any aBitmapAny = xShape->getPropertyValue("FillBitmap");
2153         uno::Reference<awt::XBitmap> xBitmap;
2154         if (aBitmapAny >>= xBitmap)
2155         {
2156             uno::Sequence<sal_Int8> aBitmapSequence(xBitmap->getDIB());
2157             SvMemoryStream aBitmapStream(aBitmapSequence.getArray(),
2158                                          aBitmapSequence.getLength(),
2159                                          StreamMode::READ);
2160             ReadDIB(aBitmap, aBitmapStream, true);
2161         }
2162     }
2163     CPPUNIT_ASSERT_EQUAL(8L, aBitmap.GetSizePixel().Width());
2164     CPPUNIT_ASSERT_EQUAL(8L, aBitmap.GetSizePixel().Height());
2165     return checkPatternValues(rExpected, aBitmap);
2166 }
2167 
2168 /* Test checks that importing a PPT file with all supported fill patterns is
2169  * correctly imported as a tiled fill bitmap with the expected pattern.
2170  */
2171 void SdImportTest::testPatternImport()
2172 {
2173     sd::DrawDocShellRef xDocRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/ppt/FillPatterns.ppt"), PPT);
2174 
2175     std::vector<sal_uInt8> aExpectedPattern1 = {
2176         1,0,0,0,0,0,0,0,
2177         0,0,0,0,0,0,0,0,
2178         0,0,0,0,0,0,0,0,
2179         0,0,0,0,0,0,0,0,
2180         0,0,0,0,1,0,0,0,
2181         0,0,0,0,0,0,0,0,
2182         0,0,0,0,0,0,0,0,
2183         0,0,0,0,0,0,0,0,
2184     };
2185     std::vector<sal_uInt8> aExpectedPattern2 = {
2186         1,0,0,0,0,0,0,0,
2187         0,0,0,0,0,0,0,0,
2188         0,0,0,0,1,0,0,0,
2189         0,0,0,0,0,0,0,0,
2190         1,0,0,0,0,0,0,0,
2191         0,0,0,0,0,0,0,0,
2192         0,0,0,0,1,0,0,0,
2193         0,0,0,0,0,0,0,0,
2194     };
2195     std::vector<sal_uInt8> aExpectedPattern3 = {
2196         1,0,0,0,1,0,0,0,
2197         0,0,0,0,0,0,0,0,
2198         0,0,1,0,0,0,1,0,
2199         0,0,0,0,0,0,0,0,
2200         1,0,0,0,1,0,0,0,
2201         0,0,0,0,0,0,0,0,
2202         0,0,1,0,0,0,1,0,
2203         0,0,0,0,0,0,0,0,
2204     };
2205     std::vector<sal_uInt8> aExpectedPattern4 = {
2206         1,0,0,0,1,0,0,0,
2207         0,0,1,0,0,0,1,0,
2208         1,0,0,0,1,0,0,0,
2209         0,0,1,0,0,0,1,0,
2210         1,0,0,0,1,0,0,0,
2211         0,0,1,0,0,0,1,0,
2212         1,0,0,0,1,0,0,0,
2213         0,0,1,0,0,0,1,0,
2214     };
2215     std::vector<sal_uInt8> aExpectedPattern5 = {
2216         1,0,1,0,1,0,1,0,
2217         0,1,0,0,0,1,0,0,
2218         1,0,1,0,1,0,1,0,
2219         0,0,0,1,0,0,0,1,
2220         1,0,1,0,1,0,1,0,
2221         0,1,0,0,0,1,0,0,
2222         1,0,1,0,1,0,1,0,
2223         0,0,0,1,0,0,0,1,
2224     };
2225     std::vector<sal_uInt8> aExpectedPattern6 = {
2226         1,0,1,0,1,0,1,0,
2227         0,1,0,1,0,1,0,1,
2228         1,0,1,0,1,0,1,0,
2229         0,1,0,1,0,0,0,1,
2230         1,0,1,0,1,0,1,0,
2231         0,1,0,1,0,1,0,1,
2232         1,0,1,0,1,0,1,0,
2233         0,0,0,1,0,1,0,1,
2234     };
2235     std::vector<sal_uInt8> aExpectedPattern7 = {
2236         1,0,1,0,1,0,1,0,
2237         0,1,0,1,0,1,0,1,
2238         1,0,1,0,1,0,1,0,
2239         0,1,0,1,0,1,0,1,
2240         1,0,1,0,1,0,1,0,
2241         0,1,0,1,0,1,0,1,
2242         1,0,1,0,1,0,1,0,
2243         0,1,0,1,0,1,0,1,
2244     };
2245     std::vector<sal_uInt8> aExpectedPattern8 = {
2246         1,1,1,0,1,1,1,0,
2247         0,1,0,1,0,1,0,1,
2248         1,0,1,1,1,0,1,1,
2249         0,1,0,1,0,1,0,1,
2250         1,1,1,0,1,1,1,0,
2251         0,1,0,1,0,1,0,1,
2252         1,0,1,1,1,0,1,1,
2253         0,1,0,1,0,1,0,1,
2254     };
2255     std::vector<sal_uInt8> aExpectedPattern9 = {
2256         0,1,1,1,0,1,1,1,
2257         1,1,0,1,1,1,0,1,
2258         0,1,1,1,0,1,1,1,
2259         1,1,0,1,1,1,0,1,
2260         0,1,1,1,0,1,1,1,
2261         1,1,0,1,1,1,0,1,
2262         0,1,1,1,0,1,1,1,
2263         1,1,0,1,1,1,0,1,
2264     };
2265     std::vector<sal_uInt8> aExpectedPattern10 = {
2266         0,1,1,1,0,1,1,1,
2267         1,1,1,1,1,1,1,1,
2268         1,1,0,1,1,1,0,1,
2269         1,1,1,1,1,1,1,1,
2270         0,1,1,1,0,1,1,1,
2271         1,1,1,1,1,1,1,1,
2272         1,1,0,1,1,1,0,1,
2273         1,1,1,1,1,1,1,1,
2274     };
2275     std::vector<sal_uInt8> aExpectedPattern11 = {
2276         1,1,1,0,1,1,1,1,
2277         1,1,1,1,1,1,1,1,
2278         1,1,1,1,1,1,1,0,
2279         1,1,1,1,1,1,1,1,
2280         1,1,1,0,1,1,1,1,
2281         1,1,1,1,1,1,1,1,
2282         1,1,1,1,1,1,1,0,
2283         1,1,1,1,1,1,1,1,
2284     };
2285     std::vector<sal_uInt8> aExpectedPattern12 = {
2286         1,1,1,1,1,1,1,1,
2287         1,1,1,1,1,1,1,1,
2288         1,1,1,1,1,1,1,1,
2289         1,1,1,1,0,1,1,1,
2290         1,1,1,1,1,1,1,1,
2291         1,1,1,1,1,1,1,1,
2292         1,1,1,1,1,1,1,1,
2293         0,1,1,1,1,1,1,1,
2294     };
2295     std::vector<sal_uInt8> aExpectedPatternLine1 = {
2296         1,0,0,0,1,0,0,0,
2297         0,1,0,0,0,1,0,0,
2298         0,0,1,0,0,0,1,0,
2299         0,0,0,1,0,0,0,1,
2300         1,0,0,0,1,0,0,0,
2301         0,1,0,0,0,1,0,0,
2302         0,0,1,0,0,0,1,0,
2303         0,0,0,1,0,0,0,1,
2304     };
2305     std::vector<sal_uInt8> aExpectedPatternLine2 = {
2306         0,0,0,1,0,0,0,1,
2307         0,0,1,0,0,0,1,0,
2308         0,1,0,0,0,1,0,0,
2309         1,0,0,0,1,0,0,0,
2310         0,0,0,1,0,0,0,1,
2311         0,0,1,0,0,0,1,0,
2312         0,1,0,0,0,1,0,0,
2313         1,0,0,0,1,0,0,0,
2314     };
2315     std::vector<sal_uInt8> aExpectedPatternLine3 = {
2316         1,1,0,0,1,1,0,0,
2317         0,1,1,0,0,1,1,0,
2318         0,0,1,1,0,0,1,1,
2319         1,0,0,1,1,0,0,1,
2320         1,1,0,0,1,1,0,0,
2321         0,1,1,0,0,1,1,0,
2322         0,0,1,1,0,0,1,1,
2323         1,0,0,1,1,0,0,1,
2324     };
2325     std::vector<sal_uInt8> aExpectedPatternLine4 = {
2326         0,0,1,1,0,0,1,1,
2327         0,1,1,0,0,1,1,0,
2328         1,1,0,0,1,1,0,0,
2329         1,0,0,1,1,0,0,1,
2330         0,0,1,1,0,0,1,1,
2331         0,1,1,0,0,1,1,0,
2332         1,1,0,0,1,1,0,0,
2333         1,0,0,1,1,0,0,1,
2334     };
2335     std::vector<sal_uInt8> aExpectedPatternLine5 = {
2336         1,1,0,0,0,0,0,1,
2337         1,1,1,0,0,0,0,0,
2338         0,1,1,1,0,0,0,0,
2339         0,0,1,1,1,0,0,0,
2340         0,0,0,1,1,1,0,0,
2341         0,0,0,0,1,1,1,0,
2342         0,0,0,0,0,1,1,1,
2343         1,0,0,0,0,0,1,1,
2344     };
2345     std::vector<sal_uInt8> aExpectedPatternLine6 = {
2346         1,0,0,0,0,0,1,1,
2347         0,0,0,0,0,1,1,1,
2348         0,0,0,0,1,1,1,0,
2349         0,0,0,1,1,1,0,0,
2350         0,0,1,1,1,0,0,0,
2351         0,1,1,1,0,0,0,0,
2352         1,1,1,0,0,0,0,0,
2353         1,1,0,0,0,0,0,1,
2354     };
2355     std::vector<sal_uInt8> aExpectedPatternLine7 = {
2356         1,0,0,0,1,0,0,0,
2357         1,0,0,0,1,0,0,0,
2358         1,0,0,0,1,0,0,0,
2359         1,0,0,0,1,0,0,0,
2360         1,0,0,0,1,0,0,0,
2361         1,0,0,0,1,0,0,0,
2362         1,0,0,0,1,0,0,0,
2363         1,0,0,0,1,0,0,0,
2364     };
2365     std::vector<sal_uInt8> aExpectedPatternLine8 = {
2366         1,1,1,1,1,1,1,1,
2367         0,0,0,0,0,0,0,0,
2368         0,0,0,0,0,0,0,0,
2369         0,0,0,0,0,0,0,0,
2370         1,1,1,1,1,1,1,1,
2371         0,0,0,0,0,0,0,0,
2372         0,0,0,0,0,0,0,0,
2373         0,0,0,0,0,0,0,0,
2374     };
2375     std::vector<sal_uInt8> aExpectedPatternLine9 = {
2376         0,1,0,1,0,1,0,1,
2377         0,1,0,1,0,1,0,1,
2378         0,1,0,1,0,1,0,1,
2379         0,1,0,1,0,1,0,1,
2380         0,1,0,1,0,1,0,1,
2381         0,1,0,1,0,1,0,1,
2382         0,1,0,1,0,1,0,1,
2383         0,1,0,1,0,1,0,1,
2384     };
2385     std::vector<sal_uInt8> aExpectedPatternLine10 = {
2386         1,1,1,1,1,1,1,1,
2387         0,0,0,0,0,0,0,0,
2388         1,1,1,1,1,1,1,1,
2389         0,0,0,0,0,0,0,0,
2390         1,1,1,1,1,1,1,1,
2391         0,0,0,0,0,0,0,0,
2392         1,1,1,1,1,1,1,1,
2393         0,0,0,0,0,0,0,0,
2394     };
2395     std::vector<sal_uInt8> aExpectedPatternLine11 = {
2396         1,1,0,0,1,1,0,0,
2397         1,1,0,0,1,1,0,0,
2398         1,1,0,0,1,1,0,0,
2399         1,1,0,0,1,1,0,0,
2400         1,1,0,0,1,1,0,0,
2401         1,1,0,0,1,1,0,0,
2402         1,1,0,0,1,1,0,0,
2403         1,1,0,0,1,1,0,0,
2404     };
2405     std::vector<sal_uInt8> aExpectedPatternLine12 = {
2406         1,1,1,1,1,1,1,1,
2407         1,1,1,1,1,1,1,1,
2408         0,0,0,0,0,0,0,0,
2409         0,0,0,0,0,0,0,0,
2410         1,1,1,1,1,1,1,1,
2411         1,1,1,1,1,1,1,1,
2412         0,0,0,0,0,0,0,0,
2413         0,0,0,0,0,0,0,0,
2414     };
2415 
2416     CPPUNIT_ASSERT_MESSAGE("Pattern1 - 5%" ,  checkPattern(xDocRef, 0,  aExpectedPattern1));
2417     CPPUNIT_ASSERT_MESSAGE("Pattern2 - 10%",  checkPattern(xDocRef, 1,  aExpectedPattern2));
2418     CPPUNIT_ASSERT_MESSAGE("Pattern3 - 20%",  checkPattern(xDocRef, 2,  aExpectedPattern3));
2419     CPPUNIT_ASSERT_MESSAGE("Pattern4 - 25%",  checkPattern(xDocRef, 3,  aExpectedPattern4));
2420     CPPUNIT_ASSERT_MESSAGE("Pattern5 - 30%",  checkPattern(xDocRef, 4,  aExpectedPattern5));
2421     CPPUNIT_ASSERT_MESSAGE("Pattern6 - 40%",  checkPattern(xDocRef, 5,  aExpectedPattern6));
2422     CPPUNIT_ASSERT_MESSAGE("Pattern7 - 50%",  checkPattern(xDocRef, 6,  aExpectedPattern7));
2423     CPPUNIT_ASSERT_MESSAGE("Pattern8 - 60%",  checkPattern(xDocRef, 7,  aExpectedPattern8));
2424     CPPUNIT_ASSERT_MESSAGE("Pattern9 - 70%",  checkPattern(xDocRef, 8,  aExpectedPattern9));
2425     CPPUNIT_ASSERT_MESSAGE("Pattern10 - 75%", checkPattern(xDocRef, 9,  aExpectedPattern10));
2426     CPPUNIT_ASSERT_MESSAGE("Pattern11 - 80%", checkPattern(xDocRef, 10, aExpectedPattern11));
2427     CPPUNIT_ASSERT_MESSAGE("Pattern12 - 90%", checkPattern(xDocRef, 11, aExpectedPattern12));
2428 
2429     CPPUNIT_ASSERT_MESSAGE("Pattern13 - Light downward diagonal", checkPattern(xDocRef, 12, aExpectedPatternLine1));
2430     CPPUNIT_ASSERT_MESSAGE("Pattern14 - Light upward diagonal",   checkPattern(xDocRef, 13, aExpectedPatternLine2));
2431     CPPUNIT_ASSERT_MESSAGE("Pattern15 - Dark downward diagonal",  checkPattern(xDocRef, 14, aExpectedPatternLine3));
2432     CPPUNIT_ASSERT_MESSAGE("Pattern16 - Dark upward diagonal",    checkPattern(xDocRef, 15, aExpectedPatternLine4));
2433     CPPUNIT_ASSERT_MESSAGE("Pattern17 - Wide downward diagonal",  checkPattern(xDocRef, 16, aExpectedPatternLine5));
2434     CPPUNIT_ASSERT_MESSAGE("Pattern18 - Wide upward diagonal",    checkPattern(xDocRef, 17, aExpectedPatternLine6));
2435 
2436     CPPUNIT_ASSERT_MESSAGE("Pattern19 - Light vertical",    checkPattern(xDocRef, 18, aExpectedPatternLine7));
2437     CPPUNIT_ASSERT_MESSAGE("Pattern20 - Light horizontal",  checkPattern(xDocRef, 19, aExpectedPatternLine8));
2438     CPPUNIT_ASSERT_MESSAGE("Pattern21 - Narrow vertical",   checkPattern(xDocRef, 20, aExpectedPatternLine9));
2439     CPPUNIT_ASSERT_MESSAGE("Pattern22 - Narrow horizontal", checkPattern(xDocRef, 21, aExpectedPatternLine10));
2440     CPPUNIT_ASSERT_MESSAGE("Pattern23 - Dark vertical",     checkPattern(xDocRef, 22, aExpectedPatternLine11));
2441     CPPUNIT_ASSERT_MESSAGE("Pattern24 - Dark horizontal",   checkPattern(xDocRef, 23, aExpectedPatternLine12));
2442 
2443     // TODO: other patterns in the test document
2444 
2445     xDocRef->DoClose();
2446 }
2447 
2448 void SdImportTest::testTdf100926()
2449 {
2450     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf100926.pptx"), PPTX);
2451     const SdrPage* pPage = GetPage(1, xDocShRef);
2452     CPPUNIT_ASSERT(pPage != nullptr);
2453 
2454     sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
2455     CPPUNIT_ASSERT(pTableObj != nullptr);
2456     uno::Reference< table::XCellRange > xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
2457 
2458     sal_Int32 nRotation = 0;
2459     uno::Reference< beans::XPropertySet > xCell(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
2460     xCell->getPropertyValue("RotateAngle") >>= nRotation;
2461     CPPUNIT_ASSERT_EQUAL(sal_Int32(27000), nRotation);
2462 
2463     xCell.set(xTable->getCellByPosition(1, 0), uno::UNO_QUERY_THROW);
2464     xCell->getPropertyValue("RotateAngle") >>= nRotation;
2465     CPPUNIT_ASSERT_EQUAL(sal_Int32(9000), nRotation);
2466 
2467     xCell.set(xTable->getCellByPosition(2, 0), uno::UNO_QUERY_THROW);
2468     xCell->getPropertyValue("RotateAngle") >>= nRotation;
2469     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nRotation);
2470 
2471     xDocShRef->DoClose();
2472 }
2473 
2474 void SdImportTest::testTdf89064()
2475 {
2476     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf89064.pptx"), PPTX);
2477     uno::Reference< presentation::XPresentationPage > xPage (getPage(0, xDocShRef), uno::UNO_QUERY_THROW);
2478     uno::Reference< drawing::XDrawPage > xNotesPage (xPage->getNotesPage(), uno::UNO_SET_THROW);
2479     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xNotesPage->getCount());
2480 
2481     xDocShRef->DoClose();
2482 }
2483 
2484 void SdImportTest::testTdf108925()
2485 {
2486     // Test document contains bulleting with too small bullet size (1%) which breaks the lower constraint
2487     // So it should be converted to the lowest allowed value (25%).
2488     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/odp/tdf108925.odp"), ODP);
2489     const SdrPage *pPage = GetPage(1, xDocShRef);
2490     SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>(pPage->GetObj(0));
2491     CPPUNIT_ASSERT_MESSAGE("No text object", pTxtObj != nullptr);
2492     const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
2493 
2494     const SvxNumBulletItem *pNumFmt = aEdit.GetParaAttribs(0).GetItem(EE_PARA_NUMBULLET);
2495     CPPUNIT_ASSERT(pNumFmt);
2496     CPPUNIT_ASSERT_EQUAL(sal_uInt16(25), pNumFmt->GetNumRule()->GetLevel(0).GetBulletRelSize());
2497 
2498     xDocShRef->DoClose();
2499 }
2500 
2501 void SdImportTest::testTdf109067()
2502 {
2503     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf109067.pptx"), PPTX);
2504     uno::Reference< beans::XPropertySet > xShape(getShapeFromPage(0, 0, xDocShRef), uno::UNO_SET_THROW);
2505     awt::Gradient gradient;
2506     CPPUNIT_ASSERT(xShape->getPropertyValue("FillGradient") >>= gradient);
2507     CPPUNIT_ASSERT_EQUAL(sal_Int16(450), gradient.Angle);
2508 
2509     xDocShRef->DoClose();
2510 }
2511 
2512 void SdImportTest::testTdf109187()
2513 {
2514     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf109187.pptx"), PPTX);
2515     uno::Reference< beans::XPropertySet > xArrow1(getShapeFromPage(0, 0, xDocShRef), uno::UNO_SET_THROW);
2516     awt::Gradient aGradient1;
2517     CPPUNIT_ASSERT(xArrow1->getPropertyValue("FillGradient") >>= aGradient1);
2518     CPPUNIT_ASSERT_EQUAL(sal_Int16(2250), aGradient1.Angle);
2519     uno::Reference< beans::XPropertySet > xArrow2(getShapeFromPage(1, 0, xDocShRef), uno::UNO_SET_THROW);
2520     awt::Gradient aGradient2;
2521     CPPUNIT_ASSERT(xArrow2->getPropertyValue("FillGradient") >>= aGradient2);
2522     CPPUNIT_ASSERT_EQUAL(sal_Int16(1350), aGradient2.Angle);
2523 
2524     xDocShRef->DoClose();
2525 }
2526 
2527 void SdImportTest::testTdf108926()
2528 {
2529     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf108926.ppt"), PPT);
2530     uno::Reference< presentation::XPresentationPage > xPage (getPage(0, xDocShRef), uno::UNO_QUERY_THROW);
2531     uno::Reference< drawing::XDrawPage > xNotesPage (xPage->getNotesPage(), uno::UNO_SET_THROW);
2532     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xNotesPage->getCount());
2533 
2534     // Second object should be imported as an empty presentation shape
2535     uno::Reference< beans::XPropertySet > xPresentationShape(xNotesPage->getByIndex(1), uno::UNO_QUERY);
2536     CPPUNIT_ASSERT(xPresentationShape.is());
2537     bool bIsEmptyPresObject = false;
2538     xPresentationShape->getPropertyValue( "IsEmptyPresentationObject" )  >>= bIsEmptyPresObject;
2539     CPPUNIT_ASSERT(bIsEmptyPresObject);
2540 
2541     xDocShRef->DoClose();
2542 }
2543 
2544 void SdImportTest::testTdf100065()
2545 {
2546     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf100065.pptx"), PPTX);
2547 
2548     uno::Reference< container::XIndexAccess > xGroupShape1(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY_THROW);
2549     uno::Reference< beans::XPropertySet > xShape1(xGroupShape1->getByIndex(1), uno::UNO_QUERY_THROW);
2550     sal_Int32 nAngle1;
2551     CPPUNIT_ASSERT(xShape1->getPropertyValue("RotateAngle") >>= nAngle1);
2552     CPPUNIT_ASSERT_EQUAL(sal_Int32(2000), nAngle1);
2553 
2554     uno::Reference< container::XIndexAccess > xGroupShape2(getShapeFromPage(1, 0, xDocShRef), uno::UNO_QUERY_THROW);
2555     uno::Reference< beans::XPropertySet > xShape2(xGroupShape2->getByIndex(0), uno::UNO_QUERY_THROW);
2556     sal_Int32 nAngle2;
2557     CPPUNIT_ASSERT(xShape2->getPropertyValue("RotateAngle") >>= nAngle2);
2558     CPPUNIT_ASSERT_EQUAL(sal_Int32(18000), nAngle2);
2559 
2560     xDocShRef->DoClose();
2561 }
2562 
2563 void SdImportTest::testTdf90626()
2564 {
2565     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf90626.pptx"), PPTX);
2566     const SdrPage *pPage = GetPage(1, xDocShRef);
2567     SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>(pPage->GetObj(1));
2568     CPPUNIT_ASSERT_MESSAGE("No text object", pTxtObj != nullptr);
2569     const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
2570     for(int i = 0; i < 4; i++)
2571     {
2572         const SvxNumBulletItem *pNumFmt = aEdit.GetParaAttribs(i).GetItem(EE_PARA_NUMBULLET);
2573         CPPUNIT_ASSERT(pNumFmt);
2574         CPPUNIT_ASSERT_DOUBLES_EQUAL(long(371), pNumFmt->GetNumRule()->GetLevel(0).GetGraphicSize().getHeight(), long(1));
2575     }
2576 
2577     xDocShRef->DoClose();
2578 }
2579 
2580 void SdImportTest::testTdf114488()
2581 {
2582     // This doc has two images - one WMF and the other PNG (fallback image).
2583     // When loading this doc, the WMF image should be preferred over the PNG image.
2584     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/odg/tdf114488.fodg"), FODG);
2585     uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, xDocShRef), uno::UNO_SET_THROW);
2586     uno::Reference<graphic::XGraphic> xGraphic;
2587     xShape->getPropertyValue("Graphic") >>= xGraphic;
2588     CPPUNIT_ASSERT(xGraphic.is());
2589     OUString sMimeType(comphelper::GraphicMimeTypeHelper::GetMimeTypeForXGraphic(xGraphic));
2590     CPPUNIT_ASSERT_EQUAL(OUString("image/x-wmf"), sMimeType);
2591 
2592     xDocShRef->DoClose();
2593 }
2594 
2595 void SdImportTest::testTdf114913()
2596 {
2597     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf114913.pptx"), PPTX);
2598     SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>(GetPage(1, xDocShRef)->GetObj(1));
2599     CPPUNIT_ASSERT_MESSAGE("No text object", pTxtObj != nullptr);
2600     const SvxNumBulletItem *pItem = pTxtObj->GetOutlinerParaObject()->GetTextObject().GetParaAttribs(0).GetItem(EE_PARA_NUMBULLET);
2601     CPPUNIT_ASSERT(pItem);
2602     CPPUNIT_ASSERT_EQUAL(long(691), pItem->GetNumRule()->GetLevel(0).GetGraphicSize().getHeight());
2603 
2604     xDocShRef->DoClose();
2605 }
2606 
2607 void SdImportTest::testTdf114821()
2608 {
2609     css::uno::Any aAny;
2610     sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc( "/sd/qa/unit/data/pptx/tdf114821.pptx" ), PPTX );
2611 
2612     uno::Reference< beans::XPropertySet > xPropSet( getShapeFromPage( 0, 0, xDocShRef ) );
2613     aAny = xPropSet->getPropertyValue( "Model" );
2614     CPPUNIT_ASSERT_MESSAGE( "The shape doesn't have the property", aAny.hasValue() );
2615 
2616     uno::Reference< chart::XChartDocument > xChartDoc;
2617     aAny >>= xChartDoc;
2618     CPPUNIT_ASSERT_MESSAGE( "failed to load chart", xChartDoc.is() );
2619     uno::Reference< chart2::XChartDocument > xChart2Doc( xChartDoc, uno::UNO_QUERY );
2620     CPPUNIT_ASSERT_MESSAGE( "failed to load chart", xChart2Doc.is() );
2621 
2622     uno::Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( xChart2Doc->getFirstDiagram(), uno::UNO_QUERY );
2623     uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysSeq( xBCooSysCnt->getCoordinateSystems() );
2624     uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[0], uno::UNO_QUERY );
2625 
2626     uno::Reference< chart2::XDataSeriesContainer > xDSCnt( xCTCnt->getChartTypes()[0], uno::UNO_QUERY );
2627     CPPUNIT_ASSERT_MESSAGE( "failed to load data series", xDSCnt.is() );
2628     uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
2629     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Invalid Series count", static_cast<sal_Int32>( 1 ), aSeriesSeq.getLength() );
2630 
2631     // These Labels have custom position, so the exported LabelPlacement (reference point) by MSO is OUTSIDE/OUTEND
2632     // Check the first label
2633     const css::uno::Reference< css::beans::XPropertySet >& rPropSet0( aSeriesSeq[0]->getDataPointByIndex( 0 ) );
2634     CPPUNIT_ASSERT( rPropSet0.is() );
2635     sal_Int32 aPlacement;
2636     rPropSet0->getPropertyValue( "LabelPlacement" ) >>= aPlacement;
2637     CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::OUTSIDE, aPlacement );
2638 
2639     // Check the second label
2640     const css::uno::Reference< css::beans::XPropertySet >& rPropSet1( aSeriesSeq[0]->getDataPointByIndex( 1 ) );
2641     CPPUNIT_ASSERT( rPropSet1.is() );
2642     rPropSet1->getPropertyValue( "LabelPlacement" ) >>= aPlacement;
2643     CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::OUTSIDE, aPlacement );
2644 
2645     // Check the third label
2646     const css::uno::Reference< css::beans::XPropertySet >& rPropSet2( aSeriesSeq[0]->getDataPointByIndex( 2 ) );
2647     CPPUNIT_ASSERT( rPropSet2.is() );
2648     rPropSet2->getPropertyValue( "LabelPlacement") >>= aPlacement;
2649     CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::OUTSIDE, aPlacement );
2650 
2651     xDocShRef->DoClose();
2652 }
2653 
2654 void SdImportTest::testTdf115394()
2655 {
2656     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf115394.pptx"), PPTX);
2657     double fTransitionDuration;
2658 
2659     // Slow in MS formats
2660     SdPage* pPage1 = xDocShRef->GetDoc()->GetSdPage(0, PageKind::Standard);
2661     fTransitionDuration = pPage1->getTransitionDuration();
2662     CPPUNIT_ASSERT_EQUAL(1.0, fTransitionDuration);
2663 
2664     // Medium in MS formats
2665     SdPage* pPage2 = xDocShRef->GetDoc()->GetSdPage(1, PageKind::Standard);
2666     fTransitionDuration = pPage2->getTransitionDuration();
2667     CPPUNIT_ASSERT_EQUAL(0.75, fTransitionDuration);
2668 
2669     // Fast in MS formats
2670     SdPage* pPage3 = xDocShRef->GetDoc()->GetSdPage(2, PageKind::Standard);
2671     fTransitionDuration = pPage3->getTransitionDuration();
2672     CPPUNIT_ASSERT_EQUAL(0.5, fTransitionDuration);
2673 
2674     // Custom values
2675     SdPage* pPage4 = xDocShRef->GetDoc()->GetSdPage(3, PageKind::Standard);
2676     fTransitionDuration = pPage4->getTransitionDuration();
2677     CPPUNIT_ASSERT_EQUAL(0.25, fTransitionDuration);
2678 
2679     SdPage* pPage5 = xDocShRef->GetDoc()->GetSdPage(4, PageKind::Standard);
2680     fTransitionDuration = pPage5->getTransitionDuration();
2681     CPPUNIT_ASSERT_EQUAL(4.25, fTransitionDuration);
2682 
2683     xDocShRef->DoClose();
2684 }
2685 
2686 void SdImportTest::testTdf115394PPT()
2687 {
2688     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/tdf115394.ppt"), PPT);
2689     double fTransitionDuration;
2690 
2691     // Fast
2692     SdPage* pPage1 = xDocShRef->GetDoc()->GetSdPage(0, PageKind::Standard);
2693     fTransitionDuration = pPage1->getTransitionDuration();
2694     CPPUNIT_ASSERT_EQUAL(0.5, fTransitionDuration);
2695 
2696     // Medium
2697     SdPage* pPage2 = xDocShRef->GetDoc()->GetSdPage(1, PageKind::Standard);
2698     fTransitionDuration = pPage2->getTransitionDuration();
2699     CPPUNIT_ASSERT_EQUAL(0.75, fTransitionDuration);
2700 
2701     // Slow
2702     SdPage* pPage3 = xDocShRef->GetDoc()->GetSdPage(2, PageKind::Standard);
2703     fTransitionDuration = pPage3->getTransitionDuration();
2704     CPPUNIT_ASSERT_EQUAL(1.0, fTransitionDuration);
2705 
2706     xDocShRef->DoClose();
2707 }
2708 
2709 void SdImportTest::testTdf51340()
2710 {
2711     // Line spacing was not inherited from upper levels (slide layout, master slide)
2712     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf51340.pptx"), PPTX);
2713     uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 1, 0, xDocShRef ) );
2714 
2715     // First paragraph has a 90% line spacing set on master slide
2716     uno::Reference<text::XTextRange> xParagraph( getParagraphFromShape( 0, xShape ) );
2717     uno::Reference< beans::XPropertySet > xPropSet( xParagraph, uno::UNO_QUERY_THROW );
2718     css::style::LineSpacing aSpacing;
2719     xPropSet->getPropertyValue( "ParaLineSpacing" ) >>= aSpacing;
2720     CPPUNIT_ASSERT_EQUAL( css::style::LineSpacingMode::PROP, aSpacing.Mode );
2721     CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int16>(90), aSpacing.Height );
2722 
2723     // Second paragraph has a 125% line spacing set on slide layout
2724     xParagraph.set( getParagraphFromShape( 1, xShape ) );
2725     xPropSet.set( xParagraph, uno::UNO_QUERY_THROW );
2726     xPropSet->getPropertyValue( "ParaLineSpacing" ) >>= aSpacing;
2727     CPPUNIT_ASSERT_EQUAL( css::style::LineSpacingMode::PROP, aSpacing.Mode );
2728     CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int16>(125), aSpacing.Height );
2729 
2730     // Third paragraph has a 70% line spacing set directly on normal slide (master slide property is overridden)
2731     xParagraph.set( getParagraphFromShape( 2, xShape ) );
2732     xPropSet.set( xParagraph, uno::UNO_QUERY_THROW );
2733     xPropSet->getPropertyValue( "ParaLineSpacing" ) >>= aSpacing;
2734     CPPUNIT_ASSERT_EQUAL( css::style::LineSpacingMode::PROP, aSpacing.Mode );
2735     CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int16>(70), aSpacing.Height );
2736 
2737     // Fourth paragraph has a 190% line spacing set directly on normal slide (slide layout property is overridden)
2738     xParagraph.set( getParagraphFromShape( 3, xShape ) );
2739     xPropSet.set( xParagraph, uno::UNO_QUERY_THROW );
2740     xPropSet->getPropertyValue( "ParaLineSpacing" ) >>= aSpacing;
2741     CPPUNIT_ASSERT_EQUAL( css::style::LineSpacingMode::PROP, aSpacing.Mode );
2742     CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int16>(190), aSpacing.Height );
2743 
2744     xDocShRef->DoClose();
2745 }
2746 
2747 void SdImportTest::testTdf116899()
2748 {
2749     // This is a PPT created in Impress and roundtripped in PP, the key times become [1, -1] in PP,
2750     //  a time of -1 (-1000) in PPT means key times have to be distributed evenly between 0 and 1
2751     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/tdf116899.ppt"), PPT);
2752 
2753     uno::Reference< drawing::XDrawPagesSupplier > xDoc(
2754         xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
2755     uno::Reference< drawing::XDrawPage > xPage(
2756         xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW );
2757     uno::Reference< animations::XAnimationNodeSupplier > xAnimNodeSupplier(
2758         xPage, uno::UNO_QUERY_THROW );
2759     uno::Reference< animations::XAnimationNode > xRootNode(
2760         xAnimNodeSupplier->getAnimationNode() );
2761     std::vector< uno::Reference< animations::XAnimationNode > > aAnimVector;
2762     anim::create_deep_vector(xRootNode, aAnimVector);
2763     uno::Reference< animations::XAnimate > xNode(
2764         aAnimVector[8], uno::UNO_QUERY_THROW );
2765     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of key times in the animation node isn't 2.", static_cast<sal_Int32>(2), xNode->getKeyTimes().getLength() );
2766     CPPUNIT_ASSERT_EQUAL_MESSAGE( "First key time in the animation node isn't 0, key times aren't normalized.", 0., xNode->getKeyTimes()[0] );
2767     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Second key time in the animation node isn't 1, key times aren't normalized.", 1., xNode->getKeyTimes()[1] );
2768 
2769     xDocShRef->DoClose();
2770 }
2771 
2772 void SdImportTest::testTdf77747()
2773 {
2774     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/tdf77747.ppt"), PPT);
2775     CPPUNIT_ASSERT(xDocShRef.is());
2776     SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>(GetPage(1, xDocShRef)->GetObj(0));
2777     CPPUNIT_ASSERT_MESSAGE("No text object", pTxtObj != nullptr);
2778     const SvxNumBulletItem *pNumFmt = pTxtObj->GetOutlinerParaObject()->GetTextObject().GetParaAttribs(0).GetItem(EE_PARA_NUMBULLET);
2779     CPPUNIT_ASSERT(pNumFmt);
2780     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bullet's suffix is wrong!", OUString("-"), pNumFmt->GetNumRule()->GetLevel(0).GetSuffix() );
2781     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bullet's numbering type is wrong!", SVX_NUM_NUMBER_HEBREW,
2782             pNumFmt->GetNumRule()->GetLevel(0).GetNumberingType());
2783 
2784     xDocShRef->DoClose();
2785 }
2786 
2787 void SdImportTest::testTdf116266()
2788 {
2789     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odp/tdf116266.odp"), ODP);
2790     SdDrawDocument *pDoc = xDocShRef->GetDoc();
2791     sfx2::LinkManager* rLinkManager = pDoc->GetLinkManager();
2792     // The document contains one SVG stored as a link.
2793     CPPUNIT_ASSERT_EQUAL(size_t(1), rLinkManager->GetLinks().size());
2794 
2795     xDocShRef->DoClose();
2796 }
2797 
2798 void SdImportTest::testTdf120028()
2799 {
2800     // Check that the table shape has 4 columns.
2801     ::sd::DrawDocShellRef xDocShRef
2802         = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf120028.pptx"), PPTX);
2803     uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocShRef->GetDoc()->getUnoModel(),
2804                                                      uno::UNO_QUERY);
2805     CPPUNIT_ASSERT(xDoc.is());
2806 
2807     uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
2808     CPPUNIT_ASSERT(xPage.is());
2809 
2810     // This failed, shape was not a table, all text was rendered in a single
2811     // column.
2812     uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage));
2813     uno::Reference<table::XColumnRowRange> xModel(xShape->getPropertyValue("Model"),
2814                                                   uno::UNO_QUERY);
2815     CPPUNIT_ASSERT(xModel.is());
2816 
2817     uno::Reference<table::XTableColumns> xColumns = xModel->getColumns();
2818     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xColumns->getCount());
2819 
2820     // Check font size in the A1 cell.
2821     uno::Reference<table::XCellRange> xCells(xModel, uno::UNO_QUERY);
2822     uno::Reference<beans::XPropertySet> xCell(xCells->getCellByPosition(0, 0), uno::UNO_QUERY);
2823     uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xCell));
2824     uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph));
2825     uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY);
2826     double fCharHeight = 0;
2827     xPropSet->getPropertyValue("CharHeight") >>= fCharHeight;
2828     // This failed, non-scaled height was 13.5.
2829     CPPUNIT_ASSERT_DOUBLES_EQUAL(11.5, fCharHeight, 1E-12);
2830 
2831     xDocShRef->DoClose();
2832 }
2833 
2834 void SdImportTest::testTdf120028b()
2835 {
2836     // Check that the table shape has 4 columns.
2837     ::sd::DrawDocShellRef xDocShRef
2838         = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf120028b.pptx"), PPTX);
2839     uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocShRef->GetDoc()->getUnoModel(),
2840                                                      uno::UNO_QUERY);
2841     CPPUNIT_ASSERT(xDoc.is());
2842 
2843     uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
2844     CPPUNIT_ASSERT(xPage.is());
2845 
2846     uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage));
2847     CPPUNIT_ASSERT(xShape.is());
2848 
2849     uno::Reference<table::XColumnRowRange> xModel(xShape->getPropertyValue("Model"),
2850                                                   uno::UNO_QUERY);
2851     CPPUNIT_ASSERT(xModel.is());
2852 
2853     uno::Reference<table::XTableColumns> xColumns = xModel->getColumns();
2854     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xColumns->getCount());
2855 
2856     // Check font color in the A1 cell.
2857     uno::Reference<table::XCellRange> xCells(xModel, uno::UNO_QUERY);
2858     uno::Reference<beans::XPropertySet> xCell(xCells->getCellByPosition(0, 0), uno::UNO_QUERY);
2859     uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xCell));
2860     uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph));
2861     uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY);
2862     sal_Int32 nCharColor = 0;
2863     xPropSet->getPropertyValue("CharColor") >>= nCharColor;
2864     // This was 0x1f497d, not white: text list style from placeholder shape
2865     // from slide layout was ignored.
2866     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xffffff), nCharColor);
2867 
2868     xDocShRef->DoClose();
2869 }
2870 
2871 void SdImportTest::testDescriptionImport()
2872 {
2873     sd::DrawDocShellRef xDocShRef
2874         = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/altdescription.pptx"), PPTX);
2875 
2876     uno::Reference<beans::XPropertySet> xPropertySet(
2877         getShapeFromPage(/*nShape=*/2, /*nPage=*/0, xDocShRef));
2878     OUString sDesc;
2879 
2880     xPropertySet->getPropertyValue("Description") >>= sDesc;
2881 
2882     CPPUNIT_ASSERT_EQUAL(OUString("We Can Do It!"), sDesc);
2883 
2884     xDocShRef->DoClose();
2885 }
2886 
2887 void SdImportTest::testTdf83247()
2888 {
2889     auto GetPause = [this](const OUString& sSrc, sal_Int32 nFormat) {
2890         sd::DrawDocShellRef xDocShRef
2891             = loadURL(m_directories.getURLFromSrc(sSrc), nFormat);
2892         uno::Reference<presentation::XPresentationSupplier> xPresentationSupplier(
2893             xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY);
2894         uno::Reference<beans::XPropertySet> xPresentationProps(
2895             xPresentationSupplier->getPresentation(), uno::UNO_QUERY_THROW);
2896 
2897         auto retVal = xPresentationProps->getPropertyValue("Pause");
2898         xDocShRef->DoClose();
2899         return retVal.get<sal_Int32>();
2900     };
2901 
2902     // 1. Check that presentation:pause attribute is imported correctly
2903     CPPUNIT_ASSERT_EQUAL(sal_Int32(10), GetPause("/sd/qa/unit/data/odp/loopPause10.odp", ODP));
2904 
2905     // 2. ODF compliance: if presentation:pause attribute is absent, it must be treated as 0
2906     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), GetPause("/sd/qa/unit/data/odp/loopNoPause.odp", ODP));
2907 
2908     // 3. Import PPT: pause should be 0
2909     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), GetPause("/sd/qa/unit/data/ppt/loopNoPause.ppt", PPT));
2910 }
2911 
2912 void SdImportTest::testTdf47365()
2913 {
2914     sd::DrawDocShellRef xDocShRef
2915         = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/loopNoPause.pptx"), PPTX);
2916     uno::Reference<presentation::XPresentationSupplier> xPresentationSupplier(
2917         xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW);
2918     uno::Reference<beans::XPropertySet> xPresentationProps(xPresentationSupplier->getPresentation(),
2919                                                            uno::UNO_QUERY_THROW);
2920 
2921     const bool bEndlessVal = xPresentationProps->getPropertyValue("IsEndless").get<bool>();
2922     const sal_Int32 nPauseVal = xPresentationProps->getPropertyValue("Pause").get<sal_Int32>();
2923 
2924     // Check that we import "loop" attribute of the presentation, and don't introduce any pauses
2925     CPPUNIT_ASSERT(bEndlessVal);
2926     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nPauseVal);
2927 
2928     xDocShRef->DoClose();
2929 }
2930 
2931 void SdImportTest::testTdf122899()
2932 {
2933     // tdf122899 FILEOPEN: ppt: old kind arc from MS Office 97 is broken
2934     // Error was, that the path coordinates of a mso_sptArc shape were read as sal_Int16
2935     // although they are unsigned 16 bit. This leads to wrong positions of start and end
2936     // point and results to a huge shape width in the test document.
2937     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/ppt/tdf122899_Arc_90_to_91_clockwise.ppt"), PPT);
2938     uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(
2939         xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW);
2940     CPPUNIT_ASSERT_MESSAGE("Could not get XDrawPagesSupplier", xDrawPagesSupplier.is());
2941     uno::Reference<drawing::XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages());
2942     uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY_THROW);
2943     CPPUNIT_ASSERT_MESSAGE("Could not get xDrawPage", xDrawPage.is());
2944     uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
2945     CPPUNIT_ASSERT_MESSAGE("Could not get xShape", xShape.is());
2946     awt::Rectangle aFrameRect;
2947     uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
2948     CPPUNIT_ASSERT_MESSAGE("Could not get the shape properties", xShapeProps.is());
2949     xShapeProps->getPropertyValue(UNO_NAME_MISC_OBJ_FRAMERECT) >>= aFrameRect;
2950     // original width is 9cm, add some tolerance
2951     CPPUNIT_ASSERT_LESS(static_cast<sal_Int32>(9020), aFrameRect.Width);
2952 
2953     xDocShRef->DoClose();
2954 }
2955 
2956 void SdImportTest::testOOXTheme()
2957 {
2958     sd::DrawDocShellRef xDocShRef
2959         = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/ooxtheme.pptx"), PPTX);
2960 
2961     uno::Reference<beans::XPropertySet> xPropSet(xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW);
2962     uno::Sequence<beans::PropertyValue> aGrabBag;
2963     xPropSet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
2964 
2965     bool bTheme = false;
2966     for (beans::PropertyValue const & prop : std::as_const(aGrabBag))
2967     {
2968         if (prop.Name == "OOXTheme")
2969         {
2970             bTheme = true;
2971             uno::Reference<xml::dom::XDocument> aThemeDom;
2972             CPPUNIT_ASSERT(prop.Value >>= aThemeDom); // PropertyValue of proper type
2973             CPPUNIT_ASSERT(aThemeDom); // Reference not empty
2974         }
2975     }
2976     CPPUNIT_ASSERT(bTheme); // Grab Bag has all the expected elements
2977 
2978     xDocShRef->DoClose();
2979 }
2980 
2981 void SdImportTest::testCropToShape()
2982 {
2983     sd::DrawDocShellRef xDocShRef
2984         = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/crop-to-shape.pptx"), PPTX);
2985     uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(
2986         xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW);
2987     CPPUNIT_ASSERT_MESSAGE("Could not get XDrawPagesSupplier", xDrawPagesSupplier.is());
2988     uno::Reference<drawing::XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages());
2989     uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY_THROW);
2990     CPPUNIT_ASSERT_MESSAGE("Could not get xDrawPage", xDrawPage.is());
2991     uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
2992     CPPUNIT_ASSERT_EQUAL(OUString{"com.sun.star.drawing.CustomShape"}, xShape->getShapeType());
2993     CPPUNIT_ASSERT_MESSAGE("Could not get xShape", xShape.is());
2994     uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
2995     css::drawing::FillStyle fillStyle;
2996     xShapeProps->getPropertyValue("FillStyle") >>= fillStyle;
2997     CPPUNIT_ASSERT_EQUAL(css::drawing::FillStyle_BITMAP, fillStyle);
2998     css::drawing::BitmapMode bitmapmode;
2999     xShapeProps->getPropertyValue("FillBitmapMode") >>= bitmapmode;
3000     CPPUNIT_ASSERT_EQUAL(css::drawing::BitmapMode_STRETCH, bitmapmode);
3001 }
3002 
3003 void SdImportTest::testTdf127964()
3004 {
3005     sd::DrawDocShellRef xDocShRef
3006         = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf127964.pptx"), PPTX);
3007     const SdrPage* pPage = GetPage(1, xDocShRef);
3008     const SdrObject* pObj = pPage->GetObj(0);
3009     auto& rFillStyleItem
3010         = dynamic_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE));
3011     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rFillStyleItem.GetValue());
3012 
3013     auto& rFillColorItem
3014         = dynamic_cast<const XFillColorItem&>(pObj->GetMergedItem(XATTR_FILLCOLOR));
3015     // Without the accompanying fix in place, this test would have failed with:
3016     // - Expected: 4294967295
3017     // - Actual  : 5210557
3018     // i.e. instead of transparent (which then got rendered as white), the shape fill color was
3019     // blue.
3020     CPPUNIT_ASSERT_EQUAL(COL_TRANSPARENT, rFillColorItem.GetColorValue());
3021     xDocShRef->DoClose();
3022 }
3023 
3024 void SdImportTest::testTdf106638()
3025 {
3026     sd::DrawDocShellRef xDocShRef
3027         = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf106638.pptx"), PPTX);
3028     uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, xDocShRef));
3029     uno::Reference<text::XTextRange> const xPara(getParagraphFromShape(1, xShape));
3030     uno::Reference<text::XText> xText= xPara->getText();
3031     uno::Reference<text::XTextCursor> xTextCursor = xText->createTextCursorByRange(xPara->getStart());
3032     uno::Reference<beans::XPropertySet> xPropSet(xTextCursor, uno::UNO_QUERY_THROW );
3033     OUString aCharFontName;
3034     CPPUNIT_ASSERT(xTextCursor->goRight(1, true));
3035     // First character U+f0fe that uses Wingding
3036     xPropSet->getPropertyValue("CharFontName") >>= aCharFontName;
3037     CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), aCharFontName);
3038 
3039     // The rest characters that do not use Wingding.
3040     CPPUNIT_ASSERT(xTextCursor->goRight(45, true));
3041     xPropSet->getPropertyValue("CharFontName") >>= aCharFontName;
3042     CPPUNIT_ASSERT(aCharFontName != "Wingdings");
3043 }
3044 
3045 void SdImportTest::testTdf128684()
3046 {
3047     sd::DrawDocShellRef xDocShRef
3048         = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf128684.pptx"), PPTX);
3049     uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocShRef->GetDoc()->getUnoModel(),
3050                                                      uno::UNO_QUERY);
3051     CPPUNIT_ASSERT(xDoc.is());
3052     uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
3053     CPPUNIT_ASSERT(xPage.is());
3054     uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage));
3055     CPPUNIT_ASSERT(xShape.is());
3056     uno::Any aAny = xShape->getPropertyValue("CustomShapeGeometry");
3057     CPPUNIT_ASSERT(aAny.hasValue());
3058     uno::Sequence<beans::PropertyValue> aProps;
3059     CPPUNIT_ASSERT(aAny >>= aProps);
3060     sal_Int32 nRotateAngle = 0;
3061     for( const auto& rProp : std::as_const(aProps) )
3062     {
3063         if( rProp.Name == "TextPreRotateAngle")
3064         {
3065             rProp.Value >>= nRotateAngle;
3066         }
3067     }
3068     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-90), nRotateAngle);
3069 }
3070 
3071 void SdImportTest::testTdf113198()
3072 {
3073     sd::DrawDocShellRef xDocShRef
3074         = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf113198.pptx"), PPTX);
3075 
3076     uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, xDocShRef));
3077     sal_Int16 nParaAdjust = -1;
3078     xShape->getPropertyValue("ParaAdjust") >>= nParaAdjust;
3079     CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER, static_cast<style::ParagraphAdjust>(nParaAdjust));
3080 }
3081 
3082 void SdImportTest::testTdf119187()
3083 {
3084     std::vector< sd::DrawDocShellRef > xDocShRef;
3085     // load document
3086     xDocShRef.push_back(loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf119187.pptx"), PPTX));
3087     // load resaved document
3088     xDocShRef.push_back(saveAndReload( xDocShRef.at(0).get(), PPTX ));
3089 
3090     // check documents
3091     for (const sd::DrawDocShellRef& xDoc : xDocShRef)
3092     {
3093         // get shape properties
3094         const SdrPage* pPage = GetPage(1, xDoc);
3095         CPPUNIT_ASSERT(pPage);
3096         SdrObject* pObj = pPage->GetObj(0);
3097         CPPUNIT_ASSERT(pObj);
3098         const sdr::properties::BaseProperties & rProperties = pObj->GetProperties();
3099 
3100         // check text vertical alignment
3101         const SdrTextVertAdjustItem& rSdrTextVertAdjustItem = rProperties.GetItem(SDRATTR_TEXT_VERTADJUST);
3102         const SdrTextVertAdjust eTVA = rSdrTextVertAdjustItem.GetValue();
3103         CPPUNIT_ASSERT_EQUAL(SDRTEXTVERTADJUST_TOP, eTVA);
3104     }
3105 }
3106 
3107 void SdImportTest::testShapeGlowEffectPPTXImpoer()
3108 {
3109     sd::DrawDocShellRef xDocShRef
3110         = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/shape-glow-effect.pptx"), PPTX);
3111 
3112     uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, xDocShRef));
3113     sal_Int32 nRadius = -1;
3114     xShape->getPropertyValue("GlowEffectRadius") >>= nRadius;
3115     CPPUNIT_ASSERT_EQUAL(sal_Int32(388), nRadius); // 139700 EMU = 388.0556 mm/100
3116     Color nColor;
3117     xShape->getPropertyValue("GlowEffectColor") >>= nColor;
3118     CPPUNIT_ASSERT_EQUAL(Color(0xFFC000), nColor);
3119     sal_Int16 nTransparency;
3120     xShape->getPropertyValue("GlowEffectTransparency") >>= nTransparency;
3121     CPPUNIT_ASSERT_EQUAL(sal_Int16(60), nTransparency);
3122 }
3123 
3124 void SdImportTest::testShapeBlurPPTXImport()
3125 {
3126     sd::DrawDocShellRef xDocShRef
3127             = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/shape-blur-effect.pptx"), PPTX);
3128 
3129     uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, xDocShRef));
3130     bool bHasShadow = false;
3131     xShape->getPropertyValue("Shadow") >>= bHasShadow;
3132     CPPUNIT_ASSERT(bHasShadow);
3133 
3134     sal_Int32 nRadius = -1;
3135     xShape->getPropertyValue("ShadowBlur") >>= nRadius;
3136     CPPUNIT_ASSERT_EQUAL(sal_Int32(388), nRadius); // 584200EMU=46pt - 139700EMU = 388Hmm = 11pt
3137 
3138 }
3139 
3140 CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest);
3141 
3142 CPPUNIT_PLUGIN_IMPLEMENT();
3143 
3144 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
3145